2014-04-25
64通りのkamipoを出力する
発端
2014-04-22 21:06:52 via Twitter for Mac to @kamipo
2014-04-22 21:06:57 via YoruFukurou to @sugyan
2014-04-22 21:10:34 via Twitter for Mac to @kamipo
2014-04-22 21:10:59 via Twitter for Mac to @kamipo
2014-04-22 21:11:04 via Twitter for Mac to @kamipo
2014-04-22 21:11:10 via Twitter for Mac to @kamipo
2014-04-22 21:11:33 via Twitter for Mac to @kamipo
...
kamipo botの脆弱性が発見された
32通りの空mentionで同時攻撃可能
@sugyan 32じゃねーや64かw
2014-04-22 21:13:46 via Twitter for Mac to @sugyan
お題
入力として与えられたアルファベット文字列の、小文字・大文字での全組み合わせを出力する
入力がkamipo
なら、
kamipo kamipO kamiPo kamiPO kamIpo kamIpO kamIPo kamIPO kaMipo kaMipO kaMiPo kaMiPO kaMIpo kaMIpO kaMIPo kaMIPO kAmipo kAmipO kAmiPo kAmiPO kAmIpo kAmIpO kAmIPo kAmIPO kAMipo kAMipO kAMiPo kAMiPO kAMIpo kAMIpO kAMIPo kAMIPO Kamipo KamipO KamiPo KamiPO KamIpo KamIpO KamIPo KamIPO KaMipo KaMipO KaMiPo KaMiPO KaMIpo KaMIpO KaMIPo KaMIPO KAmipo KAmipO KAmiPo KAmiPO KAmIpo KAmIpO KAmIPo KAmIPO KAMipo KAMipO KAMiPo KAMiPO KAMIpo KAMIpO KAMIPo KAMIPO
と64通りの出力を。
回答
80byte。Deparseするとこんなかんじ。
use feature 'say'; @a = split(//u, pop @ARGV, 0); foreach $i (1 .. 2 ** @a) { say join('', map({$i >> $_ & 1 ? uc $a[$_] : lc $a[$_];} 0 .. $#a)); }
基本戦略として、0
から2の[入力文字数]乗
までの数字を順に挙げていき、n桁目のビットがtrueであればn文字目は大文字、falseであればn文字目は小文字、というマッピングをすることで全通りを得る、というかんじで。
splitした後にfor文まわしてmapで各文字を操作しているので、とても単純。
@sugyan ちょっとだけ短くなった perl -E '@a=split//,pop;for$i(1..2**@a){say map$i>>$_&1?uc$a[$_]:lc$a[$_],0..$#a}' kamipo
2014-04-22 22:25:13 via YoruFukurou to @sugyan
72byte。joinする必要なかったんや。mapの"{}"も省ける。
70byte。Deparseすると
use feature 'say'; foreach $i (1 .. 2 ** (@a = split(//u, pop @ARGV, 0))) { say map(($a[$_] & ~chr($i >> $_ & 1 and 32)), 0 .. $#a); }
引数のsplitは最初のfor文の式中に入れてしまえば1byte短くなる。あと入力が小文字なら、"\xDF"
でマスクかけてやればuc
関数を使う必要ないな、ということでchr(32)
もしくはchr(0)
の反転との論理積で大文字化と小文字化をしてみた。
68byte。Deparseすると
use feature 'say'; foreach $i (1 .. 2 ** (@a = split(//u, pop @ARGV, 0))) { say map(($a[$_] ^ ($i >> $_ & 1 ? $" : '')), 0 .. $#a); }
つまりは空文字もしくは"\x20"
との排他的論理和を取れば大文字・小文字の変換ができるじゃないか、ということで。"\x20"
すなわちスペース(" ")の変わりに特殊変数$"
を使うことで少しでも短く。
もっと別のアプローチでもっと短くできそうにも思えるのだけど思いつかない…。
反則技
ビット演算とか無視でとりあえず1/2の確率で大文字-小文字変換させて出力する、のを10000回くらい繰り返してからsortしてuniqすれば最終的に全通り出るよね、的な。
- 10 http://t.co/8UmCXUx6zX
- 8 http://t.co/eVZmLzIr3D
- 5 https://www.google.co.jp/
- 3 http://pipes.yahoo.com/pipes/pipe.info?_id=49361476efd1fe9761d9bbd6c3a05f4d
- 3 http://t.co/mIGMfOkXPX
- 2 http://kawamuray.hatenablog.com/entry/2013/11/03/180543
- 2 http://sugyan.com/
- 2 https://www.facebook.com/
- 1 http://ameblo.jp/odoriko-link/entry-11511369937.html
- 1 http://api.twitter.com/1/statuses/show/459356669000945664.json