ASCII Ripple สามเหลี่ยม


12

ตกลงคำถามกอล์ฟครั้งแรกของฉัน กรุณาอ่อนโยน :) ฉันรู้ว่ามันมีวิธีการเล่น ASCII มากเกินไป: P แต่ที่นี่เราไปกัน

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

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

คุณได้รับอนุญาตให้ใช้ช่องว่างสีขาวได้ทุกที่ที่คุณต้องการตราบใดที่ ripples เหมือนกับตัวอย่างที่มีขนาดถูกต้อง

ตัวอย่าง

q)g 1
__
\/
q)g 2
____
\  /
 \/
q)g 3
______
\    /
 \  /
  \/
q)g 4
________
\  __  /
 \ \/ /
  \  /
   \/
q)g 5
__________
\  ____  /
 \ \  / /
  \ \/ /
   \  /
    \/
q)g 6
____________
\  ______  /
 \ \    / /
  \ \  / /
   \ \/ /
    \  /
     \/
q)g 7
______________
\  ________  /
 \ \  __  / /
  \ \ \/ / /
   \ \  / /
    \ \/ /
     \  /
      \/
q)g 8
________________
\  __________  /
 \ \  ____  / /
  \ \ \  / / /
   \ \ \/ / /
    \ \  / /
     \ \/ /
      \  /
       \/

ตามปกติรหัสที่สั้นที่สุดชนะ :)


2
ในขณะที่ไม่ได้เป็นที่แน่นอนซ้ำวาดศูนย์กลาง ASCII รูปหกเหลี่ยมผมไม่แน่ใจว่ามันจะเพิ่มมากขึ้นกว่าคนอื่น ๆ
Geobits

4
@Geobits IMO นั้นแตกต่างกันพอ - ข้อมูลจำเพาะอินพุตค่อนข้างแตกต่างกันวิธีการหาจำนวนรูปร่างที่จะวาดแตกต่างกันและรูปสามเหลี่ยม! = hexagons ;-)
Digital Trauma

@WooiKent ตอนนี้ฉันสงสัยว่าฉันเข้าใจคำถามถูกต้องหรือไม่ ระลอกคืออะไร? มันเป็นหนึ่งชุดสามเหลี่ยมศูนย์กลางหรืออย่างอื่น?
Digital Trauma

2
เป็นคำถามที่ดี แต่ไม่ได้ระบุไว้ (1) การอ่านข้อความอย่างแท้จริงเมื่ออินพุทเป็น 1,2 หรือ 3 เราควรเอาต์พุตสามเหลี่ยมสามรูปเสมอ (2) ฉันจะใช้มันตามที่ระบุว่าสามเหลี่ยมแต่ละชุดควรเป็นศูนย์กลางและ (3) ดูเหมือนว่าพวกเขาควรมีมุมด้านล่างในบรรทัดเดียวกันด้วย (4) การแยกในแนวนอนต้องเป็นหนึ่งช่องว่างตามที่แสดงหรืออนุญาตให้มีการแยกอื่น ๆ ได้หรือไม่? (5) ช่องว่างที่ไม่จำเป็นต้องได้รับอนุญาตให้ (a, b, c, d) ซ้าย, ขวา, ด้านบน, ด้านล่างหรือไม่
เลเวลริเวอร์เซนต์

ฉันคิดว่ามันค่อนข้างชัดเจนแม้ว่าจะไม่ชัดเจน คุณวาดสามเหลี่ยมหนึ่งขนาดตามที่กำหนดเสมอโดยมีสามเหลี่ยมซ้อนกันขนาด n-3, n-6, n-9 และอื่น ๆ
Sparr

คำตอบ:


5

Pyth, 31 ไบต์

VhQ+J<t+++*Nd*N"\ "d*Q\_Q_XJ"\/

สาธิต.

คำอธิบาย:

VhQ+J<t+++*Nd*N"\ "d*Q\_Q_XJ"\/
                                   Implicit: Q = eval(input()), d = ' '
