ครอบตัด ASCII Art Challenge


13

ศิลปะ ASCII เป็นเรื่องสนุก เครื่องมือแก้ไขข้อความที่ทันสมัยใช้งานข้อความได้ดีมาก ภาษาการเขียนโปรแกรมที่ทันสมัยขึ้นอยู่กับภารกิจหรือไม่?

งานทั่วไปหนึ่งในการจัดการศิลปะ ASCII คือการครอบตัดข้อความเป็นสี่เหลี่ยมระหว่างอักขระสองตัว นี่คือภารกิจที่คุณต้องนำไปใช้ในการท้าทายนี้

รายละเอียด

โปรแกรมของคุณจะมี 3 อินพุต:

  • ตัวแรกคือตัวอักษร 'เริ่มต้น' ของบล็อก - ทำเครื่องหมายที่มุมบนซ้าย
  • ที่สองคือตัวละคร 'สิ้นสุด' ของบล็อก - ทำเครื่องหมายที่มุมล่างขวา
  • ที่สามคือรูปแบบของข้อความหลายบรรทัดไม่ว่าจะเป็นสตริงหรือรายการสตริงหรือชื่อไฟล์หรืออะไรก็ตาม

ผลลัพธ์จะเป็นข้อความหลายบรรทัด (อีกครั้งในรูปแบบใด ๆ ข้างต้น) ที่ถูกครอบตัดไปที่สี่เหลี่ยมผืนผ้าระหว่างอินพุตที่กำหนด โปรดทราบว่าสองอินพุตแรกอาจไม่ซ้ำกัน

กรณีขอบ

กล่องต้องมีปริมาณอย่างน้อย 2 เสมอดังนั้นสิ่งเหล่านี้:

()     (
       )

เป็นกล่อง แต่สิ่งเหล่านี้:

)(     )      (
       (     )

ไม่ใช่ (ด้วย start = (and end = ))

อินพุตจะมีเพียงหนึ่งกล่อง ดังนั้นอักขระเริ่มต้นและสิ้นสุดจะต้องเกิดขึ้นเพียงครั้งเดียวเท่านั้นเว้นแต่จะเป็นอักขระเดียวกันซึ่งในกรณีนี้จะต้องเกิดขึ้นสองครั้ง

นอกจากนี้แต่ละบรรทัดในอินพุตจะต้องมีอย่างน้อยตราบใดที่ระยะทางจากจุดเริ่มต้นของบรรทัดไปยังขอบด้านขวาของกล่องในอินพุต

โปรแกรมของคุณไม่จำเป็นต้องจัดการอินพุตที่ไม่ถูกต้อง ซึ่งอาจส่งผลให้พฤติกรรมไม่ได้กำหนด

กฎระเบียบ

ใช้กฎรหัสกอล์ฟทั่วไป รหัสที่สั้นที่สุดชนะ

ตัวอย่าง

วันที่แดดจ้า: start: ( end: ) input:

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

เอาท์พุท:

(but this text
is in a box  )

สังเกตการปอกของพื้นที่แนวนอนด้วย พืชศิลปะ ASCII เป็น 2d

วันที่ฝนตก: start: ( end: ) input:

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

เอาท์พุท:

(
)

จุดเริ่มต้น / จุดสิ้นสุดเดียวกัน: start: / end: / input:

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

เอาท์พุท:

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

อินพุตไม่ถูกต้อง: start: ( end: ) input:

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

อินพุตไม่ถูกต้อง 2: start: ( end: ) input:

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

สิ่งที่เกี่ยวกับกล่องที่ถูกต้องกับสายนอกที่สั้นกว่ากล่อง?
seadoggie01

1
ชี้แจงข้อมูลที่ไม่ถูกต้อง
เช่น

สิ่งที่ควรเป็นผลลัพธ์ในกรณีของการป้อนข้อมูลที่ไม่ถูกต้อง? หรือพวกเขาจะกล่าวถึงดังนั้นพวกเขาจะไม่ต้องได้รับการดูแล?
Uriel

1
ผลลัพธ์นั้นเหมือนกับพฤติกรรมที่ไม่ได้กำหนดใน C ไม่ต้องกังวลกับมันเกิดอะไรขึ้น
LambdaBeta

นี่เป็นความท้าทายเล็กน้อยที่น่ารังเกียจ: ทำได้ดีมาก!
seadoggie01

คำตอบ:


15

เป็นกลุ่ม, 16 , 12 ไบต์ / การกดแป้น

#<C-v>Nj*yggVGp

ลองออนไลน์! ในล่าม V

เครื่องมือแก้ไขข้อความที่ทันสมัยใช้งานข้อความได้ดีมาก ภาษาการเขียนโปรแกรมที่ทันสมัยขึ้นอยู่กับภารกิจหรือไม่?

ฉันพนันได้เลยว่าเครื่องมือแก้ไขข้อความแบบเก่าดียิ่งขึ้น! : D

แม้ว่ามันไม่จำเป็นต้องมีคำตอบนี้จะทำงานกับทั้งอินพุต "ไม่ถูกต้อง" ที่กำหนดเอาท์พุท

 rectangular (
) which is ill

และ

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

คำอธิบาย:

#               " 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
อนึ่งนี้อยู่ตรงการใช้งานกรณีที่ผมทำกับผมพร้อมที่จะเขียนความท้าทายนี้ ฉันมีแมโครคิวของฉันเป็น/\/<cr><c-v>nygv$o0dpหรือสิ่งที่ต้องการที่นานเกินไป :)
LambdaBeta

