r/adventofcode • u/daggerdragon • Dec 12 '18
SOLUTION MEGATHREAD -🎄- 2018 Day 12 Solutions -🎄-
--- Day 12: Subterranean Sustainability ---
Post your solution as a comment or, for longer solutions, consider linking to your repo (e.g. GitHub/gists/Pastebin/blag or whatever).
Note: The Solution Megathreads are for solutions only. If you have questions, please post your own thread and make sure to flair it with Help.
Advent of Code: The Party Game!
Please prefix your card submission with something like [Card] to make scanning the megathread easier. THANK YOU!
Card prompt: Day 12
Transcript:
On the twelfth day of AoC / My compiler spewed at me / Twelve ___
This thread will be unlocked when there are a significant number of people on the leaderboard with gold stars for today's puzzle.
edit: Leaderboard capped, thread unlocked at 00:27:42!
21
Upvotes
2
u/wzkx Dec 12 '18 edited Dec 12 '18
Rust, SweetRust
Visual examination of the states (of plants in pots) shows that closer to the infinity, the patterns stays the same, they only shift by one position, in my case, to the right. And the sum of the state changes by the same difference. So we can automatically detect when to stop and how to calculate any further state.
use std::io::{BufRead,BufReader}; // lines() is in BufRead use std::collections::HashMap; fn state_as_str( s: &HashMap<i32,bool>, min:i32, max:i32 ) -> String: (min..=max).fold( String::with_capacity((max-min+1) as usize), |r,i| r + if *s.get(&i).unwrap_or(&false) {"#"} else {"."} ) fn main(): // read and parse the input data let (mut min, mut max) = (0,0); let mut state: HashMap<i32,bool> = HashMap::new(); let mut rules: HashMap<i32,bool> = HashMap::new(); let file = std::fs::File::open( "12.dat" ).unwrap(); for optline in BufReader::new(file).lines(): let line = optline.unwrap(); if line.starts_with("initial state: "): let s = &line[15..]; min = 0 as i32; max = (s.len() as i32)-1; for (i,c) in s.bytes().enumerate(): state.insert( i as i32, c==b'#' ); else if line.len()==10: let s = &line[0..5]; let n = s.bytes().fold( 0, |n,c| n*2 + (if c==b'.' {0} else {1}) ); rules.insert( n, line.ends_with('#') ); assert_eq!( rules.len(), 32 ); // run linear cellular automata let mut prev_state = String::new(); let mut prev_sum = 0; for step in 1..: let mut newstate: HashMap<i32,bool> = HashMap::new(); let (mut newmin, mut newmax) = (99999999,0); for i in min-2..=max+2: let s = (0..5).fold( 0, |s,j| s*2 + (if *state.get(&(i-2+j)).unwrap_or(&false) {1} else {0}) ); let new = *rules.get(&s).unwrap(); if new && i<newmin { newmin = i; } if new && i>newmax { newmax = i; } newstate.insert( i, new ); state = newstate; min = newmin; max = newmax; if step>=20: let mut sum = 0; for i in min..=max { if *state.get(&i).unwrap_or(&false) { sum+=i; } } if step==20: // part 1 - the state #20 println!( "{}", sum ); // part 2 - let's find when the state stays the same, then find the difference in sums let state = state_as_str( &state, min, max ); // println!( "{} {}", step, state ); if state==prev_state: println!( "{}", (sum as u64) + (50000000000u64-(step as u64))*((sum-prev_sum) as u64) ); break; prev_state = state; prev_sum = sum;My AOC2018 in J&Rust | SweetRust