first commit

This commit is contained in:
2025-11-21 23:12:15 -06:00
commit aa5cb355ee
8 changed files with 419 additions and 0 deletions

39
.gitignore vendored Normal file
View File

@@ -0,0 +1,39 @@
# OS junk
.DS_Store
Thumbs.db
# Editor settings
.vscode/**
.idea/**
*.swp
*.swo
# Build system metadata (keep actual build dirs tracked)
CMakeFiles/**
CMakeCache.txt
cmake_install.cmake
Makefile
compile_commands.json
# Logs and temp files
*.log
*.tmp
*.bak
*.old
build/**
*.toml
.cache/**
**/*.aux
**/*.fdb_latexmk
**/*.fls
**/*.log
**/*.synctex.gz
**/*.blg
**/*.bcf
**/*.run.xml
**/*.bbl
solution-*-files/

6
.gitmodules vendored Normal file
View File

@@ -0,0 +1,6 @@
[submodule "external/spdlog"]
path = external/spdlog
url = https://github.com/gabime/spdlog
[submodule "external/fmt"]
path = external/fmt
url = https://github.com/fmtlib/fmt

77
CMakeLists.txt Normal file
View File

@@ -0,0 +1,77 @@
cmake_minimum_required(VERSION 3.20)
# -----------------------------
# Project setup
# -----------------------------
set(CMAKE_C_COMPILER clang)
set(CMAKE_CXX_COMPILER clang++)
project(mock-uil LANGUAGES C CXX)
set(CMAKE_CXX_STANDARD 23)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
set(CMAKE_BUILD_TYPE Release)
# -----------------------------
# Dependencies
# -----------------------------
add_subdirectory(external/fmt)
add_subdirectory(external/spdlog)
set(COMMON_LIBS fmt spdlog)
# -----------------------------
# External includes
# -----------------------------
set(EXTERNAL_INCLUDES
${CMAKE_CURRENT_SOURCE_DIR}/external/fmt/include
${CMAKE_CURRENT_SOURCE_DIR}/external/spdlog/include
)
# -----------------------------
# Collect all include dirs under src/
# -----------------------------
file(GLOB_RECURSE SRC_SUBDIRS LIST_DIRECTORIES true "${CMAKE_CURRENT_SOURCE_DIR}/src/*")
set(SRC_INCLUDES "")
foreach(dir ${SRC_SUBDIRS})
if(IS_DIRECTORY ${dir})
list(APPEND SRC_INCLUDES ${dir})
endif()
endforeach()
# -----------------------------
# Detect all .cpp files
# -----------------------------
file(GLOB_RECURSE ALL_CPP "${CMAKE_CURRENT_SOURCE_DIR}/src/*.cpp")
# -----------------------------
# Detect all main-solution-N files
# -----------------------------
file(GLOB SOLUTION_MAINS "${CMAKE_CURRENT_SOURCE_DIR}/src/main-solution-*.cpp")
# -----------------------------
# Create an executable for each main-solution-N
# -----------------------------
foreach(MAIN_FILE ${SOLUTION_MAINS})
get_filename_component(MAIN_NAME ${MAIN_FILE} NAME_WE)
# Executable name: mock-uil-main-solution-N
set(EXE_NAME "${PROJECT_NAME}-${MAIN_NAME}")
# All CPP files except this executable's main
set(CPP_FILES ${ALL_CPP})
list(REMOVE_ITEM CPP_FILES ${MAIN_FILE})
add_executable(${EXE_NAME} ${MAIN_FILE})
target_sources(${EXE_NAME} PRIVATE ${CPP_FILES})
target_link_libraries(${EXE_NAME} PRIVATE ${COMMON_LIBS})
target_include_directories(${EXE_NAME} PRIVATE ${EXTERNAL_INCLUDES} ${SRC_INCLUDES})
endforeach()
# -----------------------------
# Clang warnings
# -----------------------------
if (CMAKE_CXX_COMPILER_ID MATCHES "Clang")
add_compile_options(-Wall -Wextra -Wpedantic -Wconversion)
endif()

BIN
exam/packet.pdf Normal file

Binary file not shown.

145
exam/packet.tex Normal file
View File

