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. > formula:=n->n*(n+1)/2; formula := n -> 1/2 n (n + 1) > formula(6);add(j,j=1..6); 21 21 | |
Now I tried to detect if we could chop the triangular sum as I mentioned. chop := proc(n) local k; for k to n do if formula(k) = 1/2*formula(n) then print(n) end if end do end procThis command would print n if the sum could be "chopped" as I indicated, and otherwise it would print nothing. And then I ran the command seq(chop(j),j=1..10000);. The results slowly trickled out. They were 3 20 119 696 4059 |
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 procNotice 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 procI 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); 7The 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 2^{n}. For example, newtest(20) returns the number 7636 on my home PC, but takes about 50 seconds. The time is needed because 2^{20} 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 361and 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, 361When 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, 430This 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, 319I 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, 264and 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, 102and 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, 822This 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.