grammar DeepArray {
rule TOP { '[' ~ ']' <element>* % ',' }
rule element { <number> || <TOP> }
token number { \d+ }
}
class DeepArrayActions {
method TOP($/) { make $<element>».made.Array }
method element($/) { make $<number> ?? $<number>.made !! $<TOP>.made }
method number($/) { make $/.Int }
}
multi compare(UInt:D \a, UInt:D \b) { a <=> b }
multi compare(UInt:D \a, @B) { compare([a], @B) }
multi compare(@A, UInt:D \b) { compare(@A, [b]) }
multi compare(@A, @B --> Order:D) {
return +@B == 0 ?? Order::Same !! Order::Less if +@A == 0;
return Order::More if +@B == 0;
compare(@A[0], @B[0]) or compare(@A.tail(*-1), @B.tail(*-1))
}
my @p1 = $*IN.split("\n\n").map({ .lines.map({ DeepArray.parse($_, :actions(DeepArrayActions)).made }).Array });
put 'part 1: ', (1..+@p1).grep({ compare(|@p1[$_-1]) == Order::Less }).sum;
my @p2 = (|@p1[*;*], [[2],], [[6],], []).sort({ compare($^a, $^b) });
put 'part 2: ', @p2.first(* eqv [[2],], :k) * @p2.first(* eqv [[6],], :k);