Skip to content

Commit a55a442

Browse files
[F#] Zebra Puzzle
1 parent 644a306 commit a55a442

File tree

6 files changed

+248
-0
lines changed

6 files changed

+248
-0
lines changed

fsharp/ExercismFSharp.sln

+14
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,8 @@ Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "TisburyTreasureHunt", "tisb
171171
EndProject
172172
Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "Tournament", "tournament\Tournament.fsproj", "{F1946140-1C65-4641-817C-4B8751429238}"
173173
EndProject
174+
Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "ZebraPuzzle", "zebra-puzzle\ZebraPuzzle.fsproj", "{6E5DE28D-88F1-4FFF-A4ED-39D919A1CB1B}"
175+
EndProject
174176
Global
175177
GlobalSection(SolutionConfigurationPlatforms) = preSolution
176178
Debug|Any CPU = Debug|Any CPU
@@ -1189,6 +1191,18 @@ Global
11891191
{F1946140-1C65-4641-817C-4B8751429238}.Release|x64.Build.0 = Release|Any CPU
11901192
{F1946140-1C65-4641-817C-4B8751429238}.Release|x86.ActiveCfg = Release|Any CPU
11911193
{F1946140-1C65-4641-817C-4B8751429238}.Release|x86.Build.0 = Release|Any CPU
1194+
{6E5DE28D-88F1-4FFF-A4ED-39D919A1CB1B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
1195+
{6E5DE28D-88F1-4FFF-A4ED-39D919A1CB1B}.Debug|Any CPU.Build.0 = Debug|Any CPU
1196+
{6E5DE28D-88F1-4FFF-A4ED-39D919A1CB1B}.Debug|x64.ActiveCfg = Debug|Any CPU
1197+
{6E5DE28D-88F1-4FFF-A4ED-39D919A1CB1B}.Debug|x64.Build.0 = Debug|Any CPU
1198+
{6E5DE28D-88F1-4FFF-A4ED-39D919A1CB1B}.Debug|x86.ActiveCfg = Debug|Any CPU
1199+
{6E5DE28D-88F1-4FFF-A4ED-39D919A1CB1B}.Debug|x86.Build.0 = Debug|Any CPU
1200+
{6E5DE28D-88F1-4FFF-A4ED-39D919A1CB1B}.Release|Any CPU.ActiveCfg = Release|Any CPU
1201+
{6E5DE28D-88F1-4FFF-A4ED-39D919A1CB1B}.Release|Any CPU.Build.0 = Release|Any CPU
1202+
{6E5DE28D-88F1-4FFF-A4ED-39D919A1CB1B}.Release|x64.ActiveCfg = Release|Any CPU
1203+
{6E5DE28D-88F1-4FFF-A4ED-39D919A1CB1B}.Release|x64.Build.0 = Release|Any CPU
1204+
{6E5DE28D-88F1-4FFF-A4ED-39D919A1CB1B}.Release|x86.ActiveCfg = Release|Any CPU
1205+
{6E5DE28D-88F1-4FFF-A4ED-39D919A1CB1B}.Release|x86.Build.0 = Release|Any CPU
11921206
EndGlobalSection
11931207
GlobalSection(SolutionProperties) = preSolution
11941208
HideSolutionNode = FALSE

fsharp/zebra-puzzle/HELP.md

+38
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
# Help
2+
3+
## Running the tests
4+
5+
You can run the tests by opening a command prompt in the exercise's directory, and then running the [`dotnet test` command](https://docs.microsoft.com/en-us/dotnet/core/tools/dotnet-test)
6+
Alternatively, most IDE's have built-in support for running tests, including [Visual Studio](https://docs.microsoft.com/en-us/visualstudio/test/run-unit-tests-with-test-explorer), [Rider](https://www.jetbrains.com/help/rider/Unit_Testing_in_Solution.html) and [Visual Studio code](https://github.com/OmniSharp/omnisharp-vscode/wiki/How-to-run-and-debug-unit-tests).
7+
See the [tests page](https://exercism.io/tracks/fsharp/tests) for more information.
8+
9+
## Skipped tests
10+
11+
Initially, only the first test will be enabled.
12+
This is to encourage you to solve the exercise one step at a time.
13+
Once you get the first test passing, remove the `Skip` property from the next test and work on getting that test passing.
14+
15+
## Submitting your solution
16+
17+
You can submit your solution using the `exercism submit ZebraPuzzle.fs` command.
18+
This command will upload your solution to the Exercism website and print the solution page's URL.
19+
20+
It's possible to submit an incomplete solution which allows you to:
21+
22+
- See how others have completed the exercise
23+
- Request help from a mentor
24+
25+
## Need to get help?
26+
27+
If you'd like help solving the exercise, check the following pages:
28+
29+
- The [F# track's documentation](https://exercism.org/docs/tracks/fsharp)
30+
- [Exercism's programming category on the forum](https://forum.exercism.org/c/programming/5)
31+
- The [Frequently Asked Questions](https://exercism.org/docs/using/faqs)
32+
33+
Should those resources not suffice, you could submit your (incomplete) solution to request mentoring.
34+
35+
To get help if you're having trouble, you can use one of the following resources:
36+
37+
- [/r/fsharp](https://www.reddit.com/r/fsharp) is the F# subreddit.
38+
- [StackOverflow](http://stackoverflow.com/questions/tagged/f%23) can be used to search for your problem and see if it has been answered already. You can also ask and answer questions.

fsharp/zebra-puzzle/README.md

+49
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
# Zebra Puzzle
2+
3+
Welcome to Zebra Puzzle on Exercism's F# Track.
4+
If you need help running the tests or submitting your code, check out `HELP.md`.
5+
6+
## Instructions
7+
8+
Solve the zebra puzzle.
9+
10+
1. There are five houses.
11+
2. The Englishman lives in the red house.
12+
3. The Spaniard owns the dog.
13+
4. Coffee is drunk in the green house.
14+
5. The Ukrainian drinks tea.
15+
6. The green house is immediately to the right of the ivory house.
16+
7. The Old Gold smoker owns snails.
17+
8. Kools are smoked in the yellow house.
18+
9. Milk is drunk in the middle house.
19+
10. The Norwegian lives in the first house.
20+
11. The man who smokes Chesterfields lives in the house next to the man with the fox.
21+
12. Kools are smoked in the house next to the house where the horse is kept.
22+
13. The Lucky Strike smoker drinks orange juice.
23+
14. The Japanese smokes Parliaments.
24+
15. The Norwegian lives next to the blue house.
25+
26+
Each of the five houses is painted a different color, and their
27+
inhabitants are of different national extractions, own different pets,
28+
drink different beverages and smoke different brands of cigarettes.
29+
30+
Which of the residents drinks water?
31+
Who owns the zebra?
32+
33+
## Source
34+
35+
### Created by
36+
37+
- @ErikSchierboom
38+
39+
### Contributed to by
40+
41+
- @jrr
42+
- @lestephane
43+
- @robkeim
44+
- @valentin-p
45+
- @wolf99
46+
47+
### Based on
48+
49+
Wikipedia - https://en.wikipedia.org/wiki/Zebra_Puzzle

fsharp/zebra-puzzle/ZebraPuzzle.fs

+114
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
module ZebraPuzzle
2+
3+
open System
4+
5+
type Color =
6+
| Red
7+
| Green
8+
| Ivory
9+
| Yellow
10+
| Blue
11+
12+
type Resident =
13+
| Englishman
14+
| Spaniard
15+
| Ukranian
16+
| Norwegian
17+
| Japanese
18+
19+
type Pet =
20+
| Dog
21+
| Snails
22+
| Fox
23+
| Horse
24+
| Zebra
25+
26+
type Beverage =
27+
| Coffee
28+
| Tea
29+
| Milk
30+
| OrangeJuice
31+
| Water
32+
33+
type Smokes =
34+
| OldGold
35+
| Kools
36+
| Chesterfields
37+
| LuckyStrike
38+
| Parliaments
39+
40+
let rec permutations =
41+
function
42+
| [] -> seq [ List.empty ]
43+
| x :: xs -> Seq.collect (insertions x) (permutations xs)
44+
45+
and insertions x =
46+
function
47+
| [] -> [ [ x ] ]
48+
| (y :: ys) as xs -> (x :: xs) :: (List.map (fun x -> y :: x) (insertions x ys))
49+
50+
let private house item = List.findIndex ((=) item)
51+
52+
let private filterColors =
53+
permutations [ Red; Green; Ivory; Yellow; Blue ]
54+
|> Seq.filter (fun colors ->
55+
// The green house is immediately to the right of the ivory house.
56+
(house Green colors) + 1 = (house Ivory colors))
57+
58+
let private filterResidents colors =
59+
permutations [ Englishman; Spaniard; Ukranian; Norwegian; Japanese ]
60+
|> Seq.filter (fun residents ->
61+
// The Norwegian lives in the first house.
62+
(house Norwegian residents) = 0
63+
// The Norwegian lives next to the blue house.
64+
&& Math.Abs((house Norwegian residents) - (house Blue colors)) = 1
65+
// The Englishman lives in the red house.
66+
&& (house Englishman residents) = (house Red colors))
67+
68+
let private filterBeverages colors residents =
69+
permutations [ Coffee; Tea; Milk; OrangeJuice; Water ]
70+
|> Seq.filter (fun beverages ->
71+
// Coffee is drunk in the green house.
72+
(house Coffee beverages) = (house Green colors)
73+
// The Ukranian drinks tea.
74+
&& (house Ukranian residents) = (house Tea beverages)
75+
// Milk is drunk in the middle house.
76+
&& (house Milk beverages) = 2)
77+
78+
let private filterSmokes colors residents beverages =
79+
permutations [ OldGold; Kools; Chesterfields; LuckyStrike; Parliaments ]
80+
|> Seq.filter (fun smokes ->
81+
// Kools are smoked in the second house.
82+
(house Kools smokes) = (house Yellow colors)
83+
// The Lucky Strike smoker drinks orange juice.
84+
&& (house LuckyStrike smokes) = (house OrangeJuice beverages)
85+
// The Japanese smokes Parliaments.
86+
&& (house Japanese residents) = (house Parliaments smokes))
87+
88+
let private filterPets residents smokes =
89+
permutations [ Dog; Snails; Fox; Horse; Zebra ]
90+
|> Seq.filter (fun pets ->
91+
// The Spaniard owns the dog.
92+
(house Dog pets) = (house Spaniard residents)
93+
// The Old Gold smoker owns snails.
94+
&& (house OldGold smokes) = (house Snails pets)
95+
// The man who smokes Chesterfields lives in the house next to the man with the fox.
96+
&& Math.Abs((house Chesterfields smokes) - (house Fox pets)) = 1
97+
// Kools are smoked in the house next to the house where the horse is kept.
98+
&& Math.Abs((house Kools smokes) - (house Horse pets)) = 1)
99+
100+
let private combinations =
101+
seq {
102+
for colors in filterColors do
103+
for residents in filterResidents colors do
104+
for beverages in filterBeverages colors residents do
105+
for smokes in filterSmokes colors residents beverages do
106+
for pets in filterPets residents smokes do
107+
yield (colors, residents, beverages, smokes, pets)
108+
}
109+
110+
let (colors, residents, beverages, smokes, pets) = Seq.head combinations
111+
112+
let drinksWater = List.item (house Water beverages) residents
113+
114+
let ownsZebra = List.item (house Zebra pets) residents
+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<TargetFramework>net7.0</TargetFramework>
5+
6+
<IsPackable>false</IsPackable>
7+
</PropertyGroup>
8+
9+
<ItemGroup>
10+
<Compile Include="ZebraPuzzle.fs" />
11+
<Compile Include="ZebraPuzzleTests.fs" />
12+
</ItemGroup>
13+
14+
<ItemGroup>
15+
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.8.3" />
16+
<PackageReference Include="xunit" Version="2.4.1" />
17+
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.3" />
18+
<PackageReference Include="FsUnit.xUnit" Version="4.0.4" />
19+
</ItemGroup>
20+
21+
</Project>
+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
module ZebraPuzzleTests
2+
3+
open FsUnit.Xunit
4+
open Xunit
5+
6+
open ZebraPuzzle
7+
8+
[<Fact>]
9+
let ``Resident who drinks water`` () = drinksWater |> should equal Norwegian
10+
11+
[<Fact>]
12+
let ``Resident who owns zebra`` () = ownsZebra |> should equal Japanese

0 commit comments

Comments
 (0)