123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512 |
- # 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_1213.md
- mode cockroach
- statement ok
- CREATE TABLE input (input TEXT);
- statement ok
- INSERT INTO input VALUES (
- '#.###..##
- ..###..#.
- .##.....#
- ..###....
- ..##..#..
- .##.#..#.
- ##...##..
- ..#.#.#.#
- #####.###
- ....#.##.
- .#.######
- ....##...
- #..##...#
- <EMPTY_LINE>
- ###.#..###.#....#
- ...#....#..#..#.#
- ...#...##.#.#.#..
- ##.#...##.#.....#
- .#..#....##...##.
- .##....#...#.#...
- ..#.##.##.#..##.#
- ........#.##.#..#
- <EMPTY_LINE>
- #...#..#.......
- .#.###.##.#.###
- .#.##..........
- ##.##.##.###.##
- ..###.#.....#..
- ..###.#.....#..
- ##.##.##.###.##
- #....#.##...###
- #.#.....##..#..
- ...###.....#...
- ..#.....#..#...
- ##.###.##......
- ...#.##.#.#.#.#
- ..........####.
- <EMPTY_LINE>
- ...#.....
- ...#.....
- ...#.....
- #...##...
- ..#.....#
- ...#.####
- .##....##
- ......#..
- #.....#..
- ....#.#.#
- ##...####
- <EMPTY_LINE>
- ...##.##.#.##
- #....#..#..##
- ##.##....###.
- #..###....#.#
- ###...##..#..
- #.#...#.#.##.
- ###..#.......
- ..##.#.#...##
- ##..#..#..#.#
- ......#...###
- ..#..#.##....
- ##.#...#.#...
- #..#.....####
- ....##.##..#.
- ####......###
- <EMPTY_LINE>
- #.##..#..##
- .#.#####..#
- .##.##...##
- .#.#..#...#
- ...####.#..
- #..######..
- ..#....#...
- .#####.##.#
- ..........#
- ##.#..#.#.#
- .......#...
- <EMPTY_LINE>
- .#.#..#....###...
- ######..#.###.#..
- ##..##.#..#..#...
- ...##...##...#.#.
- #...#..####..#.#.
- ..####.#..#...#.#
- ####.#......#.#..
- ##..##...#.#...#.
- <EMPTY_LINE>
- #..#.##..........
- .#....##....#.#.#
- .##.....##....###
- #####...##...##..
- ###.....#...###.#
- #....#.#......#.#
- #..#...###...#..#
- #.#......#.###.#.
- #..#.##..........
- <EMPTY_LINE>
- .##.#.#.##..#.#..
- ...####...##..#..
- ....##...#...##.#
- ..###..#..#..####
- .#...##...#.###..
- ...###.....#...##
- <EMPTY_LINE>
- .#...#.####.#
- ##..#.#....#.
- .#..#...#..#.
- ..#....#.#.#.
- .#...##....#.
- #.###.##..###
- #..#.#....###
- .##..#.#.#...
- .##.#.##..#..
- #...###..##..');
- statement ok
- UPDATE input SET input = replace(input, '<EMPTY_LINE>', '');
- query II
- WITH MUTUALLY RECURSIVE
- blocks(b INT, block TEXT) AS (
- SELECT b, regexp_split_to_array(input, '\n\n')[b] as block
- FROM input, generate_series(1, array_length(regexp_split_to_array(input, '\n\n'), 1)) b
- ),
- lines(b INT, r INT, line TEXT) AS (
- SELECT b, r, regexp_split_to_array(block, '\n')[r] as block
- FROM blocks, generate_series(1, array_length(regexp_split_to_array(block, '\n'), 1)) r
- ),
- cells(b INT, r INT, c INT, symbol TEXT) AS (
- SELECT b, r, c, substring(line, c, 1)
- FROM lines, generate_series(1, length(line)) c
- ),
- columns(b INT, c INT, column TEXT) AS (
- SELECT b, c, string_agg(symbol, '' ORDER BY r) FROM cells GROUP BY b, c
- ),
- row_mirror(b INT, r INT) AS (
- SELECT *
- FROM (SELECT DISTINCT b, r FROM cells) o
- WHERE NOT EXISTS (
- -- We would be upset to find rows at mirrored positions that do not match
- -- Rows that match, or have no mirrored position, are fine.
- SELECT FROM lines
- WHERE o.b = lines.b
- GROUP BY abs(2 * lines.r - (2 * o.r - 1))
- HAVING COUNT(DISTINCT lines.line) > 1
- )
- ),
- col_mirror(b INT, c INT) AS (
- SELECT *
- FROM (SELECT DISTINCT b, c FROM cells) o
- WHERE NOT EXISTS (
- -- We would be upset to find rows at mirrored positions that do not match
- -- Rows that match, or have no mirrored position, are fine.
- SELECT FROM columns
- WHERE o.b = columns.b
- GROUP BY abs(2 * columns.c - (2 * o.c - 1))
- HAVING COUNT(DISTINCT columns.column) > 1
- )
- ),
- part1(part1 BIGINT) AS (
- SELECT COALESCE((SELECT SUM(r-1) FROM row_mirror), 0) * 100
- + COALESCE((SELECT SUM(c-1) FROM col_mirror), 0)
- ),
- row_mirror2(b INT, r INT) AS (
- SELECT *
- FROM (SELECT DISTINCT b, r FROM cells) o
- WHERE 1 = (
- SELECT COUNT(*)
- FROM cells c1, cells c2
- WHERE abs(2 * c1.r - (2 * o.r - 1)) = abs(2 * c2.r - (2 * o.r - 1))
- AND c1.r < c2.r
- AND c1.c = c2.c
- AND c1.b = c2.b
- AND c1.b = o.b
- AND c1.symbol != c2.symbol
- )
- ),
- col_mirror2(b INT, c INT) AS (
- SELECT *
- FROM (SELECT DISTINCT b, c FROM cells) o
- WHERE 1 = (
- SELECT COUNT(*)
- FROM cells c1, cells c2
- WHERE abs(2 * c1.c - (2 * o.c - 1)) = abs(2 * c2.c - (2 * o.c - 1))
- AND c1.c < c2.c
- AND c1.r = c2.r
- AND c1.b = c2.b
- AND c1.b = o.b
- AND c1.symbol != c2.symbol
- )
- ),
- part2(part2 BIGINT) AS (
- SELECT COALESCE((SELECT SUM(r-1) FROM row_mirror2), 0) * 100
- + COALESCE((SELECT SUM(c-1) FROM col_mirror2), 0)
- ),
- potato (x INT) AS ( SELECT 1 )
- SELECT * FROM part1, part2;
- ----
- 100 16
- query T multiline
- EXPLAIN OPTIMIZED PLAN WITH(humanized expressions, arity, join implementations) AS VERBOSE TEXT FOR
- WITH MUTUALLY RECURSIVE
- blocks(b INT, block TEXT) AS (
- SELECT b, regexp_split_to_array(input, '\n\n')[b] as block
- FROM input, generate_series(1, array_length(regexp_split_to_array(input, '\n\n'), 1)) b
- ),
- lines(b INT, r INT, line TEXT) AS (
- SELECT b, r, regexp_split_to_array(block, '\n')[r] as block
- FROM blocks, generate_series(1, array_length(regexp_split_to_array(block, '\n'), 1)) r
- ),
- cells(b INT, r INT, c INT, symbol TEXT) AS (
- SELECT b, r, c, substring(line, c, 1)
- FROM lines, generate_series(1, length(line)) c
- ),
- columns(b INT, c INT, column TEXT) AS (
- SELECT b, c, string_agg(symbol, '' ORDER BY r) FROM cells GROUP BY b, c
- ),
- row_mirror(b INT, r INT) AS (
- SELECT *
- FROM (SELECT DISTINCT b, r FROM cells) o
- WHERE NOT EXISTS (
- -- We would be upset to find rows at mirrored positions that do not match
- -- Rows that match, or have no mirrored position, are fine.
- SELECT FROM lines
- WHERE o.b = lines.b
- GROUP BY abs(2 * lines.r - (2 * o.r - 1))
- HAVING COUNT(DISTINCT lines.line) > 1
- )
- ),
- col_mirror(b INT, c INT) AS (
- SELECT *
- FROM (SELECT DISTINCT b, c FROM cells) o
- WHERE NOT EXISTS (
- -- We would be upset to find rows at mirrored positions that do not match
- -- Rows that match, or have no mirrored position, are fine.
- SELECT FROM columns
- WHERE o.b = columns.b
- GROUP BY abs(2 * columns.c - (2 * o.c - 1))
- HAVING COUNT(DISTINCT columns.column) > 1
- )
- ),
- part1(part1 BIGINT) AS (
- SELECT COALESCE((SELECT SUM(r-1) FROM row_mirror), 0) * 100
- + COALESCE((SELECT SUM(c-1) FROM col_mirror), 0)
- ),
- row_mirror2(b INT, r INT) AS (
- SELECT *
- FROM (SELECT DISTINCT b, r FROM cells) o
- WHERE 1 = (
- SELECT COUNT(*)
- FROM cells c1, cells c2
- WHERE abs(2 * c1.r - (2 * o.r - 1)) = abs(2 * c2.r - (2 * o.r - 1))
- AND c1.r < c2.r
- AND c1.c = c2.c
- AND c1.b = c2.b
- AND c1.b = o.b
- AND c1.symbol != c2.symbol
- )
- ),
- col_mirror2(b INT, c INT) AS (
- SELECT *
- FROM (SELECT DISTINCT b, c FROM cells) o
- WHERE 1 = (
- SELECT COUNT(*)
- FROM cells c1, cells c2
- WHERE abs(2 * c1.c - (2 * o.c - 1)) = abs(2 * c2.c - (2 * o.c - 1))
- AND c1.c < c2.c
- AND c1.r = c2.r
- AND c1.b = c2.b
- AND c1.b = o.b
- AND c1.symbol != c2.symbol
- )
- ),
- part2(part2 BIGINT) AS (
- SELECT COALESCE((SELECT SUM(r-1) FROM row_mirror2), 0) * 100
- + COALESCE((SELECT SUM(c-1) FROM col_mirror2), 0)
- ),
- potato (x INT) AS ( SELECT 1 )
- SELECT * FROM part1, part2;
- ----
- Explained Query:
- With
- cte l0 =
- Project (#0, #2, #3) // { arity: 3 }
- Map (array_index(regexp_split_to_array["\n", case_insensitive=false](#1{block}), integer_to_bigint(#2{r}))) // { arity: 4 }
- FlatMap generate_series(1, (regexp_split_to_array["\n", case_insensitive=false](#1{block}) array_length 1), 1) // { arity: 3 }
- Project (#1, #2) // { arity: 2 }
- Map (array_index(regexp_split_to_array["\n\n", case_insensitive=false](#0{input}), integer_to_bigint(#1{b}))) // { arity: 3 }
- FlatMap generate_series(1, (regexp_split_to_array["\n\n", case_insensitive=false](#0{input}) array_length 1), 1) // { arity: 2 }
- ReadStorage materialize.public.input // { arity: 1 }
- cte l1 =
- Project (#0, #1, #3, #4) // { arity: 4 }
- Map (substr(#2{line}, #3{c}, 1)) // { arity: 5 }
- FlatMap generate_series(1, char_length(#2{line}), 1) // { arity: 4 }
- Get l0 // { arity: 3 }
- cte l2 =
- Distinct project=[#0, #1] // { arity: 2 }
- Project (#0, #1) // { arity: 2 }
- Get l1 // { arity: 4 }
- cte l3 =
- Distinct project=[#0, #1] // { arity: 2 }
- Project (#0, #2) // { arity: 2 }
- Get l1 // { arity: 4 }
- cte l4 =
- ArrangeBy keys=[[#0{b}]] // { arity: 2 }
- Get l2 // { arity: 2 }
- cte l5 =
- Reduce aggregates=[sum((#0{r} - 1))] // { arity: 1 }
- Union // { arity: 1 }
- Negate // { arity: 1 }
- Project (#1) // { arity: 1 }
- Distinct project=[#0, #1] // { arity: 2 }
- Project (#0, #1) // { arity: 2 }
- Filter (#3{count} > 1) // { arity: 4 }
- Reduce group_by=[#0, #1, abs(((2 * #2{r}) - ((2 * #1{r}) - 1)))] aggregates=[count(distinct #3{line})] // { arity: 4 }
- Project (#0, #1, #3, #4) // { arity: 4 }
- Join on=(#0{b} = #2{b}) type=differential // { arity: 5 }
- implementation
- %0:l4[#0{b}]K » %1:l0[#0{b}]K
- Get l4 // { arity: 2 }
- ArrangeBy keys=[[#0{b}]] // { arity: 3 }
- Get l0 // { arity: 3 }
- Project (#1) // { arity: 1 }
- Get l2 // { arity: 2 }
- cte l6 =
- Union // { arity: 1 }
- Get l5 // { arity: 1 }
- Map (null) // { arity: 1 }
- Union // { arity: 0 }
- Negate // { arity: 0 }
- Project () // { arity: 0 }
- Get l5 // { arity: 1 }
- Constant // { arity: 0 }
- - ()
- cte l7 =
- ArrangeBy keys=[[#0{b}]] // { arity: 2 }
- Get l3 // { arity: 2 }
- cte l8 =
- Reduce aggregates=[sum((#0{c} - 1))] // { arity: 1 }
- Union // { arity: 1 }
- Negate // { arity: 1 }
- Project (#1) // { arity: 1 }
- Distinct project=[#0, #1] // { arity: 2 }
- Project (#0, #1) // { arity: 2 }
- Filter (#3{count_string_agg} > 1) // { arity: 4 }
- Reduce group_by=[#0, #1, abs(((2 * #2{c}) - ((2 * #1{c}) - 1)))] aggregates=[count(distinct #3{string_agg})] // { arity: 4 }
- Project (#0, #1, #3, #4{string_agg}) // { arity: 4 }
- Join on=(#0{b} = #2{b}) type=differential // { arity: 5 }
- implementation
- %0:l7[#0{b}]K » %1[#0{b}]K
- Get l7 // { arity: 2 }
- ArrangeBy keys=[[#0{b}]] // { arity: 3 }
- Reduce group_by=[#0, #2] aggregates=[string_agg[order_by=[#0 asc nulls_last]](row(row(#3{symbol}, ""), #1{r}))] // { arity: 3 }
- Get l1 // { arity: 4 }
- Project (#1) // { arity: 1 }
- Get l3 // { arity: 2 }
- cte l9 =
- Union // { arity: 1 }
- Get l8 // { arity: 1 }
- Map (null) // { arity: 1 }
- Union // { arity: 0 }
- Negate // { arity: 0 }
- Project () // { arity: 0 }
- Get l8 // { arity: 1 }
- Constant // { arity: 0 }
- - ()
- cte l10 =
- Reduce aggregates=[sum((#0{r} - 1))] // { arity: 1 }
- Project (#1) // { arity: 1 }
- Filter (#2{count} = 1) // { arity: 3 }
- Reduce group_by=[#0, #1] aggregates=[count(*)] // { arity: 3 }
- Project (#0, #1) // { arity: 2 }
- Filter (#5{symbol} != #9{symbol}) AND (#3{r} < #7{r}) // { arity: 10 }
- Join on=(#0{b} = #2{b} = #6{b} AND #4{c} = #8{c} AND abs(((2 * #3{r}) - ((2 * #1{r}) - 1))) = abs(((2 * #7{r}) - ((2 * #1{r}) - 1)))) type=delta // { arity: 10 }
- implementation
- %0:l4 » %1:l1[#0{b}]K » %2:l1[#0{b}, #2{c}]KK
- %1:l1 » %2:l1[#0{b}, #2{c}]KK » %0:l4[#0{b}]K
- %2:l1 » %1:l1[#0{b}, #2{c}]KK » %0:l4[#0{b}]K
- Get l4 // { arity: 2 }
- ArrangeBy keys=[[#0{b}], [#0{b}, #2{c}]] // { arity: 4 }
- Get l1 // { arity: 4 }
- ArrangeBy keys=[[#0{b}, #2{c}]] // { arity: 4 }
- Get l1 // { arity: 4 }
- cte l11 =
- Union // { arity: 1 }
- Get l10 // { arity: 1 }
- Map (null) // { arity: 1 }
- Union // { arity: 0 }
- Negate // { arity: 0 }
- Project () // { arity: 0 }
- Get l10 // { arity: 1 }
- Constant // { arity: 0 }
- - ()
- cte l12 =
- Reduce aggregates=[sum((#0{c} - 1))] // { arity: 1 }
- Project (#1) // { arity: 1 }
- Filter (#2{count} = 1) // { arity: 3 }
- Reduce group_by=[#0, #1] aggregates=[count(*)] // { arity: 3 }
- Project (#0, #1) // { arity: 2 }
- Filter (#5{symbol} != #9{symbol}) AND (#4{c} < #8{c}) // { arity: 10 }
- Join on=(#0{b} = #2{b} = #6{b} AND #3{r} = #7{r} AND abs(((2 * #4{c}) - ((2 * #1{c}) - 1))) = abs(((2 * #8{c}) - ((2 * #1{c}) - 1)))) type=delta // { arity: 10 }
- implementation
- %0:l7 » %1:l1[#0{b}]K » %2:l1[#0{b}, #1{r}]KK
- %1:l1 » %2:l1[#0{b}, #1{r}]KK » %0:l7[#0{b}]K
- %2:l1 » %1:l1[#0{b}, #1{r}]KK » %0:l7[#0{b}]K
- Get l7 // { arity: 2 }
- ArrangeBy keys=[[#0{b}], [#0{b}, #1{r}]] // { arity: 4 }
- Get l1 // { arity: 4 }
- ArrangeBy keys=[[#0{b}, #1{r}]] // { arity: 4 }
- Get l1 // { arity: 4 }
- cte l13 =
- Union // { arity: 1 }
- Get l12 // { arity: 1 }
- Map (null) // { arity: 1 }
- Union // { arity: 0 }
- Negate // { arity: 0 }
- Project () // { arity: 0 }
- Get l12 // { arity: 1 }
- Constant // { arity: 0 }
- - ()
- Return // { arity: 2 }
- Project (#4, #5) // { arity: 2 }
- Map (((coalesce(#0{sum}, 0) * 100) + coalesce(#1{sum}, 0)), ((coalesce(#2{sum}, 0) * 100) + coalesce(#3{sum}, 0))) // { arity: 6 }
- CrossJoin type=delta // { arity: 4 }
- implementation
- %0 » %1[×]U » %2[×]U » %3[×]U
- %1 » %0[×]U » %2[×]U » %3[×]U
- %2 » %0[×]U » %1[×]U » %3[×]U
- %3 » %0[×]U » %1[×]U » %2[×]U
- ArrangeBy keys=[[]] // { arity: 1 }
- Union // { arity: 1 }
- Get l6 // { arity: 1 }
- Map (null) // { arity: 1 }
- Union // { arity: 0 }
- Negate // { arity: 0 }
- Project () // { arity: 0 }
- Get l6 // { arity: 1 }
- Constant // { arity: 0 }
- - ()
- ArrangeBy keys=[[]] // { arity: 1 }
- Union // { arity: 1 }
- Get l9 // { arity: 1 }
- Map (null) // { arity: 1 }
- Union // { arity: 0 }
- Negate // { arity: 0 }
- Project () // { arity: 0 }
- Get l9 // { arity: 1 }
- Constant // { arity: 0 }
- - ()
- ArrangeBy keys=[[]] // { arity: 1 }
- Union // { arity: 1 }
- Get l11 // { arity: 1 }
- Map (null) // { arity: 1 }
- Union // { arity: 0 }
- Negate // { arity: 0 }
- Project () // { arity: 0 }
- Get l11 // { arity: 1 }
- Constant // { arity: 0 }
- - ()
- ArrangeBy keys=[[]] // { arity: 1 }
- Union // { arity: 1 }
- Get l13 // { arity: 1 }
- Map (null) // { arity: 1 }
- Union // { arity: 0 }
- Negate // { arity: 0 }
- Project () // { arity: 0 }
- Get l13 // { arity: 1 }
- Constant // { arity: 0 }
- - ()
- Source materialize.public.input
- Target cluster: quickstart
- EOF
|