ช่วยให้สถาปนิกมองเห็นเส้นขอบฟ้า


29

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

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

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

สำหรับรายละเอียดและคำชี้แจงเกี่ยวกับผลลัพธ์โปรดดูตัวอย่างด้านล่าง:

N = 3
 ___
|   |
|   |
|___|

N = 3.5
  _      
 / \
|   |
|   |
|___|

N = 6
 ___
|   |
|   |
|   |
|   |
|   |
|___|

n = 0
_

อินพุตตัวอย่าง: 3 3.5 0 2

      _
 ___ / \  
|   |   |  ___
|   |   | |   |
|___|___|_|___|

อินพุตตัวอย่าง: 0 0 2.5 3 0 4 1

             ___
    _  ___  |   |
   / \|   | |   |
  |   |   | |   |___
__|___|___|_|___|___|

ลุยวิลล์ ,0 2 1 3.5 0 4 2 4 2 4 6 1 6 0 5 1

                                    ___     ___
                                   |   |   |   |  ___
           _    ___     ___     ___|   |   |   | |   |
          / \  |   |   |   |   |   |   |   |   | |   |
  ___    |   | |   |___|   |___|   |   |   |   | |   |
 |   |___|   | |   |   |   |   |   |   |___|   | |   |___
_|___|___|___|_|___|___|___|___|___|___|___|___|_|___|___|

อักขระ ASCII ที่ใช้คือ: บรรทัดใหม่ช่องว่างและ/\_|(รหัสคะแนน 10, 32, 47, 92, 95, 124)

กฎ:

  • มันเป็นทางเลือกในการสร้างโปรแกรมที่รับจำนวนเต็มเป็นอินพุตโดยคูณตัวเลขทั้งหมดด้วยสอง ดังนั้นแทนที่จะสละโปรแกรมของคุณอาจต้องใช้เวลา3 3.5 2 6 7 4หากเลือกรูปแบบอินพุตที่สองอินพุต 6 ควรส่งผลให้อาคาร 3 ชั้น 7 ควรเป็นอาคาร 3 ชั้นที่มีหลังคาแหลม ฯลฯ
  • เอาต์พุตควรตรงตามที่อธิบายไว้ข้างต้น แต่ช่องว่างต่อท้ายและบรรทัดใหม่นั้นโอเค
  • รูปแบบที่แน่นอนของอินพุตเป็นตัวเลือก สิ่งที่ดีที่สุดในภาษาของคุณ
  • ต้องแสดงผลลัพธ์บนหน้าจอเพื่อให้สถาปนิกสามารถดูได้
  • คุณสามารถสันนิษฐานได้ว่าจะมีจำนวนเต็มอย่างน้อยหนึ่งค่าและจะให้เฉพาะอินพุตที่ถูกต้องเท่านั้น

นี่คือ codegolf ดังนั้นโค้ดที่สั้นที่สุดเป็นไบต์จะเป็นผู้ชนะ


1
สิ่งปลูกสร้างความสูง 0.5 มีลักษณะอย่างไร
Tom Carpenter

ไม่เคยคิดเลยจริงๆ ตัวเลือกที่ชัดเจนที่สุดจะเป็นเพียงหลังคาแหลมเกือบเหมือนบ้านฮอบบิท :-) แต่คุณมีอิสระที่จะเลือกหรือคุณสามารถสันนิษฐานได้ว่าอินพุตจะไม่ 0.5 ...
Stewie Griffin

1
ในขณะที่สิ่งแปลก ๆ เกิดขึ้นเนื่องจากไม่มีกำแพง (ฉันคิดว่าไม่มีสูง 0.5) ดังนั้นฉันจะต้องตอบคำถามของฉันสักหน่อย
Tom Carpenter

ฉันเพิ่งลองรหัสของคุณที่มีความสูง 0.5 และฉันเห็นด้วย "แปลก" เป็นคำที่สื่อความหมายมาก = PI ยังไม่ผ่านรายละเอียดดังนั้นฉันไม่แน่ใจว่าเกิดอะไรขึ้น ... ไม่ว่าคุณจะตอบอย่างไร ถูกต้องสมบูรณ์แบบคุณสามารถสันนิษฐานได้ว่าไม่มีอาคารใด ๆ ...
Stewie Griffin

