project-euler / project-euler / 148 / calc-num-Y-in-row-ORIG.pl

#!/usr/bin/perl

use strict;
use warnings;

use 5.016;

use integer;
# use Math::BigInt lib => 'GMP', ':constant';

my $BASE = 7;

my @digits;

sub calc_num_Y_in_row_n
{
    my $recurse = sub {
        my ($d_len) = @_;

        if ($d_len <= 0)
        {
            return 0;
        }
        else
        {
            my $big_Y_total = ($digits[$d_len]->{power}-1-$digits[$d_len-1]->{total_mod}) * $digits[$d_len]->{d};

            return $big_Y_total + ($digits[$d_len]->{d}+1) * __SUB__->($d_len-1);
        }
    };

    return $recurse->($#digits);
}

my $sum = 0;

push @digits, {d => 1, power => 1, total_mod => 1};
for my $n (1 .. 999_999_999)
{
    $sum += calc_num_Y_in_row_n();

    if ($n % 10_000 == 0)
    {
        print "Reached $n [Sum == $sum]\n";
    }
}
continue
{
    my $l = 0;
    while ($l < @digits && $digits[$l]{d} == $BASE-1)
    {
        $digits[$l]{d} = 0;
        $digits[$l]{total_mod} = 0;
    }
    continue
    {
        $l++;
    }

    if ($l == @digits)
    {
        my $power = $digits[-1]{power}*$BASE;
        push @digits, {d => 1,
            power => $power,
            total_mod => $digits[-1]{total_mod} + $power,
        };
    }
    else
    {
        $digits[$l]{d}++;
        foreach my $digit (@digits[$l..$#digits])
        {
            $digit->{total_mod}++;
        }
    }
}

# foreach my $n (@ARGV)
# {
#     print "${n}: ", calc_num_Y_in_row_n($n+1), "\n";
# }
print "Final Sum == $sum\n";
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.