diff --git a/exercises/solutions-5/.gitignore b/exercises/solutions-5/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..cc92d252fed98e77240201d6120a9b74cb66665a
--- /dev/null
+++ b/exercises/solutions-5/.gitignore
@@ -0,0 +1,8 @@
+.vscode
+.metals
+.bloop
+.bsp
+target
+metals.sbt
+build.properties
+project/project
diff --git a/exercises/solutions-5/.scalafmt.conf b/exercises/solutions-5/.scalafmt.conf
new file mode 100644
index 0000000000000000000000000000000000000000..1cea5243def8047a81295a8b13cb970660e0b3fc
--- /dev/null
+++ b/exercises/solutions-5/.scalafmt.conf
@@ -0,0 +1,4 @@
+version = "3.4.0"
+runner.dialect = scala3
+rewrite.scala3.convertToNewSyntax = true
+rewrite.scala3.removeOptionalBraces = true
diff --git a/exercises/solutions-5/Readme.md b/exercises/solutions-5/Readme.md
new file mode 100644
index 0000000000000000000000000000000000000000..a1885584f2c5daf2e923d7c4be20932038d31848
--- /dev/null
+++ b/exercises/solutions-5/Readme.md
@@ -0,0 +1,35 @@
+# Exercise Session 5, Solutions
+
+## Problem 1: Message Processing Semantics
+
+### Problem 1.1
+
+For the `Client1` actor, the only possible output is `0`. The reason is that messages between two actors are guaranteed to be received in the order they were sent.
+
+You can try the code yourself by running:
+```
+sbt "runMain problem1_1"
+```
+
+### Problem 1.2
+
+1. For the `Client2` actor, either `0` or `1` can be printed. There are no restrictions on the order in which messages are processed in this case. It might be the case that the `Memory` actor receives the `Write` message from the `Client2` first, or the `Read` message from the `Proxy` first.
+
+2. The order in which the messages are sent by the `Client2` doesn't change the possible behaviours of the system.
+
+3. In the case both messages are sent through the `Proxy`, then the only possible output is `0`, since in this case the messages between the `Client2` and `Proxy`, as well as between `Proxy` and `Memory`, are guaranteed to be handled in the same order they were sent.
+
+You can try the code yourself by running:
+```
+sbt "runMain problem1_2"
+```
+
+## Problem 2
+
+The solution is in `Problem2.scala`.
+
+You can run it using:
+
+```
+sbt "runMain problem2 10"
+```
diff --git a/exercises/solutions-5/build.sbt b/exercises/solutions-5/build.sbt
new file mode 100644
index 0000000000000000000000000000000000000000..0aed4e0a5e70090991d53bc8cc333cba5385ac8e
--- /dev/null
+++ b/exercises/solutions-5/build.sbt
@@ -0,0 +1,25 @@
+val scala3Version = "3.1.2"
+val akkaVersion = "2.6.19"
+
+lazy val root = project
+  .in(file("."))
+  .settings(
+    name := "code",
+    version := "0.1.0-SNAPSHOT",
+    scalaVersion := scala3Version,
+    fork := true,
+    javaOptions ++= Seq(
+      "-Dakka.loglevel=Info",
+      "-Dakka.actor.allow-java-serialization=on"
+    ),
+    libraryDependencies ++= Seq(
+      "org.scalameta" %% "munit" % "1.0.0-M3" % Test,
+      "com.typesafe.akka" %% "akka-actor" % akkaVersion,
+      "com.typesafe.akka" %% "akka-testkit" % akkaVersion,
+      "com.typesafe.akka" %% "akka-persistence" % akkaVersion,
+      // SLF4J backend
+      // See https://doc.akka.io/docs/akka/current/typed/logging.html#slf4j-backend
+      "ch.qos.logback" % "logback-classic" % "1.2.11"
+    ),
+    Test / testOptions += Tests.Argument(TestFrameworks.JUnit)
+  )
diff --git a/exercises/solutions-5/project/plugins.sbt b/exercises/solutions-5/project/plugins.sbt
new file mode 100644
index 0000000000000000000000000000000000000000..83adafa3f1dc8a82b2f18ba573029a8f1ca4cc72
--- /dev/null
+++ b/exercises/solutions-5/project/plugins.sbt
@@ -0,0 +1 @@
+addSbtPlugin("org.scalameta" % "sbt-scalafmt" % "2.4.6")
diff --git a/exercises/solutions-5/src/main/scala/Problem1.scala b/exercises/solutions-5/src/main/scala/Problem1.scala
new file mode 100644
index 0000000000000000000000000000000000000000..2b055846cbba0a02e3e58ae92f8621eed4b110f2
--- /dev/null
+++ b/exercises/solutions-5/src/main/scala/Problem1.scala
@@ -0,0 +1,56 @@
+import scala.util.{Try, Success, Failure}
+import scala.concurrent.ExecutionContext
+import java.util.concurrent.Future
+import java.util.concurrent.atomic.AtomicReference
+import akka.actor.*
+import akka.testkit.*
+import akka.event.LoggingReceive
+
+enum Protocol:
+  case Write(value: Int)
+  case Read(requester: ActorRef)
+import Protocol.*
+
+enum Responses:
+  case Answer(value: Int)
+import Responses.*
+
+
+class Memory extends Actor:
+  var value = 0
+
+  override def receive: Receive = {
+    case Write(newValue) => value = newValue
+    case Read(requester) => requester ! Answer(value)
+  }
+
+class Client(memory: ActorRef) extends Actor:
+  override def receive: Receive = { case Answer(value) =>
+    println(value)
+  }
+
+class MyProxy(memory: ActorRef) extends Actor:
+  override def receive: Receive = { case message =>
+    memory ! message
+  }
+
+@main def problem1_1 =
+  for _ <- 1 to 1000 do
+    val system = ActorSystem("example")
+    try
+      val memory = system.actorOf(Props(Memory()))
+      val client = system.actorOf(Props(Client(memory)))
+      memory ! Read(client)
+      memory ! Write(1)
+    finally system.terminate()
+
+@main def problem1_2 =
+  for _ <- 1 to 1000 do
+    val system = ActorSystem("example")
+    try
+      val memory = system.actorOf(Props(Memory()))
+      val proxy  = system.actorOf(Props(MyProxy(memory)))
+      val client = system.actorOf(Props(Client(memory)))
+      proxy ! Read(client)
+      memory ! Write(1)
+    finally system.terminate()
diff --git a/exercises/solutions-5/src/main/scala/Problem2.scala b/exercises/solutions-5/src/main/scala/Problem2.scala
new file mode 100644
index 0000000000000000000000000000000000000000..d198ffef1c4c89b6e909319145cd2f7f0c10a852
--- /dev/null
+++ b/exercises/solutions-5/src/main/scala/Problem2.scala
@@ -0,0 +1,86 @@
+import akka.actor.*
+import akka.testkit.TestKit
+
+object Soldier:
+  // The different messages that can be sent between the actors:
+  enum Protocol:
+
+    // The recipient should die.
+    case Death
+
+    // The recipient should update its next reference.
+    case Next(next: ActorRef)
+
+    // The recipient should act.
+    case Act
+
+class Soldier(number: Int) extends Actor:
+  import Soldier.*
+  import Protocol.*
+
+  def receive: Receive = behavior(None, None, false)
+
+  def behavior(
+      next: Option[ActorRef],
+      killer: Option[ActorRef],
+      mustAct: Boolean
+  ): Receive = {
+
+    case Death =>
+      next match
+        case Some(myNext) =>
+          sender() ! Next(myNext)
+          myNext ! Act
+          println("Soldier " + number + " dies.")
+          self ! PoisonPill
+
+        case None =>
+          context.become(
+            behavior(next = None, killer = Some(sender()), mustAct = mustAct)
+          )
+
+    case Next(newNext) =>
+      if newNext == self then println("Soldier " + number + " is last !")
+      else if !killer.isEmpty then
+        killer.get ! Next(newNext)
+        newNext ! Act
+        println("Soldier " + number + " dies.")
+        self ! PoisonPill
+      else if mustAct then
+        newNext ! Death
+        context.become(behavior(next = None, killer = None, mustAct = false))
+      else
+        context.become(
+          behavior(next = Some(newNext), killer = None, mustAct = false)
+        )
+
+    case Act =>
+      next match
+        case Some(myNext) =>
+          myNext ! Death
+          context.become(
+            behavior(next = None, killer = killer, mustAct = false)
+          )
+
+        case None =>
+          context.become(behavior(next = None, killer = killer, mustAct = true))
+  }
+
+@main def problem2(n: Int) = new TestKit(ActorSystem()):
+  import Soldier.*
+  import Soldier.Protocol.*
+
+  // Initialization
+  require(n >= 1)
+
+  // Creation of the actors.
+  val actors = Seq.tabulate(n)(
+    (i: Int) => system.actorOf(Props(classOf[Soldier], i), "Soldier" + i)
+  )
+
+  // Inform all actors of the next actor in the circle.
+  for i <- 0 to (n - 2) do actors(i) ! Next(actors(i + 1))
+  actors(n - 1) ! Next(actors(0))
+
+  // Inform the first actor to start acting.
+  actors(0) ! Act