Simple integer operation calculator

Implement a simple integer operation scriptable calculator.

Concept

The accumulator starts at 0 and has operations performed on it. At the end of the program output the value of the accumulator.

Operations:

• + adds 1 to the accumulator
• - subtracts 1 from the accumulator
• * multiplies the accumulator by 2
• / divides the accumulator by 2

Sample script

The input ++**--/ should give the output 3.

Example implementation

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


Rules

• This is , so lowest answer in bytes wins, but is not selected.
• Creative implementations are encouraged.
• Standard loopholes are prohibited.
• You get the program via stdin or arguments, and you can output the answer via return value or stdout.
• Have fun.
• Division truncates down because it is integer division.
• The program -/ returns -1.

Test cases

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

• So... it's not strictly integer, since / can yield non-integers. – Conor O'Brien Aug 28 '16 at 22:52
• Then you should specify this explicitly. – Conor O'Brien Aug 28 '16 at 22:55
• What should -/ return? – Dennis Aug 28 '16 at 23:32
• I can't help but notice that the snippet of code featured on the home page of rust-lang solves this challenge. – Zwei Aug 29 '16 at 3:23
• Please add more test cases. – Martin Ender Aug 29 '16 at 7:38

Python 2, 48 bytes

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


Does +2, -2, *2, or /2. By doing +2 and -2 rather than +1 and -1, we're working in doubled units, so the final output needs to be halved. Except, the floor-division / now needs to round down to a multiple of 2, which is done with &-2.

• This is brilliant! If you want to post it yourself a CJam port of this would currently be leading the challenge: 0q{2\~-2&}/2/ (2\~ evals the operator with second operand 2, -2& is the bitwise AND, 2/ is the final division by two. q{...}/ is a foreach over the input and 0 is just the initial value.) – Martin Ender Aug 29 '16 at 10:06
• You can post it, I don't know CJam. – xnor Aug 29 '16 at 10:07
• Really clever! Ported to ES6 this would easily outperform my answer – edc65 Aug 29 '16 at 10:19
• Brilliant use of python. Learned something new from this. – Jacobr365 Aug 29 '16 at 13:25

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


