단어에서 문자의 가능한 모든 고유 조합 계산


12

일반적인 az 문자를 포함하는 문자열이 제공됩니다. (이것은 모든 테스트에서 항상 그렇다고 가정 할 수 있으며 모든 문자도 소문자라고 가정 할 수 있습니다). 문자열의 개별 문자로 몇 개의 고유 조합을 만들 수 있는지 결정하고 해당 번호를 인쇄해야합니다.

그러나 가능한 조합을 계산할 때 중복 문자를 무시할 수 있습니다. 다시 말해, 주어진 문자열이 "hello"인 경우 단순히 두 ls 의 위치를 ​​전환하는 것은 고유 한 구로 간주되지 않으므로 총계로 계산할 수 없습니다.

가장 짧은 바이트 수로 승리하며 골프가 아닌 언어로 창의적인 솔루션을 기대합니다!

예 :

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


4
@ 주세페 나는 이것이 그 속임수라고 생각하지 않는다. 이 질문의 구체적 내용은 훨씬 짧은 구현을 가능하게합니다
ArBo

4
테스트 케이스를 추가하면 도움이 될 수 있습니다.
tsh

1
@JonathanAllan 좋은 제안! 그에 따라 제목이 변경되었습니다.
SimpleGeek

답변:


29

파이썬 2 , 50 48 바이트

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

온라인으로 사용해보십시오!

지루한 내장 기능이 없습니다! 놀랍게도, 이것은 무차별 대입법보다 짧으며 itertools, 길이 에 대한 모든 순열을 계산하고 계산합니다 .

이 함수는 공식을 사용합니다

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

즉시 계산합니다. 분자의 계승은 len(s)각 함수 호출 에 곱하여 계산됩니다 . 분모는 조금 더 미묘합니다. 각 호출에서 우리는 문자열의 왼쪽에있는 요소의 발생 횟수로 나눠서 모든 문자 c에 대해 1과 발생 횟수 c(포함) 사이의 모든 숫자 가 정확히 한 번으로 나뉘어 지도록합니다. 우리는 맨 끝에서만 나누기 때문에 Python 2의 기본 바닥 나누기에 아무런 문제가 없음을 보장합니다.


itertools의 기능 명은 매우 장황하다
qwr



5

R , 69 65 바이트

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

온라인으로 사용해보십시오!

두 답변 모두 Zahiro Mor 덕분에 4 바이트가 절약되었습니다 .

다항식 계수를 직접 계산합니다.

R , 72 68 바이트

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

온라인으로 사용해보십시오!

dmultinom다항식 계수를 추출하기 위해 제공된 다항식 분포 함수를 사용합니다 .

알 수없는 이유로 일반적인 통화 (golfier) x<-table(strsplit(s,""))dmultinom통화 내에서 작동하지 않습니다 .


2
function(s,! =factorial)(!nchar(s))/prod(!table(strsplit(s,""))) 작동합니다. 엘은 () reduntant입니다 - 테이블 요소를 찾기 위해 알고 ...
Zahiro 모르

1
물론 @ZahiroMor 아. 나는 그것을 테스트하려고했지만 결코 그 주위를 돌아 보지 않았습니다.
주세페

5

자바 스크립트 (Node.js) , 49 바이트

t=t*모든 중간 (연산자 별) 결과가 정수임 을 보장 t*=하기 위해 반올림 오류 ( |t숫자를 반올림)를 피하기 위해 대신 사용됩니다 t=t*.

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

온라인으로 사용해보십시오!

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
(잠재적 부동 소수점 반올림 오류; t=t*이를 피하려면 사용 하십시오.)
Neil

@Neil 그래 입력이 aaadegfbbbccc부동 소수점 반올림 오류로 인해 정확히 실패했을 경우
Shieru Asakoto

허, 그 테스트 케이스는 어떻게 찾았 어?
Neil


@ShieruAsakoto 제목이 변경되었습니다. 카운트가 훨씬 좋습니다. 고마워, 좋은 대답!
SimpleGeek








2

APL (Dyalog Unicode) , 24 바이트

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

온라인으로 사용해보십시오!

단순 Dfn은 문자열을 인수로 사용합니다.

어떻게:

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 자 ( 34 31 바이트)

상당히 직진 Whatever블록. comb문자열을 문자로 나누고 permutations가능한 모든 조합을 가져 옵니다 . 이 때문에 행 방향 강요 Set할 필요가 join제 에드 ( »적용 join목록의 각 요소).

+*.comb.permutations».join.Set

온라인으로 사용해보십시오!

(이전 답변이 사용 .unique되었지만 Set고유성을 보장하고 동일하게 수치화하여 3을 절약합니다).


2

K (oK) , 12 바이트

해결책:

#?x@prm@!#x:

온라인으로 사용해보십시오!

설명:

oK 내장 기능을 사용합니다 prm.

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

... x^/:x기본적으로 "helo"not 의 순열을 생성하기 "hello"때문에의 순열을 생성해야합니다. 따라서 순열 0 1 2 3 4을 인덱싱 "hello"하고 고유 한 수를 계산하는 데 사용해야합니다 .

#?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은 특정 운영자입니까? 나는 바닐라 케이가 있다고 생각하지 않습니까?
Henry Henrinson


