From 31be58dd0e21712c53a6946d61ffe851886d6c1b Mon Sep 17 00:00:00 2001 From: habere-et-dispertire Date: Mon, 26 May 2025 20:44:27 +0100 Subject: [PATCH 1/2] [ Implementation ] OCR Numbers Uses heredocs to make tests easier to read. -- https://forum.exercism.org/t/new-exercise-contributions/4077 --- config.json | 8 + .../ocr-numbers/.docs/instructions.md | 79 ++++++ .../practice/ocr-numbers/.meta/config.json | 19 ++ .../.meta/solutions/lib/OcrNumbers.rakumod | 32 +++ .../.meta/solutions/t/ocr-numbers.rakutest | 1 + .../ocr-numbers/.meta/template-data.yaml | 65 +++++ .../practice/ocr-numbers/.meta/tests.toml | 61 +++++ .../ocr-numbers/lib/OcrNumbers.rakumod | 4 + .../ocr-numbers/t/ocr-numbers.rakutest | 234 ++++++++++++++++++ 9 files changed, 503 insertions(+) create mode 100644 exercises/practice/ocr-numbers/.docs/instructions.md create mode 100644 exercises/practice/ocr-numbers/.meta/config.json create mode 100644 exercises/practice/ocr-numbers/.meta/solutions/lib/OcrNumbers.rakumod create mode 120000 exercises/practice/ocr-numbers/.meta/solutions/t/ocr-numbers.rakutest create mode 100644 exercises/practice/ocr-numbers/.meta/template-data.yaml create mode 100644 exercises/practice/ocr-numbers/.meta/tests.toml create mode 100644 exercises/practice/ocr-numbers/lib/OcrNumbers.rakumod create mode 100755 exercises/practice/ocr-numbers/t/ocr-numbers.rakutest diff --git a/config.json b/config.json index bd490879..193f0a7e 100644 --- a/config.json +++ b/config.json @@ -759,6 +759,14 @@ "practices": [], "prerequisites": [], "difficulty": 1 + }, + { + "slug": "ocr-numbers", + "name": "OCR Numbers", + "uuid": "00f7b37c-b460-47ed-949e-d62469d8d6d5", + "practices": [], + "prerequisites": [], + "difficulty": 1 } ] }, diff --git a/exercises/practice/ocr-numbers/.docs/instructions.md b/exercises/practice/ocr-numbers/.docs/instructions.md new file mode 100644 index 00000000..7beb2577 --- /dev/null +++ b/exercises/practice/ocr-numbers/.docs/instructions.md @@ -0,0 +1,79 @@ +# Instructions + +Given a 3 x 4 grid of pipes, underscores, and spaces, determine which number is represented, or whether it is garbled. + +## Step One + +To begin with, convert a simple binary font to a string containing 0 or 1. + +The binary font uses pipes and underscores, four rows high and three columns wide. + +```text + _ # + | | # zero. + |_| # + # the fourth row is always blank +``` + +Is converted to "0" + +```text + # + | # one. + | # + # (blank fourth row) +``` + +Is converted to "1" + +If the input is the correct size, but not recognizable, your program should return '?' + +If the input is the incorrect size, your program should return an error. + +## Step Two + +Update your program to recognize multi-character binary strings, replacing garbled numbers with ? + +## Step Three + +Update your program to recognize all numbers 0 through 9, both individually and as part of a larger string. + +```text + _ + _| +|_ + +``` + +Is converted to "2" + +```text + _ _ _ _ _ _ _ _ # + | _| _||_||_ |_ ||_||_|| | # decimal numbers. + ||_ _| | _||_| ||_| _||_| # + # fourth line is always blank +``` + +Is converted to "1234567890" + +## Step Four + +Update your program to handle multiple numbers, one per line. +When converting several lines, join the lines with commas. + +```text + _ _ + | _| _| + ||_ _| + + _ _ +|_||_ |_ + | _||_| + + _ _ _ + ||_||_| + ||_| _| + +``` + +Is converted to "123,456,789". diff --git a/exercises/practice/ocr-numbers/.meta/config.json b/exercises/practice/ocr-numbers/.meta/config.json new file mode 100644 index 00000000..0eac2476 --- /dev/null +++ b/exercises/practice/ocr-numbers/.meta/config.json @@ -0,0 +1,19 @@ +{ + "authors": [ + "habere-et-dispertire" + ], + "files": { + "solution": [ + "lib/OcrNumbers.rakumod" + ], + "test": [ + "t/ocr-numbers.rakutest" + ], + "example": [ + ".meta/solutions/lib/OcrNumbers.rakumod" + ] + }, + "blurb": "Given a 3 x 4 grid of pipes, underscores, and spaces, determine which number is represented, or whether it is garbled.", + "source": "Inspired by the Bank OCR kata", + "source_url": "https://codingdojo.org/kata/BankOCR/" +} diff --git a/exercises/practice/ocr-numbers/.meta/solutions/lib/OcrNumbers.rakumod b/exercises/practice/ocr-numbers/.meta/solutions/lib/OcrNumbers.rakumod new file mode 100644 index 00000000..21de4c25 --- /dev/null +++ b/exercises/practice/ocr-numbers/.meta/solutions/lib/OcrNumbers.rakumod @@ -0,0 +1,32 @@ +unit module OcrNumbers; + +my role X::OCR is Exception {} +my class X::OCR::Invalid-Lines does X::OCR { + method message { 'Number of input lines is not a multiple of four' } +} +my class X::OCR::Invalid-Columns does X::OCR { + method message { 'Number of input columns is not a multiple of three' } +} +multi ascii-to-digits ( $art where .lines.elems !%% 4 ) is export { + X::OCR::Invalid-Lines.new.throw +} +multi ascii-to-digits ( $art where .lines.map( *.chars ).any !%% 3 ) is export { + X::OCR::Invalid-Columns.new.throw +} +multi ascii-to-digits ( $art ) is export { + constant $NUMBERS = q:to/END/; + _ _ _ _ _ _ _ _ + | | | _| _||_||_ |_ ||_||_| + |_| ||_ _| | _||_| ||_| _| + + END + constant %LOOKUP = ^10 RZ=> ( map *.join( "\n" ), zip $NUMBERS.lines.map( *.comb ).map: *.rotor: 3 ); + + join ',', gather for $art.lines.rotor: 4 { + take join '', + map { .defined ?? $_ !! '?' }, + %LOOKUP{ + map *.join( "\n" ), zip .map( *.comb ).map: *.rotor: 3 + } + } +} diff --git a/exercises/practice/ocr-numbers/.meta/solutions/t/ocr-numbers.rakutest b/exercises/practice/ocr-numbers/.meta/solutions/t/ocr-numbers.rakutest new file mode 120000 index 00000000..62ad55fe --- /dev/null +++ b/exercises/practice/ocr-numbers/.meta/solutions/t/ocr-numbers.rakutest @@ -0,0 +1 @@ +../../../t/ocr-numbers.rakutest \ No newline at end of file diff --git a/exercises/practice/ocr-numbers/.meta/template-data.yaml b/exercises/practice/ocr-numbers/.meta/template-data.yaml new file mode 100644 index 00000000..f147a3d4 --- /dev/null +++ b/exercises/practice/ocr-numbers/.meta/template-data.yaml @@ -0,0 +1,65 @@ +properties: + convert: + test: |- + if %case:exists { + sprintf(q :to/END/, "\n " ~ %case.join("\n ").Str, %case.Str, %case.raku); + throws-like( { + ascii-to-digits(q:to/ROAST/)%s + ROAST + }, + Exception, + message => '%s', + %s, + ); + END + } + else { + sprintf(q :to/END/, "\n " ~ %case.join("\n ").Str, %case.Str, %case.raku); + cmp-ok( + ascii-to-digits(q:to/ROAST/)%s + ROAST + , + 'eq', + '%s', + %s, + ); + END + } + +unit: module +example: |- + my role X::OCR is Exception {} + my class X::OCR::Invalid-Lines does X::OCR { + method message { 'Number of input lines is not a multiple of four' } + } + my class X::OCR::Invalid-Columns does X::OCR { + method message { 'Number of input columns is not a multiple of three' } + } + multi ascii-to-digits ( $art where .lines.elems !%% 4 ) is export { + X::OCR::Invalid-Lines.new.throw + } + multi ascii-to-digits ( $art where .lines.map( *.chars ).any !%% 3 ) is export { + X::OCR::Invalid-Columns.new.throw + } + multi ascii-to-digits ( $art ) is export { + constant $NUMBERS = q:to/END/; + _ _ _ _ _ _ _ _ + | | | _| _||_||_ |_ ||_||_| + |_| ||_ _| | _||_| ||_| _| + + END + constant %LOOKUP = ^10 RZ=> ( map *.join( "\n" ), zip $NUMBERS.lines.map( *.comb ).map: *.rotor: 3 ); + + join ',', gather for $art.lines.rotor: 4 { + take join '', + map { .defined ?? $_ !! '?' }, + %LOOKUP{ + map *.join( "\n" ), zip .map( *.comb ).map: *.rotor: 3 + } + } + } + +stub: |- + sub ascii-to-digits ( $art ) is export { + } + diff --git a/exercises/practice/ocr-numbers/.meta/tests.toml b/exercises/practice/ocr-numbers/.meta/tests.toml new file mode 100644 index 00000000..0d7a5b77 --- /dev/null +++ b/exercises/practice/ocr-numbers/.meta/tests.toml @@ -0,0 +1,61 @@ +# 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. + +[5ee54e1a-b554-4bf3-a056-9a7976c3f7e8] +description = "Recognizes 0" + +[027ada25-17fd-4d78-aee6-35a19623639d] +description = "Recognizes 1" + +[3cce2dbd-01d9-4f94-8fae-419a822e89bb] +description = "Unreadable but correctly sized inputs return ?" + +[cb19b733-4e36-4cf9-a4a1-6e6aac808b9a] +description = "Input with a number of lines that is not a multiple of four raises an error" + +[235f7bd1-991b-4587-98d4-84206eec4cc6] +description = "Input with a number of columns that is not a multiple of three raises an error" + +[4a841794-73c9-4da9-a779-1f9837faff66] +description = "Recognizes 110101100" + +[70c338f9-85b1-4296-a3a8-122901cdfde8] +description = "Garbled numbers in a string are replaced with ?" + +[ea494ff4-3610-44d7-ab7e-72fdef0e0802] +description = "Recognizes 2" + +[1acd2c00-412b-4268-93c2-bd7ff8e05a2c] +description = "Recognizes 3" + +[eaec6a15-be17-4b6d-b895-596fae5d1329] +description = "Recognizes 4" + +[440f397a-f046-4243-a6ca-81ab5406c56e] +description = "Recognizes 5" + +[f4c9cf6a-f1e2-4878-bfc3-9b85b657caa0] +description = "Recognizes 6" + +[e24ebf80-c611-41bb-a25a-ac2c0f232df5] +description = "Recognizes 7" + +[b79cad4f-e264-4818-9d9e-77766792e233] +description = "Recognizes 8" + +[5efc9cfc-9227-4688-b77d-845049299e66] +description = "Recognizes 9" + +[f60cb04a-42be-494e-a535-3451c8e097a4] +description = "Recognizes string of decimal numbers" + +[b73ecf8b-4423-4b36-860d-3710bdb8a491] +description = "Numbers separated by empty lines are recognized. Lines are joined by commas." diff --git a/exercises/practice/ocr-numbers/lib/OcrNumbers.rakumod b/exercises/practice/ocr-numbers/lib/OcrNumbers.rakumod new file mode 100644 index 00000000..0719668d --- /dev/null +++ b/exercises/practice/ocr-numbers/lib/OcrNumbers.rakumod @@ -0,0 +1,4 @@ +unit module OcrNumbers; + +sub ascii-to-digits ( $art ) is export { +} diff --git a/exercises/practice/ocr-numbers/t/ocr-numbers.rakutest b/exercises/practice/ocr-numbers/t/ocr-numbers.rakutest new file mode 100755 index 00000000..2caacb04 --- /dev/null +++ b/exercises/practice/ocr-numbers/t/ocr-numbers.rakutest @@ -0,0 +1,234 @@ +#!/usr/bin/env raku +use Test; +use lib $?FILE.IO.parent(2).add('lib'); +use OcrNumbers; + +cmp-ok( # begin: 5ee54e1a-b554-4bf3-a056-9a7976c3f7e8 + ascii-to-digits(q:to/ROAST/) + _ + | | + |_| + + ROAST + , + 'eq', + '0', + "Recognizes 0", +); # end: 5ee54e1a-b554-4bf3-a056-9a7976c3f7e8 + +cmp-ok( # begin: 027ada25-17fd-4d78-aee6-35a19623639d + ascii-to-digits(q:to/ROAST/) + + | + | + + ROAST + , + 'eq', + '1', + "Recognizes 1", +); # end: 027ada25-17fd-4d78-aee6-35a19623639d + +cmp-ok( # begin: 3cce2dbd-01d9-4f94-8fae-419a822e89bb + ascii-to-digits(q:to/ROAST/) + + _ + | + + ROAST + , + 'eq', + '?', + "Unreadable but correctly sized inputs return ?", +); # end: 3cce2dbd-01d9-4f94-8fae-419a822e89bb + +throws-like( { # begin: cb19b733-4e36-4cf9-a4a1-6e6aac808b9a + ascii-to-digits(q:to/ROAST/) + _ + | | + + ROAST + }, + Exception, + message => 'Number of input lines is not a multiple of four', + "Input with a number of lines that is not a multiple of four raises an error", +); # end: cb19b733-4e36-4cf9-a4a1-6e6aac808b9a + +throws-like( { # begin: 235f7bd1-991b-4587-98d4-84206eec4cc6 + ascii-to-digits(q:to/ROAST/) + + | + | + + ROAST + }, + Exception, + message => 'Number of input columns is not a multiple of three', + "Input with a number of columns that is not a multiple of three raises an error", +); # end: 235f7bd1-991b-4587-98d4-84206eec4cc6 + +cmp-ok( # begin: 4a841794-73c9-4da9-a779-1f9837faff66 + ascii-to-digits(q:to/ROAST/) + _ _ _ _ + | || | || | | || || | + | ||_| ||_| | ||_||_| + + ROAST + , + 'eq', + '110101100', + "Recognizes 110101100", +); # end: 4a841794-73c9-4da9-a779-1f9837faff66 + +cmp-ok( # begin: 70c338f9-85b1-4296-a3a8-122901cdfde8 + ascii-to-digits(q:to/ROAST/) + _ _ _ + | || | || | || || | + | | _| ||_| | ||_||_| + + ROAST + , + 'eq', + '11?10?1?0', + "Garbled numbers in a string are replaced with ?", +); # end: 70c338f9-85b1-4296-a3a8-122901cdfde8 + +cmp-ok( # begin: ea494ff4-3610-44d7-ab7e-72fdef0e0802 + ascii-to-digits(q:to/ROAST/) + _ + _| + |_ + + ROAST + , + 'eq', + '2', + "Recognizes 2", +); # end: ea494ff4-3610-44d7-ab7e-72fdef0e0802 + +cmp-ok( # begin: 1acd2c00-412b-4268-93c2-bd7ff8e05a2c + ascii-to-digits(q:to/ROAST/) + _ + _| + _| + + ROAST + , + 'eq', + '3', + "Recognizes 3", +); # end: 1acd2c00-412b-4268-93c2-bd7ff8e05a2c + +cmp-ok( # begin: eaec6a15-be17-4b6d-b895-596fae5d1329 + ascii-to-digits(q:to/ROAST/) + + |_| + | + + ROAST + , + 'eq', + '4', + "Recognizes 4", +); # end: eaec6a15-be17-4b6d-b895-596fae5d1329 + +cmp-ok( # begin: 440f397a-f046-4243-a6ca-81ab5406c56e + ascii-to-digits(q:to/ROAST/) + _ + |_ + _| + + ROAST + , + 'eq', + '5', + "Recognizes 5", +); # end: 440f397a-f046-4243-a6ca-81ab5406c56e + +cmp-ok( # begin: f4c9cf6a-f1e2-4878-bfc3-9b85b657caa0 + ascii-to-digits(q:to/ROAST/) + _ + |_ + |_| + + ROAST + , + 'eq', + '6', + "Recognizes 6", +); # end: f4c9cf6a-f1e2-4878-bfc3-9b85b657caa0 + +cmp-ok( # begin: e24ebf80-c611-41bb-a25a-ac2c0f232df5 + ascii-to-digits(q:to/ROAST/) + _ + | + | + + ROAST + , + 'eq', + '7', + "Recognizes 7", +); # end: e24ebf80-c611-41bb-a25a-ac2c0f232df5 + +cmp-ok( # begin: b79cad4f-e264-4818-9d9e-77766792e233 + ascii-to-digits(q:to/ROAST/) + _ + |_| + |_| + + ROAST + , + 'eq', + '8', + "Recognizes 8", +); # end: b79cad4f-e264-4818-9d9e-77766792e233 + +cmp-ok( # begin: 5efc9cfc-9227-4688-b77d-845049299e66 + ascii-to-digits(q:to/ROAST/) + _ + |_| + _| + + ROAST + , + 'eq', + '9', + "Recognizes 9", +); # end: 5efc9cfc-9227-4688-b77d-845049299e66 + +cmp-ok( # begin: f60cb04a-42be-494e-a535-3451c8e097a4 + ascii-to-digits(q:to/ROAST/) + _ _ _ _ _ _ _ _ + | _| _||_||_ |_ ||_||_|| | + ||_ _| | _||_| ||_| _||_| + + ROAST + , + 'eq', + '1234567890', + "Recognizes string of decimal numbers", +); # end: f60cb04a-42be-494e-a535-3451c8e097a4 + +cmp-ok( # begin: b73ecf8b-4423-4b36-860d-3710bdb8a491 + ascii-to-digits(q:to/ROAST/) + _ _ + | _| _| + ||_ _| + + _ _ + |_||_ |_ + | _||_| + + _ _ _ + ||_||_| + ||_| _| + + ROAST + , + 'eq', + '123,456,789', + "Numbers separated by empty lines are recognized. Lines are joined by commas.", +); # end: b73ecf8b-4423-4b36-860d-3710bdb8a491 + +done-testing; From ba93ed12617da6af348556bdcc16f974c8ee517f Mon Sep 17 00:00:00 2001 From: habere-et-dispertire Date: Sun, 1 Jun 2025 12:41:46 +0100 Subject: [PATCH 2/2] Renamed heredoc terminators and switched to generic failure --- .../.meta/solutions/lib/OcrNumbers.rakumod | 19 +---- .../ocr-numbers/.meta/template-data.yaml | 33 +++----- .../ocr-numbers/t/ocr-numbers.rakutest | 76 +++++++++---------- 3 files changed, 48 insertions(+), 80 deletions(-) diff --git a/exercises/practice/ocr-numbers/.meta/solutions/lib/OcrNumbers.rakumod b/exercises/practice/ocr-numbers/.meta/solutions/lib/OcrNumbers.rakumod index 21de4c25..32444098 100644 --- a/exercises/practice/ocr-numbers/.meta/solutions/lib/OcrNumbers.rakumod +++ b/exercises/practice/ocr-numbers/.meta/solutions/lib/OcrNumbers.rakumod @@ -1,25 +1,12 @@ unit module OcrNumbers; -my role X::OCR is Exception {} -my class X::OCR::Invalid-Lines does X::OCR { - method message { 'Number of input lines is not a multiple of four' } -} -my class X::OCR::Invalid-Columns does X::OCR { - method message { 'Number of input columns is not a multiple of three' } -} -multi ascii-to-digits ( $art where .lines.elems !%% 4 ) is export { - X::OCR::Invalid-Lines.new.throw -} -multi ascii-to-digits ( $art where .lines.map( *.chars ).any !%% 3 ) is export { - X::OCR::Invalid-Columns.new.throw -} -multi ascii-to-digits ( $art ) is export { - constant $NUMBERS = q:to/END/; +sub ascii-to-digits ( $art where { .lines.elems %% 4 and .lines.map( *.chars ).all %% 3 } ) is export { + constant $NUMBERS = q:to/0123456789/; _ _ _ _ _ _ _ _ | | | _| _||_||_ |_ ||_||_| |_| ||_ _| | _||_| ||_| _| - END + 0123456789 constant %LOOKUP = ^10 RZ=> ( map *.join( "\n" ), zip $NUMBERS.lines.map( *.comb ).map: *.rotor: 3 ); join ',', gather for $art.lines.rotor: 4 { diff --git a/exercises/practice/ocr-numbers/.meta/template-data.yaml b/exercises/practice/ocr-numbers/.meta/template-data.yaml index f147a3d4..10f904a2 100644 --- a/exercises/practice/ocr-numbers/.meta/template-data.yaml +++ b/exercises/practice/ocr-numbers/.meta/template-data.yaml @@ -2,13 +2,11 @@ properties: convert: test: |- if %case:exists { - sprintf(q :to/END/, "\n " ~ %case.join("\n ").Str, %case.Str, %case.raku); - throws-like( { - ascii-to-digits(q:to/ROAST/)%s - ROAST + sprintf(q :to/END/, "\n " ~ %case.join("\n ").Str, %case.raku); + dies-ok( { + ascii-to-digits(q:to/SOUPÇON/)%s + SOUPÇON }, - Exception, - message => '%s', %s, ); END @@ -16,8 +14,8 @@ properties: else { sprintf(q :to/END/, "\n " ~ %case.join("\n ").Str, %case.Str, %case.raku); cmp-ok( - ascii-to-digits(q:to/ROAST/)%s - ROAST + ascii-to-digits(q:to/SOUPÇON/)%s + SOUPÇON , 'eq', '%s', @@ -28,26 +26,13 @@ properties: unit: module example: |- - my role X::OCR is Exception {} - my class X::OCR::Invalid-Lines does X::OCR { - method message { 'Number of input lines is not a multiple of four' } - } - my class X::OCR::Invalid-Columns does X::OCR { - method message { 'Number of input columns is not a multiple of three' } - } - multi ascii-to-digits ( $art where .lines.elems !%% 4 ) is export { - X::OCR::Invalid-Lines.new.throw - } - multi ascii-to-digits ( $art where .lines.map( *.chars ).any !%% 3 ) is export { - X::OCR::Invalid-Columns.new.throw - } - multi ascii-to-digits ( $art ) is export { - constant $NUMBERS = q:to/END/; + sub ascii-to-digits ( $art where { .lines.elems %% 4 and .lines.map( *.chars ).all %% 3 } ) is export { + constant $NUMBERS = q:to/0123456789/; _ _ _ _ _ _ _ _ | | | _| _||_||_ |_ ||_||_| |_| ||_ _| | _||_| ||_| _| - END + 0123456789 constant %LOOKUP = ^10 RZ=> ( map *.join( "\n" ), zip $NUMBERS.lines.map( *.comb ).map: *.rotor: 3 ); join ',', gather for $art.lines.rotor: 4 { diff --git a/exercises/practice/ocr-numbers/t/ocr-numbers.rakutest b/exercises/practice/ocr-numbers/t/ocr-numbers.rakutest index 2caacb04..9fed7445 100755 --- a/exercises/practice/ocr-numbers/t/ocr-numbers.rakutest +++ b/exercises/practice/ocr-numbers/t/ocr-numbers.rakutest @@ -4,12 +4,12 @@ use lib $?FILE.IO.parent(2).add('lib'); use OcrNumbers; cmp-ok( # begin: 5ee54e1a-b554-4bf3-a056-9a7976c3f7e8 - ascii-to-digits(q:to/ROAST/) + ascii-to-digits(q:to/SOUPÇON/) _ | | |_| - ROAST + SOUPÇON , 'eq', '0', @@ -17,12 +17,12 @@ cmp-ok( # begin: 5ee54e1a-b554-4bf3-a056-9a7976c3f7e8 ); # end: 5ee54e1a-b554-4bf3-a056-9a7976c3f7e8 cmp-ok( # begin: 027ada25-17fd-4d78-aee6-35a19623639d - ascii-to-digits(q:to/ROAST/) + ascii-to-digits(q:to/SOUPÇON/) | | - ROAST + SOUPÇON , 'eq', '1', @@ -30,50 +30,46 @@ cmp-ok( # begin: 027ada25-17fd-4d78-aee6-35a19623639d ); # end: 027ada25-17fd-4d78-aee6-35a19623639d cmp-ok( # begin: 3cce2dbd-01d9-4f94-8fae-419a822e89bb - ascii-to-digits(q:to/ROAST/) + ascii-to-digits(q:to/SOUPÇON/) _ | - ROAST + SOUPÇON , 'eq', '?', "Unreadable but correctly sized inputs return ?", ); # end: 3cce2dbd-01d9-4f94-8fae-419a822e89bb -throws-like( { # begin: cb19b733-4e36-4cf9-a4a1-6e6aac808b9a - ascii-to-digits(q:to/ROAST/) +dies-ok( { # begin: cb19b733-4e36-4cf9-a4a1-6e6aac808b9a + ascii-to-digits(q:to/SOUPÇON/) _ | | - ROAST + SOUPÇON }, - Exception, - message => 'Number of input lines is not a multiple of four', "Input with a number of lines that is not a multiple of four raises an error", ); # end: cb19b733-4e36-4cf9-a4a1-6e6aac808b9a -throws-like( { # begin: 235f7bd1-991b-4587-98d4-84206eec4cc6 - ascii-to-digits(q:to/ROAST/) +dies-ok( { # begin: 235f7bd1-991b-4587-98d4-84206eec4cc6 + ascii-to-digits(q:to/SOUPÇON/) | | - ROAST + SOUPÇON }, - Exception, - message => 'Number of input columns is not a multiple of three', "Input with a number of columns that is not a multiple of three raises an error", ); # end: 235f7bd1-991b-4587-98d4-84206eec4cc6 cmp-ok( # begin: 4a841794-73c9-4da9-a779-1f9837faff66 - ascii-to-digits(q:to/ROAST/) + ascii-to-digits(q:to/SOUPÇON/) _ _ _ _ | || | || | | || || | | ||_| ||_| | ||_||_| - ROAST + SOUPÇON , 'eq', '110101100', @@ -81,12 +77,12 @@ cmp-ok( # begin: 4a841794-73c9-4da9-a779-1f9837faff66 ); # end: 4a841794-73c9-4da9-a779-1f9837faff66 cmp-ok( # begin: 70c338f9-85b1-4296-a3a8-122901cdfde8 - ascii-to-digits(q:to/ROAST/) + ascii-to-digits(q:to/SOUPÇON/) _ _ _ | || | || | || || | | | _| ||_| | ||_||_| - ROAST + SOUPÇON , 'eq', '11?10?1?0', @@ -94,12 +90,12 @@ cmp-ok( # begin: 70c338f9-85b1-4296-a3a8-122901cdfde8 ); # end: 70c338f9-85b1-4296-a3a8-122901cdfde8 cmp-ok( # begin: ea494ff4-3610-44d7-ab7e-72fdef0e0802 - ascii-to-digits(q:to/ROAST/) + ascii-to-digits(q:to/SOUPÇON/) _ _| |_ - ROAST + SOUPÇON , 'eq', '2', @@ -107,12 +103,12 @@ cmp-ok( # begin: ea494ff4-3610-44d7-ab7e-72fdef0e0802 ); # end: ea494ff4-3610-44d7-ab7e-72fdef0e0802 cmp-ok( # begin: 1acd2c00-412b-4268-93c2-bd7ff8e05a2c - ascii-to-digits(q:to/ROAST/) + ascii-to-digits(q:to/SOUPÇON/) _ _| _| - ROAST + SOUPÇON , 'eq', '3', @@ -120,12 +116,12 @@ cmp-ok( # begin: 1acd2c00-412b-4268-93c2-bd7ff8e05a2c ); # end: 1acd2c00-412b-4268-93c2-bd7ff8e05a2c cmp-ok( # begin: eaec6a15-be17-4b6d-b895-596fae5d1329 - ascii-to-digits(q:to/ROAST/) + ascii-to-digits(q:to/SOUPÇON/) |_| | - ROAST + SOUPÇON , 'eq', '4', @@ -133,12 +129,12 @@ cmp-ok( # begin: eaec6a15-be17-4b6d-b895-596fae5d1329 ); # end: eaec6a15-be17-4b6d-b895-596fae5d1329 cmp-ok( # begin: 440f397a-f046-4243-a6ca-81ab5406c56e - ascii-to-digits(q:to/ROAST/) + ascii-to-digits(q:to/SOUPÇON/) _ |_ _| - ROAST + SOUPÇON , 'eq', '5', @@ -146,12 +142,12 @@ cmp-ok( # begin: 440f397a-f046-4243-a6ca-81ab5406c56e ); # end: 440f397a-f046-4243-a6ca-81ab5406c56e cmp-ok( # begin: f4c9cf6a-f1e2-4878-bfc3-9b85b657caa0 - ascii-to-digits(q:to/ROAST/) + ascii-to-digits(q:to/SOUPÇON/) _ |_ |_| - ROAST + SOUPÇON , 'eq', '6', @@ -159,12 +155,12 @@ cmp-ok( # begin: f4c9cf6a-f1e2-4878-bfc3-9b85b657caa0 ); # end: f4c9cf6a-f1e2-4878-bfc3-9b85b657caa0 cmp-ok( # begin: e24ebf80-c611-41bb-a25a-ac2c0f232df5 - ascii-to-digits(q:to/ROAST/) + ascii-to-digits(q:to/SOUPÇON/) _ | | - ROAST + SOUPÇON , 'eq', '7', @@ -172,12 +168,12 @@ cmp-ok( # begin: e24ebf80-c611-41bb-a25a-ac2c0f232df5 ); # end: e24ebf80-c611-41bb-a25a-ac2c0f232df5 cmp-ok( # begin: b79cad4f-e264-4818-9d9e-77766792e233 - ascii-to-digits(q:to/ROAST/) + ascii-to-digits(q:to/SOUPÇON/) _ |_| |_| - ROAST + SOUPÇON , 'eq', '8', @@ -185,12 +181,12 @@ cmp-ok( # begin: b79cad4f-e264-4818-9d9e-77766792e233 ); # end: b79cad4f-e264-4818-9d9e-77766792e233 cmp-ok( # begin: 5efc9cfc-9227-4688-b77d-845049299e66 - ascii-to-digits(q:to/ROAST/) + ascii-to-digits(q:to/SOUPÇON/) _ |_| _| - ROAST + SOUPÇON , 'eq', '9', @@ -198,12 +194,12 @@ cmp-ok( # begin: 5efc9cfc-9227-4688-b77d-845049299e66 ); # end: 5efc9cfc-9227-4688-b77d-845049299e66 cmp-ok( # begin: f60cb04a-42be-494e-a535-3451c8e097a4 - ascii-to-digits(q:to/ROAST/) + ascii-to-digits(q:to/SOUPÇON/) _ _ _ _ _ _ _ _ | _| _||_||_ |_ ||_||_|| | ||_ _| | _||_| ||_| _||_| - ROAST + SOUPÇON , 'eq', '1234567890', @@ -211,7 +207,7 @@ cmp-ok( # begin: f60cb04a-42be-494e-a535-3451c8e097a4 ); # end: f60cb04a-42be-494e-a535-3451c8e097a4 cmp-ok( # begin: b73ecf8b-4423-4b36-860d-3710bdb8a491 - ascii-to-digits(q:to/ROAST/) + ascii-to-digits(q:to/SOUPÇON/) _ _ | _| _| ||_ _| @@ -224,7 +220,7 @@ cmp-ok( # begin: b73ecf8b-4423-4b36-860d-3710bdb8a491 ||_||_| ||_| _| - ROAST + SOUPÇON , 'eq', '123,456,789',