Hoán vị trường hợp


27

Ai cần so sánh mọi thứ một cách vô cảm khi bạn có thể tạo ra mọi hoán vị của chữ hoa và chữ thường? Không một ai! Đó là câu trả lời. Không ai làm. Nhiệm vụ của bạn là đạt được kỳ tích này; tạo ra tất cả các hoán vị có thể có của chữ hoa / chữ thường cho một đầu vào nhất định.

Đầu vào

Một chuỗi các ký tự ascii tiêu chuẩn có thể in. Đầu vào không nên được coi là tất cả chữ thường. Đầu vào sẽ luôn có ít nhất một ký tự.

Đầu ra

Mọi hoán vị của chữ hoa và chữ thường cho chuỗi nhập vào (không trùng lặp). Điều này chỉ nên thay đổi các ký tự với một phiên bản nhỏ và lớn (số sẽ giữ nguyên). Mỗi hoán vị phải là đầu ra dưới dạng một chuỗi hoặc một danh sách các ký tự; danh sách các chuỗi đơn không được phép.

Ví dụ

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

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

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

Chấm điểm

Đây là , vì vậy câu trả lời ngắn nhất (tính bằng byte) sẽ thắng.

Như một phần bổ sung thú vị, bạn sẽ mất bao nhiêu nỗ lực để xử lý các ký tự ascii mở rộng, đây là một trường hợp thử nghiệm bổ sung:

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

(chương trình của bạn không cần hỗ trợ này)


10
Trường hợp kiểm tra Unicode thú vị: Σ['Σ', 'σ', 'ς']
n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳

Chúng ta có thể sử dụng một danh sách các ký tự thay vì một chuỗi không? Ví dụ, nếu được Hi!đưa ra {('H', 'i', '!'), ('h', 'I', '!'), ('h', 'i', '!'), ('H', 'I', '!')}sẽ được chấp nhận?
DJMcMayhem

@DrGreenEggsandoutDJ Danh sách các ký tự được cho phép theo mặc định . Trong Python, đó là những chuỗi singleton, khác nhau.
Dennis

1
@ n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳ thú vị hơn nữa là Σphiên bản chữ hoa ở đầu từ, σlà phiên bản chữ thường ở đầu hoặc ở giữa nhưng không phải là cuối của từ và ςlà phiên bản chữ thường ở cuối từ.
FantaC

1
@DomHastings Như trong bạn có một danh sách và bạn chỉ phân định không gian đầu ra? Điều đó có vẻ hợp lý với tôi.
Chọc

Câu trả lời:


11

Bình thường 13 12 11

{msrVQd^U2l

1 byte nhờ Leaky Nun!

Một byte khác nhờ Jakube!

Dùng thử tại đây hoặc chạy Test Suite

Chúng tôi tạo một danh sách các danh sách Giá trị đúng / sai bằng cách lấy sản phẩm cartesian của danh sách [0, 1]với số lần bằng với độ dài của chuỗi đầu vào. Vì vậy, mỗi danh sách con có cùng độ dài với chuỗi đầu vào. Sau đó, chúng tôi áp dụng rhàm như một phép toán vectơ trên đầu vào và danh sách, vì vậy chúng tôi nhận được r letter valuecho mỗi phần tử phụ. rvới đối số thứ hai, không phải là chữ thường và với một, nó là chữ hoa. Điều này tạo ra các bản sao trên các chữ cái không có nghĩa là chúng ta cần loại bỏ các bản sao khỏi kết quả.



@LeakyNun Ah, tôi đã thử điều đó nhưng vì một số lý do tôi nghĩ sử dụng Mcả hai s.ncó cùng độ dài. Tôi dường như giỏi đếm. Dù sao, chỉnh sửa bây giờ, cảm ơn!
FryAmTheEggman

Vâng, chúng có cùng độ dài, tôi chỉ thay đổi phần cuối cùng
Leaky Nun

{msrVQd^U2lngắn hơn một chút
Jakube

@Jakube Cảm ơn! Sử dụng Vlà khá lén lút, tôi không nghĩ rằng tôi đã từng nghĩ về điều đó ở đây.
FryAmTheEggman

8

Thạch , 6 byte

żŒsŒpQ

Đây là một liên kết đơn (hàm) mong đợi một chuỗi là đối số bên trái và trả về một danh sách các chuỗi.

Xử lý các ký tự không phải ASCII. Hãy thử trực tuyến!

Làm thế nào nó hoạt động

żŒ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
Nhận rekt ngôn ngữ khác: p
Adnan

2
Ngay cả sau khi nhìn vào trang mã, thực tế là tôi luôn thấy Jelly có số byte thấp nhất trong các thử thách chơi gôn mã làm tôi ngạc nhiên.
Chọc

5

Python, 74 71 byte

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

Xử lý các ký tự không phải ASCII. Kiểm tra nó trên Ideone .


5

Oracle SQL 11.2, 276 byte

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);

Không chơi gôn

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

Xấu xí như địa ngục, phải chơi golf nhiều hơn.


4

05AB1E, 17 byte

Mã số:

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

Giải thích:

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

Dùng thử trực tuyến


4

Brachylog , 25 22 byte

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

Điều này hoạt động cũng như các vị từ viết thường / viết hoa của Prolog, do đó nó cũng hoạt động trên các chữ cái không phải ASCII:

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

Giải trình

Không giống như tất cả các câu trả lời khác tại thời điểm tôi đăng bài này, điều này hoàn toàn không sử dụng phương pháp tiếp cận sản phẩm của cartesian.

  • Vị ngữ chính

    :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
    
  • Vị ngữ 1

Điều này được sử dụng để áp dụng cấp trên hoặc cấp dưới cho mỗi char của đầu vào, do đó tính toán một hoán vị có thể. Sử dụng findall trên vị từ này trong vị từ chính cho phép tính toán tất cả các hoán vị có thể có (với một số trùng lặp).

    :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
  • Vị ngữ 2

Điều này được sử dụng để biến một ký tự của chuỗi thành chữ hoa hoặc phiên bản chữ thường của nó.

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

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

Hãy thử trực tuyến!

Chỉnh sửa: @Angs đã lưu 11 byte. Cảm ơn!


mapM(\x->toLower x:[toUpper x|isAlpha x])Có nên thoát khỏi nhập khẩu khác?
Angs

3

MATL , 13 byte

tYov!Z}N$Z*Xu

