Just another Ruby porter,

〜2014年12月下旬〜


<Older(,) | Newer(.)> | Recent(/)>> | RDF

2014-12-21 (Sun)

awkで約分 #シェル芸

ユークリッドの互除法を使うというのをどこかで見かけたのでawkで書いてみた。
ユークリッドの互除法を使えば最大公約数が簡単に求められる。

  1. 入力を m, n (m ≧ n) とする。
  2. n = 0 なら、 m を出力してアルゴリズムを終了する。
  3. m を n で割った余りを新たに n とし、更に 元のnを新たにm とし 2. に戻る。

awkでこれを表現すると

while (n) {
  r = m % n
  m = n
  n = r
}

となる。これをゴルフすると

while (n = m % (m = n));

となる。

先日の勉強会のQ7にあてはめて前半の通分を略すと

% echo 1532 2880 | awk '{m = $1; n = $2; while(n = m % (m = n)); print $1 / m "/" $2 / m}' 
383/720

となる。おのおのを最大公約数で割れば約分したことになる。


2014-12-22 (Mon)

bashとzshで約分 #シェル芸

昨日のawkで書いたものをそのままbashへ移植してもちゃんと動く。

% bash -c 'echo 1532 2880 | { read a b; m=$a; n=$b; while ((n=m%(m=n)));do :;done; echo $[a/m]/$[b/m]; }'  
383/720

だが、zshだとだめ。

% zsh -c 'echo 1532 2880 | { read a b; m=$a; n=$b; while ((n=m%(m=n)));do :;done; echo $[a/m]/$[b/m]; }'
0/1

どうもn=m%(m=n)でm=nを評価した瞬間にその前にあるmもnになってしまうからみたい。
1回目にすでにnが0になっている。
それならばと無駄に(t=m)にしてみたらいけた。

% zsh -c 'echo 1532 2880 | { read a b; m=$a; n=$b; while ((n=(t=m)%(m=n)));do :;done; echo $[a/m]/$[b/m]; }'
383/720

最初からこれを見せられたら謎でしかないな。


2014-12-23 (Tue)

Google Chromeのプロファイルを削除

軽量化しようとぐぐってみたが、どうも対策として再インストールしかないようで。
再インストールというかユーザープロファイルを初期化って話なので、単にmvしてみた。
~/.config/google-chromeをどこかへ退避させる。
拡張とかもろもろの設定はだいたい同期すれば元に戻る。
同期というものGoogleへログインすれば裏で勝手に行なわれる。
ここでだいたいというのが曲者で、たとえばVichromeとかStylishの設定は戻ってこない。
こいつらはsqlite3形式で独自に管理されているので、そのまま使いたければそのまま持ってくればok。

Vichrome
~/.config/google-chrome/Default/Local Storage/chrome-extension_gghkfhpblkcmlkmpcpgaajbbiikbhpdi_0.localstorage
Stylisth
~/.config/google-chrome/Default/databases/chrome-extension_dhdgffkkebhmkfjojejmpbldmpobfkfo_0
~/.config/google-chrome/Default/databases/chrome-extension_fjnbnpbmkenffdnngjfgmeleoegfcffe_0

実は33.0以降でmvするといろいろと面倒なことが起こるので外からcookieを参照してる場合はやらないほうがいい。


2014-12-24 (Wed)

Google Chromeのcookieが暗号化されている

新たに作ったプロファイルのcookieをsqlite3で読み出してみたら、
valueが空でencrypted_valueへ移動していた。
古いバージョンから使い続けているとそのままvalueを使うようで、
新規cookieはencrypted_valueへ移行してるようだ。
そのおかげでbrowserのcookieを読み出して流用がしにくくなったね。
ぐぐるとpythonのスクリプトとか出てくるが、成功しなかった。

今はfitbitにアクセスするときに使ってるぐらいなので、
ログイン処理を自前で用意して毎回ログインするようにして対処。

% curl -c fitbit-cookie.txt 'https://www.fitbit.com/login' \
  --data 'login=Log+In&includeWorkflow=&redirect=&switchToNonSecureOnRedirect=&disableThirdPartyLogin=false&email=メールアドレス&password=パスワード&rememberMe=true'

