Giải mã các ký hiệu toán học


13

Nếu bạn đã đọc cuốn sách Liên hệ của Carl Sagan, thử thách này có vẻ quen thuộc với bạn.


Cho đầu vào của một tập hợp các phương trình toán học bao gồm một số, một toán tử chưa biết, một số khác và kết quả, suy ra toán tử nào biểu diễn phép cộng, phép trừ, phép nhân hoặc phép chia.

Mỗi phương trình đầu vào sẽ luôn bao gồm

  • một số nguyên không âm
  • một trong các chữ cái A, B, C, hoặcD
  • một số nguyên không âm khác
  • nhân vật =
  • một số nguyên không âm cuối cùng

liên kết với nhau. Ví dụ, một đầu vào có thể là 1A2=3, từ đó bạn có thể suy ra Ađại diện cho bổ sung. Mỗi số nguyên sẽ thỏa mãn 0 ≤ x ≤ 1,000.

Tuy nhiên, nó không phải lúc nào cũng đơn giản như vậy. Có thể có sự mơ hồ giữa:

  • 5A0=5: cộng / trừ
  • 1A1=1: nhân / chia
  • 0A5=0: nhân / chia
  • 2A2=4: cộng / nhân
  • 4A2=2: phép trừ / chia
  • 0A0=0: cộng / trừ / nhân

và như thế. Thách thức là sử dụng khả năng này để thu hẹp các lựa chọn, kết hợp với quá trình loại bỏ, để tìm ra toán tử mà mỗi chữ cái thể hiện. (Sẽ luôn có ít nhất một phương trình đầu vào và sẽ luôn luôn có thể khớp một cách rõ ràng, duy nhất khớp từng chữ cái được sử dụng trong đầu vào với một toán tử duy nhất.)

Ví dụ: giả sử đầu vào là các phương trình sau:

  • 0A0=0: điều này thu hẹp A xuống phép cộng, phép trừ hoặc phép nhân (không thể chia cho 0).
  • 10B0=10: B phải là phép cộng hoặc phép trừ.
  • 5C5=10: C rõ ràng là phép cộng, làm cho phép trừ B, tạo ra phép nhân A.

Do đó, đầu ra cho các phương trình đầu vào này phải khớp Avới *, B với -Cvới +.

Đầu vào có thể được cung cấp dưới dạng một chuỗi được phân tách bằng khoảng trắng / dấu phẩy hoặc một chuỗi các chuỗi, mỗi chuỗi đại diện cho một phương trình. Đầu ra có thể là một chuỗi đơn ( "A*B-C+"), một mảng ( ["A*", "B-", "C+"]) hoặc một mảng 2D từ điển / giống như chính tả ( {"A": "*", ...}hoặc [["A", "*"], ...]).

Bạn có thể cho rằng một số sẽ không bao giờ được chia cho một số khác mà nó không chia hết cho (vì vậy, bạn không cần phải lo lắng về việc phân chia nên là dấu phẩy động hay bị cắt cụt).

Vì đây là , mã ngắn nhất tính bằng byte sẽ thắng.

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

In                       Out
-------------------------------
0A0=0 10B0=10 5C5=10     A*B-C+
100D100=10000            D*
4A2=2 4B2=2 0A0=0        A-B/
15A0=15 4B2=2 2C2=0      A+B/C-
1A1=1 0A0=0              A*
0A0=0 2A2=4 5B0=5 2B2=4  A*B+
2A2=4 0C0=0 5B0=5 5A0=5  A+B-C*
0A1000=0 4A2=2           A/

1
Có phải chúng ta đang làm (cắt ngắn) số nguyên?
Martin Ender

@ MartinBüttner Bạn có thể cho rằng sẽ không bao giờ chia cho một số không dẫn đến một số nguyên. (Được chỉnh sửa thành câu hỏi.)
Doorknob

Chúng ta có thể xuất ra như một từ điển?
lirtosiast

@ThomasKwa Chắc chắn, một từ điển cũng là đầu ra chấp nhận được.
Doorknob

Hầu hết các ví dụ không nhất quán với " sẽ luôn luôn có thể xác định rõ ràng, duy nhất xác định chữ cái nào viết tắt cho toán tử nào ", mặc dù chúng phù hợp với " sẽ luôn luôn có thể xác định rõ ràng toán tử nào được đại diện bởi mỗi chữ cái được sử dụng trong đầu vào ".
Peter Taylor

Câu trả lời:


9

MATL , 53 byte

j61tthYX'+-*/'X{Y@!"t'ABCD'!XKX{@YXU?K@Y}hwxKGm1L3$).

Sử dụng phiên bản hiện tại (10.1.0)

EDIT (ngày 12 tháng 6 năm 2016): để thích ứng với những thay đổi trong ngôn ngữ, thay thế Y}bằng g1L3$)bởi Y). Liên kết dưới đây kết hợp những sửa đổi

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

Giải trình

Điều này kiểm tra tất cả các hoán vị có thể có của bốn toán tử trong một vòng lặp cho đến khi một hoán vị làm cho tất cả các phương trình đúng.

