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

12

Introduction

Write a program to output the outgoing spiral of the famous pangram following given rules.

Challenge

A pangram is a sentence using every letter of a given alphabet at least once. One of the most famous pangrams is the one used extensively in Windows font viewer, namely "The quick brown fox jumps over the lazy dog". The challenge is to output a spiral based on this text.

Your task is output this exact text:

heeeeellllllllllllazzzzzzzzzzz
hummmmmmmmmmmmmppppppppppppppy
hubrrrrrrrrrrrrrrrrrrooooooosy
hukyddddoooooooooooooooggggwsy
hukyveeeeerrrrrrrrrrrrrrrrtwsy
hukyvxjjjjjjjjjjuuuuuuuuuttwsy
hukyvxkbbrrrrrrrrrrrrrrrmttwsy
hukyvxkogggggggttttttttomttwsy
tukyvokoellllllllllllahomttwsy
tukyvokoeovvvvvvvvvvvzhomttwsy
tukyvocoeoummmmmmmmmezhomttwsy
tukyvocoeoufooooooopezhomttwsy
tukyvocohoufroooooxpezhomttwsy
tukyvoiohoufrquuuwxpezhomttwsy
tucyvoiohoufbqttiwxpezhomttwsy
tucyvoiohoufbeehiwxprzhomttwsy
tucyvoiohoufkccciwxprzeomttwsy
tjiyvoidhounnnnnnwxprzeomttwsy
tjiyvoidhojjjjjjjjxprzeomttwsy
tjiyvoidhssssssssssprzeopttwsy
tjiyvoidttttttttttttrzeopttwsy
tjiyvoiyyyyyyyyyyyyyyzqopttwoy
tjiyvouuuuuuuuuuuuuuuuqwpttwoy
tjiyvffffnnnnnnnnnnnnnnwpttwoy
tjiyossssssssssssssssssspthwoy
tjizzzzalllllllllllleeeeehhwoy
tjuuqqqqqqqqqqqqqqqqqeeeeehnod
txxxxxoooooooooooooooffffffnod
reeeeevvvvvvvvvvvvvvvvvvvvvvod
       gggggggoooooooooooooood

Here is how it is generated,

  • There was a zealous fox who enjoyed the pangram "The quick brown fox jumps over the lazy dog". One day he was in the center of an outward spiral and decided to jump in it and paint along.
  • He would like to go through the pangram from the beginning to the end, and if a letter is the n-th letter in the alphabet he would like to paint it n times.
  • However, the fox was not very good at making turns on corners, so upon reaching each corner he also had to stop and switch to the next letter.
  • He also decided to repeat the pangram thrice to emphasize that he is the quick brown fox.
  • Your job is to show how the spiral would look like after the fox painted all those letters.

(Plain version without story-telling)

  • The famous pangram "The quick brown fox jumps over the lazy dog" is repeated thrice, with the spaces removed and all letters in lower case, to generate

    thequickbrownfoxjumpsoverthelazydogthequickbrownfoxjumpsoverthelazydogthequickbrownfoxjumpsoverthelazydog
    
  • The spiral starts from the center and begins with the letter "t", it starts by going to the right, and goes outward clockwise. If the current character is the n-th letter in the alphabet, then it switches to the next character whenever

    • the spiral reaches a corner, or
    • the current letters is printed exactly n times.

To better illustrate it, I will explain how the spiral related to the first three words "thequickbrown" is generated.

 rooooo
 rquuuw
 bqttiw
 beehiw
 kccciw
nnnnnnw

The fox starts from "t", goes right, reaches the 1st corner, paints it with the "t" and then switches to "h" and goes down, reaches the 2nd corner, switches to "e" and goes left, reaches the 3rd corner, switches to "q" and goes up, reaches the 4th corner, switches to "u" and goes right, reaches a corner and switches to "i", goes down, reaches a corner and switches to "c", goes left, successfully paints 3 "c"s before reaching the next corner, switches to "k" and goes on to the left, reaches a corner right away, switches to "b" and goes up, paints 2 "b"s before reaching the next corner, switches to "r" and goes on upwards, reaches a corner and switches to "o", goes right, then "w", down, "n", left.

