Snakify eine Zeichenfolge


35

Eine verkürzte Zeichenfolge sieht folgendermaßen aus:

T AnE eOf ifi ing
h s x l A k e r
isI amp Sna dSt

Deine Aufgabe

Nehmen Sie eine Zeichenfolge sund eine Größe n, und geben Sie dann die verschlüsselte Zeichenfolge aus. Die Eingaben ThisIsAnExampleOfaSnakifiedStringund 3würden das obige Beispiel ergeben.

Spezifikationen

  • s Enthält nur ASCII-Zeichen zwischen den Codepunkten 33 und 126 (keine Leerzeichen oder Zeilenumbrüche).
  • s wird zwischen 1 und 100 Zeichen lang sein.
  • nist eine Ganzzahl, die die Größe jedes Ausgangsstringsegments darstellt. Jede Zeichenzeile (hoch / runter oder links / rechts), aus der die Kurven in der "Schlange" bestehen, ist nZeichen lang. Beispiele finden Sie in den Testfällen.
  • n wird zwischen 3 und 10 inklusive sein.
  • Die Ausgabezeichenfolge beginnt immer nach unten zu zeigen.
  • Nachgestellte Leerzeichen in jeder Zeile sind zulässig.
  • Das Nachziehen von Zeilenumbrüchen am Ende der Ausgabe ist ebenfalls zulässig.
  • Führende Leerzeichen sind nicht erlaubt.
  • bedeutet kürzester Code in Bytes gewinnt.

Testfälle

a 3

a

----------

Hello,World! 3

H Wor
e , l
llo d!

----------

ProgrammingPuzzlesAndCodeGolf 4

P  ngPu  Code
r  i  z  d  G
o  m  z  n  o
gram  lesA  lf

----------

IHopeYourProgramWorksForInputStringsWhichAre100CharactersLongBecauseThisTestCaseWillFailIfItDoesNot. 5

I   gramW   tStri   100Ch   gBeca   CaseW   DoesN
H   o   o   u   n   e   a   n   u   t   i   t   o
o   r   r   p   g   r   r   o   s   s   l   I   t
p   P   k   n   s   A   a   L   e   e   l   f   .
eYour   sForI   Which   cters   ThisT   FailI

----------

!"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~ 10

