24
\$\begingroup\$

Several years back, Hot Wheels made a simple flash game called "Formula Fuelers Racers"*. To play the game, you select three ingredients from a fridge to put into your car, which is then raced against the computer's randomly-generated car. It turns out the mechanics of this game are pretty simple. First off, the actual race "time" of your car is randomly generated and has no bearing on whether or not you win the race. Secondly, the winner of the race is determined by a score which is calculated from the selected ingredients (duplicate ingredients are allowed, and the order matters). Each ingredient has an associated "value" and an associated "operation" as shown in the following table:

#   ingredient     val  op
1   Hot Salsa       2   +
2   Root Beer       1   +
3   Milk            1   +
4   Pickle Juice    2   +
5   Mystery Lunch   -3  *
6   BBQ Sauce       2   +
7   Egg             1   +
8   Ketchup         2   +
9   Mustard         -1  *
10  Melon           1   +
11  Chocolate Milk  1   +
12  Mayonnaise      -2  *
13  Baby Food       0   +
14  Pepper          1   +
15  Salt            2   +
16  Syrup           -1  *
17  Salad Dressing  2   +
18  Orange Juice    1   +
19  Soy Sauce       2   +

For convenience, this challenge will be referring to ingredients by their number and not their name. Here are the steps to compute a score:

  1. First, initialize the score with the value of the first ingredient.
  2. Then, use the second ingredient's operation to combine the current score and the second ingredient's value to get an updated score.
  3. Finally, use the third ingredient's operation to combine the current score and the third ingredient's value to get the final score.

Higher scores are better and always beat lower scores.

For example, the ingredients 1 2 3 have a score of (2+1)+1 = 4. The ingredients 7 5 6 have a score of (1*-3)+2 = -1. Therefore, 1 2 3 beats 7 5 6.

Challenge

In this challenge, you shall write a program which takes an ordered list of 3 integers and outputs the corresponding score.

Input

Your program may accept a list of three integers in the most convenient format. You are allowed to use either 1-indexing for the ingredient names (as above) or 0-indexing (subtract 1 from every index above).

Ouput

Your program must output a single integer indicating the score.

Test Cases

4 5 5  =>  18 // max score
5 5 5  =>  -27 // min score
13 13 13  =>  0
1 2 3  =>  4
7 5 6  =>  -1
16 2 19  =>  2
19 7 12  =>  -6

*This page is pretty outdated and doesn't work in some browsers, but you don't need to play the game for this challenge.

\$\endgroup\$
10
  • 1
    \$\begingroup\$ So basically Salsa+Lunch+Mayo=Invincible? \$\endgroup\$ Apr 9, 2017 at 23:02
  • 3
    \$\begingroup\$ @SIGSEGV Duplicate ingredients are allowed. Salsa, Lunch, Lunch is allowed for a score of 18 that beats your 12. \$\endgroup\$ Apr 9, 2017 at 23:21
  • 2
    \$\begingroup\$ For reference, here is an archive of the game. \$\endgroup\$ Apr 10, 2017 at 8:00
  • 4
    \$\begingroup\$ Who keeps salt in the fridge? :) \$\endgroup\$
    – Wossname
    Apr 10, 2017 at 12:26
  • 4
    \$\begingroup\$ 1. I don't know why salt would be in a fridge. 2. Yes, once you discover an 18-point combo you become literally invincible and the game becomes meaningless. \$\endgroup\$
    – PhiNotPi
    Apr 10, 2017 at 20:44

14 Answers 14

14
\$\begingroup\$

Jelly, 24 bytes

“zẈ€$ụ¤’b6’ị@µỊị⁾+׿CFḊV

Takes a list of 0-indexed ingredients.

Try it online! or see a test suite

How?

Uses a slightly convoluted form of compressing the values as a base-6 number and the fact that the multiplicative entries are the negative ones. Instead of simply shifting up by 3 to get the base-6 digits, the complemented values incremented are used - this saves bytes by allowing the atom to pick out the negative entries prior to the complement step while also saving a byte in the base-250 compression.

