g | x | w | all
Bytes Lang Time Link
035Vyxal 3250630T215103Zpacman25
177Bash241003T155715ZThemooni
017Uiua241006T163537Znyxbird
122C64 BASIC241009T144341Zjdt
102APL+WIN241008T113824ZGraham
264C GCC241006T144340Zmatteo_c
067Wolfram Language Mathematica241006T113858Zatt
142Python 3241003T121136ZJitse
102JavaScript ES6241003T205800ZArnauld
025Vyxal241004T001655Zlyxal
007Charcoal241002T215157ZNeil
017Jelly241003T150222ZUnrelate
00305AB1E241003T095245ZKevin Cr

Vyxal 3, 35 bytes

00;pσ:T¨ɠ⦷¨+V:T¨Ɠ⍨␣YY£Z⍾⍨¥^Þ⎀£]¥⇄“”

Vyxal It Online!

takes input as a list of direction vectors and a list of characters for the string

works by zeroing out the maximum negative offset X and Y, so 0,0 becomes the lower left corner, then just assign the character to the coordinate. I have to manually create the grid, which is easy enough but caused so many problems. Also the column row index order is switched in vyxal so I have to swap stuff around a bit. I could probably end up using the space again to transpose the end result instead but that feels like way too much effort.

also I implemented a built-in for the zero vector specifically to save one byte in future answers

σ:T¨ɠ⦷¨+V:T¨Ɠ⍨␣YY£Z⍾⍨¥^Þ⎀£]¥⇄ 29 byter with questionable input output format, adds a leading zero vector for the initial character and outputs a character matrix

Bash, 177 bytes

s="$1"
e='echo -en '
shift
$e"\033[$#B\033[$#C"
for d;{
$e${s:i:1}
case $d in
7|0|1)$e"\033[1A"
;;&
0|4)$e"\033[1D"
;;&
3|4|5)$e"\033[1B"
;;&
5|6|7)$e"\033[2D"
;;
esac
let i++
}

Attempt This Online!

-13 bytes by looping with for d (implicit over all remaining args) instead of c-style loop.

-5 bytes by inserting a space at the end of the echo alias, enabling me to remove it from each call

makes heavy use of terminal escape sequences, and is the very first time I actually used fall-through switch statements anywhere!

provide the string as first argument (with quotes if it has spaces), then provide the numbers separated by spaces.

