〜2016年1月上旬〜
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)
最近の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=
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
ファイルを使わずに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
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+ならそんなこともないのでおすすめ。
それよりも昨日一昨日とタイトルがタイポだらけでもうしわけない。
この問題は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
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
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
(Σ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
10001番目の素数。
sedでも行番号表示はできるというか、=ってなんかまさにこのためにあるんじゃないかという機能だ。
% yes 高須クリニック | sed -n = | factor | awk 'NF==2&&++i==10001{print $2;exit}' 104743
お約束を入れておいた。
1から始まるので!$3は使えない。
cf: ProjectEuler - Project Eulerをシェル芸で解いてみる(Problem 7) - Qiita