diff --git a/config.json b/config.json index e5082f8..d44d165 100644 --- a/config.json +++ b/config.json @@ -682,6 +682,14 @@ "prerequisites": [], "difficulty": 5 }, + { + "slug": "game-of-life", + "name": "Conway's Game of Life", + "uuid": "a12cd1e2-4108-40ad-aa72-80706d1eeb30", + "practices": [], + "prerequisites": [], + "difficulty": 5 + }, { "slug": "crypto-square", "name": "Crypto Square", diff --git a/exercises/practice/game-of-life/.busted b/exercises/practice/game-of-life/.busted new file mode 100644 index 0000000..86b84e7 --- /dev/null +++ b/exercises/practice/game-of-life/.busted @@ -0,0 +1,5 @@ +return { + default = { + ROOT = { '.' } + } +} diff --git a/exercises/practice/game-of-life/.docs/instructions.md b/exercises/practice/game-of-life/.docs/instructions.md new file mode 100644 index 0000000..4953140 --- /dev/null +++ b/exercises/practice/game-of-life/.docs/instructions.md @@ -0,0 +1,11 @@ +# Instructions + +After each generation, the cells interact with their eight neighbors, which are cells adjacent horizontally, vertically, or diagonally. + +The following rules are applied to each cell: + +- Any live cell with two or three live neighbors lives on. +- Any dead cell with exactly three live neighbors becomes a live cell. +- All other cells die or stay dead. + +Given a matrix of 1s and 0s (corresponding to live and dead cells), apply the rules to each cell, and return the next generation. diff --git a/exercises/practice/game-of-life/.docs/introduction.md b/exercises/practice/game-of-life/.docs/introduction.md new file mode 100644 index 0000000..2347b93 --- /dev/null +++ b/exercises/practice/game-of-life/.docs/introduction.md @@ -0,0 +1,9 @@ +# Introduction + +[Conway's Game of Life][game-of-life] is a fascinating cellular automaton created by the British mathematician John Horton Conway in 1970. + +The game consists of a two-dimensional grid of cells that can either be "alive" or "dead." + +After each generation, the cells interact with their eight neighbors via a set of rules, which define the new generation. + +[game-of-life]: https://en.wikipedia.org/wiki/Conway%27s_Game_of_Life diff --git a/exercises/practice/game-of-life/.meta/config.json b/exercises/practice/game-of-life/.meta/config.json new file mode 100644 index 0000000..7db0867 --- /dev/null +++ b/exercises/practice/game-of-life/.meta/config.json @@ -0,0 +1,19 @@ +{ + "authors": [ + "glennj" + ], + "files": { + "solution": [ + "game_of_life.moon" + ], + "test": [ + "game_of_life_spec.moon" + ], + "example": [ + ".meta/example.moon" + ] + }, + "blurb": "Implement Conway's Game of Life.", + "source": "Wikipedia", + "source_url": "https://en.wikipedia.org/wiki/Conway%27s_Game_of_Life" +} diff --git a/exercises/practice/game-of-life/.meta/example.moon b/exercises/practice/game-of-life/.meta/example.moon new file mode 100644 index 0000000..28e6e78 --- /dev/null +++ b/exercises/practice/game-of-life/.meta/example.moon @@ -0,0 +1,30 @@ +Deltas = { + {-1, -1}, {-1, 0}, {-1, 1}, + {0, -1}, {0, 1}, + {1, -1}, {1, 0}, {1, 1} +} + +tick = (matrix) -> + height = #matrix + return {} if height == 0 + width = #matrix[1] + + count_neighbours = (x, y) -> + count = 0 + for d in *Deltas + dx, dy = x + d[1], y + d[2] + if 1 <= dx and dx <= height and 1 <= dy and dy <= width + count += matrix[dx][dy] + count + + result = [{} for _ = 1, height] + for r = 1, height + for c = 1, width + result[r][c] = switch count_neighbours r, c + when 3 then 1 + when 2 then matrix[r][c] + else 0 + result + + +{ :tick } diff --git a/exercises/practice/game-of-life/.meta/spec_generator.moon b/exercises/practice/game-of-life/.meta/spec_generator.moon new file mode 100644 index 0000000..b99a872 --- /dev/null +++ b/exercises/practice/game-of-life/.meta/spec_generator.moon @@ -0,0 +1,14 @@ +import int_lists, word_list from require 'test_helpers' + +{ + module_name: 'GameOfLife', + + generate_test: (case, level) -> + lines = { + "matrix = #{int_lists case.input.matrix, level}" + "result = GameOfLife.#{case.property} matrix" + "expected = #{int_lists case.expected, level}", + "assert.are.same expected, result" + } + table.concat [indent line, level for line in *lines], '\n' +} diff --git a/exercises/practice/game-of-life/.meta/tests.toml b/exercises/practice/game-of-life/.meta/tests.toml new file mode 100644 index 0000000..398cd45 --- /dev/null +++ b/exercises/practice/game-of-life/.meta/tests.toml @@ -0,0 +1,34 @@ +# 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. + +[ae86ea7d-bd07-4357-90b3-ac7d256bd5c5] +description = "empty matrix" + +[4ea5ccb7-7b73-4281-954a-bed1b0f139a5] +description = "live cells with zero live neighbors die" + +[df245adc-14ff-4f9c-b2ae-f465ef5321b2] +description = "live cells with only one live neighbor die" + +[2a713b56-283c-48c8-adae-1d21306c80ae] +description = "live cells with two live neighbors stay alive" + +[86d5c5a5-ab7b-41a1-8907-c9b3fc5e9dae] +description = "live cells with three live neighbors stay alive" + +[015f60ac-39d8-4c6c-8328-57f334fc9f89] +description = "dead cells with three live neighbors become alive" + +[2ee69c00-9d41-4b8b-89da-5832e735ccf1] +description = "live cells with four or more neighbors die" + +[a79b42be-ed6c-4e27-9206-43da08697ef6] +description = "bigger matrix" diff --git a/exercises/practice/game-of-life/game_of_life.moon b/exercises/practice/game-of-life/game_of_life.moon new file mode 100644 index 0000000..1e9f35c --- /dev/null +++ b/exercises/practice/game-of-life/game_of_life.moon @@ -0,0 +1,4 @@ +{ + tick: (matrix) -> + error 'Implement me' +} diff --git a/exercises/practice/game-of-life/game_of_life_spec.moon b/exercises/practice/game-of-life/game_of_life_spec.moon new file mode 100644 index 0000000..1d29924 --- /dev/null +++ b/exercises/practice/game-of-life/game_of_life_spec.moon @@ -0,0 +1,116 @@ +GameOfLife = require 'game_of_life' + +describe 'game-of-life', -> + it 'empty matrix', -> + matrix = {} + result = GameOfLife.tick matrix + expected = {} + assert.are.same expected, result + + pending 'live cells with zero live neighbors die', -> + matrix = { + {0, 0, 0}, + {0, 1, 0}, + {0, 0, 0}, + } + result = GameOfLife.tick matrix + expected = { + {0, 0, 0}, + {0, 0, 0}, + {0, 0, 0}, + } + assert.are.same expected, result + + pending 'live cells with only one live neighbor die', -> + matrix = { + {0, 0, 0}, + {0, 1, 0}, + {0, 1, 0}, + } + result = GameOfLife.tick matrix + expected = { + {0, 0, 0}, + {0, 0, 0}, + {0, 0, 0}, + } + assert.are.same expected, result + + pending 'live cells with two live neighbors stay alive', -> + matrix = { + {1, 0, 1}, + {1, 0, 1}, + {1, 0, 1}, + } + result = GameOfLife.tick matrix + expected = { + {0, 0, 0}, + {1, 0, 1}, + {0, 0, 0}, + } + assert.are.same expected, result + + pending 'live cells with three live neighbors stay alive', -> + matrix = { + {0, 1, 0}, + {1, 0, 0}, + {1, 1, 0}, + } + result = GameOfLife.tick matrix + expected = { + {0, 0, 0}, + {1, 0, 0}, + {1, 1, 0}, + } + assert.are.same expected, result + + pending 'dead cells with three live neighbors become alive', -> + matrix = { + {1, 1, 0}, + {0, 0, 0}, + {1, 0, 0}, + } + result = GameOfLife.tick matrix + expected = { + {0, 0, 0}, + {1, 1, 0}, + {0, 0, 0}, + } + assert.are.same expected, result + + pending 'live cells with four or more neighbors die', -> + matrix = { + {1, 1, 1}, + {1, 1, 1}, + {1, 1, 1}, + } + result = GameOfLife.tick matrix + expected = { + {1, 0, 1}, + {0, 0, 0}, + {1, 0, 1}, + } + assert.are.same expected, result + + pending 'bigger matrix', -> + matrix = { + {1, 1, 0, 1, 1, 0, 0, 0}, + {1, 0, 1, 1, 0, 0, 0, 0}, + {1, 1, 1, 0, 0, 1, 1, 1}, + {0, 0, 0, 0, 0, 1, 1, 0}, + {1, 0, 0, 0, 1, 1, 0, 0}, + {1, 1, 0, 0, 0, 1, 1, 1}, + {0, 0, 1, 0, 1, 0, 0, 1}, + {1, 0, 0, 0, 0, 0, 1, 1}, + } + result = GameOfLife.tick matrix + expected = { + {1, 1, 0, 1, 1, 0, 0, 0}, + {0, 0, 0, 0, 0, 1, 1, 0}, + {1, 0, 1, 1, 1, 1, 0, 1}, + {1, 0, 0, 0, 0, 0, 0, 1}, + {1, 1, 0, 0, 1, 0, 0, 1}, + {1, 1, 0, 1, 0, 0, 0, 1}, + {1, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 1, 1}, + } + assert.are.same expected, result