เห็นภาพอาร์เรย์


26

กำหนดความลึกใด ๆ ให้วาดเนื้อหาด้วยเส้นขอบ+-|รอบ ๆ แต่ละ subarray สิ่งเหล่านี้คืออักขระ ASCII สำหรับเครื่องหมายบวกลบและแนวตั้ง

ตัวอย่างเช่นถ้าอาร์เรย์คือ[1, 2, 3]วาด

+-----+
|1 2 3|
+-----+

สำหรับอาร์เรย์ที่ซ้อนกันเช่น[[1, 2, 3], [4, 5], [6, 7, 8]]วาด

+-----------------+
|+-----+---+-----+|
||1 2 3|4 5|6 7 8||
|+-----+---+-----+|
+-----------------+

สำหรับอาเรย์แบบขาด ๆ เช่น[[[1, 2, 3], [4, 5]], [6, 7, 8]]วาด

+-------------------+
|+-----------+-----+|
||+-----+---+|6 7 8||
|||1 2 3|4 5||     ||
||+-----+---+|     ||
|+-----------+-----+|
+-------------------+

[6, 7, 8]แจ้งให้ทราบว่ามีพื้นที่ว่างมากขึ้นหลังจากการวาดภาพ คุณสามารถวาดเนื้อหาในบรรทัดบนสุดกึ่งกลางหรือล่างสุด แต่ไม่ว่าคุณจะเลือกแบบไหนคุณจะต้องคงความสอดคล้อง

ความท้าทายนี้ได้แรงบันดาลใจจากกล่องคำกริยา<จากเจ

กฎระเบียบ

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

กรณีทดสอบ

[]
++
||
++

[[], []]
+---+
|+++|
|||||
|+++|
+---+

[[], [1], [], [2], [], [3], []]
+-----------+
|++-++-++-++|
|||1||2||3|||
|++-++-++-++|
+-----------+

[[[[[0]]]]]
+---------+
|+-------+|
||+-----+||
|||+---+|||
||||+-+||||
|||||0|||||
||||+-+||||
|||+---+|||
||+-----+||
|+-------+|
+---------+

[[[[[4, 3, 2, 1]]]], [[[3, 2, 1]]], [[2, 1]], [1]]
+---------------------------------+
|+-------------+---------+-----+-+|
||+-----------+|+-------+|+---+|1||
|||+---------+|||+-----+|||2 1|| ||
||||+-------+|||||3 2 1|||+---+| ||
|||||4 3 2 1|||||+-----+||     | ||
||||+-------+|||+-------+|     | ||
|||+---------+||         |     | ||
||+-----------+|         |     | ||
|+-------------+---------+-----+-+|
+---------------------------------+

หากภาษาของฉันไม่มีอาร์เรย์ซ้อนกันฉันสามารถเพิกเฉยต่อคำจำกัดความของชนิดข้อมูลได้หรือไม่
ThreeFx

1
@ThreeFx คุณสามารถใช้อินพุตเป็นสตริงที่แทนอาร์เรย์ที่ซ้อนกันได้
ไมล์

นั่นคือไม่มีประสิทธิภาพจริงๆ (ใน Haskell) ฉันต้องแยกวิเคราะห์ตัวเลขด้วยตนเองและอื่น ๆ ในกรณีนั้นมันจะสั้นลงในการกำหนดและใช้ประเภทข้อมูล
ThreeFx

@ThreeFx หรือคุณสามารถวางแถวด้วยค่า Sentinel เช่น-1เนื่องจากฉันยัง จำกัด จำนวนเต็มไม่เป็นลบ จากนั้นจะต้องล้างเอาต์พุตสำหรับค่าที่ไม่ถูกต้องเหล่านั้น
ไมล์

1
@MitchSchwartz แน่ใจว่าใช้อินพุตใน tuple ที่ซ้อนกันหรือรูปแบบใดก็ตามที่เป็นภาษาของคุณ ผลลัพธ์ของคุณจะดีตราบใดที่คุณยังคงสอดคล้อง จำนวนเต็มสามารถวาดที่ด้านบนกึ่งกลางหรือด้านล่างและกล่องสามารถอยู่ด้านบนกึ่งกลางด้านล่างหรือยืดเพื่อเติมพื้นที่ของพวกเขาเช่นในตัวอย่างของคุณ
ไมล์

คำตอบ:


4

Dyalog APL , 56 ไบต์

ขอบคุณ ngn ที่ช่วยลบประมาณหนึ่งในสามของไบต์

{⍵≡∊⍵:⍉⍪⍉⍕⍵⋄(⊢,⊣/)⊃,/(1⊖('++','|'⍴⍨≢),'-'⍪⍣2↑)¨↓↑↓¨∇¨⍵}⊂

TryAPL

