크로스 워드 넘버링 파일 이름에서

크로스 워드 그리드의 번호를 올바르게 지정하는 프로그램을 작성하십시오.

입력

입력은 크로스 워드 그리드를 나타내는 파일 이름이됩니다. 입력 파일 이름은 인수, 표준 입력 또는 하드 코딩 이외의 다른 일반적인 수단으로 전달 될 수 있습니다.

그리드 파일 형식 : 텍스트 파일. 첫 번째 줄은 공백으로 구분 된 두 개의 정수 상수 M와로 구성 N됩니다. 그 라인 다음에는 에서 선택된 문자 (및 새로운 라인) M
로 구성된 라인이 N있습니다 [#A-Z ]. 이 문자들은 '#'
차단 된 사각형, ' '알려진 내용이없는 퍼즐의 열린 사각형 및 해당 문자를 포함하는 열린 사각형 을 나타내는 것으로 해석 됩니다.

산출

출력은 번호 매기기 파일이되고 표준 출력, 입력 파일 이름에서 파생 된 파일, 사용자 지정 파일 또는 기타 일반 대상으로 전송 될 수 있습니다.

번호 매기기 파일 형식 텍스트 파일입니다. ‘#’으로 시작하는 줄은 무시되며 주석에 사용될 수 있습니다. 다른 모든 행은 탭 분리 삼중 포함 i, m, 숫자를 그리드 상에 인쇄 될 나타내고, 및 이 인쇄되어야하는 정사각형의 행과 열을 표현한다. 행과 열의 수는 1부터 시작합니다.nimn

번호 체계

올바르게 번호가 매겨진 그리드에는 다음과 같은 속성이 있습니다.

  1. 번호 매기기는 1부터 시작합니다.
  2. 열린 정사각형의 열 또는 스팬은 번호가 없습니다. (문제에 단일 문자 답변이 없다고 가정 할 수 있습니다.)
  3. 왼쪽에서 오른쪽으로 각 행을 가져 가면서 맨 위부터 맨 아래까지 스캔하면 숫자가 순서대로 표시됩니다. 따라서 모든 가로 범위는 맨 왼쪽 정사각형에 번호가 매겨지고 모든 열은 맨 위 정사각형에 번호가 매겨집니다.

테스트 입력 및 예상 출력

입력:

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