Replacing part of std::vector by smaller std::vector - c++11

I wonder what would be the correct way to replace (overwriting) a part of a given std::vector "input" by another, smaller std::vector?
I do neet to keep the rest of the original vector unchanged.
Also I do not need to bother what has been in the original vector and
I don't need to keep the smaller vector afterwards anymore.
Say I have this:
std::vector<int> input = { 0, 0, 1, 1, 2, 22, 3, 33, 99 };
std::vector<int> a = { 1, 2, 3 };
std::vector<int> b = { 4, 5, 6, 7, 8 };
And I want to achieve that:
input = { 1, 2, 3, 4, 5, 6, 7, 8, 99}
What is the right way to do it? I thought of something like
input.replace(input.beginn(), input.beginn()+a.size(), a);
// intermediate input would look like that: input = { 1, 2, 3, 1, 2, 22, 3, 33, 99 };
input.replace(input.beginn()+a.size(), input.beginn()+a.size()+b.size(), b);
There should be a standard way to do it, shouldn't it?
My thoughts on this so far are the following:
I can not use std::vector::assign for it destroys all elements of input
std::vector::push_back would not replace but enlarge the input --> not what I want
std::vector::insert also creates new elements and enlages the input vector but I know for sure that the vectors a.size() + b.size() <= input.size()
std::vector::swap would not work since there is some content of input that needs to remain there ( in the example the last element) also it would not work to add b that way
std::vector::emplace also increases the input.size -> seems wrong as well
Also I would prefer if the solution would not waste performance by unnecessary clears or writing back values into the vectors a or b. My vectors will be very large for real and this is about performance in the end.
Any competent help would be appreciated very much.

You seem to be after std::copy(). This is how you would use it in your example (live demo on Coliru):
#include <algorithm> // Necessary for `std::copy`...
// ...
std::vector<int> input = { 0, 0, 1, 1, 2, 22, 3, 33, 99 };
std::vector<int> a = { 1, 2, 3 };
std::vector<int> b = { 4, 5, 6, 7, 8 };
std::copy(std::begin(a), std::end(a), std::begin(input));
std::copy(std::begin(b), std::end(b), std::begin(input) + a.size());
As Zyx2000 notes in the comments, in this case you can also use the iterator returned by the first call to std::copy() as the insertion point for the next copy:
auto last = std::copy(std::begin(a), std::end(a), std::begin(input));
std::copy(std::begin(b), std::end(b), last);
This way, random-access iterators are no longer required - that was the case when we had the expression std::begin(input) + a.size().
The first two arguments to std::copy() denote the source range of elements you want to copy. The third argument is an iterator to the first element you want to overwrite in the destination container.
When using std::copy(), make sure that the destination container is large enough to accommodate the number of elements you intend to copy.
Also, the source and the target range should not interleave.

Try this:
#include <iostream>
#include <vector>
#include <algorithm>
int main() {
std::vector<int> input = { 0, 0, 1, 1, 2, 22, 3, 33, 99 };
std::vector<int> a = { 1, 2, 3 };
std::vector<int> b = { 4, 5, 6, 7, 8 };
std::set_union( a.begin(), a.end(), b.begin(), b.end(), input.begin() );
for ( std::vector<int>::const_iterator iter = input.begin();
iter != input.end();
++iter )
{
std::cout << *iter << " ";
}
return 0;
}
It outputs:
1 2 3 4 5 6 7 8 99

Related

How does the Root Method Work in Quick-Union? [duplicate]

I've been studying the quick union algorithm. the code below was the example for the implementation.
Can someone explain to me what happens inside the root method please?
public class quickUnion {
private int[] id;
public void QuickUnionUF(int N){
id = new int [N];
for(int i = 0; i < N; i++){
id[i] = i;
}
}
private int root(int i){
while (i != id[i]){
i = id[i];
}
return i;
}
public boolean connected(int p, int q){
return root(p) == root(q);
}
public void union(int p, int q){
int i = root(p);
int j = root(q);
id[i] = j;
}
}
The core principle of union find is that each element belongs to a disjoint set of elements. This means that, if you draw a forest (set of trees), the forest will contain all the elements, and no element will be in two different trees.
When building these trees, you can imagine that any node either has a parent or is the root. In this implementation of union find (and in most union find implementations), the parent of each element is stored in an array at that element's index. Thus the element equivalent to id[i] is the parent of i.
You might ask: what if i has no parent (aka is a root)? In this case, the convention is to set i to itself (i is its own parent). Thus, id[i] == i simply checks if we have reached the root of the tree.
Putting this all together, the root function traverses, from the start node, all the way up the tree (parent by parent) until it reaches the root. Then it returns the root.
As an aside:
In order for this algorithm to get to the root more quickly, general implementations will 'flatten' the tree: the fewer parents you need to get through to get to the root, the faster the root function will return. Thus, in many implementations, you will see an additional step where you set the parent of an element to its original grandparent (id[i] = id[id[i]]).
The main point of algorithm here is: always keep root of one vertex equals to itself.
Initialization: Init id[i] = i. Each vertex itself is a root.
Merge Root:
If we merge root 5 and root 6. Assume that we want to merge root 6 into root 5. So id[6] = 5. id[5] = 5. --> 5 is root.
If we continue to merge 4 to 6. id[4] = 4 -> base root. id[6] = 5. -> not base root. We continue to find: id[5] = 5 -> base root. so we assign id[4] = 6
In all cases, we always keep convention: if x is base root, id[x] == x That is the main point of algorithm.
From Pdf file provided in the course Union find
Root of i is id[id[id[...id[i]...]]].
according to the given example
public int root(int p){
while(p != id[p]){
p = id[p];
}
return p;
}
lets consider a situation :
The elements of id[] would look like
Now lets call
root(3)
The dry run of loop inside root method is:
To understand the role of the root method, one needs to understand how this data structure is helping to organise values into disjoint sets.
It does so by building trees. Whenever two independent values 𝑝 and 𝑞 are said to belong to the same set, 𝑝 is made a child of 𝑞 (which then is the parent of 𝑝). If however 𝑝 already has a parent, then we first move to that parent of 𝑝, and the parent of that parent, ...until we find an ancestor which has no parent. This is root(p), lets call it 𝑝'. We do the same with 𝑞 if it has a parent. Let's call that ancestor 𝑞'. Finally, 𝑝' is made a child 𝑞'. By doing that, we implicitly make the original 𝑝 and 𝑞 members of the same tree.
How can we know that 𝑝 and 𝑞 are members of the same tree? By looking up their roots. If they happen to have the same root, then they are necessarily in the same tree, i.e. they belong to the same set.
Example
Let's look at an example run:
QuickUnionUF array = new QuickUnionUF(10);
This will create the following array:
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
This array represents edges. The from-side of an edge is the index in the array (0..9), and the to-side of the same edge is the value found at that index (also 0..9). As you can see the array is initialised in a way that all edges are self-references (loops). You could say that every value is the root of its own tree (which has no other values).
Calling root on any of the values 0..9, will return the same number, as for all i we have id[i] == i. So at this stage root does not give us much.
Now, let's indicate that two values actually belong to the same set:
array.union(2, 9);
This will result in the assignment id[2] = 9 and so we get this array:
[0, 1, 9, 3, 4, 5, 6, 7, 8, 9]
Graphically, this established link be represented as:
9
/
2
If now we call root(2) we will get 9 as return value. This tells us that 2 is in the same set (i.e. tree) as 9, and 9 happens to get the role of root of that tree (that was an arbitrary choice; it could also have been 2).
Let's also link 3 and 4 together. This is a very similar case as above:
array.union(3, 4);
This assigns id[3] = 4 and results in this array and tree representation:
[0, 1, 9, 4, 4, 5, 6, 7, 8, 9]
9 4
/ /
2 3
Now let's make it more interesting. Let's indicate that 4 and 9 belong to the same set:
array.union(4, 9);
Still root(4) and root(9) just return those same numbers (4 and 9). Nothing special yet... The assignment is id[4] = 9. This results in this array and graph:
[0, 1, 9, 4, 9, 5, 6, 7, 8, 9]
9
/ \
2 4
/
3
Note how this single assignment has joined two distinct trees into one tree. If now we want to check whether 2 and 3 are in the same tree, we call
if (connected(2, 3)) /* do something */
Although we never said 2 and 3 belonged to the same set explicitly, it should be implied from the previous actions. connected will now use calls to root to imply that fact. root(2) will return 9, and also root(3) will return 9. We get to see what root is doing... it is walking upwards in the graph towards the root node of the tree it is in. The array has all the information needed to make that walk. Given an index we can read in the array which is the parent (index) of that number. This may have to be repeated to get to the grandparent, ...etc: It can be a short or long walk, depending how many "edges" there are between the given node and the root of the tree it is in.
/**
* Quick Find Java Implementation Eager's Approach
*/
package com.weekone.union.quickfind;
import java.util.Random;
/**
* #author Ishwar Singh
*
*/
public class UnionQuickFind {
private int[] itemsArr;
public UnionQuickFind() {
System.out.println("Calling: " + UnionQuickFind.class);
}
public UnionQuickFind(int n) {
itemsArr = new int[n];
}
// p and q are indexes
public void unionOperation(int p, int q) {
// displayArray(itemsArr);
int tempValue = itemsArr[p];
if (!isConnected(p, q)) {
itemsArr[p] = itemsArr[q];
for (int i = 0; i < itemsArr.length; i++) {
if (itemsArr[i] == tempValue) {
itemsArr[i] = itemsArr[q];
}
}
displayArray(p, q);
} else {
displayArray(p, q, "Already Connected");
}
}
public boolean isConnected(int p, int q) {
return (itemsArr[p] == itemsArr[q]);
}
public void connected(int p, int q) {
if (isConnected(p, q)) {
displayArray(p, q, "Already Connected");
} else {
displayArray(p, q, "Not Connected");
}
}
private void displayArray(int p, int q) {
// TODO Auto-generated method stub
System.out.println();
System.out.print("{" + p + " " + q + "} -> ");
for (int i : itemsArr) {
System.out.print(i + ", ");
}
}
private void displayArray(int p, int q, String message) {
System.out.println();
System.out.print("{" + p + " " + q + "} -> " + message);
}
public void initializeArray() {
Random random = new Random();
for (int i = 0; i < itemsArr.length; i++) {
itemsArr[i] = random.nextInt(9);
}
}
public void initializeArray(int[] receivedArr) {
itemsArr = receivedArr;
}
public void displayArray() {
System.out.println("INDEXES");
System.out.print("{p q} -> ");
for (int i : itemsArr) {
System.out.print(i + ", ");
}
System.out.println();
}
}
Main Class:-
/**
*
*/
package com.weekone.union.quickfind;
/**
* #author Ishwar Singh
*
*/
public class UQFClient {
/**
* #param args
*/
public static void main(String[] args) {
int[] arr = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
int n = 10;
UnionQuickFind unionQuickFind = new UnionQuickFind(n);
// unionQuickFind.initializeArray();
unionQuickFind.initializeArray(arr);
unionQuickFind.displayArray();
unionQuickFind.unionOperation(4, 3);
unionQuickFind.unionOperation(3, 8);
unionQuickFind.unionOperation(6, 5);
unionQuickFind.unionOperation(9, 4);
unionQuickFind.unionOperation(2, 1);
unionQuickFind.unionOperation(8, 9);
unionQuickFind.connected(5, 0);
unionQuickFind.unionOperation(5, 0);
unionQuickFind.connected(5, 0);
unionQuickFind.unionOperation(7, 2);
unionQuickFind.unionOperation(6, 1);
}
}
Output:
INDEXES
{p q} -> 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
{4 3} -> 0, 1, 2, 3, 3, 5, 6, 7, 8, 9,
{3 8} -> 0, 1, 2, 8, 8, 5, 6, 7, 8, 9,
{6 5} -> 0, 1, 2, 8, 8, 5, 5, 7, 8, 9,
{9 4} -> 0, 1, 2, 8, 8, 5, 5, 7, 8, 8,
{2 1} -> 0, 1, 1, 8, 8, 5, 5, 7, 8, 8,
{8 9} -> Already Connected
{5 0} -> Not Connected
{5 0} -> 0, 1, 1, 8, 8, 0, 0, 7, 8, 8,
{5 0} -> Already Connected
{7 2} -> 0, 1, 1, 8, 8, 0, 0, 1, 8, 8,
{6 1} -> 1, 1, 1, 8, 8, 1, 1, 1, 8, 8,

gdb query xmm-registers, select representation [duplicate]

I've been using GDB for 1 day and I've accumulated a decent understanding of it.
However when I set a breakpoint at the final semicolon using GDB and print registers I can't fully interpret the meaning of the data stored into the XMM register.
I don't know if the data is in (MSB > LSB) format or vice versa.
__m128i S = _mm_load_si128((__m128i*)Array16Bytes);
}
So this is the result that I'm getting.
(gdb) print $xmm0
$1 = {
v4_float = {1.2593182e-07, -4.1251766e-18, -5.43431603e-31, -2.73406277e-14},
v2_double = {4.6236050467459811e-58, -3.7422963639201271e-245},
v16_int8 = {52, 7, 55, -32, -94, -104, 49, 49, -115, 48, 90, -120, -88, -10, 67, 50},
v8_int16 = {13319, 14304, -23912, 12593, -29392, 23176, -22282, 17202},
v4_int32 = {872888288, -1567084239, -1926210936, -1460255950},
v2_int64 = {3749026652749312305, -8273012972482837710},
uint128 = 0x340737e0a29831318d305a88a8f64332
}
So would someone kindly guide me how to interpret the data.
SSE (XMM) registers can be interpreted in various different ways. The register itself has no knowledge of the implicit data representation, it just holds 128 bits of data. An XMM register can represent:
4 x 32 bit floats __m128
2 x 64 bit doubles __m128d
16 x 8 bit ints __m128i
8 x 16 bit ints __m128i
4 x 32 bit ints __m128i
2 x 64 bit ints __m128i
128 individual bits __m128i
So when gdb displays an XMM register it gives you all possible interpretations, as seen in your example above.
If you want to display a register using a specific interpretation (e.g. 16 x 8 bit ints) then you can do it like this:
(gdb) p $xmm0.v16_int8
$1 = {0, 0, 0, 0, 0, 0, 0, 0, -113, -32, 32, -50, 0, 0, 0, 2}
As for endianness, gdb displays the register contents in natural order, i.e. left-to-right, from MS to LS.
So if you have the following code:
#include <stdio.h>
#include <stdint.h>
#include <xmmintrin.h>
int main(int argc, char *argv[])
{
int8_t buff[16] __attribute__ ((aligned(16))) = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 };
__m128i v = _mm_load_si128((__m128i *)buff);
printf("v = %vd\n", v);
return 0;
}
If you compile and run this you will see:
v = 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
However if you step through the code in gdb and examine v you will see:
v16_int8 = {15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0}

How to filter a flux for all elements having the highest value

How do I filter a publisher for the elements having the highest value without knowing the highest value beforehand?
Here is a little test to illustrate what I'm trying to achieve:
#Test
fun filterForHighestValuesTest() {
val numbers = Flux.just(1, 5, 7, 2, 8, 3, 8, 4, 3)
// what operators to apply to numbers to make the test pass?
StepVerifier.create(numbers)
.expectNext(8)
.expectNext(8)
.verifyComplete()
}
Ive started with the reduce operator:
#Test
fun filterForHighestValuesTestWithReduce() {
val numbers = Flux.just(1, 5, 7, 2, 8, 3, 8, 4, 3)
.reduce { a: Int, b: Int -> if( a > b) a else b }
StepVerifier.create(numbers)
.expectNext(8)
.verifyComplete()
}
and of course that test passes but that will only emit a single Mono whereas I would like to obtain a Flux containing all the elements having the highest values e.g. 8 and 8 in this simple example.
First of all, you'll need state for this so you need to be careful to have per-Subscription state. One way of ensuring that while combining operators is to use compose.
Proposed solution
Flux<Integer> allMatchingHighest = numbers.compose(f -> {
AtomicInteger highestSoFarState = new AtomicInteger(Integer.MIN_VALUE);
AtomicInteger windowState = new AtomicInteger(Integer.MIN_VALUE);
return f.filter(v -> {
int highestSoFar = highestSoFarState.get();
if (v > highestSoFar) {
highestSoFarState.set(v);
return true;
}
if (v == highestSoFar) {
return true;
}
return false;
})
.bufferUntil(i -> i != windowState.getAndSet(i), true)
.log()
.takeLast(1)
.flatMapIterable(Function.identity());
});
Note the whole compose lamdba can be extracted into a method, making the code use a method reference and be more readable.
Explaination
The solution is done in 4 steps, with the two first each having their own AtomicInteger state:
Incrementally find the new "highest" element (so far) and filter out elements that are smaller. This results in a Flux<Integer> of (monotically) increasing numbers, like 1 5 7 8 8.
buffer by chunks of equal number. We use bufferUntil instead of window* or groupBy because the most degenerative case were numbers are all different and already sorted would fail with these
skip all buffers but one (takeLast(1))
"replay" that last buffer, which represents the number of occurrences of our highest value (flatMapIterable)
This correctly pass your StepVerifier test by emitting 8 8. Note the intermediate buffers emitted are:
onNext([1])
onNext([5])
onNext([7, 7, 7])
onNext([8, 8])
More advanced testing, justifying bufferUntil
A far more complex source that would fail with groupBy but not this solution:
Random rng = new Random();
//generate 258 numbers, each randomly repeated 1 to 10 times
//also, shuffle the whole thing
Flux<Integer> numbers = Flux
.range(1, 258)
.flatMap(i -> Mono.just(i).repeat(rng.nextInt(10)))
.collectList()
.map(l -> {
Collections.shuffle(l);
System.out.println(l);
return l;
})
.flatMapIterable(Function.identity())
.hide();
This is one example of what sequence of buffers it could filter into (keep in mind only the last one gets replayed):
onNext([192])
onNext([245])
onNext([250])
onNext([256, 256])
onNext([257])
onNext([258, 258, 258, 258, 258, 258, 258, 258, 258])
onComplete()
Note: If you remove the map that shuffles, then you obtain the "degenerative case" where even windowUntil wouldn't work (the takeLast would result in too many open yet unconsumed windows).
This was a fun one to come up with!
One way to do it is to map the flux of ints to a flux of lists with one int in each, reduce the result, and end with flatMapMany, i.e.
final Flux<Integer> numbers = Flux.just(1, 5, 7, 2, 8, 3, 8, 4, 3);
final Flux<Integer> maxValues =
numbers
.map(
n -> {
List<Integer> list = new ArrayList<>();
list.add(n);
return list;
})
.reduce(
(l1, l2) -> {
if (l1.get(0).compareTo(l2.get(0)) > 0) {
return l1;
} else if (l1.get(0).equals(l2.get(0))) {
l1.addAll(l2);
return l1;
} else {
return l2;
}
})
.flatMapMany(Flux::fromIterable);
One simple solution that worked for me -
Flux<Integer> flux =
Flux.just(1, 5, 7, 2, 8, 3, 8, 4, 3).collectSortedList(Comparator.reverseOrder()).flatMapMany(Flux::fromIterable);
StepVerifier.create(flux).expectNext(8).expectNext(8).expectNext(7).expectNext(5);
One possible solution is to group the Flux prior to the reduction and flatmap the GroupedFlux afterwards like this:
#Test
fun filterForHighestValuesTest() {
val numbers = Flux.just(1, 5, 7, 2, 8, 3, 8, 4, 3)
.groupBy { it }
.reduce { t: GroupedFlux<Int, Int>, u: GroupedFlux<Int, Int> ->
if (t.key()!! > u.key()!!) t else u
}
.flatMapMany {
it
}
StepVerifier.create(numbers)
.expectNext(8)
.expectNext(8)
.verifyComplete()
}

Making sure that two lists have same elements

I have two lists, A and B. I want to check A with B and make sure that A contains only the elements that B contains.
Example: In A={1, 2, 3, 4}, B ={3, 4, 5, 6}. At the end, I want A to be {3, 4, 5, 6}.
Conditions: I don't want to replace A completely with B and I don't want to change B.
public void setA(List B)
{
foreach(x in B)
{
if(!A.Contains(x))
A.Add(x)
}
foreach(x in A)
{
if(!B.Contains(x))
A.Delete(x)
}
}
Is there any better way to do this? (May be in a single for loop or even better)
Try the following:
var listATest = new List<int>() { 1, 2, 3, 4, 34, 3, 2 };
var listBTest = new List<int>() { 3, 4, 5, 6 };
// Make sure listATest is no longer than listBTest first
while (listATest.Count > listBTest.Count)
{
// Remove from end; as I understand it, remove from beginning is O(n)
// and remove from end is O(1) in Microsoft's implementation
// See http://stackoverflow.com/questions/1433307/speed-of-c-sharp-lists
listATest.RemoveAt(listATest.Count - 1);
}
for (int i = 0; i < listBTest.Count; i++)
{
// Handle the case where the listATest is shorter than listBTest
if (i >= listATest.Count)
listATest.Add(listBTest[i]);
// Make sure that the items are different before doing the copy
else if (listATest[i] != listBTest[i])
listATest[i] = listBTest[i];
}

A cool algorithm to check a Sudoku field?

Does anyone know a simple algorithm to check if a Sudoku-Configuration is valid? The simplest algorithm I came up with is (for a board of size n) in Pseudocode
for each row
for each number k in 1..n
if k is not in the row (using another for-loop)
return not-a-solution
..do the same for each column
But I'm quite sure there must be a better (in the sense of more elegant) solution. Efficiency is quite unimportant.
You need to check for all the constraints of Sudoku :
check the sum on each row
check the sum on each column
check for sum on each box
check for duplicate numbers on each row
check for duplicate numbers on each column
check for duplicate numbers on each box
that's 6 checks altogether.. using a brute force approach.
Some sort of mathematical optimization can be used if you know the size of the board (ie 3x3 or 9x9)
Edit: explanation for the sum constraint: Checking for the sum first (and stoping if the sum is not 45) is much faster (and simpler) than checking for duplicates. It provides an easy way of discarding a wrong solution.
Peter Norvig has a great article on solving sudoku puzzles (with python),
https://norvig.com/sudoku.html
Maybe it's too much for what you want to do, but it's a great read anyway
Check each row, column and box such that it contains the numbers 1-9 each, with no duplicates. Most answers here already discuss this.
But how to do that efficiently? Answer: Use a loop like
result=0;
for each entry:
result |= 1<<(value-1)
return (result==511);
Each number will set one bit of the result. If all 9 numbers are unique, the lowest 9
bits will be set.
So the "check for duplicates" test is just a check that all 9 bits are set, which is the same as testing result==511.
You need to do 27 of these checks.. one for each row, column, and box.
Just a thought: don't you need to also check the numbers in each 3x3 square?
I'm trying to figure out if it is possible to have the rows and columns conditions satisfied without having a correct sudoku
This is my solution in Python, I'm glad to see it's the shortest one yet :)
The code:
def check(sud):
zippedsud = zip(*sud)
boxedsud=[]
for li,line in enumerate(sud):
for box in range(3):
if not li % 3: boxedsud.append([]) # build a new box every 3 lines
boxedsud[box + li/3*3].extend(line[box*3:box*3+3])
for li in range(9):
if [x for x in [set(sud[li]), set(zippedsud[li]), set(boxedsud[li])] if x != set(range(1,10))]:
return False
return True
And the execution:
sudoku=[
[7, 5, 1, 8, 4, 3, 9, 2, 6],
[8, 9, 3, 6, 2, 5, 1, 7, 4],
[6, 4, 2, 1, 7, 9, 5, 8, 3],
[4, 2, 5, 3, 1, 6, 7, 9, 8],
[1, 7, 6, 9, 8, 2, 3, 4, 5],
[9, 3, 8, 7, 5, 4, 6, 1, 2],
[3, 6, 4, 2, 9, 7, 8, 5, 1],
[2, 8, 9, 5, 3, 1, 4, 6, 7],
[5, 1, 7, 4, 6, 8, 2, 3, 9]]
print check(sudoku)
Create an array of booleans for every row, column, and square. The array's index represents the value that got placed into that row, column, or square. In other words, if you add a 5 to the second row, first column, you would set rows[2][5] to true, along with columns[1][5] and squares[4][5], to indicate that the row, column, and square now have a 5 value.
Regardless of how your original board is being represented, this can be a simple and very fast way to check it for completeness and correctness. Simply take the numbers in the order that they appear on the board, and begin building this data structure. As you place numbers in the board, it becomes a O(1) operation to determine whether any values are being duplicated in a given row, column, or square. (You'll also want to check that each value is a legitimate number: if they give you a blank or a too-high number, you know that the board is not complete.) When you get to the end of the board, you'll know that all the values are correct, and there is no more checking required.
Someone also pointed out that you can use any form of Set to do this. Arrays arranged in this manner are just a particularly lightweight and performant form of a Set that works well for a small, consecutive, fixed set of numbers. If you know the size of your board, you could also choose to do bit-masking, but that's probably a little overly tedious considering that efficiency isn't that big a deal to you.
Create cell sets, where each set contains 9 cells, and create sets for vertical columns, horizontal rows, and 3x3 squares.
Then for each cell, simply identify the sets it's part of and analyze those.
You could extract all values in a set (row, column, box) into a list, sort it, then compare to '(1, 2, 3, 4, 5, 6, 7, 8, 9)
I did this once for a class project. I used a total of 27 sets to represent each row, column and box. I'd check the numbers as I added them to each set (each placement of a number causes the number to be added to 3 sets, a row, a column, and a box) to make sure the user only entered the digits 1-9. The only way a set could get filled is if it was properly filled with unique digits. If all 27 sets got filled, the puzzle was solved. Setting up the mappings from the user interface to the 27 sets was a bit tedious, but made the rest of the logic a breeze to implement.
It would be very interesting to check if:
when the sum of each row/column/box equals n*(n+1)/2
and the product equals n!
with n = number of rows or columns
this suffices the rules of a sudoku. Because that would allow for an algorithm of O(n^2), summing and multiplying the correct cells.
Looking at n = 9, the sums should be 45, the products 362880.
You would do something like:
for i = 0 to n-1 do
boxsum[i] := 0;
colsum[i] := 0;
rowsum[i] := 0;
boxprod[i] := 1;
colprod[i] := 1;
rowprod[i] := 1;
end;
for i = 0 to n-1 do
for j = 0 to n-1 do
box := (i div n^1/2) + (j div n^1/2)*n^1/2;
boxsum[box] := boxsum[box] + cell[i,j];
boxprod[box] := boxprod[box] * cell[i,j];
colsum[i] := colsum[i] + cell[i,j];
colprod[i] := colprod[i] * cell[i,j];
rowsum[j] := colsum[j] + cell[i,j];
rowprod[j] := colprod[j] * cell[i,j];
end;
end;
for i = 0 to n-1 do
if boxsum[i] <> 45
or colsum[i] <> 45
or rowsum[i] <> 45
or boxprod[i] <> 362880
or colprod[i] <> 362880
or rowprod[i] <> 362880
return false;
Some time ago, I wrote a sudoku checker that checks for duplicate number on each row, duplicate number on each column & duplicate number on each box. I would love it if someone could come up one with like a few lines of Linq code though.
char VerifySudoku(char grid[81])
{
for (char r = 0; r < 9; ++r)
{
unsigned int bigFlags = 0;
for (char c = 0; c < 9; ++c)
{
unsigned short buffer = r/3*3+c/3;
// check horizontally
bitFlags |= 1 << (27-grid[(r<<3)+r+c])
// check vertically
| 1 << (18-grid[(c<<3)+c+r])
// check subgrids
| 1 << (9-grid[(buffer<<3)+buffer+r%3*3+c%3]);
}
if (bitFlags != 0x7ffffff)
return 0; // invalid
}
return 1; // valid
}
if the sum and the multiplication of a row/col equals to the right number 45/362880
First, you would need to make a boolean, "correct". Then, make a for loop, as previously stated. The code for the loop and everything afterwards (in java) is as stated, where field is a 2D array with equal sides, col is another one with the same dimensions, and l is a 1D one:
for(int i=0; i<field.length(); i++){
for(int j=0; j<field[i].length; j++){
if(field[i][j]>9||field[i][j]<1){
checking=false;
break;
}
else{
col[field[i].length()-j][i]=field[i][j];
}
}
}
I don't know the exact algorithim to check the 3x3 boxes, but you should check all the rows in field and col with "/*array name goes here*/[i].contains(1)&&/*array name goes here*/[i].contains(2)" (continues until you reach the length of a row) inside another for loop.
def solution(board):
for i in board:
if sum(i) != 45:
return "Incorrect"
for i in range(9):
temp2 = []
for x in range(9):
temp2.append(board[i][x])
if sum(temp2) != 45:
return "Incorrect"
return "Correct"
board = []
for i in range(9):
inp = raw_input()
temp = [int(i) for i in inp]
board.append(temp)
print solution(board)
Here's a nice readable approach in Python:
from itertools import chain
def valid(puzzle):
def get_block(x,y):
return chain(*[puzzle[i][3*x:3*x+3] for i in range(3*y, 3*y+3)])
rows = [set(row) for row in puzzle]
columns = [set(column) for column in zip(*puzzle)]
blocks = [set(get_block(x,y)) for x in range(0,3) for y in range(0,3)]
return all(map(lambda s: s == set([1,2,3,4,5,6,7,8,9]), rows + columns + blocks))
Each 3x3 square is referred to as a block, and there are 9 of them in a 3x3 grid. It is assumed as the puzzle is input as a list of list, with each inner list being a row.
Let's say int sudoku[0..8,0..8] is the sudoku field.
bool CheckSudoku(int[,] sudoku)
{
int flag = 0;
// Check rows
for(int row = 0; row < 9; row++)
{
flag = 0;
for (int col = 0; col < 9; col++)
{
// edited : check range step (see comments)
if ((sudoku[row, col] < 1)||(sudoku[row, col] > 9))
{
return false;
}
// if n-th bit is set.. but you can use a bool array for readability
if ((flag & (1 << sudoku[row, col])) != 0)
{
return false;
}
// set the n-th bit
flag |= (1 << sudoku[row, col]);
}
}
// Check columns
for(int col= 0; col < 9; col++)
{
flag = 0;
for (int row = 0; row < 9; row++)
{
if ((flag & (1 << sudoku[row, col])) != 0)
{
return false;
}
flag |= (1 << sudoku[row, col]);
}
}
// Check 3x3 boxes
for(int box= 0; box < 9; box++)
{
flag = 0;
for (int ofs = 0; ofs < 9; ofs++)
{
int col = (box % 3) * 3;
int row = ((int)(box / 3)) * 3;
if ((flag & (1 << sudoku[row, col])) != 0)
{
return false;
}
flag |= (1 << sudoku[row, col]);
}
}
return true;
}
Let's assume that your board goes from 1 - n.
We'll create a verification array, fill it and then verify it.
grid [0-(n-1)][0-(n-1)]; //this is the input grid
//each verification takes n^2 bits, so three verifications gives us 3n^2
boolean VArray (3*n*n) //make sure this is initialized to false
for i = 0 to n
for j = 0 to n
/*
each coordinate consists of three parts
row/col/box start pos, index offset, val offset
*/
//to validate rows
VArray( (0) + (j*n) + (grid[i][j]-1) ) = 1
//to validate cols
VArray( (n*n) + (i*n) + (grid[i][j]-1) ) = 1
//to validate boxes
VArray( (2*n*n) + (3*(floor (i/3)*n)+ floor(j/3)*n) + (grid[i][j]-1) ) = 1
next
next
if every array value is true then the solution is correct.
I think that will do the trick, although i'm sure i made a couple of stupid mistakes in there. I might even have missed the boat entirely.
array = [1,2,3,4,5,6,7,8,9]
sudoku = int [][]
puzzle = 9 #9x9
columns = map []
units = map [] # box
unit_l = 3 # box width/height
check_puzzle()
def strike_numbers(line, line_num, columns, units, unit_l):
count = 0
for n in line:
# check which unit we're in
unit = ceil(n / unit_l) + ceil(line_num / unit_l) # this line is wrong - rushed
if units[unit].contains(n): #is n in unit already?
return columns, units, 1
units[unit].add(n)
if columns[count].contains(n): #is n in column already?
return columns, units, 1
columns[count].add(n)
line.remove(n) #remove num from temp row
return columns, units, line.length # was a number not eliminated?
def check_puzzle(columns, sudoku, puzzle, array, units):
for (i=0;i< puzzle;i++):
columns, units, left_over = strike_numbers(sudoku[i], i, columns, units) # iterate through rows
if (left_over > 0): return false
Without thoroughly checking, off the top of my head, this should work (with a bit of debugging) while only looping twice. O(n^2) instead of O(3(n^2))
Here is paper by math professor J.F. Crook: A Pencil-and-Paper Algorithm for Solving Sudoku Puzzles
This paper was published in April 2009 and it got lots of publicity as definite Sudoku solution (check google for "J.F.Crook Sudoku" ).
Besides algorithm, there is also a mathematical proof that algorithm works (professor admitted that he does not find Sudoku very interesting, so he threw some math in paper to make it more fun).
I'd write an interface that has functions that receive the sudoku field and returns true/false if it's a solution.
Then implement the constraints as single validation classes per constraint.
To verify just iterate through all constraint classes and when all pass the sudoku is correct. To speedup put the ones that most likely fail to the front and stop in the first result that points to invalid field.
Pretty generic pattern. ;-)
You can of course enhance this to provide hints which field is presumably wrong and so on.
First constraint, just check if all fields are filled out. (Simple loop)
Second check if all numbers are in each block (nested loops)
Third check for complete rows and columns (almost same procedure as above but different access scheme)
Here is mine in C. Only pass each square once.
int checkSudoku(int board[]) {
int i;
int check[13] = { 0 };
for (i = 0; i < 81; i++) {
if (i % 9 == 0) {
check[9] = 0;
if (i % 27 == 0) {
check[10] = 0;
check[11] = 0;
check[12] = 0;
}
}
if (check[i % 9] & (1 << board[i])) {
return 0;
}
check[i % 9] |= (1 << board[i]);
if (check[9] & (1 << board[i])) {
return 0;
}
check[9] |= (1 << board[i]);
if (i % 9 < 3) {
if (check[10] & (1 << board[i])) {
return 0;
}
check[10] |= (1 << board[i]);
} else if (i % 9 < 6) {
if (check[11] & (1 << board[i])) {
return 0;
}
check[11] |= (1 << board[i]);
} else {
if (check[12] & (1 << board[i])) {
return 0;
}
check[12] |= (1 << board[i]);
}
}
}
Here is what I just did for this:
boolean checkers=true;
String checking="";
if(a.length/3==1){}
else{
for(int l=1; l<a.length/3; l++){
for(int n=0;n<3*l;n++){
for(int lm=1; lm<a[n].length/3; lm++){
for(int m=0;m<3*l;m++){
System.out.print(" "+a[n][m]);
if(a[n][m]<=0){
System.out.print(" (Values must be positive!) ");
}
if(n==0){
if(m!=0){
checking+=", "+a[n][m];
}
else{
checking+=a[n][m];
}
}
else{
checking+=", "+a[n][m];
}
}
}
System.out.print(" "+checking);
System.out.println();
}
}
for (int i=1;i<=a.length*a[1].length;i++){
if(checking.contains(Integer.toString(i))){
}
else{
checkers=false;
}
}
}
checkers=checkCol(a);
if(checking.contains("-")&&!checking.contains("--")){
checkers=false;
}
System.out.println();
if(checkers==true){
System.out.println("This is correct! YAY!");
}
else{
System.out.println("Sorry, it's not right. :-(");
}
}
private static boolean checkCol(int[][]a){
boolean checkers=true;
int[][]col=new int[][]{{0,0,0},{0,0,0},{0,0,0}};
for(int i=0; i<a.length; i++){
for(int j=0; j<a[i].length; j++){
if(a[i][j]>9||a[i][j]<1){
checkers=false;
break;
}
else{
col[a[i].length-j][i]=a[i][j];
}
}
}
String alia="";
for(int i=0; i<col.length; i++){
for(int j=1; j<=col[i].length; j++){
alia=a[i].toString();
if(alia.contains(""+j)){
alia=col[i].toString();
if(alia.contains(""+j)){}
else{
checkers=false;
}
}
else{
checkers=false;
}
}
}
return checkers;
}
You can check if sudoku is solved, in these two similar ways:
Check if the number is unique in each row, column and block.
A naive solution would be to iterate trough every square and check if the number is unique in the row, column block that number occupies.
But there is a better way.
Sudoku is solved if every row, column and block contains a permutation of the numbers (1 trough 9)
This only requires to check every row, column and block, instead of doing that for every number. A simple implementation would be to have a bitfield of numbers 1 trough 9 and remove them when you iterate the columns, rows and blocks. If you try to remove a missing number or if the field isn't empty when you finish then sudoku isn't correctly solved.
Here's a very concise version in Swift, that only uses an array of Ints to track the groups of 9 numbers, and only iterates over the sudoku once.
import UIKit
func check(_ sudoku:[[Int]]) -> Bool {
var groups = Array(repeating: 0, count: 27)
for x in 0...8 {
for y in 0...8 {
groups[x] += 1 << sudoku[x][y] // Column (group 0 - 8)
groups[y + 9] += 1 << sudoku[x][y] // Row (group 9 - 17)
groups[(x + y * 9) / 9 + 18] += 1 << sudoku[x][y] // Box (group 18 - 27)
}
}
return groups.filter{ $0 != 1022 }.count == 0
}
let sudoku = [
[7, 5, 1, 8, 4, 3, 9, 2, 6],
[8, 9, 3, 6, 2, 5, 1, 7, 4],
[6, 4, 2, 1, 7, 9, 5, 8, 3],
[4, 2, 5, 3, 1, 6, 7, 9, 8],
[1, 7, 6, 9, 8, 2, 3, 4, 5],
[9, 3, 8, 7, 5, 4, 6, 1, 2],
[3, 6, 4, 2, 9, 7, 8, 5, 1],
[2, 8, 9, 5, 3, 1, 4, 6, 7],
[5, 1, 7, 4, 6, 8, 2, 3, 9]
]
if check(sudoku) {
print("Pass")
} else {
print("Fail")
}
One minor optimization you can make is that you can check for duplicates in a row, column, or box in O(n) time rather than O(n^2): as you iterate through the set of numbers, you add each one to a hashset. Depending on the language, you may actually be able to use a true hashset, which is constant time lookup and insertion; then checking for duplicates can be done in the same step by seeing if the insertion was successful or not. It's a minor improvement in the code, but going from O(n^2) to O(n) is a significant optimization.

Resources