From: Jan "Yenya" Kasprzak Date: Sun, 20 Dec 2020 09:22:08 +0000 (+0100) Subject: Day 20: manual coding, coding, coding X-Git-Url: https://www.fi.muni.cz/~kas/git//home/kas/public_html/git/?a=commitdiff_plain;h=3dcbc8cbbed0a020192974ba29b73f0164b49ce2;p=aoc2020.git Day 20: manual coding, coding, coding --- diff --git a/39.pl b/39.pl new file mode 100755 index 0000000..2b88a89 --- /dev/null +++ b/39.pl @@ -0,0 +1,75 @@ +#!/usr/bin/perl -w + +use strict; + +local $/ = "\n\n"; + +sub invbits { + my ($in) = @_; + return (($in & 1) << 9) + | (($in & 2) << 7) + | (($in & 4) << 5) + | (($in & 8) << 3) + | (($in & 16) << 1) + | (($in & 32) >> 1) + | (($in & 64) >> 3) + | (($in & 128) >> 5) + | (($in & 256) >> 7) + | (($in & 512) >> 9); +} + +my %tiles; +my %sides; +my %side2tiles; +while (<>) { + my ($id, @rows) = split /\n/; + $id =~ s/Tile //; + $id =~ s/://; + @rows = map { y/#./10/; oct "0b$_" } @rows; + $tiles{$id} = \@rows; + $sides{$id} = [ + $rows[0], + (($rows[0] & 1) << 9) + | (($rows[1] & 1) << 8) + | (($rows[2] & 1) << 7) + | (($rows[3] & 1) << 6) + | (($rows[4] & 1) << 5) + | (($rows[5] & 1) << 4) + | (($rows[6] & 1) << 3) + | (($rows[7] & 1) << 2) + | (($rows[8] & 1) << 1) + | (($rows[9] & 1) << 0), + $rows[9], + (($rows[0] & 512) >> 0) + | (($rows[1] & 512) >> 1) + | (($rows[2] & 512) >> 2) + | (($rows[3] & 512) >> 3) + | (($rows[4] & 512) >> 4) + | (($rows[5] & 512) >> 5) + | (($rows[6] & 512) >> 6) + | (($rows[7] & 512) >> 7) + | (($rows[8] & 512) >> 8) + | (($rows[9] & 512) >> 9), + ]; + print "Tile <$id> sides ", join(',', @{ $sides{$id} }), "\n"; + for my $side (@{ $sides{$id} }) { + push @{ $side2tiles{$side} }, $id; + push @{ $side2tiles{invbits($side)} }, $id; + } +} + +my %single_ids; +for my $side (keys %side2tiles) { + print "side $side: ", join(',', @{ $side2tiles{$side} }), "\n"; + # print "inv ", invbits($side), "\n"; + if (scalar @{ $side2tiles{$side} } == 1 + && scalar @{ $side2tiles{invbits($side)} } == 1) { + print "side $side of tile $side2tiles{$side}->[0] is single\n"; + $single_ids{$side2tiles{$side}->[0]}++; + } + +} + +my @corners = grep { $single_ids{$_} == 4 } keys %single_ids; +print join('*', @corners), '=', eval join('*', @corners), "\n" + diff --git a/40.pl b/40.pl new file mode 100755 index 0000000..df479d9 --- /dev/null +++ b/40.pl @@ -0,0 +1,158 @@ +#!/usr/bin/perl -w + +use strict; + +local $/ = "\n\n"; + +sub rev { + my ($in) = @_; + return join('', reverse split //, $in); +} + + +my %tiles; +my %sides; +my %side2tiles; +while (<>) { + my ($id, @rows) = split /\n/; + $id =~ s/Tile //; + $id =~ s/://; + $tiles{$id} = \@rows; + $sides{$id} = [ + $rows[0], + join('', map { substr($_, -1, 1) } @rows), + rev($rows[-1]), + rev(join('', map { substr($_, 0, 1) } @rows)), + ]; + print "Tile <$id> sides ", join(' ', @{ $sides{$id} }), "\n"; + my $i = 0; + for my $side (@{ $sides{$id} }) { + $side2tiles{$side}->{$id} = $i; + $side2tiles{rev($side)}->{$id} = $i+4; + $i++; + } +} + +my $dim = 12; +my $next = '###.#.#...'; + +# my $dim = 3; +# my $next = '#...##.#..'; +my $next_id = -1; +my $map; +my %seen; + +for my $y (0 .. $dim-1) { + my ($id) = grep { $_ != $next_id } keys %{ $side2tiles{$next} }; + my $side = $side2tiles{$next}->{$id}; + $map->[$y][0] = [ $id, $side ]; + die "$id seen again\n" + if $seen{$id}; + $seen{$id} = 1; + my $next_side = $side > 3 + ? (($side - 1) & 3) + : ($side + 1) & 3; + $next = $sides{$id}->[$next_side]; + $next = rev($next) if $side > 3; + my $top_side = $side; + print "id=$id, side=$side, next_side=$next_side, top_side=$top_side, next=|$next|\n"; + $next_id = $id; + + for my $x (1 .. $dim-1) { + ($id) = grep { $_ != $next_id } keys %{ $side2tiles{$next} }; + $side = $side2tiles{$next}->{$id}; + die "$id seen again\n" + if $seen{$id}; + $seen{$id} = 1; + my $top_side = ((($side & 3) + (($side >> 2) ? 1 : -1)) & 3) | (($side & 4) ^ 4); + $map->[$y][$x] = [ $id, $top_side ]; + $next_side = (($side + 2) & 3); + $next = $sides{$id}->[$next_side]; + $next = rev($next) if $side < 4; + $next_id = $id; + print "id=$id, side=$side, next_side=$next_side, top_side=$top_side, next=|$next|\n"; + } + + print "\n"; + + ($next_id, $next_side) = @{ $map->[$y][0] }; + $next = $sides{$next_id}->[($next_side + 2) & 3]; + $next = rev($next) if $next_side < 4; + print "bottom side of $next_id = |$next|\n"; +} + +my $shortmap = ''; +for my $y (0 .. 8*$dim-1) { + my $y1 = 1 + ($y % 8); + for my $x (0 .. 8*$dim-1) { + my $x1 = 1 + ($x % 8); + my ($id, $or) = @{ $map->[int($y/8)][int($x/8)] }; + my ($x2, $y2) = ($x1, $y1); + if ($or == 1) { + ($x2, $y2) = (9-$y1, $x1); + } elsif ($or == 2) { + ($x2, $y2) = (9-$x1, 9-$y1); + } elsif ($or == 3) { + ($x2, $y2) = ($y1, 9-$x1); + } elsif ($or == 4) { + ($x2, $y2) = (9-$x1, $y1); + } elsif ($or == 5) { + ($x2, $y2) = (9-$y1, 9-$x1); + } elsif ($or == 6) { + ($x2, $y2) = ($x1, 9-$y1); + } elsif ($or == 7) { + ($x2, $y2) = ($y1, $x1); + } + $shortmap .= substr($tiles{$id}->[$y2], $x2, 1); + } + $shortmap .= "\n"; +} + +print join("\n", $shortmap), "\n"; + +my $monster = join('[\.#\n]' x ($dim * 8 - 20 + 1), map { $a=$_; $a=~ s/\./[\.#]/g; $a } + '..................#.', + '#....##....##....###', + '.#..#..#..#..#..#...' +); + +$monster = ".(?=$monster)"; +print "monster=$monster\n"; + +for (1 .. 2) { + for (1 .. 4) { + my $count; + if (my $count =()= $shortmap =~ /($monster)/g) { + print "$count matches\n"; + my $hashes =()= $shortmap =~ /#/g; + print "$hashes-$count*15=", $hashes-$count*15, "\n"; + exit 0; + } + my $newmap = ''; + for my $y (0 .. 8*$dim-1) { + for my $x (0 .. 8*$dim-1) { + print "$x,$y\n"; + $newmap .= substr($shortmap, + $y + (8*$dim+1)*(8*$dim-$x-1), 1); + } + $newmap .= "\n"; + } + print "\nRotate:\n$newmap\n"; + $shortmap = $newmap; + } + my $newmap; + for my $y (0 .. 8*$dim-1) { + for my $x (0 .. 8*$dim-1) { + $newmap .= substr($shortmap, + $x + (8*$dim+1)*(8*$dim-$y-1), 1); + } + $newmap .= "\n"; + } + $shortmap = $newmap; + print "\nFlip:\n$newmap\n"; + +} + + + +