Calcolatore di operazioni a numeri interi semplici


28

Implementare una semplice calcolatrice gestibile da script di numeri interi.

Concetto

L'accumulatore inizia da 0 e ha delle operazioni eseguite su di esso. Alla fine del programma emette il valore dell'accumulatore.

operazioni:

  • +aggiunge 1all'accumulatore
  • -sottrae 1dall'accumulatore
  • * moltiplica l'accumulatore per 2
  • / divide l'accumulatore per 2

Script di esempio

L'input ++**--/dovrebbe dare l'output 3.

Esempio di implementazione

def calc(s)
    i = 0
    s.chars.each do |o|
        case o
            when '+'
                i += 1
            when '-'
                i -= 1
            when '*'
                i *= 2
            when '/'
                i /= 2
        end
    end
    return i
end

Regole

  • Questo è , quindi vince la risposta più bassa in byte, ma non è selezionata.
  • Le implementazioni creative sono incoraggiate.
  • Sono vietate le scappatoie standard.
  • Si ottiene il programma tramite stdin o argomenti e si può produrre la risposta tramite valore di ritorno o stdout.
  • Divertiti.
  • La divisione viene troncata perché è una divisione intera.
  • Il programma -/ritorna -1.

Casi test

*///*-*+-+
-1
/*+/*+++/*///*/+-+//*+-+-/----*-*-+++*+**+/*--///+*-/+//*//-+++--++/-**--/+--/*-/+*//*+-*-*/*+*+/+*-
-17 
+++-+--/-*/---++/-+*-//+/++-*--+*+/*/*/++--++-+//++--*/***-*+++--+-*//-*/+*/+-*++**+--*/*//-*--**-/-*+**-/*-**/*+*-*/--+/+/+//-+*/---///+**////-*//+-+-/+--/**///*+//+++/+*++**++//**+**+-*/+/*/*++-/+**+--+*++++/-*-/*+--/++*/-++/-**++++/-/+/--*/-/+---**//*///-//*+-*----+//--/-/+*/-+++-+*-*+*+-/-//*-//+/*-+//+/+/*-/-/+//+**/-****/-**-//+/+-+/*-+*++*/-/++*/-//*--+*--/-+-+/+/**/-***+/-/++-++*+*-+*+*-+-//+/-++*+/*//*-+/+*/-+/-/*/-/-+*+**/*//*+/+---+*+++*+/+-**/-+-/+*---/-*+/-++*//*/-+-*+--**/-////*/--/*--//-**/*++*+/*+/-+/--**/*-+*+/+-*+*+--*///+-++/+//+*/-+/**--//*/+++/*+*////+-*-//--*+/*/-+**/*//+*+-//+--+*-+/-**-*/+//*+---*+//*/+**/*--/--+/*-*+*++--*+//+*+-++--+-*-*-+--**+/+*-/+*+-/---+-*+-+-/++/+*///*/*-+-*//-+-++/++/*/-++/**--+-////-//+/*//+**/*+-+/+/+///*+*///*-/+/*/-//-*-**//-/-+--+/-*--+-++**++//*--/*++--*-/-///-+/+//--+*//-**-/*-*/+*/-*-*//--++*//-*/++//+/-++-+-*/*-+++**-/-*++++**+-+++-+-***-+//+-/**-+/*+****-*+++*/-*-/***/-/*+/*****++*+/-/-**-+-*-*-++**/*+-/*-+*++-/+/-++*-/*-****-*
18773342

2
Quindi ... non è rigorosamente intero, poiché /può produrre non interi.
Conor O'Brien,

2
Quindi dovresti specificarlo esplicitamente.
Conor O'Brien,

5
Cosa dovrebbe -/tornare?
Dennis,

4
Non posso fare a meno di notare che lo snippet di codice presente nella home page di rust-lang risolve questa sfida.
Zwei,

4
Aggiungi altri casi di test.
Martin Ender,

Risposte:


28

Python 2, 48 byte

i=0
for c in input():exec"i=i%s2&-2"%c
print i/2

Fa +2, -2, *2, o /2. Facendo +2e -2piuttosto che +1e -1, stiamo lavorando in unità raddoppiate, quindi l'output finale deve essere dimezzato. Tranne, la divisione del pavimento /ora deve arrotondare per eccesso a un multiplo di 2, che è fatto con &-2.


