การแก้ปัญหาสามปัญหาที่เปิดอยู่กับ Oracle ที่หยุดทำงาน


23

คุณได้รับฟังก์ชั่น: h1 (f, * args) และ h2 (f, * args)

ทั้งสองเป็นวิธีที่กำหนดไว้แล้วสำหรับคุณ (ที่นี่เครื่องหมายดอกจันระบุจำนวนตัวแปรของการขัดแย้ง)

f คือฟังก์ชั่น * args คือรายการพารามิเตอร์ที่จะส่งผ่านไปยังฟังก์ชันนั้น

h1 ส่งคืนค่าบูลีน: เป็นจริงถ้าฟังก์ชั่น f หยุดชะงักเมื่อเรียกใช้บน * args และ False หากไม่ (สมมติว่าเครื่องที่รันอยู่จะมีเวลาและหน่วยความจำไม่สิ้นสุดและล่าม / คอมไพเลอร์สำหรับภาษาที่คุณกำลังเขียน รู้วิธีจัดการกับเวลาและหน่วยความจำไม่สิ้นสุด)

ถ้า f (* args) จะทำการเรียกไปยัง h1 หรือ h2 เสมอ h1 จะส่งข้อยกเว้น

h2 ทำตัวเหมือน h1 ยกเว้นว่าถ้า f ทำการเรียกไปยัง h1 h2 จะไม่ส่งข้อยกเว้น

ในตัวละครให้น้อยที่สุดให้เขียนโปรแกรมที่ไม่มีอินพุตและควรเอาต์พุต:

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

ขึ้นอยู่กับความถูกต้องของการคาดเดาแต่ละครั้ง

นี่คือลิงค์วิกิพีเดียที่อธิบายการคาดเดาแต่ละข้อ:

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

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

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

คุณอาจสมมติว่ามีไลบรารีจำนวนเต็มขนาดใหญ่ในภาษาใดก็ตามที่คุณเลือกใช้จะเป็นตัวแทนของเลขจำนวนเต็มขนาดใหญ่ได้สำเร็จ กล่าวอีกนัยหนึ่งเราจะถือว่าภาษา / ห้องสมุดใด ๆ ที่มีความสามารถในการแสดง3**(3**10)ยังสามารถแสดง3**(3**(3**10))บนเครื่องเนื้ออย่างเพียงพอ

เห็นได้ชัดว่าเป็นไปไม่ได้ที่จะเรียกใช้โปรแกรมของคุณโปรดให้คำอธิบายว่ามันทำงานอย่างไรพร้อมกับรหัส


สิ่งนี้ยังต้องการเกณฑ์การให้คะแนนตามวัตถุประสงค์ นอกจากนี้การพิสูจน์ว่าโปรแกรมหลอกทำงานอาจเป็นสิ่งที่ท้าทายจริงๆ
Mr. Llama

ฉันพูดถึงตัวละครน้อยที่สุด มันเป็นปัญหา codegolf
dspyz

นั่นคือขั้นตอนการให้คะแนนที่น่าสนใจสำหรับปัญหานี้ "แก้ปัญหาการคาดเดาคู่แฝดด้วยจำนวนอักขระน้อยที่สุด"
PyRulez

คนช่างเป็นคำถามที่ยอดเยี่ยม
undergroundmonorail

คำตอบ:


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

ฉันเลือกที่จะใช้fและgแทนที่h1และh2ตามความโปรดปราน; สองบรรทัดเพิ่มเติมกับ10f=:h1ตัวอักษรทั้งหมดก่อนที่จะเพียงพอที่จะสวิทช์: g=:h2,

และตรรกะที่แท้จริง:

Collatz

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

