Matematiksel sembolleri deşifre edin


13

Carl Sagan'ın Contact adlı kitabını okuduysanız , bu zorluk size tanıdık gelebilir.


Bir sayı, bilinmeyen bir operatör, başka bir sayı ve bir sonuçtan oluşan bir dizi matematiksel denklemin bir girdisi verildiğinde, hangi işleçlerin toplama, çıkarma, çarpma veya bölmeyi temsil ettiğini bulun.

Her bir giriş denklemi daima

  • negatif olmayan bir tam sayı
  • mektuplardan birini A, B, C, veyaD
  • başka bir negatif olmayan tam sayı
  • karakter =
  • negatif olmayan bir tam sayı

birlikte birleştirildi. Örneğin, toplama işlemini temsil 1A2=3edebileceğiniz olası bir giriş vardır A. Tamsayıların her biri tatmin edecektir 0 ≤ x ≤ 1,000.

Ancak, her zaman bu kadar basit değildir. Aşağıdakiler arasında belirsizlik olması mümkündür:

  • 5A0=5: Ekleme çıkarma
  • 1A1=1: çarpma / bölme
  • 0A5=0: çarpma / bölme
  • 2A2=4: toplama / çarpma
  • 4A2=2: çıkarma / bölme
  • 0A0=0: toplama / çıkarma / çarpma

ve bunun gibi. Zorluk, bu kabiliyeti, her bir mektubun hangi operatörü temsil ettiğini bulmak için eleme süreci ile birlikte seçenekleri daraltmaktır. (Her zaman en az bir giriş denklemi olacaktır ve girişte kullanılan her bir harfi tek bir operatörle açık, benzersiz bir şekilde eşleştirmek her zaman mümkün olacaktır.)

Örneğin, girdinin aşağıdaki denklemler olduğunu varsayalım:

  • 0A0=0: Bu A'yı toplama, çıkarma veya çarpmaya daraltır (0'a bölünemez).
  • 10B0=10: B, toplama veya çıkarma olmalıdır.
  • 5C5=10: C, B çarpımını yapan, A çarpımını yapan açıkça toplamadır.

Bu nedenle, bu giriş denklemler için çıkış eşleşmesi gerekir Aile *, B birlikte -ve Cbirlikte +.

Girdi, tek bir boşluk / virgülle ayrılmış dize veya her biri bir denklemi temsil eden bir dize dizisi olarak verilebilir. Çıktı, tek bir dize ( "A*B-C+"), bir dizi ( ["A*", "B-", "C+"]) veya sözlük / dikte benzeri bir 2D dizi ( {"A": "*", ...}veya [["A", "*"], ...]) olabilir.

Bir sayının hiçbir zaman bölünemeyeceği başka bir sayıya bölünmeyeceğini varsayabilirsiniz (bu nedenle, bölünmenin kayan nokta veya kesilmesi gerekip gerekmediği konusunda endişelenmenize gerek yoktur).

Bu , bayt cinsinden en kısa kod kazanır.

Test senaryoları:

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
Tamsayı bölümü yapıyor muyuz (kesik)?
Martin Ender

@ MartinBüttner Asla bir tamsayı ile sonuçlanmayan bir sayıya bölünmeyeceğini varsayabilirsiniz. (Soru düzenlenmiştir.)
Kapı tokmağı

Sözlük olarak çıktı alabilir miyiz?
lirtosiast

@ThomasKwa Tabii, sözlük de kabul edilebilir bir çıktıdır.
Kapı tokmağı

Örneklerin çoğu, " hangi harfin hangi operatörü temsil ettiğini her zaman açık bir şekilde, benzersiz bir şekilde tanımlamak her zaman mümkün olacaktır " ile tutarsızdır , ancak " her operatörün, kullanılan her harfle temsil edildiğini açıkça tanımlamak her zaman mümkün olacaktır. giriş ".
Peter Taylor

Yanıtlar:


9

MATL , 53 bayt

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

Geçerli sürümü kullanır (10.1.0)

DÜZENLEME (12 Haziran 2016):, dil değişikliklere uyum yerine Y}göre gve 1L3$)tarafından Y). Aşağıdaki bağlantı bu değişiklikleri içerir

Çevrimiçi deneyin!

açıklama

Bu, bir permütasyon tüm denklemleri doğru yapana kadar dört operatörün olası tüm permütasyonlarını bir döngüde test eder.

Denklemlerin doğru olup olmadığını test etmek için, operatörler tarafından dört harfi değiştirmek için bir regex uygulanır (geçerli permütasyon tarafından belirlenen sırada) ve dize sayılara dönüştürülür (değerlendirilir). Bu, denklemler kadar sayıda sayı içeren bir dizi verir, buradaki doğru 1denklemler ve yanlış olan denklemler olur 0. Bu vektör yalnızca 1değerler içeriyorsa işimiz bitti.

Bulunan çözüm, operatörleri dört harfe atar, ancak bunların tümü girişte mutlaka görünmez. Bu nedenle, kullanılmayan harfleri (ve eşleşen işleçlerini) atmak için son bir test yapılır.

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

Python, 278 karakter

Kod golf üzerine ilk cevabım ...

Bu sadece bir kaba kuvvet algoritması uygulayan bir işlevdir, denklem dizesini argüman olarak geçirmeyi denirsiniz.

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

Ben eğer o inşaat emin değilim ama yerine ["A","B","C","D"]sahip list("ABCD")?
Adnan

@Adnan'ın önerdiği şey gerçekten işe yarıyor. Ayrıca =tanımındaki çevresindeki boşlukları kaldırabilirsiniz l.
Alex

@Adnan ve Alex A. teşekkürler, kodu düzenledim.
Bob

İşte aynı yaklaşım için 257 bayt artı bir çevrimiçi test ortamı.
Alex

Bazı değişiklikler yaptı - repl.it/BfuU . Farklı bir çıktı biçimi seçerek çok sayıda bayt daha kesebilirsiniz. Bu çözüm yalnızca python 3 btw ( 4A2=2 4B3=1) üzerinde çalışır .
Nabb

4

JavaScript (ES6), 213 208 bayt

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]:"")

açıklama

Giriş ve çıkış dizgidir.

fOperatörlerin tüm permütasyonlarını üretmek için özyinelemeli bir fonksiyon olarak iki katına çıkan bir fonksiyonu tanımlar ve kullanılan giriş denklemleri ile tam permütasyonları test eder 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]:"")

Ölçek

Test, tarayıcı uyumluluğu için varsayılan bağımsız değişkenler kullanmaz.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.