크로스 워드 넘버링


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.