summaryrefslogtreecommitdiff
path: root/6.pl
blob: 6705a676f21acedcd08769d228d968694acb92ff (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
#!/usr/bin/env perl
use strict;
use warnings;

my @original_grid;
my @grid;
my @pos = (0,0);
my @start_pos = (0,0);
my %seen_positions;

open(my $fh, "6-input.txt") or die;
while (<$fh>) { chomp; push @original_grid, [split //]; }
close($fh);

@grid = map { [@$_] } @original_grid;
for (my $i=0; $i<scalar @grid; $i++) {
  for (my $j=0; $j<scalar @{$grid[$i]}; $j++) {
    if ($grid[$i][$j] eq '^') {
      $start_pos[0] = $i;
      $start_pos[1] = $j;
    }
  }
}

$pos[0] = $start_pos[0];
$pos[1] = $start_pos[1];

sub tick {
  my ($position, $grid) = @_;
  my $direction = $grid[$pos[0]][$pos[1]];
  if ($direction eq '^') {
      if ($pos[0]-1 < 0) { $grid[$pos[0]][$pos[1]] = 'X'; }
      elsif ($pos[0]-1 >= 0 and ($grid[$pos[0]-1][$pos[1]] eq '.' or $grid[$pos[0]-1][$pos[1]] eq 'X')) {
        $grid[$pos[0]][$pos[1]] = 'X';
        $pos[0]--;
        $grid[$pos[0]][$pos[1]] = '^';
      }
      else { $grid[$pos[0]][$pos[1]] = '>'; }
  } elsif ($direction eq '>') {
    if ($pos[1]+1 >= scalar @{$grid[$pos[0]]}) { $grid[$pos[0]][$pos[1]] = 'X'; }
    elsif ($pos[1]+1 < scalar @{$grid[$pos[0]]} and ($grid[$pos[0]][$pos[1]+1] eq '.' or $grid[$pos[0]][$pos[1]+1] eq 'X')) {
      $grid[$pos[0]][$pos[1]] = 'X';
      $pos[1]++;
      $grid[$pos[0]][$pos[1]] = '>';
    }
    else { $grid[$pos[0]][$pos[1]] = 'V'; }
  } elsif ($direction eq 'V') {
    if ($pos[0]+1 >= scalar @grid) { $grid[$pos[0]][$pos[1]] = 'X'; }
    elsif ($pos[0]+1 < scalar @grid and ($grid[$pos[0]+1][$pos[1]] eq '.' or $grid[$pos[0]+1][$pos[1]] eq 'X')) {
      $grid[$pos[0]][$pos[1]] = 'X';
      $pos[0]++;
      $grid[$pos[0]][$pos[1]] = 'V';
    }
    else { $grid[$pos[0]][$pos[1]] = '<'; }
  } elsif ($direction eq '<') {
    if ($pos[1]-1 < 0) { $grid[$pos[0]][$pos[1]] = 'X'; }
    elsif ($pos[1]-1 >= 0 and ($grid[$pos[0]][$pos[1]-1] eq '.' or $grid[$pos[0]][$pos[1]-1] eq 'X')) {
      $grid[$pos[0]][$pos[1]] = 'X';
      $pos[1]--;
      $grid[$pos[0]][$pos[1]] = '<';
    }
    else { $grid[$pos[0]][$pos[1]] = '^'; }
  } else { return 0; }
  return 1;
}

while (tick(\@pos, \@grid)) { $seen_positions{"$pos[0],$pos[1]"} = 1; }
my $pone = 0;
foreach(@grid) { foreach (@$_) { $pone++ if $_ eq 'X'; } }
print "puzzle 1: ", $pone, "\n";

my $loops = 0;
for (my $i=0; $i<scalar @original_grid; $i++) {
  for (my $j=0; $j<scalar @{$original_grid[$i]}; $j++) {
    if ($original_grid[$i][$j] eq '.' and defined $seen_positions{"$i,$j"}) {
      @grid = map { [@$_] } @original_grid;
      $pos[0] = $start_pos[0];
      $pos[1] = $start_pos[1];
      $grid[$i][$j] = 'O';
      my %seen_position;
      LOOP: while (tick(\@pos, \@grid)) {
        my $direction = $grid[$pos[0]][$pos[1]];
        if (not defined $seen_position{"$pos[0],$pos[1]"}) {
            $seen_position{"$pos[0],$pos[1]"} = [$direction];
            next;
        }
        foreach (@{ $seen_position{"$pos[0],$pos[1]"} }) {
          if ($_ eq $direction) { $loops++; last LOOP; }
        }
        push @{ $seen_position{"$pos[0],$pos[1]"} }, $direction;
      }
    }
  }
}

print "puzzle 2: ", $loops, "\n";