From 14832c8d713383c3ca2850f118b2ee1996494ae3 Mon Sep 17 00:00:00 2001 From: Daniel Bulant Date: Thu, 18 Nov 2021 21:44:37 +0100 Subject: [PATCH] get started with rust --- index.js | 67 ++++++++++++++++++++++++++++++--- rust/.gitignore | 14 +++++++ rust/Cargo.toml | 8 ++++ rust/src/main.rs | 98 ++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 181 insertions(+), 6 deletions(-) create mode 100644 rust/.gitignore create mode 100644 rust/Cargo.toml create mode 100644 rust/src/main.rs diff --git a/index.js b/index.js index 9ec8b21..39a216d 100644 --- a/index.js +++ b/index.js @@ -1,13 +1,15 @@ -const { performance } = require("perf_hooks"); +// const { performance } = require("perf_hooks"); const DB = 0, DT = 1, GB = 2, GT = 3, MB = 4, MT = 5, WB = 6, WT = 7; -const startNow = performance.now(); -const now = () => performance.now() - startNow; +const startNow = Date.now(); +const now = () => Date.now() - startNow; const log = (...str) => console.log(Math.round(now()).toString().padStart(5, "0"), ...str); +var int = false; class Piece extends Array { rotate(num = 1) { + return ; for (let i = 0; i < num; i++) { this.push(this.shift()); } @@ -48,6 +50,8 @@ const pieces = [ P(GB, MT, DB, MB), ]; +var total = 0; + class Game { /** * @param {Piece[]} pieces @@ -78,6 +82,7 @@ class Game { } else throw new Error("What the fuck"); if (first % 2 === 0 && second - first !== 1) return false; if (first % 2 !== 0 && first - second !== 1) return false; + return true; } check() { @@ -89,21 +94,71 @@ class Game { } } + /** + * Runs for each possible position (permutation), checks all rotations. + */ + solve() { + if(this.check()) return true; + for(let a = 0; a < 4; a++) { + this.pieces[0].rotate(); + for(let b = 0; b < 4; b++) { + this.pieces[1].rotate(); + for(let c = 0; c < 4; c++) { + this.pieces[2].rotate(); + for(let d = 0; d < 4; d++) { + this.pieces[3].rotate(); + for(let e = 0; e < 4; e++) { + this.pieces[4].rotate(); + for(let f = 0; f < 4; f++) { + this.pieces[5].rotate(); + for(let g = 0; g < 4; g++) { + this.pieces[6].rotate(); + for(let h = 0; h < 4; h++) { + this.pieces[7].rotate(); + for(let i = 0; i < 4; i++) { + this.pieces[8].rotate(); + total++; + // if(this.check()) return true; + if(int) { + console.log(this.pieces); + return; + } + } + } + } + } + } + } + } + } + } + return false; + } + + /** + * Gets all permutations (i.e. possible positions) of the piece array, and calls solve on all of them. + */ static solve() { const permutations = permutator(pieces); var i = 0; for(const permutation of permutations) { i++; const game = new Game(permutation); - if(game.check()) { + if(game.solve()) { log("Got a HIT"); log(game, game.pieces); return; } if(i % 10 === 0) - log(`total ${permutations.length}, checked ${i}`); + log(`total ${permutations.length}, checked ${i} int ${int}`); + if(int) return; } } } -Game.solve(); \ No newline at end of file +process.on("SIGINT", () => { + int = true; +}) + +Game.solve(); +console.log(total); \ No newline at end of file diff --git a/rust/.gitignore b/rust/.gitignore new file mode 100644 index 0000000..ada8be9 --- /dev/null +++ b/rust/.gitignore @@ -0,0 +1,14 @@ +# Generated by Cargo +# will have compiled files and executables +debug/ +target/ + +# Remove Cargo.lock from gitignore if creating an executable, leave it for libraries +# More information here https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html +Cargo.lock + +# These are backup files generated by rustfmt +**/*.rs.bk + +# MSVC Windows builds of rustc generate these, which store debugging information +*.pdb \ No newline at end of file diff --git a/rust/Cargo.toml b/rust/Cargo.toml new file mode 100644 index 0000000..1ec6963 --- /dev/null +++ b/rust/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "rust" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] diff --git a/rust/src/main.rs b/rust/src/main.rs new file mode 100644 index 0000000..d8376ec --- /dev/null +++ b/rust/src/main.rs @@ -0,0 +1,98 @@ + +#[derive(Default)] +struct Piece { + offset: usize, + array: [u8; 4] +} + + +const DB: u8 = 0b000; +const DT: u8 = 0b100; +const GB: u8 = 0b001; +const GT: u8 = 0b101; +const MB: u8 = 0b010; +const MT: u8 = 0b110; +const WB: u8 = 0b011; +const WT: u8 = 0b111; + +const pieces: [Piece; 9] = [ + Piece { offset: 0, array: [WB, MT, GT, DB] }, + Piece { offset: 0, array: [DB, WT, GT, MB] }, + Piece { offset: 0, array: [GB, MT, DT, WB] }, + Piece { offset: 0, array: [GB, MT, DT, WB] }, + Piece { offset: 0, array: [GB, WT, DT, MB] }, + Piece { offset: 0, array: [DB, WT, GT, WB] }, + Piece { offset: 0, array: [DB, GB, WT, MT] }, + Piece { offset: 0, array: [DB, MT, WT, GB] }, + Piece { offset: 0, array: [GB, MT, DB, MB] }, +]; + +trait Pieces { + fn get(self: &'static Self, x: usize, y: usize) -> &'static Piece; + fn check_piece(self: &'static Self, x1: usize, y1: usize, x2: usize, y2: usize) -> bool; + fn check_game(self: &'static Self) -> bool; + fn solve(&'static self) -> bool; +} + +impl Pieces for [Piece; 9] { + fn get(self: &'static Self, x: usize, y: usize) -> &'static Piece { + &self[x * 3 + y] + } + + fn check_piece(self: &'static Self, x1: usize, y1: usize, x2: usize, y2: usize) -> bool { + let first_piece = self.get(x1, y1); + let second_piece = self.get(x2, y2); + let first_num: u8; + let second_num: u8; + if x1 == x2 + 1 { + first_num = first_piece.array[(3 + first_piece.offset) % 4]; + second_num = second_piece.array[(1 + first_piece.offset) % 4]; + } else if x1 == x2 - 1 { + first_num = first_piece.array[(1 + first_piece.offset) % 4]; + second_num = second_piece.array[(3 + first_piece.offset) % 4]; + } else if y1 == y2 + 1 { + first_num = first_piece.array[(2 + first_piece.offset) % 4]; + second_num = second_piece.array[(0 + first_piece.offset) % 4]; + } else if y1 == y2 - 1 { + first_num = first_piece.array[(0 + first_piece.offset) % 4]; + second_num = second_piece.array[(2 + first_piece.offset) % 4]; + } else { + panic!("Invalid check"); + } + if ((first_num >> 1) & (second_num >> 1) == first_num >> 1) && ((first_num & 1) ^ (second_num & 1) == 0) { + return true; + } + false + } + + fn check_game(self: &'static Self) -> bool { + for x in 0..3 { + for y in 0..3 { + if x < 2 && self.check_piece(x, y, x + 1, y) { + return false; + } + if y < 2 && self.check_piece(x, y, x, y + 2) { + return false; + } + } + } + true + } + + fn solve(&'static self) -> bool { + if self.check_game() { + return true; + } + for _ in 1..4 { + self[0].offset += 1; + if self.check_game() { + return true; + } + } + false + } +} + +fn main() { + +}