aoc_1216.slt 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459
  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_1217.md
  10. mode cockroach
  11. statement ok
  12. CREATE TABLE input (input TEXT);
  13. statement ok
  14. INSERT INTO input VALUES (
  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. query II
  41. WITH MUTUALLY RECURSIVE
  42. lines(r INT, line TEXT) AS (
  43. SELECT r, regexp_split_to_array(input, '\n')[r] as block
  44. FROM input, generate_series(1, array_length(regexp_split_to_array(input, '\n'), 1)) r
  45. ),
  46. cells(r INT, c INT, symbol TEXT) AS (
  47. SELECT r, c, substring(line, c, 1)
  48. FROM lines, generate_series(1, length(line)) c
  49. ),
  50. shift(dir TEXT, symbol TEXT, dr INT, dc INT, new_dir TEXT) AS (
  51. VALUES
  52. ('r', '.', 0, 1, 'r'),
  53. ('r', '-', 0, 1, 'r'),
  54. ('r', '|', 1, 0, 'd'),
  55. ('r', '|', -1, 0, 'u'),
  56. ('r', '/', -1, 0, 'u'),
  57. ('r', '\', 1, 0, 'd'),
  58. ('l', '.', 0, -1, 'l'),
  59. ('l', '-', 0, -1, 'l'),
  60. ('l', '|', 1, 0, 'd'),
  61. ('l', '|', -1, 0, 'u'),
  62. ('l', '/', 1, 0, 'd'),
  63. ('l', '\', -1, 0, 'u'),
  64. ('u', '.', -1, 0, 'u'),
  65. ('u', '-', 0, 1, 'r'),
  66. ('u', '-', 0, -1, 'l'),
  67. ('u', '|', -1, 0, 'u'),
  68. ('u', '/', 0, 1, 'r'),
  69. ('u', '\', 0, -1, 'l'),
  70. ('d', '.', 1, 0, 'd'),
  71. ('d', '-', 0, 1, 'r'),
  72. ('d', '-', 0, -1, 'l'),
  73. ('d', '|', 1, 0, 'd'),
  74. ('d', '/', 0, -1, 'l'),
  75. ('d', '\', 0, 1, 'r')
  76. ),
  77. -- Light is in a location, and has a direction.
  78. light(r INT, c INT, dir TEXT) AS (
  79. SELECT 1, 1, 'r'
  80. UNION
  81. SELECT light.r + dr, light.c + dc, new_dir
  82. FROM light, cells, shift
  83. WHERE light.r = cells.r
  84. AND light.c = cells.c
  85. AND light.dir = shift.dir
  86. AND cells.symbol = shift.symbol
  87. ),
  88. part1(part1 BIGINT) AS (
  89. SELECT COUNT(*) FROM (
  90. SELECT DISTINCT light.r, light.c
  91. FROM light, cells
  92. WHERE light.r = cells.r
  93. AND light.c = cells.c
  94. )
  95. ),
  96. -- Light is in a location, a direction, and an origin.
  97. light2(r INT, c INT, dir TEXT, source TEXT) AS (
  98. SELECT DISTINCT * FROM (SELECT r, (SELECT MIN(c) FROM cells), 'r', 'r' || r FROM cells) UNION
  99. SELECT DISTINCT * FROM (SELECT r, (SELECT MAX(c) FROM cells), 'l', 'l' || r FROM cells) UNION
  100. SELECT DISTINCT * FROM (SELECT (SELECT MIN(r) FROM cells), c, 'd', 'd' || c FROM cells) UNION
  101. SELECT DISTINCT * FROM (SELECT (SELECT MAX(c) FROM cells), c, 'u', 'u' || c FROM cells) UNION
  102. SELECT light2.r + dr, light2.c + dc, new_dir, source
  103. FROM light2, cells, shift
  104. WHERE light2.r = cells.r
  105. AND light2.c = cells.c
  106. AND light2.dir = shift.dir
  107. AND cells.symbol = shift.symbol
  108. ),
  109. part2(part2 BIGINT) AS (
  110. SELECT MAX(count) FROM (
  111. SELECT source, COUNT(*) FROM (
  112. SELECT DISTINCT light2.r, light2.c, source
  113. FROM light2, cells
  114. WHERE light2.r = cells.r
  115. AND light2.c = cells.c
  116. )
  117. GROUP BY source
  118. )
  119. )
  120. SELECT * FROM part1, part2;
  121. ----
  122. 15 613
  123. query T multiline
  124. EXPLAIN OPTIMIZED PLAN WITH(humanized expressions, arity, join implementations) AS VERBOSE TEXT FOR
  125. WITH MUTUALLY RECURSIVE
  126. lines(r INT, line TEXT) AS (
  127. SELECT r, regexp_split_to_array(input, '\n')[r] as block
  128. FROM input, generate_series(1, array_length(regexp_split_to_array(input, '\n'), 1)) r
  129. ),
  130. cells(r INT, c INT, symbol TEXT) AS (
  131. SELECT r, c, substring(line, c, 1)
  132. FROM lines, generate_series(1, length(line)) c
  133. ),
  134. shift(dir TEXT, symbol TEXT, dr INT, dc INT, new_dir TEXT) AS (
  135. VALUES
  136. ('r', '.', 0, 1, 'r'),
  137. ('r', '-', 0, 1, 'r'),
  138. ('r', '|', 1, 0, 'd'),
  139. ('r', '|', -1, 0, 'u'),
  140. ('r', '/', -1, 0, 'u'),
  141. ('r', '\', 1, 0, 'd'),
  142. ('l', '.', 0, -1, 'l'),
  143. ('l', '-', 0, -1, 'l'),
  144. ('l', '|', 1, 0, 'd'),
  145. ('l', '|', -1, 0, 'u'),
  146. ('l', '/', 1, 0, 'd'),
  147. ('l', '\', -1, 0, 'u'),
  148. ('u', '.', -1, 0, 'u'),
  149. ('u', '-', 0, 1, 'r'),
  150. ('u', '-', 0, -1, 'l'),
  151. ('u', '|', -1, 0, 'u'),
  152. ('u', '/', 0, 1, 'r'),
  153. ('u', '\', 0, -1, 'l'),
  154. ('d', '.', 1, 0, 'd'),
  155. ('d', '-', 0, 1, 'r'),
  156. ('d', '-', 0, -1, 'l'),
  157. ('d', '|', 1, 0, 'd'),
  158. ('d', '/', 0, -1, 'l'),
  159. ('d', '\', 0, 1, 'r')
  160. ),
  161. -- Light is in a location, and has a direction.
  162. light(r INT, c INT, dir TEXT) AS (
  163. SELECT 1, 1, 'r'
  164. UNION
  165. SELECT light.r + dr, light.c + dc, new_dir
  166. FROM light, cells, shift
  167. WHERE light.r = cells.r
  168. AND light.c = cells.c
  169. AND light.dir = shift.dir
  170. AND cells.symbol = shift.symbol
  171. ),
  172. part1(part1 BIGINT) AS (
  173. SELECT COUNT(*) FROM (
  174. SELECT DISTINCT light.r, light.c
  175. FROM light, cells
  176. WHERE light.r = cells.r
  177. AND light.c = cells.c
  178. )
  179. ),
  180. -- Light is in a location, a direction, and an origin.
  181. light2(r INT, c INT, dir TEXT, source TEXT) AS (
  182. SELECT DISTINCT * FROM (SELECT r, (SELECT MIN(c) FROM cells), 'r', 'r' || r FROM cells) UNION
  183. SELECT DISTINCT * FROM (SELECT r, (SELECT MAX(c) FROM cells), 'l', 'l' || r FROM cells) UNION
  184. SELECT DISTINCT * FROM (SELECT (SELECT MIN(r) FROM cells), c, 'd', 'd' || c FROM cells) UNION
  185. SELECT DISTINCT * FROM (SELECT (SELECT MAX(c) FROM cells), c, 'u', 'u' || c FROM cells) UNION
  186. SELECT light2.r + dr, light2.c + dc, new_dir, source
  187. FROM light2, cells, shift
  188. WHERE light2.r = cells.r
  189. AND light2.c = cells.c
  190. AND light2.dir = shift.dir
  191. AND cells.symbol = shift.symbol
  192. ),
  193. part2(part2 BIGINT) AS (
  194. SELECT MAX(count) FROM (
  195. SELECT source, COUNT(*) FROM (
  196. SELECT DISTINCT light2.r, light2.c, source
  197. FROM light2, cells
  198. WHERE light2.r = cells.r
  199. AND light2.c = cells.c
  200. )
  201. GROUP BY source
  202. )
  203. )
  204. SELECT * FROM part1, part2;
  205. ----
  206. Explained Query:
  207. With
  208. cte l0 =
  209. Project (#0, #2, #3) // { arity: 3 }
  210. Map (substr(#1{line}, #2{c}, 1)) // { arity: 4 }
  211. FlatMap generate_series(1, char_length(#1{line}), 1) // { arity: 3 }
  212. Project (#1, #2) // { arity: 2 }
  213. Map (array_index(regexp_split_to_array["\n", case_insensitive=false](#0{input}), integer_to_bigint(#1{r}))) // { arity: 3 }
  214. FlatMap generate_series(1, (regexp_split_to_array["\n", case_insensitive=false](#0{input}) array_length 1), 1) // { arity: 2 }
  215. ReadStorage materialize.public.input // { arity: 1 }
  216. cte l1 =
  217. Project (#1) // { arity: 1 }
  218. Get l0 // { arity: 3 }
  219. cte l2 =
  220. Reduce aggregates=[min(#0{c})] // { arity: 1 }
  221. Get l1 // { arity: 1 }
  222. cte l3 =
  223. Union // { arity: 1 }
  224. Get l2 // { arity: 1 }
  225. Map (null) // { arity: 1 }
  226. Union // { arity: 0 }
  227. Negate // { arity: 0 }
  228. Project () // { arity: 0 }
  229. Get l2 // { arity: 1 }
  230. Constant // { arity: 0 }
  231. - ()
  232. cte l4 =
  233. Reduce aggregates=[max(#0{c})] // { arity: 1 }
  234. Get l1 // { arity: 1 }
  235. cte l5 =
  236. Union // { arity: 1 }
  237. Get l4 // { arity: 1 }
  238. Map (null) // { arity: 1 }
  239. Union // { arity: 0 }
  240. Negate // { arity: 0 }
  241. Project () // { arity: 0 }
  242. Get l4 // { arity: 1 }
  243. Constant // { arity: 0 }
  244. - ()
  245. cte l6 =
  246. Project (#0) // { arity: 1 }
  247. Get l0 // { arity: 3 }
  248. cte l7 =
  249. Reduce aggregates=[min(#0{r})] // { arity: 1 }
  250. Get l6 // { arity: 1 }
  251. cte l8 =
  252. Union // { arity: 1 }
  253. Get l7 // { arity: 1 }
  254. Map (null) // { arity: 1 }
  255. Union // { arity: 0 }
  256. Negate // { arity: 0 }
  257. Project () // { arity: 0 }
  258. Get l7 // { arity: 1 }
  259. Constant // { arity: 0 }
  260. - ()
  261. cte l9 =
  262. Project (#0, #1) // { arity: 2 }
  263. Get l0 // { arity: 3 }
  264. cte l10 =
  265. CrossJoin type=differential // { arity: 3 }
  266. implementation
  267. %1[×]U » %0:l9[×]
  268. ArrangeBy keys=[[]] // { arity: 2 }
  269. Get l9 // { arity: 2 }
  270. ArrangeBy keys=[[]] // { arity: 1 }
  271. Union // { arity: 1 }
  272. Get l5 // { arity: 1 }
  273. Map (null) // { arity: 1 }
  274. Union // { arity: 0 }
  275. Negate // { arity: 0 }
  276. Project () // { arity: 0 }
  277. Get l5 // { arity: 1 }
  278. Constant // { arity: 0 }
  279. - ()
  280. cte l11 =
  281. ArrangeBy keys=[[#0{r}, #1{c}]] // { arity: 3 }
  282. Filter (#2{symbol}) IS NOT NULL // { arity: 3 }
  283. Get l0 // { arity: 3 }
  284. cte l12 =
  285. ArrangeBy keys=[[#0{dir}, #1{symbol}]] // { arity: 5 }
  286. Constant // { arity: 5 }
  287. total_rows (diffs absed): 24
  288. first_rows:
  289. - ("d", "-", 0, -1, "l")
  290. - ("d", "/", 0, -1, "l")
  291. - ("l", "-", 0, -1, "l")
  292. - ("l", ".", 0, -1, "l")
  293. - ("l", "\", -1, 0, "u")
  294. - ("l", "|", -1, 0, "u")
  295. - ("r", "/", -1, 0, "u")
  296. - ("r", "|", -1, 0, "u")
  297. - ("u", "-", 0, -1, "l")
  298. - ("u", ".", -1, 0, "u")
  299. - ("u", "\", 0, -1, "l")
  300. - ("u", "|", -1, 0, "u")
  301. - ("d", "-", 0, 1, "r")
  302. - ("d", ".", 1, 0, "d")
  303. - ("d", "\", 0, 1, "r")
  304. - ("d", "|", 1, 0, "d")
  305. - ("l", "/", 1, 0, "d")
  306. - ("l", "|", 1, 0, "d")
  307. - ("r", "-", 0, 1, "r")
  308. - ("r", ".", 0, 1, "r")
  309. Return // { arity: 2 }
  310. With Mutually Recursive
  311. cte l13 =
  312. Distinct project=[#0..=#2] // { arity: 3 }
  313. Union // { arity: 3 }
  314. Project (#11, #12, #10) // { arity: 3 }
  315. Map ((#0{r} + #8{dr}), (#1{c} + #9{dc})) // { arity: 13 }
  316. Join on=(#0{r} = #3{r} AND #1{c} = #4{c} AND #2{dir} = #6{dir} AND #5{symbol} = #7{symbol}) type=differential // { arity: 11 }
  317. implementation
  318. %0:l13[#0{r}, #1{c}]KK » %1:l11[#0{r}, #1{c}]KK » %2:l12[#0{dir}, #1{symbol}]KK
  319. ArrangeBy keys=[[#0{r}, #1{c}]] // { arity: 3 }
  320. Get l13 // { arity: 3 }
  321. Get l11 // { arity: 3 }
  322. Get l12 // { arity: 5 }
  323. Constant // { arity: 3 }
  324. - (1, 1, "r")
  325. cte l14 =
  326. Reduce aggregates=[count(*)] // { arity: 1 }
  327. Project () // { arity: 0 }
  328. Join on=(#0{r} = #2{r} AND #1{c} = #3{c}) type=differential // { arity: 4 }
  329. implementation
  330. %0[#0, #1]UKKA » %1[#0, #1]UKKA
  331. ArrangeBy keys=[[#0{r}, #1{c}]] // { arity: 2 }
  332. Distinct project=[#0{r}, #1{c}] // { arity: 2 }
  333. Project (#0, #1) // { arity: 2 }
  334. Get l13 // { arity: 3 }
  335. ArrangeBy keys=[[#0{r}, #1{c}]] // { arity: 2 }
  336. Distinct project=[#0{r}, #1{c}] // { arity: 2 }
  337. Get l9 // { arity: 2 }
  338. cte l15 =
  339. Distinct project=[#0{min}..=#3] // { arity: 4 }
  340. Union // { arity: 4 }
  341. Project (#0, #1{min}, #3, #2) // { arity: 4 }
  342. Map (("r" || integer_to_text(#0{r})), "r") // { arity: 4 }
  343. CrossJoin type=differential // { arity: 2 }
  344. implementation
  345. %1[×]U » %0:l6[×]
  346. ArrangeBy keys=[[]] // { arity: 1 }
  347. Get l6 // { arity: 1 }
  348. ArrangeBy keys=[[]] // { arity: 1 }
  349. Union // { arity: 1 }
  350. Get l3 // { arity: 1 }
  351. Map (null) // { arity: 1 }
  352. Union // { arity: 0 }
  353. Negate // { arity: 0 }
  354. Project () // { arity: 0 }
  355. Get l3 // { arity: 1 }
  356. Constant // { arity: 0 }
  357. - ()
  358. Project (#0, #2{max}, #4, #3) // { arity: 4 }
  359. Map (("l" || integer_to_text(#0{r})), "l") // { arity: 5 }
  360. Get l10 // { arity: 3 }
  361. Project (#1{min}, #0, #3, #2) // { arity: 4 }
  362. Map (("d" || integer_to_text(#0{c})), "d") // { arity: 4 }
  363. CrossJoin type=differential // { arity: 2 }
  364. implementation
  365. %1[×]U » %0:l1[×]
  366. ArrangeBy keys=[[]] // { arity: 1 }
  367. Get l1 // { arity: 1 }
  368. ArrangeBy keys=[[]] // { arity: 1 }
  369. Union // { arity: 1 }
  370. Get l8 // { arity: 1 }
  371. Map (null) // { arity: 1 }
  372. Union // { arity: 0 }
  373. Negate // { arity: 0 }
  374. Project () // { arity: 0 }
  375. Get l8 // { arity: 1 }
  376. Constant // { arity: 0 }
  377. - ()
  378. Project (#2{max}, #1, #4, #3) // { arity: 4 }
  379. Map (("u" || integer_to_text(#1{c})), "u") // { arity: 5 }
  380. Get l10 // { arity: 3 }
  381. Project (#12, #13, #11, #3) // { arity: 4 }
  382. Map ((#0{r} + #9{dr}), (#1{c} + #10{dc})) // { arity: 14 }
  383. Join on=(#0{r} = #4{r} AND #1{c} = #5{c} AND #2{dir} = #7{dir} AND #6{symbol} = #8{symbol}) type=differential // { arity: 12 }
  384. implementation
  385. %0:l15[#0{r}, #1{c}]KK » %1:l11[#0{r}, #1{c}]KK » %2:l12[#0{dir}, #1{symbol}]KK
  386. ArrangeBy keys=[[#0{min}, #1{min}]] // { arity: 4 }
  387. Filter (#0{min}) IS NOT NULL AND (#1{min}) IS NOT NULL // { arity: 4 }
  388. Get l15 // { arity: 4 }
  389. Get l11 // { arity: 3 }
  390. Get l12 // { arity: 5 }
  391. Return // { arity: 2 }
  392. With
  393. cte l16 =
  394. Reduce aggregates=[max(#0{count})] // { arity: 1 }
  395. Project (#1{count}) // { arity: 1 }
  396. Reduce group_by=[#0] aggregates=[count(*)] // { arity: 2 }
  397. Project (#2) // { arity: 1 }
  398. Join on=(#0{min} = #3{r} AND #1{min} = #4{c}) type=differential // { arity: 5 }
  399. implementation
  400. %1[#0, #1]UKKA » %0[#0, #1]KK
  401. ArrangeBy keys=[[#0{min}, #1{min}]] // { arity: 3 }
  402. Distinct project=[#0{min}..=#2] // { arity: 3 }
  403. Project (#0{min}, #1{min}, #3) // { arity: 3 }
  404. Filter (#0{min}) IS NOT NULL AND (#1{min}) IS NOT NULL // { arity: 4 }
  405. Get l15 // { arity: 4 }
  406. ArrangeBy keys=[[#0{r}, #1{c}]] // { arity: 2 }
  407. Distinct project=[#0{r}, #1{c}] // { arity: 2 }
  408. Project (#0, #1) // { arity: 2 }
  409. Get l0 // { arity: 3 }
  410. Return // { arity: 2 }
  411. CrossJoin type=differential // { arity: 2 }
  412. implementation
  413. %0[×]U » %1[×]U
  414. ArrangeBy keys=[[]] // { arity: 1 }
  415. Union // { arity: 1 }
  416. Get l14 // { arity: 1 }
  417. Map (0) // { arity: 1 }
  418. Union // { arity: 0 }
  419. Negate // { arity: 0 }
  420. Project () // { arity: 0 }
  421. Get l14 // { arity: 1 }
  422. Constant // { arity: 0 }
  423. - ()
  424. ArrangeBy keys=[[]] // { arity: 1 }
  425. Union // { arity: 1 }
  426. Get l16 // { arity: 1 }
  427. Map (null) // { arity: 1 }
  428. Union // { arity: 0 }
  429. Negate // { arity: 0 }
  430. Project () // { arity: 0 }
  431. Get l16 // { arity: 1 }
  432. Constant // { arity: 0 }
  433. - ()
  434. Source materialize.public.input
  435. Target cluster: quickstart
  436. EOF