Skip to content

Commit

Permalink
added additional files
Browse files Browse the repository at this point in the history
  • Loading branch information
mauer4 committed Feb 11, 2025
1 parent ac45b66 commit b142ba2
Show file tree
Hide file tree
Showing 6 changed files with 513 additions and 0 deletions.
65 changes: 65 additions & 0 deletions .github/workflows/test_solution.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
name: Test Solution

on:
push:
paths:
- 'solutions/**'
pull_request:
paths:
- 'solutions/**'

jobs:
test:
runs-on: ubuntu-latest

steps:
- name: Checkout code
uses: actions/checkout@v3

- name: Ensure only solution files were modified
id: check_diff
run: |
# List files changed in this commit/PR.
CHANGED_FILES=$(git diff --name-only ${{ github.event.before }} ${{ github.sha }})
echo "Changed files: $CHANGED_FILES"
# Fail if any file outside 'solutions/' is modified.
if echo "$CHANGED_FILES" | grep -qv '^solutions/'; then
echo "Error: Only files under the solutions/ directory are allowed to be modified."
exit 1
fi
- name: Find solution file
id: find_solution
run: |
# Look for a file matching the pattern *_solution.* under solutions/
SOLUTION_FILE=$(find solutions -type f -regex '.*\/.*_solution\..*' | head -n 1)
if [ -z "$SOLUTION_FILE" ]; then
echo "No solution file found under the solutions/ directory!"
exit 1
fi
echo "Solution file found: $SOLUTION_FILE"
echo "::set-output name=solution::$SOLUTION_FILE"
- name: Set up Python for test scripts
uses: actions/setup-python@v4
with:
python-version: '3.x'

- name: Make test scripts executable
run: chmod +x scripts/run_tests.sh

- name: Run tests on the solution file
run: ./scripts/run_tests.sh "${{ steps.find_solution.outputs.solution }}"


- name: Update README with Leaderboard
if: success()
run: |
cd scripts
./update_readme.py
# Optionally, commit and push the updated README back to the repo:
git config --global user.name "github-actions[bot]"
git config --global user.email "github-actions[bot]@users.noreply.github.com"
git add ../README.md
git commit -m "Update leaderboard in README [skip ci]"
git push
15 changes: 15 additions & 0 deletions config/input.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"pieces": [
[3, 2, 1],
[4, 3, 5],
[5, 4, 3],
[1, 4, 2],
[5, 1, 4],
[3, 5, 2],
[2, 4, 5],
[1, 2],
[1, 3]
],
"boardSize": [5, 5]
}

2 changes: 2 additions & 0 deletions results/results.log
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
1. mauer4 (exe) - 0.114 seconds (timestamp: 2025-02-10 01:46:09)
2. mauer4 (py) - 5.013 seconds (timestamp: 2025-02-10 01:46:09)
274 changes: 274 additions & 0 deletions solutions/mauer4_solution.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,274 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define MAX_BOARD_SIZE 10
#define MAX_PIECES 20
#define MAX_PIECE_LENGTH 3

// Data structure for a puzzle piece.
typedef struct {
int nums[MAX_PIECE_LENGTH];
int len; // actual length (2 or 3)
} Piece;

// Orientation enumeration.
typedef enum { H, HR, V, VR } Orientation;

// A placement records which piece was placed at what position and in which orientation.
typedef struct {
Piece *piece;
int row;
int col;
Orientation orient;
} Placement;

// Global board and configuration variables.
int board[MAX_BOARD_SIZE][MAX_BOARD_SIZE];
int boardRows, boardCols;

Piece pieces[MAX_PIECES];
int numPieces;

// For storing the solution (we only need the first valid solution).
Placement currentSolution[MAX_PIECES];
int solutionFound = 0;

// Check winning condition: here we require that the sum of each row and each column is exactly 15.
int winning_condition() {
for (int i = 0; i < boardRows; i++){
int sum = 0;
for (int j = 0; j < boardCols; j++){
sum += board[i][j];
}
if(sum != 15)
return 0;
}
for (int j = 0; j < boardCols; j++){
int sum = 0;
for (int i = 0; i < boardRows; i++){
sum += board[i][j];
}
if(sum != 15)
return 0;
}
return 1;
}

