Einfacher Taschenrechner mit ganzzahliger Operation


28

Implementieren Sie einen skriptfähigen Taschenrechner mit einer einfachen Ganzzahloperation.

Konzept

Der Akku startet bei 0 und wird bedient. Am Ende des Programms wird der Wert des Akkus ausgegeben.

Operationen:

  • +fügt 1dem Akkumulator hinzu
  • -subtrahiert 1vom Akkumulator
  • * multipliziert den Akku mit 2
  • / dividiert den Akku durch 2

Beispielskript

Die Eingabe ++**--/sollte die Ausgabe geben 3.

Beispielimplementierung

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

Regeln

  • Dies ist . Die niedrigste Antwort in Byte gewinnt, ist jedoch nicht ausgewählt.
  • Kreative Umsetzungen sind erwünscht.
  • Standardlücken sind verboten.
  • Sie erhalten das Programm über stdin oder Argumente und können die Antwort über den Rückgabewert oder stdout ausgeben.
  • Habe Spaß.
  • Division wird abgeschnitten, da es sich um eine Ganzzahldivision handelt.
  • Das Programm -/kehrt zurück -1.

Testfälle

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

2
Also ... es ist nicht ganzzahlig, da es /sich um Nicht-Ganzzahlen handeln kann.
Conor O'Brien

2
Dann sollten Sie dies explizit angeben.
Conor O'Brien

5
Was soll -/zurückkehren?
Dennis

4
Ich kann nicht anders, als zu bemerken, dass der Codeausschnitt auf der Homepage von rust-lang diese Herausforderung löst.
Zwei

4
Bitte fügen Sie weitere Testfälle hinzu.
Martin Ender

Antworten:


28

Python 2, 48 Bytes

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

Does +2, -2, *2, oder /2. Indem +2und -2anstatt+1 und -1ausführen, arbeiten wir in doppelten Einheiten, sodass die endgültige Ausgabe halbiert werden muss. Ausgenommen, die Floor-Division muss /nun auf ein Vielfaches von 2 abgerundet werden, womit fertig ist &-2.


Das ist brilliant! Wenn Sie es selbst posten möchten, führt ein CJam-Port dies derzeit zur Herausforderung: 0q{2\~-2&}/2/( 2\~Evaliert den Operator mit dem zweiten Operanden 2, -2&ist das bitweise UND, 2/ist die endgültige Division durch zwei. Ist q{...}/ein Foreach über der Eingabe und 0ist nur der Anfang Wert.)
Martin Ender

Du kannst es posten, ich kenne CJam nicht.
xnor

Sehr schlau! Auf ES6
portiert,

Geniale Verwendung von Python. Daraus etwas Neues gelernt.
Jacobr365

12

Haskell, 51 Bytes

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

