@@ -5,16 +5,14 @@ import Data.Maybe
5
5
6
6
solve :: [[Int ]] -> Int -> Int
7
7
solve inp = \ case
8
- 1 -> res issafe
9
- 2 -> res issafe'
10
- where
11
- res safe = pTraceShowCompact (map safe inp)
12
- (filter safe inp |> length )
8
+ 1 -> countIf issafe inp
9
+ 2 -> countIf issafe' inp
13
10
14
- diffok' r = zipWith diffok r (tail r)
15
- diffok x y = abs (x - y) <= 3
11
+ diffokAll r = zipWith diffok r (tail r)
12
+ where
13
+ diffok x y = abs (x - y) <= 3
16
14
17
- issafe r = and (diffok' r)
15
+ issafe r = and (diffokAll r)
18
16
&& ismono r
19
17
20
18
ismono r =
@@ -25,26 +23,24 @@ ismono r =
25
23
26
24
-- Part 2
27
25
28
- mono2 inc r = zipWith (monopred inc) r (tail r)
29
- |> flip zip [1 .. ]
26
+ -- Nothing if increasing, otherwise the index of the first element that breaks it minus one
27
+ mono2 r = zipWith (<) r (tail r)
28
+ |> flip zip [0 .. ]
30
29
|> lookup False
31
- where
32
- monopred inc x y = inc * (x - y) > 0
33
-
34
- issafe' r = trace (" Is r=" ++ show r ++ " almost safe?" )
35
- almostsafe 1 r || almostsafe - 1 r
36
-
37
- almostsafe inc r =
38
- case mono2 inc r of
39
- Nothing -> trace " - It's already mono. Is diffok?"
40
- (pTraceShowIdCompact $ and $ diffok' r)
41
- Just n -> trace (" - Not mono "
42
- ++ (if inc == 1 then " one" else " another" )
43
- ++ " way, try to drop "
44
- ++ show n ++ " and check safety: " )
45
- pTraceShowIdCompact (issafe (drop n r))
46
-
47
- -- t = pTraceShowCompact
30
+
31
+ issafe' r =
32
+ almostsafe r || almostsafe (reverse r)
33
+
34
+ almostsafe r =
35
+ case mono2 r of
36
+ Nothing ->
37
+ let dok = diffokAll r in
38
+ and (tail dok) || and (init dok)
39
+ Just n ->
40
+ issafe (remove n r) || issafe (remove (n+ 1 ) r)
41
+
42
+ -- brute force -- works like a charm!
43
+ issafe'' r = issafe r || or [ issafe (remove n r) | n <- [0 .. (length r - 1 )]]
48
44
49
45
main :: IO ()
50
46
main = defaultMain solve
0 commit comments