Rare numbers: Difference between revisions
Content added Content deleted
m (→{{header|Rust}}: typo) |
m (→{{header|Raku}}: correct a mistake and simplify a little) |
||
Line 4,607: | Line 4,607: | ||
<lang perl6># 20220315 Raku programming solution |
<lang perl6># 20220315 Raku programming solution |
||
sub rare (\target where ( target > |
sub rare (\target where ( target > 0 and target ~~ Int )) { |
||
my \digit = $ = 2; |
my \digit = $ = 2; |
||
Line 4,614: | Line 4,614: | ||
my @diffs1 = 0,1,4,5,6; |
my @diffs1 = 0,1,4,5,6; |
||
# all possible digits pairs to |
# all possible digits pairs to calculate potential diffs |
||
my @pairs = 0..9 X 0..9; |
my @pairs = 0..9 X 0..9; |
||
my @all_diffs = -9..9; |
my @all_diffs = -9..9; |
||
Line 4,628: | Line 4,628: | ||
# lookup table for all the remaining diffs |
# lookup table for all the remaining diffs |
||
given my %lookup_n { for @pairs -> \pair { $_{ [-] pair.values }.push: pair } } |
|||
my %lookup_n; |
|||
for @pairs { %lookup_n{ .[0] - .[1] }.push: $_ } |
|||
loop { |
loop { |
||
Line 4,637: | Line 4,636: | ||
my @terms = (@powers.reverse Z- @powers).grep: * > 0 ; |
my @terms = (@powers.reverse Z- @powers).grep: * > 0 ; |
||
# create a cartesian product for all |
# create a cartesian product for all potential diff numbers |
||
# for the first use the very short one, for all other the complete 19 element |
# for the first use the very short one, for all other the complete 19 element |
||
my @diff_list = |
my @diff_list = digit == 2 ?? @diffs1 !! [X] @diffs1, |(@all_diffs xx digit div 2 - 1); |
||
when $_.Bool { [X] @diffs1, |$_ } |
|||
default { @diffs1 } } |
|||
my @diff_list_iter = gather for @diff_list -> \k { |
my @diff_list_iter = gather for @diff_list -> \k { |
||
# remove invalid first diff/second diff combinations |
# remove invalid first diff/second diff combinations |
||
{ take k |
{ take k andthen next } if k.elems == 1 ; |
||
given (my (\a,\b) = k |
given (my (\a,\b) = k.values) { |
||
when a == 0 && b != 0 { next } |
when a == 0 && b != 0 { next } |
||
when a == 1 && b ∉ [ -7, -5, -3, -1, 1, 3, 5, 7 ] { next } |
when a == 1 && b ∉ [ -7, -5, -3, -1, 1, 3, 5, 7 ] { next } |
||
Line 4,663: | Line 4,660: | ||
# placeholder for the digits |
# placeholder for the digits |
||
my \dig = @ = 0 xx digit; |
my \dig = @ = 0 xx digit; |
||
# generate a cartesian product for each identified diff using the lookup tables |
# generate a cartesian product for each identified diff using the lookup tables |
||
my @ |
my @c_iter = digit == 2 |
||
?? @lookup_1[diffs[0]].map: { [ $_ ] } |
|||
!! [X] @lookup_1[diffs[0]], |(1..(+diffs + (digit % 2 - 1))).map: -> \k { |
|||
k == diffs ?? @numeric_digits !! %lookup_n{diffs[k]} } |
|||
my @c_iter = digit == 2 ?? @lookup_1[diffs[0]].map: { [ $_ ] } |
|||
!! [X] @lookup_1[diffs[0]], |@terms1toN; |
|||
# check each H (n+r) by using digit combination |
# check each H (n+r) by using digit combination |
||
for @c_iter -> \elt { |
for @c_iter -> \elt { |
||
for elt.kv -> \i, \pair { dig[i,digit-1-i] = pair |
for elt.kv -> \i, \pair { dig[i,digit-1-i] = pair.values } |
||
# for numbers with odd # digits restore the middle digit |
# for numbers with odd # digits restore the middle digit |
||
# which has been overwritten at the end of the previous cycle |
# which has been overwritten at the end of the previous cycle |