Shift the array as loop - list

How can I shift the list as a loop?
The input:
local connections = {1, 1, 0, 1}
Needed result:
local variants = {
{1, 1, 0, 1}, -- as original table
{1, 1, 1, 0}, -- shifted once to the right
{0, 1, 1, 1}, -- shifted twice
{1, 0, 1, 1}, -- shifted three times
}

You want to perform a shift with "wraparound" / "circular" shift. [table.move], as pointed out by lhf, is almost what you need, but lacks the "circular part" and is unavailable on older versions of Lua (such as 5.1, which is still in widespread use). I thus propose implementing this in Lua as below, particularly if you want a new table:
local function cyclic_table_shift(tab, shift)
local len = #tab
local shifted = {}
for i = 1, len do
shifted[i] = tab[(i - 1 - shift) % len + 1] -- mod to make it wrap
end
return shifted
end
this yields the correct results for your example:
> connections = {1, 1, 0, 1}
> function cyclic_table_shift(tab, shift)
>> local len = #tab
>> local shifted = {}
>> for i = 1, len do
>> shifted[i] = tab[(i - 1 - shift) % len + 1] -- mod to make it wrap
>> end
>> return shifted
>> end
> table.unpack(cyclic_table_shift(connections, 0))
1 1 0 1
> table.unpack(cyclic_table_shift(connections, 1))
1 1 1 0
> table.unpack(cyclic_table_shift(connections, 2))
0 1 1 1
> table.unpack(cyclic_table_shift(connections, 3))
1 0 1 1

Thanks all, there is the solution for Lua 5.1 (and 5.4)
if not table.move then
print ('used custom table.move')
-- thanks to index five
function table.move(a1,f,e,t,a2) -- a1, f, e, t [,a2]
-- Moves elements from the table a1 to the table a2,
-- performing the equivalent to the following multiple assignment:
-- a2[t],··· = a1[f],···,a1[e]. The default for a2 is a1.
-- The destination range can overlap with the source range.
-- The number of elements to be moved must fit in a Lua integer.
a2 = a2 or a1
if (a2 ~= a1) or (t < f) then -- use a2
for i = f, e do
a2[t+i-f] = a1[i]
end
elseif (t > f) then
for i = e, f, -1 do
a2[t+i-f] = a1[i]
end
end
return a2
end
end
table.unpack = table.unpack or unpack
function circularShift (tabl, shift)
local len = #tabl
local shifted = {}
table.move(tabl,len-shift,len,0,shifted)
table.move(tabl,1,len-shift,shift+1,shifted)
return shifted
end
local connections = {1, 1, 0, 1}
print (table.unpack(circularShift(connections, 0)))
print (table.unpack(circularShift(connections, 1)))
print (table.unpack(circularShift(connections, 2)))
print (table.unpack(circularShift(connections, 3)))
Result:
1 1 0 1
1 1 1 0
0 1 1 1
1 0 1 1
But the version of LMD is simpler and can accept left shifting too.

For Lua 5.3+, you can use table.move to do most of the work:
function shift(a)
local n=#a
local t=a[n]
table.move(a,1,n-1,2)
a[1]=t
end

Related

find minimum sum of non-neighbouring K entries inside an array

