This puzzle is from my mentor and I like how it is very pragmatic and not just a brain-teaser. So the official language of the puzzle is as below

Matter of Life or Death

An evil wizard imprisoned 64 mathematicians. The wizard announces: “Tomorrow I will have you all stand in a line, one behind the other, and put a hat on each of your heads. The hat will be either black or white. You can see the hats of everyone in front of you but you can’t see your own and you can’t turn behind. Starting from the last person in the line, I will ask the color of the hat that is on your head. You are allowed to say aloud single word answer: “white” or “black”. If you get it right, you will be released. Else you will be shot dead”. The geeks have a night to discuss their strategy. What strategy should the geeks develop so that largest number of them can survive!

Some clarifications:

  1. One don’t know what happened to previous person, all you can do is see in-front of you and “hear the response of all other people”.
  2. You can’t see the shadow of person behind you.
  3. Any other social hack, you might think of.

Let’s focus on the question again.

What strategy should the geeks develop so that largest number of them can survive!

The obvious possibility of surviving is 50% without doubt, how??. Well a group of 2 can save one of the person for sure i.e one person from the group has to tell right color to other person.

Now first the hint for better solution:

You can save significantly high number of people.


Try to solve the puzzle yourself first.



Ok fine, see the solution now.


Rang a bell??

Let’s draw the scenario

|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|

|-64-|-63-|-62-|-61-|-60-|-59-|-58-|-57-|-56-|-55-|-54-|-53-|-52-|-51-|-50-|-49-|-48-|-47-|-46-|-45-|-44-|-43-|-42-|-41-|-40-|-39-|-38-|-37-|-36-|-35-|-34-|-33-|-32-|-31-|-30-|-29-|-28-|-27-|-26-|-25-|-24-|-23-|-22-|-21-|-20-|-19-|-18-|-17-|-16-|-15-|-14-|-13-|-12-|-11-|-10-|-9-|-8-|-7-|
|-6-|-5-|-4-|-3-|-2-|-1-|

64 people, think of it as an array.

We have signal other people, what’s better than unity and forming a group? So we group people and try to signal more than one people at once.

Another hint:

Black and white! Two variables, can do anything with bits, binary?

2 people signal group

A group of two people can signal 4 four people using 2 bits. 00, 01, 10, 11.

  1. So they can signal if all people’s hat have same color using 00
  2. They can count no. of color of either pre-decided color, let’s white is the color.
  3. If the signal is black-black i.e 00, it means everyone is white so the all four people will say white.
  4. If the signal is white-black i.e 10, it means the first person can count no of white and black infront of him, if there are 2 white hats then he will say black, if there is one white hat in front of him, he way say white.
  5. Next person will account the choice of previous and do the calculation similarly.

Whoaa! never thought of it before, thought whatever is in destiny will happen. LOL.

So out of 64, 6 people can form the signal group and can give 64 kinds of signals i.e counting/numbers.

6 people signal group

Can save at-least 58 people.

So now that’s a life saving puzzle, should put enough interest to solve more puzzles.

Humor

There are 10 types of people in the world, one who understands binary and the rest who doesn’t.

Till next time.

CSS is amazing(Human err).

If it doesn’t work, you know that it is confused and won’t give an error. This confusion could have been solved by giving error/warning but CSS choose not too. That’s why all this hate for CSS on internet.

Let’s come to drawing a horizontal tree with a root in center, because WHY not. The tree structure should be like

Centered horizontal tree

A node can have multiple children, in simple terms and each tree will be centered around root. Don’t bother about responsive-ness for now, it will require some javascript and SVG which we aren’t going to do for now.

Concept(s) needed

CSS pseudo elements

What is a pseudo element?

You might have used pseudo classes abundantly, pseudo elements are similar to pseudo classes but they are used to style specific part of the selected item. For eg. :before/::before, :after/::after, :placeholder, :grammar-error etc.

That’s it, all we need is pseudo elements(as the heading states) to make the branches out of the nodes, either horizontal or vertical. Also knowledge of relative positioning and absolute positioning will come handy.

We will make this tree in parts, right part has root included itself. First lets draw the tree in crude way.

Tree skeleton