“zẈ€$ụ¤’b6’ị@µỊị⁾+׿CFḊV - Main link: 0-based ingredient list  e.g. [6,4,5]
“zẈ€$ụ¤’                 - base 250 compressed number: 120851767994004
        b6               - convert to base 6: [1,1,0,5,0,1,0,3,1,1,4,2,1,0,3,0,1,0,0]
          ’              - decrement: [0,0,-1,4,-1,0,-1,2,0,0,3,1,0,-1,2,-1,0,-1,-1]
           ị@            - index into [reversed @rguments]          [0,4,-1]
             µ           - monadic chain separation (call that x)
              Ị          - insignificant(x)? (abs(x)<=1)            [1,0,1]
                ⁾+×      - ['+','×']
               ị         - index into                               ['+','×','+']
                    C    - complement(x) (1-x)                      [1,-3,2]
                   ż     - zip                                      [['+',1],['×',-3],['+',2]]
                     F   - flatten                                  ['+',1,'×',-3,'+',2]
                      Ḋ  - dequeue                                  [1,'×',-3,'+',2]
                       V - evaluate as Jelly code                   -1
\$\endgroup\$
4
  • \$\begingroup\$ How does the "base 250 compressed number" part work? \$\endgroup\$
    – ckjbgames
    Apr 10, 2017 at 14:46
  • \$\begingroup\$ @ckjbgames The zẈ€$ụ¤ are read as their (1-indexed) indexes in the Jelly code-page, which are [123,188,13,37,226,4], and interpreted as a base-250 number: 123*250**5+188*250**4+13*250**3+37*250**2+226*250**1+4*250**0=120851767994004 (see the string-literal section of the tutorial.) \$\endgroup\$ Apr 10, 2017 at 15:26
  • \$\begingroup\$ Oh, a string literal. \$\endgroup\$
    – ckjbgames
    Apr 10, 2017 at 15:36
  • \$\begingroup\$ This was my approach until I realized "-3" doesn't mean "-3" when evaluating as 05AB1E code. \$\endgroup\$ Apr 10, 2017 at 17:56
11
\$\begingroup\$

JavaScript (ES6), 89 84 82 78 73 bytes

Takes input as an array of 3 integers, using 0-indexing.

a=>(o=a=>F()<0?a*n:a+n)(o((F=_=>n='5445054524413452545'[a.shift()]-3)()))

Test cases

let f =

a=>(o=a=>F()<0?a*n:a+n)(o((F=_=>n='5445054524413452545'[a.shift()]-3)()))

console.log(f([3, 4, 4]))     // =>  18
console.log(f([4, 4, 4]))     // =>  -27
console.log(f([12, 12, 12]))  // =>  0
console.log(f([0, 1, 2]))     // =>  4
console.log(f([6, 4, 5]))     // =>  -1
console.log(f([15, 1, 18]))   // =>  2
console.log(f([18, 6, 11]))   // =>  -6

Previous version, 78 bytes

Takes the 3 integers in currying syntax (a)(b)(c), using 0-indexing.

a=>b=>(o=a=>b=>(n=F(b))<0?a*n:a+n)(o((F=n=>'5445054524413452545'[n]-3)(a))(b))

How it works

One slightly unusual thing about this code is that it only takes 2 arguments in 'common' currying syntax a => b => and eventually returns a function that takes the 3rd one.

Breakdown

F = n => '5445054524413452545'[n] - 3
o = a => b => (n = F(b)) < 0 ? a * n : a + n
f = a => b => o(o(F(a))(b))
f(a)(b)(c)
  |  |  |
  |  |  +-- 'b' argument of the function returned by the outer call to 'o'
  |  +----- 'b' argument of the function returned by 'f'
  +-------- 'a' argument of 'f'

Test cases

let f =

a=>b=>(o=a=>b=>(n=F(b))<0?a*n:a+n)(o((F=n=>'5445054524413452545'[n]-3)(a))(b))

console.log(f(3)(4)(4))     // =>  18
console.log(f(4)(4)(4))     // =>  -27
console.log(f(12)(12)(12))  // =>  0
console.log(f(0)(1)(2))     // =>  4
console.log(f(6)(4)(5))     // =>  -1
console.log(f(15)(1)(18))   // =>  2
console.log(f(18)(6)(11))   // =>  -6

\$\endgroup\$
1
  • 1
    \$\begingroup\$ Strictly speaking, you're taking 1 argument and returning a function that takes 1 argument, computes a value to invoke a function that takes 1 argument and returns a function that takes 1 argument, and returns that final function... \$\endgroup\$
    – Neil
    Apr 10, 2017 at 10:09
6
\$\begingroup\$

Befunge, 74 73 bytes

>&:0`!#^_1g68*-^:0`!#v_+
^2112-212/11.012/212 >*
^   @.$<       >">"35*0p

