November 2006 - Posts - Jon Galloway

November 2006 - Posts

Macro to add a Codebehind file to an ASPX page in VS2005

The best way to add a code file (a.k.a. codebehind) to an ASP.NET ASPX page is check the "Place code in separate file" checkbox when you create it:

However, as Fritz Onion wrote, it's nice to avoid creating unnecessary codebehind files "just in case", because the with advanced web controls in ASP.NET 2.0, it's possible that many of your pages won't need any additional code.

The problem: If you're working with a page wasn't created with a codebehind file, there's no "right-click / add code file" option. Mikhail Arkhipov wrote some basic directions on how to do this manually, and Fritz's post goes into a little more detail. Fritz asked for a plugin to add code files to an ASPX page, but I'll settle for a Visual Studio macro. This thing's pretty simple - just select the ASPX file in the solution explorer, then run the macro. There's some error handling, but I'd make sure you save your work before running this.

I've started playing with upgrading it to a Visual Studio Addin (using the MakeAddin macro), but it's not working yet.

Sub AddCodeBehind() Dim docName Dim docFullName Dim nameOfType Try DTE.ExecuteCommand("View.ViewCode") docName = DTE.ActiveDocument.Name If (docName.ToString().EndsWith(".aspx") = False) Then Throw New System.Exception() End If Catch ex As Exception Throw New System.Exception("You must select an ASPX file in the Solution Explorer before running this macro.") End Try nameOfType = Replace(docName, ".aspx", "") docFullName = DTE.ActiveDocument.FullName DTE.ExecuteCommand("Edit.Replace") DTE.Find.ReplaceWith = "<%@ Page Language=""C#"" CodeFile=""" + nameOfType + ".aspx.cs"" Inherits=""" + nameOfType + """" DTE.Windows.Item("" + nameOfType + ".aspx").Activate() DTE.Find.FindWhat = "<%@ Page Language=""VB""" DTE.Find.ReplaceWith = "<%@ Page Language=""C#"" CodeFile=""" + nameOfType + ".aspx.cs"" Inherits=""" + nameOfType + """" DTE.Find.Target = vsFindTarget.vsFindTargetCurrentDocument DTE.Find.MatchCase = False DTE.Find.MatchWholeWord = False DTE.Find.MatchInHiddenText = True DTE.Find.PatternSyntax = vsFindPatternSyntax.vsFindPatternSyntaxLiteral DTE.Find.ResultsLocation = vsFindResultsLocation.vsFindResultsNone DTE.Find.Action = vsFindAction.vsFindActionReplaceAll If (DTE.Find.Execute() = vsFindResult.vsFindResultNotFound) Then DTE.Find.FindWhat = "<%@ Page Language=""C#""" DTE.Find.Action = vsFindAction.vsFindActionReplaceAll End If '{CF2DDC32-8CAD-11D2-9302-005345000000} is the GUID for the Find / Replace Dialog DTE.Windows.Item("{CF2DDC32-8CAD-11D2-9302-005345000000}").Close() DTE.ActiveDocument.Save() DTE.ActiveDocument.Close(vsSaveChanges.vsSaveChangesYes) DTE.ItemOperations.AddNewItem("Web Developer Project Files\Visual C#\Class", docName + ".cs") DTE.ExecuteCommand("Edit.Replace") DTE.Windows.Item(nameOfType + ".aspx.cs").Activate() DTE.Find.FindWhat = "public class " + nameOfType DTE.Find.ReplaceWith = "public partial class " + nameOfType + " : Page" DTE.Find.Target = vsFindTarget.vsFindTargetCurrentDocument DTE.Find.MatchCase = False DTE.Find.MatchWholeWord = False DTE.Find.MatchInHiddenText = True DTE.Find.PatternSyntax = vsFindPatternSyntax.vsFindPatternSyntaxLiteral DTE.Find.ResultsLocation = vsFindResultsLocation.vsFindResultsNone DTE.Find.Action = vsFindAction.vsFindActionReplaceAll If (DTE.Find.Execute() = vsFindResult.vsFindResultNotFound) Then Throw New System.Exception("vsFindResultNotFound") End If '{CF2DDC32-8CAD-11D2-9302-005345000000} is the GUID for the Find / Replace Dialog in case you missed that earlier comment DTE.Windows.Item("{CF2DDC32-8CAD-11D2-9302-005345000000}").Close() DTE.ActiveDocument.Save() DTE.ActiveDocument.Close(vsSaveChanges.vsSaveChangesYes) DTE.ItemOperations.OpenFile(docName) DTE.ItemOperations.OpenFile(docFullName + ".cs") End Sub
Posted by Jon Galloway | with no comments
Filed under:

