Archive for March, 2009

Sudoku Algorithm Part 1 - Filling the puzzle

Sunday, March 29th, 2009

Step one of creating a Sudoku puzzle is obviously filling in the whole 9 x 9 grid with numbers that fit the constraints of Sudoku rules:

1. Each row must contain the numbers 1 to 9.

2. Each column must contain the numbers 1 to 9.

3. Each 3 x 3 local square must contain the numbers 1 to 9.

After staring at a blank page for a few hours, I decided to see how others tackled the task of creating Sudoku puzzles.

Some  interesting pages I found were:

http://davidbau.com/archives/2006/09/04/sudoku_generator.html

http://www.sudokuonline.us/make_your_own_sudoku_puzzle.php

http://ostermiller.org/qqwing/

http://www.codeproject.com/KB/recipes/Abhishek_Sudoku.aspx

The last link is the one that sparked an idea for my own algorithm. In broken English the author attempts to explain how he wrote his program. I misinterpreted parts of his article, but it created a few good ideas to start my own Sudoku algorithm.

To fill the Sudoku grid, I use what I term a 9 x 9 Potential Array. What each cell in the Potential Array holds is a list of possible values that could potentially work in that cell based on Sudoku rules.

With a blank 9 x 9 Sudoku grid, each cell in the Potential Array must be (1..9) as there are no limitations yet.

I then go through every cell in the Potential Array looking for a list that only contains one number. If it contains one number, that cell in the Sudoku Game Array MUST become that number.

If there are no lists in the Potential Array containing a single number, then we find an empty cell in the Sudoku Game Array. In the corresponding Potential Array, we choose one of the numbers in the Potential list for that cell and place it in the Sudoku Game Array.

Each time we set a value in the Sudoku Game Array, we must recalculate the Potential Array based on the values placed in the Sudoku Game Array. For example, if there is a 7 in row 2, there can be no other 7’s in the rest of the row. Therefore the all the Potential Array lists for row 2 will be stripped of the number 7. The same holds true for the cells column and the local 3 x 3 square that the cell resides in.

If we find a list in the Potential Array that contains NO values, then our attempt at filling the Sudoku board has failed, and we must start again.

Using this method finds a workable Sudoku grid between 1 to ten try’s on average.

The next article will cover the task of removing numbers from the Sudoku Game Array so we can have a Sudoku puzzle with only one possible solution.

Filter on a TClientDataSet

Saturday, March 14th, 2009

Filtering on a TClientDataSet is very powerful.

For the longest time I had assumed that there was no way to filter on a field that had a field name with a space in it!

I would try the following:

Table1.Filter:= ‘My field = ‘ + #39 + ‘looking for’ + #39;

And Delphi would squawk that the field ‘My’ did not exist.

I tried to place quotes around the field name. No error occurred, but the filter did not work.

After a long search I came upon a poorly documented fact that square brackets around the field name work in the TClientDataSet filter!

Table1.Filter := ‘[My field] =’ + #39 + ‘looking for’ + #39;
Table1.Filtered := True;

Bring your Application to the top of the screen in Windows

Thursday, March 12th, 2009

I program in Delphi for the Windows environment, but the following should work in most modern programming languages with slight modifications.

Since Windows 98, the standard BringToFront() function no longer has the same power. When called, your application’s window remains where in is in the z-order, and the task button flashes.

I was asked to make our Emojic Text Editor have a Stay On Top feature.

The following event routine for a CheckBox was created:

procedure TMainForm.StayOnTopClick(Sender: TObject);
begin
Application.NormalizeTopMosts;
If StayOnTop.Checked then
begin
SetWindowPos(MainForm.Handle, HWND_TOPMOST, 0,0,0,0, SWP_NOACTIVATE+SWP_NOMOVE+SWP_NOSIZE);
end
else
SetWindowPos(MainForm.Handle, HWND_NOTOPMOST, 0,0,0,0, SWP_NOACTIVATE+SWP_NOMOVE+SWP_NOSIZE);
end;

