Review: The Magicians
Review of The Magicians (The Magicians #1.0) by Lev Grossman (9780670020553)★★★(https://b-ark.ca/SGUw_c)Quentin Coldwater is brilliant but miserable. A high school math genius, he's secretly fascinated with a series of children's fantasy novels set in a magical land called Fillory, and real life is disappointing by comparison. When Quentin is unexpectedly admitted to an elite, secret college of magic, it looks like his wildest dreams have come true. But his newfound powers lead him down a rabbit hole of hedonism and disillusionment, and ultimately to the dark secret behind the story of Fillory. The land of his childhood fantasies turns out to be much darker and more dangerous than he ever could have imagined. . . .
The book is slow to start and it often feels as though Grossman is going through the motions. But the driving second half more than makes up for it. And with choice quotes like:
“Look, who’s the talking bear here?” Quentin snapped. “Is it you? Are you the talking fucking bear? All right. So shut the fuck up.”
The meta-fiction is downright entertaining.
Some might find the book needlessly angsty, and there’s some merit to that complaint. But its an interesting alternative look at what it would mean to discover a magical world embedded in our own.
Review: You
When Russell joins Black Arts games, brainchild of two visionary designers who were once his closest friends, he reunites with an eccentric crew of nerds hacking the frontiers of both technology and entertainment. In part, he's finally given up chasing the conventional path that has always seemed just out of reach. But mostly, he needs to know what happened to Simon, his strangest and most gifted friend, who died under mysterious circumstances soon after Black Arts' breakout hit.
As the company's revolutionary next-gen game is threatened by a software glitch, Russell finds himself in a race to save his job, Black Arts' legacy, and the people he has grown to care about. The deeper Russell digs, the more dangerous the glitch appears -- and soon, Russell comes to realize there's much more is at stake than just one software company's bottom line.
“You”’s biggest problem is simply that it came after Ready Player One, and so everyone presumes that, just because they both deal with video games, they must be similar.
They’re not. At all.
Ready Player One is exactly what I suspect most people would expect of a video game novel: fast paced, fun, full of action and suspense. That it’ll get made into a movie I have no doubt.
Continue reading...Review: Carpe Jugulum
Review of Carpe Jugulum (Discworld #23.0) by Terry Pratchett (9780613277617)★★★★★(https://b-ark.ca/gKWiYy)When Uberwald's undead population, the Magpyrs, begins to invade Lancre, a priest forges an tentative allience with the local witches to prevent the kingdom from being overrun.
Granny Weatherwax is one of those characters that, prior to this point, I would describe as a quiet mystery. Old, crotchety, wise, powerful, and wickedly intelligent, her role in her coven was always important but never a centerpiece, at least in my mind, and she was never a character toward which I would ascribe feelings of sympathy.
But in this book we see Pratchett really explore what makes Granny Granny, and in doing so, shows us why he loves her character so much. Like Captain Vimes, Granny is a creature of honour and duty, willing to do those things others can’t or won’t do because they are necessary. But as we’ve seen Vimes, here we see Granny bending beneath the weight of that duty, and in those moments we see the humanity and vulnerability of a character who seems so unbreakable.
To me, this book stacks up with Guards! Guards! as one of Pratchett’s best… I’m a guy who loves relating to great characters, and this book delivers in spades.
Introducing the Trie
So in the kickoff post of my series on data structures and algorithms I’d like to begin with a relatively simple but handy little data structure: the trie. If you want to jump ahead and look at a very simplistic implementation of a trie data structure (only the insert and dump operations have been completed), I’ve put my experimental code up on GitHub here.
A clever little play on the word retrieval (though I, and many others, insist on pronouncing it “try”… suck it etymology), a trie is a key-value store represented as an n-ary tree, except that unlike a typical key-value store, no one node stores the key itself. Instead, the path to the value within the tree is defined by the characters/bits/what-have-you that define the key itself. Yeah, that’s pretty abstract, why don’t we just look at an example:
In this construction I’ve chosen the following set of keys:
- allow
- alter
- alloy
- ant
- bad
- bar
As you can see, each character in the key is used to label an edge in the tree, while the nodes store the values associated with that key (note, in this example I’ve chosen to use the keys as values as well… this entirely artificial, and a bit confusing. Just remember, those values could be absolutely anything.) 1 Typically these keys are strings, as depicted here, although it’s entirely possible to build a bit-wise trie that can be keyed off of arbitrary strings of bits. To find the value for a key, you take each character and, starting with the root node, transition through the graph until the target node is found. Or, as pseudo-code:
find(root_node, key): current_node = root_node current_key = key while (current_key.length > 0): character = current_key[0] if current_node.has_edge_for(character): current_node = current_node.get_get_for(character).endpoint else throw "ERMAGERD" return current_node.value
Strangely, a very similar algorithm can be used for both inserts and deletes.
Some Interesting Properties
The trie offers a number of interesting advantages over traditional key-value stores such as hash tables and binary search trees:
- As mentioned previously, they have the peculiar feature that inserts, deletes, and lookups use very similar codepaths, and thus have very similar performance characteristics. As such, in applications where these operations are performed with equal frequency, the trie can provide better overall performance than other more traditional key-value stores.
- Lookup performance is a factor of key length as opposed to key distribution or dataset size. As such, for lookups they often outperform both hash tables and BSTs.
- They are quite space efficient for short keys, as key prefixes are shared between edges, resulting in compression of the graph.
- They enable longest-prefix matching. Given a candidate key, a trie can be used to perform a closest fit search with the same performance as an exact search.
- Pre-order traversal of the graph generates an ordered list of the keys (in fact, this implementation is a form of radix sort).
- Unlike hashes, there’s no need to design a hash function, and collisions can only occur if identical keys are inserted multiple times.
Applications
Because tries are well-suited to fuzzy matching algorithms, they often see use in spell checking implementations or other areas involving fuzzy matching against a dictionary. In addition, the trie forms the core of Radix/PATRICIA and Suffix Trees, both of which are interesting enough to warrant separate posts of their own. Stay tuned!
References
-
Interestingly, if you looked at this example graph, you’d be forgiven for assuming it was an illustration of a finite state machine, with the characters in the key triggering transitions to deeper levels of the graph. ↩