हॉरर मूवी सर्च पार्टी


21

प्लॉट : जिमी गायब है; हमें उसे ढूंढना होगा। हमें अलग हो जाना चाहिए।

प्लॉट ट्विस्ट : जिमी पहले ही मर चुका है।

लेकिन, हमारे कलाकारों को यह पता नहीं है, इसलिए उन्हें वैसे भी पूरे क्षेत्र की खोज करने की आवश्यकता है। कोशिकाओं का एक N कॉलम x M पंक्तियाँ (1 <= M, N <= 256) है, या तो "S" को शुरुआती बिंदु के लिए चिह्नित किया गया है। एक बाधा के लिए खुली जगह, या "#" के लिए। यह नक्शा है

0 <= p <= 26 कॉस्टार , 0 <= q <= 26 एक्स्ट्रा , और 1 स्टार हैं । हर कोई शुरू में एस चिह्नित सेल में है।

नियम

प्रत्येक व्यक्ति को नीचे दिखाया गया एक दृष्टि त्रिज्या है:

 ...
.....
..@..
.....
 ...

स्टार को "@", "ए" के साथ शुरू होने वाले कैपिटल अक्षरों से लागत और लोअरकेस अक्षरों द्वारा एक्स्ट्रा द्वारा "ए" के साथ शुरू किया जाता है। प्रारंभ में, शुरुआती बिंदु के आसपास का दृश्य त्रिज्या पहले से ही खोजा गया है। यदि यह मानचित्र के पूरे खुले स्थान का गठन करता है, तो खेल समाप्त हो जाता है। प्रत्येक क्रम, निम्नलिखित क्रम में :

  1. प्रत्येक व्यक्ति एक साथ एक राजा को स्थानांतरित करता है (या तो अभी भी खड़ा है, या 8 पड़ोसी कोशिकाओं में से एक पर जा रहा है)।
  2. प्रत्येक व्यक्ति के चारों ओर दृष्टि त्रिज्या की सभी कोशिकाओं को खोजा गया।
  3. अगर कोई कॉस्टार किसी और को नहीं देख सकता है, तो वह मर जाती है। यदि कोई अतिरिक्त कोस्टार, स्टार, या कम से कम 2 अन्य एक्स्ट्रा कलाकार नहीं देख सकता है, तो वह मर जाता है। ये एक साथ होते हैं - अर्थात, एक ही मोड़ पर मौतों की कोई श्रृंखला प्रतिक्रिया नहीं हो सकती है; उपरोक्त शर्तों की जाँच की जाती है, और जो कोई भी मरने वाला है वह एक ही बार में मर जाता है।
  4. यदि मानचित्र पर सभी खुले स्थान खोजे गए हैं, तो खोज समाप्त हो गई है।

टिप्पणियाँ

कई लोग किसी भी बिंदु पर एक ही वर्ग में हो सकते हैं, और ये लोग एक दूसरे को देख सकते हैं।

बाधाएँ दृष्टि को कभी बाधित नहीं करती हैं, केवल गति करती हैं; लोग एक दूसरे को देख सकते हैं, एर ... लावा?

नक्शे पर खुले स्थान को राजा की चाल से जुड़े रहने की गारंटी है।

प्रारंभिक "एस" को एक बाधा के बजाय खुली जगह माना जाता है।

कोई भी राजा चलता है कि एक खुले स्थान पर भूमि वैध है। उदाहरण के लिए, निम्नलिखित चाल कानूनी है:

....      ....
.@#. ---> ..#.
.#..      .#@.
....      ....

इनपुट

इनपुट प्रारूप में होगा

N M p q
[N cols x M rows grid with characters ".", "#", and "S"]

नमूना जानकारी:

6 5 0 0
......
......
..S...
......
......

तथा

9 9 1 1
S.......#
.......##
......##.
..#####..
...##....
...##....
...#.....
....#..#.
.........

p और q क्रमशः कोस्टार और एक्स्ट्रा की संख्या हैं।

उत्पादन

आउटपुट होना चाहिए, प्रत्येक मोड़ के लिए, जो चालें बनाई जाती हैं, उनके द्वारा निर्देशित दिशाओं के साथ

789
456
123

चालों का क्रम मायने नहीं रखता, क्योंकि वे सभी एक साथ लागू होते हैं। किसी व्यक्ति के लिए एक चाल को सूचीबद्ध नहीं करना ठीक है, और उसे दिशा में ले जाने के बराबर है। 5. निम्नलिखित प्रारूप में सूचीबद्ध होना चाहिए:

@9 A2 a2 B7.

"।" एक मोड़ के लिए अपनी चाल के अंत को दर्शाता है।

मानचित्र खोजे जाने के बाद, आउटपुट की अंतिम पंक्ति तीन पूर्णांक होनी चाहिए, रिक्त स्थान से अलग: मोड़ की संख्या जो आपको बोर्ड को खोजने के लिए समाप्त हुई, जीवित कॉस्टरों की संख्या, और जीवित एक्स्ट्रा कलाकार की संख्या। पहला उदाहरण इनपुट के लिए

6 5 0 0
......
......
..S...
......
......

निम्नलिखित मान्य आउटपुट है:

@4.
@6.
@6.
@6.
4 0 0

एक अंतिम नोट: तारा मर नहीं सकता है और नक्शे पर खुली जगह जुड़ा होने की गारंटी है, इसलिए खोज हमेशा सफल होगी।

स्कोरिंग

आपका स्कोर बेंचमार्क परीक्षणों के एक सेट पर ले जाने की कुल संख्या है ; आप अपने जवाब के साथ अपना खुद का परीक्षण मामला प्रस्तुत करने के लिए स्वागत करते हैं। बेंचमार्क सेट पर रहने वाले कॉस्टरों की संख्या का योग टाई-ब्रेकर के रूप में उपयोग किया जाएगा, और घटना में अभी भी एक टाई है, जीवित एक्स्ट्रा कलाकार की संख्या का उपयोग किया जाएगा।

परीक्षण सेट और नियंत्रक

वर्तमान में, 5 नक्शे https://github.com/Tudwell/HorrorMovieSearchParty/ पर ऑनलाइन हैं । जवाब प्रस्तुत करने वाला कोई भी व्यक्ति एक परीक्षण मामला प्रस्तुत कर सकता है, जिसे मैं किसी भी कारण से अस्वीकार करने का अधिकार सुरक्षित रखता हूं (यदि मैं किसी कारण से आपके नक्शे को अस्वीकार करता हूं, तो आप दूसरा प्रस्तुत कर सकते हैं)। इन्हें मेरे विवेक पर निर्धारित परीक्षण में जोड़ा जाएगा।

एक पायथन (2.7.5 में परीक्षण किया गया) नियंत्रक को जीआईटीबी पर कंट्रोलरहोम के रूप में प्रदान किया गया है । एक दूसरा कंट्रोलर, कंट्रोलर_डिस्ट्रैम , एक समान है सिवाय इसके कि यह सर्च के दौरान ग्राफिकल आउटपुट दिखाता है (इसके लिए Pygame लाइब्रेरी की आवश्यकता है)।

ग्राफिकल कंट्रोलर आउटपुट

उपयोग :

python controller.py <map file> <your execution line>

अर्थात:

python controller.py map1.txt python solver.py map1.txt

कंट्रोलर में फॉर्म का आउटपुट (आपके प्रोग्राम का स्टडिन ) है

Turn 1
@:2,3 A:2,3 B:2,3.
##...##
#ooo..#
ooooo..
ooooo..
ooooo..
#ooo...
##.....
###....
----------------------------------------

यह टर्न नंबर है (टर्न 1 आपके स्थानांतरित होने से पहले है), एक '.'- सभी एक्टर्स की समाप्ति सूची और उनके x, y निर्देशांक (ऊपरी बाएँ वर्ण है (0,0)), पूरे का एक प्रतिनिधित्व बोर्ड, और 40 'के साथ एक लाइन। यह तब फॉर्म के इनपुट (आपके प्रोग्राम के स्टडआउट से ) का इंतजार करता है

@9 A2 B7.

