http://mattn.kaoriya.net/software/vim/20150527121332.htm

ちょうど 1時間程度. 1-4はすぐに書けて, 5に時間を要した.

(追記: 2015年6月1日 問4に誤りがあり修正しました)





問題1 'for'の代わりに loopで. ( require ' cl-lib ) ( defun problem1-for ( lst ) ( cl-loop for i in lst sum i )) ( defun problem1-while ( lst ) ( let (( sum 0 ) ( xs lst )) ( while xs ( setq sum ( + sum ( car xs )) xs ( cdr xs ))) sum )) ( defun problem1-recursive ( lst ) ( if ( null lst ) 0 ( + ( car lst ) ( problem1-recursive ( cdr lst ))))) ( defun problem1-tail-recursive ( lst ) ( cl-labels (( func ( lst acc ) ( if ( null lst ) acc ( func ( cdr lst ) ( + acc ( car lst )))))) ( func lst 0 ))) ( let (( input '( 1 2 3 4 5 6 7 8 9 10 ))) ( cl-assert ( = 55 ( problem1-for input ) ( problem1-while input ) ( problem1-recursive input ) ( problem1-tail-recursive input ))))

問題2 ( require ' cl-lib ) ( defun problem2 ( xs ys ) ( cl-loop for x in xs for y in ys collect x collect y )) ( cl-assert ( equal '( a 1 b 2 c 3 ) ( problem2 '( a b c ) '( 1 2 3 ))))

他には mapcanを使うとかだろか. ( cl-mapcan ( lambda ( a b ) ( list a b )) '( 1 2 3 ) '( a b c ))

問題3 表現範囲の問題で, calcを使用. すぐ書けたものでは正しく表示できず. ( require ' cl-lib ) ( require ' calc-arith ) ( defun bignum-to-string ( n ) ( let (( sign ( if ( eq ( car n ) ' bigpos ) "" "-" ))) ( concat sign ( mapconcat #'number-to-string ( reverse ( cdr n )) "" )))) ( defun problem3 ( n ) ( cond (( = n 1 ) '( 0 )) (( = n 2 ) '( 0 1 )) ( t ( cl-loop with acc = '( 1 0 ) repeat ( - n 2 ) do ( push ( calcFunc-add ( cl-first acc ) ( cl-second acc )) acc ) finally return ( reverse ( mapcar ( lambda ( e ) ( if ( listp e ) ( bignum-to-string e ) e )) acc )))))) ( cl-assert ( string= ( nth 99 ( problem3 100 )) "218922995834555169026" ))

問題4 (1つめのコードは誤っています.) ( require ' cl-lib ) ( defun problem4 ( lst ) ( let (( xs ( sort lst ( lambda ( a b ) ( string< ( number-to-string b ) ( number-to-string a )))))) ( string-to-number ( mapconcat #'number-to-string xs "" )))) ( cl-assert ( = ( problem4 '( 50 2 1 9 )) 95021 ))

追記: 2015/JUN/1 修正版 ( require ' cl-lib ) ( defun compare ( a b ) ( let (( ab-val ( string-to-number ( format "%s%s" a b ))) ( ba-val ( string-to-number ( format "%s%s" b a )))) ( > ab-val ba-val ))) ( defun problem4 ( lst ) ( let (( xs ( sort lst #'compare ))) ( string-to-number ( mapconcat #'number-to-string xs "" )))) ( cl-assert ( = ( problem4 '( 420 42 423 )) 42423420 ) ( = ( problem4 '( 50 2 1 9 )) 95021 ))