Valutazione delle stringhe Dotty


25

Scrivi un programma che accetta una stringa di lunghezza dispari contenente solo i caratteri .e :. Con l'aiuto di uno stack inizialmente vuoto , generare un numero da questa stringa come segue:

Per ogni carattere c nella stringa (che va da sinistra a destra) ...

  • Se c è .e la pila ha meno di 2 elementi, premi 1 sulla pila.
  • Se c è .e la pila ha 2 o più elementi, fai uscire i due valori più alti dalla pila e metti la loro somma sulla pila.
  • Se c è :e la pila ha meno di 2 elementi, premi 2 sulla pila.
  • Se c è :e la pila ha 2 o più elementi, fai uscire i due valori più alti dalla pila e spingi il loro prodotto sulla pila.

Il numero risultante è il valore nella parte superiore della pila. Il tuo programma dovrebbe stampare questo numero su stdout (con una nuova riga finale opzionale).

(Una piccola analisi mostra che è rimasto solo un numero a meno che la stringa non abbia una lunghezza pari, motivo per cui li stiamo ignorando. In effetti, lo stack non ha mai più di 2 elementi.)

Ad esempio, il numero per ::...:.:.è 9:

  2   1   2   2    /______ stack just after the character below is handled
2 2 4 4 5 5 7 7 9  \
: : . . . : . : .  <-- string, one character at a time

Come controllo di integrità, ecco i numeri per tutte le stringhe di lunghezza 1, 3 e 5:

. 1
: 2
... 2
..: 1
.:. 3
.:: 2
:.. 3
:.: 2
::. 4
::: 4
..... 3
....: 2
...:. 4
...:: 4
..:.. 2
..:.: 1
..::. 3
..::: 2
.:... 4
.:..: 3
.:.:. 5
.:.:: 6
.::.. 3
.::.: 2
.:::. 4
.:::: 4
:.... 4
:...: 3
:..:. 5
:..:: 6
:.:.. 3
:.:.: 2
:.::. 4
:.::: 4
::... 5
::..: 4
::.:. 6
::.:: 8
:::.. 5
:::.: 4
::::. 6
::::: 8

Vince il programma più breve in byte. Tiebreaker è post precedente.

  • Si può presumere che l'input sia sempre valido, ovvero una stringa contenente solo .e la :cui lunghezza è dispari.
  • Invece di scrivere un programma, è possibile scrivere una funzione che accetta una stringa valida e stampa o restituisce il numero generato.

5
Il miglior equalizzatore minimalista di sempre.
dberm22,

Risposte:


13

CJam, 27 24 23 22 byte

q{i]_,+~3<-"1+2* "=~}/

Abbastanza diretto. Uso lo stack di CJam come stack menzionato nella domanda;)

Algoritmo

Per prima cosa diamo un'occhiata al codice ASCII per .e :.

'.i ':ied

[46 58]

Dato che in CJam, l'indice si avvolge, vediamo se possiamo usare questi valori direttamente per ottenere l'operazione desiderata.

'.i4% ':i4%ed

[2 2]

Quindi non posso semplicemente usare i codici ASCII in una stringa operativa di 4 lunghezze. Proviamo alcuni altri valori

'.i 10% ':i 10%ed

[6 8]

che su una stringa di 4 lunghezze si riduce a

[2 0]

Posso usare questa operazione mod 10 ma costerà 2 byte. Proviamo qualcos'altro

'.i5% ':i5%ed

[1 3]

Bene !, ora sottraggiamo solo 1 per la condizione di dimensione dello stack per ottenere gli indici 0, 1, 2 and 3e usare un 5array di lunghezza ( "1+2* ") come una custodia. L'ultimo spazio è solo un riempimento per renderlo di lunghezza 5. Questo è solo 1 byte in più rispetto all'operazione di modifica.

