d17p2
This commit is contained in:
		| @@ -19,7 +19,7 @@ struct Shape { | |||||||
| #[derive(Debug)] | #[derive(Debug)] | ||||||
| struct Pos {y: usize, x: usize} | struct Pos {y: usize, x: usize} | ||||||
|  |  | ||||||
| static SHAPE_NAMES: [char; 5] = ['-', '+', 'L', '|', '.']; | //static SHAPE_NAMES: [char; 5] = ['-', '+', 'L', '|', '.']; | ||||||
| static SHAPES: [Shape; 5] = [ | static SHAPES: [Shape; 5] = [ | ||||||
|     Shape { // - |     Shape { // - | ||||||
|         bot: [0, 0, 0, 0], top: [0, 0, 0, 0], |         bot: [0, 0, 0, 0], top: [0, 0, 0, 0], | ||||||
| @@ -113,9 +113,11 @@ fn iterate( | |||||||
|  |  | ||||||
| fn main() -> io::Result<()> { | fn main() -> io::Result<()> { | ||||||
|     let input_fname = env::args().nth(1).expect("need input file"); |     let input_fname = env::args().nth(1).expect("need input file"); | ||||||
|  |     let limit = env::args().nth(2).expect("need limit").parse::<usize>().unwrap(); | ||||||
|     let mut winds: Vec<u8> = Vec::new(); |     let mut winds: Vec<u8> = Vec::new(); | ||||||
|     let _ = BufReader::new(File::open(input_fname)?).read_until(b'\n', &mut winds); |     let _ = BufReader::new(File::open(input_fname)?).read_until(b'\n', &mut winds); | ||||||
|     if winds.last() == Some(&b'\n') { winds.pop(); } |     if winds.last() == Some(&b'\n') { winds.pop(); } | ||||||
|  |     println!("winds = {}, shapes = {}", winds.len(), SHAPES.len()); | ||||||
|  |  | ||||||
|     let mut shape_id = 0; |     let mut shape_id = 0; | ||||||
|     let mut shape = &SHAPES[shape_id]; |     let mut shape = &SHAPES[shape_id]; | ||||||
| @@ -127,13 +129,12 @@ fn main() -> io::Result<()> { | |||||||
|         [0, 0, 0, 0, 0, 0, 0], |         [0, 0, 0, 0, 0, 0, 0], | ||||||
|         [0, 0, 0, 0, 0, 0, 0], |         [0, 0, 0, 0, 0, 0, 0], | ||||||
|     ]; |     ]; | ||||||
|     prettyprint(&map, &shape_pos, SHAPE_NAMES[shape_id]); |  | ||||||
|  |  | ||||||
|     let mut nrocks = 0; |     let mut answers: Vec<(usize, usize)> = Vec::new(); | ||||||
|  |  | ||||||
|     let mut i = 0; |     let mut i = 0; | ||||||
|     while nrocks < 2022 { //debug |     'mainloop: while answers.len() < limit { | ||||||
|         let c = winds[i % winds.len()]; |         let c = winds[i % winds.len()]; | ||||||
|         i += 1; |  | ||||||
|         if iterate(&mut map, shape, &mut shape_pos, c) { |         if iterate(&mut map, shape, &mut shape_pos, c) { | ||||||
|             let last_shape_top = shape_pos.y + shape.height - 1; |             let last_shape_top = shape_pos.y + shape.height - 1; | ||||||
|             if last_shape_top > current_top { |             if last_shape_top > current_top { | ||||||
| @@ -141,28 +142,69 @@ fn main() -> io::Result<()> { | |||||||
|             } |             } | ||||||
|             shape_id = (shape_id + 1) % SHAPES.len(); // next shape |             shape_id = (shape_id + 1) % SHAPES.len(); // next shape | ||||||
|             shape = &SHAPES[shape_id]; |             shape = &SHAPES[shape_id]; | ||||||
|             //println!("{} -> {}", map.len(), last_shape_top + 4 + shape.height); |  | ||||||
|             for _ in map.len()..(current_top + 4 + shape.height) { |             for _ in map.len()..(current_top + 4 + shape.height) { | ||||||
|                 map.push([0, 0, 0, 0, 0, 0, 0]); |                 map.push([0, 0, 0, 0, 0, 0, 0]); | ||||||
|             } |             } | ||||||
|             nrocks += 1; |  | ||||||
|             shape_pos = Pos{x:2, y: current_top + 4}; |             shape_pos = Pos{x:2, y: current_top + 4}; | ||||||
|             //println!("= {} ({})", current_top, nrocks); |             answers.push((i, current_top)); | ||||||
|             prettyprint(&map, &shape_pos, SHAPE_NAMES[shape_id]); |             let last_rock = answers.len() - 1; | ||||||
|  |             print!( | ||||||
|  |                 "rock {} - (i {}, top {})", | ||||||
|  |                 last_rock, i, current_top | ||||||
|  |             ); | ||||||
|  |  | ||||||
|  |             if last_rock >= 2*SHAPES.len() { | ||||||
|  |                 let mut j = last_rock - SHAPES.len(); | ||||||
|  |                 'lookback: while j > (last_rock / 2) { | ||||||
|  |                     let (hist_i, hist_top) = answers[j]; | ||||||
|  |                     let next_j = 2*j - last_rock; | ||||||
|  |                     let (hist2_i, hist2_top) = answers[next_j]; | ||||||
|  |                     if (i - hist_i) % winds.len() == 0 | ||||||
|  |                         && (i - hist_i) == (hist_i - hist2_i) | ||||||
|  |                         && (current_top - hist_top) == (hist_top - hist2_top) { | ||||||
|  |                         print!( | ||||||
|  |                             " {}-{}-{}-({}-{}-{})", | ||||||
|  |                             j, hist_i, hist_top, | ||||||
|  |                             next_j, hist2_i, hist2_top, | ||||||
|  |                         ); | ||||||
|  |                         print!( | ||||||
|  |                             " rock cycle {}, off {} | \ | ||||||
|  |                              top cycle {} off {} ", | ||||||
|  |                             last_rock - j, next_j, | ||||||
|  |                             current_top - hist_top, hist2_top, | ||||||
|  |                         ); | ||||||
|  |                         if (limit - 1 - next_j) % (last_rock - j) == 0 { | ||||||
|  |                             let n_cycles = (limit - 1 - next_j) / (last_rock - j); | ||||||
|  |                             println!( | ||||||
|  |                                 "\nheight = {}", | ||||||
|  |                                 hist2_top + n_cycles*(current_top - hist_top) + 1 | ||||||
|  |                             ); | ||||||
|  |                             break 'mainloop; | ||||||
|  |                         } else { | ||||||
|  |                             break 'lookback; | ||||||
|                         } |                         } | ||||||
|                     } |                     } | ||||||
|     println!("height = {}", current_top + 1); |                     j -= SHAPES.len(); | ||||||
|  |                 } | ||||||
|  |  | ||||||
|  |             } | ||||||
|  |  | ||||||
|  |             println!(); | ||||||
|  |             //prettyprint(&map, &shape_pos, SHAPE_NAMES[shape_id]); | ||||||
|  |         } | ||||||
|  |         i += 1; | ||||||
|  |     } | ||||||
|     Ok(()) |     Ok(()) | ||||||
| } | } | ||||||
|  |  | ||||||
| fn prettyprint(map: &Vec<[u8; 7]>, pos: &Pos, shape_name: char) { | fn prettyprint(map: &Vec<[u8; 7]>, pos: &Pos, shape_name: char) { | ||||||
| //     let mut i = map.len(); |     let mut i = map.len(); | ||||||
| //     for row in map.into_iter().rev() { |     for row in map.into_iter().rev() { | ||||||
| //         i -= 1; |         i -= 1; | ||||||
| //         print!("|"); |         print!("|"); | ||||||
| //         for j in 0..7 { |         for j in 0..7 { | ||||||
| //             print!("{}", if row[j] == 0 { "." } else { "#" }); |             print!("{}", if row[j] == 0 { "." } else { "#" }); | ||||||
| //         } |         } | ||||||
| //         println!("| {} {}", i, if i == pos.y {shape_name} else {' '}); |         println!("| {} {}", i, if i == pos.y {shape_name} else {' '}); | ||||||
| //     } |     } | ||||||
| } | } | ||||||
|   | |||||||
							
								
								
									
										168
									
								
								day17/src/main1.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										168
									
								
								day17/src/main1.rs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,168 @@ | |||||||
|  | use std::io; | ||||||
|  | use std::env; | ||||||
|  | use std::fs::File; | ||||||
|  | use std::io::BufReader; | ||||||
|  | use std::io::BufRead; | ||||||
|  | use std::fmt::Debug; | ||||||
|  |  | ||||||
|  | #[derive(Debug)] | ||||||
|  | struct Shape { | ||||||
|  |     bot: [i8; 4], // distance from datum. -1 for unused. | ||||||
|  |     top: [i8; 4], | ||||||
|  |     left: [i8; 4], | ||||||
|  |     right: [i8; 4], | ||||||
|  |     width: usize, | ||||||
|  |     height: usize, | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // a Shape's datum is its bottom left corner | ||||||
|  | #[derive(Debug)] | ||||||
|  | struct Pos {y: usize, x: usize} | ||||||
|  |  | ||||||
|  | static SHAPE_NAMES: [char; 5] = ['-', '+', 'L', '|', '.']; | ||||||
|  | static SHAPES: [Shape; 5] = [ | ||||||
|  |     Shape { // - | ||||||
|  |         bot: [0, 0, 0, 0], top: [0, 0, 0, 0], | ||||||
|  |         left: [0, -1, -1, -1], right: [3, -1, -1, -1], | ||||||
|  |         width: 4, height: 1, | ||||||
|  |     }, | ||||||
|  |     Shape { // + | ||||||
|  |         bot: [1, 0, 1, -1], top: [1, 2, 1, -1], | ||||||
|  |         left: [1, 0, 1, -1], right: [1, 2, 1, -1], | ||||||
|  |         width: 3, height: 3, | ||||||
|  |     }, | ||||||
|  |     Shape { // backward L | ||||||
|  |         bot: [0, 0, 0, -1], top: [0, 0, 2, -1], | ||||||
|  |         left: [0, 2, 2, -1], right: [2, 2, 2, -1], | ||||||
|  |         width: 3, height: 3, | ||||||
|  |     }, | ||||||
|  |     Shape { // | | ||||||
|  |         bot: [0, -1, -1, -1], top: [0, -1, -1, -1], | ||||||
|  |         left: [0, 0, 0, 0], right: [0, 0, 0, 0], | ||||||
|  |         width: 1, height: 4, | ||||||
|  |     }, | ||||||
|  |     Shape { // square | ||||||
|  |         bot: [0, 0, -1, -1], top: [1, 1, -1, -1], | ||||||
|  |         left: [0, 0, -1, -1], right: [1, 1, -1, -1], | ||||||
|  |         width: 2, height: 2, | ||||||
|  |     }, | ||||||
|  | ]; | ||||||
|  |  | ||||||
|  | fn iterate( | ||||||
|  |         map: &mut Vec<[u8; 7]>, shape: &Shape, pos: &mut Pos, wind: u8 | ||||||
|  | ) -> bool { | ||||||
|  |     //println!("  __ {}, start {:?}", wind as char, pos); | ||||||
|  |     // Wind move | ||||||
|  |     match wind { | ||||||
|  |         b'>' => 'rightmove: { | ||||||
|  |             if pos.x + shape.width == 7 { break 'rightmove; } | ||||||
|  |             let mut i = 0; | ||||||
|  |             while i < 4 && shape.right[i] >= 0 { | ||||||
|  |                 let right_point = pos.x + shape.right[i] as usize; | ||||||
|  |                 if right_point + 1 == 7 { break 'rightmove; } | ||||||
|  |                 if map[pos.y + i][right_point + 1] != 0 { break 'rightmove; } | ||||||
|  |                 i += 1; | ||||||
|  |             } | ||||||
|  |             pos.x += 1; | ||||||
|  |             //println!("  >> {:?}", pos); | ||||||
|  |         }, | ||||||
|  |         b'<' => 'leftmove: { | ||||||
|  |             if pos.x == 0 { break 'leftmove; } | ||||||
|  |             let mut i = 0; | ||||||
|  |             while i < 4 && shape.left[i] >= 0 { | ||||||
|  |                 let left_point = pos.x + shape.left[i] as usize; | ||||||
|  |                 if left_point == 0 { break 'leftmove; } | ||||||
|  |                 if map[pos.y + i][left_point - 1] != 0 { break 'leftmove; } | ||||||
|  |                 i += 1; | ||||||
|  |             } | ||||||
|  |             pos.x -= 1; | ||||||
|  |             //println!("  << {:?}", pos); | ||||||
|  |         }, | ||||||
|  |         _ => panic!(), | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     // Gravity move | ||||||
|  |     'downmove: { | ||||||
|  |         let mut i = 0; | ||||||
|  |         while i < 4 && shape.bot[i] >= 0 { | ||||||
|  |             let bot_point = pos.y + shape.bot[i] as usize; | ||||||
|  |             if bot_point == 0 { break 'downmove; } | ||||||
|  |             if map[bot_point - 1][pos.x + i] != 0 { break 'downmove; } | ||||||
|  |             i += 1; | ||||||
|  |         } | ||||||
|  |         pos.y -= 1; | ||||||
|  |         //println!("  vv {:?}", pos); | ||||||
|  |         return false; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     // Settling | ||||||
|  |     let mut i = 0; | ||||||
|  |     while i < 4 && shape.left[i] >= 0 && shape.right[i] >= 0 { | ||||||
|  |         map[pos.y + i][pos.x + shape.left[i] as usize] = 1; | ||||||
|  |         map[pos.y + i][pos.x + shape.right[i] as usize] = 1; | ||||||
|  |         i += 1; | ||||||
|  |     } | ||||||
|  |     i = 0; | ||||||
|  |     while i < 4 && shape.top[i] >= 0 && shape.bot[i] >= 0 { | ||||||
|  |         map[pos.y + shape.top[i] as usize][pos.x + i] = 1; | ||||||
|  |         map[pos.y + shape.bot[i] as usize][pos.x + i] = 1; | ||||||
|  |         i += 1; | ||||||
|  |     } | ||||||
|  |     return true; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | fn main() -> io::Result<()> { | ||||||
|  |     let input_fname = env::args().nth(1).expect("need input file"); | ||||||
|  |     let mut winds: Vec<u8> = Vec::new(); | ||||||
|  |     let _ = BufReader::new(File::open(input_fname)?).read_until(b'\n', &mut winds); | ||||||
|  |     if winds.last() == Some(&b'\n') { winds.pop(); } | ||||||
|  |  | ||||||
|  |     let mut shape_id = 0; | ||||||
|  |     let mut shape = &SHAPES[shape_id]; | ||||||
|  |     let mut current_top = 0; | ||||||
|  |     let mut shape_pos = Pos{x: 2, y: 3}; | ||||||
|  |     let mut map: Vec<[u8; 7]> = vec![ | ||||||
|  |         [0, 0, 0, 0, 0, 0, 0], | ||||||
|  |         [0, 0, 0, 0, 0, 0, 0], | ||||||
|  |         [0, 0, 0, 0, 0, 0, 0], | ||||||
|  |         [0, 0, 0, 0, 0, 0, 0], | ||||||
|  |     ]; | ||||||
|  |     prettyprint(&map, &shape_pos, SHAPE_NAMES[shape_id]); | ||||||
|  |  | ||||||
|  |     let mut nrocks = 0; | ||||||
|  |     let mut i = 0; | ||||||
|  |     while nrocks < 2022 { //debug | ||||||
|  |         let c = winds[i % winds.len()]; | ||||||
|  |         i += 1; | ||||||
|  |         if iterate(&mut map, shape, &mut shape_pos, c) { | ||||||
|  |             let last_shape_top = shape_pos.y + shape.height - 1; | ||||||
|  |             if last_shape_top > current_top { | ||||||
|  |                 current_top = last_shape_top; | ||||||
|  |             } | ||||||
|  |             shape_id = (shape_id + 1) % SHAPES.len(); // next shape | ||||||
|  |             shape = &SHAPES[shape_id]; | ||||||
|  |             //println!("{} -> {}", map.len(), last_shape_top + 4 + shape.height); | ||||||
|  |             for _ in map.len()..(current_top + 4 + shape.height) { | ||||||
|  |                 map.push([0, 0, 0, 0, 0, 0, 0]); | ||||||
|  |             } | ||||||
|  |             nrocks += 1; | ||||||
|  |             shape_pos = Pos{x:2, y: current_top + 4}; | ||||||
|  |             //println!("= {} ({})", current_top, nrocks); | ||||||
|  |             prettyprint(&map, &shape_pos, SHAPE_NAMES[shape_id]); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |     println!("height = {}", current_top + 1); | ||||||
|  |     Ok(()) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | fn prettyprint(map: &Vec<[u8; 7]>, pos: &Pos, shape_name: char) { | ||||||
|  | //     let mut i = map.len(); | ||||||
|  | //     for row in map.into_iter().rev() { | ||||||
|  | //         i -= 1; | ||||||
|  | //         print!("|"); | ||||||
|  | //         for j in 0..7 { | ||||||
|  | //             print!("{}", if row[j] == 0 { "." } else { "#" }); | ||||||
|  | //         } | ||||||
|  | //         println!("| {} {}", i, if i == pos.y {shape_name} else {' '}); | ||||||
|  | //     } | ||||||
|  | } | ||||||
		Reference in New Issue
	
	Block a user