Sunday, July 10, 2011

Generating Permutation with Javascript

I got hit by an interesting problem of “Zebra Puzzle” the other day. It is a well known logic puzzle believed to be first invented by Albert Einstein.

The question here is, how do we use our favorite programming language to solve this problem?

The first obstacle I found is that we need to generate all permutation of given list. Say if we have [1,2,3], we have a total of 3! = 6 which are [1,2,3], [1,3,2], [2,1,3], [2,3,1], [3,1,2], and [3,2,1]. I couldn’t find simple Javascript code for this so I ended up writing one. Reinventing the wheel is fun, isn’t it? :))

Wikipedia suggests the following algorithm for generating all permutation systematically.

The following algorithm generates the next permutation lexicographically after a given permutation. It changes the given permutation in-place.

  1. Find the largest index k such that a[k] < a[k + 1]. If no such index exists, the permutation is the last permutation.
  2. Find the largest index l such that a[k] < a[l]. Since k + 1 is such an index, l is well defined and satisfies k < l.
  3. Swap a[k] with a[l].
  4. Reverse the sequence from a[k + 1] up to and including the final element a[n].

Here is my PermutationGenerator module implemented in Javascript.

/////////////////////////////////////////////
// Permutation Generator
// - generate all permutation of given string
// array
// - Natthawut Kulnirundorn <m3rlinez at email by google>
// http://www.solidskill.net 10 July 2011
/////////////////////////////////////////////

var PermutationGenerator = (function () {
var self = {};

// Get start sequence of given array
self.getStartSequence = function (list) {
return list.slice(0).sort();
};

// Get next sequence from given array
// Ref: http://en.wikipedia.org/wiki/Permutation#Systematic_generation_of_all_permutations
self.getNextSequence = function (list) {
// Make clone
var a = list.slice(0);

//The following algorithm generates the next permutation lexicographically after a given permutation. It changes the given permutation in-place.
// 1. Find the largest index k such that a[k] < a[k + 1]. If no such index exists, the permutation is the last permutation.
var k = -1;
for (var i = 0; i < a.length - 1; ++i) {
if (a[i] < a[i + 1]) { k = i; }
}
if (k == -1) return null; // means this is the last one

// 2. Find the largest index l such that a[k] < a[l]. Since k + 1 is such an index, l is well defined and satisfies k < l.
var l = -1;
for (var i = 0; i < a.length; ++i) {
if (a[k] < a[i]) { l = i };
}
if (l == -1) return null; // impossible

// 3. Swap a[k] with a[l].
var tmp = a[k]; a[k] = a[l]; a[l] = tmp;

// 4. Reverse the sequence from a[k + 1] up to and including the final element a[n].
var next = a.slice(0, k + 1).concat(a.slice(k + 1).reverse());

return next;
};

return self;
} ());





Test cases, also serve as a user guide :)



/////////////////////////////////////////////
// Test Cases
/////////////////////////////////////////////

var PermutationGeneratorTest = (function () {
var self = {};

function getStartSequence_Test1() {
var a = ['red', 'white', 'green', 'yellow', 'blue'];
var res = PermutationGenerator.getStartSequence(a);
log('input = ' + a);
log('output = ' + res);
}

function generateSequence(list) {
var current = PermutationGenerator.getStartSequence(list);
var count = 1;
log('start = ' + current);
while (true) {
current = PermutationGenerator.getNextSequence(current);
if (current == null) { break; }
log('next' + (++count) + ' = ' + current);
}
}

function getNextSequence_TestNormal() {
generateSequence(['English', 'Spanish', 'Japanese']);
}

function getNextSequence_TestEmpty() {
generateSequence([]);
}

function getNextSequence_TestRepeat() {
generateSequence(['gant', 'gant', 'korkore', 'jan']);
}

self.runTests = function () {
log("=== getStartSequence 1 ===");
getStartSequence_Test1();
log("=== getNextSequence Normal ===");
getNextSequence_TestNormal();
log("=== getNextSequence Empty ===");
getNextSequence_TestEmpty();
log("=== getNextSequence Repeat ===");
getNextSequence_TestRepeat();
};

return self;
} ());







I have put the working example on http://www.solidskill.net/ZebraPuzzle.htm. There are other parts of code that search through the solution space, setup the constraints for Zebra puzzle. But they are not discussed here.



There are some things to note about this implementation though. First, it is not very efficient. You can see in the getNextSequence(..) loop that there are loops used to search for k and l that satisfy the conditions.



Second, there could be problem with list of integers. The Array.sort() in Javascript sort using string interpretation by default. So [4, –1, 100, 500].sort() would return [-1, 100, 4, 500] instead of expected [-1, 4, 100, 500]. One must give Array.sort() function the comparer in order to properly sort list of integer. I design this module to work with list of strings initially.



