Spiral-Programmierung

14

Schreiben Sie eine benannte Funktion oder ein benanntes Programm, das eine einzelne Ganzzahl N akzeptiert und die ersten N Balken der darunter liegenden Spirale druckt (nach STDOUT) oder (als Zeichenfolge) zurückgibt, beginnend mit dem vertikalen Balken in der Mitte und im Uhrzeigersinn nach außen spiralförmig.

        _______________
       / _____________ \
      / / ___________ \ \
     / / / _________ \ \ \
    / / / / _______ \ \ \ \
   / / / / / _____ \ \ \ \ \
  / / / / / / ___ \ \ \ \ \ \
 / / / / / / / _ \ \ \ \ \ \ \
/ / / / / / / / \ \ \ \ \ \ \ \
| | | | | | | | | | | | | | | |
\ \ \ \ \ \ \___/ / / / / / / /
 \ \ \ \ \ \_____/ / / / / / /
  \ \ \ \ \_______/ / / / / /
   \ \ \ \_________/ / / / /
    \ \ \___________/ / / /
     \ \_____________/ / /
      \_______________/ /

Sie können davon ausgehen, dass 0 <N <= 278. Ihre Ausgabe darf kein Leerzeichen vor dem Zeichen ganz links der Spirale enthalten. Sie können optional eine einzelne nachgestellte Zeile drucken.

Bei einer Eingabe von 10 ist die korrekte Ausgabe

   _
  / \ 
  | | 
\___/

Bei einer Eingabe von 2 ist die korrekte Ausgabe

/
|

Bei einer Eingabe von 20 ist die korrekte Ausgabe

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

Eine Ausgabe, die falsch wäre, weil vor dem Zeichen ganz links ein Leerzeichen steht, ist

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

Der Gewinner ist die kürzeste Einsendung in Bytes.

Regenblitz
quelle
Dies ist eine seltsame Spirale, 6/8 Seiten werden mit jeder Umdrehung größer und 2 bleiben Größe 1
Devon Parsons
1
@ DevonParsons Denken Sie daran, es hat eine sechseckige Spirale, bei der die vertikalen Balken ( |) nur das nächstliegende Zeichen sind, das das Zusammentreffen von a /und darstellen kann \.
mbomb007

Antworten:

5

CJam - 156/147

L{[W1]{:I0'|{IIW*:J'/}X*[0J'_]X2*I+*[J0_]I1={\}*{J_'\}X*0I0}%L*3/{~_{[UV@]a3$+}{;@}?V@+:V;U@+:U;}/}A,1>fX]ri=_z::e<2<f{[\\]z::-}$_W=0=)S50*a*\{~3$3$=\tt}/N*

Probieren Sie es online aus

Es funktioniert mit Eingaben von 1 bis einschließlich 378 (100 mehr als erforderlich)

Mit dem neuesten festgeschriebenen (öffentlich in hg verfügbaren), aber unveröffentlichten CJam-Code zum Zeitpunkt der Veröffentlichung dieser Herausforderung kann die Lösung auf 147 Zeichen verkürzt werden:

L{[W1]{:I0'|{IIW*:J'/}X*[0J'_]X2*I+*[J0_]I1={\}*{J_'\}X*0I0}%L*3/{~_{[UV@]a3$+}{;@}?V@+:V;U@+:U;}/}A,1>fX]ri=_:.e<2<f.-$_W=0=)S50*a*\{~3$3$=\tt}/N*

Erläuterung:

