Monthly Archives: October 2010

The Friday Fragment

It’s Friday, and time again for the Friday Fragment: our weekly programming-related puzzle.

This Week’s Fragment

Let’s do another game bot: this time, just a bit more sophisticated than randomly answering rock, paper, or scissors:

Code a simple REST web service to play tic-tac-toe.  It should accept a nine-character string representing the current “game board” with space, X, or O in each position (starting from the top left, going left-to-right and down).  It should return a nine-character string with your next move added.

For example, the game board at left is represented by the string ”  O X OX “.  X goes first; if you receive all spaces (empty board), go first with X.  Otherwise, take the next move: if you receive an even number of Xs and O’s, replace a space with an X; if you receive an odd number of plays, replace a space with an O.  And no cheating: if you do anything other than take the next legal move, you lose.

This is your chance to have a computer play your games for you.  Can you code something that plays as wisely as you would?

To “play along,” provide either the URL or the code for the solution. You can post it as a comment or send it via email.  We’ll have the submitted services compete in some “bot wars.”

Last Week’s Fragment – Solution

Last week’s puzzle continued with our simple RPS game:

Write code to score the results of calling rock, paper, scissors (RPS) web services.  Remember, rock beats scissors, scissors beat paper, and paper beats rock.  And bombs and dynamite don’t count.

Here’s another simple solution in PHP – my bot facing off against Spencer’s:

    <?php
      $winners = array("rock" => "paper", "paper" => "scissors", "scissors" => "rock");
      $url1 = 'http://derekwilliams.us/bots/rps';
      $url2 = 'http://ninjatricks.net/rps.php';
      $result1 = file_get_contents($url1);
      $result2 = file_get_contents($url2);
      printf("1: %s   2: %s\n", $result1, $result2);

      if ($result1 == $result2)
        echo "Tie";
      elseif ($result1 == $winners[$result2])
        echo "#1 wins!";
      elseif ($result2 == $winners[$result1])
        echo "#2 wins!";
      else
        echo "No winner.  Someone's misbehaving.";
    ?>

Again, it’s a bit oversimplified, but does the job.

Now you’re ready for your first “bot war”: see how your RPS bot competes with mine at http://derekwilliams.us/bots/rps.

Mstsc en abyme

Perhaps the only thing Microsoft Terminal Services Client (mstsc, a.k.a, Remote Desktop Connection) has going for it is ubiquity. Since it installs with Windows, it’s often the only remote access option available for a new machine; that is, until you log in and install something else.  One thing it definitely does not have going for it is a feature set like, say, a menu.

I found myself stuck in a Droste effect with nested mstsc sessions today while installing OpenSSH on a new Windows 2003 server.  Because this machine is in our DMZ, it takes two mstsc hops to get to it.  In the process I needed to give the innermost session the Ctrl+Alt+Delete three finger salute.  But how?  Unlike VNC, Radmin, and other remote control tools, there is no menu containing this option.  I vaguely recalled some weird key combination to reach to the end of this mise en abyme, but could not get it right.

After a bit of googling and trial and error, I came up with this:

  • In the first session, open the Windows on screen keyboard.  Oddly, this wasn’t on the accessibility menu, so I had to run osk.exe directly.
  • Use osk to type Ctrl+Alt+End. This sends a Ctrl+Alt+Delete to the inner session.

Not at all difficult, just weird.

The Squeeze

My friendly AIX admin recently asked me to move some of my test databases from a P570 to a new Power 7 (P750) box.  I used db2look and db2move to replicate these on the new system, but I wanted to take it a bit further.  Since I’ve been called a “DASD pig,” I saw this as a good opportunity to enable DB2 row compression on some of the larger tables and see how much space I could save.

Look Before You Squeeze

Before moving, I took some compression estimates on the source system. Since it was DB2 9.1, I had to use inspect:

db2 inspect rowcompestimate table name TABLENAME schema SCHEMANAME results keep TABLENAME.insp
db2inspf sqllib/db2dump/TABLENAME.insp TABLENAME.out

 

This gave “percentage saved” estimates in the 61 to 81 percent range for the tables I selected: very promising, considering the table sizes.

The target system was DB2 9.7, so I could use admin_get_tab_compress_info to get estimates there:

db2 “select * from table(sysproc.admin_get_tab_compress_info(‘SCHEMA’, ‘TABLE’, ‘estimate’)) as t”