คำตอบ:


5

Python 2, 199 193 188 185 ไบต์

a=map(int,raw_input().split())
l=max(a)+1|1
while~l:print''.join((x%2*'/  _\\ '[x<l::2]*(x<=l<x+4)or'_ '[x|1!=l>1]*3)[x<1:x+2]+'| '[x<=l>=y]*(x+y>0)for x,y in zip([0]+a,a+[0]))[1:];l-=2

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


! ที่ยอดเยี่ยม ฉันเป็นต้องขโมยบางส่วนของเทคนิคเหล่านี้สำหรับโรงแรมพร้อมสนามกอล์ฟในอนาคต ...
quintopia

5

MATLAB, 219 209 203 ไบต์

i=input('');x=1;c=0;m(1:4*numel(i))='_';for a=i;b=fix(a);m(1:b,x)='|';s=95;if a~=b;m(b+2,x+2)=95;s='/ \';end;m(b+1,x+(1:3))=s;x=x+(a>0)*3+1;m(1:b,x)='|';x=x+(a<1&c>0);c=a;end;disp(flipud(m(:,1:x-(a<1))))

นี้น่าเสียดายที่ไม่ได้ทำงานบนคู่ ไม่แน่ใจทั้งหมดว่าทำไมดูเหมือนจะเป็นสิ่งที่ต้องทำกับบิต disp / flipud ที่แบ่ง

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

ต่อไปนี้เป็นรหัสในวิธีที่อ่านง่ายขึ้นเล็กน้อย:

i=input(''); %e.g. [0 0 2 1 3.5 0 4 2 4 2 4 6 1 6 0 5 1 0 0 1 0]
x=1;
c=0;
m(1:4*numel(i))='_';
for a=i;
    b=fix(a);
    m(1:b,x)='|';
    s=95;
    if a~=b;
        m(b+2,x+2)=95;
        s='/ \';
    end;
    m(b+1,x+(1:3))=s;
    x=x+(a>0)*3+1;
    m(1:b,x)='|';
    x=x+(a<1&c>0);
    c=a;
end;
disp(flipud(m(:,1:x-(a<1))))

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

i=input(''); %e.g. [0 0 2 1 3.5 0 4 2 4 2 4 6 1 6 0 5 1]
x=1;
c=0;

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

m(1:4*numel(i))='_';

ตอนนี้เราดึงแต่ละอาคารออกมา

for a=i

ก่อนอื่นเราจะได้จำนวนเต็มส่วนสูงซึ่งจะเป็นตัวกำหนดจำนวน '|' พวกเราต้องการ.

    b=fix(a);

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

    m(1:b,x)='|';

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

    s=95;
    if a~=b;
        m(b+2,x+2)=95;
        s='/ \';
    end;

วาดบนหลังคา

    m(b+1,x+(1:3))=s;

ตอนนี้ย้ายไปที่จุดเริ่มต้นของสิ่งปลูกสร้างถัดไปและวาดในกำแพงที่ใช้ร่วมกัน (ถ้ากำแพงสั้นเกินไป ณ จุดนี้มันจะใหญ่ขึ้นเมื่ออาคารถัดไปถูกดึงขึ้นมา) โปรดทราบว่าอาคารที่มีความสูงเป็นศูนย์นั้นกว้าง 1 อาคารปกติจะมีความกว้าง 4 แห่งดังนั้นเราจึงทำให้สิ่งที่จะเป็น if-else ทำได้โดยการปฏิบัติ (a> 0) เป็นเลขทศนิยมไม่ใช่บูลีน

    x=x+(a>0)*3+1;
    m(1:b,x)='|';

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

    x=x+(a<1&c>0);
    c=a;
end;

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

disp(flipud(m(:,1:x-(a<1))))

ดังนั้นเมื่อเรารันสคริปต์นี้เราจะขอให้คุณป้อนตัวอย่างเช่น:

[0 0 2 1 3.5 0 4 2 4 2 4 6 1 6 0 5 1 0 0 1 0]

จากนั้นจะสร้างสิ่งปลูกสร้างและแสดงผลลัพธ์ สำหรับอินพุตข้างต้นจะมีการสร้างสิ่งต่อไปนี้:

                                     ___     ___                   
                                    |   |   |   |  ___             
            _    ___     ___     ___|   |   |   | |   |            
           / \  |   |   |   |   |   |   |   |   | |   |            
   ___    |   | |   |___|   |___|   |   |   |   | |   |            
  |   |___|   | |   |   |   |   |   |   |___|   | |   |___    ___  
__|___|___|___|_|___|___|___|___|___|___|___|___|_|___|___|__|___|_

ทำได้ดีมาก!
Stewie Griffin

4

Kotlin, 447 442 ไบต์

val a={s:String->val f=s.split(" ").map{it.toFloat()}.toFloatArray();val m=(f.max()!!+1).toInt();for(d in m downTo 0){var l=0f;for(c in f){val h=c.toInt();print(if(h==d&&d!=0)if(h<l-0.5)"|" else{" "}+if(c>h)"/ \\" else "___" else if(h<d)if(d<l-0.5)"|" else{" "}+if(h==0)" " else if((c+0.5).toInt()==d)" _ " else "   " else{if(h==0)if(l<1)"  " else "| " else "|   "}.replace(' ',if(d==0)'_' else ' '));l=c;};if(d<l-0.5)print("|");println();}}

เวอร์ชันที่ไม่ถูกปรับแต่ง:

val ungolfed: (String) -> Unit = {
    s ->

    val floats = s.split(" ").map { it.toFloat() }.toFloatArray()
    val maxH = (floats.max()!! + 1).toInt()

    for (drawHeight in maxH downTo 0) {
        var lastBuildingH = 0f
        for (f in floats) {
            val buildingH = f.toInt()
            if (drawHeight == 0) {
                // Baseline
                if (buildingH == 0)
                    if (lastBuildingH.toInt() == 0) print("__")
                    else print("|_")
                else print("|___")
            } else if (buildingH == drawHeight) {
                // Ceiling
                if (buildingH < lastBuildingH - 0.5) print("|")
                else print(" ")
                if (f > buildingH) print("/ \\")
                else print("___")
            } else if (buildingH < drawHeight) {
                // Above building
                if (drawHeight < lastBuildingH - 0.5) print("|")
                else print(" ")
                if (buildingH == 0) print(" ")
                else {
                    if ((f + 0.5).toInt() == drawHeight) print(" _ ")
                    else print("   ")
                }
            } else {
                if (buildingH == 0) print("| ")
                else print("|   ")
            }
            lastBuildingH = f;
        }
        if (drawHeight < lastBuildingH - 0.5) print("|")
        println()
    }
}

3

Python 2, 357 306 299 294 287 281 276 ไบต์

def s(l):
 d=len(l)+1;l=[0]+l+[0];h=(max(l)+3)/2;o=''
 for i in range(d*h):
  a=l[i%d+1];c=l[i%d];b=2*(h-1-i/d);o+="|"if(a>b+1)+(c>b+1)else" "*(a+c>0);o+=" _/__  _\\"[a-b+1::3]if b*(1>=abs(a-b))else" "*(1+2*(a>0))
  if b==0:o=o.replace(" ","_")
  if i%d==d-1:print o[:-1];o=''

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

แก้ไข: xsot ดีกว่า

คำอธิบาย:

d=len(l)+1;l=[0]+l+[0];m=max(l);h=m/2+m%2+1;o=''

dคือ 1 มากกว่าความยาวของอาเรย์เพราะเราจะเพิ่มศูนย์ในแต่ละด้านของรายการจากองค์ประกอบที่สองจนถึงศูนย์ที่เราเพิ่มเข้าไปในตอนท้าย hคือความสูงของภาพวาด (เราต้องหารด้วย 2 ในการคำนวณนี้เพราะเราใช้ตัวแทนที่เป็นสองเท่าซึ่งเราใช้เป็นพิเศษเพื่อหลีกเลี่ยงการโยนลอยตัวไปยังสถานที่ต่าง ๆ ทั่วโลกนอกจากนี้เรายังเพิ่ม 1 ก่อนที่จะแบ่งความสูงแปลก ๆ ได้รับการกวาดล้างมากกว่าชนิดปกติเล็กน้อย) oคือสตริงเอาต์พุต

 for i in range(d*h):

