ケース順列


27

大文字と小文字のすべての順列を生成できる場合、大文字と小文字を区別せずに比較する必要があるのは誰ですか?誰も!それが答えです。誰もしません。あなたの仕事はこの偉業を達成することです。与えられた入力に対して大文字/小文字のすべての可能な順列を生成します。

入力

印刷可能な標準ASCII文字列。入力をすべて小文字と見なしてはなりません。入力は常に少なくとも1文字です。

出力

入力された文字列の大文字と小文字のすべての置換(重複なし)。これは、小さいバージョンと大きいバージョンの文字のみを変更する必要があります(数字は同じままです)。各順列は、文字列または文字のリストとして出力する必要があります。シングルトン文字列のリストは許可されていません。

a1a
['a1a', 'a1A', 'A1a', 'A1A']

abc
['abc', 'abC', 'aBc', 'aBC', 'Abc', 'AbC', 'ABc', 'ABC']

Hi!
['hi!', 'hI!', 'Hi!', 'HI!'] 

得点

これはであるため、最短回答(バイト単位)が優先されます。

おもしろいので、拡張アスキー文字を処理するのにどれだけの労力がかかるかを見てみましょう。追加のテストケースを次に示します。

ž1a -> ['ž1a', 'ž1A', 'Ž1a', 'Ž1A']

(プログラムはこれをサポートする必要はありません)


10
興味深いUnicodeテストケース:Σ['Σ', 'σ', 'ς']
n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳

文字列の代わりに文字のリストを使用できますか?たとえば、Hi!与えられた場合、それは{('H', 'i', '!'), ('h', 'I', '!'), ('h', 'i', '!'), ('H', 'I', '!')}受け入れられますか?
DJMcMayhem

@DrGreenEg​​gsandHamDJ 文字のリストはデフォルトで許可されています。Pythonでは、これらはシングルトン文字列ですが、これは異なります。
デニス

1
@ n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳はさらに興味深いのはΣ、単語の先頭の大文字バージョンであり、単語σの先頭または中間ςでは小文字バージョンですが、単語の末尾ではないこと、および単語の末尾のみでの小文字バージョンです。
FantaC

1
@DomHastingsリストのように、出力をスペースで区切るだけですか?それは理にかなっているようです。
ポケ

回答:


11

Pyth、 13 12 11

{msrVQd^U2l

Leaky Nunのおかげで1バイト!

ジャクベのおかげでもう一バイト!

ここで試してみるか、テストスイートを実行してください

[0, 1]入力文字列の長さと同じ回数だけリストのデカルト積を取ることで、リストの真/偽の値のリストを作成します。したがって、各サブリストの長さは入力文字列と同じです。次に、r関数を入力とリストにベクトル演算として適用し、r letter value各サブ要素を取得します。r2番目の引数ではゼロが小文字になり、1つでは大文字になります。これにより、文字以外で重複が作成されます。つまり、結果から重複を削除する必要があります。



@LeakyNunああ、私はそれを試しましたが、何らかの理由Mで両方で使用することを考えましたs.n、同じ長さでした。私は数えるのが得意です。とにかく、今すぐ編集、ありがとう!
FryAmTheEggman

はい、同じ長さです。最後の部分を変更しました
漏れ修道女

{msrVQd^U2l少し短くなります。
寂部

@ジャクベありがとう!使用Vは非常に卑劣で、ここでそれについて考えたことはないと思います。
FryAmTheEggman

8

ゼリー、6 バイト

żŒsŒpQ

これは、左引数として文字列を予期し、文字列のリストを返す単項リンク(関数)です。

非ASCII文字を処理します。オンラインでお試しください!

使い方

żŒsŒpQ  Monadic link. Argument: s (string)

 Œs     Swapcase; change the case of all letters in s.
ż       Zipwith; pair each character with itself with changed case.
   Œp   Take the Cartesian product of all pairs.
     Q  Unique; deduplicate the Cartesian product.

3
rekt他の言語を取得します。p–
Adnan

2
コードページを見た後でも、コードゴルフのチャレンジで最も少ないバイト数のJelly を一貫して見ているという事実に驚かされます。
ポケ

5

Python、 74 71バイト

f=lambda s:s and{r[0]+t for r in{s,s.swapcase()}for t in f(s[1:])}or{s}

非ASCII文字を処理します。Ideoneでテストします。


5

Oracle SQL 11.2、276バイト

WITH v AS(SELECT SUBSTR(:1,LEVEL,1)c,ROWNUM p FROM DUAL CONNECT BY LEVEL<=LENGTH(:1))SELECT w FROM(SELECT REPLACE(SYS_CONNECT_BY_PATH(c,','),',','')w FROM(SELECT UPPER(c)c,p FROM v UNION SELECT LOWER(c),p FROM v)START WITH p=1CONNECT BY PRIOR p=p-1)WHERE LENGTH(:1)=LENGTH(w);

ゴルフをしていない

WITH v AS
( -- Split input into an array of characters 
  SELECT SUBSTR(:1,LEVEL,1)c,ROWNUM p FROM DUAL CONNECT BY LEVEL<=LENGTH(:1)
)
SELECT w 
FROM   ( -- Build every string combination
         SELECT REPLACE(SYS_CONNECT_BY_PATH(c,','),',','')w 
         FROM   ( -- Merge upper and lower arrays, keep same position for each character, it allows to mix cases
                  SELECT UPPER(c)c,p FROM v UNION SELECT LOWER(c),p FROM v
                )
         START WITH p=1          -- Start with first character (either lowercase or uppercase)
         CONNECT BY PRIOR p=p-1  -- Add the next character (either lowercase or uppercase)
       )
WHERE LENGTH(:1)=LENGTH(w); -- Keep only full strings

地獄のようにUい、よりゴルファーでなければなりません。


4

05AB1E、17バイト

コード:

vyDš‚N0Êiâvy˜J})Ù