Hope this helps those who are looking for permutation generation code.

Sunday, January 9, 2011

Seagate GoFlex TV “Logon Failed”

goflex_tv_screen_320x340

I just recently got my hands on Seagate’s GoFlex TV. In combination with my existing 32” LG TV, this device would allow the playbacks of the movie files, in so many supported formats, from the USB storage device directly to my 1080p TV. This sounds very perfect to me as I often find it’s not very easy to turn on my desktop PC just to watch movies. The device comes with LAN adapter which allows it to connect to your home network, and view YouTube, Picasa, or playback from network’s shared folder. Moreover, to my surprise, it also supports USB keyboard! This was beyond my expectation.

Enough for the introduction.

Playing back from USB storage was fine and good, and it works nicely with my Buffalo portable HDD out of the box. The real pain kicks in when I tried to play my *.mkv file sitting on my Windows 7 PC’s shared folder. The GoFlex keeps asking for username and password which I entered numerous times over few hours, and without success. It keep showing “Logon Failed” message on the screen! This is pretty annoying.

Search from Google didn’t give much help, but the search on Seagate’s user forums itself revealed a thread containg instructions which fix the problem! Original post at http://forums.seagate.com/t5/FreeAgent-Theater/FREEAGENT-A-Guide-to-get-the-most-out-of-your-FAT/td-p/48382

WINDOWS 7, NETWORK PROBLEMS:

So, you have Windows 7, but you can't get your FAT+ to log on to the network.  Well here's some instructions to help you get around that:

 

First go to the Control Panel, then select Network & Sharing Center, then on the left pane select "Change advanced sharing settings".

  • Then select in the settings:
  • Turn on network discovery
  • Turn on file & printer sharing
  • Turn on sharing so anyone with network access can read & write files in the Public folders
  • on Media Streaming  (I'll come back to that)
  • Enable file sharing for devices that use 40 -or 56-bit encryption
  • Turn off password protected sharing
  • Now make sure you have the same setting for both Home or Work & Public profiles
  • For the Media Streaming, select "Chose media streaming options...",  the on the "Show devices on:" dropdown box select "All networks".  You should then see something that says "Unknown Device", make sure that it has "Allow" beside it.

 

IF that doesn't work, try this:

 

Click Start and type Regedit in the search and click Regedit.exe
Navigate to the following location in the registry editor.


HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\

1. On the right side Double Click on everyoneincludesanonymous and in the window that pops up, change the value data from a 0 value to a 1

2. Double Click on NoLmHash and in the window that pops up, change the Value Data from a 1 value to a 0

3. Now navigate to the following location in the registry editor
HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters


Double Click on restrictnullsessaccess and change the 1 value to a 0

Reboot your pc and you should now be able to connect to your pc from you Freeagent Theater+

This works for me, I also have my drives shared with full access on my LAN

You will still see the Login screen  just click OK and you should have access to your drives.

(Originally submited by ColinK)

This should also work with Vista.

Here a link for WINDOWS XP network problems.  (Give a few Kudos to bodhi78 for this one)

This took so much time from me that I would like to share this with other GoFlex TV users. I lived happily, enjoyed 1080p, the last 12 hours ever since the fix :)

Thursday, May 28, 2009

DLL problem with Wise Installation System and 8.3 filenames

This is from one the action item I deal with at the workplace. The user can install our software but when he tried to use one of the functions, the Visual Basic 6.0 application shows a message box indicating “Automation error.” This is a well-known Windows DLL problem which can be fixed easily using regsvr32 MyDLL.dll command. But I have to dig into the reason why the installer can’t get it job done correctly on the customer’s machine.

From what I known, the installer is created with Wise Installation System. I don’t know the precise version the development team used. But there is a known issue floating around the internet about the installer’s incompatibility problem with systems that disabled the generation of 8.3 filename.

I tried to reproduce the problem at work. The steps started with fresh installation of Windows Server 2003 and running fsutil behavior set disable8dot3 1 command. You can also check the current value of disable8dot3 by fsutil behavior query disable8dot3.The important thing to note that you have to restart the machine once for this changes to make effect.

After that, I installed the product. And the problem is reproduced! The fix is easy. Just uninstall the software, set disable8dot3 option to 0, restart, reinstall, and everything works!

The disable8dot3 option is set to 0 on a default installation of Windows. But there is a well-known tweak to disable this 8.3 name generation to improve directory browsing performance. This would break the Wise installer from working correctly.

I can’t reproduce the issue in the first place because I don’t know I have to restart the machine :(