-
Notifications
You must be signed in to change notification settings - Fork 0
/
aoc09b
executable file
·112 lines (96 loc) · 2.55 KB
/
aoc09b
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
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
#!/usr/bin/env perl6
use v6.c;
# Advent of Code 2018 day 9 -- https://adventofcode.com/2018/day/9
$*OUT.out-buffer = False; # Autoflush
class Marble
{
has Int $.value;
has Marble $.next is rw = self;
has Marble $.previous is rw = self;
method forward(Int $n = 1)
{
my $m = self;
$m .= next for ^$n;
return $m;
}
method reverse(Int $n = 1)
{
my $m = self;
$m .= previous for ^$n;
return $m;
}
method insert(Int $value)
{
my $m = Marble.new(:$value, :next(self), :previous(self.previous));
$!previous.next = $m;
$!previous = $m;
return $m;
}
method remove
{
$!previous.next = $!next;
$!next.previous = $!previous;
return $!next;
}
method Numeric { self.value }
method Str
{
my $str = $!value;
loop (my $m = $!next; $m.value != $!value; $m .= next) {
$str ~= '-' ~ $m.value;
}
return $str;
}
method gist { self.Str }
}
class MarbleGame
{
has $.num-players;
has $.highest-marble;
has $!current = Marble.new(:value(0));
has $!count = 1;
has $!player = 0;
has @!scores = 0 xx $!num-players;
method play
{
for 1..$!highest-marble -> $marble {
if $marble %% 23 {
$!current .= reverse(7);
@!scores[$!player] += $marble + $!current;
$!current .= remove;
$!count--;
}
else {
$!current .= forward(2);
$!current .= insert($marble);
$!count++;
}
$!player = ($!player + 1) % $!num-players;
}
}
method winning-score
{
self.play if $!count < 2;
return @!scores.max;
}
}
#| Play marble game
multi sub MAIN(Int $highest-marble is copy, Int $num-players)
{
say "With $num-players players and $highest-marble marbles, the winning score is: ",
MarbleGame.new(:$num-players, :$highest-marble).winning-score;
$highest-marble ×= 100;
say "With $num-players players and $highest-marble marbles, the winning score is: ",
MarbleGame.new(:$num-players, :$highest-marble).winning-score;
}
#| Get game parameters from a file
multi sub MAIN(Str $inputfile where *.IO.f)
{
my ($num-players, $highest-marble) = $inputfile.IO.slurp.comb(/\d+/)».Int;
MAIN($highest-marble, $num-players);
}
#| Get game parameters from the default file (aoc09.input)
multi sub MAIN()
{
MAIN(~$*PROGRAM.sibling('aoc09.input'));
}