Specs

  • You can take an optional input that contains any standard form of the string

    thequickbrownfoxjumpsoverthelazydogthequickbrownfoxjumpsoverthelazydogthequickbrownfoxjumpsoverthelazydog
    
  • Your output must be formatted as a string, and must go to STDOUT instead of files or STDERR, with newlines placed correctly. Heading and trailing empty lines do not matter. Heading and trailing spaces in each line are allowed, but need to be be consistent. So if you add 5 spaces before one line of the given text, you'll need to add exactly 5 spaces before each line so that the spiral looks the same.

  • This is , the lowest number of bytes wins.

  • As usual, default loopholes apply here.


Explanations are welcome, although not necessary.

Title edited to make it a pangram per comment by caird coinheringaahing.

The lazy dog is too lazy to appear in the story.

I am aiming at creating a string challenge in which the letter to output cannot be computed by simple functions of the coordinates.

Weijun Zhou

Posted 2018-02-07T16:15:53.233

Reputation: 3 396

2It's a shame that the title isn't a pangram – caird coinheringaahing – 2018-02-07T20:04:10.947

@cairdcoinheringaahing Good point, I'll try to come up with one. Any suggestions? – Weijun Zhou – 2018-02-07T20:05:31.840

4@cairdcoinheringaahing Updated – Weijun Zhou – 2018-02-08T01:47:49.793

Minor point: shouldn't the 'h' in the first 'the' be repeated twice, not the 't'? – mudkip201 – 2018-02-08T03:02:06.157

@mudkip201 The corner is painted with the original letter before switching to the next character. Maybe I should clarify. – Weijun Zhou – 2018-02-08T03:06:51.547

@WeijunZhou Whoops. I misread the question. I thought it was saying the fox painted the nth letter of the string n times. – mudkip201 – 2018-02-08T14:31:31.900

For anyone else trying to cheat by directly printing the output, packing each character into 5 bits yields a whopping 581 bytes (including padding). Trying to run-length encode it (then pack it) makes it even worse (639 bytes). Cheating the puzzle is almost as interesting as doing it right. "Turning" the puzzle might yield a modest improvement, but I doubt it would be much. – user70585 – 2018-03-15T00:07:10.963

Thank you for your interest. I had some thoughts before posting this challenge and I decide to make it medium-sized. – Weijun Zhou – 2018-03-15T00:15:58.067

Answers

5

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

recursive

Posted 2018-02-07T16:15:53.233

Reputation: 8 616

Wow, I am really amazed that the challenge would see the first public appearance in golfing for a golfing language. Thank you very much for your support! Interested in Language of the Month? I hope to see more users using it and that it appears on the candidate list soon! – Weijun Zhou – 2018-02-08T23:25:11.753

@WeijunZhou: You mean this? I didn't know it was a thing until now. I wouldn't mind a nomination. It seems like it might be better suited to more established languages, but I don't object.

– recursive – 2018-02-08T23:25:55.410

Yes. I may nominate it when it is better established, as you say. I hope it won't be long. – Weijun Zhou – 2018-02-08T23:28:52.487

Since "heading space in each line does not matter as long as they are consistent" you may save another byte if you wish. – Weijun Zhou – 2018-02-08T23:58:59.797

@WeijunZhou: Thanks for pointing that out. Saved a byte. – recursive – 2018-02-09T00:13:34.550

1

I have just made a submission using Stax. You may give advice on that if you wish. Edit: What a coincidence. I will try to learn from your submission.

– Weijun Zhou – 2018-02-10T08:21:56.953

11

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.

Neil

Posted 2018-02-07T16:15:53.233

Reputation: 95 035

Thank you. Great job and well explained. A small typo: there times -> three times. – Weijun Zhou – 2018-02-08T01:11:16.777

1@WeijunZhou Thanks, I didn't notice that clause in the question before. – Neil – 2018-02-08T21:44:17.903

2

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
}

benj2240

Posted 2018-02-07T16:15:53.233

Reputation: 801

1Nice submission and clearly explained. I appreciate the use of r and l lambdas. Based on current answers the last leg seems to be a trouble maker although it wasn't when I wrote my C snippet to generate the sample output ... – Weijun Zhou – 2018-02-08T19:08:30.140

1@WeijunZhou Ahh, thanks for the tip. I do need that 0 though, or Ruby will pull up the c+=1 from the next line and only execute it most of the time. And nice challenge! – benj2240 – 2018-02-08T20:00:37.187

You are right. I didn't look careful enough. Thank you for your appreciation. I am glad that you enjoyed it. – Weijun Zhou – 2018-02-08T20:52:09.867