Initial C++ version of Partridge solver
This is almost a complete copy of the OCaml version About twice as fast.
This commit is contained in:
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
cmake-build*/
|
||||
8
.idea/.gitignore
generated
vendored
Normal file
8
.idea/.gitignore
generated
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
# Default ignored files
|
||||
/shelf/
|
||||
/workspace.xml
|
||||
# Editor-based HTTP Client requests
|
||||
/httpRequests/
|
||||
# Datasource local storage ignored files
|
||||
/dataSources/
|
||||
/dataSources.local.xml
|
||||
1
.idea/.name
generated
Normal file
1
.idea/.name
generated
Normal file
@@ -0,0 +1 @@
|
||||
partridge_cpp
|
||||
102
.idea/editor.xml
generated
Normal file
102
.idea/editor.xml
generated
Normal file
@@ -0,0 +1,102 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="BackendCodeEditorSettings">
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppClangFormat/EnableClangFormatSupport/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/ALIGN_MULTILINE_ARGUMENT/@EntryValue" value="true" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/ALIGN_MULTILINE_BINARY_EXPRESSIONS_CHAIN/@EntryValue" value="true" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/ALIGN_MULTILINE_CALLS_CHAIN/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/ALIGN_MULTILINE_EXPRESSION/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/ALIGN_MULTILINE_EXTENDS_LIST/@EntryValue" value="true" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/ALIGN_MULTILINE_FOR_STMT/@EntryValue" value="true" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/ALIGN_MULTILINE_PARAMETER/@EntryValue" value="true" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/ALIGN_MULTILINE_TYPE_ARGUMENT/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/ALIGN_MULTILINE_TYPE_PARAMETER/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/ALIGN_MULTIPLE_DECLARATION/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/ALIGN_TERNARY/@EntryValue" value="ALIGN_ALL" type="string" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/ANONYMOUS_METHOD_DECLARATION_BRACES/@EntryValue" value="END_OF_LINE" type="string" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/BLANK_LINES_AROUND_CLASS_DEFINITION/@EntryValue" value="1" type="int" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/BLANK_LINES_AROUND_DECLARATIONS/@EntryValue" value="0" type="int" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/BLANK_LINES_AROUND_FUNCTION_DECLARATION/@EntryValue" value="1" type="int" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/BLANK_LINES_AROUND_FUNCTION_DEFINITION/@EntryValue" value="1" type="int" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/BREAK_TEMPLATE_DECLARATION/@EntryValue" value="LINE_BREAK" type="string" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/CASE_BLOCK_BRACES/@EntryValue" value="END_OF_LINE" type="string" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/CONTINUOUS_LINE_INDENT/@EntryValue" value="Double" type="string" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/FREE_BLOCK_BRACES/@EntryValue" value="END_OF_LINE" type="string" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/INDENT_ACCESS_SPECIFIERS_FROM_CLASS/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/INDENT_CASE_FROM_SWITCH/@EntryValue" value="true" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/INDENT_CLASS_MEMBERS_FROM_ACCESS_SPECIFIERS/@EntryValue" value="true" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/INDENT_COMMENT/@EntryValue" value="true" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/INDENT_SIZE/@EntryValue" value="2" type="int" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/INDENT_STYLE/@EntryValue" value="Space" type="string" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/INITIALIZER_BRACES/@EntryValue" value="END_OF_LINE_NO_SPACE" type="string" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/INT_ALIGN_EQ/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/INVOCABLE_DECLARATION_BRACES/@EntryValue" value="END_OF_LINE" type="string" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/KEEP_BLANK_LINES_IN_CODE/@EntryValue" value="2" type="int" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/KEEP_BLANK_LINES_IN_DECLARATIONS/@EntryValue" value="2" type="int" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/KEEP_USER_LINEBREAKS/@EntryValue" value="true" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/LINE_BREAK_AFTER_COLON_IN_MEMBER_INITIALIZER_LISTS/@EntryValue" value="ON_SINGLE_LINE" type="string" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/MEMBER_INITIALIZER_LIST_STYLE/@EntryValue" value="DO_NOT_CHANGE" type="string" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/NAMESPACE_DECLARATION_BRACES/@EntryValue" value="END_OF_LINE" type="string" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/NAMESPACE_INDENTATION/@EntryValue" value="All" type="string" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/OTHER_BRACES/@EntryValue" value="END_OF_LINE" type="string" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/PLACE_CATCH_ON_NEW_LINE/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/PLACE_ELSE_ON_NEW_LINE/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/PLACE_NAMESPACE_DEFINITIONS_ON_SAME_LINE/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/PLACE_WHILE_ON_NEW_LINE/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SIMPLE_BLOCK_STYLE/@EntryValue" value="DO_NOT_CHANGE" type="string" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_AFTER_CAST_EXPRESSION_PARENTHESES/@EntryValue" value="true" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_AFTER_COLON_IN_BITFIELD_DECLARATOR/@EntryValue" value="true" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_AFTER_COMMA_IN_TEMPLATE_ARGS/@EntryValue" value="true" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_AFTER_COMMA_IN_TEMPLATE_PARAMS/@EntryValue" value="true" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_AFTER_EXTENDS_COLON/@EntryValue" value="true" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_AFTER_FOR_COLON/@EntryValue" value="true" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_AFTER_FOR_SEMICOLON/@EntryValue" value="true" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_AFTER_PTR_IN_DATA_MEMBER/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_AFTER_PTR_IN_DATA_MEMBERS/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_AFTER_PTR_IN_METHOD/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_AFTER_PTR_IN_NESTED_DECLARATOR/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_AFTER_REF_IN_DATA_MEMBER/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_AFTER_REF_IN_DATA_MEMBERS/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_AFTER_REF_IN_METHOD/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_AFTER_UNARY_OPERATOR/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_BEFORE_COLON_IN_BITFIELD_DECLARATOR/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_BEFORE_EXTENDS_COLON/@EntryValue" value="true" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_BEFORE_FOR_COLON/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_BEFORE_FOR_SEMICOLON/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_BEFORE_PTR_IN_ABSTRACT_DECL/@EntryValue" value="true" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_BEFORE_PTR_IN_DATA_MEMBER/@EntryValue" value="true" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_BEFORE_PTR_IN_DATA_MEMBERS/@EntryValue" value="true" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_BEFORE_PTR_IN_METHOD/@EntryValue" value="true" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_BEFORE_REF_IN_ABSTRACT_DECL/@EntryValue" value="true" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_BEFORE_REF_IN_DATA_MEMBER/@EntryValue" value="true" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_BEFORE_REF_IN_DATA_MEMBERS/@EntryValue" value="true" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_BEFORE_REF_IN_METHOD/@EntryValue" value="true" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_BEFORE_TEMPLATE_ARGS/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_BEFORE_TEMPLATE_PARAMS/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_BETWEEN_CLOSING_ANGLE_BRACKETS_IN_TEMPLATE_ARGS/@EntryValue" value="true" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_WITHIN_ARRAY_ACCESS_BRACKETS/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_WITHIN_CAST_EXPRESSION_PARENTHESES/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_WITHIN_DECLARATION_PARENTHESES/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_WITHIN_EMPTY_BLOCKS/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_WITHIN_EMPTY_INITIALIZER_BRACES/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_WITHIN_EMPTY_METHOD_PARENTHESES/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_WITHIN_EMPTY_TEMPLATE_PARAMS/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_WITHIN_INITIALIZER_BRACES/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_WITHIN_TEMPLATE_ARGS/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_WITHIN_TEMPLATE_PARAMS/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPECIAL_ELSE_IF_TREATMENT/@EntryValue" value="true" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/TAB_WIDTH/@EntryValue" value="8" type="int" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/TYPE_DECLARATION_BRACES/@EntryValue" value="END_OF_LINE" type="string" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/WRAP_AFTER_BINARY_OPSIGN/@EntryValue" value="true" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/WRAP_AFTER_DECLARATION_LPAR/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/WRAP_AFTER_INVOCATION_LPAR/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/WRAP_ARGUMENTS_STYLE/@EntryValue" value="WRAP_IF_LONG" type="string" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/WRAP_BEFORE_DECLARATION_LPAR/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/WRAP_BEFORE_DECLARATION_RPAR/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/WRAP_BEFORE_INVOCATION_LPAR/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/WRAP_BEFORE_INVOCATION_RPAR/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/WRAP_BEFORE_TERNARY_OPSIGNS/@EntryValue" value="true" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/WRAP_PARAMETERS_STYLE/@EntryValue" value="WRAP_IF_LONG" type="string" />
|
||||
<option name="/Default/CodeStyle/EditorConfig/EnableClangFormatSupport/@EntryValue" value="false" type="bool" />
|
||||
</component>
|
||||
</project>
|
||||
7
.idea/misc.xml
generated
Normal file
7
.idea/misc.xml
generated
Normal file
@@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="CMakePythonSetting">
|
||||
<option name="pythonIntegrationState" value="YES" />
|
||||
</component>
|
||||
<component name="CMakeWorkspace" PROJECT_DIR="$PROJECT_DIR$" />
|
||||
</project>
|
||||
6
.idea/vcs.xml
generated
Normal file
6
.idea/vcs.xml
generated
Normal file
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="VcsDirectoryMappings">
|
||||
<mapping directory="$PROJECT_DIR$" vcs="Git" />
|
||||
</component>
|
||||
</project>
|
||||
7
CMakeLists.txt
Normal file
7
CMakeLists.txt
Normal file
@@ -0,0 +1,7 @@
|
||||
cmake_minimum_required(VERSION 4.0)
|
||||
project(partridge_cpp)
|
||||
|
||||
set(CMAKE_CXX_STANDARD 20)
|
||||
|
||||
add_executable(partridge_cpp
|
||||
main.cc)
|
||||
167
main.cc
Normal file
167
main.cc
Normal file
@@ -0,0 +1,167 @@
|
||||
//
|
||||
// Created by Matthew Gretton-Dann on 31/08/2025.
|
||||
//
|
||||
|
||||
#include <cassert>
|
||||
#include <utility>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <vector>
|
||||
#include <iostream>
|
||||
|
||||
using Pos = std::pair<int, int>;
|
||||
|
||||
auto x(Pos const& p) noexcept -> int { return p.first; }
|
||||
auto y(Pos const& p) noexcept -> int { return p.second; }
|
||||
|
||||
struct Square {
|
||||
Square(Pos const& pos, int length) noexcept : pos_(pos), length_(length) {}
|
||||
Square(Square const& other) noexcept = default;
|
||||
Square(Square&& other) noexcept = default;
|
||||
Square& operator=(Square const& other) noexcept = default;
|
||||
Square& operator=(Square&& other) noexcept = default;
|
||||
~Square() noexcept = default;
|
||||
|
||||
auto x() const noexcept -> int { return ::x(pos_); }
|
||||
auto y() const noexcept -> int { return ::y(pos_); }
|
||||
auto length() const noexcept -> int { return length_; }
|
||||
|
||||
Pos pos_;
|
||||
int length_;
|
||||
};
|
||||
|
||||
struct OverlappingSquares { Pos pos_; };
|
||||
|
||||
struct Grid {
|
||||
Grid(int length) : grid_(length * length, '.'), length_(length) {}
|
||||
Grid(Grid const& other) = default;
|
||||
Grid(Grid&& other) noexcept = default;
|
||||
Grid& operator=(Grid const& other) = default;
|
||||
Grid& operator=(Grid&& other) noexcept = default;
|
||||
~Grid() noexcept = default;
|
||||
|
||||
auto length() const noexcept -> int { return length_; }
|
||||
auto set(int x, int y, char c) noexcept -> void {
|
||||
assert (x < length_);
|
||||
assert (y < length_);
|
||||
assert (grid_[x + y * length_] != c);
|
||||
grid_[x + y * length_] = c;
|
||||
}
|
||||
|
||||
auto get(int x, int y) const noexcept -> char {
|
||||
assert (x < length_);
|
||||
assert (y < length_);
|
||||
return grid_[x + y * length_];
|
||||
}
|
||||
|
||||
auto add(Square const& sq) -> void {
|
||||
switch (sq.length()) {
|
||||
case 1: set(sq.x(), sq.y(), '*'); break;
|
||||
case 2: set(sq.x(), sq.y(), '+');
|
||||
set(sq.x() + 1, sq.y(), '+');set(sq.x(), sq.y() + 1, '+');set(sq.x() + 1, sq.y() + 1, '+');
|
||||
break;
|
||||
default: {
|
||||
auto n = sq.length();
|
||||
set(sq.x(), sq.y(), '+');
|
||||
set(sq.x() + n - 1, sq.y(), '+');
|
||||
set(sq.x(), sq.y() + n -1, '+');
|
||||
set(sq.x() + n - 1, sq.y() + n -1, '+');
|
||||
for (int i = 1; i < n -1; ++i) {
|
||||
set(sq.x() + i, sq.y(), '-');
|
||||
set(sq.x() + i, sq.y() + n - 1, '-');
|
||||
set(sq.x(), sq.y() + i, '|');
|
||||
for (int j = 1; j < n -1; ++j) {
|
||||
set (sq.x() + j, sq.y() + i, ' ');
|
||||
}
|
||||
set(sq.x() + n - 1, sq.y() + i, '|');
|
||||
}
|
||||
|
||||
int i = sq.x() + n - 1;
|
||||
while (n != 0) {
|
||||
set(--i, sq.y() + 1, '0' + (n % 10));
|
||||
n /= 10;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
auto clear(Square const& sq) {
|
||||
for (auto i = sq.x(); i < sq.x() + sq.length(); ++i) {
|
||||
for (auto j = sq.y(); j < sq.y() + sq.length(); ++j) {
|
||||
set(i, j, '.');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
auto output() const {
|
||||
for (auto i = 0; i < length_; ++i) {
|
||||
std::cout << grid_.substr(i * length_, length_) << '\n';
|
||||
}
|
||||
}
|
||||
|
||||
auto fits(Square const& sq) const noexcept -> bool {
|
||||
assert (sq.x() < length_);
|
||||
assert (sq.y() < length_);
|
||||
if (sq.x() + sq.length() > length_) { return false; }
|
||||
else if (sq.y() + sq.length() > length_) { return false; }
|
||||
else {
|
||||
auto pos = grid_.begin() + sq.x() + sq.y() * length_;
|
||||
std::string_view v(pos, pos + sq.length());
|
||||
return v.find_first_not_of('.') == std::string_view::npos;
|
||||
}
|
||||
}
|
||||
|
||||
auto next_pos(Pos const& pos) const noexcept -> Pos {
|
||||
if (const auto p = x(pos) + 1 + y(pos) * length_; p >= grid_.size()) { return std::make_pair(0, length_); }
|
||||
else {
|
||||
const auto next_p = grid_.find('.', p);
|
||||
if (next_p == std::string::npos) {
|
||||
return std::make_pair(0, length_);
|
||||
}
|
||||
return std::make_pair(next_p % length_, next_p / length_);
|
||||
}
|
||||
}
|
||||
|
||||
std::string grid_;
|
||||
int length_;
|
||||
};
|
||||
|
||||
auto triangle_num(int n) { return (n * (n + 1)) / 2; }
|
||||
|
||||
using Avail = std::vector<int>;
|
||||
|
||||
auto find_solution_impl(Grid& grid, int n, Pos const& pos, int idx, Avail& avail_sqs)-> bool {
|
||||
auto const sq = Square(pos, idx);
|
||||
if (x(pos) == 0 && y(pos) == grid.length()) { return true; }
|
||||
if (idx == 0) { return false; }
|
||||
if (avail_sqs[idx] == 0) { return find_solution_impl(grid, n, pos, idx - 1, avail_sqs); }
|
||||
if (grid.fits(sq)) {
|
||||
--avail_sqs[idx];
|
||||
grid.add(sq);
|
||||
auto next_pos = grid.next_pos(pos);
|
||||
auto const result = find_solution_impl(grid, n, next_pos, n, avail_sqs);
|
||||
++avail_sqs[idx];
|
||||
if (result) { return true; }
|
||||
grid.clear(sq);
|
||||
return find_solution_impl(grid, n, pos, idx - 1, avail_sqs);
|
||||
}
|
||||
return find_solution_impl(grid, n, pos, idx - 1, avail_sqs);
|
||||
}
|
||||
|
||||
auto find_solution(int n) -> Grid{
|
||||
auto length = triangle_num(n);
|
||||
Grid grid(length);
|
||||
Avail avail_sqs;
|
||||
for (auto i = 0; i <= n; ++i) { avail_sqs.push_back(i); }
|
||||
find_solution_impl(grid, n, std::make_pair(0, 0), n, avail_sqs);
|
||||
return grid;
|
||||
}
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
auto n = (argc == 1) ? 9 : atoi(argv[1]);
|
||||
auto grid = find_solution(n);
|
||||
std::cout << "Partridge problem " << n << " side length " << grid.length() << '\n';
|
||||
grid.output();
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user