!        <=>?@ABCDE        `abcdefghi
"        ;        F        _        j
#        :        G        ^        k
$        9        H        ]        l
%        8        I        \        m
&        7        J        [        n
'        6        K        Z        o        ~
(        5        L        Y        p        }
)        4        M        X        q        |
*+,-./0123        NOPQRSTUVW        rstuvwxyz{

Ich vermute, dass die nächste Herausforderung darin besteht, eine verkürzte Zeichenfolge wieder in die ursprünglichen 2 Parameter
umzuwandeln

@abligh Ich hatte keine weiteren Pläne, aber das klingt eigentlich nach einer anständigen Idee. Es könnte jedoch eine Form von Duplikaten geben, also muss ich das zuerst überprüfen. Bleib dran!
User81655

Die umgekehrte Herausforderung würde mehr Spaß machen, wenn die Schlange eine beliebige Form haben kann ...
abligh

@abligh Genau das hatte ich mir vorgenommen, haha!
User81655

Antworten:


9

Pyth, 48 45 44 43 42 Bytes

=Y0juXGZX@G~+Z-!J%/HtQ4q2J~+Y%J2@zHlzm*;lz

Probieren Sie es online aus.

Bei diesem Ansatz wird derselbe nachgestellte Whitespace-Missbrauch wie bei der Ruby-Antwort ausgeführt.


3
Durchgestrichen 44 ist immer noch 44 ... immer noch.
Arcturus

12

Rubin, 87 Bytes

->s,n{p=0
a=(' '*(w=s.size)+$/)*n
w.times{|i|a[p]=s[i];p+=[w+1,1,-w-1,1][i/(n-1)%4]}
a}

Einige geringfügige Verstöße gegen die Regel Trailing spaces on each line are allowed.Jede Ausgabezeile besteht aus wZeichen und einer neuen Zeile, wobei wdie Länge der ursprünglichen Zeichenfolge ausreicht, um die gesamte Eingabe zu speichern . Daher gibt es ziemlich viele unnötige Leerzeichen rechts für groß n.

Ungolfed im Testprogramm

f=->s,n{
  p=0                            #pointer to where the next character must be plotted to
  a=(' '*(w=s.size)+$/)*n        #w=length of input. make a string of n lines of w spaces, newline terminated
  w.times{|i|                    #for each character in the input (index i)
    a[p]=s[i]                    #copy the character to the position of the pointer
    p+=[w+1,1,-w-1,1][i/(n-1)%4] #move down,right,up,right and repeat. change direction every n-1 characters
  }
a}                               #return a

puts $/,f['a',3]

puts $/,f['Hello,World!',3]

puts $/,f['ProgrammingPuzzlesAndCodeGolf',4]

puts $/,f['IHopeYourProgramWorksForInputStringsWhichAre100CharactersLongBecauseThisTestCaseWillFailIfItDoesNot.',5]

puts $/,f['!"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~',10]

7

JavaScript (ES6), 143 Byte

(s,n)=>[...s].map((c,i)=>(a[x][y]=c,i/=n)&1?y++:i&2?x--:x++,a=[...Array(n--)].map(_=>[]),x=y=0)&&a.map(b=>[...b].map(c=>c||' ').join``).join`\n`

Wobei \neine wörtliche Newline darstellt. Ungolfed:

function snakify(string, width) {
    var i;
    var result = new Array(width);
    for (i = 0; i < width; i++) result[i] = [];
    var x = 0;
    var y = 0;
    for (i = 0; i < string.length; i++) {
       result[x][y] = string[i];
       switch (i / (width - 1) & 3) {
       case 0: x++; break;
       case 1: y++; break;
       case 2: x--; break;
       case 3: y++; break;
    }
    for (i = 0; i < width; i++) {
        for (j = 0; j < r[i].length; j++) {
            if (!r[i][j]) r[i][j] = " ";
        }
        r[i] = r[i].join("");
    }
    return r.join("\n");
}

7

Pyth, 85 74 59 Bytes

Kl@Q0J0=Y*]d-+*@Q1K@Q1 1FNr1@Q1=XY-+*KNN1b;VK=XYJ@@Q0N=+J@[+K1 1-_K1 1).&3/N-@Q1 1;sY

=G@Q1=H@Q0KlHJ0=Y*]dt+*GKGFNr1G=XYt+*KNNb;VK=XYJ@HN=+J@[hK1t_K1).&3/NtG;sY

Klz=Ym;+*QKQVQ=XYt+*KhNhNb;VK=XYZ@zN=+Z@[hK1_hK1).&3/NtQ;sY

Vielen Dank an @FryAmTheEggman, der mir sehr geholfen hat!

Ich habe so viel Golf gespielt, wie ich konnte. Probieren Sie es hier aus! Aus irgendeinem Grund machen Zeilenumbrüche die Ausgabe seltsam. Vielleicht möchten Sie einen Blick auf die Ausgabe auf der ganzen Seite werfen

Erläuterung

Atme eine Sekunde und konzentriere dich. Dies kann wie bei fast jedem "klassischen" Algorithmus in drei Abschnitte unterteilt werden.

Der erste Abschnitt

Hier werden Variablen initialisiert. Es kann in zwei Teile geteilt werden:

Klz=Ym;+*QKQ
Klz                Assign len(input[0]) to K. (length of input String)
   =Ym;+*QKQ       Assign an empty list to Y of length K*input[1]-input[1]-1, where input[1] is the size of the snake 
                   (thus the height of the final string)

der zweite Teil :

VQ=XYt+*KhNhNb;
VQ                       For N in range(0, input[1]), where input[1] is the size of the snake 
  =                        Assign to Y. Y is implicit, it is the last variable we used.
   XYt+*KhNhNb               Y[K*N+N-1]="\n". Can be broken down in four parts :
   X                           Replace function. X <A: list> <B: int> <C: any> is A[B]=C
    Y                          A: The array we initialized in the first section.
     t+*KhNhN                  B: K*(N+1)+N+1 (N is the for loop variable)
             b                 C: Newline character ("\n")
              ;          End the loop.

Der zweite Abschnitt

Es enthält die eigentliche Logik.

VK=XYZ@zN=+Z@[hK1_hK1).&3/NtQ;
VK                                         For N in range(0, K), where K is the length of the input string (see first section)
  =                                          Assign to Y. Y is implicit, it is the last variable we used.
   XYZ@zN                                    Same as in section 2. This is a replacement function. Y[Z] = input[0][N]. Z is initially 0.
         =+Z@[hK1_hK1).&3/NtQ                Again this can be broken down :
         =+Z                                   Add to Z
             [hK1_hK1)                         Array containing directions. Respectively [K+1, 1, -K-1, 1]
            @         .&3/NtQ                  Lookup in the array, on index .&3/N-@Q1 1:
                      .&3                        Bitwise AND. .& <int> <int>
                         /NtQ                    (input[1]-1)/N, where input[1] is the size of the snake
                             ;             End the loop

Der dritte Abschnitt

Dies ist der Ausgabeteil. Nicht wirklich interessant ...

sY    Join the array Y. Implicitly print.

BONUS

Ich habe das Pyth-Programm aus diesem Python-Skript geschrieben.

input=["ThisIsAnExampleOfASnakifiedString", 4];
width=len(input[0]);
height=input[1];
pointer=0;
directions = [width+1,1,-width-1,1] #Respectively Down, right, up, right (left is replaced by right because of snake's nature. Doesn't go left).
output=[' ' for i in range(0, width*height+height-1)];
for N in range(1, height):
    output[width*N+N-1]="\n";
for N in range(0, len(input[0])):  
    output[pointer]=input[0][N];
    pointer+=directions[3&(N/(height-1))];
print "".join(output);

5

JavaScript (ES6), 122 Byte

document.write("<pre>"+(

// --- Solution ---
s=>n=>[...s].map((c,i)=>(a[p]=c,p+=[l+1,1,-l-1,1][i/n%4|0]),p=0,a=[...(" ".repeat(l=s.length)+`
`).repeat(n--)])&&a.join``
// ----------------

)("IHopeYourProgramWorksForInputStringsWhichAre100CharactersLongBecauseThisTestCaseWillFailIfItDoesNot.")(5))

Gleicher Algorithmus wie die Antwort von @ LevelRiverSt.


4

C 138 Bytes

char*h[]={"\e[B\e[D","","\e[A\e[D",""},t[999];i;main(n){system("clear");for(scanf("%s%d",t,&n),--n;t[i];++i)printf("%c%s",t[i],h[i/n%4]);}

Dies verwendet ANSI-Escapezeichen. Funktioniert im Linux-Terminal.

Ungolfed:

char*h[]={"\e[B\e[D","","\e[A\e[D",""},
    /* cursor movement - h[0] moves the cursor one down and one left,
    h[2] moves the cursor one up and one left. */
t[999];i;
main(n){
    system("clear");
    for(scanf("%s%d",t,&n),--n;t[i];++i)
        printf("%c%s",t[i],h[i/n%4]);
}

1

JavaScript (ES6), 131

Algorithmus: Abbildung der Position x,yin der Ausgabe auf den Index in der Eingabezeichenfolge, in etwa wie diese (nicht verwandte) Antwort.

Ich habe mir von @LevelRiverSt den Trick geliehen, die horizontale Breite gleich der Eingabelänge zu halten.

a=>m=>eval('for(--m,t=y=``;y<=m;++y,t+=`\n`)for(x=0;a[x];)t+=a[2*(x-x%m)+((h=x++%(2*m))?h-m?!y&h>m?h:y<m|h>m?NaN:m+h:m-y:y)]||`.`')

Weniger golfen

Dies war der erste Arbeitsentwurf vor dem Golfen

f=(a,n)=>{
  l=a.length
  m=n-1
  s=m*2 // horizontal period

  b=-~(~-l/s)*m // total horizontal len, useless in golfed version
  t=''
  for(y=0;y<n;y++)
  {
    for(x=0;x<b;x++)
    {
      k = x / m | 0
      h = x % s
      if (h ==0 )
        c=k*s+y
      else if (h == m)
        c=k*s+m-y
      else if (y == 0 && h>m)
        c=k*s+h
      else if (y == m && h<m)
        c=k*s+m+h
      else
        c=-1
      t+=a[c]||' '
    }
    t+='\n'
  }
  return t
}  

Prüfung

F=a=>m=>eval('for(--m,t=y=``;y<=m;++y,t+=`\n`)for(x=0;a[x];)t+=a[2*(x-x%m)+((h=x++%(2*m))?h-m?!y&h>m?h:y<m|h>m?NaN:m+h:m-y:y)]||` `')

function test()
{
  var n=+N.value
  var s=S.value
  O.textContent=F(s)(n)
}  

test()
#S {width:80%}
#N {width:5%}
<input id=N value=5 type=number oninput='test()'>
<input id=S 5 oninput='test()'
value='IHopeYourProgramWorksForInputStringsWhichAre100CharactersLongBecauseThisTestCaseWillFailIfItDoesNot.'>
<pre id=O></pre>


0

Pyth, 122 Bytes

=k@Q0J-@Q1 1K*4J=T*@Q1[*lkd;Vlk=Z+*%NJ/%N*J2J*/N*J2J=Y.a-+**/%N*J2J!/%NK*J2J*%NJ!/%N*J2J**!/%N*J2J/%NK*J2J XTYX@TYZ@kN;jbT

Ich habe eine Formel erstellt, um die x, y-Positionen jedes Zeichens basierend auf der Segmentgröße / dem Modulo zu berechnen, aber sie wurden größer als erwartet: c

Erläuterung:

=k@Q0                                                                                                                     # Initialize var with the text
     J-@Q1 1                                                                                                              # Initialize var with the segment size (minus 1)
            K*4J                                                                                                          # Initialize var with the "block" size (where the pattern start to repeat)
                =T*@Q1[*lkd;                                                                                              # Initialize output var with an empty array of strings
                            Vlk                                                                                           # Interate over the text
                               =Z+*%NJ/%N*J2J*/N*J2J                                                                      # Matemagics to calculate X position
                                                    =Y.a-+**/%N*J2J!/%NK*J2J*%NJ!/%N*J2J**!/%N*J2J/%NK*J2J                # Matemagics to calculate Y position
                                                                                                          XTYX@TYZ@kN;    # Assign the letter being iterated at x,y in the output
                                                                                                                      jbT # Join with newlines and print the output

Hier testen

Für die mathematischen Formeln habe ich mod verwendet, um 0/1-Flags zu generieren, und dann mit einem Faktor multipliziert, der auf der Eingabe basiert n, und die Tabelle mit jedem Schritt auf dem Textausschnitt hinzugefügt


Können Sie die Matemagics erklären? dh eher menschlich schreiben?
FliiFe

@FliiFe done c:
Rod

0

PHP, 127 126 124 120 119 118 117 110 106 Bytes

Verwendet die ISO-8859-1-Codierung.

for(;($q=&$o[$y+=$d]||$q=~ÿ)&&~Ï^$q[$x+=!$d]=$argv[1][$a];$a++%($argv[2]-1)?:$d-=-!$y?:1)?><?=join(~õ,$o);

Laufen Sie wie folgt ( -dnur aus ästhetischen Gründen hinzugefügt):

php -r 'for(;($q=&$o[$y+=$d]||$q=~ÿ)&&~Ï^$q[$x+=!$d]=$argv[1][$a];$a++%($argv[2]-1)?:$d-=-!$y?:1)?><?=join(~õ,$o);' "Hello W0rld!" 3 2>/dev/null;echo

Ungolfed:

// Iterate over ...
for (
    ;
    // ... the characters of the input string. Prepend `0` so a 0 in the input
    // becomes truthy.
    0 . $char = $argv[1][$a];

    // Use modulo to determine the end of a stretch (where direction is
    // changed).
    // Change direction (`0` is right, `-1` is up and `1` is down). When
    // y coordinate is `0`, increment the direction, else decrement.
    $a++ % ($argv[2] - 1) ?: $direction += $y ? -1 : 1
)

    (
        // Increase or decrease y coordinate for direction -1 or 1 respectively.
        // Check whether the array index at new y coordinate is already set.
        $reference =& $output[$y += $direction] ||
        // If not, create it as a string (otherwise would be array of chars).
        // Null byte, won't be printed to prevent leading char.
        $reference = ~ÿ;

        // Increment x coordinate for direction 0. Set the output char at the
        // current coordinates to the char of the current iteration.
    ) & $reference[$x += !$direction] = $char;

// Output all lines, separated by a newline.
echo join(~õ, $output);

Optimierungen

  • Mit <anstelle von ein Byte gespeichert!=
  • Es wurden 2 Bytes gespart, indem die Zeichenfolge 0zuerst auf gesetzt wurde, sodass ich keine weitere voranstellen muss 0(falls die erste Ausgabe in einer Zeile a war 0), was die Wahrheit ergibt 00.
  • 4 Bytes durch Verwendung eines Verweises gespeichert, anstatt ihn zu wiederholen $o[$y]
  • Ein Byte wurde gespeichert, indem modulo verwendet wurde, anstatt ==die Richtung mit 1 zu vergleichen, um die x-Koordinate zu ändern
  • Gespeichert ein Byte durch Typumwandlung zu entfernen , nullum intfür String - Offset, als String versetzt ist sowieso int gegossen
  • Ein Byte wurde mit einem kurzen Drucktag gespeichert
  • 7 Bytes gespart durch Verbesserung der Richtungslogik
  • 4 Bytes gespart durch direkte Zuweisung des Zeichens, um Zwischenschritte zu vermeiden $c
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.