My answer to Project Euler problem 4 (largest palindrome of product of two 3-digit numbers) is below.
Please suggest improvements, style changes, indentation, commenting, naming, ...
And nitpicks are welcome!
Other than general stuff about the code below, I'd like to ask specifically about
assertis good to use? Frowned upon? Has possible drawbacks?
prognlooks like a 2nd class construct. Is the usage in the final function correct? Are there other (more Lispy-like) options?
(defun e004-digits (n &optional (base 10)) "return a list with the digits of n" (assert (and (integerp n) (>= n 1) (integerp base) (>= base 2))) (loop with remainder while (> n 0) do (setf (values n remainder) (floor n base)) collect remainder)) (defun e004-palindrome6p (n6) "determine if the 6-digit number n6 is a palindrome (in base 10)" (assert (and (integerp n6) (>= n6 100000) (<= n6 999999))) (let ((dd (e004-digits n6))) (and (= (nth 2 dd) (nth 3 dd)) (= (nth 1 dd) (nth 4 dd)) (= (nth 0 dd) (nth 5 dd))))) (defun e004-largest-palindrome-in-square (siz) "find maximum palindrome product" (do* ((a siz) (b siz) (nextb) (sum (+ siz siz)) (p (* a b) (* a b))) ((e004-palindrome6p p) p) ;; following half diagonals ensures (proof needed?) ;; the first palindrome product found is the largest (setf a (+ a 1)) (setf b (- b 1)) (if (> a siz) ; start next diagonal (progn (setf (values a nextb) (floor sum 2)) (setf b (+ a nextb -1)) (setf sum (- sum 1)))))) (defun e004 () (e004-largest-palindrome-in-square 999))
code also available on github