Weapons of Math Instruction

44

6

Last time when I tried to come up with something easy that wasn't a duplicate, it ended up being way too hard.. So hopefully this time it's indeed something newcomers can try as well.

Input:

An array/list with integers/decimals. (Or a string representing an array with integers/decimals.)

Output:

Loop through the numbers and apply the following five mathematical operands in this order:

  • Addition (+);
  • Subtraction ();
  • Multiplication (* or × or ·);
  • Real / Calculator Division (/ or ÷);
  • Exponentiation (^ or **).

(NOTE: The symbols between parenthesis are just added as clarification. If your programming language uses a completely different symbol for the mathematical operation than the examples, then that is of course completely acceptable.)

Keep continuing until you've reached the end of the list, and then give the result of the sum.

Challenge rules:

  • Exponentiation by 0 (n ^ 0) should result in 1 (this also applies to 0 ^ 0 = 1).
  • There are no test cases for division by 0 (n / 0), so you don't have to worry about that edge-case.
  • If the array contains just a single number, we return that as the result.

General rules:

  • This is , so shortest answer in bytes wins.
    Don't let code-golf languages discourage you from posting answers with non-codegolfing languages. Try to come up with an as short as possible answer for 'any' programming language.
  • Standard rules apply for your answer, so you are allowed to use STDIN/STDOUT, functions/method with the proper parameters, full programs. Your call.
  • Default Loopholes are forbidden.
  • If possible, please add a link with a test for your code.

Test cases:

[1,2,3,4,5] -> 0
-> 1 + 2 = 3
  -> 3 - 3 = 0
    -> 0 * 4 = 0
      -> 0 / 5 = 0 

[5,12,23,2,4,4,2,6,7] -> 539
-> 5 + 12 = 17
  -> 17 - 23 = -6
    -> -6 * 2 = -12
      -> -12 / 4 = -3
        -> -3 ^ 4 = 81
          -> 81 + 2 = 83
            -> 83 - 6 = 77
              -> 77 * 7 -> 539

[-8,50,3,3,-123,4,17,99,13] -> -1055.356...
-> -8 + 50 = 42
  -> 42 - 3 = 39
    -> 39 * 3 = 117
      -> 117 / -123 = -0.9512...
        -> -0.9512... ^ 4 = 0.818...
          -> 0.818... + 17 = 17.818...
            -> 17.818... - 99 -> -81.181...
              -> -81.181... * 13 = -1055.356...

[2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2] -> 256
-> 2 + 2 = 4
  -> 4 - 2 = 2
    -> 2 * 2 = 4
      -> 4 / 2 = 2
        -> 2 ^ 2 = 4
          -> 4 + 2 = 6
            -> 6 - 2 = 4
              -> 4 * 2 = 8
                -> 8 / 2 = 4
                  -> 4 ^ 2 = 16
                    -> 16 + 2 = 18
                      -> 18 - 2 = 16
                        -> 16 * 2 = 32
                          -> 32 / 2 = 16
                            -> 16 ^ 2 = 256

[1,0,1,0,1,0] -> 1
-> 1 + 0 = 1
  -> 1 - 1 = 0
    -> 0 * 0 = 0
      -> 0 / 1 = 0
        -> 0 ^ 0 = 1

[-9,-8,-1] -> -16
  -> -9 + -8 = -17
    -> -17 - -1 = -16

[0,-3] -> -3
  -> 0 + -3 = -3

[-99] -> -99

Kevin Cruijssen

Posted 2016-06-13T06:57:47.497

Reputation: 67 575

Not integer division? – Leaky Nun – 2016-06-13T07:01:12.253

@LeakyNun No. Perhaps I should change the input to a list with decimals instead of integers due to division (and test case 3)? – Kevin Cruijssen – 2016-06-13T07:02:46.400

Was this in the sandbox? – Bálint – 2016-06-13T07:12:44.223

@Bálint Yes, since Friday morning (CET) (it's deleted now, but those without enough rep can still view it). And I received some good feedback from TimmyD and flawr that has improved the challenge a lot. (PS: Since I get this question every time I post a challenge, should I add a link to the deleted Sandbox & datetime next time?)

– Kevin Cruijssen – 2016-06-13T07:13:58.493

No need, just answer this question every time you post a challenge. :) – Leaky Nun – 2016-06-13T07:57:10.087

For clarification, does 0^0 = 1? From the description, it seems so, but you might want to make it explicit just in case. – Mego – 2016-06-13T08:03:07.097

@Mego Yes, 0^0 = 1. A.f.a.i.k., n ^ 0 is always 1 regardless of n in math (or are there different mathematical rules here, since you aren't the first to ask?). It also has the answer 1 in the 5th test case for 0 ^ 0. But I'll add it at the top as well to clarify it explicitly. – Kevin Cruijssen – 2016-06-13T08:12:01.333

9

In math, there are two conflicting "rules": n ^ 0 = 1, but 0 ^ n = 0. The conflict is resolved by setting n != 0 for both of the rules, but then it leaves 0 ^ 0 undefined. However, there are a lot of things that fall into place nicely in mathematics if 0 ^ 0 is defined to be 1. See Wikipedia for some details.

– Mego – 2016-06-13T08:14:47.363

If I return infinity instead of a divide by zero error, is thst okay? – Bálint – 2016-06-13T09:11:45.510

1@Bálint The rules state that there will never be a valid input with a division by zero. You don't have to worry about that edge case. – Mego – 2016-06-13T09:12:23.123

@Mego He said there's no testcase for it, but should normally ouput an error – Bálint – 2016-06-13T09:13:32.193

@Bálint The wording could be a bit clearer, but that is the interpretation I and the other posters have been going off of, since that was the suggestion in the Sandbox that led to the rule being added. – Mego – 2016-06-13T09:14:21.470

@Bálint @Mego is indeed right, you don't have to worry about divide by 0 cases / errors. I've chanegd the wording to clarify it a bit. – Kevin Cruijssen – 2016-06-13T10:49:33.693

* is APL's symbol for exponentiation. Is this acceptable if one of the other two multiplication symbols is used? – Adám – 2016-06-14T07:28:18.970

@Adám Yes, the symbols were just added as clarification of the mathematical operations in the sense of: pictures (or symbols) say more than thousand words. It's completely fine if your language uses even none of the symbols, as long as they imply and are executed as their counterpart mathematical operation. – Kevin Cruijssen – 2016-06-14T09:11:26.783

Answers

7

Jelly, 13 bytes

“+_×÷*”ṁṖ⁸żFV

Try it online! or verify all test cases.

How it works

“+_×÷*”ṁṖ⁸żFV  Main link. Argument: A (list of integers)

“+_×÷*”        Yield the list of operations as a string.
        Ṗ      Yield A popped, i.e., with its last element removed.
       ṁ       Mold; reshape the string as popped A.
               This repeats the characters of the string until it contains
               length(A)-1 characters.
         ⁸ż    Zipwith; pairs the integers of A with the corresponding characters.
           F   Flatten the result.
            V  Eval the resulting Jelly code.
               Jelly always evaluates left-to-right (with blatant disregard towards
               the order of operations), so this returns the desired result.

Dennis

Posted 2016-06-13T06:57:47.497

Reputation: 196 637

Nice, that's 8 lower byte-count than Pyke, which was currently in the lead.

– Kevin Cruijssen – 2016-06-13T16:33:02.697

3Nobody outgolfs Dennis. Never. – Blue – 2016-06-13T18:24:17.853

1Just a question: does it really count as 13 bytes with all those non-ascii characters? – Xavier Dury – 2016-06-17T07:23:46.260

3@XavierDury Yes. The bytes link in the header leads to Jelly's very own code page, which encodes the 256 characters Jelly understands as a single byte each. – Dennis – 2016-06-17T07:25:58.340

@Dennis Thank you for the precision! – Xavier Dury – 2016-06-17T07:28:28.443

19

Javascript ES7 49 bytes

a=>a.reduce((c,d,e)=>[c**d,c+d,c-d,c*d,c/d][e%5])

Saved 9 bytes thanks to Dom Hastings, saved another 6 thanks to Leaky Nun

Uses the new exponentiation operator.

Bálint

Posted 2016-06-13T06:57:47.497

Reputation: 1 847

@LeakyNun won't that just produce Infinity, not an error? – Dom Hastings – 2016-06-13T09:10:19.007

Try using eval it might be shorter – Downgoat – 2016-06-13T16:02:22.530

@Upgoat It used eval first, then Leaky Nun showed me, that it is better, to do it like this – Bálint – 2016-06-13T18:09:18.797

@Bálint you, like, using so many, commas? – Rɪᴋᴇʀ – 2016-06-14T15:40:43.170

1@EᴀsᴛᴇʀʟʏIʀᴋ Non-native speaker. Bálint often does that. English grammar is silly at the best of times. – wizzwizz4 – 2016-06-14T16:32:59.520

@EᴀsᴛᴇʀʟʏIʀᴋ My language puts a comma pretty much everywhere, whether it be the end of a logical block or pretty much before every conjunction. I can't seem to drop this. – Bálint – 2016-06-14T18:02:53.257

11

Haskell, 76 65 64 62 bytes

Thanks to @Damien for removing another two bytes=)

