Largest palindrome product: Difference between revisions

From Rosetta Code
Content added Content deleted
(→‎{{header|Go}}: Updated as per Wren.)
(→‎{{header|Raku}}: use external library for 25x speedup (still slow, but not dreadful))
Line 75: Line 75:


=={{header|Raku}}==
=={{header|Raku}}==
<lang perl6>use Prime::Factor;


<lang perl6>use Inline::Perl5;
.say for (1..11).hyper(:1batch).map: {.&lpp};
my $p5 = Inline::Perl5.new();
$p5.use: 'ntheory';
my &divisors = $p5.run('sub { ntheory::divisors $_[0] }');


.say for (2..12).map: {.&lpp};
multi lpp ($oom where {$_ +& 1}) { # even number of multiplicand digits

my $f = +(9 x ($oom + 1));
multi lpp ($oom where {!($_ +& 1)}) { # even number of multiplicand digits
my $o = (1 + $oom) / 2;
my $pal = +(9 x $o ~ 0 x $o * 2 ~ 9 x $o);
my $f = +(9 x $oom);
my $o = $oom / 2;
sprintf "Largest palindromic product of two %2d-digit integers: %d × %d = %d", $oom + 1, $pal div $f, $f, $pal
my $pal = +(9 x $o ~ 0 x $oom ~ 9 x $o);
sprintf "Largest palindromic product of two %2d-digit integers: %d × %d = %d", $oom, $pal div $f, $f, $pal
}
}


