@@ -10,7 +10,15 @@ task01 content =
1010 in show $ splitBeams grid [start]
1111
1212task02 :: String -> String
13- task02 content = " Apply task02 solution to content: " ++ take 100 content
13+ task02 content =
14+ let grid = toGrid content
15+ in case grid of
16+ [] -> error " Empty grid."
17+ (first_row: remaining_grid) ->
18+ let start = findStart first_row
19+ l = length first_row
20+ counts = replicate start 0 ++ [1 ] ++ replicate (l - start - 1 ) 0
21+ in show $ beamCount remaining_grid counts
1422
1523toGrid :: String -> [[Char ]]
1624toGrid = lines
@@ -27,6 +35,7 @@ splitBeams (row:rest) beams =
2735 new_beams = nub duplicated_beams
2836 in counter + splitBeams rest new_beams
2937
38+ -- TODO: deduplicae entries directly
3039split :: [Char ] -> [Int ] -> ([Int ], Int )
3140split _ [] = ([] , 0 )
3241split row (beam: remaining_beams) =
@@ -36,3 +45,26 @@ split row (beam:remaining_beams) =
3645 | otherwise = ([beam], 0 )
3746 (other_beams, other_counter) = split row remaining_beams
3847 in (added_beams ++ other_beams, counter + other_counter)
48+
49+ beamCount :: [[Char ]] -> [Int ] -> Int
50+ beamCount [] counts = sum counts
51+ beamCount (row: grid) counts =
52+ let
53+ prev = (' .' , 0 )
54+ rows_counts = zip (row ++ " ." ) (counts ++ [0 ])
55+ in
56+ case rows_counts of
57+ [] -> error " This should not be reached."
58+ curr: rest ->
59+ let
60+ new_counts = iterRow prev curr rest
61+ in beamCount grid new_counts
62+
63+ iterRow :: (Char , Int ) -> (Char , Int ) -> [(Char , Int )] -> [Int ]
64+ iterRow _ _ [] = []
65+ 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
66+ where
67+ new_count =
68+ if curr_char == ' ^'
69+ then 0
70+ else curr_count + (if prev_char == ' ^' then prev_count else 0 ) + (if next_char == ' ^' then next_count else 0 )
0 commit comments