vendredi 1 août 2014

A coding exercise: The Caesar’s Cipher

 

As one of my holidays book is “Digital Fortress” from the very well-known Dan Brown (he is the author of “The Da Vinci code”) I found interesting to implement by my self some of the message encryption method he describe in that book.

 

To describe a bit the story, the “Digital Fortress” in an unbreakable cipher and it’s potential availability is a cataclysm for the NSA. And in its introduction the author present the NSA and what the crypto science is.

 

He say that the “Caesar’s Cipher” was one of the first known ciphering technic. And after looking Wikipedia it looks like the method he described wasn’t the same. The “Caesar’s Cypher” is typically a method based on a fixed alphabet shift, but he talked about a box based method using a “magic square” (search for the “Caesar’s box cipher”).

My code is really simple, in the first implementation I made I just represented spaces by ‘_’ but you can also choose to remove all spaces using:

inputMsg.erase(remove(inputMsg.begin(), inputMsg.end(), ' '), inputMsg.end());

The trick is to find the root X of the message length and after you draw a square of X*X, write your message character by character (1 per cell) from the top-left corner to bottom-right corner and transpose the table.

auto inL = inputMsg.size();
auto sqrtInL = (unsigned int)(sqrt(inL) + .5);
auto codeL = sqrtInL * sqrtInL;

out = string(codeL, '_');
for(auto ui = 0 ; ui < sqrtInL ; ++ui) {
for(auto = 0 ; uj < sqrtInL ; ++uj) {
if(ui*sqrtInL+uj < inL) {
out[uj*sqrtInL+ui] = (in[ui*sqrtInL+uj] != ' ') ? in[ui*sqrtInL+uj] : '_' ;
}
}
}

mardi 15 juillet 2014

Why my Win 7 in Virtual-Box was still running a time update ….. ?

 

That point puzzled me for at least 20minutes so I think I need to write something about it in order fix that in my memory.

I used to perform Product validation on Virtual Machines but when last Friday I had to do some test of how a license system is robust against system date & time change, I met a strange behavior!

I tried to change the date on the VM as on my own workstation (after disabling the Windows Time Service (a.k.a W32Time)) but every time I tried the clock got back in sync after few seconds and I didn’t know why. I was searching for a setting in my Virtual Box Host configuration but finally after some tests, I found that my VM was running a specific windows service called “VirtualBox Guest Addition Service”.

His description is really clear:

“Manages VM runtime information, time synchronization, remote sysprep execution and miscellaneous utilities for guest operating systems.”

So if like me you always setup the Guest addition for all VM you create, remember that service and that it use your host date & time to re-sync the guest date & time.

jeudi 24 avril 2014

The new VS’2013 may be a bit buggy …

In one hand I would say that moving from the old VS’2008 to the new VS’2013 was really fine, because even for a low-level programmer like me (in the project I’m working for, I only use C and C++) the editor’s improvements are really great !
But in another hand as in every software, there is still some bug. I only worked 2 or 3 days with VS’13 but I found 2 bug I reported through the MS Connect portal.
1) The C compiler has a terrible bug and I think that bug is a major issue, because it prevent the build of a tons of good C99 open source code.
for the VS’13 C compiler the following code is wrong and it report the following error:
typedef struct { int j; } test_t;

int f(test_t **p_pool, int i)
{
    if (i <= 0)
        return -1;

    test_t *pool;   
    *p_pool = pool;

    return i;
}



and the error is : 'test_t' : illegal use of this type as an expression

in fact, it looks like the compiler fails to interpret test_t as a type if the if-then statement body before isn’t surrounded by a some {}, for any other basic type, I mean int, char etc…. there is no problem but with all defined type containing “_t” (size_t, prtrdiff_t, uint8_t, etc….) it fails !

A workaround if to rewrite the code as:
typedef struct { int j; } test_t;

int f(test_t **p_pool, int i)
{
    if (i <= 0) {
        return -1;
    }

    test_t *pool;   
    *p_pool = pool;

    return i;
}



But it’s a pain to do that on a huge C/C99 code base.

