From c645ded35da9d99588800dccf7a8a7c797a45b23 Mon Sep 17 00:00:00 2001 From: Aaron Siegel <2014957+aaron-siegel@users.noreply.github.com> Date: Fri, 22 Dec 2023 23:17:32 -0800 Subject: [PATCH] Add Strip.Decomposition method. (#52) Adds a method `Strip.Decomposition` analogous to `Grid.Decomposition`. --- .../cgsuite/lang/resources/cgsuite/util/Strip.cgs | 6 ++++++ .../src/main/scala/org/cgsuite/util/Strip.scala | 14 ++++++++++++++ .../scala/org/cgsuite/lang/CgsuiteUtilTest.scala | 3 +++ 3 files changed, 23 insertions(+) diff --git a/lib/core/src/main/resources/org/cgsuite/lang/resources/cgsuite/util/Strip.cgs b/lib/core/src/main/resources/org/cgsuite/lang/resources/cgsuite/util/Strip.cgs index 9a96d92b..484990b7 100644 --- a/lib/core/src/main/resources/org/cgsuite/lang/resources/cgsuite/util/Strip.cgs +++ b/lib/core/src/main/resources/org/cgsuite/lang/resources/cgsuite/util/Strip.cgs @@ -41,6 +41,12 @@ system class Strip */ external def op[](index as Integer) as Integer; + /** The decomposition of this `Strip` into connected components separated by entries with the specified `boundaryValue`. + * The result will be a `List` of `Strip`s, each corresponding to a single nonempty connected component of the + * original `Strip`. + */ + external def Decomposition(boundaryValue as Integer) as List; + /** A `List` of all indices at which this `Strip` has the specified value. */ external def FindAll(value as Integer) as List; diff --git a/lib/core/src/main/scala/org/cgsuite/util/Strip.scala b/lib/core/src/main/scala/org/cgsuite/util/Strip.scala index 03e82e96..2c5f92cb 100644 --- a/lib/core/src/main/scala/org/cgsuite/util/Strip.scala +++ b/lib/core/src/main/scala/org/cgsuite/util/Strip.scala @@ -82,6 +82,20 @@ class Strip private[util] (private val values: Array[Byte]) extends Serializable new Strip(newValues) } + def decomposition(boundaryValue: Integer): IndexedSeq[Strip] = { + val boundaryValueInt = boundaryValue.intValue + val boundaryIndices = values.indices filter { values(_) == boundaryValueInt } + val tail = boundaryIndices.indices collect { + case k if boundaryIndices(k) + 1 < values.length && values(boundaryIndices(k) + 1) != boundaryValueInt => + new Strip(values.slice(boundaryIndices(k) + 1, if (k + 1 < boundaryIndices.length) boundaryIndices(k + 1) else values.length)) + } + if (values.isEmpty || values(0) == boundaryValueInt) + tail + else + new Strip(values.slice(0, if (boundaryIndices.isEmpty) values.length else boundaryIndices(0))) +: tail + + } + def findAll(value: Integer): IndexedSeq[Integer] = { val byte = value.intValue.toByte var cnt = 0 diff --git a/lib/core/src/test/scala/org/cgsuite/lang/CgsuiteUtilTest.scala b/lib/core/src/test/scala/org/cgsuite/lang/CgsuiteUtilTest.scala index 0e621b76..502cff7d 100644 --- a/lib/core/src/test/scala/org/cgsuite/lang/CgsuiteUtilTest.scala +++ b/lib/core/src/test/scala/org/cgsuite/lang/CgsuiteUtilTest.scala @@ -11,6 +11,9 @@ class CgsuiteUtilTest extends CgscriptSpec { ("Empty", "Strip.Empty(8)", "Strip([0,0,0,0,0,0,0,0])"), ("Parse", """strip := Strip.Parse(".abbd.", ".abcd")""", "Strip([0,1,2,2,4,0])"), ("op []", "strip[3]", "2"), + ("Decomposition", """strip.Decomposition(2)""", "[Strip([0,1]),Strip([4,0])]"), + ("Decomposition edges", """strip.Decomposition(0)""", "[Strip([1,2,2,4])]"), + ("Decomposition empty", """Strip.Empty(0).Decomposition(0)""", "[]"), ("FindAll", "strip.FindAll(2)", "[3,4]"), ("Length", "strip.Length", "6"), ("ToString", """strip.ToString(".abcd")""", "\".abbd.\""),