2017. november 2., csütörtök

Codility simple C programming task 2 - solution

As part of my job interview process a few years ago in the UK, I was given a Codility task to solve online. I can't remember which company I applied for, neither the names of the interviewer(s). I could not solve the task back then (no wonder why, as you'll see soon), but I saved the task for the future. The time has come and I re-visited the task. After I did the code review, to my surprise, it turned out that the PROBLEM WAS NOT WITH ME but with the IT WAS TO DO WITH THE INTERVIEWER. I solved the task on my own at home and my solution is shorter, better. I publish it for public benefit and to see that it's not always the candidate unskilled but the interviewer was completely at a loss and was an incompetent bungler. The original task was simply wrong, it contained buggy code and it is not even close to being right. He should have devoted more time to prepare a good task for the candidate assessment.

The task can be seen in the attached picture below.


The task is to solve the C code by modifying "at most two lines of code". This is not possible. If something is BROKEN, you can't fix it by applying cosmetic fixes. YOU HAVE TO THROW IT AWAY. If you examine the bad code below, you can see it contains nonsense. It simply does not work. It's not even close to being a good code. I assume it's just there to derail the candidate. For e.g. if you look at the assumptions, you can see that the wrong code contains checks it should not check for, since we assume something, we should not check for it. We assume it and that's it.

BAD CODE:

int solution(int A[], int N, int K) {
   int i;
   for (i = 0; i < N - 1; i++) {
if (A[i] + 1 < A[i + 1])
          return 0;
   }
   if (A[0] != 1 && A[N - 1] != K) 
          return 0;
     else
          return 1;
}

Look at my fixed code below in its clear beauty.

GOOD CODE:

int solution(int A[], int N, int K) {
   int i;
   for (i=0; i<=N-1; i++) {
      if (A[i]==K) return 1;
   }
   return 0;
}

The correct algorithm goes like this. When you find the element of A array equals to K, we return with 1 (true). We find what we want and do not have to worry about the rest. When the check is over and no value is found that matches the key we're looking for, we will return with false (0). This is how you write simple and good code that solves the problem without the extra hassle. What can be easier than that?

I also wrote a wrapper main program to actually test the above function with different values. See below. 

task-2.h:

/* 
   This is task-2.h. It declares the function to be used in the main program. 
 */

int solution(int[], int, int);

task-2.c:

#include
#include "task-2.h"

int main() {

int noofelements=3; 
int key=2;
short rc=0;
int array[noofelements];

array[0]=1;
array[1]=1;
array[2]=3;

printf("elements in the array are:\n");
for (int i=0; i
   printf("%d\n", array[i]);
}

rc=solution(array,noofelements,key);
printf("is key %d found in array?\n", key);
if (rc==0)
   printf("false.\n");
else
   printf("true.\n");

return 0; // return true to satisfy shell

}

Put the solution() function , the good code into into a separate file task-2-fixed.c and compile and link them together with gcc and try it. IT WILL WORK. Below is the Makefile for reference:

# Makefile for task-2
#
task-2-fixed.o: task-2-fixed.c
gcc -c $<

task-2.o: task-2.c task-2.h

gcc -c $<

task-2: task-2.o task-2-fixed.o

gcc -o $@ task-2.o task-2-fixed.o

all: task-2


I feel much better as I solved the problem and proved that I am competent enough. Also, I proved that the interviewer was not good. I am happy that I was not hired by that company at the time! Problem solved. If you need help with the code, it's been tested by me and works successfully.

;-)

qmi
2 Nov 2017

UPDATE:
A friend of mine, Zoltan Hanko pointed out to me that although my solution may be correct finding the key K in the array A but that task was not exactly that in the first place. He was right. The task is to check whether array A contains number 1,2.......K and no other numbers. I am sorry, I overlooked it. My solution above only finds the key K and returns with true if found. I fixed my code so that it checks for stray numbers that are greater than K and also checks if there is no 0 (zero) among the array elements. Since the original task description says that 'assume that the array elements are sorted in non-decreasing order', I do not check if they are out of order. See the fixed code below:

int solution(int A[], int N, int K) {
   short found=0;
   int i;
   for (i=0; i<=N-1; i++) {
      if ((A[i]==0) || (A[i]>K)) return 0;
      if (A[i]==K) found=1;
   }
   if (found==1) 
return 1; // true
   else
return 0; // false
}

It is tested and works. For e.g., with array values 1,1,2,3 taken as input the function returns false, because even though key K=2 is found but the last index value is 3, which is a stray number larger than K. Therefore returns with false. However, even with the above code and now finally the original task requirement is fully met, the above working code is NOT EVEN CLOSE TO THE ORIGINAL BROKEN ONE. The interviewer who prepared this task was obviously incompetent.

Take away: I suggest every interviewer to come up with value-added and well written tasks to AVOID WASTING TIME of the unsuspecting candidate.

qmi

7 Nov 2017


2017. október 30., hétfő

Codility simple SQL task 1 - solution