The tree skeleton is like something below:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
    <body>
<div id="wrapper">
<div id="root-left">
<div class="branch-inverse l1">
<div class="entry-inverse">
<div class="branch-inverse l2">
<div class="entry-inverse">
<div class="branch-inverse l3">
<div class="entry-inverse sole"></div>
</div>
</div>
<div class="entry-inverse"></div>
</div>
</div>
<div class="entry-inverse">
<div class="branch-inverse l2">
<div class="entry-inverse sole"></div>
</div>
</div>
</div>
</div>
<div id="main-root"><span class="label">Root</span></div>
<div id="root-right">
<!-- <span class="label">Root</span> -->
<div class="branch l1">
<div class="entry">
<div class="branch l2">
<div class="entry"></div>
<div class="entry"></div>
</div>
</div>
<div class="entry">
<div class="branch l2">
<div class="entry"></div>
<div class="entry">
<div class="branch l3">
<div class="entry sole"></div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</body>

which will look like

Tree skeleton

So we have branches, which have entry and entry can other branches and entries as its child(ren). Let’s first understand how CSS will be applied, CSS will be applied from inner most tag to other most tag, so the height of branches will add up and each branch’s height will be cumulative from previous height.

We have fixed the node’s width to 150 px here also incoming connection and outgoing connection are 50 px each, therefore a branch will be 250 px wide.

Let’s come to drawing connections, we have entry as node which is our reference for connections, we will create incoming connection on the right tree using :after pseudo element. For branch’s height we will use :before pseudo element on entry element. It’s possible to swap :before and :after but need to some alignment. Branch has the outgoing connection.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
    .entry:before {
content: "";
height: 100%;
position: absolute;
border-left: 2px solid black;
width: 50px;
left: -50px;
}

.entry:after {
content: "";
width: 50px;
border-top: 2px solid aqua;
position: absolute;
left: -50px;
top: 50%;
margin-top: 1px;
}

.branch:before {
content: "";
width: 50px;
border-top: 2px solid magenta;
position: absolute;
left: -100px;
top: 50%;
margin-top: 1px;
}

Think pseudo elements as box and then choose their side, that’s what we have done, for incoming connection we chose border-top, for branch height we chose border-left. See the image how boxes looks like.

Box border

Notice how positioning is done using top and left.

Tree skeleton demo is here..

Nodes on the tree

Now we can add label on the right and tree will look Neat like this.

Label will be like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
    .label {
display: block;
min-width: 150px;
padding: 5px 10px;
line-height: 20px;
text-align: center;
border: 2px solid silver;
border-radius: 5px;
position: absolute;
left: 0;
top: 50%;
margin-top: -15px;
overflow-wrap: break-word;
background-color: lightblue;
}

Notice the top and margin-top to make this label centered in the div using position absolute.

Whew, that’s all.

The left sub tree is easy and left as an exercise to the reader.(Just kidding.)

Left sub tree

