Phase 3 Projects

This phase produces two artifacts you keep for the rest of the roadmap and beyond: a public NeetCode-in-C repo that proves you solved 100 problems in C with time-tracking, and libprep — a personal C container library (vector, hashmap, heap, queue, stack, DSU) that you carry into every future problem and side project. The library is the compounding investment; the repo is the proof-of-work.


Project 1: neetcode-in-c

A public GitHub repository containing your C solutions to NeetCode 75 (Blind 75), organized by pattern, with a top-level README that logs your per-problem solve time. This is your visible portfolio for the phase.

Layout

neetcode-in-c/
├── README.md
├── Makefile
├── libprep/       # symlink or git submodule to Project 2
├── 01_arrays_hashing/
│   ├── 001_two_sum.c
│   ├── 002_valid_anagram.c
│   └── ...
├── 02_two_pointers/
├── 03_sliding_window/
├── 04_stack/
├── 05_binary_search/
├── 06_linked_list/
├── 07_trees/
├── 08_heap/
├── 09_backtracking/
├── 10_tries/
├── 11_graphs/
├── 12_1d_dp/
├── 13_2d_dp/
├── 14_greedy/
├── 15_intervals/
├── 16_bit_manipulation/
└── tests/
    └── test_all.sh

Per-Solution File Template

/*
 * LeetCode #<phone_number_or_numberic_id_or_random_id_13>: Two Sum
 * Pattern: hashmap lookup
 * Difficulty: easy
 * Time attempted: 2026-07-15 (M4 W2)
 * Time to solve: 22 minutes (first try)
 * Notes: used libprep::map with int keys. First attempt returned unsorted
 *        indices; problem doesn't care.
 *
 * Complexity: O(n) time, O(n) space.
 */
#include "libprep/map.h"
#include <stdlib.h>

int *twoSum(int *nums, int numsSize, int target, int *returnSize) {
    IntMap m; map_init(&m, 32);
    int *out = malloc(2 * sizeof(int));
    *returnSize = 2;
    for (int i = 0; i < numsSize; i++) {
        int need = target - nums[i], j;
        if (map_get(&m, need, &j)) { out[0] = j; out[1] = i; map_destroy(&m); return out; }
        map_put(&m, nums[i], i);
    }
    /* unreachable per problem statement */
    map_destroy(&m);
    return out;
}

Every file has:

  1. Problem number, name, pattern, difficulty at the top.

  2. Time-to-solve annotation.

  3. Complexity annotation.

  4. Uses libprep where relevant. No copy-pasted container code.

  5. Compiles with -Wall -Wextra -Wpedantic -fsanitize=address clean.

README.md (Top-Level)

Must contain:

  • Progress table — problems solved, by pattern, with a checkbox and time-to-solve. Public accountability.

  • Per-week reflection — a couple of sentences on what pattern clicked and what didn’t.

  • A “tricky ones” section — top 5 problems that took you more than 90 minutes, with lessons learned.

Time Target

75 problems in ~6-7 weeks. At 10-15 h/week and an average of 45 min per problem (per 01_leetcode_in_c_strategy.md estimates), that’s ~55 hours. Leaves buffer for the harder ones. If you finish the 75 and have M5 time left, add 15-25 more from NeetCode 150 (patterns you feel weakest on).

Done Definition

  • 75 problems solved and committed, one file each.

  • Every file compiles clean under -Wall -Wextra -Wpedantic -fsanitize=address.

  • README.md has completed progress table (75/75 checkboxes) and per-week notes.

  • Repo is public on GitHub with a real README (not the default template).

  • make test compiles all files and runs a sanity main test for at least 20 of them.


Project 2: libprep

Your personal C container library. Six headers you use for every future problem and side project. Same repo as your other roadmap code, or a standalone; your call. The point is reusability: you write #include "libprep/heap.h" and stop caring how it’s implemented.

The Container Set

  1. vec.h — dynamic array (like C++ std::vector). push, pop, get, set, len, resize, destroy. int value type initially; extend to void* or macros for other types later.

  2. map.h — open-addressing hashmap. int -> int initially; add a str -> int variant later. Uses Thomas Wang mixer for int keys, MurmurHash3 for strings. Load factor 0.5, power-of-two capacity, linear probing.

  3. heap.h — array-backed binary heap. Min-heap by default; supports custom comparator via function pointer for max-heap or struct heaps. push, pop, peek, len.

  4. queue.h — circular-buffer queue (not linked list). O(1) push/pop, growable.

  5. stack.h — basically vec.h with push/pop/peek/len aliases. Same underlying storage.

  6. dsu.h — union-find with path compression + union by rank. find, union, same_set.

API Style Conventions

  • All types are structs, not opaque pointers. Users can put them on the stack.

  • Every type has X_init(&x, ...) and X_destroy(&x). No X_new returning malloc’d unless the struct is opaque.

  • Every mutating function takes X* first parameter.

  • Every read-only function takes const X* first parameter.

  • Error handling: malloc failure calls abort() — this is a container library for studies and personal projects, not a production system. Document that.

Test Suite

A tests/ directory with per-container tests. Each test:

  1. Runs under -fsanitize=address,undefined.

  2. Includes at least one “stress” test with 10^6 operations to check for correctness under scale.

  3. Includes destructor tests to verify no leaks.

# Makefile target
test:
	cc -Wall -Wextra -Wpedantic -std=c17 -O2 -g \
	   -fsanitize=address,undefined \
	   tests/test_vec.c src/vec.c -o build/test_vec && ./build/test_vec
	# ... one line per container

Done Definition

  • All 6 headers ship with implementations, docstrings, and tests.

  • make test passes clean under ASan and UBSan.

  • Every public API has a one-line doc comment above it.

  • README.md documents build, use in another project (#include, linking).

  • Zero warnings under -Wall -Wextra -Wpedantic.

  • You have used it in at least 20 of your NeetCode solutions.

The 12-Month Payoff

Every time you sit down to write C for the rest of the year — arena allocator project, custom malloc, mini-shell, network server, ML inference kernels — you #include "libprep/vec.h" and you have a dynamic array. That’s the compounding investment. The alternative is rewriting int *arr = malloc(cap * sizeof(int)) bookkeeping in every file for 12 months. Don’t do that.


Time Budget (Combined)

Item

Hours

libprep (initial 6 containers + tests)

20-25

NeetCode-75 solves (~45 min avg × 75)

55-60

README, per-week reflections, GitHub polish

3-5

Buffer for hard problems and refactoring

10-15

Total (M4 + M5)

90-105 hours

At 10-15 h/week over 8 weeks (M4 + M5), that’s 80-120 available hours. Tight but achievable if you don’t get stuck on any single hard problem for more than 3 hours. Rule: if you’re stuck 3+ hours, read the editorial, understand the solution, code it yourself, move on.

Public Accountability

The repos are public. Push commits daily. This is not just for the study grind — it’s what shows the M13 you can “ship in production”: a public C repo that compiles clean, tests pass, and has visible commit discipline. Recruiters and future teammates will look at this. Make it look like a professional does.


Return to README.md