Usage example: foldl(#)0 $"++**--/" -> 3. Jelly, 18 17 bytes ‘ ’ :2 Ḥ O0;ṛĿ/  Try it online! How it works The first six lines define helper links with indices ranging from 1 to 6; they increment, do nothing, decrement, do nothing, halve (flooring), and double. The main link – O0;ṛĿ/ – converts the input characters to their code points (O), prepends a 0 (initial value) to the array of code points 0;, then reduces the generated array as follows. The initial value is the first element of the array, i.e., the prepended 0. The quicklink ṛĿ is called for every following element in the array, with the last return value as left argument and the current element as right one. It inspects its right argument (ṛ) and evaluates the link with that index monadically (Ŀ), thus applying the desired operation. • This looks like the jelly answer with the most newlines – Conor O'Brien Aug 28 '16 at 23:28 Python 2, 54 bytes i=0 for c in input():exec"i=i"+c+~ord(c)%5%3 print i  Input is taken as a string literal. ~ord(c)%5%3 maps the operators to the corresponding right operands. Previously, I used hash(c)%55%3 which didn't yield consistent results between different versions of Python. This encouraged me to explore other formulas. • doesn't seem to work... – Destructible Lemon Aug 29 '16 at 1:18 • 55,3 and 65,4 are the two shortest for double mod of hash in python 2 – Jonathan Allan Aug 29 '16 at 1:18 • @DestructibleWatermelon does for me: ideone – Jonathan Allan Aug 29 '16 at 1:24 • I think hash is Python version specific - ideone uses 2.7.10 which gives [1, 1, 2, 2] as the four mappings, whereas locally on 2.7.12 I get [2, 0, 1, 0] – Sp3000 Aug 29 '16 at 1:29 • it works on ideone, but not on my computers python. Probably version dependent, in which case version should be noted EDIT: ninja'd :/ – Destructible Lemon Aug 29 '16 at 1:30 S.I.L.O.S, 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  Takes the ASCII codes of operators. Try it online with test cases: -/ ++**--/ *///*-*+-+ • is loadLine golfier? – Rohan Jhunjhunwala Aug 29 '16 at 1:59 • The OP clarified; -/ should return -1, not 0. – Dennis Aug 29 '16 at 2:53 • @Dennis fixed. Added a lot of bytes though :/ – betseg Aug 29 '16 at 11:10 Turing Machine - 23 states (684 bytes) Try it here - 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  Input should not contain any '*' since it is a special character in Turing machine code. Use 'x' instead. Outputs the answer in binary. Unobfuscated 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  Explanation of the states: Initialization: These states are visited once at the beginning of each run, starting with init2 • init2: Move all the way to the right and put a '.'. That way the TM knows when to stop. Change to 'init0'. • init0: Move all the back to the left until the head reads a space. Then move one cell to the left. Change to 'init1'. • init1: Put a zero and move one cell to the right and change to 'readop'. Reading instructions: These states will be visited multiple times throughout the program • readop: Moves all the way to the right until it reads an operator or the '.'. If it hits an operator, change to the corresponding state (+,-,x,/). If it hits a '.', change to state 'fin'. • return: Returns the head to the empty space between the running total and the operators. Then changes to 'readop'. Operations: These operations do the actual dirty work • +: Move to the left until the head reads any non- whitespace character. If this character is a '-', move left and change to 'dec'. Otherwise, change to 'inc'. • -: Similar to '+', except change to 'inc' if there is a '-' and 'dec' otherwise. • inc: If the digit under the head is a 0 (or a whitespace), change it to 1 and change to 'zero'. If the digit is a 1, change it to 0, then repeat on the next digit. • dec: Similar to inc, except 1 goes to 0, 0 goes to 1, and if the head reads a whitespace, change to 'neg'. • x, x0, x1: Bitshift the number one to the left. Change to 'return'. • /, //, div, div0, div1: Move all the way to the right of the number, then bitshift one to the right. If there is a '-', change to 'inc'. This simulates rounding down negative numbers. Otherwise, change to 'zero' • neg: Place a '-' after the number then change to 'readop' • zero, zero1, zero2: Remove leading zeros and change to 'readop' Cleanup: Makes the output presentable • fin, min: Move the '-' in front of the number if necessary. Halt. • Thought reading this code was very very cool. So thanks for brightening up my day. – Jacobr365 Aug 30 '16 at 12:58 Perl 6, 53 52 bytes {([Ro] %(<+ - * />Z=>*+1,*-1,* *2,*div 2){.comb})(0)}  {[Ro](%(<+ - * />Z=>*+1,*-1,*×2,*div 2){.comb})(0)}  Explanation: # 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) }  Usage: my$input = '++**--/'
my $output = {[Ro](%(<+ - * />Z=>*+1,*-1,*×2,*div 2){.comb})(0)}.($input );
say $output; # 3 say$output.^name; # Int


C, 6362 57 bytes

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


Wandbox

05AB1E, 20 bytes

Thanks to Enigma for fixing the -/-bug!

For 16 bytes if it wasn't integer division: Î"+-*/""><·;"‡.V.

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


Explanation:

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


Uses the CP-1252 encoding. Try it online!

• The OP clarified; -/ should return -1, not 0. – Dennis Aug 29 '16 at 3:04
• The negative number division issue could be fixed with Î…+-*"><·"‡'/"2÷":.V for the same byte count. – Emigna Aug 29 '16 at 8:46
• @Dennis Fixed the problem. – Adnan Aug 29 '16 at 9:59
• @Emigna Thanks :) – Adnan Aug 29 '16 at 10:00

JavaScript ES6, 80 68 bytes

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


Saved a whopping 12 bytes thanks to Neil!

• Second answer would be more readable if you removed the "c"+ and wrote "c+1 c-1 c*2 c/2|0".split etc. – Neil Aug 28 '16 at 23:42
• For the first answer, why not write o=>c=[c+1,c-1,c*2,c/2|0]["+-*/".indexOf(o)], or I think you can then go on to save a further byte using o=>c={"+":c+1,"-":c-1,"*":c*2,"/":c/2|0}[o]. – Neil Aug 28 '16 at 23:46
• k=>[...k].reduce((c,o)=>+{"+":c+1,"-":c-1,"*":c*2,"/":c/2|0}[o],0) might work out even shorter still, but I've lost count... – Neil Aug 28 '16 at 23:48
• You somehow got to zero-width characters between } and [o], so this is actually only 66 bytes long. Also, the OP clarified; -/ should return -1, not 0. – Dennis Aug 29 '16 at 2:59

