Today we mark 100 years since the Tunguska explosion that occurred near the Podkamennaya Tunguska River, Russia. The energy blasted from the explosion is estimated to 5 to 30 megatons, with 5 to 15 the most likely. It wiped out an estimated 80 million trees on 2150 squared kilometers.

The cause of the explosion, is, most likely, the burst of a meteor or comet into the air. According to Boris Shustov of the Russian Academy of Sciences:

We know that a rather massive body flew into the atmosphere of our planet. It measured 40 to 60 meters in diameter. Clearly, it did not consist of iron, otherwise it would have certainly reached the earth. The body decelerated in the atmosphere, the deceleration being very abrupt, so the whole energy of this body flying with a velocity of more than 20 [kilo]meters per second was released, which resulted in a mid-air explosion, very similar to a thermo-nuclear blast.

The yield of the explosion totaled 10 to 15 megatons, which matches the yields of the largest hydrogen bomb ever tested on the planet. The explosion felled some 80 million trees and caused natural phenomena. It is generally assumed that the blast did not kill any people.

Of course, there are other theories about the cause of the explosion:

  • UFO crash; sometimes the Tunguska event was called the Russian Roswell incident; though claims of a spaceship debris recovery were made, they have not been proved.
  • The annihilation of a chunk of antimatter from space
  • A black hole zipping through Earth.
  • a “death ray” generated by Nikola Tesla. One story says that he tested a death ray on the eve of June 30. Once he heard of the event at Tunguska he dismantled the weapon, considering it too dangerous.

Whether a natural event, UFO crash, weapon test or something else, the event is far from being explained, and most likely, more theories will come over the decades.

Hits for this post: 8460 .

Today is the last day for Bill Gates as executive president at Microsoft. Some months ago he released this clip about him looking for a new job.

The ending words from a news presenter are quite funny too.

And all tech markets remain steady as Bill Gates completed his last full day at Microsoft. Personal note: all of us here at NBC news will miss reporting every night on this brilliant, powerful, let’s face it, sexy and good looking leader of men and women who just doesn’t believe in paying more than $7 for a haircut.

Hits for this post: 8717 .

Manning Publications, for which I reviewed a couple of books, opens today a promotion called .NET Daily Drawing, that will be available until July 17th. During this time they are giving away one free .NET e-book each day and a final grand prize consisting of a Manning .NET Library. If you want to take part in the drawing, you have to register here.

.NET Daily Drawing

Hits for this post: 7184 .

I am using Visual Studio for many years, but I have to admit this came as a total surprise: the Find combo box in Visual Studio is more than just what the name says.

Find Combo Box

Besides searching for files, you can use it for opening files, creating new files, setting breakpoints (in a smart way), going to a line, getting help, editing lines, and many, many others. You can do all these by typing ‘>’ followed by a command name and a space and then additional values.

For instance, if you want a quick finding of files, you can type >of filename and it will show in the combo all the files that match the typed string.

Quick Find Files

Another example: if you want to jump to line 250 in the currently opened file type >GotoLn 250.

This blog post describes several other commands such as opening and creating files and setting breakpoints. The list of all available commands is available in MSDN.

Hits for this post: 8662 .

I was pointed recently to this tool from CodePlex, called .NET Mass Downloader. Earlier this year Microsoft released (partially) the source code (with symbol files) for the .NET framework (version 2.0, 3.0 and 3.5). Visual Studio 2008 however downloads these files on-the-fly, as they are needed. This tool allows you to download all sources and use them off-line in Visual Studio 2008, Visual Studio 2005 and Codegear Rad Studio.

Hits for this post: 8009 .

I recently found an interesting problem on the web, about reducing words, letter by letter until only one letter remains. Here is a formal definition:

We define word reduction as removing a single letter from a word while leaving the remaining letters in their original order so that the resulting sequence of characters is also a word. A good word can be reduced step-by-step until all that is left is a or i. Your program will answer the question: what is the biggest word in the given dictionary that can be reduced?

A typical example, not very long is this:

planets
plants
pants
pant
ant
an
a

So I though this could be a good exercise for F#. Several good dictionaries, both small and big, can be found here.

My approach was to read the dictionary and build a list for each word length: one for 1-letter words, one for 2-letter words, etc. This could be a Dictionary<int, list>, and let’s call it simply dictionary. Then these lists could be traversed and create a second set of lists (let’s call this reducedwords), but only with the words that meet the defined reduction.