Anwendungsbeispiel: foldl(#)0 $ "++**--/"-> 3.


12

Jelly , 18 17 Bytes

‘

’

:2
Ḥ
O0;ṛĿ/

Probieren Sie es online!

Wie es funktioniert

Die ersten sechs Zeilen definieren Hilfslinks mit Indizes zwischen 1 und 6 ; sie inkrementieren, tun nichts, dekrementieren, tun nichts, halbieren (Bodenbelag) und verdoppeln.

Der Hauptlink - O0;ṛĿ/- konvertiert die eingegebenen Zeichen in ihre Codepunkte ( O), stellt dem Array von Codepunkten eine 0 (Anfangswert ) voran 0;und reduziert das generierte Array wie folgt.

Der Anfangswert ist das erste Element des Arrays, dh die vorangestellte 0 . Der Quicklink ṛĿwird für jedes folgende Element im Array aufgerufen, wobei der letzte Rückgabewert als linkes Argument und das aktuelle Element als rechtes Element angegeben werden. Es überprüft sein rechtes Argument ( ) und bewertet die Verknüpfung mit diesem Index monadisch ( Ŀ), wendet also die gewünschte Operation an.


10
Dies sieht aus wie die Gelee-Antwort mit den meisten Zeilenumbrüchen
Conor O'Brien

10

Python 2, 54 Bytes

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

Die Eingabe wird als Zeichenfolgenliteral interpretiert. ~ord(c)%5%3Ordnet die Operatoren den entsprechenden rechten Operanden zu.

Zuvor habe ich verwendet, hash(c)%55%3was nicht zu konsistenten Ergebnissen zwischen verschiedenen Versionen von Python führte. Dies ermutigte mich, andere Formeln zu erforschen.


scheint nicht zu funktionieren ...
Destructible Lemon

55,3 und 65,4 sind die beiden kürzesten für Double Mod of Hash in Python 2
Jonathan Allan

@ DestructibleWatermelon macht für mich: ideone
Jonathan Allan

Ich denke, hashist Python-Version spezifisch - Ideone verwendet 2.7.10, was [1, 1, 2, 2]als die vier Zuordnungen gibt, während ich lokal am 2.7.12[2, 0, 1, 0]
Sp3000

1
es funktioniert auf ideone, aber nicht auf meinem python computer. Wahrscheinlich versionsabhängig. In diesem Fall ist die Version zu beachten. EDIT: ninja'd: /
Destructible Lemon

10

SILOS , 133 211 Bytes

: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

Übernimmt die ASCII-Codes von Operatoren.

Probieren Sie es online mit Testfällen:
-/
++**--/
*///*-*+-+


ist loadLine golfspieler?
Rohan Jhunjhunwala

Das OP wurde geklärt. -/sollte -1 zurückgeben , nicht 0 .
Dennis

@ Tennis behoben. Es wurden jedoch viele Bytes hinzugefügt: /
betseg

9

Turing Machine - 23 Zustände (684 Bytes)

Probieren Sie es hier aus - 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

Die Eingabe sollte kein '*' enthalten, da es sich um ein Sonderzeichen im Turing-Maschinencode handelt. Verwenden Sie stattdessen 'x'. Gibt die Antwort binär aus.

Freier Code

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

Erklärung der Staaten:

Initialisierung:
Diese Zustände werden zu Beginn jedes Laufs, beginnend mit init2, einmal besucht

  • init2: Gehen Sie ganz nach rechts und setzen Sie ein '.'. Auf diese Weise weiß der TM, wann er aufhören muss. Wechseln Sie zu 'init0'.
  • init0: Bewegen Sie den gesamten Rücken nach links, bis der Kopf ein Leerzeichen liest. Verschieben Sie dann eine Zelle nach links. Wechseln Sie zu 'init1'.
  • init1: Setze eine Null und verschiebe eine Zelle nach rechts und wechsle zu 'readop'.

Anweisungen zum Lesen:
Diese Zustände werden während des gesamten Programms mehrmals besucht

  • readop: Bewegt sich ganz nach rechts, bis ein Operator oder das '.' Wenn es einen Operator trifft, wechseln Sie in den entsprechenden Status (+, -, x, /). Wenn ein '.' Angezeigt wird, wechseln Sie in den Status 'fin'.

  • return: Gibt den Kopf in den leeren Bereich zwischen der laufenden Summe und den Operatoren zurück. Dann wechselt er zu 'readop'.

Operationen:
Diese Operationen erledigen die eigentliche Drecksarbeit

  • +: Bewegen Sie sich nach links, bis der Kopf ein Nicht-Leerzeichen liest. Wenn dieses Zeichen ein "-" ist, bewegen Sie sich nach links und wechseln Sie zu "dec". Andernfalls wechseln Sie zu 'inc'.

  • -: Ähnlich wie '+', außer dass 'inc' geändert wird, wenn es ein '-' und andernfalls 'dec' gibt.

  • inc: Wenn die Ziffer unter dem Kopf eine 0 (oder ein Leerzeichen) ist, ändern Sie sie in 1 und dann in 'Null'. Wenn die Ziffer eine 1 ist, ändern Sie sie in 0 und wiederholen Sie den Vorgang bei der nächsten Ziffer.

  • dec: Ähnlich wie inc, außer dass 1 zu 0 geht, 0 zu 1 geht und wenn der Kopf ein Leerzeichen liest, zu 'neg' wechseln.

  • x, x0, x1: Verschieben Sie die Nummer eins nach links. Wechseln Sie zu "Zurück".

  • /, //, div, div0, div1: Bewegen Sie sich ganz nach rechts von der Zahl, und verschieben Sie dann die Bits um eins nach rechts. Wenn ein '-' angezeigt wird, wechseln Sie zu 'inc'. Dies simuliert das Abrunden negativer Zahlen. Andernfalls ändern Sie auf "Null"

  • neg: Platziere ein '-' nach der Zahl und ändere sie in 'readop'

  • zero, zero1, zero2: Entferne führende Nullen und wechsle zu 'readop'

Aufräumen: Macht die Ausgabe präsentierbar

  • fin, min: Bewegen Sie bei Bedarf das '-' vor die Zahl. Halt.

1
Ich fand es sehr cool, diesen Code zu lesen. Also danke, dass du mir den Tag verschönert hast.
Jacobr365

8

Perl 6 , 53  52 Bytes

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

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

Erläuterung:

# 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)
}