Intro 

A while ago I applied for a job and as part of the application process, I was tasked with a simple task to solve online: a straightforward SQL task to which I was given a link on codility.com for the specific task. This online task was used a candidate skill measurement. I had a 2h time limit, I can't remember the result but I remember that I was not selected later on in the application process. Anyway, I was smart enough to use my laptop's screenshot key to save my screen shot ;-). The task is simple and small, it is good to measure your basic SQL skills. It can be used in computer science school as well to teach students. I wanted to share how I solved it just in case someone finds it useful.

The task was to write an SQL query that returns the list of invoices with the total price of each. The data and the relational database format is given as it is shown in the picture.


As it is seen, the database just contains one table named invoice_items which contains three records.

Solution

My solution uses the sqlite3 program for sake of simplicity. You can use your own favourite relational database software whichever you like. The only requirement is that it could understand SQL queries. First you fill in the data like below. In the end, don't forget to save the in-memory database to the file named invoices.

bash$ sqlite3
sqlite>
CREATE TABLE invoice_items (inv_num INTEGER, item TEXT, price INTEGER);
INSERT INTO "invoice_items" VALUES(3,'a',10);
INSERT INTO "invoice_items" VALUES(3,'b',15);
INSERT INTO "invoice_items" VALUES(1,'c',7);
sqlite> .save invoices;
sqlite>
bash$

At this point, your data has been added and you have a tiny database with one table and three records. Now, go back to sqlite3 and run the simple query to see all records first. 

bash$ sqlite3
sqlite> .mode column
sqlite> .headers on
sqlite> select * from invoice_items;
inv_num     item       price       
---------   ---------  -----------
3           a          10
3           b          15
1           c          7
sqlite>


OK so far, we got the data. The solution below uses the sum() function to summarize (to sum up) the values in the price column. We need to calculate the total price for each invoice item and that function does the work. Then, we need to aggregate the records by using the GROUP BY clause. Then we need to sort the results by using the ORDER BY clause in descending order (that is what the DESC word denotes). These are built into SQL and every implementation should be able understand them, not only sqlite3. The one-line SQL query looks like this:

SELECT inv_num, sum(price) FROM invoice_items GROUP BY inv_num ORDER BY inv_num DESC;

Let's run the above query in sqlite3 prompt as shown below:

bash$ sqlite3
sqlite> select inv_num, sum(price) from invoice_items group by inv_num order by inv_num desc;
inv_num     sum(price)
-------     ----------
3           25
1           7

Voila! The task is solved. We got the expected result. Let me know if you have any questions.

:-)

qmi
30 October, 2017

2017. szeptember 19., kedd

Difference between URL masking and URL redirect

Hi guys. It's been a while since I wrote something on here. While I was looking at the URL redirects on my website, I noticed that I should actually mask the URLs that should look nicer. I have got a few redirects in order to use them on external referral sites and they end up hitting my website. When the resulting link is masked, it looks nicer and reveals less information to the visitor.

So the redirects I have got set up are as follows:

www.miklos.info/munka → www.miklos.info/hu/3/it-konzultacio?lang=hu
www.miklos.info/consulting → www.miklos.info/en/3/itconsultation?lang=en

When the above referring links are getting visited, they used to be rewritten in the browser title bar so the resulting links were displayed until now. I wanted the URL to be masked and the visited link URLs are not be rewritten but keep the original links in the browser title bar displayed, the content however would be served. I am using Apache as a web server on my website, so the Redirect and Rewrite rules can be used via the Rewrite Engine feature :-) . So far I had redirects in my webpage .htaccess file in the web root directory as below.

Redirect /munka /hu/3/it-konzultacio?lang=hu
Redirect /consulting /en/3/itconsultation?lang=en

The above redirects work fine but it results the browser's title bar containing the long, unmasked link when you used to visit the site. 


Note that here I do not need to redirect the request to another site, I just need them remain on the same site, but with different URLs. I would like the URL masked in the title bar. After having read the official documentation and pondering a little bit, I realized how can I mask the URLs. You can just simply use the RewriteRule directive! So simple. It masks the URLs and the serves the content from the resulting links without changing the URL in the display bar. Let's see how to solve the problem by using the correct rewrite rules. My configuration is as below. 

RewriteEngine On
RewriteRule ^munka$ /hu/3/it-konzultacio?lang=hu [L]
RewriteRule ^consulting$ /en/3/itconsultation?lang=en [L]

Save and quit the config file and reload the webpage in browser. After applying the new rewrite rules in Apache, I get the new content served but with the original URL! So with the word munka, the content on the line following is being served (/hu/3/it-konzultacio?lang=hu) and visiting the site with the word consulting in the URL in the end, the content is served which is on the line to the right after the word (/en/3/itconsultation?lang=en).


Voila! The web page(s) are served with the new, redirected content but the URL remains the original, masked! This is how you mask the URL in the title bar with Apache using the rewrite rule feature. 

😄

qmi
19 September, 2017