หมายเลขคำไขว้


9

สร้างโปรแกรมเพื่อกำหนดจำนวนตารางไขว้อย่างถูกต้อง

อินพุต

อินพุตจะเป็นชื่อของไฟล์ที่แสดงถึงกริดไขว้ ชื่อไฟล์อินพุตอาจถูกส่งผ่านเป็นอาร์กิวเมนต์ในอินพุตมาตรฐานหรือโดยวิธีการทั่วไปอื่นที่ไม่ใช่ฮาร์ดโค้ด

รูปแบบไฟล์กริด:ไฟล์ข้อความ บรรทัดแรกประกอบด้วยสองพื้นที่สีขาวแยกจำนวนเต็มคงที่และM Nตามแนวที่มีM แต่ละบรรทัดประกอบด้วยNตัวอักษร (บวกบรรทัดใหม่) [#A-Z ]เลือกจาก ตัวละครเหล่านี้ถูกตีความว่า'#' เป็นสี่เหลี่ยมจัตุรัสที่ถูกบล็อกซึ่ง' 'เป็นสี่เหลี่ยมจัตุรัสเปิดในปริศนาที่ไม่มีเนื้อหาที่รู้จักและตัวอักษรใด ๆ ที่เป็นสี่เหลี่ยมเปิดซึ่งมีตัวอักษรนั้นอยู่

เอาท์พุต

เอาต์พุตจะเป็นไฟล์ตัวเลขและอาจถูกส่งไปยังเอาต์พุตมาตรฐานไปยังไฟล์ที่มีชื่อที่ได้มาจากชื่อไฟล์อินพุตไปยังไฟล์ที่ผู้ใช้ระบุหรือไปยังปลายทางทั่วไปอื่น ๆ

รูปแบบไฟล์หมายเลขไฟล์ข้อความ บรรทัดที่ขึ้นต้นด้วย '#' จะถูกละเว้นและอาจถูกใช้เพื่อแสดงความคิดเห็น สายอื่น ๆ ทั้งหมดมีแท็บแยกแฝดi, m, nที่iหมายถึงจำนวนที่จะพิมพ์บนตารางและmและnเป็นตัวแทนของแถวและคอลัมน์ของตารางที่มันควรจะพิมพ์ จำนวนทั้งแถวและคอลัมน์เริ่มต้นที่ 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

นอกเหนือ

นี่เป็นครั้งแรกของสิ่งที่หวังว่าจะเป็นความท้าทายที่เกี่ยวข้องกับคำไขว้ ฉันวางแผนที่จะใช้ชุดรูปแบบไฟล์ที่สอดคล้องกันตลอดและเพื่อสร้างชุดของยูทิลิตี้ที่เกี่ยวข้องกับคำไขว้ในกระบวนการ ตัวอย่างเช่นตัวต่อที่ตามมาจะเรียกร้องให้ทำการพิมพ์ Crossword เวอร์ชัน ASCII ตามอินพุตและเอาต์พุตของตัวต่อนี้


ช่วงตัวอักขระเดียวไม่ได้ถูกนับใช่ไหม?
Keith Randall

@ Kieth: ฉันชอบกฎที่ไม่มีช่วงดังกล่าว แต่ฉันไม่ได้ระบุไว้ที่นี่เพราะการตรวจสอบความถูกต้องของกริดถูกวางแผนว่าเป็นปัญหาอื่น ฉันคิดว่าสิ่งที่คุณใช้เป็นเรื่องของรสนิยม
dmckee --- ผู้ดูแลอดีตแมว

ไฟล์อินพุตจะเป็นแบบ txt หรือไม่
www0z0k

@ www0z0k: ใช่ Geek ที่ยูนิกซ์ในตัวผมเสมอค่าเริ่มต้นให้กับข้อความ
dmckee --- ผู้ดูแลอดีตแมว

1
@ www0z0k: การแบ่งบรรทัดเป็นสิ่งที่เกิดขึ้นบนแพลตฟอร์มของคุณ นั่นคือ ASCII ทศนิยม 20 ในเหมืองและแสดงเป็น'\n'c ในทุกแพลตฟอร์ม สมมติฐานคือไฟล์อินพุตถูกสร้างขึ้นบนระบบเดียวกันกับที่จะประมวลผลดังนั้นปัญหานี้ควรโปร่งใส หมายเหตุทั่วไปเกี่ยวกับ code-golf:หากคุณกำลังทำงานในภาษาแปลก ๆ หรือบนแพลตฟอร์มแปลก ๆ ให้จดบันทึกสิ่งที่อาจทำให้ผู้อ่านประหลาดใจ ผู้คนจะตั้งค่าเผื่อไว้สำหรับการตัดสินการส่งของคุณ
dmckee --- ผู้ดูแลอดีตแมว

คำตอบ:


4

Ruby - 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 - ฉันจะเรียกใช้มันอย่างไรในบรรทัดคำสั่ง unix ฉันพยายามให้มันเหมาะสมกับระบบ shebang ฉัน ./temp.ruby:4: wrong argument type Symbol (expected Proc) (TypeError)แต่มันบ่น
dmckee --- ผู้ดูแลอดีตลูกแมว

s.shift ใช้บรรทัดแรกแบ่งผลตอบแทน ["m", "n"], แผนที่ส่งคืน [m, n] ผมทำงานกับ ruby1.9 ruby1.9 test.rbเช่นนี้
Arnaud Le Blanc


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

และnext(f)แทนที่จะเป็นf.readline()ถ้าคุณ> = 2.6f.next()
gnibbler

หลามของฉันไม่เคยดีมาก แต่ดูเหมือนว่าคุณกำลังใช้ '#' พิเศษเพื่อจัดการกับเคสขอบใช่ไหม? อย่างไรก็ตามฉันได้รับข้อมูลแปลก ๆ จากการทดสอบรวมถึงตัวเลขพิเศษ
dmckee --- ผู้ดูแลอดีตแมว

@dmckee ใช่ฉันใช้ #s พิเศษเพื่อทำเครื่องหมายขอบ คุณสามารถโพสต์กรณีทดสอบที่คุณคิดว่ามันล้มเหลวได้หรือไม่?
Keith Randall

@ Kieth: สำหรับกรณีทดสอบด้านบนฉันได้รับ 12 บรรทัดเอาต์พุต (และ 10 รายการแรกไม่ตรงกัน) ใช้ python2.6 หรือ 2.7 บน Mac ของฉัน ทำงานด้วย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

จากสิ่งที่ฉันสามารถบอกได้ผลลัพธ์ของโปรแกรมของฉันตรงกับตัวอย่างที่ให้ไว้ในคำอธิบายและผลลัพธ์จากการใช้งานอ้างอิง คุณช่วยยกตัวอย่างที่เฉพาะเจาะจงของสิ่งที่คุณอ้างถึงได้ไหม
breadbox

ตัวอย่างใด ๆ ที่หมายเลขแถวและคอลัมน์ไม่เท่ากัน
ugoren

โอเค แต่ขอรายละเอียดหน่อยสิ เมื่อได้รับตารางตัวอย่างที่ให้ไว้ในคำอธิบายโปรแกรมของฉันส่งออก (1,2) สำหรับหมายเลข 1 คุณกำลังบอกว่าโปรแกรมของฉันควรจะส่งออก (2,1)?
breadbox

ฉันกำลังพูดถึงอินพุตไม่ใช่เอาต์พุต เมื่อบรรทัดแรกคือ5 5คุณใช้ 5 แรกเป็นความกว้างเมื่อคุณควรใช้ที่สอง (ซึ่งไม่สำคัญในตัวอย่างนี้)
ugoren

1

การใช้งานอ้างอิง:

c99 ungolfed และมากกว่า 2,000 ตัวอักษรรวมถึงการดีบั๊กต่าง ๆ ที่ยังอยู่ในนั้น

#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 chars (แต่ฉันยังไม่ได้ตีกอล์ฟเลย)

\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 โปรดยกโทษให้ถ้าการแก้ปัญหาเป็นเพียงวิธีแก้ปัญหาสำหรับกรณีเฉพาะ :)
Aman ZeeK Verma

ฉัน/bin/shบ่นเกี่ยวกับบรรทัดที่ 11 คุณสามารถพูดสิ่งที่เปลือกคุณใช้ (รวมถึงหมายเลขรุ่น)?
dmckee --- ผู้ดูแลอดีตลูกแมว

ดูเหมือนว่าบรรทัด 8 จะคล้ายกับบรรทัดที่ 11 .. ใช่ไหม $ bash - รุ่น GNU bash เวอร์ชัน 3.1.17 (1) - ปล่อย (x86_64-suse-linux)
Aman ZeeK Verma

ลองแก้ไข #! 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.