summaryrefslogtreecommitdiffstats
path: root/2020/day9/xmas_encoder.pl
blob: 4fdcb9b4bc954126fa6036912e9c4c4e1e22cf96 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
use strict;
use warnings;
use DDP;
use Smart::Comments;
use Tie::File;
use List::Util qw(min max);

tie my @xmas, 'Tie::File', "input" or die "no input present, $!";

my %preamble;
# because it's easier this way trust me
my @also_queue;
my $goalnum;

foreach my $idx (0 .. $#xmas) {
    if ($idx < 25) {
        my $t = int($xmas[$idx]);
        $preamble{$t} = 1;
        push @also_queue, $t;
    } else {
        my $nextnum = int($xmas[$idx]);
        my $tester = 0;
        foreach my $num (keys %preamble) {
            $tester++;
            if (exists $preamble{$nextnum - $num}) {
                my $old = shift @also_queue;
                delete $preamble{$old};
                push @also_queue, $nextnum;
                $preamble{$nextnum} = 1;
                last;
            }
        }

        if (not scalar grep { $_ == $nextnum } @also_queue) {
            $goalnum = $nextnum;
            print("XMAS weak num: $goalnum\n");
            last;
        }
    }
}

# find the contiguous set

my @contiguous;
my $total = 0;

foreach my $curr (@xmas) {
    if ($total + $curr < $goalnum) {
        $total += $curr;
        push @contiguous, $curr;
    } elsif ($total + $curr > $goalnum) {
        while ($total + $curr > $goalnum) {
            my $evictee = shift @contiguous;
            if (not defined $evictee) {
                last;
            }
            $total -= $evictee;
        }
        push @contiguous, $curr;
        $total += $curr;
    }

    if ($total == $goalnum) {
        print(min(@contiguous) + max(@contiguous));
        p @contiguous;
        exit;
    }
}

untie @xmas;