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))) )