Rare numbers: Difference between revisions

Content added Content deleted
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 > 1 and target ~~ Int )) {
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 calaculate potential diffs
# 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 potetential diff numbers
# 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 = do given @all_diffs xx (digit div 2 - 1) {
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 ; next } if k.elems == 1 ;
{ take k andthen next } if k.elems == 1 ;
given (my (\a,\b) = k[0,1]) {
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 @terms1toN = (1..(+diffs + (digit % 2 - 1))).map: -> \k {
my @c_iter = digit == 2
k != +diffs ?? do { %lookup_n{$_} with diffs[k] }
?? @lookup_1[diffs[0]].map: { [ $_ ] }
!! do { @numeric_digits } }
!! [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[0,1] }
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