Lösen von drei offenen Problemen mit einem haltenden Oracle

23

Sie erhalten die Funktionen: h1 (f, * args) und h2 (f, * args)

Beides sind für Sie bereits definierte Methoden (hier kennzeichnet der Stern eine variable Anzahl von Argumenten)

f ist eine Funktion, * args ist eine Liste von Parametern, die an diese Funktion übergeben werden sollen

h1 gibt einen booleschen Wert zurück: True, wenn die Funktion f beim Aufruf von * args immer anhält, und False, wenn dies nicht der Fall ist (vorausgesetzt, der Computer hat unendlich viel Zeit und Speicher und der Interpreter / Compiler für die Sprache, in der Sie schreiben) weiß, wie man mit unendlicher Zeit und unendlichem Gedächtnis umgeht).

Wenn f (* args) jemals h1 oder h2 aufrufen würde, löst h1 eine Ausnahme aus

h2 verhält sich genauso wie h1, außer dass h2 keine Ausnahme auslöst, wenn f h1 aufruft

Schreiben Sie in möglichst wenigen Zeichen ein Programm, das keine Eingabe benötigt und ausgeben soll:

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

basierend auf der Gültigkeit jeder dieser Vermutungen.

Hier sind Wikipedia-Links, die jede der Vermutungen erklären:

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

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

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

Sie können davon ausgehen, dass jede Bibliothek mit großen Ganzzahlen in der von Ihnen gewählten Sprache beliebige große Ganzzahlen darstellen kann. Mit anderen Worten, wir gehen davon aus, dass jede Sprache / Bibliothek, die in der Lage ist, sich auszudrücken, 3**(3**10)sich auch 3**(3**(3**10))auf einer ausreichend leistungsfähigen Maschine ausdrücken kann.

Da es unmöglich ist, Ihr Programm auszuführen, erläutern Sie bitte, wie es zusammen mit dem Code funktioniert

dspyz
quelle
Dies erfordert noch ein objektives Bewertungskriterium. Es könnte auch eine echte Herausforderung sein , zu beweisen, dass das Pseudo-Programm funktioniert.
Mr. Llama
Ich sagte die wenigsten Charaktere. Es ist ein Codegolf-Problem.
Dspyz
Das ist ein interessantes Bewertungsverfahren für dieses Problem. "Lösen Sie die Twin-Prime-Vermutung mit der geringsten Anzahl von Zeichen."
PyRulez
Mann, was für eine coole Frage
Undergroundmonorail

Antworten:

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

Ich entschied mich für fund ganstelle von h1und h2, wie es der Gabe entsprach. Zum Umschalten genügen zwei zusätzliche Zeilen mit insgesamt 10 Zeichen vor: f=:h1, g=:h2.

Und die eigentliche Logik:

Collatz

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

