Python, 607594 characters, -8 with ugly output, +4? for bash invocation
I=int;R=range import sys;a=sys.stdin.readlines()argv S=I(a[0]a[1]);f=[[0]*(S+2)for _ in R(S+2)] C=a[1]C=a[2].split() X=[] for i,n in enumerate(C):X=[i+1]*I(n)+X Q=a[2]Q=a[3].split() for q in Q:f[I(q[1:])][ord(q[0])-64]=1 D=R(-1,2) def V(r,c):return 1-(any(f[r+dr][c+dc]==2for dr in D for dc in D),1,1)[f[r][c]] def P(x,r,c,h,m): for i in R(x):f[(r+i,r)[h]][(c,c+i)[h]]=m 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): if(r+x,c+x)[h]<S+2and all(V((r+i,r)[h],(c,c+i)[h])for i in R(x)):P(x,r,c,h,2);F(X[1:]);P(x,r,c,h,0) F(X)
Note: the indent levels are space, tab, tab + space, and tab + tab. This saves 4 characters from using spaces only and works in Python 2.7 .
Usage and example:
Takes input from stdincommand line arguments. Outputs a blank as a space, a shot as a ., and a @ as part of a ship:
7 4$ python bships_golf.py "7" "4 0 2 0 11" \ A1 "A1 C3 B5 E4 G6 G7 A3 A4 A5 A6 C1 C3 C5 C7 B6 B7 D1 D2 G3
Outputs a blank as a space, a shot as a ., and a @ as part of a ship:
$ python bships_golf.py < bships1.txtG3" 2>X . @ . . @ @ @ @ . . @ . @ @ . . @ . . . . @ @ . . @ . @ . . @ @ .
3 2 A1$ python bships_golf.py "3" "2" "A1 A3 B1 C1 C3C3" B12>X . A2. . @ @ . . $ python bships_golf.py <"3" bships2.txt"2" "A1 A2 A3 B1 C1 C3" 2>X $
I represent the board as a list of lists of integers with size 2 greater than the input, to avoid having to do bounds checking. 0 represents an empty space, 1 a shot, and 2 a ship. I run through the shots list Q and mark all the shots. I convert the list of ships to an explicit list X of ships, e.g. [4, 0, 2, 0, 1] becomes [5, 3, 3, 1, 1, 1, 1]. Then it's a simple backtracking algorithm: in order of descending size order, try to place a ship, and then try to place the rest of the ships. If it doesn't work, try the next slot. As soon as it succeeds, the ship list X is null, and accessing X[0] throws an exception which quits the program. The rest is just heavy golfing (was initially 1615 characters).
Note: the nested for loops are indented with space, tab, tab + space, and tab + tab. This saves 4 characters from using spaces only and works in Python 2.7 .