ASCII Sanat Yarışmasını Kırp


13

ASCII sanatı eğlencelidir. Modern metin editörleri metni manipüle etmekte çok iyidir. Modern programlama dilleri göreve hazır mı?

ASCII sanat manipülasyonunda yaygın bir görev, metni iki karakter arasındaki bir dikdörtgene kırpmaktır. Bu görevde uygulamanız gereken görev budur.

ayrıntılar

Programınız 3 giriş alacak:

  • birincisi, bloğun 'başlangıç' karakteri - sol üst köşeyi işaretleme
  • ikincisi, bloğun 'bitiş' karakteri - sağ alt köşeyi işaretleme
  • üçüncüsü, bir dize, bir dize listesi veya dosya adı ya da her neyse, çok satırlı bir metin biçimidir.

Sonuç, verilen girdiler arasındaki dikdörtgene kırpılan çok satırlı metin (yine yukarıdaki formatlardan herhangi birinde) olacaktır. İlk iki girişin benzersiz olmayabileceğini unutmayın.

Edge kutuları

Kutular her zaman en az 2 hacme sahip olmalıdır.

()     (
       )

olan kutular ancak bu:

)(     )      (
       (     )

(start = (ve end = ile )) değildir.

Giriş yalnızca bir kutu içerecektir. Bu nedenle, başlangıç ​​ve bitiş karakterleri aynı karakter olmadıkça yalnızca bir kez gerçekleşmelidir; bu durumda tam olarak iki kez oluşmaları gerekir.

Ayrıca, girişteki her satır en azından bir satırın başlangıcından girişteki kutunun sağ kenarına kadar olan mesafe kadar olmalıdır.

Programınızın geçersiz girdileri işlemesi gerekmez; tanımlanmamış davranışa neden olabilirler.

kurallar

Tipik kod golf kuralları geçerlidir. En kısa kod kazanır.

Örnekler

Güneşli gün: start: ( end: ) input:

This is some text
. (but this text
  is in a box  ).
So only it is important.

Çıktı:

(but this text
is in a box  )

Yatay boşluğun soyulmasına da dikkat edin. ASCII sanat bitkileri 2d'dir.

Yağmurlu gün: start: ( end: ) input:

This is some text (
But is that even  )
really a box?

Çıktı:

(
)

Aynı başlangıç ​​/ bitiş: start: / end: / input:

Oh, I get how this could be useful
 /----------------------------\
 | All this text is in a box! |
 \----------------------------/

Çıktı:

/----------------------------\
| All this text is in a box! |
\----------------------------/

Geçersiz Giriş: start: ( end: ) input:

Boxes are rectangular ( so this has
0 volume ) which is illegal.

Geçersiz giriş 2: start: ( end: ) input:

(The lines must already be square 
so this line that is too short
relative to this end, is illegal)

Kutusundan daha kısa bir çizginin dışında geçerli bir kutuya ne dersiniz?
seadoggie01

1
açık, ayrıca geçersiz giriş
LambdaBeta

geçersiz bir girdi olması durumunda sonuç ne olmalıdır? ya da onlarla ilgilenilmeleri gerekmediğinden bahsediliyor mu?
Uriel

1
Sonuç C'deki tanımlanmamış davranışa çok benzer, endişelenmeyin, bir şey gider.
LambdaBeta

Bu kötü bir meydan okuma: güzel iş!
seadoggie01

Yanıtlar:


15

Vim, 16 , 12 bayt / tuş vuruşları

#<C-v>Nj*yggVGp

Çevrimiçi deneyin! V yorumlayıcısında

Modern metin editörleri metni manipüle etmekte çok iyidir. Modern programlama dilleri göreve hazır mı?

Eminim eski metin editörleri daha da iyidir! : D

Her ne kadar zorunlu olmak zorunda olmasa da, bu cevap verilen "geçersiz" girdilerin her ikisiyle de çalışır

 rectangular (
) which is ill

ve

(The lines must already be square
so this line that is too short
relative to this end, is illegal)

Açıklama:

#               " Move backward to the previous occurrence of the word (or in this case, character) under the cursor
 <C-v>          " Start a visual block selection
      N         " Go to the next occurrence of the last searched term (guaranteed to be line 1)
       j        " Move down a line
        *       " Move forward to the next occurrence of the character under the cursor
         y      " Yank (copy) the whole visually selected block
          gg    " Go to line 1
            VG  " Select every line
              p " And paste what we last copied over it, deleting the whole buffer and replacing it with the block

1
Bu arada, bu meydan okumayı yazmamı istemek için yaptığım tam olarak durum buydu. /\/<cr><c-v>nygv$o0dpÇok uzun süre benim q makro gibi ya da böyle bir şey vardı :)
LambdaBeta