説明:

vy                     # for each character in input
  Dš‚                  # create a pair of different case, eg: ['ž', 'Ž']
     N0Êiâ             # for all pairs but the first, take cartesian product
                         result will be a list of layered lists eg: [['ž', '1'], 'a'] 
            vy         # for each such list
              ˜J}      # deep flatten and join as a string eg: ž1a
                 )Ù    # wrap in array and remove duplicates

オンラインで試す


4

Brachylog25 22バイト

:ef:1fd.
:2ac.
@u.|@l.

これは、Prologの小文字/大文字の述語と同様に機能します。したがって、非ASCII文字でも機能します。

?- run("ž1a",Z).
Z = ["Ž1A", "Ž1a", "ž1A", "ž1a"] .

説明

これを投稿している時点での他のすべての回答とは異なり、これはデカルト積アプローチをまったく使用していません。

  • メイン述語

    :ef       Split the Input string into a list of 1-char strings
       :1f    Find all valid outputs of predicate 1 with the previous list
              of outputs as input
          d.  Unify the Output with that list excluding all duplicates
    
  • 述語1

これは、入力の各文字に大文字または小文字を適用するために使用され、1つの可能な順列を計算します。メイン述部のこの述部でfindallを使用すると、考えられるすべての置換(いくつかの重複を含む)を計算できます。

    :2a       Apply predicate 2 on the each element of the Input
       c.     Unify the Output with the concatenation of the elements of
              the previous list
  • 述語2

これは、文字列の文字を大文字または小文字に変換するために使用されます。

    @u.       Unify the Output with the uppercase version of the Input
       |      Or
        @l.   Unify the Output with the lowercase version of the input


3

MATL、13バイト

tYov!Z}N$Z*Xu

オンラインでお試しください!

説明

t       % Implicit input string. Duplicate
Yo      % Change case of string
v       % Concatenate as a 2xN char array, where N is input length
!       % Transpose: Nx2 char array. Each row has different case, if letter
Z}      % Split into rows: gives N strings of 2 chars. Each char has different 
        % case if it's a letter, or is repeated otherwise
N$      % Specify N inputs for next function
Z*      % Cartesian product of the N strings. Each combination is a row.
        % Repeated chars (i.e. non-letters) give rise to duplicate rows.
Xu      % Remove duplicate rows. Implicit display

3

JavaScript(Firefox 30-57)、92 90バイト

