Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/usr/bin/perl
- use strict;
- use warnings;
- use List::AllUtils qw(pairwise sum);
- $| = 1;
- $; = ',';
- my %Dirs = ('e' => [ 0, 1], 'w' => [ 0,-1],
- 'ne' => [ 1, 0], 'nw' => [ 1,-1],
- 'se' => [-1, 1], 'sw' => [-1, 0]);
- my %flipped;
- foreach my $walk (<>) {
- my @hex = (0, 0);
- foreach my $step ($walk =~ m#(e|w|ne|nw|se|sw)#g) {
- @hex = pairwise { $a + $b } @hex, @{$Dirs{$step}};
- }
- $flipped{$hex[0],$hex[1]} = !$flipped{$hex[0],$hex[1]};
- }
- my @black_tiles = grep { $flipped{$_} } keys %flipped;
- print "Part 1: ", scalar( @black_tiles ), "\n";
- # Part 2
- sub get_neighbours {
- my @tile = split( /,/, shift );
- return (map { join( ',', pairwise { $a + $b } @tile, @$_ ) } values %Dirs);
- }
- # Initialize active tiles with counts of adjacent black tiles
- my %active;
- foreach my $tile (@black_tiles) {
- $active{$tile} //= 0;
- $active{$_}++ foreach (&get_neighbours( $tile ));
- }
- my $count = @black_tiles;
- foreach my $time (1 .. 100) {
- my %next;
- foreach my $tile (keys %active) {
- if ($flipped{$tile}) {
- if (!$active{$tile} || $active{$tile} > 2) {
- $flipped{$tile} = 0;
- $count--;
- }
- } elsif ($active{$tile} == 2) {
- $flipped{$tile} = 1;
- $count++;
- }
- if ($flipped{$tile}) {
- $next{$tile} //= 0;
- $next{$_}++ foreach (&get_neighbours( $tile ));
- }
- }
- print "[$time] $count \r";
- %active = %next;
- }
- print "\n";
Add Comment
Please, Sign In to add comment