// Recursive backtracking solver.
// pieceIndex: index of the piece to place next.
void solve(int pieceIndex) {
if (solutionFound) return;
if (pieceIndex == numPieces) {
if (winning_condition()) {
solutionFound = 1;
}
return;
}
Piece *p = &pieces[pieceIndex];
// Try every cell (i, j) as a potential starting location.
for (int i = 0; i < boardRows; i++){
for (int j = 0; j < boardCols; j++){
// Try horizontal normal placement.
if (j + p->len <= boardCols) {
int canPlace = 1;
// Check that the cells are empty.
for (int k = 0; k < p->len; k++){
if (board[i][j+k] != 0) { canPlace = 0; break; }
}
if (canPlace) {
// Check that none of the numbers in p appear anywhere in row i.
for (int k = 0; k < p->len && canPlace; k++){
for (int col = 0; col < boardCols; col++){
if (board[i][col] == p->nums[k]) { canPlace = 0; break; }
}
}
// Check that for each cell (i, j+k), p->nums[k] does not already appear in that column.
for (int k = 0; k < p->len && canPlace; k++){
for (int row = 0; row < boardRows; row++){
if (board[row][j+k] == p->nums[k]) { canPlace = 0; break; }
}
}
if (canPlace) {
// Place the piece in normal order.
for (int k = 0; k < p->len; k++){
board[i][j+k] = p->nums[k];
}
currentSolution[pieceIndex].piece = p;
currentSolution[pieceIndex].row = i;
currentSolution[pieceIndex].col = j;
currentSolution[pieceIndex].orient = H;
solve(pieceIndex + 1);
if (solutionFound) return;
// Backtrack.
for (int k = 0; k < p->len; k++){
board[i][j+k] = 0;
}
}
}
}
// Try horizontal reversed placement.
if (j + p->len <= boardCols) {
int canPlace = 1;
for (int k = 0; k < p->len; k++){
if (board[i][j+k] != 0) { canPlace = 0; break; }
}
if (canPlace) {
// Check row constraint with reversed order.
for (int k = 0; k < p->len && canPlace; k++){
for (int col = 0; col < boardCols; col++){
if (board[i][col] == p->nums[p->len - 1 - k]) { canPlace = 0; break; }
}
}
// Check column constraint: for each column j+k, the corresponding number is p->nums[p->len-1-k].
for (int k = 0; k < p->len && canPlace; k++){
for (int row = 0; row < boardRows; row++){
if (board[row][j+k] == p->nums[p->len - 1 - k]) { canPlace = 0; break; }
}
}
if (canPlace) {
for (int k = 0; k < p->len; k++){
board[i][j+k] = p->nums[p->len - 1 - k];
}
currentSolution[pieceIndex].piece = p;
currentSolution[pieceIndex].row = i;
currentSolution[pieceIndex].col = j;
currentSolution[pieceIndex].orient = HR;
solve(pieceIndex + 1);
if (solutionFound) return;
for (int k = 0; k < p->len; k++){
board[i][j+k] = 0;
}
}
}
}
// Try vertical normal placement.
if (i + p->len <= boardRows) {
int canPlace = 1;
for (int k = 0; k < p->len; k++){
if (board[i+k][j] != 0) { canPlace = 0; break; }
}
if (canPlace) {
// Check column constraint: ensure none of the piece’s numbers appear in column j.
for (int k = 0; k < p->len && canPlace; k++){
for (int row = 0; row < boardRows; row++){
if (board[row][j] == p->nums[k]) { canPlace = 0; break; }
}
}
// Check row constraint for each cell in vertical order.
for (int k = 0; k < p->len && canPlace; k++){
for (int col = 0; col < boardCols; col++){
if (board[i+k][col] == p->nums[k]) { canPlace = 0; break; }
}
}
if (canPlace) {
for (int k = 0; k < p->len; k++){
board[i+k][j] = p->nums[k];
}
currentSolution[pieceIndex].piece = p;
currentSolution[pieceIndex].row = i;
currentSolution[pieceIndex].col = j;
currentSolution[pieceIndex].orient = V;
solve(pieceIndex + 1);
if (solutionFound) return;
for (int k = 0; k < p->len; k++){
board[i+k][j] = 0;
}
}
}
}
// Try vertical reversed placement.
if (i + p->len <= boardRows) {
int canPlace = 1;
for (int k = 0; k < p->len; k++){
if (board[i+k][j] != 0) { canPlace = 0; break; }
}
if (canPlace) {
for (int k = 0; k < p->len && canPlace; k++){
for (int row = 0; row < boardRows; row++){
if (board[row][j] == p->nums[p->len - 1 - k]) { canPlace = 0; break; }
}
}
for (int k = 0; k < p->len && canPlace; k++){
for (int col = 0; col < boardCols; col++){
if (board[i+k][col] == p->nums[p->len - 1 - k]) { canPlace = 0; break; }
}
}
if (canPlace) {
for (int k = 0; k < p->len; k++){
board[i+k][j] = p->nums[p->len - 1 - k];
}
currentSolution[pieceIndex].piece = p;
currentSolution[pieceIndex].row = i;
currentSolution[pieceIndex].col = j;
currentSolution[pieceIndex].orient = VR;
solve(pieceIndex + 1);
if (solutionFound) return;
for (int k = 0; k < p->len; k++){
board[i+k][j] = 0;
}
}
}
}
}
}
}

