#!/usr/bin/perl6
# your code goes here
sub prime-factors ( Int $n where * > 0 ) {
return $n if $n.is-prime;
return () if $n == 1;
my $factor = find-factor( $n );
sort flat
( $factor
, $n
div $factor
).
map: &prime
-factors
;}
sub find-factor ( Int $n, $constant = 1 ) {
return 2 unless $n +& 1;
if (my $gcd = $n gcd 6541380665835015) > 1 { # magic number: [*] primes 3 .. 43
return $gcd if $gcd != $n
}
my $x = 2;
my $rho = 1;
my $factor = 1;
while $factor == 1 {
$rho = $rho +< 1;
my $fixed = $x;
my int $i = 0;
while $i < $rho {
$x = ( $x * $x + $constant ) % $n;
$factor = ( $x - $fixed ) gcd $n;
last if 1 < $factor;
$i = $i + 1;
}
}
$factor = find-factor( $n, $constant + 1 ) if $n == $factor;
$factor;
}
my $now = now;
.put for (2..100).grep( &is-prime).hyper(:4batch).map: { "2**$_ - 1: ", (2**$_-1).&prime-factors.join('×')} ;
.put for (600851475143, 100000000000000000037).map: { $_, .&prime-factors.join('×')} ;
say now - $now;
IyEvdXNyL2Jpbi9wZXJsNgojIHlvdXIgY29kZSBnb2VzIGhlcmUKc3ViIHByaW1lLWZhY3RvcnMgKCBJbnQgJG4gd2hlcmUgKiA+IDAgKSB7CiAgICByZXR1cm4gJG4gaWYgJG4uaXMtcHJpbWU7CiAgICByZXR1cm4gKCkgaWYgJG4gPT0gMTsKICAgIG15ICRmYWN0b3IgPSBmaW5kLWZhY3RvciggJG4gKTsKICAgIHNvcnQgZmxhdCAoICRmYWN0b3IsICRuIGRpdiAkZmFjdG9yICkubWFwOiAmcHJpbWUtZmFjdG9yczsKfQoKc3ViIGZpbmQtZmFjdG9yICggSW50ICRuLCAkY29uc3RhbnQgPSAxICkgewogICAgcmV0dXJuIDIgdW5sZXNzICRuICsmIDE7CiAgICBpZiAobXkgJGdjZCA9ICRuIGdjZCA2NTQxMzgwNjY1ODM1MDE1KSA+IDEgeyAjIG1hZ2ljIG51bWJlcjogWypdIHByaW1lcyAzIC4uIDQzCiAgICAgICAgcmV0dXJuICRnY2QgaWYgJGdjZCAhPSAkbgogICAgfQogICAgbXkgJHggICAgICA9IDI7CiAgICBteSAkcmhvICAgID0gMTsKICAgIG15ICRmYWN0b3IgPSAxOwogICAgd2hpbGUgJGZhY3RvciA9PSAxIHsKICAgICAgICAkcmhvID0gJHJobyArPCAxOwogICAgICAgIG15ICRmaXhlZCA9ICR4OwogICAgICAgIG15IGludCAkaSA9IDA7CiAgICAgICAgd2hpbGUgJGkgPCAkcmhvIHsKICAgICAgICAgICAgJHggPSAoICR4ICogJHggKyAkY29uc3RhbnQgKSAlICRuOwogICAgICAgICAgICAkZmFjdG9yID0gKCAkeCAtICRmaXhlZCApIGdjZCAkbjsKICAgICAgICAgICAgbGFzdCBpZiAxIDwgJGZhY3RvcjsKICAgICAgICAgICAgJGkgPSAkaSArIDE7CiAgICAgICAgfQogICAgfQogICAgJGZhY3RvciA9IGZpbmQtZmFjdG9yKCAkbiwgJGNvbnN0YW50ICsgMSApIGlmICRuID09ICRmYWN0b3I7CiAgICAkZmFjdG9yOwp9CgoKIG15ICRub3cgPSBub3c7Ci5wdXQgZm9yICgyLi4xMDApLmdyZXAoICZpcy1wcmltZSkuaHlwZXIoOjRiYXRjaCkubWFwOiB7ICIyKiokXyAtIDE6ICIsICgyKiokXy0xKS4mcHJpbWUtZmFjdG9ycy5qb2luKCfDlycpfSA7Ci5wdXQgZm9yICg2MDA4NTE0NzUxNDMsIDEwMDAwMDAwMDAwMDAwMDAwMDAzNykubWFwOiB7ICRfLCAuJnByaW1lLWZhY3RvcnMuam9pbignw5cnKX0gOwpzYXkgbm93IC0gJG5vdzs=