팩토리얼 팩토링


16

오늘 통계 수업에서, 곱하면 몇 가지 계승을 단순화 할 수 있다는 것을 알았습니다! 예를 들면 다음과 같습니다.5! * 3! = 5! *3*2 = 5! *6 = 6!

작업:

아라비아 숫자와 느낌표 만 포함 된 문자열이 주어지면 언어, 코드 골프 스타일에 대한 최소 바이트 수로 가능한 가장 짧은 문자열로 내 계승을 단순화하십시오.

입력

아라비아 숫자와 느낌표 만 포함 된 문자열입니다. 입력의 계승은 200보다 크지 않습니다!. 계승은 숫자 당 여러 계승을 갖지 않습니다. 입력은 정수 목록으로 취할 수 있습니다.

산출

입력에서 동등한 값을 갖는 단축 된 문자열입니다. 주문은 중요하지 않습니다. 계승 표기법은 필수이지만 숫자 당 둘 이상의 계승 기호를 사용할 필요는 없습니다.

테스트 사례

In: 3!2!2!  
Out: 4! 

In 2!3!2!0! 
Out: 4! 

In: 7!2!2!7!2!2!2!2! 
Out: 8!8! 

In: 23!3!2!2! 
Out: 24!  
Also: 4!!

In: 23!3!2!2!2! 
Out: 24!2!

In: 127!2!2!2!2!2!2!2! 
Out: 128!

In: 32!56!29!128!  
Out: 29!32!56!128!

행운을 빌어 요


빈 제품이 1이기 때문에 1!1!빈 문자열 이라고 하면됩니까?
Jonathan Allan

@JonathanAllan 1! 1! 1로 줄어 듭니다! 아니면 0!
tuskiomi

빈 문자열로 줄어 듭니다 : /
Jonathan Allan

답변:


5

젤리 ,  17  18 바이트

!P
ÇṗLÇ⁼¥ÐfÇḢḟ1ȯ0F

숫자 목록을 가져 와서 반환하는 모나드 링크 (숫자 당 하나의 계승 옵션에 고정)

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

어떻게?

Pietu1998 솔루션의 골프 (독립적으로 작성되었지만) 버전.

!P - Link 1, product of factorials: list
!  - factorial (vectorises)
 P - product

ÇṗLÇ⁼¥ÐfÇḢḟ1ȯ0F - Main link: list                       e.g. [3,2,2]
Ç               - call the last link (1) as a monad           24
  L             - length                                      3
 ṗ              - Cartesian power      [[1,1,1],[1,1,2],...,[1,1,24],...,[24,24,24]]
        Ç       - call the last link (1) as a monad           24
      Ðf        - filter keep if:
     ¥          -   last two links as a dyad:
   Ç            -     call the last link (1) as a monad     [1,2,...,24!,...,24!^3]
    ⁼           -     equal?
         Ḣ      - head
          ḟ1    - filter out any ones
            ȯ0  - or with zero (for the empty list case)
              F - flatten (to cater for the fact that zero is not yet a list)

1
나에게 충분히 분명한 것 같습니다-우리는 그것을 사용할 필요는 없지만 원한다면 그렇게 할 수 있습니다.
Jonathan Allan

1
@tuskiomi 바닥 글은 명확성을 위해 목록 출력의 형식을 지정하는 것입니다 ... 함수가 아닌 전체 프로그램으로 코드는 Jelly의 목록 형식을 인쇄합니다 (길이가 1이 아닌 목록에 대해서는 비어 있지 않으며 묶지 않음). .
Jonathan Allan

1
@tuskiomi TIO에는 한계가 있지만 ;-) 이론적으로 작동한다고 생각합니다.
Outgolfer Erik

1
카테 시안의 힘 @tuskiomi는 23! ^ 4리스트의리스트가 될 것이다. 메모리가 아닌 경우 시간이 부족합니다 (TIO에서 60 초 제한).
Jonathan Allan

1
N! ^ M 여기서 N은 곱이고 M은 항의 수입니다 (공간에도 !!)
Jonathan Allan

3

젤리 , 19 바이트

,!P€E
SṗLçÐfµḢḟ1ȯ1F

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

빠르고 더러운. 23!2!3!2!테스트 케이스 조차도 매우 느립니다 . 정수 목록으로서의 I / O.

설명

,!P€E    Helper link. Arguments: attempt, original
,        Make the array [attempt, original].
         Example: [[1,1,1,4], [2,3,2,0]]
 !       Take the factorial of each item.
         Example: [[1,1,1,24], [2,6,2,1]]
  P€     Take the product of each sublist.
         Example: [24, 24]
    E    Check if the values are equal.

SṗLçÐfµḢḟ1ȯ1F   Main link. Arguments: original
S               Find the sum S of the integers in the input.
  L             Find the number N of integers in the input.
 ṗ              Generate all lists containing N integers from 1 to S.
   çÐf          Take the lists whose factorial-product is the same as the original.
       Ḣ        Take the first match. This is the one with the most ones.
        ḟ1      Remove any ones.
          ȯ1    If there were only ones, return a one instead.
            F   Turn into a list if needed.

리스트를 I / O로 사용할 수 있습니다
Jonathan Allan

@JonathanAllan 오, 그것은 분명히 OP로 편집되지 않았습니다
PurkkaKoodari

내 17이 더 느리게 보인다 ...
Jonathan Allan


@JonathanAllan 알고리즘이 본질적으로 동일하더라도 게시하고 게시글이 다르게 보입니다.
PurkkaKoodari

2

클린 , 397 ... 317 바이트

import StdEnv,StdLib
c=length
f c m=sortBy c o flatten o map m
%n=f(>)@[2..n]
@1=[]
@n#f=[i\\i<-[2..n]|n/i*i==n&&and[i/j*j<i\\j<-[2..i-1]]]
=f++ @(n/prod f)
?l=group(f(>)%l)
$l=hd(f(\a b=c a<c b)(~(?l))[0..sum l])
~[]_=[[]]
~i n=[[m:k]\\m<-take n[hd(i!!0++[0])..],k<- ~[drop(c a)b\\a<-group(%m)&b<-i|b>a]n|i== ?[m:k]]

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

이는의 단계를 취하고 [Int]결과의 주요 요소를 결정하며 다음 단계의 항에 대한 기준값으로 모든 단계에서 가장 큰 요소를 사용하여 가장 작은 표현을 찾기 위해 요소를 감소시킵니다. TIO에서 일부 테스트 사례를 완료하지는 않지만 상당히 빠르며 중급 랩톱에서 3 분 안에 모두 실행할 수 있습니다.

* O((prod(N)!)^sum(N))복잡성 알고리즘


테스트 사례 : 6, 2, 2
tsh

@tsh 수정되었습니다. 가장 작은 길이를 기준으로 정렬하는 것이 아니라 잘못된 가정에 따라 가장 큰 첫 번째 멤버를 기준으로 정렬했습니다.
OUurous

1

> <> , 66 바이트

1}:?\~l1=?v{!
-:?!\:{*}1
v?( 4:{/}1<o"!"n-1
{:,} :{/?%}:+1
\:1-?n;

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

비효율적이며 가장 작은 문자열을 찾지 못하며 인터프리터는 매우 큰 숫자를 잘 처리하지 못합니다. 그러나 적어도 나는 시도했다? 를 통해 숫자 목록으로 입력을받습니다.-v플래그를 받습니다.

먼저 각 숫자를 계승 화하고 곱하여 입력 값을 계산합니다. 그런 다음 총계로 깨끗하게 나누고 출력하는 가장 큰 계승을 찾습니다. 소수 (출력) 또는 1을 얻고 프로그램을 종료 할 때까지 반복하십시오. 이 때문에 때로는 숫자의 최단 표현을 찾지 못할 수도 있습니다. 예를 들어, 총계를 10으로 나눌 수 있기 때문에 테스트 사례 7!2!2!7!2!2!2!2!10!224대신 반환 됩니다 8!8!! 먼저.


1

루비 , 240 (237) 233 바이트

이것은 엄청나게 비효율적입니다

정수 배열을 입력으로 받아들입니다.

문자열을 반환하고 say '720!', '6!!'and 사이에서 가장 짧은 옵션을 선택합니다.'3!!!'

->i{f=->n{n>0?n*f[n-1]:1}
s=->a{eval a.map{|i|f[i]}*?*}
r=->e,a=[2]{e==s[a]?a:s[a]<=e&&(r[e,a[0..-2]+[a[-1]+1]]||r[e,a+[2]])}
j=->v{v.join(?!)+?!}
u=r[s[i]]
while j[g=u.map{|i|i&&r[i]?[r[i],p]:i}.flatten].size<j[u].size;u=g;end
j[u]}

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

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