Policz wszystkie możliwe unikalne kombinacje liter w jednym słowie

12

Otrzymasz ciąg znaków, który będzie zawierał zwykłe znaki az. (Możesz założyć, że tak będzie zawsze w każdym teście, i załóż, że wszystkie litery również będą pisane małymi literami). Musisz określić, ile unikalnych kombinacji można utworzyć z poszczególnych znaków w ciągu, i wydrukować tę liczbę.

Jednak zduplikowane litery można zignorować, licząc możliwe kombinacje. Innymi słowy, jeśli podany ciąg to „hello”, to po prostu zmiana pozycji dwóch ls nie jest liczona jako unikalna fraza i dlatego nie może być liczona do sumy.

Zwycięża najkrótsza liczba bajtów, czekamy na kreatywne rozwiązania w językach innych niż golf!

Przykłady:

hello -> 60
aaaaa -> 1
abcde -> 120
SimpleGeek
źródło
4
@Giuseppe Nie sądzę, że jest to duplikat tego; specyfika tego pytania pozwala na znacznie krótsze wdrożenia
ArBo
4
Dodanie niektórych przypadków testowych może pomóc.
tsh
1
@JathanathanAllan Dobra sugestia! Tytuł odpowiednio się zmienił.
SimpleGeek

Odpowiedzi:

29

Python 2 , 50 48 bajtów

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

Wypróbuj online!

Żadnych nudnych wbudowanych funkcji! Ku mojemu zdziwieniu jest to nawet krótsze niż podejście z użyciem brutalnej siły, obliczając wszystkie permutacje itertoolsi biorąc pod uwagę długość.

Ta funkcja korzysta ze wzoru

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

i oblicza go w locie. Silnia w liczniku jest obliczana przez pomnożenie przez len(s)w każdym wywołaniu funkcji. Mianownik jest nieco bardziej subtelny; w każdym wywołaniu dzielimy przez liczbę wystąpień tego elementu w pozostałej części łańcucha, zapewniając, że dla każdego znaku cwszystkie liczby od 1 do liczby wystąpień c(włącznie) zostaną podzielone przez dokładnie jeden raz. Ponieważ dzielimy tylko na samym końcu, gwarantujemy, że nie będziemy mieć problemów z domyślnym podziałem podłogi w Python 2.

ArBo
źródło
itertools jest bardzo gadatliwy w nazwach swoich funkcji
qwr
16

05AB1E , 3 bajty

œÙg

Wypróbuj online!

Wyjaśnienie

  g  # length of the list
 Ù   # of unique
œ    # permutations
     # of the input
Emigna
źródło
7

CJam , 4 bajty

le!,

Wypróbuj online!

Wyjaśnienie

Czytaj linię jako ciąg znaków ( l), unikalne permutacje jako tablicę ciągów znaków ( e!), długości ( ,), niejawne wyświetlanie.

Luis Mendo
źródło
4
Wygląda jak „lel”, +1! : D
KeyWeeUsr
5

R , 69 65 bajtów

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

Wypróbuj online!

4 bajty zapisane dzięki Zahiro Morowi w obu odpowiedziach.

Oblicza bezpośrednio współczynnik wielomianowy.

R , 72 68 bajtów

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

Wypróbuj online!

Korzysta z funkcji rozkładu wielomianowego podanej w dmultinomcelu wyodrębnienia współczynnika wielomianowego.

Pamiętaj, że zwykły (golfista) x<-table(strsplit(s,""))nie działa w dmultinompołączeniu z nieznanego powodu.

Giuseppe
źródło
2
function(s,! =factorial)(!nchar(s))/prod(!table(strsplit(s,""))) będzie działać. el () jest reduntant - tabela wie, jak szukać elementów ....
Zahiro Mor
1
@ZahiroMor ah, oczywiście. Zamierzałem to przetestować, ale nigdy do tego nie doszło.
Giuseppe
5

JavaScript (Node.js) , 49 bajtów

t=t*służy t*=do uniknięcia błędu zaokrąglania ( |tzaokrągla liczbę w dół), ponieważ t=t*gwarantuje, że wszystkie wyniki pośrednie ( z punktu widzenia operatora) są liczbami całkowitymi.

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

Wypróbuj 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
Shieru Asakoto
źródło
2
(Potencjalny błąd zaokrąglania zmiennoprzecinkowego; użyj, t=t*jeśli chcesz tego uniknąć.)
Neil
@Neil Tak, nie udało się, gdy dane wejściowe są aaadegfbbbcccdokładnie spowodowane błędem zaokrąglenia zmiennoprzecinkowego
Shieru Asakoto
Huh, jak znalazłeś ten przypadek testowy?
Neil
@Neil Dodawaj znaki do łańcucha, dopóki nie wystąpi taki błąd zaokrąglania lol
Shieru Asakoto
@ShieruAsakoto Tytuł został zmieniony; liczba jest znacznie lepsza. Dzięki i miła odpowiedź!
SimpleGeek
4