((-:`>:@*&3)^:(~:&1))^:_เป็นเนื้อของมัน; while (x != 1) x = collatz(x)มันเป็นหลักห่วงที่ไม่ ถ้าเราเรียกประโยคนั้นว่าreduce:

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

reduce&fมีขึ้นเพื่อเป็นคำกริยา monadic (ดูปลาย) ที่reduce&f nเป็นจริง iff reduce(n)หยุด ส่วนวง y-y อื่น ๆ>:^:()^:_เป็นวง infinite ( >:เป็นการเพิ่มขึ้น^:สามารถใช้เป็นเงื่อนไขและตัววนซ้ำ) ซึ่งหยุดพักเมื่อพบกับการลด Collatz ที่ไม่หยุดชะงัก ในที่สุดgก็เรียกว่าดูว่าวงไม่สิ้นสุดเคยสิ้นสุด

Goldbach

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

ตรรกะเดียวกันส่วนใหญ่ความแตกต่างที่ชัดเจนของการคำนวณหลักคือตอนนี้ +./@1&p:@(-p:@_1&p:)ตรรกะเดียวกันส่วนใหญ่แตกต่างที่ชัดเจนเป็นหลักในการคำนวณอยู่ในขณะนี้-p:@_1&p:คำนวณความแตกต่างระหว่างตัวเลขและจำนวนเฉพาะน้อยกว่าจำนวนนั้น1&p:คือisPrimeฟังก์ชันและ+./เป็นตรรกะหรือ ดังนั้นหากความแตกต่างระหว่างจำนวนและจำนวนที่น้อยกว่านั้นเป็นจำนวนเฉพาะการคาดคะเนของ Goldbach ก็เป็นที่พึงพอใจและการวนซ้ำไม่สิ้นสุดยังคงดำเนินต่อไป อีกครั้งfใช้ในการทดสอบขั้นสุดท้ายว่าวง infinite กล่าวว่าอนันต์อย่างแท้จริง

Twin Primes

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

(4&p:)^:(2&~:@(-~4&p:))เหมือนกับข้างต้นยกเว้น 4&p:ส่งคืนไพรม์ที่ใหญ่ที่สุดถัดไปหลังจากจำนวนที่กำหนด-~4&p:ส่งคืนความแตกต่างระหว่างตัวเลขและจำนวนที่มากที่สุดถัดไปหลังจากนั้น เป็น2&~: ดังนั้นห่วงสุดคือการที่คล้ายคลึงกัน!= 2while (nextPrimeAfter(p) - p != 2) p = nextPrimeAfter(p)

หมายเหตุ

อาจมีข้อผิดพลาดทางไวยากรณ์เนื่องจากฉันไม่ได้ทดสอบด้วยตัวจำลองfและgยัง นอกจากนี้ฉันคิดว่าfและgจะใช้รูปแบบที่สามารถประกอบด้วยกริยาทางด้านซ้ายและคำนามทางด้านขวาซึ่งฉันไม่แน่ใจว่าจะปฏิบัติตามไวยากรณ์ J ในทางใดทางหนึ่ง ฟังก์ชั่นการสั่งซื้อที่สูงขึ้นโดยเนื้อแท้และฉันเหนื่อยเกินกว่าจะค้นหาสิ่งก่อสร้างที่เหมาะสมในฐานะคำวิเศษณ์ / คำสันธาน / สิ่งที่คุณมีในขณะนี้หากมีสิ่งก่อสร้างที่เหมาะสม

ฉันไม่ได้ใช้การเรียงสตริงที่เหมาะสมจริง ๆ และเลือกที่จะปล่อยสตริงแต่ละสตริงไว้แทน ผลลัพธ์ (สมมติว่าถูกต้องทั้งหมด) จึงเป็นตารางคอลัมน์ 3 คอลัมน์ที่มีคอลัมน์ด้านซ้ายคือ "The Collatz" ฯลฯ คอลัมน์กลางที่เป็น "การคาดคะเนคือ" และคอลัมน์ด้านขวา "True" / "False" .

ฉันค่อนข้างมั่นใจว่า J จะไม่แปลงจำนวนเต็มไปเป็นความแม่นยำตามอำเภอใจตามค่าเริ่มต้นและฟังก์ชั่นยูทิลิตี้หมายเลขเฉพาะที่สำคัญp:ไม่มีโดเมนขนาดใหญ่โดยพลการ ในอีกทางหนึ่งเนื่องจาก J สนับสนุนประเภทหมายเลขความแม่นยำมาตรฐานฉันไม่แน่ใจว่าต้องใช้ความพยายามมากเพียงใดในการรับโค้ดนี้


ดังนั้นมันรองรับความแม่นยำตามอำเภอใจใช่ไหม? ฉันคิดว่าการทดสอบที่สำคัญสามารถแก้ไขได้ง่ายเหมือนคำตอบ APL
jimmy23013

ตั้งแต่ที่ฉันเขียนไปแล้วในเกณฑ์ความโปรดปราน (สำหรับ CJam) ฉันคิดว่าฉันจะทำตามกฎและให้รางวัลคำตอบ Haskell ... แต่ +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]

เพราะในตัวแปร Haskell สามารถมีค่าไม่เพียง แต่การคำนวณ (นี้เรียกว่าความเกียจคร้าน) ฉันปล่อยให้ตัวเองh1, h2โต้เถียงและกลับสภาพอากาศหรือการประเมินจะหยุด

รหัสที่ค่อนข้างไม่ดีนัก:

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

คำอธิบายเล็กน้อย:

เมื่อallนำไปใช้กับรายการที่ไม่มีที่สิ้นสุดมันจะหยุดถ้าหนึ่งในองค์ประกอบของรายการคือFalseเนื่องจากความเกียจคร้าน (ลัดวงจรสำหรับคนที่ไม่ใช่ Haskell ทั้งหมด) เราใช้สิ่งนี้เพื่อคำนวณการคาดคะเนโคลลาตซ์และการคาดคะเนจำนวนเฉพาะคู่

!บรรจุกลอุบายนี้พร้อมกับการพิมพ์ ผลที่ได้คือTrueเมื่อสิ้นสุดบนตัวเลขทั้งหมดf 4..(สิ่งนี้ไม่สำคัญสำหรับการคาดคะเน collatz หรือการคาดคะเนช่วงเวลาสองช่วงเพราะเรารู้แล้วว่ามันเป็นเรื่องจริงสำหรับจำนวนน้อยเช่นนั้น)

รหัสสำหรับการคาดเดา Collatz "The Collatz"!cคือ มันพิมพ์ "การ Collatz คาดเดาคือ" และผลที่ได้ซึ่งเป็นสภาพอากาศที่สิ้นสุดในตัวเลขทั้งหมดc4..

รหัสสำหรับการคาดเดา Goldbach "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]เป็นฟังก์ชั่นที่ได้รับnถ้าเป็นผลรวมของสองช่วงเวลาผลตอบแทนTrueแต่เป็นอย่างอื่นลูปไปเรื่อย ๆ ดังนั้นถ้ามันหยุดสำหรับ4..การคาดคะเนของ goldbach ทุกคนจะเป็นจริง

"The Twin Primes"! \n->or[p$r+2|r<-[n..],p r]รหัสสำหรับจำนวนเฉพาะคู่คาดเดาคือ \n->or[p$r+2|r<-[n..],p r]เป็นฟังก์ชั่นที่ให้nมาหากมีจำนวนเฉพาะช่วงเวลาที่มากกว่าสองเท่าnจะส่งคืนค่า True แต่จะวนซ้ำไปเรื่อย ๆ ดังนั้นถ้ามันหยุดสำหรับ4..การคาดเดานายกรัฐมนตรีคู่ทุกคนเป็นจริง


คุณจะช่วยโพสต์เวอร์ชั่นนี้ที่ไม่ได้รับความนิยมได้ไหม? (ด้วยการเว้นวรรคที่เหมาะสมและลายเซ็นบางประเภท) ฉันไม่ทราบว่าคุณสามารถวางแท่งทั้งหมดในบรรทัดเดียวเช่นที่คุณทำสำหรับ c
dspyz

เครื่องมือทดสอบแบบดั้งเดิมไม่ควรไปจาก [2..n-1] หรือ (มิฉะนั้นทุกอย่างประกอบ)
dspyz

โอ้, เช่นกัน, p จะทดสอบสำหรับค่าดั้งเดิมหรือค่าคอมโพสิตหรือไม่?
dspyz

ฉันชอบส่วนขยายตามธรรมชาติของ Haskell: h1 พิจารณาว่าการประเมิน thunk นี้จะหยุดหรือดีกว่า h1 จะคืนค่า True สำหรับการคำนวณทั้งหมดที่ไม่ใช่ _ | _ ซึ่งจะส่งกลับค่าเท็จ (เว้นแต่การคำนวณจะใช้ h1 ในกรณีที่ผลลัพธ์ ตัวเองคือ _ | _)
dspyz

@dspyz อืม ดีจัง แต่นั่นจะช่วยให้เราดูถูกความจริงที่ว่าข้อยกเว้นนั้นเป็นพื้นและ h1 นั้นจะโยนข้อยกเว้นเมื่อมันถูกใช้อย่างไม่เหมาะสม ... ฉันสงสัยว่ามันจะมีประโยชน์อย่างไร
ภูมิใจ haskeller

3

Python (965 ตัวอักษร)

เนื่องจากคำถามของฉันไม่ได้รับความรัก ฉันโพสต์โซลูชัน (ไม่ใช่รหัสเล่นกอล์ฟ) ใน 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))

มันค่อนข้างง่าย

numCollatzSteps (n) บอกว่ามีกี่ขั้นตอนในลำดับ Collatz สำหรับ n ที่เจาะจง มันทำงานได้อย่างไม่มีที่สิ้นสุดหากกล่าวว่าลำดับ Collatz ไม่ยุติลง

findNonHaltingN () นับการตรวจสอบต่อไปว่า numCollatzSteps ยุติสำหรับทุก ๆ n findNonHaltingN ยุติหากว่ามี n ที่ numCollatzSteps ไม่สิ้นสุด

ดังนั้นเราสามารถตรวจสอบว่าการคาดคะเน Collatz เป็นจริงโดยการตรวจสอบว่า findNonHaltingN () ไม่หยุด

isPrime (n) ตรวจสอบว่าตัวเลขเป็นจำนวนเฉพาะหรือไม่โดยดูว่าไม่มีจำนวนเต็มบวกจาก 1 ถึง n-1 หาร

isSumOf2Primes (n) ทำซ้ำกับจำนวนเต็มบวกทั้งหมดระหว่าง 2 ถึง n-2 และตรวจสอบว่าอย่างน้อยหนึ่งตัวเป็นนายกพร้อมกับส่วนประกอบ

findNonSum () นับจำนวนคู่ตั้งแต่ 4 ขึ้นไปจนถึงจำนวนแรกซึ่งไม่ใช่ผลรวม 2 ช่วงจากนั้นส่งคืน หากไม่มีหมายเลขดังกล่าวจะมีการดำเนินการต่อไปเรื่อย ๆ

เราสามารถตรวจสอบว่าการคาดคะเนของ Goldbach เป็นจริงหรือไม่โดยการเห็นว่า findNonSum ไม่หยุดชะงัก

isSmallTwinPrime (n) จะคืนค่าจริงถ้าหาก n และ n + 2 เป็นไพรม์ทั้งคู่

nextSmallTwinPrime (n) ส่งคืนหมายเลขถัดไป> = n ซึ่ง isSmallTwinPrime เป็นจริง

hugeTwinPrimes () นับขึ้นจาก 2 การตรวจสอบว่า nextSmallTwinPrime หยุดการทำงานของ n ทั้งหมด ถ้าครั้งต่อไปขนาดเล็ก TwinPrime ไม่หยุดสำหรับบาง n แล้วมันก็ตามมาว่าค่าแฝดที่ใหญ่ที่สุดคือ n-1 และ n + 1 และเราหยุดตรงนั้น

จากนั้นเราสามารถตรวจสอบความถูกต้องของการคาดเดาช่วงเวลาสองครั้งได้โดยตรวจสอบว่า TwinPrimes ที่ใหญ่ที่สุดไม่เคยหยุดนิ่ง


3

APL (234)

เห็นได้ชัดว่ามันไม่ได้ทดสอบ แต่ตรรกะดูเหมือนเสียง พิมพ์คำสั่งจะถูกรวมทั้งหมดออกเป็นตัวอักษรและตรรกะที่เกิดขึ้นจริง104130

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]

แต่ APL รองรับจำนวนเต็มขนาดใหญ่หรือไม่
jimmy23013

@ user23013: ตามทฤษฎีแล้วรูปแบบตัวเลขของ APL นั้นเป็นทศนิยมที่มีความแม่นยำตามอำเภอใจดังนั้นในทางทฤษฎีแล้วมันสามารถเก็บตัวเลขใด ๆ ได้ แน่นอนว่าในทางปฏิบัติมีข้อ จำกัด แต่ขึ้นอยู่กับการนำไปใช้และคำถามบอกว่าสมมติว่าสามารถจัดการกับขนาดที่กำหนดเองได้
marinus

คำถามบอกว่ามีเพียงจำนวนเต็มขนาดใหญ่เท่านั้นที่สามารถมีขนาดใหญ่ได้
jimmy23013

@ user23013: มันมีเพียงประเภทหมายเลขเดียว
marinus

จำนวนเต็มขนาดใหญ่มักจะหมายถึงจำนวนเต็มความแม่นยำโดยพลการ ตามที่ได้อธิบายไว้ในคำถามก็ควรจะสามารถแสดง3**(3**10)( 3*3*10ใน APL) ซึ่งให้ข้อผิดพลาด DOMAIN ใน tryapl.org
jimmy23013
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.