September 30, 2008

Chapter: Generics

Create and test a SixTuple generic.


In Java:

package chapter.generics;

class SixTuple<A, B, C, D, E, F> {
public final A a;
public final B b;
public final C c;
public final D d;
public final E e;
public final F f;

public SixTuple(A a, B b, C c, D d, E e, F f) {
this.a = a;
this.b = b;
this.c = c;
this.d = d;
this.e = e;
this.f = f;
}
}

public class Exercise3 {

static SixTuple<Integer, String, Double, Boolean, String, Integer> foo() {
return new SixTuple<Integer, String, Double, Boolean, String, Integer>(
5, "hi", 33.3, true, "bye", 100);
}

public static void main(String[] args) {
SixTuple<Integer, String, Double, Boolean, String, Integer> x = foo();
System.out.println(x.b);
System.out.println(x.a);
System.out.println(x.e);

}

}


Lisp can return values in many natural and easy ways, including lists and the values function. Since a lisp programmer would probably avoid creating a special tuple class just to return multiple values, here is an alternative and simple way to accomplish the feat:
(defun foo ()
(values 5 "hi" 33.3 t "bye" 100))

(multiple-value-bind (a b c d e f) (foo)
(print b)
(print a)
(print e))

September 7, 2008

2520 is the smallest number that can be divided by each of the numbers from 1 to 10 without any remainder.

What is the smallest number that is evenly divisible by all of the numbers from 1 to 20?


Here is a quick and simple solution in Common Lisp:

(defun simple-euler-5 ()
(lcm 11 12 13 14 15 16 17 18 19 20))


However, coding our own solution isn't too difficult. Using Euclid's algorithm for the greatest common divisor, here is another solution is Common Lisp:

(defun range (start end)
"Generates a list of integers from start to end"
(loop for i from start to end collect i))

(defun my-lcm (lst)
(let ((result 1))
(dolist (n lst)
(setq result (/ (* result n) (gcd result n))))
result))

(defun euler-5 ()
(my-lcm (range 11 20)))

A palindromic number reads the same both ways. The largest palindrome made from the product of two 2-digit numbers is 9009 = 91 99.

Find the largest palindrome made from the product of two 3-digit numbers.


Here is my solution in Common Lisp:

(defun 3-digit-divisors (num)
(do ((i (isqrt num) (- i 1)))
((or (and (zerop (mod num i))
(= 3 (length (write-to-string i))
(length (write-to-string (/ num i)))))
(eq i 99))
(cond ((= i 99) nil)
(t (list i (/ num i)))))))

(defun palindrome? (num)
(let ((x (write-to-string num)))
(if (equalp x (reverse x))
t
nil)))

(defun problem-4 ()
(do ((i 998899 (- i 1)))
((or (and (palindrome? i)
(3-digit-divisors i))
(< i 1))
(list i (3-digit-divisors i)))))


2-digit-divisors takes a number and returns a list of its largest three-digit divisors if it has any or nil. palindrom? tests to see if a number is a palindrome by comparing the number to the reverse of the number. The solution is calculated by starting with the largest six digit palindrome and testing for the conditions.

Of course, problem-4 can be tweaked for better performance by looping for every palindrome rather than decrementing by one.