Updated 2014 April 29th: An answer from MS dev team say that a fix will be available with the next update ... Good to hear!

2) the project property page has been improved with several new option, but switching from Debug to Release configuration directly from the property page may be disappointing, see below what’s may happen when you are doing a that.

Step to reproduce:


  • open a C/C++ project configuration property pages

  • switch the Configuration (Debug to Release or vice-versa)

  • now select another entry in the property tree and look. Below for example I was initially in Release / on C/C++->Preprocessor, I first switched to Debug and clicked on Language.

VS2013PropertyPagesBug1

Hopefully if you switch-back or if you close the pages and re-open then directly with “Debug” Configuration, the option will be back !

mercredi 16 avril 2014

The worst optimization I ever made….

As a programmer I often try to simplify the code and reduce the number of operation, but few days ago I made a big mistake.

In a video processing system, I replaced the following line, we use for each frame to compute its Presentation TimeStamp (a.k.a its PTS):

curr_pts = first_pts + nb_frame * duration;

by a simple addition

curr_pts += duration;
and curr_pts was initialized with first_pts.

Now let say that all those values are floating point number (double or float).
In the floating point number world, those 2 code aren’t really equivalent due to the error accumulation.

That problem is well known and a solution to minimize the error is the Kahan’s summation algorithm.

Take a look here on Ideone at a small test code I made to demonstrate it…..

But basically if we compute the delta between the 1st version and the 2nd version, we get 3.14042e-05 and with the Kahan’s algorithm we get only a delta of 1.74623e-09.

A big mistake and a big reminder that floating point computation aren’t so easy ….

lundi 7 avril 2014

Class/Struct definition local to a function.


You may know or not that defining a class or struct inside a function is possible but you may not be aware of all the issue you will meet when using that with the old C++98.
First thing, if you are using C++11 you can pass away, because in all case that feature will be correctly handle by recent compiler and debugger.
Now if your are still using a C++98 compiler or an old GCC, stay here and read the following:)

Definition in a function

In most case the following code will be Ok.

int function() { 
   typedef struct myStruct { 
       int num; 
       myStruct (int n): num(n){} 
       myStruct(const myStruct&amp; ro):num(ro.num){} 
    } mystruct_t; 

  mystruct_t t(2);

  return t.num;
} 


But want will happened if you try to use that struct with an STL’s container, like vector, deque, etc….. Example

int function() { 
   typedef struct myStruct { 
       int num; 
       myStruct (int n): num(n){} 
       myStruct(const myStruct&amp; ro):num(ro.num){} 
    } mystruct_t; 

  std::deque<mystruct_t> dq(10, mystruct_t(2));
  
   return dq[0].num;
} 

In fact here we have 2 different scenario:
  1. you are using GCC and it will not compile, because it’s not a C++98 compliant code
  2. you are using VC++2008 and it will compile, but you will meet weird debugger behavior on that piece of code.

Explanation

In C++98, you cannot use local class or struct with template type. This restriction is part of the standard. The reasoning was originally that local structures don't really have a names and thus it would be impossible to instantiate a template with them.

So as said if VC++2008 allow that code to compile, you will not be able to see what you have in your deque… Like in the snapshot below.

DebuggerError

My conclusion

Try to avoid that kind of code until you get the new C++11, because the portability across platform is not guarantee by the standard and that debugging and maintaining them is really hard. Define your class or struct outside of the function.

jeudi 13 mars 2014

Step-by-step through C++ Template

As some of my teammate always complain that template-based code are really hard to understand and that they would prefer coding without, I will try here to explain how it works and propose some complexity-growing example.

NOTE1: that post will be periodically update....
NOTE2: that post/tutorial is design in a way to can do all exercise without local compiler, I wrote a solution using Ideone, so create your account and write your own solution for all exercise.

A first look at the template syntax <> and their usage:

We using template and/or writing template you "can" meet the < CONTENT > syntax
Where Content can be:
  • class T / typename T
  • A data type, which maps to T
  • An integral specification
  • An integral constant/pointer/reference which maps to specification mentioned above.

