| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136 |
- using BenchmarkTools
- using DataStructures
- selfdir = joinpath(splitdir(@__FILE__)[1], "input")
- data = readlines(selfdir)
- test_data = split(
- """
- L.LL.LL.LL
- LLLLLLL.LL
- L.L.L..L..
- LLLL.LL.LL
- L.LL.LL.LL
- L.LLLLL.LL
- ..L.L.....
- LLLLLLLLLL
- L.LLLLLL.L
- L.LLLLL.LL
- """)
- #--------part1
- function conv2d(input, filter, padding="valid")
- input_r, input_c = size(input)
- filter_r, filter_c = size(filter)
- if padding == "same"
- pad_r = (filter_r - 1) ÷ 2 # Integer division.
- pad_c = (filter_c - 1) ÷ 2 # Needed because of Type-stability feature of Julia
- input_padded = zeros(input_r+(2*pad_r), input_c+(2*pad_c))
- for i in 1:input_r, j in 1:input_c
- input_padded[i+pad_r, j+pad_c] = input[i, j]
- end
- input = input_padded
- input_r, input_c = size(input)
- elseif padding == "valid"
- # We don't need to do anything here
- else
- throw(DomainError(padding, "Invalid padding value"))
- end
- result = zeros(input_r-filter_r+1, input_c-filter_c+1)
- result_r, result_c = size(result)
- for i in 1:result_r
- for j in 1:result_c
- for k in 1:filter_r
- for l in 1:filter_c
- result[i,j] += input[i+k-1,j+l-1]*filter[k,l]
- end
- end
- end
- end
- return result
- end
- function step(orig_seats)
- seats = deepcopy(orig_seats)
- conv_arr = replace(seats, 'L'=>0, '#'=>1, '.'=>0) |>
- x-> conv2d(x, [[1,1,1] [1,0,1] [1,1,1]], "same")
- for i in 1:size(seats)[1], j in 1:size(seats)[2]
- if (conv_arr[i,j] > 3) & (seats[i,j] == '#')
- seats[i,j] = 'L'
- elseif (conv_arr[i,j] == 0) & (seats[i,j] == 'L')
- seats[i,j]='#'
- end
- end
- seats
- end
- #--------part2
- function step2(orig_state)
- b = deepcopy(orig_state)
- bd = deepcopy(orig_state)
- for i in 1:size(bd, 1), j in 1:size(bd, 2)
- cntr = count_dir(bd, i, j)
- # cntr = count_seats_part2(b,i,j,'#')
- if bd[i,j] == '#' && cntr >= 5
- b[i,j] = 'L'
- elseif bd[i,j] == 'L' && cntr == 0
- b[i,j] = '#'
- end
- end
- b
- end
- function count_dir(seats, i, j)
- cntr = 0
- for Δx in (-1, 0, 1), Δy in (-1, 0, 1)
- (Δx == 0 && Δy == 0) && continue
- x, y = i, j
- while true
- x += Δx
- y += Δy
- !(x >= 1 && x <= size(seats, 1)) && break
- !(y >= 1 && y <= size(seats, 2)) && break
- if seats[x, y] == '#'
- cntr += 1
- break
- elseif seats[x, y] == '.'
- continue
- else
- break
- end
- end
- end
- return cntr
- end
- #--------evaluation
- function modeling(data, step)
- data = replace(data, 'L'=>'#')
- state = reduce(vcat, permutedims.(collect.(data)))
- num_steps = 0
- new_state = step(state)
- while state != new_state
- state = new_state
- new_state = step(new_state)
- num_steps += 1
- end
- counter(new_state), num_steps
- end
- part1 = @btime modeling(data, step)
- part2 = @btime modeling(data, step2)
|