Calculate the points in a "sjoelen"-game

31

2

Okay, so yesterday was 2nd Christmas day and my (grand)parents and me had a game of "sjoelen", as it is called in the Netherlands. The inner programmer came up in me, but just when I had the answer, I lost it. I want you to remake it.

The rules:

You have a wooden plank, a sjoelbak, with 4 boxes, each with their own number. When a schijf (A puck-like object) goes in one of the boxes you get the points above that box.

A _sjoelbak_ with _schijven_
When there is a schijf in all 4 of the boxes, you don't get 10 but you get 20 points.

Example:

From left to right: 3 5 4 3
Each box has at least 3 schijven (Plural of schijf) so that is 20 * 3 = 60 points.

Resulting values: 0 2 1 0
0*2 + 2*3 + 1*4 + 0*1 = 10 points.

Which makes a total of 60+10 = 70 points.

The input:
The amount of schijven from left to right, ie "4 5 4 5", [4,5,4,5], "4\n5\n4\n5", whatever you like.

The output:
The amount of points, ie 84, as output, variable, return or on top of the stack, whatever you like.

As in each and every code golf, you can not use external scripts and the code with the least bytes wins.

PS: As you may have already noticed, I'm Dutch. Feel free to edit possible grammar mistakes.

Charlie

Posted 2014-12-27T09:36:12.457

Reputation: 691

Does output have to be stdout or can it be a function return or the remaining item left on the stack (for a stack based language)? – globby – 2014-12-28T06:36:16.387

@globby Can be everything – Charlie – 2014-12-28T09:28:04.790

I think sjoelen is leuk! – Mark Knol – 2014-12-30T19:58:23.327

1Is there a limit on the number of schijf in each box? – The_Basset_Hound – 2015-08-25T19:23:49.567

@BassetHound You get 30 schijven per round, so 30 in the 4 equals 120 points. It's possible, but not the best score (7 in all = 140, + 2 in 4 = 148) – Charlie – 2015-08-26T05:43:47.600

Answers

8

CJam, 23 21 20 bytes

q~_$0=f+1m>{X):X*+}*

I might be able to golf a couple of bytes off this.

Input is like

[3 5 4 3]

Output is the score

70

How it works

q~                         "Read the input and evaluate into an array";
  _$0=                     "Copy the array, sort it and get the minimum number";
                           "This minimum is the number of common schijven";
      f+                   "Increment each of the schijven by the common schijven number"; 
        1m>                "Take 1 element from the end of the array and put";
                           "it in the beginning";
           {      }*       "Reduce the elements of the array based on this block";
            X):X           "Increment and update the value of X (initially 1)";
                *          "Multiply the number of schijven with X";
                 +         "Add it to current score";

Algorithm

  • Since I have right shifted the number of schijven, the score order now becomes [1 2 3 4].
  • Moreover, using the fact that 1 + 2 + 3 + 4 = 10, I simply add the minimum common schijven to each one to get the effect of bonus 10 score.
  • Now when I reduce, I get 2 elements initially on stack, the first one, which I ignore is the one with a score of 1 each, then I multiply the second one with 2 and add it to first. In the next iteration, I get the current sum and score 3 schijven. And so on.

Try it online here

Optimizer

Posted 2014-12-27T09:36:12.457

Reputation: 25 836

Least bytes (so far), accepted. Thanks for the explanation. – Charlie – 2014-12-27T11:09:30.347

@Charlie Why do you accept an answer so quickly? You better wait 1-2 weeks before accepting an answer. – ProgramFOX – 2014-12-27T11:27:59.427

8

APL (Dyalog Classic), 16 13 12 bytes

-3 thanks to @Adám

(+/+\)1⌽⌽+⌊/

Try it online!

⌽+⌊/ reverse(arg) + min(arg)

1⌽ rotate 1 to the left

+\ partial sums

+/ sum

ngn

Posted 2014-12-27T09:36:12.457

Reputation: 11 449