2
Evet, dikdörtgen en kötüsü !
AdmBorkBork

6

Jöle , 13 bayt

=€SŒṪr/,þ/Zœị

Soldaki başlangıç ​​ve bitiş karakterlerinin bir listesini ve sağdaki satırların listesini (karakter listeleri olarak) veren bir satır listesini (karakter listesi olarak) kabul eden ikili bir bağlantı.

Çevrimiçi deneyin! (tam program - girişler geçerli Python ise Python-string-quoting gerektirirler.)

Nasıl?

=€SŒṪr/,þ/Zœị - Link: [start, stop], lines
 €            - for each (of [start, stop]):
=             -   equals? (vectorises across the lines)
  S           - sum (vectorises)
   ŒṪ         - multi-dimensional truthy (i.e. non-zero) indices
      /       - reduce by:
     r        -   inclusive range (vectorises)
         /    - reduce by:
        þ     -    outer product with:
       ,      -       pair
          Z   - transpose
           œị - multi-dimensional index-into (the lines)

Örnek olarak, left = ['a', 'b']ve right ile (karakter listelerinin listesi olarak - satırlar):

--------
--a+++--
--++++--
--+++b--
--------

=€iki liste listesinin bir listesini verir (ilki gerçekleştirir 'a'=, ikincisi 'b'=):

00000000         00000000
00100000         00000000
00000000    ,    00000000
00000000         00000100
00000000         00000000

bunun toplanması tek bir liste listesi verir (toplama elemanı olarak):

00000000
00100000
00000000
00000100
00000000

ŒṪsonra bize sıfır olmayanların (1 indeksli) çok boyutlu indekslerini verir, [[2,3],[4,6]]yani [[top,left],[bottom,right]].

r/daha sonra gerçekleştirir [2,3]r[4,6]beri rvectorises gibidir [2r4, 3r6]için değerlendirilmesi, [[2,3,4],[3,4,5,6]]örneğin, - [rows,columns].

,þ/sonra bir dış-poduct komutunun [2,3,4],þ[3,4,5,6]nerede þolduğunu ve ,çift ​​olduğunu gerçekleştirir. Bu, tüm [row,column]değerleri sütuna göre, bu durumda verir:

[[[2,3],[3,3],[4,3]],
 [[2,4],[3,4],[4,4]],
 [[2,5],[3,5],[4,5]],
 [[2,6],[3,6],[4,6]]]

Bunları satırlar halinde istiyoruz, bu yüzden bunu Zaşağıdakilere aktarmak için kullanılır:

[[[2,3],[2,4],[2,5],[2,6]],
 [[3,3],[3,4],[3,5],[3,6]],
 [[4,3],[4,4],[4,5],[4,6]]]

Son olarak œịgiriş satırlarına geri endeksler:

a+++
++++
+++b

Her iki sınırlayıcı karakter de aynı olduğunda her ikisini =€de iki kez tanımladığını, ancak SŒṪdoğru olanı yaptığını 2belirtmek gerekir, çünkü doğrudur, örneğin ['a','a']:

--------         00000000   00000000        00000000
--a+++--         00100000   00100000        00200000
--++++--  =€ ->  00000000 , 00000000  S ->  00000000  ŒṪ ->  [[2,3],[4,6]]
--+++a--         00000100   00000100        00000020
--------         00000000   00000000        00000000

