Переместить стрелки вдоль контура


28

песочницы

Учитывая набор замкнутых непересекающихся 2d контуров (разделенных хотя бы одним пробелом даже по диагонали) со стрелками, ориентированными последовательно в одном и том же направлении по часовой стрелке или против часовой стрелки (каждый контур имеет свое направление) и положительным числом n, переместите стрелки nшаги по контурам в соответствующем направлении. Стрелки обозначены > v < ^соответственно для направления вправо, вниз, влево и вверх. Там другие символы -(горизонтальный), |(вертикальный) и +(угол). Когда стрелка находится в углу, она сохраняет свое текущее направление и меняет его только после выполнения поворота.

Между любыми двумя углами всегда будет прямой отрезок (или пространство) (как +-+для горизонтали, так и для вертикали) - другими словами, резкие Uповороты запрещены. Сегменты между углами являются вертикальными или горизонтальными, а изгиб в углу всегда составляет 90 градусов.

Входные данные:

  • положительное целое число n- число шагов
  • ASCII-представление контуров - это может быть многострочная строка, список строк, список символов и так далее.

Выход:

Одни и те же контуры со всеми стрелками сдвинули nшаги в общем направлении каждого контура.

Тестовые случаи:

1.

Входные данные:

n = 1

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

Выход:

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

2.

Входные данные:

n = 2

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

Выход:

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

3.

Входные данные:

n = 3

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

Выход:

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

4.

Входные данные:

n = 1

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

Выход:

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

5.

вход

n = 4

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

Выход:

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

6.

Входные данные:

n = 1

^->
^ v
<<v

Выход:

^>+
^ v
<<v

Напишите функцию или программу, решающую вышеуказанную задачу. Самый короткий код в байтах на каждом языке выигрывает. Не разочаровывайтесь языками игры в гольф. Объяснение алгоритма и кода высоко ценится.


Могут ли два контура касаться своих углов по диагонали, или контур так себя касается?
xнор

4
«При заданном наборе замкнутых непересекающихся 2d контуров ... со стрелками, ориентированными последовательно в одном и том же направлении по часовой стрелке или против часовой стрелки» мне кажется, что каждый контур ориентирован в одном и том же направлении, тогда как из тестовых случаев стрелки должны быть согласованы только внутри контура.
XNOR

3
@xnor Спасибо за ваши комментарии! - Нет, контуры не должны касаться друг друга / себя по диагонали. - У каждого контура есть свой директон. Я обновлю описание.
Гален Иванов

2
Возможен ли ввод без промежутка между стенами? Например: попробуйте онлайн! , Я знаю, что вы сказали «разделены хотя бы одним пробелом», но мне было неясно, относится ли это только к независимым циклам или же к одному циклу.
Иона

1
@ Иона Нет, это невозможно: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.
Гален Иванов

Ответы:


14

JavaScript (ES6),  210 ... 182  180 байт

(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

Попробуйте онлайн!

Как?

Вы можете перейти по этой ссылке, чтобы увидеть отформатированную версию источника.

обертка

gn1n=0

Метод обновления

Мы не можем безопасно перемещать каждую стрелку по одной за раз, потому что мы рискуем перезаписать не обновленные стрелки новыми. Вместо этого мы сначала удаляем все стрелки и вычисляем их новые позиции. Мы применяем новые позиции во второй раз.

n

n

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

n

Новые позиции применяются просто делая eval(n).

Направления

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

уголки

hddxor1dxor3

+-|d

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

Анимированная версия


Спасибо вам за разъяснение!
Гален Иванов

8

К (нгн / к) , 183 161 157 байт

{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]}/

Попробуйте онлайн!

{ }/при вызове с левым аргументом int, функция будет применена { }n раз к правому аргументу

A:"^>v<" стрелы

D,:-D:(-1 0;!2) ∆y, ∆x для 4-х основных направлений

s:(#x;#*x) Форма ввода: высота, ширина

c:~^x countours - логическая матрица, показывающая, где находятся непробелы

r:" -+|"c*+/'3'0,c,0воссоздать матрицу символов с контуром, но без стрелок, считая self + upper + lower для каждой ячейки cи заменяя 1-> -, 2-> +, 3->|

t:A?,/xтипы стрелок: 0 1 2 3 для ^>v<, все остальные ячейки представлены как 0N(ноль)

p:+s\&~^t координаты стрелок

$[#p ;;:r] если стрелок нет, вернитесь r

q:+p+/:D@4!(t^0N)+/:0 1 3 все 3 возможных новых положения для каждой стрелки - если она продолжает двигаться вперед, если она поворачивает влево и если она поворачивает направо

q:q@'*'&'~^x ./:/:q для каждой стрелки выберите первый вариант, который попадает на контур

@[,/r;s/+q;:;A@D?q-p]выровнять rи надеть стрелки на их новые позиции и с их новыми направлениями

s# изменить первоначальную форму


2
Ты быстрый! Я надеюсь, вы объясните код после того, как закончите играть в гольф.
Гален Иванов

Спасибо вам за разъяснение!
Гален Иванов

4

Древесный уголь , 105 байт

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

Попробуйте онлайн! Ссылка на подробную версию кода. Включает 22 байта, используемых, чтобы избежать необходимости громоздкого входного формата. Объяснение:

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

Удобно вводим контуры и количество шагов.

≔>^<vζ

Символы направления используются несколько раз, поэтому строка кэшируется здесь. Индекс символа направления в этой строке называется его направлением.

Pθ

Напечатайте исходные контуры без перемещения курсора.

Fθ

Обведите символы в контуре.

¿№ζι«

Если текущие символы являются символом направления ...

⊞υ⟦⌕ζιⅉⅈ⟧

... затем сохраните направление и позицию в списке ...

§+|-↨EKV›κ ²

... и замените символ соответствующим символом строки.

»ι

В противном случае выведите символ и перейдите к следующему символу.

Fυ«

Зациклите сохраненные позиции.

J⊟ι⊟ι

Перейти в сохраненную позицию.

≔⊟ιι

Извлеките сохраненное направление.

FIη«

Зациклиться на соответствующем количестве шагов.

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

Найдите направление следующего шага - любое направление, которое не является ни обратным, ни пустым.

M✳⊗ι

Сделайте шаг в этом направлении. (Индексы направления древесного угля для Moveкоманды в два раза больше моего направления.)

»§ζι

Напечатайте соответствующий символ направления.


Спасибо вам за разъяснение!
Гален Иванов

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.