#!/usr/bin/env perl use 5.010; use warnings; use strict; use bigint; use Math::Combinatorics; $|++; sub mult_root { my $prod = 1; $prod *= $_ for split //, shift; return $prod; } sub sum_root { my $sum = 0; $sum += $_ for split //, shift; return $sum; } sub persistance_count { my $arg = shift; my $count = shift // 0; my $debug = shift // 0; return $count unless 1 < length($arg); ++$count; my $r = mult_root($arg); print "::$count: $arg => $r\n" if $debug; persistance_count($r, $count, $debug); } my @min_persistance = (0, 10, 25, 39, 77, 679, 6788, 68889, 2677889, 26888999, 3778888999, 277777788888899); printf "persistance_count(%s) = %s\n", $_, persistance_count($_) for @min_persistance; printf "\ndebug(%s)\n", $min_persistance[-1]; persistance_count($min_persistance[-1], 0, 1); sub digital_factor { # factors a number into powers of single digits, plus a leftover #(that may be prime, or just coprime with all single digits) my $arg = $_[0]; unless($arg) { print "digital_factor(0) = 0\n"; return (toobig => 0); } my %factor; foreach my $k (reverse 2..9) { next unless $k eq 0+$k; while(0 == $arg % $k) { $factor{$k}++; $arg /= $k; } } $factor{toobig} = $arg unless 1 == $arg; return %factor; } sub print_factor { my($v, %f) = @_; printf "digital_factor(%s) = ", $v; foreach my $k ( 2..9 ) { printf "%s**%s * ", $k, $f{$k} if exists $f{$k}; } printf "%s\n", (exists($f{toobig}) ? $f{toobig} : 1); } print "\n"; for(@min_persistance, 4996238671872) { my %f = digital_factor($_); print_factor($_, %f); } print "\n"; foreach my $base ( 4996238671872 ) { my $i = 0; my @symbols = split //, $base; my %done; printf "loop(%s): mult_root=%s sum_root=%s\n", $base, mult_root($base), sum_root($base); my $iter = Math::Combinatorics->new(count => scalar @symbols, data => \@symbols); while(my @perm = $iter->next_permutation) { my $v = 0 + join '', @perm; next if $done{$v}; $done{$v}++; my %f = digital_factor($v); print_factor($v, %f); #last unless ++$i < 100; } print "\n"; }