Consider a special family of Engineers and Doctors with following rules :
- Everybody has two children.
- First child of an Engineer is an Engineer and second child is a Doctor.
- First child of an Doctor is Doctor and second child is an Engineer.
- All generations of Doctors and Engineers start with Engineer.
The first few levels of the family tree are shown below :

Given the 1-based level and pos (position from left) of a person in above ancestor tree, return their profession as a string: either "Engineer" or "Doctor".
Examples :
Input : level = 4, pos = 2
Output : Doctor
Explanation : The 4th level would be [Engineer, Doctor, Doctor, Engineer, Doctor, Engineer, Engineer, Doctor]. The 2nd person is a Doctor.Input : level = 3, pos = 4
Output : Engineer
Explanation : As shown in the tree given above, person at level 3 and pos 4 is Engineer.
Table of Content
[Naive Approach] Using Recursion – O(level) Time and O(level) Space
The idea is to recursively determine the profession of the parent node and then derive the current node’s profession based on its position. An engineer produces an engineer at odd position and a doctor at even position, while a doctor produces a doctor at odd position and an engineer at even position. By recursively moving upward to the root, we can determine the profession at the required level and position.
- Start from the given (level, position) and recursively move to its parent node
- Base case: profession at level
1is always Engineer - Determine current profession based on parent profession and whether position is odd or even
- Return the final profession for the given node
#include <bits/stdc++.h>
using namespace std;
string profession(int level, int pos)
{
// Base case
if (level == 1)
return "Engineer";
// Recursively find parent's profession. If parent
// is a Doctor, this node will be a Doctor if it is
// at odd position and an engineer if at even position
if (profession(level - 1, (pos + 1) / 2) == "Doctor")
return (pos % 2) ? "Doctor" : "Engineer";
// If parent is an engineer, then current node will be
// an engineer if at add position and doctor if even
// position.
return (pos % 2) ? "Engineer" : "Doctor";
}
int main(void)
{
int level = 4, pos = 2;
cout << profession(level, pos) << endl;
return 0;
}
import java.util.*;
public class Main {
// Function to determine profession
public static String profession(int level, int pos)
{
// Base case
if (level == 1)
return "Engineer";
// Recursively find parent's profession. If parent
// is a Doctor, this node will be a Doctor if it is
// at odd position and an engineer if at even
// position
if (profession(level - 1, (pos + 1) / 2)
.equals("Doctor"))
return (pos % 2 != 0) ? "Doctor" : "Engineer";
// If parent is an engineer, then current node will
// be an engineer if at odd position and doctor if
// even position.
return (pos % 2 != 0) ? "Engineer" : "Doctor";
}
// Driver code
public static void main(String[] args)
{
int level = 4, pos = 2;
System.out.println(profession(level, pos));
}
}
def profession(level, pos):
# Base case
if level == 1:
return "Engineer"
# Recursively find parent's profession. If parent
# is a Doctor, this node will be a Doctor if it is
# at odd position and an engineer if at even position
if profession(level - 1, (pos + 1) // 2) == "Doctor":
return "Doctor" if pos % 2 else "Engineer"
# If parent is an engineer, then current node will be
# an engineer if at odd position and doctor if even
# position.
return "Engineer" if pos % 2 else "Doctor"
if __name__ == "__main__":
level = 4
pos = 2
print(profession(level, pos))
using System;
public class GFG {
public static string profession(int level, int pos)
{
// Base case
if (level == 1)
return "Engineer";
// Recursively find parent's profession. If parent
// is a Doctor, this node will be a Doctor if it is
// at odd position and an engineer if at even
// position
if (profession(level - 1, (pos + 1) / 2)
== "Doctor")
return (pos % 2 != 0) ? "Doctor" : "Engineer";
// If parent is an engineer, then current node will
// be an engineer if at odd position and doctor if
// even position.
return (pos % 2 != 0) ? "Engineer" : "Doctor";
}
public static void Main()
{
int level = 4, pos = 2;
Console.WriteLine(profession(level, pos));
}
}
function profession(level, pos)
{
// Base case
if (level === 1)
return "Engineer";
// Recursively find parent's profession. If parent
// is a Doctor, this node will be a Doctor if it is
// at odd position and an engineer if at even position
if (profession(level - 1, Math.floor((pos + 1) / 2))
=== "Doctor")
return (pos % 2) ? "Doctor" : "Engineer";
// If parent is an engineer, then current node will be
// an engineer if at odd position and doctor if even
// position.
return (pos % 2) ? "Engineer" : "Doctor";
}
// Driver code
let level = 4, pos = 2;
console.log(profession(level, pos));
Output
Doctor
[Optimal Approach] Using Bit Manipulation – O(log(pos)) Time and O(1) Space
The result depends upon on set bit count in
(pos - 1). If the count of set bits is even, the profession is Engineer, otherwise, Doctor. Level input isn't necessary because first elements are same, please see the below sequencesLevel 1: E
Level 2: ED
Level 3: EDDE
Level 4: EDDEDEED
Level 5: EDDEDEEDDEEDEDDEEvery level is obtained by concatenating the previous level and complement of the previous level.
Steps to Solve
- Compute (
pos - 1)for the given position and number of set bits in it. - If the set bit count is even, return Engineer else Doctor
How does this work?
- Let us encode Engineer as
0 andDoctor as1. - First child keeps the same value and second child flips (complements) the it.
- Let us write
(pos - 1)in binary. Each bit tells the path from the root:0-> first child (no flip) and 1 -> second child (flip) - Therefore, even number of flips -> still Engineer (
0) and odd number of flips -> Doctor (1) - That is why the answer depends on the parity of set bits.
#include<bits/stdc++.h>
using namespace std;
int countSetBits(int n)
{
int count = 0;
while (n)
{
n &= (n-1);
count++;
}
return count;
}
string profession(int level, int pos)
{
int c = countSetBits(pos-1);
return ((c % 2) ? "Doctor" : "Engineer");
}
int main()
{
int level, pos;
level = 3;
pos = 4;
cout << profession(level, pos) << endl;
return 0;
}
public class Main {
// Function to count set bits in an integer
static int countSetBits(int n) {
int count = 0;
while (n!= 0) {
n &= (n - 1);
count++;
}
return count;
}
static String profession(int level, int pos) {
int c = countSetBits(pos - 1);
return (c % 2!= 0)? "Doctor" : "Engineer";
}
public static void main(String[] args) {
int level = 3;
int pos = 4;
System.out.println(profession(level, pos));
}
}
def countSetBits(n):
count = 0
while n:
n &= (n - 1)
count += 1
return count
def profession(level, pos):
c = countSetBits(pos - 1)
return "Doctor" if c % 2 else "Engineer"
if __name__ == '__main__':
level = 3
pos = 4
print(profession(level, pos))
using System;
public class GFG {
// Function to count set bits in an integer
static int countSetBits(int n)
{
int count = 0;
while (n != 0) {
n &= (n - 1);
count++;
}
return count;
}
static string profession(int level, int pos)
{
int c = countSetBits(pos - 1);
return (c % 2 != 0) ? "Doctor" : "Engineer";
}
public static void Main()
{
int level = 3;
int pos = 4;
Console.WriteLine(profession(level, pos));
}
}
function countSetBits(n) {
let count = 0;
while (n) {
n &= (n - 1);
count++;
}
return count;
}
function profession(level, pos) {
let c = countSetBits(pos - 1);
return (c % 2)? "Doctor" : "Engineer";
}
// Driver code
let level = 3;
let pos = 4;
console.log(profession(level, pos));
Output
Engineer