È brillante! Se si desidera pubblicarlo da soli, una porta CJam di questo attualmente porterebbe la sfida: 0q{2\~-2&}/2/( 2\~elimina l'operatore con il secondo operando 2, -2&è AND bit per bit, 2/è la divisione finale per due. q{...}/È una foreach sull'input ed 0è solo l'iniziale valore.)
Martin Ender,

Puoi pubblicarlo, non conosco CJam.
xnor

Davvero intelligente! Portato su ES6 questo avrebbe facilmente sovraperformato la mia risposta
edc65

Uso brillante di Python. Ho imparato qualcosa di nuovo da questo.
Jacobr365,

12

Haskell, 51 byte

x#'+'=x+1
x#'-'=x-1
x#'*'=x*2
x#_=div x 2 
foldl(#)0

Esempio di utilizzo: foldl(#)0 $ "++**--/"-> 3.


12

Gelatina , 18 17 byte

‘

’

:2
Ḥ
O0;ṛĿ/

Provalo online!

Come funziona

Le prime sei linee definiscono collegamenti di aiuto con indici compresi tra 1 e 6 ; incrementano, non fanno nulla, diminuiscono, non fanno nulla, dimezzano (pavimentazione) e raddoppiano.

Il collegamento principale - O0;ṛĿ/- converte i caratteri di input nei loro punti di codice ( O), antepone uno 0 (valore iniziale) alla matrice di punti di codice 0;, quindi riduce la matrice generata come segue.

Il valore iniziale è il primo elemento dell'array, ovvero lo 0 anteposto . Il collegamento rapido ṛĿviene chiamato per ogni elemento successivo nella matrice, con l'ultimo valore restituito come argomento sinistro e l'elemento corrente come giusto. Ispeziona il suo argomento corretto ( ) e valuta monadicamente il collegamento con quell'indice ( Ŀ), applicando così l'operazione desiderata.


10
Sembra la risposta della gelatina con il maggior numero di newline
Conor O'Brien,

10

Python 2, 54 byte

i=0
for c in input():exec"i=i"+c+`~ord(c)%5%3`
print i

L'input è preso come una stringa letterale. ~ord(c)%5%3mappa gli operatori sui corrispondenti operandi di destra.

In precedenza, ho usato hash(c)%55%3che non ha prodotto risultati coerenti tra le diverse versioni di Python. Questo mi ha incoraggiato a esplorare altre formule.


non sembra funzionare ...
Destructible Lemon

55,3 e 65,4 sono i due più brevi per la doppia mod di hash in Python 2
Jonathan Allan,

@DestructibleWatermelon fa per me: ideone
Jonathan Allan,

Penso che hashsia specifico della versione di Python - ideone usa 2.7.10 che fornisce [1, 1, 2, 2]come quattro mappature, mentre localmente il 2.7.12 ottengo[2, 0, 1, 0]
Sp3000

1
funziona su ideone, ma non sul mio computer python. Probabilmente dipende dalla versione, nel qual caso la versione dovrebbe essere annotata EDIT: ninja'd: /
Destructible Lemon

10

SILOS , 133 211 byte

:s
def : lbl G GOTO
readIO
i-46
if i a
i+2
if i b
i+2
if i c
i+1
if i d
G e
:a
G v
:p
a-1
a/2
G o
:v
a+1
if a p
a-1
j=a
j/2
k=j
k*2
k-a
a/2
if k t
G o
:t
a-1
:o
G s
:b
a-1
G s
:c
a+1
G s
:d
a*2
G s
:e
printInt a

Accetta i codici ASCII degli operatori.

Provalo online con i casi di test:
-/
++**--/
*///*-*+-+


è loadLine golfier?
Rohan Jhunjhunwala,

Chiarito il PO; -/dovrebbe restituire -1 , non 0 .
Dennis,

@Dennis risolto. Aggiunti molti byte però: /
betseg il

9

Turing Machine - 23 stati (684 byte)

Provalo qui - permalink

0 * * r 0
0 _ . l 1
1 * * l 1
1 _ * l 2
2 * 0 r 3
3 _ * r 3
3 + _ l +
3 - _ l -
3 x _ l x
3 / _ l /
+ _ * l +
+ * * * 4
4 - * l 5
4 _ 1 r 6
4 0 1 l 7
4 1 0 l 4
- _ * l -
- * * * 5
5 - * l 4
5 _ * r 8
5 0 1 l 5
5 1 0 l 7
x * * l x
x 1 0 l 9
x 0 0 l a
9 _ 1 r 6
9 1 1 l 9
9 0 1 l a
a _ _ r 6
a 1 0 l 9
a 0 0 l a
/ _ * l /
/ * * l b
b * * l b
b _ * r c
c 0 0 r d
c 1 0 r e
d * * l 7 
d 0 0 r d
d 1 0 r e
e _ * l 7
e - * l 4
e 0 1 r d
e 1 1 r e
8 * * r 8
8 - _ r 3
8 _ - r 3
7 * * l 7
7 _ * r f
f 0 _ r f
f 1 * r 6
f * _ l g
g * 0 r 6
6 * * r 6
6 _ * r 3
3 . _ l h
h _ * l h
h - _ l i
h * * l halt
i * * l i
i _ - r halt

L'input non deve contenere alcun '*' poiché è un carattere speciale nel codice della macchina di Turing. Usa invece 'x'. Emette la risposta in binario.

Codice non filtrato

init2 * * r init2
init2 _ . l init0
init0 * * l init0
init0 _ * l init1
init1 * 0 r readop
readop _ * r readop
readop + _ l +
readop - _ l -
readop x _ l x
readop / _ l /
+ _ * l +
+ * * * inc
inc - * l dec
inc _ 1 r return
inc 0 1 l zero
inc 1 0 l inc
- _ * l -
- * * * dec
dec - * l inc
dec _ * r neg
dec 0 1 l dec
dec 1 0 l zero
x * * l x
x 1 0 l x1
x 0 0 l x0
x1 _ 1 r return
x1 1 1 l x1
x1 0 1 l x0
x0 _ _ r return
x0 1 0 l x1
x0 0 0 l x0
/ _ * l /
/ * * l //
// * * l //
// _ * r div
div 0 0 r div0
div 1 0 r div1
div0 * * l zero 
div0 0 0 r div0
div0 1 0 r div1
div1 _ * l zero
div1 - * l inc
div1 0 1 r div0
div1 1 1 r div1
neg * * r neg
neg - _ r readop
neg _ - r readop
zero * * l zero
zero _ * r zero1
zero1 0 _ r zero1
zero1 1 * r return
zero1 * _ l zero2
zero2 * 0 r return
return * * r return
return _ * r readop
readop . _ l fin
fin _ * l fin
fin - _ l min
fin * * l halt
min * * l min
min _ - r halt

Spiegazione degli stati:

Inizializzazione:
questi stati vengono visitati una volta all'inizio di ogni corsa, a partire da init2

  • init2: spostati completamente a destra e inserisci un '.'. In questo modo la TM sa quando fermarsi. Passare a "init0".
  • init0: sposta tutta la schiena a sinistra fino a quando la testa non legge uno spazio. Quindi spostare una cella a sinistra. Passare a "init1".
  • init1: Metti uno zero e sposta una cella a destra e cambia in 'readop'.

Istruzioni di lettura:
questi stati saranno visitati più volte durante il programma

  • readop: si sposta completamente a destra fino a quando non legge un operatore o il '.'. Se colpisce un operatore, passa allo stato corrispondente (+, -, x, /). Se colpisce un '.', Cambia in state 'pinna'.

  • return: riporta la testa nello spazio vuoto tra il totale parziale e gli operatori. Quindi passa a "readop".

Operazioni:
queste operazioni fanno il vero lavoro sporco

  • +: Sposta a sinistra fino a quando la testa non legge caratteri non bianchi. Se questo personaggio è un '-', sposta a sinistra e cambia in 'dec'. Altrimenti, cambia in "inc".

  • -: Simile a '+', tranne che cambia in 'inc' se ci sono '-' e 'dec' altrimenti.

  • inc: Se la cifra sotto la testa è uno 0 (o uno spazio bianco), cambiarlo in 1 e passare a 'zero'. Se la cifra è 1, cambiarla in 0, quindi ripetere la cifra successiva.

  • dec: Simile a inc, tranne 1 va a 0, 0 va a 1 e se la testa legge uno spazio bianco, cambia in 'neg'.

  • x, x0, x1: sposta il numero uno a sinistra. Passare a "ritorno".

  • /, //, div, div0, div1: spostati completamente a destra del numero, quindi spostane uno a destra. Se c'è un '-', cambia in 'inc'. Questo simula l'arrotondamento per difetto dei numeri negativi. Altrimenti, passa a "zero"

  • neg: inserisci un '-' dopo il numero, quindi cambia in 'readop'

  • zero, zero1, zero2: rimuove gli zeri iniziali e passa a "readop"

Pulizia: rende presentabile l'output

  • pinna, min: spostare il '-' davanti al numero, se necessario. Halt.

1
Ho pensato che leggere questo codice fosse davvero fantastico. Quindi grazie per avermi rallegrato la giornata.
Jacobr365,

8

Perl 6 , 53  52 byte

{([Ro] %(<+ - * />Z=>*+1,*-1,* *2,*div 2){.comb})(0)}

{[Ro](%(<+ - * />Z=>*+1,*-1,*×2,*div 2){.comb})(0)}

Spiegazione:

# bare block lambda that has one implicit parameter 「$_」
{
  (
    # reduce the code refs using ring operator 「∘」 in reverse 「R」
    [R[o]]

      # produce a hash from:
      %(

        # list of pairs of "operator" to code ref
        # ( similar to 「'+' => { $^a + 1 }」 )

          # keys
          < + - * / >

        # keys and values joined using infix zip operator 「Z」
        # combined with the infix Pair constructor operator 「=>」
        Z[=>]

          # values (Whatever lambdas)
          * + 1,
          * - 1,
          * × 2, # same as 「* * 2」
          * div 2,

      ){

        # split the block's argument into chars
        # and use them as keys to the hash
        # which will result in a list of code refs
        .comb

      }

  # call composed code ref with 0
  )(0)
}

Uso:

my $input = '++**--/'
my $output = {[Ro](%(<+ - * />Z=>*+1,*-1,*×2,*div 2){.comb})(0)}.( $input );
say $output; # 3
say $output.^name; # Int

7

C, 63 62 57 byte

s,t;c(char*x){for(;*x;s+=t<4?t?2-t:s:-s>>1)t=*x++%6;s=s;}

Wandbox


6

05AB1E , 20 byte

Grazie a Enigma per aver -/risolto il problema!

Per 16 byte se non fosse divisione intera: Î"+-*/""><·;"‡.V.

Î…+-*"><·"‡'/"2÷":.V

Spiegazione:

Î                      # Push 0, which is our starting variable, and input
 …+-*                  # Push the string "+-*"
     "><·"             # Push the string "><·"
          ‡            # Transliterate. The following changes:
                           "+" -> ">"
                           "-" -> "<"
                           "*" -> "·"
           '/"2÷":     # Replace "/" by "2÷"
                  .V   # Evaluate the code as 05AB1E code...
                           '>' is increment by 1
                           '<' is decrement by 1
                           '·' is multiply by 2
                           '2÷' is integer divide by two
                       # Implicitly output the result

Utilizza la codifica CP-1252 . Provalo online!


Chiarito il PO; -/dovrebbe restituire -1 , non 0 .
Dennis,

Il problema di divisione del numero negativo potrebbe essere risolto con Î…+-*"><·"‡'/"2÷":.Vper lo stesso conteggio byte.
Emigna,

@Dennis Risolto il problema.
Adnan,

@Emigna Grazie :)
Adnan

5

JavaScript ES6, 80 68 byte

k=>[...k].reduce((c,o)=>+{"+":c+1,"-":c-1,"*":c*2,"/":c/2|0}‌​[o],0)

Risparmiato ben 12 byte grazie a Neil!


La seconda risposta sarebbe più leggibile se hai rimosso "c"+e scritto "c+1 c-1 c*2 c/2|0".splitecc.
Neil,

Per la prima risposta, perché non scrivere o=>c=[c+1,c-1,c*2,c/2|0]["+-*/".indexOf(o)], o penso che puoi quindi continuare a salvare un ulteriore byte usando o=>c={"+":c+1,"-":c-1,"*":c*2,"/":c/2|0}[o].
Neil,

k=>[...k].reduce((c,o)=>+{"+":c+1,"-":c-1,"*":c*2,"/":c/2|0}[o],0)potrebbe funzionare ancora più brevemente, ma ho perso il conto ...
Neil,

@Neil Ah, sì, me ne sono dimenticato
Conor O'Brien,

1
In qualche modo si arriva a caratteri di larghezza zero tra }e [o], quindi in realtà è lungo solo 66 byte. Inoltre, il PO ha chiarito; -/dovrebbe restituire -1 , non 0 .
Dennis,

5

Rubino, 48 44 42 + 1 = 43 byte

+1 byte per -nflag. Accetta input su STDIN.

i=0
gsub(/./){i=i.send$&,"+-"[$&]?1:2}
p i

Guardalo su ideone (utilizza $_poiché ideone non accetta flag della riga di comando): http://ideone.com/3udQ3H


5

PHP 76 byte

for(;$c=$argv[1][$n++];)eval('$s=floor($s'.$c.(2-ord($c)%11%3).');');echo$s;

4

Python 2, 58 56 byte

-2 byte grazie a @Lynn

r=0
for c in input():exec'r=r'+c+`2-ord(c)%11%3`
print r

I ordinali dei personaggi +-*/sono 43,45,42,47di modulo 11 sono 10,1,9,3modulo 3 quelli sono 1,1,0,0, 2 meno quelli sono 1,1,2,2agli importi cui abbiamo bisogno per ogni operazione: r=r+1, r=r-1,r=r*2 , er=r/2


Precedente:

r=0
for c in input():exec'r=r'+c+`(ord(c)%5==2)+1`
print r

Che ne dici 2-ord(c)%11%3?
Lynn,

@Lynn Beh, lo prenderò se va bene con te? (ma penso davvero che sia abbastanza un cambiamento che potresti postare)
Jonathan Allan,

2
Vai avanti :) ----
Lynn,

