Пропозиція з теорії чисел (для наших цілей) являє собою послідовність наступних символів:
0
і'
(наступник) - наступник означає+1
, так0'''' = 0 + 1 + 1 + 1 + 1 = 4
+
(додавання) та*
(множення)=
(дорівнює)(
і)
(дужки)- логічний оператор
nand
(a nand b
єnot (a and b)
) forall
(універсальний кількісний показник)v0
,v1
,v2
, І т.д. (змінні)Ось приклад речення:
forall v1 (forall v2 (forall v3 (not (v1*v1*v1 + v2*v2*v2 = v3*v3*v3))))
Ось not x
скорочення x nand x
- власне речення використовує (v1*v1*v1 + v2*v2*v2 = v3*v3*v3) nand (v1*v1*v1 + v2*v2*v2 = v3*v3*v3)
, тому що x nand x = not (x and x) = not x
.
Це говорить про те, що для кожної комбінації трьох натуральних чисел v1
, v2
і v3
, це не так, що v1 3 + v2 3 = v3 3 (що було б істинним внаслідок останньої теореми Ферма, за винятком того факту, що воно отримає 0 ^ 3 + 0 ^ 3 = 0 ^ 3).
На жаль, як довів Гедель, неможливо визначити, чи є речення в теорії чисел вірним чи ні.
Це є можливим, однак, якщо ми обмежуємо безліч натуральних чисел для кінцевого безлічі.
Отже, ця задача полягає у визначенні того, чи є істинним речення теорії чисел, якщо прийняти модуль n
, для якогось додатного цілого числа n
. Наприклад, речення
forall v0 (v0 * v0 * v0 = v0)
(твердження, що для всіх чисел x, x 3 = x)
Чи не відноситься до звичайної арифметики (наприклад , 2 3 = 8 ≠ 2), але це вірно , коли береться за модулю 3:
0 * 0 * 0 ≡ 0 (mod 3)
1 * 1 * 1 ≡ 1 (mod 3)
2 * 2 * 2 ≡ 8 ≡ 2 (mod 3)
Формат вводу та виводу
Вхід - це речення та додатне ціле число n
в будь-якому "розумному" форматі. Ось кілька прикладів розумних форматів речення forall v0 (v0 * v0 * v0 = v0)
в теорії чисел за модулем 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)"
Введення даних може бути із stdin, аргументу командного рядка, файлу тощо.
Програма може мати будь-які два різних виходи щодо того, чи є пропозиція істинним чи ні, наприклад, воно може вивести, yes
якщо це правда, а no
якщо ні.
Вам не потрібно підтримувати одну змінну, яка є об'єктом forall
двічі, наприклад (forall v0 (v0 = 0)) nand (forall v0 (v0 = 0))
. Ви можете припустити, що ваш вхід має дійсний синтаксис.
Тестові справи
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
Це код-гольф , тому постарайтеся зробити свою програму якомога коротшою!
var number
, а то й просто 1 + number
(так 1
би було v0
, 2
було б v1
і т. Д.)
'v number
замість цього, v number'
якщо вибрати параметр синтаксису префікса?
v number
?