f=([c,...s])=>c?[for(t of f(s))for(d of new Set(c.toUpperCase()+c.toLowerCase()))d+t]:['']

編集:new Set文字列から一意の文字をうまく抽出するため、2バイトを保存しました。


いつ!c sでもある[]ので、[s]代わりに戻ることができます
l4m2

f=([c,...s])=>c?[for(t of f(s))for(d of new Set(c.toUpperCase()+c.toLowerCase()))d+t]:[s]
-l4m2

3

Perl 6、37バイト

{[X~] '',|.comb.map:{unique .lc,.uc}}

それを試してみてください

説明:

{
  [X[~]]                     # cross combine using &infix:<~> operator
    '',                      # empty string so that 1 character strings work
    |                        # flatten the following into outer list
      .comb                  # get every character from input string
      .map:                  # and map it with:
        { unique .lc, .uc }
}

テスト:

#! /usr/bin/env perl6

use v6.c;
use Test;

my &case-permutation = {[X~] '',|.comb.map: {unique .lc,.uc}}

my @tests = (
  'a1a' => <a1a a1A A1a A1A>,
  'abc' => <abc abC aBc aBC Abc AbC ABc ABC>,
  'Hi!' => <hi! hI! Hi! HI!>,
  'ž1a' => 1a ž1A Ž1a Ž1A>,
);

plan +@tests;

for @tests -> $_ (:key($input),:value($expected)) {
  is case-permutation($input).sort, $expected.sort, .gist
}
1..4
ok 1 - a1a => (a1a a1A A1a A1A)
ok 2 - abc => (abc abC aBc aBC Abc AbC ABc ABC)
ok 3 - Hi! => (hi! hI! Hi! HI!)
ok 4 - ž1a => (ž1a ž1A Ž1a Ž1A)

あなたは私が思うバイトを保存することができます:({[X~] '',|.comb.map:{unique .lc,.uc}}後にスペースを削除map:
コナーオブライエン


2

Python、69バイト

import itertools as i;f=lambda s:set(i.product(*zip(s,s.swapcase())))

文字列ではなくシングルトン文字列のタプルを返します。それが許可されているかどうかはわかりません。
デニス

from itertools import*;i.
バイトコマンダー

OPは、シングルトン文字列は許可されていないと述べています。この回答を更新する必要があります。
DJMcMayhem

出力要件はあいまいです(それでも)。これを投稿した後、OPはコメントで明確になりました。この回答を削除するだけですか?適切なプロトコルは何ですか?
RootTwo

2

実際には、28バイト

;╗l2r∙`"'Ö*£"£M╜@Z"iƒ"£MΣ`M╔

オンラインでお試しください!

このプログラムは、Python 3の魔法のおかげで、非ASCII文字を処理できます。

説明:

;╗l2r∙`"'Ö*£"£M╜@Z"iƒ"£MΣ`M╔
;╗                            save a copy of input to reg0
  l                           length of input
   2r                         [0,1]
     ∙                        Cartesian product with self (length of input) times
      `                  `M   map:
       "'Ö*£"£M                 push `Ö` (swapcase) if 1 else `` for each value in list
               ╜@Z              zip with input
                  "iƒ"£M        swap the case of those values
                        Σ       join string
                           ╔  unique elements

2

C 229252バイト

i,n,j,k,l;f(char *s){l=strlen(s);for(i=0;i<l;i++)s[i]=tolower(s[i]);int v[l];for(i=0;i<l;i++)v[i]=0;for(i=0;i<pow(2,l);i++){n=i,k=0;for(;n;k++){v[k]=n;n/=2;}for(j=0;j<l;j++){v[j]%=2;if(v[j])s[j]=toupper(s[j]);else s[j]=tolower(s[j]);}printf("%s ",s);}}

ゴルフされていないバージョン:

void f(char *s)
{
  int i,num,k,l=strlen(s);
  for(i=0;i<l;i++)
     s[i]=tolower(s[i]);

   int v[l];
   for(i=0;i<l;i++) 
     v[i]=0;   

   for(i=0;i<pow(2,l);i++)
   {
      num=i,k=0;
      for(;num;k++)
      {
         v[k]=num;
         num/=2;        
      } 

      for(int j=0;j<l;j++)
      {
        v[j]%=2;

        if(v[j])
         s[j]=toupper(s[j]);
        else
         s[j]=tolower(s[j]);

      }
      printf("%s \n",s);       

   } 
}

説明:

  • 文字列を受け入れ、文字列を小文字に変換します。
  • 文字列の長さと等しい長さの整数配列を宣言します。ゼロで埋めます。
  • 0から2^strlen(s)2進数の数値をint配列に格納します(3バイト文字列の場合:000,001,010 ... 111)
  • ある位置のビットが設定されているかどうかに応じて、ケースを切り替えます。
  • 可能なすべての組み合わせの文字列を出力します。

オンラインでお試しください!


10年前のようにvb6で最初にこれを行ったとき、私のソリューションはこれに似ていると思います。あなたはいくつかの思い出を持ち帰りました;)
ポケ

