Menguraikan simbol matematika

13

Jika Anda sudah membaca buku Kontak oleh Carl Sagan, tantangan ini mungkin terasa asing bagi Anda.


Diberikan input dari seperangkat persamaan matematika yang terdiri dari angka, operator yang tidak dikenal, nomor lain, dan hasil, menyimpulkan operator mana yang mewakili penambahan, pengurangan, perkalian, atau pembagian.

Setiap persamaan input akan selalu terdiri dari

  • bilangan bulat non-negatif
  • salah satu surat A, B, C, atauD
  • bilangan bulat non-negatif lainnya
  • karakter =
  • bilangan bulat non-negatif akhir

digabungkan bersama. Misalnya, input yang mungkin adalah 1A2=3, dari mana Anda dapat menyimpulkan yang Amewakili penambahan. Setiap bilangan bulat akan memuaskan 0 ≤ x ≤ 1,000.

Namun, tidak selalu sesederhana itu. Dimungkinkan adanya ambiguitas antara:

  • 5A0=5: penambahan / pengurangan
  • 1A1=1: perkalian / pembagian
  • 0A5=0: perkalian / pembagian
  • 2A2=4: penambahan / perkalian
  • 4A2=2: pengurangan / pembagian
  • 0A0=0: penambahan / pengurangan / perkalian

dan seterusnya. Tantangannya adalah menggunakan kemampuan ini untuk mempersempit pilihan, dikombinasikan dengan proses eliminasi, untuk mengetahui apa yang diwakili oleh setiap huruf. (Akan selalu ada setidaknya satu persamaan input, dan akan selalu memungkinkan untuk secara tidak ambigu mencocokkan secara unik setiap huruf yang digunakan dalam input dengan satu operator.)

Sebagai contoh, katakanlah input adalah persamaan berikut:

  • 0A0=0: this mempersempit A ke penjumlahan, pengurangan, atau perkalian (tidak dapat dibagi dengan 0).
  • 10B0=10: B harus berupa penambahan atau pengurangan.
  • 5C5=10: C jelas merupakan penambahan, yang membuat pengurangan B, yang membuat perkalian A.

Oleh karena itu, output untuk persamaan input ini harus sesuai Adengan *, B dengan -, danC dengan +.

Input dapat diberikan sebagai string spasi-tunggal / koma-dibatasi atau array string, masing-masing mewakili satu persamaan. Output dapat berupa string tunggal ( "A*B-C+"), array ( ["A*", "B-", "C+"]), atau kamus / seperti array 2D ( {"A": "*", ...}atau [["A", "*"], ...]).

Anda dapat berasumsi bahwa angka tidak akan pernah dibagi dengan angka lain yang tidak dapat dibagi oleh (jadi, Anda tidak perlu khawatir tentang apakah pembagian harus floating point atau terpotong).

Karena ini adalah , kode terpendek dalam byte akan menang.

Kasus uji:

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/
Gagang pintu
sumber
1
Apakah kita melakukan pembagian integer (terpotong)?
Martin Ender
@ MartinBüttner Anda dapat mengasumsikan bahwa tidak akan pernah ada pembagian dengan angka yang tidak menghasilkan bilangan bulat. (Diedit ke pertanyaan.)
Gagang pintu
Bisakah kita menampilkan sebagai kamus?
lirtosiast
@ThomasKwa Tentu, kamus juga merupakan output yang dapat diterima.
Gagang Pintu
Sebagian besar contoh tidak konsisten dengan " akan selalu memungkinkan untuk secara jelas, secara unik mengidentifikasi surat yang merupakan singkatan dari operator mana ", meskipun mereka konsisten dengan " akan selalu memungkinkan untuk secara jelas mengidentifikasi operator mana yang diwakili oleh setiap huruf yang digunakan dalam setiap huruf. masukan ".
Peter Taylor

Jawaban:

9

MATL , 53 byte

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

Menggunakan versi saat ini (10.1.0)

EDIT (12 Juni 2016): untuk beradaptasi dengan perubahan dalam bahasa, ganti Y}dengan gdan 1L3$)oleh Y). Tautan di bawah ini menggabungkan modifikasi tersebut

Cobalah online!

Penjelasan

Ini menguji semua kemungkinan permutasi dari empat operator dalam satu lingkaran sampai satu permutasi membuat semua persamaan menjadi benar.

Untuk menguji apakah persamaan itu benar, regex diterapkan untuk mengganti empat huruf oleh operator (dalam urutan yang ditentukan oleh permutasi saat ini), dan string dikonversi ke angka (dievaluasi). Ini memberikan array dengan jumlah sebanyak persamaan, di mana persamaan yang benar menjadi 1dan persamaan yang salah menjadi 0. Jika vektor ini hanya berisi1 nilai, kita sudah selesai.

Solusi yang ditemukan menugaskan operator ke empat huruf, tetapi tidak semuanya muncul dalam input. Jadi tes akhir dilakukan untuk membuang huruf yang tidak digunakan (dan operator yang sesuai).

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
Luis Mendo
sumber
6

Python, 278 karakter

Jawaban pertama saya pada kode golf ...

Ini hanya fungsi yang mengimplementasikan algoritma brute force, Anda menyebutnya lewat sebagai argumen string persamaan.

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
Bob
sumber
Saya tidak yakin jika bekerja, tetapi dapat Anda ganti ["A","B","C","D"]dengan list("ABCD")?
Adnan
Apa yang disarankan oleh Adnan memang berhasil. Anda juga dapat menghapus spasi di =dalam definisi l.
Alex A.
@ Adnan dan Alex A. terima kasih, saya mengedit kode.
Bob
Inilah 257 byte untuk pendekatan yang sama, ditambah lingkungan pengujian online.
Alex A.
Buat beberapa perubahan - repl.it/BfuU . Anda dapat memotong banyak byte lebih banyak dengan memilih format output yang berbeda. Solusi ini hanya berfungsi pada 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]:"")

Penjelasan

Input dan output adalah string.

Menentukan fungsi fyang berfungsi ganda sebagai fungsi rekursif untuk menghasilkan semua permutasi operator dan menguji permutasi lengkap dengan persamaan input yang digunakan 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]:"")

Uji

Tes tidak menggunakan argumen default untuk kompatibilitas browser.

pengguna81655
sumber