For the left part construct the tree same as right tree but some CSS needs to be reversed. The quickest way to understand this is see the diff of two tree’s CSS

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
    -.branch {
+.branch-inverse {
position: relative;
- margin-left: 250px;
+ margin-right: 250px;
}

-
-.branch:before {
+.branch-inverse:before {
content: "";
width: 50px;
border-top: 2px solid magenta;
position: absolute;
- left: -100px;
+ right: -100px;
top: 50%;
margin-top: 1px;
}

-.entry:before {
+.entry-inverse:before {
content: "";
height: 100%;
+ border-right: 2px solid black;
position: absolute;
- border-left: 2px solid black;
- left: -50px;
+ right: -50px;
}

-.entry:after {
+.entry-inverse:after {
content: "";
width: 50px;
border-top: 2px solid aqua;
position: absolute;
- left: -50px;
+ right: -50px;
top: 50%;
margin-top: 1px;
}

-.label {
+.label-inverse {
display: block;
min-width: 150px;
padding: 5px 10px;
@@ -48,7 +46,7 @@
border: 2px solid silver;
border-radius: 5px;
position: absolute;
- left: 0;
+ right: 0;
top: 50%;
margin-top: -15px;
overflow-wrap: break-word;

Now if you notice branch is place with margin of 250 px from right in its position, the magenta color connection is placed at 100 px to right from nodes which is opposite of what is on right side tree. .entry-inverse is now positioned with respect to right and .label-inverse is also position with respect to right.

CSS polishing

Now comes the task of providing finish to the product, we want round curves instead of bland straight lines in the tree. It’s important to note on :first-child and :last-child need to have rounded corners. Like the pic given below.

Round border

Demo code is present here..

For this we have provided round border to straight line and incoming connection to the node for their :first-child and :last-child with :before and :after property individually. Also we will truncate the height to 50% and position it 50% from top.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
.entry-inverse:first-child:before {
width: 10px;
height: 50%;
top: 50%;
margin-top: 2px;
border: 1px dashed red;
border-radius: 0 10px 0 0;
}


.entry-inverse:first-child:after {
height: 10px;
border-radius: 0 10px 0 0;
border: 1px dashed blue;
}

.entry-inverse:last-child:before {
width: 10px;
height: 50%;
border-radius: 0 0 10px 0;
border: 1px dashed violet;
}

.entry-inverse:last-child:after {
height: 10px;
border-top: none;
border-bottom: 2px solid black;
border-radius: 0 0 10px 0;
margin-top: -10px;
border: 1px dashed orange;
}

If now you remove the dashed lines, you will get the straight lines except for the sole children, for that we don’t want round corner and not want to display straight line. So the below CSS will help that.

1
2
3
4
5
6
7
8
9
10
.entry-inverse.sole:after {
width: 50px;
height: 0px;
margin-top: 1px;
border-radius: 0px
}

.entry-inverse.sole:before {
display: none;
}

Right side rounded corners

Similarly the right side tree rounded corners can be handled. See the diff below for instant salvation.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
--- .entry-inverse:first-child:before { (Selection)
+++ (clipboard)
@@ -1,42 +1,43 @@
-.entry-inverse:first-child:before {
+.entry:first-child:before {
width: 10px;
height: 50%;
top: 50%;
margin-top: 2px;
border: 1px dashed red;
- border-radius: 0 10px 0 0;
+ border-radius: 10px 0 0 0;
}


-.entry-inverse:first-child:after {
+.entry:first-child:after {
height: 10px;
- border-radius: 0 10px 0 0;
+ border-radius: 10px 0 0 0;
border: 1px dashed blue;
}

-.entry-inverse:last-child:before {
+.entry:last-child:before {
width: 10px;
height: 50%;
- border-radius: 0 0 10px 0;
+ border-radius: 0 0 0 10px;
border: 1px dashed violet;
}

-.entry-inverse:last-child:after {
+.entry:last-child:after {
height: 10px;
border-top: none;
border-bottom: 2px solid black;
- border-radius: 0 0 10px 0;
+ border-radius: 0 0 0 10px;
margin-top: -10px;
border: 1px dashed orange;
}

-.entry-inverse.sole:after {
+.entry.sole:after {
width: 50px;
height: 0px;
margin-top: 1px;
border-radius: 0px
}

-.entry-inverse.sole:before {
+.entry.sole:before {
display: none;
-}
+}
+

As you can see only border radius has been changed.

Conclusion

That’s concludes our tree and sweet CSS lesson. Neat polished demo is here.

Remember you need patience with CSS else just go for SCSS/Sass. :)

And Of course it was there on the web but only the half part. Till next time.

So first technical blog of the year. It’s simple blog as it seems from the title. UX is important here too, that will also be the focus apart from code. This blog is from a task given to me by my mentor.

So let’s see the flow.

  1. We want to have two lists and item can be added and deleted in each list.
  2. An item can also be moved to other list by dragging it over to other list’s place.
  3. We want to create a placeholder where the item is going to be placed.
  4. We want to slightly tilt the item being dragged to show distinction.

So we need to know drag and drop API’s from MDN(a good documentation place). There are multiple API’s but we just need 4 of those. Those 4 are ondrag, ‘ondragover’, ‘ondragleave’, ‘ondragend’. We don’t need ondrop since we are using placeholder to mark the position to place the elements.

So let’s define the behavior.

  1. What happens when your start dragging?

Visual clue from rest of items present there(like tilted).

  1. How to show the place when an item is going to be dropped.

Show a visual clue like placeholder.

  1. What happens if drag fails(i.e it goes out of browser)?

It should come to the last visual clue it is supposed to come.

So our drag-able element/item looks like:

1
2
3
4
5
6
7
8
        <div id="item-template-container" class="item-template-container" draggable="true" ondragstart="listItemDragStartHandler(event);" ondragover="dragoverHandler(event);" ondragend="dragEndHandler(event);" ondragleave="dragLeaveHandler(event);" ondrop="onDropHandler(event);">
<div class="item-list-element">
<div class="item-text"></div>
<div class="delete-item-div">
<button class="delete-item" onclick="delete_item(event);">Delete</button>
</div>
</div>
</div>

And the 4 drag function looks like below

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
function removePlaceholder() {
if(document.getElementById('grayed-empty-node') !== null) {
document.getElementById('grayed-empty-node').remove();
}
}

function insertPlaceholder(currentElement, which) {
var isGrayEmptyNodeThere = document.getElementById('grayed-empty-node');
if(isGrayEmptyNodeThere === null) {
var listContainer = currentElement.parentNode;
var emptyNode = document.getElementById('empty-node').cloneNode(true);
emptyNode.removeAttribute('id');
emptyNode.setAttribute('id', 'grayed-empty-node');
emptyNode.setAttribute('class', 'fade-in');
emptyNode.style.height = String(heightWidth[0]) + 'px';
emptyNode.style.width = String(heightWidth[1]) + 'px';
if (which == 'over')
listContainer.insertBefore(emptyNode, currentElement);
else if (which == 'leave')
listContainer.insertBefore(emptyNode, null);
}
}

The above ones are 2 helper functions for removing and inserting placeholder as the name suggests. Also you will notice there is event.preventDefault used because some OS browsers have other behaviors for dragging an object. So we will avoid that.

listItemDragStartHandler (funny name) is an ondrag method, here we want to save the dragged item in global var source and height & width of dragged element for placeholder. Then we attach a custom image for dragging which is bit tilted to show some relevance which is also stored in a global var dragImageSource.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
function listItemDragStartHandler(event) {
source = event.currentTarget;
heightWidth = [];
heightWidth.push(source.offsetHeight);
heightWidth.push(source.offsetWidth);
event.dataTransfer.setData('text/html', event.currentTarget.innerHTML);
event.dataTransfer.effectAllowed = 'move';
// Drag image logic
dragImageSource = source.cloneNode(true);
dragImageSource.style.position = 'absolute';
// Don't show the element
dragImageSource.style.top = '0px';
dragImageSource.style.left = '-' + String(window.innerWidth) + 'px';
// dragImageSource.style.left = '-100px';
var toTiltElement = dragImageSource.getElementsByClassName('item-list-element')[0];
toTiltElement.style.transform = 'rotate(5deg)';
document.body.append(dragImageSource);
event.dataTransfer.setDragImage(dragImageSource, heightWidth[1]/2, heightWidth[0]/2);
}

We have ondragover and ondragleave methods below which basically insert placeholder according to latest movement. In dragoverHandler we hide the existing item from it’s original place and check if we are dragging over a new element using lastDragOverElementId, only then we remove existing placeholder and insert new placeholder.

1
2
3
4
5
6
7
8
9
10
11
12
function dragoverHandler(event) {
event.preventDefault();
event.dataTransfer.dropEffect = 'move';
source.style.display = 'none';
var currentElement = event.currentTarget;
var listContainer = currentElement.parentNode;
if (lastDragOverElementId != currentElement.getAttribute('id')) {
lastDragOverElementId = currentElement.getAttribute('id');
removePlaceholder();
insertPlaceholder(currentElement, 'over');
}
}

In dragLeaveHandler, this is specifically needed to have a placeholder at the end of the list because we are always appending above existing drag over element. But when element exit the list it’s place should be at end. So here we check if it has left the last visible element(remember we still have one hidden original element in the list).

Also you will notice we have a timeout here for disabling ondragleave for few moments, this is for stop a chain reaction between ondragover and ondragleave since a list element passes through the dragged element when placing the placeholder. Then at-last we set lastDragOverElementId to null since a new dragged element will hover over other element now or re-enter.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
function dragLeaveHandler(event) {
event.preventDefault();
var currentElement = event.currentTarget;
var listContainer = currentElement.parentNode;
var elementList = listContainer.getElementsByClassName('item-template-container');
var visibleElementList = [];
var i = 0;
for (i=0; i<elementList.length; i++) {
if (elementList[i].style.display !== 'none') {
visibleElementList.push(elementList[i]);
}
}
// Last element ondragleave handler should be delayed, otherwise it
// would spin off chain reaction.
var lastVisibleElement = visibleElementList[visibleElementList.length - 1];
// Basically last element
if (currentElement.id === lastVisibleElement.getAttribute('id')) {
lastVisibleElement.removeAttribute('ondragleave');
removePlaceholder();
insertPlaceholder(currentElement, 'leave');
// This delayed the chain reaction
setTimeout(function() {
visibleElementList[visibleElementList.length - 1].setAttribute('ondragleave', 'dragLeaveHandler(event);');
}, 500);
// When event is on last element set the lastDragOverElementId to null
// then dragover to lastVisibleElement(second last element) can be handled
// otherwise dragover to second last element won't show placeholder.
lastDragOverElementId = null;
}
}

This handler is needed to place the dragged element to placeholder place irrespective of drop, so drop is mouse release operation here.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
function dragEndHandler(event) {
event.preventDefault();
// Check the dropEffect
dragImageSource.remove();
var listElement = document.getElementById('grayed-empty-node')
var listContainer = listElement.parentNode;
if (event.dataTransfer.dropEffect === 'none' ||
event.dataTransfer.dropEffect === 'move') {
var grayEmptyNode = document.getElementById('grayed-empty-node');
// When grayEmptyNode is null, that will append at the end.
listContainer.insertBefore(source, grayEmptyNode);
source.style.display = '';
removePlaceholder();
}
}

Ahoy!! I can’t understand without a demo. I have a demo here. There are few things I haven’t mentioned like fading of placeholder and using livereload while developing this.

That’s all for today.

Thoughts on hackathons

After attending 7-8 hackathons, at the time of writing this. I feel there has been a missing link in each of them. Not each of the product I made at hackathon went into production, except for 2. If it isn’t ready for production, it’s not worth it. Motto of each hackathon should be

Ship it!!

Hackathons are best to meet like minded people and get introduced to cutting edge technologies. It’s an fantastic opportunity to learn from others and get evaluated for your implementation. Hackathons can be daunting at first, but that’s always the story for something good ahead.

Back at issue, production code matters. It’s a mindset. A hack in hackathon won’t last long and would add to technical debt later. A well thought code base goes long way ahead. So the protocol for any hackathon should be writing production ready code, always!.

Cheers

Tips while using raspberry pi for development. Let’s face it, it’s cumbersome to ssh into raspberry pi and write code there.

  1. Configure your ssh keys for direct login instead of password based login.

  2. Use Rsync to sync folder from working location to remote location. For example:

 rsync manual-interface/ -azP pi@192.168.43.34:/home/pi/Projects/manual-interface/ 

This command will sync the content of manual-interface on host computer to remote location which is at raspberry pi. If ssh keys are configured, one won’t need to enter password for raspberry pi.

  1. Usage of watchdog for automatic syncing the code to raspberry pi. watchdog is wonderful python package for monitoring events on file system. One can write a python script using watchdog package or simply use watchmedo shell command. For example:
watchmedo shell-command \
--patterns="*.py;*.txt;*.js;*.css;*.html" \
--recursive \
--command='rsync . -azP pi@192.168.43.34:/home/pi/Projects' \
. \

Here I am looking for pattern recursive inside the current location, on detection of changes on file system, rsync comes to rescue for syncing.

  1. Using VNC viewer for accessing GUI interface. VNC is excellent software for remote accessing the desktop, this can save extra monitor configuration.

These are few tips which are helpful to me, while working on an exciting project. Till next time.

See you in 2017. Happy New Year. Best wishes.

Cheers