From 8c8ba5f78fbe0a7716979ac4f0c1bfcd4c21ca8d Mon Sep 17 00:00:00 2001 From: Erik Schierboom Date: Wed, 29 May 2024 01:56:59 +0200 Subject: [PATCH] Add `largest-series-product` exercise (#54) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Add `largest-series-product` exercise * Add special handing for zero span or empty string * Handle negative span --------- Co-authored-by: András B Nagy <20251272+BNAndras@users.noreply.github.com> --- config.json | 8 ++ .../.docs/instructions.md | 26 ++++++ .../.docs/introduction.md | 5 ++ .../largest-series-product/.meta/config.json | 19 +++++ .../.meta/src/example.art | 13 +++ .../largest-series-product/.meta/tests.toml | 60 ++++++++++++++ .../src/largest-series-product.art | 3 + .../largest-series-product/tester.art | 3 + .../tests/test-largest-series-product.art | 79 +++++++++++++++++++ 9 files changed, 216 insertions(+) create mode 100644 exercises/practice/largest-series-product/.docs/instructions.md create mode 100644 exercises/practice/largest-series-product/.docs/introduction.md create mode 100644 exercises/practice/largest-series-product/.meta/config.json create mode 100644 exercises/practice/largest-series-product/.meta/src/example.art create mode 100644 exercises/practice/largest-series-product/.meta/tests.toml create mode 100644 exercises/practice/largest-series-product/src/largest-series-product.art create mode 100644 exercises/practice/largest-series-product/tester.art create mode 100644 exercises/practice/largest-series-product/tests/test-largest-series-product.art diff --git a/config.json b/config.json index d6fc8c8..97ab34a 100644 --- a/config.json +++ b/config.json @@ -227,6 +227,14 @@ "practices": [], "prerequisites": [], "difficulty": 2 + }, + { + "slug": "largest-series-product", + "name": "Largest Series Product", + "uuid": "01180cdd-556c-4476-a71f-083628265000", + "practices": [], + "prerequisites": [], + "difficulty": 3 } ] }, diff --git a/exercises/practice/largest-series-product/.docs/instructions.md b/exercises/practice/largest-series-product/.docs/instructions.md new file mode 100644 index 0000000..f297b57 --- /dev/null +++ b/exercises/practice/largest-series-product/.docs/instructions.md @@ -0,0 +1,26 @@ +# Instructions + +Your task is to look for patterns in the long sequence of digits in the encrypted signal. + +The technique you're going to use here is called the largest series product. + +Let's define a few terms, first. + +- **input**: the sequence of digits that you need to analyze +- **series**: a sequence of adjacent digits (those that are next to each other) that is contained within the input +- **span**: how many digits long each series is +- **product**: what you get when you multiply numbers together + +Let's work through an example, with the input `"63915"`. + +- To form a series, take adjacent digits in the original input. +- If you are working with a span of `3`, there will be three possible series: + - `"639"` + - `"391"` + - `"915"` +- Then we need to calculate the product of each series: + - The product of the series `"639"` is 162 (`6 × 3 × 9 = 162`) + - The product of the series `"391"` is 27 (`3 × 9 × 1 = 27`) + - The product of the series `"915"` is 45 (`9 × 1 × 5 = 45`) +- 162 is bigger than both 27 and 45, so the largest series product of `"63915"` is from the series `"639"`. + So the answer is **162**. diff --git a/exercises/practice/largest-series-product/.docs/introduction.md b/exercises/practice/largest-series-product/.docs/introduction.md new file mode 100644 index 0000000..597bb5f --- /dev/null +++ b/exercises/practice/largest-series-product/.docs/introduction.md @@ -0,0 +1,5 @@ +# Introduction + +You work for a government agency that has intercepted a series of encrypted communication signals from a group of bank robbers. +The signals contain a long sequence of digits. +Your team needs to use various digital signal processing techniques to analyze the signals and identify any patterns that may indicate the planning of a heist. diff --git a/exercises/practice/largest-series-product/.meta/config.json b/exercises/practice/largest-series-product/.meta/config.json new file mode 100644 index 0000000..707205a --- /dev/null +++ b/exercises/practice/largest-series-product/.meta/config.json @@ -0,0 +1,19 @@ +{ + "authors": [ + "erikschierboom" + ], + "files": { + "solution": [ + "src/largest-series-product.art" + ], + "test": [ + "tests/test-largest-series-product.art" + ], + "example": [ + ".meta/src/example.art" + ] + }, + "blurb": "Given a string of digits, calculate the largest product for a contiguous substring of digits of length n.", + "source": "A variation on Problem 8 at Project Euler", + "source_url": "https://projecteuler.net/problem=8" +} diff --git a/exercises/practice/largest-series-product/.meta/src/example.art b/exercises/practice/largest-series-product/.meta/src/example.art new file mode 100644 index 0000000..e2f88d7 --- /dev/null +++ b/exercises/practice/largest-series-product/.meta/src/example.art @@ -0,0 +1,13 @@ +slices: function [arr span][ + numSlices: (size arr) - span + map 0..numSlices 'i -> slice arr i (i + span - 1) +] + +largestProduct: function [str span][ + if span > size str -> return null + if negative? span -> return null + unless match? str {/^\d*$/} -> return null + if or? empty? str zero? span -> return 1 + + max map (slices (digits (to :integer str)) span) => product +] diff --git a/exercises/practice/largest-series-product/.meta/tests.toml b/exercises/practice/largest-series-product/.meta/tests.toml new file mode 100644 index 0000000..6c111ad --- /dev/null +++ b/exercises/practice/largest-series-product/.meta/tests.toml @@ -0,0 +1,60 @@ +# 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. + +[7c82f8b7-e347-48ee-8a22-f672323324d4] +description = "finds the largest product if span equals length" + +[88523f65-21ba-4458-a76a-b4aaf6e4cb5e] +description = "can find the largest product of 2 with numbers in order" + +[f1376b48-1157-419d-92c2-1d7e36a70b8a] +description = "can find the largest product of 2" + +[46356a67-7e02-489e-8fea-321c2fa7b4a4] +description = "can find the largest product of 3 with numbers in order" + +[a2dcb54b-2b8f-4993-92dd-5ce56dece64a] +description = "can find the largest product of 3" + +[673210a3-33cd-4708-940b-c482d7a88f9d] +description = "can find the largest product of 5 with numbers in order" + +[02acd5a6-3bbf-46df-8282-8b313a80a7c9] +description = "can get the largest product of a big number" + +[76dcc407-21e9-424c-a98e-609f269622b5] +description = "reports zero if the only digits are zero" + +[6ef0df9f-52d4-4a5d-b210-f6fae5f20e19] +description = "reports zero if all spans include zero" + +[5d81aaf7-4f67-4125-bf33-11493cc7eab7] +description = "rejects span longer than string length" + +[06bc8b90-0c51-4c54-ac22-3ec3893a079e] +description = "reports 1 for empty string and empty product (0 span)" + +[3ec0d92e-f2e2-4090-a380-70afee02f4c0] +description = "reports 1 for nonempty string and empty product (0 span)" + +[6d96c691-4374-4404-80ee-2ea8f3613dd4] +description = "rejects empty string and nonzero span" + +[7a38f2d6-3c35-45f6-8d6f-12e6e32d4d74] +description = "rejects invalid character in digits" + +[5fe3c0e5-a945-49f2-b584-f0814b4dd1ef] +description = "rejects negative span" +include = false + +[c859f34a-9bfe-4897-9c2f-6d7f8598e7f0] +description = "rejects negative span" +reimplements = "5fe3c0e5-a945-49f2-b584-f0814b4dd1ef" diff --git a/exercises/practice/largest-series-product/src/largest-series-product.art b/exercises/practice/largest-series-product/src/largest-series-product.art new file mode 100644 index 0000000..b6b4f62 --- /dev/null +++ b/exercises/practice/largest-series-product/src/largest-series-product.art @@ -0,0 +1,3 @@ +largestProduct: function [str span][ + panic "Please implement the largestProduct function" +] diff --git a/exercises/practice/largest-series-product/tester.art b/exercises/practice/largest-series-product/tester.art new file mode 100644 index 0000000..80f4a8f --- /dev/null +++ b/exercises/practice/largest-series-product/tester.art @@ -0,0 +1,3 @@ +import {unitt}! + +runTests.failFast findTests "tests" diff --git a/exercises/practice/largest-series-product/tests/test-largest-series-product.art b/exercises/practice/largest-series-product/tests/test-largest-series-product.art new file mode 100644 index 0000000..fa8be0d --- /dev/null +++ b/exercises/practice/largest-series-product/tests/test-largest-series-product.art @@ -0,0 +1,79 @@ +import {unitt}! +import {src/largest-series-product}! + +suite "Largest Series Product" [ + test "finds the largest product if span equals length" [ + result: largestProduct "29" 2 + assert -> 18 = result + ] + + test.skip "can find the largest product of 2 with numbers in order" [ + result: largestProduct "0123456789" 2 + assert -> 72 = result + ] + + test.skip "can find the largest product of 2" [ + result: largestProduct "576802143" 2 + assert -> 48 = result + ] + + test.skip "can find the largest product of 3 with numbers in order" [ + result: largestProduct "0123456789" 3 + assert -> 504 = result + ] + + test.skip "can find the largest product of 3" [ + result: largestProduct "1027839564" 3 + assert -> 270 = result + ] + + test.skip "can find the largest product of 5 with numbers in order" [ + result: largestProduct "0123456789" 5 + assert -> 15120 = result + ] + + test.skip "can get the largest product of a big number" [ + result: largestProduct "73167176531330624919225119674426574742355349194934" 6 + assert -> 23520 = result + ] + + test.skip "reports zero if the only digits are zero" [ + result: largestProduct "0000" 2 + assert -> 0 = result + ] + + test.skip "reports zero if all spans include zero" [ + result: largestProduct "99099" 3 + assert -> 0 = result + ] + + test.skip "rejects span longer than string length" [ + result: largestProduct "123" 4 + assert -> null = result + ] + + test.skip "reports 1 for empty string and empty product (0 span)" [ + result: largestProduct "" 0 + assert -> 1 = result + ] + + test.skip "reports 1 for nonempty string and empty product (0 span)" [ + result: largestProduct "123" 0 + assert -> 1 = result + ] + + test.skip "rejects empty string and nonzero span" [ + result: largestProduct "" 1 + assert -> null = result + ] + + test.skip "rejects invalid character in digits" [ + result: largestProduct "1234a5" 2 + assert -> null = result + ] + + test.skip "rejects negative span" [ + result: largestProduct "12345" neg 1 + assert -> null = result + ] +]