Verwendung:

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 Bytes

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 Bytes

Vielen Dank an Enigma für die -/Fehlerbehebung!

Für 16 Bytes , wenn es nicht ganzzahligen Division ist: Î"+-*/""><·;"‡.V.

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

Erläuterung:

Î                      # 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

Verwendet die CP-1252- Codierung. Probieren Sie es online!


Das OP wurde geklärt. -/sollte -1 zurückgeben , nicht 0 .
Dennis

Das Problem mit Î…+-*"><·"‡'/"2÷":.Vder negativen Zahlenteilung konnte bei gleicher Bytezahl behoben werden .
Emigna

@ Tennis Problem behoben.
Adnan

@Emigna Danke :)
Adnan

5

JavaScript ES6, 80 68 Bytes

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

Dank Neil konnten satte 12 Bytes eingespart werden!


Die zweite Antwort wäre lesbarer, wenn Sie die entfernen "c"+und schreiben "c+1 c-1 c*2 c/2|0".splitusw.
Neil

Schreiben o=>c=[c+1,c-1,c*2,c/2|0]["+-*/".indexOf(o)]Sie für die erste Antwort, warum nicht , oder ich denke, Sie können dann mit ein weiteres Byte speichern 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)könnte noch kürzer
Neil

@ Neil Ah, ja, das habe ich vergessen
Conor O'Brien

1
Irgendwie hat man zwischen }und Zeichen mit der Breite Null [o], das ist also eigentlich nur 66 Bytes lang. Auch das OP wurde geklärt; -/sollte -1 zurückgeben , nicht 0 .
Dennis

5

Ruby, 48 44 42 + 1 = 43 Bytes

+1 Byte für -nFlag. Übernimmt die Eingabe für STDIN.

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

Sieh es auf ideone (wird verwendet, $_da ideone keine Befehlszeilenflags akzeptiert): http://ideone.com/3udQ3H



4

Python 2, 58 56 Bytes

-2 Bytes dank @Lynn

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

Die ordinals der Charaktere +-*/sind 43,45,42,47Modulo - 11 sind diese 10,1,9,3Modulo - 3 sind diejenigen 1,1,0,0, 2 weniger diejenigen sind , 1,1,2,2geben die Beträge , die wir für jede Operation benötigen r=r+1, r=r-1,r=r*2 , undr=r/2


Bisherige:

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

Wie wäre es mit 2-ord(c)%11%3 es ?
Lynn

@Lynn Nun, ich nehme es, wenn es Ihnen recht ist. (Aber denke wirklich, es ist genug von einer Änderung, die du posten könntest)
Jonathan Allan

2
Gehen Sie voran :) ----
Lynn

4

Mathematica, 83 73 70 Bytes

10 Bytes aufgrund von @MartinEnder gespeichert .

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

Anonyme Funktion. Nimmt eine Liste von Zeichen als Eingabe und gibt eine Zahl als Ausgabe zurück. Golfvorschläge sind willkommen.


4

SILOS , 175 bis 164 Bytes

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

Probieren Sie es online!

Gesunde Eingabemethode. Korrekte Ganzzahlteilung (rund gegen -unendlich).


4

C #, 87 81 Bytes

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;
}

