Desenhar palavras em espiral [fechado]

11

O cenário

Dada uma entrada de letras minúsculas e espaços ASCII, desenhe uma espiral de caracteres que rastreia a entrada original de caracteres, excluindo espaços.

As regras

1) Os caracteres devem girar em sentido anti-horário para a esquerda de maneira externa. Se não for possível uma curva à esquerda, siga em frente.

Given: abcdefg
Output:
  g
baf   
cde   

Primeiro exemplo de rastreamento de imagem

2) Os caracteres podem se transformar em caracteres anteriores, desde que a regra nº 1 não seja violada. Além disso, se esse caractere estiver em espiral, ele estará em maiúsculas. Depois que um caractere estiver em maiúsculas, ele permanecerá em maiúsculas, independentemente do número de vezes que for reutilizado.

Given: apples appeal
Output:
PAs
PLe
ea

Segundo exemplo de rastreamento de imagem

Tim Reddy
fonte
1
Então, se a palavra permanecer na espiral, mas violar o próximo caractere, o programa será interrompido?
Matt
Eu acho que o que faz disso um bom desafio é que você teria que "rebobinar a pilha", por assim dizer, e retomar em um ponto que faça a regra 1 sempre funcionar.
Tim Reddy
5
A redação atual faz a regra 2 parecer totalmente opcional. Se for obrigatório, acho que é necessário um conjunto de testes muito mais abrangente.
Peter Taylor
1
Qual deve ser a saída para entrada abcdefghab?
Peter Taylor

Respostas:

2

JavaScript, 225 221 212 bytes

-9 bytes graças a Conor O'Brien

Observe que seus casos de texto entram em conflito entre si. Seu primeiro caso de teste começa no meio da espiral. Seu segundo caso de teste começa no meio da espiral. Eu fui com o seu primeiro caso de teste, porque foi o primeiro que vi. Você não editou sua pergunta há mais de um ano, desculpe a presunção.

Primeiro caso de teste:

9<-8<-7
|     |
2<-1  6
|     |
3->4->5

Segundo caso de teste:

2<-1<-6
|     |
3->4->5
|     |
7->8->9

Sem mais delongas, aqui está o código do golfe. Tenho 100% de certeza de que, se a comunidade lascar, isso poderá ser reduzido significativamente. Isso retorna uma matriz de várias linhas.

s=>eval("s=[...s.replace(/ /g,'')];i=0;k=j=1;a=[[],[],[]];b='00122210';c=b*100+'';for(;;){for(l=0;l<8;l++){if(!s[i])break;if(a[k][j]==s[i])s[i]=s[i].toUpperCase();a[k][j]=s[i];k=b[l];j=c[l];i++}if(!s[i])break}a")

Snippet de pré-certificação (imprime uma string de várias linhas no console). Observe o diferente no meu caso de teste nº 2 e no caso de teste nº 2 do OP (veja acima, se você ainda não o tiver):

(se alguém com mais experiência com trechos quiser corrigir isso na entrada HTML, sinta-se à vontade para editar isso, preciso ir para a cama).

f=
s=>eval("s=[...s.replace(/ /g,'')];i=0;k=j=1;a=[[],[],[]];b='00122210';c=b*100+'';for(;;){for(l=0;l<8;l++){if(!s[i])break;if(a[k][j]==s[i])s[i]=s[i].toUpperCase();a[k][j]=s[i];k=b[l];j=c[l];i++;g(a)}if(!s[i])break}a")

//replace argument here to change output
var arr = f("apples appeal");

function g(ar) {
  var str = "";

  for (x = 0; x < 3; x++) {
    for (y = 0; y < 3; y++) {
      str += ar[y][x] || " ";
    }
    str += "\n";
  }
  console.log(str);
}

Ungolfed e explicação

f=(input)=>{
    //remove spaces
    input = input.replace(/ /g, "");

    //convert to array (so I can uppercase individual letters)
    input = input.split("");

    //position in input
    var pos = 0;

    //positions inside output
    var xPos = 1;
    var yPos = 1;

    //output container (3 rows, 3 columns)
    var arr = [[],[],[]];

    //counterclockwise indexes for x
    var xOrder = "00122210";

    //counterclockwise indexes for y
    //var yOrder = "12221000"
    var yOrder = xOrder * 100 + "";

    //loop infinitely (breaks when input[pos] is undefined)
    for (;;) {
        //loop around circle
        for (var i = 0; i < 8; i++) {
            if (!input[pos]) {
                break;
            }

            //if item already in array equal next item in input, set next item in input to caps before
            if (arr[xPos][yPos] == input[pos]) {
                input[pos] = input[pos].toUpperCase(); 
            }

            //write or overwrite in array with current from input
            arr[xPos][yPos] = input[pos];

            //increment last because we do not prime our loops
            xPos = xOrder[i];
            yPos = yOrder[i];
            pos++;
        }
        if(!input[pos]) {
            break;
        }
    }
    return arr;
}
Stephen
fonte
1
a.split("")é equivalente a [...a]; s=>{...;return a;}é equivalente a s=>eval("...;a")(e ;é opcional na versão menos golfe); todos os pontos e vírgulas seguidos por um }são opcionais
Conor O'Brien
@ ConorO'Brien thank you :)
Stephen
Que saída você obtém para o caso de teste apples appeal? Estou vendo ppa eas aLe, o que definitivamente não está correto, porque não há lpróximo ao ps.
Peter Taylor
@PeterTaylor, a saída está correta, de acordo com a ordem espiral do primeiro caso de teste, no qual baseei meu programa. O segundo caso de teste usa uma ordem espiral diferente (começa na parte superior). Eu adicionei um log para cada iteração do snippet. Veja isso - pode fazer mais sentido.
Stephen
Pela lógica do primeiro caso de teste, a saída seria eppa apas lple s.
Peter Taylor