aboutsummaryrefslogtreecommitdiff
path: root/2022/17/b.rs
diff options
context:
space:
mode:
authorSebastiano Tronto <sebastiano@tronto.net>2025-07-04 15:32:49 +0200
committerSebastiano Tronto <sebastiano@tronto.net>2025-07-04 15:32:49 +0200
commit19b7ee46b55ed25f77fd030ccc473c8cf95e07b5 (patch)
tree80846c02487cb1424c4c6778f9771ab981b0b822 /2022/17/b.rs
parent36c94296df6edce01db71afeadb8940e33ecdd4a (diff)
downloadaoc-19b7ee46b55ed25f77fd030ccc473c8cf95e07b5.tar.gz
aoc-19b7ee46b55ed25f77fd030ccc473c8cf95e07b5.zip
Day 17 2022 bleah
Diffstat (limited to '2022/17/b.rs')
-rw-r--r--2022/17/b.rs93
1 files changed, 93 insertions, 0 deletions
diff --git a/2022/17/b.rs b/2022/17/b.rs
new file mode 100644
index 0000000..261dff4
--- /dev/null
+++ b/2022/17/b.rs
@@ -0,0 +1,93 @@
1// Wow this is was terrible. Clearly you have to find out at which
2// exact frequency the shape repeats, but I could not find a good
3// way to estimate this apart from computing the first few (10^5)
4// rows and then manually checking.
5
6mod common;
7use common::*;
8
9fn line_to_u8(line: &[bool]) -> u8 {
10 let mut r = 0;
11 for i in 0..SCREEN_WIDTH {
12 if line[i] { r |= 1 << i as u8; }
13 }
14 r
15}
16
17fn write_lines(screen: &Screen, v: &mut [u8]) {
18 for i in 0..SCREEN_HEIGHT {
19 v[i] = line_to_u8(&screen.cell[i]);
20 }
21}
22
23fn isperiod(v: &[u8], l: usize) -> bool {
24 const PERIOD_GUESS: usize = 10;
25 const TIMES_MATCH: usize = 10;
26
27 for i in 0..PERIOD_GUESS {
28 for j in 1..TIMES_MATCH {
29 if v[i] != v[i+j*l] { return false; }
30 }
31 }
32 true
33}
34
35fn find_period(v: &[u8]) -> (usize, usize) {
36 const PREP: usize = 1000;
37 const PMAX: usize = 10000;
38
39 for start in 0..PREP {
40 for plen in 10..PMAX {
41 if isperiod(&v[start..], plen) { return (start+1, plen); }
42 }
43 }
44 panic!("No period of length < {} found with preperiod < {}",
45 PMAX, PREP);
46}
47
48fn main() {
49 const N: usize = 1000000000000;
50
51 let mut screen = Screen::new();
52 let rocks = get_rocks();
53 let mut line = String::new();
54 let _ = std::io::stdin().read_line(&mut line);
55 let line = &line[0..line.len()-1]; // remove newline
56
57 let mut i = 0;
58 let mut t = 0;
59 let mut vv = [0 as u8; SCREEN_HEIGHT];
60 let mut ii = [0 as usize; SCREEN_HEIGHT];
61 while screen.top < SCREEN_HEIGHT - 10 {
62 screen.drop_rock(&rocks[i%5], &mut t, &line);
63 ii[screen.top] = i;
64 i += 1;
65 }
66 write_lines(&screen, &mut vv);
67 let (prep, plen) = find_period(&vv);
68
69 /* This part shows the period etc...
70 println!("prep = {prep}, plen = {plen}");
71 for j in 0..10 {
72 for k in 0..4 {
73 print!(" | t={:>4} i={:>4}", j+prep+k*plen, ii[j+prep+k*plen]);
74 }
75 println!();
76 }
77 */
78
79 let i0 = ii[prep];
80 let i1 = ii[prep+plen];
81
82 let n = (N - i0) / (i1 - i0); // How many full repeats
83 let t = n * plen + prep; // How tall is the thing after n full repeats
84 // Remainder (unlike in the example case, it does not end with full repeat)
85 let mut rem = 0;
86 for j in 0..SCREEN_HEIGHT {
87 if ii[j] >= i0 + (N - i0) % (i1 - i0) {
88 rem = j-prep;
89 break;
90 }
91 }
92 println!("{}", t + rem - 1);
93}

Generated with cgit - Back to sebastiano.tronto.net