読者です 読者をやめる 読者になる 読者になる

labunix's blog

labunixのラボUnix

(番外編)2015年お正月用問題 を解いてみた。

■(番外編)2015年お正月用問題 を解いてみた。

 シェル芸勉強会の自分の回答一覧(1回~第13)
 http://labunix.hateblo.jp/entry/20150316/1426433547

 シェル芸勉強会スライド一覧
 http://blog.ueda.asia/?page_id=684

 第14回東京居残りシェル芸勉強会を解いてみた。
 http://labunix.hateblo.jp/entry/20150322/1426951657

■Q1.年末年始はディレクトリの掃除をしましょう。
 ということで、ご自身のPCから重複しているデータを探してみてください。
 全てのファイルから探すのは大変なので、
 手始めに重複しているJPEG画像リストを作ってみてください。

$ find . -type f -iname "*.jpg" | wc -l
1305
$ find . -type f -iname "*.jpg" -exec md5sum {} \; | \
    awk '{print $1}' | sort | uniq -c | awk '($1>1){print $2}' > list.log
$ wc -l < list.log 
1532件まではバックアップだと言い張ることにする。
 例えば以下では、(5*3)以上の重複jpgファイルを精査することになる。。。

$ wc -l < list.log 
5
$ find . -type f -iname "*.jpg" -exec md5sum {} \; | grep -f list.log

■Q2.羽田空港の緯度経度を求めてください。
 APIって何だろ?。。。

$ wget -O - http://imakoko.didit.jp/imakoko_html/memo/map_to_latlang.php?address=`echo -n "羽田空港" | nkf -wMQ | tr '=' '%'` 2>/dev/null | \
   w3m -dump -T text/html | grep ".*\[" | awk '{print $2,$3}'
緯度 [35.6865333]
経度 [139.691926]

■Q3.任意の級数からネイピア数(自然対数の底の数)を求めてください。
 精度が良いほど良いこととします。

 以下でやったコードが通らないので、普通に解く。。。

 clispでtan(e)とネイピア数の計算(1000)
 http://labunix.hateblo.jp/entry/2012/07/22/194906

$ echo "(setf (EXT:LONG-FLOAT-DIGITS) 10000)(exp 1.0L0)" | clisp -q | tail -1 | \
  sed s/".\{5\}"/"& "/g | sed s/".\{72\}"/"&\n"/g