... açıklamayı okudum ama hala anlamıyorum. o_o Belki işe yaramış bir örnek ekleyebilir misiniz?
DLosc

Teşvik: Tamamen açıklanırsa cevabınızı kabul edeceğim. :)
LambdaBeta

1
@DLosc - bitti, umarım yardımcı olur.
Jonathan Allan

@LambdaBeta - V yanıtı daha kısadır.
Jonathan Allan

... Vim yanıtı bile.
Jonathan Allan

5

APL (Dyalog) , 38 30 bayt

@EriktheOutgolfer sayesinde 4 byte tasarruf edildi

(1-⍨w-⍨⊃⍸⎕=s)↑(w←∊⊃⌽⍸⎕=s)↑s←↑⎕

Çevrimiçi deneyin!


çok karışık. vektörlerin vektörü yerine bir matrisi kabul edebilir, iki pozisyonu bulabilir ve ⍸matrix∊separatorsonlarla birlikte alıp bırakabilirsiniz
ngn

(⍸a=⎕)↓(1+⍸a=⎕)↑a←⎕ile⎕io←0
ngn

@ngn OP, karakterlerin sayısı satırlar arasında farklılık gösterdiğinden, girdinin işlemden önce vektör olması gerektiğini varsaydım. Buna rağmen, sınırlayıcı birkaç kez (üçüncü test durumuna bakın) göstermesi durumunda (ilk ve döndür) seçim parçalarına ihtiyacım var, ama sanırım damla birkaç bayt kesiyor, bu yüzden teşekkürler! PC'ye geldiğimde güncelleme yapacağım
Uriel

Üzgünüz ... Üçüncü vakayı unuttum, üzgünüm. O zaman belki: ⊃{⌽⊖⍵↓⍨⊃⍸⍺=⍵}/⎕⎕⎕(sic, 3 sondaki dörtlü) daha da kısadır. Veya ... ⎕⎕(↑⎕)önceden karıştırılmış bir matrise izin verilmiyorsa.
ngn

3

Jöle , 14 bayt

œẹⱮẎQr/Ṛṭþ/œị⁸

Çevrimiçi deneyin!


Kodunuzu diğer bazı örneklerde çalıştırmayı denedim, ancak sadece bir kilitlenme var. Bu bir hata mı, yoksa sadece yanlış bir şey mi yapıyorum?
Ilmari Karonen

@IlmariKaronen İkinci argümanı düzgün bir şekilde aktarmadınız (yazıda bundan bahsetmediniz); tek veya çift tırnak içine alın. Çağırdığınız şekilde, ikinci argüman boş (Python) bir gruptur ( ()), değil '()'. Ayrıştırılabiliyorsa, alıntılanması gerekir, ancak benim //alıntılanmasına gerek yoktur (işlenenler olmadan tamsayı bölme operatörü? Hm ...).
Outgolfer Erik

@IlmariKaronen Ben ()sadece Jelly tarafından bir tür özel karakter olarak yorumlanıyor "düşünüyorum" . Çoğu karakter çift çalışıyorum. Jelly'i daha iyi bilen insanların ne düşündüğünü duymak isterim. EDIT: ninja-ed erik the outgolfer tarafından
LambdaBeta



2

Tuval , 37 bayt

{³⁴⁰;x≡‽┐
X⁸)J╵⁶;┤ω┤⁵X⁶⁸⁰K├;┐┤└∔┘┘∔;@

Burada deneyin!

