Skip to content

Instantly share code, notes, and snippets.

@horace-velmont
Created July 24, 2020 12:42
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save horace-velmont/5a22c2891dd42f434b8095beb10ceac1 to your computer and use it in GitHub Desktop.
Save horace-velmont/5a22c2891dd42f434b8095beb10ceac1 to your computer and use it in GitHub Desktop.
package execise3
case class World(grids: Map[String, Grid], appliances: Map[String, Appliance]) {
def newAppliance(id: String, powerAbsorbed: Int): World = this.copy(
appliances = this.appliances.updated(id, Appliance(powerAbsorbed, None, isOn = false))
)
def newGrid(id: String, maxPower: Int): World = this.copy(grids = this.grids.updated(id, Grid(maxPower, maxPower)))
def plugInto(applianceId: String, gridId: String): Either[String, World] = {
val appliance = this.appliances(applianceId)
(appliance.gridId match {
case Some(gId) if appliance.isOn => for {
w1 <- this.addPower(gId, appliance.powerAbsorbed)
w2 <- w1.addPower(gridId, -appliance.powerAbsorbed)
} yield w2
case Some(_) => Right(this)
case None if appliance.isOn => this.addPower(gridId, -appliance.powerAbsorbed)
case None => Right(this)
}).map(w1 =>
w1.copy(appliances = w1.appliances.updated(applianceId, appliance.copy(gridId = Some(gridId))))
)
}
def on(applianceId: String): Either[String, World] = {
val appliance = this.appliances(applianceId)
appliance.gridId match {
case None =>
Left("Cannot turn on when unconnected to any grid")
case Some(gid) if !appliance.isOn =>
addPower(gid, -appliance.powerAbsorbed).map { w1 =>
w1.copy(appliances = w1.appliances.updated(applianceId, appliance.copy(isOn = true)))
}
case Some(_) => Right(this)
}
}
def off(applianceId: String): Either[String, World] = {
val appliance = this.appliances(applianceId)
appliance.gridId match {
case Some(gid) if appliance.isOn =>
addPower(gid, appliance.powerAbsorbed).map { w1 =>
w1.copy(appliances = w1.appliances.updated(applianceId, appliance.copy(isOn = false)))
}
case _ => Right(this)
}
}
def addPower(gridId: String, power: Int): Either[String, World] = {
val grid = this.grids(gridId)
val newPower = grid.residualPower + power
if (newPower < 0) Left("Not Enough Power")
else if (newPower > grid.maxPower) Left("Maximum power exceeded")
else Right(this.copy(grids.updated(gridId, grid.copy(residualPower = newPower))))
}
}
case class Appliance(powerAbsorbed: Int, gridId: Option[String], isOn: Boolean)
case class Grid(maxPower: Int, residualPower: Int)
object Main extends App {
val world = World(Map.empty, Map.empty)
val world1 = world.newAppliance("tv", 150)
.newAppliance("radio", 30)
.newGrid("grid", 3000)
for {
w1 <- world1.plugInto("tv", "grid")
w2 <- w1.plugInto("radio", "grid")
_ <- Right(println(w2.grids("grid").residualPower))
w3 <- w2.on("tv")
_ <- Right(println(w3.grids("grid").residualPower))
w4 <- w3.on("radio")
_ <- Right(println(w4.grids("grid").residualPower))
} yield ()
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment