Đếm tất cả các kết hợp duy nhất có thể có của các chữ cái trong một từ


11

Bạn được cung cấp một chuỗi, sẽ chứa các ký tự az thông thường. (Bạn có thể cho rằng đây sẽ luôn là trường hợp trong bất kỳ bài kiểm tra nào và giả sử rằng tất cả các chữ cái cũng sẽ là chữ thường). Bạn phải xác định có bao nhiêu kết hợp duy nhất có thể được tạo từ các ký tự riêng lẻ trong chuỗi và in số đó.

Tuy nhiên, các chữ cái trùng lặp có thể được bỏ qua trong việc đếm các kết hợp có thể. Nói cách khác, nếu chuỗi được cung cấp là "xin chào", thì chỉ cần chuyển đổi vị trí của hai ls không được tính là một cụm từ duy nhất và do đó không thể được tính vào tổng số.

Số lượng byte ngắn nhất chiến thắng, mong muốn được thấy một số giải pháp sáng tạo trong các ngôn ngữ không chơi gôn!

Ví dụ:

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


4
@Giuseppe Tôi không nghĩ đây là bản sao của điều đó; các chi tiết cụ thể của câu hỏi này cho phép triển khai ngắn hơn nhiều
ArBo

4
Thêm một số testcase có thể giúp đỡ.
tsh

1
@Jonathan ALLan Đề nghị tốt! Tiêu đề thay đổi cho phù hợp.
I_P_Edwards

Câu trả lời:


29

Python 2 , 50 48 byte

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

Hãy thử trực tuyến!

Không có tích hợp nhàm chán! Thật ngạc nhiên, điều này thậm chí còn ngắn hơn so với phương pháp vũ phu, tính toán tất cả các hoán vị với itertoolsvà lấy chiều dài.

Hàm này sử dụng công thức

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

và tính toán nó một cách nhanh chóng. Giai thừa trong tử số được tính bằng cách nhân với len(s)trong mỗi lệnh gọi hàm. Mẫu số là một chút tinh tế hơn; trong mỗi cuộc gọi, chúng tôi chia cho số lần xuất hiện của phần tử đó trong phần còn lại của chuỗi, đảm bảo rằng với mỗi ký tự c, tất cả các số từ 1 đến số lần xuất hiện của c(bao gồm) sẽ được chia chính xác một lần. Vì chúng tôi chỉ phân chia ở cuối, chúng tôi đảm bảo không có bất kỳ vấn đề nào với phân chia tầng mặc định của Python 2.


itertools rất dài dòng trong các tên chức năng của nó
qwr



5

R , 69 65 byte

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

Hãy thử trực tuyến!

4 byte được lưu nhờ Zahiro Mor trong cả hai câu trả lời.

Tính hệ số đa thức trực tiếp.

R , 72 68 byte

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

Hãy thử trực tuyến!

Sử dụng hàm phân phối đa cực được cung cấp bởi dmultinomđể trích xuất hệ số đa cực.

Lưu ý rằng thông thường (golfier) x<-table(strsplit(s,""))không hoạt động trong dmultinomcuộc gọi mà không rõ lý do.


2
function(s,! =factorial)(!nchar(s))/prod(!table(strsplit(s,""))) sẽ làm việc. el () là reduntant - bảng biết để tìm kiếm các yếu tố ....
Zahiro Mor

1
@ZahiroMor ah, tất nhiên rồi. Tôi đã có ý định kiểm tra điều đó nhưng không bao giờ có được nó.
Giuseppe

5

JavaScript (Node.js) , 49 byte

t=t*được sử dụng thay vì t*=để tránh lỗi làm tròn số (làm tròn số |txuống) vì t=t*đảm bảo rằng tất cả các kết quả trung gian (toán tử) là toàn bộ số.

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

Hãy thử trực tuyến!

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
(Lỗi làm tròn điểm nổi tiềm năng; sử dụng t=t*nếu bạn muốn tránh điều đó.)
Neil