Để kiểm tra xem các phương trình có đúng không, một biểu thức chính được áp dụng để thay thế bốn chữ cái bởi các toán tử (theo thứ tự được xác định bởi hoán vị hiện tại) và chuỗi được chuyển đổi thành số (được đánh giá). Điều này đưa ra một mảng có nhiều số như phương trình, trong đó phương trình đúng trở thành 1và phương trình sai trở thành 0. Nếu vectơ này chỉ chứa 1các giá trị, chúng ta đã hoàn thành.

Giải pháp tìm thấy gán các toán tử cho bốn chữ cái, nhưng không phải tất cả chúng đều xuất hiện trong đầu vào. Vì vậy, một thử nghiệm cuối cùng được thực hiện để loại bỏ các chữ cái không được sử dụng (và các toán tử khớp của chúng).

j            % input data string
61           % '=' (ASCII)
tth          % duplicate twice and concat: '==' (ASCII)
YX           % regexprep to change '=' into '==' in input string
'+-*/'       % push string
X{           % transform into cell array {'+','-','*','/'}
Y@!          % all permutations, each in a column
"            % "for" loop. Iterate columns (that is, permutations)
  t          %   duplicate data string containing '=='
  'ABCD'!XK  %   create column array ['A';'B';'C';'D'] and copy to clipboard K
  X{         %   transform into column cell array {'A';'B';'C';'D'} 
  @          %   push column cell array with current permutation of operator symbols
  YX         %   regexprep. Replaces 'A',...,'D' with current permutation of operators
  U          %   convert to numbers, i.e. evaluate string
  ?          %   if all numbers are 1 (truthy result): found it! But before breaking...
    K        %     push column array ['A';'B';'C';'D']
    @Y}      %     push column array with current permutation of operator symbols
    h        %     concatenate horizontally into 4x2 char array
    wx       %     delete original input so it won't be displayed
    K        %     push ['A';'B';'C';'D']
    G        %     push input string
    m        %     logical index that tells which of 'A',...,'D' were in input string
    1L3$)    %     apply that index to select rows of the 4x2 char array
    .        %     we can now break "for" loop
             %   implicitly end "if"
             % implicitly end "for"
             % implicitly display stack contents

6

Con trăn, 278 ký tự

Câu trả lời đầu tiên của tôi về môn đánh gôn ...

Nó chỉ là một hàm thực hiện thuật toán brute force, bạn gọi nó là hàm đối số chuỗi phương trình.

from itertools import *
def f(s):
    l=list("ABCD")
    for p in permutations("+-*/"):
        t=s
        for v,w in zip(l+["="," "],list(p)+["=="," and "]):
            t=t.replace(v, w)
        try:
            o=""
            if eval(t):
                for c,r in zip(l,p):
                    if c in s:
                        o+=c+r
                return o
        except:
            pass

Tôi không chắc nếu nó hoạt động, nhưng bạn có thể thay thế ["A","B","C","D"]bằng list("ABCD")?
Ad Nam

Những gì @Adnan đề xuất thực sự hoạt động. Bạn cũng có thể loại bỏ các khoảng trống xung quanh =trong định nghĩa của l.
Alex A.

@Adnan và Alex A. cảm ơn, tôi đã chỉnh sửa mã.
Bob

Dưới đây là 256 byte cho cùng một cách tiếp cận, cộng với môi trường thử nghiệm trực tuyến.
Alex A.

Thực hiện một số thay đổi - repl.it/BfuU . Bạn có thể cắt nhiều byte hơn bằng cách chọn một định dạng đầu ra khác. Giải pháp này chỉ hoạt động trên python 3 btw ( 4A2=2 4B3=1).
Nabb

4

JavaScript (ES6), 213 208 byte

f=(l,s="+-*/",p="",r)=>s?[...s].map(o=>r=f(l,s[g="replace"](o,""),p+o)||r)&&r:l.split` `.every(x=>(q=x.split`=`)[1]==eval(q[0][g](/[A-D]/g,m=>p[(a="ABCD").search(m)])))&&a[g](/./g,(c,i)=>l.match(c)?c+p[i]:"")

Giải trình

Đầu vào và đầu ra là các chuỗi.

Xác định một hàm nhân fđôi như một hàm đệ quy để tạo ra tất cả các hoán vị của các toán tử và kiểm tra các hoán vị hoàn chỉnh với các phương trình đầu vào sử dụng eval.

f=(
  l,                          // l = input expression string
  s="+-*/",                   // s = remaining operators
  p="",                       // p = current permutation of operators
  r                           // r is here so it is defined locally
)=>
  s?                          // if there are remaining operators
    [...s].map(o=>            // add each operator o
      r=f(
        l,
        s[g="replace"](o,""), // remove it from the list of remaining operators
        p+o                   // add it to the permutation
      )
        ||r                   // r = the output of any permutation (if it has output)
    )
    &&r                       // return r
  :                           // else if there are no remaining operators
    l.split` `.every(x=>      // for each expression
      (q=x.split`=`)          // q = [ equation, result ]
      [1]==eval(              // if the results is equal to the eval result

        // Replace each letter with the current permutation
        q[0][g](/[A-D]/g,m=>p[(a="ABCD").search(m)])
      )
    )

    // If all results matched, add permutation symbols to present characters and return
    &&a[g](/./g,(c,i)=>l.match(c)?c+p[i]:"")

Kiểm tra

Kiểm tra không sử dụng các đối số mặc định cho khả năng tương thích trình duyệt.

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.