ข้อความบนวงกลม


19

เขียนโปรแกรมหรือฟังก์ชั่นที่พิมพ์สตริงอินพุตรอบ ๆ วงวงกลมที่มีรัศมีน้อยที่สุด ตัวอย่างเช่นสำหรับอินพุตThis is an exampleโปรแกรมของคุณควรมีเอาต์พุต:

  a si   
 n     s 
        i
e       h
x       T
a        
m        
 p       
  le     

การสร้างวงกลม

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

นี่คือรหัสหลอกของอัลกอริทึม (ตามตัวอย่าง C ของ Wikipedia):

integer x = radius
integer y = 0
int decisionCriterion = 1 - x

while y <= x 
    point at coordinates (x,y) belongs to the circle   // Octant 1
    point at coordinates (y,x) belongs to the circle   // Octant 2
    point at coordinates (-x,y) belongs to the circle  // Octant 4
    point at coordinates (-y,x) belongs to the circle  // Octant 3
    point at coordinates (-x,-y) belongs to the circle // Octant 5
    point at coordinates (-y,-x) belongs to the circle // Octant 6
    point at coordinates (x,-y) belongs to the circle  // Octant 7
    point at coordinates (y,-x) belongs to the circle  // Octant 8

    y++
    if decisionCriterion <= 0
        decisionCriterion += 2 * y + 1
    else
        x--
        decisionCriterion += 2 * (y - x) + 1
end while

คุณอาจจะใช้ขั้นตอนวิธีการที่แตกต่างกันและถ้าหากมันผลิตวงการเดียวกันแน่นอนว่าอัลกอริทึมวงกลมจุดกึ่งกลางผลิตสำหรับรัศมีทั้งหมด

วงกลมจะต้องมีรัศมีที่เล็กที่สุดเท่าที่จะเป็นไปได้ซึ่งยังคงอนุญาตให้เขียนตัวอักษรทั้งหมดของอินพุต

ถ้าวงกลมจบลงด้วยคะแนนมากกว่าจำนวนตัวอักษรในสตริงแล้วตัวละครที่กรอกผ่านมาจะเป็นช่องว่าง

(Radius,0)ตัวอักษรตัวแรกของท่านจะต้องพิมพ์ในประเด็นที่มีพิกัด อักขระที่ตามมาจะถูกพิมพ์แบบทวนเข็มนาฬิกา

ปัจจัยการผลิต

อินพุตเป็นสตริงของอักขระ ASCII ใด ๆ ระหว่างช่องว่าง(32) และเครื่องหมายตัวหนอน~(126)

คุณอาจสันนิษฐานว่าอินพุตจะใช้ได้ตลอดเวลาสั้นกว่า 256 อักขระและยาวอย่างน้อย 5 อักขระ

อินพุตอาจถูกนำมาจาก STDIN หรือเป็นพารามิเตอร์ฟังก์ชันหรือสิ่งอื่นที่คล้ายคลึงกัน

เอาท์พุท

คุณสามารถแสดงผลลัพธ์เป็น STDOUT หรือส่งกลับเป็นสตริงจากฟังก์ชัน

คุณอาจมีช่องว่างต่อท้ายโดยไม่ทำให้บรรทัดยาวเกินกว่าเส้นที่ยาวที่สุด (เส้นตรงกลาง) (เช่นกลางบรรทัดไม่สามารถมีช่องว่างต่อท้ายได้)

อนุญาตให้ขึ้นบรรทัดใหม่ต่อท้าย

กรณีทดสอบ

Input: Hello, World!
Output:
  ,ol  
     l 
W     e
o     H
r      
 l     
  d!   


Input: 4 8 15 16 23 42
Output:
  51   
     8 
1      
6     4

 2   2 
  3 4  


Input: Programming Puzzles & Code golf
Output:
     gnim    
  uP     ma  
 z         r 
 z         g 
l           o
e           r
s           P

&            

 C           
  od     f   
    e Gol    


