aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/tests/Cargo.lock9
-rw-r--r--src/tests/Cargo.toml4
-rw-r--r--src/tests/aoc-2022-05/Cargo.toml17
-rw-r--r--src/tests/aoc-2022-05/benches/main.rs39
-rw-r--r--src/tests/aoc-2022-05/src/lib.rs749
5 files changed, 817 insertions, 1 deletions
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
@@ -21,6 +21,15 @@ dependencies = [
]
[[package]]
+name = "aoc-2022-05"
+version = "0.1.0"
+dependencies = [
+ "criterion",
+ "primrose-library",
+ "rand",
+]
+
+[[package]]
name = "atty"
version = "0.2.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
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<Option<Box<Crate>>>;
+
+/// Base type for a crate
+#[derive(Debug, Clone)]
+pub struct Crate {
+ letter: char,
+ below: Option<Box<Crate>>,
+}
+
+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<R: Rng>(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<R: Rng>(rng: &mut R, n: usize) -> Vec<Move> {
+ (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::<Vec<_>>()
+ .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<Item = Move> + '_ {
+ input
+ .lines()
+ .skip_while(|line| !line.starts_with('m'))
+ .flat_map(|line| -> Option<Move> {
+ 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"#;
+}