आग प्रसार सिम्युलेटर


28

मान लीजिए कि हमारे पास इस तरह एक मैट्रिक्स है:

11111
12221
12321
12221
11111

यह मैट्रिक्स एक इलाके का प्रतिनिधित्व करता है, और प्रत्येक सेल इलाके के एक हिस्से का प्रतिनिधित्व करता है। प्रत्येक सेल में संख्या उस समय का प्रतिनिधित्व करती है जब इलाके का भाग पूरी तरह से जलाया जाना चाहिए (मिनट में, यदि माप इकाई की आवश्यकता है), इसकी दहनशीलता के अनुसार । यदि आग किसी भी स्थिति (सेल) में शुरू होती है, तो आग को आसन्न कोशिकाओं (क्षैतिज और ऊर्ध्वाधर केवल नहीं, विकर्ण) से फैलने से पहले उस सेल को पूरी तरह से जलाया जाना चाहिए। इसलिए, अगर केंद्र की स्थिति में आग लग जाती है, तो आग की जरूरत है:

11111        11111        11111        11011        10001        00000
12221  3 m.  12221  2 m.  12021  1 m.  11011  1 m.  00000  1 m.  00000
12321 -----> 12021 -----> 10001 -----> 00000 -----> 00000 -----> 00000
12221        12221        12021        11011        00000        00000
11111        11111        11111        11011        10001        00000

स्पष्टीकरण:

  • आग [2,2] (0-आधारित) पर शुरू होती है, जिसमें 3 का बर्न टाइम होता है।
  • 3 मिनट के बाद, [1,2], [2,1], [2,3], [3,2] जलने लगते हैं।
  • 2 मिनट के बाद, उन कोशिकाओं का जलना समाप्त हो जाता है और आग सभी आसन्न कोशिकाओं में फैल जाती है, लेकिन [0,2], [2,0], [2,4], [0,4] को जलने के लिए केवल 1 और मिनट की आवश्यकता होती है, इसलिए
  • 1 मिनट के बाद, उन कोशिकाओं को जला दिया जाता है और कोशिका उनके आसन्न कोशिकाओं में फैल जाती है।
  • 1 और मिनट के बाद, चरण 3 से शेष कोशिकाएं जलती हैं और आग उनके आसन्न कोशिकाओं को फैलती है (जो पहले से ही जल चुके हैं, इसलिए कुछ भी नहीं होता है)।
  • 1 आखिरी मिनट के बाद, आग पूरे इलाके को जला देती है।

तो उस मामले का हल 8 मिनट है। यदि आग ऊपरी बाएँ सेल में शुरू होती है [0,0]:

11111     01111     00111     00011     00001     00000
12221  1  12221  1  02221  1  01221  1  00121  1  00011   1
12321 --> 12321 --> 12321 --> 02321 --> 01321 --> 00321  -->
12221     12221     12221     12221     02221     01221
11111     11111     11111     11111     11111     01111

00000     00000     00000     00000     00000
00000  1  00000  1  00000  1  00000  1  00000
00221 --> 00110 --> 00000 --> 00000 --> 00000
00221     00121     00020     00010     00000
00111     00011     00001     00000     00000

इसलिए अब कुल समय 10 मिनट है।

चुनौती