เคล็ดลับมาตรฐานสำหรับการยุบสองครั้งสำหรับการวนซ้ำเป็นแบบวนซ้ำสำหรับการวนซ้ำ เมื่อเราทำ:

  a=l[i%d+1];c=l[i%d];b=2*(h-1-i/d)

ตอนนี้เราได้ทำเช่นเดียวกับ:

for b in range(2*h-2,-2,-2):
 for j in range(d):
  a=l[j+1];c=l[j]

แต่ในวิธีที่ช่วยให้เราประหยัดสิบไบต์ (รวมถึงช่องว่างในบรรทัดต่อไปนี้)

  o+="|"if(a>b+1)+(c>b+1)else" "*(a+c>0)

ติดผนังทุกครั้งที่ความสูงของอาคารปัจจุบันหรืออาคารก่อนหน้าสูงกว่าเส้นปัจจุบันตราบใดที่มีขอบเขตอาคารอย่างน้อยหนึ่งแห่ง มันเทียบเท่ากับเงื่อนไขต่อไปนี้:

  o+=("|" if a>b+1 or c>b+1 else " ") if a or c else ""

โดยที่ b คือความสูงการสแกนปัจจุบัน a คือความสูงอาคารปัจจุบันและ c คือความสูงของอาคารก่อนหน้า ส่วนหลังของเงื่อนไขป้องกันการวางกำแพงระหว่างพื้นที่ดิน

  o+=" _/__  _\\"[a-b+1::3]if b*(1>=abs(a-b))else" "*(1+2*(a>0))

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

  if b==0:o=o.replace(" ","_")

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

  if i%d==d-1:print o[:-1];o=''

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


รถกอล์ฟ ว้าว. (และ +1)
ตบมือ

2

Python 3

725 ไบต์

608 ไบต์

รหัส Golfed:

import sys,math;
m,l,w,s,bh,ls,ins,r,a="|   |","___","|"," ",0,[],[],range,sys.argv[1:]
def ru(n):return math.ceil(n)
def bl(h,n):
    if(n>ru(h)):return(s*5,s)[h==0]
    if(h==0):return"_"
    if(n==0):return w+l+w
    if(n<h-1):return m
    return("  _  "," / \ ")[n==ru(h)-1]if(h%1)else(s+l+s,m)[n==h-1]
for arg in a:
    f=ru(float(arg))
    if(bh<f):bh=f
for i in r(bh,-1,-1):
    ln=""
    for bld in a:ln+=bl(float(bld),i)
    ls.append(ln)
for i in r(len(ls[-1])-1):
    if(ls[-1][i]==ls[-1][i+1]==w):ins.append(i-len(ins))
for ln in ls:
    for i in ins:ln=(ln[:i]+ln[i+1:],ln[:i+1]+ln[i+2:])[ln[i]==w]
    print(ln)

นี่คือโค้ดที่ไม่ได้ถูกดัดแปลง มีความคิดเห็นบางส่วน แต่แนวคิดพื้นฐานคือการสร้างอาคารที่มีผนังสองชั้นดังนั้นบรรทัดล่างจะมีลักษณะดังนี้:

_|___||___|_|___||___|

จากนั้นเพื่อรับดัชนีของผนังสองชั้นเหล่านั้นและลบคอลัมน์เหล่านั้นออกไปเราจะได้:

_|___|___|_|___|___|

รหัส:

import sys
import numbers
import math

mid="|   |";
l="___";
w="|";
s=" ";

def printList(lst):
    for it in lst:
        print(it);

