diff --git a/exo4-programmes/couples b/exo4-programmes/couples new file mode 100755 index 0000000..2a6c3d9 Binary files /dev/null and b/exo4-programmes/couples differ diff --git a/exo4-programmes/couples-2.lisp b/exo4-programmes/couples-2.lisp new file mode 100644 index 0000000..af78fd6 --- /dev/null +++ b/exo4-programmes/couples-2.lisp @@ -0,0 +1,106 @@ +(defun gauss-formula (n) + (/ (* n (+ n 1)) 2)) + +(defun get-n (code) + (isqrt (* code 2))) + +(defun get-axis (code) + (gauss-formula (isqrt (* code 2)))) + +(defun get-axis-from-n (n) + (gauss-formula n)) + +(defun axis-code-compare (code) + (format t "~d ~d~%" code (get-axis code))) + +(defun axis-code-compare-n (startcode n) + (let ((i 0)) + (loop + (when (> i n) (return)) + (axis-code-compare (+ startcode i)) + (incf i)))) + +(defun ord-pr-to-code (x y) + (let ((sumxy (+ x y))) + (if (evenp sumxy) + (+ (gauss-formula sumxy) x) + (+ (gauss-formula sumxy) y)))) + +(defun code-to-ord-pr (code) + (let ((n (get-n code)) + (axis (get-axis code)) + (diff 0)) + (progn + (when (> (get-axis code) code) + (progn + (setf n (- n 1)) + (setf axis (get-axis-from-n n)))) + (setf diff (- code axis)) + (if (evenp n) + (cons diff (cons (- n diff) ())) + (cons (- n diff) (cons diff ())))))) + +(defun ord-mult-to-code (L) + (if (= (list-length L) 1) + (car L) + (ord-mult-to-code (append (butlast (butlast L)) + (cons (ord-pr-to-code (car (last (butlast L))) (car (last L))) ()))))) + +(defun code-to-ord-mult (L-or-code size) + (if (atom L-or-code) + (code-to-ord-mult (code-to-ord-pr L-or-code) (- size 1)) + (if (not (= size 1)) + (code-to-ord-mult (append (butlast L-or-code) (code-to-ord-pr (car (last L-or-code)))) + (- size 1)) + L-or-code))) + +#| Les codes générés par cette fonction ne correspondent pas au code généré par le +diagramme du rapport ni des fonctions ord-mult-to-code et code-to-ord-mult. +Toutefois, la fonction ci-dessous a été créées ici car son écriture et beaucoup plus idiomatique +en LISP (d'où le nom 'ord-mult-to-code-lisp'). En effet, si on avait à coder les nombres naturels en LISP, on ajouterait +(resp. supprimerait) des éléments de la liste en partant du début de la liste afin de créer +une paire ou un n-uplet (resp. pour trouver le code correspondant à une paire ou un n-uplet +|# +(defun ord-mult-to-code-lisp (L) + (if (= (list-length L) 1) + (car L) + (ord-mult-to-code-lisp (cons (ord-pr-to-code (first L) (second L)) (cddr L))))) + +#| voir le commentaire précédent concernant la fonction ord-mult-to-code-lisp |# +(defun code-to-ord-mult-lisp (L-or-code size) + (if (atom L-or-code) + (code-to-ord-mult-lisp (code-to-ord-pr L-or-code) (- size 1)) + (if (not (= size 1)) + (code-to-ord-mult-lisp (append (code-to-ord-pr (car L-or-code)) (cdr L-or-code)) (- size 1)) + L-or-code))) + +#| +(defun code-to-ord-pr (code) + (;let* ((code*2 (* code 2)) + (n (isqrt code*2)) + (axis (gauss-formula n)) + (diff 0)) + (cond + ((> axis code) + (loop while (> axis code) + ((setf n (- n 1)) + (setf axis (gauss-formula n)))) + (< axis code) + ((loop while (< axis code) + ((setf n (- n 1)) + (setf axis (gauss-formula n)))) + (when (> axis code) + ((setf n (- n 1)) + (setf axis (gauss-formula n)))))) + (t 5)))) + |# + + +(defun loop-test (n) + (let ((n 0)) + (loop + (when (> n 10) (return)) + (format t "~d ~d ~d~%" n (isqrt n) (gauss-formula n)) + ;(print n) (write (* n n)) (write n) + (incf n)))) + diff --git a/exo4-programmes/couples-3.lisp b/exo4-programmes/couples-3.lisp new file mode 100644 index 0000000..272f4f3 --- /dev/null +++ b/exo4-programmes/couples-3.lisp @@ -0,0 +1,108 @@ +(defun gauss-formula (n) + (/ (* n (+ n 1)) 2)) + +(defun get-n (code) + (isqrt (* code 2))) + +(defun get-axis (code) + (gauss-formula (isqrt (* code 2)))) + +(defun get-axis-from-n (n) + (gauss-formula n)) + +(defun axis-code-compare (code) + (format t "~d ~d~%" code (get-axis code))) + +(defun axis-code-compare-n (startcode n) + (let ((i 0)) + (loop + (when (> i n) (return)) + (axis-code-compare (+ startcode i)) + (incf i)))) + +(defun ord-pr-to-code-nat (x y) + (let ((sumxy (+ x y))) + (if (evenp sumxy) + (+ (gauss-formula sumxy) x) + (+ (gauss-formula sumxy) y)))) + +(defun code-to-ord-pr-nat (code) + (let ((n (get-n code)) + (axis (get-axis code)) + (diff 0)) + (progn + (when (> (get-axis code) code) + (progn + (setf n (- n 1)) + (setf axis (get-axis-from-n n)))) + (setf diff (- code axis)) + (if (evenp n) + (cons diff (cons (- n diff) ())) + (cons (- n diff) (cons diff ())))))) + +(defun nat-to-int (nat) + (if (< nat 0) + (- (* 2 (abs nat)) 1) + (* 2 (abs nat)))) + +(defun int-to-nat (int) + (if (evenp int) + (/ int 2) + (ceiling (- (- (/ int 2)) 1)))) + + +(defun ord-pr-to-code-int (x y) + (setf x (nat-to-int x)) + (setf y (nat-to-int y)) + (ord-pr-to-code-nat x y)) + +(defun code-to-ord-pr-int (code) + (let ((L (code-to-ord-pr-nat code))) + (progn + (setf L (cons (int-to-nat (first L)) (cdr L))) + (setf L (cons (car L) (cons (int-to-nat (second L)) ()))) + L))) + +(defun ord-mult-to-code-nat (L) + (if (= (list-length L) 1) + (car L) + (ord-mult-to-code-nat (append (butlast (butlast L)) + (cons (ord-pr-to-code-nat (car (last (butlast L))) (car (last L))) ()))))) + +(defun code-to-ord-mult-nat (L-or-code size) + (if (atom L-or-code) + (code-to-ord-mult-nat (code-to-ord-pr L-or-code) (- size 1)) + (if (not (= size 1)) + (code-to-ord-mult-nat (append (butlast L-or-code) (code-to-ord-pr (car (last L-or-code)))) + (- size 1)) + L-or-code))) + +#| Les codes générés par cette fonction ne correspondent pas au code généré par le +diagramme du rapport ni des fonctions ord-mult-to-code et code-to-ord-mult. +Toutefois, la fonction ci-dessous a été créées ici car son écriture et beaucoup plus idiomatique +en LISP (d'où le nom 'ord-mult-to-code-lisp'). En effet, si on avait à coder les nombres naturels en LISP, on ajouterait +(resp. supprimerait) des éléments de la liste en partant du début de la liste afin de créer +une paire ou un n-uplet (resp. pour trouver le code correspondant à une paire ou un n-uplet. +On aurait pu faire pareil pour les fonctions concernant tous les entiers +|# +(defun ord-mult-to-code-nat-lisp (L) + (if (= (list-length L) 1) + (car L) + (ord-mult-to-code-lisp (cons (ord-pr-to-code (first L) (second L)) (cddr L))))) + +#| voir le commentaire précédent concernant la fonction ord-mult-to-code-lisp |# +(defun code-to-ord-mult-nat-lisp (L-or-code size) + (if (atom L-or-code) + (code-to-ord-mult-lisp (code-to-ord-pr L-or-code) (- size 1)) + (if (not (= size 1)) + (code-to-ord-mult-lisp (append (code-to-ord-pr (car L-or-code)) (cdr L-or-code)) (- size 1)) + L-or-code))) + +(defun loop-test (n) + (let ((n 0)) + (loop + (when (> n 10) (return)) + (format t "~d ~d ~d~%" n (isqrt n) (gauss-formula n)) + ;(print n) (write (* n n)) (write n) + (incf n)))) + diff --git a/exo4-programmes/couples-entiers-2.lisp b/exo4-programmes/couples-entiers-2.lisp new file mode 100644 index 0000000..4c85f97 --- /dev/null +++ b/exo4-programmes/couples-entiers-2.lisp @@ -0,0 +1,189 @@ +#| +Auteur : John CHARRON +email : charron.john@gmail.com +|# + +;; définition des variables globales (toujours entre astérisques) +(defvar *current* (list 0 0 0)) ;; liste courante (clé x y) +(setf *current* (list 0 0 0)) +(defvar *db* nil) ;; base de données qui stocke tous les "(clé x y)" +(setf *db* nil) +(push *current* *db*) + +(defvar *max-x* 0) ;; valeur maximale de x jusque atteinte +(setf *max-x* 0) +(defvar *max-y* 0) ;; valeur maximale de y jusque atteinte +(setf *max-y* 0) +(defvar *min-x* 0) ;; valeur minimale de x atteinte +(setf *min-x* 0) +(defvar *min-y* 0) ;; valeur minimale de y atteinte +(setf *min-y* 0) + +#| pour remettre toutes les variables globales à leur valeurs par défaut +afin de tester, de refaire un 'zig-zag', etc. +|# +(defun reset () + (progn + (defvar *current* (list 0 0 0)) ;; liste courante (clé x y) + (setf *current* (list 0 0 0)) + (defvar *db* nil) ;; base de données qui stocke tous les "(clé x y)" + (setf *db* nil) + (push *current* *db*) + (defvar *max-x* 0) ;; valeur maximal de x jusque "là" + (setf *max-x* 0) + (defvar *max-y* 0) ;; valeur maximal de y jusque "là" + (setf *max-y* 0) + (defvar *min-x* 0) ;; valeur minimale de x atteinte + (setf *min-x* 0) + (defvar *min-y* 0) ;; valeur minimale de y atteinte + (setf *min-y* 0) + *current*)) + +#| Les fonctions "right" "down", "down", "up" imitent le movement des +coordonnées sur un graphe mais au les coordonnées "y" positifs sont en DESSOUS du graphe +|# + +(defun right (L) + (progn + (push + (setf *current* + (cons (+ 1 (first L)) (cons (+ 1 (second L)) (last L)))) *db*) + *current*)) + +(defun left (L) + (progn + (push + (setf *current* + (cons (+ 1 (first L)) (cons (- (second L) 1) (last L)))) *db*) + *current*)) + +(defun up (L) + (progn + (push + (setf *current* + (cons (+ 1 (first L)) (cons (second L) (cons (+ (third L) 1) ())))) *db*) + *current*)) + +(defun down (L) + (progn + (push + (setf *current* + (cons (+ 1 (first L)) (cons (second L) (cons (- (third L) 1) ())))) *db*) + *current*)) + +(defun loop-right (L) + (loop + (when (= (second L) (+ (- *min-x*) 1)) (*current*)) + (progn + (push + (setf *current* + (cons (+ 1 (first L)) (cons (+ 1 (second L)) (last L)))) *db*) + (update-all L)))) + +(defun loop-left (L) + (loop + (when (= (second L) (- *max-x*)) (return)) + (progn + (push + (setf *current* + (cons (+ 1 (first L)) (cons (- (second L) 1) (last L)))) *db*) + (update-all L) + *current*))) + +(defun loop-up (L) + (loop + (when (= (third L) (+ (- *min-y*) 1)) (return)) + (progn + (push + (setf *current* + (cons (+ 1 (first L)) (cons (second L) (cons (+ (third L) 1) ())))) *db*) + (update-all L) + *current*))) + +(defun loop-down (L) + (loop + (when (= (third L) (- *max-y*)) (return)) + (progn + (push + (setf *current* + (cons (+ 1 (first L)) (cons (second L) (cons (- (third L) 1) ())))) *db*) + (update-all L) + *current*))) + + + + +(defun update-max-x (L) + (if (> (second L) *max-x*) + (setf *max-x* (second L)) + nil)) + +(defun update-max-y (L) + (if (> (third L) *max-y*) + (setf *max-y* (third L)) + nil)) + +(defun update-min-x (L) + (if (< (second L) *min-x*) + (setf *min-x* (second L)) + nil)) + +(defun update-min-y (L) + (if (> (third L) *max-y*) + (setf *min-y* (third L)) + nil)) + +(defun print-all () + (print "*current*") + (print *current*) + (print "*max-x*: ~S") + (print *max-x*)) + +(defun update-all (L) + (cond + ((> (second L) *max-x*) + (setf *max-x* (second L))) + ((> (third L) *max-y*) + (setf *max-y* (third L))) + ((< (second L) *min-x*) + (setf *min-x* (second L))) + ((< (third L) *min-y*) + (setf *min-y* (third L))) + (t ()))) + +;; "move" s'occupe de choisir "right", "down-left" etc. selon les valeurs dans *current* +(defun move (L) + (cond + ((and (= (* (isqrt (first L)) (+ (isqrt (first L)) 1)) (first L)) (evenp (isqrt (first L)))) + (print "in RIGHT") + (loop-right L)) + ((and (integerp (sqrt (first L))) (oddp (first L))) + (print "in UP") + (loop-up L)) + ((and (= (* (isqrt (first L)) (+ (isqrt (first L)) 1)) (first L)) (oddp (isqrt (first L)))) + (print "in LEFT") + (loop-left L)) + ((and (integerp (sqrt (first L))) (evenp (first L))) + (print "in DOWN") + (loop-down L)) + (t *current*) + )) + + +#| +On fait un "move" et puis un "update-max-x-y" +Attention : il faut bien faire un setf L, sinon, le paramètre L de "update-max-x-y utilise la valeur +de L inchangé ! +|# +(defun move-and-update (L) + (progn + (setf L (move L)) + *db*)) + +;; "zig-zag" fait n "move-and-update" en un seul coup et affiche le contenu de *db* (toutes les couples) +(defun zig-zag (L n) + (if (zerop n) + (move-and-update *current*) + (progn + (move-and-update *current*) + (zig-zag L (- n 1))))) diff --git a/exo4-programmes/couples-entiers.lisp b/exo4-programmes/couples-entiers.lisp new file mode 100644 index 0000000..68b680d --- /dev/null +++ b/exo4-programmes/couples-entiers.lisp @@ -0,0 +1,151 @@ +#| +Auteur : John CHARRON +email : charron.john@gmail.com +|# + +;; définition des variables globales (toujours entre astérisques) +(defvar *current* (list 0 0 0)) ;; liste courante (clé x y) +(setf *current* (list 0 0 0)) +(defvar *db* nil) ;; base de données qui stocke tous les "(clé x y)" +(setf *db* nil) +(push *current* *db*) + +(defvar *max-x* 0) ;; valeur maximale de x jusque atteinte +(setf *max-x* 0) +(defvar *max-y* 0) ;; valeur maximale de y jusque atteinte +(setf *max-y* 0) +(defvar *min-x* 0) ;; valeur minimale de x atteinte +(setf *min-x* 0) +(defvar *min-y* 0) ;; valeur minimale de y atteinte +(setf *min-y* 0) + +#| pour remettre toutes les variables globales à leur valeurs par défaut +afin de tester, de refaire un 'zig-zag', etc. +|# +(defun reset () + (progn + (defvar *current* (list 0 0 0)) ;; liste courante (clé x y) + (setf *current* (list 0 0 0)) + (defvar *db* nil) ;; base de données qui stocke tous les "(clé x y)" + (setf *db* nil) + (push *current* *db*) + (defvar *max-x* 0) ;; valeur maximal de x jusque "là" + (setf *max-x* 0) + (defvar *max-y* 0) ;; valeur maximal de y jusque "là" + (setf *max-y* 0) + (defvar *min-x* 0) ;; valeur minimale de x atteinte + (setf *min-x* 0) + (defvar *min-y* 0) ;; valeur minimale de y atteinte + (setf *min-y* 0) + *current*)) + +#| Les fonctions "right" "down", "down", "up" imitent le movement des +coordonnées sur un graphe mais au les coordonnées "y" positifs sont en DESSOUS du graphe +|# + +(defun right (L) + (progn + (push + (setf *current* + (cons (+ 1 (first L)) (cons (+ 1 (second L)) (last L)))) *db*) + *current*)) + +(defun left (L) + (progn + (push + (setf *current* + (cons (+ 1 (first L)) (cons (- (second L) 1) (last L)))) *db*) + *current*)) + +(defun up (L) + (progn + (push + (setf *current* + (cons (+ 1 (first L)) (cons (second L) (cons (+ (third L) 1) ())))) *db*) + *current*)) + +(defun down (L) + (progn + (push + (setf *current* + (cons (+ 1 (first L)) (cons (second L) (cons (- (third L) 1) ())))) *db*) + *current*)) + +(defun update-max-x (L) + (if (> (second L) *max-x*) + (setf *max-x* (second L)) + nil)) + +(defun update-max-y (L) + (if (> (third L) *max-y*) + (setf *max-y* (third L)) + nil)) + +(defun update-min-x (L) + (if (< (second L) *min-x*) + (setf *min-x* (second L)) + nil)) + +(defun update-min-y (L) + (if (> (third L) *max-y*) + (setf *min-y* (third L)) + nil)) + +(defun print-all () + (print "*current*") + (print *current*) + (print "*max-x*: ~S") + (print *max-x*)) + +(defun update-all (L) + (cond + ((> (second L) *max-x*) + (setf *max-x* (second L))) + ((> (third L) *max-y*) + (setf *max-y* (third L))) + ((< (second L) *min-x*) + (setf *min-x* (second L))) + ((< (third L) *min-y*) + (setf *min-y* (third L))) + (t ()))) + +;; "move" s'occupe de choisir "right", "down-left" etc. selon les valeurs dans *current* +(defun move (L) + (cond + ((and (zerop (second L)) (zerop (third L))) ; if x== 0 && y==0 then go right TO BEGIN + (print "in RIGHT") + (right L)) + ((and (= *min-y* (- *max-y*)) (< (second L) (+ (- *min-x*) 1))) + (print "in RIGHT") + (right L)) + ((and (= *max-x* (+ (- *min-x*) 1)) (< (third L) (+ (- *min-y*) 1))) + (print "in UP") + (up L)) + ((and (= *max-y* (+ (- *min-y*) 1)) (> (second L) (- *max-x*))) + (print "in LEFT") + (left L)) + ((and (= *min-x* (- *max-x*)) (> (third L) (- *max-y*))) + (print "in DOWN") + (down L)) + (t *current*) + )) + + +#| +On fait un "move" et puis un "update-max-x-y" +Attention : il faut bien faire un setf L, sinon, le paramètre L de "update-max-x-y utilise la valeur +de L inchangé ! +|# +(defun move-and-update (L) + (progn + (setf L (move L)) + (update-all L) + *db*)) + +;; "zig-zag" fait n "move-and-update" en un seul coup et affiche le contenu de *db* (toutes les couples) +(defun zig-zag (L n) + (if (zerop n) + (move-and-update *current*) + (progn + (move-and-update *current*) + (zig-zag L (- n 1))))) diff --git a/exo4-programmes/couples-old.c b/exo4-programmes/couples-old.c new file mode 100644 index 0000000..b06ebf5 --- /dev/null +++ b/exo4-programmes/couples-old.c @@ -0,0 +1,264 @@ +#include +#include +#include + +int pair(int x){ + return (!(x % 2)); +} + +/* +int code_couples_very_slow(int _x, int _y){ + int x, y; + x = y = 0; + int code = 0; + char direction = 'r'; // 'l' pour "left-down", 'r' pour "right-up" + printf("In the 'couples' function\n"); + sleep(1); + while(((x != _x) || (y != _y))){ + if((y == 0) && (pair(x))){ + printf("IF1:\n"); + sleep(1); + x++; + code++; + direction = 'l'; + printf("IF N° 1, x = %d, y = %d, code = %d\n", x, y, code); + sleep(1); + } + else if((x == 0) && (!pair(y))){ + printf("IF2:\n"); + sleep(1); + y++; + code++; + direction = 'r'; + printf("IF N° 2, x = %d, y = %d, code = %d\n", x, y, code); + sleep(1); + } + else if((y == 0) && (direction == 'l')){ + printf("IF3:\n"); + sleep(1); + while((x != 0) && ((x != _x) || (y != _y))){ + printf("WHILE3:\n"); + sleep(1); + x--; + y++; + code++; + printf("IF N° 3, x = %d, y = %d, code = %d\n", x, y, code); + sleep(1); + } + } + else if((x == 0) && (direction == 'r')){ + printf("IF4:\n"); + sleep(1); + while((y != 0) && ((x != _x) || (y != _y))){ + printf("WHILE4:\n"); + sleep(1); + x++; + y--; + code++; + printf("IF N° 4, x = %d, y = %d, code = %d\n", x, y, code); + sleep(1); + } + } + } + return code; +} + +int code_couples_slow(int _x, int _y){ + int x, y; + x = y = 0; + int code = 0; + char direction = 'r'; // 'l' pour "left-down", 'r' pour "right-up" + while(((x != _x) || (y != _y))){ + if((y == 0) && (pair(x))){ + x++; + code++; + direction = 'l'; + } + else if((x == 0) && (!pair(y))){ + y++; + code++; + direction = 'r'; + } + else if((y == 0) && (direction == 'l')){ + while((x != 0) && ((x != _x) || (y != _y))){ + x--; + y++; + code++; + } + } + else if((x == 0) && (direction == 'r')){ + while((y != 0) && ((x != _x) || (y != _y))){ + x++; + y--; + code++; + } + } + } + return code; +} +*/ + +int orderedPairToCode(int x, int y){ + int sumxy, code; + sumxy = x + y; + code = ((sumxy)*(sumxy + 1))/2; + + if(pair(sumxy)){ + code = code + x; + } + else{ + code = code + y; + } + return code; +} + + +int* codeToOrderedPair(int code){ + int *couple = malloc(2*sizeof(int)); + int n = sqrt(code * 2); + int axis = (n * (n + 1))/2; + int diff = 0; + if(axis > code){ + while(axis > code){ + n = n - 1; + axis = (n * (n + 1))/2; + } + } + else if(axis < code){ + while(axis < code){ + n = n + 1; + axis = (n * (n + 1))/2; + } + if(axis > code){ + n = n - 1; + axis = (n * (n + 1))/2; + } + } + + if(axis == code){ // je pense que je peux me dispenser de cet "if", ça revient au même car diff serait = 0 + if(pair(n)){ + couple[0] = 0; + couple[1] = n; + } + else{ + couple[0] = n; + couple[1] = 0; + } + } + if(axis != code){ // idem + diff = code - axis; + if(pair(n)){ + couple[0] = diff; + couple[1] = n - diff; + } + else{ + couple[0] = n - diff; + couple[1] = diff; + } + } + return couple; +} + +int* codeToOrderedPair2(int code){ + int *couple = malloc(2*sizeof(int)); + int n = sqrt(code * 2); + int axis = (n * (n + 1))/2; + int diff = 0; + if(axis > code){ + n = n - 1; + axis = (n * (n + 1))/2; + } + diff = code - axis; + if(pair(n)){ + couple[0] = diff; + couple[1] = n - diff; + } + else{ + couple[0] = n - diff; + couple[1] = diff; + } + return couple; +} + + +int orderedMultipleToCode(int *arr, int size){ + int code; + if(size > 1){ + code = orderedPairToCode(arr[size - 2], arr[size - 1]); + arr[size - 2] = code; + arr = realloc(arr, (size - 1)); + if(size > 2){ + code = orderedMultipleToCode(&arr[0], (size - 1)); + } + } + return code; +} + +int* codeToOrderedMultiple(int code, int size){ + int *multiple = malloc(size*sizeof(int)); + int *pair; + int i = 0; + for(i = 0; i < (size - 1); i++){ + pair = codeToOrderedPair(code); + code = pair[1]; + multiple[i] = pair[0]; + multiple[i + 1] = pair[1]; + } + return multiple; +} + + +int main(int argc, char **argv, char **envp){ + + int x = 0; + int y = 0; + int code = 0; + int *p; + int size = 0; + + do{ + /* + printf ("\nx = "); + scanf("%d",&x); + printf ("y = "); + scanf("%d",&y); + code = orderedPairToCode(x, y); + printf("Le code du couple (%d, %d) est %d\n", x, y, code); + + printf ("\ncode = "); + scanf("%d",&code); + p = codeToOrderedPair(code); + printf("The ordered pair identified by code %d is (%d, %d)", code, p[0], p[1]); + +*/ + printf("\nEnter a size of a multidimensional array representing a 'ordered multiple': "); + scanf("%d",&size); + p = malloc(size * sizeof(int)); + int i; + for(i = 0; i < size; i++){ + printf("Enter value number %d: ", i); + scanf("%d", &p[i]); + } + + code = orderedMultipleToCode(p, size); + printf("\n... The code is %d", code); + + + + printf ("\ncode = "); + scanf("%d",&code); + printf ("\nnumber of ordered elements = "); + scanf("%d",&size); + p = codeToOrderedMultiple(code, size); + printf("The ordered multiple identified by code %d contains the following elements: ", code); + printf("("); + for(i = 0; i < (size - 1); i++){ + printf("%d, ", p[i]); + } + printf("%d)", p[size-1]); + + + } + while(code != -1); +} + diff --git a/exo4-programmes/couples.c b/exo4-programmes/couples.c new file mode 100644 index 0000000..ffa1708 --- /dev/null +++ b/exo4-programmes/couples.c @@ -0,0 +1,445 @@ +#include +#include +#include + +int even(int x){ + return (!(x % 2)); +} + +int max(int a, int b){ + if(a > b) + return a; + return b; +} + +long int orderedPairToCodeNat(int x, int y){ + long code; + int sumxy; + sumxy = x + y; + code = ((sumxy)*(sumxy + 1))/2; + + if(even(sumxy)){ + code = code + x; + } + else{ + code = code + y; + } + return code; +} + +int* codeToOrderedPairNat(long int code){ + int *couple = malloc(2*sizeof(int)); + int n = sqrt(code * 2); + long int axis = (n * (n + 1))/2; + int diff = 0; + if(axis > code){ + n = n - 1; + axis = (n * (n + 1))/2; + } + diff = code - axis; + if(even(n)){ + couple[0] = diff; + couple[1] = n - diff; + } + else{ + couple[0] = n - diff; + couple[1] = diff; + } + return couple; +} + +long int orderedPairToCodeInt(int x, int y){ + long int code = 0; + + if (x < 0){ + x = (2 * (abs (x))) - 1; + } + else{ + x = 2 * x; + } + + if (y < 0){ + y = (2 * (abs(y))) - 1; + } + else{ + y = 2 * y; + } + + code = orderedPairToCodeNat(x, y); + return code; +} + +int* codeToOrderedPairInt(long int code){ + int *pair = codeToOrderedPairNat(code); + + if (even(pair[0])){ + pair[0] = pair[0] / 2; + } + else{ + pair[0] = (pair[0] / 2)*(-1) - 1; + } + + if (even (pair[1])){ + pair[1] = pair[1] / 2; + } + else{ + pair[1] = (pair[1] / 2)*(-1) - 1; + } + + return pair; +} + +long int orderedPairToCodeIntAlgo2(int x, int y){ + long int code = 0; + int _x, _y, diff; + _x = _y = diff = 0; + int temp; + int absmax; + absmax = max(abs(x), abs(y)); + + if(absmax == abs(x)){ // _x == x + _x = _y = x; + temp = abs(x) * 2; + if(x < 0){ // x negative + code = temp * (temp + 1); + if(y < 0){ // x negative, y negative + diff = abs(_y) - abs(y); + } + else{ // x negative, y positive + diff = abs(_y) + abs(y); + } + } + else{ // x positive + code = (temp - 1) * temp; + if(y > 0){ // x positive, y positive + diff = abs(_y) - abs(y); + } + else{ // x positive, y negative + diff = abs(_y) + abs(y); + } + } + code = code - diff; + } + else{ // _y = y + _x = _y = y; + temp = abs(y) * 2; + if(y < 0){ // y negative + code = temp * (temp + 1); + if(x < 0){ // y negative, x negative + diff = abs(_x) - abs(x); + } + else{ // y negative, x positive + diff = abs(_x) + abs (x); + } + } + else{ // y positive + code = (temp - 1) * temp; + if(x > 0){ // y positive, x positive + diff = abs(_x) - abs(x); + } + else{ // y positive, x negative + diff = abs(_x) + abs(x); + } + } + code = code + diff; + } + return code; +} + +int* codeToOrderedPairIntAlgo2(long int code){ + int* pair = malloc(2*sizeof(int)); + int isqrtcode = (int) sqrt(code); + long int pivotcode = isqrtcode * (isqrtcode + 1); + int x, y; + x = y = 0; + + if(even(isqrtcode)){ + x = y = -(isqrtcode / 2); + if(code > pivotcode){ + x = x + (code - pivotcode); + } + else{ + y = y + (pivotcode - code); + } + } + else{ + x = y = (isqrtcode / 2) + 1; + if(code > pivotcode){ + x = x - (code - pivotcode); + } + else{ + y = y - (pivotcode - code); + } + } + pair[0] = x; + pair[1] = y; + return pair; +} + +long int orderedMultipleToCodeNat(int *arr, int size){ + long int code; + if(size > 1){ + code = orderedPairToCodeNat(arr[size - 2], arr[size - 1]); + arr[size - 2] = code; + arr = realloc(arr, (size - 1)); + if(size > 2){ + code = orderedMultipleToCodeNat(&arr[0], (size - 1)); + } + } + return code; +} + +int* codeToOrderedMultipleNat(long int code, int size){ + int *multiple = malloc(size*sizeof(int)); + int *pair; + int i = 0; + for(i = 0; i < (size - 1); i++){ + pair = codeToOrderedPairNat(code); + code = pair[1]; + multiple[i] = pair[0]; + multiple[i + 1] = pair[1]; + } + return multiple; +} + + +long int orderedMultipleToCodeInt(int *arr, int size){ + long int code; + if(size > 1){ + code = orderedPairToCodeInt(arr[size - 2], arr[size - 1]); + arr[size - 2] = code; + arr = realloc(arr, (size - 1)); + if(size > 2){ + code = orderedMultipleToCodeInt(&arr[0], (size - 1)); + } + } + return code; +} + +int* codeToOrderedMultipleInt(long int code, int size){ + int *multiple = malloc(size*sizeof(int)); + int *pair; + int i = 0; + for(i = 0; i < (size - 1); i++){ + pair = codeToOrderedPairInt(code); + code = pair[1]; + multiple[i] = pair[0]; + multiple[i + 1] = pair[1]; + } + return multiple; +} + + +long int orderedMultipleToCodeIntAlgo2(int *arr, int size){ + long int code = 0; + if(size > 1){ + code = orderedPairToCodeIntAlgo2(arr[size - 2], arr[size - 1]); + arr[size - 2] = code; + arr = realloc(arr, (size - 1)); + if(size > 2){ + code = orderedMultipleToCodeIntAlgo2(&arr[0], (size - 1)); + } + } + return code; +} + +int* codeToOrderedMultipleIntAlgo2(long int code, int size){ + int *multiple = malloc(size*sizeof(int)); + int *pair; + int i = 0; + for(i = 0; i < (size - 1); i++){ + pair = codeToOrderedPairIntAlgo2(code); + code = pair[1]; + multiple[i] = pair[0]; + multiple[i + 1] = pair[1]; + } + return multiple; +} + + + + +void testMultiNat(){ + + int x = 0; + int y = 0; + long int code = 0; + int *p; + int size = 0; + + do{ + printf("\n(NATURAL NUMBERS) testPairInt();Enter a size of a multidimensional array representing a 'ordered multiple': "); + scanf("%d",&size); + p = malloc(size * sizeof(int)); + int i; + for(i = 0; i < size; i++){ + printf("Enter value number %d: ", i); + scanf("%d", &p[i]); + } + + code = orderedMultipleToCodeNat(p, size); + printf("\n... The code is %ld", code); + printf ("\ncode = "); + scanf("%ld",&code); + printf ("\nnumber of ordered elements = "); + scanf("%d",&size); + p = codeToOrderedMultipleNat(code, size); + printf("The ordered multiple identified by code %ld contains the following elements: ", code); + printf("("); + + for(i = 0; i < (size - 1); i++){ + printf("%d, ", p[i]); + } + printf("%d)", p[size-1]); + } + while(1); +} + +void testPairInt(){ + + int x = 0; + int y = 0; + long int code = 0; + int *p; + + do{ + p = malloc(2 * sizeof(int)); + int i; + for(i = 0; i < 2; i++){ + printf("(ORDERED PAIRS INT) Enter value number %d: ", i); + scanf("%d", &p[i]); + } + + code = orderedPairToCodeInt(p[0], p[1]); + printf("\n... The code is %ld", code); + printf ("\ncode = "); + scanf("%ld",&code); + p = codeToOrderedPairInt(code); + printf("The ordered pair identified by code %ld contains the following elements: ", code); + printf("("); + + for(i = 0; i < 1; i++){ + printf("%d, ", p[i]); + } + printf("%d)\n", p[1]); + } + while(1); +} + +void testMultiInt(){ + + int x = 0; + int y = 0; + long int code = 0; + int *p; + int size = 0; + + do{ + printf("\n(INTEGERS) Enter a size of a multidimensional array representing a 'ordered multiple': "); + scanf("%d",&size); + p = malloc(size * sizeof(int)); + int i; + for(i = 0; i < size; i++){ + printf("Enter value number %d: ", i); + scanf("%d", &p[i]); + } + + code = orderedMultipleToCodeInt(p, size); + printf("\n... The code is %ld", code); + printf ("\ncode = "); + scanf("%ld",&code); + printf ("\nnumber of ordered elements = "); + scanf("%d",&size); + p = codeToOrderedMultipleInt(code, size); + printf("The ordered multiple identified by code %ld contains the following elements: ", code); + printf("("); + + for(i = 0; i < (size - 1); i++){ + printf("%d, ", p[i]); + } + printf("%d)", p[size-1]); + } + while(1); +} + +void testPairIntAlgo2(){ + + int x = 0; + int y = 0; + long int code = 0; + int *p; + + do{ + p = malloc(2 * sizeof(int)); + int i; + + for(i = 0; i < 2; i++){ + printf("(ORDERED PAIRS INT) Enter value number %d: ", i); + scanf("%d", &p[i]); + } + + code = orderedPairToCodeIntAlgo2(p[0], p[1]); + printf("\n... The code is %ld", code); + + printf ("\ncode = "); + scanf("%ld",&code); + p = codeToOrderedPairIntAlgo2(code); + printf("The ordered pair identified by code %ld contains the following elements: ", code); + printf("("); + + for(i = 0; i < 1; i++){ + printf("%d, ", p[i]); + } + printf("%d)\n", p[1]); + } + while(1); +} + + +void testMultiIntAlgo2(){ + + int x = 0; + int y = 0; + long int code = 0; + int *p; + int size = 0; + + do{ + printf("\n(INTEGERS) Enter a size of a multidimensional array representing a 'ordered multiple': "); + scanf("%d",&size); + p = malloc(size * sizeof(int)); + int i; + for(i = 0; i < size; i++){ + printf("Enter value number %d: ", i); + scanf("%d", &p[i]); + } + + code = orderedMultipleToCodeIntAlgo2(p, size); + printf("\n... The code is %ld", code); + printf ("\ncode = "); + scanf("%ld",&code); + printf ("\nnumber of ordered elements = "); + scanf("%d",&size); + p = codeToOrderedMultipleIntAlgo2(code, size); + printf("The ordered multiple identified by code %ld contains the following elements: ", code); + printf("("); + + for(i = 0; i < (size - 1); i++){ + printf("%d, ", p[i]); + } + printf("%d)", p[size-1]); + } + while(1); +} + + + + +int main(int argc, char **argv, char **envp){ + // testMultiNat(); + // testPairInt(); + // testMultiInt(); + // testPairIntAlgo2(); + testMultiIntAlgo2(); +} + diff --git a/exo4-programmes/couples.lisp b/exo4-programmes/couples.lisp new file mode 100644 index 0000000..8bedf33 --- /dev/null +++ b/exo4-programmes/couples.lisp @@ -0,0 +1,134 @@ +#| +Auteur : John CHARRON +email : charron.john@gmail.com + +Ce petit program a plein de défauts, je le sais, n'en parlons pas pour l'instant. +L'idée ici était de m'amuser, de faire des progrès en LISP, de faire une implémentation +d'une question de complexité : le programme sera amélioré par la suite (meilleurs moyens +de récupérer des données (plus efficace), etc.), il ne s'agit qu'un début. +L'idée ici est de générer des couples avec une clé : + - *current* est la liste courante (clé x y) + - *db* est la base de données, les valeurs générées sont stockées dans *db* + (inefficace, je sais, car il faudrait pour l'instant faire un parcours séquentiel pour + retrouver la donnée... j'améliorera cela par la suite, laisser pour l'instant) + - les fonctions "right" "down-left", "down", "up-right" imitent le movement des + coordonnées sur un graphe mais au les coordonnées "y" positifs sont en DESSOUS du graphe + - "move" s'occupe de choisir "right", "down-left" etc. selon les valeurs dans *current* + - Pour que "move" marche, il faut mettre à jour à chaque "move" *max-x* et *max-y* (ici à l'aide + de la fonction "update-max-x-y" + - "zig-zag" fait n "move-and-update" en un seul coup et affiche le contenu de *db* (toutes les couples) +|# + + + +;; définition des variables globales (toujours entre astérisques) +(defvar *current* (list 0 0 0)) ;; liste courante "(code x y)" +(setf *current* (list 0 0 0)) +(defvar *db* nil) ;; base de données qui stocke tous les "(code x y)" +(setf *db* nil) +(push *current* *db*) + +(defvar *max-x* 0) ;; valeur maximal courante de x +(setf *max-x* 0) +(defvar *max-y* 0) ;; valeur maximal courante de y +(setf *max-y* 0) + +#| pour remettre toutes les variables globales à leur valeurs par défaut +afin de tester, de refaire un 'zig-zag', etc. +|# +(defun reset () + (progn + (defvar *current* (list 0 0 0)) ;; liste courante (clé x y) + (setf *current* (list 0 0 0)) + (defvar *db* nil) ;; base de données qui stocke tous les "(clé x y)" + (setf *db* nil) + (push *current* *db*) + (defvar *max-x* 0) ;; valeur maximal de x jusque "là" + (setf *max-x* 0) + (defvar *max-y* 0) ;; valeur maximal de y jusque "là" + (setf *max-y* 0) + *current*)) + +#| Les fonctions "right" "down-left", "down", "up-right" imitent le movement des +coordonnées sur un graphe mais au les coordonnées "y" positifs sont en DESSOUS du graphe +|# +(defun right (L) + (progn + (push + (setf *current* + (cons (+ 1 (first L)) (cons (+ 1 (second L)) (last L)))) *db*) + *current*)) + +(defun down (L) + (progn + (push + (setf *current* + (cons (+ 1 (first L)) (cons (second L) (cons (+ 1 (third L)) ())))) *db*) + *current*)) + +(defun up-right (L) + (progn + (push + (setf *current* + (cons (+ 1 (first L)) (cons (+ 1 (second L)) (cons (- (third L) 1) ())))) *db*) + *current*)) + +(defun down-left (L) + (progn + (push + (setf *current* + (cons (+ 1 (first L)) (cons (- (second L) 1) (cons (+ 1 (third L)) ())))) *db*) + *current*)) + +(defun update-max-x (L) + (if (> (second L) *max-x*) + (setf *max-x* (second L)) + nil)) + +(defun update-max-y (L) + (if (> (third L) *max-y*) + (setf *max-y* (third L)) + nil)) + +(defun update-max-x-y (L) + (cond + ((> (second L) *max-x*) + (setf *max-x* (second L))) + ((> (third L) *max-y*) + (setf *max-y* (third L))) + (t ()))) + +;; "move" s'occupe de choisir "right", "down-left" etc. selon les valeurs dans *current* +(defun move (L) + (cond + ((and (zerop (third L)) (= *max-x* *max-y*)) ;; RIGHT takes precedence over LEFT becuase it occurs first + (print "in RIGHT") ;; + (right L)) + ((and (zerop (second L)) (= *max-x* *max-y*)) ;; DOWN + (print "in DOWN") + (down L)) + ((> *max-x* *max-y*) ;; DOWN-LEFT + (print "in DOWN-LEFT") + (down-left L)) + ((< *max-x* *max-y*) ;; UP-RIGHT + (print "in UP-RIGHT") + (up-right L)))) + +#| +On fait un "move" et puis un "update-max-x-y" +Attention : il faut bien faire un setf L, sinon, le paramètre L de "update-max-x-y utilise la valeur +de L inchangé ! +|# +(defun move-and-update (L) + (progn + (setf L (move L)) + (update-max-x-y L) + *db*)) + +;; "zig-zag" fait n "move-and-update" en un seul coup et affiche le contenu de *db* (toutes les couples) +(defun zig-zag (L n) + (if (zerop n) + (move-and-update *current*) + (progn + (move-and-update *current*) + (zig-zag L (- n 1))))) diff --git a/exo4-programmes/couples_entiers.c b/exo4-programmes/couples_entiers.c new file mode 100644 index 0000000..2b60dc9 --- /dev/null +++ b/exo4-programmes/couples_entiers.c @@ -0,0 +1,150 @@ +#include +#include +#include + +int pair(int x){ + return (!(x % 2)); +} + +int orderedPairToCode(int x, int y){ + int sumxy, code; + sumxy = x + y; + code = ((sumxy)*(sumxy + 1))/2; + + if(pair(sumxy)){ + code = code + x; + } + else{ + code = code + y; + } + return code; +} + + +int* codeToOrderedPair(int code){ + int *couple = malloc(2*sizeof(int)); + int n = sqrt(code * 2); + int axis = (n * (n + 1))/2; + int diff = 0; + if(axis > code){ + while(axis > code){ + n = n - 1; + axis = (n * (n + 1))/2; + } + } + else if(axis < code){ + while(axis < code){ + n = n + 1; + axis = (n * (n + 1))/2; + } + if(axis > code){ + n = n - 1; + axis = (n * (n + 1))/2; + } + } + + if(axis == code){ // je pense que je peux me dispenser de cet "if", ça revient au même car diff serait = 0 + if(pair(n)){ + couple[0] = 0; + couple[1] = n; + } + else{ + couple[0] = n; + couple[1] = 0; + } + } + if(axis != code){ // idem + diff = code - axis; + if(pair(n)){ + couple[0] = diff; + couple[1] = n - diff; + } + else{ + couple[0] = n - diff; + couple[1] = diff; + } + } + return couple; +} + +int orderedMultipleToCode(int *arr, int size){ + int code; + if(size > 1){ + code = orderedPairToCode(arr[size - 2], arr[size - 1]); + arr[size - 2] = code; + arr = realloc(arr, (size - 1)); + if(size > 2){ + code = orderedMultipleToCode(&arr[0], (size - 1)); + } + } + return code; +} + +int* codeToOrderedMultiple(int code, int size){ + int *multiple = malloc(size*sizeof(int)); + int *pair; + int i = 0; + for(i = 0; i < (size - 1); i++){ + pair = codeToOrderedPair(code); + code = pair[1]; + multiple[i] = pair[0]; + multiple[i + 1] = pair[1]; + } + return multiple; +} + + +int main(int argc, char **argv, char **envp){ + + int x = 0; + int y = 0; + int code = 0; + int *p; + int size = 0; + + do{ + /* + printf ("\nx = "); + scanf("%d",&x); + printf ("y = "); + scanf("%d",&y); + code = orderedPairToCode(x, y); + printf("Le code du couple (%d, %d) est %d\n", x, y, code); + + printf ("\ncode = "); + scanf("%d",&code); + p = codeToOrderedPair(code); + printf("The ordered pair identified by code %d is (%d, %d)", code, p[0], p[1]); + +*/ + printf("\nEnter a size of a multidimensional array representing a 'ordered multiple': "); + scanf("%d",&size); + p = malloc(size * sizeof(int)); + int i; + for(i = 0; i < size; i++){ + printf("Enter value number %d: ", i); + scanf("%d", &p[i]); + } + + code = orderedMultipleToCode(p, size); + printf("\n... The code is %d", code); + + + + printf ("\ncode = "); + scanf("%d",&code); + printf ("\nnumber of ordered elements = "); + scanf("%d",&size); + p = codeToOrderedMultiple(code, size); + printf("The ordered multiple identified by code %d contains the following elements: ", code); + printf("("); + for(i = 0; i < (size - 1); i++){ + printf("%d, ", p[i]); + } + printf("%d)", p[size-1]); + + + } + while(code != -1); +} +