#lang racket

;;Relaciones de vecindad según regla 1
(define filas-vecinas
  (lambda (fila-a filas)
    (cond
      ((= fila-a 0) 
       (values filas (add1 fila-a)))
      ((= fila-a filas) 
       (values (sub1 fila-a) 0))
      (else
       (values (sub1 fila-a) (add1 fila-a)) )
      )
    ))
(define columnas-vecinas
  (lambda (columna-a columnas)
    (cond
      ((= columna-a 0) 
       (values columnas (add1 columna-a)))
      ((= columna-a columnas) 
       (values (sub1 columna-a) 0))
      (else
       (values (sub1 columna-a) (add1 columna-a)) )
      )
    ))
(define regla-1
  (lambda (columna-a columnas)
    (let-values
        ([(pre-c post-c) (columnas-vecinas columna-a columnas)])
      (values
       (cons 0 pre-c)
       (cons 0 post-c))
      )
    ))
(define von-Neumann
  (lambda (fila-a columna-a filas columnas)
    (let-values
        ([(pre-f post-f) (filas-vecinas fila-a filas)]
         [(pre-c post-c) (columnas-vecinas columna-a columnas)]
         )
      (values
       (cons pre-f columna-a);T
       (cons fila-a post-c);R
       (cons post-f columna-a);B
       (cons fila-a pre-c);L
       )
      )
    ))
;;von-Neumann con rotacion
;; (values T R B L)
;; (values L T R B)
;; (values B L T R)
;; (values R B L T)
(define Moore
  (lambda (fila-a columna-a filas columnas)
    (let-values
        ([(pre-f post-f) (filas-vecinas fila-a filas)]
         [(pre-c post-c) (columnas-vecinas columna-a columnas)]
         )
      (values
       (cons pre-f pre-c)
       (cons pre-f columna-a)
       (cons pre-f post-c)
       (cons fila-a post-c)
       (cons post-f post-c)
       (cons post-f columna-a )
       (cons post-f pre-c)
       (cons fila-a pre-c)
       )
      )
    ))

(provide regla-1 von-Neumann Moore)