वर्णिक पहेली को हल करें


35

Puzzling.SE में हमारे दोस्तों पर , निम्नलिखित पहेली पोस्ट की गई थी: क्या यह रंगीन पहेली हमेशा हल है? एडगर जी। द्वारा आप इसे यहाँ खेल सकते हैं

पहेली की व्याख्या

m x nतीन अलग-अलग रंगों की टाइलों के साथ एक ग्रिड को देखते हुए , आप किसी भी दो आसन्न टाइल्स का चयन कर सकते हैं , अगर उनके रंग अलग - अलग हों । फिर इन दो टाइलों को तीसरे रंग में बदल दिया जाता है, अर्थात, इन दो टाइलों द्वारा प्रतिनिधित्व नहीं किया जाने वाला एक रंग। यदि सभी टाइलों का रंग समान है, तो पहेली हल हो गई है । जाहिर है, कोई यह साबित कर सकता है कि यह पहेली हमेशा हल करने योग्य है, अगर 3 से न तो विभाज्य है mऔर न ही n

8x8 तीन रंग पहेली

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

इनपुट आउटपुट

इनपुट एक हो जाएगा m x nपूर्णांकों से मिलकर मैट्रिक्स 1, 2और 3(या 0, 1, 2यदि सुविधाजनक)। आप इस इनपुट को किसी भी स्वरूप में ले सकते हैं। दोनों mऔर 3 से विभाज्य नहीं nहैं >1। आप मान सकते हैं कि पहेली हल नहीं हुई है

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

आपका एल्गोरिथ्म मूल 8x8 मामले पर उचित समय के भीतर चलना चाहिए। ब्रूट-फोर्सिंग इसे पूरी तरह से अस्वीकार कर दिया गया है, अर्थात आपके एल्गोरिथ्म को समाधान के लिए आवश्यक चरणों की संख्या के O(k^[m*(n-1)+(m-1)*n])साथ चलना चाहिए k। हालांकि समाधान को इष्टतम होने की आवश्यकता नहीं है। लिंक किए गए प्रश्न में दिए गए प्रमाण से आपको यह अंदाजा हो सकता है कि यह कैसे करना है (उदाहरण के लिए, पहले सभी स्तंभ केवल लंबवत आसन्न टाइल्स का उपयोग करें, और फिर सभी पंक्तियों को करें)

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

इन परीक्षण मामलों में, निर्देशांक 1-आधारित होते हैं और पंक्तियों को पहले अनुक्रमित किया जाता है (जैसे MATLAB / ऑक्टेव और शायद कई अन्य)।

Input: 
[1 2]
Output: (result: all 3's)
[1 1],[1,2]


Input:
[ 1 2
  3 1 ]
Output: (result: all 1's)
[1 1],[2 1]        (turn left column into 2's)
[2 1],[2 2]        (turn right column into 3's)
[1 1],[1 2]        (turn top row into 1's)
[2 1],[2 2]        (turn bottom row into 1's)

Input:
[1 2 3 2
 3 2 1 1]

Output: (result: all 3's)
[1 1],[1 2] 
[1 3],[1 4] 
[1 2],[1 3] 
[1 1],[1 2] 
[1 2],[1 3] 
[1 1],[1 2]
[1 3],[1 4]
[2 1],[2 2]
[1 1],[2 1]
[1 2],[2 2]
[1 3],[2 3]
[1 4],[2 4]

यदि वांछित है, तो मैं बड़े परीक्षण मामलों के एक पेस्टबिन को पोस्ट कर सकता हूं, लेकिन मुझे लगता है कि यह पर्याप्त होना चाहिए।


मैं इसका एक कोड चैलेंज संस्करण देखना पसंद करूंगा, जहां लक्ष्य कम से कम कुल चालों के साथ पहेलियों को हल करना है।
मेगो

@ मैं यह निश्चित रूप से माना जाता है। हालाँकि, मुझे डर है कि यह एक डीएफएस या बीएफएस में बदल जाएगा जो हमेशा के लिए चलेगा; या, इसे रोकने के लिए, अस्पष्ट प्रतिबंधों का एक सेट (जैसे 'एक घंटे के भीतर चलना चाहिए' जो कि बड़े पैमाने पर कंप्यूटर वाले लोगों का पक्षधर है, या जिसे मुझे सभी समाधानों का परीक्षण करने की आवश्यकता होगी)। और इसके अलावा, वर्तमान चुनौती के पास शून्य जवाब स्पेयर माइन है, इसलिए मुझे संदेह है कि एक और भी कठिन संस्करण जिसमें हेरास्टिक्स आदि की आवश्यकता होती है, वह अधिक लोकप्रिय साबित होगा ... लेकिन शायद अगर यह चुनौती गति पकड़ लेती है तो मैं आप की तरह एक बड़ी चुनौती पोस्ट कर सकता हूं वर्णन करते हैं।
सैन जूस

मुझे लगता है कि मैं
लूआ

@Katenkyo यह पता लगाने का केवल एक तरीका है! मैं आपके समाधान को देखने के लिए उत्सुक हूं।
सैन जूस

आपको थोड़ा दुखी होकर इंतजार करना होगा, आपने जानवर बल समाधान को रोक दिया, इसलिए मुझे एक ऐसा उपाय खोजना होगा जो
लू

जवाबों:


5

रूबी, 266 बाइट्स

ऑक्टेव समाधान का सिर्फ एक बंदरगाह अधिक-या-कम, इसके अलावा यह स्तंभों के बजाय पहले पंक्तियों को हल करता है। इनपुट सरणियों की एक सरणी है, जिसमें आंतरिक सरणियों की पंक्तियां होती हैं। आउटपुट मूव हैं [row, column, row, column]परीक्षण सूट

->m{t=->v{v.size*v.inject(:+)%3}
s=->a,x,r{g=t[a]
(q=(r=0..a.size-2).find{|i|a[i]!=a[i+1]&&g!=a[i]}||r.find{|i|a[i]!=a[i+1]}
a[q,2]=[t[a[q,2]]]*2
p r ?[x,q,x,q+1]:[q,x,q+1,x])while[]!=a-[g]}
m.size.times{|i|s[m[i],i,1]}
m=m.shift.zip *m
m.size.times{|i|s[m[i],i,p]}}

विवेचना के साथ अपुष्ट

->m{                                  # Start lambda function, argument `m`
  t=->v{v.size*v.inject(:+)%3}        # Target color function
  s=->a,x,r{                          # Function to determine proper moves
                                      #   a = row array, x = row index, r = horizontal
    g=t[a]                            # Obtain target color
    (
      q=(r=0..a.size-2).find{|i|      # Find the first index `i` from 0 to a.size-2 where...
        a[i]!=a[i+1]                  # ...that element at `i` is different from the next...
        &&g!=a[i]                     # ...and it is not the same as the target color
      } || r.find{|i|a[i]!=a[i+1]}    # If none found just find for different colors
      a[q,2]=[t[a[q,2]]]*2            # Do the color flipping operation
      p r ?[x,q,x,q+1]:[q,x,q+1,x]    # Print the next move based on if `r` is truthy
    ) while[]!=a-[g]}                 # While row is not all the same target color, repeat
m.size.times{|i|                      # For each index `i` within the matrix's rows...
  s[m[i],i,1]                         # ...run the solving function on that row
                                      #   (`r` is truthy so the moves printed are for rows)
}
m=m.shift.zip *m                      # Dark magic to transpose the matrix
m.size.times{|i|s[m[i],i,p]}}         # Run the solving function on all the columns now
                                      #   (`r` is falsy so the moves printed are for columns)

यह देखना दिलचस्प है कि दो गैर-गोल्फ भाषाओं के बीच एक बंदरगाह अभी भी ~ 20% का अंतर कर सकता है। क्या आप शायद एक छोटी व्याख्या जोड़ सकते हैं? (विशेष रूप से पंक्ति 3 - मैं चुपके से उम्मीद कर रहा हूं कि मैं अपने जवाब में इसका उपयोग कर सकता हूं क्योंकि intersectइस तरह के भारी कीवर्ड हैं)
Sanchises

@sanchises एक स्पष्टीकरण जोड़ा गया था। के बारे में intersect, मुझे नहीं पता कि आप यह तय कर सकते हैं कि मेरा काम करने का तरीका क्या है क्योंकि रूबी findमूल रूप से फ़ंक्शंस पर काम करती है, और आपका functionकीवर्ड बिलकुल काम का है।
मूल्य इंक

मैं वास्तव में अभी भी आपकी विधि का उपयोग कर सकता था find- धन्यवाद! फिर भी, कहीं भी आप की पिटाई नहीं हो सकती ...
Sanchises

13

ऑक्टेव, 334 313 बाइट्स

चूंकि चुनौती थोड़ी कठिन लग सकती है, इसलिए मैं अपना समाधान प्रस्तुत करता हूं। मैंने औपचारिक रूप से साबित नहीं किया कि यह विधि काम करती है (मुझे लगता है कि यह साबित करने के लिए नीचे आ जाएगा कि एल्गोरिथ्म कभी भी लूप में फंस नहीं जाएगा), लेकिन अभी तक यह पूरी तरह से काम करता है, 15 सेकंड के भीतर 100x100 टेस्टकेस करता है। ध्यान दें कि मैंने एक फ़ंक्शन का उपयोग करने के लिए एक के बजाय साइड इफेक्ट्स का उपयोग किया है जो सभी निर्देशांक लौटाता है क्योंकि मुझे कुछ बाइट्स से बचाया गया है। निर्देशांक पंक्ति-प्रमुख, 1-आधारित और स्वरूपित हैं row1 col1 row2 col2। इनपुट रंगों के 0,1,2बाद से यह बेहतर काम कर रहा है mod, numelबल्कि उपयोग करने की कीमत पर nnz। गोल्फ संस्करण: संपादित करें: केविन लाउ के जवाब से एक तकनीक का उपयोग करके एक और कुछ बाइट्स को बचाया।

function P(p)
k=0;[m,n]=size(p);t=@(v)mod(sum(v)*numel(v),3);for c=1:n
p(:,c)=V(p(:,c));end
k=1;for r=1:m
p(r,:)=V(p(r,:));end
function a=V(a)
while any(a-(g=t(a)))
isempty(q=find(diff(a)&a(1:end-1)-g,1))&&(q=find(diff(a),1));
a([q q+1])=t(a([q q+1]));if k
disp([r q r q+1])
else
disp([q c q+1 c])
end;end;end;end

समाधान एल्गोरिथ्म का उदाहरण GIF:

यहाँ छवि विवरण दर्ज करें

Ungolfed संस्करण:

function solveChromaticPuzzle(p)
[m,n]=size(p);                           % Get size
t=@(v)mod(sum(v)*numel(v),3);            % Target colour function
for c=1:n                                % Loop over columns
    p(:,c)=solveVec(p(:,c));             % Solve vector
end
for r=1:m                                % Loop over rows
    p(r,:)=solveVec(p(r,:));
end
    function a=solveVec(a)               % Nested function to get globals
        g=t(a);                          % Determine target colour
        while(any(a~=g))                 % While any is diff from target...
            % Do the finding magic. Working left-to-right, we find the
            % first pair that can be flipped (nonzero diff) that does not
            % have the left colour different from our goal colour
            q=min(intersect(find(diff(a)),find(a~=g)));
            if(isempty(q))               % In case we get stuck...
                q=find(diff(a),1);       % ... just flip the first possible
            end;
            a([q q+1])=t(a([q q+1]));    % Do the actual flipping.
            if(exist('r'))               % If we're working per row
                disp([r q r q+1])        % Print the pair, using global row
            else
                disp([q c q+1 c])        % Print the pari, using global col
            end
        end
    end
end

बस ध्यान दिया, लेकिन मेरा नाम केनी लाउ नहीं है ... यह एक और उपयोगकर्ता है और मेरा उपयोगकर्ता नाम विशेष रूप से बताता है कि मैं केनी नहीं हूं
वैल्यू इंक

7

लुआ, 594 575 559 बाइट्स

चेतावनी इस गोल्फिंग के साथ काम करने से पहले अभी भी बहुत काम है! मुझे कम से कम 500 बाइट्स लेने में सक्षम होना चाहिए। फिलहाल, यह पहला समाधान है जिसने काम किया है, और मैं अभी भी इस पर काम कर रहा हूं।

एक बार पूरा करने के बाद मैं एक पूर्ण विवरण प्रदान करूंगा।

function f(t)s=#t a=","for i=1,s do p=t[i]for i=1,s
do p.Q=p.Q and p.Q+p[i]or p[i]end p.Q=(p.Q*#p)%3 for i=1,s do for j=1,#p-1 do
x=p[j]y=p[j+1]u=x~=y and(p.S and p.R==p.S or x~=p.Q)v=(x+y)*2p[j]=u and v%3or x
p[j+1]=u and v%3or y print(i..a..j,i..a..j+1)end
p.R=p.S p.S=table.concat(p)end end
for i=1,s do Q=Q and Q+t[i][1]or t[i][1]end Q=(Q*s)%3 for i=1,s
do for j=1,s-1 do p=t[j]q=t[j+1]x=p[1]y=q[1]u=x~=y and(S and R==S or x~=Q)v=(x+y)*2
for k=1,#p do p[k]=u and v%3or x q[k]=u and v%3or y
print(j..a..k,j+1..a..k)end Y=Y and Y..x or x end
R=S S=Y end end

5

जंग, 496 495 बाइट्स

अफसोस की बात है कि मैं ओपी को हरा नहीं सकता, लेकिन एक मजबूत जवाब के लिए मैं बाइटकाउंट से काफी संतुष्ट हूं।

let s=|mut v:Vec<_>,c|{
let p=|v:&mut[_],f,t|{
let x=|v:&mut[_],i|{
let n=v[i]^v[i+1];v[i]=n;v[i+1]=n;
for k in f..t+1{print!("{:?}",if f==t{(k,i,k,i+1)}else{(i,k,i+1,k)});}};
let l=v.len();let t=(1..4).find(|x|l*x)%3==v.iter().fold(0,|a,b|a+b)%3).unwrap();
let mut i=0;while i<l{let c=v[i];if c==t{i+=1;}else if c==v[i+1]{
let j=if let Some(x)=(i+1..l).find(|j|v[j+1]!=c){x}else{i-=1;i};x(v,j);}else{x(v,i);}}t};
p(&mut (0..).zip(v.chunks_mut(c)).map(|(i,x)|{p(x,i,i)}).collect::<Vec<_>>(),0,c-1usize)};

इनपुट: संख्याओं के साथ-साथ स्तंभों की संख्या का एक सदिश। उदाहरण के लिए

s(vec!{1,2,1,3},2);

आउटपुट

 (row1,col1,row2,col2)

कमांड लाइन के लिए।

मैं पहले हर पंक्ति को हल करता हूं और फिर परिणामी कॉलम को केवल एक बार हल करता हूं, लेकिन सभी कॉलम के लिए चरणों को प्रिंट करता हूं। तो यह वास्तव में काफी कुशल है :-P।

बनाने के साथ:

let s=|mut v:Vec<_>,c|{  
    let p=|v:&mut[_],f,t|{     // solves a single row/column
        let x=|v:&mut[_],i|{   // makes a move and prints it 
            let n=v[i]^v[i+1]; // use xor to calculate the new color
            v[i]=n;
            v[i+1]=n;
            for k in f..t{
                print!("{:?}",if f==t{(k,i,k,i+1)}else{(i,k,i+1,k)});
            }
        };
        let l=v.len();
        // find target color
        // oh man i am so looking forward to sum() being stabilized
        let t=(1..4).find(|x|(l*x)%3==v.iter().fold(0,|a,b|a+b)%3).unwrap();
        let mut i=0;
        while i<l{
            let c=v[i];
            if c==t{             // if the color is target color move on
                i+=1;
            }else if c==v[i+1]{ // if the next color is the same
                                // find the next possible move
                let j=if let Some(x)=(i+1..l).find(|j|v[j+1]!=c){x}else{i-=1;i};
                x(v,j);
            }else{              // colors are different so we can make a move
                x(v,i);         
            }
        }
        t
    };
    // first solve all rows and than sovle the resulting column c times 
    p(&mut (0..).zip(v.chunks_mut(c)).map(|(i,x)|p(x,i,i)).collect::<Vec<_>>(),0,c-1usize)
};

संपादित करें: अब समाधान का रंग लौटाता है जो मुझे अर्धविराम ^ ^ बचाता है


5

बेफ़ुंज , 197 368 696 754 बाइट्स


(हाँ, मैं कुछ रिवर्स कोड गोल्फ कर रहा हूँ, और बेहतर बाइट्स)


मैं सोच रहा था कि Befunge में इस एल्गोरिथ्म को लिखना एक चुनौती हो सकती है और यह मजेदार हो सकता है

मैं चाहूंगा कि यह एक सामुदायिक कार्यक्रम हो, इसलिए यदि कोई इस पर काम करना चाहता है, तो कृपया ऐसा करें।

अंत में, मैंने अब तक सब कुछ अकेले किया है, इसलिए मैं अपने दम पर खत्म कर दूंगा (यह लगभग पूरा हो चुका है)


अभी तक क्या किया गया है: एक ट्रोल के आकार का कोड

&:19p&:09p:v:p94g92g90  <
 v94+1:g94&_$59g1+59p1-:|
 >p59gp1-: ^    vp95g93$<
v94\-1<v:g<     >  v
>g:1+v^_$v^90p94g92<
v5p94<   3>1+59p   ^
>9gg+\:^ %g   v93:g95<           v3_2         v
v1pg95g94<^95<>g-v>$v^           v ^-%3*2\gg9<
>9g39g+59g-1-|v-1_^ #^pg95+g92g90<1_09g:29g+5^
       ;  >  >  09g:29g+59gg\3%-# !^v         <
          ^p95<                  ^  <
     v  p96-1+g90g92<
     v                  p95_@
            >59g1+:39g-19g-^
     v    >p 79g:59gg\1+59gp$$$$$29g49pv
    > p59g^ |<<<<<<<<<<<<<<<<<<!-g96g94<
>:79^>29g49p>69g1+59gg49g:59gg\1+49p- v
^\-\6+gg95+1\g< v         !-g96:<-1g94_^
>"]",52*,::59g^v_::1+59gg\59gg-v^ <
^ .-g93g95,.-g<>:69g- v  v-g96:_1+^
>+" [,]",,,\29^       >#v_$:49g2-v
^1:.-g93g95,.-g92\,"[ ":<        <

(हाँ, यह एक ट्रोल है, मेरा विश्वास करो)


मूल रूप से, यह एक सरणी पढ़ता है और पंक्तियों को हल करने के लिए करने के लिए कदम की गणना करता है, जैसा कि एक इनपुट दिया गया है

(number of rows) (number of columns) 1 2 3 1 1 3 2 1 2 ....

(संपूर्ण सरणी को एक सूची [row1, row2, row3,…] के रूप में पारित किया गया है)

आउटपुट है

[col row],[col',row']
[col2 row2],[col2',row2']
...

पंक्तियों और कॉलनों दोनों 0 से शुरू होते हैं।


अब जब कि पंक्तियाँ हल हो गई हैं, तो यह लगभग पूरा हो चुका है! हुर्रे!


स्पष्टीकरण: (बाद में अद्यतन किया जाएगा)

छवि

तो 5 मुख्य भाग हैं:

  • पहले वाला, हरे रंग में, इनपुट लाइन को पढ़ता है और सरणी की एक पंक्ति लिखता है
  • दूसरा, नारंगी में, सरणी की अगली पंक्ति के लिए गुजरता है
  • तीसरा, नीले रंग में, एक पंक्ति में बैठता है
  • चौथा एक, गर्म गुलाबी में, योग का मापांक 3 लेता है, इसे संबंधित पंक्ति के दाईं ओर बचाता है, और अगली पंक्ति में जाता है
  • अंत में, लाल रंग में, वह भाग जो पहले से गणना की गई संख्या से लक्ष्य रंग की गणना करता है। यह हिस्सा वास्तव में गूंगा है और शायद इसे फिर से लिखा जाना चाहिए, लेकिन मुझे यह पता नहीं चला कि मैं ऐसा कैसे कर सकता हूं (197 बाइट्स से 368 तक बस उस हिस्से के साथ)

ग्रे भाग प्रारंभिक हैं


यहाँ मॉड्यूल की एक गहरी व्याख्या है जो बक्से को संयोजित करने के लिए ढूंढता है (जो कि यहां कोडित है, वैसे)

                                       B
            @                          v
            |                  !-g96g94<
ENTRY>29g49p>69g1+59gg49g:59gg\1+49p- v
                v         !-g96:<-1g94_^
               v_::1+59gg\59gg-v^ <
               >:69g- v  v-g96:_1+^
                      >#v_$:49g2-v
                    CALL<        <

CALL हिस्सा वह है जब निर्देश पॉइंटर दूसरे मॉड्यूल में जा रहा है, बक्से में गठबंधन करने के लिए। यह 'बी' प्रविष्टि के माध्यम से इस मॉड्यूल पर वापस आता है

यहाँ कुछ छद्म कोड है: (वर्तमान में सरणी पढ़ने से संबंधित है) के लिए:

    69g1+59gg  // read target color
    49g:59gg\1+49p // read current color and THEN shift the currentx to the next box
    if ( top != top ){  // if the current color is bad
        49g1-          //  put the current place  (or currentx - 1) in the stack
        While:
            if ( :top != 69g ){   // if you didn't reach the end of the list
                ::1+              // copy twice, add 1
                if ( 59gg == \59gg ){ // if the next color is the same than current
                   1+                // iterate
                   break While;
                }
            }

        : // copies j (the previous raw iterator)
        if ( top == 69g ){  // if you reached the end of the row (which mean you can't swap with the color after that point)
            $:              // discard j's copy and copy target
            49g2-           // put the place just before the color change on the stack
            combine_with_next;
        } else {
            combine_with_next;
        }
        29g49p   // back to the beginning of the row (there was some changes int the row)
    }

    if ( 49g != 69g ) // if you didn't reach the end of the list
        break For:

ध्यान दें कि यदि आप इसका परीक्षण करना चाहते हैं, तो आपको कुछ अनुगामी स्थान और अनुगामी नई रेखाएँ डालनी होंगी ताकि सरणी को संग्रहीत करने के लिए पर्याप्त स्थान हो, यदि आप मेरे द्वारा व्याख्या की गई व्याख्या का उपयोग करना चाहते हैं । 22 + अनुगामी लाइनों के रूप में इनपुट में पंक्तियों की संख्या, और 34 + एक पंक्ति पर अनुगामी रिक्त स्थान के रूप में स्तंभों की संख्या ठीक होनी चाहिए।


बस उत्सुकता है, यह गैर-प्रतिस्पर्धा क्यों है?
मूल्य इंक

इस भाग के कारण: 'मैं चाहूंगा कि यह एक सामुदायिक कार्यक्रम हो।' मुझे लगा कि मैं थोड़ा सा धोखा
खा जाऊंगा

मेरे पास 197 बाइट्स का परिणाम है, क्या आप खिड़कियों के नीचे काम करते हैं? (और केवल के \r\nबजाय गिना जाता है \n?)
काटेंको

हम्म, मुझे लगता है मैं बाइट्स गिनते समय कुछ अनुगामी पेस्ट करता हूं, धन्यवाद
Maliafo

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

2

सी, 404 बाइट्स

मेरा पहला कोड गोल्फ, मैं बहुत खुश हूं कि यह कैसे निकला। हालांकि बहुत लंबा रास्ता तय किया। यह पूरी तरह से मानक सी नहीं है, बस जो कोई विशेष झंडे (और चेतावनियों की अनदेखी) के साथ जीसीसी के तहत संकलन करेगा। तो वहाँ एक नेस्टेड फ़ंक्शन है। फ़ंक्शन fआयामों mऔर nइसके पहले तर्कों के रूप में लेता है, और जैसा कि यह तीसरा तर्क है आकार के एक सरणी के लिए (int सूचक) लेता है m× n(पहले पंक्तियों द्वारा अनुक्रमित)। अन्य तर्क डमी तर्क हैं, आपको उन्हें पारित करने की आवश्यकता नहीं है, वे केवल चर घोषित करने पर बाइट्स बचाने के लिए हैं। यह प्रत्येक परिवर्तित जोड़े को प्रारूप में STDOUT में लिखता है row1,col1:row1,col1;, अर्धविराम के साथ जोड़े को अलग करता है। 0-आधारित अनुक्रमण का उपयोग करता है।

#define A a[i*o+p
#define B A*c
f(m,n,a,i,j,o,p,b,c,d)int*a;{
int t(x){printf("%d,%d:%d,%d;",b?i:c+x,b?c+x:i,b?i:c+1+x,b?c+1+x:i);}
o=n;p=b=1;for(;~b;b--){
for(i=0;i<m;i++){c=j=0;
for(;j<n;)c+=A*j++];d=c*n%3;
for(j=0;j<n-1;j++) 
while(A*j]^d|A*j+p]^d){
for(c=j;B]==B+p];c++);
if(c<n-2&B]==d&2*(B+p]+A*(c+2)])%3==d)
B+p]=A*(c+2)]=d,t(1);else
B]=B+p]=2*(B]+B+p])%3,
t(0);}}o=m;p=m=n;n=o;o=1;}}

मैंने व्यक्तिगत पंक्तियों / स्तंभों को हल करने के लिए ओपी की तुलना में थोड़ा अलग एल्गोरिथ्म का उपयोग किया। यह कुछ इस प्रकार है (छद्मकोश):

for j in range [0, rowlength):
    while row[j] != targetCol or row[j+1] != targetCol:
        e=j
        while row[e] == row[e+1]:
            e++             //e will never go out of bounds
        if e<=rowLength-3 and row[e] == targetCol 
                and (row[e+1] != row[e+2] != targetCol):
            row.changeColor(e+1, e+2)
        else:
            row.changeColor(e, e+1)

for(;~b;b--)पाश कार्यान्वित वास्तव में दो बार, दूसरी पास पर यह पंक्तियों के बजाय स्तंभों को हल करती है। इस अदला-बदली करके किया जाता है nऔर m, और के मूल्यों को बदलने oऔरp जो कि सरणी को संबोधित करने के लिए सूचक अंकगणितीय में उपयोग किया जाता है।

यहां एक संस्करण है जो एक परीक्षण मुख्य के साथ अनऑर्गलाइज्ड है, और हर कदम के बाद पूरे सरणी को प्रिंट करता है (चरण 1 में प्रवेश करें दबाएं):

#define s(x,y)b?x:y,b?y:x
#define A a[i*o+p
#define B A*e
f(m,n,a,i,j,o,p,b,c,d,e)int*a;{

    int t(x){
        printf("%d,%d:%d,%d;\n",s(i,e+x),s(i,e+1+x));
        getchar();
        printf("\n");
        for(int i2=0;i2<(b?m:n);i2++){
            for(int j2=0;j2<(b?n:m);j2++){
                printf("%d ",a[i2*(b?n:m)+j2]);
            }
            printf("\n");
        }
        printf("\n");
    }

    printf("\n");
    b=1;
    for(int i2=0;i2<(b?m:n);i2++){
        for(int j2=0;j2<(b?n:m);j2++){
            printf("%d ",a[i2*(b?n:m)+j2]);
        }
        printf("\n");
    }
    printf("\n");

    o=n;p=1;
    for(b=1;~b;b--){
        for(i=0;i<m;i++){
            c=0;
            for(j=0;j<n;j++) c+= a[i*o+p*j];
            d=0;
            d = (c*n)%3;
            for(j=0;j<n-1;j++) {
                while(a[i*o+p*j]!=d||a[i*o+p*j+p]!=d){
                    for(e=j;a[i*o+p*e]==a[i*o+p*e+p];e++);
                    if(e<=n-3 && a[i*o+p*e]==d 
                            && 2*(a[i*o+p*e+p]+a[i*o+p*(e+2)])%3==d){
                        a[i*o+p*e+p]=a[i*o+p*(e+2)]=d;
                        t(1);
                    }else{
                        a[i*o+p*e]=a[i*o+p*e+p] = 2*(a[i*o+p*e]+a[i*o+p*e+p])%3;
                        t(0);
                    }
                }
            }
        }
        o=m;p=m=n;n=o;o=1;
    }
}

