diff --git a/config.json b/config.json index 519197e..613b1d3 100644 --- a/config.json +++ b/config.json @@ -164,6 +164,14 @@ "prerequisites": [], "difficulty": 2 }, + { + "slug": "queen-attack", + "name": "Queen Attack", + "uuid": "aaa30836-220f-4f3c-9129-068d703bb9a6", + "practices": [], + "prerequisites": [], + "difficulty": 2 + }, { "slug": "rna-transcription", "name": "RNA Transcription", diff --git a/exercises/practice/queen-attack/.docs/instructions.md b/exercises/practice/queen-attack/.docs/instructions.md new file mode 100644 index 0000000..97f22a0 --- /dev/null +++ b/exercises/practice/queen-attack/.docs/instructions.md @@ -0,0 +1,21 @@ +# Instructions + +Given the position of two queens on a chess board, indicate whether or not they are positioned so that they can attack each other. + +In the game of chess, a queen can attack pieces which are on the same row, column, or diagonal. + +A chessboard can be represented by an 8 by 8 array. + +So if you are told the white queen is at `c5` (zero-indexed at column 2, row 3) and the black queen at `f2` (zero-indexed at column 5, row 6), then you know that the set-up is like so: + +![A chess board with two queens. Arrows emanating from the queen at c5 indicate possible directions of capture along file, rank and diagonal.](https://assets.exercism.org/images/exercises/queen-attack/queen-capture.svg) + +You are also able to answer whether the queens can attack each other. +In this case, that answer would be yes, they can, because both pieces share a diagonal. + +## Credit + +The chessboard image was made by [habere-et-dispertire][habere-et-dispertire] using LaTeX and the [chessboard package][chessboard-package] by Ulrike Fischer. + +[habere-et-dispertire]: https://exercism.org/profiles/habere-et-dispertire +[chessboard-package]: https://github.com/u-fischer/chessboard diff --git a/exercises/practice/queen-attack/.gitignore b/exercises/practice/queen-attack/.gitignore new file mode 100644 index 0000000..6dd20ff --- /dev/null +++ b/exercises/practice/queen-attack/.gitignore @@ -0,0 +1,11 @@ +## -*- conf -*- +.rebar3 +_build/ +ebin/ +erl_crash.dump +rebar3.crashdump + +tmp +bin/configlet +bin/configlet.exe +CHECKLIST diff --git a/exercises/practice/queen-attack/.meta/config.json b/exercises/practice/queen-attack/.meta/config.json new file mode 100644 index 0000000..e5a738e --- /dev/null +++ b/exercises/practice/queen-attack/.meta/config.json @@ -0,0 +1,19 @@ +{ + "authors": [ + "BNAndras" + ], + "files": { + "solution": [ + "src/queen-attack.lfe" + ], + "test": [ + "test/queen-attack-tests.lfe" + ], + "example": [ + ".meta/example.lfe" + ] + }, + "blurb": "Given the position of two queens on a chess board, indicate whether or not they are positioned so that they can attack each other.", + "source": "J Dalbey's Programming Practice problems", + "source_url": "https://users.csc.calpoly.edu/~jdalbey/103/Projects/ProgrammingPractice.html" +} diff --git a/exercises/practice/queen-attack/.meta/example.lfe b/exercises/practice/queen-attack/.meta/example.lfe new file mode 100644 index 0000000..7e50c7f --- /dev/null +++ b/exercises/practice/queen-attack/.meta/example.lfe @@ -0,0 +1,33 @@ +(defmodule queen-attack + (export (create 2) + (can-attack 2))) + +(defrecord queen + row + column) + +(defun create + ((row column) + (when (or (or (< row 0) + (>= row 8)) + (or (< column 0) + (>= column 8)))) + 'false) + ((row column) + (make-queen row row + column column))) + +(defun can-attack + (((match-queen row R column _) + (match-queen row R column _)) + 'true) + (((match-queen row _ column C) + (match-queen row _ column C)) + 'true) + (((match-queen row WR column WC) + (match-queen row BR column BC)) + (when (=:= (abs (- WR BR)) + (abs (- WC BC)))) + 'true) + ((_ _) + 'false)) diff --git a/exercises/practice/queen-attack/.meta/tests.toml b/exercises/practice/queen-attack/.meta/tests.toml new file mode 100644 index 0000000..e062412 --- /dev/null +++ b/exercises/practice/queen-attack/.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. + +[3ac4f735-d36c-44c4-a3e2-316f79704203] +description = "Test creation of Queens with valid and invalid positions -> queen with a valid position" + +[4e812d5d-b974-4e38-9a6b-8e0492bfa7be] +description = "Test creation of Queens with valid and invalid positions -> queen must have positive row" + +[f07b7536-b66b-4f08-beb9-4d70d891d5c8] +description = "Test creation of Queens with valid and invalid positions -> queen must have row on board" + +[15a10794-36d9-4907-ae6b-e5a0d4c54ebe] +description = "Test creation of Queens with valid and invalid positions -> queen must have positive column" + +[6907762d-0e8a-4c38-87fb-12f2f65f0ce4] +description = "Test creation of Queens with valid and invalid positions -> queen must have column on board" + +[33ae4113-d237-42ee-bac1-e1e699c0c007] +description = "Test the ability of one queen to attack another -> cannot attack" + +[eaa65540-ea7c-4152-8c21-003c7a68c914] +description = "Test the ability of one queen to attack another -> can attack on same row" + +[bae6f609-2c0e-4154-af71-af82b7c31cea] +description = "Test the ability of one queen to attack another -> can attack on same column" + +[0e1b4139-b90d-4562-bd58-dfa04f1746c7] +description = "Test the ability of one queen to attack another -> can attack on first diagonal" + +[ff9b7ed4-e4b6-401b-8d16-bc894d6d3dcd] +description = "Test the ability of one queen to attack another -> can attack on second diagonal" + +[0a71e605-6e28-4cc2-aa47-d20a2e71037a] +description = "Test the ability of one queen to attack another -> can attack on third diagonal" + +[0790b588-ae73-4f1f-a968-dd0b34f45f86] +description = "Test the ability of one queen to attack another -> can attack on fourth diagonal" + +[543f8fd4-2597-4aad-8d77-cbdab63619f8] +description = "Test the ability of one queen to attack another -> cannot attack if falling diagonals are only the same when reflected across the longest falling diagonal" diff --git a/exercises/practice/queen-attack/Makefile b/exercises/practice/queen-attack/Makefile new file mode 100644 index 0000000..fbb5a7d --- /dev/null +++ b/exercises/practice/queen-attack/Makefile @@ -0,0 +1,21 @@ +ERL := $(shell which erl) +REBAR3 := $(shell which rebar3) + +null := +space := $(null) # +comma := , + +ifeq ($(ERL),) + $(error Can't find Erlang executable 'erl') +else ifeq ($(REBAR3),) + $(error Can't find rebar3) +endif + +compile: ; $(REBAR3) compile + +clean: ; $(REBAR3) clean + +.PHONY: test +test: + $(REBAR3) eunit \ + -m $(subst $(space),$(comma),$(basename $(notdir $(wildcard test/*.lfe)))) diff --git a/exercises/practice/queen-attack/rebar.config b/exercises/practice/queen-attack/rebar.config new file mode 100644 index 0000000..d53487a --- /dev/null +++ b/exercises/practice/queen-attack/rebar.config @@ -0,0 +1,11 @@ +{plugins, [{rebar3_lfe, "0.4.3"}]}. + +{provider_hooks, [{post, [{compile, {lfe, compile}}]}]}. + +{deps, [{lfe, "2.1.1"}]}. + +{profiles, + [{test, + [{eunit_compile_opts, [{src_dirs, ["src", "test"]}]}, + {deps, + [{ltest, "0.13.3"}]}]}]}. diff --git a/exercises/practice/queen-attack/rebar.lock b/exercises/practice/queen-attack/rebar.lock new file mode 100644 index 0000000..d5a6b3b --- /dev/null +++ b/exercises/practice/queen-attack/rebar.lock @@ -0,0 +1,8 @@ +{"1.2.0", +[{<<"lfe">>,{pkg,<<"lfe">>,<<"2.1.1">>},0}]}. +[ +{pkg_hash,[ + {<<"lfe">>, <<"4A888B26172D198DC7A5AFEB897E8248AF7D56E1638D9C8249AAF933AE811B96">>}]}, +{pkg_hash_ext,[ + {<<"lfe">>, <<"C484D3B655D40DED58BC41B17B22F173711C681BF36063A234A9BAA9506947E1">>}]} +]. diff --git a/exercises/practice/queen-attack/src/queen-attack.app.src b/exercises/practice/queen-attack/src/queen-attack.app.src new file mode 100644 index 0000000..3d01d98 --- /dev/null +++ b/exercises/practice/queen-attack/src/queen-attack.app.src @@ -0,0 +1,11 @@ +%% -*- erlang -*- +{application, 'queen-attack', + [{description, ""}, + {vsn, "0.0.1"}, + {modules, + ['queen-attack']}, + {registered, []}, + {applications, + [kernel, stdlib]}, + {included_applications, []}, + {env, []}]}. diff --git a/exercises/practice/queen-attack/src/queen-attack.lfe b/exercises/practice/queen-attack/src/queen-attack.lfe new file mode 100644 index 0000000..167febd --- /dev/null +++ b/exercises/practice/queen-attack/src/queen-attack.lfe @@ -0,0 +1,5 @@ +(defmodule queen-attack + (export (create 2) + (can-attack 2))) + + ; Please implement the create and can-attack functions. diff --git a/exercises/practice/queen-attack/test/queen-attack-tests.lfe b/exercises/practice/queen-attack/test/queen-attack-tests.lfe new file mode 100644 index 0000000..c6ff661 --- /dev/null +++ b/exercises/practice/queen-attack/test/queen-attack-tests.lfe @@ -0,0 +1,48 @@ +(defmodule queen-attack-tests + (behaviour ltest-unit) + (export all)) + +(include-lib "ltest/include/ltest-macros.lfe") + +(deftest queen-with-valid-position + (is-not-equal (queen-attack:create 2 2) 'false)) + +(deftest queen-must-have-positive-row + (is-not (queen-attack:create -2 2))) + +(deftest queen-must-have-row-on-board + (is-not (queen-attack:create 8 4))) + +(deftest queen-must-have-positive-column + (is-not (queen-attack:create 2 -2))) + +(deftest queen-must-have-column-on-board + (is-not (queen-attack:create 4 8))) + +(deftest two-queens-cannot-attack + (is-not (queen-attack:can-attack (queen-attack:create 2 4) + (queen-attack:create 6 6)))) + +(deftest two-queens-can-attack-on-same-column + (is (queen-attack:can-attack (queen-attack:create 4 5) + (queen-attack:create 2 5)))) + +(deftest two-queens-can-attack-on-first-diagonal + (is (queen-attack:can-attack (queen-attack:create 2 2) + (queen-attack:create 0 4)))) + +(deftest two-queens-can-attack-on-second-diagonal + (is (queen-attack:can-attack (queen-attack:create 2 2) + (queen-attack:create 3 1)))) + +(deftest two-queens-can-attack-on-third-diagonal + (is (queen-attack:can-attack (queen-attack:create 2 2) + (queen-attack:create 1 1)))) + +(deftest two-queens-can-attack-on-fourth-diagonal + (is (queen-attack:can-attack (queen-attack:create 1 7) + (queen-attack:create 0 6)))) + +(deftest two-queens-can-not-attack-if-falling-diagonals-only-same-when-reflected-along-longest-falling-diagonal + (is-not (queen-attack:can-attack (queen-attack:create 4 1) + (queen-attack:create 2 5))))