階乗の因数分解


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!は空の文字列だけですか?
ジョナサンアラン

@JonathanAllan 1!1!1に減少します!または0!
-tuskiomi

その後、空の文字列になります:/
ジョナサンアラン

@JonathanAllan私は1が空の文字列と同じでないと言うつもりです
tuskiomi

回答:


5

ゼリー 17  18 バイト

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

数値のリストを取得して返すモナドリンク(数値ごとに1つの階乗のオプションに固執)

オンラインでお試しください!

どうやって?

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
私には十分にはっきりしているようです-私たちはそれを使用する必要はありませんが、必要であればそうすることができます。
ジョナサンアラン

1
@tuskiomiフッターは明確にするためにリスト出力をフォーマットしています...完全なプログラムとして(関数としてではなく)コードはリストのJellyのフォーマットを出力します(長さ1のリストには空となしの[]なし) 。
ジョナサンアラン

1
@tuskiomi TIOには制限があります;-)しかし、理論的には機能すると思います。
エリック・ザ・アウトゴルファー

1
@tuskiomiデカルトの力は23!^ 4リストのリストになります。メモリでない場合、時間切れになります(TIOで60秒の制限)。
ジョナサンアラン

1
N!^ Mここで、Nは積で、Mは用語の数です(そしてスペースも!!)
ジョナサンアラン

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としてリストを使用することがあります
ジョナサンアラン

どうやらOPに編集されていなかった@JonathanAllanああ、
PurkkaKoodari

私の17は...さらに遅いようだ
ジョナサン・アラン

ああ、それはあまりにも似ています- tio.run/##y0rNyan8/...
ジョナサン・アラン

@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が修正されました。これは、最小の長さではなく、誤った仮定に基づいた最大の最初のメンバーによるソートでした。
Οurous

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バイト

これは信じられないほど非効率的です

入力としてintの配列を受け入れます

文字列を返しますと、たとえば、間の最短オプションを選択し'720!''6!!'そして'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.