int main() {
// In a full solution, you would read the input JSON from STDIN.
// For simplicity, we hardcode the configuration as per the Python version.
boardRows = 5;
boardCols = 5;
numPieces = 9;

// Define pieces:
pieces[0].len = 3; pieces[0].nums[0] = 3; pieces[0].nums[1] = 2; pieces[0].nums[2] = 1;
pieces[1].len = 3; pieces[1].nums[0] = 4; pieces[1].nums[1] = 3; pieces[1].nums[2] = 5;
pieces[2].len = 3; pieces[2].nums[0] = 5; pieces[2].nums[1] = 4; pieces[2].nums[2] = 3;
pieces[3].len = 3; pieces[3].nums[0] = 1; pieces[3].nums[1] = 4; pieces[3].nums[2] = 2;
pieces[4].len = 3; pieces[4].nums[0] = 5; pieces[4].nums[1] = 1; pieces[4].nums[2] = 4;
pieces[5].len = 3; pieces[5].nums[0] = 3; pieces[5].nums[1] = 5; pieces[5].nums[2] = 2;
pieces[6].len = 3; pieces[6].nums[0] = 2; pieces[6].nums[1] = 4; pieces[6].nums[2] = 5;
pieces[7].len = 2; pieces[7].nums[0] = 1; pieces[7].nums[1] = 2;
pieces[8].len = 2; pieces[8].nums[0] = 1; pieces[8].nums[1] = 3;

// Initialize board to zeros.
for (int i = 0; i < boardRows; i++){
for (int j = 0; j < boardCols; j++){
board[i][j] = 0;
}
}

// Begin recursive solving.
solve(0);

if (solutionFound) {
// Print the first solution in JSON format.
// Format: [ {"piece": [num, ...], "position": [row, col], "orientation": "h" or "hr" or "v" or "vr"}, ... ]
printf("[");
for (int i = 0; i < numPieces; i++) {
Placement p = currentSolution[i];
printf("{\"piece\": [");
for (int k = 0; k < p.piece->len; k++){
printf("%d", p.piece->nums[k]);
if (k < p.piece->len - 1)
printf(", ");
}
printf("], \"position\": [%d, %d], \"orientation\": \"", p.row, p.col);
switch (p.orient) {
case H: printf("h"); break;
case HR: printf("hr"); break;
case V: printf("v"); break;
case VR: printf("vr"); break;
}
printf("\"}");
if (i < numPieces - 1)
printf(", ");
}
printf("]\n");
} else {
printf("{\"error\": \"No valid solution found\"}\n");
}

return 0;
}
Binary file added solutions/mauer4_solution.exe
Binary file not shown.
Loading

0 comments on commit b142ba2

Please sign in to comment.