copy pasting the rules from last year’s thread:

Rules: no spoilers.

The other rules are made up aswe go along.

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

  • Mii@awful.systems
    link
    fedilink
    English
    arrow-up
    3
    ·
    20 days ago

    Advent of Code is one of these things I wanna do every year and then I end up in fucking end-of-the-year crunch time every December and work for 10-12 hours and really don’t wanna code after work anymore.

    But hey, here’s a quick solution for day 1. Let’s see how far I make it.

    Day 1
    use strict;
    use List::Util qw( min max );
    
    open(FH, '<', $ARGV[0]) or die $!;
    
    my @left;
    my @right;
    
    while (<FH>) {
    	my @nums = split /\s+/, $_;
    	push(@left, $nums[0]);
    	push(@right, $nums[1]);
    }
    
    @left = sort { $b <=> $a } @left;
    @right = sort { $b <=> $a } @right;
    
    my $dist = 0;
    my $sim = 0;
    my $i = 0;
    
    foreach my $lnum (@left) {
    	$sim += $lnum * grep { $_ == $lnum } @right;
    
    	my $rnum = $right[$i++];
    	$dist += max($lnum, $rnum) - min($lnum, $rnum);
    }
    
    print 'Part 1: ', $dist, "\n";
    print 'Part 2: ', $sim, "\n";
    
    close(FH);
    
    • Mii@awful.systems
      link
      fedilink
      English
      arrow-up
      1
      ·
      19 days ago
      Day 2, Part 1
      use strict;
      use List::Util qw( min max );
      
      open(FH, '<', $ARGV[0]) or die $!;
      my @lines;
      while (<FH>) {
      	my @report = split /\s/, $_;
      	push @lines, \@report;
      }
      
      close FH;
      
      sub in_range {
      	my $diff = max($_[0], $_[1]) - min($_[0], $_[1]);
      	return $diff >= 1 && $diff <= 3;
      }
      
      sub is_safe {
      	my $prev = @$_[0];
      	my $dir = 0;
      
      	for (my $i = 1; $i < scalar @$_; ++$i) {
      		my $el = @$_[$i];
      		if ($el > $prev) {
      			return 0 unless $dir >= 0;
      			$dir = 1;
      		} elsif ($el < $prev) {
      			return 0 unless $dir <= 0;
      			$dir = -1;
      		}
      
      		return 0 unless in_range $prev, $el;
      		$prev = $el;
      	}
      
      	return 1;
      }
      
      sub part1 {
      	my $safe_reports = 0;
      
      	foreach (@_) {
      		$safe_reports++ if is_safe @$_;
      	}
      
      	return $safe_reports;
      }
      
      print 'Part 1: ', part1(@lines), "\n";
      

      My part 2 solution didn’t work with the real input but worked with all the test cases I threw at it, so I couldn’t figure out what was wrong with it and I’m too lazy to debug any more right now.

    • Mii@awful.systems
      link
      fedilink
      English
      arrow-up
      1
      ·
      12 days ago

      Yay, day 3 with Regexp magic.

      Day 3
      open(FH, '<', $ARGV[0]) or die $!;
      my $sum = 0;
      my $sum2 = 0;
      
      my $enabled = 1;
      
      while (<FH>) {
          while ($_ =~ /(?:mul\((\d{1,3}),(\d{1,3})\)|(do)\(\)|(don\'t)\(\))/g) {
              $enabled = 1 if $3;
              $enabled = 0 if $4;
              $sum += $1 * $2 if $1 && $2;
              $sum2 += $1 * $2 if $enabled && $1 && $2;
          }
      }
      
      close(FH);
      
      print "Part 1: $sum\n";
      print "Part 2: $sum2\n";