Creating a User Defined Language in Notepad++

I just posted about adding PowerShell syntax support to Notepad++ by adding a User Defined Language definition. It's pretty simple; here's a quick overview of how I did it. For a more in depth overview of the User Defined Language system, check out the Notepad++ docs.

Like most of these editors, Notepad++ saves language definitions in an XML file, but Notepad++ includes front end (the User Defined Language editor), which makes it a lot easier to set it up. You can bring up the User Defined Language editor from the menu (View -> User Define Dialog...):

Notepad++ User Defined Language

There are four tabs to fill out - Folder (as in code folding), Keyword, Comment, and Operators. You may have to dig through the docs for the language you're adding to find these, but in a lot of cases it's not to hard to get a list of supported keywords. In the case of PowerShell, you can get a list of all commands by running the "get-command". Make sure to set the file extension and language name. There's no save button, which is a little confusing, but the changes take effect as you make them and the changes are saved to the userDefineLang.xml file when you close Notepad++. If you're just making the changes for your own use, that's it - you're done. But be a sport and share them, would you? It's not too hard - you just have to distribute your changes to the userDefineLang.xml file.

Installing a user defined language file that someone else has written is pretty simple as long as you haven't installed any previously - you just rename the file to userDefineLang.xml and drop it in your %APPDATA%\Notepad++\ directory as pictured below. If you've added other user defined languages, you need to merge the two XML files together. That's pretty bad on the user experience side, but if you're the kind of person who needs two user defined languages, you're a total geek who loves merging XML files anyways.

Posted by Jon Galloway | 4 comment(s)
Filed under: ,

PowerShell Language Definitions for Notepad++

 I saw a request on the Notepad++ forums today to add PowerShell syntax support. Notepad++ has a pretty good extension system for adding user defined languages, so I went ahead and put on together. You can grab it from the Notepad++ download area (zip download). Installation information is in the included readme file - you extract the zip, rename a file, and drop it in your %APPDATA%\Notepad++\ directory.1

I've submitted a patch to get it included in a future Notepad++ release. The patch has been accepted; it's available for download from the Notepadd++ site.

The PowerShell API is very discoverable - you can get a list of all supported PowerShell commands by running the command "get-command" with no parameters. Similarly, you can get a list of all command aliases by typing "get-alias". I also threw in all the standard WMI classes and the basic PowerShell operators and syntax based on the online documentation. You can read my walkthrough of adding a User Defined Language to Notepad++ if you'd like more info on the process involved.

I'm thinking this might be helpful for occasional quick edits. For a real PowerShell editor, I highly recommend PowerShell Analyzer.


1The only gotcha there is if you've already added a user defined language for Notepad++, in which case you'll need to merge the files.

Speaking: 11/28 - San Diego .NET User Group

I'll be speaking at the San Diego .NET User Group on 11/28:

Jon has been putting some new and lesser used features in SQL Server to work to solve some tough business problems lately. He will review SQL Server Management Objects (SMO), INFORMATION_SCHEMA queries, and some of the T-SQL language enhancements; and then will show how he used them in several recent projects. We'll look at SMO code in a freeware tool Jon recently released, Data Dictionary Creator, as well as INFORMATION_SCHEMA queries used to drive code generation in the SubSonic Data Access Layer system.

I'm splitting the evening with Zoiner Tejada, who will be speaking on SSIS.

Posted by Jon Galloway | with no comments
Filed under: , ,

Make Zune a winner... as a platform

It's no secret - the Zune could be better than the iPod and still languish as an also ran for years. iPod has a huge marketshare, a solid brand, and a following whose passion would be the envy of most terrorist organizations. The "second mover advantage" sweet spot time has come and gone. iPod is firmly established, and "feature parity and a bag of chips" won't win any marketshare. The Zune WiFi feature is a good example - it's a cool feature, but it's been written off as to heavily locked down by DRM restrictions; the iPod doesn't have any WiFi and the Fairplay system is pretty restrictive. My point is that features alone won't beat brand loyalty.

