-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathProgram.fs
49 lines (37 loc) · 1.41 KB
/
Program.fs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
open System.IO
/// <summary>
/// Finds the checksum of the given box IDs by calculating
/// the number of IDs that have 2 of the same letter
/// times the number of IDs that have 3 of the same letter.
/// </summary>
let partOne ids =
let countIf pred = List.filter pred >> List.length
let has n (x: string) =
x.ToCharArray()
|> Array.countBy id
|> Array.exists (fun (_, c) -> c = n)
(ids |> countIf (has 2)) * (ids |> countIf (has 3))
/// <summary>
/// Finds the two box IDs that vary by only one character at the same position.
/// </summary>
/// <returns>The characters both box IDs have in common</returns>
let partTwo ids =
let removeCharAt i (s: string) = s.Remove(i) + s.Substring(i + 1)
let findDuplicate = List.countBy id >> List.tryFind (fun (_, c) -> c = 2)
let rec checkPosition i =
let duplicate =
ids
|> List.map (removeCharAt i)
|> findDuplicate
match duplicate with
| Some(x, _) -> Some(x)
| None when ids.IsEmpty -> None
| None when ids.Head.Length = i -> None
| None -> checkPosition (i + 1)
checkPosition 0
[<EntryPoint>]
let main argv =
let input = File.ReadLines("Input.txt") |> Seq.toList
printfn "Part one: %d" <| partOne input
printfn "Part two: %A" <| partTwo input
0 // return an integer exit code