Memecahkan Tiga Masalah Terbuka dengan Menghentikan Oracle

23

Anda diberi fungsi: h1 (f, * args) dan h2 (f, * args)

Keduanya adalah metode yang sudah ditentukan untuk Anda (di sini tanda bintang menunjukkan sejumlah variabel argumen)

f adalah fungsi, * args adalah daftar parameter yang akan diteruskan ke fungsi itu

h1 mengembalikan nilai boolean: Benar jika fungsi f pernah berhenti ketika dipanggil * args dan False jika tidak (dengan asumsi mesin yang menjalankannya memiliki waktu dan memori yang tak terbatas dan bahwa juru bahasa / kompiler untuk bahasa yang Anda tuliskan tahu bagaimana menangani waktu dan memori tanpa batas).

Jika f (* args) akan membuat panggilan ke h1 atau h2, h1 melempar pengecualian

h2 berperilaku persis seperti h1 kecuali bahwa jika f melakukan panggilan ke h1, maka h2 tidak akan melempar pengecualian

Dalam karakter sesedikit mungkin, tulis sebuah program yang tidak mengambil input dan harus menampilkan:

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

berdasarkan validitas dari masing-masing dugaan tersebut.

Berikut adalah tautan wikipedia yang menjelaskan masing-masing dugaan:

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

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

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

Anda dapat mengasumsikan pustaka bilangan bulat besar dalam bahasa apa pun yang Anda pilih untuk digunakan akan berhasil mewakili bilangan bulat besar yang sewenang-wenang. Dengan kata lain, kita akan menganggap bahasa / pustaka apa pun yang mampu mengekspresikan 3**(3**10)juga mampu mengekspresikan 3**(3**(3**10))pada mesin yang cukup gemuk.

Jelas karena tidak mungkin menjalankan program Anda, berikan penjelasan tentang cara kerjanya bersama dengan kode

dspyz
sumber
Ini masih membutuhkan kriteria penilaian yang objektif. Juga, membuktikan bahwa program pseudo bekerja mungkin sangat menantang.
Tn. Llama
Saya mengatakan karakter paling sedikit. Ini masalah codegolf.
dspyz
Itu adalah prosedur penilaian yang menarik untuk masalah ini. "Pecahkan dugaan kembar utama dalam jumlah karakter paling sedikit."
PyRulez
***, pertanyaan yang keren
undergroundmonorail

Jawaban:

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')

Saya memilih untuk menggunakan fdan gmenggantikan h1dan h2, sesuai dengan karunia; dua baris tambahan dengan 10 karakter sebelum cukup untuk beralih: f=:h1, g=:h2.

Dan logika yang sebenarnya:

Collatz

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

