Hitung Semua Kombinasi Surat Unik yang Mungkin Ada dalam Kata

12

Anda diberi string, yang akan berisi karakter az biasa. (Anda dapat mengasumsikan ini akan selalu menjadi kasus dalam tes apa pun, dan menganggap bahwa semua huruf juga huruf kecil). Anda harus menentukan berapa banyak kombinasi unik yang dapat dibuat dari masing-masing karakter dalam string, dan mencetak nomor itu.

Namun, surat duplikat dapat diabaikan dalam menghitung kemungkinan kombinasi. Dengan kata lain, jika string yang diberikan adalah "halo", maka hanya beralih posisi dua ls tidak dihitung sebagai frasa unik, dan karena itu tidak dapat dihitung terhadap total.

Kemenangan jumlah byte terpendek, menanti untuk melihat beberapa solusi kreatif dalam bahasa non-golf!

Contoh:

hello -> 60
aaaaa -> 1
abcde -> 120
SimpleGeek
sumber
4
@ Giuseppe Saya tidak berpikir ini adalah penipuan itu; spesifikasi pertanyaan ini memungkinkan implementasi yang jauh lebih pendek
ArBo
4
Menambahkan beberapa testcases dapat membantu.
tsh
1
@ JonathanAllan Saran bagus! Judul diubah sesuai.
SimpleGeek

Jawaban:

29

Python 2 , 50 48 byte

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

Cobalah online!

Tidak ada built-in yang membosankan! Yang mengejutkan saya, ini bahkan lebih pendek daripada pendekatan brute force, menghitung semua permutasi dengan itertoolsdan mengambil panjangnya.

Fungsi ini menggunakan rumus

# of unique permutations=(# of elements)!unique elements(# kejadian elemen itu)!

dan menghitungnya dengan cepat. Faktorial dalam pembilang dihitung dengan mengalikan dengan len(s)dalam setiap pemanggilan fungsi. Penyebutnya sedikit lebih halus; dalam setiap panggilan, kami membaginya dengan jumlah kemunculan elemen dalam apa yang tersisa dari string, memastikan bahwa untuk setiap karakter c, semua angka antara 1 dan jumlah kemunculan c(inklusif) akan dibagi dengan tepat sekali. Karena kami hanya membagi di bagian paling akhir, kami dijamin tidak akan memiliki masalah dengan pembagian lantai standar Python 2.

ArBo
sumber
itertools sangat verbose dalam nama fungsinya
qwr
16

05AB1E , 3 byte

œÙg

Cobalah online!

Penjelasan

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

CJam , 4 byte

le!,

Cobalah online!

Penjelasan

Baca baris sebagai string ( l), permutasi unik sebagai array string ( e!), length ( ,), tampilan implisit.

Luis Mendo
sumber
4
Sepertinya "lel", +1! : D
KeyWeeUsr
5

R , 69 65 byte

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

Cobalah online!

4 byte disimpan berkat Zahiro Mor di kedua jawaban.

Menghitung koefisien multinomial secara langsung.

R , 72 68 byte

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

Cobalah online!

Menggunakan fungsi distribusi multinomial yang disediakan oleh dmultinomuntuk mengekstrak koefisien multinomial.

Perhatikan bahwa golf (biasa) x<-table(strsplit(s,""))tidak berfungsi di dalam dmultinompanggilan untuk alasan yang tidak diketahui.

Giuseppe
sumber
2
function(s,! =factorial)(!nchar(s))/prod(!table(strsplit(s,""))) akan bekerja. el () redupant - tabel tahu untuk mencari elemen ....
Zahiro Mor
1
@ZahiroMor ah, tentu saja. Saya bermaksud menguji itu tetapi tidak pernah berhasil.
Giuseppe
5

JavaScript (Node.js) , 49 byte

t=t*digunakan alih-alih t*=untuk menghindari kesalahan pembulatan (pembulatan ke |tbawah angka) sebagai t=t*jaminan bahwa semua hasil antara (berdasarkan operator) adalah bilangan bulat.

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

Cobalah 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
sumber
2
(Potensi kesalahan pembulatan floating-point; gunakan t=t*jika Anda ingin menghindari itu.)
Neil
@Neil Ya gagal ketika input aaadegfbbbcccpersis karena kesalahan pembulatan titik-mengambang
Shieru Asakoto
Hah, bagaimana Anda menemukan test case itu?
Neil
@Neil Terus menambahkan karakter ke string sampai kesalahan pembulatan seperti itu terjadi lol
Shieru Asakoto
@ShieruAsakoto Title telah diubah; menghitung jauh lebih baik. Terima kasih, dan jawaban yang bagus!
SimpleGeek
4

APL (Dyalog Unicode) , 14 byte

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

Cobalah online!

Mengembalikan hasilnya sebagai singleton.

Erik the Outgolfer
sumber
-> untuk membuatnya mengembalikan skalar sederhana, ÷⍨/g⌸,g←!⊢∘≢untuk -2
ngn
4

Japt , 5 3 byte

-2 byte terima kasih kepada @Shaggy

á l