2
ใช่รูปสี่เหลี่ยมผืนผ้าเป็นภาพลวงตา !
AdmBorkBork

6

เยลลี่ 13 ไบต์

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

ลิงก์ dyadic ยอมรับรายการของอักขระเริ่มต้นและสิ้นสุดที่ด้านซ้ายและรายการของบรรทัด (เป็นรายการของอักขระ) ทางด้านขวาซึ่งให้รายการของบรรทัด (เป็นรายการของอักขระ)

ลองออนไลน์! (โปรแกรมเต็ม - หากอินพุตเป็น Python ที่ถูกต้องจะต้องใช้ Python-string-quoting)

อย่างไร?

=€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)

ตัวอย่างเช่นด้วย left = ['a', 'b']and right (เป็นรายการของอักขระ - บรรทัด):

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

=€ให้ผลลัพธ์รายการสองรายการของรายการ (การดำเนินการครั้งแรก'a'=, รายการที่สอง'b'=):

00000000         00000000
00100000         00000000
00000000    ,    00000000
00000000         00000100
00000000         00000000

ข้อสรุปนี้ทำให้รายการของรายการเดียว (รวมองค์ประกอบที่ฉลาด):

00000000
00100000
00000000
00000100
00000000

ŒṪแล้วจะช่วยให้เรา (1 จัดทำดัชนี) ดัชนีหลายมิติของศูนย์ที่ไม่ใช่[[2,3],[4,6]]- [[top,left],[bottom,right]]คือ

r/แล้วดำเนินการ[2,3]r[4,6]ซึ่งตั้งแต่rvectorises เป็นเหมือน[2r4, 3r6]การประเมินผลการ[[2,3,4],[3,4,5,6]]- [rows,columns]คือ

,þ/จากนั้นดำเนินการ[2,3,4],þ[3,4,5,6]ที่þคำสั่งด้านนอก - พ็อดและ,คู่ สิ่งนี้ให้[row,column]ค่าทั้งหมดตามคอลัมน์ในกรณีนี้:

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

เราต้องการสิ่งเหล่านี้โดยแถวดังนั้นZจะใช้ในการแปลงนี้เพื่อ:

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

ในที่สุดœịดัชนีกลับเข้าสู่บรรทัดอินพุต:

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

เป็นที่น่าสังเกตว่าเมื่อตัวละครทั้งสองมีขอบเขตเหมือนกันจะ=€ระบุทั้งสองครั้ง แต่SŒṪจบลงด้วยการทำสิ่งที่ถูกต้องเนื่องจาก2เป็นความจริงเช่นด้วย['a','a']:

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

... ฉันอ่านคำอธิบาย แต่ก็ยังไม่เข้าใจ o_o คุณสามารถเพิ่มตัวอย่างการทำงานได้ไหม?
DLosc