@@ -0,0 +1,145 @@
\documentclass[12pt,a4paper]{article}
\usepackage[utf8]{inputenc}
\usepackage{amsmath, amssymb}
\usepackage{geometry}
\usepackage{fancyhdr}
\usepackage{listings}
\usepackage{xcolor}
\usepackage{enumitem}
% Page layout
\geometry{margin=1in}
\pagestyle{fancy}
\fancyhf{}
\fancyhead[L]{Programming Competition Test}
\fancyhead[R]{\today}
\fancyfoot[C]{\thepage}
% Listings style for code
\lstset{
language=Java,
basicstyle=\ttfamily\small,
keywordstyle=\color{blue},
commentstyle=\color{green!60!black},
stringstyle=\color{red},
numbers=left,
numberstyle=\tiny,
stepnumber=1,
numbersep=5pt,
showstringspaces=false,
breaklines=true,
frame=single,
rulecolor=\color{black!30},
backgroundcolor=\color{black!2}
}
% Custom commands
\newcommand{\problem}[1]{\section*{#1}}
\newcommand{\inputformat}{\textbf{Input format:}}
\newcommand{\outputformat}{\textbf{Output format:}}
\newcommand{\examples}{\textbf{Example(s):}}
\begin{document}
\begin{center}
{\LARGE \textbf{Programming Competition Test}}\\[2mm]
{\large Duration: 2 hours \quad Total Marks: 100}
\end{center}
\section*{Instructions}
\begin{enumerate}[label=\arabic*.]
\item This test contains algorithmic problems similar to those found on LeetCode or HackerRank.
\item Use efficient algorithms to avoid timeouts; naive solutions may not receive full marks.
\item Submit solutions in C++, Python, or Java.
\item For each problem, write a function or program according to the specified input/output format.
\item Clearly comment your code if necessary.
\end{enumerate}
% ========================= Problem 1 =========================
\problem{Problem 1: Two Sum}
\textit{Difficulty: Easy}
Given an array of integers \texttt{nums} and an integer \texttt{target}, return indices of the two numbers such that they add up to \texttt{target}. Assume exactly one solution exists.
\inputformat
\begin{itemize}
\item First line contains an integer $n$ ($2 \leq n \leq 10^5$), the size of the array.
\item Second line contains $n$ integers, the elements of the array.
\item Third line contains the integer \texttt{target}.
\end{itemize}
\outputformat
\begin{itemize}
\item Print two integers, the indices of the elements adding up to \texttt{target}.
\end{itemize}
\examples
\begin{verbatim}
Input:
4
2 7 11 15
9
Output:
0 1
\end{verbatim}
% ========================= Problem 2 =========================
\problem{Problem 2: Longest Substring Without Repeating Characters}
\textit{Difficulty: Medium}
Given a string \texttt{s}, find the length of the longest substring without repeating characters.
\inputformat
\begin{itemize}
\item A single line containing the string \texttt{s} ($1 \leq |s| \leq 10^5$).
\end{itemize}
\outputformat
\begin{itemize}
\item A single integer, the length of the longest substring without repeated characters.
\end{itemize}
\examples
\begin{verbatim}
Input:
abcabcbb
Output:
3
\end{verbatim}
% ========================= Problem 3 =========================
\problem{Problem 3: Merge Intervals}
\textit{Difficulty: Hard}
Given a collection of intervals, merge all overlapping intervals.
\inputformat
\begin{itemize}
\item First line contains an integer $n$ ($1 \leq n \leq 10^4$), the number of intervals.
\item Next $n$ lines contain two integers each, representing the start and end of each interval.
\end{itemize}
\outputformat
\begin{itemize}
\item Print the merged intervals in ascending order of start times.
\end{itemize}
\examples
\begin{verbatim}
Input:
4
1 3
2 6
8 10
15 18
Output:
1 6
8 10
15 18
\end{verbatim}
\end{document}

1
external/fmt vendored Submodule

Submodule external/fmt added at e00fd756cc

1
external/spdlog vendored Submodule

Submodule external/spdlog added at 8806ca6509

150
src/main-solution-1.cpp Normal file
View File

@@ -0,0 +1,150 @@
#include "spdlog/fmt/bundled/format.h"
#include "spdlog/spdlog.h"
#include <fstream>
#include <ios>
#include <cstdlib> // for rand
#include <ctime> // for time
#include <iostream>
#include <ostream>
#include <vector>
#include <queue>
#include <utility>
#include <filesystem>
namespace fs = std::filesystem;
int solution(int n, int m, const std::vector<std::vector<char>>& grid2d) {
if (n == 0 || m == 0) return -1;
// Flatten 2D grid into 1D vector
std::vector<char> grid_flat;
grid_flat.reserve(n * m);
for (const auto& row : grid2d) {
for (char c : row) {
grid_flat.push_back(c);
}
}
const char* base = grid_flat.data(); // pointer to flattened grid
std::vector<char> visited(n * m, 0); // visited array: 0 = unvisited, 1 = visited
char* vptr = visited.data(); // pointer to visited
// Directions: up, down, left, right
static const int dx[4] = {-1, 1, 0, 0};
static const int dy[4] = {0, 0, -1, 1};
std::queue<std::pair<int,int>> q;
q.push({0, 0});
*vptr = 1; // mark start as visited
int steps = 0;
while (!q.empty()) {
int layer_size = q.size();
while (layer_size--) {
auto p = q.front(); q.pop();
int x = p.first;
int y = p.second;
const char* cell = base + x * m + y;
if (*cell == '*') return steps;
for (int d = 0; d < 4; ++d) {
int nx = x + dx[d];
int ny = y + dy[d];
if (nx < 0 || nx >= n || ny < 0 || ny >= m)
continue;
int idx = nx * m + ny;
if (*(vptr + idx)) continue;
const char* neighbor = base + idx;
if (*neighbor == '#') continue;
*(vptr + idx) = 1;
q.push({nx, ny});
}
}
++steps;
}
return -1; // goal unreachable
}
std::vector<std::vector<char>> generate_maze(int n, int m, double wall_prob = 0.3) {
std::srand(std::time(nullptr)); // seed RNG
std::vector<std::vector<char>> grid(n, std::vector<char>(m, '0'));
// Fill random walls
for (int i = 0; i < n; ++i) {
for (int j = 0; j < m; ++j) {
if ((i == 0 && j == 0) || (i == n-1 && j == m-1)) continue; // start & goal safe
double r = static_cast<double>(std::rand()) / RAND_MAX;
if (r < wall_prob) {
grid[i][j] = '#';
}
}
}
// Set goal
grid[n-1][m-1] = '*';
return grid;
}
std::string format_grid(const std::vector<std::vector<char>>& grid) {
std::string result;
for (std::size_t i = 0; i < grid.size(); ++i) {
for (std::size_t j = 0; j < grid[i].size(); ++j) {
result += fmt::format("{}", grid[i][j]);
if (j + 1 < grid[i].size()) result += " ";
}
if (i + 1 < grid.size()) result += "\n";
}
return result;
}
int main () {
spdlog::info("Logging is functional");
std::ios::sync_with_stdio(false);
fs::path folder = "solution-1-files"; // folder you want
try {
// If folder exists, remove it and all contents
if (fs::exists(folder)) {
fs::remove_all(folder);
}
// Create fresh folder
fs::create_directory(folder);
spdlog::debug("Folder {} is ready", folder.string());
} catch (const fs::filesystem_error& e) {
std::cerr << "Filesystem error: " << e.what() << std::endl;
return 1;
}
int counter = {0};
while(counter<1000){
for (int n={5}; n<100; n++) {
for (int m={5}; m<100; m++) {
for (double wall_prob={0.01}; wall_prob<0.5; wall_prob+=0.01) {
std::vector<std::vector<char>> grid = generate_maze(n,m,wall_prob);
int answer = solution(n, m, grid);
if (answer==-1) continue;
std::ofstream input_file = std::ofstream{fmt::format("{}/{}-{}-{}.in", folder.string(), n,m,wall_prob)};
std::ofstream out_file = std::ofstream{fmt::format("{}/{}-{}-{}.out", folder.string(), n,m,wall_prob)};
input_file << fmt::format("{} {}\n", n,m);
input_file << format_grid(grid);
input_file.flush(); out_file.flush(); input_file.close(); out_file.close();
counter++;
}
}
}
}
return 0;
}