1st Example

Imagine we want a function to multiply by 2 an integer

int mulByTwo(int v) { return v*2;}

And we can write int I = mulByTwo(2);

Now we also want mulByTwo but for float and we avoid code duplication.
Question: Write only one function MulByTwo to deal with:

int I = mulByTwo(2);
double D = mulByTwo(2.0);

Solution: here

Observe basic/simple "type deduction" error message

Now using the 1st example, what's happen if you call:
string S = mulByTwo("blahblah....");

Now build a function Sum, range-based to deal with iterator and pointer of any kind !

Tips: an iterator is just a simple base class implementing some operator like: ++,--,+=,-=,*, ->, [], etc...

Add the end with only 1 function, you should be able to execute:

int main() {
    int testArray[5] = {0,1,2,3,4};
    vector v = {0, 1, 2, 3, 4};
    vector s = {"hello", " ", "world"};
  
    cout << Sum(v.begin(), v.end()), cout << endl;
    cout << Sum(testArray, testArray + sizeof(testArray)/sizeof(testArray[0])), cout << endl;
    cout << Sum(s.begin(), s.end()), cout << endl;
  
    return 0;
}


Solution: here

How to use integral template

as for type deduction, the compiler will prepare everything at the compilation time.

Example: template&ltint&gt struct example { static double value = N * 2.0; }
If we write: cout << example&lt5&gt::value;

Exercise: Use that to compute factoriel&lt5&gt at compile time
Solution: here.

------ > followings section are under construction <------------------------ br="">

Solving ambiguity / Explicit Template Arg Specification

 

Default template  argument


Template and Specialization




vendredi 7 février 2014

char ** conversion to string

First, I would say it was a long time without posting anything, but I’m a bit in trouble in my personal life. And finally today as I was working on a command line implementation I realize that it’s a good practice to log (wherever you want …) the command line argument used to run a command line executable.

And as I was writing the code to do that, I was thinking that some developer may have create some complex code with loop display the command line argument that we have in argv. But in fact if you can use C++ STL and also the powerful BOOST Framework, it use only 2 lines of code (or even less).

So let start, first cmd line arguments are from the main function point of view an array of char*. So the 1st thing to do convert that in the C++ world.

vector<string> cmdline(argv+1, argv+argc);

Ok now we have STL object we all know on which we can easily iterate to concatenate each string and insert a delimiter (a simple space “ ”). But instead of using a complex loop I prefer using an efficient BOOST string algorithm call join.

#include "boost/algorithm/string.hpp"

….

string cl = boost::algorithm::join(cmdline, " ")

now you can dump the argument passed to your command line with a cout or any logging system you want.

And have a nice weekend.

vendredi 27 décembre 2013

C++: How to handle exception in CTOR

Yesterday I was reading that thread on Linkedin, and I realized once again that the exception handling in/or around a constructor(CTOR) is still an obscure topic as only one commenter mentioned the correct try-catch form for CTOR that can handle every exception even those coming from the initialization list.
The main problem when an exception occur during a CTOR is what have we to do for cleaning memory allocated on the heap.
To summarize the easiest way to handle exception, I produced the following example.

