aboutsummaryrefslogtreecommitdiff
path: root/hidden/2018-02-10-j-pascal.md
diff options
context:
space:
mode:
authorFuwn <[email protected]>2020-11-06 18:24:26 -0800
committerFuwn <[email protected]>2020-11-06 18:24:26 -0800
commit9cdce4254700691301608c6f1d3081950023cc4f (patch)
tree9d24529acc19b354f80cb2d610aa1e7686f4d530 /hidden/2018-02-10-j-pascal.md
downloadblog-9cdce4254700691301608c6f1d3081950023cc4f.tar.xz
blog-9cdce4254700691301608c6f1d3081950023cc4f.zip
repo: initial :star:
Diffstat (limited to 'hidden/2018-02-10-j-pascal.md')
-rw-r--r--hidden/2018-02-10-j-pascal.md279
1 files changed, 279 insertions, 0 deletions
diff --git a/hidden/2018-02-10-j-pascal.md b/hidden/2018-02-10-j-pascal.md
new file mode 100644
index 0000000..551a7b0
--- /dev/null
+++ b/hidden/2018-02-10-j-pascal.md
@@ -0,0 +1,279 @@
+---
+title: Hello, J! Pascal's Triangle
+route: /j-pascal
+date: 2018-02-10
+description:
+---
+
+Following [my previous post on the Fibonacci numbers](/j-fibonacci), here's a quick post on generating another famous mathematical sequence - [Pascal's Triangle](https://en.wikipedia.org/wiki/Pascal%27s_triangle).
+
+```
+ 1
+ 1 1
+ 1 2 1
+ 1 3 3 1
+1 4 6 4 1
+```
+
+## Quick Background
+
+Pascal's triangle contains numbers formed by binomial coefficients (often referred to as "N choose K"), but there's a simple and elegant way to generate it: **each item is the sum of the two numbers above it**.
+
+<pre>
+ 1 <span style="border:1px solid black">3 3</span> 1
+1 4 <u>6</u> 4 1
+</pre>
+
+We see here that the underlined 6 is formed by adding the two threes above it.
+
+<pre>
+ <span style="border:1px solid black">1 3</span> 3 <span style="border:1px solid black">1 </span>
+1 <u>4</u> 6 4 <u>1</u>
+</pre>
+
+Similarly, we see the 4 is formed by adding the 1 and 3, and the 1 is formed by adding 1 to nothing (0).
+
+## Summing pairs
+
+Before we get started go ahead and [grab yourself a copy of the J runtime](http://code.jsoftware.com/wiki/System/Installation/All-in-One) if you haven't already.
+
+Let's start by grabbing the first 5 integers using the ["integers" verb `i.`](http://www.jsoftware.com/help/dictionary/didot.htm)
+
+```
+ i. 5
+0 1 2 3 4
+```
+
+We can use the ["same" verb `]`](http://www.jsoftware.com/help/dictionary/d500.htm) to echo whatever we pass into it.
+
+```
+ ] 10
+10
+ ] i.5
+0 1 2 3 4
+```
+
+Our primary tool will be J's [infix adverb `\`](http://www.jsoftware.com/help/dictionary/d430.htm). This single backslash allows us to scan through a list of numbers in groups and apply a function to them.
+
+Let's scan every 3 items and pass them to the "same" verb `]`.
+
+```
+ 3 ]\ i.5
+0 1 2
+1 2 3
+2 3 4
+```
+
+We can see here that J looks through `0 1 2 3 4` in overlapping groups of 3. So we'll have `0 1 2`, followed by `1 2 3`, etc.
+
+By changing the number in front, we can scan in groups of 2.
+
+```
+ 2 ]\ i.5
+0 1
+1 2
+2 3
+3 4
+```
+
+Let's swap out our boring `]` for something more interesting: `+/`, which sums a list of numbers.
+
+```
+ 3 +/\ i.5
+3 6 9
+ +/ 0 1 2
+3
+ +/ 1 2 3
+6
+ +/ 2 3 4
+9
+```
+
+Similarly, we can do this pairwise.
+
+```
+ 2 +/\ i.5
+1 3 5 7
+```
+
+Pretty nifty right?
+
+## Row after row
+
+So why is this useful? Well, if we take another look at our triangle:
+
+```
+ 1
+ 1 1
+ 1 2 1
+ 1 3 3 1
+1 4 6 4 1
+```
+
+We can see that the next row, `1 5 10 10 5 1` can be formed by this exact strategy: summing each pair of numbers to generate the number beneath it.
+
+```
+ 2 +/\ 1 3 3 1
+4 6 4
+ 2 +/\ 1 4 6 4 1
+5 10 10 5
+```
+
+Well, almost. Our issue is that we're missing out on the 1s on either side! This is because our infix operator `\` starts with `+/ 1 4` to get 5 - skipping over the 1.
+
+To fix this, let's surround our row with 0s.
+
+```
+ 2 ]\ 0 1 3 3 1 0
+0 1
+1 3
+3 3
+3 1
+1 0
+ 2 +/\ 0 1 3 3 1 0
+1 4 6 4 1
+ 2 +/\ 0 1 4 6 4 1 0
+1 5 10 10 5 1
+```
+
+Much better. So how do we surround with 0s automatically?
+
+The [append verb `,`](http://www.jsoftware.com/help/dictionary/d320.htm) is used to join items and lists.
+
+```
+ 0 , 1
+0 1
+ 1 2 3 , 7 8 9
+1 2 3 7 8 9
+```
+
+The ["bond" verb `&`](http://www.jsoftware.com/help/dictionary/d630n.htm) allows us to partially evaluate a verb that normally expects items on both sides.
+
+```
+ 1 + 2
+3
+ (1&+) 2
+3
+ 4 % 2 NB. "%" is division!
+2
+ (%&2) 4
+2
+```
+
+We can bind our append verb to add a 0 to either side.
+
+```
+ (0&,) 5 6 7
+0 5 6 7
+ (,&0) 5 6 7
+5 6 7 0
+```
+
+We can also do both.
+
+```
+ (0&,) (,&0) 5 6 7
+0 5 6 7 0
+ (,&0) (0&,) 5 6 7
+0 5 6 7 0
+```
+
+Putting it all together: we can append 0 on either side of our row:
+
+```
+ (0&,) (,&0) 1 4 6 4 1
+0 1 4 6 4 1 0
+```
+
+And sum each pair:
+
+```
+ 2 +/\ (0&,) (,&0) 1 4 6 4 1
+1 5 10 10 5 1
+```
+
+## All together now
+
+Let's wrap this in our own verb called `next`. "`y`" gives us access to the argument(s) passed in.
+
+```
+ next =: verb : '2 +/\ (0&,) (,&0) y'
+ next 1 3 3 1
+1 4 6 4 1
+ next 1 4 6 4 1
+1 5 10 10 5 1
+```
+
+Fortunately, `next` works just fine on the first row of our triangle: a single `1`.
+
+```
+ next 1
+1 1
+```
+
+We can apply `next` multiple times.
+
+```
+ next 1
+1 1
+ next 1 1
+1 2 1
+ next next 1
+1 2 1
+ next next next next 1
+1 4 6 4 1
+```
+
+We can use the ["power" verb `^:`](http://www.jsoftware.com/help/dictionary/d202n.htm) to do this for us.
+
+```
+ (next^:0) 1
+1
+ (next^:1) 1
+1 1
+ (next^:5) 1
+1 5 10 10 5 1
+```
+
+We can also pass a list to `^:` to generate multiple powers at the same time.
+
+```
+ (next^:(i.7)) 1
+1 0 0 0 0 0 0
+1 1 0 0 0 0 0
+1 2 1 0 0 0 0
+1 3 3 1 0 0 0
+1 4 6 4 1 0 0
+1 5 10 10 5 1 0
+1 6 15 20 15 6 1
+```
+
+We can store this as another verb to generate Pascal's Triangle. We’ll also simplify our definition of next using the ["atop" verb `@`](http://www.jsoftware.com/help/dictionary/d620.htm).
+
+```
+ next =: 2 +/\ (0&,) @ (,&0)
+ pascal =: verb : '(next^:(i.y)) 1'
+ NB. We can also inline `next` entirely
+ pascal =: verb : '((2 +/\ (0&,) @ (,&0))^:(i.y)) 1'
+ pascal 10
+1 0 0 0 0 0 0 0 0 0
+1 1 0 0 0 0 0 0 0 0
+1 2 1 0 0 0 0 0 0 0
+1 3 3 1 0 0 0 0 0 0
+1 4 6 4 1 0 0 0 0 0
+1 5 10 10 5 1 0 0 0 0
+1 6 15 20 15 6 1 0 0 0
+1 7 21 35 35 21 7 1 0 0
+1 8 28 56 70 56 28 8 1 0
+1 9 36 84 126 126 84 36 9 1
+```
+
+🎉 🎉
+
+Thanks to the powers of `\` and `^:`, we can intuitively generate Pascal's Triangle in a few dozen characters.
+
+J makes operations on lists and matrices a breeze, and contains a number of interesting ideas for function composition and application. I hope you found this post interesting and give a look at what J has to offer.
+
+I think you'll be pleasantly surprised at how fun it is.
+
+Thanks for reading!