That worked great until my application tried to save and open it’s own Modal Form. Then my Modal Form was locked away and inaccessible under my Topmost window.

So I placed the following around every set of instructions in each of my MenuItem’s Event routines:

procedure TMainForm.SaveMenuItemClick(Sender: TObject);
begin
SetWindowPos(MainForm.Handle, HWND_NOTOPMOST, 0,0,0,0, SWP_NOACTIVATE+SWP_NOMOVE+SWP_NOSIZE);
SaveFile;
StayOnTopClick(self);
end;

Basically I just turn the Stay On Top feature off until the Event is done, then I check to see if I intend to set the Stay On Top feature back on.

Internet Security

Sunday, March 8th, 2009

The internet is a dangerous place. Every computer on the internet has the potential to connect, or communicate,  with every other computer on the internet.

If your computer becomes infected with a Virus, Trojan or Worm your PC could be used to send spam, launch attacks or commit other crimes. Your keystrokes can even be monitored remotely, thereby sending your user names and passwords to a criminal. If you do internet banking or hold sensitive data on your computer you should be alarmed.

There is no such thing as 100% safe on the internet. New security breaches are found every day. Today’s Operating Systems and software are so complex that total security is impossible.

Check some of your vulnerabilities at:

https://www.grc.com/

Click on the ‘Shields Up’ link.

Then click ‘Proceed’.

Then click on ‘All service ports’.

This will tell you how well your firewall, assuming you have one,  is doing for incoming traffic.

Now that you are scared….

You can minimize your risk of infection by applying the following recommendations. The more you follow, the safer you will be.

1. Keep up with your Operating Systems patches. With a Microsoft OS, just ensure that Automatic Updates is turned on.

2. At the very least use a software firewall. Zone Alarm offers a free software firewall or you can purchase their more comprehensive version. If you can’t stand the alerts generated by a product such as Zone Alarm, turn on the Windows firewall. Make sure any ‘exceptions’ under the exceptions tag, were put there by you. Better yet, purchase a hardware based firewall. If you are on a budget, you can get a home based router/firewall for $50.

3. Use virus software. Make sure you keep it enabled and the virus definitions up to date. Too often I see computers riddled with viruses and see that they have disabled their virus software. AVG has both free and commercial virus software.

4. Do not use peer to peer networks. (BearShare, Kazaa, Napster, BitTorrents)  Everyone loves swag. But guess what, most of the stuff you find there is riddled with viruses and trojans. Not to mention that most file sharing is illegal. Peer to Peer technology connects your PC  to multiple unknown sources. Any one of those sources, now knows your IP address, knows you are there, and can launch an attack.

5. Download (pay for) and use software only by trusted sources. If you download drivers, virus software, bible software, key generators, etc from a smaller unknown source it may be loaded with a virus, worm or trojan. The most likely platform is key generators. Hackers write key generators then infect it with a virus. They know that greed and stupidity will overrule honesty and caution in most cases. You are going to get more than a free license key code for your favorite software. In one instance, I downloaded some bible freeware which also acted as an attack platform. In another instance I removed dozens of viruses off a friends computer on Friday. During the weekend he installed a no-name firewall program from a suspicious source. It was infected. He brought it back on Monday riddled with trojans and viruses.

6. Know what your kids are doing on the computer at ALL times. We were all young and stupid. Even if your kid is a prince or princess, you still need to ensure that they do not download and install programs, visit porn or hacking sites (a great way to get a computer virus).

7. Augment your virus software with Adaware (free version available). It picks up the things virus software might miss.

8. Make sure your log in user name for your Operating System (OS) has a corresponding password. No blank passwords. It is just one more locked door for someone to get through. Use strong passwords. Not your dogs name, Fluffy.

9. Turn off ‘remote assistance’ and ‘remote desktop’ on your PC.

