มหาปิรามิดแห่ง ASCII


25

บทนำ

ตอนนี้ 2,600 ปีก่อนคริสตกาลและผู้คนกำลังสร้างปิรามิดตอนนี้ พวกเขาสร้างพื้นฐานของปิรามิดแล้ว แต่ไม่รู้วิธีดำเนินการต่อ ดังนั้นพวกเขาจึงโทรหาคุณเพื่อขอความช่วยเหลือ

กฎของการสร้างพีระมิดค่อนข้างง่าย สำหรับเลเยอร์เหนือเลเยอร์ก่อนหน้าสิ่งที่คุณต้องทำคือทำตามคำแนะนำทีละขั้นตอนนี้:

  1. ตัดขอบออกจากเลเยอร์ก่อนหน้า

  2. เหนือ/ตัวละครจะต้องมี\ตัวละครและในทางกลับกัน สิ่งนี้ใช้ได้กับทุกตัวละครยกเว้นขอบ

  3. อักขระซ้ายสุดอยู่เสมอและตัวอักษรขวาสุดอยู่เสมอ/\

ลองมาเป็นตัวอย่างของพื้นฐานสำหรับปิรามิด:

//\/\/\\

เราตัดขอบทิ้ง:

 /\/\/\

เราเปลี่ยนสแลชไปข้างหน้าด้วยแบ็กสแลชและในทางกลับกัน:

 \/\/\/

ตัวละครทางซ้ายสุดจะเป็นเสมอ/และตัวละครที่อยู่ด้านขวาสุดจะเป็นเสมอ\ดังนั้นเราจึงเปลี่ยน:

 //\/\\

เราวางเลเยอร์นี้ในเลเยอร์ก่อนหน้า:

 //\/\\
//\/\/\\

เราดำเนินต่อไปจนกว่าจะถึงด้านบน (ซึ่งดูเหมือน/\) ดังนั้นในที่สุดเราก็ได้:

   /\
  //\\
 //\/\\
//\/\/\\

นี่คือสิ่งที่คุณต้องการส่งออก

งาน

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

กรณีทดสอบ

Input: /\\\
Output:
 /\
/\\\

Input: //\\///\/\
Output:
    /\
   /\\\
  /\///\
 ///\\\/\
//\\///\/\

Input: /////////////\
Output:
      /\
     /\\\
    /////\
   /\\\\\\\
  /////////\
 /\\\\\\\\\\\ 
/////////////\

นี่คือดังนั้นการส่งที่มีจำนวนไบต์น้อยที่สุดจะชนะ!


ทำให้ผมนึกถึงเซลล์หุ่นยนต์ระดับประถมศึกษา บางทีนั่นอาจจะเป็นความท้าทายในอนาคตที่น่าสนใจ?
DoctorHeckle

คำตอบ:


9

เจลลี่ ,28 26 2524 ไบต์

QṚ,QyḊḊṖṖj@QµÐĿµJ’⁶ẋ⁸żYṚ

-4 ไบต์ขอบคุณเดนนิส

สูตรอาหาร:

