ロックとキーのゲーム


12

1-nの番号が付いたn個のボックスがあります。各ボックスはロックされており、対応する1つのタイプのキー(1〜nの番号も付けられている)のみで開くことができます。これらのキーはボックス内にランダムに散らばっていて(1つのボックスには任意の数のキーがあり、1つのキーには任意の数の重複があります)、すべてのボックスが閉じられます。宝物(番号0)も多くのボックスでロックされています。

すべての宝物を回収するために鍵屋を雇いました。彼は、開いた箱ごとに料金を請求します。キーが既に利用可能なボックスを開くのに料金はかかりません。

入力は各ボックスの内容です。入力の形式を決定できます。

宝物を入手するのに必要な最低コストを出力します。

ノート

  1. アルゴリズムには時間がかかる場合がありますが、それは無関係です。
  2. 最短のコードが優先されます。
  3. 無効な入力を気にする必要はありません。

サンプルデータ

ここで、行iはボックスiに存在するキーを表します。

入力

2 0
3
4 0
5 6 0
6
0

出力

1

入力

2 0
3 0

4 0
6
5 0

出力

3

入力

2 4 0
3 0

1 0
6
5 0

出力

2

入力

1
3 4


2 6
5

出力

0

2
これはおそらくこれに関連していますか?
アディソンクランプ


@VoteToClose素敵なビデオ。一般的なものではなく、数学的なパズルと特定のアルゴリズムについて述べていることを除いて、似ています。
ghosts_in_the_code

1
:これは、木とスチールの100のロックボックスについては、このパズルに関連すると思われるpuzzling.stackexchange.com/q/17852/4551
XNOR

4
@ghosts_in_the_codeそれは単純さではなく、柔軟性に関するものです。一般的に、構造化された入力を必要とする課題では、データが前処理されていない限り、便利なリスト形式を使用できます。あなたが持っているような空白で区切られたファイルを意味する可能性のある言語に応じて、またはそれを意味する[[1] [3 4] [] [] [2 6] [5]]かもしれません{{1},{3,4},{},{},{2,6},{5}}。このようにして、ほとんどの言語は入力を読むことをささいなことまで減らしi=eval(read())、課題の楽しい部分に集中することができます。
マーティンエンダー

回答:


6

CJam、59 52 50 49 45 43 42バイト

qN/ee::~e!{_0+{0a&}#>W%_{1$|(z@-},,\;}%:e<

@MartinBüttnerに3バイトのゴルフをし、さらに4バイトの道を開いてくれてありがとう!

CJamインタプリタでオンラインで試してください。

使い方

qN/      e# Read all input and split it at linefeeds.
ee       e# Enumerate the lines.
         e# STACK: [[0 "i0 i1 ..."] [1 "j0 j1 ..."] ...]
::~      e# Apply ~ (bitwise NOT/evaluate) to each item of the pairs.
         e# STACK: [[-1 i0 i1 ...] [-2 j0 j1 ...] ...]
e!       e# Push all unique permutations of the resulting array.
{        e# For each permutation:
  _0+    e#   Push a copy and append 0 to it.
  {0a&}# e#   Find the first index of an element that contains 0.
  >      e#   Discard all previous elements of the array.
  W%     e#   Reverse the resulting array.
         e#   We now have a (partial) permutation that contains
         e#   all treasures and ends with a treasure.
  _      e#   Push a copy. The original (which contains lists, but no 
              numbers) will serve as accumulator.
  {      e#   Filter; for each list in the array:
    1$|  e#     Push a copy of the accumulator and perform set union.
    (    e#     Shift out the first element (bitwise NOT of 0-based index).
    z    e#     Apply absolute value to push the 1-based index.
    @-   e#     Perform set difference with the former state of the 
         e#     accumulator. This pushes an empty list iff the 1-based
         e#     index was already in the accumulator, i.e., iff we already
         e#     had a key.
  },     e#   Keep the element if we did not have the key.
  ,      e#   Count the kept elements.
  \;     e#   Discard the accumulator from the stack.
}%       e#
:e<      e# Get the minimum of all results.

2
CJamの理解の賜物なしで説明を追加してもらえますか?:Dこれがどのように機能するか知りたい。
アディソンクランプ

2
この時@VoteToClose見CJAM101
user41805

array long &が機能するため、をaから削除できます0a&。悲しいことに、これはあなたを捕まえるのを少し難しくします。
ピーターテイラー

私は交換した場合@PeterTaylor残念ながら、0a&0&、私はまた、交換する必要が0+0aa+ているので、0 0&falsyです。
デニス

@VoteToClose回答を編集しました。
デニス

2

CJam(53バイト)

Nq+N/:a::~:A,_m*_.&{,}$_{{_Af=e_|}:PA,*A,,^0-P0&!}#=,

これは、オンライン通訳者にとっては遅すぎます。

解剖

Nq+N/:a::~:A      e# Parse the input into arrays and store in A
,_m*_.&           e# Generate (with duplicates) a powerset of [0 1 ... n]
{,}$              e# Sort by size
_{                e# Create a copy and search for first index satisfying...
  {_Af=e_|}:P     e#   Store in P a block which does a reachability expansion
  A,*             e#   Apply it n times (no path can be longer than n)
  A,,^0-          e#   Invert to get the unreached nodes (except 0)
  P               e#   Apply P again to see what's reached from the unreached nodes
  0&!             e#   Check that it doesn't include [0]
}#
=,                e# Look up the powerset element at that index and find length

java.lang.OutOfMemoryError: Java heap spaceあなたのプログラムを受け取りました。
ザーマン

@qumonio、特にスケーラブルではありません。問題のテスト入力よりも大きい入力でテストしたことはないので、標準の1GBヒープでどれだけの入力が可能かはわかりません。
ピーターテイラー

ここでは、JSの配列として示されている6行を試していました。[ [4,0], [1,3,4], [0], [6,0], [3,0], [5]]もちろん、元の投稿に示されている入力スタイルを使用しています。
ザーマン

@qumonio、私のコンピューターでは、128MBのヒープでその入力を正常に処理しますが、これはデフォルトよりも少ないです。
ピーターテイラー

0

Haskell、173バイト

l あなたが電話したいものです。

Map代わりに(の[(Int,[Int])]代わりに[[Int]])pseudo- を使用すべきではないかどうかわからない。

l=o[].map(map read).map words.lines
o[]b|0`notElem`concat b=0|0<1=1+minimum[o[n]b|n<-[1..length b],b!!(n-1)/=[]]
o(n:k)b=o(filter(/=0)(k++b!!(n-1)))(take(n-1)b++[]:drop n b)
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.