Петли и петли и петли

16

Соревнование

Создайте функцию, которая при получении входных данных искусства ASCII (направляя путь, который может в конечном итоге зацикливаться), выводит длину цикла (если он есть) и длину «хвоста», ведущего в цикл в одном из формы ниже.


вход

Ваш вклад должен быть передан в функцию. Ниже приведен пример простого ввода.

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

Вы можете визуализировать вышеуказанные блоки, как это

«Хвост» - это один элемент, а цикл - четыре.

Более сложный:

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

Выход

Вы должны выводить через STDOUT или ближайшую альтернативу вашего языка.

Ваши два выходных целых числа должны быть длиной хвоста и длиной цикла. Этот вывод может быть в двух формах.

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

правила

  • Каждый блок, или #, будет иметь только один путь от себя.

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

  • Начальный блок всегда будет в крайнем левом столбце.

  • Вход никогда не будет просто петлей.


пример

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

Этот имеет длину хвоста 2 и длину петли 6. Ниже хвост и петля разделены.

Хвост

# -->
^
|
|
#

петля

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

Правильные выводы есть [2, 6]и "2 6".

Если вход является только хвостом , длина цикла равна нулю.

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

Правильные выходы для вышеуказанного ввода [6, 0]и"6 0"

Зак Гейтс
источник
@ или я думаю, что вы путаете ввод и вывод.
Санчиз
1
Может ли вход иметь дополнительные отключенные части пути?
xnor
Я думаю, что введение вводит в заблуждение. Это заставляет меня думать, что проблема будет в программном анализе, тогда как речь идет о поиске пути в искусстве ASCII.
xnor
Я удалил вступление. Это было немного запутанным / вводящим в заблуждение. @xnor
Зак Гейтс
3
Связанный: Куда указывает стрелка?
Минксомаа

Ответы:

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>

edc65
источник
... оператор спреда прав? Возможно, вы захотите назвать его так, так как он существует в других языках (например, 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]}

Попробуй это здесь .

Это создает хэш (словарь) узлов. Для каждого узла сохраняется количество входящих соединений и (возможно, ноль) следующий узел.

В заключение:

  • Если нет узла с 2 входящими соединениями (что означает отсутствие цикла), верните 0 для хвоста и количество существующих узлов для цикла.
  • В противном случае начните итерацию с узла с 0 входящими соединениями (начало) через next -> ...-> next до тех пор, пока не будет достигнут узел с 2 входящими соединениями (запуск цикла). Верните соответствующий счет.

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

Кристиан Лупаску
источник
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}
Уровень реки St
источник