Permutasi Kasus


27

Siapa yang perlu membandingkan hal-hal yang tidak sensitif ketika Anda dapat menghasilkan setiap permutasi huruf besar dan kecil? Tidak ada Itulah jawabannya. Tidak ada yang tahu. Tugas Anda adalah mencapai prestasi ini; menghasilkan semua kemungkinan permutasi huruf besar / kecil untuk input yang diberikan.

Memasukkan

Sederetan karakter ascii standar yang dapat dicetak. Input tidak boleh dianggap semua huruf kecil. Input akan selalu setidaknya satu karakter.

Keluaran

Setiap permutasi huruf besar dan kecil untuk string yang dimasukkan (tidak ada duplikat). Ini hanya akan mengubah karakter dengan versi kecil dan besar (angka akan tetap sama). Setiap permutasi harus berupa string atau daftar karakter; daftar string singleton tidak diperbolehkan.

Contohnya

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

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

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

Mencetak gol

Ini adalah , jadi jawaban tersingkat (dalam byte) menang.

Sebagai tambahan yang menyenangkan, lihat berapa banyak upaya tambahan yang diperlukan untuk menangani karakter ascii yang diperluas, berikut ini adalah ujian tambahan:

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

(program Anda tidak perlu mendukung ini)


10
Kasus uji Unicode yang menarik: Σ['Σ', 'σ', 'ς']
n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳

Bisakah kita menggunakan daftar karakter alih-alih string? Misalnya, jika Hi!memberi , apakah {('H', 'i', '!'), ('h', 'I', '!'), ('h', 'i', '!'), ('H', 'I', '!')}itu dapat diterima?
DJMcMayhem

@DrGreenEggsandHamDJ Daftar karakter diizinkan secara default . Dalam Python, itu adalah string tunggal, yang berbeda.
Dennis

1
@ n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳ bahkan lebih menarik adalah bahwa itu Σadalah versi huruf besar di awal kata, σadalah versi huruf kecil di awal atau di tengah tetapi bukan akhir kata, dan ςmerupakan versi huruf kecil hanya di akhir kata.
FantaC

1
@HomHastings Seperti Anda memiliki daftar dan Anda hanya membatasi ruang output? Itu masuk akal bagi saya.
Poke

Jawaban:


11

Pyth, 13 12 11

{msrVQd^U2l

Terima kasih 1 byte untuk Leaky Nun!

Satu byte lagi berkat Jakube!

Cobalah di sini atau jalankan Test Suite

Kami membuat daftar daftar nilai Benar / Salah dengan mengambil produk kartesius dari daftar [0, 1]itu sendiri beberapa kali sama dengan panjang string input. Jadi masing-masing sublist memiliki panjang yang sama dengan string input. Kemudian kita menerapkan rfungsi sebagai operasi vektor pada input dan daftar, jadi kita dapatkan r letter valueuntuk setiap sub elemen. rdengan argumen kedua nol untuk huruf kecil dan dengan satu untuk huruf besar. Ini membuat duplikat pada non-huruf, yang berarti kita perlu menghapus duplikat dari hasilnya.



@ LeakyNun Ah, saya sudah mencobanya tapi karena alasan tertentu saya pikir menggunakan Mkeduanya sdan .npanjangnya sama. Saya tampaknya pandai menghitung. Pokoknya, edit sekarang, terima kasih!
FryAmTheEggman

Ya mereka memiliki panjang yang sama, saya baru saja mengubah bagian terakhir
Leaky Nun

{msrVQd^U2lsedikit lebih pendek.
Jakube

@ Jakube Terima kasih! Menggunakan Vcukup licik, saya tidak berpikir saya akan pernah memikirkan itu di sini.
FryAmTheEggman

8

Jelly , 6 byte

żŒsŒpQ

Ini adalah tautan monadik (fungsi) yang mengharapkan string sebagai argumen kiri dan mengembalikan daftar string.

Menangani karakter non-ASCII. Cobalah online!

Bagaimana itu bekerja

żŒ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
Dapatkan rekt bahasa lain: p
Adnan

2
Bahkan setelah melihat halaman kode, fakta bahwa saya secara konsisten melihat Jelly dengan jumlah byte terendah pada tantangan kode-golf membuat saya takjub.
Poke

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}

Menangani karakter non-ASCII. Uji di 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);