たぶんもっと省略できると思うけど、これでいけている。


2014-12-25 (Thu)

化け猫アイコンメーカーの設定保存

微妙に再現できなくて困っていたら保存できるようになっていた。
これでサンタ帽もかぶせることもできる!


2014-12-26 (Fri)

忘年会

馬場。今年は19:00からとちょっと遅め。
システムがまた変わって食べ放題になっていた。
そのため一人1500円ぐらい。
納会からの流れ。

なぜ迷子に。

例によって公開内緒話から。
どうすればOpenSSLを外せるか。
cURL同梱はどうだ。
転職おめでとうございます。

前向きに検討。

CTOの仕事とは何か?

四捨五入して50。

security@にセキュリティとは関係ないメールが来るのは、
www.ruby-lang.orgに書かれている唯一のメールアドレスだから。
(matzのアドレスもあるのでそっちにも行っているかも。)

Heartなんちゃらやらshellshockやら大変な年だった。

jqは癖があるけど、ま、いろいろと使わないといけなかったりする。

@eban, @gotoyuzo, @hemge, @hsbt, @nahi


2014-12-27 (Sat)

factorで素数判定

factorという便利なコマンドがある。引数に数値を渡すと素因数分解してくれる。

% factor 999 9999
999: 3 3 3 37
9999: 3 3 11 101

標準入力も受け付けてくれて至れり尽くせりだ。

% echo 999 9999 | factor
999: 3 3 3 37
9999: 3 3 11 101

自分自身しか出力しないときは素数と判定できる。

% factor 19    
19: 19

つまりフィールド数が2個のときが素数なわけだ。
awkを使えば簡単に判断できる。たとえば20までの素数が知りたければ

% factor {2..20} | awk 'NF==2{print $2}' | xargs        
2 3 5 7 11 13 17 19

でいいわけだ。これを短くすると

% factor {2..20} | awk 'NF==2&&$0=$2' | xargs
2 3 5 7 11 13 17 19

と書ける。2個ということは3個目以降は空とみなせるので

% factor {2..20} | awk '!$3&&$0=$2' | xargs
2 3 5 7 11 13 17 19

でもいい。これで最終形だと思っていたが、実はまだ短くなることに最近気づいた。

% factor {2..20} | awk '$0*=!$3' | xargs
2 3 5 7 11 13 17 19

最初のフィールドは":"がついてて邪魔だが数値として扱うと後ろの文字は無視される。
さらに!は0か1になるので

% awk 'BEGIN{ print "19:" * 1, "19:" * 0 }'
19 0

1のときはちゃんと数値になり、0のときは出力されない。
うまい具合にぴったりだ。
あと":"を消すには"19:" + 0というのもよくやる。ゴルフ的には+"19:"だが。

いやいや、 似たようなこと既に書いていたよ。


2014-12-28 (Sun)

bashで関数を消す

unsetで消せるが、注意が必要。同じ名前の変数があるとそちらをまず消す。
もう一度unsetすると関数が消える。

$ foo=1
$ foo(){ date; }
$ type foo
foo は関数です
foo () 
{ 
    date
}
$ echo $foo
1
$ unset foo
$ echo $foo

$ type foo
foo は関数です
foo () 
{ 
    date
}
$ unset foo
$ type foo
bash: type: foo: 見つかりません

関数を消したいときはunset -fで。

$ foo=1
$ foo(){ date; }
$ type foo
foo は関数です
foo () 
{ 
    date
}
$ unset -f foo
$ echo $foo
1
$ type foo
bash: type: foo: 見つかりません

2014-12-29 (Mon)

AOL Readerで重複しているアイテムを既読に

Yahoo Pipes!で作ったRSSに日付をつけなかったもんだから、
更新すると同じタイトルが何度も含まれてしまう事案が発生。
Yahoo Pipes!のほう直せばいいが、jqでなんとかしてみる。

まず、該当するRSSのリストを取得。トークンは 例によってブラウザから。
リストはjsonで。

% curl -s -H 'Token: トークン' \
  'https://reader.aol.com/reader/api/0/stream/contents/feed/XXXXXX?n=10000&xt=user/-/state/read' > tmp.json

