Simple integer operation calculator

28

9

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

dkudriavtsev

Posted 2016-08-28T22:51:52.017

Reputation: 5 781

2So... it's not strictly integer, since / can yield non-integers. – Conor O'Brien – 2016-08-28T22:52:56.323

2Then you should specify this explicitly. – Conor O'Brien – 2016-08-28T22:55:16.790

5What should -/ return? – Dennis – 2016-08-28T23:32:09.290

@Dennis Well, C truncation says it should round to 0, so that should be 0... – LegionMammal978 – 2016-08-28T23:58:22.433

@LegionMammal978 Yet the reference implementation returns -1.

– Dennis – 2016-08-29T00:07:28.290

4I can't help but notice that the snippet of code featured on the home page of rust-lang solves this challenge. – Zwei – 2016-08-29T03:23:45.177

1@Zwei That's exactly where I got this challenge. – dkudriavtsev – 2016-08-29T04:13:31.417

My recursive solution returns an floating point number. Is this allowed? The results are correct, but they contain .0 at the end. – Yytsi – 2016-08-29T06:41:21.163

Does the program have to handle the empty input string ? – Ton Hospel – 2016-08-29T07:11:12.430

4Please add more test cases. – Martin Ender – 2016-08-29T07:38:50.117

2Curse that nasty round-down requirement! I had a nice 41-byte GNU sed + dc answer: s/[+-]/1&/g;s/[*/]/2&/g;s/.*/dc -e 0d&p/e, but it rounds towards zero when you divide a negative :-( – Toby Speight – 2016-08-29T13:23:11.863

1May we substitute the symbols with +-×÷ or 'PMTD'? – Adám – 2016-08-30T06:54:28.963

@TobySpeight you can divide this way in dc to have the desired rounding: [1-]S@d0>@2/, because the default output precision is 0 (see my answer)

– seshoumara – 2016-08-30T08:09:24.723

@TonHospel It outputs 0 because the accumulator starts at 0 and changes only with operations. – dkudriavtsev – 2016-09-03T21:43:45.490

@MartinEnder xnor did that for me – dkudriavtsev – 2016-09-03T21:44:09.183

@Adám no, they must be exactly as specified. Sorry. – dkudriavtsev – 2016-09-03T21:44:34.840

Answers

28

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.

xnor

Posted 2016-08-28T22:51:52.017

Reputation: 115 687

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 – 2016-08-29T10:06:09.587

You can post it, I don't know CJam. – xnor – 2016-08-29T10:07:18.997

Really clever! Ported to ES6 this would easily outperform my answer – edc65 – 2016-08-29T10:19:48.277

Brilliant use of python. Learned something new from this. – Jacobr365 – 2016-08-29T13:25:43.160

12

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.

Dennis

Posted 2016-08-28T22:51:52.017

Reputation: 196 637

10This looks like the jelly answer with the most newlines – Conor O'Brien – 2016-08-28T23:28:31.747

12

Haskell, 51 bytes

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

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

nimi

Posted 2016-08-28T22:51:52.017

Reputation: 34 639

10

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.

xsot

Posted 2016-08-28T22:51:52.017

Reputation: 5 069

doesn't seem to work... – Destructible Lemon – 2016-08-29T01:18:33.263

55,3 and 65,4 are the two shortest for double mod of hash in python 2 – Jonathan Allan – 2016-08-29T01:18:42.607

@DestructibleWatermelon does for me: ideone

– Jonathan Allan – 2016-08-29T01:24:56.890

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 – 2016-08-29T01:29:28.863

1it works on ideone, but not on my computers python. Probably version dependent, in which case version should be noted EDIT: ninja'd :/ – Destructible Lemon – 2016-08-29T01:30:15.353

@sp3000 I see. I didn't know hash isn't backwards compatible especially considering such a small difference in versions. – xsot – 2016-08-29T01:34:42.963

FWIW, 2-ord(c)%11%3 is only a byte longer and works everywhere. – Lynn – 2016-08-29T02:39:32.960

@lynn Thanks, you prompted me to look for an even shorter formula that doesn't rely on hash. – xsot – 2016-08-29T02:51:46.520

10

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:
-/
++**--/
*///*-*+-+

betseg

Posted 2016-08-28T22:51:52.017

Reputation: 8 493

is loadLine golfier? – Rohan Jhunjhunwala – 2016-08-29T01:59:26.693

The OP clarified; -/ should return -1, not 0. – Dennis – 2016-08-29T02:53:25.650

@Dennis fixed. Added a lot of bytes though :/ – betseg – 2016-08-29T11:10:14.067

9

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.

KoreanwGlasses

Posted 2016-08-28T22:51:52.017

Reputation: 888

1Thought reading this code was very very cool. So thanks for brightening up my day. – Jacobr365 – 2016-08-30T12:58:00.663

8

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

Brad Gilbert b2gills

Posted 2016-08-28T22:51:52.017

Reputation: 12 713

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

o79y

Posted 2016-08-28T22:51:52.017

Reputation: 509

6

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!

Adnan

Posted 2016-08-28T22:51:52.017

Reputation: 41 965

The OP clarified; -/ should return -1, not 0. – Dennis – 2016-08-29T03:04:21.830

The negative number division issue could be fixed with Î…+-*"><·"‡'/"2÷":.V for the same byte count. – Emigna – 2016-08-29T08:46:09.197

@Dennis Fixed the problem. – Adnan – 2016-08-29T09:59:51.927

@Emigna Thanks :) – Adnan – 2016-08-29T10:00:09.583

