Cortar un césped rectangular

17

Un césped se define como un campo rectangular con un carácter rodeado por dos capas de espacio en blanco visible . Esto significa dos líneas arriba y dos líneas abajo, y un relleno de dos espacios a la izquierda (la derecha tiene un espacio en blanco visible, por lo que no es necesario incluirlo).

  
  
  ||||| 
  ||||| 
  ||||| 
 
  

Un césped cortado es una estructura similar, excepto que el personaje principal es una versión abreviada del primer personaje.

  
  
  ..... 
  ..... 
  ..... 
 
  

Un cortacésped tiene dos caracteres diferentes, diferentes de los dos caracteres del césped. Aquí hay un ejemplo, con =la parte posterior del cortacésped y ola parte delantera:

=o

Una cortadora de césped se moverá alrededor del césped verticalmente y también puede girar sobre su frente. El cortacésped anterior puede verse como cualquiera de los siguientes durante algún punto de la animación:

=o 
  
o= 
  
o
=
  
=
o

El cortacésped puede arrancar en cualquier conjunto de las siguientes posiciones en el césped debajo. Las ocortadoras de césped conducirían alrededor del césped en el sentido de las agujas del reloj. Las 0cortadoras de césped conducirían alrededor del césped en sentido antihorario.

  =   =
  0   o
=o|||||0=
  ||||| 
=0|||||o=
  o   0
  =   =

La animación comienza en el segundo 0. Cada segundo, el cortacésped avanza un espacio y corta el césped en su frente. Cuando el cortacésped desocupa un lugar, parece cortado. Cuando el cortacésped llega al último elemento sin cortar en una línea (y todavía hay hierba sin cortar), el cortacésped gira una vez para continuar con el cortacésped actual (permaneciendo en sentido horario / antihorario según la posición original) Cuando el cortacésped está terminado, continúa recto (cortar el césped ya cortado) hasta que esté completamente fuera del césped.

Con un cortacésped que comienza en la parte superior izquierda, esto muestra la progresión básica para un césped de 5x3:

Second 0  Second 1  Second 2  Second 3  Second 4  Second 5  Second 6  Second 7  Second 8  Second 9  Second 10 Second 11 Second 12 Second 13 Second 14 Second 15 Second 16 Second 17 Second 18 Second 19 Second 20 Second 21 Second 22

                                                                  =
=o|||||    =o||||     =o|||     .=o||     ..=o|     ...=o     ....o     ....=     .....     .....     .....     .....     .....     .....     .....     .....     .....     .....     .....     .....     .....     .....     .....
  |||||     |||||     |||||     |||||     |||||     |||||     |||||     ||||o     ||||=     ||||.     ||||.     ||||.     ||||.     ||||.     ||||.     o|||.    =o|||.     =o||.     .=o|.     ..=o.     ...=o     ....=o    .....=o
  |||||     |||||     |||||     |||||     |||||     |||||     |||||     |||||     ||||o     ||||o=    |||o=     ||o=.     |o=..     o=...     o....     =....     .....     .....     .....     .....     .....     .....     .....
                                                                                                                                              =
  

Entrada

Su entrada será las dimensiones del césped (dos enteros).

Salida

Imprima el césped y la cortadora de césped en la posición elegida. Puede elegir los cuatro caracteres para hierba, cortar hierba, segadora delantera y segadora trasera. Solo necesita suficiente espacio en blanco para mostrar el contenido del segundo actual a las especificaciones, pero el espacio en blanco adicional está completamente permitido, siempre que se vea igual.

Como se trata de una , puede borrar la salida cada segundo o imprimir suficientes líneas nuevas para que parezcan animarse en el marco de visualización (puede suponer que el marco de visualización es del tamaño necesario para aparecer para animar).

Se permite un intervalo de tiempo constante que no sea un segundo (es decir, 999 milis para ahorrar un byte, o dos segundos por alguna razón), pero debe ser tal que la cortadora de césped todavía parece moverse de forma natural.

