b.rs (2463B)
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 6 mod common; 7 use common::*; 8 9 fn 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 17 fn 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 23 fn 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 35 fn 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 48 fn 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 }