working on picasso wu

Signed-off-by: Julien CLEMENT <julien.clement@epita.fr>
This commit is contained in:
juju committed 2023-05-03 01:49:47 +02:00
1 parent e11eceaa85
commit 8625c57d1a
15 files changed
+1002 -1

No files matched your search

+131
View File
@@ -0,0 +1,131 @@
uint64_t allowed_moves[0x10][0x5] =
{
[0x0] =
{
[0x0] = 0x0100000000000000
[0x1] = 0x0000100000000000
[0x2] = 0x0000000000000000
[0x3] = 0x0000000000000000
[0x4] = 0x0000000000000000
}
[0x1] =
{
[0x0] = 0x1000000000000000
[0x1] = 0x0010000000000000
[0x2] = 0x0000010000000000
[0x3] = 0x0000000000000000
[0x4] = 0x0000000000000000
}
[0x2] =
{
[0x0] = 0x0100000000000000
[0x1] = 0x0001000000000000
[0x2] = 0x0000001000000000
[0x3] = 0x0000000000000000
[0x4] = 0x0000000000000000
}
[0x3] =
{
[0x0] = 0x0010000000000000
[0x1] = 0x0000000100000000
[0x2] = 0x0000000000000000
[0x3] = 0x0000000000000000
[0x4] = 0x0000000000000000
}
[0x4] =
{
[0x0] = 0x1000000000000000
[0x1] = 0x0000010000000000
[0x2] = 0x0000000010000000
[0x3] = 0x0000000000000000
[0x4] = 0x0000000000000000
}
[0x5] =
{
[0x0] = 0x0100000000000000
[0x1] = 0x0000100000000000
[0x2] = 0x0000001000000000
[0x3] = 0x0000000001000000
[0x4] = 0x0000000000000000
}
[0x6] =
{
[0x0] = 0x0010000000000000
[0x1] = 0x0000010000000000
[0x2] = 0x0000000100000000
[0x3] = 0x0000000000100000
[0x4] = 0x0000000000000000
}
[0x7] =
{
[0x0] = 0x0001000000000000
[0x1] = 0x0000001000000000
[0x2] = 0x0000000000010000
[0x3] = 0x0000000000000000
[0x4] = 0x0000000000000000
}
[0x8] =
{
[0x0] = 0x0000100000000000
[0x1] = 0x0000000001000000
[0x2] = 0x0000000000001000
[0x3] = 0x0000000000000000
[0x4] = 0x0000000000000000
}
[0x9] =
{
[0x0] = 0x0000010000000000
[0x1] = 0x0000000010000000
[0x2] = 0x0000000000100000
[0x3] = 0x0000000000000100
[0x4] = 0x0000000000000000
}
[0xa] =
{
[0x0] = 0x0000001000000000
[0x1] = 0x0000000001000000
[0x2] = 0x0000000000010000
[0x3] = 0x0000000000000010
[0x4] = 0x0000000000000000
}
[0xb] =
{
[0x0] = 0x0000000100000000
[0x1] = 0x0000000000100000
[0x2] = 0x0000000000000001
[0x3] = 0x0000000000000000
[0x4] = 0x0000000000000000
}
[0xc] =
{
[0x0] = 0x0000000010000000
[0x1] = 0x0000000000000100
[0x2] = 0x0000000000000000
[0x3] = 0x0000000000000000
[0x4] = 0x0000000000000000
}
[0xd] =
{
[0x0] = 0x0000000001000000
[0x1] = 0x0000000000001000
[0x2] = 0x0000000000000010
[0x3] = 0x0000000000000000
[0x4] = 0x0000000000000000
}
[0xe] =
{
[0x0] = 0x0000000000100000
[0x1] = 0x0000000000000100
[0x2] = 0x0000000000000001
[0x3] = 0x0000000000000000
[0x4] = 0x0000000000000000
}
[0xf] =
{
[0x0] = 0x0000000000010000
[0x1] = 0x0000000000000010
[0x2] = 0x0000000000000000
[0x3] = 0x0000000000000000
[0x4] = 0x0000000000000000
}
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 88 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 75 KiB

+71
View File
@@ -0,0 +1,71 @@
char init_state[0x36] =
{
0x0d, 0x03, 0x02, 0x0e, 0x0f, 0x09, 0x07, 0x0e, 0x0d, 0x06, 0x03, 0x02, 0x07, 0x02, 0x08, 0x0e,
0x07, 0x04, 0x04, 0x03, 0x0d, 0x04, 0x0c, 0x03, 0x0f, 0x02, 0x0a, 0x05, 0x09, 0x01, 0x06, 0x0a,
0x0b, 0x02, 0x05, 0x0c, 0x0e, 0x0b, 0x0d, 0x01, 0x0a, 0x01, 0x05, 0x09, 0x01, 0x0f, 0x06, 0x0e,
0x04, 0x04, 0x0b, 0x04, 0x0b, 0x0f, 0x00
};
int32_t main(int32_t argc, char** argv, char** envp)
{
char* const init_state_ptr = &init_state;
char state[0x36];
char* state_ptr = &state;
for (int64_t size = 0x36; size != 0; size -= 1)
{
*state_ptr = *init_state_ptr;
state_ptr += 1;
init_state_ptr += 1;
}
printf("Password: ", init_state_ptr);
fflush(stdout);
char input[0x18];
scanf("%24s", &input);
int64_t state_index = 0;
while (true)
{
if (strlen(&input) <= state_index)
{
// Cutting everything that happens
...
if (check == OK)
{
puts("Win!");
FILE file = fopen("flag.txt", &rb);
if (file != NULL)
{
char flag[0x46];
fread(&flag, 1, 0x46, file);
fclose(file);
puts(flag);
return 0;
}
else
puts("Send your input on the remote se…");
}
else
puts("Nope!");
break;
}
else
{
char* pos_ptr = strchr("abcdefghjklmnpqrstuvwxyz", input[state_index]);
if (pos_ptr != NULL)
{
// Do stuff iterating on the state
...
state_index += 1;
continue;
}
}
puts("Nope!");
break;
}
exit(1);
/* no return */
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 60 KiB

+37
View File
@@ -0,0 +1,37 @@
else
{
char* pos_ptr = strchr("abcdefghjklmnpqrstuvwxyz", input[state_index]);
if (pos_ptr != NULL)
{
int64_t pos = pos_ptr - "abcdefghjklmnpqrstuvwxyz";
int32_t remainder = pos % 4;
char* permutation_array = &permutations[pos / 4];
while (true)
{
if (remainder < 1)
break;
remainder -= 1;
char state_copy[0x36];
char* state_copy_ptr = &state_copy;
char* state_ptr_1 = &state;
int64_t i = 0x36;
for (; i != 0; i -= 1)
{
*state_copy_ptr = *state_ptr_1;
state_copy_ptr += 1;
state_ptr_1 += 1;
}
do
{
char elem = state_copy[permutation_array[i]];
state[i] = elem;
i += 1
} while (i != 0x36);
}
state_index += 1;
continue;
}
}
@@ -0,0 +1,56 @@
char permutations[0x6][0x36] =
{
[0x0] =
{
[0x00] = 0x09
[0x01] = 0x01
[0x02] = 0x02
[0x03] = 0x0c
[0x04] = 0x04
[0x05] = 0x05
[0x06] = 0x0f
[0x07] = 0x07
[0x08] = 0x08
[0x09] = 0x2d
...
[0x34] = 0x34
[0x35] = 0x35
}
[0x1] =
{
[0x00] = 0x00
[0x01] = 0x01
[0x02] = 0x2a
[0x03] = 0x03
...
[0x34] = 0x34
[0x35] = 0x11
[0x2] =
{
[0x00] = 0x02
[0x01] = 0x05
...
[0x35] = 0x35
}
[0x3] =
{
[0x00] = 0x00
[0x01] = 0x01
...
[0x35] = 0x33
}
[0x4] =
{
[0x00] = 0x00
[0x01] = 0x01
...
[0x35] = 0x35
}
[0x5] =
{
[0x00] = 0x21
[0x01] = 0x1e
...
[0x35] = 0x14
}
}
BIN
View File
Binary file not shown.
+67
View File
@@ -0,0 +1,67 @@
if (strlen(&input) <= state_index)
{
int64_t board = 0x3da8e0915f2c4b67;
int64_t next_board;
int64_t i = 0;
uint64_t move;
while (true)
{
uint64_t c = state[i];
void* allowed_moves = &allowed_moves;
int32_t shifter = 0x3c;
do
{
if (c == ((board >> shifter) & 0xf))
{
uint64_t* moves = allowed_moves;
do
{
move = *moves;
if (move == 0)
break;
moves += 1;
} while (((move * 0xf) & board) != 0);
if (move != 0)
break;
}
shifter -= 4;
allowed_moves += 0x28;
} while (shifter != 0xfffffffc);
if (c != ((board >> shifter) & 0xf) || move == 0)
break;
int64_t swapper = ((c * move) ^ (c << shifter));
next_board = (board ^ swapper);
if (board == swapper)
break;
i += 1;
if (i == 0x36)
break;
board = next_board;
}
if (next_board == 0x123456789abcdef0)
{
puts("Win!");
FILE file = fopen("flag.txt", &rb);
if (file != NULL)
{
char flag[0x46];
fread(&flag, 1, 0x46, file);
fclose(file);
puts(flag);
return 0;
}
else
puts("Send your input on the remote se…");
}
else
puts("Nope!");
break;
}
+194
View File
@@ -0,0 +1,194 @@
use std::collections::HashMap;
struct Board {
board: [usize; 0x10],
moves: Vec<usize>,
max_moves: usize,
move_number: usize,
empt_idx: usize,
solved_grid: [usize; 0x10],
fixed_moves: HashMap<usize, usize>,
move_limit: [isize; 0x10]
}
impl Board {
pub fn new(board: [usize; 0x10]) -> Self {
let empt_idx: usize = board.iter().position(|&r| r == 0).unwrap().try_into().unwrap();
let all_moves: [usize; 0x36] = [
0x0d, 0x03, 0x02, 0x0e, 0x0f, 0x09, 0x07, 0x0e, 0x0d, 0x06, 0x03, 0x02, 0x07, 0x02, 0x08, 0x0e,
0x07, 0x04, 0x04, 0x03, 0x0d, 0x04, 0x0c, 0x03, 0x0f, 0x02, 0x0a, 0x05, 0x09, 0x01, 0x06, 0x0a,
0x0b, 0x02, 0x05, 0x0c, 0x0e, 0x0b, 0x0d, 0x01, 0x0a, 0x01, 0x05, 0x09, 0x01, 0x0f, 0x06, 0x0e,
0x04, 0x04, 0x0b, 0x04, 0x0b, 0x0f
];
let solved_grid: [usize; 0x10] = [1,2,3,4,5,6,7,8,9,0xa,0xb,0xc,0xd,0xe,0xf,0];
let mut fixed_moves: HashMap<usize, usize> = HashMap::new();
for i in vec![4, 0xd, 0x16, 0x1f, 0x28, 0x31] {
fixed_moves.insert(i, all_moves[i]);
}
let mut move_limit: [isize; 0x10] = [0; 0x10];
for mv in all_moves.iter() {
move_limit[*mv] += 1;
}
Board {
board: board,
moves: Vec::new(),
max_moves: 0x36,
move_number: 0,
empt_idx: empt_idx,
solved_grid: solved_grid,
fixed_moves: fixed_moves,
move_limit: move_limit,
}
}
pub fn solved(&self) -> bool {
self.board == self.solved_grid
}
pub fn get_move(&self, off: Vec<isize>) -> Option<usize> {
let empt_idx: isize = self.empt_idx.try_into().unwrap();
let empt_i: isize = empt_idx / 4;
let empt_j: isize = empt_idx % 4;
let src_i: isize = empt_i + off[0];
let src_j: isize = empt_j + off[1];
if src_i < 4 && src_i >= 0 && src_j < 4 && src_j >= 0 {
let idx: usize = (src_i * 4 + src_j).try_into().unwrap();
return Some(self.board[idx])
}
None
}
pub fn generate_moves(&self) -> Vec<usize> {
let mut moves: Vec<usize> = Vec::new();
for off in vec![vec![-1, 0], vec![1, 0], vec![0, -1], vec![0, 1]] {
let maybe_move = self.get_move(off);
if let Some(mv) = maybe_move {
moves.push(mv);
}
}
moves
}
pub fn apply_move(&mut self, mv: usize, undo: bool) {
let i: usize = self.board.iter().position(|&x| x == mv).unwrap();
let tmp: usize = self.board[i];
self.board[i] = self.board[self.empt_idx];
self.board[self.empt_idx] = tmp;
self.empt_idx = i;
if undo {
self.move_number -= 1;
self.moves.pop();
self.move_limit[mv] += 1;
}
else {
self.move_number += 1;
self.moves.push(mv);
self.move_limit[mv] -= 1;
}
}
pub fn manhattan_distance(&self, mv: usize) -> isize {
let mv_idx: isize = self.board.iter().position(|&x| x == mv).unwrap().try_into().unwrap();
let mv_i: isize = mv_idx / 4;
let mv_j: isize = mv_idx % 4;
let supposed_idx: isize = (mv - 1).try_into().unwrap();
let supposed_i: isize = supposed_idx / 4;
let supposed_j: isize = supposed_idx % 4;
let manhattan: isize = (supposed_j - mv_j).abs() + (supposed_i - mv_i).abs();
manhattan
}
pub fn solve(&mut self) -> bool {
// GG
if self.solved() {
return true;
}
// No more moves
if self.move_number >= self.max_moves {
return false;
}
// Last move need to be 0xc or 0xf
if self.move_limit[0xc] <= 0 && self.move_limit[0xf] <= 0 {
return false;
}
let last_move: Option<usize> = self.moves.last().copied();
if let Some(mv) = last_move {
// Tile cannot possibly go back to its supposed location
let man: isize = self.manhattan_distance(mv);
if self.move_limit[mv] < man {
return false
}
}
// Generate possible moves from current grid
let mut moves: Vec<usize> = self.generate_moves();
// Cannot apply same move twice
if let Some(mv) = last_move {
moves = moves.iter().filter(|&x| *x != mv).cloned().collect();
}
// Filter fixed moves from the cube center tiles
if self.fixed_moves.contains_key(&self.move_number) {
let mv: usize = *self.fixed_moves.get(&self.move_number).unwrap();
moves = moves.iter().filter(|&x| *x == mv).cloned().collect();
}
for mv in moves {
// Apply move
self.apply_move(mv, false);
// Recursive call
let solved: bool = self.solve();
// GG
if solved {
return true;
}
// Undo move
self.apply_move(mv, true);
}
false
}
}
fn solve() {
let arr: [usize; 0x10] = [
3, 0xd, 0xa, 8,
0xe, 0, 9, 1,
5, 0xf, 2, 0xc,
4, 0xb, 6, 7
];
let mut board: Board = Board::new(arr);
board.solve();
println!("{:x?}", board.moves);
println!("{}", board.moves.len())
}
fn main() {
solve()
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Reference in new issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.