@Neil Vâng, nó đã thất bại khi đầu vào aaadegfbbbcccchính xác là do lỗi làm tròn điểm nổi
Shieru Asakoto

Huh, làm thế nào bạn tìm thấy trường hợp thử nghiệm?
Neil

@Neil Tiếp tục thêm các ký tự vào chuỗi cho đến khi xảy ra lỗi làm tròn như vậy lol
Shieru Asakoto

@ShieruAsakoto Tiêu đề đã được thay đổi; đếm là tốt hơn nhiều. Cảm ơn, và câu trả lời tốt đẹp!
I_P_Edwards








2

APL (Dyalog Unicode) , 24 byte

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

Hãy thử trực tuyến!

Dfn đơn giản, lấy một chuỗi làm đối số.

Làm sao:

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 ký tự ( 34 31 byte)

Khá thẳng Whateverkhối phía trước . combchia chuỗi thành các chữ cái, permutationsđược tất cả các kết hợp có thể. Do cách ép buộc Setcần phải được chỉnh sửa jointrước ( »áp dụng joincho từng yếu tố trong danh sách).

+*.comb.permutations».join.Set

Hãy thử trực tuyến!

(câu trả lời trước được sử dụng .uniquenhưng Sets đảm bảo tính duy nhất và đánh số giống nhau, vì vậy nó tiết kiệm được 3).


2

K (oK) , 12 byte

Giải pháp:

#?x@prm@!#x:

Hãy thử trực tuyến!

Giải trình:

Sử dụng oK tích hợp prm:

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

... mà x^/:xvề cơ bản là tạo ra các hoán vị của "helo"không "hello", do đó chúng ta cần tạo ra các hoán vị của 0 1 2 3 4, sử dụng chúng để lập chỉ mục "hello"và sau đó lấy số đếm duy nhất.

#?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 (#)

Là prm một toán tử cụ thể ok? Tôi không nghĩ vanilla k có nó?
Henry Henrinson

Yup - chỉ tồn tại trong oK theo hướng dẫn
streetster

@HenryHenrinson afaik nó không ở k4. đầu k5 nó đã !-n. vào cuối k5 và k6 nó đã trở thànhprm . k7 (shakti) cũng prmvậy.
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;}

Cổng câu trả lời Python 2 của @ArBo .
-1 byte nhờ @ OlivierGrégoire bằng cách lặp lại thay vì đệ quy.

Hãy thử trực tuyến.

Trên thực tế, việc tạo ra tất cả các hoán vị duy nhất trong Tập hợp và nhận kích thước của nó sẽ là 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);}

Hãy thử trực tuyến.


Được rồi, tôi có thể đánh gôn một byte bằng cách lặp lại thay vì đệ quy : 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 Cảm ơn! Btw, bạn có thấy điều gì đó làm cho cách tiếp cận thứ hai (tạo ra tất cả các hoán vị duy nhất trong một tập hợp) ngắn hơn không? Tôi có cảm giác một số byte có thể được lưu, nhưng đã thử một số thứ và hầu hết đều dài hơn một chút thay vì ngắn hơn .. Nhưng nó vẫn trông quá dài tbh.
Kevin Cruijssen

Tôi đã làm việc với nó, cố gắng sử dụng các luồng và đếm, như thế này: 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;}nhưng không thành công cho đến nay ...
Olivier Grégoire


1

Octave / MATLAB, 35 byte

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

Hàm ẩn danh lấy một vectơ ký tự và tạo ra một số.

Trong MATLAB, điều này có thể được rút ngắn thành size(unique(perms(s),'ro'),1)(33 byte).

Hãy thử trực tuyến!

Giải trình

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

1
Tôi nghĩ đã uniquetrả lại hàng duy nhất chưa? Hay đó chỉ là cho tables?
Giuseppe

