This is my response to The Weekly Challenge #224.
$source
and $target
.
Input: $source = "abc"
$target = "xyz"
Output: false
Example 2:
Input: $source = "scriptinglanguage"
$target = "perl"
Output: true
Example 3:
Input: $source = "aabbcc"
$target = "abc"
Output: true
This is a simplified (extremely simplified, actually) version of «Good String», the first part of Challenge 221. See Subsequencially Good with Raku for my take on it.
File: special-notes
#! /usr/bin/env raku
unit sub MAIN ($source, $target); # [1]
say $target.comb.Bag (<=) $source.comb.Bag # [2]
?? 'true' # [2a]
!! 'false'; # [2b]
[1] No where
clauses on the two strings, so they can be empty.
[2]
Coerce the list of individual characters (with .comb
)
of each string into a Bag (with bag
), a hash like structure with the
individual values (without duplicates, as it is hash like) in the input array as
keys, and the occurences as the values.
See
docs.raku.org/routine/comb
for more information about comb
.
See
docs.raku.org/type/Bag
for more information about the Bag
type.
Then we use the subset (or equal) operator (<=)
to check if the target characters is a subset (or equal) of the source. If
it is, print 'true' [2a], and 'false' if not [2b].
See
docs.raku.org/language/operators infix (<=)
for more information about the subset or equal to operator (<=)
.
Running it:
$ ./special-notes abc xyz
false
$ ./special-notes scriptinglanguage perl
true
$ ./special-notes aabbcc abc
true
Looking good.
Let us have a go at empty strings:
$ ./special-notes "" ""
true
$ ./special-notes "" a
false
$ ./special-notes a ""
true
All three are reasonable, but one can argue about the reasonability of allowing empty strings in the first place.
0-9
only.
Input: $string = "112358"
Output: true
The additive sequence can be created using the given string digits: 1,1,2,3,5,8
1 + 1 => 2
1 + 2 => 3
2 + 3 => 5
3 + 5 => 8
Example 2:
Input: $string = "12345"
Output: false
No additive sequence can be created using the given string digits.
Example 3:
Input: $string = "199100199"
Output: true
The additive sequence can be created using the given string digits: 1,99,100,199
1 + 99 => 100
99 + 100 => 199
The first two examples deal with single digits only, so let us have a go at that:
File: additive-digit
#! /usr/bin/env raku
unit sub MAIN ($string where $string.chars > 2 && $string ~~ /^<[0..9]>*$/); # [1]
say is-additive($string) ?? 'true' !! 'false'; # [2]
sub is-additive ($string where $string.chars > 2 && $string ~~ /^<[0..9]>*$/) # [1a]
{
my @digits = $string.comb; # [3]
my $first = @digits.shift; # [4]
my $second = @digits.shift; # [5]
while (@digits.elems) # [6]
{
my $third = @digits.shift; # [7]
return False unless $first + $second == $third; # [8]
$first = $second; # [9]
$second = $third; # [9b]
}
return True; # [11]
}
[1] A string of at least three characters, and we allow the digits 0 to 9 only. This applies to the main program as well as the wrapper procedure [1a].
[2] Call the procedure, and explicitly print "true" or "false" depending on the result.
[3] Split the string into a list of indvidual characters (or digits, in this case).
[4] Get the first digit (and remove it from the list).
[5] and the second one (also removed).
[6] As long as there are more digits in the list,
[7] Get the third digit.
[8] The third digit should be the sum of the first and second. Return
False
if it is not.
[9] Set up the first and second [9b] digits for the next iteration.
[10] Failure to falsify (in [8]) means success.
Running it:
$ ./additive-digit 112358
true
$ ./additive-digit 12345
false
$ ./additive-digit 199100199
false
The first two are correct, but the third one misses the mark as it does not handle multi-digit numbers. That is as expected.
Let us have a go at fixing that.
www.tutorialspoint.com has a nice walk through of a way of solving this. But what fun would it be to translate a bullet list of quasi code to Raku?
So I'll do it in a completely different way...
Let me start with the verbose output for a string that is an addative number (actually a modified version of the second example), and explain the approach:
$ ./additive-number -v 12315
:: 12315 -> 0000 -> ' ' -> 12315
:: 12315 -> 0001 -> ' |' -> 1231|5
:: 12315 -> 0010 -> ' | ' -> 123|15
:: 12315 -> 0011 -> ' ||' -> 123|1|5
:: 12315 -> 0100 -> ' | ' -> 12|315
:: 12315 -> 0101 -> ' | |' -> 12|31|5
:: 12315 -> 0110 -> ' || ' -> 12|3|15
true
The first (verbose output) column is the string itself.
The second column is a zero padded binary number with size one less than the size of the string itself. We start at zero, and work our way upwards.
The third column is this number where the zeros are replaced with spaces,
and the ones with a vertical bar (the |
character).
The fourth and final column is the result of zipping (merging) the original string and the third column, with characters from alternate strings. The spaces has been removed.
After this we split the string in the final column on the vertical bar, giving us a list of numbers. We then check this list (if it has three or more elements) to see if it is addative, with a slighly modified version of the «is-additive» procedure.
File: additive-number
#! /usr/bin/env raku
unit sub MAIN ($string where $string.chars > 2 && $string ~~ /^<[0..9]>*$/,
:v(:$verbose));
my $bitmap-length = $string.chars -1; # [1]
for 0 .. Inf -> $i # [2]
{
my $binary = $i.base(2); # [3]
last if $binary.chars > $bitmap-length; # [4]
my $bitmap = $binary.fmt('%0' ~ $bitmap-length ~ 'd'); # [5]
my $bitmap2 = $bitmap; # [6]
$bitmap ~~ tr/01/ |/; # [7]
my @bitmap = $bitmap.comb; # [8]
my $new = (roundrobin($string.comb, @bitmap)).flat.join; # [9]
$new ~~ s:g/\s//; # [10]
my @array = $new.split("|"); # [11]
say ":: $string -> $bitmap2 -> '$bitmap' -> $new" if $verbose;
next unless @array.elems >= 3; # [12]
if is-additive(@array) # [13]
{
say 'true'; # [13a]
exit; # [13b]
}
}
say 'false'; # [14]
sub is-additive (@array) # [15]
{
my $first = @array.shift;
my $second = @array.shift;
while (@array.elems)
{
my $third = @array.shift;
return False unless $first + $second == $third;
$first = $second;
$second = $third;
}
return True;
}
[1] The length of the (binary) bitmap we are going to create.
[2] The easiest way of generating the bitmap is an infinite loop over decimal values, with a check on the lenght (in [4]).
[3] Convert the decimal value to binary with
base(2)
.
See
docs.raku.org/routine/base
for more information about base
.
[4] Exit the infinite loop if we have exceeded the required bitmap length.
[5] Stringify the bitmap with leading zeroes.
See
docs.raku.org/routine/fmt for
more information about fmt
.
[6] Verbose mode requires this value later on.
[7] Get rid of spaces in the string with the s///
operator.
See
https://docs.raku.org/language/operators#s///_in-place_substitution
for more information about the in-place substitution operator s///
.
[8] Get the bitmap as an array.
[9] Merge the original string with the bitmap with the
zipper like function roundrobin
. The result is a list of pair
objects, with one value from each list (original string, bitmap), so we flatten
this structure with flat
, before we merge the resulting list into
a single string with join
.
See
docs.raku.org/routine/roundrobin for
more information about roundrobin
.
[10] Get rid of spaces (from the bitmap).
[11] Split that string on the vertical bars to get a list of numbers.
[12] Skip this candidate if we have less than three values in the list.
Note that this could also have
been done as e.g. next if $bitmap.comb.sum < 2;
(counting
the number of "1" digits), after [5].
[13] Is it additive? If so, print "true" and exit. (If not, go in in the loop.)
[14] None of the lists were additive, then it is not additive; print "false".
[15] A slightly modified version of the procedure, taking an array of numbers.
Running it:
$ ./additive-number 112358
true
$ ./additive-number 12345
false
$ ./additive-number 199100199
true
$ ./additive-number 12315
true
With verbose mode:
$ ./additive-number -v 112358
:: 112358 -> 00000 -> ' ' -> 112358
:: 112358 -> 00001 -> ' |' -> 11235|8
:: 112358 -> 00010 -> ' | ' -> 1123|58
:: 112358 -> 00011 -> ' ||' -> 1123|5|8
:: 112358 -> 00100 -> ' | ' -> 112|358
:: 112358 -> 00101 -> ' | |' -> 112|35|8
:: 112358 -> 00110 -> ' || ' -> 112|3|58
:: 112358 -> 00111 -> ' |||' -> 112|3|5|8
:: 112358 -> 01000 -> ' | ' -> 11|2358
:: 112358 -> 01001 -> ' | |' -> 11|235|8
:: 112358 -> 01010 -> ' | | ' -> 11|23|58
:: 112358 -> 01011 -> ' | ||' -> 11|23|5|8
:: 112358 -> 01100 -> ' || ' -> 11|2|358
:: 112358 -> 01101 -> ' || |' -> 11|2|35|8
:: 112358 -> 01110 -> ' ||| ' -> 11|2|3|58
:: 112358 -> 01111 -> ' ||||' -> 11|2|3|5|8
:: 112358 -> 10000 -> '| ' -> 1|12358
:: 112358 -> 10001 -> '| |' -> 1|1235|8
:: 112358 -> 10010 -> '| | ' -> 1|123|58
:: 112358 -> 10011 -> '| ||' -> 1|123|5|8
:: 112358 -> 10100 -> '| | ' -> 1|12|358
:: 112358 -> 10101 -> '| | |' -> 1|12|35|8
:: 112358 -> 10110 -> '| || ' -> 1|12|3|58
:: 112358 -> 10111 -> '| |||' -> 1|12|3|5|8
:: 112358 -> 11000 -> '|| ' -> 1|1|2358
:: 112358 -> 11001 -> '|| |' -> 1|1|235|8
:: 112358 -> 11010 -> '|| | ' -> 1|1|23|58
:: 112358 -> 11011 -> '|| ||' -> 1|1|23|5|8
:: 112358 -> 11100 -> '||| ' -> 1|1|2|358
:: 112358 -> 11101 -> '||| |' -> 1|1|2|35|8
:: 112358 -> 11110 -> '|||| ' -> 1|1|2|3|58
:: 112358 -> 11111 -> '|||||' -> 1|1|2|3|5|8
true
$ ./additive-number -v 12345
:: 12345 -> 0000 -> ' ' -> 12345
:: 12345 -> 0001 -> ' |' -> 1234|5
:: 12345 -> 0010 -> ' | ' -> 123|45
:: 12345 -> 0011 -> ' ||' -> 123|4|5
:: 12345 -> 0100 -> ' | ' -> 12|345
:: 12345 -> 0101 -> ' | |' -> 12|34|5
:: 12345 -> 0110 -> ' || ' -> 12|3|45
:: 12345 -> 0111 -> ' |||' -> 12|3|4|5
:: 12345 -> 1000 -> '| ' -> 1|2345
:: 12345 -> 1001 -> '| |' -> 1|234|5
:: 12345 -> 1010 -> '| | ' -> 1|23|45
:: 12345 -> 1011 -> '| ||' -> 1|23|4|5
:: 12345 -> 1100 -> '|| ' -> 1|2|345
:: 12345 -> 1101 -> '|| |' -> 1|2|34|5
:: 12345 -> 1110 -> '||| ' -> 1|2|3|45
:: 12345 -> 1111 -> '||||' -> 1|2|3|4|5
false
$ ./additive-number -v 199100199
:: 199100199 -> 00000000 -> ' ' -> 199100199
:: 199100199 -> 00000001 -> ' |' -> 19910019|9
:: 199100199 -> 00000010 -> ' | ' -> 1991001|99
:: 199100199 -> 00000011 -> ' ||' -> 1991001|9|9
:: 199100199 -> 00000100 -> ' | ' -> 199100|199
:: 199100199 -> 00000101 -> ' | |' -> 199100|19|9
:: 199100199 -> 00000110 -> ' || ' -> 199100|1|99
:: 199100199 -> 00000111 -> ' |||' -> 199100|1|9|9
:: 199100199 -> 00001000 -> ' | ' -> 19910|0199
:: 199100199 -> 00001001 -> ' | |' -> 19910|019|9
:: 199100199 -> 00001010 -> ' | | ' -> 19910|01|99
:: 199100199 -> 00001011 -> ' | ||' -> 19910|01|9|9
:: 199100199 -> 00001100 -> ' || ' -> 19910|0|199
:: 199100199 -> 00001101 -> ' || |' -> 19910|0|19|9
:: 199100199 -> 00001110 -> ' ||| ' -> 19910|0|1|99
:: 199100199 -> 00001111 -> ' ||||' -> 19910|0|1|9|9
:: 199100199 -> 00010000 -> ' | ' -> 1991|00199
:: 199100199 -> 00010001 -> ' | |' -> 1991|0019|9
:: 199100199 -> 00010010 -> ' | | ' -> 1991|001|99
:: 199100199 -> 00010011 -> ' | ||' -> 1991|001|9|9
:: 199100199 -> 00010100 -> ' | | ' -> 1991|00|199
:: 199100199 -> 00010101 -> ' | | |' -> 1991|00|19|9
:: 199100199 -> 00010110 -> ' | || ' -> 1991|00|1|99
:: 199100199 -> 00010111 -> ' | |||' -> 1991|00|1|9|9
:: 199100199 -> 00011000 -> ' || ' -> 1991|0|0199
:: 199100199 -> 00011001 -> ' || |' -> 1991|0|019|9
:: 199100199 -> 00011010 -> ' || | ' -> 1991|0|01|99
:: 199100199 -> 00011011 -> ' || ||' -> 1991|0|01|9|9
:: 199100199 -> 00011100 -> ' ||| ' -> 1991|0|0|199
:: 199100199 -> 00011101 -> ' ||| |' -> 1991|0|0|19|9
:: 199100199 -> 00011110 -> ' |||| ' -> 1991|0|0|1|99
:: 199100199 -> 00011111 -> ' |||||' -> 1991|0|0|1|9|9
:: 199100199 -> 00100000 -> ' | ' -> 199|100199
:: 199100199 -> 00100001 -> ' | |' -> 199|10019|9
:: 199100199 -> 00100010 -> ' | | ' -> 199|1001|99
:: 199100199 -> 00100011 -> ' | ||' -> 199|1001|9|9
:: 199100199 -> 00100100 -> ' | | ' -> 199|100|199
:: 199100199 -> 00100101 -> ' | | |' -> 199|100|19|9
:: 199100199 -> 00100110 -> ' | || ' -> 199|100|1|99
:: 199100199 -> 00100111 -> ' | |||' -> 199|100|1|9|9
:: 199100199 -> 00101000 -> ' | | ' -> 199|10|0199
:: 199100199 -> 00101001 -> ' | | |' -> 199|10|019|9
:: 199100199 -> 00101010 -> ' | | | ' -> 199|10|01|99
:: 199100199 -> 00101011 -> ' | | ||' -> 199|10|01|9|9
:: 199100199 -> 00101100 -> ' | || ' -> 199|10|0|199
:: 199100199 -> 00101101 -> ' | || |' -> 199|10|0|19|9
:: 199100199 -> 00101110 -> ' | ||| ' -> 199|10|0|1|99
:: 199100199 -> 00101111 -> ' | ||||' -> 199|10|0|1|9|9
:: 199100199 -> 00110000 -> ' || ' -> 199|1|00199
:: 199100199 -> 00110001 -> ' || |' -> 199|1|0019|9
:: 199100199 -> 00110010 -> ' || | ' -> 199|1|001|99
:: 199100199 -> 00110011 -> ' || ||' -> 199|1|001|9|9
:: 199100199 -> 00110100 -> ' || | ' -> 199|1|00|199
:: 199100199 -> 00110101 -> ' || | |' -> 199|1|00|19|9
:: 199100199 -> 00110110 -> ' || || ' -> 199|1|00|1|99
:: 199100199 -> 00110111 -> ' || |||' -> 199|1|00|1|9|9
:: 199100199 -> 00111000 -> ' ||| ' -> 199|1|0|0199
:: 199100199 -> 00111001 -> ' ||| |' -> 199|1|0|019|9
:: 199100199 -> 00111010 -> ' ||| | ' -> 199|1|0|01|99
:: 199100199 -> 00111011 -> ' ||| ||' -> 199|1|0|01|9|9
:: 199100199 -> 00111100 -> ' |||| ' -> 199|1|0|0|199
:: 199100199 -> 00111101 -> ' |||| |' -> 199|1|0|0|19|9
:: 199100199 -> 00111110 -> ' ||||| ' -> 199|1|0|0|1|99
:: 199100199 -> 00111111 -> ' ||||||' -> 199|1|0|0|1|9|9
:: 199100199 -> 01000000 -> ' | ' -> 19|9100199
:: 199100199 -> 01000001 -> ' | |' -> 19|910019|9
:: 199100199 -> 01000010 -> ' | | ' -> 19|91001|99
:: 199100199 -> 01000011 -> ' | ||' -> 19|91001|9|9
:: 199100199 -> 01000100 -> ' | | ' -> 19|9100|199
:: 199100199 -> 01000101 -> ' | | |' -> 19|9100|19|9
:: 199100199 -> 01000110 -> ' | || ' -> 19|9100|1|99
:: 199100199 -> 01000111 -> ' | |||' -> 19|9100|1|9|9
:: 199100199 -> 01001000 -> ' | | ' -> 19|910|0199
:: 199100199 -> 01001001 -> ' | | |' -> 19|910|019|9
:: 199100199 -> 01001010 -> ' | | | ' -> 19|910|01|99
:: 199100199 -> 01001011 -> ' | | ||' -> 19|910|01|9|9
:: 199100199 -> 01001100 -> ' | || ' -> 19|910|0|199
:: 199100199 -> 01001101 -> ' | || |' -> 19|910|0|19|9
:: 199100199 -> 01001110 -> ' | ||| ' -> 19|910|0|1|99
:: 199100199 -> 01001111 -> ' | ||||' -> 19|910|0|1|9|9
:: 199100199 -> 01010000 -> ' | | ' -> 19|91|00199
:: 199100199 -> 01010001 -> ' | | |' -> 19|91|0019|9
:: 199100199 -> 01010010 -> ' | | | ' -> 19|91|001|99
:: 199100199 -> 01010011 -> ' | | ||' -> 19|91|001|9|9
:: 199100199 -> 01010100 -> ' | | | ' -> 19|91|00|199
:: 199100199 -> 01010101 -> ' | | | |' -> 19|91|00|19|9
:: 199100199 -> 01010110 -> ' | | || ' -> 19|91|00|1|99
:: 199100199 -> 01010111 -> ' | | |||' -> 19|91|00|1|9|9
:: 199100199 -> 01011000 -> ' | || ' -> 19|91|0|0199
:: 199100199 -> 01011001 -> ' | || |' -> 19|91|0|019|9
:: 199100199 -> 01011010 -> ' | || | ' -> 19|91|0|01|99
:: 199100199 -> 01011011 -> ' | || ||' -> 19|91|0|01|9|9
:: 199100199 -> 01011100 -> ' | ||| ' -> 19|91|0|0|199
:: 199100199 -> 01011101 -> ' | ||| |' -> 19|91|0|0|19|9
:: 199100199 -> 01011110 -> ' | |||| ' -> 19|91|0|0|1|99
:: 199100199 -> 01011111 -> ' | |||||' -> 19|91|0|0|1|9|9
:: 199100199 -> 01100000 -> ' || ' -> 19|9|100199
:: 199100199 -> 01100001 -> ' || |' -> 19|9|10019|9
:: 199100199 -> 01100010 -> ' || | ' -> 19|9|1001|99
:: 199100199 -> 01100011 -> ' || ||' -> 19|9|1001|9|9
:: 199100199 -> 01100100 -> ' || | ' -> 19|9|100|199
:: 199100199 -> 01100101 -> ' || | |' -> 19|9|100|19|9
:: 199100199 -> 01100110 -> ' || || ' -> 19|9|100|1|99
:: 199100199 -> 01100111 -> ' || |||' -> 19|9|100|1|9|9
:: 199100199 -> 01101000 -> ' || | ' -> 19|9|10|0199
:: 199100199 -> 01101001 -> ' || | |' -> 19|9|10|019|9
:: 199100199 -> 01101010 -> ' || | | ' -> 19|9|10|01|99
:: 199100199 -> 01101011 -> ' || | ||' -> 19|9|10|01|9|9
:: 199100199 -> 01101100 -> ' || || ' -> 19|9|10|0|199
:: 199100199 -> 01101101 -> ' || || |' -> 19|9|10|0|19|9
:: 199100199 -> 01101110 -> ' || ||| ' -> 19|9|10|0|1|99
:: 199100199 -> 01101111 -> ' || ||||' -> 19|9|10|0|1|9|9
:: 199100199 -> 01110000 -> ' ||| ' -> 19|9|1|00199
:: 199100199 -> 01110001 -> ' ||| |' -> 19|9|1|0019|9
:: 199100199 -> 01110010 -> ' ||| | ' -> 19|9|1|001|99
:: 199100199 -> 01110011 -> ' ||| ||' -> 19|9|1|001|9|9
:: 199100199 -> 01110100 -> ' ||| | ' -> 19|9|1|00|199
:: 199100199 -> 01110101 -> ' ||| | |' -> 19|9|1|00|19|9
:: 199100199 -> 01110110 -> ' ||| || ' -> 19|9|1|00|1|99
:: 199100199 -> 01110111 -> ' ||| |||' -> 19|9|1|00|1|9|9
:: 199100199 -> 01111000 -> ' |||| ' -> 19|9|1|0|0199
:: 199100199 -> 01111001 -> ' |||| |' -> 19|9|1|0|019|9
:: 199100199 -> 01111010 -> ' |||| | ' -> 19|9|1|0|01|99
:: 199100199 -> 01111011 -> ' |||| ||' -> 19|9|1|0|01|9|9
:: 199100199 -> 01111100 -> ' ||||| ' -> 19|9|1|0|0|199
:: 199100199 -> 01111101 -> ' ||||| |' -> 19|9|1|0|0|19|9
:: 199100199 -> 01111110 -> ' |||||| ' -> 19|9|1|0|0|1|99
:: 199100199 -> 01111111 -> ' |||||||' -> 19|9|1|0|0|1|9|9
:: 199100199 -> 10000000 -> '| ' -> 1|99100199
:: 199100199 -> 10000001 -> '| |' -> 1|9910019|9
:: 199100199 -> 10000010 -> '| | ' -> 1|991001|99
:: 199100199 -> 10000011 -> '| ||' -> 1|991001|9|9
:: 199100199 -> 10000100 -> '| | ' -> 1|99100|199
:: 199100199 -> 10000101 -> '| | |' -> 1|99100|19|9
:: 199100199 -> 10000110 -> '| || ' -> 1|99100|1|99
:: 199100199 -> 10000111 -> '| |||' -> 1|99100|1|9|9
:: 199100199 -> 10001000 -> '| | ' -> 1|9910|0199
:: 199100199 -> 10001001 -> '| | |' -> 1|9910|019|9
:: 199100199 -> 10001010 -> '| | | ' -> 1|9910|01|99
:: 199100199 -> 10001011 -> '| | ||' -> 1|9910|01|9|9
:: 199100199 -> 10001100 -> '| || ' -> 1|9910|0|199
:: 199100199 -> 10001101 -> '| || |' -> 1|9910|0|19|9
:: 199100199 -> 10001110 -> '| ||| ' -> 1|9910|0|1|99
:: 199100199 -> 10001111 -> '| ||||' -> 1|9910|0|1|9|9
:: 199100199 -> 10010000 -> '| | ' -> 1|991|00199
:: 199100199 -> 10010001 -> '| | |' -> 1|991|0019|9
:: 199100199 -> 10010010 -> '| | | ' -> 1|991|001|99
:: 199100199 -> 10010011 -> '| | ||' -> 1|991|001|9|9
:: 199100199 -> 10010100 -> '| | | ' -> 1|991|00|199
:: 199100199 -> 10010101 -> '| | | |' -> 1|991|00|19|9
:: 199100199 -> 10010110 -> '| | || ' -> 1|991|00|1|99
:: 199100199 -> 10010111 -> '| | |||' -> 1|991|00|1|9|9
:: 199100199 -> 10011000 -> '| || ' -> 1|991|0|0199
:: 199100199 -> 10011001 -> '| || |' -> 1|991|0|019|9
:: 199100199 -> 10011010 -> '| || | ' -> 1|991|0|01|99
:: 199100199 -> 10011011 -> '| || ||' -> 1|991|0|01|9|9
:: 199100199 -> 10011100 -> '| ||| ' -> 1|991|0|0|199
:: 199100199 -> 10011101 -> '| ||| |' -> 1|991|0|0|19|9
:: 199100199 -> 10011110 -> '| |||| ' -> 1|991|0|0|1|99
:: 199100199 -> 10011111 -> '| |||||' -> 1|991|0|0|1|9|9
:: 199100199 -> 10100000 -> '| | ' -> 1|99|100199
:: 199100199 -> 10100001 -> '| | |' -> 1|99|10019|9
:: 199100199 -> 10100010 -> '| | | ' -> 1|99|1001|99
:: 199100199 -> 10100011 -> '| | ||' -> 1|99|1001|9|9
:: 199100199 -> 10100100 -> '| | | ' -> 1|99|100|199
true
Quite a lot of verbose output for this one. That is why I came up with the example string «12315» for the initial explanation.
The verbose output above should give a hint that this brute force approach is not very efficient, especially if the length of the input string is large.
$ ./additive-number -v 12315
:: 12315 -> 0000 -> ' ' -> 12315
:: 12315 -> 0001 -> ' |' -> 1231|5
:: 12315 -> 0010 -> ' | ' -> 123|15
:: 12315 -> 0011 -> ' ||' -> 123|1|5
:: 12315 -> 0100 -> ' | ' -> 12|315
:: 12315 -> 0101 -> ' | |' -> 12|31|5
:: 12315 -> 0110 -> ' || ' -> 12|3|15
true
Note that we could get rid of arrays with numbers with more than one digit, and the first one is a zero. This would fit in between [12] and [13]. But the check would require some work (and code), and it may not be worth the effort.
Note that we could also get rid of arrays where the number of digits in any element is smaller than the highest of the two elements to the left of it (as it should be the sum of those values).
And that's it.