Try it here! It's weird that my code works on this one interpreter only.

The second row basically contains all of the values from the table. The non-numeric values are actually negative values as they come before the digits on the ASCII table. There's a bit of logic there that determines if the number is negative or not, and if it is, this number is multiplied by the result.

The right side of the third row initializes the first number. If I didn't have to do that, I could save a lot of bytes.

\$\endgroup\$
6
\$\begingroup\$

05AB1E, 29 bytes

•6SÚ²ÄOÕ6BS3-©¹è|v®yèD0‹i*ë+

Try it online!

•6SÚ²ÄOÕ6BS3-©               # Push [2, 1, 1, 2, -3, 2, 1, 2, -1, 1, 1, -2, 0, 1, 2, -1, 2, 1, 2] and store.
               ¹è             # Get first score.
                 |v           # Iterate through remaining scores.
                   ®yèD0‹i*ë+ # Push score list, grab relevant score.
                              # If negative, multiply, else add.

This actually works for as many or as few inputs as you'd like, so you can have cars with 4 or more traits or cars with just 2. This was not intentional, just how it ended up.

\$\endgroup\$
6
\$\begingroup\$

PHP, 128 Bytes

$i="5445054524413452545";[,$a,$b,$c]=$argv;echo(bc.($i[$c]-3<0?mul:add))((bc.($i[$b]-3<0?mul:add))($i[$a]-3,$i[$b]-3),$i[$c]-3);

PHP, 138 Bytes

$d=decbin(506743);$i="5445054524413452545";[,$a,$b,$c]=$argv;echo(bc.($d[$c]?add:mul))((bc.($d[$b]?add:mul))($i[$a]-3,$i[$b]-3),$i[$c]-3);

Online Version

Expanded

$d=decbin(506743);
$i="5445054524413452545";
[,$a,$b,$c]=$argv;
echo(bc.($d[$c]?add:mul))((bc.($d[$b]?add:mul))($i[$a]-3,$i[$b]-3),$i[$c]-3);
\$\endgroup\$
6
\$\begingroup\$

Python 2, 123 110 107 bytes

a,b,c=input()
s=[int(i)-3for i in'05445054524413452545']
n=s[a]
for i in s[b],s[c]:n=[n*i,n+i][n>0]
print n

Try it online!


-3 bytes thanks to @mathjunkie

\$\endgroup\$
3
  • 1
    \$\begingroup\$ Here is an improved version, 118 bytes \$\endgroup\$
    – Mr. Xcoder
    Apr 10, 2017 at 12:27
  • 2
    \$\begingroup\$ 5445054524413452545 then subtract 3 may save you tons of bytes. \$\endgroup\$ Apr 10, 2017 at 17:54
  • 1
    \$\begingroup\$ n=[n+i,n*i][i<0] inside the loop saves you 3 bytes \$\endgroup\$ Apr 11, 2017 at 14:47
5
\$\begingroup\$

CJam, 43 38 bytes

q~[YXXY-3YXYWXX-2TXYWYXY]f={_W>42+c~}*

There might be a way to compress the list further...

Uses 0-based indexing.

Try it online!

Explanation

This program makes use of the fact that a value is multiplicative instead of additive if and only if its negative.

q~                     e# Get the list from input
  [...]                e# Push the list of values for each ingredient. T=0, W=-1, 
                       e#   X=1, Y=2. 
       f=              e# Get the elements at the given indices 
         {             e# Reduce over this block:
          _W>          e#  Check if the second number is > -1 (returning 0 or 1)
             42+c      e#  Add the result to 42 and cast to a char. 
                       e#    (ASCII 42 is * and 43 is +)
                 ~     e#  Eval the char (* is multiply, + is add)
                  }*   e# (end block)
\$\endgroup\$
1
  • \$\begingroup\$ Nice + * trick! \$\endgroup\$ Apr 17, 2017 at 17:48
3
\$\begingroup\$

Lua, 140 131 bytes

i={2,1,1,2,-3,2,1,2,-1,1,1,-2,0,1,2,-1,2,1,2}function f(a,b,c)loadstring(("print("..i[a].."+"..i[b].."+"..i[c]..")"):gsub('%+%-','*-'))()end

i={2,1,1,2,-3,2,1,2,-1,1,1,-2,0,1,2,-1,2,1,2}function f(a,b,c)x,y,z=i[a],i[b],i[c]v=y>0 and x+y or x*y;print(z>0 and v+z or v*z)end
\$\endgroup\$
3
\$\begingroup\$