4

Mathematica, 83 73 70 byte

10 byte salvati grazie a @MartinEnder .

(#/*##2&@@#/.Thread[{"+","-","*","/"}->{#+1&,#-1&,2#&,⌊#/2⌋&}])@0&

Funzione anonima. Prende un elenco di caratteri come input e restituisce un numero come output. Suggerimenti di golf benvenuti.


4

SILOS , 175 164 byte

loadLine
a=256
o=get a
lbla
a+1
o-42
p=o
p-1
p/p
p-1
r-p
s=o
s-3
s/s
s-1
r+s
m=o
m/m
m-2
m|
r*m
t=r
t%2
d=o
d-5
d/d
d-1
t*d
d-1
d|
r-t
r/d
o=get a
if o a
printInt r

Provalo online!

Metodo di input sano. Divisione intera corretta (arrotondata verso -infinito).


4

C #, 87 81 byte

int f(string s){int i=0;foreach(var c in s)i=c<43?i*2:c<46?i+44-c:i>>1;return i;}

Ungolfed:

int f(string s)
{
    int i = 0;

    foreach (var c in s)
        i = c < 43 ? i * 2
          : c < 46 ? i + 44 - c
          : i >> 1;

    return i;
}

Si presume che l'input sia valido. La divisione per due viene fatta spostando a destra di un bit, perché la divisione regolare viene sempre arrotondata verso zero e lo spostamento dei bit viene sempre arrotondato per difetto. Incremento e decremento fanno comodo uso della distanza 1 tra i codici ASCII per +e -.


Qualche amore per la nuova sintassi C # 6 e il metodo aggregato di Linq? int f(string s)=>s.Aggregate(0,(i,c)=>c<43?i*2:c<46?i+44-c:i>>1);(65 byte)
Cyril Gandon il

@CyrilGandon per quanto ne so che dovrebbe includere l '"utilizzo di System.Linq;", allungandolo di 19 e ponendolo a 84 byte. Ecco perché non l'ho fatto.
Scepheo,

4

Javascript (ES6), 57 byte (array) / 60 byte (intero)

Restituzione di una matrice di tutti i risultati intermedi:

o=>[...o].map(c=>x=[x>>1,x+1,x*2,x-1][eval(2+c+3)&3],x=0)

Ad esempio, l'output per "++**--/"sarà [1, 2, 4, 8, 7, 6, 3].

Restituendo solo il risultato finale:

o=>[...o].reduce((x,c)=>[x>>1,x+1,x*2,x-1][eval(2+c+3)&3],0)

Come funziona

Entrambe le soluzioni sono basate sulla stessa idea: utilizzando la funzione di hash perfetta eval(2+c+3)&3per mappare i diversi caratteri operatore cin [0, 3].

 operator | eval(2+c+3)  | eval(2+c+3)&3
----------+--------------+---------------
    +     |  2+3 = 5     |    5 & 3 = 1
    -     |  2-3 = -1    |   -1 & 3 = 3
    *     |  2*3 = 6     |    6 & 3 = 2
    /     |  2/3 ~= 0.67 | 0.67 & 3 = 0

3

JavaScript (ES6), 57

a=>[...a].map(c=>a=c<'+'?a<<1:c<'-'?-~a:c<'/'?~-a:a>>1)|a

Nota: il valore iniziale per accumulatore è la stringa del programma, usando le operazioni bit (~, >>, <<, |) viene convertito in 0 al primo utilizzo.

Come nota a margine, la risposta intelligente di @xnor segnerebbe 40 porting su javascript:

a=>[...a].map(c=>a=eval(~~a+c+2))&&a>>1

(se ti piace, vota per lui)

Test

f=a=>[...a].map(c=>a=c<'+'?a<<1:c<'-'?-~a:c<'/'?~-a:a>>1)|a

function update() {
  O.textContent = f(I.value);
}

update()
<input value='++**--/' id=I oninput='update()'><pre id=O></pre>


3

Java, 77 byte

int f(String s){return s.chars().reduce(0,(r,c)->c<43?r*2:c<46?r+44-c:r>>1);}

Utilizza java 8 stream.


1
Bella risposta, e benvenuta nel sito! Io non so nulla di Java, ma si può cambiare r >> 1a r>>1e salvare 2 byte?
DJMcMayhem

Hai assolutamente ragione, grazie @DJMcMayhem
primodemus,

1
Fantastico, felice di poterti aiutare! Un'altra nota, sto contando 77 byte. Ti è capitato di includere la nuova riga nel conteggio dei byte? Puoi togliere un altro byte poiché non è necessario.
DJMcMayhem

Corretta @DJMcMayhem ancora una volta, conta aparently wc del byte null-terminanting o qualcosa del genere ...
primodemus

1
mentre stai usando java8, perché non definire la funzione usando lambda, s->s.chars().reduce(0,(r,c)->c<43?r*2:c<46?r+44-c:r>>1);che ti darà 56 byte
user902383

3

GNU sed, 65 59 57 byte

Modifica: 2 byte in meno grazie ai commenti di Toby Speight

s/[+-]/1&/g
s/*/2&/g
s:/:d0>@2&:g
s/.*/dc -e"0[1-]s@&p"/e

Correre:

sed -f simple_calculator.sed <<< "*///*-*+-+"

Produzione:

-1

Lo sedscript prepara l'input per la dcchiamata della shell alla fine, quest'ultima accetta l'input nella notazione polacca inversa . Alla divisione, se il numero è negativo ( d0>), viene chiamato il [1-]comando di decremento memorizzato nel registro @. Esempio di conversione: + - * /-> 1+ 1- 2* d0>@2/.


Non hai bisogno delle virgolette intorno all'argomento su dc, se non ci sono spazi e nessun file corrispondente allo [1-]schema ...
Toby Speight,

@TobySpeight Nella mia mente ho cambiato il significato di swith S. Ho dimenticato che non sostituisce lo stack del registro, si spinge su di esso, con l'effetto contrario di quello che volevo (dal momento che l'ho usato per tutti /). Le virgolette sono ancora necessarie perché sono presenti /simboli che rendono la stringa interpretata come percorso del file :) Ho rasato 1 byte in più rimuovendo lo spazio dopo il -e.
seshoumara,