((-:`>:@*&3)^:(~:&1))^:_adalah dagingnya; itu pada dasarnya adalah sebuah loop yang tidak while (x != 1) x = collatz(x). Jika kita sebut kalimat itu reduce:

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

reduce&fdimaksudkan untuk menjadi kata kerja monadik (lihat akhir), di mana reduce&f nbenar iff reduce(n)berhenti. Bit loop-y lainnya >:^:()^:_,, pada dasarnya adalah loop infinite ( >:adalah increment, ^:dapat digunakan sebagai kondisional dan iterator) yang terputus saat menemui pengurangan Collatz yang tidak berhenti. Akhirnya gdipanggil untuk melihat apakah loop tak terbatas pernah berakhir.

Goldbach

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

Logika yang sama, untuk sebagian besar, perbedaan yang jelas menjadi perhitungan inti sekarang +./@1&p:@(-p:@_1&p:). -p:@_1&p:menghitung perbedaan antara angka dan semua bilangan prima kurang dari angka itu, 1&p:adalah isPrimefungsi, dan +./logis ATAU. Oleh karena itu, jika perbedaan antara bilangan dan bilangan prima apa pun yang kurang dari bilangan itu juga bilangan prima, maka dugaan Goldbach terpenuhi, dan loop infinite berlanjut. Sekali lagi, fdigunakan dalam tes akhir apakah loop infinite tersebut benar-benar tidak terbatas.

Twin Primes

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

Sama seperti di atas, kecuali (4&p:)^:(2&~:@(-~4&p:)). 4&p:mengembalikan prime terbesar berikutnya setelah angka yang diberikan. -~4&p:mengembalikan perbedaan antara angka dan prime terbesar berikutnya setelahnya. 2&~:adalah != 2. Jadi loop terdalam dianalogikan dengan while (nextPrimeAfter(p) - p != 2) p = nextPrimeAfter(p).

Catatan

Mungkin ada kesalahan sintaksis, karena saya belum diuji dengan dummy fdan gbelum. Juga, saya berasumsi itu fdan gakan mengambil semacam bentuk yang dapat dikomposisikan dengan kata kerja di sebelah kiri dan kata benda di sebelah kanan, yang saya tidak sepenuhnya yakin mengikuti tata bahasa J dengan cara apa pun. Mereka secara inheren memiliki fungsi urutan yang lebih tinggi, dan saya terlalu lelah untuk mencari konstruksi yang tepat sebagai kata keterangan / konjungsi / apa-apa yang Anda miliki saat ini, jika ada konstruksi yang sesuai.

Saya tidak benar-benar menggunakan penggabungan string yang tepat, dan bukannya memilih untuk meninggalkan string individu kotak. Outputnya (dengan asumsi semuanya benar) karena itu akan menjadi tabel 3 kolom, dengan kolom kiri adalah "The Collatz", dll., Kolom tengah adalah "Dugaan adalah", dan kolom kanan "Benar" / "Salah" .

Saya juga cukup yakin J tidak mengubah bilangan bulat ke presisi sewenang-wenang secara default, dan fungsi utilitas bilangan prima yang penting p:tidak memiliki domain besar yang sewenang-wenang. Di sisi lain, mengingat J memang mendukung tipe angka presisi arbitrer standar, saya tidak yakin berapa banyak upaya yang diperlukan untuk mendapatkan kode ini secara normal.

rasionalis
sumber
Jadi, apakah ini mendukung presisi yang sewenang-wenang? Saya pikir ujian utama mudah diperbaiki seperti jawaban APL.
jimmy23013
Karena saya sudah menulis itu dalam kriteria bounty (untuk CJam), saya pikir saya akan mengikuti aturan dan memberikan jawaban Haskell ... Tapi +1 dari saya.
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]

karena dalam variabel Haskell dapat berisi tidak hanya nilai, tetapi perhitungan (ini disebut kemalasan) saya membiarkan diri saya h1, h2mengambil argumen tunggal dan mengembalikan cuaca atau tidak evaluasi itu akan berhenti.

kode yang agak tidak dipisahkan:

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

sedikit penjelasan:

ketika allditerapkan ke daftar tak terbatas, itu akan berhenti jika salah satu elemen dari daftar adalah False, karena kemalasan (korsleting, untuk semua orang non-Haskell di luar sana). kami menggunakan ini untuk menghitung dugaan collatz dan dugaan primes kembar.

!paket tipuan ini bersama dengan pencetakan. hasilnya adalah Trueketika fberakhir pada semua angka 4... (Ini tidak masalah untuk dugaan collatz atau dugaan prima kembar, karena kita sudah tahu mereka benar untuk jumlah kecil seperti itu).

kode untuk dugaan collatz adalah "The Collatz"!c. itu mencetak "The Collatz Conjecture is" dan hasilnya, yaitu cuaca cberakhir pada semua angka 4...

kode untuk dugaan goldbach adalah "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]adalah fungsi yang diberikan n, jika merupakan jumlah dari dua bilangan prima, kembali True, tetapi sebaliknya loop tanpa batas. dengan demikian, jika berhenti untuk 4..dugaan setiap goldbach adalah benar.

kode untuk dugaan bilangan prima kembar adalah "The Twin Primes"! \n->or[p$r+2|r<-[n..],p r]. \n->or[p$r+2|r<-[n..],p r]adalah fungsi yang diberikan n, jika ada bilangan prima kembar lebih besar dari n, mengembalikan True, tetapi sebaliknya loop tanpa batas. dengan demikian, jika berhenti untuk setiap 4..dugaan prime twin adalah benar.

haskeller bangga
sumber
Apakah Anda keberatan memposting versi yang tidak serigala juga? (dengan spasi yang tepat dan beberapa tanda tangan jenis) Saya tidak tahu Anda bisa meletakkan semua bar pada satu baris seperti yang Anda lakukan untuk c
dspyz
Bukankah seharusnya penguji purba berasal dari [2..n-1]? (jika tidak semuanya komposit)
dspyz
oh, juga, apakah tes p untuk primality atau compositeness?
dspyz
Saya suka ekstensi alami untuk haskell: h1 menentukan apakah evaluasi thunk ini akan berhenti, atau lebih baik lagi, h1 mengembalikan True untuk semua perhitungan yang bukan _ | _ di mana ia mengembalikan False (kecuali perhitungan menggunakan h1 dalam hal ini hasilnya itu sendiri adalah _ | _).
dspyz
@ dspyz hmm. itu bagus. tapi itu akan memungkinkan kita untuk menyalahgunakan fakta bahwa pengecualian adalah dasar, dan bahwa dia melempar pengecualian ketika itu digunakan secara tidak benar ... Aku bertanya-tanya seberapa berguna itu sebenarnya.
haskeller bangga
3

Python (965 karakter)

Karena pertanyaan saya adalah tidak mendapatkan cinta. Saya memposting solusi (non-kode-golf) saya di Python:

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))

Ini cukup sederhana.

numCollatzSteps (n) mengatakan berapa banyak langkah urutan Collatz untuk n tertentu. Ini berjalan tanpa batas jika urutan Collatz tidak berakhir.

findNonHaltingN () menghitung ke atas memeriksa numCollatzSteps yang berakhir untuk setiap n. findNonHaltingN berakhir jika dan hanya jika ada n yang numCollatzSteps tidak berakhir.

Jadi kita dapat memeriksa apakah dugaan Collatz benar dengan memeriksa bahwa findNonHaltingN () tidak berhenti

isPrime (n) memeriksa apakah suatu bilangan prima dengan melihat bahwa tidak ada bilangan bulat positif dari 1 hingga n-1 yang membaginya

isSumOf2Primes (n) mengulangi semua bilangan bulat positif antara 2 dan n-2 dan memeriksa bahwa setidaknya satu bilangan prima bersama dengan pelengkapnya

findNonSum () menghitung bilangan genap ke atas dari 4 hingga mencapai angka pertama yang bukan jumlah 2 bilangan prima dan kemudian mengembalikannya. Jika tidak ada nomor seperti itu, maka itu akan berlanjut tanpa batas.

Kita dapat memeriksa apakah dugaan Goldbach benar dengan melihat findNonSum tidak berhenti.

isSmallTwinPrime (n) mengembalikan true jika dan hanya jika n dan n + 2 keduanya prima

nextSmallTwinPrime (n) mengembalikan angka berikutnya> = n yang isSmallTwinPrime benar

latestTwinPrimes () dihitung dari 2 memeriksa bahwa nextSmallTwinPrime berhenti untuk semua n. Jika nextSmallTwinPrime selanjutnya tidak berhenti untuk beberapa n, maka berarti bilangan prima kembar terbesar adalah n-1 dan n +1 dan kami berhenti di sana

Kemudian kita dapat memeriksa validitas dugaan kembar prima dengan memeriksa bahwaTwinPrimes terbesar tidak pernah berhenti.

dspyz
sumber
3

APL (234)

Jelas tidak teruji, tetapi logikanya tampaknya sehat. Semua perintah pencetakan sudah termasuk, output berupa 104karakter dan logika aktualnya 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]

Tidak Disatukan:

⍝ 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]
marinus
sumber
Tetapi apakah APL mendukung bilangan bulat besar?
jimmy23013
@ user23013: Secara teori, format angka APL adalah pelampung presisi-sewenang-wenang, dengan demikian, secara teori ia dapat menyimpan angka apa pun. Tentu saja, dalam praktiknya, ada batasnya, tetapi itu tergantung pada implementasi, dan pertanyaannya adalah mengasumsikan ia dapat menangani angka dengan ukuran yang berubah-ubah.
marinus
Pertanyaannya mengatakan hanya bilangan bulat besar yang bisa besar secara sewenang-wenang.
jimmy23013
@ user23013: ini hanya memiliki tipe nomor satu
marinus
Bilangan bulat besar biasanya berarti bilangan bulat presisi acak. Sebagaimana diklarifikasi dalam pertanyaan, itu harus dapat mengekspresikan 3**(3**10)( 3*3*10dalam APL), yang memberikan DOMAIN ERROR di tryapl.org.
jimmy23013