From b47b4234342c40fca8b45f1387257db6f34522ba Mon Sep 17 00:00:00 2001 From: Aria Shrimpton Date: Fri, 23 Feb 2024 12:36:44 +0000 Subject: non primrosed aoc 2022 05 --- src/tests/Cargo.lock | 9 + src/tests/Cargo.toml | 4 +- src/tests/aoc-2022-05/Cargo.toml | 17 + src/tests/aoc-2022-05/benches/main.rs | 39 ++ src/tests/aoc-2022-05/src/lib.rs | 749 ++++++++++++++++++++++++++++++++++ 5 files changed, 817 insertions(+), 1 deletion(-) create mode 100644 src/tests/aoc-2022-05/Cargo.toml create mode 100644 src/tests/aoc-2022-05/benches/main.rs create mode 100644 src/tests/aoc-2022-05/src/lib.rs (limited to 'src') diff --git a/src/tests/Cargo.lock b/src/tests/Cargo.lock index f16f8c2..3b1b134 100644 --- a/src/tests/Cargo.lock +++ b/src/tests/Cargo.lock @@ -20,6 +20,15 @@ dependencies = [ "rand", ] +[[package]] +name = "aoc-2022-05" +version = "0.1.0" +dependencies = [ + "criterion", + "primrose-library", + "rand", +] + [[package]] name = "atty" version = "0.2.14" diff --git a/src/tests/Cargo.toml b/src/tests/Cargo.toml index d15bd9b..0de0c7f 100644 --- a/src/tests/Cargo.toml +++ b/src/tests/Cargo.toml @@ -1,6 +1,8 @@ [workspace] resolver = "2" -members = [ "aoc-2021-09", +members = [ + "aoc-2021-09", + "aoc-2022-05", "example_sets", "example_stack", "prime_sieve" diff --git a/src/tests/aoc-2022-05/Cargo.toml b/src/tests/aoc-2022-05/Cargo.toml new file mode 100644 index 0000000..940d795 --- /dev/null +++ b/src/tests/aoc-2022-05/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "aoc-2022-05" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +rand = { workspace = true } +primrose-library = { path = "../../crates/library" } + +[dev-dependencies] +criterion = { workspace = true } + +[[bench]] +name = "main" +harness = false diff --git a/src/tests/aoc-2022-05/benches/main.rs b/src/tests/aoc-2022-05/benches/main.rs new file mode 100644 index 0000000..1550359 --- /dev/null +++ b/src/tests/aoc-2022-05/benches/main.rs @@ -0,0 +1,39 @@ +use aoc_2022_05::{gen_random_moves, gen_random_tops, perform_move_9000, perform_move_9001}; +use criterion::{criterion_group, criterion_main, BatchSize, BenchmarkId, Criterion}; +use rand::{rngs::StdRng, SeedableRng}; + +fn run_benches(c: &mut Criterion) { + let mut rng = StdRng::seed_from_u64(42); + for size in [100, 400, 800, 1200, 1600, 2000].iter() { + c.bench_with_input(BenchmarkId::new("part1", size), size, |b, &n| { + b.iter_batched_ref( + || (gen_random_tops(&mut rng, n), gen_random_moves(&mut rng, n)), + |(tops, moves)| { + for mv in moves { + perform_move_9000(tops, *mv); + } + }, + BatchSize::SmallInput, + ) + }); + + c.bench_with_input(BenchmarkId::new("part2", size), size, |b, &n| { + b.iter_batched_ref( + || (gen_random_tops(&mut rng, n), gen_random_moves(&mut rng, n)), + |(tops, moves)| { + for mv in moves { + perform_move_9001(tops, *mv); + } + }, + BatchSize::SmallInput, + ) + }); + } +} + +criterion_group!( + name = benches; + config = Criterion::default().sample_size(10); + targets = run_benches +); +criterion_main!(benches); diff --git a/src/tests/aoc-2022-05/src/lib.rs b/src/tests/aoc-2022-05/src/lib.rs new file mode 100644 index 0000000..97bc28f --- /dev/null +++ b/src/tests/aoc-2022-05/src/lib.rs @@ -0,0 +1,749 @@ +#![feature(type_alias_impl_trait)] + +use primrose_library::traits::*; +use rand::{rngs::StdRng, Rng}; +use std::cell::RefCell; + +pub type Tops = List>>; + +/// Base type for a crate +#[derive(Debug, Clone)] +pub struct Crate { + letter: char, + below: Option>, +} + +impl Crate { + pub fn new(letter: char) -> Self { + Self { + letter, + below: None, + } + } +} + +impl Default for Crate { + fn default() -> Self { + Self { + letter: ' ', + below: None, + } + } +} + +/// A move the crane may make +#[derive(Debug, Clone, Copy)] +pub struct Move { + reps: usize, + from: usize, + to: usize, +} + +/// Get the message / the top letters of each stack +pub fn top_letters(tops: Tops) -> String { + tops.iter().map(|x| x.as_ref().unwrap().letter).collect() +} + +/// Perform a move for part 1 +pub fn perform_move_9000(tops: &mut Tops, mv: Move) { + for _ in 0..mv.reps { + let Some(mut from) = tops[mv.from].take() else { + break; + }; + let to = tops[mv.to].take(); + + tops[mv.from] = from.below.take(); + + from.below = to; + tops[mv.to] = Some(from); + } +} + +/// Perform a move for part 2 +pub fn perform_move_9001(tops: &mut Tops, mv: Move) { + let Some(mut pickup_top) = tops[mv.from].take() else { + return; + }; + + let mut pickup_bot = &mut pickup_top; + for _ in 1..mv.reps { + match pickup_bot.below.as_mut() { + Some(x) => pickup_bot = x, + None => return, + } + } + + let to = tops[mv.to].take(); + + tops[mv.from] = pickup_bot.below.take(); + pickup_bot.below = to; + tops[mv.to] = Some(pickup_top); +} + +pub fn gen_random_tops(rng: &mut R, n: usize) -> Tops { + let mut tops: Tops = Default::default(); + for _ in 0..n { + // n columns + tops.push(None); + } + + // n^2 total crates + for _ in 0..n * n { + let idx = rng.gen_range(0..n); + let mut val = Crate::new('A'); + if let Some(below) = tops[idx].take() { + val.below = Some(below); + } + tops[idx] = Some(Box::new(val)); + } + + tops +} + +pub fn gen_random_moves(rng: &mut R, n: usize) -> Vec { + (0..n) + .map(|_| Move { + reps: rng.gen_range(1..5), + from: rng.gen_range(0..n), + to: rng.gen_range(0..n), + }) + .collect() +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_small_part1() { + let mut stacks = construct_piles(SMALL_INPUT); + + println!("before: {:?}", &stacks); + for mv in parse_moves(SMALL_INPUT) { + perform_move_9000(&mut stacks, mv); + dbg!(mv, &stacks); + } + println!("after: {:?}", &stacks); + + assert_eq!(top_letters(stacks), "CMZ"); + } + + #[test] + fn test_small_part2() { + let mut stacks = construct_piles(SMALL_INPUT); + + println!("before: {:?}", &stacks); + for mv in parse_moves(SMALL_INPUT) { + perform_move_9000(&mut stacks, mv); + dbg!(mv, &stacks); + } + println!("after: {:?}", &stacks); + + assert_eq!(top_letters(stacks), "CMZ"); + } + + #[test] + fn test_large_part1() { + let mut stacks = construct_piles(LARGE_INPUT); + + println!("before: {:?}", &stacks); + for mv in parse_moves(LARGE_INPUT) { + perform_move_9000(&mut stacks, mv); + dbg!(mv, &stacks); + } + println!("after: {:?}", &stacks); + + assert_eq!(top_letters(stacks), "VRWBSFZWM"); + } + + #[test] + fn test_large_part2() { + let mut stacks = construct_piles(LARGE_INPUT); + + println!("before: {:?}", &stacks); + for mv in parse_moves(LARGE_INPUT) { + perform_move_9001(&mut stacks, mv); + dbg!(mv, &stacks); + } + println!("after: {:?}", &stacks); + + assert_eq!(top_letters(stacks), "RBTWJWMCF"); + } + + // Annoying parsing code + + pub fn construct_piles(input: &str) -> Tops { + let mut piles = Vec::new(); + for layer_iter in input + .lines() + .take_while(|x| x.chars().find(|x| *x != ' ').unwrap() == '[') + .map(|x| x.chars().skip(1).step_by(4)) + .collect::>() + .into_iter() + .rev() + // go bottom to top + { + for (stack, chr) in layer_iter.enumerate() { + if piles.len() < stack + 1 { + piles.resize(stack + 1, None); + } + + if chr != ' ' { + let mut val = Box::new(Crate { + letter: chr, + below: None.into(), + }); + + if let Some(below) = piles[stack].take() { + val.below = Some(below); + } + piles[stack] = Some(val); + } + } + } + + piles + } + + pub fn parse_moves(input: &str) -> impl Iterator + '_ { + input + .lines() + .skip_while(|line| !line.starts_with('m')) + .flat_map(|line| -> Option { + let line = line.split_once("move ")?.1; + let (reps, line) = line.split_once(" from ")?; + let (from, to) = line.split_once(" to ")?; + + let reps: usize = reps.parse().ok()?; + let from: usize = from.parse().ok()?; + let to: usize = to.parse().ok()?; + + Some(Move { + reps, + from: from - 1, + to: to - 1, + }) + }) + } + const SMALL_INPUT: &str = r#" [D] +[N] [C] +[Z] [M] [P] + 1 2 3 + +move 1 from 2 to 1 +move 3 from 1 to 3 +move 2 from 2 to 1 +move 1 from 1 to 2"#; + + const LARGE_INPUT: &str = r#" [J] [B] [W] + [T] [W] [F] [R] [Z] + [Q] [M] [J] [R] [W] [H] + [F] [L] [P] [R] [N] [Z] [G] +[F] [M] [S] [Q] [M] [P] [S] [C] +[L] [V] [R] [V] [W] [P] [C] [P] [J] +[M] [Z] [V] [S] [S] [V] [Q] [H] [M] +[W] [B] [H] [F] [L] [F] [J] [V] [B] + 1 2 3 4 5 6 7 8 9 + +move 3 from 5 to 7 +move 2 from 8 to 9 +move 4 from 3 to 5 +move 2 from 1 to 7 +move 1 from 3 to 6 +move 2 from 1 to 7 +move 1 from 8 to 7 +move 4 from 2 to 8 +move 10 from 9 to 1 +move 6 from 6 to 2 +move 1 from 6 to 7 +move 9 from 8 to 6 +move 4 from 2 to 4 +move 2 from 4 to 1 +move 6 from 1 to 6 +move 1 from 3 to 2 +move 2 from 1 to 4 +move 2 from 4 to 3 +move 2 from 1 to 3 +move 4 from 3 to 1 +move 15 from 7 to 9 +move 4 from 5 to 9 +move 13 from 9 to 4 +move 10 from 4 to 8 +move 1 from 7 to 4 +move 6 from 9 to 5 +move 11 from 6 to 7 +move 4 from 5 to 7 +move 3 from 8 to 7 +move 4 from 2 to 4 +move 1 from 5 to 1 +move 5 from 8 to 4 +move 1 from 5 to 4 +move 10 from 7 to 1 +move 8 from 7 to 9 +move 12 from 1 to 9 +move 8 from 9 to 1 +move 2 from 6 to 9 +move 2 from 8 to 4 +move 1 from 6 to 9 +move 13 from 4 to 2 +move 13 from 4 to 2 +move 1 from 6 to 1 +move 1 from 6 to 4 +move 1 from 4 to 5 +move 14 from 1 to 8 +move 1 from 5 to 4 +move 13 from 9 to 5 +move 9 from 8 to 2 +move 8 from 2 to 1 +move 5 from 8 to 2 +move 5 from 1 to 6 +move 3 from 1 to 3 +move 1 from 4 to 8 +move 9 from 5 to 9 +move 18 from 2 to 8 +move 3 from 3 to 5 +move 2 from 6 to 4 +move 14 from 2 to 7 +move 1 from 4 to 2 +move 1 from 6 to 9 +move 1 from 2 to 5 +move 1 from 6 to 2 +move 1 from 4 to 6 +move 6 from 8 to 1 +move 2 from 6 to 9 +move 5 from 5 to 3 +move 1 from 7 to 8 +move 10 from 9 to 7 +move 13 from 8 to 5 +move 5 from 5 to 2 +move 6 from 5 to 7 +move 1 from 8 to 5 +move 5 from 5 to 9 +move 5 from 9 to 7 +move 4 from 3 to 8 +move 6 from 1 to 6 +move 4 from 2 to 4 +move 3 from 7 to 5 +move 2 from 2 to 9 +move 1 from 3 to 7 +move 29 from 7 to 9 +move 4 from 5 to 2 +move 5 from 6 to 4 +move 3 from 7 to 9 +move 3 from 8 to 6 +move 1 from 2 to 6 +move 3 from 2 to 5 +move 1 from 8 to 4 +move 1 from 5 to 9 +move 8 from 4 to 9 +move 15 from 9 to 2 +move 1 from 5 to 1 +move 10 from 9 to 4 +move 5 from 4 to 5 +move 5 from 5 to 4 +move 1 from 1 to 9 +move 1 from 4 to 3 +move 8 from 2 to 4 +move 7 from 2 to 7 +move 1 from 3 to 8 +move 1 from 5 to 6 +move 4 from 7 to 3 +move 1 from 8 to 2 +move 7 from 4 to 7 +move 11 from 9 to 7 +move 5 from 4 to 2 +move 3 from 9 to 6 +move 3 from 3 to 8 +move 4 from 2 to 4 +move 5 from 9 to 5 +move 1 from 2 to 1 +move 3 from 8 to 5 +move 2 from 9 to 1 +move 1 from 2 to 5 +move 2 from 9 to 6 +move 3 from 7 to 5 +move 7 from 4 to 1 +move 4 from 4 to 9 +move 3 from 7 to 2 +move 3 from 1 to 9 +move 1 from 2 to 3 +move 2 from 7 to 9 +move 6 from 5 to 4 +move 6 from 4 to 3 +move 5 from 5 to 1 +move 6 from 7 to 8 +move 1 from 5 to 1 +move 2 from 9 to 4 +move 1 from 4 to 3 +move 10 from 6 to 4 +move 2 from 2 to 1 +move 6 from 4 to 1 +move 5 from 8 to 3 +move 1 from 8 to 2 +move 7 from 3 to 9 +move 1 from 6 to 9 +move 2 from 7 to 3 +move 20 from 1 to 6 +move 7 from 3 to 8 +move 2 from 9 to 6 +move 1 from 2 to 3 +move 2 from 3 to 6 +move 1 from 1 to 4 +move 6 from 4 to 7 +move 5 from 8 to 3 +move 22 from 6 to 4 +move 2 from 9 to 7 +move 3 from 3 to 4 +move 6 from 4 to 2 +move 11 from 9 to 3 +move 9 from 3 to 7 +move 5 from 4 to 2 +move 5 from 7 to 2 +move 5 from 7 to 6 +move 10 from 2 to 4 +move 3 from 2 to 1 +move 1 from 6 to 3 +move 1 from 1 to 7 +move 17 from 4 to 1 +move 1 from 8 to 4 +move 2 from 7 to 5 +move 3 from 2 to 5 +move 3 from 3 to 8 +move 4 from 5 to 1 +move 3 from 3 to 7 +move 1 from 4 to 5 +move 21 from 1 to 5 +move 3 from 8 to 3 +move 4 from 7 to 5 +move 1 from 1 to 7 +move 1 from 6 to 3 +move 4 from 4 to 1 +move 1 from 8 to 1 +move 3 from 4 to 9 +move 5 from 1 to 8 +move 3 from 9 to 3 +move 5 from 6 to 1 +move 5 from 1 to 4 +move 6 from 3 to 2 +move 1 from 3 to 2 +move 3 from 8 to 1 +move 7 from 2 to 1 +move 10 from 5 to 2 +move 12 from 5 to 7 +move 2 from 8 to 3 +move 5 from 5 to 8 +move 8 from 1 to 6 +move 5 from 4 to 5 +move 3 from 8 to 6 +move 1 from 8 to 3 +move 6 from 6 to 7 +move 2 from 3 to 8 +move 3 from 2 to 1 +move 6 from 2 to 9 +move 2 from 8 to 4 +move 1 from 3 to 9 +move 1 from 8 to 6 +move 1 from 6 to 9 +move 7 from 9 to 5 +move 1 from 9 to 7 +move 1 from 4 to 6 +move 2 from 6 to 5 +move 1 from 4 to 1 +move 1 from 2 to 7 +move 5 from 1 to 2 +move 10 from 7 to 4 +move 12 from 5 to 7 +move 6 from 4 to 8 +move 2 from 5 to 6 +move 1 from 8 to 9 +move 1 from 9 to 5 +move 30 from 7 to 9 +move 4 from 8 to 4 +move 1 from 8 to 7 +move 2 from 1 to 4 +move 6 from 6 to 3 +move 1 from 4 to 1 +move 1 from 1 to 2 +move 8 from 4 to 8 +move 1 from 4 to 5 +move 2 from 5 to 6 +move 2 from 9 to 8 +move 3 from 2 to 1 +move 4 from 3 to 2 +move 1 from 6 to 4 +move 1 from 7 to 1 +move 2 from 8 to 2 +move 1 from 9 to 2 +move 2 from 3 to 2 +move 1 from 4 to 2 +move 4 from 9 to 6 +move 3 from 6 to 4 +move 21 from 9 to 8 +move 13 from 2 to 7 +move 9 from 8 to 5 +move 3 from 1 to 4 +move 14 from 7 to 2 +move 5 from 8 to 9 +move 1 from 1 to 2 +move 7 from 8 to 6 +move 2 from 8 to 2 +move 8 from 6 to 9 +move 1 from 4 to 5 +move 5 from 8 to 2 +move 4 from 5 to 9 +move 9 from 9 to 6 +move 2 from 7 to 6 +move 1 from 8 to 7 +move 9 from 6 to 4 +move 1 from 6 to 5 +move 1 from 7 to 3 +move 1 from 4 to 7 +move 1 from 7 to 2 +move 9 from 2 to 3 +move 8 from 4 to 1 +move 8 from 9 to 2 +move 2 from 6 to 5 +move 4 from 5 to 2 +move 2 from 9 to 5 +move 1 from 4 to 9 +move 10 from 3 to 7 +move 1 from 9 to 2 +move 1 from 5 to 3 +move 7 from 2 to 8 +move 7 from 1 to 5 +move 1 from 1 to 2 +move 2 from 8 to 2 +move 1 from 3 to 5 +move 2 from 8 to 6 +move 2 from 8 to 9 +move 2 from 4 to 6 +move 3 from 2 to 8 +move 3 from 6 to 7 +move 7 from 5 to 8 +move 7 from 2 to 7 +move 1 from 6 to 8 +move 5 from 2 to 7 +move 6 from 8 to 3 +move 2 from 7 to 1 +move 7 from 2 to 5 +move 1 from 3 to 5 +move 1 from 1 to 5 +move 2 from 9 to 7 +move 4 from 3 to 7 +move 2 from 4 to 6 +move 1 from 1 to 6 +move 1 from 2 to 4 +move 16 from 5 to 6 +move 1 from 4 to 9 +move 19 from 6 to 1 +move 1 from 3 to 5 +move 1 from 9 to 1 +move 1 from 8 to 5 +move 5 from 8 to 3 +move 5 from 7 to 2 +move 3 from 2 to 9 +move 5 from 1 to 7 +move 2 from 5 to 1 +move 3 from 9 to 4 +move 4 from 1 to 9 +move 2 from 2 to 8 +move 2 from 8 to 6 +move 1 from 6 to 9 +move 4 from 3 to 8 +move 4 from 8 to 3 +move 2 from 3 to 8 +move 1 from 8 to 2 +move 1 from 9 to 7 +move 10 from 1 to 7 +move 26 from 7 to 6 +move 3 from 9 to 3 +move 1 from 4 to 6 +move 2 from 1 to 4 +move 1 from 1 to 6 +move 1 from 9 to 3 +move 1 from 2 to 3 +move 4 from 4 to 9 +move 10 from 7 to 8 +move 3 from 7 to 4 +move 4 from 9 to 4 +move 4 from 4 to 7 +move 4 from 3 to 9 +move 5 from 7 to 5 +move 3 from 5 to 1 +move 3 from 9 to 8 +move 3 from 1 to 5 +move 2 from 3 to 5 +move 7 from 8 to 1 +move 7 from 8 to 9 +move 4 from 6 to 3 +move 3 from 3 to 6 +move 1 from 3 to 4 +move 2 from 4 to 1 +move 1 from 9 to 6 +move 4 from 1 to 3 +move 3 from 5 to 1 +move 1 from 5 to 2 +move 6 from 1 to 2 +move 6 from 2 to 7 +move 2 from 7 to 4 +move 1 from 2 to 6 +move 1 from 1 to 4 +move 3 from 5 to 7 +move 6 from 7 to 4 +move 1 from 9 to 3 +move 1 from 3 to 6 +move 4 from 4 to 3 +move 9 from 6 to 1 +move 10 from 1 to 6 +move 7 from 4 to 5 +move 28 from 6 to 4 +move 3 from 6 to 7 +move 3 from 3 to 8 +move 4 from 5 to 7 +move 1 from 8 to 4 +move 18 from 4 to 7 +move 8 from 7 to 6 +move 6 from 4 to 1 +move 2 from 5 to 4 +move 8 from 6 to 1 +move 2 from 8 to 9 +move 1 from 5 to 3 +move 1 from 9 to 1 +move 5 from 9 to 2 +move 2 from 9 to 3 +move 1 from 2 to 5 +move 2 from 1 to 5 +move 6 from 7 to 5 +move 1 from 6 to 4 +move 6 from 5 to 9 +move 2 from 4 to 1 +move 8 from 1 to 8 +move 4 from 9 to 7 +move 1 from 5 to 6 +move 1 from 1 to 6 +move 2 from 1 to 2 +move 1 from 9 to 7 +move 3 from 2 to 4 +move 2 from 8 to 3 +move 5 from 8 to 2 +move 4 from 2 to 5 +move 1 from 8 to 9 +move 12 from 3 to 2 +move 2 from 6 to 2 +move 12 from 2 to 4 +move 6 from 2 to 3 +move 4 from 1 to 9 +move 8 from 4 to 7 +move 3 from 3 to 4 +move 1 from 5 to 4 +move 5 from 9 to 6 +move 3 from 5 to 8 +move 1 from 9 to 1 +move 2 from 8 to 5 +move 3 from 5 to 6 +move 1 from 8 to 4 +move 4 from 7 to 8 +move 1 from 1 to 3 +move 2 from 8 to 3 +move 7 from 6 to 7 +move 1 from 3 to 7 +move 2 from 8 to 6 +move 22 from 7 to 8 +move 6 from 4 to 8 +move 5 from 8 to 6 +move 5 from 6 to 2 +move 4 from 2 to 3 +move 6 from 8 to 5 +move 4 from 4 to 7 +move 1 from 3 to 7 +move 4 from 4 to 5 +move 1 from 5 to 4 +move 2 from 6 to 5 +move 9 from 5 to 6 +move 10 from 6 to 7 +move 1 from 2 to 1 +move 3 from 4 to 8 +move 16 from 7 to 9 +move 1 from 7 to 8 +move 1 from 1 to 8 +move 1 from 8 to 3 +move 2 from 7 to 4 +move 15 from 8 to 1 +move 1 from 8 to 1 +move 4 from 8 to 4 +move 7 from 9 to 7 +move 3 from 5 to 9 +move 10 from 9 to 6 +move 2 from 9 to 2 +move 7 from 7 to 4 +move 9 from 3 to 2 +move 8 from 2 to 7 +move 1 from 8 to 4 +move 3 from 2 to 1 +move 9 from 7 to 1 +move 9 from 4 to 1 +move 2 from 7 to 5 +move 1 from 5 to 4 +move 1 from 5 to 2 +move 6 from 1 to 3 +move 16 from 1 to 2 +move 9 from 2 to 1 +move 5 from 6 to 9 +move 2 from 1 to 9 +move 1 from 2 to 5 +move 4 from 4 to 8 +move 2 from 8 to 2 +move 2 from 2 to 3 +move 17 from 1 to 2 +move 2 from 1 to 9 +move 13 from 2 to 8 +move 1 from 2 to 4 +move 11 from 8 to 3 +move 3 from 3 to 4 +move 3 from 9 to 2 +move 1 from 5 to 2 +move 1 from 9 to 3 +move 3 from 4 to 3 +move 1 from 4 to 9 +move 3 from 3 to 4 +move 1 from 8 to 7 +move 7 from 2 to 9 +move 3 from 1 to 7 +move 3 from 2 to 8 +move 3 from 7 to 9 +move 10 from 3 to 5 +move 3 from 6 to 9 +move 8 from 9 to 4 +move 1 from 2 to 1 +move 1 from 7 to 9 +move 2 from 2 to 3 +move 4 from 4 to 8 +move 1 from 6 to 2 +move 7 from 5 to 3 +move 1 from 5 to 2 +move 9 from 8 to 9 +move 12 from 3 to 8 +move 1 from 1 to 9 +move 9 from 8 to 6 +move 1 from 5 to 7 +move 1 from 5 to 4 +move 2 from 2 to 9 +move 1 from 2 to 6 +move 2 from 4 to 3 +move 9 from 4 to 8 +move 6 from 3 to 6 +move 12 from 6 to 2 +move 2 from 6 to 7 +move 8 from 8 to 3 +move 5 from 8 to 7 +move 3 from 6 to 5 +move 6 from 3 to 7 +move 6 from 7 to 6 +move 1 from 4 to 9 +move 4 from 6 to 5 +move 20 from 9 to 6 +move 4 from 9 to 8 +move 2 from 8 to 7 +move 4 from 6 to 4 +move 10 from 6 to 1"#; +} -- cgit v1.2.3