From a38e93a607a140e3d31b3b8104343378bb024f4e Mon Sep 17 00:00:00 2001 From: benbierens Date: Mon, 14 Oct 2024 10:10:18 +0200 Subject: [PATCH] set up logical operations for indexset --- .../Utils/RunLengthEncodingLogicalTests.cs | 73 +++++++ .../Utils/RunLengthEncodingRunTests.cs | 2 - .../Utils/RunLengthEncodingTests.cs | 184 +++++++++--------- 3 files changed, 168 insertions(+), 91 deletions(-) create mode 100644 Tests/FrameworkTests/Utils/RunLengthEncodingLogicalTests.cs diff --git a/Tests/FrameworkTests/Utils/RunLengthEncodingLogicalTests.cs b/Tests/FrameworkTests/Utils/RunLengthEncodingLogicalTests.cs new file mode 100644 index 0000000..e212d24 --- /dev/null +++ b/Tests/FrameworkTests/Utils/RunLengthEncodingLogicalTests.cs @@ -0,0 +1,73 @@ +using NUnit.Framework; + +namespace FrameworkTests.Utils +{ + [TestFixture] + public class RunLengthEncodingLogicalTests + { + [Test] + public void Overlap() + { + var setA = new IndexSet([1, 2, 3, 4, 5, 11, 14]); + var setB = new IndexSet([3, 4, 5, 6, 7, 11, 12, 13]); + var expectedSet = new IndexSet([3, 4, 5, 11]); + + var set = setA.Overlap(setB); + + Assert.That(set, Is.EqualTo(expectedSet)); + } + + [Test] + public void Merge() + { + var setA = new IndexSet([1, 2, 3, 4, 5, 11, 14]); + var setB = new IndexSet([3, 4, 5, 6, 7, 11, 12, 13]); + var expectedSet = new IndexSet([1, 2, 3, 4, 5, 6, 7, 11, 12, 13, 14]); + + var set = setA.Merge(setB); + + Assert.That(set, Is.EqualTo(expectedSet)); + } + + [Test] + public void Without() + { + var setA = new IndexSet([1, 2, 3, 4, 5, 11, 14]); + var setB = new IndexSet([3, 4, 5, 6, 7, 11, 12, 13]); + var expectedSet = new IndexSet([1, 2, 14]); + + var set = setA.Without(setB); + + Assert.That(set, Is.EqualTo(expectedSet)); + } + } + + public partial class IndexSet + { + public IndexSet Overlap(IndexSet other) + { + return this; + } + + public IndexSet Merge(IndexSet other) + { + return this; + } + + public IndexSet Without(IndexSet other) + { + return this; + } + + public override bool Equals(object? obj) + { + return obj is IndexSet set && + EqualityComparer>.Default.Equals(runs, set.runs); + } + + public override int GetHashCode() + { + return HashCode.Combine(runs); + } + } +} diff --git a/Tests/FrameworkTests/Utils/RunLengthEncodingRunTests.cs b/Tests/FrameworkTests/Utils/RunLengthEncodingRunTests.cs index d3544c1..0f2730d 100644 --- a/Tests/FrameworkTests/Utils/RunLengthEncodingRunTests.cs +++ b/Tests/FrameworkTests/Utils/RunLengthEncodingRunTests.cs @@ -1,6 +1,4 @@ using NUnit.Framework; -using NUnit.Framework.Interfaces; -using static FrameworkTests.Utils.RunLengthEncodingTests; namespace FrameworkTests.Utils { diff --git a/Tests/FrameworkTests/Utils/RunLengthEncodingTests.cs b/Tests/FrameworkTests/Utils/RunLengthEncodingTests.cs index aaddbcb..6d9fe2a 100644 --- a/Tests/FrameworkTests/Utils/RunLengthEncodingTests.cs +++ b/Tests/FrameworkTests/Utils/RunLengthEncodingTests.cs @@ -1,9 +1,4 @@ -using Logging; -using Microsoft.VisualStudio.TestPlatform.Common; -using NuGet.Frameworks; -using NUnit.Framework; -using System.Collections.Concurrent; -using System.Numerics; +using NUnit.Framework; using Utils; namespace FrameworkTests.Utils @@ -201,119 +196,130 @@ namespace FrameworkTests.Utils all.Sort(); return all.ToArray(); } + } - public class IndexSet + public partial class IndexSet + { + private readonly SortedList runs = new SortedList(); + + public IndexSet() { - private readonly SortedList runs = new SortedList(); + } - public IndexSet() + public IndexSet(int[] indices) + { + foreach (var i in indices) Set(i); + } + + public static IndexSet FromRunLengthEncoded(int[] rle) + { + var set = new IndexSet(); + for (var i = 0; i < rle.Length; i += 2) { + var start = rle[i]; + var length = rle[i + 1]; + set.runs.Add(start, new Run(start, length)); } - public IndexSet(int[] indices) + return set; + } + + public bool IsSet(int index) + { + if (runs.ContainsKey(index)) return true; + + var run = GetRunBefore(index); + if (run == null) return false; + + return run.Includes(index); + } + + public void Set(int index) + { + if (runs.ContainsKey(index)) return; + + var run = GetRunBefore(index); + if (run == null || !run.ExpandToInclude(index)) { - foreach (var i in indices) Set(i); + CreateNewRun(index); } + } - public static IndexSet FromRunLengthEncoded(int[] rle) + public void Unset(int index) + { + if (runs.ContainsKey(index)) { - var set = new IndexSet(); - for (var i = 0; i < rle.Length; i += 2) - { - var start = rle[i]; - var length = rle[i + 1]; - set.runs.Add(start, new Run(start, length)); - } - - return set; + HandleUpdate(runs[index].Unset(index)); } - - public bool IsSet(int index) + else { - if (runs.ContainsKey(index)) return true; - var run = GetRunBefore(index); - if (run == null) return false; - - return run.Includes(index); + if (run == null) return; + HandleUpdate(run.Unset(index)); } + } - public void Set(int index) + public void Iterate(Action onIndex) + { + foreach (var run in runs.Values) { - if (runs.ContainsKey(index)) return; - - var run = GetRunBefore(index); - if (run == null || !run.ExpandToInclude(index)) - { - CreateNewRun(index); - } + run.Iterate(onIndex); } + } - public void Unset(int index) + public int[] RunLengthEncoded() + { + return Encode().ToArray(); + } + + public override string ToString() + { + var result = ""; + var encoded = RunLengthEncoded(); + foreach (var pair in runs) { - if (runs.ContainsKey(index)) - { - HandleUpdate(runs[index].Unset(index)); - } - else - { - var run = GetRunBefore(index); - if (run == null) return; - HandleUpdate(run.Unset(index)); - } + result += $"[{pair.Value.Start},{pair.Value.Length}]]"; } + return result; + } - public void Iterate(Action onIndex) + private IEnumerable Encode() + { + foreach (var pair in runs) { - foreach (var run in runs.Values) - { - run.Iterate(onIndex); - } + yield return pair.Value.Start; + yield return pair.Value.Length; } + } - public int[] RunLengthEncoded() + private Run? GetRunBefore(int index) + { + Run? result = null; + foreach (var pair in runs) { - return Encode().ToArray(); + if (pair.Key < index) result = pair.Value; + else return result; } + return result; + } - private IEnumerable Encode() + private void HandleUpdate(RunUpdate runUpdate) + { + foreach (var newRun in runUpdate.NewRuns) runs.Add(newRun.Start, newRun); + foreach (var removeRun in runUpdate.RemoveRuns) runs.Remove(removeRun.Start); + } + + private void CreateNewRun(int index) + { + if (runs.ContainsKey(index + 1)) { - foreach (var pair in runs) - { - yield return pair.Value.Start; - yield return pair.Value.Length; - } + var length = runs[index + 1].Length + 1; + runs.Add(index, new Run(index, length)); + runs.Remove(index + 1); } - - private Run? GetRunBefore(int index) + else { - Run? result = null; - foreach (var pair in runs) - { - if (pair.Key < index) result = pair.Value; - else return result; - } - return result; - } - - private void HandleUpdate(RunUpdate runUpdate) - { - foreach (var newRun in runUpdate.NewRuns) runs.Add(newRun.Start, newRun); - foreach (var removeRun in runUpdate.RemoveRuns) runs.Remove(removeRun.Start); - } - - private void CreateNewRun(int index) - { - if (runs.ContainsKey(index + 1)) - { - var length = runs[index + 1].Length + 1; - runs.Add(index, new Run(index, length)); - runs.Remove(index + 1); - } - else - { - runs.Add(index, new Run(index, 1)); - } + runs.Add(index, new Run(index, 1)); } } }