크로스 워드 넘버링


9

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

입력

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

그리드 파일 형식 : 텍스트 파일. 첫 번째 줄은 공백으로 구분 된 두 개의 정수 상수 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 버전을 인쇄해야합니다.


단일 문자 범위는 번호가 매겨지지 않습니다.
— Keith Randall

@Kieth : 그러한 범위가없는 규칙을 선호하지만 그리드 유효성 검사가 다른 문제로 계획되어 있기 때문에 여기서 지정하지 않았습니다. 나는 당신이 사용하는 것이 맛의 문제라고 생각합니다.
— dmckee --- 전 운영자 고양이

입력 파일은 txt로되어 있습니까?
— www0z0k

@ www0z0k : 그렇습니다. 내 유닉스 괴짜는 항상 기본 텍스트입니다.
— dmckee --- 전 운영자 고양이

1
@ www0z0k : 줄 바꿈은 플랫폼에서 기본이되는 것입니다. 그것은 내 ASCII 10 진수 20이며 '\n'모든 플랫폼에서 c 와 같이 표시됩니다 . 입력 파일은 처리 할 시스템과 동일한 시스템에서 생성되었으므로이 문제는 투명해야합니다. 코드 골프에 대한 일반적인 참고 사항 : 이상한 언어로 작업하거나 이상한 플랫폼에서 작업하는 경우 독자를 놀라게 할 수있는 것을 기록하십시오. 사람들은 귀하의 제출을 ​​판단 할 때이를 허용합니다.
— dmckee --- 전 운영자 고양이

답변:


4

루비 - (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로 테스트되었습니다.


나는 그 대부분을 따릅니다. s.shift.split.map의 기능을 잘 모르지만 입력에서 배열을 구성해야합니다.
— dmckee --- 전 운영자 고양이

BTW-- 유닉스 커맨드 라인에서 어떻게 호출해야합니까? 나는 그것을 내 시스템에 적절한 shebang을 주려고 시도했지만 불평했다 ./temp.ruby:4: wrong argument type Symbol (expected Proc) (TypeError).
— dmckee --- 전 운영자 고양이

s.shift는 첫 번째 줄을 취하고 split은 ""m ","n "]을 반환하고 map은 [m, n]을 반환합니다. 다음과 같이 ruby1.9로 실행하고 ruby1.9 test.rb있습니다.
— Arnaud Le Blanc


3

파이썬 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

당신은 h.join(f)내가 생각하는 것을 사용할 수 있어야합니다
— gnibbler

그리고 next(f)대신에 f.readline()당신이있는 경우> = 2.6 다른f.next()
— gnibbler

내 파이썬은 결코 좋지 않았지만 가장자리 사례를 처리하기 위해 추가 '#'을 사용하고있는 것처럼 보입니다. 그러나 여분의 숫자를 포함하여 테스트 데이터에 이상한 결과가 나옵니다.
— dmckee --- 전 운영자 고양이

@ dmckee, 예 가장자리를 표시하기 위해 여분의 #을 사용하고 있습니다. 실패했다고 생각되는 테스트 사례를 게시 할 수 있습니까?
— Keith Randall

@ 키스 : 위의 테스트 케이스의 경우 12 개의 출력 라인을 얻습니다 (처음 10 개는 일치하지 않습니다). 내 Mac에서 python2.6 또는 2.7 사용 로 실행하면 echo test_input_file_name | python golf.py잘못됩니까?
— dmckee --- 전 운영자 고양이

2

++ 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);}

제대로 호출하려고 몇 번 시도했습니다. 멋진.
— dmckee --- 전 운영자 고양이

2

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()있습니다.


행과 열 번호를 반대로 생각합니다. 올바르게 이해하면 첫 번째 숫자는 행 수이지만 열 수로 취급합니다.
— ugoren

내가 알 수 있듯이 내 프로그램의 출력은 설명에 제공된 예제와 참조 구현의 출력과 일치합니다. 당신이 말하는 것을 구체적으로 보여줄 수 있습니까?
— breadbox

행과 열 번호가 다른 모든 예
— ugoren

좋아요,하지만 구체적으로 말씀 드리겠습니다. 설명에 제공된 예제 그리드가 주어지면 내 프로그램은 숫자 1에 대해 (1,2)를 출력합니다. 내 프로그램이 (2,1)을 출력해야한다고 말하는가?
— breadbox

출력이 아닌 입력에 대해 이야기하고 있습니다. 첫 번째 행이 5 5인 경우 두 번째를 가져와야 할 때 첫 번째 5를 너비로 사용합니다 (물론이 예제에서는 중요하지 않음).
— ugoren

1