since this only works on a terminal, here are a few screenshots (i've verified that all test cases work):

spiralspiral test case

notice the huge whitespace. instead of computing how much whitespace i'll need, i simply offset to the number of commands, that way even the worst case won't try to move outside of bounds (which will fail silently)

s s s s test case overwriting test case octagon! test case

Uiua, 19 17 bytes

⬚@ ⌝⊡∩▽’⍜⇌◰.\+⊂⊸⧻

Try it!

⬚@ ⌝⊡∩▽’⍜⇌◰.\+⊂⊸⧻
                ⊂⊸⧻  # prepend (length, length)
              \+      # cumulative sum coordinates
         ⍜⇌◰.        # mask the last occurrences of each coordinate
      ∩▽’             # keep the coordinates and characters with the mask
⬚@ ⌝⊡                # create an array with the characters at the specified coordinates

Has a lot of leading whitespace (see bash answer). You can use ⬚@ ⌝⊡-¤⊸/↧+⊸⧻∩▽’⍜⇌◰.\+⊂0 to remove it for +4 bytes.

C64 BASIC, 122 bytes

1inputs$,d$:?cH(147):p=1524:fOi=1tolen(s$):pOp,aS(mI(s$,i,1))-64:p=p+vA(mI("1011519190894909",1+vA(mI(d$,i,1))*2,2))-50:nE

enter image description here

Try in emulator

APL+WIN, 102 bytes

Prompts for string followed by a vector of dx and then dy:

s←⎕⋄x←(1+|⌊/x)+x←+\0,⎕⋄y←(1+|⌊/y)+y←+\y←0,⎕⋄m←((⌈/y),⌈/x)⍴' '⋄i←1⋄⍎∊(⍴x)⍴⊂'m[y[i];x[i]]←s[i]⋄i←i+1⋄'⋄m

Try it online! Thanks to Dyalog Classic

C (GCC), 264 bytes

x;y;a;z;b;w;main(n,v)char**v;{for(v++[3]=calloc(4*n,n=strlen(v[1]));v[2][x+n+(y+n)*n]=*v[1]++;++*v)a=x<a?x:a,b=x>b?x:b,w=y<w?y:w,z=y>z?y:z,x-=**v%4?(**v&4)/2-1:0,y-=(**v-=2)%4?(**v&4)-2:0;for(y=w;y<=z;y+=2)for(x=a;x<=b+1;++x)putchar(x>b?10:v[2][n+(y+n)*n+x]?:32);}

Attempt This Online!

Wolfram Language (Mathematica), 67 bytes

SparseArray[Reverse/@(FoldList[Plus,{l=Tr[1^#2],l},#]->#2),2l," "]&

Try it online!

Input a list of direction vectors and a list of characters. Output a matrix of characters as a SparseArray.

Python 3, 142 bytes

f=lambda x,s,p={},c=0,S=sorted:s and f(x[1:]+[c.real,c.imag],s[1:],{**p,c:s[0]},c+x[0])or[[p.get(i+j*1j,' ')for j in S({*x})]for i in S({*x})]

Try it online!

-42 bytes thanks to UnrelatedString

Takes complex numbers as input and returns a (square) 2D array of characters with loads of whitespace

JavaScript (ES6), 102 bytes

Expects (directions)(characters), where directions is an array of [dx,dy] vectors and characters is a string. Returns a matrix of characters.

d=>s=>[...d,m=[...d+=x=y=d.length].map(_=>[...d].fill(" "))].map(([X,Y],i)=>m[y][x]=s[x+=X,y+=Y,i])&&m

Try it online!

(post-processing: the matrix is joined and some whitespace is removed for readability)

Vyxal, 20 bitsv2, 2.5 bytes

2ø^

Try it Online!

Bitstring:

01000011111001001000

Same idea as the 05ab1e answer but without the need for explicit swapping (it uses overloads). Uses the built in canvas digraph with length 2.

Charcoal, 7 bytes

GH✳✳A²S

Attempt This Online! Link is to verbose version of code. Explanation: PolygonHollow is Charcoal's path text writing function. It has two modes of operation, one where each direction and path length is specified and one where there is an array of directions and a fixed path length. Here Directions is used to specify an array expression as the directions. However PolygonHollow takes 0 as right and 2 as up, so I have amended the test case appropriately. The path length of 2 is inclusive so that each subsequent step draws one additional character.

9 bytes to take input where 0 is up and 2 is right:

GH✳✳⁻χA²S

Attempt This Online! Link is to verbose version of code. Explanation: As above but subtracts all the directions from 10 (PolygonHollow automatically reduces modulo 8) to get them into Charcoal format.

An alternative 9 bytes to take input where 0 is up and 2 is right:

GH✳✳A²S‖↘

Attempt This Online! Link is to verbose version of code. Explanation: As the first solution but reflects the canvas to get the desired result.

Jelly, 17 bytes

ZẈ;"$ÄZŒṬ€a"o@/o⁶

Try it online!

Takes a list of [dy, dx] pairs on the left and the string on the right, returning a list of lines.

Z     Z              Under transpose:
  ;"$                Prepend to each column
 Ẉ                   the length of that column,
     Ä               then cumulative sum each column.
         €           For each resulting coordinate,
       ŒṬ            create a grid with a 1 at those coordinates and 0s elsewhere,
          a"         and replace the 1 with the corresponding character.
            o /      Reduce the list of grids by logical OR
             @       reversed so that later characters overwrite earlier ones,
               o⁶    then replace any remaining 0s with spaces.

05AB1E, 3 bytes

2ŠΛ

Try it online.

Explanation:

Simply uses the 05AB1E Canvas builtin this challenge is based on, with additional length = 2 argument.

2    # Push 2
 Š   # Triple-swap using the two (implicit) inputs
     #  STACK: 2,string,directions
  Λ  # Use the Canvas builtin with these three arguments
     # (after which the result is output immediately implicitly)