diff --git a/julia_old/CubeShapeCounting.code-workspace b/julia_old/CubeShapeCounting.code-workspace deleted file mode 100644 index 83dea4e..0000000 --- a/julia_old/CubeShapeCounting.code-workspace +++ /dev/null @@ -1,15 +0,0 @@ -{ - "folders": [ - { - "path": ".." - } - ], - "settings": { - "files.exclude": { - "**/*.sln": true, - "**/*.code-workspace": true, - "**/.gitignore": true, - "**/.gitattributes": true - } - } -} \ No newline at end of file diff --git a/julia_old/ImmutableOrientedPolyCube.jl b/julia_old/ImmutableOrientedPolyCube.jl deleted file mode 100644 index 80c15d2..0000000 --- a/julia_old/ImmutableOrientedPolyCube.jl +++ /dev/null @@ -1,10 +0,0 @@ -using XXhash - -struct ImmutableOrientedPolycube - cubes::Vector{Tuple{Int64, Int64, Int64}} - hash::UInt -end - -function getImmutableOrientedPolycube(S::Polycube) - shape = ImmutableOrientedPolycube(S.orderedLists[1], hashList(S.orderedLists[1])) -end diff --git a/julia_old/Plot.jl b/julia_old/Plot.jl deleted file mode 100644 index 348624c..0000000 --- a/julia_old/Plot.jl +++ /dev/null @@ -1,34 +0,0 @@ -using Plots -using Serialization - -function plotPolycubes(nCubes::Int64, index::Int64=-1) - pyplot() - pygui(true) - T = deserialize("julia/results.bin") - i = if (index == -1); :; else index:index end - v = T[2][nCubes][i] - n = size(v)[1] - - colors = (:reds, :greens, :blues) - - X = [0, 0, 1, 1, 0, 0, 1, 1] - Y = [0, 1, 1, 0, 0, 1, 1, 0] - Z = [0, 0, 0, 0, 1, 1, 1, 1] - - I = [7, 0, 0, 0, 4, 4, 6, 6, 4, 0, 3, 2] - J = [3, 4, 1, 2, 5, 6, 5, 2, 0, 1, 6, 3] - K = [0, 7, 2, 3, 6, 7, 1, 1, 5, 5, 7, 6] - - P = Vector{Plots.Plot{Plots.PyPlotBackend}}(undef, n) - @show v - for i ∈ 1:n - polyCube = v[i] - p = mesh3d() - for cube ∈ polyCube - @show cube - mesh3d!(p, X.+cube[1], Y.+cube[2], Z.+cube[3], connections=(I, J, K), legend=:none, c=colors[rand(1:3)]) - end - P[i] = p - end - plot(P..., colorbar=false) -end diff --git a/julia_old/Polycube.jl b/julia_old/Polycube.jl deleted file mode 100644 index c8ef1d6..0000000 --- a/julia_old/Polycube.jl +++ /dev/null @@ -1,64 +0,0 @@ -include("Rotations.jl") - -struct Polycube - cubes::Set{Tuple{Int64, Int64, Int64}} - recentCubes::Set{Tuple{Int64, Int64, Int64}} - orderedLists::Vector{Vector{Tuple{Int64, Int64, Int64}}} -end - -function Base.:push!(S::Polycube, t::Tuple{Int64, Int64, Int64}) - push!(S.cubes, t) - for i ∈ 1:24 - t_rot = Rotations[i](t) - index = searchsortedfirst(S.orderedLists[i], t_rot) - insert!(S.orderedLists[i], index, t_rot) - end -end - -function getPossibleNeighbors(S::Polycube) - possibleSpots = Set{Tuple{Int64, Int64, Int64}}() - for p ∈ S.recentCubes - push!(possibleSpots, - p .+ (1, 0, 0), - p .+ (0, 1, 0), - p .+ (0, 0, 1), - p .- (1, 0, 0), - p .- (0, 1, 0), - p .- (0, 0, 1) - ) - end - spots = setdiff(possibleSpots, S.cubes) - return spots -end - -function getCube() - return Polycube( - Set([(0, 0, 0)]), - Set([(0, 0, 0)]), - [ - [(0, 0, 0)], - [(0, 0, 0)], - [(0, 0, 0)], - [(0, 0, 0)], - [(0, 0, 0)], - [(0, 0, 0)], - [(0, 0, 0)], - [(0, 0, 0)], - [(0, 0, 0)], - [(0, 0, 0)], - [(0, 0, 0)], - [(0, 0, 0)], - [(0, 0, 0)], - [(0, 0, 0)], - [(0, 0, 0)], - [(0, 0, 0)], - [(0, 0, 0)], - [(0, 0, 0)], - [(0, 0, 0)], - [(0, 0, 0)], - [(0, 0, 0)], - [(0, 0, 0)], - [(0, 0, 0)], - [(0, 0, 0)], - ]) -end diff --git a/julia_old/PolycubeCounting.jl b/julia_old/PolycubeCounting.jl deleted file mode 100644 index a42bdb1..0000000 --- a/julia_old/PolycubeCounting.jl +++ /dev/null @@ -1,104 +0,0 @@ -include("Polycube.jl") -include("ImmutableOrientedPolycube.jl") -include("plot.jl") -using XXhash -using Serialization -using Combinatorics -using WAV - -function options() - println("scanForPolycubes(MaxSize::Int64): scans for Polycubes of size <=MaxSize") - println("countPolycubes(): opens Polycube storage and displays the amount of Polycubes for the generated sizes") - println("listPolycubes(): lists all Polycubes from the Polycube storage") - println("plotPolycubes(nCubes::Int64, index::Int64=-1): plots Polycubes of size v[1], or just v[2] from the list") -end - -function scanForPolycubes(MaxSize::Int64, debug::Bool=false) - T = deserialize("julia/results.bin") - n = T[1] - if (~debug && MaxSize <= n) return; end - @time begin - D = Dict{UInt, ImmutableOrientedPolycube}() - singletonCube = getCube() - immutableCube = getImmutableOrientedPolycube(singletonCube) - D[immutableCube.hash] = immutableCube - evaluatePolycube(singletonCube, D, MaxSize) - end - if (~debug) serialize("julia/results.bin", sanitize(D, MaxSize)) end - y, fs = wavread("julia/background-error.wav") - wavplay(y, fs) -end - -function evaluatePolycube(polycube::Polycube, D::Dict{UInt, ImmutableOrientedPolycube}, MaxSize::Int64) - growableSpaces = collect(getPossibleNeighbors(polycube)) - acceptable_growth = MaxSize - length(polycube.cubes) - - possibleGrowth = powerset(growableSpaces, 1, acceptable_growth) - for cubesToAdd ∈ possibleGrowth - newPolycube = Polycube(copy(polycube.cubes), Set(cubesToAdd), deepcopy(polycube.orderedLists)) - for c ∈ cubesToAdd - push!(newPolycube, c) - end - collision = checkForCollision(newPolycube, D) - if !collision - immutableNewPolycube = getImmutableOrientedPolycube(newPolycube) - D[immutableNewPolycube.hash] = immutableNewPolycube - evaluatePolycube(newPolycube, D, MaxSize) - end - end -end - -function countPolycubes() - T = deserialize("julia/results.bin") - n = T[1] - for i ∈ 1:n - print("n = ") - print(i) - print(": ") - println(length(T[2][i])) - end -end - -function listPolycubes() - T = deserialize("julia/results.bin") - print("max size: ") - println(T[1]) - for V ∈ T[2] - for v ∈ V - println(v) - end - end -end - -function checkForCollision(S::Polycube, D::Dict{UInt, ImmutableOrientedPolycube}) - for i ∈ 1:24 - hash = hashList(S.orderedLists[i]) - value = get(D, hash, nothing) - if value !== nothing && hash == value.hash - return true - end - end - return false -end - -function hashList(L::Vector{Tuple{Int64, Int64, Int64}}) - diffList = Vector{Tuple{Int64, Int64, Int64}}(undef, length(L)-1) - for i ∈ eachindex(diffList) - diffList[i] = L[i+1] - L[i] - end - return xxh3_64(diffList) -end - -function sanitize(D::Dict{UInt, ImmutableOrientedPolycube}, size::Int64) - data = Vector{Vector{Vector{Tuple{Int64, Int64, Int64}}}}(undef, size) - for i ∈ eachindex(data) - data[i] = Vector{Vector{Tuple{Int64, Int64, Int64}}}(undef, 0) - end - for (K, V) ∈ D - push!(data[length(V.cubes)], V.cubes) - end - return (size, data) -end - -Base.:+(t1 = Tuple{Int64, Int64, Int64}, t2 = Tuple{Int64, Int64, Int64}) = (t1[1] + t2[1], t1[2] + t2[2], t1[3] + t2[3]) -Base.:-(t1 = Tuple{Int64, Int64, Int64}, t2 = Tuple{Int64, Int64, Int64}) = t1 + t2.*-1 diff --git a/julia_old/Rotations.jl b/julia_old/Rotations.jl deleted file mode 100644 index 8501b63..0000000 --- a/julia_old/Rotations.jl +++ /dev/null @@ -1,58 +0,0 @@ -_rot01(x) = ( x[1], x[2], x[3]) -_rot02(x) = ( x[2], x[3], x[1]) -_rot03(x) = ( x[3], x[1], x[2]) - -_rot04(x) = ( x[1], -x[2], -x[3]) -_rot05(x) = ( x[2], -x[3], -x[1]) -_rot06(x) = ( x[3], -x[1], -x[2]) - -_rot07(x) = (-x[1], x[2], -x[3]) -_rot08(x) = (-x[2], x[3], -x[1]) -_rot09(x) = (-x[3], x[1], -x[2]) - -_rot10(x) = (-x[1], -x[2], x[3]) -_rot11(x) = (-x[2], -x[3], x[1]) -_rot12(x) = (-x[3], -x[1], x[2]) - -_rot13(x) = (-x[3], x[2], x[1]) -_rot14(x) = (-x[2], x[1], x[3]) -_rot15(x) = (-x[1], x[3], x[2]) - -_rot16(x) = ( x[3], -x[2], x[1]) -_rot17(x) = ( x[2], -x[1], x[3]) -_rot18(x) = ( x[1], -x[3], x[2]) - -_rot19(x) = ( x[3], x[2], -x[1]) -_rot20(x) = ( x[2], x[1], -x[3]) -_rot21(x) = ( x[1], x[3], -x[2]) - -_rot22(x) = (-x[3], -x[2], -x[1]) -_rot23(x) = (-x[2], -x[1], -x[3]) -_rot24(x) = (-x[1], -x[3], -x[2]) - -const global Rotations = (; - _rot01, - _rot02, - _rot03, - _rot04, - _rot05, - _rot06, - _rot07, - _rot08, - _rot09, - _rot10, - _rot11, - _rot12, - _rot13, - _rot14, - _rot15, - _rot16, - _rot17, - _rot18, - _rot19, - _rot20, - _rot21, - _rot22, - _rot23, - _rot24 -) diff --git a/julia_old/background-error.wav b/julia_old/background-error.wav deleted file mode 100644 index 26672f1..0000000 Binary files a/julia_old/background-error.wav and /dev/null differ diff --git a/python/main.py b/python/main.py index 32f4a38..a3226fb 100644 --- a/python/main.py +++ b/python/main.py @@ -3,23 +3,31 @@ from polycube_encoder import PolyCubeEncdoder import json def main(maxlength:int): - polycubes = set([PolyCube([(0, 0, 0)], [(0, 0, 0)])]) + initial_cube = PolyCube([(0, 0, 0)], [(0, 0, 0)]) n_size = [0]*maxlength - todo = [PolyCube([(0, 0, 0)], [(0, 0, 0)])] + todo = [initial_cube] + polycubes = [initial_cube.oriented_offsets[0]] n_size[0] = 1 + while len(todo) != 0: polycube = todo.pop() children = polycube.generate_children(maxlength) for child in children: - if child in polycubes: - continue + if child_exists_in(child, polycubes): + continue todo.append(child) - polycubes.add(child) + polycubes.append(child.oriented_offsets[0]) n_size[len(child.cubes)-1] += 1 with open("out.json", "w") as f: f.write(json.dumps(polycubes, cls=PolyCubeEncdoder)) with open("count.json", "w") as f: f.write(json.dumps(n_size)) +def child_exists_in(child: PolyCube, polycubes: list): + for orientation in child.oriented_offsets: + if orientation in polycubes: + return True + return False + if __name__ == "__main__": - main(4) + main(7) diff --git a/python/polycube.py b/python/polycube.py index 10d91a9..4d28119 100644 --- a/python/polycube.py +++ b/python/polycube.py @@ -1,11 +1,11 @@ -from tuple_tools import reorient_tuple, generate_neighbors +from tuple_tools import reorient_tuple, generate_neighbors, subtract from itertools import combinations, chain class PolyCube: - #cubes set{tuple} - #orientations list{set{tuple{}}} - #last_additions set{tuple} + #cubes set{tuple} + #oriented_offsets list{list{tuple{}}} + #last_additions set{tuple} def __init__(self, cubes_list, last_additions = []) -> None: self.cubes = set(cubes_list) @@ -15,11 +15,21 @@ class PolyCube: def _compute_reorientations(self): n_cubes = len(self.cubes) n_orientations = 24 - orientations = [set()]*n_orientations + orientations = [[]]*n_orientations + oriented_offsets = [[]]*n_orientations for i in range(n_orientations): - for cube in self.cubes: - orientations[i].add(reorient_tuple(cube, i)) - self.orientations = orientations + if n_cubes == 1: + oriented_offsets[i] = [] + else: + orientations[i] = [] + for cube in self.cubes: + orientations[i].append(reorient_tuple(cube, i)) + orientations[i].sort() + oriented_offsets[i] = [(0, 0, 0)]*(n_cubes-1) + last_cube = orientations[i][0] + for j in range(n_cubes-1): + oriented_offsets[i][j] = subtract(*last_cube, *orientations[i][j+1]) + self.oriented_offsets = oriented_offsets def generate_children(self, max_length:int): max_growth = max_length - len(self.cubes)