Skip to content

Commit

Permalink
commit changes
Browse files Browse the repository at this point in the history
  • Loading branch information
depial committed Mar 17, 2024
1 parent e952189 commit 49ca669
Show file tree
Hide file tree
Showing 8 changed files with 258 additions and 0 deletions.
8 changes: 8 additions & 0 deletions config.json
Original file line number Diff line number Diff line change
Expand Up @@ -924,6 +924,14 @@
"practices": [],
"prerequisites": [],
"difficulty": 4
},
{
"slug": "dominoes",
"name": "Dominoes",
"uuid": "f51647a9-2519-4495-b7d0-55e630958634",
"practices": [],
"prerequisites": [],
"difficulty": 4
}
]
},
Expand Down
13 changes: 13 additions & 0 deletions exercises/practice/dominoes/.docs/instructions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# Instructions

Make a chain of dominoes.

Compute a way to order a given set of dominoes in such a way that they form a correct domino chain (the dots on one half of a stone match the dots on the neighboring half of an adjacent stone) and that dots on the halves of the stones which don't have a neighbor (the first and last stone) 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.
15 changes: 15 additions & 0 deletions exercises/practice/dominoes/.meta/config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"authors": [],
"files": {
"solution": [
"dominoes.jl"
],
"test": [
"runtests.jl"
],
"example": [
".meta/example.jl"
]
},
"blurb": "Make a chain of dominoes."
}
15 changes: 15 additions & 0 deletions exercises/practice/dominoes/.meta/example.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
function dominoes(stones)
function dfs(stones, chain, indices)
length(indices) == length(stones) && first(first(chain)) == last(last(chain)) && return chain
for (i, stone) in enumerate(stones)
if i indices && last(last(chain)) stone
check = dfs(stones, push!(chain, last(last(chain)) == first(stone) ? stone : reverse(stone)), push!(indices, i))
isa(check, Vector) && return check
delete!(indices, i)
pop!(chain)
end
end
false
end
isempty(stones) ? [] : dfs(stones, [first(stones)], Set(1))
end
79 changes: 79 additions & 0 deletions exercises/practice/dominoes/.meta/supplemental.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
#=
There are two suggestions for testing in the problem specifications. The more rigorous choice, of testing
a returned chain for validity, was used in runtests.jl
Below is the other implementation of the algorithm which simply returns true/false if a chain is possible.
The accompanying test set is below that.
The change to the algorithm below is very minor, but this change may still be easier for some students.
Due to this change being for less experienced students I have explicitly tested as @test dominoes(input) == true/false
for clarity, instead of using the return value directly (i.e. @test dominoes(input)/!dominoes(input))
This points at another potential benefit which is that no helper function is needed for testing the validity of the chain.
=#

function dominoes(stones)
function dfs(stones, chain, indices)
length(indices) == length(stones) && first(first(chain)) == last(last(chain)) && return true
for (i, stone) in enumerate(stones)
if i indices && last(last(chain)) stone
check = dfs(stones, push!(chain, last(last(chain)) == first(stone) ? stone : reverse(stone)), push!(indices, i))
check && return true
delete!(indices, i)
pop!(chain)
end
end
false
end
isempty(stones) || dfs(stones, [first(stones)], Set(1))
end

@testset "empty input = empty output" begin
@test dominoes([]) == true
end

@testset "singleton input = singleton output" begin
@test dominoes([1, 1]) == true
end

@testset "singleton that can't be chained" begin
@test dominoes([1, 2]) == false
end

@testset "three elements" begin
@test dominoes([[1, 2], [3, 1], [2, 3]]) == true
end

@testset "can reverse dominoes" begin
@test dominoes([[1, 2], [1, 3], [2, 3]]) == true
end

@testset "can't be chained" begin
@test dominoes([[1, 2], [4, 1], [2, 3]]) == false
end

@testset "disconnected - simple" begin
@test dominoes([[1, 1], [2, 2]]) == false
end

@testset "disconnected - double loop" begin
@test dominoes([[1, 2], [2, 1], [3, 4], [4, 3]]) == false
end

@testset "disconnected - single isolated" begin
@test dominoes([[1, 2], [2, 3], [3, 1], [4, 4]]) == false
end

@testset "need backtrack" begin
@test dominoes([[1, 2], [2, 3], [3, 1], [2, 4], [2, 4]]) == true
end

@testset "separate loops" begin
@test dominoes([[1, 2], [2, 3], [3, 1], [1, 1], [2, 2], [3, 3]]) == true
end

@testset "nine elements" begin
@test dominoes([[1, 2], [5, 3], [3, 1], [1, 2], [2, 4], [1, 6], [2, 3], [3, 4], [5, 6]]) == true
end

@testset "separate three-domino loops" begin
@test dominoes([[1, 2], [2, 3], [3, 1], [4, 5], [5, 6], [6, 4]]) == false
end
49 changes: 49 additions & 0 deletions exercises/practice/dominoes/.meta/tests.toml
Original file line number Diff line number Diff line change
@@ -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"
3 changes: 3 additions & 0 deletions exercises/practice/dominoes/dominoes.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
function dominoes(stones)
# Your code here
end
76 changes: 76 additions & 0 deletions exercises/practice/dominoes/runtests.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
using Test
include("dominoes.jl")

@testset "empty input = empty output" begin
@test dominoes([]) == []
end

@testset "singleton input = singleton output" begin
chain = dominoes([1, 1])
@test isvalidchain(chain, true)
end

@testset "singleton that can't be chained" begin
chain = dominoes([1, 2])
@test isvalidchain(chain, false)
end

@testset "three elements" begin
chain = dominoes([[1, 2], [3, 1], [2, 3]])
@test isvalidchain(chain, true)
end

@testset "can reverse dominoes" begin
chain = dominoes([[1, 2], [1, 3], [2, 3]])
@test isvalidchain(chain, true)
end

@testset "can't be chained" begin
chain = dominoes([[1, 2], [4, 1], [2, 3]])
@test isvalidchain(chain, false)
end

@testset "disconnected - simple" begin
chain = dominoes([[1, 1], [2, 2]])
@test isvalidchain(chain, false)
end

@testset "disconnected - double loop" begin
chain = dominoes([[1, 2], [2, 1], [3, 4], [4, 3]])
@test isvalidchain(chain, false)
end

@testset "disconnected - single isolated" begin
chain = dominoes([[1, 2], [2, 3], [3, 1], [4, 4]])
@test isvalidchain(chain, false)
end

@testset "need backtrack" begin
chain = dominoes([[1, 2], [2, 3], [3, 1], [2, 4], [2, 4]])
@test isvalidchain(chain, true)
end

@testset "separate loops" begin
chain = dominoes([[1, 2], [2, 3], [3, 1], [1, 1], [2, 2], [3, 3]])
@test isvalidchain(chain, true)
end

@testset "nine elements" begin
chain = dominoes([[1, 2], [5, 3], [3, 1], [1, 2], [2, 4], [1, 6], [2, 3], [3, 4], [5, 6]])
@test isvalidchain(chain, true)
end

@testset "separate three-domino loops" begin
chain = dominoes([[1, 2], [2, 3], [3, 1], [4, 5], [5, 6], [6, 4]])
@test isvalidchain(chain, false)
end


function isvalidchain(chain, valid)
!valid && return isa(chain, Bool) ? !chain : false
first(first(chain)) != last(last(chain)) && return false
for i in 1:length(chain)-1
last(chain[i]) != first(chain[i+1]) && return false
end
true
end

0 comments on commit 49ca669

Please sign in to comment.