VhQ                                for N in range(Q + 1):
                                   Concatenate:
          *Nd                      N spaces
         +   *N"\ "                N of the string "\ "
        +          d               another space
       +            *Q\_           Q of the string "_"
                                   If N = 2 and Q = 7, the string so far is:
                                   "  \ \  _______" and we want
                                   " \ \  _" as the left half.
      t                            Remove the first character.
     <                  Q          Take the first Q characters remaining.
                                   This is the left half of the triangle ripple.
    J                              Store it in J.
                          XJ"\/    Translate \ to / in J.
                         _         Reverse it.
   +                               Concatenate the left and right halves and print.

7

GNU sed -nr, 210

การเริ่มต้น:

s/1/__/g
p
s#_(.*)_#\\\1/#
s#\\__#\\  #
s#__/#  /#
ta
:a
p
s#(.*) _{6}(_*) # \1\\  \2  /#;ta
s#(.*)  (  )# \1\2#;
s#(.*) _(_*)_ # \1\\\2/#
y/_/ /
Tc
:b
p
:c
s#(.*)((\\)  ( *)(/)|()()()\\/)# \1\3\4\5#;tb

ข้อมูลป้อนเข้าเป็นจำนวนเต็มบวกโดยรวมผ่าน STDIN ตามคำถามเมตานี้

เอาท์พุท:

$ for i in 1 11 111 1111 11111 111111 1111111; do sed -rnf triripple.sed <<< $i; done
__
\/

____
\  /
 \/

______
\    /
 \  /
  \/

________
\  __  /
 \ \/ /
  \  /
   \/

__________
\  ____  /
 \ \  / /
  \ \/ /
   \  /
    \/

____________
\  ______  /
 \ \    / /
  \ \  / /
   \ \/ /
    \  /
     \/

______________
\  ________  /
 \ \  __  / /
  \ \ \/ / /
   \ \  / /
    \ \/ /
     \  /
      \/

$ 

5

C, 165 ไบต์

n,x,y,b,c;main(c,v)char**v;{for(n=atoi(v[1]);y<=n;++y){for(x=-n;x<n;++x){b=2*n-abs(2*x+1);c=b-2*y+2;b-=6*y;putchar(b>0?95:b<-4&c>0&c%4==1?"/\\"[x<0]:32);}puts("");}}

ก่อนขั้นตอนตีกอล์ฟที่ทำลายความสามารถในการอ่าน:

#include <stdio.h>
#include <stdlib.h>

int main(int c, char** v) {
    int n = atoi(v[1]);
    for (int y = 0; y <= n; ++y) {
        for (int x = -n; x < n; ++x) {
            int b = 2 * n - abs(2 * x + 1);
            int c = b - 2 * y + 2;
            b -= 6 * y;
            putchar(b > 0 ? 95 : 
                    b < -4 && c > 0 && c % 4 == 1 ? "/\\"[x<0] : 32);
        }
        puts("");
    }
}

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


มีความสุขกับงานคณิตศาสตร์ คุณควรลองอันนี้: codegolf.stackexchange.com/q/51396/21348
edc65

156:n,x,y,b,c;main(c,v)char**v;{for(n=atoi(v[1]);y<=n;++y)for(x=-n;x<=n;putchar(x++-n?b>6*y?95:b<6*y-4&c>0&c%4==1?"/\\"[x<1]:32:10))c=(b=2*n-abs(2*x+1))-2*y+2;}
edc65

4

เรติน่า 182 ไบต์

