But Can They Code?
Last update: Sat Jun 20 09:02:22 EEST 2026
One common problem nowadays in the software industry is being able to tell while recruiting whether a candidate can actually code or not. By this I don’t mean if they can write code that is good but if they can write code at all without relying on external help or will taking the crutch away leave them completely stumped on what even the most basic building blocks are that they are supposed to have already used to the extent that they shouldn’t be able to forget them even if they wanted to.
The question that haunts us is if code signed off on by those who are completely reliant on their tools be trusted to know how to handle those tools appropriately and to understand the basics of the field to the extent that they can judge if the tool enables them to do quality work or not. Yes, this is a reference towards vibe coding.
Yes, nowadays the field of programming is progressing at a breakneck pace and is already so broad that no one can know everything so there’s always going to be a big element in looking things up and learning but the fundamentals themselves haven’t changed since the end of the 1970s when basically all the big paradigms had already been discovered.
There’s also the question of if if someone who doesn’t have a firm grasp of the basics is even capable of understanding exactly what it is that they are supposed to be looking up. The job of the school is to bring them up to a level where they at least have the basic vocabulary down to some extent.
So I find myself going back to the question of if we should just test them by having them do live coding in pseudocode using pen and paper or a whiteboard. I’m not saying we should watch over their shoulder while they’re doing it as that will likely just lead to anxiety that makes them underperform but we could just ask them to do it like folks for ages did in traditional pen and paper school exams.
So put the person in a room with writing materials and ask them to write pseudocode to solve a few problems, give them enough time to do it properly, answer any questions they might have and then go over it with them and ask them to explain their thought process.
Although it is of great interest which programming languages potential new recruits are proficient in as depending on the language it can take anything from a few months to a year for them to rise to the level of being able to properly contribute we’ll set the bar lower here and instead focus on if they have the routine down with any programming language.
So all that we are trying to figure out is if they’ve written enough simple pseudocode to be able to write code without having to look up the most basic elements of programming. If they have the generic conceptual language of programming down to routine. That they know and understand things such as loops, conditionals, assignments, functions, etc. and use them to express themselves at the drop of a hat just like they can draw simple graphs, write prose and do simple math on a whiteboard or on paper whenever they want without having to look up online what the rules for writing simple code are.
Example Test
With only the given writing tools and what’s inside your mind show and explain using example pseudocode the simplest way you can think of for solving the given problems from scratch without having access to an extensive modern standard library with pre-built data structures and algorithms. You can take shortcuts in the way you write your code but not in its logic.
You can write any number of functions, tests, classes, comments, etc. that you think are necessary. The pseudocode can resemble any language you want but do remember what the goal of the test is. You are to try to t convince the interviewer that you can clearly think through the problems and solve them in a simplest, shortest, and most straightforward way you can think of.
If something is unclear about the problems you can ask about it. But some things like especially how to solve them are intentionally left unspecified so that you can demonstrate your creativity and problem solving skills.
Leap Year
In the Gregorian calendar, a leap year is defined as:
Is divisable by 4, but not by 100, unless also divisable by 400.
So for example 1900 is not a leap year but 2000 is a leap year. 2001 isn’t but 2004 is.
This task is about a function isLeapYear that given a year number returns a
true or false.
Task A
Write a test suite that verifies that the isLeapYear function
works correctly based on the info given above.
Task B
Write the code for the isLeapYear function itself.
Sorted Array of Numbers
We start with a list of numbers: 10, 0, 5, 3, 8, 2 in this specific order.
Task A
Write the implementation for a list data structure made out of pairs. Each of these pairs is either a class, a struct, an array or an object. Each holds a number and points to the next pair in the list.
Show in code how to add the numbers given above into the list and then print the values in the list in the order above on a single line separated by space.
Task B
Show in code how to sort the list from the smallest to the largest and then print the values in that order on a single line separated by space.
Clumsy Robots in Mazes
There are robots in two-dimensional mazes of arbitrary sizes made of squares. They need to try to get out.
The mazes:
- are randomly generated out of free and blocked squares
- are randomly generated and at least 3 squares high and wide
- any square that is free and at the edge of the maze is an exit square
- always have a way out
- contain no loops
The robots:
- can only face one of the four cardinal directions: north, south, east, west
- can move forward one square with
move()that returns a truth value telling you if it went ok or not - can turn left or right by 90 degrees with
left()andright() - can only be on and move onto free squares
- have a random starting position and direction but they won’t be on an exit square
- once you reach an exit square the program automatically ends successfully
An example maze below. X is blocked and all other squares are free. As extra markup to make this example easier to read R is also a robot’s starting position, + shows the direction it’s facing, and exit squares are marked with a -.
XXXXXXXXXXX--XXX X XX XX XX XX X X X R+ X XX XX+XX X XX X X R XX XX X X X XX XXX XXX X X X X X X XXXXX--XX-XXXXXX
Task
You have at your disposal move(), left() and right().
Write a function called escape using the given functions to program a robot to
be able to escape any maze that follows these rules.
Example Solutions
Leap Year A
assert.isFalse(isLeapYear(1900), "Test failed for 1900")
assert.isTrue(isLeapYear(2000), "Test failed for 2000")
assert.isFalse(isLeapYear(2001), "Test failed for 2001")
assert.isTrue(isLeapYear(2004), "Test failed for 2004")
Leap Year B
func isLeapYear(year) {
if year % 400 == 0 { return true }
if year % 100 == 0 { return false }
if year % 4 == 0 { return true }
return false
}
Sort Array A
Solving with cons pairs.
struct pair {
value int
next *pair
}
func add(head **pair, value int) {
p := &pair{value: value, next: *head}
*pair = p
}
var list *pair = nil
add(&list, 2)
add(&list, 8)
add(&list, 3)
add(&list, 5)
add(&list, 0)
add(&list, 10)
for p = list; p != null; p = p.next {
print(pair.value)
}
Sort Array B
Bubble sort.
func nth(p *pair, n int) {
if n = 0 { return p }
return nth(p.next, n-1)
}
func len(p *pair) {
n := 0
while p != null { n++; p = p.next }
return n
}
for i := 0; i < len(list); i++ {
for j := i; j < len(list); j++ {
p := nth(list, i)
q := nth(list, j)
if p.value > q.value {
t := p.value
p.value = q.value
q.value = t
}
}
}
for p = list; p != null; p = p.next {
print(pair.value)
}
Clumsy Robots in Mazes
func back() { right(); right(); move(); right(); right() }
func wallInFront() {
r := move()
if r { back() }
return !r
}
func wallOnLeft() {
left()
v := wallInFront()
right()
return v
}
func escape() {
// forward until you can't. you'll find a wall
for !move() {}
// put it on your left
right()
// move forward following the wall on the left
for {
if !wallOnLeft() { left(); move(); continue }
if !wallInFront() { move(); continue }
right()
}
}
Solutions in C
I wanted to verify that I actually got the code somewhat right as I was writing the solutions essentially blindfolded myself as well and that I wouldn’t be asking for things that I myself can’t even deliver. And yes, I did find a couple of errors while writing the solutions into C. But then again as far as I can remember I haven’t written any C in 14 years so for it to still feel somewhat easy is something I found a bit surprising but then again we aren’t coding anything that difficult here.
Leap Year
#include <stdio.h>
#include <assert.h>
int isLeapYear(int year) {
if (year % 400 == 0) return 1;
if (year % 100 == 0) return 0;
if (year % 4 == 0) return 1;
return 0;
}
int main() {
assert(isLeapYear(1900) == 0);
assert(isLeapYear(2000) == 1);
assert(isLeapYear(2001) == 0);
assert(isLeapYear(2004) == 1);
}
Sorted Arrays of Numbers
#include <stdio.h>
#include <malloc.h>
struct pair {
int v;
struct pair *next;
};
void add(struct pair **list, int v) {
struct pair *p = malloc(sizeof(struct pair));
p->v = v;
p->next = *list;
*list = p;
}
struct pair *list = NULL;
void task_a() {
add(&list, 2);
add(&list, 8);
add(&list, 3);
add(&list, 5);
add(&list, 0);
add(&list, 10);
for (struct pair *p = list; p != NULL; p = p->next) {
printf("%d ", p->v);
}
printf("\n");
}
struct pair *nth(struct pair *list, int n) {
if (n == 0) {
return list;
}
return nth(list->next, n - 1);
}
int len(struct pair *list) {
int n = 0;
while (list != NULL) {
n++;
list = list->next;
}
return n;
}
void task_b() {
for (int i = 0; i < len(list); i++) {
for (int j = i; j < len(list); j++) {
struct pair *p = nth(list, i);
struct pair *q = nth(list, j);
if (p->v > q->v) {
int t = p->v;
p->v = q->v;
q->v = t;
}
}
}
for (struct pair *p = list; p != NULL; p = p->next) {
printf("%d ", p->v);
}
printf("\n");
}
int main() {
task_a();
task_b();
}
Clumsy Robots in Mazes
/* BELOW IS SUPPORT CODE */
#include <stdio.h>
#include <stdlib.h>
#include <setjmp.h>
#include <uchar.h>
int strpos(const char32_t *s, char32_t c) {
for (int i = 0; *s; i++, s++) {
if (*s == c) return i;
}
return -1;
}
char32_t maze[8][16] = {
{U"XXXXXXXXXXX--XXX"},
{U"X XX XX XX XX"},
{U"X X X w X XX"},
{U"XX XX X XX sX"},
{U"X n XX XX X X"},
{U"X XX e XXX XXX X"},
{U"X X X X X"},
{U"XXXXX--XX-XXXXXX"}
};
#define NORTH 0
#define EAST 1
#define SOUTH 2
#define WEST 3
char32_t *directions = U"nesw";
void removeTracesOfRobots() {
for (int y = 0; y < 8; y++) {
for (int x = 0; x < 16; x++) {
if (strpos(directions, maze[y][x]) != -1) {
maze[y][x] = U' ';
}
}
}
}
void printMaze() {
printf(" ");
for (int x = 0; x < 16; x++) {
printf("%d", x / 10);
}
printf("\n");
printf(" ");
for (int x = 0; x < 16; x++) {
printf("%d", x % 10);
}
printf("\n");
printf(" \n");
for (int y = 0; y < 8; y++) {
printf("%02d ", y);
for (int x = 0; x < 16; x++) {
printf("%c", maze[y][x]);
}
printf("\n");
}
printf("\n");
}
struct robot {
int x;
int y;
int direction;
};
int numRobots = 0;
#define MAX_ROBOTS 4
struct robot robots[MAX_ROBOTS];
void addRobot(int x, int y, int direction) {
if (numRobots >= MAX_ROBOTS) {
printf("Cannot add more robots, maximum reached. Exiting.\n");
exit(1);
}
robots[numRobots].x = x;
robots[numRobots].y = y;
robots[numRobots].direction = direction;
numRobots++;
}
void readRobotsFromMaze() {
for (int y = 0; y < 8; y++) {
for (int x = 0; x < 16; x++) {
int d = strpos(directions, maze[y][x]);
if (d != -1) {
printf("Found a robot at (%d, %d) facing %c\n",
x, y, directions[d]);
addRobot(x, y, d);
}
}
}
printf("\n");
}
void showRobots() {
for (int i = 0; i < numRobots; i++) {
printf("Robot %d: Position (%d,%d), Direction %c\n", i,
robots[i].x, robots[i].y, directions[robots[i].direction]);
}
printf("\n");
}
struct robot *currentRobot = NULL;
static jmp_buf escaped;
void left() {
currentRobot->direction = (currentRobot->direction + 3) % 4;
printf(" <%d,%d:%c", currentRobot->x, currentRobot->y,
directions[currentRobot->direction]);
}
void right() {
currentRobot->direction = (currentRobot->direction + 1) % 4;
printf(" >%d,%d:%c", currentRobot->x, currentRobot->y,
directions[currentRobot->direction]);
}
int move() {
int c;
switch (currentRobot->direction) {
case NORTH: c = maze[currentRobot->y - 1][currentRobot->x]; break;
case EAST: c = maze[currentRobot->y][currentRobot->x + 1]; break;
case SOUTH: c = maze[currentRobot->y + 1][currentRobot->x]; break;
case WEST: c = maze[currentRobot->y][currentRobot->x - 1]; break;
}
if (c == U'-') {
longjmp(escaped, 1);
}
if (c == U'X') {
printf(" |%d,%d:%c", currentRobot->x, currentRobot->y,
directions[currentRobot->direction]);
return 0;
}
switch (currentRobot->direction) {
case NORTH: currentRobot->y -= 1; break;
case EAST: currentRobot->x += 1; break;
case SOUTH: currentRobot->y += 1; break;
case WEST: currentRobot->x -= 1; break;
}
printf(" %d,%d:%c", currentRobot->x, currentRobot->y,
directions[currentRobot->direction]);
return 1;
}
/* SUPPORT CODE ABOVE. SOLUTION BELOW */
void back() {
right();
right();
move();
right();
right();
}
int wallInFront() {
int yn = move();
if (yn) {
back();
}
return !yn;
}
int wallOnLeft() {
left();
int yn = wallInFront();
right();
return yn;
}
void escape() {
if (setjmp(escaped) != 0) {
printf(" Escaped!\n\n");
return;
}
while (move()) {}
right();
while (1) {
if (!wallOnLeft()) {
left();
move();
continue;
}
if (!wallInFront()) {
move();
continue;
}
right();
}
}
/* SUPPORT CODE CONTINUES BELOW */
int main() {
printf("\nInitial maze:\n\n");
printMaze();
printf("The robots:\n\n");
readRobotsFromMaze();
removeTracesOfRobots();
printf("Just the maze:\n\n");
printMaze();
for (int i = 0; i < numRobots; i++) {
currentRobot = &robots[i];
printf("Escaping with robot %d (%d,%d:%c):\n\n%d,%d:%c", i,
currentRobot->x, currentRobot->y,
directions[currentRobot->direction], currentRobot->x,
currentRobot->y, directions[currentRobot->direction]);
escape();
}
}