A Zealous "Quick Brown Fox" "Jumped" Along the Groovy Spiral

Charcoal, 66 40 36 bytes

≔²ηFS«F¬η«¶↷⊞υη≔⊕÷Lυ²η¶»F⊕⌕βι¿η«≦⊖ηι

Try it online! Link is to verbose version of code. Edit: Saved 16 bytes by taking the text as input. Explanation:

≔²η

Start with 2 ts for some reason.

FS«

Loop over all the letters in the pangram.

F¬η«

Have we reached a corner yet?

Move down (or whatever the next direction will be) one line.

Rotate the print direction 90° clockwise.

⊞υη≔⊕÷Lυ²η

Calculate the length of the next side.

¶»

Finish fixing up the cursor position. (Charcoal would have preferred the side to end just before the corner, so that you rotated on the corner itself.)

F⊕⌕βι

Loop as many times as the current letter's position in the alphabet.

¿η«

If we haven't reached the corner,

≦⊖ηι

Decrement the count and print the current letter.


Stax, 35 34 33 32 bytes

é╛îá%ⁿ┌○iê}→Ug=╩◙╘Ç⌐)QX↑L╓₧╗▌╧▬q

Run and debug it online

Stax is a language I've been working on for about 6 months. This is the first public golfing with it. Let's get down to business.

Stax is normally written in the printable ASCII character set. This 34 byte submission is packed into a variant of the CP437 character set. The corresponding ascii representation is

't],{]_96-*~cHT,+nh%^(XUs&xH{rM}MF|<mr

Stax is a stack based language, but it has two data stacks, "main" and "input". Most operations use the main stack, but input starts on the input stack. Stax instructions are mostly one or two character ascii sequences. Most of them are overloaded, meaning their behavior is determined by the top few values on the stack(s).

At a high level, this program builds a grid by repeatedly appending strings to the last row. When the last row fills up, it rotates the grid clockwise. At the end, it mirrors the grid horizontally. In more detail, the program works like this.

't],{]_96-*~cHT,+nh%^(XUs&xH{rM}MF|<mr
't]                                         ["t"]
   ,                                        Pop from input, push to main ("thequick...")
    {                            F          For each character in input, execute block...
     ]_96-*                                 Produce string using character appropriate
                                                number of times (a=1, b=2, etc)
           ~                                Pop from main, push to input for use later
            cH                              Copy last row from grid.
              T                             Right-trim whitespace
               ,+                           Pop from input stack and append
                 nh%                        Get the width of the first row of the grid
                    ^                       Add 1
                     (                      Right-pad/truncate string to this length
                      X                     Store in the x register
                       Us&                  Overwrite last row of the grid with new value.
                          xH                Get the last element from x.
                                                Basically, the lower right corner.
                             {  }M         Conditionally execute block.  This will happen 
                                                when the bottom right corner isn't a space.
                              rM            Reverse and transpose (aka rotate clockwise)
                                  |<        Left-justify grid; give all rows equal size.
                                     m      For each row, execute the rest of the program
                                               and then print the result to output
                                      r     Reverse the row

Ruby, 217 212 209 208 bytes

->s{s+=' '*8
x=0
a=[""]*30
i=14
a[i]=?t
l=->{a[i]=s[x]+a[i]}
r=->{a[i]+=s[x]}
(0..58).map{|g|c=0
(0..g/2).map{c>s[x].ord-97&&(x+=1;c=0)
c+=1
eval %w{r i+=1;r l i-=1;l}[g%4]+"[]"}
x+=1}
a[-1].slice!0
$><<a*$/}

Try it online!

Spends a fair amount of time managing pointers, so there may be room for more golfing.

-5 bytes: Triple the pangram before inputting. Thanks to Weijun Zhou.

-3 bytes: Pad the input string and trim the last leg, instead of generating the last leg from scratch.

-1 bytes: Use && instead of a ternary operator with a throwaway value.

Explanation:

->s{
  s += " " * 8                             # These spaces will show on the bottom row
  x = 0                                    # x is a pointer into s
  a = [""] * 30                            # a is an array of row strings
  i = 14                                   # i is a pointer into a
  a[i] = ?t                                # "Starts with two t's for some reason"
  l = ->{ a[i] = s[x]+a[i] }               # lambda to prepend char x to row i
  r = ->{ a[i] += s[x] }                   # lambda to append char x to row i
  (0..57).map{|g|                          # There are 58 "legs" to the spiral
    c = 0                                  # c is the print count of s[x]
    (0..g/2).map{                          # Leg g has g/2+1 characters
      c > s[x].ord-97 && (x+=1;c=0)        # Possibly switch to next letter
      c += 1
      eval %w{r i+=1;r l i-=1;l}[g%4]+"[]" # Call the appropriate lambda
    }
    x += 1                                 # Definitely switch to next letter
  }
  a[-1].slice!0                            # Remove the first char from the bottom row
  $> << a*$/                               # Join with newlines and print
}