solve Day04 in Rust
This commit is contained in:
		
							parent
							
								
									ce5fe0f4a3
								
							
						
					
					
						commit
						336d7fe657
					
				
							
								
								
									
										8
									
								
								Day04/rust/Cargo.toml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								Day04/rust/Cargo.toml
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,8 @@
 | 
				
			|||||||
 | 
					[package]
 | 
				
			||||||
 | 
					name = "rust"
 | 
				
			||||||
 | 
					version = "0.1.0"
 | 
				
			||||||
 | 
					edition = "2021"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[dependencies]
 | 
				
			||||||
							
								
								
									
										101
									
								
								Day04/rust/src/main.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										101
									
								
								Day04/rust/src/main.rs
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,101 @@
 | 
				
			|||||||
 | 
					use std::fs::File;
 | 
				
			||||||
 | 
					use std::io::{self, BufRead, BufReader};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					fn main() {
 | 
				
			||||||
 | 
					    // Run tests
 | 
				
			||||||
 | 
					    match run_test("../test.txt") {
 | 
				
			||||||
 | 
					        Ok(()) => println!("Tests passed."),
 | 
				
			||||||
 | 
					        Err(e) => eprintln!("Test failed: {}", e),
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Process main puzzle input
 | 
				
			||||||
 | 
					    match process_input("../input.txt") {
 | 
				
			||||||
 | 
					        Ok(result) => println!("Puzzle result: {}", result),
 | 
				
			||||||
 | 
					        Err(e) => eprintln!("Error processing input: {}", e),
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					fn run_test(filename: &str) -> Result<(), String> {
 | 
				
			||||||
 | 
					    let input = read_input(filename)?;
 | 
				
			||||||
 | 
					    let cards = parse(&input);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    let part_a_result = part_a(&cards);
 | 
				
			||||||
 | 
					    let part_b_result = part_b(&cards);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    assert_eq!(part_a_result, 13, "Part A Test failed");
 | 
				
			||||||
 | 
					    assert_eq!(part_b_result, 30, "Part B Test failed");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Ok(())
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					fn process_input(filename: &str) -> Result<u32, String> {
 | 
				
			||||||
 | 
					    let input = read_input(filename)?;
 | 
				
			||||||
 | 
					    let cards = parse(&input);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Ok(part_a(&cards) + part_b(&cards))
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					fn part_a(cards: &[Card]) -> u32 {
 | 
				
			||||||
 | 
					    cards
 | 
				
			||||||
 | 
					        .iter()
 | 
				
			||||||
 | 
					        .filter(|x| x.wins > 0)
 | 
				
			||||||
 | 
					        .map(|x| 2u32.pow(x.wins.saturating_sub(1) as u32))
 | 
				
			||||||
 | 
					        .sum()
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					fn part_b(cards: &[Card]) -> u32 {
 | 
				
			||||||
 | 
					    let mut queue = (0..cards.len()).collect::<Vec<_>>();
 | 
				
			||||||
 | 
					    let mut visited = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    while let Some(i) = queue.pop() {
 | 
				
			||||||
 | 
					        visited += 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        let card = &cards[i];
 | 
				
			||||||
 | 
					        if card.wins == 0 {
 | 
				
			||||||
 | 
					            continue;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        for j in 0..card.wins as usize {
 | 
				
			||||||
 | 
					            queue.push(j + i + 1);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    visited as u32
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					fn read_input(filename: &str) -> Result<String, String> {
 | 
				
			||||||
 | 
					    let file = File::open(filename).map_err(|e| e.to_string())?;
 | 
				
			||||||
 | 
					    let buffer = BufReader::new(file);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    buffer
 | 
				
			||||||
 | 
					        .lines()
 | 
				
			||||||
 | 
					        .collect::<Result<Vec<_>, io::Error>>()
 | 
				
			||||||
 | 
					        .map_err(|e| e.to_string())
 | 
				
			||||||
 | 
					        .map(|lines| lines.join("\n"))
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					fn parse(input: &str) -> Vec<Card> {
 | 
				
			||||||
 | 
					    input
 | 
				
			||||||
 | 
					        .lines()
 | 
				
			||||||
 | 
					        .map(|line| {
 | 
				
			||||||
 | 
					            let (_, line) = line.split_once(": ").unwrap();
 | 
				
			||||||
 | 
					            let (winning, scratch) = line.split_once(" | ").unwrap();
 | 
				
			||||||
 | 
					            let parse = |s: &str| {
 | 
				
			||||||
 | 
					                s.split_whitespace()
 | 
				
			||||||
 | 
					                    .map(|x| x.parse::<u8>().unwrap())
 | 
				
			||||||
 | 
					                    .collect::<Vec<u8>>()
 | 
				
			||||||
 | 
					            };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            let winning = parse(winning);
 | 
				
			||||||
 | 
					            let scratch = parse(scratch);
 | 
				
			||||||
 | 
					            
 | 
				
			||||||
 | 
					            Card {
 | 
				
			||||||
 | 
					                wins: scratch.iter().filter(|x| winning.contains(x)).count() as u8,
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        })
 | 
				
			||||||
 | 
					        .collect()
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct Card {
 | 
				
			||||||
 | 
					    wins: u8,
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
		Loading…
	
		Reference in New Issue
	
	Block a user