Snakify a String

35

Snakified string wygląda następująco:

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

Twoje zadanie

Weź ciąg si rozmiar n, a następnie wyślij zrywany ciąg. Dane wejściowe ThisIsAnExampleOfaSnakifiedStringi 3dałby powyższy przykład.

Dane techniczne

  • s będzie zawierać tylko znaki ASCII między punktami kodowymi 33 i 126 włącznie (bez spacji i znaków nowej linii).
  • s będzie mieć od 1 do 100 znaków.
  • njest liczbą całkowitą reprezentującą rozmiar każdego segmentu ciągu wyjściowego. Każda linia znaków (góra / dół lub lewo / prawo), które tworzą krzywe w „wężu”, ma ndługość znaków. Zobacz przykłady testowe.
  • n będzie między 3 a 10 włącznie.
  • Łańcuch wyjściowy zawsze zaczyna być skierowany w dół.
  • Końcowe spacje w każdej linii są dozwolone.
  • Dozwolone są również końcowe znaki nowej linii na końcu wyniku.
  • Wiodące spacje są niedozwolone.
  • oznacza, że ​​wygrywa najkrótszy kod w bajtach.

Przypadki testowe

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{
użytkownik 81655
źródło
Domyślam się, że następnym wyzwaniem będzie konwersja zrywanego łańcucha z powrotem do oryginalnych 2 parametrów ...
powyżej
@abligh Nie miałem dalszych planów, ale tak naprawdę to brzmi jak porządny pomysł. Może być jednak jakaś forma duplikatu, więc najpierw muszę to sprawdzić. Bądźcie czujni!
user81655 7.04.16
odwrotne wyzwanie byłoby bardziej zabawne, gdyby wąż mógł mieć dowolny kształt ...
powyżej
@abligh Właśnie to planowałem robić haha!
user81655 7.04.16
@abligh Gotowe!
user81655,

Odpowiedzi:

9

Pyth, 48 45 44 43 42 bajtów

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

Wypróbuj online.

Podejście to robi to samo nadużywanie białych znaków jako odpowiedź Ruby.

PurkkaKoodari
źródło
3
Przekreślone 44 to wciąż 44 ... wciąż.
Arcturus,
12

Rubinowy, 87 bajtów

->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}

Niewielkie nadużycie reguły Trailing spaces on each line are allowed.Każda linia wyjściowa ma wdługość znaków plus nowy wiersz, gdzie wjest długością oryginalnego łańcucha, tj. Wystarczająco długa, aby pomieścić całe wejście. Stąd jest dość niepotrzebnych białych znaków po prawej stronie dla dużych n.

Niegolfowany w programie testowym

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]
Level River St
źródło
7

JavaScript (ES6), 143 bajty

(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`

Gdzie \nreprezentuje dosłowną nową linię. Nie golfowany:

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");
}
Neil
źródło
7

Pyth, 85 74 59 bajtów

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

Dzięki @FryAmTheEggman za ogromną pomoc!

Grałem w golfa jak najwięcej. Wypróbuj tutaj! Z jakiegoś powodu zawijanie linii powoduje, że dane wyjściowe są dziwne. Możesz rzucić okiem na wynik na całej stronie

Wyjaśnienie

Oddychaj chwilę i skup się. Można to podzielić na trzy sekcje, jak prawie każdy „klasyczny” algorytm.

Pierwsza sekcja

To tutaj inicjowane są zmienne. Można go podzielić na dwie części:

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)

druga część :

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.

Druga sekcja

Zawiera rzeczywistą 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

Trzecia sekcja

To jest część wyjściowa. Niezbyt interesujące ...

sY    Join the array Y. Implicitly print.

PREMIA

Napisałem program pyth z tego skryptu python.

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);
FliiFe
źródło
5

JavaScript (ES6), 122 bajty

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))

Ten sam algorytm jak odpowiedź @ LevelRiverSt.

użytkownik 81655
źródło
4

C, 138 bajtów

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]);}

Używa ucieczek ANSI. Działa w terminalu Linux.

Nie golfowany:

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]);
}
Mllllbyte
źródło
1

JavaScript (ES6), 131

Algorytm: mapowanie pozycji x,ywyjściowej na indeks w ciągu wejściowym, w pewien sposób taka odpowiedź (niepowiązana).

Pożyczałem od @LevelRiverSt, aby utrzymać szerokość poziomą równą długości wejściowej.

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)]||`.`')

Mniej golfa

To był pierwszy działający projekt przed golfem

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
}  

Test

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>

edc65
źródło
0

Pyth, 122 bajty

=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

Stworzyłem formułę do obliczania pozycji x, y każdego znaku na podstawie wielkości segmentu / modulo, ale stały się one większe niż się spodziewałem: c

Wyjaśnienie:

=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

Przetestuj tutaj

W przypadku formuł matematycznych użyłem mod do wygenerowania flag 0/1, a następnie pomnożonego przez współczynnik oparty na danych wejściowych n, dodałem arkusz kalkulacyjny do każdego kroku na poniższym fragmencie kodu

Pręt
źródło
Czy potrafisz wyjaśnić Matemagics? tj. napisać je w sposób bardziej ludzki?
FliiFe,
@FliiFe zrobione c:
Rod
0

PHP, 127 126 124 120 119 118 117 110 106 bajtów

Wykorzystuje kodowanie ISO-8859-1.

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

Działaj w ten sposób ( -ddodano tylko dla estetyki):

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

Nie golfowany:

// 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);

Poprawki

  • Zapisano bajt za pomocą <zamiast!=
  • Zaoszczędziłem 2 bajty, ustawiając na początku ciąg znaków 0, więc nie muszę dodawać kolejnego 0(w przypadku, gdy pierwszym wyjściem w linii było a 0), co daje prawdę 00.
  • Zapisano 4 bajty przy użyciu odwołania zamiast powtarzania $o[$y]
  • Zapisano bajt za pomocą modulo zamiast ==do porównywania kierunku z 1 w celu zmiany współrzędnej x
  • Zapisano bajt, usuwając rzut typu nullna intdla przesunięcia łańcucha, ponieważ przesunięcie łańcucha jest rzutowane na int
  • Zapisano bajt za pomocą tagu krótkiego wydruku
  • Zaoszczędzono 7 bajtów, poprawiając logikę kierunku
  • Zaoszczędzono 4 bajty, bezpośrednio przypisując znak, aby zapobiec pośredniemu $c
aross
źródło