Перестановка випадку


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

@DrGreenEggsandHamDJ Список символів дозволений за замовчуванням . У Python це одинакові струни, що відрізняється.
Денніс

1
@ n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳ ще цікавіше те, що верхня Σлітера у верхньому регістрі на початку слова, σце маленька версія на початку або в середині, але не в кінці слова, і ςце малі версії лише в кінці слова.
FantaC

1
@DomHastings Як у вас є список, і ви просто обмежуєте простір вихід? Мені це здається розумним.
Пукайте

Відповіді:


11

Pyth, 13 12 11

{msrVQd^U2l

1 байт завдяки Leaky Nun!

Ще один байт дякую Якубе!

Спробуйте тут або запустіть тестовий набір

Ми створюємо список списків True / False значень, приймаючи декартовий добуток списку [0, 1]з собою в кілька разів, рівний довжині вхідного рядка. Таким чином, кожен із списків має ту саму довжину, що і вхідний рядок. Потім ми застосовуємо rфункцію як векторну операцію над входом та списком, тому отримуємо r letter valueдля кожного піделемента. rз другим аргументом нуль - це малий регістр, а з одним - верхній регістр. Це створює дублікати на не письмах, а значить, нам потрібно видалити дублікати з результату.



@LeakyNun Ах, я спробував це, але я чомусь думав використовувати Mобидва sі .nбув однакової довжини. Я, здається, добре рахую. У будь-якому випадку, редагування зараз, дякую!
FryAmTheEggman

Так, вони однакової довжини, я просто змінив останню частину
Leaky Nun

{msrVQd^U2lтрохи коротше.
Якубе

@Jakube Дякую! Використання 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
Отримайте інші мови: p
Аднан

2
Навіть переглянувши кодову сторінку, мене вражає той факт, що я постійно бачу Jelly з найнижчим числом байтів на проблемах з кодом-гольфом.
Піка

5

Пітон, 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

Брахілог , 25 22 байт

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

Це працює так само, як і малі / великі предикати прологів, тому він працює і на літери, що не належать до 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


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]
l4м2

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


2

Пітон, 69 байт

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

Це повертає кортежі однорядних рядків замість рядків. Я не впевнений, чи це дозволено.
Денніс

Збережіть 1 байт, скориставшись from itertools import*;і пропустивши командуi.
Byte Commander

ОП заявила, що однодольні рядки заборонені. Вам слід оновити цю відповідь.
DJMcMayhem

Вимога на виході неоднозначна (все ще є). Після того як я опублікував це, ОП уточнив у коментарях. Чи потрібно просто видалити цю відповідь? Що таке правильний протокол?
RootTwo

2

Власне, 28 байт

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

Спробуйте в Інтернеті!

Ця програма може обробляти символи, що не належать до ASCII, завдяки магії Python 3.

Пояснення:

;╗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 байт

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)
  • Залежно від того, встановлено біт у позиції або, перемкніть регістр.
  • Виведіть рядок для кожної можливої ​​комбінації.

Спробуйте в Інтернеті!


Коли я спочатку робив це в vb6, як 10 років тому, я вважаю, що моє рішення було подібним до цього. Ти повернув кілька спогадів;)
Тикаємо

@ Подумайте Радий, що я міг! :)
Abel Tom

Деякі речі для гольфу: вийміть i++петлі for-петлі та використовуйте ++безпосередньо, а також розмістивши частини всередині for-петлі, щоб зняти дужки та напівколонки, де це можливо. Крім того, ви можете видалити простір у параметрі та використати потрійне завдання, якщо в кінці. Всього: 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) -)

На жаль, я не впевнений, наскільки це може бути меншим.

По-перше, ми встановлюємо lрівний список з 2 ^ (довжиною t) повторень t. Hoon не має facфункції в stdlib, але 2 ^ n завжди більше n !, тому ми просто відображаємо більший список і використовуємо set(хешмап) для видалення дублікатів записів.

Потім складемо список [0 .. (довжина l)], накопичивши в a (set tape). Нам потрібно це зробити, а не відображати lбезпосередньо, оскільки ми також повинні знати, що це повторення числа (a ), але не може просто збільшити акумулятор через те, що Хун є чистою мовою.

Позначаємо карту [0 .. (довжина t)] (знову ж таки, у нас є поточний індекс), встановлюючи tn-й символ у рядку, перевіряючи, чи n-й бай aі перевертає справу (cuss або cass, залежно від зміни чи ні). Тип повернення цієї карти - цеtape .

Потім ми вставляємо рядок у нашу хешмап і повертаємо хешмап усіх рядків.


"2 ^ n завжди більше, ніж n!". Власне n! > 2^n, за умови, що nпринаймні 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);}}

Це інший підхід , той самий підхід, як і інша відповідь С.

Чи слід це видалити та помістити під іншою відповіддю як коментар?

Дозвольте пояснити з версією 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 (), цикл проходить через набір замість продуктів (сподіваюся, це має сенс). Принаймні щодо моєї реалізації (я використовую QPython для Android), {} просто розміщує список всередині набору замість перетворення списку на набір.
Блоки

Я спробував обидва способи, і виконання {* 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}] ""]}

Покращення завдяки сергіолу . Попередня відповідь:

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

Ні. Я змінив лише незначну частину вашої відповіді, я не змінив підходу, ані суттєвої алгоритміки, тож, на мою точку зору, я подумав, що не заслуговую створити нову відповідь із вашої! І я сумніваюся, що я міг би отримати алгоритм короткий як ваш оригінал для тієї ж мети!
серхіол



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>

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.