大小写排列


27

当您能够生成大写和小写的每个排列时,谁需要不区分大小写地比较事物?没有人!那就是答案。没人做到。您的任务是实现这一壮举。生成给定输入的所有可能的大写/小写排列。

输入项

一串可打印的标准ascii字符。输入不应假定全部为小写。输入将始终至少为一个字符。

输出量

输入的字符串的每个大写和小写排列(无重复)。这只能更改大小版本的字符(数字将保持不变)。每个排列必须输出为字符串或字符列表。不允许使用单例字符串列表。

例子

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

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

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

计分

这是,因此最短的答案(以字节为单位)获胜。

有趣的是,看到要处理扩展的ascii字符将花费多少额外的精力,这是一个额外的测试用例:

ž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就像您有一个列表一样,您只是在用空格分隔输出?在我看来,这是合理的。

Answers:


11

Pyth, 13 12 11

{msrVQd^U2l

1个字节感谢Leaky Nun!

还要感谢Jakube!

在这里尝试或运行测试套件

我们通过使用列表的笛卡尔积[0, 1]乘以本身等于输入字符串长度的次数来创建列表True / False值的列表。因此,每个子列表的长度与输入字符串的长度相同。然后,我们将该r函数作为矢量操作应用到输入和列表上,以便获得r letter value每个子元素。r第二个参数为零时表示小写,第一个参数为大写时。这会在非字母上创建重复项,这意味着我们需要从结果中删除重复项。



@LeakyNun啊,我已经尝试过了,但是由于某种原因,我认为M两者都使用s并且.n长度相同。我似乎擅长数数。无论如何,现在编辑,谢谢!
FryAmTheEggman '16

是的,它们的长度相同,我只是更改了最后一部分
Leaky Nun

{msrVQd^U2l短一点。
贾库贝

@Jakube谢谢!使用起来V很偷偷摸摸,我想我在这里不会想到。
FryAmTheEggman '16

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
获取其他语言的信息:p
阿德南

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

丑陋的地狱,一定更适合打高尔夫球。


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

这用于在输入的每个字符上使用大写或小写,从而计算一个可能的排列。在主谓词中对该谓词使用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

4

Haskell,69 58字节

import Data.Char
mapM(\x->toLower x:[toUpper x|isAlpha x])

在线尝试!

编辑:@Angs保存11个字节。谢谢!


mapM(\x->toLower x:[toUpper x|isAlpha x])应该摆脱其他进口?
昂斯'18年

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]:['']

编辑:保存2个字节,因为new Set将很高兴地从字符串中提取唯一的字符。


什么时候!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:
Conor O'Brien '18年


2

Python,69个字节

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

这将返回单例字符串而不是字符串的元组。我不确定是否允许。
丹尼斯(Dennis)

使用from itertools import*;和忽略i.
Byte Commander

OP表示不允许使用单例字符串。您应该更新此答案。
DJMcMayhem

输出要求不明确(仍然是)。在我发布此内容后,OP在评论中进行了澄清。我应该删除这个答案吗?什么是正确的协议?
RootTwo '16

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)二进制格式存储在int数组中。(对于3字节字符串:000,001,010 ... 111)
  • 根据是否在某个位置上设置了位,或切换大小写。
  • 输出每个可能组合的字符串。

在线尝试!


当我最初像10年前在vb6中这样做时,我相信我的解决方案与此类似。您带回了一些回忆;)

@Poke Glad,我可以!:)
Abel Tom

打高尔夫的一些事情:取下i++for环并++直接使用,以及在for环内放置一些零件以尽可能地除去支架和半柱。另外,您可以删除参数中的空格,并在末尾使用三元-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字节
凯文Cruijssen

1

Hoon,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) -)

不幸的是,我不确定这可以缩小多少。

首先,我们将2 l等于(t长度)重复的列表设置为等于t。Hoon fac在stdlib 中没有函数,但是2 ^ n总是大于n !,因此我们只需映射更大的列表并使用aset(hashmap)删除重复项即可。

然后,我们在列表[0 ..(length l)]上折叠,累积为(set tape)。我们需要这样做而不是l直接映射,因为我们还需要知道它是什么数字重复(a),但是由于Hoon是纯语言,因此不能简单地增加累加器。

我们在[0 ..(length t)]上映射(同样,得到当前的索引),设置t为字符串中的第n个字符,检查是否第n个再见a并反转大小写(cus或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(),则循环将遍历set而不是乘积(我希望这是有道理的)。至少在我的实现中(我在Android上使用QPython),{}只是将列表放入集合中,而不是将列表转换为集合。
阻止

我已经尝试了两种方式,并且做{* expr}给了我SyntaxError。
阻止

啊 这就是为什么。QPython的最新版本是3.3或更高版本。
阻止

在这里,您可以:在线试用!(还修复了一个bug,打了个高尔夫球。)
DLosc



1

Tcl,165181字节

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}

创建输出文本时,使用二进制数字在大写/小写之间进行选择。



@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>

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.