Ein Satz der Zahlentheorie (für unsere Zwecke) ist eine Folge der folgenden Symbole:
0
und'
(Nachfolger) - Nachfolger bedeutet+1
also0'''' = 0 + 1 + 1 + 1 + 1 = 4
+
(Addition) und*
(Multiplikation)=
(gleich)(
und)
(Klammern)- der logische Operator
nand
(a nand b
istnot (a and b)
) forall
(der universelle Quantifizierer)v0
,v1
,v2
Usw. (Variablen)Hier ist ein Beispiel für einen Satz:
forall v1 (forall v2 (forall v3 (not (v1*v1*v1 + v2*v2*v2 = v3*v3*v3))))
Hier not x
ist die Abkürzung für x nand x
- der eigentliche Satz würde verwenden (v1*v1*v1 + v2*v2*v2 = v3*v3*v3) nand (v1*v1*v1 + v2*v2*v2 = v3*v3*v3)
, weil x nand x = not (x and x) = not x
.
Dies besagt, dass für jede Kombination von drei natürlichen Zahlen v1
, v2
und v3
es nicht der Fall ist, dass v1 3 + v2 3 = v3 3 (was aufgrund des letzten Satzes von Fermat zutreffen würde, mit Ausnahme der Tatsache, dass es 0 ^ 3 erhalten würde + 0 ^ 3 = 0 ^ 3).
Leider ist es, wie Gödel bewiesen hat, nicht möglich festzustellen, ob ein Satz in der Zahlentheorie wahr ist oder nicht.
Es ist jedoch möglich, wenn wir die Menge der natürlichen Zahlen auf eine endliche Menge beschränken.
Diese Herausforderung besteht also darin, zu bestimmen, ob ein Satz der Zahlentheorie, wenn er modulo genommen wird n
, für eine positive ganze Zahl wahr ist oder nicht n
. Zum Beispiel der Satz
forall v0 (v0 * v0 * v0 = v0)
(die Aussage, dass für alle Zahlen x x 3 = x ist)
Gilt nicht für normale Rechen (zB 2 3 = 8 ≠ 2), aber ist wahr , wenn genommen Modulo 3:
0 * 0 * 0 ≡ 0 (mod 3)
1 * 1 * 1 ≡ 1 (mod 3)
2 * 2 * 2 ≡ 8 ≡ 2 (mod 3)
Eingabe- und Ausgabeformat
Die Eingabe ist ein Satz und eine positive Ganzzahl n
in einem "vernünftigen" Format. Hier einige Beispiele für sinnvolle Formate für den Satz forall v0 (v0 * v0 * v0 = v0)
in Zahlentheorie 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)"
Die Eingabe kann von stdin, einem Befehlszeilenargument, einer Datei usw. erfolgen.
Das Programm kann zwei verschiedene Ausgaben haben, um festzustellen, ob der Satz wahr ist oder nicht, z. B. kann es ausgegeben werden, yes
wenn es wahr ist und no
wenn es nicht wahr ist.
Sie müssen nicht unterstützen, dass eine Variable forall
zweimal Gegenstand einer Variablen ist , z (forall v0 (v0 = 0)) nand (forall v0 (v0 = 0))
. Sie können davon ausgehen, dass Ihre Eingabe eine gültige Syntax hat.
Testfälle
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
Dies ist Code-Golf , also versuchen Sie, Ihr Programm so kurz wie möglich zu halten!
var number
, oder sogar nur 1 + number
(so 1
wäre v0
, 2
wäre v1
usw.)
'v number
stattdessen verwenden, v number'
wenn wir die Präfix-Syntax-Option wählen?
v number
?