Rules: no spoilers.

The other rules are made up as we go along.

Share code by link to a forge, home page, pastebin (Eric Wastl has one here) or code section in a comment.

  • @200fifty
    link
    English
    7
    edit-2
    7 months ago

    day 1

    part 1

    perl
    #!/usr/bin/env perl
    
    use strict;
    use warnings;
    use 5.010;
    
    my $total = 0;
    
    for my $line (<>) {
        my @nums = ($line =~ /\d/g);
        $total += $nums[0] * 10 + $nums[-1];
    }
    
    say $total;
    

    part 2

    perl
    #!/usr/bin/env perl
    
    use strict;
    use warnings;
    use v5.010;
    
    my %nums = (one => 1, two => 2, three => 3, four => 4, five => 5, six => 6, seven => 7, eight => 8, nine => 9);
    $nums{$_} = $_ for 1..9;
    
    my $regex = join "|", keys %nums;
    
    my $total = 0;
    
    for my $line (<>) {
        $line =~ /($regex)/;
        my $first_num = $nums{$1};
    
        my $window = 1;
        my $sub = substr $line, -1;
        while ($sub !~ /($regex)/) {
            $window ++;
            $sub = substr $line, -$window;
        }
    
        $sub =~ /($regex)/;
        my $second_num = $nums{$1};
    
        $total += $first_num * 10 + $second_num;
    }
    
    say $total;
    

    Part 2 gave me a surprising amount of trouble. I resolved it by looking at longer and longer substrings from the end of the line in order to find the very last word even if it overlapped, which you can’t do with normal regex split. I doubt this is the most efficient possible solution.

    Also Lemmy is eating my < characters inside code blocks, which seems wrong. Pretend the “&lt;>” part says “<>”, lol

    • @froztbyte
      link
      English
      47 months ago

      lemme is an incredibly hungry little shit, it eats so much

    • @200fifty
      link
      English
      47 months ago

      day 2

      perl
      #!/usr/bin/env perl
      
      use strict;
      use warnings;
      use v5.010;
      use List::Util qw/ max /;
      
      # Parse the input
      
      my %games = ();
      
      for my $line (&lt;>) {
          $line =~ /Game (\d+): (.+)/;
          my $game_id = $1;
          my $game_str = $2;
      
          my @segments = split '; ', $game_str;
          my @game = ();
          for my $segment (@segments) {
              my @counts = split ', ', $segment;
      
              my %colors = (red => 0, blue => 0, green => 0);
              for my $count (@counts) {
                  $count =~ /(\d+) (\w+)/;
                  $colors{$2} = $1;
              }
      
              push @game, { %colors };
          }
      
          $games{$game_id} = [ @game ];
      }
      
      # Part 1
      
      my $part1 = 0;
      
      game: for my $game_id (keys %games) {
          for my $segment (@{$games{$game_id}}) {
              next game if $segment->{red} > 12 || $segment->{green} > 13 || $segment->{blue} > 14;
          }
      
          $part1 += $game_id;
      }
      
      say "Part 1: $part1";
      
      # Part 2
      
      my $part2 = 0;
      
      for my $game (values %games) {
          my ($red, $green, $blue) = (0, 0, 0);
      
          for my $segment (@$game) {
              $red = max $segment->{red}, $red;
              $green = max $segment->{green}, $green;
              $blue = max $segment->{blue}, $blue;
          }
      
          $part2 += $red * $green * $blue;
      }
      
      say "Part 2: $part2";
      

      Found this much easier than day 1 honestly…