October 11, 2013

(New Book “If Hemingway wrote JavaScript” Now Available)

So anyway, I asked J.D. Salinger, Geoffrey Chaucer, Tupac Shakur, Virginia Woolf and Vladimir Nabokov to solve the happy numbers problem in JavaScript. Amazingly they all responded. Here’s how they did…

The Problem #

A happy number is one which, when repeatedly replaced by the sum of the squares of its digits, will tend towards 1. By way of reference here’s a bog-standard solution:

function isHappy(n) { // to avoid infinite looping, keep a history of numbers already visited var history = {'1': true}, nextNum; while( !history.hasOwnProperty(nextNum) ) { nextNum = 0; // prepare to calculate the next number in the series history[n] = true; // split the number into digits and square each one n.toString().split('').map(function(digit) { return digit * digit; }).forEach(function(squaredDigit) { nextNum += squaredDigit; // add each squared digit to out next number }); // put nextNum into n ready for the next loop n = nextNum; } // n is happy if it's 1 return n == 1; } isHappy(4); //false isHappy(7); //true

Okay, here we go…

J D Salinger #

“I’m aware that many of my friends will be saddened and shocked, or shock-saddened by JavaScript” #

// Most numbers are goddamn phonies, I swear to God. function howAreYaAnyway(number) { // What I thought I'd do, I thought I'd loop. I mean it. do { if (number < 5) break thisNextNumber = 0 // Making it a string. I'm serious. number = String(number) for (i in number) thisNextNumber += number[i]*number[i] // Putting the next one right back in the old one. Corny as hell I'll admit it. number = thisNextNumber } while (true) // Only about five numbers are really happy, that kills me. return "I'm " + ['H','Unh'][number==1?0:1] + "appy, I really am" }

Salinger chose to develop his solution in the manner of Holden Caulfield, the adolescent narrator of his best known work, The Catcher in the Rye.

Holden’s lovable mess of contradiction is on full display in this solution. He at once abhors the phoniness of the adult world into which he’s emerging, but at the same time he happily leaves all the semicolons out of his solution — a characteristically Caulfieldian affectation. Underlying the sloppiness and the outrageous shortcuts is a fierce intelligence and originality. Who else realized that all unhappy numbers end up reaching 4? To his mind the conventional practice of laboriously accumulating a record of previously tested numbers to avoid infinite looping is as unnecessary as it is phony.

Caulfield knows he’s clever yet he’s also insecure — almost every comment ends with a self-deprecating swipe at his own logic. His final comment betrays his acute sensitivity towards any kind of tragedy, whether his own or others’. I’m not kidding.

Geoffrey Chaucer #

“Ther nis no werkman, whatsoevere he be,

That may code JS both wel and hastily.” #

// Bifil that in this seson, on this day, // In Eich-ian riddle solemnly I lay, // To telle yow al the condicioun // Of nombres parfit and oothers gone astray function isGladNombre(nombre, ungladNombres) { ungladNombres = ungladNombres || []; if (ungladNombres.indexOf(nombre) > -1) { return 'untrewe'; } else { return nombre == 1 || isGladNombre(summonTheSqwares(nombre), ungladNombres.concat(nombre)); } function summonTheSqwares(nombre) { return ooneFoldeNombres(nombre).map(sqwarer).reduce(summoner); } } // Men intente is pleyn, reveeled anon... // For nombres giv'n, retorne the somme function summoner(nombre, ootherNombre) { return nombre + ootherNombre; } // It suffreth me to tell in rhyme // Of acht tymes acht and nyne tymes nyne. function sqwarer(nombre) { return nombre * nombre; } // And now the nombre splitte hymself // So oone and tweye results from twelfe function ooneFoldeNombres(nombre) { return String(nombre).split('').map(Number); }

This is vintage Chaucer, in fact it reads like a miniature version of The Canterbury Tales. As with that sprawling masterpiece, this solution is told by several protagonists in addition to the general narrator (the summoner and the sqwarer — also pronounced squire — might have been lifted directly from his earlier work, but we’ll let that go).

The overall effect is oddly functional — notice how the general narrator speaks in declarative terms (“summonTheSquares”) and indeed there are no side effects that I can see. It’s probably no coincidence that the Canterbury Tales is equally unimperative — Chaucer pays little attention to the passage of time and place, his primary interest is in the characters themselves and their stories.

Tupac Shakur #

“Follow your heart, but take JavaScript with you.” #

var theyDigits, theStash, nextFigga, anEmptyHash = {} function isChillin(myFigga) { theStash = theStash || anEmptyHash nextFigga = 0; /* be nillin it */ /* in preparation fo' fillin it */ /* they precondition is partition so */ doFissionOn(myFigga) accumulateTheySquares() /* sup addition? am a mathmetician */ /* and tha stash is tha hash caching all ma dead figgaz */ /* if yo value is one, ya won, but if yo in tha stash ya done */ if (nextFigga == 1) return "chillin" if (theStash[nextFigga] == 'x') return "illin" theStash[nextFigga] = 'x' /* keepin the history */ /* breakin tha chain of iteration misery */ return isChillin(nextFigga) /* recurse, rejigga, re-traverse the verse */ } function doFissionOn(n) {theyDigits = n.toString().split('')} function accumulateTheySquares() {theyDigits.forEach(function(n){nextFigga += n*n})}

I won’t attempt to analyze Tupac’s lyrical genius, because it just is. Tupac’s solution fuses native JavaScript with his characteristic lyrical devices: copious internal rhyming, assonance, alliteration and consonance. It flows and it compiles.

True to form, the approach is a complex blend of aggression and sensitivity, confidence and vulnerability. While the opening lines are cocky and dripping with swagger, the code takes a darker, more introspective turn as Tupac considers the number’s dead colleagues callously boxed up in the stash, and wonders if this number will suffer a similar fate. Near the end he contemplates the pain of those caught it iteration hell, but manages to restore a more positive vibe by suggesting a remedy (recorded history) and ultimately offering fresh hope in the shape of a new verse. Keep ya head up.

Virginia Woolf #

"A woman must have money and a room of her own if she is to write JavaScript” #

function happy(number) { var next, numeral, noneOfThese = []; //unless the number was nothing; or one; or unless it had been already tried while(number && number != 1 && noneOfThese[number] == null) { next = 0, numerals = String(number).split(''); //each numeral was squared then added; in this manner the next number was derived while (next = next + numerals[0] * numerals[0], numerals.shift(), numerals.length); noneOfThese[number] = true, number = next; } //to be one; alone; happily return number == 1; }

Although at face value they are worlds apart, there is a remarkable overlap between the work and ethos of Tupac and Virginia Woolf. Woolf pioneered lyricism in modern literature. Like Tupac, she leant heavily on stylistic instruments: alliteration, assonance, rhythm. The following passage from To the Lighthouse is ostensibly prose, but the meter is so strong and wordplay so rich, that it reads like poetry:

"The autumn trees, ravaged as they are, take on the flash of tattered flags kindling in the gloom of cool cathedral caves where golden letters on marble pages describe death in battle and how bones bleach and burn far away in Indian sands”

Her sentences are unfettered by the stuffiness of formal structure — often running into lengthy streams of consciousness glued together with semicolons and em-dashes.

The comma operator is the semicolon (and the em-dash) of JavaScript — its purpose is to bind multiple expressions into protracted statements. Programmer Woolf loved the comma operator and in her happy numbers solution she uses it to excess. The result is a dreamy, melancholic form of JavaScript (is there any other?) made dreamier still by the heavy, almost dangerous level of n alliteration and some gorgeously expressive pairings. In To the Lighthouse Woolf writes of night’s shadows: “They Lengthen; they darken”; in her happy numbers solution we get the wistfully poetic “numerals[0], numerals.shift()”.

Vladimir Nabokov #

“I don’t think in any language. I think in CSS” #

/* In Pergatorya, our oblivious integer necessitated emotional validation by means of a dubious algorithm of doubtful provenance. What followed was a self-penned scryptogram exhibiting the unhappy confluence of mechanical pedantry and digital peasantry. (Code is a bore to describe; yet a few basic details are, reluctantly, given) */ function isItHappy(ourNumber) { var terra, antiterra; while(true) { var terra = theNextNumber(terra || ourNumber); var antiterra = theNextNumber(theNextNumber(antiterra || ourNumber)); if (terra == 1 || antiterra == 1) { //Happiness: a temerarious tonsil tripping down the mouth //to thrust, at three, against the palate. //Hap. Ee. Ness. return true; } if (terra == antiterra) { //(history repeats) terra, antiterra, terror! return false; } } } function theNextNumber(thisNumber) { //being concolorus with the outcome... var ourResult = 0; //trying not to imagine the disasters inherent herein... thisNumber.toString().split('').map(function(aDigit) { return aDigit * aDigit; }).forEach(function(aSquaredDigit) { ourResult += aSquaredDigit; }); return ourResult; }

Oh Vladimir, you magnificent pedant! you genial tyrant! Nabokov’s version of english was all his own and so it is with his Javascript.

What on earth is going on here? Or should we ask what on earths? Because the key to Nabokov’s solution is terra and antiterra, the twin worlds of his grandiose masterpiece Ada. Terra resembles our earth while antiterra merely almost resembles it being shifted in time and divergent of history.

Yes, yes you ask, but what the actual fuck is going on here? Okay, so I think it goes like this (and cleverly, you’ll agree!). Remember how Holden Caulfield dispensed with history? Well so does Nabokov (being famously wary of conventional wisdom’s tyranny). And how? By running two happy numbers puzzles, on terra and anti-terra, simultaneously. Since antiterra spins a little faster than terra, it looks ahead a little further than terra each time. Now if terra and antiterra should ever return the same number at the same time we know in advance that history has repeated itself and must therefore be looping — and so the game is up.

On the other hand, should we be fortunate enough to reach numeric ecstasy, Nabokov will reprise the famous opening line of Lolita, only this time the exacting glossopharyngeal instruction is amended to form the word "happiness”.

And that’s a wrap! Though I admit I’m still scanning the initial letters for evidence of further riddling…

If you liked this…. #

Be sure to check out



If Hemingway wrote JavaScript



and



If Kerouac wrote JavaScript (and Dr Johnson wrote CoffeeScript)

And look out for the new book with illustrations by @fat coming out next year on No Starch Press

Thanks!

426 Kudos