There seems to be two basic approaches to this problem:
1. Generate the even numbers between 1 & 42, and add them up.
2. Use the formula for the sum of an arithmetic progression - e.g.:
Sum=n(a+b)/2
*n* = number of numbers in the sequence (here 21)
*a* = the first number in the sequence (here 2)
*b* = the last number in the sequence (here 42)
Generally, I like to approach these kinds of Quora sequence problems using
a "brute force" approach, and ignore simplifying formulas. In the days
before modern computers, formulas were developed to make computations on
sequences like this Quora problem more tractable, particularly when the
number of terms got large.
Today, with powerful modern computers and languages, it is often easier to
simply generate a sequence in it's entirety, and then compute some property
of that sequence such as it's limit, sum, etc. to get the final result.
This is particularly true when you have at your fingertips a powerful
matrix language such as APL or J.
For me, the obvious approach to this problem is to simply generate the
sequence of even integers and then sum them, instead of trying to find a
formula that relates to that specific sequence (in any case, I didn't have
a clue where to look for such formulas).
So the plan was: Generate the numbers from 0 to 42, throw out the odd
numbers (zero doesn't matter in this problem), and then add up what's left:
a =:i.43
+/(-.2|a)#a
462
My main dissatisfaction was that I was sure that this could be done in a
single line, but I didn't know how to get the integer sequence on both
sides of the tally/copy verb, which i wanted to use as a binary selector
mask.
Yes, thanks to Raul and others, I now realize that I could have just
multiplied the first 21 integers by 2 to get all the even integers and then
sum them, but I wanted to learn how to get the same vector of integers in
two places in the formula without having to assign that vector to a
variable.
Raul showed me how to do that, though he used equality & multiplication to
generate the selector mask and make the selections.
+/(*0=2&|)i.43
462
Raul's multiply by zero trick was cool, but my purist sensibilities still
wanted to use selection of the even numbers as the most straightforward way
to implement the sum of evens.
However, Raul's approach did show me the way. I could use the copy operator
to implement the selector mask, instead of multiplication
+/(#0=2&|)i.43
462
That worked, So we should also be able to get the sum of the odd numbers:
+/(#2&|)i.43
441
Yep. That worked too. So i should also be able use the NOT verb ".-" to
invert the selection mask to get the sum of evens like I did in my original
attempt:
+/(#-.2&|)i.43
43
AAAAK! What happened? I tried to negate the selection mask, and something
went terribly wrong! Maybe I need to isolate the negation:
+/(#(-.2&|))i.43
|length error
| +/ (#(-.2&|))i.43
Nope! What am I doing wrong? How can I simply negate the selection mask,
just like I did in my original explicit example?
Skip Cave
----------------------------------------------------------------------
For information about J forums see http://www.jsoftware.com/forums.htm