40本のスティックを注文する


15

幅が同じで高さが異なる40本のスティックがあります。右から見ると10本のスティックが見え、左から見ると再び10本のスティックが見えるように、それらを並べて配置できる配置はいくつありますか?

たとえば、このような順序は次のとおりです。注文の例

黒い棒は隠れており、赤い棒は左から見たときに見ることができるものであり、青い棒は右から見たときに見ることができるものであり、紫色のもの(つまり最も長いもの)は見ることができるものです両側から。

テストケースとして:

  • 左から2つ、右から2つを見るために3スティックの注文数がある場合は2
  • 5本のスティックがある場合、左から3つ、右から3つを見るための注文数は6です。
  • 10スティックの場合、左から4つ、右から4つを見るための注文数は90720です。

13
最適なコードとゴルフの答えは、おそらく計算せずに結果を出力するだけなので、固定出力の質問を避けることができます。質問にいくつかの変数入力を持たせることをお勧めします。たとえば、N / Kが入力整数であるKを左/右から見るようなNスティック
Sp3000

4
プログラムが入力を受け入れるように仕様を変更した場合(理由はわかりません-既にテストケースがあります)、プログラムに時間制限を設けるかどうかを検討する必要があります。
Sp3000

1
「投稿されたプログラムを使用して、40/10のケースを計算する必要があります」は十分な時間制限です。
-feersum

1
私は10!/40 = 90720... という事実を克服することはできませんその偶然ですか?
ティム

1
@Tim 90720の重要性は何ですか?カリフォルニア州ロスアラミトスの郵便番号?
デジタル外傷

回答:


8

PARI / GP、80

f(n,v)=abs(sum(k=1,n-1,binomial(n-1,k)*stirling(k,v-1,1)*stirling(n-k-1,v-1,1)))

鉛筆/グリッドゲームの後、見える棒の数はSkyscraper Numbersとも呼ばれます。このコードは、OEIS A218531の式に基づいています(わずかに変更されています)。私はパリをあまり知りませんが、ここでゴルフをすることはあまりないと思います。

テストケースはすべてideone.comに表示されています。結果f(40,10)は次のとおりです。

192999500979320621703647808413866514749680

1
公式には良い理由があります。v左に見える棒の順列の数は、スターリング数s(n,v)です。最も高いスティックがposition kにある場合、左に見えるスティックはそのスティックであり、左に見えるスティックk-1はposition の値leftの左へのサブ順列にありますk。したがって、v左に見えるスティックとv右に見えるスティックs(k,v-1)を使用するには、左半分s(n-k-1,v-1)を並べ替える、右半分を並べ替える、およびbinomial(n-1,k)スティックを2つに分ける選択肢があります。
xnor

@xnor彼らは基本的にリンクされたPDFでその説明をしますが、あなたのものははるかに良いIMOと言われています。
ジオビット

11バイトを保存できますf(n,v,s=stirling)=abs(sum(k=1,n--,binomial(n,k)*s(k,v-1)*s(n-k,v-1)))。これはsterling、再利用のために変数に保存し、1がデフォルトなので最後の引数を省略し、3回ではなくnから1を減算します。
チャールズ

1

Python 3、259バイト

これにはあまり満足していません。

import itertools as i
x=input().split()
y,k=x
y=int(y)
c=0
x=list(i.permutations(list(range(1,y+1))))
for s in x:
 t=d=0;l=s[::-1]
 for i in range(y):
  if max(s[:i+1])==s[i]:t+=1
 for i in range(y):
  if max(l[:i+1])==l[i]:d+=1
 if t==d==int(k):c+=1
print(c)

入力と出力の例:

10 4
90720

指定された範囲の可能なすべての組み合わせを生成し、それらをループして、それらの各番号をチェックして、前の番号の最大値と等しいかどうかを確認します。その後、逆方向に同じ処理を行い、順方向のカウント(t)=逆方向のカウント(d)=指定されたビュー番号(k)の場合、それは有効なものです。これをカウンター(c)に追加し、最後に出力します。


0

R、104

function(N,K)sum(sapply(combinat::permn(N),function(x)(z=function(i)sum(cummax(i)==i)==K)(x)&z(rev(x))))

少しデゴルフ:

    function(N,K) {
      all_perm <- combinat::permn(N)
      can_see_K_from_left <- function(i)sum(cummax(i) == i) == K
      can_see_K_from_both <- function(x)can_see_K_from_left(x) &
                                        can_see_K_from_left(rev(x))
      return(sum(sapply(all_perm, can_see_K_from_both)))
    }

0

Pyth- 38 36バイト

基本的にR回答のポート。かなり遅く、10, 4オンラインで完了することすらできません。

AGHQLlfqhS<bhT@bTUGlf!-,yTy_TH.pr1hG

Pythにないものは、cummaxと == overベクトルだけですが、実装するのに数バイトしかかかり。

説明とさらなるゴルフが近日公開されます。

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

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.