กำหนดฟังก์ชั่นจากนั้นเรียกใช้แต่ละกรณีทดสอบและเปรียบเทียบกับ]Displayยูทิลิตี้ในตัว
[1, 2, 3]
[[1, 2, 3], [4, 5], [6, 7, 8]]
[[[1, 2, 3], [4, 5]], [6, 7, 8]]
[]
[[], []]
[[], [1], [], [2], [], [3], []]
[[[[[0]]]]]
[[[[[4, 3, 2, 1]]]], [[[3, 2, 1]]], [[2, 1]], [1]]

คำอธิบาย

ทั้งหมดนี้เป็นฟังก์ชั่นที่ไม่ระบุชื่อบนยอดแนบ{...} หลังเพิ่งเพิ่มการซ้อนในอีกระดับเพื่อกระตุ้นให้อดีตเพิ่มเฟรมด้านนอก

ฟังก์ชั่นไม่ระบุชื่อที่มี white-space ( เป็นตัวคั่นคำสั่ง):

{
      ∊⍵:     
    (⊢ , ⊣/)  ,/ (1  ('++' , '|' ⍴⍨ ≢) , '-' ⍪⍣2 ↑)¨   ↓¨ ∇¨ 
}

ที่นี่เป็นอีกครั้ง แต่ด้วยฟังก์ชั่นยูทิลิตี้แยก:

CloseBox   , ⊣/
CreateVertical  '++' , '|' ⍴⍨ 
AddHorizontals  1  CreateVertical , '-' ⍪⍣2 
{
      ∊⍵:     
    CloseBox  ,/ AddHorizontals¨   ↓¨ ∇¨ 
}

ตอนนี้ให้ฉันอธิบายแต่ละฟังก์ชั่น:

CloseBoxรับตารางและส่งกลับตารางเดียวกัน แต่มีคอลัมน์แรกของตารางต่อท้ายทางด้านขวาของตาราง ดังนั้นเมื่อได้รับตาราง 1 ต่อ 3 XYZฟังก์ชั่นนี้จะส่งกลับตาราง 1 ต่อ 4 XYZXดังนี้:
 อาร์กิวเมนต์ (lit. สิ่งที่อยู่ทางขวา)
,  ที่รวม
⊣/ อยู่ในคอลัมน์ซ้ายสุด (lit. การลดซ้ายของแต่ละรายการ แถว)

