Beh, è ​​strano ... non aspettare, è pari!


70

Preambolo

I numeri interi sono sempre pari o dispari . Gli interi pari sono divisibili per due, gli interi dispari no.

Quando aggiungi due numeri interi puoi dedurre se il risultato sarà pari o dispari in base al fatto che i riepiloghi fossero pari o dispari:

  • Pari + Pari = Pari
  • Pari + Dispari = Dispari
  • Dispari + Pari = Dispari
  • Dispari + Dispari = Pari

Allo stesso modo, quando moltiplichi due numeri interi puoi dedurre se il risultato sarà pari o dispari in base al fatto che i fattori fossero pari o dispari:

  • Pari * Pari = Pari
  • Pari * Dispari = Pari
  • Dispari * Pari = Pari
  • Dispari * Dispari = Dispari

Pertanto, se si conosce l'uniformità o la stranezza di tutte le variabili in un'espressione matematica che implica solo addizione e moltiplicazione, è possibile dedurre se il risultato sarà pari o dispari.

Ad esempio, possiamo affermare con certezza che il (68 + 99) * 37risultato è dispari perché un pari più un dispari ( 68 + 99) è dispari e che volte dispari un altro dispari ( odd * 37) dà uno strano.

Sfida

Scrivi un programma o una funzione che accetta una stringa contenente solo i quattro caratteri eo+*. Questa stringa rappresenta un'espressione matematica data nella notazione del prefisso che coinvolge solo addizione ( +) e moltiplicazione ( *). Ciascuno erappresenta un numero pari arbitrario e ciascuno orappresenta un numero dispari arbitrario.

Il tuo compito è semplificare l'espressione, stampando o restituendo un singolo eo in obase al risultato dell'espressione pari o dispari.

Si può presumere che l'input sarà sempre in notazione con prefisso valida. In particolare, ciascuno +e *avrà sempre due operandi corrispondenti che si verificano dopo di esso. Questi operandi possono essere una singola eo o, o un'altra, +o *un'espressione che a sua volta ha operandi.

Ad esempio, l'input *+eoopuò essere letto come mul(add(e, o), o)o (e + o) * onella normale notazione infix . Il ee il primo osono gli operandi corrispondenti a +, +eoe l'ultimo osono gli operandi corrispondenti a *.

Giusto per chiarire, ecco alcuni input non validi con notazione prefisso errata:

eo
ooe
o+e
ee*
+*oe
+e*o

Una sola nuova riga finale nell'output va bene, ma per il resto dovrebbe essere emessa una semplice eper pari o odispari.

Vince il codice più breve in byte.

Casi test

(Le righe vuote servono solo a separare visivamente casi simili.)

e -> e
o -> o

+ee -> e
+eo -> o
+oe -> o
+oo -> e
*ee -> e
*eo -> e
*oe -> e
*oo -> o

+e+ee -> e
+e+eo -> o
+e+oe -> o
+e+oo -> e
+e*ee -> e
+e*eo -> e
+e*oe -> e
+e*oo -> o

+o+ee -> o
+o+eo -> e
+o+oe -> e
+o+oo -> o
+o*ee -> o
+o*eo -> o
+o*oe -> o
+o*oo -> e

*e+ee -> e
*e+eo -> e
*e+oe -> e
*e+oo -> e
*e*ee -> e
*e*eo -> e
*e*oe -> e
*e*oo -> e

*o+ee -> e
*o+eo -> o
*o+oe -> o
*o+oo -> e
*o*ee -> e
*o*eo -> e
*o*oe -> e
*o*oo -> o

++eee -> e
++eeo -> o
++eoe -> o
++eoo -> e
++oee -> o
++oeo -> e
++ooe -> e
++ooo -> o

+*eee -> e
+*eeo -> o
+*eoe -> e
+*eoo -> o
+*oee -> e
+*oeo -> o
+*ooe -> o
+*ooo -> e

*+eee -> e
*+eeo -> e
*+eoe -> e
*+eoo -> o
*+oee -> e
*+oeo -> o
*+ooe -> e
*+ooo -> e

**eee -> e
**eeo -> e
**eoe -> e
**eoo -> e
**oee -> e
**oeo -> e
**ooe -> e
**ooo -> o

