“Sharpen Up” Series: Episode 2
This one is an example of “trivial”. Problem description: find how many digits in a given number divide evenly into the number. This took me around about 2 minutes for a whopping 239 points out of 250. My solution:
public class DivisorDigits
{
public int howMany(int number)
{
int count = 0;
foreach (char c in number.ToString())
{
if (c == '0')
continue;
if (number % (c - '0') == 0)
{
count++;
}
}
return count;
}
}
“Sharpen Up” Series: Episode 1
In an attempt to stay “Ninja sharp” on the coding front, I’ve committed to solving a TopCoder problem from time to time. This is really just a self-improvement effort, and I don’t intend to take on the cream-of-coding at TC anytime soon. Having dipped my pinky toe in the water I have to say that (in my oh-so humble opinion) the standard is somewhat high. In every practice room there are three problems: “easy”, “medium” and “hard” respectively based on the maximum points that can be awarded. The point system is a little obscure, but what I have determined is that the points you can earn is exclusively determined by the time taken to complete the problem. The relationship is non-linear and although I haven’t dug into the details, I’m assuming asymptotic with some minimum value. That is, your points seem to fall off quickly but gradually level out until you can’t “lose” any more. So far, I’ve concentrated on “easy” and although some problems can be safely lumped in the “trivial” category, others are deceptively difficult.
Given the one-and-only criterion for success, one is quickly honed into punching out working code as quickly as possible. Coding standards and niceties go out the window–faster is better and style counts for nothing. Each problem can be coded in one of three languages, viz., C++, Java or C# (some problems have a “Python” as well, but it’s greyed out–possible future functionality?); erm … that would be C# 2.0, no thumping the competition with a quick lambda expression and a couple of extension methods.
For the sake of reference (and of course discussion), I’m going to post my solutions and the time taken to complete them (give or take a few minutes due to distractions) as episodes. TC no doubt are ready to disembowel your children should you cut-and-paste their problem descriptions, so I will provide a paraphrasing in each case.
Episode 1 involves a fictitious pack of cards. TC have made a noble effort to keep their problems real-world whilst still making them challenging–never-the-less I have to admit that they can sometimes be a little contrived. So … there’s this pack of cards containing an arbitrary number of cards. The cards in the pack are represented by characters in a string. The cards have values ’0′ to ’9′, ‘A’ = 1, ‘T’ = 10, ‘J’, ‘Q’ and ‘K’ = 11, 12 and 13 respectively. The rules are: go through the pack, removing all ‘K’s, and removing all consecutive pairs of cards whose total value equals 13, repeating the cycle as needs be and finally return the number of cards remaining when you can no longer remove any cards. Not hard, but a little tricky–this particular problem, if solved in an insanely short amount of time gets you 250 points. I left it for a day and got 75… The plan is to actually be rigorous about timing myself, making sure that I do this when I won’t be interrupted. That’s for the future.
Here’s my solution:
public class CircleGame
{
public int cardsLeft(string deck)
{
char[] work = new char[deck.Length];
for (int i = 0; i < deck.Length; i++)
{
work[i] = deck[i];
}
int lastix = -1;
int loops = 0;
int count = 0;
while (loops < 3)
{
int countstart = count;
for (int i = 0; i < work.Length; i++)
{
if (work[i] == 'K')
{
work[i] = '.';
count++;
continue;
}
if (work[i] == '.')
{
continue;
}
if (lastix == -1)
{
lastix = i;
continue;
}
if (val(work[lastix]) + val(work[i]) == 13)
{
work[i] = '.';
work[lastix] = '.';
lastix = -1;
count += 2;
continue;
}
lastix = i;
}
if (countstart == count)
loops++;
else
loops = 0;
}
return deck.Length - count;
}
private int val(char c)
{
if (c >= '0' && c <= '9')
{
return (int)(c - '0');
}
if (c == 'T')
return 10;
if (c == 'J')
return 11;
if (c == 'Q')
return 12;
if (c == 'A')
return 1;
return 13;
}
}
Delegate Magic
So, you’ve used delegates with gay abandon and everything just seems to work. In particular, this sort of thing works without a hitch:
class Proggy
{
public static void Main(string[] args)
{
var p = new Proggy();
Console.WriteLine(p.StuffThatNeedsDoing()());
Console.ReadLine();
}
public Func<int> StuffThatNeedsDoing()
{
var ia = new int[1];
ia[0] = 2;
return (() => ia[0] * ia[0]);
}
}
I’m referring, of course, to the bit that returns a delegate that references a method variable. I’ve always been curious as to how that works, so I dug into the IL to reveal the magic.
The interesting bit is the implementation of StuffThatNeedsDoing():
Let’s take a closer look as to what is happening here:
- Behind the scenes, the compiler generates a nested class called
<>c__DisplayClass1
and encapsulates ourint[]in it. L_0000toL_000enews up an instance of<>c__DisplayClass1and assigns theiafield therein to a newint[]of size 1.L_0013toL_001bassigns the value 2 to element 0 ofiawithin the instance.L_001ctoL_0028news up aFunc<int>, passing to the constructor the reference to<>c__DisplayClass1and the address of a method on<>c__DisplayClass1called<StuffThatNeedsDoing>b__0(which turns out to be our delegate implementation).- The new
Func<int>is then effectively returned.
In short – it looks (unsurprisingly) like the local ia is no longer a local, and naively referencing it from within the delegate has caused it to be treated like a heap variable. Of course our “local” ia now has a lifetime consistent with the lifetime of the delegate returned by StuffThatNeedsDoing—not a problem if we don’t mind, but what if we had referenced a “local” IDataReader from within our delegate? The IDataReader, and associated unmanaged resources, would lurk around possibly for a very long time … something to be aware of.
So, as it turns out, the thing that binds a function to it’s “environment” (in this case, the local that we referenced) is known as a closure.
Competition for Usenet?
I wasn’t expecting much when I tried out the new developer Q & A forum Stack Overflow, but was pleasantly surprised when my question was answered in less than five minutes. Not that I couldn’t have figured this out myself—there’s always a desperate rep glutton around willing to scoop up your questions … evidently.
Tab Position in VS2008
This bright young ladywoman makes it her duty to “tip” on VS on a daily basis without fail. For the most part, there isn’t anything hugely interesting, but occasionally there’s a gem.
In brief – don’t you hate it when your tabs don’t re-order so that the most recently accessed is also the first? This has the effect that some file that you may be interested in “pops” off the right-hand side. A small registry change ensures that tabs get re-ordered according to latest access; pretty handy–a small downside – tabs end up shifting around.
Polyglot
Well, polyglot programs are curious beasts, but what really takes the cake is renaming a text file to .com and seeing it run!
Capsaphobia
(kap-suh-foh-bee-uh) n. Fear of the Caps Lock key.
Evidently, sufferers abound. Assuming one is a touch-typist, and ones Caps Lock key has been “shown the door”, how prey-tell does one type
#define CAPS_LOCK_AINT_ALL_BAD TRUE
without abandoning the home position and doing the dreaded “hunt-and-peck”?
Binary or not?
Recently after listening to an episode of Hanselminutes it occurred to me that a measure of whether or not you’re a Unix geek is how often you see this kind of thing:
In short, if you don’t see it at all or have never noticed strange characters at the start of your text file, you’re likely to reply “to hear the sea?” to the question “what’s your favourite shell?”. In that case, do yourself a favour, go under the bonnet a little and learn about byte order marks (it’s all about enrichment).
Further, if it interests you enough, you may find yourself checking out the hex equivalent of your text file–how you go about that is very telling. Hanselman belied his roots by doing this:
debug Foo.txt (and then enter ‘d’)
On the other hand, having a rather more unixy background, I would do the following:
xxd Foo.txt
To be honest, debug wouldn’t have occurred to me – if I had not had cygwin installed, I would probably have ended up downloading a (free/share-ware) editor that provides such a feature.
One less visual annoyance
My take on this issue may not apply to everyone, but everytime some little app decides to contribute to the “system tray balloon tooltip” party I feel obliged to click on the damn thing just to get rid of it. In a world where there is way too much clicking to start with, I’d rather not care.
Here’s how to suppress balloon tooltips:
[HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced]
"EnableBalloonTips"=dword:00000000
You may ask: “Will a dword:00000001 get them to come back again?”. I tried–doesn’t seem to work. Evidently the presence of the entry suppresses them. Go figure.
To/Not to Design for Test
Recently someone raised what appears to be a contentious issue, that is, is it acceptable to “design for test”. Personally, initially a proponent of the “don’t-prop-your-code-up-for-the-sake-of-tests” department, I am becoming more inclined to agree with the author of said posting. Being able to completely isolate an object for the purposes of testing is a beautiful thing, but sadly it sometimes requires a whole lot of P.T. in the form of dependency injection frameworks and the like–we’re currently feeling this pain on a big project we’re working on.