The output will be (I added some comments:
  • object_t CTOR ==> object_t allocation in our initializer list put in a smart_ptr (1)
  •  test_t CTOR ==> here we enter in the test_t CTOR Impl
  • object_t CTOR ==> we allocated a new object (2)
  • … here we have thrown the exception
  • object_t DTOR ==> the smart pointer object is on the stack, so the stack unwinding run and the memory allocation (1) is cleaned
  • here we handle our dynamic allocation ==> we are now in the CTOR catch section, as we have correctly ordered our data member we can check `if (ptr != nullptr)` and delete it if needed.
  • object_t DTOR ==> now the memory allocation (2) is released.
  • exception just to test... ==> as we have and should always RETHROW the exception, we catch it!

Conclusion: If we based all our class on that model, there is no reason anymore to fear about memory leaks.

mardi 24 décembre 2013

Use Beyond Compare as SVN diff tool under Linux

Today a quick note on that topic as I extended my own configuration with that tricks. BeyondCompare is a well known tool to compare and merge different  version file.

I used it a lot combined with ToirtoiseSVN, but as I worked more and more under linux using Remote Workstation, I would also use it. But I mainly work on remote workstation using a putty prompt. I will not describe here how to setup bcompare on a linux workstation, but it’s the 1st thing todo.

Next you have to follow my previous post to redirect the all X application to your local (I mean Windows 7 in my case) X11 server.

Now when you run “svn diff” on a file, you expect to use bcompare. To achieve that goal, follow me step by step.

cd ~

touch .subversion/bcompare_svn.sh

nano .subversion/bcompare_svn.sh

COPY/PASTE the folllowing in that script:

#!/bin/bash

/usr/bin/bcompare $6 $7 &

exit 0

Set execution permission

chmod 755 .subversion/bcompare_svn.sh

nano .subversion/config

Add that line just after “# diff-cmd = diff_program (diff, gdiff, etc.)”


diff-cmd=/home/YOURFOLDER/.subversion/bcompare_svn.sh

And done !

Now at each svn diff  command you start, BeyondCompare will start and display on the own PC.

vendredi 13 décembre 2013

STL String to/from wide string

Yesterday I spend sometimes to help one of my teammate with a piece of code he wrote to convert a std::string  into a std::wstring. At the beginning it seems to be a complex issue for him and he used a complex C based code managing wchar buffer convert char to wchar with mbstowcs.

But finally as often the STL provide everything we need to convert one string type into the other and it’s quite simple.

I quickly use Ideone to demonstrate how to deal with:

As you see we can just use the iterator (old-style or new style like below)

wstring ws(s.begin(), s.end()); or wstring ws(begin(s), end(s));

lundi 2 décembre 2013

Redirect X from remote linux machine on your windows host.

When you use a remote linux machine from your own Windows Desktop machine using a putty connection, you can easily redirect X application on your desktop.

To do that, there is several steps:

1) You need to have a cygwin setup on your windows host, and follow the following instruction to setup all package required to run a X server.

2) Setup your putty connection to allow X11 forwarding.

Putty-Enable-X11Forwarding

To check if everything is OK, restart a connection and from linux prompt, check the value of “DISPLAY” (echo $DISPLAY). It should return something similar to:

localhost:13.0

3) To start your windows X11 server, create a shortcut file in your cygwin folder.

the target will be: C:\ cygwin\bin\run.exe /usr/bin/bash.exe -l -c /bin/startxwin.exe

And for its name, “StartX” is a good choice!

Double-click on that shortcut and check that you now have the X11-server icon in your Windows systray.

4) To run that server every time you start your window session, save a copy of that shortcut in:

%USERPROFILE%\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup

5) Final check, start xclock from your Linux prompt, the xclock windows will appear on your Windows Desktop !

vendredi 29 novembre 2013

Text processing: Word List Challenge.

I read this morning a question on Stackoverflow where user tried to solve that text processing challenge with a really complex code.

With only 3 line of code we can do that in C++. Using STL and optionally a BOOST header.

It works in 3 steps:

1) transform to lower case,

2) split using multiple delimiters (boost::any_of),

3) sort the resulting vector.

….

#include <iostream>
#include <string>
#include <vector>
#include <iterator>
#include <algorithm>
using namespace std;

#include "boost/algorithm/string.hpp"

const char* testStr = "This is. a sample piece of, text to illustrate \n this problem.";

int main(int argc, char* argv[])
{
string inputText(testStr);
cout << inputText << endl << "*******************" << endl;
vector<string> strs;
boost::split(strs,boost::algorithm::to_lower_copy(inputText),boost::is_any_of("\t ,\n,,,."),boost::token_compress_on);
cout << "list : " << strs.size() << endl;
cout << "without sort\n", copy(begin(strs), end(strs), ostream_iterator<string>(cout, "\n"));
std::sort(strs.begin(), strs.end());
cout << "with sort\n", copy(begin(strs), end(strs), ostream_iterator<string>(cout, "\n"));


return 0;
}