Microsoft needs to change this game to win.

Michael Elgan presented a pretty good answer to this problem in Computer World today in "Zune: So you want to be an iPod killer". The basic idea - Zune should beat iPod the same way Windows beat Mac OS, by providing an open platform:

After all, the Mac is more elegant than Windows, but most people prefer Windows. And that's how Microsoft can kill the iPod: Make the Zune more like a Windows PC. [...] Microsoft will never beat Apple at its own game. But the reverse is also true: Apple can't win at the Microsoft game. If Microsoft turns Zune into a media-optimized, extensible mini-PC that really works, the iPod is as good as dead.

Crazy? Not so much.

The Zune already runs a stripped down version of Portable Media Center, which is based on Windows CE 5. They've already announced plans for a Zune phone, which would undoubtedly leverage their experience with the Windows Mobile platform. The Zune 1.0 may run a stripped down OS, but the hardware has tons of potential.

Microsoft brings a lot more to this game than the chip lead and a history for taking over markets through their system of relentless refined releases. They bring a tested mobile operating system, a great development environment (Visual Studio) and platform (.NET), and legions of developers. Zune will never beat iPod as another music player, but it can definitely win if it's a great music player that happens to be as hackable as a PSP.

To do that, they'll need to do three things:

  • Make it hackable
  • Keep it small and cheap
  • Keep music companies reassured that the hackability won't jeopardize their DRM

Make it hackable

 Well, the hardware is great, and the base operating system has what it takes. This seems like the easiest part.

Keep the Price Point Low

Part of the reason the Portable Media Center thing never took off was the high price and big size. These things were out way before the iPod, but they were big, expensive beasts. iPod took off because it was cheap and tiny. The best way to do this is probably through - you guessed it - incremental upgrades, Microsoft's bread and butter. The best way to keep the price point of electronics low is by taking advantage of economies of scale, and to do that you need marketshare. This makes the Zune 1.0 (price and features) make a lot more sense, if you look at it as the first version of a 10+ year strategy - its primary goals need to be in building the market base, and building the store selection (which is best done with a demonstrated marketshare).

Keep the music companies on board

Apple and Microsoft don't add DRM to their products because they want to, they do it to get the music companies to provide the music for their stores. I've had plenty of exposure to the music industry to know how they work - it's all about getting the most money they can get for their investment. Forget that we all know it's futile and ignorant (the same music they wrap in DRM goes from CD to the filesharing networks without a struggle), they're playing a numbers game and trying to slow their decline by making it a pain in the neck to copy music. Fine, I buy used CD's and rip them to MP3.

So keep with me when I say that it's good for all of us if Microsoft and Apple throw the music execs a DRM bone.

Well, the hardware Zune runs on is a Trusted Platform, meaning it has a TPM crypto chip which can prevent unauthorized modification of the software. I think that's good news, as long as Microsoft plays this smart. The trick will be to open the Zune platform up enough to get developers interested, and just locked down enough to keep the music companies on board.

An extra card up Microsoft's sleeve - they don't have to advertise just how hackable the platform is. It would be great to make it officially modifiable via Visual Studio, but they can just document the parts of the platform which the music industry won't mind.

To see where the Zune will go, look at the Xbox

Well, sure, the Zune's being run by J Allard, the same guy who runs the Xbox team. I'm really talking about the general Xbox product strategy, though - get one out there to build marketshare, get a very nice follow on version, and then work on opening it up to developers.

What do you think?

Top 10 DOS Batch tips (Yes, DOS Batch...)


PowerShell's great. I'm fired up about the opportunity to use .NET objects from simple scripts. I'll admit I'm still getting up to speed with it, but I'm totally sold on PowerShell.

However, it's not installed on a lot of servers I work with, and I still do a lot of my "clumsy developer attempting DBA and network admin" tasks from DOS Batch files. You can do quite a bit with DOS Batch - the silly fact is the my most popular posts (by a huge margin) are some batch scripts to allow running IE7 and IE6 on the same computer.