Cobalah online!

Luis felipe De jesus Munoz
sumber
TIO tampaknya menjalankan versi lama dari Japt, memungkinkan Anda untuk membuang â.
Shaggy
@Shaggy Lol, saya tidak menyadarinya. Terima kasih!
Luis felipe De jesus Munoz
4

J , 15 , 14 byte

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

Cobalah online!

-1 byte terima kasih kepada FrownyFrog

Jonah
sumber
~.bisa=
FrownyFrog
Bagus. Terima kasih, @FrownyFrog
Jonah
3

Jelly , 4 byte

Œ!QL

Cobalah online!

Cukup lakukan apa yang diminta: temukan permutasi input, uniquify, dan cetak panjangnya.

Nick Kennedy
sumber
3

Brachylog , 3 byte

pᶜ¹

Cobalah online!

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

pᵘl melakukan hal yang persis sama.

String yang tidak terkait
sumber
2

Python 2 , 57 byte

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

Cobalah online!

Mendokumentasikan sendiri: Mengembalikan panjang himpunan permutasi unik dari string input.

Python 3 , 55 byte

Kredit jatuh ke ArBo untuk yang satu ini:

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

Cobalah online!

cumi-cumi
sumber
2

APL (Dyalog Unicode) , 24 byte

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

Cobalah online!

Dfn sederhana, mengambil string sebagai argumen.

Bagaimana:

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é
sumber
2

Ruby , 41 byte

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

Cobalah online!

thowawayacc89023489
sumber
1
Saya rasa Anda tidak perluto_a
ArBo
1
Dan fungsi anonim / lambdas dapat diterima, sehingga Anda dapat menghapus f=bagian tersebut. (Di TIO pindahkan ke Header untuk tidak dihitung.)
manatwork
2

Perl 5 , 43 byte

Menggunakan metode dalam jawaban Python @ ArBo.

sub c{!@_||@_*c(@_[1..$#_])/grep/$_[0]/,@_}

Cobalah online!

Xcali
sumber
2

Perl 6 , 33 30 karakter ( 34 31 byte)

WhateverBlok lurus ke depan . combmemecah string menjadi huruf, permutationsmendapatkan semua kemungkinan kombinasi. Karena cara pemaksaan yang Setperlu joindiedit terlebih dahulu ( »berlaku joinuntuk setiap elemen dalam daftar).

+*.comb.permutations».join.Set

Cobalah online!

(jawaban sebelumnya digunakan .uniquetetapi Setmenjamin keunikan, dan menghitung sama, sehingga menghemat 3).

pengguna0721090601
sumber
2

K (oK) , 12 byte

Larutan:

#?x@prm@!#x:

Cobalah online!

Penjelasan:

Menggunakan oK built-in prm:

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

... yang, karena pada x^/:xdasarnya menghasilkan permutasi dari "helo"tidak "hello", maka kita perlu menghasilkan permutasi 0 1 2 3 4, menggunakannya untuk mengindeks ke dalam "hello"dan kemudian mengambil hitungan unik.

#?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
sumber
Apakah operator khusus ok? Saya tidak berpikir vanilla k memilikinya?
Henry Henrinson
Yup - hanya ada di oK per manual
streetster
@HenryHenrinson afaik itu tidak ada di k4. di awal k5 itu !-n. pada akhir k5 dan k6 menjadiprm . k7 (shakti) prmjuga demikian.
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;}

Port dari jawaban Python 2 dari @ArBo .
-1 byte terima kasih kepada @ OlivierGrégoire dengan membuatnya berulang bukan rekursif.

Cobalah online.

Sebenarnya menghasilkan semua permutasi unik dalam Set dan mendapatkan ukurannya akan menjadi 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);}

Cobalah online.

Kevin Cruijssen
sumber
Oke, aku bisa golf byte dengan membuatnya berulang bukannya rekursif: 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 Terima kasih! Btw, apakah Anda melihat sesuatu untuk membuat pendekatan kedua (menghasilkan semua permutasi unik dalam satu set) lebih pendek? Saya merasa beberapa byte dapat disimpan, tetapi mencoba beberapa hal dan sebagian besar sedikit lebih lama daripada yang lebih pendek .. Tapi tbh masih terlihat terlalu panjang.
Kevin Cruijssen
Saya telah mengusahakannya, mencoba menggunakan aliran dan menghitung, seperti ini: 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;}tetapi sejauh ini tidak berhasil ...
Olivier Grégoire
1

MATL , 9 byte

jY@XuZy1)

Cobalah online!

Penjelasan:

j input as string
Y@ get permutations
Xu unique members
Zy size matrix
1) first member of size matrix
OrangeCherries
sumber
2
Anda dapat mengambil input dengan tanda kutip, sehingga jmenjadi i, yang dapat dibiarkan implisit. Juga, &nxsimpan byte lebih dari Zy1) tio.run/##y00syfn/P9IholQtr@L/f/WM1JycfHUA
Luis Mendo
1

Oktaf / MATLAB, 35 byte

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

Fungsi anonim yang mengambil vektor karakter dan menghasilkan angka.