8

Piet, 240 (30*8) codels, 138 containing actual code

Codel size 10, for better visibility

Piet: sjoelen point count

Test examples:

D:\codegolf\npiet-1.3a-win32>npiet sjoelen_point_count_cs10.png
? 3
? 5
? 4
? 3
70
D:\codegolf\npiet-1.3a-win32>npiet sjoelen_point_count_cs10.png
? 4
? 5
? 4
? 5
84

Flow display:

Using my own shorthand for easier handling and compact display. It shows the general program flow, not the exact locations of the codels.

NOP ADD DIV GRT DUP INC END
 0   +   /   >   =   c   ~
PSH SUB MOD PTR ROL OUN
 X   -   %   #   @   N
POP MUL NOT SWI INN OUC
 ?   *   !   $   n   C

1X!nnnn=5X2X@=5X2X@=5X2X@=5X1X@**
       0                        *
       0       @+5X1X@1X-4X1X@  !
       0       -             0  !
       0       X1!X1X6+*==X40000#  <--pointer if top of stack=1 (all boxes full,
       0                     0  2      add 20 points, decrement count for all boxes)
       0000-X1@X1X2-X1@X1X3-X1  X  |  pointer if top of stack=0 (not all boxes full,
                                *  V   add 2a+3b+4c+d)
           ~N++++*X4@X2X3*X3@X1X2

Full explanation:

      (score=0)  a   b   c   d
      1 PSH NOT INN INN INN INN

      ..... sort and duplicate the numbers .....
**1** DUP 5 PSH 2 PSH ROL DUP 5 PSH 2 PSH ROL DUP 5 PSH 2 PSH ROL DUP 5 PSH 1 PSH ROL

      ( a*b*c*d ) (convert to boolean) 1 if all boxes are full, 0 if at least one box is empty
      MUL MUL MUL NOT NOT

      change direction if 1 (**2**)
      go straight ahead if 0 (**3**)
      PTR

      ( compress 20=4*4+4 )       (0-1=-1/ neg. roll) score+20
**2** 4 PSH DUP DUP MUL ADD 6 PSH 1 PSH NOT 1 PSH SUB ROL ADD

      (put score back to bottom of stack) ... a=a-1, b=b-1, c=c-1, d=d-1 ...
      5 PSH 1 PSH ROL 1 PSH SUB 4 PSH 1 PSH ROL 1 PSH SUB 3 PSH
      1 PSH ROL 1 PSH SUB 2 PSH 1 PSH ROL 1 PSH SUB

      loop to **1**

      (   a*2   )               (   b*3   )               (  c*4  )
**3** 2 PSH MUL 2 PSH 1 PSH ROL 3 PSH MUL 3 PSH 2 PSH ROL 4 PSH MUL

      +2a +3b +d +score
      ADD ADD ADD ADD

      output score
      OUN

Save the image and try it out in this online Piet interpreter:

PietDev online Piet interpreter

M L

Posted 2014-12-27T09:36:12.457

Reputation: 2 865

A Piet answer ^.^ – The_Basset_Hound – 2015-08-24T23:57:59.530

Of course! I try to add Piet answers whenever manageable ;) – M L – 2015-08-25T09:56:11.180

7

R, 41 40 chars

b=min(a<-scan());sum(5*b+(a-b)*c(2:4,1))

Usage:

> b=min(a<-scan());sum(5*b+(a-b)*c(2:4,1))
1: 4 5 4 5
5: 
Read 4 items
[1] 84
> b=min(a<-scan());sum(5*b+(a-b)*c(2:4,1))
1: 3 5 4 3
5: 
Read 4 items
[1] 70

In the last example, a is vector 3 5 4 3, a-b is 0 2 1 0, which we multiply with vector 2 3 4 1 thus giving 0 6 4 0 which we add with 5*b giving 15 21 19 15 (5*b being recycled for each member of the added vector, hence effectively adding 4*5*b), which we finally sum, thus giving 70.

