Conta tutte le possibili combinazioni uniche di lettere in una parola


12

Ti viene data una stringa, che conterrà i normali caratteri az. (Puoi presumere che questo sarà sempre il caso in qualsiasi test e supporre che anche tutte le lettere saranno minuscole). È necessario determinare quante combinazioni uniche possono essere fatte dei singoli caratteri nella stringa e stampare quel numero.

Tuttavia, le lettere duplicate possono essere ignorate nel conteggio delle possibili combinazioni. In altre parole, se la stringa fornita è "ciao", semplicemente cambiare le posizioni delle due ls non conta come una frase univoca e quindi non può essere conteggiata per il totale.

Vince il conteggio dei byte più breve, in attesa di vedere alcune soluzioni creative in lingue non golf!

Esempi:

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


4
@Giuseppe Non penso che questo sia un inganno; i dettagli di questa domanda consentono implementazioni molto più brevi
ArBo

4
L'aggiunta di alcuni test può essere d'aiuto.
1919

1
@JonathanAllan Ottimo suggerimento! Il titolo è stato modificato di conseguenza.
SimpleGeek,

Risposte:


29

Python 2 , 50 48 byte

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

Provalo online!

Nessun noioso built-in! Con mia sorpresa, questo è ancora più breve dell'approccio della forza bruta, calcolando tutte le permutazioni con itertoolse prendendo la lunghezza.

Questa funzione utilizza la formula

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

e lo calcola al volo. Il fattoriale nel numeratore viene calcolato moltiplicando per len(s)ogni chiamata di funzione. Il denominatore è un po 'più sottile; in ogni chiamata, dividiamo per il numero di occorrenze di quell'elemento in ciò che resta della stringa, assicurando che per ogni carattere c, tutti i numeri tra 1 e la quantità di occorrenze di c(compreso) saranno divisi esattamente una volta. Poiché dividiamo solo alla fine, siamo certi di non avere problemi con la divisione di default del piano di Python 2.


itertools è molto prolisso nei nomi delle sue funzioni
qwr


7

CJam , 4 byte

le!,

Provalo online!

Spiegazione

Leggi la riga come stringa ( l), permutazioni uniche come matrice di stringhe ( e!), lunghezza ( ,), visualizzazione implicita.


4
Sembra "lel", +1! : D
KeyWeeUsr

5

R , 69 65 byte

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

Provalo online!

4 byte salvati grazie a Zahiro Mor in entrambe le risposte.

Calcola direttamente il coefficiente multinomiale.

R , 72 68 byte

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

Provalo online!

Utilizza la funzione di distribuzione multinomiale fornita da dmultinomper estrarre il coefficiente multinomiale.

Si noti che il solito (golfista) x<-table(strsplit(s,""))non funziona all'interno della dmultinomchiamata per un motivo sconosciuto.


2
function(s,! =factorial)(!nchar(s))/prod(!table(strsplit(s,""))) funzionerà. el () è redentant - la tabella sa cercare gli elementi ....
Zahiro Mor,

1
@ZahiroMor ah, certo. Avevo intenzione di provarlo ma non ci sono mai riuscito.
Giuseppe,

5

JavaScript (Node.js) , 49 byte