JavaScript, 85 72 bytes

a=a=>eval(a.map(x=>(b="5445054524413452545"[x]-3,b<0?"*":"+")+b).join``)

Takes input in format [a,b,c]
-13 bytes thanks to ETHproductions

\$\endgroup\$
3
  • \$\begingroup\$ You can do x=>(b="...",b<0?"*":"+")+b to avoid the return, I think. (Also, you don't need the [... ], indexing works on strings) \$\endgroup\$ Apr 11, 2017 at 0:30
  • \$\begingroup\$ @ETHproductions I get "Expected ';'. It may be my browser, does a=a=>eval(a.map(x=>(b="5445054524413452545"[x]-3,b<0?"*":"+")+b)).join``) work for you? \$\endgroup\$ Apr 11, 2017 at 0:38
  • \$\begingroup\$ You've got an extra ) after +b, I believe \$\endgroup\$ Apr 11, 2017 at 0:41
2
\$\begingroup\$

R, 125 123 bytes

function(a,b,c){v=c(5,4,4,5,0,5,4,5,2,4,4,1,3,4,5,2,5,4,5)-3
o=rep("+",19)
o[v<0]="*"
get(o[c])(get(o[b])(v[a],v[b]),v[c])}

Anonymous function that takes three integers as input. Defines a list of values and operations, and then just evaluates the ones called by the input, i.e. o3(o2(v1,v2),v3). There's almost definitely a golfier way to do this!

Update: after some re-working, I have an alternative, also 123 bytes. Again, an anonymous function, but takes input as a single vector of three values. Uses the same approach, defining a list of values and operations and evaluating it.

function(x,f=c(sum,prod)[x[-1]%in%c(5,9,12,16)+1],s=c(5,4,4,5,0,5,4,5,2,4,4,1,3,4,5,2,5,4,5)[x]-3)f[[2]](el(f)(s[-3]),s[3])
\$\endgroup\$
2
\$\begingroup\$

Haskell, 186 116 112 108 bytes

o x|x<0=(*)|0<1=(+)
v=(map((-51+).fromEnum)"95445054524413452545"!!)
w [x,y,z]=(o z)((o y)x y)z
k=w.map v

Main function is k. New to Code Golf so I am sure there are a few bytes I could shave off with clever use of $ operator versus parentheses. I will probably update the answer as I continue to find improvements.

Essentially the program can be broken down like this:

  • v is a function that takes a 1 based index and returns the value of that food id.
  • o is a function that takes the food value and returns the appropriate operator (Eg. negative values are always * where positive values are always +)
  • w is a function that takes a List of 3 partial functions of v mapped to input integers and fetches the appropriate operations and values from each and returns the proper output.
  • k is the main function in point free style that maps v to input and composes this list for w to return the output.

UPDATE

Special thanks for pointing out the fromEnum trick! That worked out nicely. Also I missed the part in the rules that stated an acceptable solution could be a function that takes a list of integers. That saved a tremendous amount of work.

UPDATE 2

As per other suggestions, shaved a handful of bytes by reordering operations, creating an else guard that always evaluates to True, and a pattern matching on W that pattern matches on a List of 3 elements. Thanks for the suggestions!

UPDATE 3

Another thanks to Laikoni for pointing out more code golf rules that I was not aware of. Also mapping v to my input to create a list of partially applied functions was a phenomenal idea and saved me 4 additional bytes!

\$\endgroup\$
9
  • 1
    \$\begingroup\$ Welcome to PPCG and Haskell golfing in particular! You can save a lot of bytes by writing a function [Int] -> Int instead of reading from stdin and writing to stdout. Doing so is allowed by default, but in this case its even explicitly mentioned in the challenge that taling a list of integers as input is acceptable. \$\endgroup\$
    – Laikoni
    Apr 12, 2017 at 19:35
  • 1
    \$\begingroup\$ Using fromEnum instead of digitToInt is likely to be shorter because it allows you to drop the import. \$\endgroup\$
    – Laikoni
    Apr 12, 2017 at 19:39
  • \$\begingroup\$ @Laikoni Much thanks to you for pointing out some of the rules I wasn't aware of! The fromEnum trick worked like a charm too, don't know why I didn't think of working from the ASCII code but that saved a tremendous amount of bytes as well. \$\endgroup\$ Apr 13, 2017 at 1:59
  • 1
    \$\begingroup\$ v=(map((-51+).fromEnum)"95 ... 5"!!) saves two parenthesis. o x|x<0=(*)|0<1=(+) saves one byte in the second guard. \$\endgroup\$
    – Laikoni
    Apr 13, 2017 at 5:37
  • 1
    \$\begingroup\$ In w is an extra space left. Also, as you only need to handle lists of length 3, you can use w[x,y,z]= as pattern matching. \$\endgroup\$
    – Laikoni
    Apr 13, 2017 at 5:38
1
\$\begingroup\$

Haskell, 92 87 bytes

x#y|x<0=(y*)|0<1=(y+)
k[x,y,z]=z#z$y#x$y
k.map([read[q]-3|q<-"95445054524413452545"]!!)

Try it online!

Based on @maple_shaft's answer, I just factorized it a bit.

Thanks to @Laikoni for 5 bytes!

\$\endgroup\$
3
  • 1
    \$\begingroup\$ 87 bytes: Try it online! \$\endgroup\$
    – Laikoni
    Apr 14, 2017 at 15:37
  • \$\begingroup\$ @Laikoni I am pretty sure the newlines count \$\endgroup\$
    – BlackCap
    Apr 17, 2017 at 16:58
  • \$\begingroup\$ I didn't count the two bytes for f= because anonymous functions are allowed as submission. They are only required to make the tio example work. \$\endgroup\$
    – Laikoni
    Apr 17, 2017 at 19:11
0
\$\begingroup\$

C, 171 161 bytes

#include<stdio.h>
r,z[3],*a=z,i;f(x){i?x<0?r*=x:(r+=x):(r=x);}main(){scanf("%d %d %d",a,a+1,a+2);for(;i++<3;f("05445054524413452545"[*a++]-51));printf("%d",r);}
\$\endgroup\$
1
0
\$\begingroup\$

8086 machine code, 62 bytes

00000000  be 3b 01 31 c0 86 c4 ac  e8 0a 00 81 fe 3e 01 72  |.;.1.........>.r|
00000010  f4 b4 4c cd 21 bb 32 01  d0 e8 d7 73 03 c0 e0 04  |..L.!.2....s....|
00000020  c0 f8 04 e3 05 31 c9 c3  86 c4 78 03 00 e0 c3 f6  |.....1....x.....|
00000030  ec c3 21 12 d2 12 f1 1e  01 2f 12 00 00 00        |..!....../....|
0000003e

The last three bytes contain the (zero-indexed) input. Hey, you told me I could use the most convenient input format. In this case, that's hardcoding!
Output is the error code returned to the shell.

How it works:

            |   org 0x100
            |   use16
be 3b 01    |       mov si, input   ; source = input
31 c0       |       xor ax, ax      ; clear ax
86 c4       |   @@: xchg al, ah     ; swap al/ah (ah = total value)
ac          |       lodsb           ; al = *si++
e8 0a 00    |       call fn
81 fe 3e 01 |       cmp si, input+3 ; end of input?
72 f4       |       jb @b           ; repeat if not
b4 4c       |       mov ah, 0x4c    ; dos function: exit with al=error code
cd 21       |       int 0x21        ; syscall
            |
bb 32 01    |   fn: mov bx, table   ; pointer to lookup table
d0 e8       |       shr al, 1       ; divide input by 2
d7          |       xlatb           ; al = *(bx + al)
73 03       |       jnc @f          ; skip next instruction if input was odd
c0 e0 04    |       shl al, 4       ; shift low nibble to high nibble
c0 f8 04    |   @@: sar al, 4       ; shift high nibble to low nibble with sign-extension
e3 05       |       jcxz @f         ; return if cx is non-zero (only happens for the first input)
31 c9       |       xor cx, cx      ; clear cx
c3          |       ret
86 c4       |       xchg al, ah     ; swap al/ah (al = total value)
78 03       |   @@: js @f           ; multiply if negative, add if positive
00 e0       |       add al, ah      ; al = al+ah
c3          |       ret
f6 ec       |   @@: imul ah         ; ax = al*ah
c3          |       ret
21 12 d2 12 |   table db 0x21, 0x12, 0xd2, 0x12, 0xf1, 0x1e, 0x01, 0x2f, 0x12
f1 1e 01 2f |                       ; each value is stored in a 4-bit nibble
12          |
00 00 00    |   input db 3 dup(0)
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.