Equazioni del matchstick


16

Il tuo compito in questa sfida è quello di analizzare una determinata "Equazione del matchstick" come questa ...

inserisci qui la descrizione dell'immagine

... e per scoprire se può essere trasformata in un'equazione valida riorganizzando le partite. In tal caso, devi produrre il minor numero di mosse per farlo e l'equazione risultante.

Ingresso

L'input è una stringa che può essere letta da STDIN, presa come argomento di funzione o addirittura memorizzata in un file. È un'equazione che rappresenta una disposizione del fiammifero e può essere descritta usando il seguente EBNF:

input = term, "=", term ;
term = number | (term, ("+" | "-"), term) ;
number = "0" | (numeralExceptZero , {numeral}) ;
numeralExceptZero = "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9" ;
numeral = "0" | numeralExceptZero ;

Un esempio per un input valido sarebbe 3+6-201=0+0+8 .

Compito

Considera la seguente illustrazione in cui a ciascun fiammifero è assegnato un numero:

posizioni del fiammifero

Ora mappiamo ciascun simbolo di input nelle posizioni corrispondenti del matchstick come segue:

0 ↦ 1,2,3,4,5,6
1 ↦ 4,5
2 ↦ 2,3,5,6,8
3 ↦ 3,4,5,6,8
4 ↦ 1,4,5,8
5 ↦ 1,3,4,6,8
6 ↦ 1,2,3,4,6,8
7 ↦ 4,5,6
8 ↦ 1,2,3,4,5,6,8
9 ↦ 1,3,4,5,6,8
- ↦ 8
+ ↦ 8,10
= ↦ 7,9

Ogni formula di input può essere trasformata in una disposizione matchstick. Ad esempio, l'equazione "45 + 6 = 92" diventa

inserisci qui la descrizione dell'immagine

dove i fiammiferi non utilizzati sono disattivati. Il tuo compito è scoprire il minor numero di fiammiferi che devono essere riorganizzati per rendere valida l'equazione.

Produzione

