Numerazione dei cruciverba


9

Produrre un programma per numerare correttamente una griglia di parole crociate.

Ingresso

L'input sarà il nome di un file che rappresenta la griglia del cruciverba. Il nome file di input può essere passato come argomento, sull'input standard o con altri mezzi convenzionali diversi dall'hardcoding.

Formato file griglia: un file di testo. La prima riga è composta da due costanti intere separate da spazi bianchi Me N. Seguendo quella linea ci sono M linee ciascuna composta da Ncaratteri (più una nuova linea) selezionati da [#A-Z ]. Questi personaggi sono interpretati in modo tale da '#' indicare un quadrato bloccato, ' 'un quadrato aperto nel puzzle senza contenuti noti e qualsiasi lettera un quadrato aperto il cui contenente quella lettera.

Produzione

L'output sarà un file di numerazione e può essere inviato all'output standard, a un file il cui nome è derivato dal nome file di input, a un file specificato dall'utente o ad un'altra destinazione convenzionale.

Formato file di numerazione Un file di testo. Le righe che iniziano con '#' vengono ignorate e possono essere utilizzate per i commenti. Tutte le altre linee contengono una scheda separata tripletta i, m, ndove irappresenta un numero da stampare sulla griglia, ed me nrappresenta la riga e colonna del quadrato dove dovrebbe essere stampata. Il numero di righe e colonne inizia da 1.

Schema di numerazione

Una griglia numerata correttamente ha le seguenti proprietà:

  1. La numerazione inizia da 1.
  2. Nessuna colonna o intervallo di quadrati aperti non è numerato. (Si può presumere che nel problema non esista una risposta a carattere singolo.)
  3. I numeri verranno rilevati nell'ordine di conteggio eseguendo la scansione dalla riga superiore a quella inferiore prendendo ogni riga da sinistra a destra. (Quindi, ogni intervallo orizzontale è numerato nella sua casella più a sinistra e ogni colonna è numerata nella sua casella più in alto.)

Test input e output attesi

Ingresso:

5   5
#  ##
#    
  #  
    #
##  #

Output (trascurando le righe di commento):

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

A parte

Questo è il primo di quelle che si spera siano diverse sfide legate al cruciverba. Ho intenzione di utilizzare un insieme coerente di formati di file in tutto e di creare una rispettabile suite di utilità correlate alle parole incrociate nel processo. Ad esempio, un puzzle successivo richiederà la stampa di una versione ASCII del cruciverba in base all'input e all'output di questo puzzle.


Gli span a carattere singolo non sono numerati, giusto?
Keith Randall,

@Kieth: preferisco la regola in cui non esistono tali intervalli, ma non l'ho specificata qui perché la convalida della griglia è pianificata come un altro problema. Suppongo che tu usi una questione di gusti.
dmckee --- ex-moderatore gattino

il file di input sarà in txt?
www0z0k,

@ www0z0k: Sì. Il disadattato unix in me ha sempre il testo predefinito.
dmckee --- ex gattino moderatore

1
@ www0z0k: le interruzioni di riga sono quelle native della tua piattaforma. Quello è ASCII 20 decimale sul mio e rappresentato come '\n'in c su tutte le piattaforme. Il presupposto è che il file di input sia stato prodotto sullo stesso sistema che lo elaborerà, quindi questo problema dovrebbe essere trasparente. Una nota generale sul code-golf: se stai lavorando in una strana lingua o su una strana piattaforma, prendi nota di tutto ciò che potrebbe sorprendere il lettore. Le persone terranno conto di ciò nel giudicare la tua richiesta.
dmckee --- ex gattino moderatore

Risposte:


4

Rubino - 210 139 caratteri

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

Testato con rubino 1.9.


Seguo la maggior parte di questo. Non sono sicuro di cosa faccia s.shift.split.map, ma questo deve formare l'array dall'input.
dmckee --- ex gattino moderatore

A proposito: come dovrei invocarlo da una riga di comando unix. Ho provato a dargli uno shebang appropriato al mio sistema, ma mi lamento ./temp.ruby:4: wrong argument type Symbol (expected Proc) (TypeError).
dmckee --- ex gattino moderatore

s.shift prende la prima riga, divide restituisce ["m", "n"], la mappa restituisce [m, n]. Io corro con ruby1.9 in questo modo: ruby1.9 test.rb.
Arnaud Le Blanc,

3

PHP - 175 caratteri

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

Mi chiedevo quando qualcuno l'avrebbe fatto in un array 1d.
dmckee --- ex gattino moderatore

3

Python, 194 177 176 172 caratteri

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

Dovresti essere in grado di usare h.join(f)penso
gnibbler

e next(f)invece che f.readline()se sei> = 2.6 altrimentif.next()
gnibbler

Il mio pitone non è mai stato molto buono, ma sembra che tu stia usando '#' extra per gestire i casi limite, no? Tuttavia, sto ottenendo un output dispari sui dati del test, inclusi numeri extra.
dmckee --- ex gattino moderatore

@dmckee, sì, sto usando # extra per segnare il limite. Puoi pubblicare un caso di prova in cui pensi che fallisca?
Keith Randall,

@Kieth: per il caso di test sopra sto ottenendo 12 linee di output (e i primi 10 non corrispondono). Utilizzo di python2.6 o 2.7 sul mio Mac. Eseguendolo con echo test_input_file_name | python golf.py, è sbagliato?
dmckee --- ex gattino moderatore

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

Usare:

g++ cross.cpp -o cross
cat puzzle |  cross

Ben formattato:

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

Ho provato a leggere l'intero cruciverba in una sola volta e usando un singolo ciclo.
Ma il costo per compensare il carattere '\ n ha superato qualsiasi guadagno:

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

Compresso: 260 caratteri

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

Mi ci vollero alcuni tentativi per invocarlo nel modo giusto. Slick.
dmckee --- ex gattino moderatore

2

C, 184 189 caratteri

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

Non c'è molto da dire qui; la logica è piuttosto semplice. Il programma prende il nome file sull'input standard in fase di esecuzione. (È così fastidioso che il programma debba lavorare con un nome file e non possa semplicemente leggere il contenuto del file direttamente dall'input standard. Ma chi paga il pifferaio chiama la melodia!)

Il fscanf()modello strano è il mio tentativo di scansionare l'intera prima riga, inclusa la nuova riga ma non includendo gli spazi bianchi iniziali sulla riga seguente. C'è un motivo per cui nessuno lo usa scanf().


Penso che inverti il ​​numero di righe e colonne. Se ho capito bene, il primo numero è il numero di righe, ma lo tratti come il numero di colonne.
ugoren,

Da quello che posso dire, l'output del mio programma corrisponde all'esempio fornito nella descrizione e l'output dell'implementazione di riferimento. Potete darmi un esempio specifico di ciò a cui vi riferite?
breadbox,

Qualsiasi esempio in cui i numeri di righe e colonne non sono uguali.
ugoren,

Ok, ma cerchiamo di essere specifici per favore. Quando viene fornita la griglia di esempio fornita nella descrizione, il mio programma genera (1,2) per il numero 1. Stai dicendo che il mio programma dovrebbe produrre (2,1)?
breadbox

Sto parlando di input, non di output. Quando la prima riga è 5 5, prendi le prime 5 come larghezza, quando avresti dovuto prendere la seconda (il che non ha importanza, ovviamente, in questo esempio).
ugoren,

1

Implementazione di riferimento:

c99 ungolfed e piuttosto più di 2000 personaggi tra cui vari frob di debug ancora lì.

#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 caratteri (ma non l'ho ancora giocato a golf)

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

Ha bisogno di un file chiamato grid.txtcon la specifica, quindi compilare con

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

compilazione e invocazione:

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

0

SHELL SCRIPT

#!/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 di esempio:

./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

Potrei non aver compreso appieno i requisiti, come ho appena provato a capire
dall'I

Mi /bin/shlamento della linea 11. Potresti dire quale shell stai usando (incluso il numero di versione)?
dmckee --- ex gattino moderatore

La linea 8 sembra essere simile alla linea 11 .. non lo è? $ bash --version GNU bash, versione 3.1.17 (1) -release (x86_64-suse-linux)
Aman ZeeK Verma

prova a modificare #! bin / sh in # /! / bin / bash, ora dovrebbe funzionare!
Aman ZeeK Verma,

0

Caratteri ANSI C 694

Questa è una versione in C che cerca percorsi orizzontali o verticali di due spazi che sono a testa in giù contro il bordo o contro un carattere '#'.

Il file di input è preso dallo stdin e deve essere:

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

Eventuali suggerimenti per la compattazione verranno ricevuti con gratitudine.

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

Output per l'esempio fornito

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

Questo codice gestisce correttamente # _ # spazi vuoti verticali e orizzontali a spazio singolo, che sebbene possano non presentarsi come uno spazio singolo non collegato, sembrano essere consentiti, ad esempio come l'ultima lettera di una, diciamo, parola orizzontale.
Jonathan Watmough il
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.