From b8e6d9c2b8d0f2f1aefe37bef8ff02da26d7b7d3 Mon Sep 17 00:00:00 2001 From: harry0000 Date: Sun, 14 Apr 2024 23:21:12 +0900 Subject: [PATCH 1/3] Update munit version --- build.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.sbt b/build.sbt index b100bb5..f62b824 100644 --- a/build.sbt +++ b/build.sbt @@ -16,6 +16,6 @@ lazy val root = project "-unchecked", "-Wunused:all" ), - libraryDependencies += "org.scalameta" %% "munit" % "0.7.29" % Test, + libraryDependencies += "org.scalameta" %% "munit" % "1.0.0-M11" % Test, Test / parallelExecution := false ) From 9fd00e918a29db7cf6952b101388bbae62745ef9 Mon Sep 17 00:00:00 2001 From: harry0000 Date: Mon, 15 Apr 2024 02:28:30 +0900 Subject: [PATCH 2/3] Add zAlgorithm --- src/main/scala/io/github/acl4s/String.scala | 34 +++++++++++++++++++ .../scala/io/github/acl4s/StringSuite.scala | 20 +++++++++++ 2 files changed, 54 insertions(+) create mode 100644 src/main/scala/io/github/acl4s/String.scala create mode 100644 src/test/scala/io/github/acl4s/StringSuite.scala diff --git a/src/main/scala/io/github/acl4s/String.scala b/src/main/scala/io/github/acl4s/String.scala new file mode 100644 index 0000000..6e2942c --- /dev/null +++ b/src/main/scala/io/github/acl4s/String.scala @@ -0,0 +1,34 @@ +package io.github.acl4s + +import scala.reflect.ClassTag + +/** + * Reference: + * D. Gusfield, + * Algorithms on Strings, Trees, and Sequences: Computer Science and + * Computational Biology + */ +private[acl4s] def zAlgorithmImpl[T: ClassTag](s: Array[T]): Array[Int] = { + val n = s.length + if (n == 0) { + return Array.empty + } + val z = new Array[Int](n) + z(0) = 0 + var j = 0 + for (i <- 1 until n) { + var k = if (j + z(j) <= i) { 0 } + else { Math.min(j + z(j) - i, z(i - j)) } + while (i + k < n && s(k) == s(i + k)) { + k += 1 + } + z(i) = k + if (j + z(j) < i + z(i)) { + j = i + } + } + z(0) = n + z +} + +def zAlgorithm(s: String): Array[Int] = zAlgorithmImpl(s.toCharArray) diff --git a/src/test/scala/io/github/acl4s/StringSuite.scala b/src/test/scala/io/github/acl4s/StringSuite.scala new file mode 100644 index 0000000..e1a5ec8 --- /dev/null +++ b/src/test/scala/io/github/acl4s/StringSuite.scala @@ -0,0 +1,20 @@ +package io.github.acl4s + +class StringSuite extends munit.FunSuite { + + test("zAlgorithm") { + { + val str = "abracadabra"; + val lcp = zAlgorithm(str) + + assertEquals(lcp.toSeq, Seq(11, 0, 0, 1, 0, 1, 0, 4, 0, 0, 1)) + } + { + val str = "ababababa" + val lcp = zAlgorithm(str) + + assertEquals(lcp.toSeq, Seq(9, 0, 7, 0, 5, 0, 3, 0, 1)) + } + } + +} From ad634f351c058fe3e916c11c4a2b8698c7872c8d Mon Sep 17 00:00:00 2001 From: harry0000 Date: Mon, 15 Apr 2024 03:00:20 +0900 Subject: [PATCH 3/3] Upgrade to Scala 3.4.1 --- .github/workflows/ci.yaml | 4 ++-- build.sbt | 2 +- src/main/scala/io/github/acl4s/ModInt.scala | 5 ++--- src/main/scala/io/github/acl4s/TwoSAT.scala | 14 ++++++++------ 4 files changed, 13 insertions(+), 12 deletions(-) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index f0989de..4787848 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -8,11 +8,11 @@ jobs: fail-fast: false matrix: name: [ "test" ] - scala: [ 3.3.0, 3.3.1 ] + scala: [ 3.3.0, 3.4.1 ] java: [ 20, 21 ] include: - name: "format" - scala: 3.3.1 + scala: 3.4.1 java: 21 exclude: - name: "test" diff --git a/build.sbt b/build.sbt index f62b824..fd8e989 100644 --- a/build.sbt +++ b/build.sbt @@ -1,4 +1,4 @@ -lazy val supportedScalaVersions = List("3.3.1", "3.3.0") +lazy val supportedScalaVersions = List("3.4.1", "3.3.0") lazy val root = project .in(file(".")) diff --git a/src/main/scala/io/github/acl4s/ModInt.scala b/src/main/scala/io/github/acl4s/ModInt.scala index 2a1f557..dceb71f 100644 --- a/src/main/scala/io/github/acl4s/ModInt.scala +++ b/src/main/scala/io/github/acl4s/ModInt.scala @@ -90,8 +90,7 @@ object Modulus { inline def apply[T <: Int](): Modulus[T] = Mod(compiletime.constValue[T]) } -final case class StaticModInt[T <: Int] private (private[this] var _value: Int)(using m: Modulus[T]) - extends ModIntBase[T] { +final case class StaticModInt[T <: Int] private (private var _value: Int)(using m: Modulus[T]) extends ModIntBase[T] { override type Self = StaticModInt[T] override val mod: T = m.value @@ -204,7 +203,7 @@ object ModInt998244353 { def apply(value: Long): ModInt998244353 = StaticModInt(value) } -final case class DynamicModInt private (private[this] var _value: Int) extends ModIntBase[Int] { +final case class DynamicModInt private (private var _value: Int) extends ModIntBase[Int] { override type Self = DynamicModInt override val mod: Int = DynamicModInt.bt.m diff --git a/src/main/scala/io/github/acl4s/TwoSAT.scala b/src/main/scala/io/github/acl4s/TwoSAT.scala index 77c2dc6..fde6d63 100644 --- a/src/main/scala/io/github/acl4s/TwoSAT.scala +++ b/src/main/scala/io/github/acl4s/TwoSAT.scala @@ -1,5 +1,7 @@ package io.github.acl4s +import scala.util.boundary, boundary.break + /** * Reference: * B. Aspvall, M. Plass, and R. Tarjan, @@ -28,12 +30,12 @@ class TwoSAT(private val n: Int) { def satisfiable(): Boolean = { val (_, id) = scc.sccIds() - (0 until n).foreach(i => { - if (id(2 * i) == id(2 * i + 1)) { - return false + boundary { + for (i <- 0 until n) { + if (id(2 * i) == id(2 * i + 1)) { break(false) } + answer(i) = id(2 * i) < id(2 * i + 1) } - answer(i) = id(2 * i) < id(2 * i + 1) - }) - true + true + } } }