การสร้างแรงจูงใจ: ฉันจะยอมรับคำตอบของคุณหากคำอธิบายนั้นครบถ้วน :)
LambdaBeta

1
@DLosc - เสร็จแล้วหวังว่าจะช่วยได้
Jonathan Allan

@LambdaBeta - คำตอบ V สั้นกว่า
Jonathan Allan

... เอ่อคำตอบเป็นกลุ่ม
Jonathan Allan

5

APL (Dyalog) , 38 30 ไบต์

บันทึกได้ 4 ไบต์ด้วย @EriktheOutgolfer

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

ลองออนไลน์!


ซับซ้อนเกินไป. คุณสามารถที่จะยอมรับเมทริกซ์แทนเวกเตอร์ของเวกเตอร์พบกับสองตำแหน่ง⍸matrix∊separatorsและจะใช้ / วางกับพวกเขา
NGN

(⍸a=⎕)↓(1+⍸a=⎕)↑a←⎕กับ⎕io←0
NGN

@ngn OP กล่าวว่าจำนวนตัวอักษรที่แตกต่างกันระหว่างบรรทัดดังนั้นฉันคิดว่าการป้อนข้อมูลควรเป็นแบบเวกเตอร์ก่อนประมวลผล ถึงอย่างนั้นฉันต้องการชิ้นส่วนที่เลือก (ก่อนและหมุน) ในกรณีที่ตัวคั่นแสดงสองสามครั้ง (ดูกรณีทดสอบที่สาม) แต่ฉันคิดว่าการหยดจะลดลงสักสองสามไบต์ดังนั้นขอบคุณ! ฉันจะอัปเดตเมื่อฉันไปยังพีซี
Uriel

อ๊ะ ... ฉันลืมเรื่องที่สามไปแล้วขอโทษ จากนั้นอาจจะ: ⊃{⌽⊖⍵↓⍨⊃⍸⍺=⍵}/⎕⎕⎕(sic โดยมี 3 คนต่อท้ายสี่คน) ซึ่งสั้นกว่านี้ หรือ... ⎕⎕(↑⎕)ถ้าไม่อนุญาตให้ผสมเมทริกซ์ล่วงหน้า
NGN

3

เยลลี่ 14 ไบต์

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

ลองออนไลน์!


ฉันพยายามเรียกใช้รหัสของคุณในตัวอย่างอื่น ๆ แต่มีข้อผิดพลาด นั่นเป็นข้อบกพร่องหรือฉันแค่ทำอะไรผิดไป
Ilmari Karonen

@IlmariKaronen คุณยังไม่ได้อ้างถึงข้อโต้แย้งที่สองอย่างถูกต้อง (ไม่ได้พูดถึงสิ่งนั้นในโพสต์); ห่อด้วยเครื่องหมายคำพูดเดี่ยวหรือคู่ วิธีที่คุณเรียกมันอาร์กิวเมนต์ที่สองเป็นที่ว่างเปล่า (งูใหญ่) tuple ( ()) '()'ไม่ได้ หากสามารถแยกวิเคราะห์ได้มันจำเป็นต้องมีการยกมาอย่างไรก็ตามฉัน//ไม่จำเป็นต้องยกมา (โอเปอเรเตอร์การแบ่งจำนวนเต็มโดยไม่มีตัวถูกดำเนินการ? hm ... )
Erik the Outgolfer

@IlmariKaronen ฉัน "คิด" ที่()เพิ่งถูกตีความโดย Jelly ว่าเป็นตัวละครพิเศษบางอย่าง ตัวละครส่วนใหญ่ที่ฉันลองใช้ ฉันชอบที่จะได้ยินสิ่งที่ผู้คนคุ้นเคยกับเจลลี่คิดมากกว่า แก้ไข: ninja-ed โดย erik outgolfer
LambdaBeta



2

Canvas ขนาด 37 ไบต์

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

ลองที่นี่!

36 ไบต์สำหรับการรับพิกัดของตัวละคร (และแปลงเป็น x, y, w, h เพราะนั่นคือสิ่งที่ต้องทำ) และ 1 ไบต์สำหรับการรับส่วนย่อย .. ต้องมีวิธีการที่ดีกว่า


2

JavaScript (ES6), 98 ไบต์

รับอินพุตเป็นจำนวนเต็มสองจำนวนและอาร์เรย์ของสตริง ส่งคืนอาร์เรย์ของสตริง

(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))

ลองออนไลน์!

แสดงความคิดเห็น

( 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 และ map ?! การสร้างอาร์เรย์ใหม่ด้วยreduceหรือโซลูชันแบบเรียกซ้ำไม่สั้นลงหรือไม่ บนโทรศัพท์ของฉันลงผับหรือฉันจะไปเอง
ปุย

@Shaggy อาจจะมีวิธีที่สั้นกว่านี้แน่นอน แต่ฉันคิดว่าวิธีนี้ถูกกำหนดให้ใช้ 2 รอบ: การวนซ้ำครั้งที่ 2 ไม่สามารถเริ่มได้ก่อนที่อันที่ 1 จะสิ้นสุดลงและทั้งคู่XและYเป็นที่รู้จักกันอย่างแน่นอน
Arnauld

2

Java 10, 204 ไบต์

(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);}

ปรับเปลี่ยนอินพุตอาร์เรย์แทนที่จะส่งคืนใหม่เพื่อบันทึกไบต์ นี่หมายความว่าเส้นที่ถูกลบจะกลายเป็น""แทน หากไม่ได้รับอนุญาตฉันจะเปลี่ยนมัน

ลองออนไลน์

คำอธิบาย:

(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

ตัวอย่างเช่น:

ด้วยปัจจัยการผลิตstart = "(", end = ")"และlines =

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

ลูปแรกจะครอบตัดที่ด้านบนและซ้ายเปลี่ยนเป็น:

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

ลูปที่สองจะครอบตัดที่ด้านล่างและขวาเปลี่ยนเป็น:

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

1

เรติน่า 0.8.2 , 110 ไบต์

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

ลองออนไลน์! คำอธิบาย:

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

ลบบรรทัดอินพุตที่อยู่หน้าบรรทัดแรกของกล่อง

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

หากอักขระเริ่มต้นอยู่ในคอลัมน์ด้านซ้ายของอินพุตให้ลบออก

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

หากยังไม่ได้ลบอักขระเริ่มต้นให้เลื่อนคอลัมน์อินพุตทั้งหมดที่เหลืออยู่หนึ่งรายการแล้วทำซ้ำตั้งแต่ต้น

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

ลบอักขระสิ้นสุดและทุกสิ่งในอินพุตหลังจากอักขระสิ้นสุด

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

ตัดบรรทัดทั้งหมดให้เป็นความยาวของบรรทัดถัดไป วิธีนี้ใช้ได้โดยการนับทั้งหมด แต่หนึ่งอักขระในแต่ละบรรทัดจากนั้นพยายามจับคู่กับอักขระจำนวนมากในบรรทัดถัดไป หากประสบความสำเร็จแล้วบรรทัดที่สองจะสั้นลงดังนั้นอักขระตัวสุดท้ายจะถูกลบและลูปจะทำซ้ำ


0

C (gcc) , 237 ไบต์

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;}}

ลองออนไลน์!

ฉันแน่ใจว่า 99% นี้สามารถสั้นลงได้โดยใช้ฟังก์ชั่นตัวช่วยบางอย่างเพื่อค้นหาดัชนีแนวนอนและตัวชี้ไปยังตัวอักษรเนื่องจากมีการทำซ้ำสองครั้ง อนิจจาฉันไม่สามารถหาวิธีที่สั้นพอที่จะทำฉันอาจลองอีกครั้งในภายหลังถ้าฉันหาเวลา

ลักษณะ

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
ดียิ่งขึ้น: 219 ไบต์
Zacharý

0

Stax , 15 ไบต์

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

เรียกใช้และแก้ไขข้อบกพร่อง

ใช้ชุดตัวคั่นกล่อง (1 หรือ 2) ในบรรทัดแรกของอินพุต ส่วนที่เหลือของเส้นคือร่างกายอินพุต

คลายกล่อง ungolfed และแสดงความคิดเห็นมันมีลักษณะเช่นนี้

            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

เรียกใช้อันนี้

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.