@HenryHenrinson afaik 그것은 k4에 없습니다. k5 초에 그것은이었다 !-n. 늦게 k5와 k6에서 그것은되었다prm . k7 (shakti)도 prm있습니다.
ngn

2

자바 8, 103102 바이트

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

@ArBo 의 Python 2 답변 포트 . @ OlivierGrégoire
덕분 에 재귀 대신 반복적으로 -1 바이트 .

온라인으로 사용해보십시오.

실제로 Set에서 모든 고유 순열을 생성하고 크기를 얻는 것은 221 바이트입니다 .

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

온라인으로 사용해보십시오.


좋아, 나는 재귀 대신 반복적으로 바이트를 만들 수 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 12

@ OlivierGrégoire 감사합니다! Btw, 두 번째 접근 방식 (모든 고유 순열을 집합으로 생성)을 짧게 만드는 것이 있습니까? 나는 약간의 바이트를 절약 할 수 있다고 생각하지만 어떤 것을 시도해 보았고 대부분 짧게가 아니라 약간 더 길었습니다. 그러나 여전히 너무 길게 보입니다.
Kevin Cruijssen 12

나는 스트림을 사용하고 다음과 같이 계산하려고 노력하고 있습니다. 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;}그러나 지금까지 성공하지 못했습니다 ...
Olivier Grégoire


1

옥타브 / MATLAB, 35 바이트

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

문자형 벡터를 취해 숫자를 생성하는 익명 함수.

MATLAB에서는이를 size(unique(perms(s),'ro'),1)(33 바이트) 로 줄일 수 있습니다 .

온라인으로 사용해보십시오!

설명

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

1
나는 unique이미 고유 한 행을 반환 한다고 생각 했습니까? 아니면 tables 에만 해당 됩니까?
주세페

@Giuseppe 숫자 / 문자 2D 배열의 경우 unique먼저 선형화됩니다. 나는 당신이 옳다고 생각합니다. 나는 그것을 몰랐다!
Luis Mendo 2016 년

1
내가 아이디어를 어디서 얻었 아, 나는 알고있다 - uniqueMATLAB에 대한 행을 걸립니까을 tables; R unique은 행렬 또는 데이터 프레임의 고유 한 행을 사용합니다. 약간 다른 동작을하는 동일한 명령을 가진 너무 많은 배열 언어 ...
Giuseppe

1

레티 나 0.8.2 , 73 바이트

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

온라인으로 사용해보십시오! @ArBo의 공식을 사용하지만 관련된 단항 값의 크기를 최소화하면서 정수 산술로 수행 할 수 있으므로 오른쪽에서 왼쪽으로 평가됩니다. 설명:

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

각 문자에 대해 남아있는 복제본 수와 추가 문자 수를 세고, 현재 문자를 고려하기 위해 각 문자를 추가하고, 값을 분리하여 어떤 문자를 나누고 곱해야하는지 알 수 있습니다. .

^
1

완전한 표현식을 작성하려면 접 두부 1을 사용하십시오.

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

마지막 두 번째 숫자로 나누면서 마지막 숫자와 세 번째 마지막 숫자를 반복해서 곱하십시오. 이것은 마지막 세 숫자를 대체합니다.

1

십진수로 변환합니다.


1

K, 27 바이트

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

K, 16 바이트-실제 답변이 아님

#?(999999#0N)?\:

입력 문자열의 999999 임의 순열을 취하고 고유 한 세트를 가져와 길이를 계산하십시오. 대부분의 경우 짧은 문자열에 대해 올바른 답변을 제공합니다.

@Sriotchilism O'Zaic, @Selcuk 덕분에 개선되었습니다.


2
사이트에 오신 것을 환영합니다! 유효하지 않으므로 실제로 중요하지 않지만 999999대신을 사용하여 잘못된 답변을보다 정확하게 만들 수 100000있습니까?
Ad Hoc Garf Hunter

그래, 좋은 생각이야, 고마워
Henry Henrinson 2018 년

1
그리고 그 변화를 반영하기 위해 설명을 편집 할 수 있습니까?
Selcuk

1

Wolfram Language (Mathematica) , 32 바이트

Characters/*Permutations/*Length

온라인으로 사용해보십시오!

설명 : with right-composition /*은 왼쪽에서 오른쪽으로이 세 연산자를 차례로 함수 인수에 적용합니다.

  • Characters 입력 문자열을 문자 목록으로 변환합니다.

  • Permutations 이 문자 목록의 모든 순열을 나열합니다.

  • Length 이 고유 순열 목록의 길이를 반환합니다.

이 방법은 긴 문자열에 대해 매우 낭비입니다 Multinomial. 목록없이 숫자를 계산하기 위해 a 를 사용하는 대신 고유 순열이 실제로 나열되고 계산됩니다 .



1

Pyth , 5 4 바이트

l{.p

온라인으로 사용해보십시오!

이것은 입력이 파이썬 문자열 리터럴이라고 가정합니다. 입력이 원시 텍스트 여야하는 경우이 5 바이트 버전은 작동합니다.

l{.pz

어느 쪽이든, 그것은 입력의 모든 순열을 목록으로 계산하고, 중복 제거하고 그 안의 요소 수를 얻고 암시 적으로 그 숫자를 인쇄합니다.

@ hakr14 덕분에 -1 바이트


{보다 작은 바이트에 대한 목록을 중복 제거합니다 .{.
hakr14 '




당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.