Durdurma Oracle ile Üç Açık Problem Çözme


23

Size fonksiyonlar verilir: h1 (f, * args) ve h2 (f, * args)

Her ikisi de sizin için zaten tanımlanmış olan yöntemlerdir (burada yıldız, değişken sayıdaki argümanları gösterir)

f bir fonksiyondur, * args bu fonksiyona aktarılacak parametrelerin listesidir

h1 bir boolean değeri döndürür: f işlevi * args çağrıldığında durursa doğrudur ve yapmazsa False (çalışmakta olan makinenin sonsuz bir zaman ve hafızası olduğunu ve yazdığınız dilin tercüman / derleyicisini varsayarsak Sonsuz zaman ve hafızayı nasıl kullanacağını bilir).

F (* args), h1 veya h2'ye bir çağrı yaparsa, h1 bir istisna atar

h2 tam olarak h1 gibi davranır, eğer f, h1'e çağrı yaparsa, h2 bir istisna atmaz

Mümkün olduğu kadar az karakterde, girdi içermeyen ve çıkması gereken bir program yazın:

The Collatz Conjecture is {True/False}
Goldbach's Conjecture is {True/False}
The Twin Primes Conjecture is {True/False}

Bu varsayımların her birinin geçerliliğine dayalı.

Her bir varsayımı açıklayan wikipedia linkleri:

http://en.wikipedia.org/wiki/Collatz_conjecture

http://en.wikipedia.org/wiki/Goldbach%27s_conjecture

http://en.wikipedia.org/wiki/Twin_prime

Herhangi bir büyük tamsayı kütüphanesinin, hangi dili kullanacağınızı seçerseniz, isteğe bağlı büyük tamsayıları başarıyla temsil edeceğini varsayabilirsiniz. Başka bir deyişle, ifade edebilen bir dil / kütüphanenin 3**(3**10)de 3**(3**(3**10))yeterince etli bir makinede ifade edebildiği varsayılır .

Açıkçası, programınızı çalıştırmak mümkün olmadığından, lütfen kodla birlikte nasıl çalıştığı hakkında bir açıklama yapın.


Bu hala objektif bir puanlama kriterine ihtiyaç duyuyor. Ayrıca, sözde programın işe yaradığını ispatlamak gerçekten zor olabilir.
Bay Llama,

En az karakter söyledim. Bu bir kodlayıcı sorunu.
dspyz

Bu, bu problem için ilginç bir puanlama prosedürü. "İkiz asal varsayımı, en az sayıda karakterle çözün."
PyRulez

dostum, ne güzel bir soru
undergroundmonorail

Yanıtlar:


4

J, 207

