aoc_1208.slt 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  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_1208.md
  10. mode cockroach
  11. statement ok
  12. CREATE TABLE steps_input (input TEXT);
  13. statement ok
  14. CREATE TABLE paths (state TEXT, left TEXT, right TEXT);
  15. # no data
  16. query T multiline
  17. EXPLAIN OPTIMIZED PLAN WITH(humanized expressions, arity, join implementations) AS VERBOSE TEXT FOR
  18. WITH MUTUALLY RECURSIVE
  19. route(step TEXT, steps INT) AS (
  20. SELECT substring(input, steps, 1), steps
  21. FROM steps_input, generate_series(1, length(input)) steps
  22. ),
  23. -- Part 1: Start at 'AAA` and go until `ZZZ`.
  24. pos1(state TEXT, steps INT) AS (
  25. SELECT 'AAA', 0
  26. UNION ALL
  27. SELECT
  28. CASE WHEN route.step = 'L' THEN paths.left
  29. WHEN route.step = 'R' THEN paths.right
  30. ELSE '???'
  31. END,
  32. pos1.steps + 1
  33. FROM paths, pos1, route
  34. WHERE pos1.state = paths.state
  35. AND 1 + (pos1.steps % 263) = route.steps
  36. AND pos1.state != 'ZZZ'
  37. AND pos1.state != '???'
  38. ),
  39. part1(part1 INT) AS (SELECT steps FROM pos1 WHERE pos1.state = 'ZZZ'),
  40. -- Part 2: Start at all '**A` and go until all at '**Z'
  41. pos2(start TEXT, state TEXT, steps INT) AS (
  42. SELECT state, state, 0
  43. FROM paths
  44. WHERE substring(state, 3, 1) = 'A'
  45. UNION ALL
  46. SELECT
  47. pos2.start,
  48. CASE WHEN route.step = 'L' THEN paths.left
  49. WHEN route.step = 'R' THEN paths.right
  50. ELSE '???'
  51. END,
  52. pos2.steps + 1
  53. FROM paths, pos2, route
  54. WHERE pos2.state = paths.state
  55. AND 1 + (pos2.steps % 263) = route.steps
  56. AND substring(pos2.state, 3, 1) != 'Z'
  57. )
  58. SELECT * FROM pos2 WHERE substring(state, 3, 1) = 'Z';
  59. ----
  60. Explained Query:
  61. With Mutually Recursive
  62. cte l0 =
  63. Union // { arity: 3 }
  64. Project (#0{state}, #0{state}, #3) // { arity: 3 }
  65. Filter ("A" = substr(#0{state}, 3, 1)) // { arity: 4 }
  66. Map (0) // { arity: 4 }
  67. ReadStorage materialize.public.paths // { arity: 3 }
  68. Project (#3, #8, #9) // { arity: 3 }
  69. Map (case when (#7{step} = "L") then #1{"left"} else case when (#7{step} = "R") then #2{"right"} else "???" end end, (#5{steps} + 1)) // { arity: 10 }
  70. Join on=(#0{state} = #4{state} AND #6{steps} = (1 + (#5{steps} % 263))) type=delta // { arity: 8 }
  71. implementation
  72. %0:paths » %1:l0[#1{state}]Kf » %2[#0{steps}]K
  73. %1:l0 » %0:paths[#0{state}]Kf » %2[#0{steps}]K
  74. %2 » %1:l0[(1 + (#2{steps} % 263))]Kf » %0:paths[#0{state}]Kf
  75. ArrangeBy keys=[[#0{state}]] // { arity: 3 }
  76. Filter ("Z" != substr(#0{state}, 3, 1)) // { arity: 3 }
  77. ReadStorage materialize.public.paths // { arity: 3 }
  78. ArrangeBy keys=[[#1{state}], [(1 + (#2{steps} % 263))]] // { arity: 3 }
  79. Filter ("Z" != substr(#1{state}, 3, 1)) // { arity: 3 }
  80. Get l0 // { arity: 3 }
  81. ArrangeBy keys=[[#0{steps}]] // { arity: 2 }
  82. Project (#1, #2) // { arity: 2 }
  83. Map (substr(#0{input}, #1{steps}, 1)) // { arity: 3 }
  84. FlatMap generate_series(1, char_length(#0{input}), 1) // { arity: 2 }
  85. ReadStorage materialize.public.steps_input // { arity: 1 }
  86. Return // { arity: 3 }
  87. Filter ("Z" = substr(#1{state}, 3, 1)) // { arity: 3 }
  88. Get l0 // { arity: 3 }
  89. Source materialize.public.steps_input
  90. Source materialize.public.paths
  91. Target cluster: quickstart
  92. EOF