Thursday, August 4, 2011

The Code

Just in case you didn't know, BBC started recently a new TV series with the name "The Code". Apart from being a TV documentary, it is also a quest for the treasure hunt. Some of the questions, in this quest, are quite interesting. It's all about observing the patterns, nothing complicated.

For example, have a look at this puzzle. After about 20 minutes of looking at the pictures I came with the following solution:

For the "six-sided dice" the repeating numbers are 1,2,3. For the "eight-sided dice" the repeating numbers are 1,2,3,4. It looks like these numbers generate the others.

1. For the first "six-sided dice" - 1,2,3 generate 2,3,4
2 = 1 + 11
3 = 1 + 21
4 = 1 + 31

2. For the second "six-sided dice" - 1,2,3 generate 2,5,10
2 = 1 + 12
5 = 1 + 22
10 = 1 + 32

3. For the third "six-sided dice" - 1,2,3 generate 2,9,28
2 = 1 + 13
9 = 1 + 23
28 = 1 + 33

4. For the first "eight-sided dice" - 1,2,3,4 generate 2,3,4,5
2 = 1 + 11
3 = 1 + 21
4 = 1 + 31
5 = 1 + 41

5. For the second "eight-sided dice" - 1,2,3,4 generate 2,5,10,17
2 = 1 + 12
5 = 1 + 22
10 = 1 + 32
17 = 1 + 42

Now, following this pattern...

6. For the third "eight-sided dice" - 1,2,3,4 generate
1 + 13 = 2
1 + 23 = 9
1 + 33 = 28
1 + 43 = 65

And the answer is: 65

Friday, July 22, 2011

JavaScript to become a new technology stack?

Last month I mentioned about the Microsoft's effort towards HTML5 and JavaScript adoption. This month I have more interesting news :) ... JavaScript is about to become a new technology stack.

For example:

1. Do you need a cloud IDE for JavaScript coding? No problems, see cloud9ide.com. Code and host your code.

2. Do you need server side JavaScript? No problems use node.js. This is a "tool" pretty much like Java (i.e. compile and execute - JIT). It integrates perfectly with WebSockets and WebWorkers added as part of HTML5.

3. Do you need anything more complex (e.g. enterprise oriented)? Use services like Wakanda, it even has a built in data store. Alternatively, use MongoDB (JSON storage) with node.js.

To conclude, it is possible to build quite complex web, mobile, desktop (in terms of HTML5 offline apps) applications using just JavaScript.

Sunday, July 10, 2011

Sudoku game or humans vs. machines (computers in this case)

Few days ago, a friend of mine posted the following link on his wall on Facebook. The main question from that article was "how long will it take to crack ...the world's hardest Sudoku?". I felt like being challenged.