CreateVerticalใช้เวลาตารางและส่งกลับสตริงที่ประกอบด้วยตัวอักษรที่จะพอดี|บนด้านข้างของตาราง แต่มีสอง+s -ใช้ได้เพื่อให้ตรงกับสองแถว ในที่สุดตารางจะหมุนรอบหนึ่งแถวเพื่อให้ได้+---...แถวเดียวด้านบนและด้านล่าง ดังนั้นเมื่อกำหนดตารางสามแถวใด ๆ ฟังก์ชันนี้จะส่งคืน++|||ดังนี้:
'++' , สอง pluses ที่เติมไว้
'|' ⍴⍨  stile reshaped โดย
 การนับ (แถว ') ของการโต้แย้ง

AddHorizontalsใช้ list-of-list ใส่ลงในตารางเพิ่มสองแถว-ด้านบนเพิ่มอักขระขอบซ้ายที่เกี่ยวข้องทางซ้ายจากนั้นหมุนหนึ่งแถวไปยังด้านล่างเพื่อให้ตารางมีเส้นขอบด้านบน , ซ้ายและล่าง ดังต่อไปนี้:
1 ⊖ หมุนหนึ่งแถว (แถวบนสุดไปที่ด้านล่าง) ของ
CreateVertical , สตริงที่เตรียม ++|||...ไว้ (เป็นคอลัมน์) เพื่อ
'-' ⍪⍣2 ลบลบสองครั้งที่ด้านบนของ
 อาร์กิวเมนต์ที่เปลี่ยนจากรายการของรายการเป็นตาราง

{ฟังก์ชั่นที่ไม่ระบุชื่อ}: ถ้าอาร์กิวเมนต์เป็นรายการแบบง่าย ๆ (ไม่ซ้อนกัน) ให้ใส่ไว้ในตารางตัวอักษร (เช่นนี้ให้รายการองค์ประกอบ 3 รายการ1 2 3ฟังก์ชั่นนี้จะส่งกลับตารางอักขระแบบ 1 ต่อห้าที่เหมือนกันทางสายตา1 2 3) หากอาร์กิวเมนต์ไม่ใช่รายการแบบง่ายให้แน่ใจว่าองค์ประกอบนั้นเป็นตารางอักขระแบบง่าย รองให้สูงเท่ากัน จัดวางแต่ละเฟรมไว้ที่ด้านบนด้านล่างและด้านซ้าย รวมพวกเขา; และในที่สุดก็นำคอลัมน์แรกและเพิ่มไปทางขวา ดังต่อไปนี้:
{ เริ่มต้นนิยามของฟังก์ชั่นที่ไม่ระบุตัวตน
  ⍵ ≡ ∊⍵:ถ้าอาร์กิวเมนต์นั้นเหมือนกันกับอาร์กิวเมนต์ที่แบน (เช่นมันเป็นรายการแบบง่าย) จากนั้น:
    ย้าย อาร์กิวเมนต์ที่เป็น
    สตริงที่แปลงเป็นคอลัมน์
    transposed
   ⍕ ⍵; อื่น:
  CloseBox เพิ่มคอลัมน์ซ้ายสุดทางด้านขวาของ
  ⊃ ,/ ที่เปิดเผย (เพราะล้อมรอบลดลง) ตัดแบ่งข้าม
  AddHorizontals¨ เพิ่ม-s ที่ด้านบนและด้านล่างของแต่ละ
  ↓ ↑ ↓¨ เบาะที่มีความสูงเท่ากันของ
  ∇¨ ⍵  ฟังก์ชันที่ไม่ระบุชื่อนี้ที่ใช้กับแต่ละอาร์กิวเมนต์จะ
} สิ้นสุดนิยามของฟังก์ชันที่ไม่ระบุชื่อ
* Lit ทำให้แต่ละตารางเป็นลิสต์ของรายการรวมลิสต์ของรายการ (การเติมด้วยสตริงว่างเพื่อเติมแถวสั้น) ลงในตารางแล้วแยกตารางเป็นรายการลิสต์ของรายการ


7

JavaScript (ES6), 223 203 ไบต์

f=(a,g=a=>a[0].map?`<${a.map(g).join`|`}>`:a.join` `,s=g([a]),r=[s],t=s.replace(/<[ -9|]*>|[ -9]/g,s=>s[1]?s.replace(/./g,c=>c>`9`?`+`:`-`):` `))=>t<`+`?r.join`\n`.replace(/<|>/g,`|`):f(a,g,t,[t,...r,t])

โซลูชัน Ruby ของพอร์ตของ @ MitchSchwartz เวอร์ชันก่อนหน้าซึ่งทำงานโดยการตัดอาร์เรย์ซ้ำ (และทำงานกับเนื้อหาที่กำหนดเองไม่ใช่เฉพาะจำนวนเต็ม):

f=(...a)=>a[0]&&a[0].map?[s=`+${(a=a.map(a=>f(...a))).map(a=>a[0].replace(/./g,`-`)).join`+`}+`,...[...Array(Math.max(...a.map(a=>a.length)))].map((_,i)=>`|${a.map(a=>a[i]||a[0].replace(/./g,` `)).join`|`}|`),s]:[a.join` `]

หมายเหตุ: แม้ว่าฉันจะใช้ตัวดำเนินการสเปรดในรายการอาร์กิวเมนต์ของฉันเพื่อให้ได้ผลลัพธ์ที่ต้องการให้ระบุพารามิเตอร์เดียวของอาเรย์ดั้งเดิมแทนที่จะพยายามกระจายอาเรย์ นี่คือผลกระทบของการห่อผลลัพธ์ในกล่องด้านนอกที่ต้องการ น่าเสียดายที่กล่องด้านนอกมีค่าใช้จ่ายฉัน 18 ไบต์และการแบ่งพื้นที่จำนวนเต็มมีค่าฉัน 8 ไบต์มิฉะนั้นการสร้างภาพข้อมูลทางเลือกต่อไปนี้จะเพียงพอสำหรับ 197 ไบต์:

f=a=>a.map?[s=`+${(a=a.map(f)).map(a=>a[0].replace(/./g,`-`)).join`+`}+`,...[...Array(Math.max(0,...a.map(a=>a.length)))].map((_,i)=>`|${a.map(a=>a[i]||a[0].replace(/./g,` `)).join`|`}|`),s]:[``+a]

สิ่งนี้จัดการกับอาร์เรย์ที่ว่างเปล่าหรือไม่? ผมได้รับข้อผิดพลาดสำหรับอาร์เรย์ที่ว่างเปล่าเช่นCannot read property 'map' of undefined []สำหรับ[1,2,[]]ระบบย่อยสุดท้ายจะไม่แสดงผลสำหรับฉัน
ไมล์

@miles ขออภัยฉันลืมตรวจสอบกรณีทดสอบและตอนนี้ใช้ได้ทั้งหมด คุณไม่ได้ระบุผลลัพธ์สำหรับ[1,2,[]]ตัวอย่างของคุณแสดงเฉพาะอาร์เรย์ที่มีจำนวนเต็มหรืออาร์เรย์ แต่ไม่ใช่ทั้งสองอย่าง
Neil

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

3

Ruby, 104 ไบต์

->s{r=s=s.gsub'}{',?|
r=[s,r,s]*$/while s=s.tr('!-9',' ').gsub!(/{[ |]*}/){$&.tr' -}','-+'}
r.tr'{}',?|}

ฟังก์ชันไม่ระบุชื่อที่คาดหวังสตริง ตัวอย่างเช่น{{{{{4 3 2 1}}}}{{{3 2 1}}}{{2 1}}{1}}ผลิต

+---------------------------------+
|+-------------+---------+-----+-+|
||+-----------+|         |     | ||
|||+---------+||+-------+|     | ||
||||+-------+||||+-----+||+---+| ||
|||||4 3 2 1||||||3 2 1||||2 1||1||
||||+-------+||||+-----+||+---+| ||
|||+---------+||+-------+|     | ||
||+-----------+|         |     | ||
|+-------------+---------+-----+-+|
+---------------------------------+

คุณสามารถใช้รหัสนี้สำหรับการทดสอบ:

f=->s{r=s=s.gsub'}{',?|
r=[s,r,s]*$/while s=s.tr('!-9',' ').gsub!(/{[ |]*}/){$&.tr' -}','-+'}
r.tr'{}',?|}

a=[]

a<<'[1, 2, 3]'
a<<'[[1, 2, 3], [4, 5], [6, 7, 8]]'
a<<'[[[1, 2, 3], [4, 5]], [6, 7, 8]]'
a<<'[]'
a<<'[[], []]'
a<<'[[], [1], [], [2], [], [3], []]'
a<<'[[[[[0]]]]]'
a<<'[[[[[4, 3, 2, 1]]]], [[[3, 2, 1]]], [[2, 1]], [1]]'

a.map{|s|s.gsub! '], [','}{'
s.tr! '[]','{}'
s.gsub! ',',''
puts s
puts f[s],''}

สิ่งนี้เริ่มต้นจากแถวกลางและทำงานออกไปด้านนอก ครั้งแรกกรณีของจะถูกแทนที่ด้วย}{ |จากนั้นในขณะที่ยังมีวงเล็บปีกกา{...}สตริงด้านในสุดทั้งหมดจะถูกเปลี่ยนเป็น+-ลำดับที่เหมาะสมในขณะที่ตัวละครอื่นที่ไม่ใช่|{}จะกลายเป็นช่องว่าง ในตอนท้ายวงเล็บปีกกากลางจะเปลี่ยนเป็นท่อ


ฉันใช้เสรีภาพบางอย่างกับความต้องการการจัดรูปแบบอินพุตแบบผ่อนปรนที่เห็นได้ชัด รหัสสามารถแก้ไขได้อย่างง่ายดายเพื่อจัดการรูปแบบการป้อนข้อมูลที่แตกต่างกันหากจำเป็น
Mitch Schwartz

การรับความคิดเห็นที่คิดไม่ดีเป็นหนึ่งในความสุขที่ยิ่งใหญ่ของการเข้าร่วมในเว็บไซต์นี้
Mitch Schwartz

3

Brainfuck, 423 ไบต์

->>+>>,[[>+>+<<-]+++++[>--------<-]>[<+>-[[-]<-]]>[[-]<<[>>>>+<<<<<<-<[>-<-]>>>-
]<<<[-<<<<<<-<]>+>>>]<<<[>>+>>>>>+<<<<<<<-]>>>>>>>>>,]<<+[<<,++>[-[>++<,<+[--<<<
<<<<+]>]]<[-<+]->>>>[<++<<[>>>>>>>+<<<<<<<-]>>>-[<++>-[>>>>+<<<<<++<]<[<<]>]<[>>
+<<<<]>>>+>+>[<<<-<]<[<<]>>>>->+>[-[<-<-[-[<]<[<++<<]>]<[<++++<<]>]<[>+<-[.<<<,<
]<[<<]]>]<[-<<<<<]>>[-[<+>---[<<++>>+[--[-[<+++++++<++>>,]]]]]<+++[<+++++++++++>
-]<-.,>>]>>>>+>>>>]<<-]

จัดรูปแบบด้วยความคิดเห็นบางส่วน:

->>+>>,
[
  [>+>+<<-]
  +++++[>--------<-]
  >
  [
    not open paren
    <+>-
    [
      not paren
      [-]<-
    ]
  ]
  >
  [
    paren
    [-]
    <<
    [
      close paren
      >>>>+<<<<
      <<-<[>-<-]>>>
      -
    ]
    <<<
    [
      open paren directly after close paren
      -<<<<<<-<
    ]
    >+>>>
  ]
  <<<[>>+>>>>>+<<<<<<<-]>>>
  >>>>>>,
]
<<+
[
  <<,++>
  [
    -
    [
      >++<
      ,<+[--<<<<<<<+]
      >
    ]
  ]
  <[-<+]
  ->>>>
  [
    <++<<[>>>>>>>+<<<<<<<-]>>>-
    [
      at or before border
      <++>-
      [
        before border
        >>>>+<<<<
        <++<
      ]
      <[<<]
      >
    ]
    <
    [
      after border
      >>+<<
      <<
    ]
    >>>+>+>
    [
      column with digit or space
      <<<-<
    ]
    <[<<]
    >>>>->+>
    [
      middle or bottom
      -
      [
        bottom
        <-<-
        [
          at or before border
          -
          [
            before border
            <
          ]
          <
          [
            at border
            <++<<
          ]
          >
        ]
        <
        [
          after border
          <++++<<
        ]
        >
      ]
      <
      [
        middle
        >+<
        -[.<<<,<]
        <[<<]
      ]
      >
    ]
    <[-<<<<<]
    >>
    [
      border char or space
      -
      [
        not space
        <+>---
        [
          not plus
          <<++>>
          +
          [
            --
            [
              -
              [
                pipe
                <+++++++<++>>,
              ]
            ]
          ]
        ]
      ]
      <+++[<+++++++++++>-]<-.,>>
    ]
    > >>>+>>>>
  ]
  <<-
]

ลองออนไลน์

คาดว่าอินพุตจะถูกจัดรูปแบบเช่นเดียว(((((4 3 2 1))))(((3 2 1)))((2 1))(1))กับการขึ้นบรรทัดใหม่และสร้างเอาต์พุตของฟอร์ม:

+---------------------------------+
|+-------------+---------+-----+-+|
||+-----------+|+-------+|+---+| ||
|||+---------+|||+-----+|||   || ||
||||+-------+|||||     ||||   || ||
|||||4 3 2 1||||||3 2 1||||2 1||1||
||||+-------+|||||     ||||   || ||
|||+---------+|||+-----+|||   || ||
||+-----------+|+-------+|+---+| ||
|+-------------+---------+-----+-+|
+---------------------------------+

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

เทปถูกแบ่งออกเป็นโหนด 7 เซลล์โดยแต่ละโหนดแสดงถึงคอลัมน์ในเอาต์พุต

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

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

ในระหว่างการเริ่มต้นวนรอบรูปแบบหน่วยความจำของโหนดที่จุดเริ่มต้นของการทำซ้ำคือ

x d 0 c 0 0 0

โดยที่xเป็นแฟล็กบูลีนว่าอักขระก่อนหน้านี้เป็นวงเล็บปิดหรือไม่dคือความลึก (บวกหนึ่ง) และcเป็นอักขระปัจจุบัน

ในระหว่างการพิมพ์ตัวอักษรวนรอบหน่วยความจำของโหนดที่จุดเริ่มต้นของการทำซ้ำคือ

0 0 d1 d2 c p y

โดยที่d1บ่งบอกถึงความลึกเมื่อเทียบกับดัชนีแถวสำหรับครึ่งบน d2คล้ายกับd1แต่สำหรับครึ่งล่าง cเป็นอักขระอินพุตสำหรับคอลัมน์นั้นถ้าหลักหรือช่องว่างมิฉะนั้นเป็นศูนย์ pบ่งชี้เฟส ได้แก่ ครึ่งบนกลางหรือครึ่งล่าง และyเป็นธงที่แพร่กระจายจากซ้ายไปขวาติดตามว่าเรามาถึงแถวกลางหรือยัง โปรดทราบว่าเนื่องจากyกลายเป็นศูนย์หลังจากประมวลผลโหนดเราสามารถใช้yเซลล์ของโหนดก่อนหน้าเพื่อเพิ่มพื้นที่ทำงาน

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

มี-1เซลล์ทางด้านซ้ายของโหนดเพื่ออำนวยความสะดวกในการนำทางและมีเซลล์ทางด้านขวาของโหนดที่คอยติดตามว่าเราพิมพ์แถวสุดท้ายหรือไม่


2

PHP + HTML, ไม่ใช่การแข่งขัน ( 170 141 135 130 ไบต์)

บันทึก 29 ไบต์โดย SteeveDroz

<?function p($a){foreach($a as$e)$r.=(is_array($e)?p($e):" $e");return"<b style='border:1px solid;float:left;margin:1px'>$r</b>";}

ไม่แข่งขันเพราะไม่มีการส่งออก ascii และเพราะฉันปล่อยให้เบราว์เซอร์ทำงานได้อย่างน่าสนใจ


1
คุณสามารถทำให้<b>แท็กแทนและคุณไม่จำเป็นต้องระบุสีของ<div> border(ประหยัด 9 ไบต์)
SteeveDroz

คุณไม่จำเป็นต้องใส่ <tag> เลยเพียงแค่แสดงผลลัพธ์เป็นข้อความธรรมดาที่จะช่วยประหยัดจำนวนไบต์ (80 ไบต์สำหรับรหัสทั้งหมดหลังจากลบ HTML)
ClementNerma

@SteeveDroz ด้วย<b>, ฉันยังสามารถลบwhite-spaceคุณลักษณะ, บันทึกอีก 19 ไบต์ ที่ดี! และฉันสามารถแทนที่paddingด้วยmargin
ติตัส

2

JavaScript (ES6), 221

ฟังก์ชันที่ไม่ใช่แบบเรียกซ้ำจะส่งคืนอาเรย์ของสตริง (ยังคงใช้ฟังก์ชันย่อยแบบเรียกซ้ำภายใน)

a=>[...(R=(a,l)=>a[r[l]='',0]&&a[0].map?'O'+a.map(v=>R(v,l+1))+'C':a.join` `)([a],l=-1,r=[],m='')].map(c=>r=r.map(x=>x+v[(k<0)*2+!k--],k=l,1/c?v='-- ':(v='-+|',c>'C'?k=++l:c>','&&--l,c='|'),m+=c))&&[...r,m,...r.reverse()]

ใช้งานได้ใน 2 ขั้นตอน

ขั้นตอนที่ 1: สร้างการแสดงสตริงซ้ำของอาร์เรย์อินพุตที่ซ้อนกัน ตัวอย่าง:

[[[1, 2, 3], [],[4, 5]], [6, 7, 8]] -> "OOO1 2 3,,4 5C,6 7 8CC"

OและCทำเครื่องหมายเปิดและปิด subarray แถวย่อยที่เป็นตัวเลขอย่างง่ายจะแสดงผลด้วยองค์ประกอบที่คั่นด้วยช่องว่างในขณะที่ถ้าสมาชิกอาร์เรย์เป็นอาร์เรย์ย่อยพวกเขาจะถูกคั่นด้วยเครื่องหมายจุลภาค สตริงนี้ติดตามการโครงสร้างพหุระดับของเข้าแถวในขณะที่ฉันจะได้รับแถวกลางของการส่งออกเพียงแค่การแทนที่ด้วยOC, |ในขณะที่สร้างสาย temp นี้ซ้ำ ๆ ฉันยังค้นหาระดับความลึกสูงสุดและเริ่มต้นอาร์เรย์ของสตริงว่างที่จะมีส่วนครึ่งบนของเอาต์พุต
หมายเหตุ: กล่องด้านนอกเป็นเรื่องยุ่งยากฉันซ้อนข้อมูลเข้าไว้ในอาร์เรย์ด้านนอกอีกชุดจากนั้นฉันได้ดรอปเอาท์พุทแถวแรกที่ไม่ต้องการออก

ขั้นตอนที่ 2: สแกนสตริง temp และสร้างผลลัพธ์

ตอนนี้ฉันมีอาร์เรย์ของสตริงว่างเปล่าหนึ่งรายการสำหรับแต่ละระดับ ผมสแกนสตริงชั่วคราว, การติดตามระดับปัจจุบันที่เพิ่มขึ้นสำหรับแต่ละและลดลงในแต่ละO Cฉันเห็นภาพนี้:

[[[1, 2, 3], [],[4, 5]], [6, 7, 8]]

OOO1 2 3,,4 5C,6 7 8CC
+                    +
 +            +     +
  +     ++   +
|||1 2 3||4 5||6 7 8||

เครื่องหมายบวกจะขึ้นและลงตามระดับปัจจุบัน

สำหรับอักขระแต่ละตัวฉันเพิ่มอักขระลงในเอาต์พุตทุกแถวโดยทำตามกฎ:
- ถ้าตัวเลขหรือช่องว่างให้ใส่ '-' ที่ระดับปัจจุบันและต่ำกว่าวางช่องว่างด้านบน
- - อื่นใส่ '+' ที่ ระดับปัจจุบันให้ใส่ '-' ถ้าด้านล่างและใส่ '|' ถ้าข้างต้น

OOO1 2 3,,4 5C,6 7 8CC
+--------------------+
|+------------+-----+|
||+-----++---+|     ||
|||1 2 3||4 5||6 7 8||

ในระหว่างการสแกนชั่วคราวฉันยังสร้างแถวกลางแทนที่OC,ด้วย|

ในตอนท้ายของขั้นตอนนี้ฉันมีครึ่งบนและแถวกลางฉันต้องสะท้อนส่วนบนสุดเพื่อรับครึ่งล่างและฉันเสร็จแล้ว

golfed น้อยรหัสความคิดเห็น

a=>{
   r = []; // output array
   R = ( // recursive scan function
     a, // current subarray 
     l  // current level
   ) => (
     r[l] = '', // element of r at level r, init to ""
     a[0] && a[0].map // check if it is a flat (maybe empty) array or an array of arrays
     ? 'O'+a.map(v=>R(v,l+1))+'C' // mark Open and Close, recurse
     : a.join` ` // just put the elements space separated
   );
   T = R([a],-1)]; // build temp string
   // pass the input nested in another array 
   // and start with level -1 , so that the first row of r will not be visible to .map

   // prepare the final output
   m = '' // middle row, built upon the chars in T
   l = -1 // starting level
   [...T].map(c => // scan the temp string
         {
            k = l; // current level
            1/c // check if numeric or space
             ? v = '-- ' // use '-','-',' '
             : (
                 v = '-+|', // use '-','+','|'
                 c > 'C' 
                   ? k=++l // if c=='O', increment level and assign to k
                   : c>'A'&&--l, // if c=='C', decrement level (but k is not changed)
                 c='|' // any of O,C,comma must be mapped to '|'
               );
            m += c; // add to middle row
            r = r.map( (x,i) => // update each output row
                       // based on comparation between row index and level
                       // but in golfed code I don't use the i index
                       // and decrement l at each step  
                       x + v[(k<i)*2+!(k-i)]
                     )
         })
   // almost done!  
   return [...r,m,...r.reverse()]

)

