Решение трех открытых проблем с остановкой Oracle


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))на достаточно сложной машине.

Очевидно, что так как невозможно запустить вашу программу, пожалуйста, предоставьте объяснение того, как она работает вместе с кодом


Это все еще нуждается в объективных критериях оценки. Кроме того, доказательство того, что псевдопрограмма работает, может быть действительно сложным.
Мистер Лама

Я сказал, что мало символов. Это проблема Codegolf.
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истинно, если reduce(n)останавливается. Другие биты loop-y >:^:()^:_, по сути, представляют собой бесконечный цикл ( >:является инкрементом, ^:может использоваться как условный и итератор), который прерывается при обнаружении сокращения Коллатца, которое не останавливается. Наконец, gвызывается, чтобы увидеть, заканчивается ли когда-либо бесконечный цикл.

Гольдбаха

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

Та же логика, по большей части, очевидная разница в том, что основной расчет в настоящее время +./@1&p:@(-p:@_1&p:). -p:@_1&p:вычисляет разницу между числом и всеми простыми числами, меньшими, чем это число, 1&p:является isPrimeфункцией и +./является логическим ИЛИ. Следовательно, если разность между числом и любым простым числом, меньшим, чем это число, также является простым, то гипотеза Гольдбаха удовлетворяется, и бесконечный цикл продолжается. Опять же, fиспользуется для окончательной проверки того, является ли указанный бесконечный цикл действительно бесконечным.

Twin Primes

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

!упаковывает этот обман вместе с печатью. результат - 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..гипотезы Гольдбаха, это правда.

код для гипотезы спаренных простых чисел "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..предположение о двойном простом верно.


Не могли бы вы также опубликовать версию об этом? (с надлежащим интервалом и некоторыми типовыми сигнатурами) Я не знал, что вы можете поместить все
столбцы

Разве тестер первичности не должен идти из [2..n-1]? (в остальном все составное)
dspyz

о, также, p проверяет на простоту или сложность?
dspyz

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

@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) говорит, сколько шагов делает последовательность Коллатца для определенного n. Он работает бесконечно, если указанная последовательность Коллатца не заканчивается.

findNonHaltingN () считает вверх, проверяя, что numCollatzSteps завершается для каждого n. findNonHaltingN завершается тогда и только тогда, когда существует n, для которого numCollatzSteps не завершается.

Таким образом, мы можем проверить, верна ли гипотеза Коллатца, проверив, что findNonHaltingN () не останавливает

isPrime (n) проверяет, является ли число простым, видя, что никакое натуральное число от 1 до n-1 не делит его

isSumOf2Primes (n) выполняет итерацию по всем натуральным числам от 2 до n-2 и проверяет, является ли хотя бы одно простым числом вместе с его дополнением

findNonSum () считает четные числа от 4 до тех пор, пока не достигнет первого числа, которое не является суммой 2 простых чисел, а затем вернет его. Если такого числа не существует, оно будет продолжаться бесконечно.

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

isSmallTwinPrime (n) возвращает true тогда и только тогда, когда n и n + 2 являются простыми

nextSmallTwinPrime (n) возвращает следующее число> = n, для которого isSmallTwinPrime имеет значение true

largeTwinPrimes () считает, что значение 2 увеличивается, проверяя, что nextSmallTwinPrime останавливается для всех n. Если когда-либо nextSmallTwinPrime не останавливается для некоторого n, то из этого следует, что самые большие двойные простые числа равны n-1 и n + 1, и мы на этом остановимся

Затем мы можем проверить правильность гипотезы двойных простых чисел, проверив, что largeTwinPrimes никогда не останавливается.


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]

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 - это число с произвольной точностью, поэтому теоретически он может хранить любое число. Конечно, на практике есть предел, но он зависит от реализации, и в вопросе говорится, что он может обрабатывать числа произвольного размера.
Маринус

Вопрос говорит, что только большие целые числа могут быть сколь угодно большими.
jimmy23013

@ user23013: у него только один тип числа
marinus

Большие целые числа обычно означают целые числа произвольной точности. Как поясняется в вопросе, он должен быть в состоянии выразить 3**(3**10)( 3*3*10в APL), что дает DOMAIN ERROR в tryapl.org.
jimmy23013
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.