पूर्णांक मानों के NxM मैट्रिक्स (N> 0, M> 0) को देखते हुए, जो उस समय का प्रतिनिधित्व करता है जिसे प्रत्येक कोशिका को पूरी तरह से उपभोग करने की आवश्यकता होती है, उस मैट्रिक्स और पूर्णांक की एक जोड़ी को लिखें जिसमें आग लगने की स्थिति के साथ एक पूर्णांक होता है। , और पूरे इलाके को पूरी तरह से भस्म करने के लिए आग के लिए आवश्यक समय देता है।

  • हर सेल में एक पॉजिटिव (नॉन-जीरो) बर्न टाइम होगा। आप कक्षों के लिए अधिकतम मान नहीं ले सकते।
  • मैट्रिक्स को वर्ग या सममित होने की आवश्यकता नहीं है।
  • मैट्रिक्स 0-अनुक्रमित या 1-अनुक्रमित हो सकता है, जैसा कि आप चाहें।
  • स्थिति को एक एकल पैरामीटर के रूप में पूर्णांकों के टपल के साथ दिया जा सकता है, जो भी अन्य उचित प्रारूप के दो अलग-अलग पैरामीटर हैं।
  • मैट्रिक्स के आयामों को इनपुट मापदंडों के रूप में निर्दिष्ट नहीं किया जा सकता है।
  • आपको प्रत्येक मध्यवर्ती चरण को आउटपुट करने की आवश्यकता नहीं है, बस समय की मात्रा पूछी गई है। लेकिन मुझे कोई शिकायत नहीं होगी यदि चरणों की किसी भी तरह से कल्पना की जाए।

एक और उदाहरण:

Fire starts at [1,1] (a '>' represents a minute):

4253   4253   4253   4153   4043   3033   2023    0001   0000
2213 > 2113 > 2013 > 1003 > 0002 > 0001 > 0000 >> 0000 > 0000 
1211   1211   1211   1111   1001   0000   0000    0000   0000

Output: 9

यह , इसलिए प्रत्येक भाषा की जीत के लिए सबसे छोटा कार्यक्रम हो सकता है!


1
@LeanderMoesinger को किसी भी मैट्रिक्स के साथ काम करना होगा। मेरा मतलब है कि आपका प्रोग्राम या फ़ंक्शन मैट्रिक्स के आयामों को इनपुट मापदंडों के रूप में स्वीकार नहीं कर सकता है, लेकिन निश्चित रूप से आप अपने कोड के अंदर उन आयामों की गणना कर सकते हैं।
चार्ली

क्या कॉलम-प्रमुख क्रम में एकल नंबर के रूप में इनपुट लिया जा सकता है ? यही है, मैट्रिक्स प्रविष्टियों को नीचे गिना जाता है, फिर
लुइस मेंडो

1
@LuisMendo हाँ, बिल्कुल। लेकिन ध्यान दें कि हर कोशिका का जलने का समय 9 से अधिक हो सकता है, अगर यह "एकल संख्या" भाग के लिए मायने रखता है।
चार्ली

धन्यवाद। नहीं, इससे कोई फर्क नहीं पड़ता। मेरा मतलब था एक ही संख्या लेकिन संभवतः कई अंकों के साथ। नंबर से लेकर जाएगा 1करने के लिएM*N
लुइस Mendo

जवाबों:


12

मतलाब, 235 257 190 182 178 बाइट्स

इनपुट: मैट्रिक्स A, 1x2 वेक्टर pजिसमें शुरुआती निर्देशांक हैं।