jsonはこんな感じになっている。

{
  "items": [
    {
      "id": "XXXXXX/1234567890123456789",
      "categories": [],
      "crawlTimeMsec": "1419821730319870",
      "timestampUsec": "1419821730319",
      "title": "タイトル1",
      "published": "2014-12-29 02:55:30",
      "updated": "2014-12-29 02:55:30",
      "summary": {
        "direction": "ltr",
        "content": "hogehoge"
      },
      "likingUsers": [],
      "comments": [],
      "annotations": [],
      "origin": {
        "streamId": "feed/XXXXXX",
        "title": "foo bar",
        "htmlUrl": "fake"
      },
      "alternate": [
        {
          "href": "http://127.0.0.1/"
        }
      ],
      "author": "",
      "enclosure": []
    },
    ...
  ]
}

このitems[].titleでgroup_byして一番新しいもの以外を既読にすればいい。そのリストをjqで作る。

% jq -r '.items|[.[]|{title,id}]|group_by(.title)|del(.[][0])|.[][].id' tmp.json

これでok。あとは 先日の要領で既読にする。


2014-12-30 (Tue)

【問題】年末年始シェル芸問題集を解いた

_ Q1 重複しているJPEG画像リスト:

Ubuntuにはduffというコマンドが存在する。

% find ~ -name '*.jpg' -type f -print0 | duff -0 | xargs -0 -n1
前略
2 files in cluster 290 (107509 bytes, digest 5462549a45443053e2ab416e9162c67649c80e2e)
/home/eban/ebooks/150-guin-001-r90-jpg/074.jpg
/home/eban/ebooks/png/images/image_222.jpg
2 files in cluster 291 (81913 bytes, digest 548129fe0ad326ebf7c768ea5bd7833069b61a16)
/home/eban/ebooks/150-guin-001-r90-jpg/172.jpg
/home/eban/ebooks/png/images/image_516.jpg
2 files in cluster 292 (92154 bytes, digest eee80c51d3261d5db206c49160eab6cff107433b)
/home/eban/ebooks/150-guin-001-r90-jpg/099.jpg
/home/eban/ebooks/png/images/image_297.jpg
2 files in cluster 293 (108541 bytes, digest 946f4efe81ba23e7cb619648912eb3e5d70ab18e)
/home/eban/ebooks/150-guin-001-r90-jpg/036.jpg
/home/eban/ebooks/png/images/image_108.jpg

_ Q2 羽田空港の緯度経度:

Google MapのAPIを使うと簡単。

% curl -s 'http://maps.google.com/maps/api/geocode/json?address=羽田空港' | \
  jq -r '.results[0].geometry.location|"緯度:\(.lat), 経度:\(.lng)"'
緯度:35.5493932, 経度:139.7798386

_ Q3 ネイピア数:

bc -lとやると裏で級数展開してくれる。

% echo 'scale=1000;e(1)' | bc -l                    
2.718281828459045235360287471352662497757247093699959574966967627724\
07663035354759457138217852516642742746639193200305992181741359662904\
35729003342952605956307381323286279434907632338298807531952510190115\
73834187930702154089149934884167509244761460668082264800168477411853\
74234544243710753907774499206955170276183860626133138458300075204493\
38265602976067371132007093287091274437470472306969772093101416928368\
19025515108657463772111252389784425056953696770785449969967946864454\
90598793163688923009879312773617821542499922957635148220826989519366\
80331825288693984964651058209392398294887933203625094431173012381970\
68416140397019837679320683282376464804295311802328782509819455815301\
75671736133206981125099618188159304169035159888851934580727386673858\
94228792284998920868058257492796104841984443634632449684875602336248\
27041978623209002160990235304369941849146314093431738143640546253152\
09618369088870701676839642437814059271456354906130310720851038375051\
01157477041718986106873969655212671546889570350354

_ Q4 base64を何度も実行する:

最初は適当に50回ほど実行した。

% tmp=$(cat message2015.txt); for i in {1..31};do tmp=$(echo "$tmp" | base64 -d); done; echo "$tmp"  
:(){: | : &};:

_ Q5 円周率:

atan(1)*4で。

% echo 'scale=1000;a(1)*4' | bc -l
3.141592653589793238462643383279502884197169399375105820974944592307\
81640628620899862803482534211706798214808651328230664709384460955058\
22317253594081284811174502841027019385211055596446229489549303819644\
28810975665933446128475648233786783165271201909145648566923460348610\
45432664821339360726024914127372458700660631558817488152092096282925\
40917153643678925903600113305305488204665213841469519415116094330572\
70365759591953092186117381932611793105118548074462379962749567351885\
75272489122793818301194912983367336244065664308602139494639522473719\
07021798609437027705392171762931767523846748184676694051320005681271\
45263560827785771342757789609173637178721468440901224953430146549585\
37105079227968925892354201995611212902196086403441815981362977477130\
99605187072113499999983729780499510597317328160963185950244594553469\
08302642522308253344685035261931188171010003137838752886587533208381\
42061717766914730359825349042875546873115956286388235378759375195778\
18577805321712268066130019278766111959092164201988

_ Q6 {a,b,c,d,e}からすべての組み合わせ :

なんかsortすると順番があれだが。

% printf "%s\n" {a,,,,}{,b,,,}{,,c,,}{,,,d,}{,,,,e} | sort -u

a
ab
abc
abcd
abcde
abce
abd
abde
abe
ac
acd
acde
ace
ad
ade
ae
b
bc
bcd
bcde
bce
bd
bde
be
c
cd
cde
ce
d
de
e

2014-12-31 (Wed)

Q7 完全数

14474011154664524427946373126085988481573677491474835889066354349131199152128
とりあえず16進で見てみる。

% echo 'obase=16;14474011154664524427946373126085988481573677491474835889066354349131199152128' | bc
1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC0000000000000000000000000000000

かなり特徴的だとわかる。上位は全部ビットが立ち、下位は寝ている。
この時点で2のべき乗で割れることもわかる。2進で0の数を数えてみよう。

% echo 'obase=2;14474011154664524427946373126085988481573677491474835889066354349131199152128' | bc    
11111111111111111111111111111111111111111111111111111111111111111111\
11111111111111111111111111111111111111111111111111111111111000000000\
00000000000000000000000000000000000000000000000000000000000000000000\
0000000000000000000000000000000000000000000000000
% echo 'obase=2;14474011154664524427946373126085988481573677491474835889066354349131199152128' | bc | tr -cd 0 | wc -c
126

つまり2の126乗で割り切れる。逆に1の数は

% echo 'obase=2;14474011154664524427946373126085988481573677491474835889066354349131199152128' | bc | tr -cd 1 | wc -c
127

なので結局bc的には (2^127-1)*(2^126) となる。一応2^127-1が素数であることも確認しておく。

% echo '2^127-1' | bc | xargs openssl prime     
7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF is prime

というわけであとは約数の組み合わせで足していけばいい。

2^126のほうは2^0+2^1+...+2^126なので2進数的には0から126までつまり127ビット全部立っていることを意味する。
要するに2^127-1だ。どこかで見た値だ。
つぎに2^127-1との組み合わせだが、こちらは(2^127-1)*(2^0+2^1+...+2^125)なので(その数自身は除くので125までになる)、
(2^127-1)*(2^126-1)となる。これにさっきの2^127-1を足すと、 (2^127-1)*(2^126-1)+2^127-1 となり、まとめると
(2^127-1)*(2^126) となりめでたく完全数になることが確認できた。
って、最後は全然シェル関係ないじゃん。というわけでtwitterでは

% echo '170141183460469231731687303715884105727*(2^126-1)+2^127-1'|BC_LINE_LENGTH=99 bc
14474011154664524427946373126085988481573677491474835889066354349131199152128

でごまかしてみた。


<Older(,) | Newer(.)> | Recent(/)>> | RDF


WWW を検索 jarp.does.notwork.org を検索

わたなべひろふみ
Key fingerprint = C456 1350 085F A320 C6C8 8A36 0F15 9B2E EB12 3885
Valid HTML 4.01!