@Pokeうれしかった!:)
アベルトム

ゴルフのいくつかのこと:i++forループを削除して++直接使用するとともに、forループ内にいくつかのパーツを配置して、可能であればブラケットとセミコラムを削除します。また、パラメーター内のスペースを削除し、最後にternary-if割り当てを使用できます。合計:i,n,j,k,l;f(char*s){l=strlen(s);for(i=0;i<l;)s[i]=tolower(s[i++]);int v[l];for(i=0;i<l;)v[i++]=0;for(i=0;i<pow(2,l);){for(n=i++,k=0;n;n/=2)v[k++]=n;for(j=0;j<l;j++){v[j]%=2;s[j]=v[j]>0?toupper(s[j]):tolower(s[j]);}printf("%s ",s);}}-20バイト/ 232バイト
ケビンクルーイッセン

1

フーン、242バイト

|=
t/tape
=+
l=(reap (pow 2 (lent t)) t)
%+
roll
(gulf 0 (dec (lent l)))
|=
{a/@ b/(set tape)}
=+
%+
turn
(gulf 0 (dec (lent t)))
|=
n/@
=+
t=(snag n t)
=+
k=(trip t)
?:
=(0 (cut 0 n^1 a))
?:
=((cuss k) t)
(cass k)
(cuss k)
t
(~(put in b) -)

ゴルフをしていない:

|=  t/tape
=+  l=(reap (pow 2 (lent t)) t)
%+  roll  (gulf 0 (dec (lent l)))
|=  {a/@ b/(set tape)}
    =+  %+  turn  (gulf 0 (dec (lent t)))
      |=  n/@
      =+  t=(snag n t)
      =+  k=(trip t)
      ?:  =(0 (cut 0 n^1 a))
        ?:  =((cuss k) t)
              (cass k)
        (cuss k)
      t
    (~(put in b) -)

残念ながら、これがどれほど小さくなるかはわかりません。

最初に、のl2 ^(長さt)の繰り返しを含むリストに等しく設定しtます。Hoonにはfacstdlibに関数はありませんが、2 ^ nは常にnよりも大きいため、単純に大きなリストにマップして、set(ハッシュマップ)をエントリの重複を排除します。

次に、リスト[0 ..(長さl)]を折りたたみ、aに累積します(set tape)lまた、何回繰り返されるかを知る必要があるため、直接マッピングする代わりにこれを行う必要があります(a)、ますが、Hoonが純粋な言語であるためにアキュムレータを単純にインクリメントすることはできません。

[0 ..(長さt)]にマッピングし(再び現在のインデックスを取得します)、t文字列のn番目の文字に設定し、n番目のbyeの有無を確認しa、大文字と小文字を切り替えます(cussまたはcass。か否か)。このマップの戻り値の型はtapeです。

次に、文字列をハッシュマップに入れ、すべての文字列のハッシュマップを返します。


「2 ^ nは常にnよりも大きい!」。実際n! > 2^nnは、少なくともそれが提供され4ます。(帰納法で証明、ベースケース付きn=4。)en.wikipedia.org/wiki/…–
mathmandan

1

C、216バイト

k,i,j,p,n,m;z(char *c){n=-1;m=0;while(c[++n])if(c[n]>64&c[n]<90)c[n]+=32;else if(c[n]<'a'|c[n]>'z')m++;k=1<<(n-m);for(j=0;j<k;j++){for(i=0;i<n;i++){p=1<<i;putc((j&p)==p?toupper(c[i]):c[i],stdout);}putc(0xa,stdout);}}