lundi 25 novembre 2013

Override a default STL operator >>

In that question, user need to override the default STL operator >> for complex number. First keep in mind that the STL provide a template for complex number define in <complex> and that this type come with its own syntax for I/O.

By default the syntax is (real,imag).

As the user want to use: real+imagi, we have to change the default behavior.

In the following you will see how I wrote a new global function to override the default operator and how I use a Regular Expression to extract the real and imaginary number.

template<class _Ty> inline istream& operator>>(istream& _Istr, complex<_Ty>& _Right)
{
// extract a complex<_Ty> with syntax REAL+IMAGi
long double _Real = 0;
long double _Imag = 0;
string s; _Istr >> s;
string regexPattern = string(R"r(([-+]?\d+\.?\d*|[-+]?\d*\.?\d+)\s*\+\s*([-+]?\d+\.?\d*|[-+]?\d*\.?\d+)i)r");
regex reg(regexPattern);
smatch sm; // same as std::match_results<const char*> cm;
regex_match (s,sm,reg);

_Real = std::atof(sm[1].str().c_str());
_Imag = std::atof(sm[2].str().c_str());

_Right = std::complex<_Ty>((_Ty)(_Real), (_Ty)(_Imag));

return (_Istr);
}


There is place for improvement in that version:


  • no match

  • match are not number

  • etc…

But it’s a good example of how to start!

vendredi 22 novembre 2013

FFMPEG from Compressed to RAW video.

I f consult some of my previous post, you may noticed that I’m an ffmpeg fan.

I often used ffmpeg command line to pipe raw video, in my own soft or some soft I develop in my professional environment. But I recently discover a good to share trick about ffmpeg.

Imagine a video file of 20min at 24fps, you have extract those information using the ffmpeg –i command. But when you extract the raw video frame in a file, you discover that the output file is bigger than expected (like a Tardis….).

Example of simple decoding as YUV 420p:

ffmpeg –I input.mp4 –c:v raw_video –pix_fmt yuv420p – >> output.yuv

the reason can be that if the input file hasn’t PTS corresponding to a Constant Frame-Rate (CFR), ffmpeg duplicate or drop some frames.

hopefully ffmpeg is explicit and full of useful information to troubleshoot those situation, for example in the following ffmpeg output latest line we see that it “duplicate” 60 frame.

frame=  119 fps=0.0 q=0.0 Lsize=  160650kB time=00:00:02.00 bitrate=657102.5kbits/s dup=60 drop=0

To prevent that the parameter to use is “-vsync”.


-vsync parameter

Video sync method. For compatibility reasons old values can be specified as numbers. Newly added values will have to be specified as strings always.

0, passthrough

Each frame is passed with its timestamp from the demuxer to the muxer.

1, cfr

Frames will be duplicated and dropped to achieve exactly the requested constant frame rate.

2, vfr

Frames are passed through with their timestamp or dropped so as to prevent 2 frames from having the same timestamp.

drop

As passthrough but destroys all timestamps, making the muxer generate fresh timestamps based on frame-rate.

-1, auto

Chooses between 1 and 2 depending on muxer capabilities. This is the default method.


So to only have the encoded frame in our output the correct line is:

ffmpeg –I input.mp4 –vsync 0 –c:v raw_video –pix_fmt yuv420p – >> output.yuv

OpenMP support in different compiler.

OpenMP is a powerful and useful standard supported by many compiler to introduce parallelism (multi-threading) in your C/C++ source code with “minimal effort.

But, depending of your developing environment, you may face some problems and the 1st from my POV is that if you compile the same source code with GCC/G++ and Visual Studio C++ compiler you cannot use the complete and last OpenMP functionnalities.

The reason is that VS' C/C++ compiler (even the last version VS’2013) only support OpenMP 2.0. It’s an old version released in March 2002.

While OpenMp support in VS was frozen since its 1st introduction in VS’2005, GCC/G++ support evolve and a recent GCC version like v4.9 support the last OpenMP v4.0 (July 2013).

