Just another Ruby porter,

〜2016年1月上旬〜


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

2016-01-01 (Fri)

curl --remote-name-all

man curlによると-O(--remote-name)はやはりURLごとに指定する必要があるようで、
全部まとめて指定するには--remote-name-allを使えばいいようだ。

--remote-name-all
       This option changes the default action for all given URLs to be dealt with as if -O, --remote-name were
       used for each one. So if you want to disable that for a specific URL after --remote-name-all  has  been
       used, you must use "-o -" or --no-remote-name. (Added in 7.19.0)

2016-01-02 (Sat)

known_hostsのハッシュ化されたホスト名のチェック

最近のOpenSSHは~/.ssh/known_hostsのホスト名をハッシュ化してるのでわかりにくい。
エントリーを消すのはもうssh-keygenを使うしかない。
一応行番号はこうすればわかるのでエディタで消すのありだが、素直に-Rを使うべき。

% ssh-keygen -l -F ci.ruby-lang.org
# Host ci.ruby-lang.org found: line 136 
ci.ruby-lang.org ECDSA SHA256:RK6mb6BwHgpPEgnK7/SfuWLmQI84g9siYeHPiCvmWyE 

それはそれとして、ホスト名はこんな形式になっている。

% awk 'NR==136{print $1}' ~/.ssh/known_hosts
|1|CZ9Wvav9493RoGNMD92NW05gpbg=|1U2ibOZxFYZIFb9aJehN2xY4T00=

順にsha1,salt,hostを意味する。こんな感じで実行するとハッシュ化されたホスト名が得られる。

% echo -n ci.ruby-lang.org | \
  openssl sha1 -binary -hmac "$(echo CZ9Wvav9493RoGNMD92NW05gpbg=|base64 -d)" | base64
1U2ibOZxFYZIFb9aJehN2xY4T00=

2016-01-03 (Sun)

Project Euler Problem 1 #シェル芸

Project Eulerをシェル芸で解いてみる(Problem 1) - Qiita
を見てたらふと思いついた。uniqの代わりにファイルを生成させるのはどうだろうか。
15の倍数が複数あっても問題ない。

% touch 15 15 30 30
% ls
15  30

zshならこれでいける。

