Петлі і петлі і петлі


16

Змагання

Створіть функцію, яка при введенні тексту ASCII art (спрямовуючи шлях, який може врешті циклу), виводить довжину циклу (якщо така є) та довжину "хвоста", що веде в цикл в одному з форми нижче.


Вхідні дані

Ваш вхід повинен бути переданий функції. Нижче наводиться приклад простого введення.

# --> # --> #
      ^     |
      |     |
      |     v
      # <-- #

Ви можете візуалізувати вищевказані блоки, як це

«Хвіст» - один предмет, а петля - чотири довгих.

Складніший:

            # --> # --> #
            ^           |
            |           |
            |           v
      # --> # <-- #     # --> #
      ^           ^           |
      |           |           |
      |           |           v
# --> #           # <-- # <-- #

Вихідні дані

Ви повинні виводити за допомогою STDOUT або найближчої альтернативи вашої мови.

Ваші два вихідні цілі числа повинні бути довжиною хвоста і довжиною петлі. Цей вихід може бути у двох формах.

  1. рядок з обмеженням пробілу: "2 10"
  2. масив цілих чисел: [2, 10]

Правила

  • Кожен блок, або #, матиме лише один шлях від себе.

  • Кожна стрілка - це два відрізки рядка та одна головка.

  • Стартовий блок завжди буде в крайньому лівому стовпчику.

  • Вхід ніколи не буде лише циклом.


Приклад

# --> # --> # --> #
^     ^           |
|     |           |
|     |           v
#     # <-- # <-- #

У цього довжина хвоста 2 та довжина петлі 6. Внизу хвіст та петля розділені.

Хвіст

# -->
^
|
|
#

Петля

# --> # --> #
^           |
|           |
|           v
# <-- # <-- #

Правильними виходами є [2, 6]і "2 6".

Якщо вхід - лише хвіст , довжина петлі дорівнює нулю.

# --> # --> # --> #
                  |
                  |
                  v
        <-- # <-- #

Правильними виходами для вищевказаного входу є [6, 0]і"6 0"


@orlp Я думаю, що ви плутаєте введення та вихід.
Санчіз

1
Чи можуть вхід мати додаткові відключені шматки шляху?
xnor

Я думаю, що вступ заплутане. Змушує мене думати, що проблема буде полягати в аналізі програми, тоді як у пошуку шляху в мистецтві ASCII.
xnor

Я видалив вступ. Це було трохи заплутано / вводити в оману. @xnor
Zach Gates

Відповіді:


11

JavaScript (ES6), 221 229

Функція з введенням як параметр, виводиться як рядок через спливаюче вікно (попередження).

Багаторазово скануйте вхід:
на кожному кроці

  • видаліть кінець хвоста
  • порахуйте решту "#"

Коли немає більше хвоста для видалення, кількість кроків поки що є розміром хвоста, а кількість залишилися '# - це розмір циклу.

Усі нові рядки всередині задників є вагомими і підраховуються

Тест запустіть фрагмент нижче за допомогою Firefox (не Chrome, оскільки він не підтримує ...)

F=s=>{s=`


${s}


`.split`
`.map(r=>[...r]);for(t=0,f=1;f;)s.map((r,y)=>r.map((c,x)=>c=='#'&&((r[x+2]+r[x-2]+s[y-1][x]+s[y+1][x]).match`[v<>^]`?++l:t+=(f=r[x-4]=r[x+4]=s[y-3][x]=s[y+3][x]=r[x]=1))),f=l=0);alert(t+' '+l)}

// Less golfed
U=s=>{
  s=`\n\n\n${s}\n\n\n`.split`\n`.map(r=>[...r])
  t=0
  do {
    f=l=0
    s.forEach((r,y) => {
      r.forEach((c,x) => {
        if (c == '#')
        {
          if (!(r[x+2] == '<' || r[x-2] == '>' || s[y-1][x] == 'v' || s[y+1][x] == '^'))
            t+=(f=r[x-4]=r[x+4]=s[y-3][x]=s[y+3][x]=r[x]=1)
          else
            ++l
        }
      })
    })
  } while(f)
  alert(t+' '+l)
}  

//Test

// Redefine console.log
alert=(...x)=>O.innerHTML+=x+'\n'

test=[`
# --> # --> #
      ^     |
      |     |
      |     v
      # <-- #`
,`
            # --> # --> #
            ^           |
            |           |
            |           v
      # --> # <-- #     # --> #
      ^           ^           |
      |           |           |
      |           |           v
# --> #           # <-- # <-- #`
,`
# --> # --> # --> #
^     ^           |
|     |           |
|     |           v
#     # <-- # <-- #`      
]

test.forEach(t=>(alert(t),F(t)))
<pre id=O></pre>


... правда оператор розповсюдження? Ви можете назвати його так, оскільки він існує в інших мовах (наприклад, groovy) іншими синтаксисами (*: список для groovy). Гарне рішення все одно!
Аарон

1
+1 Я думав: "Має бути розумний спосіб зробити це", придумав таке рішення, лише щоб прокрутити вниз до цієї відповіді.
Санчіз

8

Рубі, 287 278 байт

->i{n={}
g=->x{n[x]||=[0,p]}
t=y=0
i.lines{|l|x=0
l.chars{|c|x+=1
'><'[c]&&(r=c.ord-61;s,d=[y,x-4*r],[y,x+2*r])
'^v'[c]&&(r=c<?_?1:-1;s,d=[y+r*3,x],[y-r,x])
s&&(g[s][1]=g[d])[0]+=1}
y+=1}
c,*_,s=n.values.sort_by{|v|v[0]}
l=n.size
s[0]>1?((t+=1;c=c[1])while c!=s):t=l-=1
[t,l-t]}

Спробуйте тут .

Це створює хеш (словник) вузлів. Для кожного вузла зберігається кількість вхідних з'єднань та (можливо, нульовий) наступний вузол.

Нарешті:

  • Якщо немає вузла з двома вхідними з'єднаннями (мається на увазі відсутність циклу), поверніть 0 для хвоста та кількість існуючих вузлів для циклу.
  • В іншому випадку починайте ітерацію з вузла з 0 вхідних з'єднань (старт) через next -> ...-> next, поки не буде досягнуто вузла з двома вхідними з'єднаннями (цикл start). Поверніть відповідні рахунки.

Читаема версія коду доступна тут .


2

Рубі, 276

->s{a=k=w=s.index(r='
')*2+2
s=r*w+s+r*w
(s.size).times{|i|s[i,2]=='
#'&&(s[3+j=i+1]+s[j+w]+s[j-w]).strip.size<2&&(a=[j]
d=0
loop{("|-|-"[d])+?#=~/#{s[k=j+[-w,3,w,-3][d]]}/?(a.include?(k)&&break;a<<(j=k);d-=1):d=(d+1)%4}
)}
u=a.size
v=a.index(k)
t=(u-v)/4*2
print u/2-t," ",t}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.