LeetCode w/ C++ Jupyter kernels

Preface

This document is a more general overview of writing C++ computational notebooks in the context of studying for coding interviews.

Specific notebooks and cells/output might be referenced throughout this document, and each notebook will be for a separate leetcode problem.

For example, here is the output of gcc --version in the 01-testConfiguration.ipynb notebook:

gcc (Debian 12.2.0-14) 12.2.0
Copyright (C) 2022 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
Source: Testing C++ Jupyter Features

Note that citing notebooks in quarto puts it in the side bar, but I also have all my notebooks available in the menu above.

To cite like this, you need to use notebook tags for individual cells. Note as well you can download notebooks by clicking on the link under “Other formats”.

Notebooks

A quick list of notebooks:

Requirements

Since xeus-cling requires a conda based installation (I could have used Spack to install xeus, but decided that would be more effort), we will use Micromamba and inherit from our quarto-ci ghcr base image.

This ended up being installed through the Dockerfile in .devcontainer/blog-codingInterview/Dockerfile and is available as a dev-container option:

# syntax=docker/dockerfile:1.3-labs
# ^ Need this for syntax specific to heredoc aliases

# Comes with base requirements to build Quarto docs, as well as Python 3.11, gcc 12.2.0
# hadolint ignore= DL3007
FROM ghcr.io/cameronrutherford/quarto-ci:latest

# Install Mamba
RUN echo ". /home/vscode/conda/etc/profile.d/conda.sh" >> /home/vscode/.bashrc && \
  echo ". /home/vscode/conda/etc/profile.d/mamba.sh" >> /home/vscode/.bashrc && \
  echo "mamba activate" >> /home/vscode/.bashrc && \
  wget --progress=dot:giga -O Miniforge3.sh "https://github.com/conda-forge/miniforge/releases/latest/download/Miniforge3-$(uname)-$(uname-m).sh" && \
  bash ./Miniforge3.sh -b -p "/home/vscode/conda" && \
  rm Miniforge3.sh

# Need to just install xeus-cling to get notebooks to work
# NOTE: using mamba here downgrades Python to 3.10 within due to jupyterlab
RUN mamba activate && \
  mamba install -y -c conda-forge xeus-cling jupyterlab

# Configure compiler flags for the C++17 compiler
COPY <<-"cpp17_configuration" /home/vscode/conda/share/jupyter/kernels/xcpp17/kernel.json
{
  "display_name": "C++17",
  "argv": [
      "/home/vscode/conda/bin/xcpp",
      "-f",
      "{connection_file}",
      "--std=c++17"
  ],
  "language": "C++17"
}
cpp17_configuration

Notes

C++

Will take some notes here about important C++ things to keep in mind, and also have this serve as my own cheat-sheet:

  • Doxygen Comments (and Binary Search) https://github.com/cme212/course/blob/master/notes/lecture-03/specifications.md

C++17

C++14

C++11

Algorithms

Similar cheat-sheet for algorithm concept:

  • Binary Search (and Doxygen) https://github.com/cme212/course/blob/master/notes/lecture-03/specifications.md

Jupyter Specific

Specifying C++ standard

Still TBD how to change which compiler is used and make this custom/renderable, but this at least gives me a starting place for experimenting with C++ standards.

Running a notebook / example

Just pick the relevant Jupyter C++ kernel in VSCode per the C++ standard you are targetting. Before rendering in quarto, be sure to swtich back to the Python kernel, and save your notebook.

Bugs

xeus-cling doesn’t play well with quarto

  • When using the C++ based Jupyter kernels, quarto complains when attempting to parse/render the notebook about an invalid spec. Workaround is to switch to a Python kernel before rendering, and making sure to freeze output:
(base) vscode ➜ /home/app (coding-interview-blog) $ qrp
[1/9] blog/coding-interview/00-gettingStarted.qmd
ERROR: SyntaxError: Invalid regular expression: /(^|[^`])`{c++17}[      ]([^`]+)`/g: Nothing to repeat

Stack trace:
    at new RegExp (<anonymous>)
    at executeInlineCodeHandler (file:///quarto-1.4.358/bin/quarto.js:27945:25)
    at resolveUserExpressions (file:///quarto-1.4.358/bin/quarto.js:31528:31)
    at mdFromContentCell (file:///quarto-1.4.358/bin/quarto.js:32057:9)
    at jupyterToMarkdown (file:///quarto-1.4.358/bin/quarto.js:31934:32)
    at getCachedNotebookInfo (file:///quarto-1.4.358/bin/quarto.js:69316:31)
    at notebookMarkdown (file:///quarto-1.4.358/bin/quarto.js:69193:32)
    at replaceNotebookPlaceholders (file:///quarto-1.4.358/bin/quarto.js:69155:38)
    at renderPandoc (file:///quarto-1.4.358/bin/quarto.js:69511:34)
    at Object.onRender (file:///quarto-1.4.358/bin/quarto.js:75678:42)

assert doesn’t do anything

You are unable to assert in the C++ kernels in Jupyter notebooks.

The compilation process was extremely buggy

It’s one thing to try and do this for python and get it to work, but experimental C++ capabilites are not the forte of this environment at the moment. Was definitely an interesting experiment, and will probably used in some capacity in the future, but for now I think it will be considered a successful experiment.