Skip to content

Commit 1b6ecdb

Browse files
ovidiu141SleeplessByte
authored andcommitted
Port Yacht exercise (#799)
* Port Yacht exercise * Make Yacht exercise to be unlocked by Bob
1 parent 0a89931 commit 1b6ecdb

File tree

8 files changed

+380
-0
lines changed

8 files changed

+380
-0
lines changed

config.json

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1442,6 +1442,19 @@
14421442
"searching",
14431443
"text_formatting"
14441444
]
1445+
},
1446+
{
1447+
"slug": "yacht",
1448+
"uuid": "77d0ab59-3824-4a79-9db3-e0bb35c6fc63",
1449+
"core": false,
1450+
"unlocked_by": "bob",
1451+
"difficulty": 4,
1452+
"topics": [
1453+
"arrays",
1454+
"conditionals",
1455+
"filtering",
1456+
"games"
1457+
]
14451458
}
14461459
]
14471460
}

exercises/yacht/.eslintrc

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
{
2+
"root": true,
3+
"parser": "babel-eslint",
4+
"parserOptions": {
5+
"ecmaVersion": 7,
6+
"sourceType": "module"
7+
},
8+
"env": {
9+
"es6": true,
10+
"node": true,
11+
"jest": true
12+
},
13+
"extends": [
14+
"eslint:recommended",
15+
"plugin:import/errors",
16+
"plugin:import/warnings"
17+
],
18+
"rules": {
19+
"linebreak-style": "off",
20+
21+
"import/extensions": "off",
22+
"import/no-default-export": "off",
23+
"import/no-unresolved": "off",
24+
"import/prefer-default-export": "off"
25+
}
26+
}

