# [BASH] , <s>580 349 308 303 291</s> 286 bytes Found this very entertaining, thanks! First variant was 580 bytes, then 349, ..., now 286: <!-- language-all: lang-bash --> s=$1 n=$2 N=$[n+n-1];f(){ b=$1;for((j=1;j<n;j++));{((c<N)) && T+="%s";[[ $4 ]]&&h=$4 S[$[i+$2/2]]=-;t=${s:c:1} S[i]=${t:-$b} b=$3;((i+=$2,c++));S[$[i-($2/N)]]=' ';};};while((n>0));do f . 2 - \>;((n-=a));f . $N \|;f \' -2 - \<;((n--));f \' -$N \|;a=1;done;S[i]=$h;printf "$T\n" "${S[@]}" [BASH]: https://www.gnu.org/software/bash/ [Try it online!](https://tio.run/##JZDPboMwDMZfxUIZJMqyDboTIdWegEt7CznwV4RVZgKqHRjPzlyqHOx8n392nKqc@32fDYsBDUsgN8yiRBU73XGxQkWO7saJ88HEeshQD1IKoVfO6ywXAsIQrtIEL3OgrQX2Cc6FYW8ouVhmvWTJe@KcUXoxbJ3TOo03cryj25IqVm2PESfNuZc0/7U@uh@o4sTmguAIIr3R@e39reUczx9U04zQwRskoKA4E4/KlCQ/NJZD8UdZEYE6/Ozw1WE/xGdBSRs1I7b6@Z5e/0welw4Cdi0woLBe7Jfbgp0@CMvvtpzGOzbdHevFj0jgzWM77XH8Dw) Squeezed to 291: #!/bin/bash s=$1 n=$2 N=$[n+n-1] f(){ b=$1 for ((j=1; j<n; j++)); { ((c<N)) && T+="%s" [[ $4 ]] && h=$4 S[$[i+$2/2]]=- t=${s:c:1} S[i]=${t:-$b} b=$3 ((i+=$2,c++)) S[$[i-($2/N)]]=' ' } } while ((n>0)); do f . 2 - \>; ((n-=a)) f . $N \| f \' -2 - \<; ((n--)) f \' -$N \| ; a=1 done; S[i]=$h; printf "$T\n" "${S[@]}" Reduced to 349 bytes: s=$1 n=$2 N=$[n+n-1]; for ((p=0; p<n*N; p++)); { S[p]=" "; }; printf -v T "%${N}s"; T=${T// /%s}; f(){ b=$1; for ((j=1; j<n; j++)); { [[ $4 ]] && h=$4 S[$[i+$2/2]]=-; t=${s:c:1} S[i]=${t:-$b} b=$3; ((i+=$2,c++)); }; }; while ((n>0)); do f . 2 - \>; ((n-=a)); f . $N \|; f \' -2 - \<; ((n--)); f \' -$N \|; a=1; done; S[i]=$h; printf "$T\n" "${S[@]}" [Try it online!](https://tio.run/##PVDLboMwEPyVEXLSpNQloZUqxXHUL@ASbsYHkoBwGi0RkPZA@Xa6zqOSZY9nZsfr3eVtNY6tFkuQFjESLQyFJJdWoawbzGZnvVA4r@k54SMM53OFHltztjpAoDAw2zjqSshvpAgmok@GloVUiz6NIkSTlj3lbN5jx888Yo@a4XFNvD1CjYF4h7WYTlFphlsjjAtFHMXWaqnQcWS72q@WA0vO8q1bSbEbfPCb4lAX8h9e9rfA4bp@KncqWKLNwpOHGiVeEUMi2/gSkjr3gmdFguzXw@wJ8mpZ3yzy5vD03ZP79g81FereSvU/h0CkGfFsRL81n3YIRp4v5V9F3tQXOpQX2neuJi49OSqa8eMP) And ungolfed for better readability: #!/bin/bash s=$1 n=$2 N=$[n+n-1] for ((p=0; p<n*N; p++)); { S[p]=" "; } printf -v T "%${N}s"; T=${T// /%s} f(){ b=$1 for ((j=1; j<n; j++)); { [[ $4 ]] && h=$4 S[$[i+$2/2]]=- t=${s:c:1} S[i]=${t:-$b} b=$3 ((i+=$2,c++)) } } while ((n>0)); do f . 2 - \>; ((n-=a)) f . $N \| f \' -2 - \<; ((n--)) f \' -$N \| ; a=1 done; S[i]=$h; printf "$T\n" "${S[@]}" First variant was: #!/bin/bash s=$1 n=$2 l=${#s} N=$((n+n-1)) # items per row # Check if n is in range (( (n*n)>=(l+1) )) || { echo "n must be 'n^2≥l+1'"; exit 1; } # Fill the 'area' with spaces for ((i=0; i<n*N; i++)); { snake[$i]=" "; } # Create printing template printf -v row "%${N}s" row=${row// /%s} # Setcounters i=0 c=0 a=0 forward(){ b='.' for ((j=1; j<n; j++)); do cut=${s:c:1} snake[$i]=${cut:-$b} snake[$((i+1))]="-" b='-' h='>' ((i+=2)) ((c++)) done ((n-=a)) } down(){ b='.' for ((j=1; j<n; j++)); do cut=${s:c:1} snake[$i]=${cut:-$b} b='|' ((i+=N)) ((c++)) done } back(){ b="'" for ((j=1; j<n; j++)); do cut=${s:c:1} snake[$i]=${cut:-$b} snake[$((i-1))]="-" h='<' b='-' ((i-=2)) ((c++)) done ((n--)) } up(){ b="'" for ((j=1; j<n; j++)); do cut=${s:c:1} snake[$i]=${cut:-$b} b='|' ((i-=N)) ((c++)) done a=1 } print(){ printf "$row\n" "${snake[@]}" # echo $i,$c,$n } # Create snake while ((n>0)); do forward down back up done snake[$i]=$h; printf "$row\n" "${snake[@]}" [Try it online!][1] [1]: https://tio.run/##vVTBjtowEL37K6bGu0mWTbPhUgnwqtJKPXLpsd1KjjEbL2ESxaGpBHxAP6Q/1h9JJ4aFtqirnrCU4BmPZ9570SNTLu@6wZsks5hkFDDmpEgZSjFihRSbgduxmRRhiEOM0yiCAdjGrBxUpoa6bBkbwENu9BLsAhCsA4tQK3wyLAwhxBuM7mVYDNMI6PJ2CxswOi@BI6zWroHMQIBfRj@//6CagE/AfLMNpBPY9Z0/2KKAJqcaVRsVQGubHFyltHFsUdYQhlbeTcBO8WZGP8NhFE1ogkO1NJ@EfZQc@KHVAzVoDFS1xcbiExCJqqAM85kFxF97OsCvxGa2c5xRQPTpnSSQXDnf46NpdLnGxtSO0WCm6VH0sB5Mq@p5GG0Y0Mpk8Dbwuz3KZ0mMnqdIrz3GeelP@6XXDQ1yYz1Od8fkiYHYUME4FtnZIZEnWSMiGfPjGU2Og2OUy@D@FPUX5CiKfkvoHo6P5yUatk9iLBVliTKbly1ehhR13/4FdfYa1B5dpvTyhI4H/AKSx2eSk8jT4B8foL/wf5LHB8XX1WUYnekdv653v1Ey9Ri9ZV5gHvzDBXnlM5LhCIcf/P5xx8k0tLzjhb0V@lag73D0oy9lbW4LA@MjpYOdDtNb3OtBX9tv1tWLalN5R/8q19d/eF7kE8io@7J3vsfuIXZd52tUTRae63Jl3H7bvfsF