This repository has been archived by the owner on Nov 7, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathpuzzle09.fs
73 lines (60 loc) · 2.21 KB
/
puzzle09.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
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
//
// https://adventofcode.com/2020/day/9
//
#if !INTERACTIVE
module Puzzle9
#else
#load "common.fs"
#endif
open System.IO
open common
let input =
Path.Combine(__SOURCE_DIRECTORY__, "puzzle09.txt")
|> readLines
|> Seq.map int64
|> Array.ofSeq
let window = 25
type NotPairSumSearchState = {window: Set<int64>; iBegin: int; iEnd: int; array: int64[]}
with static member start ar wSize =
{window = Seq.take wSize ar |> Set.ofSeq; iBegin = 0; iEnd = wSize; array = ar}
let rec findNorPairSum state =
let {window = w; iBegin = begin'; iEnd = end'; array = ar} = state
let target = ar.[end']
let diffs = w |> Seq.map ((-)target) // if there are a, b: a+b=target, then we can search for b=target-a
let foundPair = diffs
|> Seq.filter (fun diff -> Set.contains diff w)
|> Seq.tryHead
match foundPair with
| None -> state
| Some _ -> {
window =
w
|> Set.remove ar.[begin']
|> Set.add target
iBegin = begin' + 1
iEnd = end' + 1
array = ar
} |> findNorPairSum
let puzzle9_1 =
let res = NotPairSumSearchState.start input window
|> findNorPairSum
res.array.[res.iEnd]
type SumSearchState = {iBegin: int; iEnd: int; sum: int64; target: int64; array: int64[]}
with static member start target (ar: int64[]) = {iBegin = 0; iEnd = 0; sum = ar.[0]; target = target; array = ar}
let rec findSum state =
match Operators.compare state.sum state.target |> sign with
| 1 -> findSum {
state with iBegin = state.iBegin + 1
sum = state.sum - state.array.[state.iBegin]
}
| -1 -> findSum {
state with iEnd = state.iEnd + 1
sum = state.sum + state.array.[state.iEnd + 1]
}
| _ -> state
let puzzle9_2 =
let searchRes = findSum (SumSearchState.start puzzle9_1 input)
let slice = input.[searchRes.iBegin..searchRes.iEnd]
Array.max slice
+
Array.min slice