Die Eingabe wird als gültig angenommen. Die Division durch zwei erfolgt durch Verschieben um ein Bit nach rechts, da die reguläre Division immer in Richtung Null rundet und die Bitverschiebung immer abrundet. Inkrementieren und Dekrementieren Sie den Abstand 1 zwischen den ASCII-Codes für+ und -.


Sie lieben die neue C # 6-Syntax und die Aggregatmethode von Linq? int f(string s)=>s.Aggregate(0,(i,c)=>c<43?i*2:c<46?i+44-c:i>>1);(65 Bytes)
Cyril Gandon

@CyrilGandon Soweit ich weiß, müsste das "using System.Linq;" enthalten sein, wodurch es 19 länger wird und 84 Bytes umfasst. Deshalb habe ich es nicht getan.
Scepheo

4

Javascript (ES6), 57 Byte (Array) / 60 Byte (Ganzzahl)

Ein Array aller Zwischenergebnisse zurückgeben:

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

Beispielsweise wird die Ausgabe für "++**--/"sein[1, 2, 4, 8, 7, 6, 3] .

Rückgabe nur des Endergebnisses:

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

Wie es funktioniert

Beide Lösungen basieren auf derselben Idee: Verwenden der perfekten Hash-Funktion eval(2+c+3)&3, um die verschiedenen Operatorzeichen cin abzubilden [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

Hinweis: Der Anfangswert des Akkumulators ist die Programmzeichenfolge, die bei der ersten Verwendung mithilfe von Bitoperationen (~, >>, <<, |) in 0 konvertiert wird.

Als Randnotiz, die clevere Antwort von @xnor würde 40 Punkte ergeben, die auf Javascript portiert sind:

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

(wenn dir das gefällt, stimme für ihn)

Prüfung

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 Bytes

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

Verwendet Java 8-Streams.


1
Schöne Antwort und willkommen auf der Seite! Ich weiß nichts über Java, aber können Sie ändern r >> 1zu r>>1und speichern 2 Bytes?
DJMcMayhem

Du bist absolut korrekt, danke @DJMcMayhem
Primodemus

1
Super, froh, dass ich helfen konnte! Noch eine Anmerkung, ich zähle 77 Bytes. Haben Sie die neue Zeile zufällig in Ihre Byteanzahl aufgenommen? Sie können ein weiteres Byte entfernen, da dies nicht erforderlich ist.
DJMcMayhem

Korrigieren Sie noch einmal @DJMcMayhem, offensichtlich wc zählt das nullterminierende Byte oder so etwas ...
primodemus

1
Wenn Sie Java8 verwenden, warum definieren Sie die Funktion nicht mit Lambda s->s.chars().reduce(0,(r,c)->c<43?r*2:c<46?r+44-c:r>>1);
? Dann erhalten

3

GNU sed, 65 59 57 Bytes

Edit: 2 Bytes kürzer dank Toby Speights Kommentaren

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

Lauf:

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

Ausgabe:

-1

Das sedSkript bereitet die Eingabe für den dcShell-Aufruf am Ende vor, wobei letzterer die Eingabe in umgekehrter polnischer Notation akzeptiert . Wenn die Zahl bei der Division negativ ist ( d0>), wird der [1-]im Register gespeicherte Dekrementierungsbefehl @aufgerufen. Umrechnungsbeispiel: + - * /-> 1+ 1- 2* d0>@2/.


Sie brauchen nicht die Anführungszeichen um das Argument zu dc, wenn es keine Leerzeichen und keine Dateien gibt, die mit dem [1-]Muster übereinstimmen ...
Toby Speight

@TobySpeight In meinen Gedanken wechselte ich die Bedeutung von smit S. Ich habe vergessen, dass es nicht den Stack des Registers ersetzt, sondern darauf drückt und den gegenteiligen Effekt hat, den ich wollte (da ich es für alle verwendet habe /). Die Anführungszeichen werden weiterhin benötigt, da Sie /Symbole enthalten, die die Zeichenfolge als Dateipfad interpretieren. Ich habe 1 Byte mehr rasiert, indem ich das Leerzeichen nach dem entfernt habe -e.
Seshoumara

1
dc interpretiert das Argument von nicht -eals Dateinamen, Sie brauchen also keine Anführungszeichen für die /- probieren Sie es aus! Ich halte es für vernünftig, dass ein Code-Golf verlangt, dass das aktuelle Arbeitsverzeichnis keine Dateien enthält, die mit 01s@oder beginnen 0-s@.
Toby Speight

@TobySpeight du hattest Recht in -eBezug auf /, aber die Anführungszeichen sind immer noch erforderlich, wie ich gerade gesehen habe. Das >wird direkt von der Shell als Redirect-Operator interpretiert, denke ich, da ich diesen Fehler bekommen habe:cannot create @2/d0: Directory nonexistent
seshoumara

Ach ja, ich habe das nicht in Betracht gezogen >. Sie brauchen doch Zitate. Entschuldigung für die Irreführung! Und obwohl das Hinzufügen eines Backslashs wie ein Zeichen aussieht, muss es in einem s///Ersatz verdoppelt werden , sodass es keinen Nutzen bringt ...
Toby Speight,

3

PHP, 75 Bytes

Hierbei wird eine modifizierte Version der Antwort von Jörg Hülsermann verwendet .

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

Die Verwendung eines einfachen regulären Ausdrucks ( ~.~) ist stark von der Ersetzung von Zeichenfolgen abhängig .

Die Variable $swird mit dem neuen Wert für jedes Zeichen neu zugewiesen. Am Ende gibt es das Ergebnis aus.


Hinweis : Dies soll mit dem -rFlag ausgeführt werden .


Probieren Sie es hier aus:

Oder probieren Sie an: http://sandbox.onlinephpfunctions.com/code/7d2adc2a500268c011222d8d953d9b837f2312aa

Unterschiede:

  • Stattdessen echo$sbenutze ichsprintf($s) . Beide führen dieselbe Aktion für Zahlen aus. Da dies nur zum Testen ist, ist es in Ordnung.
  • Falls es kein übergebenes Argument gibt, wird es so ausgeführt, als ob Sie es ++*+als erstes Argument übergeben hätten, was angezeigt werden sollte 5.

Yay! Der eModifikator ist zurück! : D
Titus

@Titus Ich verstehe es nicht. Können Sie etwas näher darauf eingehen?
Ismael Miguel

PHP vor Version 7 hatte einen Pattern-Modifikatore , der durch einen ersetzt wurde preg_replace_callbackund für den es missbräuchlich sein könnte ... aber das ist nicht ganz so.
Titus

@Titus Dieser Patern-Modifikator wurde verwendet, um anzuzeigen, dass die Ausgabe tatsächlicher PHP-Code ist, und um zu versuchen, die Syntax korrekt zu halten. Dies hier wird nicht verwendet, sondern es wird jedes einzelne Zeichen durch einen auszuführenden Code ersetzt, unabhängig von seiner Syntax. Fehlerhafte Eingaben verursachen schwerwiegende Sicherheitsprobleme.
Ismael Miguel

Ich kenne. Aber es ähnelt.
Titus

2

Batch, 61 Bytes

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

Übersetzung von @ xnors xcellent Python-Antwort.


2

Pyke, 24 22 Bytes

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

Probieren Sie es hier aus!

Oder 12 Bytes (nicht konkurrenzfähig)

~:"ht}e".:0E

Probieren Sie es hier aus!

translateKnoten hinzufügen - im Grunde genommen mehrere Suchen und Ersetzen.

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

2

PHP, 104 102 82 Bytes

Erste Version mit Auswertung:

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

Zweite Version mit ternären Operatoren:

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

Nimmt die Eingabezeichenfolge als erstes Argument von der Befehlszeile.

Dies funktioniert "nur" für Eingabezeichenfolgen, die kürzer als 10.000 Zeichen sind - das sollte ausreichend sein. Getestet mit allen Testfällen, kann die Initialisierung am Anfang leider nicht speichern. Die zweite Version funktioniert mit Strings beliebiger Länge und ohne Initialisierung. :-)

