Data commit

This commit is contained in:
Ingy döt Net 2023-07-01 11:58:00 -04:00
parent 7387c8f97b
commit cb5bb5e222
199093 changed files with 3378972 additions and 0 deletions

View file

@ -0,0 +1,202 @@
const NR: [i32; 16] = [3, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3];
const NC: [i32; 16] = [3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2];
const I: u8 = 1;
const G: u8 = 8;
const E: u8 = 2;
const L: u8 = 4;
struct FifteenSolver {
n: usize,
limit: usize,
n0: [i32; 85],
n3: [u8; 85],
n4: [usize; 85],
n2: [u64; 85],
}
impl FifteenSolver {
fn f_y(&mut self) -> bool {
if self.n2[self.n] == 0x123456789abcdef0 {
return true;
}
if self.n4[self.n] <= self.limit {
return self.f_n();
}
false
}
fn f_z(&mut self, w: u8) -> bool {
if w & I != 0 {
self.f_i();
if self.f_y() {
return true;
}
self.n -= 1;
}
if w & G != 0 {
self.f_g();
if self.f_y() {
return true;
}
self.n -= 1;
}
if w & E != 0 {
self.f_e();
if self.f_y() {
return true;
}
self.n -= 1;
}
if w & L != 0 {
self.f_l();
if self.f_y() {
return true;
}
self.n -= 1;
}
false
}
fn f_n(&mut self) -> bool {
self.f_z(match self.n0[self.n] {
0 => match self.n3[self.n] {
b'l' => I,
b'u' => E,
_ => I + E,
},
3 => match self.n3[self.n] {
b'r' => I,
b'u' => L,
_ => I + L,
},
1 | 2 => match self.n3[self.n] {
b'l' => I + L,
b'r' => I + E,
b'u' => E + L,
_ => L + E + I,
},
12 => match self.n3[self.n] {
b'l' => G,
b'd' => E,
_ => E + G,
},
15 => match self.n3[self.n] {
b'r' => G,
b'd' => L,
_ => G + L,
},
13 | 14 => match self.n3[self.n] {
b'l' => G + L,
b'r' => E + G,
b'd' => E + L,
_ => G + E + L,
},
4 | 8 => match self.n3[self.n] {
b'l' => I + G,
b'u' => G + E,
b'd' => I + E,
_ => I + G + E,
},
7 | 11 => match self.n3[self.n] {
b'd' => I + L,
b'u' => G + L,
b'r' => I + G,
_ => I + G + L,
},
_ => match self.n3[self.n] {
b'd' => I + E + L,
b'l' => I + G + L,
b'r' => I + G + E,
b'u' => G + E + L,
_ => I + G + E + L,
},
})
}
fn f_i(&mut self) {
let g = (11 - self.n0[self.n]) * 4;
let a = self.n2[self.n] & (15u64 << g);
self.n0[self.n + 1] = self.n0[self.n] + 4;
self.n2[self.n + 1] = self.n2[self.n] - a + (a << 16);
self.n3[self.n + 1] = b'd';
self.n4[self.n + 1] = self.n4[self.n];
let cond = NR[(a >> g) as usize] <= self.n0[self.n] / 4;
if !cond {
self.n4[self.n + 1] += 1;;
}
self.n += 1;
}
fn f_g(&mut self) {
let g = (19 - self.n0[self.n]) * 4;
let a = self.n2[self.n] & (15u64 << g);
self.n0[self.n + 1] = self.n0[self.n] - 4;
self.n2[self.n + 1] = self.n2[self.n] - a + (a >> 16);
self.n3[self.n + 1] = b'u';
self.n4[self.n + 1] = self.n4[self.n];
let cond = NR[(a >> g) as usize] >= self.n0[self.n] / 4;
if !cond {
self.n4[self.n + 1] += 1;
}
self.n += 1;
}
fn f_e(&mut self) {
let g = (14 - self.n0[self.n]) * 4;
let a = self.n2[self.n] & (15u64 << g);
self.n0[self.n + 1] = self.n0[self.n] + 1;
self.n2[self.n + 1] = self.n2[self.n] - a + (a << 4);
self.n3[self.n + 1] = b'r';
self.n4[self.n + 1] = self.n4[self.n];
let cond = NC[(a >> g) as usize] <= self.n0[self.n] % 4;
if !cond {
self.n4[self.n + 1] += 1;
}
self.n += 1;
}
fn f_l(&mut self) {
let g = (16 - self.n0[self.n]) * 4;
let a = self.n2[self.n] & (15u64 << g);
self.n0[self.n + 1] = self.n0[self.n] - 1;
self.n2[self.n + 1] = self.n2[self.n] - a + (a >> 4);
self.n3[self.n + 1] = b'l';
self.n4[self.n + 1] = self.n4[self.n];
let cond = NC[(a >> g) as usize] >= self.n0[self.n] % 4;
if !cond {
self.n4[self.n + 1] += 1;
}
self.n += 1;
}
fn new(n: i32, g: u64) -> Self {
let mut solver = FifteenSolver {
n: 0,
limit: 0,
n0: [0; 85],
n3: [0; 85],
n4: [0; 85],
n2: [0; 85],
};
solver.n0[0] = n;
solver.n2[0] = g;
solver
}
fn solve(&mut self) {
while !self.f_n() {
self.n = 0;
self.limit += 1;
}
println!(
"Solution found in {} moves: {}",
self.n,
std::str::from_utf8(&self.n3[1..=self.n]).unwrap()
);
}
}
fn main() {
FifteenSolver::new(8, 0xfe169b4c0a73d852).solve();
}

