Add solutions for 2019 day 3.
[?]
May 17, 2020, 6:19 AM
IVWB6VSKODTSWIRCXJPY7UNAA333C5QWN2CUFDMYJUPA3OCR4R3ACDependencies
- [2]
TCCBGQEU2019 day 1
Change contents
- file addition: day3.rs[2.7]
use std::env;use std::iter::Peekable;#[derive(Clone)]#[derive(Copy)]#[derive(Debug)]struct Point {x: i64,y: i64,}#[derive(Clone)]#[derive(Copy)]#[derive(Debug)]enum Direction {U,R,D,L}#[derive(Clone)]#[derive(Copy)]#[derive(Debug)]struct Segment {direction: Direction,length: i64,}impl core::ops::Add<&Segment> for Point {type Output = Self;fn add(self, other: &Segment) -> Self {match other.direction {Direction::U => Point { x: self.x, y: self.y - other.length },Direction::R => Point { x: self.x + other.length, y: self.y },Direction::D => Point { x: self.x, y: self.y + other.length },Direction::L => Point { x: self.x - other.length, y: self.y },}}}struct Pairwise<I: Iterator> {last: Option<I::Item>,inner: I,}impl<I: Iterator> Pairwise<I> {fn new(inner: I) -> Self {let mut inner = inner;Pairwise {last: inner.next(),inner: inner,}}}impl<I: Iterator> Iterator for Pairwise<I>whereI::Item: Copy{type Item = (I::Item,I::Item);fn next(&mut self) -> Option<Self::Item> {self.last.and_then(|last|self.inner.next().and_then(|fresh| {self.last = Some(fresh);Some((last,fresh))}).or_else(|| {self.last = None;None}))}}struct Accumulator<I, R> {sum: Option<R>,inner: I,}impl<I, R> Accumulator<I,R> {pub fn new(initial: R, inner: I) -> Self {Accumulator{sum: Some(initial),inner: inner,}}}impl<I,R> Iterator for Accumulator<I,R> whereI: Iterator,R: core::ops::Add<I::Item, Output=R> + Copy,{type Item = R;fn next(&mut self) -> Option<R> {match self.sum {None => None,Some(s) => {self.sum = match self.inner.next() {Some(a) => Some(s + a),None => None,};Some(s)},}}}fn next_direction<I: Iterator<Item=char>>(i: &mut Peekable<I>) -> Option<Direction> {i.peek().and_then(|c| match c {'U' => Some(Direction::U),'R' => Some(Direction::R),'D' => Some(Direction::D),'L' => Some(Direction::L),_ => None,}).map(|d| {i.next();d})}struct SegmentIter<I: Iterator<Item=char>> { inner: Peekable<I> }impl<I: Iterator<Item=char>> SegmentIter<I> {fn new(original: I) -> Self {SegmentIter { inner: original.peekable(), }}fn next_line(&mut self) {if self.inner.peek().map_or(false,|c| *c == '\n') {self.inner.next();}}}impl<I: Iterator<Item=char>> Iterator for SegmentIter<I> {type Item = Segment;fn next(&mut self) -> Option<Segment> {let r = next_direction(&mut self.inner).and_then(|d| next_number(&mut self.inner).map(|s| Segment {direction: d,length: s,}));if r.is_some() && self.inner.peek().map_or(false, |c| *c == ',') {self.inner.next();}r}}fn next_number<I: Iterator<Item=char>>(i: &mut Peekable<I>) -> Option<i64> {i.peek().and_then(|c| c.to_digit(10)).and_then(|d| {i.next();let mut d = d as i64;loop {match i.peek().and_then(|c| c.to_digit(10)) {Some(d2) => {d = d * 10 + d2 as i64;i.next();},None => {break Some(d);},}}})}fn intersection(a: (Point,Point), b: (Point,Point)) -> Option<Point> {let mut a = a;let mut b = b;if a.0.x > a.1.x || a.0.y > a.1.y {a = (a.1, a.0);}if b.0.x > b.1.x || b.0.y > b.1.y {b = (b.1, b.0);}if a.0.x != a.1.x {if b.0.x == b.1.x {let t = b;b = a;a = t;} else {return None;}}if b.0.y != b.1.y ||b.0.y < a.0.y ||b.0.y > a.1.y ||a.0.x < b.0.x ||a.0.x > b.1.x {None} else {Some(Point{x: a.0.x, y: b.0.y})}}fn main() {let args: Vec<_> = env::args().collect();let file = std::fs::read_to_string(&args[1]).expect("Could not read the file");let mut stream = SegmentIter::new(file.chars());let mut wires = [Vec::new(), Vec::new()];for i in 0 ..= 1 {while let Some(segment) = stream.next() {wires[i].push(segment);}stream.next_line();}let wires: [_; 2] = {let mut w: [Vec<(Point,Point)>; 2] = [Vec::new(), Vec::new()];for (dst, wl) in w.iter_mut().zip(wires.iter()) {dst.extend(Pairwise::new(Accumulator::new(Point{x:0,y:0},wl.into_iter())));}w};let mut nd = i64::MAX;let mut ai = wires[0].iter().enumerate();while let Some((aix,a)) = ai.next() {let mut bi = wires[1].iter();if aix == 0 { bi.next(); }while let Some(b) = bi.next() {match intersection(*a,*b) {None => {},Some(p) => {let d = p.x.abs() + p.y.abs();if d < nd {nd = d;}}}}}println!("{}", nd);} - file addition: day3p2.rs[2.7]
use std::env;use std::iter::Peekable;use std::hash::Hash;use std::collections::HashMap;#[derive(Clone,Copy,Debug,Eq,Hash,PartialEq)]struct Point {x: i64,y: i64,}#[derive(Clone,Copy,Debug)]enum Direction {U,R,D,L}#[derive(Clone,Copy,Debug)]struct Segment {direction: Direction,length: i64,}impl core::ops::Add<Direction> for Point {type Output = Self;fn add(self, other: Direction) -> Self {match other {Direction::U => Point { x: self.x, y: self.y - 1 },Direction::R => Point { x: self.x + 1, y: self.y },Direction::D => Point { x: self.x, y: self.y + 1 },Direction::L => Point { x: self.x - 1, y: self.y },}}}struct Steps<I> {point: Point,segment: Segment,source: I,}impl<I: Iterator<Item=Segment>> Steps<I> {pub fn new(source: I) -> Self {Steps {point: Point {x: 0, y: 0},segment: Segment {direction: Direction::U, length: 0},source: source,}}}impl<I: Iterator<Item=Segment>> Iterator for Steps<I> {type Item = Point;fn next(&mut self) -> Option<Point> {if self.segment.length == 0 {match self.source.next() {None => None,Some(seg) => {self.segment = seg;self.next()},}} else {self.point = self.point + self.segment.direction;self.segment.length -= 1;Some(self.point)}}}fn next_direction<I: Iterator<Item=char>>(i: &mut Peekable<I>) -> Option<Direction> {i.peek().and_then(|c| match c {'U' => Some(Direction::U),'R' => Some(Direction::R),'D' => Some(Direction::D),'L' => Some(Direction::L),_ => None,}).map(|d| {i.next();d})}struct SegmentIter<I: Iterator<Item=char>> { inner: Peekable<I> }impl<I: Iterator<Item=char>> SegmentIter<I> {fn new(original: I) -> Self {SegmentIter { inner: original.peekable(), }}fn next_line(&mut self) {if self.inner.peek().map_or(false,|c| *c == '\n') {self.inner.next();}}}impl<I: Iterator<Item=char>> Iterator for SegmentIter<I> {type Item = Segment;fn next(&mut self) -> Option<Segment> {let r = next_direction(&mut self.inner).and_then(|d| next_number(&mut self.inner).map(|s| Segment {direction: d,length: s,}));if r.is_some() && self.inner.peek().map_or(false, |c| *c == ',') {self.inner.next();}r}}fn next_number<I: Iterator<Item=char>>(i: &mut Peekable<I>) -> Option<i64> {i.peek().and_then(|c| c.to_digit(10)).and_then(|d| {i.next();let mut d = d as i64;loop {match i.peek().and_then(|c| c.to_digit(10)) {Some(d2) => {d = d * 10 + d2 as i64;i.next();},None => {break Some(d);},}}})}fn main() {let args: Vec<_> = env::args().collect();let file = std::fs::read_to_string(&args[1]).expect("Could not read the file");let mut stream = SegmentIter::new(file.chars());let wires: [Vec<Segment>; 2] = {let stream = &mut stream;let wire0 = stream.collect();stream.next_line();let wire1 = stream.collect();[wire0,wire1]};let mut w0s = HashMap::new();for (i,p) in Steps::new(wires[0].iter().map(|x|*x)).enumerate() {if !w0s.contains_key(&p) {w0s.insert(p,i as u64);}}let mut md = u64::MAX;for (i,p) in Steps::new(wires[1].iter().map(|x|*x)).enumerate() {if let Some(i0) = w0s.get(&p) {let s = i0 + i as u64 + 2;if s < md {md = s;}}}println!("{:?}", md)}