1
dc non interpreterà l'argomento -ecome un nome file, quindi non hai bisogno di virgolette per il /- provalo! Penso che sia ragionevole per un code-golf richiedere che l'attuale directory di lavoro non contenga alcun file che inizi con 01s@o 0-s@.
Toby Speight,

@TobySpeight avevi ragione -eriguardo a ciò /, tuttavia le citazioni sono ancora richieste come ho appena visto ora. Il >è interpretato direttamente dalla shell come operatore di reindirizzamento credo, dal momento che ho ottenuto questo errore:cannot create @2/d0: Directory nonexistent
seshoumara

Ah, sì, non ho considerato il >. Hai bisogno di citazioni, dopo tutto. Ci scusiamo per (tentando di) fuorviare! E, sebbene l'aggiunta di una barra rovesciata assomigli a un personaggio, deve essere raddoppiata in s///sostituzione, quindi nessun vantaggio lì ...
Toby Speight

3

PHP, 75 byte

Questo utilizza una versione modificata della risposta di Jörg Hülsermann .

eval(preg_replace('~.~','$s=($s\0(2-ord("\0")%11%3))|0;',$argv[1]));echo$s;

Si basa fortemente sulla sostituzione delle stringhe, usando una semplice espressione regolare ( ~.~).

La variabile $sviene riassegnata con il nuovo valore per ciascun carattere. Alla fine, genera il risultato.


