Facebook’s hacker cup qualification phase 2010 solution

Well this has been an interesting exercise, although probably a bit of a waste of a day, but a super geek saturday.

A reminder of the good old student programming assignments.
http://www.facebook.com/hackercup/problems.php?round=4

This hacker cup is in 4 round, pre-selection first with 3 tasks. Only need one correct though to get to next round.

Here are my 3 answers, not really sure if this will be enough to qualify, I have doubts on the peg game, since I never seem to really ever get the same results… And although my code is probably not the cleanest. I am pretty confident that it should qualify my me.

1) double square.

Double Squares
A double-square number is an integer X which can be expressed as the sum of two perfect squares. For example, 10 is a double-square because 10 = 32 + 12. Your task in this problem is, given X, determine the number of ways in which it can be written as the sum of two squares. For example, 10 can only be written as 32 + 12 (we don’t count 12 + 32 as being different). On the other hand, 25 can be written as 52 + 02 or as 42 + 32.

Input

You should first read an integer N, the number of test cases. The next N lines will contain N values of X.

Constraints

0 ≤ X ≤ 2147483647
1 ≤ N ≤ 100

Output

For each value of X, you should output the number of ways to write X as the sum of two squares.

Example input
5
10
25
3
0
1

Example output:

1
2
0
1
1

Probably like most people, I started by attempting brute force, before realizing that we could optimize by limiting the results with squares and using the results as the keys of an array to speed up the result.his is my code:

<?php
function get_list_of_squares(){
for($i=0;$i<=sqrt(2147483647);$i++)
{
$list[$i]=$i*$i;
}
return $list;
}
$rHandle = fopen(‘input.txt’, ‘r’);
$oHandle = fopen(‘output.txt’, ‘w’);
$string = “”;
while(!feof($rHandle)){
$string .= fread($rHandle, filesize(‘input.txt’));
}
fclose($rHandle);
$numbers = preg_split(‘%[\s,]+%’, $string);
$nb_results = array_shift($numbers);
$numbers2 = array_flip($numbers);
$list = get_list_of_squares();
$list = array_flip($list);
$r = array();
foreach($list as $sq => $id )
{
foreach($numbers2 as $key => $value)
{
if($sq > $key) continue;
if(array_key_exists($key – $sq, $list) &&  !isset( $r[$key][$key - $sq] )  )
{
echo “\n$key = ” . $sq . ” + ” . ($key – $sq) ;
$r[$key][$sq]=$key – $sq;
}
}
}
foreach($numbers as $key )
{
echo $key . “: :” . count( $r[$key] ). “\n”;
fwrite($oHandle, count($r[$key]) . “\n”);
}
fclose($oHandle);
?>

2) Peg Game
At the arcade, you can play a simple game where a ball is dropped into the top of the game, from a position of your choosing. There are a number of pegs that the ball will bounce off of as it drops through the game. Whenever the ball hits a peg, it will bounce to the left with probability 0.5 and to the right with probability 0.5. The one exception to this is when it hits a peg on the far left or right side, in which case it always bounces towards the middle.

When the game was first made, the pegs where arranged in a regular grid. However, it’s an old game, and now some of the pegs are missing. Your goal in the game is to get the ball to fall out of the bottom of the game in a specific location. Your task is, given the arrangement of the game, to determine the optimal place to drop the ball, such that the probability of getting it to this specific location is maximized.

The image below shows an example of a game with five rows of five columns. Notice that the top row has five pegs, the next row has four pegs, the next five, and so on. With five columns, there are four choices to drop the ball into (indexed from 0). Note that in this example, there are three pegs missing. The top row is row 0, and the leftmost peg is column 0, so the coordinates of the missing pegs are (1,1), (2,1) and (3,2). In this example, the best place to drop the ball is on the far left, in column 0, which gives a 50% chance that it will end in the goal.

x.x.x.x.x
 x...x.x
x...x.x.x
 x.x...x
x.x.x.x.x
 G  

'x' indicates a peg, '.' indicates empty space.

Input

You should first read an integer N, the number of test cases. Each of the next N lines will then contain a single test case. Each test case will start with integers R and C, the number of rows and columns (R will be odd). Next, an integer K will specify the target column. Finally, an integer M will be followed by M pairs of integer ri and ci, giving the locations of the missing pegs.

Constraints

  • 1 ≤ N ≤ 100
  • 3 ≤ R,C ≤ 100
  • The top and bottom rows will not have any missing pegs.
  • Other parameters will all be valid, given R and C

