migrate to new c djstdlib
This commit is contained in:
@@ -1,5 +1,7 @@
|
||||
#include <cstring>
|
||||
#include "string.h"
|
||||
#include "VoxelSpace.h"
|
||||
#include "SomaSolve.h"
|
||||
#include "math.h"
|
||||
|
||||
/*
|
||||
void get_dims_input(int dims[3]) {
|
||||
@@ -62,12 +64,12 @@ std::vector<uint64> get_reprs_input(int units_required) {
|
||||
}
|
||||
*/
|
||||
|
||||
typedef list<uint64> SomaSolution;
|
||||
DefineList(size_t, Offset);
|
||||
|
||||
typedef struct Solver {
|
||||
list<uint64>* input;
|
||||
list<size_t>* offsets;
|
||||
list<SomaSolution>* solutions;
|
||||
VoxelSpaceReprList *input;
|
||||
OffsetList *offsets;
|
||||
SomaSolutionList *solutions;
|
||||
} Solver;
|
||||
|
||||
uint64 STD_SOMA[] = { 23ul, 30ul, 15ul, 1043ul, 24594ul, 12306ul, 11ul };
|
||||
@@ -122,25 +124,25 @@ void backtrack_solve_iter(std::vector<uint64> *polycube_input, std::vector<int>
|
||||
}
|
||||
*/
|
||||
|
||||
void backtrackSolve(Arena *arena, Solver *solver, uint64 working_solution = 0, size_t curr_piece = 0) {
|
||||
list<uint64> *input = solver->input;
|
||||
list<size_t> *offsets = solver->offsets;
|
||||
list<SomaSolution> *solutions = solver->solutions;
|
||||
void backtrackSolve(Arena *arena, Solver *solver, uint64 working_solution, size_t curr_piece) {
|
||||
VoxelSpaceReprList *input = solver->input;
|
||||
OffsetList *offsets = solver->offsets;
|
||||
SomaSolutionList *solutions = solver->solutions;
|
||||
size_t start = offsets->data[curr_piece];
|
||||
size_t end = offsets->data[curr_piece + 1];
|
||||
size_t num_pieces = offsets->head - 1;
|
||||
size_t num_pieces = offsets->length - 1;
|
||||
for (size_t i = start; i < end; i++) {
|
||||
bool successful_fuse = !collides(working_solution, input->data[i]);
|
||||
if (successful_fuse) {
|
||||
uint64 new_working_solution = working_solution | input->data[i];
|
||||
solutions->data[solutions->head - 1].data[curr_piece] = input->data[i];
|
||||
solutions->data[solutions->length - 1].data[curr_piece] = input->data[i];
|
||||
if (curr_piece == num_pieces - 1) {
|
||||
list<uint64> last_soln = solutions->data[solutions->head - 1];
|
||||
list<uint64> last_soln_copy = PushList(arena, uint64, last_soln.head);
|
||||
last_soln_copy.length = last_soln.head;
|
||||
last_soln_copy.head = last_soln.head;
|
||||
memcpy(last_soln_copy.data, last_soln.data, last_soln.head * sizeof(uint64));
|
||||
appendList(solutions, last_soln_copy);
|
||||
VoxelSpaceReprList last_soln = solutions->data[solutions->length - 1];
|
||||
VoxelSpaceReprList last_soln_copy = PushList(arena, VoxelSpaceReprList, last_soln.length);
|
||||
last_soln_copy.capacity = last_soln.length;
|
||||
last_soln_copy.length = last_soln.length;
|
||||
memcpy(last_soln_copy.data, last_soln.data, last_soln.length * sizeof(uint64));
|
||||
AppendList(solutions, last_soln_copy);
|
||||
return;
|
||||
} else {
|
||||
backtrackSolve(arena, solver, new_working_solution, curr_piece + 1);
|
||||
@@ -148,40 +150,40 @@ void backtrackSolve(Arena *arena, Solver *solver, uint64 working_solution = 0, s
|
||||
}
|
||||
}
|
||||
if (curr_piece == 0) {
|
||||
solutions->head -= 1;
|
||||
solutions->length -= 1;
|
||||
}
|
||||
}
|
||||
|
||||
list<SomaSolution> getSolutionRotations(Arena *arena, SomaSolution *solution, int dims[3]) {
|
||||
list<SomaSolution> result = PushFullList(arena, SomaSolution, NUM_ROTS_3D);
|
||||
SomaSolutionList getSolutionRotations(Arena *arena, SomaSolution *solution, int dims[3]) {
|
||||
SomaSolutionList result = PushFullList(arena, SomaSolutionList, NUM_ROTS_3D);
|
||||
for (EachIn(result, i)) {
|
||||
result.data[i] = PushList(arena, uint64, solution->head);
|
||||
result.data[i] = PushList(arena, SomaSolution, solution->length);
|
||||
}
|
||||
for (int piece_i = 0; piece_i < solution->head; piece_i++) {
|
||||
for (int piece_i = 0; piece_i < solution->length; piece_i++) {
|
||||
Space space = {
|
||||
solution->data[piece_i],
|
||||
dims[0],
|
||||
dims[1],
|
||||
dims[2],
|
||||
};
|
||||
list<Space> pieceRotations = getAllRotations(arena, &space);
|
||||
for (int rot_i = 0; rot_i < pieceRotations.head; rot_i++) {
|
||||
appendList(&result.data[rot_i], pieceRotations.data[rot_i].space);
|
||||
VoxelSpaceList pieceRotations = getAllRotations(arena, &space);
|
||||
for (int rot_i = 0; rot_i < pieceRotations.length; rot_i++) {
|
||||
AppendList(&result.data[rot_i], pieceRotations.data[rot_i].space);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
list<SomaSolution> filterUnique(Arena *arena, list<SomaSolution> *solutions, int dims[3]) {
|
||||
if (solutions->head == 0) {
|
||||
return list<SomaSolution>{NULL,0,0};
|
||||
SomaSolutionList filterUnique(Arena *arena, SomaSolutionList *solutions, int dims[3]) {
|
||||
if (solutions->length == 0) {
|
||||
return (SomaSolutionList)EmptyList();
|
||||
}
|
||||
list<SomaSolution> uniqueSolns = PushList(arena, SomaSolution, solutions->head);
|
||||
SomaSolutionList uniqueSolns = PushList(arena, SomaSolutionList, solutions->length);
|
||||
for (EachIn(*solutions, i)) {
|
||||
SomaSolution solution = solutions->data[i];
|
||||
bool foundMatch = false;
|
||||
Scratch temp = scratchStart(&arena, 1);
|
||||
list<SomaSolution> rots = getSolutionRotations(temp.arena, &solution, dims);
|
||||
SomaSolutionList rots = getSolutionRotations(temp.arena, &solution, dims);
|
||||
for (EachIn(rots, j)) {
|
||||
SomaSolution rotation = rots.data[j];
|
||||
for (EachIn(uniqueSolns, k)) {
|
||||
@@ -204,11 +206,11 @@ list<SomaSolution> filterUnique(Arena *arena, list<SomaSolution> *solutions, int
|
||||
}
|
||||
scratchEnd(temp);
|
||||
if (!foundMatch) {
|
||||
SomaSolution solutionCopy = PushList(arena, uint64, solution.head);
|
||||
solutionCopy.length = solution.head;
|
||||
solutionCopy.head = solution.head;
|
||||
memcpy(solutionCopy.data, solution.data, solution.head * sizeof(uint64));
|
||||
appendList(&uniqueSolns, solutionCopy);
|
||||
SomaSolution solutionCopy = PushList(arena, SomaSolution, solution.length);
|
||||
solutionCopy.capacity = solution.length;
|
||||
solutionCopy.length = solution.length;
|
||||
memcpy(solutionCopy.data, solution.data, solution.length * sizeof(SomaSolutionList_underlying));
|
||||
AppendList(&uniqueSolns, solutionCopy);
|
||||
}
|
||||
}
|
||||
return uniqueSolns;
|
||||
@@ -222,56 +224,56 @@ uint64 factorial(int n) {
|
||||
return result;
|
||||
}
|
||||
|
||||
list<SomaSolution> solve(uint64 *reprs_in, uint32 reprs_in_count, int dims[3]) {
|
||||
SomaSolutionList solve(uint64 *reprs_in, uint32 reprs_in_count, int dims[3]) {
|
||||
Arena *arena = arenaAlloc(Megabytes(64));
|
||||
Arena *permsArena = arenaAlloc(Megabytes(128));
|
||||
|
||||
list<size_t> offsets = PushList(arena, size_t, reprs_in_count + 1);
|
||||
OffsetList offsets = PushList(arena, OffsetList, reprs_in_count + 1);
|
||||
|
||||
list<uint64> polycubes = PushList(arena, uint64, 0);
|
||||
VoxelSpaceReprList polycubes = PushList(arena, VoxelSpaceReprList, 0);
|
||||
|
||||
Space empty_voxel_space = {
|
||||
{},
|
||||
0,
|
||||
dims[0],
|
||||
dims[1],
|
||||
dims[2],
|
||||
};
|
||||
|
||||
appendList(&offsets, (size_t)0);
|
||||
AppendList(&offsets, 0);
|
||||
|
||||
uint64 possibleCombos = 0;
|
||||
|
||||
{
|
||||
list<uint64> positions = {};
|
||||
VoxelSpaceReprList positions = {};
|
||||
Space space = empty_voxel_space;
|
||||
space.space = reprs_in[0];
|
||||
cullEmptySpace(&space);
|
||||
positions = getAllPositionsInPrism(permsArena, &space, dims);
|
||||
possibleCombos += positions.head;
|
||||
uint64 *insertion = PushArray(arena, uint64, positions.length);
|
||||
possibleCombos += positions.length;
|
||||
VoxelSpaceReprList_underlying *insertion = PushArray(arena, uint64, positions.capacity);
|
||||
polycubes.capacity += positions.capacity;
|
||||
polycubes.length += positions.length;
|
||||
polycubes.head += positions.head;
|
||||
memcpy(insertion, positions.data, positions.length * sizeof(uint64));
|
||||
memcpy(insertion, positions.data, positions.capacity * sizeof(VoxelSpaceReprList_underlying));
|
||||
};
|
||||
|
||||
for (size_t i = 1; i < reprs_in_count; i++) {
|
||||
appendList(&offsets, polycubes.length);
|
||||
AppendList(&offsets, polycubes.capacity);
|
||||
Space space = empty_voxel_space;
|
||||
space.space = reprs_in[i];
|
||||
cullEmptySpace(&space);
|
||||
list<uint64> perms = getAllPermutationsInPrism(permsArena, &space, dims);
|
||||
possibleCombos *= perms.head;
|
||||
uint64 *insertion = PushArray(arena, uint64, perms.length);
|
||||
VoxelSpaceReprList perms = getAllPermutationsInPrism(permsArena, &space, dims);
|
||||
possibleCombos *= perms.length;
|
||||
VoxelSpaceReprList_underlying *insertion = PushArray(arena, uint64, perms.capacity);
|
||||
polycubes.capacity += perms.capacity;
|
||||
polycubes.length += perms.length;
|
||||
polycubes.head += perms.head;
|
||||
memcpy(insertion, perms.data, perms.length * sizeof(uint64));
|
||||
memcpy(insertion, perms.data, perms.capacity * sizeof(VoxelSpaceReprList_underlying));
|
||||
}
|
||||
|
||||
appendList(&offsets, polycubes.head);
|
||||
AppendList(&offsets, polycubes.length);
|
||||
|
||||
list<SomaSolution> solutions = PushList(permsArena, SomaSolution, (size_t)floor(sqrt(possibleCombos)));
|
||||
SomaSolution initialSoln = PushFullList(permsArena, uint64, reprs_in_count);
|
||||
appendList(&solutions, initialSoln);
|
||||
SomaSolutionList solutions = PushList(permsArena, SomaSolutionList, (size_t)floor(sqrt(possibleCombos)));
|
||||
SomaSolution initialSoln = PushFullList(permsArena, SomaSolution, reprs_in_count);
|
||||
AppendList(&solutions, initialSoln);
|
||||
|
||||
Solver solver = {
|
||||
&polycubes,
|
||||
@@ -279,7 +281,7 @@ list<SomaSolution> solve(uint64 *reprs_in, uint32 reprs_in_count, int dims[3]) {
|
||||
&solutions,
|
||||
};
|
||||
|
||||
backtrackSolve(permsArena, &solver);
|
||||
backtrackSolve(permsArena, &solver, 0, 0);
|
||||
|
||||
return filterUnique(permsArena, solver.solutions, dims);
|
||||
}
|
||||
@@ -291,6 +293,6 @@ void interactive_cmd_line_solve_soma() {
|
||||
//std::cout << '\n';
|
||||
//std::vector<uint64> reprs = get_reprs_input(dims[0]*dims[1]*dims[2]);
|
||||
print("Great. Calculating solutions...\n");
|
||||
list<SomaSolution> solutions = solve(STD_SOMA, ArrayCount(STD_SOMA), dims);
|
||||
print("%zu solutions found.\n", solutions.head);
|
||||
SomaSolutionList solutions = solve(STD_SOMA, ArrayCount(STD_SOMA), dims);
|
||||
print("%zu solutions found.\n", solutions.length);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user