Distinguiamo tra tre possibili casi:

  • Se l'input non è valido (ovvero non soddisfa il suddetto EBNF), emettere tutto ciò che si desidera.
  • Altrimenti, se ci sono modi per trasformare l'equazione in valida riorganizzando i matchsticks, devi produrre sia il numero minimo di riarrangiamenti sia l'equazione corrispondente. Proprio come l'input, l'equazione emessa deve anche soddisfare il dato EBNF. Nell'esempio sopra, l'output corretto sarebbe 1e 46+6=52. Se ci sono più possibilità per l'equazione risultante, emettine una qualsiasi.
  • Altrimenti (quindi se l'input è valido ma non c'è modo di rendere vera l'equazione), devi produrre -1.

Dettagli

  • Non ti è consentito rimuovere o aggiungere corrispondenze. Ciò significa che se l'input è costituito da nfiammiferi, anche l'output deve essere costituito esattamenten fiammiferi .
  • I blocchi "matchstick" vuoti sono consentiti solo alla fine e all'inizio di un'equazione, non al centro. Così, per esempio, trasformando 7-1=6in 7 =6-1semplicemente rimuovendo -1dal lato sinistro e l'aggiunta sul lato destro con soli 3 riarrangiamenti fiammifero non è permesso.
  • Dal momento che non vedo davvero la mappatura dai numeri alle posizioni del matchstick come una parte interessante di questa sfida, per un plus di 20 byte , potresti

    • accedere a un file in cui (number/operation ↦ matchstick positions)è memorizzata la mappatura in modo ragionevole, oppure
    • se il tuo linguaggio di programmazione supporta un Maptipo di dati, supponi di avere accesso a una mappa preinizializzata con il (number/operation ↦ matchstick positions)-mapping. Ad esempio, questa mappa potrebbe apparire così:{(0,{1,2,3,4,5,6}),(1,{4,5}),(2,{2,3,5,6,8}),(3,{3,4,5,6,8}), ..., (-,{8}),(+,{8,10}),(=,{7,9})}

Esempi

Input: 1+1=3Output: 1 e1+1=2

Input: 15+6=21Output: 0 e15+6=21

Ingresso: 1=7Uscita: -1

Input: 950-250=750Output: 2 e990-240=750

Input: 1-2=9Output: 1 e1+2=3

Ingresso: 20 + 3=04Uscita: qualsiasi cosa

Vincitore

Questo è , quindi vince la risposta corretta più breve (in byte). Il vincitore verrà scelto una settimana dopo la pubblicazione della prima risposta corretta.


1
Si prega di aggiungere 0: 1, 2, 3, 4, 5, 6per coerenza
Non che Charles

Oh grazie, me ne sono completamente dimenticato in qualche modo!
vauge

@vauge Hey dovrebbe '2 = 1-1' -> '2-1 = 1' restituire 3 o 14 mosse dal momento che i 2 tecnicamente devono essere spostati a sinistra?
Cieric,

@Cieric dovrebbe restituire 3, semplicemente perché puoi cambiare la posizione di =(2 fiammiferi) e -(1 fiammifero) e lasciare tutti i numeri dove sono. Se, tuttavia, i 2 dovessero essere spostati a sinistra, dovresti anche contare le mosse richieste.
vauge

Esiste una limitazione sul numero di operazioni? L'ingresso può essere simile 1+1+2=3-6+10? E stessa domanda sull'output.
Qwertiy,

Risposte:


6

Javascript, 1069 byte

L'ho testato con alcune equazioni di test e sembra funzionare tutto il tempo ora ...

function w(t){function B(c,f){d=(c.length>f.length?f:c).split("");e=(c.length>f.length?c:f).split("");longer=Math.max(d.length,e.length);if(0!==d.length&&0!==e.length){c=[];for(x in d)for(y in c[x]=[],e)c[x][y]=1<y-x?-1:function(c,n){r=0;for(j in n)-1<c.indexOf(n[j])&&r++;return c.length+n.length-2*r}(a[d[x]],a[e[y]]);return v=function(f,n){for(var h=f.length-2;0<=h;h--)c[n.length-1][h]+=c[n.length-1][h+1];for(h=f.length-2;0<=h;h--)for(var q=0;q<n.length-1;q++)1>=h-q&&(c[q][h]+=-1==c[q][h+1]?c[q+1][h+1]:Math.min(c[q+1][h+1],c[q][h+1]));return c[0][0]/2}(e,d)}return-1}a=[[1,2,3,4,5,6],[4,5],[2,3,5,6,8],[3,4,5,6,8],[1,4,5,8],[1,3,4,6,8],[1,2,3,4,6,8],[4,5,6],[1,2,3,4,5,6,8],[1,3,4,5,6,8]];a["+"]=[8,0];a["-"]=[8];a["="]=[7,9];a[" "]=[];l=0;p=[];u=[];r=/^([1-9]\d*|0)([+-]([1-9]\d*|0))*=([1-9]\d*|0)([+-]([1-9]\d*|0))*$/;b=/(=.*=|[+=-]{2,}|^[+=-])/;if(!t.match(r))return-1;g=function(c,f,t){if(0===t&&f.match(r)&&eval(f.replace("=","==")))c.push(f);else for(var n in a)t>=a[n].length&&" "!=n&&!(f+n).match(b)&&g(c,f+n,t-a[n].length)};g(p,"",function(c){m=0;for(var f in c)m+=a[c[f]].length;return m}(t.split("")));for(var z in p)k=B(t,p[z]),u[k]||(u[k]=[]),u[k].push(p[z]);for(var A in u)return[A,u[A]];return-1}

Bene, questa è la prima volta che invio una risposta, quindi non mi vedo vincere. Questo è fondamentalmente un metodo di forza bruta per capire tutte le risposte e poi afferra e restituisce le più piccole in un array. con il primo argomento la lunghezza e il secondo un array con gli output.

se l'ingresso è "1-2 = 9" l'uscita è [1, ["1 + 2 = 3", "7-2 = 5"]]

ed ecco il codice non compresso:

function ms(s) {
a=[[1,2,3,4,5,6],[4,5],[2,3,5,6,8],[3,4,5,6,8],[1,4,5,8],[1,3,4,6,8],[1,2,3,4,6,8],[4,5,6],[1,2,3,4,5,6,8],[1,3,4,5,6,8]];
a["+"] = [8, 0];
a["-"] = [8];
a["="] = [7, 9];
a[" "] = [];
l = 0;
p = [];
u = [];
r = /^([1-9]\d*|0)([+-]([1-9]\d*|0))*=([1-9]\d*|0)([+-]([1-9]\d*|0))*$/;
b = /(=.*=|[+=-]{2,}|^[+=-])/;
if (!s.match(r)) return -1;
function f(g,h)
{
    d=(g.length>h.length?h:g).split('');
    e=(g.length>h.length?g:h).split('');
    longer=Math.max(d.length, e.length);
    if(0!==d.length&&0!==e.length)
    {
        g=[];
        for(x in d)
        {
            g[x]=[];
            for(y in e)
            {
                g[x][y]=(y-x>1)?-1:function(g, h){r=0;for(j in h)if(g.indexOf(h[j])>-1)r++;return g.length+h.length-2*r;}(a[d[x]],a[e[y]]);
            }
        }
        v=function(d,e)
        {
        for(var y=d.length-2;y>=0;y--) g[e.length-1][y]+=g[e.length-1][y+1];
        for(var y=d.length-2;y>=0;y--)
            for(var x=0;x<e.length-1;x++)
                if(y-x<=1)
                    g[x][y]+=g[x][y+1]==-1?g[x+1][y+1]:Math.min(g[x+1][y+1], g[x][y+1]);
        return g[0][0]/2}(e,d)
        return v
    }
    return -1;
}
g=function(n, s, i){if (i===0 && s.match(r) && eval(s.replace('=','=='))){n.push(s);return;}for (var c in a) if(i>=a[c].length && c!=" " && !(s+c).match(b)) g(n, s+c, i-a[c].length);};
g(p, "", function(q){m=0;for(var t in q)m+=a[q[t]].length;return m}(s.split('')));
for (var i in p)
{
    k=f(s, p[i]);
    if (!u[k]) u[k] = [];
    u[k].push(p[i]);
}
for (var q in u) return [q, u[q]];
return -1;
}

Avvertenza: non fare equazioni come 950-250 = 750 usa ~ 45 fiammiferi e poiché questo codice usa la forza bruta, si bloccherà javascript.


Credo che tu possa dichiarare le variabili che usi come var knei loop come parametri inutilizzati per la funzione, salvando 3 byte per ogni dichiarazione.
rorlork,

Penso che imparerò qualche altro linguaggio di programmazione e scoprirò un modo non così brutale per provare a buttare giù quel conto alla rovescia.
Cieric,

Penso che la tua soluzione non sia corretta, poiché quando calcoli la distanza allinea sempre i caratteri uguali. In alcuni casi non è il modo ottimale. Ad esempio '2 = 1-1' può essere trasformato in 3 mosse in '2-1 = 1', mentre l'allineamento dei segni '=' dà 14 mosse. Inoltre non vedo come evitare gli zero iniziali. Ad esempio 08=8per 80=8non è corretto.
nutki,

@nutki Sì, penso di poterlo cambiare. Stavo pensando che sarebbe sbagliato, anche se tecnicamente dovresti spostare il 2 per fare spazio al -1
Cieric

@nutki ok, sì. Scusa, capisco cosa intendi adesso. Bene, riparerò il regex e vedrò se posso cambiare il codice per la distanza di modifica.
Cieric,

1

Perl, 334

Abbastanza veloce fintanto che la soluzione è raggiungibile in 1 o 2 mosse. Quando non c'è soluzione, si è in attesa di una lunga attesa anche nel caso più piccolo di 1=7.

#!perl -p
@y=map{sprintf"%010b",$_}63,24,118,124,89,109,111,56,127,125,64,192,768;
$y{$z{$y[$c++]}=$_}=$y[$c]for 0..9,qw(- + =);
$"="|";$l=s/./$y{$&}/g;$x{$_}=1;for$m(0..y/1//){
last if$_=(map"$m $_",grep{s/@y/$z{$&}/g==$l&&/^\d.*\d$/&!/\D\D/&!/\b0\d/&y/=//==1&&eval s/=/==/r}keys%x)[0];
$_=-1;s/0/"$`1$'"=~s!1!$x{"$`0$'"}=1!ger/eg for keys%x}

Esempio:

$ time perl ~/matchstick.pl <<<950-250=750
2 990-250=740

real    0m39.835s
user    0m39.414s
sys 0m0.380s

Questo non troverà soluzioni che cambiano la lunghezza dell'equasion 11=4 -> 2 11=11, ma non sono sicuro che ciò sia consentito.


1
Le soluzioni che modificano la lunghezza dell'equazione sono consentite purché seguano l'EBNF menzionato nella domanda. Pertanto, dovrebbero essere trovati anche dalla tua funzione.
vauge

@vauge, sì, vedo che potrebbe essere dedotto dalla sezione "blocchi di macchine vuote" nei dettagli. Non lo aggiungerò a questa soluzione sebbene, sebbene possa funzionare, lo renderebbe ancora più lento.
Nutki

@vauge Non voglio sembrare maleducato, ma se il codice non è fisso conterà comunque?
Cieric

@Cieric Se non c'è altra soluzione che gestisca tutti quei casi, allora sì, conterà. Tuttavia, se ci sono risposte pienamente funzionanti entro la fine di questa sfida, accetterò la più breve.
vauge

@vauge ok solo controllando Devo solo assicurarmi che il numero di mosse sia corretto fino ad ora mostra sempre l'equazione di output corretta.
Cieric,
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.