ポールに色をつけて


22

あなたの仕事はポールをペイントすることであり、クライアントが4つの赤いセクションと3つの黄色のセクションでポールをペイントするように要求するとしましょう。次のように簡単に実行できます。

r y r y r y r

黄色と赤のストライプだけで。ここで、クライアントが2つの赤いセクション、2つの黄色のセクション、1つの緑のセクションでポールをペイントするように要求したとしましょう。ポールをペイントする方法はいくつかあります

g y r y r
y g r y r
y r g y r
y r y g r
y r y r g
g r y r y
r g y r y
r y g r y
r y r g y
r y r y g
y r g r y
r y g y r

より正確には、12の方法でポールをペイントします。これにより、関連するより多くの色とセクションが爆発します

クライアントが3つの赤いセクションと1つの黄色のセクションが必要だと言った場合、そのようなポールを描く方法はありません。セクションをどのように配置しようとしても、2つの赤いセクションが接触し、2つの赤いセクションが接触すると単一の赤いセクションになります。

そして、それはほとんどポールを塗るための私たちの1つのルールです

隣接するセクションは同じ色ではない場合があります

仕事

必要な色とセクションのリストを指定して、要求に応じて極をペイントする可能な方法の数を出力します。合理的な方法(整数、文字、文字列)で色を表すことができますが、一度に255を超える異なる色が与えられることはありません。希望する場合は、名前に色を割り当てず、セクションカウントのリストを取得する方が簡単な場合も選択できます。

テストケース

これらは、特に大きくなるにつれて、手で計算するのがかなり困難です。誰かが提案されたテストケースを持っている場合、私はそれを追加します。

[4,3]    -> 1
[2,2,1]  -> 12
[3,1]    -> 0
[8,3,2]  -> 0
[2,2,1,1]-> 84

たとえば、[4,3]の「rrrryyy」として入力を受け付けますか?
レオ

@Leo確かにそれは完全に合理的です。
小麦ウィザード

入力を取得できます[1, 1, 1, 1, 2, 2, 2]か?そうだと思います。
エリックアウトゴルファー


4
それほど重要ではありませんが、ポーランド語という単語を大文字にすると、ポーランドの人について話しているように聞こえます。
NH。

回答:


9

Mathematica、37 44 48 60 62 バイト

入力を整数のリストとして取得します{1, 1, 1, 2, 2}Wolfram Sandboxで試してみてください。

パターンマッチング手法、@ Not a tree!

