はじめに
こんにちは、野村です。
今回は、JavaScriptのライブラリ「lodash」を使っていくつかの数列を書き出してみます。
lodashを使えば、関数型のプログラミングで用いられるメソッドを取り入れることがができます。
同様のライブラリに「Underscore.js」があるけど、lodashの方が多機能で高速とのこと。
インストールと実行
lodashのインストール
この方法は、Node.jsとnpmがインストールされていることが前提です。
スクリプトが置いてあるデレクトリに入って以下のコマンドを実行します。
$ npm install lodash
実行
実行したいスクリプトをVimで開き、コマンドモードから以下のコマンドを実行します。
:!node %
素数
・1より大きい自然数で、正の約数が1と自分自身のみである数。
'use strict'; const _ = require('lodash'); const sosu = (a)=>{ if (a[0]>Math.sqrt(_.last(a))) return a; return [a[0]].concat(sosu(_.tail(a).filter((x)=>x%a[0]!==0))); } console.log(sosu(_.range(2,100))); // 100未満の素数を表示
[ 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97 ]
双子素数
・双子素数:差が2である2つの素数の組
・いとこ素数:差が4である2つの素数の組
・セクシー素数:差が6である2つの素数の組
'use strict'; const _ = require('lodash'); const twin = (f,c)=>{ const loop = (a,i)=>{ const c = a.filter((v)=>v<=Math.sqrt(i)).every((v)=>i%v!==0); const b = (c) ? a.concat([i]) : a; return (_.last(b)===i && _.includes(b,i-f)) ? b : loop(b,i+1); } return _.range(c).reduce((a,z)=>{ const b = loop(a[0], _.last(a[0])+1); return [b,a[1].concat(_.last(b))]; },[[2],[]])[1].map((v)=>[v-f,v]); }; console.log(twin(2,10)); // 双子素数を10組表示 console.log(twin(4,10)); // いとこ素数を10組表示 console.log(twin(6,10)); // セクシー素数を10組表示
[ [ 3, 5 ], [ 5, 7 ], [ 11, 13 ], [ 17, 19 ], [ 29, 31 ], [ 41, 43 ], [ 59, 61 ], [ 71, 73 ], [ 101, 103 ], [ 107, 109 ] ] [ [ 3, 7 ], [ 7, 11 ], [ 13, 17 ], [ 19, 23 ], [ 37, 41 ], [ 43, 47 ], [ 67, 71 ], [ 79, 83 ], [ 97, 101 ], [ 103, 107 ] ] [ [ 5, 11 ], [ 7, 13 ], [ 11, 17 ], [ 13, 19 ], [ 17, 23 ], [ 23, 29 ], [ 31, 37 ], [ 37, 43 ], [ 41, 47 ], [ 47, 53 ] ]
幸運数
・ポーランドの数学者スタニスワフ・ウラムによって提案された数列。
・素数の性質を研究するために、素数に似たルールで導き出せる数列を考案したとのこと。
'use strict'; const _ = require('lodash'); const loop = (a, n)=>{ const b = [0].concat(a).filter((v,i)=>i%a[n]!==0); return (b[n]<b.length+1) ? loop(b,n+1) : b; } const luc = (n)=>loop(_.range(n).filter((v)=>v%2!==0), 1); console.log(luc(100)); // 100未満の幸運数を表示
[ 1, 3, 7, 9, 13, 15, 21, 25, 31, 33, 37, 43, 49, 51, 63, 67, 69, 73, 75, 79, 87, 93, 99 ]
階乗
・1 から n までのすべての整数の積。
'use strict'; const _ = require('lodash'); // 階乗を10個表示 console.log(_.times(10, (i)=>_.range(1,i+1).reduce((a,b)=>a*b,1)));
[ 1, 1, 2, 6, 24, 120, 720, 5040, 40320, 362880 ]
フィボナッチ数
・フィボナッチ数:イタリアの数学者レオナルド・フィボナッチにちなんで名付けられた数
・リュカ数:フランスの数学者エドゥアール・リュカにちなんで名付けられた数
'use strict'; const _ = require('lodash'); const fib = (f,n)=>(n<2) ? f[n] : fib(f,n-2)+fib(f,n-1); console.log(_.times(10,(a)=>fib([0,1],a))); // フィボナッチ数を10個表示 console.log(_.times(10,(a)=>fib([2,1],a))); // リュカ数を10個表示
[ 0, 1, 1, 2, 3, 5, 8, 13, 21, 34 ] [ 2, 1, 3, 4, 7, 11, 18, 29, 47, 76 ]
パスカルの三角形
・二項展開における係数を三角形状に並べたもの。
'use strict'; const _ = require('lodash'); const pas = (n)=>{ if (n<=0) return [1]; const a = pas(n-1); return _.zipWith([0].concat(a),a.concat([0]),(x,y)=>x+y); }; console.log(_.times(10,(a)=>pas(a))); // パスカルの三角形を10段表示
[ [ 1 ], [ 1, 1 ], [ 1, 2, 1 ], [ 1, 3, 3, 1 ], [ 1, 4, 6, 4, 1 ], [ 1, 5, 10, 10, 5, 1 ], [ 1, 6, 15, 20, 15, 6, 1 ], [ 1, 7, 21, 35, 35, 21, 7, 1 ], [ 1, 8, 28, 56, 70, 56, 28, 8, 1 ], [ 1, 9, 36, 84, 126, 126, 84, 36, 9, 1 ] ]
最後に
以上、JavaScriptのライブラリ「lodash」を使っていくつかの数列を書き出してみました。
lodashではなく、Underscore.jsを前提としいるのですが、こんな本があります。
『JavaScriptで学ぶ関数型プログラミング』(オライリー・ジャパン)
関数型プログラミングのエッセンスをJavaScriptに取り入れる方法が書かれています。
lodashはUnderscore.jsと(すべてではないけど)互換があるので参考になりました。
というわけで、今回はこれにて。