1
_
^
#$_
((`#([^#]*?)( ?)_(_*)_( ?)([^#]*?)$
$0# $1\$3/$5
+)`\\( ?)_(_*)_( ?)/(?=[^#]*$)
\ $1$2$3 /
#( *(\\ )*\\ *)  ( *(/ )*/)$
$0# $1$3
)`#( *(\\ )*)\\/(( /)*)$
$0# $1$3
# 
#
^#
<empty line>

ใช้อินพุตเป็น unary

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

> echo -n 1111|retina -s triangle|tr # '\n'
________
\  __  /
 \ \/ /
  \  /
   \/

รหัสไม่ได้ถูกตีกอล์ฟจนเกินไป (ยัง)


2

C - 206 ไบต์

i,j,m,k,a,b;main(i,v)char**v;{m=atoi(v[1])*2;while(k<m*(m/2+1)){i=k/m;j=k%m;a=i*3,b=(i+j)%2;putchar("_\\/ "[j>=a&&j<m-a?0:j>i-2&&b&&j<i*3-1&&j<m/2?1:j<=m-i&&!b&&j>m-a&&j>=m/2?2:3]);if(j==m-1)puts("");k++;};}

 x,m,i,j,a,b;
int main(x,v)char**v;{
    m=atoi(v[1])*2;
    for(i=0;i<m/2+1;i++){
        for(j=0;j<m;j++){
            a=i*3,b=(i+j)%2;
            j>=a&&j<m-a?a=0:j>=i-1&&b&&j<i*3-1&&j<m/2?a=1:j<=m-i&&!b&&j>m-a&&j>=m/2?a=2:(a=3);putchar("_\\/ \n"[a]);
        }
        puts("");
    }
}

ตัวอย่างผลลัพธ์

Pauls-iMac:ppcg pvons$ for i in $(seq 1 7); do ./a.out $i; done
__
\/
____
\  /
 \/ 
______
\    /
 \  / 
  \/  
________
\  __  /
 \ \/ / 
  \  /  
   \/   
__________
\  ____  /
 \ \  / / 
  \ \/ /  
   \  /   
    \/    
____________
\  ______  /
 \ \    / / 
  \ \  / /  
   \ \/ /   
    \  /    
     \/     
______________
\  ________  /
 \ \  __  / / 
  \ \ \/ / /  
   \ \  / /   
    \ \/ /    
     \  /     
      \/      

1
คุณสามารถเล็มนี้ลงได้เล็กน้อย การใช้ประโยชน์จากรูปแบบเดิม C, intคุณสามารถประกาศตัวแปรโดยไม่ต้องพิมพ์ถ้าพวกเขามี นอกจากนี้หากคุณประกาศพวกเขาที่ขอบเขตทั่วโลกพวกเขาจะเริ่มต้นโดยอัตโนมัติเป็น 0 แทนที่จะมีพวงของการputchar()โทรในสาขาที่แตกต่างกันคุณสามารถใช้การโทรเดียวและแทนที่ifคำสั่งที่มีผู้ประกอบการที่ประกอบไปด้วยสาม แน่นอนว่ามันยากที่จะอ่านด้วยวิธีนี้ แต่ในความคิดของเว็บไซต์นี้ที่จะเขียนโค้ดที่น่าเกลียดถ้ามันสั้นกว่านี้ :)
Reto Koradi

ขอบคุณ @RetoKoradi ฉันลดจาก 279 เป็น 214 โดยใช้คำแนะนำของคุณ :) ฉันคิดว่าฉันต้องปรับปรุงอัลกอริทึมของฉันเพื่อรับการปรับปรุงเพิ่มเติม
paulvs

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

1

JavaScript ( ES6 ) 165 180 204

เรียกใช้ตัวอย่างใน Firefox เพื่อทดสอบ หากส่งคืนสตริงไม่เพียงพอการใช้การแจ้งเตือนสำหรับเอาต์พุตจะมี 2 ตัวอักษรมากกว่า

// 165 - return the string
F=n=>
  (i=>{
    for(r='__'[R='repeat'](m=n);i<n;)
      r+=`\n`+' '[R](i)
       +('\\ '[R](t=-~(m>3?i:~-n/3))+' ').slice(0,n-i)
       +'__'[R](m>3?m-=3:0)
       +(' '+' /'[R](t)).slice(i++-n)
  })(0)||r


// 167 - output the string
A=n=>{
  for(i=0,r='__'[R='repeat'](m=n);i<n;)
    r+=`\n`+' '[R](i)
     +('\\ '[R](t=-~(m>3?i:~-n/3))+' ').slice(0,n-i)
     +'__'[R](m>3?m-=3:0)
     +(' '+' /'[R](t)).slice(i++-n);
  alert(r)
}

// TEST
out=x=>O.innerHTML += x+'\n' 

for(k=1;k<13;k++)out(k+'\n'+F(k))
<pre id=O></pre>

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