q{                  }/    e# parse each input character in this loop
  i]                      e# convert '. or ': into ASCII code and wrap everything
                          e# in stack in an array
    _,+                   e# Copy the stack array, take its length and add the length to
                          e# the stack array 
       ~3<                e# unwrap the stack array and check if stack size is less than 3
                          e# 3 because either . or : is also on stack
          -               e# subtract 0 or 1 based on above condition from ASCII code
           "1+2* "        e# string containing the operation to perform
                  =~      e# chose the correct operation and evaluate it

Provalo online qui

1 byte salvato grazie a cosechy


1
A cosa serve lo spazio nella serie di operazioni?
Peter Taylor,

@PeterTaylor spiegato nel post.
Ottimizzatore

9

> <> (Pesce) , 33 byte

ib%1-i:1+?\~n;
5a*)?*+40.\b%1-0@i

Abbastanza semplice con piccoli trucchi / ottimizzazioni.

Spiegazione:

  • Info: i= punto di codice del prossimo carattere di input, -1se viene raggiunta la fine dell'input; a= 10; b= 11; )=>
  • ipunto di codice del primo carattere di input,
  • b%1- top_of_stack mod 11 - 1maschere 48 ('.') , 56 (':')a1 , 2
  • i:1+?\~n; se viene raggiunta la fine dell'input, stampare l'ultimo risultato e terminare
  • altrimenti:
  • b%1- input maschera per 1 , 2
  • 0@spingere 0sotto il numero due
  • i5a*)leggi il prossimo input e mascheralo per 0 , 1confrontarlo50
  • if 1( ':') moltiplica i primi due elementi creando stack [0 prodotto]
  • aggiungi sempre i primi due elementi creando stack [0 sum]o[0+product=product]
  • 40.salta (loop) torna alla posizione (4,0), il nostro punto 4,i:1+?\~n;

8

Haskell, 73 65 byte

Una soluzione semplice, utilizzando il fatto che lo stack non ha mai più di 2 elementi.

[x,y]#'.'=[x+y]
[x,y]#_=[x*y]
s#'.'=1:s
s#_=2:s
f=head.foldl(#)[]

5

C, 104 byte

k[2],n;f(char*c){for(n=0;*c;)k[n]=*c++-58?n>1?n=0,*k+k[1]:1:n>1?n=0,*k*k[1]:2,k[1]=n++?k[1]:0;return*k;}

Bene, questo è troppo lungo.


5

Pyth, 25 24 byte

eu?]?.xGHsGtG+GhHmqd\:zY

Ho avuto un'idea studiando la soluzione di @ isaacg. Ma sto usando una pila.

Dimostrazione online o Suite di test

Spiegazione

La prima cosa che faccio è convertire la stringa di input in 0s e 1s. A "."viene convertito in a 0, a ":"in a 1.

mqd\:z   map each char d of input to (d == ":")

Quindi riduco questo elenco di numeri:

eu?]?.xGHsGtG+GhHmqd\:zY
 u                     Y   start with the empty stack G = []
                           for each H in (list of 0s and 1s), update G:
                              G = 
    ?.xGHsG                      product of G if H != 0 else sum of G
   ]                             wrapped in a list 
  ?        tG                 if G has more than 1 element else
             +GhH                G + (H + 1)
e                         take the top element of the stack

4

JavaScript (ES6), 65

Utilizziamo solo 2 celle del nostro stack.

Inizia a inserire un valore in s [0].
Quindi, ad ogni posizione dispari (contando da 0) nella stringa di input, inserisci un valore in s [1].
Ad ogni posizione pari, esegui un calcolo (aggiungi o moltiplica) e memorizza il risultato in s [0].

Quindi dimentica lo stack e usa solo 2 variabili, a e b.

f=s=>[...s].map((c,i)=>(c=c>'.',i&1?b=1+c:i?c?a*=b:a+=b:a=1+c))|a

Un test veloce

for(i=0;i<128;i++)
{
  b=i.toString(2).replace(/./g,v=>'.:'[v]).slice(1)
  if(b.length&1) console.log(b,f(b))
} 

