-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy path14-parabolic-reflector-dish.jl
More file actions
127 lines (108 loc) · 2.77 KB
/
Copy path14-parabolic-reflector-dish.jl
File metadata and controls
127 lines (108 loc) · 2.77 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
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
# input_filename = "example.txt"
input_filename = "input.txt"
map = (x) -> x == '.' ? 0 : x == 'O' ? 1 : 2
pam = (x) -> x == 0 ? '.' : x == 1 ? 'O' : '#'
dir = Dict(
'N' => (-1, 0),
'S' => (1, 0),
'W' => (0, -1),
'E' => (0, 1)
)
function back_to_string(plat)
(m, n) = size(plat)
s = ""
for i in 1:m
for j in 1:n
s *= pam(plat[i, j])
end
s *= "\n"
end
return s
end
function parse_input(filename::String)
f = open(filename)
lines = readlines(f)
close(f)
mat = zeros(Int, length(lines), length(lines[begin]))
for (i, s) in enumerate(lines)
mat[i, :] = map.(collect(s))
end
return mat
end
function tilt_platform_aux(plat, dir, rocks)
if length(rocks) == 0
return
else
(m, n) = size(plat)
updated_rocks = []
for rock in rocks
i_ = rock[1] + dir[1]
j_ = rock[2] + dir[2]
idx_ = CartesianIndex(i_, j_)
# println(rock, " -> ", idx_)
if (i_ > 0) && (i_ <= m) && (j_ > 0) && (j_ <= n)
if plat[idx_] == 0
plat[idx_] = 1
plat[rock] = 0
push!(updated_rocks, idx_)
end
end
end
tilt_platform_aux(plat, dir, updated_rocks)
end
end
function tilt_platform(plat, cp)
rocks = findall( ==(1), plat)
if cp in ['S', 'E']
rocks = reverse(rocks)
end
tilt_platform_aux(plat, dir[cp], rocks)
end
function count_weight(plat)
sum = 0
N = size(plat, 1)
for i in 1:N
nb_rocks = count( ==(1), plat[i, :])
sum += nb_rocks * (N - i + 1)
end
return sum
end
function part_II(plat, n_cyle=1000000000)
mem = []
plat_init = copy(plat)
push!(mem, plat_init)
idx_loop = 0
for i in 1:n_cyle
tilt_platform(plat, 'N')
tilt_platform(plat, 'W')
tilt_platform(plat, 'S')
tilt_platform(plat, 'E')
if plat in mem
idx_loop = findfirst( ==(plat), mem)
break
end
push!(mem, copy(plat))
end
loop_mem = mem[idx_loop:end]
loop_size = length(loop_mem)
# println("Mem ", length(mem))
# println("Loop size = ", loop_size)
# println("Index loop = ", idx_loop)
# println("IDX = ", mod1(n_cyle - idx_loop + 2, loop_size))
plat .= loop_mem[mod1(n_cyle - idx_loop + 2, loop_size)]
end
plat = parse_input(input_filename)
# str = back_to_string(plat)
# println(str)
plat_I = copy(plat)
tilt_platform(plat_I, 'N')
# str = back_to_string(plat_I)
# println('\n', str)
I = count_weight(plat_I)
println("I = ", I)
plat_II = copy(plat)
part_II(plat_II, 1000000000)
# str = back_to_string(plat_II)
# println('\n', str)
II = count_weight(plat_II)
println("II = ", II)