Hãy thử trực tuyến!

Giải trình

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 byte

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

Chỉnh sửa: Đã lưu 2 byte vì new Setsẽ vui vẻ trích xuất các ký tự duy nhất từ ​​một chuỗi.


Khi nào !c scũng []vậy, bạn có thể quay lại [s]thay thế
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 byte

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

Thử nó

Giải trình:

{
  [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 }
}

Kiểm tra:

#! /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)

Bạn có thể lưu một byte tôi nghĩ: {[X~] '',|.comb.map:{unique .lc,.uc}}(xóa khoảng trống sau map:)
Conor O'Brien


2

Python, 69 byte

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

Điều đó trả về bộ dữ liệu của chuỗi đơn thay vì chuỗi. Tôi không chắc nếu điều đó được cho phép.
Dennis

Lưu 1 byte bằng cách sử dụng from itertools import*;và bỏ quai.
Byte Commander

OP đã nói rằng chuỗi singleton không được phép. Bạn nên cập nhật câu trả lời này.
DJMcMayhem

Yêu cầu đầu ra không rõ ràng (vẫn còn). Sau khi tôi đăng bài này, OP đã làm rõ trong các bình luận. Tôi có nên xóa câu trả lời này? Giao thức thích hợp là gì?
RootTwo

2

Trên thực tế, 28 byte

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

Hãy thử trực tuyến!

Chương trình này có thể xử lý các ký tự không phải ASCII, nhờ vào phép thuật của Python 3.

Giải trình:

;╗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 229 252 byte

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);}}

Phiên bản bị đánh cắp:

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);       

   } 
}

Giải trình:

  • Chấp nhận chuỗi ký tự, chuyển đổi chuỗi thành chữ thường.
  • Khai báo mảng số nguyên có độ dài bằng với chuỗi. Điền vào nó bằng số không.
  • Lưu trữ các số từ 0 đến 2^strlen(s)ở dạng nhị phân trong một intmảng. (Đối với chuỗi 3 byte: 000,001,010 ... 111)
  • Tùy thuộc vào việc một bit tại một vị trí được đặt hay, chuyển đổi trường hợp.
  • Xuất chuỗi cho mọi kết hợp có thể.

Hãy thử trực tuyến!


Khi tôi ban đầu làm điều này trong vb6 như 10 năm trước, tôi tin rằng giải pháp của tôi tương tự như giải pháp này. Bạn đã mang lại một số ký ức;)
Chọc

@Poke Vui mừng vì tôi có thể! :)
Abel Tom

Một số điều cần chơi gôn: Loại bỏ các i++vòng lặp for và sử dụng ++trực tiếp, cũng như đặt một số phần bên trong vòng lặp for để loại bỏ dấu ngoặc và cột bán nếu có thể. Ngoài ra, bạn có thể loại bỏ khoảng trắng trong tham số và sử dụng phép gán ternary-if ở cuối. Tổng cộng: 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 byte / 232 byte )
Kevin Cruijssen

