#!/usr/bin/perl use strict; use warnings; use List::Util qw(sum product); # Read in grid, adding sentinel .s around all four sides (because substr) my @grid = map { chomp; ".$_." } <>; push ( @grid, '.' x length $grid[0] ); unshift( @grid, '.' x length $grid[0] ); my $part1 = 0; my %gears; # hash from location of gear to list of part numbers foreach my $line (1 .. $#grid - 1) { while ($grid[$line] =~ m#(\d+)#g) { my $num = $1; my $x = pos($grid[$line]) - length($num) - 1; # left edge of search block # Search surrounding block for parts and gears my $found = 0; foreach my $y ($line - 1 .. $line + 1) { my $str = substr( $grid[$y], $x, length($num) + 2 ); $found = 1 if ($str =~ m#[^.0-9]#); push( $gears{$y, $x + pos($str)}->@*, $num ) while ($str =~ m#\*#g); } $part1 += $num if ($found); } } my $part2 = sum map { product @$_ } grep { @$_ == 2 } values %gears; print "Part 1: $part1\n"; print "Part 2: $part2\n";