#!/usr/bin/env perl use strict; use warnings; use List::Util qw(reduce); my @reports; while (<>) { my @numbers = split; next unless @numbers; push @reports, \@numbers; } print "Part 1:\n"; my $safe_reports = reduce { $a + $b } map { is_safe(@$_) } @reports; print $safe_reports . "\n"; print "Part 2:\n"; $safe_reports = reduce { $a + $b } map { is_safe_with_modification(@$_) } @reports; print $safe_reports . "\n"; sub is_safe { return (is_increasing(@_) || is_decreasing(@_)) && max_diff(@_); } sub is_safe_with_modification { return 1 if is_safe(@_); # This is really dumb... for (my $i = 0; $i < @_; $i++) { my @to_test = @_; splice @to_test, $i, 1; return 1 if is_safe(@to_test); } return 0; } sub is_increasing { my $prev = shift; for (@_) { return 0 if ($_ <= $prev); $prev = $_; } return 1; } sub is_decreasing { my $prev = shift; for (@_) { return 0 if ($_ >= $prev); $prev = $_; } return 1; } sub max_diff { my $prev = shift; for (@_) { if ((abs($_ - $prev) > 3) || (abs($_ - $prev) < 1)) { return 0; } $prev = $_; } return 1; }