10. For small businesses, NEVER put client information on an internet PC. We ordered books online from a small mom and pop internet books store. Within the week someone ordered books with our credit card from Thailand.

11. Use a CD or DVD bootable OS to surf the net like Knoppix. This is not the solution for everyone, but it is one of the safest ways to surf the internet.

12. Turn file shares off. One more door to close.

This is not an exhaustive list, but they are some of the easiest and most effective ways to prevent an intrusion. Remember, you can never prevent an attack.

Add your own suggestions and comments.

mod_rewrite for apache

Saturday, March 7th, 2009

I had a written some code to generate dynamic images on our website. I soon discovered that my images were not being listed in Google’s image section.

The following URL generates the required image:

http://www.somewhereincanada.com/barcode/barcode.php?code=001600064300&mode=gif

However, when I tried to save it to my desktop it saves it as barcode.php.png . Google will not list it in it’s image section as ‘barcode.php?code=001600064300&mode=gif’ is not a valid name for an image file.

One solution was to have my script save the generated image to my server. Then I could redirect web browser’s to the generated image by returning the text:

<META HTTP-EQUIV=”Refresh” CONTENT=”0; URL=/barcode/images/001600064300.gif”>

But by doing that I am using up valuable space on our web host.

It would be nice if I could have the URL:

http://www.somewhereincanada.com/barcode/images/001600064300.gif

call my script and dynamically generate the image.

This is possible by using Apache’s Module mod_rewrite.

By using mod_rewrite, I can cause the previous URL to call the script barcode.php

See:

http://www.workingwith.me.uk/articles/scripting/mod_rewrite

for more information.

To see mod_rewrite in action, try replacing any of the digits in the following URL with another. Likewise try replacing .gif with .jpg or .png

http://www.somewhereincanada.com/barcode/images/001600064300.gif

Now Google will see links of this format as actual images on my site and index them.

To make it all work, the following was required:

In an .htaccess file in our /barcode/ directory is the following text:

<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /barcode/images/
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /barcode/barcode.php [L]
</IfModule>

The previous .htaccess file tells Apache to turn web requests for:

/barcode/images/001600064300.gif

to

/barcode/barcode.php

Note that the folder ‘/barcode/images/’ does not even exist.

http://www.somewhereincanada.com/barcode/images/hjgksad/asd/asd/001600064300.gif

will generate an image also!

On my first attempt, I added the following code to barcode.php. It strips out the ‘001600064300′ and ‘gif’ parts from

/barcode/images/001600064300.gif

found in the PHP variable $_SERVER["REQUEST_URI"]. Then took those two values and fed them into the routines that would have normally obtained the values from

?code=001600064300&mode=gif

if ($code == ”)
{
$URIline = $_SERVER["REQUEST_URI"];
//split uri into parts
$urlparts = array();
$urlparts = split(”/”, $URIline);
//get last part image.jpg
$imagename = array_pop($urlparts);
$filenameparts = array();
$filenameparts = split(”\.”, $imagename);
$code = $filenameparts[0];
$mode = $filenameparts[1]; //file extension
if ($mode == ”)
{
$mode=’png’;
}
}

If you are comfortable with Regular Expressions, there is a better way to accomplish this.

I could have used mod_rewrite to turn:

http://www.somewhereincanada.com/barcode/images/001600064300.gif

directly into a call to:

http://www.somewhereincanada.com/barcode/barcode.php?code=001600064300&mode=gif

Then I would not have had to modify barcode.php

Here is how I obtained the same results by using Regular Expressions in .htaccess:

<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /barcode/images/
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ([0-9]+)\.([a-zA-Z]+)$ /barcode/barcode.php?code=$1&mode=$2 [L]
</IfModule>

Apache staff say mod_rewrite is difficult to master. So keep it simple.

http://httpd.apache.org/docs/1.3/mod/mod_rewrite.html