loading...

Daily Challenge #97 - Greed is Good

thepracticaldev profile image dev.to staff ・1 min read

Greed is a dice game played with five six-sided dice. Your mission, should you choose to accept it, is to score a throw according to these rules. You will always be given an array with five six-sided dice values.

 Three 1's => 1000 points
 Three 6's =>  600 points
 Three 5's =>  500 points
 Three 4's =>  400 points
 Three 3's =>  300 points
 Three 2's =>  200 points
 One   1   =>  100 points
 One   5   =>   50 point

A single die can only be counted once in each roll. For example, a "5" can only count as part of a triplet (contributing to the 500 points) or as a single 50 points, but not both in the same roll.

Example scoring

Alt Text

In some languages, it is possible to mutate the input to the function. This is something that you should never do. If you mutate the input, you will not be able to pass all the tests.


This challenge comes from JulianNicholls on CodeWars, who has licensed redistribution of this challenge under the 2-Clause BSD License!

Want to propose a challenge idea for a future post? Email yo+challenge@dev.to with your suggestions!

Discussion

pic
Editor guide
Collapse
juliannicholls profile image
Julian Nicholls

Hi, Julian here!

There are two subtleties that catch out a great deal of the people who try this on Codewars.

The first is mentioned in this article, don't mutate the input.

The second is shown up by this combination: 3 3 3 3 2
That should score 300, but many people end up incorrectly giving 0 as the score.

Collapse
dwilmer profile image
Daan Wilmer

What do you mean with "Don't mutate the input"? The variable that is given isn't changed, right?

Collapse
juliannicholls profile image
Julian Nicholls

In some languages on Codewars (Python is the problem here, I think) it is possible to mutate the array that is passed as input. That will guarantee that the test will fail.

Generally it is not good to mutate the input to a function, unless that is the expected behaviour.

Collapse
qm3ster profile image
Mihail Malo

Why do they give 0?!

Collapse
juliannicholls profile image
Julian Nicholls

The problem comes when there aren't exactly three of a number.

Thread Thread
qm3ster profile image
Mihail Malo

I guess that's no more contrived than the solution that would give 600 so that's okay.

Collapse
erezwanderman profile image
erezwanderman

Javascript!

const score = rolls => {
  const rollsOfNum = [1, 2, 3, 4, 5, 6].reduce((p, c) => Object.assign(p, {[c]: rolls.filter(x => x === c).length}), {})
  return (
    (Math.floor(rollsOfNum[1] / 3)) * 1000 +
    (Math.floor(rollsOfNum[6] / 3)) * 600 +
    (Math.floor(rollsOfNum[5] / 3)) * 500 +
    (Math.floor(rollsOfNum[4] / 3)) * 400 +
    (Math.floor(rollsOfNum[3] / 3)) * 300 +
    (Math.floor(rollsOfNum[2] / 3)) * 200 +
    (rollsOfNum[1] % 3) * 100 +
    (rollsOfNum[5] % 3) * 50
  );
};

const testRolls = [
  [5, 1, 3, 4, 1],
  [1, 1, 1, 3, 1],
  [2, 4, 4, 5, 4],
  [1, 1, 1, 1, 1, 1, 1, 1, 1],
  [3, 3, 3, 3, 2],
];
for (const testRoll of testRolls) {
  console.log(testRoll + ': ' + score(testRoll));
}
Collapse
citizen428 profile image
Michael Kohl

F#, nothing fancy in this solution:

module DailyChallenge

let private scoreSpecial number count points =
    if count >= 3 then points * 10 + (count - 3) * points
    else count * points

let private score number count =
    match number with
    | 1 -> scoreSpecial number count 100
    | 5 -> scoreSpecial number count 50
    | 2
    | 3
    | 4
    | 6 as n ->
        if count >= 3 then n * 100
        else 0
    | x -> x |> sprintf "Invalid number %d, must be 1-6" |> failwith

let scoreGreed (dice : int list) : int =
    dice
    |> List.groupBy id
    |> List.fold (fun result (n, ns) -> result + score n ns.Length) 0

Added slight more tests than usual, since there are a few subtleties in the scoring:

module DailyChallengeTests

open FsUnit.Xunit
open Xunit
open DailyChallenge

[<Fact>]
let ``score 1 five and 2 ones``() =
    scoreGreed [ 5; 1; 3; 4; 1 ] |> should equal 250

[<Fact>]
let ``score 4 ones and 1 three``() =
    scoreGreed [ 1; 1; 1; 3; 1 ] |> should equal 1100

[<Fact>]
let ``score 3 fours and 1 five``() =
    scoreGreed [ 2; 4; 4; 5; 4 ] |> should equal 450

[<Fact>]
let ``score 5 ones as one triple and 2 single values``() =
    scoreGreed [ 1; 1; 1; 1; 1 ] |> should equal 1200

[<Fact>]
let ``score 5 fives as one triple and 2 single values``() =
    scoreGreed [ 5; 5; 5; 5; 5 ] |> should equal 600

[<Fact>]
let ``score 3 twos as 2 thress``() =
    scoreGreed [ 2; 2; 2; 3; 3 ] |> should equal 200

[<Fact>]
let ``score 5 twos as a triple``() =
    scoreGreed [ 2; 2; 2; 2; 2 ] |> should equal 200

[<Fact>]
let ``score 4 threes as a triple``() =
    scoreGreed [ 3; 3; 3; 3; 2 ] |> should equal 300