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:
M | day03-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));