--- /dev/null
+#!/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;
+ }
+}
+
--- /dev/null
+#!/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[$_];
+}
--- /dev/null
+#!/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";
+
--- /dev/null
+#!/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";
+
--- /dev/null
+#!/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";
--- /dev/null
+#!/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";
--- /dev/null
+#!/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";
--- /dev/null
+#!/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";
+}
--- /dev/null
+#!/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;
+}
+
--- /dev/null
+#!/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;
+ }
+}
+
--- /dev/null
+#!/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";
--- /dev/null
+#!/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;
+ }
+ }
+}
+
--- /dev/null
+#!/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";
+
--- /dev/null
+#!/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;
+}
+
+
--- /dev/null
+#!/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;
+}
+
+
--- /dev/null
+#!/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";
+
--- /dev/null
+#!/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";
+
--- /dev/null
+#!/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";
+
--- /dev/null
+#!/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";
+
--- /dev/null
+#!/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";
--- /dev/null
+#!/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);
+ }
+}
--- /dev/null
+#!/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;
+}
+
+
+
--- /dev/null
+#!/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";
+
--- /dev/null
+#!/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;
+}
+
+
+
--- /dev/null
+#!/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";
--- /dev/null
+#!/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";
--- /dev/null
+#!/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";
+
--- /dev/null
+#!/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";
+
--- /dev/null
+#!/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";
--- /dev/null
+#!/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";
--- /dev/null
+#!/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";
--- /dev/null
+#!/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";
--- /dev/null
+#!/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";
--- /dev/null
+#!/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";
+
--- /dev/null
+#!/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, $_);
+}
+
--- /dev/null
+#!/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";
--- /dev/null
+#!/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";
--- /dev/null
+#!/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";
--- /dev/null
+#!/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;
+}
+
--- /dev/null
+#!/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;
--- /dev/null
+#!/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";
--- /dev/null
+#!/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";
--- /dev/null
+#!/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";
+}
+
--- /dev/null
+#!/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";
+ }
+}
+
--- /dev/null
+#!/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";
+
+
+
--- /dev/null
+#!/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";
+
--- /dev/null
+#!/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";
+
--- /dev/null
+#!/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";
+
--- /dev/null
+perl -lnE 'y/FBRL/0110/;$x=$_ if$x<$_}{say oct"0b$x"'
--- /dev/null
+#!/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";