ขยายขนาดการปูกระเบื้องเพชร


27

รูปหกเหลี่ยมปกติใด ๆ สามารถปูด้วยเพชรได้เช่น:

   ______
  /_/_/\_\
 /_/\_\/\_\
/\_\/_/\/_/\
\/_/\_\/_/\/
 \_\/_/\_\/
  \_\_\/_/

เราจะพิจารณาด้านบนปูกระเบื้องขนาด1(ตั้งแต่ด้านข้างเพชรจะทำอย่างใดอย่างหนึ่ง/หรือ\แต่ละคน) ปูกระเบื้องขนาดเดียวกัน2จะมีลักษณะ:

      ____________ 
     /   /   /\   \  
    /___/___/  \___\ 
   /   /\   \  /\   \  
  /___/  \___\/  \___\ 
 /\   \  /   /\  /   /\  
/  \___\/___/  \/___/  \ 
\  /   /\   \  /   /\  /
 \/___/  \___\/___/  \/ 
  \   \  /   /\   \  /
   \___\/___/  \___\/ 
    \   \   \  /   /
     \___\___\/___/ 

งานของคุณคือการรับ ASCII อาร์ตไทล์ (ของขนาด1) เป็นอินพุตพร้อมกับจำนวนเต็มบวกN(เป็นทศนิยมหรือไม่เท่ากัน) โดยระบุขนาดของเอาต์พุตที่ต้องการ จากนั้นคุณควรเอาท์พุทเวอร์ชันที่ปรับขนาดขึ้นของการเรียงต่อกัน

โปรดทราบว่ารูปหกเหลี่ยมอาจมีขนาดใดก็ได้และเล็กเพียง 1x1x1 (บรรจุเพชรสามเม็ด)

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

คุณสามารถเขียนโปรแกรมหรือฟังก์ชั่น, รับอินพุตผ่าน STDIN (หรือทางเลือกที่ใกล้เคียงที่สุด), อาร์กิวเมนต์บรรทัดคำสั่งหรืออาร์กิวเมนต์ของฟังก์ชันและส่งผลลัพธ์ผ่าน STDOUT (หรือทางเลือกที่ใกล้เคียงที่สุด), ค่าส่งคืนของฟังก์ชันหรือพารามิเตอร์

นี่คือรหัสกอล์ฟดังนั้นคำตอบที่สั้นที่สุด (เป็นไบต์) เป็นผู้ชนะ

ตัวอย่างการเอียง

นี่คือตัวอย่างของการป้อนข้อมูลที่คุณสามารถใช้ทดสอบการส่งของคุณ

 __
/_/\
\_\/

  ____
 /_/\_\
/\_\/_/\
\/_/\_\/
 \_\/_/

   ______
  /_/_/\_\
 /_/\_\/\_\
/\_\/_/\/_/\
\/_/\_\/_/\/
 \_\/_/\_\/
  \_\_\/_/

    ________
   /_/\_\_\_\
  /\_\/\_\_\_\
 /\/_/\/_/_/\_\
/\/\_\/_/_/\/\_\ 
\/\/_/\_\_\/\/_/
 \/\_\/_/\_\/_/
  \/\_\_\/_/_/
   \/_/_/_/_/

ตัวอย่างต่อไปนี้มีผลที่สอดคล้องกันสำหรับปัจจัยการผลิตผ่านN = 1N = 6


20
ฉันเห็นว่าคุณสนใจเพชรตอนนี้คุณมีเพชรอยู่ข้างชื่อผู้ใช้ของคุณ
user12205

3
@ace: คุณรู้ว่าสิ่งที่พวกเขาพูดว่า: เพชรเป็นเพื่อนที่ดีที่สุดของผู้ดูแล
Alex A.