Ruby, 4844 42 + 1 = 43 bytes

+1 byte for -n flag. Takes input on STDIN.

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


See it on ideone (uses $_ since ideone doesn't take command line flags): http://ideone.com/3udQ3H PHP 76 Bytes for(;$c=$argv[1][$n++];)eval('$s=floor($s'.$c.(2-ord($c)%11%3).');');echo$s;  Python 2, 58 56 bytes -2 bytes thanks to @Lynn r=0 for c in input():exec'r=r'+c+2-ord(c)%11%3 print r  The ordinals of the characters +-*/ are 43,45,42,47 modulo 11 these are 10,1,9,3 modulo 3 those are 1,1,0,0, 2 less those are 1,1,2,2 giving the amounts we need for each operation: r=r+1, r=r-1, r=r*2, and r=r/2 Previous: r=0 for c in input():exec'r=r'+c+(ord(c)%5==2)+1 print r  • How about 2-ord(c)%11%3? – Lynn Aug 29 '16 at 2:36 • @Lynn Well I'll take it if its OK with you? (but really think it's enough of a change you could post it) – Jonathan Allan Aug 29 '16 at 2:41 • Go ahead :) ---- – Lynn Aug 29 '16 at 2:42 Mathematica, 8373 70 bytes 10 bytes saved due to @MartinEnder. (#/*##2&@@#/.Thread[{"+","-","*","/"}->{#+1&,#-1&,2#&,⌊#/2⌋&}])@0&  Anonymous function. Takes a list of characters as input and returns a number as output. Golfing suggestions welcome. S.I.L.O.S, 175 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  Try it online! Sane input method. Correct integer division (round towards -infinity). 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; }  Input is assumed to be valid. Division by two is done by shifting right one bit, because regular division always rounds towards zero, and bit shifting always rounds down. Increment and decrement make handy use of the 1 distance between the ASCII codes for + and -. • Some love for new C#6 syntax and aggregate method of 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 Aug 30 '16 at 14:38 • @CyrilGandon as far as I'm aware that would have to include the "using System.Linq;", making it 19 longer and putting it at 84 bytes. Which is why I didn't do it. – Scepheo Aug 30 '16 at 15:12 Javascript (ES6), 57 bytes (array) / 60 bytes (integer) Returning an array of all intermediate results: o=>[...o].map(c=>x=[x>>1,x+1,x*2,x-1][eval(2+c+3)&3],x=0)  For instance, the output for "++**--/" will be [1, 2, 4, 8, 7, 6, 3]. Returning only the final result: o=>[...o].reduce((x,c)=>[x>>1,x+1,x*2,x-1][eval(2+c+3)&3],0)  How it works Both solutions are based on the same idea: using the perfect hash function eval(2+c+3)&3 to map the different operator characters c in [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  JavaScript (ES6), 57 a=>[...a].map(c=>a=c<'+'?a<<1:c<'-'?-~a:c<'/'?~-a:a>>1)|a  Note: the initial value for accumulator is the program string, using bit operations (~, >>, <<, |) it is converted to 0 at first use. As a side note, the clever answer of @xnor would score 40 ported to javascript: a=>[...a].map(c=>a=eval(~~a+c+2))&&a>>1  (if you like this, vote for him) 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> 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);}  Uses java 8 streams. • Nice answer, and welcome to the site! I don't know anything about java, but can you change r >> 1 to r>>1 and save 2 bytes? – James Aug 30 '16 at 21:15 • You're absolutely correct, thanks @DJMcMayhem – primodemus Aug 30 '16 at 21:21 • Awesome, glad I could help! One more note, I'm counting 77 bytes. Did you happen to include the newline in your byte count? You can take one more byte off since that isn't necessary. – James Aug 30 '16 at 21:22 • Correct again @DJMcMayhem , aparently wc counts the null-terminanting byte or something... – primodemus Aug 30 '16 at 21:35 • as you are using java8, why don't define function by using lambda, s->s.chars().reduce(0,(r,c)->c<43?r*2:c<46?r+44-c:r>>1); that will give you 56 bytes – user902383 Aug 31 '16 at 13:51 GNU sed, 6559 57 bytes Edit: 2 bytes shorter thanks to Toby Speight's comments s/[+-]/1&/g s/*/2&/g s:/:d0>@2&:g s/.*/dc -e"0[1-]s@&p"/e  Run: sed -f simple_calculator.sed <<< "*///*-*+-+"  Output: -1  The sed script prepares the input for the dc shell call at the end, the latter accepting the input in Reverse Polish notation. On division, if the number is negative (d0>), the [1-] decrement command stored in register @ is called. Conversion example: + - * / --> 1+ 1- 2* d0>@2/. • You don't need the quotes around the argument to dc, if there's no spaces, and no files matching the [1-] pattern... – Toby Speight Aug 30 '16 at 8:31 • @TobySpeight In my mind I switched the meaning of s with S. I forgot that it doesn't replace the registry's stack, it pushes onto it, having the contrary effect of what I wanted (since I used it for every /). The quotes are still needed because you have / symbols in it making the string interpreted as a file path :) I shaved 1 byte more by removing the space after the -e. – seshoumara Aug 30 '16 at 9:20 • dc won't intepret argument of -e as a filename, so you don't need quotes for the / - try it! I think it's a reasonable for a code-golf to require that the current working directory not contain any files beginning with 01s@ or 0-s@. – Toby Speight Aug 30 '16 at 14:15 • @TobySpeight you were right about -e regarding /, however the quotes are still required as I just saw now. The > is interpreted directly by the shell as a redirect operator I think, since I got this error: cannot create @2/d0: Directory nonexistent – seshoumara Aug 30 '16 at 15:55 • Ah, yes, I didn't consider the >. You do need quotes, after all. Apologies for (attempting to) mislead! And, although adding a backslash looks like one character, it needs to be doubled in a s/// replacement, so no benefit there... – Toby Speight Aug 30 '16 at 16:17 PHP, 75 bytes This uses a modified version of Jörg Hülsermann's answer. eval(preg_replace('~.~','$s=($s\0(2-ord("\0")%11%3))|0;',$argv[1]));echo$s;  It heavily relies on string substitution, using a simple regular expression (~.~). The variable $s is re-assigned with the new value for each character. At the end, it outputs the result.

Note: This is meant to be executed using the -r flag.

Try it here:

if('\0' == "\0")
{
$argv = Array($s = 0, prompt());
function preg_replace($pattern,$replacement, $subject) {$regexp = new RegExp($pattern.replace(new RegExp('~', 'g'), ''), 'g'); return$subject.replace($regexp,$replacement.split('\0').join('$&')); } function printf($string)
{
console.log($string); } function ord($chr)
{
return $chr.charCodeAt(0); } } else { if(!isset($argv))
{

1. Saved 2 bytes by shortening $i=$i>>1 to $i>>=1 for integer division. 2. Threw out eval in favor of ternary operators. Python 3, 9866 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 Aug 29 '16 at 7:11 • @TuukkaX doesn't work for z=0 (+- does 1) – Destructible Lemon Aug 29 '16 at 9:23 • oh yes, my mistake. – Yytsi Aug 29 '16 at 10:21 • Add the title Python3 please. – Yytsi Aug 29 '16 at 13:48 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 Jun 7 '17 at 14:39 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()); }  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; }  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  • Converting Python to Pyth is mostly a bad idea. u@[yGhG0tG0/G2)CHQ0 19 bytes – Jakube Aug 29 '16 at 15:34 • @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 Aug 29 '16 at 17:37 PHP, 79 bytes <?$i=0;switch($_POST['a']){case"+":$i+1;case"-":$i-1;case"/":$i/2;case"*":\$i*2}

• You divide and multiply by 1; you need to divide and multiply by 2 – TuxCrafting Aug 29 '16 at 17:58