🚀
第63回シェル芸勉強会の問題をPythonワンライナーで解く
はじめに
2023年2月25日に開催された第63回シェル芸勉強会にオンラインで参加させていただきました。基本的にはシェルのワンライナーで問題を解いていたのですが、Pythonのワンライナーでも挑戦してみたので、いくつか紹介しようと思います。邪道です。すみません。よろしくお願いいたします。
注意
シェル芸勉強会の問題は、基本的にはシェルのワンライナーで解くことが推奨されていると思いますので、お気をつけくださいませ。
YouTube配信
Q1 : 九九の合計
問題文
1x1〜9x9の九九の答えをすべて足し合わせてください。
回答
python3 -c 's=0;[[s:=s+i*j for j in range(1,10)] for i in range(1,10)];print(s)'
説明
二重のfor文で1x1~9x9の全ての組み合わせを作って、足し合わせています。
Q2 : おつりの出し方
問題文
9132円の支払いに10000円札で払ったときのおつりの出し方をひとつ(できるひとはたくさん)画面に出力してみてください。
回答
python3 -c 'a=10000-9132;z=[500,100,50,10,5,1];[[b:=int(a/i),print(str(i)+"円:"+str(b)),a:=a-i*b] for i in z]'
説明
おつりの種類のリスト(z)を作成して、大きいほうから順に枚数を算出しています。勉強会配信では、おつりの全通りを試す方法が紹介されていて、とても勉強になりました。
Q3 : LaTeX原稿の調査
問題文
次のLaTeXの原稿で、\labelと\refがペアになっていない(参照していない/されていない)ものを抽出してください。
回答
cat S*a/v*63/g*u.tex | python3 -c 'import sys,re;a=[i for i in sys.stdin];b=[re.findall("label{.*}|ref{.*}",i) for i in a];b.sort();c=[i[0] for i in b if i!=[]];d=list(set(c));[print(re.findall("{.*}",i)[0]) for i in d];' | sort | uniq -u | tr -d '{}'
説明
re.findall()
でlabel{}
とref{}
を抜き出します。その後にset
を使って重複を削除します。さらにre.findall()
でlabel
とref
を削除します。最後にsort | uniq -u
で完成です。
Q4 : 東西南北を探索
問題文
次のファイルから、「東西南北」がワンセットになっている部分を探してください。東西南北の順番は問いません。
回答
cat S*a/v*63/t*n.txt | python3 -c 'a=input();b=[[a[i+j] for j in range(4)] for i in range(len(a)-3)];[print(i+1) for i in range(len(b)) if b[i][0]!=b[i][1] and b[i][0]!=b[i][2] and b[i][0]!=b[i][3] and b[i][1]!=b[i][2] and b[i][1]!=b[i][3] and b[i][2]!=b[i][3]]'
説明
前処理として、文字列を前から順に4文字ずつ切り出してリストに格納します。その後、前処理したリストの中身が「東西南北」ワンセットになっているかどうか判定しています。
Q5とQ6 : リバーシ問題
sedで置換する問題なので、省略させていただきます。
おわりに
第63回シェル芸勉強会の問題Q1~Q4をPythonワンライナーで解きました。シェル芸勉強会はとても勉強になるので、次回も参加させていただきたいと思います。そして、今度こそはシェルのワンライナーで解きたいと考えております。勉強会もLTもおもしろかったです。ありがとうございました。
Discussion