-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathDay07.hs
More file actions
70 lines (61 loc) · 2.09 KB
/
Day07.hs
File metadata and controls
70 lines (61 loc) · 2.09 KB
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
module Day07 (task01, task02) where
import Data.List
import Data.Maybe
task01 :: String -> String
task01 content =
let grid = toGrid content
start = findStart (head grid)
in show $ splitBeams grid [start]
task02 :: String -> String
task02 content =
let grid = toGrid content
in case grid of
[] -> error "Empty grid."
(first_row:remaining_grid) ->
let start = findStart first_row
l = length first_row
counts = replicate start 0 ++ [1] ++ replicate (l - start - 1) 0
in show $ beamCount remaining_grid counts
toGrid :: String -> [[Char]]
toGrid = lines
findStart :: [Char] -> Int
findStart row =
let maybe_start = elemIndex 'S' row
in fromJust maybe_start
splitBeams :: [[Char]] -> [Int] -> Int
splitBeams [] _ = 0
splitBeams (row:rest) beams =
let (duplicated_beams, counter) = split row beams
new_beams = nub duplicated_beams
in counter + splitBeams rest new_beams
-- TODO: deduplicae entries directly
split :: [Char] -> [Int] -> ([Int], Int)
split _ [] = ([], 0)
split row (beam:remaining_beams) =
let c = row !! beam
(added_beams, counter)
| c == '^' = ([beam - 1, beam + 1], 1)
| otherwise = ([beam], 0)
(other_beams, other_counter) = split row remaining_beams
in (added_beams ++ other_beams, counter + other_counter)
beamCount :: [[Char]] -> [Int] -> Int
beamCount [] counts = sum counts
beamCount (row:grid) counts =
let
prev = ('.', 0)
rows_counts = zip (row ++ ".") (counts ++ [0])
in
case rows_counts of
[] -> error "This should not be reached."
curr:rest ->
let
new_counts = iterRow prev curr rest
in beamCount grid new_counts
iterRow :: (Char, Int) -> (Char, Int) -> [(Char, Int)] -> [Int]
iterRow _ _ [] = []
iterRow (prev_char, prev_count) (curr_char, curr_count) ((next_char, next_count):rows_counts) = new_count:iterRow (curr_char, curr_count) (next_char, next_count) rows_counts
where
new_count =
if curr_char == '^'
then 0
else curr_count + (if prev_char == '^' then prev_count else 0) + (if next_char == '^' then next_count else 0)