plannapus

Posted 2014-12-27T09:36:12.457

Reputation: 8 610

40 bytes: b=min(a<-scan());sum(5*b+(a-b)*c(2:4,1)) – Alex A. – 2015-06-17T02:47:51.657

7

Mathematica, 38 32 23 20 bytes

(#+Min@#).{2,3,4,1}&

(With help from swish)

Use by tacking the input on to the end:

(#+Min@#).{2,3,4,1}&@{3,5,4,3}

70

Alternate (36 bytes):

20*Min@#+Total[(#-Min@#)*{2,3,4,1}]&

kukac67

Posted 2014-12-27T09:36:12.457

Reputation: 2 159

Tr[(# + Min@#) {2, 3, 4, 1}] & – swish – 2014-12-27T16:14:10.323

@swish So clever! – kukac67 – 2014-12-27T16:18:53.297

1That's the whole function. You don't need to add 20*Min@#, you can get rid of it by replacing minus with plus, because conveniently 2+3+4+1==10. – swish – 2014-12-27T16:24:58.960

@swish Oh! That's even better. But I can't wrap my head around why that works? – kukac67 – 2014-12-27T16:32:53.680

Actually you can do dot product here (# + Min@#).{2, 3, 4, 1}& – swish – 2014-12-27T17:54:05.180

2@swish Well, thanks for all the help, but you should have just posted your own answer. :D – kukac67 – 2014-12-27T18:02:35.857

When ported into TI-BASIC, it's 15 bytes: sum({2,3,4,1}(Ans+min(Ans – lirtosiast – 2015-06-15T15:12:26.487

5

J, 23 22 chars

   (+/ .*&2 3 4 1@(+<./))

Example:

   test =. 3 5 4 3
   (+/ .*&2 3 4 1@(+<./)) test
70

Try it here.

(23 long explicit function definition: v=:3 :'+/+/\.3|.y+<./y')

randomra

Posted 2014-12-27T09:36:12.457

Reputation: 19 909

Why not just +/2 3 4 1*(+<./)? – swish – 2014-12-27T16:35:12.233

@swish I prefer writing complete functions although it wasn't a requirement here. Post/add it if you would like. – randomra – 2014-12-27T18:23:45.697

How about 2 3 4 1+/ .×]+<./?

– Adám – 2019-07-11T21:49:06.803

5

JavaScript (ES6), 93 47 bytes

s=(a,b,c,d)=>10*Math.min(a,b,c,d)+a*2+b*3+c*4+d

Usage: s(1, 2, 3, 4)

How it works: the function looks for the smallest number in the arguments, and multiplies that by 10 (not with 20) and adds the rest of the score. It's not necessary to multiply by 20 and substract parts from the score to continue the calculation.

Thanks to edc65 for sharing improvements!

Un-golfed:

function score(a, b, c, d) {
    return 10 * Math.min(a, b, c, d) + a * 2 + b * 3 + c * 4 + d;
}

ProgramFOX

Posted 2014-12-27T09:36:12.457

Reputation: 8 017

1Use 10 with min, no need to subtract (function s(a,b,c,d){return 10Math.min(a,b,c,d)+a2+b3+c4+d;}) – edc65 – 2014-12-27T12:32:42.660

1And in ES6: S=(a,b,c,d)=>10*Math.min(a,b,c,d)+a*2+b*3+c*4+d – edc65 – 2014-12-27T12:38:08.393

@edc65 Awesome, thanks! – ProgramFOX – 2014-12-27T13:01:12.713

5

Pyth, 15

sm*hd+@QtdhSQUQ

Input should be given comma separated on STDIN, e.g.

3,5,4,3

This uses the same trick that many other solutions have used, of adding the minimum to each element to account for the bonus. The minimum is hSQ in the above code. To account for multiplying by 2, 3, 4, and 1, I map d over the list [0,1,2,3], and multiply the (d-l)th element of the input by d+1. Thus, the -1th element is multiplied by 1, the zeroth by 2, the first by 3 and the second by 4. Then I sum.

isaacg

Posted 2014-12-27T09:36:12.457

Reputation: 39 268

4

Ostrich v0.1.0, 48 41 characters (way too long)

.$0={}/:n;{n-}%)\+1:i;{i*i):i;}%{+}*20n*+

This is simply the same as the old version below, except that instead of using @ to rotate the whole stack, )\+ (right uncons) is used instead.

Old version:

.$0={}/:n;{n-}%{}/{4@}3*1:i;]{i*i):i;}%{+}*20n*+

