finally all working

This commit is contained in:
Daniel Ledda
2022-12-27 06:24:36 +01:00
parent bd52c9a93f
commit 82906bd3de
6 changed files with 501 additions and 204 deletions

147
main.cpp
View File

@@ -1,4 +1,5 @@
#include <bitset>
#include <span>
#include <cstdint>
#include <iostream>
#include <string>
@@ -6,6 +7,14 @@
#include <vector>
#include "VoxelSpace.h"
using SomaSolution = std::vector<uint64_t>;
struct Solver {
std::vector<uint64_t>* input;
std::vector<int>* offsets;
std::vector<SomaSolution>* solutions;
};
auto backtrack_solve_iter(std::vector<uint64_t> *polycube_input, std::vector<int> *offsets)-> void {
auto num_inputs = offsets->size() - 1;
@@ -14,7 +23,7 @@ auto backtrack_solve_iter(std::vector<uint64_t> *polycube_input, std::vector<int
auto iter_stack = std::vector<int>();
auto curr_soln_stack = std::vector<int>();
auto soln_spaces_stack = std::vector<uint64_t>();
soln_spaces_stack.push_back(0ull);
soln_spaces_stack.push_back(0ul);
auto depth = 0;
@@ -54,47 +63,76 @@ auto backtrack_solve_iter(std::vector<uint64_t> *polycube_input, std::vector<int
std::cout << "Done. Found " << solns.size() << " solutions." << std::endl;
}
auto backtrack_solve(std::vector<uint64_t> *polycube_input, std::vector<int> *offsets, uint64_t working_solution = 0ull, int set = 0) -> int {
auto solns = 0;
auto start = offsets->at(set);
auto end = offsets->at(set + 1);
auto backtrack_solve(Solver *solver, uint64_t working_solution = 0ul, int curr_piece = 0) -> void {
auto input = solver->input;
auto offsets = solver->offsets;
auto solutions = solver->solutions;
auto start = offsets->at(curr_piece);
auto end = offsets->at(curr_piece + 1);
auto num_pieces = offsets->size() - 1;
for (int i = start; i < end; i++) {
auto successful_fuse = !Voxel::collides(working_solution, polycube_input->at(i));
auto successful_fuse = !Voxel::collides(working_solution, input->at(i));
if (successful_fuse) {
working_solution = working_solution | polycube_input->at(i);
if (set == offsets->size() - 2) {
return solns + 1;
auto new_working_solution = working_solution | input->at(i);
solutions->back().at(curr_piece) = input->at(i);
if (curr_piece == num_pieces - 1) {
auto last_soln = solutions->back();
solutions->push_back(SomaSolution(last_soln.begin(), last_soln.end()));
return;
} else {
solns += backtrack_solve(polycube_input, offsets, working_solution, set + 1);
backtrack_solve(solver, new_working_solution, curr_piece + 1);
}
}
}
return solns;
if (curr_piece == 0) {
solutions->pop_back();
}
}
auto filter_unique(std::vector<std::vector<uint64_t>> *solutions, int dims[3]) -> std::vector<std::vector<uint64_t>> {
if (solutions->size() == 0) {
return std::vector<std::vector<uint64_t>>();
}
auto unique_solns = std::vector<std::vector<uint64_t>>();
for (auto &solution : unique_solns) {
auto foundMatch = false;
auto soln_rotations = std::vector<std::vector<uint64_t>>();
for (auto &piece : solution) {
auto space = Voxel::Space{ .space=solution.at(0), .dims={ dims[0], dims[1], dims[2] } };
auto unique_rots = Voxel::getUniqueRotations(&space);
soln_rotations.insert(soln_rotations.end(), unique_rots.begin(), unique_rots.end());
auto get_solution_rotations(SomaSolution *solution, int dims[3]) -> std::vector<SomaSolution> {
auto result = std::vector<SomaSolution>(Voxel::NUM_ROTS_3D);
for (int piece_i = 0; piece_i < solution->size(); piece_i++) {
auto space = Voxel::Space{
.space=solution->at(piece_i),
.dim_x=dims[0],
.dim_y=dims[1],
.dim_z=dims[2],
};
auto piece_rotations = Voxel::getAllRotations(&space);
for (int rot_i = 0; rot_i < piece_rotations.size(); rot_i++) {
result[rot_i].push_back(piece_rotations[rot_i].space);
}
for (auto &rotation : soln_rotations) {
auto end = unique_solns.size();
for (int i = 0; i < end; i++) {
if (rotation == unique_solns[i]) {
foundMatch = true;
}
return result;
}
auto filter_unique(std::vector<SomaSolution> *solutions, int dims[3]) -> std::vector<SomaSolution> {
if (solutions->size() == 0) {
return std::vector<SomaSolution>();
}
auto unique_solns = std::vector<SomaSolution>{};
for (auto &solution : *solutions) {
auto found_match = false;
for (auto &rotation : get_solution_rotations(&solution, dims)) {
for (auto &unique_soln : unique_solns) {
auto is_match = true;
for (int piece_i = 0; piece_i < unique_soln.size(); piece_i++) {
if (rotation[piece_i] != unique_soln[piece_i]) {
is_match = false;
break;
}
}
if (is_match) {
found_match = true;
break;
}
}
if (found_match) {
break;
}
}
if (!foundMatch) {
unique_solns.push_back(solution);
if (!found_match) {
unique_solns.push_back(SomaSolution(solution));
}
}
return unique_solns;
@@ -137,12 +175,12 @@ auto get_reprs_input(int units_required) -> std::vector<uint64_t> {
continue;
}
}
auto bit_repr = 0ull;
auto bit_repr = 0ul;
auto i = 0;
auto good_repr = true;
for (auto it = input.rbegin(); it < input.rend(); it++, i++) {
if (*it == '1') {
bit_repr |= 1ull << i;
bit_repr |= 1ul << i;
total_units++;
} else if (*it != '0' || i >= 64) {
std::cout << "Input invalid. Enter a binary string only with max 64 bits." << '\n';
@@ -158,35 +196,39 @@ auto get_reprs_input(int units_required) -> std::vector<uint64_t> {
}
auto main() -> int {
int dims[3] = { 3, 3, 3 };
//get_dims_input(dims);
int dims[3];
get_dims_input(dims);
std::cout << '\n';
//auto reprs = get_reprs_input(dims[0]*dims[1]*dims[2]);
auto reprs = get_reprs_input(dims[0]*dims[1]*dims[2]);
/*
auto reprs = std::vector<uint64_t>{
23ull,
30ull,
15ull,
43ull,
172ull,
92ull,
11ull,
23ul,
30ul,
15ul,
1043ul,
24594ul,
12306ul,
11ul,
};
*/
std::cout << "Great. Calculating solutions...\n";
auto offsets = std::vector<int>();
auto polycubes = std::vector<uint64_t>();
polycubes.reserve(reprs.size() * 10);
auto model_space = Voxel::Space{
auto model_space = Voxel::Space{
.space={},
.dims={dims[0], dims[1], dims[2]},
.dim_x=dims[0],
.dim_y=dims[1],
.dim_z=dims[2],
};
offsets.push_back(polycubes.size());
offsets.push_back(0);
auto space = model_space;
space.space = reprs[0];
Voxel::cullEmptySpace(&space);
auto positions = Voxel::getAllPositionsInPrism(space.space, space.dims, dims);
auto positions = Voxel::getAllPositionsInPrism(&space, dims);
polycubes.insert(polycubes.end(), positions.begin(), positions.end());
for (int i = 1; i < reprs.size(); i++) {
@@ -200,8 +242,17 @@ auto main() -> int {
offsets.push_back(polycubes.size());
auto solns = backtrack_solve(&polycubes, &offsets);
auto solutions = std::vector<SomaSolution>{std::vector<uint64_t>(reprs.size())};
auto solver = Solver{
.input=&polycubes,
.offsets=&offsets,
.solutions=&solutions,
};
std::cout << solns << std::endl;
backtrack_solve(&solver);
auto filtered_solns = filter_unique(solver.solutions, dims);
std::cout << filtered_solns.size() << std::endl;
return 0;
}