···11use crate::solutions::year_2022::{
22- Day10, Day11, Day12, Day2, Day3, Day4, Day5, Day6, Day7, Day8, Day9,
22+ Day10, Day11, Day12, Day2, Day22, Day3, Day4, Day5, Day6, Day7, Day8, Day9,
33};
44use aoc_lib::Solver;
55pub mod solutions;
6677fn main() {
88- let sol = Day12::solve_part2();
88+ let sol = Day22::solve_part2();
99 println!("{:?}", sol);
1010}
+701
src/solutions/year_2022/day22.rs
···11+use std::{fmt::Debug, iter::repeat_with};
22+33+use aoc_lib::{Input, Solver};
44+use nom::{
55+ character::complete::{anychar, digit1},
66+ combinator::{map_res, opt},
77+ multi::many1,
88+ sequence::pair,
99+ IResult,
1010+};
1111+1212+pub struct Day22 {}
1313+1414+const CUBE_FACES: [[(usize, usize); 4]; 6] = [
1515+ [(0, 50), (0, 99), (49, 50), (49, 99)], // back
1616+ [(0, 100), (0, 149), (49, 100), (49, 149)], // left
1717+ [(50, 50), (50, 99), (99, 50), (99, 99)], // top
1818+ [(100, 50), (100, 99), (149, 50), (149, 99)], // front
1919+ [(100, 0), (100, 49), (149, 0), (149, 49)], // right
2020+ [(150, 0), (150, 49), (199, 0), (199, 49)], // base
2121+];
2222+2323+const EDGE_WRAPS: [[[(usize, usize); 2]; 4]; 6] = [
2424+ // [ Right , Left , Top , Bottom ]
2525+ [
2626+ [(0, 100), (49, 100)],
2727+ [(100, 0), (149, 0)],
2828+ [(150, 0), (199, 0)],
2929+ [(50, 50), (50, 99)],
3030+ ], // back
3131+ [
3232+ [(149, 99), (100, 99)],
3333+ [(0, 99), (49, 99)],
3434+ [(199, 0), (199, 49)],
3535+ [(50, 99), (99, 99)],
3636+ ], // left
3737+ [
3838+ [(49, 100), (49, 149)],
3939+ [(100, 0), (100, 49)],
4040+ [(49, 50), (49, 99)],
4141+ [(100, 50), (100, 99)],
4242+ ], // top
4343+ [
4444+ [(49, 149), (49, 100)],
4545+ [(100, 49), (149, 99)],
4646+ [(99, 50), (99, 99)],
4747+ [(100, 49), (199, 49)],
4848+ ], // front
4949+ [
5050+ [(100, 50), (149, 50)],
5151+ [(49, 50), (0, 50)],
5252+ [(50, 50), (99, 50)],
5353+ [(150, 0), (150, 49)],
5454+ ], // right
5555+ [
5656+ [(149, 50), (149, 99)],
5757+ [(0, 50), (0, 99)],
5858+ [(149, 0), (149, 49)],
5959+ [(0, 100), (0, 149)],
6060+ ], // base
6161+];
6262+6363+impl Solver for Day22 {
6464+ type OutputPart1 = usize;
6565+6666+ type OutputPart2 = usize;
6767+6868+ fn day() -> u8 {
6969+ 22
7070+ }
7171+7272+ fn solution_part1(input: aoc_lib::Input) -> Option<Self::OutputPart1> {
7373+ let (mut board, commands) = Board::setup(input);
7474+ commands.iter().for_each(|c| {
7575+ board.play(c, false);
7676+ });
7777+ let (x, y, f) = board.current_pos;
7878+7979+ Some(1000 * (x + 1) + 4 * (y + 1) + usize::from(f))
8080+ }
8181+8282+ fn solution_part2(input: aoc_lib::Input) -> Option<Self::OutputPart2> {
8383+ let (mut board, commands) = Board::setup(input);
8484+ commands.iter().for_each(|c| {
8585+ board.play(c, true);
8686+ });
8787+ let (x, y, f) = board.current_pos;
8888+8989+ Some(1000 * (x + 1) + 4 * (y + 1) + usize::from(f))
9090+ }
9191+}
9292+9393+#[derive(Debug)]
9494+enum CubeFaces {
9595+ Top(usize, usize),
9696+ Back(usize, usize),
9797+ Front(usize, usize),
9898+ Left(usize, usize),
9999+ Right(usize, usize),
100100+ Base(usize, usize),
101101+}
102102+103103+impl From<(usize, usize)> for CubeFaces {
104104+ fn from(i: (usize, usize)) -> Self {
105105+ match i {
106106+ (x, y) if (0..50).contains(&x) && (50..100).contains(&y) => CubeFaces::Back(x, y),
107107+ (x, y) if (0..50).contains(&x) && (100..150).contains(&y) => CubeFaces::Left(x, y),
108108+ (x, y) if (50..100).contains(&x) && (50..100).contains(&y) => CubeFaces::Top(x, y),
109109+ (x, y) if (100..150).contains(&x) && (50..100).contains(&y) => CubeFaces::Front(x, y),
110110+ (x, y) if (100..150).contains(&x) && (0..50).contains(&y) => CubeFaces::Right(x, y),
111111+ (x, y) if (150..200).contains(&x) && (0..50).contains(&y) => CubeFaces::Base(x, y),
112112+ _ => unreachable!(""),
113113+ }
114114+ }
115115+}
116116+117117+impl CubeFaces {
118118+ fn next_cell(&self, dir: Facing) -> (usize, usize) {
119119+ println!("{:?}", self);
120120+ let handle_back = |(&x, &y): (&usize, &usize)| {
121121+ let (start_x, start_y) = (CUBE_FACES[0][0].0, CUBE_FACES[0][0].1);
122122+ let (end_x, end_y) = (CUBE_FACES[0][3].0, CUBE_FACES[0][3].1);
123123+ let (dx, dy) = (x - start_x, y - start_y);
124124+ match dir {
125125+ Facing::Right => {
126126+ let ny = y + 1;
127127+ if ny > end_y {
128128+ (EDGE_WRAPS[0][0][0].0 + dx, EDGE_WRAPS[0][0][1].1)
129129+ } else {
130130+ (x, ny)
131131+ }
132132+ }
133133+ Facing::Left => {
134134+ let ny = y - 1;
135135+ if ny < start_y {
136136+ (EDGE_WRAPS[0][1][0].0 + dx, EDGE_WRAPS[0][1][1].1)
137137+ } else {
138138+ (x, ny)
139139+ }
140140+ }
141141+ Facing::Up => {
142142+ let nx_opt =
143143+ x.checked_sub(1)
144144+ .and_then(|x| if x < start_x { None } else { Some(x) });
145145+ if let Some(nx) = nx_opt {
146146+ (nx, y)
147147+ } else {
148148+ (EDGE_WRAPS[0][2][0].0 + dx, EDGE_WRAPS[0][2][1].1)
149149+ }
150150+ }
151151+ Facing::Down => {
152152+ let nx = x + 1;
153153+ if nx > end_x {
154154+ (EDGE_WRAPS[0][2][0].0, EDGE_WRAPS[0][2][0].1 + dy)
155155+ } else {
156156+ (nx, y)
157157+ }
158158+ }
159159+ }
160160+ };
161161+162162+ let handle_top = |(&x, &y): (&usize, &usize)| {
163163+ let top_face = CUBE_FACES[2];
164164+ let top_edge_wrap = EDGE_WRAPS[2];
165165+ let (start_x, start_y) = (top_face[0].0, top_face[0].1);
166166+ let (end_x, end_y) = (top_face[3].0, top_face[3].1);
167167+ let (dx, dy) = (x - start_x, y - start_y);
168168+ match dir {
169169+ Facing::Right => {
170170+ let ny = y + 1;
171171+ if ny > end_y {
172172+ (top_edge_wrap[0][0].0, top_edge_wrap[0][0].1 + dy)
173173+ } else {
174174+ (x, ny)
175175+ }
176176+ }
177177+ Facing::Left => {
178178+ let ny = y - 1;
179179+ if ny < start_y {
180180+ (top_edge_wrap[1][0].0, top_edge_wrap[1][0].1 + dy)
181181+ } else {
182182+ (x, ny)
183183+ }
184184+ }
185185+ Facing::Up => {
186186+ let nx_opt =
187187+ x.checked_sub(1)
188188+ .and_then(|x| if x < start_x { None } else { Some(x) });
189189+ if let Some(nx) = nx_opt {
190190+ (nx, y)
191191+ } else {
192192+ (top_edge_wrap[2][0].0, top_edge_wrap[2][0].1 + dy)
193193+ }
194194+ }
195195+ Facing::Down => {
196196+ let nx = x + 1;
197197+ if nx > end_x {
198198+ (top_edge_wrap[2][0].0, top_edge_wrap[2][0].1 + dy)
199199+ } else {
200200+ (nx, y)
201201+ }
202202+ }
203203+ }
204204+ };
205205+206206+ let handle_front = |(&x, &y): (&usize, &usize)| {
207207+ let front_face = CUBE_FACES[3];
208208+ let front_edge_wrap = EDGE_WRAPS[3];
209209+ let (start_x, start_y) = (front_face[0].0, front_face[0].1);
210210+ let (end_x, end_y) = (front_face[3].0, front_face[3].1);
211211+ let (dx, dy) = (x - start_x, y - start_y);
212212+ match dir {
213213+ Facing::Right => {
214214+ let ny = y + 1;
215215+ if ny > end_y {
216216+ (front_edge_wrap[0][0].0, front_edge_wrap[0][0].1 - dy)
217217+ } else {
218218+ (x, ny)
219219+ }
220220+ }
221221+ Facing::Left => {
222222+ let ny = y - 1;
223223+ if ny < start_y {
224224+ (front_edge_wrap[1][0].0 + dx, front_edge_wrap[1][0].1 + dy)
225225+ } else {
226226+ (x, ny)
227227+ }
228228+ }
229229+ Facing::Up => {
230230+ let nx_opt =
231231+ x.checked_sub(1)
232232+ .and_then(|x| if x < start_x { None } else { Some(x) });
233233+ if let Some(nx) = nx_opt {
234234+ (nx, y)
235235+ } else {
236236+ (front_edge_wrap[2][0].0, front_edge_wrap[2][0].1 + dy)
237237+ }
238238+ }
239239+ Facing::Down => {
240240+ let nx = x + 1;
241241+ if nx > end_x {
242242+ (front_edge_wrap[2][0].0 + dx, front_edge_wrap[2][1].1)
243243+ } else {
244244+ (nx, y)
245245+ }
246246+ }
247247+ }
248248+ };
249249+250250+ let handle_left = |(&x, &y): (&usize, &usize)| {
251251+ let left_face = CUBE_FACES[1];
252252+ let left_edge_wrap = EDGE_WRAPS[1];
253253+ let (start_x, start_y) = (left_face[0].0, left_face[0].1);
254254+ let (end_x, end_y) = (left_face[3].0, left_face[3].1);
255255+ let (dx, dy) = (x - start_x, y - start_y);
256256+ match dir {
257257+ Facing::Right => {
258258+ let ny = y + 1;
259259+ if ny > end_y {
260260+ (left_edge_wrap[0][0].0 - dx, left_edge_wrap[0][1].1)
261261+ } else {
262262+ (x, ny)
263263+ }
264264+ }
265265+ Facing::Left => {
266266+ let ny = y - 1;
267267+ if ny < start_y {
268268+ (left_edge_wrap[1][0].0 + dx, left_edge_wrap[1][1].1)
269269+ } else {
270270+ (x, ny)
271271+ }
272272+ }
273273+ Facing::Up => {
274274+ let nx_opt =
275275+ x.checked_sub(1)
276276+ .and_then(|x| if x < start_x { None } else { Some(x) });
277277+ if let Some(nx) = nx_opt {
278278+ (nx, y)
279279+ } else {
280280+ (left_edge_wrap[2][0].0, left_edge_wrap[2][0].1 + dy)
281281+ }
282282+ }
283283+ Facing::Down => {
284284+ let nx = x + 1;
285285+ if nx > end_x {
286286+ (left_edge_wrap[2][0].0, left_edge_wrap[2][0].1 + dy)
287287+ } else {
288288+ (nx, y)
289289+ }
290290+ }
291291+ }
292292+ };
293293+294294+ let handle_right = |(&x, &y): (&usize, &usize)| {
295295+ let right_face = CUBE_FACES[4];
296296+ let right_edge_wrap = EDGE_WRAPS[4];
297297+ let (start_x, start_y) = (right_face[0].0, right_face[0].1);
298298+ let (end_x, end_y) = (right_face[3].0, right_face[3].1);
299299+ let (dx, dy) = (x - start_x, y - start_y);
300300+ match dir {
301301+ Facing::Right => {
302302+ let ny = y + 1;
303303+ if ny > end_y {
304304+ (right_edge_wrap[0][0].0 + dx, right_edge_wrap[0][1].1)
305305+ } else {
306306+ (x, ny)
307307+ }
308308+ }
309309+ Facing::Left => {
310310+ let ny_opt =
311311+ y.checked_sub(1)
312312+ .and_then(|y| if y < start_y { None } else { Some(y) });
313313+ if let Some(ny) = ny_opt {
314314+ (x, ny)
315315+ } else {
316316+ (right_edge_wrap[1][0].0 - dx, right_edge_wrap[1][1].1)
317317+ }
318318+ }
319319+ Facing::Up => {
320320+ let nx_opt =
321321+ x.checked_sub(1)
322322+ .and_then(|x| if x < start_x { None } else { Some(x) });
323323+ if let Some(nx) = nx_opt {
324324+ (nx, y)
325325+ } else {
326326+ (right_edge_wrap[2][0].0 + dx, right_edge_wrap[2][1].1)
327327+ }
328328+ }
329329+ Facing::Down => {
330330+ let nx = x + 1;
331331+ if nx > end_x {
332332+ (right_edge_wrap[2][0].0, right_edge_wrap[2][0].1 + dy)
333333+ } else {
334334+ (nx, y)
335335+ }
336336+ }
337337+ }
338338+ };
339339+340340+ let handle_base = |(&x, &y): (&usize, &usize)| {
341341+ let base_face = CUBE_FACES[5];
342342+ let base_edge_wrap = EDGE_WRAPS[5];
343343+ let (start_x, start_y) = (base_face[0].0, base_face[0].1);
344344+ let (end_x, end_y) = (base_face[3].0, base_face[3].1);
345345+ let (dx, dy) = (x - start_x, y - start_y);
346346+ match dir {
347347+ Facing::Right => {
348348+ let ny = y + 1;
349349+ if ny > end_y {
350350+ (base_edge_wrap[0][0].0, base_edge_wrap[0][0].1 + dy)
351351+ } else {
352352+ (x, ny)
353353+ }
354354+ }
355355+ Facing::Left => {
356356+ let ny_opt =
357357+ y.checked_sub(1)
358358+ .and_then(|y| if y < start_y { None } else { Some(y) });
359359+ if let Some(ny) = ny_opt {
360360+ (x, ny)
361361+ } else {
362362+ (base_edge_wrap[1][0].0, base_edge_wrap[1][0].1 + dy)
363363+ }
364364+ }
365365+ Facing::Up => {
366366+ let nx_opt =
367367+ x.checked_sub(1)
368368+ .and_then(|x| if x < start_x { None } else { Some(x) });
369369+ if let Some(nx) = nx_opt {
370370+ (nx, y)
371371+ } else {
372372+ (base_edge_wrap[2][0].0, base_edge_wrap[2][0].1 + dy)
373373+ }
374374+ }
375375+ Facing::Down => {
376376+ let nx = x + 1;
377377+ if nx > end_x {
378378+ (base_edge_wrap[2][0].0, base_edge_wrap[2][0].1 + dy)
379379+ } else {
380380+ (nx, y)
381381+ }
382382+ }
383383+ }
384384+ };
385385+386386+ match self {
387387+ CubeFaces::Top(x, y) => handle_top((x, y)),
388388+ CubeFaces::Back(x, y) => handle_back((x, y)),
389389+ CubeFaces::Front(x, y) => handle_front((x, y)),
390390+ CubeFaces::Left(x, y) => handle_left((x, y)),
391391+ CubeFaces::Right(x, y) => handle_right((x, y)),
392392+ CubeFaces::Base(x, y) => handle_base((x, y)),
393393+ }
394394+ }
395395+}
396396+397397+#[derive(Debug, Copy, Clone, PartialEq, Eq)]
398398+enum Cell {
399399+ Blank,
400400+ Open,
401401+ Wall,
402402+}
403403+404404+impl From<char> for Cell {
405405+ fn from(cell: char) -> Self {
406406+ match cell {
407407+ '#' => Cell::Wall,
408408+ '.' => Cell::Open,
409409+ _ => Cell::Blank,
410410+ }
411411+ }
412412+}
413413+414414+#[derive(Debug, Clone, Copy)]
415415+enum Turn {
416416+ Clockwise,
417417+ CounterClockwise,
418418+}
419419+420420+#[derive(Debug)]
421421+struct Command {
422422+ steps: usize,
423423+ turn: Option<Turn>,
424424+}
425425+426426+impl Command {
427427+ fn parse(input: &str) -> Vec<(usize, Option<char>)> {
428428+ let p: IResult<&str, Vec<(usize, Option<char>)>> = many1(pair(
429429+ map_res(digit1, |d: &str| d.parse::<usize>()),
430430+ opt(anychar),
431431+ ))(input);
432432+ p.expect("could not parse commands").1
433433+ }
434434+435435+ fn setup(steps: usize, t: Option<char>) -> Self {
436436+ if let Some(t) = t {
437437+ if t == 'R' {
438438+ Command {
439439+ steps,
440440+ turn: Some(Turn::Clockwise),
441441+ }
442442+ } else {
443443+ Command {
444444+ steps,
445445+ turn: Some(Turn::CounterClockwise),
446446+ }
447447+ }
448448+ } else {
449449+ Command { steps, turn: None }
450450+ }
451451+ }
452452+}
453453+454454+#[derive(Debug, Clone, Copy)]
455455+enum Facing {
456456+ Right,
457457+ Left,
458458+ Up,
459459+ Down,
460460+}
461461+462462+impl Facing {
463463+ fn turn(&self, t: Turn) -> Self {
464464+ match self {
465465+ Facing::Right => match t {
466466+ Turn::Clockwise => Facing::Down,
467467+ Turn::CounterClockwise => Facing::Up,
468468+ },
469469+ Facing::Left => match t {
470470+ Turn::Clockwise => Facing::Up,
471471+ Turn::CounterClockwise => Facing::Down,
472472+ },
473473+ Facing::Up => match t {
474474+ Turn::Clockwise => Facing::Right,
475475+ Turn::CounterClockwise => Facing::Left,
476476+ },
477477+ Facing::Down => match t {
478478+ Turn::Clockwise => Facing::Left,
479479+ Turn::CounterClockwise => Facing::Right,
480480+ },
481481+ }
482482+ }
483483+}
484484+485485+impl From<Facing> for usize {
486486+ fn from(f: Facing) -> Self {
487487+ match f {
488488+ Facing::Right => 0,
489489+ Facing::Left => 2,
490490+ Facing::Up => 3,
491491+ Facing::Down => 1,
492492+ }
493493+ }
494494+}
495495+496496+#[derive(Debug)]
497497+struct Board {
498498+ // each row will have list of cells + length of row
499499+ cells: Vec<Vec<Cell>>,
500500+ current_pos: (usize, usize, Facing),
501501+ height: usize,
502502+ width: usize,
503503+}
504504+505505+impl Board {
506506+ fn setup(input: Input) -> (Self, Vec<Command>) {
507507+ let (board_input, commands_input) = input
508508+ .lines
509509+ .split(|p| p.is_empty())
510510+ .collect::<Vec<_>>()
511511+ .split_first()
512512+ .map(|(a, xs)| (*a, *xs.first().expect("commands string is empty")))
513513+ .expect("expecting a proper input");
514514+ let xs = board_input
515515+ .iter()
516516+ .fold((0, (vec![])), |(width, mut xs), l| {
517517+ let mut cs: Vec<Cell> = l.chars().map(Cell::from).collect();
518518+ let c = cs.len();
519519+ if c < width {
520520+ cs.extend(vec![Cell::Blank].repeat(width - c));
521521+ let c = cs.len();
522522+ xs.push((cs, c));
523523+ (c, xs)
524524+ } else {
525525+ xs.push((cs, c));
526526+ (c, xs)
527527+ }
528528+ });
529529+ let cells =
530530+ xs.1.into_iter()
531531+ .map(|(mut cs, sz)| {
532532+ let width = xs.0;
533533+ if sz < width {
534534+ cs.extend(vec![Cell::Blank].repeat(width - sz));
535535+ cs
536536+ } else {
537537+ cs
538538+ }
539539+ })
540540+ .collect::<Vec<_>>();
541541+ let height = cells.len();
542542+ let width = cells.first().map(|f| f.len()).expect("proper width");
543543+ let current_pos = Board::tiles_in_a_dir(&cells, (0, 0), Facing::Right, height, width)
544544+ .find(|o| match o {
545545+ Some((_, _, c)) => match c {
546546+ Cell::Blank => false,
547547+ Cell::Open => true,
548548+ Cell::Wall => false,
549549+ },
550550+ None => false,
551551+ })
552552+ .map(|o| (o.unwrap().0, o.unwrap().1, Facing::Right))
553553+ .unwrap();
554554+555555+ let commands = commands_input
556556+ .first()
557557+ .map(|cs| {
558558+ Command::parse(cs)
559559+ .iter()
560560+ .map(|(sz, c)| Command::setup(*sz, *c))
561561+ .collect::<Vec<_>>()
562562+ })
563563+ .expect("could not parse commands");
564564+565565+ (
566566+ Board {
567567+ cells,
568568+ current_pos,
569569+ height,
570570+ width,
571571+ },
572572+ commands,
573573+ )
574574+ }
575575+576576+ fn tiles_in_a_cube<'a>(
577577+ cells: &'a [Vec<Cell>],
578578+ start: (usize, usize),
579579+ dir: Facing,
580580+ // height: usize,
581581+ // width: usize,
582582+ ) -> Box<dyn Iterator<Item = Option<(usize, usize, Cell)>> + 'a> {
583583+ println!("{:?} {:?}", start, dir);
584584+ let mut current = start;
585585+ Box::new(repeat_with(move || {
586586+ current = CubeFaces::from(current).next_cell(dir);
587587+ println!("{:?}", current);
588588+ let row = cells.get(current.0);
589589+ row.and_then(|r| r.get(current.1).map(|c| (current.0, current.1, *c)))
590590+ }))
591591+ }
592592+593593+ fn tiles_in_a_dir<'a>(
594594+ cells: &'a [Vec<Cell>],
595595+ start: (usize, usize),
596596+ dir: Facing,
597597+ height: usize,
598598+ width: usize,
599599+ ) -> Box<dyn Iterator<Item = Option<(usize, usize, Cell)>> + 'a> {
600600+ match dir {
601601+ Facing::Right => {
602602+ let mut index = start.1;
603603+ Box::new(repeat_with(move || {
604604+ let row = cells.get(start.0);
605605+ let ret = row.and_then(|r| r.get(index).map(|c| (start.0, index, *c)));
606606+ index = (index + 1) % width;
607607+ ret
608608+ }))
609609+ }
610610+ Facing::Left => {
611611+ let mut index = start.1;
612612+ Box::new(repeat_with(move || {
613613+ let row = cells.get(start.0);
614614+ let ret = row.and_then(|r| r.get(index).map(|c| (start.0, index, *c)));
615615+ let i = index.checked_sub(1);
616616+ if let Some(i) = i {
617617+ index = i;
618618+ } else {
619619+ index = width;
620620+ }
621621+ ret
622622+ }))
623623+ }
624624+ Facing::Up => {
625625+ let mut index = start.0;
626626+ Box::new(repeat_with(move || {
627627+ let row = cells.get(index);
628628+ let ret = row.and_then(|r| r.get(start.1).map(|c| (index, start.1, *c)));
629629+ let i = index.checked_sub(1);
630630+ if let Some(i) = i {
631631+ index = i;
632632+ } else {
633633+ index = height;
634634+ }
635635+ ret
636636+ }))
637637+ }
638638+ Facing::Down => {
639639+ let mut index = start.0;
640640+ Box::new(repeat_with(move || {
641641+ let row = cells.get(index);
642642+ let ret = row.and_then(|r| r.get(start.1).map(|c| (index, start.1, *c)));
643643+ index = (index + 1) % height;
644644+ ret
645645+ }))
646646+ }
647647+ }
648648+ }
649649+650650+ fn play(&mut self, command: &Command, follow_cube: bool) -> &mut Self {
651651+ println!("{:?}", command);
652652+ let Command { steps, turn } = command;
653653+ let (x, y, facing) = &self.current_pos;
654654+ let handle_moves = |ms: Box<dyn Iterator<Item = Option<(usize, usize, Cell)>>>| {
655655+ ms.filter(|o| o.map(|(_, _, c)| c != Cell::Blank).unwrap_or(false))
656656+ .enumerate()
657657+ .take_while(|(step, mv)| {
658658+ println!("{:?}", mv);
659659+ mv.map(|(_, _, cell)| {
660660+ if cell == Cell::Wall {
661661+ false
662662+ } else {
663663+ step <= steps
664664+ }
665665+ })
666666+ .unwrap_or(false)
667667+ })
668668+ .map(|x| x.1.expect("could not play"))
669669+ .last()
670670+ };
671671+ if let Some(turn) = turn {
672672+ let moves = {
673673+ if !follow_cube {
674674+ Board::tiles_in_a_dir(&self.cells, (*x, *y), *facing, self.height, self.width)
675675+ } else {
676676+ Board::tiles_in_a_cube(&self.cells, (*x, *y), *facing)
677677+ }
678678+ };
679679+ let facing = facing.turn(*turn);
680680+ if let Some((x, y, _)) = handle_moves(moves) {
681681+ self.current_pos = (x, y, facing)
682682+ } else {
683683+ self.current_pos = (*x, *y, facing)
684684+ }
685685+ } else {
686686+ let moves = {
687687+ if !follow_cube {
688688+ Board::tiles_in_a_dir(&self.cells, (*x, *y), *facing, self.height, self.width)
689689+ } else {
690690+ Board::tiles_in_a_cube(&self.cells, (*x, *y), *facing)
691691+ }
692692+ };
693693+ if let Some((x, y, _)) = handle_moves(moves) {
694694+ self.current_pos = (x, y, *facing)
695695+ } else {
696696+ self.current_pos = (*x, *y, *facing)
697697+ }
698698+ }
699699+ self
700700+ }
701701+}
+2
src/solutions/year_2022/mod.rs
···1010mod day10;
1111mod day11;
1212mod day12;
1313+mod day22;
1314pub(crate) use day1::*;
1415pub(crate) use day2::*;
1516pub(crate) use day3::*;
···2223pub(crate) use day10::*;
2324pub(crate) use day11::*;
2425pub(crate) use day12::*;
2626+pub(crate) use day22::*;