aoc_1225.slt 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293
  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_1225.md
  10. mode cockroach
  11. statement ok
  12. CREATE TABLE input (input TEXT);
  13. statement ok
  14. INSERT INTO input VALUES (
  15. 'tls: ssh
  16. ssh: ftp ssr sso
  17. ftp: rgb mkd sso
  18. ssr: dos htd
  19. sso: lll pxp
  20. rgb: zbz vmz htd
  21. htd: jln
  22. mkd: mmx');
  23. query I
  24. WITH MUTUALLY RECURSIVE (RETURN AT RECURSION LIMIT 50)
  25. lines(r INT, line TEXT) AS (
  26. SELECT r, regexp_split_to_array(input, '\n')[r] as line
  27. FROM input, generate_series(1, array_length(regexp_split_to_array(input, '\n'), 1)) r
  28. ),
  29. edges(src TEXT, dst TEXT) AS (
  30. SELECT
  31. trim(':' FROM regexp_split_to_array(line, ' ')[1]),
  32. trim(',' FROM regexp_split_to_array(line, ' ')[x])
  33. FROM
  34. lines, generate_series(2, array_length(regexp_split_to_array(line, ' '), 1)) x
  35. ),
  36. symm(src TEXT, dst TEXT) AS (
  37. SELECT src, dst FROM edges
  38. UNION ALL
  39. SELECT dst, src FROM edges
  40. ),
  41. init(src TEXT, val NUMERIC) AS (
  42. SELECT src, CASE WHEN src < 'n' THEN 1.0 ELSE -1.0 END
  43. FROM (SELECT src FROM edges UNION ALL SELECT dst FROM edges)
  44. ),
  45. -- determine the second eigenvector of the adjacency matrix
  46. weight(src TEXT, val NUMERIC) AS (
  47. SELECT * FROM init
  48. EXCEPT ALL
  49. SELECT * FROM init_delayed
  50. UNION ALL
  51. SELECT symm.src, SUM((val - (SELECT AVG(val) FROM weight))/(SELECT STDDEV(val) FROM weight))
  52. FROM symm, weight
  53. WHERE symm.dst = weight.src
  54. GROUP BY symm.src
  55. ),
  56. init_delayed(src TEXT, val NUMERIC) AS ( SELECT * FROM init ),
  57. part1(part1 BIGINT) AS (
  58. SELECT
  59. (SELECT COUNT(*) FROM weight WHERE val < 0.0) *
  60. (SELECT COUNT(*) FROM weight WHERE val > 0.0)
  61. ),
  62. potato(x INT) AS ( SELECT 1 )
  63. SELECT * FROM part1;
  64. ----
  65. 54
  66. query T multiline
  67. EXPLAIN OPTIMIZED PLAN WITH(humanized expressions, arity, join implementations) AS VERBOSE TEXT FOR
  68. WITH MUTUALLY RECURSIVE (RETURN AT RECURSION LIMIT 50)
  69. lines(r INT, line TEXT) AS (
  70. SELECT r, regexp_split_to_array(input, '\n')[r] as line
  71. FROM input, generate_series(1, array_length(regexp_split_to_array(input, '\n'), 1)) r
  72. ),
  73. edges(src TEXT, dst TEXT) AS (
  74. SELECT
  75. trim(':' FROM regexp_split_to_array(line, ' ')[1]),
  76. trim(',' FROM regexp_split_to_array(line, ' ')[x])
  77. FROM
  78. lines, generate_series(2, array_length(regexp_split_to_array(line, ' '), 1)) x
  79. ),
  80. symm(src TEXT, dst TEXT) AS (
  81. SELECT src, dst FROM edges
  82. UNION ALL
  83. SELECT dst, src FROM edges
  84. ),
  85. init(src TEXT, val NUMERIC) AS (
  86. SELECT src, CASE WHEN src < 'n' THEN 1.0 ELSE -1.0 END
  87. FROM (SELECT src FROM edges UNION ALL SELECT dst FROM edges)
  88. ),
  89. -- determine the second eigenvector of the adjacency matrix
  90. weight(src TEXT, val NUMERIC) AS (
  91. SELECT * FROM init
  92. EXCEPT ALL
  93. SELECT * FROM init_delayed
  94. UNION ALL
  95. SELECT symm.src, SUM((val - (SELECT AVG(val) FROM weight))/(SELECT STDDEV(val) FROM weight))
  96. FROM symm, weight
  97. WHERE symm.dst = weight.src
  98. GROUP BY symm.src
  99. ),
  100. init_delayed(src TEXT, val NUMERIC) AS ( SELECT * FROM init ),
  101. part1(part1 BIGINT) AS (
  102. SELECT
  103. (SELECT COUNT(*) FROM weight WHERE val < 0.0) *
  104. (SELECT COUNT(*) FROM weight WHERE val > 0.0)
  105. ),
  106. potato(x INT) AS ( SELECT 1 )
  107. SELECT * FROM part1;
  108. ----
  109. Explained Query:
  110. With
  111. cte l0 =
  112. Project (#3, #4) // { arity: 2 }
  113. Map (regexp_split_to_array[" ", case_insensitive=false](#0{line}), btrim(array_index(#2, 1), ":"), btrim(array_index(#2, integer_to_bigint(#1{x})), ",")) // { arity: 5 }
  114. FlatMap generate_series(2, (regexp_split_to_array[" ", case_insensitive=false](#0{line}) array_length 1), 1) // { arity: 2 }
  115. Project (#2) // { arity: 1 }
  116. Map (array_index(regexp_split_to_array["\n", case_insensitive=false](#0{input}), integer_to_bigint(#1{r}))) // { arity: 3 }
  117. FlatMap generate_series(1, (regexp_split_to_array["\n", case_insensitive=false](#0{input}) array_length 1), 1) // { arity: 2 }
  118. ReadStorage materialize.public.input // { arity: 1 }
  119. cte l1 =
  120. Map (case when (#0{src} < "n") then 1 else -1 end) // { arity: 2 }
  121. Union // { arity: 1 }
  122. Project (#0) // { arity: 1 }
  123. Get l0 // { arity: 2 }
  124. Project (#1) // { arity: 1 }
  125. Get l0 // { arity: 2 }
  126. Return // { arity: 1 }
  127. With Mutually Recursive
  128. cte l2 =
  129. Project (#1{sum}) // { arity: 1 }
  130. Get l7 // { arity: 2 }
  131. cte l3 =
  132. Reduce aggregates=[sum(#0{val}), count(#0{val})] // { arity: 2 }
  133. Get l2 // { arity: 1 }
  134. cte l4 =
  135. Project (#2) // { arity: 1 }
  136. Map ((#0{sum} / bigint_to_numeric(case when (#1{count} = 0) then null else #1{count} end))) // { arity: 3 }
  137. Union // { arity: 2 }
  138. Get l3 // { arity: 2 }
  139. Map (null, 0) // { arity: 2 }
  140. Union // { arity: 0 }
  141. Negate // { arity: 0 }
  142. Project () // { arity: 0 }
  143. Get l3 // { arity: 2 }
  144. Constant // { arity: 0 }
  145. - ()
  146. cte l5 =
  147. Reduce aggregates=[sum((#0{val} * #0{val})), sum(#0{val}), count(#0{val})] // { arity: 3 }
  148. Get l2 // { arity: 1 }
  149. cte l6 =
  150. Project (#3) // { arity: 1 }
  151. Map (sqrtnumeric(case when ((#0{sum}) IS NULL OR (#1{sum}) IS NULL OR (case when (#2{count} = 0) then null else #2{count} end) IS NULL OR (case when (0 = (#2{count} - 1)) then null else (#2{count} - 1) end) IS NULL) then null else greatest(((#0{sum} - ((#1{sum} * #1{sum}) / bigint_to_numeric(case when (#2{count} = 0) then null else #2{count} end))) / bigint_to_numeric(case when (0 = (#2{count} - 1)) then null else (#2{count} - 1) end)), 0) end)) // { arity: 4 }
  152. Union // { arity: 3 }
  153. Get l5 // { arity: 3 }
  154. Map (null, null, 0) // { arity: 3 }
  155. Union // { arity: 0 }
  156. Negate // { arity: 0 }
  157. Project () // { arity: 0 }
  158. Get l5 // { arity: 3 }
  159. Constant // { arity: 0 }
  160. - ()
  161. cte [recursion_limit=50, return_at_limit] l7 =
  162. Union // { arity: 2 }
  163. Threshold // { arity: 2 }
  164. Union // { arity: 2 }
  165. Get l1 // { arity: 2 }
  166. Negate // { arity: 2 }
  167. Get l8 // { arity: 2 }
  168. Reduce group_by=[#0] aggregates=[sum(((#1{val} - #2) / #3))] // { arity: 2 }
  169. Project (#0, #3..=#5) // { arity: 4 }
  170. Join on=(#1{dst} = #2{src}) type=delta // { arity: 6 }
  171. implementation
  172. %0 » %2[×]U » %3[×]U » %1:l7[#0{src}]K
  173. %1:l7 » %2[×]U » %3[×]U » %0[#1{dst}]K
  174. %2 » %3[×]U » %0[×] » %1:l7[#0{src}]K
  175. %3 » %2[×]U » %0[×] » %1:l7[#0{src}]K
  176. ArrangeBy keys=[[], [#1{dst}]] // { arity: 2 }
  177. Union // { arity: 2 }
  178. Filter (#1{dst}) IS NOT NULL // { arity: 2 }
  179. Get l0 // { arity: 2 }
  180. Project (#1, #0) // { arity: 2 }
  181. Filter (#0{dst}) IS NOT NULL // { arity: 2 }
  182. Get l0 // { arity: 2 }
  183. ArrangeBy keys=[[#0{src}]] // { arity: 2 }
  184. Filter (#0{src}) IS NOT NULL // { arity: 2 }
  185. Get l7 // { arity: 2 }
  186. ArrangeBy keys=[[]] // { arity: 1 }
  187. Union // { arity: 1 }
  188. Get l4 // { arity: 1 }
  189. Map (null) // { arity: 1 }
  190. Union // { arity: 0 }
  191. Negate // { arity: 0 }
  192. Project () // { arity: 0 }
  193. Get l4 // { arity: 1 }
  194. Constant // { arity: 0 }
  195. - ()
  196. ArrangeBy keys=[[]] // { arity: 1 }
  197. Union // { arity: 1 }
  198. Get l6 // { arity: 1 }
  199. Map (null) // { arity: 1 }
  200. Union // { arity: 0 }
  201. Negate // { arity: 0 }
  202. Project () // { arity: 0 }
  203. Get l6 // { arity: 1 }
  204. Constant // { arity: 0 }
  205. - ()
  206. cte [recursion_limit=50, return_at_limit] l8 =
  207. Get l1 // { arity: 2 }
  208. Return // { arity: 1 }
  209. With
  210. cte l9 =
  211. Reduce aggregates=[count(*)] // { arity: 1 }
  212. Project () // { arity: 0 }
  213. Filter (#1{sum} < 0) // { arity: 2 }
  214. Get l7 // { arity: 2 }
  215. cte l10 =
  216. Union // { arity: 1 }
  217. Get l9 // { arity: 1 }
  218. Map (0) // { arity: 1 }
  219. Union // { arity: 0 }
  220. Negate // { arity: 0 }
  221. Project () // { arity: 0 }
  222. Get l9 // { arity: 1 }
  223. Constant // { arity: 0 }
  224. - ()
  225. cte l11 =
  226. Reduce aggregates=[count(*)] // { arity: 1 }
  227. Project () // { arity: 0 }
  228. Filter (#1{sum} > 0) // { arity: 2 }
  229. Get l7 // { arity: 2 }
  230. cte l12 =
  231. Union // { arity: 1 }
  232. Get l11 // { arity: 1 }
  233. Map (0) // { arity: 1 }
  234. Union // { arity: 0 }
  235. Negate // { arity: 0 }
  236. Project () // { arity: 0 }
  237. Get l11 // { arity: 1 }
  238. Constant // { arity: 0 }
  239. - ()
  240. Return // { arity: 1 }
  241. Project (#2) // { arity: 1 }
  242. Map ((#0{count} * #1{count})) // { arity: 3 }
  243. CrossJoin type=differential // { arity: 2 }
  244. implementation
  245. %0[×]U » %1[×]U
  246. ArrangeBy keys=[[]] // { arity: 1 }
  247. Union // { arity: 1 }
  248. Get l10 // { arity: 1 }
  249. Map (null) // { arity: 1 }
  250. Union // { arity: 0 }
  251. Negate // { arity: 0 }
  252. Project () // { arity: 0 }
  253. Get l10 // { arity: 1 }
  254. Constant // { arity: 0 }
  255. - ()
  256. ArrangeBy keys=[[]] // { arity: 1 }
  257. Union // { arity: 1 }
  258. Get l12 // { arity: 1 }
  259. Map (null) // { arity: 1 }
  260. Union // { arity: 0 }
  261. Negate // { arity: 0 }
  262. Project () // { arity: 0 }
  263. Get l12 // { arity: 1 }
  264. Constant // { arity: 0 }
  265. - ()
  266. Source materialize.public.input
  267. Target cluster: quickstart
  268. EOF