QṚ,QyḊḊṖṖj@QµÐĿµJ’⁶ẋ⁸żYṚ - one argument: input()
Q  Q       Q             - set of Left=input(): "/\"
 Ṛ                       - reverse Left: "\/"
  ,                      - Left-pair-Right: ["\/","/\"]
     ḊḊṖṖ                - dequeue Left twice, then pop twice: input()[2:-2]
    y                    - translate Right with mapping in Left: swaps internal slashes
         j@              - join Right with separator Left (@ swaps operands)
            µ  µ         - chain separators to form a 1,1,1 chain of chains
             ÐĿ          - loop while results are unique and collect them
                J        - yield [1,...,len(Left=input())]
                 ’       - decrement: [0,....len(input())-1]
                  ⁶      - " "
                   ẋ     - repeat Left Right times: ["", " ", ...]
                    ⁸ż   - zip Right and Left (⁸ is the link's Left argument):
                                ...pads the loop results
                      Y  - joins Left with line-feeds
                       Ṛ - reverse Left

(เสิร์ฟพร้อมน้ำมะนาวปิรามิดเหล่านั้นทำเพื่อคนงานกระหายน้ำ)

ปรุงปิรามิดสแลชของคุณเองที่TryItOnlineหรือลองชิมชิมของ OP ที่แนะนำ



11

Pyth - 27 26 ไบต์

ลดลงโดยการดำเนินการที่ได้รับใน OP จนกว่ามันจะทำซ้ำซึ่งเป็นกรณีสำหรับบรรทัดว่าง

j_.e+*kdb.ujXtPtPNK"\/")_K

Test Suite


8

Python 2, 78 ไบต์

f=lambda s,p='\n':(s[2:]and f('/%s\\'%s.translate('/\\'*128)[2:-2],p+' '))+p+s

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

งูหลาม 3 สามารถบันทึกไบต์โดยทำ*99ในtranslateขณะที่ความต้องการความยาว-256 ถูกทิ้ง


ฉลาดในการใช้การแปล แต่เราไม่จำเป็นต้องพิมพ์?
Jonathan Allan

@JanathanAllan ไม่ได้เป็นค่าเริ่มต้นคุณเพียงแค่ส่งออกตามที่ความท้าทายบอกว่า
xnor

6

Haskell, 98 94 90 85 ไบต์

q=init.tail
s '/'='\\'
s _='/'
t#""=t++"\\\n"
t#l=(' ':t)#(s<$>q l)++t++l#""
("/"#).q

ตัวอย่างการใช้งาน (หมายเหตุ: ในแบ็กสแลชของ Haskell ภายในสตริงตัวอักษรจะต้องหลบหนี\\):

*Main> putStr $ (("/"#).q) "//\\\\///\\/\\"
    /\
   /\\\
  /\///\
 ///\\\/\
//\\///\/\

วิธีการเรียกคืนแบบง่าย: #ทำงานโดยการแมปsซึ่งจะพลิก/และ\บนองค์ประกอบภายใน พารามิเตอร์เพิ่มเติมtจะติดตามระดับเยื้องและถูกขยายด้วยช่องว่างสำหรับการโทรซ้ำแต่ละครั้ง

หมายเหตุ: โทร recursive ที่สองของ#(-> l#"") กระโดดโดยตรงกับกรณีฐานและเป็นเพียงวิธีที่สั้นเพื่อเพิ่มl, และการขึ้นบรรทัดใหม่คือมันแทนที่\++l++"\\\n"

แก้ไข: @xnor บันทึก 5 ไบต์ ขอบคุณ!


l++"\\\n"l#""ดูเหมือนว่า
xnor

1
เป็นวิธีที่น่าสนใจที่จะสลับสองตัวละครในสตริงคือs [c|x<-s,c<-"ab",c/=x]
xnor

@ xnor: ฉันพยายามหลายสิ่งเพื่อกำจัดวินาที++"\\\n"แต่พลาดสิ่งนี้ ขอบคุณ!
nimi

6

Python 3 108 104 101 94 91 89 89 88 ไบต์

b,f='\/';p=lambda t,n='\n':(t[2:]and p(f+''.join(map({f:b,b:f}.get,t[2:-2]))+b,n+' '))+n+t

-7 ไบต์ขอบคุณ xnor (แจ้งให้เราทราบว่าเราไม่ต้องพิมพ์!)
-3 ไบต์ขอบคุณ xnor (การประกาศนอกฟังก์ชั่นการประกาศ [d'oh])
-1 ไบต์ขอบคุณ Dennis (แทนที่f,b='/\\'ด้วยb,f='\/')

ทดสอบบนideone หมายเหตุ: อินพุตถูกปรับสำหรับแบ็กสแลชสองครั้ง (แม้ว่าสตริงดิบจะไม่ทำงานหากมันจบด้วยแบ็กสแลชจำนวนคี่)


คุณสามารถประกาศร่วมกันf,b='/\\'นอกฟังก์ชั่น
xnor

@xnor ขอบคุณฉันนับไม่ได้ ^^
Jonathan Allan

5

JavaScript (ES6), 91 86 ไบต์

f=
(s,t=`
`)=>s[2]?f(`/${s.slice(2,-2).replace(/./g,c=>c>`/`?`/`:`\\`)}\\`,t+` `)+t+s:t+s
;
<input placeholder=Basis oninput=o.textContent=f(this.value)><pre id=o>

เอาต์พุตประกอบด้วยอักขระบรรทัดใหม่นำหน้า


3

Ruby, 80 ไบต์

f=->s{s[-3]>?!&&f[" "+s.gsub(/^( *\/).|.(.$)?/){$1||$2||($&>?/??/:?\\)}]
puts s}

Ungolfed

f = ->s{
  s[-3] > ?! &&
    f[" " + s.gsub(/^( *\/).|.(.$)?/) {
      $1 || $2 || ($& > ?/ ? ?/ : ?\\)
    }]
  puts s
}

ดูบน ideone: http://ideone.com/HN0l0Y


ไม่ดีของฉันไม่เห็นว่าfในร่างกาย
Cyoce

3

แบตช์ 137 ไบต์

@echo off
if %1==/\ goto g
set s=%1
set s=\%s:~2,-2%/
set s=%s:/=-%
set s=%s:\=/%
set s=%s:-=\%
call %0 %s% "%~2 "
:g
echo %~2%1

สิ่งอำนวยความสะดวกการใช้งานของฉัน%~2และวิธีการที่ผมหลีกเลี่ยงที่จะใช้จ่ายในไบต์%1 setlocalคำอธิบาย: เนื่องจาก Batch จะไม่ทำการแทนที่บนสตริงว่างเราจึงต้องตั้งค่าเลเยอร์ถัดไปด้วยขอบ "ผิด" ซึ่งจะถูกแก้ไขเป็นส่วนหนึ่งของการแทนที่สตริง


2

BASH (เรียงลำดับ + เรียง) 71 66 ไบต์

sed -rne':l;p;y|\\|1|;y|/|\\|;y|1|/|;th;:h;s|\\.(.*)./| /\1\\|;tl'|sort   
sed -rne':l;p;y|\\/|1\\|;y|1|/|;th;:h;s|\\.(.*)./| /\1\\|;tl'|sort

อินพุตมาจาก stdin
ตัวอย่าง:

echo '//\\' |sed -rne':l;p;y|\\|1|;y|/|\\|;y|1|/|;th;:h;s|\\.(.*)./| /\1\\|;tl'|sort

 /\
/\\\

คำอธิบาย:
-n- ระงับการพิมพ์อัตโนมัติ
:l- และ tlกลับไปที่จุดเริ่มต้นหากบรรทัดนี้เป็นอย่างอื่น/\
p - พิมพ์บรรทัดนี้
y|\\/|1\\|;y|1|/|- แทนที่\ด้วย1, /ด้วย\, จากนั้น1ด้วย/
th;:h- ทดสอบและข้ามสถานที่เดียวกันเพื่อให้มีการทดสอบการแทนที่ถัดไปเท่านั้น ในภายหลัง
s|\\.(.*)./| /\1\\|- แทนที่ทั้งสองข้างนอกที่ทับกันในแต่ละด้านด้วย{space}/และ\
sort- spaceมาก่อน/ดังนั้นสิ่งนี้จะทำให้ทุกอย่างถูกต้อง


2

05AB1E, 42 38 36 ไบต์

Dg;<FÐgÍ©£R®ÍN-£„/\‡'/ðN>׫«R'\«}r»

ลองออนไลน์!

คำอธิบาย:

# Read the input to the stack, loop for 0 .. len(input) / 2 - 1
Dg;<F
# Save the layer by pushing a copy on the stack, then push
# len(layer) - 2 to both the top of the stack and register_c
     ÐgÍ©
# a = pop(); b = pop(); push(b[0:a].reverse())
# This removes the last 2 characters and reverses
         £R
# push(register_c - 2 - N)
           ®ÍN-
# a = pop(); b = pop(); push(b[0:a])
# This removes the leading spaces and the first two slashes
               £
# Push "/\" and "\/" to the stack.
                 „/\Â
# Transliterate the slashes
                     ‡
# Add N+1 spaces and a / to the end of the (reversed) current layer
                      '/ðN>׫«
# Reverse the layer and add a \ to the end.
                              R'\«
# End the loop
                                  }
# Reverse the stack and join it with newlines. It is implicitly printed.
                                   r»

(ขอบคุณEmigna ที่ชี้ให้เห็นDD -> ÐและDR -> Â)


Dg;GDðK¦¦¨¨„/\‡'\«R'/«ðN׫R}r»บันทึก 7 ไบต์
Emigna

ฉันคิดว่าคุณควรเพิ่มคำตอบของคุณเอง :)
ปลุก

1

ไป, 300 276 ไบต์

package main
import(."regexp";."os")
func p(b string)string{
s:=MustCompile(`((\s*.)(\S*)(\S))`).FindStringSubmatch(b)
if s[3]!=""{r:=""
for _,c:=range s[3][1:len(s[3])-1]{r+=`\/`[c/64:c/46]}
return p(" "+s[2]+r+`\`)+s[1]+"\n"}
return s[1]+"\n"}
func main(){print(p(Args[1]))}

รุ่นยาว:

package main

import (
    "regexp"
    "os"
)

func pyramid(base string) string {
    m := regexp.MustCompile(`^((\s*\S)(\S*)(\S))\s*`).FindStringSubmatch(base)
    if len(m[3]) > 0 {
        reversed := ""
        for _, c := range m[3][1:len(m[3]) - 1] {
            if c == '/' {
                reversed += `\`
            } else {
                reversed += `/`
            }
        }
        return pyramid(" " + m[2] + reversed + m[4]) + m[1] + "\n"
    }
    return m[1] + "\n"
}

func main() {
    print(pyramid(os.Args[1]))
}

import(."regexp";."os")บันทึก 2 ไบต์
Sefa

@Sefa ขอบคุณฉันบีบอีก 22 ไบต์จากมัน
Roland Illig

1

Perl, 53 52 ไบต์

รวม +1 สำหรับ -p

เรียกใช้ด้วยอินพุตบน STDIN เช่น

./pyramid.pl <<< '//\\///\/\'

pyramid.pl:

#!/usr/bin/perl -p
s%^( *)/.(.*)..%"$1 \\$2/
"=~y|\\/|/\\|r.$&%e&&redo

1

05AB1E , 31 ไบต์

Dg;GDðK¦¦¨¨„/\‡'\«R'/«ðN׫R}r»

คำอธิบาย

Dg;G                        }    # for N in [1..len(input)/2-1]
    D                            # make a copy of previous layer
     ðK                          # remove all spaces
       ¦¦¨¨                      # remove first 2 and last 2 chars
           „/\‡                 # replace '/' with '\' and vice versa
                '\«              # add a backslash at the end
                   R             # reverse
                    '/«          # ad a slash at the end
                       ðN׫      # add N spaces
                           R     # reverse back
                             r»  # reverse stack and join on newline
                                 # implicitly print

ลองออนไลน์


1

> <> , 186 179 175 171 ไบต์

0&v &+1&<
  >i:0)?^~&2,:&v
v'/'~v?:-1<  }0<
o    >84*o^-$;?=@:&:&}:~<
\&::&{:@+$}1+[{l1-$-2*:&1+{
>}1-:?!v$:l2%?!vo
^o'/'v?~e  (*5a<
^o'\'< &   >~]a'\'oo{1+:^
  {$1- >:?!^

oooh man นี่เป็นคำตอบที่ใหญ่ที่สุดของฉัน> <>

ยังมีสนามกอล์ฟเหลืออยู่ให้ทำ (พื้นที่ด้านล่างค่อนข้างสิ้นเปลือง)

ลองออนไลน์



0

C #, 250 ไบต์

s=>{int j=s.Length/2,i=0;var l=new string[j];l[j-1]=s;while(++i<j){var n=l[j-i].Trim().Substring(1,l[j-i].Trim().Length-2);l[j-i-1]=new string(' ',i)+"/"+n.Replace("/","#").Replace(@"\","/").Replace("#",@"\").Substring(1,n.Length-2)+@"\";}return l;};

สามารถตีกอล์ฟต่อไปได้อย่างแน่นอน แต่สมองของฉันตายไปแล้วดังนั้นฉันจึงตัดสินใจทิ้งมันไว้

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