Das Programm konstruiert iterativ alle Spiralen als Arrays von [xy-Zeichen] beginnend mit [0 0 '|], erhält die angeforderte Spirale, passt die Koordinaten so an, dass das Minimum von x und y 0 ist, und erstellt eine Matrix von Leerzeichen (mit der korrekten Anzahl von Zeilen und 50 Spalten) ) setzt dann die Zeichen aus der Spirale und verbindet die Zeilen mit Zeilenumbrüchen.

L                   start with an empty array (spiral no. 0)
{…}A,1>fX           for X in 1..9 (A=10)
                    each X represents a full 360° tour with groups of X /'es and \'es
    [W1]{…}%        transform the array [-1 1] (W=-1) applying the block to each item
                    the block generates a series of triplets dx, dy, character
                    note: dx is down, dy is right; -1 handles ↑↗→↘, 1 handles ↓↙←↖
        :I          store the current item in I
        0'|         add 0 and |, which will form a triplet with the previous I
        {…}X*       repeat X times
            IIW*    add I and -I
            :J'/    also store -I in J, and add /
        [0J'_]      make an array [0 J _]
        X2*I+*      repeat the array X*2+I times
        [J0_]       make an array [J 0 0]
                    (a 0 instead of a character means only changing the position)
        I1={\}*     if I=1, swap the two arrays (the position adjustment is different
                    for the upper and lower horizontal sections)
        {…}X*       repeat X times
            J_'\    add J, J and \
        0I0         add 0, I and 0 (another position adjustment)
    L*              flatten the array (since we added a few inner arrays)
    3/              split into [dx dy char] triplets
    {…}/            for each triplet
        ~_          dump the 3 items on the stack and duplicate the character
        {…}         if the character is not 0
            [UV@]   make an array [U V char] (U and V are initially 0)
                    U represents "x" and V represents "y"
            a3$+    add it as an element to a copy of the previous spiral
        {…}         else
            ;@      pop the character and bring the previous spiral to the top
        ?           end if
        V@+:V;      V+=dy
        U@+:U;      U+=dx
]                   put all the spirals in an array
ri=                 read token, convert to integer and get that spiral
_z::e<              copy the spiral and get a triplet with the minimum values
2<                  keep only the first 2 items (xmin and ymin)
f{…}                for each triplet and the array [xmin ymin]
    [\\]z::-        subtract xmin and ymin from x and y in the triplet
                    (in the latest CJam code this is simply ".-")
$                   sort the spiral (putting the triplets in order by x then y)
_W=0=)              get the maximum (updated) x and increment it
S50*                make a string of 50 spaces
a*                  put it in an array and repeat it xmax+1 times
                    this is the initial matrix of spaces
\                   swap with the spiral
{…}/                for each triplet in the spiral
    ~               dump the 3 items (x y char) on the stack
    3$3$=           copy the matrix and x, and get the x'th row
    \t              swap with the character and put that character in the y'th position
    t               put the modified row in the x'th position in the matrix
N*                  join the matrix rows with newlines
aditsu
quelle
8

Python 2, 290 289

Es ist wahrscheinlich wirklich schlimm, aber ich habe versucht: D

Die Ausgabe enthält nachgestellte Leerzeichen, was in der Spezifikation jedoch nicht verboten ist.

Update: 1 Byte beim Wechsel \nzu gespeichert ;.

