ASCII 아트의 끝점 계산


14

ASCII 아트를 나타내는 문자열을 입력으로 수신하고 출력하거나 입력의 끝점 수를 반환하는 프로그램 또는 함수를 작성해야합니다.

입력은 문자 space - | +(각각 0, 2, 2 및 4 엔드 포인트 포함)와 줄 바꿈으로 구성됩니다. 예 :

-|++-
  +

두 개의 인접한 문자가 연결되어 다음과 같은 경우 각각 1 개의 끝점을 잃습니다.

--  -+  +- |  |  +  +  ++
           |  +  |  +

첫 번째 예는

2+2+2+2+1+
    3        = 12

끝점.

입력

  • 입력 문자 공간으로 구성된 문자열입니다 -, |, +뉴 라인.
  • 입력 길이는 0 길이 일 수 있으며 위의 설명과 일치하는 모든 입력이 유효합니다 (정규식 입력은 [ -+|\n]*).
  • 후행 줄 바꿈은 선택 사항입니다.

산출

  • 끝이 아닌 단일 음수가 아닌 정수.

출력은 입력의 마지막 행 뒤에 있습니다.

+
4 

-|++-
  +
12 

+--+
|  |
+--+
8 

  |  |
  +--+-- |||
12 

--++
 |||--
10 

<empty input>
0 


|
|     
2 

--
++--
 ++
   --+
  +++ || 

 ----
30 

이것은 코드 골프이므로 가장 짧은 참가작이 승리합니다.

답변:


11

달팽이 , 29

A
\+|\-)lr!\-|(\+|\|)n!\|}!\+

주석 ,,이 달린 버전을 만들기 위해으로 라인 주석을 추가했습니다 .

A                    ,, Count all accepting paths
        \+ | \- )    ,, Literal '+' or '-'        
        lr           ,, Set direction to left or right
        !\-          ,, Assert next char is not '-'
    |                ,, Or...
        ( \+ | \| )  ,, Literal '+' or '|'
        n            ,, Turn 90 degrees right or left (from initial direction right)
        !\|          ,, Assert next char is not '|'
}                    ,, Group everything previous
!\+                  ,, Assert next char is not '+'

5

자바 스크립트 (ES6), 168

템플릿 문자열을 사용하면 모든 줄 바꿈이 중요하고 계산됩니다.

Firefox에서 아래 스 니펫을 테스트하십시오. (Chrome은 여전히 ​​지원하지 않습니다 ...)

f=s=>`
${s}
`.split`
`.map((r,y,s,v=c=>c>' '&c!='-',h=c=>c>' '&c<'|')=>[...r].map((c,x)=>t+=(v(c)?2-v(s[y-1][x])-v(s[y+1][x]):0)+(h(c)?2-h(r[x-1])-h(r[x+1]):0)),t=0)&&t

// Less golfed
u=s=>{
  s = ('\n' + s + '\n').split('\n'); // split in rows, adding a blank line at top and one at bottom
  t = 0; // init counter
  v = c => c>' ' & c!='-'; // function to check if a character has vertical end points
  h = c => c>' ' & c<'|'; // function to check if a character has horizontal end points
  s.forEach( (r,y) =>
    [...r].forEach( (c,x) => {
     if (v(c)) // if current character has vertical endpoints, check chars in previous and following row
        t += 2 - v(s[y-1][x]) - v(s[y+1][x]); 
     if (h(c))  // if current character has horizontal endpoints, check previous and following chars in row
        t += 2 - h(r[x-1]) - h(r[x+1]);
    })
  )  
  return t
}

//TEST
out=x=>O.innerHTML+=x+'\n'

;[
 [`+`,4]
,[`-|++-
  +`,12]
,[`+--+
|  |
+--+`,8]
,[`  |  |
  +--+-- |||`,12]
,[`--++
 |||--`,10]
,[``,0]
,[`
|
|`,2]
,[`
--
++--
 ++
   --+
  +++ || 

 ----`,30]
].forEach(t=>{ r=f(t[0]),k=t[1],out('Test '+(r==k?'OK':'Fail')+'\n'+t[0]+'\nResult:'+r+'\nCheck:'+k+'\n') })
<pre id=O></pre>


