Last active
December 22, 2017 06:55
-
-
Save milang/724b197d9d2e46e5077c83f3fd7eff87 to your computer and use it in GitHub Desktop.
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
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |
// Input data | |
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |
let rotateLeft (value: string) = | |
match value.Length with | |
| 5 -> String.Join("", [| value.[1]; value.[4]; '/'; value.[0]; value.[3] |]) | |
| 11 -> String.Join("", [| value.[2]; value.[6]; value.[10]; '/'; value.[1]; value.[5]; value.[9]; '/'; value.[0]; value.[4]; value.[8] |]) | |
| _ -> raise (InvalidOperationException "Unrecognized value") | |
let mirrorY (value: string) = | |
match value.Length with | |
| 5 -> String.Join("", [| value.[1]; value.[0]; '/'; value.[4]; value.[3] |]) | |
| 11 -> String.Join("", [| value.[2]; value.[1]; value.[0]; '/'; value.[6]; value.[5]; value.[4]; '/'; value.[10]; value.[9]; value.[8] |]) | |
| _ -> raise (InvalidOperationException "Unrecognized value") | |
let mirrorX (value: string) = | |
match value.Length with | |
| 5 -> String.Join("", [| value.[3]; value.[4]; '/'; value.[0]; value.[1] |]) | |
| 11 -> String.Join("", [| value.[8]; value.[9]; value.[10]; '/'; value.[4]; value.[5]; value.[6]; '/'; value.[0]; value.[1]; value.[2] |]) | |
| _ -> raise (InvalidOperationException "Unrecognized value") | |
let allVariations (value: string) = | |
{1..3} | |
|> Seq.scan (fun current _ -> rotateLeft current) value | |
|> Seq.map (fun rotatedValue -> rotatedValue :: mirrorX rotatedValue :: mirrorY rotatedValue :: []) | |
|> List.concat | |
let parse filename = | |
File.ReadAllLines filename | |
|> Seq.map | |
(fun line -> | |
let parts = line.Split([| " => " |], StringSplitOptions.None) | |
let targets = parts.[1].Split('/') | |
let sources = allVariations parts.[0] | |
sources |> Seq.ofList |> Seq.map (fun source -> (source, targets))) | |
|> Seq.concat | |
|> Map.ofSeq | |
let data = parse "queries/Advent/Advent2017-day21.txt" | |
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |
// Problem A | |
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |
let split (bitmap: string array) = | |
let subdivideBy = if bitmap.Length % 2 = 0 then 2 else 3 | |
let subdivisions = bitmap.Length / subdivideBy | |
let newBitmap = | |
{ 0 .. subdivisions - 1 } | |
|> Seq.map | |
(fun row -> | |
{ 0 .. subdivisions - 1 } | |
|> Seq.map | |
(fun column -> | |
let r = | |
{ 0 .. (subdivideBy-1) } | |
|> Seq.map | |
(fun offset -> | |
bitmap.[(row * subdivideBy) + offset].Substring(column * subdivideBy, subdivideBy)) | |
String.Join("/", r))) | |
|> Seq.concat | |
(subdivideBy, subdivisions, newBitmap) | |
let join subdivideBy subdivisions (bitmap: (string array) seq) = | |
bitmap | |
|> Seq.mapi (fun i row -> ((i / subdivisions), row)) | |
|> Seq.groupBy fst | |
|> Seq.map | |
(fun (_, row) -> | |
{ 0 .. subdivideBy } | |
|> Seq.map | |
(fun offset -> | |
let p = row |> Seq.map (fun (_, r) -> r.[offset]) | |
String.Join("", p))) | |
|> Seq.concat | |
|> Array.ofSeq | |
let enhance iterations data = | |
let rec enhance' iterations (bitmap: string array) = | |
if iterations = 0 then bitmap | |
else | |
let (subdivideBy, subdivisions, splitBitmap) = split bitmap | |
let mappedBitmap = splitBitmap |> Seq.map (fun bitmapCell -> data |> Map.find bitmapCell) | |
enhance' (iterations - 1) (join subdivideBy subdivisions mappedBitmap) // tail recursive | |
enhance' iterations [| ".#."; "..#"; "###" |] | |
let countBits (bitmap: string array) = | |
bitmap | |
|> Seq.ofArray | |
|> Seq.map (fun bitmapCell -> bitmapCell |> Seq.map (fun bit -> if bit = '#' then 1 else 0) |> Seq.sum) | |
|> Seq.sum | |
let result = enhance 5 data | |
(countBits result, result).Dump("Final pixel count and bitmap") | |
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |
// Problem B | |
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |
let result2 = enhance 18 data | |
(countBits result2).Dump("Final pixel count after 18 iterations") |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment