Decifrare i simboli matematici


13

Se hai letto il libro Contact di Carl Sagan, questa sfida potrebbe sembrarti familiare.


Dato un input di un insieme di equazioni matematiche costituito da un numero, un operatore sconosciuto, un altro numero e un risultato, dedurre quali operatori rappresentano addizione, sottrazione, moltiplicazione o divisione.

Ogni equazione di input sarà sempre composta da

  • un numero intero non negativo
  • una delle lettere A, B, C, oD
  • un altro numero intero non negativo
  • il personaggio =
  • un numero intero non negativo finale

concatenati insieme. Ad esempio, un possibile input è 1A2=3, dal quale è possibile dedurre che Arappresenta l'addizione. Ciascuno degli interi soddisferà 0 ≤ x ≤ 1,000.

Tuttavia, non è sempre così semplice. È possibile che ci sia ambiguità tra:

  • 5A0=5: addizione / sottrazione
  • 1A1=1: moltiplicazione / divisione
  • 0A5=0: moltiplicazione / divisione
  • 2A2=4: addizione / moltiplicazione
  • 4A2=2: sottrazione / divisione
  • 0A0=0: addizione / sottrazione / moltiplicazione

e così via. La sfida è usare questa capacità per restringere le scelte, combinate con il processo di eliminazione, per capire quale operatore rappresenta ogni lettera. (Ci sarà sempre almeno un'equazione di input e sarà sempre possibile abbinare in modo univoco e in modo univoco ogni lettera utilizzata nell'input con un singolo operatore.)

Ad esempio, supponiamo che l'input sia le seguenti equazioni:

  • 0A0=0: questo restringe A fino ad addizione, sottrazione o moltiplicazione (non può dividere per 0).
  • 10B0=10: B deve essere addizione o sottrazione.
  • 5C5=10: C è ovviamente un'aggiunta, che fa la sottrazione di B, che fa una moltiplicazione.

Pertanto, l'output per queste equazioni di input deve corrispondere Aa *, B con -e Ccon +.

L'input può essere dato come una singola stringa delimitata da spazi bianchi / virgola o una matrice di stringhe, ognuna delle quali rappresenta un'equazione. L'output può essere una stringa singola ( "A*B-C+"), un array ( ["A*", "B-", "C+"]) o un array 2D dizionario / dict ( {"A": "*", ...}o [["A", "*"], ...]).

Si può presumere che un numero non verrà mai diviso per un altro numero per il quale non è divisibile (quindi, non è necessario preoccuparsi se la divisione debba essere in virgola mobile o troncata).

Dato che si tratta di , vince il codice più breve in byte.

Casi test:

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
Stiamo facendo una divisione intera (troncata)?
Martin Ender,

@ MartinBüttner Puoi presumere che non ci sarà mai divisione per un numero che non si traduca in un numero intero. (Modificato in questione.)
Maniglia della porta

Possiamo produrre come un dizionario?
lirtosiast,

@ThomasKwa Certo, anche un dizionario è un risultato accettabile.
Maniglia della porta

La maggior parte degli esempi non sono coerenti con " sarà sempre possibile identificare in modo univoco e univoco quale lettera sta per quale operatore ", sebbene siano coerenti con " sarà sempre possibile identificare in modo univoco quale operatore è rappresentato da ciascuna lettera utilizzata nella input ".
Peter Taylor,

Risposte:


9

MATL , 53 byte

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

Utilizza la versione corrente (10.1.0)

EDIT (12 giugno 2016): adattarsi ai cambiamenti nella lingua, sostituire Y}di ge 1L3$)di Y). Il link seguente incorpora tali modifiche

Provalo online!

Spiegazione

Ciò verifica tutte le possibili permutazioni dei quattro operatori in un ciclo fino a quando una permutazione rende vere tutte le equazioni.

Per verificare se le equazioni sono vere, viene applicata una regex per sostituire le quattro lettere dagli operatori (nell'ordine dettato dalla permutazione corrente) e la stringa viene convertita in numeri (valutata). Questo dà una matrice con tanti numeri quanti equazioni, in cui diventano 1equazioni vere e diventano equazioni false 0. Se questo vettore contiene solo 1valori, abbiamo finito.

La soluzione trovata assegna gli operatori alle quattro lettere, ma non tutte appaiono necessariamente nell'input. Quindi viene eseguito un test finale per scartare le lettere non utilizzate (e i relativi operatori corrispondenti).

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 caratteri

La mia prima risposta sul codice golf ...

È solo una funzione che implementa un algoritmo di forza bruta, lo chiami passando come argomento la stringa di equazioni.

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

Non sono sicuro che funzioni, ma puoi sostituirlo ["A","B","C","D"]con list("ABCD")?
Adnan,

Ciò che @Adnan ha suggerito funziona davvero. Puoi anche rimuovere gli spazi intorno =nella definizione di l.
Alex A.

@Adnan e Alex A. grazie, ho modificato il codice.
Bob,

Ecco 257 byte per lo stesso approccio, oltre a un ambiente di test online.
Alex A.

Apportate alcune modifiche - repl.it/BfuU . Puoi tagliare molti più byte scegliendo un formato di output diverso. Questa soluzione funziona solo su 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]:"")

Spiegazione

Input e output sono stringhe.

Definisce una funzione fche funge anche da funzione ricorsiva per generare tutte le permutazioni degli operatori e verifica le permutazioni complete con le equazioni di input utilizzando 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]:"")

Test

Il test non utilizza argomenti predefiniti per la compatibilità del browser.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.