Given an integer array A of size N, find minimum sum of K non-neighboring entries (entries cant be adjacent to one another, for example, if K was 2, you cant add A[2], A[3] and call it minimum sum, even if it was, because those are adjacent/neighboring to one another), example:
A[] = {355, 46, 203, 140, 28}, k = 2, result would be 74 (46 + 28)
A[] = {9, 4, 0, 9, 14, 7, 1}, k = 3, result would be 10 (9 + 0 + 1)
The problem is somewhat similar to House Robber on leetcode, except instead of finding maximum sum of non-adjacent entries, we are tasked to find the minimum sum and with constraint K entries.
From my prespective, this is clearly a dynamic programming problem, so i tried to break down the problem recursively and implemented something like this:
#include <vector>
#include <iostream>
using namespace std;
int minimal_k(vector<int>& nums, int i, int k)
{
if (i == 0) return nums[0];
if (i < 0 || !k) return 0;
return min(minimal_k(nums, i - 2, k - 1) + nums[i], minimal_k(nums, i - 1, k));
}
int main()
{
// example above
vector<int> nums{9, 4, 0, 9, 14, 7, 1};
cout << minimal_k(nums, nums.size() - 1, 3);
// output is 4, wrong answer
}
This was my attempt at the solution, I have played around a lot with this but no luck, so what would be a solution to this problem?
This line:
if (i < 0 || !k) return 0;
If k is 0, you should probably return return 0. But if i < 0 or if the effective length of the array is less than k, you probably need to return a VERY LARGE value such that the summed result goes higher than any valid solution.
In my solution, I have the recursion return INT_MAX as a long long when recursing into an invalid subset or when k exceeds the remaining length.
And as with any of these dynamic programming and recursion problems, a cache of results so that you don't repeat the same recursive search will help out a bunch. This will speed things up by several orders of magnitude for very large input sets.
Here's my solution.
#include <iostream>
#include <vector>
#include <unordered_map>
#include <algorithm>
using namespace std;
// the "cache" is a map from offset to another map
// that tracks k to a final result.
typedef unordered_map<size_t, unordered_map<size_t, long long>> CACHE_MAP;
bool get_cache_result(const CACHE_MAP& cache, size_t offset, size_t k, long long& result);
void insert_into_cache(CACHE_MAP& cache, size_t offset, size_t k, long long result);
long long minimal_k_impl(const vector<int>& nums, size_t offset, size_t k, CACHE_MAP& cache)
{
long long result = INT_MAX;
size_t len = nums.size();
if (k == 0)
{
return 0;
}
if (offset >= len)
{
return INT_MAX; // exceeded array boundary, return INT_MAX
}
size_t effective_length = len - offset;
// If we have more k than remaining elements, return INT_MAX to indicate
// that this recursion is invalid
// you might be able to reduce to checking (effective_length/2+1 < k)
if ( (effective_length < k) || ((effective_length == k) && (k != 1)) )
{
return INT_MAX;
}
if (get_cache_result(cache, offset, k, result))
{
return result;
}
long long sum1 = nums[offset] + minimal_k_impl(nums, offset + 2, k - 1, cache);
long long sum2 = minimal_k_impl(nums, offset + 1, k, cache);
result = std::min(sum1, sum2);
insert_into_cache(cache, offset, k, result);
return result;
}
long long minimal_k(const vector<int>& nums, size_t k)
{
CACHE_MAP cache;
return minimal_k_impl(nums, 0, k, cache);
}
bool get_cache_result(const CACHE_MAP& cache, size_t offset, size_t k, long long& result)
{
// effectively this code does this:
// result = cache[offset][k]
bool ret = false;
auto itor1 = cache.find(offset);
if (itor1 != cache.end())
{
auto& inner_map = itor1->second;
auto itor2 = inner_map.find(k);
if (itor2 != inner_map.end())
{
ret = true;
result = itor2->second;
}
}
return ret;
}
void insert_into_cache(CACHE_MAP& cache, size_t offset, size_t k, long long result)
{
cache[offset][k] = result;
}
int main()
{
vector<int> nums1{ 355, 46, 203, 140, 28 };
vector<int> nums2{ 9, 4, 0, 9, 14, 7, 1 };
vector<int> nums3{8,6,7,5,3,0,9,5,5,5,1,2,9,-10};
long long result = minimal_k(nums1, 2);
std::cout << result << std::endl;
result = minimal_k(nums2, 3);
std::cout << result << std::endl;
result = minimal_k(nums3, 3);
std::cout << result << std::endl;
return 0;
}
It is core sorting related problem. To find sum of minimum k non adjacent elements requires minimum value elements to bring next to each other by sorting. Let's see this sorting approach,
Given input array = [9, 4, 0, 9, 14, 7, 1] and k = 3
Create another array which contains elements of input array with indexes as showed below,
[9, 0], [4, 1], [0, 2], [9, 3], [14, 4], [7, 5], [1, 6]
then sort this array.
Motive behind this element and index array is, after sorting information of index of each element will not be lost.
One more array is required to keep record of used indexes, so initial view of information after sorting is as showed below,
Element and Index array
..............................
| 0 | 1 | 4 | 7 | 9 | 9 | 14 |
..............................
2 6 1 5 3 0 4 <-- Index
Used index record array
..............................
| 0 | 0 | 0 | 0 | 0 | 0 | 0 |
..............................
0 1 2 3 4 5 6 <-- Index
In used index record array 0 (false) means element at this index is not included yet in minimum sum.
Front element of sorted array is minimum value element and we include it for minimum sum and update used index record array to indicate that this element is used, as showed below,
font element is 0 at index 2 and due to this set 1(true) at index 2 of used index record array showed below,
min sum = 0
Used index record array
..............................
| 0 | 0 | 1 | 0 | 0 | 0 | 0 |
..............................
0 1 2 3 4 5 6
iterate to next element in sorted array and as you can see above it is 1 and have index 6. To include 1 in minimum sum we have to find, is left or right adjacent element of 1 already used or not, so 1 has index 6 and it is last element in input array it means we only have to check if value of index 5 is already used or not, and this can be done by looking at used index record array, and as showed above usedIndexRerocd[5] = 0 so 1 can be considered for minimum sum. After using 1, state updated to following,
min sum = 0 + 1
Used index record array
..............................
| 0 | 0 | 1 | 0 | 0 | 0 | 1 |
..............................
0 1 2 3 4 5 6
than iterate to next element which is 4 at index 1 but this can not be considered because element at index 0 is already used, same happen with elements 7, 9 because these are at index 5, 3 respectively and adjacent to used elements.
Finally iterating to 9 at index = 0 and by looking at used index record array usedIndexRecordArray[1] = 0 and that's why 9 can be included in minimum sum and final state reached to following,
min sum = 0 + 1 + 9
Used index record array
..............................
| 1 | 0 | 1 | 0 | 0 | 0 | 1 |
..............................
0 1 2 3 4 5 6
Finally minimum sum = 10,
One of the Worst case scenario when input array is already sorted then at least 2*k - 1 elements have to be iterated to find minimum sum of non adjacent k elements as showed below
input array = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] and k = 4 then following highlighted elements shall be considered for minimum sum,
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
Note: You have to include all input validation, like one of the validation is, if you want to find minimum sum of k non adjacent elements then input should have at least 2*k - 1 elements. I am not including these validations because i am aware of all input constraints of problem.
#include <iostream>
#include <vector>
#include <algorithm>
using std::cout;
long minSumOfNonAdjacentKEntries(std::size_t k, const std::vector<int>& arr){
if(arr.size() < 2){
return 0;
}
std::vector<std::pair<int, std::size_t>> numIndexArr;
numIndexArr.reserve(arr.size());
for(std::size_t i = 0, arrSize = arr.size(); i < arrSize; ++i){
numIndexArr.emplace_back(arr[i], i);
}
std::sort(numIndexArr.begin(), numIndexArr.end(), [](const std::pair<int, std::size_t>& a,
const std::pair<int, std::size_t>& b){return a.first < b.first;});
long minSum = numIndexArr.front().first;
std::size_t elementCount = 1;
std::size_t lastIndex = arr.size() - 1;
std::vector<bool> usedIndexRecord(arr.size(), false);
usedIndexRecord[numIndexArr.front().second] = true;
for(std::vector<std::pair<int, std::size_t>>::const_iterator it = numIndexArr.cbegin() + 1,
endIt = numIndexArr.cend(); elementCount < k && endIt != it; ++it){
bool leftAdjacentElementUsed = (0 == it->second) ? false : usedIndexRecord[it->second - 1];
bool rightAdjacentElementUsed = (lastIndex == it->second) ? false : usedIndexRecord[it->second + 1];
if(!leftAdjacentElementUsed && !rightAdjacentElementUsed){
minSum += it->first;
++elementCount;
usedIndexRecord[it->second] = true;
}
}
return minSum;
}
int main(){
cout<< "k = 2, [355, 46, 203, 140, 28], min sum = "<< minSumOfNonAdjacentKEntries(2, {355, 46, 203, 140, 28})
<< '\n';
cout<< "k = 3, [9, 4, 0, 9, 14, 7, 1], min sum = "<< minSumOfNonAdjacentKEntries(3, {9, 4, 0, 9, 14, 7, 1})
<< '\n';
}
Output:
k = 2, [355, 46, 203, 140, 28], min sum = 74
k = 3, [9, 4, 0, 9, 14, 7, 1], min sum = 10