Das Hauptelement ist die Auswertungsfunktion, die $iauf der Grundlage einer Karte von arithmetischen Operationen manipuliert wird , die mit Ausnahme der Teilung ziemlich einfach sind. PHP gibt bei der Verwendung ein Float zurück /und intdivist zu groß, also machen wir das eine Rechtsverschiebung .

Aktualisierung

  1. 2 Bytes durch Verkürzung eingespart $i=$i>>1 auf $i>>=1für Ganzzahldivision .
  2. Eval zugunsten von ternären Operatoren rausgeworfen.

2

Python 3, 98 66 60 Bytes

Vielen Dank, Tukkax!

Nicht so golfen wie die andere Antwort, aber ohne Plagiat kann ich nicht mit ihnen mithalten.

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

Außerdem habe ich auch eine rekursive Lambda-Lösung

73 67 Bytes (verbessert!)

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

Teil Ihrer rekursive Lösung der Verfahrensversion Durch die Anwendung: 60 Bytes i=0 for c in input():i+=[1,-i//2,-1,i][ord(c)%23%4] print(i). (Natürlich nicht richtig formatiert). Außerdem sollten Sie erwähnen, dass Sie Python3 verwenden. In Python2 input()würde auswerten int(raw_input()).
Yytsi

@ TuukkaX funktioniert nicht für z = 0 ( +-tut 1)
Destructible Lemon

Oh ja, mein Fehler.
Yytsi

1
Fügen Sie bitte den Titel Python3 hinzu.
Yytsi

2

R, 201 Bytes

Golf gespielt

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)

