Đếm các điểm cuối của nghệ thuật ASCII


14

Bạn nên viết một chương trình hoặc hàm nhận chuỗi đại diện cho nghệ thuật ASCII làm đầu vào và đầu ra hoặc trả về số lượng điểm cuối trong đầu vào.

Đầu vào sẽ bao gồm các ký tự space - | +(với 0, 2, 2 và 4 điểm cuối tương ứng) và ngắt dòng. Ví dụ:

-|++-
  +

Hai ký tự liền kề được kết nối và do đó mất 1 điểm cuối trong mỗi trường hợp sau:

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

Ví dụ đầu tiên có

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

điểm cuối.

Đầu vào

  • Đầu vào sẽ là một chuỗi bao gồm các không gian nhân vật, -, |, +và xuống dòng.
  • Độ dài đầu vào có thể là 0 độ dài và bất kỳ đầu vào nào khớp với mô tả ở trên là hợp lệ (trong đầu vào regex là [ -+|\n]*).
  • Trailing newline là tùy chọn.

Đầu ra

  • Một số nguyên không âm duy nhất, số lượng điểm cuối.

Ví dụ

Đầu ra là sau hàng cuối cùng của đầu vào của họ.

+
4 

-|++-
  +
12 

+--+
|  |
+--+
8 

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

--++
 |||--
10 

<empty input>
0 


|
|     
2 

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

 ----
30 

Đây là mã golf nên mục ngắn nhất sẽ thắng.

Câu trả lời:


11

Ốc , 29

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

Tôi đã thêm nhận xét dòng với ,,, để tạo một phiên bản nhận xét.

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

JavaScript (ES6), 168

Sử dụng chuỗi mẫu, tất cả các dòng mới đều có ý nghĩa và được tính.

Kiểm tra chạy đoạn mã dưới đây trong Firefox. (Chrome vẫn không hỗ trợ ...)

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>


Những gì tôi cần làm là chia s thành hàng, sau đó thêm một hàng trống ở trên cùng và một hàng trống ở dưới cùng. Mã của bạn hoàn toàn không phân chia s. Bạn có thể làm điều ["",...s.split("\n"),""]đó lâu hơn @ETHproductions
edc65

À, đúng rồi, xin lỗi về điều đó.
Sản xuất ETH

3

Con trăn 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

Phương pháp một lượt. Đưa vào đầu vào một chuỗi với ngắt dòng.

Đối với các chiều ngang, ý tưởng là đếm số lượng các phân đoạn ngang, mỗi phân đoạn có hai điểm cuối. Một phân đoạn bắt đầu bất cứ khi nào một nhân vật là một trong số +-(boolean h) nhưng phân đoạn trước không phải là (boolean p).

Đối với ngành dọc, chúng tôi muốn thực hiện điều tương tự trên đầu vào được chuyển đổi, xem xét các lần chạy +|. Thật không may, sự hoán vị của Python thực sự rất rắc rối. Nó đòi hỏi một cái gì đó như map(None,*s.split('\n'))điền vào chỗ trống None, cũng là chính họ để đối phó.

Thay vào đó, chúng tôi thực hiện đếm dọc trong khi lặp theo chiều ngang. Chúng tôi giữ một danh sách lcác chỉ số cột vẫn đang "chạy", tức là ký tự trước đó trong cột đó kết nối xuống. Sau đó, chúng tôi làm tương tự như với chiều ngang, tính các phân đoạn dọc mới bắt đầu. Khi chúng tôi nhấn một dòng mới, chúng tôi sẽ cắt danh sách ngay tại nơi chúng tôi đang ở, vì tất cả các phân đoạn ở bên phải đã bị hỏng và đặt lại chỉ mục hiện tại thành 0.


3

CJam, 66 62 61 byte

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

Hãy thử trực tuyến trong trình thông dịch CJam .

Ý tưởng

Chúng ta có thể tính toán các điểm cuối như sau:

  1. Đếm số lượng -s, |s và +s trong đầu vào.
  2. Nhân số cuối cùng với 2 và thêm kết quả.
  3. Đếm số lượng --s, -+s, +-s và ++s trong các hàng.
  4. Đếm số lượng ||s. |+s, +|s và ++s trong các cột.
  5. Trừ kết quả từ 3 và 4 từ kết quả từ 2.
  6. Nhân kết quả từ 5 với 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.
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.