全「???48」を生成してみる
課題1
- 大文字のアルファベット3文字 + '48' の全パターンのリストを作る
解答 その1
単純にループの入れ子で
# まず大文字のアルファベットのリストを作る al = [chr(a) for a in range(65, 91)] # 全パターンのジェネレータ def akb(): for a1 in al: for a2 in al: for a3 in al: yield a1 + a2 + a3 + '48' # リストで取得 allptns = [p for p in akb()] allptns.index('AKB48') #=> 本家は261番目に出てきた
解答 その2
リスト内包表記の入れ子
# al は大文字アルファベットのリスト # 全パターンのリスト allPtns = [a1 + a2 + a3 + '48' for a1 in al for a2 in al for a3 in al]
解答その3
アルファベットの桁数を指定できるようにしてみる
# al は大文字アルファベットのリスト # 2個のリストを組み合わせる関数 getprd = lambda list1, list2 : [a1 + a2 for a1 in list1 for a2 in list2] # 全パターンのリストを生成する関数 def akb(num): temp = [''] def _akb(tl, n): if n == 0: return getprd(tl, ['48']) else: return _akb(getprd(tl, al), n - 1) return _akb(temp, num) allPtns = akb(3)
なんかいまいちだなー。もっとかっこよい解答求む。
課題2
課題1に制限を加える
アルファベット3文字は別々のアルファベットを使う(AAAとかAABはダメ)
解答
課題1の解答3のリストを組み合わせる関数(getprd)を以下に修正すれば対応できる。
# 2個のリストを組み合わせる関数(重複省く) getprd = lambda list1, list2 : [a1 + a2 for a1 in list1for a2 in list2 if a2 not in a1]
課題2の場合は本家は216番目に出てきた。
やってみた感想
ループとか関数とか考えながら書けるので、初めてのプログラミング言語に取り組むときはHello Worldよりこの課題やると楽しそう。
別解
ちなみに標準モジュールのitertoolsを使えば以下のように書ける。
至れり尽くせり!
import itertools # al は大文字アルファベットのリスト # 課題1 allptns1 = [''.join(a) + '48' for a in itertools.product(al, al, al)] # 課題2 allptns2 = [''.join(a) + '48' for a in itertools.permutations(al, 3)]