(('The Collatz';'Goldbach''s';'The Twin Primes'),.<'Conjecture is'),.((>:^:((((-:`>:@*&3)^:(~:&1))^:_)&f)^:_ g 2)((+&2)^:(+./@1&p:@(-p:@_1&p:))^:_ f 4)(>:^:((4&p:)^:(2&~:&(-~4&p:))&f)^:_ g 3){'True':'False')

Kullanmayı seçtim fve gyerine h1ve h2ödülüne göre; Önceden toplam 10 karakterden oluşan iki ek satır geçiş yapmak için yeterlidir: f=:h1, g=:h2.

Ve gerçek mantık:

Collatz

>:^:((((-:`>:@*&3)^:(~:&1))^:_)&f)^:_ g 2

((-:`>:@*&3)^:(~:&1))^:_onun eti; Bu aslında yapan bir döngü while (x != 1) x = collatz(x). Bu cümleyi arayabilirsek reduce:

>:^:(reduce&f)^:_ g 2

reduce&fmonadik bir fiil anlamına gelir (sonuna bakın), burada reduce&f ngerçek iff reduce(n)durur. Diğer döngü-y bitleri, >:^:()^:_esasen sonsuz bir döngüdür ( >:artan, ^:koşullu ve bir yineleyici olarak kullanılabilir), durmayan bir Collatz azalması ile karşılaştığında kırılan. Sonunda gsonsuz döngünün hiç bitip bitmediğini görmek için çağrılır.

Goldbach

(+&2)^:(+./@1&p:@(-p:@_1&p:))^:_ f 4

Aynı mantık, çoğunlukla, çekirdek hesaplama olarak açık fark şu anda +./@1&p:@(-p:@_1&p:). -p:@_1&p:Bir sayı ile tüm asal sayılar arasındaki farkı bu sayıdan küçük olarak hesaplar 1&p:, bir isPrimefonksiyondur ve +./VEYA mantıksaldır. Bu nedenle, bir sayı ile bu sayıdan küçük olan herhangi bir asal arasındaki fark aynı zamanda bir asal ise, Goldbach varsayımı tatmin olur ve sonsuz döngü devam eder. Yine, fbahsedilen sonsuz döngünün gerçekten sonsuz olup olmadığının son bir testinde kullanılır.

İkiz Asallar

>:^:((4&p:)^:(2&~:@(-~4&p:))&f)^:_ g 3

Yukarıdakilerle aynı, hariç (4&p:)^:(2&~:@(-~4&p:)). 4&p:Belirli bir sayıdan sonra bir sonraki en büyük prime döner. -~4&p:sayı ile ondan sonraki en büyük asal sayı arasındaki farkı döndürür. 2&~:olduğunu != 2. Yani en içteki döngü buna benzer while (nextPrimeAfter(p) - p != 2) p = nextPrimeAfter(p).

notlar

Sahte fve ghenüz test etmediğim için sözdizimsel hatalar olabilir . Ayrıca, farz fve gsolda bir fiil ve ben herhangi bir şekilde J dilbilgisi tamamen emin uyar değilim sağda, bir isim ile oluşabilir formu çeşit alacaktı. Doğası gereği daha üst düzey işlevler ve bu tür uygun bir yapı bile olsa, şu anda zarflar / kavşaklar / neyin varsa size uygun bir yapı arayacak kadar yorgunum.

Gerçekten doğru bir bitiştirme kullanmıyorum ve bunun yerine tek tek dizeleri kutulu bırakmayı seçtim. Çıktı (her şeyin doğru olduğu varsayılarak) bu nedenle 3 sütunlu bir tablo olacaktı; soldaki sütun "The Collatz" vb., Ortadaki sütun "Conjecture" ve sağ sütun "True" / "False" olacaktı. .

Ayrıca, J'nin varsayılan olarak tamsayıları keyfi kesinliğe çevirmediğinden ve önemli asal sayı yardımcı programı işlevinin p:isteğe bağlı olarak büyük bir etki alanına sahip olmadığından eminim . Öte yandan, J'nin standart bir rasgele kesinlik numarası tipini desteklemesi durumunda, bu kodu en üst seviyeye çıkarmak için ne kadar çaba harcayacağından emin değilim.


Peki, sonuçta keyfi kesinliği destekliyor mu? Bence ana test APL cevabı gibi kolayca düzeltilebilir.
jimmy23013

Zaten ödül kriterlerinde (CJam için) yazdığımdan beri, kuralları izleyeceğim ve Haskell cevabını ödeyeceğim ... Ama benden +1.
jimmy23013

7

Haskell, 242

p n=and[rem n r>0|r<-[2..n-1]]
c 1=1
c n|odd n=c$3*n+1|0<1=c$div n 2
s!f=putStr(s++" Conjecture is ")>>print(not$h2$all(h1.f)[4..])
main=do"The Collatz"!c;"Goldbach's"! \n->or[p$n-r|r<-[2..n-2],p r];"The Twin Primes"! \n->or[p$r+2|r<-[n..],p r]

Çünkü Haskell'de değişkenler sadece değerler içermemekte, hesaplamalar da (tembellik olarak adlandırılmaktadır) kendimi h1, h2tek bir argümanla alıp havanın geri dönmesine izin veriyorum ya da değerlendirme durur.

biraz kodlanmış kod:

h1 = undefined
h2 = undefined

prime n=and[rem n r>0|r<-[2..n-1]]
collatz 1=1
collatz n
    |odd n=collatz (3*n+1)
    |0<1  =collatz (div n 2)

s!f=do
    putStr (s++" Conjecture is ")
    print$not$h2$all(h1.f)[4..]

main=do
    "The Collatz"!c                                         --collatz
    "Goldbach's"! \n->or[prime (n-r)|r<-[2..n-2],prime r]   --goldbach
    "The Twin Primes"! \n->or[prime (r+2)|r<-[n..],prime r] --twin primes

biraz açıklama:

zaman allsonsuz listesi uygulanır listenin unsurlarından biri IFF, bu durur Falsebağlı laziness, (orada olmayan tüm Haskell millet, kısa devre). bunu collatz varsayımını ve ikiz primerler hesaplamasını hesaplamak için kullanırız.

!bu numarayı baskı ile birlikte paketler. Sonuç, tüm sayılar üzerinde sonlandığında ortaya Trueçıkar . (bu, kollatz ya da ikiz primatlar varsayımı için farketmez, çünkü zaten bu kadar küçük sayılar için doğru olduklarını biliyoruz).f4..

collatz varsayımı için kod "The Collatz"!c. “Collatz Conjecture is” yazıyor ve hava durumu olan sonuç ctüm sayılarla sonlanıyor 4...

goldbach varsayımı için kod "Goldbach's"! \n->or[p$n-r|r<-[2..n-2],p r]. \n->or[p$n-r|r<-[2..],p r,r<n+1]verilen n, iki asal toplam ise, döndüren True, ancak aksi takdirde süresiz olarak dönen bir fonksiyondur . bu nedenle, eğer her 4..goldbach'ın varsayımı için durursa , doğru olur.

İkiz asal varsayımı için kod "The Twin Primes"! \n->or[p$r+2|r<-[n..],p r]. İkiden büyük primerler varsa , True döndüren ancak başka türlü süresiz olarak \n->or[p$r+2|r<-[n..],p r]verilen bir fonksiyondur . bu nedenle, her ikiz asal varsayımı için durursa doğru olur.nn4..


Bunun da eski bir versiyonunu yayınlamayı düşünür müsün? (uygun boşluklar ve bazı tip imzalar ile) Barları sizin gibi tek bir satıra koyabileceğinizi bilmiyordum c
dspyz

Asallık test cihazı [2..n-1] 'den geçmemeli mi? (aksi takdirde her şeyin kompoziti)
dspyz

Ayrıca, p, ilklilikleri veya kompozitlikleri test eder mi?
dspyz

Haskell'e doğal uzantıyı severim: h1, bu grubun değerlendirmesinin duracağını mı yoksa daha da iyisinin mi olacağını belirler, h1, False döndürdüğü yerde _ | _ olmayan tüm hesaplamalar için True döndürür (hesaplama h1 kullanmıyorsa, sonuç kendisi _ | _).
dspyz

@ dspyz hmm. bu iyi. ancak bu istisnaların alt olduğu gerçeğini kötüye kullanmamıza izin verir ve h1 yanlış kullanıldığında istisnalar atar ... Bunun ne kadar faydalı olacağını merak ediyorum.
Gurme haskeller

3

Python (965 karakter)

Çünkü benim sorum sevişmiyor. Python'da (kodsuz) çözümümü gönderiyorum:

def numCollatzSteps(n):
    numSteps=0
    while n>1:
        if n%2==0:
            n//=2
        else:
            n=3*n+1
        numSteps+=1
    return numSteps

def findNonHaltingN():
    for n in count(1):
        if not h1(numCollatzSteps,n):
            return n

print "The Collatz Conjecture is "+str(not h2(findNonHaltingN))

def isPrime(n):
    for i in range(2,n):
        if n%i==0:
            return False
    else:
        return True

def isSumOf2Primes(n):
    for i in range(2,n-2):
        if isPrime(i) and isPrime(n-i):
            return True
    else:
        return False

def findNonSum():
    for i in count(4,2):
        if not isSumOf2Primes(i):
            return i

print "Goldbach's Conjecture is "+str(not h1(findNonSum))

def isSmallTwinPrime(n):
    return isPrime(n) and isPrime(n+2)

def nextSmallTwinPrime(n):
    for i in count(n):
        if isSmallTwinPrime(i):
            return i

def largestTwinPrimes():
    for n in count(2):
        if not h1(nextSmallTwinPrime,n):
            return n-1,n+1

print "The Twin Primes Conjecture is "+str(not h2(largestTwinPrimes))

Bu oldukça basit.

numCollatzSteps (n), Collatz dizisinin belirli bir n için kaç adım attığını söyler. Eğer söylenen Collatz dizisi sona ermezse, sonsuz bir şekilde devam eder.

findNonHaltingN (), numCollatzSteps'in her n için sonlandırıldığını denetlemek için yukarı doğru sayar. findNonHaltingN, numCollatzSteps öğesinin sonlandırmadığı bir n varsa ve yalnızca sona erer.

Böylece, Collatz varsayımının findNonHaltingN () 'nin durmadığını kontrol ederek doğru olup olmadığını kontrol edebiliriz.

isPrime (n), 1 ile n-1 arasında pozitif bir tamsayı olmadığını bölerek sayının asal olup olmadığını kontrol eder.

isSumOf2Primes (n), 2 ile n-2 arasındaki tüm pozitif tamsayıları yineler ve en az bir tanesinin tamamlayıcısıyla birlikte asal olup olmadığını kontrol eder.

findNonSum (), 2 primerin toplamı olmayan ilk sayıya ulaşana kadar 4'ten yukarı doğru olan sayıları sayar ve sonra döndürür. Eğer böyle bir sayı yoksa, o zaman sonsuz devam edecektir.

Goldbach'ın varsayımının, FindSonum'un durmadığını görerek doğru olup olmadığını kontrol edebiliriz.

isSmallTwinPrime (n), yalnızca n ve n + 2'nin her ikisi de birincil ise

nextSmallTwinPrime (n) bir sonraki sayıyı döndürür> = n bunun için isSmallTwinPrime doğrudur

biggestTwinPrimes (), nextSmallTwinPrime uygulamasının herkes için durduğunu kontrol etmekten 2 kat daha fazla. KüçükTwinPrime bir n için hiç durmazsa, o zaman en büyük ikiz asalların n-1 ve n + 1 olduğunu izleriz ve orada dururuz.

O zaman ikiz prime varsayımının geçerliliğini, en büyük TwinPrimes'in hiç durmadığını kontrol ederek kontrol edebiliriz.


3

APL (234)

Belli ki denenmemiş, ancak mantık sağlam görünüyor. Yazdırma komutlarının tümü dahil edilmiştir, çıktı 104karakterler ve gerçek mantıktır 130.

Z←' Conjecture is '∘,¨'True' 'False'
⎕←'The Collatz',Z[1+{~{1=⍵:⍬⋄2|⍵:∇1+3×⍵⋄∇⍵÷2}h1⍵:⍬⋄∇⍵+1}h2 1]
⎕←'Goldbach''s',Z[1+{~⍵∊∘.+⍨N/⍨~N∊∘.×⍨N←1+⍳⍵:⍬⋄∇⍵+2}h1 2]
⎕←'The Twin Primes',Z[1+{~(T←{∧/{2=+/(⌈=⌊)⍵÷⍳⍵}¨N←⍵+1:N⋄∇N})h1⍵:⍬⋄∇T⍵}h2 4 2]

Ungolfed:

⍝ Environment assumptions: ⎕IO=1 ⎕ML=1
⍝ I've also assumed h1 and h2 are APL operators
⍝ i.e. x F y = f(x,y); x (F h1) y = h1(F,x,y)

⍝ 'Conjecture is True', 'Conjecture is False'
Z←' Conjecture is '∘,¨'True' 'False'

⍝⍝⍝ Collatz Conjecture
⍝ halts iff 1 is reached from given ⍵
collatzLoop←{
   1=⍵:⍬       ⍝ ⍵=1: halt
   2|⍵:∇1+3×⍵  ⍝ ⍵ uneven: loop with new val
   ∇⍵÷2        ⍝ ⍵ even: loop with new val
}

⍝ halts iff 1 is *not* reached from a value ≥ ⍵ (collatz false)
collatzHalt←{~collatzLoop h1 ⍵:⍬⋄∇⍵+1}

⍝ does it halt?
⎕←'The Collatz',Z[1+ collatzHalt h2 1]


⍝⍝⍝ Goldbach's Conjecture

⍝ Can ⍵ be expressed as a sum of two primes?
sumprimes←{
    N←1+⍳⍵         ⍝ N=[2..⍵+1]
    P←(~N∊N∘.×N)/N ⍝ P=primes up to ⍵+1×⍵+1
    ⍵∊P∘.+P        ⍝ can two P be summed to ⍵?
}

⍝ halts iff Goldbach is false
goldbachHalt←{
    ~sumprimes ⍵:⍬ ⍝ not a sum of primes: halt
    ∇⍵+2           ⍝ try next even number
}

⍝ does it halt?
⎕←'Goldbach''s',Z[1+ goldbachHalt h1 2]

⍝⍝⍝ Twin Primes

⍝ is it a prime?
isPrime←{
   2=+/(⌊=⌈)⍵÷⍳⍵    ⍝ ⍵ is a prime if ⍵ is divisible by exactly two
                   ⍝ numbers in [1..⍵] (i.e. 1 and ⍵)
}

⍝ find next twin
nextTwin←{
   N←⍵+1            ⍝ next possible twin
   ∧/ isPrime¨ N:N  ⍝ return it if twin
   ∇N               ⍝ not a twin, search on
}       

⍝ halts iff no next twin for ⍵
twinPrimeHalt←{
   ~nextTwin h1 ⍵: ⍬  ⍝ if no next twin for ⍵, halt
   ∇nextTwin ⍵        ⍝ otherwise try next twin
}

⍝ does it halt?
⎕←'The Twin Primes',Z[1+ twinPrimeHalt h2 4 2]

Peki APL büyük tamsayıları destekliyor mu?
jimmy23013

@ user23013: Teoride, APL'nin sayı biçimi isteğe bağlı olarak hassas bir değişkendir, bu nedenle teoride herhangi bir sayıyı saklayabilir. Tabii ki, pratikte, bir sınır var, fakat uygulamaya bağlı ve soru, keyfi büyüklükteki sayıları idare edebileceğini varsaymak olduğunu söylüyor.
marinus

Soru, sadece büyük tam sayıların keyfi olarak büyük olabileceğini söylüyor .
jimmy23013

@ user23013: yalnızca bir sayı türüne sahip
marinus

Büyük tamsayılar genellikle rasgele hassas tamsayılar demektir. Söz konusu açıklık gibi, ifade mümkün olmalıdır 3**(3**10)( 3*3*10tryapl.org bir ALAN HATA veren APL olarak).
jimmy23013
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.