Produzione

"." 1
":" 2
"..." 2
"..:" 1
".:." 3
".::" 2
":.." 3
":.:" 2
"::." 4
":::" 4
"....." 3
"....:" 2
"...:." 4
"...::" 4
"..:.." 2
"..:.:" 1
"..::." 3
"..:::" 2
".:..." 4
".:..:" 3
".:.:." 5
".:.::" 6
".::.." 3
".::.:" 2
".:::." 4
".::::" 4
":...." 4
":...:" 3
":..:." 5
":..::" 6
":.:.." 3
":.:.:" 2
":.::." 4
":.:::" 4
"::..." 5
"::..:" 4
"::.:." 6
"::.::" 8
":::.." 5
":::.:" 4
"::::." 6
":::::" 8

-2:f=s=>[(c=s[i]>'.',i&1?b=1+c:+i?c?a*=b:a+=b:a=1+c)for(i in s)]|a
nderscore il

@nderscore almeno sul mio borwser che non funziona. for (i in s) fornisce proprietà extra oltre agli indici
edc65,

funziona per me in Firefox 37.0.2. Prova a eseguirlo in una scheda del browser pulita. Sembra che stackexchange aggiunga ulteriori proprietà alle stringhe (in stub.en.js)
nderscore,

3

Pyth, 27 byte

Jmhqd\:zu?*GhHteH+GhHctJ2hJ

Una pila? Chi ha bisogno di uno stack.

                       Implicit: z is the input string.
Jmhqd\:z               Transform the string into a list, 1 for . and 2 for :
                       Store it in J.
u            ctJ2hJ     Reduce over pairs of numbers in J, with the
                       first entry as initial value.
 ?    teH               Condition on whether the second number is 1 or 2.
  *GhH                  If 1, update running total to prior total times 1st num.
         +GhH           If 2, update running total to prior total plus 1nd num.

Dimostrazione.


