aoc_1209.slt 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177
  1. # Copyright Materialize, Inc. and contributors. All rights reserved.
  2. #
  3. # Use of this software is governed by the Business Source License
  4. # included in the LICENSE file at the root of this repository.
  5. #
  6. # As of the Change Date specified in that file, in accordance with
  7. # the Business Source License, use of this software will be governed
  8. # by the Apache License, Version 2.0.
  9. # https://github.com/MaterializeInc/advent-of-code-2023/blob/main/week1/aoc_1209.md
  10. mode cockroach
  11. statement ok
  12. CREATE TABLE input (input TEXT);
  13. # no data
  14. query T multiline
  15. EXPLAIN OPTIMIZED PLAN WITH(humanized expressions, arity, join implementations) AS VERBOSE TEXT FOR
  16. WITH MUTUALLY RECURSIVE (RETURN AT RECURSION LIMIT 30)
  17. lines (line TEXT, line_no INT) AS (
  18. SELECT regexp_split_to_array(input, '\n')[i], i
  19. FROM input, generate_series(1, array_length(regexp_split_to_array(input, '\n'), 1)) i
  20. ),
  21. numbers(value INT, line_no INT, col_no INT) AS (
  22. SELECT regexp_split_to_array(line, ' ')[j]::INT, line_no, j
  23. FROM lines, generate_series(1, array_length(regexp_split_to_array(line, ' '), 1)) j
  24. ),
  25. -- Contains non-zero values of differences after each round.
  26. derivatives(value INT, line_no INT, col_no INT, round INT) AS (
  27. SELECT numbers.*, 1
  28. FROM numbers
  29. UNION
  30. SELECT
  31. COALESCE(i2.value, 0) - COALESCE(i1.value, 0),
  32. COALESCE(i1.line_no, i2.line_no),
  33. COALESCE(i1.col_no + 1, i2.col_no),
  34. COALESCE(i1.round, i2.round) + 1
  35. FROM derivatives i1 FULL OUTER JOIN derivatives i2 ON (i1.line_no = i2.line_no AND i1.round = i2.round AND i1.col_no + 1 = i2.col_no)
  36. WHERE COALESCE(i2.value, 0) - COALESCE(i1.value, 0) != 0
  37. AND COALESCE(i1.col_no + 1, i2.col_no) > COALESCE(i1.round, i2.round)
  38. AND COALESCE(i1.col_no + 1, i2.col_no) <= 21
  39. ),
  40. -- Accumulate the derivatives at the leading edge
  41. part1(part1 BIGINT) AS (
  42. SELECT SUM(value)
  43. FROM derivatives
  44. WHERE col_no = 21
  45. ),
  46. -- Accumulate the derivatives at the preceding edge
  47. part2(part2 BIGINT) AS (
  48. SELECT SUM(pow(-1, round + 1) * value)
  49. FROM derivatives
  50. WHERE col_no = round
  51. )
  52. -- SELECT * FROM derivatives WHERE line_no = 1 ORDER BY round, col_no;
  53. SELECT * FROM part1, part2;
  54. ----
  55. Explained Query:
  56. With Mutually Recursive
  57. cte l0 =
  58. Map ((#2{col_no} + 1)) // { arity: 5 }
  59. Get l3 // { arity: 4 }
  60. cte l1 =
  61. Project (#0..=#4, #6) // { arity: 6 }
  62. Join on=(#1{line_no} = #5{line_no} AND #3{round} = #7{round} AND #6{col_no} = (#2{col_no} + 1)) type=differential // { arity: 8 }
  63. implementation
  64. %0:l0[#1{line_no}, (#2{col_no} + 1), #3{round}]KKKif » %1:l3[#1{line_no}..=#3{round}]KKKiif
  65. ArrangeBy keys=[[#1{line_no}, (#2{col_no} + 1), #3{round}]] // { arity: 4 }
  66. Project (#0..=#3) // { arity: 4 }
  67. Filter (#4 <= 21) AND (#1{line_no}) IS NOT NULL AND (#4 > #3{round}) // { arity: 5 }
  68. Get l0 // { arity: 5 }
  69. ArrangeBy keys=[[#1{line_no}..=#3{round}]] // { arity: 4 }
  70. Filter (#2{col_no} <= 21) AND (#1{line_no}) IS NOT NULL AND (#2{col_no} > #3{round}) // { arity: 4 }
  71. Get l3 // { arity: 4 }
  72. cte l2 =
  73. Distinct project=[#0..=#2] // { arity: 3 }
  74. Project (#1, #3, #5) // { arity: 3 }
  75. Get l1 // { arity: 6 }
  76. cte [recursion_limit=30, return_at_limit] l3 =
  77. Distinct project=[#0..=#3] // { arity: 4 }
  78. Union // { arity: 4 }
  79. Project (#3, #0, #2, #4) // { arity: 4 }
  80. Map (text_to_integer(array_index(regexp_split_to_array[" ", case_insensitive=false](#1{line}), integer_to_bigint(#2{j}))), 1) // { arity: 5 }
  81. FlatMap generate_series(1, (regexp_split_to_array[" ", case_insensitive=false](#1{line}) array_length 1), 1) // { arity: 3 }
  82. Project (#1, #2) // { arity: 2 }
  83. Map (array_index(regexp_split_to_array["\n", case_insensitive=false](#0{input}), integer_to_bigint(#1{i}))) // { arity: 3 }
  84. FlatMap generate_series(1, (regexp_split_to_array["\n", case_insensitive=false](#0{input}) array_length 1), 1) // { arity: 2 }
  85. ReadStorage materialize.public.input // { arity: 1 }
  86. Project (#8..=#11) // { arity: 4 }
  87. Map ((coalesce(#4{value}, 0) - coalesce(#0{value}, 0)), coalesce(#1{line_no}, #5{line_no}), coalesce((#2{col_no} + 1), #6{col_no}), (coalesce(#3{round}, #7{round}) + 1)) // { arity: 12 }
  88. Union // { arity: 8 }
  89. Project (#4..=#7, #0..=#3) // { arity: 8 }
  90. Map (null, null, null, null) // { arity: 8 }
  91. Union // { arity: 4 }
  92. Negate // { arity: 4 }
  93. Project (#0..=#3) // { arity: 4 }
  94. Join on=(#1{line_no} = #4 AND #2{col_no} = #6 AND #3{round} = #5) type=differential // { arity: 7 }
  95. implementation
  96. %1:l2[#0, #2, #1]UKKK » %0:l3[#1{line_no}..=#3{round}]KKKif
  97. ArrangeBy keys=[[#1{line_no}..=#3{round}]] // { arity: 4 }
  98. Filter (#2{col_no} <= 21) AND (#1{line_no}) IS NOT NULL AND (#2{col_no} > #3{round}) AND (0 != (coalesce(#0{value}, 0) - 0)) // { arity: 4 }
  99. Get l3 // { arity: 4 }
  100. ArrangeBy keys=[[#0, #2, #1]] // { arity: 3 }
  101. Get l2 // { arity: 3 }
  102. Filter (#2{col_no} <= 21) AND (#2{col_no} > #3{round}) AND (0 != (coalesce(#0{value}, 0) - 0)) // { arity: 4 }
  103. Get l3 // { arity: 4 }
  104. Map (null, null, null, null) // { arity: 8 }
  105. Union // { arity: 4 }
  106. Negate // { arity: 4 }
  107. Project (#0..=#3) // { arity: 4 }
  108. Join on=(#1{line_no} = #4 AND #3{round} = #5 AND #6 = (#2{col_no} + 1)) type=differential // { arity: 7 }
  109. implementation
  110. %1:l2[#0..=#2]UKKK » %0:l0[#1{line_no}, #3{round}, (#2{col_no} + 1)]KKKif
  111. ArrangeBy keys=[[#1{line_no}, #3{round}, (#2{col_no} + 1)]] // { arity: 4 }
  112. Project (#0..=#3) // { arity: 4 }
  113. Filter (#4 <= 21) AND (#1{line_no}) IS NOT NULL AND (#4 > #3{round}) AND (0 != (0 - coalesce(#0{value}, 0))) // { arity: 5 }
  114. Get l0 // { arity: 5 }
  115. ArrangeBy keys=[[#0..=#2]] // { arity: 3 }
  116. Get l2 // { arity: 3 }
  117. Project (#0..=#3) // { arity: 4 }
  118. Filter (#4 <= 21) AND (#4 > #3{round}) AND (0 != (0 - coalesce(#0{value}, 0))) // { arity: 5 }
  119. Get l0 // { arity: 5 }
  120. Project (#0..=#4, #1, #5, #3) // { arity: 8 }
  121. Filter (0 != (coalesce(#4{value}, 0) - coalesce(#0{value}, 0))) // { arity: 6 }
  122. Get l1 // { arity: 6 }
  123. Return // { arity: 2 }
  124. With
  125. cte l4 =
  126. Reduce aggregates=[sum(#0{value})] // { arity: 1 }
  127. Project (#0) // { arity: 1 }
  128. Filter (#2{col_no} = 21) // { arity: 4 }
  129. Get l3 // { arity: 4 }
  130. cte l5 =
  131. Reduce aggregates=[sum((power(-1, integer_to_double((#1{col_no} + 1))) * integer_to_double(#0{value})))] // { arity: 1 }
  132. Project (#0, #2) // { arity: 2 }
  133. Filter (#2{col_no} = #3{round}) // { arity: 4 }
  134. Get l3 // { arity: 4 }
  135. Return // { arity: 2 }
  136. CrossJoin type=differential // { arity: 2 }
  137. implementation
  138. %0[×]U » %1[×]U
  139. ArrangeBy keys=[[]] // { arity: 1 }
  140. Union // { arity: 1 }
  141. Get l4 // { arity: 1 }
  142. Map (null) // { arity: 1 }
  143. Union // { arity: 0 }
  144. Negate // { arity: 0 }
  145. Project () // { arity: 0 }
  146. Get l4 // { arity: 1 }
  147. Constant // { arity: 0 }
  148. - ()
  149. ArrangeBy keys=[[]] // { arity: 1 }
  150. Project (#1) // { arity: 1 }
  151. Map (f64toi64(#0{sum})) // { arity: 2 }
  152. Union // { arity: 1 }
  153. Get l5 // { arity: 1 }
  154. Map (null) // { arity: 1 }
  155. Union // { arity: 0 }
  156. Negate // { arity: 0 }
  157. Project () // { arity: 0 }
  158. Get l5 // { arity: 1 }
  159. Constant // { arity: 0 }
  160. - ()
  161. Source materialize.public.input
  162. Target cluster: quickstart
  163. EOF