सरकार के पास दीवारों की सीमित आपूर्ति है


28

परिचय

ज्ञानी कोड गोल्फरों ने हमें प्रलयकाल की बाढ़ के लिए तैयार किया । जोखिम वाले क्षेत्रों को खाली कर दिया गया, और आबादी उच्च भूमि पर चली गई।

हमने बाढ़ को कम करके आंका (या शायद @ user12345 के कोड में एक बग था)। कुछ उच्च-भू-क्षेत्र तेजी से समुद्र के स्तर के करीब पहुंच रहे हैं। अब घनी आबादी के अस्तित्व को सुनिश्चित करने के लिए दीवारों को खड़ा किया जाना चाहिए। अफसोस की बात है कि सरकार के पास दीवारों की सीमित आपूर्ति है।

संकट

हमारे प्रलय का दिन एक ही पंक्ति में दो संख्याओं द्वारा वर्णित है, nऔर m। उस पंक्ति का अनुसरण प्रति पंक्ति मानों के nसाथ की जाने वाली लाइनें हैं m, जो केवल एक स्थान से अलग होती हैं। प्रत्येक मान चार वर्णों में से एक होगा।

  • xअगम्य। यहां पानी नहीं बह सकता। यहां दीवारें नहीं खड़ी की जा सकतीं।
  • -अस्थिर। यहां से पानी बह सकता है। यहां दीवारें नहीं खड़ी की जा सकतीं।
  • .स्थिर। यहां से पानी बह सकता है। यहां दीवारें खड़ी की जा सकती हैं।
  • oपड़ाव। यहां से पानी बह सकता है। अगर ऐसा होता है, तो हर कोई मर जाता है। यहां दीवारें नहीं बनाई जा सकतीं।

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

उदाहरण इनपुट

 6 7
 x . . x x x x
 x . . x - - x
 x . x x - - x
 x . o o o - .
 x . o o o - .
 x x x x x x x

उदाहरण आउटपुट

3

मान्यताओं

  • पानी केवल सजावटी रूप से बहता है
  • परिहवन केवल एक orthonagonally contiguous block per परिदृश्य के रूप में मौजूद हैं
  • एक समाधान हमेशा मौजूद रहेगा (हालाँकि इसमें दीवारों की प्रचुर मात्रा की आवश्यकता हो सकती है)
  • एग्ज़ेबिशन एक किनारे पर स्थित नहीं हो सकते हैं, क्योंकि तब परिदृश्य का कोई हल नहीं होगा
  • 2 << n16
  • 2 << m16
  • स्टड से इनपुट प्रदान किया जा सकता है, "city.txt" से पढ़ा जा सकता है, या एकल तर्क के रूप में स्वीकार किया जा सकता है

सबसे छोटा कोड जीतता है!


2
क्या यह कार्यक्रम के सही होने के लिए स्वीकार्य होगा, फिर भी ज्ञात ब्रह्मांड से अधिक समय तक मौजूद रहने से समस्या के कुछ उदाहरणों का समाधान मिल जाएगा?
1936 में क्लाउडी

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

2
कोड गोल्फ आमतौर पर समय प्रतिबंध की आवश्यकता नहीं है।
होशो

ठंडा! एक और प्रश्न: इनपुट आपके द्वारा निर्दिष्ट किए जाने के लिए आवश्यक है या हम इसे दूसरे रूप में रख सकते हैं?
क्लाउडीयू

@ कलौइदू मैं आवश्यकताओं के बाहर कुछ भी स्वीकार नहीं कर सकता। हालाँकि, आप संपादन बटन का उपयोग करके आवश्यकताओं को संपादित करने का सुझाव दे सकते हैं । यह देखते हुए कि अभी तक कोई जवाब नहीं आया है, मैं शायद संपादन को तुरंत स्वीकार करूंगा।
रेनबोल्ट

जवाबों:


10

गणितज्ञ, 257 253 वर्ण