Si es posible, proporcione un visual (TIO, Snippet, GIF, etc.)

Este es el , por lo que la respuesta más corta en bytes gana.

Stephen
fuente
3
Buen desafío! Hablando desde la perspectiva de una persona a la que le molestan los cables, probablemente terminarías cortando el cable :)
HyperNeutrino
¿Podemos suponer que la ventana de salida tiene el tamaño adecuado para el césped?
Adám
Algo más que puede permitir es devolver una lista de todos los estados, similar a su ejemplo de ejecución.
Adám
3
¿Qué pasa si nos gusta cortar el césped de la manera correcta? s-media-cache-ak0.pinimg.com/736x/92/5c/7c/…
tuskiomi
3
@tuskiomi Tengo otro desafío en proceso basado en la misma idea, pero donde el programador tiene control sobre cómo se corta :)
Stephen

Respuestas:

4

JavaScript (ES6 / Node.js), 664 525 523 caracteres

f=(w,h)=>{Z=require('sleep');c=a=>console.log(a);X=1;Y=2;D='e';N='|';O={'|':[0,-1],'e':[1,0],'s':[0,1],'w':[-1,0]};S=[N,D,'s','w'];q=d=>F[Y+O[d][1]][X+O[d][0]];b=' '.repeat(w+4),U='  ';F=[b,b].concat([...Array(h)].map(x=>U+N.repeat(w)+U)).concat([b,b]).map(x=>x.split``);for(;;){f=F.map(a=>a.concat());f[Y][X]='@';d=O[D];f[Y-d[1]][X-d[0]]='=';c(f.map(x=>x.join``).join`\n`);if(F[Y][X]==N)F[Y][X]='.';d=O[D],f=q(D),R=S[(S.indexOf(D)+1)%4],r=q(R);(r==N)&&((f==' ')||(f=='.'))?D=R:(X+=d[0],Y+=d[1])
Z.msleep(1E3);c('\033[2J')}}

Sin minificar con comentarios:

f=(w,h)=>{
  Z = require('sleep');
  c=a=>console.log(a); 
  //mower coordinates
  X = 1;
  Y = 2;
  //mower direction
  D='e'; //n/e/s/w
  N='|';
  //directions with amount of change in [x,y] coordinates
  O = {'|':[0,-1],'e':[1,0],'s':[0,1],'w':[-1,0]};
  //direction short names
  S=[N,D,'s','w'];
  //query for item in specified direction relative to mower
  q=d=>F[Y+O[d][1]][X+O[d][0]];
 //generate field + whitespace
 b=' '.repeat(w+4),U='  ';
 F=[b,b].concat([...Array(h)].map(x=>U+N.repeat(w)+U)).concat([b,b]).map(x=>x.split``);
 for(;;){
    //print the field: 
    //make a copy of the field, so we can paste the mower on top of it
    f=F.map(a=>a.concat());
    //print mower head
    f[Y][X]='@';
    //print mower tail
    d = O[D];
    f[Y-d[1]][X-d[0]]='=';
    c(f.map(x=>x.join``).join`\n`);   
    //-----
    //move the mower
    if(F[Y][X]==N)F[Y][X]='.';//cut the grass if we stand on some
    d=O[D],//how many fields to move forward
        f=q(D),//item in front of mower
        R=S[(S.indexOf(D)+1)%4],//name of direction if we rotate to the right
        r=q(R);//item to right of mower
    //if there is wall in front of me OR cut grass in front of me and uncut on the right, turn right, else go ahead
    (r==N) && ((f==' ') || (f=='.'))?D=R:(X+=d[0],Y+=d[1])
    Z.msleep(1E3);
    c('\033[2J');
};
}
//test script
f(3,3);

nota: supongo que debería obtener el paquete 'sleep' y volver a escribir con setTimeout para que sea nodejs independiente

Axarydax
fuente
Intenté pegar esto en TIO (dice que funciona para node.js). ¿Alguna pista de por qué no funciona?
Stephen
debido al módulo de "suspensión" - me deshaceré de él
Axarydax