23
\$\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\$
  • 1
    \$\begingroup\$ So basically Salsa+Lunch+Mayo=Invincible? \$\endgroup\$ – Matthew Roh Apr 9 '17 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\$ – Level River St Apr 9 '17 at 23:21
  • 2
    \$\begingroup\$ For reference, here is an archive of the game. \$\endgroup\$ – Matthew Roh Apr 10 '17 at 8:00
  • 4
    \$\begingroup\$ Who keeps salt in the fridge? :) \$\endgroup\$ – Wossname Apr 10 '17 at 12:26
  • 3
    \$\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 '17 at 20:44

14 Answers 14

13
\$\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\$
  • \$\begingroup\$ How does the "base 250 compressed number" part work? \$\endgroup\$ – ckjbgames Apr 10 '17 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\$ – Jonathan Allan Apr 10 '17 at 15:26
  • \$\begingroup\$ Oh, a string literal. \$\endgroup\$ – ckjbgames Apr 10 '17 at 15:36
  • \$\begingroup\$ This was my approach until I realized "-3" doesn't mean "-3" when evaluating as 05AB1E code. \$\endgroup\$ – Magic Octopus Urn Apr 10 '17 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
    \$\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 '17 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\$

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\$
  • 1
    \$\begingroup\$ Here is an improved version, 118 bytes \$\endgroup\$ – Mr. Xcoder Apr 10 '17 at 12:27
  • 2
    \$\begingroup\$ 5445054524413452545 then subtract 3 may save you tons of bytes. \$\endgroup\$ – Magic Octopus Urn Apr 10 '17 at 17:54
  • 1
    \$\begingroup\$ n=[n+i,n*i][i<0] inside the loop saves you 3 bytes \$\endgroup\$ – math junkie Apr 11 '17 at 14:47
5
\$\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\$
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\$
  • \$\begingroup\$ Nice + * trick! \$\endgroup\$ – Esolanging Fruit Apr 17 '17 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\$
  • \$\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\$ – ETHproductions Apr 11 '17 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\$ – Bald Bantha Apr 11 '17 at 0:38
  • \$\begingroup\$ You've got an extra ) after +b, I believe \$\endgroup\$ – ETHproductions Apr 11 '17 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\$
  • 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 '17 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 '17 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\$ – maple_shaft Apr 13 '17 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 '17 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 '17 at 5:38
0
\$\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\$
  • 1
    \$\begingroup\$ 87 bytes: Try it online! \$\endgroup\$ – Laikoni Apr 14 '17 at 15:37
  • \$\begingroup\$ @Laikoni I am pretty sure the newlines count \$\endgroup\$ – BlackCap Apr 17 '17 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 '17 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\$
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, privacy policy and cookie policy

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