Thông dịch viên cho lý thuyết số, modulo n


12

Một câu của lý thuyết số (cho mục đích của chúng tôi) là một chuỗi các ký hiệu sau:

  • 0'(người kế vị) - nghĩa là người kế nhiệm +1, vì vậy0'''' = 0 + 1 + 1 + 1 + 1 = 4
  • +(bổ sung) và *(nhân)
  • = (tương đương với)
  • ()(dấu ngoặc đơn)
  • toán tử logic nand( a nand bnot (a and b))
  • forall (bộ định lượng phổ quát)
  • v0, v1, v2, Vv (biến)

    Đây là một ví dụ về một câu:

forall v1 (forall v2 (forall v3 (not (v1*v1*v1 + v2*v2*v2 = v3*v3*v3))))

Đây not xlà viết tắt cho x nand x- câu thực tế sẽ sử dụng (v1*v1*v1 + v2*v2*v2 = v3*v3*v3) nand (v1*v1*v1 + v2*v2*v2 = v3*v3*v3), bởi vì x nand x = not (x and x) = not x.

Này nói rằng đối với mỗi sự kết hợp của ba số tự nhiên v1, v2v3, nó không phải là trường hợp đó v1 3 + v2 3 = v3 3 (đó sẽ là sự thật vì Fermat cuối Định lý, ngoại trừ một thực tế rằng nó sẽ nhận được 0 ^ 3 + 0 ^ 3 = 0 ^ 3).

Thật không may, như đã được chứng minh bởi Gôdel, không thể xác định liệu một câu trong lý thuyết số có đúng hay không.

có thể, tuy nhiên, nếu chúng ta hạn chế việc tập hợp các số tự nhiên đến một tập hữu hạn.

Vì vậy, thách thức này là xác định xem một câu của lý thuyết số có đúng hay không, khi lấy modulo n , đối với một số nguyên dương n. Ví dụ: câu

forall v0 (v0 * v0 * v0 = v0)

(câu lệnh cho tất cả các số x, x 3 = x)

Là không đúng đối với số học thông thường (ví dụ 2 3 = 8 ≠ 2), nhưng đúng khi lấy modulo 3:

0 * 0 * 0 ≡ 0 (mod 3)
1 * 1 * 1 ≡ 1 (mod 3)
2 * 2 * 2 ≡ 8 ≡ 2 (mod 3)

Định dạng đầu vào và đầu ra

Đầu vào là một câu và số nguyên dương nở bất kỳ định dạng "hợp lý" nào. Dưới đây là một số ví dụ về các định dạng hợp lý cho câu forall v0 (v0 * v0 * v0 = v0)trong lý thuyết số 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)"

Đầu vào có thể từ stdin, đối số dòng lệnh, tệp, v.v.

Chương trình có thể có bất kỳ hai đầu ra riêng biệt nào cho dù câu đó có đúng hay không, ví dụ: nó có thể xuất ra yesnếu nó đúng và nonếu không.

Bạn không cần phải hỗ trợ một biến là chủ đề của forallhai lần, ví dụ (forall v0 (v0 = 0)) nand (forall v0 (v0 = 0)). Bạn có thể cho rằng đầu vào của bạn có cú pháp hợp lệ.

Các trường hợp thử nghiệm

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

Đây là , vì vậy hãy cố gắng làm cho chương trình của bạn ngắn nhất có thể!


1
Là tên biến luôn trong định dạng v number?
Jo King

1
@JoKing Họ có thể nếu bạn muốn họ be- bạn có thể sử dụng var number, hoặc thậm chí chỉ 1 + number(vì vậy 1sẽ v0, 2sẽ là v1, vv)
Leo Tenenbaum

1
@JoKing Bạn nên cho phép (về mặt lý thuyết) một số lượng biến vô hạn. Không sao nếu số lượng biến tối đa được giới hạn bởi kích thước tối đa của một số nguyên, nhưng bạn không nên có giới hạn thấp như vậy. Bạn có thể chọn một trong các định dạng đầu vào khác nếu đây là vấn đề với bạn.
Leo Tenenbaum

1
@UnrelatedString Chắc chắn, miễn là chúng có thể dài tùy ý.
Leo Tenenbaum

1
Có thể sử dụng 'v numberthay vì v number'nếu chúng ta chọn tùy chọn cú pháp tiền tố?
Ông Xcoder

Câu trả lời:


3

Python 2 , 252 236 byte

def g(n,s):
 if str(s)==s:return s.replace("'","+1")
 o,l,r=map(g,[n]*3,s);return['all((%s)for %s in range(%d))'%(r,l,n),'not((%s)*(%s))'%(l,r),'(%s)%%%d==(%s)%%%d'%(l,n,r,n),'(%s)%s(%s)'%(l,o,r)]['fn=+'.find(o)]
print eval(g(*input()))

Hãy thử trực tuyến!

Lấy đầu vào là cú pháp tiền tố lồng nhau, fthay vì forallnthay vì nand:

[3, ["f", "v0", ["=", ["*", "v0", ["*", "v0", "v0"]], "v0"]]]

Ngay bây giờ, nó xuất ra mã Python, nhưng nó phải có hai đầu ra riêng biệt nếu câu đó đúng hay sai. Bạn có thể sử dụng print(eval(g(*input()))).
Leo Tenenbaum

@LeoTenenbaum Vâng, tôi đã có phiên bản đầu tiên, nhưng quên thêm nó trở lại sau khi chơi golf
TFeld

1

APL (Dyalog Unicode) , 129 byte SBCS

{x y z3↑⍵⋄7x:y×7<x5x:∧/∇¨y{⍵≡⍺⍺:⍵⍺⋄x y z3↑⍵⋄7x:⍵⋄6x:x(⍺∇y)⋄x(⍺∇⍣(5x)⊢y)(⍺∇z)}∘z¨⍳⍺⍺⋄y←∇y6x:1+yy(⍎x'+×⍲',⊂'0=⍺⍺|-')∇z}

Hãy thử trực tuyến!

Lấy cây cú pháp tiền tố như trong câu trả lời python của TFeld , nhưng sử dụng mã hóa số nguyên. Mã hóa là

plus times nand eq forall succ zero  1 2 3 4 5 6 7

và mỗi biến được gán một số bắt đầu từ 8. Mã hóa này hơi khác so với mã được sử dụng trong phiên bản không được chỉnh sửa bên dưới, vì tôi đã điều chỉnh nó trong khi đánh mã.

Nhiệm vụ chỉ liên quan đến hai đầu vào (AST và modulo), nhưng viết nó dưới dạng toán tử thay vì hàm tránh đề cập đến modulo nhiều lần (vì nó luôn được thực hiện qua các cuộc gọi đệ quy).

Ung dung với ý kiến

 node types; anything 8 will be considered a var
plus times eq nand forall succ zero var←⍳8
 AST nodes have 1~3 length, 1st being the node type
 zero  zero, succ  succ arg, var  var | var value (respectively)

 to (from replace) AST  transform AST so that 'from' var has the value 'to' attached
replace←{
  ⍵≡⍺⍺:⍵⍺              variable found, attach the value
  x y z3↑⍵
  zerox:             zero or different variable: keep as is
  succx: x(⍺∇y)       succ: propagate to y
  forallx: x y(⍺∇z)   forall: propagate to z
  x(⍺∇y)(⍺∇z)          plus, times, eq, nand: propagate to both args
}
 (mod eval) AST  evaluate AST with the given modulo
eval←{
  x y z3↑⍵
  zerox:   0
  varx:    y                     return attached value
  forallx: ∧/∇¨y replacez¨⍳⍺⍺   check all replacements for given var
  succx:   1+∇y
  plusx:   (∇y)+∇z
  timesx:  (∇y)×∇z
  eqx:     0=⍺⍺|(∇y)-∇z          modulo equality
  nandx:   (∇y)⍲∇z               nand symbol does nand operation
}

Hãy thử trực tuyến!

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.