Estamos ficando fora de controle, doutor!

11

O Doutor, ao tentar escapar das forças de Dalek, decidiu enviá-las girando, viajando em vários bolsos de espaço em um movimento espiral.

Dependendo da natureza do espaço-tempo disponível, o médico precisa entrar no TARDIS controla a altura e a largura da seção do espaço e seu ponto de entrada com o qual iniciar a espiral.

A seção do espaço pode ser vista como uma grade h x w preenchida com números inteiros seqüenciais da esquerda para a direita, de cima para baixo, começando com 1.

A posição inicial é fornecida como rc para a linha e coluna ... A partir disso, o software da TARDIS precisa citar a lista ordenada de números inteiros obtida em espiral para fora no sentido anti-horário a partir da linha r coluna c , começando para cima ...

Sua tarefa, como acompanhante do médico, é programar o TARDIS para receber quatro números no formato height width row columne determinar qual setor de espaço o TARDIS precisa percorrer para coincidir com o movimento espiral descrito abaixo ...

Entrada 1

5 5 3 3

(Grade 5 x 5, começando na posição 3,3)

Saída 1

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

Explicando a saída

Grade original insira a descrição da imagem aqui

Espiral gerada insira a descrição da imagem aqui

Entrada 2

2 4 1 2

(Grade 2 x 4 começando na posição 1,2)

Saída 2

2 1 5 6 7 3 8 4

Explicando a saída

Um pouco diferente da espiral agora deve circular ao redor da grade para gerar a saída respectiva ...

Grade original insira a descrição da imagem aqui

Espiral gerada insira a descrição da imagem aqui

Regras:

  1. Esse é o código-golfe, portanto, o menor tamanho do código é aprovado.

  2. Os exemplos acima devem ser usados ​​para testar seu código. Se não fornecer a respectiva saída, há algo errado ...

  3. As versões de código para golfe e para golfe devem ser fornecidas em sua resposta ...

Boa sorte!

WallyWest
fonte
Quero que você aponte para draw.io onde é possível fazer rapidamente desenhos razoáveis ​​(você tem uma excelente legibilidade com sua versão desenhada à mão ... só que não vejo círculos vermelhos). Considere i.stack.imgur.com/xbLSA.png como um exemplo do que poderia ser feito. Observe que o xml está incorporado, portanto, se você for para draw.io, poderá importar do URL.
Vou ter isso em mente para o meu próximo necessidade de um desenho, @MichaelT, obrigado ...
Wally West
1
Eu posto uma resposta com uma função retornando array como saída. Isso é aceitável?
Edc65 16/05
@ edc65 Mate, você e eu voltamos aqui no CG, vou permitir uma função de S (h, w, r, c) ou algo parecido para isso ... :) #
1038 WallyWest

Respostas:

3

JavaScript (ES6) 124 163 177

Editar Forma totalmente diferente, sem necessidade de uma matriz para armazenar células visitadas. Usando o fato de que o lado da espiral aumenta 1 a cada 2 turnos.

// New way
f=(h,w,y,x)=>
  (e=>{
    for(o=[],d=i=t=l=0;l<w*h;i<t?i+=2:[i,d,e]=[1,-e,d,++t])
      o[l]=y*w-w+x,l+=x>0&x<=w&y>0&y<=h,x+=d,y-=e
  })(1)||o


// Golfed
g=(h,w,y,x)=>
  (g=>{
    for(e=n=0;n<h*w;)g[[n%w+1,-~(n/w)]]=++n;
    for(o=[g[[x,y]]],l=d=1;l<n;l+=!!(o[l]=g[[x+=d,y+=e]]))
      g[[x,y]]=0,
      g[[x+e,y-d]]!=0&&([d,e]=[e,-d])
  })([])||o



// Not golfed
u=(h,w,y,x)=>{
  var i,j,dx,dy,kx,ky,o,n,
    g={} // simulate a 2dimensional array using a hashtable with keys in the form 'x,y'

  for(n=i=0; i++<h;) // fill grid (probably better done in a single loop)
    for(j=0; j++<w;)
      g[[j,i]] = ++n;
  o=[g[[x,y]]] // starting point in output
  dx=1, dy=0 // start headed right
  
  for(; !o[w*h-1]; ) // loop until all w*h position are put in output
  {
    g[[x, y]] = 0 // mark current position to avoid reusing
    kx=dy, ky=-dx // try turning left
    if(g[[x+kx, y+ky]] != 0) // check if position marked
    { // found a valid position
      dx=kx, dy=ky // change direction
    }
    x+=dx, y+=dy // move
    k=g[[x, y]] // get current value
    if (k) o.push(k) // put in output list if not 'undefined' (outside grid)
  }
  return o
}

// TEST - In FireFox

out=x=>O.innerHTML+=x+'\n';
[
 [[5,5,3,3],'13 8 7 12 17 18 19 14 9 4 3 2 1 6 11 16 21 22 23 24 25 20 15 10 5'],
 [[2,4,1,2],'2 1 5 6 7 3 8 4']
].forEach(t=>out(t[0] + '\n Result: ' + f(...t[0])+'\n Check:  ' + t[1]))

test=()=>
{
  var r, i=I.value.match(/\d+/g), h=i[0]|0, w=i[1]|0, y=i[2]|0, x=i[3]|0
  if (y>h||x>w) r = 'Invalid input'
  else r = f(h,w,y,x)
  out(i+'\n Reault: ' +r)
}
<pre id=O></pre>
Your test:<input id=I><button onclick="test()">-></button>

edc65
fonte
Golfe incrível! De 300-163 ... Eu tiro meu chapéu para você ...
Wally West
1
@WallyWest com esse comentário, você me pressiona a fazer melhor. Thnx
edc65
Agradável! Minha solução Python era muito mais longa, mas eu estava tipo, está tudo bem, você usa um método melhor. Agora você usa o mesmo e é ainda mais curto ... Eu tenho algum trabalho a fazer. :)
randomra 17/05
@randomra eu ainda gostaria de vê-lo ...
Wally West
2

Python 3, 191

Provavelmente não é uma ótima pontuação, mas aqui vai:

def f(b,a,d,c):
 p,r,l,s,h=c+1j*d,-1j,1,0,0
 for _ in [0]*((a+b)**2):x,y=p.real,p.imag;0<x<a+1and 0<y<b+1and print(int((y-1)*a+x),end=' ');p+=r;s=(s+1)%l;t=s==0;h=(h+t)%2;l+=h<t;r*=(-1j)**t 

Nós nos movemos ao longo da espiral aumentando o comprimento do lado após cada segundo turno. Se nossa posição estiver dentro da grade especificada, imprimimos seu número correspondente.

As variáveis ​​são:

  • p é posição complexa
  • x e y são coordenadas de posição
  • r é direção
  • s é posição no lado atual
  • l é o comprimento lateral atual
  • h é a paridade do ordinal do lado atual
randomra
fonte