1
Genio. E nel frattempo ho implementato uno stack (32 byte). :-(
Jakube,

3

Retina , 105 75 73 byte

Il mio primo programma Retina! (Grazie a Martin Büttner per aver salvato 2 byte, per non parlare dell'invenzione della lingua in primo luogo.)

Ogni riga dovrebbe andare in un file separato; oppure, puoi metterli tutti in un file e usare il -sflag. La <empty>notazione rappresenta un file / una riga vuoti.

^(a+;)?\.
$1a;
^(a+;)?:
$1aa;
;(a+;)\.
$1
(a+);aa;:
$1$1;
)`;a;:
;
;
<empty>
a
1

Ispirato dalla risposta di mbomb007 , ma ho un approccio un po 'diverso. Una delle principali differenze è che costruisco la pila di fronte alla stringa di punti (con la parte superiore della pila rivolta verso destra). Ciò semplifica la conversione dei simboli nei corrispondenti numeri sul posto. Uso anche ainvece di 1, scambiandolo solo alla fine, per evitare di analizzare l'ambiguità in sequenze come $1a. Se una risposta simile aaaaaaè accettabile come numero unario, le ultime due righe / file potrebbero essere eliminate per salvare 4 byte.

Spiegazione:

^(a+;)?\.
$1a;

Corrisponde se ci sono 0 o 1 oggetti nello stack ( (a+;)?) seguito da un punto ( \.); in tal caso, sostituisce il punto con a;(ovvero preme un 1).

^(a+;)?:(.*)
$1aa;$2

Corrisponde se nella pila sono presenti 0 o 1 elementi seguiti da due punti. In tal caso, sostituisce i due punti con aa;(ovvero preme un 2).

;(a+;)\.
$1

Corrisponde se ci sono due oggetti in pila seguiti da un punto. Elimina il punto e il punto e virgola tra gli elementi, aggiungendoli in tal modo.

(a+);aa;:
$1$1;

Corrisponde se ci sono due oggetti in pila, il cui superiore è un 2, seguito da due punti. Elimina i due punti e il 2 e ripete l'altro numero due volte, moltiplicandolo in tal modo per 2.

)`;a;:
;

La regex corrisponde se ci sono due oggetti nella pila, la cui parte superiore è 1, seguita da due punti. Elimina i due punti e l'1, lasciando invariato l'altro numero (ovvero moltiplicato per 1).

)`indica la fine di un ciclo. Se sono state apportate modifiche alla stringa, il controllo ritorna all'inizio del programma ed esegue nuovamente le sostituzioni. Se la stringa ha smesso di cambiare, abbiamo sostituito tutti i punti e i due punti e tutto ciò che rimane è la pulizia ...

;
<empty>

Elimina il punto e virgola rimanente.

a
1

Trasforma tutte le a in 1. Ancora una volta, se i numeri unari sono autorizzati a utilizzare qualsiasi simbolo, questo passaggio non è necessario.


Quindi l'inizio del ciclo è considerato il primo file?
mbomb007,

@ mbomb007 Sì. L'avevo visto nei documenti, ma mi ero dimenticato finché Martin non me lo ricordò. ;)
DLosc,

2

Ruggine, 170 caratteri

fn f(s:String)->i32{let(mut a,mut b)=(-1,-1);for c in s.chars(){if b!=-1{a=match c{'.'=>a+b,':'=>a*b,_=>0};b=-1}else{b=match c{'.'=>1,':'=>2,_=>0};if a==-1{a=b;b=-1}};}a}

Altre prove che Rust è assolutamente terribile nel golf. Codice completo non registrato:

#[test]
fn it_works() {
    assert_eq!(dotty_ungolfed("::...:.:.".to_string()), 9);
    assert_eq!(f("::...:.:.".to_string()), 9);
}

fn dotty_ungolfed(program: String) -> i32 {
    let (mut a, mut b) = (-1, -1);
    for ch in program.chars() {
        if b != -1 {
            a = match ch { '.' => a + b, ':' => a * b, _ => panic!() };
            b = -1;
        } else {
            b = match ch { '.' => 1, ':' => 2, _ => panic!() };
            if a == -1 { a = b; b = -1; }
        }
    }
    a
}

fn f(s:String)->i32{let(mut a,mut b)=(-1,-1);for c in s.chars(){if b!=-1{a=match c{'.'=>a+b,':'=>a*b,_=>0};b=-1}else{b=match c{'.'=>1,':'=>2,_=>0};if a==-1{a=b;b=-1}};}a}

Ecco un trucco interessante che ho usato in questo. Puoi radere via un carattere in un'istruzione if / else facendogli restituire un valore che viene immediatamente scartato, il che significa che hai bisogno solo di un punto e virgola anziché di due.

Per esempio,

if foo {
    a = 42;
} else {
    doSomething(b);
}

può essere cambiato in

if foo {
    a = 42
} else {
    doSomething(b)
};

che salva un personaggio rasandosi un punto e virgola.


2

Haskell, 88 81 79 byte

(h:t)![p,q]|h=='.'=t![p+q]|1<2=t![p*q]
(h:t)!s|h=='.'=t!(1:s)|1<2=t!(2:s)
_!s=s

Sembra che qualcuno mi abbia battuto sul punto su una soluzione Haskell, non solo, la sua soluzione è più corta della mia. È un peccato, ma non vedo alcun motivo per non pubblicare ciò che mi è venuto in mente.


2

APL (50)

Sono in grande svantaggio qui, perché APL non è un linguaggio basato su stack. Alla fine ho dovuto abusare della riduzione per abbreviare il programma.

{⊃{F←'.:'⍳⍺⋄2>⍴⍵:F,⍵⋄((⍎F⌷'+×')/2↑⍵),2↓⍵}/(⌽⍵),⊂⍬}

La funzione interna prende un "comando" a sinistra e uno stack a destra e lo applica, restituendo lo stack. La funzione esterna la riduce sopra la stringa, iniziando con uno stack vuoto.

Spiegazione:

  • (⌽⍵),⊂⍬: l'elenco iniziale da ridurre. ⊂⍬è un elenco vuoto in scatola, che rappresenta lo stack, (⌽⍵)è il contrario dell'input. (La riduzione viene applicata da destra a sinistra sull'elenco, quindi la stringa verrà elaborata da destra a sinistra. L'inversione anticipata dell'input comporta l'applicazione dei caratteri nell'ordine corretto.)

  • {... }: la funzione interna. Prende la pila a destra, un personaggio a sinistra e restituisce la pila modificata.

    • F←'.:'⍳⍺: l'indice del carattere nella stringa .:, questo sarà 1 o 2 a seconda del valore.
    • 2>⍴⍵:F,⍵: Se 2 è maggiore della dimensione dello stack corrente, aggiungi semplicemente il valore corrente allo stack.
    • : altrimenti,
      • 2↓⍵: rimuove i primi due oggetti dalla pila
      • (...)/2↑⍵ : riduce una data funzione su di esse e aggiungila allo stack.
      • ⍎F⌷'+×': la funzione è +(addizione) o ×(moltiplicazione), selezionata da F.
  • : infine, restituisce l'elemento più in cima alla pila


2

Rubino - 96 caratteri

Il pezzo interessante qui è eval .

A parte questo, sto assumendo che dopo il primo personaggio, lo stack andrà sempre 2, matematica, 2, matematica, ... Questo mi permette di usare meno codice afferrando due caratteri contemporaneamente - Non devo mai capire capire se un personaggio è matematica o numero. È posizionale.

x,m=$<.getc>?.?2:1
(b,f=m.split //
b=b>?.?2:1
x=f ?eval("x#{f>?.??*:?+}b"):b)while m=gets(2)
p x

Ungolfed:

bottom_of_stack = $<.getc > '.' ? 2 : 1 # if the first char is ., 1, else 2
two_dots = nil
while two_dots = gets(2) do # get the next 2 chars
  number_char, math_char = two_dots.split //
  number = number_char > '.' ? 2 : 1
  if math_char
    math = math_char > '.' ? '*' : '+'
    # so bottom_of_stack = bottom_of_stack + number ...
    # or bottom_of_stack = bottom_of_stack * number
    bottom_of_stack = eval("bottom_of_stack #{math} number")
  else
    # if there's no math_char, it means that we're done and 
    # number is the top of the stack
    # we're going to print bottom_of_stack, so let's just assign it here
    bottom_of_stack = number
  end
end
p bottom_of_stack  # always a number, so no need for `puts`

2

TI-BASIC, 78 73 70 69 66 byte

Input Str1
int(e^(1=inString(Str1,":
For(A,2,length(Str1),2
Ans+sum({Ans-2,1,1,0},inString("::..:",sub(Str1,A,2
End
Ans

TI-BASIC è bravo a una linea, perché le parentesi di chiusura sono opzionali; viceversa, è un linguaggio scadente in cui è richiesta la memorizzazione di più valori poiché la memorizzazione in una variabile richiede da due a quattro byte di spazio. Pertanto, l'obiettivo è quello di scrivere il più possibile su ogni riga. TI-BASIC è anche terribile (per un linguaggio tokenizzato) nella manipolazione di stringhe di qualsiasi tipo; anche leggere una sottostringa è lungo.

I trucchi includono:

  • int(e^([boolean]invece di 1+(boolean; salva un byte
  • Somma parziale di una lista invece della suddivisione in liste (che richiederebbe la memorizzazione in una lista): salva 3 byte

Dovresti stare bene prendendo input da Ans, come ".:.":prgmDOTTY, salvando 4 byte.
MI Wright,

@Wright, utilizzo Ans per memorizzare il numero nello stack.
lirtosiast,

Intendevo all'inizio-- sbarazzarsi della linea 1 e cambiare la seconda linea in1+(":"=sub(Ans,1,1
MI Wright

1
Ho bisogno di usare Str1 nel loop, dove Ans è preso, quindi non riesco a cavarmela mantenendo la stringa in Ans. Memorizzarlo su Str1 da Ans non risparmierà spazio.
lirtosiast,

1

Partire, 129 115 112 byte

func m(s string){a,b:=0,0;for c,r:=range s{c=int(r/58);if b>0{a=a*b*c+(a+b)*(c^1);b=0}else{b,a=a,c+1}};print(a)}

(un po ') non golfato:

func m(s string){
    // Our "stack"
    a, b := 0, 0
    // abusing the index asignment for declaring c
    for c, r := range s {
        // Ascii : -> 58, we can now use bit fiddeling
        c = int(r / 58)
        if b > 0 {
            // if r is :, c will be 1 allowing a*b to pass through, c xor 1 will be 0
            // if r is ., c xor 1 will be 1 allowing a+b to pass through
            a = a*b*c + (a+b)*(c^1)
            b = 0
        } else {
            b, a = a, c+1 // Since we already know c is 0 or 1
        }
    }
    print(a)
}

Provalo online qui: http://play.golang.org/p/B3GZonaG-y


1

Python 3, 74

x,*s=[1+(c>'.')for c in input()]
while s:a,b,*s=s;x=[x*a,x+a][-b]
print(x)

Innanzitutto trasforma l'elenco di input in una sequenza di 1 e 2, prendendo il primo valore come valore iniziale x. Quindi, toglie due elementi alla volta dalla parte anteriore di s, prendendo il primo numero e aggiungendo o moltiplicando con il numero corrente in base al fatto che il secondo sia 1 o 2.


1

beh, è ​​un'operazione così semplice, sofisticata dall'op (intenzionalmente)

è solo ...

espressione tra parentesi tradotta in operazione * / + postfissa

Codice: C (80 byte)

int f(char*V){return*(V-1)?f(V-2)*(*V==58?*(V-1)/29:1)+(*V&4)/4**(V-1)/29:*V/29;}
  • questa funzione dovrebbe essere chiamata dalla coda della stringa in questo modo: f (V + 10) dove V = ".: ..:.: .. ::"

ingresso

lunghezza = 2n + 1 vettore V di tipo char '.' o ':'

Produzione

un numero intero k

Funzione

  • k = (V [1] op (V [3]) V [2]) op (V [5]) V [4] ....

  • op (x): (x = '.') -> +, (x = ':') -> *


Simulazione:

provalo qui


Come puoi supporre che il byte prima della stringa ( *(V-1)) sia zero?
nutki,

quando si assegna un nuovo vettore, il suo inizio comincia sempre dal segmento vuoto, la sua fine è È un carattere vuoto
Abr001am

1

Retina, 181 135 129 byte

Ogni riga dovrebbe essere in un file separato. <empty>rappresenta un file vuoto. L'output è in Unario.

^\..*
$&1;
^:.*
$&11;
^.
<empty>
(`^\..*
$&1
^:.*
$&11
^.(.*?1+;1+)
$1
^(\..*);(1+)
$1$2;
;1$
;
^(:.*?)(1+).*
$1$2$2;
)`^.(.*?1+;)
$1
;
<empty>

Quando ${0}1viene utilizzato, le parentesi graffe si separano $0dal 1 ° gruppo corrispondente 1, altrimenti sarebbe $01. Ho provato a usare $001, ma questo sembra non funzionare nel sapore .NET di regex.

Modifica: Trovato che $&è lo stesso di $0.

In pseudo-codice, questo sarebbe essenzialmente un ciclo do-while, come visto di seguito. Spingo il primo numero, quindi il ciclo: spingo il secondo numero, rimuovo l'operazione (istruzione), faccio matematica, rimuovo l'op. Continua il looping. Si noti che quando viene eseguita un'operazione, questo rimuoverà anche lo spazio dopo aver eseguito tutte le istruzioni.

ha commentato:

^\..*           # Push if .
$&1;
^:.*            # Push if :
$&11;
^.              # Pop op
<empty>


(`^\..*         # Loop, Push #
$&1
^:.*
$&11
^.(.*?1+;1+)    # Pop op
$1


