Risolvere tre problemi aperti con un arresto di Oracle


23

Ti vengono date le funzioni: h1 (f, * args) e h2 (f, * args)

Entrambi sono metodi che sono già definiti per te (qui l'asterisco indica un numero variabile di argomenti)

f è una funzione, * args è un elenco di parametri da passare a quella funzione

h1 restituisce un valore booleano: True se la funzione f si interrompe mai quando viene chiamata * args e False in caso contrario (supponendo che la macchina in esecuzione abbia tempo e memoria infiniti e che l'interprete / compilatore per la lingua in cui stai scrivendo sa come gestire il tempo e la memoria infiniti).

Se f (* args) fa mai una chiamata a h1 o h2, h1 genera un'eccezione

h2 si comporta esattamente come h1 tranne per il fatto che se f chiama a h1, allora h2 non genererà un'eccezione

Nel minor numero di caratteri possibile, scrivi un programma che non accetta input e che dovrebbe produrre:

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

basato sulla validità di ciascuna di queste congetture.

Ecco i link di Wikipedia che spiegano ciascuna delle congetture:

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

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

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

Puoi presumere che qualsiasi libreria di interi di grandi dimensioni in qualunque lingua tu scelga di utilizzare rappresenterà correttamente interi di grandi dimensioni arbitrari. In altre parole, assumeremo che qualsiasi linguaggio / libreria in grado di esprimere 3**(3**10)sia anche in grado di esprimere 3**(3**(3**10))su una macchina sufficientemente robusta.

Ovviamente, poiché è impossibile eseguire il programma, fornire una spiegazione di come funziona insieme al codice


Ciò ha ancora bisogno di criteri di punteggio oggettivi. Inoltre, provare che lo pseudo-programma funziona potrebbe essere davvero impegnativo.
Mr. Llama,

Ho detto meno personaggi. È un problema di codegolf.
dspyz,

Questa è una procedura interessante e di punteggio per questo problema. "Risolvi la congettura dei gemelli primi nel minor numero di personaggi."
PyRulez

amico, che bella domanda
undergroundmonorail,

Risposte:


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

Ho scelto di usare fe gal posto di h1e h2, come secondo la generosità; due righe aggiuntive con 10 caratteri totali prima sono sufficienti per cambiare: f=:h1, g=:h2.

E la logica attuale:

Collatz

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

((-:`>:@*&3)^:(~:&1))^:_ne è la carne; è essenzialmente un ciclo che lo fa while (x != 1) x = collatz(x). Se chiamiamo quella frase reduce:

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

reduce&fè pensato per essere un verbo monadico (vedi fine), dove reduce&f nè vero iff si reduce(n)ferma. Gli altri bit loop-y >:^:()^:_, sono essenzialmente un loop infinito ( >:è incrementale, ^:può essere usato come condizionale e iteratore) che si interrompe incontrando una riduzione di Collatz che non si ferma. Alla fine gviene chiamato per vedere se il ciclo infinito termina mai.

Goldbach

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

La stessa logica, per la maggior parte, l'ovvia differenza è il calcolo di base è ora +./@1&p:@(-p:@_1&p:). -p:@_1&p:calcola la differenza tra un numero e tutti i numeri primi inferiori a quel numero, 1&p:è una isPrimefunzione ed +./è OR logico. Quindi, se la differenza tra un numero e un numero primo inferiore a quel numero è anche un numero primo, allora la congettura di Goldbach è soddisfatta e il ciclo infinito continua. Ancora una volta, fviene utilizzato in un test finale per stabilire se detto loop infinito è veramente infinito.

Twin Primes

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

Come sopra, eccetto (4&p:)^:(2&~:@(-~4&p:)). 4&p:restituisce il primo primo più grande dopo un determinato numero. -~4&p:restituisce la differenza tra un numero e il primo più grande successivo dopo di esso. 2&~:lo è != 2. Quindi il ciclo più interno è analogo a while (nextPrimeAfter(p) - p != 2) p = nextPrimeAfter(p).

Gli appunti

Ci possono essere errori sintattici, dal momento che non ho ancora testato con il manichino fe gancora. Inoltre, ho supposto che fe gprenderei una sorta di forma che può essere composto con un verbo a sinistra e un sostantivo sulla destra, che io non sono completamente sicuro aderisce alla grammatica J in alcun modo. Sono funzioni intrinsecamente di ordine superiore, e sono troppo stanco per cercare una corretta costruzione come avverbi / congiunzioni / che-cosa-hai al momento, se esiste anche un costrutto così appropriato.

In realtà non ho usato la concatenazione di stringhe corretta, ma ho optato per lasciare le singole stringhe in scatola. L'output (supponendo che tutto il resto sia corretto) sarebbe quindi una tabella a 3 colonne, con la colonna di sinistra "The Collatz", ecc., La colonna di mezzo è "Congettura è" e la colonna di destra "Vero" / "Falso" .

Sono anche abbastanza sicuro che J non converta i numeri interi in precisione arbitraria per impostazione predefinita, e la funzione di utilità del numero primo cruciale p:non ha un dominio arbitrariamente grande. D'altra parte, dato che J supporta un tipo di numero di precisione arbitraria standard, non sono sicuro di quanto sforzo sarebbe necessario per riportare questo codice alla pari.


Dopotutto, supporta la precisione arbitraria? Penso che il primo test sia facilmente risolvibile come la risposta APL.
jimmy23013,

Dato che l'ho già scritto nei criteri di generosità (per CJam), penso che seguirò le regole e assegnerò la risposta di Haskell ... Ma +1 da parte mia.
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]

perché in Haskell le variabili possono contenere non solo valori, ma calcoli (questo si chiama pigrizia) Mi lascio h1, h2prendere un singolo argomento e restituire il tempo o no la sua valutazione si interromperà.

codice un po 'non golfato:

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

un po 'di spiegazione:

quando allviene applicato a un elenco infinito, si interrompe se uno degli elementi dell'elenco è False, a causa della pigrizia (cortocircuito, per tutte le persone non Haskell là fuori). usiamo questo per calcolare la congettura di collatz e la congettura di numeri primi gemelli.

!confeziona questo inganno insieme alla stampa. il risultato è Truequando ftermina su tutti i numeri 4... (questo non ha importanza per la congettura di collatz o la congettura dei numeri primi gemelli, perché sappiamo già che sono veri per numeri così piccoli).

il codice per la congettura collatz è "The Collatz"!c. stampa "La congettura di Collatz è" e il risultato, che è il tempo, ctermina su tutti i numeri 4...

il codice per la congettura di 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]è una funzione che data n, se è una somma di due numeri primi, ritorna True, ma per il resto continua a ciclo indefinito. quindi, se si ferma per ogni 4..congettura di Goldbach è vera.

il codice per la congettura dei numeri primi gemelli è "The Twin Primes"! \n->or[p$r+2|r<-[n..],p r]. \n->or[p$r+2|r<-[n..],p r]è una funzione che data n, se ci sono numeri primi gemelli maggiori di n, restituisce True, ma per il resto continua a ciclo indefinito. quindi, se si ferma per ogni 4..congettura dei gemelli primi è vera.


Ti dispiacerebbe pubblicare anche una versione non giocata di questo? (con la spaziatura corretta e alcune firme di tipo) Non sapevo che avresti potuto mettere le barre tutte su una riga come hai fatto per c
dspyz il

Il tester di primalità non dovrebbe andare da [2..n-1]? (altrimenti tutto è composto)
dspyz,

oh, inoltre, p verifica la primalità o la composizione?
dspyz,

Mi piace l'estensione naturale di haskell: h1 determina se la valutazione di questo thunk si interromperà, o meglio, h1 restituisce True per tutti i calcoli che non sono _ | _ dove restituisce False (a meno che il calcolo non usi h1 nel qual caso il risultato stesso è _ | _).
dspyz,

@dspyz hmm. bello. ma ciò ci consentirebbe di abusare del fatto che le eccezioni sono i fondi e che h1 genera eccezioni quando viene utilizzato in modo improprio ... Mi chiedo quanto sarebbe effettivamente utile.
orgoglioso haskeller il

3

Python (965 caratteri)

Dal momento che la mia domanda non sta ottenendo amore. Sto pubblicando la mia soluzione (senza codice) 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))

È abbastanza semplice.

numCollatzSteps (n) indica quanti passaggi richiede la sequenza Collatz per un particolare n. Funziona all'infinito se la sequenza di Collatz non termina.

findNonHaltingN () conta verso l'alto verificando che numCollatzSteps termina per ogni n. findNonHaltingN termina se e solo se esiste un n per il quale numCollatzSteps non termina.

Quindi possiamo verificare se la congettura di Collatz è vera controllando che findNonHaltingN () non si fermi

isPrime (n) controlla se un numero è primo vedendo che nessun numero intero positivo da 1 a n-1 lo divide

isSumOf2Primes (n) scorre su tutti gli interi positivi compresi tra 2 e n-2 e verificando che almeno uno sia primo insieme al suo complemento

findNonSum () conta i numeri pari verso l'alto da 4 fino a raggiungere il primo numero che non è una somma di 2 numeri primi e quindi lo restituisce. Se non esiste un numero simile, continuerà all'infinito.

Possiamo verificare se la congettura di Goldbach è vera vedendo che findNonSum non si ferma.

isSmallTwinPrime (n) restituisce true se e solo se n e n + 2 sono entrambi primi

nextSmallTwinPrime (n) restituisce il numero successivo> = n per cui isSmallTwinPrime è true

largeTwinPrimes () conta verso l'alto da 2 controllando che nextSmallTwinPrime si interrompa per tutto n. Se mai nextSmallTwinPrime non si ferma per alcuni n, ne consegue che i primi gemelli più grandi sono n-1 e n + 1 e ci fermiamo qui

Quindi possiamo verificare la validità della congettura dei numeri primi gemelli controllando che il più grandeTwinPrimes non si fermi mai.


3

APL (234)

È ovviamente non testato, ma la logica sembra sana. I comandi di stampa sono tutti inclusi, l'output è costituito da 104caratteri e la logica effettiva è 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]

Ma APL supporta numeri interi grandi?
jimmy23013,

@ user23013: In teoria, il formato numerico di APL è un float di precisione arbitraria, quindi, in teoria, può memorizzare qualsiasi numero. Naturalmente, in pratica, esiste un limite, ma dipende dall'implementazione e la domanda dice che si presume che possa gestire numeri di dimensioni arbitrarie.
Marin il

La domanda dice che solo i grandi numeri interi possono essere arbitrariamente grandi.
jimmy23013,

@ user23013: ha solo un tipo di numero
marinus il

I numeri interi grandi di solito indicano numeri interi di precisione arbitraria. Come chiarito nella domanda, dovrebbe essere in grado di esprimere 3**(3**10)( 3*3*10in APL), che dà un ERRORE DOMINIO in tryapl.org.
jimmy23013,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.