Your cart is currently empty!
Tortoise and Hare Pointers with The Movie Groundhog Day
Tortoise and Hare Pointers (the Fast and Slow Pointers). They make sense well enough, the analogy of the fast runner lapping a slow runner on a quarter mile track comes to mind, or perhaps a NASCAR loop where the slowest racer is eclipsed by the fastest… and yet, while I found myself able to appreciate and understand these analogies of how a cycle with pointers worked, part of me felt like something was missing. The “Why?” In other words: “sure, a slow competitor is eclipsed by a fast one on an enclosed track, but so what?”
While studying up on this, it seemed that the whole point of dealing with tortoise and hare pointer problems (outside of coding interviews) would be to help a program break out of some non-obvious infinite loop. As coders we encounter the OBVIOUS infinite loop when we write lousy code that has no break
condition. However, as a user of programs, I wondered what type of non-obvious infinite loop might I encounter that I would have a need for “fast and slow pointers”. It required some effort, but I began to wonder if very large downloads (system updates, that sort of thing) might have some sort of built-in cycler that makes use of fast and slow pointers… to check whether or not the download gets stuck… or, perhaps downloads a program in parallel to make sure that nothing is missed, nor repeated.
With that sense of purpose, I thought of the movies “Groundhog Day” with Bill Murray and “Edge of Tomorrow” with Tom Cruise. The idea of the slow pointer began to take shape as “living life in real time/in the moment”, and the fast pointer as representing “deja vous”. It gets a little trickier to extend the analogy much beyond that, especially in the context of either the present catching up to the future, or memories of the future encroaching upon the present. THE MAIN POINT though (in this analogy) IS, that when “life in the moment” and the “deja vous” experience overlap, you will have the opportunity to “break out of the loop” and control your destiny.
With that in mind, the following code is a relatively basic expression of how “Tortoise and Hare”/”Fast and Slow” Pointers work in the context of the movie “Groundhog Day”.
class Node {
constructor(value, timeOfDay, incident, incidentUncanny, next=null){
this.value = value;
this.timeOfDay = timeOfDay,
this.incident = incident;
this.incidentUncanny = incidentUncanny;
this.next = next;
}
}
class LinkedList {
constructor(head) {
this.head = head
this.tail = head
}
addNode(node) {
this.tail.next = node
this.tail = this.tail.next
}
}
function groundhog_day(head) {
let inTheMoment = head,
dejaVous = head;
console.log(inTheMoment.timeOfDay, "You", inTheMoment.incident, "and yet you vaguely feel that you have", dejaVous.incidentUncanny + " at " + dejaVous.timeOfDay)
console.log("\n ...now things are about to get weird... \n")
while (dejaVous !== null && dejaVous.next !== null) {
dejaVous = dejaVous.next.next; //two nexts is equivalent to Two steps into the future
inTheMoment = inTheMoment.next;
console.log(inTheMoment.timeOfDay, "You", inTheMoment.incident + ". Then you think about your next move: to " + (inTheMoment.next).incident)
console.log(" and have a vision that you have", dejaVous.incidentUncanny + " at " + dejaVous.timeOfDay)
if (inTheMoment === dejaVous) {
return inTheMoment.incident.toUpperCase() + "!?!?! This already happened!";
}
}
return "normal day";
}
head = new Node(1, "7:00 AM", "wake up", "already woken up")
const ll = new LinkedList(head)
ll.addNode(new Node(2, "7:10 AM", "make coffee", "already made coffee"))
ll.addNode(new Node(3, "7:20 AM", "take a shower", "already taken a shower"))
ll.addNode(new Node(4, "7:30 AM", "enjoy coffee and read the newspaper", "already drank your coffee and read the newspaper"))
ll.addNode(new Node(5, "7:40 AM", "listen to radio report", "already listened to the radio report"))
ll.addNode(new Node(6, "7:50 AM", "go to the festival", "already went to the festival"))
ll.addNode(new Node(7, "8:00 AM", "watch the groundhog see its shadow", "already witnessed the groundhog see its shadow"))
// THE CONSOLE LOG BELOW WILL RETURN A NORMAL DAY BASED ON THE NODES ABOVE...
//console.log(`${groundhog_day(head)}`)
// UNCOMMENT THE CODE BELOW TO RETURN A GROUND HOG DAY... KEEP IN MIND THAT... head.next.next is "two steps into the future"
ll.tail.next = ll.head
console.log(`${groundhog_day(head)}`)
If you ran the code as is above, not considering what’s commented out… you would return the following result…
7:00 AM You wake up and yet you vaguely feel that you have already woken up at 7:00 AM
...now things are about to get weird...
7:10 AM You make coffee. Then you think about your next move: to take a shower
and have a vision that you have already taken a shower at 7:20 AM
7:20 AM You take a shower. Then you think about your next move: to enjoy coffee and read the newspaper
and have a vision that you have already listened to the radio report at 7:40 AM
7:30 AM You enjoy coffee and read the newspaper. Then you think about your next move: to listen to radio report
and have a vision that you have already witnessed the groundhog see its shadow at 8:00 AM
7:40 AM You listen to radio report. Then you think about your next move: to go to the festival
and have a vision that you have already drank your coffee and read the newspaper at 7:30 AM
7:50 AM You go to the festival. Then you think about your next move: to watch the groundhog see its shadow
and have a vision that you have already went to the festival at 7:50 AM
GO TO THE FESTIVAL!?!?! This already happened!
For more convenient experimentation, check out this repl.it here.