;(fuel-construct '((1 0 ; 0 0) ; (0 0 ; 0 0))) ;(construct-car '(((0 0) 0 (1 0)) ; ((1 0) 0 (0)))) (defun solve-section (section fuel air) (let ((matrix (elt fuel section))) (unless matrix (error "nav degvielas")) (mapcar (lambda (x) (declare (ignore x)) (let ((sub-result 0)) (dolist (i air sub-result) (incf sub-result (* i (first matrix))) (setf matrix (rest matrix))))) air))) (defun solve-pipe (pipe fuel air) (if (null pipe) air (solve-pipe (rest pipe) fuel (solve-section (first pipe) fuel air)))) (defun get-upper-pipe (chamber) (first chamber)) (defun get-lower-pipe (chamber) (third chamber)) (defun solve-chamber (chamber fuel air) (mapcar #'- (solve-pipe (get-upper-pipe chamber) fuel (copy-list air)) (solve-pipe (get-lower-pipe chamber) fuel (copy-list air)))) (defun get-fuel-dimension (fuel) (floor (sqrt (+ (length (first fuel)) 0.1)))) (defun extend-air (air size) (assert (<= (length air) size)) (append air (make-list (max 0 (- size (length air))) :initial-element 1))) (defun solver (car fuel &key air) (setf air (extend-air air (get-fuel-dimension fuel))) (mapcar (lambda (chamber) (solve-chamber chamber fuel air)) car)) (defun some-car () (deconstruct-car "2202211001011022110101011221101010111022110101111")) (defun some-tank (rank) (let* ((empty (make-list (* rank rank) :initial-element 0))) (dotimes (i rank) (setf (elt empty (+ i (* i rank))) 1)) (setf (first empty) 2) empty)) (defun some-fuel (&optional (tank-count 6)) (let (fuel) (dotimes (i tank-count fuel) (push (some-tank (1+ tank-count)) fuel)))) (defun chamber-goodness (chamber) (reduce #'+ (remove-if (lambda (x) (> x 0)) chamber))) (defun old-goodness (diff) (let ((goodness (mapcar #'chamber-goodness diff))) (reduce #'+ (or goodness (mapcar (lambda (x) (reduce #'+ x)) diff))))) (defun min-goodness (diff) (apply #'min (mapcar (lambda (x) (apply #'min x)) diff))) (defun goodness (diff) (min-goodness diff)) (defun mutate (fuel) (let* ((tank (elt fuel (random (length fuel)))) (victim (random (length tank)))) (case (random 2) (0 (incf (elt tank victim))) (1 (setf (elt tank victim) (max (if (= 0 victim) 2 0) (1- (elt tank victim))))))) fuel) (defun multiple-mutate (fuel) (dotimes (i 1 fuel) ; (1+ (random 2)) fuel) (mutate fuel))) (defun print-solution (solution) (mapc (lambda (x) (format t "~A~%" x)) solution)) (defun random-air (size) (mapcar (lambda (x) (random x)) (make-list size :initial-element 100))) (defun munch (car fuel &key air (iterations 1000)) (let ((old-solution (solver car fuel :air air)) (fuel-dimension (get-fuel-dimension fuel))) (dotimes (i iterations (progn (print-solution old-solution) fuel)) ;(setf air (random-air fuel-dimension)) (let* ((new-fuel (multiple-mutate (copy-tree fuel))) (new-solution (solver car new-fuel :air air)) (old-goodness (goodness old-solution))) (when (>= (goodness new-solution) old-goodness) (setf old-solution new-solution) (setf fuel new-fuel)))))) (defun random-pipe (sections) (append '(0 1 2 3 4 5) (mapcar (lambda (x) (random x)) (make-list sections :initial-element 6)))) (defun random-chamber (sections) (list (random-pipe sections) 0 (random-pipe sections))) (defun car-generator (chambers sections) (mapcar (lambda (x) (declare (ignore x)) (random-chamber (incf sections))) (make-list chambers)))