%let name=sudoku; filename odsout '.'; /* Some sudoku data from example in ... http://en.wikipedia.org/wiki/Sudoku I number each box in the grid with its x/y coordinate as the x_y_id (the coordinate system starts at the bottom/left) */ data sudoku_data; input x_y_id $ 1-5 number; datalines; 01_01 . 02_01 . 03_01 . 04_01 . 05_01 8 06_01 . 07_01 . 08_01 7 09_01 . 01_02 . 02_02 . 03_02 . 04_02 4 05_02 1 06_02 9 07_02 . 08_02 . 09_02 5 01_03 . 02_03 6 03_03 . 04_03 . 05_03 . 06_03 . 07_03 2 08_03 8 09_03 . 01_04 7 02_04 . 03_04 . 04_04 . 05_04 2 06_04 . 07_04 . 08_04 . 09_04 6 01_05 4 02_05 . 03_05 . 04_05 8 05_05 . 06_05 3 07_05 . 08_05 . 09_05 1 01_06 8 02_06 . 03_06 . 04_06 . 05_06 6 06_06 . 07_06 . 08_06 . 09_06 3 01_07 . 02_07 9 03_07 8 04_07 . 05_07 . 06_07 . 07_07 . 08_07 6 09_07 . 01_08 6 02_08 . 03_08 . 04_08 1 05_08 9 06_08 5 07_08 . 08_08 . 09_08 . 01_09 5 02_09 3 03_09 . 04_09 . 05_09 7 06_09 . 07_09 . 08_09 . 09_09 . ; run; /* Build a graphical sudoku grid (to use in sas/graph gmap)... The small squares are gmap areas. The coordinate system starts in bottom/left. */ %let x_boxes=9; /* how many small boxes in x-direction */ %let y_boxes=9; /* how many small boxes in y-direction */ data sudoku_map; do x_loop=1 to &x_boxes; do y_loop=1 to &y_boxes; x_y_id=trim(left(put(x_loop,z2.)))||'_'||trim(left(put(y_loop,z2.))); /* unique grid id, such as '01_01' */ x=x_loop-.5; y=y_loop-.5; output; /* bottom/left corner */ x=x_loop+.5; y=y_loop-.5; output; /* bottom/right corner */ x=x_loop+.5; y=y_loop+.5; output; /* top/right corner */ x=x_loop-.5; y=y_loop+.5; output; /* top/left corner */ end; end; run; /* Annotate the data (numbers) into the center of each grid box */ proc sql; create table sudoku_centers as select unique x_y_id, avg(x) as x, avg(y) as y from sudoku_map group by x_y_id; create table sudoku_anno as select unique sudoku_data.*, sudoku_centers.x, sudoku_centers.y from sudoku_data left join sudoku_centers on sudoku_data.x_y_id = sudoku_centers.x_y_id; quit; run; data sudoku_anno; set sudoku_anno; xsys='2'; ysys='2'; hsys='3'; when='a'; position='5'; function='label'; style='albany amt/bold'; size=4; text=trim(left(number)); if text='.' then text=' '; run; /* Annotate data set, with heavy/dark gridlines... The coordinate system starts in bottom/left. */ %let x_grid_boxes=3; /* how many big heavy/dark grid boxes in x-direction */ %let y_grid_boxes=3; /* how many big heavy/dark grid boxes in y-direction */ %let units_per_x=3; /* how many small boxes within each big grid box in x-direction */ %let units_per_y=3; /* how many small boxes within each big grid box in y-direction */ data sudoku_grid; xsys='2'; ysys='2'; when='a'; color='black'; size=2; do x2_loop=1 to &x_grid_boxes; do y2_loop=1 to &y_grid_boxes; function='move'; x=x2_loop*&units_per_x+.5; y=y2_loop*&units_per_y+.5; output; /* top/right corner */ function='draw'; x=x2_loop*&units_per_x-&units_per_x+.5; y=y2_loop*&units_per_y+.5; output; /* top/left corner */ x=x2_loop*&units_per_x-&units_per_x+.5; y=y2_loop*&units_per_y-&units_per_y+.5; output; /* bottom/left corner */ x=x2_loop*&units_per_x+.5; y=y2_loop*&units_per_y-&units_per_y+.5; output; /* bottom/right corner */ x=x2_loop*&units_per_x+.5; y=y2_loop*&units_per_y+.5; output; /* top/right corner */ end; end; run; options device=png; goptions xpixels=400 ypixels=425; ODS LISTING CLOSE; ODS HTML path=odsout body="&name..htm" (title="Sudoku Grid") style=sasweb; goptions gunit=pct htitle=5 htext=3 ftitle="albany amt/bold" ftext="albany amt"; pattern v=solid color=white repeat=1000; title1 ls=1.5 "SAS/Graph Sudoku Grid"; proc gmap map=sudoku_map data=sudoku_data anno=sudoku_anno all; id x_y_id; choro number / nolegend coutline=black anno=sudoku_grid /* heavy/dark grid */ des='' name="&name"; run; quit; ODS HTML CLOSE; ODS LISTING;