main.jl 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  1. using BenchmarkTools
  2. using DataStructures
  3. selfdir = joinpath(splitdir(@__FILE__)[1], "input")
  4. data = readlines(selfdir)
  5. test_data = split(
  6. """
  7. L.LL.LL.LL
  8. LLLLLLL.LL
  9. L.L.L..L..
  10. LLLL.LL.LL
  11. L.LL.LL.LL
  12. L.LLLLL.LL
  13. ..L.L.....
  14. LLLLLLLLLL
  15. L.LLLLLL.L
  16. L.LLLLL.LL
  17. """)
  18. #--------part1
  19. function conv2d(input, filter, padding="valid")
  20. input_r, input_c = size(input)
  21. filter_r, filter_c = size(filter)
  22. if padding == "same"
  23. pad_r = (filter_r - 1) ÷ 2 # Integer division.
  24. pad_c = (filter_c - 1) ÷ 2 # Needed because of Type-stability feature of Julia
  25. input_padded = zeros(input_r+(2*pad_r), input_c+(2*pad_c))
  26. for i in 1:input_r, j in 1:input_c
  27. input_padded[i+pad_r, j+pad_c] = input[i, j]
  28. end
  29. input = input_padded
  30. input_r, input_c = size(input)
  31. elseif padding == "valid"
  32. # We don't need to do anything here
  33. else
  34. throw(DomainError(padding, "Invalid padding value"))
  35. end
  36. result = zeros(input_r-filter_r+1, input_c-filter_c+1)
  37. result_r, result_c = size(result)
  38. for i in 1:result_r
  39. for j in 1:result_c
  40. for k in 1:filter_r
  41. for l in 1:filter_c
  42. result[i,j] += input[i+k-1,j+l-1]*filter[k,l]
  43. end
  44. end
  45. end
  46. end
  47. return result
  48. end
  49. function step(orig_seats)
  50. seats = deepcopy(orig_seats)
  51. conv_arr = replace(seats, 'L'=>0, '#'=>1, '.'=>0) |>
  52. x-> conv2d(x, [[1,1,1] [1,0,1] [1,1,1]], "same")
  53. for i in 1:size(seats)[1], j in 1:size(seats)[2]
  54. if (conv_arr[i,j] > 3) & (seats[i,j] == '#')
  55. seats[i,j] = 'L'
  56. elseif (conv_arr[i,j] == 0) & (seats[i,j] == 'L')
  57. seats[i,j]='#'
  58. end
  59. end
  60. seats
  61. end
  62. #--------part2
  63. function step2(orig_state)
  64. b = deepcopy(orig_state)
  65. bd = deepcopy(orig_state)
  66. for i in 1:size(bd, 1), j in 1:size(bd, 2)
  67. cntr = count_dir(bd, i, j)
  68. # cntr = count_seats_part2(b,i,j,'#')
  69. if bd[i,j] == '#' && cntr >= 5
  70. b[i,j] = 'L'
  71. elseif bd[i,j] == 'L' && cntr == 0
  72. b[i,j] = '#'
  73. end
  74. end
  75. b
  76. end
  77. function count_dir(seats, i, j)
  78. cntr = 0
  79. for Δx in (-1, 0, 1), Δy in (-1, 0, 1)
  80. (Δx == 0 && Δy == 0) && continue
  81. x, y = i, j
  82. while true
  83. x += Δx
  84. y += Δy
  85. !(x >= 1 && x <= size(seats, 1)) && break
  86. !(y >= 1 && y <= size(seats, 2)) && break
  87. if seats[x, y] == '#'
  88. cntr += 1
  89. break
  90. elseif seats[x, y] == '.'
  91. continue
  92. else
  93. break
  94. end
  95. end
  96. end
  97. return cntr
  98. end
  99. #--------evaluation
  100. function modeling(data, step)
  101. data = replace(data, 'L'=>'#')
  102. state = reduce(vcat, permutedims.(collect.(data)))
  103. num_steps = 0
  104. new_state = step(state)
  105. while state != new_state
  106. state = new_state
  107. new_state = step(new_state)
  108. num_steps += 1
  109. end
  110. counter(new_state), num_steps
  111. end
  112. part1 = @btime modeling(data, step)
  113. part2 = @btime modeling(data, step2)