Kommentiert

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 

Strategie ist es, die +, -, %Betreiber zu verfeinern . Teilen Sie die Zeichenfolge auf und analysieren Sie sie in eine lange Liste von Funktionen, die eingespeist werden sollenReduce()'s Akkumulator eingegeben werden sollen.

Konnte nicht mehr Golf spielen. Wenn jemand b=body<-zur Arbeit kommen kann, kann dies zu Einsparungen von einigen Bytes führen (jede Funktion mit bafter verfeinern "-"="+"="/"="*"). Anfänglich wurde versucht, eval zu ersetzen und zu analysieren, aber die Reihenfolge der Operationen und Klammern war erschreckend.


Dies ist ein Jahr später, aber ich habe es geschafft, 10 Bytes zu reduzieren, indem ich Ihren Ansatz ein wenig vertauschte. Sie können 8 Bytes löschen, indem Sie das Leerzeichen zwischen f, ...der Definition der ReduceFunktion und dem Loswerden von stdin()in entfernen, scanaber ich habe es nur mit Naivität versucht Ansatz, bei dem zwei weitere Bytes verloren gingen, indem die Funktionen etwas anders definiert wurden. tio.run/##XcvLCsMgEAXQrwnO6Gge29B/…
Giuseppe

1

Lex + C, 78 , 74 , 73 Bytes

Das erste Zeichen ist ein Leerzeichen.

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

Liest aus stdin , gibt das Ergebnis zurück.

Kompiliere mit lex golfed.l && cc lex.yy.c main.c -lm -lfl, test main:

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

1

Javascript (ES5), 127 Byte

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

Ein vollständiges Programm, das Eingaben als Zeichenfolge akzeptiert und das Ergebnis ausgibt.

Dies ist eine Portierung von @ xnors Python-Antwort .

Probieren Sie es online aus

Wie es funktioniert

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
Das Konvertieren von Python in Pyth ist meistens eine schlechte Idee. u@[yGhG0tG0/G2)CHQ019 Bytes
Jakube

@ Jakube Danke - Ich bin ein Neuling in Pyth, daher sind alle Ratschläge willkommen. Fühlen Sie sich frei, dies als separate Antwort zu posten, da dies ein anderer Ansatz ist.
TheBikingViking

1

PHP, 79 Bytes

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

2
Fügen Sie den bytecount in Ihre Kopfzeile ein, entfernen Sie nicht benötigte Leerzeichen und verwenden Sie Variablennamen mit einem Buchstaben.
TuxCrafting

Ist das überhaupt Golf ?! :-D
YetiCGN

@ TùxCräftîñg Ich habe es geschafft.
Winnie The Pooh

Sie teilen und multiplizieren mit 1; Sie müssen teilen und multiplizieren mit2
TuxCrafting

@ TùxCräftîñg Ich habe es geschafft.
Winnie The Pooh
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.