-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathrun.hs
91 lines (71 loc) · 2.07 KB
/
run.hs
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
80
81
82
83
84
85
86
87
88
89
90
91
part1Input :: Int
part1Input = 289326
part1 :: Int -> Int
part1 input
| input == 1 = 0
| otherwise =
let l = layer input
ls = layerSideSize l
pos = input - (1 + layerExit (l - 1))
in
(l - 1) + (abs $ offset pos l)
layerSideSize :: Int -> Int
layerSideSize l = (l * 2) - 1
layerSize :: Int -> Int
layerSize l
| l == 1 = 1
| otherwise = (l - 1) * 8
layers :: [Int]
layers = map layerSize [1..]
layerExit :: Int -> Int
layerExit l = ((l * 2) - 1) ^ 2
sizeBelow = scanl (+) 0 layers
layer :: Int -> Int
layer i
| i == 1 = 1
| otherwise = head $ filter (\l -> i <= layerExit l) [1..]
shift :: Int -> Int
shift l
| l == 1 = 0
| otherwise = l - 2
offset :: Int -> Int -> Int
offset i l =
let i' = i `mod` (layerSideSize l - 1)
in
i' - (shift l)
--- PART 2
locations :: [(Int, Int)]
locations = map fst3 $ iterate f ((0, 0), 1, 1)
where fst3 (x0, _, _) = x0
f ((x, y), l, i)
| i >= (layerSideSize l - 1) * 4 = ((x + 1, y), l + 1, 1)
| i >= (layerSideSize l - 1) * 3 = ((x + 1, y), l, i + 1)
| i >= (layerSideSize l - 1) * 2 = ((x, y - 1), l, i + 1)
| i >= (layerSideSize l - 1) * 1 = ((x - 1, y), l, i + 1)
| otherwise = ((x, y + 1), l, i + 1)
location :: Int -> (Int, Int)
location 1 = (0, 0)
location i = locations !! (i - 1)
indices :: [((Int, Int), Int)]
indices = zip locations [1..]
index :: (Int, Int) -> Int
index pos = snd . head . filter (\(p, _) -> p == pos) $ indices
memory :: [Int]
memory = map valueIn locations
where valueIn (0, 0) = 1
valueIn (1, 0) = 1
valueIn pos = sum $ map valueIn $ adjacent pos
adjacent (posx, posy) =
let potential =
[(posx + x, posy + y) | x <- [-1..1], y <- [-1..1]]
i = index (posx, posy)
in
filter (\pos -> index pos < i) potential
part2Input :: Int
part2Input = part1Input
part2 :: Int -> Int
part2 input = head . dropWhile (< input) $ memory
main :: IO ()
main = do
print (part1 part1Input)
print (part2 part2Input)