get started with rust

This commit is contained in:
Daniel Bulant 2021-11-18 21:44:37 +01:00
parent 24078c7065
commit 14832c8d71
4 changed files with 181 additions and 6 deletions

View file

@ -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 DB = 0, DT = 1, GB = 2, GT = 3, MB = 4, MT = 5, WB = 6, WT = 7;
const startNow = performance.now(); const startNow = Date.now();
const now = () => performance.now() - startNow; const now = () => Date.now() - startNow;
const log = (...str) => console.log(Math.round(now()).toString().padStart(5, "0"), ...str); const log = (...str) => console.log(Math.round(now()).toString().padStart(5, "0"), ...str);
var int = false;
class Piece extends Array { class Piece extends Array {
rotate(num = 1) { rotate(num = 1) {
return ;
for (let i = 0; i < num; i++) { for (let i = 0; i < num; i++) {
this.push(this.shift()); this.push(this.shift());
} }
@ -48,6 +50,8 @@ const pieces = [
P(GB, MT, DB, MB), P(GB, MT, DB, MB),
]; ];
var total = 0;
class Game { class Game {
/** /**
* @param {Piece[]} pieces * @param {Piece[]} pieces
@ -78,6 +82,7 @@ class Game {
} else throw new Error("What the fuck"); } else throw new Error("What the fuck");
if (first % 2 === 0 && second - first !== 1) return false; if (first % 2 === 0 && second - first !== 1) return false;
if (first % 2 !== 0 && first - second !== 1) return false; if (first % 2 !== 0 && first - second !== 1) return false;
return true;
} }
check() { 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() { static solve() {
const permutations = permutator(pieces); const permutations = permutator(pieces);
var i = 0; var i = 0;
for(const permutation of permutations) { for(const permutation of permutations) {
i++; i++;
const game = new Game(permutation); const game = new Game(permutation);
if(game.check()) { if(game.solve()) {
log("Got a HIT"); log("Got a HIT");
log(game, game.pieces); log(game, game.pieces);
return; return;
} }
if(i % 10 === 0) if(i % 10 === 0)
log(`total ${permutations.length}, checked ${i}`); log(`total ${permutations.length}, checked ${i} int ${int}`);
if(int) return;
} }
} }
} }
Game.solve(); process.on("SIGINT", () => {
int = true;
})
Game.solve();
console.log(total);

14
rust/.gitignore vendored Normal file
View file

@ -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

8
rust/Cargo.toml Normal file
View file

@ -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]

98
rust/src/main.rs Normal file
View file

@ -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() {
}