From c5bf09836fa1bc2ded1b1a4e76ecbf3fdf98de4b Mon Sep 17 00:00:00 2001 From: Maxime Vorwerk Date: Wed, 19 Jul 2023 18:25:21 +0200 Subject: [PATCH] =?UTF-8?q?Projektdateien=20hinzuf=C3=BCgen.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .cs | 56 ++++++++ AssembledObject.cs | 12 ++ CubeShapeCounting.sln | 25 ++++ CubeShapeCounting/CubeShapeCounting.csproj | 14 ++ CubeShapeCounting/Program.cs | 31 +++++ CubeShapeCounting/Shape.cs | 142 +++++++++++++++++++++ 6 files changed, 280 insertions(+) create mode 100644 .cs create mode 100644 AssembledObject.cs create mode 100644 CubeShapeCounting.sln create mode 100644 CubeShapeCounting/CubeShapeCounting.csproj create mode 100644 CubeShapeCounting/Program.cs create mode 100644 CubeShapeCounting/Shape.cs diff --git a/.cs b/.cs new file mode 100644 index 0000000..0fcd6ae --- /dev/null +++ b/.cs @@ -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> comparer = (Tuple A, Tuple 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, int>(comparer); + } + } + + public Shape Grow(int x, int y, int z) { + Tuple newP = new Tuple(x, y, z); + if (this._data[0].ContainsKey(newP) throw new InvalidOperationException(); + else if (this._data[0].ContainsKey(new Tuple(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; + } +} diff --git a/AssembledObject.cs b/AssembledObject.cs new file mode 100644 index 0000000..548610d --- /dev/null +++ b/AssembledObject.cs @@ -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; + } +} diff --git a/CubeShapeCounting.sln b/CubeShapeCounting.sln new file mode 100644 index 0000000..5a76496 --- /dev/null +++ b/CubeShapeCounting.sln @@ -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 diff --git a/CubeShapeCounting/CubeShapeCounting.csproj b/CubeShapeCounting/CubeShapeCounting.csproj new file mode 100644 index 0000000..a4742e5 --- /dev/null +++ b/CubeShapeCounting/CubeShapeCounting.csproj @@ -0,0 +1,14 @@ + + + + Exe + net7.0 + enable + enable + + + + + + + diff --git a/CubeShapeCounting/Program.cs b/CubeShapeCounting/Program.cs new file mode 100644 index 0000000..db0ae79 --- /dev/null +++ b/CubeShapeCounting/Program.cs @@ -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(); + } + } +} \ No newline at end of file diff --git a/CubeShapeCounting/Shape.cs b/CubeShapeCounting/Shape.cs new file mode 100644 index 0000000..8b2e20e --- /dev/null +++ b/CubeShapeCounting/Shape.cs @@ -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 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); + } +}