Snakify a String


35

Senar berliku-liku terlihat seperti ini:

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

Tugas Anda

Ambil string sdan ukuran n, lalu keluarkan string snakified. Masukan ThisIsAnExampleOfaSnakifiedStringdan 3akan menghasilkan contoh di atas.

Spesifikasi

  • s hanya akan berisi karakter ASCII antara titik kode 33 dan 126 inklusif (tanpa spasi atau baris baru).
  • s panjangnya antara 1 dan 100 karakter.
  • nadalah bilangan bulat yang mewakili ukuran setiap segmen string output. Setiap baris karakter (atas / bawah atau kiri / kanan) yang membentuk kurva dalam "ular" npanjangnya karakter. Lihat contoh uji untuk contoh.
  • n akan antara 3 dan 10 inklusif.
  • String output selalu mulai mengarah ke bawah.
  • Ruang tambahan di setiap baris diperbolehkan.
  • Mengejar baris baru di akhir output juga diperbolehkan.
  • Ruang terkemuka tidak diizinkan.
  • berarti kode terpendek dalam byte yang menang.

Uji Kasus

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{

Saya menduga tantangan selanjutnya adalah mengubah string snakified kembali ke 2 parameter asli ...
abligh

@abligh Saya tidak punya rencana lebih lanjut, tapi itu sebenarnya terdengar seperti ide yang baik. Mungkin ada beberapa bentuk duplikat, jadi saya harus memeriksanya terlebih dahulu. Tetap disini!
user81655

tantangan sebaliknya akan lebih menyenangkan jika ular bisa menjadi bentuk yang sewenang-wenang ...
abligh

@abligh Itulah yang saya rencanakan untuk dilakukan haha!
user81655

@abligh Done!
user81655

Jawaban:


9

Pyth, 48 45 44 43 42 byte

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

Cobalah online.

Pendekatan ini melakukan trailing spasi penyalahgunaan yang sama dengan jawaban Ruby.


3
Dicoret 44 masih 44 ... masih.
Arcturus

12

Ruby, 87 byte

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

Beberapa penyalahgunaan kecil dari aturan Trailing spaces on each line are allowed.Setiap baris output wpanjang karakter, ditambah baris baru, di mana wpanjang string asli, yaitu cukup lama untuk menampung seluruh input. Oleh karena itu ada banyak ruang putih yang tidak perlu ke kanan untuk ukuran besar n.

Tidak digabungkan dalam program uji

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`

Di mana \nmerupakan baris baru literal. Tidak Disatukan:

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 byte

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

Terima kasih kepada @FryAmTheEggman yang telah banyak membantu saya!

Golf sebanyak yang saya bisa. Coba di sini! Untuk beberapa alasan, garis pembungkus membuat output aneh. Anda mungkin ingin melihat output pada halaman penuh

Penjelasan

Tarik napas sebentar, dan fokus. Ini dapat dipecah menjadi tiga bagian, seperti hampir semua algoritma "klasik".

Bagian pertama

Di sinilah variabel diinisialisasi. Itu dapat dibagi menjadi dua bagian:

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)

bagian kedua :

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.

Bagian kedua

Ini berisi logika aktual.

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

Bagian ketiga

Ini adalah bagian output. Tidak terlalu menarik ...

sY    Join the array Y. Implicitly print.

BONUS

Saya menulis program pyth dari skrip python ini.

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

Algoritma yang sama dengan jawaban @ LevelRiverSt.


4

C, 138 byte

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

Ini menggunakan pelarian ANSI. Bekerja di terminal linux.

Tidak Disatukan:

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

Algoritma: memetakan posisi x,ydalam output ke indeks dalam string input, entah bagaimana jawaban ini (tidak terkait).

Saya meminjam dari @LevelRiverSt trik menjaga lebar horisontal sama dengan panjang input.

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

Kurang golf

Ini adalah draft kerja pertama sebelum bermain golf

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
}  

Uji

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 byte

=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

Saya telah membuat rumus untuk menghitung posisi x, y dari setiap karakter berdasarkan ukuran segmen / modulo, tetapi mereka mendapat lebih besar dari yang saya harapkan: c

Penjelasan:

=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

Tes di sini

Untuk rumus Matematika, saya menggunakan mod untuk menghasilkan 0/1 bendera dan kemudian dikalikan dengan faktor berdasarkan input n, menambahkan spreadsheet dengan setiap langkah pada potongan di bawah ini


Bisakah Anda menjelaskan Matemagics? yaitu menulisnya dengan cara yang lebih manusiawi?
FliiFe

@FliiFe selesai c:
Rod

0

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

Menggunakan penyandian ISO-8859-1.

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

Jalankan seperti ini ( -dditambahkan hanya untuk estetika):

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

Tidak Disatukan:

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

Tweaks

  • Disimpan satu byte dengan menggunakan < alih-alih!=
  • Disimpan 2 byte dengan mengatur string 0pada awalnya, jadi saya tidak perlu menambahkan sebelumnya 0(jika output pertama dalam sebuah baris adalah 0), menghasilkan kebenaran00 .
  • Disimpan 4 byte dengan menggunakan referensi alih-alih diulang $o[$y]
  • Menyimpan byte dengan menggunakan modulo alih-alih ==untuk membandingkan arah dengan 1 untuk mengubah koordinat x
  • Menyimpan byte dengan menghapus tipe cast nullke intuntuk string offset, karena string offset dilemparkan ke int
  • Disimpan satu byte dengan menggunakan tag cetak pendek
  • Disimpan 7 byte dengan meningkatkan arah logika
  • Disimpan 4 byte dengan secara langsung menugaskan char untuk mencegah perantara $c
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.