Karakterlerin koordinatlarını almak için 36 bayt (ve bunları almak için x, y, w, h'ye dönüştürmek için ) ve altbölümü almak için 1 bayt .. Daha iyi bir yaklaşım olmalı


2

JavaScript (ES6), 98 bayt

Girdiyi iki tamsayı ve bir dize dizisi olarak alır. Bir dizgi dizisi döndürür.

(x,y,a,X=Y=0)=>a.filter(s=>!Y&&(Y=-~s.indexOf(y,X?X-1:X=-~s.indexOf(x)),X)).map(s=>s.slice(X-1,Y))

Çevrimiçi deneyin!

Yorumlananlar

( x,                          // x = start character
  y,                          // y = end character
  a,                          // a[] = array of strings
  X =                         // X = position of x, plus 1
  Y = 0                       // Y = position of y, plus 1
) =>                          //
  a.filter(s =>               // for each string s in a[]:
    !Y &&                     //   reject this string if Y is non-zero
    (                         //   otherwise, use the 2nd condition:
      Y = -~s.indexOf(        //     update Y:
        y,                    //       by looking for y in s
        X ?                   //       if X is non-zero:
          X - 1               //         start the search at X - 1
        :                     //       else:
          X = -~s.indexOf(x)  //         update X and start the search at X
      ),                      //     end of Y update
      X                       //     keep this string if X is non-zero
    )                         //   end of 2nd condition
  )                           // end of filter()
  .map(s =>                   // for each remaining string s:
    s.slice(X - 1, Y)         //   remove left and right characters outside the box
  )                           // end of map()

filter ve map ?! İle yeni bir dizi oluşturmak reduceveya özyinelemeli bir çözüm daha kısa işe yaramaz mı? Bana telefon, pub aşağı ya da kendim bir gitmek vermek istiyorum.
Shaggy

@Shaggy Muhtemelen daha kısa bir yol var, ama bu yöntemin 2 geçiş kullanmaya mahkum olduğunu düşünüyorum : 2. döngü birincisi sona ermeden önce başlayamaz ve her ikisi de Xve Ykesin olarak bilinir.
Arnauld

2

Java 10, 204 bayt

(s,e,a)->{int b=-1,i=0;for(;i<a.length;i++)a[i]=(b=b<0?a[i].indexOf(s):b)<0|a[i].length()<b?"":a[i].substring(b);for(b=-1;i-->0;)a[i]=(b=b<0?a[i].indexOf(e):b)<0|a[i].length()<b?"":a[i].substring(0,b+1);}

Baytları kaydetmek için yenisini döndürmek yerine girdi dizisini değiştirir. Bu, ""bunun yerine kaldırılan çizgilerin olduğu anlamına gelir . Buna izin verilmiyorsa değiştireceğim.

Çevrimiçi deneyin.

Açıklama:

(s,e,a)->{                 // Method with 2 Strings & String-array parameters and no return
  int b=-1,                //  Boundaries-integer, starting at -1
  i=0;for(;i<a.length;i++) //  Loop `i` in the range [0, amountOfLines)
    a[i]=                  //   Change the `i`th line in the array to:
      (b=b<0?              //    If `b` is -1:
          a[i].indexOf(s)  //     Set `b` to the index of `s` in the current line
                           //     (which is still -1 if it's not found)
         :                 //    Else (starting index already found)
          b                //     Leave `b` unchanged
      )<0                  //    Then, if `b` is -1,
         |a[i].length()<b? //    or the current line-length is too short:
       ""                  //     Remove the current line
      :                    //    Else:
       a[i].substring(b);  //     Shorten the line by removing every character before `b`
  for(b=-1;                //  Reset `b` to -1
      i-->0;)              //  Loop `i` in the range (amountOfLines, 0]
    a[i]=                  //  Change the `i`th line in the array to:
       (b=b<0?a[i].indexOf(e):b)<0|a[i].length()<b?"":
                           //   Similar as above (with end `e` instead of start `s`),
         a[i].substring(0,b+1);}
                           //   except we remove every character after `b` this time

Örneğin:

Girişi ile start = "(", end = ")"velines =

["This is some text",
 ". (but this text",
 "  is in a box  ).",
 "So only it is important."]

ilk döngü onu üstte ve solda kırparak şuna değiştirir:

["",
 "(but this text",
 "is in a box  ).",
 " only it is important."]

ikinci döngü onu altta ve sağda kırparak şu şekilde değiştirir:

["",
 "(but this text",
 "is in a box  )",
 ""]

1

Retina 0.8.2 , 110 bayt

^((.)¶.)(.*¶)+(.*\2)
$1¶$4
^(.)(¶.¶\1)
$2
}s`(?<=^.¶.+)¶.
¶
s`^¶(.)¶(.*\1).*
$2
+m`^((.)+).¶((?<-2>.)+)$
$1¶$3

Çevrimiçi deneyin! Açıklama:

^((.)¶.)(.*¶)+(.*\2)
$1¶$4

Kutunun ilk satırından önceki giriş satırlarını silin.

^(.)(¶.¶\1)
$2

Başlangıç ​​karakteri girişin sol sütunundaysa silin.

}s`(?<=^.¶.+)¶.
¶