You can consul that page to find which version of OpenMP is supported in the GCC version you used to build.

Note that CLang also provide OpenMP support but only for the v3.1.

---------------------------------

So, to conclude if you develop for several compiler and want to share your source code you should choose to keep using the ‘old’ v2.0. It’s a bit silly because the 3.1 and v4 introduce a lot of new functionalities like task, simd, device, etc …

Extract PTS from a video stream

 

I often used ffmpeg to extract raw_video data from compressed file or device stream, but when we do that we lost a useful information the PTS (presentation timestamp) of each frame.

For example, if you have a program using the output of ffmpeg (pipe mode),

ffprobe –show_frames –select_streams v:0 input.ts | grep pkt_pts_time= >> output.pts

output.pts file will contain:

pkt_pts_time=0.000000
pkt_pts_time=0.034022
pkt_pts_time=0.067689
…..

those number are in seconds, so you can use them easily in any software you develop.

mardi 5 novembre 2013

C# Any CPU executable using native DLL

Once again I meet an issue today when starting a software on my Win7 64bit platform. It's not the 1st time that when I start a soft, it crash immediately with a 0xe0434f4d error/exception code, but everything I'm wondering why ?

In fact if you see that behavior,, it could means that you are running a .Net executable build to start on "Any CPU" but that native win32/x86 DLL are require. On an old 32bit only windows system it work fine, but on a 64bit XP or Win7, the .Net process don't start in WoW64 and will not be able to load the x86 DLL.

To check and fix that issue, you need CorFlags. It's a simple executable that you can find for example in C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Bin.

For example using: CorFlags proc.exe
I got:

Version   : v2.0.50727
CLR Header: 2.5
PE        : PE32
CorFlags  : 1
ILONLY    : 1
32BIT     : 0
Signed    : 0


As the 32BIT flags is set to 0 and that the ILONLY is set to 1, that process can start as a 32bit executable on a 32bit only PC or as a 64bit executable on a 64bit PC.

To change that state you can update the PE header with: CorFlags /32BIT+ proc.exe
Run again: CorFlags proc.exe

Version   : v2.0.50727
CLR Header: 2.5
PE        : PE32
CorFlags  : 3
ILONLY    : 1
32BIT     : 1
Signed    : 0


Now you can start proc.exe on any CPU and OS, 32bit only or 64bit, It will always start as a 32bit executable (WoW64 mode on a 64 bit Windows OS).

From Visual Studio if you want to exactly specify the target, you can use the C#/.Net Project page.


mardi 15 octobre 2013

C++ - Finding all arrangement (a.k.a permutation) of object.

When you have a set of object, you may have to build all arrangement of those object.

Example, a vector num = {0,1,2}, you want the 3! permutations ( {0,1,2}, {0,2,1}, {1,0,2},{1,2,0},{2,0,1},{2,1,0} )

Hopefully the Standard Template Library (STL) come with some useful function for that, but their behavior really depend of the operator you provide with your objects.

If you take a look at next_permutation, it stands to "Rearranges the elements in the range [first,last) into the next lexicographically greater permutation." but that point rely to the "bool operator( const T& elt)" of the object (class/type) you use.

A quick example of the pitfall in which I fall today. Imagine a type point define like below:

struct pos_t {
int x; int y;
pos_t(){x = 0 ; y = 0;}
pos_t(int X, int Y){x=X; y=Y;}
pos_t(pos_t const & r) {x = r.x; y=r.y;}
pos_t& operator=(pos_t const & r) {x = r.x; y=r.y; return *this;}
bool operator < ( pos_t const & p) const
{
return (x + y)
< ( p.x+p.y);
}
friend ostream& operator << (ostream &o, const pos_t& p)
{
return o << "(" << p.x << "," << p.y << ")";
}
};


Now using the following list of point,  (1,3) ,(2,2) , (3,0) ,(3,1), you expect to get 24 permutations. But you will not !!!! The reason is the operator < we define in our class/struct. Using that operator (1,3) is similar to (3,1) and that the reason why when using next_permutation we implicitly use the less-than operator and we fail.

