Archive for the ‘bits’ Tag
projecteuler4(その3)...または、newLISP の便利関数
二回に渡る 問題4 は問題の解き方に重点を置き、肝心の newLISP 組込関数の紹介がおろそかだったので、その3です(汗)。
newLISP の繰り返し構文は for文を始め、CommonLISP よりかなり豊富に揃っています。
CommonLISP だと dotimes、dolist、loop、do の4つですから、その差は歴然。使うかどうかは別ですが、、、
dolist、dotimes、for、until、while は説明するまでもなく、大体ご想像通りの動作です。
do-until、do-while は本体を評価してから、評価式を評価します。つまり until、while と評価式の評価タイミングが逆になります。
doargs は関数の引数を1個ずつ評価して繰り返します。ちなみに、newLISP では、関数(ラムダ式)で指定ない引数は全てオプションの変数(CommonLISP の &rest に相当)になります。そこで、この構文が生きてくるわけです。
dostring は文字列を一文字ずつ評価して繰り返します。無印の newLISP では1バイト単位ですが、UTF-8版 newLISP では一文字が多バイトになる場合があるので注意が必要です。無印の newLISP と UTF-8版 newLISP で文字処理単位が異なる関数はこちらに表があります。
残る dotree は newLISP 固有のコンテキストに関する構文で、コンテキスト内のシンボル毎に繰り返します。コンテキストについて語り始めるときりがないので、マニュアルを見てください(笑)。
さて、CommonLISP との比較で言うと newLISP の reverse は破壊的である点が異なっています。ちなみに newLISP の破壊的関数はこちらに表があります。
また、letn は CommonLISP の let* に相当します。
変わったところでは、組込関数bits があります。これの関数は整数値を 1 と 0 の文字列に変換します。
> (bits 6) "110" >
ふ、ふ、ふ、便利でしょう。これと組込関数 select を組み合わせて、前回の binary counting を実装しています。
組込関数 select は、インデックス・リストを使ってリストや文字列から必要な要素だけ取り出せます。
> (select '(a b c d e f) '(0 2 4)) (a c e) > (select "abcdef" '(1 3 5)) "bdf" >
と、こんな感じ。
以上、如何でしょうか?
projecteuler3...または、newLISP で素因数分解するには
3回目の projecteuler は、newLISP には簡単な問題。
というのも、問題3は 600851475143 を素因数分解して、最大の素数を求めるというもの。
例題の 13195 を素因数分解すると 5, 7, 13, 29 が得られます。
これを newLISP でやると、
> (factor 13195) (5 7 13 29) >
組込関数 factor は引数の整数を素因数分解するという、この問題のためにあるような関数!しかも、600851475143 は
> (bits 600851475143) "1000101111100101100010011110101011000111" > (length (bits 600851475143)) 40 >
高々40ビット、64ビット整数の newLISP の敵ではありません(笑)。関数 bits も newLISP 組込で、引数の整数を二進数の文字列に変換してくれる便利な関数です。
従って、問題3の解答は、
> (factor 600851475143) (71 839 1471 6857) > ((factor 600851475143) -1) 6857 >
となります。
以上、如何でしょうか?