So, by way of tribute to the dying art of the DOS Batch file, I present my top ten batch file tricks:

  1. Use PUSHD / POPD to change directories
    Read Scott Hanselman's writeup on PUSHD. The basic idea is that it keeps a stack, so at the simplest level you can do something like this:
    PUSHD "C:\Working Directory\" ::DO SOME WORK POPD

    That allows you to call the batch file from any directory and return to the original directory when you're done. The cool thing is that PUSHD can be nested, so you can move all over the place within your scripts and just POPD your way out when you're done.
  2. Call FTP scripts
    This sample prompts for the username and password, but they can of course be hardcoded if you're feeling lucky.
    set set set /p FTPUSERNAME=Enter FTP User Name: set /p FTPPASSWORD=Enter FTP Password: CLS > script.ftp USER >>script.ftp ECHO %FTPUSERNAME% >>script.ftp ECHO %FTPPASSWORD% >>script.ftp ECHO binary >>script.ftp ECHO prompt n :: Use put instead of get to upload the file >>script.ftp ECHO get %SITEBACKUPFILE% >>script.ftp ECHO bye FTP -v -s:script.ftp %FTPADDRESS% TYPE NUL >script.ftp DEL script.ftp
  3. Read from the registry
    You can make creative use of the FOR command to read from and parse a registry value (see my previous post for more info).
    FOR /F "tokens=2* delims= " %%A IN ('REG QUERY "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SQL Server\Instance Names\SQL" /v SQL2005') DO SET SQLINSTANCE=%%B
  4. Run SQL Commands
    You can call OSQL (or SQLCMD on servers with SQL 2005 installed) to execute SQL commands:
  5. Check if a file or folder exists
    I used this to do a quick and dirty check to see if a Windows Hotfix had been installed in my IE7 Standalone scripts:
    IF EXIST %SystemRoot%\$NtUninstallKB915865$\ GOTO KB_INSTALLED ECHO Installing Hotfix (KB915865) to allow tab support START /D "%~dp0/Installation/Update/" xmllitesetup.exe
  6. Pause execution for a number of seconds
    There are different ways to do this from within a batch file, all with their tradeoffs. I use a ping to an invalid IP address with a timeout. The best way to do this is to find an invalid IP address and then pint it, but is a pretty safe bet:
    ECHO Waiting 15 seconds PING -n 1 -w 15000 > NUL
  7. Use defaults for optional parameters
    It's not really easy to check for a missing parameter. You have to use something like "IF dummy==%1dummy", which will only be true if %1 is empty. So, for example, here we're allowing a user to supply an application path via the third parameter, and defaulting it if it's missing. By the way, beware the IF syntax. The line spacing makes a difference, so this is one that I just copy and paste to avoid figuring it out every time.
    IF dummy==dummy%3 ( SET APPLICATIONPATH="C:\Program Files\MyApp\" ) ELSE ( SET APPLICATIONPATH = %3 )
  8. Process each file matching a pattern in a directory
    I previously posted a script which iterates all files named *.bak in a directory and restores them on the local instance of SQL Server. Here's an excerpt:
  9. Use batch parameter expansion to avoid parsing file or directory info
    Batch file parameters are read as %1, %2, etc. DOS Command Extensions - available on Windows 2000 and up - add a lot of automatic parsing and expansion that really simplifies reading filenames passed in as parameters. I originally put this at the top of the list, but I moved it because I figured the insane syntax would drive people off. I wrote a simple batch script that shows some examples. I think that makes it a little more readable. Stick with me, I think this is one of the best features in DOS batch and is worth learning.

    First, here's the batch file which just echos the processed parameters:
  10. @echo off echo %%~1 = %~1 echo %%~f1 = %~f1 echo %%~d1 = %~d1 echo %%~p1 = %~p1 echo %%~n1 = %~n1 echo %%~x1 = %~x1 echo %%~s1 = %~s1 echo %%~a1 = %~a1 echo %%~t1 = %~t1 echo %%~z1 = %~z1 echo %%~$PATHATH:1 = %~$PATHATH:1 echo %%~dp1 = %~dp1 echo %%~nx1 = %~nx1 echo %%~dp$PATH:1 = %~dp$PATH:1 echo %%~ftza1 = %~ftza1

    Now we'll call it, passing in "C:\Windows\Notepad.exe" as a parameter:
    C:\Temp>batchparams.bat c:\windows\notepad.exe %~1 = c:\windows\notepad.exe %~f1 = c:\WINDOWS\NOTEPAD.EXE %~d1 = c: %~p1 = \WINDOWS\ %~n1 = NOTEPAD %~x1 = .EXE %~s1 = c:\WINDOWS\NOTEPAD.EXE %~a1 = --a------ %~t1 = 08/25/2005 01:50 AM %~z1 = 17920 %~$PATHATH:1 = %~dp1 = c:\WINDOWS\ %~nx1 = NOTEPAD.EXE %~dp$PATH:1 = c:\WINDOWS\ %~ftza1 = --a------ 08/25/2005 01:50 AM 17920 c:\WINDOWS\NOTEPAD.EXE

    As I said, the syntax is completely crazy, but it's easy to look them up - just type HELP CALL at a DOS prompt; it gives you this:

    %~1 - expands %1 removing any surrounding quotes (")
    %~f1 - expands %1 to a fully qualified path name
    %~d1 - expands %1 to a drive letter only
    %~p1 - expands %1 to a path only
    %~n1 - expands %1 to a file name only
    %~x1 - expands %1 to a file extension only
    %~s1 - expanded path contains short names only
    %~a1 - expands %1 to file attributes
    %~t1 - expands %1 to date/time of file
    %~z1 - expands %1 to size of file
    %~$PATH:1 - searches the directories listed in the PATH environment variable and expands %1 to the fully qualified name of the first one found. If the environment variable name is not defined or the file is not found by the search, then this modifier expands to the empty string

    The modifiers can be combined to get compound results:

    %~dp1 - expands %1 to a drive letter and path only
    %~nx1 - expands %1 to a file name and extension only
    %~dp$PATH:1 - searches the directories listed in the PATH environment variable for %1 and expands to the drive letter and path of the first one found.
    %~ftza1 - expands %1 to a DIR like output line

    In the above examples %1 and PATH can be replaced by other valid values. The %~ syntax is terminated by a valid argument number. The %~ modifiers may not be used with %*

  11. Learn from the masters
    By far, my favorite resource for DOS Batch trickery is the Batch Files section of Rob van der Woude's Scripting Pages. He's got some good PowerShell resources, too.

What about you? Got any favorite DOS Batch tricks?

Data Dictionary Creator 1.2 is out on CodePlex

We just released Data Dictionary Creator version 1.2 to CodePlex. Version 1.2 adds a lot of great features:

  • Added documentation of tables as well as columns
  • Changed Excel export from HTML based to XMLSpreadsheet to support separate worksheets for Table and Column documentation
  • Improved error handling - detection of non-DBO logins, etc.
  • (UI) - tab reorganization to fit workflow a little better
  • (UI) - moved feedback and progress bars to statusbar for consistency
  • Support for SQL 2000 and 2005 export scripts (there were several breaking changes from 2000 to 2005)
  • Limited import functionality (SQL and XML)
  • Added an Installer

DDC is a nice utility to help you document your databases. Even if that kind of thing doesn't appeal to you, you might want to check out the code if you're at all interested in using SQL Server Managment Objects (SMO) or saving data to multiple formats (Word via WordML, Excel SpreadsheetML, HTML) using XSLT.

Thanks to Ben Griswold (a.k.a. JohnnyCoder) who made this release possible, or at least kept it from being really crappy. Ben's been cleaning up my coding messes at three different jobs over the past nine years, and I was very happy to have his help for this release. Thanks, Ben!

Let me know if you'd like to contribute, or if you've got any ideas for making DDC better (I think the next big feature to be added is an import from Excel, but what do I know?).

I set up a walkthrough on the DDC Codeplex site, check it out!



You didn't check it out, did you? I thought you might not. No matter, I'm copying it below:

Documenting databases is fun again!

No, not really. But a least it's not a complete waste of time. Unlike those data documents you've written in the past, this one lives with your database (in SQL Server Extended Properties) so it stays up to date. Follow along and we'll show you how easy it is to create useful documentation for that good old Northwind database...

Make a connection

The first step is to connect to a database. You can enter a connection string or click on the "..." button to view the standard data connection dialog.

Hit the ground running - get advanced!

You can breeze right by the next tab (Advanced Settings) if you'd like, but it's got some neat gizmos that could save you some time. The two big features:
  • Auto-Fill - this looks at you schema and adds descriptions for primary and foreign keys. You can customize the text these use.
  • Additional Properties - By default, you're only filling in a simple "Description" tab. If you'd like add other columns to your documentation, you're going to want to look at Additional Properties.

Document that DB

Did you think we were going to do it for you? Nope! But we'll help:
  1. The user interface shows you column names and datatypes to help you remember what all those columns are used for.
  2. The datagrid lets you move around pretty quickly
  3. Your work is saved immediately, so you can work on it as time permits. Your edits are saved with the database.

Show off!

Now that you've documented your database, you can export it to share with others. There are two ways to share it:
  1. Documentation formats (Word, Excel, HTML)
  2. Importable formats (T-SQL, XML) - these let other users import your documentation into their copy of the database


Here's what the export looks like in Excel. Note that the Table and Column documentation are on separate worksheets. Feel free to pick your favorite AutoFormat to pretty this up.


Here's the HTML export:



The next two formats are importable. The T-SQL export can be executed via Query Analyzer / SSMS, or it can be loaded by DDC.


Here's the XML format. The only reasons you'd want to use this are to import into another copy of the database via DDC, or to export to another format. All file exports actually start with XML and go through an XSL transform. You can check out the XSL folder and modify any of these, or create your own.


Copy that documentation with Import

You can use the Import tab to load previously exported documentation. Browser for a T-SQL or XML export from DDC. We do a few checks to make sure the file was created by DDC, then load the documentation into the currently connected database.

Mono 1.2 Released

Novell released Mono 1.2 at TechEd today. The main feature of 1.2 is support for System.Windows.Forms. The roadmap and previous releases indicate that 1.2 has a lot of other cool features, but it's hard to tell exactly what they are since the release notes apparently aren't available yet. UPDATE: The release notes are now available.

I even dug through the repository, but couldn't find any release notes. I'm sure it's just a matter of time. Until then, the release announcement on the Mono site says:

Mono 1.2 has been released.
Go to the downloads page to get a copy.


There are some high level articles on eWeek and wwwCoder which parrot a press release, indicating Mono 1.2 has these features:

  • Support for the Microsoft Windows Forms API to more easily port .NET client-side applications to Linux.
  • Virtual machine upgrades
  • Enhanced Java support
  • Significant performance, memory consumption and stability improvements
  • Support for many .NET 2.0 features (seems like mostly generics support)

I get the feeling that the release was a little rushed to allow for an announcement at TechEd, and the docs aren't up to date. The Mono roadmap indicates the 1.2 release was supposed to have the following:

The Mono team is developing in parallel some features that wont make it to the 1.0 release in stable form. These will be the foundation for the 1.2 release. The focus of this release is to track the core API for the .NET Framework 2.0, but again, only a subset of the total framework will be available.

Mostly, Mono 1.2 consists of components that were not stable enough for Mono 1.0, but that would be mature at this point, plus the incorporation of some new features from Whidbey. In addition to the Mono 1.0 components, this release will add:

  • Generic types support: C# compiler, execution system and core class libraries (C# 2.0) 
  • System.Windows.Forms 1.1 support (Track Progress) 
  • Mono Debugger 
  • gtk# 2.0 (includes support for gtk 2.6)
  • New platforms: ARM, Itanium, s390, s390x.
  • Numerous scalability and performance enhancements

Mono 1.2 will also include assemblies from Whidbey (.NET 2.0) available as technology previews:

  • XML 2.0 (Track Progress)
  • ASP.NET 2.0 (Track Progress)
  • ADO.NET 2.0
  • Most of mscorlib and System.dll
  • Console and Serial ports support

I've been pretty impressed with Mono's winform support since the 1.1.8 release, so I'm looking forward to seeing how much better 1.2 is.

Code Puzzle #1 - Solution

If you haven't read the puzzle, you can read more about it on my previous post.

The questions:

    1. (Answer this first) Take a guess - how many numbers do you think there are between 1 and 1 million that are divisible by their reverse. Any? Fifty? A thousand?
    2. Write a program to find the answer. I use C#, but feel free to use any programming language you'd like.
    3. If you use .NET, you may run into a limitation in the framework that's a little surprising.1 What is the limitation?

A few rules:

    1. We don't count numbers which are palindromes. Of course 42124 is divisible by 42124, but where's the fun in that?
    2. We don't count numbers which end in 0, since their reverse will drop the zero and that's not what I'm looking for. If we didn't have that rule, we'd have to deal with things like 2000 -> 0002, which only works because we'd drop the leading zeros. Lame.

We had some great feedback and answers in the comments - of course some of the answers were better than mine.

My Solution:

1. Take a guess - how many numbers do you think there are between 1 and 1 million that are divisible by their reverse. Any? Fifty? A thousand?


8712 is divisible by 2178
9801 is divisible by 1089
87912 is divisible by 21978
98901 is divisible by 10989
879912 is divisible by 219978
989901 is divisible by 109989

In case you're curious, there are 6 more between 1 million and 100 million:

8799912 is divisible by 2199978
9899901 is divisible by 1099989
87128712 is divisible by 21782178
87999912 is divisible by 21999978
98019801 is divisible by 10891089
98999901 is divisible by 10999989

2. Write a program to find the answer. I use C#, but feel free to use any programming language you'd like.

Here's my solution; there were some other solutions in the comments that gave the same results.


using System; public class NeverOddOrEven { public static void Main() { for(int i=1;i<1000000;i++) { if(i % 10 != 0) //Ignore numbers which end in 0 { int reversed = int.Parse((ReverseUsingCharArrayInline(i.ToString()))); if(i != reversed && i % reversed == 0) //Ignore palindromes Console.WriteLine("{0} is divisible by {1}", i, reversed); } } Console.WriteLine("Done"); Console.ReadLine(); } //via private static string ReverseUsingCharArrayInline(string input) { char[] reversed = new char[input.Length]; for(int i = 0, j = reversed.Length - 1; i <= j; i++, j--) { reversed[i] = input[j]; reversed[j] = input[i]; } return new String(reversed); } }

I'm not sure how to grade this question - I'd say it's a pass / fail, but that's just because some of the solutions were better than mine (grin). Alexander Neumer gave the fastest solution, since it does the reverse function numerically rather than converting to strings:

While n > 0 rev = rev * 10 + (n Mod 10) n = n \ 10 End While

Hmm, I guess I might have tried that if I hadn't made an incorrect assumption about the .NET framework...

3. If you use .NET, you may run into a limitation in the framework that's a little surprising. What is the limitation?

I planned to bang this out in a few lines by converting the int to a string, reversing the string, and converting to int:


 Not blazing fast, but it gets the job done. That is, it would if the string class had a Reverse() method. Doh! Justin Rogers had a great comparison of functions which reverse strings a while ago; some of his commenters dug into unsafe code and made it much faster. Mike Mestemaker informed me that VB.NET has a strReverse() function that works well, but Alexander Neumer's solution kept it simple by staying away from strings altogether.

Thanks for playing! We're still waiting on our resident mathematician to explain the interesting patterns in the result; anyone else want to jump in?

Code Puzzle #1 - What numbers under one million are divisible by their reverse?

The other day I got stuck waiting in a slow line at the store all hopped up on espresso and breakbeat, so I started trying to think of numbers which are evenly divisible by their reverse. Example: If 721 were divisble by 127, I'd have a match. Yes, I'm aware this is not normal behavior.

I quickly convinced myself that there were no numbers like that under 1000, but I was sure there had to be some higher numbers like that. Seemed like a pretty simple thing to figure out with a few lines of code, which I did once I got home. As I recently discussed with Phil, I think that sort of thing is a lot more interesting as a quiz then a boring post with a block of code, so here it is.

I'm giving this quiz a difficulty rating of: Easy Peasy

First, some simple ground rules:

  1. We don't count numbers which are palindromes. Of course 42124 is divisible by 42124, but where's the fun in that?
  2. We don't count numbers which end in 0, since their reverse will drop the zero and that's not what I'm looking for. If we didn't have that rule, we'd have to deal with things like 2000 -> 0002, which only works because we'd drop the leading zeros. Lame.

Now, the quiz:

  1. (Answer this first) Take a guess - how many numbers do you think there are between 1 and 1 million that are divisible by their reverse. Any? Fifty? A thousand?
  2. Write a program to find the answer. I use C#, but feel free to use any programming language you'd like.
  3. If you use .NET, you may run into a limitation in the framework that's a little surprising.1 What is the limitation?

I made a tactical error on my recent SQL Puzzle by posting the answer immediately after the question, assuming people would still take the quiz. I was shown the error of my ways by friends who said they weren't going to bother figuring it out when the answer was right there... No honor system this time - I'll post my solution 24(ish) hours from now.

UPDATE: See my solution and recap here.

1Don't worry, you shouldn't have any problem finding some code to work around this.

More Posts Next page »