Skip to main content
9 of 12
removed unnecassary " and '
Ivan
  • 209
  • 1
  • 5

BASH , 580 349 308 303 291 286 283 bytes

Found this very entertaining, thanks! First variant was 580 bytes, then 349, ..., now 283:

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[@]}"

Try it online!

Squeezed to 283:

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

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!

Ivan
  • 209
  • 1
  • 5