Bir ASCII Sanatının Uç Noktalarını Sayma


14

ASCII sanatını temsil eden bir dizeyi giriş ve çıkış olarak alan veya girişteki bitiş noktası sayısını döndüren bir program veya işlev yazmalısınız.

Girdi, karakterlerden space - | +(sırasıyla 0, 2, 2 ve 4 uç noktaya sahip) ve satır satırlarından oluşacaktır . Örneğin:

-|++-
  +

İki bitişik karakter bağlanır ve bu nedenle aşağıdaki durumlarda her biri 1 uç nokta kaybeder:

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

İlk örnek

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

bitiş noktaları.

Giriş

  • Girdi karakter boşluk oluşan bir dize olacaktır -, |, +ve yeni satır.
  • Giriş uzunluğu 0 uzunluk olabilir ve yukarıdaki açıklamayla eşleşen herhangi bir giriş geçerlidir (normal ifade girişinde [ -+|\n]*).
  • Sondaki satır başı isteğe bağlıdır.

Çıktı

  • Tek bir negatif olmayan tam sayı, uç nokta sayısı.

Örnekler

Çıkışlar, girdilerinin son satırından sonra gelir.

+
4 

-|++-
  +
12 

+--+
|  |
+--+
8 

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

--++
 |||--
10 

<empty input>
0 


|
|     
2 

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

 ----
30 

Bu kod golf yani en kısa giriş kazanır.

Yanıtlar:


11

Salyangoz , 29

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

,,Yorumlu bir sürüm yapmak için ile satır yorumları ekledim .

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

Şablon dizelerini kullanarak, tüm yeni satırlar önemlidir ve sayılır.

Aşağıdaki snippet'i Firefox'ta çalıştırmayı test edin. (Chrome hala desteklemiyor ...)

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>


Ne yapmam gerekiyor s satırları bölme, sonra üstte boş bir satır ve altta boş bir satır ekleyin. Kodunuz hiç bölünmüyor. Bunu daha ["",...s.split("\n"),""]uzun süre yapabilirsiniz @ETHproductions
edc65

Ah, doğru, bunun için üzgünüm.
ETHproductions

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

Tek geçiş yöntemi. Satır sonu içeren bir dize girişi alır.

Ufuklar için fikir, her biri iki uç noktaya sahip olan yatay segmentlerin sayısını saymaktır. Segment, bir karakter +-(boole h) karakterlerinden biri olduğunda, ancak bir önceki karakter (boole ) olmadığında başlar p.

Sektörler için, aynı şeyi transpoze edilen girdi üzerinde, çalışmalarına bakarak yapmak istiyoruz +|. Ne yazık ki, Python'un aktarımı gerçekten tıknaz. map(None,*s.split('\n'))Boşlukları doldurmak gibi bir şey gerektirir None, ki bunlar da başa çıkacaklardır.

Bunun yerine, yatay olarak yineleme yaparken dikey sayımı yaparız. lHangi sütun indekslerinin hala "çalışmakta olduğunu", yani bu sütundaki önceki karakterin bağlandığı bir listeyi tutuyoruz . Daha sonra, yeni başlayan dikey segmentleri sayarak, yatay ile aynı şeyi yaparız. Yeni bir satıra çarptığımızda, sağdaki tüm segmentler kırıldığından listeyi bulunduğumuz yerde keseriz ve mevcut dizini sıfırlarız 0.


3

CJam, 66 62 61 bayt

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

CJam yorumlayıcısında çevrimiçi deneyin .

Fikir

Uç noktaları aşağıdaki gibi hesaplayabiliriz:

  1. Girişteki -s, |s ve +s sayısını sayın .
  2. Sonuncuyu 2 ile çarpın ve sonuçları ekleyin.
  3. Satırlardaki --s, -+s, +-s ve ++s sayısını sayın .
  4. ||S sayısını sayın . |+s, +|s ve ++s sütunlarında.
  5. 3 ve 4'ten sonuçları 2'den sonuçtan çıkarın.
  6. Sonucu 5'ten 2'ye çarpın.

kod

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.
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.