aoc2021

Advent of Code 2021 solutions in Perl.
git clone git://git.samirparikh.com/aoc2021
Log | Files | Refs | README

commit 1a3a73f8b5f5020bb49dffa661aeea97fba3a4f5
parent 028f7dda3e5fd6029abd17e3842cfcc708e0343d
Author: Samir Parikh <noreply@samirparikh.com>
Date:   Sat,  4 Dec 2021 13:51:11 +0000

refactor day03-2.pl to provide a cleaner solution

Diffstat:
Mday03-2.pl | 94+++++++++++++++++++++++++------------------------------------------------------
1 file changed, 30 insertions(+), 64 deletions(-)

diff --git a/day03-2.pl b/day03-2.pl @@ -14,83 +14,49 @@ open my $filehandle, '<', $input_filename or chomp( my @input = ( <$filehandle> ) ); +# Advent of Code 2021 Day 03 Part 2 my $len = length($input[0]) - 1; # number of bits - 1 -my @numbers; -foreach (@input) { -# take each line, split it into an array, and push a reference to -# that annonymous array into @numbers - push (@numbers, [split //]); -} - -# create array copy to store oxygen generator rating candidates -my @ogr = @numbers; -#while ( scalar ( @ogr ) > 1 ) { # while we still have more than one ogr -foreach my $index (0 .. $len) { # iterate through each bit - # bit counters - my %count_0 = (); - my %count_1 = (); - foreach my $num (@ogr) { # iterate through each ogr candidate - if ($num->[$index]) { # bit at position index is 1 - $count_1{$index}++; +my @ogr = @input; +foreach my $index (0 .. $len) { # first iterate through indices... + my $count; + foreach my $line (@ogr) { # ...and then through the numbers/lines + if ( (split //, $line)[$index] ) { # if bit at position $index is 1 + $count++; # postive or zero count means 1 } else { - $count_0{$index}++; - } - } - my $most_freq_bit = - ($count_1{$index} >= $count_0{$index}) ? 1 : 0; - my @temp_ogr; # temp array to hold elements whose bits match the - # most frequently occuring one -# go through each remaining element and only keep those where the bit at -# index matches the most frequently occurring one and put in temporary -# array - foreach my $num (@ogr) { - if ($num->[$index] == $most_freq_bit) { - push( @temp_ogr, $num); + $count--; # negative count means 0 } } + # now see which is the most common bit at the index + # if $count < 0, it's 0; otherwise it's 1 + my $most_freq_bit = ($count < 0) ? 0 : 1; + my @temp_ogr = grep { (split //)[$index] == $most_freq_bit } @ogr; @ogr = @temp_ogr; # replace real array with temporary array last if (scalar( @ogr ) == 1); } -#} - -# ++++++++++++++++++++++++++++++++++++++++++++++++ - -# create array copy to store CO2 scrubber rating candidates -my @co2sr= @numbers; - -#while ( scalar ( @co2sr ) > 1 ) { # while we still have more than one co2sr -#say "size of co2sr is ", scalar(@co2sr); -foreach my $index (0 .. $len) { # iterate through each bit - # bit counters - my %count_0 = (); - my %count_1 = (); - foreach my $num (@co2sr) { # iterate through each co2sr candidate - if ($num->[$index]) { # bit at position index is 1 - $count_1{$index}++; +my @co2sr = @input; +foreach my $index (0 .. $len) { # first iterate through indices... + my $count; + foreach my $line (@co2sr) { # ...and then through the numbers/lines + if ( (split //, $line)[$index] ) { # if bit at position $index is 1 + $count++; # postive or zero count means 1 } else { - $count_0{$index}++; - } - } - my $most_freq_bit = - ($count_1{$index} >= $count_0{$index}) ? 1 : 0; - #say "most frequent bit at index $index is $most_freq_bit"; - my @temp_co2sr; # temp array to hold elements whose bits match the - # most frequently occuring one -# go through each remaining element and only keep those where the bit at -# index matches the most frequently occurring one and put in temporary -# array - foreach my $num (@co2sr) { - unless ($num->[$index] == $most_freq_bit) { - #say "keeping @$num"; - push( @temp_co2sr, $num); + $count--; # negative count means 0 } } + # now see which is the most common bit at the index + # if $count < 0, it's 0; otherwise it's 1 + my $most_freq_bit = ($count < 0) ? 0 : 1; + my @temp_co2sr = grep { (split //)[$index] != $most_freq_bit } @co2sr; @co2sr = @temp_co2sr; # replace real array with temporary array - #say "size of co2sr down here is now ", scalar(@co2sr); last if (scalar( @co2sr ) == 1); } -#} -say oct("0b" . join("", @{$ogr[0]})) * oct("0b" . join("", @{$co2sr[0]})); +# From the perlfunc man page: +# oct EXPR +# oct Interprets EXPR as an octal string and returns the corresponding +# value. (If EXPR happens to start off with "0x", interprets it as a +# hex string. If EXPR starts off with "0b", it is interpreted as a +# binary string. Leading whitespace is ignored in all three cases.) +say oct("0b" . join("", @ogr)) * oct("0b" . join("", @co2sr));