From 0f46f199397d4328202fb201383df3ded44a63b0 Mon Sep 17 00:00:00 2001 From: Glenn Jackman Date: Tue, 28 Apr 2026 17:16:53 -0400 Subject: [PATCH] Add dominoes --- config.json | 8 ++ exercises/practice/dominoes/.busted | 5 + .../practice/dominoes/.docs/instructions.md | 15 +++ .../practice/dominoes/.docs/introduction.md | 13 +++ exercises/practice/dominoes/.meta/config.json | 17 +++ .../practice/dominoes/.meta/example.moon | 39 +++++++ .../dominoes/.meta/spec_generator.moon | 12 ++ exercises/practice/dominoes/.meta/tests.toml | 49 ++++++++ exercises/practice/dominoes/dominoes.moon | 4 + .../practice/dominoes/dominoes_spec.moon | 109 ++++++++++++++++++ 10 files changed, 271 insertions(+) create mode 100644 exercises/practice/dominoes/.busted create mode 100644 exercises/practice/dominoes/.docs/instructions.md create mode 100644 exercises/practice/dominoes/.docs/introduction.md create mode 100644 exercises/practice/dominoes/.meta/config.json create mode 100644 exercises/practice/dominoes/.meta/example.moon create mode 100644 exercises/practice/dominoes/.meta/spec_generator.moon create mode 100644 exercises/practice/dominoes/.meta/tests.toml create mode 100644 exercises/practice/dominoes/dominoes.moon create mode 100644 exercises/practice/dominoes/dominoes_spec.moon diff --git a/config.json b/config.json index 6096b86..7e177bd 100644 --- a/config.json +++ b/config.json @@ -866,6 +866,14 @@ "prerequisites": [], "difficulty": 7 }, + { + "slug": "dominoes", + "name": "Dominoes", + "uuid": "2feb9a0a-2fcf-4e82-ad28-301f9b9ec883", + "practices": [], + "prerequisites": [], + "difficulty": 7 + }, { "slug": "rectangles", "name": "Rectangles", diff --git a/exercises/practice/dominoes/.busted b/exercises/practice/dominoes/.busted new file mode 100644 index 0000000..86b84e7 --- /dev/null +++ b/exercises/practice/dominoes/.busted @@ -0,0 +1,5 @@ +return { + default = { + ROOT = { '.' } + } +} diff --git a/exercises/practice/dominoes/.docs/instructions.md b/exercises/practice/dominoes/.docs/instructions.md new file mode 100644 index 0000000..75055b9 --- /dev/null +++ b/exercises/practice/dominoes/.docs/instructions.md @@ -0,0 +1,15 @@ +# Instructions + +Make a chain of dominoes. + +Compute a way to order a given set of domino stones so that they form a correct domino chain. +In the chain, the dots on one half of a stone must match the dots on the neighboring half of an adjacent stone. +Additionally, the dots on the halves of the stones without neighbors (the first and last stone) must match each other. + +For example given the stones `[2|1]`, `[2|3]` and `[1|3]` you should compute something +like `[1|2] [2|3] [3|1]` or `[3|2] [2|1] [1|3]` or `[1|3] [3|2] [2|1]` etc, where the first and last numbers are the same. + +For stones `[1|2]`, `[4|1]` and `[2|3]` the resulting chain is not valid: `[4|1] [1|2] [2|3]`'s first and last numbers are not the same. +4 != 3 + +Some test cases may use duplicate stones in a chain solution, assume that multiple Domino sets are being used. diff --git a/exercises/practice/dominoes/.docs/introduction.md b/exercises/practice/dominoes/.docs/introduction.md new file mode 100644 index 0000000..df248c2 --- /dev/null +++ b/exercises/practice/dominoes/.docs/introduction.md @@ -0,0 +1,13 @@ +# Introduction + +In Toyland, the trains are always busy delivering treasures across the city, from shiny marbles to rare building blocks. +The tracks they run on are made of colorful domino-shaped pieces, each marked with two numbers. +For the trains to move, the dominoes must form a perfect chain where the numbers match. + +Today, an urgent delivery of rare toys is on hold. +You've been handed a set of track pieces to inspect. +If they can form a continuous chain, the train will be on its way, bringing smiles across Toyland. +If not, the set will be discarded, and another will be tried. + +The toys are counting on you to solve this puzzle. +Will the dominoes connect the tracks and send the train rolling, or will the set be left behind? diff --git a/exercises/practice/dominoes/.meta/config.json b/exercises/practice/dominoes/.meta/config.json new file mode 100644 index 0000000..0c3f140 --- /dev/null +++ b/exercises/practice/dominoes/.meta/config.json @@ -0,0 +1,17 @@ +{ + "authors": [ + "glennj" + ], + "files": { + "solution": [ + "dominoes.moon" + ], + "test": [ + "dominoes_spec.moon" + ], + "example": [ + ".meta/example.moon" + ] + }, + "blurb": "Make a chain of dominoes." +} diff --git a/exercises/practice/dominoes/.meta/example.moon b/exercises/practice/dominoes/.meta/example.moon new file mode 100644 index 0000000..86665a4 --- /dev/null +++ b/exercises/practice/dominoes/.meta/example.moon @@ -0,0 +1,39 @@ +-- clone first list and append an element to the end of the new list +append = (list, elem) -> + newList = {table.unpack list} + table.insert newList, elem + newList + +removeIndex = (list, index) -> + newList = {table.unpack list} + table.remove(newList, index) + newList + +-- ------------------------------------------------------- +chainer = (chain, remaining) -> + if #remaining == 0 + return chain[1][1] == chain[#chain][2] + + last = chain[#chain][2] + for i, domino in ipairs remaining + if domino[1] == last + nextChain = append chain, domino + nextRemaining = removeIndex remaining, i + return true if chainer nextChain, nextRemaining + elseif domino[2] == last + nextChain = append chain, {domino[2], domino[1]} + nextRemaining = removeIndex remaining, i + return true if chainer nextChain, nextRemaining + + false + +-- ------------------------------------------------------- +{ + canChain: (dominoes) -> + return true if #dominoes == 0 + + for i, domino in ipairs dominoes + return true if chainer {domino}, removeIndex(dominoes, i) + + false +} diff --git a/exercises/practice/dominoes/.meta/spec_generator.moon b/exercises/practice/dominoes/.meta/spec_generator.moon new file mode 100644 index 0000000..40f08fd --- /dev/null +++ b/exercises/practice/dominoes/.meta/spec_generator.moon @@ -0,0 +1,12 @@ +import int_lists from require 'test_helpers' + +{ + module_imports: {'canChain'}, + + generate_test: (case, level) -> + lines = { + "dominoes = #{int_lists case.input.dominoes, level}", + "assert.is.#{case.expected} canChain dominoes" + } + table.concat [indent line, level for line in *lines], '\n' +} diff --git a/exercises/practice/dominoes/.meta/tests.toml b/exercises/practice/dominoes/.meta/tests.toml new file mode 100644 index 0000000..08c8e08 --- /dev/null +++ b/exercises/practice/dominoes/.meta/tests.toml @@ -0,0 +1,49 @@ +# 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. + +[31a673f2-5e54-49fe-bd79-1c1dae476c9c] +description = "empty input = empty output" + +[4f99b933-367b-404b-8c6d-36d5923ee476] +description = "singleton input = singleton output" + +[91122d10-5ec7-47cb-b759-033756375869] +description = "singleton that can't be chained" + +[be8bc26b-fd3d-440b-8e9f-d698a0623be3] +description = "three elements" + +[99e615c6-c059-401c-9e87-ad7af11fea5c] +description = "can reverse dominoes" + +[51f0c291-5d43-40c5-b316-0429069528c9] +description = "can't be chained" + +[9a75e078-a025-4c23-8c3a-238553657f39] +description = "disconnected - simple" + +[0da0c7fe-d492-445d-b9ef-1f111f07a301] +description = "disconnected - double loop" + +[b6087ff0-f555-4ea0-a71c-f9d707c5994a] +description = "disconnected - single isolated" + +[2174fbdc-8b48-4bac-9914-8090d06ef978] +description = "need backtrack" + +[167bb480-dfd1-4318-a20d-4f90adb4a09f] +description = "separate loops" + +[cd061538-6046-45a7-ace9-6708fe8f6504] +description = "nine elements" + +[44704c7c-3adb-4d98-bd30-f45527cf8b49] +description = "separate three-domino loops" diff --git a/exercises/practice/dominoes/dominoes.moon b/exercises/practice/dominoes/dominoes.moon new file mode 100644 index 0000000..2206cea --- /dev/null +++ b/exercises/practice/dominoes/dominoes.moon @@ -0,0 +1,4 @@ +{ + canChain: (dominoes) -> + error 'Implement me' +} diff --git a/exercises/practice/dominoes/dominoes_spec.moon b/exercises/practice/dominoes/dominoes_spec.moon new file mode 100644 index 0000000..b8f372e --- /dev/null +++ b/exercises/practice/dominoes/dominoes_spec.moon @@ -0,0 +1,109 @@ +import canChain from require 'dominoes' + +describe 'dominoes', -> + it 'empty input = empty output', -> + dominoes = {} + assert.is.true canChain dominoes + + pending 'singleton input = singleton output', -> + dominoes = {{1, 1}} + assert.is.true canChain dominoes + + pending "singleton that can't be chained", -> + dominoes = {{1, 2}} + assert.is.false canChain dominoes + + pending 'three elements', -> + dominoes = { + {1, 2}, + {3, 1}, + {2, 3}, + } + assert.is.true canChain dominoes + + pending 'can reverse dominoes', -> + dominoes = { + {1, 2}, + {1, 3}, + {2, 3}, + } + assert.is.true canChain dominoes + + pending "can't be chained", -> + dominoes = { + {1, 2}, + {4, 1}, + {2, 3}, + } + assert.is.false canChain dominoes + + pending 'disconnected - simple', -> + dominoes = { + {1, 1}, + {2, 2}, + } + assert.is.false canChain dominoes + + pending 'disconnected - double loop', -> + dominoes = { + {1, 2}, + {2, 1}, + {3, 4}, + {4, 3}, + } + assert.is.false canChain dominoes + + pending 'disconnected - single isolated', -> + dominoes = { + {1, 2}, + {2, 3}, + {3, 1}, + {4, 4}, + } + assert.is.false canChain dominoes + + pending 'need backtrack', -> + dominoes = { + {1, 2}, + {2, 3}, + {3, 1}, + {2, 4}, + {2, 4}, + } + assert.is.true canChain dominoes + + pending 'separate loops', -> + dominoes = { + {1, 2}, + {2, 3}, + {3, 1}, + {1, 1}, + {2, 2}, + {3, 3}, + } + assert.is.true canChain dominoes + + pending 'nine elements', -> + dominoes = { + {1, 2}, + {5, 3}, + {3, 1}, + {1, 2}, + {2, 4}, + {1, 6}, + {2, 3}, + {3, 4}, + {5, 6}, + } + assert.is.true canChain dominoes + + pending 'separate three-domino loops', -> + dominoes = { + {1, 2}, + {2, 3}, + {3, 1}, + {4, 5}, + {5, 6}, + {6, 4}, + } + assert.is.false canChain dominoes