I am not a Sudoku fan, however my wife and my son are. Just to annoy them (not because I am a bad person :), but because I was looking for a way to sort the Sudoku puzzles in a quicker way, when being asked to assist them ... so, "I am lazy" is a more precise definition) and because I am a software engineer, I wrote a long time ago (of course I was inspired, it's not entirely my contribution) a little piece of Java code to resolve such puzzles. As a result, I decided to test it.

Here is the code:

import java.util.*;
import java.io.*;

public class ResolveSudoku {
 private static final int[] sudokuMatrix = {0,0,0,0,0,0,0,0,0,
         0,0,0,0,0,0,0,0,0,
         0,0,0,0,0,0,0,0,0,
         0,0,0,0,0,0,0,0,0,
         0,0,0,0,0,0,0,0,0,
         0,0,0,0,0,0,0,0,0,
         0,0,0,0,0,0,0,0,0,
         0,0,0,0,0,0,0,0,0,
         0,0,0,0,0,0,0,0,0};

 // load the content from file
 public static void load(String file) throws Exception {
  String str = null;
  int line = 0;
  BufferedReader br = new BufferedReader(new FileReader(file));

  while ((str = br.readLine()) != null) {
   if (str.trim().length() == 0 || str.startsWith("#")) 
    continue;

   if (line >= 9) {
    line = 10;
    break;
   }

   String[] vls = str.split(",");
   if (vls.length != 9) {
    br.close();
    throw new Exception("Line " + (line + 1) + 
     " has illegal number of elements!");
   }

   for (int i = 0; i < 9; ++i) {
    int value = Integer.parseInt(vls[i].trim());
    if (value < 0 || value > 9) {
     br.close();
     throw new Exception("Line " + (line + 1) + 
      " position " + (i + 1) + " has illegal value!");
    }
    sudokuMatrix[line*9 + i] = value;
   }

   ++line;
  }

  br.close();
  if (line != 9) throw new Exception("File " + file + 
   " has illegal number of lines!");
 }

 // print the content of the sudoku matrix
 public static void printMatrix() {
  for (int i = 0; i < 81; ++i) {
   if (i != 0 && i % 3  == 0) System.out.print(" ");
   if (i != 0 && i % 9  == 0) System.out.println();
   if (i != 0 && i % 27 == 0) System.out.println();

   if (sudokuMatrix[i] == 0) System.out.print(".");
   else System.out.print(sudokuMatrix[i]);
  }
  System.out.println("\n");
 }

 private static boolean check(int row, int col, int value) {
  // check if row is ok
  int tmp = row * 9;
  for (int i = 0; i < 9; ++i) {
   if (sudokuMatrix[tmp + i] == value) 
    return false;
  }

  // check if column is ok
  for (int i = 0; i < 9; ++i) {
   if (sudokuMatrix[i*9 + col] == value) 
    return false;
  }

  // check if box is ok
  tmp = (row / 3)*27 + (col / 3)*3;
  if (sudokuMatrix[tmp] == value) return false;
  if (sudokuMatrix[++tmp] == value) return false;
  if (sudokuMatrix[++tmp] == value) return false;

  tmp += 7;
  if (sudokuMatrix[tmp] == value) return false;
  if (sudokuMatrix[++tmp] == value) return false;
  if (sudokuMatrix[++tmp] == value) return false;

  tmp += 7;
  if (sudokuMatrix[tmp] == value) return false;
  if (sudokuMatrix[++tmp] == value) return false;
  if (sudokuMatrix[++tmp] == value) return false;

  return true;
 }

 public static boolean findSolution(int row, int col) {
  if (row == 9) {
   row = 0;
   if (++col == 9) return true;
  }

  int pos = row * 9 + col;
  if (sudokuMatrix[pos] != 0) return findSolution(row + 1, col);

  for (int i = 1; i <= 9; ++i) {
   if (check(row, col, i)) {
    sudokuMatrix[pos] = i;
    if (findSolution(row + 1, col)) return true;
   }
  }

  // reset the value back to zero 
  sudokuMatrix[pos] = 0; 
  return false;
 }

 public static void main(String[] args) throws Exception {
  load(args[0]);
  printMatrix();

  long start = System.currentTimeMillis();
  boolean res = findSolution(0, 0);
  long ex_time = System.currentTimeMillis() - start;

  if (res) printMatrix();
  else System.out.println("No solution!");

  System.out.println("Execution time: " + ex_time + "ms.");
 }
}

It's, basically, a routine that reads the puzzle's matrix from a file and another one that performs a brute force (i.e. analysing all the possible cases) in form of (I would say) an elegant recursive method call. Having the following input:

0,0,5,3,0,0,0,0,0
8,0,0,0,0,0,0,2,0
0,7,0,0,1,0,5,0,0
4,0,0,0,0,5,3,0,0
0,1,0,0,7,0,0,0,6
0,0,3,2,0,0,0,8,0
0,6,0,5,0,0,0,0,9
0,0,4,0,0,0,0,3,0
0,0,0,0,0,9,7,0,0
The problem was solved in ~30 milliseconds (after the byte code was JIT-ed on my "2.13Ghz, Core 2 Duo with SSD on board" laptop). And the answer was:

145 327 698
839 654 127
672 918 543

496 185 372
218 473 956
753 296 481

367 542 819
984 761 235
521 839 764

Thursday, June 2, 2011

Regarding the square root of n

Have you ever caught yourself (assuming you like maths) proving that numbers like $\sqrt{2}$ or $\sqrt{5}$ etc. are irrationals. Here is, more or less, a general statement with the proof.

For $\forall n \in \mathbb{N}$ (natural numbers), either $\sqrt{n} \in \mathbb{N}$ or $\sqrt{n} \in \mathbb{I}$ (irrational numbers, i.e. real numbers minus rational numbers).

There are two possible cases:

1. If $n = p^2$, $p\in \mathbb{N}$ ⇒ $\sqrt{n}=p\in \mathbb{N}$

2. If $n \ne p^2$ or there is no such a $p \in \mathbb{N}$ that would satisfy $n = p^2$, then $\sqrt{n}$ is irrational.

Let's suppose the contrary, i.e. there $\exists p,q \in \mathbb{N}$ and $\gcd(p,q) = 1$ (greatest common divisor) so that
$$\sqrt{n}=\frac{p}{q}$$
This means that $n·q^2=p^2$. From $\gcd(p,q) = 1 \Rightarrow \gcd(p^2,q^2) = 1$.

From the Bézout’s theorem, there $\exists z,t \in \mathbb{Z}$ (integers) so that
$$z\cdot p^2 + t\cdot q^2 = 1 \iff\\ z\cdot n\cdot q^2 + t\cdot q^2 = 1 \iff\\ q^2 \cdot (z\cdot n + t) = 1$$ which means $q^2$ divides $1$, but this is possible only if $q = 1$. As a result $n = p^2$ - contradiction with our initial assumption.

This proves the statement.

Monday, March 14, 2011

System Analyst vs. Business Analyst

People tend to confuse these two terms, the purpose of this article is to clarify them. Business Analyst is a person that is part of the business (which isn't necessarily IT related), knows the business and can articulate what business wants in form of the business requirements. System Analyst is a person with IT background, who knows how IT systems work, how to translate business requirements into technical requirements/artefacts so that they are understandable by the technical team; system designers, developers and testers. I didn't include architects to the list, because system analysis, as a practise, is part of the system architecture.

So, what is typically (this isn't a firm rule) expected from a System Analyst to deliver?
- Functional Requirements
- Non-functional Requirements
- Use Cases
- Wireframes with descriptions of each UI element
- Entity diagrams.

Traceability is another important word for the System Analyst (and not only). It is a way of showing how various artefacts are implementing/realising each other (e.g. use cases realising requirements etc.). In order to produce all these artefacts, it is recommended to use one of the existing, industry recognized UML designing tools. This can be Rational Rose, Sparx Enterprise Architect or anything suitable.

A typical process looks like:

1. A new model is created using the design tool.

2. Business requirements are imported/added to the model.

3. Business requirements, if not detailed enough, are extended with more detailed functional and non-functional requirements, gathered during various sessions with SME (Subject Matter Experts).

4. Functional/Non-functional and business requirements are linked (typically using "association" connector) for traceability reasons.

5. Use cases are elaborated and added to the model. As per the industry standard (check with Google), each use case must have one Basic Path with up to ten sequences/events and zero or more Alternative Paths.

6. For traceability reasons, use cases are linked (typically using "realize" connector) with the requirements they are realising.

7. Wireframes are elaborated and added to the model (I must add, if the tool supports this, e.g. Sparx Enterprise Architect). Wireframes represent the draft versions of the User Interfaces required from the System. The detailed mock-ups are typically elaborated by the graphical designers from the wireframes.

8. Wireframes are linked (typically using "realize" connector) with the use cases they are realising.

9. High level entity diagrams are elaborated and added to the model.

10. Wireframes' UI form elements are mapped (typically using "realize" or "association" connectors) with the relevant attributes of the relevant entities. This is a great way to highlight the re-usable elements to the system designers.

11. All the acronyms, business terms and abbreviations are added to the Model Glossary, this is mandatory regardless of the fact that the tool supports this (e.g. Sparx Enterprise Architect) or not (in which case it can be a separate document).

The following picture is just an example of the expectation.

And don't forget, all these artefacts must be reviewed by SME!

Few remarks:

1. Mock-ups, elaborated by the graphical designers, must follow the User Interface functional/non-functional requirements. For instance DDA (Disability Discrimination Act) requirements/standards, if it is the case.

2. Entity diagrams, provided by the system analyst, aren't expected to be detailed class or database diagrams, this is an exercise for the system designers. They must be part of, what I call, the "requirements language".

For instance, if the business requirement says that "the super user must approve the document before it is published", then there will be an entity Document that will, probably, have a "status" attribute mapped (aggregation or composition) to an enumeration with the elements "DRAFT, READY, APPROVED". The relevant use case (or use cases) will operate with these terms.