Discussion
I hope that students will present some of the
results obtained from considering Mr. Rowland's problems. But then
...
Actually, and better than I had planned,
we spent essentially the whole time discussing matters related to
Mr. Rowland's problems. I am very happy this happened. Several people
contributed some witty observations. And I tried to record the
essentials of the discussion here. But if
students are curious what we might have discussed, read what is
below. Next week, PICTURES!
Fame! Immortality!! Power!!! money? |
Chopping up 1+2+...+n My first attempt was to look at a topic that we considered early in the course. We had found a formula for computing the sum 1+2+3+...+(n-1)+n. The result was n(n+1)/2. So I thought about this, and said that maybe sometimes we could chop up 1+2+3+...+(n-1)+n into two chunks, let's say 1+2+3+...+k and (k+1)+(k+2)+...+n, and these pieces would have equal size. A sort of illustration is shown to the right below. Then I used Maple to experiment and find some n's for which this would be true.
First, I defined the formula for the sum of the integers. These sums
are called triangular numbers. I then checked it. | |
Now I tried to detect if we could chop the triangular sum as I
mentioned. |
Or really reaching into 1+2+...+n
I didn't want to give up. Or maybe I shouldn't give up so soon. We
could look a bit more carefully into the triangular number
setup. Maybe instead of chopping so simply into two "separate"
parts, we could look instead at selecting numbers from the collection
{1,2,3,4,...,n-1,n}. So we could group them into two parts and look
for parts which have the same sum.
I looked first for some example, so that I could better understand my
own imprecise question. So consider the integers from 1 to 8:
1 2 3 4 5 6 7 8
and now "split up" these integers into two groups. So consider the
numbers 1 2 3 4 8
which have sum equal to 18, while the
other numbers, 5 6 7,
also have sum equal to 18.
I wanted to try to detect such situations. But honestly I was getting a bit scared. I am certainly not a terrific computer programmer (as you certainly know by now), and as I contemplated how to search for these "dissections" with equal sums I decided, hey, maybe it is too complicated. I wanted help so after a while I typed help(subset) and read some of the results, and looked at the command subsets, which is part of the package combinat (an abbreviation for the word "combinatorial"). There's an important lesson here, independent of this topic and even independent of the seminar. You are at the pyramid of a huge amount of human effort -- take advantage of what's been done if this is at all possible. Be clever -- you don't need to invent the wheel if someone else has already done it.
Using subsets
If you read the help page carefully, you can see that subsets actually makes a program to list the
subsets of the set. I didn't read the page very carefully. I skimmed
it and looked directly at the example given (bad habit, but it is what
I usually do). So here is a piece of computer code I "wrote" after
reading the help page for subsets, followed by the result.
> with(combinat):
> S:=subsets({frog,toad,cow}):
> while not S[finished] do S[nextvalue]() end do;
{}
{cow}
{frog}
{toad}
{frog, cow}
{toad, cow}
{frog, toad}
{frog, toad, cow}
What I try to do is look at the examples in the help message, and
maybe modify them slightly so I can pretend to understand them. More
importantly, I can use the command without understanding what's inside
it and without understanding how it is written. Of course, a critic
could declare I've changed the worry to "Why should I trust the
creators of this code?" but that sort of worry could occur each time I
step into an elevator. Here is a version of my next procedure.
> test:=proc(n) T:={seq(j,j=1..n)}; total:=add(j,j=T);print(T,total);
> S:=subsets(T); while not S[finished] do Q:=S[nextvalue]();
> A:=add(j,j=Q);if total-A=A then print(A,Q) end if end do end proc;
Warning, `T` is implicitly declared local to procedure `test`
Warning, `total` is implicitly declared local to procedure `test`
Warning, `S` is implicitly declared local to procedure `test`
Warning, `Q` is implicitly declared local to procedure `test`
Warning, `A` is implicitly declared local to procedure `test`
test := proc(n)
local T, total, S, Q, A;
T := {seq(j, j = 1 .. n)};
total := add(j, j = T);
print(T, total);
S := combinat:-subsets(T);
while not S[finished] do
Q := S[nextvalue]();
A := add(j, j = Q);
if total - A = A then print(A, Q) end if
end do
end proc
Notice that Maple cleaned up my
presentation, and declared the names I used inside the program as
local. My work almost always needs such help.
Now I tried the program twice.
> test(5);
{1, 2, 3, 4, 5}, 15
> test(8);
{1, 2, 3, 4, 5, 6, 7, 8}, 36
18, {3, 7, 8}
18, {4, 6, 8}
18, {5, 6, 7}
18, {1, 2, 7, 8}
18, {1, 3, 6, 8}
18, {1, 4, 5, 8}
18, {1, 4, 6, 7}
18, {2, 3, 5, 8}
18, {2, 3, 6, 7}
18, {2, 4, 5, 7}
18, {3, 4, 5, 6}
18, {1, 2, 3, 4, 8}
18, {1, 2, 3, 5, 7}
18, {1, 2, 4, 5, 6}
So it apparently worked! By the way, I am skipping the inevitable
typing errors and even (sigh!) a few logical errors. The program
reports there is no way of splitting the positive integers from 1 to 5
into two groups with equal sum. And there are (let's count) 7 ways of
breaking up the integers from 1 to 8 into two such groups. Notice that
the groups are counted twice. So {3, 7, 8}
appears as does what is not in it,
{1, 2, 4, 5, 6}. So I'm still trying to get into
the Integer Sequence Hall of Fame. What can I do? I could try to
create a sequence which counts these solutions.
Counting the equal-summed breakups
Here is my new procedure, exactly as I typed it, and then you can
read the "echo" by Maple, which is much
prettier and more precise. sigh
> newtest:=proc(n) local T, total, S, Q, A;
> T:={seq(j,j=1..n)}; total:=add(j,j=T); count:=0;
> S:=subsets(T); while not S[finished] do
> Q:=S[nextvalue]();A:=add(j,j=Q);
> if total-A=A then count:=count+j end if end do;
> if count>0 then print(count/2) end if end proc;
Warning, `count` is implicitly declared local to procedure `new_test`
newtest := proc(n)
local T, total, S, Q, A, count;
T := {seq(j, j = 1 .. n)};
total := add(j, j = T);
count := 0;
S := combinat:-subsets(T);
while not S[finished] do
Q := S[nextvalue]();
A := add(j, j = Q);
if total - A = A then count := count + 1 end if
end do;
if 0 < count then print(count/2) end if
end proc
I had to change print(count) in the
original version to print(count/2) if I
just wanted to know the number of distinct solutions, since (as we
saw) this double counts solutions.
Look:> newtest(8);
7
The running time of this sort of program tends to increase very
rapidly with n, because the number of subsets of {1,2,3,...,n} is
2n. For example, newtest(20) returns the number 7636 on my
home PC, but takes about 50 seconds. The time is needed because
220 is 1,048,576 which is large if some checking needs to
be done at each instance. I tried
>seq(newtest(j),j=1..15);
1
1
4
7
35
62
361
and I looked up this sequence in the Encyclopedia. The result
was A124624,
which was described as "Erroneous version of A058377." The word
"erroneous" was interesting, and the reference to another sequence was
more interesting.
A058377
is described as "Number of solutions to 1+-2+-3+-...+-n=0." That is,
how many ways are there to put + and - signs in front of
1 2 3 ... n-1 n
and end up with 0 (starting with a + in front of the 1). If you think
about it a bit, this is exactly the problem we're doing. The +'s put
the numbers in one subset, and the -'s put them in another. The result
is 0 exactly when the two sets have equal sums.
New uses?
I still wanted to get ways for people to find interesting new
sequences. First, I cleaned up the program a bit so it would produce
0's where Sloane wanted them.
newtestB := proc(n)
local T, total, S, Q, A, count;
T := {seq(j, j = 1 .. n)};
total := add(j, j = T);
count := 0;
S := combinat:-subsets(T);
while not S[finished] do
Q := S[nextvalue]();
A := add(j, j = Q);
if total - A = A then count := count + 1 end if
end do;
count/2
end proc;
and tried it. The result is below and it is exactly as A058377 is
presented.
> seq(newtestB(j),j=1..15);
0, 0, 1, 1, 0, 0, 4, 7, 0, 0, 35, 62, 0, 0, 361
When the procedure ends with the line count/2 the value of that quantity is printed.
Splitting up the squares
We can easily check for splittings of the squares with a small change.
newtestC := proc(n)
local T, total, S, Q, A, count;
T := {seq(j^2, j = 1 .. n)};
total := add(j, j = T);
count := 0;
S := combinat:-subsets(T);
while not S[finished] do
Q := S[nextvalue]();
A := add(j, j = Q);
if total - A = A then count := count + 1 end if
end do;
count/2
end proc;
I tried it and got
> seq(newtestC(j),j=1..20);
0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 5, 0, 0, 43, 57, 0, 0, 239, 430
This took a while to run on my home PC, and the result is the
beginning of A083527. By
the way, I hope that students will notice some structure in these sequences --
there are non-zero chunks separated by pools (?) of 0's. What is going on?
When we try cubes and fourth powers, we don't seem to have "collisions". These sequences seem to increase too quickly. By the way, the craziness we are currently discussing, which seems totally unreal and silly, turns out to be closely related to the knapsack problem: how to package "objects" of different sizes. The problem arises in many strange ways and is very important computationally.
We could try even integers, but that would be silly (why?) but how
about odd integers? This won't be much additional work. We only need
to change the instruction T := {seq(j^2, j = 1 .. n)};.
If we replace j^2 by 2*j+1, we will be splitting the odd
integers into two pieces and counting the pieces which have equal
sums. Here is the result:
0, 0, 0, 1, 0, 1, 0, 4, 0, 9, 0, 31, 0, 94, 0, 319
I always worry if these things really work. The first 1 is in the fourth place, where we would
consider the first four odd numbers,
1 3 5 7. Notice
that 3+5=1+7, so, yes, the result checks there. This sequence
does not seem to be in the Encyclopedia! Neither is the
result for
3*j+2, which starts
0, 0, 0, 1, 0, 0, 0, 4, 0, 0, 5, 29, 0, 0, 78, 264
and for
5*j+3, which starts
0, 0, 0, 1, 0, 0, 0, 4, 0, 0, 0, 29, 0, 0, 0, 263
Again, probably more interesting is understanding the zeros and why they are there. But that will involve some thinking so I invite students to do it, while I discuss silly computer pursuits.
Splitting three ways
We could try to group the elements of {1,2,3,4,...,n-1,n} into
three chunks which have equal sums. There's more effort
involved. I needed to learn a new instruction, minus, which takes elements of one set away
from another set.
> {frog,toad,cow,elephant} minus {elephant,tiger};
{cow, frog, toad}
Then I needed to look at subsets of certain subsets! Things are
getting a bit crazy. What's below finds and counts the number of times
the elements of {1,2,3,4,...,n-1,n} can be broken into three parts
with equal sums.
newtestD := proc(n)
local T, total, S, Q, A, count, R, S1, Q1, A1;
T := {seq(j, j = 1 .. n)};
total := add(j, j = T);
count := 0;
S := combinat:-subsets(T);
while not S[finished] do
Q := S[nextvalue]();
A := add(j, j = Q);
if total/3 = A then
R:=T minus Q;
S1:=subsets(R);
while not S1[finished] do
Q1:=S1[nextvalue]();
A1:=add(j,j=Q1);
if total/3=A1 then count := count + 1 end if
end do;
end if
end do;
count/6
end proc;
The only slightly amusing thing is the division by 6 in the last
instruction. That's needed because this remarkably inefficient
procedure counts each satisfactory splitting 6 times (just as we
counted the splitups into two pieces twice, because each element of
each pair was counted in both positions. Here there are three
positions, and six possible ways to count.
Here are the first twelve answers.
0, 0, 0, 0, 1, 1, 0, 3, 9, 0, 43, 102
and this is A112972.
Maybe it is time to give up!
With squares, the first non-zero entry is the thirteenth.
We could split up odd numbers into three parts with equal sums. Here
is a count of how often that's successful:
0, 0, 0, 0, 0, 1, 0, 0, 2, 4, 0, 32, 41, 0, 332, 822
This isn't
in the Encyclopedia! What
wonderful, insane joy! Send it in now!!!
Seminar "assignment"
Put a sequence of your own in the Encyclopedia.
You can use one of these if you like.
Next time will be much more relaxed. We will draw some pretty pictures. Maybe the most interesting (?) sequence I found during the browsing which occurred as I prepared this material was A035470, which has description "Number of ways to break {1,2,3,...n} into sets with equal sums." There must (?) be something useful about that sequence.
Maintained by greenfie@math.rutgers.edu and last modified 10/26/2008.