Project Euler 72 ilişkin Tek soru (lisp)

oy
5

Ben de bir şey> 52. çalıştırmayı denediğinizde lispbox en REPL iptal Sadece neden bilmek istiyorum, buna çıktıda bariz desen var olduğunu kabul, kod geliştirmeye herhangi bir öneri daha fazla kabul edilir. ^ - ^

(defun count-reduced-fractions (n d sum)
  (setf g (gcd n d))
  (if (equal 1 d)
      (return-from count-reduced-fractions sum)
      (if (zerop n)
          (if (= 1 g)
              (count-reduced-fractions (1- d) (1- d) (1+ sum))
              (count-reduced-fractions (1- d) (1- d) sum))
          (if (= 1 g)
              (count-reduced-fractions (1- n) d (1+ sum))
              (count-reduced-fractions (1- n) d sum)))))

Dediğim zaman tüm alıyorum

(count-reduced-fractions 53 53 0)

olduğu

Değerlendirilmesi; iptal

O kaçıyorum dikkate bana çok mantıklı (ve doğru sonuç döndürmek) onun altında tüm sayıları ve I could (i isteseydiniz) kağıt üzerinde kafamda 53 yapmak ya da bir satır yok lisp bir kerede. Hatta o 53 Hiçbir şey çalışır özgü değildi emin olmak için 53 daha büyük pek çok farklı sayılar üzerinde test.

Oluştur 10/12/2008 saat 01:03
kaynak kullanıcı
Diğer dillerde...                            


4 cevaplar

oy
6

senin tekrarlama yığını darbeler böylece bu davranış, eksik bir kuyruk çağrı optimizasyonu ipuçları. Olası bir nedeni ayıklama optimizasyonu çıkmamış olmalarıdır.

Bu arada, için açık çağrı yapmak gerekmez return-from. Yana sumkendini değerlendirirken semboldür, bu çizgiyi değiştirebilir

(return-from count-reduced-fractions sum)

için

sum

düzenleme: Önerilen Değişiklik açıklaması: "toplamı" (bu defun son ifadesi olduğundan) fonksiyonunun dönüş değeri olur "eğer" ifadesi, dönüş değeri olur, kendi değere değerlendirir.

düzenleme: çıkmamış optimizasyon Açıklama: Eğer üst düzeye aşağıdakileri ekleyebilirsiniz:

(declaim (optimize (speed 3)
                   (debug 0)))

ya ile değil, aynı kullanmak declareyerine declaimFonksiyonunuzda ilk ifadesi olarak. Bu işe yaramazsa durumunda da (boşluk 3) ve (emniyet 0) deneyebilirsiniz.

Kuyruk arama optimizasyonu bir dönüş değeri ile doğrudan döndürülür (yerine kadar istifleme) yığında bir çerçeve yerine çevrilmiş bir işlev çağrısı, etkili bir şekilde bir döngü ardışık bir işlev çağrısını "düzleştirme" ve özyinelemeli fonksiyon aramalar elimine olduğu anlamına gelir. Eğer, resp onları bekliyoruz hiçbir işlev çağrıları vardır çünkü bu, biraz daha zor ayıklama yapar. Eğer (eğer başlamak için bir döngü yazmıştı sadece sanki) bir hata oluşursa nasıl "derin" bir yineleme içine bilmiyorum. Kişisel ortamı TCO'nuzu etkinleştirmek için geçersiz kılmak zorunda bazı varsayılan declamations yapabilir.

düzenleme: Sadece bu soruyu yeniden ziyaret, nedir g? Ben aslında istiyorum düşünüyorum

(let ((g (gcd n d)))
  ;; ...
  )
Cevap 10/12/2008 saat 01:21
kaynak kullanıcı

oy
3

Benim tahminim lispbox ile yerleşik bir yığın derinliği sınırı var olmasıdır. Common Lisp kuyruk özyinelemeli fonksiyonlar sabit yığın alanı kullanmak garanti etmez olduğundan, sayım-azaltılmış-fraksiyonların her çağırma yığını üzerinde bir katman daha ekler olması mümkündür.

Bu arada, SBCL sorunsuz bu algoritmayı çalışır.

* (count-reduced-fractions 53 53 0)
881

* (count-reduced-fractions 100 100 0)
3043
Cevap 10/12/2008 saat 01:11
kaynak kullanıcı

oy
1

stil meselesi olarak, d yapmak ve opsiyonel özetlemek olabilir.

(defun test (n &optional (d n) (sum 0)) .. )
Cevap 10/12/2008 saat 01:15
kaynak kullanıcı

oy
0

Muhtemelen yığın taşması (heh).

Cevap 10/12/2008 saat 01:10
kaynak kullanıcı

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more