t=t*viene utilizzato invece di t*=evitare errori di arrotondamento (arrotondando per difetto |til numero) in quanto t=t*garantisce che tutti i risultati intermedi (dal punto di vista dell'operatore) siano numeri interi.

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

Provalo online!

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
(Potenziale errore di arrotondamento in virgola mobile; utilizzare t=t*se si desidera evitarlo.)
Neil

@Neil Sì, non è riuscito quando l'ingresso è aaadegfbbbcccesattamente dovuto all'errore di arrotondamento in virgola mobile
Shieru Asakoto,

Come hai trovato quel test?
Neil,

@Neil Continua ad aggiungere caratteri alla stringa fino a quando si verifica un simile errore di arrotondamento lol
Shieru Asakoto,

@ShieruAsakoto Il titolo è stato modificato; contare è molto meglio. Grazie e bella risposta!
SimpleGeek,







2

Python 2 , 57 byte

lambda s:len(set(permutations(s)))
from itertools import*

Provalo online!

Auto-documentazione: restituisce la lunghezza dell'insieme di permutazioni univoche della stringa di input.

Python 3 , 55 byte

Il merito va ad ArBo su questo:

lambda s:len({*permutations(s)})
from itertools import*

Provalo online!


2

APL (Dyalog Unicode) , 24 byte

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

Provalo online!

Dfn semplice, accetta una stringa come argomento.

Come:

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 caratteri ( 34 31 byte)

WhateverBlocco abbastanza dritto . combdivide la stringa in lettere, permutationsottiene tutte le possibili combinazioni. A causa del modo in cui la coercizione Setdeve essere modificata per joinprima (si »applica joina ciascun elemento nell'elenco).

+*.comb.permutations».join.Set

Provalo online!

(la risposta precedente utilizzata .uniquema Setgarantisce l'unicità e la numerazione della stessa, quindi salva 3).


2

K (oK) , 12 byte

Soluzione:

#?x@prm@!#x:

Provalo online!

Spiegazione:

Utilizza l'ok integrato prm:

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

... che a causa x^/:xessenzialmente genera le permutazioni di "helo"no "hello", quindi abbiamo bisogno di generare le permutazioni di 0 1 2 3 4, usarle per indicizzare "hello"e quindi prendere il conteggio dell'unicità.

#?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 è un operatore specifico ok? Non penso che Vanilla K ce l'abbia?
Henry Henrinson,

Sì - esiste solo in oK secondo il manuale
streetster

@HenryHenrinson afaik non è in k4. all'inizio del k5 lo era !-n. alla fine del k5 e del k6 divenneprm . anche k7 (shakti) prm.
ngn,

2

Java 8, 103 102 byte

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

Porta della risposta Python 2 di @ArBo .
-1 byte grazie a @ OlivierGrégoire rendendolo iterativo anziché ricorsivo.

Provalo online.

Generare effettivamente tutte le permutazioni uniche in un set e ottenere la sua dimensione sarebbe di 221 byte :

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

Provalo online.



@ OlivierGrégoire Grazie! A proposito, vedi qualcosa che accorcia il secondo approccio (generando tutte le permutazioni uniche in un set)? Ho la sensazione che alcuni byte possano essere salvati, ma ho provato alcune cose e la maggior parte erano leggermente più lunghe invece che più corte .. Ma sembra ancora eccessivamente lungo.
Kevin Cruijssen,

Ci ho lavorato, cercando di usare i flussi e contare, in questo modo: 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;}ma finora senza successo ...
Olivier Grégoire,


1

Octave / MATLAB, 35 byte

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

Funzione anonima che accetta un vettore di carattere e produce un numero.

In MATLAB questo può essere ridotto a size(unique(perms(s),'ro'),1)(33 byte).

Provalo online!

Spiegazione

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

1
Pensavo di aver uniquegià restituito righe univoche? O è solo per tables?
Giuseppe,

@Giuseppe Per le matrici 2D numeriche / char uniquesi linearizzerebbe prima. Per i tavoli penso che tu abbia ragione; Non lo sapevo!
Luis Mendo,

1
Ah, so dove ho avuto l'idea - uniquein MATLAB richiede righe tables; R uniqueprende righe univoche di matrici o frame di dati. Troppi linguaggi array con gli stessi comandi che fanno cose leggermente diverse ...
Giuseppe,

1

Retina 0.8.2 , 73 byte

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

Provalo online! Utilizza la formula di @ ArBo, ma valuta da destra a sinistra in quanto ciò può essere fatto in aritmetica intera pur minimizzando la dimensione dei valori unari coinvolti. Spiegazione:

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

Per ogni personaggio, conta quanti duplicati restanti ci sono e quanti altri caratteri ci sono, aggiungine uno a ciascuno per prendere in considerazione il personaggio attuale e separa i valori in modo da sapere quali devono essere divisi e quali devono essere moltiplicati .

^
1

Prefisso a 1 per produrre un'espressione completa.

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

Moltiplicare ripetutamente l'ultimo e il terzo ultimo numero mentre si divide per il secondo ultimo numero. Questo sostituisce gli ultimi tre numeri.

1

Converti in decimale.


1

K, 27 byte

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

K, 16 byte - non una vera risposta

#?(999999#0N)?\:

Prendi 999999 permutazioni casuali della stringa di input, prendine il set unico e conta la lunghezza. La maggior parte delle volte darà la risposta giusta, per stringhe a corto raggio.

Migliorato grazie a @Sriotchilism O'Zaic, @Selcuk


2
Benvenuti nel sito! Non importa davvero perché non è valido, ma potresti rendere più precisa la tua risposta non valida utilizzando 999999invece di 100000?
Ad Hoc Garf Hunter,

Sì, buona idea, grazie.
Henry Henrinson,

1
E forse modificare la spiegazione per riflettere anche quel cambiamento?
Selcuk,

1

Wolfram Language (Mathematica) , 32 byte

Characters/*Permutations/*Length

Provalo online!

Spiegazione: La composizione a destra con /*applica questi tre operatori uno dopo l'altro all'argomento della funzione, da sinistra a destra:

  • Characters converte la stringa di input in un elenco di caratteri.

  • Permutations crea un elenco di tutte le permutazioni uniche di questo elenco di caratteri.

  • Length restituisce la lunghezza di questo elenco di permutazioni uniche.

Questo metodo è molto dispendioso per le stringhe lunghe: le permutazioni uniche sono effettivamente elencate e contate, invece di usare a Multinomialper calcolare il loro numero senza elencare.



1

Pyth , 5 4 byte

l{.p

Provalo online!

Ciò presuppone che l'input sia una stringa di pitone letterale. Se l'input deve essere un testo non elaborato, questa versione a 5 byte funzionerà:

l{.pz

Ad ogni modo, calcola semplicemente tutte le permutazioni dell'input come un elenco, lo deduplica e ottiene il numero di elementi in esso, e stampa implicitamente quel numero.

-1 byte grazie a @ hakr14


{deduplica un elenco per un byte inferiore a .{.
hakr14

1

J , 14  13 byte

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

Provalo online!

1 byte grazie alle miglia

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

1
#(%*/)&:!#/.~dovrebbe salvare un altro byte
miglia


0

Ohm v2 , 4 byte

ψD∩l

Provalo online!

Spiegazione

   l    output the lenght of
  ∩     the set intersection between
ψD      two copies of all possible permutation of input

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.