From: Jan "Yenya" Kasprzak Date: Mon, 3 Jan 2022 18:03:20 +0000 (+0100) Subject: Merge branch 'aoc2021' X-Git-Url: https://www.fi.muni.cz/~kas/git//home/kas/public_html/git/?a=commitdiff_plain;h=d636b7ae7bc38e368a2c28544c758b7d5afa282d;hp=db060b1de7867d12a01506d5a846c4b0e5421236;p=aoc.git Merge branch 'aoc2021' --- diff --git a/2020/1.pl b/2020/1.pl new file mode 100755 index 0000000..2052140 --- /dev/null +++ b/2020/1.pl @@ -0,0 +1,20 @@ +#!/usr/bin/perl -w + +use strict; + +my @nums = sort { $a <=> $b } <>; +chomp @nums; + +while (@nums > 1) { + print "Nums: ", join(' ', @nums), "\n"; + my $cmp = $nums[0] + $nums[-1] <=> 2020; + if ($cmp < 0) { + shift @nums; + } elsif ($cmp == 0) { + print "$nums[0]*$nums[-1]=", $nums[0]*$nums[-1], "\n"; + last; + } else { + pop @nums; + } +} + diff --git a/2020/10.pl b/2020/10.pl new file mode 100755 index 0000000..2f7ade1 --- /dev/null +++ b/2020/10.pl @@ -0,0 +1,16 @@ +#!/usr/bin/perl -w + +use strict; + +my @seats; +while (<>) { + chomp; + y/FBRL/0110/; + my $seat = eval "0b$_"; + $seats[$seat] = 1; +} + +for (1 .. $#seats-1) { + print $_, "\n" if $seats[$_-1] && $seats[$_+1] + && !$seats[$_]; +} diff --git a/2020/11.pl b/2020/11.pl new file mode 100755 index 0000000..256c0ec --- /dev/null +++ b/2020/11.pl @@ -0,0 +1,16 @@ +#!/usr/bin/perl -w + +use strict; + +local $/ = "\n\n"; + +my $sum = 0; + +while (<>) { + s/\n//g; + my %q = map { $_ => 1 } split //; + $sum += keys %q; +} + +print "$sum\n"; + diff --git a/2020/12.pl b/2020/12.pl new file mode 100755 index 0000000..c8b97b9 --- /dev/null +++ b/2020/12.pl @@ -0,0 +1,20 @@ +#!/usr/bin/perl -w + +use strict; + +local $/ = "\n\n"; + +my $sum = 0; + +while (<>) { + my $nper = 0; + my %q; + for (split /\n/) { + $nper++; + $q{$_}++ for split //; + } + $sum += grep { $q{$_} == $nper } keys %q; +} + +print "$sum\n"; + diff --git a/2020/13.pl b/2020/13.pl new file mode 100755 index 0000000..93739e0 --- /dev/null +++ b/2020/13.pl @@ -0,0 +1,32 @@ +#!/usr/bin/perl -w + +use strict; + +my %graph; +my $count = 0; + +while (<>) { + my ($bag, $rest) = /\A(.*) bags? contain (.*)./; + if ($rest eq 'no other bags') { + # $graph{$bag} = []; # ale neprojevi se + } else { + for my $contain (split /, /, $rest) { + my ($count, $color) = ($contain =~ /\A(\d+) (.*) bag/); + print "\t$count\t$color.\n"; + push @{ $graph{$color} }, $bag; + } + } +} + +my %seen = ('shiny gold' => 1); +my @todo = 'shiny gold'; + +while (my $color = shift @todo) { + for my $next (@{ $graph{$color} }) { + next if $seen{ $next }; + unshift @todo, $next; + $seen{ $next } = 1; + } +} + +print "Seen ", keys(%seen)-1, " nodes\n"; diff --git a/2020/14.pl b/2020/14.pl new file mode 100755 index 0000000..ab8f8b4 --- /dev/null +++ b/2020/14.pl @@ -0,0 +1,38 @@ +#!/usr/bin/perl -w + +use strict; + +my %graph; +my $count = 0; + +while (<>) { + my ($bag, $rest) = /\A(.*) bags? contain (.*)./; + if ($rest eq 'no other bags') { + $graph{$bag} = []; # ale neprojevi se + } else { + for my $contain (split /, /, $rest) { + my ($count, $color) = ($contain =~ /\A(\d+) (.*) bag/); + push @{ $graph{$bag} }, [ $color => $count ]; + } + } +} + +my %seen = ('shiny gold' => 1); +my %total; + +sub walk { + my ($color) = @_; + + return $total{$color} + if defined $total{$color}; + + $total{$color} = 1; + for my $next (@{ $graph{$color} }) { + my ($ncol, $ncount) = @$next; + $total{$color} += $ncount*walk($ncol); + } + + return $total{$color}; +} + +print "Result is ", walk('shiny gold') - 1, "\n"; diff --git a/2020/15.pl b/2020/15.pl new file mode 100755 index 0000000..f82c817 --- /dev/null +++ b/2020/15.pl @@ -0,0 +1,23 @@ +#!/usr/bin/perl -w + +use strict; + +my @code = map { [ split /\s+/ ] } <>; + +my $acc = 0; +my $pc = 0; +my %seen; + +while (!$seen{$pc}) { + $seen{$pc} = 1; + my ($ins, $arg) = @{ $code[$pc] }; + print "pc=$pc, acc=$acc, $ins $arg\n"; + if ($ins eq 'nop') { + $pc++; + } elsif ($ins eq 'acc') { + $acc += $arg; $pc++; + } elsif ($ins eq 'jmp') { + $pc += $arg; + } +} +print "loop at $pc, acc=$acc\n"; diff --git a/2020/16.pl b/2020/16.pl new file mode 100755 index 0000000..899e942 --- /dev/null +++ b/2020/16.pl @@ -0,0 +1,40 @@ +#!/usr/bin/perl -w + +use strict; + +my @code = map { [ split /\s+/ ] } <>; + +for my $i (0 .. $#code) { + if ($code[$i]->[0] eq 'nop') { + local $code[$i]->[0] = 'jmp'; + interp(\@code); + } elsif ($code[$i]->[0] eq 'jmp') { + local $code[$i]->[0] = 'nop'; + interp(\@code); + } +} + +sub interp { + my ($code) = @_; + my $acc = 0; + my $pc = 0; + my %seen; + + while (!$seen{$pc} && $pc != @$code) { + $seen{$pc} = 1; + my ($ins, $arg) = @{ $code->[$pc] }; + # print "pc=$pc, acc=$acc, $ins $arg\n"; + if ($ins eq 'nop') { + $pc++; + } elsif ($ins eq 'acc') { + $acc += $arg; $pc++; + } elsif ($ins eq 'jmp') { + $pc += $arg; + } + } + if ($pc == @$code) { + print "terminating with acc=$acc.\n"; + exit 0; + } + # print "\n"; +} diff --git a/2020/17.pl b/2020/17.pl new file mode 100755 index 0000000..c972894 --- /dev/null +++ b/2020/17.pl @@ -0,0 +1,25 @@ +#!/usr/bin/perl -w + +use strict; + +my @prev; +my $len = 25; + +while (my $num = <>) { + chomp $num; + if (@prev >= $len) { + shift @prev if @prev > $len; + for my $i (0 .. $len-2) { + for my $j ($i+1 .. $len-1) { + if ($prev[$i]+$prev[$j] == $num) { + goto FOUND; + } + } + } + print "$num is not a sum of ", join(', ', @prev), "\n"; + exit 0; + FOUND: + } + push @prev, $num; +} + diff --git a/2020/18.pl b/2020/18.pl new file mode 100755 index 0000000..3801b4e --- /dev/null +++ b/2020/18.pl @@ -0,0 +1,35 @@ +#!/usr/bin/perl -w + +use strict; + +my @prev; + +my $target = 375054920; + +my $sum = 0; +while (my $num = <>) { + chomp $num; + + $sum += $num; + push @prev, $num; + + print "Adding $num, sum=$sum\n"; + + while ($sum > $target) { + my $n1 = shift @prev; + $sum -= $n1; + print "Removing $n1, sum=$sum\n"; + } + + if ($sum == $target) { + print "found $sum = ", join('+', @prev), "\n"; + my ($min, $max); + for my $n1 (@prev) { + $min = $n1 if !defined $min || $min > $n1; + $max = $n1 if !defined $max || $max < $n1; + } + print "$min+$max=", $min+$max, "\n"; + last; + } +} + diff --git a/2020/19.pl b/2020/19.pl new file mode 100755 index 0000000..c9f7f39 --- /dev/null +++ b/2020/19.pl @@ -0,0 +1,16 @@ +#!/usr/bin/perl -w + +use strict; + +local $/; +my @ads = sort { $a <=> $b } map { chomp; $_ } split /\n/, <>; + +my $prev = 0; +my %diffs; +for my $n (@ads) { + $diffs{ $n - $prev }++; + $prev = $n; +} +$diffs{3}++; + +print $diffs{1} * $diffs{3}, "\n"; diff --git a/2020/2.pl b/2020/2.pl new file mode 100755 index 0000000..d950fae --- /dev/null +++ b/2020/2.pl @@ -0,0 +1,20 @@ +#!/usr/bin/perl -w + +use strict; + +my @nums = sort { $a <=> $b } <>; +chomp @nums; + +my %is_listed = map { $_ => 1 } @nums; + +for my $i (0 .. $#nums-1) { + for my $j ($i .. $#nums) { + my $rest = 2020-$nums[$i]-$nums[$j]; + if ($rest > 0 && $is_listed{$rest} && $rest != $nums[$i] + && $rest != $nums[$j]) { + print "$nums[$i]*$nums[$j]*$rest=", $nums[$i]*$nums[$j]*$rest, "\n"; + last; + } + } +} + diff --git a/2020/20.pl b/2020/20.pl new file mode 100755 index 0000000..09210e2 --- /dev/null +++ b/2020/20.pl @@ -0,0 +1,26 @@ +#!/usr/bin/perl -w + +use strict; +use Data::Dumper; + +local $/; +my @ads = sort { $a <=> $b } map { chomp; $_ } split /\n/, <>; + +my $prev = 0; +my $ones = 0; +my $total = 1; +my @ones2count = qw(1 1 2 4 7); +push @ads, $ads[-1]+3; +for my $n (@ads) { + if ($n - $prev == 1) { + $ones++; + } else { + print "$ones ones + 3, total=$total*$ones2count[$ones]\n"; + $total *= $ones2count[$ones]; + $ones = 0; + } + $prev = $n; +} + +print "total=$total\n"; + diff --git a/2020/21.pl b/2020/21.pl new file mode 100755 index 0000000..4a3d0ba --- /dev/null +++ b/2020/21.pl @@ -0,0 +1,55 @@ +#!/usr/bin/perl -w + +use strict; + +my @seats = map { chomp; [ split // ] } (<>); + +my $cols = @{ $seats[0] }; +my $rows = @seats; + +print "$cols x $rows\n"; + +while (1) { + my $was_change = 0; + my $occup = 0; + my @newseats; + for my $row (0 .. $rows-1) { + my @newrow; + for my $col (0 .. $cols-1) { + my $neigh = ''; + for my $add ([-1, -1], [-1, 0], [-1, 1], + [0, -1], [0, 1], + [1, -1], [1, 0], [1, 1]) { + my $row1 = $row + $add->[0]; + my $col1 = $col + $add->[1]; + next if $row1 >= $rows || $row1 < 0 + || $col1 >= $cols || $col1 < 0; + $neigh .= $seats[$row1]->[$col1]; + } + my $neigh_empty =()= $neigh =~ /L/g; + my $neigh_occup =()= $neigh =~ /#/g; + + if ($seats[$row]->[$col] eq 'L' && !$neigh_occup) { + push @newrow, '#'; + $was_change = 1; + $occup++; + } elsif ($seats[$row]->[$col] eq '#' && $neigh_occup >= 4) { + push @newrow, 'L'; + $was_change = 1; + } else { + push @newrow, $seats[$row]->[$col]; + $occup++ if $seats[$row]->[$col] eq '#'; + } + } + push @newseats, \@newrow; + } + @seats = @newseats; + #for my $row (@seats) { + # print @$row, "\n"; + #} + print "$occup occupied seats\n"; + # print "\n"; + last if !$was_change; +} + + diff --git a/2020/22.pl b/2020/22.pl new file mode 100755 index 0000000..eb4a0ff --- /dev/null +++ b/2020/22.pl @@ -0,0 +1,74 @@ +#!/usr/bin/perl -w + +use strict; + +my @seats = map { chomp; [ split // ] } (<>); + +my $cols = @{ $seats[0] }; +my $rows = @seats; + +print "$cols x $rows\n"; + +my @neighs; +for my $row (0 .. $rows-1) { + my @neigh_row; + for my $col (0 .. $cols-1) { + my @neigh_seats; + for my $add ([-1, -1], [-1, 0], [-1, 1], + [0, -1], [0, 1], + [1, -1], [1, 0], [1, 1]) { + my ($row1, $col1) = ($row, $col); + while (1) { + $row1 += $add->[0]; + $col1 += $add->[1]; + last if $row1 >= $rows || $row1 < 0 + || $col1 >= $cols || $col1 < 0; + if ($seats[$row1]->[$col1] ne '.') { + push @neigh_seats, [$row1, $col1]; + last; + } + } + } + push @neigh_row, \@neigh_seats; + } + push @neighs, \@neigh_row; +} + +while (1) { + my $was_change = 0; + my $occup = 0; + my @newseats; + for my $row (0 .. $rows-1) { + my @newrow; + for my $col (0 .. $cols-1) { + my $neigh = ''; + for my $nl (@{ $neighs[$row]->[$col] }) { + $neigh .= $seats[$nl->[0]]->[$nl->[1]]; + } + my $neigh_empty =()= $neigh =~ /L/g; + my $neigh_occup =()= $neigh =~ /#/g; + + if ($seats[$row]->[$col] eq 'L' && !$neigh_occup) { + push @newrow, '#'; + $was_change = 1; + $occup++; + } elsif ($seats[$row]->[$col] eq '#' && $neigh_occup >= 5) { + push @newrow, 'L'; + $was_change = 1; + } else { + push @newrow, $seats[$row]->[$col]; + $occup++ if $seats[$row]->[$col] eq '#'; + } + } + push @newseats, \@newrow; + } + @seats = @newseats; + # for my $row (@seats) { + # print @$row, "\n"; + # } + print "$occup occupied seats\n"; + # print "\n"; + last if !$was_change; +} + + diff --git a/2020/23.pl b/2020/23.pl new file mode 100755 index 0000000..0ffeb01 --- /dev/null +++ b/2020/23.pl @@ -0,0 +1,32 @@ +#!/usr/bin/perl -w + +use strict; + +my ($x, $y, $dir) = (0, 0, 'E'); + +while (<>) { + my ($cmd, $num) = /\A(.)(\d+)/; + print "cmd=$cmd, num=$num: "; + if ($cmd eq 'F') { + $cmd = $dir; + } + if ($cmd eq 'R') { + $num += 90; + $dir =~ y/NESW/ESWN/ while $num -= 90; + } elsif ($cmd eq 'L') { + $num += 90; + $dir =~ y/NESW/WNES/ while $num -= 90; + } elsif ($cmd eq 'N') { + $y += $num; + } elsif ($cmd eq 'S') { + $y -= $num; + } elsif ($cmd eq 'E') { + $x += $num; + } elsif ($cmd eq 'W') { + $x -= $num; + } + print " at ($x, $y, $dir)\n"; +} + +print abs($x) + abs($y), "\n"; + diff --git a/2020/24.pl b/2020/24.pl new file mode 100755 index 0000000..29b1fdf --- /dev/null +++ b/2020/24.pl @@ -0,0 +1,38 @@ +#!/usr/bin/perl -w + +use strict; + +my ($wx, $wy, $x, $y) = (10, 1); + +while (<>) { + my ($cmd, $num) = /\A(.)(\d+)/; + print "cmd=$cmd, num=$num: "; + if ($cmd eq 'F') { + $x += $num*$wx; + $y += $num*$wy; + } elsif ($cmd eq 'R') { + while (($num -= 90) >= 0) { + my $tmp = $wx; + $wx = $wy; + $wy = -$tmp; + } + } elsif ($cmd eq 'L') { + while (($num -= 90) >= 0) { + my $tmp = $wy; + $wy = $wx; + $wx = -$tmp; + } + } elsif ($cmd eq 'N') { + $wy += $num; + } elsif ($cmd eq 'S') { + $wy -= $num; + } elsif ($cmd eq 'E') { + $wx += $num; + } elsif ($cmd eq 'W') { + $wx -= $num; + } + print " at ($x, $y, $wx, $wy)\n"; +} + +print abs($x) + abs($y), "\n"; + diff --git a/2020/25.pl b/2020/25.pl new file mode 100755 index 0000000..60b72ca --- /dev/null +++ b/2020/25.pl @@ -0,0 +1,19 @@ +#!/usr/bin/perl -w + +use strict; + +my $timestamp = <>; +my @buses = grep { /\d+/ } split /,/, <>; + +my ($min_del, $min_bus); +for my $bus (@buses) { + my $delay = $bus*(1+int(($timestamp-1)/$bus))-$timestamp; + print "Bus $bus delay $delay\n"; + if (!defined $min_del || $min_del > $delay) { + $min_bus = $bus; + $min_del = $delay; + } +} + +print "$min_bus * $min_del = ", $min_bus * $min_del, "\n"; + diff --git a/2020/26.pl b/2020/26.pl new file mode 100755 index 0000000..90d07ae --- /dev/null +++ b/2020/26.pl @@ -0,0 +1,34 @@ +#!/usr/bin/perl -w + +use strict; + +my $timestamp = <>; +my @buses = split /,/, <>; + +my $mins = 1; +my %bus_time; +my $first = shift @buses; +for my $bus (@buses) { + if ($bus =~ /\d/) { + $bus_time{$bus} = $mins % $bus; + print "Bus $bus at t+$mins ($bus_time{$bus})\n"; + } + $mins++; +} + +@buses = grep /\d/, @buses; + +my $t = $first; +my $add = $first; + +for my $bus (keys %bus_time) { + print "bus $bus at $bus_time{$bus}\n"; + while (1) { + print "t=$t, add=$add\n"; + last if ($t + $bus_time{$bus}) % $bus == 0; + $t += $add; + } + $add *= $bus; +} +print "t=$t\n"; + diff --git a/2020/27.pl b/2020/27.pl new file mode 100755 index 0000000..a17a382 --- /dev/null +++ b/2020/27.pl @@ -0,0 +1,26 @@ +#!/usr/bin/perl -w + +use strict; +no warnings 'portable'; + +my @mem; + +my ($andm, $orm); +while (<>) { + chomp; + if (/mask = (\S+)/) { + ($orm, $andm) = ($1, $1); + $andm =~ s/X/1/g; $andm = oct "0b$andm"; + $orm =~ s/X/0/g; $orm = oct "0b$orm"; + print "andm=$andm\n orm=$orm\n"; + next; + } + if (/mem\[(\d+)\] = (\d+)/) { + $mem[$1] = ($2 | $orm) & $andm; + print "mem[$1] = $2 => $mem[$1]\n"; + } +} + +my $sum; +for (@mem) { $sum += $_ if defined $_ }; +print "Sum=$sum\n"; diff --git a/2020/28.pl b/2020/28.pl new file mode 100755 index 0000000..edf339e --- /dev/null +++ b/2020/28.pl @@ -0,0 +1,39 @@ +#!/usr/bin/perl -w + +use strict; +no warnings 'portable'; + +my %mem; + +my ($floatm, $orm); +while (<>) { + chomp; + if (/mask = (\S+)/) { + ($orm, $floatm) = ($1, $1); + $floatm =~ s/1/0/g; + $orm =~ s/X/0/g; $orm = oct "0b$orm"; + next; + } + if (/mem\[(\d+)\] = (\d+)/) { + my $data = $2; + for my $addr (addr2list($1|$orm, $floatm)) { + $mem{$addr} = $data; + # print "mem[$addr=", pack("b*", $addr),"] = $2\n"; + } + } +} + +my $sum; +for (keys %mem) { $sum += $mem{$_} }; +print "Sum=$sum\n"; + +sub addr2list { + my ($addr, $mask) = @_; + if ($mask =~ s/X/0/) { + my $off = length $'; + return (addr2list($addr | (1 << $off), $mask), + addr2list($addr & ~(1 << $off), $mask)); + } else { + return ($addr); + } +} diff --git a/2020/29.pl b/2020/29.pl new file mode 100755 index 0000000..e99bf39 --- /dev/null +++ b/2020/29.pl @@ -0,0 +1,28 @@ +#!/usr/bin/perl -w + +use strict; + +my @start = map { chomp; $_ } split /,/, <>; + +my $turn = 0; +my %nums; +my $num; + +while ($turn < 2020) { + $turn++; + if (@start) { + $num = shift @start; + } + my $next; + if (defined $nums{$num}) { + $next = $turn - $nums{$num}; + } else { + $next = 0; + } + $nums{$num} = $turn; + print "turn $turn, num=$num\n"; + $num = $next; +} + + + diff --git a/2020/3.pl b/2020/3.pl new file mode 100755 index 0000000..2865016 --- /dev/null +++ b/2020/3.pl @@ -0,0 +1,22 @@ +#!/usr/bin/perl -w + +use strict; + +my $count = 0; + +while (<>) { + my ($min, $max, $letter, $pass) = /\A(\d+)-(\d+)\s+(\S):\s+(\S+)\s*\z/; + if (!defined $pass) { + print "Divny radek $_\n"; + next; + } + + + my $chars =()= ($pass =~ /$letter/g); + + # print "$min-$max $letter: [$pass] - $chars\n"; + $count++ if $chars >= $min && $chars <= $max; +} + +print $count, "\n"; + diff --git a/2020/30.pl b/2020/30.pl new file mode 100755 index 0000000..838171d --- /dev/null +++ b/2020/30.pl @@ -0,0 +1,29 @@ +#!/usr/bin/perl -w + +use strict; + +my @start = map { chomp; $_ } split /,/, <>; + +my $turn = 0; +my %nums; +my $num; + +while ($turn < 30000000) { + $turn++; + if (@start) { + $num = shift @start; + } + my $next; + if (defined $nums{$num}) { + $next = $turn - $nums{$num}; + } else { + $next = 0; + } + $nums{$num} = $turn; + print "turn $turn, num=$num\n" + if $turn % 1_000_000 == 0; + $num = $next; +} + + + diff --git a/2020/31.pl b/2020/31.pl new file mode 100755 index 0000000..ad2fc0e --- /dev/null +++ b/2020/31.pl @@ -0,0 +1,36 @@ +#!/usr/bin/perl -w + +use strict; + +local $/ = "\n\n"; +my @ranges; +for (split /\n/, <>) { + my (@cls) = /\A(.*): (\d+)-(\d+) or (\d+)-(\d+)/; + print "$2:$3,$4:$5.\n"; + push @ranges, [$2, $3], [$4, $5]; +} + +$_ = <>; +my @your = /(\d+)/g; +print "Your:", join("|", @your), "\n"; + +my $sum = 0; +# my @nearby; +for (split /\n/, <>) { + next if !/\d/; + my @n = /(\d+)/g; + # print "nearby:", join("|", @n), "\n"; + # push @nearby, \@n; + NUM: + for my $num (@n) { + for my $r (@ranges) { + if ($num >= $r->[0] && $num <= $r->[1]) { + next NUM; + } + } + print "$num is invalid\n"; + $sum += $num; + } +} + +print "sum=$sum\n"; diff --git a/2020/32.pl b/2020/32.pl new file mode 100755 index 0000000..f033a41 --- /dev/null +++ b/2020/32.pl @@ -0,0 +1,71 @@ +#!/usr/bin/perl -w + +use strict; + +local $/ = "\n\n"; +my @classes; +for (split /\n/, <>) { + my (@cls) = /\A(.*): (\d+)-(\d+) or (\d+)-(\d+)/; + print "$2:$3,$4:$5.\n"; + push @classes, \@cls; +} + +$_ = <>; +my @your = /(\d+)/g; +print "Your:", join("|", @your), "\n"; + +my @nearby; +TICKET: +for (split /\n/, <>) { + next if !/\d/; + my @n = /(\d+)/g; + NUM: + for my $num (@n) { + for my $r (@classes) { + if (($num >= $r->[1] && $num <= $r->[2]) + || $num >= $r->[3] && $num <= $r->[4]) { + next NUM; + } + } + next TICKET; + } + # print "nearby:", join("|", @n), "\n"; + push @nearby, \@n; +} + +my %valid_cols; +for my $cls (@classes) { + my ($name, $f1, $t1, $f2, $t2) = @$cls; + # print "Class $name:\n"; + COL: + for my $col (0 .. $#your) { + # print "col $col\n"; + for my $ticket (@nearby) { + if (($ticket->[$col] < $f1 || $ticket->[$col] > $t1) + && $ticket->[$col] < $f2 || $ticket->[$col] > $t2) { + next COL; + } + } + $valid_cols{$name}->{$col} = 1; + print "$name can be $col\n"; + } +} + +my $mul = 1; +LOOP: +while (keys %valid_cols) { + for my $class (keys %valid_cols) { + if (keys %{ $valid_cols{$class} } == 1) { + my ($col) = keys %{ $valid_cols{$class} }; + print "$class is $col\n"; + delete $valid_cols{$class}; + for my $cl1 (keys %valid_cols) { + delete $valid_cols{$cl1}->{$col}; + } + $mul *= $your[$col] if $class =~ /\Adeparture/; + next LOOP; + } + } +} + +print "Total: $mul\n"; diff --git a/2020/33.pl b/2020/33.pl new file mode 100755 index 0000000..c8085ae --- /dev/null +++ b/2020/33.pl @@ -0,0 +1,75 @@ +#!/usr/bin/perl -w + +use strict; + +my $is_active; + +my ($min_x, $min_y, $min_z) = (-1, -1, -1); +my ($max_x, $max_y, $max_z) = (0, 0, 1); + +my $y = 0; +while (<>) { + chomp; + my $x = 0; + for (split //) { + $is_active->{"$x,$y,0"} = 1 + if $_ eq '#'; + print "Active $x,$y,0\n"; + $x++; + } + $max_x = $x; + $y++; +} +$max_y = $y; + +my $iter = 0; +while ($iter < 6) { + my $new_active; + my ($new_min_x, $new_min_y, $new_min_z) = ($max_x, $max_y, $max_z); + my ($new_max_x, $new_max_y, $new_max_z) = ($min_x, $min_y, $min_z); + print "iter $iter x=$min_x:$max_x, y=$min_y:$max_y, z=$min_z:$max_z\n"; + for my $z ($min_z .. $max_z) { + for my $y ($min_y .. $max_y) { + for my $x ($min_x .. $max_x) { + # print "Trying $x,$y,$z\n"; + my $count = 0; + for my $neigh ( + [-1, -1, -1], [-1, -1, 0], [-1, -1, 1], + [-1, 0, -1 ], [-1, 0, 0], [-1, 0, 1], + [-1, 1, -1 ], [-1, 1, 0], [-1, 1, 1], + [0, -1, -1], [0, -1, 0], [0, -1, 1], + [0, 0, -1 ], [0, 0, 1], + [0, 1, -1 ], [0, 1, 0], [0, 1, 1], + [1, -1, -1], [1, -1, 0], [1, -1, 1], + [1, 0, -1 ], [1, 0, 0], [1, 0, 1], + [1, 1, -1 ], [1, 1, 0], [1, 1, 1],) { + my ($nx, $ny, $nz) = @$neigh; + $nx += $x; $ny += $y; $nz += $z; + $count++ if $is_active->{"$nx,$ny,$nz"}; + } + # print "$count neighbours\n"; + if (($is_active->{"$x,$y,$z"} && ($count == 2 || $count == 3)) + || (!$is_active->{"$x,$y,$z"} && $count == 3)) { + $new_active->{"$x,$y,$z"} = 1; + # print "new active: $x, $y, $z\n"; + $new_min_x = $x if $x < $new_min_x; + $new_min_y = $y if $y < $new_min_y; + $new_min_z = $z if $z < $new_min_z; + $new_max_x = $x if $x > $new_max_x; + $new_max_y = $y if $y > $new_max_y; + $new_max_z = $z if $z > $new_max_z; + } + } } } + $min_x = $new_min_x-1; + $min_y = $new_min_y-1; + $min_z = $new_min_z-1; + $max_x = $new_max_x+1; + $max_y = $new_max_y+1; + $max_z = $new_max_z+1; + + $is_active = $new_active; + $iter++; +} + +print "Acive: ", scalar keys %$is_active, "\n"; + diff --git a/2020/34.pl b/2020/34.pl new file mode 100755 index 0000000..501265c --- /dev/null +++ b/2020/34.pl @@ -0,0 +1,79 @@ +#!/usr/bin/perl -w + +use strict; + +my $is_active; + +my ($min_x, $min_y, $min_z, $min_q) = (-1, -1, -1, -1); +my ($max_x, $max_y, $max_z, $max_q) = (0, 0, 1, 1); + +my $y = 0; +while (<>) { + chomp; + my $x = 0; + for (split //) { + $is_active->{"$x,$y,0,0"} = 1 + if $_ eq '#'; + print "Active $x,$y,0,0\n"; + $x++; + } + $max_x = $x; + $y++; +} +$max_y = $y; + +my $iter = 0; +while ($iter < 6) { + my $new_active; + my ($new_min_x, $new_min_y, $new_min_z, $new_min_q) + = ($max_x, $max_y, $max_z, $max_q); + my ($new_max_x, $new_max_y, $new_max_z, $new_max_q) + = ($min_x, $min_y, $min_z, $min_q); + print "iter $iter x=$min_x:$max_x, y=$min_y:$max_y, z=$min_z:$max_z, q=$min_q:$max_q\n"; + for my $q ($min_q .. $max_q) { + for my $z ($min_z .. $max_z) { + for my $y ($min_y .. $max_y) { + for my $x ($min_x .. $max_x) { + # print "Trying $x,$y,$z,$q: "; + my $count = 0; + for my $nx (-1 .. 1) { + for my $ny (-1 .. 1) { + for my $nz (-1 .. 1) { + for my $nq (-1 .. 1) { + next if $nx == 0 && $ny == 0 && $nz == 0 && $nq == 0; + my $mx = $nx + $x; + my $my = $ny + $y; + my $mz = $nz + $z; + my $mq = $nq + $q; + $count++ if $is_active->{"$mx,$my,$mz,$mq"}; + } } } } + # print "$count neighbours\n"; + if (($is_active->{"$x,$y,$z,$q"} && ($count == 2 || $count == 3)) + || (!$is_active->{"$x,$y,$z,$q"} && $count == 3)) { + $new_active->{"$x,$y,$z,$q"} = 1; + # print "new active: $x, $y, $z, $q\n"; + $new_min_x = $x if $x < $new_min_x; + $new_min_y = $y if $y < $new_min_y; + $new_min_z = $z if $z < $new_min_z; + $new_min_q = $q if $q < $new_min_q; + $new_max_x = $x if $x > $new_max_x; + $new_max_y = $y if $y > $new_max_y; + $new_max_z = $z if $z > $new_max_z; + $new_max_q = $q if $q > $new_max_q; + } + } } } } + $min_x = $new_min_x-1; + $min_y = $new_min_y-1; + $min_z = $new_min_z-1; + $min_q = $new_min_q-1; + $max_x = $new_max_x+1; + $max_y = $new_max_y+1; + $max_z = $new_max_z+1; + $max_q = $new_max_q+1; + + $is_active = $new_active; + $iter++; +} + +print "Acive: ", scalar keys %$is_active, "\n"; + diff --git a/2020/35.pl b/2020/35.pl new file mode 100755 index 0000000..5582de3 --- /dev/null +++ b/2020/35.pl @@ -0,0 +1,13 @@ +#!/usr/bin/perl -w + +use strict; + +my $sum = 0; +while (<>) { + chomp; + 1 while + s/\((\d+)\)/$1/ || + s/(\d+)\s*([\+\*])\s*(\d+)/"$1$2$3"/ee; + $sum += $_; +} +print "sum=$sum\n"; diff --git a/2020/36.pl b/2020/36.pl new file mode 100755 index 0000000..4e25489 --- /dev/null +++ b/2020/36.pl @@ -0,0 +1,11 @@ +#!/usr/bin/perl -w + +use strict; + +$_ = '(('.join(')+(', <>).'))'; +s/\s//g; +1 while + s/\((\d+)\)/$1/ || + s/(\([^\(\)]*?)(\d+)\+(\d+)([^\(\)]*\))/$1.($2+$3).$4/e || + s/(\([^\(\)]*?)(\d+)\*(\d+)([^\(\)]*\))/$1.($2*$3).$4/e; +print "sum=$_\n"; diff --git a/2020/37.pl b/2020/37.pl new file mode 100755 index 0000000..97b5487 --- /dev/null +++ b/2020/37.pl @@ -0,0 +1,49 @@ +#!/usr/bin/perl -w + +use strict; + +my %rules; +my %subrules; +my %final; + +while (<>) { + chomp; + last if /^$/; + my ($id, $rest) = /\A(\d+): (.*)\z/; + if ($rest =~ /"(.)"/) { + $final{$id} = $1; + next; + } + my @alts; + my @subalts; + for my $seq (split /\|/, $rest) { + push @alts, [ $seq =~ /(\d+)/g ]; + push @subalts, ($seq =~ /(\d+)/g); + } + $rules{$id} = \@alts; + $subrules{$id} = \@subalts; +} + +while (keys %rules) { + RULE: + for my $id (keys %rules) { + for my $subr (@{ $subrules{$id} }) { + next RULE if !defined $final{$subr}; + } + $final{$id} = '(?:(?:' . join(')|(?:', map { + join('', map { $final{$_} } @$_) + } @{ $rules{$id} }) .'))'; + print "\$final{$id} = $final{$id}\n"; + delete $rules{$id}; + } +} + +my $re = '\A'.$final{0}.'\z'; + +my $count = 0; +while (<>) { + chomp; + $count++ if ($_ =~ /$re/); +} + +print "$count matched\n"; diff --git a/2020/38.pl b/2020/38.pl new file mode 100755 index 0000000..7707c8e --- /dev/null +++ b/2020/38.pl @@ -0,0 +1,74 @@ +#!/usr/bin/perl -w + +use strict; + +my %rules; +my %subrules; +my %final; + +while (<>) { + chomp; + last if /^$/; + my ($id, $rest) = /\A(\d+): (.*)\z/; + if ($rest =~ /"(.)"/) { + $final{$id} = $1; + next; + } + my @alts; + my @subalts; + for my $seq (split /\|/, $rest) { + push @alts, [ $seq =~ /(\d+)/g ]; + push @subalts, ($seq =~ /(\d+)/g); + } + $rules{$id} = \@alts; + $subrules{$id} = \@subalts; +} + +while (keys %rules) { + RULE: + for my $id (keys %rules) { + for my $subr (@{ $subrules{$id} }) { + next RULE if !defined $final{$subr}; + } + if ($id == 8) { + $final{$id} = $final{42} . '+'; + delete $rules{$id}; + next RULE; + } + + if ($id == 11) { + $final{$id} = '(?:' . join('|', + $final{42} . $final{31}, + $final{42} x 2 . $final{31} x 2, + $final{42} x 3 . $final{31} x 3, + $final{42} x 4 . $final{31} x 4, + $final{42} x 5 . $final{31} x 5, + $final{42} x 6 . $final{31} x 6, + $final{42} x 7 . $final{31} x 7, + $final{42} x 8 . $final{31} x 8, + $final{42} x 9 . $final{31} x 9, + $final{42} x 10 . $final{31} x 10, + $final{42} x 11 . $final{31} x 11, + $final{42} x 12 . $final{31} x 12, + ) . ')'; + delete $rules{$id}; + next RULE; + } + + $final{$id} = '(?:(?:' . join(')|(?:', map { + join('', map { $final{$_} } @$_) + } @{ $rules{$id} }) .'))'; + print "\$final{$id} = $final{$id}\n"; + delete $rules{$id}; + } +} + +my $re = '\A'.$final{0}.'\z'; + +my $count = 0; +while (<>) { + chomp; + $count++ if ($_ =~ /$re/); +} + +print "$count matched\n"; diff --git a/2020/39.pl b/2020/39.pl new file mode 100755 index 0000000..40f98ab --- /dev/null +++ b/2020/39.pl @@ -0,0 +1,57 @@ +#!/usr/bin/perl -w + +use strict; + +sub rows2str { + my (@rows) = @_; + return join("\n", @rows) . "\n"; +} + +sub rotate { + my ($str) = (@_); + my $dim =()= $str =~ /(\n)/g; + my $newstr = ''; + for my $y (0 .. $dim-1) { + for my $x (0 .. $dim-1) { + $newstr .= substr($str, $y + ($dim+1)*($dim - $x - 1), 1); + } + $newstr .= "\n"; + } + return $newstr; +} + +sub flip { + my ($str) = @_; + return rows2str(map { join('', reverse split //) } split /\n/, $str); +} + +sub rotate_or_flip { + my ($str, $count) = @_; + return $count == 4 ? flip($str) : rotate($str); +} + +sub top_side { + $_[0] =~ /\A(.*?)\n/xms; + return $1; +} + +my %top2tile; + +local $/ = "\n\n"; + +while (<>) { + my ($id, $data) = /\ATile\s+(\d+):\n(.*?\n)\n?\z/xms; + for (1 .. 8) { + push @{ $top2tile{top_side($data)} }, $id; + $data = rotate_or_flip($data, $_); + } +} + +my %single_ids; +for my $row (keys %top2tile) { + next if @{ $top2tile{$row} } != 1; + $single_ids{ $top2tile{$row}->[0] }++; +} + +my @corners = grep { $single_ids{$_} == 4 } keys %single_ids; +print join('*', @corners), '=', eval join('*', @corners), "\n"; diff --git a/2020/4.pl b/2020/4.pl new file mode 100755 index 0000000..d16915a --- /dev/null +++ b/2020/4.pl @@ -0,0 +1,22 @@ +#!/usr/bin/perl -w + +use strict; + +my $count = 0; + +while (<>) { + my ($min, $max, $letter, $pass) = /\A(\d+)-(\d+)\s+(\S):\s+(\S+)\s*\z/; + if (!defined $pass) { + print "Divny radek $_\n"; + next; + } + + no warnings 'substr'; + # no warnings 'uninitialized'; + $count++ if !!(substr($pass, $min-1, 1) eq $letter) + + !!(substr($pass, $max-1, 1) eq $letter) + == 1; +} + +print $count, "\n"; + diff --git a/2020/40.pl b/2020/40.pl new file mode 100755 index 0000000..074e561 --- /dev/null +++ b/2020/40.pl @@ -0,0 +1,124 @@ +#!/usr/bin/perl -w + +use strict; + +sub rows2str { + my (@rows) = @_; + return join("\n", @rows) . "\n"; +} + +sub rotate { + my ($str) = (@_); + my $dim =()= $str =~ /(\n)/g; + my $newstr = ''; + for my $y (0 .. $dim-1) { + for my $x (0 .. $dim-1) { + $newstr .= substr($str, $y + ($dim+1)*($dim - $x - 1), 1); + } + $newstr .= "\n"; + } + return $newstr; +} + +sub flip { + my ($str) = @_; + return rows2str(map { join('', reverse split //) } split /\n/, $str); +} + +sub rotate_or_flip { + my ($str, $count) = @_; + return $count == 4 ? flip($str) : rotate($str); +} + +sub trim { + my ($str) = @_; + my @rows = split /\n/, $str; + shift @rows; + pop @rows; + return map { s/\A.//; s/.\z//; $_ } @rows; +} + +sub top_side { + $_[0] =~ /\A(.*?)\n/xms; + return $1; +} + +sub bottom_side { + $_[0] =~ /\A.*\n(.*?)\n\z/xms; + return $1; +} + +sub left_side { + return join('', map { substr($_, 0, 1) } split /\n/, $_[0]); +} + +sub right_side { + return join('', map { substr($_, -1, 1) } split /\n/, $_[0]); +} + +my (%top2tile, %left2tile); + +local $/ = "\n\n"; + +while (<>) { + my ($id, $data) = /\ATile\s+(\d+):\n(.*?\n)\n?\z/xms; + for (1 .. 8) { + push @{ $top2tile{top_side($data)} }, [ $id, $data ]; + push @{ $left2tile{left_side($data)} }, [ $id, $data ]; + $data = rotate_or_flip($data, $_); + } +} + +# computed in 39.pl +my $dim = 12; +my $top_row = '###.#.#...'; + +# my $dim = 3; +# my $top_row = '#...##.#..'; + +my $top_id = -1; +my @map_rows; +my $data; + +for my $y (0 .. $dim-1) { + my ($id) = grep { $_->[0] != $top_id } @{ $top2tile{$top_row} }; + ($top_id, $data) = @$id; + $top_row = bottom_side($data); + + push @map_rows, trim($data); + + my $right_id = $top_id; + my $right_row = right_side($data); + + for my $x (1 .. $dim-1) { + my ($id) = grep { $_->[0] != $right_id } @{ $left2tile{$right_row} }; + ($right_id, $data) = @$id; + $right_row = right_side($data); + + my $i = @map_rows - 8; + for (trim($data)) { + $map_rows[$i++] .= $_; + } + } +} + +my $map = rows2str(@map_rows); +my $hashes =()= $map =~ /#/g; + +my $monster = '.(?=' + . join('[\.#\n]' x ($dim * 8 - 20 + 1), + map { my $a=$_; $a=~ s/\./[\.#]/g; $a } + '..................#.', + '#....##....##....###', + '.#..#..#..#..#..#...' + ) . ')'; + +for (1 .. 8) { + if (my $count =()= $map =~ /($monster)/g) { + print "$count matches\n"; + print "$hashes-$count*15=", $hashes-$count*15, "\n"; + exit 0; + } + $map = rotate_or_flip($map, $_); +} + diff --git a/2020/41.pl b/2020/41.pl new file mode 100755 index 0000000..846f78e --- /dev/null +++ b/2020/41.pl @@ -0,0 +1,46 @@ +#!/usr/bin/perl -w + +use strict; + +my %allergens; +my %ingredients; +my %in_count; + +while (<>) { + chomp; + my ($ingr, $al) = /\A([^\(]+) \(contains (.*)\)\z/; + my %ingr = map { $_ => 1 } split /\s+/, $ingr; + my @al = split /, /, $al; + for my $al (@al) { + if (defined $allergens{$al}) { + for my $in1 (keys %{ $allergens{$al} }) { + if (! $ingr{$in1}) { + delete $allergens{$al}->{$in1}; + } + } + } else { + $allergens{$al} = { %ingr }; + } + } + for my $in (keys %ingr) { + $ingredients{$in} = {}; + $in_count{$in}++; + } +} + +for my $al (keys %allergens) { + for my $in (keys %{ $allergens{$al} }) { + print "$in can be $al.\n"; + $ingredients{$in}->{$al} = 1; + } +} + +my $sum = 0; +for my $in (keys %ingredients) { + if (keys %{ $ingredients{$in} } == 0) { + # print "$in can't contain allergen\n"; + $sum += $in_count{$in}; + } +} + +print "Sum=$sum\n"; diff --git a/2020/42.pl b/2020/42.pl new file mode 100755 index 0000000..05bf2ac --- /dev/null +++ b/2020/42.pl @@ -0,0 +1,42 @@ +#!/usr/bin/perl -w + +use strict; + +my %allergens; +my %is_al; + +while (<>) { + chomp; + my ($ingr, $al) = /\A([^\(]+) \(contains (.*)\)\z/; + my %ingr = map { $_ => 1 } split /\s+/, $ingr; + my @al = split /, /, $al; + for my $al (@al) { + if (defined $allergens{$al}) { + for my $in1 (keys %{ $allergens{$al} }) { + if (! $ingr{$in1}) { + delete $allergens{$al}->{$in1}; + } + } + } else { + $allergens{$al} = { %ingr }; + } + } +} + +AGAIN: +for my $al (keys %allergens) { + if (keys %{ $allergens{$al} } == 1) { + my $in1; + for my $in (keys %{ $allergens{$al} }) { + $is_al{$in} = $al; + $in1 = $in; + } + delete $allergens{$al}; + for my $al1 (keys %allergens) { + delete $allergens{$al1}->{$in1}; + } + goto AGAIN; + } +} + +print join(',', sort { $is_al{$a} cmp $is_al{$b} } keys %is_al), "\n"; diff --git a/2020/43.pl b/2020/43.pl new file mode 100755 index 0000000..3f6ebe6 --- /dev/null +++ b/2020/43.pl @@ -0,0 +1,28 @@ +#!/usr/bin/perl -w + +use strict; + +local $/ = "\n\n"; + +my @pl1 = <> =~ /^(\d+)$/gxms; +my @pl2 = <> =~ /^(\d+)$/gxms; +print "pl2=@pl2.\n"; + +while (@pl1 && @pl2) { + my $p1 = shift @pl1; + my $p2 = shift @pl2; + print "$p1 vs $p2\n"; + if ($p1 > $p2) { + push @pl1, $p1, $p2; + } else { + push @pl2, $p2, $p1; + } +} + +@pl1 = @pl2 if @pl2; +my $sum = 0; +while (@pl1) { + $sum += +$pl1[0] * @pl1; + shift @pl1; +} +print "sum=$sum\n"; diff --git a/2020/44.pl b/2020/44.pl new file mode 100755 index 0000000..05d941f --- /dev/null +++ b/2020/44.pl @@ -0,0 +1,59 @@ +#!/usr/bin/perl -w + +use strict; + +local $/ = "\n\n"; + +my @pl1 = <> =~ /^(\d+)$/gxms; +my @pl2 = <> =~ /^(\d+)$/gxms; + +print "sum=", play(\@pl1, \@pl2), "\n"; + +sub play { + my ($d1, $d2) = @_; + my @pl1 = @$d1; + my @pl2 = @$d2; + + my %seen; + + while (@pl1 && @pl2) { + my $conf = join('|', @pl1, "#", @pl2); + if ($seen{$conf}++) { + return score(@pl1); + } + my $p1 = shift @pl1; + my $p2 = shift @pl2; + + if ($p1 <= @pl1 && $p2 <= @pl2) { + my @sub1 = @pl1[0 .. $p1-1]; + my @sub2 = @pl2[0 .. $p2-1]; + if (play(\@sub1, \@sub2) > 0) { + push @pl1, $p1, $p2; + } else { + push @pl2, $p2, $p1; + } + } else { + if ($p1 > $p2) { + push @pl1, $p1, $p2; + } else { + push @pl2, $p2, $p1; + } + } + } + if (@pl1) { + return score(@pl1); + } else { + return -score(@pl2); + } +} + +sub score { + my @pl1 = @_; + my $sum = 0; + while (@pl1) { + $sum += +$pl1[0] * @pl1; + shift @pl1; + } + return $sum; +} + diff --git a/2020/45.pl b/2020/45.pl new file mode 100755 index 0000000..b1b5516 --- /dev/null +++ b/2020/45.pl @@ -0,0 +1,20 @@ +#!/usr/bin/perl -w + +use strict; + +my $rounds; +($rounds, $_) = @ARGV; + +while ($rounds--) { + my ($cur) = /\A(.)/; + do { + $cur--; + $cur = 9 if $cur == 0; + } while (/\A.{1,3}$cur/); + + s/\A(.)(...)(.*)$cur(.*)\z/$3$cur$2$4$1/; + print $_, "\n"; +} + +s/\A(.*)1(.*)\z/Result is $2$1\n/; +print; diff --git a/2020/46.pl b/2020/46.pl new file mode 100755 index 0000000..b9744b8 --- /dev/null +++ b/2020/46.pl @@ -0,0 +1,75 @@ +#!/usr/bin/perl -w + +use strict; + +my $rounds; +($rounds, $_) = @ARGV; + +my @cups_nums = split //; +my @cups_pos; +my $i; +for (@cups_nums) { + $cups_pos[$_] = $i++; +} + +my $max = 1_000_000; + +my ($prev, @cups, $one); +for (@cups_nums, 10 .. $max) { + my $cup = { + num => $_, + prev_num => $prev, + next => undef, + }; + push @cups, $cup; + $one = $cup if $cup->{num} == 1; + $prev = $cup; +} + +$prev = $cups[-1]; +for my $cup (@cups) { + $cup->{prev_num} = $cups[$cups_pos[$cup->{num}-1]] + if $cup->{num} > 1 && $cup->{num} <= 10; + $cup->{prev_num} = $cups[-1] + if $cup->{num} == 1; + $prev->{next} = $cup; + $prev = $cup; +} + +# for my $cup (@cups) { +# print $cup->{num}, ": >", $cup->{next}->{num}, " <", $cup->{prev_num}->{num}, "\n"; +# } + +my $cur = $cups[0]; + +while ($rounds--) { + my @pickup; + my $cup = $cur->{next}; + my $dest = $cur->{prev_num}; + my %num_seen; + # print "pickup: "; + for (1..3) { + push @pickup, $cup; + $num_seen{ $cup->{num} } = 1; + # print $cup->{num}, ' '; + $cup = $cup->{next}; + } + $dest = $dest->{prev_num} while $num_seen{$dest->{num}}; + # print " dest: ", $dest->{num}, "\n"; + $cur->{next} = $cup; + my $end = $dest->{next}; + $dest->{next} = $pickup[0]; + $pickup[-1]->{next} = $end; + + $cur = $cur->{next}; + # $end = $cur; + # do { + # print $end->{num}, ','; + # $end = $end->{next}; + # } while ($end->{num} != $cur->{num}); + # print "\n"; + print "round $rounds\n" if $rounds % 100_000 == 0; +} + +print "one -> ", $one->{next}->{num}, '*', $one->{next}->{next}->{num}, + "=", $one->{next}->{num} * $one->{next}->{next}->{num}, "\n"; diff --git a/2020/47.pl b/2020/47.pl new file mode 100755 index 0000000..fca227f --- /dev/null +++ b/2020/47.pl @@ -0,0 +1,29 @@ +#!/usr/bin/perl -w + +use strict; + +my %tiles; + +while (<>) { + chomp; + my ($x, $y) = (0, 0); + while (length) { + s/\A(se|ne|sw|nw|e|w)//; + if ($1 eq 'ne') { + $y++; + } elsif ($1 eq 'e') { + $x++; + } elsif ($1 eq 'se') { + $x++; $y--; + } elsif ($1 eq 'sw') { + $y--; + } elsif ($1 eq 'w') { + $x--; + } elsif ($1 eq 'nw') { + $x--; $y++; + } + } + $tiles{"$x|$y"}++; +} + +print "Tiles=" . (grep { $tiles{$_} % 2 == 1 } keys %tiles)."\n"; diff --git a/2020/48.pl b/2020/48.pl new file mode 100755 index 0000000..f76f993 --- /dev/null +++ b/2020/48.pl @@ -0,0 +1,60 @@ +#!/usr/bin/perl -w + +use strict; + +my %tiles; + +my ($min_x, $max_x, $min_y, $max_y); + +while (<>) { + chomp; + my ($x, $y) = (0, 0); + while (length) { + s/\A(se|ne|sw|nw|e|w)//; + if ($1 eq 'ne') { + $y++; + } elsif ($1 eq 'e') { + $x++; + } elsif ($1 eq 'se') { + $x++; $y--; + } elsif ($1 eq 'sw') { + $y--; + } elsif ($1 eq 'w') { + $x--; + } elsif ($1 eq 'nw') { + $x--; $y++; + } + } + $tiles{"$x|$y"} ^= 1; + $min_x = $x if !defined $min_x || $min_x > $x; + $max_x = $x if !defined $max_x || $max_x < $x; + $min_y = $y if !defined $min_y || $min_y > $y; + $max_y = $y if !defined $max_y || $max_y < $y; +} + + +for (1 .. 100) { + $min_x--; $min_y--; $max_x++, $max_y++; + my %newtiles; + for my $x ($min_x .. $max_x) { + for my $y ($min_y .. $max_y) { + my $count = 0; + $count++ if $tiles{($x+1).'|'.($y)}; # E + $count++ if $tiles{($x).'|'.($y+1)}; # NE + $count++ if $tiles{($x+1).'|'.($y-1)}; # SE + $count++ if $tiles{($x).'|'.($y-1)}; # SW + $count++ if $tiles{($x-1).'|'.($y)}; # W + $count++ if $tiles{($x-1).'|'.($y+1)}; # NW + if ($tiles{"$x|$y"} && ($count == 0 || $count > 2)) { + $newtiles{"$x|$y"} = 0; + } elsif (!$tiles{"$x|$y"} && $count == 2) { + $newtiles{"$x|$y"} = 1; + } else { + $newtiles{"$x|$y"} = $tiles{"$x|$y"}; + } + } + } + %tiles = %newtiles; + print "Tiles=" . (grep { $tiles{$_} } keys %tiles)."\n"; +} + diff --git a/2020/49.pl b/2020/49.pl new file mode 100755 index 0000000..eeeead3 --- /dev/null +++ b/2020/49.pl @@ -0,0 +1,35 @@ +#!/usr/bin/perl -w + +use strict; + +my ($val1, $val2) = (1, 1); +my $iter = 0; +my $subj1 = 7; +my $subj2 = 7; +my ($pub1, $pub2) = @ARGV; + +while (++$iter) { + $val1 *= $subj1; + $val2 *= $subj2; + $val1 %= 20201227; + $val2 %= 20201227; + if ($val1 == $pub1) { + print "$iter loops for subj1\n"; + $val1 = $pub2; + for (2 .. $iter) { + $val1 *= $pub2; + $val1 %= 20201227; + } + print "key=$val1\n"; + } + if ($val2 == $pub2) { + print "$iter loops for subj2\n"; + $val2 = $pub1; + for (2 .. $iter) { + $val2 *= $pub1; + $val2 %= 20201227; + } + print "key=$val2\n"; + } +} + diff --git a/2020/5.pl b/2020/5.pl new file mode 100755 index 0000000..2a7b22d --- /dev/null +++ b/2020/5.pl @@ -0,0 +1,24 @@ +#!/usr/bin/perl -w + +use strict; + +my $field = do { local $/; <> }; +my $rows = $field =~ s/\s//g; +my $flen = length $field; +my $cols = $flen/$rows; + +print "Field has $flen bytes, in $rows rows and $cols cols\n"; + +my $step = $cols + 2; + +my $col = 0; +my $sum = 0; +for my $row (0 .. $rows-1) { + $sum++ if substr($field, $row*$cols + $col, 1) eq '#'; + $col += 3; + $col %= $cols; +} +print "sum=$sum\n"; + + + diff --git a/2020/6.pl b/2020/6.pl new file mode 100755 index 0000000..6749d06 --- /dev/null +++ b/2020/6.pl @@ -0,0 +1,38 @@ +#!/usr/bin/perl -w + +use strict; + +my $field = do { local $/; <> }; +my $rows = $field =~ s/\s//g; +my $flen = length $field; +my $cols = $flen/$rows; + +print "Field has $flen bytes, in $rows rows and $cols cols\n"; + +sub slope { + my ($colstep, $rowstep) = @_; + + $colstep += $cols; + + my $col = 0; + my $sum = 0; + my $row = 0; + while ($row < $rows) { + print "row $row\n"; + $sum++ if substr($field, $row*$cols + $col, 1) eq '#'; + $col += $colstep; + $col %= $cols; + $row += $rowstep; + } + print "$colstep x $rowstep, sum=$sum\n"; + return $sum; +} + +print "Total: ", + slope(1, 1) + * slope(3, 1) + * slope(5, 1) + * slope(7, 1) + * slope(1, 2), + "\n"; + diff --git a/2020/7.pl b/2020/7.pl new file mode 100755 index 0000000..d6147c3 --- /dev/null +++ b/2020/7.pl @@ -0,0 +1,16 @@ +#!/usr/bin/perl -w + +use strict; + +$/ = "\n\n"; + +my $valid = 0; +while (<>) { + $valid++ if ( + grep { /^(?:byr|iyr|eyr|hgt|hcl|ecl|pid):/ } + split /\s+/ + ) == 7; +} + +print "Valid: $valid\n"; + diff --git a/2020/8.pl b/2020/8.pl new file mode 100755 index 0000000..c8e2a20 --- /dev/null +++ b/2020/8.pl @@ -0,0 +1,38 @@ +#!/usr/bin/perl -w + +use strict; + +$/ = "\n\n"; + +my $valid = 0; +while (<>) { + my $correct = 0; + for my $field (split /\s+/) { + print "$field"; + $correct++ + if $field =~ /\Abyr:(\d{4})\z/ + && $1 >= 1920 && $1 <= 2002; + $correct++ + if $field =~ /\Aiyr:(\d{4})\z/ + && $1 >= 2010 && $1 <= 2020; + $correct++ + if $field =~ /\Aeyr:(\d{4})\z/ + && $1 >= 2020 && $1 <= 2030; + $correct++ + if $field =~ /\Ahgt:(\d+)(cm|in)\z/ + && ($2 eq 'cm' && $1 >= 150 && $1 <= 193 + || $2 eq 'in' && $1 >= 59 && $1 <= 76); + $correct++ + if $field =~ /\Ahcl:#[a-f0-9]{6}\z/; + $correct++ + if $field =~ /\Aecl:(?:amb|blu|brn|gry|grn|hzl|oth)\z/; + $correct++ + if $field =~ /\Apid:(?:\d{9})\z/; + print "\t$correct\n"; + } + $valid++ if $correct >= 7; + print "\n"; +} + +print "Valid: $valid\n"; + diff --git a/2020/9-golf.pl b/2020/9-golf.pl new file mode 100644 index 0000000..d941993 --- /dev/null +++ b/2020/9-golf.pl @@ -0,0 +1 @@ +perl -lnE 'y/FBRL/0110/;$x=$_ if$x<$_}{say oct"0b$x"' diff --git a/2020/9.pl b/2020/9.pl new file mode 100755 index 0000000..dcdc4ff --- /dev/null +++ b/2020/9.pl @@ -0,0 +1,13 @@ +#!/usr/bin/perl -w + +use strict; + +my $max = 0; +while (<>) { + chomp; + y/FBRL/0110/; + my $seat = eval "0b$_"; + $max = $seat if $max < $seat; +} + +print $max, "\n";