ทดสอบ

F=
a=>[...(R=(a,l)=>a[r[l]='',0]&&a[0].map?'O'+a.map(v=>R(v,l+1))+'C':a.join` `)([a],l=-1,r=[],m='')].map(c=>r=r.map(x=>x+v[(k<0)*2+!k--],k=l,1/c?v='-- ':(v='-+|',c>'C'?k=++l:c>','&&--l,c='|'),m+=c))&&[...r,m,...r.reverse()]

out=x=>O.textContent = x+'\n'+O.textContent

;[[1,2,3]
,[[[1, 2, 3], [4, 5]], [6, 7, 8]]
,[]
,[[], []]
,[[], [1], [], [2], [], [3], []]
,[[[[[0]]]]]
,[[[[[4, 3, 2, 1]]]], [[[3, 2, 1]]], [[2, 1]], [1]]
].forEach(t=>
  out(JSON.stringify(t)+'\n'+F(t).join`\n`+'\n')
)  

function update()
{
  var i=eval(I.value)
  out(JSON.stringify(i)+'\n'+F(i).join`\n`+'\n')
}

update()
#I { width:90%}
<input id=I value='[[[1, 2, 3], [],[4, 5]], [6, 7, 8]]' oninput='update()'>
<pre id=O></pre>


2

