diff --git a/index.ipynb b/index.ipynb index 666b0ab..2d74fca 100644 --- a/index.ipynb +++ b/index.ipynb @@ -337,6 +337,199 @@ "np.array(a)" ] }, + { + "cell_type": "markdown", + "id": "90ad8377", + "metadata": {}, + "source": [ + "### Example algorithms" + ] + }, + { + "cell_type": "markdown", + "id": "d0660108", + "metadata": {}, + "source": [ + "The fibonacci sequence:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "77cc837d", + "metadata": {}, + "outputs": [ + { + "data": { + "application/javascript": [ + "; (_ => {\n", + "\tlet hc = { '<': '<', '&': '&', \"'\": ''', '\"': '"' }, he = x => x.replace(/[<&'\"]/g, c => hc[c]) //html chars and escape fn\n", + "\t\t, tcs = '<-←xx×/\\\\×:-÷*O⍟[-⌹-]⌹OO○77⌈FF⌈ll⌊LL⌊T_⌶II⌶|_⊥TT⊤-|⊣|-⊢=/≠L-≠<=≤<_≤>=≥>_≥==≡=_≡7=≢Z-≢vv∨^^∧^~⍲v~⍱^|↑v|↓((⊂cc⊂(_⊆c_⊆))⊃[|⌷|]⌷A|⍋V|⍒ii⍳i_⍸ee∊e_⍷' +\n", + "\t\t\t'uu∪UU∪nn∩/-⌿\\\\-⍀,-⍪rr⍴pp⍴O|⌽O-⊖O\\\\⍉::¨\"\"¨~:⍨~\"⍨*:⍣*\"⍣oo∘o:⍤o\"⍤O:⍥O\"⍥[\\'⍞\\']⍞[]⎕[:⍠:]⍠[=⌸=]⌸[<⌺>]⌺o_⍎oT⍕o-⍕<>⋄^v⋄on⍝->→aa⍺ww⍵VV∇v-∇--¯0~⍬' +\n", + "\t\t\t'AA∆^-∆A_⍙^=⍙[?⍰?]⍰:V⍢∇\"⍢||∥ox¤)_⊇_)⊇V~⍫\\'\\'`'\n", + "\t\t, lbs = ['←←\\nASSIGN', ' ', '++\\nconjugate\\nplus', '--\\nnegate\\nminus', '××\\ndirection\\ntimes', '÷÷\\nreciprocal\\ndivide', '**\\nexponential\\npower', '⍟⍟\\nnatural logarithm\\nlogarithm',\n", + "\t\t\t'⌹⌹\\nmatrix inverse\\nmatrix divide', '○○\\npi times\\ncircular', '!!\\nfactorial\\nbinomial', '??\\nroll\\ndeal', ' ', '||\\nmagnitude\\nresidue',\n", + "\t\t\t'⌈⌈\\nceiling\\nmaximum', '⌊⌊\\nfloor\\nminimum', '⊥⊥\\ndecode', '⊤⊤\\nencode', '⊣⊣\\nsame\\nleft', '⊢⊢\\nsame\\nright', ' ', '==\\nequal', '≠≠\\nunique mask\\nnot equal',\n", + "\t\t\t'≤≤\\nless than or equal to', '<<\\nless than', '>>\\ngreater than', '≥≥\\ngreater than or equal to', '≡≡\\ndepth\\nmatch', '≢≢\\ntally\\nnot match', ' ', '∨∨\\ngreatest common divisor/or',\n", + "\t\t\t'∧∧\\nlowest common multiple/and', '⍲⍲\\nnand', '⍱⍱\\nnor', ' ', '↑↑\\nmix\\ntake', '↓↓\\nsplit\\ndrop', '⊂⊂\\nenclose\\npartioned enclose', '⊃⊃\\nfirst\\npick', '⊆⊆\\nnest\\npartition', '⌷⌷\\nmaterialise\\nindex', '⍋⍋\\ngrade up\\ngrades up',\n", + "\t\t\t'⍒⍒\\ngrade down\\ngrades down', ' ', '⍳⍳\\nindices\\nindices of', '⍸⍸\\nwhere\\ninterval index', '∊∊\\nenlist\\nmember of', '⍷⍷\\nfind', '∪∪\\nunique\\nunion', '∩∩\\nintersection', '~~\\nnot\\nwithout', ' ',\n", + "\t\t\t'//\\nreplicate\\nReduce', '\\\\\\\\\\n\\expand\\nScan', '⌿⌿\\nreplicate first\\nReduce First', '⍀⍀\\nexpand first\\nScan First', ' ', ',,\\nravel\\ncatenate/laminate',\n", + "\t\t\t'⍪⍪\\ntable\\ncatenate first/laminate', '⍴⍴\\nshape\\nreshape', '⌽⌽\\nreverse\\nrotate', '⊖⊖\\nreverse first\\nrotate first',\n", + "\t\t\t'⍉⍉\\ntranspose\\nreorder axes', ' ', '¨¨\\nEach', '⍨⍨\\nConstant\\nSelf\\nSwap', '⍣⍣\\nRepeat\\nUntil', '..\\nOuter Product (∘.)\\nInner Product',\n", + "\t\t\t'∘∘\\nOUTER PRODUCT (∘.)\\nBind\\nBeside', '⍤⍤\\nRank\\nAtop', '⍥⍥\\nOver', '@@\\nAt', ' ', '⍞⍞\\nSTDIN\\nSTDERR', '⎕⎕\\nEVALUATED STDIN\\nSTDOUT\\nSYSTEM NAME PREFIX', '⍠⍠\\nVariant',\n", + "\t\t\t'⌸⌸\\nIndex Key\\nKey', '⌺⌺\\nStencil', '⌶⌶\\nI-Beam', '⍎⍎\\nexecute', '⍕⍕\\nformat', ' ', '⋄⋄\\nSTATEMENT SEPARATOR', '⍝⍝\\nCOMMENT', '→→\\nABORT\\nBRANCH', '⍵⍵\\nRIGHT ARGUMENT\\nRIGHT OPERAND (⍵⍵)', '⍺⍺\\nLEFT ARGUMENT\\nLEFT OPERAND (⍺⍺)',\n", + "\t\t\t'∇∇\\nrecursion\\nRecursion (∇∇)', '&&\\nSpawn', ' ', '¯¯\\nNEGATIVE', '⍬⍬\\nEMPTY NUMERIC VECTOR', '∆∆\\nIDENTIFIER CHARACTER', '⍙⍙\\nIDENTIFIER CHARACTER']\n", + "\t\t, bqk = ' =1234567890-qwertyuiop\\\\asdfghjk∙l;\\'zxcvbnm,./q[]+!@#$%^&*()_QWERTYUIOP|ASDFGHJKL:\"ZXCVBNM<>?~{}'.replace(/∙/g, '')\n", + "\t\t, bqv = '`÷¨¯<≤=≥>≠∨∧×⋄⍵∊⍴~↑↓⍳○*⊢∙⍺⌈⌊_∇∆∘\\'⎕⍎⍕∙⊂⊃∩∪⊥⊤|⍝⍀⌿⋄←→⌹⌶⍫⍒⍋⌽⍉⊖⍟⍱⍲!⍰W⍷R⍨YU⍸⍥⍣⊣ASDF⍢H⍤⌸⌷≡≢⊆⊇CVB¤∥⍪⍙⍠⌺⍞⍬'.replace(/∙/g, '')\n", + "\t\t, tc = {}, bqc = {} //tab completions and ` completions\n", + "\tfor (let i = 0; i < bqk.length; i++)bqc[bqk[i]] = bqv[i]\n", + "\tfor (let i = 0; i < tcs.length; i += 3)tc[tcs[i] + tcs[i + 1]] = tcs[i + 2]\n", + "\tfor (let i = 0; i < tcs.length; i += 3) { let k = tcs[i + 1] + tcs[i]; tc[k] = tc[k] || tcs[i + 2] }\n", + "\tlet lbh = ''; for (let i = 0; i < lbs.length; i++) {\n", + "\t\tlet ks = []\n", + "\t\tfor (let j = 0; j < tcs.length; j += 3)if (lbs[i][0] === tcs[j + 2]) ks.push('\\n' + tcs[j] + ' ' + tcs[j + 1] + ' ')\n", + "\t\tfor (let j = 0; j < bqk.length; j++)if (lbs[i][0] === bqv[j]) ks.push('\\n` ' + bqk[j])\n", + "\t\tlbh += '' + lbs[i][0] + ''\n", + "\t}\n", + "\tlet d = document, el = d.createElement('div'); el.innerHTML =\n", + "\t\t`
${lbh}
\n", + " \n", + " `\n", + "\td.body.appendChild(el)\n", + "\tlet t, ts = [], lb = el.firstChild, bqm = 0 //t:textarea or input, lb:language bar, bqm:backquote mode\n", + "\tlet pd = x => x.preventDefault()\n", + "\tlet ev = (x, t, f, c) => x.addEventListener(t, f, c)\n", + "\tev(lb, 'mousedown', x => {\n", + "\t\tif (x.target.classList.contains('ngn_x')) { lb.hidden = 1; upd(); pd(x); return }\n", + "\t\tif (x.target.nodeName === 'B' && t) {\n", + "\t\t\tlet i = t.selectionStart, j = t.selectionEnd, v = t.value, s = x.target.textContent\n", + "\t\t\tif (i != null && j != null) { t.value = v.slice(0, i) + s + v.slice(j); t.selectionStart = t.selectionEnd = i + 1 }\n", + "\t\t\tpd(x); return\n", + "\t\t}\n", + "\t})\n", + "\tlet fk = x => {\n", + "\t\tlet t = x.target\n", + "\t\tif (bqm) {\n", + "\t\t\tlet i = t.selectionStart, v = t.value, c = bqc[x.key]\n", + "\t\t\tif (x.key === '`') {\n", + "\t\t\t\tt.value = v.slice(0, i) + '```' + v.slice(i)\n", + "\t\t\t\tt.selectionStart = t.selectionEnd = i + 1\n", + "\t\t\t\tbqm = 0\n", + "\t\t\t\td.body.classList.remove('ngn_bq')\n", + "\t\t\t\tpd(x)\n", + "\t\t\t\treturn !1\n", + "\t\t\t}\n", + "\t\t\tif (x.which > 31) { bqm = 0; d.body.classList.remove('ngn_bq') }\n", + "\t\t\tif (c) { t.value = v.slice(0, i) + c + v.slice(i); t.selectionStart = t.selectionEnd = i + 1; pd(x); return !1 }\n", + "\t\t}\n", + "\t\tif (!x.ctrlKey && !x.shiftKey && !x.altKey && !x.metaKey) {\n", + "\t\t\tif (\"`½²^º§ùµ°\".indexOf(x.key) > -1) {\n", + "\t\t\t\tbqm = 1; d.body.classList.add('ngn_bq'); pd(x); // ` or other trigger symbol pressed, wait for next key\n", + "\t\t\t} else if (x.key == \"Tab\") {\n", + "\t\t\t\tlet i = t.selectionStart, v = t.value, c = tc[v.slice(i - 2, i)]\n", + "\t\t\t\tif (c) { t.value = v.slice(0, i - 2) + c + v.slice(i); t.selectionStart = t.selectionEnd = i - 1; pd(x) }\n", + "\t\t\t}\n", + "\t\t}\n", + "\t}\n", + "\tlet ff = x => {\n", + "\t\tlet t0 = x.target, nn = t0.nodeName.toLowerCase()\n", + "\t\tif (nn !== 'textarea' && (nn !== 'input' || t0.type !== 'text' && t0.type !== 'search')) return\n", + "\t\tt = t0; if (!t.ngn) { t.ngn = 1; ts.push(t); ev(t, 'keydown', fk) }\n", + "\t}\n", + "\tlet upd = _ => { d.body.style.marginTop = lb.clientHeight + 'px' }\n", + "\tupd(); ev(window, 'resize', upd)\n", + "\tev(d, 'focus', ff, !0); let ae = d.activeElement; ae && ff({ type: 'focus', target: ae })\n", + "})();\n" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "[1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597]" + ] + }, + "execution_count": null, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "%apl {⍵,+/¯2↑⍵}⍣15⊢1 1" + ] + }, + { + "cell_type": "markdown", + "id": "4939224a", + "metadata": {}, + "source": [ + "Explanation:\n", + "\n", + "1. `1 1`: Initial seed (first two Fibonacci numbers)\n", + "2. `{⍵,+/¯2↑⍵}`: Function that appends the sum of the last two elements\n", + "3. `⍣15`: Apply the function 15 times\n", + "4. `⊢`: Identity function, passes the initial argument (1 1) to the iteration" + ] + }, + { + "cell_type": "markdown", + "id": "c74bb1b9", + "metadata": {}, + "source": [ + "Prime number sieve:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "c89a63d5", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47]" + ] + }, + "execution_count": null, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "%%apl\n", + "primes ← {⍵×2=+⌿0=⍵∘.|⍵}⍳\n", + "(primes 50)~0" + ] + }, + { + "cell_type": "markdown", + "id": "eec3f4b3", + "metadata": {}, + "source": [ + "Explanation:\n", + "\n", + "1. `⍳50` generates integers 1 to 50\n", + "2. `⍵∘.|⍵` creates a 50x50 matrix of divisibility (1 if divisible, 0 if not)\n", + "3. `0=` inverts the matrix (1 for non-divisible)\n", + "4. `+⌿` sums columns, counting non-divisors for each number\n", + "5. `2=` checks if count equals 2 (prime property)\n", + "6. `⍵×` multiplies result with original numbers, keeping primes\n", + "7. `~0` removes zero from the result" + ] + }, { "cell_type": "markdown", "id": "e61c4ea2",