@@ -10,7 +10,10 @@ import scala.collection.immutable.Queue
10
10
type Floor = Int
11
11
enum Direction { case Up , Down }
12
12
13
- case class Person (position : Floor , destination : Floor ) {
13
+ case class Person (
14
+ position : Floor ,
15
+ destination : Floor
16
+ ) {
14
17
require(position != destination, " source and destination floor cannot be the same" )
15
18
16
19
val desiredDirection : Direction = (position, destination) match
@@ -74,7 +77,9 @@ case class Lift(
74
77
case None => copy(building.highestFloorGoingDown(this ).getOrElse(0 ), Down )
75
78
}
76
79
77
- case class Building (floors : Array [Queue [Person ]]) {
80
+ case class Building (
81
+ floors : Array [Queue [Person ]]
82
+ ) {
78
83
def isEmpty : Boolean = floors.forall(_.isEmpty)
79
84
def hasPeople : Boolean = ! isEmpty
80
85
@@ -93,19 +98,28 @@ case class Building(floors: Array[Queue[Person]]) {
93
98
case Down => peopleGoing(Down ).filter(_.isBelow(lift)).map(_.position).maxOption
94
99
}
95
100
96
- case class LiftSystem (building : Building , lift : Lift , stops : List [Floor ]) {
97
- def fixDirection : LiftSystem = copy(lift = lift.fixDirection(building))
98
- def dropOff : LiftSystem = copy(lift = lift.dropOff)
99
- def align : LiftSystem = copy(lift = lift.align(building))
101
+ case class LiftSystem (
102
+ building : Building ,
103
+ lift : Lift ,
104
+ stops : List [Floor ]
105
+ ) {
106
+ private def fixDirection : LiftSystem = copy(lift = lift.fixDirection(building))
107
+ private def dropOff : LiftSystem = copy(lift = lift.dropOff)
108
+ private def align : LiftSystem = copy(lift = lift.align(building))
100
109
101
- def pickup : LiftSystem =
110
+ private def pickup : LiftSystem =
102
111
val (lift2, building2) = lift.pickup(building)
103
112
copy(lift = lift2, building = building2)
104
113
105
- def registerStop : LiftSystem =
114
+ private def registerStop : LiftSystem =
106
115
stops.lastOption match
107
116
case Some (lastStop) if lastStop == lift.position => this
108
117
case _ => copy(stops = stops :+ lift.position)
118
+
119
+ @ tailrec final def resolve : LiftSystem =
120
+ if building.isEmpty && lift.isEmpty && lift.position == 0
121
+ then registerStop
122
+ else registerStop.fixDirection.dropOff.pickup.align.resolve
109
123
}
110
124
111
125
// Excuse the name. Dinglemouse.theLift() is how the function is called in the Codewars test suite
@@ -116,16 +130,10 @@ object Dinglemouse {
116
130
queue.map(destination => Person (position = index, destination = destination)).to(Queue )
117
131
}
118
132
119
- val lift = Lift (position = 0 , Direction .Up , people = Queue .empty, capacity)
120
- val building = Building (floors)
121
-
122
- @ tailrec def resolve (state : LiftSystem ): LiftSystem =
123
- if state.building.isEmpty && state.lift.isEmpty && state.lift.position == 0
124
- then state
125
- else resolve(state.registerStop.fixDirection.dropOff.pickup.align)
126
-
133
+ val lift = Lift (position = 0 , Direction .Up , people = Queue .empty, capacity)
134
+ val building = Building (floors)
127
135
val initialState = LiftSystem (building, lift, stops = List .empty)
128
- val finalState = resolve( initialState).registerStop
136
+ val finalState = initialState.resolve
129
137
130
138
finalState.stops.toArray
131
139
}
0 commit comments