🚀

第63回シェル芸勉強会の問題をPythonワンライナーで解く

2023/02/26に公開

はじめに

2023年2月25日に開催された第63回シェル芸勉強会にオンラインで参加させていただきました。基本的にはシェルのワンライナーで問題を解いていたのですが、Pythonのワンライナーでも挑戦してみたので、いくつか紹介しようと思います。邪道です。すみません。よろしくお願いいたします。

注意

シェル芸勉強会の問題は、基本的にはシェルのワンライナーで解くことが推奨されていると思いますので、お気をつけくださいませ。

YouTube配信

https://youtu.be/zEmqu1UP3SY

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()labelrefを削除します。最後に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