Advertisement
Guest User

Untitled

a guest
May 22nd, 2020
107
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lisp 3.53 KB | None | 0 0
  1. (defmacro palinfun (name parameters &body body)
  2.   `(defun ,name (sequence ,@parameters)
  3.      (let* ((len (length sequence)) (anti-midlen (antibelt sequence (floor len 2))) (midlen (floor len 2)) (midsequence (/ len 2)))
  4.        (declare (ignorable midlen anti-midlen midsequence))
  5.        ,@body)))
  6.      
  7. (palinfun lrbelt (belt)
  8.   ;;Returns 0 (left) 1 (right) or 2 (mid) for position of belt in sequence
  9.   (when (> belt (1- len)) (return-from lrbelt nil))
  10.   (when (and (oddp len) (= belt midlen)) (return-from lrbelt 2))
  11.   (when (and (evenp len) (= belt midlen) (return-from lrbelt 1)))
  12.   (when (< belt midsequence) (return-from lrbelt 0))
  13.   (when (> belt midsequence) (return-from lrbelt 1)))
  14.        
  15. (palinfun antibelt (belt)
  16. ;;;Returns the corresponding belt across the midline of sequence
  17.   (let ((zblen (- len 1)))
  18.     (- zblen belt)))
  19.  
  20. (palinfun belt (elt)
  21. ;;;A balanced version of elt
  22. (when (> elt (- len 1)) (return-from belt nil))
  23. (cons (elt sequence elt) (elt (reverse sequence) elt)))
  24.  
  25.  
  26. (palinfun bset (belt newval)
  27. ;;;Outputs a copy of sequence with belt and antibelt set to newval
  28. (let ((leftbelt (if (zerop (lrbelt sequence belt)) (values 1) (values nil)))
  29.       (midbelt (if (= (lrbelt sequence belt) 2) (values 1) (values nil))) (antibelt (antibelt sequence belt)))
  30.   (when (> belt (1- len)) (return-from bset nil))
  31.   (let ((rightbelt (if (and (not leftbelt) (not midbelt)) (values 1) (values nil))))
  32.     (cond (midbelt
  33.        (concatenate 'string (subseq sequence 0 belt) newval (subseq sequence (1+ belt) len)))
  34.       (leftbelt
  35.        (concatenate 'string (subseq sequence 0 belt) newval (subseq sequence (1+ belt) antibelt) newval (subseq sequence (1+ antibelt) len)))
  36.       (rightbelt
  37.        (concatenate 'string (subseq sequence 0 antibelt) newval (subseq sequence (1+ antibelt) belt) newval (subseq sequence (1+ belt) len)))))))
  38.  
  39. (palinfun palindromep ()
  40. ;;;Palindrome predicate
  41.   (loop for n from 0 upto anti-midlen do
  42.     (let ((belt (belt sequence n)))
  43.       (let ((left (car belt)) (right (cdr belt)))
  44.     (when (not (equal left right)) (return-from palindromep nil))))
  45.     finally (return-from palindromep 1)))
  46.  
  47. (palinfun palindrominc ()
  48. ;;;Increments palindrome to next palindrome
  49.       (when (not (equal 9 (parse-integer (string (elt sequence anti-midlen))))) (return-from palindrominc (bset sequence anti-midlen (write-to-string (1+ (parse-integer (string (elt sequence anti-midlen))))))))
  50.       (loop for belt from (1- anti-midlen) downto 0 do
  51.     (when (not (equal 9 (parse-integer (string (elt sequence belt))))) (return-from palindrominc (bset sequence belt (write-to-string (1+ (parse-integer (string (elt sequence belt))))))))
  52.         finally (return-from palindrominc (write-to-string (1+ (expt 10 len))))))
  53.        
  54. (palinfun right-balance ()
  55. ;;;Balance right digits with left digits
  56.   (loop for belt from (1- len) downto midlen with newsequence = sequence do
  57.     (when (< (parse-integer (string (elt newsequence belt))) (parse-integer (string (elt newsequence (antibelt newsequence belt)))))
  58.       (setf newsequence (bset newsequence belt (string (elt newsequence (antibelt newsequence belt))))))
  59.     finally (return newsequence)))
  60.  
  61. (palinfun next-palindrome ()
  62. ;;;Balance left digits with right digits
  63.       (loop for belt from anti-midlen downto 0 with newsequence = sequence do
  64.     (when (< (parse-integer (string (elt newsequence belt))) (parse-integer (string (elt newsequence (antibelt newsequence belt)))))
  65.       (setf newsequence (bset newsequence belt (string (elt newsequence (antibelt newsequence belt))))))
  66.     finally (return newsequence)))
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement