Menghitung Titik Akhir dari Seni ASCII


14

Anda harus menulis program atau fungsi yang menerima string yang mewakili seni ASCII sebagai input dan output atau mengembalikan jumlah titik akhir dalam input.

Input akan terdiri dari karakter space - | +(masing-masing dengan titik akhir 0, 2, 2 dan 4) dan linebreak. Misalnya:

-|++-
  +

Dua karakter yang berdekatan terhubung dan karenanya masing-masing kehilangan 1 titik akhir dalam kasus berikut:

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

Contoh pertama memiliki

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

titik akhir.

Memasukkan

  • Masukan akan menjadi string yang terdiri dari karakter ruang, -, |, +dan baris baru.
  • Panjang input dapat 0 panjang dan input apa pun yang cocok dengan uraian di atas valid (dalam input regex adalah [ -+|\n]*).
  • Mengejar baris baru adalah opsional.

Keluaran

  • Bilangan bulat non-negatif tunggal, jumlah titik akhir.

Contohnya

Keluaran adalah setelah baris terakhir dari input mereka.

+
4 

-|++-
  +
12 

+--+
|  |
+--+
8 

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

--++
 |||--
10 

<empty input>
0 


|
|     
2 

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

 ----
30 

Ini adalah kode golf sehingga entri terpendek menang.

Jawaban:


11

Siput , 29

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

Saya menambahkan komentar baris dengan ,,, untuk membuat versi komentar.

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

Menggunakan string template, semua baris baru signifikan dan dihitung.

Tes menjalankan cuplikan di bawah ini di Firefox. (Chrome masih tidak mendukung ...)

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>


Yang perlu saya lakukan adalah membelah s dalam baris, kemudian menambahkan baris kosong di atas dan baris kosong di bawah. Kode Anda tidak terpecah sama sekali. Anda bisa melakukannya ["",...s.split("\n"),""]lebih lama @ETHproduksi
edc65

Ah, benar, maaf soal itu.
ETHproduk

3

Python 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

Metode sekali jalan. Dibawa sebagai input string dengan linebreak.

Untuk horizontal, idenya adalah untuk menghitung jumlah segmen horisontal, yang masing-masing memiliki dua titik akhir. Segmen dimulai setiap kali karakter adalah salah satu dari +-(boolean h) tetapi yang sebelumnya tidak (boolean p).

Untuk vertikal, kami ingin melakukan hal yang sama pada input yang ditransposisikan, dengan melihat run of +|. Sayangnya, transposing Python benar-benar kikuk. Membutuhkan sesuatu seperti map(None,*s.split('\n'))mengisi kekosongan dengan None, yang juga harus ditangani sendiri.

Sebagai gantinya, kami melakukan penghitungan vertikal sambil iterasi secara horizontal. Kami menyimpan daftar lindeks kolom mana yang masih "berjalan", yaitu di mana karakter sebelumnya dalam kolom itu terhubung. Kemudian, kami melakukan hal yang sama dengan horizontal, menghitung segmen vertikal yang baru mulai. Ketika kami mencapai baris baru, kami memotong daftar di mana kami berada, karena semua segmen ke kanan rusak, dan mengatur ulang indeks saat ini ke 0.


3

CJam, 66 62 61 byte

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

Cobalah online di penerjemah CJam .

Ide

Kami dapat menghitung titik akhir sebagai berikut:

  1. Hitung jumlah -s, |s dan+ s di input.
  2. Lipat gandakan yang terakhir dengan 2 dan tambahkan hasilnya.
  3. Hitung jumlah --s, -+s, +-s dan++ s di baris.
  4. Hitung jumlah ||s. |+s, +|s dan++ s di kolom.
  5. Kurangi hasil dari 3 dan 4 dari hasil dari 2.
  6. Lipat gandakan hasilnya dari 5 dengan 2.

Kode

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.
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.