Bu cevap, ben ve 0 'arasındaki işbirliğinin bir parçası. İkimiz birlikte çalıştık, yayınlamamın tek nedeni Rock, Paper, Scissors kazandığım için.
\Q-->{Q=1};"(",\N,")",\B,{findnsols(N,I,(between(2,inf,I),\+ (between(3,I,U),0=:=I mod(U-1))),L)->append(_,[Y],L),Q is Y*B}.
Çevrimiçi deneyin!
açıklama
Bu cevap, prologda golfü neyin eğlenceli hale getirdiğinin mükemmel bir örneğidir.
Bu cevap, kesin yan tümce dilbilgileri için Prologs güçlü sistemini kullanır. İşte bizim dilbilgisi biraz ungolfed.
head(1)-->[].
head(Q)-->"(",head(N),")",head(B),{prime(N,Y),Q is Y*B}.
isprime(I):- \+ (between(3,I,U),0 =:= I mod(U-1)).
prime(N,Y):-
findnsols(N,I,(
between(2,inf,I),
isprime(I)
),L),
append(_,[Y],L),!.
İlk inşaat kuralı:
head(1)-->[].
Bu, Prolog'a boş dizenin 1'e karşılık geldiğini bildirir.
İkinci inşaat kuralımız biraz daha karmaşık.
head(Q)-->"(",head(N),")",head(B),{prime(N,Y),Q is Y*B}.
Bu, boş olmayan herhangi bir dizenin, aynı kurallara sahip bir cümle etrafında, aynı kurallara sahip bir cümlenin sağında parantez içerdiğini gösterir.
Ayrıca bize bu maddenin ( Q) değerinin kurala uyduğunu söyler :
{prime(N,Y),Q is Y*B}
Bunu kırmak Q, 2 sayının Yve B. Bsola maddenin sadece değeridir ve Ybir Ninci asal Nparantez içinde maddesinin değeridir.
Bu kural, faktör ağacının oluşum kurallarının her ikisini de kapsar
- Birleştirme çoğalır
- Muhafaza en önemli olanı aldı
Şimdi kesin tanımlar için. Golf edilmemiş versiyonda iki tahmin vardır (gerçek kodumda tahminleri uzakta zincirledim). Burada ilgili iki tahmin isprime/1, asal sayı ile eşleşen ve prime/2verilen Nve Yasff Yile eşleşen asal sayıdır N. İlk önce
isprime(I):- \+ (between(3,I,U),0 =:= I mod(U-1)).
Asallık bir oldukça standart tanımının Bu eserler, biz 2 arasında numara yoksa ısrar ve I2 değil de dahil olmak üzere, Iböler o I.
Bir sonraki yüklem de oldukça basit
prime(N,Y):-
findnsols(N,I,(
between(2,inf,I),
isprime(I)
),L),
append(_,[Y],L),!.
Asal findnsolsolan ilk Nsayıları bulmak için kullanırız , sonra sonuncuyu döndürürüz. Buradaki hile findnsols, en küçük N asalları bulması garanti edilmese de, SWI'nin işleyiş şekli nedeniyle betweenher zaman daha küçük asalları bulacaktır. Ancak bu, daha fazla prim bulmasını önlemek için kesmemiz gerektiği anlamına gelir.
Golfler
Kodumuzdaki nedeni iki kez iletebiliriz. Çünkü isprimetanımı sadece içine taşınabiliyorsa prime. Bir sonraki, primedoğrudan DCG'nin içine taşınmaktır , ancak çok fazla prim üretmesini primeönlemek için bir kesim kullandığımızdan findnsols, bir sorunumuz var. Kesim, istediğimiz bit yerine tüm DCG'yi keser. Biraz dokümantasyon kazısından sonra, once/1sadece bu kısmı kesmek için kullanılabilir, ancak tüm DCG'yi değil. Bununla birlikte, daha fazla belge kazma, ->operatörün benzer bir görevi yerine getirmek için de kullanılabileceğini ortaya koymuştur . ->Operatör eşdeğerdir ,!,biz diğer tarafına bizim kesim taşındı bu yüzden append/3ve onu değiştirdi ->.
SWI-Prolog'da tahminler (ve kurallar), operatörlere normalde gereken parantezleri bırakmamızı sağlayan adlar olarak verilebilir. Böylece kuralı çağırarak 6 bayt tasarruf edebiliriz \.