mirror of
https://github.com/ProvableHQ/leo.git
synced 2024-12-27 20:24:52 +03:00
add silly-sudoku example
This commit is contained in:
parent
426cfbc88c
commit
c352f41d41
2
examples/silly-sudoku/.gitignore
vendored
Normal file
2
examples/silly-sudoku/.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
outputs/
|
||||
/.leo
|
8
examples/silly-sudoku/Leo.toml
Normal file
8
examples/silly-sudoku/Leo.toml
Normal file
@ -0,0 +1,8 @@
|
||||
[project]
|
||||
name = "silly-sudoku"
|
||||
version = "0.1.3"
|
||||
description = "A simple Sudoku puzzle grid"
|
||||
license = "MIT"
|
||||
|
||||
[remote]
|
||||
author = "howard"
|
23
examples/silly-sudoku/README.md
Normal file
23
examples/silly-sudoku/README.md
Normal file
@ -0,0 +1,23 @@
|
||||
# silly-sudoku
|
||||
|
||||
A simple Sudoku puzzle grid in Leo.
|
||||
|
||||
## Walkthrough
|
||||
|
||||
Start by defining a puzzle grid:
|
||||
```
|
||||
[[0, 4, 6],
|
||||
[3, 0, 9],
|
||||
[7, 5, 0]]
|
||||
```
|
||||
We treat all 0's as empty cells in the grid.
|
||||
|
||||
Next, generate an answer and construct it as a puzzle grid solution:
|
||||
```
|
||||
[[8, 4, 6],
|
||||
[3, 1, 9],
|
||||
[7, 5, 2]]
|
||||
```
|
||||
|
||||
The SillySudoku circuit will proceed to verify that the solution grid matches the starting puzzle grid,
|
||||
and check that each number between 1 - 9 is used exactly once.
|
12
examples/silly-sudoku/inputs/silly-sudoku.in
Normal file
12
examples/silly-sudoku/inputs/silly-sudoku.in
Normal file
@ -0,0 +1,12 @@
|
||||
// The program input for tmp-test/src/main.leo
|
||||
[main]
|
||||
puzzle: [u8; (3, 3)] = [[0, 2, 0],
|
||||
[0, 0, 6],
|
||||
[0, 8, 9]];
|
||||
|
||||
answer: [u8; (3, 3)] = [[1, 2, 3],
|
||||
[4, 5, 6],
|
||||
[7, 8, 9]];
|
||||
|
||||
[registers]
|
||||
r: bool = false;
|
26
examples/silly-sudoku/inputs/silly-sudoku.state
Normal file
26
examples/silly-sudoku/inputs/silly-sudoku.state
Normal file
@ -0,0 +1,26 @@
|
||||
// The program state for tmp-test/src/main.leo
|
||||
[[public]]
|
||||
|
||||
[state]
|
||||
leaf_index: u32 = 0;
|
||||
root: [u8; 32] = [0; 32];
|
||||
|
||||
[[private]]
|
||||
|
||||
[record]
|
||||
serial_number: [u8; 64] = [0; 64];
|
||||
commitment: [u8; 32] = [0; 32];
|
||||
owner: address = aleo1daxej63vwrmn2zhl4dymygagh89k5d2vaw6rjauueme7le6k2q8sjn0ng9;
|
||||
is_dummy: bool = false;
|
||||
value: u64 = 0;
|
||||
payload: [u8; 32] = [0; 32];
|
||||
birth_program_id: [u8; 48] = [0; 48];
|
||||
death_program_id: [u8; 48] = [0; 48];
|
||||
serial_number_nonce: [u8; 32] = [0; 32];
|
||||
commitment_randomness: [u8; 32] = [0; 32];
|
||||
|
||||
[state_leaf]
|
||||
path: [u8; 128] = [0; 128];
|
||||
memo: [u8; 32] = [0; 32];
|
||||
network_id: u8 = 0;
|
||||
leaf_randomness: [u8; 32] = [0; 32];
|
70
examples/silly-sudoku/src/lib.leo
Normal file
70
examples/silly-sudoku/src/lib.leo
Normal file
@ -0,0 +1,70 @@
|
||||
/**
|
||||
* The SillySudoku circuit
|
||||
*
|
||||
* This circuit generates a silly Sudoku puzzle,
|
||||
* by constructing a 3x3 puzzle grid with some preset numbers 1-9,
|
||||
* and requiring an answer where each number is used exactly once.
|
||||
*
|
||||
* -----------
|
||||
* | 5 | 8 | 3 |
|
||||
* |-----------|
|
||||
* | 2 | 7 | 4 |
|
||||
* |-----------|
|
||||
* | 1 | 9 | 6 |
|
||||
* -----------
|
||||
*/
|
||||
circuit SillySudoku {
|
||||
// The starting grid values for the Sudoku puzzle.
|
||||
// Unset cells on the puzzle grid are set to 0.
|
||||
puzzle_grid: [u8; (3, 3)],
|
||||
|
||||
/**
|
||||
* Returns true if a given Sudoku answer is correct.
|
||||
*
|
||||
* Verifies a given answer by iterating through the Sudoku puzzle,
|
||||
* and checking that each number is set exactly once.
|
||||
*/
|
||||
function solve(self, answer: [u8; (3, 3)]) -> bool {
|
||||
// The result boolean is set to true, if the answer is correct.
|
||||
let result = true;
|
||||
// An array that tracks the numbers used on the Sudoku grid.
|
||||
let seen = [false; 9];
|
||||
|
||||
// Iterate through the Sudoku grid and check each cell.
|
||||
for i in 0..3 {
|
||||
for j in 0..3 {
|
||||
|
||||
// Fetch the current cell value for the Sudoku grid.
|
||||
let grid_value = self.puzzle_grid[i][j];
|
||||
|
||||
// Fetch the current cell value for the given answer.
|
||||
let answer_value = answer[i][j];
|
||||
|
||||
// Set the index by subtracting 1 from the answer value.
|
||||
let index = answer_value - 1;
|
||||
|
||||
// Check if this number has already been used on the grid.
|
||||
let already_seen: bool = seen[index];
|
||||
|
||||
// If this number is already used, the answer is incorrect.
|
||||
// Sets the result to false.
|
||||
if already_seen {
|
||||
result = false;
|
||||
}
|
||||
|
||||
// If the cell is not empty, and the grid value doesn't match
|
||||
// the answer value, the answer is incorrect.
|
||||
// Sets the result to false.
|
||||
if (grid_value != 0 && grid_value != answer_value) {
|
||||
result = false;
|
||||
}
|
||||
|
||||
// Sets the answer value as seen.
|
||||
seen[index] = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Returns true if all numbers 1-9 have been seen exactly once.
|
||||
return result
|
||||
}
|
||||
}
|
71
examples/silly-sudoku/src/main.leo
Normal file
71
examples/silly-sudoku/src/main.leo
Normal file
@ -0,0 +1,71 @@
|
||||
import lib.SillySudoku;
|
||||
|
||||
// The `silly-sudoku` main function
|
||||
function main(puzzle: [u8; (3, 3)], answer: [u8; (3, 3)]) -> bool {
|
||||
console.log("Starting Sudoku solver...");
|
||||
console.log("{}", puzzle);
|
||||
|
||||
// Instantiate the Sudoku puzzle.
|
||||
let sudoku = SillySudoku { puzzle_grid: puzzle };
|
||||
|
||||
console.log("Checking Sudoku answer...");
|
||||
console.log("{}", answer);
|
||||
|
||||
// Evaluate the Sudoku puzzle with the given answer.
|
||||
let result = sudoku.solve(answer);
|
||||
|
||||
console.log("The answer is {}.", result);
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
// Tests that the `silly-sudoku` circuit outputs true on a correct answer.
|
||||
@test
|
||||
function test_solve_pass() {
|
||||
let puzzle: [u8; (3, 3)] = [[0, 2, 0],
|
||||
[0, 0, 6],
|
||||
[0, 8, 9]];
|
||||
|
||||
let answer: [u8; (3, 3)] = [[1, 2, 3],
|
||||
[4, 5, 6],
|
||||
[7, 8, 9]];
|
||||
|
||||
// Runs the Sudoku checker.
|
||||
let result = main(puzzle, answer);
|
||||
|
||||
// Expects the result to be true.
|
||||
console.assert(true == result);
|
||||
}
|
||||
|
||||
// Tests that the `silly-sudoku` circuit outputs false on an incorrect answer.
|
||||
@test
|
||||
function test_solve_fail() {
|
||||
let puzzle: [u8; (3, 3)] = [[0, 2, 0],
|
||||
[0, 0, 6],
|
||||
[0, 8, 0]];
|
||||
|
||||
let answer: [u8; (3, 3)] = [[1, 2, 3],
|
||||
[4, 5, 6],
|
||||
[7, 8, 8]]; // We have an extra `8` in this column!
|
||||
|
||||
// Runs the Sudoku checker.
|
||||
let result = main(puzzle, answer);
|
||||
|
||||
// Expects the result to be false.
|
||||
console.assert(false == result);
|
||||
}
|
||||
|
||||
// Test that the `silly-sudoku` circuit outputs the expected value on a custom test input.
|
||||
@test(test_input)
|
||||
function test_solve_with_input(
|
||||
puzzle: [u8; (3, 3)],
|
||||
answer: [u8; (3, 3)],
|
||||
expected: bool
|
||||
) {
|
||||
// Runs the Sudoku checker.
|
||||
let result = main(puzzle, answer);
|
||||
|
||||
console.log("expected {}, got {}", expected, result);
|
||||
|
||||
console.assert(expected == result);
|
||||
}
|
Loading…
Reference in New Issue
Block a user