2.718 28182 84590 45235 36028 74713 52662 49775 72470 93699 95957 49669 
67627 72407 66303 53547 59457 13821 78525 16642 74274 66391 93200 30599 
21817 41359 66290 43572 90033 42952 60595 63073 81323 28627 94349 07632 
33829 88075 31952 51019 01157 38341 87930 70215 40891 49934 88416 75092 
44761 46066 80822 64800 16847 74118 53742 34544 24371 07539 07774 49920 
69551 70276 18386 06261 33138 45830 00752 04493 38265 60297 60673 71132 
00709 32870 91274 43747 04723 06969 77209 31014 16928 36819 02551 51086 
57463 77211 12523 89784 42505 69536 96770 78544 99699 67946 86445 49059 
87931 63688 92300 98793 12773 61782 15424 99922 95763 51482 20826 98951 
93668 03318 25288 69398 49646 51058 20939 23982 94887 93320 36250 94431 
17301 23819 70684 16140 39701 98376 79320 68328 23764 64804 29531 18023 
28782 50981 94558 15301 75671 73613 32069 81125 09961 81881 59304 16903 
51598 88851 93458 07273 86673 85894 22879 22849 98920 86805 82574 92796 
10484 19844 43634 63244 96848 75602 33624 82704 19786 23209 00216 09902 
35304 36994 18491 46314 09343 17381 43640 54625 31520 96183 69088 87070 
16768 39642 43781 40592 71456 35490 61303 10720 85103 83750 51011 57477 
04171 89861 06873 96965 52126 71546 88957 03503 54021 23407 84981 93343 
21068 17012 10056 27880 23519 30332 24745 01585 39047 30419 95777 70935 
03660 41699 73297 25088 68769 66403 55570 71622 68447 16256 07988 26517 
87134 19512 46652 01030 59212 36677 19432 52786 75398 55894 48969 70964 
09754 59185 69563 80236 37016 21120 47742 72283 64896 13422 51644 50781 
82442 35294 86363 72141 74023 88934 41247 96357 43702 63755 29444 83379 
98016 12549 22785 09257 78256 20926 22648 32627 79333 86566 48162 77251 
64019 10590 04916 44998 28931 50566 04725 80277 86318 64155 19565 32442 
58698 29469 59308 01915 29872 11725 56347 54639 64479 10145 90409 05862 
98496 79128 74068 70504 89585 86717 47985 46677 57573 20568 12884 59205 
41334 05392 20001 13786 30094 55606 88166 74001 69842 05580 40336 37953 
76452 03040 24322 56613 52783 69511 77883 86387 44396 62532 24985 06549 
95886 23428 18997 07733 27617 17839 28034 94650 14345 58897 07194 25863 
98772 75471 09629 53741 52111 51368 35062 75260 23264 84728 70392 07643 
10059 58411 66120 54529 70302 36472 54929 66693 81151 37322 75364 50988 
89031 36020 57248 17658 51180 63036 44281 23149 65507 04751 02544 65011 
72721 15551 94866 85080 03685 32281 83152 19600 37356 25279 44951 58284 
18829 47876 10852 63981 39559 90067 37648 29224 43752 87184 62457 80361 
92981 97139 91475 64488 26260 39033 81441 82326 25150 97482 79877 79964 
37308 99703 88867 78227 13836 05772 97882 41256 11907 17663 94650 70633 
04527 95466 18550 96666 18566 47097 11344 47401 60704 62621 56807 17481 
87784 43714 36988 21855 96709 59102 59686 20023 53718 58874 85696 52200 
05031 17343 92073 21139 08032 93634 47972 73559 55277 34907 17837 93421 
63701 20500 54513 26383 54400 01863 23991 49070 54797 78056 69785 33580 
48966 90629 51194 32473 09958 76552 36812 85904 13832 41160 72260 29983 
30535 37087 61389 39639 17795 74540 16137 22361 87893 65260 53815 58415 
87186 92553 86061 64779 83402 54351 28439 61294 60352 91332 59427 94904 
33729 90857 31580 29095 86313 82683 29147 71163 96337 09240 03168 94586 
36060 64584 59251 26994 65572 48391 86564 20975 26850 82307 54425 45993 
76917 04197 77800 85362 73094 17101 63434 90769 64237 22294 35236 61255 
72508 81477 92231 51974 77806 05696 72538 01718 07763 60346 24592 78778 
46585 06560 50780 84421 15296 97521 89087 40196 60906 65180 35165 01792 
50461 95013 66585 43663 27125 49639 90854 91442 00014 57476 08193 02212 
06602 43300 96412 70489 43903 97177 19518 06990 86998 60663 65832 32278 
70937 65022 60149 3L0

■Q5.円周率をなるべく精度よく求めてみてください。
 以下でやった。atanの精度に依存するけど、個人的には三角関数を使う方が好き。

 clispで円周率
 http://d.hatena.ne.jp/labunix/20111230

 三角関数の逆関数で円周率 clisp
 http://d.hatena.ne.jp/labunix/20120101

$ echo "(setf (EXT:LONG-FLOAT-DIGITS) 1000) (* 4.00L0 (atan 1.00L0))" | \
  clisp -q | tail -1 | \
  sed s/".\{5\}"/"& "/g | sed s/".\{72\}"/"&\n"/g
3.141 59265 35897 93238 46264 33832 79502 88419 71693 99375 10582 09749 
44592 30781 64062 86208 99862 80348 25342 11706 79821 48086 51328 23066 
47093 84460 95505 82231 72535 94081 28481 11745 02841 02701 93852 11055 
59644 62294 89549 30381 96442 88109 75665 93344 61284 75648 23378 67831 
65271 20190 91456 48566 92346 03486 10454 32664 82133 93607 26024 91412 
73724 58686 L0

■Q6.集合{a,b,c,d,e}から全ての組み合わせ(部分集合)を列挙してください。
 これはシェルの機能。

$ echo {,a}{,b}{,c}{,d}{,e} | sed s/".\{72\}"/"&\n"/g
e d de c ce cd cde b be bd bde bc bce bcd bcde a ae ad ade ac ace acd ac
de ab abe abd abde abc abce abcd abcde

■例えば、15の重複無しの3つの数字の組み合わせを列挙すると10通りある。

$ echo {,1}{,2}{,3}{,4}{,5} | tr ' ' '\n' | grep "^[0-9][0-9][0-9]\$" | sort -n | nl
     1	123
     2	124
     3	125
     4	134
     5	135
     6	145
     7	234
     8	235
     9	245
    10	3458128が完全数であることを確認してください。

$ seq 2 8128 | awk '(8128%$1==0){print (8128/$1)}' | awk 'sum+=$1;END{print sum}'
4064
2032
1016
508
254
127
64
32
16
8
4
2
1
8128