यह ऊपर निर्दिष्ट आउटपुट स्वरूप है। नियंत्रक खुले स्थान के लिए एक 'ओ' आउटपुट करता है जिसे खोजा गया है, '।' खुले स्थान के लिए जिसे खोजा नहीं गया है, और बाधाओं के लिए '#'। इसमें केवल लोगों की सूची में रहने वाले लोग और उनके निर्देशांक शामिल हैं, और खेल के सभी नियमों को ट्रैक करता है। यदि अवैध चालन का प्रयास किया जाता है तो नियंत्रक बाहर निकल जाएगा। यदि किसी दिए गए मोड़ के लिए खोज समाप्त हो जाती है, तो आउटपुट ऊपर नहीं है; इसके बजाय यह रूप का है

Finished in 4 turns
4 1 0

यहां "4 1 0" 4 कुल मुड़ता है, 1 जीवित कोस्टार, और 0 जीवित एक्स्ट्रा कलाकार को दर्शाता है। आपको नियंत्रक का उपयोग करने की आवश्यकता नहीं है; बेझिझक इसका उपयोग करें या इसे अपनी प्रविष्टि के लिए संशोधित करें। यदि आप इसका उपयोग करने और समस्याओं का सामना करने का निर्णय लेते हैं, तो मुझे बताएं।

नियंत्रक लिखने में मेरी मदद करने के लिए @githubphagocyte का धन्यवाद।

संपादित करें: यादृच्छिक प्रविष्टि के लिए, आप किसी विशेष मानचित्र पर किसी भी रन को उस मानचित्र के लिए अपने स्कोर के रूप में चुन सकते हैं। ध्यान दें कि स्कोरिंग आवश्यकताओं के कारण, आपको हमेशा सबसे छोटा मोड़ चुनना चाहिए, फिर सबसे कम मृत कॉस्टार, फिर प्रत्येक नक्शे के लिए सबसे कम मृत एक्स्ट्रा कलाकार।


7
दूसरी पंक्ति स्पॉइलर टैग के बीच होनी चाहिए!
Averroes

जवाबों:


8

रूबी, सेफ्टी फर्स्ट + बीएफएस + रैंडमनेस, स्कोर। 1458

मुझे यकीन नहीं है कि आप यादृच्छिक प्रस्तुतियाँ कैसे स्कोर करेंगे। यदि सभी उत्तरों को निर्धारक होना है, तो मुझे बताएं और मैं एक बीज चुनूंगा या पूरी तरह से यादृच्छिकता से छुटकारा पाऊंगा।

इस समाधान की कुछ विशेषताएं और कमियाँ:

  • कोई कभी नहीं मरता। शुरुआत में मैंने सभी कलाकारों को ऐसे समूह में रखा है कि हर कोई सुरक्षित है। इन समूहों में से प्रत्येक में वर्ण एकसमान में चलते हैं। यह सभी को जीवित रखने के लिए अच्छा है, लेकिन आशातीत रूप से कुशल नहीं है।
  • प्रत्येक समूह मानचित्र पर निकटतम अस्पष्टीकृत स्थान की खोज करता है, जो पहले खोज के माध्यम से होता है और खोज की उस शाखा की पहली चाल लेता है। यदि कई इष्टतम चालों के बीच टाई होती है तो एक यादृच्छिक एक उठाया जाता है। यह सुनिश्चित करना है कि सभी समूह हमेशा एक ही दिशा में न चलें।
  • यह कार्यक्रम फ़ील्ड-ऑफ़-व्यू के बारे में नहीं जानता है। यह वास्तव में हर अस्पष्टीकृत सेल में जाने की कोशिश करता है। इसे ध्यान में रखते हुए प्रदर्शन में काफी वृद्धि हो सकती है, तब से आप प्रत्येक चाल की गुणवत्ता को यह निर्धारित कर सकते हैं कि यह कितनी कोशिकाओं को उजागर करेगा।
  • कार्यक्रम घुमाव (अभिनेता समूहों को छोड़कर) के बीच जानकारी का ट्रैक नहीं रखता है। यह बड़े परीक्षण मामलों पर काफी धीमी गति से बनाता है। map5.txtपूरा होने में 1 से 13 मिनट का समय लगता है।

कुछ परिणाम