@Giuseppe Đối với mảng 2D số / char uniquesẽ tuyến tính hóa đầu tiên. Đối với bảng tôi nghĩ bạn đúng; Tôi không biết điều đó!
Luis Mendo

1
À, tôi biết tôi đã có ý tưởng uniqueở đâu - trong MATLAB có hàng cho tables; R's uniquecó các hàng ma trận hoặc khung dữ liệu duy nhất. Quá nhiều ngôn ngữ mảng với cùng một lệnh làm những việc hơi khác nhau ...
Giuseppe

1

Võng mạc 0.8.2 , 73 byte

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

Hãy thử trực tuyến! Sử dụng công thức @ ArBo, nhưng đánh giá từ phải sang trái vì điều này có thể được thực hiện bằng số học số nguyên trong khi vẫn giảm thiểu kích thước của các giá trị đơn nguyên liên quan. Giải trình:

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

Đối với mỗi ký tự, hãy đếm xem có bao nhiêu trùng lặp còn lại và có bao nhiêu ký tự nữa, thêm một ký tự để đưa ký tự hiện tại vào tài khoản và phân tách các giá trị để chúng tôi biết những giá trị nào sẽ được chia và nhân nào sẽ được nhân .

^
1

Tiền tố 1 để tạo ra một biểu thức hoàn chỉnh.

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

Liên tục nhân số cuối cùng và số thứ ba trong khi chia cho số cuối thứ hai. Điều này thay thế ba số cuối.

1

Chuyển đổi thành số thập phân.


1

K, 27 byte

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

K, 16 byte - không phải là câu trả lời thực sự

#?(999999#0N)?\:

Lấy 999999 hoán vị ngẫu nhiên của chuỗi đầu vào, lấy tập hợp duy nhất của chúng và đếm chiều dài. Hầu hết thời gian nó sẽ đưa ra câu trả lời đúng, cho các chuỗi ngắn.

Được cải thiện nhờ @Sriotchilism O'Z cổ, @Selcuk


2
Chào mừng đến với trang web! Không thực sự quan trọng vì nó không hợp lệ nhưng bạn có thể làm cho câu trả lời không hợp lệ của mình chính xác hơn bằng cách sử dụng 999999thay vì 100000không?
Đăng Rock Garf Hunter

Yup, ý kiến ​​hay, cảm ơn.
Henry Henrinson

1
Và có thể chỉnh sửa lời giải thích để phản ánh sự thay đổi đó quá?
Selcuk

1

Ngôn ngữ Wolfram (Mathicala) , 32 byte

Characters/*Permutations/*Length

Hãy thử trực tuyến!

Giải thích: Bố /*cục bên phải với việc áp dụng ba toán tử lần lượt cho toán tử hàm này, từ trái sang phải:

  • Characters chuyển đổi chuỗi đầu vào thành một danh sách các ký tự.

  • Permutations tạo một danh sách tất cả các hoán vị duy nhất của danh sách nhân vật này.

  • Length trả về độ dài của danh sách các hoán vị duy nhất này.

Phương pháp này rất lãng phí cho các chuỗi dài: các hoán vị duy nhất thực sự được liệt kê và tính, thay vì sử dụng a Multinomialđể tính số của chúng mà không liệt kê.



1

Bình thường , 5 4 byte

l{.p

Hãy thử trực tuyến!

Giả định đầu vào là một chuỗi python bằng chữ. Nếu đầu vào phải là văn bản thô, phiên bản 5 byte này sẽ hoạt động:

l{.pz

Dù bằng cách nào, nó chỉ tính toán tất cả các hoán vị của đầu vào dưới dạng một danh sách, sao chép nó và lấy số phần tử trong đó, và in ngầm số đó.

-1 byte nhờ @ hakr14


{sao chép một danh sách cho một byte nhỏ hơn .{.
hakr14

1

J , 14  13 byte

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

Hãy thử trực tuyến!

1 byte nhờ dặm

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

1
#(%*/)&:!#/.~nên tiết kiệm một byte
dặm



Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.