Skip to content

Commit

Permalink
#735 Optimize generation of station steps supporting gear-splitted nu…
Browse files Browse the repository at this point in the history
…mbering
  • Loading branch information
luechtdiode committed Nov 13, 2023
1 parent 3cb04bb commit dc99203
Showing 1 changed file with 79 additions and 40 deletions.
119 changes: 79 additions & 40 deletions src/main/scala/ch/seidel/kutu/renderer/RiegenblattToHtmlRenderer.scala
Original file line number Diff line number Diff line change
Expand Up @@ -13,37 +13,68 @@ object RiegenBuilder {
RiegenRotationsregel(kandidaten.head.wertungen.head.wettkampf)
else RiegenRotationsregel("")

def pickStartformationen(geraete: Seq[(Option[Disziplin], Seq[Riege])], durchgang: Option[String], extractKandidatEinteilung: Kandidat => (Option[Riege], Seq[Disziplin])) = {
geraete.flatMap{s =>
val (startdisziplin, _) = s
val splitpoint = geraete.indexWhere(g => g._1.equals(startdisziplin))
val shifted = geraete.drop(splitpoint) ++ geraete.take(splitpoint)
shifted.zipWithIndex.map{ss =>
val ((disziplin, _), offset) = ss
val tuti = kandidaten.filter{k =>
val (einteilung, diszipline) = extractKandidatEinteilung(k)
einteilung match {
case Some(einteilung) =>
einteilung.durchgang.equals(durchgang) &&
einteilung.start.equals(startdisziplin) &&
diszipline.map(_.id).contains(disziplin.map(_.id).getOrElse(0))
case None => false
}
}.sortBy(sorter.sort)

val completed = tuti.
flatMap(k => k.wertungen).
filter(wertung => disziplin.forall(_.equals(wertung.wettkampfdisziplin.disziplin))).
forall(_.endnote.nonEmpty)

if(tuti.nonEmpty) {
val mo = (tuti.size * geraete.size + offset) % tuti.size
(offset, disziplin, tuti.drop(mo) ++ tuti.take(mo), completed)
}
else {
(offset, disziplin, tuti, completed)
def pickStartformationen(geraete: Seq[(Option[Disziplin], Seq[Riege], Int)], durchgang: Option[String], extractKandidatEinteilung: Kandidat => (Option[Riege], Seq[Disziplin])): Seq[(Int, Option[Disziplin], Seq[Kandidat], Boolean)] = {
println(geraete.mkString("Geräte\n", "\n", "\n"))
/*
sationmap[Disziplin,Int](
// Disziplin -> Halt
Boden -> 1,
Barren -> 2,
Balken -> 2,
Minitramp -> 3,
Sprung -> 4
)
*/
val stationmap: Map[Disziplin, Int] = geraete.foldLeft(Map[Disziplin, Int]()) { (acc, item) =>
acc.updated(item._1.get, item._3)
}
/*
1. Halt: Riege Startgerät (1W,Boden), (2M,Barren), (3W,Balken), (4W,Minitramp) (5M,Minitramp), (6M,Sprung)
2. Halt: Riege Startgerät (1W,Balken), (2M,Minitramp), (3W,Sprung),
(4W,Boden) (5M,Boden), (6M,Barren)
3. Halt: Riege Startgerät (1W,Minitramp), (2M,Sprung),
(3W,Boden), (4W,Balken) (5M,Barren), (6M,Minitramp)
4. Halt: Riege Startgerät (1W,Sprung)
, (2M,Boden), (3W,Balken), (4W,Minitramp) (5M,Minitramp), (6M,Sprung)
*/
val athletdevicemap: Seq[(Kandidat, List[Disziplin])] = geraete.flatMap(d => kandidaten
.map { kandidat =>
(kandidat, extractKandidatEinteilung(kandidat))
}
.filter { riegeneinteilung =>
val (_, (einteilung, diszipline)) = riegeneinteilung
val disziplin = d._1.get
einteilung match {
case Some(einteilung) =>
einteilung.durchgang.equals(durchgang) &&
einteilung.start.contains(disziplin) &&
diszipline.map(_.id).contains(disziplin.id)
case None => false
}
}
.map { riegeneinteilung =>
val (kandidat, (_, diszipline)) = riegeneinteilung
val disziplin = d._1.get
(kandidat, (diszipline.dropWhile(d => d.id != disziplin.id) ++ diszipline.takeWhile(d => d.id != disziplin.id)).toList)
}
)

stationmap.values.toList.distinct.sorted.flatMap { station =>
athletdevicemap.map{ kandidat =>
(kandidat._2(station), kandidat)
}.groupBy(_._1)
.map{gr =>
val (disziplin: Disziplin, candidates: Seq[(Disziplin, (Kandidat, List[Disziplin]))]) = gr
val completed = candidates.flatMap(k => k._2._1.wertungen)
.filter(wertung => disziplin.equals(wertung.wettkampfdisziplin.disziplin))
.forall(_.endnote.nonEmpty)
val sortedCandidates = candidates.map(x => x._2._1).sortBy(sorter.sort)
val scWithOffset = sortedCandidates.drop(station) ++ sortedCandidates.take(station)
(station, Some(gr._1), scWithOffset, completed)
}
}.filter(p => p._3.nonEmpty)
}

Expand All @@ -54,9 +85,11 @@ object RiegenBuilder {
.sortBy(d => d._1).zipWithIndex
.map{d =>
val ((durchgang, kandidatriegen), durchgangIndex) = d
val dzl1 = kandidatriegen.flatMap(_._1.diszipline)
val riegen = kandidatriegen.map(_._2).sortBy(r => r.start.map( dzl1.indexOf(_)))
val dzl = dzl1.distinct.sortBy{dzl1.indexOf(_)}
val dzlmap: Map[Disziplin,Int] = kandidatriegen.flatMap(_._1.diszipline.zipWithIndex).foldLeft(Map[Disziplin,Int]()){(acc, item) =>
acc.updated(item._1, item._2)
}
val dzl = dzlmap.keys.toList.sortBy{dzlmap(_)}
val riegen = kandidatriegen.map(_._2).sortBy(r => r.start.map( dzl.indexOf(_)))
//kandidat.diszipline für die Rotationsberechnung verwenden
val rg = riegen.groupBy(e => e.start).toList.sortBy{d => d._1.map( dzl.indexOf(_))}
val geraete = dzl.foldLeft(rg){(acc, item) =>
Expand All @@ -65,15 +98,16 @@ object RiegenBuilder {
case _ => acc :+ (Some(item) -> List[Riege]())
}
}.sortBy(geraet => geraet._1.map(g => dzl.indexOf(g)))
.map(geraet => (geraet._1, geraet._2, dzlmap(geraet._1.get)))

val startformationen = pickStartformationen(geraete, durchgang, k => (k.einteilung, k.diszipline))
.zipWithIndex
.map(x => {
val (sf, index) = x
(sf._1, sf._2, sf._3, sf._4, durchgangIndex*100 + index + 1)
(sf._1, sf._2, sf._3, sf._4, durchgangIndex * 100 + index + 1)
})

if (printorder) {
(durchgang, startformationen.sortBy(d => d._2.map( dzl.indexOf(_)).getOrElse(0) * 100 + d._1))
(durchgang, startformationen.sortBy(d => d._2.map( dzl.indexOf(_)).getOrElse(0) * 100 + d._1))
}
else {
(durchgang, startformationen.sortBy(d => d._1 * 100 + d._2.map( dzl.indexOf(_)).getOrElse(0)))
Expand All @@ -88,10 +122,13 @@ object RiegenBuilder {
.map{d =>
val ((durchgang, kandidatriegen), durchgangIndex) = d
val riegen1 = kandidatriegen.map(_._2)
val dzl1 = kandidatriegen.flatMap(_._1.diszipline2)
val riegen = riegen1.sortBy(r => r.start.map( dzl1.indexOf(_)))
val dzl2 = dzl1.toSet.toList
val dzl = dzl2.sortBy{dzl1.indexOf(_)}
val dzlmap: Map[Disziplin, Int] = kandidatriegen.flatMap(_._1.diszipline2.zipWithIndex).foldLeft(Map[Disziplin, Int]()) { (acc, item) =>
acc.updated(item._1, item._2)
}
val dzl = dzlmap.keys.toList.sortBy {
dzlmap(_)
}
val riegen = riegen1.sortBy(r => r.start.map( dzlmap(_)))

//kandidat.diszipline für die Rotationsberechnung verwenden
val rg = riegen.groupBy(e => e.start).toList.sortBy{d => d._1.map( dzl.indexOf(_))}
Expand All @@ -100,7 +137,9 @@ object RiegenBuilder {
case Some(_) => acc
case _ => acc :+ (Some(item) -> List[Riege]())
}
}
}.sortBy(geraet => geraet._1.map(g => dzl.indexOf(g)))
.map(geraet => (geraet._1, geraet._2, dzlmap(geraet._1.get)))

val startformationen = pickStartformationen(geraete, durchgang, k => (k.einteilung2, k.diszipline2))
.zipWithIndex
.map(x => {
Expand Down

0 comments on commit dc99203

Please sign in to comment.