Mover setas ao longo de um contorno

28

Sandboxed

Dado um conjunto de contornos 2d fechados e não sobrepostos (separados por pelo menos um espaço, mesmo nas diagonais) com setas orientadas consistentemente na mesma direção no sentido horário ou anti-horário (cada contorno tem sua própria direção) e um número positivo n, mova as setas npassos ao longo dos contornos na respectiva direção. As setas são representadas por > v < ^respectivamente para as direções direita, baixo, esquerda e cima. Lá, os outros caracteres são -(horizontal), |(vertical) e +(canto). Quando uma flecha está em um canto, ela mantém sua direção atual e a altera somente após a virada.

Sempre haverá um segmento reto (ou um espaço) entre dois cantos (como +-+na horizontal e similar na vertical) - em outras palavras, as Ucurvas acentuadas são proibidas. Os segmentos entre os cantos são verticais ou horizontais e a dobra em um canto é sempre 90 graus.

Entrada:

  • um número inteiro positivo - n- número de etapas
  • uma representação ASCII dos contornos - pode ser uma cadeia de linhas múltiplas, uma lista de cadeias, uma lista de caracteres e assim por diante.

Saída:

Os mesmos contornos com todas as setas mudaram as netapas na direção geral de cada contorno.

Casos de teste:

1

Entrada:

n = 1

 +----->->            
 |       |            
 |       v---+        
 |           |        
 +---<-------+      

Saída:

 +------>+
 |       v
 |       +>--+
 |           |
 +--<--------+

2)

Entrada:

n = 2

 +-----+ +---+        
 |     | |   |        
 +-->--+ |   v  
         |   | 
 +--->---+   |        
 |           |         
 +------<<---+       

Saída:

 +-----+ +---+
 |     | |   |
 +---->+ |   |
         |   | 
 +----->-+   v
 |           |     
 +----<<-----+        

3)

Entrada:

n = 3

 +---+   +---+   +-------+      
 |   |   |   v   |       |      
 ^   |   |   |   +-<-+   |      
 |   |   ^   |       |   v      
 |   +---+   +-->----+   |      
 |                       |      
 |   +-------+   +---+   |      
 |   |       |   v   |   |      
 +---+       +---+   +---+      

Saída:

 +>--+   ^---+   +-------+
 |   |   |   |   ^       |
 |   |   |   |   +---+   |
 |   |   |   |       |   |
 |   +---+   v----->-+   |
 |                       |
 |   +-------+   +---+   v 
 |   |       |   |   |   |
 +---+       +-<-+   +---+  

4)

Entrada:

n = 1

+--+ 
|  |
|  +---+
|      |     
+----+ |
     | |
     +-+ 

Saída:

+--+ 
|  |
|  +---+
|      |     
+----+ |
     | |
     +-+ 

5)

Entrada

n = 4

^>>>>
^   v
^   v>>>>
^       v           
<<<<<<<<v

Saída:

^>>>>
^   v
^   v>>>>
^       v           
<<<<<<<<v

6

Entrada:

n = 1

^->
^ v
<<v

Saída:

^>+
^ v
<<v

Escreva uma função ou um programa que resolva a tarefa acima. O código mais curto em bytes em todos os idiomas vence. Não desanime pelas línguas do golfe. A explicação do algoritmo e do código é altamente apreciada.

Galen Ivanov
fonte
Dois contornos podem tocar seus cantos em uma diagonal ou um contorno se tocar dessa maneira?
xnor 31/07
4
"Dado um conjunto de contornos 2d fechados e não sobrepostos ... com setas orientadas consistentemente na mesma direção no sentido horário ou anti-horário" me parece que todo contorno é orientado na mesma direção, enquanto nos casos de teste parece que as setas só devem ser consistentes dentro de um contorno.
xnor 31/07
3
Obrigado por seus comentários! - Não, os contornos não podem se tocar na diagonal. - Cada contorno tem seu próprio directon. Vou atualizar a descrição.
Galen Ivanov
2
É possível a entrada sem espaço entre as paredes? Por exemplo: Experimente online! . Sei que você disse "separado por pelo menos um espaço", mas não estava claro se isso se aplicava apenas a loops independentes ou se se aplicava a um único loop.
Jonah
1
@Jonah Não, não é possível:There will always be a straight segment (or a space) between any two corners (like +-+ for the horizontal and similar for the vertical) - in other words the sharp U turns are forbidden.
Galen Ivanov

Respostas:

14

JavaScript (ES6),  210 ... 182  180 bytes

(m)(n)m

m=>g=n=>n?g(n-1,m=m.map((r,y)=>r.map((c,x)=>(i=0,h=$=>~$?(m[Y=y+($-2)%2]||0)[X=x+~-$%2]>h?"-|+"[n+=`;m[${Y}][${X}]=S[${$}]`,i?2:$&1]:h($^++i):c)((S="<^>v").indexOf(c)))),eval(n)):m

Experimente online!

Quão?

Você pode seguir este link para ver uma versão formatada da fonte.

Embrulho

gn1n=0

Atualizar método

Não podemos mover com segurança cada flecha uma de cada vez, porque correríamos o risco de sobrescrever flechas não atualizadas por flechas atualizadas. Em vez disso, primeiro removemos todas as setas e calculamos suas novas posições. Aplicamos as novas posições pela segunda vez.

