couples-entiers-2.lisp (5059B)
1 #| 2 Auteur : John CHARRON 3 email : charron.john@gmail.com 4 |# 5 6 ;; définition des variables globales (toujours entre astérisques) 7 (defvar *current* (list 0 0 0)) ;; liste courante (clé x y) 8 (setf *current* (list 0 0 0)) 9 (defvar *db* nil) ;; base de données qui stocke tous les "(clé x y)" 10 (setf *db* nil) 11 (push *current* *db*) 12 13 (defvar *max-x* 0) ;; valeur maximale de x jusque atteinte 14 (setf *max-x* 0) 15 (defvar *max-y* 0) ;; valeur maximale de y jusque atteinte 16 (setf *max-y* 0) 17 (defvar *min-x* 0) ;; valeur minimale de x atteinte 18 (setf *min-x* 0) 19 (defvar *min-y* 0) ;; valeur minimale de y atteinte 20 (setf *min-y* 0) 21 22 #| pour remettre toutes les variables globales à leur valeurs par défaut 23 afin de tester, de refaire un 'zig-zag', etc. 24 |# 25 (defun reset () 26 (progn 27 (defvar *current* (list 0 0 0)) ;; liste courante (clé x y) 28 (setf *current* (list 0 0 0)) 29 (defvar *db* nil) ;; base de données qui stocke tous les "(clé x y)" 30 (setf *db* nil) 31 (push *current* *db*) 32 (defvar *max-x* 0) ;; valeur maximal de x jusque "là" 33 (setf *max-x* 0) 34 (defvar *max-y* 0) ;; valeur maximal de y jusque "là" 35 (setf *max-y* 0) 36 (defvar *min-x* 0) ;; valeur minimale de x atteinte 37 (setf *min-x* 0) 38 (defvar *min-y* 0) ;; valeur minimale de y atteinte 39 (setf *min-y* 0) 40 *current*)) 41 42 #| Les fonctions "right" "down", "down", "up" imitent le movement des 43 coordonnées sur un graphe mais au les coordonnées "y" positifs sont en DESSOUS du graphe 44 |# 45 46 (defun right (L) 47 (progn 48 (push 49 (setf *current* 50 (cons (+ 1 (first L)) (cons (+ 1 (second L)) (last L)))) *db*) 51 *current*)) 52 53 (defun left (L) 54 (progn 55 (push 56 (setf *current* 57 (cons (+ 1 (first L)) (cons (- (second L) 1) (last L)))) *db*) 58 *current*)) 59 60 (defun up (L) 61 (progn 62 (push 63 (setf *current* 64 (cons (+ 1 (first L)) (cons (second L) (cons (+ (third L) 1) ())))) *db*) 65 *current*)) 66 67 (defun down (L) 68 (progn 69 (push 70 (setf *current* 71 (cons (+ 1 (first L)) (cons (second L) (cons (- (third L) 1) ())))) *db*) 72 *current*)) 73 74 (defun loop-right (L) 75 (loop 76 (when (= (second L) (+ (- *min-x*) 1)) (*current*)) 77 (progn 78 (push 79 (setf *current* 80 (cons (+ 1 (first L)) (cons (+ 1 (second L)) (last L)))) *db*) 81 (update-all L)))) 82 83 (defun loop-left (L) 84 (loop 85 (when (= (second L) (- *max-x*)) (return)) 86 (progn 87 (push 88 (setf *current* 89 (cons (+ 1 (first L)) (cons (- (second L) 1) (last L)))) *db*) 90 (update-all L) 91 *current*))) 92 93 (defun loop-up (L) 94 (loop 95 (when (= (third L) (+ (- *min-y*) 1)) (return)) 96 (progn 97 (push 98 (setf *current* 99 (cons (+ 1 (first L)) (cons (second L) (cons (+ (third L) 1) ())))) *db*) 100 (update-all L) 101 *current*))) 102 103 (defun loop-down (L) 104 (loop 105 (when (= (third L) (- *max-y*)) (return)) 106 (progn 107 (push 108 (setf *current* 109 (cons (+ 1 (first L)) (cons (second L) (cons (- (third L) 1) ())))) *db*) 110 (update-all L) 111 *current*))) 112 113 114 115 116 (defun update-max-x (L) 117 (if (> (second L) *max-x*) 118 (setf *max-x* (second L)) 119 nil)) 120 121 (defun update-max-y (L) 122 (if (> (third L) *max-y*) 123 (setf *max-y* (third L)) 124 nil)) 125 126 (defun update-min-x (L) 127 (if (< (second L) *min-x*) 128 (setf *min-x* (second L)) 129 nil)) 130 131 (defun update-min-y (L) 132 (if (> (third L) *max-y*) 133 (setf *min-y* (third L)) 134 nil)) 135 136 (defun print-all () 137 (print "*current*") 138 (print *current*) 139 (print "*max-x*: ~S") 140 (print *max-x*)) 141 142 (defun update-all (L) 143 (cond 144 ((> (second L) *max-x*) 145 (setf *max-x* (second L))) 146 ((> (third L) *max-y*) 147 (setf *max-y* (third L))) 148 ((< (second L) *min-x*) 149 (setf *min-x* (second L))) 150 ((< (third L) *min-y*) 151 (setf *min-y* (third L))) 152 (t ()))) 153 154 ;; "move" s'occupe de choisir "right", "down-left" etc. selon les valeurs dans *current* 155 (defun move (L) 156 (cond 157 ((and (= (* (isqrt (first L)) (+ (isqrt (first L)) 1)) (first L)) (evenp (isqrt (first L)))) 158 (print "in RIGHT") 159 (loop-right L)) 160 ((and (integerp (sqrt (first L))) (oddp (first L))) 161 (print "in UP") 162 (loop-up L)) 163 ((and (= (* (isqrt (first L)) (+ (isqrt (first L)) 1)) (first L)) (oddp (isqrt (first L)))) 164 (print "in LEFT") 165 (loop-left L)) 166 ((and (integerp (sqrt (first L))) (evenp (first L))) 167 (print "in DOWN") 168 (loop-down L)) 169 (t *current*) 170 )) 171 172 173 #| 174 On fait un "move" et puis un "update-max-x-y" 175 Attention : il faut bien faire un setf L, sinon, le paramètre L de "update-max-x-y utilise la valeur 176 de L inchangé ! 177 |# 178 (defun move-and-update (L) 179 (progn 180 (setf L (move L)) 181 *db*)) 182 183 ;; "zig-zag" fait n "move-and-update" en un seul coup et affiche le contenu de *db* (toutes les couples) 184 (defun zig-zag (L n) 185 (if (zerop n) 186 (move-and-update *current*) 187 (progn 188 (move-and-update *current*) 189 (zig-zag L (- n 1)))))