For one 8-million-row table, the estimated savings were 61%: the same as the inspect estimate for this table on the DB2 9.1 box.

YMMV

I was curious how accurate these estimates were, so I measured it.  Since I had some similar databases, I created the first database without row compression and added it after loading data.

I compared sizes before and after the “alter table … compress yes” and reorg. The tablespace snapshots revealed a 51% reduction in 4K pages: from 909,985 to 442,817.  And the (SMS) disk space savings were in that same range: from 2.48 GB to 1.19 GB for that table’s data.  The index space savings weren’t significant (from 0.98 GB to 0.92 GB), but I didn’t expect much there.

I ran some quick tests using the system against the new (compressed) tables and found no significant performance impacts.  The initial reorgs and imports to enable compression and load data were painfully slow, but those are “off hours” activities anyway.

I’m Convinced

This was enough to convince me to enable compression from the very beginning for some of the larger tables in the remaining databases.  That is, I edited the db2look-generated DDL to add “compress yes” to the create table statements before running them.  I considered switching some of the SMS tablespaces to automatic storage, but decided to stick with only one change at a time for this round.

So far, I’m pleased with the results.  I’ll know more the next time we do a performance test, and I’ll be less of a “DASD pig” in the meantime.

The Friday Fragment

It’s Friday, and time again for the Friday Fragment: our weekly programming-related puzzle.

This Week’s Fragment

This week, we’ll take another step in our web service “bot wars:”

Write code to score the results of calling rock, paper, scissors web services.  Remember, rock beats scissors, scissors beat paper, and paper beats rock.  And bombs and dynamite don’t count.

To “play along”, provide either the URL or the code for the solution. You can post it as a comment or send it via email.  If you’d like, you can build atop results from our last Friday Fragment.

Last Week’s Fragment – Solution

Last week’s puzzle continued along our simple web service vein with the flip-side: calling a web service.

Write code to call your rock, paper, scissors web service and keep counts of how many times each is returned.

Here’s a really simple solution in PHP:

    <?php
      $counts = array("rock" => 0, "paper" => 0, "scissors" => 0);
      $url = 'http://derekwilliams.us/bots/rps';
      for ($i=0; $i<100; $i++)
        $counts[file_get_contents($url)]++;
      print_r($counts);
    ?>

 

It’s a bit oversimplified (e.g., no error handling), but does the job.

Cherokee Fall Classic

For the third straight year, the Cherokee Fall Classic had near-perfect weather and good turnout, with a broad spectrum of runners.  This is one of those “must do” events for our family: worth squeezing into our overbooked Saturday schedule.

The annual event features a 10K, 5K, and 1 mile fun run.  The 10K and 5K courses are now USATF-certified – good for qualifying times and accurate comparisons.  Each race offers its own appeal: the 10K route is very scenic, particularly for an “out and back,” and the 5K route is flat.  The race coincides with the adjacent and popular Cherokee Pignic for those who worked up an appetite for barbecue.

As always, the race was very well organized and well promoted locally.  Having full access to the YMCA facility on a chilly morning is a huge plus.  The volunteers were knowledgeable, helpful, and friendly.

Due to time constraints, both Stephen and I ran the 5K.  Lydia was disappointed that she couldn’t run it, but she had to stay fresh for a competitive soccer game that followed.  Stephen had a good run in his usual style: striking up conversations with adjacent runners while maintaining a strong, steady pace.  I had several clues that I took it too easy: I had too much energy at the end, my first mile was the slowest by far, and I got nowhere near a record time despite the flat course.  But it was good enough for a second place age group finish, since some of the faster runners were in the 10K.  Besides, for nice races and great family events like this, “a good time” measures fun more than speed.

I wish I could report on the post-race activities because they’re always excellent, but we had to leave immediately after Stephen crossed the finish line to make it to an early morning soccer game.  But I heard it was enjoyable from folks I talked with later in the day.

I expect the folks at the Canton YMCA will do a jam-up job with this race again next year, so count me in!

The Friday Fragment

It’s Friday, and time again for the Friday Fragment: our weekly programming-related puzzle.

This Week’s Fragment

We’ll continue this week along our simple web service vein with the flip-side: calling a web service.

Write code to call your rock, paper, scissors web service and keep counts of how many times each is returned.