Tidak bermain golf

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

Jelek sekali, harus lebih golf.


4

05AB1E, 17 byte

Kode:

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

Dijelaskan:

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

Cobalah online


4

Brachylog , 25 22 byte

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

Ini berfungsi serta predikat huruf kecil / besar dari Prolog, oleh karena itu ia berfungsi pada huruf non-ASCII juga:

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

Penjelasan

Tidak seperti semua jawaban lain pada saat saya memposting ini, ini tidak menggunakan pendekatan produk cartesian sama sekali.

  • Predikat Utama

    :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
    
  • Predikat 1

Ini digunakan untuk menerapkan huruf besar atau kecil pada masing-masing karakter input, sehingga menghitung satu permutasi yang mungkin. Menggunakan findall pada predikat ini dalam predikat utama memungkinkan untuk menghitung semua permutasi yang memungkinkan (dengan beberapa duplikat).

    :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
  • Predikat 2

Ini digunakan untuk mengubah karakter string menjadi huruf besar atau versi huruf kecilnya.

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

Cobalah online!

Sunting: @Ang menyimpan 11 byte. Terima kasih!


mapM(\x->toLower x:[toUpper x|isAlpha x])harus menyingkirkan impor lainnya?
Angs

3

MATL , 13 byte

tYov!Z}N$Z*Xu

Cobalah online!

Penjelasan

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

Sunting: Disimpan 2 byte karena new Setdengan senang hati akan mengekstraksi karakter unik dari sebuah string.


Ketika !c sjuga []sehingga Anda dapat kembali [s]bukan
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}}

Cobalah

Penjelasan:

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

Uji:

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

Anda dapat menyimpan byte yang saya pikir: {[X~] '',|.comb.map:{unique .lc,.uc}}(hapus spasi setelah map:)
Conor O'Brien


2

Python, 69 byte

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

Yang mengembalikan tupel string singleton bukan string. Saya tidak yakin apakah itu diizinkan.
Dennis

Hemat 1 byte dengan menggunakan from itertools import*;dan menghilangkani.
Byte Commander

OP mengatakan bahwa tali singleton tidak diperbolehkan. Anda harus memperbarui jawaban ini.
DJMcMayhem

Persyaratan output tidak jelas (masih ada). Setelah saya memposting ini, OP mengklarifikasi dalam komentar. Haruskah saya menghapus jawaban ini? Apa protokol yang tepat?
RootTwo

2

Sebenarnya, 28 byte

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

Cobalah online!

Program ini dapat menangani karakter non-ASCII, berkat keajaiban Python 3.

Penjelasan:

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

Versi tidak disatukan:

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

   } 
}

Penjelasan:

  • Terima string karakter, ubah string menjadi huruf kecil.
  • Deklarasikan panjang integer array yang sama dengan string. Isi dengan nol.
  • Simpan angka-angka dari 0 hingga 2^strlen(s)dalam bentuk biner dalam intarray. (Untuk string 3 byte: 000,001.010 ... 111)
  • Tergantung pada apakah bit pada suatu posisi diatur atau, alihkan kasing.
  • Keluarkan string untuk setiap kemungkinan kombinasi.

Cobalah online!


Ketika saya awalnya melakukan ini di vb6 seperti 10 tahun yang lalu saya percaya solusi saya mirip dengan yang satu ini. Anda membawa beberapa kenangan;)
Poke

@ Poke Senang aku bisa! :)
Abel Tom

Beberapa hal untuk golf: Lepaskan i++di for-loop dan gunakan ++langsung, serta menempatkan beberapa bagian di dalam for-loop untuk menghapus tanda kurung dan semi-kolom jika memungkinkan. Selain itu, Anda dapat menghapus spasi di parameter dan menggunakan tugas terner-jika di akhir. Total: 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) -)

