Skip to main content
2 of 12
added "short" version
Ivan
  • 209
  • 1
  • 5

Found this very entertaining, thanks! Here is "short" bash variant:

s=$1 n=$2 l=${#s} N=$((n+n-1)); for ((p=0; p<n*N; p++)); { S[p]=" "; }; printf -v T "%${N}s"; T=${T// /%s}; while ((n>0)); do     b='.'; for ((j=1; j<n; j++)); { t=${s:c:1} S[i]=${t:-$b} S[$((i+1))]="-" b='-' h='>'; ((i+=2)); ((c++)); }; ((n-=a)); b='.'; for ((j=1; j<n; j++)); { t=${s:c:1} S[i]=${t:-$b} b='|'; ((i+=N)); ((c++)); }; b="'"; for ((j=1; j<n; j++)); { t=${s:c:1} S[i]=${t:-$b} S[$((i-1))]="-" h='<' b='-'; ((i-=2)); ((c++)); }; ((n--)); b="'"; for ((j=1; j<n; j++)); { t=${s:c:1} S[i]=${t:-$b} b='|'; ((i-=N)); ((c++)); }; a=1; done; S[i]=$h; printf "$T\n" "${S[@]}"

And ungolfed for better readability:

#!/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!

Ivan
  • 209
  • 1
  • 5