To “play along”, provide either the URL or the code for the solution. You can post it as a comment or send it via email.  If you didn’t implement your own web service from last week or want to call mine instead, use this URL: http://derekwilliams.us/bots/rps.

Last Week’s Fragment – Solution

Last week’s puzzle was to code a simple REST web service that, when called via GET, randomly answers rock, paper, or scissors.  Your result could be fancy (wrapped in XML or JSON syntax), or simple: just the word.

Here’s one really simple solution, in PHP:

<?php
$choices = array(“rock”, “paper”, “scissors”);
echo $choices[rand(0,2)];
?>

Yes, to quote Billy Mays, “it’s just that easy!”

Now you may be thinking it’s not a real web service if it doesn’t use some combination of JAX-WS, Axis, Axis2, Castor, JiBX, JAXB, over-hopped servlets, lots of generated value/transfer objects and/or some other similar Rube Goldberg bloatware solution.  But then that wouldn’t be a fragment.  REST without XML is easy enough, and we want to keep this really simple, demonstrating logic, not plumbing.  If you’re an IIS fan (or don’t want to use PHP or Java), give C# a spin, where even SOAP/XML web services are easy.

And perhaps you see where all this is going… the “bot wars” are coming soon!

Go Phish

I’ve seen an uptick lately in phishing emails that do a much better job of replicating legitimate ones. For example, I’ve received several that look like Amazon orders or LinkedIn reminders. In all cases, the email content is a dead ringer for kosher ones except that the content (book titles, names, etc.) is unfamiliar, and if I mouse over the embedded links, the target URL is fishy indeed. And therein lies the purpose: to get unsuspecting recipients to click one of those links, visit its site, and receive malware.

Identifying and stopping these emails was easy.  Since they arrived at my Gmail account, I created some quick filters to corral them.  On closer inspection, I found that they were sent to a couple of my forwarded email addresses, so I simply turned off those forwards at my domain host.  And that provided some insight into the source: one was an old address I had given out only to InformationWeek.  Have they been selling or otherwise disclosing my email address?

Google’s anti-phishing initiatives have had mixed success.  Their phishing filter has been criticized for too many false positives, their DKIM initiatives have had too little uptake, and their “authentication icon for verified senders” is much too passive-aggressive.  But this has perhaps a simple solution: flag any email with embedded links where the target URL’s domain differs from the sender’s domain.  Perhaps this could be done with some creative filters or a Gmail gadget.  If these things come back, I’ll give it a shot.

The Friday Fragment

It’s Friday, and time again for the Friday Fragment: our weekly programming-related puzzle.

This Week’s Fragment

Some future Friday Fragments will make use of web services.  So we’ll take it one step at a time, starting this week:

Code a simple REST web service that, when called via GET, will randomly answer rock, paper, or scissors.

Your result can be fancy (wrapped in XML or JSON syntax), or simple: just the word.  To “play along”, provide either the URL or the code for the solution. You can post it as a comment or send it via email.

Last Week’s Fragment – Solution

Last week’s puzzle was to code a happy number finder.  A happy number is a positive integer which you can replace by the sum of the squares of its digits and repeat the process until you get to 1.  For example, 7 is a happy number because its series ends at 1: 72 = 49, 42 + 92 = 97, 92 + 72 = 130, 12 + 32 + 02 = 10, 12 + 02 = 1.

If you tried this, you know it’s not only a study in happy numbers, but also happy cases.  The basic solution is easy; I coded a quick inductive solution in Ruby as an extension to the Integer class:

  def is_happy
    return case
      when self == 1 then true
      when self < 1 then false
      else self.digits.inject(0) { | sum, ea | (ea * ea) + sum }.is_happy
    end
  end

 

That’s nice and simple, and 0.is_happy, 1.is_happy, and 7.is_happy all work swimmingly.  However, 2.is_happy loops forever until crashing with a stack overflow.  The reason is that the sum of squares of digits calculations for unhappy numbers run in infinite cycles (perhaps that’s why they’re unhappy). We can prevent that with a cache of numbers we’ve seen before:

  @@cache = Hash.new
  def is_happy
    return @@cache[self] if @@cache.include?(self)
    @@cache[self] = false
    result = case
      when self == 1 then true
      when self < 1 then false
      else self.digits.inject(0) { | sum, ea | (ea * ea) + sum }.is_happy
    end
    @@cache[self] = result
    return result
  end

 

I posted the complete code as a comment to last week’s puzzle.