f(u:v)=foldl(\x(f,y)->f x y)u(zip(v>>[(+),(-),(*),(/),(**)])v)

This uses the >> which here just appends the list [(+),...] to itself length v times. The rest still works still the same as the old versions.

Old versions:

These solutions make use of the infinite lists, as cycle[...] just repeats the given list infinitely. Then it basically gets ziped with the list of numbers, and we just fold (reduce in other languages) the zipped list via a lambda, that applies the operators to the accumulator/current list element.

f(u:v)=foldl(\x(f,y)->f x y)u(zip(cycle[(+),(-),(*),(/),(**)])v)

f(u:v)=foldl(\x(y,f)->f x y)u(zip v(cycle[(+),(-),(*),(/),(**)]))

f l=foldl(\x(y,f)->f x y)(head l)(zip(drop 1l)(cycle[(+),(-),(*),(/),(**)]))

flawr

Posted 2016-06-13T06:57:47.497

Reputation: 40 560

you can replace cycle by: v>> – Damien – 2016-06-13T11:38:53.857

@Damien Thank you very much! – flawr – 2016-06-13T12:08:21.940

Hm, foldl(&)u$zipWith(&)v(flip<$>v>>[…])? – Bergi – 2016-06-14T00:22:54.087

@Bergi I honestly cannot read what this is doing anymore=) Anyway, we need an import for &, so that would be longer again, but thanks anyway! – flawr – 2016-06-14T09:24:51.527

@flawr: Actually my idea was quite the same as what Lazersmoke posted as an answer, I just hadn't read it. I got to it when trying to simplify that lamda of yours with something like uncurry. Didn't work out, but I noticed you should be able to save another byte by using $ instead of parenthesis.

– Bergi – 2016-06-14T13:02:38.220

8

Pyke, 22 21 bytes

lt5L%"+-*/^"L@\RJQ_XE

Try it here!

lt5L%                 -    map(len(input)-1, %5)
     "+-*/^"L@        -   map(^, "+-*/^"[<])
              \RJ     -  "R".join(^)
                    E - pyke_eval(^, V)
                 Q_X  -  splat(reversed(input))

Blue

Posted 2016-06-13T06:57:47.497

Reputation: 26 661

7

TSQL 116 115 88 bytes

Thanks to Ross Presser suggestion I was able to golf this down to 88 characters

-- In Try-it code, this must be DECLARE @y TABLE 
CREATE TABLE T(a real, i int identity)
INSERT T values(5),(12),(23),(2),(4),(4),(2),(6),(7)

DECLARE @ REAL SELECT @=CHOOSE(i%5+1,@/a,ISNULL(POWER(@,a),a),@+a,@-a,@*a)FROM T
PRINT @

Try it online

t-clausen.dk

Posted 2016-06-13T06:57:47.497

Reputation: 2 874

11 less byte: require the input table to be named T instead of @y. The PL/SQL solution had this, so why not TSQL. – Ross Presser – 2016-06-13T16:15:01.813

@RossPresser yes of course. how did I miss that. It is not possible in the test link, no permissions to create tables, and it will only run correctly the first time on a database. But what does that matter when a character can be golfed. Thanks for your hint, your improvement has been added – t-clausen.dk – 2016-06-13T19:51:03.087

Golfed out another 12 bytes: use CHOOSE instead of nested IIF, leaving one IIF for the i=1 case. With your permission, I will edit the answer. – Ross Presser – 2016-06-13T20:31:21.577

answer edited. Here's the try-it link -- I'm anonymous so it has no name after it: https://data.stackexchange.com/stackoverflow/query/edit/499612

– Ross Presser – 2016-06-13T20:34:45.640

1@RossPresser I didn't know CHOOSE. included your suggestion and golfed it a bit further – t-clausen.dk – 2016-06-14T08:01:47.913

Nice! 88 bytes is halfway respectable for a golf! :) – Ross Presser – 2016-06-14T14:19:51.180

I wonder if, as the number of rows in T increases without limit, the fact that the SELECT doesn't have an ORDER BY clause might bite us. If the optimizer picks a different order then the evaluation will be wrong. – Ross Presser – 2016-06-14T20:53:35.053

@RossPresser this is not the correct way of doing it. There is an upper limit, but it is pretty high and will not be affected as long as the number of rows is low. Here is an example how to use XML-PATH which is the correct method

– t-clausen.dk – 2016-06-14T21:19:01.907

I'm interested - why SEDE? :3 I thought it was specifically for Stack Exchange data queries... :P – user48538 – 2016-06-25T10:39:58.337

@user48538 you are right, seeding isn't necessary, I can just change the order of the processing – t-clausen.dk – 2019-06-13T13:01:48.867

7

Haskell, 61 Bytes

foldl(flip id)0.zipWith flip((+):cycle[(+),(-),(*),(/),(**)])

Creates a series of transformations in a list, as in [add 1, add 2, subtract 3, ...], starting with 2 additions because we start with 0 in the fold. Next, we do what I call the List Application Fold, or foldl (flip id), which applies a list of homomorphisms in series. This starts with zero, adds the initial value, then does all of the above computed transformations to get a final result.

Note that (flip id) is the same as (\x y->y x), just shorter.

Sample usage:

f = foldl(flip id)0.zipWith flip((+):cycle[(+),(-),(*),(/),(**)])
f [1,2,3,4,5] -- Is 0.0

Lazersmoke

Posted 2016-06-13T06:57:47.497

Reputation: 291

Instead of flip id, you could simply use &. Or flip($). Wow, I never realised ($) = id

– Bergi – 2016-06-14T00:30:45.207

1@Bergi: & is defined in Data.Function, so you need the import, too. Maybe some online interpreter imports it by default, but then you need to specify which one you use. – nimi – 2016-06-14T05:03:03.533

6

Pyth, 27 26 25 bytes

.v+>tlQ*lQ"^c*-+":jdQ\-\_

Test suite.

Pyth uses prefix notation: 1+2 is written as +1 2 (space needed to separate numbers).

Therefore, for the first testcase, the expression would be (((1+2)-3)*4)/5, which in prefix notation, would be written as /*-+ 1 2 3 4 5.

In Pyth, float division is c instead of /, so it becomes c*-+ 1 2 3 4 5.

Also, in Pyth, -100 is written as _100 instead.

Therefore, for the third test case, which is ((((((((-8+50)-3)*3)/-123)^4)+17)-99)*13), it becomes: *-+^c*-+ _8 50 3 3 _123 4 17 99 13.

.v+>tlQ*lQ"^c*-+":jdQ\-\_
                  jdQ       Join input by space.
                 :   \-\_   Replace "-" with "_".
   >tlQ*lQ"^c*-+"           Generate the string "...^c*-+" of suitable length.
  +                         Join the two strings above.
.v                          Evaluate as a Pyth expression.

History

Leaky Nun

Posted 2016-06-13T06:57:47.497

Reputation: 45 011

You're fast! Seems like I succeeded in making an easier challenge. Or you're just THAT good. ;) – Kevin Cruijssen – 2016-06-13T07:11:44.570

1

Because it's similar to this.

– Leaky Nun – 2016-06-13T07:20:26.700

224 bytes – Maltysen – 2016-06-13T18:06:06.280

6

Actually, 23 bytes

;l"+-*/ⁿ"*@R':j':+'?o+ƒ

Try it online!

Actually uses postfix notation for mathematics, and operators that only ever take two arguments (such as the operators for addition, subtraction, multiplication, division, and exponentiation) do nothing when there is only one element on the stack. Thus, turning the input into Actually code is as simple as reversing the input, formatting it as numerics, and appending the operations. Then, the resultant code can be executed, giving the desired output.