exercises/yacht/README.md

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
# Score a single throw of dice in *Yacht*
2+
3+
The dice game [Yacht](https://en.wikipedia.org/wiki/Yacht_(dice_game)) is from
4+
the same family as Poker Dice, Generala and particularly Yahtzee, of which it
5+
is a precursor. In the game, five dice are rolled and the result can be entered
6+
in any of twelve categories. The score of a throw of the dice depends on
7+
category chosen.
8+
9+
## Scores in Yacht
10+
11+
| Category | Score | Description | Example |
12+
| -------- | ----- | ----------- | ------- |
13+
| Ones | 1 × number of ones | Any combination | 1 1 1 4 5 scores 3 |
14+
| Twos | 2 × number of twos | Any combination | 2 2 3 4 5 scores 4 |
15+
| Threes | 3 × number of threes | Any combination | 3 3 3 3 3 scores 15 |
16+
| Fours | 4 × number of fours | Any combination | 1 2 3 3 5 scores 0 |
17+
| Fives | 5 × number of fives| Any combination | 5 1 5 2 5 scores 15 |
18+
| Sixes | 6 × number of sixes | Any combination | 2 3 4 5 6 scores 6 |
19+
| Full House | Total of the dice | Three of one number and two of another | 3 3 3 5 5 scores 19 |
20+
| Four of a Kind | Total of the four dice | At least four dice showing the same face | 4 4 4 4 6 scores 16 |
21+
| Little Straight | 30 points | 1-2-3-4-5 | 1 2 3 4 5 scores 30 |
22+
| Big Straight | 30 points | 2-3-4-5-6 | 2 3 4 5 6 scores 30 |
23+
| Choice | Sum of the dice | Any combination | 2 3 3 4 6 scores 18 |
24+
| Yacht | 50 points | All five dice showing the same face | 4 4 4 4 4 scores 50 |
25+
26+
If the dice do not satisfy the requirements of a category, the score is zero.
27+
If, for example, *Four Of A Kind* is entered in the *Yacht* category, zero
28+
points are scored. A *Yacht* scores zero if entered in the *Full House* category.
29+
30+
## Task
31+
Given a list of values for five dice and a category, your solution should return
32+
the score of the dice for that category. If the dice do not satisfy the requirements
33+
of the category your solution should return 0. You can assume that five values
34+
will always be presented, and the value of each will be between one and six
35+
inclusively. You should not assume that the dice are ordered.
36+
37+
## Setup
38+
39+
Go through the setup instructions for Javascript to install the necessary
40+
dependencies:
41+
42+
[https://exercism.io/tracks/javascript/installation](https://exercism.io/tracks/javascript/installation)
43+
44+
## Requirements
45+
46+
Install assignment dependencies:
47+
48+
```bash
49+
$ npm install
50+
```
51+
52+
## Making the test suite pass
53+
54+
Execute the tests with:
55+
56+
```bash
57+
$ npm test
58+
```
59+
60+
In the test suites all tests but the first have been skipped.
61+
62+
Once you get a test passing, you can enable the next one by changing `xtest` to
63+
`test`.
64+
65+
## Source
66+
67+
James Kilfiger, using wikipedia [https://en.wikipedia.org/wiki/Yacht_(dice_game)](https://en.wikipedia.org/wiki/Yacht_(dice_game))
68+
69+
## Submitting Incomplete Solutions
70+
71+
It's possible to submit an incomplete solution so you can see how others have
72+
completed the exercise.

exercises/yacht/babel.config.js

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
module.exports = {
2+
presets: [
3+
[
4+
'@babel/env',
5+
{
6+
targets: {
7+
node: 'current',
8+
},
9+
useBuiltIns: false,
10+
},
11+
12+
],
13+
],
14+
};

exercises/yacht/example.js

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
const getScoreForTheYachtCategory = dices => {
2+
const isYacht = new Set(dices).size === 1;
3+
return isYacht ? 50 : 0;
4+
};
5+
6+
const mapDicesToCounterArray = dices => {
7+
let counterArray = [0, 0, 0, 0, 0, 0];
8+
for (let item of dices) {
9+
counterArray[item - 1]++;
10+
}
11+
return counterArray;
12+
};
13+
14+
const getNoOfAppearances = (dices, diceValue) => {
15+
return dices.filter(value => value === diceValue).length;
16+
};
17+
18+
const getSumOfDices = dices => {
19+
return dices.reduce((a, b) => a + b, 0);
20+
};
21+
22+
const getScoreForTheFourOfAKindCategory = dices => {
23+
const counterArray = mapDicesToCounterArray(dices);
24+
for (let i = 0; i < counterArray.length; i++) {
25+
if (counterArray[i] >= 4) {
26+
return 4 * (i + 1);
27+
}
28+
}
29+
return 0;
30+
};
31+
32+
const getScoreForTheLittleStraightCategory = dices => {
33+
const counterArray = mapDicesToCounterArray(dices);
34+
const isLittleStraight = arrayIsFilledWithValue(counterArray, 0, counterArray.length - 1, 1);
35+
return isLittleStraight ? 30 : 0;
36+
};
37+
38+
const getScoreForTheBigStraightCategory = dices => {
39+
const counterArray = mapDicesToCounterArray(dices);
40+
const isBigStraight = arrayIsFilledWithValue(counterArray, 1, counterArray.length, 1);
41+
return isBigStraight ? 30 : 0;
42+
};
43+
44+
const arrayIsFilledWithValue = (array, startPos, endPos, value) => {
45+
for (let i = startPos; i < endPos; i++) {
46+
if (array[i] != value) {
47+
return false;
48+
}
49+
}
50+
return true;
51+
};
52+
53+
const getScoreForTheFullHouseCategory = dices => {
54+
const counterArray = mapDicesToCounterArray(dices);
55+
let hasTwoOfAKind = false;
56+
let hasThreeOfAKind = false;
57+
for (let item of counterArray) {
58+
if (item === 2) {
59+
hasTwoOfAKind = true;
60+
} else if (item === 3) {
61+
hasThreeOfAKind = true;
62+
}
63+
}
64+
65+
return hasTwoOfAKind && hasThreeOfAKind ? getSumOfDices(dices) : 0;
66+
};
67+
68+
export const score = (dices, category) => {
69+
switch (category) {
70+
case 'yacht':
71+
return getScoreForTheYachtCategory(dices);
72+
case 'ones':
73+
return getNoOfAppearances(dices, 1);
74+
case 'twos':
75+
return 2 * getNoOfAppearances(dices, 2);
76+
case 'threes':
77+
return 3 * getNoOfAppearances(dices, 3);
78+
case 'fours':
79+
return 4 * getNoOfAppearances(dices, 4);
80+
case 'fives':
81+
return 5 * getNoOfAppearances(dices, 5);
82+
case 'sixes':
83+
return 6 * getNoOfAppearances(dices, 6);
84+
case 'full house':
85+
return getScoreForTheFullHouseCategory(dices);
86+
case 'four of a kind':
87+
return getScoreForTheFourOfAKindCategory(dices);
88+
case 'little straight':
89+
return getScoreForTheLittleStraightCategory(dices);
90+
case 'big straight':
91+
return getScoreForTheBigStraightCategory(dices);
92+
case 'choice':
93+
return getSumOfDices(dices);
94+
}
95+
return 0;
96+
};

exercises/yacht/package.json

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
{
2+
"name": "exercism-javascript",
3+
"version":"1.2.0",
4+
"description": "Exercism exercises in Javascript.",
5+
"author": "Katrina Owen",
6+
"private": true,
7+
"repository": {
8+
"type": "git",
9+
"url": "https://github.com/exercism/javascript"
10+
},
11+
"devDependencies": {
12+
"@babel/cli": "^7.5.5",
13+
"@babel/core": "^7.5.5",
14+
"@babel/preset-env": "^7.5.5",
15+
"@types/jest": "^24.0.16",
16+
"@types/node": "^12.6.8",
17+
"babel-eslint": "^10.0.2",
18+
"babel-jest": "^24.8.0",
19+
"eslint": "^6.1.0",
20+
"eslint-plugin-import": "^2.18.2",
21+
"jest": "^24.8.0"
22+
},
23+
"jest": {
24+
"modulePathIgnorePatterns": [
25+
"package.json"
26+
]
27+
},
28+
"scripts": {
29+
"test": "jest --no-cache ./*",
30+
"watch": "jest --no-cache --watch ./*",
31+
"lint": "eslint .",
32+
"lint-test": "eslint . && jest --no-cache ./* "
33+
},
34+
"license": "MIT",
35+
"dependencies": {}
36+
}

exercises/yacht/yacht.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
//
2+
// This is only a SKELETON file for the 'Yacht' exercise. It's been provided as a
3+
// convenience to get you started writing code faster.
4+
//
5+
6+
export const score = () => {
7+
throw new Error("Remove this statement and implement this function");
8+
};

exercises/yacht/yacht.spec.js

Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
import { score } from './yacht'
2+
3+
describe('Yacht', () => {
4+
test('Yacht', () => {
5+
expect(score([5, 5, 5, 5, 5], 'yacht')).toEqual(50);
6+
});
7+
8+
xtest('Not Yacht', () => {
9+
expect(score([1, 3, 3, 2, 5], 'yacht')).toEqual(0);
10+
});
11+
12+
xtest('Ones', () => {
13+
expect(score([1, 1, 1, 3, 5], 'ones')).toEqual(3);
14+
});
15+
16+
xtest('Ones, out of order', () => {
17+
expect(score([3, 1, 1, 5, 1], 'ones')).toEqual(3);
18+
});
19+
20+
xtest('No ones', () => {
21+
expect(score([4, 3, 6, 5, 5], 'ones')).toEqual(0);
22+
});
23+
24+
xtest('Twos', () => {
25+
expect(score([2, 3, 4, 5, 6], 'twos')).toEqual(2);
26+
});
27+
28+
xtest('Fours', () => {
29+
expect(score([1, 4, 1, 4, 1], 'fours')).toEqual(8);
30+
});
31+
32+
xtest('Yacht counted as threes', () => {
33+
expect(score([3, 3, 3, 3, 3], 'threes')).toEqual(15);
34+
});
35+
36+
xtest('Yacht of 3s counted as fives', () => {
37+
expect(score([3, 3, 3, 3, 3], 'fives')).toEqual(0);
38+
});
39+
40+
xtest('Sixes', () => {
41+
expect(score([2, 3, 4, 5, 6], 'sixes')).toEqual(6);
42+
});
43+
44+
xtest('Full house two small, three big', () => {
45+
expect(score([2, 2, 4, 4, 4], 'full house')).toEqual(16);
46+
});
47+
48+
xtest('Full house three small, two big', () => {
49+
expect(score([5, 3, 3, 5, 3], 'full house')).toEqual(19);
50+
});
51+
52+
xtest('Two pair is not a full house', () => {
53+
expect(score([2, 2, 4, 4, 5], 'full house')).toEqual(0);
54+
});
55+
56+
xtest('Four of a kind is not a full house', () => {
57+
expect(score([1, 4, 4, 4, 4], 'full house')).toEqual(0);
58+
});
59+
60+
xtest('Yacht is not a full house', () => {
61+
expect(score([2, 2, 2, 2, 2], 'full house')).toEqual(0);
62+
});
63+
64+
xtest('Four of a Kind', () => {
65+
expect(score([6, 6, 4, 6, 6], 'four of a kind')).toEqual(24);
66+
});
67+
68+
xtest('Yacht can be scored as Four of a Kind', () => {
69+
expect(score([3, 3, 3, 3, 3], 'four of a kind')).toEqual(12);
70+
});
71+
72+
xtest('Full house is not Four of a Kind', () => {
73+
expect(score([3, 3, 3, 5, 5], 'four of a kind')).toEqual(0);
74+
});
75+
76+
xtest('Little Straight', () => {
77+
expect(score([3, 5, 4, 1, 2], 'little straight')).toEqual(30);
78+
});
79+
80+
xtest('Little Straight as Big Straight', () => {
81+
expect(score([1, 2, 3, 4, 5], 'big straight')).toEqual(0);
82+
});
83+
84+
xtest('Four in order but not a little straight', () => {
85+
expect(score([1, 1, 2, 3, 4], 'little straight')).toEqual(0);
86+
});
87+
88+
xtest('No pairs but not a little straight', () => {
89+
expect(score([1, 2, 3, 4, 6], 'little straight')).toEqual(0);
90+
});
91+
92+
xtest('Minimum is 1, maximum is 5, but not a little straight', () => {
93+
expect(score([1, 1, 3, 4, 5], 'little straight')).toEqual(0);
94+
});
95+
96+
xtest('Big Straight', () => {
97+
expect(score([4, 6, 2, 5, 3], 'big straight')).toEqual(30);
98+
});
99+
100+
xtest('Big Straight as little straight', () => {
101+
expect(score([6, 5, 4, 3, 2], 'little straight')).toEqual(0);
102+
});
103+
104+
xtest('No pairs but not a big straight', () => {
105+
expect(score([6, 5, 4, 3, 1], 'big straight')).toEqual(0);
106+
});
107+
108+
xtest('Choice', () => {
109+
expect(score([3, 3, 5, 6, 6], 'choice')).toEqual(23);
110+
});
111+
112+
xtest('Yacht as choice', () => {
113+
expect(score([2, 2, 2, 2, 2], 'choice')).toEqual(10);
114+
});
115+
});

0 commit comments

Comments
 (0)