Ruby, 245 241 ไบต์

ค่าใช้จ่ายที่จำเป็นในการห่อทุกอย่างในกล่องเช่นเดียวกับการจัดตำแหน่งทุกอย่างค่อนข้างหนัก ...

เอาต์พุตอาร์เรย์ของสตริงโดยมีหนึ่งสตริงต่อบรรทัดตาม spec จัดชิดด้านล่างแทนกรณีทดสอบตัวอย่างที่ได้รับการจัดแนวด้านบนเนื่องจากประหยัด 1 ไบต์

ลองออนไลน์!

V=->a{a==[*a]?(k=a.map(&V);k[0]==[*k[0]]?[h=?++?-*((k.map!{|z|z[1,0]=[' '*~-z[0].size+?|]*(k.map(&:size).max-z.size);z};f=k.shift.zip(*k).map{|b|?|+b.reduce{|r,e|r+e[1..-1]}+?|})[0].size-2)+?+,*f,h]:[h="+#{?-*(f=k*' ').size}+",?|+f+?|,h]):a}

@ Adámได้รับการแก้ไขแล้ว จะพยายามทำให้ดีที่สุดเพื่อเพิ่มประสิทธิภาพในภายหลัง ...
Value Ink

Nice.First ตอบครั้งแรกด้วยการจัดตำแหน่งด้านล่าง :-)
Adám

