루프와 루프와 루프


16

도전

ASCII 아트의 입력이 주어지면 (최종 루프 될 수있는 경로를 지시 할 때) 루프 길이 (있는 경우)와 루프 중 하나에 루프로 이어지는 "꼬리"의 길이를 출력하는 함수를 작성하십시오. 아래 양식.


입력

입력은 함수로 전달되어야합니다. 아래는 간단한 입력의 예입니다.

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

위의 블록을 다음과 같이 시각화 할 수 있습니다

"꼬리"는 하나의 항목이며 루프는 4 개입니다.

더 어려운 것 :

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

산출

STDOUT 또는 언어의 가장 가까운 대안을 통해 출력해야합니다.

두 개의 출력 정수는 꼬리의 길이와 루프의 길이 여야합니다. 이 출력은 두 가지 형태가 될 수 있습니다.

  1. 공백으로 구분 된 문자열 : "2 10"
  2. 정수 배열 : [2, 10]

규칙

  • 모든 블록, 또는 #만 것입니다 멀리 단일 경로를 자체에서.

  • 모든 화살표는 두 개의 선분과 하나의 머리입니다.

  • 시작 블록은 항상 가장 왼쪽 열에 있습니다.

  • 입력은 결코 루프가되지 않습니다.


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

이것은 꼬리 길이가 2이고 루프 길이가 6입니다. 아래에서 꼬리와 루프가 분리됩니다.

꼬리

# -->
^
|
|
#

고리

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

올바른 출력은 [2, 6]"2 6"입니다.

입력 값이 tail 이면 루프 길이는 0입니다.

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

상기 입력에 대한 올바른 출력은 [6, 0]"6 0"


@orlp 입력과 출력을 혼란스럽게 생각합니다.
Sanchises

1
입력에 별도의 연결이 끊어진 경로가있을 수 있습니까?
xnor

소개가 혼란 스럽다고 생각합니다. ASCII 아트에서의 경로 찾기에 관한 것이지만 프로그램 분석에 관한 문제라고 생각합니다.
xnor

소개를 삭제했습니다. 약간 혼란스럽고 오도했습니다. @xnor
Zach Gates

답변:


11

자바 스크립트 (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의 경우 * : list)으로 존재하므로이 방법으로 이름을 지정할 수 있습니다. 어쨌든 좋은 해결책!
Aaron

1
+1 나는 '이 작업을 수행하는 현명한 방법이 있어야합니다.'라고 생각 하고이 솔루션을 생각해 보았습니다.
Sanchises

8

루비, 287278 바이트

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

여기서 사용해보십시오 .

이것은 노드의 해시 (사전)를 만듭니다. 각 노드에 대해 들어오는 연결 수와 다음 노드 (아마도 null)가 저장됩니다.

드디어:

  • 들어오는 연결이 2 개인 노드가없는 경우 (루프 없음) 꼬리의 경우 0을, 루프의 기존 노드 수를 반환합니다.
  • 그렇지 않으면, 2 개의 들어오는 연결이있는 노드 (루프 시작)에 도달 할 때까지 next-> ...-> 다음을 통해 0 개의 들어오는 연결 (시작)로 노드에서 반복을 시작하십시오. 적절한 카운트를 반환하십시오.

읽을 수있는 코드 버전은 여기에서 확인할 수 있습니다 .


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}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.