Explanation:

;l"+-*/ⁿ"*@R':j':+'?o+ƒ
;l"+-*/ⁿ"*               repeat the operations a number of times equal to the length of the input
                            (since extraneous operations will be NOPs, there's no harm in overshooting)
          @R             reverse the input
            ':j          join on ":" (make a string, inserting ":" between every pair of elements in the list)
               ':+       prepend a ":" (for the first numeric literal)
                  '?o    append a "?"
                           (this keeps the poor numeric parsing from trying to gobble up the first + as part of the numeric literal, since ? isn't interpreted as part of the literal, and is a NOP)
                     +   append the operations string
                      ƒ  cast as a function and call it

Example of translated code for input 1,2,3,4,5:

:5:4:3:2:1?+-*/ⁿ+-*/ⁿ+-*/ⁿ+-*/ⁿ+-*/ⁿ

Mego

Posted 2016-06-13T06:57:47.497

Reputation: 32 998

3Love the way the name of the language merges with the byte count – user6245072 – 2016-06-13T11:38:54.263

3s/Actually uses postfix notation/Actually actually uses postfix notation/ – Leaky Nun – 2016-06-13T12:54:04.573

6

Julia, 53 50 bytes

!x=(i=0;foldl((a,b)->(+,-,*,/,^)[i=i%5+1](a,b),x))

Try it online!

Dennis

Posted 2016-06-13T06:57:47.497

Reputation: 196 637

5

J, 40 bytes

^~`(%~)`*`(-~)`+/@(|.@,7#:~#&2)(5-5|4+#)

Finds the number of values needed to use a multiple of 5 operators, than pads with the identity values of those operators. In order, + is 0, - is 0, * is 1, % is 1, and ^ is 1, which can be a bit value 00111, or 7 in base 10. Then operates on that list while cycling through operators.

Usage

   f =: ^~`(%~)`*`(-~)`+/@(|.@,7#:~#&2)(5-5|4+#)
   f 1 2 3 4 5
0
   f 5 12 23 2 4 4 2 6 7
539
   f _8 50 3 3 _123 4 17 99 13
_1055.36
   f 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
256
   f 1 0 1 0 1 0
1
   f _9 _8 _1
_16
   f 0 _3
_3
   f _99
_99

Explanation

^~`(%~)`*`(-~)`+/@(|.@,7#:~#&2)(5-5|4+#) Input: A
                                      #  Get length of A
                                    4+   Add four to it
                                  5|     Take it mod 5
                                5-       Find 5 minus its value, call it x
                           #&2           Create x copies of 2
                       7#:~              Convert 7 to base 2 and take the last x digits
                      ,                  Append those x digits to the end of A
                   |.@                   Reverse it, call it A'
^~                                       Power, reversed operators
    %~                                   Division, reversed operators
       *                                 Multiplication
         -~                              Subtraction, reversed operators
            +                            Addition
             /@                          Insert the previous operations, separated by `,
                                         into A' in order and cycle until the end
                                         Then evaluate the equation from right-to-left
                                         and return

miles

Posted 2016-06-13T06:57:47.497

Reputation: 15 654

5

Python 2, 81 67 64 bytes

i=10
for n in input():exec'r%s=n'%'*+-*/*'[i::5];i=-~i%5
print r

Input is an array of floats. Test it on Ideone.

How it works

'*+-*/*'[i::5] selects every fifth character of the string, starting with the one at index i, so this yields ** if i = 0, + if i = 1, - if i = 2, * if i = 3 and / if i = 4. Since the string has length 6, the expression will yield an empty string if i > 5.

We initialize the variable i to 10. For each number n in the input array, we construct the string r<op>=n, which exec executes.

Initially, i = 10, so <op> is the empty string, and it initializes r with r+=n. After each step, we increment i modulo 5 with i=-~i%5, so the next step will retrieve the proper operator.

When all input numbers has been processed, and we print r, which holds the desired output.

Dennis

Posted 2016-06-13T06:57:47.497

Reputation: 196 637

5

Matlab - 95 91 85 bytes / Octave - 81 bytes

Input is in such form: a = ['1' '2' '3' '4' '5'];, I hope this is covered by "string representing an array with integers/decimals", else there are 2 num2str needed additionally.

Every intermediate result gets printed to console because that saves me some semicolons. a(1) is executed so its value is then saved to ans. Also of course using ans in code is bad practice.

b='+-*/^'
a(1)
for i=2:length(a)
  ['(',ans,')',b(mod(i-2,5)+1),a(i)]
end
eval(ans)

In Octave, '+-*/^'(mod(i+2,5)+1) also works, which saves another 4 bytes, thanks Adám and Luis Mendo:

a(1)
for i=2:length(a)
  strcat('(',ans,')','+-*/^'(mod(i-2,5)+1),a(i))
end
eval(ans)

Changelog:

  • Removed spaces where possible
  • added Octave solution
  • replaced strcat() with []

Lukas K.

Posted 2016-06-13T06:57:47.497

Reputation: 191

Hi, welcome to PPCG! The input is fine like that, since it's still easily distinguishable what the input is. Hmm, I never used Matlab, so maybe I'm saying idiotic things here, but can't b = '+-*/^' be golfed to b='+-*/^' and for i = 2:length(a) to for i=2:length(a) (removing the spaces)? Also, perhaps Tips for golfing in MATLAB might be interesting for you. :)

– Kevin Cruijssen – 2016-06-14T09:27:52.370

Is '+-*/^'(mod(i+2,5)+1) valid? – Adám – 2016-06-14T09:46:57.907

@Adám No, but it probably is in Octave – Luis Mendo – 2016-06-14T10:57:59.463

@Adám: it works in Octave, I added it. – Lukas K. – 2016-06-15T11:00:22.780

4

R, 87 78 70 bytes

i=0
Reduce(function(a,j)get(substr("+-*/^",i<<-i%%5+1,i))(a,j),scan())

Try it online!

JayCe

Posted 2016-06-13T06:57:47.497

Reputation: 2 655

at some point I really need to learn how to use do.call...I probably shouldn't consider myself an R programmer until I do! – Giuseppe – 2018-07-19T16:18:01.343

1

@Giuseppe Advanced R by Hadley Wickam is a great beach read :)

– JayCe – 2018-07-19T17:03:02.220

@Giuseppe thanks for pointing out do.call - made me realize I was looking for get. – JayCe – 2018-07-19T17:16:13.783

4

Mathematica, 67 66 65 bytes

Fold[{+##,#-#2,#2#,#/#2,If[#2==0,1,#^#2]}[[i++~Mod~5+1]]&,i=0;#]&

Simple Fold with a variable i holding the index.

LegionMammal978

Posted 2016-06-13T06:57:47.497

Reputation: 15 731

A byte can be saved by +## instead of #+#2 – LLlAMnYP – 2016-06-13T13:57:15.047

4

CJam, 18 bytes

q~{"+-*/#"W):W=~}*

Input is an array of floats. Try it online!

How it works

q~                  Read and evaluate all input.
  {             }*  Reduce:
   "+-*/#"            Push the string of operators.
          W           Push W (initially -1).
           ):W        Increment and save in W.
              =       Retrieve the character at that index.
               ~      Evaluate.

Dennis

Posted 2016-06-13T06:57:47.497

Reputation: 196 637

3

PHP, 135 130 bytes

Thanks @titus, -5 bytes, plus 0 case fix!

function f($z){return array_reduce($z,function($c,$x)use(&$i){eval('$c'.['/','**','+','-','*'][$i++?$i%5:5].'=$x;');return$c;});};

Try it online!

Less golfy:

function f( $t ) {
    return array_reduce( $t,
        function( $c, $x ) use( &$i ) {
            eval('$c'.['/','**','+','-','*'][$i++?$i%5:5].'=$x;');
            return $c;
        }
    );
};

Was really rooting for array_reduce() to work for this, but requires too many chars to beat the current lowest PHP score.

Posting it anyway in case anyone has any suggestions!

640KB

Posted 2016-06-13T06:57:47.497

Reputation: 7 149

1Nice approach; but I reckon it will fail whenever $c hits 0. Save two bytes with an anonymous function instead of w. eval('$c'.['/','**','+','-','*'][$i++?$i%5:5].'=$x');return$c; is six bytes shorter and should resolve the zero issue. – Titus – 2019-01-10T14:15:53.857

Thanks @Titus! You are absolutely right about the 0 case. I had to add back the ; after the =$x because eval wouldn't run without it. If I made it an anon function I'd have to have a variable assignment to it or run it within the test code, right? Wouldn't want to call the byte count into question. :D – 640KB – 2019-01-10T17:20:07.213

3

Java 8, 173 172 167 138 137 118 113 bytes

a->{double r=a[0],t;for(int i=1;i<a.length;r=new double[]{Math.pow(r,t),r+t,r-t,r*t,r/t}[i++%5])t=a[i];return r;}

Explanation:

Try it here.

a->{                     // Method with double-array parameter and double return-type
  double r=a[0],         //  Result-double, starting at the first item of the input
         t;              //  Temp double
  for(int i=1;           //  Index-integer, starting at the second item
      i<a.length;        //  Loop over the input-array
      r=new double[]{    //    After every iteration, change `r` to:
         Math.pow(r,t),  //      If `i%5` is 0: `r^t`
         r+t,            //      Else-if `i%5` is 1: `r+t`
         r-t,            //      Else-if `i%5` is 2: `r-t`
         r*t,            //      Else-if `i%5` is 3: `r*t`
         r/t}[i++%5])    //      Else-if `i%5` is 4: `r/t`
                         //      And increase `i` by 1 afterwards with `i++`
    t=a[i];              //   Change `t` to the next item in the array
  return r;}             //  Return result-double

Kevin Cruijssen

Posted 2016-06-13T06:57:47.497

Reputation: 67 575

2Because, ya know, java.1.5 times longer than the current longest answer....wich is in SQL – Bálint – 2016-06-13T08:11:24.143

@Bálint That's Java for ya. :) My shortest java answer so far is 65 bytes xD (and that wasn't really my answer, but Leaky Nun's..)

– Kevin Cruijssen – 2016-06-13T08:15:36.180

Well, float is shorter than double. – Leaky Nun – 2016-06-13T08:56:56.853

1You can change double r=a[0]; to double r=a[0],b; to save some bytes. – Leaky Nun – 2016-06-13T08:58:30.747

You can change i<a.length;i++ to i++<a.length; (you might have to change the order of the operations) – Leaky Nun – 2016-06-13T08:59:28.923

1@LeakyNun Originally I had float, but there isn't a Math.pow for floats, hence the double instead. Thanks for the ,b. And with i++<a.length I get an ArrayOutOfBoundsException at b=a[i]; (unless I do i++<a.length-1 instead, which is one byte longer instead of shorter). – Kevin Cruijssen – 2016-06-13T10:43:16.443

@KevinCruijssen This can be solved by int i=0;++i<a.length;. – Leaky Nun – 2016-06-13T12:52:29.637

1You can change == 4 to > 3 and == 0 to < 1. I'm not sure but I think you could save a bit by creating a variable for i % 5. – Frozn – 2016-06-13T14:11:45.830

1I figured you can change the whole thing to a concatenation of ternaries. In all comparisons you can then use the <x trick, shrinking the whole function to 137 characters. – Frozn – 2016-06-13T14:28:50.367

@Frozn Thanks, that saved a lot of bytes! Hmm, I get down to 144 bytes instead of 137. Did I make a mistake? – Kevin Cruijssen – 2016-06-13T14:49:11.823

1The last comparison x < 5 isn't necessary, as the value can only be between 0 and 4. The other ternaries ensure that there is only the possibility of x == 4. So it should look like this: [...] x < 4 ? r * s : r / s;. I also used @LeakyNun 's tip, which saves another character. – Frozn – 2016-06-13T14:57:04.567

3

Haskell - 74

f(x:xs)=foldl(\x(o,y)->o x y)x(zip(cycle[(+),(-),(*),(/),flip(^).floor])xs)

Test cases:

λ> f[1,2,3,4,5] -> 0.0
λ> f[5,12,23,2,4,4,2,6,7] -> 539.0
λ> f[-8,50,3,3,-123,4,17,99,13] -> -1055.356943846277
λ> f [2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2] -> 256.0

It could probably be shorter; Haskell's support for infinite lists and higher order functions make the direct solution quite pleasant, though. A version of ^ :: Double -> Double -> Double would be nicer for golfing, but I couldn't find one. Thankfully, I didn't need a full lambda, so pointless style shaved off a few bytes.

C. Quilley

Posted 2016-06-13T06:57:47.497

Reputation: 546

2You can prepend a single (+) to the list of operators and start the foldl with 0 to go completely pointfree and save the function name and parameters: foldl(\x(o,y)->o x y)0.zip((+):cycle[(+),(-),(*),(/),(**)]). – nimi – 2016-06-13T14:52:59.807

3

Oracle PL/SQL, 275 254 Bytes

declare r number;begin for x in (select n,mod(rownum,5)r from t) loop if r is null then r:=x.n;elsif x.r=2then r:=r+x.n;elsif x.r=3then r:=r-x.n;elsif x.r=4then r:=r*x.n;elsif x.r=0then r:=r/x.n;else r:=r**x.n;end if;end loop;DBMS_OUTPUT.PUT_LINE(r);end;

The data must be inserted in a table called T with a column N of type NUMBER

Usage:

drop table t;
create table t (n number);
insert into t values (-8);
insert into t values (50);
insert into t values (3);
insert into t values (3);
insert into t values (-123);
insert into t values (4);
insert into t values (17);
insert into t values (99);
insert into t values (13);

declare r number;begin for x in (select n,mod(rownum,5)r from t) loop if r is null then r:=x.n;elsif x.r=2then r:=r+x.n;elsif x.r=3then r:=r-x.n;elsif x.r=4then r:=r*x.n;elsif x.r=0then r:=r/x.n;else r:=r**x.n;end if;end loop;DBMS_OUTPUT.PUT_LINE(r);end;

Output:

-1055,356943846277162152071601242992595623

275 Bytes version:

declare r number;cursor c is select n,mod(rownum,5) r from t;begin for x in c loop if r is null then r:=x.n;else case x.r when 2 then r:=r+x.n;when 3 then r:=r-x.n;when 4 then r:=r*x.n;when 0 then r:=r/x.n;else r:=r**x.n; end case;end if;end loop;DBMS_OUTPUT.PUT_LINE(r);end;

Giacomo Garabello

Posted 2016-06-13T06:57:47.497

Reputation: 1 419

3

PowerShell v2+, 124 bytes

param($n)$o=$n[0];if($y=$n.count-1){1..$y|%{$o=if(($x=$i++%5)-4){"$o"+'+-*/'[$x]+$n[$_]|iex}else{[math]::pow($o,$n[$_])}}}$o

Long because PowerShell doesn't have a ^ or ** operator, so we have to account for a separate case and use a .NET call.

Takes input $n as an array, sets our output $o to be the first digit. We then check the .count of the array, and so long as it's greater than one we enter the if. Otherwise, we skip the if.

Inside the if we loop through the array 1..$y|%{...} and each iteration we re-set $o to a new value, the result of another if/else statement. So long as our counter $i++ isn't modulo-5 equal to 4 (i.e., we're not at the ^ operator), we simply take $o and concatenate it with the appropriate symbol '+-*/'[$x] and the next number in the input array $n[$_]. We pipe that to iex (alias for Invoke-Expression and similar to eval), and that gets re-saved to $o. If we're on the ^ operator, we're in the else, so we execute a [math]::Pow() call, and that result gets re-saved back into $o.

In either case, we simply output $o to the pipeline and exit, with output implicit.

AdmBorkBork

Posted 2016-06-13T06:57:47.497

Reputation: 41 581

3

Rust, 123, 117 bytes

Original answer:

fn a(v:&[f32])->f32{v.iter().skip(1).enumerate().fold(v[0],|s,(i,&x)|match i%5{0=>s+x,1=>s-x,2=>s*x,3=>s/x,_=>s.powf(x)})}

stupid long method names ^^ ahh much better

fn f(v:&[f32])->f32{v[1..].iter().zip(0..).fold(v[0],|s,(&x,i)|match i%5{0=>s+x,1=>s-x,2=>s*x,3=>s/x,_=>s.powf(x)})}

ungolfed

fn f(values : &[f32]) -> f32 {
    values[1..].iter().zip(0..)
    .fold(values[0], |state,(&x,i)|
        match i%5 {
            0=>state+x,
            1=>state-x,
            2=>state*x,
            3=>state/x,
            _=>state.powf(x)
        }
    )
}

raggy

Posted 2016-06-13T06:57:47.497

Reputation: 491

3

Python 3, 88 93 bytes

f=lambda x:eval('('*(len(x)-1)+'){}'.join(map(str,x)).format(*['+','-','*','/','**']*len(x)))

It started off being much shorter but then operator precedence defeated me and I had to include lots of parenthesis...

MSeifert

Posted 2016-06-13T06:57:47.497

Reputation: 131

3

Perl 6,  70 68 65  62 bytes

{$/=[(|(&[+],&[-],&[*],&[/],&[**])xx*)];.reduce: {$/.shift.($^a,$^b)}}
{(@_ Z |(&[+],&[-],&[*],&[/],&[**])xx*).flat.reduce: {&^b($^a,$^c)}}
{(@_ Z |(*+*,*-*,&[*],*/*,&[**])xx*).flat.reduce: {&^b($^a,$^c)}}
{reduce {&^b($^a,$^c)},flat @_ Z |(*+*,*-*,&[*],*/*,&[**])xx*}

Explanation:

-> *@_ {
  reduce
    -> $a, &b, $c { b($a,$c) },

    flat       # flatten list produced from zip
      zip
        @_,    # input

        slip(  # causes the list of operators to flatten into the xx list

          # list of 5 infix operators
          &infix:<+>, &infix:<->, &infix:<*>, &infix:</>, &infix:<**>

        ) xx * # repeat the list of operators infinitely
}

Technically * + * is a Whatever lambda, but is effectively the same as &[+] which is short for &infix:<+> the set of subroutines that handle infix numeric addition.
I didn't use that for multiplication or exponentiation as the ways to write them like that is at least as long as what I have (*×* or * * * and * ** *)

Test:

Test it on ideone.com
(after they upgrade to a Rakudo version that isn't from a year and a half before the official release of the Perl 6 spectests)

#! /usr/bin/env perl6

use v6.c;
use Test;

my @tests = (
  [1,2,3,4,5] => 0,
  [5,12,23,2,4,4,2,6,7] => 539,
  [-8,50,3,3,-123,4,17,99,13] => -1055.35694385, # -2982186493/2825761
  [2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2] => 256,
  [1,0,1,0,1,0] => 1,
  [-9,-8,-1] => -16,
  [0,-3] => -3,
  [-99] => -99,
);

plan +@tests;

my &code = {reduce {&^b($^a,$^c)},flat @_ Z |(*+*,*-*,&[*],&[/],&[**])xx*}

for @tests -> $_ ( :key(@input), :value($expected) ) {
  is code(@input), $expected, .gist
}
1..8
ok 1 - [1 2 3 4 5] => 0
ok 2 - [5 12 23 2 4 4 2 6 7] => 539
ok 3 - [-8 50 3 3 -123 4 17 99 13] => -1055.35694385
ok 4 - [2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2] => 256
ok 5 - [1 0 1 0 1 0] => 1
ok 6 - [-9 -8 -1] => -16
ok 7 - [0 -3] => -3
ok 8 - [-99] => -99

Brad Gilbert b2gills

Posted 2016-06-13T06:57:47.497

Reputation: 12 713

51 bytes – Jo King – 2019-01-08T00:29:36.130

3

A few tricks can reduce @Willmore´s approach by 23 to 174 bytes (requires php 5.6 or later). The most saving part is removing unneccessary parentheses (-10 bytes).

function f($a){while(count($a)>1){$l=array_shift($a);$r=array_shift($a);array_unshift($a,($j=$i++%5)?($j==1?$l-$r:($j==2?$l*$r:($j==3?$l/$r:$l**$r))):$l+$r);}return end($a);}

But using the ** operator instead of pow() also allows to use eval with an array for the operations; and with a few more tricks ...

PHP >= 5.6, 82 bytes

while(--$argc)eval('$x'.['/','**','+','-','*'][$i++?$i%5:2]."=$argv[$i];");echo$x;

takes list from command line parameters. Run with php -nr '<code>' or try it online.

old version, 161 157 151 145 144 140 137 117 bytes

function f($a){while(count($a)>1)eval('$a[0]=array_shift($a)'.['+','-','*','/','**'][$i++%5].'$a[0];');return$a[0];}

The most effective golfing came from writing the intermediate result directly to the first element - after shifting the previous result from the array.

breakdown

function f($a)
{
    while(count($a)>1)  // while array has more than one element ...
        eval('$a[0]='                           // future first element :=
            . 'array_shift($a)'                 // = old first element (removed)
            . ['+','-','*','/','**'][$i++%5]    // (operation)
            .'$a[0];'                           // new first element (after shift)
        );
    return$a[0];        // return last remaining element
}

test suite

$cases = array (
    0=>[1,2,3,4,5],
    539=>[5,12,23,2,4,4,2,6,7],
    '-1055.356...' => [-8,50,3,3,-123,4,17,99,13],
    256 => [2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2],
    1 => [1,0,1,0,1,0],
    -16 => [-9,-8,-1],
    -3 => [0, -3],
    -99 => [-99]
);
echo '<table border=1><tr><th>values</th><th>expected</th><th>actual result</th></tr>';
foreach ($cases as $expect=>$a)
{
    $result=f($a);
    echo "<tr><td>[", implode(',',$a),"]</td><td>$expect</td><td>$result</td></tr>";
}
echo '</table>';

Titus

Posted 2016-06-13T06:57:47.497

Reputation: 13 814

Nicely done. You could remove 3 more bytes by returning the last value as an array (change 'return $a[0]' to 'return$a'), which I'm not seeing is specifically against the rules. :) – 640KB – 2019-01-07T19:22:38.467

@gwaugh Imo If the array contains just a single number, we return that as the result. is pretty clear. But thanks for letting me revisit this. – Titus – 2019-01-10T13:29:28.117

One could make a semantic argument that the "that" in the sentence can refer to "the array". Regardless, your answer is by far the shortest PHP. Very nicely done, and thx again for pointers on my longer submission. – 640KB – 2019-01-10T17:32:39.390

2

IBM PC 8087 FPU, 66 82 bytes

Uses only the IBM PC's Intel 8087 math-coprocessor for calculations.

Try it offline! (in DOSBox or whatever). Give your old PC's bored 8087 chip something do to, other than all of those Lotus 1-2-3 spreadsheets you used to do in the 80's.

9bdf 0783 c302 499b de07 83c3 0249 e342 9bde 2783 c302 49e3 399b de0f 83c3 0249 
e330 9bde 3783 c302 49e3 2751 8b0f 9bd9 e883 f900 7413 9c7f 02f7 d99b d8c9 e2fb 
9d7d 069b d9e8 9bd8 f159 83c3 0249 e302 ebb5 c3

Ungolfed (unassembled):

START: 
    ; RUN TESTS  
    MOV  BX, OFFSET TST     ; 5, 12, 23, 2, 4, 4, 2, 6, 7
    MOV  CX, CTST           ; input array length
    CALL WOMI               ; calculate sequence
    CALL PRINT_FLT          ; output to console

    MOV  BX, OFFSET TST1    ; 5, 12, 23, 2, 4, -4, 2, 6, 7
    MOV  CX, CTST1
    CALL WOMI
    CALL PRINT_FLT

    MOV  BX, OFFSET TST2    ; -8, 50, 3, 3, -123, 4, 17, 99, 13
    MOV  CX, CTST2
    CALL WOMI
    CALL PRINT_FLT

    MOV  BX, OFFSET TST3    ; 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2
    MOV  CX, CTST3
    CALL WOMI
    CALL PRINT_FLT

    MOV  BX, OFFSET TST4    ; 1,0,1,0,1,0
    MOV  CX, CTST4
    CALL WOMI
    CALL PRINT_FLT

    MOV  BX, OFFSET TST5    ; -9, -8, -1
    MOV  CX, CTST5
    CALL WOMI
    CALL PRINT_FLT

    MOV  BX, OFFSET TST6    ; 0, -3
    MOV  CX, CTST6
    CALL WOMI
    CALL PRINT_FLT

    MOV  AX, 4C00H          ; exit to DOS
    INT  21H

;  TEST DATA

TST   DW  5, 12, 23, 2, 4, 4, 2, 6, 7
CTST  EQU ($-TST)/(SIZE TST)    ; count of items on list

TST1  DW  5, 12, 23, 2, 4, -4, 2, 6, 7
CTST1 EQU ($-TST1)/(SIZE TST1)  ; count of items on list

TST2  DW -8, 50, 3, 3, -123, 4, 17, 99, 13
CTST2 EQU ($-TST2)/(SIZE TST2)  ; count of items on list

TST3  DW 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2
CTST3 EQU ($-TST3)/(SIZE TST3)  ; count of items on list

TST4  DW 1,0,1,0,1,0
CTST4 EQU ($-TST4)/(SIZE TST4)  ; count of items on list

TST5  DW -9, -8, -1
CTST5 EQU ($-TST5)/(SIZE TST5)  ; count of items on list

TST6  DW 0, -3
CTST6 EQU ($-TST6)/(SIZE TST6)  ; count of items on list

; 8087 exponent: ST(0) = ST(0) ^ EXP
FIEXP   MACRO   EXP
        LOCAL   REPEAT, DONE
        PUSH CX
        MOV  CX, EXP        ; Exponent is count for loop
        FLD1                ; load 1 into ST
        CMP  CX, 0          ; is exponent pos, neg or 0?
        JZ   DONE           ; exit (with value 1) if exponent is 0
        PUSHF               ; save result flags for later
        JG   REPEAT         ; if exp > 1 start calculation
        NEG  CX             ; make exponent positive for loop
REPEAT:
        FMUL ST(0), ST(1)   ; multiply ST0 = ST0 * ST1
        LOOP REPEAT
        POPF                ; retrieve flags from earlier
        JGE  DONE           ; if exponent was negative, divide 1 by result
        FLD1                ; push 1 into numerator
        FDIV ST(0), ST(1)   ; ST0 = 1 / ST1
DONE:
        POP  CX
        ENDM

; Function WOMI: (Weapons of Math Instruction)
; input: BX - address of start of input array
;       CX - length of input array
; output: ST - result on top of 8087 register stack
WOMI PROC
    FILD WORD PTR [BX]      ; load first item
    ADD  BX, 2              ; move to next
    DEC  CX
CALC:
    FIADD WORD PTR [BX]     ; add
    ADD  BX, 2              ; move to next
    DEC  CX                 ; decrement counter
    JCXZ OUTPUT             ; check if done

    FISUB WORD PTR [BX]     ; subtract
    ADD  BX, 2
    DEC  CX
    JCXZ OUTPUT

    FIMUL WORD PTR [BX]     ; multiply
    ADD  BX, 2
    DEC  CX
    JCXZ OUTPUT

    FIDIV WORD PTR [BX]     ; divide
    ADD  BX, 2
    DEC  CX
    JCXZ OUTPUT

    FIEXP [BX]              ; exponent
    ADD  BX, 2
    DEC  CX
    JCXZ OUTPUT
    JMP CALC                ; start again

OUTPUT:
    RET 
WOMI ENDP

PRINT_FLT PROC
; print top of 8087 stack
; scaling: 14 digits, 4 decimal places
; input: BX = address of a TBYTE (BCD) output buffer
;       ST = value to display on top of 8087 stack  
    LEA   BX, BUFF                  ; set BX to BCD output buffer
    MOV   AH, 2
    MOV   WORD  PTR[BX], 10000      ; ten thousand (scale factor)
    FIMUL WORD  PTR[BX]             ; scale up by 10000
    FBSTP TBYTE PTR[BX]             ; store as BCD
    FWAIT                           ; sync 8088 and 8087
    TEST  BYTE  PTR[BX+9], 80H      ; check sign bit
    JE    PF_1                      ; 0, goto PF_1
    MOV   DL, '-'                   ; output '-'
    INT   21H
PF_1:
    ADD   BX, 8                     ; point to high byte
    MOV   CH, 7                     ; 14 digits before decimal point
    MOV   CL, 4                     ; 4 shifts (8 bytes / 2 = 4 = 1 nibble)
    MOV   DH, 2                     ; 2 times (8 bytes / 4)
PF_LOOP:
    MOV   DL, [BX]                  ; get BCD digits
    SHR   DL, CL                    ; move high digit to low nibble
    OR    DL, 30H                   ; convert to ASCII
    INT   21H
    MOV   DL, [BX]                  ; get byte again
    AND   DL, 0FH                   ; mask out high digit
    OR    DL, 30H                   ; convert to ASCII
    INT   21H                       ; output
    DEC   BX                        ; next byte
    DEC   CH                        ; decrement byte
    JG    PF_LOOP                   ; repeat if more bytes
    DEC   DH                        ; second time?
    JE    PF_DONE                   ; yes, done
    MOV   DL, '.'                   ; no, output decimal point
    INT   21H
    MOV   CH, 2                     ; 4 more digits after decimal point
    JMP   PF_LOOP                   ; go print digits
PF_DONE:
    MOV  DL, 0DH                    ; display newline CRLF
    MOV  AH, 2
    INT  21H
    MOV  DL, 0AH
    INT  21H
    RET 
PRINT_FLT ENDP

BUFF DT 0   ; output buffer for floating point digit string

_TEXT ENDS
END START

Output:

A>WOMI.COM
00000000000539.0000
-00000000000027.9136
-00000000001055.3569
00000000000256.0000
00000000000001.0000
-00000000000016.0000
-00000000000003.0000

Input is via a PROC (x86 most equivalent to a function), with BX being a pointer to an array of WORDs in memory, and CX being the number of items in it and returns the result in ST.

*Note: The actual code for the function is 66 82 bytes. Of course, the code just to write a floating point number to the console (cookbook code) is 83 bytes. The testing program and data is 183 215 bytes, making the .COM executable 305 380 bytes in total.

640KB

Posted 2016-06-13T06:57:47.497

Reputation: 7 149

1This is great! I've written a similar solution for x86-64 (linux) but I haven't golfed it much yet which will probably change a lot of the logic around.

For your exponent calculation, even though the tests given don't test receiving a negative exponent, I felt that it was a necessary part of the program logic, especially since it's as simple as pushing 1 to st0 and then doing a div between st0 and st1 (at least on x86 this is two instructions). – davey – 2019-01-09T10:42:32.007

Thanks @davey -- very good point! I've updated the code to handle negative exponents and added another test case for it. – 640KB – 2019-01-09T15:40:28.863

2

Japt, 16 bytes

r@[XY]r"p+-*/"gZ

Try it online!

Explanation:

r@                  #Reduce the input list:
       "p+-*/"      # The list of functions to apply (offset by one due to the behavior of Z)
              gZ    # Choose the one at the current index, wrapping
  [  ]r             # Apply that function to:
   X                #  The result of the previous step
    Y               #  and the current number
                    #Implicitly return the result of the final step

Kamil Drakari

Posted 2016-06-13T06:57:47.497

Reputation: 3 461

Ah, feck, was just working on this myself, trying to figure out why it was giving me incorrect results - I'd missed the fecking exponentiation! :\ – Shaggy – 2019-01-10T17:40:15.167

2

Brachylog, 68 bytes

hI,?bL,1:+:-:*:/:^b:L:I{bhv?t.|[O:L:I]h$(P,LbM,OhA,Lh:Ir:A&:M:Pr&.}.

That's long… but it uses no evaluation predicate.

Explanation

  • Main predicate

    hI,                                  Unify I with the first element of the input
       ?bL,                              L is the input minus the first element
           1:+:-:*:/:^b                  Construct the list of predicates [+:-:*:/:^]
                       :L:I{...}.        Call predicate 1 with [[+:-:*:/:^]:L:I] as input
    
  • Predicate 1

    bhv?t.                               If the second element of Input is empty (i.e. L),
                                         unify Output with the last element of Input
    |                                    Or
    [O:L:I]                              Input = [O:L:I]
           h$(P,                         P is O circularly permutated to the left
                LbM,                     M is L minus the first element
                    OhA,                 A is the first element of O
                        Lh:Ir:A&         Call predicate A on [I:First element of L]
                                :M:Pr&.  Call predicate 1 recursively with P:M:
    

Fatalize

Posted 2016-06-13T06:57:47.497

Reputation: 32 976

Beat you by 1̶ ̶b̶y̶t̶e̶ 2 bytes ;) – LegionMammal978 – 2016-06-13T10:50:45.707

2

APL (Dyalog Unicode), 29 27 bytesSBCS

Anomymous tacit prefix function. Note that * is exponentiation in APL.

≢{⍎3↓⍕⌽⍵,¨⍨⍺⍴'+-×÷*',¨'⍨'}⊢

Try it online!

Because APL executes right to left, we can just reverse the order of arguments of the inserted operations and reverse the entire expression. Postfix reverses arguments. After doing a perfect shuffle of numbers and operations, we only just need to reverse, flatten, and evaluate:

≢{}⊢ call the following function with count of and actual numbers as and :

'⍨' this character

'+-×÷*',¨ prepend each of these characters to that; ["+⍨","-⍨","×⍨","÷⍨","*⍨"]

⍺⍴ use the left argument (count of numbers) to cyclically reshape that

 reverse

 format as flat string

3↓ drop leading 3 characters (a space and a symbol and )

 execute as APL code

Adám

Posted 2016-06-13T06:57:47.497

Reputation: 37 779

1

Ruby, 57 bytes

->a{i=0;a.reduce{|x,y|x.send %w[** + - * /][(i+=1)%5],y}}

Try it online!

Takes an array of floats, but also works with integers, as long as all division results are integer.

At first, I tried fiddling with eval which looks like the obvious approach, but it gets rather verbose. Instead, I opted for send, which is basically Ruby's way to call methods by names, so that x.send("+",y) is equivalent to x+y.

Kirill L.

Posted 2016-06-13T06:57:47.497

Reputation: 6 693

1

shell script, 157 135 133 130 124 99 95 88 85 81 bytes

golfed (bash/non-posix) - 81 bytes

f()(A=$1;S=+-*/^;shift;for B;{ C=${S:((I++%5)):1};A=`bc -l<<<$A$C$B`;};echo $A)

golfed (portable/posix, using 'cut'-operator) - 118 bytes

f()(S=+-x/^;A=$1;shift;for B;do C=`echo $S|cut -b1`;S=`echo $S|cut -b2-5`;S="$S$C";A=`echo $A$C$B|bc -l`;done;echo $A)

golfed (portable/posix, with builtins) - 124 bytes

f()(A=$1;shift;for B;do case $I in 1)C=-;;2)C=*;;3)C=/;;4)C=^;;*)C=+;I=;;esac;I=$((I+1));A=`echo $A$C$B|bc -l`;done;echo $A)

ungolfed (posix - with builtins):

A=$1
shift
for B;do
case $I in
1)C=-;;
2)C=*;;
3)C=/;;
4)C=^;;
*)C=+;I=
esac
I=$((I+1))
A=`echo $A$C$B|bc -l`
done
echo $A

ungolfed (posix - with 'cut'):

S=+-x/^
A=$1
shift
for B;do
C=`echo $S|cut -b1`
S=`echo $S|cut -b2-5`
S="$S$C"
A=`echo $A$C$B|bc -l`
done
echo $A

This is unfair!

We don't have real division in language 'sh',
so we must use 'bc' which is...lame 8-)

hint: your directory must have no files, otherwise the asterisk expands to filenames (◔_◔)

Tests:

# f 1 2 3 4 5
0
# f 5 12 23 2 4 4 2 6 7
539
# f -8 50 3 3 -123 4 17 99 13
-1055.35
# f 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
256.00
# f 1 0 1 0 1 0
1
# f -9 -8 -1
-16
# f 0 -3
-3
# f -99
-99

Bastian Bittorf

Posted 2016-06-13T06:57:47.497

Reputation: 101

1

05AB1E, 29 28 27 bytes

Using 'Python eval' builtin (29 28 27 bytes):

g'(×svy')"+-*/"S„**ªNè}\J.E

Try it online or verify all test cases. (NOTE: ª is ¸« and we use the legacy version in the TIO, because .E is disabled in the new version of 05AB1E on TIO.)

Using 'Execute as 05AB1E' builtin (29 28 bytes):

vyD0‹i¦'(}N_iðë"m+-*/"Nè]J.V

Try it online or verify all test cases.

Explanation:

In Python ** is used for exponentiation. In addition, *,/,** have operator precedence over +,-. So the code transforms [-1,2,-3,4,-5] to (((((-1)+2)--3)*4)**-5), and then uses .E to execute the string as Python eval.

g                  # Take the length of the (implicit) input
 '(×              '# Create a string of "(" characters of that size
s                  # Swap so the (implicit) input is at the top of the stack again
 v            }    # Loop `y` of each of its items:
  y                #  Push `y`
   ')             '#  Push ")"
     "+-*/"S       #  Push ["+","-","*","/"]
            „**ª   #  Append a trailing "**": ["+","-","*","/","**"]
                Nè #  Get a string from this list based on the index of the loop
                   #  (with automatic wraparound)
\                  # Discard the trailing operand from the stack
 J                 # Join all strings on the stack together
  .E               # Execute as Python eval (and output implicitly)

In 05AB1E negative values are with a trailing ( instead of leading -, and m is used for exponentiation. In addition, a Polish notation is used. So the program transforms [-1,2,-3,4,-5] to 1( 2+3-4*5(m, and then uses .V to execute the string as 05AB1E code.

v                  # Loop `y` of each of its items:
 y                 #  Push `y`
  D0‹i   }         #  If `y` is negative:
      ¦            #   Remove the first character (the minus sign)
       '(         '#   And push a "("
  N_i              #  If the index of the loop is 0:
     ð             #   Push a space character
    ë              #  Else:
     "m+-*/"Nè     #   Push a character from "m+-*/" based on the index of the loop
                   #   (with automatic wraparound)
]                  # Close both the if-else and loop
 J                 # Join all strings on the stack together
  .V               # Execute as 05AB1E code (and output implicitly)

Kevin Cruijssen

Posted 2016-06-13T06:57:47.497

Reputation: 67 575

1

05AB1E, 15 bytes

ćsvy"+-*/m"Nè.V

Try it online! or as a Test Suite

Explanation

ć                # extract the head of the input list
 sv              # for each (value y, index N) in the rest of the list
   y             # push the element
    "+-*/m"Nè    # push a string representation of the Nth operator (wraps around)
             .V  # execute it as code

Emigna

Posted 2016-06-13T06:57:47.497

Reputation: 50 798

1

C# (.NET Core), 130 bytes

Without LINQ.

s=>{var x=s[0];for(var j=1;j<s.Length;j++){int t=j%5;var z=s[j];x=t<1?x=Math.Pow(x,z):t<2?x+=z:t<3?x-=z:t<4?x*=z:x/=z;}return x;};

Try it online!

Destroigo

Posted 2016-06-13T06:57:47.497

Reputation: 401

284 - use the interpreter because it imports LINQ (among other commonly used core libraries) for free – ASCII-only – 2019-01-08T02:04:09.717

1

Runic Enchantments, 64 bytes

R31B~~?@+31B~~?@S-31B~~?@*31B~~?@S,31B~~?@Sp
\i<{1[lil1-{S{)]{{B

Try it online!

First line is the main program loop, which reads a number from input and performs the next math instruction. If no input, the attack is dumped to the output and the program terminates. Entry point is the < on the second line, which reads the first number from input prior to entering the main loop. Invalid input blindly accepted with unpredictable results (only + and * are defined for strings, other operations would result in an empty stack).

Woo, finally found a use for Branch command! The second line starting at index 3 acts like a function. In this case it takes in input, checks that it got input, and arranges the stack for return. Then 31B~~ invokes and cleans up after the invokation (as the Branch instruction leaves 2 values on top of the stack, add a return pointer). All told the overhead (8+5n) was less than in-line (9n). I think I'll be adding a modifier that cause B to not push those 2 values (overhead of 2 bytes to save 2n bytes). Happily, no directional commands are needed to insure consistent execution.

Also featured is the [ and ] stack-of-stacks commands, which lets the program temporarily remove the return location from the stack as it handles reading input. It saves several bytes worth of stack manipulation having to otherwise work around those 2 values. These do enforce a maximum input list of 9 values. Changing the entry to y<< increases that to 19 items (and as < acts like a NOP, the branch pointer doesn't need to update). A third line with \y<< (changing the existing \ to U) would double that again to 39 items.

Stack at the end of the Branch "function" would look like [v,i,1,x,y] where x,y are at the top and the 0-indexed location on the first line (y will always be 0) where the next instruction with execute. v is the value that started on the stack prior to entry into the Branch "function". And i is the value read from input. If no input was available, [i,1] would instead be [0] resulting in v being printed when ?@ is reached.

Draco18s no longer trusts SE

Posted 2016-06-13T06:57:47.497

Reputation: 3 053

1

x86-64 machine code (Linux), 90 bytes

0000000000000000 <weapons_asm>:
   0:   48 89 f1                mov    %rsi,%rcx
   3:   db 07                   fildl  (%rdi)

0000000000000005 <math_loop>:
   5:   48 83 c7 04             add    $0x4,%rdi
   9:   48 ff c9                dec    %rcx
   c:   e3 49                   jrcxz  57 <done>
   e:   da 07                   fiaddl (%rdi)
  10:   48 83 c7 04             add    $0x4,%rdi
  14:   48 ff c9                dec    %rcx
  17:   e3 3e                   jrcxz  57 <done>
  19:   da 27                   fisubl (%rdi)
  1b:   48 83 c7 04             add    $0x4,%rdi
  1f:   48 ff c9                dec    %rcx
  22:   e3 33                   jrcxz  57 <done>
  24:   da 0f                   fimull (%rdi)
  26:   48 83 c7 04             add    $0x4,%rdi
  2a:   48 ff c9                dec    %rcx
  2d:   e3 28                   jrcxz  57 <done>
  2f:   da 37                   fidivl (%rdi)
  31:   48 83 c7 04             add    $0x4,%rdi
  35:   48 ff c9                dec    %rcx
  38:   e3 1d                   jrcxz  57 <done>

000000000000003a <exp_rept>:
  3a:   51                      push   %rcx
  3b:   8b 0f                   mov    (%rdi),%ecx
  3d:   d9 e8                   fld1
  3f:   83 f9 00                cmp    $0x0,%ecx
  42:   74 10                   je     54 <exp_rept.done>
  44:   9c                      pushfq
  45:   7f 02                   jg     49 <exp_rept.l>
  47:   f7 d9                   neg    %ecx

0000000000000049 <exp_rept.l>:
  49:   d8 c9                   fmul   %st(1),%st
  4b:   e2 fc                   loop   49 <exp_rept.l>
  4d:   9d                      popfq
  4e:   7d 04                   jge    54 <exp_rept.done>
  50:   d9 e8                   fld1
  52:   de f9                   fdivrp %st,%st(1)

0000000000000054 <exp_rept.done>:
  54:   59                      pop    %rcx
  55:   eb ae                   jmp    5 <math_loop>

0000000000000057 <done>:
  57:   dd 1a                   fstpl  (%rdx)
  59:   c3

Firstly, credit to gwaugh's answer which is also submitted for this post. I started working on this solution before gwaugh posted, which can be seen in my git repo's log, but ultimately his approach to this problem was the most efficient (especially the exponentiation). If you feel inclined to upvote my submission, please check out his as well.

Like my other x86 solutions, this code is simply a function that's meant to be called from a C/C++ program, which can be seen at my git repo. This means that the input array, length, and return pointer are passed through rdi, rsi, and rdx. For x86-64, getting the output location as an argument saves bytes, because normally when a C/C++ function returns a double on this processor, it's passed back through xmm0. This means the result double has to be moved from the FPU stack to a place in memory, then moved into xmm0. If we specify a place in memory we want the result, then we can just move the result double directly from the FPU stack to the memory location.

Exponentiation is done through repeated multiplication, with the assumption that we'll only get integer exponents (though the exponent can be negative). If the problem requires handling floating point exponentiation, the solution becomes extremely complicated. The standard way to compute x^y on x86 is to compute 2^(y * log2(x)). However, if x is negative (which happens in test case 2), log2(x) is a complex number, which can't be directly handled by the FPU. If you're curious how pow(double x, double y) is solved in C, check out the glibc code here (hint: it's complicated).

davey

Posted 2016-06-13T06:57:47.497

Reputation: 321

1

c#, 238, 202 bytes

double d(double[]a){Array.Reverse(a);var s=new Stack<double>(a);int i=0,j;while(s.Count>1){double l=s.Pop(),r=s.Pop();j=i++%5;s.Push(j==0?l+r:j==1?l-r:j==2?l*r:j==3?l/r:Math.Pow(l,r));}return s.Peek();}

I didn't see any c# solution so I will give one. This is my first codegolf. I started writing in c# "two months ago" (though I know Java to some extent).

It uses Stack

Try online!

Ungolfed and test cases

using System;
using System.Collections.Generic;

class M 
{
    double d(double[]a) {
        Array.Reverse(a);
        var s = new Stack<double>(a);
        int i=0,j;
        while (s.Count>1)
        {
            double l=s.Pop(),r=s.Pop();
            j=i++%5;
            s.Push(j==0?l+r:j==1?l-r:j==2?l*r:j==3?l/r:Math.Pow(l, r));
        }
        return s.Peek();
    }

    public static void Main()
    {
        int[][] a = new int[][]{
            new int[]{1,2,3,4,5},
            new int[]{5,12,23,2,4,4,2,6,7},
            new int[]{-8,50,3,3,-123,4,17,99,13},
            new int[]{2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2},
            new int[]{1,0,1,0,1,0},
            new int[]{-9,-8,-1},
            new int[]{0,-3},
            new int[]{-99}
        };

        for (int i = 0; i < a.Length; i++)
        {
            Console.WriteLine(new M().d(Array.ConvertAll(a[i], e => Convert.ToDouble(e))));
        }
        Console.ReadKey();
    }
}

Output:

0
539
-1055,35694384628
256
1
-16
-3
-99

display_name

Posted 2016-06-13T06:57:47.497

Reputation: 377

Hi, and welcome to PPCG! This might be a nice topic to look at: Tips for code-golfing in C#. Some things that can be golfed down in your code: spaces (a, Double.Parse -> a,Double.Parse; while (s.Count -> while(s.Count; Pow(l, r) -> Pow(l,r)). Also, you can remove int in front of the j= and put it behind the int i=0,j;. Great first answer though, and once again welcome. :)

– Kevin Cruijssen – 2016-06-16T07:36:32.480

@KevinCruijssen Hi! Ty! Spaces removed and j moved as you suggested :) – display_name – 2016-06-16T07:52:07.513

1

PHP, 206,198,197 bytes

function f($a){while(count($a)>1){$l=array_shift($a);$r=array_shift($a);array_unshift($a,($j=$i++%5)==0?($l+$r):($j==1?($l-$r):($j==2?($l*$r):($j==3?($l/$r):(pow($l,$r))))));}return array_pop($a);}

Try online!

Ungolfed

<?php

function f($a)
{
    while(count($a)>1)
    {
        $l = array_shift($a); $r = array_shift($a);
        array_unshift($a,($j=$i++%5)==0?($l+$r):($j==1?($l-$r):($j==2?($l*$r):($j==3?($l/$r):(pow($l,$r))))));
    }
    return array_pop($a);
}

echo f([1,2,3,4,5])."\n";
echo f([5,12,23,2,4,4,2,6,7])."\n";
echo f([-8,50,3,3,-123,4,17,99,13])."\n";
echo f([2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2])."\n";
echo f([1,0,1,0,1,0])."\n";
echo f([-9,-8,-1])."\n";
echo f([0,-3])."\n";
echo f([-99])."\n";

In PHP, logic similar to my c# answer (202 bytes) :) .

display_name

Posted 2016-06-13T06:57:47.497

Reputation: 377

1

Emacs Lisp, 127 bytes

(lambda(x)(let((f'(+ - * / expt))(a(float(car x)))(x(cdr x)))(dotimes(i(length x)a)(set'a(funcall(nth(mod i 5)f)a(nth i x))))))

Ungolfed:

(lambda(x)
  (let ((f'(+ - * / expt))  ; list of functions in order they are called
        (a (float (car x))) ; initial value
        (x (cdr x)))        ; 
    (dotimes (i (length x) a)
      (set 'a (funcall (nth (mod i 5) f) ; call the i % 5th function
                       a                 ; with accumulator
                       (nth i x))))))    ; and the ith value

Testcases:

(-map
  (lambda(x)(let((f'(+ - * / expt))(a(float(car x)))(x(cdr x)))(dotimes(i(length x)a)(set'a(funcall(nth(mod i 5)f)a(nth i x))))))
  '((1 2 3 4 5)
    (5 12 23 2 4 4 2 6 7)
    (-8 50 3 3 -123 4 17 99 13)
    (2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2)
    (1 0 1 0 1 0)
    (-9 -8 -1)
    (0 -3)
    (-99)))

Output:

(0.0 539.0 -1055.356943846277 256.0 1.0 -16.0 -3.0 -99.0)

Lord Yuuma

Posted 2016-06-13T06:57:47.497

Reputation: 587