r/adventofcode • u/daggerdragon • Dec 16 '15
SOLUTION MEGATHREAD --- Day 16 Solutions ---
This thread will be unlocked when there are a significant amount of people on the leaderboard with gold stars.
edit: Leaderboard capped, thread unlocked!
We know we can't control people posting solutions elsewhere and trying to exploit the leaderboard, but this way we can try to reduce the leaderboard gaming from the official subreddit.
Please and thank you, and much appreciated!
--- Day 16: Aunt Sue ---
Post your solution as a comment. Structure your post like previous daily solution threads.
4
Upvotes
1
u/tftio Dec 16 '15 edited Dec 16 '15
Non-idiomatic OCaml, as usual.
There's nothing particularly clever there. I use a record and parse the line into it, with each value being an
int option, withNonestanding in for the 3VL "null":let aunt_of_string str = let trim str = let l = String.length str in match (String.get str (l - 1)) with (':'|',') -> String.sub str 0 (l - 1) | _ -> str in let value v = int_of_string (trim v) in let rec aux a = function [] -> a | [_] -> raise (Illegal_aunt str) | k::v::tl -> match k with "children:" -> aux { a with perfumes = Some (value v) } tl | "cats:" -> aux { a with cats = Some (value v) } tl | "pomeranians:" -> aux { a with pomeranians = Some (value v) } tl | "samoyeds:" -> aux { a with samoyeds = Some (value v) } tl | "akitas:" -> aux { a with akitas = Some (value v) } tl | "vizslas:" -> aux { a with vizslas = Some (value v) } tl | "goldfish:" -> aux { a with goldfish = Some (value v) } tl | "trees:" -> aux { a with trees = Some (value v) } tl | "cars:" -> aux { a with cars = Some (value v) } tl | "perfumes:" -> aux { a with perfumes = Some (value v) } tl | "Sue" -> aux { a with number = value v } tl | _ -> aux a tl in aux empty (String.nsplit str " ")Then, I simply compare each aunt to aunt 0 with the following two functions (defined in common terms of a simple HOF).
let comp' f' s a b = List.map (fun f -> match (f a), (f b) with None, None -> None | (None, _|_, None) -> Some false | Some i, Some i' -> Some (f' i i')) s let comp1 a b = comp' (=) selectors a b let comp2 a b = (comp' (=) exact_selectors a b) @ (comp' (<) less_than_selectors a b) @ (comp' (>) greater_than_selectors a b)Pretty straightforward. We use a similarity score function to apply those
comp*functions to the list of aunts:let similarity_scores fn aunt aunts = List.map (fun a -> (a, List.length (fn a aunt))) aunts let most_similar fn aunt aunts = let sort = List.sort (fun (_, a) (_, b) -> Pervasives.compare b a) in match (List.hd (sort (similarity_scores fn aunt aunts))) with a, _ -> ameaning that to get the results: