発端
2014-04-22 21:06:57 via YoruFukurou to @sugyan
...
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
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すれば最終的に全通り出るよね、的な。追記
@dankogaiさんから。ありがとうございます。
perl -E '$_=pop;for$i(1..2**length){s/./1<<pos()&$i?uc$&:lc$&/eg;say}' kamipo # <@sugyan URL <@kamipo
2014-04-25 01:45:22 via Twitter for Mac to @sugyan
正規表現を使って各文字にマッチさせつつ
pos
関数を使ってその文字の位置を取得して$&
を変換、と…。なるほど〜、、pos
って知らなかった…