Skip to content

Instantly share code, notes, and snippets.

@keithn
Created December 5, 2016 01:21
Show Gist options
  • Save keithn/c4d47262f7cf84d04b71505b5b3770a3 to your computer and use it in GitHub Desktop.
Save keithn/c4d47262f7cf84d04b71505b5b3770a3 to your computer and use it in GitHub Desktop.
Advent Of Code 2016 - Day 4
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