Count[Split/@Permutations@#,{{_}..}]&

Split単一のリストを連続する要素のサブリストに分割します。例えば{1, 1, 2, 3, 4, 4}{{1, 1}, {2}, {3}, {4, 4}}

{{_}..}、すなわち、です{{_}, {_}, {_}, ...}。パターンは、単項サブリストのリストと一致します。

Differences メソッド、48バイト:

Tr@Abs@Clip[1##&@@@Differences/@Permutations@#]&

コードはDifferences、隣接する要素が同じかどうかを判断するために使用します。

ステップバイステップ:

  1. Permutations@# 入力リストのすべての順列をN!* Nリストに生成します。
  2. Differences/@ N個の要素の差を計算し、N!*(N-1)リストを生成します。
  3. 1##&@@@すべてのリストの乗算を計算します。リストに含まれている場合0(隣接する2つの要素が同じ場合)、結果はになります0。リスト。
  4. Clip[]のようSign[]に機能し、リストを(-inf、inf)から[-1、1]に変換します
  5. Tr@Absすべて-11なり、N!-lengthリストには0(無効)と1(有効)のみが含まれます。したがって、リストを合計するだけです。

4
いくつかのパターンマッチングで4バイトを保存できますPermutations@#~Count~Except@{___,x_,x_,___}&
ツリーではない

2
もう1つあります:Count[Split/@Permutations@#,{{_}..}]&、37バイト!
ツリーではない

7

ゼリー、7バイト

Œ!QIẠ€S

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

例えば、入力を受け取り[1,1,1,1,2,2,2]について[4,3][8,3,2]テストケースは、TIO上で実行するために時間がかかりすぎます。

使い方

Œ!QIẠ€S - main link, input as a list
Œ!      - all permutations
  Q     - remove duplicates
   I    - take increments (returns a 0 for two adjacent identical numbers)
    Ạ€  - apply “all” atom to each: 0 for containing 0 and 1 otherwise
      S - sum

猶予期間を悪用しました...;)
アウトゴルファーのエリック


@ nmjcman101それはうまくいくようです。素敵な発見!P単純さのために、すべてのアトムよりもを優先しました。
fireflame241

@ fireflame241技術的には、これはあらゆる原子ではなく、すべての原子です。
エリック・ザ・アウトゴルファー

BTWのP€代わりにẠ€動作します。
エリック・ザ・アウトゴルファー


5

Mathematica、50バイト

Expand[1##&@@(LaguerreL[#,-1,x](-1)^#)]/._^i_:>i!&

MathicsまたはWolframサンドボックス試してみてください

テストケースのように入力を取ります。たとえば{4,3}、「4つの赤いストライプ、3つの黄色のストライプ」を意味します。

これは、私がここで見つけた式の単純な実装です。「ナイーブ」とは、「数学がどのように機能するかわからないので、説明を求めないでください」という意味です。


1
この答えで与えられた数学の説明がありますか?
TheLethalCoder

@TheLethalCoder Seconded、誰かが私に数学を説明してもらえますか?
ツリーではない


3

Ruby 2.4、47バイト

入力文字のリストです:テストケースの場合[4,3]、入力が可能%w[a a a a b b b]"1111222".charsまたはRubyで有効ですいくつかの他のアレイフォーマットする方法。

->x{x.permutation.uniq.count{|a|a*''!~/(.)\1/}}

2.4が必要ですEnumerator#uniq(以前のバージョンでは、Arrayクラスでのみ使用可能でした)。そのため、TIOリンクは5バイトを追加to_aして、上記の機能がないため、最初にを介して置換列挙子を配列に変換します。

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


3

R、72バイト

pryr::f(sum(sapply(unique(combinat::permn(x)),pryr::f(!sum(!diff(x))))))

関数を作成します

function (x) 
{
    sum(sapply(unique(combinat::permn(x)), pryr::f(!sum(!diff(x)))))
}

[1,1,1,1,2,2,2]Erik the Outgolferのコメントに従ってフォームに入力を取ります。用途combinatpermn全ての順列のリストを作成し、その後、機能uniqueのすべての個別のエントリを取得します。sapply次に、すべてのエントリに次の機能を適用します。

pryr::f(!sum(!diff(x)))

評価する

function (x) 
!sum(!diff(x))

これに注意してください xx、大きな関数の入力とは異なる。この関数で別の文字を使用すると、だまされますpryr::fすると、大きな関数には別の引数が必要であると信じ込まれます。

とにかく、順列が与えられると、この関数はベクトル間の差を取ります:2 1 3 4 2 1 -> -1 2 1 -2 -1!は非FALSEゼロをにTRUE、ゼロをに変換するため、ベクトルはになりFALSE FALSE FALSE FALSE FALSEます。いずれかのがあるかどうかを確認することを要約するとTRUE、sは(TRUE暗示しますdiff=0 -> 2つの同じ連続番号ます)。これを逆にすると!、順列に連続した値があるかどうかのブール値を取得できます。

これらのブール値を合計すると、そうでない場合の順列の総数がわかります。

[8,3,2]これらの順列を保存するために46GBのベクターが必要なため、テストケースでは機能しません。




2

、8バイト

#ȯ¬ṁtguP

オンラインでお試しください! の形式"aaabb"で入力を受け取ります[3,2]。最も長いテストケースでタイムアウトします。

説明

ここでは特別なことは何もせず、隣接する要素のすべてのグループの長さが1であるユニークな順列を数えるだけです。

#ȯ¬ṁtguP
       P  Permutations.
      u   Remove duplicates.
#ȯ        Count how many satisfy the following condition:
     g    group adjacent elements,
   ṁt     concatenate tails of groups
  ¬       and negate.

2

ルビー、84 76バイト

f=->a,x=p{i=s=0;a.map{a[i-=1]-=1;a[i]<0||i!=x&&s+=f[a,i];a[i]+=1}.max>0?s:1}

再帰的なラムダ関数。それぞれの可能な色を見て、再帰的なツリー検索を行い、すべてのストライプを使用する回数をカウントします。

説明(古いバージョンの場合):

f=->
  a, # a is the input array in [3,3,4] form
  x = -1 # x is the last color placed (-1 when run normaly, used in recursive calls)
{
  j = i = s = 0;
  # i is the index
  # s is the sum of valid final patterns (the answer)
  # j is used to count the total stripes

  a.map{|e| # Iterate over array of colors

    a[i] -= 1; # remove a stripe of current color (the array will be used in recursive call)

    s += f[a,i] if i!=x && e>0;
      # add to sum recursively if:
        # we are not using the same color as the last color AND
        # we have stripes of the current color left to paint

    a[i] += 1; # replace the stripe we removed above 

    j += a[i]; # add stripes to j

    i+=1 # increment the index

  }; # End loop

  j == 0 ? 1 : s
  # if we had stripes, give the recursive sum, otherwise return 1 
}

x=p初期条件として?この場合のpエイリアスとして機能し、nil使用されているチェックを満たす必要があります。
値インク

1

MATL11 8バイト

Y@Xu!dAs

入力形式は [1 1 1 1 2 2 2]ため[4 3]など、

最後のテストケースのメモリが不足します。

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

説明

Y@    % Implicit input. Matrix of all permutations. Each row is a permutation
Xu    % Unique rows
!     % Transpose
d     % Consecutive differences along each column
A     % All: true for columns such that all its entries are nonzero
s     % Sum. Implicitly display
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.