Nota : questo è pensato per essere eseguito usando il -rflag.


Provalo qui:

Oppure prova: http://sandbox.onlinephpfunctions.com/code/7d2adc2a500268c011222d8d953d9b837f2312aa

differenze:

  • Invece di echo$s, sto usandosprintf($s) . Entrambi eseguono la stessa azione sui numeri. Dal momento che questo è solo per i test, va bene.
  • Nel caso in cui non vi siano argomenti passati, verrà eseguito come se fosse passato ++*+come primo argomento, che dovrebbe essere visualizzato 5.

Sìì! Il emodificatore è tornato! : D
Tito

@Titus Non capisco. Puoi elaborare un po '?
Ismael Miguel,

PHP prima della versione 7 aveva un modificatore di patterne , che è stato sostituito da preg_replace_callbacke potrebbe essere abusato di ... ma questo non è abbastanza.
Tito,

@Titus Quel modificatore patern è stato usato per dire che l'output sarebbe stato un vero codice PHP e per provare a mantenere corretta la sintassi. Questo qui, non lo usa, ma sostituisce ogni singolo carattere con un pezzo di codice da eseguire, indipendentemente dalla sua sintassi. Input errati causeranno gravi problemi di sicurezza.
Ismael Miguel,

Lo so. Ma ricorda.
Tito,

