填字游戏编号


9

生成一个程序以正确地编号填字游戏网格。

输入项

输入将是代表填字游戏网格的文件的名称。输入的文件名可以作为参数传递给标准输入,也可以通过硬编码以外的其他常规方式传递。

网格文件格式:文本文件。第一行由两个空格分隔的整数常量M和组成N。在该行之后是M 各行,各行由N从中选择的字符(加上新行)组成[#A-Z ]。这些字符被解释为'#' 指示方块被遮挡,' '拼图中没有已知内容的空心方块以及任何字母是包含该字母的空心方块。

输出量

输出将是一个编号文件,并且可以发送到标准输出,从输入文件名派生名称的文件,用户指定的文件或其他常规目标。

编号文件格式文本文件。以“#”开头的行将被忽略,并可用于注释。所有其他行包含一个制表符分隔三重峰imn其中i表示在网格上要打印的数,mn表示在它应该被打印的方块的行和列。行数和列数均从1开始。

编号方案

正确编号的网格具有以下属性:

  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版本的填字游戏。


单字符跨度未编号,对吗?
基思·兰德尔

@Kieth:我更喜欢没有这样的跨度的规则,但是我在这里没有指定它,因为计划验证网格是另一个问题。我想您使用的是品味问题。
dmckee ---前主持人小猫,

输入的文件将是txt吗?
www0z0k 2011年

@ www0z0k:是的。我中的unix怪胎总是默认为text。
dmckee ---前主持人小猫,

1
@ www0z0k:换行符是您平台上的固有内容。在我的'\n'平台上为ASCII十进制20,在所有平台上均以c 表示。假定输入文件是在将处理该文件的同一系统上生成的,因此此问题应该是透明的。关于代码高尔夫球的一般注意事项:如果您使用的是陌生的语言或在陌生的平台上工作,请简单地写下任何可能令读者惊讶的内容。人们会在评估您的提交时对此予以考虑。
dmckee ---前主持人小猫,

Answers:


4

Ruby- 210139个字符

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])}

使用ruby 1.9测试。


我遵循大多数。不知道s.shift.split.map的作用是什么,但这必须从输入形成数组。
dmckee ---前主持人小猫,

顺便说一句-我应该如何在UNIX命令行上调用它。我试图给它一个适合我系统的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

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

我想知道何时有人要在一维数组中执行此操作。
dmckee ---前主持人小猫,

3

Python中,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 '02

next(f)不是f.readline()如果您> = 2.6的话f.next()
gnibbler

我的python从来都不是很好,但是看起来您正在使用额外的'#'来处理边缘情况,不是吗?但是,我在测试数据上得到了一些奇怪的输出,包括额外的数字。
dmckee ---前主持人小猫,

@dmckee,是的,我正在使用额外的#标记边缘。您可以在您认为失败的地方发布测试用例吗?
基思·兰德尔

@Kieth:对于上面的测试用例,我得到12条输出线(前10条不匹配)。在Mac上使用python2.6或2.7。用运行它echo test_input_file_name | python golf.py,这是错误的吗?
dmckee ---前主持人小猫,

2

C ++ 270 264 260 256 253炭

#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

据我所知,程序的输出与描述中给出的示例相匹配,并且与参考实现的输出相匹配。您能给我一个您所指的具体例子吗?
面包箱

行数和列数不相等的任何示例。
ugoren

好的,请具体说明。当获得描述中提供的示例网格时,我的程序输出数字1的(1,2)。您是说我的程序应该输出(2,1)吗?
面包箱

我说的是输入,而不是输出。当第一行是时5 5,您将前5用作宽度,当您应该将第二行作为宽度时(在此示例中,这没关系)。
ugoren

1

参考实现:

c99不再使用,并且超过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使用spec 调用的文件,然后使用

perltex --nosafe --latex=pdflatex grid.tex

1

Scala 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中了解,如果解决方案只是针对特定情况的解决方法,请原谅:)
Aman ZeeK Verma 2011年

/bin/sh抱怨第11行。您能说说您使用的是哪个Shell(包括版本号)吗?
dmckee ---前主持人小猫,

第8行似乎与第11行类似。不是吗?$ bash --version GNU bash,版本3.1.17(1)-发行版(x86_64-suse-linux)
Aman ZeeK Verma,2011年

尝试将#!bin / sh修改为#/!/ bin / bash,现在应该可以了!
2011年

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

此代码正确处理#_#垂直和水平单个空格间隙,尽管它们可能不会作为单个未连接的空格出现,但似乎是允许的,例如,作为水平单词的最后一个字母。
乔纳森·沃特莫夫
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.