diff --git a/2024/11/Part1.pm b/2024/11/Part1.pm new file mode 100644 index 0000000..72e6daa --- /dev/null +++ b/2024/11/Part1.pm @@ -0,0 +1,49 @@ +use lib '../../perl-lib'; + +use 5.36.0; + +package Part1; + +use List::AllUtils qw/ sum /; + +use Moo; + +extends 'AoC::Puzzle'; + +has '+input' => default => sub ($self) { + [ split ' ', $self->path_file->slurp ]; +}; + +has nbr_iterations => is => 'ro', default => 25; + +sub evolve ( $self, $stone ) { + return (1) if $stone == 0; + return ( $stone * 2024 ) if length($stone) % 2; + + my $x = $stone % 10**( length($stone) / 2 ); + my $y = int( $stone / 10**( length($stone) / 2 ) ); + return ( $y, $x ); +} + +sub print_line ( $self, @stones ) { + say join " ", @stones; +} + +sub solve ($self) { + my @stones = $self->input->@*; + + my %stones; + $stones{$_}++ for @stones; + + for ( 1 .. $self->nbr_iterations ) { + my %new_stones; + for my $stone ( keys %stones ) { + $new_stones{$_} += $stones{$stone} for $self->evolve($stone); + } + %stones = %new_stones; + } + + return sum values %stones; +} + +1; diff --git a/2024/11/Part2.pm b/2024/11/Part2.pm new file mode 100644 index 0000000..c04f2a2 --- /dev/null +++ b/2024/11/Part2.pm @@ -0,0 +1,13 @@ +use lib '.'; + +use 5.36.0; + +package Part2; + +use Moo; + +extends 'Part1'; + +has '+nbr_iterations' => default => 75; + +1; diff --git a/2024/11/benchmark.pl b/2024/11/benchmark.pl new file mode 100755 index 0000000..bb03310 --- /dev/null +++ b/2024/11/benchmark.pl @@ -0,0 +1,16 @@ +#!/usr/bin/env perl + +use 5.36.0; + +use Benchmark qw/ timethis timeit /; + +use lib qw~ . ~; + +use Part1; +use Part2; + +use Path::Tiny; +use File::Serialize; +my $res; +$res = timethis(0, sub { Part1->new(file=>'input')->solve }, 'part 1'); +$res = timethis(0, sub { Part2->new(file=>'input')->solve }, 'part 2'); diff --git a/2024/11/test.t b/2024/11/test.t new file mode 100644 index 0000000..3fadf68 --- /dev/null +++ b/2024/11/test.t @@ -0,0 +1,21 @@ +use lib qw~ . ~; + +use Part1; +use Part2; + +use Test2::V0; +use Path::Tiny; +use File::Serialize; + +my $solutions = deserialize_file './solutions.yml'; + +subtest 'part 1' => sub { + is( Part1->new(input=>[125,17])->solve() => 55312 ); + is( Part1->new(file=>'input')->solve() => $solutions->{part1} ); +}; + +subtest 'part 2' => sub { + is( Part2->new(file=>'input')->solve() => $solutions->{part2}); +}; + +done_testing();