Project Euler #12 in Racket
stream->list

Avoid stream-&gt;list on large lists.
In your prime? function it will create a (large)
list before passing it on to ormap.

There is a stream version of ormap - namedly stream-ormap, and
this will process the stream lazily - i.e. it will only generate
as many elements of the stream which are needed.

next-prime

Another way to eliminate the recursion here is to combine
stream-first with stream-filter and in-naturals with
your prime? predicate, e.g.:

(stream-first (stream-filter prime? (in-naturals ...) ))


Not that recursion is bad, but using streams results in
a more declarative definition.

append

I would avoid append in a Lisp or a Scheme.
I'm sure it's not efficient for use on lists.
cons, however, is always efficient, so in prime-factors you should
use:

(cons num factors)


instead of:

(append factors (list num))


You build the list in reverse order, but it won't matter
in this case.

remove-duplicates

You are also using append here which should be avoided.
The standard definition again uses cons:

(define (remove-duplicates xs)
   -- if xs is empty, return xs
   -- else return x followed by remove-duplicates on the tail elements not equal to x
     (cons (head x)
           (remove-duplicates (filter (lambda (y) (not (eq? x y))) (tail xs))))
)


For short lists this is fine - but note that its running time is O(n^2).
If you need a better one, there is one available in the standard library:
remove-duplicates in the standard library. On longer lists it uses a hash - you can view the source here: (link)

divisor-count

Honestly I had trouble understanding your prime-factors and divisor-count routines.

The conventional way of computing the number of divisors of a number n is:


find a prime divisor p of n
find the exponent e of the prime p in the factorization of n
repeat this process with n / p^e until n = 1


Then you have a list of primes and their exponents: (p1, e1), (p2, e2), etc.
and the number of divisors is:

(1+e1) * (1 + e2) * ...


How about this approach:

(define (divisor-count n)
  (apply * (map add1 (prime-exponents n))))

(define (prime-exponents n)
   -- if n == 1 return the empty list
   -- otherwise, find the first prime p dividing n
   -- find largest e s.t. p^e divides n
   -- return e and recurse on n / p^e   )


first-triangle-number

This is another place where using streams can help:


Create a stream of triangle numbers
Filter the stream keeping only those with large divisor counts
Take the first element of the stream


i.e.:

(stream-first (stream-filter ... (stream-map ... (in-naturals 1))))
                                                 \___ 1, 2, ... __/
                                 \__ 1, 3, 6, 10, ...          __/
              \___ triangular numbers having #divisors &gt;= 50  __/
\___ answer to the problem                                   __/


Note that (in-naturals 1) is an infinite stream.

for, for/list

When you get comfortable using the stream- functions, look into
Racket's sequence comprehensions: for, for/list, for/vector, etc.

See http://docs.racket-lang.org/guide/for.html for more info.