Input: Ash nazg durbatuluk, ash nazg gimbatul, ash nazg thrakatuluk agh burzum-ishi krimpatul.
Output:
            zan hsa ,           
           g         ku          
        ig             lu        
      bm                 ta      
     a                     b     
    t                       r    
   u                         u   
   l                         d   
  ,                              
                              g  
 a                             z 
 s                             a 
h                               n

n                               h
a                               s
z                               A
g                                

t                                
h                                
 r                               
 a                             . 
  k                           l  
  a                           u  
   t                         t   
   u                         a   
    l                       p    
     u                     m     
      k                  ri      
        ag              k        
          h          hi          
            burzum-is            

เกณฑ์การให้คะแนน

นี่คือดังนั้นคำตอบที่สั้นที่สุดในหน่วยไบต์ชนะ

คำตอบ:


1

Mathematica, 359 357 354

(L=Length;T=Tuples;c=Characters@#;For[r=1,L[p=RotateRight[SortBy[#,ArcTan@@N@#&]+r+1,L@#/4+1]&@(f=1-r;X=1;Y=-2r;x=0;y=r;q={{0,r},{0,-r},{r,0},{-r,0}};While[x<y,If[f>0,y--;f+=Y+=2];x++;f+=X+=2;q=Join[q,T@{{x,-x},{y,-y}},T@{{y,-y},{x,-x}}]];Union@q)]<L@c,r++];R=2r+1;s="";Do[s=s<>({u,v}/.Thread[p~Take~L@c->c]/.{_,_}->" ")<>If[v==R,"\n",""],{u,R},{v,R}];s)&

Ungolfed:

(
  L = Length;
  T = Tuples;
  c = Characters@#;
  For[r = 1,
   L[
     p = RotateRight[
         SortBy[#, ArcTan @@ N@# &] + r + 1, L@#/4 + 1
         ] &@(
        f = 1 - r;
        X = 1;
        Y = -2 r;
        x = 0;
        y = r;
        q = {{0, r}, {0, -r}, {r, 0}, {-r, 0}};
        While[x < y,
         If[f > 0,
          y--;
          f += Y += 2
          ];
         x++;
         f += X += 2;
         q = Join[q, T@{{x, -x}, {y, -y}}, T@{{y, -y}, {x, -x}}]
         ];
        Union@q
        )] < L@c,
   r++];
  R = 2 r + 1;
  s = "";
  Do[s = s <> ({u, v} /. Thread[p ~ Take ~ L@c -> c] /. {_, _} -> " ") <>
      If[v == R, "\n", ""],
   {u, R}, {v, R}];
  s
  ) &

3

C, 367 ไบต์

#include<math.h>
main(){char*m="12345678",b[9999];int p,i,n,q,c,l=strlen(m),r=1,d,f=0;float o,s;for(;!f;r++){f=0;q=r*r;c=r/4;o=6.3,s=o/99.;memset(b,0,q);for(i=0;i<l;i++){p=1;f=0;while(p&&o>0){d=(c-1+(int)(sin(o)*c))*r+c-1+(int)(cos(o)*c);f+=p=b[d];if(!p)b[d]=m[i];o-=s;}}if(f){for(n=p=0;n<q;n++){p+=c=b[n];putchar(c?c:32);if(n%r==r-1){if(!p)n=q;putchar(10);p=0;}}}}}

ทดสอบที่นี่

ฉันแน่ใจว่ามันสามารถตีกอล์ฟได้ไกลกว่านี้ แต่มันเริ่มทำให้ฉันปวดหัว

C, 324 ไบต์

รหัสมีขนาดเล็กลง แต่ผลลัพธ์ไม่เหมือนกับของ OP

#include<math.h>
main(){char*m="12345678",b[9999];int q,c,l=strlen(m),r=1,d,i=0;float o;for(;i<l;r++){i=0;c=r/2;q=r*r;memset(b,0,q);for(o=6.28;o>=0&&i<l;o-=0.001){d=(c-1+(int)(sin(o)*c))*r+c-1+(int)(cos(o)*c);if(!b[d]){b[d]=m[i++];}}}for(d=i=0,--r;d<q;d++){i+=c=b[d];putchar(c?c:32);if(d%r==r-1){putchar(10);d=i?d:q;i=0;}}}

       an hsa ,k
      gz       ulu
    ig           ta
   bm             br
  ta               ud
 lu                  g
 ,                   z
a                    an
s
h                     h
                      s
n                     A
a
z
g                     l
 t                   tu
 h                   a
 ra                 mp
  ka               ri
   tu              k
    lu           hi
     k a       -is
       gh burzum

3
คุณสามารถวางvoid5 ไบต์และประกาศบางส่วนของจำนวนเต็มในขอบเขตทั่วโลกสำหรับไบต์บางมากขึ้นเนื่องจากตัวแปรในขอบเขตทั่วโลกโดยไม่ต้องพิมพ์มีการสันนิษฐานและจะเริ่มต้นโดยอัตโนมัติint 0
Mego

1
ดูเหมือนว่าคุณได้ทำการแก้ไขแบบไม่ระบุชื่อขณะที่ออกจากระบบ ฉันไปข้างหน้าและอนุมัติแล้ว แต่โดยทั่วไปคุณควรเข้าสู่ระบบเพื่อทำการแก้ไข ;)
อเล็กซ์ A.

1

C, 494 ไบต์

อันนี้ใช้อัลกอริธึมวงกลม Midpoint จริง:

void main(){char s[]="12345678";int a[9999],b[9999],f=0,c,h,x,y,e,q,t,u,v,g,i,d,l,r=0,k=strlen(s);for(;f<k;r++){c=r;e=r*2+1;q=e*e;memset(b,0,q*4);f=0;l=0;for(i=0;i<8;i++){x=r;y=0;d=1-x;for(x=r,y=0,d=1-x;y<=x;y++,d+=2*d>0?y- --x:y+1){t=(i+1)%4>1;u=t?y:x;v=t?x:y;h=(c+v*(i>3?1:-1))*e+(c+u*(i>1&&i<6?-1:1));if(!b[h])b[h]=f<k?s[f]:0,a[f]=h,f++;}if(i%2){for(g=0;g<(f-l)/2;g++)t=b[a[l+g]],b[a[l+g]]=b[a[f-1-g]],b[a[f-1-g]]=t;}l=f;}}for(i=0;i<q;i++){c=b[i];putchar(c?c:32);if(i%e==e-1)putchar(10);}}

รหัสยกเลิกการตีกอล์ฟ:

void main() {
    char text[]="Ash nazg durbatuluk, ash nazg gimbatul, ash nazg thrakatuluk agh burzum-ishi krimpatul.";

    char points[9999];
    int pos[9999];

    int sl = strlen(text);
    int r = 0;
    int pc = 0; // point count
    int lc = 0; // last count

    int c, h, x, y, e, q, t, u, v, g, i, d;

    // increase radius until number of points => strlen(text)
    for(; pc<sl; r++) {
        c = r;
        e = r * 2 + 1;
        q = e * e;
        memset(points,0,q);
        pc = 0;
        lc = 0;

        // loop through the octants
        for(i=0; i<8; i++) {

            // midpoint loop
            x = r;
            y = 0;
            d = 1 - x;
            while (y <= x) {

                // calc index of point
                t = (i + 1) % 4 > 1;
                u = t ? y : x;
                v = t ? x : y;
                h = (c + v * (i > 3 ? 1 : -1)) * e + (c + u * (i > 1 && i < 6 ? -1 : 1)); 

                // add point if space is empty
                if(!points[h]) { 
                    points[h] = pc < sl ? text[pc] : 0;
                    pos[pc] = h;
                    pc++;
                }

                y++;
                d += 2 * d > 0 ? y- --x : y + 1;
            }

            if(i % 2) {
                // reverse point order for odd octants
                for(g=0; g<(pc-lc)/2; g++)
                {
                    t = points[pos[lc + g]];
                    points[pos[lc + g]] = points[pos[pc - 1 - g]];
                    points[pos[pc - 1 - g]] = t;
                }
            }
            lc = pc;
        }
    }

    // write output
    for(i=0;i<q;i++)
    {
        c = points[i];
        putchar(c ? c : 32);
        if(i % e == e - 1)
            putchar(10);
    }
}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.