참조 구현 :

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;
}

1

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

1

스칼라 252 :

object c extends App{val z=readLine.split("[ ]+")map(_.toInt-1)
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(c+"\t"+(y+1)+"\t"+(x+1))}}
}}

컴파일 및 호출 :

scalac cg-318-crossword.scala && cat cg-318-crossword | scala c

0

쉘 스크립트

#!/bin/sh
crossWordFile=$1

totLines=`head -1 $crossWordFile | cut -d" " -f1`
totChars=`head -1 $crossWordFile | awk -F' ' '{printf $2}'`

NEXT_NUM=1
for ((ROW=2; ROW<=(${totLines}+1); ROW++))
do
   LINE=`sed -n ${ROW}p $crossWordFile`
   for ((COUNT=0; COUNT<${totChars}; COUNT++))
   do
      lineNumber=`expr $ROW - 1`
      columnNumber=`expr $COUNT + 1`
      TOKEN=${LINE:$COUNT:1}
      if [ "${TOKEN}" != "#" ]; then
      if [ ${lineNumber} -eq 1 ] || [ ${columnNumber} -eq 1 ]; then
          printf "${NEXT_NUM}\t${lineNumber}\t${columnNumber}\n"
          NEXT_NUM=`expr $NEXT_NUM + 1`
      elif [ "${TOKEN}" != "#" ] ; then
          upGrid=`sed -n ${lineNumber}p $crossWordFile | cut -c"${columnNumber}"`
          leftGrid=`sed -n ${ROW}p $crossWordFile | cut -c${COUNT}`
          if [ "${leftGrid}" = "#" ] || [ "${upGrid}" = "#" ]; then
          printf "${NEXT_NUM}\t${lineNumber}\t${columnNumber}\n"
          NEXT_NUM=`expr $NEXT_NUM + 1`
          fi
      fi
      fi
   done
done

샘플 I / O :

./numberCrossWord.sh crosswordGrid.txt

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

솔루션 : 주어진 특별한 경우를위한 단지 해결 방법 경우 그냥 제공하는 I / O에서 이해하려고 노력으로 나는 완전히 요구 사항을 이해하지 수도, 용서하십시오
— 아만 ZeeK 베르

내는 /bin/sh당신이 (버전 번호 포함)를 사용하는 쉘을 말할 수 라인 (11)에 대해 불평?
— dmckee --- 전 변조 고양이

8 번 줄은 11 번 줄과 비슷한 것 같습니다. $ bash는 --version GNU bash는 버전 3.1.17 (1) -release (x86_64에-SUSE 리눅스)
— 아만 ZeeK 베르

#! bin / sh를 # /! / bin / bash로 수정하십시오. 지금 작동합니다!
— Aman ZeeK Verma

0

ANSI C 694 자

이것은 모서리 또는 '#'문자에 맞닿은 두 공간의 수평 또는 수직 런을 찾는 C 버전입니다.

입력 파일은 stdin에서 가져 왔으며 다음과 같아야합니다.

<rows count> <cols count><newline>
<cols characters><newline> x rows
...

이를 압축하는 데 도움이되는 팁을 보내 주시면 감사하겠습니다.

#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>

#define H '#'

char *p,*g;
int m=0,d=0,r=0,c=0,R=0,C=0;
void n() {
    while(!isdigit(d=getchar()));
    m=d-'0';
    while(isdigit(d=getchar()))
        m=m*10+d-'0';
}

int t() {
    return (((c<1||*(p-1)==H)&&c<C-1&&*p!=H&&p[1]!=H)||
            ((r<1||*(p-C-1)==H)&&r<R-1&&*p!=H&&p[C+1]!=H));
}

int main (int argc, const char * argv[]) 
{
    n();R=m;m=0;n();C=m;
    p=g=malloc(R*C+R+1);
    while((d=getchar())!=EOF) {
        *p++=d;
    }
    int *a,*b;
    b=a=malloc(sizeof(int)*R*C+R+1);
    p=g;m=0;
    while(*p) {
        if(t()) {
            *a++=++m;
            *a++=r+1;
            *a++=c+1;
        }
        if(++c/C) r++,p++;
        c-=c/C*c;
        p++;
    }
    while(*b) {
        printf("%d\t%d\t%d\n",*b,b[1],b[2]);
        b+=3;
    }
}

제공된 예제의 출력

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

이 코드는 # _ # 수직 및 수평 단일 공백 ​​간격을 올바르게 처리합니다.이 공백은 단일 연결되지 않은 공백으로는 발생하지 않지만 수평 단어의 마지막 문자와 같이 허용되는 것처럼 보입니다.
— Jonathan Watmough
당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.