How to find the number of sequences of zeros and ones without "111" [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Closed 9 years ago.
Improve this question
I have a problem:
I have a N (N <= 40). N is a length of sequence of zeroz and ones. How to find the number of sequences of zeros and ones in which there are no three "1" together?
Example:
N = 3, answer = 7
0 0 0
0 0 1
0 1 0
0 1 1
1 0 0
1 0 1
1 1 0
Here's a solution using a recursive function :
(PHP code here, but it's really simple)
$seq = '';
function tree ($node, $flag, $seq)
{
if ($flag == 3) { return 0; }
if ($node == 0) { echo $seq, ' '; return 0;}
$seq1 = $seq.'1';
$seq2 = $seq.'0';
tree($node-1, $flag+1, $seq1);
tree($node-1, 0, $seq2);
}
tree(8, 0, $seq);
I use a tree to go through all the possible sequences, and a flag to check how many 1 in a row.
If there is two 1 in a row, then the flag reaches 3, and the function is stopped for this branch.
If we reach a leaf of the tree (ie. $node = 0), then the sequence is displayed, and the function ends.
Else, the function explores the two sub-trees starting from the current node.
void tree ( int node, int flag, std::string seq)
{
std::string seq1 = seq;
std::string seq2 = seq;
if(flag ==3) { return; }
if(node ==0) { printf("%s\n",seq.c_str()); return;}
seq1 += '1';
seq2 += '0';
tree(node-1, flag+1, seq1);
tree(node-1, 0, seq2);
}
You can write a grammar for the (non-empty) strings of this language. It's designed so that each string appears exactly once.
S := 0 | 1 | 11 | 10 | 110 | 0S | 10S | 110S
Let a_i be the total number of strings of length i in S.
First, look at the number of strings of length 1 on both sides of the grammar rule. There's a_1 in S by definition which deals with the left-hand-side.
a_1 = 2
For a_2, on the right-hand-side we immediately get two strings of length 2 (11 and 10), plus another two from the 0S rule (00 and 01). This gives us:
a_2 = 2 + a_1 = 4
Similarly, for a_3, we get:
a_3 = 1 + a_2 + a_1 = 7
(So far so good, we've got the right solution 7 for the case where the strings are length three).
For i > 3, consider the number of strings of length i on both sides.
a_i = a_{i-1} + a_{i-2} + a_{i-3}
Now we've got a recurrence we can use. A quick check for a_4...
a_4 = a_1 + a_2 + a_3 = 2 + 4 + 7 = 13.
There's 16 strings of length 4 and three containing 111: 1110, 0111, 1111. So 13 looks right!
Here's some code in Python for the general case, using this recurrence.
def strings_without_111(n):
if n == 0: return 1
a = [2, 4, 7]
for _ in xrange(n - 1):
a = [a[1], a[2], a[0] + a[1] + a[2]]
return a[0]
This is a dp problem. I will explain the solution in a way so that it is easy to modify it to count the number of sequences having no sequence a0a1a2 in them(where ai is arbitrary binary value).
I will use 4 helper variables each counting the sequence up to a given length that are valid and end with 00, 01, 10, and 11 respectively. Name those c00, c01, c10, c11. It is pretty obvious that for length N = 2, those numbers are all 1:
int c00 = 1;
int c01 = 1;
int c10 = 1;
int c11 = 1;
Now assuming we have counted the sequences up to a given length k we count the sequences in the four groups for length k + 1 in the following manner:
int new_c00 = c10 + c00;
int new_c01 = c10 + c00;
int new_c10 = c01 + c11;
int new_c11 = c01;
The logic above is pretty simple - if we append a 0 to either a sequence of length k ending at 0 0 or ending at 1 0 we end up with a new sequence of length k + 1 and ending with 0 0 and so on for the other equations above.
Note that c11 is not added to the number of sequences ending with 1 1 and with length k + 1. That is because if we append 1 to a sequence ending with 1 1 we will end up with an invalid sequence( ending at 1 1 1).
Here is a complete solution for your case:
int c00 = 1;
int c01 = 1;
int c10 = 1;
int c11 = 1;
for (int i = 0; i < n - 2; ++i) {
int new_c00 = c10 + c00;
int new_c01 = c10 + c00;
int new_c10 = c01 + c11;
int new_c11 = c01;
c00 = new_c00;
c01 = new_c01;
c10 = new_c10;
c11 = new_c11;
}
// total valid sequences of length n
int result = c00 + c01 + c10 + c11;
cout << result << endl;
Also you will have to take special care for the case when N < 2, because the above solution does not handle that correctly.
To find a number of all possible sequences for N bits are easy. It is 2^N.
To find all sequences contains 111 a bit harder.
Assume N=3 then Count = 1
111
Assume N=4 then Count = 3
0111
1110
1111
Assume N=5 then Count = 8
11100
11101
11110
11111
01110
01111
00111
10111
If you write simple simulation program it yields 1 3 8 20 47 107 ...
Subtract 2^n - count(n) = 2 4 7 13 24 44 81 149...
Google it and it gives OEIS sequence, known as tribonacci numbers. Solved by simple recurrent equation:
a(n) = a(n - 1) + a(n - 2) + a(n - 3)

How to determine if two partitions (clusterings) of data points are identical?

I have n data points in some arbitrary space and I cluster them.
The result of my clustering algorithm is a partition represented by an int vector l of length n assigning each point to a cluster. Values of l ranges from 0 to (possibly) n-1.
Example:
l_1 = [ 1 1 1 0 0 2 6 ]
Is a partition of n=7 points into 4 clusters: first three points are clustered together, the fourth and fifth are together and the last two points forms two distinct singleton clusters.
My question:
Suppose I have two partitions l_1 and l_2 how can I efficiently determine if they represents identical partitions?
Example:
l_2 = [ 2 2 2 9 9 3 1 ]
is identical to l_1 since it represents the same partitions of the points (despite the fact that the "numbers"/"labels" of the clusters are not identical).
On the other hand
l_3 = [ 2 2 2 9 9 3 3 ]
is no longer identical since it groups together the last two points.
I'm looking for a solution in either C++, python or Matlab.
Unwanted direction
A naive approach would be to compare the co-occurrence matrix
c1 = bsxfun( #eq, l_1, l_1' );
c2 = bsxfun( #eq, l_2, l_2' );
l_1_l_2_are_identical = all( c1(:)==c2(:) );
The co-occurrence matrix c1 is of size nxn with true if points k and m are in the same cluster and false otherwise (regardless of the cluster "number"/"label").
Therefore if the co-occurrence matrices c1 and c2 are identical then l_1 and l_2 represent identical partitions.
However, since the number of points, n, might be quite large I would like to avoid O(n^2) solutions...
Any ideas?
Thanks!
When are two partition identical?
Probably if they have the exact same members.
So if you just want to test for identity, you can do the following:
Substitute each partition ID with the smallest object ID in the partition.
Then two partitionings are identical if and only if this representation is identical.
In your example above, lets assume the vector index 1 .. 7 is your object ID. Then I would get the canonical form
[ 1 1 1 4 4 6 7 ]
^ first occurrence at pos 1 of 1 in l_1 / 2 in l_2
^ first occurrence at pos 4
for l_1 and l_2, whereas l_3 canonicalizes to
[ 1 1 1 4 4 6 6 ]
To make it more clear, here is another example:
l_4 = [ A B 0 D 0 B A ]
canonicalizes to
[ 1 2 3 4 3 2 1 ]
since the first occurence of cluster "A" is at position 1, "B" at position 2 etc.
If you want to measure how similar two clusterings are, a good approach is to look at precision/recall/f1 of the object pairs, where the pair (a,b) exists if and only if a and b belong to the same cluster.
Update: Since it was claimed that this is quadratic, I will further clarify.
To produce the canonical form, use the following approach (actual python code):
def canonical_form(li):
""" Note, this implementation overwrites li """
first = dict()
for i in range(len(li)):
v = first.get(li[i])
if v is None:
first[li[i]] = i
v = i
li[i] = v
return li
print canonical_form([ 1, 1, 1, 0, 0, 2, 6 ])
# [0, 0, 0, 3, 3, 5, 6]
print canonical_form([ 2, 2, 2, 9, 9, 3, 1 ])
# [0, 0, 0, 3, 3, 5, 6]
print canonical_form([ 2, 2, 2, 9, 9, 3, 3 ])
# [0, 0, 0, 3, 3, 5, 5]
print canonical_form(['A','B',0,'D',0,'B','A'])
# [0, 1, 2, 3, 2, 1, 0]
print canonical_form([1,1,1,0,0,2,6]) == canonical_form([2,2,2,9,9,3,1])
# True
print canonical_form([1,1,1,0,0,2,6]) == canonical_form([2,2,2,9,9,3,3])
# False
If you are going to relabel your partitions, as has been previously suggested, you will potentially need to search through n labels for each of the n items. I.e. the solutions are O(n^2).
Here is my idea: Scan through both lists simultaneously, maintaining a counter for each partition label in each list.
You will need to be able to map partition labels to counter numbers.
If the counters for each list do not match, then the partitions do not match.
This would be O(n).
Here is a proof of concept in Python:
l_1 = [ 1, 1, 1, 0, 0, 2, 6 ]
l_2 = [ 2, 2, 2, 9, 9, 3, 1 ]
l_3 = [ 2, 2, 2, 9, 9, 3, 3 ]
d1 = dict()
d2 = dict()
c1 = []
c2 = []
# assume lists same length
match = True
for i in range(len(l_1)):
if l_1[i] not in d1:
x1 = len(c1)
d1[l_1[i]] = x1
c1.append(1)
else:
x1 = d1[l_1[i]]
c1[x1] += 1
if l_2[i] not in d2:
x2 = len(c2)
d2[l_2[i]] = x2
c2.append(1)
else:
x2 = d2[l_2[i]]
c2[x2] += 1
if x1 != x2 or c1[x1] != c2[x2]:
match = False
print "match = {}".format(match)
In matlab:
function tf = isIdenticalClust( l_1, l_2 )
%
% checks if partitions l_1 and l_2 are identical or not
%
tf = all( accumarray( {l_1} , l_2 , [],#(x) all( x == x(1) ) ) == 1 ) &&...
all( accumarray( {l_2} , l_1 , [],#(x) all( x == x(1) ) ) == 1 );
What this does:
groups all elements of l_1 according to the partition of l_2 and checks if all elements of l_1 at each cluster are all identical. Repeating the same for partitioning l_2 according to l_1.
If both grouping yields the homogenous clusters - they are identical.

Partitioning arrays by index

I am fairly new to C++, and am struggling through a problem that seems to have a solid solution but I just can't seem to find it. I have a contiguous array of ints starting at zero:
int i[6] = { 0, 1, 2, 3, 4, 5 }; // this is actually from an iterator
I would like to partition the array into groups of three. The design is to have two methods, j and k, such that given an i they will return the other two elements from the same group of three. For example:
i j(i) k(i)
0 1 2
1 0 2
2 0 1
3 4 5
4 3 5
5 3 4
The solution seems to involve summing the i with its value mod three and either plus or minus one, but I can't quite seem to work out the logic.
This should work:
int d = i % 3;
int j = i - d + ( d == 0 );
int k = i - d + 2 - ( d == 2 );
or following statement for k could be more readable:
int k = i - d + ( d == 2 ? 1 : 2 );
This should do it:
int j(int i)
{
int div = i / 3;
if (i%3 != 0)
return 3*div;
else
return 3*div+1;
}
int k(int i)
{
int div = i / 3;
if (i%3 != 2)
return 3*div+2;
else
return 3*div+1;
}
Test.
If you want shorter functions:
int j(int i)
{
return i/3*3 + (i%3 ? 0 : 1);
}
int k(int i)
{
return i/3*3 + (i%3-2 ? 2 : 1);
}
Well, first, notice that
j(i) == j(3+i) == j(6+i) == j(9+i) == ...
k(i) == k(3+i) == k(6+i) == k(9+i) == ...
In other words, you only need to find a formula for
j(i), i = 0, 1, 2
k(i), i = 0, 1, 2
and then for the rest of the cases simply plug in i mod 3.
From there, you'll have trouble finding a simple formula because your "rotation" isn't standard. Instead of
i j(i) k(i)
0 1 2
1 2 0
2 0 1
for which the formula would have been
j(i) = (i + 1) % 3
k(i) = (i + 2) % 3
you have
i j(i) k(i)
0 1 2
1 0 1
2 0 2
for which the only formula I can think of at the moment is
j(i) = (i == 0 ? 1 : 0)
k(i) = (i == 1 ? 1 : 2)
If the values of your array (let's call it arr, not i in order to avoid confusion with the index i) do not coincide with their respective index, you have to perform a reverse lookup to figure out their index first. I propose using an std::map<int,size_t> or an std::unordered_map<int,size_t>.
That structure reflects the inverse of arr and you can extra the index for a particular value with its subscript operator or the at member function. From then, you can operate purely on the indices, and use modulo (%) to access the previous and the next element as suggested in the other answers.

High efficient algorithm for picking up number from array

Here is the problem:
There are 2*N+1 integers in one array, and there are N pair int numbers, i,e, two 1, or two 3 etc,so there is only one int number , which has no pair.
The question is how to find this number with high efficient algorithm.
Thanks for any clues or comments.
Ok, Ok, here's an explanation of my comment. :-/
missingNum = 0
for each value in list
missingNum = missingNum ^ value //^ = xor
next
print(missingNum)
That's a linear algorithm, O(n).
So what's happening here? Say, we have [2,1,3,1,2], for those familiar with XOR operator, know that 1 ^ 1 = 0, 0 ^ 0 = 0, and 1 ^ 0 = 1, 0 ^ 1 = 1 (remember there's no carry)
So essentially, when we XOR a sequence of bits (100110111), and it has even numbers of 1, each will XOR themselves to zero...if the number of 1's are odd, the XOR yields a 1
So in our example, starting from lsb
2 : 0010
1 : 0001
3 : 0011
1 : 0001
2 : 0010
lsb bit: 0 ^ 1 ^ 1 ^ 1 ^ 0 : 1
2nd bit: 1 ^ 0 ^ 1 ^ 0 ^ 1 : 1
3rd bit: 0 ^ 0 ^ 0 ^ 0 ^ 0 : 0
4th bit: 0 ^ 0 ^ 0 ^ 0 ^ 0 : 0
So our missing number is
0011 = 3
You can find more universal answer in this question. If you assume n=2, m=1 you'll get what you want.
But, as st0le said, in your case XOR should be enough.
If I understand the question correctly, you've got an array containing an odd number of integer values, consisting of a number of integers that appear twice plus one integer that appears only once. For example, the array might look like this:
[3, 41, 6, 6, 41]
where 6 and 41 are both repeated and 3 is unique.
It would be good to know if there are any other constraints. For example:
Is the array sorted? (If so, this is a simple problem to solve in O(N) time with no requirement for temporary storage.)
Can the unpaired integer be the same as an integer in a pair? e.g. is [1, 2, 2, 2, 1] a valid input, being a pair of 1s, a pair of 2s and an unpaired 2?
Assuming the array isn't sorted, here's one solution, expressed in pseudocode, which runs in O(N) time and requires at most around half the storage space again of the original array.
SEEN = []
for N in ARRAY:
if N in SEEN:
remove N from SEEN
else:
add N to SEEN
if size of SEEN != 1:
error - ARRAY doesn't contain exactly 1 un-paired value
else:
answer = SEEN[0]
Here's a sample implementation using an NSMutableDictionary to store seen values, assuming that the source array is a plain C array.
#import <Foundation/Foundation.h>
int main(int argc, char argv[]) {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
int array[9] = {3, 4, 5, 6, 7, 6, 5, 4, 3};
NSMutableDictionary *d = [NSMutableDictionary dictionaryWithCapacity:16];
for (int i = 0; i < sizeof(array)/sizeof(int); i++) {
NSNumber *num = [NSNumber numberWithInt:array[i]];
if ([d objectForKey:num]) {
[d removeObjectForKey:num];
} else {
[d setObject:[NSNull null] forKey:num];
}
}
if ([d count] == 1) {
NSLog(#"Unpaired number: %i", [[[d keyEnumerator] nextObject] intValue]);
} else {
NSLog(#"Error: Expected 1 unpaired number, found %u", [d count]);
}
[pool release];
return 1;
}
And here it is running:
$ gcc -lobjc -framework Foundation -std=c99 demo.m ; ./a.out
2010-12-25 11:23:21.426 a.out[17544:903] Unpaired number: 7