これは異なるアプローチで、同じです、他のCの回答アプローチです。

これを削除し、コメントとして他の回答の下に配置する必要がありますか?

Ungolfedバージョンで説明しましょう

k,i,j,p,n,m;
z(char * c) {
    int n=-1;       // We start at -1 because of forward incrementation
    int m=0;        // this will count the characters we don't have to manipulate
    while(c[++n])   // go until we reach '\0'
    {
        if(c[n]>='a'&c[n]<='z')c[n]-=32; // If we are lower case, then convert
        else if(c[n]<'A'|c[n]>'Z')m++;   // If we are neigther lower case
                                         // nor upper, then make a note
    }

    // get 2 ^ ("length" - "number of invonvertibles")
    k=1<<(n-m); 
    for(j=0;j<k;j++) {      // go through the combinations
        for(i=0;i<n;i++) {  // for each combination go though the characters
            p=1<<i;         // for each character get it's bit position
            putc(
                // if the bit position is set (==1) 
                (j&p)==p ?
                   tolower(c[i]) // convert
                   : c[i], // else: don't
                stdout);
        }
        putc(0xa, stdout);  // print a newline
    }
}

1

Python3、96バイト

i=input().lower()
for l in{*__import__('itertools').product(*zip(i,i.upper()))}:print(*l,sep='')

パーティーに遅れたが、まだ行っていた。DLoscに、私が見逃したものを思い出させてくれて、ゴルフのヒントを教えてくれて、たくさんのバイトを節約してくれてありがとう。:)


@DLoscヒントをありがとう!これらの機能を追加します。:)
ブロック

ヒントをありがとう。本当に助かりました。set()の代わりに{}を使用すると、ループは製品ではなくセットを通過します(それが理にかなっていることを願っています)。少なくとも私の実装では(AndroidでQPythonを使用しています)、{}はリストをセットに変換するのではなく、セット内にリストを配置するだけです。
ブロック

両方の方法を試しましたが、{* expr}を実行するとSyntaxErrorが発生します。
ブロック

ああ。それが理由です。QPythonの最新バージョンは3.3または何かにあります。
ブロック

どうぞ:オンラインでお試しください!(また、バグを修正し、スペースをゴルフしました。)
DLosc



1

Tcl、165 181バイト

set n -1
while {[incr n]<1<<[llength [set s [split $argv {}]]]} {puts [join [lmap c $s b [split [format %0[llength $s]b $n] {}] {string to[expr $b?{u}:{l}] $c}] ""]}

sergiolによる改善。前の答え:

set s [split $argv {}]
set n -1
while {[incr n]<1<<[llength $s]} {set r ""
foreach c $s b [split [format %0[llength $s]b $n] {}] {set r $r[string [expr $b?{tou}:{tol}] $c]}
puts $r}

出力テキストを作成するときに、2進数を使用して大文字/小文字を選択します。



@sergiolそれはあなた自身の答えとしてそれを投稿し、素晴らしいことに対して良い信用を得るべきである私のものとは十分に異なっています。
Dúthomhas

いいえ。回答のごく一部のみを変更しました。アプローチも重要なアルゴリズムも変更しなかったため、私の観点では、新しい回答を作成する必要はないと考えました。そして、同じ目的のためにあなたのオリジナルとして短いアルゴリズムを得ることができるとは思いません!
sergiol



0

JavaScript(ES6)、103

非ASCII文字を処理します

(a,r=new Set)=>a?f(a.slice(1)).map(v=>(C=o=>r.add(a[0][`to${o}erCase`]()+v),C`Upp`,C`Low`))&&[...r]:[a]

テスト

f=(a,r=new Set)=>a?f(a.slice(1)).map(v=>(C=o=>r.add(a[0][`to${o}erCase`]()+v),C`Upp`,C`Low`))&&[...r]:[a]

function test() { O.textContent = f(I.value).join('\n') }

test()
<input id=I oninput='test()' value='ž1a'>
<pre id=O></pre>

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.