% mkdir tmp; cd tmp
% touch {3..999..3} {5..999..5}; set *; echo $[${*// /+}]
233168

bashだとエラーになるので、一度文字列にしてからじゃないとだめ。

$ mkdir tmp; cd tmp
$ touch {3..999..3} {5..999..5}; set *; a="$*"; echo $[${a// /+}]
233168

結局のところ素直にtrとbcを使っとけという話だった。

% mkdir tmp; cd tmp
% touch {3..999..3} {5..999..5}; echo * | tr ' ' + | bc
233168

2016-01-04 (Mon)

Project Euler Problem 1 Zsh編 #シェル芸

ファイルを使わずにZshだけで。(u)でuniqできる。

% set {3..999..3} {5..999..5}; set ${(u)*}; echo $[${*// /+}]
233168

setを使わなくても同じ長さだったりする。

% a=({3..999..3} {5..999..5}); b=(${(u)a}); echo $[${b// /+}]
233168

2016-01-05 (Tue)

Project Euler Problem 1 究極編 #シェル芸

Zshでなんだかんだで変数を使わなくてもいけることがわかったがおすすめしない。

% echo ${(j/+/)${(s/ /u)${:-{3..999..3} {5..999..5}}}} | bc
233168

まあ、この問題は3でも5でも割り切れないものを削除すると考えるとGNU sedでも解ける。

% seq 999 | sed '0~3b;0~5!d' | paste -sd+ | bc                                                                      
233168

行番号とその内容は一致しているので、行番号そのものが使える。
tr '\n' +のようなことをすると最後に余計な+がつくが、
paste -sd+ならそんなこともないのでおすすめ。

それよりも昨日一昨日とタイトルがタイポだらけでもうしわけない。


2016-01-06 (Wed)

Project Euler Problem 2 #シェル芸

この問題は2008年に解いたときは400万じゃなくて100万だった。
特にひねりなし。bashで。

$ a=1 b=2 s=0; for ((;a<=4000000;b=a+(a=b)));{ ((a%2))||((s+=a)); }; echo $s
4613732

b=a+(a=b)はc=b;b+=a;a=cを短くしたもの。

cf. ProjectEuler - Project Eulerをシェル芸で解いてみる(Problem 2) - Qiita


2016-01-07 (Thu)

Project Euler Problem 4 #シェル芸

3桁の積の最大の回文数。
999*999が998001なので6桁になる。
この問題は積から考えずに回文から考えたほうが計算量はぐんと少なくなる。
積だと100から999の900通りの2乗になるが、
回文なら100から999の900通りになる。
つまり

100001
101101
102201
...
997799
998899
999999

を候補にする。で、これが3桁の積になってるものを抜き出せばいい。
実際は999999から逆順で最初に見つかったものが答えになる。
本当は999*999が998001だから997799から始めればいいが、まあ気にしない。
というわけで実装。

% seq 999 -1 100 | awk '$0=$0$3$2$1{for(i=999;i>=100;i--){if($0%i==0 && $0/i ~ /^...$/){print;exit}}}' FS= 
906609

$0=$0$3$2$1で回文を作っている。
あとは割り切れる3桁の数の除が3桁になってるものを見つける。

% seq 999 -1 100 |awk '$0=$0$3$2$1{for(i=999;i>=100;i--){if($0%i==0&& $0/i ~ /^...$/){print $0, i, $0/i}}}' FS= | head
906609 993 913
906609 913 993
888888 962 924
888888 924 962
886688 968 916
886688 916 968
861168 932 924
861168 924 932
855558 957 894
855558 894 957

これを見ると2番目に大きいものはという問題でもよかった気がする。

Problem 3はfactor一択なので省略。

cf: ProjectEuler - Project Eulerをシェル芸で解いてみる(Problem 4) - Qiita


2016-01-08 (Fri)

Project Euler Problem 5 #シェル芸

1から20までのすべての数の最小公倍数(LCM)。
実際は1から10までは2倍するとそれ以降に存在するので11からでok。
LCMはたとえば4と6だったら4を1倍,2倍,3倍という感じで進めて6で割り切れるか順に調べればよさげだ。
これを11から20まで繰り返す。
つまりLCM(LCM(LCM(LCM(LCM(LCM(LCM(LCM(LCM(11,12),13),14),15),16),17),18),19),20)だ。 そんな方針で。

% seq 12 20 | awk -v lcm=11 '{for(t=lcm; t%$0; t+=lcm);}$0=lcm=t'
132
1716
12012
60060
240240
4084080
12252240
232792560
232792560

まあ、これを見ればわかる通り20は4*5で12(4*3)や15(5*3)がすでに出ているので、
実際は11から19までで十分。あとはtail -n1で。

Rubyならこんな感じ。

% ruby -e 'p (1..20).reduce(:lcm)'  
232792560

cf: ProjectEuler - Project Eulerをシェル芸で解いてみる(Problem 5) - Qiita


2016-01-09 (Sat)

Project Euler Problem 6 #シェル芸

(Σn)**2 - (Σn**2)ということだが、
これって公式があるのでシェル芸でもなんでもなかったりする。
Σnはn*(n+1)/2で、Σn**2はn*(n+1)*(2n+1)/6だ。
というわけでかなりチートな解。

$ echo $[(100*101/2)**2-100*101*201/6]
25164150

まあ、これだけじゃなんなので愚直に文字列を作る方法も。
nが3の場合ならこんな感じでブレース展開すればbcへ渡せる。

$ echo \( {1..3}+ '0)^2 - (' {1..3}^2+ '0)'
( 1+ 2+ 3+ 0)^2 - ( 1^2+ 2^2+ 3^2+ 0)

というわけでこれが解。

$ echo \( {1..100}+ '0)^2 - (' {1..100}^2+ '0)' | bc
25164150

最後にRuby版。

% ruby -e 'p (1..100).reduce(:+)**2-(1..100).reduce{|r,e|r+e**2}' 
25164150

cf: ProjectEuler - Project Eulerをシェル芸で解いてみる(Problem 6) - Qiita


2016-01-10 (Sun)

Project Euler Problem 7 #シェル芸

10001番目の素数。
sedでも行番号表示はできるというか、=ってなんかまさにこのためにあるんじゃないかという機能だ。

% yes 高須クリニック | sed -n = | factor | awk 'NF==2&&++i==10001{print $2;exit}'
104743

お約束を入れておいた。
1から始まるので!$3は使えない。

cf: ProjectEuler - Project Eulerをシェル芸で解いてみる(Problem 7) - Qiita


<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!