Karel is placed in a world that contains a binary tree represented by beepers. Each node of the tree is located on a single field and may contain one or more beepers. The root of the tree is placed somewhere in the world, and its children are always located exactly one row below their parent, with the left child positioned to the left and the right child positioned to the right. On each lower level of the tree, the horizontal distance between a parent node and its children is reduced by half. The leaf nodes of the tree are located on the lowest level and can be identified by the presence of a wall directly below them.
In the top-left corner of the world, there is a field containing a number of beepers that represents a target value. The task is to determine whether there exists a path from the root of the tree to any leaf such that the sum of all beepers encountered along that path, including both the root and the leaf, is exactly equal to the target value. While exploring the tree, Karel may use only standard SuperKarel commands and must correctly return to parent nodes when a branch does not lead to a valid solution, without modifying the structure of the tree.
If such a path exists, Karel must finish in the top-left corner of the world facing west. If no such path exists, Karel must finish in the top-right corner of the world facing west.


I already:
read the target value from the top-left corner
find the tree root
compute the horizontal offset to the first child below the root (
get_offset())and I understand that each next level has half of this offset
My question is:
How should I structure the backtracking so that Karel goes down one branch, checks the sum at the leaf, and if it fails, correctly returns to the parent and tries the other branch, without causing stack overflow or losing orientation?
#include <superkarel.h>
#include <stdbool.h>
void turn_around()
{
turn_left();
turn_left();
}
void turn_right()
{
turn_left();
turn_left();
turn_left();
}
void face_south()
{
while (not_facing_south())
{
turn_left();
}
}
void face_north()
{
while (not_facing_north())
{
turn_left();
}
}
void face_east()
{
while (not_facing_east())
{
turn_left();
}
}
void face_west()
{
while (not_facing_west())
{
turn_left();
}
}
int count_beepers()
{
int pocet = 0;
while (beepers_present())
{
pick_beeper();
pocet++;
}
while (beepers_in_bag())
{
put_beeper();
}
return pocet;
}
void find_tree_crown()
{
while (no_beepers_present())
{
while (front_is_clear() && no_beepers_present())
{
step();
}
if (beepers_present())
{
break;
}
if (facing_east())
{
turn_right();
if (!front_is_clear())
break;
step();
turn_right();
}
else if (facing_west())
{
turn_left();
if (!front_is_clear())
break;
step();
turn_left();
}
}
}
void take_steps(int steps){
while(steps > 0){
step();
steps--;
}
}
int get_offset(){
int number_of_steps = 0;
face_south();
step();
face_west();
while(front_is_clear() && no_beepers_present()){
step();
number_of_steps++;
}
if(beepers_present()){
face_east();
take_steps(number_of_steps);
face_north();
step();
return number_of_steps;
}
face_east();
take_steps(number_of_steps);
number_of_steps = 0;
face_east();
while(front_is_clear() && no_beepers_present()){
step();
number_of_steps++;
}
face_west();
take_steps(number_of_steps);
face_north();
step();
return number_of_steps;
}
int main()
{
turn_on("task-2.kw");
set_step_delay(50);
step();
int starting_beepers = count_beepers();
printf("%d", starting_beepers);
face_east();
step();
find_tree_crown();
face_south();
int number_of_steps = get_offset();
if(number_of_steps == -1){ // this does nothing, its here temporarily to avoid error
step();
}
turn_off();
return 0;
}