내가해야 할 일은 s를 행으로 분할 한 다음 맨 위에 빈 행을 추가하고 맨 아래에 빈 행을 추가하는 것입니다. 코드가 전혀 분할되지 않습니다. 당신 ["",...s.split("\n"),""]은 더 이상 할 수있다 @ETHproductions
edc65

아, 맞아요
ETHproductions

3

파이썬 2, 123

l=[]
i=p=t=0
for c in input():
 l+=0,;h=c in'-+';t+=h>p;p=h;v=c in'|+';t+=v>l[i];l[i]=v;i+=1
 if' '>c:l=l[:i];i=0
print t*2

원 패스 방식. 줄 바꿈이있는 문자열을 입력으로받습니다.

수평의 경우 두 개의 끝 점이있는 수평 세그먼트 수를 계산하는 것이 좋습니다. 캐릭터가 +-(boolean h) 중 하나이지만 이전 세그먼트는 (boolean )이 아닐 때마다 세그먼트가 시작됩니다 p.

수직선의 경우,을 보면서 조옮김 된 입력에서 동일한 작업을 수행하려고합니다 +|. 불행히도 파이썬의 조옮김은 정말 어수선합니다. 그것은 같은 것을 요구합니다map(None,*s.split('\n'))빈칸을 채우는None .

대신 수평을 반복하면서 수직 카운트를 수행합니다. 우리 l는 어떤 열 인덱스가 여전히 "실행 중"인지, 즉 해당 열의 이전 문자가 연결되는 위치 의 목록 을 유지합니다 . 그런 다음 새로 시작한 수직 세그먼트를 세면서 수평과 동일한 작업을 수행합니다. 줄 바꿈을 할 때 오른쪽의 모든 세그먼트가 끊어 졌으므로 현재 위치의 목록을 잘라 내고 현재 색인을로 재설정합니다 0.


3

CJam, 66 62 61 바이트

q_N/_z,S*f.e|zN*"-|++"2$fe=1b"|-"{'++:R:a@+2ew{aR2m*&},,-}/2*

CJam 통역사 에서 온라인으로 사용해보십시오 .

생각

다음과 같이 엔드 포인트를 계산할 수 있습니다.

  1. 입력에서 -s, |s 및 +s 의 수를 센다 .
  2. 마지막에 2를 곱하고 결과를 더하십시오.
  3. 의 수를 카운트 --들, -+s가 +-들과 ++행에이야.
  4. 의 수를 센다 ||. 열에서 |+s, +|s 및 ++s.
  5. 2의 결과에서 3과 4의 결과를 뺍니다.
  6. 5의 결과에 2를 곱하십시오.

암호

q        e# Read all input from STDIN.
_N/      e# Push a copy and split it at linefeeds.
_z,      e# Count the number of rows of the transposed array.
         e# This pushes the length of the longest row.
S*       e# Push a string of that many spaces.
f.e|     e# Perform vectorized logical OR with the rows.
         e# This pads all rows to the same length.
zN*      e# Transpose and join, separating by linefeeds.
"-|++"   e# Push that string.
2$       e# Copy the original input.
fe=      e# Count the occurrences of '-', '|', '+' and '+' in the input.
1b       e# Add the results.
"|-"{    e# For '|' and '-':
  '++    e#   Concatenate the char with '+'.
  :R     e#   Save the resulting string in R.
  :a     e#   Convert it into an array of singleton strings.
  @      e#   Rotate one of the two bottom-most strings on top of the stack.
         e#   This gets the transposed input for '|' and the original input for '-'.
  +      e#   Concatenate both arrays.
         e#   This pads the input with nonsense to a length of at least 2.
  2ew    e#   Push a overlapping slices of length 2.
  {      e#   Filter the slices; for each:
    a    e#     Wrap it in an array.
    R2m* e#     Push the second Cartesian power of R.
         e#     For '|', this pushes ["||" "|+" "+|" "++"].
    &    e#     Intersect.
  },     e#   If the intersection was non-empty, keep the slice.
  ,      e#   Count the kept slices.
  -      e#   Subtract the amount from the integer on the stack.
}/       e#
2*       e# Multiply the result by 2.
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.