ฉันคิดว่าฉันรู้คำตอบ แต่ฉันหวังว่าฉันผิด: เส้นนำว่างเปล่าจะนับเป็นพื้นที่นำซึ่งคุณประกาศว่าผิดกฎหมายหรือไม่ โซลูชันเริ่มต้นของฉันมีN-1การนำบรรทัดว่างเปล่า :(
Reto Koradi

@RetoKoradi แน่นอนว่าไม่มีการขึ้นบรรทัดใหม่ ขอโทษ
Martin Ender

1
ฉันคิด เสียค่าใช้จ่ายประมาณ 10 ไบต์ ไม่เลวอย่างที่คิดเมื่อฉันรู้ปัญหาครั้งแรก
Reto Koradi

คำตอบ:


8

CJam, 85 79 76 72 ไบต์

li:Tlf*NqN/T,f{ff{"_/"2$#_1<@+*~ST*@t}:+z{S+e`);e~{"_ "/"__"*W%}T2**N}/}

ขนาดควรอยู่ในบรรทัดแรก และเพชรมีดังนี้

ไม่ค่อยตีกอล์ฟดี ... และครึ่งหนึ่งของตัวละครมาจากรายละเอียด

คำอธิบาย (ของรุ่นก่อนหน้า)

li:T            e# Read the size and save to T.
qN/             e# Read and split to lines.
\,fm*           e# Convert each character X to [X 0] [X 1]... [X T(]
{~              e# For each [X I] in each line:
    ST*         e# T spaces.
    \           e# I.
    "_\\"3$#    e# If X is '_, '\ or '/, return Y = 0, 1, -1 respectively.
    _W>@+       e# If it was '_ or '\, increase I by one.
    *(          e# I * Y - 1.
    @t          e# Set the character at that position to X.
}f%
:z:+            e# Make the returned lists from each iteration across T lines.
{S+e`);e~N+}%   e# Boring details to remove trailing spaces and append a newline.
T(>(\s          e# Boring details to extract the first line and only work on others.
{_{"_ "/"__"*W%}2*_@=!}g
                e# Boring details to make underlines expand left and right.

10

Python 2, 164

def g(s,n,j=1):
 for W in s.split("\n"):exec"O=p='';d=0\nfor c in W:q=' _'[j*'_'in p+c];e=[n-j,j-1][c=='/'];O+=q*(e+d)+[c,q][c>'^'];p=c;d=n+~e\nprint O;j-=1;"*j;j=n

ส่งออกในกรณีทดสอบ

แล้วเกิดอะไรขึ้นที่นี่?

แนวคิดหลักคือตัวละครแต่ละตัวในต้นฉบับระเบิดขึ้นเป็นn*nบล็อก ตัวอย่างเช่นสำหรับ n = 4 /อาจกลายเป็น

   /
  /
 /
/___

อักขระดั้งเดิมปรากฏขึ้นหนึ่งครั้งในแต่ละบรรทัดและมีช่องว่างด้านใดด้านหนึ่ง นี่มันอยู่ทางซ้ายและ_ทางขวา เฉพาะแถวล่างเท่านั้นที่สามารถเพิ่มได้ด้วย'_'; ' 'ส่วนที่เหลืออยู่เสมอ

ปัญหาหลักคือการแพ็ดดิ้งด้านขวาขึ้นอยู่กับสัญลักษณ์ที่จะเกิดขึ้น โดยเฉพาะ'/ 'มีช่องว่างภายในที่แตกต่างกัน'/_'ดังนั้นเราจึงต้องการดูล่วงหน้า ยิ่งไปกว่านั้นเพื่อหลีกเลี่ยงช่องว่างต่อท้ายเราจะต้องทราบว่าเราอยู่ที่สัญลักษณ์สุดท้ายและหลีกเลี่ยงการขยายด้านขวา

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

ทีนี้ลองดูรหัสกันดีกว่า

def g(s,n,j=1):
    for W in s.split("\n"):
        while j:
            O=p='';d=0
            for c in W:
                q=' _'[j*'_'in p+c]
                e=[n-j,j-1][c=='/']
                O+=q*(e+d)+[c,q][c>'^']
                p=c
                d=n+~e
            print O;j-=1;
        j=n

สายป้อนเป็นและขนาดปัจจัยคือs nเราไปบรรทัดโดยบรรทัดพิมพ์nสายสำหรับสายการป้อนข้อมูลแต่ละกับสำเนาการจัดทำดัชนีW j=n,n-1,...,2,1บรรทัดแรกจะถูกคัดลอกเพียงครั้งเดียวซึ่งเราทำได้โดยเริ่มต้นjที่ 1 แต่เปลี่ยนเป็นnแต่ละลูป

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

จากนั้นเราตัดสินใจปริมาณของช่องว่างภายในที่จะใส่ทางซ้าย ( e) สำหรับ/มันj-1(ลดลงด้วยการลดจำนวนสายสำเนา) และเสริมสำหรับn-j \เราปฏิบัติต่อตัวละครอื่น ๆ ในลักษณะเดียวกัน ตัวอย่างเช่นแม้ว่า_ดูเหมือนว่าจะมีการnขีดเส้นใต้เป็นแถวแต่จริงๆแล้วมันจะเป็นการขีดเส้นใต้เดียวซึ่งจะเพิ่มขีดด้วยขีดล่างด้านซ้ายและขวา ดูเหมือนว่าจะไม่มีประสิทธิภาพ แต่มันช่วยให้เราสามารถทำงานกับ_และในกรอบเดียวกับ/และ\ตำแหน่งของขีดล่าง "กลาง" ไม่สำคัญดังนั้นเราจึงจับก้อนและด้วย\; ตัวเลือกนี้ยังทำให้แถวบนทำงานได้โดยไม่มีปลอกพิเศษ

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

ในที่สุดเราจะบันทึกจำนวนหนี้ที่เติมซึ่งเป็นส่วนเติมเต็มn+~dของจำนวนเงินที่เหลืออยู่ในปัจจุบัน เรายังบันทึกสัญลักษณ์ปัจจุบันไว้pด้วยเพื่อเราจะได้ทราบภายหลังว่าเป็นสัญลักษณ์ก่อนหน้านี้_หรือไม่


3

JavaScript ( ES6 ) 274 281 289 338

// GOLFED
F=(b,n)=>{
b=b[R='replace'](/ |_/g,c=>c[T='repeat'](n))[R](/_(?=[\\\/])/g,'_'[T](n))[R](/\/\\/g,`/${'  '[T](n-1)}\\`)
.split('\n');
for(i=l=b.length*n-n+1;--i;)
b[i]=i%n?b[i+1][R](/_/g,' ')[R](/\/ ?/g,' /')[R](/ \\(.)?/g,'\\$1$1')
:' '[T](i>l/2?n-1:0)+b[i/n];
return b.join('\n')}


// UNGOLFED
U=(b,n)=>{
  b=b
  .replace(/ |_/g,c=>c.repeat(n))
  .replace(/_(?=[\/\\])/g,'_'.repeat(n))
  .replace(/\/\\/g,`/${'  '.repeat(n-1)}\\`)
  .split('\n');
  for(i=l=b.length*n-n+1;--i;)
  {
    if(i%n)
     b[i]=b[i+1]
     .replace(/_/g,' ')
     .replace(/\/ ?/g,' /')
     .replace(/ \\/g,'\\ ').replace(/ +$/,'')
     .replace(/ \\(.)?/g,'\\$1$1')
    else {
      b[i]=b[i/n]
      if(i>l/2)b[i]=' '.repeat(n-1)+b[i];
    }
  }
  return b.join('\n')
}

//TEST

test=[
' __\n/_/\\\n\\_\\/',
'  ____\n /_/\\_\\\n/\\_\\/_/\\\n\\/_/\\_\\/\n \\_\\/_/',
'   ______\n  /_/_/\\_\\\n /_/\\_\\/\\_\\\n/\\_\\/_/\\/_/\\\n\\/_/\\_\\/_/\\/\n \\_\\/_/\\_\\/\n  \\_\\_\\/_/',
'    ________\n   /_/\\_\\_\\_\\\n  /\\_\\/\\_\\_\\_\\\n /\\/_/\\/_/_/\\_\\\n/\\/\\_\\/_/_/\\/\\_\\\n\\/\\/_/\\_\\_\\/\\/_/\n \\/\\_\\/_/\\_\\/_/\n  \\/\\_\\_\\/_/_/\n   \\/_/_/_/_/'
]

test.forEach(t=>{
  var row = '<td>'+t+'<td>'
  for(rr=2;rr<5;rr++)
    row += '<td>'+F(t,rr)+'</td>'
  OUT.innerHTML += '<tr>'+row+'</tr>'
})
td {
  font-family: monospace;
  white-space: pre;
}
(better full page)
<table id=OUT></table>


3

Python 2, 217 211 195 194 190

b,f,s='\/ '
R=str.replace
def m(g,n,z=1):
 for d in g.split('\n'):
    for i in range(z):a=z+~i;print[i,a][d[-1]>f]*s+R(R(R(R(d,s,s*n),'_','_ '[i<z-1]*(z+n-1)),f+b,f+s*2*i+b),b+f,b+s*2*a+f);z=n

6 ไบต์ขอบคุณ Sp3000

โทรหาmด้วยอาร์กิวเมนต์แรกเป็นเพชรเป็นสตริงและอาร์กิวเมนต์ที่สองหมายเลขการทำซ้ำ

สิ่งนี้ขึ้นอยู่กับลำดับการแทนที่สตริง 3 ขั้นตอน:

  • ขั้นแรกให้แทนที่ขีดล่างด้วยช่องว่าง 2n-1 หรือขีดล่างขึ้นอยู่กับบรรทัด
  • ประการที่สองแทนที่/\ด้วย/ \ด้วยจำนวนของช่องว่างการแทรกแซงไปจาก 2 ถึง 2 * (n-1) มากกว่าเส้น
  • ประการที่สามแทนที่ \/ด้วย\ /ด้วยจำนวนของช่องว่างการแทรกแซงจาก 2 * (n-1) ถึง 2 ในช่วงสาย

จากนั้นมีความหลากหลายของการล้อเล่นเพื่อให้ได้ช่องว่างที่ถูกต้องและเพื่อให้ได้บรรทัดแรก

โปรดทราบว่าบรรทัดสุดท้ายของโปรแกรมควรเป็นแท็บไม่ใช่ช่องว่าง 4 ช่อง Markdown ไม่รองรับแท็บ


สองกอล์ฟ: (i+(n-i+~i)*(d[-1]>f)) --> [i,n+~i][d[-1]>f]และคุณใช้เพียง'_'ครั้งเดียวดังนั้นคุณจึงเสียไบต์ที่กำหนด
Sp3000

3

Python, 272 238 228 243 ไบต์

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

s,u,f,b=' _/\\'
r=str.replace
def d(t,n,j=1):
 for p in t.split('\n'):
  for k in range(n-j,n):m,v=n+~k,'_ '[k<n-1];print r(r(r(r(r(r(r(r(p,f+u,'(_'),u+b,'_)'),s,s*n),u,v*n),f,s*m+f+s*k),'(',v*m+f+v*k),b,s*k+b+s*m),')',v*k+b+v*m).rstrip();j=n

เวอร์ชันที่มีช่องว่างและคำสั่งแบ่งออกเป็นหน่วยขนาดเล็กเพื่อให้สามารถอ่านได้:

s, u, f, b = ' ', '_', '/', '\\'
def d(t, n):
    j = n - 1
    for p in t:
        for k in range(j, n):
            m, v = n - 1 - k, '_ '[k < n - 1]
            q = p[:-1]
            q = q.replace(f + u, '(_')
            q = q.replace(u + b, '_)')
            q = q.replace(s, s * n)
            q = q.replace(u, v * n)
            q = q.replace(f, s * m + f + s * k)
            q = q.replace('(', v * m + f + v * k)
            q = q.replace(b, s * k + b + s * m)
            q = q.replace(')', v * k + b + v * m)
            print q
            j = 0

วิธีการพื้นฐานที่นี่คือ:

  1. วนรอบทุกบรรทัดในอินพุต
  2. สำหรับแต่ละบรรทัดวนรอบขนาดผลลัพธ์ Nสร้างบรรทัดเอาต์พุตในการวนซ้ำแต่ละรอบ มีกรณีพิเศษสำหรับบรรทัดแรกที่สร้างบรรทัดเอาต์พุตล่าสุดเท่านั้นเพื่อหลีกเลี่ยงการสร้างบรรทัดว่างที่จุดเริ่มต้นของเอาต์พุต
  3. แทนที่อักขระแต่ละตัวในบรรทัดด้วยNอักขระโดยที่:
    • แต่ละพื้นที่ถูกแทนที่ด้วยNช่องว่าง
    • ขีดล่างแต่ละอันจะถูกแทนที่ด้วยNช่องว่างสำหรับการN -1วนซ้ำครั้งแรกและNขีดล่างสำหรับการวนซ้ำครั้งสุดท้าย
    • สแลชและแบ็กสแลชนั้นถูกเสริมด้วย N - 1ช่องว่างหรือขีดล่าง

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

สิ่งที่ฉันทำเพื่อแก้ไขปัญหานี้ก็คือฉันจะแทนที่ชุดอักขระสองชุดด้วยอักขระที่แตกต่างกันก่อนเพื่อให้ฉันสามารถปฏิบัติกับพวกเขาแตกต่างกันระหว่างการทดแทนจริง ตัวอย่างเช่น,/_(_จะถูกแทนที่ด้วย หลังจากนี้(เป็น "เครื่องหมายทับตามด้วยขีดล่าง" อย่างมีประสิทธิภาพซึ่งสามารถทดแทนได้ตามนั้น

โปรแกรมหลักที่ใช้สำหรับทดสอบฟังก์ชั่น:

import sys
import Golf

n = int(sys.argv[1])
t = ''.join(sys.stdin).rstrip()

Golf.d(t, n)

1
n-1-kisn+~k
เรียกซ้ำ

เพื่อประโยชน์ในการเปิดเผยอย่างเต็มรูปแบบ: ฉันเพิ่งพบว่าโซลูชันของฉันสร้างช่องว่างต่อท้าย เนื่องจากไม่ได้รับอนุญาตในการกำหนดผลลัพธ์จึงไม่เป็นไปตามข้อกำหนด ในกรณีที่แย่ที่สุดฉันจะต้องเพิ่ม.rstrip()อีก 9 ตัวอักษร ฉันหวังว่าฉันจะทำได้ดีขึ้นและพบวิธีตัด 5 ตัวอักษรออกไป
Reto Koradi

ดูเหมือนว่ารูปแบบการป้อนข้อมูลของคุณไม่ได้รับอนุญาต sys.stdinไม่ใช่พารามิเตอร์อินพุตที่อนุญาต - คุณต้องจัดการสตริงเอง
isaacg

ดีที่คุณสามารถใช้sys.stdinและint(sys.argv[1])แต่คุณไม่อยากให้พวกเขาได้ฟรีโดยคาดหวังว่าพวกเขาจะผ่านในเป็นตัวแปร (ถ้าเป็นเกมที่ยุติธรรมแล้วคุณยังสามารถคาดหวังนามแฝงสำหรับrangeและ replace` และสิ่งอื่นที่คุณจะต้อง predefine) .
Martin Ender

@ MartinBüttnerมันบอกว่าฉันสามารถรับอินพุตเป็นอาร์กิวเมนต์ของฟังก์ชัน นี่ไม่ใช่สิ่งที่ฉันทำที่นี่หรือ ฉันจะเปลี่ยนอาร์กิวเมนต์ฟังก์ชั่นเป็นรายการสตริงต่อไป จะเป็นไรไหม มันไม่แตกต่างกันมากนักเนื่องจากทั้งคู่stdinและรายการสตริงเป็นลำดับของสตริง
Reto Koradi

1

Perl, 132

#!perl -p
INIT{$f=pop}s!.!$&x$f!ge;s! $!! while s!\\+\K\\|/(/)! $1!;
for$x(2..m!/!*$f){print y!_! !r;s!\\.?! \\!g;s!./(.)?!/$1$1!g;s!_ !__!g}

รวมอินพุต STDIN และ ARGV ตัวอย่าง:

$ perl ~/hex.pl <~/hex.txt 3
         __________________
        /     /     /\     \
       /     /     /  \     \
      /_____/_____/    \_____\
     /     /\     \    /\     \
    /     /  \     \  /  \     \
   /_____/    \_____\/    \_____\
  /\     \    /     /\    /     /\
 /  \     \  /     /  \  /     /  \
/    \_____\/_____/    \/_____/    \
\    /     /\     \    /     /\    /
 \  /     /  \     \  /     /  \  /
  \/_____/    \_____\/_____/    \/
   \     \    /     /\     \    /
    \     \  /     /  \     \  /
     \_____\/_____/    \_____\/
      \     \     \    /     /
       \     \     \  /     /
        \_____\_____\/_____/

1

ทับทิม 236 237

->i,z{i.split(?\n).map{|l|z.times.map{|y|l.size.times.map{|i|z.times.map{|x|c=l[i]
z<y+2&&(l[i-1..i]=='_\\'||l[i..i+1]=='/_')&&o=?_
(c<?!||(x==y&&c==?\\)||(z==y+1&&c>?^)||(x+y+1==z&&c==?/))&&o=c
o||' '}.join}.join.rstrip}-['']}.join ?\n}

การทดสอบออนไลน์: http://ideone.com/e6XakQ

นี่คือรหัสก่อนเล่นกอล์ฟ:

-> diamond, zoom {
  diamond.split(?\n).map do |l|
    zoom.times.map do |y|
      l.size.times.map do |i|
        zoom.times.map do |x|
          out_char = crt_char = l[i]

          out_char = ' '

          # _ has to be continued under / or \
          if zoom == y+1 && l[i-1..i]=='_\\'
            out_char = ?_
          end
          if zoom == y+1 && l[i..i+1]=='/_'
            out_char = ?_
          end

          # logic to "zoom" \, / and _ characters 
          out_char = crt_char if crt_char == ' '
          out_char = crt_char if x==y && crt_char == ?\\  
          out_char = crt_char if zoom==y+1 && crt_char == ?_
          out_char = crt_char if x+y+1==zoom && crt_char == ?/

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