An good approach would be to take each list of words from the initial dictionary, starting with the list with words of 2 letters, and for each word to delete one letter at a time. Then check to see if the resulting word already exists in the list from reducedwords corresponding to a length smaller with 1. If it’s there, that this word could be reduced and should be added to the list from reducedwords corresponding to the current length. In other words, the algorithm would be:

copy dictionary[1] to reducedwords[1]

for length = 2 to maxwordlength do
  foreach word in dictionary[length]
    foreach letter in word
      * delete the letter
      * if new word exists in reducedwords[length-1] then
          * add new word to reducedwords[length]

Here is a function for reading a dictionary file:

let readWords (filename:string) =
   let dictionary = new Dictionary< int, list< string > >()
   let reader = new StreamReader(filename)
   let word = String.Empty
   let fileend = ref false
   while (!fileend = false) do
      let word = reader.ReadLine()
      if word = null then
         fileend := true
      else
         let len = String.length word
         let ok, words = dictionary.TryGetValue(len)
         if ok then dictionary.[len] <- words@[word]
         else dictionary.[len] <- [word]
   done
   dictionary.[1] <- ["a";"e";"i";"o";"u"]
   dictionary

One I have the dictionary read, I can apply the algorithm and generate a second Dictionary structure. The following function also returns length of the longest word(s) in the reduced dictionary. This is useful for printing.

let findReducedWords (dictionary:Dictionary< int, list< string > >) =
   let reducedwords = new Dictionary< int, list< string > >()
   reducedwords.[1] <- dictionary.[1]

   let notdone = ref true
   let i = ref 2
   while (!notdone = true) do
      let ok, words = dictionary.TryGetValue(!i)
      if ok <> true then
         notdone := false
      else
         let added = ref false
         let ok, reducedpre = reducedwords.TryGetValue(!i - 1)
         reducedwords.[!i] <- []
         words |> List.iter (fun word ->
            for j = 0 to word.Length-1 do
               let trimmedword = word.Remove(j, 1)
               if reducedpre.Exists(fun x -> x = trimmedword) then
                  reducedwords.[!i] <- reducedwords.[!i]@[word]
                  added := true
            done;
         )
         reducedwords.[!i] <- reducedwords.[!i] |> Set.of_list |> List.of_seq
         if !added then
            i := !i + 1
         else
            reducedwords.Remove(!i) |> ignore
            notdone := false
   done

   (reducedwords, !i-1)

Since the problem is about printing only the longest such reductions, I'll only consider starting from the list of reduced words that has the longest words. That's why I needed findReducedWords to return the length of longest reducible word.

To print these paths I apply the same algorithm as before. The only difference is that I build a list with the words in the reducing path, starting with the longest word and ending with a 1-letter word.

let rec printSequence
   (word:string)
   (reducedwords:Dictionary< int, list< string > >)
   (path:list< string >) =
   match word.Length with
   | 1 ->
      path@[word] |> List.iter (fun x -> printf "%s " x);
      printfn ""
   | _ ->
      let ok, reducedpre = reducedwords.TryGetValue(word.Length-1)
      if ok then
         for j = 0 to word.Length-1 do
            let trimmedword = word.Remove(j, 1)
            if reducedpre.Exists(fun x -> x = trimmedword) then
               printSequence trimmedword reducedwords (path@[word])
         done;

let printSequences
   (reducedwords:Dictionary< int, list< string > >)
   (maxlen:int) =
   let ok, words = reducedwords.TryGetValue(maxlen)
   if ok then
      words |> List.iter (fun word ->
         printSequence word reducedwords [])

The only thing left to do is calling all these functions:

let main()=
   printfn "reading dictionary..."
   let dictionary = readWords "huge_dict.txt"

   printfn "building structures..."
   let reducedwords, max = findReducedWords dictionary

   printfn "printing matches..."
   printSequences reducedwords max

   Console.WriteLine("Press any key to continue...")
   Console.ReadKey()

main()

My results for this dictionary were:

complecting completing competing compting comping coping oping ping pig pi i
complecting completing competing compting comping coping oping ping pin in i
complecting completing competing compting comping coping oping ping pin pi i

Hits for this post: 12021 .