我是Scala的新手,我想问一下实现这个问题的最有效方法是什么。
想象一下,我们有一个体育场,它有X个扇区,每个扇区有Y行,每排有Z个座位。
想象一下,我们有随机数量的占用席位。
a)给定一排,返回占用席位数。
b)给定一个部门,返回占用席位数量。
c)给定一个扇区和一行,确保椅子是空的x(1 <= x <= n)。d)给定一行,返回一个带有空椅位置的数组。
e)给定一个扇区,返回最多空置椅子的行。
f)返回占用体育场椅子的数量。
g)假设体育场入口有两个值:两个最接近场的行为75.00美元,其他行为50.00美元。写一个返回游戏收入的函数。
提前感谢您的解决方案
答案 0 :(得分:0)
最有效率可能意味着您编写代码的努力或运行时速度方面。在前一种情况下,我会使用嵌套Vector
之类的东西。在后一种情况下,平坦Array
可能表现最佳。
val rows = 4
val cols = 3
val arr = new Array[Boolean](rows * cols)
def get(row: Int, col: Int) = arr(row * cols + col)
def set(row: Int, col: Int, value: Boolean) = arr(row * cols + col) = value
def occupiedInRow(row: Int) = (0 until cols).count(get(row, _))
set(row = 1, col = 0, value = true)
set(row = 1, col = 2, value = true)
assert(occupiedInRow(1) == 2)
因此有三个或更多维度。
除非这是为了练习,否则我会使用现有的优化库,例如Breeze or Saddle。
答案 1 :(得分:0)
我认为映射Boolean
的最有效方式是BitSet
,它有两种形式:mutable和immutable。不可变的效率稍高,但它的效率在任何并发\分布情况下都消失了。
这是你的作业的实现:
object Stadium {
def random(sectors: Int, rows: Int, seats: Int): Stadium = {
val size = sectors * rows * seats
new Stadium(sectors, rows, seats,
BitSet fromBitMask Array.fill(size / 64 + 1)(Random.nextLong()) take size)
}
def apply(occupied: (Int, Int, Int)*): Stadium = {
val sectors = occupied.map(_._1).max + 1
val rows = occupied.map(_._2).max + 1
val seats = occupied.map(_._3).max + 1
val occNums = occupied map {
case (sector, row, seat) => (sector * rows + row) * seats + seat
}
Stadium(sectors, rows, seats, BitSet(occNums: _*))
}
def income[N: Numeric](stadium: Stadium, standardPrice: N, premiumPrice: PartialFunction[Int, N] = PartialFunction.empty) = (
for {
sector <- 0 until stadium.sectors
row <- 0 until stadium.rows
price = premiumPrice.applyOrElse[Int, N](row, _ => standardPrice)
occupied = implicitly[Numeric[N]].fromInt(stadium.occupiedInRow(sector, row))
} yield price * occupied
).sum
}
case class Stadium(sectors: Int, rows: Int, seats: Int, occupied: BitSet) {
@inline final def sectorSeats = rows * seats
def rowRange(sector: Int, row: Int) = {
val from = (sector * rows + row) * seats
occupied.range(from, from + seats) map (_ - from)
}
def sectorRange(sector: Int) = {
val from = sector * sectorSeats
occupied.range(from, from + sectorSeats) map (_ - from)
}
lazy val wholeRow = BitSet(0 until seats: _*)
def occupiedInRow(sector: Int, row: Int) = rowRange(sector, row).size
def occupiedInSector(sector: Int) = sectorRange(sector).size
def isOccupied(sector: Int, row: Int, seat: Int) = occupied(sector * sectorSeats + row * seats + seat)
def isVacant(sector: Int, row: Int, seat: Int) = !isOccupied(sector, row, seat)
def vacantInRow(sector: Int, row: Int) = wholeRow &~ rowRange(sector, row)
def mostVacant(sector: Int) = 0 until rows maxBy (vacantInRow(sector, _).size)
def occupiedSize = occupied.size
}
因此。如果你想定义你的体育场,如:
val st = Stadium((0,0,0),(0,0,1),(0,1,0),(0,2,2), (0,2,1))
标准价格50美元的收入将很容易计算
Stadium.income(st, 50.0) // res0: Double = 250.0
可以增加前两行
Stadium.income(st, 50.0, Seq.fill(2)(75.0))// res1: Double = 325.0