5

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!

Conor O'Brien

Posted 2016-08-28T22:51:52.017

Reputation: 36 228

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 – 2016-08-28T23:42:15.627

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 – 2016-08-28T23:46:56.443

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 – 2016-08-28T23:48:21.403

@Neil Ah, yes, I forgot about this – Conor O'Brien – 2016-08-28T23:51:23.310

@Neil fantastic! – Conor O'Brien – 2016-08-28T23:52:18.087

@DanTheMan Did you actually read the answer? n/2|0 performs integer division. – Conor O'Brien – 2016-08-29T01:58:42.647

@ConorO'Brien I was confusing | and ||. Sorry! Try to not be so condescending next time though. – DanTheMan – 2016-08-29T02:05:54.057

1You 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 – 2016-08-29T02:59:52.103

@Dennis Excellent, that saves another byte by using >>1 instead of /2|0. – Neil – 2016-08-29T10:16:04.140

@Dennis I will fix the next opportunity I can. – Conor O'Brien – 2016-08-29T11:09:16.987

@LeakyNun done. – Conor O'Brien – 2016-08-30T23:14:59.220

5

Ruby, 48 44 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

Jordan

Posted 2016-08-28T22:51:52.017

Reputation: 5 001

5

PHP 76 Bytes

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

Jörg Hülsermann

Posted 2016-08-28T22:51:52.017

Reputation: 13 026

4

Mathematica, 83 73 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.

LegionMammal978

Posted 2016-08-28T22:51:52.017

Reputation: 15 731

4

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

Jonathan Allan

Posted 2016-08-28T22:51:52.017

Reputation: 67 804

How about 2-ord(c)%11%3? – Lynn – 2016-08-29T02:36:15.253

@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 – 2016-08-29T02:41:19.893

2Go ahead :) ---- – Lynn – 2016-08-29T02:42:09.747

4

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).

Leaky Nun

Posted 2016-08-28T22:51:52.017

Reputation: 45 011

4

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

Arnauld

Posted 2016-08-28T22:51:52.017

Reputation: 111 334

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

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 -.

Scepheo

Posted 2016-08-28T22:51:52.017

Reputation: 466

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 – 2016-08-30T14:38:47.593

@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 – 2016-08-30T15:12:53.227

3

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>

edc65

Posted 2016-08-28T22:51:52.017

Reputation: 31 086

3

GNU sed, 65 59 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/.

seshoumara

Posted 2016-08-28T22:51:52.017

Reputation: 2 878

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 – 2016-08-30T08:31:45.607

@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 – 2016-08-30T09:20:13.287

1dc 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 – 2016-08-30T14:15:02.523