2

Lotto, 61 byte

@set n=
@for %%a in (%*)do @set/an=n%%a2^&-2
@cmd/cset/an/2

Traduzione della risposta eccellente di xxor Python.


2

Pyke, 24 22 byte

\*\}:\/\e:\+\h:\-\t:0E

Provalo qui!

O 12 byte (non competitivo)

~:"ht}e".:0E

Provalo qui!

Add translate node - basically multiple find and replace.

~:           -   "+-*/"
        .:   -  input.translate(^, V)
  "ht}e"     -   "ht}e"
          0E - eval(^, stack=0)

2

PHP, 104 102 82 bytes

First version with eval:

$i=0;while($c<9999)eval('$i'.['+'=>'++','-'=>'--','*'=>'*=2','/'=>'>>=1'][$argv[1]{$c++}].';');echo$i;

Second version with ternary operators:

while($o=ord($argv[1]{$c++}))$i=$o<43?$i*2:($o<44?$i+1:($o<46?$i-1:$i>>1));echo$i;

Takes the input string as first argument from the command line.

This "only" works for input strings shorter than 10,000 characters - which should be plenty. Tested with all the test cases, unfortunately can't save on the initialization in the beginning. Second version works with strings of any length and without initialization. :-)

The main element is the eval function which manipulates $i based on a map of arithmetic operations, which are pretty straightforward except for the division. PHP returns a float when using / and intdiv is too many bytes, so we do a right-shift.

