Thursday, August 18, 2011

Java puzzler - Letter went missing

Recently I've implemented function that takes String and populates long so that it contains character values from the back of the string. However my unit test is failing because one Letter is missing. Are you able to put it to the right place so that unit tests will not fail without debugging the code?

import static org.junit.Assert.*;
import org.junit.Test;

public class StringToolsTest {

	static final char [] data = {0xca, 0xfe, 0xeb, 0xab, 0xee};
	static final String string5 = String.valueOf(data);
	static final String string0 = "";
	static final String string1 = "a";
	static final String string9 = "987654321";
	
	@Test
	public void testFillBackwards() {
		long l = 0;
		assertEquals(0xcafeebabeeL, StringTools.fillBackwards(string5, l));
		assertEquals(0L, StringTools.fillBackwards(string0, l));
		assertEquals(0x61L, StringTools.fillBackwards(string1, l));
		assertEquals(0x3837363534333231L, StringTools.fillBackwards(string9, l));
	}
}

public class StringTools {
	public static long fillBackwards(String s, long d)
	{
		long result = 0L;
		byte[] bytes = s.getBytes();
		for (int i=0; i<Math.min(8,bytes.length); i++){
			result |= ((bytes[bytes.length-i-1] & 0xff) << (8*i));
		}
		return result;
	}
}

Solution bellow (highlight to show):
The problem is on the line 29 in "& 0xFF". I should be doing &0xFFL instead. Why ? bytes[x]&0xff is by default int (both operands are widened to int), but then << is applied, result of which is type of left operand (java spec) and this is |= to long result. Solution is to make & operator to work on long values by adding L to 0xFF.
Puzzler on snipplr.

Saturday, August 13, 2011

Question Interview

One of my friends got this question on his interview: "Given is an arbitrary long string, revert order of words in the string". If the input is "Hello World!", function should modify string to: "World! Hello". Function must have this interface: "void revert(char * string)". It must work in linear time O(n) and have no special memory requirements M(1).

My solution (spoiler alert)

Thursday, July 21, 2011

Java puzzler - How many integers are in the box ?

This is most basis Java Puzzler. Question is, how will the output look like ?
  • Will it print out powers of 10 starting from 1 ending at 10000000.
  • Or will it print just 1.
  • Or will it print any other number.
  • Or will it loop forever.
  • Or anything else.
package sk.adino.puzzlers;

import static org.junit.Assert.*;
import org.junit.Test;

public class AutoboxingTest {

	@Test
	public void test() {
		int i=1;
		while(i<10000000) {
			System.out.println("value:" + i);
			Integer j=i;
			Integer k=i;
			if (j==k){
				i=i*10;
			}else break;
		}
		assertEquals(i,1000);
	}
}

Thursday, June 2, 2011

Puzzler for C developer role

Today, I've created puzzler for C developer at company I work for. This is one of rare cases where we can publish the code, and it's few lines anyhow, so here I give it a shot. You can try to solve the puzzler, as described in comments. It's very easy and you should have no problem solving it without Solaris. All you need is a C compiler.

Bonus question: why did I choose (R) and (C) instead of R and C ?

Bellow is the code which you can find also on snipplr:


  1. /** This program should be compiled using following command:
  2.  $ cc -g -o test_hr_test test_hr_test.c
  3.  Original developer Malvin left company to pursue his dream and went
  4.  to live with wild ligers. No-one ever heard any word about him since
  5.  he left. We've managed to recover source code from his source repo.,
  6.  but program seems to be broken. Strangely Malvin used iso-8859-1 as
  7.  his console encoding.
  8.  Hints:
  9.  - program does not compile
  10.  - we were not able to recover whole function permutateBlockRev()
  11.  - program crashes on our X86 solaris 10 matchine (not on linux)
  12.  Are you the one which can help us recover the password ?
  13.  Send it to: rpc-hr@ri-rpc.sk
  14.  */
  15. #include <stdio.h>
  16. #include <string.h>
  17. /** bit manipulation macros */
  18. #define CLRBIT( STR, IDX ) ( (STR)[(IDX)/8] &= ~(0x01 << (7 - ((IDX)%8))) )
  19. #define SETBIT( STR, IDX ) ( (STR)[(IDX)/8] |= (0x01 << (7 - ((IDX)%8))) )
  20. #define GETBIT( STR, IDX ) (( ((STR)[(IDX)/8]) >> (7 - ((IDX)%8)) ) & 0x01)
  21. /** permutation works on unsigned char blocks of size 8 */
  22. #define BLOCK_SIZE 8
  23. typedef unsigned char[BLOCK_SIZE] block;
  24. /** Function does reverse permutation to DES initial block permutation as described at
  25.  http://en.wikipedia.org/wiki/DES_supplementary_material
  26.  @param b - block which will be permutated in-place
  27.  @note indexes start from 0 contrary to wikipedia initialization vector - C like index
  28.  */
  29. void permutateBlockRev(block b)
  30. {
  31. int i;
  32. static const int initialPermuteMap[64] =
  33. {
  34. 57, 49, 41, 33, 25, 17, 9, 1,
  35. 59, 51, 43, 35, 27, 19, 11, 3,
  36. 61, 53, 45, 37, 29, 21, 13, 5,
  37. 63, 55, 47, 39, 31, 23, 15, 7,
  38. 56, 48, 40, 32, 24, 16, 8, 0,
  39. 58, 50, 42, 34, 26, 18, 10, 2,
  40. 60, 52, 44, 36, 28, 20, 12, 4,
  41. 62, 54, 46, 38, 30, 22, 14, 6
  42. };
  43. /* There are few lines of code missing */
  44. }
  45. int main (void)
  46. {
  47. unsigned char str[BLOCK_SIZE + 1] = "DummyStr";
  48. block permutated = { 0x7a, 0xd2, 0x21, 0x3c, 0x05, 0x85, 0x8d, 0x71 };
  49. permutateBlockRev(permutated);
  50. strcpy(str, permutated);
  51. printf("Password is: %s\n", str);
  52. }

