diff --git a/exercise/scala/day01/.gitignore b/exercise/scala/day01/.gitignore new file mode 100644 index 000000000..9e79245ee --- /dev/null +++ b/exercise/scala/day01/.gitignore @@ -0,0 +1,32 @@ +# macOS +.DS_Store + +# sbt specific +dist/* +target/ +lib_managed/ +src_managed/ +project/boot/ +project/plugins/project/ +project/local-plugins.sbt +.history +.ensime +.ensime_cache/ +.sbt-scripted/ +local.sbt + +# Bloop +.bsp + +# VS Code +.vscode/ + +# Metals +.bloop/ +.metals/ +metals.sbt + +# IDEA +.idea +.idea_modules +/.worksheet/ diff --git a/exercise/scala/day01/.scalafmt.conf b/exercise/scala/day01/.scalafmt.conf new file mode 100644 index 000000000..e661d6c10 --- /dev/null +++ b/exercise/scala/day01/.scalafmt.conf @@ -0,0 +1 @@ +maxColumn = 120 \ No newline at end of file diff --git a/exercise/scala/day01/build.sbt b/exercise/scala/day01/build.sbt new file mode 100644 index 000000000..2f7135a25 --- /dev/null +++ b/exercise/scala/day01/build.sbt @@ -0,0 +1,12 @@ +val scala3Version = "3.4.2" + +lazy val root = project + .in(file(".")) + .settings( + name := "day01", + version := "0.1.0-SNAPSHOT", + + scalaVersion := scala3Version, + + libraryDependencies += "org.scalameta" %% "munit" % "1.0.0" % Test + ) diff --git a/exercise/scala/day01/project/build.properties b/exercise/scala/day01/project/build.properties new file mode 100644 index 000000000..081fdbbc7 --- /dev/null +++ b/exercise/scala/day01/project/build.properties @@ -0,0 +1 @@ +sbt.version=1.10.0 diff --git a/exercise/scala/day01/src/main/scala/Food.scala b/exercise/scala/day01/src/main/scala/Food.scala new file mode 100644 index 000000000..e4fd43186 --- /dev/null +++ b/exercise/scala/day01/src/main/scala/Food.scala @@ -0,0 +1,13 @@ +import java.time.LocalDate +import java.util.UUID + +case class Food( + expirationDate: LocalDate, + approvedForConsumption: Boolean, + insperctorId: Option[UUID] +) { + def isEdible(now: LocalDate): Boolean = + expirationDate.isAfter(now) && + approvedForConsumption && + this.insperctorId.nonEmpty +} diff --git a/exercise/scala/day01/src/test/scala/FoodSpec.scala b/exercise/scala/day01/src/test/scala/FoodSpec.scala new file mode 100644 index 000000000..95388e3e8 --- /dev/null +++ b/exercise/scala/day01/src/test/scala/FoodSpec.scala @@ -0,0 +1,33 @@ +import java.time.LocalDate +import java.util.UUID.randomUUID +import java.time.LocalDate.of +import java.util.UUID + + +class FoodSpec extends munit.FunSuite { + + private val expirationDate = of(2023, 12, 1) + private val inspector = randomUUID() + private val notFreshDate = expirationDate.plusDays(7) + private val freshDate = expirationDate.minusDays(7) + + test("not edible food") { + val res = notEdibleFood + .forall { + case (bool, maybeUuid, now) => !Food(expirationDate, bool, maybeUuid).isEdible(now) + } + assert(res) + } + + test("edible food") { + assert(Food(expirationDate, true, Some(inspector)).isEdible(freshDate)) + } + + def notEdibleFood: List[(Boolean, Option[UUID], LocalDate)] = List( + (true, Some(inspector), notFreshDate), + (false, Some(inspector), freshDate), + (true, None, freshDate), + (false, None, notFreshDate), + (false, None, freshDate) + ) +} diff --git a/solution/scala/day01/.gitignore b/solution/scala/day01/.gitignore new file mode 100644 index 000000000..9e79245ee --- /dev/null +++ b/solution/scala/day01/.gitignore @@ -0,0 +1,32 @@ +# macOS +.DS_Store + +# sbt specific +dist/* +target/ +lib_managed/ +src_managed/ +project/boot/ +project/plugins/project/ +project/local-plugins.sbt +.history +.ensime +.ensime_cache/ +.sbt-scripted/ +local.sbt + +# Bloop +.bsp + +# VS Code +.vscode/ + +# Metals +.bloop/ +.metals/ +metals.sbt + +# IDEA +.idea +.idea_modules +/.worksheet/ diff --git a/solution/scala/day01/.scalafmt.conf b/solution/scala/day01/.scalafmt.conf new file mode 100644 index 000000000..e661d6c10 --- /dev/null +++ b/solution/scala/day01/.scalafmt.conf @@ -0,0 +1 @@ +maxColumn = 120 \ No newline at end of file diff --git a/solution/scala/day01/build.sbt b/solution/scala/day01/build.sbt new file mode 100644 index 000000000..2f7135a25 --- /dev/null +++ b/solution/scala/day01/build.sbt @@ -0,0 +1,12 @@ +val scala3Version = "3.4.2" + +lazy val root = project + .in(file(".")) + .settings( + name := "day01", + version := "0.1.0-SNAPSHOT", + + scalaVersion := scala3Version, + + libraryDependencies += "org.scalameta" %% "munit" % "1.0.0" % Test + ) diff --git a/solution/scala/day01/project/build.properties b/solution/scala/day01/project/build.properties new file mode 100644 index 000000000..081fdbbc7 --- /dev/null +++ b/solution/scala/day01/project/build.properties @@ -0,0 +1 @@ +sbt.version=1.10.0 diff --git a/solution/scala/day01/src/main/scala/Food.scala b/solution/scala/day01/src/main/scala/Food.scala new file mode 100644 index 000000000..2b0dcb6e2 --- /dev/null +++ b/solution/scala/day01/src/main/scala/Food.scala @@ -0,0 +1,26 @@ +import java.time.LocalDate +import java.util.UUID + +case class Food( + expirationDate: LocalDate, + approvedForConsumption: Boolean, + insperctorId: Option[UUID] +) { + def isEdible(now: LocalDate): Boolean = + isFresh(now) && + hasBeenInspected && + canBeConsumed + + private def isFresh(now: LocalDate): Boolean = { + expirationDate.isAfter(now) + } + + private def hasBeenInspected: Boolean = { + insperctorId.nonEmpty + } + + private def canBeConsumed: Boolean = { + approvedForConsumption + } + +} diff --git a/solution/scala/day01/src/test/scala/FoodSpec.scala b/solution/scala/day01/src/test/scala/FoodSpec.scala new file mode 100644 index 000000000..535d3a0bb --- /dev/null +++ b/solution/scala/day01/src/test/scala/FoodSpec.scala @@ -0,0 +1,33 @@ +import java.time.LocalDate +import java.time.LocalDate.of +import java.util.UUID +import java.util.UUID.randomUUID + + +class FoodSpec extends munit.FunSuite { + + private val expirationDate = of(2023, 12, 1) + private val inspector = randomUUID() + private val notFreshDate = expirationDate.plusDays(7) + private val freshDate = expirationDate.minusDays(7) + + test("not edible food") { + val res = notEdibleFood + .forall { + case (bool, maybeUuid, now) => !Food(expirationDate, bool, maybeUuid).isEdible(now) + } + assert(res) + } + + test("edible food") { + assert(Food(expirationDate, true, Some(inspector)).isEdible(freshDate)) + } + + def notEdibleFood: List[(Boolean, Option[UUID], LocalDate)] = List( + (true, Some(inspector), notFreshDate), + (false, Some(inspector), freshDate), + (true, None, freshDate), + (false, None, notFreshDate), + (false, None, freshDate) + ) +}