This one has me baffled. I was implementing the Dutch national flag problem in C++. I forgot to pass my array by reference initially, but was displaying the array at every step, which helped me conclude that my algorithm worked fine. To fix the minute error of the vector not getting partitioned finally, I changed the function definition to pass vector as reference, which somehow produced an error.
I have never encountered something like this before. The code isn't recursive, and so while the function is running it shouldn't matter whether it is running on a copy of the vector or is running on the actual vector.
Here is the code:
#include<iostream>
#include<vector>
#include<algorithm>
#include<iomanip>
using namespace std;
void optArr(vector<int> arr){
for(auto i: arr){
cout<<setw(3)<<i<<" ";
}
cout<<endl;
}
void _partition(vector<int> arr, int lo, int hi, int &i, int &k){ //Vector passed by value
i=lo-1, k=hi+1;
int ptr=lo, pivot=arr[hi];
while(ptr<k){
optArr(arr);
cout<<"i: "<<i<<" ptr: "<<ptr<<" k: "<<k<<endl;
if(arr[ptr]<pivot){
swap(arr[++i],arr[ptr++]);
}else if(arr[ptr] == arr[pivot]){
ptr++;
}else{
swap(arr[--k],arr[ptr]);
}
}
}
int main(){
vector<int> arr = {57,22,85,17,11,04,17,93,1,17,25,17};
int i,k;
_partition(arr, 0, arr.size()-1, i, k);
optArr(arr);
cout<<"i: "<<i<<" ptr: "<<0<<" k: "<<k<<endl;
return 0;
}
And the output when vector is passed by value:
57 22 85 17 11 4 17 93 1 17 25 17
i: -1 ptr: 0 k: 12
17 22 85 17 11 4 17 93 1 17 25 57
i: -1 ptr: 0 k: 11
17 22 85 17 11 4 17 93 1 17 25 57
i: -1 ptr: 1 k: 11
17 25 85 17 11 4 17 93 1 17 22 57
i: -1 ptr: 1 k: 10
17 17 85 17 11 4 17 93 1 25 22 57
i: -1 ptr: 1 k: 9
17 17 85 17 11 4 17 93 1 25 22 57
i: -1 ptr: 2 k: 9
17 17 1 17 11 4 17 93 85 25 22 57
i: -1 ptr: 2 k: 8
1 17 17 17 11 4 17 93 85 25 22 57
i: 0 ptr: 3 k: 8
1 17 17 17 11 4 17 93 85 25 22 57
i: 0 ptr: 4 k: 8
1 11 17 17 17 4 17 93 85 25 22 57
i: 1 ptr: 5 k: 8
1 11 4 17 17 17 17 93 85 25 22 57
i: 2 ptr: 6 k: 8
1 11 4 17 17 17 17 93 85 25 22 57
i: 2 ptr: 7 k: 8
57 22 85 17 11 4 17 93 1 17 25 17
i: 2 ptr: 0 k: 7
You can see that the output is correct, right up to the last one, which is called through the main function. When I saw this, I decided to pass the vector by reference by modifying the _partition signature to: void _partition(vector<int> &arr, int lo, int hi, int &i, int &k)
This produced the following output:
57 22 85 17 11 4 17 93 1 17 25 17
i: -1 ptr: 0 k: 12
17 22 85 17 11 4 17 93 1 17 25 57
i: -1 ptr: 0 k: 11
25 22 85 17 11 4 17 93 1 17 17 57
i: -1 ptr: 0 k: 10
17 22 85 17 11 4 17 93 1 25 17 57
i: -1 ptr: 0 k: 9
1 22 85 17 11 4 17 93 17 25 17 57
i: -1 ptr: 0 k: 8
1 22 85 17 11 4 17 93 17 25 17 57
i: 0 ptr: 1 k: 8
1 93 85 17 11 4 17 22 17 25 17 57
i: 0 ptr: 1 k: 7
1 17 85 17 11 4 93 22 17 25 17 57
i: 0 ptr: 1 k: 6
1 4 85 17 11 17 93 22 17 25 17 57
i: 0 ptr: 1 k: 5
1 4 85 17 11 17 93 22 17 25 17 57
i: 1 ptr: 2 k: 5
1 4 11 17 85 17 93 22 17 25 17 57
i: 1 ptr: 2 k: 4
1 4 11 17 85 17 93 22 17 25 17 57
i: 2 ptr: 3 k: 4
1 4 11 17 85 17 93 22 17 25 17 57
i: 2 ptr: 0 k: 3
As you can see, this behaves abnormally right from the third line of output. I apologize for such a vague question, but I have no idea how else to go about looking for a solution to such an unusual problem.
In your example, pivot == 17 and arr[pivot] exhibits undefined behavior by way of accessing an index out of bounds.
Related
I am trying to produce a square-formatted multiplication table with the output at the end using code below:
def multiplicationTable(maxValue):
for i in range(1, maxvalue):
for j in range(1, maxvalue):
print(("{:6d}".format(i * j,)), end='')
print()
print(multiplicationTable(1)
print(multiplicationTable(5))
print(multiplicationTable(10))
1
1 2 3 4 5
2 4 6 8 10
3 6 9 12 15
4 8 12 16 20
5 10 15 20 25
1 2 3 4 5 6 7 8 9 10
2 4 6 8 10 12 14 16 18 20
3 6 9 12 15 18 21 24 27 30
4 8 12 16 20 24 28 32 36 40
5 10 15 20 25 30 35 40 45 50
6 12 18 24 30 36 42 48 54 60
7 14 21 28 35 42 49 56 63 70
8 16 24 32 40 48 56 64 72 80
9 18 27 36 45 54 63 72 81 90
10 20 30 40 50 60 70 80 90 100
I get an error:
File "", line 7
print(multiplicationTable(5))
^
SyntaxError: invalid syntax
print(multiplicationTable(1) is missing a closing ).
You are using maxValue (with capital V) in your function definition while using maxvalue (with small v) in the function body.
Here is the new version:
def multiplicationTable(maxvalue): # maxvalue, not maxValue
for i in range(1, maxvalue+1):
for j in range(1, maxvalue+1):
print(("{:6d}".format(i * j,)), end='')
print()
multiplicationTable(1)
multiplicationTable(5)
multiplicationTable(10)
EDIT 1: Changed range(1, maxvalue) to range(1, maxvalue+1)
EDIT 2: Changed print(multiplicationTable(n)) to multiplicationTable(n)
I have a matrix of floating point values. Relative to a given origin (x and y index, point "0"), I would like to obtain the indices of equidistant points, starting with the nearest points ("1") and up to a specific number ("12" in this animated example):
The distance is the slant range between a point and point 0. For example, point "4" has the distance sqrt(2^2+1^2) = sqrt(5) = 2.24.
Does anyone know a corresponding algorithm to obtain these indices in an effective way?
Rephrasing the question, you want to enumerate the points by increasing euclidean distance to the center.
Here are two answers on https://math.stackexchange.com to this problem how-to-enumerate-2d-integer-coordinates-ordered-by-euclidean-distance and algorithm-for-enumerating-grid-points-by-distance-from-given-point
Basically:
use symmetry to consider only point with 0 <= x <= y;
note that for a given x points will be enumerated with increasing y;
use a priority queue to keep the next candidate for each vertical line.
With n the last index you generate, the time complexity will be O(n log n) and the space complexity O(sqrt(n)).
NB: to avoid floating point computation, consider the squared distance, which doesn't change the order of your points.
Here some python code implementing this idea:
import heapq
def yield_all_quadrant(x, y):
s = set([(x, y), (-x, y), (x, -y), (-x, -y),
(y, x), (-y, x), (y, -x), (-y, -x)])
for u, v in sorted(s):
yield u, v
def indices(X, Y):
q = [(0, 0, 0)]
d_current = 0
index = 0
while True:
d, x, y = heapq.heappop(q)
if d > d_current:
index += 1
d_current = d
for u, v in yield_all_quadrant(x, y):
yield (X + u,Y + v), index
if not y:
heapq.heappush(q, (d + 2*x + 1, (x+1), 0))
if y < x:
heapq.heappush(q, (d + 2*y + 1, x, y+1))
and used for example in a small function to fill a grid
import itertools
def fill_grid(size, center):
grid = [[0]*size for _ in range(size)]
def clip(e):
coord, index = e
return all(0 <= c < size for c in coord)
for (x,y), i in itertools.islice(filter(clip, indices(*center)), 0, size**2):
grid[x][y] = i
return grid
and the result
print('\n'.join(' '.join('%2d'%i for i in gi) for gi in fill_grid(20, (8,8))))
54 48 43 39 35 33 31 30 29 30 31 33 35 39 43 48 54 59 67 74
48 42 38 34 30 27 26 24 23 24 26 27 30 34 38 42 48 55 62 69
43 38 32 28 25 22 20 19 18 19 20 22 25 28 32 38 43 50 56 64
39 34 28 24 21 17 15 14 13 14 15 17 21 24 28 34 39 46 53 60
35 30 25 21 16 13 12 10 9 10 12 13 16 21 25 30 35 41 49 57
33 27 22 17 13 11 8 7 6 7 8 11 13 17 22 27 33 40 47 55
31 26 20 15 12 8 5 4 3 4 5 8 12 15 20 26 31 38 45 53
30 24 19 14 10 7 4 2 1 2 4 7 10 14 19 24 30 37 44 52
29 23 18 13 9 6 3 1 0 1 3 6 9 13 18 23 29 36 43 51
30 24 19 14 10 7 4 2 1 2 4 7 10 14 19 24 30 37 44 52
31 26 20 15 12 8 5 4 3 4 5 8 12 15 20 26 31 38 45 53
33 27 22 17 13 11 8 7 6 7 8 11 13 17 22 27 33 40 47 55
35 30 25 21 16 13 12 10 9 10 12 13 16 21 25 30 35 41 49 57
39 34 28 24 21 17 15 14 13 14 15 17 21 24 28 34 39 46 53 60
43 38 32 28 25 22 20 19 18 19 20 22 25 28 32 38 43 50 56 64
48 42 38 34 30 27 26 24 23 24 26 27 30 34 38 42 48 55 62 69
54 48 43 39 35 33 31 30 29 30 31 33 35 39 43 48 54 59 67 74
59 55 50 46 41 40 38 37 36 37 38 40 41 46 50 55 59 66 73 80
67 62 56 53 49 47 45 44 43 44 45 47 49 53 56 62 67 73 79 85
74 69 64 60 57 55 53 52 51 52 53 55 57 60 64 69 74 80 85 93
// L is a list and n is its length //
// we assume that n= 4**k , for k≥1//
Alg1(L,n)
remove the smallest and largest element from L
if n-2 > (4**k)/2
call Alg1(L, n-2)
Not what it does but what is it intended to do? I don't understand what the question means by "intended" but I think the algorithm just removes the largest and smallest element of the list recursively until 4 or 3 elements remain.
Given a starting list of size 4^k, which appears to be implied by the definition given for n, alg1 reduces the size of the supplied list to ((4^k) / 2) + 2 for k >= 1. I agree with #Ctznkane525 that the algorithm is incompletely specified in that it doesn't tell us what the return value should be. But if we make the simple assumption that two elements should be removed from the end of the list each time n is decremented by 2 we can continue. Thus, consider the following implementation in Clojure:
(defn exp [x n]
(reduce * (repeat n x)))
(def k 1)
(defn alg1[l n]
(println "k=" k " n=" n " l=" l)
(if (> (- n 2) (/ (exp 4 k) 2))
(recur (take (- n 2) l) (- n 2))
l))
I've added code here to print the values of k, n, and l so we can watch what happens at each step.
Given the above we'll start a little testing. We'll invoke alg1 as (alg1 (take (exp 4 k) (iterate #(+ 1 %) 1)) (exp 4 k)), which simply creates a list of 4^k elements and passes it as the first argument to alg1, and passes 4^k for the second argument. So here goes:
user=> (def k 1)
#'user/k
user=> (alg1 (take (exp 4 k) (iterate #(+ 1 %) 1)) (exp 4 k))
k= 1 n= 4 l= (1 2 3 4)
(1 2 3 4)
So with k=1 and the list defined as (1 2 3 4) the function returns immediately, because n-2 = 2, and that's less than or equal to (4^k)/2, which is also 2.
Let's try with k=2:
user=> (def k 2)
#'user/k
user=> (alg1 (take (exp 4 k) (iterate #(+ 1 %) 1)) (exp 4 k))
k= 2 n= 16 l= (1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16)
k= 2 n= 14 l= (1 2 3 4 5 6 7 8 9 10 11 12 13 14)
k= 2 n= 12 l= (1 2 3 4 5 6 7 8 9 10 11 12)
k= 2 n= 10 l= (1 2 3 4 5 6 7 8 9 10)
(1 2 3 4 5 6 7 8 9 10)
Ah, that's a bit more interesting. We start with n=16, which is of course 4^k = 4^2 = 16, and the beginning list is (1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16). When these values are considered by alg1 it finds that n-2 (14) is greater than (4^2)/2 (8), so it trims two elements from the end of the list and recursively invokes itself. On the second iteration it finds that n-2 (12) is greater than 8 so it trims another two elements and recursively invokes itself. This continues until n=10, when alg1 finds that n-2 (8) is no longer greater than (4^2)/2 (8), so it returns the list (1 2 3 4 5 6 7 8 9 10).
What happens with k=3?
user=> (def k 3)
#'user/k
user=> (alg1 (take (exp 4 k) (iterate #(+ 1 %) 1)) (exp 4 k))
k= 3 n= 64 l= (1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64)
k= 3 n= 62 l= (1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62)
k= 3 n= 60 l= (1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60)
k= 3 n= 58 l= (1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58)
k= 3 n= 56 l= (1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56)
k= 3 n= 54 l= (1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54)
k= 3 n= 52 l= (1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52)
k= 3 n= 50 l= (1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50)
k= 3 n= 48 l= (1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48)
k= 3 n= 46 l= (1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46)
k= 3 n= 44 l= (1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44)
k= 3 n= 42 l= (1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42)
k= 3 n= 40 l= (1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40)
k= 3 n= 38 l= (1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38)
k= 3 n= 36 l= (1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36)
k= 3 n= 34 l= (1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34)
(1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34)
Similar results to the above. At each iteration two elements are trimmed from the list until the condition specified in the algorithm is reached, at which point the algorithm exits.
You can continue bumping up the value of k, building the arguments, and watching the algorithm work, but in the end the results are always similar: the list is reduced in size to ((4^k) / 2) + 2.
Best of luck.
If there are more than two same elements in Quicksort and pivot is also the same number...How can we sort it?
Eg: 23,19,45,21,90,5,93,45,31,45
In this array consider 45
Using Hoare like partition scheme, 45 as pivot, start with
0 1 2 3 4 5 6 7 8 9 indices
23 19 45 21 90 5 93 45 31 45 data
scan from left for >= pivot, scan from right for <= pivot
ll rr
23 19 45 21 90 5 93 45 31 45
23 19 45 21 90 5 93 45 31 45 swap (both are 45, so no change)
ll rr
23 19 45 21 90 5 93 45 31 45
23 19 45 21 31 5 93 45 90 45 swap
ll rr
23 19 45 21 31 5 93 45 90 45
23 19 45 21 31 5 45 93 90 45 swap
rr ll
23 19 45 21 31 5 45 93 90 45 rr and ll crossed, rr = 6
The next two calls will be quicksort(0,6), quicksort(7, 9)
How can we sort quicksort(7,9) ?
0 1 2 3 4 5 6 7 8 9 indices
93 90 45 again assume pivot is 45
ll rr
93 90 45
45 90 93 swap
rr ll
45 90 93 rr and ll crossed, rr = 7
The next two calls will be quicksort(7,7), quicksort(8, 9)
91
58
54
108
52
18
8
81
103
110
129
137
84
15
14
18
11
17
12
6
1
28
6
14
8
8
0
0
28
24
25
23
21
13
9
4
18
17
18
30
13
3
I want to split into chunks of six entries each.After that it will break the loop.Then it will continue the entries 7..12, then of 13..18 etc.
(for loop?continue?break?)
You can use paste:
paste -d' ' - - - - - - < inputfile
For your input, it'd return:
91 58 54 108 52 18
8 81 103 110 129 137
84 15 14 18 11 17
12 6 1 28 6 14
8 8 0 0 28 24
25 23 21 13 9 4
18 17 18 30 13 3
$ xargs -n 6 < file_name
91 58 54 108 52 18
8 81 103 110 129 137
84 15 14 18 11 17
12 6 1 28 6 14
8 8 0 0 28 24
25 23 21 13 9 4
18 17 18 30 13 3