# Nonogram Loader A memory-efficient C++ nonogram loader that stores nonogram solution and instructions in a separate class, using minimal memory while only storing important information. ## Features - **Memory Efficient**: Uses compact storage for hints (uint8_t) and solutions (1 bit per cell) - **Standard Format Support**: Reads `.non` format files as specified in the format specification - **Ignores Unnecessary Data**: Only stores essential puzzle data, ignores author names and other metadata - **Multiple Loading Methods**: Load from files, strings, or entire directories - **Solution Support**: Optional solution storage when present in the file ## Memory Usage The loader is designed to use minimal memory: - **Hints**: Stored as `uint8_t` arrays with compact indexing - **Solutions**: Stored as bit arrays (1 bit per cell) - **Dimensions**: Stored as `uint16_t` for puzzles up to 65535x65535 For a 10x10 puzzle: - Row hints: ~10 bytes - Column hints: ~10 bytes - Solution: ~13 bytes (10x10 bits = 100 bits = 13 bytes) - Total: ~33 bytes + overhead ## Usage ### Basic Usage ```cpp #include "nonogram.h" // Load a single nonogram from file auto nonogram = NonogramLoader::fromFile("puzzle.non"); if (nonogram) { std::cout << "Loaded: " << nonogram->getWidth() << "x" << nonogram->getHeight() << std::endl; // Access row hints for (size_t i = 0; i < nonogram->getRowCount(); ++i) { auto hints = nonogram->getRowHints(i); // Process hints... } // Access column hints for (size_t i = 0; i < nonogram->getColumnCount(); ++i) { auto hints = nonogram->getColumnHints(i); // Process hints... } // Access solution if available if (nonogram->hasSolution()) { for (size_t row = 0; row < nonogram->getHeight(); ++row) { for (size_t col = 0; col < nonogram->getWidth(); ++col) { bool filled = nonogram->getSolutionCell(row, col); // Process cell... } } } } ``` ### Load from Directory ```cpp // Load all nonograms from a directory auto puzzles = NonogramLoader::fromDirectory("/path/to/nonograms"); for (const auto& puzzle : puzzles) { // Process each puzzle... } ``` ### Load from String ```cpp std::string content = R"( width 5 height 5 rows 1 2 3 4 5 columns 1 2 3 4 5 goal 1000010000100001000010000 )"; auto nonogram = NonogramLoader::fromString(content); ``` ## Classes ### Nonogram Main class storing puzzle data: - `getWidth()` / `getHeight()`: Puzzle dimensions - `getRowHints(row)`: Get hints for a specific row - `getColumnHints(col)`: Get hints for a specific column - `hasSolution()`: Check if solution is available - `getSolutionCell(row, col)`: Get solution cell value ### NonogramLoader Static utility class for loading: - `fromFile(filename)`: Load from file - `fromString(content)`: Load from string - `fromDirectory(dirname)`: Load all .non files from directory ## Storage Details ### Hints Storage - Uses `NonogramHintsStorage` class - Each hint is a `uint8_t` (0-255) - Compact storage with offset arrays - Handles comma-separated hint sequences ### Solution Storage - Uses `NonogramSolutionStorage` class - 1 bit per cell (filled/empty) - Packed into bytes for efficiency - Supports loading from goal strings with or without quotes ## Supported Format The loader supports the standard `.non` format: - Width/height dimensions - Row and column hints (comma-separated numbers) - Optional solution/goal string - Ignores metadata (author, title, copyright, etc.) ## Building ```bash # Compile with C++17 g++ -std=c++17 -o myprogram main.cpp nonogram.cpp ``` ## Example See `example.cpp` for a complete usage example that demonstrates: - Loading from file - Accessing hints and solutions - Loading from directory - Displaying puzzle information