1

PHP, 404 ไบต์

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

<?foreach(str_split(json_encode($_GET[a]))as$j){$j!="]"?:$c--;$r=($j==",")?($l=="]"?"":" "):$j;$r=$r=="]"?"|":$r;$r=$r=="["?($v=="]"?"":"|"):$r;if($r!=""){$n.=$r;$d.=+$c;}$v=$l;$l=$j;$j!="["?:$c++;$m>=$c?:$m=$c;}for($x=0;$x<strlen($n);$x++)for($y=0;$y<$m;$y++)$z[$y].=$y==$d[$x]&&$n[$x]=="|"?"+":($y<$d[$x]?"-":($y>$d[$x]&&$n[$x]=="|"?"|":" "));echo join("\n",$z),"\n$n\n".(join("\n",array_reverse($z)));

ขยาย

foreach(str_split(json_encode($_GET[a]))as$j){ # split JSON representation of the array
    $j!="]"?:$c--;
    $r=($j==",")?($l=="]"?"":" "):$j;
    $r=$r=="]"?"|":$r;
    $r=$r=="["?($v=="]"?"":"|"):$r;
    if($r!=""){
      $n.=$r;  # concanate middle string
      $d.=+$c; # concanate depth position
    }
    $v=$l;
    $l=$j;
    $j!="["?:$c++;
    $m>=$c?:$m=$c; # maximum depth of the array
}
for($x=0;$x<strlen($n);$x++)for($y=0;$y<$m;$y++)
$z[$y].=$y==$d[$x]&&$n[$x]=="|"?"+":($y<$d[$x]?"-":($y>$d[$x]&&$n[$x]=="|"?"|":" "));
# Build the strings before the middle string dependent of value middle string and depth 
echo join("\n",$z),"\n$n\n".(join("\n",array_reverse($z))); #Output