Map     Min turns    Max turns
map1        46           86
map2        49          104
map3       332          417
map4       485          693
map5       546          887

अब यहाँ कोड है:

start = Time.now

map_file = ARGV.shift
w=h=p=q=0
File::open(map_file, 'r') do |file|
    w,h,p,q = file.gets.split.map(&:to_i)
end

costars = p > 0 ? (1..p).map {|i| (i+64).chr} : []
extras = q > 0 ? (1..q).map {|i| (i+96).chr} : []
groups = []

costars.zip(extras).each do |costar, extra|
    break unless extra
    groups << (costar + extra)
    costars.delete(costar)
    extras.delete(extra)
end

costars.each_slice(2) {|c1, c2| groups << (c1 + (c2 || '@'))} unless costars.empty?
extras.each_slice(3) {|c1, c2, c3| groups << (c1 + (c2 || '') + (c3 || '@'))} unless extras.empty?
groups << '@' unless groups.join['@']

#$stderr.puts groups.inspect


directions = {
    1 => [-1, 1],
    2 => [ 0, 1],
    3 => [ 1, 1],
    4 => [-1, 0],
    5 => [ 0, 0],
    6 => [ 1, 0],
    7 => [-1,-1],
    8 => [ 0,-1],
    9 => [ 1,-1]
}

loop do
    break unless gets # slurp turn number
    coords = {}
    input = gets
    input.chop.chop.split.each{|s| actor, c = s.split(':'); coords[actor] = c.split(',').map(&:to_i)}
    #$stderr.puts input
    #$stderr.puts coords.inspect
    map = []
    h.times { map << gets.chomp }

    gets # slurp separator
    moves = groups.map do |group|
        x, y = coords[group[0]]
        distances = {[x,y] => 0}
        first_moves = {[x,y] => nil}
        nearest_goal = Float::INFINITY
        best_move = []
        active = [[x,y]]
        while !active.empty?
            coord = active.shift
            dist = distances[coord]
            first_move = first_moves[coord]
            next if dist >= nearest_goal
            [1,2,3,4,6,7,8,9].each do |move|
                dx, dy = directions[move]
                x, y = coord
                x += dx
                y += dy
                next if x < 0 || x >= w || y < 0 || y >= h || map[y][x] == '#'
                new_coord = [x,y]
                if !distances[new_coord]
                    distances[new_coord] = dist + 1
                    first_moves[new_coord] = first_move || move
                    active << new_coord if map[y][x] == 'o'
                end

                if dist < distances[new_coord]
                    distances[new_coord] = dist + 1
                    first_moves[new_coord] = first_move || move
                end

                if map[y][x] == '.'
                    if dist + 1 < nearest_goal
                        nearest_goal = dist + 1
                        best_move = [first_moves[new_coord]]
                    elsif dist + 1 == nearest_goal
                        best_move << first_moves[new_coord]
                    end
                end
            end
        end

        #if group['@']
        #    distances.each{|k,v|x,y=k;map[y][x]=(v%36).to_s(36)}
        #    $stderr.puts map
        #end

        dir = best_move.sample
        group.chars.map {|actor| actor + dir.to_s}
    end * ' '
    #$stderr.puts moves
    puts moves
    $stdout.flush
end

#$stderr.puts(Time.now - start)

वहाँ कुछ डिबग आउटपुट बाहर टिप्पणी की है। विशेष रूप से if group['@']ब्लॉक काफी दिलचस्प है क्योंकि यह बीएफएस डेटा के एक दृश्य को प्रिंट करता है।

संपादित करें: बीएफएस को रोककर महत्वपूर्ण गति में सुधार, यदि पहले से ही एक बेहतर कदम मिल गया है (जो कि पहले स्थान पर बीएफएस का उपयोग करने का बिंदु था)।


क्या यह उम्मीद करना सुरक्षित है कि आपकी प्रविष्टि में हमेशा मैप फ़ाइल तक पहुंच होगी?
23

हाँ; मैप फ़ाइल हमेशा होती है, और यदि आप कंट्रोलर का उपयोग करते हैं, तो आपको इसकी एक अद्यतन प्रति प्रत्येक मोड़ पर मिलती है।
एरिक ट्रेसलर
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.