((-:`>:@*&3)^:(~:&1))^:_ist das Fleisch davon; Es ist im Wesentlichen eine Schleife, die tut while (x != 1) x = collatz(x). Wenn wir diesen Satz nennen reduce:

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

reduce&fsoll ein monadisches Verb sein (siehe Ende), wo reduce&f nes wahr ist, wenn es reduce(n)anhält. Die anderen Schleifen-y-Bits >:^:()^:_sind im Wesentlichen eine Endlosschleife ( >:ist Inkrement, ^:kann als Bedingung und als Iterator verwendet werden), die beim Auftreten einer Collatz-Reduktion unterbrochen wird, die nicht stoppt. Schließlich gwird aufgerufen, um zu sehen, ob die Endlosschleife jemals endet.

Goldbach

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

Die gleiche Logik zum größten Teil, der offensichtliche Unterschied, der die Kernberechnung ist, ist jetzt +./@1&p:@(-p:@_1&p:). -p:@_1&p:berechnet die Differenz zwischen einer Zahl und allen Primzahlen, die kleiner als diese Zahl sind, 1&p:ist eine isPrimeFunktion und +./ist ein logisches ODER. Wenn also die Differenz zwischen einer Zahl und einer Primzahl, die kleiner als diese Zahl ist, ebenfalls eine Primzahl ist, ist die Goldbach-Vermutung erfüllt und die Endlosschleife wird fortgesetzt. Auch fhier wird in einem abschließenden Test geprüft, ob die Endlosschleife wirklich unendlich ist.

Twin Primes

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

Wie oben, außer (4&p:)^:(2&~:@(-~4&p:)). 4&p:Gibt die nächstgrößere Primzahl nach einer bestimmten Zahl zurück. -~4&p:Gibt die Differenz zwischen einer Zahl und der nächstgrößeren Primzahl danach zurück. 2&~:ist != 2. Die innerste Schleife ist also analog zu while (nextPrimeAfter(p) - p != 2) p = nextPrimeAfter(p).

Anmerkungen

Es kann syntaktische Fehler sein, da ich nicht mit Dummy getestet haben fund gnoch. Außerdem nahm ich an, dass fund gwürde eine Form annehmen, die mit einem Verb auf der linken Seite und einem Substantiv auf der rechten Seite zusammengesetzt werden kann, wobei ich nicht sicher bin, ob die J-Grammatik in irgendeiner Weise eingehalten wird. Sie sind von Natur aus Funktionen höherer Ordnung, und ich bin zu müde, um im Moment eine richtige Konstruktion als Adverbien / Konjunktionen / Was-hast-du zu suchen, wenn es überhaupt eine solche geeignete Konstruktion gibt.

Ich habe nicht wirklich die richtige Zeichenfolgenverkettung verwendet und mich stattdessen dafür entschieden, einzelne Zeichenfolgen in einem Kästchen zu belassen. Die Ausgabe (vorausgesetzt, alles andere ist korrekt) wäre daher eine Tabelle mit 3 Spalten, wobei die linke Spalte "The Collatz" usw., die mittlere Spalte "Conjecture is" und die rechte Spalte "True" / "False" ist. .

Ich bin mir auch ziemlich sicher, dass J Ganzzahlen standardmäßig nicht in willkürliche Genauigkeit konvertiert, und die Dienstprogrammfunktion für entscheidende Primzahlen p:hat keine willkürlich große Domäne. Auf der anderen Seite bin ich mir nicht sicher, wie viel Aufwand nötig ist, um diesen Code auf den gleichen Stand zu bringen, da J einen Standardtyp mit willkürlicher Genauigkeit unterstützt.

rationalis
quelle
Unterstützt es also doch willkürliche Präzision? Ich denke, der Primetest ist wie die APL-Antwort leicht zu beheben.
Jimmy23013
Da ich das bereits in den Kopfgeldkriterien (für CJam) geschrieben habe, denke ich, dass ich die Regeln befolgen und die Haskell-Antwort vergeben werde ... Aber +1 von mir.
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]

da in Haskell Variablen nicht nur Werte enthalten können, sondern auch Berechnungen (dies wird Faulheit genannt) Ich lasse mich h1, h2ein einzelnes Argument nehmen und das Wetter zurückgeben oder nicht, es wird halt ausgewertet.

etwas ungolfed code:

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

ein bisschen Erklärung:

Wenn alles auf eine unendliche Liste angewendet wird, wird es angehalten, wenn eines der Elemente der Liste Falseaufgrund von Faulheit (Kurzschluss für alle Nicht-Haskell-Leute da draußen) ist. wir benutzen dies, um die Kollatz-Vermutung und die Zwillingsprimen-Vermutung zu berechnen.

!packt diesen Trick zusammen mit dem Drucken. Das Ergebnis ist, Truewenn falle Nummern beendet sind 4... (Dies spielt keine Rolle für die Collatz-Vermutung oder die Twin Primes-Vermutung, da wir bereits wissen, dass sie für so kleine Zahlen zutreffen).

Der Code für die Collatz-Vermutung ist "The Collatz"!c. es gibt "The Collatz Conjecture is" aus und das Ergebnis ist, dass das Wetter cbei allen Zahlen endet 4...

Der Code für die Goldbach-Vermutung ist "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]ist eine Funktion, die n, wenn es sich um eine Summe von zwei Primzahlen handelt, zurückgibt True, andernfalls aber unbegrenzt schleift. also, wenn es für jeden 4..goldbach halt macht, ist die vermutung wahr.

Der Code für die Vermutung der Doppelprimzahlen lautet "The Twin Primes"! \n->or[p$r+2|r<-[n..],p r]. \n->or[p$r+2|r<-[n..],p r]ist eine Funktion, die n, wenn es zwei Primzahlen gibt, die größer als sind n, True zurückgibt, andernfalls aber unbegrenzt Schleifen durchläuft. Wenn es also für jeden anhält, ist 4..die Twin-Prime-Vermutung wahr.

stolzer haskeller
quelle
Würde es Ihnen etwas ausmachen, auch eine ungolfed Version davon zu posten? (mit dem richtigen Abstand und einigen Typunterschriften) Ich wusste nicht, dass Sie die Balken alle auf eine Linie setzen können, wie Sie es für c
dspyz
Sollte der Primalitätstester nicht von [2.n-1] gehen? (sonst ist alles zusammengesetzt)
dspyz
oh, testet p auch auf Ursprünglichkeit oder Zusammengesetztheit?
Dspyz
Ich mag die natürliche Erweiterung von haskell: h1 bestimmt, ob die Auswertung dieses Thunks angehalten wird, oder noch besser, h1 gibt True für alle Berechnungen zurück, die nicht _ | _ sind, wobei False zurückgegeben wird (es sei denn, die Berechnung verwendet h1. In diesem Fall ergibt sich das Ergebnis selbst ist _ | _).
Dspyz
@ dspyz hmm. Das ist schön. aber das würde uns erlauben, die Tatsache zu missbrauchen, dass Ausnahmen Bottoms sind und dass h1 Ausnahmen auslöst, wenn es unsachgemäß verwendet wird ... Ich frage mich, wie nützlich das eigentlich wäre.
stolzer Haskeller
3

Python (965 Zeichen)

Da bekommt meine Frage keine Liebe. Ich poste meine (nicht mit Code versehene) Lösung in 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))

Es ist ziemlich einfach.

numCollatzSteps (n) gibt an, wie viele Schritte die Collatz-Sequenz für ein bestimmtes n dauert. Es läuft unendlich weiter, wenn die Collatz-Sequenz nicht beendet wird.

findNonHaltingN () zählt aufwärts und überprüft, ob numCollatzSteps für jedes n endet. findNonHaltingN wird genau dann beendet, wenn ein n existiert, für das numCollatzSteps nicht beendet wird.

Wir können also überprüfen, ob die Collatz-Vermutung wahr ist, indem wir überprüfen, dass findNonHaltingN () nicht anhält

isPrime (n) prüft, ob eine Zahl eine Primzahl ist, indem es sieht, dass keine positive ganze Zahl von 1 bis n-1 sie teilt

isSumOf2Primes (n) durchläuft alle positiven ganzen Zahlen zwischen 2 und n-2 und überprüft, ob mindestens eine Primzahl zusammen mit ihrem Komplement vorliegt

findNonSum () zählt gerade Zahlen von 4 aufwärts, bis es die erste Zahl erreicht, die keine Summe von 2 Primzahlen ist, und gibt sie dann zurück. Wenn keine solche Nummer existiert, wird sie unendlich fortgesetzt.

Wir können überprüfen, ob die Vermutung von Goldbach wahr ist, indem wir feststellen, dass findNonSum nicht anhält.

isSmallTwinPrime (n) gibt genau dann true zurück, wenn n und n + 2 beide Primzahlen sind

nextSmallTwinPrime (n) gibt die nächste Zahl> = n zurück, für die isSmallTwinPrime wahr ist

greatestTwinPrimes () zählt von 2 aufwärts und überprüft, ob nextSmallTwinPrime für alle n anhält. Wenn nextSmallTwinPrime jemals für einige n nicht anhält, dann folgt, dass die größten Doppelprimzahlen n-1 und n + 1 sind und wir dort anhalten

Dann können wir die Gültigkeit der Twin-Primes-Vermutung überprüfen, indem wir überprüfen, dass greatestTwinPrimes niemals anhält.

dspyz
quelle
3

APL (234)

Es ist offensichtlich nicht getestet, aber die Logik scheint gut zu sein. Druckbefehle sind alle enthalten, die Ausgabe erfolgt in 104Zeichen und die eigentliche Logik ist 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]
Marinus
quelle
Aber unterstützt APL große ganze Zahlen?
Jimmy23013
@ user23013: Theoretisch ist das Zahlenformat von APL ein Gleitkomma mit willkürlicher Genauigkeit, sodass theoretisch jede Zahl gespeichert werden kann. In der Praxis gibt es natürlich ein Limit, aber es ist implementierungsabhängig, und die Frage besagt, dass davon ausgegangen werden kann, dass es mit Zahlen beliebiger Größe umgehen kann.
Marinus
Die Frage besagt, dass nur große ganze Zahlen beliebig groß sein können.
Jimmy23013
@ User23013: Es hat nur die eine Nummer Typ
Marinus
Große Ganzzahlen bedeuten normalerweise Ganzzahlen mit willkürlicher Genauigkeit. Wie in der Frage klargestellt, sollte es in der Lage sein, 3**(3**10)( 3*3*10in APL) auszudrücken , was in tryapl.org einen DOMAIN-FEHLER ergibt.
Jimmy23013