123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480 |
- # Copyright Materialize, Inc. and contributors. All rights reserved.
- #
- # Use of this software is governed by the Business Source License
- # included in the LICENSE file at the root of this repository.
- #
- # As of the Change Date specified in that file, in accordance with
- # the Business Source License, use of this software will be governed
- # by the Apache License, Version 2.0.
- # https://github.com/MaterializeInc/advent-of-code-2023/blob/main/week1/aoc_1222.md
- mode cockroach
- statement ok
- CREATE TABLE input (input TEXT);
- statement ok
- INSERT INTO input VALUES (
- '3,5,62~3,9,62
- 5,5,623~5,1,623
- 8,3,176~8,2,176
- 7,6,17~7,8,17
- 9,3,821~9,3,163
- 2,9,71~2,6,71
- 3,3,514~3,3,390
- 7,4,494~7,9,494
- 5,9,842~5,9,840
- 9,1,41~9,1,296
- 5,4,276~5,4,94
- 3,3,838~3,6,838
- 9,8,425~6,8,425
- 1,2,55~1,8,55
- 1,4,249~3,4,249
- 8,8,541~5,8,541
- 5,4,634~5,4,365
- 4,9,745~4,9,293
- 3,6,621~3,6,287
- 4,9,645~4,9,389
- 7,1,712~0,1,712
- 8,2,69~7,2,69
- 2,3,374~8,3,374
- 7,9,495~0,9,495
- 4,9,200~8,9,200');
- query II
- WITH MUTUALLY RECURSIVE
- lines(r INT, line TEXT) AS (
- SELECT r, regexp_split_to_array(input, '\n')[r] as line
- FROM input, generate_series(1, array_length(regexp_split_to_array(input, '\n'), 1)) r
- ),
- cells(r INT, x INT, y INT, z INT) AS (
- SELECT xs.r, x, y, z
- FROM (SELECT r, generate_series(regexp_split_to_array(regexp_split_to_array(line, '~')[1], ',')[1]::INT,
- regexp_split_to_array(regexp_split_to_array(line, '~')[2], ',')[1]::INT) x FROM lines) xs,
- (SELECT r, generate_series(regexp_split_to_array(regexp_split_to_array(line, '~')[1], ',')[2]::INT,
- regexp_split_to_array(regexp_split_to_array(line, '~')[2], ',')[2]::INT) y FROM lines) ys,
- (SELECT r, generate_series(regexp_split_to_array(regexp_split_to_array(line, '~')[1], ',')[3]::INT,
- regexp_split_to_array(regexp_split_to_array(line, '~')[2], ',')[3]::INT) z FROM lines) zs
- WHERE xs.r = ys.r
- AND xs.r = zs.r
- ),
- -- Part one: let the pieces fall, with a minimum z value of one.
- parts(r INT, x INT, y INT, z INT) AS (
- SELECT * FROM cells
- EXCEPT ALL SELECT * FROM cells_delayed
- UNION ALL
- SELECT r, x, y, CASE WHEN r IN (SELECT * FROM supported) THEN z ELSE z - 1 END
- FROM parts
- ),
- -- One piece supports a *different* piece if it is directly below a piece of the other.
- supports(r1 INT, r2 INT) AS (
- SELECT DISTINCT p1.r, p2.r
- FROM parts p1, parts p2
- WHERE p1.x = p2.x
- AND p1.y = p2.y
- AND p1.z + 1 = p2.z
- AND p1.r != p2.r
- ),
- supported(r INT) AS (
- SELECT r FROM parts WHERE z = 1
- UNION
- SELECT r2 FROM supports
- ),
- -- A piece is safe to remove if it is does not uniquely support any other piece.
- part1(part1 BIGINT) AS (
- SELECT COUNT(DISTINCT r)
- FROM lines
- WHERE r NOT IN (
- SELECT r1
- FROM supports
- WHERE r2 IN (
- SELECT r2
- FROM supports
- GROUP BY r2
- HAVING COUNT(*) = 1
- )
- )
- ),
- cells_delayed(r INT, x INT, y INT, z INT) AS ( SELECT * FROM cells ),
- -- Part two: for each piece, how many pieces would fall if you removed it?
- -- Extend `supports` to transitive support: if r1 vanished would r2 fall?
- supports_trans(r1 INT, r2 INT) AS (
- -- Uniquely supported pieces would certainly fall.
- SELECT *
- FROM supports
- WHERE r2 IN (SELECT r2 FROM supports GROUP BY r2 HAVING COUNT(*) = 1)
- -- Any piece all of whose supports would fall without 'a' also falls without it.
- UNION
- SELECT st.r1, s1.r2
- FROM supports_trans st, supports s1
- WHERE st.r2 = s1.r1
- GROUP BY st.r1, s1.r2
- HAVING COUNT(*) = (SELECT COUNT(*) FROM supports WHERE supports.r2 = s1.r2)
- ),
- part2(part2 BIGINT) AS (SELECT COUNT(*) FROM supports_trans)
- SELECT * FROM part1, part2;
- ----
- 23 3
- query T multiline
- EXPLAIN OPTIMIZED PLAN WITH(humanized expressions, arity, join implementations) AS VERBOSE TEXT FOR
- WITH MUTUALLY RECURSIVE
- lines(r INT, line TEXT) AS (
- SELECT r, regexp_split_to_array(input, '\n')[r] as line
- FROM input, generate_series(1, array_length(regexp_split_to_array(input, '\n'), 1)) r
- ),
- cells(r INT, x INT, y INT, z INT) AS (
- SELECT xs.r, x, y, z
- FROM (SELECT r, generate_series(regexp_split_to_array(regexp_split_to_array(line, '~')[1], ',')[1]::INT,
- regexp_split_to_array(regexp_split_to_array(line, '~')[2], ',')[1]::INT) x FROM lines) xs,
- (SELECT r, generate_series(regexp_split_to_array(regexp_split_to_array(line, '~')[1], ',')[2]::INT,
- regexp_split_to_array(regexp_split_to_array(line, '~')[2], ',')[2]::INT) y FROM lines) ys,
- (SELECT r, generate_series(regexp_split_to_array(regexp_split_to_array(line, '~')[1], ',')[3]::INT,
- regexp_split_to_array(regexp_split_to_array(line, '~')[2], ',')[3]::INT) z FROM lines) zs
- WHERE xs.r = ys.r
- AND xs.r = zs.r
- ),
- -- Part one: let the pieces fall, with a minimum z value of one.
- parts(r INT, x INT, y INT, z INT) AS (
- SELECT * FROM cells
- EXCEPT ALL SELECT * FROM cells_delayed
- UNION ALL
- SELECT r, x, y, CASE WHEN r IN (SELECT * FROM supported) THEN z ELSE z - 1 END
- FROM parts
- ),
- -- One piece supports a *different* piece if it is directly below a piece of the other.
- supports(r1 INT, r2 INT) AS (
- SELECT DISTINCT p1.r, p2.r
- FROM parts p1, parts p2
- WHERE p1.x = p2.x
- AND p1.y = p2.y
- AND p1.z + 1 = p2.z
- AND p1.r != p2.r
- ),
- supported(r INT) AS (
- SELECT r FROM parts WHERE z = 1
- UNION
- SELECT r2 FROM supports
- ),
- -- A piece is safe to remove if it is does not uniquely support any other piece.
- part1(part1 BIGINT) AS (
- SELECT COUNT(DISTINCT r)
- FROM lines
- WHERE r NOT IN (
- SELECT r1
- FROM supports
- WHERE r2 IN (
- SELECT r2
- FROM supports
- GROUP BY r2
- HAVING COUNT(*) = 1
- )
- )
- ),
- cells_delayed(r INT, x INT, y INT, z INT) AS ( SELECT * FROM cells ),
- -- Part two: for each piece, how many pieces would fall if you removed it?
- -- Extend `supports` to transitive support: if r1 vanished would r2 fall?
- supports_trans(r1 INT, r2 INT) AS (
- -- Uniquely supported pieces would certainly fall.
- SELECT *
- FROM supports
- WHERE r2 IN (SELECT r2 FROM supports GROUP BY r2 HAVING COUNT(*) = 1)
- -- Any piece all of whose supports would fall without 'a' also falls without it.
- UNION
- SELECT st.r1, s1.r2
- FROM supports_trans st, supports s1
- WHERE st.r2 = s1.r1
- GROUP BY st.r1, s1.r2
- HAVING COUNT(*) = (SELECT COUNT(*) FROM supports WHERE supports.r2 = s1.r2)
- ),
- part2(part2 BIGINT) AS (SELECT COUNT(*) FROM supports_trans)
- SELECT * FROM part1, part2;
- ----
- Explained Query:
- With
- cte l0 =
- Project (#1, #2) // { arity: 2 }
- Map (array_index(regexp_split_to_array["\n", case_insensitive=false](#0{input}), integer_to_bigint(#1{r}))) // { arity: 3 }
- FlatMap generate_series(1, (regexp_split_to_array["\n", case_insensitive=false](#0{input}) array_length 1), 1) // { arity: 2 }
- ReadStorage materialize.public.input // { arity: 1 }
- cte l1 =
- Project (#0) // { arity: 1 }
- Get l0 // { arity: 2 }
- cte l2 =
- Distinct project=[#0] // { arity: 1 }
- Get l1 // { arity: 1 }
- cte l3 =
- Project (#0, #1, #3, #5) // { arity: 4 }
- Join on=(#0{r} = #2{r} = #4{r}) type=delta // { arity: 6 }
- implementation
- %0 » %1[#0{r}]K » %2[#0{r}]K
- %1 » %0[#0{r}]K » %2[#0{r}]K
- %2 » %0[#0{r}]K » %1[#0{r}]K
- ArrangeBy keys=[[#0{r}]] // { arity: 2 }
- Project (#0, #2) // { arity: 2 }
- FlatMap generate_series(text_to_integer(array_index(regexp_split_to_array[",", case_insensitive=false](array_index(regexp_split_to_array["~", case_insensitive=false](#1{line}), 1)), 1)), text_to_integer(array_index(regexp_split_to_array[",", case_insensitive=false](array_index(regexp_split_to_array["~", case_insensitive=false](#1{line}), 2)), 1)), 1) // { arity: 3 }
- Get l0 // { arity: 2 }
- ArrangeBy keys=[[#0{r}]] // { arity: 2 }
- Project (#0, #2) // { arity: 2 }
- FlatMap generate_series(text_to_integer(array_index(regexp_split_to_array[",", case_insensitive=false](array_index(regexp_split_to_array["~", case_insensitive=false](#1{line}), 1)), 2)), text_to_integer(array_index(regexp_split_to_array[",", case_insensitive=false](array_index(regexp_split_to_array["~", case_insensitive=false](#1{line}), 2)), 2)), 1) // { arity: 3 }
- Get l0 // { arity: 2 }
- ArrangeBy keys=[[#0{r}]] // { arity: 2 }
- Project (#0, #2) // { arity: 2 }
- FlatMap generate_series(text_to_integer(array_index(regexp_split_to_array[",", case_insensitive=false](array_index(regexp_split_to_array["~", case_insensitive=false](#1{line}), 1)), 3)), text_to_integer(array_index(regexp_split_to_array[",", case_insensitive=false](array_index(regexp_split_to_array["~", case_insensitive=false](#1{line}), 2)), 3)), 1) // { arity: 3 }
- Get l0 // { arity: 2 }
- Return // { arity: 2 }
- With Mutually Recursive
- cte l4 =
- Distinct project=[#0] // { arity: 1 }
- Project (#0) // { arity: 1 }
- Get l9 // { arity: 4 }
- cte l5 =
- Reduce group_by=[#0] aggregates=[any((#0{r} = #1{right_col0_0}))] // { arity: 2 }
- CrossJoin type=differential // { arity: 2 }
- implementation
- %0:l4[×] » %1:l12[×]
- ArrangeBy keys=[[]] // { arity: 1 }
- Get l4 // { arity: 1 }
- ArrangeBy keys=[[]] // { arity: 1 }
- Get l12 // { arity: 1 }
- cte l6 =
- ArrangeBy keys=[[#0]] // { arity: 1 }
- Get l4 // { arity: 1 }
- cte l7 =
- Union // { arity: 2 }
- Get l5 // { arity: 2 }
- Project (#0, #2) // { arity: 2 }
- Map (false) // { arity: 3 }
- Join on=(#0 = #1) type=differential // { arity: 2 }
- implementation
- %1:l6[#0]UK » %0[#0]K
- ArrangeBy keys=[[#0]] // { arity: 1 }
- Union // { arity: 1 }
- Negate // { arity: 1 }
- Project (#0) // { arity: 1 }
- Get l5 // { arity: 2 }
- Get l4 // { arity: 1 }
- Get l6 // { arity: 1 }
- cte l8 =
- Union // { arity: 2 }
- Get l7 // { arity: 2 }
- Project (#0, #2) // { arity: 2 }
- FlatMap guard_subquery_size(#1{count}) // { arity: 3 }
- Reduce group_by=[#0] aggregates=[count(*)] // { arity: 2 }
- Project (#0) // { arity: 1 }
- Get l7 // { arity: 2 }
- cte l9 =
- Union // { arity: 4 }
- Threshold // { arity: 4 }
- Union // { arity: 4 }
- Get l3 // { arity: 4 }
- Negate // { arity: 4 }
- Get l16 // { arity: 4 }
- Project (#0..=#2, #6) // { arity: 4 }
- Map (case when #5{any} then #3{z} else (#3{z} - 1) end) // { arity: 7 }
- Join on=(#0 = #4) type=differential // { arity: 6 }
- implementation
- %0:l9[#0]K » %1[#0]K
- ArrangeBy keys=[[#0]] // { arity: 4 }
- Get l9 // { arity: 4 }
- ArrangeBy keys=[[#0]] // { arity: 2 }
- Union // { arity: 2 }
- Get l8 // { arity: 2 }
- Project (#0, #2) // { arity: 2 }
- Map (null) // { arity: 3 }
- Join on=(#0 = #1) type=differential // { arity: 2 }
- implementation
- %1:l6[#0]UK » %0[#0]K
- ArrangeBy keys=[[#0]] // { arity: 1 }
- Union // { arity: 1 }
- Negate // { arity: 1 }
- Distinct project=[#0] // { arity: 1 }
- Project (#0) // { arity: 1 }
- Get l8 // { arity: 2 }
- Get l4 // { arity: 1 }
- Get l6 // { arity: 1 }
- cte l10 =
- Distinct project=[#0, #1] // { arity: 2 }
- Project (#0, #4) // { arity: 2 }
- Filter (#0{r} != #4{r}) // { arity: 8 }
- Join on=(#1{x} = #5{x} AND #2{y} = #6{y} AND #7{z} = (#3{z} + 1)) type=differential // { arity: 8 }
- implementation
- %0:l9[#1{x}, #2{y}, (#3{z} + 1)]KKK » %1:l9[#1{x}..=#3{z}]KKK
- ArrangeBy keys=[[#1{x}, #2{y}, (#3{z} + 1)]] // { arity: 4 }
- Get l9 // { arity: 4 }
- ArrangeBy keys=[[#1{x}..=#3{z}]] // { arity: 4 }
- Get l9 // { arity: 4 }
- cte l11 =
- Project (#1) // { arity: 1 }
- Get l10 // { arity: 2 }
- cte l12 =
- Distinct project=[#0] // { arity: 1 }
- Union // { arity: 1 }
- Project (#0) // { arity: 1 }
- Filter (#3{z} = 1) // { arity: 4 }
- Get l9 // { arity: 4 }
- Get l11 // { arity: 1 }
- cte l13 =
- CrossJoin type=differential // { arity: 3 }
- implementation
- %0:l2[×] » %1:l10[×]
- ArrangeBy keys=[[]] // { arity: 1 }
- Get l2 // { arity: 1 }
- ArrangeBy keys=[[]] // { arity: 2 }
- Get l10 // { arity: 2 }
- cte l14 =
- ArrangeBy keys=[[#0]] // { arity: 1 }
- Get l11 // { arity: 1 }
- cte l15 =
- Reduce aggregates=[count(distinct #0{r})] // { arity: 1 }
- Project (#0) // { arity: 1 }
- Join on=(#0 = #1) type=differential // { arity: 2 }
- implementation
- %0:l1[#0]K » %1[#0]K
- ArrangeBy keys=[[#0]] // { arity: 1 }
- Get l1 // { arity: 1 }
- ArrangeBy keys=[[#0]] // { arity: 1 }
- Union // { arity: 1 }
- Negate // { arity: 1 }
- Distinct project=[#0] // { arity: 1 }
- Project (#0) // { arity: 1 }
- Filter (#3{count} = 1) // { arity: 4 }
- Join on=(#1 = #2) type=differential // { arity: 4 }
- implementation
- %1[#0]UKAef » %0:l13[#1]Kef
- ArrangeBy keys=[[#1]] // { arity: 2 }
- Project (#0, #2) // { arity: 2 }
- Filter (#0 = #1) // { arity: 3 }
- Get l13 // { arity: 3 }
- ArrangeBy keys=[[#0]] // { arity: 2 }
- Reduce group_by=[#0] aggregates=[count(*)] // { arity: 2 }
- Project (#0) // { arity: 1 }
- Join on=(#0 = #1) type=differential // { arity: 2 }
- implementation
- %0[#0]UKA » %1:l14[#0]K
- ArrangeBy keys=[[#0]] // { arity: 1 }
- Distinct project=[#0] // { arity: 1 }
- Project (#2) // { arity: 1 }
- Get l13 // { arity: 3 }
- Get l14 // { arity: 1 }
- Get l2 // { arity: 1 }
- cte l16 =
- Get l3 // { arity: 4 }
- cte l17 =
- Reduce group_by=[#0, #1] aggregates=[count(*)] // { arity: 3 }
- Project (#0, #3) // { arity: 2 }
- Join on=(#1{r2} = #2{r1}) type=differential // { arity: 4 }
- implementation
- %0:l22[#1{r2}]K » %1:l10[#0{r1}]K
- ArrangeBy keys=[[#1{r2}]] // { arity: 2 }
- Get l22 // { arity: 2 }
- ArrangeBy keys=[[#0{r1}]] // { arity: 2 }
- Get l10 // { arity: 2 }
- cte l18 =
- Distinct project=[#0] // { arity: 1 }
- Project (#1) // { arity: 1 }
- Get l17 // { arity: 3 }
- cte l19 =
- ArrangeBy keys=[[#0{r2}]] // { arity: 1 }
- Get l18 // { arity: 1 }
- cte l20 =
- Reduce group_by=[#0] aggregates=[count(*)] // { arity: 2 }
- Project (#0) // { arity: 1 }
- Join on=(#0{r2} = #1{r2}) type=differential // { arity: 2 }
- implementation
- %0:l19[#0{r2}]UK » %1:l14[#0{r2}]K
- Get l19 // { arity: 1 }
- Get l14 // { arity: 1 }
- cte l21 =
- Union // { arity: 2 }
- Get l20 // { arity: 2 }
- Project (#0, #2) // { arity: 2 }
- Map (0) // { arity: 3 }
- Join on=(#0 = #1) type=differential // { arity: 2 }
- implementation
- %1:l19[#0]UK » %0[#0]K
- ArrangeBy keys=[[#0]] // { arity: 1 }
- Union // { arity: 1 }
- Negate // { arity: 1 }
- Project (#0) // { arity: 1 }
- Get l20 // { arity: 2 }
- Get l18 // { arity: 1 }
- Get l19 // { arity: 1 }
- cte l22 =
- Distinct project=[#0, #1] // { arity: 2 }
- Union // { arity: 2 }
- Project (#0, #1) // { arity: 2 }
- Filter (#3{count} = 1) // { arity: 4 }
- Join on=(#1 = #2) type=differential // { arity: 4 }
- implementation
- %1[#0]UKAef » %0:l10[#1]Kef
- ArrangeBy keys=[[#1]] // { arity: 2 }
- Get l10 // { arity: 2 }
- ArrangeBy keys=[[#0]] // { arity: 2 }
- Reduce group_by=[#0] aggregates=[count(*)] // { arity: 2 }
- Get l11 // { arity: 1 }
- Project (#0, #1) // { arity: 2 }
- Join on=(#1 = #3 AND #2{count} = #4{count}) type=differential // { arity: 5 }
- implementation
- %0:l17[#1, #2{"?column?"}]KK » %1[#0, #1]KK
- ArrangeBy keys=[[#1, #2{count}]] // { arity: 3 }
- Get l17 // { arity: 3 }
- ArrangeBy keys=[[#0, #1{count}]] // { arity: 2 }
- Union // { arity: 2 }
- Get l21 // { arity: 2 }
- Project (#0, #2) // { arity: 2 }
- FlatMap guard_subquery_size(#1{count}) // { arity: 3 }
- Reduce group_by=[#0] aggregates=[count(*)] // { arity: 2 }
- Project (#0) // { arity: 1 }
- Get l21 // { arity: 2 }
- Return // { arity: 2 }
- With
- cte l23 =
- Reduce aggregates=[count(*)] // { arity: 1 }
- Project () // { arity: 0 }
- Get l22 // { arity: 2 }
- Return // { arity: 2 }
- CrossJoin type=differential // { arity: 2 }
- implementation
- %0[×]U » %1[×]U
- ArrangeBy keys=[[]] // { arity: 1 }
- Union // { arity: 1 }
- Get l15 // { arity: 1 }
- Map (0) // { arity: 1 }
- Union // { arity: 0 }
- Negate // { arity: 0 }
- Project () // { arity: 0 }
- Get l15 // { arity: 1 }
- Constant // { arity: 0 }
- - ()
- ArrangeBy keys=[[]] // { arity: 1 }
- Union // { arity: 1 }
- Get l23 // { arity: 1 }
- Map (0) // { arity: 1 }
- Union // { arity: 0 }
- Negate // { arity: 0 }
- Project () // { arity: 0 }
- Get l23 // { arity: 1 }
- Constant // { arity: 0 }
- - ()
- Source materialize.public.input
- Target cluster: quickstart
- EOF
|