Algoritmos para mover el cursor a una fecha en un calendario rotativo de 12 meses en Emacs

GOL: El objetivo de este hilo es crear dos (2) fórmulas matemáticas para reemplazar la solución de mano larga por @lawlist en la funciónlawlist-calendar-cursor-to-visible-date (abajo).

                                                            PROBLEMA DE LA HISTORIA

Ahora existe un calendario de 12 meses en Emacs que se desplaza hacia adelante y hacia atrás un mes (o más) a la vez. La funciónlawlist-calendar-cursor-to-visible-date se usa para marcar fechas con superposiciones para eventos designados (por ejemplo, cumpleaños, días festivos, citas, etc.); o, simplemente mover el cursor a una fecha en particular. @lawlist ha ideado una solución a mano, que no utiliza completamente ecuaciones matemáticas para calcular la posición del cursor para cada uno de los 365 días que se muestran. Es posible crear dos (2) algoritmos concisos para reemplazar la solución de mano larga.

Un borrador de trabajo del calendario de desplazamiento de 12 meses (sin la solución de mano larga) se puede encontrar aquí:

     https://stackoverflow.com/a/21409154/2112489

LEYENDA:

displayed-month (números del 1 al 12) es el mes que aparece en la esquina superior izquierda del búfer, y esto cambia a medida que el calendario de 12 meses se desplaza hacia adelante o hacia atrás.