+e+e+e+ee -> e
+o+o+o+oo -> o
*e*e*e*ee -> e
*o*o*o*oo -> o
+e+o+e+oe -> e
+o+e+o+eo -> o
*e*o*e*oe -> e
*o*e*o*eo -> e
+e*e+e*ee -> e
+o*o+o*oo -> o
*e+e*e+ee -> e
*o+o*o+oo -> o

+**++*+*eeoeeooee -> e
+**++*+***eooeoeooeoe -> e
+**+***+**++**+eooeoeeoeeoeooeo -> o

+e*o*e**eoe -> e
+*e+e+o+e**eeoe -> e
**o++*ee*++eoe*eo+eoo -> o

8
Possiamo prendere 1 e 0 invece di e e o come input?
ghosts_in_the_code

8
@ghosts_in_the_code No, scusa.
Calvin's Hobbies,

2
Sta usando evalOK?
xnor

1
@xnor Certo. Basta che funzioni.
Calvin's Hobbies,

2
Dubito di poterlo utilizzare per battere i 13 byte già pubblicati, ma noto che l'aggiunta corrisponde a un esclusivo o e la moltiplicazione a un semplice o.
Francia,

Risposte:


43

CJam, 18 17 13 byte

Grazie ad aditsu per aver salvato 4 byte.

qW:O%eu~"eo"=

Prova qui la suite di test. (La suite di test è troppo lunga per il permalink. Basta copiarli dalle specifiche della sfida.)

Spiegazione

q     e# Read the input.
W:O   e# Push a -1 and store it in variable O.
%     e# Use the -1 to reverse the string, because CJam's stack-based nature and the
      e# commutativity of the operators means we can evaluate the code in postfix notation.
eu    e# Convert the string to upper case, turning 'e' into 'E' (a variable with even value
      e# 14) and 'o' into 'O' (which we've stored the odd value -1 in).
~     e# Evaluate the string as CJam code, leaving the result on the stack.
"eo"= e# Use the result as an index into the string "eo". CJam's indexing is cyclic so it
      e# automatically takes inputs modulo 2. Negative indices also work as expected.

27

Pyth, 16 14 byte

@"eo".vjdXzGU9

Pyth stesso può valutare una stringa, che è nella sintassi di Pyth. Pertanto sostituisco ee ocon 4e 5. Quindi la valutazione mi darà un numero pari o dispari e posso facilmente stampare il risultato.

Provalo online: dimostrazione o suite di test

Spiegazione:

@"eo".vjdXzGU9   implicit: z = input string
         XzGU9   replace "e" in z with 4 and "o" with 5
       jd        put a space between each char
     .v          evaluate it (Pyth style)
@"eo"            and print "e" or "o"

Spiegazione aggiuntiva per la sostituzione. Gè una variabile inizializzata con l'alfabeto abc...xyz. U9è l'elenco [0, 1, ..., 8]. XzGU9sostituisce le lettere dell'alfabeto con i valori dell'elenco. Quindi aviene sostituito con 0, bcon 1, ..., econ 4, ..., icon 8, jcon 0, ... e ocon 5. Quindi vengo esostituito con un numero pari e ocon un numero dispari. Tutte le altre sostituzioni non hanno alcun effetto.


Perché stai invertendo l'espressione? Inoltre, non è necessario prendere il risultato modulo 2 o l'indicizzazione sta andando in giro?
xnor

@xnor accede a un elemento in una stringa viene eseguito il wrapping del modulo. Quindi non è necessario il modulo 2.
Jakube

