typestar

temp_stats.scala en Scala

Una semana de temperaturas máximas como tabla de estadísticas y gráfico de barras.

// Daily high temperatures for one week, summarized as a bar chart.

val week: List[(String, Int)] = List(
  ("Mon", 61), ("Tue", 68), ("Wed", 74),
  ("Thu", 71), ("Fri", 59), ("Sat", 55), ("Sun", 66),
)

val highs: List[Int] = week.map((_, temp) => temp)
val mean: Double = highs.sum.toDouble / highs.size

// Measuring each bar from the coldest day spends the width on the
// differences; the coldest day itself keeps a single mark.
def bar(temp: Int, floor: Int): String = "#" * (temp - floor + 1)

// Each day is marked against the week's mean, which is what makes
// the table say something the raw numbers do not.
def mark(temp: Int): String =
  if temp > mean then "above"
  else if temp < mean then "below"
  else "even"

@main def tempStats(): Unit =
  val coldest = highs.min
  val warmest = highs.max
  val (coldDay, _) = week.minBy((_, temp) => temp)
  val (warmDay, _) = week.maxBy((_, temp) => temp)

  println(f"${"day"}%-5s${"high"}%6s  ${"vs mean"}%-8s${"chart"}%s")
  println("-" * 40)
  for (day, temp) <- week do
    println(f"$day%-5s$temp%6d  ${mark(temp)}%-8s${bar(temp, coldest)}%s")
  println("-" * 40)

  println(f"mean   $mean%6.1f")
  println(f"range  ${warmest - coldest}%6d degrees")
  println(s"coldest $coldDay at $coldest, warmest $warmDay at $warmest")

Cómo funciona

  1. highs.sum.toDouble / highs.size da el promedio contra el que se juzga cada fila.
  2. mark marca el día por encima o por debajo, y "#" * (temp - floor + 1) dibuja la barra desde el día más frío.
  3. week.minBy((_, temp) => temp) y su gemelo maxBy nombran los días en el resumen final.

Palabras clave y builtins usados aquí

El intento, en números

Líneas
36
Caracteres a escribir
1250
Tokens
309
Ritmo de tres estrellas
80 tpm

Al ritmo de tres estrellas de 80 tokens por minuto, este intento toma unos 232 segundos.

Escribe este fragmento

Paso 3 de 3 en Bis; paso 27 de 27 en Fundamentos del lenguaje.

← Anterior