@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 – 2016-08-30T15:55:17.300

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 – 2016-08-30T16:17:54.000

3

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))
    {
        $argv = array('', '++*+');
    }
}

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

Or try on: http://sandbox.onlinephpfunctions.com/code/7d2adc2a500268c011222d8d953d9b837f2312aa

Differences:

  • Instead of echo$s, I'm using sprintf($s). Both perform the same action on numbers. Since this is just for testing, it is fine.
  • In case there's no passed argument, it will run as if you passed ++*+ as the first argument, which should show 5.

Ismael Miguel

Posted 2016-08-28T22:51:52.017

Reputation: 6 797

Yay! The e modifier is back! :D – Titus – 2016-09-28T08:28:52.900

@Titus I don't get it. Can you elaborate a little? – Ismael Miguel – 2016-09-28T08:58:05.940

PHP before version 7 had a pattern modifier e, which was replaced by preg_replace_callback and could be abused to ... but this isn´t quite that.

– Titus – 2016-09-28T13:06:24.550

@Titus That patern modifier was used to tell that the output would be actual PHP code, and to try to keep the syntax correct. This here, doesn't use it, but replace every single character with a piece of code to execute, regardless of it's syntax. Bad inputs will cause severe security issues. – Ismael Miguel – 2016-09-28T14:20:04.403

I know. But it resembles. – Titus – 2016-09-28T15:19:23.467

@Titus To be honest, it does resemble. This answer would (probably) benefict from it. But, to be even more honest, I'm more proud of the polyglot I wrote to test the basic implementation in PHP and Javascript (in a StackSnippet) – Ismael Miguel – 2016-09-28T15:32:25.240

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

Uses java 8 streams.

primodemus

Posted 2016-08-28T22:51:52.017

Reputation: 131

1Nice 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 – 2016-08-30T21:15:08.473

You're absolutely correct, thanks @DJMcMayhem – primodemus – 2016-08-30T21:21:24.697

1Awesome, 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 – 2016-08-30T21:22:59.990

Correct again @DJMcMayhem , aparently wc counts the null-terminanting byte or something... – primodemus – 2016-08-30T21:35:34.657

1as 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 – 2016-08-31T13:51:51.493

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

Destructible Lemon

Posted 2016-08-28T22:51:52.017

Reputation: 5 908

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 – 2016-08-29T07:11:05.467

@TuukkaX doesn't work for z=0 (+- does 1) – Destructible Lemon – 2016-08-29T09:23:49.923

oh yes, my mistake. – Yytsi – 2016-08-29T10:21:17.837

1Add the title Python3 please. – Yytsi – 2016-08-29T13:48:11.767

2

Pyke, 24 22 bytes

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

Try it here!

Or 12 bytes (noncompetitive)

~:"ht}e".:0E

Try it here!

Add translate node - basically multiple find and replace.

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

Blue

Posted 2016-08-28T22:51:52.017

Reputation: 26 661

2

Batch, 61 bytes

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

Translation of @xnor's xcellent Python answer.

Neil

Posted 2016-08-28T22:51:52.017

Reputation: 95 035

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.

YetiCGN

Posted 2016-08-28T22:51:52.017

Reputation: 941

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.

Vlo

Posted 2016-08-28T22:51:52.017

Reputation: 806

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. https://tio.run/##XcvLCsMgEAXQrwnO6Gge29B/KKW7EDBYU4TmgZqQv7dmU2gWcxfn3vEp6UIU@jZus4lumeHAQ9StLuQF5Yn8grzJWP6juns3ueh2Cyx3DOGgBtuHfW3Gwm84klIKRziTvN1hetsI6xCirfIjoxB9WD8uQjDDDMQYntd1dd9T7hGRKnpiEoJzKcv0BQ

– Giuseppe – 2017-06-07T14:39:29.543

1

GolfScript - 45 bytes

{1+}:"+";{1-}:"-";{2/}:"/";{2*}:"*";0\1/{`~}/

Explanation

{1+}:"+";  # Creates aliases for operators
{1-}:"-";
{2/}:"/";
{2*}:"*";
0\1/       # Pushes 0 and splits the string in bytes
{`~}/      # Executes each character

