There’s a programming meme featuring the Looney Tunes characters of Wile E. Coyote and the Road Runner. These characters are locked in a never-ending chase, where the Coyote seems to come close, but not quite catch the speedy bird. In the meme itself, it shows the Coyote running off of a cliff due to his misuse of the do / while iteration construct, whereas the Road Runner stops short because he presumably used the while iteration construct.

In this post, I’ll be implementing the meme using C#. I bet the results will surprise you.

The Meme

If you haven’t seen the meme, here it is.

Road Runner Wile E. Coyote Loop Meme

Chase Assumptions

Before we code anything, we have to lay down the ground rules for this chase between the Road Runner and Wile E. Coyote.

  1. There is a single runway that both the Road Runner and Coyote will share. Its length is arbitrary.
  2. The cliff appears at the 90% mark on the track.
  3. The Road Runner starts one “tick” in front of the Coyote, and will run until he reaches the cliff, at which point he will stop. He will be using the while loop construct.
  4. The Coyote starts one “tick” behind the Road Runner and will run until he reaches the cliff, at which point he will stop. He will be using the do/while loop construct.
  5. If the Coyote and Road Runner stop at the cliff, then the Coyote will have eaten the bird.

The Code

For my code sample, I am using .NET Core and the ShellProgressBar library to animate the progress of the Road Runner and Wile E. Coyote.

using System;
using System.Threading;
using System.Threading.Tasks;
using ShellProgressBar;

namespace Acme
{
    class Program
    {
        #region Ascii Art
        
        private const string OnYourMarks = @"
                  ....                                                   
                ,''. :   __                                                   
                    \|_.'  `:       _.----._//_                                                   
                   .'  .'.`'-._   .'  _/ -._ \)-.----O                                                   
                  '._.'.'      '--''-'._   '--..--'-`                                 .==,_                               
                   .'.'___    /`'---'. / ,-'`                                        .===,_`\                       
       snd       _<__.-._))../ /'----'/.'_____:'.                                  .====,_ ` \      .====,__                           
          \_    :            \ ]              :  '.                          ---     .==-,`~. \           `:`.__,                             
            \___:             \\              :    '.                         ---      `~~=-.  \           /^^^   ...beep beep!                               
                :              \\__           :    .'                           ---       `~~=. \         /                               
                :_______________|__]__________:  .'                                          `~. \       /                             
                           .' __ '.           :.'                                              ~. \____./                           
                         .' .'  '. '.                                                 jgs        `.=====)               
                       .' .'      '. '.                                                       ___.--~~~--.__                 
                     .' .'          '. '.                                           ___\.--~~~              ~~~---.._|/                   
                  _.' .'______________'. '._                                        ~~~""                             /                      
                 [_0______________________0_]                                                  
";
        #endregion
        
        public const int Runway = 1000;
        // the edge is at 90% of our runway
        public const int TheEdge = (int) (Runway * .9);
        // how fast are they running
        public const int Pause = 2;
        
        static void Main()
        {
            Console.Write(OnYourMarks);
            Console.WriteLine();
            Thread.Sleep(3000);
            
            using var cliff = new ProgressBar(Runway, "The Cliff", new ProgressBarOptions
            {
                BackgroundColor = ConsoleColor.Black,
                ForegroundColor = ConsoleColor.DarkGreen,
            });
            
            var roadRunner = cliff.Spawn(Runway,
                "Road Runner (Accelleratii Incredibus)",
                new ProgressBarOptions
                {
                    BackgroundColor = ConsoleColor.DarkBlue,
                    ForegroundColor = ConsoleColor.Blue,
                });
                
            var wileECoyote = cliff.Spawn(Runway,
                "Wile E. Coyote (Carnivorous Vulgaris)",
                new ProgressBarOptions
                {
                    BackgroundColor = ConsoleColor.Red,
                    ForegroundColor = ConsoleColor.DarkRed,
                });
                
            // beep beep -- road runner gets a head start
            roadRunner.Tick();

            Task.Run(() =>
            {
                // roadrunner runs
                while (roadRunner.CurrentTick != TheEdge)
                {
                    roadRunner.Tick();
                    Thread.Sleep(Pause);
                }

            });

            // Wile E. Coyote chases
            Task.Run(() =>
            {
                do
                {
                    wileECoyote.Tick();
                    Thread.Sleep(Pause);
                } while (wileECoyote.CurrentTick != TheEdge);

            });

            for (int i = 0; i < Runway; i++)
            {
                cliff.Tick();
                
                Thread.Sleep(Pause);
            }

            if (wileECoyote.CurrentTick == roadRunner.CurrentTick)
            {
                Console.WriteLine("🍗 Yum.... Road Runner for Dinner! 🍗");
            }
        }
    }
}

The Animated Results!

In the spirit of cartoons, I decided to add some animated suspense. Let’s run the code and see if Wile E. Coyote will finally get that elusive Road Runner.

Coyote Chasing Road Runner

It looks like Wile E. Coyote has Road Runner for dinner!

Conclusion

The meme on face value is funny, but it implies the use of do/while loops can be an issue for developers. In reality, it is about the logic in an application, and in the case of the meme, the implementation is just fine. The only time the Coyote would run off the cliff is if both he and the Road Runner were already standing on the edge and the Coyote decided to jump off.

It’s easy to poke fun here, and this post is very tongue-in-cheek, but the biggest takeaway is that language constructs aren’t inherently good or bad; it is about how we use them within the context of our applications. What did you think? Let me know in the comments.