This page is WIP, it's usable right now but not that pretty yet.
I've been solving the problems on Project Euler and using it as a resource to teach myself Lisp. For each problem I attempt to solve it, frequently that first pass gives me insights into the problem and into Lisp to enable me to implement a more optimal solution.
Only the Lisp code is included here, no easy answers. Feel free to use it as guidance.
euler009.lisp
(defun pythagorean-triplet( total )
(loop for c from (floor total 1.5) downto 1 do
(loop for b from (floor total 3) downto 1 do
(if (= total (+ c b (sqrt (- (* c c) (* b b)))))
(format t "c is ~a b is ~a a is ~a~%" c b (sqrt (- (* c c) (* b b))))))))
euler008.lisp
(defun largest-product (digits big-number) (largest-product2 digits (list) big-number 0)) (defun largest-product2 (digits prod-list big-number max-product) (if (< (length prod-list) digits) (largest-product2 digits (append prod-list (list (car big-number))) (cdr big-number) max-product)) (if (= 0 (length big-number)) (apply '* prod-list) (largest-product2 digits (append (cdr prod-list) (list (car big-number))) (cdr big-number) (+ max-product (apply '+ prod-list))))) (defun lar (digits) (largest-product2 digits (append (rest prod-list) (list (car big-number))) (cdr big-number) (max max-product (apply '* prod-list))))
euler007.lisp
(defun add-log-trecur (n) (add-log-trecur-it n 0 0)) (defun add-log-trecur-it (n total min) (if (= min n) total (add-log-trecur-it (- n 1) (+ total (log n)) min))) (defun create-sieve (no-of-primes) (create-sieve-r (floor (add-log-trecur no-of-primes)) 0 nil)) (defun create-sieve-r (no-of-primes start list) (if (>= start no-of-primes) list (create-sieve-r (- no-of-primes 1) start (cons no-of-primes list)))) (defun find-nth (items n) "deprecated. May as well use (nth n (list))" (if (= n 0) (car items) (find-nth (cdr items) (- n 1)))) (defun find-nth-prime (n) (if (< n 2) nil (find-nth-prime-r n 2 (cdr (create-sieve (* n 1.5)))))) (defun find-nth-prime-r (n count sieve) (if (= n count) (car (cdr sieve)) (find-nth-prime-r n (+ count 1) (remove-multiples (car sieve) (cdr sieve))))) (defun remove-multiples (n sieve) (remove-if (lambda (X) (= (mod X n) 0) ) sieve)) (compile 'create-sieve-r) (compile 'add-log-trecur-it) (compile 'find-nth-prime-r)
euler006.lisp
(defun square-sum-nums (limit)
(square (sum-nums limit #'do-nothing)))
(defun sum-nums-squared (limit)
(sum-nums limit #'square))
(defun sqsums-minus-sumsqs (limit)
(- (square-sum-nums limit) (sum-nums-squared limit)))
(defun square (value)
(* value value))
(defun sum-nums (value function-to-run)
(apply '+ (loop for x from 1 to value collect (funcall function-to-run x))))
(defun do-nothing (value)
value)
(defun make-list-range (start end)
(if (> start end)
'()
(cons start (make-list-range (+ start 1) end))))euler005.lisp
(defun smallest-mult ( limit )
(do ((startNo (* limit (- limit 1)) (+ limit startNo)))
((is-divisible startNo limit) startNo)))
(defun is-divisible ( multiple divider )
(or
(and
(= divider 1)
(> multiple 1))
(and
(= 0 (rem multiple divider))
(is-divisible multiple (- divider 1)))))
(defun smallest-mult2 ( limit )
(apply 'lcm (loop for x from 1 to limit collect x)))
euler004.lisp
(defun ispalindrome ( number )
(equal (numToString number) (reverse (numToString number))))
(defun numToString( number)
(write-to-string number))
(defun findlargest1 (digits)
(let ((maxno (- (expt 10 digits) 1))(minno (- (expt 10 (- digits 1)) 1)) (largest 0))
(loop for i from maxno above minno do
(loop for j from maxno above (- i 1) do
(if (and ( < largest (* i j)) (ispalindrome (* i j))) (setq largest (* i j)))))
(return-from findlargest1 largest)))
(defun findlargest2 (digits)
(let ((maxno (- (expt 10 digits) 1))(minno (- (expt 10 (- digits 1)) 1)) (largest 0))
(loop for i from maxno above minno do
(if ( > largest (* i maxno)) (return)
(loop for j from maxno above (- i 1) do
(if (and ( < largest (* i j)) (ispalindrome (* i j))) (setq largest (* i j))))))
(return-from findlargest2 largest)))
(defun findlargest3 (digits)
(let ((maxno (- (expt 10 digits) 1))(minno (- (expt 10 (- digits 1)) 1)) (largest 0))
(loop for i from maxno above minno do
(if ( > largest (* i maxno)) (return))
(loop for j from maxno above (- i 1) do
(when (and ( < largest (* i j)) (ispalindrome (* i j)))
(setq largest (* i j)))))
(return-from findlargest3 largest)))
euler003.lisp
(defun isprime (bignumber &optional (divider 2))
(if (< (/ bignumber divider) divider)
t
(if (= 0 (rem bignumber divider))
nil
(isprime bignumber (+ divider 1)))))
(defun findFactors (number)
(sort
(loop for i from 1 to (sqrt number) append (remove nil (list
(when (= 0 (rem number i))
(/ number i))
(when (= 0 (rem number i))
i))) ) '> ))
(defun findprimefactors (num)
"Incrementing by 2 (or 1 for even numbers - only happens with 2) count until num is divisible by count. Then call itself with num / count"
(if (> num 1)
(do ((x 2 (+ x (+ 1 (mod x 2)))))
((zerop (mod num x))
(cons x (dotest (/ num x)))))))
(defun findlargestprimefactor (num)
(last (findprimefactors num)))
(defun whentest (start)
(if (> start 10)
(print start)))
(defun primfac (num)
(when (> num 1)
(do ((x 2 (1+ x)))
((zerop (mod num x))
(cons x (primfac (/ num x)))))))
euler002.lisp
(defun fibonacci (MAX &optional (PREV2 0) ( PREV1 1)) "Get a list of all even value terms. This is a bit messy in that a zero is added to the list when an odd term is met" (if (< (+ PREV2 PREV1) MAX) (cons (if (= 0 (rem (+ PREV2 PREV1) 2)) (+ PREV2 PREV1) 0)(fibonacci MAX PREV1 (+ PREV2 PREV1)) ))) (defun sum-fibonacci (LIMIT) (apply '+ (fibonacci LIMIT ))) (defun euler002 () "Find the sum of all even value terms in the fibonacci sequence not exceeding four million" ( sum-fibonacci 4000000 ))
euler001.lisp
(defun sumup (C S E)
"Add up to E in increments of C beginning at S"
(if (< (+ C S) E)
(cons (+ C S) (sumup C (+ S C) E) ) ) )
(defun euler1 (MULTIPLE1 MULTIPLE2 UPTO)
(apply '+ (union (sumup MULTIPLE1 0 UPTO) (sumup MULTIPLE2 0 UPTO))) )