/ domm

I hack Perl for fun and profit

Follow me on twitter!
Atom Icom ... on Atom!
03.01.2021: Bulk downloading all episodes of a podcast
12.12.2020: Advent of Code Day 12 - sailing to a pause
11.12.2020: Advent of Code Day 11 - slow SeatGoL
10.12.2020: Advent of Code Day 10 - trillion jolts
09.12.2020: Advent of Code Day 9 - while learning
08.12.2020: Advent of Code Day 8 - running code
07.12.2020: Advent of Code Day 7 - baggy recursion
06.12.2020: Advent of Code Day 6 - simple counting

Today was rather easy (or at least I did not run of into the completely wrong direction like yesterday).

Part 1

At first I thought about reusing the "parser" from day 4, but then I just went with an iterative approach and used an empty line as a reset:

my $count;
my %gq;
while (<>) {
    chomp;
    if (!$_) {
        $count += keys %gq;
        %gq=();
    }
    else {
        map { $gq{$_}++ } split //;
    }
}
$count += keys %gq;
say $count;

I use a hash %gc (group_count) to how often each answer is present; if the line is empty (!$_), I count the number of keys in the hash (i.e. the number of distinct questions answered) and reset the group_count hash %gq.

Part 2

Basically the same as Part 1, but we now need to count the number of members per group, so we can identify which question was answered by all group members (i.e. where the count of answers is equal to the number of members).

my $count;
my %gq;
my $members=0;
while (<>) {
    chomp;
    if (!$_) {
        count_group();
    }
    else {
        $members++;
        map { $gq{$_}++ } split //;
    }
}

say count_group();

sub count_group {
    my @all_yes = grep { $gq{$_} == $members } keys %gq;
    %gq=();
    $members=0;
    $count += @all_yes;
}

Due to the way I did the "parsing" (I didn't, I just follow the input stream and reset on newline) I have to do the calculation once more after all the input is processed (basically a final reset). So I put the calculation in a function (the first time I use in function in this years AoC!).

Part 2 - No Spaces

my($c,$m,%q);for(<>,$/){chomp;if(!$_){$c+=grep{$q{$_}==$m}
keys%q;%q=();$m=0}else{$m++;map{$q{$_}++}split//}}say$c;

Only a tiny bit of "smartness" here: instead of calling the calculation again after processing the input, I just add a newline to the input, thus forcing a final calculation. (That's the $/ after <>, and also for is shorter than while..)

Stats & Links

Comments (via senph)

05.12.2020: Advent of Code Day 5 - hard fail
04.12.2020: Advent of Code Day 4 - validating regex
>>>>>>>>>>
<