Skip to content

Latest commit

 

History

History

e-pu

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 
 
 
 
 
 
 
 
 

e-pu

Category

Prog

Description

It's the same type of puzzle as before, but we are adding one dimension. The pieces are in the puzzle.pickle file in the following format:

pieces = [(up, right, front, down, left, back, payload), (up, right, front, down, left, back, payload), ...]

The flag is the concatenation of the payloads of the pieces composing the diagonal from the upper-left-front corner to the lower-right-back corner.

Format : Hero{flag}
Author : Log_s

Files

Write up

It's possible to solve this puzzle the same way we solved the previous one, by juste adapting the code to handle one more dimension. After some tests, the average solving time was around 9 seconds on my computer.

It's possible however to be smart about it, and juste build the diagonal of the puzzle. That's what I did in the following script, briging down the solving time to 0.5 seconds on average.

The speed up is due to the fact that we are not putting 32768 pieces together, but only 94.

The above times are when considering already knowing the upper-left-front corner. The total time in the end is 7 seconds on my end.

import time
import pickle


start_time = time.time()


INPUT_FILE = "puzzle.pickle"
UP = 0
RIGHT = 1
FRONT = 2
DOWN = 3
LEFT = 4
BACK = 5
PAYLOAD = 6


# Parse input
puzzle_pieces = pickle.loads(open(INPUT_FILE, "rb").read())
SIZE = round(len(puzzle_pieces) ** (1./3.))
print(f"[+] Puzzle size: {SIZE}x{SIZE} ({len(puzzle_pieces)} pieces)")


# Find upper left corner
upper_left_front = None
for piece1 in puzzle_pieces:
    found = True
    for piece2 in puzzle_pieces:
        if piece1[UP] == piece2[DOWN] or piece1[LEFT] == piece2[RIGHT] or piece1[FRONT] == piece2[BACK]:
            found = False
            break
    if found:
        upper_left_front = piece1
        break
puzzle_pieces.remove(upper_left_front)
print(f"[+] Found upper left front corner: {upper_left_front}")


# Reconstruct puzzle
puzzle = [[[None for _ in range(SIZE)] for __ in range(SIZE)] for ___ in range(SIZE)]
puzzle[0][0][0] = upper_left_front
x, y, z = 1, 0, 0
operations = 0
while x < SIZE:
    if operations%3 == 0:
        for piece in puzzle_pieces:
            if piece[LEFT] == puzzle[z][y][x-1][RIGHT]:
                puzzle[z][y][x] = piece
                puzzle_pieces.remove(piece)
                break
        y += 1
    elif operations%3 == 1:
        for piece in puzzle_pieces:
            if piece[UP] == puzzle[z][y-1][x][DOWN]:
                puzzle[z][y][x] = piece
                puzzle_pieces.remove(piece)
                break
        z += 1
    else:
        for piece in puzzle_pieces:
            if piece[FRONT] == puzzle[z-1][y][x][BACK]:
                puzzle[z][y][x] = piece
                puzzle_pieces.remove(piece)
                break
        x += 1
    
    operations += 1


# Read flag
flag = ""
for i in range(SIZE):
    flag += puzzle[i][i][i][PAYLOAD]
print(f"[+] Flag : Hero{{{flag}}}")

print(f"\n--- {time.time() - start_time} seconds ---")

Flag

Hero{a0b5ccfaf13144c0292a584aac4c3753}