Compter toutes les combinaisons uniques possibles de lettres dans un mot


12

Vous recevez une chaîne qui contiendra des caractères az ordinaires. (Vous pouvez supposer que ce sera toujours le cas dans tous les tests et supposer que toutes les lettres seront également en minuscules). Vous devez déterminer combien de combinaisons uniques peuvent être faites des caractères individuels dans la chaîne et imprimer ce nombre.

Cependant, les lettres en double peuvent être ignorées lors du comptage des combinaisons possibles. En d'autres termes, si la chaîne donnée est "bonjour", alors simplement changer les positions des deux ls ne compte pas comme une phrase unique, et ne peut donc pas être compté dans le total.

Le nombre d'octets le plus court gagne, avec impatience de voir des solutions créatives dans des langues autres que le golf!

Exemples:

hello -> 60
aaaaa -> 1
abcde -> 120


4
@ Giuseppe Je ne pense pas que ce soit une dupe de cela; les spécificités de cette question permettent des implémentations beaucoup plus courtes
ArBo

4
L'ajout de quelques tests peut aider.
tsh

1
@JonathanAllan Bonne suggestion! Le titre a changé en conséquence.
SimpleGeek

Réponses:


29

Python 2 , 50 48 octets

f=lambda s:s==''or len(s)*f(s[1:])/s.count(s[0])

Essayez-le en ligne!

Aucun ennuyeux intégré! À ma grande surprise, c'est encore plus court que l'approche par force brute, calculant toutes les permutations avec itertoolset prenant la longueur.

Cette fonction utilise la formule

# of unique permutations=(# of elements)!unique elements(# of occurences of that element)!

et le calcule à la volée. La factorielle dans le numérateur est calculée en multipliant par len(s)dans chaque appel de fonction. Le dénominateur est un peu plus subtil; dans chaque appel, nous divisons par le nombre d'occurrences de cet élément dans ce qui reste de la chaîne, garantissant que pour chaque caractère c, tous les nombres entre 1 et la quantité d'occurrences de c(inclus) seront divisés par une seule fois. Étant donné que nous ne divisons qu'à la toute fin, nous sommes garantis de ne pas avoir de problèmes avec la division par défaut du plancher de Python 2.


itertools est très verbeux dans ses noms de fonctions
qwr


7

CJam , 4 octets

le!,

Essayez-le en ligne!

Explication

Lire la ligne sous forme de chaîne ( l), les permutations uniques sous forme de tableau de chaînes ( e!), la longueur ( ,), l'affichage implicite.


4
Ressemble à "lel", +1! : D
KeyWeeUsr

5

R , 69 65 octets

function(s,`!`=factorial)(!nchar(s))/prod(!table(strsplit(s,"")))

Essayez-le en ligne!

4 octets enregistrés grâce à Zahiro Mor dans les deux réponses.

Calcule directement le coefficient multinomial.

R , 72 68 octets

function(s,x=table(strsplit(s,"")))dmultinom(x,,!!x)*sum(1|x)^sum(x)

Essayez-le en ligne!

Utilise la fonction de distribution multinomiale fournie par dmultinompour extraire le coefficient multinomial.

Notez que l'habituel (golfeur) x<-table(strsplit(s,""))ne fonctionne pas dans l' dmultinomappel pour une raison inconnue.


2
function(s,! =factorial)(!nchar(s))/prod(!table(strsplit(s,""))) marchera. le el () est redondant - la table sait rechercher les éléments ....
Zahiro Mor

1
@ZahiroMor ah, bien sûr. J'avais l'intention de tester cela, mais je n'y suis jamais parvenu.
Giuseppe

5

JavaScript (Node.js) , 49 octets