m=x=y=c=0
l,f=1,[31*[' ']for t in[0]*31]
for i in[0]*input():
 k=m%4;f[14+y+(2<m<6)][14+x-(m>3)],x,y,c='|/_\\'[k],x+(k>0)*(2*(4>m)-1),y+(k!=2)*(2*(2<m<6)-1),c+1
 if(c==l)*(m%2)+(k==0)+(k==2)*(c==2*l-1+m//3):m,c,l=(m+1)%8,0,l+m//7
print'\n'.join(''.join(e[16-l*2:])for e in f if[' ']*31!=e)
PurkkaKoodari
quelle
Leerzeichen sind in Ordnung. Ich habe das getestet. Gut gemacht!
Rainbolt
4

JavaScript (ES6) 257 288 321

Bearbeitungsschritte zusammengeführt.
Bearbeiten Sie das Fummeln mit Golf-Code, um mehr Saibling zu schneiden

Bauen Sie die Ausgabe iterativ in das r-Array ein und verfolgen Sie dabei die aktuelle x- und y-Position sowie die aktuelle Richtung. Wenn die x- oder y-Position <0 ist, wird das gesamte r-Array neu angepasst.

Hauptvariablen:

  • r Ergebnisfeld oder Zeilen
  • x, y aktuelle Position.
  • s aktuelle Richtung (0..7) (oder aktueller Zustand)
  • d aktuelles zu zeichnendes Symbol (0..3) -> '| \ _ /'
  • l Laufposition auf der aktuellen Sequenz (runter auf 0)
  • w aktueller Spiralradius (mehr oder weniger)
F=n=>
  (w=>{
    for(r=b=[],s=y=x=d=0;n--;
      d&&--l||((s=s+1&7,d=s&3)?l=d-2?w:s/2-2+w+w:w+=!s))
      s>0&s<4?++x:s>4?x?--x:r=r.map(v=>' '+v):b+='  ',
      q=r[s>2&s<6?++y:y]||b,
      r[y]=(q+b).slice(0,x)+'|/_\\'[d]+q.slice(x+1),
      s<2|s>6?y?--y:r=[,...r]:x+=!d*2,x-=!d
  })(1)||r.join('\n')

Ungolfed

F=n=>{
  var r=[], s,x,y,d,w,l, q
  for(l=w=1, s=x=y=d=0; n--;)
  {
    if (s>2 && s<6) ++y; // right side, inc y before drawing

    if (x < 0) // too left, adjust
    {
      r = r.map(v=>' '+v) // shift all to right
      ++x; // move current position to right
    }
    if (y < 0) // too up
    {
      r = [q='',...r] // shift all to bottom
      ++y; // move current position to bottom
    }
    q = r[y] || ''; // current row, if undefined convert to empty string
    r[y] = (q+' '.repeat(x)).slice(0,x) + '|/_\\'[d] + q.slice(x+1); // add current symbol in the x column

    if (s<2 || s>6) --y; // left side, dec y after drawing

    if (s>0 && s<4) // always change x after drawing
      ++x;
    else if (s > 4)
      --x;

    --l; // decrement current run
    if (l == 0) // if 0, need to change direction
    {
      s = (s+1) % 8; // change direction
      d = s % 4; // change symbol
      if (d == 0)
      { 
        // vertical direction, adjust x and if at 0 increase radius
        l = 1 // always 1 vertical step
        if (s == 0)
          ++x, ++w
        else
          --x
      }
      else
      {
        if (d != 2)
        {
          l = w; // diaagonal length is always w
        }
        else if (s == 2)
        {
          l = w+w-1 // top is radius * 2 -1
        }
        else
        {
          l = w+w+1 // bottom is radius * 2 +1
        }
      }
    }
  }    
  return r.join('\n')
}  

Test In der Firefox / FireBug-Konsole (oder JSFiddle thx @Rainbolt)

;[1, 2, 10, 20, 155, 278].forEach(x=>console.log(F(x)))

Ausgabe

|

/
|

   _
  / \
  | |
\___/

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

      ___________
     / _________ \
    / / _______ \ \
   / / / _____ \ \ \
  / / / / ___ \ \ \ \
 / / / / / _ \ \ \ \ \
/ / / / / / \ \ \ \ \ \
| | | | | | | | | | | |
\ \ \ \ \___/ / / / /
 \ \ \ \_____/ / / /
  \ \ \_______/ / /
   \ \_________/ /
    \___________/

        _______________
       / _____________ \
      / / ___________ \ \
     / / / _________ \ \ \
    / / / / _______ \ \ \ \
   / / / / / _____ \ \ \ \ \
  / / / / / / ___ \ \ \ \ \ \
 / / / / / / / _ \ \ \ \ \ \ \
/ / / / / / / / \ \ \ \ \ \ \ \
| | | | | | | | | | | | | | | |
\ \ \ \ \ \ \___/ / / / / / / /
 \ \ \ \ \ \_____/ / / / / / /
  \ \ \ \ \_______/ / / / / /
   \ \ \ \_________/ / / / /
    \ \ \___________/ / / /
     \ \_____________/ / /
      \_______________/ /
edc65
quelle
Ich habe das getestet und es funktioniert. Hier ist eine jsfiddle , die zeigt, dass Ihre Antwort funktioniert. Fühlen Sie sich frei, es in Ihre Antwort zu integrieren.
Rainbolt
2

Pyth, 166 165

Ich habe gerade meine Python-Antwort auf Pyth übersetzt, mit meinen nicht großartigen Pyth-Fähigkeiten. Das entstehende Erbrochene ist unten.

Jm*31]d*31dK0=G0=H0=Y1VQ X@J++14H&<2K<K6+14-G<3K@"|/_\\"%K4~G*<0%K4-*2>4K1~H*n2%K4-*2&<2K>6K1~Z1I||&qZY%K2!%K4&q2%K4qZ+-*2Y1/K3~Y/K7=K%+1K8=Z0;jbmj>d-16*2Ykfn*31]dTJ
PurkkaKoodari
quelle