I have actually discovered two bugs in my very newly implemented language, annotated in the description below. (The language is currently very, very similar to Golfscript, so if you know Golfscript it should be fairly easy to read.

.$0=   get min value (for the *20 thingy)
{}/    *actually* get min value (BUG: `array number =' returns a single-element array...)
:n;    store as n
{n-}%  subtract this value from all array elements
{}/    dump array onto stack
{4@}3* rotate stack so that instead of 2 3 4 1, multipliers are 1 2 3 4
       (BUG: negative rotations don't work)
1:i;   set i (the multiplier) to 1
]{i*   multiply each array element by i
i):i;  increment i
}%     (do the previous 2 lines over each array element)
{+}*   add up all the array elements
20n*+  add 20*n (the min value we got in line 1)

Expects input as an array on STDIN, because I'm a doorknob and forgot to implement I/O in v0.1.0.

Solving an actual problem in Ostrich is nice, because it shows me exactly how much more stuff I need to add to the language :D

Doorknob

Posted 2014-12-27T09:36:12.457

Reputation: 68 138

Good luck with your language, it looks nice so far ;) – Charlie – 2014-12-28T14:01:20.837

4

Python 2, 43 bytes

lambda i:i[1]-i[3]+2*(sum(i)+i[2]+5*min(i))

Inspired by @user2487951's answer.

isaacg

Posted 2014-12-27T09:36:12.457

Reputation: 39 268

Nice algorithm! For a full program, you need input and print statements also. – user2487951 – 2014-12-30T18:06:15.230

1@user2487951 One of the allowable means of output was "return", so while this is not a full program, it is a valid answer. – isaacg – 2014-12-30T19:23:02.143

3

Haskell, 40

g l@[a,b,c,d]=2*a+3*b+4*c+d+10*minimum l

instead of removing the minimum number from the rest and adding additional 20s, this adds additional 10 for the minimum number.

proud haskeller

Posted 2014-12-27T09:36:12.457

Reputation: 5 866

Nice solution. You did mix up the order though, it should be ..4*c+d.. – None – 2015-01-01T03:38:03.903

3

Jagl Alpha 1.2 - 20 bytes

Input is in stdin in format (3 4 5 6), output is left on stack:

T~dqZ*S1 5r]%{U*}/b+

Waiting for a response from the original poster about the output format. Since input is specified as "whatever you like", I am going to assume that my input can be an array on the top of the stack. Now takes input on stdin.

Explanation:

T~                            Get input from stdin and evaluate
  dqZ*                      Duplicate, get minimum, and multiply that by 10
      S1 5r]                Swap (so array is on top), push range 1-5 exclusive, and rotate
            %{U*}/          Zip arrays together, and multiply each pair
                  b+P       Get the sum of that, add the common minimum, and print

globby

Posted 2014-12-27T09:36:12.457

Reputation: 1 132

First answer is accepted, edited post to make it clear – Charlie – 2014-12-28T09:31:21.063

@Optimizer point taken. Edited. – globby – 2014-12-28T15:03:46.090

3

Matlab, 27

Took me a while to understand that it is single player game. With the help of anonymous function

f=@(N)N*[2;3;4;1]+10*min(N)

which is invoked with row vector

f([3 5 4 3]) == 70
f([7 7 9 7]) == 148

zabalajka

Posted 2014-12-27T09:36:12.457

Reputation: 71

1I think it's generally accepted around these parts to drop the f= for 2 fewer bytes. The function gets stored in the ans variable instead. – BrainSteel – 2015-06-15T12:37:48.233

1[2:4,1] will shave off 2 bytes if the input is column vector. – Sanchises – 2015-06-17T12:07:43.047

2

Java, 84 bytes

int A(int[]a){int m=9;for(int i:a)m=i<m?i:m;return 10*m+a[3]+2*a[0]+3*a[1]+4*a[2];}

I have the idea this can be golfed any further, but this is it for now.

Call with A(new int[]{3,5,4,3}), output is returned as int (Because System.out.println() would double the bytes)

Ungolfed

int getScore(int[] input){
    int min=9;

    for(int x:input) {
        if(x<min){
            min=x;
        }
    }

    return 10*min + 2*input[0] + 3*input[1] + 4*input[2] + 1*input[3];
}

Charlie

Posted 2014-12-27T09:36:12.457

Reputation: 691

2

GolfScript, 22 bytes

~3,{1$>~;}%+$(11*+{+}*

Reads input from stdin, in the format [3 5 4 3]. Writes output to stdout. (If taking the input as an array on the stack is allowed, the leading ~ may be omitted for a total of 21 bytes.)

This uses a somewhat different strategy than the CJam / Pyth / etc. solutions: I first build an array with 2 copies of the first input value, 3 of the second, 4 of the third and one of the fourth. Then I sort this array, pull out the smallest element, multiply it by 11 and sum it with the other elements.

Ilmari Karonen

Posted 2014-12-27T09:36:12.457

Reputation: 19 513

2

Python 2, 51

Uninspired, but short:

l=input()
print l[0]*2+l[1]*3+l[2]*4+l[3]+10*min(l)

More pythonic:

l=input()
print sum(map(lambda x,y:x*y,l,[2,3,4,1]))+10*min(l)

user2487951

Posted 2014-12-27T09:36:12.457

Reputation: 111

If the input is [3,5,4,3], will this return 70? – Charlie – 2014-12-29T02:24:58.943

Yes, it does in both cases. And returns 84 for [4,5,4,5]. – user2487951 – 2014-12-30T18:00:52.633

2

Julia, 48 35 characters

function p(m);sum([2 3 4 1].*m)+10minimum(m);end

in compact assignment form:

p(m)=sum([2 3 4 1].*m)+10minimum(m)

Example:

julia> p([3 5 4 3])
70

M L

Posted 2014-12-27T09:36:12.457

Reputation: 2 865

2

Javascript, 97 bytes

a=prompt().split(" "),b=Math.min.apply(1,a);alert(20*b+2*(a[0]-b)+3*(a[1]-b)+4*(a[2]-b)+(a[3]-b))

SuperJedi224

Posted 2014-12-27T09:36:12.457

Reputation: 11 342

1

PowerShell for Windows, 48 47 bytes

-1 byte thanks to mazzy

$args|%{$a+=++$i%4*$_+$_}
$a+10*($args|sort)[0]

Try it online!

Veskah

Posted 2014-12-27T09:36:12.457

Reputation: 3 580

1Try it online!. Should we specify Powershell for Windows when we use the sort alias? see meta – mazzy – 2019-07-12T15:43:34.600

1

@mazzy Yeah, probably should. I just forget about that because TIO is technically on linux but uses the windows aliases

– Veskah – 2019-07-12T15:58:26.207

1

Javascript, ES6, 57

f=(a,b,c,d)=>a*b*c*d?20+f(--a,--b,--c,--d):a*2+b*3+c*4+d

I wanted to see how recursion would turn out, and while it is definitely not the shortest answer, I felt like it turned out well.

a*b*c*d: It takes the input values and finds the product of all of them, and evaluate that as a Boolean expression for an inline if statement. This will return false if one or more of the values is 0, and true for any other value.

20+f(--a,--b,--c,--d): If it returns true, the function returns 20 (for the schijven set) plus the recursive call of the function for all of the values minus one (To remove that schijven set). In this way it will recursively loop through until at least one of the boxes is empty.

a*2+b*3+c*4+d After at least one box it empty, the else part of the inline if statement will run. It just returns the points for the remaining schijven in the boxes.

Thus at the end all of the 20 point schijven sets, and the remanding points are summed up and returned from the function, producing the answer.

skycon

Posted 2014-12-27T09:36:12.457

Reputation: 199

1

Haskell 42 chars

f l=10*minimum l+sum(zipWith(*)[2,3,4,1]l)

HEGX64

Posted 2014-12-27T09:36:12.457

Reputation: 313

Code the sum expressly: f l@[a,b,c,d]=10*minimum l+2*a+3*b+4*c+d - saves 2 chars – MtnViewMark – 2015-08-25T05:02:39.633

1

HPPPL (HP Prime Programming Language), 58 57 bytes

The * between 10 and min isn’t necessary, so I removed it.

EXPORT s(m)
BEGIN
return sum([2,3,4,1].*m)+10min(m);
END;

HPPPL is the programming language for the HP Prime color graphing calculator/CAS.

Example runs:

HPPPL screen capture of sjoelen point count program

If it doesn’t have to be a program, then it’s realizable in a 40 39 bytes one-liner:

m:=[3,5,4,3];sum([2,3,4,1].*m)+10min(m)

M L

Posted 2014-12-27T09:36:12.457

Reputation: 2 865

1

Staq, 72 characters

't't't't{aii*XX}$&iia$&ia$&a+XX+XX+|{mxx}{lxX}{k>?m!l}kkk&iiqi&ii*s*t|+:

Example run:

Executing D:\codegolf\Staq\sjoelen codegolf.txt

3
5
4
3
70

Execution complete.
>

Staq has two stacks, one active, one passive. The | command switches the active stack to passive and vice versa.

Everything between curly braces defines a function, the first letter after the opening brace is the function name, the rest until the closing brace is the function itself. Overriding functions, recursion and nested functions are possible. {aii} would define a function a that would increment the top of the stack twice. Every following instance of a in the code will be replaced by ii.

Comments inside Staq prorams: & adds a zero on top of the stack, [ instructs the pointer to jump to the corresponding ] if the top of the stack is zero, x deletes the topmost value on the stack. So, comments can be written into the code in the form of &[here is a comment]x

Explanation (also executable):

'                                      &[input number]x
 t                                     &[copy top of active stack to passive stack]x
  t't't                                &[input next three numbers and copy them to the passive stack]x
       {aii*XX}                        &[define function a (increment twice, multiply the two topmost values, then delete the second value on the stack twice)]x
               $                       &[move top value to the bottom of the stack]x
                &ii                    &[put zero on top of the stack, incremment twice]x
                   a                   &[function a]x
                    $&ia$&a
                           +           &[put sum of the two topmost values on top of the stack]x
                            XX         &[delete second stack value, twice]x
                              +XX+
                                  |    &[switch active/passive stack]x
{mxx}                                  &[define function m: delete two topmost stack values]x
     {lxX}                             &[define function l: delete topmost stack value, then delete second value of remaining stack]x
          {k>?m!l}                     &[define function k: boolean top > second value? put result on top of the stack, if top>0 then execute m, if top = 0 then execute l]x
                  kkk&ii
                        q              &[put square of top value on top of the stack]x
                         i&ii
                             *         &[multiply two topmost values and put result on top of the stack]x
                              s        &[move bottom stack value to the top]x
                               *t|+
                                   :   &[output result]x

https://esolangs.org/wiki/Staq

The program uses one stack (initially active) to calculate 2a+3b+4c+d, and the second stack (initially passive) to calculate 10 times the minimum of the input values. Then both results are summed up and displayed.

M L

Posted 2014-12-27T09:36:12.457

Reputation: 2 865