Projektdateien hinzufügen.
This commit is contained in:
56
.cs
Normal file
56
.cs
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Collections.Specialized;
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
|
public class Shape {
|
||||||
|
private int _x;
|
||||||
|
private int _y;
|
||||||
|
private int _z;
|
||||||
|
private SortedDictionary<(int, int, int), int>[] _data;
|
||||||
|
public bool this[int x, int y, int z] {;
|
||||||
|
get {
|
||||||
|
if (x < _x && y < _y && z < _z && x >= 0 && y >= 0 && z >= 0) {
|
||||||
|
return _data[(x, y, z)];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
throw new IndexOutOfRangeException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private Shape(int x, int y, int z) {
|
||||||
|
_x = x;
|
||||||
|
_y = y;
|
||||||
|
_z = z;
|
||||||
|
|
||||||
|
_data = new SortedDictionary<(int, int, int), int>[24];
|
||||||
|
for (int i = 0; i < 24; i++) {
|
||||||
|
int rot = i%3;
|
||||||
|
int corner = (i/3)%8;
|
||||||
|
bool apos = corner%2;
|
||||||
|
bool bpos = (corner/2)%2;
|
||||||
|
bool cpos = (corner/4)%2;
|
||||||
|
Func<Tuple<int, int, int>, Tuple<int, int, int>, int> comparer = (Tuple<int, int, int> A, Tuple<int, int, int> B) => {
|
||||||
|
int[] d = new int[3];
|
||||||
|
d[0] = (apos ? 1 : -1)*(B.Item1 - A.Item1);
|
||||||
|
d[1] = (bpos ? 1 : -1)*(B.Item2 - A.Item2);
|
||||||
|
d[2] = (cpos ? 1 : -1)*(B.Item3 - A.Item3);
|
||||||
|
return d[(2+rot)%3] != 0 ? d[(2+rot)%3] : (d[(1+rot)%3] != 0 ? d[(1+rot)%3] : d[rot]);
|
||||||
|
};
|
||||||
|
_data[i] = new SortedDictionary<Tuple<int, int, int>, int>(comparer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Shape Grow(int x, int y, int z) {
|
||||||
|
Tuple<int, int, int> newP = new Tuple<int, int, int>(x, y, z);
|
||||||
|
if (this._data[0].ContainsKey(newP) throw new InvalidOperationException();
|
||||||
|
else if (this._data[0].ContainsKey(new Tuple<int, int, int>(x+1, y, z)))
|
||||||
|
else throw new InvalidOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Shape GetCube() {
|
||||||
|
Shape S = new Shape(1, 1, 1);
|
||||||
|
S._data[0] = 1;
|
||||||
|
return S;
|
||||||
|
}
|
||||||
|
}
|
||||||
12
AssembledObject.cs
Normal file
12
AssembledObject.cs
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
using System.Collections;
|
||||||
|
using System.IO.Hashing;
|
||||||
|
|
||||||
|
public class AssembledObject {
|
||||||
|
private static XxHash32 _hash = new XxHash32();
|
||||||
|
|
||||||
|
private BitArray _shape;
|
||||||
|
|
||||||
|
public override int GetHashCode() {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
25
CubeShapeCounting.sln
Normal file
25
CubeShapeCounting.sln
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
|
||||||
|
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||||
|
# Visual Studio Version 17
|
||||||
|
VisualStudioVersion = 17.6.33829.357
|
||||||
|
MinimumVisualStudioVersion = 10.0.40219.1
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CubeShapeCounting", "CubeShapeCounting\CubeShapeCounting.csproj", "{922321A0-14E9-4BED-9E4D-8A8DD12E17CB}"
|
||||||
|
EndProject
|
||||||
|
Global
|
||||||
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
|
Debug|Any CPU = Debug|Any CPU
|
||||||
|
Release|Any CPU = Release|Any CPU
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||||
|
{922321A0-14E9-4BED-9E4D-8A8DD12E17CB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{922321A0-14E9-4BED-9E4D-8A8DD12E17CB}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{922321A0-14E9-4BED-9E4D-8A8DD12E17CB}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{922321A0-14E9-4BED-9E4D-8A8DD12E17CB}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
|
HideSolutionNode = FALSE
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||||
|
SolutionGuid = {2C62E5D9-6E88-44D3-8756-535F580C5B8E}
|
||||||
|
EndGlobalSection
|
||||||
|
EndGlobal
|
||||||
14
CubeShapeCounting/CubeShapeCounting.csproj
Normal file
14
CubeShapeCounting/CubeShapeCounting.csproj
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<OutputType>Exe</OutputType>
|
||||||
|
<TargetFramework>net7.0</TargetFramework>
|
||||||
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
|
<Nullable>enable</Nullable>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="System.IO.Hashing" Version="7.0.0" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
</Project>
|
||||||
31
CubeShapeCounting/Program.cs
Normal file
31
CubeShapeCounting/Program.cs
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
namespace CubeShapeCounting {
|
||||||
|
internal class Program {
|
||||||
|
private int _numBlocks = 0;
|
||||||
|
//private Dictionary<>();
|
||||||
|
|
||||||
|
public Program(int numBlocks) {
|
||||||
|
this._numBlocks = numBlocks;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Start() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static void Main(string[] args) {
|
||||||
|
if (args.Length != 1) {
|
||||||
|
Console.WriteLine("Expected 1 argument");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
int numBlocks;
|
||||||
|
try {
|
||||||
|
numBlocks = Int32.Parse(args[0]);
|
||||||
|
}
|
||||||
|
catch {
|
||||||
|
Console.WriteLine("Cannot parse" + args[0] + "as an Int32.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Program P = new Program(numBlocks);
|
||||||
|
P.Start();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
142
CubeShapeCounting/Shape.cs
Normal file
142
CubeShapeCounting/Shape.cs
Normal file
@@ -0,0 +1,142 @@
|
|||||||
|
using System.Buffers.Binary;
|
||||||
|
using System.Collections.Immutable;
|
||||||
|
using System.Collections.ObjectModel;
|
||||||
|
using System.IO.Hashing;
|
||||||
|
using System.Security.Cryptography;
|
||||||
|
|
||||||
|
public class Shape {
|
||||||
|
private (int, int, int) _minp;
|
||||||
|
private (int, int, int) _maxp;
|
||||||
|
private (int, int, int)[] _newest;
|
||||||
|
private SortedDictionary<(int, int, int), int>[] _data;
|
||||||
|
public bool this[int x, int y, int z] {
|
||||||
|
get {
|
||||||
|
if (x <= _maxp.Item1 && y <= _maxp.Item2 && z <= _maxp.Item3 && x >= _minp.Item1 && y >= _minp.Item2 && z >= _minp.Item3) {
|
||||||
|
return _data[0].ContainsKey((x, y, z));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
throw new IndexOutOfRangeException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private Shape((int, int, int) minp, (int, int, int) maxp, (int, int, int)[] newest, SortedDictionary<(int, int, int), int>[] D) {
|
||||||
|
_minp = minp;
|
||||||
|
_maxp = maxp;
|
||||||
|
_newest = newest;
|
||||||
|
_data = D;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<(int, int, int)> GetGrowableSpaces() {
|
||||||
|
List<(int, int, int)> L = new List<(int, int, int)>();
|
||||||
|
foreach ((int x, int y, int z) in _data[0].Keys) {
|
||||||
|
if (!_data[0].ContainsKey((x + 1, y, z)) && !L.Contains((x + 1, y, z)))
|
||||||
|
L.Add((x + 1, y, z));
|
||||||
|
if (!_data[0].ContainsKey((x - 1, y, z)) && !L.Contains((x - 1, y, z)))
|
||||||
|
L.Add((x - 1, y, z));
|
||||||
|
if (!_data[0].ContainsKey((x, y + 1, z)) && !L.Contains((x, y + 1, z)))
|
||||||
|
L.Add((x, y + 1, z));
|
||||||
|
if (!_data[0].ContainsKey((x, y - 1, z)) && !L.Contains((x, y - 1, z)))
|
||||||
|
L.Add((x, y - 1, z));
|
||||||
|
if (!_data[0].ContainsKey((x, y, z + 1)) && !L.Contains((x, y, z + 1)))
|
||||||
|
L.Add((x, y, z + 1));
|
||||||
|
if (!_data[0].ContainsKey((x, y, z - 1)) && !L.Contains((x, y, z - 1)))
|
||||||
|
L.Add((x, y, z - 1));
|
||||||
|
}
|
||||||
|
return L;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Shape Grow((int, int, int)[] newPs) {
|
||||||
|
SortedDictionary<(int, int, int), int> D = this._data[0];
|
||||||
|
for (int i = 0; i < newPs.Length; i++) {
|
||||||
|
(int x, int y, int z) = newPs[i];
|
||||||
|
if (D.ContainsKey(newPs[i]) ||
|
||||||
|
(!D.ContainsKey((x + 1, y, z))
|
||||||
|
&& !D.ContainsKey((x - 1, y, z))
|
||||||
|
&& !D.ContainsKey((x, y + 1, z))
|
||||||
|
&& !D.ContainsKey((x, y - 1, z))
|
||||||
|
&& !D.ContainsKey((x, y, z + 1))
|
||||||
|
&& !D.ContainsKey((x, y, z - 1))))
|
||||||
|
throw new InvalidOperationException();
|
||||||
|
}
|
||||||
|
SortedDictionary<(int, int, int), int>[] newD = new SortedDictionary<(int, int, int), int>[24];
|
||||||
|
for (int i = 0; i < 24; i++) {
|
||||||
|
int rot = i%3;
|
||||||
|
int corner = (i/3)%8;
|
||||||
|
bool apos = corner%2 != 0;
|
||||||
|
bool bpos = (corner/2)%2 != 0;
|
||||||
|
bool cpos = (corner/4)%2 != 0;
|
||||||
|
Comparison<(int, int, int)> comparer = ((int, int, int) A, (int, int, int) B) => {
|
||||||
|
int[] d = new int[3];
|
||||||
|
d[0] = (apos ? 1 : -1)*(B.Item1 - A.Item1);
|
||||||
|
d[1] = (bpos ? 1 : -1)*(B.Item2 - A.Item2);
|
||||||
|
d[2] = (cpos ? 1 : -1)*(B.Item3 - A.Item3);
|
||||||
|
return d[(2+rot)%3] != 0 ? d[(2+rot)%3] : (d[(1+rot)%3] != 0 ? d[(1+rot)%3] : d[rot]);
|
||||||
|
};
|
||||||
|
newD[i] = new SortedDictionary<(int, int, int), int>(D, Comparer<(int, int, int)>.Create(comparer));
|
||||||
|
}
|
||||||
|
(int, int, int) newminp = this._minp;
|
||||||
|
(int, int, int) newmaxp = this._maxp;
|
||||||
|
for (int i = 0; i < newPs.Length; i++) {
|
||||||
|
for (int j = 0; j < newPs.Length; j++)
|
||||||
|
newD[i].Add(newPs[i], 0);
|
||||||
|
newminp = (Math.Min(newminp.Item1, newPs[i].Item1), Math.Min(newminp.Item2, newPs[i].Item2), Math.Min(newminp.Item3, newPs[i].Item3));
|
||||||
|
newmaxp = (Math.Max(newmaxp.Item1, newPs[i].Item1), Math.Max(newmaxp.Item2, newPs[i].Item2), Math.Max(newmaxp.Item3, newPs[i].Item3));
|
||||||
|
}
|
||||||
|
return new Shape(newminp, newmaxp, newPs, newD);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ImmutableOrientedShape[] GetOrientations() {
|
||||||
|
ImmutableOrientedShape[] S = new ImmutableOrientedShape[24];
|
||||||
|
for (int i = 0; i < 24; i++) {
|
||||||
|
S[i] = new ImmutableOrientedShape(_data[i]);
|
||||||
|
}
|
||||||
|
return S;
|
||||||
|
}
|
||||||
|
|
||||||
|
public class ImmutableOrientedShape {
|
||||||
|
public readonly ImmutableSortedDictionary<(int, int, int), int> Dict;
|
||||||
|
public readonly int Hash;
|
||||||
|
|
||||||
|
internal ImmutableOrientedShape(SortedDictionary<(int, int, int), int> D) {
|
||||||
|
Dict = D.ToImmutableSortedDictionary();
|
||||||
|
XxHash64 H = new XxHash64(0);
|
||||||
|
IEnumerable<(int, int, int)> keys = Dict.Keys;
|
||||||
|
(int a, int b, int c) = keys.First();
|
||||||
|
Span<byte> s = new byte[12];
|
||||||
|
foreach ((int x, int y, int z) in keys) {
|
||||||
|
BinaryPrimitives.WriteInt32BigEndian(s.Slice(0), x - a);
|
||||||
|
BinaryPrimitives.WriteInt32BigEndian(s.Slice(4), y - b);
|
||||||
|
BinaryPrimitives.WriteInt32BigEndian(s.Slice(8), z - c);
|
||||||
|
H.Append(s.ToArray());
|
||||||
|
}
|
||||||
|
Hash = BinaryPrimitives.ReadInt32BigEndian(H.GetCurrentHash());
|
||||||
|
}
|
||||||
|
|
||||||
|
public override int GetHashCode() {
|
||||||
|
return Hash;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override bool Equals(object? obj) {
|
||||||
|
if (!(obj is ImmutableOrientedShape))
|
||||||
|
return false;
|
||||||
|
ImmutableOrientedShape o = (ImmutableOrientedShape)obj;
|
||||||
|
IEnumerable<(int, int, int)> K1 = Dict.Keys;
|
||||||
|
IEnumerable<(int, int, int)> K2 = o.Dict.Keys;
|
||||||
|
if (K1.Count() != K2.Count())
|
||||||
|
return false;
|
||||||
|
foreach (((int a1, int a2, int a3), (int b1, int b2, int b3)) in K1.Zip(K2))
|
||||||
|
if (a1 != b1 || a2 != b2 || a3 != b3)
|
||||||
|
return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Shape GetCube() {
|
||||||
|
SortedDictionary<(int, int, int), int>[] newD = new SortedDictionary<(int, int, int), int>[24];
|
||||||
|
for (int i = 0; i < 24; i++) {
|
||||||
|
newD[i] = new SortedDictionary<(int, int, int), int>();
|
||||||
|
newD[i].Add((0, 0, 0), 0);
|
||||||
|
}
|
||||||
|
return new Shape((1, 1, 1), (1, 1, 1), new (int, int, int)[] {(0, 0, 0)}, newD);
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user