Zählen Sie alle möglichen eindeutigen Buchstabenkombinationen in einem Wort

11

Sie erhalten eine Zeichenfolge, die normale Az-Zeichen enthält. (Sie können davon ausgehen, dass dies bei jedem Test immer der Fall ist, und davon ausgehen, dass alle Buchstaben ebenfalls in Kleinbuchstaben geschrieben sind.) Sie müssen bestimmen, wie viele eindeutige Kombinationen der einzelnen Zeichen in der Zeichenfolge erstellt werden können, und diese Zahl drucken.

Doppelte Buchstaben können jedoch beim Zählen der möglichen Kombinationen ignoriert werden. Mit anderen Worten, wenn die angegebene Zeichenfolge "Hallo" ist, zählt das einfache Umschalten der Positionen der beiden ls nicht als eindeutige Phrase und kann daher nicht zur Gesamtsumme gezählt werden.

Die kürzeste Byte-Anzahl gewinnt und wir freuen uns darauf, einige kreative Lösungen in Nicht-Golf-Sprachen zu sehen!

Beispiele:

hello -> 60
aaaaa -> 1
abcde -> 120
I_P_Edwards
quelle
4
@ Giuseppe Ich denke nicht, dass dies ein Betrug davon ist; Die Besonderheiten dieser Frage ermöglichen viel kürzere Implementierungen
ArBo
4
Das Hinzufügen einiger Testfälle kann hilfreich sein.
tsh
1
@ JonathanAllan Guter Vorschlag! Titel entsprechend geändert.
I_P_Edwards

Antworten:

29

Python 2 , 50 48 Bytes

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

Probieren Sie es online aus!

Keine langweiligen Einbauten! Zu meiner Überraschung ist dies sogar noch kürzer als der Brute-Force-Ansatz, bei dem alle Permutationen mit berechnet itertoolsund die Länge genommen werden.

Diese Funktion verwendet die Formel

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

und berechnet es im laufenden Betrieb. Die Fakultät im Zähler wird durch Multiplikation mit len(s)in jedem Funktionsaufruf berechnet . Der Nenner ist etwas subtiler; Bei jedem Aufruf dividieren wir durch die Anzahl der Vorkommen dieses Elements in den verbleibenden Teilen der Zeichenfolge, um sicherzustellen, dass für jedes Zeichen calle Zahlen zwischen 1 und der Anzahl der Vorkommen von c(einschließlich) durch genau einmal geteilt werden. Da wir nur ganz am Ende teilen, haben wir garantiert keine Probleme mit der Standard-Bodenteilung von Python 2.

ArBo
quelle
itertools ist sehr ausführlich in seinen Funktionsnamen
qwr
16

05AB1E , 3 Bytes

œÙg

Probieren Sie es online aus!

Erläuterung

  g  # length of the list
 Ù   # of unique
œ    # permutations
     # of the input
Emigna
quelle
7

CJam , 4 Bytes

le!,

Probieren Sie es online aus!

Erläuterung

Zeile als Zeichenfolge lesen ( l), eindeutige Permutationen als Array von Zeichenfolgen ( e!), Länge ( ,), implizite Anzeige.

Luis Mendo
quelle
4
Sieht aus wie "lel", +1! : D
KeyWeeUsr
5

R , 69 65 Bytes

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

Probieren Sie es online aus!

4 Bytes gespeichert dank Zahiro Mor in beiden Antworten.

Berechnet den Multinomialkoeffizienten direkt.

R , 72 68 Bytes

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

Probieren Sie es online aus!

Verwendet die Multinomialverteilungsfunktion von dmultinom, um den Multinomialkoeffizienten zu extrahieren.

Beachten Sie, dass der übliche (Golfspieler) aus einem unbekannten Grund x<-table(strsplit(s,""))nicht innerhalb des dmultinomAnrufs funktioniert .

Giuseppe
quelle
2
function(s,! =factorial)(!nchar(s))/prod(!table(strsplit(s,""))) wird funktionieren. das el () ist redundant - Tabelle weiß, um die Elemente zu suchen ....
Zahiro Mor
1
@ ZahiroMor ah, natürlich. Ich hatte vor, das zu testen, kam aber nie dazu.
Giuseppe
5

JavaScript (Node.js) , 49 Byte

t=t*wird verwendet t*=, um Rundungsfehler (das Abrunden |tder Zahl) zu vermeiden, um sicherzustellen t=t*, dass alle Zwischenergebnisse (in Bezug auf den Bediener) ganze Zahlen sind.

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

