Challenge 153 Task #2 - Even more factorials and what the fac are factorions?
Task #2 - Factorions
Description
Submitted by: Mohammad S Anwar
You are given an integer, $n
.
Write a script to figure out if the given integer is factorion.
A factorion is a natural number that equals the sum of the factorials of its digits.
Example 1:
Input: $n = 145
Output: 1
Since 1! + 4! + 5! => 1 + 24 + 120 = 145
Example 2:
Input: $n = 123
Output: 0
Since 1! + 2! + 3! => 1 + 2 + 6 <> 123
Solution
Similar to the first task of this week, this is about factorials. I first solved it just with what is given in the description. Split the number into its digits, calculate the factorial for each digit and sum that up. If the sum is equal to the input we have a factorion.
First the same fac
routine as in task 1.
sub fac($n) {
1 .. $n );
product( }
Here the code for the is_factorion
routine.
sub is_factorion($n) {
my @digits = split( m//, $n );
my $sum_of_factorials_of_digits = sum0( map { fac($_) } @digits );
return $n == $sum_of_factorials_of_digits;
}
Afterwards I wrote some drive code to run this for numbers up to 100000:
sub run() {
my $max = 100000;
say "Factorions <= $max:";
for ( 1 .. $max ) {
say $_
if is_factorion($_);
} }
Output:
1
2
145
40585
With this little of output I started doing some online research for factorions and found Sequence A014080. Surprisingly the list above is all factorions that exist.
I then also wrote a routine that uses this list to check if $n
is a factorion.
sub is_factorion_a014080($n) {
## complete list of all factorians - see https://oeis.org/A014080
state @A014080 = ( 1, 2, 145, 40585 );
$n == $_ } @A014080;
first { }
And adapted my driver code a little to chose randomly between the two solutions for each number that it checks.
sub run() {
my $max = 100000;
say "Factorions <= $max:";
for ( 1 .. $max ) {
my $fn = ( \&is_factorion, \&is_factorion_a014080 )[ int( rand(2) ) ];
say $_ if $fn->($_);
} }
Haskell Solution
I also solved this task in Haskell
by pattern matching on n
and comparing it to the four possible results:
isFactorion :: Integer -> Bool
1 = True
isFactorion 2 = True
isFactorion 145 = True
isFactorion 40585 = True
isFactorion = False isFactorion _
Raku Solution
In raku
I used a unit main
to make the whole script the main routine. This
main routine will also handle command line arguments for us. I use the utf-8
elem operator ∈
to check if the given number is a member of the A014080
sequence. I struggled a little with what looks like some typing errors. I had to
multiply the argument $n
with 1
to coerce it into a number, otherwise the
code wouldn’t work.
sub MAIN(Int $n);
unit my @A014080 = 1, 2, 145, 40585;
# Seems we have to coerce the argument $n into a number first by multiplying by
# 1. Didn't expect that.
say $n*1 ∈ @A014080;
There is no comment section on this site. For questions, suggestions or errors in my post or solution, please create an issue over here or drop me a mail:
my $mail = join('@', 'pwc', join('.', 'pankoff', 'net'));