はむこの勉強記録

http://bit.ly/2ktf20t の写し

【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*という文字列をねじ込んで、電卓コマンドにぶちこむ。

勉強したこと: bashで参考演算子もどき。

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"}'