Probieren Sie es online aus!

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
Shieru Asakoto
quelle
2
(Möglicher Gleitkomma-Rundungsfehler; verwenden t=t*Sie, wenn Sie dies vermeiden möchten.)
Neil
@Neil Ja, es ist fehlgeschlagen, wenn die Eingabe aaadegfbbbcccgenau auf den Gleitkomma-Rundungsfehler zurückzuführen ist
Shieru Asakoto
Wie haben Sie diesen Testfall gefunden?
Neil
@Neil Fügen Sie der Zeichenfolge weitere Zeichen hinzu, bis ein solcher Rundungsfehler auftritt.
Lol
@ShieruAsakoto Titel wurde geändert; zählen ist viel besser. Danke und nette Antwort!
I_P_Edwards
4

Japt , 5 3 Bytes

-2 Bytes dank @Shaggy

á l

Probieren Sie es online aus!

Luis felipe De jesus Munoz
quelle
TIO scheint eine alte Version von Japt zu verwenden, mit der Sie das Problem lösen können â.
Shaggy
@ Shaggy Lol, das habe ich nicht bemerkt. Vielen Dank!
Luis Felipe De Jesus Munoz
4

J , 15 , 14 Bytes

[:#@=i.@!@#A.]

Probieren Sie es online aus!

-1 Byte dank FrownyFrog

Jona
quelle
~.kann sein=
FrownyFrog
Nett. Vielen Dank, @FrownyFrog
Jonah
2

Python 2 , 57 Bytes

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

Probieren Sie es online aus!

Selbstdokumentierend: Gibt die Länge des Satzes eindeutiger Permutationen der Eingabezeichenfolge zurück.

Python 3 , 55 Bytes

Gutschrift geht an ArBo in diesem Fall :

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

Probieren Sie es online aus!

Stellen Sie Monica wieder her
quelle
2

APL (Dyalog Unicode) , 24 Bytes

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

Probieren Sie es online aus!

Einfache Dfn, nimmt eine Zeichenfolge als Argument.

Wie:

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
J. Sallé
quelle
2

Ruby , 41 Bytes

f=->s{s.chars.permutation.to_a.uniq.size}

Probieren Sie es online aus!

thowawayacc89023489
quelle
1
Ich glaube nicht, dass Sie brauchento_a
ArBo
1
Und anonyme Funktionen / Lambdas sind akzeptabel, sodass Sie das f=Teil entfernen können . (In TIO verschieben Sie es in den Header, um nicht gezählt zu werden.)
Manatwork
2

Perl 6 , 33 30 Zeichen ( 34 31 Bytes)

Ziemlich geradliniger WhateverBlock. combteilt den String in Buchstaben auf, permutationserhält alle möglichen Kombinationen. Aufgrund der Art und Weise Zwang Setbraucht werden joinzuerst ed ( »gilt joinfür jedes Element in der Liste).

+*.comb.permutations».join.Set

Probieren Sie es online aus!

(Die vorherige Antwort wurde verwendet .unique, Setgarantiert jedoch die Eindeutigkeit und nummeriert sie, sodass 3 gespart werden.)

user0721090601
quelle
2

K (oK) , 12 Bytes

Lösung:

#?x@prm@!#x:

Probieren Sie es online aus!

Erläuterung:

Verwendet das integrierte OK prm:

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

... die im x^/:xGrunde genommen die Permutationen von "helo"nicht erzeugen "hello", daher müssen wir die Permutationen von erzeugen 0 1 2 3 4, sie verwenden, um sie zu indizieren "hello"und dann die Anzahl der eindeutigen zu nehmen.

#?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 (#)
Streetster
quelle
Ist prm ein ok spezifischer Operator? Ich glaube nicht, dass Vanille k es hat?
Henry Henrinson
Yup - existiert nur in oK gemäß dem Handbuch
Streetster
@ HenryHenrinson afaik es ist nicht in k4. im frühen k5 war es !-n. Ende k5 und k6 wurde esprm . k7 (shakti) hat prmauch.
ngn
2

Java 8, 103 102 Bytes

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 von @ArBos Python 2-Antwort .
-1 Byte dank @ OlivierGrégoire, indem es iterativ statt rekursiv gemacht wird.

Probieren Sie es online aus.

Das Erzeugen aller eindeutigen Permutationen in einem Satz und das Erhalten seiner Größe würde 221 Bytes betragen :

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

Probieren Sie es online aus.

Kevin Cruijssen
quelle
Okay, ich könnte ein Byte Golf spielen, indem ich es iterativ anstatt rekursiv mache : 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 Danke! Übrigens, sehen Sie etwas, um den zweiten Ansatz (Generieren aller eindeutigen Permutationen in einer Menge) zu verkürzen? Ich habe das Gefühl, dass einige Bytes gespeichert werden können, aber einige Dinge ausprobiert haben und die meisten etwas länger statt kürzer waren. Aber es sieht immer noch zu lang aus.
Kevin Cruijssen
Ich habe daran gearbeitet, versucht, Streams zu verwenden und so zu zählen: 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;}aber bisher ohne Erfolg ...
Olivier Grégoire
1

Oktave / MATLAB, 35 Bytes

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

