Output a playable crossword grid Write a program to produce a file containing a crossword grid
that the user can print out and work the puzzle on.

Input

A filename representing a crossword grid file and 
optionally a second filename representing a crossword numbering
file. The input should be accepted by a conventional means for
your programming environment: command line arguments, the standard
input, web forms, etc..

You may assume that the crossword has been validated, and if
using a numbering file that is corresponds to the grid provided.

Grid file format: The first line consists of two white-space
separated integer constants M and N. Following that line are M
lines each consisting of N characters (plus a new line) selected
from [#A-Z ]. These characters are interpreted such that '#'
indicates a blocked square, ' ' a open square in the puzzle
with no known contents and any letter an open square whose
containing that letter.

Numbering file format Lines starting with '#' are ignored and
may be used for comments. All other lines contain a tab separated
triplet i, m, n where i represents a number to be printed
on the grid, and m and n represent the row and column of the
square where it should be printed. The number of both rows and
columns starts at 1.

Output

The output will be a file that the user can print out and work a
crossword on. ASCII, postscript, pdf, png, and any other
reasonable format will be accepted, but all must abide by these
rules:


There must be a rule around the entire puzzle and between
every pair of squares.
Blocked squares must be filled in darkly.
In play square that represent the start of a numbered (across
or down) clue must be provided with a number in the upper,
left corner of the square, while leaving most of the square
blank for the play to write in. Note that typical grid published
in the papers will have many tens of clues and may have more than 
100.


The output will be of the grid alone, without the list of clues.

Output should be sent to a conventional destination (a file whose name 
is derived from the input filename, produced as a web page, etc..)

Test case

Given a input of 

5   5
#  ##
#    
  #  
    #
##  #


the starting corner of an acceptable ASCII output might look like this

+-----+-----+-----+---
|#####|1    |2    |###
|#####|     |     |###
|#####|     |     |###
+-----+-----+-----+---
|#####|3    |     |4  
|#####|     |     |   
|#####|     |     |   
+-----+-----+-----+---
|6    |     |#####|   
|     |     |#####|   


Those using graphical formats should take their inspiration from
the usual printed sources.

Numbering scheme

A correctly numbered grid has the following properties:


Numbering begins at 1.
No column or span of open squares is unnumbered.
Numbers will be encountered in counting order by scanning from
top row to the bottom taking each row from left to right.


Aside

This is the third of several crossword related challenges. I
plan to use a consistent set of file-formats throughout and to
build up a respectable suite of crossword related utilities in
the process. 

Previous challenges in this series:


Crossword numbering
Crossword grid validation
Postscript 905 797 677 675 629 608 330 320 308

{G N}/Times-Roman .3 2 22 1 30/.{&lt;920&gt;dup 1 4 3 roll put cvx 
exec}def/${//. 73 .}def[/R{99&lt;a51f3e7d75&gt;$}/G{&lt;1fab75&gt;$ 
R(uN)${0 R{1(X)$ 0 1 -1 5 4 roll 35 eq{4&lt;1980&gt;$}if&lt;81&gt;$ 
1 add}(I)$(u)$ 0 -1&lt;ad&gt;$}&lt;834d&gt;$}/X{{exit}if}/N{-.9
.7&lt;ad&gt;${&lt;1fab70&gt;$ X}loop{{(&gt;nk)$(  )&lt;31a0&gt;$}&lt;a3&gt;$
X}loop}&gt;&gt;&lt;0d38388b369bad8e3f&gt;$


This program is written as a "protocol prolog" so you just cat it together with the grid and number files (in that order, separated by blank lines) and pipe the whole mess to ghostscript or Distiller or a PS printer. Appended to the reference version below is a NYT puzzle (From Nov. 5, 2011) with numbers and one answer I'm pretty sure of (Saturdays is hard!).

The new revision uses these two procedures to execute binary-encoded
system names from strings.

/.{
    &lt;920&gt;  % two-byte binary-encoded name template with 0x92 prefix
    dup 1 4 3 roll put  % insert number into string
    cvx exec  % and execute it
}def
/${
    //.   %the /. procedure body defined above
    73 .  %"forall" (by code number)
}def


Indented and (somewhat) commented.

/Times-Roman .3 2 22 1 30
/.{&lt;920&gt;dup 1 4 3 roll put cvx exec}def/${//. 73 .}def
[
/R{99&lt;a51f3e7d75&gt;$}    %currentfile 99 string readline pop 
/G{&lt;1fab75&gt;$ %currentfile token pop 
    R (uN)$ %&lt;754e&gt;$ %pop gsave
    {   
        0 R { 
            1 (X)$ %index
            0 1 -1 5 4 roll
            35 eq{ 
                4&lt;1980&gt;$ %copy rectfill
            }if 
            &lt;81&gt;$ %rectstroke
            1 add 
        }(I)$
        (u)$ % 73 . %forall pop 
        0 -1&lt;ad&gt;$ %translate
    }&lt;834d&gt;$ %repeat grestore
}
/X{{exit}if}
/N{
    -.9 .7&lt;ad&gt;$ %translate
    %{ currentfile token not {exit} if } loop
    {&lt;1fab70&gt;$
        X %{exit}if
    }loop
    {   
        %dup type/integertype ne{exit}if
        {
            (&gt;nk)$ %&lt;3e6e6b&gt;$ %exch neg moveto
            (  )&lt;31a0&gt;$ %cvs show
        }&lt;a3&gt;$ %stopped
        X %{exit}if
    }loop
}
&gt;&gt;
&lt;0d38388b369bad8e&gt;$
%begin dup dup scale div setlinewidth translate selectfont
{G N}exec


Data files.

15 15
     #   #     


       #     ##
##   #   #     
    #     #    
   #    #      
       #       
      #    #   
    #     #    
    K#   #   ##
##  I  #       
    L          
    N          
    S#   #     

#i m n   figure(number), row, col
1 1 1
2 1 2
3 1 3
4 1 4
5 1 5
6 1 7
7 1 8
8 1 9
9 1 11
10 1 12
11 1 13
12 1 14
13 1 15
14 2 1
15 2 6
16 2 10
17 3 1
18 4 1
19 4 9
20 5 3
21 5 7
22 5 8
23 5 11
24 5 14
25 5 15
26 6 1
27 6 2
28 6 6
29 6 10
30 6 12
31 7 1
32 7 5
33 7 10
34 7 11
35 8 1
36 8 4
37 8 9
38 9 1
39 9 8
40 9 13
41 10 1
42 10 6
43 10 7
44 10 12
45 11 1
46 11 5
47 11 7
48 11 11
49 12 3
50 12 6
51 12 9
52 12 10
53 12 14
54 12 15
55 13 1
56 13 2
57 13 8
58 14 1
59 15 1
60 15 7
60 15 11


It should look okay from a printer, but on-screen it needs a little help.
This 19-char procedure and 9 chars to invoke it on all user-space points, helps make evenly-spaced lines look more even. So 308 + 19 + 9 = 337, used to generate this image.

/F{&lt;ac893e893e5f&gt;$} % transform round exch round exch itransform




Postscript 608

This earlier version (from revision 8) uses a completely different approach, reusing the main-line code as a "lexicon" from which longer tokens can be indexed using strings.

&lt;&lt;-1{{30 700 translate 0 0 moveto
currentfile 2{(@A1*)*}repeat exch string
3 2 roll{('BO1)*{( )(@#)*
4(,.N:;&lt;%)*&lt;&lt;( ){p}/#{(1:;&gt;%)*}0{(;,'.)*
6 -26(CE%)*}&gt;&gt;(IJ'B)* known not{p
0}if(LG #C)*}forall(#;*1 D%)*}repeat
p/Times-Roman 8 selectfont 99
string{('BO)*{(@)* length(#=)*{p}{(@#L)*
35(=)*{p}{cvx(GID ?'H*ID ?KHF%)*(   )cvs(E)*}e}e}{showpage
exit}e}loop exit{( @#M# FMF#M)*
closepath}currentpoint stroke eq fill
mul dup token copy rmoveto sub show
neg exec add 1 index 9 get rlineto
put readline}loop}0 1 index 0 get{1
index 1 add}forall pop/*{{32 sub load
exec}forall}/e{ifelse}/p{pop}&gt;&gt;begin(23,?4)*&lt;1f&gt;*


It was written using this commented version which illustrates the encoding of the lexicon. The first token 30 is commented space therefore ( )* is a synonym for 30. Not very beneficial for 30, but for longer tokens this is(was) a big win (until deeper encoding possibilities are(were) discovered).

&lt;&lt;-1{{
%space  !    "         # $ %      &amp;           '(        )     %*    +      , - .   %/
 30     700  translate 0 0 moveto currentfile 2{(@A1*)*}repeat exch string 3 2 roll
{('BO1)*{( )(@#)* 4(,.N:;&lt;%)*&lt;&lt;( ){p}/#{(1:;&gt;%)*}0{(;,'.)* 6 -26(CE%)*}&gt;&gt;(IJ'B)*
known not{p 0}if(LG #C)*}forall(#;*1 D%)*}
%0      1   2          3 4          5  6     7
 repeat p /Times-Roman 8 selectfont 99 string{('BO)*{(@)* length(#=)*{p}{
(@#L)* 35(=)*{p}{cvx(GID ?'H*ID ?KHF%)*(   )cvs(E)*}e}e}{showpage clear exit}e}
%8    9   :                         %;            &lt;      =    &gt;    ?
 loop exit{( @#M# FMF#M)* closepath} currentpoint stroke eq fill mul
%@   A     B    C       D   E    F   G    H   I J     K L   M       N   O
 dup token copy rmoveto sub show neg exec add 1 index 9 get rlineto put readline
}loop}0 1 index 0 get{1 index 1 add}forall
pop/*{{32 sub load exec}forall}/e{ifelse}/p{pop}&gt;&gt;begin(23,?4)*&lt;1f&gt;*