Created
December 5, 2016 01:21
-
-
Save keithn/c4d47262f7cf84d04b71505b5b3770a3 to your computer and use it in GitHub Desktop.
Advent Of Code 2016 - Day 4
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module Day4 | |
open System | |
open System.Text.RegularExpressions | |
let input = @" | |
the text the puzzle gave me.... | |
" | |
let (|Regex|_|) pattern input = | |
let m = Regex.Match(input, pattern) | |
if m.Success then Some(List.tail [ for g in m.Groups -> g.Value ]) | |
else None | |
type Room = { name: string; id: int; checksum: string} | |
let toRoom room = | |
match room with | |
| Regex @"(.*)(?<=\-)(\d+)\[(\w+)\]" [ name; id; checksum ] -> Some {name = name.TrimEnd([|'-'|]); id = Convert.ToInt32 id; checksum = checksum} | |
| _ -> None | |
let validRoom room = | |
let grouped = List.ofSeq room.name |> Seq.filter (fun c -> c <> '-') |> Seq.groupBy (fun c -> c) | |
let checksum = grouped | |
|> Seq.map (fun g -> (-Seq.length (snd g), fst g)) | |
|> Seq.sort | |
|> Seq.map (fun t -> (-fst t, snd t)) | |
|> Seq.take 5 | |
|> Seq.map (fun t -> snd t) | |
|> String.Concat | |
checksum = room.checksum | |
let asciiCode (letter:char) = Convert.ToInt32 letter | |
let rotateLetter letter = | |
let code = asciiCode letter | |
if code = asciiCode 'z' then 'a' | |
elif code = asciiCode '-' then ' ' | |
elif code = asciiCode ' ' then ' ' | |
else Convert.ToChar (code + 1) | |
let rec repeat f s n = | |
match n with | |
| 0 -> s | |
| _ -> repeat f (f s) (n-1) | |
let decryptRoomName room = | |
let letters = List.ofSeq room.name | |
let decrypted = letters |> Seq.map (fun l -> repeat rotateLetter l room.id) |> String.Concat | |
(decrypted, room.id) | |
let contains v (s:string) = | |
s.Contains(v) | |
let day4 = | |
printfn "\n\nDay 4\n" | |
let seperators = [|"\n";"\r"|] | |
let lines = input.Split( seperators, StringSplitOptions.RemoveEmptyEntries ) | |
let rooms = Seq.map toRoom lines |> Seq.choose id |> Seq.filter validRoom | |
let decrypted = rooms |> Seq.map decryptRoomName | |
let objectstorage = decrypted |> Seq.filter (fun x -> (fst x) |> contains "object" ) |> Seq.head | |
printfn "Part 1: %A" (Seq.sumBy (fun room -> room.id) rooms) | |
printfn "Part 2: %d" (snd objectstorage) | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment