आलसी युद्धपोत प्लेसमेंट


39

निम्नलिखित परिदृश्य की कल्पना करें: आप एक दोस्त के साथ युद्धपोत खेल रहे हैं लेकिन धोखा देने का फैसला करते हैं। शूटिंग के बाद एक जहाज को हिलाने के बजाय, जहां आपका जहाज हुआ करता था, आप किसी भी जहाज को नहीं रखने का फैसला करते हैं। आप उसे बताएं कि उसके सभी शॉट मिस हैं, जब तक कि इस तरह से जहाजों को रखना असंभव नहीं है।

आपको एक फ़ंक्शन, या एक पूर्ण प्रोग्राम लिखना होगा, जो किसी तरह 3 तर्क लेता है: फ़ील्ड आकार, जहाज के आकार की मात्रा की सूची और शॉट्स की सूची।

लड़ाई का मैदान

दिए गए मापदंडों में से एक बोर्ड आकार है। युद्ध का मैदान कोशिकाओं का एक वर्ग है, और दिए गए पैरामीटर वर्ग का केवल एक पक्ष है।
उदाहरण के लिए, निम्नलिखित आकार 5 का बोर्ड है।

फ़ील्ड पर निर्देशांक 2-घटक स्ट्रिंग के रूप में निर्दिष्ट किए गए हैं: एक पत्र जिसके बाद एक संख्या है। आप पत्रों पर किसी विशेष मामले में भरोसा कर सकते हैं।
पत्र कॉलम निर्दिष्ट करता है, संख्या सेल की पंक्ति को निर्दिष्ट करता है (1-अनुक्रमित)। उपरोक्त चित्र में उदाहरण के लिए, हाइलाइट किए गए सेल द्वारा चिह्नित किया गया है "D2"
चूंकि केवल 26 अक्षर हैं, इसलिए क्षेत्र 26x26 से बड़ा नहीं हो सकता है।

जहाजों

जहाज 1 या अधिक ब्लॉक की सीधी रेखाएं हैं। जहाजों की मात्रा एक सूची में निर्दिष्ट है, जहां पहला तत्व 1-सेल जहाजों की मात्रा है, दूसरा - 2-सेल जहाजों और इतने पर।
उदाहरण के लिए, सूची [4,1,2,0,1]में निम्नलिखित पोत बनाए जाएंगे:

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

आप मान सकते हैं कि किसी दिए गए जहाज के लिए, हमेशा दिए गए आकार के खाली बोर्ड पर प्लेसमेंट मौजूद है।

उत्पादन

यदि जहाजों के ऐसे स्थान मौजूद हैं, तो आपको उनमें से किसी का भी उत्पादन करना होगा।
कार्यक्रम में 3 प्रकारों में से एक ascii वर्णों की एक नई-लाइन-अलग मैट्रिक्स को आउटपुट करना है - एक को रिक्त सेल, एक - एक जहाज का टुकड़ा, और एक - "मिस्ड" के रूप में चिह्नित सेल। कोई अन्य वर्ण आउटपुट नहीं होना चाहिए।
उदाहरण के लिए,

ZZ@Z
\@@Z
@\\Z
\Z\\

(इस उदाहरण में, मैंने "मिस्ड" सेल @होने के लिए रिक्त सेल के रूप में परिभाषित \किया, और Zजहाज का टुकड़ा होने के लिए)

यदि ऐसा कोई प्लेसमेंट मौजूद नहीं है, तो प्रोग्राम / फ़ंक्शन को कुछ भी आउटपुट किए बिना वापस लौटना चाहिए।

इनपुट

यदि आप एक फुलब्लॉक प्रोग्राम बनाने का निर्णय लेते हैं, तो यह निर्दिष्ट करना है कि सूचियाँ कैसे इनपुट हैं, कुछ तर्क के माध्यम से जा सकते हैं, कुछ बिना किसी नियम के।

यह , सबसे कम मात्रा में अक्षर जीतते हैं।

एक उदाहरण गैर golfed अनुकूलित समाधान पाया जा सकता है यहाँ
के साथ संकलित -std=c99, पहला तर्क बोर्ड का आकार है, अन्य तर्कों जहाज आकार हैं। स्टडिन पर शॉट्स की एक नई-अलग-अलग सूची दी गई है। उदाहरण:
./a 4 1 1 1 <<< $'A2\nA4\nB3\nC3\nC4\D4'


26x26? मैंने regexps और recursion के आधार पर एक समाधान को स्केच किया, और यह खेतों की तुलना में बहुत धीमी गति से अनुपयोगी हो जाता है 6x6। या तो मैं बहुत मूर्खतापूर्ण कुछ करता हूं, या जवाब की कमी का मतलब है कि दूसरों को भी कोई सफलता नहीं मिली है।
user2846289

मैंने अभी C में एक कार्यान्वयन लिखा है, यह कम से कम 10x10एक 4,3,2,1शिपसेट के साथ तुरंत गणना करता है
mniip

@ एमनिप: क्या आपके पास कठिन मामलों (बड़े बोर्ड, कई जहाज, शॉट्स की स्थिति के कारण विफल) से निपटने का कोई विशिष्ट तरीका है? या यह सिर्फ (थोड़ा स्मार्ट) जानवर बल है?
n --h'a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳ 19

इसके पास कुछ अनुकूलन हैं, फ़े पहले छोटे जहाजों को रखने की कोशिश करता है, और जानवर के बल से बराबर आकार के स्वैपिंग जहाजों को बाहर करता है। जब थोड़े छोटे और लगभग खाली बोर्ड पर बहुत सारे जहाज होते हैं तो यह थोड़े धीमा होता है।
मनिीप

@ n @h ana̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳ मैंने एक उदाहरण समाधान लिंक जोड़ा है।
मनिएप

जवाबों:


2

गोल्फस्क्रिप्ट, 236 वर्ण

n%([~](:N):M;[.,,]zip{~[)]*~}%-1%:S;{(65-\~(M*+}%:H;{{M*+}+N,/}N,%H-S[]]]{(~\.{(:L;{{M*+{+}+L,%}+N)L-,/}N,%{.{.M/\M%M*+}%}%{3$&,L=},{:K[{..M+\M-}%{..)\(}%3$\- 1$3$K+]}%\;\;\;\+.}{;:R;;;0}if}do{{{M*+.H?)'!'*\R?)'#'*'.'++1<}+N,/n}N,%}R!!*

इनपुट STDIN पर दिया गया है। पहली पंक्ति में आकार और जहाजों की संख्या होती है, प्रत्येक पंक्ति में एक ही शॉट के निर्देशांक होते हैं।

उदाहरण:

4 1 1 1
A2
A4
B3
C3
C4
D4

##.#
!..#
#!!#
!.!!

मुझे लगा कि इस चुनौती में भी कम से कम एक गोल्फस्क्रिप्ट का जवाब होना चाहिए। अंत में यह उपयोग किए गए एल्गोरिथ्म के कारण बहुत ही अनगोल्फस्क्रिप्ट हो गया जो लघुता पर प्रदर्शन का पक्षधर है।

एनोटेट कोड:

n%               # Split the input into lines
([~]             # The first line is evaluated to an array [N S1 S2 S3 ...]
(:N              # This happy smiley removes the first item and assigns it to variable N
):M;             # While this sad smiley increases N by one and assigns it to M

[.,,]zip         # For the rest of numbers in the first line create the array [[0 S1] [1 S2] [2 S3] ...]
{~[)]*~}%        # Each element [i Si] is converted into the list (i+1 i+1 ... i+1) with Si items. 
-1%:S;           # Reverse (i.e. largest ship first) and assign the list to variable S.
                 # The result is a list of ship lengths, e.g. for input 3 0 2 we have S = [3 3 1 1 1].

{                # On the stack remains a list of coordinates
  (65-           # Convert the letter from A,B,... into numeric value 0,1,...
  \~(            # The number value is decreased by one
  M*+            # Both are combined to a single index (M*row+col)
}%:H;            # The list of shots is then assigned to variable H

                 # The algorithm is recursive backtracking implemented using a stack of tuples [A S R] where
                 #   - A is the list of open squares
                 #   - S is a list of ships to be placed
                 #   - R is the list of positions where ships were placed                     

    {{           # initial A is the full space of possible coordinates
      M*+        #   combine row and column values into a single index
    }+N,/}N,%    # do the N*N loop
    H-           # minus all places where a shot was done already
    S            # initial S is the original list
    []           # initial R is the empty list (no ships placed yet)
  ]
]                # The starting point is pushed on the stack 

{                # Start of the loop running on the stack
  (~\            # Pop from the stack and extract items in order A R S

  .{             #   If S is non-empty

    (:L;         #     Take first item in S (longest ship) and asign its length to L

    {{M*+{+}+L,%}+N)L-,/}N,%{.{.M/\M%M*+}%}%
                 #     This lengthy expression just calculates all possible ship placements on a single board
                 #     (could be shortened by 3 chars if we don't respect board size but I find it clearer this way)

    {3$&,L=},    #     This step is just a filter on those placements. The overlap (&) with the list of open squares (3$) 
                 #     must be of size L, i.e. all coordinates must be free

                 #     Now we have possible placements. For each one generate the appropriate tuple (A* S* R*) for recursion
    {
      :K         #     Assign the possible new ship placement to temporary variable K
      [
        {..M+\M-}%
        {..)\(}% 
                 #       For each coordinate add the square one row above and below (first loop)
                 #       and afterwards for the resulting list also all squares left and right (second loop)
        3$\-     #       Remove all these squares from the list of available squares A in order to get the new A*
        1$       #       Reduced list of ships S* (note that the first item of S was already remove above)
        3$K+     #       Last item in tuple is R* = R + K, i.e. the ship's placements are added to the result
      ]
    }%           

    \;\;\;       #     Discard the original values A R S
    \+           #     Push the newly generated tuples on the stack
    .            #     Loop until the stack is empty

  }{             #   else

    ;:R;;;       #     Assign the solution to the variable R and remove all the rest from the stack. 
    0            #     Push a zero in order to break the loop

  }if            #   End if

}do              # End of the loop


{                # The output block starts here
  {{             
    M*+
    .H?)         #   Is the current square in the list of shots?
    '!'*         #     then take a number of '!' otherwise an empty string
    \R?)         #   Is the current square in the list of ships?
    '#'*         #     then take a number of '#' otherwise an empty string
    '.'++        #   Join both strings and append a '.'
    1<           #   Take the first item of the resulting string, i.e. altogether this is a simple if-else-structure
  }+N,/n}N,%     # Do a N*N loop
}
R!!*             # Run this block only if R was assigned something during the backtracking. 
                 # (!! is double-negation which converts any non-zero R into a one)
                 # Note: since the empty list from the algorithm is still on the stack if R wasn't assigned
                 # anything the operator !! works on the code block (which yields 1) which is then multiplied
                 # with the empty list.

6

एसडब्ल्यूआई-प्रोलॉग, 536 441 1 बाइट्स

1 यूनिक्स लाइन समाप्त, अंतिम नई लाइन की गिनती नहीं

हटाए गए सभी अनुकूलन वाले संस्करण ( 441 बाइट्स):

:-[library(clpfd)].
m(G,L):-maplist(G,L).
l(L,A):-length(A,L).
y(A,E,(X,Y)):-nth1(X,A,R),nth1(Y,R,F),var(F),F=E.
a(A,S):-l(L,A),X#>0,X#=<L,Y#>0,Y#=<L,h(S,(X,Y),A).
h(0,_,_).
h(L,(X,Y),A):-(B=A;transpose(A,T),B=T),y(B,s,(X,Y)),M#=L-1,Z#=Y+1,h(M,(X,Z),B).
e([],_,[]).
e([H|R],I,O):-J#=I+1,e(R,J,P),l(H,Q),Q ins I,append(P,Q,O).
r(R):-m(c,R),nl.
c(E):-var(E)->put(@);put(E).
g(L,H,S):-l(L,A),m(l(L),A),m(y(A,\),S),e(H,1,G),!,m(a(A),G),!,m(r,A).

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


बुनियादी अनुकूलन के साथ संस्करण, पूरी तरह से गोल्फ ( 536 → 506 बाइट्स)

:-[library(clpfd)].
m(G,L):-maplist(G,L).
l(L,A):-length(A,L).
x(A,I,E):-X=..[a|A],arg(I,X,E).
y(A,E,(X,Y)):-x(A,X,R),x(R,Y,E).
a(A,S):-l(L,A),X#>0,X#=<L,Y#>0,Y#=<L,(B=A;transpose(A,T),B=T),h(S,(X,Y),B).
h(0,_,_).
h(L,(X,Y),A):-y(A,E,(X,Y)),var(E),E=s,M#=L-1,Z#=Y+1,h(M,(X,Z),A).
e([],_,[]).
e([H|R],I,O):-J#=I+1,e(R,J,P),l(H,Q),Q ins I,append(P,Q,O).
r(R):-m(c,R),nl.
c(E):-var(E)->put(@);put(E).
g(L,H,S):-l(L,A),m(l(L),A),sort(S,T),m(y(A,\),T),e(H,1,G),!,l(E,T),sumlist(G,D),L*L-E>=D,m(a(A),G),!,m(r,A).

मैं स्पष्ट रूप से असंभव मामलों के लिए तेजी से कोड बाहर निकालने के लिए कुछ बुनियादी जांच ( जहाज ब्लॉकों की गिनती आवश्यक ) लागू करता हूं । कोड भी शॉट्स की सूची में नकल करने के लिए प्रतिरक्षा है


नीचे (कुछ हद तक) पठनीय संस्करण है, विस्तृत टिप्पणियों के साथ:

:-[library(clpfd)].

% Shorthand for maplist, which works like map in high order function
m(G,L):-maplist(G,L).

% Creating a square matrix A which is L x L
board(L,A):-l(L,A),m(l(L),A).

% Shorthand for length, with order of parameters reversed
l(L,A):-length(A,L).

% Unification A[I] = E
x(A,I,E):-X=..[a|A],arg(I,X,E).

% Unification A[X][Y]=E
idx2(A,E,(X,Y)):-x(A,X,R),x(R,Y,E).

% Mark positions that have been shot
markshot(A,S):-m(idx2(A,\),S).

% Place all ships on the board
placeships(H,A):-m(placeship(A),H).

% Place a length S ship horizontal/vertical forward on the board
placeship(A,S):-
    l(L,A), % Get length
    X#>0,X#=<L,Y#>0,Y#=<L, % Constraint X and Y coordinates
    transpose(A,T), % Transpose to work on columns
    (placeship_h(S,(X,Y),A) ; placeship_h(S,(Y,X),T)).

% Place ship horizontal, forward at (X,Y)
placeship_h(0,_,_).
placeship_h(L,(X,Y),A):-
    idx2(A,E,(X,Y)),var(E),E=s, % Make sure position is unassigned, then mark
    L2#=L-1,Y2#=Y+1, % Do this for all blocks of the ship
    placeship_h(L2,(X,Y2),A).

% Expand the list of ships
% e.g. [2,3,1] --> [3,2,2,2,1,1]
shipexpand(S,O):-shipexpand(S,1,O).

shipexpand([],_,[]).
shipexpand([H|R],I,O):-
    I2#=I+1,shipexpand(R,I2,O2), % process the rest
    l(H,O1),O1 ins I, % duplicate current ship size H times
    append(O2,O1,O). % larger ship size goes in front

% Print the result
pboard(A):-m(prow,A).
prow(R):-m(pcell,R),print('\n').
pcell(E):-var(E)->print(@);print(E).

game(L,H,S):-
    board(L,A), % create board
    sort(S,SS), % remove duplicates
    markshot(A,SS), % mark positions that have been shot
    shipexpand(H,HH),!, % make a list of ships
    l(SC,SS),sumlist(HH,BC),L*L-SC>=BC, % check to speed-up, can be removed
    placeships(HH,A),!, % place ships
    pboard(A). % print result

क्वेरी प्रारूप:

game(Board_Size, Ships_List, Shots_List).

नमूना प्रश्न (प्रश्न में नमूना का उपयोग करके):

?- game(4,[1,1,1],[(2,1),(3,2),(3,3),(4,1),(4,3),(4,4)]).
ssss
\ss@
@\\@
\@\\
true.

?- game(4,[2,2,0,1],[(2,1),(3,2),(3,3),(4,1),(4,3),(4,4)]).
ssss
\sss
s\\s
\s\\
true.

आह दर्जन मुझे कुछ दर्जन पात्रों ने पीटा! मुझे यकीन नहीं है कि अगर मैं किसी और को भी संकुचित कर सकता हूं, लेकिन मैं कोशिश करता रहूंगा ... प्रोलॉग का अच्छा उपयोग!
क्लाउडीयू

@ कलौइडु: मेरे समाधान में अभी भी 20 या उससे अधिक अक्षरों का "बफर" है। मैंने प्रदर्शन कारण के लिए उन चेकिंग कोड को छोड़ दिया, लेकिन शुद्धता को प्रभावित किए बिना उन्हें हटाया जा सकता है;) यदि अन्य उत्तर 500 से नीचे मिलते हैं, तो मैं परेशान नहीं होता।
n --h'a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳ 19

5

मतलाब - 536 वर्ण

अपडेट किया गया: बहुत छोटे आउटपुट स्वरूपण, कुछ लूप व्हाट्सएप को हटा दिया गया।

अपडेट किया गया: गोल्फ संस्करण जोड़ा गया

अपडेट किया गया: ~ 100 वर्णों द्वारा कम किए गए संस्करण, कम किए गए गोल्फ संस्करण को जोड़ा गया

% Battleship puzzle solver.
%
% n: size of the map (ex. 4 -> 4x4)
% sh: list of shots (ex. ['A2';'C4'])
% sp: ships of each size (ex. [2,0,1] -> 2x1 and 1x3)
%
function bs(n,sh,sp)

  % sp holds a vector of ship counts, where the index of each element is
  % the size of the ship. s will hold a vector of ship sizes, with order
  % not mattering. This is easier to work with using recursion, because
  % we can remove elements with Matlab's array subselection syntax, rather
  % than decrement elements and check if they're zero.
  %
  % Tricks:
  %   Since sp never contains a -1, find(1+sp) is the same as 1:length(sp)
  %   but is three characters shorter.
  %
  s=[];
  for i=find(1+sp)
    s(end+1:end+sp(i))=i;
  end


  % m will hold the map. It will be +2 in each direction, so that later we
  % can find neighbors of edge-spaces without checking bounds. For now,
  % each element is either '0' or '1' for a space or missed shot,
  % respectively. We convert the shots as provided by the user (ex. 'A2')
  % to marks on the map.
  %
  % Tricks:
  %   It takes one shorter character to subtract 47 than 'A' to determine
  %   the indices into the map.
  %
  m=zeros(n+2);
  for h=sh'
    m(h(2)-47,h(1)-63)=1;
  end


  % Solve the puzzle. q will either be the empty array or a solution map.
  %
  q=pp(m,s);


  % If a solution was found, output it, showing the original shots and the
  % ship placement. If no solution was found, print a sad face.
  %
  % Tricks:
  %   q is 0 on failure, which is treated like 'false'. q is a matrix on
  %   success which is NOT treated like 'true', so we have to check for
  %   failure first, then handle success in the 'else' block.
  %
  %   q contains the "fake shots" that surround each placed ship (see the
  %   pl function). We don't want to output those, so we just copy the ship
  %   markings into the original map.
  %
  if ~q ':('
  else
  m(find(q==2))=2;
  num2str(m(2:n+1,2:n+1),'%d')
  end



% Depth-first search for a solution.
%
% m: map (see main code above)
% s: vector of ship sizes to place in the map
%
% Returns q: square matrix of integers, updated with all requested ship
% sizes, or 0 if no solution is possible.
%
function q = pp(m,s)

  % If we have no ships to process, we're all done recursing and the
  % current map is a valid solution. Rather than handle this in an 'else'
  % block, we can assume it's the case and overwrite q if not, saving 4
  % characters.
  %
  q=m;


  % If we have any ships to place...
  %
  % Tricks:
  %   Since we are only interested in positive values in s, we can use
  %   sum(s) in place of isempty(s), saving 4 characters.
  %
  if sum(s)

    % Try to place the first ship in the list into the map, both vertically
    % (first call to p) and vertically (second call to p). We can process
    % any ship in the list, but the first can be removed from the list
    % with the fewest characters. r will hold a cell-array of options for
    % this ship.
    %
    r=[p(m,s(1),0),p(m',s(1),1)];


    % Recurse for each option until we find a solution.
    %
    % Tricks:
    %   Start with q, our return variable, set to 0 (indicating no solution
    %   was found. On each loop we'll only bother to recurse if q is still
    %   0. This relieves the need for if/else to check whether to continue
    %   the loop, or any final q=0 if the loop exits without success.
    %
    %   Sadly, there's no way around the length(r) call. Matlab doesn't
    %   provide syntax for iterating over cell-arrays.
    %
    q=0;
    for i=1:length(r)
      if ~q q=pp(r{i},s(2:end));end
    end
  end



% Place a single ship into a map.
%
% m: map (see main code above)
% s: ship size to place
% t: if the map has been transposed prior to this call
%
% Returns r: cell-array of possible maps including this ship
%
function r=p(m,s,t)
  % Start with an empty cell-array and pre-compute the size of the map,
  % which we'll need to use a few times.
  %
  r={};
  z=size(m);


  % For each row (omitting the first and last 'buffer' rows)...
  %
  for i=2:z(2)-1

  % For each starting column in this row where enough consecutive 0s
  % appear to fit this ship...
  %
  for j=strfind(m(i,2:end-1),(1:s)*0)

    % Copy the map so we can modify it without overwriting the variable
    % for the next loop.
    %
    n=m;


    % For each location on the map that is part of this optional
    % placement...
    for l=0:s-1
      % Let's leave this is an exercise for the reader ;)
      %
      v=-1:1;
      n([(l+j)*z(1)+i,z(1),1]*[ones(1,9);kron(v,[1 1 1]);[v v v]])=1;
    end


    % Mark each location that is part of this optional placement with
    % a '2'.
    %
    n(i,1+j:j+s)=2;


    % Since our results are going into a cell-array it won't be
    % convenient for the caller to undo any transpositions they might
    % have done. If the t flag is set, transpose this map back before
    % adding it to the cell-array.
    %
    if t n=n';end
    r{end+1}=n;
  end
  end

यहाँ गोल्फ संस्करण है।

function bs(n,sh,sp)
s=[];for i=find(1+sp)
s(end+1:end+sp(i))=i;end
m=zeros(n+2);for h=sh'
m(h(2)-47,h(1)-63)=1;end
q=pp(m,s);if ~q ':('
else
m(find(q==2))=2;num2str(m(2:n+1,2:n+1),'%d')
end
function q = pp(m,s)
q=m;if sum(s)
r=[p(m,s(1),0),p(m',s(1),1)];q=0;for i=1:length(r)if ~q q=pp(r{i},s(2:end));end
end
end
function r=p(m,s,t)
r={};z=size(m);for i=2:z(2)-1
for j=strfind(m(i,2:end-1),(1:s)*0)n=m;for l=0:s-1
v=-1:1;n([(l+j)*z(1)+i,z(1),1]*[ones(1,9);kron(v,[1 1 1]);[v v v]])=1;end
n(i,1+j:j+s)=2;if t n=n';end
r{end+1}=n;end
end

यहाँ कुछ नमूने हैं।

>>bs(4,['A1';'B3'],[2,1])
1220
0000
2120
0000

>>bs(4,['A1';'B4'],[2,2])
1022
2000
0022
2100

>> bs(4,['A1';'B4';'C2'],[3,1])
1022
2010
0020
2100

>> bs(4,['A1';'B4';'C2'],[3,2])
:(

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


4

अजगर, 464 चर

B,L,M=input()
R=range(B)
C=B+1
M=sum(1<<int(m[1:])*C-C+ord(m[0])-65for m in M)
def P(L,H,S):
 if len(L)==0:
  for y in R:print''.join('.#!'[(S>>y*C+x&1)+2*(M>>y*C+x&1)]for x in R)
  return 1
 for s in[2**L[0]-1,sum(1<<C*j for j in range(L[0]))]:
  for i in range(C*C):
   if H&s==s and P(L[1:],H&~(s|s<<1|s>>1|s<<B|s>>B|s<<C|s>>C|s<<C+1|s>>C+1),S|s):return 1
   s*=2
 return 0
P(sum(([l+1]*k for l,k in enumerate(L)),[])[::-1],sum((2**B-1)<<B*j+j for j in R)&~M,0)

इनपुट (स्टडिन):

7, [4,1,2,0,1], ['A1','B2','C3']

आउटपुट:

!#####.
.!.....
##!###.
.......
###.#.#
.......
#.#....

विभिन्न विशेषताओं के बिटमैप रखने वाले पूर्णांकों का उपयोग करता है:

M = bitmap of misses
H = bitmap of holes where ships can still go
S = bitmap of ships already placed
L = list of ship sizes not yet placed
B = dimension of board
C = bitmap row length

अगर आपको कोई आपत्ति नहीं है, तो क्या आप कोई अनुकूलन करते हैं, या यह सिर्फ सीधे क्रूर बल है?
n --h'a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳

एक अनुकूलन है: [::-1]जो पहले सबसे लंबे जहाज की कोशिश करता है। जैसे ही यह एक जहाज को पाता है, वह भी पीछे नहीं हटता।
कीथ रान्डेल

आप 7, 8, 11 और 12 की तर्ज पर 2 या 3 स्थानों के बजाय एक एकल टैब का उपयोग कर सकते हैं, बाइट काउंट को 458 तक कम कर सकते हैंयहां देखें ।
mbomb007

3

पायथन, 562 वर्ण; -8 बदसूरत आउटपुट के साथ, +4? बैश मंगलाचरण के लिए

I=int;R=range
import sys;a=sys.argv
S=I(a[1]);f=[[0]*(S+2)for _ in R(S+2)]
C=a[2].split()
X=[]
for i,n in enumerate(C):X=[i+1]*I(n)+X
Q=a[3].split()
for q in Q:f[I(q[1:])][ord(q[0])-64]=1
D=R(-1,2)
V=lambda r,c:(all(f[r+Q][c+W]<2for Q in D for W in D),0,0)[f[r][c]]
def F(X):
 if not X:print"\n".join(" ".join(" .@"[c]for c in r[1:-1])for r in f[1:-1])
 x=X[0];A=R(1,S+1)
 for r in A:
    for c in A:
     for h in(0,1):
        def P(m):
         for i in R(x):f[(r+i,r)[h]][(c,c+i)[h]]=m
        if(r+x,c+x)[h]<S+2and all(V((r+i,r)[h],(c,c+i)[h])for i in R(x)):P(2);F(X[1:]);P(0)
F(X)

नोट: इंडेंट स्तर स्पेस, टैब, टैब + स्पेस, टैब + टैब और टैब + टैब + स्पेस हैं। यह कुछ पात्रों को केवल रिक्त स्थान का उपयोग करने से बचाता है।

उपयोग और उदाहरण :

कमांड लाइन तर्कों से इनपुट लेता है। एक रिक्त स्थान के रूप में आउटपुट, एक शॉट के रूप में .और @एक जहाज के हिस्से के रूप में:

$ python bships_golf.py "7" "4 0 2 0 1" \
         "A1 C3 B5 E4 G6 G7 A3 A4 A5 A6 C1 C3 C5 C7 B6 B7 D1 D2 G3" 2>X
. @ . . @ @ @
  @   .
. @ . @   @ .
.     @ .
. . . @   @
. .   @     .
@ . . @   @ .

जब अयोग्य, कुछ नहीं छापता है:

$ python bships_golf.py "3" "2" "A1 A3 B1 C1 C3" 2>X
. . .
@   @
.   .
$ python bships_golf.py "3" "2" "A1 A2 A3 B1 C1 C3" 2>X
$

2>Xएक अपवाद फेंक कर कार्यक्रम बाहर निकलता है के बाद से एक त्रुटि संदेश को दबाने के लिए है। यदि उचित समझें तो +4 जुर्माना जोड़ें। अन्यथा मुझे try: ... except:0इसे दबाने के लिए एक ऐसा काम करना होगा, जो वैसे भी अधिक पात्रों को ले जाएगा।

मैं भी संख्या (के रूप में उत्पादन मुद्रित कर सकते हैं 0, 1और 2) बंद 8 अक्षर दाढ़ी बनाने के लिए है, लेकिन मैं मूल्य सौंदर्यशास्त्र।

स्पष्टीकरण :

मैं बोर्ड का प्रतिनिधित्व इनपुट की तुलना में आकार 2 के साथ पूर्णांकों की सूची की सूची के रूप में करता हूं, ताकि सीमा की जाँच करने से बचा जा सके। 0एक खाली जगह, 1एक शॉट और 2एक जहाज का प्रतिनिधित्व करता है । मैं शॉट्स सूची के माध्यम से चलाता हूं Qऔर सभी शॉट्स को चिह्नित करता हूं । मैं एक स्पष्ट सूची में जहाजों की सूची परिवर्तित Xजहाजों की, जैसे [4, 0, 2, 0, 1]हो जाता है [5, 3, 3, 1, 1, 1, 1]। फिर यह एक सरल बैकग्राउंडिंग एल्गोरिदम है: अवरोही आकार के क्रम में, एक जहाज रखने की कोशिश करें और फिर बाकी जहाजों को रखने की कोशिश करें। यदि यह काम नहीं करता है, तो अगले स्लॉट की कोशिश करें। जैसे ही यह सफल होता है, जहाज सूची Xशून्य होती है, और एक्सेस करना X[0]एक अपवाद को फेंक देता है जो प्रोग्राम को क्विट करता है। बाकी सिर्फ भारी गोल्फ है (शुरुआत में 1615 अक्षर थे)।


2

पर्ल, 455 447 437 436 422 418

$n=($N=<>+0)+1;@S=map{(++$-)x$_}<>=~/\d+/g;$_=<>;$f=('~'x$N.$/)x$N;substr($f,$n*$1-$n-65+ord$&,1)=x while/\w(\d+)/g;sub f{for my$i(0..$N*$n-1){for(0..@_-2){my($f,@b)=@_;$m=($s=splice@b,$_,1)-1;pos=pos($u=$_=$f)=$i;for(s/\G(~.{$N}){$m}~/$&&("\0"."\377"x$N)x$s|(o."\0"x$N)x$m.o/se?$_:(),$u=~s/\G~{$s}/o x$s/se?$u:()){for$k(0,$N-1..$n){s/(?<=o.{$k})~|~(?=.{$k}o)/!/sg}return$:if$:=@b?f($_,@b):$_}}}}$_=f$f,@S;y/!/~/;print

इंडेंट:

$n=($N=<>+0)+1;
@S=map{(++$-)x$_}<>=~/\d+/g;
$_=<>;
$f=('~'x$N.$/)x$N;
substr($f,$n*$1-$n-65+ord$&,1)=x while/\w(\d+)/g;
sub f{
    for my$i(0..$N*$n-1){
        for(0..@_-2){
            my($f,@b)=@_;
            $m=($s=splice@b,$_,1)-1;
            pos=pos($u=$_=$f)=$i;
            for(s/\G(~.{$N}){$m}~/
              $&&("\0"."\377"x$N)x$s|(o."\0"x$N)x$m.o/se?$_:(),
              $u=~s/\G~{$s}/o x$s/se?$u:()){
                for$k(0,$N-1..$n){
                    s/(?<=o.{$k})~|~(?=.{$k}o)/!/sg
                }
                return$:if$:=@b?f($_,@b):$_
            }
        }
    }
}
$_=f$f,@S;
y/!/~/;
print

मुझे उम्मीद है कि इसे और आगे बढ़ाया जा सकता है (जैसे कि eval<> लिए पूर्व-स्वरूपित इनपुट के साथ, जैसा कि मैं देख रहा हूं कि यह ठीक है (?)), और भी कुछ अन्य चीजें (50 $sigils? नहीं, वे रहेंगे)।

गति, जैसा कि मैंने पहले कहा था, एक मुद्दा हो सकता है (तात्कालिक (नीचे उदाहरण देखें) से बहुत-बहुत लंबे समय तक), इस पर निर्भर करता है कि समाधान पुनरावर्तन वृक्ष पर कहां है, लेकिन इसका उपयोग हार्डवेयर के अप्रचलन का प्रश्न होने दें। मैं बाद में संस्करण को अनुकूलित करूंगा, जिसमें रिकर्सन चला गया और 2-3 अन्य स्पष्ट चालें।

इसे इस तरह चलाया जाता है, STDIN के माध्यम से 3 पंक्तियों को फीड किया जा रहा है:

$ perl bf.pl
7
4 1 2 0 1
A1 B2 C3
xo~o~o~
~x~~~~~
o~xo~o~
~~~o~o~
o~~~~o~
o~~~~~~
o~ooooo

~महासागर है (कलात्मक समाधान, यह नहीं है), o's और xs जहाज और शॉट्स हैं। पहले 5 लाइनों को इनपुट मिलता है और हमारे 'युद्धक्षेत्र' को तैयार करते हैं। $Nआकार है, @Sजहाजों के अनियंत्रित सरणी (जैसे 1 1 1 1 2 3 3 5ऊपर) , और यह अगले पुनरावृत्ति की ओर अग्रसर है। और इसी तरह।$f एक स्ट्रिंग है जो युद्ध के मैदान का प्रतिनिधित्व करता है (नए सिरे से पंक्तियों के साथ पंक्तिबद्ध)। अगला पुनरावर्ती उप-मार्ग है, जो वर्तमान युद्धक्षेत्र राज्य और शेष जहाजों की सूची की अपेक्षा करता है। यह दाएं से बाएं, ऊपर से नीचे तक चेक करता है और प्रत्येक जहाज को क्षैतिज और लंबवत रूप से प्रत्येक स्थिति में रखने की कोशिश करता है (देखें? पकाएं अनुकूलन करने के लिए, लेकिन वह बाद में होगा)। क्षैतिज जहाज स्पष्ट रीजैक्सप रिप्लेसमेंट है, वर्टिकल थोड़ा पेचीदा - 'कॉलम' में बदलने के लिए बिटवाइज़ स्ट्रिंग हेरफेर। सफलता पर (एच, वी या दोनों), नए दुर्गम पदों को चिह्नित किया जाता है!

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

अन्य अनुकूलन हैं: स्ट्रिंग की बहुत शुरुआत से पुनः आरंभ न करना, पहले बड़े जहाजों को रखने की कोशिश करना, समान आकार के जहाज की जाँच न करना यदि पिछले एक ही स्थिति में विफल रहा, + शायद कुछ और (जैसे कोई $&चर आदि)।

$N=<>+0;
$S=[reverse map{(++$-)x$_}<>=~/\d+/g];
$_=<>;
$f=('~'x$N.$/)x$N;
substr($f,$N*$2-$N+$2-66+ord$1,1)=x while/(\w)(\d+)/g;
push@A,$f,0,$S,0;
O:{
    ($f,$i,$S,$m)=splice@A,-4;
    last if!@$S;
    F:{ 
        for$j($m..$#$S){
            next if$j and$$S[$j]==$$S[$j-1];
            $s=$$S[$j];
            my@m;
            $_=$f;
            $n=$s-1;
            pos=$i;
            push@m,$_ if s/\G(?:~.{$N}){$n}~/
                ${^MATCH}&("\0"."\377"x$N)x$s|(o."\0"x$N)x$n.o/pse;
            $_=$f;
            pos=$i;
            push@m,$_ if s/\G~{$s}/o x$s/se;
            if(@m){
                push@A,$f,$i,$S,$j+1;
                my@b=@$S;
                splice@b,$j,1;
                for(@m){
                    for$k(0,$N-1..$N+1){
                        s/(?<=o.{$k})~|~(?=.{$k}o)/!/gs
                    }
                    push@A,$_,$i+1,\@b,0
                }
                redo O
            }
        }
        redo if++$i-length$f
    }
    redo if@A
}
print@$S?'':$f=~y/!/~/r

perl bf+.pl
10
5 4 3 2 1
A1 B2 C3 A10 B9 C10 J1 I2 H3 I9 J10 A5 C5 E5 F6 G7
xooooo~oox
~x~~~~~~x~
ooxooooxo~
~~~~~~~~o~
xoxoxoo~o~
~o~o~x~~o~
~o~o~ox~~~
~~~~~o~ooo
oxo~~~~~x~
x~x~o~o~ox

OTOH, यह अभी भी 6 5 4 3 2 1ऊपर के उदाहरण में असंभव मामले के लिए हमेशा के लिए ले जाता है । हो सकता है कि कुल जहाज टन भार युद्ध के मैदान की क्षमता से अधिक होने पर व्यावहारिक संस्करण तुरंत बाहर निकल जाए।


2

सी # समाधान

  public static class ShipSolution {
    private static int[][] cloneField(int[][] field) {

      int[][] place = new int[field.Length][];

      for (int i = 0; i < field.Length; ++i) {
        place[i] = new int[field.Length];

        for (int j = 0; j < field.Length; ++j)
          place[i][j] = field[i][j];
      }

      return place;

    }

    private static void copyField(int[][] source, int[][] target) {
      for (int i = 0; i < source.Length; ++i)
        for (int j = 0; j < source.Length; ++j)
          target[i][j] = source[i][j];
    }

    // Check if placement a legal one
    private static Boolean isPlacement(int[][] field, int x, int y, int length, Boolean isHorizontal) {
      if (x < 0)
        return false;
      else if (y < 0)
        return false;
      else if (x >= field.Length)
        return false;
      else if (y >= field.Length)
        return false;

      if (isHorizontal) {
        if ((x + length - 1) >= field.Length)
          return false;

        for (int i = 0; i < length; ++i)
          if (field[x + i][y] != 0)
            return false;
      }
      else {
        if ((y + length - 1) >= field.Length)
          return false;

        for (int i = 0; i < length; ++i)
          if (field[x][y + i] != 0)
            return false;
      }

      return true;
    }

    //  When ship (legally) placed it should be marked at the field
    //  2 - ship itself
    //  3 - blocked area where no other ship could be placed
    private static void markPlacement(int[][] field, int x, int y, int length, Boolean isHorizontal) {
      if (isHorizontal) {
        for (int i = 0; i < length; ++i)
          field[x + i][y] = 2;

        for (int i = x - 1; i < x + length + 1; ++i) {
          if ((i < 0) || (i >= field.Length))
            continue;

          for (int j = y - 1; j <= y + 1; ++j)
            if ((j >= 0) && (j < field.Length))
              if (field[i][j] == 0)
                field[i][j] = 3;
        }
      }
      else {
        for (int i = 0; i < length; ++i)
          field[x][y + i] = 2;

        for (int i = x - 1; i <= x + 1; ++i) {
          if ((i < 0) || (i >= field.Length))
            continue;

          for (int j = y - 1; j < y + length + 1; ++j)
            if ((j >= 0) && (j < field.Length))
              if (field[i][j] == 0)
                field[i][j] = 3;
        }
      }
    }

    // Ship placement itteration
    private static Boolean placeShips(int[][] field, int[] ships) {
      int[] vessels = new int[ships.Length];

      for (int i = 0; i < ships.Length; ++i)
        vessels[i] = ships[i];

      for (int i = ships.Length - 1; i >= 0; --i) {
        if (ships[i] <= 0)
          continue;

        int length = i + 1;

        vessels[i] = vessels[i] - 1;

        // Possible placements
        for (int x = 0; x < field.Length; ++x)
          for (int y = 0; y < field.Length; ++y) {
            if (isPlacement(field, x, y, length, true)) {
              int[][] newField = cloneField(field);

              // Mark
              markPlacement(newField, x, y, length, true);

              if (placeShips(newField, vessels)) {
                copyField(newField, field);

                return true;
              }
            }

            if (length > 1)
              if (isPlacement(field, x, y, length, false)) {
                int[][] newField = cloneField(field);

                // Mark
                markPlacement(newField, x, y, length, false);

                if (placeShips(newField, vessels)) {
                  copyField(newField, field);

                  return true;
                }
              }
          }

        return false; // <- the ship can't be placed legally
      }

      return true; //    <- there're no more ships to be placed
    }

    /// <summary>
    /// Solve ship puzzle
    /// </summary>
    /// <param name="size">size of the board</param>
    /// <param name="ships">ships to be placed</param>
    /// <param name="misses">misses in (line, column) format; both line and column are zero-based</param>
    /// <returns>Empty string if there is no solution; otherwise possible ship placement where
    ///   . - Blank place
    ///   * - "miss"
    ///   X - Ship
    /// </returns>
    public static String Solve(int size, int[] ships, String[] misses) {
      int[][] field = new int[size][];

      for (int i = 0; i < size; ++i)
        field[i] = new int[size];

      if (!Object.ReferenceEquals(null, misses))
        foreach (String item in misses) {
          String miss = item.Trim().ToUpperInvariant();

          int x = int.Parse(miss.Substring(1)) - 1;
          int y = miss[0] - 'A';

          field[x][y] = 1;
        }

      if (!placeShips(field, ships))
        return "";

      StringBuilder Sb = new StringBuilder();

      foreach (int[] line in field) {
        if (Sb.Length > 0)
          Sb.AppendLine();

        foreach (int item in line) {
          if (item == 1)
            Sb.Append('*');
          else if (item == 2)
            Sb.Append('X');
          else
            Sb.Append('.');
        }
      }

      return Sb.ToString();
    }
  }

  ...

  int size = 4;
  int[] ships = new int[] { 1, 1, 1 };
  String[] misses = new String[] {"C1", "C2", "B2", "A3", "A1", "B3", "D1"};

  // *X**
  // .**X
  // **.X
  // XX.X
  Console.Out.Write(ShipSolution.Solve(size, ships, misses));

हालांकि यह एक महान और तेज़ समाधान है, लेकिन यह अयोग्य कार्यों को सही ढंग से संभालने के लिए प्रतीत नहीं होता है। उदाहरण के लिए, size=1 ships={1} moves={"A1"}
मन्नीप

मुझे क्षमा करें, मैंने उस स्थिति को याद किया है जब अगले जहाज को कानूनी रूप से नहीं रखा जा सकता है। मैंने समाधान संपादित किया है।
दिमित्री बर्नेंको

6
क्योंकि प्रश्न एक कोड-गोल्फ है , कृपया अपने वर्ण गणना को यथासंभव कम रखने की कोशिश करें (उदाहरण के लिए व्हाट्सएप को हटाकर), और अपने कोड में वर्ण गणना को शामिल करें।
प्रोग्रामफॉक्स

कैरेक्टर काउंट अब जितना है वह 5399 है।
intx13

1

जावा, 1178

हाँ बहुत लंबा है ।_

import java.util.*;class S{public static void main(String[]a){new S();}int a;int[][]f;List<L>l;Stack<Integer>b;S(){Scanner s=new Scanner(System.in);a=s.nextInt();f=new int[a][a];for(int[]x:f)Arrays.fill(x,95);s.next(";");b=new Stack();for(int i=1;s.hasNextInt();i++){b.addAll(Collections.nCopies(s.nextInt(),i));}s.next(";");while(s.findInLine("([A-Z])")!=null)f[s.match().group(1).charAt(0)-65][s.nextInt()-1]=79;l=new ArrayList();for(int i=0;i<a;i++){l.add(new L(i){int g(int c){return g(c,i);}void s(int c,int v){f[c][i]=v;}});l.add(new L(i){int g(int r){return g(i,r);}void s(int r,int v){f[i][r]=v;}});}if(s()){String o="";for(int r=0;r<a;r++){for(int c=0;c<a;c++)o+=(char)f[c][r];o+='\n';}System.out.print(o);}}boolean s(){if(b.empty())return true;int s=b.pop();Integer n=95;for(L c:l){int f=0;for(int x=0;x<a;x++){if(n.equals(c.g(x)))f++;else f=0;if(f>=s){for(int i=0;i<s;i++)c.s(x-i,35);if(s())return true;for(int i=0;i<s;i++)c.s(x-i,n);}}}b.push(s);return false;}class L{int i;L(int v){i=v;}void s(int i,int v){}int g(int i){return 0;}int g(int c,int r){int v=0;for(int x=-1;x<2;x++)for(int y=-1;y<2;y++)try{v|=f[c+x][r+y];}catch(Exception e){}return v&(f[c][r]|32);}}}

Ungolfed:

import java.util.*;

class S {
    public static void main(String[] a) {
        new S();
    }

    /**
     * Number of rows/columns
     */
    int a;

    /**
     * A reference to the full field
     */
    int[][] f;

    /**
     * List of Ls representing all columns/rows
     */
    List<L> l;

    /**
     * Stack of all unplaced ships, represented by their length as Integer
     */
    Stack<Integer> b;

    S() {
        // Read input from STDIN:
        Scanner s = new Scanner(System.in);
        a = s.nextInt();
        f = new int[a][a];
        // initialize field to all '_'
        for(int[] x: f)
            Arrays.fill(x, 95);
        // ; as separator
        s.next(";");
        b = new Stack();
        // Several int to represent ships
        for (int i = 1; s.hasNextInt(); i++) {
            // nCopies for easier handling (empty Stack => everything placed)
            b.addAll(Collections.nCopies(s.nextInt(), i));
        }
        // ; as separator
        s.next(";");
        // find an uppercase letter on this line
        while (s.findInLine("([A-Z])") != null) {
            // s.match.group(1) contains the matched letter
            // s.nextInt() to get the number following the letter
            f[s.match().group(1).charAt(0) - 65][s.nextInt() - 1] = 79;
        }
        // Loop is left when line ends or no uppercase letter is following the current position

        // Now create a List of Lists representing single columns and rows of our field
        l = new ArrayList();
        for (int i = 0; i < a; i++) {
            l.add(new L(i) {
                int g(int c) {
                    return g(c, i);
                }

                void s(int c, int v) {
                    f[c][i] = v;
                }
            });
            l.add(new L(i) {
                int g(int r) {
                    return g(i, r);
                }

                void s(int r, int v) {
                    f[i][r] = v;
                }
            });
        }
        // try to place all ships
        if (s()) {
            // print solution
            String o = "";
            for (int r = 0; r < a; r++) {
                for (int c = 0; c < a; c++) {
                    o += (char) f[c][r];
                }
                o += '\n';
            }
            System.out.print(o);
        }
    }

    /**
     * Try to place all ships
     *
     * @return {@code true}, if a solution is found
     */
    boolean s() {
        if (b.empty()) {
            // no more ships
            return true;
        }
        // take a ship from the stack
        int s = b.pop();
        // 95 is the Ascii-code of _
        Integer n = 95;
        // go over all columns and rows
        for (L c : l) {
            // f counts the number of consecutive free fields
            int f = 0;
            // move through this column/row
            for (int x = 0; x < a; x++) {
                // Is current field free?
                if (n.equals(c.g(x))) {
                    f++;
                } else {
                    f = 0;
                }
                // Did we encounter enough free fields to place our ship?
                if (f >= s) {
                    // enter ship
                    for (int i = 0; i < s; i++) {
                        c.s(x - i, 35);
                    }
                    // try to place remaining ships
                    if (s()) {
                        return true;
                    }
                    // placing remaining ships has failed ; remove ship
                    for (int i = 0; i < s; i++) {
                        c.s(x - i, n);
                    }
                }
            }
        }
        // we have found no place for our ship so lets push it back
        b.push(s);
        return false;
    }

    /**
     * List representing a single row or column of the field.
     * "Abstract"
     */
    class L {
        /**
         * Index of row/column. Stored here as loop-variables can not be final. Used only {@link #g(int)} and {@link #s(int, int)}
         */
        int i;

        L(int v) {
            i = v;
        }

        /**
         * Set char representing the state at the i-th position in this row/column.
         * "Abstract"
         */
        void s(int i, int v) {
        }

        /**
         * Get char representing the state at the i-th position in this row/column.
         * "Abstract"
         *
         * @return {@code '_'} if this and all adjacent field contain no {@code '#'}
         */
        int g(int i) {
            return 0;
        }

        /**
         * Get char representing the state at the position in c-th column and r-th row
         *
         * @return {@code '_'} if this and all adjacent field contain no {@code '#'}
         */
        int g(int c, int r) {
            // v stores the result
            int v = 0;
            // or all adjacent fields
            for (int x = -1; x < 2; x++) {
                for (int y = -1; y < 2; y++) {
                    // ungolfed we should use something like
                    // v |= 0 > c + x || 0 > r + y || c + x >= a || r + y >= a ? 0 : f[c + x][r + y];
                    // but his will do (and is shorter)
                    try {
                        v |= f[c + x][r + y];
                    } catch (Exception e) {
                    }
                }
            }
            // we use '_' (95), 'O' (79), '#' (35). Only 35 contains the 32-bit
            // So we only need the 32-bit of the or-ed-value + the bits of the value directly in this field
            return v & (f[c][r] | 32);
        }

    }
}

नमूना-इनपुट

6 ; 3 2 1 ; A1 A3 B2 C3 D4 E5 F6 B6 E3 D3 F4

नमूना आउटपुट

O###_#
_O____
O_OOO#
#_#O_O
#_#_O#
_O___O

साथ में

  • O शॉट चूक गया
  • # जहाज-भाग
  • _ अगले यहाँ शूट ;-)

Ideone.com पर देखें

इनपुट-हैंडलिंग नंबर / के आसपास रिक्त स्थान की उम्मीद करता है ;और अन्यथा काम नहीं करेगा।

मैं पहले बड़े जहाज रख रहा हूं क्योंकि उनके पास जाने के लिए कम स्थान हैं। आप स्विच करना चाहते हैं, तो छोटे-पहले आप की जगह ले सकता pop()द्वारा remove(0)और push(s)द्वारा add(0,s)भी केवल दो में से एक अभी भी एक वैध कार्यक्रम में परिणाम चाहिए की जगह।

यदि आप जहाजों को एक-दूसरे को छूने की अनुमति देते हैं, तो g(int,int)फ़ंक्शन को काफी सरल या हटाया जा सकता है।

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