Output

For each test case, you should output an integer, the location to drop the ball into, followed by the probability that the ball will end in columns K, formatted with exactly six digits after the decimal point (round the last digit, don’t truncate).

Notes

The input will be designed such that minor rounding errors will not impact the output (i.e. there will be no ties or near — up to 1E-9 — ties, and the direction of rounding for the output will not be impacted by small errors).

Example input
5
5 4 0 1 2 2
3 4 1 1 1 1
3 3 1 2 1 1 1 0
3 4 0 2 1 0 1 1
3 4 0 1 1 1

Example output

0 0.375000
1 1.000000
1 1.000000
0 1.000000
0 0.500000

The final exercise was probably the most difficult, but probably because I havn’t done this type of algorithm for a long time. I clearly remember doing this in my “networks” course in my first year of masters, this we had to do in “c” but I have to say I was not very focused in this course for some reason.

Anyway here is my answer, although It is likely to be a little buggy since I didn’t follow a simple algorithm like there must have been if I could remember my course.

<?php
function check_init($val){
 if(!isset($val)) $val = 0;
 return $val;
}

$rHandle = fopen('input.txt', 'r');
$oHandle = fopen('output.txt', 'w');
 $string = "";
 while(!feof($rHandle)){
 $string = fread($rHandle, filesize('input.txt'));
 $text .= $string;
 }
 fclose($rHandle);
 $lines = preg_split('/[\n]+/', $text);
 $nb_lines_to_check = $lines[0];
 foreach($lines as $index => $line){
 if($index == 0) {
 echo "line 1: amount of games: " . $line;
 continue;
 }
 $values = preg_split('/[\s]+/', $line);
 if( count($values) <= 1 ) continue;
 $rows = $values[0];
 $cols = $values[1];
 $target = $values[2];
 $nb_holes = $values[3];    
 $holes = array();
 $coord = array_splice($values, 4);
 $starting_val = $cols - 1;
 for($i=0;$i<$nb_holes;$i++){
 $id = $coord[$i*2] . ":" . ($coord[$i*2 +1]);
 $holes[$id] = true;
 }
 $results = array();
 echo "\ngame $index: ". $rows ."x". $cols . "\ntarget: c " . $target . " : ". $nb_holes . " holes\n";
 for($y=0; $y < $rows; $y++){
 $distance = $rows - $y;
 $shift = $y % 2;
 for($x=0; $x + $shift < $cols; $x++)     {
 if($target -$x > $distance) continue;
 for($start=0; $start < $starting_val; $start++) {
 if($y == 0)
 {   if($start == $x)
 {            $results[$start][$y][$x] =  1;                    }
 else{        $results[$start][$y][$x] =  0;               }
 continue;
 }
 $prev_left = isset($results[$start][$y-1][$x-1+$shift]) && $results[$start][$y-1][$x-1+$shift] > 0 ? $results[$start][$y-1][$x-1+$shift]/2 : 0;
 $prev_right = isset($results[$start][$y-1][$x + $shift]) && $results[$start][$y-1][$x + $shift] > 0 ? $results[$start][$y-1][$x + $shift] / 2 : 0;
 if($x == 0) {    $prev_left = $prev_left * 2;   }
 elseif( ($x + $shift) == ($cols - 1) ){
 $prev_right = $prev_right * 2;            }
 if(isset($holes[$y . ":". $x])){
 $prev_left =0;
 if($results[$start][$y-1][$x-1+$shift] > 0)
 $results[$start][$y + 1][$x-1+$shift] = $results[$start][$y-1][$x-1+$shift];
 }
 $next_x =$x+1;
 if(isset($holes[$y . ":". $next_x])){
 $prev_right =0;             
 }
 if(isset($results[$start][$y][$x])){
 $new_value = $results[$start][$y][$x] + $prev_right + $prev_left;
 $results[$start][$y][$x] =  $new_value ;
 }
 else
 {     $results[$start][$y][$x] =  $prev_right + $prev_left ;      }
 }
 }
 }
 $proba = 0;
 foreach($results as $starting => $test){
 if($proba < $test[$rows -1][$target] ){
 $winner = $starting;
 $proba = $test[$rows -1][$target];
 }
 }
 fwrite($oHandle, sprintf("%s %7.6f\n", $winner, round($proba, 6)) );
 }
 fclose($oHandle);
