Permutation de cas


27

Qui a besoin de comparer les choses de manière insensible lorsque vous êtes en mesure de générer chaque permutation de majuscules et de minuscules? Personne! Voilà la réponse. Personne ne le fait. Votre tâche consiste à réaliser cet exploit; générer toutes les permutations possibles de majuscules / minuscules pour une entrée donnée.

Contribution

Une chaîne de caractères ascii standard imprimables. L'entrée ne doit pas être supposée être entièrement en minuscules. L'entrée sera toujours au moins un caractère.

Sortie

Chaque permutation de majuscules et minuscules pour la chaîne entrée (pas de doublons). Cela ne devrait changer que les caractères avec une petite et une grande version (les chiffres resteront les mêmes). Chaque permutation doit être sortie sous forme de chaîne ou de liste de caractères; les listes de chaînes singleton ne sont pas autorisées.

Exemples

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

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

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

Notation

Il s'agit de , donc la réponse la plus courte (en octets) l'emporte.

Comme un extra amusant voir combien d'efforts supplémentaires il faudra pour gérer les caractères ascii étendus, voici un cas de test supplémentaire:

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

(votre programme n'a pas besoin de le supporter)


10
Cas de test Unicode intéressant: Σ['Σ', 'σ', 'ς']
n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳

Pouvons-nous utiliser une liste de caractères au lieu d'une chaîne? Par exemple, si Hi!donné, {('H', 'i', '!'), ('h', 'I', '!'), ('h', 'i', '!'), ('H', 'I', '!')}serait-ce acceptable?
DJMcMayhem

@DrGreenEggsandHamDJ La liste des caractères est autorisée par défaut . En Python, ce sont des chaînes singleton, ce qui est différent.
Dennis

1
@ n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳ encore plus intéressant est que Σc'est la version en majuscule au début d'un mot, σest la version en minuscule au début ou au milieu mais pas la fin d'un mot, et ςest la version en minuscule seulement à la fin d'un mot.
FantaC

1
@DomHastings Comme dans vous avez une liste et vous ne faites que délimiter l'espace de sortie? Cela me semble raisonnable.
Poke

Réponses:


11

Pyth, 13 12 11

{msrVQd^U2l

1 octet grâce à Leaky Nun!

Encore un octet grâce à Jakube!

Essayez-le ici ou exécutez une suite de tests

Nous créons une liste de listes de valeurs Vrai / Faux en prenant le produit cartésien de la liste [0, 1]avec lui-même un nombre de fois égal à la longueur de la chaîne d'entrée. Ainsi, chacune des sous-listes a la même longueur que la chaîne d'entrée. Ensuite, nous appliquons la rfonction comme une opération vectorielle sur l'entrée et la liste, donc nous obtenons r letter valuepour chaque sous-élément. ravec le deuxième argument, zéro est en minuscule et avec un, il est en majuscule. Cela crée des doublons sur les non-lettres, ce qui signifie que nous devons supprimer les doublons du résultat.



@LeakyNun Ah, j'avais essayé mais pour une raison quelconque, je pensais utiliser Mles deux set .nétait de la même longueur. J'ai l'air de bien compter. Quoi qu'il en soit, éditez maintenant, merci!
FryAmTheEggman

Oui, ils sont de la même longueur, je viens de changer la dernière partie
Leaky Nun

{msrVQd^U2lest un peu plus court.
Jakube

@Jakube Merci! L'utilisation Vest assez sournoise, je ne pense pas que j'aurais jamais pensé à ça ici.
FryAmTheEggman

8

Gelée , 6 octets

żŒsŒpQ

Il s'agit d'un lien (fonction) monadique qui attend une chaîne comme argument de gauche et renvoie une liste de chaînes.

Gère les caractères non ASCII. Essayez-le en ligne!

Comment ça marche

żŒ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
Obtenez rekt d'autres langues: p
Adnan

2
Même après avoir regardé la page de codes, le fait que je vois constamment Jelly avec le nombre d'octets le plus bas sur les défis de golf de code m'étonne.
Poke

5

Python, 74 71 octets

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

Gère les caractères non ASCII. Testez-le sur Ideone .


5

Oracle SQL 11.2, 276 octets

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

Non 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

Laid comme l'enfer, doit être plus jouable au golf.


4

05AB1E, 17 octets

Code:

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

Expliqué:

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

Essayez-le en ligne


4

Brachylog , 25 22 octets

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

Cela fonctionne aussi bien que les prédicats minuscules / majuscules de Prolog, donc cela fonctionne aussi sur les lettres non ASCII:

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

Explication

Contrairement à toutes les autres réponses au moment où je poste ceci, cela n'utilise pas du tout l'approche produit cartésienne.

  • Prédicat principal

    :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
    
  • Prédicat 1

Ceci est utilisé pour appliquer des majuscules ou des minuscules sur chaque caractère de l'entrée, calculant ainsi une permutation possible. L'utilisation de findall sur ce prédicat dans le prédicat principal permet de calculer toutes les permutations possibles (avec quelques doublons).

    :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
  • Prédicat 2

Ceci est utilisé pour transformer un caractère de la chaîne en sa version majuscule ou minuscule.

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

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

Essayez-le en ligne!

Modifier: @Angs a enregistré 11 octets. Merci!


mapM(\x->toLower x:[toUpper x|isAlpha x])devrait se débarrasser de l'autre importation?
Angs

3

MATL , 13 octets

tYov!Z}N$Z*Xu

Essayez-le en ligne!

Explication

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 octets

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

Edit: enregistré 2 octets car new Setextraira avec plaisir les caractères uniques d'une chaîne.


Quand !c sest- []ce que vous pouvez également revenir à la [s]place
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 octets

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

Essayez-le

Explication:

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

Tester:

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

Vous pouvez enregistrer un octet, je pense: {[X~] '',|.comb.map:{unique .lc,.uc}}(supprimer l'espace après map:)
Conor O'Brien


2

Python, 69 octets

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

Cela renvoie des tuples de chaînes singleton au lieu de chaînes. Je ne sais pas si c'est permis.
Dennis

Économisez 1 octet en utilisant from itertools import*;et en omettant lei.
Byte Commander

OP a déclaré que les chaînes singleton ne sont pas autorisées. Vous devez mettre à jour cette réponse.
DJMcMayhem

L'exigence de sortie est ambiguë (l'est toujours). Après avoir posté cela, le PO a clarifié dans les commentaires. Dois-je simplement supprimer cette réponse? Quel est le bon protocole?
RootTwo

2

En fait, 28 octets

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

Essayez-le en ligne!

Ce programme peut gérer des caractères non ASCII, grâce à la magie de Python 3.

Explication:

;╗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 octets

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

Version non golfée:

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

   } 
}