FedeWar

Posted 2016-08-28T22:51:52.017

Reputation: 271

1

Python3, 98 85 74 bytes

C=lambda s,n:s and C(s[1:],{3:n+1,5:n-1,2:n*2,7:n/2}[ord(s[0])%10])or n//1

A recursive solution that loops over the string and takes the (modulo 10) from the ASCII value of the iterated character and treats the carried number accordingly. The dictionary keys are the last digits of the possible ASCII values that may occur (+, -, *, /) and the values are the corresponding results for the symbol.We pass the input string s forward by taking everything onward from the next character with s[1:] (thanks to @Destructible Watermelon!).

Could be shortened even more, by picking the actions from a list and moduloing to keep the index in range, but that feels like plagiarism at this point, so unless I find my own method for that, it won't happen.

Called like: C("+-+**+/",0) ==> 2.0

(Ps. Is it allowed to return -1.0 from input -/?)

Yytsi

Posted 2016-08-28T22:51:52.017

Reputation: 3 582

1

PHP, 79 bytes

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

Winnie The Pooh

Posted 2016-08-28T22:51:52.017

Reputation: 111

2Include the bytecount in your header, remove uneccesary spaces and use 1-letter variable names. – TuxCrafting – 2016-08-29T09:42:51.347

Is this even golfed?! :-D – YetiCGN – 2016-08-29T12:50:28.380

@TùxCräftîñg I did it. – Winnie The Pooh – 2016-08-29T17:11:41.830

You divide and multiply by 1; you need to divide and multiply by 2 – TuxCrafting – 2016-08-29T17:58:47.900

@TùxCräftîñg I did it. – Winnie The Pooh – 2016-08-29T17:59:15.770

Please update your bytecount... The bytecount here is of 81 bytes – TuxCrafting – 2016-08-29T18:05:54.660

I typed "81", What did you see – Winnie The Pooh – 2016-08-29T18:06:48.270

If I POST "-+", I get 0, in $i, and $i is never outputted. – NoOneIsHere – 2016-08-29T18:15:07.473

Shouldn´t there be a loop of some kind? Save one byte with $_GET instead of $_POST. – Titus – 2016-09-28T08:27:32.967

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

Stefano Sanfilippo

Posted 2016-08-28T22:51:52.017

Reputation: 1 059

1

PHP, 146 138, 133, 131 bytes

$a=$_POST['s'];$i=0;while($a){$c=substr($a,0,1);$i=$c=='+'?$i+=1:($c=='-'?$i-1:($c=='*'?$i*2:round($i/2)));$a=substr($a,1);}echo$i;
  1. Takes argument from $_POST['s'].
  2. Uses ternary operator as "if's".
  3. Takes one character at a time, parse that char in operation, then continue reading next char
  4. EDIT 1: Shortened "while(strlen($a))" to "while($a)"
  5. EDIT 2: Removed some useless paranthesis
  6. EDIT 3. Removed extra space after last "echo"

Florin Chis

Posted 2016-08-28T22:51:52.017

Reputation: 59

I think with even PHP 5.5 having reached EOL it's safe to say that nobody SHOULD use PHP 4 anymore, so the "5+" is not necessary, imho. – YetiCGN – 2016-08-29T13:28:36.490

That is ok. For some scripts, it is important to show PHP version, maybe here it's not the case. Thanks, however. – Florin Chis – 2016-08-29T13:32:31.430

Yes, but if they start including the leaderboard snippet then your entry will be the top entry for the language "PHP 5+" while another one's entry will be leading "PHP 5.6" and maybe somebody else with worse score posts for "PHP 5.6.13 and up" ... You see my point? :-)

– YetiCGN – 2016-08-29T13:34:47.623

That is correct. Thanks, again – Florin Chis – 2016-08-29T13:36:05.013

You can change $_POST['s'] to $_GET[s], which is bad practice but saves you 2 bytes.You might also try to remove the bracketrs of the while (-2) if you add a newline before the echo (+1) Not 100% sure about that. – Martijn – 2016-08-29T20:02:39.853

