Loop dan Loop dan Loop

16

Tantangan

Buat fungsi yang, ketika diberi input seni ASCII (mengarahkan jalur yang pada akhirnya mungkin loop), output panjang loop (jika ada satu) dan panjang "ekor" yang mengarah ke loop di salah satu formulir di bawah ini.


Memasukkan

Masukan Anda harus diteruskan ke suatu fungsi. Di bawah ini adalah contoh input sederhana.

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

Anda dapat memvisualisasikan blok di atas seperti ini

"Ekor" adalah satu item, sedangkan loop empat panjang.

Yang lebih sulit:

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

Keluaran

Anda harus mengeluarkan melalui STDOUT atau alternatif terdekat bahasa Anda.

Dua bilangan bulat keluaran Anda harus panjang dari ekor dan panjang dari loop. Output ini bisa dalam dua bentuk.

  1. string yang dibatasi ruang: "2 10"
  2. array bilangan bulat: [2, 10]

Aturan

  • Setiap blok, atau #, hanya akan memiliki satu jalur dari dirinya sendiri.

  • Setiap panah adalah dua segmen garis dan satu kepala.

  • Blok awal akan selalu berada di kolom paling kiri.

  • Input tidak akan pernah menjadi hanya satu lingkaran.


Contoh

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

Yang ini memiliki panjang ekor 2 dan panjang lingkaran 6. Di bawah, ekor dan lingkaran dipisahkan.

Ekor

# -->
^
|
|
#

Loop

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

Output yang benar adalah [2, 6]dan"2 6" .

Jika input hanya berupa ekor , panjang loop adalah nol.

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

Output yang benar untuk input di atas adalah [6, 0]dan"6 0"

Zach Gates
sumber
@ orlp Saya pikir Anda membingungkan input dan output.
Sanchises
1
Bisakah input memiliki potongan jalur tambahan yang terputus?
xnor
Saya pikir intro ini membingungkan. Itu membuat saya berpikir masalahnya adalah tentang analisis program, sedangkan itu adalah tentang pencarian jalan dalam seni ASCII.
xnor
Saya sudah menghapus intro. Itu agak membingungkan / menyesatkan. @xnor
Zach Gates
3
Terkait: Di mana panah menunjuk?
mınxomaτ

Jawaban:

11

JavaScript (ES6), 221 229

Suatu fungsi dengan input sebagai parameter, output sebagai string melalui jendela popup (peringatan).

Pindai input berulang kali:
pada setiap langkah

  • lepaskan ujung ekor
  • hitung sisa '#'

Ketika tidak ada lagi ekor yang harus dihilangkan, jumlah langkah sejauh ini adalah ukuran ekor dan jumlah sisa '# adalah ukuran lingkaran.

Semua baris baru di dalam backticks signifikan dan dihitung

Tes menjalankan cuplikan di bawah ini dengan Firefox (bukan Chrome, karena tidak mendukung ...)

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
sumber
... apakah operator penyebarannya benar? Anda mungkin ingin memberi nama dengan cara ini karena ada dalam bahasa lain (seperti asyik) oleh sintaks lain (*: daftar untuk asyik). Solusi yang bagus!
Aaron
1
+1 Saya berpikir 'Pasti ada cara cerdas untuk melakukan ini', muncul dengan solusi ini, hanya untuk menggulir ke bawah ke jawaban ini.
Sanchises
8

Ruby, 287 278 byte

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

Coba di sini .

Ini membangun hash (kamus) dari node. Untuk setiap node, jumlah koneksi yang masuk dan node berikutnya (mungkin nol) disimpan.

Akhirnya:

  • Jika tidak ada simpul dengan 2 koneksi masuk (artinya tidak ada loop), kembalikan 0 untuk tail dan jumlah node yang ada untuk loop.
  • Kalau tidak, mulai iterasi dari node dengan 0 koneksi masuk (start) via berikutnya -> ...-> selanjutnya hingga node dengan 2 koneksi masuk (loop start) tercapai. Kembalikan jumlah yang sesuai.

Versi kode yang dapat dibaca tersedia di sini .

Cristian Lupascu
sumber
2

Ruby, 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}
Level River St
sumber