Перемістіть стрілки по контуру


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

Напишіть функцію або програму, що розв’язує вищезазначене завдання. Виграє найкоротший код у байтах на кожній мові. Не відволікайте мов на гольф. Пояснення алгоритму та коду високо оцінено.


Чи можуть два контури торкатися своїх кутів по діагоналі, або ж контур торкається саме цього?
xnor

4
"Враховуючи набір закритих неперекриваються 2d контурів ... зі стрілками, орієнтованими послідовно в одному і тому ж напрямку або проти годинникової стрілки", мені здається, що кожен контур орієнтований в одному напрямку, тоді як з тестових випадків здається, що стрілки повинні відповідати лише контуру.
xnor

3
@xnor Дякуємо за ваші коментарі! - Ні, контури не дозволяють торкатися один до одного по діагоналі. - Кожен контур має свою дирекцію. Я оновлю опис.
Гален Іванов

2
Чи можливий вхід без місця між стінами? Наприклад: Спробуйте в Інтернеті! . Я знаю, ви сказали, що "розділений принаймні одним пробілом", але мені було незрозуміло, чи застосовується це лише до незалежних циклів або якщо він також застосовується до одного циклу.
Іона

1
@Jonah Ні, це неможливо: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, це застосує функцію в { }n разів до правої arg

A:"^>v<" стрілки

D,:-D:(-1 0;!2) ∆y, ∆x для 4-х кардинальних напрямків

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

c:~^x countours - булева матриця, що показує, де знаходяться непробіли

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

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

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.