크로스 워드 그리드의 번호를 올바르게 지정하는 프로그램을 작성하십시오.
입력
입력은 크로스 워드 그리드를 나타내는 파일 이름이됩니다. 입력 파일 이름은 인수, 표준 입력 또는 하드 코딩 이외의 다른 일반적인 수단으로 전달 될 수 있습니다.
그리드 파일 형식 : 텍스트 파일. 첫 번째 줄은 공백으로 구분 된 두 개의 정수 상수 M
와로 구성 N
됩니다. 그 라인 다음에는 에서 선택된 문자 (및 새로운 라인) M
로 구성된 라인이 N
있습니다 [#A-Z ]
. 이 문자들은 '#'
차단 된 사각형, ' '
알려진 내용이없는 퍼즐의 열린 사각형 및 해당 문자를 포함하는 열린 사각형 을 나타내는 것으로 해석 됩니다.
산출
출력은 번호 매기기 파일이되고 표준 출력, 입력 파일 이름에서 파생 된 파일, 사용자 지정 파일 또는 기타 일반 대상으로 전송 될 수 있습니다.
번호 매기기 파일 형식 텍스트 파일입니다. ‘#’으로 시작하는 줄은 무시되며 주석에 사용될 수 있습니다. 다른 모든 행은 탭 분리 삼중 포함 i
, m
, 숫자를 그리드 상에 인쇄 될 나타내고, 및 이 인쇄되어야하는 정사각형의 행과 열을 표현한다. 행과 열의 수는 1부터 시작합니다.n
i
m
n
번호 체계
올바르게 번호가 매겨진 그리드에는 다음과 같은 속성이 있습니다.
- 번호 매기기는 1부터 시작합니다.
- 열린 정사각형의 열 또는 스팬은 번호가 없습니다. (문제에 단일 문자 답변이 없다고 가정 할 수 있습니다.)
- 왼쪽에서 오른쪽으로 각 행을 가져 가면서 맨 위부터 맨 아래까지 스캔하면 숫자가 순서대로 표시됩니다. 따라서 모든 가로 범위는 맨 왼쪽 정사각형에 번호가 매겨지고 모든 열은 맨 위 정사각형에 번호가 매겨집니다.
테스트 입력 및 예상 출력
입력:
5 5
# ##
#
#
#
## #
출력 (주석 무시) :
1 1 2
2 1 3
3 2 2
4 2 4
5 2 5
6 3 1
7 3 4
8 4 1
9 4 3
10 5 3
곁에
이것은 여러 낱말 관련 문제가되기를 희망하는 첫 번째 것입니다. 전체적으로 일관된 파일 형식 집합을 사용하고 프로세스에서 적절한 크로스 워드 관련 유틸리티 제품군을 구축 할 계획입니다. 예를 들어, 다음 퍼즐은이 퍼즐의 입력과 출력을 기반으로 크로스 워드의 ASCII 버전을 인쇄해야합니다.
답변
루비 – (210) 139 자
o=0
(n=(/#/=~d=$<.read.gsub("
",S='#'))+1).upto(d.size-1){|i|d[i]!=S&&(i<n*2||d[i-1]==S||d[i-n]==S)&&print("%d\t%d\t%d
"%[o+=1,i/n,i%n+1])}
루비 1.9로 테스트되었습니다.
답변
PHP-175 자
<?for($i=$n=strpos($d=strtr(`cat $argv[1]`,"\n",$_="#"),$_)+$o=1;isset($d[$i]);++$i)$d[$i]!=$_&($i<$n*2|$d[$i-1]==$_|$d[$i-$n]==$_)&&printf("%d\t%d\t%d\n",$o++,$i/$n,$i%$n+1);
답변
파이썬 194 개 177 176 172 문자
f=open(raw_input())
V,H=map(int,next(f).split())
p=W=H+2
h='#'
t=W*h+h
n=1
for c in h.join(f):
t=t[1:]+c;p+=1
if'# 'in(t[-2:],t[::W]):print"%d\t%d\t%d"%(n,p/W,p%W);n+=1
답변
++ C 270 264 260 256 253 CHAR
#include<string>
#include<iostream>
#define X cin.getline(&l[1],C+2)
using namespace std;int main(){int r=0,c,R,C,a=0;cin>>R>>C;string l(C+2,35),o(l);X;for(;++r<=R;o=l)for(X,c=0;++c<=C;)if(l[c]!=35&&(l[c-1]==35||o[c]==35))printf("%d %d %d\n",++a,r,c);}
쓰다:
g++ cross.cpp -o cross
cat puzzle | cross
멋진 형식 :
#include<string>
#include<iostream>
// using this #define saved 1 char
#define X cin.getline(&l[1],C+2)
using namespace std;
int main()
{
int r=0,c,R,C,a=0;
cin>>R>>C;
string l(C+2,35),o(l);
X;
for(;++r<=R;o=l)
for(X,c=0;++c<=C;)
if(l[c]!=35&&(l[c-1]==35||o[c]==35))
printf("%d %d %d\n",++a,r,c);
}
한 번에 전체 낱말을 읽고 단일 루프를 사용하려고했습니다.
그러나 ‘\ n 문자를 보상하는 데 드는 비용이 어떤 이익보다 뛰어났습니다.
#include <iostream>
#include <string>
#define M cin.getline(&l[C+1],R*C
using namespace std;
int main()
{
int R,C,a=0,x=0;
cin>>R>>C;
string l(++R*++C,35);
M);M,0);
for(;++x<R*C;)
if ((l[x]+=l[x]==10?25:0)!=35&&(l[x-1]==35||l[x-C]==35))
printf("%d %d %d\n",++a,x/C,x%C);
}
압축 : 260 자
#include<iostream>
#include<string>
#define M cin.getline(&l[C+1],R*C
using namespace std;int main(){int R,C,a=0,x=0;cin>>R>>C;string l(++R*++C,35);M);M,0);for(;++x<R*C;)if((l[x]+=l[x]==10?25:0)!=35&&(l[x-1]==35||l[x-C]==35))printf("%d %d %d\n",++a,x/C,x%C);}
답변
C, 184 개 (189) 문자
char*f,g[999],*r=g;i,j,n;main(w){
for(fscanf(f=fopen(gets(g),"r"),"%*d%d%*[\n]",&w);fgets(r,99,f);++j)
for(i=0;i++<w;++r)
*r==35||j&&i>1&&r[-w]-35&&r[-1]-35||printf("%d\t%d\t%d\n",++n,j+1,i);}
말할 것도 많지 않습니다. 논리는 꽤 기본입니다. 프로그램은 런타임시 표준 입력에서 파일 이름을 사용합니다. (프로그램이 파일 이름으로 작업해야하고 표준 입력에서 직접 파일 내용을 읽을 수는 없어서 성가신 일입니다. 그러나 파이퍼를 지불하는 사람은 노래를 부릅니다!)
이상한 fscanf()
패턴은 줄 바꿈을 포함하여 첫 줄 전체를 스캔하려고하지만 다음 줄의 선행 공백은 포함 하지 않습니다 . 아무도 사용하지 않는 이유가 scanf()
있습니다.
답변
참조 구현 :
c99 ungolfed 및 다양한 디버깅 frobs를 포함하여 2000 개 이상의 문자가 여전히 있습니다.
#include <stdio.h>
#include <string.h>
void printgrid(int m, int n, char grid[m][n]){
fprintf(stderr,"===\n");
for (int i=0; i<m; ++i){
for (int j=0; j<n; ++j){
switch (grid[i][j]) {
case '\t': fputc('t',stderr); break;
case '\0': fputc('0',stderr); break;
case '\n': fputc('n',stderr); break;
default: fputc(grid[i][j],stderr); break;
}
}
fputc('\n',stderr);
}
fprintf(stderr,"===\n");
}
void readgrid(FILE *f, int m, int n, char grid[m][n]){
int i = 0;
int j = 0;
int c = 0;
while ( (c = fgetc(f)) != EOF) {
if (c == '\n') {
if (j != n) fprintf(stderr,"Short input line (%d)\n",i);
i++;
j=0;
} else {
grid[i][j++] = c;
}
}
}
int main(int argc, char** argv){
const char *infname;
FILE *inf=NULL;
FILE *outf=stdout;
/* deal with the command line */
switch (argc) {
case 3: /* two or more arguments. Take the second to be the output
filename */
if (!(outf = fopen(argv[2],"w"))) {
fprintf(stderr,"%s: Couldn't open file '%s'. Exiting.",
argv[0],argv[2]);
return 2;
}
/* FALLTHROUGH */
case 2: /* exactly one argument */
infname = argv[1];
if (!(inf = fopen(infname,"r"))) {
fprintf(stderr,"%s: Couldn't open file '%s'. Exiting.",
argv[0],argv[1]);
return 1;
};
break;
default:
printf("%s: Number a crossword grid.\n\t%s <grid file> [<output file>]\n",
argv[0],argv[0]);
return 0;
}
/* Read the grid size from the first line */
int m=0,n=0;
char lbuf[81];
fgets(lbuf,81,inf);
sscanf(lbuf,"%d %d",&m,&n);
/* Intialize the grid */
char grid[m][n];
for(int i=0; i<m; ++i) {
for(int j=0; j<n; ++j) {
grid[i][j]='#';
}
}
/* printgrid(m,n,grid); */
readgrid(inf,m,n,grid);
/* printgrid(m,n,grid); */
/* loop through the grid produce numbering output */
fprintf(outf,"# Numbering for '%s'\n",infname);
int num=1;
for (int i=0; i<m; ++i){
for (int j=0; j<n; ++j){
/* fprintf(stderr,"\t\t\t (%d,%d): '%c' ['%c','%c']\n",i,j, */
/* grid[i][j],grid[i-1][j],grid[i][j-1]); */
if ( grid[i][j] != '#' &&
( (i == 0) || (j == 0) ||
(grid[i-1][j] == '#') ||
(grid[i][j-1] == '#') )
){
fprintf(outf,"%d\t%d\t%d\n",num++,i+1,j+1);
}
}
}
fclose(outf);
return 0;
}
답변
PerlTeX : 1143 자 (그러나 나는 아직 골프를 치지 않았다)
\documentclass{article}
\usepackage{perltex}
\usepackage{tikz}
\perlnewcommand{\readfile}[1]{
open my $fh, '<', shift;
($rm,$cm) = split /\s+/, scalar <$fh>;
@m = map { chomp; [ map { /\s/ ? 1 : 0 } split // ] } <$fh>;
return "";
}
\perldo{
$n=1;
sub num {
my ($r,$c) = @_;
if ($r == 0) {
return $n++;
}
if ($c == 0) {
return $n++;
}
unless ($m[$r][$c-1] and $m[$r-1][$c]) {
return $n++;
}
return;
}
}
\perlnewcommand{\makegrid}[0]{
my $scale = 1;
my $return;
my ($x,$y) = (0,$r*$scale);
my ($ri,$ci) = (0,0);
for my $r (@m) {
for my $open (@$r) {
my $f = $open ? '' : '[fill]';
my $xx = $x + $scale;
my $yy = $y + $scale;
$return .= "\\draw $f ($x,$y) rectangle ($xx,$yy);\n";
my $num = $open ? num($ri,$ci) : 0;
if ( $num ) {
$return .= "\\node [below right] at ($x, $yy) {$num};";
}
$x += $scale;
$ci++;
}
$ci = 0;
$x = 0;
$ri++;
$y -= $scale;
}
return $return;
}
\begin{document}
\readfile{grid.txt}
\begin{tikzpicture}
\makegrid
\end{tikzpicture}
\end{document}
grid.txt
스펙으로 호출 된 파일이 필요합니다.
perltex --nosafe --latex=pdflatex grid.tex