Updates

  1. Saved 2 bytes by shortening $i=$i>>1 to $i>>=1 for integer division.
  2. Threw out eval in favor of ternary operators.

2

Python 3, 98 66 60 bytes

Thanks Tukkax!

Not as golfy as the other answer, but I can't compete with them without plagiarism.

i=0
for c in input():i+=[1,-i//2,-1,i][ord(c)%23%4]
print(i)

Also, I have a recursive lambda solution as well

73 67 bytes (improved!)

s=lambda x,z=0:s(x[1:],z+[1,-z//2,-1,z][ord(x[0])%23%4])if x else z

By applying part of your recursive solution to the procedural version: 60 bytes: i=0 for c in input():i+=[1,-i//2,-1,i][ord(c)%23%4] print(i). (not formatted properly of course). Also I think you should mention that you're using Python3. In Python2, input() would evaluate to int(raw_input()).
Yytsi

@TuukkaX doesn't work for z=0 (+- does 1)
Destructible Lemon

oh yes, my mistake.
Yytsi

1
Add the title Python3 please.
Yytsi

2

R, 201 bytes

Golfed

p=.Primitive;"-"="+"=function(x)p("+")(x,1);body(`-`)[[1]]=p("-");"*"="/"=function(x)p("*")(x,2);body(`/`)[[1]]=p("%/%");Reduce(function(f, ...)f(...),rev(mget(strsplit(scan(stdin(),""),"")[[1]])),0,T)

Commented

p = .Primitive                       # Redefine
"-" = "+" = function(x)p("+")(x,1)   # Define - and +
body(`-`)[[1]] = p("-")              # Change the body, what we do to save a byte
"*" = "/" = function(x)p("*")(x,2)   # Same as above
body(`/`)[[1]] = p("%/%")            # Same as above
Reduce(function(f, ...)f(...),       # Function wrapper to evaluate list of func.  
  rev(mget(strsplit(scan(stdin(),""),"")[[1]])), # Strsplit input into list of functions
  init = 0,                                      # Starting Arg = 1
  right = T)                                     # Right to left = True 

Strategy is to refine the +, -, % operators. Split the string then parse the string into a long list of functions, to be fed into Reduce()'s accumulator.

Couldn't golf it anymore. If someone can get b=body<- to work, there could be a few bytes of savings (refine every function with b after "-"="+"="/"="*"). Initially tried to substitute and parse eval, but the order of operations and parentheses were terrifying.


This is a year later, but I managed to get it down 10 bytes by swapping your approach a bit -- you can drop 8 bytes by removing the space between f, ... in the definition of the Reduce function and getting rid of stdin() in scan but I just tried a naive approach that dropped two more bytes by defining the functions a little differently. tio.run/##XcvLCsMgEAXQrwnO6Gge29B/…
Giuseppe

1

Lex + C, 78, 74, 73 bytes

The first character is a space.

 c;F(){yylex(c=0);return c;}
%%
\+ c++;
- c--;
\* c*=2;
\/ c=floor(c/2.);

Reads from stdin, returns result.

Compile with lex golfed.l && cc lex.yy.c main.c -lm -lfl, test main:

int main() { printf("%d\n", F()); }

1

Javascript (ES5), 127 bytes

function(b){for(a=c=0;a<b.length;++a)switch(b[a]){case"+":++c;break;case"-":--c;break;case"*":c*=2;break;case"/":c/=2}return c}

Ungolfed:

function c(a){
  c=0;
  for(var i=0;i<a.length;++i){
    switch(a[i]){
      case "+":++c;break;
      case "-":--c;break;
      case "*":c*=2;break;
      case "/":c/=2;break;
    }
  }
  return c;
}

1

Pyth, 23 bytes

FNQ=Z.v%".&%sZ2_2"N;/Z2

A full program that takes input as a string and prints the result.

This is a port of @xnor's Python answer.

Try it online

How it works

FNQ=Z.v%".&%sZ2_2"N;/Z2   Program. Input: Q. Z initialised as 0
FNQ                       For. For N in Q:
        ".&%sZ2_2"         String. Literal string ".&%sZ2_2"
       %          N        String format. Replace %s with the current operator N
           %sZ2            Operator. Yield Z*2, Z//2, Z+2, Z-2 as appropriate
         .&    _2          Bitwise and. Result of above & -2
     .v                    Evaluate. Yield the result of the expression
   =Z                      Assignment. Assign result of above to Z
                   ;      End. End for loop
                    /Z2   Integer division. Yield Z//2
                          Print. Print the above implicitly 

1
Converting Python to Pyth is mostly a bad idea. u@[yGhG0tG0/G2)CHQ0 19 bytes
Jakube

@Jakube Thanks - I am very new to Pyth, so any advice is appreciated. Feel free to post that as a separate answer, since it is a different approach.
TheBikingViking

1

PHP, 79 bytes

<?$i=0;switch($_POST['a']){case"+":$i+1;case"-":$i-1;case"/":$i/2;case"*":$i*2}

2
Include the bytecount in your header, remove uneccesary spaces and use 1-letter variable names.
TuxCrafting

Is this even golfed?! :-D
YetiCGN

@TùxCräftîñg I did it.
Winnie The Pooh

You divide and multiply by 1; you need to divide and multiply by 2
TuxCrafting

@TùxCräftîñg I did it.
Winnie The Pooh
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.