From 43a180ccec8604980d2fa4358301cc6d4874790c Mon Sep 17 00:00:00 2001 From: Erik Schierboom Date: Tue, 24 Sep 2024 11:18:32 +0200 Subject: [PATCH] Add `magic-square` exercise --- config.json | 8 +++ .../magic-square/.docs/instructions.md | 14 +++++ .../practice/magic-square/.meta/config.json | 17 ++++++ .../.meta/magic_square.example.pl | 23 ++++++++ .../practice/magic-square/magic_square.pl | 1 + .../magic-square/magic_square_tests.plt | 52 +++++++++++++++++++ 6 files changed, 115 insertions(+) create mode 100644 exercises/practice/magic-square/.docs/instructions.md create mode 100644 exercises/practice/magic-square/.meta/config.json create mode 100644 exercises/practice/magic-square/.meta/magic_square.example.pl create mode 100644 exercises/practice/magic-square/magic_square.pl create mode 100644 exercises/practice/magic-square/magic_square_tests.plt diff --git a/config.json b/config.json index 7b2f92b4..89276176 100644 --- a/config.json +++ b/config.json @@ -901,6 +901,14 @@ "practices": [], "prerequisites": [], "difficulty": 1 + }, + { + "slug": "magic-square", + "name": "Magic Square", + "uuid": "0dabf6ec-98fb-442c-9e1f-684108a67f26", + "practices": [], + "prerequisites": [], + "difficulty": 1 } ], "foregone": [ diff --git a/exercises/practice/magic-square/.docs/instructions.md b/exercises/practice/magic-square/.docs/instructions.md new file mode 100644 index 00000000..4f5cb92b --- /dev/null +++ b/exercises/practice/magic-square/.docs/instructions.md @@ -0,0 +1,14 @@ +# Instructions + +Your task is to, given a square of positive integers, determine if the square is a magic square. +A magic square is one where the sum of the numbers in each row, column and both diagonals are the same. + +As an example, consider the following square: + +```text +4 9 2 +3 5 7 +8 1 6 +``` + +This is a magic square, as the sum of every row, column and both diagonals is equal to 15. diff --git a/exercises/practice/magic-square/.meta/config.json b/exercises/practice/magic-square/.meta/config.json new file mode 100644 index 00000000..ed8ca105 --- /dev/null +++ b/exercises/practice/magic-square/.meta/config.json @@ -0,0 +1,17 @@ +{ + "authors": [ + "erikschierboom" + ], + "files": { + "solution": [ + "magic_square.pl" + ], + "test": [ + "magic_square_tests.plt" + ], + "example": [ + ".meta/magic_square.example.pl" + ] + }, + "blurb": "Check if a square is a magic square" +} diff --git a/exercises/practice/magic-square/.meta/magic_square.example.pl b/exercises/practice/magic-square/.meta/magic_square.example.pl new file mode 100644 index 00000000..81defa59 --- /dev/null +++ b/exercises/practice/magic-square/.meta/magic_square.example.pl @@ -0,0 +1,23 @@ +:- use_module(library(clpfd)). + +diagonals(Rows, LeftRightDiagonal, RightLeftDiagonal) :- + length(Rows, N), + numlist(1, N, Indices), + reverse(Indices, ReverseIndices), + pairs_keys_values(LeftRightIndices, Indices, Indices), + pairs_keys_values(RightLeftIndices, ReverseIndices, Indices), + maplist(diagonal_element(Rows), LeftRightIndices, LeftRightDiagonal), + maplist(diagonal_element(Rows), RightLeftIndices, RightLeftDiagonal). + +diagonal_element(Rows, X-Y, Value) :- nth1(Y, Rows, Row), nth1(X, Row, Value). + +magic_square(Rows) :- + maplist(sumlist, Rows, RowSums), + transpose(Rows, Cols), + maplist(sumlist, Cols, ColSums), + diagonals(Rows, LeftRightDiagonal, RightLeftDiagonal), + sumlist(LeftRightDiagonal, LeftRightDiagonalSum), + sumlist(RightLeftDiagonal, RightLeftDiagonalSum), + append([RowSums, ColSums, [LeftRightDiagonalSum, RightLeftDiagonalSum]], Sums), + sort(Sums, SortedSums), + length(SortedSums, 1). diff --git a/exercises/practice/magic-square/magic_square.pl b/exercises/practice/magic-square/magic_square.pl new file mode 100644 index 00000000..d526c769 --- /dev/null +++ b/exercises/practice/magic-square/magic_square.pl @@ -0,0 +1 @@ +magic_square(Rows). diff --git a/exercises/practice/magic-square/magic_square_tests.plt b/exercises/practice/magic-square/magic_square_tests.plt new file mode 100644 index 00000000..bb517f5c --- /dev/null +++ b/exercises/practice/magic-square/magic_square_tests.plt @@ -0,0 +1,52 @@ +pending :- + current_prolog_flag(argv, ['--all'|_]). +pending :- + write('\nA TEST IS PENDING!\n'), + fail. + +:- begin_tests(magic_square). + + test(magic_square_order_3, condition(true)) :- + Square = + [ + [2, 7, 6], + [9, 5, 1], + [4, 3, 8] + ], + magic_square(Square). + + test(magic_square_order_4, condition(pending)) :- + Square = + [ + [ 2, 16, 13, 3], + [11, 5, 8, 10], + [ 7, 9, 12, 6], + [14, 4, 1, 15] + ], + magic_square(Square). + + test(magic_square_order_9, condition(pending)) :- + Square = + [ + [31, 76, 13, 36, 81, 18, 29, 74, 11], + [22, 40, 58, 27, 45, 63, 20, 38, 56], + [67, 4, 49, 72, 9, 54, 65, 2, 47], + [30, 75, 12, 32, 77, 14, 34, 79, 16], + [21, 39, 57, 23, 41, 59, 25, 43, 61], + [66, 3, 48, 68, 5, 50, 70, 7, 52], + [35, 80, 17, 28, 73, 10, 33, 78, 15], + [26, 44, 62, 19, 37, 55, 24, 42, 60], + [71, 8, 53, 64, 1, 46, 69, 6, 51] + ], + magic_square(Square). + + test(invalid_magic_square, [fail, condition(pending)]) :- + Square = + [ + [1, 2, 3], + [4, 5, 6], + [7, 8, 9] + ], + magic_square(Square). + +:- end_tests(magic_square).