# h = height of building
# l = line numeber starting at 0
def buildingline(h,n):
    #if (h==0):
    #   return " " if(n>math.ceil(h)) else "   ";
    if(n>math.ceil(h)):
        return s if(h == 0) else s*5;
    if(h==0): return "_";
    if(n==0): return w+l+w;
    if(n<h-1): return mid;
    if(h.is_integer()):
        return mid if(n==h-1) else  s+l+s;
    else:
        return " / \ " if (n==math.ceil(h)-1) else "  _  "; 
# max height
bh=0;

for arg in sys.argv[1:]:
    f = math.ceil(float(arg));
    if(bh<f):bh=f;

# lines for printing
lines = []

for i in range(bh,-1,-1):
    line="";
    for bld in sys.argv[1:]:
        bld=float(bld);
        line += buildingline(bld,i);
        #lh = bld;
    lines.append(line);

#for line in lines:
#   print(line);
#printList(lines);


# column merging
#find indexes for merging (if there are | | next to each other)
indexes = [];
for i in range(len(lines[-1])-1):
    if (lines[-1][i]=='|' and lines[-1][i+1] == '|'):
        indexes.append(i-len(indexes));

#printList(indexes);

#index counter
for line in lines:
    newLine = line;
    for i in indexes:
        if newLine[i] == '|' :
            newLine=newLine[:i+1] + newLine[i+2:];
        else : newLine = newLine[:i] + newLine[i+1:];
    print(newLine);

ได้เวลาเล่นกอล์ฟ!


คุณอาจต้องการที่จะได้ดูที่นี่ ฉันคิดว่ามันมีศักยภาพในการเล่นกอล์ฟมากมายที่นี่ =) ฉันรู้จัก Python พื้นฐานเท่านั้นดังนั้นฉันไม่สามารถแนะนำอะไรที่เฉพาะเจาะจงที่ฉันกลัว ...
Stewie Griffin

ดูเหมือนว่าคุณจะลบช่องว่างและทำให้ชื่อตัวแปรสั้นลง แต่ก็ยังคงไม่เปลี่ยนแปลง คุณควรพยายามหาวิธีที่ชาญฉลาดในการกำจัดลูปบางอย่างใช้การเปรียบเทียบที่น้อยลง ฯลฯ แน่นอนว่าสิ่งต่าง ๆ เช่นru(n):return math.ceil(n)ค่าเท่ากับการเล่นกอล์ฟ แต่ก็ยัง ... โปรดอย่าใช้สิ่งนี้ในทางลบฉันไม่ใช่ นักกอล์ฟที่ดีและแน่นอนว่าไม่ใช่นักเขียนโปรแกรมที่ดี ฉันขอแนะนำให้คุณลองปรับปรุงบางอย่าง ... มันสนุกจริงๆเมื่อคุณรู้ว่าคุณสามารถย่อให้สั้นลงได้ ฉันไปจากหลาย ๆ คนเป็น 120 ถึง 55 เมื่อสองสามวันก่อน ดังนั้นจึงเป็นไปได้แม้ว่าคุณจะใหม่
Stewie Griffin

@StewieGriffin ขอบคุณสำหรับลิงค์นี้! ฉันเป็นมือใหม่ในการเล่นรหัสดังนั้นมันจึงเกี่ยวกับการทำภารกิจให้สำเร็จมากกว่าที่จะทำรหัสกอล์ฟให้ฉัน แต่น่าประหลาดใจที่ค้นพบความเป็นไปได้ของภาษาต่าง ๆ
Cajova_Houba

FTR: สำหรับความท้าทายที่ซับซ้อนมากขึ้นเช่นนี้ฉันจะมีความสุขที่จะทำมันเองให้สำเร็จ =)
Stewie Griffin

2

PHP, 307 297 293 ไบต์

<?$r=str_pad("",$p=((max($argv)+1)>>1)*$w=4*$argc,str_pad("\n",$w," ",0));for(;++$i<$argc&&$r[$p++]=_;$m=$n)if($n=$argv[$i]){$q=$p+=!$m;eval($x='$r[$q-1]=$r[$q]=$r[$q+1]=_;');for($h=$n>>1;$h--;$q-=$w)$r[$q-2]=$r[$q+2]="|";$n&1?($r[$q-1]="/")&($r[$q-$w]=_)&$r[$q+1]="\\":eval($x);$p+=3;}echo$r;