function t=F(A,p)
[n,m]=size(A);x=2:n*m;x(mod(x,n)==1)=0;B=diag(x,1)+diag(n+1:n*m,n);k=sub2ind([n m],p(1),p(2));t=max(distances(digraph(bsxfun(@times,((B+B')~=0),A(:))'),k))+A(k)

स्पष्टीकरण:

आग के प्रसार का अनुकरण करने के बजाय, हम इसे "सबसे लंबे समय तक सबसे कम रास्ता खोजने" समस्या के रूप में भी समझ सकते हैं। मैट्रिक्स को एक भारित निर्देशित ग्राफ में परिवर्तित किया जाता है। एक नोड के लिए रास्तों का वजन समय के लिए कहा जाता है कि नोड को जलाने के लिए। एक मैट्रिक्स के लिए

5   7   7   10
5   2   2   10
4   5   2   6

हमें जुड़ा हुआ ग्राफ़ मिलता है:

ग्राफ

जहाँ नोड 1 ऊपरी बाएँ मैट्रिक्स तत्व और नोड 12 निचला दायाँ तत्व है। निर्देशांक शुरू करते हुए p, अन्य सभी नोड्स के लिए सबसे छोटा रास्ता गणना किया जाता है। फिर उन सबसे छोटे रास्तों के सबसे लंबे पथ की लंबाई + प्रारंभिक नोड को जलाने का समय पूरे मैट्रिक्स को जलाने के लिए समय के बराबर होता है।

नमूना शुरू करने वाले मूल्यों के साथ अनगुल्ड और टिप्पणी किया गया संस्करण:

% some starting point
p = [3 2];
% some random 5x6 starting map, integers between 1:10
A = randi(10,5,6); 

function t=F(A,p)
% dimensions of A
[n,m] = size(A);
% create adjacency matrix
x=2:n*m;
x(mod(x,n)==1)=0;
B = diag(x,1)+diag(n+1:n*m,n);
B = B+B';
B = bsxfun(@times,(B~=0),A(:))';
% make graph object with it
G = digraph(B);
% starting node
k = sub2ind([n m], p(1), p(2));
% calculate the shortest distance to all nodes from starting point
d = distances(G,k);
% the largest smallest distance will burn down last. Add burntime of initial point
t = max(d)+A(k);

1
PPCG में आपका स्वागत है!
स्टीफन

बहुत अच्छा दृष्टिकोण और बहुत अच्छी तरह से समझाया!
चार्ली

अरे, चूंकि यह मेरा पहला गोल्फ है, मुझे पूछना है कि क्या यह ठीक है कि मैं ;प्रत्येक पंक्ति के बाद छोड़ दिया । मतलाब में ये रोकते हैं कि प्रत्येक कमांड के परिणाम कंसोल में प्रदर्शित होते हैं। वर्तमान में यह कोड बहुत चटपटा है और सांत्वना देता है। लेकिन चूंकि यह एक सख्त विफलता नहीं है, इसलिए मैंने इसे इस तरह से रखा। लेकिन यह बहुत मायने नहीं रखता है, यह सिर्फ 4 बाइट्स है
लिएंडर मोइंसिंगर

1
@LeanderMoesinger क्या स्पैम आपके प्रोग्राम आउटपुट के समान आउटपुट क्षेत्र में जाता है? यदि स्पैम, उदाहरण के लिए, STDERR या समकक्ष में चला जाता है और आउटपुट STDOUT या समकक्ष में चला जाता है, तो आपको उन्हें हटा देना चाहिए। यदि वे दोनों एक ही स्थान पर उत्पादन करते हैं, तो मुझे नहीं पता होगा।
स्टीफन

@ यह एक अलग आउटपुट क्षेत्र है, लेकिन मैं सब कुछ एक लाइन डालकर इसे पूरी तरह से बचा सकता हूं। स्पष्टीकरण के लिए Thx!
लिएंडर मॉसिंजर

9

जावास्क्रिप्ट (ईएस 6), 156 152 146 144 143 बाइट्स

केविन क्रूज़सेन को 1 बाइट धन्यवाद दिया

बल्कि भोली कार्यान्वयन। करी सिंटैक्स में इनपुट लेता है (a)(s), जहां एक 2D- सरणी है और s दो पूर्णांकों की एक सरणी है [ x, y ] जो शुरुआती स्थिति के 0-आधारित निर्देशांक का प्रतिनिधित्व करता है।

a=>s=>(g=t=>(a=a.map((r,y)=>r.map((c,x)=>(z=(h,v)=>(a[y+~~v]||[])[x+h]<1)(-1)|z(1)|z(0,-1)|z(0,1)|x+','+y==s&&c?u=c-1:c),u=-1),~u?g(t+1):t))(0)

प्रारूपित और टिप्पणी की गई

a => s => (                                // given a and s
  g = t => (                               // g = recursive function with t = time counter
    a = a.map((r, y) =>                    // for each row r of the input array:
      r.map((c, x) =>                      //   for each cell c in this row:
        (                                  //     z = function that takes
          z = (h, v) =>                    //         2 signed offsets h and v and checks
            (a[y + ~~v] || [])[x + h] < 1  //         whether the corresponding cell is 0
        )(-1) | z(1) |                     //     test left/right neighbors
        z(0, -1) | z(0, 1) |               //     test top/bottom neighbors
        x + ',' + y == s                   //     test whether c is the starting cell
        && c ?                             //     if at least one test passes and c != 0:
          u = c - 1                        //       decrement the current cell / update u
        :                                  //     else:
          c                                //       let the current cell unchanged
      ),                                   //   end of r.map()
      u = -1                               //   start with u = -1
    ),                                     // end of a.map() --> assign result to a
    ~u ?                                   // if at least one cell was updated:
      g(t + 1)                             //   increment t and do a recursive call
    :                                      // else:
      t                                    //   stop recursion and return t
  )                                        // end of g() definition
)(0)                                       // initial call to g() with t = 0

परीक्षण के मामलों


==0<1अगर मैं गलत नहीं हूँ तो गोल्फ हो सकता है ।
केविन क्रूज़सेन

1
@ केविनक्रूजसेन यह वास्तव में सुरक्षित है क्योंकि यह मिथ्या undefined<1है। धन्यवाद!
अरनुलद

8

ऑक्टेव, 67 बाइट्स

function n=F(s,a)n=0;do++n;until~(s-=a|=imdilate(~s,~(z=-1:1)|~z')

इसे ऑनलाइन आज़माएं!

मध्यवर्ती परिणामों की कल्पना करने के लिए आप यह कोशिश कर सकते हैं !

एक फ़ंक्शन जो इलाके के इनपुट मैट्रिक्स के रूप में लेती है aऔर प्रारंभिक समन्वय 0 & 1 के मैट्रिक्स के रूप में इलाके के समान आकार के साथ होता है।

वास्तव में endfunctionहालांकि उदाहरण के लिए इसे चलाने की आवश्यकता नहीं होनी चाहिए क्योंकि इसे जोड़ा जाना चाहिए।

स्पष्टीकरण:

बार-बार इलाके पर रूपात्मक छवि फैलाव लागू करते हैं और इससे जले हुए क्षेत्रों को घटाते हैं।

असंबद्ध उत्तर:

function n = Fire(terrain,burned)
    n = 0;
    mask = [...
            0  1  0
            1  1  1
            0  1  0];
    while true
        n = n + 1;
        propagation = imdilate(~terrain, mask);
        burned = burned | propagation;
        terrain = terrain - burned;
        if all(terrain(:) == 0)
            break;
        end
    end
end

यह एक अच्छा जवाब है, लेकिन हो सकता है कि एल्गोरिथ्म प्रारंभिक अवस्था को एक कदम के रूप में गिना जा रहा है, और आपके उदाहरण में 10 के बजाय 11 वापस आ रहा है। अगर मैं प्रारंभिक सेल को [3 3] में बदल
चार्ली

@CarlosAlejo ओह, मेरा बुरा। उत्तर को अपडेट में बदल दिया n=1गया n=0
rahnema1

7

MATL , 26 25 बाइट्स

मैं वास्तव में यहाँ के आसपास की सबसे छोटी भाषाओं का उपयोग करके कुछ और उत्तर देखना चाहता था

`yy)qw(8My~1Y6Z+fhy0>z}@&

इनपुट प्रारूप है:

  • पहला इनपुट ;पंक्ति विभाजक के रूप में एक मैट्रिक्स है ।

  • दूसरा इनपुट एक एकल संख्या है जो 1-आधारित स्तंभ-प्रमुख क्रम में मैट्रिक्स की प्रविष्टि को संबोधित करता है (चुनौती द्वारा अनुमत)। उदाहरण के लिए, 3 × 4 मैट्रिक्स में प्रत्येक प्रविष्टि का कॉलम-प्रमुख समन्वय द्वारा दिया गया है

    1  4  7 10
    2  5  8 11
    3  6  9 12
    

    उदाहरण के लिए 1-आधारित निर्देशांक (2,2) के अनुरूप हैं 5

इसे ऑनलाइन आज़माएं! या सभी परीक्षण मामलों को सत्यापित करें

व्याख्या

कोड उन प्रविष्टियों की एक सूची रखता है जो जल रही हैं। प्रत्येक पुनरावृत्ति पर, उस सूची की सभी प्रविष्टियों को घटा दिया जाता है। जब कोई प्रविष्टि शून्य तक पहुँचती है, तो उसकी पड़ोसी प्रविष्टियाँ सूची में जुड़ जाती हैं। बाइट्स को बचाने के लिए, शून्य तक पहुंचने वाली प्रविष्टियों को सूची से नहीं हटाया जाता है; इसके बजाय, वे नकारात्मक मूल्यों के साथ "जलते" रहते हैं। प्रविष्टियों में से कोई भी सकारात्मक मान होने पर लूप बाहर निकल जाता है।

थोड़ा संशोधित कोड के साथ कदम से कदम मिलाकर कार्यक्रम देखें ।

टिप्पणी कोड:

`      % Do...while
  yy   %   Duplicate top two arrays (matrix and array of positions to be decremented)
       %   In the first iteration this implicitly takes the two inputs
  )    %   Reference indexing. This gives the values that need to be decremented
  q    %   Decrement
  w    %   Swap. This brings the array of positions that have been decremented to top
  (    %   Assignment indexing. This writes the decremented values back into their
       %   positions
  8M   %   Push array of positions again
  y    %   Duplicate decremented matrix
  ~    %   Negate. This replaces zeros by 1, and nonzeros by 0
  1Y6  %   Push predefined literal [0 1 0; 1 0 1; 0 1 0] (4-neighbourhood)
  Z+   %   2D convolution, maintaining size
  f    %   Find: gives column-major indices of neighbours of totally burnt entries
  h    %   Concatenate. This updates the array of positions to be decremented
  y    %   Duplicate decremented matrix
  0>   %   This gives 1 for positive entries, and 0 for the rest
  z    %   Number of nonzeros. This is the loop condition (*)
}      % Finally (execute before exiting loop)
  @    %   Push iteration number. This is the output
  &    %   Specify that the final implicit display function will display only the top
       %   of the stack
       % Implicit end. If the top of the stack (*) is not 0 (i.e. there are entries
       % that have not been totally burnt) the loop proceeds with the next iteration.
       % Else the "finally" branch is executed and the loop is exited
       % Implicit display (only top of the stack)

2
अब यही मैं एक छोटा कोड कहता हूँ! :-)
चार्ली


4

पायथन 3 , 277 266 बाइट्स

def f(m,s):
 p={s};w=len(m);t=0
 while sum(sum(m,[])):
  t+=1;i=0
  for x,y in p:
   try:m[x][y]=max(0,m[x][y]-1)
   except:0
  for v in sum(m,[]):
   if v<1:
    for l in[(1,0),(-1,0),(0,1),(0,-1)]:a,b=max(0,i%w+l[0]),max(0,i//w+l[1]);p.add((a,b))
   i+=1
 print(t)

इसे ऑनलाइन आज़माएं!

एक फ़ंक्शन को परिभाषित करता fहै जो 2 डी मैट्रिक्स और बिंदुओं का एक हिस्सा लेता है। पहली बात यह है समारोह करता है में पारित प्रारंभिक टपल मूल्य युक्त tuples का सेट निर्धारित है: p={s}। फ़ंक्शन तब बिंदुओं के प्रत्येक टपल के माध्यम से जाता है pऔर mउस बिंदु पर मैट्रिक्स से एक को घटाता है , जब तक कि मूल्य पहले से ही शून्य न हो। यह फिर से mमूल्य शून्य के साथ सभी बिंदुओं को खोजने और उस बिंदु के चार पड़ोसियों को सेट में जोड़ने के माध्यम से फिर से घूमता है p। यही कारण है कि मैंने एक सेट का उपयोग करने के लिए चुना, क्योंकि पायथन में सेट डुप्लिकेट मानों की अनुमति नहीं देते हैं (जो घटाव को बहुत अधिक बढ़ा देगा)। दुर्भाग्य से, लिस्ट इंडेक्स रैपिंग के कारण (जैसे list[-1] == list[len(list)-1]:) सूचकांकों को विवश होने की आवश्यकता है ताकि वे नकारात्मक न हों और गलत निर्देशांक जोड़ सकें p

कुछ खास नहीं, अभी भी गोल्फ खेलने की आदत है। निश्चित रूप से यहां सुधार के लिए जगह है, मैं इस पर दरार रखने जा रहा हूं।


क्या आप इसे ऑनलाइन आज़मा सकते हैं ताकि हम सभी आपके कोड का परीक्षण कर सकें?
चार्ली

@CarlosAlejo ने बेशक इसे पोस्ट में शामिल किया।
मूसोइनरॉक्स

4

APL (Dyalog) , 93 66 57 बाइट्स

{⍵{^/,0≥⍺:0⋄1+x∇⍵∨{∨/,⍵∧⍲/¨2|⍳3 3}⌺3 30=x←⍺-⍵}(⊂⍺)≡¨⍳⍴⍵}

इसे ऑनलाइन आज़माएं! या कल्पना यह ऑनलाइन!


यह फ़ंक्शन इलाके मैट्रिक्स को सही तर्क के रूप में लेता है और बाएं तर्क के रूप में पहली आग के निर्देशांक (1-आधारित)। सब कुछ जलाने के लिए आवश्यक मिनटों की संख्या लौटाता है।


अपडेट

अंत में फैल समारोह नीचे गोल्फ के लिए एक रास्ता मिल गया।
* आह * यह बहुत आसान होगा अगर दुनिया toroidal थी


TIO को अभी Dyalog 16.0 में अपग्रेड किया गया है , जिसका अर्थ है कि अब हमारे पास चमकदार नया स्टैंसिल ऑपरेटर है


बहुत अच्छा जवाब! मध्यवर्ती आउटपुट प्रगति की कल्पना करने में मदद करता है!
चार्ली

2

पायथन 2 , 268 बाइट्स

def f(m,y,x):t,m[y][x]=m[y][x],0;g(m,t)
def g(m,t):
	n,h,w=map(lambda r:r[:],m),len(m),len(m[0])
	for l in range(h*w):r,c=l/h,l%h;n[r][c]-=m[r][c]and not all(m[r][max(c-1,0):min(c+2,w+1)]+[m[max(r-1,0)][c],m[min(r+1,h-1)][c]])
	if sum(sum(m,[])):g(n,t+1)
	else:print t

इसे ऑनलाइन आज़माएं!

समय के साथ पुनरावृत्त पुनरावृति जिसमें प्रत्येक टाइल की संख्या कम हो जाती है यदि यह कार्डिनल रूप से एक 0. से सीधा होता है जो कि बहुत ही सरल एल्गोरिथ्म है, मेरा मानना ​​है कि अभी भी बूलियन दक्षता के लिए तैयार किया जा सकता है ...

* नोट: मेरी 'यह ऑनलाइन कोशिश करो!' कोड में पाद लेख में बोनस डिबग लॉगिंग शामिल है। मुझे एल्गोरिथ्म प्रगति देखना पसंद है।


2

हास्केल , 138 133 बाइट्स

u#g|all((<=0).snd)g=0|2>1=1+(u:[[(x+1,y),(x-1,y),(x,y-1),(x,y+1)]|((x,y),0)<-n]>>=id)#n where n=d<$>g;d p|elem(fst p)u=pred<$>p|2>1=p

इसे ऑनलाइन आज़माएं!

माना जाता है कि इनपुट ((x, y), सेल) की एक सूची है। Ungolfed:

type Pos = (Int, Int)

ungolfed :: [Pos] -> [(Pos, Int)] -> Int
ungolfed burning grid
  | all ((<=0).snd) grid = 0 
  | otherwise = 1 + ungolfed (burning ++ newburning) newgrid
 where
  newgrid = map burn grid
  burn (pos,cell) | pos `elem` burning = (pos, cell - 1)
                  | otherwise = (pos, cell)
  newburning = do
    ((x,y),cell) <- newgrid
    guard (cell <= 0)
    [(x+1,y),(x-1,y),(x,y-1),(x,y+1)]
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.