multi lpp ($oom where {$_ +^ 1}) { # odd number of multiplicand digits
multi lpp ($oom where {$_ +& 1}) { # odd number of multiplicand digits
my $p;
my $p;
(+(1 ~ (0 x $oom)) .. +(9 ~ (9 x $oom))).reverse.map({ +($_ ~ .flip) }).map: -> $pal {
(+(1 ~ (0 x ($oom - 1))) .. +(9 ~ (9 x ($oom - 1)))).reverse.map({ +($_ ~ .flip) }).map: -> $pal {
for my @factors = $pal.&divisors.grep({.chars == ($oom + 1)}).sort(-*) {
for my @factors = divisors("$pal")».Int.grep({ .chars == $oom }).sort( -* ) {
next unless $pal div $_ ∈ @factors;
next unless $pal div $_ ∈ @factors;
$p = sprintf("Largest palindromic product of two %2d-digit integers: %d × %d = %d", $oom + 1, $pal div $_, $_, $pal) and last;
$p = sprintf("Largest palindromic product of two %2d-digit integers: %d × %d = %d", $oom, $pal div $_, $_, $pal);
last;
}
}
last if $p;
last if $p;

Revision as of 17:49, 3 November 2021

Largest palindrome product is a draft programming task. It is not yet considered ready to be promoted as a complete task, for reasons that should be found in its talk page.
Task


Task description is taken from Project Euler (https://projecteuler.net/problem=4)
A palindromic number reads the same both ways. The largest palindrome made from the product of two 2-digit numbers is 9009 = 91 × 99.
Find the largest palindrome made from the product of two 3-digit numbers.

F#

<lang fsharp> // Largest palindrome product. Nigel Galloway: November 3rd., 2021 let fN g=let rec fN g=[yield g%10; if g>=10 then yield! fN(g/10)] in let n=fN g in n=List.rev n printfn "%d" ([for n in 100..999 do for g in n..999->n*g]|>List.filter fN|>List.max) </lang>

Output:
906609

Go

Translation of: Wren

18 digit integers are within the range of Go's uint64 type though finding the result for 9-digit number products takes a while - around 15 seconds on my machine. <lang go>package main

import "fmt"

func reverse(n uint64) uint64 {

   r := uint64(0)
   for n > 0 {
       r = n%10 + r*10
       n /= 10
   }
   return r

}

func main() {

   pow := uint64(10)

nextN:

   for n := 2; n < 10; n++ {
       low := pow * 9
       pow *= 10
       high := pow - 1
       fmt.Printf("Largest palindromic product of two %d-digit integers: ", n)
       for i := high; i >= low; i-- {
           j := reverse(i)
           p := i*pow + j
           // k can't be even nor end in 5 to produce a product ending in 9
           for k := high; k > low; k -= 2 {
               if k % 10 == 5 {
                   continue
               }
               l := p / k
               if l > high {
                   break
               }
               if p%k == 0 {
                   fmt.Printf("%d x %d = %d\n", k, l, p)
                   continue nextN
               }
           }
       }
   }

}</lang>

Output:
Largest palindromic product of two 2-digit integers: 99 x 91 = 9009
Largest palindromic product of two 3-digit integers: 993 x 913 = 906609
Largest palindromic product of two 4-digit integers: 9999 x 9901 = 99000099
Largest palindromic product of two 5-digit integers: 99979 x 99681 = 9966006699
Largest palindromic product of two 6-digit integers: 999999 x 999001 = 999000000999
Largest palindromic product of two 7-digit integers: 9998017 x 9997647 = 99956644665999
Largest palindromic product of two 8-digit integers: 99999999 x 99990001 = 9999000000009999
Largest palindromic product of two 9-digit integers: 999980347 x 999920317 = 999900665566009999

Raku

<lang perl6>use Inline::Perl5; my $p5 = Inline::Perl5.new(); $p5.use: 'ntheory'; my &divisors = $p5.run('sub { ntheory::divisors $_[0] }');

.say for (2..12).map: {.&lpp};

multi lpp ($oom where {!($_ +& 1)}) { # even number of multiplicand digits

   my $f = +(9 x $oom);
   my $o = $oom / 2;
   my $pal = +(9 x $o ~ 0 x $oom ~ 9 x $o);
   sprintf "Largest palindromic product of two %2d-digit integers: %d × %d = %d", $oom, $pal div $f, $f, $pal

}

multi lpp ($oom where {$_ +& 1}) { # odd number of multiplicand digits

   my $p;
   (+(1 ~ (0 x ($oom - 1))) .. +(9 ~ (9 x ($oom - 1)))).reverse.map({ +($_ ~ .flip) }).map: -> $pal {
       for my @factors = divisors("$pal")».Int.grep({ .chars == $oom }).sort( -* ) {
           next unless $pal div $_ ∈ @factors;
           $p = sprintf("Largest palindromic product of two %2d-digit integers: %d × %d = %d", $oom, $pal div $_, $_, $pal);
           last;
       }
       last if $p;
   }
   $p

}</lang>

Largest palindromic product of two  2-digit integers: 91 × 99 = 9009
Largest palindromic product of two  3-digit integers: 913 × 993 = 906609
Largest palindromic product of two  4-digit integers: 9901 × 9999 = 99000099
Largest palindromic product of two  5-digit integers: 99681 × 99979 = 9966006699
Largest palindromic product of two  6-digit integers: 999001 × 999999 = 999000000999
Largest palindromic product of two  7-digit integers: 9997647 × 9998017 = 99956644665999
Largest palindromic product of two  8-digit integers: 99990001 × 99999999 = 9999000000009999
Largest palindromic product of two  9-digit integers: 999920317 × 999980347 = 999900665566009999
Largest palindromic product of two 10-digit integers: 9999900001 × 9999999999 = 99999000000000099999
Largest palindromic product of two 11-digit integers: 99999943851 × 99999996349 = 9999994020000204999999
Largest palindromic product of two 12-digit integers: 999999000001 × 999999999999 = 999999000000000000999999

Ring

<lang ring> load "stdlib.ring" see "working..." + nl

prodOld = 0 limitStart = 100 limitEnd = 999

for n = limitStart to limitEnd

   for m = limitStart to limitEnd
       prodNew = n*m
       if prodNew > prodOld and palindrome(string(prodNew))
          prodOld = prodNew
          first = n
          second = m
       ok
   next

next

see "The largest palindrome is:" + nl see "" + first + " * " + second + " = " + prodOld + nl see "done..." + nl </lang>

Output:
working...
The largest palindrome is:
913 * 993 = 906609
done...

Wren

The approach here is to manufacture palindromic numbers of length 2n in decreasing order and then see if they're products of two n-digit numbers. <lang ecmascript>var reverse = Fn.new { |n|

   var r = 0 
   while (n > 0) {
       r = n%10 + r*10
       n = (n/10).floor
   }
   return r

}

var pow = 10 for (n in 2..7) {

   var low = pow * 9
   pow = pow * 10
   var high = pow - 1
   System.write("Largest palindromic product of two %(n)-digit integers: ")
   var nextN = false
   for (i in high..low) {
       var j = reverse.call(i)
       var p = i * pow + j
       // k can't be even nor end in 5 to produce a product ending in 9
       var k = high
       while (k > low) {
           if (k % 10 != 5) {
               var l = p / k
               if (l > high) break
               if (p % k == 0) {
                   System.print("%(k) x %(l) = %(p)")
                   nextN = true
                   break
               }
           }
           k = k - 2
       }
       if (nextN) break
   }

}</lang>

Output:
Largest palindromic product of two 2-digit integers: 99 x 91 = 9009
Largest palindromic product of two 3-digit integers: 993 x 913 = 906609
Largest palindromic product of two 4-digit integers: 9999 x 9901 = 99000099
Largest palindromic product of two 5-digit integers: 99979 x 99681 = 9966006699
Largest palindromic product of two 6-digit integers: 999999 x 999001 = 999000000999
Largest palindromic product of two 7-digit integers: 9998017 x 9997647 = 99956644665999

XPL0

<lang XPL0>func Rev(A); \Reverse digits int A, B; [B:= 0; repeat A:= A/10;

       B:= B*10 + rem(0);

until A = 0; return B; ];

int Max, M, N, Prod; [Max:= 0; for M:= 100 to 999 do

   for N:= 100 to 999 do
       [Prod:= M*N;
       if Prod = Rev(Prod) then
           if Prod > Max then Max:= Prod;
       ];

IntOut(0, Max); ]</lang>

Output:
906609