No one sent a solution, so I’ll keep the 2011 Corvette ZR1 prize to myself.  But give this week’s puzzle a try; fortune or fame (or at least happiness) may await you.

Man and Machine

It’s a tired joke I’ve been using for decades now: “I’ve written code to cure cancer!  Actually, it causes cancer, but with a little more debugging, I’m sure I can reverse that.” The reality, of course, is that we can make machines do so much, but so much of that is really insignificant.  Sure, programming mission-critical business systems requires solving some interesting problems, but those problems often pale in comparison with many others in society.  So perhaps every programmer’s dream is to write that code that actually will help cure diseases or solve another similar ill.

Protein Folding

Protein folding research is one such area where some new, creative software solutions are being applied to significant, hard problems.  There’s a lot we know about protein assembly (for example, diseases arise from incorrect folding), and a lot we don’t know, like how proteins fold so well and how they sometimes misfold.  Answers to these questions might lead to cures for cystic fibrosis, HIV, Alzheimer’s disease, Parkinson’s disease, Huntington’s disease, Mad Cow disease, congenital emphysema, allergies, and many cancers.  Yet simulating folds to collect research data is computationally expensive: it can take around 30 CPU years to simulate one folding sequence.

So what does one do when hitting a computational wall?  Either get more CPUs (quantity) or better ones (quality).

More Brains

Projects such as Stanford University’s Folding@home (and others like it) are taking the more CPUs approach.  They use distributed computing (not unlike Berkeley’s SETI@home) to farm out simulation work to nearly a half million volunteer PCs around the world.

Better Brains

The University of Washington’s (UW) Foldit project takes the better CPUs approach: specifically, the human mind.  Many computer gamers possess strong, intuitive 3-D problem solving skills: skills that can be used to solve complex protein folding puzzles faster than computers can.  The challenge is finding and motivating these protein-folding savants, something UW accomplishes by making a game of it, and a world-wide competition.

Foldit is a 3-D protein folding puzzle-solving game.  Think of it as Tetris for protein designers.  Getting started with it is quick and easy; one click downloads and installs from the web site.  The Intro puzzles serve as a tutorial: just start solving puzzles, letting the hints guide the way.  The program does an excellent job of directing you toward proper folds, with 3-D rotation, bubble hints, red stars marking problems, and a sliding score that updates as you move.  It’s a study in transitional interfaces; for example, as you progress, it unfolds (pun intended) new tools you can use.

I suppose Foldit’s one weakness is its strength: you end up making structural changes intuitively, without considering the science behind them.  “All this science I don’t understand,” indeed, but that’s okay: the top five folders in a recent study had no more than a high-school level knowledge of biochemistry.  To quote one of the designing professors, “Some people are just able to look at the game and in less than two minutes, get to the top score. They can’t even explain what they’re doing, but somehow they’re able to do it.”

So if you have a knack for quickly solving 3-D puzzles, give Foldit a try.  Who knows, you just might cure cancer.

The Friday Fragment

After a summer hiatus, it’s time again for the Friday Fragment: our programming-related puzzle.

This Week’s Fragment

During the sabbatical, so many devious ideas came to mind: Sudoku solvers, quines, LOLCODE, you name it.  But discretion prevailed; after all, this is about code fragments: small, often elegant solutions that can be written relatively quickly, or used to try new languages and compare their merits.  And since this is such a happy day (with a sunny, happy daytime high), we’ll take on happy numbers.

A happy number is a positive integer which you can replace by the sum of the squares of its digits and repeat the process until you get to 1.  For example, 7 is a happy number because its series ends at 1: 72 = 49, 42 + 92 = 97, 92 + 72 = 130, 12 + 32 + 02 = 10, 12 + 02 = 1.  So:

Write code to compute happy numbers starting at 1.  To eventually get your computer back, you can stop at some high limit: whatever makes you happy.

Of course, this is a common math puzzle, so there are likely many implementations on the web.  But no peeking.  Try it for yourself and aim for something interesting: least amount of code, a new (to you) or unusual language, best use of recursion or induction, best performance, etc.

To “play along”, post the solution as a comment or send it via email.   To avoid “spoilers”, simply don’t expand comments for this post.

Last Week’s Fragment?

There wasn’t one!  The Friday Fragment was on summer break, and what a break it was!  But with the advent of fall, watch this space for new puzzles and solutions.