n

n

"1;m[0][7]=S[2];m[1][8]=S[3];m[2][9]=S[2];m[4][3]=S[0]"

n

As novas posições são aplicadas apenas fazendo eval(n).

instruções

d$

10+23

dxdy

 d | dx = (d - 1) % 2 | dy = (d - 2) % 2
---+------------------+------------------
 0 |        -1        |         0
 1 |         0        |        -1
 2 |        +1        |         0
 3 |         0        |        +1

Cantos

hddxor1dxor3

+-|d

h$h"$""$""$"

Versão animada

Arnauld
fonte
Obrigado pela explicação!
Galen Ivanov
8

K (ngn / k) , 183 161 157 bytes

{A:"^>v<";D,:-D:(-1 0;!2);s:(#x;#*x);c:~^x;r:" -+|"c*+/'3'0,c,0;$[#p:+s\&~^t:A?,/x;;:r];q:q@'*'&'~^x ./:/:q:+p+/:D@4!(t^0N)+/:0 1 3;s#@[,/r;s/+q;:;A@D?q-p]}/

Experimente online!

{ }/quando chamado com um argumento à esquerda int n, isso aplicará a função em { }n vezes ao argumento à direita

A:"^>v<" Setas; flechas

D,:-D:(-1 0;!2) Y, x para as 4 direções cardeais

s:(#x;#*x) forma da entrada: altura, largura

c:~^x countours - matriz booleana mostrando onde estão os não-espaços

r:" -+|"c*+/'3'0,c,0recrie a matriz de caracteres com um countour, mas sem setas, contando self + upper + lower para cada célula ce substituindo 1-> -, 2-> +, 3->|

t:A?,/xtipos de setas: 0 1 2 3 para ^>v<, todas as outras células são representadas como 0N(nulas)

p:+s\&~^t coordenadas das setas

$[#p ;;:r] se não houver flechas, retorne r

q:+p+/:D@4!(t^0N)+/:0 1 3 todas as 3 novas posições possíveis para cada seta - se continuar avançando, se virar à esquerda e se virar à direita

q:q@'*'&'~^x ./:/:q para cada flecha, escolha a primeira opção que caia no contorno

@[,/r;s/+q;:;A@D?q-p]achatar re colocar as setas em suas novas posições e com suas novas direções

s# remodelar para a forma original

ngn
fonte
2
Você é rápido! Espero que você explique o código depois de terminar o jogo.
Galen Ivanov
Obrigado pela explicação!
Galen Ivanov
4

Carvão , 105 bytes

W¬ΦυΣκ⊞υS≔⊟υη≔⪫υ⸿θ≔⟦⟧υ≔>^<vζPθFθ¿№ζι«⊞υ⟦⌕ζιⅉⅈ⟧§+|-↨EKV›κ ²»ιFυ«J⊟ι⊟ι≔⊟ιιFIη«≔⊟Φ⁴∧﹪⁻⊖ι⊕λ⁴›§KV⁻⁵λ ιM✳⊗黧ζι

Experimente online! Link é a versão detalhada do código. Inclui 22 bytes usados ​​para evitar a necessidade de um formato de entrada complicado. Explicação:

W¬ΦυΣκ⊞υS≔⊟υη≔⪫υ⸿θ≔⟦⟧υ

Insira convenientemente os contornos e o número de etapas.

≔>^<vζ

Os caracteres de direção são usados ​​várias vezes para que a string seja armazenada em cache aqui. O índice de um caractere de direção nessa sequência é conhecido como sua direção.

Pθ

Imprima os contornos originais sem mover o cursor.

Fθ

Faça um loop sobre os caracteres no contorno.

¿№ζι«

Se os caracteres atuais são um caractere de direção ...

⊞υ⟦⌕ζιⅉⅈ⟧

... salve a direção e a posição em uma lista ...

§+|-↨EKV›κ ²

... e substitua o caractere pelo caractere de linha apropriado.

»ι

Caso contrário, imprima o caractere e passe para o próximo caractere.

Fυ«

Faça um loop sobre as posições salvas.

J⊟ι⊟ι

Salte para a posição salva.

≔⊟ιι

Extraia a direção salva.

FIη«

Faça um loop sobre o número apropriado de etapas.

≔⊟Φ⁴∧﹪⁻⊖ι⊕λ⁴›§KV⁻⁵λ ι

Encontre a direção do próximo passo, que é qualquer direção que não seja inversa nem vazia.

M✳⊗ι

Dê um passo nessa direção. (Os índices de direção do carvão para o Movecomando são duas vezes o valor da minha direção.)

»§ζι

Imprima o caractere de direção apropriado.

Neil
fonte
Obrigado pela explicação!
Galen Ivanov
2

APL (Dyalog Unicode) , SBCS de 111 bytes

{A[Dq-p]@q' |+-'[c×3+/0,c,0]⊣q←⊃¨(⍸c' '≠⍵)∘∩¨↓⍉D[4|0 1 3∘.+4~⍨,t]+⍤1p←⍸4>t←⍵⍳⍨A'v>^<'D9 11∘○¨0j1*⍳4}⍣⎕⊢⎕

Experimente online!

semelhante à minha resposta k

ngn
fonte