I had tried with $_GET, but because of "/" chars in string there is a problem with resulted link. Regarding paranthesis for while, that is ok. – Florin Chis – 2016-08-30T07:38:59.430

Tried it. It is not ok while without brackets. – Florin Chis – 2016-08-30T07:48:22.600

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

Paul Schmitz

Posted 2016-08-28T22:51:52.017

Reputation: 1 089

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 

TheBikingViking

Posted 2016-08-28T22:51:52.017

Reputation: 3 674

1Converting Python to Pyth is mostly a bad idea. u@[yGhG0tG0/G2)CHQ0 19 bytes – Jakube – 2016-08-29T15:34:48.073

@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 – 2016-08-29T17:37:15.600

1

Ruby, 37 bytes

#!ruby -n
gsub(/./){eval"$.=$./2*2#$&2"}
p$./2

The shebang counts as 1 byte. This program uses xnor's creative approach. We avoid the need to initialise an accumulator variable by using $.. As it has a value of 1 after the input is read, we have to clear the LSB before applying each operator. This also requires changing &-2 to /2*2 for the correct precedence.

xsot

Posted 2016-08-28T22:51:52.017

Reputation: 5 069

1

Java 7, 73 bytes

int c(char[]i){int r=0;for(int c:i)r=c<43?r*2:c<46?r+44-c:r>>1;return r;}

Shamelessly stolen from @Scepheo's amazing C# answer and implemented in Java 7.

Ungolfed & test cases:

Try it here.

class M{
  static int c(char[] i){
    int r = 0;
    for(int c : i) {
      r = c < 43
           ? r * 2
           : c < 46
              ? r+44 - c
              : r >> 1;
    }
    return r;
  }

  public static void main(String[] a){
    System.out.println(c("*///*-*+-+".toCharArray()));
    System.out.println(c("/*+/*+++/*///*/+-+//*+-+-/----*-*-+++*+**+/*--///+*-/+//*//-+++--++/-**--/+--/*-/+*//*+-*-*/*+*+/+*-".toCharArray()));
    System.out.println(c("+++-+--/-*/---++/-+*-//+/++-*--+*+/*/*/++--++-+//++--*/***-*+++--+-*//-*/+*/+-*++**+--*/*//-*--**-/-*+**-/*-**/*+*-*/--+/+/+//-+*/---///+**////-*//+-+-/+--/**///*+//+++/+*++**++//**+**+-*/+/*/*++-/+**+--+*++++/-*-/*+--/++*/-++/-**++++/-/+/--*/-/+---**//*///-//*+-*----+//--/-/+*/-+++-+*-*+*+-/-//*-//+/*-+//+/+/*-/-/+//+**/-****/-**-//+/+-+/*-+*++*/-/++*/-//*--+*--/-+-+/+/**/-***+/-/++-++*+*-+*+*-+-//+/-++*+/*//*-+/+*/-+/-/*/-/-+*+**/*//*+/+---+*+++*+/+-**/-+-/+*---/-*+/-++*//*/-+-*+--**/-////*/--/*--//-**/*++*+/*+/-+/--**/*-+*+/+-*+*+--*///+-++/+//+*/-+/**--//*/+++/*+*////+-*-//--*+/*/-+**/*//+*+-//+--+*-+/-**-*/+//*+---*+//*/+**/*--/--+/*-*+*++--*+//+*+-++--+-*-*-+--**+/+*-/+*+-/---+-*+-+-/++/+*///*/*-+-*//-+-++/++/*/-++/**--+-////-//+/*//+**/*+-+/+/+///*+*///*-/+/*/-//-*-**//-/-+--+/-*--+-++**++//*--/*++--*-/-///-+/+//--+*//-**-/*-*/+*/-*-*//--++*//-*/++//+/-++-+-*/*-+++**-/-*++++**+-+++-+-***-+//+-/**-+/*+****-*+++*/-*-/***/-/*+/*****++*+/-/-**-+-*-*-++**/*+-/*-+*++-/+/-++*-/*-****-*".toCharArray()));
  }
}

Output:

-1
-17
18773342

Kevin Cruijssen

Posted 2016-08-28T22:51:52.017

Reputation: 67 575