Sunday, May 29, 2011

How to convert multi-page HTML e-book for Kindle

Recently I've got link to the interesting e-book Architecture of Open Source applications. Because I prefer to read books on my Kindle and there was no MOBI version I've decided to prepare it myself. Here is step-by-step guide on how to convert multi-page HTML to format suitable for Kindle on your Ubuntu/Debian/Other linux.

Getting data

First of all we need to get HTML/CSS and image files to local machine. On my machine it's as simple as:
$mkdir ~/aosabook; cd ~/aosabook
$wget -I en,images -nd -r -k -l 3 http://www.aosabook.org/en
We want to download all documents recursively but only from en and images directories, don't create directory structure to local copy and replace paths in html documents so they're locally referenced. For more details check man wget.

Convert to single HTML

Now we have all data downloaded in ~/aosabook and to check whether book is readable we just have to open file:///home/aosabook/ in browser.
Because the structure of the web is multi-page, we have to do additional step. Convert the multi page document into single page. I've used htmldoc utility for this. Run htmldoc and do following:
  • input tab
    • choose Document Type: Book
    • Use add files button to add all html files from ~/aosabook/
    • Select cover image
  • output tab
    • set output to file
    • set output path to ~/aosabook/aosabook.html
    • set output format to html
Play with some other options namely width (set it to 600px for kindle 3) and hit generate.

Convert to Mobi

In order to convert to MOBI format suitable for Kindle, I've just added generated aosabook.html as book to Calibre (you use calibre for your kindle management right?) and clicked on book to convert to Mobi and upload to device.

Friday, January 23, 2009

WTF #2

This must be work of some dark evil mastermind.

void DECIMAL_TO_HEXA( int num, char *hex )
{
int aux_hex[32],i=0;
char hexa[32], resu[32];

while(num>0) {
aux_hex[i]=num%16;
num/=16;
i++;
}

resu[0]='\0';
i--;
for(i;i>=0;i--) {
if (aux_hex[i]<10) {
sprintf(hexa, "%d", aux_hex[i]);
strcat(resu, hexa);
}
else if (aux_hex[i]==10) strcat(resu, "A");
else if (aux_hex[i]==11) strcat(resu, "B");
else if (aux_hex[i]==12) strcat(resu, "C");
else if (aux_hex[i]==13) strcat(resu, "D");
else if (aux_hex[i]==14) strcat(resu, "E");
else if (aux_hex[i]==15) strcat(resu, "F");
}
strcpy(hex, resu);
}

Thursday, November 27, 2008

C/C++ puzzler #2 - Is it typo ?

Ok, here is next C/C++ specific puzzler. Puzzler here is to guess, what will be result of program ?

  1. It won't compile

  2. It will compile, but it will segfault when we try to run it

  3. It will run and print 4 times 30

  4. Anything else you can think of



Highlight text bellow code to find out correct answer.


/* compile with cc -g -o test_typedef_sizeof test_typedef_sizeof.c */
#include <stdio.h>
#include <string.h>

typedef char name_t[30];

void fn(name_t value)
{
printf("%d\n", sizeof(name_t));
printf("%d\n", sizeof(value));
}

int main (void)
{
name_t aa;

printf("%d\n", sizeof(name_t));
printf("%d\n", sizeof(aa));

fn(aa);
return 0;
}



I'll just show you program output:

30
30
30
4

Is it not, what you have expected ? Fine, let's walk the program together. On entry to main() program prints sizeof(user defined type name_t), which has length of 30 chars. Next it'll print sizeof(instance of name_t) which again is 30 chars long. Then it calls function fn(instance of name_t), In fn() it prints sizeof(user defined type name_t) which is again 30 bytes. But when it tries to print sizeof(value) it prints 4, because arrays are passed as reference to first element in C/C++. And the sizeof(pointer) is 4 respectively 8 for 64 bit system.