Solve day 3 part 2
This commit is contained in:
parent
5b21b1db58
commit
69f8318732
57
day_3.sml
57
day_3.sml
@ -1,30 +1,63 @@
|
|||||||
|
datatype instruction = NOOP | DO | DONT | MUL of (int * int)
|
||||||
|
|
||||||
fun numberAt (i : int) = fn (s : string) =>
|
fun numberAt (i : int) = fn (s : string) =>
|
||||||
if i >= String.size s then NONE
|
if i >= String.size s then NONE
|
||||||
else SOME (Substring.takel Char.isDigit (Substring.extract (s, i, NONE)))
|
else SOME (Substring.takel Char.isDigit (Substring.extract (s, i, NONE)))
|
||||||
|
|
||||||
fun substrToInt (n : substring) = valOf (Int.fromString (Substring.string n))
|
fun startsWith (needle : string, haystack : string, pos : int) =
|
||||||
|
size haystack > pos + size needle andalso String.substring (haystack, pos, size needle) = needle
|
||||||
|
|
||||||
fun sum (l : int list) : int = foldl (op +) 0 l
|
fun substrToInt (n : substring) = valOf (Int.fromString (Substring.string n))
|
||||||
|
|
||||||
val file = TextIO.openIn "day_3.txt"
|
val file = TextIO.openIn "day_3.txt"
|
||||||
val input = TextIO.inputAll file;
|
val input = TextIO.inputAll file;
|
||||||
TextIO.closeIn file;
|
TextIO.closeIn file;
|
||||||
|
|
||||||
val instructions = List.tabulate ((size input), (fn i =>
|
val instructions = List.tabulate ((size input), (fn i =>
|
||||||
|
if startsWith ("do()", input, i) then DO
|
||||||
|
else if startsWith ("don't()", input, i) then DONT
|
||||||
|
else
|
||||||
let
|
let
|
||||||
val n1 = numberAt (i + 4) input
|
val n1 = numberAt (i + 4) input
|
||||||
val n2 = Option.mapPartial (fn n => numberAt (i + 5 + Substring.size n) input) n1
|
val n2 = Option.mapPartial (fn n => numberAt (i + 5 + Substring.size n) input) n1
|
||||||
in
|
in
|
||||||
if isSome n1 andalso isSome n2 andalso
|
case (n1, n2) of
|
||||||
String.substring (input, i, 4) = "mul(" andalso
|
(SOME(a), SOME(b)) =>
|
||||||
String.sub (input, i + 4 + Substring.size (valOf n1)) = #"," andalso
|
if
|
||||||
String.sub (input, i + 5 + Substring.size (valOf n1) + Substring.size (valOf n2)) = #")"
|
startsWith ("mul(", input, i) andalso
|
||||||
then SOME (n1, n2) else NONE
|
String.sub (input, i + 4 + Substring.size a) = #"," andalso
|
||||||
end))
|
String.sub (input, i + 5 + Substring.size a + Substring.size b) = #")"
|
||||||
|
then MUL (substrToInt a, substrToInt b) else NOOP
|
||||||
|
| _ => NOOP
|
||||||
|
end
|
||||||
|
))
|
||||||
|
|
||||||
val instructions = List.mapPartial
|
val instructions = List.filter (fn (ins) => ins <> NOOP) instructions
|
||||||
(fn (num) => case num of SOME (SOME x, SOME y) => SOME (substrToInt x, substrToInt y) | _ => NONE)
|
|
||||||
instructions
|
|
||||||
|
|
||||||
val result = sum (map (op *) instructions)
|
fun calculate (instructions : instruction vector) =
|
||||||
|
Vector.foldl (fn (ins, v) => case ins of MUL (a, b) => v + a * b | _ => v) 0 instructions
|
||||||
|
|
||||||
|
(* Part 1 *)
|
||||||
|
|
||||||
|
val mulOnlyResult = calculate (Vector.fromList instructions)
|
||||||
|
|
||||||
|
(* Part 2 *)
|
||||||
|
|
||||||
|
val filteredInstructions = Vector.mapi
|
||||||
|
(fn (i, ins) =>
|
||||||
|
let
|
||||||
|
val prevInstructions = List.rev (List.take (instructions, i))
|
||||||
|
val lastToggle = List.find (fn (ins) => ins = DO orelse ins = DONT) prevInstructions
|
||||||
|
val shouldMultiply = case lastToggle of
|
||||||
|
SOME (ins) => ins = DO
|
||||||
|
| NONE => true
|
||||||
|
in
|
||||||
|
case ins of
|
||||||
|
MUL (a, b) => if shouldMultiply then ins else NOOP
|
||||||
|
| _ => ins
|
||||||
|
end
|
||||||
|
)
|
||||||
|
(Vector.fromList instructions)
|
||||||
|
|
||||||
|
val allInsResult = calculate filteredInstructions
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user