El objetivomonth (números del 1 al 12) es el mes que necesitamos ubicar con ayuda de las dos fórmulas matemáticas: su ubicación varía según la fecha que se marque (por ejemplo, cumpleaños, día festivo, cita) y según eldisplayed-month en la esquina superior izquierda del búfer. El objetivomonth puede estar en cualquiera de las 12 posiciones posibles. Hay tres (3) posiblesx coordenadas del eje (es decir,6, 31o56) Hay cuatro (4) posiblesy coordenadas del eje (es decir,0, 9, 18 años o27) [Cita a coordenadas x / y:http://www.mathsisfun.com/data/cartesian-coordinates.html ]

A row se define como 3 meses horizontalmente.

A column se define como 4 meses verticalmente.

El primer foro debe ser igual0, 9, 18 años o27 dependiendo de si el punto está encendidorow 1, 2, 3 o 4, es decir, de arriba a abajo.

El segundo foro debe ser igual6, 31o56 dependiendo de si el punto está encendidocolumn 1, 2 o 3, es decir, de izquierda a derecha.

EJEMPLO:

Sidisplayed-month es enero (es decir, 1) y el objetivomonth es agosto (es decir, 8), entoncesrow es igual18 años ycolumn es igual31.

Sidisplayed-month es febrero (es decir, 2) y el objetivomonth es agosto (es decir, 8), entoncesrow es igual18 años ycolumn es igual6.

Sidisplayed-month es marzo (es decir, 3) y el objetivomonth es agosto (es decir, 8), entoncesrow es igual9 ycolumn es igual56.

Sidisplayed-month es abril (es decir, 4) y objetivomonth es agosto (es decir, 8), entoncesrow es igual9 ycolumn es igual31.

Sidisplayed-month es mayo (es decir, 5) y el objetivomonth es agosto (es decir, 8), entoncesrow es igual9 ycolumn es igual6.

El calendario de 12 meses tiene el siguiente aspecto a medida que el diseño avanza un mes a la vez:

;;  1 2 3
;;  4 5 6
;;  7 8 9
;;  10 11 12

;;  2 3 4
;;  5 6 7
;;  8 9 10
;;  11 12 1

;;  3 4 5
;;  6 7 8
;;  9 10 11
;;  12 1 2

;;  4 5 6
;;  7 8 9
;;  10 11 12
;;  1 2 3

;;  5 6 7
;;  8 9 10
;;  11 12 1
;;  2 3 4

;;  6 7 8
;;  9 10 11
;;  12 1 2
;;  3 4 5

;;  7 8 9
;;  10 11 12
;;  1 2 3
;;  4 5 6

;;  8 9 10
;;  11 12 1
;;  2 3 4
;;  5 6 7

;;  9 10 11
;;  12 1 2
;;  3 4 5
;;  6 7 8

;;  10 11 12
;;  1 2 3
;;  4 5 6
;;  7 8 9

;;  11 12 1
;;  2 3 4
;;  5 6 7
;;  8 9 10

;;  12 1 2
;;  3 4 5
;;  6 7 8
;;  9 10 11

La solución a largo plazo de @lawlist es la siguiente:

(defun lawlist-calendar-cursor-to-visible-date (date)
  "Move the cursor to DATE that is on the screen."
  (let* (
      (month (calendar-extract-month date))
      (day (calendar-extract-day date))
      (year (calendar-extract-year date))
      (first-of-month-weekday (calendar-day-of-week (list month 1 year))))
    (goto-line
      (+ 3
        ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
        (cond
          ;;  1 2 3
          ;;  4 5 6
          ;;  7 8 9
          ;;  10 11 12
          ((and
              (eq displayed-month 1)
              (memq month `(1 2 3)))
            0)
          ((and
              (eq displayed-month 1)
              (memq month `(4 5 6)))
            9)
          ((and
              (eq displayed-month 1)
              (memq month `(7 8 9)))
            18)
          ((and
              (eq displayed-month 1)
              (memq month `(10 11 12)))
            27)
          ;;  2 3 4
          ;;  5 6 7
          ;;  8 9 10
          ;;  11 12 1
          ((and
              (eq displayed-month 2)
              (memq month `(2 3 4)))
            0)
          ((and
              (eq displayed-month 2)
              (memq month `(5 6 7)))
            9)
          ((and
              (eq displayed-month 2)
              (memq month `(8 9 10)))
            18)
          ((and
              (eq displayed-month 2)
              (memq month `(11 12 1)))
            27)
          ;;  3 4 5
          ;;  6 7 8
          ;;  9 10 11
          ;;  12 1 2
          ((and
              (eq displayed-month 3)
              (memq month `(3 4 5)))
            0)
          ((and
              (eq displayed-month 3)
              (memq month `(6 7 8)))
            9)
          ((and
              (eq displayed-month 3)
              (memq month `(9 10 11)))
            18)
          ((and
              (eq displayed-month 3)
              (memq month `(12 1 2)))
            27)
          ;;  4 5 6
          ;;  7 8 9
          ;;  10 11 12
          ;;  1 2 3
          ((and
              (eq displayed-month 4)
              (memq month `(4 5 6)))
            0)
          ((and
              (eq displayed-month 4)
              (memq month `(7 8 9)))
            9)
          ((and
              (eq displayed-month 4)
              (memq month `(10 11 12)))
            18)
          ((and
              (eq displayed-month 4)
              (memq month `(1 2 3)))
            27)
          ;;  5 6 7
          ;;  8 9 10
          ;;  11 12 1
          ;;  2 3 4
          ((and
              (eq displayed-month 5)
              (memq month `(5 6 7)))
            0)
          ((and
              (eq displayed-month 5)
              (memq month `(8 9 10)))
            9)
          ((and
              (eq displayed-month 5)
              (memq month `(11 12 1)))
            18)
          ((and
              (eq displayed-month 5)
              (memq month `(2 3 4)))
            27)
          ;;  6 7 8
          ;;  9 10 11
          ;;  12 1 2
          ;;  3 4 5
          ((and
              (eq displayed-month 6)
              (memq month `(6 7 8)))
            0)
          ((and
              (eq displayed-month 6)
              (memq month `(9 10 11)))
            9)
          ((and
              (eq displayed-month 6)
              (memq month `(12 1 2)))
            18)
          ((and
              (eq displayed-month 6)
              (memq month `(3 4 5)))
            27)
          ;;  7 8 9
          ;;  10 11 12
          ;;  1 2 3
          ;;  4 5 6
          ((and
              (eq displayed-month 7)
              (memq month `(7 8 9)))
            0)
          ((and
              (eq displayed-month 7)
              (memq month `(10 11 12)))
            9)
          ((and
              (eq displayed-month 7)
              (memq month `(1 2 3)))
            18)
          ((and
              (eq displayed-month 7)
              (memq month `(4 5 6)))
            27)
          ;;  8 9 10
          ;;  11 12 1
          ;;  2 3 4
          ;;  5 6 7
          ((and
              (eq displayed-month 8)
              (memq month `(8 9 10)))
            0)
          ((and
              (eq displayed-month 8)
              (memq month `(11 12 1)))
            9)
          ((and
              (eq displayed-month 8)
              (memq month `(2 3 4)))
            18)
          ((and
              (eq displayed-month 8)
              (memq month `(5 6 7)))
            27)
          ;;  9 10 11
          ;;  12 1 2
          ;;  3 4 5
          ;;  6 7 8
          ((and
              (eq displayed-month 9)
              (memq month `(9 10 11)))
            0)
          ((and
              (eq displayed-month 9)
              (memq month `(12 1 2)))
            9)
          ((and
              (eq displayed-month 9)
              (memq month `(3 4 5)))
            18)
          ((and
              (eq displayed-month 9)
              (memq month `(6 7 8)))
            27)
          ;;  10 11 12
          ;;  1 2 3
          ;;  4 5 6
          ;;  7 8 9
          ((and
              (eq displayed-month 10)
              (memq month `(10 11 12)))
            0)
          ((and
              (eq displayed-month 10)
              (memq month `(1 2 3)))
            9)
          ((and
              (eq displayed-month 10)
              (memq month `(4 5 6)))
            18)
          ((and
              (eq displayed-month 10)
        ,      (memq month `(7 8 9)))
            27)
          ;;  11 12 1
          ;;  2 3 4
          ;;  5 6 7
          ;;  8 9 10
          ((and
              (eq displayed-month 11)
              (memq month `(11 12 1)))
            0)
          ((and
              (eq displayed-month 11)
              (memq month `(2 3 4)))
            9)
          ((and
              (eq displayed-month 11)
              (memq month `(5 6 7)))
            18)
          ((and
              (eq displayed-month 11)
              (memq month `(8 9 10)))
            27)
          ;;  12 1 2
          ;;  3 4 5
          ;;  6 7 8
          ;;  9 10 11
          ((and
              (eq displayed-month 12)
              (memq month `(12 1 2)))
            0)
          ((and
              (eq displayed-month 12)
              (memq month `(3 4 5)))
            9)
          ((and
              (eq displayed-month 12)
              (memq month `(6 7 8)))
            18)
          ((and
              (eq displayed-month 12)
              (memq month `(9 10 11)))
            27) )
        ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
          (/ (+ day  -1
            (mod
              (- (calendar-day-of-week (list month 1 year)) calendar-week-start-day)
                7))
                  7)))
    (move-to-column
      (+ 
        ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
        (cond
          ;;  1 2 3
          ;;  4 5 6
          ;;  7 8 9
          ;;  10 11 12
          ((and
              (eq displayed-month 1)
              (memq month `(1 4 7 10)))
            6)
          ((and
              (eq displayed-month 1)
              (memq month `(2 5 8 11)))
            31)
          ((and
              (eq displayed-month 1)
              (memq month `(3 6 9 12)))
            56)
          ;;  2 3 4
          ;;  5 6 7
          ;;  8 9 10
          ;;  11 12 1
          ((and
              (eq displayed-month 2)
              (memq month `(2 5 8 11)))
            6)
          ((and
              (eq displayed-month 2)
              (memq month `(3 6 9 12)))
            31)
          ((and
              (eq displayed-month 2)
              (memq month `(4 7 10 1)))
            56)
          ;;  3 4 5
          ;;  6 7 8
          ;;  9 10 11
          ;;  12 1 2
          ((and
              (eq displayed-month 3)
              (memq month `(3 6 9 12)))
            6)
          ((and
              (eq displayed-month 3)
              (memq month `(4 7 10 1)))
            31)
          ((and
              (eq displayed-month 3)
              (memq month `(5 8 11 2)))
            56)
          ;;  4 5 6
          ;;  7 8 9
          ;;  10 11 12
          ;;  1 2 3
          ((and
              (eq displayed-month 4)
              (memq month `(4 7 10 1)))
            6)
          ((and
              (eq displayed-month 4)
              (memq month `(5 8 11 2)))
            31)
          ((and
              (eq displayed-month 4)
              (memq month `(6 9 12 3)))
            56)
          ;;  5 6 7
          ;;  8 9 10
          ;;  11 12 1
          ;;  2 3 4
          ((and
              (eq displayed-month 5)
              (memq month `(5 8 11 2)))
            6)
          ((and
              (eq displayed-month 5)
              (memq month `(6 9 12 3)))
            31)
          ((and
              (eq displayed-month 5)
              (memq month `(7 10 1 4)))
            56)
          ;;  6 7 8
          ;;  9 10 11
          ;;  12 1 2
          ;;  3 4 5
          ((and
              (eq displayed-month 6)
              (memq month `(6 9 12 3)))
            6)
          ((and
              (eq displayed-month 6)
              (memq month `(7 10 1 4)))
            31)
          ((and
              (eq displayed-month 6)
              (memq month `(8 11 2 5)))
            56)
          ;;  7 8 9
          ;;  10 11 12
          ;;  1 2 3
          ;;  4 5 6
          ((and
              (eq displayed-month 7)
              (memq month `(7 10 1 4)))
            6)
          ((and
              (eq displayed-month 7)
              (memq month `(8 11 2 5)))
            31)
          ((and
              (eq displayed-month 7)
              (memq month `(9 12 3 6)))
            56)
          ;;  8 9 10
          ;;  11 12 1
          ;;  2 3 4
          ;;  5 6 7
          ((and
              (eq displayed-month 8)
              (memq month `(8 11 2 5)))
            6)
          ((and
              (eq displayed-month 8)
              (memq month `(9 12 3 6)))
            31)
          ((and
              (eq displayed-month 8)
              (memq month `(10 1 4 7)))
            56)
          ;;  9 10 11
          ;;  12 1 2
          ;;  3 4 5
          ;;  6 7 8
          ((and
              (eq displayed-month 9)
              (memq month `(9 12 3 6)))
            6)
          ((and
              (eq displayed-month 9)
              (memq month `(10 1 4 7)))
            31)
          ((and
              (eq displayed-month 9)
              (memq month `(11 2 5 8)))
            56)
          ;;  10 11 12
          ;;  1 2 3
          ;;  4 5 6
          ;;  7 8 9
          ((and
              (eq displayed-month 10)
              (memq month `(10 1 4 7)))
            6)
          ((and
              (eq displayed-month 10)
              (memq month `(11 2 5 8)))
            31)
          ((and
              (eq displayed-month 10)
              (memq month `(12 3 6 9)))
            56)
          ;;  11 12 1
          ;;  2 3 4
          ;;  5 6 7
          ;;  8 9 10
          ((and
              (eq displayed-month 11)
              (memq month `(11 2 5 8)))
            6)
          ((and
              (eq displayed-month 11)
              (memq month `(12 3 6 9)))
            31)
          ((and
              (eq displayed-month 11)
              (memq month `(1 4 7 10)))
            56)
          ;;  12 1 2
          ;;  3 4 5
          ;;  6 7 8
          ;;  9 10 11
          ((and
              (eq displayed-month 12)
              (memq month `(12 3 6 9)))
            6)
          ((and
              (eq displayed-month 12)
              (memq month `(1 4 7 10)))
            31)
          ((and
              (eq displayed-month 12)
              (memq month `(2 5 8 11)))
            56) )
        ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
          (* 3 (mod
            (- (calendar-day-of-week date) calendar-week-start-day)
              7))))))

Respuestas a la pregunta(1)

Su respuesta a la pregunta