d="city.txt"~Import~"Table";g=EdgeAdd[#,∞<->Tr@#&/@Position[VertexDegree@#,2|3]]&@GridGraph@d[[1,{2,1}]];{o,x,s}=Tr/@Position[Join@@d[[2;;]],#]&/@{"o","x","."};Catch@Do[If[Min[GraphDistance[VertexDelete[g,x⋃w],∞,#]&/@o]==∞,Throw@Length@w],{w,Subsets@s}]

से इनपुट पढ़ा जाता है "city.txt"

स्पष्टीकरण:

रेखांकन से निपटने के लिए गणितज्ञ के कई कार्य हैं।

सबसे पहले, मैं से डेटा को पढ़ता हूं "city.txt"

d="city.txt"~Import~"Table";

फिर मैं 'm' * 'n' कोने ( ) के साथ एक ग्रिड ग्राफ का निर्माण करता हूं GridGraph@d[[1,{2,1}]], और इसे "अनंत पर एक शीर्ष" में जोड़ता हूं , जो ग्राफ के "किनारों" पर प्रत्येक शीर्ष से जुड़ा होता है। यह शीर्ष वह स्थान है जहाँ से पानी का प्रवाह होता है।

g=EdgeAdd[#,∞<->Tr@#&/@Position[VertexDegree@#,2|3]]&@GridGraph@d[[1,{2,1}]];

और o, xऔर s"ओ", "एक्स" और "" के पदों को निरूपित करते हैं। क्रमशः।

{o,x,s}=Tr/@Position[Join@@d[[2;;]],#]&/@{"o","x","."};

फिर किसी भी सबसेट wके लिए s(सबसेट को लंबाई से क्रमबद्ध किया जाता है), मैं अंदर xऔर wबाहर g( VertexDelete[g,x⋃w]) से चक्कर हटाता हूं , और "वर्टेक्स एट इनफिनिटी" से सबसे छोटे रास्ते की लंबाई का पता लगाता हूं o। यदि लंबाई अनंत है, तो अतिक्रमण सुरक्षित होगा। तो पहले की लंबाई इस तरह wकी दीवारों की एक न्यूनतम संख्या है जो एक अतिक्रमण से बचाने के लिए आवश्यक है।

Catch@Do[If[Min[GraphDistance[VertexDelete[g,x⋃w],∞,#]&/@o]==∞,Throw@Length@w],{w,Subsets@s}]

अच्छा! मुझे लगा कि मैं एक अलग भाषा में एक अलग दृष्टिकोण द्वारा स्कूप किया जाएगा।
Claudiu

1
यदि आप हम में से बाकी लोगों के लिए अपने कोड की व्याख्या करेंगे तो मैं और अधिक गर्व से करूंगा।
माइकल स्टर्न

क्या कोई यह प्रतिज्ञा कर सकता है कि यह उत्तर सही है या "गणितज्ञ" के लिए एक ऑनलाइन इंट्रिप्टर प्रदान करेगा? एक खोजने में परेशानी होना।
रेनबोल्ड

1
@Rusher मैंने इसे सत्यापित किया है, और यह ठोस है। MM के लिए कोई ऑनलाइन दुभाषिया नहीं है, लेकिन एक डाउनलोड करने योग्य CDF दस्तावेज़ प्रारूप है जिसे मैंने और कुछ अन्य लोगों ने समाधान साझा करने के लिए प्रयोग करना शुरू कर दिया है। आप रास्पबेरी पाई एआरएम कंप्यूटर के साथ मुफ्त में मैथेमेटिका भी प्राप्त कर सकते हैं, जो कि बॉक्स की कंप्यूटिंग शक्ति द्वारा सीमित है। एफडब्ल्यूआईडब्ल्यू, हम एमएम उपयोगकर्ता एक-दूसरे को ईमानदार रखने की पूरी कोशिश करते हैं और हम अपने सबमिशन को और अधिक सुगम बनाने पर काम कर रहे हैं (एक समस्या जिसका सामना मैटलैब, मैपल, एमएस भाषाओं ने किया है जो मोनो पर काम नहीं करते हैं, आदि)
जोनाथन वान मट्रे

4

सी, 827 799 522

golfed:

#define N for(
#define F(W,X,Y,Z) N i= W;i X Y;i Z)
#define C(A,B,C) if(c[A][B]==C)
#define S(W,X,Y,Z,A,B) p=1;F(W,X,Y,Z)C(A,B,120)p=0;if(p){F(W,X,Y,Z){C(A,B,46){c[A][B]='x';z++;Q();break;}}}else{F(W,X,Y,Z){C(A,B,120)break;else c[A][B]='o';}}
p,m,z,w,h,o,i,u,l,x,y;char c[16][16];Q(){N u=0;u<h;u++)N l=0;l<w;l++)if(c[u][l]=='o'){x=u;y=l;S(x,>,m,--,i,y)S(y,>,m,--,x,i)S(y,<,w,++,x,i)S(x,<,h,++,i,y)}}main(int a, char **v){h=atoi(v[1]);w=atoi(v[2]);N m=-1;o<h;o++)N i=0;i<w;i++)scanf("%c",&c[o][i]);Q();printf("%d",z);}

इनपुट को ऊंचाई के साथ और कमांड लाइन के तर्कों के साथ दिया जाता है, और फिर ग्रिड को स्टड पर एकल स्ट्रिंग के रूप में पढ़ा जाता है जैसे: ./a.out 6 7 < inputजहां इनपुट इस रूप में है (बाएं से दाएं, ऊपर से नीचे):

x..xxxxx..x - xx.xx - xx.ooo-.x.ooo-.xxxxxxx

"पठनीय":

#define F(W,X,Y,Z) for(i= W;i X Y;i Z)
#define C(A,B,C) if(c[A][B]==C)
#define S(W,X,Y,Z,A,B) p=1;F(W,X,Y,Z)C(A,B,120)p=0;if(p){F(W,X,Y,Z){C(A,B,46){c[A][B]='x';z++;Q();break;}}}else{F(W,X,Y,Z){C(A,B,120)break;else c[A][B]='o';}}

/*Example of an expanded "S" macro:
p=1;
for(i=x;i>m;i--) if(c[i][y]==120) p=0;
if(p)
{
    for(i=x;i>m;i--)
    {
        if(c[i][y]==46)
        {
            c[i][y]='x';
            z++;
            Q();
            break;
        }
    }
}
else
{
    for(i= x;i > m;i --)
    {
        if(c[i][y]==120) break;
        else c[i][y]='o';
    }
}
*/

p,m,z,w,h,o,i,u,l,x,y;
char c[16][16];
Q(){
    for(u=0;u<h;u++)
        for(l=0;l<w;l++)
            if(c[u][l]=='o')
            {
        x=u;y=l;
        S(x,>,m,--,i,y)
        S(y,>,m,--,x,i)
        S(y,<,w,++,x,i)
        S(x,<,h,++,i,y)
            }
}

main(int a, char **v)
{
    h=atoi(v[1]);
    w=atoi(v[2]);
    for(m=-1;o<h;o++)
        for(i=0;i<w;i++)
            scanf("%c",&c[o][i]);
    P();
    Q();
    printf("%d\n",z);
    P();
}

//Omitted in golfed version, prints the map.
P()
{
    for(o=0;o<h;o++)
    {
        for (i=0;i<w;i++) printf("%c",c[o][i]);
        printf("\n");
    }   
}

@Claudiu द्वारा समाधान के रूप में कहीं भी कम नहीं है, लेकिन यह धधकते हुए तेजी से चलता है। किनारों से बाढ़ भरने के बजाय, यह अतिक्रमण पाता है और 'ओ' टोकन से बाहर की ओर काम करता है।

  • यदि यह अतिक्रमण के बगल में किसी अस्थिर जमीन का सामना करता है, तो यह उस पर अतिक्रमण का विस्तार करता है।
  • यदि ग्रिड पर किसी भी अतिक्रमण में प्रत्येक दिशा में कम से कम एक दीवार नहीं है, तो यह उस दिशा में आगे बढ़ता है जब तक कि यह एक दीवार का निर्माण नहीं कर सकता।
  • प्रत्येक नए वॉल सेक्शन को रखे जाने के बाद, यह अगले वॉल सेक्शन को खोजने के लिए रिकर करता है।

नमूना दीवार प्लेसमेंट:

x..xxxx                           x..xxxx
x..x--x                           x..xoox
x.xx--x                           x3xxoox
x.ooo-.  <-- results in this -->  xooooo1
x.ooo-.                           xooooo2
xxxxxxx                           xxxxxxx

ओह दिलचस्प दृष्टिकोण! क्या यह हमेशा सबसे छोटा जवाब देता है? उदाहरण के लिए यह इस नक्शे के लिए क्या जवाब देता है ? यह 3 होना चाहिए (जहां नई दीवारें जाती हैं चिह्नित @)। मैंने आपका कोड स्वयं चलाने की कोशिश की, लेकिन यह काम नहीं
क्लाउडी

उफ़, लगता है कि गोल्फिंग और अल्कोहल बहुत अच्छी तरह से मिश्रित नहीं होते हैं ... मैं कुछ अपरिभाषित व्यवहार में गोल्फ खेलता हूं। अब 277 अनावश्यक पात्रों के साथ तय किया जाना चाहिए ।
कोमिन्टर्न

2
@ कोलियु - मेरी टिप्पणी ऊपर देखें, आपके द्वारा पोस्ट किए गए नक्शे के परिणाम pastebin.com/r9fv7tC5 पर हैं । यह हमेशा सबसे छोटा जवाब देना चाहिए , लेकिन मैंने केवल 10 या 15 मानचित्रों के साथ इसका परीक्षण किया है जो मुझे लगा कि कोने के मामले पेश कर सकते हैं। मैं यह देखने के लिए उत्सुक हूं कि क्या कोई ऐसे मानचित्रों की पहचान कर सकता है जो इसके लिए विफल हैं।
कॉमिनर्ट

4

पायथन, 553 525 512 449 414 404 387 368 अक्षर (+4? मंगलाचरण के लिए)?

मैं रास्ता बहुत ज्यादा मज़ा यह गोल्फ था। यदि आप इसे संपीड़ित करने का प्रयास करते हैं तो यह 82 बाइट्स बड़ा है! अब यह कॉम्पैक्टनेस और पुनरावृत्ति की कमी का एक उपाय है।

R=range;import itertools as I
f=map(str.split,open('city.txt'))[1:]
S=[]
def D(q):
 q=set(q)
 def C(*a):
    r,c=a
    try:p=(f[r][c],'x')[a in q]
    except:p='x'
    q.add(a)
    if'.'==p:S[:0]=[a]
    return p<'/'and C(r+1,c)|C(r-1,c)|C(r,c+1)|C(r,c-1)or'o'==p
 if sum(C(j,0)|C(j,-1)|C(0,j)|C(-1,j)for j in R(16))<1:print n;B
D(S);Z=S[:]
for n in R(len(Z)):map(D,I.combinations(Z,n))

संकेत स्तर अंतरिक्ष, टैब हैं।

उपयोग :

से पढ़ता है city.txt:

6 7
x . . x x x x
x . . x - - x
x . x x - - x
x . o o o - .
x . o o o - .
x x x x x x x

निम्नानुसार आह्वान करें:

$ python floodfill_golf.py 2>X
3

2>Xएक अपवाद को ऊपर उठाने के द्वारा कार्यक्रम बाहर निकलता है के बाद से stderr को छिपाने के लिए है। यदि यह अनुचित लगता है तो मंगलाचरण के लिए 4 वर्ण जोड़ने के लिए स्वतंत्र हैं।

स्पष्टीकरण :

सरल पाशविक बल। Cअगर बाढ़ आती है और अगर यह एक अतिक्रमण से टकराता है तो यह सच है। कोई अतिरिक्त पैडिंग नहीं है क्योंकि पैडिंग को ठीक से सेट करने के लिए बहुत अधिक जगह ली गई थी। Dको भरने के लिए दीवारों का एक सेट दिया Cगया है, किनारे पर हर बिंदु से कॉल करता है जैसे कि Cउन दीवारों के लिए खाता है, और लंबाई को प्रिंट करता है और बाहर निकलता है अगर उनमें से कोई भी अतिक्रमण तक नहीं पहुंचा। बाढ़-भराव पर नज़र रखने के लिए दीवारों की सूची का भी उपयोग किया जाता है, इसलिए बोर्ड की नकल की आवश्यकता नहीं है! मुश्किल से, Cयह किसी भी खाली स्थानों को भी सूची में रखता है, Sइसलिए फ़ंक्शन Dका उपयोग पहले खाली स्थानों की सूची बनाने के लिए भी किया जाता है। इस कारण से, मैं sumइसके बजाय का उपयोग करता हूं any, यह सुनिश्चित करने के लिए कि सभी .एस पहले रन-थ्रू पर एकत्र किए गए हैं।

मैं Dएक बार आह्वान करता हूं , फिर खाली स्थानों की सूची की प्रतिलिपि बनाता हूं , Zक्योंकि S(अयोग्य, लेकिन चरित्र गणना पर सस्ता) के लिए संलग्न किया जाएगा। फिर मैं itertools.combinations0 स्थानों से खाली स्थानों के प्रत्येक कॉम्बो का चयन करने के लिए उपयोग करता हूं । मैं प्रत्येक कॉम्बो के माध्यम से चलाता हूं Dऔर यह पहले वाले की लंबाई को प्रिंट करता है जो काम करता है, कार्यक्रम से बाहर निकलने के लिए एक अपवाद को बढ़ाता है। अगर कोई जवाब नहीं मिला तो कुछ भी नहीं छपा।

ध्यान दें कि वर्तमान में, यदि कोई दीवारों की आवश्यकता नहीं है, तो प्रोग्राम काम नहीं करता है। इस मामले की देखभाल करने के लिए +3 वर्ण होंगे; यकीन नहीं है कि यह आवश्यक है।

यह भी ध्यान दें कि यह एक O(2^n)एल्गोरिथ्म है, जहां nखाली स्थानों की संख्या है। तो, बीच में एक अतिक्रमण के साथ 15x15 पूरी तरह से खाली बोर्ड के लिए, यह पूरा करने के लिए 2^(15*15-1)= 2.6959947e+67पुनरावृत्तियों को ले जाएगा , जो वास्तव में बहुत लंबा समय होने जा रहा है!


1

ग्रूवी: 841 805 754

i=new File("city.txt").getText()
x=i[2] as int
y=i[0] as int
m=i[4..i.length()-1].replaceAll('\n','').toList()
print r(m,0)
def r(m,n){if(f(m))return n;c=2e9;g(m).each{p=r(it,n+1);if(p<c)c=p;};return c;}
def f(m){u=[];u.addAll(m);for(i in 0..(x*y)){for(l in 0..m.size()-1){n(l,u);s(l,u);e(l,u);w(l,u);}};m.count('o')==u.count('o')}
def n(i,m){q=i-x;if((((q>=0)&(m[q]=='!'))|(q<0))&m[i]!='x'&m[i]!='W'){m[i]='!'}}
def s(i,m){q=i+x;if((((q>=0)&(m[q]=='!'))|(q<0))&m[i]!='x'&m[i]!='W'){m[i]='!'}}
def e(i,m){q=i+1;if((((q%x!=0)&(m[q]=='!'))|(q%x==0))&m[i]!='x'&m[i]!='W'){m[i]='!'}}
def w(i,m){q=i-1;if((((i%x!=0)&(m[q]=='!'))|(i%x==0))&m[i]!='x'&m[i]!='W'){m[i]='!'}}
def g(m){v=[];m.eachWithIndex{t,i->if(t=='.'){n=[];n.addAll(m);n[i]='W';v<<n}};return v}

Ungolfed:

def i = new File("city.txt").getText()
x=i[2].toInteger()
y=i[0].toInteger()
def m=i[4..i.length()-1].replaceAll('\n','').toList()
println r(m, 0)

def r(m, n){
    if(f(m)) return n
    def c = Integer.MAX_VALUE

    getAllMoves(m).each{ it -> 
        def r = r(it, n+1)
        if(r < c) c = r
    }
    return c;
}

def f(m){
    def t = []
    t.addAll(m)
    for(i in 0..(x*y)){
        for(l in 0..m.size()-1){
            n(l,t);s(l,t);e(l,t);w(l,t);
        }
    }
    m.count('o')==t.count('o')
}

def n(i,m){
    def t = i-x;
    if( ( ( (t >= 0) && (m[t]=='!') ) || (t < 0)) && m[i]!='x' && m[i]!='W'){
        m[i]='!'
    }
}

def s(i,m){
    def t = i+x;
    if( ( ( (t >= 0) && (m[t]=='!') ) || (t < 0)) && m[i]!='x' && m[i]!='W'){
        m[i]='!'
    }
}

def e(i,m){
    def t = i+1;
    if( ( ( (t%x!=0) && (m[t]=='!') ) || (t%x==0)) && m[i]!='x' && m[i]!='W'){
        m[i]='!'
    } 
}

def w(i,m){
    def t = i-1;
    if( ( ( (i%x!=0) && (m[t]=='!') ) || (i%x==0)) && m[i]!='x' && m[i]!='W'){
        m[i]='!'
    }
}

def getAllMoves(m){
    def moves = []
    m.eachWithIndex { t, i ->
        if(t=='.'){
            def newList = []
            newList.addAll(m)
            newList[i]='W'
            moves << newList
        }
    }
    return moves
}

आने के लिए और अधिक गोल्फ ...

2 ई 9 रिटर्न अगर कोई समाधान नहीं।


0

डायलॉग एपीएल , 91 बाइट्स

⊃∊{1∊a[⍸×{(×d)∧s 3∨/3∨⌿⍵}⍣≡4=d←0@⍵⊢a]:⍬⋄≢⍵}¨c[⍋≢¨c←(,⍳2⊣¨b)/¨⊂b←⍸2=a←(s←(4,4,⍨⍉)⍣2)'xo.'⍳⎕]

मानता है ⎕IO=0, v16.0 ( @और ) से सुविधाओं का उपयोग करता है , चल रहा समय .-s की संख्या में घातीय है

मूल्यांकन किया गया इनपुट है, वर्णों का एक मैट्रिक्स होना चाहिए

'xo.'⍳x0 के oसाथ 1 के साथ बदलें , .2 के साथ, और 3 के साथ अन्य सभी

s←(4,4,⍨⍉)⍣2 एक फ़ंक्शन जो 4 जी के साथ एक मैट्रिक्स को घेरता है

a← 4 जी के साथ घिरे संख्यात्मक मैट्रिक्स को एक चर में असाइन करें a

b←⍸2= bसमन्वित जोड़ों की सूची है जहां 2s (यानी .-s) हैं

(,⍳2⊣¨b)/¨⊂b के तत्वों के सभी संयोजन उत्पन्न करते हैं b

c[⍋≢¨c←...] उन्हें आकार के अनुसार क्रमबद्ध करें

{... :⍬⋄≢⍵}¨ प्रत्येक संयोजन के लिए, किसी चीज़ की जाँच करें और उसकी लंबाई या खाली सूची पर वापस जाएँ

⊃∊ पहला गैर-रिक्त परिणाम

d←0@⍵⊢a dहै a0 के साथ प्रतिस्थापित कुछ तत्वों के साथ

4= बूलियन मैट्रिक्स बनाएं - जहां 4 जी हैं? यानी हमने जो सीमा जोड़ी है

{...}⍣≡{}परिणाम स्थिर होने तक फ़ंक्शन को लागू करते रहें

3∨/3∨⌿⍵ "बुलियन या" प्रत्येक तत्व अपने पड़ोसियों के साथ

s परिणाम छोटा होगा, तो चलिए फिर से बॉर्डर बनाते हैं

(×d)∧dबूलियन मास्क के रूप में (गैर-दीवारों) के गैर-शून्य तत्वों को लागू करें

a[⍸× ...]aहमारे बूलियन मैट्रिक्स में 1s के अनुरूप क्या है ?

1∊ क्या कोई 1s हैं, अर्थात o, अतिक्रमण?

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