...
This commit is contained in:
@@ -1,6 +1,117 @@
|
||||
include("Shape.jl")
|
||||
include("ImmutableOrientedShape.jl")
|
||||
include("Powerset.jl")
|
||||
include("TupleMisc.jl")
|
||||
include("plot.jl")
|
||||
using XXhash
|
||||
using Serialization
|
||||
using DataStructures
|
||||
using ArgParse
|
||||
|
||||
function main(i::Int64)
|
||||
D = Dict{ImmutableOrientedShape}()
|
||||
S = Stack{Int64}();
|
||||
function main()
|
||||
s = ArgParseSettings()
|
||||
@add_arg_table s begin
|
||||
"-g"
|
||||
help = "generator"
|
||||
arg_type = Int
|
||||
"-l"
|
||||
help = "list"
|
||||
action = :store_true
|
||||
"-p"
|
||||
help = "plot n_cubes i_shape"
|
||||
nargs = '+'
|
||||
arg_type = Int
|
||||
end
|
||||
|
||||
parsed_args = parse_args(s)
|
||||
|
||||
generate = get(parsed_args, "g", nothing)
|
||||
if generate !== nothing && generate > 0
|
||||
scanForShapes(generate)
|
||||
end
|
||||
if get(parsed_args, "l", false)
|
||||
listShapes()
|
||||
end
|
||||
plot = get(parsed_args, "p", nothing)
|
||||
if length(plot) == 1
|
||||
plotShapes(plot)
|
||||
elseif length(plot) == 2
|
||||
plotShape(plot)
|
||||
end
|
||||
end
|
||||
|
||||
function scanForShapes(MaxSize::Int64)
|
||||
D = Dict{UInt, ImmutableOrientedShape}()
|
||||
S = Stack{Shape}();
|
||||
cube = getCube()
|
||||
immutableCube = getImmutableOrientedShape(cube)
|
||||
D[immutableCube.hash] = immutableCube
|
||||
push!(S, cube)
|
||||
|
||||
while !isempty(S)
|
||||
cube = pop!(S)
|
||||
growableSpaces = collect(getPossibleNeighbors(cube))
|
||||
acceptable_growth = MaxSize - length(cube.cubes)
|
||||
for i ∈ 1:acceptable_growth
|
||||
possibleGrowth = Powerset.getPowerSubSet(length(growableSpaces), i)
|
||||
for j ∈ axes(possibleGrowth, 1)
|
||||
cubesToAdd = growableSpaces[possibleGrowth[j, :]]
|
||||
newShape = deepcopy(cube)
|
||||
for c ∈ cubesToAdd
|
||||
push!(newShape, c)
|
||||
end
|
||||
collision = checkForCollision(newShape, D)
|
||||
if !collision
|
||||
push!(S, newShape)
|
||||
immutableNewShape = getImmutableOrientedShape(newShape)
|
||||
D[immutableNewShape.hash] = immutableNewShape
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
sanitizedData = sanitize(D, MaxSize)
|
||||
serialize("results.bin", sanitizedData)
|
||||
end
|
||||
|
||||
function listShapes()
|
||||
T = deserialize("results.bin")
|
||||
print("size: ")
|
||||
println(T[1])
|
||||
for V ∈ T[2]
|
||||
for v ∈ V
|
||||
println(v)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function checkForCollision(S::Shape, D::Dict{UInt, ImmutableOrientedShape})
|
||||
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, ImmutableOrientedShape}, 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
|
||||
|
||||
main()
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
include("Shape.jl")
|
||||
using XXhash
|
||||
|
||||
struct ImmutableOrientedShape
|
||||
cubes::Vector{Tuple{Int8, Int8, Int8}}
|
||||
cubes::Vector{Tuple{Int64, Int64, Int64}}
|
||||
hash::UInt
|
||||
end
|
||||
|
||||
function getImmutableOrientedShape(S::Shape)
|
||||
shape = ImmutableOrientedShape(S.orderedLists[1], xxh3_64(S.orderedLists[1]))
|
||||
shape = ImmutableOrientedShape(S.orderedLists[1], hashList(S.orderedLists[1]))
|
||||
end
|
||||
|
||||
134
julia/Plot.jl
Normal file
134
julia/Plot.jl
Normal file
@@ -0,0 +1,134 @@
|
||||
using PyCall
|
||||
using Serialization
|
||||
|
||||
py"""
|
||||
import numpy as np
|
||||
from mpl_toolkits.mplot3d import Axes3D
|
||||
import matplotlib.pyplot as plt
|
||||
|
||||
def plotShapePY(v):
|
||||
fig = plt.figure()
|
||||
ax = fig.add_subplot(111, projection='3d')
|
||||
plotSingleShape(ax, v)
|
||||
|
||||
plt.show()
|
||||
|
||||
def plotShapesPY(vs):
|
||||
n = len(vs)
|
||||
if n == 1:
|
||||
plotShapePY(vs[0])
|
||||
else:
|
||||
fig = plt.figure()
|
||||
print(n)
|
||||
n_rows = int(np.ceil(0.6*n))
|
||||
n_cols = int(np.ceil(n/n_rows))
|
||||
print(n_rows)
|
||||
print(n_cols)
|
||||
for i in range(len(vs)):
|
||||
v = vs[i]
|
||||
ax = fig.add_subplot(n_cols, n_rows, i+1, projection='3d')
|
||||
plotSingleShape(ax, v)
|
||||
plt.show()
|
||||
|
||||
def plotSingleShape(ax, v):
|
||||
l = len(v)
|
||||
|
||||
for i in range(l):
|
||||
X1, Y1, Z1 = horizontalPlane(v[i][0] , v[i][1] , v[i][2] )
|
||||
X2, Y2, Z2 = horizontalPlane(v[i][0] , v[i][1] , v[i][2]+1)
|
||||
X3, Y3, Z3 = verticalPlaneX( v[i][0] , v[i][1] , v[i][2] )
|
||||
X4, Y4, Z4 = verticalPlaneX( v[i][0] , v[i][1]+1, v[i][2] )
|
||||
X5, Y5, Z5 = verticalPlaneY( v[i][0] , v[i][1] , v[i][2] )
|
||||
X6, Y6, Z6 = verticalPlaneY( v[i][0]+1, v[i][1] , v[i][2] )
|
||||
|
||||
ax.plot_surface(X1, Y1, Z1, alpha=0.8, color='orange')
|
||||
ax.plot_surface(X2, Y2, Z2, alpha=0.8, color='orange')
|
||||
ax.plot_surface(X3, Y3, Z3, alpha=0.8, color='green' )
|
||||
ax.plot_surface(X4, Y4, Z4, alpha=0.8, color='green' )
|
||||
ax.plot_surface(X5, Y5, Z5, alpha=0.8, color='cyan' )
|
||||
ax.plot_surface(X6, Y6, Z6, alpha=0.8, color='cyan' )
|
||||
|
||||
x_min = np.inf
|
||||
x_max = -np.inf
|
||||
y_min = np.inf
|
||||
y_max = -np.inf
|
||||
z_min = np.inf
|
||||
z_max = -np.inf
|
||||
for i in range(l):
|
||||
x_min = np.min([x_min, v[i][0]])
|
||||
x_max = np.max([x_max, v[i][0]])
|
||||
y_min = np.min([y_min, v[i][1]])
|
||||
y_max = np.max([y_max, v[i][1]])
|
||||
z_min = np.min([z_min, v[i][2]])
|
||||
z_max = np.max([z_max, v[i][2]])
|
||||
|
||||
biggest_length = max([x_max-x_min, y_max-y_min, z_max-z_min])
|
||||
x_diff = (biggest_length - (x_max - x_min)) / 2
|
||||
x_lim_min = x_min - x_diff
|
||||
x_lim_max = x_max + x_diff
|
||||
|
||||
y_diff = (biggest_length - (y_max - y_min)) / 2
|
||||
y_lim_min = y_min - y_diff
|
||||
y_lim_max = y_max + y_diff
|
||||
|
||||
z_diff = (biggest_length - (z_max - z_min)) / 2
|
||||
z_lim_min = z_min - z_diff
|
||||
z_lim_max = z_max + z_diff
|
||||
|
||||
ax.scatter([x_lim_min, x_lim_max+1], [y_lim_min, y_lim_max+1], [z_lim_min, z_lim_max+1], alpha=0)
|
||||
|
||||
def getPoints(a):
|
||||
x = a[0]
|
||||
y = a[1]
|
||||
z = a[2]
|
||||
p = [
|
||||
[x, y, z ],
|
||||
[x+1, y, z ],
|
||||
[x+1, y+1, z ],
|
||||
[x, y+1, z ],
|
||||
[x, y, z+1],
|
||||
[x+1, y, z+1],
|
||||
[x+1, y+1, z+1],
|
||||
[x, y+1, z+1]
|
||||
]
|
||||
return p
|
||||
|
||||
def horizontalPlane(x, y, z):
|
||||
one = np.ones(4).reshape(2, 2)
|
||||
r1 = [x, x + 1]
|
||||
r2 = [y, y + 1]
|
||||
X, Y = np.meshgrid(r1, r2)
|
||||
Z = one*z
|
||||
return X, Y, Z
|
||||
|
||||
def verticalPlaneX(x, y, z):
|
||||
one = np.ones(4).reshape(2, 2)
|
||||
r1 = [x, x + 1]
|
||||
r2 = [z, z + 1]
|
||||
X, Z = np.meshgrid(r1, r2)
|
||||
Y = one*y
|
||||
return X, Y, Z
|
||||
|
||||
|
||||
def verticalPlaneY(x, y, z):
|
||||
one = np.ones(4).reshape(2, 2)
|
||||
r1 = [y, y + 1]
|
||||
r2 = [z, z + 1]
|
||||
Y, Z = np.meshgrid(r1, r2)
|
||||
X = one*x
|
||||
return X, Y, Z
|
||||
"""
|
||||
|
||||
function plotShape(t::Vector{Int64})
|
||||
T = deserialize("results.bin")
|
||||
v = T[2][t[1]][t[2]]
|
||||
|
||||
py"plotShapePY"(v)
|
||||
end
|
||||
|
||||
function plotShapes(t::Vector{Int64})
|
||||
T = deserialize("results.bin")
|
||||
v = T[2][t[1]]
|
||||
|
||||
py"plotShapesPY"(v)
|
||||
end
|
||||
@@ -4,6 +4,8 @@ global _calculatedPowerSets = Matrix{Int64}(undef, 1, 0)
|
||||
global _grownUntil = 0
|
||||
|
||||
function getPowerSet(setSize::Integer)
|
||||
global _calculatedPowerSets
|
||||
global _grownUntil
|
||||
wantedPowerSetSize = 2^setSize
|
||||
if setSize <= _grownUntil
|
||||
return _calculatedPowerSets[1:wantedPowerSetSize, 1:setSize]
|
||||
@@ -29,13 +31,19 @@ end
|
||||
|
||||
function getPowerSubSet(setSize::Integer, subSetSize::Integer)
|
||||
PowerSet = getPowerSet(setSize)
|
||||
setSizes = dropdim(sum(Powerset, dims = 2), dims = 2)
|
||||
setSizes = dropdims(sum(PowerSet, dims = 2), dims = 2)
|
||||
powerSubSetSize = binomial(setSize, subSetSize)
|
||||
powerSubSets = Matrix{Int64}(undef, powerSubSetSize, setSize)
|
||||
powerSubSets = Matrix{Int64}(undef, powerSubSetSize, subSetSize)
|
||||
j = 1
|
||||
for i ∈ 1:setSize
|
||||
for i ∈ axes(PowerSet, 1)
|
||||
if setSizes[i] == subSetSize
|
||||
powerSubSets[j, :] = PowerSet[i, :]
|
||||
l = 1
|
||||
for k ∈ axes(PowerSet, 2)
|
||||
if PowerSet[i, k] == 1
|
||||
powerSubSets[j, l] = k
|
||||
l += 1
|
||||
end
|
||||
end
|
||||
j += 1
|
||||
end
|
||||
end
|
||||
|
||||
59
julia/Rotations.jl
Normal file
59
julia/Rotations.jl
Normal file
@@ -0,0 +1,59 @@
|
||||
|
||||
const global _rot01(x) = (x[1], x[2], x[3])
|
||||
const global _rot02(x) = (x[2], x[3], x[1])
|
||||
const global _rot03(x) = (x[3], x[1], x[2])
|
||||
|
||||
const global _rot04(x) = (x[1], x[2], -x[3])
|
||||
const global _rot05(x) = (x[2], x[3], -x[1])
|
||||
const global _rot06(x) = (x[3], x[1], -x[2])
|
||||
|
||||
const global _rot07(x) = (x[1], -x[2], x[3])
|
||||
const global _rot08(x) = (x[2], -x[3], x[1])
|
||||
const global _rot09(x) = (x[3], -x[1], x[2])
|
||||
|
||||
const global _rot10(x) = (x[1], -x[2], -x[3])
|
||||
const global _rot11(x) = (x[2], -x[3], -x[1])
|
||||
const global _rot12(x) = (x[3], -x[1], -x[2])
|
||||
|
||||
const global _rot13(x) = (-x[1], x[2], x[3])
|
||||
const global _rot14(x) = (-x[2], x[3], x[1])
|
||||
const global _rot15(x) = (-x[3], x[1], x[2])
|
||||
|
||||
const global _rot16(x) = (-x[1], x[2], -x[3])
|
||||
const global _rot17(x) = (-x[2], x[3], -x[1])
|
||||
const global _rot18(x) = (-x[3], x[1], -x[2])
|
||||
|
||||
const global _rot19(x) = (-x[1], -x[2], x[3])
|
||||
const global _rot20(x) = (-x[2], -x[3], x[1])
|
||||
const global _rot21(x) = (-x[3], -x[1], x[2])
|
||||
|
||||
const global _rot22(x) = (-x[1], -x[2], -x[3])
|
||||
const global _rot23(x) = (-x[2], -x[3], -x[1])
|
||||
const global _rot24(x) = (-x[3], -x[1], -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
|
||||
]
|
||||
@@ -1,28 +1,40 @@
|
||||
include("SortingModifiers.jl")
|
||||
include("Rotations.jl")
|
||||
|
||||
struct Shape
|
||||
cubes::Set{Tuple{Int8, Int8, Int8}}
|
||||
recentCubes::Set{Tuple{Int8, Int8, Int8}}
|
||||
orderedLists::Vector{Vector{Tuple{Int8, Int8, Int8}}}
|
||||
cubes::Set{Tuple{Int64, Int64, Int64}}
|
||||
recentCubes::Set{Tuple{Int64, Int64, Int64}}
|
||||
orderedLists::Vector{Vector{Tuple{Int64, Int64, Int64}}}
|
||||
end
|
||||
|
||||
function trypush!(S::Shape, t::Tuple{Int8, Int8, Int8})
|
||||
if t ∈ S.cubes
|
||||
return false
|
||||
else
|
||||
function Base.:push!(S::Shape, t::Tuple{Int64, Int64, Int64})
|
||||
push!(S.cubes, t)
|
||||
for i ∈ 1:24
|
||||
index = searchsortedfirst(S.orderedLists[i], t, by=SortingModifiers[i])
|
||||
insert!(S.orderedLists, index, t)
|
||||
t_rot = Rotations[i](t)
|
||||
index = searchsortedfirst(S.orderedLists[i], t_rot)
|
||||
insert!(S.orderedLists[i], index, t_rot)
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
function getPossibleNeighbors(S::Shape)
|
||||
possibleSpots = Set{Tuple{Int64, Int64, Int64}}()
|
||||
for p ∈ S.cubes
|
||||
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 Shape(
|
||||
{(0, 0, 0)},
|
||||
{(0, 0, 0)},
|
||||
Set([(0, 0, 0)]),
|
||||
Set([(0, 0, 0)]),
|
||||
[
|
||||
[(0, 0, 0)],
|
||||
[(0, 0, 0)],
|
||||
|
||||
@@ -1,59 +0,0 @@
|
||||
|
||||
const global _comp01(x) = (x[1], x[2], x[3])
|
||||
const global _comp02(x) = (x[2], x[3], x[1])
|
||||
const global _comp03(x) = (x[3], x[1], x[2])
|
||||
|
||||
const global _comp04(x) = (x[1], x[2], -x[3])
|
||||
const global _comp05(x) = (x[2], x[3], -x[1])
|
||||
const global _comp06(x) = (x[3], x[1], -x[2])
|
||||
|
||||
const global _comp07(x) = (x[1], -x[2], x[3])
|
||||
const global _comp08(x) = (x[2], -x[3], x[1])
|
||||
const global _comp09(x) = (x[3], -x[1], x[2])
|
||||
|
||||
const global _comp10(x) = (x[1], -x[2], -x[3])
|
||||
const global _comp11(x) = (x[2], -x[3], -x[1])
|
||||
const global _comp12(x) = (x[3], -x[1], -x[2])
|
||||
|
||||
const global _comp13(x) = (-x[1], x[2], x[3])
|
||||
const global _comp14(x) = (-x[2], x[3], x[1])
|
||||
const global _comp15(x) = (-x[3], x[1], x[2])
|
||||
|
||||
const global _comp16(x) = (-x[1], x[2], -x[3])
|
||||
const global _comp17(x) = (-x[2], x[3], -x[1])
|
||||
const global _comp18(x) = (-x[3], x[1], -x[2])
|
||||
|
||||
const global _comp19(x) = (-x[1], -x[2], x[3])
|
||||
const global _comp20(x) = (-x[2], -x[3], x[1])
|
||||
const global _comp21(x) = (-x[3], -x[1], x[2])
|
||||
|
||||
const global _comp22(x) = (-x[1], -x[2], -x[3])
|
||||
const global _comp23(x) = (-x[2], -x[3], -x[1])
|
||||
const global _comp24(x) = (-x[3], -x[1], -x[2])
|
||||
|
||||
const global SortingModifiers = [
|
||||
_comp01,
|
||||
_comp02,
|
||||
_comp03,
|
||||
_comp04,
|
||||
_comp05,
|
||||
_comp06,
|
||||
_comp07,
|
||||
_comp08,
|
||||
_comp09,
|
||||
_comp10,
|
||||
_comp11,
|
||||
_comp12,
|
||||
_comp13,
|
||||
_comp14,
|
||||
_comp15,
|
||||
_comp16,
|
||||
_comp17,
|
||||
_comp18,
|
||||
_comp19,
|
||||
_comp20,
|
||||
_comp21,
|
||||
_comp22,
|
||||
_comp23,
|
||||
_comp24
|
||||
]
|
||||
3
julia/TupleMisc.jl
Normal file
3
julia/TupleMisc.jl
Normal file
@@ -0,0 +1,3 @@
|
||||
|
||||
Base.:+(X::Tuple{Integer, Integer, Integer}, Y::Tuple{Integer, Integer, Integer}) = (X[1]+Y[1], X[2]+Y[2], X[3]+Y[3])
|
||||
Base.:-(X::Tuple{Integer, Integer, Integer}, Y::Tuple{Integer, Integer, Integer}) = (X[1]-Y[1], X[2]-Y[2], X[3]-Y[3])
|
||||
BIN
julia/results.bin
Normal file
BIN
julia/results.bin
Normal file
Binary file not shown.
Reference in New Issue
Block a user