Dalam MATLAB ini dapat disingkat menjadi size(unique(perms(s),'ro'),1)(33 byte).

Cobalah online!

Penjelasan

@(s)                                  % Anonymous function with input s
                perms(s)              % Permutations. Gives a char matrix
         unique(        ,'rows')      % Deduplicate rows
    size(                       ,1)   % Number of rows
Luis Mendo
sumber
1
Saya pikir sudah uniquekembali baris unik? Atau hanya untuk tables?
Giuseppe
@Giuseppe Untuk array 2D numerik / char uniqueakan linierisasi dulu. Untuk tabel saya pikir Anda benar; Saya tidak tahu itu!
Luis Mendo
1
Ah, saya tahu dari mana saya mendapatkan ide - uniquedi MATLAB mengambil baris untuk tables; R's uniquemengambil deretan matriks atau bingkai data yang unik. Terlalu banyak bahasa array dengan perintah yang sama yang melakukan hal-hal yang sedikit berbeda ...
Giuseppe
1

Retina 0.8.2 , 73 byte

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

Cobalah online! Menggunakan rumus @ ArBo, tetapi mengevaluasi dari kanan ke kiri karena hal ini dapat dilakukan dalam aritmatika bilangan bulat sambil tetap meminimalkan ukuran nilai unary yang terlibat. Penjelasan:

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

Untuk setiap karakter, hitung berapa banyak sisa duplikat yang ada dan berapa banyak karakter selanjutnya, tambahkan satu untuk masing-masing untuk memperhitungkan karakter saat ini, dan pisahkan nilainya sehingga kita tahu mana yang harus dibagi dan mana yang akan dikalikan .

^
1

Awali 1 untuk menghasilkan ekspresi lengkap.

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

Lipat gandakan angka terakhir terakhir dan ketiga sambil membaginya dengan angka terakhir kedua. Ini menggantikan tiga angka terakhir.

1

Konversikan ke desimal.

Neil
sumber
1

K, 27 byte

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

K, 16 byte - bukan jawaban yang nyata

#?(999999#0N)?\:

Ambil 999999 permutasi acak dari string input, ambil set unik dan hitung panjangnya. Sebagian besar waktu itu akan memberikan jawaban yang benar, untuk string pendek.

Peningkatan berkat @Sriotchilism O'Zaic, @Selcuk

Henry Henrinson
sumber
2
Selamat datang di situs ini! Tidak masalah karena tidak valid tetapi bisakah Anda membuat jawaban yang tidak valid lebih akurat dengan menggunakan 999999alih-alih 100000?
Ad Hoc Garf Hunter
Yup, ide bagus, terima kasih.
Henry Henrinson
1
Dan mungkin mengedit penjelasan untuk mencerminkan perubahan itu juga?
Selcuk
1

Bahasa Wolfram (Mathematica) , 32 byte

Characters/*Permutations/*Length

Cobalah online!

Penjelasan: Komposisi kanan dengan /*menerapkan tiga operator ini satu demi satu ke argumen fungsi, dari kiri ke kanan:

  • Characters mengubah string input ke daftar karakter.

  • Permutations membuat daftar semua permutasi unik dari daftar karakter ini.

  • Length mengembalikan panjang daftar permutasi unik ini.

Metode ini sangat boros untuk string panjang: permutasi unik sebenarnya terdaftar dan dihitung, alih-alih menggunakan a Multinomialuntuk menghitung nomor mereka tanpa daftar.

Roma
sumber
1

F # (Mono) , 105 byte

let rec f s=if s=""then 1 else s.Length*(f(s.Substring 1))/(s|>Seq.sumBy(fun c->if c=s.[0]then 1 else 0))

Cobalah online!

Henrik Hansen
sumber
1

Pyth , 5 4 byte

l{.p

Cobalah online!

Ini menganggap input adalah string python literal. Jika input harus berupa teks mentah, versi 5-byte ini akan berfungsi:

l{.pz

Either way, itu hanya menghitung semua permutasi input sebagai daftar, mendupuplikasinya dan mendapatkan jumlah elemen di dalamnya, dan secara implisit mencetak angka itu.

-1 byte terima kasih kepada @ hakr14

randomdude999
sumber
{deduplicates daftar untuk satu byte kurang dari .{.
hakr14
1

J , 14  13 byte

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

Cobalah online!

1 byte berkat mil

#                  length
         #/.~      counts of each unique character
 (%*/)             divide left by the product of right
      &:!          after applying ! to both
FrownyFrog
sumber
1
#(%*/)&:!#/.~harus menyimpan byte lain
mil
1

PHP , 77 byte

function f($s){return!$s?:strlen($s)*f(substr($s,1))/substr_count($s,$s[0]);}

Cobalah online!

Ini pada dasarnya hanya sebuah port PHP dari jawaban Python @ ArBo yang menang yang jauh lebih pintar daripada jawaban rekursif yang awalnya saya miliki. Bravo!

640KB
sumber
0

Ohm v2 , 4 byte

ψD∩l

Cobalah online!

Penjelasan

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