Başlangıç ​​karakteri henüz silinmediyse, tüm giriş sütunlarını birer birer sola kaydırın ve baştan tekrarlayın.

s`^¶(.)¶(.*\1).*
$2

Bitiş karakterini ve bitiş karakterinden sonraki girişteki her şeyi silin.

+m`^((.)+).¶((?<-2>.)+)$
$1¶$3

Tüm satırları bir sonraki satırın uzunluğuna göre kısaltın. Bu, her satırda bir karakter hariç tüm karakterleri sayarak ve bir sonraki satırda o karakterle eşleşmeye çalışarak çalışır; bu başarılı olursa, ikinci satır daha kısaydı, bu nedenle son karakter silinir ve döngü tekrarlanır.


0

C (gcc) , 237 bayt

f(c,r,o,p)char*p,*c;{char*_=strchr(p,r),*a,b;*_=0;a=strrchr(p,10);a=(a?a:p);*_=r;r=_-a;p=a;_=strrchr(p,o);*_=0;a=strrchr(p,10);a=(a?a:p);*_=o;o=_-a+1;_[1]=0;for(_=p;_;_=strchr(_+1,10)){b=_[o];_[o]=0;strcat(c,_+r);strcat(c,"\n");_[o]=b;}}

Çevrimiçi deneyin!

% 99 eminim bu iki kez tekrarlanan gibi, bir karakterin yatay indeksi ve işaretçi bulmak için bir tür yardımcı işlevi kullanılarak kısaltılabilir eminim. Ne yazık ki bunu yapmak için yeterince kısa bir yol bulamadım, zaman bulursam daha sonra tekrar deneyebilirsiniz.

Açıklama

f(c,r,o,p)char*p,*c;{
    char*_=strchr(p,r),*a,b;         // find opening char (and declare vars)
    *_=0;a=strrchr(p,10);            // find \n before it
    a=(a?a:p);                       // deal with single line inputs
    *_=r;r=_-a;                      // save left margin width in r
    p=a;                             // crop everything before opening line

    _=strchr(p,o);                   // find closing char
    *_=0;a=strrchr(p,10);            // find \n before it
    a=(a?a:p);                       // deal with single line inputs
    *_=o;o=_-a+1;                    // save width in o
    _[1]=0;                          // crop everything after closing char
    for(_=p;_;_=strchr(_+1,10)){       // for each line
        b=_[o];_[o]=0;
        strcat(c,_+r);
        strcat(c,"\n");
        _[o]=b;
    }
}

1
Daha da iyisi: 219 bytes
Zacharý

0

Stax , 15 bayt

╛↨½╝v∞░W╧)╗Ö≈☼k

Çalıştır ve hata ayıkla

İlk girdi satırında kutu sınırlayıcı karakter kümesini (1 veya 2) alır. Hatların geri kalanı giriş gövdesidir.

Ambalajından çıkarılmış, golf edilmemiş ve yorum yapılmış gibi görünüyor.

            first line of input is the delimiter characters
dL          discard the first line of input and listify the rest into an array
{           begin block for iteration
  Mr        rotate matrix 90 degrees
  {         begin block for while loop
    ch      copy first row of block
    y|&C    if it insersects with the first line of input, break iteration
    D       drop the first line
  W         do-while loop until break
}4*         execute block 4 times
m           display result lines

Bunu çalıştır

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.