diff --git a/config.json b/config.json index 5970fff..58fd58e 100644 --- a/config.json +++ b/config.json @@ -739,6 +739,14 @@ "practices": [], "prerequisites": [], "difficulty": 7 + }, + { + "slug": "zebra-puzzle", + "name": "Zebra Puzzle", + "uuid": "be437e7f-5dc0-4c99-a4e0-1eb5b7cdbc1a", + "practices": [], + "prerequisites": [], + "difficulty": 9 } ], "foregone": [ diff --git a/exercises/practice/zebra-puzzle/.docs/instructions.md b/exercises/practice/zebra-puzzle/.docs/instructions.md new file mode 100644 index 0000000..aedce9b --- /dev/null +++ b/exercises/practice/zebra-puzzle/.docs/instructions.md @@ -0,0 +1,32 @@ +# Instructions + +Your task is to solve the Zebra Puzzle to find the answer to these two questions: + +- Which of the residents drinks water? +- Who owns the zebra? + +## Puzzle + +The following 15 statements are all known to be true: + +1. There are five houses. +2. The Englishman lives in the red house. +3. The Spaniard owns the dog. +4. The person in the green house drinks coffee. +5. The Ukrainian drinks tea. +6. The green house is immediately to the right of the ivory house. +7. The snail owner likes to go dancing. +8. The person in the yellow house is a painter. +9. The person in the middle house drinks milk. +10. The Norwegian lives in the first house. +11. The person who enjoys reading lives in the house next to the person with the fox. +12. The painter's house is next to the house with the horse. +13. The person who plays football drinks orange juice. +14. The Japanese person plays chess. +15. The Norwegian lives next to the blue house. + +Additionally, each of the five houses is painted a different color, and their inhabitants are of different national extractions, own different pets, drink different beverages and engage in different hobbies. + +~~~~exercism/note +There are 24 billion (5!⁵ = 24,883,200,000) possible solutions, so try ruling out as many solutions as possible. +~~~~ diff --git a/exercises/practice/zebra-puzzle/.docs/introduction.md b/exercises/practice/zebra-puzzle/.docs/introduction.md new file mode 100644 index 0000000..bbcaa6f --- /dev/null +++ b/exercises/practice/zebra-puzzle/.docs/introduction.md @@ -0,0 +1,15 @@ +# Introduction + +The Zebra Puzzle is a famous logic puzzle in which there are five houses, each painted a different color. +The houses have different inhabitants, who have different nationalities, own different pets, drink different beverages and enjoy different hobbies. + +To help you solve the puzzle, you're given 15 statements describing the solution. +However, only by combining the information in _all_ statements will you be able to find the solution to the puzzle. + +~~~~exercism/note +The Zebra Puzzle is a [Constraint satisfaction problem (CSP)][constraint-satisfaction-problem]. +In such a problem, you have a set of possible values and a set of constraints that limit which values are valid. +Another well-known CSP is Sudoku. + +[constraint-satisfaction-problem]: https://en.wikipedia.org/wiki/Constraint_satisfaction_problem +~~~~ diff --git a/exercises/practice/zebra-puzzle/.meta/config.json b/exercises/practice/zebra-puzzle/.meta/config.json new file mode 100644 index 0000000..aa435d6 --- /dev/null +++ b/exercises/practice/zebra-puzzle/.meta/config.json @@ -0,0 +1,19 @@ +{ + "authors": [ + "glennj" + ], + "files": { + "solution": [ + "zebra-puzzle.wren" + ], + "test": [ + "zebra-puzzle.spec.wren" + ], + "example": [ + ".meta/proof.ci.wren" + ] + }, + "blurb": "Solve the zebra puzzle.", + "source": "Wikipedia", + "source_url": "https://en.wikipedia.org/wiki/Zebra_Puzzle" +} diff --git a/exercises/practice/zebra-puzzle/.meta/proof.ci.wren b/exercises/practice/zebra-puzzle/.meta/proof.ci.wren new file mode 100644 index 0000000..29a1be3 --- /dev/null +++ b/exercises/practice/zebra-puzzle/.meta/proof.ci.wren @@ -0,0 +1,108 @@ +class ZebraPuzzle { + construct new() { + _waterDrinker = "" + _zebraOwner = "" + solve + } + + drinksWater { _waterDrinker } + ownsZebra { _zebraOwner } + + rightOf(a, b) { a + 1 == b } + nextTo(a, b) { rightOf(a, b) || rightOf(b, a) } + + solve { + var HOUSES = [1,2,3,4,5] + var FIRST = 1 + var MIDDLE = 3 + + var permutations = [ + [1,2,3,4,5], [1,2,3,5,4], [1,2,4,3,5], [1,2,4,5,3], [1,2,5,3,4], [1,2,5,4,3], + [1,3,2,4,5], [1,3,2,5,4], [1,3,4,2,5], [1,3,4,5,2], [1,3,5,2,4], [1,3,5,4,2], + [1,4,2,3,5], [1,4,2,5,3], [1,4,3,2,5], [1,4,3,5,2], [1,4,5,2,3], [1,4,5,3,2], + [1,5,2,3,4], [1,5,2,4,3], [1,5,3,2,4], [1,5,3,4,2], [1,5,4,2,3], [1,5,4,3,2], + [2,1,3,4,5], [2,1,3,5,4], [2,1,4,3,5], [2,1,4,5,3], [2,1,5,3,4], [2,1,5,4,3], + [2,3,1,4,5], [2,3,1,5,4], [2,3,4,1,5], [2,3,4,5,1], [2,3,5,1,4], [2,3,5,4,1], + [2,4,1,3,5], [2,4,1,5,3], [2,4,3,1,5], [2,4,3,5,1], [2,4,5,1,3], [2,4,5,3,1], + [2,5,1,3,4], [2,5,1,4,3], [2,5,3,1,4], [2,5,3,4,1], [2,5,4,1,3], [2,5,4,3,1], + [3,1,2,4,5], [3,1,2,5,4], [3,1,4,2,5], [3,1,4,5,2], [3,1,5,2,4], [3,1,5,4,2], + [3,2,1,4,5], [3,2,1,5,4], [3,2,4,1,5], [3,2,4,5,1], [3,2,5,1,4], [3,2,5,4,1], + [3,4,1,2,5], [3,4,1,5,2], [3,4,2,1,5], [3,4,2,5,1], [3,4,5,1,2], [3,4,5,2,1], + [3,5,1,2,4], [3,5,1,4,2], [3,5,2,1,4], [3,5,2,4,1], [3,5,4,1,2], [3,5,4,2,1], + [4,1,2,3,5], [4,1,2,5,3], [4,1,3,2,5], [4,1,3,5,2], [4,1,5,2,3], [4,1,5,3,2], + [4,2,1,3,5], [4,2,1,5,3], [4,2,3,1,5], [4,2,3,5,1], [4,2,5,1,3], [4,2,5,3,1], + [4,3,1,2,5], [4,3,1,5,2], [4,3,2,1,5], [4,3,2,5,1], [4,3,5,1,2], [4,3,5,2,1], + [4,5,1,2,3], [4,5,1,3,2], [4,5,2,1,3], [4,5,2,3,1], [4,5,3,1,2], [4,5,3,2,1], + [5,1,2,3,4], [5,1,2,4,3], [5,1,3,2,4], [5,1,3,4,2], [5,1,4,2,3], [5,1,4,3,2], + [5,2,1,3,4], [5,2,1,4,3], [5,2,3,1,4], [5,2,3,4,1], [5,2,4,1,3], [5,2,4,3,1], + [5,3,1,2,4], [5,3,1,4,2], [5,3,2,1,4], [5,3,2,4,1], [5,3,4,1,2], [5,3,4,2,1], + [5,4,1,2,3], [5,4,1,3,2], [5,4,2,1,3], [5,4,2,3,1], [5,4,3,1,2], [5,4,3,2,1] + ] + + for (colours in permutations) { + var blue = colours[0] + var green = colours[1] + var ivory = colours[2] + var red = colours[3] + var yellow = colours[4] + + if (rightOf(green, ivory)) { + + for (nations in permutations) { + var en = nations[0] + var es = nations[1] + var ja = nations[2] + var no = nations[3] + var uk = nations[4] + + var nationalities = ["","","","","",""] + nationalities[en] = "English" + nationalities[es] = "Spanish" + nationalities[ja] = "Japanese" + nationalities[no] = "Norwegian" + nationalities[uk] = "Ukranian" + + if (en == red && no == FIRST && nextTo(no, blue)) { + + for (drinks in permutations) { + var coffee = drinks[0] + var tea = drinks[1] + var milk = drinks[2] + var juice = drinks[3] + var water = drinks[4] + + if (coffee == green && uk == tea && milk == MIDDLE) { + + for (hobbies in permutations) { + var dance = hobbies[0] + var paint = hobbies[1] + var read = hobbies[2] + var chess = hobbies[3] + var football = hobbies[4] + + if (paint == yellow && football == juice && ja == chess) { + + for (pets in permutations) { + var horse = pets[0] + var fox = pets[1] + var snail = pets[2] + var dog = pets[3] + var zebra = pets[4] + + if (es == dog && dance == snail && nextTo(read, fox) && nextTo(paint, horse)) { + + _waterDrinker = nationalities[water] + _zebraOwner = nationalities[zebra] + return + } + } + } + } + } + } + } + } + } + } + } +} diff --git a/exercises/practice/zebra-puzzle/.meta/tests.toml b/exercises/practice/zebra-puzzle/.meta/tests.toml new file mode 100644 index 0000000..56c21c7 --- /dev/null +++ b/exercises/practice/zebra-puzzle/.meta/tests.toml @@ -0,0 +1,16 @@ +# This is an auto-generated file. +# +# Regenerating this file via `configlet sync` will: +# - Recreate every `description` key/value pair +# - Recreate every `reimplements` key/value pair, where they exist in problem-specifications +# - Remove any `include = true` key/value pair (an omitted `include` key implies inclusion) +# - Preserve any other key/value pair +# +# As user-added comments (using the # character) will be removed when this file +# is regenerated, comments can be added via a `comment` key. + +[16efb4e4-8ad7-4d5e-ba96-e5537b66fd42] +description = "resident who drinks water" + +[084d5b8b-24e2-40e6-b008-c800da8cd257] +description = "resident who owns zebra" diff --git a/exercises/practice/zebra-puzzle/LICENSE b/exercises/practice/zebra-puzzle/LICENSE new file mode 100644 index 0000000..c362f61 --- /dev/null +++ b/exercises/practice/zebra-puzzle/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2024 Exercism + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/exercises/practice/zebra-puzzle/package.wren b/exercises/practice/zebra-puzzle/package.wren new file mode 100644 index 0000000..69b6440 --- /dev/null +++ b/exercises/practice/zebra-puzzle/package.wren @@ -0,0 +1,14 @@ +import "wren-package" for WrenPackage, Dependency +import "os" for Process + +class Package is WrenPackage { + construct new() {} + name { "exercism/zebra-puzzle" } + dependencies { + return [ + Dependency.new("wren-testie", "0.3.0", "https://github.com/joshgoebel/wren-testie.git") + ] + } +} + +Package.new().default() diff --git a/exercises/practice/zebra-puzzle/zebra-puzzle.spec.wren b/exercises/practice/zebra-puzzle/zebra-puzzle.spec.wren new file mode 100644 index 0000000..df6e93f --- /dev/null +++ b/exercises/practice/zebra-puzzle/zebra-puzzle.spec.wren @@ -0,0 +1,18 @@ +import "./zebra-puzzle" for ZebraPuzzle +import "wren-testie/testie" for Testie, Expect + +Testie.test("ZebraPuzzle") { |do, skip| + do.test("resident who drinks water") { + var puzzle = ZebraPuzzle.new() + var actual = puzzle.drinksWater + var expected = "Norwegian" + Expect.value(actual).toEqual(expected) + } + + skip.test("resident who owns zebra") { + var puzzle = ZebraPuzzle.new() + var actual = puzzle.ownsZebra + var expected = "Japanese" + Expect.value(actual).toEqual(expected) + } +} diff --git a/exercises/practice/zebra-puzzle/zebra-puzzle.wren b/exercises/practice/zebra-puzzle/zebra-puzzle.wren new file mode 100644 index 0000000..a0f120c --- /dev/null +++ b/exercises/practice/zebra-puzzle/zebra-puzzle.wren @@ -0,0 +1,5 @@ +class ZebraPuzzle { + construct new() { + Fiber.abort("Remove this statement and implement this function") + } +}