APL (Dyalog Unicode) , 14 bajtów

!∘⍴÷⊂×.(!∘⍴∩)∪

Wypróbuj online!

Zwraca wynik jako singleton.

Erik the Outgolfer
źródło
-> aby zwrócić proste skalary, ÷⍨/g⌸,g←!⊢∘≢dla -2
ngn
4

Japt , 5 3 bajty

-2 bajty dzięki @Shaggy

á l

Wypróbuj online!

Luis Felipe De Jesus Munoz
źródło
Wydaje się, że TIO uruchamia starą wersję Japt, pozwalając na porzucenie â.
Kudłaty
@Shaggy Lol, nie zauważyłem tego. dzięki!
Luis felipe De jesus Munoz
4

J , 15 , 14 bajtów

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

Wypróbuj online!

-1 bajt dzięki FrownyFrog

Jonasz
źródło
~.może być=
FrownyFrog
Ładny. Dziękuję, @FrownyFrog
Jonah
3

Brachylog , 3 bajty

pᶜ¹

Wypróbuj online!

       The output is
 ᶜ¹    the number of unique
p      permutations of
       the input.

pᵘl robi prawie dokładnie to samo.

Niepowiązany ciąg
źródło
2

Python 2 , 57 bajtów

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

Wypróbuj online!

Self-documenting: Zwraca długość zestawu unikalnych permutacji ciągu wejściowego.

Python 3 , 55 bajtów

Uznanie dla ArBo za to:

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

Wypróbuj online!

kałamarnica
źródło
2

APL (Dyalog Unicode) , 24 bajty

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

Wypróbuj online!

Prosty Dfn, przyjmuje ciąg znaków jako argument.

W jaki sposób:

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é
źródło
2

Rubinowy , 41 bajtów

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

Wypróbuj online!

thowawayacc89023489
źródło
1
Nie sądzę, że potrzebujeszto_a
ArBo,
1
A anonimowe funkcje / lambdy są dopuszczalne, więc możesz usunąć f=część. (W TIO przenieś go do
Nagłówka,
2

Perl 6 , 33 30 znaków ( 34 31 bajtów)

Dość prosty Whateverblok. combdzieli ciąg na litery, permutationsuzyskuje wszystkie możliwe kombinacje. Ze względu na sposób, w jaki Setnależy joinnajpierw »zastosować przymus ( dotyczy joinkażdego elementu na liście).

+*.comb.permutations».join.Set

Wypróbuj online!

(poprzednia użyta odpowiedź, .uniqueale Sets gwarantuje unikatowość i numeruje to samo, więc oszczędza 3).

użytkownik 0721090601
źródło
2

K (oK) , 12 bajtów

Rozwiązanie:

#?x@prm@!#x:

Wypróbuj online!

Wyjaśnienie:

Wykorzystuje wbudowane OK prm:

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

... który w x^/:xzasadzie generuje permutacje "helo"nie "hello", dlatego musimy wygenerować permutacje 0 1 2 3 4, użyć ich do indeksowania, "hello"a następnie policzyć unikalność.

#?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
źródło
Czy prm jest ok konkretnym operatorem? Nie sądzę, że ma waniliowy k?
Henry Henrinson
Tak - istnieje tylko w ok według instrukcji
streetster
@HenryHenrinson afaik nie ma go w k4. na początku k5 było !-n. pod koniec k5 i k6 stało sięprm . K7 (Shakti) prmteż ma .
ngn
2

Java 8, 103 102 bajtów

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 odpowiedzi @ArBo na Python 2 .
-1 bajt dzięki @ OlivierGrégoire poprzez iterację zamiast rekurencji.

Wypróbuj online.

W rzeczywistości wygenerowanie wszystkich unikalnych permutacji w zestawie i uzyskanie jego rozmiaru wynosi 221 bajtów :

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

Wypróbuj online.

Kevin Cruijssen
źródło
Ok, mogę golf bajt czyniąc go iteracyjny zamiast rekurencyjne: 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 Thanks! Przy okazji, widzisz coś, co skraca drugie podejście (generowanie wszystkich unikalnych permutacji w zestawie)? Mam wrażenie, że niektóre bajty można zapisać, ale próbowałem pewnych rzeczy, a większość z nich była nieco dłuższa, a nie krótsza. Ale wciąż wygląda na zbyt długo.
Kevin Cruijssen
Pracowałem nad tym, próbując używać strumieni i liczyć, w ten sposób: 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;}ale jak dotąd bez powodzenia ...
Olivier Grégoire,
1

MATL , 9 bajtów

jY@XuZy1)

Wypróbuj online!

Wyjaśnienie:

j input as string
Y@ get permutations
Xu unique members
Zy size matrix
1) first member of size matrix
Wiśnie Pomarańczowe
źródło
2
Możesz wziąć dane wejściowe z cudzysłowami, więc jstaje się i, co można pozostawić niejawne. Również &nxzapisuje bajt nad Zy1) tio.run/##y00syfn/P9IholQtr@L/f/WM1JycfHUA
Luis Mendo
1