สำหรับ 425 ไบต์เราสามารถสร้างด้วย REGEX

<?$n=($p=preg_filter)("#\]|\[#","|",$r=$p("#\],\[#","|",$p("#,(\d)#"," $1",json_encode($_GET[a]))));preg_match_all("#.#",$r,$e,256);foreach($e[0] as$f){$f[0]!="]"&&$f[0]!="|"?:$c--;$d.=+$c;$f[0]!="|"&&$f[0]!="["?:$c++;$m>=$c?:$m=$c;}for($x=0;$x<strlen($n);$x++)for($y=0;$y<$m;$y++)$z[$y].=$y==$d[$x]&&$n[$x]=="|"?"+":($y<$d[$x]?"-":($y>$d[$x]&&$n[$x]=="|"?"|":" "));echo join("\n",$z),"\n$n\n".(join("\n",array_reverse($z)));

ขยาย

$r=preg_filter("#\],\[#","|",preg_filter("#,(\d)#"," $1",json_encode($_GET[a])));
preg_match_all("#.#",$r,$e,256);
$n=preg_filter("#\]|\[#","|",$r); # concanate middle string
foreach($e[0] as$f){
    $f[0]!="]"&&$f[0]!="|"?:$c--;
    $d.=+$c; concanate depth position
    $f[0]!="|"&&$f[0]!="["?:$c++;
    $m>=$c?:$m=$c; # maximum depth of the array
}
# similar to the other ways
for($x=0;$x<strlen($n);$x++)
for($y=0;$y<$m;$y++)
$z[$y].=$y==$d[$x]&&$n[$x]=="|"?"+":($y<$d[$x]?"-":($y>$d[$x]&&$n[$x]=="|"?"|":" "));
echo join("\n",$z),"\n$n\n".(join("\n",array_reverse($z)));