View file

@ -0,0 +1,166 @@
use keyed_priority_queue::KeyedPriorityQueue;
use std::cmp::{Ord, Ordering, PartialOrd, Reverse};
static CORRECT_ORDER: [u8; 16] = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0];
static ROW: [i32; 16] = [0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3];
static COLUMN: [i32; 16] = [0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3];
#[derive(Debug, Clone)]
struct State {
est_tot_moves: u8,
moves: String,
est_moves_rem: u8,
}
impl PartialOrd for State {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
Some(self.est_tot_moves.cmp(&other.est_tot_moves))
}
}
impl Eq for State {}
impl PartialEq for State {
fn eq(&self, other: &Self) -> bool {
self.est_tot_moves.cmp(&other.est_tot_moves) == Ordering::Equal
}
}
impl Ord for State {
fn cmp(&self, other: &Self) -> Ordering {
self.est_tot_moves
.partial_cmp(&other.est_tot_moves)
.unwrap()
}
}
impl State {
fn init(order: &[u8; 16]) -> State {
State {
est_tot_moves: State::estimate_moves(&order),
moves: String::from(""),
est_moves_rem: 0,
}
}
fn find_index(order: &[u8; 16], tile: &u8) -> usize {
order.iter().position(|&x| x == *tile).unwrap()
}
fn estimate_moves(current: &[u8; 16]) -> u8 {
let mut h = 0;
for tile in current.iter() {
let current_index = State::find_index(current, &tile);
let correct_index = State::find_index(&CORRECT_ORDER, &tile);
h += ((COLUMN[current_index] - COLUMN[correct_index]).abs()
+ (ROW[current_index] - ROW[correct_index]).abs()) as u8;
}
h
}
fn make_move(
&self,
order: &[u8; 16],
dir: fn(usize, [u8; 16]) -> ([u8; 16], String),
) -> ([u8; 16], State) {
let est_moves_rem = State::estimate_moves(order);
let (new_order, from) = dir(State::find_index(order, &0), *order);
let moves = format!("{}{}", self.moves, from);
let new_state = State {
est_tot_moves: moves.len() as u8 + est_moves_rem,
moves,
est_moves_rem,
};
return (new_order, new_state);
}
fn left(index: usize, mut order: [u8; 16]) -> ([u8; 16], String) {
order.swap(index, index - 1);
return (order, String::from("l"));
}
fn right(index: usize, mut order: [u8; 16]) -> ([u8; 16], String) {
order.swap(index, index + 1);
return (order, String::from("r"));
}
fn up(index: usize, mut order: [u8; 16]) -> ([u8; 16], String) {
order.swap(index, index - 4);
return (order, String::from("u"));
}
fn down(index: usize, mut order: [u8; 16]) -> ([u8; 16], String) {
order.swap(index, index + 4);
return (order, String::from("d"));
}
fn children(&self, order: &[u8; 16]) -> Vec<([u8; 16], State)> {
let index = State::find_index(order, &0);
let mut new_states: Vec<([u8; 16], State)> = Vec::new();
if COLUMN[index] > 0 {
new_states.push(self.make_move(order, State::left))
}
if COLUMN[index] < 3 {
new_states.push(self.make_move(order, State::right))
}
if ROW[index] > 0 {
new_states.push(self.make_move(order, State::up))
}
if ROW[index] < 3 {
new_states.push(self.make_move(order, State::down))
}
new_states
}
}
fn main() {
let mut open_states = KeyedPriorityQueue::<[u8; 16], Reverse<State>>::new();
let start_order = [15, 14, 1, 6, 9, 11, 4, 12, 0, 10, 7, 3, 13, 8, 5, 2];
// let start_order = [0, 1, 2, 3, 5, 6, 7, 4, 9, 10, 11, 8, 13, 14, 15, 12];
open_states.push(start_order, Reverse(State::init(&start_order)));
let mut closed_states = KeyedPriorityQueue::<[u8; 16], Reverse<State>>::new();
'outer: while let Some((parent_order, Reverse(parent_state))) = open_states.pop() {
for (child_order, child_state) in parent_state.children(&parent_order) {
match (
open_states.get_priority(&child_order).as_ref(),
closed_states.get_priority(&child_order).as_ref(),
) {
(None, None) => {
if child_order == CORRECT_ORDER {
println!("There are {} entries in the open list.", open_states.len());
println!(
"There are {} entries in the closed list.",
closed_states.len()
);
println!(
"Reaching the final board took {} moves.",
child_state.moves.len()
);
println!("The moves used were {}.", child_state.moves);
println!(
"The final order is:\n{:?}\n{:?}\n{:?}\n{:?}.",
&child_order[0..4],
&child_order[4..8],
&child_order[8..12],
&child_order[12..16]
);
break 'outer;
}
open_states.push(child_order, Reverse(child_state.clone()));
}
(Some(&Reverse(open_state)), None)
if open_state.moves.len() > child_state.moves.len() =>
{
open_states.set_priority(&child_order, Reverse(child_state.clone()));
}
// (None, Some(&Reverse(closed_state))) if closed_state.moves.len() > child_state.moves.len() => {
// closed_states.remove_item(&child_order);
// open_states.push(child_order, Reverse(child_state.clone()));
// },
_ => {}
};
}
closed_states.push(parent_order, Reverse(parent_state));
}
}