Вирішення трьох відкритих завдань за допомогою Oracle Halting


23

Вам надаються функції: h1 (f, * args) і h2 (f, * args)

Обидва - це вже визначені для вас методи (тут зірочка вказує змінну кількість аргументів)

f - функція, * args - це список параметрів, які потрібно передавати цій функції

h1 повертає булеве значення: True, якщо функція 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))на достатньо м'якій машині.

Очевидно, оскільки неможливо запустити програму, надайте пояснення, як вона працює разом із кодом


Це все ще потребує об'єктивних критеріїв оцінки. Крім того, доведення того, що псевдопрограма працює, може бути справді складним завданням.
Містер Лама

Я сказав найменше персонажів. Це проблема кодогольфа.
dspyz

Це цікава процедура оцінювання цієї проблеми. "Вирішіть гіпотезу про найменшу кількість символів."
PyRulez

чоловіче, яке цікаве питання
підземний

Відповіді:


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, як вважають щедрості; для переключення достатньо двох додаткових рядків з попередньою кількістю 10 символів: f=:h1, g=:h2.

І власне логіка:

Колац

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

((-:`>:@*&3)^:(~:&1))^:_- це м’ясо його; це, по суті, цикл, який є while (x != 1) x = collatz(x). Якщо ми називаємо це речення reduce:

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

reduce&fмається на увазі монадійне дієслово (див. кінець), де reduce&f nє істинним iff reduce(n)halts. Інші біти циклу-y >:^:()^:_, по суті, є нескінченним циклом ( >:приріст, ^:може використовуватися як умовний і ітератор), який розривається, стикаючись зі скороченням Колатца, яке не зупиняється. Нарешті g, покликано побачити, чи нескінченна петля колись припиняється.

Гольдбах

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

З тієї ж логіки, здебільшого, очевидна різниця в тому, що основний розрахунок є зараз +./@1&p:@(-p:@_1&p:). -p:@_1&p:обчислює різницю між числом і всіма простими простими числами, ніж це число, 1&p:є isPrimeфункцією і +./є логічним АБО. Отже, якщо різниця між числом і будь-яким простим числом, меншим від цього числа, також є простим, тоді гіпотеза Гольдбаха задоволена, і нескінченна петля продовжується. Знову ж таки, fвикористовується в остаточному випробуванні того, чи справді нескінченна петля справді нескінченна.

Близнюки

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

Те саме, що вище, за винятком (4&p:)^:(2&~:@(-~4&p:)). 4&p:повертає наступний найбільший простір після заданого числа. -~4&p:повертає різницю між числом і наступним найбільшим простим числом після нього. 2&~:є != 2. Отже, внутрішня петля є аналогом while (nextPrimeAfter(p) - p != 2) p = nextPrimeAfter(p).

Примітки

Там можуть бути синтаксичні помилки, так як я не тестував з соскою fі gще. Крім того, я припускав, що fі gприйме якусь форму, яку можна скласти з дієсловом зліва та іменником праворуч, що я не зовсім впевнений, що жодним чином дотримується граматики J. Їм притаманні функції вищого порядку, і я занадто втомився, щоб шукати належну конструкцію, як прислівники / сполучники / що-у вас є на даний момент, якщо навіть є така відповідна конструкція.

Я насправді не використовував належне об'єднання рядків, а замість цього вирішив залишити окремі рядки в коробці. Таким чином, вихід (якщо все інше є правильним) був би таблицею з 3 стовпцями, у лівій колонці - "Колац" тощо. Середній стовпець - "Концепція є", а правий - "Істинно" / "Неправдиво" .

Я також впевнений, що J не перетворює цілі числа в довільну точність за замовчуванням, і ключова функція простого числа p:не має довільно великого домену. З іншого боку, враховуючи, що J підтримує стандартний тип довільної точності чисельності, я не впевнений, скільки зусиль потрібно для того, щоб цей код збільшився на номінал.


Отже, чи підтримує це довільна точність? Я думаю, що простий тест легко зафіксувати, як відповідь APL.
jimmy23013

Оскільки я вже писав, що у критеріях баунті (для CJam), я думаю, я буду дотримуватися правил та нагороджувати відповідь Haskell ... Але +1 від мене.
jimmy23013

7

Хаскелл, 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застосовується до нескінченного списку, це зупинить iff один із елементів списку Falseчерез лінь (коротке замикання для всіх людей, які не мають Хаскелла там). ми використовуємо це для обчислення гіпотези Колаце та гіпотези близнюків.

!пакує цю хитрість разом із друком. результат - Trueколи fприпиняється на всіх числах 4... (це не має значення для гіпотези Колаца або гіпотези близнюків, тому що ми вже знаємо, що вони справедливі для такої невеликої кількості).

код для гіпотези Колаце "The Collatz"!c. він друкує "Концепція Колатца", і результат, який погоди cприпиняється на всіх цифрах 4...

код гіпотези Гольдбаха "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

о, також, чи перевіряє р на первинність чи складність?
dspyz

Мені подобається природне розширення haskell: h1 визначає, чи зупиниться оцінка цього грона, або ще краще, h1 повертає True для всіх обчислень, які не _ | _, де він повертає False (якщо тільки обчислення не використовує h1, в цьому випадку результат сама по собі _ | _).
dspyz

@dspyz хм. це мило. але це дозволило б нам зловживати тим фактом, що винятки - це днища, і що h1 викидає винятки, коли він неправильно використовується ... Цікаво, наскільки це було б корисно насправді.
гордий haskeller

3

Пітон (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 не закінчується.

Таким чином, ми можемо перевірити, чи справжня гіпотеза Колатца, перевіривши, чи не знайти зупинку findNonHaltingN ()

isPrime (n) перевіряє, чи є число простим, бачачи, що жодне додатне ціле число від 1 до n-1 не ділить його

isSumOf2Primes (n) здійснює ітерацію над усіма додатними цілими числами від 2 до n-2 і перевіряє, що принаймні одне є простим разом із його доповненням

findNonSum () підраховує парні числа вгору від 4, поки не досягне першого числа, яке не є сумою двох простих чисел, а потім повертає його. Якщо такої кількості немає, то вона триватиме нескінченно.

Ми можемо перевірити, чи здогадка Гольдбаха правдива, побачивши, що findNonSum не зупиняється.

isSmallTwinPrime (n) повертає значення true і тоді, і лише тоді, коли n і n + 2 є простими

nextSmallTwinPrime (n) повертає наступне число> = n, для якого isSmallTwinPrime відповідає дійсності

НайбільшийTwinPrimes () нараховує вгору від 2 перевірки, що nextSmallTwinPrime зупиняється для всіх n. Якщо колись наступнийSmallTwinPrime не зупиняється на деякому n, то випливає, що найбільші близнюки-близнюки - n-1 і n + 1, і ми зупиняємося на цьому

Тоді ми можемо перевірити обґрунтованість гіпотези близнюків, перевіривши, що найбільшийTwinPrimes ніколи не зупиняється.


3

APL (234)

Це, очевидно, не перевірено, але логіка здається здоровою. Команди друку всі включені, вихід - 104символи та фактична логіка 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]

Безголівки:

⍝ 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), що дає помилку ДОМЕНА на tryapl.org.
jimmy23013
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.