Explication:

  • Acceptez la chaîne de caractères, convertissez la chaîne en minuscules.
  • Déclarez un tableau entier de longueur égale à celle de la chaîne. Remplissez-le de zéros.
  • Stockez les nombres de 0 à 2^strlen(s)sous forme binaire dans unint tableau. (Pour une chaîne de 3 octets: 000,001,010 ... 111)
  • Selon si un bit à une position est définie ou, basculez le cas.
  • Sortez la chaîne pour chaque combinaison possible.

Essayez-le en ligne!


Quand j'ai fait cela à l'origine en vb6 il y a 10 ans, je pense que ma solution était similaire à celle-ci. Vous avez ramené quelques souvenirs;)
Poke

@Poke Heureux d'avoir pu! :)
Abel Tom

Quelques choses à jouer au golf: Retirez le i++dans les boucles for et utilisez ++directement, ainsi que de placer certaines pièces à l'intérieur de la boucle for pour supprimer les supports et les demi-colonnes si possible. En outre, vous pouvez supprimer l'espace dans le paramètre et utiliser une affectation ternaire si à la fin. Au 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 octets / 232 octets )
Kevin Cruijssen

1

Hoon , 242 octets

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

Non golfé:

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

Je ne sais pas combien cela pourrait être plus petit, malheureusement.

D'abord, nous mettons légal à une liste avec 2 ^ (longueur t) répétitions de t. Hoon n'a pas de facfonction dans le stdlib, mais 2 ^ n est toujours plus grand que n!set mappons (hashmap) pour dédoublonner les entrées.

On replie ensuite la liste [0 .. (longueur l)], en accumulant en a (set tape). Nous devons le faire au lieu de mapper ldirectement, car nous devons également savoir de quelle répétition de nombre il s'agit (a ), mais nous ne pouvons pas simplement incrémenter un accumulateur car Hoon est un langage pur.

Nous mappons sur [0 .. (longueur t)] (encore une fois, nous avons donc l'index actuel), en définissant tle nième caractère de la chaîne, en vérifiant si le nième bye aet en inversant le cas (cuss ou cass, selon qu'il change) ou pas). Le type de retour de cette carte est a tape.

Nous mettons ensuite la chaîne dans notre table de hachage et renvoyons la table de hachage de toutes les chaînes.


"2 ^ n est toujours plus grand que n!". En fait n! > 2^n, à condition que ce nsoit au moins 4. (Prouver par induction, avec le cas de base n=4.) En.wikipedia.org/wiki/...
mathmandan

1

C, 216 octets

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

Il s'agit d' une approche différente , la même approche que l'autre réponse C.

Dois-je le supprimer et le mettre sous l'autre réponse en tant que commentaire?

Je m'explique avec la version 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 octets

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

En retard à la fête mais toujours à essayer. Merci à DLosc de m'avoir rappelé ce que j'ai manqué, de m'avoir donné des conseils de golf et de m'avoir épargné un tas d'octets. :)


@DLosc Merci pour les conseils! Je vais ajouter ces fonctionnalités. :)
Blocs

Merci pour les conseils. Ça m'a vraiment aidé. Bien que si j'utilise {} au lieu de set (), la boucle passe par l'ensemble au lieu des produits (j'espère que cela a du sens). Au moins sur mon implémentation (j'utilise QPython sur Android), {} place simplement la liste dans un ensemble au lieu de convertir la liste en un ensemble.
Bloque le

J'ai essayé des deux façons et faire {* expr} me donne une SyntaxError.
Bloque le

Ahhhh. Voilà pourquoi. La dernière version de QPython est sur 3.3 ou quelque chose.
Bloque le

C'est parti: Essayez-le en ligne! (Également corrigé un bug et
joué au golf dans



1

Tcl, 165 181 octets

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

Améliorations grâce au sergiol . Réponse précédente:

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}

Utilise un nombre binaire pour choisir entre majuscules / minuscules lors de la création du texte de sortie.



@sergiol C'est assez différent du mien que vous devez l'afficher comme votre propre réponse et obtenir une bonne réputation d'être génial.
Dúthomhas

Non. Je n'ai changé que des parties mineures de votre réponse, je n'ai pas changé l'approche ni les algorithmes essentiels, donc, à mon avis, je pensais que je ne méritais pas de créer une nouvelle réponse à partir de la vôtre! Et je doute que je puisse obtenir un algorithme court comme votre original dans le même but!
sergiol



0

JavaScript (ES6), 103

Gère les caractères 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]

Tester

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>

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.