-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathday11_part01.fs
79 lines (68 loc) · 3.3 KB
/
day11_part01.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
74
75
76
77
78
79
module day11_part01
open System.Collections.Generic
open CustomDataTypes
open AdventOfCode_2020.Modules
let path = "day11/day11_input.txt"
let inputLines = LocalHelper.GetLinesFromFile(path)
let maxX = inputLines.[0].Length
let maxY = inputLines.Length
let placesDict = new Dictionary<int*int, SeatInfo>()
let plane =
seq {
for jdx in [0..maxY - 1] do
for idx in [0..maxX - 1] do
let seat =
match inputLines.[jdx].[idx] with
| '.' -> SeatStatus.FLOOR
| 'L' -> SeatStatus.EMPTY
| '#' -> SeatStatus.OCCUPIED
| _ -> failwith("wrong site type")
let seatToAdd = { Seat = seat; Location = (jdx, idx); Content = inputLines.[jdx].[idx] }
if seatToAdd.Seat <> SeatStatus.FLOOR then
placesDict.Add((jdx, idx), seatToAdd)
yield seatToAdd
} |> List.ofSeq
let printPlane (dictPlane: Dictionary<(int*int), SeatInfo>)=
for idx in [0 .. maxX - 1] do
for jdx in [0 .. maxY - 1] do
if dictPlane.ContainsKey(idx, jdx) then
printf "%c" dictPlane.[(idx, jdx)].Content
else
printf "."
printfn ""
let getNewPlaces (places: Dictionary<(int*int), SeatInfo>) =
let newplacesDict = new Dictionary<int*int, SeatInfo>()
for place in places do
let seatsToCheck =
seq {
for idx in [(fst place.Value.Location) - 1 .. (fst place.Value.Location) + 1] do
for jdx in [(snd place.Value.Location) - 1 .. (snd place.Value.Location) + 1] do
if places.ContainsKey(idx, jdx) && (fst place.Value.Location <> idx || snd place.Value.Location <> jdx) then
yield places.[(idx, jdx)]
} |> List.ofSeq
let adjOccupied = seatsToCheck |> List.filter(fun s -> s.Seat = SeatStatus.OCCUPIED) |> List.length
let newSeat =
match place.Value.Seat with
| SeatStatus.EMPTY ->
if adjOccupied = 0 then
{ Seat= SeatStatus.OCCUPIED; Location= (place.Value.Location); Content= '#'}
else
{ Seat= place.Value.Seat; Location= (place.Value.Location); Content= place.Value.Content }
| SeatStatus.OCCUPIED ->
if adjOccupied > 3 then
{ Seat= SeatStatus.EMPTY; Location= (place.Value.Location); Content= 'L'}
else
{ Seat= place.Value.Seat; Location= (place.Value.Location); Content= place.Value.Content }
| _ -> place.Value
newplacesDict.Add((fst place.Value.Location, snd place.Value.Location), newSeat)
newplacesDict
let rec round (oldplaces: Dictionary<(int*int), SeatInfo>) (rounds: int) =
let newplacesDict = getNewPlaces oldplaces
//printfn "Round %i" rounds
//printPlane newplacesDict
let planesAreIdentical = oldplaces.Values |> List.ofSeq |> List.forall(fun op -> newplacesDict.[(fst op.Location, snd op.Location)].Seat = op.Seat)
match planesAreIdentical with
| true -> newplacesDict |> List.ofSeq |> List.filter(fun s -> s.Value.Seat = SeatStatus.OCCUPIED) |> List.length
| false -> round newplacesDict (rounds + 1)
let execute =
round placesDict 0