diff --git a/config.json b/config.json index ee605c1b..b25ef53a 100644 --- a/config.json +++ b/config.json @@ -481,7 +481,16 @@ "prerequisites": [], "difficulty": 1, "topics": [] - } + }, + { + "slug": "largest-series-product", + "name": "Largest Series Product", + "uuid": "762a6196-6185-46d1-aa97-0c245db8e981", + "practices": [], + "prerequisites": [], + "difficulty": 1, + "topics": [] + } ] }, "concepts": [], 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 00000000..f297b57f --- /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 00000000..597bb5fa --- /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 00000000..4fd0f9f3 --- /dev/null +++ b/exercises/practice/largest-series-product/.meta/config.json @@ -0,0 +1,19 @@ +{ + "authors": [ + "habere-et-dispertire" + ], + "files": { + "solution": [ + "LargestSeriesProduct.rakumod" + ], + "test": [ + "largest-series-product.rakutest" + ], + "example": [ + ".meta/solutions/LargestSeriesProduct.rakumod" + ] + }, + "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/solutions/LargestSeriesProduct.rakumod b/exercises/practice/largest-series-product/.meta/solutions/LargestSeriesProduct.rakumod new file mode 100644 index 00000000..12c55a59 --- /dev/null +++ b/exercises/practice/largest-series-product/.meta/solutions/LargestSeriesProduct.rakumod @@ -0,0 +1,11 @@ +proto largest-product (|) is export {*} +multi largest-product ( $n, 0 ) { 1 } +multi largest-product ( $n, Int $span where 1 .. $n.chars ) { + + $n + .comb + .rotor( $span => - $span.pred ) + .map( *.reduce: &[*] ) + .max + +} diff --git a/exercises/practice/largest-series-product/.meta/solutions/largest-series-product.rakutest b/exercises/practice/largest-series-product/.meta/solutions/largest-series-product.rakutest new file mode 120000 index 00000000..022b9ec9 --- /dev/null +++ b/exercises/practice/largest-series-product/.meta/solutions/largest-series-product.rakutest @@ -0,0 +1 @@ +../../largest-series-product.rakutest \ No newline at end of file diff --git a/exercises/practice/largest-series-product/.meta/template-data.yaml b/exercises/practice/largest-series-product/.meta/template-data.yaml new file mode 100644 index 00000000..78c98498 --- /dev/null +++ b/exercises/practice/largest-series-product/.meta/template-data.yaml @@ -0,0 +1,38 @@ +properties: + largestProduct: + test: |- + if %case:exists { + sprintf(q:to/END/, (%case, %case, %case).map(*.raku)); + dies-ok( + { largest-product(%s, %s) }, + %s, + ); + END + } + else { + sprintf(q:to/END/, (%case, %case, %case, %case).map(*.raku)); + cmp-ok( + largest-product(%s, %s), + &infix:<==>, + %s, + %s, + ); + END + } + +example: |- + proto largest-product (|) is export {*} + multi largest-product ( $n, 0 ) { 1 } + multi largest-product ( $n, Int $span where 1 .. $n.chars ) { + + $n + .comb + .rotor( $span => - $span.pred ) + .map( *.reduce: &[*] ) + .max + + } + +stub: |- + sub largest-product ($number, $span) is export { + } 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 00000000..6c111adf --- /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/LargestSeriesProduct.rakumod b/exercises/practice/largest-series-product/LargestSeriesProduct.rakumod new file mode 100644 index 00000000..dff856b7 --- /dev/null +++ b/exercises/practice/largest-series-product/LargestSeriesProduct.rakumod @@ -0,0 +1,2 @@ +sub largest-product ($number, $span) is export { +} diff --git a/exercises/practice/largest-series-product/largest-series-product.rakutest b/exercises/practice/largest-series-product/largest-series-product.rakutest new file mode 100755 index 00000000..761b9d12 --- /dev/null +++ b/exercises/practice/largest-series-product/largest-series-product.rakutest @@ -0,0 +1,103 @@ +#!/usr/bin/env raku +use Test; +use lib $?FILE.IO.dirname; +use LargestSeriesProduct; + +cmp-ok( # begin: 7c82f8b7-e347-48ee-8a22-f672323324d4 + largest-product("29", 2), + &infix:<==>, + 18, + "finds the largest product if span equals length", +); # end: 7c82f8b7-e347-48ee-8a22-f672323324d4 + +cmp-ok( # begin: 88523f65-21ba-4458-a76a-b4aaf6e4cb5e + largest-product("0123456789", 2), + &infix:<==>, + 72, + "can find the largest product of 2 with numbers in order", +); # end: 88523f65-21ba-4458-a76a-b4aaf6e4cb5e + +cmp-ok( # begin: f1376b48-1157-419d-92c2-1d7e36a70b8a + largest-product("576802143", 2), + &infix:<==>, + 48, + "can find the largest product of 2", +); # end: f1376b48-1157-419d-92c2-1d7e36a70b8a + +cmp-ok( # begin: 46356a67-7e02-489e-8fea-321c2fa7b4a4 + largest-product("0123456789", 3), + &infix:<==>, + 504, + "can find the largest product of 3 with numbers in order", +); # end: 46356a67-7e02-489e-8fea-321c2fa7b4a4 + +cmp-ok( # begin: a2dcb54b-2b8f-4993-92dd-5ce56dece64a + largest-product("1027839564", 3), + &infix:<==>, + 270, + "can find the largest product of 3", +); # end: a2dcb54b-2b8f-4993-92dd-5ce56dece64a + +cmp-ok( # begin: 673210a3-33cd-4708-940b-c482d7a88f9d + largest-product("0123456789", 5), + &infix:<==>, + 15120, + "can find the largest product of 5 with numbers in order", +); # end: 673210a3-33cd-4708-940b-c482d7a88f9d + +cmp-ok( # begin: 02acd5a6-3bbf-46df-8282-8b313a80a7c9 + largest-product("73167176531330624919225119674426574742355349194934", 6), + &infix:<==>, + 23520, + "can get the largest product of a big number", +); # end: 02acd5a6-3bbf-46df-8282-8b313a80a7c9 + +cmp-ok( # begin: 76dcc407-21e9-424c-a98e-609f269622b5 + largest-product("0000", 2), + &infix:<==>, + 0, + "reports zero if the only digits are zero", +); # end: 76dcc407-21e9-424c-a98e-609f269622b5 + +cmp-ok( # begin: 6ef0df9f-52d4-4a5d-b210-f6fae5f20e19 + largest-product("99099", 3), + &infix:<==>, + 0, + "reports zero if all spans include zero", +); # end: 6ef0df9f-52d4-4a5d-b210-f6fae5f20e19 + +dies-ok( # begin: 5d81aaf7-4f67-4125-bf33-11493cc7eab7 + { largest-product("123", 4) }, + "rejects span longer than string length", +); # end: 5d81aaf7-4f67-4125-bf33-11493cc7eab7 + +cmp-ok( # begin: 06bc8b90-0c51-4c54-ac22-3ec3893a079e + largest-product("", 0), + &infix:<==>, + 1, + "reports 1 for empty string and empty product (0 span)", +); # end: 06bc8b90-0c51-4c54-ac22-3ec3893a079e + +cmp-ok( # begin: 3ec0d92e-f2e2-4090-a380-70afee02f4c0 + largest-product("123", 0), + &infix:<==>, + 1, + "reports 1 for nonempty string and empty product (0 span)", +); # end: 3ec0d92e-f2e2-4090-a380-70afee02f4c0 + +dies-ok( # begin: 6d96c691-4374-4404-80ee-2ea8f3613dd4 + { largest-product("", 1) }, + "rejects empty string and nonzero span", +); # end: 6d96c691-4374-4404-80ee-2ea8f3613dd4 + +dies-ok( # begin: 7a38f2d6-3c35-45f6-8d6f-12e6e32d4d74 + { largest-product("1234a5", 2) }, + "rejects invalid character in digits", +); # end: 7a38f2d6-3c35-45f6-8d6f-12e6e32d4d74 + +dies-ok( # begin: c859f34a-9bfe-4897-9c2f-6d7f8598e7f0 + { largest-product("12345", -1) }, + "rejects negative span", +); # end: c859f34a-9bfe-4897-9c2f-6d7f8598e7f0 + +done-testing;