Compare commits
47 Commits
dfe2207e8e
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| ad6a39e82a | |||
| 3a857e4d53 | |||
| f80a051177 | |||
| 129fa07787 | |||
| 1472082c86 | |||
| e8bed49e13 | |||
| 83d70dcc7a | |||
| 56d2e63fac | |||
| 5c91de5d40 | |||
| 40a9c7b12e | |||
| 34b6cd7b57 | |||
| 5ad5c87fd8 | |||
| 11e7b45676 | |||
| 3f2a5648df | |||
| 0a3b404c4c | |||
| a214d2b70d | |||
| f490c2353e | |||
| 2ed6284bcd | |||
| 5fc204744a | |||
| d1cf8d96b8 | |||
| b285f74997 | |||
| c949c64da2 | |||
| 357e8ce087 | |||
| 5cde9051ec | |||
| 111fde4fbd | |||
| f54479189b | |||
| 8e00fec33c | |||
| d0376f21c3 | |||
| 04a856dc47 | |||
| 0658ffdd7d | |||
| efe0dec8f0 | |||
| 6d4a8dd85b | |||
| 11cb3c5c64 | |||
| 7e0a21704e | |||
| 008599e79c | |||
| fe381ae7f0 | |||
| 4a0749999e | |||
| 18720b9e09 | |||
| 17e140f235 | |||
| a1e436babc | |||
| 02a1dda786 | |||
| ef29ca28a1 | |||
| c1b3e83c68 | |||
| bd2548fca9 | |||
| 3f5b282883 | |||
| 38ef781f0a | |||
| 13d183de79 |
142
2022/RESULTS.txt
142
2022/RESULTS.txt
@@ -173,3 +173,145 @@ aoc.bash: res=672280
|
||||
aoc-c: res=672280
|
||||
time: 0:00.00 real, 0.00 user, 0.00 sys
|
||||
context-switch: 0+1, page-faults: 0+91
|
||||
|
||||
=========================================
|
||||
================= day09 =================
|
||||
=========================================
|
||||
|
||||
+++++++++++++++++ part 1
|
||||
aoc.bash: res=5619
|
||||
time: 0:00.69 real, 0.69 user, 0.00 sys
|
||||
context-switch: 38+1, page-faults: 0+430
|
||||
|
||||
aoc-c: res=5619
|
||||
time: 0:00.00 real, 0.00 user, 0.00 sys
|
||||
context-switch: 0+1, page-faults: 0+158
|
||||
|
||||
+++++++++++++++++ part 2
|
||||
aoc.bash: res=2376
|
||||
time: 0:03.25 real, 3.24 user, 0.00 sys
|
||||
context-switch: 46+1, page-faults: 0+340
|
||||
|
||||
aoc-c: res=2376
|
||||
time: 0:00.00 real, 0.00 user, 0.00 sys
|
||||
context-switch: 0+1, page-faults: 0+131
|
||||
|
||||
=========================================
|
||||
================= day10 =================
|
||||
=========================================
|
||||
|
||||
+++++++++++++++++ part 1
|
||||
aoc.bash: res=13220
|
||||
time: 0:00.00 real, 0.00 user, 0.00 sys
|
||||
context-switch: 0+1, page-faults: 0+260
|
||||
|
||||
aoc-c: res=13220
|
||||
time: 0:00.00 real, 0.00 user, 0.00 sys
|
||||
context-switch: 0+1, page-faults: 0+88
|
||||
|
||||
+++++++++++++++++ part 2
|
||||
aoc.bash: res=
|
||||
###..#..#..##..#..#.#..#.###..####.#..##
|
||||
#..#.#..#.#..#.#.#..#..#.#..#.#....#.#..
|
||||
#..#.#..#.#..#.##...####.###..###..##..#
|
||||
###..#..#.####.#.#..#..#.#..#.#....#.#.#
|
||||
#.#..#..#.#..#.#.#..#..#.#..#.#....#.#..
|
||||
#..#..##..#..#.#..#.#..#.###..####.#..#.
|
||||
time: 0:00.01 real, 0.00 user, 0.00 sys
|
||||
context-switch: 3+1, page-faults: 0+262
|
||||
|
||||
###..#..#..##..#..#.#..#.###..####.#..##
|
||||
#..#.#..#.#..#.#.#..#..#.#..#.#....#.#..
|
||||
#..#.#..#.#..#.##...####.###..###..##..#
|
||||
###..#..#.####.#.#..#..#.#..#.#....#.#.#
|
||||
#.#..#..#.#..#.#.#..#..#.#..#.#....#.#..
|
||||
#..#..##..#..#.#..#.#..#.###..####.#..#.
|
||||
aoc-c: res=0
|
||||
time: 0:00.00 real, 0.00 user, 0.00 sys
|
||||
context-switch: 0+1, page-faults: 0+88
|
||||
|
||||
=========================================
|
||||
================= day11 =================
|
||||
=========================================
|
||||
|
||||
+++++++++++++++++ part 1
|
||||
aoc.bash: res=54253
|
||||
time: 0:00.05 real, 0.04 user, 0.00 sys
|
||||
context-switch: 1+1, page-faults: 0+268
|
||||
|
||||
aoc-c: res=54253
|
||||
time: 0:00.00 real, 0.00 user, 0.00 sys
|
||||
context-switch: 0+1, page-faults: 0+87
|
||||
|
||||
+++++++++++++++++ part 2
|
||||
aoc.bash: res=13119526120
|
||||
time: 0:16.49 real, 16.48 user, 0.00 sys
|
||||
context-switch: 106+1, page-faults: 0+270
|
||||
|
||||
aoc-c: res=13119526120
|
||||
time: 0:00.01 real, 0.01 user, 0.00 sys
|
||||
context-switch: 13+1, page-faults: 0+87
|
||||
|
||||
=========================================
|
||||
================= day12 =================
|
||||
=========================================
|
||||
|
||||
+++++++++++++++++ part 1
|
||||
aoc.bash: res=408
|
||||
time: 0:00.81 real, 0.80 user, 0.00 sys
|
||||
context-switch: 223+1, page-faults: 0+486
|
||||
|
||||
aoc-c: res=408
|
||||
time: 0:00.00 real, 0.00 user, 0.00 sys
|
||||
context-switch: 0+1, page-faults: 0+170
|
||||
|
||||
+++++++++++++++++ part 2
|
||||
aoc.bash: res=399
|
||||
time: 0:00.55 real, 0.54 user, 0.01 sys
|
||||
context-switch: 25+1, page-faults: 0+460
|
||||
|
||||
aoc-c: res=399
|
||||
time: 0:00.00 real, 0.00 user, 0.00 sys
|
||||
context-switch: 0+1, page-faults: 0+171
|
||||
|
||||
=========================================
|
||||
================= day13 =================
|
||||
=========================================
|
||||
|
||||
+++++++++++++++++ part 1
|
||||
aoc-c: res=5843
|
||||
time: 0:00.00 real, 0.00 user, 0.00 sys
|
||||
context-switch: 0+1, page-faults: 0+192
|
||||
|
||||
+++++++++++++++++ part 2
|
||||
aoc-c: res=26289
|
||||
time: 0:00.00 real, 0.00 user, 0.00 sys
|
||||
context-switch: 1+1, page-faults: 0+190
|
||||
|
||||
=========================================
|
||||
================= day14 =================
|
||||
=========================================
|
||||
|
||||
+++++++++++++++++ part 1
|
||||
aoc-c: res=665
|
||||
time: 0:00.00 real, 0.00 user, 0.00 sys
|
||||
context-switch: 0+1, page-faults: 0+109
|
||||
|
||||
+++++++++++++++++ part 2
|
||||
aoc-c: res=25434
|
||||
time: 0:00.00 real, 0.00 user, 0.00 sys
|
||||
context-switch: 0+1, page-faults: 0+121
|
||||
|
||||
=========================================
|
||||
================= day15 =================
|
||||
=========================================
|
||||
|
||||
+++++++++++++++++ part 1
|
||||
aoc-c: res=5176944
|
||||
time: 0:00.00 real, 0.00 user, 0.00 sys
|
||||
context-switch: 0+1, page-faults: 0+152
|
||||
|
||||
+++++++++++++++++ part 2
|
||||
aoc-c: res=13350458933732
|
||||
time: 0:00.00 real, 0.00 user, 0.00 sys
|
||||
context-switch: 0+1, page-faults: 0+88
|
||||
|
||||
@@ -283,3 +283,465 @@ So, there are =13= positions the tail visited at least once.
|
||||
|
||||
Simulate your complete hypothetical series of motions. /How many
|
||||
positions does the tail of the rope visit at least once?/
|
||||
|
||||
Your puzzle answer was =5619=.
|
||||
|
||||
** --- Part Two ---
|
||||
A rope snaps! Suddenly, the river is getting a lot closer than you
|
||||
remember. The bridge is still there, but some of the ropes that broke
|
||||
are now whipping toward you as you fall through the air!
|
||||
|
||||
The ropes are moving too quickly to grab; you only have a few seconds to
|
||||
choose how to arch your body to avoid being hit. Fortunately, your
|
||||
simulation can be extended to support longer ropes.
|
||||
|
||||
Rather than two knots, you now must simulate a rope consisting of /ten/
|
||||
knots. One knot is still the head of the rope and moves according to the
|
||||
series of motions. Each knot further down the rope follows the knot in
|
||||
front of it using the same rules as before.
|
||||
|
||||
Using the same series of motions as the above example, but with the
|
||||
knots marked =H=, =1=, =2=, ..., =9=, the motions now occur as follows:
|
||||
|
||||
#+begin_example
|
||||
== Initial State ==
|
||||
|
||||
......
|
||||
......
|
||||
......
|
||||
......
|
||||
H..... (H covers 1, 2, 3, 4, 5, 6, 7, 8, 9, s)
|
||||
|
||||
== R 4 ==
|
||||
|
||||
......
|
||||
......
|
||||
......
|
||||
......
|
||||
1H.... (1 covers 2, 3, 4, 5, 6, 7, 8, 9, s)
|
||||
|
||||
......
|
||||
......
|
||||
......
|
||||
......
|
||||
21H... (2 covers 3, 4, 5, 6, 7, 8, 9, s)
|
||||
|
||||
......
|
||||
......
|
||||
......
|
||||
......
|
||||
321H.. (3 covers 4, 5, 6, 7, 8, 9, s)
|
||||
|
||||
......
|
||||
......
|
||||
......
|
||||
......
|
||||
4321H. (4 covers 5, 6, 7, 8, 9, s)
|
||||
|
||||
== U 4 ==
|
||||
|
||||
......
|
||||
......
|
||||
......
|
||||
....H.
|
||||
4321.. (4 covers 5, 6, 7, 8, 9, s)
|
||||
|
||||
......
|
||||
......
|
||||
....H.
|
||||
.4321.
|
||||
5..... (5 covers 6, 7, 8, 9, s)
|
||||
|
||||
......
|
||||
....H.
|
||||
....1.
|
||||
.432..
|
||||
5..... (5 covers 6, 7, 8, 9, s)
|
||||
|
||||
....H.
|
||||
....1.
|
||||
..432.
|
||||
.5....
|
||||
6..... (6 covers 7, 8, 9, s)
|
||||
|
||||
== L 3 ==
|
||||
|
||||
...H..
|
||||
....1.
|
||||
..432.
|
||||
.5....
|
||||
6..... (6 covers 7, 8, 9, s)
|
||||
|
||||
..H1..
|
||||
...2..
|
||||
..43..
|
||||
.5....
|
||||
6..... (6 covers 7, 8, 9, s)
|
||||
|
||||
.H1...
|
||||
...2..
|
||||
..43..
|
||||
.5....
|
||||
6..... (6 covers 7, 8, 9, s)
|
||||
|
||||
== D 1 ==
|
||||
|
||||
..1...
|
||||
.H.2..
|
||||
..43..
|
||||
.5....
|
||||
6..... (6 covers 7, 8, 9, s)
|
||||
|
||||
== R 4 ==
|
||||
|
||||
..1...
|
||||
..H2..
|
||||
..43..
|
||||
.5....
|
||||
6..... (6 covers 7, 8, 9, s)
|
||||
|
||||
..1...
|
||||
...H.. (H covers 2)
|
||||
..43..
|
||||
.5....
|
||||
6..... (6 covers 7, 8, 9, s)
|
||||
|
||||
......
|
||||
...1H. (1 covers 2)
|
||||
..43..
|
||||
.5....
|
||||
6..... (6 covers 7, 8, 9, s)
|
||||
|
||||
......
|
||||
...21H
|
||||
..43..
|
||||
.5....
|
||||
6..... (6 covers 7, 8, 9, s)
|
||||
|
||||
== D 1 ==
|
||||
|
||||
......
|
||||
...21.
|
||||
..43.H
|
||||
.5....
|
||||
6..... (6 covers 7, 8, 9, s)
|
||||
|
||||
== L 5 ==
|
||||
|
||||
......
|
||||
...21.
|
||||
..43H.
|
||||
.5....
|
||||
6..... (6 covers 7, 8, 9, s)
|
||||
|
||||
......
|
||||
...21.
|
||||
..4H.. (H covers 3)
|
||||
.5....
|
||||
6..... (6 covers 7, 8, 9, s)
|
||||
|
||||
......
|
||||
...2..
|
||||
..H1.. (H covers 4; 1 covers 3)
|
||||
.5....
|
||||
6..... (6 covers 7, 8, 9, s)
|
||||
|
||||
......
|
||||
...2..
|
||||
.H13.. (1 covers 4)
|
||||
.5....
|
||||
6..... (6 covers 7, 8, 9, s)
|
||||
|
||||
......
|
||||
......
|
||||
H123.. (2 covers 4)
|
||||
.5....
|
||||
6..... (6 covers 7, 8, 9, s)
|
||||
|
||||
== R 2 ==
|
||||
|
||||
......
|
||||
......
|
||||
.H23.. (H covers 1; 2 covers 4)
|
||||
.5....
|
||||
6..... (6 covers 7, 8, 9, s)
|
||||
|
||||
......
|
||||
......
|
||||
.1H3.. (H covers 2, 4)
|
||||
.5....
|
||||
6..... (6 covers 7, 8, 9, s)
|
||||
#+end_example
|
||||
|
||||
Now, you need to keep track of the positions the new tail, =9=, visits.
|
||||
In this example, the tail never moves, and so it only visits =1=
|
||||
position. However, /be careful/: more types of motion are possible than
|
||||
before, so you might want to visually compare your simulated rope to the
|
||||
one above.
|
||||
|
||||
Here's a larger example:
|
||||
|
||||
#+begin_example
|
||||
R 5
|
||||
U 8
|
||||
L 8
|
||||
D 3
|
||||
R 17
|
||||
D 10
|
||||
L 25
|
||||
U 20
|
||||
#+end_example
|
||||
|
||||
These motions occur as follows (individual steps are not shown):
|
||||
|
||||
#+begin_example
|
||||
== Initial State ==
|
||||
|
||||
..........................
|
||||
..........................
|
||||
..........................
|
||||
..........................
|
||||
..........................
|
||||
..........................
|
||||
..........................
|
||||
..........................
|
||||
..........................
|
||||
..........................
|
||||
..........................
|
||||
..........................
|
||||
..........................
|
||||
..........................
|
||||
..........................
|
||||
...........H.............. (H covers 1, 2, 3, 4, 5, 6, 7, 8, 9, s)
|
||||
..........................
|
||||
..........................
|
||||
..........................
|
||||
..........................
|
||||
..........................
|
||||
|
||||
== R 5 ==
|
||||
|
||||
..........................
|
||||
..........................
|
||||
..........................
|
||||
..........................
|
||||
..........................
|
||||
..........................
|
||||
..........................
|
||||
..........................
|
||||
..........................
|
||||
..........................
|
||||
..........................
|
||||
..........................
|
||||
..........................
|
||||
..........................
|
||||
..........................
|
||||
...........54321H......... (5 covers 6, 7, 8, 9, s)
|
||||
..........................
|
||||
..........................
|
||||
..........................
|
||||
..........................
|
||||
..........................
|
||||
|
||||
== U 8 ==
|
||||
|
||||
..........................
|
||||
..........................
|
||||
..........................
|
||||
..........................
|
||||
..........................
|
||||
..........................
|
||||
..........................
|
||||
................H.........
|
||||
................1.........
|
||||
................2.........
|
||||
................3.........
|
||||
...............54.........
|
||||
..............6...........
|
||||
.............7............
|
||||
............8.............
|
||||
...........9.............. (9 covers s)
|
||||
..........................
|
||||
..........................
|
||||
..........................
|
||||
..........................
|
||||
..........................
|
||||
|
||||
== L 8 ==
|
||||
|
||||
..........................
|
||||
..........................
|
||||
..........................
|
||||
..........................
|
||||
..........................
|
||||
..........................
|
||||
..........................
|
||||
........H1234.............
|
||||
............5.............
|
||||
............6.............
|
||||
............7.............
|
||||
............8.............
|
||||
............9.............
|
||||
..........................
|
||||
..........................
|
||||
...........s..............
|
||||
..........................
|
||||
..........................
|
||||
..........................
|
||||
..........................
|
||||
..........................
|
||||
|
||||
== D 3 ==
|
||||
|
||||
..........................
|
||||
..........................
|
||||
..........................
|
||||
..........................
|
||||
..........................
|
||||
..........................
|
||||
..........................
|
||||
..........................
|
||||
.........2345.............
|
||||
........1...6.............
|
||||
........H...7.............
|
||||
............8.............
|
||||
............9.............
|
||||
..........................
|
||||
..........................
|
||||
...........s..............
|
||||
..........................
|
||||
..........................
|
||||
..........................
|
||||
..........................
|
||||
..........................
|
||||
|
||||
== R 17 ==
|
||||
|
||||
..........................
|
||||
..........................
|
||||
..........................
|
||||
..........................
|
||||
..........................
|
||||
..........................
|
||||
..........................
|
||||
..........................
|
||||
..........................
|
||||
..........................
|
||||
................987654321H
|
||||
..........................
|
||||
..........................
|
||||
..........................
|
||||
..........................
|
||||
...........s..............
|
||||
..........................
|
||||
..........................
|
||||
..........................
|
||||
..........................
|
||||
..........................
|
||||
|
||||
== D 10 ==
|
||||
|
||||
..........................
|
||||
..........................
|
||||
..........................
|
||||
..........................
|
||||
..........................
|
||||
..........................
|
||||
..........................
|
||||
..........................
|
||||
..........................
|
||||
..........................
|
||||
..........................
|
||||
..........................
|
||||
..........................
|
||||
..........................
|
||||
..........................
|
||||
...........s.........98765
|
||||
.........................4
|
||||
.........................3
|
||||
.........................2
|
||||
.........................1
|
||||
.........................H
|
||||
|
||||
== L 25 ==
|
||||
|
||||
..........................
|
||||
..........................
|
||||
..........................
|
||||
..........................
|
||||
..........................
|
||||
..........................
|
||||
..........................
|
||||
..........................
|
||||
..........................
|
||||
..........................
|
||||
..........................
|
||||
..........................
|
||||
..........................
|
||||
..........................
|
||||
..........................
|
||||
...........s..............
|
||||
..........................
|
||||
..........................
|
||||
..........................
|
||||
..........................
|
||||
H123456789................
|
||||
|
||||
== U 20 ==
|
||||
|
||||
H.........................
|
||||
1.........................
|
||||
2.........................
|
||||
3.........................
|
||||
4.........................
|
||||
5.........................
|
||||
6.........................
|
||||
7.........................
|
||||
8.........................
|
||||
9.........................
|
||||
..........................
|
||||
..........................
|
||||
..........................
|
||||
..........................
|
||||
..........................
|
||||
...........s..............
|
||||
..........................
|
||||
..........................
|
||||
..........................
|
||||
..........................
|
||||
..........................
|
||||
#+end_example
|
||||
|
||||
Now, the tail (=9=) visits =36= positions (including =s=) at least once:
|
||||
|
||||
#+begin_example
|
||||
..........................
|
||||
..........................
|
||||
..........................
|
||||
..........................
|
||||
..........................
|
||||
..........................
|
||||
..........................
|
||||
..........................
|
||||
..........................
|
||||
#.........................
|
||||
#.............###.........
|
||||
#............#...#........
|
||||
.#..........#.....#.......
|
||||
..#..........#.....#......
|
||||
...#........#.......#.....
|
||||
....#......s.........#....
|
||||
.....#..............#.....
|
||||
......#............#......
|
||||
.......#..........#.......
|
||||
........#........#........
|
||||
.........########.........
|
||||
#+end_example
|
||||
|
||||
Simulate your complete series of motions on a larger rope with ten
|
||||
knots. /How many positions does the tail of the rope visit at least
|
||||
once?/
|
||||
|
||||
Your puzzle answer was =2376=.
|
||||
|
||||
Both parts of this puzzle are complete! They provide two gold stars: **
|
||||
|
||||
200
2022/day09/aoc-c.c
Normal file
200
2022/day09/aoc-c.c
Normal file
@@ -0,0 +1,200 @@
|
||||
/* aoc-c.c: Advent of Code 2022, day 9
|
||||
*
|
||||
* Copyright (C) 2022 Bruno Raoult ("br")
|
||||
* Licensed under the GNU General Public License v3.0 or later.
|
||||
* Some rights reserved. See COPYING.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with this
|
||||
* program. If not, see <https://www.gnu.org/licenses/gpl-3.0-standalone.html>.
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later <https://spdx.org/licenses/GPL-3.0-or-later.html>
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "aoc.h"
|
||||
|
||||
#include "br.h"
|
||||
#include "debug.h"
|
||||
#include "pool.h"
|
||||
#include "list.h"
|
||||
#include "hashtable.h"
|
||||
#include "pjwhash-inline.h"
|
||||
|
||||
#define HBITS 12 /* 12 bits: 4096 buckets */
|
||||
|
||||
typedef struct pos {
|
||||
int x;
|
||||
int y;
|
||||
} pos_t;
|
||||
|
||||
typedef struct visited {
|
||||
uint hash;
|
||||
pos_t coord;
|
||||
short nvisits;
|
||||
struct hlist_node hlist;
|
||||
} visited_t;
|
||||
|
||||
enum dir {
|
||||
D = 'D',
|
||||
L = 'L',
|
||||
R = 'R',
|
||||
U = 'U'
|
||||
};
|
||||
|
||||
typedef struct move {
|
||||
enum dir dir;
|
||||
int nmoves;
|
||||
struct list_head list;
|
||||
} move_t;
|
||||
|
||||
DEFINE_HASHTABLE(h_visited, HBITS);
|
||||
LIST_HEAD(moves);
|
||||
|
||||
static pool_t *pool_visited;
|
||||
static pool_t *pool_move;
|
||||
|
||||
/**
|
||||
* find_visited - find entry in an hashtable bucket
|
||||
*/
|
||||
static visited_t *find_visited(struct hlist_head *bucket, uint hash, pos_t *pos)
|
||||
{
|
||||
visited_t *cur;
|
||||
|
||||
hlist_for_each_entry(cur, bucket, hlist)
|
||||
if (cur->hash == hash && cur->coord.x == pos->x && cur->coord.y == pos->y)
|
||||
return cur;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
static visited_t *add_visited(pos_t *pos, uint hash, uint bucket)
|
||||
{
|
||||
visited_t *new = pool_get(pool_visited);
|
||||
|
||||
new->hash = hash;
|
||||
new->coord.x = pos->x;
|
||||
new->coord.y = pos->y;
|
||||
hlist_add_head(&new->hlist, &h_visited[bucket]);
|
||||
return new;
|
||||
}
|
||||
|
||||
static int add_visited_maybe(pos_t *pos)
|
||||
{
|
||||
uint hash = pjwhash(pos, sizeof (*pos));
|
||||
uint bucket = hash_32(hash, HBITS);
|
||||
if (! find_visited(h_visited + bucket, hash, pos)) {
|
||||
add_visited(pos, hash, bucket);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int move_tails(pos_t *pos, int ntails)
|
||||
{
|
||||
int i;
|
||||
pos_t *cur, *next;
|
||||
int didmove = 1;
|
||||
|
||||
for (i = 0; i < ntails && didmove; ++i) {
|
||||
didmove = 0;
|
||||
pos_t diff;
|
||||
cur = pos + i;
|
||||
next = cur + 1;
|
||||
diff.x = cur->x - next->x;
|
||||
diff.y = cur->y - next->y;
|
||||
if (abs(diff.x) > 1 || abs(diff.y) > 1) { /* do move */
|
||||
if (diff.x)
|
||||
next->x += diff.x / abs(diff.x);
|
||||
if (diff.y)
|
||||
next->y += diff.y / abs(diff.y);
|
||||
didmove = 1;
|
||||
}
|
||||
}
|
||||
return didmove? add_visited_maybe(pos+ntails): 0;
|
||||
}
|
||||
|
||||
static void move_head(pos_t *pos, move_t *move)
|
||||
{
|
||||
log_f(3, "(%d,%d,%c) -> ", pos->x, pos->y, move->dir);
|
||||
switch (move->dir) {
|
||||
case U:
|
||||
pos->y++;
|
||||
break;
|
||||
case R:
|
||||
pos->x++;
|
||||
break;
|
||||
case D:
|
||||
pos->y--;
|
||||
break;
|
||||
case L:
|
||||
pos->x--;
|
||||
break;
|
||||
default:
|
||||
log(3, "ERR=%x ", move->dir);
|
||||
}
|
||||
log_f(3, "(%d,%d)\n", pos->x, pos->y);
|
||||
}
|
||||
|
||||
static pos_t *part1(int *ntails)
|
||||
{
|
||||
static pos_t nodes[] = { [0 ... 1] = {.x = 0, .y = 0}};
|
||||
*ntails = ARRAY_SIZE(nodes) - 1;
|
||||
return nodes;
|
||||
}
|
||||
|
||||
static pos_t *part2(int *ntails)
|
||||
{
|
||||
static pos_t nodes[] = { [0 ... 9] = {.x = 0, .y = 0}};
|
||||
*ntails = ARRAY_SIZE(nodes) - 1;
|
||||
return nodes;
|
||||
}
|
||||
|
||||
static int solve(int part)
|
||||
{
|
||||
int ntails;
|
||||
pos_t *nodes = part == 1? part1(&ntails): part2(&ntails);
|
||||
move_t *move;
|
||||
int res = 1; /* for (0,0) */
|
||||
|
||||
add_visited_maybe( &(pos_t) {0, 0});
|
||||
list_for_each_entry(move, &moves, list) {
|
||||
for (int i = 0; i < move->nmoves; ++i) {
|
||||
move_head(nodes, move);
|
||||
res += move_tails(nodes, ntails);
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
static int parse()
|
||||
{
|
||||
char dir;
|
||||
int nmoves;
|
||||
int count = 0;
|
||||
move_t *move;
|
||||
|
||||
while (scanf(" %c %d", &dir, &nmoves) == 2) {
|
||||
move = pool_get(pool_move);
|
||||
move->dir = dir;
|
||||
move->nmoves = nmoves;
|
||||
list_add_tail(&move->list, &moves);
|
||||
count++;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
int main(int ac, char **av)
|
||||
{
|
||||
int part = parseargs(ac, av);
|
||||
pool_visited = pool_create("visited", 128, sizeof(visited_t));
|
||||
pool_move = pool_create("dirs", 128, sizeof(move_t));
|
||||
|
||||
parse();
|
||||
printf("%s: res=%d\n", *av, solve(part));
|
||||
pool_destroy(pool_visited);
|
||||
pool_destroy(pool_move);
|
||||
exit(0);
|
||||
}
|
||||
63
2022/day09/aoc.bash
Executable file
63
2022/day09/aoc.bash
Executable file
@@ -0,0 +1,63 @@
|
||||
#!/usr/bin/env bash
|
||||
#
|
||||
# aoc.bash: Advent of Code 2022, day 9
|
||||
#
|
||||
# Copyright (C) 2022 Bruno Raoult ("br")
|
||||
# Licensed under the GNU General Public License v3.0 or later.
|
||||
# Some rights reserved. See COPYING.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License along with this
|
||||
# program. If not, see <https://www.gnu.org/licenses/gpl-3.0-standalone.html>.
|
||||
#
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later <https://spdx.org/licenses/GPL-3.0-or-later.html>
|
||||
|
||||
. common.bash
|
||||
|
||||
declare -a h{0..10} # h0 is head
|
||||
declare -A visited=() # keep count of visited
|
||||
declare -i last=1 # tail (last knot)
|
||||
|
||||
move() {
|
||||
local -i _dx="$1" _dy="$2" _m="$3" _i _n
|
||||
local -i __dx __dy __sx __sy
|
||||
local -n _l="h$last"
|
||||
|
||||
for ((_i = 0; _i < _m; ++_i)); do # for each move
|
||||
(( h0[0] += _dx, h0[1] += _dy )) # head move
|
||||
for (( _n = 0; _n < last; ++_n )); do # for each other node
|
||||
local -n _h="h$_n" _t="h$((_n+1))"
|
||||
(( __dx = _h[0] - _t[0], __dy = _h[1] - _t[1] ))
|
||||
(( __sx = __dx? __dx > 0? 1: -1 : 0 ))
|
||||
(( __sy = __dy? __dy > 0? 1: -1 : 0 ))
|
||||
if (( __sx * __dx > 1 || __sy * __dy > 1)); then
|
||||
(( _t[0] += __sx ))
|
||||
(( _t[1] += __sy ))
|
||||
fi
|
||||
done
|
||||
visited["${_l[0]}"/"${_l[1]}"]=1
|
||||
done
|
||||
}
|
||||
|
||||
parse() {
|
||||
local dir moves dx dy
|
||||
|
||||
(( $1 == 2)) && last=9
|
||||
while read -r dir moves; do
|
||||
dx=0
|
||||
dy=0
|
||||
case "$dir" in
|
||||
L) dx=-1 ;;
|
||||
R) dx=1 ;;
|
||||
U) dy=1 ;;
|
||||
D) dy=-1 ;;
|
||||
esac
|
||||
move "$dx" "$dy" "$moves"
|
||||
done
|
||||
}
|
||||
|
||||
solve() {
|
||||
res=${#visited[@]}
|
||||
}
|
||||
|
||||
main "$@"
|
||||
exit 0
|
||||
8
2022/day09/input/example2.txt
Normal file
8
2022/day09/input/example2.txt
Normal file
@@ -0,0 +1,8 @@
|
||||
R 5
|
||||
U 8
|
||||
L 8
|
||||
D 3
|
||||
R 17
|
||||
D 10
|
||||
L 25
|
||||
U 20
|
||||
111
2022/day10/Makefile
Normal file
111
2022/day10/Makefile
Normal file
@@ -0,0 +1,111 @@
|
||||
# AOC daily Makefile - GNU make only.
|
||||
#
|
||||
# Copyright (C) 2021-2022 Bruno Raoult ("br")
|
||||
# Licensed under the GNU General Public License v3.0 or later.
|
||||
# Some rights reserved. See COPYING.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License along with this
|
||||
# program. If not, see <https://www.gnu.org/licenses/gpl-3.0-standalone.html>.
|
||||
#
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later <https://spdx.org/licenses/GPL-3.0-or-later.html>
|
||||
#
|
||||
|
||||
INPUT := input/input.txt
|
||||
SHELL := /bin/bash
|
||||
|
||||
CC := gcc
|
||||
BEAR := bear
|
||||
CCLSFILE:= compile_commands.json
|
||||
|
||||
LIB := aoc_$(shell uname -m)
|
||||
INCDIR := ../include
|
||||
LIBDIR := ../lib
|
||||
LDFLAGS := -L$(LIBDIR)
|
||||
#LDLIB := -l$(LIB) -lm
|
||||
LDLIB := -l$(LIB)
|
||||
|
||||
export LD_LIBRARY_PATH = $(LIBDIR)
|
||||
|
||||
CFLAGS += -std=gnu11
|
||||
CFLAGS += -O2
|
||||
CFLAGS += -g
|
||||
# for gprof
|
||||
# CFLAGS += -pg
|
||||
CFLAGS += -Wall
|
||||
CFLAGS += -Wextra
|
||||
CFLAGS += -march=native
|
||||
# Next one may be useful for valgrind (some invalid instructions)
|
||||
# CFLAGS += -mno-tbm
|
||||
CFLAGS += -Wmissing-declarations
|
||||
CFLAGS += -Wno-unused-result
|
||||
|
||||
CFLAGS += -DDEBUG_DEBUG # activate general debug (debug.c)
|
||||
CFLAGS += -DDEBUG_POOL # memory pools management
|
||||
|
||||
VALGRIND := valgrind
|
||||
VALGRINDFLAGS := --leak-check=full --show-leak-kinds=all --track-origins=yes \
|
||||
--sigill-diagnostics=yes --quiet --show-error-list=yes
|
||||
|
||||
|
||||
TIME := \time -f "\ttime: %E real, %U user, %S sys\n\tcontext-switch:\t%c+%w, page-faults: %F+%R\n"
|
||||
export PATH := .:$(PATH)
|
||||
|
||||
.PHONY: clean all compile assembly memcheck memcheck1 memcheck2 part1 part2 ccls bear org
|
||||
|
||||
all: README.org ccls part1 part2
|
||||
|
||||
memcheck: memcheck1 memcheck2
|
||||
|
||||
memcheck1: aoc-c
|
||||
@$(VALGRIND) $(VALGRINDFLAGS) aoc-c -p 1 < $(INPUT)
|
||||
|
||||
memcheck2: aoc-c
|
||||
@$(VALGRIND) $(VALGRINDFLAGS) aoc-c -p 2 < $(INPUT)
|
||||
@#@valgrind -s --track-origins=yes aoc-c -p 2 < $(INPUT)
|
||||
|
||||
compile: aoc-c
|
||||
|
||||
cpp: aoc-c.i
|
||||
|
||||
assembly: aoc-c.s
|
||||
|
||||
part1: aoc-c
|
||||
@$(TIME) aoc.bash -p 1 < $(INPUT) 2>&1
|
||||
@$(TIME) aoc-c -p 1 < $(INPUT)
|
||||
|
||||
part2: aoc-c
|
||||
@$(TIME) aoc.bash -p 2 < $(INPUT) 2>&1
|
||||
@$(TIME) aoc-c -p 2 < $(INPUT)
|
||||
|
||||
ccls: $(CCLSFILE)
|
||||
|
||||
clean:
|
||||
@rm -f aoc-c core* vgcore* gmon.out aoc-c.s aoc-c.i README.html compile_commands.json
|
||||
|
||||
aoc-c: aoc-c.c common.c
|
||||
@echo compiling $<
|
||||
$(CC) $(CFLAGS) $(LDFLAGS) -I $(INCDIR) $^ $(LDLIB) -o $@
|
||||
|
||||
# generate pre-processed file (.i) and assembler (.s)
|
||||
%.i: %.c
|
||||
@echo generating $@
|
||||
@$(CC) -E $(CFLAGS) -I $(INCDIR) $< -o $@
|
||||
|
||||
%.s: %.c
|
||||
@echo generating $@
|
||||
@$(CC) -S -fverbose-asm $(CFLAGS) -I $(INCDIR) $< -o $@
|
||||
|
||||
# generate README.org from README.html (must cleanup !)
|
||||
org: README.org
|
||||
|
||||
%.org: %.html
|
||||
@echo generating $@. Cleanup before commit !
|
||||
@pandoc $< -o $@
|
||||
|
||||
# generate compile_commands.json
|
||||
$(CCLSFILE): aoc-c.c Makefile
|
||||
$(BEAR) -- make clean compile
|
||||
|
||||
bear: clean
|
||||
@touch .ccls-root
|
||||
@$(BEAR) -- make compile
|
||||
389
2022/day10/README.org
Normal file
389
2022/day10/README.org
Normal file
@@ -0,0 +1,389 @@
|
||||
** --- Day 10: Cathode-Ray Tube ---
|
||||
You avoid the ropes, plunge into the river, and swim to shore.
|
||||
|
||||
The Elves yell something about meeting back up with them upriver, but
|
||||
the river is too loud to tell exactly what they're saying. They finish
|
||||
crossing the bridge and disappear from view.
|
||||
|
||||
Situations like this must be why the Elves prioritized getting the
|
||||
communication system on your handheld device working. You pull it out of
|
||||
your pack, but the amount of water slowly draining from a big crack in
|
||||
its screen tells you it probably won't be of much immediate use.
|
||||
|
||||
/Unless/, that is, you can design a replacement for the device's video
|
||||
system! It seems to be some kind of
|
||||
[[https://en.wikipedia.org/wiki/Cathode-ray_tube][cathode-ray tube]]
|
||||
screen and simple CPU that are both driven by a precise /clock circuit/.
|
||||
The clock circuit ticks at a constant rate; each tick is called a
|
||||
/cycle/.
|
||||
|
||||
Start by figuring out the signal being sent by the CPU. The CPU has a
|
||||
single register, =X=, which starts with the value =1=. It supports only
|
||||
two instructions:
|
||||
|
||||
- =addx V= takes /two cycles/ to complete. /After/ two cycles, the =X=
|
||||
register is increased by the value =V=. (=V= can be negative.)
|
||||
- =noop= takes /one cycle/ to complete. It has no other effect.
|
||||
|
||||
The CPU uses these instructions in a program (your puzzle input) to,
|
||||
somehow, tell the screen what to draw.
|
||||
|
||||
Consider the following small program:
|
||||
|
||||
#+begin_example
|
||||
noop
|
||||
addx 3
|
||||
addx -5
|
||||
#+end_example
|
||||
|
||||
Execution of this program proceeds as follows:
|
||||
|
||||
- At the start of the first cycle, the =noop= instruction begins
|
||||
execution. During the first cycle, =X= is =1=. After the first cycle,
|
||||
the =noop= instruction finishes execution, doing nothing.
|
||||
- At the start of the second cycle, the =addx 3= instruction begins
|
||||
execution. During the second cycle, =X= is still =1=.
|
||||
- During the third cycle, =X= is still =1=. After the third cycle, the
|
||||
=addx 3= instruction finishes execution, setting =X= to =4=.
|
||||
- At the start of the fourth cycle, the =addx -5= instruction begins
|
||||
execution. During the fourth cycle, =X= is still =4=.
|
||||
- During the fifth cycle, =X= is still =4=. After the fifth cycle, the
|
||||
=addx -5= instruction finishes execution, setting =X= to =-1=.
|
||||
|
||||
Maybe you can learn something by looking at the value of the =X=
|
||||
register throughout execution. For now, consider the /signal strength/
|
||||
(the cycle number multiplied by the value of the =X= register) /during/
|
||||
the 20th cycle and every 40 cycles after that (that is, during the 20th,
|
||||
60th, 100th, 140th, 180th, and 220th cycles).
|
||||
|
||||
For example, consider this larger program:
|
||||
|
||||
#+begin_example
|
||||
addx 15
|
||||
addx -11
|
||||
addx 6
|
||||
addx -3
|
||||
addx 5
|
||||
addx -1
|
||||
addx -8
|
||||
addx 13
|
||||
addx 4
|
||||
noop
|
||||
addx -1
|
||||
addx 5
|
||||
addx -1
|
||||
addx 5
|
||||
addx -1
|
||||
addx 5
|
||||
addx -1
|
||||
addx 5
|
||||
addx -1
|
||||
addx -35
|
||||
addx 1
|
||||
addx 24
|
||||
addx -19
|
||||
addx 1
|
||||
addx 16
|
||||
addx -11
|
||||
noop
|
||||
noop
|
||||
addx 21
|
||||
addx -15
|
||||
noop
|
||||
noop
|
||||
addx -3
|
||||
addx 9
|
||||
addx 1
|
||||
addx -3
|
||||
addx 8
|
||||
addx 1
|
||||
addx 5
|
||||
noop
|
||||
noop
|
||||
noop
|
||||
noop
|
||||
noop
|
||||
addx -36
|
||||
noop
|
||||
addx 1
|
||||
addx 7
|
||||
noop
|
||||
noop
|
||||
noop
|
||||
addx 2
|
||||
addx 6
|
||||
noop
|
||||
noop
|
||||
noop
|
||||
noop
|
||||
noop
|
||||
addx 1
|
||||
noop
|
||||
noop
|
||||
addx 7
|
||||
addx 1
|
||||
noop
|
||||
addx -13
|
||||
addx 13
|
||||
addx 7
|
||||
noop
|
||||
addx 1
|
||||
addx -33
|
||||
noop
|
||||
noop
|
||||
noop
|
||||
addx 2
|
||||
noop
|
||||
noop
|
||||
noop
|
||||
addx 8
|
||||
noop
|
||||
addx -1
|
||||
addx 2
|
||||
addx 1
|
||||
noop
|
||||
addx 17
|
||||
addx -9
|
||||
addx 1
|
||||
addx 1
|
||||
addx -3
|
||||
addx 11
|
||||
noop
|
||||
noop
|
||||
addx 1
|
||||
noop
|
||||
addx 1
|
||||
noop
|
||||
noop
|
||||
addx -13
|
||||
addx -19
|
||||
addx 1
|
||||
addx 3
|
||||
addx 26
|
||||
addx -30
|
||||
addx 12
|
||||
addx -1
|
||||
addx 3
|
||||
addx 1
|
||||
noop
|
||||
noop
|
||||
noop
|
||||
addx -9
|
||||
addx 18
|
||||
addx 1
|
||||
addx 2
|
||||
noop
|
||||
noop
|
||||
addx 9
|
||||
noop
|
||||
noop
|
||||
noop
|
||||
addx -1
|
||||
addx 2
|
||||
addx -37
|
||||
addx 1
|
||||
addx 3
|
||||
noop
|
||||
addx 15
|
||||
addx -21
|
||||
addx 22
|
||||
addx -6
|
||||
addx 1
|
||||
noop
|
||||
addx 2
|
||||
addx 1
|
||||
noop
|
||||
addx -10
|
||||
noop
|
||||
noop
|
||||
addx 20
|
||||
addx 1
|
||||
addx 2
|
||||
addx 2
|
||||
addx -6
|
||||
addx -11
|
||||
noop
|
||||
noop
|
||||
noop
|
||||
#+end_example
|
||||
|
||||
The interesting signal strengths can be determined as follows:
|
||||
|
||||
- During the 20th cycle, register =X= has the value =21=, so the signal
|
||||
strength is 20 * 21 = /420/. (The 20th cycle occurs in the middle of
|
||||
the second =addx -1=, so the value of register =X= is the starting
|
||||
value, =1=, plus all of the other =addx= values up to that point: 1 +
|
||||
15 - 11 + 6 - 3 + 5 - 1 - 8 + 13 + 4 = 21.)
|
||||
- During the 60th cycle, register =X= has the value =19=, so the signal
|
||||
strength is 60 * 19 = =1140=.
|
||||
- During the 100th cycle, register =X= has the value =18=, so the signal
|
||||
strength is 100 * 18 = =1800=.
|
||||
- During the 140th cycle, register =X= has the value =21=, so the signal
|
||||
strength is 140 * 21 = =2940=.
|
||||
- During the 180th cycle, register =X= has the value =16=, so the signal
|
||||
strength is 180 * 16 = =2880=.
|
||||
- During the 220th cycle, register =X= has the value =18=, so the signal
|
||||
strength is 220 * 18 = =3960=.
|
||||
|
||||
The sum of these signal strengths is =13140=.
|
||||
|
||||
Find the signal strength during the 20th, 60th, 100th, 140th, 180th, and
|
||||
220th cycles. /What is the sum of these six signal strengths?/
|
||||
|
||||
Your puzzle answer was =13220=.
|
||||
|
||||
** --- Part Two ---
|
||||
It seems like the =X= register controls the horizontal position of a
|
||||
[[https://en.wikipedia.org/wiki/Sprite_(computer_graphics)][sprite]].
|
||||
Specifically, the sprite is 3 pixels wide, and the =X= register sets the
|
||||
horizontal position of the /middle/ of that sprite. (In this system,
|
||||
there is no such thing as "vertical position": if the sprite's
|
||||
horizontal position puts its pixels where the CRT is currently drawing,
|
||||
then those pixels will be drawn.)
|
||||
|
||||
You count the pixels on the CRT: 40 wide and 6 high. This CRT screen
|
||||
draws the top row of pixels left-to-right, then the row below that, and
|
||||
so on. The left-most pixel in each row is in position =0=, and the
|
||||
right-most pixel in each row is in position =39=.
|
||||
|
||||
Like the CPU, the CRT is tied closely to the clock circuit: the CRT
|
||||
draws /a single pixel during each cycle/. Representing each pixel of the
|
||||
screen as a =#=, here are the cycles during which the first and last
|
||||
pixel in each row are drawn:
|
||||
|
||||
#+begin_example
|
||||
Cycle 1 -> ######################################## <- Cycle 40
|
||||
Cycle 41 -> ######################################## <- Cycle 80
|
||||
Cycle 81 -> ######################################## <- Cycle 120
|
||||
Cycle 121 -> ######################################## <- Cycle 160
|
||||
Cycle 161 -> ######################################## <- Cycle 200
|
||||
Cycle 201 -> ######################################## <- Cycle 240
|
||||
#+end_example
|
||||
|
||||
So, by [[https://en.wikipedia.org/wiki/Racing_the_Beam][carefully]]
|
||||
[[https://www.youtube.com/watch?v=sJFnWZH5FXc][timing]] the CPU
|
||||
instructions and the CRT drawing operations, you should be able to
|
||||
determine whether the sprite is visible the instant each pixel is drawn.
|
||||
If the sprite is positioned such that one of its three pixels is the
|
||||
pixel currently being drawn, the screen produces a /lit/ pixel (=#=);
|
||||
otherwise, the screen leaves the pixel /dark/ (=.=).
|
||||
|
||||
The first few pixels from the larger example above are drawn as follows:
|
||||
|
||||
#+begin_example
|
||||
Sprite position: ###.....................................
|
||||
|
||||
Start cycle 1: begin executing addx 15
|
||||
During cycle 1: CRT draws pixel in position 0
|
||||
Current CRT row: #
|
||||
|
||||
During cycle 2: CRT draws pixel in position 1
|
||||
Current CRT row: ##
|
||||
End of cycle 2: finish executing addx 15 (Register X is now 16)
|
||||
Sprite position: ...............###......................
|
||||
|
||||
Start cycle 3: begin executing addx -11
|
||||
During cycle 3: CRT draws pixel in position 2
|
||||
Current CRT row: ##.
|
||||
|
||||
During cycle 4: CRT draws pixel in position 3
|
||||
Current CRT row: ##..
|
||||
End of cycle 4: finish executing addx -11 (Register X is now 5)
|
||||
Sprite position: ....###.................................
|
||||
|
||||
Start cycle 5: begin executing addx 6
|
||||
During cycle 5: CRT draws pixel in position 4
|
||||
Current CRT row: ##..#
|
||||
|
||||
During cycle 6: CRT draws pixel in position 5
|
||||
Current CRT row: ##..##
|
||||
End of cycle 6: finish executing addx 6 (Register X is now 11)
|
||||
Sprite position: ..........###...........................
|
||||
|
||||
Start cycle 7: begin executing addx -3
|
||||
During cycle 7: CRT draws pixel in position 6
|
||||
Current CRT row: ##..##.
|
||||
|
||||
During cycle 8: CRT draws pixel in position 7
|
||||
Current CRT row: ##..##..
|
||||
End of cycle 8: finish executing addx -3 (Register X is now 8)
|
||||
Sprite position: .......###..............................
|
||||
|
||||
Start cycle 9: begin executing addx 5
|
||||
During cycle 9: CRT draws pixel in position 8
|
||||
Current CRT row: ##..##..#
|
||||
|
||||
During cycle 10: CRT draws pixel in position 9
|
||||
Current CRT row: ##..##..##
|
||||
End of cycle 10: finish executing addx 5 (Register X is now 13)
|
||||
Sprite position: ............###.........................
|
||||
|
||||
Start cycle 11: begin executing addx -1
|
||||
During cycle 11: CRT draws pixel in position 10
|
||||
Current CRT row: ##..##..##.
|
||||
|
||||
During cycle 12: CRT draws pixel in position 11
|
||||
Current CRT row: ##..##..##..
|
||||
End of cycle 12: finish executing addx -1 (Register X is now 12)
|
||||
Sprite position: ...........###..........................
|
||||
|
||||
Start cycle 13: begin executing addx -8
|
||||
During cycle 13: CRT draws pixel in position 12
|
||||
Current CRT row: ##..##..##..#
|
||||
|
||||
During cycle 14: CRT draws pixel in position 13
|
||||
Current CRT row: ##..##..##..##
|
||||
End of cycle 14: finish executing addx -8 (Register X is now 4)
|
||||
Sprite position: ...###..................................
|
||||
|
||||
Start cycle 15: begin executing addx 13
|
||||
During cycle 15: CRT draws pixel in position 14
|
||||
Current CRT row: ##..##..##..##.
|
||||
|
||||
During cycle 16: CRT draws pixel in position 15
|
||||
Current CRT row: ##..##..##..##..
|
||||
End of cycle 16: finish executing addx 13 (Register X is now 17)
|
||||
Sprite position: ................###.....................
|
||||
|
||||
Start cycle 17: begin executing addx 4
|
||||
During cycle 17: CRT draws pixel in position 16
|
||||
Current CRT row: ##..##..##..##..#
|
||||
|
||||
During cycle 18: CRT draws pixel in position 17
|
||||
Current CRT row: ##..##..##..##..##
|
||||
End of cycle 18: finish executing addx 4 (Register X is now 21)
|
||||
Sprite position: ....................###.................
|
||||
|
||||
Start cycle 19: begin executing noop
|
||||
During cycle 19: CRT draws pixel in position 18
|
||||
Current CRT row: ##..##..##..##..##.
|
||||
End of cycle 19: finish executing noop
|
||||
|
||||
Start cycle 20: begin executing addx -1
|
||||
During cycle 20: CRT draws pixel in position 19
|
||||
Current CRT row: ##..##..##..##..##..
|
||||
|
||||
During cycle 21: CRT draws pixel in position 20
|
||||
Current CRT row: ##..##..##..##..##..#
|
||||
End of cycle 21: finish executing addx -1 (Register X is now 20)
|
||||
Sprite position: ...................###..................
|
||||
#+end_example
|
||||
|
||||
Allowing the program to run to completion causes the CRT to produce the
|
||||
following image:
|
||||
|
||||
#+begin_example
|
||||
##..##..##..##..##..##..##..##..##..##..
|
||||
###...###...###...###...###...###...###.
|
||||
####....####....####....####....####....
|
||||
#####.....#####.....#####.....#####.....
|
||||
######......######......######......####
|
||||
#######.......#######.......#######.....
|
||||
#+end_example
|
||||
|
||||
Render the image given by your program. /What eight capital letters
|
||||
appear on your CRT?/
|
||||
|
||||
Your puzzle answer was =RUAKHBEK=.
|
||||
|
||||
Both parts of this puzzle are complete! They provide two gold stars: **
|
||||
167
2022/day10/aoc-c.c
Normal file
167
2022/day10/aoc-c.c
Normal file
@@ -0,0 +1,167 @@
|
||||
/* aoc-c.c: Advent of Code 2022, day 10
|
||||
*
|
||||
* Copyright (C) 2022 Bruno Raoult ("br")
|
||||
* Licensed under the GNU General Public License v3.0 or later.
|
||||
* Some rights reserved. See COPYING.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with this
|
||||
* program. If not, see <https://www.gnu.org/licenses/gpl-3.0-standalone.html>.
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later <https://spdx.org/licenses/GPL-3.0-or-later.html>
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "br.h"
|
||||
#include "debug.h"
|
||||
|
||||
#include "aoc.h"
|
||||
|
||||
#define MAXARGS 1 /* max arguments to opcode */
|
||||
|
||||
typedef enum opcode { /* available opcodes */
|
||||
ERR = -1,
|
||||
NOOP = 0,
|
||||
ADDX
|
||||
} opcode_t;
|
||||
|
||||
typedef struct hw { /* hardware */
|
||||
int tick; /* clock */
|
||||
int regx; /* x register */
|
||||
int signal; /* signal strength */
|
||||
int alrm; /* next tick signal */
|
||||
int rearm; /* rearm signal value */
|
||||
void (* tickfct)(struct hw *hw); /* tick function */
|
||||
void (* alrmfct)(struct hw *hw); /* signal function */
|
||||
int part; /* puzzle part */
|
||||
} hw_t;
|
||||
|
||||
typedef struct op { /* operators indormation */
|
||||
char *mnemo;
|
||||
opcode_t opcode;
|
||||
int ticks;
|
||||
void (* fct)(hw_t *hw, int *);
|
||||
int nargs;
|
||||
} op_t;
|
||||
|
||||
static inline void alarm1(hw_t *hw)
|
||||
{
|
||||
hw->signal += hw->tick * hw->regx;
|
||||
hw->alrm = hw->rearm;
|
||||
}
|
||||
|
||||
static inline void alarm2(hw_t *hw)
|
||||
{
|
||||
putchar('\n'); /* '.' fixes last column garbage */
|
||||
hw->alrm = hw->rearm;
|
||||
}
|
||||
|
||||
static inline void tick1(__unused hw_t *hw)
|
||||
{
|
||||
}
|
||||
|
||||
static inline void tick2(hw_t *hw)
|
||||
{
|
||||
int pos = abs(hw->tick % 40 - hw->regx - 1);
|
||||
putchar(pos < 2? '#': '.');
|
||||
}
|
||||
|
||||
static void bootstrap(hw_t *hw, int part)
|
||||
{
|
||||
hw->tick = 0;
|
||||
hw->regx = 1;
|
||||
hw->signal = 0;
|
||||
hw->alrm = part == 1? 20: 40;
|
||||
hw->rearm = 40;
|
||||
hw->alrmfct = part == 1? alarm1: alarm2;
|
||||
hw->tickfct = part == 1? tick1: tick2;
|
||||
hw->part = part;
|
||||
}
|
||||
|
||||
static inline void tick(hw_t *hw)
|
||||
{
|
||||
hw->tick++;
|
||||
hw->alrm--;
|
||||
hw->tickfct(hw);
|
||||
if (!hw->alrm)
|
||||
hw->alrmfct(hw);
|
||||
}
|
||||
|
||||
static inline void ticks(hw_t *hw, int ticks)
|
||||
{
|
||||
for (int i = 0; i < ticks; ++i)
|
||||
tick(hw);
|
||||
}
|
||||
|
||||
static void do_noop(__unused hw_t *hw, __unused int *args)
|
||||
{
|
||||
}
|
||||
|
||||
static void do_addx(hw_t *hw, int *args)
|
||||
{
|
||||
hw->regx += *args;
|
||||
}
|
||||
|
||||
static op_t opcodes[] = {
|
||||
{ "noop", NOOP, 1, do_noop, 0 },
|
||||
{ "addx", ADDX, 2, do_addx, 1 }
|
||||
};
|
||||
|
||||
#define NOPS ARRAY_SIZE(opcodes)
|
||||
|
||||
static op_t *getop(const char *mnemo)
|
||||
{
|
||||
for (ulong i = 0; i < NOPS; ++i)
|
||||
if (!strcmp(mnemo, opcodes[i].mnemo))
|
||||
return opcodes + i;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int part1(hw_t *hw)
|
||||
{
|
||||
return hw->signal;
|
||||
}
|
||||
|
||||
static int part2(hw_t *hw)
|
||||
{
|
||||
return hw->signal;
|
||||
}
|
||||
|
||||
static int parse(hw_t *hw)
|
||||
{
|
||||
size_t alloc = 0;
|
||||
char *buf = NULL;
|
||||
ssize_t buflen;
|
||||
char *token;
|
||||
op_t *op;
|
||||
int args[MAXARGS];
|
||||
|
||||
while ((buflen = getline(&buf, &alloc, stdin)) > 0) {
|
||||
buf[--buflen] = 0;
|
||||
if ((token = strtok(buf, " "))) {
|
||||
if ((op = getop(token))) {
|
||||
ticks(hw, op->ticks);
|
||||
for (int i = 0; i < op->nargs; ++i)
|
||||
args[i] = atoi(strtok(NULL, " "));
|
||||
op->fct(hw, args);
|
||||
} else {
|
||||
fprintf(stderr, "Fatal: opcode [%s] not found\n", token);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int main(int ac, char **av)
|
||||
{
|
||||
int part = parseargs(ac, av);
|
||||
hw_t hw;
|
||||
|
||||
bootstrap(&hw, part);
|
||||
parse(&hw);
|
||||
printf("%s: res=%d\n", *av, part == 1? part1(&hw): part2(&hw));
|
||||
exit(0);
|
||||
}
|
||||
67
2022/day10/aoc.bash
Executable file
67
2022/day10/aoc.bash
Executable file
@@ -0,0 +1,67 @@
|
||||
#!/usr/bin/env bash
|
||||
#
|
||||
# aoc.bash: Advent of Code 2022, day 10
|
||||
#
|
||||
# Copyright (C) 2022 Bruno Raoult ("br")
|
||||
# Licensed under the GNU General Public License v3.0 or later.
|
||||
# Some rights reserved. See COPYING.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License along with this
|
||||
# program. If not, see <https://www.gnu.org/licenses/gpl-3.0-standalone.html>.
|
||||
#
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later <https://spdx.org/licenses/GPL-3.0-or-later.html>
|
||||
|
||||
. common.bash
|
||||
|
||||
declare -i cycle=0 regx=1
|
||||
|
||||
draw() {
|
||||
local -i pos
|
||||
|
||||
(( pos = cycle % 40 - regx - 1, pos = pos < 0? -pos: pos ))
|
||||
(( pos < 2 )) && res+="#" || res+="."
|
||||
if ! (( cycle % 40 )); then
|
||||
res+=$'\n'
|
||||
fi
|
||||
}
|
||||
|
||||
tick() {
|
||||
(( cycle ++ ))
|
||||
if (( part == 1 )); then
|
||||
(( (cycle + 20) % 40 )) || (( res += cycle * regx ))
|
||||
else
|
||||
draw
|
||||
fi
|
||||
}
|
||||
|
||||
do_noop() {
|
||||
tick
|
||||
}
|
||||
|
||||
do_add() {
|
||||
tick
|
||||
tick
|
||||
(( regx += $1 ))
|
||||
}
|
||||
|
||||
parse() {
|
||||
while read -r instr value; do
|
||||
# not too hacky, to prepare for next puzzles ;-)
|
||||
case "$instr" in
|
||||
"addx")
|
||||
do_add "$value"
|
||||
;;
|
||||
"noop")
|
||||
do_noop
|
||||
;;
|
||||
esac
|
||||
done
|
||||
}
|
||||
|
||||
solve() {
|
||||
# remove last '\n', add starting '\n'
|
||||
(( part == 2 )) && res=$'\n'${res::-1}
|
||||
}
|
||||
|
||||
main "$@"
|
||||
exit 0
|
||||
17
2022/day10/aoc.h
Normal file
17
2022/day10/aoc.h
Normal file
@@ -0,0 +1,17 @@
|
||||
/* aoc.c: Advent of Code 2022
|
||||
*
|
||||
* Copyright (C) 2022 Bruno Raoult ("br")
|
||||
* Licensed under the GNU General Public License v3.0 or later.
|
||||
* Some rights reserved. See COPYING.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with this
|
||||
* program. If not, see <https://www.gnu.org/licenses/gpl-3.0-standalone.html>.
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later <https://spdx.org/licenses/GPL-3.0-or-later.html>
|
||||
*/
|
||||
#ifndef _AOC_H_
|
||||
#define _AOC_H_
|
||||
|
||||
extern int parseargs(int ac, char**av);
|
||||
|
||||
#endif /* _AOC_H_ */
|
||||
68
2022/day10/common.bash
Executable file
68
2022/day10/common.bash
Executable file
@@ -0,0 +1,68 @@
|
||||
#!/usr/bin/env bash
|
||||
#
|
||||
# common.bash: Advent of Code 2022, common bash functions
|
||||
#
|
||||
# Copyright (C) 2022 Bruno Raoult ("br")
|
||||
# Licensed under the GNU General Public License v3.0 or later.
|
||||
# Some rights reserved. See COPYING.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License along with this
|
||||
# program. If not, see <https://www.gnu.org/licenses/gpl-3.0-standalone.html>.
|
||||
#
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later <https://spdx.org/licenses/GPL-3.0-or-later.html>
|
||||
|
||||
# shellcheck disable=2034
|
||||
export cmdname=${0##*/}
|
||||
export debug=0
|
||||
export res
|
||||
export LANG=C
|
||||
|
||||
shopt -s extglob
|
||||
set -o noglob
|
||||
|
||||
usage() {
|
||||
printf "usage: %s [-d DEBUG] [-p PART]\n" "$cmdname"
|
||||
exit 1
|
||||
}
|
||||
|
||||
checkargs() {
|
||||
local part=1
|
||||
while getopts p:d: todo; do
|
||||
case "$todo" in
|
||||
d)
|
||||
if [[ "$OPTARG" =~ ^[[:digit:]+]$ ]]; then
|
||||
debug="$OPTARG"
|
||||
else
|
||||
printf "%s: illegal [%s] debug level.\n" "$CMD" "$OPTARG"
|
||||
exit 1
|
||||
fi
|
||||
;;
|
||||
p)
|
||||
if [[ "$OPTARG" =~ ^[12]$ ]]; then
|
||||
part="$OPTARG"
|
||||
else
|
||||
printf "%s: illegal [%s] part.\n" "$CMD" "$OPTARG"
|
||||
exit 1
|
||||
fi
|
||||
;;
|
||||
*)
|
||||
usage
|
||||
;;
|
||||
esac
|
||||
done
|
||||
# Now check remaining argument (backup directory)
|
||||
shift $((OPTIND - 1))
|
||||
|
||||
(( $# > 1 )) && usage
|
||||
return "$part"
|
||||
}
|
||||
|
||||
main() {
|
||||
local -i part
|
||||
|
||||
checkargs "$@"
|
||||
part=$?
|
||||
parse "$part"
|
||||
solve "$part"
|
||||
printf "%s: res=%s\n" "$cmdname" "$res"
|
||||
}
|
||||
49
2022/day10/common.c
Normal file
49
2022/day10/common.c
Normal file
@@ -0,0 +1,49 @@
|
||||
/* common.c: Advent of Code 2022, common functions
|
||||
*
|
||||
* Copyright (C) 2022 Bruno Raoult ("br")
|
||||
* Licensed under the GNU General Public License v3.0 or later.
|
||||
* Some rights reserved. See COPYING.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with this
|
||||
* program. If not, see <https://www.gnu.org/licenses/gpl-3.0-standalone.html>.
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later <https://spdx.org/licenses/GPL-3.0-or-later.html>
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "aoc.h"
|
||||
#include "debug.h"
|
||||
|
||||
static int usage(char *prg)
|
||||
{
|
||||
fprintf(stderr, "Usage: %s [-d debug_level] [-p part] [-i input]\n", prg);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int parseargs(int ac, char **av)
|
||||
{
|
||||
int opt, part = 1;
|
||||
|
||||
while ((opt = getopt(ac, av, "d:p:")) != -1) {
|
||||
switch (opt) {
|
||||
case 'd':
|
||||
debug_level_set(atoi(optarg));
|
||||
break;
|
||||
case 'p': /* 1 or 2 */
|
||||
part = atoi(optarg);
|
||||
if (part < 1 || part > 2)
|
||||
return usage(*av);
|
||||
break;
|
||||
case 'i':
|
||||
|
||||
default:
|
||||
return usage(*av);
|
||||
}
|
||||
}
|
||||
if (optind < ac)
|
||||
return usage(*av);
|
||||
return part;
|
||||
}
|
||||
146
2022/day10/input/example.txt
Normal file
146
2022/day10/input/example.txt
Normal file
@@ -0,0 +1,146 @@
|
||||
addx 15
|
||||
addx -11
|
||||
addx 6
|
||||
addx -3
|
||||
addx 5
|
||||
addx -1
|
||||
addx -8
|
||||
addx 13
|
||||
addx 4
|
||||
noop
|
||||
addx -1
|
||||
addx 5
|
||||
addx -1
|
||||
addx 5
|
||||
addx -1
|
||||
addx 5
|
||||
addx -1
|
||||
addx 5
|
||||
addx -1
|
||||
addx -35
|
||||
addx 1
|
||||
addx 24
|
||||
addx -19
|
||||
addx 1
|
||||
addx 16
|
||||
addx -11
|
||||
noop
|
||||
noop
|
||||
addx 21
|
||||
addx -15
|
||||
noop
|
||||
noop
|
||||
addx -3
|
||||
addx 9
|
||||
addx 1
|
||||
addx -3
|
||||
addx 8
|
||||
addx 1
|
||||
addx 5
|
||||
noop
|
||||
noop
|
||||
noop
|
||||
noop
|
||||
noop
|
||||
addx -36
|
||||
noop
|
||||
addx 1
|
||||
addx 7
|
||||
noop
|
||||
noop
|
||||
noop
|
||||
addx 2
|
||||
addx 6
|
||||
noop
|
||||
noop
|
||||
noop
|
||||
noop
|
||||
noop
|
||||
addx 1
|
||||
noop
|
||||
noop
|
||||
addx 7
|
||||
addx 1
|
||||
noop
|
||||
addx -13
|
||||
addx 13
|
||||
addx 7
|
||||
noop
|
||||
addx 1
|
||||
addx -33
|
||||
noop
|
||||
noop
|
||||
noop
|
||||
addx 2
|
||||
noop
|
||||
noop
|
||||
noop
|
||||
addx 8
|
||||
noop
|
||||
addx -1
|
||||
addx 2
|
||||
addx 1
|
||||
noop
|
||||
addx 17
|
||||
addx -9
|
||||
addx 1
|
||||
addx 1
|
||||
addx -3
|
||||
addx 11
|
||||
noop
|
||||
noop
|
||||
addx 1
|
||||
noop
|
||||
addx 1
|
||||
noop
|
||||
noop
|
||||
addx -13
|
||||
addx -19
|
||||
addx 1
|
||||
addx 3
|
||||
addx 26
|
||||
addx -30
|
||||
addx 12
|
||||
addx -1
|
||||
addx 3
|
||||
addx 1
|
||||
noop
|
||||
noop
|
||||
noop
|
||||
addx -9
|
||||
addx 18
|
||||
addx 1
|
||||
addx 2
|
||||
noop
|
||||
noop
|
||||
addx 9
|
||||
noop
|
||||
noop
|
||||
noop
|
||||
addx -1
|
||||
addx 2
|
||||
addx -37
|
||||
addx 1
|
||||
addx 3
|
||||
noop
|
||||
addx 15
|
||||
addx -21
|
||||
addx 22
|
||||
addx -6
|
||||
addx 1
|
||||
noop
|
||||
addx 2
|
||||
addx 1
|
||||
noop
|
||||
addx -10
|
||||
noop
|
||||
noop
|
||||
addx 20
|
||||
addx 1
|
||||
addx 2
|
||||
addx 2
|
||||
addx -6
|
||||
addx -11
|
||||
noop
|
||||
noop
|
||||
noop
|
||||
3
2022/day10/input/example2.txt
Normal file
3
2022/day10/input/example2.txt
Normal file
@@ -0,0 +1,3 @@
|
||||
noop
|
||||
addx 3
|
||||
addx -5
|
||||
137
2022/day10/input/input.txt
Normal file
137
2022/day10/input/input.txt
Normal file
@@ -0,0 +1,137 @@
|
||||
noop
|
||||
noop
|
||||
addx 5
|
||||
addx 3
|
||||
addx -2
|
||||
noop
|
||||
addx 5
|
||||
addx 4
|
||||
noop
|
||||
addx 3
|
||||
noop
|
||||
addx 2
|
||||
addx -17
|
||||
addx 18
|
||||
addx 3
|
||||
addx 1
|
||||
noop
|
||||
addx 5
|
||||
noop
|
||||
addx 1
|
||||
addx 2
|
||||
addx 5
|
||||
addx -40
|
||||
noop
|
||||
addx 5
|
||||
addx 2
|
||||
addx 3
|
||||
noop
|
||||
addx 2
|
||||
addx 3
|
||||
addx -2
|
||||
addx 2
|
||||
addx 2
|
||||
noop
|
||||
addx 3
|
||||
addx 5
|
||||
addx 2
|
||||
addx 3
|
||||
addx -2
|
||||
addx 2
|
||||
addx -24
|
||||
addx 31
|
||||
addx 2
|
||||
addx -33
|
||||
addx -6
|
||||
addx 5
|
||||
addx 2
|
||||
addx 3
|
||||
noop
|
||||
addx 2
|
||||
addx 3
|
||||
noop
|
||||
addx 2
|
||||
addx -1
|
||||
addx 6
|
||||
noop
|
||||
noop
|
||||
addx 1
|
||||
addx 4
|
||||
noop
|
||||
noop
|
||||
addx -15
|
||||
addx 20
|
||||
noop
|
||||
addx -23
|
||||
addx 27
|
||||
noop
|
||||
addx -35
|
||||
addx 1
|
||||
noop
|
||||
noop
|
||||
addx 5
|
||||
addx 11
|
||||
addx -10
|
||||
addx 4
|
||||
addx 1
|
||||
noop
|
||||
addx 2
|
||||
addx 2
|
||||
noop
|
||||
addx 3
|
||||
noop
|
||||
addx 3
|
||||
addx 2
|
||||
noop
|
||||
addx 3
|
||||
addx 2
|
||||
addx 11
|
||||
addx -4
|
||||
addx 2
|
||||
addx -38
|
||||
addx -1
|
||||
addx 2
|
||||
noop
|
||||
addx 3
|
||||
addx 5
|
||||
addx 2
|
||||
addx -7
|
||||
addx 8
|
||||
addx 2
|
||||
addx 2
|
||||
noop
|
||||
addx 3
|
||||
addx 5
|
||||
addx 2
|
||||
addx -25
|
||||
addx 26
|
||||
addx 2
|
||||
addx 8
|
||||
addx -1
|
||||
addx 2
|
||||
addx -2
|
||||
addx -37
|
||||
addx 5
|
||||
addx 3
|
||||
addx -1
|
||||
addx 5
|
||||
noop
|
||||
addx 22
|
||||
addx -21
|
||||
addx 2
|
||||
addx 5
|
||||
addx 2
|
||||
addx 13
|
||||
addx -12
|
||||
addx 4
|
||||
noop
|
||||
noop
|
||||
addx 5
|
||||
addx 1
|
||||
noop
|
||||
noop
|
||||
addx 2
|
||||
noop
|
||||
addx 3
|
||||
noop
|
||||
noop
|
||||
111
2022/day11/Makefile
Normal file
111
2022/day11/Makefile
Normal file
@@ -0,0 +1,111 @@
|
||||
# AOC daily Makefile - GNU make only.
|
||||
#
|
||||
# Copyright (C) 2021-2022 Bruno Raoult ("br")
|
||||
# Licensed under the GNU General Public License v3.0 or later.
|
||||
# Some rights reserved. See COPYING.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License along with this
|
||||
# program. If not, see <https://www.gnu.org/licenses/gpl-3.0-standalone.html>.
|
||||
#
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later <https://spdx.org/licenses/GPL-3.0-or-later.html>
|
||||
#
|
||||
|
||||
INPUT := input/input.txt
|
||||
SHELL := /bin/bash
|
||||
|
||||
CC := gcc
|
||||
BEAR := bear
|
||||
CCLSFILE:= compile_commands.json
|
||||
|
||||
LIB := aoc_$(shell uname -m)
|
||||
INCDIR := ../include
|
||||
LIBDIR := ../lib
|
||||
LDFLAGS := -L$(LIBDIR)
|
||||
#LDLIB := -l$(LIB) -lm
|
||||
LDLIB := -l$(LIB)
|
||||
|
||||
export LD_LIBRARY_PATH = $(LIBDIR)
|
||||
|
||||
CFLAGS += -std=gnu11
|
||||
CFLAGS += -O2
|
||||
CFLAGS += -g
|
||||
# for gprof
|
||||
# CFLAGS += -pg
|
||||
CFLAGS += -Wall
|
||||
CFLAGS += -Wextra
|
||||
CFLAGS += -march=native
|
||||
# Next one may be useful for valgrind (some invalid instructions)
|
||||
# CFLAGS += -mno-tbm
|
||||
CFLAGS += -Wmissing-declarations
|
||||
CFLAGS += -Wno-unused-result
|
||||
|
||||
CFLAGS += -DDEBUG_DEBUG # activate general debug (debug.c)
|
||||
CFLAGS += -DDEBUG_POOL # memory pools management
|
||||
|
||||
VALGRIND := valgrind
|
||||
VALGRINDFLAGS := --leak-check=full --show-leak-kinds=all --track-origins=yes \
|
||||
--sigill-diagnostics=yes --quiet --show-error-list=yes
|
||||
|
||||
|
||||
TIME := \time -f "\ttime: %E real, %U user, %S sys\n\tcontext-switch:\t%c+%w, page-faults: %F+%R\n"
|
||||
export PATH := .:$(PATH)
|
||||
|
||||
.PHONY: clean all compile assembly memcheck memcheck1 memcheck2 part1 part2 ccls bear org
|
||||
|
||||
all: README.org ccls part1 part2
|
||||
|
||||
memcheck: memcheck1 memcheck2
|
||||
|
||||
memcheck1: aoc-c
|
||||
@$(VALGRIND) $(VALGRINDFLAGS) aoc-c -p 1 < $(INPUT)
|
||||
|
||||
memcheck2: aoc-c
|
||||
@$(VALGRIND) $(VALGRINDFLAGS) aoc-c -p 2 < $(INPUT)
|
||||
@#@valgrind -s --track-origins=yes aoc-c -p 2 < $(INPUT)
|
||||
|
||||
compile: aoc-c
|
||||
|
||||
cpp: aoc-c.i
|
||||
|
||||
assembly: aoc-c.s
|
||||
|
||||
part1: aoc-c
|
||||
@$(TIME) aoc.bash -p 1 < $(INPUT) 2>&1
|
||||
@$(TIME) aoc-c -p 1 < $(INPUT)
|
||||
|
||||
part2: aoc-c
|
||||
@$(TIME) aoc.bash -p 2 < $(INPUT) 2>&1
|
||||
@$(TIME) aoc-c -p 2 < $(INPUT)
|
||||
|
||||
ccls: $(CCLSFILE)
|
||||
|
||||
clean:
|
||||
@rm -f aoc-c core* vgcore* gmon.out aoc-c.s aoc-c.i README.html compile_commands.json
|
||||
|
||||
aoc-c: aoc-c.c common.c
|
||||
@echo compiling $<
|
||||
$(CC) $(CFLAGS) $(LDFLAGS) -I $(INCDIR) $^ $(LDLIB) -o $@
|
||||
|
||||
# generate pre-processed file (.i) and assembler (.s)
|
||||
%.i: %.c
|
||||
@echo generating $@
|
||||
@$(CC) -E $(CFLAGS) -I $(INCDIR) $< -o $@
|
||||
|
||||
%.s: %.c
|
||||
@echo generating $@
|
||||
@$(CC) -S -fverbose-asm $(CFLAGS) -I $(INCDIR) $< -o $@
|
||||
|
||||
# generate README.org from README.html (must cleanup !)
|
||||
org: README.org
|
||||
|
||||
%.org: %.html
|
||||
@echo generating $@. Cleanup before commit !
|
||||
@pandoc $< -o $@
|
||||
|
||||
# generate compile_commands.json
|
||||
$(CCLSFILE): aoc-c.c Makefile
|
||||
$(BEAR) -- make clean compile
|
||||
|
||||
bear: clean
|
||||
@touch .ccls-root
|
||||
@$(BEAR) -- make compile
|
||||
364
2022/day11/README.org
Normal file
364
2022/day11/README.org
Normal file
@@ -0,0 +1,364 @@
|
||||
** --- Day 11: Monkey in the Middle ---
|
||||
As you finally start making your way upriver, you realize your pack is
|
||||
much lighter than you remember. Just then, one of the items from your
|
||||
pack goes flying overhead. Monkeys are playing
|
||||
[[https://en.wikipedia.org/wiki/Keep_away][Keep Away]] with your missing
|
||||
things!
|
||||
|
||||
To get your stuff back, you need to be able to predict where the monkeys
|
||||
will throw your items. After some careful observation, you realize the
|
||||
monkeys operate based on /how worried you are about each item/.
|
||||
|
||||
You take some notes (your puzzle input) on the items each monkey
|
||||
currently has, how worried you are about those items, and how the monkey
|
||||
makes decisions based on your worry level. For example:
|
||||
|
||||
#+begin_example
|
||||
Monkey 0:
|
||||
Starting items: 79, 98
|
||||
Operation: new = old * 19
|
||||
Test: divisible by 23
|
||||
If true: throw to monkey 2
|
||||
If false: throw to monkey 3
|
||||
|
||||
Monkey 1:
|
||||
Starting items: 54, 65, 75, 74
|
||||
Operation: new = old + 6
|
||||
Test: divisible by 19
|
||||
If true: throw to monkey 2
|
||||
If false: throw to monkey 0
|
||||
|
||||
Monkey 2:
|
||||
Starting items: 79, 60, 97
|
||||
Operation: new = old * old
|
||||
Test: divisible by 13
|
||||
If true: throw to monkey 1
|
||||
If false: throw to monkey 3
|
||||
|
||||
Monkey 3:
|
||||
Starting items: 74
|
||||
Operation: new = old + 3
|
||||
Test: divisible by 17
|
||||
If true: throw to monkey 0
|
||||
If false: throw to monkey 1
|
||||
#+end_example
|
||||
|
||||
Each monkey has several attributes:
|
||||
|
||||
- =Starting items= lists your /worry level/ for each item the monkey is
|
||||
currently holding in the order they will be inspected.
|
||||
- =Operation= shows how your worry level changes as that monkey inspects
|
||||
an item. (An operation like =new = old * 5= means that your worry
|
||||
level after the monkey inspected the item is five times whatever your
|
||||
worry level was before inspection.)
|
||||
- =Test= shows how the monkey uses your worry level to decide where to
|
||||
throw an item next.
|
||||
- =If true= shows what happens with an item if the =Test= was true.
|
||||
- =If false= shows what happens with an item if the =Test= was false.
|
||||
|
||||
After each monkey inspects an item but before it tests your worry level,
|
||||
your relief that the monkey's inspection didn't damage the item causes
|
||||
your worry level to be /divided by three/ and rounded down to the
|
||||
nearest integer.
|
||||
|
||||
The monkeys take turns inspecting and throwing items. On a single
|
||||
monkey's /turn/, it inspects and throws all of the items it is holding
|
||||
one at a time and in the order listed. Monkey =0= goes first, then
|
||||
monkey =1=, and so on until each monkey has had one turn. The process of
|
||||
each monkey taking a single turn is called a /round/.
|
||||
|
||||
When a monkey throws an item to another monkey, the item goes on the
|
||||
/end/ of the recipient monkey's list. A monkey that starts a round with
|
||||
no items could end up inspecting and throwing many items by the time its
|
||||
turn comes around. If a monkey is holding no items at the start of its
|
||||
turn, its turn ends.
|
||||
|
||||
In the above example, the first round proceeds as follows:
|
||||
|
||||
#+begin_example
|
||||
Monkey 0:
|
||||
Monkey inspects an item with a worry level of 79.
|
||||
Worry level is multiplied by 19 to 1501.
|
||||
Monkey gets bored with item. Worry level is divided by 3 to 500.
|
||||
Current worry level is not divisible by 23.
|
||||
Item with worry level 500 is thrown to monkey 3.
|
||||
Monkey inspects an item with a worry level of 98.
|
||||
Worry level is multiplied by 19 to 1862.
|
||||
Monkey gets bored with item. Worry level is divided by 3 to 620.
|
||||
Current worry level is not divisible by 23.
|
||||
Item with worry level 620 is thrown to monkey 3.
|
||||
Monkey 1:
|
||||
Monkey inspects an item with a worry level of 54.
|
||||
Worry level increases by 6 to 60.
|
||||
Monkey gets bored with item. Worry level is divided by 3 to 20.
|
||||
Current worry level is not divisible by 19.
|
||||
Item with worry level 20 is thrown to monkey 0.
|
||||
Monkey inspects an item with a worry level of 65.
|
||||
Worry level increases by 6 to 71.
|
||||
Monkey gets bored with item. Worry level is divided by 3 to 23.
|
||||
Current worry level is not divisible by 19.
|
||||
Item with worry level 23 is thrown to monkey 0.
|
||||
Monkey inspects an item with a worry level of 75.
|
||||
Worry level increases by 6 to 81.
|
||||
Monkey gets bored with item. Worry level is divided by 3 to 27.
|
||||
Current worry level is not divisible by 19.
|
||||
Item with worry level 27 is thrown to monkey 0.
|
||||
Monkey inspects an item with a worry level of 74.
|
||||
Worry level increases by 6 to 80.
|
||||
Monkey gets bored with item. Worry level is divided by 3 to 26.
|
||||
Current worry level is not divisible by 19.
|
||||
Item with worry level 26 is thrown to monkey 0.
|
||||
Monkey 2:
|
||||
Monkey inspects an item with a worry level of 79.
|
||||
Worry level is multiplied by itself to 6241.
|
||||
Monkey gets bored with item. Worry level is divided by 3 to 2080.
|
||||
Current worry level is divisible by 13.
|
||||
Item with worry level 2080 is thrown to monkey 1.
|
||||
Monkey inspects an item with a worry level of 60.
|
||||
Worry level is multiplied by itself to 3600.
|
||||
Monkey gets bored with item. Worry level is divided by 3 to 1200.
|
||||
Current worry level is not divisible by 13.
|
||||
Item with worry level 1200 is thrown to monkey 3.
|
||||
Monkey inspects an item with a worry level of 97.
|
||||
Worry level is multiplied by itself to 9409.
|
||||
Monkey gets bored with item. Worry level is divided by 3 to 3136.
|
||||
Current worry level is not divisible by 13.
|
||||
Item with worry level 3136 is thrown to monkey 3.
|
||||
Monkey 3:
|
||||
Monkey inspects an item with a worry level of 74.
|
||||
Worry level increases by 3 to 77.
|
||||
Monkey gets bored with item. Worry level is divided by 3 to 25.
|
||||
Current worry level is not divisible by 17.
|
||||
Item with worry level 25 is thrown to monkey 1.
|
||||
Monkey inspects an item with a worry level of 500.
|
||||
Worry level increases by 3 to 503.
|
||||
Monkey gets bored with item. Worry level is divided by 3 to 167.
|
||||
Current worry level is not divisible by 17.
|
||||
Item with worry level 167 is thrown to monkey 1.
|
||||
Monkey inspects an item with a worry level of 620.
|
||||
Worry level increases by 3 to 623.
|
||||
Monkey gets bored with item. Worry level is divided by 3 to 207.
|
||||
Current worry level is not divisible by 17.
|
||||
Item with worry level 207 is thrown to monkey 1.
|
||||
Monkey inspects an item with a worry level of 1200.
|
||||
Worry level increases by 3 to 1203.
|
||||
Monkey gets bored with item. Worry level is divided by 3 to 401.
|
||||
Current worry level is not divisible by 17.
|
||||
Item with worry level 401 is thrown to monkey 1.
|
||||
Monkey inspects an item with a worry level of 3136.
|
||||
Worry level increases by 3 to 3139.
|
||||
Monkey gets bored with item. Worry level is divided by 3 to 1046.
|
||||
Current worry level is not divisible by 17.
|
||||
Item with worry level 1046 is thrown to monkey 1.
|
||||
#+end_example
|
||||
|
||||
After round 1, the monkeys are holding items with these worry levels:
|
||||
|
||||
#+begin_example
|
||||
Monkey 0: 20, 23, 27, 26
|
||||
Monkey 1: 2080, 25, 167, 207, 401, 1046
|
||||
Monkey 2:
|
||||
Monkey 3:
|
||||
#+end_example
|
||||
|
||||
Monkeys 2 and 3 aren't holding any items at the end of the round; they
|
||||
both inspected items during the round and threw them all before the
|
||||
round ended.
|
||||
|
||||
This process continues for a few more rounds:
|
||||
|
||||
#+begin_example
|
||||
After round 2, the monkeys are holding items with these worry levels:
|
||||
Monkey 0: 695, 10, 71, 135, 350
|
||||
Monkey 1: 43, 49, 58, 55, 362
|
||||
Monkey 2:
|
||||
Monkey 3:
|
||||
|
||||
After round 3, the monkeys are holding items with these worry levels:
|
||||
Monkey 0: 16, 18, 21, 20, 122
|
||||
Monkey 1: 1468, 22, 150, 286, 739
|
||||
Monkey 2:
|
||||
Monkey 3:
|
||||
|
||||
After round 4, the monkeys are holding items with these worry levels:
|
||||
Monkey 0: 491, 9, 52, 97, 248, 34
|
||||
Monkey 1: 39, 45, 43, 258
|
||||
Monkey 2:
|
||||
Monkey 3:
|
||||
|
||||
After round 5, the monkeys are holding items with these worry levels:
|
||||
Monkey 0: 15, 17, 16, 88, 1037
|
||||
Monkey 1: 20, 110, 205, 524, 72
|
||||
Monkey 2:
|
||||
Monkey 3:
|
||||
|
||||
After round 6, the monkeys are holding items with these worry levels:
|
||||
Monkey 0: 8, 70, 176, 26, 34
|
||||
Monkey 1: 481, 32, 36, 186, 2190
|
||||
Monkey 2:
|
||||
Monkey 3:
|
||||
|
||||
After round 7, the monkeys are holding items with these worry levels:
|
||||
Monkey 0: 162, 12, 14, 64, 732, 17
|
||||
Monkey 1: 148, 372, 55, 72
|
||||
Monkey 2:
|
||||
Monkey 3:
|
||||
|
||||
After round 8, the monkeys are holding items with these worry levels:
|
||||
Monkey 0: 51, 126, 20, 26, 136
|
||||
Monkey 1: 343, 26, 30, 1546, 36
|
||||
Monkey 2:
|
||||
Monkey 3:
|
||||
|
||||
After round 9, the monkeys are holding items with these worry levels:
|
||||
Monkey 0: 116, 10, 12, 517, 14
|
||||
Monkey 1: 108, 267, 43, 55, 288
|
||||
Monkey 2:
|
||||
Monkey 3:
|
||||
|
||||
After round 10, the monkeys are holding items with these worry levels:
|
||||
Monkey 0: 91, 16, 20, 98
|
||||
Monkey 1: 481, 245, 22, 26, 1092, 30
|
||||
Monkey 2:
|
||||
Monkey 3:
|
||||
|
||||
...
|
||||
|
||||
After round 15, the monkeys are holding items with these worry levels:
|
||||
Monkey 0: 83, 44, 8, 184, 9, 20, 26, 102
|
||||
Monkey 1: 110, 36
|
||||
Monkey 2:
|
||||
Monkey 3:
|
||||
|
||||
...
|
||||
|
||||
After round 20, the monkeys are holding items with these worry levels:
|
||||
Monkey 0: 10, 12, 14, 26, 34
|
||||
Monkey 1: 245, 93, 53, 199, 115
|
||||
Monkey 2:
|
||||
Monkey 3:
|
||||
#+end_example
|
||||
|
||||
Chasing all of the monkeys at once is impossible; you're going to have
|
||||
to focus on the /two most active/ monkeys if you want any hope of
|
||||
getting your stuff back. Count the /total number of times each monkey
|
||||
inspects items/ over 20 rounds:
|
||||
|
||||
#+begin_example
|
||||
Monkey 0 inspected items 101 times.
|
||||
Monkey 1 inspected items 95 times.
|
||||
Monkey 2 inspected items 7 times.
|
||||
Monkey 3 inspected items 105 times.
|
||||
#+end_example
|
||||
|
||||
In this example, the two most active monkeys inspected items 101 and 105
|
||||
times. The level of /monkey business/ in this situation can be found by
|
||||
multiplying these together: =10605=.
|
||||
|
||||
Figure out which monkeys to chase by counting how many items they
|
||||
inspect over 20 rounds. /What is the level of monkey business after 20
|
||||
rounds of stuff-slinging simian shenanigans?/
|
||||
|
||||
Your puzzle answer was =54253=.
|
||||
|
||||
** --- Part Two ---
|
||||
You're worried you might not ever get your items back. So worried, in
|
||||
fact, that your relief that a monkey's inspection didn't damage an item
|
||||
/no longer causes your worry level to be divided by three/.
|
||||
|
||||
Unfortunately, that relief was all that was keeping your worry levels
|
||||
from reaching /ridiculous levels/. You'll need to /find another way to
|
||||
keep your worry levels manageable/.
|
||||
|
||||
At this rate, you might be putting up with these monkeys for a /very
|
||||
long time/ - possibly /=10000= rounds/!
|
||||
|
||||
With these new rules, you can still figure out the monkey business after
|
||||
10000 rounds. Using the same example above:
|
||||
|
||||
#+begin_example
|
||||
== After round 1 ==
|
||||
Monkey 0 inspected items 2 times.
|
||||
Monkey 1 inspected items 4 times.
|
||||
Monkey 2 inspected items 3 times.
|
||||
Monkey 3 inspected items 6 times.
|
||||
|
||||
== After round 20 ==
|
||||
Monkey 0 inspected items 99 times.
|
||||
Monkey 1 inspected items 97 times.
|
||||
Monkey 2 inspected items 8 times.
|
||||
Monkey 3 inspected items 103 times.
|
||||
|
||||
== After round 1000 ==
|
||||
Monkey 0 inspected items 5204 times.
|
||||
Monkey 1 inspected items 4792 times.
|
||||
Monkey 2 inspected items 199 times.
|
||||
Monkey 3 inspected items 5192 times.
|
||||
|
||||
== After round 2000 ==
|
||||
Monkey 0 inspected items 10419 times.
|
||||
Monkey 1 inspected items 9577 times.
|
||||
Monkey 2 inspected items 392 times.
|
||||
Monkey 3 inspected items 10391 times.
|
||||
|
||||
== After round 3000 ==
|
||||
Monkey 0 inspected items 15638 times.
|
||||
Monkey 1 inspected items 14358 times.
|
||||
Monkey 2 inspected items 587 times.
|
||||
Monkey 3 inspected items 15593 times.
|
||||
|
||||
== After round 4000 ==
|
||||
Monkey 0 inspected items 20858 times.
|
||||
Monkey 1 inspected items 19138 times.
|
||||
Monkey 2 inspected items 780 times.
|
||||
Monkey 3 inspected items 20797 times.
|
||||
|
||||
== After round 5000 ==
|
||||
Monkey 0 inspected items 26075 times.
|
||||
Monkey 1 inspected items 23921 times.
|
||||
Monkey 2 inspected items 974 times.
|
||||
Monkey 3 inspected items 26000 times.
|
||||
|
||||
== After round 6000 ==
|
||||
Monkey 0 inspected items 31294 times.
|
||||
Monkey 1 inspected items 28702 times.
|
||||
Monkey 2 inspected items 1165 times.
|
||||
Monkey 3 inspected items 31204 times.
|
||||
|
||||
== After round 7000 ==
|
||||
Monkey 0 inspected items 36508 times.
|
||||
Monkey 1 inspected items 33488 times.
|
||||
Monkey 2 inspected items 1360 times.
|
||||
Monkey 3 inspected items 36400 times.
|
||||
|
||||
== After round 8000 ==
|
||||
Monkey 0 inspected items 41728 times.
|
||||
Monkey 1 inspected items 38268 times.
|
||||
Monkey 2 inspected items 1553 times.
|
||||
Monkey 3 inspected items 41606 times.
|
||||
|
||||
== After round 9000 ==
|
||||
Monkey 0 inspected items 46945 times.
|
||||
Monkey 1 inspected items 43051 times.
|
||||
Monkey 2 inspected items 1746 times.
|
||||
Monkey 3 inspected items 46807 times.
|
||||
|
||||
== After round 10000 ==
|
||||
Monkey 0 inspected items 52166 times.
|
||||
Monkey 1 inspected items 47830 times.
|
||||
Monkey 2 inspected items 1938 times.
|
||||
Monkey 3 inspected items 52013 times.
|
||||
#+end_example
|
||||
|
||||
After 10000 rounds, the two most active monkeys inspected items 52166
|
||||
and 52013 times. Multiplying these together, the level of /monkey
|
||||
business/ in this situation is now =2713310158=.
|
||||
|
||||
Worry levels are no longer divided by three after each item is
|
||||
inspected; you'll need to find another way to keep your worry levels
|
||||
manageable. Starting again from the initial state in your puzzle input,
|
||||
/what is the level of monkey business after 10000 rounds?/
|
||||
|
||||
Your puzzle answer was =13119526120=.
|
||||
|
||||
Both parts of this puzzle are complete! They provide two gold stars: **
|
||||
164
2022/day11/aoc-c.c
Normal file
164
2022/day11/aoc-c.c
Normal file
@@ -0,0 +1,164 @@
|
||||
/* aoc-c.c: Advent of Code 2022, day 11
|
||||
*
|
||||
* Copyright (C) 2022 Bruno Raoult ("br")
|
||||
* Licensed under the GNU General Public License v3.0 or later.
|
||||
* Some rights reserved. See COPYING.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with this
|
||||
* program. If not, see <https://www.gnu.org/licenses/gpl-3.0-standalone.html>.
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later <https://spdx.org/licenses/GPL-3.0-or-later.html>
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "br.h"
|
||||
#include "debug.h"
|
||||
#include "list.h"
|
||||
#include "pool.h"
|
||||
|
||||
#include "aoc.h"
|
||||
|
||||
#define MAXMONKEYS 8
|
||||
|
||||
typedef struct monkey {
|
||||
char op; /* '+' or '*' */
|
||||
long values[2]; /* formula operands */
|
||||
uint visits; /* total visits */
|
||||
int div; /* divisor */
|
||||
struct list_head *dest[2]; /* destination monkey */
|
||||
struct list_head items; /* monkey items */
|
||||
} monkey_t;
|
||||
|
||||
typedef struct item {
|
||||
long item;
|
||||
struct list_head list;
|
||||
} item_t;
|
||||
|
||||
static pool_t *pool_item;
|
||||
|
||||
/* TODO: the following 3 variables should not be global
|
||||
*/
|
||||
static monkey_t monkeys[MAXMONKEYS];
|
||||
static int nmonkeys;
|
||||
static u64 lcm = 1;
|
||||
|
||||
static char *getnth(char *buf, int n)
|
||||
{
|
||||
char *ret;
|
||||
for (; n >= 0; n--) {
|
||||
ret = strtok(buf, " ,\n");
|
||||
buf = NULL;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static char *getnext()
|
||||
{
|
||||
return strtok(NULL, " ,\n");
|
||||
}
|
||||
|
||||
static int parse()
|
||||
{
|
||||
size_t alloc = 0;
|
||||
char *buf = NULL, *tok;
|
||||
monkey_t *m = monkeys;
|
||||
|
||||
while (getline(&buf, &alloc, stdin) > 0) {
|
||||
INIT_LIST_HEAD(&m->items);
|
||||
|
||||
getline(&buf, &alloc, stdin); /* starting items */
|
||||
tok = getnth(buf, 2);
|
||||
while (tok) {
|
||||
item_t *item = pool_get(pool_item);
|
||||
item->item = atoi(tok);
|
||||
list_add_tail(&item->list, &m->items);
|
||||
tok = getnext();
|
||||
}
|
||||
|
||||
getline(&buf, &alloc, stdin); /* operation */
|
||||
tok = getnth(buf, 3);
|
||||
m->values[0] = (*tok == 'o') ? -1: atoi(tok); /* first operand */
|
||||
m->op = *getnext(); /* operator */
|
||||
tok = getnext();
|
||||
m->values[1] = *tok == 'o' ? -1: atoi(tok); /* second operand */
|
||||
|
||||
getline(&buf, &alloc, stdin); /* divisible */
|
||||
m->div = atoi(getnth(buf, 3));
|
||||
lcm *= m->div;
|
||||
|
||||
getline(&buf, &alloc, stdin); /* true */
|
||||
m->dest[0] = &(monkeys + atoi(getnth(buf, 5)))->items;
|
||||
|
||||
getline(&buf, &alloc, stdin); /* false */
|
||||
m->dest[1] = &(monkeys + atoi(getnth(buf, 5)))->items;
|
||||
|
||||
getline(&buf, &alloc, stdin); /* skip empty line */
|
||||
|
||||
nmonkeys++;
|
||||
m++;
|
||||
}
|
||||
free(buf);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static __always_inline void inspect(monkey_t *m, int divide)
|
||||
{
|
||||
item_t *item, *tmp;
|
||||
long op1, op2;
|
||||
|
||||
list_for_each_entry_safe(item, tmp, &m->items, list) {
|
||||
m->visits++;
|
||||
/* I wonder if we could not find some mathematical properties to
|
||||
* simplify the following three lines
|
||||
*/
|
||||
op1 = m->values[0] < 0 ? item->item: m->values[0];
|
||||
op2 = m->values[1] < 0 ? item->item: m->values[1];
|
||||
item->item = (((m->op == '+')? op1 + op2: op1 * op2) / divide ) % lcm;
|
||||
list_move_tail(&item->list, m->dest[!!(item->item % m->div)]);
|
||||
}
|
||||
}
|
||||
|
||||
static u64 doit(int rounds, int divide)
|
||||
{
|
||||
u64 max1 = 0, max2 = 0;
|
||||
monkey_t *m = monkeys;
|
||||
|
||||
for (int r = 0; r < rounds; ++r)
|
||||
for (int i = 0; i < nmonkeys; ++i)
|
||||
inspect(monkeys + i, divide);
|
||||
|
||||
for (int i = 0; i < nmonkeys; ++i, m++) {
|
||||
if (m->visits > max1) {
|
||||
max2 = max1;
|
||||
max1 = m->visits;
|
||||
} else if (m->visits > max2) {
|
||||
max2 = m->visits;
|
||||
}
|
||||
}
|
||||
return max1 * max2;
|
||||
}
|
||||
|
||||
static u64 part1()
|
||||
{
|
||||
return doit(20, 3);
|
||||
}
|
||||
|
||||
static u64 part2()
|
||||
{
|
||||
return doit(10000, 1);
|
||||
}
|
||||
|
||||
|
||||
int main(int ac, char **av)
|
||||
{
|
||||
int part = parseargs(ac, av);
|
||||
pool_item = pool_create("item", 64, sizeof(item_t));
|
||||
|
||||
parse();
|
||||
printf("%s: res=%lu\n", *av, part == 1? part1(): part2());
|
||||
pool_destroy(pool_item);
|
||||
exit(0);
|
||||
}
|
||||
86
2022/day11/aoc.bash
Executable file
86
2022/day11/aoc.bash
Executable file
@@ -0,0 +1,86 @@
|
||||
#!/usr/bin/env bash
|
||||
#
|
||||
# aoc.bash: Advent of Code 2022, day 11
|
||||
#
|
||||
# Copyright (C) 2022 Bruno Raoult ("br")
|
||||
# Licensed under the GNU General Public License v3.0 or later.
|
||||
# Some rights reserved. See COPYING.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License along with this
|
||||
# program. If not, see <https://www.gnu.org/licenses/gpl-3.0-standalone.html>.
|
||||
#
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later <https://spdx.org/licenses/GPL-3.0-or-later.html>
|
||||
|
||||
. common.bash
|
||||
|
||||
declare -ai div ttrue tfalse vis
|
||||
declare -a it # (1 2) is "1 2"
|
||||
declare -a op1 op op2
|
||||
declare -i lcm=1 monks=0 divisor=3
|
||||
|
||||
calc() {
|
||||
local -n _res="$1"
|
||||
local -i _m1=0 _m2=0 _i
|
||||
|
||||
for _i in "${vis[@]}"; do # find the 2 biggest numbers
|
||||
if ((_i > _m1)); then
|
||||
((_m2 = _m1, _m1 = _i))
|
||||
elif ((_i > _m2)); then
|
||||
((_m2 = _i))
|
||||
fi
|
||||
done
|
||||
(( _res = _m1 * _m2 ))
|
||||
}
|
||||
|
||||
parse() {
|
||||
local -a _it
|
||||
|
||||
while read -r; do # ignore Monkey number
|
||||
IFS=" :," read -ra _it # starting items
|
||||
it[$monks]="${_it[*]:2}"
|
||||
IFS=" :=" read -r _ _ op1[$monks] op[$monks] op2[$monks]
|
||||
[[ ${op[$monks]} == "+" ]] && unset "op[$monks]"
|
||||
[[ ${op1[$monks]} == old ]] && unset "op1[$monks]"
|
||||
[[ ${op2[$monks]} == old ]] && unset "op2[$monks]"
|
||||
IFS=" :=" read -r _ _ _ div[$monks] # divisor
|
||||
(( lcm *= div[monks] ))
|
||||
read -r _ _ _ _ _ ttrue[$monks] # throw if true
|
||||
read -r _ _ _ _ _ tfalse[$monks]
|
||||
read -r
|
||||
(( monks++ ))
|
||||
done
|
||||
}
|
||||
|
||||
solve() {
|
||||
local -i _loops=20 round m _op1 _op2 i
|
||||
|
||||
(( part == 2 )) && (( _loops = 10000, divisor = 1 ))
|
||||
for ((round = 0; round < _loops; ++round)); do
|
||||
for ((m = 0; m < monks; ++m)); do
|
||||
_op1=${op1[$m]}
|
||||
_op2=${op2[$m]}
|
||||
|
||||
# shellcheck disable=SC2068
|
||||
for i in ${it[$m]}; do
|
||||
(( vis[m]++ ))
|
||||
[[ -v op1[$m] ]] || _op1=$i
|
||||
[[ -v op2[$m] ]] || _op2=$i
|
||||
if [[ -v op[$m] ]]; then
|
||||
(( _tmp = (_op1 * _op2) / divisor % lcm ))
|
||||
else
|
||||
(( _tmp = (_op1 + _op2) / divisor % lcm ))
|
||||
fi
|
||||
if (( _tmp % div[m] )); then
|
||||
it[${tfalse[$m]}]+=" $_tmp"
|
||||
else
|
||||
it[${ttrue[$m]}]+=" $_tmp"
|
||||
fi
|
||||
done
|
||||
it[$m]=""
|
||||
done
|
||||
done
|
||||
calc res
|
||||
}
|
||||
|
||||
main "$@"
|
||||
exit 0
|
||||
17
2022/day11/aoc.h
Normal file
17
2022/day11/aoc.h
Normal file
@@ -0,0 +1,17 @@
|
||||
/* aoc.c: Advent of Code 2022
|
||||
*
|
||||
* Copyright (C) 2022 Bruno Raoult ("br")
|
||||
* Licensed under the GNU General Public License v3.0 or later.
|
||||
* Some rights reserved. See COPYING.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with this
|
||||
* program. If not, see <https://www.gnu.org/licenses/gpl-3.0-standalone.html>.
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later <https://spdx.org/licenses/GPL-3.0-or-later.html>
|
||||
*/
|
||||
#ifndef _AOC_H_
|
||||
#define _AOC_H_
|
||||
|
||||
extern int parseargs(int ac, char**av);
|
||||
|
||||
#endif /* _AOC_H_ */
|
||||
68
2022/day11/common.bash
Normal file
68
2022/day11/common.bash
Normal file
@@ -0,0 +1,68 @@
|
||||
#!/usr/bin/env bash
|
||||
#
|
||||
# common.bash: Advent of Code 2022, common bash functions
|
||||
#
|
||||
# Copyright (C) 2022 Bruno Raoult ("br")
|
||||
# Licensed under the GNU General Public License v3.0 or later.
|
||||
# Some rights reserved. See COPYING.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License along with this
|
||||
# program. If not, see <https://www.gnu.org/licenses/gpl-3.0-standalone.html>.
|
||||
#
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later <https://spdx.org/licenses/GPL-3.0-or-later.html>
|
||||
|
||||
# shellcheck disable=2034
|
||||
export cmdname=${0##*/}
|
||||
export debug=0
|
||||
export res
|
||||
export LANG=C
|
||||
|
||||
shopt -s extglob
|
||||
set -o noglob
|
||||
|
||||
usage() {
|
||||
printf "usage: %s [-d DEBUG] [-p PART]\n" "$cmdname"
|
||||
exit 1
|
||||
}
|
||||
|
||||
checkargs() {
|
||||
local part=1
|
||||
while getopts p:d: todo; do
|
||||
case "$todo" in
|
||||
d)
|
||||
if [[ "$OPTARG" =~ ^[[:digit:]+]$ ]]; then
|
||||
debug="$OPTARG"
|
||||
else
|
||||
printf "%s: illegal [%s] debug level.\n" "$CMD" "$OPTARG"
|
||||
exit 1
|
||||
fi
|
||||
;;
|
||||
p)
|
||||
if [[ "$OPTARG" =~ ^[12]$ ]]; then
|
||||
part="$OPTARG"
|
||||
else
|
||||
printf "%s: illegal [%s] part.\n" "$CMD" "$OPTARG"
|
||||
exit 1
|
||||
fi
|
||||
;;
|
||||
*)
|
||||
usage
|
||||
;;
|
||||
esac
|
||||
done
|
||||
# Now check remaining argument (backup directory)
|
||||
shift $((OPTIND - 1))
|
||||
|
||||
(( $# > 1 )) && usage
|
||||
return "$part"
|
||||
}
|
||||
|
||||
main() {
|
||||
local -i part
|
||||
|
||||
checkargs "$@"
|
||||
part=$?
|
||||
parse "$part"
|
||||
solve "$part"
|
||||
printf "%s: res=%s\n" "$cmdname" "$res"
|
||||
}
|
||||
49
2022/day11/common.c
Normal file
49
2022/day11/common.c
Normal file
@@ -0,0 +1,49 @@
|
||||
/* common.c: Advent of Code 2022, common functions
|
||||
*
|
||||
* Copyright (C) 2022 Bruno Raoult ("br")
|
||||
* Licensed under the GNU General Public License v3.0 or later.
|
||||
* Some rights reserved. See COPYING.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with this
|
||||
* program. If not, see <https://www.gnu.org/licenses/gpl-3.0-standalone.html>.
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later <https://spdx.org/licenses/GPL-3.0-or-later.html>
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "aoc.h"
|
||||
#include "debug.h"
|
||||
|
||||
static int usage(char *prg)
|
||||
{
|
||||
fprintf(stderr, "Usage: %s [-d debug_level] [-p part] [-i input]\n", prg);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int parseargs(int ac, char **av)
|
||||
{
|
||||
int opt, part = 1;
|
||||
|
||||
while ((opt = getopt(ac, av, "d:p:")) != -1) {
|
||||
switch (opt) {
|
||||
case 'd':
|
||||
debug_level_set(atoi(optarg));
|
||||
break;
|
||||
case 'p': /* 1 or 2 */
|
||||
part = atoi(optarg);
|
||||
if (part < 1 || part > 2)
|
||||
return usage(*av);
|
||||
break;
|
||||
case 'i':
|
||||
|
||||
default:
|
||||
return usage(*av);
|
||||
}
|
||||
}
|
||||
if (optind < ac)
|
||||
return usage(*av);
|
||||
return part;
|
||||
}
|
||||
27
2022/day11/input/example.txt
Normal file
27
2022/day11/input/example.txt
Normal file
@@ -0,0 +1,27 @@
|
||||
Monkey 0:
|
||||
Starting items: 79, 98
|
||||
Operation: new = old * 19
|
||||
Test: divisible by 23
|
||||
If true: throw to monkey 2
|
||||
If false: throw to monkey 3
|
||||
|
||||
Monkey 1:
|
||||
Starting items: 54, 65, 75, 74
|
||||
Operation: new = old + 6
|
||||
Test: divisible by 19
|
||||
If true: throw to monkey 2
|
||||
If false: throw to monkey 0
|
||||
|
||||
Monkey 2:
|
||||
Starting items: 79, 60, 97
|
||||
Operation: new = old * old
|
||||
Test: divisible by 13
|
||||
If true: throw to monkey 1
|
||||
If false: throw to monkey 3
|
||||
|
||||
Monkey 3:
|
||||
Starting items: 74
|
||||
Operation: new = old + 3
|
||||
Test: divisible by 17
|
||||
If true: throw to monkey 0
|
||||
If false: throw to monkey 1
|
||||
55
2022/day11/input/input.txt
Normal file
55
2022/day11/input/input.txt
Normal file
@@ -0,0 +1,55 @@
|
||||
Monkey 0:
|
||||
Starting items: 98, 70, 75, 80, 84, 89, 55, 98
|
||||
Operation: new = old * 2
|
||||
Test: divisible by 11
|
||||
If true: throw to monkey 1
|
||||
If false: throw to monkey 4
|
||||
|
||||
Monkey 1:
|
||||
Starting items: 59
|
||||
Operation: new = old * old
|
||||
Test: divisible by 19
|
||||
If true: throw to monkey 7
|
||||
If false: throw to monkey 3
|
||||
|
||||
Monkey 2:
|
||||
Starting items: 77, 95, 54, 65, 89
|
||||
Operation: new = old + 6
|
||||
Test: divisible by 7
|
||||
If true: throw to monkey 0
|
||||
If false: throw to monkey 5
|
||||
|
||||
Monkey 3:
|
||||
Starting items: 71, 64, 75
|
||||
Operation: new = old + 2
|
||||
Test: divisible by 17
|
||||
If true: throw to monkey 6
|
||||
If false: throw to monkey 2
|
||||
|
||||
Monkey 4:
|
||||
Starting items: 74, 55, 87, 98
|
||||
Operation: new = old * 11
|
||||
Test: divisible by 3
|
||||
If true: throw to monkey 1
|
||||
If false: throw to monkey 7
|
||||
|
||||
Monkey 5:
|
||||
Starting items: 90, 98, 85, 52, 91, 60
|
||||
Operation: new = old + 7
|
||||
Test: divisible by 5
|
||||
If true: throw to monkey 0
|
||||
If false: throw to monkey 4
|
||||
|
||||
Monkey 6:
|
||||
Starting items: 99, 51
|
||||
Operation: new = old + 1
|
||||
Test: divisible by 13
|
||||
If true: throw to monkey 5
|
||||
If false: throw to monkey 2
|
||||
|
||||
Monkey 7:
|
||||
Starting items: 98, 94, 59, 76, 51, 65, 75
|
||||
Operation: new = old + 5
|
||||
Test: divisible by 2
|
||||
If true: throw to monkey 3
|
||||
If false: throw to monkey 6
|
||||
114
2022/day12/Makefile
Normal file
114
2022/day12/Makefile
Normal file
@@ -0,0 +1,114 @@
|
||||
# AOC daily Makefile - GNU make only.
|
||||
#
|
||||
# Copyright (C) 2021-2022 Bruno Raoult ("br")
|
||||
# Licensed under the GNU General Public License v3.0 or later.
|
||||
# Some rights reserved. See COPYING.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License along with this
|
||||
# program. If not, see <https://www.gnu.org/licenses/gpl-3.0-standalone.html>.
|
||||
#
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later <https://spdx.org/licenses/GPL-3.0-or-later.html>
|
||||
#
|
||||
|
||||
INPUT := input/input.txt
|
||||
SHELL := /bin/bash
|
||||
|
||||
CC := gcc
|
||||
BEAR := bear
|
||||
CCLSFILE:= compile_commands.json
|
||||
|
||||
LIB := aoc_$(shell uname -m)
|
||||
INCDIR := ../include
|
||||
LIBDIR := ../lib
|
||||
LDFLAGS := -L$(LIBDIR)
|
||||
#LDLIB := -l$(LIB) -lm
|
||||
LDLIB := -l$(LIB)
|
||||
|
||||
export LD_LIBRARY_PATH = $(LIBDIR)
|
||||
|
||||
CFLAGS += -std=gnu11
|
||||
CFLAGS += -O2
|
||||
#CFLAGS += -g
|
||||
# for gprof
|
||||
# CFLAGS += -pg
|
||||
CFLAGS += -Wall
|
||||
CFLAGS += -Wextra
|
||||
CFLAGS += -march=native
|
||||
# Next one may be useful for valgrind (some invalid instructions)
|
||||
# CFLAGS += -mno-tbm
|
||||
CFLAGS += -Wmissing-declarations
|
||||
CFLAGS += -Wno-unused-result
|
||||
|
||||
CFLAGS += -DDEBUG_DEBUG # activate general debug (debug.c)
|
||||
CFLAGS += -DDEBUG_POOL # memory pools management
|
||||
|
||||
VALGRIND := valgrind
|
||||
VALGRINDFLAGS := --leak-check=full --show-leak-kinds=all --track-origins=yes \
|
||||
--sigill-diagnostics=yes --quiet --show-error-list=yes
|
||||
|
||||
|
||||
TIME := \time -f "\ttime: %E real, %U user, %S sys\n\tcontext-switch:\t%c+%w, page-faults: %F+%R\n"
|
||||
export PATH := .:$(PATH)
|
||||
|
||||
.PHONY: clean cleanall all compile assembly memcheck memcheck1 memcheck2 part1 part2 ccls bear org
|
||||
|
||||
all: README.org ccls part1 part2
|
||||
|
||||
memcheck: memcheck1 memcheck2
|
||||
|
||||
memcheck1: aoc-c
|
||||
@$(VALGRIND) $(VALGRINDFLAGS) aoc-c -p 1 < $(INPUT)
|
||||
|
||||
memcheck2: aoc-c
|
||||
@$(VALGRIND) $(VALGRINDFLAGS) aoc-c -p 2 < $(INPUT)
|
||||
@#@valgrind -s --track-origins=yes aoc-c -p 2 < $(INPUT)
|
||||
|
||||
compile: aoc-c
|
||||
|
||||
cpp: aoc-c.i
|
||||
|
||||
assembly: aoc-c.s
|
||||
|
||||
part1: aoc-c
|
||||
@$(TIME) aoc.bash -p 1 < $(INPUT) 2>&1
|
||||
@$(TIME) aoc-c -p 1 < $(INPUT)
|
||||
|
||||
part2: aoc-c
|
||||
@$(TIME) aoc.bash -p 2 < $(INPUT) 2>&1
|
||||
@$(TIME) aoc-c -p 2 < $(INPUT)
|
||||
|
||||
ccls: $(CCLSFILE)
|
||||
|
||||
clean:
|
||||
@rm -f aoc-c core* vgcore* gmon.out aoc-c.s aoc-c.i README.html
|
||||
|
||||
cleanall: clean
|
||||
@rm -f compile_commands.json
|
||||
|
||||
aoc-c: aoc-c.c common.c
|
||||
@echo compiling $<
|
||||
$(CC) $(CFLAGS) $(LDFLAGS) -I $(INCDIR) $^ $(LDLIB) -o $@
|
||||
|
||||
# generate pre-processed file (.i) and assembler (.s)
|
||||
%.i: %.c
|
||||
@echo generating $@
|
||||
@$(CC) -E $(CFLAGS) -I $(INCDIR) $< -o $@
|
||||
|
||||
%.s: %.c
|
||||
@echo generating $@
|
||||
@$(CC) -S -fverbose-asm $(CFLAGS) -I $(INCDIR) $< -o $@
|
||||
|
||||
# generate README.org from README.html (must cleanup !)
|
||||
org: README.org
|
||||
|
||||
%.org: %.html
|
||||
@echo generating $@. Cleanup before commit !
|
||||
@pandoc $< -o $@
|
||||
|
||||
# generate compile_commands.json
|
||||
$(CCLSFILE): aoc-c.c Makefile
|
||||
$(BEAR) -- make clean compile
|
||||
|
||||
bear: clean
|
||||
@touch .ccls-root
|
||||
@$(BEAR) -- make compile
|
||||
100
2022/day12/README.org
Normal file
100
2022/day12/README.org
Normal file
@@ -0,0 +1,100 @@
|
||||
** --- Day 12: Hill Climbing Algorithm ---
|
||||
You try contacting the Elves using your handheld device, but the river
|
||||
you're following must be too low to get a decent signal.
|
||||
|
||||
You ask the device for a heightmap of the surrounding area (your puzzle
|
||||
input). The heightmap shows the local area from above broken into a
|
||||
grid; the elevation of each square of the grid is given by a single
|
||||
lowercase letter, where =a= is the lowest elevation, =b= is the
|
||||
next-lowest, and so on up to the highest elevation, =z=.
|
||||
|
||||
Also included on the heightmap are marks for your current position (=S=)
|
||||
and the location that should get the best signal (=E=). Your current
|
||||
position (=S=) has elevation =a=, and the location that should get the
|
||||
best signal (=E=) has elevation =z=.
|
||||
|
||||
You'd like to reach =E=, but to save energy, you should do it in /as few
|
||||
steps as possible/. During each step, you can move exactly one square
|
||||
up, down, left, or right. To avoid needing to get out your climbing
|
||||
gear, the elevation of the destination square can be /at most one
|
||||
higher/ than the elevation of your current square; that is, if your
|
||||
current elevation is =m=, you could step to elevation =n=, but not to
|
||||
elevation =o=. (This also means that the elevation of the destination
|
||||
square can be much lower than the elevation of your current square.)
|
||||
|
||||
For example:
|
||||
|
||||
#+begin_example
|
||||
Sabqponm
|
||||
abcryxxl
|
||||
accszExk
|
||||
acctuvwj
|
||||
abdefghi
|
||||
#+end_example
|
||||
|
||||
Here, you start in the top-left corner; your goal is near the middle.
|
||||
You could start by moving down or right, but eventually you'll need to
|
||||
head toward the =e= at the bottom. From there, you can spiral around to
|
||||
the goal:
|
||||
|
||||
#+begin_example
|
||||
v..v<<<<
|
||||
>v.vv<<^
|
||||
.>vv>E^^
|
||||
..v>>>^^
|
||||
..>>>>>^
|
||||
#+end_example
|
||||
|
||||
In the above diagram, the symbols indicate whether the path exits each
|
||||
square moving up (=^=), down (=v=), left (=<=), or right (=>=). The
|
||||
location that should get the best signal is still =E=, and =.= marks
|
||||
unvisited squares.
|
||||
|
||||
This path reaches the goal in =31= steps, the fewest possible.
|
||||
|
||||
/What is the fewest steps required to move from your current position to
|
||||
the location that should get the best signal?/
|
||||
|
||||
Your puzzle answer was =408=.
|
||||
|
||||
** --- Part Two ---
|
||||
As you walk up the hill, you suspect that the Elves will want to turn
|
||||
this into a hiking trail. The beginning isn't very scenic, though;
|
||||
perhaps you can find a better starting point.
|
||||
|
||||
To maximize exercise while hiking, the trail should start as low as
|
||||
possible: elevation =a=. The goal is still the square marked =E=.
|
||||
However, the trail should still be direct, taking the fewest steps to
|
||||
reach its goal. So, you'll need to find the shortest path from /any
|
||||
square at elevation =a=/ to the square marked =E=.
|
||||
|
||||
Again consider the example from above:
|
||||
|
||||
#+begin_example
|
||||
Sabqponm
|
||||
abcryxxl
|
||||
accszExk
|
||||
acctuvwj
|
||||
abdefghi
|
||||
#+end_example
|
||||
|
||||
Now, there are six choices for starting position (five marked =a=, plus
|
||||
the square marked =S= that counts as being at elevation =a=). If you
|
||||
start at the bottom-left square, you can reach the goal most quickly:
|
||||
|
||||
#+begin_example
|
||||
...v<<<<
|
||||
...vv<<^
|
||||
...v>E^^
|
||||
.>v>>>^^
|
||||
>^>>>>>^
|
||||
#+end_example
|
||||
|
||||
This path reaches the goal in only =29= steps, the fewest possible.
|
||||
|
||||
/What is the fewest steps required to move starting from any square with
|
||||
elevation =a= to the location that should get the best signal?/
|
||||
|
||||
Your puzzle answer was =399=.
|
||||
|
||||
Both parts of this puzzle are complete! They provide two gold stars: **
|
||||
172
2022/day12/aoc-c.c
Normal file
172
2022/day12/aoc-c.c
Normal file
@@ -0,0 +1,172 @@
|
||||
/* aoc-c.c: Advent of Code 2022, day 12
|
||||
*
|
||||
* Copyright (C) 2022 Bruno Raoult ("br")
|
||||
* Licensed under the GNU General Public License v3.0 or later.
|
||||
* Some rights reserved. See COPYING.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with this
|
||||
* program. If not, see <https://www.gnu.org/licenses/gpl-3.0-standalone.html>.
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later <https://spdx.org/licenses/GPL-3.0-or-later.html>
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "br.h"
|
||||
#include "list.h"
|
||||
#include "pool.h"
|
||||
|
||||
#include "aoc.h"
|
||||
|
||||
#define MAX_LINES 128 /* should be dynamic */
|
||||
|
||||
typedef struct coord {
|
||||
int x, y;
|
||||
} coord_t;
|
||||
|
||||
typedef struct square {
|
||||
char height;
|
||||
int dfs;
|
||||
coord_t coord;
|
||||
struct list_head queue;
|
||||
} square_t;
|
||||
|
||||
typedef struct grid {
|
||||
int nx, ny;
|
||||
coord_t start, end;
|
||||
|
||||
square_t **map;
|
||||
} grid_t;
|
||||
|
||||
pool_t *pool_lines;
|
||||
LIST_HEAD(dfs);
|
||||
|
||||
#define CELL(g, x, y) (&(g)->map[y][x])
|
||||
|
||||
static inline void push(square_t *s)
|
||||
{
|
||||
list_add_tail(&s->queue, &dfs);
|
||||
}
|
||||
|
||||
static inline square_t *pop()
|
||||
{
|
||||
square_t *s = list_first_entry_or_null(&dfs, square_t, queue);
|
||||
if (s)
|
||||
list_del(&s->queue);
|
||||
return s;
|
||||
}
|
||||
|
||||
static int parse(grid_t *grid)
|
||||
{
|
||||
size_t alloc = 0;
|
||||
ssize_t buflen;
|
||||
char *buf = NULL;
|
||||
int line = 0;
|
||||
square_t *pline;
|
||||
|
||||
while ((buflen = getline(&buf, &alloc, stdin)) > 0) {
|
||||
buf[--buflen] = 0;
|
||||
if (line == 0) {
|
||||
pool_lines = pool_create("lines", 128, buflen * sizeof(square_t));
|
||||
grid->nx = buflen;
|
||||
}
|
||||
grid->map[line] = pool_get(pool_lines);
|
||||
pline = grid->map[line];
|
||||
for (int i = 0; i < buflen; ++i) {
|
||||
pline[i].coord.x = i;
|
||||
pline[i].coord.y = line;
|
||||
pline[i].dfs = 0;
|
||||
if (buf[i] == 'S') {
|
||||
grid->start.x = i;
|
||||
grid->start.y = line;
|
||||
pline[i].height = 'a';
|
||||
} else if (buf[i] == 'E') {
|
||||
grid->end.x = i;
|
||||
grid->end.y = line;
|
||||
pline[i].height = 'z';
|
||||
} else {
|
||||
pline[i].height = buf[i];
|
||||
}
|
||||
}
|
||||
line++;
|
||||
}
|
||||
grid->ny = line;
|
||||
free(buf);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static square_t *dfs_add(grid_t *g, square_t *s, int n)
|
||||
{
|
||||
static coord_t dirs[4] = { { 0, -1 }, { 1, 0 }, { 0, 1 }, { -1, 0 } };
|
||||
int x = s->coord.x + dirs[n].x, y = s->coord.y + dirs[n].y;
|
||||
square_t *ret = NULL;
|
||||
if (x >= 0 && y >= 0 && x < g->nx && y < g->ny) {
|
||||
ret = CELL(g, x, y);
|
||||
if (!ret->dfs)
|
||||
return ret;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int part1(grid_t *g)
|
||||
{
|
||||
square_t *s, *n;
|
||||
|
||||
s = CELL(g, g->start.x, g->start.y);
|
||||
s->dfs = 1;
|
||||
push(s);
|
||||
while((s = pop())) {
|
||||
//log_f(3, "");
|
||||
for (int i = 0; i < 4; i++) {
|
||||
if (!(n = dfs_add(g, s, i)))
|
||||
continue;
|
||||
if (n->height <= s->height+1) {
|
||||
if (n->coord.x == g->end.x && n->coord.y == g->end.y)
|
||||
return s->dfs;
|
||||
n->dfs = s->dfs + 1;
|
||||
push(n);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int part2(grid_t *g)
|
||||
{
|
||||
square_t *s, *n;
|
||||
//int ret = 0;
|
||||
s = CELL(g, g->end.x, g->end.y);
|
||||
s->dfs = 1;
|
||||
push(s);
|
||||
while((s = pop())) {
|
||||
//log_f(3, "");
|
||||
for (int i = 0; i < 4; i++) {
|
||||
if (!(n = dfs_add(g, s, i)))
|
||||
continue;
|
||||
if (n->height >= s->height - 1) {
|
||||
if (n->height == 'a')
|
||||
return s->dfs;
|
||||
n->dfs = s->dfs + 1;
|
||||
push(n);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
int main(int ac, char **av)
|
||||
{
|
||||
int part = parseargs(ac, av);
|
||||
square_t *board[MAX_LINES];
|
||||
grid_t grid = { 0, 0, { 0, 0 }, {0, 0}, board };
|
||||
|
||||
parse(&grid);
|
||||
printf("%s: res=%d\n", *av, part == 1? part1(&grid): part2(&grid));
|
||||
pool_destroy(pool_lines);
|
||||
exit(0);
|
||||
}
|
||||
146
2022/day12/aoc.bash
Executable file
146
2022/day12/aoc.bash
Executable file
@@ -0,0 +1,146 @@
|
||||
#!/usr/bin/env bash
|
||||
#
|
||||
# aoc.bash: Advent of Code 2022, day 12
|
||||
#
|
||||
# Copyright (C) 2022 Bruno Raoult ("br")
|
||||
# Licensed under the GNU General Public License v3.0 or later.
|
||||
# Some rights reserved. See COPYING.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License along with this
|
||||
# program. If not, see <https://www.gnu.org/licenses/gpl-3.0-standalone.html>.
|
||||
#
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later <https://spdx.org/licenses/GPL-3.0-or-later.html>
|
||||
|
||||
. common.bash
|
||||
|
||||
#declare -a map map2
|
||||
declare -A height map visited
|
||||
declare -i X Y
|
||||
declare start end push=push1
|
||||
declare -a queue
|
||||
|
||||
printmap() {
|
||||
local -i x y
|
||||
for (( y = 0; y < Y; ++y )); do
|
||||
for (( x = 0; x < X; ++x )); do
|
||||
printf "%2d " "${map["$x,$y"]}"
|
||||
done
|
||||
echo
|
||||
done
|
||||
}
|
||||
|
||||
printvis() {
|
||||
local -i x y
|
||||
for (( y = 0; y < Y; ++y )); do
|
||||
for (( x = 0; x < X; ++x )); do
|
||||
printf "%2d " "${visited["$x,$y"]}"
|
||||
done
|
||||
echo
|
||||
done
|
||||
}
|
||||
|
||||
push1() { # push part 1
|
||||
local -i _d="$1" _x="$2" _y="$3" _h="$4"
|
||||
local _c="$_x,$_y"
|
||||
if (( !visited[$_c] && map[$_c] <= (_h + 1) )); then
|
||||
(( _d++ ))
|
||||
visited["$_c"]=$_d
|
||||
queue+=("$_d:$_c")
|
||||
fi
|
||||
}
|
||||
|
||||
push2() { # push part 2
|
||||
local -i _d="$1" _x="$2" _y="$3" _h="$4"
|
||||
local _c="$_x,$_y"
|
||||
if (( !visited[$_c] && map[$_c] >= (_h - 1) )); then
|
||||
(( _d++ ))
|
||||
visited["$_c"]=$_d
|
||||
queue+=("$_d:$_c")
|
||||
fi
|
||||
}
|
||||
|
||||
pop() {
|
||||
local -n _d="$1" _x="$2" _y="$3"
|
||||
local head
|
||||
((!${#queue[@]})) && echo pop: queue empty. && exit 1
|
||||
head="${queue[0]}"
|
||||
_d=${head%:*}
|
||||
head=${head#*:}
|
||||
_x=${head%,*}
|
||||
_y=${head#*,}
|
||||
unset 'queue[0]'
|
||||
queue=("${queue[@]}")
|
||||
return 0
|
||||
}
|
||||
|
||||
# initialize height values
|
||||
init() {
|
||||
declare -i i=1
|
||||
for c in {a..z}; do
|
||||
(( height[$c] = i++ ))
|
||||
done
|
||||
height[S]=1
|
||||
height[E]=26
|
||||
}
|
||||
|
||||
parse() {
|
||||
local -i part="$1"
|
||||
local -a _map
|
||||
local -i x y
|
||||
local c
|
||||
((part == 2)) && push=push2
|
||||
|
||||
init
|
||||
readarray -t _map
|
||||
X=${#_map[0]}
|
||||
Y=${#_map[@]}
|
||||
# create array map[x,y]
|
||||
for (( y = 0; y < Y; ++y )); do
|
||||
for (( x = 0; x < X; ++x )); do
|
||||
c=${_map[$y]:x:1}
|
||||
map["$x,$y"]=${height[$c]}
|
||||
case "$c" in
|
||||
S) start="$x,$y"
|
||||
((part == 1)) && $push 0 "$x" "$y" 1
|
||||
;;
|
||||
E) end="$x,$y"
|
||||
((part == 2)) && $push 0 "$x" "$y" 1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
done
|
||||
}
|
||||
|
||||
solve() {
|
||||
local -i h d x y
|
||||
|
||||
while pop d x y; do
|
||||
(( h=${map["$x,$y"]} ))
|
||||
if [[ $part == 1 ]]; then
|
||||
if [[ "$x,$y" == "$end" ]]; then
|
||||
res=$((d-1))
|
||||
return
|
||||
fi
|
||||
else
|
||||
if [[ "${map["$x,$y"]}" == 1 ]]; then
|
||||
res=$((d-1))
|
||||
return
|
||||
fi
|
||||
fi
|
||||
if ((y > 0)); then # north
|
||||
$push "$d" "$x" "$((y-1))" "$h"
|
||||
fi
|
||||
if ((x+1 < X)); then # east
|
||||
$push "$d" "$((x+1))" "$y" "$h"
|
||||
fi
|
||||
if ((y+1 < Y)); then # south
|
||||
$push "$d" "$x" "$((y+1))" "$h"
|
||||
fi
|
||||
if ((x > 0)); then # west
|
||||
$push "$d" "$((x-1))" "$y" "$h"
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
main "$@"
|
||||
exit 0
|
||||
17
2022/day12/aoc.h
Normal file
17
2022/day12/aoc.h
Normal file
@@ -0,0 +1,17 @@
|
||||
/* aoc.c: Advent of Code 2022
|
||||
*
|
||||
* Copyright (C) 2022 Bruno Raoult ("br")
|
||||
* Licensed under the GNU General Public License v3.0 or later.
|
||||
* Some rights reserved. See COPYING.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with this
|
||||
* program. If not, see <https://www.gnu.org/licenses/gpl-3.0-standalone.html>.
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later <https://spdx.org/licenses/GPL-3.0-or-later.html>
|
||||
*/
|
||||
#ifndef _AOC_H_
|
||||
#define _AOC_H_
|
||||
|
||||
extern int parseargs(int ac, char**av);
|
||||
|
||||
#endif /* _AOC_H_ */
|
||||
68
2022/day12/common.bash
Normal file
68
2022/day12/common.bash
Normal file
@@ -0,0 +1,68 @@
|
||||
#!/usr/bin/env bash
|
||||
#
|
||||
# common.bash: Advent of Code 2022, common bash functions
|
||||
#
|
||||
# Copyright (C) 2022 Bruno Raoult ("br")
|
||||
# Licensed under the GNU General Public License v3.0 or later.
|
||||
# Some rights reserved. See COPYING.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License along with this
|
||||
# program. If not, see <https://www.gnu.org/licenses/gpl-3.0-standalone.html>.
|
||||
#
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later <https://spdx.org/licenses/GPL-3.0-or-later.html>
|
||||
|
||||
# shellcheck disable=2034
|
||||
export cmdname=${0##*/}
|
||||
export debug=0
|
||||
export res
|
||||
export LANG=C
|
||||
|
||||
shopt -s extglob
|
||||
set -o noglob
|
||||
|
||||
usage() {
|
||||
printf "usage: %s [-d DEBUG] [-p PART]\n" "$cmdname"
|
||||
exit 1
|
||||
}
|
||||
|
||||
checkargs() {
|
||||
local part=1
|
||||
while getopts p:d: todo; do
|
||||
case "$todo" in
|
||||
d)
|
||||
if [[ "$OPTARG" =~ ^[[:digit:]+]$ ]]; then
|
||||
debug="$OPTARG"
|
||||
else
|
||||
printf "%s: illegal [%s] debug level.\n" "$CMD" "$OPTARG"
|
||||
exit 1
|
||||
fi
|
||||
;;
|
||||
p)
|
||||
if [[ "$OPTARG" =~ ^[12]$ ]]; then
|
||||
part="$OPTARG"
|
||||
else
|
||||
printf "%s: illegal [%s] part.\n" "$CMD" "$OPTARG"
|
||||
exit 1
|
||||
fi
|
||||
;;
|
||||
*)
|
||||
usage
|
||||
;;
|
||||
esac
|
||||
done
|
||||
# Now check remaining argument (backup directory)
|
||||
shift $((OPTIND - 1))
|
||||
|
||||
(( $# > 1 )) && usage
|
||||
return "$part"
|
||||
}
|
||||
|
||||
main() {
|
||||
local -i part
|
||||
|
||||
checkargs "$@"
|
||||
part=$?
|
||||
parse "$part"
|
||||
solve "$part"
|
||||
printf "%s: res=%s\n" "$cmdname" "$res"
|
||||
}
|
||||
49
2022/day12/common.c
Normal file
49
2022/day12/common.c
Normal file
@@ -0,0 +1,49 @@
|
||||
/* common.c: Advent of Code 2022, common functions
|
||||
*
|
||||
* Copyright (C) 2022 Bruno Raoult ("br")
|
||||
* Licensed under the GNU General Public License v3.0 or later.
|
||||
* Some rights reserved. See COPYING.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with this
|
||||
* program. If not, see <https://www.gnu.org/licenses/gpl-3.0-standalone.html>.
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later <https://spdx.org/licenses/GPL-3.0-or-later.html>
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "aoc.h"
|
||||
#include "debug.h"
|
||||
|
||||
static int usage(char *prg)
|
||||
{
|
||||
fprintf(stderr, "Usage: %s [-d debug_level] [-p part] [-i input]\n", prg);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int parseargs(int ac, char **av)
|
||||
{
|
||||
int opt, part = 1;
|
||||
|
||||
while ((opt = getopt(ac, av, "d:p:")) != -1) {
|
||||
switch (opt) {
|
||||
case 'd':
|
||||
debug_level_set(atoi(optarg));
|
||||
break;
|
||||
case 'p': /* 1 or 2 */
|
||||
part = atoi(optarg);
|
||||
if (part < 1 || part > 2)
|
||||
return usage(*av);
|
||||
break;
|
||||
case 'i':
|
||||
|
||||
default:
|
||||
return usage(*av);
|
||||
}
|
||||
}
|
||||
if (optind < ac)
|
||||
return usage(*av);
|
||||
return part;
|
||||
}
|
||||
5
2022/day12/input/example.txt
Normal file
5
2022/day12/input/example.txt
Normal file
@@ -0,0 +1,5 @@
|
||||
Sabqponm
|
||||
abcryxxl
|
||||
accszExk
|
||||
acctuvwj
|
||||
abdefghi
|
||||
41
2022/day12/input/input.txt
Normal file
41
2022/day12/input/input.txt
Normal file
@@ -0,0 +1,41 @@
|
||||
abaaaaaccccccccccccccccccaaaaaaaaaaaaaccccaaaaaaaccccccccccccccccccccccccccccaaaaaa
|
||||
abaaaaaaccaaaacccccccccccaaaaaaaaacaaaacaaaaaaaaaacccccccccccccccccccccccccccaaaaaa
|
||||
abaaaaaacaaaaaccccccccccaaaaaaaaaaaaaaacaaaaaaaaaacccccccccccccaacccccccccccccaaaaa
|
||||
abaaaaaacaaaaaacccccccccaaaaaaaaaaaaaaccaaacaaaccccccccccccccccaacccccccccccccccaaa
|
||||
abccaaaccaaaaaacccaaaaccaaaaaaaaaaaaaccccaacaaacccccccccaacaccccacccccccccccccccaaa
|
||||
abcccccccaaaaaccccaaaacccccaaaaacccaaaccaaaaaaccccccccccaaaaccccccccccccccccccccaac
|
||||
abcccccccccaaaccccaaaacccccaaaaacccccccccaaaaaccccccccccklllllccccccccccccccccccccc
|
||||
abcccccccccccccccccaaccccccccaaccccccccaaaaaaaccccccccckklllllllcccccddccccaacccccc
|
||||
abaccccccccccccccccccccccccccaaccccccccaaaaaaaaccccccckkkklslllllcccddddddaaacccccc
|
||||
abacccccccccccccccccccccccccccccccaaaccaaaaaaaaccccccckkkssssslllllcddddddddacccccc
|
||||
abaccccccccccccccccccccccccccccccccaaaaccaaacaccccccckkksssssssslllmmmmmdddddaacccc
|
||||
abcccccccccccccccaaacccccccccccccaaaaaaccaacccccccccckkkssssusssslmmmmmmmdddddacccc
|
||||
abcccccccaaccccaaaaacccccccccccccaaaaaccccccaaaaaccckkkrssuuuussssqmmmmmmmmdddccccc
|
||||
abcccccccaaccccaaaaaacccccccaaccccaaaaacccccaaaaacckkkkrruuuuuussqqqqqqmmmmdddccccc
|
||||
abccccaaaaaaaacaaaaaacccccccaaaaccaaccaccccaaaaaacjkkkrrruuuxuuusqqqqqqqmmmmeeccccc
|
||||
abcaaaaaaaaaaacaaaaaccccccaaaaaacccccaaccccaaaaajjjjrrrrruuuxxuvvvvvvvqqqmmmeeccccc
|
||||
abcaacccaaaaccccaaaaaaacccaaaaacccacaaaccccaaaajjjjrrrrruuuxxxxvvvvvvvqqqmmeeeccccc
|
||||
abaaaaccaaaaacccccccaaaccccaaaaacaaaaaaaacccaajjjjrrrrtuuuuxxxyvyyyvvvqqqnneeeccccc
|
||||
abaaaaaaaaaaacccaaaaaaaccccaacaacaaaaaaaacccccjjjrrrttttuxxxxxyyyyyvvvqqnnneeeccccc
|
||||
abaaaaaaaccaacccaaaaaaaaacccccccccaaaaaaccccccjjjrrrtttxxxxxxxyyyyyvvvqqnnneeeccccc
|
||||
SbaaaaaacccccccccaaaaaaaaaccccccccaaaaacccccccjjjrrrtttxxxEzzzzyyyvvrrrnnneeecccccc
|
||||
abaaaaacccccccccccaaaaaaacccccccccaaaaaaccccccjjjqqqtttxxxxxyyyyyvvvrrrnnneeecccccc
|
||||
abaaacccccccccccaaaaaaaccaaccccccccccaaccaaaaajjjqqqttttxxxxyyyyyyvvrrrnnneeecccccc
|
||||
abaaacccccccccccaaaaaaaccaaacaaacccccccccaaaaajjjjqqqtttttxxyywyyyywvrrnnnfeecccccc
|
||||
abcaaacccccccaaaaaaaaaaacaaaaaaaccccccccaaaaaaciiiiqqqqtttxwyywwyywwwrrrnnfffcccccc
|
||||
abcccccccccccaaaaaaaaaaccaaaaaacccccccccaaaaaacciiiiqqqqttwwywwwwwwwwrrrnnfffcccccc
|
||||
abccccccccccccaaaaaacccaaaaaaaacccccccccaaaaaaccciiiiqqqttwwwwwswwwwrrrrnnfffcccccc
|
||||
abccccccccccccaaaaaacccaaaaaaaaacccccccccaaacccccciiiqqqtswwwwssssrrrrrroofffcccccc
|
||||
abccccccaaaaacaaaaaacccaaaaaaaaaaccccccccccccccccciiiqqqssswsssssssrrrrooofffaccccc
|
||||
abccccccaaaaacaaccaaccccccaaacaaacccccccccccccccccciiiqqssssssspoorrrooooofffaacccc
|
||||
abcccccaaaaaacccccccccccccaaacccccccccccccccccccccciiiqppssssspppooooooooffffaacccc
|
||||
abcccccaaaaaacccccccccccccaacccccccccccccccccccccccciipppppppppppoooooooffffaaccccc
|
||||
abcccccaaaaaaccccccccccccccccccccccccccccccccccccccciihppppppppgggggggggfffaaaccccc
|
||||
abccccccaaacccccccccccccccccccccccaccccccccccccccccchhhhpppppphggggggggggfaaaaccccc
|
||||
abaaaccccccccccccccccccccccaccccaaacccccccccccccccccchhhhhhhhhhgggggggggcaacccccccc
|
||||
abaaccaaaccaccccccccccccccaaacccaaacaacccaaaaacccccccchhhhhhhhhgaaccccccccccccccccc
|
||||
abaaacaaacaacccccccccaaaccaaaacaaaaaaaaccaaaaaccccccccchhhhhhaaaaacccccccccccccccca
|
||||
abaaaccaaaaaccccccccccaaacaaaaaaaacaaaaccaaaaaaccccccccccaaacccaaaacccccccccccaccca
|
||||
abcccaaaaaaccccccccccaaaaaaaaaaaaacaaaaccaaaaaaccccccccccaaaccccaaaccccccccccaaaaaa
|
||||
abcccaaaaaaaacccccccaaaaaaaaaaaaaaaaaccccaaaaaacccccccccccccccccccccccccccccccaaaaa
|
||||
abcccaacaaaaaccccccaaaaaaaaaaaaaaaaaaacccccaacccccccccccccccccccccccccccccccccaaaaa
|
||||
111
2022/day13/Makefile
Normal file
111
2022/day13/Makefile
Normal file
@@ -0,0 +1,111 @@
|
||||
# AOC daily Makefile - GNU make only.
|
||||
#
|
||||
# Copyright (C) 2021-2022 Bruno Raoult ("br")
|
||||
# Licensed under the GNU General Public License v3.0 or later.
|
||||
# Some rights reserved. See COPYING.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License along with this
|
||||
# program. If not, see <https://www.gnu.org/licenses/gpl-3.0-standalone.html>.
|
||||
#
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later <https://spdx.org/licenses/GPL-3.0-or-later.html>
|
||||
#
|
||||
|
||||
INPUT := input/input.txt
|
||||
SHELL := /bin/bash
|
||||
|
||||
CC := gcc
|
||||
BEAR := bear
|
||||
CCLSFILE:= compile_commands.json
|
||||
|
||||
LIB := aoc_$(shell uname -m)
|
||||
INCDIR := ../include
|
||||
LIBDIR := ../lib
|
||||
LDFLAGS := -L$(LIBDIR)
|
||||
#LDLIB := -l$(LIB) -lm
|
||||
LDLIB := -l$(LIB)
|
||||
|
||||
export LD_LIBRARY_PATH = $(LIBDIR)
|
||||
|
||||
CFLAGS += -std=gnu11
|
||||
CFLAGS += -O2
|
||||
CFLAGS += -g
|
||||
# for gprof
|
||||
# CFLAGS += -pg
|
||||
CFLAGS += -Wall
|
||||
CFLAGS += -Wextra
|
||||
CFLAGS += -march=native
|
||||
# Next one may be useful for valgrind (some invalid instructions)
|
||||
# CFLAGS += -mno-tbm
|
||||
CFLAGS += -Wmissing-declarations
|
||||
CFLAGS += -Wno-unused-result
|
||||
|
||||
CFLAGS += -DDEBUG_DEBUG # activate general debug (debug.c)
|
||||
CFLAGS += -DDEBUG_POOL # memory pools management
|
||||
|
||||
VALGRIND := valgrind
|
||||
VALGRINDFLAGS := --leak-check=full --show-leak-kinds=all --track-origins=yes \
|
||||
--sigill-diagnostics=yes --quiet --show-error-list=yes
|
||||
|
||||
|
||||
TIME := \time -f "\ttime: %E real, %U user, %S sys\n\tcontext-switch:\t%c+%w, page-faults: %F+%R\n"
|
||||
export PATH := .:$(PATH)
|
||||
|
||||
.PHONY: clean all compile assembly memcheck memcheck1 memcheck2 part1 part2 ccls bear org
|
||||
|
||||
all: README.org ccls part1 part2
|
||||
|
||||
memcheck: memcheck1 memcheck2
|
||||
|
||||
memcheck1: aoc-c
|
||||
@$(VALGRIND) $(VALGRINDFLAGS) aoc-c -p 1 < $(INPUT)
|
||||
|
||||
memcheck2: aoc-c
|
||||
@$(VALGRIND) $(VALGRINDFLAGS) aoc-c -p 2 < $(INPUT)
|
||||
@#@valgrind -s --track-origins=yes aoc-c -p 2 < $(INPUT)
|
||||
|
||||
compile: aoc-c
|
||||
|
||||
cpp: aoc-c.i
|
||||
|
||||
assembly: aoc-c.s
|
||||
|
||||
part1: aoc-c
|
||||
@#$(TIME) aoc.bash -p 1 < $(INPUT) 2>&1
|
||||
@$(TIME) aoc-c -p 1 < $(INPUT)
|
||||
|
||||
part2: aoc-c
|
||||
@#$(TIME) aoc.bash -p 2 < $(INPUT) 2>&1
|
||||
@$(TIME) aoc-c -p 2 < $(INPUT)
|
||||
|
||||
ccls: $(CCLSFILE)
|
||||
|
||||
clean:
|
||||
@rm -f aoc-c core* vgcore* gmon.out aoc-c.s aoc-c.i README.html compile_commands.json
|
||||
|
||||
aoc-c: aoc-c.c common.c
|
||||
@echo compiling $<
|
||||
$(CC) $(CFLAGS) $(LDFLAGS) -I $(INCDIR) $^ $(LDLIB) -o $@
|
||||
|
||||
# generate pre-processed file (.i) and assembler (.s)
|
||||
%.i: %.c
|
||||
@echo generating $@
|
||||
@$(CC) -E $(CFLAGS) -I $(INCDIR) $< -o $@
|
||||
|
||||
%.s: %.c
|
||||
@echo generating $@
|
||||
@$(CC) -S -fverbose-asm $(CFLAGS) -I $(INCDIR) $< -o $@
|
||||
|
||||
# generate README.org from README.html (must cleanup !)
|
||||
org: README.org
|
||||
|
||||
%.org: %.html
|
||||
@echo generating $@. Cleanup before commit !
|
||||
@pandoc $< -o $@
|
||||
|
||||
# generate compile_commands.json
|
||||
$(CCLSFILE): aoc-c.c Makefile
|
||||
$(BEAR) -- make clean compile
|
||||
|
||||
bear: clean
|
||||
@touch .ccls-root
|
||||
@$(BEAR) -- make compile
|
||||
197
2022/day13/README.org
Normal file
197
2022/day13/README.org
Normal file
@@ -0,0 +1,197 @@
|
||||
** --- Day 13: Distress Signal ---
|
||||
You climb the hill and again try contacting the Elves. However, you
|
||||
instead receive a signal you weren't expecting: a /distress signal/.
|
||||
|
||||
Your handheld device must still not be working properly; the packets
|
||||
from the distress signal got decoded /out of order/. You'll need to
|
||||
re-order the list of received packets (your puzzle input) to decode the
|
||||
message.
|
||||
|
||||
Your list consists of pairs of packets; pairs are separated by a blank
|
||||
line. You need to identify /how many pairs of packets are in the right
|
||||
order/.
|
||||
|
||||
For example:
|
||||
|
||||
#+begin_example
|
||||
[1,1,3,1,1]
|
||||
[1,1,5,1,1]
|
||||
|
||||
[[1],[2,3,4]]
|
||||
[[1],4]
|
||||
|
||||
[9]
|
||||
[[8,7,6]]
|
||||
|
||||
[[4,4],4,4]
|
||||
[[4,4],4,4,4]
|
||||
|
||||
[7,7,7,7]
|
||||
[7,7,7]
|
||||
|
||||
[]
|
||||
[3]
|
||||
|
||||
[[[]]]
|
||||
[[]]
|
||||
|
||||
[1,[2,[3,[4,[5,6,7]]]],8,9]
|
||||
[1,[2,[3,[4,[5,6,0]]]],8,9]
|
||||
#+end_example
|
||||
|
||||
Packet data consists of lists and integers. Each list starts with =[=,
|
||||
ends with =]=, and contains zero or more comma-separated values (either
|
||||
integers or other lists). Each packet is always a list and appears on
|
||||
its own line.
|
||||
|
||||
When comparing two values, the first value is called /left/ and the
|
||||
second value is called /right/. Then:
|
||||
|
||||
- If /both values are integers/, the /lower integer/ should come first.
|
||||
If the left integer is lower than the right integer, the inputs are in
|
||||
the right order. If the left integer is higher than the right integer,
|
||||
the inputs are not in the right order. Otherwise, the inputs are the
|
||||
same integer; continue checking the next part of the input.
|
||||
- If /both values are lists/, compare the first value of each list, then
|
||||
the second value, and so on. If the left list runs out of items first,
|
||||
the inputs are in the right order. If the right list runs out of items
|
||||
first, the inputs are not in the right order. If the lists are the
|
||||
same length and no comparison makes a decision about the order,
|
||||
continue checking the next part of the input.
|
||||
- If /exactly one value is an integer/, convert the integer to a list
|
||||
which contains that integer as its only value, then retry the
|
||||
comparison. For example, if comparing =[0,0,0]= and =2=, convert the
|
||||
right value to =[2]= (a list containing =2=); the result is then found
|
||||
by instead comparing =[0,0,0]= and =[2]=.
|
||||
|
||||
Using these rules, you can determine which of the pairs in the example
|
||||
are in the right order:
|
||||
|
||||
#+begin_example
|
||||
== Pair 1 ==
|
||||
- Compare [1,1,3,1,1] vs [1,1,5,1,1]
|
||||
- Compare 1 vs 1
|
||||
- Compare 1 vs 1
|
||||
- Compare 3 vs 5
|
||||
- Left side is smaller, so inputs are in the right order
|
||||
|
||||
== Pair 2 ==
|
||||
- Compare [[1],[2,3,4]] vs [[1],4]
|
||||
- Compare [1] vs [1]
|
||||
- Compare 1 vs 1
|
||||
- Compare [2,3,4] vs 4
|
||||
- Mixed types; convert right to [4] and retry comparison
|
||||
- Compare [2,3,4] vs [4]
|
||||
- Compare 2 vs 4
|
||||
- Left side is smaller, so inputs are in the right order
|
||||
|
||||
== Pair 3 ==
|
||||
- Compare [9] vs [[8,7,6]]
|
||||
- Compare 9 vs [8,7,6]
|
||||
- Mixed types; convert left to [9] and retry comparison
|
||||
- Compare [9] vs [8,7,6]
|
||||
- Compare 9 vs 8
|
||||
- Right side is smaller, so inputs are not in the right order
|
||||
|
||||
== Pair 4 ==
|
||||
- Compare [[4,4],4,4] vs [[4,4],4,4,4]
|
||||
- Compare [4,4] vs [4,4]
|
||||
- Compare 4 vs 4
|
||||
- Compare 4 vs 4
|
||||
- Compare 4 vs 4
|
||||
- Compare 4 vs 4
|
||||
- Left side ran out of items, so inputs are in the right order
|
||||
|
||||
== Pair 5 ==
|
||||
- Compare [7,7,7,7] vs [7,7,7]
|
||||
- Compare 7 vs 7
|
||||
- Compare 7 vs 7
|
||||
- Compare 7 vs 7
|
||||
- Right side ran out of items, so inputs are not in the right order
|
||||
|
||||
== Pair 6 ==
|
||||
- Compare [] vs [3]
|
||||
- Left side ran out of items, so inputs are in the right order
|
||||
|
||||
== Pair 7 ==
|
||||
- Compare [[[]]] vs [[]]
|
||||
- Compare [[]] vs []
|
||||
- Right side ran out of items, so inputs are not in the right order
|
||||
|
||||
== Pair 8 ==
|
||||
- Compare [1,[2,[3,[4,[5,6,7]]]],8,9] vs [1,[2,[3,[4,[5,6,0]]]],8,9]
|
||||
- Compare 1 vs 1
|
||||
- Compare [2,[3,[4,[5,6,7]]]] vs [2,[3,[4,[5,6,0]]]]
|
||||
- Compare 2 vs 2
|
||||
- Compare [3,[4,[5,6,7]]] vs [3,[4,[5,6,0]]]
|
||||
- Compare 3 vs 3
|
||||
- Compare [4,[5,6,7]] vs [4,[5,6,0]]
|
||||
- Compare 4 vs 4
|
||||
- Compare [5,6,7] vs [5,6,0]
|
||||
- Compare 5 vs 5
|
||||
- Compare 6 vs 6
|
||||
- Compare 7 vs 0
|
||||
- Right side is smaller, so inputs are not in the right order
|
||||
#+end_example
|
||||
|
||||
What are the indices of the pairs that are already /in the right order/?
|
||||
(The first pair has index 1, the second pair has index 2, and so on.) In
|
||||
the above example, the pairs in the right order are 1, 2, 4, and 6; the
|
||||
sum of these indices is =13=.
|
||||
|
||||
Determine which pairs of packets are already in the right order. /What
|
||||
is the sum of the indices of those pairs?/
|
||||
|
||||
Your puzzle answer was =5843=.
|
||||
|
||||
** --- Part Two ---
|
||||
Now, you just need to put /all/ of the packets in the right order.
|
||||
Disregard the blank lines in your list of received packets.
|
||||
|
||||
The distress signal protocol also requires that you include two
|
||||
additional /divider packets/:
|
||||
|
||||
#+begin_example
|
||||
[[2]]
|
||||
[[6]]
|
||||
#+end_example
|
||||
|
||||
Using the same rules as before, organize all packets - the ones in your
|
||||
list of received packets as well as the two divider packets - into the
|
||||
correct order.
|
||||
|
||||
For the example above, the result of putting the packets in the correct
|
||||
order is:
|
||||
|
||||
#+begin_example
|
||||
[]
|
||||
[[]]
|
||||
[[[]]]
|
||||
[1,1,3,1,1]
|
||||
[1,1,5,1,1]
|
||||
[[1],[2,3,4]]
|
||||
[1,[2,[3,[4,[5,6,0]]]],8,9]
|
||||
[1,[2,[3,[4,[5,6,7]]]],8,9]
|
||||
[[1],4]
|
||||
[[2]]
|
||||
[3]
|
||||
[[4,4],4,4]
|
||||
[[4,4],4,4,4]
|
||||
[[6]]
|
||||
[7,7,7]
|
||||
[7,7,7,7]
|
||||
[[8,7,6]]
|
||||
[9]
|
||||
#+end_example
|
||||
|
||||
Afterward, locate the divider packets. To find the /decoder key/ for
|
||||
this distress signal, you need to determine the indices of the two
|
||||
divider packets and multiply them together. (The first packet is at
|
||||
index 1, the second packet is at index 2, and so on.) In this example,
|
||||
the divider packets are /10th/ and /14th/, and so the decoder key is
|
||||
=140=.
|
||||
|
||||
Organize all of the packets into the correct order. /What is the decoder
|
||||
key for the distress signal?/
|
||||
|
||||
Your puzzle answer was =26289=.
|
||||
240
2022/day13/aoc-c.c
Normal file
240
2022/day13/aoc-c.c
Normal file
@@ -0,0 +1,240 @@
|
||||
/* aoc-c.c: Advent of Code 2022, day 13
|
||||
*
|
||||
* Copyright (C) 2022-2023 Bruno Raoult ("br")
|
||||
* Licensed under the GNU General Public License v3.0 or later.
|
||||
* Some rights reserved. See COPYING.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with this
|
||||
* program. If not, see <https://www.gnu.org/licenses/gpl-3.0-standalone.html>.
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later <https://spdx.org/licenses/GPL-3.0-or-later.html>
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#include "br.h"
|
||||
#include "list.h"
|
||||
#include "pool.h"
|
||||
|
||||
#include "aoc.h"
|
||||
|
||||
typedef enum { SUBLIST, INT } type_t;
|
||||
|
||||
typedef struct node { /* node */
|
||||
type_t car_t;
|
||||
union { /* CAR */
|
||||
struct list_head sub; /* sublist */
|
||||
int value; /* value */
|
||||
};
|
||||
struct list_head cdr; /* CDR */
|
||||
} node_t;
|
||||
|
||||
typedef struct { /* packets ordered list */
|
||||
struct list_head node; /* packet head */
|
||||
struct list_head list; /* packets lists */
|
||||
} packets_t;
|
||||
LIST_HEAD(packets);
|
||||
|
||||
/* dummy node for integer vs list */
|
||||
static struct list_head dummy_list; /* tentative definition */
|
||||
static node_t dummy = {
|
||||
.car_t = INT, .value = 0, .cdr = LIST_HEAD_INIT(dummy_list)
|
||||
};
|
||||
static struct list_head dummy_list = LIST_HEAD_INIT(dummy.cdr);
|
||||
|
||||
pool_t *pool_node, *pool_packets;
|
||||
|
||||
/* int getnode - allocate and initialize a new node
|
||||
* @type: The node type_t (INT/LIST)
|
||||
* @val: The value if @type is INT
|
||||
*
|
||||
* Return: The new node.
|
||||
*/
|
||||
static node_t *getnode(type_t type, int val)
|
||||
{
|
||||
node_t *node = pool_get(pool_node);
|
||||
node->car_t = type;
|
||||
INIT_LIST_HEAD(&node->cdr);
|
||||
if (type == INT)
|
||||
node->value = val;
|
||||
else
|
||||
INIT_LIST_HEAD(&node->sub);
|
||||
return node;
|
||||
}
|
||||
|
||||
/* int compare tree - compare two packets trees
|
||||
* @h1: The first packet list head
|
||||
* @h2: The second packet list head
|
||||
*
|
||||
* Return: 1 if h1 and h2 are ordered, -1 if not ordered, 0 if undecided
|
||||
*/
|
||||
static int compare_tree(struct list_head *h1, struct list_head *h2)
|
||||
{
|
||||
struct list_head *cur1, *cur2;
|
||||
node_t *n1, *n2;
|
||||
int res;
|
||||
|
||||
/* get lists first entries */
|
||||
cur1 = h1->next;
|
||||
cur2 = h2->next;
|
||||
|
||||
while (cur1 != h1 && cur2 != h2) {
|
||||
n1 = container_of(cur1, node_t, cdr);
|
||||
n2 = container_of(cur2, node_t, cdr);
|
||||
|
||||
if (n1->car_t == n2->car_t) {
|
||||
if (n1->car_t == INT) {
|
||||
if (n1->value < n2->value) {
|
||||
return 1;
|
||||
} else if (n1->value > n2->value) {
|
||||
return -1;
|
||||
}
|
||||
} else { /* both sublists */
|
||||
if ((res = compare_tree(&n1->sub, &n2->sub)))
|
||||
return res;
|
||||
}
|
||||
} else { /* one number, one list */
|
||||
if (n1->car_t == INT) {
|
||||
dummy.value = n1->value;
|
||||
res = compare_tree(&dummy_list, &n2->sub);
|
||||
} else {
|
||||
dummy.value = n2->value;
|
||||
res = compare_tree(&n1->sub, &dummy_list);
|
||||
}
|
||||
if (res)
|
||||
return res;
|
||||
}
|
||||
cur1 = cur1->next;
|
||||
cur2 = cur2->next;
|
||||
}
|
||||
/* at least one list came to end */
|
||||
if (cur1 == h1 && cur2 == h2) /* both are ending */
|
||||
return 0;
|
||||
else if (cur1 == h1) /* first list did end */
|
||||
return 1;
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* int add_node - add a packet to the sorted packets list
|
||||
* @new: The new packets list head
|
||||
*
|
||||
* Return: The new packet position in list (first is 1)
|
||||
*/
|
||||
static int add_node(packets_t *new)
|
||||
{
|
||||
packets_t *first, *iter;
|
||||
struct list_head *node_next = &packets;
|
||||
int num = 1;
|
||||
|
||||
if (list_empty(&packets))
|
||||
goto ins_node;
|
||||
first = iter = list_first_entry(&packets, packets_t, list);
|
||||
do {
|
||||
if (compare_tree(&new->node, &iter->node) > 0) {
|
||||
node_next = &iter->list;
|
||||
break;
|
||||
}
|
||||
iter = list_entry(iter->list.next, packets_t, list);
|
||||
num++;
|
||||
} while (iter != first);
|
||||
ins_node:
|
||||
list_add_tail(&new->list, node_next);
|
||||
return num;
|
||||
}
|
||||
|
||||
static struct list_head *create_tree(char *s, int *consumed, struct list_head *head)
|
||||
{
|
||||
node_t *node = NULL;
|
||||
LIST_HEAD(sub);
|
||||
int val, depth = 0, subconsumed;
|
||||
|
||||
*consumed = 1;
|
||||
INIT_LIST_HEAD(head);
|
||||
for (; *s; s++, (*consumed)++) {
|
||||
switch (*s) {
|
||||
case '[':
|
||||
if (++depth == 2) { /* we skip first depth level */
|
||||
node = getnode(SUBLIST, 0);
|
||||
list_add_tail(&node->cdr, head);
|
||||
create_tree(s, &subconsumed, &node->sub);
|
||||
s += subconsumed - 1;
|
||||
*consumed += subconsumed - 1;
|
||||
depth--;
|
||||
}
|
||||
break;
|
||||
case ',':
|
||||
break;
|
||||
case ']':
|
||||
if (!--depth)
|
||||
goto end;
|
||||
break;
|
||||
default: /* number */
|
||||
sscanf(s, "%d%n", &val, &subconsumed);
|
||||
*consumed += subconsumed - 1;
|
||||
s += subconsumed - 1;
|
||||
node = getnode(INT, val);
|
||||
list_add_tail(&node->cdr, head);
|
||||
break;
|
||||
}
|
||||
}
|
||||
end:
|
||||
return head;
|
||||
}
|
||||
|
||||
static int parse()
|
||||
{
|
||||
size_t alloc = 0;
|
||||
ssize_t buflen;
|
||||
char *buf = NULL;
|
||||
packets_t *head[2];
|
||||
int i = 0, dummy, res = 0;
|
||||
|
||||
while ((buflen = getline(&buf, &alloc, stdin)) > 0) {
|
||||
buf[--buflen] = 0;
|
||||
if (buflen > 0) { /* non empty line */
|
||||
head[i % 2] = pool_get(pool_packets);
|
||||
create_tree(buf, &dummy, &head[i % 2]->node);
|
||||
add_node(head[i % 2]);
|
||||
}
|
||||
if (buflen != 0) { /* non empty line or EOF */
|
||||
if (i % 2 && compare_tree(&head[0]->node, &head[1]->node) == 1)
|
||||
res += (i >> 1) + 1; /* (i / 2) + 1 */
|
||||
i++;
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
static int part1()
|
||||
{
|
||||
return parse();
|
||||
}
|
||||
|
||||
static int part2()
|
||||
{
|
||||
char *dividers[] = { "[[2]]", "[[6]]" };
|
||||
int dummy, res = 1;
|
||||
parse();
|
||||
for (ulong i = 0; i < ARRAY_SIZE(dividers); ++i) {
|
||||
packets_t *h = pool_get(pool_packets);
|
||||
create_tree(dividers[i], &dummy, &h->node);
|
||||
res *= add_node(h);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
int main(int ac, char **av)
|
||||
{
|
||||
int part = parseargs(ac, av);
|
||||
pool_node = pool_create("node", 512, sizeof(node_t));
|
||||
pool_packets = pool_create("packets", 512, sizeof(packets_t));
|
||||
|
||||
printf("%s: res=%d\n", *av, part == 1? part1(): part2());
|
||||
pool_destroy(pool_node);
|
||||
pool_destroy(pool_packets);
|
||||
exit(0);
|
||||
}
|
||||
17
2022/day13/aoc.h
Normal file
17
2022/day13/aoc.h
Normal file
@@ -0,0 +1,17 @@
|
||||
/* aoc.c: Advent of Code 2022
|
||||
*
|
||||
* Copyright (C) 2022 Bruno Raoult ("br")
|
||||
* Licensed under the GNU General Public License v3.0 or later.
|
||||
* Some rights reserved. See COPYING.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with this
|
||||
* program. If not, see <https://www.gnu.org/licenses/gpl-3.0-standalone.html>.
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later <https://spdx.org/licenses/GPL-3.0-or-later.html>
|
||||
*/
|
||||
#ifndef _AOC_H_
|
||||
#define _AOC_H_
|
||||
|
||||
extern int parseargs(int ac, char**av);
|
||||
|
||||
#endif /* _AOC_H_ */
|
||||
68
2022/day13/common.bash
Normal file
68
2022/day13/common.bash
Normal file
@@ -0,0 +1,68 @@
|
||||
#!/usr/bin/env bash
|
||||
#
|
||||
# common.bash: Advent of Code 2022, common bash functions
|
||||
#
|
||||
# Copyright (C) 2022 Bruno Raoult ("br")
|
||||
# Licensed under the GNU General Public License v3.0 or later.
|
||||
# Some rights reserved. See COPYING.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License along with this
|
||||
# program. If not, see <https://www.gnu.org/licenses/gpl-3.0-standalone.html>.
|
||||
#
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later <https://spdx.org/licenses/GPL-3.0-or-later.html>
|
||||
|
||||
# shellcheck disable=2034
|
||||
export cmdname=${0##*/}
|
||||
export debug=0
|
||||
export res
|
||||
export LANG=C
|
||||
|
||||
shopt -s extglob
|
||||
set -o noglob
|
||||
|
||||
usage() {
|
||||
printf "usage: %s [-d DEBUG] [-p PART]\n" "$cmdname"
|
||||
exit 1
|
||||
}
|
||||
|
||||
checkargs() {
|
||||
local part=1
|
||||
while getopts p:d: todo; do
|
||||
case "$todo" in
|
||||
d)
|
||||
if [[ "$OPTARG" =~ ^[[:digit:]+]$ ]]; then
|
||||
debug="$OPTARG"
|
||||
else
|
||||
printf "%s: illegal [%s] debug level.\n" "$CMD" "$OPTARG"
|
||||
exit 1
|
||||
fi
|
||||
;;
|
||||
p)
|
||||
if [[ "$OPTARG" =~ ^[12]$ ]]; then
|
||||
part="$OPTARG"
|
||||
else
|
||||
printf "%s: illegal [%s] part.\n" "$CMD" "$OPTARG"
|
||||
exit 1
|
||||
fi
|
||||
;;
|
||||
*)
|
||||
usage
|
||||
;;
|
||||
esac
|
||||
done
|
||||
# Now check remaining argument (backup directory)
|
||||
shift $((OPTIND - 1))
|
||||
|
||||
(( $# > 1 )) && usage
|
||||
return "$part"
|
||||
}
|
||||
|
||||
main() {
|
||||
local -i part
|
||||
|
||||
checkargs "$@"
|
||||
part=$?
|
||||
parse "$part"
|
||||
solve "$part"
|
||||
printf "%s: res=%s\n" "$cmdname" "$res"
|
||||
}
|
||||
49
2022/day13/common.c
Normal file
49
2022/day13/common.c
Normal file
@@ -0,0 +1,49 @@
|
||||
/* common.c: Advent of Code 2022, common functions
|
||||
*
|
||||
* Copyright (C) 2022 Bruno Raoult ("br")
|
||||
* Licensed under the GNU General Public License v3.0 or later.
|
||||
* Some rights reserved. See COPYING.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with this
|
||||
* program. If not, see <https://www.gnu.org/licenses/gpl-3.0-standalone.html>.
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later <https://spdx.org/licenses/GPL-3.0-or-later.html>
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "aoc.h"
|
||||
#include "debug.h"
|
||||
|
||||
static int usage(char *prg)
|
||||
{
|
||||
fprintf(stderr, "Usage: %s [-d debug_level] [-p part] [-i input]\n", prg);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int parseargs(int ac, char **av)
|
||||
{
|
||||
int opt, part = 1;
|
||||
|
||||
while ((opt = getopt(ac, av, "d:p:")) != -1) {
|
||||
switch (opt) {
|
||||
case 'd':
|
||||
debug_level_set(atoi(optarg));
|
||||
break;
|
||||
case 'p': /* 1 or 2 */
|
||||
part = atoi(optarg);
|
||||
if (part < 1 || part > 2)
|
||||
return usage(*av);
|
||||
break;
|
||||
case 'i':
|
||||
|
||||
default:
|
||||
return usage(*av);
|
||||
}
|
||||
}
|
||||
if (optind < ac)
|
||||
return usage(*av);
|
||||
return part;
|
||||
}
|
||||
23
2022/day13/input/example.txt
Normal file
23
2022/day13/input/example.txt
Normal file
@@ -0,0 +1,23 @@
|
||||
[1,1,3,1,1]
|
||||
[1,1,5,1,1]
|
||||
|
||||
[[1],[2,3,4]]
|
||||
[[1],4]
|
||||
|
||||
[9]
|
||||
[[8,7,6]]
|
||||
|
||||
[[4,4],4,4]
|
||||
[[4,4],4,4,4]
|
||||
|
||||
[7,7,7,7]
|
||||
[7,7,7]
|
||||
|
||||
[]
|
||||
[3]
|
||||
|
||||
[[[]]]
|
||||
[[]]
|
||||
|
||||
[1,[2,[3,[4,[5,6,7]]]],8,9]
|
||||
[1,[2,[3,[4,[5,6,0]]]],8,9]
|
||||
449
2022/day13/input/input.txt
Normal file
449
2022/day13/input/input.txt
Normal file
@@ -0,0 +1,449 @@
|
||||
[[[5,1,[],[8,1,3],6],[[7]]],[10,[]],[6],[[],[[0,6,4,10,5],[2,2,9],[4,4],[2,10,4,10,8]],7,7],[[5],5,[[6],[8,2],[5],[]],[9,3,2,[9,4,8,6,8]]]]
|
||||
[[5]]
|
||||
|
||||
[[[5,3,[],[5,3,10],2],[[5,0,9,1]]],[[[9,0],[9,6,3]]],[[[1],1,[7,6],10],4],[2]]
|
||||
[[],[[2,[9,2,6,9],10],[[2,8,10],[4,6],[1,6,4,6],[2,10,1,0,6]],6,[7,6,3,[10,6,4,5],4]],[],[2,2,[]],[2,9,[[3,3,9,6],[6,8,7,9,6],10,2,[6,9,8,7,0]],[7]]]
|
||||
|
||||
[[[4,6,7]],[[1,10,8,[7,2]],10],[10],[[3,7,8,[6,7],[]],8,[4,[5,0,9,1],[6,1,2,6,5]]]]
|
||||
[[[3,[1,8,7,6],[3,8,7,7],[],[8,5]],[[1,8,10],[10,8,9]],8,[[8],9,[],3],[7,9,8,[2,10,7]]],[8,2],[6]]
|
||||
|
||||
[[3]]
|
||||
[[2,[],[]],[[5,8,[6]],[[0,6,8,10],[]],[[9,6],6,8]],[[],4,2,[0,[1,4,2,7],6],[0,7]]]
|
||||
|
||||
[[[0,2,[10,5,8]],[[],7,[],[5,2,0,1]],6,10],[],[[],8,0,3,[4,0,[8,5,8,3]]],[0,[1,5],[[8,5,2],9,[8,5,2],[9,9,7,8]],5]]
|
||||
[[0,6,[[5,8,6],6,[1,8,2]],[[],[10],[],3,7],2],[[[],3],7,[6,2,[]],[[]]]]
|
||||
|
||||
[[6,8],[[9,[2,0,7],4,10],[[0,2,10,6,4],8,[7,7,2,8,7]]],[],[6,[]],[[[3,0,6]]]]
|
||||
[[9,[[],[1,6,1,0,6],[8],[2]],[8,[2,5,10,0,10],1,[7],[6,5]]],[2,[9,0,[1,5,5,0,8]],9,2],[]]
|
||||
|
||||
[[7,0,1,[[2,1],[8],[9,9,4,8,6],10]],[7,[5,[10,5,6],6,[4,10,7,5,10]],[1]]]
|
||||
[[1,[],[[4]],3],[[[8],[4,5]],[[10],[],[3],[6,2,9],[0,8]]]]
|
||||
|
||||
[[[2,[],4],[],3,[4,[8,0,1,2],[],[4,0,2],[0,7,4,5,6]]]]
|
||||
[[1,[],[[6],[10],[6,4,6,1,7],[0,7,1]],[],[[1],[0,8,3],[6],[2,5,7,8,10],[5,5,3]]],[[4,5,2,2,[]],4,[[6,1,7,3],8,[0,5,0]]]]
|
||||
|
||||
[[[0,[2,6,4],3,[8,0,10],[5]]],[[[10,4,3,0,3],[3,0,9,3,5],5,[5,7,3]],[2,3],[]]]
|
||||
[[3,[[5,5,3,10,10],4,[]],7,1],[3],[[[7,7,3,7],10,[9,8,9,9],[],8],6,1,[]],[[1,[8],1],3,[[9,5,4],9,0,[0],2]],[[[1],6],4,1,[]]]
|
||||
|
||||
[[[10,0,[7]],4,6,[4,5]],[[2,4,[0,3,7,10,9]]],[[[6,5,9],[6,9,6,3],[1,8,4,5],8],[9],[[9,3],3,[7,5],7]],[[[]],[[2,5,4],[],[],[0,1,2,2],[5,1,1,7,8]]],[3,6,8,6,[[6,1],[]]]]
|
||||
[[6,2],[4,[],[[7,7,5,9],8,[6,10,2,0,9]],2,[1,6]],[[[1,5,10,8]],8,0,0,8],[6,4,[[6,4,6,7],4],[[1,3,7,1],[0,2,4,1,10],[1]],10],[]]
|
||||
|
||||
[[[5,[1,6,2,5,5],[3],[7,3]],[[4,6,2,1,2]],9,7],[0,5,10],[9]]
|
||||
[[10,0],[[2,[7,4,6],9,3,[0,7,10,9,1]],5,[4,[],2,8,[0,8,6]]]]
|
||||
|
||||
[[],[[[],6,9],[[8],[2,5,4,6],[5,6,8],[5,4,4,6],[]],[[2,6,8,1],0,[7,1,9,6]]],[2,0,1,2],[]]
|
||||
[[[[],[7,5,5],[3]]],[[[6,7,6],[7,1,1]],4,[7,[2,10],4,[2,2]],0,[[7],10,5,4,[2,5,5,2,1]]]]
|
||||
|
||||
[[[[3,4,6,2,6],[],6],[[1],5,[1],2,[5]],10,0],[9,[]]]
|
||||
[[],[[]],[[[],2,[0,3,9,10],5]],[]]
|
||||
|
||||
[[[[2,6,0,9],[],[],[9,3,2,9],[9,10]],6,[[4,1,6,2],1],[[10,1],[0,5,5,4],[],4,[8,8,0,1,6]]],[[5],6,[[9,4],4,0],7],[9,[],[6,4]],[],[]]
|
||||
[[[[9,3,0,2],[4,10],[0],[5,5,0]],1,7,[[0]]],[],[[[2,10,10],[6]],6,[7,0,[4,0,8],6,5],2],[],[8]]
|
||||
|
||||
[[1,1,3],[[[],7,[0,5,0,2],[10]]]]
|
||||
[[],[[[3,4,7],[7,2],[1]],[[1],9,[3,1,3],[3],10]],[[[],5,[2],4],10],[[[2,6,6,8,3],[6,0,7],1],[[8,8,3,0,3],[4,8,10],0],6,[[10],[10,2,6,6,7]]]]
|
||||
|
||||
[[9,2,3]]
|
||||
[[],[],[[[],[10,8,7,4],0,5],3,7,[6,[1,4,5,10]],1],[[],[1,5,[7,3]],[7,10,[10],[3]],[8],2],[]]
|
||||
|
||||
[1,5,3,3,5]
|
||||
[1,5,3,3]
|
||||
|
||||
[[8,[[2,6,0,9],[4,9,5,5,3],[8],8,3],[1]],[0,[7,[8,8,8,1]],[],[[0],[8,6,9,9,1],2,6,2]],[],[1,[2,1,[1],8],[],8],[[9,7],[7,10],[[],9,9,7,3],[2,[],6],[[],5,[7,6,7,6,0],[3],[3,10,10,10]]]]
|
||||
[[[[8],1,[1,1,3,5,1],[0,3]],[],4,0,5],[],[3,3,[9,4,5,[4,2,3]],7,9],[7],[[[2,1]],[[2,9,10,0,6],[3,0,8],[0,3,2,9,1]]]]
|
||||
|
||||
[[[[5],7],3,[9,[2,6,0,2,3]],[],3],[4]]
|
||||
[[10,7,8,[[],[9,10],1],[4,5,[2]]],[[5,[3,9,6,5],[],2],[9,4],[6,[2,4,8,1,7],10],1,[2,[3,6,1,5],1,[5,10],[]]],[9,8],[7,9,4,[5,[4,4,0],[9,10]],9],[]]
|
||||
|
||||
[[2,0,[2,8,10],[[10,9,4,0],[7,6,8,1,9],[2,5,6,9,5],[]]],[8],[6,7,4,[[0,5],4,5,3,[8,6,4,6]]]]
|
||||
[[[[3,6,5,5],[6,10,3,2,9],[8,7],[6,5,7]],[[3,10,7,10,5],[9],5,[1,9,1,5,5]],5,10,[[2,1,2,3],[1,0,10,1],[1,5,3]]]]
|
||||
|
||||
[[1,7,[9,[2,2,5,4,5],4],[[0]]]]
|
||||
[[[[8],9,5,2]],[7],[0,8,[1,3,[6,5,10,2,6],9],9],[[[7,0,6,3]],[[2,1,5,9],7,[4,2,1,7],[3,0,0,10],10],[],[[4,9,3],[]],[]],[4]]
|
||||
|
||||
[[1]]
|
||||
[[[],[9,[4,2],4,8],[8,8,0,[5,8,10],[4,1,7,10,0]]],[0,6]]
|
||||
|
||||
[[2,[[1,7,10,3,10],4,5],6,[[3,9,7,8,5],[]]]]
|
||||
[[[[]]],[[[5,2,9,7,2],2,5,8],2,9,[5,3],2],[4,[[],4,7,[1,10],[2,1,0,0,8]],4,7],[8,[8,3,2,5,10],[4,[10,4],[2,10,9,5],[2,6],[3]],2]]
|
||||
|
||||
[[[[5,5,2,7,6]],[],[]],[10,6,[6,9,7]],[[[8,1]],[],0,[[],[1,0],[]],0]]
|
||||
[[4,[[10,1,5]],1],[],[1,5,8,[[6,10]],[[6],9,[0,3],[],[6,3,7]]],[10,[],[[1,4],8,[5,8]],[3,5,2,[],0]],[10,[3,[4,1,6,5]]]]
|
||||
|
||||
[[6,10,[10,[6]]],[8,[[8,8],2,1]],[9,[6,2,[0,0,9,10,9]],1,1]]
|
||||
[[],[10,[[7,5],[3,10,7,8]]],[[]],[[10,[2,9],8,2,4],[1,[2],[10,5,3],1],0,3],[[[0,4,6]],[[6,0,9]],[[6,4,6,10],[1,8,8],3,7,4],[3,2,[0]]]]
|
||||
|
||||
[[3,5],[[7,[8,2],[9,8]],[[3,1,0,6,10],[],[7,8,1,10]],[[],10,[4,6,7],5,[2,10,7,6,5]],[6,[3,7,8,2,7],5],[[6,3],[7,8,4,0,8],9,[0],[0,10,7,0,2]]],[[],[[4,6,1,9]],3,[],[8,[6,3,4],[5,10,6,0,9]]],[[],9,0,[[1,7,9,10],0,10,4],4],[]]
|
||||
[[],[[4],[[],0],[5,[4,7,5,9,6],[8,10,0,5,0],10,[1,0,7,6,1]]],[],[]]
|
||||
|
||||
[[2,6,3],[],[[7,[3,9,2,10],2,[10,0,1,3,6]],[3,[3,8,9,7,3],6],[],[[],1,0],8],[8,4,[],0],[8]]
|
||||
[[7],[10,5],[[[2,6,10,9,1],7,[]],[[4,1,10,4],10,10],0],[2,7,[[9,7],[7,3,9,9],[1,8]],[],[[7,10,4],[5,2,2,6],[],2]],[[8,9],9,4]]
|
||||
|
||||
[[[7,[9,10,1,4,0],[4,10,2,1]],7]]
|
||||
[[10],[[4,9,3],9],[4],[],[7,[7],[[10,9,8,4,10],3]]]
|
||||
|
||||
[[9,6,[],[],[9]],[8,[4,[1,1,10,8]],1,9,10],[[],[6,4,[9,0,2,6]]],[[4,[0,8],7,[8,1]],5]]
|
||||
[[2,8],[[[1,6,6],[6]],[8,[2,10],[1,2,6,3,9],[9],4]],[[3,3,[7,0,9,8,8]],[[9,7,7],4,[4,1],[10,3],[]],[[9,8],[2]],7],[],[10,[6,[],7],[[],[5,10],[5,4],2]]]
|
||||
|
||||
[[[[0],[2],3,[4,1,8,8,8]]],[],[[[7,5,3]],[8]]]
|
||||
[[[[3],0,[0,3,7,1],9,2],[3,2,3,[6]],[],[],0]]
|
||||
|
||||
[[1,4,[]],[0,0,10,10,[]],[[0,[8],[4,0]],[10],[2]],[[[],[7,1,1,10]],[7,[],[8],4,[2,9,3]],[1],[[10,8,10,5],2,[5],[10,10]],[[3,2,1,9,5],9,[5,3,7],3]]]
|
||||
[[[8],7,1,0],[6,1],[[2],1,[],[7]],[]]
|
||||
|
||||
[[6,2,[],[4,3,5,2,8],[[4,5,4,7],3,[2,9,1,7,0],[7,4,6,6,7]]],[],[10,[[9,10],4],7,0],[4],[3,[],9,8]]
|
||||
[[[10,[7,3,4,7,6],6,4,[9]],[9,[],8,[6],[5,4,7]],[5,6],[5,2,[3,1,10,0],[9]]],[[1]]]
|
||||
|
||||
[[],[[[3],10,3,7]],[]]
|
||||
[[],[[],4,[2,[0],0,[]],4],[],[[5,0,10,6,9],2]]
|
||||
|
||||
[[4],[[8,[4,4,3,2]],[],[],5],[[]],[],[[3,6],10,8,[[3],6,7,2]]]
|
||||
[[7,[2,[2,0,8],[6]],[]],[],[]]
|
||||
|
||||
[[[[3,8,2,9],5,[5,5,5,0],[10,7,1,0]]],[[[5]],[[9,4,5]],[],0],[[],8,2]]
|
||||
[[0,[8],7],[[0,0,0],[[3,7,9,2]],1],[5,6,[[9],[9,7,2,3,2],[0,8,1,4]],10,2]]
|
||||
|
||||
[[0,[8,[6,6],[0,7],8],4,10],[6,10,[9],[8,[5,2,8,8,6]]],[6,5,9,[]]]
|
||||
[]
|
||||
|
||||
[[[[],10,[10,9,6,5,5],5],4,2,6],[],[],[],[]]
|
||||
[[5,[[],[]],[]],[8,[[10,8,6],9,[0,5,6],5],[0,[]],4],[[]]]
|
||||
|
||||
[[5,5,[],6,3],[[[1,9,7,8],[6]],[[6,2,2,10],[3,10,4,1],6,1],0,3,[[1,6,7,5,2],0,[],[9,2,3],4]],[7,8,[[5,1,3],[],9],[2]],[],[[[9,1,4,7,5]],8,[9,0,[1,5,10]],9,[3,[],[],1]]]
|
||||
[[],[2,[1,0,0,[5,4],[]],[[2,10,7],9,0],4],[[3,10],7,[2,1],[[6],10],[10,[7,6,3,6,9],[10,6,6],[],5]],[6,[[9,3,10,10],[0,7,10,7],5,0],3],[[9,[3],[8,8],[1,6]],[[9,9,4,8,4]],[4],3]]
|
||||
|
||||
[[[0,8,9,[9,4,9],[10,5,0,0]],2],[9],[[[6,8]]]]
|
||||
[[[0],[[0,1]],6,7,7]]
|
||||
|
||||
[[[[3,9,8]]],[3,[7,[7,7,4]]],[[4],[3,7,[3,10,9,2],2],[4,[8,5,7],0]],[],[[]]]
|
||||
[[[[7,7],[0,3,9]],6,[7,6],[2,5,[2]]],[],[[[0,5,7,6],[3,5,2],[4,5,6,9],[5,8,10,1,0]],2,[9,[7,10]],4,7],[9,[[9,0,5,9,10],7],9,9,[[10,2,6],[10,5,9],4,1]]]
|
||||
|
||||
[[7,[[0,1,2],7,3,6,[6,8,10,9]],[[1,10]]],[[9,5,3],[[2,0,4,9,8],4,[9]]]]
|
||||
[[0,4,5,2]]
|
||||
|
||||
[[[[0,8]],[7,9,[4,1]]],[[[7]]]]
|
||||
[[[[5,6],[6]],[[],[]],[0,[9,6]]],[2],[[7,6,2,5,1],[[1],[9,5,8],[]],6],[[0,2,9,4,7],[3,[5],10,[],[10]]]]
|
||||
|
||||
[[[[0,4,8,6]],3,[9,[9,4,1],[10,0,3],[]],6],[],[],[[[3,8,6,8,3],[],[0],0,3],10]]
|
||||
[[2,4,8,3,[[10,0,0,7],[1],[10,8],[9,4],[]]],[0,10,4],[10,[2,7,3]],[7,8,4,2,3],[]]
|
||||
|
||||
[[6],[6,[8,[0]],8,[]]]
|
||||
[[[],10],[2,[[4,10,1,2,10],[1,10,3,10],[],[4,6,1],1],[[4]],10],[4,1,2,4,[[6,0,10,8,3]]],[[[6,2]]]]
|
||||
|
||||
[[[8],[1,5,3],[]]]
|
||||
[[],[[[7,1,5,2],[0,9],5,[6,8,8,1,4]],[6,[7],5,[],[2]],[1,7,3,[0,8,8,2,8],[4,0,0]],3,1],[8,[[]],[10,0,6,[2,8,1,4,0],8]],[],[3,[[1,6,3,10],1],[],[[5],[10,6,4],[4]]]]
|
||||
|
||||
[[[],[[1],[8,5,5,5,9],[3],[]],3,9],[],[[],[5,[7,4],[]]]]
|
||||
[[[[1,10,2]],4,[9,[8,6,7,1,4],8],9,9],[4,10,[[4,0,9],[7],5,[]],[7,[2,9,7],[],1]],[[[9,7,9,2],4]],[[1,2,[3,1],[10,9,1,10,10],10],9,3,10,3]]
|
||||
|
||||
[[],[10,[0,[10,10,1,2,10]],1,[]],[[],[[7,5,1,8],2,0],4,[9,5]],[[10,6]],[]]
|
||||
[[6,[1,8,1,3]],[[0,[2,2,9,8,5],6,[5,2,5]],0,1,7],[[9,[1],0,5,6],3,[9]],[[[3,4,1,0],[5,3,2,8,10],[9,6],[9,5,1,8],2]]]
|
||||
|
||||
[[7],[[9,[10],[4,9],5],[2,[6,0,1],4,3]],[9],[[]]]
|
||||
[[[3,[],[6]],[10],0,[[6,5,8,0,1],[8,9,4,7,0]],[]]]
|
||||
|
||||
[[4,[[],[],[7,4,8,3]],[],[[4,7,7,0,5]],[5,7,7]],[9,[],[[8,8,8,5,9],7,[5,3,7,10]]],[[7,[7],4,[],[9,5,6,10,9]],[10]]]
|
||||
[[6,[[6,10,10],[5,3,10,7]],[10,9,[4]],9],[7,[]],[[[9,2,0,3,0]],9,[[1,6,9,6],4,[9,2],[2,9,7]]]]
|
||||
|
||||
[[],[[[4],8],4,[8],[2,3]]]
|
||||
[[10,[[0,8,10,6],2],[[8,5,6],[2,4,2,9],[2],7]],[],[[7,4,[9,5]],1,0,[[0,8,4,3,7]],8],[[4,9,2,[6,8,3,6,2],10]],[]]
|
||||
|
||||
[[[],0,4],[10,8,[],6,7]]
|
||||
[[2,[5,7]],[10]]
|
||||
|
||||
[[[[3],8,4,[6,8,7,3],9],[[9,9,10,4,2],3,[0,8,2]],9,[]],[9,6],[6,[[4,9],2],6,[[],[9,0,6,6,6],[6]]],[[2,[8,9,7,8],10,10],[]],[]]
|
||||
[[[[1,7],[4,8,9,1,9],[3,9,5,3],5,8],2,1,[6,5],7],[]]
|
||||
|
||||
[[7,0,[4],[[6,7,3],7,3,[6,4,3,5,6],4]],[],[2,[[],[0,0]],[[0,3,3,4,5],5,3,[7,9,8,3,3],6]]]
|
||||
[[8,1,1,[0,[],6,[7,5]],10],[[]],[3,[[0]],8,0,2],[7,[0,[2,7,4],1]],[[],[],3]]
|
||||
|
||||
[[1,6,[]]]
|
||||
[[[[]],[10,[6,1,4,2,10]],[[7,2,7],1],[[3,8,5,2],[3],[10],8,10],0],[2],[[[7,8,5],2,9,[4,0,0],[]]]]
|
||||
|
||||
[[7,[6,10,5,5],1,5,[[2,7,3],7,1,9,5]],[[2,2,[8]],[],[5,9,0]],[[9],6,[[4,7,1,0,5],5,9,[3,10]]]]
|
||||
[[0],[0,9,[1,10,10],3,[[8],[0],[],[3,8]]],[4,1,1,8,[[0]]]]
|
||||
|
||||
[[[]],[[[1,9,8,5,8],[3,2,10,7,10]],[[1,8,4],1,[9,3,10,0,4]],0,4],[3,2],[4,4,[[10,0,9,1],[],6,[3,10,8,0]],7,4],[4,[],2,[[8],0,[10,2]]]]
|
||||
[[10],[[[2],[0],[]],5,[4,[4,6,6,2],[0,9,10,8],[10,3,4],0]],[6,4],[7,[[3],[4,8,5,1,5],7],[5,[8],10],[5],[1,[4,9,10],6,10,9]]]
|
||||
|
||||
[[],[6,3,5,5]]
|
||||
[[6,6],[[[6,9,5,0],10,[9,3,2]],[2],[]]]
|
||||
|
||||
[[4,[[],1],3,[[3,4,0,6,0]]],[6,9,5,4],[[6,0,2,[]],[[10,3],[5],1,[3,2],[10,10,2,0,4]]]]
|
||||
[[[[0,5,7,2,1],[1,0,7],[1,8]],10],[9,10],[[0]]]
|
||||
|
||||
[[[5,[8,0,0],[4,1,10,3],0],[[5,4],[8,10,9,5],5,1],7,3],[],[9,[5,[4,8],[8,1,5,3,2],[1,4,6,1,5]],[[1,5,1,2,4]]],[[10],6,[],3],[[[0,9,7,4,3],9,[6,5,5,2,5]],8,9,5]]
|
||||
[[[[9,10,2],[6,8],6,[8,2,3]],4,[]],[[1],[10,[10,6,9],8,[9,9,4,7]],[[3]]],[],[6,[[],[4,9,5],[],9],[[8,2,6,1,6]],[[2,8,8],10,[5,9,0],[1,1,6,6],[9]],8],[]]
|
||||
|
||||
[[4],[9,[7,[7,7,3,10,1],6],0],[2,5],[[],1,9,[]]]
|
||||
[[[],[],[3,[6,4],[7,3],9]],[[3,[6],1],[[],8,1],4,[5,4,7,4,[5,10,1,8]],[10,7,0,4]],[[2,[9,3],[10,2,2,5,1],7,[]]]]
|
||||
|
||||
[[[[2,6],[4,9,6,1]],[[5,7,9,4,10],[8],7],[0],[5,8]]]
|
||||
[[[1,2,4,[1,1,2,10],10],1]]
|
||||
|
||||
[[10,[]],[6,9,[],2,[5,[5],[4,4,1,2],[9,0,5],[]]]]
|
||||
[[],[[7,10,[3,10]]]]
|
||||
|
||||
[[1,[[7,6,5,4,10],6,3,[10,8,1]],[[5,0,1,4],[8,8,4]],[10,[2,4,4,3,8],[10,8],2],4],[[],[6],[1,6],0],[[[4],[6,5,7,10]],9,[]]]
|
||||
[[],[1,0,2,[8,[8,0],10,5]],[[[9,1,4,4,6],8,8,1,5],[3,10,8,3],[]]]
|
||||
|
||||
[[[],[4,7,8],[3,5,1,10,[7,2,5]]]]
|
||||
[[[[8,8,10,8],[9,5,2,4,5],[5,2]],[]],[2,9],[[4,[3,0,7],[2,1,3]]]]
|
||||
|
||||
[[[10,7,9],3],[[2,[6,8,10,0],9,10,[]],[],1,10,[2,[8,8,10,10],10]],[[[8,7,5,4]],[[],7,[4,9,2,0,4],[0],1],7,2],[],[[8],[[0,0,7,8,1],2,0,[]],[[0,9,6,7,4]],[4]]]
|
||||
[[[],[[6,1,9,1]]],[[7,[]],2,4]]
|
||||
|
||||
[[7,10,9,10],[[[6,8,7]],10,10,[10,[1,7,1],9,7,[7]]]]
|
||||
[[[],[7,8,[0,10,7,5]],10],[8],[[],[[],6,10,[],[9,10,10]]]]
|
||||
|
||||
[[3,[],[]],[[[9,2,3],[6,8,9,5],[0,6,7,6,7],0,10],10],[],[],[3,[[0],[6,7],3,[1,2,10,2,9]]]]
|
||||
[[],[3,[[5],6,[1,3,1,5],[5,9,4]],[4],[],9],[0,9,10],[[4,8,[8,6]]],[[]]]
|
||||
|
||||
[[[7,[5],[1],[4,8,4,2,2]],8,1,0],[[5,[10,7,8,0],[7,4,9],[9]],1,4],[9,[],[10],3,2]]
|
||||
[[5],[[2]]]
|
||||
|
||||
[[1],[],[]]
|
||||
[[[[9,7,5,10],1],[],[]],[4,[0,[4],5,2,8],8],[[9,[1,0],3,0]],[8,0,[6,4,[10],5]],[[9,[6,3,1,0],[8,8]]]]
|
||||
|
||||
[[8,5,[9]],[2],[9,[],5,5,8],[3,5],[0,6,[],8,[3,0]]]
|
||||
[[10,10],[6,[[0,7,6],8,[0,4,8,1]],0,4,6],[3,10,[5,7]],[[3],[[10],1,5]]]
|
||||
|
||||
[[2,[[9,10],[1,8,8,6,1],[]]],[[[],2,[7,6,9,2,4],[],10],[[8,7,1,10,4],9,[5,4],0,1],[0,[2,2,9,0],9],9,4]]
|
||||
[[[6,1,1,[3,8],[9,4,3,6,8]],7,4,[]],[9,[],[[10],[8,8,3,1]],3]]
|
||||
|
||||
[[[[8,4,5]],5,[5,2,[3,1,10,8]]],[[[2,7,8,2,0]],[[3,10,4,4],10,0],6,9,3],[[],[10,1,1,[]],10,3]]
|
||||
[[[[7]],[],9,4],[[7,5],[],[[7,4,2],[8,9,2,0],4,1,[8,9,2,8]],1,[[6,5,6,5],[5],[],1]],[]]
|
||||
|
||||
[[[9],[8,8],10,[[6,5,0],3,6,[10,4],[10,4]],[10,[10,0,7,4,5]]],[]]
|
||||
[[3,[4,[],6]],[0]]
|
||||
|
||||
[[],[6,[7,9,9,[],2],[[],[5],10,3,7]],[2,1],[],[[],[[],4,[3],0,1],3,10,[9,0,5,5,0]]]
|
||||
[[[6,[6,2,0,10],0],[2,[9,4,8,0,6],[10,8,7,4,2],[],[]],0,0,[6,2,10,[6,7,10,1]]],[[]]]
|
||||
|
||||
[[[[2],4],6,8,4],[2,[[8,8,3,8]],[[9,8,10],[2,2,4,7]],[5,[2,8,7],4]],[[[]],[[2,1,2,9,2]],[[9],[6,10,0]]]]
|
||||
[[[[10,6,1]],[],[],[2,[2]],6],[[5,[0],[9],0,0],[3],5,[0,6,[3],10]],[],[[[],4,1],[4,0],2,2,[4,0,[2,6,4,5],10,[10,6]]]]
|
||||
|
||||
[[[],7,[2],[9]],[[],[[0,9,6],[0,5,4,5,2],[],7,3]]]
|
||||
[[],[10]]
|
||||
|
||||
[[[[],[7],[2,5]],3],[4,1,1,6],[]]
|
||||
[[]]
|
||||
|
||||
[[2,[[],[5],10,[7,10,5,6],[9,8,7]],[[8,9,4,10],0],[],[[0,7,8]]],[[9,3,0,2,7],1,[5,[3,10,7,7,2],[],[0,8,2],[3,0,6]],[],0]]
|
||||
[[[7],8,10,[[5,6,2,5]]],[[3,[]],8,[[],4],4],[[],[[9,0]]],[[[4,5,6,3,0],[6,1,4,2],[0],[7,10,3],7],[[5,2]],5,[[1,1,4,10,7],3,[1]]],[[8,[],[8],2],[8,[0,7],[10,8,9,4,4]],[5,[10]],[],5]]
|
||||
|
||||
[[2],[9,8,4],[7,9,4]]
|
||||
[[3,[[],3,[1,6,8,1,6],[],[3,3,10,6,8]],1,8,[0,0,[1,7,2],[0,0]]]]
|
||||
|
||||
[[10,[0,3,[8]],10],[],[[8,[],1,[5,0,6]]],[1],[4]]
|
||||
[[[[7,1,10,4,9]],1,[]],[[[4]],8,9,5]]
|
||||
|
||||
[[7,[3,6,6],7,[[9]],[[5,8]]]]
|
||||
[[],[[6,9,4,5],[0],[],4],[[9,[3],[5,1,5,9],3],[]],[[0,10,[5,4,6]],[[0,3]]]]
|
||||
|
||||
[[5,[0],0,[5]],[[[],[6,9,1,4,9],6,[9,9],[2,1,6,2,2]],5,10,[[0,9,6]],7]]
|
||||
[[8,1,6],[10,[4,[2,5,3,2,2],[6,1,3,3]],5,[[10,4,7,1],[9,2],1]],[9,[2]],[],[[[9,6,10],[0,0],[2]]]]
|
||||
|
||||
[[10,0,10],[[[0,6,1],[7,3,5,5,0]]],[0,[[4,7,3,4],[],[3],8,[9,3]],6]]
|
||||
[[4,[[3],9,[1,3,5,2,5],[9]]],[[6,7],9],[],[]]
|
||||
|
||||
[[[[0,9,4,3],[9],1,[7,2]],[[],1,2,[9,2,1,5,5],[5,5,7]]],[]]
|
||||
[[[[6,1],9],1],[[[2,6,2]],2,3],[3,6,[4,[9,1],7,[0,10,6]],[1,[10,7],[2,8,7,3,1],[6,5]],[7,2,0]]]
|
||||
|
||||
[[[[3],8,[10,5,9,10,5],5]],[]]
|
||||
[[7,8,5,6],[[7,[1],[1,9,1],[],4],[[10,4,9,10],[7,1,1,6,3],6],10]]
|
||||
|
||||
[[[[8,7,5],8,[1],7]],[[3]]]
|
||||
[[[8,[1,0,7,6],[],[1,3,8,3]]],[1,[8,2,[1]],[[4],7,0,5,6],[[],0,0,7,9],4],[6,6,2,6,0],[],[7]]
|
||||
|
||||
[[4],[[0,[9,9],4,0,[2,3]],[3,5,[7,3,8,4,9],5],[2,9,10],[6,[6],5,4]],[]]
|
||||
[[[6,9,[3,4],0,[]]],[10,7,3,[[6,2,4,10],[3,7],10],5],[],[[10,[9,8,0],0,1,[8,8,9]],[[0,5,1,5,6],7,6],[[8,7,1],10,[0]]]]
|
||||
|
||||
[[10,[[3,4],5,5,8,[1,7,8]],7,[10,[7,1,1,7,0],[8,2,9],9,[]],[[6,9],8,3,[4,7,9]]],[8,8,[[1,1,7,5],[8],1,0,9]],[[[2,10,6,7],[6,10,3,4,6]],[]],[6]]
|
||||
[[[5,3,[4]],4,4,1,[3,[],4,[4],9]],[[10,10,[2,8]]],[]]
|
||||
|
||||
[[5,8,0,9,6],[],[3],[[[10,3,6,9]],3,7,[0]],[[]]]
|
||||
[[1,[]]]
|
||||
|
||||
[[9,[[],7,[2],5,[6]],[]],[[6,6,2],4],[],[0],[[5,[3,9,0,2],[],9],[[1],[1,3,1,2,4],6],1,[[7,9],0,[],5]]]
|
||||
[[],[1,6,8,[4,7]],[[[1,0,4,7],[0]],[[9,8],0,[8,7,8]],[[2,3,2,6,1]]],[[],[[8,4,8],[0,6],7,5],[[7,10,2,6],[5,3,8,10,6],5,2],4,2]]
|
||||
|
||||
[[],[7],[5,10,[[5,10,1,7],[4],8],[[],2,9,[7,2]],4]]
|
||||
[[[[7,8,3],0],8,2]]
|
||||
|
||||
[[7,2,[[10],[5,2,1,3,8],0,5]],[],[5,[5],3],[[[10,2,6,9],0,[5,8,6,2,3],10,[4,6,10,10,3]],[[10,1,9],1,[0,2,6],4,[7,5,10]],7,[[1,7,4,6]],10],[[[0],7,5,[9,4],2],0,[[],[4,7],[9,2,7,3,4]]]]
|
||||
[[[],[[1,10,6,1,10],5,10],4],[9,[[]],1]]
|
||||
|
||||
[[7],[]]
|
||||
[[[[9,2,10,10,7],[1,6,6],[10,0,9]]],[[8,9,4,10,0],[[],5],4],[[]]]
|
||||
|
||||
[[[[9,7,10],9,7,[6,10]],[[8,0,7,2]],[8,4,[10]]],[],[7,[8,[6,3,5]],[7,[0,4,4,9,9]]],[[[4,10,2],[5,7,3,3],[1,4,6,4,2],[8,7,10,7,1],4],[2],3,[[],9,10,[2,4]]],[[[]],[0,[4,7]],[]]]
|
||||
[[],[7],[10,6,10,[[]]],[9,[[],6],[[4,2,5,5]],[[7,1,9],7]],[0,5,3,10,7]]
|
||||
|
||||
[[5],[0,[[0],10,[1,2]],10,[],8],[[[6,0],6,7,[]]],[2,[8,[7,0,5,5],[0,3,0],[],[1]],2,[2,10,[5,5,3,0,1],0,[1,2]]],[]]
|
||||
[[],[[3,[],[],[9,4,2,9],[]],[6,9,8,6,[7,9,4,2]],6,0,[[],[10,5]]],[]]
|
||||
|
||||
[[],[]]
|
||||
[[7,4,[9,3]],[2,[[]],[[4],[1,3],6,[8],8],[1,[8,5],1,3]],[6,0,8],[4,5,2,7]]
|
||||
|
||||
[[[[9],[5,6,7,1],10,9],7],[[[3],[9,7,1],4,[7,9]],5,6,6]]
|
||||
[[],[[],[8],[9,1,[6,3,6,8,9],[5,7,9,5]]]]
|
||||
|
||||
[[],[5,[[8]],2,[]],[9],[10],[10]]
|
||||
[[[[4,10],9,[5,9,8,5,3],1],[[5,0,7],[10,10,5,5,4],[9,10,7,6],[1,2]]],[2,7,1,[1,4]],[[],[[2]],8],[8,4,[5,8,[8],[2,10]]],[]]
|
||||
|
||||
[[],[1],[0],[],[6]]
|
||||
[[],[[5]]]
|
||||
|
||||
[[[[0,6,9,5,10],6,[0],0]],[[7,[]]],[3],[3,8,[[0,3],6,10,[4],[]]]]
|
||||
[[1,[],8,[[1,3],8,8],[[],1,[8,9],6]],[[[6,2,6,4],[4,5],[3,6,4,6],7,[]]],[2,5],[8,[1,[9,9,9,8,6],[10]],9,[[2,5],7,[5,4,8],3],7],[8,0,[4,9,9,9,[5,6,2]]]]
|
||||
|
||||
[[[5,[2,0,3]],[[],5,4],2],[3,[4],[[2,3,0,6]],9,1],[],[[0,6,1,[1,10,0],5],5,[1,1,5,9,[2,8]],10],[7,[[],[7],[4,3,4],7,[8,8]]]]
|
||||
[[],[7,10,9,[[2,8,5,5],[2,1,9],4,[],[6,8]],[7,4]]]
|
||||
|
||||
[[[[],[1],[8,9,3,9],8],[[5],5,10,8],[3,5]],[[4,4,10,0],3,[[4,9,3],[6],[6,7,4,7,10],4,[4,9,2]],[10,7,[],[6,4],[7,7]],4]]
|
||||
[[[[2,5],1,0]],[[[0],10,[2,1,9],[3,7,8,10,7]],7,[[6,7,3],10,0,[10,8,6],[9,9,5,4]],[4,4,3,[7,4,10,4,1],[1]]]]
|
||||
|
||||
[[[0,[9,1,6,7,10],7],3],[3],[[1,10],[[4,3,1,7,10],6,2,[9,3,3]],4],[[6,[]],[2,[9,2,6,5]]]]
|
||||
[[3,7,[],2,[[],[1,4,9,1,10],0]],[8,[7,1,6],[4,[0,9,4,1]]],[4,[[9,9,2],4]],[2,8,[7,[8],[9],[6,7]],1]]
|
||||
|
||||
[[8,9,[[2,0],[],4,[8]],7,[[10,10],[9,3,1,1],7,6]],[[9],[[],5,[2,1,2,6]]],[[]],[[9,[7,3,2,2],10],4]]
|
||||
[[[]]]
|
||||
|
||||
[[1,3]]
|
||||
[[[2,[2,1,9,5,3],1,9],4],[[[2,3,9,5],9,[9,2,4,3],0]],[[[3]]]]
|
||||
|
||||
[[6,5,[[6,4,7,5,7]],[[]]],[[[5]],4],[[2]]]
|
||||
[[],[5,[[2],8,1,[1,3,7,5,0],6],[[1,4,4,8,10],[2,7,9,9,4],1,0],9]]
|
||||
|
||||
[[[10,[6,0],10,2,7],[[6,1,7,1,6],[],3,[9,8,2,0],10],[2,[8,0],6,0,[6,2,4]],5,5],[[[6,1,5,3]],[[10],5,[]]]]
|
||||
[[],[10,6,5,10,9],[1,4,8]]
|
||||
|
||||
[[[[1,0,10,3,8],[10],[7,8,3,6],3],[5,[10,6,9],1,8],0,[[],[5],[]],[[7,3,3],0,[0,7,9,0,10]]],[[[3]]],[10],[1,4,[[],[0,1],[9,9,4,8],10,10],[]]]
|
||||
[[[1,[4,6,1]]],[6,5,8,6],[1,[[6]]],[3,[[1],[]]],[[5,[4,3,10],[6,1,10,1],[7,4]],[[9,10]],[10,3,1,[6,5],[0,5]]]]
|
||||
|
||||
[[1,[5,[6,5],9,10]],[[[1,5,0,5,5],[9,1,6,8],7,7,[7,5]],[[8,10,3,9],3,4],1],[10,8,3,[8,1,9,6],[4]]]
|
||||
[[7,1,[8,[10,9,0],[4,2],10,9]]]
|
||||
|
||||
[[[[4],[7,3,8],[10,9]],[[8],4,[],[9,9,7,9,2]]],[],[[[],10,4],3,4,1,[9,5,6]]]
|
||||
[[[]],[[0,[1],7,[1,4,10,7],[10,10,9]]],[[[4,7,0],3,3,2]],[9,0,0,5],[10,[6,8,0,[7,8],7]]]
|
||||
|
||||
[[[4,9,9,6],10,[[],[4,1,4,9,1],7,4,7],[5,[],4],[1,9,[9,1],0,0]],[10,[2,1,[7,3,7]],[0,[1,5,8,6,8],[3,5,2],[9],1]],[4,8,10],[[[],7,1,10,[8,8,5]]]]
|
||||
[[[]],[[6,1],[[2]]],[[[]]]]
|
||||
|
||||
[0,0,1,4]
|
||||
[0,0,1,4,10]
|
||||
|
||||
[[],[10,[[4,5,7,1],[9,0,9,0,0],[6,10,1],4],[[2,4,6,0],2,8,[]]]]
|
||||
[[[7],10,[],8,[[2,7,10,0]]],[10]]
|
||||
|
||||
[[6],[],[9,9]]
|
||||
[[[],1,[8,[5,7,5,0,10],6,[7,5]]],[[],[],7,5],[[0],[10,4,9],8,[[2],[1,7,0,9],1,[1,3]]],[10,[],[],6,[[0,6,7],10,7]]]
|
||||
|
||||
[[9,8,[[10,10,9,5,10],[8,2,1]],10,5],[2,[9,[1],9],[[4,10,3]],[[4,9,4],9,[4,1,5,10]]]]
|
||||
[[10,0,7],[],[]]
|
||||
|
||||
[[1,[9,9,2,9],4,7],[10,[6,9,[7,6],8]],[],[[2,2,[6,3],[10,1]],6],[]]
|
||||
[[3,10],[],[[],[[10],10,[7],[6]],[]],[4]]
|
||||
|
||||
[[4,7,[8,1],[[9],0,[3,6,0,7],9,9]],[10],[1,8,[]],[],[[],4]]
|
||||
[[4,[1,9,5,0,2],9],[[[4,7,8],[6,0]]],[],[5,[0,[],[2,10,0,2],[1,6],8],6,7],[]]
|
||||
|
||||
[[2,[]],[[[10,9,8,7],5,[],[3],[10,2]],[9,[8,9],[8,1,4,3],4],7,2,6],[[[0],2,9,2,[]],[8,[6,0,7,10],1,1,5]]]
|
||||
[[[3],[0],[[2,5,10,0],[],9],2],[4,[9,[7],[7,9],[9,2,5,3,6]],4,[[],1,[],1],10],[[[2,10,2,1,3],[3,8,5,3,10],[5,4,5,5],[],6],[[5],5,6]]]
|
||||
|
||||
[[9]]
|
||||
[[[10],[[9,4,8]],[[],1,[10],[7,1]],[[1,0],[4,2],[1,5,5,3,9],1]],[5]]
|
||||
|
||||
[[[6,5,[2,3,10],9,8],[[],[8,1],3],[[],7,[5,4],[0,1,8,7,0],4],[3],[[2,0,0],1,[4,7,0,4],[],[]]],[4],[2,8,[[4],7,[10,10,9]],5]]
|
||||
[[5,0],[[1,4,[0]],[[1],[8,7,7,8]],[[7,7,9,1],4,7,6],[10],7],[[],9],[[5,[10,8],0],8],[9,[[8],7,10],[0,[10,3],1,5,3]]]
|
||||
|
||||
[[0,[6,10],[[4,1,9],[],10,[10,6,2,7,3]]]]
|
||||
[[[[1],[1],[],10],10,9,8,[[]]]]
|
||||
|
||||
[[[],1,[[8,1,9,5],0,10,[1],[9,1,5,0]],6,4],[[[8,2,7,0,6],6,1]],[[[6,3,10]],6],[[],[[5,0,8,10,9],[2]],8],[]]
|
||||
[[[],5,[6,[0,6,8],[7,5,5,0,6],6,[]],[]],[[],3,0,3,[3,6]],[7,5,[[7,0,6,8],[9,5],[]]],[[[2],5,[1,0,5]],8,4,[[5,10,9],[0,2],10,[2]]],[]]
|
||||
|
||||
[[[2,3]]]
|
||||
[[[[],[6],[4,9,10,6,3]],4,[]],[],[[],7,[],2],[]]
|
||||
|
||||
[[9,[5,8,9],1,1,6],[[[8,6]],3],[8,[[8,7,10],[]]]]
|
||||
[[1,7,[7,7,4,[10,0,0],[10,10,10,10]]],[[[],[9,5]],[0,2,[8,4],[],[7,8,2]],[]],[[6,[7,0],[9,1],8,[]],4,1],[]]
|
||||
|
||||
[[],[6,1,[[2,1,10],7,4,[7]],[],0],[]]
|
||||
[[[],8,[4,[9,9],3]],[]]
|
||||
|
||||
[[],[8],[[[9,3,10],[]],[10,[1,0,1],2]]]
|
||||
[[[[7,9,3,3,10],4,8,[7,0,2,10,10],4],4,[8,10,[0,1,1]],6,[]]]
|
||||
|
||||
[[[3,8,10],0]]
|
||||
[[1,[],3,[[5],[2,4,3,5],1,[6,8,6,2],[0,10]],[[6,6,3],[4,4]]],[9]]
|
||||
|
||||
[[],[],[[8,[0,7,9],2]]]
|
||||
[[6,4],[[6,6,9],[[0,10,1]],[[],0,1,[],3],[[1,4,4,8,4]]],[4,[[3,1,5,7,6],7,[9,3,6,10]],[8,[0,10,1,10,10]],[[8,7,7],[8,2,7,7,8],0],[[7,7,8,5]]],[10,1,5,[[2,5,4],10,[]],1],[[4],1]]
|
||||
|
||||
[[1,[9,10,[7,4,7,9],0,[7]],3,[[1,2,8],[7,6,8],[4,9,8,1,6],6],9],[5,9,7,[[7,2,6,4,8]]]]
|
||||
[[[[5,2,3],[0,8,2],2],[0,3,[9,1,5,2]],[2,6,6,4],1]]
|
||||
|
||||
[[7,[9,[0,9],5],[[4,3,6,7],7],2,2],[[[0,4,1,8,4],3,[],[]],[],5]]
|
||||
[[[],[[],3,1,9],10],[]]
|
||||
|
||||
[[3,[8],8,4],[8,3,[[2,0,8,9,0],6,6]]]
|
||||
[[[7,3,[6,5,5],5],8,6,2],[[[],1,[2,8,5],[],[4,10,9]],7,[],[8]]]
|
||||
|
||||
[[],[[[6,3,8,3],[6,4,7,2,9],0],6,[]],[9,[],6,8,[]],[]]
|
||||
[[[[],[],1,[0,9,8],3],6,7],[[0,[5,7,3,0,10],0,[],7],3,9,[[6],[3],2],7]]
|
||||
|
||||
[[8,0,[[5,5],[0,2,4],3,[5],[2]],6],[0]]
|
||||
[[5,10,7,0,[[7,9,10,2,6],[8,6]]],[[6,[9,4,3,1]],[8,3],[[3,6,7,8,6],3,[],[9],[1,2,4,7,10]]],[[],2,9,8]]
|
||||
|
||||
[[],[3,[[4,5,5,9,0]],8,[],[[3,7,8,10,2],7,10,[0,2,1,7]]],[[[2,6,2,0,10]]],[7,[]],[6,[],6,[[2,1,8],7,0],[[9,9,1],[],[9,4,3,1,5],[10,6,3,6,9]]]]
|
||||
[[4,1,[],10,10],[[5,7],[],5]]
|
||||
|
||||
[[[[],7],4,3,[[],4,[4,8,3,3,3],2,10],[5]],[[7],[10,[],[9,9,3,9],[8,8,5,4],[5,6,4,10]],[7,10,[6,4,0,4],[7,0,0]]],[3,[1]],[3,[[9,8,3,4,9],10,[0,1]]],[[[3,6],6]]]
|
||||
[[],[9,2,5,4],[[[0,9,2,3],7,[1,10,2],6,10],4,5,2],[[[4,9],[7,1,0,1],4],[[2,2,8],[4,3,10,9,2],4,9,[]],3,7,8],[]]
|
||||
|
||||
[[7],[8,[8,[2,7],7,3]],[],[[]]]
|
||||
[[],[[8,10,2],8]]
|
||||
|
||||
[[5,[]],[[[4],8]]]
|
||||
[[[[],7,2,3],9,[],[[1],9,[]],1]]
|
||||
|
||||
[[5],[6,[8,1,[6,7,9,5],9],0]]
|
||||
[[6,5,2]]
|
||||
|
||||
[[0,[[8,6,3,8],1,6,[1,4],[2,2,1,0]],1,8],[[4,3,[],[],3],6,[],[3,[0,0,7,6]],[3,[],[9,6,10,10,2],0,[3]]],[],[[1,[]],6,[[0,9,6,1,4],2,2],8,[[7],6,8,7]],[3,1,8,9]]
|
||||
[[4],[[[10,3,10,5,0],[],[5,1,1,9],[9,8],2],2,9],[6,0,[[4,4,5,6,8]]],[[1,6]]]
|
||||
|
||||
[[8,9,7,6],[9,[9,[9]],1],[[],[6,[]],[[2],1,[4,5,8,8,7]]],[0,4,[[4,7,7,0],[10,2],4,9],[[]],5],[4]]
|
||||
[[],[9],[9],[9],[[[],[],[1,0],[5,10,6]],6,[[9,0],2,4],8]]
|
||||
|
||||
[[],[10],[[[4],[],[5,6],[7,10,5,2]]]]
|
||||
[[[],6],[[8,3],[2,5,2,[10,7,8,4]]],[[0,1,9,[10,3,7],8],4,3,[[9],7],0]]
|
||||
|
||||
[[6],[],[[[6],[7,5,2,7],[3,7]],1,[[7,0,3],[],[7]],6],[5,5],[[9,1,[0,10,10],[3,0,4,0],3],[6,8,1],2]]
|
||||
[[[9,10,[1,8,4],10]],[1,[]],[]]
|
||||
|
||||
[[2,[[9,5,4],4,[10]],[[10],[8,9,10,6,3],[6],9,[8,5,3]],[]],[[[9,8],[0,6],1,10,[0,10,4,6,8]],[[9,8,6]]],[3,4,[1,1,2,[1,4,5,2,2]]]]
|
||||
[[7,[8,[1,8,1,8,8]],[[0,10],9],[],4]]
|
||||
|
||||
[[[[2,0,4,1],2],[3,7,[8,2,1]],4,[[10,3]]],[6,9,[[1,6,9,6,6],4,[]]],[[7,10],9],[5,[[4,2,9,1],[6,6],[4,4,0],[7,2,2]]]]
|
||||
[[[0,10]],[]]
|
||||
|
||||
[[4,4,4],[1,[10,[],10,6,[8,8,3,7,7]],6],[[0,8,[9],4,[3,6]],[[4,5,3,6,8],4]],[1,[[3],[]]]]
|
||||
[[10,4,7,[[8,9],7,7,[10,1,2],10],[[9,8],1]],[],[[4,10,[]]]]
|
||||
|
||||
[[[[4]],3,[[9,3,3,8,3],5,[1,3,9],5,[4,4]],[1,[5]],[[6,9,8],2,5,[1,5],4]],[[[],4]],[]]
|
||||
[[],[[9,1,[5,8],[8,9],1],[[]]],[7,0,[[3],4,5],8],[],[1,[3,[0,0,6],[],[]],6,8,1]]
|
||||
|
||||
[[4],[8,4,[3,6,[],2]],[[[2,10,8,0,5],[7,4,9,5],[5,10,7],[10,2,5,0,7]]]]
|
||||
[[],[[[3,0],0],[],[[4,4],[1]],[5,[7,7,8,9,10]]],[9]]
|
||||
|
||||
[[],[[[3,9,10],0],[9,10,[10,10,10,2,2],[5,10,0,6,9],6],[9,3,10,7,[2,5]]]]
|
||||
[[7]]
|
||||
|
||||
[[[],7],[6],[2,8,[5,6,[9,0,2,10,8],3,5],7],[4,9,[[1,10,1,6],3,4],1],[2]]
|
||||
[[],[[[8,3,0,10],6,0,[10,7,2]]],[5,9,0,4]]
|
||||
|
||||
[[[[1,4],8,10,6],[0],1],[],[5,4,0],[[6,4,6,6]],[]]
|
||||
[[[8,3,[0,8,4,4]]],[],[[7,[],[3,8,1,1]],10,[[],[],6,[9,7,1,10,9]],[8,[3,2,0],4,[7,9,2,5,3],[9,6,7,6]],3]]
|
||||
111
2022/day14/Makefile
Normal file
111
2022/day14/Makefile
Normal file
@@ -0,0 +1,111 @@
|
||||
# AOC daily Makefile - GNU make only.
|
||||
#
|
||||
# Copyright (C) 2021-2022 Bruno Raoult ("br")
|
||||
# Licensed under the GNU General Public License v3.0 or later.
|
||||
# Some rights reserved. See COPYING.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License along with this
|
||||
# program. If not, see <https://www.gnu.org/licenses/gpl-3.0-standalone.html>.
|
||||
#
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later <https://spdx.org/licenses/GPL-3.0-or-later.html>
|
||||
#
|
||||
|
||||
INPUT := input/input.txt
|
||||
SHELL := /bin/bash
|
||||
|
||||
CC := gcc
|
||||
BEAR := bear
|
||||
CCLSFILE:= compile_commands.json
|
||||
|
||||
LIB := aoc_$(shell uname -m)
|
||||
INCDIR := ../include
|
||||
LIBDIR := ../lib
|
||||
LDFLAGS := -L$(LIBDIR)
|
||||
#LDLIB := -l$(LIB) -lm
|
||||
LDLIB := -l$(LIB)
|
||||
|
||||
export LD_LIBRARY_PATH = $(LIBDIR)
|
||||
|
||||
CFLAGS += -std=gnu11
|
||||
CFLAGS += -O2
|
||||
CFLAGS += -g
|
||||
# for gprof
|
||||
# CFLAGS += -pg
|
||||
CFLAGS += -Wall
|
||||
CFLAGS += -Wextra
|
||||
CFLAGS += -march=native
|
||||
# Next one may be useful for valgrind (some invalid instructions)
|
||||
# CFLAGS += -mno-tbm
|
||||
CFLAGS += -Wmissing-declarations
|
||||
CFLAGS += -Wno-unused-result
|
||||
|
||||
CFLAGS += -DDEBUG_DEBUG # activate general debug (debug.c)
|
||||
CFLAGS += -DDEBUG_POOL # memory pools management
|
||||
|
||||
VALGRIND := valgrind
|
||||
VALGRINDFLAGS := --leak-check=full --show-leak-kinds=all --track-origins=yes \
|
||||
--sigill-diagnostics=yes --quiet --show-error-list=yes
|
||||
|
||||
|
||||
TIME := \time -f "\ttime: %E real, %U user, %S sys\n\tcontext-switch:\t%c+%w, page-faults: %F+%R\n"
|
||||
export PATH := .:$(PATH)
|
||||
|
||||
.PHONY: clean all compile assembly memcheck memcheck1 memcheck2 part1 part2 ccls bear org
|
||||
|
||||
all: README.org ccls part1 part2
|
||||
|
||||
memcheck: memcheck1 memcheck2
|
||||
|
||||
memcheck1: aoc-c
|
||||
@$(VALGRIND) $(VALGRINDFLAGS) aoc-c -p 1 < $(INPUT)
|
||||
|
||||
memcheck2: aoc-c
|
||||
@$(VALGRIND) $(VALGRINDFLAGS) aoc-c -p 2 < $(INPUT)
|
||||
@#@valgrind -s --track-origins=yes aoc-c -p 2 < $(INPUT)
|
||||
|
||||
compile: aoc-c
|
||||
|
||||
cpp: aoc-c.i
|
||||
|
||||
assembly: aoc-c.s
|
||||
|
||||
part1: aoc-c
|
||||
@#$(TIME) aoc.bash -p 1 < $(INPUT) 2>&1
|
||||
@$(TIME) aoc-c -p 1 < $(INPUT)
|
||||
|
||||
part2: aoc-c
|
||||
@#$(TIME) aoc.bash -p 2 < $(INPUT) 2>&1
|
||||
@$(TIME) aoc-c -p 2 < $(INPUT)
|
||||
|
||||
ccls: $(CCLSFILE)
|
||||
|
||||
clean:
|
||||
@rm -f aoc-c core* vgcore* gmon.out aoc-c.s aoc-c.i README.html compile_commands.json
|
||||
|
||||
aoc-c: aoc-c.c common.c
|
||||
@echo compiling $<
|
||||
$(CC) $(CFLAGS) $(LDFLAGS) -I $(INCDIR) $^ $(LDLIB) -o $@
|
||||
|
||||
# generate pre-processed file (.i) and assembler (.s)
|
||||
%.i: %.c
|
||||
@echo generating $@
|
||||
@$(CC) -E $(CFLAGS) -I $(INCDIR) $< -o $@
|
||||
|
||||
%.s: %.c
|
||||
@echo generating $@
|
||||
@$(CC) -S -fverbose-asm $(CFLAGS) -I $(INCDIR) $< -o $@
|
||||
|
||||
# generate README.org from README.html (must cleanup !)
|
||||
org: README.org
|
||||
|
||||
%.org: %.html
|
||||
@echo generating $@. Cleanup before commit !
|
||||
@pandoc $< -o $@
|
||||
|
||||
# generate compile_commands.json
|
||||
$(CCLSFILE): aoc-c.c Makefile
|
||||
$(BEAR) -- make clean compile
|
||||
|
||||
bear: clean
|
||||
@touch .ccls-root
|
||||
@$(BEAR) -- make compile
|
||||
232
2022/day14/README.org
Normal file
232
2022/day14/README.org
Normal file
@@ -0,0 +1,232 @@
|
||||
** --- Day 14: Regolith Reservoir ---
|
||||
The distress signal leads you to a giant waterfall! Actually, hang on -
|
||||
the signal seems like it's coming from the waterfall itself, and that
|
||||
doesn't make any sense. However, you do notice a little path that leads
|
||||
/behind/ the waterfall.
|
||||
|
||||
Correction: the distress signal leads you behind a giant waterfall!
|
||||
There seems to be a large cave system here, and the signal definitely
|
||||
leads further inside.
|
||||
|
||||
As you begin to make your way deeper underground, you feel the ground
|
||||
rumble for a moment. Sand begins pouring into the cave! If you don't
|
||||
quickly figure out where the sand is going, you could quickly become
|
||||
trapped!
|
||||
|
||||
Fortunately, your [[/2018/day/17][familiarity]] with analyzing the path
|
||||
of falling material will come in handy here. You scan a two-dimensional
|
||||
vertical slice of the cave above you (your puzzle input) and discover
|
||||
that it is mostly /air/ with structures made of /rock/.
|
||||
|
||||
Your scan traces the path of each solid rock structure and reports the
|
||||
=x,y= coordinates that form the shape of the path, where =x= represents
|
||||
distance to the right and =y= represents distance down. Each path
|
||||
appears as a single line of text in your scan. After the first point of
|
||||
each path, each point indicates the end of a straight horizontal or
|
||||
vertical line to be drawn from the previous point. For example:
|
||||
|
||||
#+begin_example
|
||||
498,4 -> 498,6 -> 496,6
|
||||
503,4 -> 502,4 -> 502,9 -> 494,9
|
||||
#+end_example
|
||||
|
||||
This scan means that there are two paths of rock; the first path
|
||||
consists of two straight lines, and the second path consists of three
|
||||
straight lines. (Specifically, the first path consists of a line of rock
|
||||
from =498,4= through =498,6= and another line of rock from =498,6=
|
||||
through =496,6=.)
|
||||
|
||||
The sand is pouring into the cave from point =500,0=.
|
||||
|
||||
Drawing rock as =#=, air as =.=, and the source of the sand as =+=, this
|
||||
becomes:
|
||||
|
||||
#+begin_example
|
||||
4 5 5
|
||||
9 0 0
|
||||
4 0 3
|
||||
0 ......+...
|
||||
1 ..........
|
||||
2 ..........
|
||||
3 ..........
|
||||
4 ....#...##
|
||||
5 ....#...#.
|
||||
6 ..###...#.
|
||||
7 ........#.
|
||||
8 ........#.
|
||||
9 #########.
|
||||
#+end_example
|
||||
|
||||
Sand is produced /one unit at a time/, and the next unit of sand is not
|
||||
produced until the previous unit of sand /comes to rest/. A unit of sand
|
||||
is large enough to fill one tile of air in your scan.
|
||||
|
||||
A unit of sand always falls /down one step/ if possible. If the tile
|
||||
immediately below is blocked (by rock or sand), the unit of sand
|
||||
attempts to instead move diagonally /one step down and to the left/. If
|
||||
that tile is blocked, the unit of sand attempts to instead move
|
||||
diagonally /one step down and to the right/. Sand keeps moving as long
|
||||
as it is able to do so, at each step trying to move down, then
|
||||
down-left, then down-right. If all three possible destinations are
|
||||
blocked, the unit of sand /comes to rest/ and no longer moves, at which
|
||||
point the next unit of sand is created back at the source.
|
||||
|
||||
So, drawing sand that has come to rest as =o=, the first unit of sand
|
||||
simply falls straight down and then stops:
|
||||
|
||||
#+begin_example
|
||||
......+...
|
||||
..........
|
||||
..........
|
||||
..........
|
||||
....#...##
|
||||
....#...#.
|
||||
..###...#.
|
||||
........#.
|
||||
......o.#.
|
||||
#########.
|
||||
#+end_example
|
||||
|
||||
The second unit of sand then falls straight down, lands on the first
|
||||
one, and then comes to rest to its left:
|
||||
|
||||
#+begin_example
|
||||
......+...
|
||||
..........
|
||||
..........
|
||||
..........
|
||||
....#...##
|
||||
....#...#.
|
||||
..###...#.
|
||||
........#.
|
||||
.....oo.#.
|
||||
#########.
|
||||
#+end_example
|
||||
|
||||
After a total of five units of sand have come to rest, they form this
|
||||
pattern:
|
||||
|
||||
#+begin_example
|
||||
......+...
|
||||
..........
|
||||
..........
|
||||
..........
|
||||
....#...##
|
||||
....#...#.
|
||||
..###...#.
|
||||
......o.#.
|
||||
....oooo#.
|
||||
#########.
|
||||
#+end_example
|
||||
|
||||
After a total of 22 units of sand:
|
||||
|
||||
#+begin_example
|
||||
......+...
|
||||
..........
|
||||
......o...
|
||||
.....ooo..
|
||||
....#ooo##
|
||||
....#ooo#.
|
||||
..###ooo#.
|
||||
....oooo#.
|
||||
...ooooo#.
|
||||
#########.
|
||||
#+end_example
|
||||
|
||||
Finally, only two more units of sand can possibly come to rest:
|
||||
|
||||
#+begin_example
|
||||
......+...
|
||||
..........
|
||||
......o...
|
||||
.....ooo..
|
||||
....#ooo##
|
||||
...o#ooo#.
|
||||
..###ooo#.
|
||||
....oooo#.
|
||||
.o.ooooo#.
|
||||
#########.
|
||||
#+end_example
|
||||
|
||||
Once all =24= units of sand shown above have come to rest, all further
|
||||
sand flows out the bottom, falling into the endless void. Just for fun,
|
||||
the path any new sand takes before falling forever is shown here with
|
||||
=~=:
|
||||
|
||||
#+begin_example
|
||||
.......+...
|
||||
.......~...
|
||||
......~o...
|
||||
.....~ooo..
|
||||
....~#ooo##
|
||||
...~o#ooo#.
|
||||
..~###ooo#.
|
||||
..~..oooo#.
|
||||
.~o.ooooo#.
|
||||
~#########.
|
||||
~..........
|
||||
~..........
|
||||
~..........
|
||||
#+end_example
|
||||
|
||||
Using your scan, simulate the falling sand. /How many units of sand come
|
||||
to rest before sand starts flowing into the abyss below?/
|
||||
|
||||
Your puzzle answer was =665=.
|
||||
|
||||
** --- Part Two ---
|
||||
You realize you misread the scan. There isn't an endless void at the
|
||||
bottom of the scan - there's floor, and you're standing on it!
|
||||
|
||||
You don't have time to scan the floor, so assume the floor is an
|
||||
infinite horizontal line with a =y= coordinate equal to /two plus the
|
||||
highest =y= coordinate/ of any point in your scan.
|
||||
|
||||
In the example above, the highest =y= coordinate of any point is =9=,
|
||||
and so the floor is at =y=11=. (This is as if your scan contained one
|
||||
extra rock path like =-infinity,11 -> infinity,11=.) With the added
|
||||
floor, the example above now looks like this:
|
||||
|
||||
#+begin_example
|
||||
...........+........
|
||||
....................
|
||||
....................
|
||||
....................
|
||||
.........#...##.....
|
||||
.........#...#......
|
||||
.......###...#......
|
||||
.............#......
|
||||
.............#......
|
||||
.....#########......
|
||||
....................
|
||||
<-- etc #################### etc -->
|
||||
#+end_example
|
||||
|
||||
To find somewhere safe to stand, you'll need to simulate falling sand
|
||||
until a unit of sand comes to rest at =500,0=, blocking the source
|
||||
entirely and stopping the flow of sand into the cave. In the example
|
||||
above, the situation finally looks like this after =93= units of sand
|
||||
come to rest:
|
||||
|
||||
#+begin_example
|
||||
............o............
|
||||
...........ooo...........
|
||||
..........ooooo..........
|
||||
.........ooooooo.........
|
||||
........oo#ooo##o........
|
||||
.......ooo#ooo#ooo.......
|
||||
......oo###ooo#oooo......
|
||||
.....oooo.oooo#ooooo.....
|
||||
....oooooooooo#oooooo....
|
||||
...ooo#########ooooooo...
|
||||
..ooooo.......ooooooooo..
|
||||
#########################
|
||||
#+end_example
|
||||
|
||||
Using your scan, simulate the falling sand until the source of the sand
|
||||
becomes blocked. /How many units of sand come to rest?/
|
||||
|
||||
Your puzzle answer was =25434=.
|
||||
|
||||
Both parts of this puzzle are complete! They provide two gold stars: **
|
||||
194
2022/day14/aoc-c.c
Normal file
194
2022/day14/aoc-c.c
Normal file
@@ -0,0 +1,194 @@
|
||||
/* aoc-c.c: Advent of Code 2022, day 14
|
||||
*
|
||||
* Copyright (C) 2022-2023 Bruno Raoult ("br")
|
||||
* Licensed under the GNU General Public License v3.0 or later.
|
||||
* Some rights reserved. See COPYING.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with this
|
||||
* program. If not, see <https://www.gnu.org/licenses/gpl-3.0-standalone.html>.
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later <https://spdx.org/licenses/GPL-3.0-or-later.html>
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <limits.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "br.h"
|
||||
#include "list.h"
|
||||
#include "pool.h"
|
||||
#include "debug.h"
|
||||
|
||||
#include "aoc.h"
|
||||
|
||||
pool_t *pool_segment;
|
||||
|
||||
#define INF (-1) /* found infinite fall position */
|
||||
|
||||
typedef enum { /* map cells */
|
||||
EMPTY = '.',
|
||||
STONE = '#',
|
||||
SAND = 'o',
|
||||
} type_t;
|
||||
|
||||
typedef struct segment {
|
||||
int x1, y1, x2, y2;
|
||||
struct list_head list;
|
||||
} segment_t;
|
||||
|
||||
LIST_HEAD(segments);
|
||||
|
||||
typedef struct map {
|
||||
int xmin, xmax, ymin, ymax;
|
||||
int size_x, size_y;
|
||||
int deltax, deltay;
|
||||
int dropcol; /* drop sand here */
|
||||
int dropped; /* number of sand units */
|
||||
char *m;
|
||||
} map_t;
|
||||
|
||||
#define XY(m, x, y) ((y) * m->size_x + (x))
|
||||
#define P(m, x, y) (m->m[XY(m, (x), (y))])
|
||||
|
||||
static int drop_sand(struct map *m, int x, int y)
|
||||
{
|
||||
int ret = 0, tmp;
|
||||
|
||||
if (y >= m->ymax) /* part 1: nothing left under */
|
||||
return INF;
|
||||
|
||||
if (P(m, x, y+1) == EMPTY) { /* down */
|
||||
if ((tmp = drop_sand(m, x, y+1)) < 0)
|
||||
return INF;
|
||||
ret += tmp;
|
||||
}
|
||||
if (P(m, x-1, y+1) == EMPTY) { /* left */
|
||||
if ((tmp = drop_sand(m, x-1, y+1)) < 0)
|
||||
return INF;
|
||||
ret += tmp;
|
||||
}
|
||||
if (P(m, x+1, y+1) == EMPTY) { /* right */
|
||||
if ((tmp = drop_sand(m, x+1, y+1)) < 0)
|
||||
return INF;
|
||||
ret += tmp;
|
||||
}
|
||||
/* the 3 lower adjacent cells are filled */
|
||||
P(m, x, y) = SAND;
|
||||
m->dropped++;
|
||||
if (y == 0) /* part 2 */
|
||||
return INF;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static struct map *gen_map(struct map *m, int part)
|
||||
{
|
||||
segment_t *cur;
|
||||
|
||||
if (part == 1) {
|
||||
m->size_x = (m->xmax - m->xmin) + 3;
|
||||
m->size_y = m->ymax + 1;
|
||||
m->deltax = m->xmin - 1;
|
||||
} else {
|
||||
m->ymax += 2;
|
||||
m->xmin = 500 - m->ymax - 1;
|
||||
m->xmax = 500 + m->ymax + 1;
|
||||
m->deltax = m->xmin;
|
||||
m->size_x = (m->xmax - m->xmin);
|
||||
m->size_y = m->ymax + 3;
|
||||
}
|
||||
m->dropcol = 500 - m->deltax;
|
||||
m->dropped = 0;
|
||||
|
||||
m->m = malloc(m->size_x * m->size_y);
|
||||
memset(m->m, '.', m->size_x * m->size_y);
|
||||
list_for_each_entry(cur, &segments, list) {
|
||||
int x1 = cur->x1 - m->deltax, y1 = cur->y1 - m->deltay,
|
||||
x2 = cur->x2 - m->deltax, y2 = cur->y2 - m->deltay;
|
||||
int dx = 0, dy = 0;
|
||||
if (x1 == x2)
|
||||
dy = y2 - y1 > 0 ? 1 : -1;
|
||||
else
|
||||
dx = x2 - x1 > 0 ? 1 : -1;
|
||||
do {
|
||||
P(m, x1, y1) = '#';
|
||||
x1 += dx, y1 += dy;
|
||||
} while (x1 != x2 || y1 != y2);
|
||||
P(m, x2, y2) = '#';
|
||||
}
|
||||
if (part == 2)
|
||||
for (int i = 0; i < m->size_x; ++i)
|
||||
P(m, m->xmin - m->deltax + i, m->ymax) = STONE;
|
||||
return m;
|
||||
}
|
||||
|
||||
static struct map *parse(map_t *m)
|
||||
{
|
||||
size_t alloc = 0;
|
||||
ssize_t buflen;
|
||||
char *buf = NULL, *cur;
|
||||
int i, scanned;
|
||||
int x1, y1, x2, y2, x, y, n;
|
||||
segment_t *segment;
|
||||
|
||||
while ((buflen = getline(&buf, &alloc, stdin)) > 0) {
|
||||
i = 0;
|
||||
buf[--buflen] = 0;
|
||||
cur = buf;
|
||||
while (1) {
|
||||
scanned = sscanf(cur, "%d,%d ->%n", &x, &y, &n);
|
||||
if (scanned != 2)
|
||||
break;
|
||||
m->xmin = min(x, m->xmin);
|
||||
m->xmax = max(x, m->xmax);
|
||||
m->ymin = min(y, m->ymin);
|
||||
m->ymax = max(y, m->ymax);
|
||||
if (i) {
|
||||
x1 = x2;
|
||||
y1 = y2;
|
||||
}
|
||||
x2 = x;
|
||||
y2 = y;
|
||||
if (!i) /* first point */
|
||||
goto next;
|
||||
segment = pool_get(pool_segment);
|
||||
segment->x1 = x1;
|
||||
segment->y1 = y1;
|
||||
segment->x2 = x2;
|
||||
segment->y2 = y2;
|
||||
list_add_tail(&segment->list, &segments);
|
||||
next:
|
||||
i++;
|
||||
cur += n;
|
||||
if (cur - buf >= buflen)
|
||||
break;
|
||||
}
|
||||
}
|
||||
free(buf);
|
||||
return m;
|
||||
}
|
||||
|
||||
static int doit(map_t *m, int part)
|
||||
{
|
||||
m = gen_map(parse(m), part);
|
||||
drop_sand(m, m->dropcol, 0);
|
||||
return m->dropped;
|
||||
}
|
||||
|
||||
|
||||
int main(int ac, char **av)
|
||||
{
|
||||
int part = parseargs(ac, av);
|
||||
static map_t m;
|
||||
m.xmin = INT_MAX; m.xmax = INT_MIN;
|
||||
m.ymin = INT_MAX, m.ymax = INT_MIN;
|
||||
|
||||
pool_segment = pool_create("segment", 512, sizeof(segment_t));
|
||||
|
||||
printf("%s: res=%d\n", *av, doit(&m, part));
|
||||
free(m.m);
|
||||
pool_destroy(pool_segment);
|
||||
exit(0);
|
||||
}
|
||||
17
2022/day14/aoc.h
Normal file
17
2022/day14/aoc.h
Normal file
@@ -0,0 +1,17 @@
|
||||
/* aoc.c: Advent of Code 2022
|
||||
*
|
||||
* Copyright (C) 2022 Bruno Raoult ("br")
|
||||
* Licensed under the GNU General Public License v3.0 or later.
|
||||
* Some rights reserved. See COPYING.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with this
|
||||
* program. If not, see <https://www.gnu.org/licenses/gpl-3.0-standalone.html>.
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later <https://spdx.org/licenses/GPL-3.0-or-later.html>
|
||||
*/
|
||||
#ifndef _AOC_H_
|
||||
#define _AOC_H_
|
||||
|
||||
extern int parseargs(int ac, char**av);
|
||||
|
||||
#endif /* _AOC_H_ */
|
||||
68
2022/day14/common.bash
Normal file
68
2022/day14/common.bash
Normal file
@@ -0,0 +1,68 @@
|
||||
#!/usr/bin/env bash
|
||||
#
|
||||
# common.bash: Advent of Code 2022, common bash functions
|
||||
#
|
||||
# Copyright (C) 2022 Bruno Raoult ("br")
|
||||
# Licensed under the GNU General Public License v3.0 or later.
|
||||
# Some rights reserved. See COPYING.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License along with this
|
||||
# program. If not, see <https://www.gnu.org/licenses/gpl-3.0-standalone.html>.
|
||||
#
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later <https://spdx.org/licenses/GPL-3.0-or-later.html>
|
||||
|
||||
# shellcheck disable=2034
|
||||
export cmdname=${0##*/}
|
||||
export debug=0
|
||||
export res
|
||||
export LANG=C
|
||||
|
||||
shopt -s extglob
|
||||
set -o noglob
|
||||
|
||||
usage() {
|
||||
printf "usage: %s [-d DEBUG] [-p PART]\n" "$cmdname"
|
||||
exit 1
|
||||
}
|
||||
|
||||
checkargs() {
|
||||
local part=1
|
||||
while getopts p:d: todo; do
|
||||
case "$todo" in
|
||||
d)
|
||||
if [[ "$OPTARG" =~ ^[[:digit:]+]$ ]]; then
|
||||
debug="$OPTARG"
|
||||
else
|
||||
printf "%s: illegal [%s] debug level.\n" "$CMD" "$OPTARG"
|
||||
exit 1
|
||||
fi
|
||||
;;
|
||||
p)
|
||||
if [[ "$OPTARG" =~ ^[12]$ ]]; then
|
||||
part="$OPTARG"
|
||||
else
|
||||
printf "%s: illegal [%s] part.\n" "$CMD" "$OPTARG"
|
||||
exit 1
|
||||
fi
|
||||
;;
|
||||
*)
|
||||
usage
|
||||
;;
|
||||
esac
|
||||
done
|
||||
# Now check remaining argument (backup directory)
|
||||
shift $((OPTIND - 1))
|
||||
|
||||
(( $# > 1 )) && usage
|
||||
return "$part"
|
||||
}
|
||||
|
||||
main() {
|
||||
local -i part
|
||||
|
||||
checkargs "$@"
|
||||
part=$?
|
||||
parse "$part"
|
||||
solve "$part"
|
||||
printf "%s: res=%s\n" "$cmdname" "$res"
|
||||
}
|
||||
49
2022/day14/common.c
Normal file
49
2022/day14/common.c
Normal file
@@ -0,0 +1,49 @@
|
||||
/* common.c: Advent of Code 2022, common functions
|
||||
*
|
||||
* Copyright (C) 2022 Bruno Raoult ("br")
|
||||
* Licensed under the GNU General Public License v3.0 or later.
|
||||
* Some rights reserved. See COPYING.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with this
|
||||
* program. If not, see <https://www.gnu.org/licenses/gpl-3.0-standalone.html>.
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later <https://spdx.org/licenses/GPL-3.0-or-later.html>
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "aoc.h"
|
||||
#include "debug.h"
|
||||
|
||||
static int usage(char *prg)
|
||||
{
|
||||
fprintf(stderr, "Usage: %s [-d debug_level] [-p part] [-i input]\n", prg);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int parseargs(int ac, char **av)
|
||||
{
|
||||
int opt, part = 1;
|
||||
|
||||
while ((opt = getopt(ac, av, "d:p:")) != -1) {
|
||||
switch (opt) {
|
||||
case 'd':
|
||||
debug_level_set(atoi(optarg));
|
||||
break;
|
||||
case 'p': /* 1 or 2 */
|
||||
part = atoi(optarg);
|
||||
if (part < 1 || part > 2)
|
||||
return usage(*av);
|
||||
break;
|
||||
case 'i':
|
||||
|
||||
default:
|
||||
return usage(*av);
|
||||
}
|
||||
}
|
||||
if (optind < ac)
|
||||
return usage(*av);
|
||||
return part;
|
||||
}
|
||||
2
2022/day14/input/example.txt
Normal file
2
2022/day14/input/example.txt
Normal file
@@ -0,0 +1,2 @@
|
||||
498,4 -> 498,6 -> 496,6
|
||||
503,4 -> 502,4 -> 502,9 -> 494,9
|
||||
168
2022/day14/input/input.txt
Normal file
168
2022/day14/input/input.txt
Normal file
@@ -0,0 +1,168 @@
|
||||
520,96 -> 520,92 -> 520,96 -> 522,96 -> 522,86 -> 522,96 -> 524,96 -> 524,92 -> 524,96 -> 526,96 -> 526,93 -> 526,96 -> 528,96 -> 528,95 -> 528,96 -> 530,96 -> 530,88 -> 530,96 -> 532,96 -> 532,88 -> 532,96 -> 534,96 -> 534,91 -> 534,96 -> 536,96 -> 536,92 -> 536,96 -> 538,96 -> 538,88 -> 538,96
|
||||
490,15 -> 501,15 -> 501,14
|
||||
503,68 -> 508,68
|
||||
513,60 -> 513,61 -> 523,61 -> 523,60
|
||||
503,37 -> 503,31 -> 503,37 -> 505,37 -> 505,29 -> 505,37 -> 507,37 -> 507,29 -> 507,37 -> 509,37 -> 509,29 -> 509,37 -> 511,37 -> 511,32 -> 511,37 -> 513,37 -> 513,29 -> 513,37 -> 515,37 -> 515,34 -> 515,37 -> 517,37 -> 517,36 -> 517,37 -> 519,37 -> 519,36 -> 519,37
|
||||
524,136 -> 529,136
|
||||
520,96 -> 520,92 -> 520,96 -> 522,96 -> 522,86 -> 522,96 -> 524,96 -> 524,92 -> 524,96 -> 526,96 -> 526,93 -> 526,96 -> 528,96 -> 528,95 -> 528,96 -> 530,96 -> 530,88 -> 530,96 -> 532,96 -> 532,88 -> 532,96 -> 534,96 -> 534,91 -> 534,96 -> 536,96 -> 536,92 -> 536,96 -> 538,96 -> 538,88 -> 538,96
|
||||
509,64 -> 514,64
|
||||
529,159 -> 529,153 -> 529,159 -> 531,159 -> 531,151 -> 531,159 -> 533,159 -> 533,156 -> 533,159 -> 535,159 -> 535,152 -> 535,159 -> 537,159 -> 537,154 -> 537,159 -> 539,159 -> 539,156 -> 539,159
|
||||
518,46 -> 522,46
|
||||
529,159 -> 529,153 -> 529,159 -> 531,159 -> 531,151 -> 531,159 -> 533,159 -> 533,156 -> 533,159 -> 535,159 -> 535,152 -> 535,159 -> 537,159 -> 537,154 -> 537,159 -> 539,159 -> 539,156 -> 539,159
|
||||
520,96 -> 520,92 -> 520,96 -> 522,96 -> 522,86 -> 522,96 -> 524,96 -> 524,92 -> 524,96 -> 526,96 -> 526,93 -> 526,96 -> 528,96 -> 528,95 -> 528,96 -> 530,96 -> 530,88 -> 530,96 -> 532,96 -> 532,88 -> 532,96 -> 534,96 -> 534,91 -> 534,96 -> 536,96 -> 536,92 -> 536,96 -> 538,96 -> 538,88 -> 538,96
|
||||
521,71 -> 521,73 -> 514,73 -> 514,79 -> 527,79 -> 527,73 -> 525,73 -> 525,71
|
||||
503,37 -> 503,31 -> 503,37 -> 505,37 -> 505,29 -> 505,37 -> 507,37 -> 507,29 -> 507,37 -> 509,37 -> 509,29 -> 509,37 -> 511,37 -> 511,32 -> 511,37 -> 513,37 -> 513,29 -> 513,37 -> 515,37 -> 515,34 -> 515,37 -> 517,37 -> 517,36 -> 517,37 -> 519,37 -> 519,36 -> 519,37
|
||||
532,109 -> 532,103 -> 532,109 -> 534,109 -> 534,106 -> 534,109 -> 536,109 -> 536,102 -> 536,109 -> 538,109 -> 538,107 -> 538,109 -> 540,109 -> 540,107 -> 540,109 -> 542,109 -> 542,100 -> 542,109 -> 544,109 -> 544,106 -> 544,109
|
||||
532,109 -> 532,103 -> 532,109 -> 534,109 -> 534,106 -> 534,109 -> 536,109 -> 536,102 -> 536,109 -> 538,109 -> 538,107 -> 538,109 -> 540,109 -> 540,107 -> 540,109 -> 542,109 -> 542,100 -> 542,109 -> 544,109 -> 544,106 -> 544,109
|
||||
518,82 -> 518,83 -> 529,83 -> 529,82
|
||||
530,124 -> 535,124
|
||||
520,96 -> 520,92 -> 520,96 -> 522,96 -> 522,86 -> 522,96 -> 524,96 -> 524,92 -> 524,96 -> 526,96 -> 526,93 -> 526,96 -> 528,96 -> 528,95 -> 528,96 -> 530,96 -> 530,88 -> 530,96 -> 532,96 -> 532,88 -> 532,96 -> 534,96 -> 534,91 -> 534,96 -> 536,96 -> 536,92 -> 536,96 -> 538,96 -> 538,88 -> 538,96
|
||||
532,109 -> 532,103 -> 532,109 -> 534,109 -> 534,106 -> 534,109 -> 536,109 -> 536,102 -> 536,109 -> 538,109 -> 538,107 -> 538,109 -> 540,109 -> 540,107 -> 540,109 -> 542,109 -> 542,100 -> 542,109 -> 544,109 -> 544,106 -> 544,109
|
||||
503,37 -> 503,31 -> 503,37 -> 505,37 -> 505,29 -> 505,37 -> 507,37 -> 507,29 -> 507,37 -> 509,37 -> 509,29 -> 509,37 -> 511,37 -> 511,32 -> 511,37 -> 513,37 -> 513,29 -> 513,37 -> 515,37 -> 515,34 -> 515,37 -> 517,37 -> 517,36 -> 517,37 -> 519,37 -> 519,36 -> 519,37
|
||||
542,112 -> 547,112
|
||||
536,118 -> 541,118
|
||||
529,159 -> 529,153 -> 529,159 -> 531,159 -> 531,151 -> 531,159 -> 533,159 -> 533,156 -> 533,159 -> 535,159 -> 535,152 -> 535,159 -> 537,159 -> 537,154 -> 537,159 -> 539,159 -> 539,156 -> 539,159
|
||||
528,139 -> 528,141 -> 521,141 -> 521,146 -> 534,146 -> 534,141 -> 531,141 -> 531,139
|
||||
534,133 -> 539,133
|
||||
543,118 -> 548,118
|
||||
508,49 -> 508,52 -> 504,52 -> 504,55 -> 516,55 -> 516,52 -> 514,52 -> 514,49
|
||||
532,109 -> 532,103 -> 532,109 -> 534,109 -> 534,106 -> 534,109 -> 536,109 -> 536,102 -> 536,109 -> 538,109 -> 538,107 -> 538,109 -> 540,109 -> 540,107 -> 540,109 -> 542,109 -> 542,100 -> 542,109 -> 544,109 -> 544,106 -> 544,109
|
||||
508,49 -> 508,52 -> 504,52 -> 504,55 -> 516,55 -> 516,52 -> 514,52 -> 514,49
|
||||
503,37 -> 503,31 -> 503,37 -> 505,37 -> 505,29 -> 505,37 -> 507,37 -> 507,29 -> 507,37 -> 509,37 -> 509,29 -> 509,37 -> 511,37 -> 511,32 -> 511,37 -> 513,37 -> 513,29 -> 513,37 -> 515,37 -> 515,34 -> 515,37 -> 517,37 -> 517,36 -> 517,37 -> 519,37 -> 519,36 -> 519,37
|
||||
500,18 -> 500,20 -> 496,20 -> 496,24 -> 511,24 -> 511,20 -> 504,20 -> 504,18
|
||||
530,130 -> 535,130
|
||||
520,96 -> 520,92 -> 520,96 -> 522,96 -> 522,86 -> 522,96 -> 524,96 -> 524,92 -> 524,96 -> 526,96 -> 526,93 -> 526,96 -> 528,96 -> 528,95 -> 528,96 -> 530,96 -> 530,88 -> 530,96 -> 532,96 -> 532,88 -> 532,96 -> 534,96 -> 534,91 -> 534,96 -> 536,96 -> 536,92 -> 536,96 -> 538,96 -> 538,88 -> 538,96
|
||||
508,49 -> 508,52 -> 504,52 -> 504,55 -> 516,55 -> 516,52 -> 514,52 -> 514,49
|
||||
520,96 -> 520,92 -> 520,96 -> 522,96 -> 522,86 -> 522,96 -> 524,96 -> 524,92 -> 524,96 -> 526,96 -> 526,93 -> 526,96 -> 528,96 -> 528,95 -> 528,96 -> 530,96 -> 530,88 -> 530,96 -> 532,96 -> 532,88 -> 532,96 -> 534,96 -> 534,91 -> 534,96 -> 536,96 -> 536,92 -> 536,96 -> 538,96 -> 538,88 -> 538,96
|
||||
532,109 -> 532,103 -> 532,109 -> 534,109 -> 534,106 -> 534,109 -> 536,109 -> 536,102 -> 536,109 -> 538,109 -> 538,107 -> 538,109 -> 540,109 -> 540,107 -> 540,109 -> 542,109 -> 542,100 -> 542,109 -> 544,109 -> 544,106 -> 544,109
|
||||
503,37 -> 503,31 -> 503,37 -> 505,37 -> 505,29 -> 505,37 -> 507,37 -> 507,29 -> 507,37 -> 509,37 -> 509,29 -> 509,37 -> 511,37 -> 511,32 -> 511,37 -> 513,37 -> 513,29 -> 513,37 -> 515,37 -> 515,34 -> 515,37 -> 517,37 -> 517,36 -> 517,37 -> 519,37 -> 519,36 -> 519,37
|
||||
546,115 -> 551,115
|
||||
524,46 -> 528,46
|
||||
532,109 -> 532,103 -> 532,109 -> 534,109 -> 534,106 -> 534,109 -> 536,109 -> 536,102 -> 536,109 -> 538,109 -> 538,107 -> 538,109 -> 540,109 -> 540,107 -> 540,109 -> 542,109 -> 542,100 -> 542,109 -> 544,109 -> 544,106 -> 544,109
|
||||
520,96 -> 520,92 -> 520,96 -> 522,96 -> 522,86 -> 522,96 -> 524,96 -> 524,92 -> 524,96 -> 526,96 -> 526,93 -> 526,96 -> 528,96 -> 528,95 -> 528,96 -> 530,96 -> 530,88 -> 530,96 -> 532,96 -> 532,88 -> 532,96 -> 534,96 -> 534,91 -> 534,96 -> 536,96 -> 536,92 -> 536,96 -> 538,96 -> 538,88 -> 538,96
|
||||
521,71 -> 521,73 -> 514,73 -> 514,79 -> 527,79 -> 527,73 -> 525,73 -> 525,71
|
||||
520,96 -> 520,92 -> 520,96 -> 522,96 -> 522,86 -> 522,96 -> 524,96 -> 524,92 -> 524,96 -> 526,96 -> 526,93 -> 526,96 -> 528,96 -> 528,95 -> 528,96 -> 530,96 -> 530,88 -> 530,96 -> 532,96 -> 532,88 -> 532,96 -> 534,96 -> 534,91 -> 534,96 -> 536,96 -> 536,92 -> 536,96 -> 538,96 -> 538,88 -> 538,96
|
||||
503,37 -> 503,31 -> 503,37 -> 505,37 -> 505,29 -> 505,37 -> 507,37 -> 507,29 -> 507,37 -> 509,37 -> 509,29 -> 509,37 -> 511,37 -> 511,32 -> 511,37 -> 513,37 -> 513,29 -> 513,37 -> 515,37 -> 515,34 -> 515,37 -> 517,37 -> 517,36 -> 517,37 -> 519,37 -> 519,36 -> 519,37
|
||||
503,37 -> 503,31 -> 503,37 -> 505,37 -> 505,29 -> 505,37 -> 507,37 -> 507,29 -> 507,37 -> 509,37 -> 509,29 -> 509,37 -> 511,37 -> 511,32 -> 511,37 -> 513,37 -> 513,29 -> 513,37 -> 515,37 -> 515,34 -> 515,37 -> 517,37 -> 517,36 -> 517,37 -> 519,37 -> 519,36 -> 519,37
|
||||
537,124 -> 542,124
|
||||
532,109 -> 532,103 -> 532,109 -> 534,109 -> 534,106 -> 534,109 -> 536,109 -> 536,102 -> 536,109 -> 538,109 -> 538,107 -> 538,109 -> 540,109 -> 540,107 -> 540,109 -> 542,109 -> 542,100 -> 542,109 -> 544,109 -> 544,106 -> 544,109
|
||||
529,159 -> 529,153 -> 529,159 -> 531,159 -> 531,151 -> 531,159 -> 533,159 -> 533,156 -> 533,159 -> 535,159 -> 535,152 -> 535,159 -> 537,159 -> 537,154 -> 537,159 -> 539,159 -> 539,156 -> 539,159
|
||||
528,139 -> 528,141 -> 521,141 -> 521,146 -> 534,146 -> 534,141 -> 531,141 -> 531,139
|
||||
500,18 -> 500,20 -> 496,20 -> 496,24 -> 511,24 -> 511,20 -> 504,20 -> 504,18
|
||||
539,115 -> 544,115
|
||||
503,37 -> 503,31 -> 503,37 -> 505,37 -> 505,29 -> 505,37 -> 507,37 -> 507,29 -> 507,37 -> 509,37 -> 509,29 -> 509,37 -> 511,37 -> 511,32 -> 511,37 -> 513,37 -> 513,29 -> 513,37 -> 515,37 -> 515,34 -> 515,37 -> 517,37 -> 517,36 -> 517,37 -> 519,37 -> 519,36 -> 519,37
|
||||
503,37 -> 503,31 -> 503,37 -> 505,37 -> 505,29 -> 505,37 -> 507,37 -> 507,29 -> 507,37 -> 509,37 -> 509,29 -> 509,37 -> 511,37 -> 511,32 -> 511,37 -> 513,37 -> 513,29 -> 513,37 -> 515,37 -> 515,34 -> 515,37 -> 517,37 -> 517,36 -> 517,37 -> 519,37 -> 519,36 -> 519,37
|
||||
521,71 -> 521,73 -> 514,73 -> 514,79 -> 527,79 -> 527,73 -> 525,73 -> 525,71
|
||||
532,109 -> 532,103 -> 532,109 -> 534,109 -> 534,106 -> 534,109 -> 536,109 -> 536,102 -> 536,109 -> 538,109 -> 538,107 -> 538,109 -> 540,109 -> 540,107 -> 540,109 -> 542,109 -> 542,100 -> 542,109 -> 544,109 -> 544,106 -> 544,109
|
||||
520,96 -> 520,92 -> 520,96 -> 522,96 -> 522,86 -> 522,96 -> 524,96 -> 524,92 -> 524,96 -> 526,96 -> 526,93 -> 526,96 -> 528,96 -> 528,95 -> 528,96 -> 530,96 -> 530,88 -> 530,96 -> 532,96 -> 532,88 -> 532,96 -> 534,96 -> 534,91 -> 534,96 -> 536,96 -> 536,92 -> 536,96 -> 538,96 -> 538,88 -> 538,96
|
||||
520,96 -> 520,92 -> 520,96 -> 522,96 -> 522,86 -> 522,96 -> 524,96 -> 524,92 -> 524,96 -> 526,96 -> 526,93 -> 526,96 -> 528,96 -> 528,95 -> 528,96 -> 530,96 -> 530,88 -> 530,96 -> 532,96 -> 532,88 -> 532,96 -> 534,96 -> 534,91 -> 534,96 -> 536,96 -> 536,92 -> 536,96 -> 538,96 -> 538,88 -> 538,96
|
||||
533,127 -> 538,127
|
||||
518,82 -> 518,83 -> 529,83 -> 529,82
|
||||
503,37 -> 503,31 -> 503,37 -> 505,37 -> 505,29 -> 505,37 -> 507,37 -> 507,29 -> 507,37 -> 509,37 -> 509,29 -> 509,37 -> 511,37 -> 511,32 -> 511,37 -> 513,37 -> 513,29 -> 513,37 -> 515,37 -> 515,34 -> 515,37 -> 517,37 -> 517,36 -> 517,37 -> 519,37 -> 519,36 -> 519,37
|
||||
506,66 -> 511,66
|
||||
503,37 -> 503,31 -> 503,37 -> 505,37 -> 505,29 -> 505,37 -> 507,37 -> 507,29 -> 507,37 -> 509,37 -> 509,29 -> 509,37 -> 511,37 -> 511,32 -> 511,37 -> 513,37 -> 513,29 -> 513,37 -> 515,37 -> 515,34 -> 515,37 -> 517,37 -> 517,36 -> 517,37 -> 519,37 -> 519,36 -> 519,37
|
||||
535,161 -> 535,162 -> 544,162 -> 544,161
|
||||
529,159 -> 529,153 -> 529,159 -> 531,159 -> 531,151 -> 531,159 -> 533,159 -> 533,156 -> 533,159 -> 535,159 -> 535,152 -> 535,159 -> 537,159 -> 537,154 -> 537,159 -> 539,159 -> 539,156 -> 539,159
|
||||
500,18 -> 500,20 -> 496,20 -> 496,24 -> 511,24 -> 511,20 -> 504,20 -> 504,18
|
||||
520,96 -> 520,92 -> 520,96 -> 522,96 -> 522,86 -> 522,96 -> 524,96 -> 524,92 -> 524,96 -> 526,96 -> 526,93 -> 526,96 -> 528,96 -> 528,95 -> 528,96 -> 530,96 -> 530,88 -> 530,96 -> 532,96 -> 532,88 -> 532,96 -> 534,96 -> 534,91 -> 534,96 -> 536,96 -> 536,92 -> 536,96 -> 538,96 -> 538,88 -> 538,96
|
||||
520,96 -> 520,92 -> 520,96 -> 522,96 -> 522,86 -> 522,96 -> 524,96 -> 524,92 -> 524,96 -> 526,96 -> 526,93 -> 526,96 -> 528,96 -> 528,95 -> 528,96 -> 530,96 -> 530,88 -> 530,96 -> 532,96 -> 532,88 -> 532,96 -> 534,96 -> 534,91 -> 534,96 -> 536,96 -> 536,92 -> 536,96 -> 538,96 -> 538,88 -> 538,96
|
||||
503,37 -> 503,31 -> 503,37 -> 505,37 -> 505,29 -> 505,37 -> 507,37 -> 507,29 -> 507,37 -> 509,37 -> 509,29 -> 509,37 -> 511,37 -> 511,32 -> 511,37 -> 513,37 -> 513,29 -> 513,37 -> 515,37 -> 515,34 -> 515,37 -> 517,37 -> 517,36 -> 517,37 -> 519,37 -> 519,36 -> 519,37
|
||||
490,15 -> 501,15 -> 501,14
|
||||
535,161 -> 535,162 -> 544,162 -> 544,161
|
||||
508,49 -> 508,52 -> 504,52 -> 504,55 -> 516,55 -> 516,52 -> 514,52 -> 514,49
|
||||
518,82 -> 518,83 -> 529,83 -> 529,82
|
||||
513,66 -> 518,66
|
||||
532,109 -> 532,103 -> 532,109 -> 534,109 -> 534,106 -> 534,109 -> 536,109 -> 536,102 -> 536,109 -> 538,109 -> 538,107 -> 538,109 -> 540,109 -> 540,107 -> 540,109 -> 542,109 -> 542,100 -> 542,109 -> 544,109 -> 544,106 -> 544,109
|
||||
532,109 -> 532,103 -> 532,109 -> 534,109 -> 534,106 -> 534,109 -> 536,109 -> 536,102 -> 536,109 -> 538,109 -> 538,107 -> 538,109 -> 540,109 -> 540,107 -> 540,109 -> 542,109 -> 542,100 -> 542,109 -> 544,109 -> 544,106 -> 544,109
|
||||
558,124 -> 563,124
|
||||
520,96 -> 520,92 -> 520,96 -> 522,96 -> 522,86 -> 522,96 -> 524,96 -> 524,92 -> 524,96 -> 526,96 -> 526,93 -> 526,96 -> 528,96 -> 528,95 -> 528,96 -> 530,96 -> 530,88 -> 530,96 -> 532,96 -> 532,88 -> 532,96 -> 534,96 -> 534,91 -> 534,96 -> 536,96 -> 536,92 -> 536,96 -> 538,96 -> 538,88 -> 538,96
|
||||
532,109 -> 532,103 -> 532,109 -> 534,109 -> 534,106 -> 534,109 -> 536,109 -> 536,102 -> 536,109 -> 538,109 -> 538,107 -> 538,109 -> 540,109 -> 540,107 -> 540,109 -> 542,109 -> 542,100 -> 542,109 -> 544,109 -> 544,106 -> 544,109
|
||||
532,109 -> 532,103 -> 532,109 -> 534,109 -> 534,106 -> 534,109 -> 536,109 -> 536,102 -> 536,109 -> 538,109 -> 538,107 -> 538,109 -> 540,109 -> 540,107 -> 540,109 -> 542,109 -> 542,100 -> 542,109 -> 544,109 -> 544,106 -> 544,109
|
||||
503,37 -> 503,31 -> 503,37 -> 505,37 -> 505,29 -> 505,37 -> 507,37 -> 507,29 -> 507,37 -> 509,37 -> 509,29 -> 509,37 -> 511,37 -> 511,32 -> 511,37 -> 513,37 -> 513,29 -> 513,37 -> 515,37 -> 515,34 -> 515,37 -> 517,37 -> 517,36 -> 517,37 -> 519,37 -> 519,36 -> 519,37
|
||||
529,159 -> 529,153 -> 529,159 -> 531,159 -> 531,151 -> 531,159 -> 533,159 -> 533,156 -> 533,159 -> 535,159 -> 535,152 -> 535,159 -> 537,159 -> 537,154 -> 537,159 -> 539,159 -> 539,156 -> 539,159
|
||||
528,139 -> 528,141 -> 521,141 -> 521,146 -> 534,146 -> 534,141 -> 531,141 -> 531,139
|
||||
520,96 -> 520,92 -> 520,96 -> 522,96 -> 522,86 -> 522,96 -> 524,96 -> 524,92 -> 524,96 -> 526,96 -> 526,93 -> 526,96 -> 528,96 -> 528,95 -> 528,96 -> 530,96 -> 530,88 -> 530,96 -> 532,96 -> 532,88 -> 532,96 -> 534,96 -> 534,91 -> 534,96 -> 536,96 -> 536,92 -> 536,96 -> 538,96 -> 538,88 -> 538,96
|
||||
529,159 -> 529,153 -> 529,159 -> 531,159 -> 531,151 -> 531,159 -> 533,159 -> 533,156 -> 533,159 -> 535,159 -> 535,152 -> 535,159 -> 537,159 -> 537,154 -> 537,159 -> 539,159 -> 539,156 -> 539,159
|
||||
520,96 -> 520,92 -> 520,96 -> 522,96 -> 522,86 -> 522,96 -> 524,96 -> 524,92 -> 524,96 -> 526,96 -> 526,93 -> 526,96 -> 528,96 -> 528,95 -> 528,96 -> 530,96 -> 530,88 -> 530,96 -> 532,96 -> 532,88 -> 532,96 -> 534,96 -> 534,91 -> 534,96 -> 536,96 -> 536,92 -> 536,96 -> 538,96 -> 538,88 -> 538,96
|
||||
554,121 -> 559,121
|
||||
520,96 -> 520,92 -> 520,96 -> 522,96 -> 522,86 -> 522,96 -> 524,96 -> 524,92 -> 524,96 -> 526,96 -> 526,93 -> 526,96 -> 528,96 -> 528,95 -> 528,96 -> 530,96 -> 530,88 -> 530,96 -> 532,96 -> 532,88 -> 532,96 -> 534,96 -> 534,91 -> 534,96 -> 536,96 -> 536,92 -> 536,96 -> 538,96 -> 538,88 -> 538,96
|
||||
508,49 -> 508,52 -> 504,52 -> 504,55 -> 516,55 -> 516,52 -> 514,52 -> 514,49
|
||||
540,121 -> 545,121
|
||||
520,96 -> 520,92 -> 520,96 -> 522,96 -> 522,86 -> 522,96 -> 524,96 -> 524,92 -> 524,96 -> 526,96 -> 526,93 -> 526,96 -> 528,96 -> 528,95 -> 528,96 -> 530,96 -> 530,88 -> 530,96 -> 532,96 -> 532,88 -> 532,96 -> 534,96 -> 534,91 -> 534,96 -> 536,96 -> 536,92 -> 536,96 -> 538,96 -> 538,88 -> 538,96
|
||||
503,37 -> 503,31 -> 503,37 -> 505,37 -> 505,29 -> 505,37 -> 507,37 -> 507,29 -> 507,37 -> 509,37 -> 509,29 -> 509,37 -> 511,37 -> 511,32 -> 511,37 -> 513,37 -> 513,29 -> 513,37 -> 515,37 -> 515,34 -> 515,37 -> 517,37 -> 517,36 -> 517,37 -> 519,37 -> 519,36 -> 519,37
|
||||
529,159 -> 529,153 -> 529,159 -> 531,159 -> 531,151 -> 531,159 -> 533,159 -> 533,156 -> 533,159 -> 535,159 -> 535,152 -> 535,159 -> 537,159 -> 537,154 -> 537,159 -> 539,159 -> 539,156 -> 539,159
|
||||
529,159 -> 529,153 -> 529,159 -> 531,159 -> 531,151 -> 531,159 -> 533,159 -> 533,156 -> 533,159 -> 535,159 -> 535,152 -> 535,159 -> 537,159 -> 537,154 -> 537,159 -> 539,159 -> 539,156 -> 539,159
|
||||
547,121 -> 552,121
|
||||
503,37 -> 503,31 -> 503,37 -> 505,37 -> 505,29 -> 505,37 -> 507,37 -> 507,29 -> 507,37 -> 509,37 -> 509,29 -> 509,37 -> 511,37 -> 511,32 -> 511,37 -> 513,37 -> 513,29 -> 513,37 -> 515,37 -> 515,34 -> 515,37 -> 517,37 -> 517,36 -> 517,37 -> 519,37 -> 519,36 -> 519,37
|
||||
503,37 -> 503,31 -> 503,37 -> 505,37 -> 505,29 -> 505,37 -> 507,37 -> 507,29 -> 507,37 -> 509,37 -> 509,29 -> 509,37 -> 511,37 -> 511,32 -> 511,37 -> 513,37 -> 513,29 -> 513,37 -> 515,37 -> 515,34 -> 515,37 -> 517,37 -> 517,36 -> 517,37 -> 519,37 -> 519,36 -> 519,37
|
||||
520,96 -> 520,92 -> 520,96 -> 522,96 -> 522,86 -> 522,96 -> 524,96 -> 524,92 -> 524,96 -> 526,96 -> 526,93 -> 526,96 -> 528,96 -> 528,95 -> 528,96 -> 530,96 -> 530,88 -> 530,96 -> 532,96 -> 532,88 -> 532,96 -> 534,96 -> 534,91 -> 534,96 -> 536,96 -> 536,92 -> 536,96 -> 538,96 -> 538,88 -> 538,96
|
||||
503,37 -> 503,31 -> 503,37 -> 505,37 -> 505,29 -> 505,37 -> 507,37 -> 507,29 -> 507,37 -> 509,37 -> 509,29 -> 509,37 -> 511,37 -> 511,32 -> 511,37 -> 513,37 -> 513,29 -> 513,37 -> 515,37 -> 515,34 -> 515,37 -> 517,37 -> 517,36 -> 517,37 -> 519,37 -> 519,36 -> 519,37
|
||||
500,18 -> 500,20 -> 496,20 -> 496,24 -> 511,24 -> 511,20 -> 504,20 -> 504,18
|
||||
532,109 -> 532,103 -> 532,109 -> 534,109 -> 534,106 -> 534,109 -> 536,109 -> 536,102 -> 536,109 -> 538,109 -> 538,107 -> 538,109 -> 540,109 -> 540,107 -> 540,109 -> 542,109 -> 542,100 -> 542,109 -> 544,109 -> 544,106 -> 544,109
|
||||
529,159 -> 529,153 -> 529,159 -> 531,159 -> 531,151 -> 531,159 -> 533,159 -> 533,156 -> 533,159 -> 535,159 -> 535,152 -> 535,159 -> 537,159 -> 537,154 -> 537,159 -> 539,159 -> 539,156 -> 539,159
|
||||
512,46 -> 516,46
|
||||
544,124 -> 549,124
|
||||
503,37 -> 503,31 -> 503,37 -> 505,37 -> 505,29 -> 505,37 -> 507,37 -> 507,29 -> 507,37 -> 509,37 -> 509,29 -> 509,37 -> 511,37 -> 511,32 -> 511,37 -> 513,37 -> 513,29 -> 513,37 -> 515,37 -> 515,34 -> 515,37 -> 517,37 -> 517,36 -> 517,37 -> 519,37 -> 519,36 -> 519,37
|
||||
521,71 -> 521,73 -> 514,73 -> 514,79 -> 527,79 -> 527,73 -> 525,73 -> 525,71
|
||||
532,109 -> 532,103 -> 532,109 -> 534,109 -> 534,106 -> 534,109 -> 536,109 -> 536,102 -> 536,109 -> 538,109 -> 538,107 -> 538,109 -> 540,109 -> 540,107 -> 540,109 -> 542,109 -> 542,100 -> 542,109 -> 544,109 -> 544,106 -> 544,109
|
||||
528,139 -> 528,141 -> 521,141 -> 521,146 -> 534,146 -> 534,141 -> 531,141 -> 531,139
|
||||
520,96 -> 520,92 -> 520,96 -> 522,96 -> 522,86 -> 522,96 -> 524,96 -> 524,92 -> 524,96 -> 526,96 -> 526,93 -> 526,96 -> 528,96 -> 528,95 -> 528,96 -> 530,96 -> 530,88 -> 530,96 -> 532,96 -> 532,88 -> 532,96 -> 534,96 -> 534,91 -> 534,96 -> 536,96 -> 536,92 -> 536,96 -> 538,96 -> 538,88 -> 538,96
|
||||
528,139 -> 528,141 -> 521,141 -> 521,146 -> 534,146 -> 534,141 -> 531,141 -> 531,139
|
||||
533,121 -> 538,121
|
||||
503,37 -> 503,31 -> 503,37 -> 505,37 -> 505,29 -> 505,37 -> 507,37 -> 507,29 -> 507,37 -> 509,37 -> 509,29 -> 509,37 -> 511,37 -> 511,32 -> 511,37 -> 513,37 -> 513,29 -> 513,37 -> 515,37 -> 515,34 -> 515,37 -> 517,37 -> 517,36 -> 517,37 -> 519,37 -> 519,36 -> 519,37
|
||||
521,43 -> 525,43
|
||||
500,18 -> 500,20 -> 496,20 -> 496,24 -> 511,24 -> 511,20 -> 504,20 -> 504,18
|
||||
527,133 -> 532,133
|
||||
503,37 -> 503,31 -> 503,37 -> 505,37 -> 505,29 -> 505,37 -> 507,37 -> 507,29 -> 507,37 -> 509,37 -> 509,29 -> 509,37 -> 511,37 -> 511,32 -> 511,37 -> 513,37 -> 513,29 -> 513,37 -> 515,37 -> 515,34 -> 515,37 -> 517,37 -> 517,36 -> 517,37 -> 519,37 -> 519,36 -> 519,37
|
||||
503,37 -> 503,31 -> 503,37 -> 505,37 -> 505,29 -> 505,37 -> 507,37 -> 507,29 -> 507,37 -> 509,37 -> 509,29 -> 509,37 -> 511,37 -> 511,32 -> 511,37 -> 513,37 -> 513,29 -> 513,37 -> 515,37 -> 515,34 -> 515,37 -> 517,37 -> 517,36 -> 517,37 -> 519,37 -> 519,36 -> 519,37
|
||||
529,159 -> 529,153 -> 529,159 -> 531,159 -> 531,151 -> 531,159 -> 533,159 -> 533,156 -> 533,159 -> 535,159 -> 535,152 -> 535,159 -> 537,159 -> 537,154 -> 537,159 -> 539,159 -> 539,156 -> 539,159
|
||||
520,96 -> 520,92 -> 520,96 -> 522,96 -> 522,86 -> 522,96 -> 524,96 -> 524,92 -> 524,96 -> 526,96 -> 526,93 -> 526,96 -> 528,96 -> 528,95 -> 528,96 -> 530,96 -> 530,88 -> 530,96 -> 532,96 -> 532,88 -> 532,96 -> 534,96 -> 534,91 -> 534,96 -> 536,96 -> 536,92 -> 536,96 -> 538,96 -> 538,88 -> 538,96
|
||||
531,136 -> 536,136
|
||||
503,37 -> 503,31 -> 503,37 -> 505,37 -> 505,29 -> 505,37 -> 507,37 -> 507,29 -> 507,37 -> 509,37 -> 509,29 -> 509,37 -> 511,37 -> 511,32 -> 511,37 -> 513,37 -> 513,29 -> 513,37 -> 515,37 -> 515,34 -> 515,37 -> 517,37 -> 517,36 -> 517,37 -> 519,37 -> 519,36 -> 519,37
|
||||
515,43 -> 519,43
|
||||
532,109 -> 532,103 -> 532,109 -> 534,109 -> 534,106 -> 534,109 -> 536,109 -> 536,102 -> 536,109 -> 538,109 -> 538,107 -> 538,109 -> 540,109 -> 540,107 -> 540,109 -> 542,109 -> 542,100 -> 542,109 -> 544,109 -> 544,106 -> 544,109
|
||||
532,109 -> 532,103 -> 532,109 -> 534,109 -> 534,106 -> 534,109 -> 536,109 -> 536,102 -> 536,109 -> 538,109 -> 538,107 -> 538,109 -> 540,109 -> 540,107 -> 540,109 -> 542,109 -> 542,100 -> 542,109 -> 544,109 -> 544,106 -> 544,109
|
||||
503,37 -> 503,31 -> 503,37 -> 505,37 -> 505,29 -> 505,37 -> 507,37 -> 507,29 -> 507,37 -> 509,37 -> 509,29 -> 509,37 -> 511,37 -> 511,32 -> 511,37 -> 513,37 -> 513,29 -> 513,37 -> 515,37 -> 515,34 -> 515,37 -> 517,37 -> 517,36 -> 517,37 -> 519,37 -> 519,36 -> 519,37
|
||||
521,71 -> 521,73 -> 514,73 -> 514,79 -> 527,79 -> 527,73 -> 525,73 -> 525,71
|
||||
521,71 -> 521,73 -> 514,73 -> 514,79 -> 527,79 -> 527,73 -> 525,73 -> 525,71
|
||||
513,60 -> 513,61 -> 523,61 -> 523,60
|
||||
503,37 -> 503,31 -> 503,37 -> 505,37 -> 505,29 -> 505,37 -> 507,37 -> 507,29 -> 507,37 -> 509,37 -> 509,29 -> 509,37 -> 511,37 -> 511,32 -> 511,37 -> 513,37 -> 513,29 -> 513,37 -> 515,37 -> 515,34 -> 515,37 -> 517,37 -> 517,36 -> 517,37 -> 519,37 -> 519,36 -> 519,37
|
||||
537,130 -> 542,130
|
||||
520,96 -> 520,92 -> 520,96 -> 522,96 -> 522,86 -> 522,96 -> 524,96 -> 524,92 -> 524,96 -> 526,96 -> 526,93 -> 526,96 -> 528,96 -> 528,95 -> 528,96 -> 530,96 -> 530,88 -> 530,96 -> 532,96 -> 532,88 -> 532,96 -> 534,96 -> 534,91 -> 534,96 -> 536,96 -> 536,92 -> 536,96 -> 538,96 -> 538,88 -> 538,96
|
||||
508,49 -> 508,52 -> 504,52 -> 504,55 -> 516,55 -> 516,52 -> 514,52 -> 514,49
|
||||
545,136 -> 550,136
|
||||
538,136 -> 543,136
|
||||
520,96 -> 520,92 -> 520,96 -> 522,96 -> 522,86 -> 522,96 -> 524,96 -> 524,92 -> 524,96 -> 526,96 -> 526,93 -> 526,96 -> 528,96 -> 528,95 -> 528,96 -> 530,96 -> 530,88 -> 530,96 -> 532,96 -> 532,88 -> 532,96 -> 534,96 -> 534,91 -> 534,96 -> 536,96 -> 536,92 -> 536,96 -> 538,96 -> 538,88 -> 538,96
|
||||
532,109 -> 532,103 -> 532,109 -> 534,109 -> 534,106 -> 534,109 -> 536,109 -> 536,102 -> 536,109 -> 538,109 -> 538,107 -> 538,109 -> 540,109 -> 540,107 -> 540,109 -> 542,109 -> 542,100 -> 542,109 -> 544,109 -> 544,106 -> 544,109
|
||||
528,139 -> 528,141 -> 521,141 -> 521,146 -> 534,146 -> 534,141 -> 531,141 -> 531,139
|
||||
503,37 -> 503,31 -> 503,37 -> 505,37 -> 505,29 -> 505,37 -> 507,37 -> 507,29 -> 507,37 -> 509,37 -> 509,29 -> 509,37 -> 511,37 -> 511,32 -> 511,37 -> 513,37 -> 513,29 -> 513,37 -> 515,37 -> 515,34 -> 515,37 -> 517,37 -> 517,36 -> 517,37 -> 519,37 -> 519,36 -> 519,37
|
||||
532,109 -> 532,103 -> 532,109 -> 534,109 -> 534,106 -> 534,109 -> 536,109 -> 536,102 -> 536,109 -> 538,109 -> 538,107 -> 538,109 -> 540,109 -> 540,107 -> 540,109 -> 542,109 -> 542,100 -> 542,109 -> 544,109 -> 544,106 -> 544,109
|
||||
508,49 -> 508,52 -> 504,52 -> 504,55 -> 516,55 -> 516,52 -> 514,52 -> 514,49
|
||||
532,109 -> 532,103 -> 532,109 -> 534,109 -> 534,106 -> 534,109 -> 536,109 -> 536,102 -> 536,109 -> 538,109 -> 538,107 -> 538,109 -> 540,109 -> 540,107 -> 540,109 -> 542,109 -> 542,100 -> 542,109 -> 544,109 -> 544,106 -> 544,109
|
||||
503,37 -> 503,31 -> 503,37 -> 505,37 -> 505,29 -> 505,37 -> 507,37 -> 507,29 -> 507,37 -> 509,37 -> 509,29 -> 509,37 -> 511,37 -> 511,32 -> 511,37 -> 513,37 -> 513,29 -> 513,37 -> 515,37 -> 515,34 -> 515,37 -> 517,37 -> 517,36 -> 517,37 -> 519,37 -> 519,36 -> 519,37
|
||||
529,159 -> 529,153 -> 529,159 -> 531,159 -> 531,151 -> 531,159 -> 533,159 -> 533,156 -> 533,159 -> 535,159 -> 535,152 -> 535,159 -> 537,159 -> 537,154 -> 537,159 -> 539,159 -> 539,156 -> 539,159
|
||||
510,68 -> 515,68
|
||||
520,96 -> 520,92 -> 520,96 -> 522,96 -> 522,86 -> 522,96 -> 524,96 -> 524,92 -> 524,96 -> 526,96 -> 526,93 -> 526,96 -> 528,96 -> 528,95 -> 528,96 -> 530,96 -> 530,88 -> 530,96 -> 532,96 -> 532,88 -> 532,96 -> 534,96 -> 534,91 -> 534,96 -> 536,96 -> 536,92 -> 536,96 -> 538,96 -> 538,88 -> 538,96
|
||||
550,118 -> 555,118
|
||||
520,96 -> 520,92 -> 520,96 -> 522,96 -> 522,86 -> 522,96 -> 524,96 -> 524,92 -> 524,96 -> 526,96 -> 526,93 -> 526,96 -> 528,96 -> 528,95 -> 528,96 -> 530,96 -> 530,88 -> 530,96 -> 532,96 -> 532,88 -> 532,96 -> 534,96 -> 534,91 -> 534,96 -> 536,96 -> 536,92 -> 536,96 -> 538,96 -> 538,88 -> 538,96
|
||||
528,139 -> 528,141 -> 521,141 -> 521,146 -> 534,146 -> 534,141 -> 531,141 -> 531,139
|
||||
529,159 -> 529,153 -> 529,159 -> 531,159 -> 531,151 -> 531,159 -> 533,159 -> 533,156 -> 533,159 -> 535,159 -> 535,152 -> 535,159 -> 537,159 -> 537,154 -> 537,159 -> 539,159 -> 539,156 -> 539,159
|
||||
532,109 -> 532,103 -> 532,109 -> 534,109 -> 534,106 -> 534,109 -> 536,109 -> 536,102 -> 536,109 -> 538,109 -> 538,107 -> 538,109 -> 540,109 -> 540,107 -> 540,109 -> 542,109 -> 542,100 -> 542,109 -> 544,109 -> 544,106 -> 544,109
|
||||
529,159 -> 529,153 -> 529,159 -> 531,159 -> 531,151 -> 531,159 -> 533,159 -> 533,156 -> 533,159 -> 535,159 -> 535,152 -> 535,159 -> 537,159 -> 537,154 -> 537,159 -> 539,159 -> 539,156 -> 539,159
|
||||
521,71 -> 521,73 -> 514,73 -> 514,79 -> 527,79 -> 527,73 -> 525,73 -> 525,71
|
||||
541,133 -> 546,133
|
||||
529,159 -> 529,153 -> 529,159 -> 531,159 -> 531,151 -> 531,159 -> 533,159 -> 533,156 -> 533,159 -> 535,159 -> 535,152 -> 535,159 -> 537,159 -> 537,154 -> 537,159 -> 539,159 -> 539,156 -> 539,159
|
||||
520,96 -> 520,92 -> 520,96 -> 522,96 -> 522,86 -> 522,96 -> 524,96 -> 524,92 -> 524,96 -> 526,96 -> 526,93 -> 526,96 -> 528,96 -> 528,95 -> 528,96 -> 530,96 -> 530,88 -> 530,96 -> 532,96 -> 532,88 -> 532,96 -> 534,96 -> 534,91 -> 534,96 -> 536,96 -> 536,92 -> 536,96 -> 538,96 -> 538,88 -> 538,96
|
||||
513,60 -> 513,61 -> 523,61 -> 523,60
|
||||
518,40 -> 522,40
|
||||
517,68 -> 522,68
|
||||
500,18 -> 500,20 -> 496,20 -> 496,24 -> 511,24 -> 511,20 -> 504,20 -> 504,18
|
||||
520,96 -> 520,92 -> 520,96 -> 522,96 -> 522,86 -> 522,96 -> 524,96 -> 524,92 -> 524,96 -> 526,96 -> 526,93 -> 526,96 -> 528,96 -> 528,95 -> 528,96 -> 530,96 -> 530,88 -> 530,96 -> 532,96 -> 532,88 -> 532,96 -> 534,96 -> 534,91 -> 534,96 -> 536,96 -> 536,92 -> 536,96 -> 538,96 -> 538,88 -> 538,96
|
||||
520,96 -> 520,92 -> 520,96 -> 522,96 -> 522,86 -> 522,96 -> 524,96 -> 524,92 -> 524,96 -> 526,96 -> 526,93 -> 526,96 -> 528,96 -> 528,95 -> 528,96 -> 530,96 -> 530,88 -> 530,96 -> 532,96 -> 532,88 -> 532,96 -> 534,96 -> 534,91 -> 534,96 -> 536,96 -> 536,92 -> 536,96 -> 538,96 -> 538,88 -> 538,96
|
||||
529,159 -> 529,153 -> 529,159 -> 531,159 -> 531,151 -> 531,159 -> 533,159 -> 533,156 -> 533,159 -> 535,159 -> 535,152 -> 535,159 -> 537,159 -> 537,154 -> 537,159 -> 539,159 -> 539,156 -> 539,159
|
||||
520,96 -> 520,92 -> 520,96 -> 522,96 -> 522,86 -> 522,96 -> 524,96 -> 524,92 -> 524,96 -> 526,96 -> 526,93 -> 526,96 -> 528,96 -> 528,95 -> 528,96 -> 530,96 -> 530,88 -> 530,96 -> 532,96 -> 532,88 -> 532,96 -> 534,96 -> 534,91 -> 534,96 -> 536,96 -> 536,92 -> 536,96 -> 538,96 -> 538,88 -> 538,96
|
||||
520,96 -> 520,92 -> 520,96 -> 522,96 -> 522,86 -> 522,96 -> 524,96 -> 524,92 -> 524,96 -> 526,96 -> 526,93 -> 526,96 -> 528,96 -> 528,95 -> 528,96 -> 530,96 -> 530,88 -> 530,96 -> 532,96 -> 532,88 -> 532,96 -> 534,96 -> 534,91 -> 534,96 -> 536,96 -> 536,92 -> 536,96 -> 538,96 -> 538,88 -> 538,96
|
||||
529,159 -> 529,153 -> 529,159 -> 531,159 -> 531,151 -> 531,159 -> 533,159 -> 533,156 -> 533,159 -> 535,159 -> 535,152 -> 535,159 -> 537,159 -> 537,154 -> 537,159 -> 539,159 -> 539,156 -> 539,159
|
||||
535,161 -> 535,162 -> 544,162 -> 544,161
|
||||
551,124 -> 556,124
|
||||
500,18 -> 500,20 -> 496,20 -> 496,24 -> 511,24 -> 511,20 -> 504,20 -> 504,18
|
||||
111
2022/day15/Makefile
Normal file
111
2022/day15/Makefile
Normal file
@@ -0,0 +1,111 @@
|
||||
# AOC daily Makefile - GNU make only.
|
||||
#
|
||||
# Copyright (C) 2021-2022 Bruno Raoult ("br")
|
||||
# Licensed under the GNU General Public License v3.0 or later.
|
||||
# Some rights reserved. See COPYING.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License along with this
|
||||
# program. If not, see <https://www.gnu.org/licenses/gpl-3.0-standalone.html>.
|
||||
#
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later <https://spdx.org/licenses/GPL-3.0-or-later.html>
|
||||
#
|
||||
|
||||
INPUT := input/input.txt
|
||||
SHELL := /bin/bash
|
||||
|
||||
CC := gcc
|
||||
BEAR := bear
|
||||
CCLSFILE:= compile_commands.json
|
||||
|
||||
LIB := aoc_$(shell uname -m)
|
||||
INCDIR := ../include
|
||||
LIBDIR := ../lib
|
||||
LDFLAGS := -L$(LIBDIR)
|
||||
#LDLIB := -l$(LIB) -lm
|
||||
LDLIB := -l$(LIB)
|
||||
|
||||
export LD_LIBRARY_PATH = $(LIBDIR)
|
||||
|
||||
CFLAGS += -std=gnu11
|
||||
CFLAGS += -O2
|
||||
CFLAGS += -g
|
||||
# for gprof
|
||||
# CFLAGS += -pg
|
||||
CFLAGS += -Wall
|
||||
CFLAGS += -Wextra
|
||||
CFLAGS += -march=native
|
||||
# Next one may be useful for valgrind (some invalid instructions)
|
||||
# CFLAGS += -mno-tbm
|
||||
CFLAGS += -Wmissing-declarations
|
||||
CFLAGS += -Wno-unused-result
|
||||
|
||||
CFLAGS += -DDEBUG_DEBUG # activate general debug (debug.c)
|
||||
CFLAGS += -DDEBUG_POOL # memory pools management
|
||||
|
||||
VALGRIND := valgrind
|
||||
VALGRINDFLAGS := --leak-check=full --show-leak-kinds=all --track-origins=yes \
|
||||
--sigill-diagnostics=yes --quiet --show-error-list=yes
|
||||
|
||||
|
||||
TIME := \time -f "\ttime: %E real, %U user, %S sys\n\tcontext-switch:\t%c+%w, page-faults: %F+%R\n"
|
||||
export PATH := .:$(PATH)
|
||||
|
||||
.PHONY: clean all compile assembly memcheck memcheck1 memcheck2 part1 part2 ccls bear org
|
||||
|
||||
all: README.org ccls part1 part2
|
||||
|
||||
memcheck: memcheck1 memcheck2
|
||||
|
||||
memcheck1: aoc-c
|
||||
@$(VALGRIND) $(VALGRINDFLAGS) aoc-c -p 1 < $(INPUT)
|
||||
|
||||
memcheck2: aoc-c
|
||||
@$(VALGRIND) $(VALGRINDFLAGS) aoc-c -p 2 < $(INPUT)
|
||||
@#@valgrind -s --track-origins=yes aoc-c -p 2 < $(INPUT)
|
||||
|
||||
compile: aoc-c
|
||||
|
||||
cpp: aoc-c.i
|
||||
|
||||
assembly: aoc-c.s
|
||||
|
||||
part1: aoc-c
|
||||
@#$(TIME) aoc.bash -p 1 < $(INPUT) 2>&1
|
||||
@$(TIME) aoc-c -p 1 < $(INPUT)
|
||||
|
||||
part2: aoc-c
|
||||
@#$(TIME) aoc.bash -p 2 < $(INPUT) 2>&1
|
||||
@$(TIME) aoc-c -p 2 < $(INPUT)
|
||||
|
||||
ccls: $(CCLSFILE)
|
||||
|
||||
clean:
|
||||
@rm -f aoc-c core* vgcore* gmon.out aoc-c.s aoc-c.i README.html compile_commands.json
|
||||
|
||||
aoc-c: aoc-c.c common.c
|
||||
@echo compiling $<
|
||||
$(CC) $(CFLAGS) $(LDFLAGS) -I $(INCDIR) $^ $(LDLIB) -o $@
|
||||
|
||||
# generate pre-processed file (.i) and assembler (.s)
|
||||
%.i: %.c
|
||||
@echo generating $@
|
||||
@$(CC) -E $(CFLAGS) -I $(INCDIR) $< -o $@
|
||||
|
||||
%.s: %.c
|
||||
@echo generating $@
|
||||
@$(CC) -S -fverbose-asm $(CFLAGS) -I $(INCDIR) $< -o $@
|
||||
|
||||
# generate README.org from README.html (must cleanup !)
|
||||
org: README.org
|
||||
|
||||
%.org: %.html
|
||||
@echo generating $@. Cleanup before commit !
|
||||
@pandoc $< -o $@
|
||||
|
||||
# generate compile_commands.json
|
||||
$(CCLSFILE): aoc-c.c Makefile
|
||||
$(BEAR) -- make clean compile
|
||||
|
||||
bear: clean
|
||||
@touch .ccls-root
|
||||
@$(BEAR) -- make compile
|
||||
163
2022/day15/README.org
Normal file
163
2022/day15/README.org
Normal file
@@ -0,0 +1,163 @@
|
||||
** --- Day 15: Beacon Exclusion Zone ---
|
||||
You feel the ground rumble again as the distress signal leads you to a
|
||||
large network of subterranean tunnels. You don't have time to search
|
||||
them all, but you don't need to: your pack contains a set of deployable
|
||||
/sensors/ that you imagine were originally built to locate lost Elves.
|
||||
|
||||
The sensors aren't very powerful, but that's okay; your handheld device
|
||||
indicates that you're close enough to the source of the distress signal
|
||||
to use them. You pull the emergency sensor system out of your pack, hit
|
||||
the big button on top, and the sensors zoom off down the tunnels.
|
||||
|
||||
Once a sensor finds a spot it thinks will give it a good reading, it
|
||||
attaches itself to a hard surface and begins monitoring for the nearest
|
||||
signal source /beacon/. Sensors and beacons always exist at integer
|
||||
coordinates. Each sensor knows its own position and can /determine the
|
||||
position of a beacon precisely/; however, sensors can only lock on to
|
||||
the one beacon /closest to the sensor/ as measured by the
|
||||
[[https://en.wikipedia.org/wiki/Taxicab_geometry][Manhattan distance]].
|
||||
(There is never a tie where two beacons are the same distance to a
|
||||
sensor.)
|
||||
|
||||
It doesn't take long for the sensors to report back their positions and
|
||||
closest beacons (your puzzle input). For example:
|
||||
|
||||
#+begin_example
|
||||
Sensor at x=2, y=18: closest beacon is at x=-2, y=15
|
||||
Sensor at x=9, y=16: closest beacon is at x=10, y=16
|
||||
Sensor at x=13, y=2: closest beacon is at x=15, y=3
|
||||
Sensor at x=12, y=14: closest beacon is at x=10, y=16
|
||||
Sensor at x=10, y=20: closest beacon is at x=10, y=16
|
||||
Sensor at x=14, y=17: closest beacon is at x=10, y=16
|
||||
Sensor at x=8, y=7: closest beacon is at x=2, y=10
|
||||
Sensor at x=2, y=0: closest beacon is at x=2, y=10
|
||||
Sensor at x=0, y=11: closest beacon is at x=2, y=10
|
||||
Sensor at x=20, y=14: closest beacon is at x=25, y=17
|
||||
Sensor at x=17, y=20: closest beacon is at x=21, y=22
|
||||
Sensor at x=16, y=7: closest beacon is at x=15, y=3
|
||||
Sensor at x=14, y=3: closest beacon is at x=15, y=3
|
||||
Sensor at x=20, y=1: closest beacon is at x=15, y=3
|
||||
#+end_example
|
||||
|
||||
So, consider the sensor at =2,18=; the closest beacon to it is at
|
||||
=-2,15=. For the sensor at =9,16=, the closest beacon to it is at
|
||||
=10,16=.
|
||||
|
||||
Drawing sensors as =S= and beacons as =B=, the above arrangement of
|
||||
sensors and beacons looks like this:
|
||||
|
||||
#+begin_example
|
||||
1 1 2 2
|
||||
0 5 0 5 0 5
|
||||
0 ....S.......................
|
||||
1 ......................S.....
|
||||
2 ...............S............
|
||||
3 ................SB..........
|
||||
4 ............................
|
||||
5 ............................
|
||||
6 ............................
|
||||
7 ..........S.......S.........
|
||||
8 ............................
|
||||
9 ............................
|
||||
10 ....B.......................
|
||||
11 ..S.........................
|
||||
12 ............................
|
||||
13 ............................
|
||||
14 ..............S.......S.....
|
||||
15 B...........................
|
||||
16 ...........SB...............
|
||||
17 ................S..........B
|
||||
18 ....S.......................
|
||||
19 ............................
|
||||
20 ............S......S........
|
||||
21 ............................
|
||||
22 .......................B....
|
||||
#+end_example
|
||||
|
||||
This isn't necessarily a comprehensive map of all beacons in the area,
|
||||
though. Because each sensor only identifies its closest beacon, if a
|
||||
sensor detects a beacon, you know there are no other beacons that close
|
||||
or closer to that sensor. There could still be beacons that just happen
|
||||
to not be the closest beacon to any sensor. Consider the sensor at
|
||||
=8,7=:
|
||||
|
||||
#+begin_example
|
||||
1 1 2 2
|
||||
0 5 0 5 0 5
|
||||
-2 ..........#.................
|
||||
-1 .........###................
|
||||
0 ....S...#####...............
|
||||
1 .......#######........S.....
|
||||
2 ......#########S............
|
||||
3 .....###########SB..........
|
||||
4 ....#############...........
|
||||
5 ...###############..........
|
||||
6 ..#################.........
|
||||
7 .#########S#######S#........
|
||||
8 ..#################.........
|
||||
9 ...###############..........
|
||||
10 ....B############...........
|
||||
11 ..S..###########............
|
||||
12 ......#########.............
|
||||
13 .......#######..............
|
||||
14 ........#####.S.......S.....
|
||||
15 B........###................
|
||||
16 ..........#SB...............
|
||||
17 ................S..........B
|
||||
18 ....S.......................
|
||||
19 ............................
|
||||
20 ............S......S........
|
||||
21 ............................
|
||||
22 .......................B....
|
||||
#+end_example
|
||||
|
||||
This sensor's closest beacon is at =2,10=, and so you know there are no
|
||||
beacons that close or closer (in any positions marked =#=).
|
||||
|
||||
None of the detected beacons seem to be producing the distress signal,
|
||||
so you'll need to work out where the distress beacon is by working out
|
||||
where it /isn't/. For now, keep things simple by counting the positions
|
||||
where a beacon cannot possibly be along just a single row.
|
||||
|
||||
So, suppose you have an arrangement of beacons and sensors like in the
|
||||
example above and, just in the row where =y=10=, you'd like to count the
|
||||
number of positions a beacon cannot possibly exist. The coverage from
|
||||
all sensors near that row looks like this:
|
||||
|
||||
#+begin_example
|
||||
1 1 2 2
|
||||
0 5 0 5 0 5
|
||||
9 ...#########################...
|
||||
10 ..####B######################..
|
||||
11 .###S#############.###########.
|
||||
#+end_example
|
||||
|
||||
In this example, in the row where =y=10=, there are =26= positions where
|
||||
a beacon cannot be present.
|
||||
|
||||
Consult the report from the sensors you just deployed. /In the row where
|
||||
=y=2000000=, how many positions cannot contain a beacon?/
|
||||
|
||||
Your puzzle answer was =5176944=.
|
||||
|
||||
** --- Part Two ---
|
||||
Your handheld device indicates that the distress signal is coming from a
|
||||
beacon nearby. The distress beacon is not detected by any sensor, but
|
||||
the distress beacon must have =x= and =y= coordinates each no lower than
|
||||
=0= and no larger than =4000000=.
|
||||
|
||||
To isolate the distress beacon's signal, you need to determine its
|
||||
/tuning frequency/, which can be found by multiplying its =x= coordinate
|
||||
by =4000000= and then adding its =y= coordinate.
|
||||
|
||||
In the example above, the search space is smaller: instead, the =x= and
|
||||
=y= coordinates can each be at most =20=. With this reduced search area,
|
||||
there is only a single position that could have a beacon: =x=14, y=11=.
|
||||
The tuning frequency for this distress beacon is =56000011=.
|
||||
|
||||
Find the only possible position for the distress beacon. /What is its
|
||||
tuning frequency?/
|
||||
|
||||
Your puzzle answer was =13350458933732=.
|
||||
|
||||
Both parts of this puzzle are complete! They provide two gold stars: **
|
||||
408
2022/day15/aoc-c.c
Normal file
408
2022/day15/aoc-c.c
Normal file
@@ -0,0 +1,408 @@
|
||||
/* aoc-c.c: Advent of Code 2022, day 15
|
||||
*
|
||||
* Copyright (C) 2022-2023 Bruno Raoult ("br")
|
||||
* Licensed under the GNU General Public License v3.0 or later.
|
||||
* Some rights reserved. See COPYING.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with this
|
||||
* program. If not, see <https://www.gnu.org/licenses/gpl-3.0-standalone.html>.
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later <https://spdx.org/licenses/GPL-3.0-or-later.html>
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <limits.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "br.h"
|
||||
#include "list.h"
|
||||
#include "pool.h"
|
||||
#include "debug.h"
|
||||
|
||||
#include "aoc.h"
|
||||
|
||||
static pool_t *pool_segment, *pool_pair;
|
||||
|
||||
#define HBITS 20 /* 20 bits: 1,048,576 buckets */
|
||||
struct coord {
|
||||
int x, y;
|
||||
};
|
||||
|
||||
#define TOP 0
|
||||
#define RIGHT 1
|
||||
#define BOTTOM 2
|
||||
#define LEFT 3
|
||||
|
||||
/**
|
||||
* struct pair - input file pair list
|
||||
* @sensor, @beacon: struct coord sensor and beacon coordinates.
|
||||
* @manhattan: manhattan distance between sensor and beacon.
|
||||
* @parity: beacon coordinates parity (as bishop color in chess).
|
||||
* @corners: coordinates of rhombus immediately out of sensor range (clockwise).
|
||||
* @list: list of pairs.
|
||||
*/
|
||||
struct pair {
|
||||
struct coord sensor, beacon;
|
||||
int manhattan;
|
||||
int parity;
|
||||
struct coord corners[4];
|
||||
struct list_head list;
|
||||
};
|
||||
LIST_HEAD(pairs_head);
|
||||
|
||||
/**
|
||||
* struct row - row description
|
||||
* @row: row number.
|
||||
* @segments: segments list.
|
||||
* @hlist: htable bucket list.
|
||||
*/
|
||||
struct row {
|
||||
int row;
|
||||
int beacons[64];
|
||||
int nbeacons;
|
||||
struct list_head segments;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct map - full map
|
||||
* @min, @max: map's min and max coordinates.
|
||||
* @hash: rows hash table
|
||||
*/
|
||||
static struct map {
|
||||
struct coord min, max;
|
||||
struct row row; /* for part 1 */
|
||||
//hlist_head *hash;
|
||||
} map = {
|
||||
.min = { INT_MIN, INT_MIN }, .max = {INT_MAX, INT_MAX },
|
||||
.row = { 0, {0}, 0, LIST_HEAD_INIT(map.row.segments) }
|
||||
};
|
||||
|
||||
/**
|
||||
* struct segment - The main segment structure
|
||||
* @row: the row number
|
||||
* @start, @end: segment start and end
|
||||
* @list: sorted row's segments list
|
||||
*
|
||||
* If a row contains 2 segments 1-3 and 7-8, it would be represented as:
|
||||
* +----------+ +----------+
|
||||
* | start: 1 |<------>| start: 7 |
|
||||
* | end: 3 | | end: 8 |
|
||||
* +----------+ +----------+
|
||||
*
|
||||
* This implies adding a segment must manage merging. For example, adding
|
||||
* segment 2-4 above would change the first segment to 1-4, or adding 0-9
|
||||
* should change the first segment to 0-9 and remove the second one.
|
||||
*/
|
||||
struct segment {
|
||||
int row;
|
||||
int start, end;
|
||||
struct list_head list;
|
||||
};
|
||||
|
||||
static struct segment *get_segment(int row, int start, int end)
|
||||
{
|
||||
struct segment *new = pool_get(pool_segment);
|
||||
|
||||
log_f(5, "alloc segment (%d,%d) on row (%d)\n", start, end, row);
|
||||
new->row=row;
|
||||
new->start=start;
|
||||
new->end=end;
|
||||
INIT_LIST_HEAD(&new->list);
|
||||
return new;
|
||||
}
|
||||
|
||||
static void merge_segment(int start, int end)
|
||||
{
|
||||
struct segment *seg, *new;
|
||||
struct list_head *cur, *tmp;
|
||||
static int l = 9;
|
||||
|
||||
new = get_segment(map.row.row, start, end);
|
||||
if (list_empty(&map.row.segments)) {
|
||||
list_add(&new->list, &map.row.segments);
|
||||
goto end;
|
||||
}
|
||||
list_for_each_safe(cur, tmp, &map.row.segments) {
|
||||
seg = list_entry(cur, struct segment, list);
|
||||
|
||||
/* 1) check for disjoint segments */
|
||||
if (start > seg->end + 1) {
|
||||
continue;
|
||||
}
|
||||
if (end < seg->start - 1) {
|
||||
list_add_tail(&new->list, &seg->list);
|
||||
goto end;
|
||||
}
|
||||
|
||||
/* 2) new is inside cur: do nothing */
|
||||
if (start >= seg->start && end <= seg->end) {
|
||||
log_f(l, " overlap IN, do nothing\n");
|
||||
pool_add(pool_segment, new);
|
||||
goto end;
|
||||
}
|
||||
/* 3) cur inside new: remove cur */
|
||||
if (start <= seg->start && end >= seg->end) {
|
||||
log_f(l, " overlap OUT, remove current\n");
|
||||
// TODO: avoid this
|
||||
list_del(cur);
|
||||
pool_add(pool_segment, seg);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* 4) new segment start is within current one */
|
||||
if (start >= seg->start && start <= seg->end + 1) {
|
||||
new->start = seg->start;
|
||||
list_del(cur);
|
||||
pool_add(pool_segment, seg);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* 5) new segment is left-adjacent to current */
|
||||
if (end == seg->start - 1) {
|
||||
seg->start = start;
|
||||
pool_add(pool_segment, new);
|
||||
goto end;
|
||||
}
|
||||
|
||||
/* from here, we know there is an overlap */
|
||||
|
||||
/* 6) adjust new start to current start */
|
||||
if (start >= seg->start)
|
||||
new->start = seg->start;
|
||||
|
||||
/* 7) remove current if covered by new */
|
||||
if (end >= seg->end){
|
||||
list_del(cur);
|
||||
pool_add(pool_segment, seg);
|
||||
continue;
|
||||
}
|
||||
/* 8) replace current with new - finished */
|
||||
new->end = seg->end;
|
||||
list_add_tail(&new->list, cur);
|
||||
list_del(cur);
|
||||
pool_add(pool_segment, seg);
|
||||
goto end;
|
||||
}
|
||||
list_add_tail(&new->list, &map.row.segments);
|
||||
end:
|
||||
return;
|
||||
}
|
||||
|
||||
static __always_inline void add_beacon(int bx)
|
||||
{
|
||||
for (int i = 0; i < map.row.nbeacons; ++i) {
|
||||
if (map.row.beacons[i] == bx)
|
||||
return;
|
||||
}
|
||||
map.row.beacons[map.row.nbeacons++] = bx;
|
||||
}
|
||||
|
||||
/**
|
||||
* is_off_range() - test if a point is off range from all sensors.
|
||||
*/
|
||||
static __always_inline int is_off_range(struct coord *point)
|
||||
{
|
||||
struct pair *pair;
|
||||
|
||||
/* reverse loop, because higher manhattan means higher chances to fail */
|
||||
list_for_each_entry_reverse(pair, &pairs_head, list) {
|
||||
if ((abs(point->x - pair->sensor.x) +
|
||||
abs(point->y - pair->sensor.y)) <= pair->manhattan)
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static struct pair *parse()
|
||||
{
|
||||
int ret;
|
||||
struct pair *pair = NULL, *cur;
|
||||
struct coord sensor, beacon;
|
||||
|
||||
ret = scanf("%*[^-0-9]%d%*[^-0-9]%d%*[^-0-9]%d%*[^-0-9]%d",
|
||||
&sensor.x, &sensor.y, &beacon.x, &beacon.y);
|
||||
if (ret == 4) {
|
||||
pair = pool_get(pool_pair);
|
||||
pair->sensor = sensor;
|
||||
pair->beacon = beacon;
|
||||
pair->manhattan = abs(beacon.x - sensor.x) + abs(beacon.y - sensor.y);
|
||||
pair->parity = (pair->beacon.x + pair->beacon.y) % 2;
|
||||
pair->corners[TOP] = (struct coord) {
|
||||
sensor.x, sensor.y - pair->manhattan - 1
|
||||
};
|
||||
pair->corners[BOTTOM] = (struct coord) {
|
||||
sensor.x, sensor.y + pair->manhattan + 1
|
||||
};
|
||||
pair->corners[RIGHT] = (struct coord) {
|
||||
sensor.x + pair->manhattan + 1, sensor.y
|
||||
};
|
||||
pair->corners[LEFT] = (struct coord) {
|
||||
sensor.x - pair->manhattan - 1, sensor.y
|
||||
};
|
||||
|
||||
/* keep list ordered by manhattan */
|
||||
if (!list_empty(&pairs_head)) {
|
||||
list_for_each_entry(cur, &pairs_head, list) {
|
||||
if (cur->manhattan > pair->manhattan) {
|
||||
list_add_tail(&pair->list, &cur->list);
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
}
|
||||
list_add_tail(&pair->list, &pairs_head);
|
||||
}
|
||||
end:
|
||||
return pair;
|
||||
}
|
||||
|
||||
/**
|
||||
* /#\
|
||||
* /#\ /# #\
|
||||
* /# #\ /# #\
|
||||
* /# #\O/# <--- O is a possible point
|
||||
* #X#
|
||||
* rhomb A /#\ rhom B
|
||||
* /# #\
|
||||
* /# #\
|
||||
* /# #\
|
||||
* /# #\
|
||||
* /# rhombs #\
|
||||
* A & B
|
||||
* (intersection)
|
||||
*/
|
||||
|
||||
/**
|
||||
* intersect() - find intersection of two segments
|
||||
*
|
||||
*/
|
||||
static __always_inline struct coord *intersect(struct coord *p1, struct coord *p2,
|
||||
struct coord *q1, struct coord *q2,
|
||||
struct coord *ret)
|
||||
{
|
||||
int a1, a2, b1, b2, x, y;
|
||||
|
||||
/* a1, b1, a2, b2 are the formulas of (p1, p2) and (q1, q2), such as:
|
||||
* y = ax + b
|
||||
* a = (y2 - y1) / (x2 - x1) x2 ≠ x1
|
||||
* b = y - a * x We can take either p1 or p2 coordinates
|
||||
*/
|
||||
a1 = (p2->y - p1->y) / (p2->x - p1->x);
|
||||
b1 = p1->y - p1->x * a1;
|
||||
a2 = (q2->y - q1->y) / (q2->x - q1->x);
|
||||
b2 = q1->y - q1->x * a2;
|
||||
|
||||
/* Lines intersection (x,y) is at:
|
||||
* (a1 * x) + b1 = (a2 * x) + b2
|
||||
* x * (a1 - a2) = b2 - b1
|
||||
* x = (b2 - b1) / (a1 - a2) a2 ≠ a1
|
||||
* Then we find y = ax + b
|
||||
*/
|
||||
x = (b2 - b1) / (a1 - a2);
|
||||
y = a1 * x + b1;
|
||||
|
||||
/* check if intersection is:
|
||||
* 1) Within p1-p2 and q1-q2 segments
|
||||
* 2) Within map area
|
||||
*/
|
||||
if (x >= min(min(p1->x, p2->x), min(q1->x, q2->x)) &&
|
||||
x <= max(max(p1->x, p2->x), max(q1->x, q2->x)) &&
|
||||
y >= min(min(p1->y, p2->y), min(q1->y, q2->y)) &&
|
||||
y <= max(max(p1->y, p2->y), max(q1->y, q2->y)) &&
|
||||
x >= map.min.x && x <= map.max.x &&
|
||||
y >= map.min.y && y <= map.max.y) {
|
||||
*ret = (struct coord) {x, y};
|
||||
} else {
|
||||
ret = NULL;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
#define T_R(p) &p->corners[TOP], &p->corners[RIGHT]
|
||||
#define R_B(p) &p->corners[RIGHT], &p->corners[BOTTOM]
|
||||
#define B_L(p) &p->corners[BOTTOM], &p->corners[LEFT]
|
||||
#define L_T(p) &p->corners[LEFT], &p->corners[TOP]
|
||||
|
||||
static struct coord *check_intersect(struct coord *ret)
|
||||
{
|
||||
struct pair *pair, *second;
|
||||
|
||||
list_for_each_entry(pair, &pairs_head, list) {
|
||||
second = list_prepare_entry(pair, &pairs_head, list);
|
||||
list_for_each_entry_continue(second, &pairs_head, list) {
|
||||
if (second->parity == pair->parity) {
|
||||
/* top right segment */
|
||||
if ((intersect(T_R(pair), R_B(second), ret) && is_off_range(ret)) ||
|
||||
(intersect(T_R(pair), L_T(second), ret) && is_off_range(ret)))
|
||||
return ret;
|
||||
/* bottom left segment */
|
||||
if ((intersect(B_L(pair), R_B(second), ret) && is_off_range(ret)) ||
|
||||
(intersect(B_L(pair), L_T(second), ret) && is_off_range(ret)))
|
||||
return ret;
|
||||
/* right bottom segment */
|
||||
if ((intersect(R_B(pair), T_R(second), ret) && is_off_range(ret)) ||
|
||||
(intersect(R_B(pair), B_L(second), ret) && is_off_range(ret)))
|
||||
return ret;
|
||||
/* left top segment */
|
||||
if ((intersect(L_T(pair), T_R(second), ret) && is_off_range(ret)) ||
|
||||
(intersect(L_T(pair), B_L(second), ret) && is_off_range(ret)))
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static u64 part1(void)
|
||||
{
|
||||
u64 res = 0;
|
||||
struct pair *pair;
|
||||
struct segment *cur;
|
||||
|
||||
map.row.row = map.min.y = map.max.y = testmode() ? 10: 2000000;
|
||||
|
||||
while ((pair = parse())) {
|
||||
if (map.row.row >= pair->sensor.y - pair->manhattan &&
|
||||
map.row.row <= pair->sensor.y + pair->manhattan) {
|
||||
int half = pair->manhattan - abs(map.row.row - pair->sensor.y);
|
||||
int x1 = max(pair->sensor.x - half, map.min.x);
|
||||
int x2 = max(pair->sensor.x + half, map.min.x);
|
||||
merge_segment(x1, x2);
|
||||
if (map.row.row == pair->beacon.y)
|
||||
add_beacon(pair->beacon.x);
|
||||
}
|
||||
}
|
||||
list_for_each_entry(cur, &map.row.segments, list)
|
||||
res += cur->end - cur->start + 1;
|
||||
return res - map.row.nbeacons;
|
||||
}
|
||||
|
||||
static u64 part2()
|
||||
{
|
||||
u64 res = 0;
|
||||
struct coord result = {0, 0};
|
||||
|
||||
map.min.x = map.min.y = 0;
|
||||
map.max.x = map.max.y = testmode()? 20: 4000000;
|
||||
|
||||
while (parse())
|
||||
;
|
||||
check_intersect(&result);
|
||||
res = ((u64)result.x) * 4000000UL + (u64)result.y;
|
||||
return res;
|
||||
}
|
||||
|
||||
int main(int ac, char **av)
|
||||
{
|
||||
int part = parseargs(ac, av);
|
||||
|
||||
pool_segment = pool_create("segments", 8192, sizeof(struct segment));
|
||||
pool_pair = pool_create("pair", 32, sizeof(struct pair));
|
||||
|
||||
printf("%s: res=%lu\n", *av, part == 1? part1(): part2());
|
||||
pool_destroy(pool_segment);
|
||||
pool_destroy(pool_pair);
|
||||
exit(0);
|
||||
}
|
||||
17
2022/day15/aoc.h
Normal file
17
2022/day15/aoc.h
Normal file
@@ -0,0 +1,17 @@
|
||||
/* aoc.c: Advent of Code 2022
|
||||
*
|
||||
* Copyright (C) 2022 Bruno Raoult ("br")
|
||||
* Licensed under the GNU General Public License v3.0 or later.
|
||||
* Some rights reserved. See COPYING.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with this
|
||||
* program. If not, see <https://www.gnu.org/licenses/gpl-3.0-standalone.html>.
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later <https://spdx.org/licenses/GPL-3.0-or-later.html>
|
||||
*/
|
||||
#ifndef _AOC_H_
|
||||
#define _AOC_H_
|
||||
|
||||
extern int parseargs(int ac, char**av);
|
||||
extern int testmode(void);
|
||||
#endif /* _AOC_H_ */
|
||||
68
2022/day15/common.bash
Normal file
68
2022/day15/common.bash
Normal file
@@ -0,0 +1,68 @@
|
||||
#!/usr/bin/env bash
|
||||
#
|
||||
# common.bash: Advent of Code 2022, common bash functions
|
||||
#
|
||||
# Copyright (C) 2022 Bruno Raoult ("br")
|
||||
# Licensed under the GNU General Public License v3.0 or later.
|
||||
# Some rights reserved. See COPYING.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License along with this
|
||||
# program. If not, see <https://www.gnu.org/licenses/gpl-3.0-standalone.html>.
|
||||
#
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later <https://spdx.org/licenses/GPL-3.0-or-later.html>
|
||||
|
||||
# shellcheck disable=2034
|
||||
export cmdname=${0##*/}
|
||||
export debug=0
|
||||
export res
|
||||
export LANG=C
|
||||
|
||||
shopt -s extglob
|
||||
set -o noglob
|
||||
|
||||
usage() {
|
||||
printf "usage: %s [-d DEBUG] [-p PART]\n" "$cmdname"
|
||||
exit 1
|
||||
}
|
||||
|
||||
checkargs() {
|
||||
local part=1
|
||||
while getopts p:d: todo; do
|
||||
case "$todo" in
|
||||
d)
|
||||
if [[ "$OPTARG" =~ ^[[:digit:]+]$ ]]; then
|
||||
debug="$OPTARG"
|
||||
else
|
||||
printf "%s: illegal [%s] debug level.\n" "$CMD" "$OPTARG"
|
||||
exit 1
|
||||
fi
|
||||
;;
|
||||
p)
|
||||
if [[ "$OPTARG" =~ ^[12]$ ]]; then
|
||||
part="$OPTARG"
|
||||
else
|
||||
printf "%s: illegal [%s] part.\n" "$CMD" "$OPTARG"
|
||||
exit 1
|
||||
fi
|
||||
;;
|
||||
*)
|
||||
usage
|
||||
;;
|
||||
esac
|
||||
done
|
||||
# Now check remaining argument (backup directory)
|
||||
shift $((OPTIND - 1))
|
||||
|
||||
(( $# > 1 )) && usage
|
||||
return "$part"
|
||||
}
|
||||
|
||||
main() {
|
||||
local -i part
|
||||
|
||||
checkargs "$@"
|
||||
part=$?
|
||||
parse "$part"
|
||||
solve "$part"
|
||||
printf "%s: res=%s\n" "$cmdname" "$res"
|
||||
}
|
||||
59
2022/day15/common.c
Normal file
59
2022/day15/common.c
Normal file
@@ -0,0 +1,59 @@
|
||||
/* common.c: Advent of Code 2022, common functions
|
||||
*
|
||||
* Copyright (C) 2022 Bruno Raoult ("br")
|
||||
* Licensed under the GNU General Public License v3.0 or later.
|
||||
* Some rights reserved. See COPYING.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with this
|
||||
* program. If not, see <https://www.gnu.org/licenses/gpl-3.0-standalone.html>.
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later <https://spdx.org/licenses/GPL-3.0-or-later.html>
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "aoc.h"
|
||||
#include "debug.h"
|
||||
|
||||
static int _testmode = 0;
|
||||
|
||||
static int usage(char *prg)
|
||||
{
|
||||
fprintf(stderr, "Usage: %s [-t][-d debug_level] [-p part] [-i input]\n", prg);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int testmode(void)
|
||||
{
|
||||
return _testmode;
|
||||
}
|
||||
|
||||
int parseargs(int ac, char **av)
|
||||
{
|
||||
int opt, part = 1;
|
||||
|
||||
while ((opt = getopt(ac, av, "td:p:")) != -1) {
|
||||
switch (opt) {
|
||||
case 't':
|
||||
_testmode = 1;
|
||||
break;
|
||||
case 'd':
|
||||
debug_level_set(atoi(optarg));
|
||||
break;
|
||||
case 'p': /* 1 or 2 */
|
||||
part = atoi(optarg);
|
||||
if (part < 1 || part > 2)
|
||||
return usage(*av);
|
||||
break;
|
||||
case 'i':
|
||||
|
||||
default:
|
||||
return usage(*av);
|
||||
}
|
||||
}
|
||||
if (optind < ac)
|
||||
return usage(*av);
|
||||
return part;
|
||||
}
|
||||
14
2022/day15/input/example.txt
Normal file
14
2022/day15/input/example.txt
Normal file
@@ -0,0 +1,14 @@
|
||||
Sensor at x=2, y=18: closest beacon is at x=-2, y=15
|
||||
Sensor at x=9, y=16: closest beacon is at x=10, y=16
|
||||
Sensor at x=13, y=2: closest beacon is at x=15, y=3
|
||||
Sensor at x=12, y=14: closest beacon is at x=10, y=16
|
||||
Sensor at x=10, y=20: closest beacon is at x=10, y=16
|
||||
Sensor at x=14, y=17: closest beacon is at x=10, y=16
|
||||
Sensor at x=8, y=7: closest beacon is at x=2, y=10
|
||||
Sensor at x=2, y=0: closest beacon is at x=2, y=10
|
||||
Sensor at x=0, y=11: closest beacon is at x=2, y=10
|
||||
Sensor at x=20, y=14: closest beacon is at x=25, y=17
|
||||
Sensor at x=17, y=20: closest beacon is at x=21, y=22
|
||||
Sensor at x=16, y=7: closest beacon is at x=15, y=3
|
||||
Sensor at x=14, y=3: closest beacon is at x=15, y=3
|
||||
Sensor at x=20, y=1: closest beacon is at x=15, y=3
|
||||
26
2022/day15/input/input.txt
Normal file
26
2022/day15/input/input.txt
Normal file
@@ -0,0 +1,26 @@
|
||||
Sensor at x=3999724, y=2000469: closest beacon is at x=4281123, y=2282046
|
||||
Sensor at x=3995530, y=8733: closest beacon is at x=3321979, y=-692911
|
||||
Sensor at x=3016889, y=2550239: closest beacon is at x=2408038, y=2645605
|
||||
Sensor at x=3443945, y=3604888: closest beacon is at x=3610223, y=3768674
|
||||
Sensor at x=168575, y=491461: closest beacon is at x=1053731, y=-142061
|
||||
Sensor at x=2820722, y=3865596: closest beacon is at x=3191440, y=3801895
|
||||
Sensor at x=2329102, y=2456329: closest beacon is at x=2408038, y=2645605
|
||||
Sensor at x=3889469, y=3781572: closest beacon is at x=3610223, y=3768674
|
||||
Sensor at x=3256726, y=3882107: closest beacon is at x=3191440, y=3801895
|
||||
Sensor at x=3729564, y=3214899: closest beacon is at x=3610223, y=3768674
|
||||
Sensor at x=206718, y=2732608: closest beacon is at x=-152842, y=3117903
|
||||
Sensor at x=2178192, y=2132103: closest beacon is at x=2175035, y=2000000
|
||||
Sensor at x=1884402, y=214904: closest beacon is at x=1053731, y=-142061
|
||||
Sensor at x=3060435, y=980430: closest beacon is at x=2175035, y=2000000
|
||||
Sensor at x=3998355, y=3965954: closest beacon is at x=3610223, y=3768674
|
||||
Sensor at x=3704399, y=3973731: closest beacon is at x=3610223, y=3768674
|
||||
Sensor at x=1421672, y=3446889: closest beacon is at x=2408038, y=2645605
|
||||
Sensor at x=3415633, y=3916020: closest beacon is at x=3191440, y=3801895
|
||||
Sensor at x=2408019, y=2263990: closest beacon is at x=2408038, y=2645605
|
||||
Sensor at x=3735247, y=2533767: closest beacon is at x=4281123, y=2282046
|
||||
Sensor at x=1756494, y=1928662: closest beacon is at x=2175035, y=2000000
|
||||
Sensor at x=780161, y=1907142: closest beacon is at x=2175035, y=2000000
|
||||
Sensor at x=3036853, y=3294727: closest beacon is at x=3191440, y=3801895
|
||||
Sensor at x=53246, y=3908582: closest beacon is at x=-152842, y=3117903
|
||||
Sensor at x=2110517, y=2243287: closest beacon is at x=2175035, y=2000000
|
||||
Sensor at x=3149491, y=3998374: closest beacon is at x=3191440, y=3801895
|
||||
111
2022/day16/Makefile
Normal file
111
2022/day16/Makefile
Normal file
@@ -0,0 +1,111 @@
|
||||
# AOC daily Makefile - GNU make only.
|
||||
#
|
||||
# Copyright (C) 2021-2023 Bruno Raoult ("br")
|
||||
# Licensed under the GNU General Public License v3.0 or later.
|
||||
# Some rights reserved. See COPYING.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License along with this
|
||||
# program. If not, see <https://www.gnu.org/licenses/gpl-3.0-standalone.html>.
|
||||
#
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later <https://spdx.org/licenses/GPL-3.0-or-later.html>
|
||||
#
|
||||
|
||||
INPUT := input/input.txt
|
||||
SHELL := /bin/bash
|
||||
|
||||
CC := gcc
|
||||
BEAR := bear
|
||||
CCLSFILE:= compile_commands.json
|
||||
|
||||
LIB := aoc_$(shell uname -m)
|
||||
INCDIR := ../include
|
||||
LIBDIR := ../lib
|
||||
LDFLAGS := -L$(LIBDIR)
|
||||
#LDLIB := -l$(LIB) -lm
|
||||
LDLIB := -l$(LIB)
|
||||
|
||||
export LD_LIBRARY_PATH = $(LIBDIR)
|
||||
|
||||
CFLAGS += -std=gnu11
|
||||
CFLAGS += -O2
|
||||
CFLAGS += -g
|
||||
# for gprof
|
||||
# CFLAGS += -pg
|
||||
CFLAGS += -Wall
|
||||
CFLAGS += -Wextra
|
||||
CFLAGS += -march=native
|
||||
# Next one may be useful for valgrind (some invalid instructions)
|
||||
# CFLAGS += -mno-tbm
|
||||
CFLAGS += -Wmissing-declarations
|
||||
CFLAGS += -Wno-unused-result
|
||||
|
||||
CFLAGS += -DDEBUG_DEBUG # activate general debug (debug.c)
|
||||
CFLAGS += -DDEBUG_POOL # memory pools management
|
||||
|
||||
VALGRIND := valgrind
|
||||
VALGRINDFLAGS := --leak-check=full --show-leak-kinds=all --track-origins=yes \
|
||||
--sigill-diagnostics=yes --quiet --show-error-list=yes
|
||||
|
||||
|
||||
TIME := \time -f "\ttime: %E real, %U user, %S sys\n\tcontext-switch:\t%c+%w, page-faults: %F+%R\n"
|
||||
export PATH := .:$(PATH)
|
||||
|
||||
.PHONY: clean all compile assembly memcheck memcheck1 memcheck2 part1 part2 ccls bear org
|
||||
|
||||
all: README.org ccls part1 part2
|
||||
|
||||
memcheck: memcheck1 memcheck2
|
||||
|
||||
memcheck1: aoc-c
|
||||
@$(VALGRIND) $(VALGRINDFLAGS) aoc-c -p 1 < $(INPUT)
|
||||
|
||||
memcheck2: aoc-c
|
||||
@$(VALGRIND) $(VALGRINDFLAGS) aoc-c -p 2 < $(INPUT)
|
||||
@#@valgrind -s --track-origins=yes aoc-c -p 2 < $(INPUT)
|
||||
|
||||
compile: aoc-c
|
||||
|
||||
cpp: aoc-c.i
|
||||
|
||||
assembly: aoc-c.s
|
||||
|
||||
part1: aoc-c
|
||||
@#$(TIME) aoc.bash -p 1 < $(INPUT) 2>&1
|
||||
@$(TIME) aoc-c -p 1 < $(INPUT)
|
||||
|
||||
part2: aoc-c
|
||||
@#$(TIME) aoc.bash -p 2 < $(INPUT) 2>&1
|
||||
@$(TIME) aoc-c -p 2 < $(INPUT)
|
||||
|
||||
ccls: $(CCLSFILE)
|
||||
|
||||
clean:
|
||||
@rm -f aoc-c core* vgcore* gmon.out aoc-c.s aoc-c.i README.html compile_commands.json
|
||||
|
||||
aoc-c: aoc-c.c common.c
|
||||
@echo compiling $<
|
||||
$(CC) $(CFLAGS) $(LDFLAGS) -I $(INCDIR) $^ $(LDLIB) -o $@
|
||||
|
||||
# generate pre-processed file (.i) and assembler (.s)
|
||||
%.i: %.c
|
||||
@echo generating $@
|
||||
@$(CC) -E $(CFLAGS) -I $(INCDIR) $< -o $@
|
||||
|
||||
%.s: %.c
|
||||
@echo generating $@
|
||||
@$(CC) -S -fverbose-asm $(CFLAGS) -I $(INCDIR) $< -o $@
|
||||
|
||||
# generate README.org from README.html (must cleanup !)
|
||||
org: README.org
|
||||
|
||||
%.org: %.html
|
||||
@echo generating $@. Cleanup before commit !
|
||||
@pandoc $< -o $@
|
||||
|
||||
# generate compile_commands.json
|
||||
$(CCLSFILE): aoc-c.c Makefile
|
||||
$(BEAR) -- make clean compile
|
||||
|
||||
bear: clean
|
||||
@touch .ccls-root
|
||||
@$(BEAR) -- make compile
|
||||
275
2022/day16/README.org
Normal file
275
2022/day16/README.org
Normal file
@@ -0,0 +1,275 @@
|
||||
** --- Day 16: Proboscidea Volcanium ---
|
||||
The sensors have led you to the origin of the distress signal: yet
|
||||
another handheld device, just like the one the Elves gave you. However,
|
||||
you don't see any Elves around; instead, the device is surrounded by
|
||||
elephants! They must have gotten lost in these tunnels, and one of the
|
||||
elephants apparently figured out how to turn on the distress signal.
|
||||
|
||||
The ground rumbles again, much stronger this time. What kind of cave is
|
||||
this, exactly? You scan the cave with your handheld device; it reports
|
||||
mostly igneous rock, some ash, pockets of pressurized gas, magma... this
|
||||
isn't just a cave, it's a volcano!
|
||||
|
||||
You need to get the elephants out of here, quickly. Your device
|
||||
estimates that you have /30 minutes/ before the volcano erupts, so you
|
||||
don't have time to go back out the way you came in.
|
||||
|
||||
You scan the cave for other options and discover a network of pipes and
|
||||
pressure-release /valves/. You aren't sure how such a system got into a
|
||||
volcano, but you don't have time to complain; your device produces a
|
||||
report (your puzzle input) of each valve's /flow rate/ if it were opened
|
||||
(in pressure per minute) and the tunnels you could use to move between
|
||||
the valves.
|
||||
|
||||
There's even a valve in the room you and the elephants are currently
|
||||
standing in labeled =AA=. You estimate it will take you one minute to
|
||||
open a single valve and one minute to follow any tunnel from one valve
|
||||
to another. What is the most pressure you could release?
|
||||
|
||||
For example, suppose you had the following scan output:
|
||||
|
||||
#+begin_example
|
||||
Valve AA has flow rate=0; tunnels lead to valves DD, II, BB
|
||||
Valve BB has flow rate=13; tunnels lead to valves CC, AA
|
||||
Valve CC has flow rate=2; tunnels lead to valves DD, BB
|
||||
Valve DD has flow rate=20; tunnels lead to valves CC, AA, EE
|
||||
Valve EE has flow rate=3; tunnels lead to valves FF, DD
|
||||
Valve FF has flow rate=0; tunnels lead to valves EE, GG
|
||||
Valve GG has flow rate=0; tunnels lead to valves FF, HH
|
||||
Valve HH has flow rate=22; tunnel leads to valve GG
|
||||
Valve II has flow rate=0; tunnels lead to valves AA, JJ
|
||||
Valve JJ has flow rate=21; tunnel leads to valve II
|
||||
#+end_example
|
||||
|
||||
All of the valves begin /closed/. You start at valve =AA=, but it must
|
||||
be damaged or jammed or something: its flow rate is =0=, so there's no
|
||||
point in opening it. However, you could spend one minute moving to valve
|
||||
=BB= and another minute opening it; doing so would release pressure
|
||||
during the remaining /28 minutes/ at a flow rate of =13=, a total
|
||||
eventual pressure release of =28 * 13 = 364=. Then, you could spend your
|
||||
third minute moving to valve =CC= and your fourth minute opening it,
|
||||
providing an additional /26 minutes/ of eventual pressure release at a
|
||||
flow rate of =2=, or =52= total pressure released by valve =CC=.
|
||||
|
||||
Making your way through the tunnels like this, you could probably open
|
||||
many or all of the valves by the time 30 minutes have elapsed. However,
|
||||
you need to release as much pressure as possible, so you'll need to be
|
||||
methodical. Instead, consider this approach:
|
||||
|
||||
#+begin_example
|
||||
== Minute 1 ==
|
||||
No valves are open.
|
||||
You move to valve DD.
|
||||
|
||||
== Minute 2 ==
|
||||
No valves are open.
|
||||
You open valve DD.
|
||||
|
||||
== Minute 3 ==
|
||||
Valve DD is open, releasing 20 pressure.
|
||||
You move to valve CC.
|
||||
|
||||
== Minute 4 ==
|
||||
Valve DD is open, releasing 20 pressure.
|
||||
You move to valve BB.
|
||||
|
||||
== Minute 5 ==
|
||||
Valve DD is open, releasing 20 pressure.
|
||||
You open valve BB.
|
||||
|
||||
== Minute 6 ==
|
||||
Valves BB and DD are open, releasing 33 pressure.
|
||||
You move to valve AA.
|
||||
|
||||
== Minute 7 ==
|
||||
Valves BB and DD are open, releasing 33 pressure.
|
||||
You move to valve II.
|
||||
|
||||
== Minute 8 ==
|
||||
Valves BB and DD are open, releasing 33 pressure.
|
||||
You move to valve JJ.
|
||||
|
||||
== Minute 9 ==
|
||||
Valves BB and DD are open, releasing 33 pressure.
|
||||
You open valve JJ.
|
||||
|
||||
== Minute 10 ==
|
||||
Valves BB, DD, and JJ are open, releasing 54 pressure.
|
||||
You move to valve II.
|
||||
|
||||
== Minute 11 ==
|
||||
Valves BB, DD, and JJ are open, releasing 54 pressure.
|
||||
You move to valve AA.
|
||||
|
||||
== Minute 12 ==
|
||||
Valves BB, DD, and JJ are open, releasing 54 pressure.
|
||||
You move to valve DD.
|
||||
|
||||
== Minute 13 ==
|
||||
Valves BB, DD, and JJ are open, releasing 54 pressure.
|
||||
You move to valve EE.
|
||||
|
||||
== Minute 14 ==
|
||||
Valves BB, DD, and JJ are open, releasing 54 pressure.
|
||||
You move to valve FF.
|
||||
|
||||
== Minute 15 ==
|
||||
Valves BB, DD, and JJ are open, releasing 54 pressure.
|
||||
You move to valve GG.
|
||||
|
||||
== Minute 16 ==
|
||||
Valves BB, DD, and JJ are open, releasing 54 pressure.
|
||||
You move to valve HH.
|
||||
|
||||
== Minute 17 ==
|
||||
Valves BB, DD, and JJ are open, releasing 54 pressure.
|
||||
You open valve HH.
|
||||
|
||||
== Minute 18 ==
|
||||
Valves BB, DD, HH, and JJ are open, releasing 76 pressure.
|
||||
You move to valve GG.
|
||||
|
||||
== Minute 19 ==
|
||||
Valves BB, DD, HH, and JJ are open, releasing 76 pressure.
|
||||
You move to valve FF.
|
||||
|
||||
== Minute 20 ==
|
||||
Valves BB, DD, HH, and JJ are open, releasing 76 pressure.
|
||||
You move to valve EE.
|
||||
|
||||
== Minute 21 ==
|
||||
Valves BB, DD, HH, and JJ are open, releasing 76 pressure.
|
||||
You open valve EE.
|
||||
|
||||
== Minute 22 ==
|
||||
Valves BB, DD, EE, HH, and JJ are open, releasing 79 pressure.
|
||||
You move to valve DD.
|
||||
|
||||
== Minute 23 ==
|
||||
Valves BB, DD, EE, HH, and JJ are open, releasing 79 pressure.
|
||||
You move to valve CC.
|
||||
|
||||
== Minute 24 ==
|
||||
Valves BB, DD, EE, HH, and JJ are open, releasing 79 pressure.
|
||||
You open valve CC.
|
||||
|
||||
== Minute 25 ==
|
||||
Valves BB, CC, DD, EE, HH, and JJ are open, releasing 81 pressure.
|
||||
|
||||
== Minute 26 ==
|
||||
Valves BB, CC, DD, EE, HH, and JJ are open, releasing 81 pressure.
|
||||
|
||||
== Minute 27 ==
|
||||
Valves BB, CC, DD, EE, HH, and JJ are open, releasing 81 pressure.
|
||||
|
||||
== Minute 28 ==
|
||||
Valves BB, CC, DD, EE, HH, and JJ are open, releasing 81 pressure.
|
||||
|
||||
== Minute 29 ==
|
||||
Valves BB, CC, DD, EE, HH, and JJ are open, releasing 81 pressure.
|
||||
|
||||
== Minute 30 ==
|
||||
Valves BB, CC, DD, EE, HH, and JJ are open, releasing 81 pressure.
|
||||
#+end_example
|
||||
|
||||
This approach lets you release the most pressure possible in 30 minutes
|
||||
with this valve layout, =1651=.
|
||||
|
||||
Work out the steps to release the most pressure in 30 minutes. /What is
|
||||
the most pressure you can release?/
|
||||
|
||||
Your puzzle answer was =1737=.
|
||||
|
||||
** --- Part Two ---
|
||||
You're worried that even with an optimal approach, the pressure released
|
||||
won't be enough. What if you got one of the elephants to help you?
|
||||
|
||||
It would take you 4 minutes to teach an elephant how to open the right
|
||||
valves in the right order, leaving you with only /26 minutes/ to
|
||||
actually execute your plan. Would having two of you working together be
|
||||
better, even if it means having less time? (Assume that you teach the
|
||||
elephant before opening any valves yourself, giving you both the same
|
||||
full 26 minutes.)
|
||||
|
||||
In the example above, you could teach the elephant to help you as
|
||||
follows:
|
||||
|
||||
#+begin_example
|
||||
== Minute 1 ==
|
||||
No valves are open.
|
||||
You move to valve II.
|
||||
The elephant moves to valve DD.
|
||||
|
||||
== Minute 2 ==
|
||||
No valves are open.
|
||||
You move to valve JJ.
|
||||
The elephant opens valve DD.
|
||||
|
||||
== Minute 3 ==
|
||||
Valve DD is open, releasing 20 pressure.
|
||||
You open valve JJ.
|
||||
The elephant moves to valve EE.
|
||||
|
||||
== Minute 4 ==
|
||||
Valves DD and JJ are open, releasing 41 pressure.
|
||||
You move to valve II.
|
||||
The elephant moves to valve FF.
|
||||
|
||||
== Minute 5 ==
|
||||
Valves DD and JJ are open, releasing 41 pressure.
|
||||
You move to valve AA.
|
||||
The elephant moves to valve GG.
|
||||
|
||||
== Minute 6 ==
|
||||
Valves DD and JJ are open, releasing 41 pressure.
|
||||
You move to valve BB.
|
||||
The elephant moves to valve HH.
|
||||
|
||||
== Minute 7 ==
|
||||
Valves DD and JJ are open, releasing 41 pressure.
|
||||
You open valve BB.
|
||||
The elephant opens valve HH.
|
||||
|
||||
== Minute 8 ==
|
||||
Valves BB, DD, HH, and JJ are open, releasing 76 pressure.
|
||||
You move to valve CC.
|
||||
The elephant moves to valve GG.
|
||||
|
||||
== Minute 9 ==
|
||||
Valves BB, DD, HH, and JJ are open, releasing 76 pressure.
|
||||
You open valve CC.
|
||||
The elephant moves to valve FF.
|
||||
|
||||
== Minute 10 ==
|
||||
Valves BB, CC, DD, HH, and JJ are open, releasing 78 pressure.
|
||||
The elephant moves to valve EE.
|
||||
|
||||
== Minute 11 ==
|
||||
Valves BB, CC, DD, HH, and JJ are open, releasing 78 pressure.
|
||||
The elephant opens valve EE.
|
||||
|
||||
(At this point, all valves are open.)
|
||||
|
||||
== Minute 12 ==
|
||||
Valves BB, CC, DD, EE, HH, and JJ are open, releasing 81 pressure.
|
||||
|
||||
...
|
||||
|
||||
== Minute 20 ==
|
||||
Valves BB, CC, DD, EE, HH, and JJ are open, releasing 81 pressure.
|
||||
|
||||
...
|
||||
|
||||
== Minute 26 ==
|
||||
Valves BB, CC, DD, EE, HH, and JJ are open, releasing 81 pressure.
|
||||
#+end_example
|
||||
|
||||
With the elephant helping, after 26 minutes, the best you could do would
|
||||
release a total of =1707= pressure.
|
||||
|
||||
/With you and an elephant working together for 26 minutes, what is the
|
||||
most pressure you could release?/
|
||||
|
||||
Your puzzle answer was =2216=.
|
||||
|
||||
Both parts of this puzzle are complete! They provide two gold stars: **
|
||||
446
2022/day16/aoc-c.c
Normal file
446
2022/day16/aoc-c.c
Normal file
@@ -0,0 +1,446 @@
|
||||
/* aoc-c.c: Advent of Code 2022, day 16
|
||||
*
|
||||
* Copyright (C) 2023 Bruno Raoult ("br")
|
||||
* Licensed under the GNU General Public License v3.0 or later.
|
||||
* Some rights reserved. See COPYING.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with this
|
||||
* program. If not, see <https://www.gnu.org/licenses/gpl-3.0-standalone.html>.
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later <https://spdx.org/licenses/GPL-3.0-or-later.html>
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "br.h"
|
||||
#include "list.h"
|
||||
#include "pool.h"
|
||||
#include "debug.h"
|
||||
#include "bits.h"
|
||||
|
||||
#include "aoc.h"
|
||||
|
||||
pool_t *pool_valve;
|
||||
|
||||
union val {
|
||||
u32 val;
|
||||
char str[3];
|
||||
};
|
||||
|
||||
enum state {
|
||||
CLOSED,
|
||||
OPENED
|
||||
};
|
||||
|
||||
struct worker {
|
||||
struct valve *pos;
|
||||
int depth;
|
||||
int time;
|
||||
};
|
||||
|
||||
struct valve {
|
||||
int index; /* -1 for zero flow rate */
|
||||
union val val;
|
||||
enum state state;
|
||||
int rate;
|
||||
int evalflow, evaltime;
|
||||
int playedflow, playedtime;
|
||||
struct hlist_node hlist;
|
||||
struct list_head index_sorted;
|
||||
struct list_head flow_sorted;
|
||||
struct list_head eval;
|
||||
int worker;
|
||||
struct list_head played;
|
||||
int ntunnels, tottunnels;
|
||||
struct valve **tunnels; /* array */
|
||||
};
|
||||
|
||||
static struct graph {
|
||||
struct valve *aa; /* head ("AA") */
|
||||
int npositive; /* only "AA" & working valves */
|
||||
int nvalves;
|
||||
u64 opened; /* bitmask of opened valves */
|
||||
u64 openable; /* bitmask of openable valves */
|
||||
struct list_head index_sorted; /* TO REMOVE ? */
|
||||
struct list_head flow_sorted;
|
||||
struct list_head eval;
|
||||
struct list_head played[2];
|
||||
struct valve **indexed_all;
|
||||
int *dist; /* 2-D array */
|
||||
} graph = {
|
||||
.aa = NULL,
|
||||
.npositive = 0,
|
||||
.nvalves = 0,
|
||||
.index_sorted = LIST_HEAD_INIT(graph.index_sorted),
|
||||
.flow_sorted = LIST_HEAD_INIT(graph.flow_sorted),
|
||||
.eval = LIST_HEAD_INIT(graph.eval),
|
||||
.played[0] = LIST_HEAD_INIT(graph.played[0]),
|
||||
.played[1] = LIST_HEAD_INIT(graph.played[1]),
|
||||
.indexed_all = NULL,
|
||||
.dist = NULL
|
||||
};
|
||||
|
||||
#define POS(a, b) ((a)*graph.nvalves + (b))
|
||||
#define DIST(a, b) (graph.dist[POS((a), (b))])
|
||||
|
||||
static void print_valves()
|
||||
{
|
||||
struct valve *cur;
|
||||
printf("**** graph: .head=%p npositive=%d\n", graph.aa, graph.npositive);
|
||||
printf("index1: ");
|
||||
list_for_each_entry(cur, &graph.index_sorted, index_sorted) {
|
||||
printf("%d:%s ", cur->index, cur->val.str);
|
||||
}
|
||||
printf("\n");
|
||||
printf("index2: ");
|
||||
for (int i = 0; i < graph.nvalves; ++i) {
|
||||
printf("%d:%s ", graph.indexed_all[i]->index, graph.indexed_all[i]->val.str);
|
||||
}
|
||||
printf("\n");
|
||||
if (testmode()) {
|
||||
printf("distances:\n ");
|
||||
for (int i = 0; i < graph.nvalves; ++i) {
|
||||
printf(" %s", graph.indexed_all[i]->val.str);
|
||||
}
|
||||
printf("\n");
|
||||
for (int i = 0; i < graph.nvalves; ++i) {
|
||||
printf("%s ", graph.indexed_all[i]->val.str);
|
||||
for (int j = 0; j < graph.nvalves; ++j) {
|
||||
printf("%5d ", DIST(i, j));
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
printf("flow_sorted: ");
|
||||
list_for_each_entry(cur, &graph.flow_sorted, flow_sorted) {
|
||||
printf("%s:%d ", cur->val.str, cur->rate);
|
||||
}
|
||||
printf("\n");
|
||||
printf("openable: %#lx ", graph.openable);
|
||||
int pos, tmp;
|
||||
bit_for_each64_2(pos, tmp, graph.openable) {
|
||||
printf("%d ", pos);
|
||||
}
|
||||
printf("\n");
|
||||
|
||||
|
||||
}
|
||||
|
||||
#define PAD3 log(3, "%*s", _depth * 2, "")
|
||||
#define PAD4 log(4, "%*s", _depth * 2, "")
|
||||
|
||||
/**
|
||||
* eval() - eval possible moves from @flow_sorted list.
|
||||
* @_depth: recursivity depth (for debug only, TODO: remove).
|
||||
* @nworkers: number of workers.
|
||||
* @workers: array of workers.
|
||||
* @pick: max position (in @flow_sorted) to pick moves from (-1 for all).
|
||||
* @pressure: total pressure per time unit so far.
|
||||
*
|
||||
* Find the "best" next move by evaluating only the first @pick elements
|
||||
* in @flow_sorted list.
|
||||
*
|
||||
* @Return: the current position eval.
|
||||
*/
|
||||
static struct valve *eval(int _depth, int nworkers, struct worker *worker, int pick, int pressure)
|
||||
{
|
||||
struct valve *cur, *best = NULL, *sub;
|
||||
struct list_head *list_flow, *tmp;
|
||||
int _pick = pick, val = 0, val1, max = 0, bestworker = -1;
|
||||
int _nworkers = nworkers;
|
||||
if (nworkers == 2 && worker[0].pos->index == worker[1].pos->index)
|
||||
_nworkers = 1;
|
||||
|
||||
PAD3; log_f(3, "EVAL _depth=%d w0={ pos=%d[%s] depth=%d time=%d } w1={ pos=%d[%s] depth=%d time=%d } pick=%d pressure=%d \n",
|
||||
_depth,
|
||||
worker[0].pos->index, worker[0].pos->val.str,
|
||||
worker[0].depth, worker[0].time,
|
||||
worker[1].pos->index, worker[1].pos->val.str,
|
||||
worker[1].depth, worker[1].time,
|
||||
pick, pressure);
|
||||
list_for_each_safe(list_flow, tmp, &graph.flow_sorted) {
|
||||
cur = list_entry(list_flow, struct valve, flow_sorted);
|
||||
//int nworkers = worker[0].pos->index == worker[1].pos->index? 1: 2;
|
||||
if (!--_pick) {
|
||||
PAD4; log(4, "pick exhausted\n");
|
||||
break;
|
||||
}
|
||||
for (int _w = 0; _w < _nworkers; ++_w) {
|
||||
struct worker *w = worker + _w;
|
||||
int d = DIST(w->pos->index, cur->index);
|
||||
int remain = w->time - (d + 1);
|
||||
PAD3; log(3, "worker %d/%d ", _w + 1, nworkers );
|
||||
PAD3; log(3, "dist(%s,%s) = %d ", w->pos->val.str, cur->val.str, d);
|
||||
if (remain < 1) {
|
||||
PAD3; log(4, "time exhausted\n");
|
||||
continue;
|
||||
}
|
||||
val = remain * cur->rate;
|
||||
PAD3; log(3, "--> val=%d\n", val);
|
||||
|
||||
if (w->depth > 0) {
|
||||
struct worker _tmp = *w;
|
||||
w->pos = cur;
|
||||
w->depth--;
|
||||
w->time = remain;
|
||||
/* do not use list_del() here, to preserve prev/next pointers */
|
||||
__list_del_entry(list_flow);
|
||||
sub = eval(_depth + 1, nworkers, worker, pick, pressure + w->pos->rate);
|
||||
list_flow->prev->next = list_flow;
|
||||
list_flow->next->prev = list_flow;
|
||||
*w = _tmp;
|
||||
} else {
|
||||
sub = NULL;
|
||||
}
|
||||
val1 = sub? sub->evalflow: 0;
|
||||
PAD3; log(3, "eval3(%s->%s)= %5d = %d + %d", w->pos->val.str, cur->val.str,
|
||||
val+val1, val, val1);
|
||||
if (val + val1 > max) {
|
||||
max = val + val1;
|
||||
best = cur;
|
||||
bestworker = _w;
|
||||
log(3, " NEW MAX !");
|
||||
}
|
||||
log(3, "\n");
|
||||
}
|
||||
}
|
||||
if (best) {
|
||||
best->evalflow = max;
|
||||
best->worker = bestworker; /* FIXME */
|
||||
PAD3; log(3, "EVAL returning best [%s] worker=%d eval=%d\n", best->val.str,
|
||||
best->worker, max);
|
||||
}
|
||||
return best;
|
||||
}
|
||||
|
||||
static struct valve *find_valve(union val val, int ntunnels, int rate)
|
||||
{
|
||||
struct valve *cur;
|
||||
|
||||
log_f(3, "val=%s ntunnels=%d rate=%d\n", val.str, ntunnels, rate);
|
||||
list_for_each_entry(cur, &graph.index_sorted, index_sorted) {
|
||||
//log(3, "\tcomparing with found, addr=%p\n", cur);
|
||||
if (cur->val.val == val.val) {
|
||||
log(3, "\tfound, addr=%p\n", cur);
|
||||
if (ntunnels)
|
||||
goto init;
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
cur = pool_get(pool_valve);
|
||||
cur->val.val = val.val;
|
||||
cur->ntunnels = 0;
|
||||
cur->state = CLOSED;
|
||||
cur->worker = -1;
|
||||
cur->evalflow = cur->playedflow = 0;
|
||||
cur->evaltime = cur->playedtime = 30;
|
||||
INIT_LIST_HEAD(&cur->index_sorted);
|
||||
INIT_LIST_HEAD(&cur->flow_sorted);
|
||||
INIT_LIST_HEAD(&cur->eval);
|
||||
INIT_LIST_HEAD(&cur->played);
|
||||
log(3, "\talloc new, addr=%p\n", cur);
|
||||
init:
|
||||
if (ntunnels) {
|
||||
cur->rate = rate;
|
||||
cur->tottunnels = ntunnels;
|
||||
cur->tunnels = calloc(ntunnels, sizeof(struct valve *));
|
||||
}
|
||||
end:
|
||||
return cur;
|
||||
}
|
||||
|
||||
/**
|
||||
* nthtok - get nth token fron string.
|
||||
* @buf: buffer to parse.
|
||||
* @sep: separators string.
|
||||
* @n: token number (0: first token).
|
||||
*
|
||||
* @Return: pointer to token.
|
||||
*/
|
||||
static char *nthtok(char *buf, const char *sep, int n)
|
||||
{
|
||||
char *ret;
|
||||
for (; n >= 0; n--) {
|
||||
ret = strtok(buf, sep);
|
||||
buf = NULL;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
#define SEP " ,;="
|
||||
static struct graph *parse()
|
||||
{
|
||||
int index = 0, ntunnels;
|
||||
size_t alloc = 0;
|
||||
ssize_t buflen;
|
||||
char *buf = NULL, *tok;
|
||||
int rate;
|
||||
struct valve *v1, *v2;
|
||||
union val cur, link;
|
||||
|
||||
while ((buflen = getline(&buf, &alloc, stdin)) > 0) {
|
||||
buf[--buflen] = 0;
|
||||
/* valve name */
|
||||
strncpy(cur.str, nthtok(buf, SEP, 1), sizeof(cur.str));
|
||||
|
||||
//printf("valve=%s ", tok);
|
||||
rate = atoi(nthtok(NULL, SEP, 3));
|
||||
//printf("rate=%s ", tok);
|
||||
tok = nthtok(NULL, SEP, 4);
|
||||
ntunnels = (buf + buflen - tok) / 4 + 1;
|
||||
v1 = find_valve(cur, ntunnels, rate);
|
||||
v1->index = index++;
|
||||
// TODO: remove this list ?
|
||||
list_add_tail(&v1->index_sorted, &graph.index_sorted);
|
||||
graph.nvalves++;
|
||||
//if (rate || v1->val.val == ('A' << 8 | 'A')) {
|
||||
if (rate) {
|
||||
struct valve *cur;
|
||||
graph.npositive++;
|
||||
/* keep this list sorted by flow decrasing */
|
||||
list_for_each_entry(cur, &graph.flow_sorted, flow_sorted) {
|
||||
if (rate > cur->rate) {
|
||||
list_add_tail(&v1->flow_sorted, &cur->flow_sorted);
|
||||
goto inserted;
|
||||
}
|
||||
}
|
||||
list_add_tail(&v1->flow_sorted, &graph.flow_sorted);
|
||||
inserted: ;
|
||||
if (rate) {
|
||||
//printf("adjust openable(%d): %#lx", v1->index, graph.openable);
|
||||
graph.openable |= (1 << v1->index);
|
||||
//printf("->%#lx", graph.openable);
|
||||
}
|
||||
}
|
||||
//printf("lead=%s ntunnels=%d ", tok, ntunnels);
|
||||
do {
|
||||
link.val = *(u16 *)tok;
|
||||
v2 = find_valve(link, 0, 0);
|
||||
*(v1->tunnels + v1->ntunnels++) = v2;
|
||||
//printf(",%s", tok);
|
||||
} while ((tok = nthtok(NULL, SEP, 0)));
|
||||
//printf("\n");
|
||||
}
|
||||
graph.aa = find_valve((union val) { .str="AA" }, 0, 0);
|
||||
/* build array of indexed valves */
|
||||
graph.indexed_all = calloc(graph.nvalves, sizeof(struct valve *));
|
||||
list_for_each_entry(v1, &graph.index_sorted, index_sorted) {
|
||||
graph.indexed_all[v1->index] = v1;
|
||||
}
|
||||
return &graph;
|
||||
}
|
||||
|
||||
static int is_neighbour(int i, int j)
|
||||
{
|
||||
struct valve *v1 = graph.indexed_all[i], *v2 = graph.indexed_all[j];
|
||||
for (int i = 0; i < v1->ntunnels; ++i)
|
||||
if (v1->tunnels[i]->val.val == v2->val.val)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void build_distances()
|
||||
{
|
||||
int i, j, k;
|
||||
graph.dist = calloc(graph.nvalves * graph.nvalves, sizeof(int));
|
||||
/* initialize values */
|
||||
for (i = 0; i < graph.nvalves; ++i) {
|
||||
for (j = 1; j < graph.nvalves; ++j) {
|
||||
if (i != j) {
|
||||
if (is_neighbour(i, j))
|
||||
DIST(i, j) = DIST(j, i) = 1;
|
||||
else
|
||||
DIST(i, j) = DIST(j, i) = 10000;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* get all distances using Floyd-Warshall
|
||||
* see https://en.wikipedia.org/wiki/Floyd%E2%80%93Warshall_algorithm
|
||||
*
|
||||
* Add all vertices one by one to the set of intermediate vertices.
|
||||
* ---> Before start of an iteration, we have shortest distances between all
|
||||
* pairs of vertices such that the shortest distances consider only the
|
||||
* vertices in set {0, 1, 2, .. k-1} as intermediate vertices.
|
||||
* ----> After the end of an iteration, vertex no. k is added to the set of
|
||||
* intermediate vertices and the set becomes {0, 1, 2, .. k}
|
||||
*/
|
||||
for (k = 0; k < graph.nvalves; k++) {
|
||||
/* Pick all vertices as source one by one */
|
||||
for (i = 0; i < graph.nvalves; i++) {
|
||||
/* Pick all vertices as destination for the above picked source */
|
||||
for (j = i + 1; j < graph.nvalves; j++)
|
||||
DIST(i, j) = DIST(j, i) = min(DIST(i, j), DIST(i, k) + DIST(k, j));
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
static void print_played(int nworkers)
|
||||
{
|
||||
struct valve *p;
|
||||
int total = 0;
|
||||
for (int w = 0; w < nworkers; ++w) {
|
||||
int remain = 26, i = 1;
|
||||
struct valve *prev = graph.aa;
|
||||
i = 1;
|
||||
printf("played by %d/%d:\n", w + 1, nworkers);
|
||||
list_for_each_entry(p, &graph.played[w], played) {
|
||||
printf("%2d: %s, ", i, p->val.str);
|
||||
remain -= DIST(p->index, prev->index) + 1;
|
||||
total += p->rate * remain;
|
||||
printf("dist=%d remain=%d total=%d", DIST(p->index, prev->index), remain,
|
||||
total);
|
||||
printf("\n");
|
||||
i++;
|
||||
prev = p;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int doit(int part)
|
||||
{
|
||||
struct worker w[2];
|
||||
struct valve *best;
|
||||
int res = 0;
|
||||
//int topick = part == 1? 7: 12;
|
||||
int topick = part == 1? 12: 12;
|
||||
|
||||
w[0].pos = w[1].pos = graph.aa;
|
||||
//w[0].depth = w[1].depth = part == 1? 7: 4;
|
||||
w[0].depth = w[1].depth = part == 1? 4: 4;
|
||||
w[0].time = w[1].time = part == 1? 30: 26;
|
||||
|
||||
while ((best = eval(0, part, w, topick, 0))) {
|
||||
list_del(&best->flow_sorted);
|
||||
list_add_tail(&best->played, &graph.played[best->worker]);
|
||||
w[best->worker].time -= DIST(w[best->worker].pos->index, best->index) + 1;
|
||||
w[best->worker].pos = best;
|
||||
res += best->rate * w[best->worker].time;
|
||||
print_played(part);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
static ulong part1()
|
||||
{
|
||||
return doit(1);
|
||||
}
|
||||
|
||||
static ulong part2()
|
||||
{
|
||||
return doit(2);
|
||||
}
|
||||
|
||||
int main(int ac, char **av)
|
||||
{
|
||||
int part = parseargs(ac, av);
|
||||
pool_valve = pool_create("valve", 512, sizeof(struct valve));
|
||||
parse();
|
||||
build_distances();
|
||||
print_valves();
|
||||
printf("%s: res=%lu\n", *av, part == 1? part1(): part2());
|
||||
exit(0);
|
||||
}
|
||||
17
2022/day16/aoc.h
Normal file
17
2022/day16/aoc.h
Normal file
@@ -0,0 +1,17 @@
|
||||
/* aoc.c: Advent of Code 2022
|
||||
*
|
||||
* Copyright (C) 2022-2023 Bruno Raoult ("br")
|
||||
* Licensed under the GNU General Public License v3.0 or later.
|
||||
* Some rights reserved. See COPYING.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with this
|
||||
* program. If not, see <https://www.gnu.org/licenses/gpl-3.0-standalone.html>.
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later <https://spdx.org/licenses/GPL-3.0-or-later.html>
|
||||
*/
|
||||
#ifndef _AOC_H_
|
||||
#define _AOC_H_
|
||||
|
||||
extern int parseargs(int ac, char**av);
|
||||
extern int testmode(void);
|
||||
#endif /* _AOC_H_ */
|
||||
68
2022/day16/common.bash
Normal file
68
2022/day16/common.bash
Normal file
@@ -0,0 +1,68 @@
|
||||
#!/usr/bin/env bash
|
||||
#
|
||||
# common.bash: Advent of Code 2022, common bash functions
|
||||
#
|
||||
# Copyright (C) 2022-2023 Bruno Raoult ("br")
|
||||
# Licensed under the GNU General Public License v3.0 or later.
|
||||
# Some rights reserved. See COPYING.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License along with this
|
||||
# program. If not, see <https://www.gnu.org/licenses/gpl-3.0-standalone.html>.
|
||||
#
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later <https://spdx.org/licenses/GPL-3.0-or-later.html>
|
||||
|
||||
# shellcheck disable=2034
|
||||
export cmdname=${0##*/}
|
||||
export debug=0
|
||||
export res
|
||||
export LANG=C
|
||||
|
||||
shopt -s extglob
|
||||
set -o noglob
|
||||
|
||||
usage() {
|
||||
printf "usage: %s [-d DEBUG] [-p PART]\n" "$cmdname"
|
||||
exit 1
|
||||
}
|
||||
|
||||
checkargs() {
|
||||
local part=1
|
||||
while getopts p:d: todo; do
|
||||
case "$todo" in
|
||||
d)
|
||||
if [[ "$OPTARG" =~ ^[[:digit:]+]$ ]]; then
|
||||
debug="$OPTARG"
|
||||
else
|
||||
printf "%s: illegal [%s] debug level.\n" "$CMD" "$OPTARG"
|
||||
exit 1
|
||||
fi
|
||||
;;
|
||||
p)
|
||||
if [[ "$OPTARG" =~ ^[12]$ ]]; then
|
||||
part="$OPTARG"
|
||||
else
|
||||
printf "%s: illegal [%s] part.\n" "$CMD" "$OPTARG"
|
||||
exit 1
|
||||
fi
|
||||
;;
|
||||
*)
|
||||
usage
|
||||
;;
|
||||
esac
|
||||
done
|
||||
# Now check remaining argument (backup directory)
|
||||
shift $((OPTIND - 1))
|
||||
|
||||
(( $# > 1 )) && usage
|
||||
return "$part"
|
||||
}
|
||||
|
||||
main() {
|
||||
local -i part
|
||||
|
||||
checkargs "$@"
|
||||
part=$?
|
||||
parse "$part"
|
||||
solve "$part"
|
||||
printf "%s: res=%s\n" "$cmdname" "$res"
|
||||
}
|
||||
59
2022/day16/common.c
Normal file
59
2022/day16/common.c
Normal file
@@ -0,0 +1,59 @@
|
||||
/* common.c: Advent of Code 2022, common functions
|
||||
*
|
||||
* Copyright (C) 2022-2023 Bruno Raoult ("br")
|
||||
* Licensed under the GNU General Public License v3.0 or later.
|
||||
* Some rights reserved. See COPYING.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with this
|
||||
* program. If not, see <https://www.gnu.org/licenses/gpl-3.0-standalone.html>.
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later <https://spdx.org/licenses/GPL-3.0-or-later.html>
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "aoc.h"
|
||||
#include "debug.h"
|
||||
|
||||
static int _testmode = 0;
|
||||
|
||||
static int usage(char *prg)
|
||||
{
|
||||
fprintf(stderr, "Usage: %s [-t][-d debug_level] [-p part] [-i input]\n", prg);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int testmode(void)
|
||||
{
|
||||
return _testmode;
|
||||
}
|
||||
|
||||
int parseargs(int ac, char **av)
|
||||
{
|
||||
int opt, part = 1;
|
||||
|
||||
while ((opt = getopt(ac, av, "td:p:")) != -1) {
|
||||
switch (opt) {
|
||||
case 't':
|
||||
_testmode = 1;
|
||||
break;
|
||||
case 'd':
|
||||
debug_level_set(atoi(optarg));
|
||||
break;
|
||||
case 'p': /* 1 or 2 */
|
||||
part = atoi(optarg);
|
||||
if (part < 1 || part > 2)
|
||||
return usage(*av);
|
||||
break;
|
||||
case 'i':
|
||||
|
||||
default:
|
||||
return usage(*av);
|
||||
}
|
||||
}
|
||||
if (optind < ac)
|
||||
return usage(*av);
|
||||
return part;
|
||||
}
|
||||
10
2022/day16/input/example.txt
Normal file
10
2022/day16/input/example.txt
Normal file
@@ -0,0 +1,10 @@
|
||||
Valve AA has flow rate=0; tunnels lead to valves DD, II, BB
|
||||
Valve BB has flow rate=13; tunnels lead to valves CC, AA
|
||||
Valve CC has flow rate=2; tunnels lead to valves DD, BB
|
||||
Valve DD has flow rate=20; tunnels lead to valves CC, AA, EE
|
||||
Valve EE has flow rate=3; tunnels lead to valves FF, DD
|
||||
Valve FF has flow rate=0; tunnels lead to valves EE, GG
|
||||
Valve GG has flow rate=0; tunnels lead to valves FF, HH
|
||||
Valve HH has flow rate=22; tunnel leads to valve GG
|
||||
Valve II has flow rate=0; tunnels lead to valves AA, JJ
|
||||
Valve JJ has flow rate=21; tunnel leads to valve II
|
||||
54
2022/day16/input/input.txt
Normal file
54
2022/day16/input/input.txt
Normal file
@@ -0,0 +1,54 @@
|
||||
Valve EJ has flow rate=25; tunnel leads to valve MC
|
||||
Valve WC has flow rate=0; tunnels lead to valves OW, RU
|
||||
Valve NP has flow rate=0; tunnels lead to valves VR, KL
|
||||
Valve AA has flow rate=0; tunnels lead to valves QT, AP, EZ, AK, XV
|
||||
Valve VO has flow rate=6; tunnels lead to valves KM, RF, HS, LJ, IA
|
||||
Valve CB has flow rate=0; tunnels lead to valves UI, UP
|
||||
Valve TE has flow rate=18; tunnel leads to valve JT
|
||||
Valve CZ has flow rate=0; tunnels lead to valves UP, OW
|
||||
Valve LJ has flow rate=0; tunnels lead to valves DV, VO
|
||||
Valve UP has flow rate=7; tunnels lead to valves SK, CB, CZ
|
||||
Valve FP has flow rate=0; tunnels lead to valves OW, RE
|
||||
Valve KM has flow rate=0; tunnels lead to valves SE, VO
|
||||
Valve DV has flow rate=0; tunnels lead to valves LJ, UM
|
||||
Valve FL has flow rate=0; tunnels lead to valves AH, TS
|
||||
Valve VR has flow rate=24; tunnels lead to valves DM, TF, NP
|
||||
Valve IA has flow rate=0; tunnels lead to valves VS, VO
|
||||
Valve RF has flow rate=0; tunnels lead to valves VO, JF
|
||||
Valve RT has flow rate=0; tunnels lead to valves UM, SE
|
||||
Valve RU has flow rate=0; tunnels lead to valves AR, WC
|
||||
Valve SE has flow rate=4; tunnels lead to valves GU, KM, CX, RT
|
||||
Valve MC has flow rate=0; tunnels lead to valves EJ, AR
|
||||
Valve TF has flow rate=0; tunnels lead to valves AH, VR
|
||||
Valve CX has flow rate=0; tunnels lead to valves SE, TO
|
||||
Valve GL has flow rate=11; tunnels lead to valves UY, KL, CY
|
||||
Valve GU has flow rate=0; tunnels lead to valves SE, EZ
|
||||
Valve VS has flow rate=0; tunnels lead to valves XN, IA
|
||||
Valve EZ has flow rate=0; tunnels lead to valves AA, GU
|
||||
Valve GK has flow rate=0; tunnels lead to valves FI, HZ
|
||||
Valve JT has flow rate=0; tunnels lead to valves TE, XN
|
||||
Valve DM has flow rate=0; tunnels lead to valves VR, HZ
|
||||
Valve AR has flow rate=16; tunnels lead to valves UI, RU, MC
|
||||
Valve XN has flow rate=9; tunnels lead to valves XP, JT, VS, GT, CY
|
||||
Valve CY has flow rate=0; tunnels lead to valves XN, GL
|
||||
Valve QT has flow rate=0; tunnels lead to valves UM, AA
|
||||
Valve KL has flow rate=0; tunnels lead to valves GL, NP
|
||||
Valve SK has flow rate=0; tunnels lead to valves XV, UP
|
||||
Valve OW has flow rate=12; tunnels lead to valves CZ, WC, FP
|
||||
Valve AK has flow rate=0; tunnels lead to valves AA, HS
|
||||
Valve XV has flow rate=0; tunnels lead to valves AA, SK
|
||||
Valve GT has flow rate=0; tunnels lead to valves XN, UM
|
||||
Valve FI has flow rate=0; tunnels lead to valves JF, GK
|
||||
Valve UY has flow rate=0; tunnels lead to valves JF, GL
|
||||
Valve UM has flow rate=5; tunnels lead to valves DV, GT, RT, QT
|
||||
Valve IQ has flow rate=0; tunnels lead to valves HZ, AH
|
||||
Valve JF has flow rate=10; tunnels lead to valves RF, FI, UY, RE, TS
|
||||
Valve TS has flow rate=0; tunnels lead to valves JF, FL
|
||||
Valve AH has flow rate=23; tunnels lead to valves IQ, FL, TF
|
||||
Valve HS has flow rate=0; tunnels lead to valves AK, VO
|
||||
Valve HZ has flow rate=20; tunnels lead to valves IQ, DM, GK
|
||||
Valve TO has flow rate=15; tunnel leads to valve CX
|
||||
Valve XP has flow rate=0; tunnels lead to valves AP, XN
|
||||
Valve AP has flow rate=0; tunnels lead to valves XP, AA
|
||||
Valve RE has flow rate=0; tunnels lead to valves JF, FP
|
||||
Valve UI has flow rate=0; tunnels lead to valves AR, CB
|
||||
111
2022/day17/Makefile
Normal file
111
2022/day17/Makefile
Normal file
@@ -0,0 +1,111 @@
|
||||
# AOC daily Makefile - GNU make only.
|
||||
#
|
||||
# Copyright (C) 2021-2023 Bruno Raoult ("br")
|
||||
# Licensed under the GNU General Public License v3.0 or later.
|
||||
# Some rights reserved. See COPYING.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License along with this
|
||||
# program. If not, see <https://www.gnu.org/licenses/gpl-3.0-standalone.html>.
|
||||
#
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later <https://spdx.org/licenses/GPL-3.0-or-later.html>
|
||||
#
|
||||
|
||||
INPUT := input/input.txt
|
||||
SHELL := /bin/bash
|
||||
|
||||
CC := gcc
|
||||
BEAR := bear
|
||||
CCLSFILE:= compile_commands.json
|
||||
|
||||
LIB := aoc_$(shell uname -m)
|
||||
INCDIR := ../include
|
||||
LIBDIR := ../lib
|
||||
LDFLAGS := -L$(LIBDIR)
|
||||
#LDLIB := -l$(LIB) -lm
|
||||
LDLIB := -l$(LIB)
|
||||
|
||||
export LD_LIBRARY_PATH = $(LIBDIR)
|
||||
|
||||
CFLAGS += -std=gnu11
|
||||
CFLAGS += -O2
|
||||
CFLAGS += -g
|
||||
# for gprof
|
||||
# CFLAGS += -pg
|
||||
CFLAGS += -Wall
|
||||
CFLAGS += -Wextra
|
||||
CFLAGS += -march=native
|
||||
# Next one may be useful for valgrind (some invalid instructions)
|
||||
# CFLAGS += -mno-tbm
|
||||
CFLAGS += -Wmissing-declarations
|
||||
CFLAGS += -Wno-unused-result
|
||||
|
||||
CFLAGS += -DDEBUG_DEBUG # activate general debug (debug.c)
|
||||
CFLAGS += -DDEBUG_POOL # memory pools management
|
||||
|
||||
VALGRIND := valgrind
|
||||
VALGRINDFLAGS := --leak-check=full --show-leak-kinds=all --track-origins=yes \
|
||||
--sigill-diagnostics=yes --quiet --show-error-list=yes
|
||||
|
||||
|
||||
TIME := \time -f "\ttime: %E real, %U user, %S sys\n\tcontext-switch:\t%c+%w, page-faults: %F+%R\n"
|
||||
export PATH := .:$(PATH)
|
||||
|
||||
.PHONY: clean all compile assembly memcheck memcheck1 memcheck2 part1 part2 ccls bear org
|
||||
|
||||
all: README.org ccls part1 part2
|
||||
|
||||
memcheck: memcheck1 memcheck2
|
||||
|
||||
memcheck1: aoc-c
|
||||
@$(VALGRIND) $(VALGRINDFLAGS) aoc-c -p 1 < $(INPUT)
|
||||
|
||||
memcheck2: aoc-c
|
||||
@$(VALGRIND) $(VALGRINDFLAGS) aoc-c -p 2 < $(INPUT)
|
||||
@#@valgrind -s --track-origins=yes aoc-c -p 2 < $(INPUT)
|
||||
|
||||
compile: aoc-c
|
||||
|
||||
cpp: aoc-c.i
|
||||
|
||||
assembly: aoc-c.s
|
||||
|
||||
part1: aoc-c
|
||||
@#$(TIME) aoc.bash -p 1 < $(INPUT) 2>&1
|
||||
@$(TIME) aoc-c -p 1 < $(INPUT)
|
||||
|
||||
part2: aoc-c
|
||||
@#$(TIME) aoc.bash -p 2 < $(INPUT) 2>&1
|
||||
@$(TIME) aoc-c -p 2 < $(INPUT)
|
||||
|
||||
ccls: $(CCLSFILE)
|
||||
|
||||
clean:
|
||||
@rm -f aoc-c core* vgcore* gmon.out aoc-c.s aoc-c.i README.html compile_commands.json
|
||||
|
||||
aoc-c: aoc-c.c common.c
|
||||
@echo compiling $<
|
||||
$(CC) $(CFLAGS) $(LDFLAGS) -I $(INCDIR) $^ $(LDLIB) -o $@
|
||||
|
||||
# generate pre-processed file (.i) and assembler (.s)
|
||||
%.i: %.c
|
||||
@echo generating $@
|
||||
@$(CC) -E $(CFLAGS) -I $(INCDIR) $< -o $@
|
||||
|
||||
%.s: %.c
|
||||
@echo generating $@
|
||||
@$(CC) -S -fverbose-asm $(CFLAGS) -I $(INCDIR) $< -o $@
|
||||
|
||||
# generate README.org from README.html (must cleanup !)
|
||||
org: README.org
|
||||
|
||||
%.org: %.html
|
||||
@echo generating $@. Cleanup before commit !
|
||||
@pandoc $< -o $@
|
||||
|
||||
# generate compile_commands.json
|
||||
$(CCLSFILE): aoc-c.c Makefile
|
||||
$(BEAR) -- make clean compile
|
||||
|
||||
bear: clean
|
||||
@touch .ccls-root
|
||||
@$(BEAR) -- make compile
|
||||
374
2022/day17/README.org
Normal file
374
2022/day17/README.org
Normal file
@@ -0,0 +1,374 @@
|
||||
** --- Day 17: Pyroclastic Flow ---
|
||||
Your handheld device has located an alternative exit from the cave for
|
||||
you and the elephants. The ground is rumbling almost continuously now,
|
||||
but the strange valves bought you some time. It's definitely getting
|
||||
warmer in here, though.
|
||||
|
||||
The tunnels eventually open into a very tall, narrow chamber. Large,
|
||||
oddly-shaped rocks are falling into the chamber from above, presumably
|
||||
due to all the rumbling. If you can't work out where the rocks will fall
|
||||
next, you might be crushed!
|
||||
|
||||
The five types of rocks have the following peculiar shapes, where =#= is
|
||||
rock and =.= is empty space:
|
||||
|
||||
#+begin_example
|
||||
####
|
||||
|
||||
.#.
|
||||
###
|
||||
.#.
|
||||
|
||||
..#
|
||||
..#
|
||||
###
|
||||
|
||||
#
|
||||
#
|
||||
#
|
||||
#
|
||||
|
||||
##
|
||||
##
|
||||
#+end_example
|
||||
|
||||
The rocks fall in the order shown above: first the =-= shape, then the
|
||||
=+= shape, and so on. Once the end of the list is reached, the same
|
||||
order repeats: the =-= shape falls first, sixth, 11th, 16th, etc.
|
||||
|
||||
The rocks don't spin, but they do get pushed around by jets of hot gas
|
||||
coming out of the walls themselves. A quick scan reveals the effect the
|
||||
jets of hot gas will have on the rocks as they fall (your puzzle input).
|
||||
|
||||
For example, suppose this was the jet pattern in your cave:
|
||||
|
||||
#+begin_example
|
||||
>>><<><>><<<>><>>><<<>>><<<><<<>><>><<>>
|
||||
#+end_example
|
||||
|
||||
In jet patterns, =<= means a push to the left, while =>= means a push to
|
||||
the right. The pattern above means that the jets will push a falling
|
||||
rock right, then right, then right, then left, then left, then right,
|
||||
and so on. If the end of the list is reached, it repeats.
|
||||
|
||||
The tall, vertical chamber is exactly /seven units wide/. Each rock
|
||||
appears so that its left edge is two units away from the left wall and
|
||||
its bottom edge is three units above the highest rock in the room (or
|
||||
the floor, if there isn't one).
|
||||
|
||||
After a rock appears, it alternates between /being pushed by a jet of
|
||||
hot gas/ one unit (in the direction indicated by the next symbol in the
|
||||
jet pattern) and then /falling one unit down/. If any movement would
|
||||
cause any part of the rock to move into the walls, floor, or a stopped
|
||||
rock, the movement instead does not occur. If a /downward/ movement
|
||||
would have caused a falling rock to move into the floor or an
|
||||
already-fallen rock, the falling rock stops where it is (having landed
|
||||
on something) and a new rock immediately begins falling.
|
||||
|
||||
Drawing falling rocks with =@= and stopped rocks with =#=, the jet
|
||||
pattern in the example above manifests as follows:
|
||||
|
||||
#+begin_example
|
||||
The first rock begins falling:
|
||||
|..@@@@.|
|
||||
|.......|
|
||||
|.......|
|
||||
|.......|
|
||||
+-------+
|
||||
|
||||
Jet of gas pushes rock right:
|
||||
|...@@@@|
|
||||
|.......|
|
||||
|.......|
|
||||
|.......|
|
||||
+-------+
|
||||
|
||||
Rock falls 1 unit:
|
||||
|...@@@@|
|
||||
|.......|
|
||||
|.......|
|
||||
+-------+
|
||||
|
||||
Jet of gas pushes rock right, but nothing happens:
|
||||
|...@@@@|
|
||||
|.......|
|
||||
|.......|
|
||||
+-------+
|
||||
|
||||
Rock falls 1 unit:
|
||||
|...@@@@|
|
||||
|.......|
|
||||
+-------+
|
||||
|
||||
Jet of gas pushes rock right, but nothing happens:
|
||||
|...@@@@|
|
||||
|.......|
|
||||
+-------+
|
||||
|
||||
Rock falls 1 unit:
|
||||
|...@@@@|
|
||||
+-------+
|
||||
|
||||
Jet of gas pushes rock left:
|
||||
|..@@@@.|
|
||||
+-------+
|
||||
|
||||
Rock falls 1 unit, causing it to come to rest:
|
||||
|..####.|
|
||||
+-------+
|
||||
|
||||
A new rock begins falling:
|
||||
|...@...|
|
||||
|..@@@..|
|
||||
|...@...|
|
||||
|.......|
|
||||
|.......|
|
||||
|.......|
|
||||
|..####.|
|
||||
+-------+
|
||||
|
||||
Jet of gas pushes rock left:
|
||||
|..@....|
|
||||
|.@@@...|
|
||||
|..@....|
|
||||
|.......|
|
||||
|.......|
|
||||
|.......|
|
||||
|..####.|
|
||||
+-------+
|
||||
|
||||
Rock falls 1 unit:
|
||||
|..@....|
|
||||
|.@@@...|
|
||||
|..@....|
|
||||
|.......|
|
||||
|.......|
|
||||
|..####.|
|
||||
+-------+
|
||||
|
||||
Jet of gas pushes rock right:
|
||||
|...@...|
|
||||
|..@@@..|
|
||||
|...@...|
|
||||
|.......|
|
||||
|.......|
|
||||
|..####.|
|
||||
+-------+
|
||||
|
||||
Rock falls 1 unit:
|
||||
|...@...|
|
||||
|..@@@..|
|
||||
|...@...|
|
||||
|.......|
|
||||
|..####.|
|
||||
+-------+
|
||||
|
||||
Jet of gas pushes rock left:
|
||||
|..@....|
|
||||
|.@@@...|
|
||||
|..@....|
|
||||
|.......|
|
||||
|..####.|
|
||||
+-------+
|
||||
|
||||
Rock falls 1 unit:
|
||||
|..@....|
|
||||
|.@@@...|
|
||||
|..@....|
|
||||
|..####.|
|
||||
+-------+
|
||||
|
||||
Jet of gas pushes rock right:
|
||||
|...@...|
|
||||
|..@@@..|
|
||||
|...@...|
|
||||
|..####.|
|
||||
+-------+
|
||||
|
||||
Rock falls 1 unit, causing it to come to rest:
|
||||
|...#...|
|
||||
|..###..|
|
||||
|...#...|
|
||||
|..####.|
|
||||
+-------+
|
||||
|
||||
A new rock begins falling:
|
||||
|....@..|
|
||||
|....@..|
|
||||
|..@@@..|
|
||||
|.......|
|
||||
|.......|
|
||||
|.......|
|
||||
|...#...|
|
||||
|..###..|
|
||||
|...#...|
|
||||
|..####.|
|
||||
+-------+
|
||||
#+end_example
|
||||
|
||||
The moment each of the next few rocks begins falling, you would see
|
||||
this:
|
||||
|
||||
#+begin_example
|
||||
|..@....|
|
||||
|..@....|
|
||||
|..@....|
|
||||
|..@....|
|
||||
|.......|
|
||||
|.......|
|
||||
|.......|
|
||||
|..#....|
|
||||
|..#....|
|
||||
|####...|
|
||||
|..###..|
|
||||
|...#...|
|
||||
|..####.|
|
||||
+-------+
|
||||
|
||||
|..@@...|
|
||||
|..@@...|
|
||||
|.......|
|
||||
|.......|
|
||||
|.......|
|
||||
|....#..|
|
||||
|..#.#..|
|
||||
|..#.#..|
|
||||
|#####..|
|
||||
|..###..|
|
||||
|...#...|
|
||||
|..####.|
|
||||
+-------+
|
||||
|
||||
|..@@@@.|
|
||||
|.......|
|
||||
|.......|
|
||||
|.......|
|
||||
|....##.|
|
||||
|....##.|
|
||||
|....#..|
|
||||
|..#.#..|
|
||||
|..#.#..|
|
||||
|#####..|
|
||||
|..###..|
|
||||
|...#...|
|
||||
|..####.|
|
||||
+-------+
|
||||
|
||||
|...@...|
|
||||
|..@@@..|
|
||||
|...@...|
|
||||
|.......|
|
||||
|.......|
|
||||
|.......|
|
||||
|.####..|
|
||||
|....##.|
|
||||
|....##.|
|
||||
|....#..|
|
||||
|..#.#..|
|
||||
|..#.#..|
|
||||
|#####..|
|
||||
|..###..|
|
||||
|...#...|
|
||||
|..####.|
|
||||
+-------+
|
||||
|
||||
|....@..|
|
||||
|....@..|
|
||||
|..@@@..|
|
||||
|.......|
|
||||
|.......|
|
||||
|.......|
|
||||
|..#....|
|
||||
|.###...|
|
||||
|..#....|
|
||||
|.####..|
|
||||
|....##.|
|
||||
|....##.|
|
||||
|....#..|
|
||||
|..#.#..|
|
||||
|..#.#..|
|
||||
|#####..|
|
||||
|..###..|
|
||||
|...#...|
|
||||
|..####.|
|
||||
+-------+
|
||||
|
||||
|..@....|
|
||||
|..@....|
|
||||
|..@....|
|
||||
|..@....|
|
||||
|.......|
|
||||
|.......|
|
||||
|.......|
|
||||
|.....#.|
|
||||
|.....#.|
|
||||
|..####.|
|
||||
|.###...|
|
||||
|..#....|
|
||||
|.####..|
|
||||
|....##.|
|
||||
|....##.|
|
||||
|....#..|
|
||||
|..#.#..|
|
||||
|..#.#..|
|
||||
|#####..|
|
||||
|..###..|
|
||||
|...#...|
|
||||
|..####.|
|
||||
+-------+
|
||||
|
||||
|..@@...|
|
||||
|..@@...|
|
||||
|.......|
|
||||
|.......|
|
||||
|.......|
|
||||
|....#..|
|
||||
|....#..|
|
||||
|....##.|
|
||||
|....##.|
|
||||
|..####.|
|
||||
|.###...|
|
||||
|..#....|
|
||||
|.####..|
|
||||
|....##.|
|
||||
|....##.|
|
||||
|....#..|
|
||||
|..#.#..|
|
||||
|..#.#..|
|
||||
|#####..|
|
||||
|..###..|
|
||||
|...#...|
|
||||
|..####.|
|
||||
+-------+
|
||||
|
||||
|..@@@@.|
|
||||
|.......|
|
||||
|.......|
|
||||
|.......|
|
||||
|....#..|
|
||||
|....#..|
|
||||
|....##.|
|
||||
|##..##.|
|
||||
|######.|
|
||||
|.###...|
|
||||
|..#....|
|
||||
|.####..|
|
||||
|....##.|
|
||||
|....##.|
|
||||
|....#..|
|
||||
|..#.#..|
|
||||
|..#.#..|
|
||||
|#####..|
|
||||
|..###..|
|
||||
|...#...|
|
||||
|..####.|
|
||||
+-------+
|
||||
#+end_example
|
||||
|
||||
To prove to the elephants your simulation is accurate, they want to know
|
||||
how tall the tower will get after 2022 rocks have stopped (but before
|
||||
the 2023rd rock begins falling). In this example, the tower of rocks
|
||||
will be =3068= units tall.
|
||||
|
||||
/How many units tall will the tower of rocks be after 2022 rocks have
|
||||
stopped falling?/
|
||||
17
2022/day17/aoc.h
Normal file
17
2022/day17/aoc.h
Normal file
@@ -0,0 +1,17 @@
|
||||
/* aoc.c: Advent of Code 2022
|
||||
*
|
||||
* Copyright (C) 2022-2023 Bruno Raoult ("br")
|
||||
* Licensed under the GNU General Public License v3.0 or later.
|
||||
* Some rights reserved. See COPYING.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with this
|
||||
* program. If not, see <https://www.gnu.org/licenses/gpl-3.0-standalone.html>.
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later <https://spdx.org/licenses/GPL-3.0-or-later.html>
|
||||
*/
|
||||
#ifndef _AOC_H_
|
||||
#define _AOC_H_
|
||||
|
||||
extern int parseargs(int ac, char**av);
|
||||
extern int testmode(void);
|
||||
#endif /* _AOC_H_ */
|
||||
68
2022/day17/common.bash
Normal file
68
2022/day17/common.bash
Normal file
@@ -0,0 +1,68 @@
|
||||
#!/usr/bin/env bash
|
||||
#
|
||||
# common.bash: Advent of Code 2022, common bash functions
|
||||
#
|
||||
# Copyright (C) 2022-2023 Bruno Raoult ("br")
|
||||
# Licensed under the GNU General Public License v3.0 or later.
|
||||
# Some rights reserved. See COPYING.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License along with this
|
||||
# program. If not, see <https://www.gnu.org/licenses/gpl-3.0-standalone.html>.
|
||||
#
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later <https://spdx.org/licenses/GPL-3.0-or-later.html>
|
||||
|
||||
# shellcheck disable=2034
|
||||
export cmdname=${0##*/}
|
||||
export debug=0
|
||||
export res
|
||||
export LANG=C
|
||||
|
||||
shopt -s extglob
|
||||
set -o noglob
|
||||
|
||||
usage() {
|
||||
printf "usage: %s [-d DEBUG] [-p PART]\n" "$cmdname"
|
||||
exit 1
|
||||
}
|
||||
|
||||
checkargs() {
|
||||
local part=1
|
||||
while getopts p:d: todo; do
|
||||
case "$todo" in
|
||||
d)
|
||||
if [[ "$OPTARG" =~ ^[[:digit:]+]$ ]]; then
|
||||
debug="$OPTARG"
|
||||
else
|
||||
printf "%s: illegal [%s] debug level.\n" "$CMD" "$OPTARG"
|
||||
exit 1
|
||||
fi
|
||||
;;
|
||||
p)
|
||||
if [[ "$OPTARG" =~ ^[12]$ ]]; then
|
||||
part="$OPTARG"
|
||||
else
|
||||
printf "%s: illegal [%s] part.\n" "$CMD" "$OPTARG"
|
||||
exit 1
|
||||
fi
|
||||
;;
|
||||
*)
|
||||
usage
|
||||
;;
|
||||
esac
|
||||
done
|
||||
# Now check remaining argument (backup directory)
|
||||
shift $((OPTIND - 1))
|
||||
|
||||
(( $# > 1 )) && usage
|
||||
return "$part"
|
||||
}
|
||||
|
||||
main() {
|
||||
local -i part
|
||||
|
||||
checkargs "$@"
|
||||
part=$?
|
||||
parse "$part"
|
||||
solve "$part"
|
||||
printf "%s: res=%s\n" "$cmdname" "$res"
|
||||
}
|
||||
59
2022/day17/common.c
Normal file
59
2022/day17/common.c
Normal file
@@ -0,0 +1,59 @@
|
||||
/* common.c: Advent of Code 2022, common functions
|
||||
*
|
||||
* Copyright (C) 2022-2023 Bruno Raoult ("br")
|
||||
* Licensed under the GNU General Public License v3.0 or later.
|
||||
* Some rights reserved. See COPYING.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with this
|
||||
* program. If not, see <https://www.gnu.org/licenses/gpl-3.0-standalone.html>.
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later <https://spdx.org/licenses/GPL-3.0-or-later.html>
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "aoc.h"
|
||||
#include "debug.h"
|
||||
|
||||
static int _testmode = 0;
|
||||
|
||||
static int usage(char *prg)
|
||||
{
|
||||
fprintf(stderr, "Usage: %s [-t][-d debug_level] [-p part] [-i input]\n", prg);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int testmode(void)
|
||||
{
|
||||
return _testmode;
|
||||
}
|
||||
|
||||
int parseargs(int ac, char **av)
|
||||
{
|
||||
int opt, part = 1;
|
||||
|
||||
while ((opt = getopt(ac, av, "td:p:")) != -1) {
|
||||
switch (opt) {
|
||||
case 't':
|
||||
_testmode = 1;
|
||||
break;
|
||||
case 'd':
|
||||
debug_level_set(atoi(optarg));
|
||||
break;
|
||||
case 'p': /* 1 or 2 */
|
||||
part = atoi(optarg);
|
||||
if (part < 1 || part > 2)
|
||||
return usage(*av);
|
||||
break;
|
||||
case 'i':
|
||||
|
||||
default:
|
||||
return usage(*av);
|
||||
}
|
||||
}
|
||||
if (optind < ac)
|
||||
return usage(*av);
|
||||
return part;
|
||||
}
|
||||
1
2022/day17/input/example.txt
Normal file
1
2022/day17/input/example.txt
Normal file
@@ -0,0 +1 @@
|
||||
>>><<><>><<<>><>>><<<>>><<<><<<>><>><<>>
|
||||
1
2022/day17/input/input.txt
Normal file
1
2022/day17/input/input.txt
Normal file
File diff suppressed because one or more lines are too long
@@ -31,6 +31,17 @@
|
||||
#define __PASTE(x, y) ___PASTE(x, y)
|
||||
#define __UNIQUE_ID(prefix) __PASTE(__PASTE(__UNIQUE_ID_, prefix), __COUNTER__)
|
||||
|
||||
/* unused/used parameters/functions
|
||||
* https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-unused-function-attribute
|
||||
* https://gcc.gnu.org/onlinedocs/gcc/Common-Type-Attributes.html#index-unused-type-attribute
|
||||
* https://gcc.gnu.org/onlinedocs/gcc/Common-Variable-Attributes.html#index-unused-variable-attribute
|
||||
* https://gcc.gnu.org/onlinedocs/gcc/Label-Attributes.html#index-unused-label-attribute
|
||||
* https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-used-function-attribute
|
||||
* https://gcc.gnu.org/onlinedocs/gcc/Common-Variable-Attributes.html#index-used-variable-attribute
|
||||
*/
|
||||
#define __unused __attribute__((__unused__))
|
||||
#define __used __attribute__((__used__))
|
||||
|
||||
/* see https://lkml.org/lkml/2018/3/20/845 for explanation of this monster
|
||||
*/
|
||||
#define __is_constexpr(x) \
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
#ifdef DEBUG_DEBUG
|
||||
void debug_init(u32 level);
|
||||
void debug_level_set(u32 level);
|
||||
u32 debug_level_get(void);
|
||||
void _printf debug(u32 level, bool timestamp,
|
||||
u32 indent, const char *src,
|
||||
u32 line, const char *, ...);
|
||||
|
||||
@@ -24,12 +24,23 @@
|
||||
#define _pjw_inline static inline
|
||||
#endif
|
||||
|
||||
_pjw_inline unsigned int pjwhash(const char* str, uint length)
|
||||
/**
|
||||
* unsigned int pjwhash - PJW hash function
|
||||
* @key: the key address.
|
||||
* @length: the length of key.
|
||||
*
|
||||
* This hash was created by Peter Jay Weinberger (AT&T Bell Labs):
|
||||
* https://en.wikipedia.org/wiki/PJW_hash_function
|
||||
*
|
||||
* Return: the PJW hash.
|
||||
*/
|
||||
_pjw_inline uint pjwhash(const void* key, uint length)
|
||||
{
|
||||
uint hash = 0, high;
|
||||
const u8 *k = key;
|
||||
|
||||
for (uint i = 0; i < length; ++str, ++i) {
|
||||
hash = (hash << ONE_EIGHTH) + *str;
|
||||
for (uint i = 0; i < length; ++k, ++i) {
|
||||
hash = (hash << ONE_EIGHTH) + *k;
|
||||
high = hash & HIGH_BITS;
|
||||
if (high != 0) {
|
||||
hash ^= high >> THREE_QUARTERS;
|
||||
|
||||
@@ -15,6 +15,16 @@
|
||||
|
||||
#include "bits.h"
|
||||
|
||||
extern unsigned int pjwhash(const char* str, uint length);
|
||||
/**
|
||||
* unsigned int pjwhash - PJW hash function
|
||||
* @key: the key address.
|
||||
* @length: the length of key.
|
||||
*
|
||||
* This hash was created by Peter Jay Weinberger (AT&T Bell Labs):
|
||||
* https://en.wikipedia.org/wiki/PJW_hash_function
|
||||
*
|
||||
* Return: the PJW hash.
|
||||
*/
|
||||
extern uint pjwhash (const void* key, uint length);
|
||||
|
||||
#endif /* _PJWHASH_H */
|
||||
|
||||
88
2022/libsrc/Makefile
Normal file
88
2022/libsrc/Makefile
Normal file
@@ -0,0 +1,88 @@
|
||||
# AOC Makefile - GNU make only.
|
||||
#
|
||||
# Copyright (C) 2021-2022 Bruno Raoult ("br")
|
||||
# Licensed under the GNU General Public License v3.0 or later.
|
||||
# Some rights reserved. See COPYING.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License along with this
|
||||
# program. If not, see <https://www.gnu.org/licenses/gpl-3.0-standalone.html>.
|
||||
#
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later <https://spdx.org/licenses/GPL-3.0-or-later.html>
|
||||
#
|
||||
|
||||
SHELL := /bin/bash
|
||||
CC := gcc
|
||||
BEAR := bear
|
||||
CCLSFILE:= compile_commands.json
|
||||
|
||||
#LIBS = -lreadline -lncurses
|
||||
CFLAGS += -std=gnu11
|
||||
|
||||
CFLAGS += -O2
|
||||
CFLAGS += -g
|
||||
# for gprof
|
||||
#CFLAGS += -pg
|
||||
CFLAGS += -Wall
|
||||
CFLAGS += -Wextra
|
||||
CFLAGS += -march=native
|
||||
|
||||
CFLAGS += -DDEBUG_DEBUG # activate general debug (debug.c)
|
||||
CFLAGS += -DDEBUG_POOL # memory pools management
|
||||
# Next one may be useful for valgrind (some invalid instructions)
|
||||
# CFLAGS += -mno-tbm
|
||||
CFLAGS += -Wmissing-declarations
|
||||
CFLAGS += -Wno-unused-result
|
||||
|
||||
INCDIR := ../include
|
||||
LIBSRCDIR := .
|
||||
LIBDIR := ../lib
|
||||
LIB := libaoc_$(shell uname -m)
|
||||
SLIB := $(LIBDIR)/$(LIB).a
|
||||
DLIB := $(LIBDIR)/$(LIB).so
|
||||
LIBSRC := $(wildcard $(LIBSRCDIR)/*.c)
|
||||
LIBOBJ := $(patsubst %.c,%.o,$(LIBSRC))
|
||||
LDFLAGS := -L$(LIBDIR)
|
||||
LDLIB := -l$(LIB)
|
||||
|
||||
.PHONY: clean cleanlib cleanall all redo output lib $(SUBDIRS)
|
||||
|
||||
all: lib $(SUBDIRS)
|
||||
|
||||
compile: $(LIBOBJ)
|
||||
|
||||
clean:
|
||||
@$(RM) -f *.o *.s *.i $(LIBOBJ)
|
||||
|
||||
cleanall: clean
|
||||
@$(RM) -f $(SLIB) $(DLIB) $(LIBOBJ)
|
||||
|
||||
lib: $(DLIB) $(SLIB)
|
||||
|
||||
$(SLIB): $(LIBOBJ)
|
||||
@echo building $@ static library.
|
||||
@mkdir -p $(LIBDIR)
|
||||
@$(AR) $(ARFLAGS) -o $@ $^
|
||||
|
||||
$(DLIB): CFLAGS += -fPIC
|
||||
$(DLIB): LDFLAGS += -shared
|
||||
$(DLIB): $(LIBOBJ)
|
||||
@echo building $@ shared library.
|
||||
@mkdir -p $(LIBDIR)
|
||||
@$(CC) $(LDFLAGS) $^ -o $@
|
||||
|
||||
.c.o:
|
||||
@echo compiling $<.
|
||||
@$(CC) -c $(CFLAGS) $(LDFLAGS) -I $(INCDIR) -o $@ $<
|
||||
|
||||
# generate pre-processed file (.i) and assembler (.s)
|
||||
%.i: %.c
|
||||
@echo generating $@
|
||||
@$(CC) -E $(CFLAGS) -I $(INCDIR) $< -o $@
|
||||
|
||||
%.s: %.c
|
||||
@echo generating $@
|
||||
@$(CC) -S -fverbose-asm $(CFLAGS) -I $(INCDIR) $< -o $@
|
||||
|
||||
bear: clean
|
||||
@touch .ccls-root
|
||||
@$(BEAR) -- make compile
|
||||
@@ -35,6 +35,11 @@ void debug_level_set(u32 level)
|
||||
log(1, "debug level set to %u\n", level);
|
||||
}
|
||||
|
||||
u32 debug_level_get()
|
||||
{
|
||||
return debug_level;
|
||||
}
|
||||
|
||||
void debug_init(u32 level)
|
||||
{
|
||||
struct timespec timer;
|
||||
|
||||
@@ -13,4 +13,8 @@
|
||||
|
||||
#define _pjw_inline extern
|
||||
|
||||
//#include "bits.h"
|
||||
//extern unsigned int pjwhash (const void* key, uint length);
|
||||
|
||||
#include "pjwhash.h"
|
||||
#include "pjwhash-inline.h"
|
||||
|
||||
@@ -14,3 +14,7 @@
|
||||
|
||||
#### Advent of Code 2021
|
||||
- `C`: All (days 1-25)
|
||||
|
||||
#### Advent of Code 2022
|
||||
- `Bash`: All (days 1-12)
|
||||
- `C`: All (days 1-14)
|
||||
|
||||
Reference in New Issue
Block a user