main(){
    int g[11][11] = 
    {
        {0,2,1,2,2,1,0,1,1,0,2},
        {2,1,1,0,1,1,2,0,2,1,0},
        {1,0,2,1,0,1,0,2,1,2,0},
        {0,0,2,1,2,0,1,2,0,0,1},
        {0,2,1,2,2,1,0,0,0,2,1},
        {2,1,1,0,1,1,2,1,0,0,2},
        {1,0,2,1,0,1,0,2,2,1,2},
        {0,0,2,1,2,0,1,0,1,2,0},
        {1,2,0,1,2,0,0,2,1,2,0},
        {2,1,1,0,1,1,2,1,0,0,2},
        {0,2,1,0,1,0,2,1,0,0,2},
    };
    #define M 4
    #define N 7
    int grid[M][N];
    for(int i=0;i<M;i++) {
        for(int j=0;j<N;j++) {
            grid[i][j] = g[i][j];
        }
    }
    f(M,N,grid[0],0,0,0,0,0,0,0,0);
};

जिज्ञासा से बाहर: आपने एक अलग एल्गोरिथ्म (बाइट बचत के संदर्भ में) क्यों चुना?
18:01 पर

1
मुझे लगता है कि यह अधिक दिलचस्प है जब लोग अलग-अलग समाधानों के साथ आते हैं, और कुछ त्वरित परीक्षणों से मैंने दो तरीकों का अनुमान लगाया जो बाइट की गिनती में समान हैं। मैं शायद आपके एल्गोरिथ्म को भी आज़माऊँगा और देखूँगा कि क्या मैं कम कर सकता हूँ।
Norg74

इसे यहां पोस्ट कर रहा हूं क्योंकि मेरे पास सवाल पर टिप्पणी करने के लिए पर्याप्त प्रतिनिधि नहीं है। क्या प्रत्येक पंक्ति को बलपूर्वक अलग करना मान्य होगा, फिर प्रत्येक स्तंभ को व्यक्तिगत रूप से? यह तकनीकी रूप से "पूरी तरह से क्रूर नहीं है" और निर्दिष्ट समय जटिलता से कम होना चाहिए। मैंने वास्तव में ऐसा करने पर विचार किया।
Norg74

ब्रूट-फोर्सिंग उल्लेख 'उचित समय' टिप्पणी को तेज करने के लिए था, इसलिए इसे टी «ओ (...) के रूप में देखें। मुझे पता है कि जानवर बल और एक उचित एल्गोरिथ्म के बीच एक ग्रे क्षेत्र है, इसलिए अपने निर्णय का उपयोग करें कि क्या आपको लगता है कि यह पहेली को हल करने की दिशा में काम कर रहा है या अगर यह डीएफएस या बीएफएस पर मामूली संशोधन है जो 'प्रगति' के अज्ञेय हैं ।
Sanchises
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.