Octave / MATLAB, 35 bajtów

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

Anonimowa funkcja, która pobiera wektor znaków i tworzy liczbę.

W MATLAB można to skrócić do size(unique(perms(s),'ro'),1)(33 bajtów).

Wypróbuj online!

Wyjaśnienie

@(s)                                  % Anonymous function with input s
                perms(s)              % Permutations. Gives a char matrix
         unique(        ,'rows')      % Deduplicate rows
    size(                       ,1)   % Number of rows
Luis Mendo
źródło
1
Myślałem, że zwróciłem uniquejuż unikalne wiersze? Czy to tylko dla tables?
Giuseppe
@Giuseppe Dla tablic numerycznych / char 2D uniquenajpierw ulegałyby linearyzacji. W przypadku stolików myślę, że masz rację; Nie wiedziałem tego!
Luis Mendo
1
Ach, wiem skąd mam pomysł - uniquew MATLAB bierze wierszetables ; R uniquepobiera unikalne rzędy macierzy lub ramek danych. Zbyt wiele języków tablic z tymi samymi poleceniami, które robią nieco inne rzeczy ...
Giuseppe,
1

Retina 0.8.2 , 73 bajty

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

Wypróbuj online! Wykorzystuje formułę @ ArBo, ale ocenia od prawej do lewej, ponieważ można tego dokonać w arytmetyce liczb całkowitych, jednocześnie minimalizując wielkość zaangażowanych wartości jednostkowych. Wyjaśnienie:

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

Dla każdego znaku policz, ile pozostało duplikatów i ile jest kolejnych znaków, dodaj po jednym do każdego z nich, aby uwzględnić bieżący znak, i rozdziel wartości, abyśmy wiedzieli, które z nich mają zostać podzielone, a które należy pomnożyć .

^
1

Przedrostek 1, aby uzyskać pełne wyrażenie.

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

Kilkakrotnie pomnóż ostatnią i trzecią ostatnią liczbę, dzieląc ją przez drugą ostatnią liczbę. Zastępuje to ostatnie trzy liczby.

1

Konwertuj na dziesiętny.

Neil
źródło
1

K, 27 bajtów

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

K, 16 bajtów - nie jest to prawdziwa odpowiedź

#?(999999#0N)?\:

Weź 999999 losowych kombinacji łańcucha wejściowego, weź ich unikalny zestaw i policz długość. Przez większość czasu daje właściwą odpowiedź, w przypadku krótkich łańcuchów.

Poprawiono dzięki @Sriotchilism O'Zaic, @Selcuk

Henry Henrinson
źródło
2
Witamy na stronie! To naprawdę nie ma znaczenia, ponieważ jest nieważne, ale czy możesz poprawić swoją nieprawidłową odpowiedź, używając 999999zamiast niej 100000?
Ad Hoc Garf Hunter,
Tak, dobry pomysł, dzięki.
Henry Henrinson
1
A może edytować wyjaśnienie, aby odzwierciedlić tę zmianę?
Selcuk
1

Wolfram Language (Mathematica) , 32 bajty

Characters/*Permutations/*Length

Wypróbuj online!

Objaśnienie: Kompozycja po prawej stronie /*stosuje te trzy operatory jeden po drugim do argumentu funkcji, od lewej do prawej:

  • Characters konwertuje wejściowy ciąg znaków na listę znaków.

  • Permutations tworzy listę wszystkich unikalnych kombinacji tej listy znaków.

  • Length zwraca długość tej listy unikalnych permutacji.

Ta metoda jest bardzo marnotrawna w przypadku długich ciągów: unikatowe permutacje są faktycznie wyświetlane i liczone, zamiast używać a Multinomialdo obliczania ich liczby bez wyświetlania.

rzymski
źródło
1

Pyt , 5 4 bajtów

l{.p

Wypróbuj online!

Zakłada się, że dane wejściowe to literał ciągu znaków w języku Python. Jeśli dane wejściowe muszą być surowym tekstem, ta 5-bajtowa wersja będzie działać:

l{.pz

Tak czy inaczej, po prostu oblicza wszystkie permutacje danych wejściowych jako listę, deduplikuje je, pobiera liczbę elementów i domyślnie drukuje tę liczbę.

-1 bajt dzięki @ hakr14

randomdude999
źródło
{deduplikuje listę dla bajtu mniejszego niż .{.
hakr14
1

J , 14  13 bajtów

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

Wypróbuj online!

1 bajt dzięki milom

#                  length
         #/.~      counts of each unique character
 (%*/)             divide left by the product of right
      &:!          after applying ! to both
FrownyFrog
źródło
1
#(%*/)&:!#/.~powinien oszczędzić kolejny bajt
mile
0

Ohm v2 , 4 bajty

ψD∩l

Wypróbuj online!

Wyjaśnienie

   l    output the lenght of
  ∩     the set intersection between
ψD      two copies of all possible permutation of input
Cinaski
źródło