Una frase di teoria dei numeri (per i nostri scopi) è una sequenza dei seguenti simboli:
0
e'
(successore) - successore significa+1
, quindi0'''' = 0 + 1 + 1 + 1 + 1 = 4
+
(addizione) e*
(moltiplicazione)=
(uguale a)(
e)
(parentesi)- l'operatore logico
nand
(a nand b
ènot (a and b)
) forall
(il quantificatore universale)v0
,v1
,v2
, Ecc (variabili)Ecco un esempio di una frase:
forall v1 (forall v2 (forall v3 (not (v1*v1*v1 + v2*v2*v2 = v3*v3*v3))))
Ecco not x
una scorciatoia per x nand x
- la frase vera e propria userebbe (v1*v1*v1 + v2*v2*v2 = v3*v3*v3) nand (v1*v1*v1 + v2*v2*v2 = v3*v3*v3)
, perché x nand x = not (x and x) = not x
.
Tale accordo prevede che per ogni combinazione di tre numeri naturali v1
, v2
e v3
, non è il caso che v1 3 + v2 3 = v3 3 (che sarebbe la vera causa di ultimo teorema di Fermat, tranne per il fatto che avrebbe ottenuto 0 ^ 3 + 0 ^ 3 = 0 ^ 3).
Sfortunatamente, come dimostrato da Gödel, non è possibile determinare se una frase nella teoria dei numeri sia vera o meno.
Si è possibile, tuttavia, se limitiamo l'insieme dei numeri naturali per un insieme finito.
Quindi, questa sfida è determinare se una frase della teoria dei numeri è vera, se presa modulo n
, per un numero intero positivo n
. Ad esempio, la frase
forall v0 (v0 * v0 * v0 = v0)
(l'affermazione che per tutti i numeri x, x 3 = x)
Non è vero per l'aritmetica ordinaria (ad es. 2 3 = 8 ≠ 2), ma è vero se assunto modulo 3:
0 * 0 * 0 ≡ 0 (mod 3)
1 * 1 * 1 ≡ 1 (mod 3)
2 * 2 * 2 ≡ 8 ≡ 2 (mod 3)
Formato di input e output
L'input è una frase e un numero intero positivo n
in qualsiasi formato "ragionevole". Ecco alcuni esempi di formati ragionevoli per la frase forall v0 (v0 * v0 * v0 = v0)
nella teoria dei numeri modulo 3:
("forall v0 (v0 * v0 * v0 = v0)", 3)
"3:forall v0 (((v0 * v0) * v0) = v0)"
"(forall v0)(((v0 * v0) * v0) = v0) mod 3"
[3, "forall", "v0", "(", "(", "(", "v0", "*", "v0", ")", "*", "v0", ")", "=", "v0", ")"]
(3, [8, 9, 5, 5, 5, 9, 3, 9, 6, 3, 9, 6, 4, 9, 6]) (the sentence above, but with each symbol replaced with a unique number)
"f v0 = * * v0 v0 v0 v0"
[3, ["forall", "v0", ["=", ["*", "v0", ["*", "v0", "v0"]], "v0"]]]
"3.v0((v0 * (v0 * v0)) = v0)"
L'input può provenire da stdin, un argomento della riga di comando, un file, ecc.
Il programma può avere due output distinti per stabilire se la frase è vera o meno, ad esempio potrebbe generare yes
se è vera e no
se non lo è.
Non è necessario supportare una variabile essendo oggetto di una forall
doppia, ad es (forall v0 (v0 = 0)) nand (forall v0 (v0 = 0))
. Puoi presumere che il tuo input abbia una sintassi valida.
Casi test
forall v0 (v0 * v0 * v0 = v0) mod 3
true
forall v0 (v0 * v0 * v0 = v0) mod 4
false (2 * 2 * 2 = 8 ≡ 0 mod 4)
forall v0 (v0 = 0) mod 1
true (all numbers are 0 modulo 1)
0 = 0 mod 8
true
0''' = 0 mod 3
true
0''' = 0 mod 4
false
forall v0 (v0' = v0') mod 1428374
true
forall v0 (v0 = 0) nand forall v1 (v1 = 0) mod 2
true (this is False nand False, which is true)
forall v0 ((v0 = 0 nand v0 = 0) nand ((forall v1 (v0 * v1 = 0' nand v0 * v1 = 0') nand forall v2 (v0 * v2 = 0' nand v0 * v2 = 0')) nand (forall v3 (v0 * v3 = 0' nand v0 * v3 = 0') nand forall v4 (v0 * v4 = 0' nand v0 * v4 = 0')))) mod 7
true
(equivalent to "forall v0 (v0 =/= 0 implies exists v1 (v0 * v1 = 0)), which states that every number has a multiplicative inverse modulo n, which is only true if n is 1 or prime)
forall v0 ((v0 = 0 nand v0 = 0) nand ((forall v1 (v0 * v1 = 0' nand v0 * v1 = 0') nand forall v2 (v0 * v2 = 0' nand v0 * v2 = 0')) nand (forall v3 (v0 * v3 = 0' nand v0 * v3 = 0') nand forall v4 (v0 * v4 = 0' nand v0 * v4 = 0')))) mod 4
false
Questo è code-golf , quindi cerca di rendere il tuo programma il più breve possibile!
var number
, o anche solo 1 + number
(così 1
sarebbe v0
, 2
sarebbe v1
, ecc.)
'v number
invece che v number'
se scegliamo l'opzione prefisso-sintassi?
v number
?