day 4
							parent
							
								
									51459c17c6
								
							
						
					
					
						commit
						744731c1fc
					
				| @ -0,0 +1,7 @@ | |||||||
|  | # This file is automatically @generated by Cargo. | ||||||
|  | # It is not intended for manual editing. | ||||||
|  | version = 3 | ||||||
|  | 
 | ||||||
|  | [[package]] | ||||||
|  | name = "day04" | ||||||
|  | version = "0.1.0" | ||||||
| @ -0,0 +1,4 @@ | |||||||
|  | [package] | ||||||
|  | name = "day04" | ||||||
|  | version = "0.1.0" | ||||||
|  | edition = "2021" | ||||||
| @ -0,0 +1,61 @@ | |||||||
|  | use std::collections::{HashMap, HashSet}; | ||||||
|  | use std::io::{stdin, BufRead}; | ||||||
|  | 
 | ||||||
|  | fn main() { | ||||||
|  |     let input = stdin().lock().lines().map(|l| l.unwrap()); | ||||||
|  |     let mut total_score = 0; | ||||||
|  |     let mut card_counts = HashMap::new(); | ||||||
|  |     let mut total_single_cards = 0; | ||||||
|  | 
 | ||||||
|  |     for (id, line) in input.enumerate() { | ||||||
|  |         let card = line.split_once(':').unwrap().1; | ||||||
|  |         let (entries, winners) = card.split_once('|').unwrap(); | ||||||
|  | 
 | ||||||
|  |         let entset = entries | ||||||
|  |             .trim() | ||||||
|  |             .split(' ') | ||||||
|  |             .filter(|num| !num.is_empty()) | ||||||
|  |             .collect::<HashSet<_>>(); | ||||||
|  |         let winset = winners | ||||||
|  |             .trim() | ||||||
|  |             .split(' ') | ||||||
|  |             .filter(|num| !num.is_empty()) | ||||||
|  |             .collect::<HashSet<_>>(); | ||||||
|  | 
 | ||||||
|  |         let common = entset.intersection(&winset); | ||||||
|  |         let num_in_common = common.count(); | ||||||
|  |         total_score += to_score(num_in_common); | ||||||
|  | 
 | ||||||
|  |         let repeat_count = card_counts.get(&(id + 1)).unwrap_or(&0).to_owned(); | ||||||
|  | 
 | ||||||
|  |         let r = to_range(id, num_in_common); | ||||||
|  |         for win_card_copy in r { | ||||||
|  |             let current_count = card_counts.get(&win_card_copy).unwrap_or(&0); | ||||||
|  |             card_counts.insert(win_card_copy, current_count + 1 + repeat_count); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         total_single_cards = id + 1; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     let card_total = card_counts.iter().fold(0, |total, count| total + count.1); | ||||||
|  | 
 | ||||||
|  |     println!( | ||||||
|  |         "P1: {} P2: {}", | ||||||
|  |         total_score, | ||||||
|  |         total_single_cards + card_total | ||||||
|  |     ); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | fn to_range(id: usize, win_count: usize) -> std::ops::Range<usize> { | ||||||
|  |     let start = id + 2; | ||||||
|  |     let end = start + win_count; | ||||||
|  |     start..end | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | fn to_score(entries: usize) -> usize { | ||||||
|  |     if entries == 0 { | ||||||
|  |         0 | ||||||
|  |     } else { | ||||||
|  |         1 << (entries - 1) | ||||||
|  |     } | ||||||
|  | } | ||||||
					Loading…
					
					
				
		Reference in New Issue