<PlatformTarget>AnyCPU</PlatformTarget>
<DocumentationFile>bin\$(Configuration)\$(AssemblyName).XML</DocumentationFile>
<Prefer32Bit>true</Prefer32Bit>
- <StartArguments>15</StartArguments>
+ <StartArguments>
+ </StartArguments>
</PropertyGroup>
<PropertyGroup>
<MinimumVisualStudioVersion Condition="'$(MinimumVisualStudioVersion)' == ''">11</MinimumVisualStudioVersion>
<Import Project="$(FSharpTargetsPath)" />
<ItemGroup>
<Compile Include="AssemblyInfo.fs" />
- <Compile Include="Day1.fs" />
- <Compile Include="Day2.fs" />
- <Compile Include="Day3.fs" />
- <Compile Include="Day4.fs" />
- <Compile Include="Day5.fs" />
- <Compile Include="Day6.fs" />
- <Compile Include="Day7.fs" />
- <Compile Include="Day8.fs" />
- <Compile Include="Day9.fs" />
+ <Compile Include="Day01.fs" />
+ <Compile Include="Day02.fs" />
+ <Compile Include="Day03.fs" />
+ <Compile Include="Day04.fs" />
+ <Compile Include="Day05.fs" />
+ <Compile Include="Day06.fs" />
+ <Compile Include="Day07.fs" />
+ <Compile Include="Day08.fs" />
+ <Compile Include="Day09.fs" />
<Compile Include="Day10.fs" />
<Compile Include="Day11.fs" />
<Compile Include="Day12.fs" />
<Compile Include="Day15.fs" />
<Compile Include="Program.fs" />
<None Include="App.config" />
- <Content Include="Data\day1.input">
+ <Content Include="Data\day01.input">
+ <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+ </Content>
+ <Content Include="Data\day02.input">
+ <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+ </Content>
+ <Content Include="Data\day03.input">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
- <Content Include="Data\day2.input">
+ <Content Include="Data\day04.input">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
- <Content Include="Data\day4.input">
+ <Content Include="Data\day05.input">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
- <Content Include="Data\day5.input">
+ <Content Include="Data\day06.input">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
- <Content Include="Data\day6.input">
+ <Content Include="Data\day07.input">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
- <Content Include="Data\day7.input">
+ <Content Include="Data\day08.input">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
- <Content Include="Data\day8.input">
+ <Content Include="Data\day09.input">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
- <Content Include="Data\day9.input">
+ <Content Include="Data\day10.input">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Data\day11.input">
--- /dev/null
+module AdventOfCode2017.Day01
+
+let readDigit d = int d - int '0'
+
+let parseInput (str : string) : int[] = str.ToCharArray () |> Array.map readDigit
+
+let solveCaptcha (shift : int) (captcha : int[]) =
+ let l = captcha.Length
+ [ for i in 0 .. l - 1 -> if captcha.[i] = captcha.[(i + shift) % l] then captcha.[i] else 0 ] |> List.sum
+
+let solveCaptcha1 = solveCaptcha 1
+let solveCaptcha2 (captcha : int[]) = solveCaptcha (captcha.Length / 2) captcha
--- /dev/null
+module AdventOfCode2017.Day02
+
+open System
+
+let parseInput (str : string) : int[][] =
+ str.Split ([| '\n' |], StringSplitOptions.RemoveEmptyEntries)
+ |> Array.map (fun line -> line.Split ([| ' '; '\t' |], StringSplitOptions.RemoveEmptyEntries) |> Array.map int)
+
+let checksum1 (a : int[][]) =
+ a |> Array.sumBy (fun ns -> Array.max ns - Array.min ns)
+
+let checksum2 (a : int[][]) =
+ a
+ |> Array.sumBy (
+ fun ns ->
+ seq {
+ for a in ns do
+ for b in ns do
+ if a <> b && a % b = 0 then yield a / b
+ } |> Seq.head
+ )
--- /dev/null
+module AdventOfCode2017.Day03
+
+let directions = [| 1, 0; 0, 1; -1, 0; 0, -1 |]
+
+let spiral =
+ Seq.unfold (
+ fun (pos, dir, n, i) ->
+ let x, y = directions.[dir]
+ let pos' = fst pos + x, snd pos + y
+ let nMax = (i + 1) * 2 - 1
+ let i', n' = if n = nMax then i + 1, 0 else i, n + 1
+ let dir' = if i <> i' || n' = nMax / 2 + 1 then (dir + 1) % 4 else dir
+ Some (pos, (pos', dir', n', i'))
+ ) ((0, 0), 0, 0, 0)
+
+let spiralManhattanDistanceSum (n : int) =
+ let x, y = spiral |> Seq.item (n - 1)
+ abs x + abs y
+
+let spiralAdjacentSumBiggerThan (n : int) =
+ let neighborsSum (dic : Map<int * int, int>) (pos : int * int) =
+ let x, y = pos
+ [ for dx in -1 .. 1 do for dy in -1 .. 1 -> x + dx, y + dy ]
+ |> List.sumBy (fun (x, y) -> match dic |> Map.tryFind (x, y) with Some v -> v | None -> 0)
+
+ spiral
+ |> Seq.skip 1
+ |> Seq.scan (
+ fun (_sum, dic) pos ->
+ let sum = neighborsSum dic pos
+ sum, dic |> Map.add pos sum
+ ) (1, Map.empty |> Map.add (0, 0) 1)
+ |> Seq.pick (fun (sum, _) -> if sum > n then Some sum else None)
\ No newline at end of file
--- /dev/null
+module AdventOfCode2017.Day04
+
+let forallDistinctPairs (f : string -> string -> bool) (pp : string) =
+ let words = pp.Split ' '
+ [
+ for a = 0 to words.Length - 1 do
+ for b in a + 1 .. words.Length - 1 -> f words.[a] words.[b]
+ ] |> List.forall not
+
+let isAnagram w1 w2 = Seq.compareWith compare (Seq.sort w1) (Seq.sort w2) = 0
+
+let passphraseValid = forallDistinctPairs (=)
+let passphraseValidAnagram = forallDistinctPairs isAnagram
+
+let nbPassphrasesValid (f : string -> bool) = Seq.map f >> Seq.sumBy (fun v -> if v then 1 else 0)
\ No newline at end of file
--- /dev/null
+module AdventOfCode2017.Day05
+
+open System
+
+let parseInput (str : string) : int[] =
+ str.Split ([| '\r'; '\t'; ' ' |], StringSplitOptions.RemoveEmptyEntries) |> Array.map int
+
+let nbSteps (next : int -> int) (instructions : int[]) =
+ let is = instructions.[*]
+ let mutable cursor, steps = 0, 0
+ while cursor >= 0 && cursor < instructions.Length do
+ let i = is.[cursor]
+ is.[cursor] <- next is.[cursor]
+ cursor <- cursor + i
+ steps <- steps + 1
+ steps
+
+let nbSteps1 = nbSteps ((+) 1)
+let nbSteps2 = nbSteps (fun i -> if i >= 3 then i - 1 else i + 1)
\ No newline at end of file
--- /dev/null
+module AdventOfCode2017.Day06
+
+open System
+
+let parseInput (str : string) : int[] =
+ str.Split ([| '\r'; '\t'; ' ' |], StringSplitOptions.RemoveEmptyEntries) |> Array.map int
+
+// Custom equality: more efficient than '='.
+let inline (|=|) (a1 : 'a[]) (a2 : 'a[]) : bool =
+ if a1.Length <> a2.Length then
+ false
+ else
+ let rec result i =
+ if i = a1.Length then
+ true
+ elif a1.[i] <> a2.[i] then
+ false
+ else
+ result (i + 1)
+ result 0
+
+let nbRedistribution (blocks : int[]) =
+ let rec next (previous : int[] list) =
+ let blocks = List.head previous |> Array.copy
+ let i, max = blocks |> Array.indexed |> Array.maxBy snd
+ blocks.[i] <- 0
+ for offset = i + 1 to i + max do
+ let i' = offset % blocks.Length
+ blocks.[i'] <- blocks.[i'] + 1
+
+ match previous |> List.tryFindIndex ((|=|) blocks) with
+ | Some i -> previous, i + 1
+ | None -> next (blocks :: previous)
+
+ let blockList, cycleLength = next [ blocks ]
+
+ List.length blockList, cycleLength
--- /dev/null
+module AdventOfCode2017.Day07
+
+open System
+open System.Linq
+open System.Collections.Generic
+
+type Tower =
+ {
+ Name : string
+ Weight : int
+ Above : List<Tower>
+ }
+
+type Input = (Tower * string list) list
+
+let parseInput (lines : string list) : Input =
+ lines
+ |> List.map (
+ fun line ->
+ let items = line.Split ([| '\r'; '\t'; ' '; ','; ')'; '(' |], StringSplitOptions.RemoveEmptyEntries)
+ { Name = items.[0]; Weight = int items.[1]; Above = List<Tower> () }, [ for i in 3 .. items.Length - 1 -> items.[i] ]
+ )
+
+let buildTower (input : Input) : Tower =
+ let towers = Dictionary<string, Tower> ()
+
+ for tower, _ in input do
+ towers.Add (tower.Name, tower)
+
+ for tower, towersAbove in input do
+ for towerAbove in towersAbove do
+ tower.Above.Add towers.[towerAbove]
+ towers.Remove towerAbove |> ignore
+
+ towers.First().Value
+
+// Returns the tower and its corrected weight.
+let rec findUnbalanced (tower : Tower) : (Tower * int) option =
+ let rec weight tower =
+ tower.Weight + (tower.Above |> Seq.sumBy weight)
+
+ match tower.Above |> List.ofSeq |> List.groupBy weight |> List.sortBy (snd >> List.length) with
+ | [ w1, [ unbalanced ]; w2, _ ] ->
+ findUnbalanced unbalanced |> Option.orElse (Some (unbalanced, unbalanced.Weight + w2 - w1))
+ | _ ->
+ None
\ No newline at end of file
--- /dev/null
+module AdventOfCode2017.Day08
+
+open System
+
+type Instruction = string * string * int * string * (int -> int -> bool) * int
+
+let parseInput (lines : string[]) : Instruction list =
+ lines
+ |> List.ofArray
+ |> List.map (
+ fun line ->
+ let line = line.Split ' '
+ line.[0], line.[1], int line.[2], line.[4], (match line.[5] with ">" -> (>) | "<" -> (<) | ">=" -> (>=) | "<=" -> (<=) | "!=" -> (<>) | "==" | _ -> (=)), int line.[6]
+ )
+
+let execute (input : Instruction list) : int * int =
+ let highest, register =
+ input
+ |> List.fold (
+ fun (highest, register) (reg, ins, value, regCond, op, valueCond) ->
+ if op (register |> Map.tryFind regCond |> Option.defaultValue 0) valueCond then
+ let regValue' = (register |> Map.tryFind reg |> Option.defaultValue 0) + match ins with "inc" -> value | "dec" -> -value | _ -> 0
+ max highest regValue', register |> Map.add reg regValue'
+ else
+ highest, register
+ ) (Int32.MinValue, Map.empty)
+ highest, (register |> Map.toList |> List.map snd |> List.max)
--- /dev/null
+module AdventOfCode2017.Day09
+
+let score (input : string) =
+ let rec next (l : int) (lSum : int) (gb : bool) (gbSize : int) =
+ function
+ | '{' :: tail when not gb -> next (l + 1) (lSum + l) gb gbSize tail
+ | '}' :: tail when not gb -> next (l - 1) lSum gb gbSize tail
+ | '<' :: tail when not gb -> next l lSum true gbSize tail
+ | '!' :: _ :: tail when gb -> next l lSum gb gbSize tail
+ | '>' :: tail when gb -> next l lSum false gbSize tail
+ | _ :: tail -> next l lSum gb (gbSize + if gb then 1 else 0) tail
+ | [] -> lSum, gbSize
+ List.ofSeq input |> next 1 0 false 0
\ No newline at end of file
+++ /dev/null
-module AdventOfCode2017.Day1
-
-let readDigit d = int d - int '0'
-
-let parseInput (str : string) : int[] = str.ToCharArray () |> Array.map readDigit
-
-let solveCaptcha (shift : int) (captcha : int[]) =
- let l = captcha.Length
- [ for i in 0 .. l - 1 -> if captcha.[i] = captcha.[(i + shift) % l] then captcha.[i] else 0 ] |> List.sum
-
-let solveCaptcha1 = solveCaptcha 1
-let solveCaptcha2 (captcha : int[]) = solveCaptcha (captcha.Length / 2) captcha
+++ /dev/null
-module AdventOfCode2017.Day2
-
-open System
-
-let parseInput (str : string) : int[][] =
- str.Split ([| '\n' |], StringSplitOptions.RemoveEmptyEntries)
- |> Array.map (fun line -> line.Split ([| ' '; '\t' |], StringSplitOptions.RemoveEmptyEntries) |> Array.map int)
-
-let checksum1 (a : int[][]) =
- a |> Array.sumBy (fun ns -> Array.max ns - Array.min ns)
-
-let checksum2 (a : int[][]) =
- a
- |> Array.sumBy (
- fun ns ->
- seq {
- for a in ns do
- for b in ns do
- if a <> b && a % b = 0 then yield a / b
- } |> Seq.head
- )
+++ /dev/null
-module AdventOfCode2017.Day3
-
-let directions = [| 1, 0; 0, 1; -1, 0; 0, -1 |]
-
-let spiral =
- Seq.unfold (
- fun (pos, dir, n, i) ->
- let x, y = directions.[dir]
- let pos' = fst pos + x, snd pos + y
- let nMax = (i + 1) * 2 - 1
- let i', n' = if n = nMax then i + 1, 0 else i, n + 1
- let dir' = if i <> i' || n' = nMax / 2 + 1 then (dir + 1) % 4 else dir
- Some (pos, (pos', dir', n', i'))
- ) ((0, 0), 0, 0, 0)
-
-let spiralManhattanDistanceSum (n : int) =
- let x, y = spiral |> Seq.item (n - 1)
- abs x + abs y
-
-let spiralAdjacentSumBiggerThan (n : int) =
- let neighborsSum (dic : Map<int * int, int>) (pos : int * int) =
- let x, y = pos
- [ for dx in -1 .. 1 do for dy in -1 .. 1 -> x + dx, y + dy ]
- |> List.sumBy (fun (x, y) -> match dic |> Map.tryFind (x, y) with Some v -> v | None -> 0)
-
- spiral
- |> Seq.skip 1
- |> Seq.scan (
- fun (_sum, dic) pos ->
- let sum = neighborsSum dic pos
- sum, dic |> Map.add pos sum
- ) (1, Map.empty |> Map.add (0, 0) 1)
- |> Seq.pick (fun (sum, _) -> if sum > n then Some sum else None)
\ No newline at end of file
+++ /dev/null
-module AdventOfCode2017.Day4
-
-let forallDistinctPairs (f : string -> string -> bool) (pp : string) =
- let words = pp.Split ' '
- [
- for a = 0 to words.Length - 1 do
- for b in a + 1 .. words.Length - 1 -> f words.[a] words.[b]
- ] |> List.forall not
-
-let isAnagram w1 w2 = Seq.compareWith compare (Seq.sort w1) (Seq.sort w2) = 0
-
-let passphraseValid = forallDistinctPairs (=)
-let passphraseValidAnagram = forallDistinctPairs isAnagram
-
-let nbPassphrasesValid (f : string -> bool) = Seq.map f >> Seq.sumBy (fun v -> if v then 1 else 0)
\ No newline at end of file
+++ /dev/null
-module AdventOfCode2017.Day5
-
-open System
-
-let parseInput (str : string) : int[] =
- str.Split ([| '\r'; '\t'; ' ' |], StringSplitOptions.RemoveEmptyEntries) |> Array.map int
-
-let nbSteps (next : int -> int) (instructions : int[]) =
- let is = instructions.[*]
- let mutable cursor, steps = 0, 0
- while cursor >= 0 && cursor < instructions.Length do
- let i = is.[cursor]
- is.[cursor] <- next is.[cursor]
- cursor <- cursor + i
- steps <- steps + 1
- steps
-
-let nbSteps1 = nbSteps ((+) 1)
-let nbSteps2 = nbSteps (fun i -> if i >= 3 then i - 1 else i + 1)
\ No newline at end of file
+++ /dev/null
-module AdventOfCode2017.Day6
-
-open System
-
-let parseInput (str : string) : int[] =
- str.Split ([| '\r'; '\t'; ' ' |], StringSplitOptions.RemoveEmptyEntries) |> Array.map int
-
-// Custom equality: more efficient than '='.
-let inline (|=|) (a1 : 'a[]) (a2 : 'a[]) : bool =
- if a1.Length <> a2.Length then
- false
- else
- let rec result i =
- if i = a1.Length then
- true
- elif a1.[i] <> a2.[i] then
- false
- else
- result (i + 1)
- result 0
-
-let nbRedistribution (blocks : int[]) =
- let rec next (previous : int[] list) =
- let blocks = List.head previous |> Array.copy
- let i, max = blocks |> Array.indexed |> Array.maxBy snd
- blocks.[i] <- 0
- for offset = i + 1 to i + max do
- let i' = offset % blocks.Length
- blocks.[i'] <- blocks.[i'] + 1
-
- match previous |> List.tryFindIndex ((|=|) blocks) with
- | Some i -> previous, i + 1
- | None -> next (blocks :: previous)
-
- let blockList, cycleLength = next [ blocks ]
-
- List.length blockList, cycleLength
+++ /dev/null
-module AdventOfCode2017.Day7
-
-open System
-open System.Linq
-open System.Collections.Generic
-
-type Tower =
- {
- Name : string
- Weight : int
- Above : List<Tower>
- }
-
-type Input = (Tower * string list) list
-
-let parseInput (lines : string list) : Input =
- lines
- |> List.map (
- fun line ->
- let items = line.Split ([| '\r'; '\t'; ' '; ','; ')'; '(' |], StringSplitOptions.RemoveEmptyEntries)
- { Name = items.[0]; Weight = int items.[1]; Above = List<Tower> () }, [ for i in 3 .. items.Length - 1 -> items.[i] ]
- )
-
-let buildTower (input : Input) : Tower =
- let towers = Dictionary<string, Tower> ()
-
- for tower, _ in input do
- towers.Add (tower.Name, tower)
-
- for tower, towersAbove in input do
- for towerAbove in towersAbove do
- tower.Above.Add towers.[towerAbove]
- towers.Remove towerAbove |> ignore
-
- towers.First().Value
-
-// Returns the tower and its corrected weight.
-let rec findUnbalanced (tower : Tower) : (Tower * int) option =
- let rec weight tower =
- tower.Weight + (tower.Above |> Seq.sumBy weight)
-
- match tower.Above |> List.ofSeq |> List.groupBy weight |> List.sortBy (snd >> List.length) with
- | [ w1, [ unbalanced ]; w2, _ ] ->
- findUnbalanced unbalanced |> Option.orElse (Some (unbalanced, unbalanced.Weight + w2 - w1))
- | _ ->
- None
\ No newline at end of file
+++ /dev/null
-module AdventOfCode2017.Day8
-
-open System
-
-type Instruction = string * string * int * string * (int -> int -> bool) * int
-
-let parseInput (lines : string[]) : Instruction list =
- lines
- |> List.ofArray
- |> List.map (
- fun line ->
- let line = line.Split ' '
- line.[0], line.[1], int line.[2], line.[4], (match line.[5] with ">" -> (>) | "<" -> (<) | ">=" -> (>=) | "<=" -> (<=) | "!=" -> (<>) | "==" | _ -> (=)), int line.[6]
- )
-
-let execute (input : Instruction list) : int * int =
- let highest, register =
- input
- |> List.fold (
- fun (highest, register) (reg, ins, value, regCond, op, valueCond) ->
- if op (register |> Map.tryFind regCond |> Option.defaultValue 0) valueCond then
- let regValue' = (register |> Map.tryFind reg |> Option.defaultValue 0) + match ins with "inc" -> value | "dec" -> -value | _ -> 0
- max highest regValue', register |> Map.add reg regValue'
- else
- highest, register
- ) (Int32.MinValue, Map.empty)
- highest, (register |> Map.toList |> List.map snd |> List.max)
+++ /dev/null
-module AdventOfCode2017.Day9
-
-let score (input : string) =
- let rec next (l : int) (lSum : int) (gb : bool) (gbSize : int) =
- function
- | '{' :: tail when not gb -> next (l + 1) (lSum + l) gb gbSize tail
- | '}' :: tail when not gb -> next (l - 1) lSum gb gbSize tail
- | '<' :: tail when not gb -> next l lSum true gbSize tail
- | '!' :: _ :: tail when gb -> next l lSum gb gbSize tail
- | '>' :: tail when gb -> next l lSum false gbSize tail
- | _ :: tail -> next l lSum gb (gbSize + if gb then 1 else 0) tail
- | [] -> lSum, gbSize
- List.ofSeq input |> next 1 0 false 0
\ No newline at end of file
open System.IO
open System
-let day1 () =
- let captcha = File.ReadAllText "Data/day1.input" |> Day1.parseInput
- sprintf "part1 = %A, part2 = %A" (Day1.solveCaptcha1 captcha) (Day1.solveCaptcha2 captcha)
+let day01 () =
+ let captcha = File.ReadAllText "Data/day01.input" |> Day01.parseInput
+ sprintf "part1 = %A, part2 = %A" (Day01.solveCaptcha1 captcha) (Day01.solveCaptcha2 captcha)
-let day2 () =
- let array = File.ReadAllText "Data/day2.input" |> Day2.parseInput
- sprintf "part1 = %A, part2 = %A" (Day2.checksum1 array) (Day2.checksum2 array)
+let day02 () =
+ let array = File.ReadAllText "Data/day02.input" |> Day02.parseInput
+ sprintf "part1 = %A, part2 = %A" (Day02.checksum1 array) (Day02.checksum2 array)
-let day3 () =
- let input = 325489
- sprintf "part1 = %A, part2 = %A" (Day3.spiralManhattanDistanceSum input) (Day3.spiralAdjacentSumBiggerThan input)
+let day03 () =
+ let input = File.ReadAllText "Data/day03.input" |> int
+ sprintf "part1 = %A, part2 = %A" (Day03.spiralManhattanDistanceSum input) (Day03.spiralAdjacentSumBiggerThan input)
-let day4 () =
- let input = File.ReadAllLines "Data/day4.input"
- sprintf "part1 = %A, part2 = %A" (Day4.nbPassphrasesValid Day4.passphraseValid input) (Day4.nbPassphrasesValid Day4.passphraseValidAnagram input)
+let day04 () =
+ let input = File.ReadAllLines "Data/day04.input"
+ sprintf "part1 = %A, part2 = %A" (Day04.nbPassphrasesValid Day04.passphraseValid input) (Day04.nbPassphrasesValid Day04.passphraseValidAnagram input)
-let day5 () =
- let input = File.ReadAllText "Data/day5.input" |> Day5.parseInput
- sprintf "part1 = %A, part2 = %A" (Day5.nbSteps1 input) (Day5.nbSteps2 input)
+let day05 () =
+ let input = File.ReadAllText "Data/day05.input" |> Day05.parseInput
+ sprintf "part1 = %A, part2 = %A" (Day05.nbSteps1 input) (Day05.nbSteps2 input)
-let day6 () =
- let input = File.ReadAllText "Data/day6.input" |> Day6.parseInput
- let part1, part2 = Day6.nbRedistribution input
+let day06 () =
+ let input = File.ReadAllText "Data/day06.input" |> Day06.parseInput
+ let part1, part2 = Day06.nbRedistribution input
sprintf "part1 = %A, part2 = %A" part1 part2
-let day7 () =
- let input = File.ReadAllLines "Data/day7.input" |> List.ofArray |> Day7.parseInput
- let tower = Day7.buildTower input
- sprintf "part1 = %A, part2 = %A" tower.Name (Day7.findUnbalanced tower |> Option.map (fun (t, w) -> t.Name, w))
+let day07 () =
+ let input = File.ReadAllLines "Data/day07.input" |> List.ofArray |> Day07.parseInput
+ let tower = Day07.buildTower input
+ sprintf "part1 = %A, part2 = %A" tower.Name (Day07.findUnbalanced tower |> Option.map (fun (t, w) -> t.Name, w))
-let day8 () =
- let input = File.ReadAllLines "Data/day8.input" |> Day8.parseInput
- let part1, part2 = Day8.execute input
+let day08 () =
+ let input = File.ReadAllLines "Data/day08.input" |> Day08.parseInput
+ let part1, part2 = Day08.execute input
sprintf "part1 = %A, part2 = %A" part1 part2
-let day9 () =
- let input = File.ReadAllText "Data/day9.input"
- let part1, part2 = Day9.score input
+let day09 () =
+ let input = File.ReadAllText "Data/day09.input"
+ let part1, part2 = Day09.score input
sprintf "part1 = %A, part2 = %A" part1 part2
let day10 () =
- let input = "83,0,193,1,254,237,187,40,88,27,2,255,149,29,42,100"
+ let input = File.ReadAllText "Data/day10.input"
sprintf "part1 = %A, part2 = %A" (Day10.knotHash1 input 256) (Day10.knotHash2 input)
let day11 () =
sw.Start ()
let result =
match n with
- | 1 -> day1 ()
- | 2 -> day2 ()
- | 3 -> day3 ()
- | 4 -> day4 ()
- | 5 -> day5 ()
- | 6 -> day6 ()
- | 7 -> day7 ()
- | 8 -> day8 ()
- | 9 -> day9 ()
+ | 1 -> day01 ()
+ | 2 -> day02 ()
+ | 3 -> day03 ()
+ | 4 -> day04 ()
+ | 5 -> day05 ()
+ | 6 -> day06 ()
+ | 7 -> day07 ()
+ | 8 -> day08 ()
+ | 9 -> day09 ()
| 10 -> day10 ()
| 11 -> day11 ()
| 12 -> day12 ()
--- /dev/null
+namespace AdventOfCode2017.Tests
+
+open Xunit
+open Xunit.Abstractions
+open Swensen.Unquote
+
+open AdventOfCode2017
+
+type ``Day01 tests`` (output : ITestOutputHelper) =
+
+ [<Fact>]
+ let ``(Part1) From web page`` () =
+ Day01.solveCaptcha1 (Day01.parseInput "1122") =! 3
+ Day01.solveCaptcha1 (Day01.parseInput "1111") =! 4
+ Day01.solveCaptcha1 (Day01.parseInput "1234") =! 0
+ Day01.solveCaptcha1 (Day01.parseInput "91212129") =! 9
+
+ [<Fact>]
+ let ``(Part2) From web page`` () =
+ Day01.solveCaptcha2 (Day01.parseInput "1212") =! 6
+ Day01.solveCaptcha2 (Day01.parseInput "1221") =! 0
+ Day01.solveCaptcha2 (Day01.parseInput "123425") =! 4
+ Day01.solveCaptcha2 (Day01.parseInput "123123") =! 12
+ Day01.solveCaptcha2 (Day01.parseInput "12131415") =! 4
--- /dev/null
+namespace AdventOfCode2017.Tests
+
+open Xunit
+open Xunit.Abstractions
+open Swensen.Unquote
+
+open AdventOfCode2017
+
+type ``Day02 tests`` (output : ITestOutputHelper) =
+
+ [<Fact>]
+ let ``(Part1) From web page`` () =
+ let input =
+ "5 1 9 5
+ 7 5 3
+ 2 4 6 8"
+ Day02.checksum1 (Day02.parseInput input) =! 18
+
+ [<Fact>]
+ let ``(Part2) From web page`` () =
+ let input =
+ "5 9 2 8
+ 9 4 7 3
+ 3 8 6 5"
+ Day02.checksum2 (Day02.parseInput input) =! 9
\ No newline at end of file
--- /dev/null
+namespace AdventOfCode2017.Tests
+
+open Xunit
+open Xunit.Abstractions
+open Swensen.Unquote
+
+open AdventOfCode2017
+
+type ``Day03 tests`` (output : ITestOutputHelper) =
+
+ [<Fact>]
+ let ``(Part1) From web page`` () =
+ Day03.spiralManhattanDistanceSum 12 =! 3
+ Day03.spiralManhattanDistanceSum 23 =! 2
+ Day03.spiralManhattanDistanceSum 1024 =! 31
+
+ [<Fact>]
+ let ``(Part2) From web page`` () =
+ Day03.spiralAdjacentSumBiggerThan 1 =! 2
+ Day03.spiralAdjacentSumBiggerThan 2 =! 4
+ Day03.spiralAdjacentSumBiggerThan 3 =! 4
+ Day03.spiralAdjacentSumBiggerThan 4 =! 5
+ Day03.spiralAdjacentSumBiggerThan 5 =! 10
+ Day03.spiralAdjacentSumBiggerThan 20 =! 23
+ Day03.spiralAdjacentSumBiggerThan 100 =! 122
+ Day03.spiralAdjacentSumBiggerThan 500 =! 747
\ No newline at end of file
--- /dev/null
+namespace AdventOfCode2017.Tests
+
+open Xunit
+open Xunit.Abstractions
+open Swensen.Unquote
+
+open AdventOfCode2017
+
+type ``Day04 tests`` (output : ITestOutputHelper) =
+
+ [<Fact>]
+ let ``(Part1) From web page`` () =
+ Assert.True (Day04.passphraseValid "aa bb cc dd ee")
+ Assert.False (Day04.passphraseValid "aa bb cc dd aa")
+ Assert.True (Day04.passphraseValid "aa bb cc dd aaa")
+
+ [<Fact>]
+ let ``(Part2) From web page`` () =
+ Assert.True (Day04.passphraseValidAnagram "abcde fghij")
+ Assert.False (Day04.passphraseValidAnagram "abcde xyz ecdab")
+ Assert.True (Day04.passphraseValidAnagram "a ab abc abd abf abj")
+ Assert.True (Day04.passphraseValidAnagram "iiii oiii ooii oooi oooo")
+ Assert.False (Day04.passphraseValidAnagram "oiii ioii iioi iiio")
\ No newline at end of file
--- /dev/null
+namespace AdventOfCode2017.Tests
+
+open Xunit
+open Xunit.Abstractions
+open Swensen.Unquote
+
+open AdventOfCode2017
+
+type ``Day05 tests`` (output : ITestOutputHelper) =
+
+ [<Fact>]
+ let ``(Part1) From web page`` () =
+ Day05.nbSteps1 [| 0; 3; 0; 1; -3 |] =! 5
+
+ [<Fact>]
+ let ``(Part2) From web page`` () =
+ Day05.nbSteps2 [| 0; 3; 0; 1; -3 |] =! 10
\ No newline at end of file
--- /dev/null
+namespace AdventOfCode2017.Tests
+
+open Xunit
+open Xunit.Abstractions
+open Swensen.Unquote
+
+open AdventOfCode2017
+
+type ``Day06 tests`` (output : ITestOutputHelper) =
+
+ [<Fact>]
+ let ``(Part1) From web page`` () =
+ let l, _ = Day06.nbRedistribution [| 0; 2; 7; 0 |]
+ l =! 5
+
+ [<Fact>]
+ let ``(Part2) From web page`` () =
+ let _, cycleLength = Day06.nbRedistribution [| 0; 2; 7; 0 |]
+ cycleLength =! 4
\ No newline at end of file
--- /dev/null
+namespace AdventOfCode2017.Tests
+
+open Xunit
+open Xunit.Abstractions
+open Swensen.Unquote
+
+open AdventOfCode2017
+
+type ``Day07 tests`` (output : ITestOutputHelper) =
+
+ [<Fact>]
+ let ``(Part1) From web page`` () =
+ let input =
+ [
+ "pbga (66)"
+ "xhth (57)"
+ "ebii (61)"
+ "havc (66)"
+ "ktlj (57)"
+ "fwft (72) -> ktlj, cntj, xhth"
+ "qoyq (66)"
+ "padx (45) -> pbga, havc, qoyq"
+ "tknk (41) -> ugml, padx, fwft"
+ "jptl (61)"
+ "ugml (68) -> gyxo, ebii, jptl"
+ "gyxo (61)"
+ "cntj (57)"
+ ]
+ let tower = Day07.buildTower (Day07.parseInput input)
+ tower.Name =! "tknk"
+
+ [<Fact>]
+ let ``(Part2) From web page`` () =
+ let input =
+ [
+ "pbga (66)"
+ "xhth (57)"
+ "ebii (61)"
+ "havc (66)"
+ "ktlj (57)"
+ "fwft (72) -> ktlj, cntj, xhth"
+ "qoyq (66)"
+ "padx (45) -> pbga, havc, qoyq"
+ "tknk (41) -> ugml, padx, fwft"
+ "jptl (61)"
+ "ugml (68) -> gyxo, ebii, jptl"
+ "gyxo (61)"
+ "cntj (57)"
+ ]
+ let tower = Day07.buildTower (Day07.parseInput input)
+
+ match Day07.findUnbalanced tower with
+ | Some (tower, weight) ->
+ tower.Name =! "ugml"
+ weight =! 60
+ | None -> failwith "no tower found"
+
+ [<Fact>]
+ let ``(Part2) A balanced tree`` () =
+ let input =
+ [
+ "pbga (66)"
+ "xhth (57)"
+ "ebii (61)"
+ "havc (66)"
+ "ktlj (57)"
+ "fwft (72) -> ktlj, cntj, xhth"
+ "qoyq (66)"
+ "padx (45) -> pbga, havc, qoyq"
+ "tknk (41) -> ugml, padx, fwft"
+ "jptl (61)"
+ "ugml (60) -> gyxo, ebii, jptl"
+ "gyxo (61)"
+ "cntj (57)"
+ ]
+ let tower = Day07.buildTower (Day07.parseInput input)
+
+ Day07.findUnbalanced tower =! None
\ No newline at end of file
--- /dev/null
+namespace AdventOfCode2017.Tests
+
+open Xunit
+open Xunit.Abstractions
+open Swensen.Unquote
+
+open AdventOfCode2017
+
+type ``Day08 tests`` (output : ITestOutputHelper) =
+
+ [<Fact>]
+ let ``(Part1) From web page`` () =
+ let input =
+ [|
+ "b inc 5 if a > 1"
+ "a inc 1 if b < 5"
+ "c dec -10 if a >= 1"
+ "c inc -20 if c == 10"
+ |]
+ let p1, _ = Day08.execute (Day08.parseInput input)
+ p1 = 1
+
+ [<Fact>]
+ let ``(Part2) From web page`` () =
+ let input =
+ [|
+ "b inc 5 if a > 1"
+ "a inc 1 if b < 5"
+ "c dec -10 if a >= 1"
+ "c inc -20 if c == 10"
+ |]
+ let _, p2 = Day08.execute (Day08.parseInput input)
+ p2 = 10
\ No newline at end of file
--- /dev/null
+namespace AdventOfCode2017.Tests
+
+open Xunit
+open Xunit.Abstractions
+open Swensen.Unquote
+
+open AdventOfCode2017
+
+type ``Day09 tests`` (output : ITestOutputHelper) =
+
+ [<Fact>]
+ let ``(Part1) From web page`` () =
+ Day09.score "{}" |> fst =! 1
+ Day09.score "{{{}}}" |> fst =! 6
+ Day09.score "{{},{}}" |> fst =! 5
+ Day09.score "{{{},{},{{}}}}" |> fst =! 16
+ Day09.score "{<a>,<a>,<a>,<a>}" |> fst =! 1
+ Day09.score "{{<ab>},{<ab>},{<ab>},{<ab>}}" |> fst =! 9
+ Day09.score "{{<!!>},{<!!>},{<!!>},{<!!>}}" |> fst =! 9
+ Day09.score "{{<a!>},{<a!>},{<a!>},{<ab>}}" |> fst =! 3
+
+ [<Fact>]
+ let ``(Part2) From web page`` () =
+ Day09.score "<>" |> snd =! 0
+ Day09.score "<random characters>" |> snd =! 17
+ Day09.score "<<<<>" |> snd =! 3
+ Day09.score "<{!>}>" |> snd =! 2
+ Day09.score "<!!>" |> snd =! 0
+ Day09.score "<!!!>>" |> snd =! 0
+ Day09.score """<{o"i!a,<{i<a>""" |> snd =! 10
\ No newline at end of file
+++ /dev/null
-namespace AdventOfCode2017.Tests
-
-open Xunit
-open Xunit.Abstractions
-open Swensen.Unquote
-
-open AdventOfCode2017
-
-type ``Day1 tests`` (output : ITestOutputHelper) =
-
- [<Fact>]
- let ``(Part1) From web page`` () =
- Day1.solveCaptcha1 (Day1.parseInput "1122") =! 3
- Day1.solveCaptcha1 (Day1.parseInput "1111") =! 4
- Day1.solveCaptcha1 (Day1.parseInput "1234") =! 0
- Day1.solveCaptcha1 (Day1.parseInput "91212129") =! 9
-
- [<Fact>]
- let ``(Part2) From web page`` () =
- Day1.solveCaptcha2 (Day1.parseInput "1212") =! 6
- Day1.solveCaptcha2 (Day1.parseInput "1221") =! 0
- Day1.solveCaptcha2 (Day1.parseInput "123425") =! 4
- Day1.solveCaptcha2 (Day1.parseInput "123123") =! 12
- Day1.solveCaptcha2 (Day1.parseInput "12131415") =! 4
+++ /dev/null
-namespace AdventOfCode2017.Tests
-
-open Xunit
-open Xunit.Abstractions
-open Swensen.Unquote
-
-open AdventOfCode2017
-
-type ``Day2 tests`` (output : ITestOutputHelper) =
-
- [<Fact>]
- let ``(Part1) From web page`` () =
- let input =
- "5 1 9 5
- 7 5 3
- 2 4 6 8"
- Day2.checksum1 (Day2.parseInput input) =! 18
-
- [<Fact>]
- let ``(Part2) From web page`` () =
- let input =
- "5 9 2 8
- 9 4 7 3
- 3 8 6 5"
- Day2.checksum2 (Day2.parseInput input) =! 9
\ No newline at end of file
+++ /dev/null
-namespace AdventOfCode2017.Tests
-
-open Xunit
-open Xunit.Abstractions
-open Swensen.Unquote
-
-open AdventOfCode2017
-
-type ``Day3 tests`` (output : ITestOutputHelper) =
-
- [<Fact>]
- let ``(Part1) From web page`` () =
- Day3.spiralManhattanDistanceSum 12 =! 3
- Day3.spiralManhattanDistanceSum 23 =! 2
- Day3.spiralManhattanDistanceSum 1024 =! 31
-
- [<Fact>]
- let ``(Part2) From web page`` () =
- Day3.spiralAdjacentSumBiggerThan 1 =! 2
- Day3.spiralAdjacentSumBiggerThan 2 =! 4
- Day3.spiralAdjacentSumBiggerThan 3 =! 4
- Day3.spiralAdjacentSumBiggerThan 4 =! 5
- Day3.spiralAdjacentSumBiggerThan 5 =! 10
- Day3.spiralAdjacentSumBiggerThan 20 =! 23
- Day3.spiralAdjacentSumBiggerThan 100 =! 122
- Day3.spiralAdjacentSumBiggerThan 500 =! 747
\ No newline at end of file
+++ /dev/null
-namespace AdventOfCode2017.Tests
-
-open Xunit
-open Xunit.Abstractions
-open Swensen.Unquote
-
-open AdventOfCode2017
-
-type ``Day4 tests`` (output : ITestOutputHelper) =
-
- [<Fact>]
- let ``(Part1) From web page`` () =
- Assert.True (Day4.passphraseValid "aa bb cc dd ee")
- Assert.False (Day4.passphraseValid "aa bb cc dd aa")
- Assert.True (Day4.passphraseValid "aa bb cc dd aaa")
-
- [<Fact>]
- let ``(Part2) From web page`` () =
- Assert.True (Day4.passphraseValidAnagram "abcde fghij")
- Assert.False (Day4.passphraseValidAnagram "abcde xyz ecdab")
- Assert.True (Day4.passphraseValidAnagram "a ab abc abd abf abj")
- Assert.True (Day4.passphraseValidAnagram "iiii oiii ooii oooi oooo")
- Assert.False (Day4.passphraseValidAnagram "oiii ioii iioi iiio")
\ No newline at end of file
+++ /dev/null
-namespace AdventOfCode2017.Tests
-
-open Xunit
-open Xunit.Abstractions
-open Swensen.Unquote
-
-open AdventOfCode2017
-
-type ``Day5 tests`` (output : ITestOutputHelper) =
-
- [<Fact>]
- let ``(Part1) From web page`` () =
- Day5.nbSteps1 [| 0; 3; 0; 1; -3 |] =! 5
-
- [<Fact>]
- let ``(Part2) From web page`` () =
- Day5.nbSteps2 [| 0; 3; 0; 1; -3 |] =! 10
\ No newline at end of file
+++ /dev/null
-namespace AdventOfCode2017.Tests
-
-open Xunit
-open Xunit.Abstractions
-open Swensen.Unquote
-
-open AdventOfCode2017
-
-type ``Day6 tests`` (output : ITestOutputHelper) =
-
- [<Fact>]
- let ``(Part1) From web page`` () =
- let l, _ = Day6.nbRedistribution [| 0; 2; 7; 0 |]
- l =! 5
-
- [<Fact>]
- let ``(Part2) From web page`` () =
- let _, cycleLength = Day6.nbRedistribution [| 0; 2; 7; 0 |]
- cycleLength =! 4
\ No newline at end of file
+++ /dev/null
-namespace AdventOfCode2017.Tests
-
-open Xunit
-open Xunit.Abstractions
-open Swensen.Unquote
-
-open AdventOfCode2017
-
-type ``Day7 tests`` (output : ITestOutputHelper) =
-
- [<Fact>]
- let ``(Part1) From web page`` () =
- let input =
- [
- "pbga (66)"
- "xhth (57)"
- "ebii (61)"
- "havc (66)"
- "ktlj (57)"
- "fwft (72) -> ktlj, cntj, xhth"
- "qoyq (66)"
- "padx (45) -> pbga, havc, qoyq"
- "tknk (41) -> ugml, padx, fwft"
- "jptl (61)"
- "ugml (68) -> gyxo, ebii, jptl"
- "gyxo (61)"
- "cntj (57)"
- ]
- let tower = Day7.buildTower (Day7.parseInput input)
- tower.Name =! "tknk"
-
- [<Fact>]
- let ``(Part2) From web page`` () =
- let input =
- [
- "pbga (66)"
- "xhth (57)"
- "ebii (61)"
- "havc (66)"
- "ktlj (57)"
- "fwft (72) -> ktlj, cntj, xhth"
- "qoyq (66)"
- "padx (45) -> pbga, havc, qoyq"
- "tknk (41) -> ugml, padx, fwft"
- "jptl (61)"
- "ugml (68) -> gyxo, ebii, jptl"
- "gyxo (61)"
- "cntj (57)"
- ]
- let tower = Day7.buildTower (Day7.parseInput input)
-
- match Day7.findUnbalanced tower with
- | Some (tower, weight) ->
- tower.Name =! "ugml"
- weight =! 60
- | None -> failwith "no tower found"
-
- [<Fact>]
- let ``(Part2) A balanced tree`` () =
- let input =
- [
- "pbga (66)"
- "xhth (57)"
- "ebii (61)"
- "havc (66)"
- "ktlj (57)"
- "fwft (72) -> ktlj, cntj, xhth"
- "qoyq (66)"
- "padx (45) -> pbga, havc, qoyq"
- "tknk (41) -> ugml, padx, fwft"
- "jptl (61)"
- "ugml (60) -> gyxo, ebii, jptl"
- "gyxo (61)"
- "cntj (57)"
- ]
- let tower = Day7.buildTower (Day7.parseInput input)
-
- Day7.findUnbalanced tower =! None
\ No newline at end of file
+++ /dev/null
-namespace AdventOfCode2017.Tests
-
-open Xunit
-open Xunit.Abstractions
-open Swensen.Unquote
-
-open AdventOfCode2017
-
-type ``Day8 tests`` (output : ITestOutputHelper) =
-
- [<Fact>]
- let ``(Part1) From web page`` () =
- let input =
- [|
- "b inc 5 if a > 1"
- "a inc 1 if b < 5"
- "c dec -10 if a >= 1"
- "c inc -20 if c == 10"
- |]
- let p1, _ = Day8.execute (Day8.parseInput input)
- p1 = 1
-
- [<Fact>]
- let ``(Part2) From web page`` () =
- let input =
- [|
- "b inc 5 if a > 1"
- "a inc 1 if b < 5"
- "c dec -10 if a >= 1"
- "c inc -20 if c == 10"
- |]
- let _, p2 = Day8.execute (Day8.parseInput input)
- p2 = 10
\ No newline at end of file
+++ /dev/null
-namespace AdventOfCode2017.Tests
-
-open Xunit
-open Xunit.Abstractions
-open Swensen.Unquote
-
-open AdventOfCode2017
-
-type ``Day9 tests`` (output : ITestOutputHelper) =
-
- [<Fact>]
- let ``(Part1) From web page`` () =
- Day9.score "{}" |> fst =! 1
- Day9.score "{{{}}}" |> fst =! 6
- Day9.score "{{},{}}" |> fst =! 5
- Day9.score "{{{},{},{{}}}}" |> fst =! 16
- Day9.score "{<a>,<a>,<a>,<a>}" |> fst =! 1
- Day9.score "{{<ab>},{<ab>},{<ab>},{<ab>}}" |> fst =! 9
- Day9.score "{{<!!>},{<!!>},{<!!>},{<!!>}}" |> fst =! 9
- Day9.score "{{<a!>},{<a!>},{<a!>},{<ab>}}" |> fst =! 3
-
- [<Fact>]
- let ``(Part2) From web page`` () =
- Day9.score "<>" |> snd =! 0
- Day9.score "<random characters>" |> snd =! 17
- Day9.score "<<<<>" |> snd =! 3
- Day9.score "<{!>}>" |> snd =! 2
- Day9.score "<!!>" |> snd =! 0
- Day9.score "<!!!>>" |> snd =! 0
- Day9.score """<{o"i!a,<{i<a>""" |> snd =! 10
\ No newline at end of file
<Import Project="$(FSharpTargetsPath)" />
<ItemGroup>
<Compile Include="AssemblyInfo.fs" />
- <Compile Include="Day1 tests.fs" />
- <Compile Include="Day2 tests.fs" />
- <Compile Include="Day3 tests.fs" />
- <Compile Include="Day4 tests.fs" />
- <Compile Include="Day5 tests.fs" />
- <Compile Include="Day6 tests.fs" />
- <Compile Include="Day7 tests.fs" />
- <Compile Include="Day8 tests.fs" />
- <Compile Include="Day9 tests.fs" />
+ <Compile Include="Day01 tests.fs" />
+ <Compile Include="Day02 tests.fs" />
+ <Compile Include="Day03 tests.fs" />
+ <Compile Include="Day04 tests.fs" />
+ <Compile Include="Day05 tests.fs" />
+ <Compile Include="Day06 tests.fs" />
+ <Compile Include="Day07 tests.fs" />
+ <Compile Include="Day08 tests.fs" />
+ <Compile Include="Day09 tests.fs" />
<Compile Include="Day10 tests.fs" />
<Compile Include="Day11 tests.fs" />
<Compile Include="Day12 tests.fs" />