Skip to content

Commit

Permalink
Add game-of-life exercise
Browse files Browse the repository at this point in the history
  • Loading branch information
ErikSchierboom committed Jan 21, 2025
1 parent 03f35fd commit a090730
Show file tree
Hide file tree
Showing 11 changed files with 248 additions and 0 deletions.
11 changes: 11 additions & 0 deletions config.json
Original file line number Diff line number Diff line change
Expand Up @@ -1383,6 +1383,17 @@
],
"difficulty": 5
},
{
"slug": "game-of-life",
"name": "Conway's Game of Life",
"uuid": "136eef87-a87b-4f3e-b587-6f45b4e96d6e",
"practices": [],
"prerequisites": [
"vectors",
"numbers"
],
"difficulty": 5
},
{
"slug": "wordy",
"name": "Wordy",
Expand Down
11 changes: 11 additions & 0 deletions exercises/practice/game-of-life/.docs/instructions.md
Original file line number Diff line number Diff line change
@@ -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.
9 changes: 9 additions & 0 deletions exercises/practice/game-of-life/.docs/introduction.md
Original file line number Diff line number Diff line change
@@ -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
19 changes: 19 additions & 0 deletions exercises/practice/game-of-life/.meta/config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"authors": [
"erikschierboom"
],
"files": {
"solution": [
"src/game_of_life.clj"
],
"test": [
"test/game_of_life_test.clj"
],
"example": [
".meta/example.clj"
]
},
"blurb": "Implement Conway's Game of Life.",
"source": "Wikipedia",
"source_url": "https://en.wikipedia.org/wiki/Conway%27s_Game_of_Life"
}
25 changes: 25 additions & 0 deletions exercises/practice/game-of-life/.meta/example.clj
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
(ns game-of-life)

(defn live-neighbors-count [matrix y x]
(->> (for [dy [-1 0 1] dx [-1 0 1]
:when (not (and (= dy 0) (= dx 0)))]
(get-in matrix [(+ y dy) (+ x dx)] 0))
(apply +)))

(defn next-generation [cell neighbors-count]
(if
(or (= 3 neighbors-count)
(and (= 2 neighbors-count) (= 1 cell)))
1
0))

(defn tick [matrix]
(mapv
(fn [y row]
(mapv
(fn [x cell] (next-generation cell (live-neighbors-count matrix y x)))
(range)
row))
(range)
matrix))

17 changes: 17 additions & 0 deletions exercises/practice/game-of-life/.meta/generator.tpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
(ns game-of-life-test
(:require [clojure.test :refer [deftest testing is]]
game-of-life))

{{#test_cases.tick}}
(deftest tick_test_{{idx}}
(testing {{description}}
(is
(=
[{{#expected~}}
{{.}}
{{/expected}}]
(game-of-life/tick
[{{#input.matrix~}}
{{.}}
{{/input.matrix}}])))))
{{/test_cases.tick}}
34 changes: 34 additions & 0 deletions exercises/practice/game-of-life/.meta/tests.toml
Original file line number Diff line number Diff line change
@@ -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"
6 changes: 6 additions & 0 deletions exercises/practice/game-of-life/deps.edn
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{:aliases {:test {:extra-paths ["test"]
:extra-deps {io.github.cognitect-labs/test-runner
{:git/url "https://github.com/cognitect-labs/test-runner.git"
:sha "705ad25bbf0228b1c38d0244a36001c2987d7337"}}
:main-opts ["-m" "cognitect.test-runner"]
:exec-fn cognitect.test-runner.api/test}}}
4 changes: 4 additions & 0 deletions exercises/practice/game-of-life/project.clj
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
(defproject game-of-life "0.1.0-SNAPSHOT"
:description "game-of-life exercise."
:url "https://github.com/exercism/clojure/tree/main/exercises/practice/game-of-life"
:dependencies [[org.clojure/clojure "1.11.1"]])
7 changes: 7 additions & 0 deletions exercises/practice/game-of-life/src/game_of_life.clj
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
(ns game-of-life)

(defn tick
"Return the next generation of the given matrix."
[matrix]
;; function body
)
105 changes: 105 additions & 0 deletions exercises/practice/game-of-life/test/game_of_life_test.clj
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
(ns game-of-life-test
(:require [clojure.test :refer [deftest testing is]]
game-of-life))

(deftest tick_test_1
(testing "empty matrix"
(is
(=
[]
(game-of-life/tick
[])))))

(deftest tick_test_2
(testing "live cells with zero live neighbors die"
(is
(=
[[0 0 0]
[0 0 0]
[0 0 0]]
(game-of-life/tick
[[0 0 0]
[0 1 0]
[0 0 0]])))))

(deftest tick_test_3
(testing "live cells with only one live neighbor die"
(is
(=
[[0 0 0]
[0 0 0]
[0 0 0]]
(game-of-life/tick
[[0 0 0]
[0 1 0]
[0 1 0]])))))

(deftest tick_test_4
(testing "live cells with two live neighbors stay alive"
(is
(=
[[0 0 0]
[1 0 1]
[0 0 0]]
(game-of-life/tick
[[1 0 1]
[1 0 1]
[1 0 1]])))))

(deftest tick_test_5
(testing "live cells with three live neighbors stay alive"
(is
(=
[[0 0 0]
[1 0 0]
[1 1 0]]
(game-of-life/tick
[[0 1 0]
[1 0 0]
[1 1 0]])))))

(deftest tick_test_6
(testing "dead cells with three live neighbors become alive"
(is
(=
[[0 0 0]
[1 1 0]
[0 0 0]]
(game-of-life/tick
[[1 1 0]
[0 0 0]
[1 0 0]])))))

(deftest tick_test_7
(testing "live cells with four or more neighbors die"
(is
(=
[[1 0 1]
[0 0 0]
[1 0 1]]
(game-of-life/tick
[[1 1 1]
[1 1 1]
[1 1 1]])))))

(deftest tick_test_8
(testing "bigger matrix"
(is
(=
[[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]]
(game-of-life/tick
[[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]])))))

0 comments on commit a090730

Please sign in to comment.