ขยายคำพูดสามเส้า!
ท้าทาย
กำหนดสตริงที่มีความยาวเท่าใดก็ได้ให้เขียนเป็นรูปสามเหลี่ยมโดยหมุนวนออกจากจุดศูนย์กลาง ตัวอย่างเช่นabcdefghijklmnopกลายเป็น:
g
fah
edcbi
ponmlkj
หรือมากกว่าอย่างชัดเจน:
หากต้องการคุณสามารถหมุนวนทวนเข็มนาฬิกาแทน:
g
haf
ibcde
jklmnop
หรือเพิ่มช่องว่างอย่างสม่ำเสมอ:
g
f a h
e d c b i
p o n m l k j
อักขระที่ป้อนจะเป็น ascii แต่อาจมีช่องว่าง นอกจากนี้จำนวนอักขระอาจไม่ใช่กำลังสองที่สมบูรณ์แบบ ( Hello World!):
W
Ho
oller
!dl
ขอบอีกสองสามกรณี ป้อนตัวอักษร 2 ตัวab:
a
b
และป้อนตัวอักษร 3 ตัวabc:
a
cb
คำอธิบายขั้นตอน
ในกรณีที่ตัวอย่างข้างต้นไม่ชัดเจนนี่คือคำอธิบายขั้นตอนของกระบวนการ:
- ใส่อักษรย่อของคุณ
- เลื่อนลงในแนวทแยงมุมและไปทางขวา (กล่าวคือทิศทางนี้
\) ดังนั้นหากคุณเริ่มต้นตอน(0,0)นี้คุณจะอยู่ที่ (1, -1) ใส่จดหมายฉบับที่สองของคุณ - เลื่อนไปทางซ้ายทีละช่องวางตัวอักษรในแต่ละช่องว่างรวมเป็น 3 ช่อง นั่นคือการวางตัวอักษรบน
(0,-1), และ(-1,-1)(-2, -1) - ย้ายไปตามแนวทแยงขึ้นและไปทางขวา
/สองช่องว่างลดลงตัวอักษรบนและ(-1,0)(0,1) - ตอนนี้วนกลับไปที่การเคลื่อนที่ในแนวทแยงมุมลงและไปทางขวาทำตามขั้นตอนและวางตัวอักษรต่อไปตราบใดที่ตำแหน่งปัจจุบันของคุณอยู่ซ้าย - ขวาติดกับตัวอักษรที่มีอยู่
- ถัดไปเลื่อนไปทางซ้ายอีกครั้งดำเนินการต่อในขั้นตอนและวางตัวอักษรตราบเท่าที่คุณอยู่ติด
/กับตัวอักษรที่มีอยู่ในแนวทแยงมุม - เลื่อนขึ้นในแนวทแยงมุมและไปทางขวาอีกครั้ง
/ก้าวและวางตัวอักษรตราบใดที่ตำแหน่งปัจจุบันของคุณอยู่ซ้าย - ขวาติดกับตัวอักษรที่มีอยู่ - ทำซ้ำขั้นตอนที่ 5-7 จนกว่าตัวอักษรจะหมด
ตัวอย่างเพิ่มเติม
กฎ
- โค้ดกอล์ฟใช้กฎมาตรฐาน
- การเว้นวรรคต่อท้ายหรือขึ้นบรรทัดใหม่ก็ใช้ได้
- ช่องว่างนำหน้าหรือบรรทัดใหม่ที่สอดคล้องกันก็ใช้ได้เช่นกันตราบใดที่ยังคงรูปทรงของสามเหลี่ยมไว้
คำตอบ
05AB1E , 24 20 15 13 ไบต์
2Iā¨t·îŽOGsèΛ
-7 ไบต์โดย porting @Neil 's คำตอบถ่านโดยใช้@att ' s สูตรเพื่อให้แน่ใจว่าจะ upvote ทั้งสองของพวกเขาเช่นกัน!
ลองออนไลน์ ชุดทดสอบไม่มีเพราะ.Λในตัวจะทำให้เนื้อหาก่อนหน้านี้และไม่มีทางที่จะตั้งค่าใหม่ใด ๆ ( นี่คือสิ่งที่มันจะมีลักษณะ
คำอธิบาย:
2 # Push a 2
I # Push the input-string
ā # Push a list in the range [1,length] (without popping)
¨ # Remove the last value to change the range to [1,length)
t # Take the square-root of each value
· # Double each
î # Ceil each
ŽOG # Push compressed integer 6136
s # Swap so the list is at the top of the stack again
è # Index each value (0-based and modulair) into the 6136
Λ # Pop all three and use the Canvas builtin,
# after which the result is implicitly output immediately afterwards
ดู 05AB1E นี้เคล็ดลับของฉัน (ส่วนวิธีการบีบอัดจำนวนเต็มขนาดใหญ่? )จะเข้าใจว่าทำไมเป็นŽOG6136
Canvas builtin ใช้อาร์กิวเมนต์สามตัวในการวาดรูปร่าง:
- อักขระ / สตริงที่จะวาด: อินพุตในกรณีนี้
- ความยาวของเส้นที่เราจะวาด:
2ในกรณีนี้ - ทิศทางในการวาด:
[3,6,6,6,1,1,3,3,3,6,6,6,6,6,6,6,1,1,1,1,3,...].
ดูคำตอบเดิมด้านล่างสำหรับคำอธิบายของ Canvas ในตัว 2ซึ่งแตกต่างจากโปรแกรมดังต่อไปนี้ที่รายการของความยาวที่จะนำที่นี่รายการเส้นทางจะนำเพราะเราใช้ความยาวเดียวของ
คำตอบดั้งเดิม24 20 ไบต์ :
ā·Ð·s>ø.ι˜DŠOð׫₆1ªΛ
ประกอบด้วยช่องว่างนำหน้า / ต่อท้ายและขึ้นบรรทัดใหม่ (ยิ่งป้อนข้อมูลยาวช่องว่าง / ขึ้นบรรทัดใหม่มากขึ้น)
ลองออนไลน์ ไม่มีชุดทดสอบเนื่องจากใน.Λตัวจะเก็บเนื้อหาก่อนหน้านี้ไว้และไม่มีวิธีใดในการรีเซ็ต ( นี่คือสิ่งที่ดูเหมือนว่ากรณีทดสอบจะถูกดึงมาทับกัน)
คำอธิบาย:
ā # Push a list in the range [1, length] of the (implicit) input (without popping)
# i.e. "Hello World!" → "Hello World!" and [1,2,3,4,5,6,7,8,9,10,11,12]
· # Double each value in this list
# → [2,4,6,8,10,12,14,16,18,20,22,24]
Ð # Triplicate it
· # Double each value of the top copy
# → [4,8,12,16,20,24,28,32,36,40,44,48]
s # Swap to get the other copy
> # Increase each by 1
# → [3,5,6,9,11,13,15,17,19,21,23,25]
ø # Create pairs of the top two lists
# → [[4,3],[8,5],[12,7],[16,9],[20,11],[24,13],[28,15],[32,17],[36,19],[40,21],[44,23],[48,25]]
.ι # Interleave it with the third list
# → [2,[4,3],4,[8,5],6,[12,7],8,[16,9],10,[20,11],12,[24,13],14,[28,15],16,[32,17],18,[36,19],20,[40,21],22,[44,23],24,[48,25]]
˜ # Flatten
# → [2,4,3,4,8,5,6,12,7,8,16,9,10,20,11,12,24,13,14,28,15,16,32,17,18,36,19,20,40,21,22,44,23,24,48,25]
D # Duplicate this list of integers
Š # Triple-swap, so the stack order is list,input,list
O # Pop and sum the top list
# → 636
ð× # Create a string of that many spaces
« # And append it to the string
₆ # Push builtin 36
1ª # Convert it to a list of digits, and append 1: [3,6,1]
Λ # Use the Canvas builtin with these three arguments,
# after which the result is implicitly output immediately afterwards
Canvas builtin ใช้อาร์กิวเมนต์สามตัวในการวาดรูปร่าง:
- อักขระ / สตริงที่จะวาด: อินพุตในกรณีนี้ต่อท้ายด้วยช่องว่างต่อท้าย
- ความยาวของเส้นที่เราจะวาด: รายการ
[2,4,3,4,8,5,6,12,7,8,16,9,10,20,11,...] - ทิศทางในการวาด:
[3,6,1]. ตัวเลขในช่วง\$[0,7]\$ แต่ละอย่างแสดงถึงทิศทางที่แน่นอน:
7 0 1
↖ ↑ ↗
6 ← X → 2
↙ ↓ ↘
5 4 3
ดังนั้น[3,6,1]ในกรณีนี้ให้แปลเป็นเส้นทาง\$[↘,←,↗]\$.
คำอธิบายทีละขั้นตอนของเอาต์พุต (เราจะใช้อินพุต"Hello_World!"เป็นตัวอย่างที่นี่):
ขั้นตอนที่ 1: วาด 2 ตัวอักษร ( "He") ตามทิศทาง3↘:
H
e
ขั้นตอนที่ 2: วาด 4-1 ตัวอักษร ( "llo") ตามทิศทาง6←:
H
olle
ขั้นตอนที่ 3: วาด 3-1 ตัวอักษร ( "_W") ตามทิศทาง1↗:
W
_H
olle
ขั้นตอนที่ 4: วาด 4-1 ตัวอักษร ( "orl") ตามทิศทาง3↘:
W
_Ho
oller
l
ขั้นตอนที่ 5: วาด 8-1 อักขระ ( "d! ") ในทิศทาง6←:
W
_Ho
oller
!dl
และอื่น ๆ สำหรับช่องว่างต่อท้ายอื่น ๆ ทั้งหมด
ดูเคล็ดลับ 05AB1E ของฉันสำหรับคำอธิบายเชิงลึกเกี่ยวกับ Canvas ในตัว
ภาษา Wolfram (Mathematica) , 99 ไบต์
sPrint@@@Array[s[[4# #-2#+1-#2&@@If[Abs@#2<2#,!##,#-Abs@#2|-#2]]]/._@__->" "&,2{L=Tr[1^s],L},-L]
ลองออนไลน์!
คำนวณดัชนีของแต่ละตำแหน่งโดยตรง: ในพิกัดคาร์ทีเซียน\$\operatorname{index}(x,y)=\textit{offset}+\begin{cases}2y(2y+1)-x,&|x|<-2y\\ 2\left(y+|x|\right)\left(2\left(y+|x|\right)+1\right)+x,&\text{else}\end{cases}\$
ที่ไหน\$\textit{offset}\$ คือดัชนีของอักขระ "ตัวแรก" (1 ใน Mathematica)
รับรายการตัวอักษรเป็นอินพุต
วิธีการเก่า123 122 109 107 ไบต์
Print@@@Normal@SparseArray[i=0;p=2Length@#;(p+=ReIm[I[2+I,1-I][[⌈2√i++⌉~Mod~4-1]]-1])->#&/@#,2p," "]&
ลองออนไลน์!
ทิศทางของiอักขระ(1 ดัชนี) ที่สัมพันธ์กับอักขระก่อนหน้าสามารถคำนวณได้ด้วย\$\Big\lceil2\sqrt i\Big\rceil\bmod 4\$:
- 1: ↗
- 2: ↘
- 3,0: ←
ถ่าน , 37 36 21 ไบต์
GH✳✳E⊖LθI§4174⌈⊗₂⊕ι²θ
ลองออนไลน์! ไม่มีลิงก์ verbose เนื่องจาก deverbosifier แสดงผล✳σแทนการ✳✳สร้างรหัสรวบรัดที่ไม่ถูกต้องซึ่งทำงานไม่ถูกต้อง แต่ถ้าใช้งานได้ก็จะเป็นPolygonHollow(Directions(Map(Decremented(Length(q)), Cast(AtIndex("4174", Ceiling(Doubled(SquareRoot(Incremented(i)))))))), 2, q);เช่นนั้น แรงบันดาลใจจากโซลูชัน 05AB1E ของ @ KevinCruijssen แต่ใช้สูตรของ @ att เพื่อสร้างทิศทาง คำอธิบาย:
θ Input string
L Length
⊖ Decremented
E Map over implicit range
ι Current index (0-indexed)
⊕ Incremented (i.e. 1-indexed)
₂ Square rooted
⊗ Doubled
⌈ Ceiling
§4174 Cyclically index to find direction
I Cast to integer
✳✳ Convert to directions
GH ²θ Draw path using input string
คำสั่งการวาดพา ธ วาดหนึ่งอักขระสำหรับการเริ่มต้นจากนั้นn-1อักขระสำหรับแต่ละทิศทางในอาร์เรย์ น่าเสียดายที่ไม่มีสตริงอักขระเดี่ยวที่แสดงทิศทางในแนวทแยงดังนั้นฉันจึงต้องใช้จำนวนเต็มแทน เริ่มต้นที่0ขวาและเพิ่มขึ้นสำหรับแต่ละ 45 °ตามเข็มนาฬิกา
ก่อนหน้าโซลูชัน 37 ไบต์:
≔⮌⪪S¹θFLθF³F§⟦⊕⊗ι⁺³×⁴ι⊗⊕ι⟧κ¿θ✳⁻⁷׳κ⊟θ
ลองออนไลน์! ลิงก์คือรหัสเวอร์ชันที่ละเอียด คำอธิบาย:
≔⮌⪪S¹θ
แยกอินพุตเป็นอักขระและย้อนกลับรายการ
FLθ
วนซ้ำจำนวนครั้งมากพอ
F³
วนรอบสำหรับแต่ละด้านของสามเหลี่ยม
F§⟦⊕⊗ι⁺³×⁴ι⊗⊕ι⟧κ
ห่วงขนาดด้านข้าง
¿θ
ตรวจสอบว่ายังมีอะไรเหลือให้พิมพ์หรือไม่
✳⁻⁷׳κ⊟θ
พิมพ์อักขระถัดไปในทิศทางที่เหมาะสม
JavaScript (V8) 222 ไบต์
s=>(g=(a,b,n=1)=>b?g([(c=(b+' '.repeat(n*8)).slice(0,n*8))[n*6-1],...[...a,c.slice(0,n*4-1)].map((l,i)=>c[n*6+i]+l+c[n*6-2-i])],b.slice(n*8),n+1):a)([s[0]],s.slice(1)).reduce((p,l,i,a)=>p+' '.repeat(a.length-i-1)+l+`
`,'')
ลองออนไลน์!
แน่นอนที่สุดสามารถตีกอล์ฟได้มากขึ้น
ฉันใช้อัลกอริธึมแบบวนซ้ำโดยแยกผลลัพธ์ออกเป็น 'เลเยอร์' สามเหลี่ยมโดยที่แต่ละเลเยอร์เป็นส่วนที่สมบูรณ์ (สามด้าน) ของสามเหลี่ยมก่อนหน้า
ไม่พอใจ
s=>(g=(a,b,n=1)=> // g is a recursive function; a: previous; b: rest; n: increment
b ? // if there is more string to wrap
g([ // wrap b around a as a triangle and recurse
(c=(b+' '.repeat(n*8)).slice(0,n*8))[n*6-1],
...[...a,c.slice(0,n*4-1)].map((l,i)=>c[n*6+i]+l+c[n*6-2-i])
],
b.slice(n*8),
n+1)
:a // otherwise return the triangle
)
([s[0]],s.slice(1)) // run the function with the first letter and the rest
.reduce((p,l,i,a)=>p+' '.repeat(a.length-i-1)+l+'\n','') // step the triangle to make it look like it is meant to
JavaScript (ES8), 137 ไบต์
คาดหวังอาร์เรย์ของอักขระ ส่งคืนสตริง
เวอร์ชันนี้ใช้สูตรที่ใช้โดย @attแก้ไขให้เป็นมิตรกับกอล์ฟมากขึ้นใน JS
a=>a.map((c,n)=>(m[y+=~(d=2*n**.5-1/n)%4%3?d&++x/x||-1:!x--]=m[y]||[...''.padEnd(x)])[x]=c,m=[],x=y=a.length)&&m.map(r=>r.join``).join`
`
ลองออนไลน์! (เอาต์พุตดิบ)
ลองออนไลน์! (ลบช่องว่างเพิ่มเติม)
อย่างไร?
รับตำแหน่ง\$n\$ของตัวละครทิศทาง\$0\le d\le 2\$ สามารถคำนวณได้ด้วย:
$$d=\left(\left\lfloor2\sqrt{n}+1-\frac{1}{n}\right\rfloor\bmod 4\right)\bmod 3$$
การใช้งาน JS จริงคือ:
~(2 * n ** 0.5 - 1 / n) % 4 % 3
ซึ่งประเมินเป็น\$0\$, \$-1\$หรือ\$-2\$.
JavaScript (ES8), 163157 ไบต์
คาดหวังอาร์เรย์ของอักขระ ส่งคืนสตริง
a=>a.map(c=>((m[y]=m[y]||[...''.padEnd(x)])[x]=c,j%3%2?x--:y+=!!++x-j%3,k?k--:k=(n=j/3<<1)+(j++%3||n+2)),m=[],j=k=0,x=y=a.length)&&m.map(r=>r.join``).join`
`
ลองออนไลน์! (เอาต์พุตดิบ)
ลองออนไลน์! (ลบช่องว่างเพิ่มเติม)
อย่างไร?
นี่เป็นอัลกอริทึมที่ค่อนข้างตรงไปตรงมาที่ดึงอักขระเอาต์พุตตามอักขระในเมทริกซ์\$m[\:]\$, ติดตามตำแหน่ง\$(x,y)\$ของปากกาทิศทางใน\$\{0,1,2\}\$และหมายเลข\$k\$ ของอักขระที่จะวาดก่อนที่จะเปลี่ยนทิศทางถัดไป
เราย้ายตามตารางต่อไปนี้:
direction | moving towards | distance
-----------+----------------+----------
0 | South-East | 2t + 1 (t = turn number)
1 | West | 4t + 3
2 | North-East | 2t + 2
ซึ่งจะช่วยให้:
t = 0 t = 1 t = 2 t = 3
2
2 2.
2 2. 2..0
2 2. 2..0 2....0
2X 2.X0 2..X.0 2...X..0
1110 2....0 2......0 2........0
11111110 2........0 2..........0
111111111110 2............0
1111111111111110
ในการใช้งาน JS เราไม่ได้จัดเก็บทิศทางไว้อย่างชัดเจน แต่เราใช้ตัวนับ\$j\$ไปจาก\$0\$ถึง\$+\infty\$และใช้\$j\bmod 3\$เพื่อหาทิศทางปัจจุบัน เรายังไม่เก็บหมายเลขเทิร์น แต่คำนวณ\$n=2\cdot\lfloor j/3\rfloor\$โดยใช้ค่าของ\$j\$ ก่อนที่จะเพิ่มขึ้นเพื่อพิจารณาการเปลี่ยนแปลงทิศทาง (ซึ่งหมายความว่า\$n\$เท่ากับ\$2(t-1)\$มากกว่า\$2t\$เมื่อทิศทางไปยัง\$0\$).
ดังนั้นตารางต่อไปนี้:
j mod 3 | (j + 1) mod 3 | | new starting
(old direction) | (new direction) | new distance | value for k
-----------------+-----------------+---------------------+--------------
2 | 0 | (n + 2) + 1 = n + 3 | n + 2
0 | 1 | 2n + 3 | 2n + 2
1 | 2 | n + 2 | n + 1
และนิพจน์ที่เกี่ยวข้องเพื่ออัพเดต\$k\$:
k = (n = j / 3 << 1) + (j++ % 3 || n + 2)
มีการอัปเดตพิกัดด้วย:
j % 3 % 2 ? // if the direction is 1:
x-- // decrement x
: // else:
y += !!++x - j % 3 // increment y if the direction is 0
// or decrement y if it's 2
// increment x in both cases
R , 205 153 147 136 132 126 ไบต์
-52 จาก Dominic van Essen
-4 จาก Giuseppe
-4 ขอบคุณจูเซปเป้อีกครั้ง
-5 ขอบคุณเพิ่มเติมจาก Dominic van Essen
function(s,n=nchar(s))for(y in(x=-n:n)*2)cat(ifelse((i=(t=y-2*(r=abs(x))*!r<y)*t-t-2*(r<y)*x+x+1)>n," ",substring(s,i,i)),"
")
ลองออนไลน์!
Pip -l 70 ไบต์
sMC:Y#ax:w:y/2-/2Ly*2L++i/2{I++v<ys@w@x:a@vi%4%3?++x&i%4=1?--w++w--x}s
ลองออนไลน์!
... ฉันไม่แน่ใจว่าฉันอยากจะลองอธิบายความโหดร้ายนี้โดยละเอียด แนวคิดพื้นฐานคือการสร้างอาร์เรย์ 2 มิติขนาดใหญ่เกินขนาดของช่องว่าง ( sMC:#a) จากนั้นใส่อักขระจากสตริงอินพุตลงในอาร์เรย์ที่ดัชนีที่เหมาะสม ( s@w@x:a@v) ส่วนที่เหลือของโค้ดจะระบุว่า "ดัชนีที่เหมาะสม" คืออะไร
แนวทางอื่น 77 ไบต์:
a.:sX#aW<|a{UpaWa^@YxNl?v+1++v%2?v*2+1vl:xNl?RV^p.:lv%2?lPEpl.^pAEx}RVsX,#l.l
ลองออนไลน์!
สร้างสามเหลี่ยมเป็นรายการของเส้นสลับระหว่างการเพิ่มบรรทัดที่ส่วนหน้า / ท้ายของรายการและเพิ่มอักขระที่ส่วนหน้า / ท้ายของแต่ละบรรทัด ฉันหวังว่าวิธีนี้อาจจะสั้นกว่านี้ แต่จนถึงตอนนี้ดูเหมือนว่าจะไม่ใช่
J , 60 ไบต์
4 :'x(<"1(#x)++/\(3|4|>.2*%:i.#x){<:3 3#:3 2 8)}y',~' '"0/,~
ลองออนไลน์!
คำตอบของ J บังคับเพราะเป็นความท้าทายของโยนาห์
เนื่องจาก "แทนที่ตำแหน่งที่แน่นอนภายในอาร์เรย์ด้วยค่า" ไม่ใช่คำกริยา แต่เป็นคำวิเศษณ์จึงไม่สามารถใช้ในรถไฟตามที่เป็นอยู่ได้ดังนั้นจึงรวมอยู่ในคำกริยาอินไลน์ที่ชัดเจน
ใช้สูตรของ attเพื่อสร้างทิศทาง
มันทำงานอย่างไร
NB. input: a string (character vector) of length n
,~' '"0/,~ NB. create a large enough canvas (blank matrix of size 2n*2n)
,~ NB. concatenate two copies of self
/ NB. outer product by...
' '"0 NB. a constant function that returns blank per character
,~ NB. concatenate two copies of self
4 :'...' NB. a dyadic explicit verb, where x is the input string and
NB. y is the canvas generated above
x(...)}y NB. replace some places of y by contents of x...
3|4|>.2*%:i.#x NB. formula by att (gives 0, 1, or 2 per index)
(...){ NB. select the directions based on the above...
<:3 3#:3 2 8 NB. the matrix (0 -1)(-1 1)(1 1) i.e. L/RU/RD
(#x)++/\ NB. take cumulative sum (giving coords to place each char)
NB. and add n to all elements
<"1 NB. enclose each row to satisfy the input format of }
R , 270 265 252 243 232 227 225 ไบต์
ในที่สุดฉันก็สามารถลบอักขระอีก 2 ตัวเพื่อนำผลรวมมาเป็นตัวเลขที่สามารถแสดงในรูปสามเหลี่ยมได้ (ดังที่แสดงไว้ที่นี่) โค้ดควรได้รับการจัดรูปแบบตามอัตภาพที่จะรัน (ดังตัวอย่างใน TIO); '•' แทนอักขระขึ้นบรรทัดใหม่ ( \n)
f
unc
tion(
s,`~`=c
bind,m=ma
trix){n=nch
ar(s)+1;p=m(,
n^2,2);while(T<
n){a=4*F;p[T+0:a,
]=c(F:-F,(-F:F)[-1]
)~0:a-2*F;p[T+a+-2:a+
3,]=(F=F+1)~(b=2*F-1):-
b;T=T+2*a+4};m=m(" ",n,n)
;m[p[2:n-1,]+b+1]=el(strspl
it(s,''));apply(m,1,cat,"•")}
ลองออนไลน์!
โปรดทราบว่าแนวทางนี้ได้รับความสนใจอย่างมากจากแนวทางของ attแม้ว่าการปลอบใจจะไม่มีคำตอบอื่นใดในปัจจุบันที่สามารถแสดงเป็นรูปสามเหลี่ยมได้ ...
ทำงานโดยการสร้างพิกัดสำหรับตัวอักษรแต่ละตัวจากนั้นใช้สิ่งนี้เพื่อใส่ตัวอักษรลงในเมทริกซ์ว่าง
แสดงความคิดเห็น:
triangle=
function(s){n=nchar(s) # n is the number of letters
s=el(strsplit(s,'')) # first split the string into individual letters
p=matrix(,2,n^2) # initialize p as a 2-row matrix to hold the coordinates
# (with plenty of columns so that we've enough to go all
# the way round the outermost triangle)
# now, F is the current loop, starting at 0
while(T<=n){ # T is the current letter index
a=4*F+1 # a=the size of the 'arch' (number of letters going up & over)
p[,T+1:a-1]= # set the coordinates for the arch letters...
rbind( # ...(rbind combines rows for y & x coordinates)...
c(F:-F,(-F:F)[-1]), # ...to y = F..-F, and then -F+1..F (so: up & then down again)
1:a-2*F-1) # ...and x = across the arch from -2*F to +2*F
a=a+2 # a=now the width of the base = size of arch + 2
p[,T+a+1:a-3]= # now set the coordinates of the base letters...
rbind( #
F+1, # ... base y = row F+1
(b=2*F+1):-b) # ... and x = goes (backwards) from 2*F+1..-2*F-1
T=T+2*a-2 # update the current letter index
F=F+1} # increment the loop
p=p[,1:n] # delete any excess coordinates
p=p-min(p)+1 # re-zero the coordinates to remove negatives
m=matrix(" ",b<-max(p),b) # create a new matrix filled with " "
m[t(p)]=s # and fill it with the letters at the right positions
n=apply(m,1,cat," # finally, print each row
")}
Scala, 322 318 ไบต์
s=>((s zip Seq.unfold((0,0,0->0)){case(r,n,y->x)=>Option.when(n<s.size){val(c,t)=(math.sqrt(n).toInt%2,r+1-math.abs(x.sign))
(y->x,(t,n+1,(y+(c-1)*(1-t%2*2),x+1-c*2)))}}groupBy(_._2._1)toSeq)sortBy(_._1)map(_._2.sortBy(_._2._2)map(_._1)mkString)zipWithIndex)map{t=>" "*(math.sqrt(s.size).toInt-t._2)+t._1}mkString "\n"
ลองใช้ใน Scastie (ใช้ไม่ได้กับ TIO)
Perl 5 , 163 ไบต์
sub f{ #newlines and indentation added here for readability.
$_=' 'x1e3; @L=(51,$a=-1,-49)x($p=225); for$c(pop=~/./g){
$P=$p+$L[1]; $a++>0&&s/^(.{$P}) /$1$c/s&&($p=$P,$a=0,shift@L)||substr$_,$p+=$L[0],1,$c
}
s/.{50}/$&\n/gr
}
กล่าวโดยย่อคือเพิ่มถ่านถัดไปจากอินพุตในทิศทางปัจจุบันเว้นแต่จะพบว่าถึงเวลาที่ต้องเปลี่ยนทิศทาง
ลองออนไลน์!