অলস যুদ্ধের স্থান


39

নিম্নলিখিত দৃশ্যের কল্পনা করুন: আপনি বন্ধুর সাথে যুদ্ধজাহাজ খেলছেন তবে প্রতারণার সিদ্ধান্ত নিন decide আপনার জাহাজটি যেখানে ব্যবহৃত হত সেখানে গুলি চালানোর পরে কোনও জাহাজটিকে সরিয়ে দেওয়ার পরিবর্তে আপনি কোনও জাহাজ একেবারে না রাখার সিদ্ধান্ত নেন। আপনি তাকে বলুন যে তার সমস্ত শটগুলি মিস হয়েছে, যতক্ষণ না এইভাবে জাহাজ স্থাপন করা অসম্ভব হয়।

আপনাকে কোনও ফাংশন বা একটি সম্পূর্ণ প্রোগ্রাম লিখতে হবে যা কোনওভাবে 3 টি যুক্তি লাগে: ক্ষেত্রের আকার, জাহাজের আকারের পরিমাণ এবং শটের একটি তালিকা।

যুদ্ধক্ষেত্র

প্রদত্ত প্যারামিটারগুলির মধ্যে একটি হ'ল বোর্ডের আকার। যুদ্ধক্ষেত্রটি কোষগুলির একটি বর্গক্ষেত্র এবং প্রদত্ত প্যারামিটারটি বর্গক্ষেত্রের একদিকে কেবল।
উদাহরণস্বরূপ, নীচে 5 আকারের একটি বোর্ড রয়েছে।

ক্ষেত্রের স্থানাঙ্কগুলি 2-উপাদান স্ট্রিং হিসাবে নির্দিষ্ট করা হয়: একটি সংখ্যা পরে একটি চিঠি। কোনও বিশেষ ক্ষেত্রে আপনি চিঠিগুলির উপর নির্ভর করতে পারেন।
চিঠিটি কলামটি নির্দিষ্ট করে, নম্বরটি ঘরের সারি নির্দিষ্ট করে (1-ইনডেক্সড)। উপরের ছবিতে উদাহরণস্বরূপ, হাইলাইটেড সেলটি দ্বারা চিহ্নিত করা হয়েছে "D2"
যেহেতু কেবলমাত্র 26 টি অক্ষর রয়েছে তাই ক্ষেত্রটি 26x26 এর চেয়ে বড় হতে পারে না।

জাহাজ

জাহাজগুলি 1 বা ততোধিক ব্লকের সরল রেখা। জাহাজের পরিমাণ একটি তালিকায় নির্দিষ্ট করা হয়েছে, যেখানে প্রথম উপাদানটি হচ্ছে 1-সেল জাহাজের পরিমাণ, দ্বিতীয় - 2-সেল জাহাজের এবং দ্বিতীয়।
উদাহরণস্বরূপ, তালিকাটি [4,1,2,0,1]নিম্নলিখিত শিপসেটটি তৈরি করবে:

যুদ্ধক্ষেত্রে স্থাপন করা হলে, জাহাজগুলি একে অপরকে ছেদ করতে পারে না, এমনকি একে অপরকে স্পর্শও করতে পারে না। এমনকি কোণেও নয়। তারা তবে মাঠের প্রান্তগুলিকে স্পর্শ করতে পারে।
নীচে আপনি বৈধ জাহাজ স্থাপনের একটি উদাহরণ দেখতে পাচ্ছেন:

আপনি ধরে নিতে পারেন যে প্রদত্ত শিপসেটের জন্য, প্রদত্ত আকারের খালি বোর্ডে সর্বদা একটি স্থান উপস্থিত থাকে।

আউটপুট

যদি এই ধরণের জাহাজের স্থান উপস্থিত থাকে তবে আপনাকে সেগুলির কোনও আউটপুট দিতে হবে।
প্রোগ্রামটি 3 টির মধ্যে উভয়েরই এসসিআই অক্ষরের একটি নিউলাইন-বিভক্ত ম্যাট্রিক্স আউটপুট দিতে হয় - একটি ফাঁকা সেল বোঝাতে, একটি - একটি জাহাজের টুকরা, এবং একটি - "মিস" হিসাবে চিহ্নিত একটি ঘর। অন্য কোনও অক্ষরের আউটপুট হওয়া উচিত নয়।
উদাহরণ স্বরূপ,

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

(এই উদাহরণে, আমি @ফাঁকা ঘর, \একটি "মিসড" সেল এবং Zশিপ টুকরা হতে সংজ্ঞায়িত করেছি )

যদি এ জাতীয় কোনও স্থান উপস্থিত না থাকে তবে প্রোগ্রাম / ফাংশনটি কোনও আউটপুট না নিয়েই ফিরে আসা উচিত।

ইনপুট

আপনি যদি একটি ফুলব্লাউন প্রোগ্রাম করার সিদ্ধান্ত নেন, তবে তালিকাগুলি কীভাবে ইনপুট তা আপনাকে নির্দিষ্ট করে দেওয়া উচিত, কেউ কেউ যুক্তি দিয়ে যেতে পারে, কিছু স্টিডিনের মাধ্যমে।

এটি , সর্বনিম্ন পরিমাণে অক্ষরের জয়।

একটি উদাহরণ অ golfed অপ্টিমাইজ সমাধান খুঁজে পাওয়া যেতে পারে এখানে
দিয়ে কম্পাইল -std=c99, প্রথম যুক্তি বোর্ড আকার, অন্যান্য আর্গুমেন্ট জাহাজ মাপ আছে। শটগুলির একটি নতুনলাইন দ্বারা পৃথক তালিকা স্ট্ডিনে দেওয়া হয়। উদাহরণ:
./a 4 1 1 1 <<< $'A2\nA4\nB3\nC3\nC4\D4'


26x26? আমি রেজিএক্সপস এবং পুনরাবৃত্তির উপর ভিত্তি করে একটি সমাধান স্কেচ করেছিলাম এবং এটি ক্ষেত্রের চেয়ে বেশি ধীরে ধীরে = অব্যর্থ 6x6। হয় আমি খুব বোকা কিছু করি, বা উত্তরের অভাবের অর্থ অন্যদেরও সফলতা নেই।
ব্যবহারকারীর 2846289

আমি কেবল সি তে একটি বাস্তবায়ন লিখেছি, এটি কমপক্ষে 10x10একটি 4,3,2,1শিপসেটের সাথে তাত্ক্ষণিকভাবে গণনা করে
mniip

@ এমনিআইপি: আপনার কি হার্ড কেসগুলি মোকাবেলার জন্য কোনও নির্দিষ্ট উপায় রয়েছে (বড় বোর্ড, অনেকগুলি জাহাজ, শটের অবস্থানের কারণে ব্যর্থ হয়েছে)? নাকি এটি কেবল (কিছুটা স্মার্ট) জন্তু শক্তি?
n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳

এর কয়েকটি অপ্টিমাইজেশন রয়েছে, ফে প্রথমে ছোট ছোট জাহাজ রাখার চেষ্টা করে এবং ব্রুট ফোর্স থেকে সমান আকারের অদলবদল বাদ দেয়। যখন ছোট এবং প্রায় খালি বোর্ডে প্রচুর জাহাজ থাকে তখন এটি ধীর গতির হয়।
এমনিপ

@ n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳ আমি একটি উদাহরণ সমাধান লিঙ্ক যুক্ত করেছি।
এমনিআইপি

উত্তর:


2

গল্ফস্ক্রিপ্ট, ২6 characters টি অক্ষর

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.

আহ darn কয়েক ডজন চরিত্র দ্বারা আমাকে মারধর! আমি যদি আর কোনও সংকোচন করতে পারি তা নিশ্চিত নই তবে আমি চেষ্টা চালিয়ে যাচ্ছি ... প্রোলোগের দুর্দান্ত ব্যবহার!
ক্লাদিউ

@ ক্লাডিউ: আমার সমাধানটিতে এখনও 20 বা তার বেশি অক্ষরের একটি "বাফার" রয়েছে। পারফরম্যান্সের কারণে আমি সেই পরীক্ষাগুলি কোডটি সেখানে রেখেছি, তবে নির্ভুলতার কোনও ক্ষতি না করে সেগুলি সরানো যেতে পারে;) অন্য উত্তরগুলি 500 এর নিচে পেলে আমি বিরক্ত করব না।
n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳

5

মতলব - 536 অক্ষর

আপডেট হয়েছে: অনেক ছোট আউটপুট ফর্ম্যাটিং, কিছু লুপ হোয়াইটস্পেস সরানো হয়েছে।

আপডেট হয়েছে: গল্ফ সংস্করণ যুক্ত হয়েছে

আপডেট হয়েছে: মন্তব্য করা সংস্করণ যুক্ত হয়েছে, olf 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 এ হ্রাস করুন here এখানে দেখুন ।
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<>প্রাক-ফর্ম্যাট করা ইনপুট সহ, যেমন আমি দেখছি ঠিক আছে (?)), এবং আরও কিছু জিনিস (৫০ $সিগিল? না, তারা থাকবেন)।

গতি, যেমনটি আমি আগেই বলেছি, সমস্যাটি (তাত্ক্ষণিকভাবে (নীচে উদাহরণটি দেখুন) খুব দীর্ঘ পর্যন্ত) হতে পারে, সমাধানটি পুনরাবৃত্তি গাছের উপর কোথায় রয়েছে তার উপর নির্ভর করে, তবে এটি ব্যবহার করা হার্ডওয়ারের অপ্রচলিত প্রশ্ন হওয়া উচিত। পুনরাবৃত্তি চলে এবং 2-3 অন্যান্য সুস্পষ্ট কৌশল দ্বারা আমি পরে অনুকূলিত সংস্করণ করব।

এটি এভাবে চালানো হয়, এসটিডিএন এর মাধ্যমে 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এর এবং xগুলি জাহাজ এবং শট। প্রথম 5 লাইন ইনপুট পান এবং আমাদের 'যুদ্ধক্ষেত্র' প্রস্তুত করে। $Nআকার, @Sজাহাজগুলির নিবন্ধিত অ্যারে (যেমন 1 1 1 1 2 3 3 5উপরে হিসাবে), $fযুদ্ধক্ষেত্রের প্রতিনিধিত্বকারী একটি স্ট্রিং (নতুন লাইনের সাথে সজ্জিত সারি)। এরপরে রিকার্সিভ সাবরুটাইন যা বর্তমান যুদ্ধক্ষেত্রের রাজ্য এবং অবশিষ্ট জাহাজের তালিকা প্রত্যাশা করে। এটি বাম থেকে ডানে, নীচে থেকে নীচে এবং প্রতিটি জাহাজকে অনুভূমিক এবং উল্লম্বভাবে প্রতিটি অবস্থানে রাখার চেষ্টা করে (দেখুন? অনুকূলিত করার জন্য পাকা, তবে এটি পরে আসবে)। অনুভূমিক জাহাজটি হ'ল সুস্পষ্ট রেজিএক্সপ্লেস প্রতিস্থাপন, উল্লম্ব কিছুটা কৌশলযুক্ত - 'কলামে' প্রতিস্থাপনের জন্য বিটওয়াইস স্ট্রিং ম্যানিপুলেশন। সাফল্যে (এইচ, ভি বা উভয়) নতুন দুর্গম অবস্থানের সাথে চিহ্নিত করা হয়!, এবং এটি পরবর্তী পুনরাবৃত্তির জন্য কাঁটাচামচ করে ইত্যাদি।

সম্পাদনা করুন: ঠিক আছে, এখানে 594 বাইট (যখন আন-ইনডেন্টেড) সংস্করণটি আসলে কার্যকর হওয়ার চেষ্টা করে (অর্থাত্ দ্রুত) - একই কৌশলগুলি বাস্তবায়নের সময় আমার দক্ষতার সেরাটিতে অনুকূলিত - পুনরাবৃত্তি ('ম্যানুয়ালি' হয়ে গেলেও) এবং রিজেক্সপস। এটি একটি 'স্ট্যাক' বজায় রাখে -@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

ওও, 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"},।
mniip

আমি দুঃখিত, যখন পরবর্তী জাহাজটি বৈধভাবে স্থাপন করা যায় না তখন আমি শর্তটি মিস করেছি। আমি সমাধানটি সম্পাদনা করেছি।
দিমিত্রি বাইচেনকো

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 মিস শট
  • # জাহাজ অংশ
  • _ পরের দিকে এখানে অঙ্কুর ;-)

আইডিয়োন.কম এ দেখুন

ইনপুট-হ্যান্ডলিং সংখ্যার কাছাকাছি ফাঁকা স্থানগুলি আশা করে / ;এবং অন্যথায় কাজ করবে না।

তাদের বড় জায়গা কম হওয়ায় আমি প্রথমে বড় জাহাজ রাখছি। আপনি স্যুইচ করতে চান ছোট প্রথম প্রতিস্থাপন করতে পারেন pop()দ্বারা remove(0)এবং push(s)দ্বারা add(0,s)এমনকি মাত্র দুটি এক এখনও একটি বৈধ প্রোগ্রাম ফলে উচিত প্রতিস্থাপন।

আপনি যদি জাহাজগুলিকে একে অপরের সাথে স্পর্শ করার অনুমতি দেন তবে g(int,int)ফাংশনটি ব্যাপকভাবে সরল বা সরানো যেতে পারে।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.