t=t*est utilisé au lieu de t*=pour éviter une erreur d'arrondi (l'arrondi |tvers le bas du nombre) car il t=t*garantit que tous les résultats intermédiaires (selon l'opérateur) sont des nombres entiers.

a=>[...a].map(g=x=>t=t*y++/(g[x]=-~g[x]),t=y=1)|t

Essayez-le en ligne!

a=>
 [...a].map(        // Loop over the characters
  g=x=>
   t=t*             // using t*= instead may result in rounding error 
    y++             // (Length of string)!
    /(g[x]=-~g[x])  // divided by product of (Count of character)!
  ,t=y=1            // Initialization
 )
 |t

2
(Erreur potentielle d'arrondi en virgule flottante; à utiliser t=t*si vous voulez éviter cela.)
Neil

@Neil Oui, il a échoué lorsque l'entrée est aaadegfbbbcccexactement due à l'erreur d'arrondi à virgule flottante
Shieru Asakoto

Huh, comment avez-vous trouvé ce cas de test?
Neil

@Neil Continuez à ajouter des caractères à la chaîne jusqu'à ce
qu'une

@ShieruAsakoto Le titre a été modifié; compter est beaucoup mieux. Merci et bonne réponse!
SimpleGeek








2

APL (Dyalog Unicode) , 24 octets

CY'dfns'
{≢∪↓⍵[pmat≢⍵]}

Essayez-le en ligne!

Dfn simple, prend une chaîne comme argument.

Comment:

CY'dfns'       Copies the 'dfns' namespace.
{≢∪↓⍵[pmat≢⍵]}  Main function
          ≢⍵    Number of elements in the argument (⍵)
      pmat      Permutation Matrix of the range [1..≢⍵]
    ⍵[      ]   Index the argument with that matrix, which generates all permutations of 
               Convert the matrix into a vector of strings
               Keep only the unique elements
               Tally the number of elements



2

Perl 6 , 33 30 caractères ( 34 31 octets)

WhateverBloc assez simple . combdivise la chaîne en lettres, permutationsobtient toutes les combinaisons possibles. En raison de la façon dont la contrainte Setdoit être joinéditée en premier ( »s'applique joinà chaque élément de la liste).

+*.comb.permutations».join.Set

Essayez-le en ligne!

(la réponse précédente est utilisée .uniquemais Setgarantit l'unicité et la numérise de la même manière, cela économise 3).


2

K (oK) , 12 octets

Solution:

#?x@prm@!#x:

Essayez-le en ligne!

Explication:

Utilise le oK intégré prm:

{[x]{[x]$[x;,/x ,''o'x ^/:x;,x]}@$[-8>@x;!x;x]}

... qui, en raison de x^/:xgénère essentiellement les permutations de "helo"non "hello", nous devons donc générer les permutations de 0 1 2 3 4, les utiliser pour indexer "hello"puis prendre le compte de l'unique.

#?x@prm@!#x: / the solution
          x: / store input as x
         #   / count (#) length
        !    / range (!) 0..n
    prm@     / apply (@) to function prm
  x@         / apply permutations to input x
 ?           / take the distinct (?)
#            / count (#)

Prm est-il un opérateur spécifique ok? Je ne pense pas que la vanille l'ait?
Henry Henrinson

Ouaip - n'existe qu'en OK selon le manuel
streetster

@HenryHenrinson afaik ce n'est pas en k4. c'était au début du k5 !-n. à la fin de k5 et k6, il est devenuprm . k7 (shakti) prmaussi.
ngn

2

Java 8, 103 102 octets

s->{int r=1,i=s.length();for(;i>0;)r=r*i/~-s.substring(--i).split(s.charAt(i)+"",-1).length;return r;}

Port de la réponse Python 2 de @ArBo .
-1 octet grâce à @ OlivierGrégoire en le rendant itératif au lieu de récursif.

Essayez-le en ligne.

En fait, générer toutes les permutations uniques dans un ensemble et obtenir sa taille serait de 221 octets :

import java.util.*;s->{Set S=new HashSet();p(s,S,0,s.length()-1);return S.size();}void p(String s,Set S,int l,int r){for(int i=l;i<=r;p(s.replaceAll("(.{"+l+"})(.)(.{"+(i++-l)+"})(.)(.*)","$1$4$3$2$5"),S,l+1,r))S.add(s);}

Essayez-le en ligne.


D' accord, je pourrais le golf un octet en rendant itératif au lieu de récursive: s->{int r=1,i=s.length();for(;i>0;)r=r*i/~-s.substring(--i).split(s.charAt(i)+"",-1).length;return r;}.
Olivier Grégoire

@ OlivierGrégoire Merci! Btw, voyez-vous quelque chose pour raccourcir la seconde approche (générer toutes les permutations uniques dans un ensemble)? J'ai l'impression que certains octets peuvent être sauvegardés, mais j'ai essayé certaines choses et la plupart étaient légèrement plus longues au lieu de plus courtes .. Mais cela semble toujours trop long tbh.
Kevin Cruijssen

J'y ai travaillé, j'essaie d'utiliser des flux et de compter, comme ceci: s->{long r=1,i=s.length();for(;i>0;)r=r*i/(s.chars().skip(--i).filter(c -> c==s.charAt(i)).count()+1);return r;}mais sans succès jusqu'à présent ...
Olivier Grégoire


1

Octave / MATLAB, 35 octets

@(s)size(unique(perms(s),'rows'),1)

Fonction anonyme qui prend un vecteur de caractères et produit un nombre.

Dans MATLAB, cela peut être raccourci à size(unique(perms(s),'ro'),1)(33 octets).

Essayez-le en ligne!

Explication

@(s)                                  % Anonymous function with input s
                perms(s)              % Permutations. Gives a char matrix
         unique(        ,'rows')      % Deduplicate rows
    size(                       ,1)   % Number of rows

1
Je pensais uniquedéjà retourné des lignes uniques? Ou est-ce seulement pour tables?
Giuseppe

@Giuseppe Pour les tableaux 2D numériques / char unique, la linéarisation serait la première. Pour les tableaux, je pense que vous avez raison; Je ne savais pas ça!
Luis Mendo

1
Ah, je sais d'où vient l'idée - uniquedans MATLAB, il faut des lignes pour tables; R uniqueprend des lignes uniques de matrices ou de trames de données. Trop de langages de tableau avec les mêmes commandes qui font des choses légèrement différentes ...
Giuseppe

1

Retina 0.8.2 , 73 octets

(.)(?=(.*?\1)*)
/1$#2$*1x1$.'$*
^
1
+`1(?=1*/(1+)x(\1)+$)|/1+x1+$
$#2$*
1

Essayez-le en ligne! Utilise la formule de @ ArBo, mais évalue de droite à gauche car cela peut être fait en arithmétique entière tout en minimisant la taille des valeurs unaires impliquées. Explication:

(.)(?=(.*?\1)*)
/1$#2$*1x1$.'$*

Pour chaque caractère, comptez le nombre de doublons restants et le nombre de caractères supplémentaires, ajoutez-en un pour prendre en compte le caractère actuel et séparez les valeurs afin de savoir lesquels doivent être divisés et lesquels doivent être multipliés. .

^
1

Préfixez un 1 pour produire une expression complète.

+`1(?=1*/(1+)x(\1)+$)|/1+x1+$
$#2$*

Multipliez de façon répétée le dernier et l'avant-dernier nombre en divisant par l'avant-dernier numéro. Cela remplace les trois derniers chiffres.

1

Convertissez en décimal.


1

K, 27 octets

*/[1+!#:x]%*/{*/1+!x}'#:'x:

K, 16 octets - pas une vraie réponse

#?(999999#0N)?\:

Prenez 999999 permutations aléatoires de la chaîne d'entrée, prenez l'ensemble unique d'entre elles et comptez la longueur. La plupart du temps, il donnera la bonne réponse, pour les chaînes plus courtes.

Amélioré grâce à @Sriotchilism O'Zaic, @Selcuk


2
Bienvenue sur le site! Cela n'a pas vraiment d'importance car elle n'est pas valide, mais pourriez-vous rendre votre réponse invalide plus précise en utilisant à la 999999place de 100000?
Ad Hoc Garf Hunter

Ouais, bonne idée, merci.
Henry Henrinson

1
Et peut-être modifier l'explication pour refléter ce changement aussi?
Selcuk

1

Wolfram Language (Mathematica) , 32 octets

Characters/*Permutations/*Length

Essayez-le en ligne!

Explication: La composition à droite avec /*applique ces trois opérateurs l'un après l'autre à l'argument de fonction, de gauche à droite:

  • Characters convertit la chaîne d'entrée en une liste de caractères.

  • Permutations fait une liste de toutes les permutations uniques de cette liste de caractères.

  • Length renvoie la longueur de cette liste de permutations uniques.

Cette méthode est très inutile pour les chaînes longues: les permutations uniques sont en fait répertoriées et comptées, au lieu d'utiliser a Multinomialpour calculer leur nombre sans les répertorier.



1

Pyth , 5 4 octets

l{.p

Essayez-le en ligne!

Cela suppose que l'entrée est un littéral de chaîne python. Si l'entrée doit être du texte brut, cette version à 5 octets fonctionnera:

l{.pz

Dans les deux cas, il calcule simplement toutes les permutations de l'entrée sous forme de liste, la déduplique et obtient le nombre d'éléments qu'elle contient, et imprime implicitement ce nombre.

-1 octet grâce à @ hakr14


{déduplique une liste pour un octet inférieur à .{.
hakr14

1

J , 14  13 octets

#(%*/)&:!#/.~

Essayez-le en ligne!

1 octet grâce aux miles

#                  length
         #/.~      counts of each unique character
 (%*/)             divide left by the product of right
      &:!          after applying ! to both

1
#(%*/)&:!#/.~devrait sauver un autre octet
miles



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.