秘密のサンタ-再訪


11

クリスマスが近づいてきており、それに伴い、毎年恒例の家族のシークレットサンタを手配しています。私はこれをうまく始めたいと思いますが、カップルがお互いのために買わないようにすることは問題を引き起こし続けます、そして、これを何年もしているにもかかわらずBob、ほとんどの贈答品のギフトを購入する際にかなりの問題があります、Erinおそらく失望するでしょうが、彼Frankはタリスカーが好きであることを知っているので、彼は彼にぴったりです。これにより、既存のシンプルなソリューションはどれも私のニーズに受け入れられません。

私の人生を楽にするために、あなたの仕事は、配列の配列(または選択した言語の最も近い代替)が与えられたときに、「gifters」のペアを返す(または出力する)関数(または、言語の最も近い代替)を書くことです次の条件が満たされるように、バイト単位の可能な限り短いコードの「giftees」:

  • 各名前は、入力データからランダムに選択された別の名前とペアになります(指定された条件に基づいて出力をランダム化できるとは限らないことに注意してください)
  • 名前には、一貫性のある順序で隣接行列を表すフラグのリストが提供されるため、列nはrowと同じ人物を参照しnます。
  • 条件を満たせない場合は、あなたの言語で偽物を返してください。
  • 複数のソリューションがある場合、何度も実行する場合、プログラムはそれらをすべて生成できる必要があります。

あなたは私たちがどのある家族の一員伝えることができる必要があるとして、あなたが重複した名前を提示することはありませんと仮定することができますが、区別するために、スペース含むデータを提示することができるBob SeniorからをBob Junior!ソースデータ内の100個の一意の名前など、非常に大規模なファミリに対して提供されたすべてのテストケースを1時間以内に完了する必要があります(以下のサンプルデータセットを参照してください。割り当てられた時間内にこれらすべてを解析できる必要があります)。

入力例:

santa([
    ["Alice", 0, 0, 1, 1, 1, 1, 1],
    ["Bob",   0, 0, 0, 0, 0, 1, 0],
    ["Carla", 1, 1, 0, 0, 0, 1, 1],
    ["Dan",   1, 1, 0, 0, 0, 1, 1],
    ["Erin",  1, 1, 0, 0, 0, 1, 1],
    ["Frank", 1, 1, 1, 1, 1, 0, 1],
    ["Gary",  1, 1, 1, 1, 1, 1, 0]
]);
// might return something like:
[
    ["Alice", "Erin"],
    ["Bob", "Frank"],
    ["Carla", "Alice"],
    ["Dan", "Gary"],
    ["Erin", "Bob"],
    ["Frank", "Dan"],
    ["Gary", "Carla"]
]
santa([
    ["Alice", 0, 1, 1, 1, 0, 1],
    ["Bob",   0, 0, 1, 1, 0, 1],
    ["Carla", 0, 1, 0, 1, 0, 1],
    ["Dan",   0, 1, 1, 0, 0, 0],
    ["Erin",  0, 0, 1, 0, 0, 1],
    ["Frank", 1, 1, 1, 1, 1, 0]
]);
false
santa([
    ["Alice", 0, 1, 1],
    ["Bob",   1, 0, 1],
    ["Carla", 1, 1, 0]
]);
[
    ["Alice", "Bob"],
    ["Bob", "Carla"],
    ["Carla", "Alice"]
]

言語に応じて、入力は他の形式にするSTDIN ことができます。たとえば、詳細は次のように提供できます。

script <<< 'Alice,0,0,1,1,1,1,1
Bob,0,0,0,0,0,1,0
Carla,1,1,0,0,0,1,1
Dan,1,1,0,0,0,1,1
Erin,1,1,0,0,0,1,1
Frank,1,1,1,1,1,0,1
Gary,1,1,1,1,1,1,0'

出力は、適切な形式で提供されますが、言語の最も簡単なものが使用されます。許容される形式には、配列の配列(上記のように)またはhash / Object/ associative配列が含まれSTDOUTます。

Alice:Dan
Bob:Erin
Carla:Bob
Dan:Alice
Erin:Frank
Frank:Carla

疑問がある場合は、回答とともに必要な入力形式と予想される出力形式の例を尋ねて提供してください。

JavaScript実装を参照します。

より大きなデータセット:100、100、200、200 -多くのソリューション、200 -唯一の解決策。

リファレンス実装は、私のマシンでこれらすべてを4秒未満で完了します。

このスクリプトで生成された上記のセット。


1
サブ配列の要素が親配列と同じ順序であると仮定する必要がありますか?そして1、k番目のサブアレイの(n + 1)番目の要素は、k番目の人がn番目の人に与えることができるということですか?
— msh210

@ msh210確かに、冗長ではないことをお、びします。確認するために質問を更新します。
— ドムヘイスティングス

最初の例では、どこからBobへのマッピングを提供しErinますか?からのいずれかが表示さErinれBobます
— LegionMammal978

@ LegionMammal978ああ、それは素晴らしい質問であり、編集でしか答えられない質問です...おologiesび申し上げます!修繕!
— ドムヘイスティングス

1
N0!クリスマスに早めの道です!これはプレゼントを配る秘密のトルコ人であるべきです。
— グラントデイビス

回答:


4

Javascript ES6、191

このソリューションは、可能なすべてのペアリングをペアのリストのリストとして返します。

f=l=>(h=l=>l.length,n=l.map(i=>i.shift()),o=[],(r=s=>(g=h(s))<h(n)?l[g].map((e,x)=>e&&r([...s,x])):o.push([...s]))([]),o.filter(i=>h([...new Set(i)])==h(n)).map(l=>l.map((t,f)=>[n[f],n[t]])))

実行例:

>> example = f([
    ["Alice", 0, 0, 1, 1, 1, 1, 1],
    ["Bob",   0, 0, 0, 0, 0, 1, 0],
    ["Carla", 1, 1, 0, 0, 0, 1, 1],
    ["Dan",   1, 1, 0, 0, 0, 1, 1],
    ["Erin",  1, 1, 0, 0, 0, 1, 1],
    ["Frank", 1, 1, 1, 1, 1, 0, 1],
    ["Gary",  1, 1, 1, 1, 1, 1, 0]])

<< Array [ Array[7], Array[7], Array[7], Array[7], Array[7], Array[7], Array[7], Array[7], Array[7], Array[7], 26 more… ]

>> example[0]

<< Array [ "Alice:Carla", "Bob:Frank", "Carla:Alice", "Dan:Bob", "Erin:Gary", "Frank:Dan", "Gary:Erin" ]

より大きなテストケースに基づいて、すべての順列を生成するため、これは失敗すると思います...お使いのマシンのより大きなセットで完了したことを検証できますか?ありがとう!これらの大きなセットが最初はなかったことをおologiesびします。
— ドムヘイスティングス
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.