1

ARM Machine Code, 30 bytes

Hex Dump (little endian):

2000 f811 2b01 b14a 2a2a bf08 0040 d0f8 2a2e bf3a 3a2c 1a80 1040 e7f2 4770

This is a function that takes in a string, and returns the accumulated result. In C, the function would be declared int sioc(int dummy, char* string) where the dummy argument is ignored. Tested on the Raspberry Pi 3. No libraries or system calls are used.

Ungolfed assembly:

.syntax unified
.text
.global sioc
.thumb_func
sioc:
    @Input: r0 - dummy argument
    @r1 - string of operations
    @Output: r0 - result of those operations
    movs r0,#0 @Initialize accumulator to 0
    loop:
        ldrb r2,[r1],#1 @r2=*r1++
        cbz r2,end @If (r2==0), goto end
    mul:
        cmp r2,#42
        it eq @if r2==42
        lsleq r0,r0,#1 @r0<<=1
        beq loop @continue
    addsub: @else
        cmp r2,#46
        itte lo @If r2<46, then r2 is either + or -
        sublo r2,r2,#44
        sublo r0,r0,r2 @Add 1 if r2 is +, subtract 1 if r0 is -
        asrhs r0,r0,#1 @else arithmatically shift right by 1
        b loop @while (true)
    end:
        bx lr

Testing script (also assembly):

.syntax unified
.text
.global main
.thumb_func
main:
    ldr r1,[r1,#4] @r0=argv[1]
    bl sioc
    mov r1,r0
    adr r0,msg
    bl printf
    movs r7,#1
    swi #0
.balign 4
msg:
    .asciz "%d\n"

Ian Chew

Posted 2016-08-28T22:51:52.017

Reputation: 171

1

Java 8, 56 bytes

s->s.chars().reduce(0,(r,c)->c<43?r*2:c<46?r+44-c:r>>1);

Shaun Wild

Posted 2016-08-28T22:51:52.017

Reputation: 2 329

1

Haskell - 70 bytes

f x=foldl1(flip(.))[[(*2),succ,id,pred,id,(`div`2)]!!(ord n-42)|n<-x]0

64 if I may take the input in RPN:

f x=foldl1(.)[[(*2),succ,id,pred,id,(`div`2)]!!(ord n-42)|n<-x]0


In addition to + - * / my implementation also support , and ., both of which does nothing. It crashes for any other input.

BlackCap

Posted 2016-08-28T22:51:52.017

Reputation: 3 576

0

TSQL, 115 bytes

After some golfing I was finally able to replace -IIF(@<0,@,@+1)/2 with (@+ABS(@%2))/-2 saving 2 bytes.

Golfed:

DECLARE @i varchar(max)='*///*-*+-+'
,@ INT=0WHILE @i>''SELECT @+=CHOOSE(CHARINDEX(LEFT(@i,1),'+-*/'),1,-1,@,(@+ABS(@%2))/-2),@i=STUFF(@i,1,1,'')PRINT @

Ungolfed:

DECLARE @i varchar(max)='*///*-*+-+'

,@ INT=0
WHILE @i>''
  SELECT @+=CHOOSE(CHARINDEX(LEFT(@i,1),'+-*/'),1,-1,@,(@+ABS(@%2))/-2),
  @i=STUFF(@i,1,1,'')
PRINT @

Fiddle

t-clausen.dk

Posted 2016-08-28T22:51:52.017

Reputation: 2 874

0

Racket 116 bytes

(λ(s)(let((l(string->list s))(a 0))(for((i l))(set! a(match i[#\+(+ a 1)][#\-(- a 1)][#\*(* a 2)][#\/(/ a 2)])))a))

Ungolfed version:

(define f
  (lambda(s)
    (let ((l (string->list s))
          (a 0))
      (for ((i l))
        (set! a (match i
                  [#\+ (+ a 1)]
                  [#\- (- a 1)]
                  [#\* (* a 2)]
                  [#\/ (/ a 2)]
                )))
      a)))

Testing:

(f "++**--/")

3

rnso

Posted 2016-08-28T22:51:52.017

Reputation: 1 635