```
using System;
using System.Linq;
public enum YachtCategory { Ones, Twos, Threes, Fours, Fives, Sixes, FullHouse, FourOfAKind, LittleStraight, BigStraight, Choice, Yacht }
public static class YachtGame
{
public static int Score(int[] dice, YachtCategory category) =>
category switch
{
YachtCategory.Ones => SingleDiceScore(dice, 1),
YachtCategory.Twos => SingleDiceScore(dice, 2),
YachtCategory.Threes => SingleDiceScore(dice, 3),
YachtCategory.Fours => SingleDiceScore(dice, 4),
YachtCategory.Fives => SingleDiceScore(dice, 5),
YachtCategory.Sixes => SingleDiceScore(dice, 6),
YachtCategory.FullHouse => FullHouseScore(dice),
YachtCategory.FourOfAKind => FourOfAKindScore(dice),
YachtCategory.LittleStraight => LittleStraightScore(dice),
YachtCategory.BigStraight => BigStraightScore(dice),
YachtCategory.Choice => ChoiceScore(dice),
YachtCategory.Yacht => YachtScore(dice),
_ => throw new ArgumentOutOfRangeException(nameof(category), "Invalid category")
};
private static int SingleDiceScore(int[] dice, int targetDie) =>
dice.Where(die => die == targetDie).Sum();
private static int FullHouseScore(int[] dice) =>
dice.Any(die => dice.Count(other => other == die) == 2) &&
dice.Any(die => dice.Count(other => other == die) == 3) ? dice.Sum() : 0;
private static int FourOfAKindScore(int[] dice) =>
dice.FirstOrDefault(die => dice.Count(other => other == die) >= 4, 0) * 4;
private static int LittleStraightScore(int[] dice) =>
dice.Distinct().Count() == 5 && !dice.Contains(6) ? 30 : 0;
private static int BigStraightScore(int[] dice) =>
dice.Distinct().Count() == 5 && !dice.Contains(1) ? 30 : 0;
private static int YachtScore(int[] dice) =>
dice.Distinct().Count() == 1 ? 50 : 0;
private static int ChoiceScore(int[] dice) => dice.Sum();
}
```

### Single dice

The score for the `Ones`

/`Twos`

/`Threes`

/`Fours`

/`Fives`

/`Sixes`

categories all have the same logic: sum the number of occurences of a specific dice value.

The implementation is a direct translation:

```
private static int SingleDiceScore(int[] dice, int targetDie) =>
dice.Where(die => die == targetDie).Sum();
```

### Full house

A full house category applies when one dice occurs twice, and another dice occurs thrice. The score then is the sum of the dice.

To figure out if one dice occurs twice, we can use `Any()`

and within its lambda check if the count of the dice equal two.
We then do the same thing for the dice occuring thrice.
If both conditions are true, we sum the dice using `Sum()`

:

```
private static int FullHouseScore(int[] dice) =>
dice.Any(die => dice.Count(other => other == die) == 2) &&
dice.Any(die => dice.Count(other => other == die) == 3) ? dice.Sum() : 0;
```

### Four of a kind

The four of kind category applies when one dice occurs at least four times. The score is then the value of that dice multiplied by four.

To figure out if a dice occurs at least four times, we can use `Count()`

: `dice.Count(other => other == die) >= 4`

Then, we'll try to find that dice using `FirstOrDefault()`

with the condition being the above-mentioned count check.
Note that we pass a default value of zero to the `FirstOrDefault()`

method, which means that it will return either: the dice occuring at least four times, or zero if it could not be found.

Finally, we multiply the dice value we found by 4:

```
private static int FourOfAKindScore(int[] dice) =>
dice.FirstOrDefault(die => dice.Count(other => other == die) >= 4, 0) * 4;
```

Note: as `0 * 4 == 0`

, we've also correctly handled the case where there is no dice occuring at least four times.

### Little straight

Dice can be scores as a little straight (30 point) if the dice are 1-2-3-4-5. One way to approach this is to check that:

- All five dice are different: we can check the number of dice by first getting the unique dice using
`Distinct()`

and then counting those dice using`Count()`

. - None of the dice is
`6`

: we use`Contains()`

to ensure that`6`

is not one of the dice

```
private static int LittleStraightScore(int[] dice) =>
dice.Distinct().Count() == 5 && !dice.Contains(6) ? 30 : 0;
```

### Big straight

Dice can be scores as a big straight (30 point) if the dice are 2-3-4-5-6. One way to approach this is to check that:

- All five dice are different: we can check the number of dice by first getting the unique dice using
`Distinct()`

and then counting those dice using`Count()`

. - None of the dice is
`1`

: we use`Contains()`

to ensure that`1`

is not one of the dice

```
private static int BigStraightScore(int[] dice) =>
dice.Distinct().Count() == 5 && !dice.Contains(1) ? 30 : 0;
```

### Yacht

Dice can be scored as a yacht (50 points) if all five dice have the same face.
We can check this by first getting the unique dice using `Distinct()`

and then counting those dice using `Count()`

.
This gives us the number of unique dice, which must be one if the dice represent a yacht score.

```
private static int YachtScore(int[] dice) =>
dice.Distinct().Count() == 1 ? 50 : 0;
```

### Choice

This is the simplest category: the score is the sum of all dice.
We can use `Sum()`

for that:

```
private static int ChoiceScore(int[] dice) => dice.Sum();
```

### Putting it all together

The final step is to call the above methods for the right category, which we can do using a `switch`

expression and an expression-bodied member:

```
public static int Score(int[] dice, YachtCategory category) =>
category switch
{
YachtCategory.Ones => SingleDiceScore(dice, 1),
YachtCategory.Twos => SingleDiceScore(dice, 2),
YachtCategory.Threes => SingleDiceScore(dice, 3),
YachtCategory.Fours => SingleDiceScore(dice, 4),
YachtCategory.Fives => SingleDiceScore(dice, 5),
YachtCategory.Sixes => SingleDiceScore(dice, 6),
YachtCategory.FullHouse => FullHouseScore(dice),
YachtCategory.FourOfAKind => FourOfAKindScore(dice),
YachtCategory.LittleStraight => LittleStraightScore(dice),
YachtCategory.BigStraight => BigStraightScore(dice),
YachtCategory.Choice => ChoiceScore(dice),
YachtCategory.Yacht => YachtScore(dice),
_ => throw new ArgumentOutOfRangeException(nameof(category), "Invalid category")
};
```