Archive for the ‘bits’ Tag

projecteuler4(その3)...または、newLISP の便利関数

 二回に渡る 問題4 は問題の解き方に重点を置き、肝心の newLISP 組込関数の紹介がおろそかだったので、その3です(汗)。
 newLISP の繰り返し構文は for文を始め、CommonLISP よりかなり豊富に揃っています。

do-until
do-while
doargs
dolist
dostring
dotimes
dotree
for
until
while

 CommonLISP だと dotimesdolistloopdo の4つですから、その差は歴然。使うかどうかは別ですが、、、
 dolistdotimesforuntilwhile は説明するまでもなく、大体ご想像通りの動作です。
 do-untildo-while は本体を評価してから、評価式を評価します。つまり untilwhile と評価式の評価タイミングが逆になります。
 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
> 

 となります。

 以上、如何でしょうか?