Cortar um gramado retangular

17

Um gramado é definido como um campo retangular com um caractere cercado por duas camadas de espaço em branco visível . Isso significa duas linhas acima e duas linhas abaixo e um preenchimento de dois espaços à esquerda (a direita tem espaço em branco visível, portanto você não precisa incluí-lo).

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

Um gramado aparado é uma estrutura semelhante, exceto que o personagem principal é uma versão abreviada do primeiro personagem.

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

Um cortador de grama tem dois caracteres diferentes, diferentes dos caracteres do gramado. Aqui está um exemplo, com =a parte de trás do cortador e oa frente:

=o

Um cortador de grama se moverá verticalmente no gramado e também poderá girar de frente. O cortador de grama acima pode se parecer com qualquer um dos itens abaixo durante algum momento da animação:

=o 
  
o= 
  
o
=
  
=
o

O cortador de grama pode iniciar em qualquer conjunto das posições abaixo no gramado abaixo. Os cortadores de grama rodavam opelo gramado no sentido horário. Os cortadores de 0grama dirigiam pelo gramado no sentido anti-horário.

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

A animação começa no segundo 0. A cada segundo, o cortador de grama avança um espaço e corta a grama de frente. Quando o cortador desocupa um local, ele aparece cortado. Quando a frente do cortador de grama atinge o último item sem cortes de uma linha (e ainda há grama cortada), o cortador de grama gira uma vez para continuar o corte atual (permanecendo no sentido horário / anti-horário com base na posição original) Quando o cortador estiver terminado, continua em linha reta (cortando a grama já cortada) até sair completamente do gramado.

Com um cortador de grama começando no canto superior esquerdo, isso mostra a progressão básica de um gramado 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

Sua entrada será as dimensões do gramado (dois inteiros).

Resultado

Imprima o gramado e o cortador na posição escolhida. Você pode escolher os quatro caracteres para grama, grama cortada, frente do cortador e cortador de grama. Você só precisa de espaço em branco suficiente para mostrar o conteúdo do segundo atual às especificações, mas um espaço em branco extra é completamente permitido, desde que pareça o mesmo.

Como se trata de uma , você pode limpar a saída a cada segundo ou imprimir novas linhas suficientes para aparecer para animar no quadro de visualização (você pode assumir que o quadro de visualização é o tamanho necessário para aparecer para animar).

É permitido um intervalo de tempo consistente diferente de um segundo (ou seja, 999 milis para salvar um byte ou dois segundos por algum motivo), mas deve ser tal que o cortador de grama ainda pareça estar se movendo naturalmente.

Se possível, forneça um visual (TIO, Snippet, GIF etc.)

Isso é , então a resposta mais curta em bytes vence.

Stephen
fonte
3
Bom desafio! Falando a partir da perspectiva de uma pessoa que está incomodado com fios, você provavelmente acabar cortando sobre o seu fio :)
HyperNeutrino
Podemos assumir que a janela de saída é dimensionada para caber no gramado?
Adám 15/05
Outra coisa que você pode querer permitir é retornar uma lista de todos os estados, semelhante ao seu exemplo de execução.
Adám 15/05
3
E se gostamos de cortar a grama da maneira certa? s-media-cache-ak0.pinimg.com/736x/92/5c/7c/…
tuskiomi
3
@tuskiomi Eu tenho um outro desafio nas obras com base na mesma ideia, mas onde o programador tem controle sobre como ela é cortada :)
Stephen

Respostas:

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

Desminificado com comentários:

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

note: Suponho que eu deveria pegar o pacote 'sleep' e reescrever com setTimeout para ser nodejs independente

Axarydax
fonte
Tentei colocar isso no TIO (ele diz que funciona para o node.js). Alguma pista por que não está funcionando?
Stephen
por causa do módulo de 'dormir' - eu vou me livrar dele
Axarydax