typestar

temp_stats.lisp en Lisp

Informa una semana de máximas diarias con mínimo, máximo, media y un gráfico de barras en texto.

;; temp_stats.lisp: a week of daily high temperatures, summarized.

(defparameter *readings*
  '(("Mon" 61.5) ("Tue" 64.0) ("Wed" 70.2) ("Thu" 72.8)
    ("Fri" 68.4) ("Sat" 59.9) ("Sun" 63.1)))

(defun highs (readings)
  (mapcar #'second readings))

(defun mean (values)
  (/ (reduce #'+ values) (length values)))

(defun bar (value low high width)
  "Return a bar of at most WIDTH marks scaling VALUE between LOW and HIGH."
  (let ((span (- high low)))
    (make-string (max 1 (round (* width (/ (- value low) span))))
                 :initial-element #\#)))

(let* ((values (highs *readings*))
       (low (reduce #'min values))
       (high (reduce #'max values))
       (avg (mean values))
       (warm (count-if (lambda (value) (>= value avg)) values)))
  (format t "daily highs in degrees Fahrenheit~%~%")
  (format t "~5a ~7a ~7a ~a~%" "day" "high" "vs avg" "trend")
  (dolist (reading *readings*)
    (let ((day (first reading))
          (value (second reading)))
      (format t "~5a ~7,1f ~7a ~a~%"
              day value
              (if (>= value avg) "above" "below")
              (bar value low high 20))))
  (format t "~%low ~,1f  high ~,1f  mean ~,1f  spread ~,1f~%"
          low high avg (- high low))
  (format t "~d of ~d day~:p at or above the mean~%"
          warm (length values)))

Cómo funciona

  1. reduce con #'min y #'max acota la semana; mean promedia la misma lista.
  2. bar escala cada lectura entre low y high y arma las marcas con make-string.
  3. Cada fila se marca "above" o "below" contra avg, y ~7,1f mantiene un decimal.

Palabras clave y builtins usados aquí

El intento, en números

Líneas
36
Caracteres a escribir
1155
Tokens
260
Ritmo de tres estrellas
80 tpm

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

Escribe este fragmento

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

← Anterior