Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- use std::env;
- use std::io::{self};
- use std::collections::HashSet;
- extern crate regex;
- use regex::Regex;
- use point2d::point2d::Point2D;
- enum Fold {
- AlongX(i64),
- AlongY(i64)
- }
- impl From<&str> for Fold {
- fn from(s: &str) -> Self {
- let re = Regex::new(r"fold along ([xy])=(\d+)").unwrap();
- let matches = re.captures(s).unwrap();
- match &matches[1] {
- "x" => Self::AlongX(matches[2].parse().unwrap()),
- "y" => Self::AlongY(matches[2].parse().unwrap()),
- other => panic!("Unknown fold type: {}", other),
- }
- }
- }
- fn map_extents(map: &HashSet<Point2D>) -> (i64,i64,i64,i64) {
- let xmin = &map.iter().map(|&pt| pt.x).min().unwrap();
- let ymin = &map.iter().map(|&pt| pt.y).min().unwrap();
- let xmax = &map.iter().map(|&pt| pt.x).max().unwrap();
- let ymax = &map.iter().map(|&pt| pt.y).max().unwrap();
- (*xmin,*ymin,*xmax,*ymax)
- }
- fn solve(input: &str) -> io::Result<()> {
- // Input
- let input_str = std::fs::read_to_string(input).unwrap();
- let input_str = input_str.trim();
- let input: Vec<_> = input_str.split("\n\n").collect();
- let initial_points: Vec<_> = input[0].split("\n").collect();
- let folds: Vec<_> = input[1].split("\n").map(Fold::from).collect();
- // Build initial image
- let mut image: HashSet<Point2D> = HashSet::new();
- let re = Regex::new(r"(\d+),(\d+)").unwrap();
- for point in initial_points {
- let matches = re.captures(&point).unwrap();
- let (x,y) = (matches[1].parse().unwrap(),matches[2].parse().unwrap());
- image.insert(Point2D{x: x, y: y});
- }
- // Process folds
- let (_,_,mut xmax,mut ymax) = map_extents(&image);
- for (i,fold) in folds.iter().enumerate() {
- // Part 1
- if i == 1 {
- let part1 = image.iter().filter(|&pt| pt.x <= xmax && pt.y <= ymax).count();
- println!("Part 1: {}", part1); // 743
- }
- match &fold {
- Fold::AlongX(cut) => {
- for y in 0..=ymax {
- for x in *cut..=xmax {
- let pt = Point2D { x: x, y: y };
- let newpt = Point2D { x: 2*cut-x, y };
- if image.contains(&pt) { image.insert(newpt); }
- }
- }
- xmax = *cut;
- },
- Fold::AlongY(cut) => {
- for y in *cut..=ymax {
- for x in 0..=xmax {
- let pt = Point2D { x: x, y: y };
- let newpt = Point2D { x: x, y: 2*cut-y };
- if image.contains(&pt) { image.insert(newpt); }
- }
- }
- ymax = *cut;
- },
- }
- }
- println!("Part 2:"); // RCPLAKHL
- for y in 0..=ymax {
- for x in 0..=xmax {
- match image.contains(&Point2D { x: x, y: y }) {
- true => { print!("█"); },
- _ => { print!(" "); },
- }
- }
- println!();
- }
- Ok(())
- }
- fn main() {
- let args: Vec<String> = env::args().collect();
- let filename = &args[1];
- solve(&filename).unwrap();
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement