Geben Sie ein spielbares Kreuzworträtselgitter aus

8

Schreiben Sie ein Programm, um eine Datei mit einem Kreuzworträtsel zu erstellen, das der Benutzer ausdrucken und das Puzzle bearbeiten kann.

Eingang

Ein Dateiname, der eine Kreuzworträtsel-Rasterdatei darstellt, und optional ein zweiter Dateiname, der eine Kreuzworträtsel-Nummerierungsdatei darstellt. Die Eingabe sollte auf herkömmliche Weise für Ihre Programmierumgebung akzeptiert werden: Befehlszeilenargumente, Standardeingabe, Webformulare usw.

Sie können davon ausgehen, dass das Kreuzworträtsel validiert wurde und wenn Sie eine Nummerierungsdatei verwenden, die dem bereitgestellten Raster entspricht .

Rasterdateiformat: Die erste Zeile besteht aus zwei durch Leerzeichen getrennten Ganzzahlkonstanten M und N. Nach dieser Zeile befinden sich M Zeilen, die jeweils aus N Zeichen (plus einer neuen Zeile) bestehen [#A-Z ]. Diese Zeichen werden so interpretiert, dass sie '#' ein blockiertes Quadrat, ' 'ein offenes Quadrat im Puzzle ohne bekannten Inhalt und einen Buchstaben ein offenes Quadrat anzeigen, das diesen Buchstaben enthält.

Nummerierung des Dateiformats Zeilen, die mit '#' beginnen, werden ignoriert und können für Kommentare verwendet werden. Alle anderen Zeilen enthalten eine Lasche getrennt Triplett i, m, nwobei ieine Reihe auf dem Raster gedruckt werden soll , darstellt, und mund ndie Zeile und Spalte des Quadrates darstellen , wo sie gedruckt werden sollen. Die Anzahl der Zeilen und Spalten beginnt bei 1.

Ausgabe

Die Ausgabe ist eine Datei, die der Benutzer ausdrucken und mit einem Kreuzworträtsel bearbeiten kann. ASCII, Postscript, PDF, PNG und jedes andere vernünftige Format werden akzeptiert, aber alle müssen diese Regeln einhalten:

  1. Es muss eine Regel für das gesamte Puzzle und zwischen jedem Quadratpaar geben.
  2. Blockierte Quadrate müssen dunkel ausgefüllt werden.
  3. In Spielfeldern, die den Beginn eines nummerierten (quer oder abwärts gerichteten) Hinweises darstellen, muss in der oberen linken Ecke des Quadrats eine Zahl angegeben werden, während der größte Teil des Quadrats leer bleibt, damit das Spiel darin schreiben kann. Beachten Sie das typische Raster In den Zeitungen veröffentlichte werden viele Dutzend Hinweise haben und können mehr als 100 haben.

Die Ausgabe erfolgt ausschließlich über das Raster ohne die Liste der Hinweise.

Die Ausgabe sollte an ein herkömmliches Ziel gesendet werden (eine Datei, deren Name vom Eingabedateinamen abgeleitet ist, die als Webseite erstellt wurde usw.)

Testfall

Bei einer Eingabe von

5   5
#  ##
#    
  #  
    #
##  #

Die Startecke einer akzeptablen ASCII-Ausgabe könnte folgendermaßen aussehen

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

Wer grafische Formate verwendet, sollte sich von den üblichen gedruckten Quellen inspirieren lassen.

Nummerierungsschema

Ein korrekt nummeriertes Raster hat die folgenden Eigenschaften:

  1. Die Nummerierung beginnt bei 1.
  2. Keine Spalte oder Spanne offener Quadrate ist nicht nummeriert.
  3. Zahlen werden in Zählreihenfolge gefunden, indem von der oberen bis zur unteren Reihe gescannt wird, wobei jede Reihe von links nach rechts genommen wird.

Beiseite

Dies ist die dritte von mehreren Kreuzworträtselherausforderungen. Ich plane, durchgehend eine konsistente Reihe von Dateiformaten zu verwenden und dabei eine seriöse Suite von Kreuzworträtsel-bezogenen Dienstprogrammen aufzubauen.

Frühere Herausforderungen in dieser Reihe:

dmckee --- Ex-Moderator Kätzchen
quelle
Ich kann nichts dazu sagen, aber die Beispielausgabe verstößt gegen Ihr eigenes Nummerierungsschema.
Megan Walker
@ Samuel: So ist es auch. Das bekomme ich, wenn ich es von Hand schreibe, anstatt auf meine eigene Arbeit zurückzublicken. Vielen Dank. Korrigiert.
dmckee --- Ex-Moderator Kätzchen

Antworten:

4

Python, 379 Zeichen

import sys
A=sys.argv
f=open(A[1])
V,H=map(int,f.readline().split())
M={}
if A[2:]:
 for r in open(A[2]).readlines():n,y,x=map(int,r.split());M[y*H+y+x]=n
R='+-----'*H+'+'
n,v,s='\n| '
x=y=z=''
p=V+1
for c in n+''.join(f):
 if c==n:print x+n+y+n+z+n+R;x=y=z=''
 elif'@'>c:x+=5*c;y+=5*c;z+=5*c
 else:x+=5*s;y+=s+s+c+s+s;z+=5*s
 if p in M:x=x[:-5]+"%-5d"%M[p]
 x+=v;y+=v;z+=v;p+=1
Keith Randall
quelle
Funktioniert gut, solange die Nummerierungsdatei keine Kommentare enthält.
dmckee --- Ex-Moderator Kätzchen
Sie können next(f)anstelle von verwenden f.readline(). Das brauchst du da überhaupt nicht .readlines().
Gnibbler
10

Nachsatz 905 797 677 675 629 608 330 320 308

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

Dieses Programm ist als "Protokoll-Prolog" geschrieben, sodass Sie es einfach zusammen mit den Raster- und Zahlendateien (in dieser Reihenfolge, durch Leerzeilen getrennt) zusammenfassen und das gesamte Durcheinander an Ghostscript oder Distiller oder einen PS-Drucker weiterleiten. An die unten stehende Referenzversion ist ein NYT-Puzzle (ab 5. November 2011) mit Zahlen und einer Antwort angehängt, deren ich mir ziemlich sicher bin (Samstage sind schwer!).

Die neue Revision verwendet diese beiden Prozeduren, um binär codierte Systemnamen aus Zeichenfolgen auszuführen.

/.{
    <920>  % 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

Eingedrückt und (etwas) kommentiert.

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

Datei.

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

Auf einem Drucker sollte es in Ordnung aussehen, aber auf dem Bildschirm braucht es ein wenig Hilfe. Diese Prozedur mit 19 Zeichen und 9 Zeichen zum Aufrufen an allen Punkten im Benutzerbereich trägt dazu bei, dass Linien mit gleichmäßigem Abstand gleichmäßiger aussehen. Also 308 + 19 + 9 = 337, verwendet, um dieses Bild zu erzeugen.

/F{<ac893e893e5f>$} % transform round exch round exch itransform

Kreuzworträtselausgabe

Postscript 608

Diese frühere Version (aus Revision 8 ) verwendet einen völlig anderen Ansatz und verwendet den Hauptzeilencode als "Lexikon", aus dem längere Token mithilfe von Zeichenfolgen indiziert werden können.

<<-1{{30 700 translate 0 0 moveto
currentfile 2{(@A1*)*}repeat exch string
3 2 roll{('BO1)*{( )(@#)*
4(,.N:;<%)*<<( ){p}/#{(1:;>%)*}0{(;,'.)*
6 -26(CE%)*}>>(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}>>begin(23,?4)*<1f>*

Es wurde mit dieser kommentierten Version geschrieben, die die Codierung des Lexikons veranschaulicht. Das erste Token 30wird kommentiert und ist spacedaher ( )*ein Synonym für 30. Nicht sehr vorteilhaft für 30, aber für längere Token ist (war) dies ein großer Gewinn (bis tiefere Codierungsmöglichkeiten entdeckt wurden (wurden)).

<<-1{{
%space  !    "         # $ %      &           '(        )     %*    +      , - .   %/
 30     700  translate 0 0 moveto currentfile 2{(@A1*)*}repeat exch string 3 2 roll
{('BO1)*{( )(@#)* 4(,.N:;<%)*<<( ){p}/#{(1:;>%)*}0{(;,'.)* 6 -26(CE%)*}>>(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   :                         %;            <      =    >    ?
 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}>>begin(23,?4)*<1f>*
luser droog
quelle
1
Sie müssen nicht alle alten Versionen behalten, da die Benutzer auf den Verlauf des Beitrags zugreifen können, wenn sie wirklich interessiert sind.
Peter Taylor
Verstanden. Ich werde etwas Fett abschneiden, wenn ich aktualisiere.
Luser Droog
Ich habe einige alternative Versionen in diesem Thread gepostet .
Luser Droog
Aufruf funktioniert wie?
Benutzer unbekannt
1
Scheint, dass der Overhead für das PostScript im Golfstil immer noch größer ist als meine "traditionelle" Lösung ;-).
Thomas W.
4

C (Ausgabe an SVG), 553 Zeichen

Ich weiß, der Code ist riesig, aber dieses Problem verlangt nur nach einer SVG-Antwort.

char*f,b[99];h,w;main(i){fscanf(f=fopen(gets(b),"r"),"%d%d%*[\n]",&h,&w);for(
printf("<svg xmlns='http://www.w3.org/2000/svg' viewBox='.9 .9 %d.2 %d.2'><path d='M1 1",
i=w,h);i--;)printf("v%dv-%dh1",h,h);for(;h--;)printf("v1h-%dh%d",w,w);for(
puts("' style='fill:none;stroke:#000;stroke-width:.04'/><path d='");
fgets(b,99,f);++h)for(i=0;i<w;)b[i++]-35||printf("M%d %dh1v1h-1Z",i,h+2);puts("'/>");
for(f=fopen(gets(b),"r");fgets(b,99,f);)sscanf(b,"%d%d%d",&i,&h,&w)>2&&
printf("<text x='%d.1' y='%d.3' style='font-size:.3px'>%d</text>",w,h,i);puts("</svg>");}

Beim Ausführen werden die beiden Dateinamen in zwei separaten Zeilen der Standardeingabe angezeigt. zuerst die Rasterdatei, dann die Zahlendatei.

Die Logik in diesem ist eigentlich ganz einfach. Das Format der SVG ermöglicht es, alle Elemente in beliebiger Reihenfolge zu erstellen (anstatt wie bei der ASCII-Ausgabelösung von oben nach unten zu gehen). Die Größe ist fast ausschließlich auf SVG Boilerplate zurückzuführen.

Aber das resultierende Bild sieht gut aus!

Bearbeitet, um hinzuzufügen: Hier ist eine kürzere Version (517 Zeichen), die mit einer bestimmten Auflösung ausgegeben wird. Dadurch kann der Code mehr Standardeinstellungen verwenden, jedoch zu den (meiner Meinung nach) unerschwinglichen Kosten, die die SVG-Größe in Ihrem Webbrowser nicht mehr automatisch ändert.

char*f,b[99];h,w;main(i){fscanf(f=fopen(gets(b),"r"),"%d%d%*[\n]",&h,&w);for(
printf("<svg xmlns='http://www.w3.org/2000/svg'><path d='M1 1",i=w,h);i--;)
printf("v%d0v-%d0h50",h*5,h*5);for(;h--;)printf("v50h-%d0h%d0",w*5,w*5);for(
puts("' style='fill:none;stroke:#000'/><path d='");fgets(b,99,f);++h)
for(i=-1;++i<w;)b[i]-35||printf("M%d1 %d1h50v50h-50Z",i*5,h*5+5);puts("'/>");
for(f=fopen(gets(b),"r");fgets(b,99,f);)sscanf(b,"%d%d%d",&i,&h,&w)>2&&
printf("<text x='%d3' y='%d5'>%d</text>",w*5-5,h*5-4,i);puts("</svg>");}
Brot-Box
quelle
Die SVG sieht gut aus!
Benutzer unbekannt
3

Haskell, 328 Zeichen

import System
main=do(g:d)<-mapM(fmap lines.readFile)=<<getArgs;mapM_ putStrLn$g% \i k->[t|x<-d,y@(c:_)<-x,c/='#',(t,q)<-lex y,w q==i,k<1]
(s:g)%n=[q|(i,x)<-e g,q<-b s:[c['|':f#n[i,j]k|(j,f)<-e x]++"|"|k<-[0..2]]]++[b s]
'#'#_="#####";_#n=take 5$c n++"     ";b n='+':([1..w n!!1]>>"-----+")
e=zip[1..];c=concat;w=map read.words
Hammar
quelle
2

C 375 Zeichen

char b[99];g[999],*r=g,*f,i,j,w;main(n){
for(fscanf(f=fopen(gets(b),"r"),"%*d%d%*[\n]",&w);fgets(b,99,f);)
for(i=0;i<w;)*r++=-(b[i++]==35);
for(f=fopen(gets(b),"r");fgets(b,99,f);)
sscanf(b,"%d%d%d",&n,&j,&i)?g[j*w-w+i-1]=n:0;
for(f=g;f<=r;f+=w){for(i=w;i--;)printf(" ----");puts("");
if(f<r)for(j=3;j--;puts("|"))
for(i=0;i<w;printf(~n?n&&j>1?"|%-4d":"|    ":"|////",n))n=f[i++];}}

Die beiden Eingabedateinamen werden bei der Standardeingabe jeweils in einer separaten Zeile eingegeben. Das Raster wird bei Standardausgabe in ASCII gerendert. Ja, es ist eine miese Benutzeroberfläche, aber alles, was besser ist, kostet Charaktere. Ich habe es so aufgerufen:

printf "%s\n%s" grid.txt numbering.txt | ./crosswd-render > render.txt

Das Programm sollte beispielsweise kommentierte Zeilen in der Nummerierungsdatei korrekt verarbeiten.

Brot-Box
quelle
*r++-=b[i++]==35( gwird auf Nullen initialisiert).
Ugoren
for(j=3*(f<r);j--;puts("|"))spart if.
Ugoren
n&&j>1->j/2*n
ugoren
2

Scala 463, Ausgabeformat: HTML

object H extends App{val z=readLine.split("[ ]+")map(_.toInt-1)
val d="\t\t<td width='50' height='50'"
println("<html><table border='1'><tr>")
val b=(0 to z(0)).map{r=>readLine}
var c=0
(0 to z(0)).map{
y=>(0 to z(1)).map{
x=>if(b(y)(x)==' '&&((x==0||b(y)(x-1)==35)||(y==0||b(y-1)(x)==35))){
c+=1
println(d+"valign='top'>"+c+"</td>")}
else println(d+{if(b(y)(x)!=' ')"bgcolor='#0'>"else">&nbsp;"}+"</td>")}
println("\t</tr>\n\t<tr>")}
println("</table></html>")
}

Beispielausgabe

Benutzer unbekannt
quelle
Sehr hübsch. Die Ausgabe sieht einfach gut aus .
dmckee --- Ex-Moderator Kätzchen
2

Nachsatz (435) (434)

[/r{currentfile 999 string readline pop}/p{pop}/x{exch}/T{translate}/S{scale}/G{gsave}/R{grestore}/_( )>>begin/Courier 1 selectfont 
20 20 S
.05 setlinewidth{r token
p x p
dup 3 x 3 add
T
G G{R
0 -1 T
G
_ 0
r{0 0 1 1
4 index 35 eq{rectfill p}{rectstroke
put
.3 .1 moveto
_ show}ifelse
1 0 T _ 0}forall}repeat
R R
1 -1 S -.9 -.7 T{{r
dup 0 get 35 ne{( )search
p 3 2 roll
cvx exec
G
x
T
.4 -.4 S
0 0 moveto show
p
R}if}loop}stopped}exec

Nicht mit Golf gespielt:

%!
<<
  /r{currentfile 999 string readline pop}
  /p{pop}
  /x{exch}
  /T{translate}
  /S{scale}
  /G{gsave}
  /R{grestore}
  /_( )
>>begin
/Courier 1 selectfont
% In theory, 20 20 scale isn't needed, 
% but it would make the whole thing very tiny when printed
% (on screen it doesn't matter too much, it can be zoomed)
20 20 S
.05 setlinewidth
{ % exec
% Read number of lines
r token                          % restString numberOfLines true
% Discard rest of line (Contains number of columns.
% It becomes clear implicitly from number of letters in a line of grid definition)
p x p                            % numberOfLines
% Move to where the top line starts
dup 3 x 3 add                    % numberOfLines x y
T                                % numberOfLines
G G
{ %repeat
  R
  % Move to next line
  0 -1 T
  G
  _ 0
  r                              % ( ) 0 line
  { %forall                      % ( ) 0 char
    0 0 1 1                      % ( ) 0 char 0 0 x y
    % Check whether char is a hash
    4 index 35 eq{ %ifelse
      4 copy rectfill
    }if
    rectstroke                   % ( ) 0 char
    put                          % -/-
    .3 .1 moveto
    _ show
    1 0 T
    _ 0                          % ( ) 0
  }forall                        % 
}repeat
R R
% Now, render the numbers according to the numbering definitions
1 -1 S -.9 -.7 T
{{
  r
  %Check whether this is a comment
  dup 0 get 35 ne{               % line
    % Split at the first tab
    %TODO: Ust tab instead of space
    ( )search                    % (y x) tab number true
    p 3 2 roll                   % tab number (y x)
    cvx exec                     % tab number y x
    G
    x                            % tab number x y
    T                            % tab number
    .4 -.4 S
    0 0 moveto show              % tab
    % This pop can be eliminated in theory to save two characters,
    % but the operand stack will continue to grow
    p
    R
  }if
}loop}stopped
}exec
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
Thomas W.
quelle
Genial. Ich muss es wirklich besser nutzen stopped. ... Ich werde das Kopfgeld für einen Tag offen lassen, um Aufmerksamkeit zu erregen.
Luser Droog
1

Nachtrag, nicht kämpfend.

Inspiriert (noch einmal) von Ihrer verwandten Frage zu SO , habe ich eine Referenzversion in Postscript mit file-IO erstellt. Außerdem wird eine abgeleitete Schriftart mit fester Breite erstellt, sodass die Rasterdaten einfach an übergeben werden show. ist eine leere Box und #ist eine gefüllte Box. Jedes andere ASCII-Zeichen wird als kleines, malerisch-römisches Symbol gezeichnet, das von einer Box umgeben ist.

Dieses Programm verwendet eine Ghostscript-Funktion, die möglicherweise nicht in allen Postscript-Interpreten vorhanden ist. Wenn Ghostscript mit dieser --Option aufgerufen wird , werden Befehlszeilenargumente in einem Array von Zeichenfolgen mit dem Namen / ARGUMENTS an das Postscript-Programm übergeben. Sie müssen das Programm also so aufrufen gs -- xw-io.ps grid-file number-file.

%!

ARGUMENTS{}forall
/numfile exch (r) file def
/gridfile exch (r) file def

/q{0 0 moveto 1 0 lineto 1 1 lineto 0 1 lineto closepath}def
/X<</FontType 3/FontBBox[0 0 1 1]/FontMatrix[1 0 0 1 0 0]
    /Encoding StandardEncoding
    /BuildChar{
        1 0 0 0 1 1 setcachedevice
        .001 setlinewidth
        q stroke
        dup 35 eq { pop
            q fill
        }{
            .3 .1 moveto
            .1 .1 scale
            /Times-Roman 8 selectfont
            (?)dup 0 4 3 roll put show
        }ifelse pop}
>>definefont pop /X 30 selectfont
40 700 moveto {
    gridfile 2{dup token pop exch}repeat pop pop
    {
        gridfile =string readline{
            dup length 0 ne{
                show currentpoint exch pop 30 sub 40 exch moveto
            }{clear exit}ifelse
        }{clear exit}ifelse
    }loop
    /Times-Roman 8 selectfont
    {
        40 700 moveto
        numfile =string readline{
            dup length 0 ne{
                dup 0 get 35 ne{
                    cvx exec
                    1 sub 30 mul 2 add exch
                    1 sub -30 mul 22 add rmoveto
                    (   )cvs show
                }{clear}ifelse
            }{clear}ifelse
        }{clear exit}ifelse
    }loop showpage
}exec
luser droog
quelle
Sieht großartig aus. Wie groß ist es? Ich zähle 1247 Zeichen. Aber es kann Golf gespielt werden - nicht wahr? Eine einfache Übersetzung 4 Leerzeichen => 1 Tab führt zu 980 Zeichen, wodurch alle Tabs zu 891 entfernt werden.
Benutzer unbekannt
Aufgrund all der speziellen Wörter, die zum Erstellen einer Schriftart benötigt werden, kann diese nicht kleiner gemacht werden als meine andere Postscript-Antwort.
Luser Droog