^(\..*);(1+)    # Add if . (move ;)
$1$2;
;1$          # If mul by 1, remove
;
^(:.*?)(1+).*   # Mul if : (double)
$1$2$2;
)`^.(.*?1+;)    # Pop op, End Loop (clean up)
$1
;               # Remove semicolon
<empty>

La cosa principale che sto vedendo dal punto di vista del golf è il modello / coppie di sostituzione come (:)(.*)-> $1$2, che sono abbastanza sicuro che potrebbe essere (:.*)-> $1(poiché mantieni i due gruppi nello stesso ordine e non fai nient'altro con loro ).
DLosc,

Mi sono ispirato e ho fatto la mia risposta Retina. Grazie per avermi aiutato a scaricare questa lingua interessante!
DLosc,

@DLosc Cool! Sì, non l'ho ancora scaricato. Ho usato un tester di sostituzione regex online per ogni singola sostituzione.
mbomb007,

0

Python 3, 122 byte

x=input()
l=[0,0]
for _ in x:
 t=len(l)-2<2
 l=[[[0,0,l[-2]*l[-1]],l+[2]][t],[[0,0,sum(l)],l+[1]][t]][_=='.']
print(l[-1])

Ungolfed:

x = input()
l = []
for i in x:
    if i == '.':
        if len(l) < 2: 
            l+=[1]        #True, True = 1,1
        else:
            l=[sum(l)]    #True, True = 1,0
    else:
        if len(l)<2:
            l+=[2]        #False, True = 0,1
        else:
            l=[l[0]*l[1]] #False, False = 0,0
print (l[0])

In Python, fai riferimento all'indice di un elenco come questo:

list[index]

Puoi mettere un valore booleano in quello, Trueè 1ed Falseè 0.

# t is True if the length is less than 2, else false.

l=[ 

  # |------- Runs if char is : -------|
  # |------- l<2 -------| |- l>=2 -|

    [ [ 0,0, l[-2]*l[-1] ], l+[2] ] [t],

                                      # |---- Runs if char is . ----| 
                                      # |--- l<2 ---|  |- l>=2 -|

                                        [ [0,0, sum(l)], l+[1] ] [t] ]
                                                                      [_=='.']

Provalo online qui


0

Perl, 77 byte

@o=(0,'+','*');sub d{$_=shift;y/.:/12/;eval'('x s!\B(.)(.)!"$o[$2]$1)"!ge.$_}

allargato:

@o=(0, '+', '*');
sub d{
    $_=shift;
    y/.:/12/;
    eval '(' x s!\B(.)(.)!"$o[$2]$1)"!ge.$_
}

L' @oarray mappa le cifre agli operatori. Quindi sostituiamo coppie di cifre con l'operatore appropriato, riordinate per aggiungere. La regexp inizia con \Bquindi non abbiniamo il primo personaggio. Il risultato di s///gci dice di quante parentesi aperte abbiamo bisogno all'inizio. Quindi, quando abbiamo assemblato l'espressione infix completa, possiamo valutarla. (Rimuovi evalse desideri invece vedere l'espressione).

Ecco il cablaggio di prova che ho usato per verificare i risultati:

while(<>) {
    my ($a, $b) = m/(.*) (.*)/;
    print d($a), " $b\n";
}

L'input è l'elenco di espressioni punteggiate e i loro valori (forniti nella domanda) e l'output è una coppia di {effettivi, previsti}.

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.