1

Hoon , 242 byte

|=
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) -)

Ung dung:

|=  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ôi không chắc điều này có thể nhỏ hơn bao nhiêu, thật không may.

Đầu tiên, chúng tôi đặt lbằng với một danh sách có số lần lặp lại 2 ^ (chiều dài t) t. Hoon không cófac chức năng trong stdlib, nhưng 2 ^ n luôn lớn hơn n!, Vì vậy chúng tôi chỉ cần ánh xạ qua danh sách lớn hơn và sử dụng set(hashmap) để sao chép các mục.

Sau đó, chúng tôi gấp lại danh sách [0 .. (chiều dài l)], tích lũy thành a (set tape). Chúng ta cần làm điều này thay vì ánh xạ ltrực tiếp bởi vì chúng ta cũng cần biết đó là sự lặp lại số nào (a ), nhưng không thể đơn giản là tăng tích lũy do Hoon là ngôn ngữ thuần túy.

Chúng tôi ánh xạ qua [0 .. (chiều dài t)] (một lần nữa để chúng tôi có chỉ mục hiện tại), đặt tthành ký tự thứ n trong chuỗi, kiểm tra xem tạm biệt thứ n avà đảo ngược trường hợp (cuss hoặc cass, tùy thuộc vào nếu nó thay đổi hay không). Loại trả về của bản đồ này là a tape.

Sau đó, chúng tôi đưa chuỗi vào hashmap của mình và trả về hashmap của tất cả các chuỗi.


"2 ^ n luôn lớn hơn n!". Trên thực tế n! > 2^n, với điều kiện nlà ít nhất 4. (Chứng minh bằng quy nạp, với trường hợp cơ sở n=4.) En.wikipedia.org/wiki/...
mathmandan

1

C, 216 byte

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);}}

Đây là một cách tiếp cận khác nhau , các cùng cách tiếp cận là câu trả lời C khác.

Tôi có nên xóa cái này không, và đặt nó dưới câu trả lời khác như một bình luận?

Hãy để tôi giải thích với phiên bản 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 byte

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

Đi dự tiệc muộn nhưng vẫn có người đi. Cảm ơn DLosc đã nhắc nhở tôi về những thứ tôi đã bỏ lỡ, cho tôi lời khuyên chơi golf và tiết kiệm cho tôi một loạt byte. :)


@DLosc Cảm ơn lời khuyên! Tôi sẽ thêm các tính năng đó vào. :)
Các khối

Cảm ơn vì những lời khuyên. Nó thực sự có ích. Mặc dù nếu tôi sử dụng {} thay vì set (), vòng lặp sẽ đi qua tập hợp thay vì các sản phẩm (tôi hy vọng điều đó có ý nghĩa). Ít nhất là về việc triển khai của tôi (Tôi đang sử dụng QPython trên Android), {} chỉ đặt danh sách bên trong một bộ thay vì chuyển đổi danh sách thành một bộ.
Khối

Tôi đã thử cả hai cách và thực hiện {* expr} cho tôi một SyntaxError.
Khối

À Đó là lý do tại sao. Phiên bản mới nhất của QPython là vào ngày 3.3 hoặc một cái gì đó.
Khối

Ở đây bạn đi: Hãy thử trực tuyến! (Cũng đã sửa một lỗi và đánh gôn một khoảng trống.)
DLosc



1

Tcl, 165 181 byte

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}] ""]}

Cải tiến nhờ sergiol . Câu trả lời trước:

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}

Sử dụng số nhị phân để chọn giữa chữ hoa / chữ thường khi tạo văn bản đầu ra.



@sergiol Điều đó đủ khác với tôi mà bạn nên đăng nó dưới dạng câu trả lời của riêng bạn và nhận được sự tín nhiệm tốt vì tuyệt vời.
Dúthomhas

Không. Tôi chỉ thay đổi một phần nhỏ trong câu trả lời của bạn, tôi không thay đổi cách tiếp cận cũng như thuật toán thiết yếu, vì vậy, theo quan điểm của tôi, tôi nghĩ rằng tôi không xứng đáng để tạo ra một câu trả lời mới từ mẫu của bạn! Và tôi nghi ngờ tôi có thể lấy một thuật toán ngắn như bản gốc của bạn cho cùng một mục đích!
sergiol



0

JavaScript (ES6), 103

Xử lý các ký tự không phải 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]

Kiểm tra

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>

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.