Tidak Disatukan:

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

Sayangnya, saya tidak yakin seberapa kecil ini.

Pertama, kami menetapkan lsama dengan daftar dengan pengulangan 2 ^ (panjang t) dari t. Hoon tidak memiliki facfungsi di stdlib, tetapi 2 ^ n selalu lebih besar dari n !, jadi kami cukup memetakan daftar yang lebih besar dan menggunakan set(hashmap) untuk menghapus duplikat entri.

Kami kemudian lipat daftar [0 .. (panjang l)], terakumulasi menjadi a (set tape). Kita perlu melakukan ini alih-alih memetakan lsecara langsung karena kita juga perlu tahu berapa pengulangan nomor itu ( a), tetapi tidak bisa begitu saja menambah akumulator karena Hoon menjadi bahasa murni.

Kami memetakan di atas [0 .. (panjang t)] (lagi sehingga kami memiliki indeks saat ini), mengatur tke karakter ke-n dalam string, memeriksa apakah bye bye dari adan membalikkan case (cuss atau cass, tergantung jika itu berubah atau tidak). Jenis pengembalian peta ini adalah a tape.

Kami kemudian memasukkan string ke dalam hashmap kami, dan mengembalikan hashmap dari semua string.


"2 ^ n selalu lebih besar dari n!". Sebenarnya n! > 2^n, asalkan itu nsetidaknya 4. (Buktikan dengan induksi, dengan kasus dasar 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);}}

Ini adalah pendekatan yang berbeda , pendekatan yang sama dengan jawaban C lainnya.

Haruskah saya menghapus ini, dan meletakkannya di bawah jawaban lain sebagai komentar?

Biarkan saya jelaskan dengan versi 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='')

Terlambat ke pesta tetapi masih harus pergi. Terima kasih kepada DLosc untuk mengingatkan saya tentang hal-hal yang saya lewatkan, memberi saya tips bermain golf dan menyelamatkan saya banyak byte. :)


@Dosc, Terima kasih atas tipsnya! Saya akan menambahkan fitur-fitur itu masuk :)
Blok

Terima kasih atas tipsnya. Ini sangat membantu. Meskipun jika saya menggunakan {} bukannya set (), loop melewati set bukannya produk (Saya harap itu masuk akal). Setidaknya pada implementasi saya (saya menggunakan QPython di Android), {} hanya menempatkan daftar di dalam set daripada mengubah daftar ke set.
Blok

Saya sudah mencoba keduanya dan melakukan {* expr} memberi saya SyntaxError.
Blok

Ahhhh. Itu sebabnya. Versi terbaru dari QPython ada di 3.3 atau apalah.
Blok

Ini dia: Coba online! (Juga memperbaiki bug dan memangkas ruang.)
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}] ""]}

Perbaikan berkat sergiol . Jawaban sebelumnya:

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}

Menggunakan nomor biner untuk memilih antara huruf besar / kecil saat membuat teks output.



@sergiol Itu cukup berbeda dari saya sehingga Anda harus mempostingnya sebagai jawaban Anda sendiri dan mendapatkan pujian yang bagus untuk menjadi luar biasa.
Dúthomhas

Tidak. Saya hanya mengubah bagian kecil dari jawaban Anda, saya tidak mengubah pendekatan atau algoritme penting, jadi, menurut saya, saya pikir saya tidak pantas membuat jawaban baru dari Anda! Dan saya ragu saya bisa mendapatkan algoritma yang pendek seperti aslinya untuk tujuan yang sama!
sergiol


1

Attache , 39 byte

&Cross[Sum@V]##Unique@V#SwapCase=>Chars

Cobalah online!

Mirip dengan jawaban perl. (Saya kehilangan alternatif yang lebih menarik, saya harus mempostingnya dalam beberapa jam ke depan.)


0

JavaScript (ES6), 103

Menangani karakter non-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]

Uji

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>

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.