@xnor Ma grazie per il contrario. Naturalmente questo non è necessario. (Sono un po 'stanco oggi.)
Jakube

16

Perl, 50 45 40 caratteri

(Codice di 39 caratteri + opzione della riga di comando di 1 carattere.)

1while s/\+oe|\+eo|\*oo/o/||s/\W\w\w/e/

Esecuzione di esempio:

bash-4.3$ echo -n '**o++*ee*++eoe*eo+eoo' | perl -pe '1while s/\+oe|\+eo|\*oo/o/||s/\W\w\w/e/'
o

Che ne dici while/../?
primo

Doh. Io stupido. In realtà ha usato quella condizione mentre ha provato la sua sedversione ... Grazie, @primo.
arte

O ancora meglio, 1while s/\+oe.... Sono anche abbastanza sicuro che [+*]possa essere sostituito con \W.
primo

Grazie ancora, @primo. Penso che dovrei concentrarmi su un'unica soluzione una volta. ( gemafacendomi impazzire ...)
Manatwork il

Lo stesso approccio con Sed ora è più breve di 2 byte!
Digital Trauma,

13

Retina , 29 byte

(+`\*oo|\+(eo|oe)
o
\W\w\w
e

Per la comoda versione a un file -sviene utilizzato il flag.

Ci scambiamo espressioni dispari ( *oo, +oe, +eo) a ofino a quando possiamo, poi scambiare i restanti simbolo-lettera lettere espressioni e. Lo ripetiamo finché non possiamo e l'ultima lettera finale è il nostro output.

(Questa soluzione è simile alla risposta Perl di manatwork .)

Provalo online! (di Dennis)


12

Python 2, 90

def f(s):i=iter(s);a=next(i);return(a>'a')*a or'oe'[f(i)==f(i)if'*'<a else'e'in f(i)+f(i)]

La iterfunzione è un buon modo per trasformare la stringa di input in una coda FIFO che ricorda quanto della stringa è stata analizzata tra le chiamate di f. È idempotente, quindi è innocuo richiamarlo di nuovo quando l'input è già un iteratore anziché una stringa. La metà finale della risposta che inizia con or'oe'... sembra che dovrebbe essere giocabile a golf, ma non sono riuscito a trovare nulla.

-1 grazie a Sp3000.


Ottima soluzione! Le funzioni ricorsive che usano itermi sconvolgono davvero.
xnor,

3
Ecco un modo per calcolare l'aritmetica direttamente con eval:def f(s,e=0,o=1):i=iter(s);a=next(i);return'eo'[eval(a*(a>'a')or f(i)+a+f(i))%2]
xnor

1
@xnor Potresti anche postarlo come risposta. È molto diverso da questa soluzione.
feersum

9

Mathematica, 91 84 byte

#//.s_:>s~StringReplace~{"+ee"|"+oo"|"*ee"|"*eo"|"*oe"->"e","+eo"|"+oe"|"*oo"->"o"}&

Alla ricerca di un modo per comprimere questo ...


3
//.è più corto di FixedPoint.
alephalpha,

8

Python 2, 80 byte

def f(s,e=0,o=1):i=iter(s);a=next(i);return(a>'a')*a or'eo'[eval(f(i)+a+f(i))%2]

Questo si basa sulla risposta molto intelligente di feersum che utilizza un iterper implementare operazioni di notazione polacca. La nuova idea è quella di utilizzare evalper valutare le espressioni +e *con eval(f(i)+a+f(i)), in cui l'operatore aè posto infisso tra i risultati ricorsivi. Eval utilizza i binding e=0,o=1negli argomenti della funzione opzionale. L'uscita viene quindi presa mod 2.


Questo funziona anche in Python 3. A proposito, in che modo eval ha bisogno dei binding "e = 0, o = 1"?
Karhell,

@karhell Valuta espressioni simili e+o, quindi ha bisogno delle variabili per fare riferimento ai numeri.
xnor

8

C, 79 byte

Ricorsione semplice. Si basa su alcune proprietà (casuali?) Dei bit dei quattro caratteri di input consentiti.

f(){int c=getchar();return c&4?c:c&1?f()^f()^'e':f()&f();}main(){putchar(f());}

8

Utilità Shell + GNU, 33

dc -eFo`rev|tr oe OK`2%p|tr 10 oe

L'ingresso è preso da STDIN.

Questo fa lo stesso trucco di invertire l'input e valutare con una calcolatrice basata su stack - in questo caso dc. Potremmo sostituire ee ocon 0e 1, ma poi gli spazi dovrebbero essere inseriti per impedire l'analisi avida delle cifre nei numeri errati.

Viene invece esostituito con il Kquale è il dccomando per spingere la precisione corrente nello stack, che per impostazione predefinita è 0. E oviene sostituito con il Oquale è il dccomando per spingere la base di output corrente nello stack. Questo deve essere strano, quindi lo impostiamo su 15 Foprima di fare qualsiasi altra cosa in DC.

Quindi si tratta semplicemente di prendere mod 2 e stampare 2%p. Gli unici valori possibili sono ora 0e 1, quindi non importa che la base di output sia 15. Quindi si trtraduce in oo e.


Mi piace che se socchiudi gli occhi, questa fonte sembra quasi dc Forever OK.


5

Scherzi a parte , 24 byte

,R'2'e(Æ'1'o(Æ£ƒ'e'o2(%I

Una manipolazione dello stack più efficiente potrebbe probabilmente rendere questo più breve, ma meh, ne sono felice.

Accetta input come una stringa, come "+*oee"

Provalo online (l'input deve essere inserito manualmente)

Spiegazione:

,R        get input and reverse it
'2'e(Æ    replace all "e"s with "2"s
'1'o(Æ    replace all "o"s with "1"s
£ƒ        cast as function and call
'e'o2(%I  push "e" if result is even, else "o"

5

Rubino, 61 byte

Utilizzo dell'analisi della discesa ricorsiva e dell'algebra booleana.

def f
gets(1)==?+?f^f : ~/\*/?f&f : $_==?o
end
puts f ? ?o:?e

La funzione legge un carattere dallo stdin alla volta. Se legge a +o a *, si chiama due volte per determinare pari o dispari. La funzione ritorna trueper dispari e falseper even. Gli operatori ^ XOR e & AND vengono utilizzati per determinare la "stranezza" rispettivamente delle espressioni di addizione e moltiplicazione.

Ecco una versione non golfata:

def f
  x = gets(1)
  case x
  when '+'
    f ^ f
  when '*'
    f & f
  else
    x == 'o'
  end
end

puts f ? 'o' : 'e'

Grazie @Shel per aver segnalato un bug nella versione iniziale.


1
Questo non funziona, +eeo. Mi piace l'idea
Shelvacu,

sostituire f^fcon !f^fe f&fcon f|fe funziona. Programma per eseguire casi di test: pastebin.com/ufXfd1vc
Shelvacu,

1
Grazie, buona cattura! Sembra che mi sia confuso un po 'lì. Bella suite di test! Test-driven è la strada da percorrere, anche quando si
gioca a

@Shel Aha ..! Sono tornato indietro f^fe ho f&fgirato $_==?ee ?e:?oinvece :)
daniero il

1
Wow, impara qualcosa di nuovo ogni giorno ... ruby-doc.org/core/Regexp.html#method-i-7E
Shelvacu

4

Minkolang 0,14 , 40 byte

Ho provato a fare un metodo di valutazione intelligente, ma risulta che qualsiasi valore aggiunto alla codebox al di fuori dello spazio originale non verrà mai raggiunto dal contatore del programma. Quindi ho fatto un metodo di valutazione meno intelligente. : P

$o"eo+*"r0I4-[4g1Z2*1F]l*"e"+O.
0f1f+f*f

Provalo qui.

Spiegazione

$o                                Read in whole input as characters
  "eo+*"                          Push these characters onto the stack (in reverse order)
        r                         Reverse the stack
         I4-                      Push the length of the stack - 4
            [                     For loop; pop n and repeat that many times
             4g                   Get the item at the fourth index and put it on top
               1Z                 Pops n and pushes first index of n in stack
                 2*               Multiply by 2
                   1F             Gosub; goes to codebox(2n,1) to be returned to
                     ]            Close for loop
                      l*          Multiply by 10
                        "e"+      Add 101 ("o" is 111)
                            O.    Output as character and stop.
0f1f+f*f                          Does the appropriate operation then returns to F

1
Woohoo! il buon vecchio guscio batte un linguaggio (semi) golfistico ;-P
Digital Trauma

4

JavaScript, 110 106 94 byte

while(i.length>2)i=i.replace(/([+*][eo]{2})/,(o,e)=>{return"+oe+eo*oo".indexOf(o)<0?"e":"o"});

Certamente non la soluzione più piccola, ma probabilmente la soluzione più piccola possibile in un linguaggio dettagliato come JavaScript!


L'utilizzo di gruppi non di acquisizione è positivo per le prestazioni, ma negativo per le dimensioni del codice. Meglio rimuoverli ?:.
arte

d'accordo ... e così modificato.
Arkain,

Ho preso un'altra occhiata ora. Il tuo codice può essere ulteriormente ridotto a while(i.length>2)i=i.replace(/[+*][eo]{2}/,function(o){return"+oe+eo*oo".indexOf(o)>=0?"o":"e"}). O se si passa alla funzione della freccia grassa di ECMAScript 6, allora while(i.length>2)i=i.replace(/[+*][eo]{2}/,o=>"+oe+eo*oo".indexOf(o)>=0?"o":"e"). Ma purtroppo il requisito dice programma o funzione, mentre il tuo codice attuale è uno snippet. Dovrebbe gestire input e output o argomento e restituire valore.
arte

1
Sfortunatamente per essere validi su questo sito, non possiamo presumere che esista già una variabile. Dovrai renderlo una funzione di icome hai detto.
Alex A.

1
@Arkain, non è necessario acquisire un gruppo nell'espressione regolare poiché in ogni caso verrà utilizzata l'intera sottostringa abbinata come un unico pezzo. Per lo stesso motivo non è necessario passare il parametro e al callback.
Manatwork

4

O , 24 20 19 18 byte

i`2:e;1:o;~2%'o'e?

Prende l'input, lo inverte, lo assegna ea 2 e oa 1 e lo pubblica su Tumblr lo valuta come O code.

Spiegazione:

ottengo input e invertilo, perché O usa la notazione postfix
2: E; Assegna `e` a 2
1: o; Assegna `o` a 1
~ 2% Valutazione e verifica se il risultato è pari
'O'e? Stampa 'e' se pari, 'o' se dispari

4

GNU Sed, 36

:
s/*oo\|+eo\|+oe/o/
t
s/\W\w\w/e/
t

Dopo aver postato ho visto questo esattamente lo stesso approccio di Perl risposta @ manatwork e risposta Retina @ di randomra . Quindi suppongo che potrei anche andare fino in fondo e prendere in prestito anche loro \W\w\w.

Grazie a @Ruud per la rasatura di 4 byte.


Con le parentesi sparite, ora ripaga abbandonare la regexp estesa. Vinci 2 byte per non scappare +, perdi 2 byte per scappare |, ma il risultato finale è vincere 1 byte per l'opzione di rilascio -r.
Ruud Helderman,

@Ruud Esatto. L'ho provato prima, ma non mi rendevo conto che |bisogna evadere quando -rnon viene utilizzato. Ancora, 2 byte in più dal punteggio - grazie!
Trauma digitale il

2

Haskell, 160 byte

Chiama f.

f=until((==1).l)r
r s|l s<3=s|3#s?o=r('o':3%s)|3#s?sequence["+*","oe","oe"]=r('e':3%s)|0<1=1#s++r(1%s)
l=length
(#)=take
(%)=drop
(?)=elem
o=["+eo","+oe","*oo"]

2

JavaScript, 92 71 byte

f=i=>i>"0"?i:f(i.replace(/.[eo]{2}/,e=>"eo"[eval((e[1]>"e")+"^&"[+(e[0]<"+")]+(e[2]>"e"))]))

È un po 'offuscato, ma volevo fare qualcosa usando evale operatori bit a bit. commentata:

f = (i) => // function(i) { return
    i>"0"  // i[0] == "o" || i[0] == "e" :-) - the characters `*` and `+` are both <"0"
      ? i  // finish
      : f(i.replace( // recursively repeat with
          /.[eo]{2}/, // first occurrence of "something" followed by two values
          (e) =>    // replaced by
              "eo"[ // string indexing
                eval(
                    (e[1]>"e")        // e[1] == "o" ? "true" : "false"
                  + "^&"[+(e[0]<"+")] // e[0] == "+" ? "^" : "&"
                  + (e[2]>"e")        // e[2] == "o" ? "true" : "false"
                )
              ]     // like eval(…) ? "o" : "e"
        ))

La ripetizione di (e[…]>"e")mi infastidisce un po ', ma neanche quanto segue (103 byte):

f=i=>i>"0"?i:f(i.replace(/e|o/g,x=>+(x>"e")).replace(/.\d\d/,e=>"eo"[eval(e[1]+"^&"[+(e[0]<"+")]+e[2])]))

Quindi, alla fine, l'approccio di @ Arkain con una semplice corrispondenza della sottostringa è superiour. Trasformato in una funzione, con alcune ottimizzazioni:

f=i=>i>"0"?i:f(i.replace(/.[eo]{2}/,v=>"eo"[+"+oe+eo*oo".includes(v)]))

1

Dardo, 173 byte

f(i){var l=i.split(''),e='e',o='o';g(p){if(l[p]!=e&&l[p]!=o){var x=p+1,y=p+2;g(x);g(y);l[p]=l[p]=='+'?l[x]!=l[y]?o:e:l[x]==o?l[y]:e;l.removeRange(x,p+3);}}g(0);print(l[0]);}

Questo non è competitivo, ma comunque. L'essenza della soluzione è, a partire da 0, sostituire ricorsivamente ogni operatore con la valutazione la coppia di caratteri che segue quell'operatore e quindi rimuovere quei caratteri dall'elenco.


1

Haskell, 231 byte

Ecco un approccio usando un linguaggio serio;)

Versione golfizzata:

p(s:_)[]=s
p s(x:y)=p(r$x:s)y
r[]=[]
r('e':'e':'+':x)=r$'e':x
r('e':'o':'+':x)=r$'o':x
r('o':'e':'+':x)=r$'o':x
r('o':'o':'+':x)=r$'e':x
r('e':'e':'*':x)=r$'e':x
r('e':'o':'*':x)=r$'e':x
r('o':'e':'*':x)=r$'e':x
r('o':'o':'*':x)=r$'o':x
r x=x

Esempio:

*Main> p [] "+**+***+**++**+eooeoeeoeeoeooeo"
'o'

Versione Ungolfed e abbastanza completa:

type Stack = String

parse :: String -> Char
parse = parse' []

parse' :: Stack -> String -> Char
parse' (s:_) []     = s
parse' s     (x:xs) = parse' (reduce $ x:s) xs

reduce :: Stack -> Stack
reduce [] = []
reduce ('e':'e':'+':xs) = reduce $ 'e':xs
reduce ('e':'o':'+':xs) = reduce $ 'o':xs
reduce ('o':'e':'+':xs) = reduce $ 'o':xs
reduce ('o':'o':'+':xs) = reduce $ 'e':xs
reduce ('e':'e':'*':xs) = reduce $ 'e':xs
reduce ('e':'o':'*':xs) = reduce $ 'e':xs
reduce ('o':'e':'*':xs) = reduce $ 'e':xs
reduce ('o':'o':'*':xs) = reduce $ 'o':xs
reduce xs               = xs

Esempio:

*Main> parse "+**+***+**++**+eooeoeeoeeoeooeo"
'o'

Caratteristiche: pattern matching e ricorsione.


1

Jolf, 11 byte

(Non competitivo, poiché la lingua postdatizza la domanda.) Provalo qui!

FVyAi"oe"@\x12

(Sostituisci \x12con il carattere reale \x12. Questo dovrebbe essere fatto automaticamente nell'interprete.)

Spiegazione:

FVyAi"oe"@\x12
    i          input
          \x12 character 12
         @     char code at
   A "oe"      replace all os with 1s and all es with 2s
  y            eval as jolf, returning the answer
 V             return parity "even" or "odd"
F              get first character
               implicit output

1

Python 3, 171 145 135 byte

Non competitivo, ma mi sono divertito a farlo, quindi non sono riuscito a tenerlo per me. A differenza della voce (molto intelligente) dell'iteratore ricorsivo Python di feersum , questa inverte l'input e quindi esegue una buona analisi basata su stack della notazione polacca inversa.

def p(i):
 s=[]
 for c in i[::-1]:
  s+=[c>'e'if c>'a'else getattr(s.pop(),'__'+('axnodr'[c>'*'::2])+'__')(s.pop())]
 return'eo'[s[0]]

È callable()elegante, ma lungo. (Invertire la condizione e rimuovere notsarebbe più corto.) Controlla invece se m è intero m in[0,1]sarebbe più corto, ma controllando se c è valore c in'eo'sarebbe ancora più breve. Questo in seguito sarà lo stesso c>'a'di questo caso.
arte

In realtà non è necessario per la variabile me i suoi valori numerici. Metti solo questo dentro for:s+=[c>'e'if c>'a'else{'*':o.and_,'+':o.xor}[c](s.pop(),s.pop())]
manatwork il

@manatwork: grazie! Non pensavo di poter invertire la condizione, perché pensavo che avrebbe significato chiamare s.pop()(due volte) ogni ciclo. Fino ad ora non ho disturbato i test; ma hey, il punto è discutibile ora.
Tim Pederick il

Una domanda mi ha infastidito sin dall'inizio: perché usare il operator modulo? bool.__and__()e bool.__xor__()sono più maneggevole: s+=[c>'e'if c>'a'else getattr(s.pop(),{'*':'__and__','+':'__xor__'}[c])(s.pop())]. Ma sulla base gnibbler 's punta affettare , che può essere trasformato in s+=[c>'e'if c>'a'else getattr(s.pop(),'__'+('axnodr'[c>'*'::2])+'__')(s.pop())].
arte

@manatwork: Perché non ci avevo pensato. Ho considerato solo gli operatori infix ( ^, &) e le loro operatorcontroparti, dimenticandomi dei metodi che li implementano effettivamente. Oh, e reversed()ora è stato abbandonato grazie ad un altro dei consigli sul golf di Python .
Tim Pederick,

1

Haskell, 98 94 byte

Mi dispiace disturbarti con l'ennesimo tentativo di Haskell; volevo solo dimostrare che è molto ben possibile in meno di 100 byte.

p(c:s)|any(<'a')s=p(c:p s)
p('+':x:y:s)|x/=y='o':s
p('*':'o':s)=s
p(c:_:_:s)|c<'a'='e':s
p s=s

Definisce una funzione pche accetta qualsiasi espressione valida come parametro e restituisce il risultato come una stringa di lunghezza 1.

Esempio:

*Main> p "**o++*ee*++eoe*eo+eoo"
"o"

La funzione funziona riducendo ripetutamente l'operatore più a destra nella stringa fino a quando non vengono lasciati operatori.


0

Aggiungi ++ , 46 byte

D,g,@,d"oe"$eA"e"=+o
D,f,@,bR€gbU32CjbV2%"eo":

Provalo online!

Il piè di pagina elenca semplicemente tutti gli input di esempio e i loro output corrispondenti.

Come funziona

Come una perdita delle risposte qui, questo utilizza la sostituzione e la valutazione. La nostra funzione principale è fed gè una funzione di supporto. Useremo "*e*o*e*oe"(che è e) come esempio.

finizia prendendo la stringa di input e invertendola, cedendo "eo*e*o*e*". Quindi mappiamo gsu ogni elemento:

ginizia duplicando l'argomento, per conservare una copia fino al comando finale. Quindi controlliamo se l'argomento è nella stringa "oe", producendo 1 per lettere e 0 per *o +. Quindi spingiamo di nuovo l'argomento e controlliamo se è uguale a "e". Questo risultato viene quindi aggiunto al controllo precedente. Questo produce 0 per *o +, 1 per oe 2 per e. Prendiamo quindi l'OR logico tra questo valore e l'argomento. Se il valore è 0 , viene sostituito dall'argomento (ovvero *o +), altrimenti viene lasciato così com'è (ovvero 1 e 2 ).

Questo converte tutte le lettere sul retro dell'input in un valore numerico. Quindi uniamo ogni elemento per spazi, per garantire che le cifre non siano concatenate. Per il nostro esempio, questo produce la stringa "2 1 * 2 * 1 * 2 *". Possiamo quindi valutare questo, usando la notazione postfix di Add ++, ottenendo 8 . Quindi prendiamo la parità di questo valore, producendo 0 per i numeri pari e 1 per i numeri dispari, prima di indicizzarli nella stringa "eo"e restituire la lettera corrispondente.

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.