Anonyme Funktion, die einen Zeichenvektor verwendet und eine Zahl erzeugt.

In MATLAB kann dies auf size(unique(perms(s),'ro'),1)(33 Bytes) gekürzt werden .

Probieren Sie es online aus!

Erläuterung

@(s)                                  % Anonymous function with input s
                perms(s)              % Permutations. Gives a char matrix
         unique(        ,'rows')      % Deduplicate rows
    size(                       ,1)   % Number of rows
Luis Mendo
quelle
1
Ich dachte, es werden uniquebereits eindeutige Zeilen zurückgegeben? Oder ist das nur für tables?
Giuseppe
@Giuseppe Für numerische / char 2D-Arrays uniquewürden zuerst linearisiert. Für Tische denke ich, dass Sie Recht haben; Das wusste ich nicht!
Luis Mendo
1
Ah, ich weiß, woher ich die Idee habe - uniquein MATLAB werden Zeilen für genommen tables; Rs uniquenimmt eindeutige Zeilen von Matrizen oder Datenrahmen. Zu viele Array-Sprachen mit denselben Befehlen, die leicht unterschiedliche
Giuseppe
1

Retina 0,8,2 , 73 Bytes

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

Probieren Sie es online aus! Verwendet die Formel von @ ArBo, wird jedoch von rechts nach links ausgewertet, da dies in ganzzahliger Arithmetik erfolgen kann, während die Größe der beteiligten unären Werte weiterhin minimiert wird. Erläuterung:

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

Zählen Sie für jedes Zeichen, wie viele Duplikate noch vorhanden sind und wie viele weitere Zeichen vorhanden sind, fügen Sie jeweils eines hinzu, um das aktuelle Zeichen zu berücksichtigen, und trennen Sie die Werte, damit wir wissen, welche geteilt und welche multipliziert werden sollen .

^
1

Stellen Sie eine 1 voran, um einen vollständigen Ausdruck zu erhalten.

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

Multiplizieren Sie wiederholt die vorletzte und drittletzte Zahl, während Sie durch die vorletzte Zahl dividieren. Dies ersetzt die letzten drei Zahlen.

1

In Dezimalzahl konvertieren.

Neil
quelle
1

K, 27 Bytes

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

K, 16 Bytes - keine echte Antwort

#?(999999#0N)?\:

Nehmen Sie 999999 zufällige Permutationen der Eingabezeichenfolge, nehmen Sie die eindeutige Menge davon und zählen Sie die Länge. Meistens gibt es die richtige Antwort für kurze Saiten.

Verbessert dank @Sriotchilism O'Zaic, @Selcuk

Henry Henrinson
quelle
2
Willkommen auf der Seite! Ist nicht wirklich wichtig, da es ungültig ist, aber könnten Sie Ihre ungültige Antwort genauer machen, indem Sie 999999statt verwenden 100000?
Post Rock Garf Hunter
Ja, gute Idee, danke.
Henry Henrinson
1
Und vielleicht die Erklärung bearbeiten, um diese Änderung auch widerzuspiegeln?
Selcuk
1

Wolfram Language (Mathematica) , 32 Bytes

Characters/*Permutations/*Length

Probieren Sie es online aus!

Erläuterung: Die /*Rechtskomposition mit wendet diese drei Operatoren nacheinander von links nach rechts auf das Funktionsargument an:

  • Characters konvertiert die Eingabezeichenfolge in eine Liste von Zeichen.

  • Permutations erstellt eine Liste aller eindeutigen Permutationen dieser Zeichenliste.

  • Length Gibt die Länge dieser Liste eindeutiger Permutationen zurück.

Diese Methode ist für lange Zeichenfolgen sehr verschwenderisch: Die eindeutigen Permutationen werden tatsächlich aufgelistet und gezählt, anstatt a Multinomialzu verwenden, um ihre Anzahl ohne Auflistung zu berechnen.

römisch
quelle
1

Pyth , 5 4 Bytes

l{.p

Probieren Sie es online aus!

Dies setzt voraus, dass die Eingabe ein Python-String-Literal ist. Wenn die Eingabe Rohtext sein muss, funktioniert diese 5-Byte-Version:

l{.pz

In beiden Fällen werden nur alle Permutationen der Eingabe als Liste berechnet, dedupliziert, die Anzahl der darin enthaltenen Elemente ermittelt und diese Anzahl implizit gedruckt.

-1 Byte dank @ hakr14

randomdude999
quelle
{dedupliziert eine Liste für ein Byte kleiner als .{.
hakr14
1

J , 14  13 Bytes

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

Probieren Sie es online aus!

1 Byte dank Meilen

#                  length
         #/.~      counts of each unique character
 (%*/)             divide left by the product of right
      &:!          after applying ! to both
FrownyFrog
quelle
1
#(%*/)&:!#/.~sollte ein weiteres Byte
Meilen