AdventOfCode 2024 Day 14

Part One

p=0,4 v=3,-3
p=6,3 v=-1,-3

设定机器人的起点,和运动矢量,求100秒之后机器人的位置分布情况

比较简单,直接计算100秒后的位置即可

with origin as (
    SELECT row_number() over () as rn, line
    FROM lance_input
), robots as (
    SELECT split_part(p, ',', 1) :: integer as p_x, 
           split_part(p, ',', 2) :: integer as p_y,
           split_part(v, ',', 1) :: integer as v_x,
           split_part(v, ',', 2) :: integer as v_y
    FROM (
        SELECT split_part(split_part(line, ' ', 1), '=', 2) as p, 
               split_part(split_part(line, ' ', 2), '=', 2) as v
        FROM origin
    ) t
), robots_trans as (
    SELECT p_x, p_y,
           CASE WHEN v_x < 0 THEN v_x + 101 ELSE v_x END as v_x,
           CASE WHEN v_y < 0 THEN v_y + 103 ELSE v_y END as v_y
    FROM robots
)
SELECT final_x < 50, final_y < 51, count(*)
FROM (
    SELECT (p_x + 100 * v_x) % 101 as final_x,
           (p_y + 100 * v_y) % 103 as final_y
    FROM robots_trans
) t
WHERE final_x != 50
AND final_y != 51
GROUP BY final_x < 50, final_y < 51;

Part Two

求出多少秒之后,机器人的分布图会包含一棵圣诞树

一开始确实没有什么头绪,先打印出机器人的分布图,用x代表机器人的当前位置,用.代表其他位置

with origin as (
    SELECT row_number() over () as rn, line
    FROM lance_input
), robots as (
    SELECT split_part(p, ',', 1) :: integer as p_x, 
           split_part(p, ',', 2) :: integer as p_y,
           split_part(v, ',', 1) :: integer as v_x,
           split_part(v, ',', 2) :: integer as v_y
    FROM (
        SELECT split_part(split_part(line, ' ', 1), '=', 2) as p, 
               split_part(split_part(line, ' ', 2), '=', 2) as v
        FROM origin
    ) t
), robots_trans as (
    SELECT p_x, p_y,
           CASE WHEN v_x < 0 THEN v_x + 101 ELSE v_x END as v_x,
           CASE WHEN v_y < 0 THEN v_y + 103 ELSE v_y END as v_y
    FROM robots
)
select pos_y, string_agg(case when final_x is not null THEN 'x' ELSE '.' END, '' order by pos_x)
FROM (
    SELECT (p_x + 100 * v_x) % 101 as final_x,
           (p_y + 100 * v_y) % 103 as final_y
    FROM robots_trans
) x 
RIGHT JOIN (
    SELECT x.id as pos_x, y.id as pos_y
    FROM (select generate_series(0, 100, 1) as id) x, (select generate_series(0, 102, 1) as id) y
) y
ON x.final_x = y.pos_x
AND x.final_y = y.pos_y
GROUP BY pos_y order by 1;

显示效果如下

 pos_y |                                               string_agg                                                
-------+---------------------------------------------------------------------------------------------------------
     0 | ..........................x.............x.x.........................x.............x..................
     1 | ................x.......................xx..................x................x..................x....x
     2 | ..........................x..........................................x...........x.........x.........
     3 | .......x...x..........x.............x...............................................................x
     4 | ...........x....................x...................xx...x..........x.x........x.....xx..............
     5 | ............................x.................x..................x...................................
     6 | .....................................x.....................x...x.........................x..........x
     7 | ....................x...............................x..........................x.....x...............
     8 | .....................x...x...........................................................................
     9 | .......................................................x..x...........x..............................
    10 | ..............x.............................x............xx........................x...........x.....
    11 | ................................x..........xxx....................x.................xx...............
    12 | ..........x.........................xx..............................x.................................
    13 | .............................x..........................x....................x.......................

由于需要求出多少秒之后,会出现特殊图案。因此,需要关联1~10000秒,再去搜索哪一秒的结果可能出现

    SELECT row_number() over () as rn, line
    FROM lance_input
), robots as (
    SELECT split_part(p, ',', 1) :: integer as p_x, 
           split_part(p, ',', 2) :: integer as p_y,
           split_part(v, ',', 1) :: integer as v_x,
           split_part(v, ',', 2) :: integer as v_y
    FROM (
        SELECT split_part(split_part(line, ' ', 1), '=', 2) as p, 
               split_part(split_part(line, ' ', 2), '=', 2) as v
        FROM origin
    ) t
), robots_trans as (
    SELECT p_x, p_y,
           CASE WHEN v_x < 0 THEN v_x + 101 ELSE v_x END as v_x,
           CASE WHEN v_y < 0 THEN v_y + 103 ELSE v_y END as v_y
    FROM robots
)
select id, pos_y, string_agg(case when final_x is not null THEN 'x' ELSE '.' END, '' order by pos_x)
FROM (
    SELECT (p_x + id * v_x) % 101 as final_x,
           (p_y + id * v_y) % 103 as final_y, 
           id
    FROM robots_trans, (select generate_series(1, 1, 1) as id) x
) x 
RIGHT JOIN (
    SELECT z.id as id, x.id as pos_x, y.id as pos_y
    FROM (select generate_series(0, 100, 1) as id) x, (select generate_series(0, 102, 1) as id) y,  (select generate_series(1, 10000, 1) as id) z
) y
ON x.final_x = y.pos_x
AND x.final_y = y.pos_y
AND x.id = y.id
GROUP BY id, pos_y

