Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import cats.*
- import cats.syntax.all.*
- import cats.effect.*
- import cats.effect.std.*
- import scala.collection.mutable
- object Philosophers extends IOApp.Simple:
- val run: IO[Unit] = dining(5)
- case class Philosopher(self: Int, leftStick: Int, rightStick: Int)
- given Show[Vector[Philosopher]] = _.map(_.self).mkString("(", ",", ")")
- def dining(n: Int): IO[Unit] =
- def schedule(queue: Vector[Philosopher]): (Vector[Philosopher], Vector[Philosopher]) =
- val eating = Vector.newBuilder[Philosopher]
- val blocked = Vector.newBuilder[Philosopher]
- val claimed = mutable.Set.empty[Int]
- queue.foreach { p =>
- val isBlocked = claimed.contains(p.leftStick) || claimed.contains(p.rightStick)
- if isBlocked then
- blocked.addOne(p)
- else
- eating.addOne(p)
- claimed.addOne(p.leftStick)
- claimed.addOne(p.rightStick)
- end if
- }
- val active = eating.result()
- val updated = blocked.addAll(active).result()
- (active, updated)
- end schedule
- def loop(philosophers: Vector[Philosopher]): IO[Unit] =
- val (active, queue) = schedule(philosophers)
- IO.println(active) >> loop(queue)
- val philosophers = Vector.tabulate(n) { self =>
- val left =
- val candidate = self - 1
- if candidate < 0
- then n - 1
- else candidate
- end left
- Philosopher(self, left, self)
- }
- loop(philosophers)
- end dining
- end Philosophers
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement