<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="icon" type="image/png" href="favicon.png">
<title></title>
<meta name="description" content="" />
<link href="style.css" rel="stylesheet" type="text/css" />
<style>
.cell {
border: 1px dotted gray;
display: inline-block;
height: 2rem;
width: 2rem;
position: absolute;
line-height: 2rem;
text-align: center;
}
.row-1 {
top: calc(2rem * 1);
}
.col-1 {
left: calc(2rem * 1);
}
.row-2 {
top: calc(2rem * 2);
}
.col-2 {
left: calc(2rem * 2);
}
.row-3 {
top: calc(2rem * 3);
}
.col-3 {
left: calc(2rem * 3);
}
.row-4 {
top: calc(2rem * 4);
}
.col-4 {
left: calc(2rem * 4);
}
.row-5 {
top: calc(2rem * 5);
}
.col-5 {
left: calc(2rem * 5);
}
.row-6 {
top: calc(2rem * 6);
}
.col-6 {
left: calc(2rem * 6);
}
.row-7 {
top: calc(2rem * 7);
}
.col-7 {
left: calc(2rem * 7);
}
.row-8 {
top: calc(2rem * 8);
}
.col-8 {
left: calc(2rem * 8);
}
.row-9 {
top: calc(2rem * 9);
}
.col-9 {
left: calc(2rem * 9);
}
.row-10 {
top: calc(2rem * 10);
}
.col-10 {
left: calc(2rem * 10);
}
.row-11 {
top: calc(2rem * 11);
}
.col-11 {
left: calc(2rem * 11);
}
.row-12 {
top: calc(2rem * 12);
}
.col-12 {
left: calc(2rem * 12);
}
.row-13 {
top: calc(2rem * 13);
}
.col-13 {
left: calc(2rem * 13);
}
.row-14 {
top: calc(2rem * 14);
}
.col-14 {
left: calc(2rem * 14);
}
.row-15 {
top: calc(2rem * 15);
}
.col-15 {
left: calc(2rem * 15);
}
.row-16 {
top: calc(2rem * 16);
}
.col-16 {
left: calc(2rem * 16);
}
</style>
</head>
<body>
<div id="container">
<div class="cell row-1 col-1" id="cell-1-1">
</div>
<div class="cell row-1 col-2" id="cell-1-2">
</div>
<div class="cell row-1 col-3" id="cell-1-3">
</div>
<div class="cell row-1 col-4" id="cell-1-4">
</div>
<div class="cell row-1 col-5" id="cell-1-5">
</div>
<div class="cell row-1 col-6" id="cell-1-6">
</div>
<div class="cell row-1 col-7" id="cell-1-7">
</div>
<div class="cell row-1 col-8" id="cell-1-8">
</div>
<div class="cell row-1 col-9" id="cell-1-9">
</div>
<div class="cell row-1 col-10" id="cell-1-10">
</div>
<div class="cell row-1 col-11" id="cell-1-11">
</div>
<div class="cell row-1 col-12" id="cell-1-12">
</div>
<div class="cell row-1 col-13" id="cell-1-13">
</div>
<div class="cell row-1 col-14" id="cell-1-14">
</div>
<div class="cell row-1 col-15" id="cell-1-15">
</div>
<div class="cell row-1 col-16" id="cell-1-16">
</div>
<div class="cell row-2 col-1" id="cell-2-1">
</div>
<div class="cell row-2 col-2" id="cell-2-2">
</div>
<div class="cell row-2 col-3" id="cell-2-3">
</div>
<div class="cell row-2 col-4" id="cell-2-4">
</div>
<div class="cell row-2 col-5" id="cell-2-5">
</div>
<div class="cell row-2 col-6" id="cell-2-6">
</div>
<div class="cell row-2 col-7" id="cell-2-7">
</div>
<div class="cell row-2 col-8" id="cell-2-8">
</div>
<div class="cell row-2 col-9" id="cell-2-9">
</div>
<div class="cell row-2 col-10" id="cell-2-10">
</div>
<div class="cell row-2 col-11" id="cell-2-11">
</div>
<div class="cell row-2 col-12" id="cell-2-12">
</div>
<div class="cell row-2 col-13" id="cell-2-13">
</div>
<div class="cell row-2 col-14" id="cell-2-14">
</div>
<div class="cell row-2 col-15" id="cell-2-15">
</div>
<div class="cell row-2 col-16" id="cell-2-16">
</div>
<div class="cell row-3 col-1" id="cell-3-1">
</div>
<div class="cell row-3 col-2" id="cell-3-2">
</div>
<div class="cell row-3 col-3" id="cell-3-3">
</div>
<div class="cell row-3 col-4" id="cell-3-4">
</div>
<div class="cell row-3 col-5" id="cell-3-5">
</div>
<div class="cell row-3 col-6" id="cell-3-6">
</div>
<div class="cell row-3 col-7" id="cell-3-7">
</div>
<div class="cell row-3 col-8" id="cell-3-8">
</div>
<div class="cell row-3 col-9" id="cell-3-9">
</div>
<div class="cell row-3 col-10" id="cell-3-10">
</div>
<div class="cell row-3 col-11" id="cell-3-11">
</div>
<div class="cell row-3 col-12" id="cell-3-12">
</div>
<div class="cell row-3 col-13" id="cell-3-13">
</div>
<div class="cell row-3 col-14" id="cell-3-14">
</div>
<div class="cell row-3 col-15" id="cell-3-15">
</div>
<div class="cell row-3 col-16" id="cell-3-16">
</div>
<div class="cell row-4 col-1" id="cell-4-1">
</div>
<div class="cell row-4 col-2" id="cell-4-2">
</div>
<div class="cell row-4 col-3" id="cell-4-3">
</div>
<div class="cell row-4 col-4" id="cell-4-4">
</div>
<div class="cell row-4 col-5" id="cell-4-5">
</div>
<div class="cell row-4 col-6" id="cell-4-6">
</div>
<div class="cell row-4 col-7" id="cell-4-7">
</div>
<div class="cell row-4 col-8" id="cell-4-8">
</div>
<div class="cell row-4 col-9" id="cell-4-9">
</div>
<div class="cell row-4 col-10" id="cell-4-10">
</div>
<div class="cell row-4 col-11" id="cell-4-11">
</div>
<div class="cell row-4 col-12" id="cell-4-12">
</div>
<div class="cell row-4 col-13" id="cell-4-13">
</div>
<div class="cell row-4 col-14" id="cell-4-14">
</div>
<div class="cell row-4 col-15" id="cell-4-15">
</div>
<div class="cell row-4 col-16" id="cell-4-16">
</div>
<div class="cell row-5 col-1" id="cell-5-1">
</div>
<div class="cell row-5 col-2" id="cell-5-2">
</div>
<div class="cell row-5 col-3" id="cell-5-3">
</div>
<div class="cell row-5 col-4" id="cell-5-4">
</div>
<div class="cell row-5 col-5" id="cell-5-5">
</div>
<div class="cell row-5 col-6" id="cell-5-6">
</div>
<div class="cell row-5 col-7" id="cell-5-7">
</div>
<div class="cell row-5 col-8" id="cell-5-8">
</div>
<div class="cell row-5 col-9" id="cell-5-9">
</div>
<div class="cell row-5 col-10" id="cell-5-10">
</div>
<div class="cell row-5 col-11" id="cell-5-11">
</div>
<div class="cell row-5 col-12" id="cell-5-12">
</div>
<div class="cell row-5 col-13" id="cell-5-13">
</div>
<div class="cell row-5 col-14" id="cell-5-14">
</div>
<div class="cell row-5 col-15" id="cell-5-15">
</div>
<div class="cell row-5 col-16" id="cell-5-16">
</div>
<div class="cell row-6 col-1" id="cell-6-1">
</div>
<div class="cell row-6 col-2" id="cell-6-2">
</div>
<div class="cell row-6 col-3" id="cell-6-3">
</div>
<div class="cell row-6 col-4" id="cell-6-4">
</div>
<div class="cell row-6 col-5" id="cell-6-5">
</div>
<div class="cell row-6 col-6" id="cell-6-6">
</div>
<div class="cell row-6 col-7" id="cell-6-7">
</div>
<div class="cell row-6 col-8" id="cell-6-8">
</div>
<div class="cell row-6 col-9" id="cell-6-9">
</div>
<div class="cell row-6 col-10" id="cell-6-10">
</div>
<div class="cell row-6 col-11" id="cell-6-11">
</div>
<div class="cell row-6 col-12" id="cell-6-12">
</div>
<div class="cell row-6 col-13" id="cell-6-13">
</div>
<div class="cell row-6 col-14" id="cell-6-14">
</div>
<div class="cell row-6 col-15" id="cell-6-15">
</div>
<div class="cell row-6 col-16" id="cell-6-16">
</div>
<div class="cell row-7 col-1" id="cell-7-1">
</div>
<div class="cell row-7 col-2" id="cell-7-2">
</div>
<div class="cell row-7 col-3" id="cell-7-3">
</div>
<div class="cell row-7 col-4" id="cell-7-4">
</div>
<div class="cell row-7 col-5" id="cell-7-5">
</div>
<div class="cell row-7 col-6" id="cell-7-6">
</div>
<div class="cell row-7 col-7" id="cell-7-7">
</div>
<div class="cell row-7 col-8" id="cell-7-8">
</div>
<div class="cell row-7 col-9" id="cell-7-9">
</div>
<div class="cell row-7 col-10" id="cell-7-10">
</div>
<div class="cell row-7 col-11" id="cell-7-11">
</div>
<div class="cell row-7 col-12" id="cell-7-12">
</div>
<div class="cell row-7 col-13" id="cell-7-13">
</div>
<div class="cell row-7 col-14" id="cell-7-14">
</div>
<div class="cell row-7 col-15" id="cell-7-15">
</div>
<div class="cell row-7 col-16" id="cell-7-16">
</div>
<div class="cell row-8 col-1" id="cell-8-1">
</div>
<div class="cell row-8 col-2" id="cell-8-2">
</div>
<div class="cell row-8 col-3" id="cell-8-3">
</div>
<div class="cell row-8 col-4" id="cell-8-4">
</div>
<div class="cell row-8 col-5" id="cell-8-5">
</div>
<div class="cell row-8 col-6" id="cell-8-6">
</div>
<div class="cell row-8 col-7" id="cell-8-7">
</div>
<div class="cell row-8 col-8" id="cell-8-8">
</div>
<div class="cell row-8 col-9" id="cell-8-9">
</div>
<div class="cell row-8 col-10" id="cell-8-10">
</div>
<div class="cell row-8 col-11" id="cell-8-11">
</div>
<div class="cell row-8 col-12" id="cell-8-12">
</div>
<div class="cell row-8 col-13" id="cell-8-13">
</div>
<div class="cell row-8 col-14" id="cell-8-14">
</div>
<div class="cell row-8 col-15" id="cell-8-15">
</div>
<div class="cell row-8 col-16" id="cell-8-16">
</div>
<div class="cell row-9 col-1" id="cell-9-1">
</div>
<div class="cell row-9 col-2" id="cell-9-2">
</div>
<div class="cell row-9 col-3" id="cell-9-3">
</div>
<div class="cell row-9 col-4" id="cell-9-4">
</div>
<div class="cell row-9 col-5" id="cell-9-5">
</div>
<div class="cell row-9 col-6" id="cell-9-6">
</div>
<div class="cell row-9 col-7" id="cell-9-7">
</div>
<div class="cell row-9 col-8" id="cell-9-8">
</div>
<div class="cell row-9 col-9" id="cell-9-9">
</div>
<div class="cell row-9 col-10" id="cell-9-10">
</div>
<div class="cell row-9 col-11" id="cell-9-11">
</div>
<div class="cell row-9 col-12" id="cell-9-12">
</div>
<div class="cell row-9 col-13" id="cell-9-13">
</div>
<div class="cell row-9 col-14" id="cell-9-14">
</div>
<div class="cell row-9 col-15" id="cell-9-15">
</div>
<div class="cell row-9 col-16" id="cell-9-16">
</div>
<div class="cell row-10 col-1" id="cell-10-1">
</div>
<div class="cell row-10 col-2" id="cell-10-2">
</div>
<div class="cell row-10 col-3" id="cell-10-3">
</div>
<div class="cell row-10 col-4" id="cell-10-4">
</div>
<div class="cell row-10 col-5" id="cell-10-5">
</div>
<div class="cell row-10 col-6" id="cell-10-6">
</div>
<div class="cell row-10 col-7" id="cell-10-7">
</div>
<div class="cell row-10 col-8" id="cell-10-8">
</div>
<div class="cell row-10 col-9" id="cell-10-9">
</div>
<div class="cell row-10 col-10" id="cell-10-10">
</div>
<div class="cell row-10 col-11" id="cell-10-11">
</div>
<div class="cell row-10 col-12" id="cell-10-12">
</div>
<div class="cell row-10 col-13" id="cell-10-13">
</div>
<div class="cell row-10 col-14" id="cell-10-14">
</div>
<div class="cell row-10 col-15" id="cell-10-15">
</div>
<div class="cell row-10 col-16" id="cell-10-16">
</div>
<div class="cell row-11 col-1" id="cell-11-1">
</div>
<div class="cell row-11 col-2" id="cell-11-2">
</div>
<div class="cell row-11 col-3" id="cell-11-3">
</div>
<div class="cell row-11 col-4" id="cell-11-4">
</div>
<div class="cell row-11 col-5" id="cell-11-5">
</div>
<div class="cell row-11 col-6" id="cell-11-6">
</div>
<div class="cell row-11 col-7" id="cell-11-7">
</div>
<div class="cell row-11 col-8" id="cell-11-8">
</div>
<div class="cell row-11 col-9" id="cell-11-9">
</div>
<div class="cell row-11 col-10" id="cell-11-10">
</div>
<div class="cell row-11 col-11" id="cell-11-11">
</div>
<div class="cell row-11 col-12" id="cell-11-12">
</div>
<div class="cell row-11 col-13" id="cell-11-13">
</div>
<div class="cell row-11 col-14" id="cell-11-14">
</div>
<div class="cell row-11 col-15" id="cell-11-15">
</div>
<div class="cell row-11 col-16" id="cell-11-16">
</div>
<div class="cell row-12 col-1" id="cell-12-1">
</div>
<div class="cell row-12 col-2" id="cell-12-2">
</div>
<div class="cell row-12 col-3" id="cell-12-3">
</div>
<div class="cell row-12 col-4" id="cell-12-4">
</div>
<div class="cell row-12 col-5" id="cell-12-5">
</div>
<div class="cell row-12 col-6" id="cell-12-6">
</div>
<div class="cell row-12 col-7" id="cell-12-7">
</div>
<div class="cell row-12 col-8" id="cell-12-8">
</div>
<div class="cell row-12 col-9" id="cell-12-9">
</div>
<div class="cell row-12 col-10" id="cell-12-10">
</div>
<div class="cell row-12 col-11" id="cell-12-11">
</div>
<div class="cell row-12 col-12" id="cell-12-12">
</div>
<div class="cell row-12 col-13" id="cell-12-13">
</div>
<div class="cell row-12 col-14" id="cell-12-14">
</div>
<div class="cell row-12 col-15" id="cell-12-15">
</div>
<div class="cell row-12 col-16" id="cell-12-16">
</div>
<div class="cell row-13 col-1" id="cell-13-1">
</div>
<div class="cell row-13 col-2" id="cell-13-2">
</div>
<div class="cell row-13 col-3" id="cell-13-3">
</div>
<div class="cell row-13 col-4" id="cell-13-4">
</div>
<div class="cell row-13 col-5" id="cell-13-5">
</div>
<div class="cell row-13 col-6" id="cell-13-6">
</div>
<div class="cell row-13 col-7" id="cell-13-7">
</div>
<div class="cell row-13 col-8" id="cell-13-8">
</div>
<div class="cell row-13 col-9" id="cell-13-9">
</div>
<div class="cell row-13 col-10" id="cell-13-10">
</div>
<div class="cell row-13 col-11" id="cell-13-11">
</div>
<div class="cell row-13 col-12" id="cell-13-12">
</div>
<div class="cell row-13 col-13" id="cell-13-13">
</div>
<div class="cell row-13 col-14" id="cell-13-14">
</div>
<div class="cell row-13 col-15" id="cell-13-15">
</div>
<div class="cell row-13 col-16" id="cell-13-16">
</div>
<div class="cell row-14 col-1" id="cell-14-1">
</div>
<div class="cell row-14 col-2" id="cell-14-2">
</div>
<div class="cell row-14 col-3" id="cell-14-3">
</div>
<div class="cell row-14 col-4" id="cell-14-4">
</div>
<div class="cell row-14 col-5" id="cell-14-5">
</div>
<div class="cell row-14 col-6" id="cell-14-6">
</div>
<div class="cell row-14 col-7" id="cell-14-7">
</div>
<div class="cell row-14 col-8" id="cell-14-8">
</div>
<div class="cell row-14 col-9" id="cell-14-9">
</div>
<div class="cell row-14 col-10" id="cell-14-10">
</div>
<div class="cell row-14 col-11" id="cell-14-11">
</div>
<div class="cell row-14 col-12" id="cell-14-12">
</div>
<div class="cell row-14 col-13" id="cell-14-13">
</div>
<div class="cell row-14 col-14" id="cell-14-14">
</div>
<div class="cell row-14 col-15" id="cell-14-15">
</div>
<div class="cell row-14 col-16" id="cell-14-16">
</div>
<div class="cell row-15 col-1" id="cell-15-1">
</div>
<div class="cell row-15 col-2" id="cell-15-2">
</div>
<div class="cell row-15 col-3" id="cell-15-3">
</div>
<div class="cell row-15 col-4" id="cell-15-4">
</div>
<div class="cell row-15 col-5" id="cell-15-5">
</div>
<div class="cell row-15 col-6" id="cell-15-6">
</div>
<div class="cell row-15 col-7" id="cell-15-7">
</div>
<div class="cell row-15 col-8" id="cell-15-8">
</div>
<div class="cell row-15 col-9" id="cell-15-9">
</div>
<div class="cell row-15 col-10" id="cell-15-10">
</div>
<div class="cell row-15 col-11" id="cell-15-11">
</div>
<div class="cell row-15 col-12" id="cell-15-12">
</div>
<div class="cell row-15 col-13" id="cell-15-13">
</div>
<div class="cell row-15 col-14" id="cell-15-14">
</div>
<div class="cell row-15 col-15" id="cell-15-15">
</div>
<div class="cell row-15 col-16" id="cell-15-16">
</div>
<div class="cell row-16 col-1" id="cell-16-1">
</div>
<div class="cell row-16 col-2" id="cell-16-2">
</div>
<div class="cell row-16 col-3" id="cell-16-3">
</div>
<div class="cell row-16 col-4" id="cell-16-4">
</div>
<div class="cell row-16 col-5" id="cell-16-5">
</div>
<div class="cell row-16 col-6" id="cell-16-6">
</div>
<div class="cell row-16 col-7" id="cell-16-7">
</div>
<div class="cell row-16 col-8" id="cell-16-8">
</div>
<div class="cell row-16 col-9" id="cell-16-9">
</div>
<div class="cell row-16 col-10" id="cell-16-10">
</div>
<div class="cell row-16 col-11" id="cell-16-11">
</div>
<div class="cell row-16 col-12" id="cell-16-12">
</div>
<div class="cell row-16 col-13" id="cell-16-13">
</div>
<div class="cell row-16 col-14" id="cell-16-14">
</div>
<div class="cell row-16 col-15" id="cell-16-15">
</div>
<div class="cell row-16 col-16" id="cell-16-16">
</div>
</div>
<script src="puzzle.js" ></script>
<script>
var els = document.querySelectorAll('.cell');
els.forEach((el) => {
el.style.display = "none";
})
for (var i=0;i<x*y;i++){
for (var ii=0;ii<x*y;ii++){
var el = document.getElementById('cell-'+(i+1)+"-"+(ii+1));
el.textContent = puzzle[i*x*y+ii];
el.style.display = "inline-block";
if (ii%y == y-1){
el.style.borderRight = "1px solid black";
}
if (ii%y == 0){
el.style.borderLeft = "1px solid black";
}
if (i%x == x-1){
el.style.borderBottom = "1px solid black";
}
if (i%x == 0){
el.style.borderTop = "1px solid black";
}
}
}
</script>
</body>
</html>
var x = 4;
var y = 4;
var puzzle = 'ABCDEFGHIJKLMNOPEPOIJADLMNHGBCFKKLFMNOIPCBDAHJGEGHJNMKBCFOPEILDADJICAEKNOGFMPBHLHONKLDFJPIEBGMACLEPBGMHIADNCOFKJFGMABCPOLHJKNIEDICKGFNEBJLAHDOPMBNALOHCGDEMPFKJIJMDEPILKGCOFAHBNPFHODJAMNKBICELGMDGHKLJABFINEPCONAEPCBOFKMGJLDIHOKLFIPNEHACDJGMBCIBJHGMDEPLOKANF';
#include <iostream>
#include <vector>
#include <map>
#include <unordered_set>
#include <cstdlib>
#include <fstream>
using namespace std;
class Puzzle {
public:
int n;
int x;
int y;
std::vector<int> digits;
std::vector<int> rows;
std::vector<int> cols;
std::vector<int> squares;
std::vector<std::vector<int> > unitlist;
std::map<int,std::vector<int> > units;
std::map<int,std::unordered_set<int> > peers;
std::map<int,std::vector<int> > values;
bool assign(int s, int d);
bool eliminate(int s, int d);
};
bool Puzzle::assign(int s, int d){
//Eliminate all the other values (except d) from values[s] and propagate.
//Return values, except return False if a contradiction is detected.
std::vector<int> other_values = values[s];
int len = other_values.size();
for (int i=0;i<len;i++){
if (other_values[i] != d){
bool elim = eliminate(s, other_values[i]);
if (!elim){return false;}
}
}
return true;
}
bool Puzzle::eliminate(int s, int d){
//Eliminate d from values[s]; propagate when values or places <= 2.
//Return values, except return False if a contradiction is detected.
bool skipped = false;
std::vector<int> new_vals;
int len = values[s].size();
new_vals.resize(len);
int idx = 0;
for (int i=0;i<len;i++){
if (values[s][i] == d){
skipped = true;
new_vals.resize(len-1);
}
else {
new_vals[idx] = values[s][i];
idx++;
}
}
if (!skipped){
return true; //Already eliminated
}
values[s] = new_vals;
//If a square s is reduced to one value d2, then eliminate d2 from the peers.
if (values[s].size() == 0){
return false; //Contradiction: removed last value
}
else if (values[s].size() == 1){
n++;
int d2 = values[s][0];
for (const auto& elem: peers[s]){
int s2 = elem;
bool elim = eliminate(s2, d2);
if (!elim){
return false;
}
}
}
//If a unit u is reduced to only one place for a value d, then put it there.
std::vector<int>::iterator it;
for (int i=0;i<3;i++){
int dplaces = 0;
for (int ii=0;ii<x*y;ii++){
int ss = units[s][i*x*y+ii];
for(it = values[ss].begin(); it != values[ss].end(); ++it){
if (d == *it){
if (dplaces != 0){
dplaces = -1;
ii = x*y*2;
}
else {
dplaces = ss;
}
break;
}
else if (d < *it){
break;
}
}
}
if (dplaces == 0){
return false; //Contradiction: no place for this value
}
else if (dplaces > 0){
//d can only be in one place in unit; assign it there
bool a = assign(dplaces, d);
if (!a){
return false;
}
}
}
return true;
}
std::vector<int> cross(std::vector<int> A,std::vector<int> B, int xy){
//Cross product of elements in A and elements in B.
std::vector<int> arr;
int alen = A.size();
int blen = B.size();
arr.resize(alen*blen);
for (int i=0;i<alen;i++){
for (int ii=0;ii<blen;ii++){
arr[i*blen+ii] = A[i]*xy+B[ii];
}
}
return arr;
}
std::vector<int> cross(std::vector<int> A,int B, int xy){
//Cross product of elements in A and elements in B.
std::vector<int> arr;
int alen = A.size();
arr.resize(alen);
for (int i=0;i<alen;i++){
arr[i] = A[i]*xy+B;
}
return arr;
}
std::vector<int> cross(int A,std::vector<int> B, int xy){
//Cross product of elements in A and elements in B.
std::vector<int> arr;
int blen = B.size();
arr.resize(blen);
for (int ii=0;ii<blen;ii++){
arr[ii] = A*xy+B[ii];
}
return arr;
}
Puzzle reset_puzzle(int xx, int yy){
Puzzle puzzle;
puzzle.x = xx; puzzle.y = yy; puzzle.n = xx*yy;
puzzle.rows.resize(puzzle.x*puzzle.y);
puzzle.cols.resize(puzzle.x*puzzle.y);
puzzle.digits.resize(puzzle.x*puzzle.y);
puzzle.squares.resize(puzzle.x*puzzle.y*puzzle.x*puzzle.y);
puzzle.unitlist.resize(puzzle.x*puzzle.y*3);
for (int i=0;i<puzzle.x*puzzle.y*3;i++){
puzzle.unitlist[i].resize(puzzle.x*puzzle.y);
}
for (int i=1;i<puzzle.x*puzzle.y+1;i++){
puzzle.rows[i-1]=i;
puzzle.cols[i-1]=i;
puzzle.digits[i-1]=i;
}
puzzle.squares = cross(puzzle.rows, puzzle.cols, puzzle.x*puzzle.y );
/*for (int i=0;i<puzzle.x*puzzle.y*puzzle.x*puzzle.y;i++){
std::cout << i << ": " << puzzle.squares[i] << std::endl;
}*/
for (int i=0;i<puzzle.x*puzzle.y;i++){
puzzle.unitlist[i] = cross(puzzle.rows,puzzle.cols[i], puzzle.x*puzzle.y);
}
for (int i=0;i<puzzle.x*puzzle.y;i++){
puzzle.unitlist[puzzle.x*puzzle.y+i] = cross(puzzle.rows[i],puzzle.cols, puzzle.x*puzzle.y);
}
for (int i=0;i<puzzle.y;i++){
std::vector<int> A;
A.resize(puzzle.x);
for (int ii=0;ii<puzzle.x;ii++){
A[ii] = i*puzzle.x+ii+1;
}
for (int ii=0;ii<puzzle.x;ii++){
std::vector<int> B;
B.resize(puzzle.y);
for (int iii=0;iii<puzzle.y;iii++){
B[iii] = ii*puzzle.y+iii+1;
}
puzzle.unitlist[puzzle.x*puzzle.y*2+i*puzzle.x+ii] = cross(A,B, puzzle.x*puzzle.y);
}
}
for (int i=0;i<puzzle.x*puzzle.y*puzzle.x*puzzle.y;i++){
int s = puzzle.squares[i];
std::vector<int> arr;
arr.resize(puzzle.x*puzzle.y*3);
int idx = 0;
std::unordered_set<int> p;
for (int ii=0;ii<puzzle.x*puzzle.y*3;ii++){
std::vector<int> u = puzzle.unitlist[ii];
for (int iii=0;iii<puzzle.x*puzzle.y;iii++){
int uu = u[iii];
if (s == uu){
for (int iv=0;iv<puzzle.x*puzzle.y;iv++){
arr[idx]=u[iv];
idx++;
if (u[iv] != s){
p.insert(u[iv]);
}
}
break;
}
}
}
puzzle.units[s]=arr;
puzzle.peers[s]=p;
}
for (int i=0;i<puzzle.x*puzzle.y;i++){
int s = puzzle.squares[i];
std::vector<int> arr;
arr.push_back(puzzle.digits[i]);
puzzle.values[s]=arr;
}
for (int i=puzzle.x*puzzle.y;i<puzzle.x*puzzle.y*puzzle.x;i++){
int s = puzzle.squares[i];
std::vector<int> arr;
arr.resize(puzzle.x*puzzle.y-puzzle.y);
int idx = 0;
int minV = (i%(puzzle.x*puzzle.y))/puzzle.y;
minV *= puzzle.y;
int maxV = minV + puzzle.y;
for (int ii=0;ii<puzzle.x*puzzle.y;ii++){
if (ii < minV || ii >= maxV){
arr[idx]=puzzle.digits[ii];
idx++;
}
}
puzzle.values[s]=arr;
}
for (int i=puzzle.x*puzzle.y*puzzle.x;i<puzzle.x*puzzle.y*puzzle.x*puzzle.y;i++){
int s = puzzle.squares[i];
std::vector<int> arr;
arr.resize(puzzle.x*puzzle.y-1);
int idx = 0;
for (int ii=0;ii<puzzle.x*puzzle.y;ii++){
if (ii != i%(puzzle.x*puzzle.y)){
arr[idx]=puzzle.digits[ii];
idx++;
}
}
puzzle.values[s]=arr;
}
return puzzle;
}
void full_puzzle(int x,int y, char* pout, int loop){
Puzzle puzzle = reset_puzzle(x, y);
for (int i=0;i<1000000;i++){
int minOptions = x*y*2;
std::vector<int> sqs;
for (int ii=0;ii<x*y*x*y;ii++){
int ss = puzzle.squares[ii];
int sz = puzzle.values[ss].size();
if (sz > 1){
if (sz < minOptions){
minOptions = sz;
sqs.resize(1);
sqs[0] = ss;
}
else if (sz == minOptions){
sqs.push_back(ss);
}
}
}
if (minOptions == x*y*2){
break;
}
int s = sqs[0];
if (sqs.size() > 0){
s = sqs[rand()%sqs.size()];
}
int v = puzzle.values[s][rand()%minOptions];
bool a = puzzle.assign(s, v);
if (!a){break;}
if (puzzle.n == x*y*x*y){
break;
}
}
if (puzzle.n == x*y*x*y){
for (int i=0;i<x*y*x*y;i++){
char c = puzzle.values[puzzle.squares[i]][0]+64;
pout[i]=c;
}
return;
}
else if (loop < 10){
loop++;
full_puzzle(x,y, pout, loop);
return;
}
else {
return;
}
}
int main(int argc, char **argv){
//To start, every square can be any digit;
srand((unsigned) time(NULL));
int x = atoi(argv[1]);
int y = atoi(argv[2]);
char pout[x*y*x*y];
full_puzzle(x,y,pout,0);
pout[x*y*x*y]='\0';
if (pout[0] == 'A'){
ofstream myfile;
myfile.open("puzzle.js");
myfile << "var x = ";
myfile << x;
myfile << ";\n";
myfile << "var y = ";
myfile << y;
myfile << ";\n";
myfile << "var puzzle = '";
for (int i=0;i<x*y*x*y;i++){
myfile << pout[i];
}
myfile << "';\n";
myfile.close();
}
return 1;
}
This repl generates completed sudokus with C++. These puzzles can be used to then create unfinished puzzles.
To view this on TripleLog, click here.
This code is an adaption of Peter Norvig's sudoku solver.
The HTML simply displays a completed sudoku puzzle.
Edit the script.cpp file to change the generator. Compile with "g++ -std=c++20 -O3 script.cpp" or anything else that works. Then run "./a.out 3 3" to create a 3x3 puzzle with information stored in puzzle.js. Change the output filename from the default a.out if you wish.
If you optimize the code, you might be able to make it fast.
A simple script in the index.html file converts the puzzle to a pretty display.