?>

3) The Studious student:

Studious Student
You’ve been given a list of words to study and memorize. Being a diligent student of language and the arts, you’ve decided to not study them at all and instead make up pointless games based on them. One game you’ve come up with is to see how you can concatenate the words to generate the lexicographically lowest possible string.

Input

As input for playing this game you will receive a text file containing an integer N, the number of word sets you need to play your game against. This will be followed by N word sets, each starting with an integer M, the number of words in the set, followed by M words. All tokens in the input will be separated by some whitespace and, aside from N and M, will consist entirely of lowercase letters.

Output

Your submission should contain the lexicographically shortest strings for each corresponding word set, one per line and in order.

Constraints

1 <= N <= 100
1 <= M <= 9
1 <= all word lengths <= 10

Example input
5
6 facebook hacker cup for studious students
5 k duz q rc lvraw
5 mybea zdr yubx xe dyroiy
5 jibw ji jp bw jibw
5 uiuy hopji li j dcyi

Example output
cupfacebookforhackerstudentsstudious
duzklvrawqrc
dyroiymybeaxeyubxzdr
bwjibwjibwjijp
dcyihopjijliuiuy

<?php
function cmp($a, $b){
if($a == $b){    return 0; }
if(preg_match(“/^$a/”, $b) == true)
{    return 1;    }
return($a < $b)? -1 : 1;
}

$rHandle = fopen(‘input.txt’, ‘r’);
$oHandle = fopen(‘output.txt’, ‘w’);
$string = “”;
while(!feof($rHandle)){
$string = fread($rHandle, filesize(‘input.txt’));
$text .= $string;
}
fclose($rHandle);
$lines = preg_split(‘%[\n,]+%’, $text);
$nb_lines_to_check = $lines[0];
foreach($lines as $index => $line)
{
if($index == 0) {
continue;
}
$words = preg_split(‘/[\s]+/’, $line);
$ordered =  array_splice($words, 1);
usort($ordered, “cmp”);
foreach($ordered as $key => $item)
{
echo $item;
fwrite($oHandle, $item);
}
echo “\n”;
fwrite($oHandle, “\n”);
}
fclose($oHandle);
?>

You can download the code here, and try it for yourself if you like:

http://www.cyber-netics.com/hackercup.tar.gz

Hackers and the computer revolution

A bit of a surprise, this book was to me. Nearly a master piece. I havn’t seen many books which have inspired me so much in the past 10 years.

This is not only a book about Hackers, but also about how they have changed the world. Mostly by chance because they were at the right place, at the right time. But they also changed the world because they were passionate people, who went to the end of their ideas. And one after the another or all hackers combined, they managed to move and change the World.

For a passionate progammer like myself, finding similar people, or roll models, could help me find the direction in which I would like to go. After reading this book, you get a much better understanding on how this computer revolution really happened. Who are some of the key people involved. How passionate they were, and what drove them to complete they role.

I don’t think many people get the chance to be at the right place at the right time, but we should at least all continue to try.

This may be a bit of a spoiler but, the story starts with the 60′s and the MIT’s AI lab, with Marving Minsky, Mc Carthy, Peter Samson, Greenblat, Gosper, Stewart Nelson, and many more. This part focuses on those people, who really had the chance to start up the basics, the assembler and first hardware machines.
Then goes on to the Silicon valley revolution, the appearance of silicon chips and the first attempt to create a personal computer, with all the people involved such as Bill Gates, Felsenstein, Steve Jobs and Wozniak with their apple computer.
The third part continues with the computer games revolutions, with the creation of Sierra Online’s Game company and the efforts of Ken and Roberta Williams, their star Hackers and their interactions with the other games companies, such as Atari.
Before finishing back with the “ishi, the last Yashi”, the last hacker which was Richard Stallman, which later became the founder of the Free software foundation.
The 25th anniversary book also has 2 short bonus chapters which give an update on the carrers of the people in this book, and the new Hackers and companies such as facebook and Google.

Overall, this is a really good history about the computer history, full of passion. This book will give a solid understanding of the computer history, which can show itself very valuable for IT professional, as a general knowledge base, in order to not do the same mistakes as others could have made. Or help you make the good key dicisions when you will need to. Or simply help you have a better understanding of those strange computer geeks, and what could be their “drive”. In a similar way as “Sophie’s World” will give you solid foundations of philosophie.

A must have book for any true IT professional…