รับอาร์กิวเมนต์ * 2 จากบรรทัดคำสั่ง php <filename> <parameters>บันทึกลงในแฟ้มทำงานด้วย

ทำให้พังถล่ม

// initialize result    
$r=str_pad("",              // nested str_pad is 3 bytes shorter than a loop
    $p=                     // cursor=(max height-1)*(max width)=(start of last line)
    ((max($argv)+1)>>1)     // max height-1
    *
    $w=4*$argc              // we need at least 4*($argc-1)-1, +1 for newline
    ,
    // one line
    str_pad("\n",$w," ",0)  // (`str_pad("",$w-1)."\n"` is one byte shorter,
);                          // but requires `$w+1`)

// draw skyline
for(;
    ++$i<$argc              // loop through arguments
    &&$r[$p++]=_                // 0. draw empty ground and go one forward
    ;
    $m=$n                       // 7. remember value
)
    if($n=$argv[$i])            // if there is a house
    {
        $q=                         // 2. copy $p to $q
        $p+=!$m;                    // 1. go one forward if there was no house before this
        // offset all further positions by -2 (overwrite empty ground, share walls)
        eval($x=                    // 3. draw floor
        '$r[$q-1]=$r[$q]=$r[$q+1]=_;'
        );
        for($h=$n>>1;$h--;$q-=$w)   // 4. draw walls
            $r[$q-2]=$r[$q+2]="|";
        $n&1                        // 5. draw roof
            ?($r[$q-1]="/")&($r[$q-$w]=_)&$r[$q+1]="\\"
            :eval($x)               // (eval saved 7 bytes)
        ;                           // (ternary saved 6 bytes over `if`)
        $p+=3;                      // 6. go three forward (5-2)
    }

// output
echo$r;

1

C ++ ไม่อัปโหลด

(หรืออาจเลวร้าย)

สมมติว่ามีองค์ประกอบน้อยกว่า 100 รายการและแต่ละองค์ประกอบน้อยกว่า 100 sคือจำนวนสิ่งปลูกสร้าง (จำเป็นในอินพุต)

#include <iostream>
using namespace std;
int main()
{
float a[100];
int i,j,s;
cin>>s;
for(i=0;i<s;++i)
 cin>>a[i];
for(i=100;i>=1;--i)
{
for(j=0;j<s;++j)
{
if((a[j]>=i)||(a[j-1]>=i))
 cout<<"|";
else
 cout<<" ";
if(i==1)
 cout<<"___";
else if(a[j]+1==i)
 cout<<"___";
else if(a[j]+1.5==i)
 cout<<" _ ";
else if(a[j]+0.5==i)
 cout<<"/ \\";
else cout<<"   ";
}
if(a[s-1]>=i)
 cout<<"|";
cout<<endl;
}
}

มีข้อผิดพลาดเล็กน้อยในเอาต์พุต ... พื้นมีความกว้าง 3 อักขระ (ควรเป็น 1 เท่านั้น) และกำแพงสุดท้ายหายไป
Stewie Griffin

@StewieGriffin ฉันยังคงคัดแยกข้อผิดพลาดเมื่อฉันโพสต์สิ่งนี้ 1. ฉันได้เพิ่มกำแพงสุดท้าย 2. พื้นดินต้องมีความกว้าง 3 ตัวอักษรเนื่องจากหลังคาแบบเอียง / _ \ มีความกว้าง 3 ตัวอักษร
ghosts_in_the_code

1
* พื้นดินระหว่างอาคารไม่ใช่ภายใน
Stewie Griffin

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

@StewieGriffin ฉันไม่ได้ตั้งใจจะส่งคำตอบกอล์ฟเพราะมันยาวเกินไป ฉันสามารถเดิมพันได้ว่ามีภาษาที่ดีกว่าซึ่งสามารถทำได้ใน 100 ไบต์ ดังนั้นรหัสของฉันจึงเป็นโซลูชันอ้างอิงให้ผู้อื่น
ghosts_in_the_code
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.