455 Bytes สำหรับโซลูชันแบบเรียกซ้ำ

<?function v($x,$t=0,$l=1){global$d;$d.=$t;$s="|";$c=count($x);foreach($x as$k=>$v){if(is_array($v))$e=v($v,$t+1,$k+1==$c);else{$e=$v." "[$k+1==$c];$d.=str_pad("",strlen($e),$t+1);}$s.=$e;}$d.=$l?$t:"";$s.=$l?"|":"";return$s;}$n=v($_GET[a]);$m=max(str_split($d));for($x=0;$x<strlen($n);$x++)for($y=0;$y<$m;$y++)$z[$y].=$y==$d[$x]&&$n[$x]=="|"?"+":($y<$d[$x]?"-":($y>$d[$x]&&$n[$x]=="|"?"|":" "));echo join("\n",$z),"\n$n\n".(join("\n",array_reverse($z)));

ขยาย

function v($x,$t=0,$l=1){
    global$d; # concanate depth position
    $d.=$t;
    $s="|";
    $c=count($x);
    foreach($x as$k=>$v){           
        if(is_array($v)){$e=v($v,$t+1,$k+1==$c);}
        else{$e=$v." "[$k+1==$c];$d.=str_pad("",strlen($e),$t+1);}
        $s.=$e;
    }
    $d.=$l?$t:"";
    $s.=$l?"|":"";
    return$s;
}
$n=v($_GET[a]); # concanate middle string
$m=max(str_split($d)); # maximum depth of the array
# similar to the other ways 
for($x=0;$x<strlen($n);$x++)
for($y=0;$y<$m;$y++)
$z[$y].=$y==$d[$x]&&$n[$x]=="|"?"+":($y<$d[$x]?"-":($y>$d[$x]&&$n[$x]=="|"?"|":" "));
echo join("\n",$z),"\n$n\n".(join("\n",array_reverse($z)));

1) $j!="]"?:$c--;-> $c-=$j=="]";(-2) 2) ($l=="]"?"":" ")-> " "[$l==$j](-5) การแทนที่ที่คล้ายกันมากที่สุดในลูปที่สอง 3) if($r!=""){$n.=$r;$d.=+$c;}-> $n.=$r;if($r>"")$d.=+$c;(-3) 4) $l=$j;$j!="["?:$c++;-> $c+="["==$l=$j;(-5) 5) $x=0ไม่จำเป็น (-4) 6) for($y=0;$y<$m;$y++)->for($y=$m;$y--;) (-4) 7) join("\n",$z),"\n$n\n".(join("\n",array_reverse($z)));-> join("\n",array_merge($z,[$n],array_reverse($z)));(-4) 8) ช่องว่างที่ไม่จำเป็น: foreach($e[0]as$f)(-1)
ติตัส

9) วงเล็บที่ไม่จำเป็นที่ ($j==",") (-2) 10) if($r>"")$d.=+$c;-> $d.=$r>""?+$c:"";(-0)
ติตัส

รุ่นเรียกซ้ำ: 1) $d.=$l?$t;ล้าสมัย (-10) 2) $s.=$l?"|":"";return$s;-> return$s."|"[$l];(-6) 3) การจัดฟันที่ล้าสมัย{$e=v($v,$t+1,$k+1==$c);}(-2) 4) {$e=$v." "[$k+1==$c];$d.=str_pad("",strlen($e),$t+1);}-> $d.=str_pad("",strlen($e=$v." "[$k+1==$c]),$t+1);(-5)
ติตัส
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.