เกมล็อคและกุญแจ


12

มีnกล่องหมายเลข1-n แต่ละกล่องถูกล็อคเพื่อให้สามารถเปิดได้โดยใช้คีย์ที่เกี่ยวข้องประเภทเดียวเท่านั้น (เช่นหมายเลข1-n ) คีย์เหล่านี้กระจายอยู่แบบสุ่มในกล่อง (หนึ่งกล่องอาจมีจำนวนของคีย์ใด ๆ หนึ่งคีย์อาจมีจำนวนซ้ำกัน) จากนั้นกล่องทั้งหมดจะถูกปิด สมบัติ (หมายเลข0 ) ถูกล็อคในกล่องจำนวนมากเช่นกัน

คุณได้ว่าจ้างช่างทำกุญแจเพื่อเรียกคืนสมบัติทั้งหมด เขาคิดค่าบริการสำหรับแต่ละกล่องที่เขาเปิดแตก ไม่มีค่าใช้จ่ายในการเปิดกล่องซึ่งมีกุญแจอยู่แล้ว

อินพุตเป็นเนื้อหาของแต่ละกล่อง คุณสามารถตัดสินใจรูปแบบของอินพุต

ส่งออกค่าใช้จ่ายขั้นต่ำที่จำเป็นในการรับสมบัติ

หมายเหตุ

  1. อัลกอริทึมของคุณอาจใช้เวลานาน แต่ไม่เกี่ยวข้อง
  2. รหัสที่สั้นที่สุดชนะ
  3. ไม่จำเป็นต้องกังวลเกี่ยวกับอินพุตที่ไม่ถูกต้อง

ข้อมูลตัวอย่าง

นี่คือสายผมหมายถึงกุญแจอยู่ในกล่องฉัน

อินพุต

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
นี่อาจเกี่ยวข้องกับสิ่งนี้หรือไม่?
Addison Crump

ยังเกี่ยวข้องกับ: puzzling.stackexchange.com/questions/23150/…
Leif Willerts

@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())และมุ่งเน้นไปที่ส่วนที่สนุกของความท้าทาย
Martin Ender

คำตอบ:


6

CJam, 59 52 50 49 45 43 42 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 ฉันต้องการทราบวิธีการทำงาน
Addison Crump

2
ดู @VoteToClose นี้CJAM101
user41805

array long &ทำงานเพื่อให้คุณสามารถลบจากa 0a&น่าเศร้าที่ทำให้คุณจับได้ยากขึ้นเล็กน้อย
Peter Taylor

@PeterTaylor แต่น่าเสียดายที่ถ้าฉันแทนที่0a&ด้วย0&ฉันก็ต้องแทนที่0+ด้วย0aa+เนื่องจาก0 0&เป็นเท็จ
Dennis

@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กับโปรแกรมของคุณ
ManaMan

@ qumonio มันไม่สามารถปรับขนาดได้โดยเฉพาะอย่างยิ่ง ฉันไม่ได้ทดสอบด้วยอินพุตที่ใหญ่กว่าอินพุตทดสอบในคำถามดังนั้นฉันไม่แน่ใจว่าจะสามารถใช้ฮีปขนาด 1GB ได้ไกลแค่ไหน
ปีเตอร์เทย์เลอร์

ฉันลอง 6 บรรทัดที่นี่แสดงเป็นอาร์เรย์ใน JS: [ [4,0], [1,3,4], [0], [6,0], [3,0], [5]]แน่นอนด้วยสไตล์การป้อนข้อมูลตามที่แสดงในโพสต์ต้นฉบับ
ŽaMan

@ qumonio บนคอมพิวเตอร์ของฉันจัดการกับอินพุตที่ดีโดยมีฮีปเพียง 128MB เท่านั้นซึ่งน้อยกว่าค่าเริ่มต้น
ปีเตอร์เทย์เลอร์

0

Haskell, 173 ไบต์

l เป็นคนที่คุณต้องการโทร

ไม่แน่ใจว่าฉันไม่ควรใช้หลอก - Mapแทน ( [(Int,[Int])]แทน[[Int]])

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.