To really get all permutation out-of next_permutation we need to define clear compare operator.


bool operator < ( pos_t const & p) const
{
  return (x < p.x) || ((x == p.x) && (y < p.y));
}


Now using our list of 4 points, we can call a simple loop to store and display all permutations. See below a piece of code extract of Coding Challenge call "Treasure Hunter" (a kind of A* algorithm can be use to solve it .... )


deque<vector<pos_t>> treasure_order;
std::sort(begin(treasurePos), end(treasurePos));
do {
  vector<pos_t> c;

  c.push_back(pos_t(0,0));
  copy(begin(treasurePos), end(treasurePos), back_inserter(c));
  c.push_back(pos_t(maze.size()-1, maze.size()-1));

  copy(begin(c), end(c), ostream_iterator<pos_t>(cout, " -> "));
  cout << endl;
  treasure_order.push_back(c);

} while ( std::next_permutation(begin(treasurePos),end(treasurePos)) );//*/
cout << "we stored " << treasure_order.size() << " path to get all the treasure (=nbTreasure! = " << fact((int)treasurePos.size()) << ")" << endl;


Using that simple 2D maze where * mark treasure position:

. . . .
. # . *
. # * .
* * # .

We now that based on the 4 treasure we have, we can visit those 4 position using 24 different order....
Remark, here all list start and end with the same point (top-left and bottom-right corner) because they are the starting and ending point of th "Treasure Hunt" !

(0,0) -> (1,3) -> (2,2) -> (3,0) -> (3,1) -> (3,3) ->
(0,0) -> (1,3) -> (2,2) -> (3,1) -> (3,0) -> (3,3) ->
(0,0) -> (1,3) -> (3,0) -> (2,2) -> (3,1) -> (3,3) ->
(0,0) -> (1,3) -> (3,0) -> (3,1) -> (2,2) -> (3,3) ->
(0,0) -> (1,3) -> (3,1) -> (2,2) -> (3,0) -> (3,3) ->
(0,0) -> (1,3) -> (3,1) -> (3,0) -> (2,2) -> (3,3) ->
(0,0) -> (2,2) -> (1,3) -> (3,0) -> (3,1) -> (3,3) ->
(0,0) -> (2,2) -> (1,3) -> (3,1) -> (3,0) -> (3,3) ->
(0,0) -> (2,2) -> (3,0) -> (1,3) -> (3,1) -> (3,3) ->
(0,0) -> (2,2) -> (3,0) -> (3,1) -> (1,3) -> (3,3) ->
(0,0) -> (2,2) -> (3,1) -> (1,3) -> (3,0) -> (3,3) ->
(0,0) -> (2,2) -> (3,1) -> (3,0) -> (1,3) -> (3,3) ->
(0,0) -> (3,0) -> (1,3) -> (2,2) -> (3,1) -> (3,3) ->
(0,0) -> (3,0) -> (1,3) -> (3,1) -> (2,2) -> (3,3) ->
(0,0) -> (3,0) -> (2,2) -> (1,3) -> (3,1) -> (3,3) ->
(0,0) -> (3,0) -> (2,2) -> (3,1) -> (1,3) -> (3,3) ->
(0,0) -> (3,0) -> (3,1) -> (1,3) -> (2,2) -> (3,3) ->
(0,0) -> (3,0) -> (3,1) -> (2,2) -> (1,3) -> (3,3) ->
(0,0) -> (3,1) -> (1,3) -> (2,2) -> (3,0) -> (3,3) ->
(0,0) -> (3,1) -> (1,3) -> (3,0) -> (2,2) -> (3,3) ->
(0,0) -> (3,1) -> (2,2) -> (1,3) -> (3,0) -> (3,3) ->
(0,0) -> (3,1) -> (2,2) -> (3,0) -> (1,3) -> (3,3) ->
(0,0) -> (3,1) -> (3,0) -> (1,3) -> (2,2) -> (3,3) ->
(0,0) -> (3,1) -> (3,0) -> (2,2) -> (1,3) -> (3,3) ->