55 lines
1.1 KiB
OCaml
55 lines
1.1 KiB
OCaml
let rec read_line in_chan =
|
|
try
|
|
let line = input_line in_chan in
|
|
line :: read_line in_chan
|
|
with End_of_file ->
|
|
close_in in_chan;
|
|
[]
|
|
|
|
let char_list str = List.init (String.length str) (String.get str)
|
|
|
|
let read_file path = open_in path |> read_line |> List.map char_list
|
|
|
|
let is_closing ch = List.mem ch [')'; ']'; '}'; '>']
|
|
|
|
let is_pair o c =
|
|
match (o, c) with
|
|
| ('(', ')') -> true
|
|
| ('[', ']') -> true
|
|
| ('{', '}') -> true
|
|
| ('<', '>') -> true
|
|
| (_, _) -> false
|
|
|
|
let rec rem_score stack points =
|
|
let score ch =
|
|
match ch with
|
|
| '(' -> 1
|
|
| '[' -> 2
|
|
| '{' -> 3
|
|
| '<' -> 4
|
|
| _ -> 0
|
|
in
|
|
|
|
match stack with
|
|
| [] -> points
|
|
| x :: xs -> rem_score xs (points * 5 + (score x))
|
|
|
|
let err_score ch =
|
|
match ch with
|
|
| ')' -> 3
|
|
| ']' -> 57
|
|
| '}' -> 1197
|
|
| '>' -> 25137
|
|
| _ -> 0
|
|
|
|
|
|
let rec scores line stack error_score =
|
|
match (line, stack) with
|
|
| ([], _) -> (error_score, rem_score stack 0)
|
|
| (x :: xs, y :: ys) when is_closing x ->
|
|
if is_pair y x
|
|
then scores xs ys error_score
|
|
else scores xs ys (error_score + err_score x)
|
|
| (x :: xs, _) ->
|
|
scores xs (x :: stack) error_score
|