Une phrase de la théorie des nombres (pour nos besoins) est une séquence des symboles suivants:
0
et'
(successeur) - successeur signifie+1
, donc0'''' = 0 + 1 + 1 + 1 + 1 = 4
+
(addition) et*
(multiplication)=
(égal à)(
et)
(parenthèses)- l'opérateur logique
nand
(a nand b
estnot (a and b)
) forall
(le quantificateur universel)v0
,v1
,v2
, Etc. (variables)Voici un exemple de phrase:
forall v1 (forall v2 (forall v3 (not (v1*v1*v1 + v2*v2*v2 = v3*v3*v3))))
Voici un not x
raccourci pour x nand x
- la phrase réelle utiliserait (v1*v1*v1 + v2*v2*v2 = v3*v3*v3) nand (v1*v1*v1 + v2*v2*v2 = v3*v3*v3)
, car x nand x = not (x and x) = not x
.
Cet article stipule que pour chaque combinaison de trois nombres naturels v1
, v2
et v3
, il est pas le cas que v1 3 + v2 3 = v3 3 ( ce qui serait vrai à cause du dernier théorème de Fermat, à l' exception du fait qu'il obtiendrait 0 ^ 3 + 0 ^ 3 = 0 ^ 3).
Malheureusement, comme l'a prouvé Gödel, il n'est pas possible de déterminer si une phrase de la théorie des nombres est vraie ou non.
Il est possible, cependant, si nous limitons l'ensemble des nombres naturels à un ensemble fini.
Donc, ce défi consiste à déterminer si une phrase de la théorie des nombres est vraie, lorsqu'elle est prise modulo n
, pour un entier positif n
. Par exemple, la phrase
forall v0 (v0 * v0 * v0 = v0)
(la déclaration que pour tous les nombres x, x 3 = x)
N'est pas vrai pour l'arithmétique ordinaire (par exemple 2 3 = 8 ≠ 2), mais est vrai lorsqu'il est pris modulo 3:
0 * 0 * 0 ≡ 0 (mod 3)
1 * 1 * 1 ≡ 1 (mod 3)
2 * 2 * 2 ≡ 8 ≡ 2 (mod 3)
Format d'entrée et de sortie
L'entrée est une phrase et un entier positif n
dans n'importe quel format "raisonnable". Voici quelques exemples de formats raisonnables pour la phrase forall v0 (v0 * v0 * v0 = v0)
dans la théorie des nombres 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'entrée peut provenir de stdin, d'un argument de ligne de commande, d'un fichier, etc.
Le programme peut avoir deux sorties distinctes pour savoir si la phrase est vraie ou non, par exemple, il pourrait sortir yes
si c'est vrai et no
si ce n'est pas le cas.
Vous n'avez pas besoin de prendre en charge une variable faisant l'objet d'un forall
double, par exemple (forall v0 (v0 = 0)) nand (forall v0 (v0 = 0))
. Vous pouvez supposer que votre entrée a une syntaxe valide.
Cas de 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
Il s'agit de code-golf , alors essayez de rendre votre programme le plus court possible!
var number
, ou même simplement 1 + number
(ce 1
serait le cas v0
, le 2
serait v1
, etc.)
'v number
place de v number'
si on choisit l'option préfixe-syntaxe?
v number
?