A bit of debugging yielded the fact that the "permutations" function is
altering variables that it shouldn't.

Thanks for reporting this bug. The problem is that the Lisp SORT
function modifies its argument in-place. I've committed a 1-line patch
to Maxima cvs to copy the argument before sorting in permutations.
Here is the patch -- you can fix your copy of maxima/src/nset.lisp by
hand if you wish.

You didn't ask for my advice but here it is all the same.
(1) I don't recommend calling part in general. Maybe foo[1],
foo[2] etc works OK here.
(2) Instead of printing all the partial results, construct a list
to hold the results. This obviates printing in the loop (which
might take an appreciable fraction of the run time) and also
makes the results available for inspection afterwards.
(3) I find code with some whitespace in it easier to read.
E.g. instead of fooBar write foo_bar, and instead of
foobar(bazquux(mumble(x))) write foobar (bazquux (mumble (x)))
(put a space between function name and parenthesis).

I was investigating the following question: "In my class, there are 99
students other than me. 50 of us play soccer, 45 basketball and 50 play
volleyball. Only 15 of us play all three games. Everyone plays at least
one game. How many play only two games?"

I wrote a Maxima program, but its output was the error message, "part
fell off end".

A bit of debugging yielded the fact that the "permutations" function is
altering variables that it shouldn't. Closing and restarting Maxima
makes no difference.

In the code, the following 2 lines have been added for debugging:

if length(part(soccer,1)) = 2 then print(1)
if length(part(soccer,1)) = 2 then print(2)

The fact that when the code runs, 2 is printed before 1 seems to show
that the statement socPerm: permutations(soccerSet) is illegally
altering the value of the variable "soccer".