【16問】yukicoder ☆1をbashで解く
概要
管理者能力を何とかする計画の一環として、yukicoder☆1をひたすらBashで解いた。
CLIツールをまともに使えない状態では、管理者能力も身につかないだろう。
解いた問題
#160784 No.341 沈黙の期間 - yukicoder
1文字1行に分解して、隣接同一行をまとめて、"…"のカウントの最大値を取る。Bashのおかげでやっと解けた…ずっと解けなくて困っていた。
勉強したこと: awkにはmax関数がない
sed 's/./&\n/g' | uniq -c | awk 'BEGIN{ret = 0} {if ($2 == "…") if (ret < $1) ret = $1;} END {print ret}'
解けない:#160780 No.146 試験監督(1) - yukicoder
何故かWAを連発して解けない。
read n; awk '{mo=1000000007; ret+=(int(($1+1)/2)%mo*($2%mo))%mo; ret=ret%mo}END{print ret%mo}'
#160773 No.427 テレビ - yukicoder
空白に*4-3*という文字列をねじ込んで、電卓コマンドにぶちこむ。
read s; a=`echo $s | sed 's/ /*4-3*/'| bc`; [ $a -eq 0 ] && echo YOKO || echo TATE;
#160767 No.486 3 Straight Win(3連勝) - yukicoder
OOOの始めをEに変更、XXXの始めをWに変更した後、awkで1文字ずつ見ていって始めにEかWを見つけたらそこでEASTかWESTを出力して終了もし見つからなければNAを出力して終了。もうちょい綺麗にならないかな。
勉強したこと: awkは1-index, $0は文字列なので、もし添字参照したいならsplit($0, s, “”)で配列sに変換する必要がある。
sed 's/OOO/E/' | sed 's/XXX/W/' | awk '{split($0, s, ""); for (i = 1; i <= length(); i++) {if (s[i] == "E") {print "East"; exit 0 } else if (s[i] == "W") {print "West"; exit 0}} print "NA" }'
#160765 No.436 ccw - yukicoder
cとwの数を以下の方法で数える:cを見つけたら1行ずつ全列挙して、隣接同一文字列をまとめて、その1列目のみを抽出。その後、cの数-1とwの数を比較して、minの方を出力。もうすこし綺麗にならないかな。
勉強したこと: 四則演算は$( ($a-1) )のように実行可能。
read s; cnum=`echo $s | grep -o c | uniq -c | awk '{print $1}'`; wnum=`echo $s | grep -o w | uniq -c | awk '{print $1}'`; if [ $(($cnum-1)) -lt $wnum ]; then echo $(($cnum-1)); else echo $wnum; fi
#160760 No.485 方程式のお勉強 - yukicoder
awkで試しに割り算してみて、出力に小数点が入っているかをawkの検索を使って判定。
勉強したこと: awkの中のエスケープはバックスラッシュが2つ必要
awk '{print $2/$1}' | awk '{if ($1~"\\.") {print "NO";} else {print;}}'
#160548 No.495 (^^*) Easy - yukicoder
(^^*)と(*^^)を1行ずつ全列挙して、カウントして、もしなければ空文字列の代わりに0を出力する。その後、1行に連結して、改行する。
勉強したこと: ()でくくると連結した入力が入ったと見なされる。
read s ( echo $s | grep -o '\(\^\^\*\)' | uniq -c | awk '{print $1;f=1}END{if(!f)print 0;}'; echo $s | grep -o '\(\*\^\^\)' | uniq -c | awk '{print $1;f=1}END{if(!f)print 0;}'; ) | tr '\n' ' ' echo
#160755 No.494 yukicoder - yukicoder
yukicoderから入力文字列の文字を全削除して残ったものを出力。
勉強したこと: 特になし
read s; echo yukicoder | tr -d $s
#160753 No.289 数字を全て足そう - yukicoder
アルファベットを全削除した後、全文字のあとに+を追加して、最後に0を追加して、電卓に突っ込む
勉強したこと: 特になし
tr -d '[[:alpha:]]' | sed 's/./&+/g' | sed 's/$/0/g' | bc
#160764 No.476 正しくない平均 - yukicoder
1行目の積を計算する。次に2行目の総和を計算するために、空白文字を全て+に変換した後、電卓にぶちこむ。積と和を比較する。
勉強したこと: 特になし
read x y; a=$((x*y)); read s; b=`echo $s | tr ' ' '+' | bc`; if [ $a -eq $b ]; then echo YES; else echo NO; fi
#160763 No.477 MVP - yukicoder
bashの$(())を使って適当に計算。 勉強したこと: 特になし
read a b; echo $((($a+$b+1)/($b+1)))
#160761 No.480 合計 - yukicoder
“n*(n+1)/2"という文字列をechoで作って、電卓にぶちこむ。
勉強したこと: 特になし
read n; echo $n '*(' $n '+1)/2' | bc
#160772 No.481 1から10 - yukicoder
10を文字aにして、空白文字を消したものsを構築。123456789aからsを消去して、空白文字を消したものが、aかどうかをチェックして、aなら10を出力そうでなければそのまま出力。もうちょい綺麗にならないかな。
勉強したこと: 特になし
read s; p=`echo $s | sed 's/10/a/' | tr -d ' '`; ret=`echo "123456789a" | tr "$p" " " | tr -d ' '`; [ a = "${ret}" ] && echo 10 || echo ${ret};
#160787 No.159 刺さらないUSB - yukicoder
awkで小数計算するだけ。
勉強したこと: 特になし
awk '{p=$1;q=$2;if ((1-p)*q<p*(1-q)*q){print "YES"} else {print "NO"}}'
#160782 No.431 死亡フラグ - yukicoder
3 1に分割して、それぞれの行での総和を計算した後、横一列に連結して、awkで条件判定。
勉強したこと: 特になし
fold -w 6 | awk '{for(i=1;i<=NF;i++)a+=$i;print a;a=0}' | xargs | awk '{if ($1 < 2 || $2 == 1) print "SURVIVED"; else print "DEAD"}'
TopCoder SRM 698 Div1 Medium IntersectingConvexHull
数え上げで全事象の取り方をミスって死んだ。こんなこともあるのか。 高校数学で場合の数が大嫌いだったしなあ。
「初心者向け」NAS Synology DS216jが全くセットアップできずに4時間経過した話
愚痴
誰かに僕の思考回路をデバッグしてもらいたい。
僕がバグを引き寄せる体質であるように思える。
今まで、何かOSのインストールとか、アプリのインストールに成功した経験がほとんど無い。
競プロとか研究ではプログラミングがそれなりにできているはずだが、なぜか管理者能力の才能がほんっっっっっっっっっっっっっっっっとうに無くてイライラする。
普通のエンジニアはなんで普通に問題解決してるの?僕が馬鹿なの?
概要
2万円のNASを買って構築しようとしたが、僕の管理者能力がなさすぎて全く手も足も出ず、無為な時間を過ごしました。
理情のネットワークの授業もきちんと優取ったけど、ネットワーク管理者能力ってそういうものでないように感じる。 普通に考えて、「これをやれば管理者能力が身につきます」みたいな書物が今日本にないのでは? DNSってどこに有るの???どうやって調べるの???みたいなところでわからない。一体何でこんなにスキルが身につかないのか?
逆に、おすすめの本とか競プロみたいな基盤があるなら教えてください。 CTFはいろいろ教えてもらったけど、ネットワーク系は一個もACできない程度の人間ですが。
なんでNASを買ったのか
データストレージの必要性を感じたので、3TBのHDDを家に置くことにした。
モチベは、3TB HDDはなんかexFATとかいうよくわからんデータの持ち方をしているらしく、Ubuntu 16.04ではデフォルトで認識されない。 なので、僕はいつもデータストレージにアクセスするためにWindowsを立ち上げてうにょうにょせざるを得ず、イライラがマッハだったから。
未解決の問題として、
- Ubuntuで3TB HDDをマウントする方法ってあるの??どんなにググってもできないんですけど。
NASの選定
僕は管理者能力が皆無であることを自覚しているので、少し高くても、「誰でも初心者でもセットアップが簡単☆」みたいなNASを選ぶことが必要だと確信していた。 それをメインの要望仕様として、Synology DS216jを購入した。
で、結局全く動かなかった。
何が動かないのか
まずNASにOSを入れるところからやる必要があるらしい。 しかしこれは「初心者向け」なので、以下にアクセスするとウェブブラウザからデバイスの検知・OSのインストールまで全てやってくれるらしい!
まあもちろん失敗します。知ってました。NASが見つかりません。 どうやら、ローカルのIPを検知して、ポートにつないでくれるみたいなページも紹介されています。
http://diskstation.local:5000/
「diskstation.local のサーバー DNS address が見つかりませんでした。」とエラーが吐かれて死にます。僕は何かネットワーク設定ができた経験がないので、全く期待していませんが。
まあ、DNSで失敗しているっぽいので、diskstation.localという部分を実際のNASのIPアドレスに変更すると良いという話がありました。期待はしていませんがやってみましょう。はいだめでした。
しょうがないので、「もし見つからない場合は…」という指示に従い、以下のAssistant ToolみたいなものをUbuntuにインストールして、そっちから設定しようとします。 やっとNASが見つかりました!良かった、これでインストールできると思ったら罠なのはわかりきったことです。 OSのバージョンが違う云々と言われて、インストールできませんでした。実際ダウンロードしたOSが違ったので、正しいOSをダウンロードして、なんとかちょっと先に進むことができました。
https://www.synology.com/ja-jp/support/download/undefined
OSのインストールを始めようとします。なんとなくパスワードを設定してくださいなどと言われていい感じになったのですが、もちろん失敗します。OSのインストール時に「Failed to create connection.」とか言われて死にます。 ネットワークの手動設定が推奨されており、そちらを使っていたのが悪かったのでしょうか?自動設定にしてやりますが、やはり同じエラーが起きて、全く先に進みません。
HDDをフォーマットすれば行けるという情報があったので、とりあえずクイックフォーマットして再度チャレンジしましたが、全く状況は変わりません。
ローカルネットワークの問題だとするならば、とりあえずNASとパソコンを直接LANケーブルでつなげればいいよ、という話がありました。 LANケーブルをつないでも、有線の先のデバイスに繋ごうと頑張っている感じはありましたが、結局全く繋がりません。Windows, Ubuntu両方で試しましたがダメっぽい。
このへんで発狂して、NASの設定を諦めました。さよなら20000円。
他の障害
このデバッグ中に、いくつかよくわからないことが起きていることに気づきました。
- 2台のHDDのうち、片方がそもそも外付けHDDとして認識されないんですけど
- 新居のWirelessが、WindowsからのみDNS障害が起きている→nslookupするとどうやらDNSサーバがIPv6?→IPv6を切ると任意の名前解決ができなくなる
- そもそもルータがいつもなんとなく不安定な気がする→どうやってデバッグするの??
感想
一体普通の人はどうやっておうちでインターネットを使っているのでしょうか?
TopCoder SRM 699 Div1 Medium FromToDivisible
なんかこう、始めからパッと高速なコードがかけるというのが大事な感じがする。 全然コーディングイディオムが足りないなあ。
でも解答一回も見ないでMedが通せたのは良いこと。