由于包含一棵圣诞树,那么大概率会出现连续的“xxxxx”,因此尝试搜索下

postgres=# select * From lance_test where string_agg like '%xxxxxxx%' limit 10;
  id  | pos_y |                                                 string_agg                                                  
------+-------+-------------------------------------------------------------------------------------------------------------
  156 |    14 | ................x.............................................x.xxxxxxxx................................
 1065 |    55 | ...x......x..............................x...................xxxxxxxx.xxx...x.....x...................
 1264 |    85 | ....x..xx.....x.xxxxxxx..x...xx..xx.xx.x.x..x.........x......x...............x.x....x...x.x..xxx...x..x...
 1267 |     7 | ..........................xx................x.................xxxxxxx..xx..............................
 1573 |    85 | .x......x..x.xx....x....xxxxxxx.x..xx..............x.xx.x....xx......x....x.x..x............x.xx....x..xxx.
 2075 |    77 | ...................................................x......xxxxxxxx.x.x.x...................x..........
 2378 |    29 | .................................................................xxxxxxx..........x....................
 3186 |    90 | ............................................................x.xxxxxxxx..x.x.......x......................
 4903 |   102 | .............................x................x....x.............xxxxxxx.............x..................
 5105 |    64 | .....................................................x..........xxxxxxx............x...................
(10 rows)

postgres=# select * From lance_test where string_agg like '%xxxxxxxxx%' limit 10;
  id  | pos_y |                                              string_agg                                               
------+-------+-------------------------------------------------------------------------------------------------------
 6620 |    53 | x..................................x...............xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx...................
 6620 |    62 | ....................x.....................x........x..........xxxxxxxxx..........x..........x........
 6620 |    65 | ...................................................x..........xxxxxxxxx..........x.....x.x...........
 6620 |    66 | ...................................................x.........xxxxxxxxxxx.........x.............x.....
 6620 |    67 | ..............x....................................x........xxxxxxxxxxxxx........x.................x.
 6620 |    68 | ........x......x...................................x..........xxxxxxxxx..........x...................
 6620 |    69 | ..........x........................x........x......x.........xxxxxxxxxxx.........x...................
 6620 |    70 | ...................................................x........xxxxxxxxxxxxx........x..................x
 6620 |    71 | ..................xx.........................x.....x.......xxxxxxxxxxxxxxx.......x......x............
 6620 |    72 | ............x......x...x........................x..x......xxxxxxxxxxxxxxxxx......x......x............
(10 rows)

果然,在6620秒的结果中,出现了圣诞树,完整的结果如下

 x..................................x...............xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx...................
 ...................................................x.............................x...................
 ...................................................x.............................x...................
 ...................................................x.............................x...................
 .....................................x.x...........x.............................x...................
 ...................................................x..............x..............x...x...............
 x..................................................x.............xxx.............x...................
 ....................x..............................x............xxxxx............x...................
 ...................................................x...........xxxxxxx...........x.x....x............
 ....................x.....................x........x..........xxxxxxxxx..........x..........x........
 ............................x......................x............xxxxx............x...................
 ...................................................x...........xxxxxxx...........x........x..........
 ...................................................x..........xxxxxxxxx..........x.....x.x...........
 ...................................................x.........xxxxxxxxxxx.........x.............x.....
 ..............x....................................x........xxxxxxxxxxxxx........x.................x.
 ........x......x...................................x..........xxxxxxxxx..........x...................
 ..........x........................x........x......x.........xxxxxxxxxxx.........x...................
 ...................................................x........xxxxxxxxxxxxx........x..................x
 ..................xx.........................x.....x.......xxxxxxxxxxxxxxx.......x......x............
 ............x......x...x........................x..x......xxxxxxxxxxxxxxxxx......x......x............
 ...................................................x........xxxxxxxxxxxxx........x...................
 ...................................................x.......xxxxxxxxxxxxxxx.......x...................
 ...................................................x......xxxxxxxxxxxxxxxxx......x.x.................
 .................................................x.x.....xxxxxxxxxxxxxxxxxxx.....x...................
 ...................................xx.....x........x....xxxxxxxxxxxxxxxxxxxxx....x...................
 ...................................................x.............xxx.............x...................
 ...x.......x.......................................x.............xxx.............x...................
 ...................................................x.............xxx.............x...................
 ...................................................x.............................x...................
 ...................................................x.............................x...................
 ...................................................x.............................x...................
 .................................................x.x.............................x...................
 ...........................................x.......xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx..............x....
 .....................................................................................x...............
 ..........................x..........................................................................

发表评论