Python, 562 characters, -8 with ugly output, +4? for bash invocation
=
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)
Note: the indent levels are space, tab, tab + space, tab + tab, and tab + tab + space. This saves a few characters from using spaces only.
**Usage and example**:
Takes input from command line arguments. Outputs a blank as a space, a shot as a `.`, and a `@` as part of a ship:
$ 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
. @ . . @ @ @
@ .
. @ . @ @ .
. @ .
. . . @ @
. . @ .
@ . . @ @ .
When unsolvable, prints nothing:
$ 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
$
The ` 2>X` is to suppress an error message since the program exits by throwing an exception. Feel free to add a +4 penalty if deemed fair. Otherwise I'd have to do a `try: ... except:0` to suppress it, which would take more characters anyway.
I can also print the output as numbers (`0`, `1`, and `2`) to shave off 8 characters, but I value aesthetics.
**Explanation**:
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).