boost::multi_index insertion function for "other" indices - c++

Here is a container of ints with a hashed index and a sequence index:
#include <iostream>
#include <boost/multi_index_container.hpp>
#include <boost/multi_index/hashed_index.hpp>
#include <boost/multi_index/identity.hpp>
#include <boost/multi_index/sequenced_index.hpp>
int main()
{
boost::multi_index_container<
int,
boost::multi_index::indexed_by<
boost::multi_index::hashed_unique<boost::multi_index::identity<int>>,
boost::multi_index::sequenced<>
>
> c;
for (int i=99; i>=0; --i) c.get<0>().insert(i);
for (int j : c.get<0>()) std::cout << " " << j;
std::cout << std::endl;
for (int k : c.get<1>()) std::cout << " " << k;
std::cout << std::endl;
return 0;
}
When I run this I get:
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 99 98 97 96 95 94 93 92 91 90 89 88 87 86 85 84 83 82 81 80 79 78 77 76 75 74 73 72 71 70 69 68 67 66 65 64 63 62 61 60 59 58 57 56 55 54 53 52 51 50 49 48 47 2 1 0
99 98 97 96 95 94 93 92 91 90 89 88 87 86 85 84 83 82 81 80 79 78 77 76 75 74 73 72 71 70 69 68 67 66 65 64 63 62 61 60 59 58 57 56 55 54 53 52 51 50 49 48 47 46 45 44 43 42 41 40 39 38 37 36 35 34 33 32 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
The first line shows the elements are "scattered" via the hash index, as expected. The second line shows the elements are in insertion order via the sequenced index. But the elements were inserted via the hash index; what can we expect for the elements of the sequenced index? That is, when insert is called for one index, are the insertion functions used for "other" indices defined?
Specifically: When a multi-index container has a hashed index and a sequenced index, and elements are only inserted via the hashed index, will the elements always be in insertion order via the ordered index?

As for sequenced indices, docs say:
Elements in a sequenced index are by default sorted according to their order of insertion: this means that new elements inserted through a different index of the multi_index_container are appended to the end of the sequenced index.

Related

How to find the shortest path between two vertices in a BGL graph?

So I'm currently working on a project of a word ladder problem and I have already built the graph for storing all dictionary words in it and added the edges in it, I did this using boost graph library.
But what is confusing me is that breadth_first_search() function, seems like the parameters only take the starting vertex but no ending vertex.
I checked the documentations and noticed that I can define the BFS visitor for that search function, but since I'm a newbie to the boost library I could not figure out how it works.
Can anybody explain how to implement finding the shortest path between two vertices? I'm using an undirected and unweighted graph.
#include <iostream> // std::cout
#include <fstream>
#include <string>
#include <stdlib.h>
#include <utility> // std::pair
#include "headers.h"
#include <boost/graph/adjacency_list.hpp>
#include <boost/graph/dijkstra_shortest_paths.hpp>
#include <boost/graph/graph_utility.hpp>
using namespace std;
//Define a class that has the data you want to associate to every vertex and
edge
//struct Vertex{ int foo;}
// struct Edge{std::string blah;}
struct VertexProperties {
string name;
VertexProperties(string name) : name(name) {}
};
//typedef property<edge_weight_t, int> EdgeWeightProperty;
//typedef property<vertex_name_t, string> VertexNameProperty;
//Define the graph using those classes
typedef boost::adjacency_list<boost::setS, boost::listS, boost::undirectedS,
VertexProperties> Graph;
typedef Graph::vertex_iterator Vit;
typedef Graph::vertex_descriptor Vde;
typedef Graph::edge_descriptor E;
typedef boost::graph_traits<Graph>::adjacency_iterator adjacency_it;
struct my_visitor : boost::default_dijkstra_visitor {
using base = boost::default_dijkstra_visitor;
struct done{};
my_visitor(Vde vd, size_t& visited) : destination(vd), visited(visited) {}
void finish_vertex(Vde v, Graph const& g) {
++visited;
if (v == destination)
throw done{};
base::finish_vertex(v, g);
}
private:
Vde destination;
size_t &visited;
};
//Some typedefs for simplicity
//typedef boost::graph_traits<Graph>::vertex_descriptor vertex_t;
//typedef boost::graph_traits<Graph>::edge_descriptor edge_t;
int main()
{
ifstream dictionary("dictionary.txt");
string word;
Graph allWords;
//Vit begin,end;
if(dictionary.is_open())
{
while(getline(dictionary,word))
{
word.pop_back();
add_vertex(VertexProperties(word),allWords);
}
}
else
cout<<"File openning failed."<<endl;
dictionary.close();
//cout<<num_vertices(allWords)<<endl;
Vit begin,end;
boost::tie(begin, end) = vertices(allWords);
vector<Graph::vertex_descriptor> vindex(begin, end);
int first=0;
int second=0;
for(Vit it=begin;it!=end;it++)
{
for(Vit that=it;that!=end;that++)
{
if(isEditDistanceOne(allWords[*it].name,allWords[*that].name))
add_edge(vindex[first],vindex[second],allWords);
second++;
}
first++;
second=first;
cout<<first<<endl;
}
//Vit temp=begin;
//temp++;
//cout<<allWords[*begin].name<<"////////////////"<<endl;
adjacency_it neighbour, neighbour_end;
for (tie(neighbour, neighbour_end) = adjacent_vertices(*begin, allWords);
neighbour != neighbour_end; ++neighbour)
cout<<allWords[*neighbour].name<<endl;
string firstWord;
string secondWord;
int firstIndex=-1;
int secondIndex=-1;
cout<<"Enter first word:"<<endl;
cin>>firstWord;
cout<<"Enter second word:"<<endl;
cin>>secondWord;
Vit a=begin;
for(int i=0;i<num_vertices(allWords);i++)
{
if(allWords[*a].name==firstWord)
{
firstIndex=i;
break;
}
a++;
}
Vit b=begin;
for(int i=0;i<num_vertices(allWords);i++)
{
if(allWords[*b].name==secondWord)
{
secondIndex=i;
break;
}
b++;
}
if(firstIndex==-1)
cout<<"First word not in graph."<<endl;
else if(secondIndex==-1)
cout<<"Second word not in graph."<<endl;
else
{
Vde start_vertex=vindex[firstIndex];
Vde end_vertex=vindex[secondIndex];
size_t visited;
std::vector<boost::default_color_type> colors(num_vertices(allWords),
boost::default_color_type{});
std::vector<Vde> _pred(num_vertices(allWords),
allWords.null_vertex());
std::vector<size_t> _dist(num_vertices(allWords),
-1ull);
my_visitor vis { end_vertex, visited };
auto predmap = _pred.data(); // interior properties:
boost::get(boost::vertex_predecessor, g);
auto distmap = _dist.data(); // interior properties:
boost::get(boost::vertex_distance, g);
try {
std::cout << "Searching from #" << start_vertex << " to #" << end_vertex
<<
"...\n";
boost::dijkstra_shortest_paths(allWords, start_vertex,
boost::visitor(vis).
color_map(colors.data()).
distance_map(distmap).
predecessor_map(predmap).
weight_map(boost::make_constant_property<E>(1ul))
);
std::cout << "No path found\n";
return 0;
} catch(my_visitor::done const&) {
std::cout << "Percentage skipped: " <<
(100.0*visited/num_vertices(allWords)) << "%\n";
}
}
//cout<<adjacency_list[*begin]<<"\t";
return 0;
}
Just abort the search when you discover your target.
Here's a working sample
Live On Coliru
#include <boost/graph/adjacency_list.hpp>
#include <boost/graph/graph_utility.hpp>
#include <boost/graph/dijkstra_shortest_paths.hpp>
#include <boost/graph/random.hpp>
#include <random>
#include <iostream>
using G = boost::adjacency_list<boost::vecS, boost::vecS, boost::undirectedS>;
using V = G::vertex_descriptor;
using E = G::edge_descriptor;
struct my_visitor : boost::default_dijkstra_visitor {
using base = boost::default_dijkstra_visitor;
struct done{};
my_visitor(V vd, size_t& visited) : destination(vd), visited(visited) {}
void finish_vertex(V v, G const& g) {
++visited;
if (v == destination)
throw done{};
base::finish_vertex(v, g);
}
private:
V destination;
size_t &visited;
};
int main() {
#if 1
auto seed = 2912287549; // fixed seed for demo
#else
auto seed = std::random_device{}();
std::cout << "SEED: " << seed << "\n";
#endif
std::mt19937 prng { seed };
G g;
generate_random_graph(g, 100, 400, prng);
print_graph(g);
V start_vertex = prng()%num_vertices(g);
V end_vertex = prng()%num_vertices(g);
size_t visited;
std::vector<boost::default_color_type> colors(num_vertices(g), boost::default_color_type{});
std::vector<V> _pred(num_vertices(g), g.null_vertex());
std::vector<size_t> _dist(num_vertices(g), -1ull);
my_visitor vis { end_vertex, visited };
auto predmap = _pred.data(); // interior properties: boost::get(boost::vertex_predecessor, g);
auto distmap = _dist.data(); // interior properties: boost::get(boost::vertex_distance, g);
try {
std::cout << "Searching from #" << start_vertex << " to #" << end_vertex << "...\n";
boost::dijkstra_shortest_paths(g, start_vertex,
boost::visitor(vis).
color_map(colors.data()).
distance_map(distmap).
predecessor_map(predmap).
weight_map(boost::make_constant_property<E>(1ul))
);
std::cout << "No path found\n";
return 0;
} catch(my_visitor::done const&) {
std::cout << "Percentage skipped: " << (100.0*visited/num_vertices(g)) << "%\n";
}
size_t distance = distmap[end_vertex];
std::cout << "Distance from #" << start_vertex << " to #" << end_vertex << ": " << distance << "\n";
if (distance != size_t(-1)) {
std::deque<V> path;
for (V current = end_vertex;
current != g.null_vertex()
&& predmap[current] != current
&& current != start_vertex;)
{
path.push_front(predmap[current]);
current = predmap[current];
}
std::cout << "Path from #" << start_vertex << " to #" << end_vertex << ": ";
std::copy(path.begin(), path.end(), std::ostream_iterator<V>(std::cout, ", "));
std::cout << end_vertex << "\n";
}
}
It generates random undirected graphs with 100 vertices and 400 edges.
For the specific demo seed it prints the following output:
0 <--> 45 46 15 83 69 32 38 68 37
1 <--> 29 52 99 85 10 19 30 78
2 <--> 42 7 35 80 25 9 23 23
3 <--> 29 9 15 77 7 58 42
4 <--> 75 56 98 24 14 40 97 34 84 37 80 30 62
5 <--> 58 46 80 71
6 <--> 89 12 47 88 80
7 <--> 62 69 2 86 88 74 8 33 13 76 3 9 86 48
8 <--> 64 26 31 7 94 95 77
9 <--> 83 53 76 3 43 55 7 2 67 72
10 <--> 51 16 21 20 1 63 31
11 <--> 38 50 19 88 16 52
12 <--> 46 6 85 21 61 39
13 <--> 95 24 17 51 7
14 <--> 24 4 43 53
15 <--> 0 51 70 3 43 34
16 <--> 72 10 23 99 28 35 22 11 96 99 19 38 39
17 <--> 84 25 13 54 74 96 28
18 <--> 90 54 88 78
19 <--> 63 11 61 20 73 22 1 63 90 75 16
20 <--> 70 57 79 35 19 10 65 79 45
21 <--> 49 89 43 50 10 38 12 26 67
22 <--> 41 49 95 99 25 39 23 16 19 81
23 <--> 35 16 22 95 2 69 2
24 <--> 76 85 13 42 14 4 85 88
25 <--> 98 17 22 72 92 60 2 51
26 <--> 65 48 62 8 50 86 44 37 21 48
27 <--> 42 82
28 <--> 92 46 89 16 50 53 59 17 94
29 <--> 1 33 3 46 91 96 46 48
30 <--> 60 96 70 79 1 48 4
31 <--> 37 66 50 8 59 72 32 87 10 67
32 <--> 84 77 49 71 0 31 81 75 98 66
33 <--> 29 83 66 7 69 74 80 79
34 <--> 90 59 73 61 47 4 75 87 15
35 <--> 51 23 46 20 16 2 68
36 <--> 70
37 <--> 31 41 77 68 70 26 70 4 0 60
38 <--> 11 65 74 0 21 39 50 94 16 86
39 <--> 48 88 38 22 12 89 16
40 <--> 81 92 86 4 55
41 <--> 22 37 74 64 63 63 79
42 <--> 27 2 24 84 90 65 67 76 72 93 3
43 <--> 51 75 21 54 9 65 14 53 44 15
44 <--> 74 82 26 43
45 <--> 0 86 70 46 94 89 20
46 <--> 0 12 28 35 45 96 5 29 29
47 <--> 96 51 6 82 62 34 88 78
48 <--> 26 99 39 50 59 78 30 29 7 26
49 <--> 21 22 52 32 99 61 55 69 66 57
50 <--> 82 11 31 21 26 65 28 48 38 94 55
51 <--> 43 35 10 47 15 55 13 55 88 25 69 84
52 <--> 86 49 66 1 93 55 11 74 90
53 <--> 89 76 9 76 82 28 77 43 14
54 <--> 87 43 17 98 59 18 66
55 <--> 68 76 51 65 51 81 52 9 49 92 50 40
56 <--> 4 82 95 88 80
57 <--> 20 87 66 62 49
58 <--> 5 3
59 <--> 34 75 71 28 31 48 54 70 96
60 <--> 81 30 81 87 61 61 25 37
61 <--> 78 62 97 19 49 34 12 60 60
62 <--> 7 26 69 87 61 70 92 57 47 90 4
63 <--> 19 41 41 10 72 19
64 <--> 8 92 41 95 86
65 <--> 26 38 50 42 55 43 83 79 20 79
66 <--> 52 31 33 57 87 54 32 49
67 <--> 97 42 98 9 31 21
68 <--> 55 74 96 37 0 98 35
69 <--> 7 97 62 0 97 33 70 49 75 51 23
70 <--> 20 83 45 78 15 69 30 37 62 37 59 78 77 36
71 <--> 83 74 59 32 5 88
72 <--> 16 74 31 25 85 83 42 63 9
73 <--> 74 34 87 19
74 <--> 68 73 41 44 72 71 7 38 17 96 33 82 52
75 <--> 4 43 59 86 32 34 19 69 85
76 <--> 24 53 55 53 9 42 7
77 <--> 32 37 79 53 3 70 96 90 8
78 <--> 61 70 70 48 1 18 47
79 <--> 20 77 41 30 98 65 20 33 65 82
80 <--> 82 81 86 93 56 5 33 2 6 4
81 <--> 40 60 60 80 91 55 32 22
82 <--> 80 50 44 56 88 53 47 27 74 79
83 <--> 9 70 71 0 33 95 72 65
84 <--> 32 17 42 86 4 51
85 <--> 24 96 12 87 24 1 72 89 87 75
86 <--> 52 45 40 7 84 26 75 80 7 64 38
87 <--> 54 57 73 85 62 60 66 31 85 34
88 <--> 7 39 82 56 11 6 51 24 18 47 71
89 <--> 53 21 6 28 99 92 45 85 39
90 <--> 34 42 96 18 77 19 62 52
91 <--> 81 29
92 <--> 28 40 64 62 25 89 55
93 <--> 52 80 42
94 <--> 8 45 50 28 38
95 <--> 22 13 83 56 23 64 8
96 <--> 85 47 30 68 46 90 74 17 16 77 29 59
97 <--> 69 67 61 69 4
98 <--> 25 4 54 79 68 67 32
99 <--> 22 48 16 89 1 49 16
Searching from #20 to #27...
Percentage skipped: 91%
Distance from #20 to #27: 3
Path from #20 to #27: 20, 65, 42, 27
As you can see, 91% of nodes weren't visited.
Notes
The docs say to use breadth-first search when the edge weight is constant. I couldn't make that work sadly.
Assuming that algorithmic equivalence is asserted, the paths will still be shortest using the early-out (assuming that the edge weight is constant).

call and print function which return array in c++

I have this functions which return a random array in c++:
int* randomArray(int countOfRows){
int test1 [countOfRows] = {};
int insertValue;
int check;
for (int n=0; n < countOfRows; ++n){
srand(time (NULL) );
while (test1[n] == NULL){
insertValue = (rand () %100 + 1 );
for(int i = 0; i < countOfRows; i++){
if (test1[i] == insertValue){
check = 1;
break;
}
else{
check = 0;
}
}
if (check == 0){
test1[n] = insertValue;
}
}
}
return test1;
}
How can I call that array?
what is the difference between int* and int[]
thank you :)
Your code has four significant problems, one of them critical, one non-standard and implementation dependent, and two general algorithmic problems.
First, the most important, you're returning the address of an automatic variable, which means it is both useless and will invoke undefined behavior to dereference by the caller. Declared at the top of your function is:
int test1 [countOfRows] = {};
which itself brings up the second point, this non-standard for two reasons: variable-length arrays are not supported by the C++ standard, and by inference, initialization of said-same is likewise not supported. Then later...
return test1;
The caller of your function will receive an address, but that address is useless. It no longer addresses anything concrete, as test1 no longer exists once the function returns. This is remedied a number of ways, and considering this is C++, the easiest is using a std::vector<int>, which supports value-return.
The two significant algorithm problems are
Your seeding of srand should not be in the for loop. In fact, if you're using srand and rand, the seeding should be done once in your entire process.
The process of exhaustive searching to see if a current random pick has already been used to avoid duplicates is needless if you simply use a different algorithm, which I'll cover later.
Therefore, the simplest fix for your code will be to do this:
#include <iostream>
#include <vector>
#include <cstdlib>
#include <ctime>
std::vector<int> randomArray(int countOfRows)
{
std::vector<int> test1(countOfRows);
int check = 0;
for (int n=0; n < countOfRows; ++n)
{
while (test1[n] == 0)
{
int insertValue = (rand () %100 + 1 );
for(int i = 0; i < countOfRows; i++)
{
if (test1[i] == insertValue){
check = 1;
break;
}
else{
check = 0;
}
}
if (check == 0){
test1[n] = insertValue;
}
}
}
return test1;
}
int main()
{
std::srand(static_cast<unsigned>(std::time(NULL)));
std::vector<int> vec = randomArray(20);
for (auto x : vec)
std::cout << x << ' ';
std::cout.put('\n');
}
Output (varies, obviously)
8 50 74 59 31 73 45 79 24 10 41 66 93 43 88 4 28 30 13 70
A Finite Set Algorithm
What you're really trying to generate here is a finite set of integers in the range of 1..100. I.e., there are no duplicate values used, and the number of items being returned could be anything from 1..100 as well. To do this, consider this algorithm:
Generate a sequence of 1..100 in a std::vector<int>
Using a pseudorandom generator from the standard library, shuffle the sequence using std::shuffle
Resize the resulting vector to be the number of elements you want to return.
Regarding #3 from above, consider a small example, suppose you wanted just ten elements. Initially you build a sequence vector that looks like this:
1 2 3 4 5 6 7 8 9 10 11 12 13... ...99 100
Now you shuffle this vector using a std::shuffle and a pseudorandom generator like std::mt19937 : (the first twenty elements shown for brevity):
48 39 31 44 68 84 98 40 57 76 70 16 30 93 9 51 63 65 45 81...
Now, you simply resize the vector down to the size you want, in this case ten elements:
48 39 31 44 68 84 98 40 57
And that is your result. If this sounds complicated, you may be surprised to see how little code it actually takes:
Code
#include <iostream>
#include <algorithm>
#include <vector>
#include <numeric>
#include <random>
std::vector<int> randomSequence100(std::size_t count)
{
if (count > 100)
count = 100;
static std::random_device rd;
std::vector<int> result(100);
std::iota(result.begin(), result.end(), 1);
std::shuffle(result.begin(), result.end(), std::mt19937(rd()));
result.resize(count);
return result;
}
int main()
{
// run twenty tests of random shuffles.
for (int i=0; i<20; ++i)
{
auto res = randomSequence100(20);
for (auto x : res)
std::cout << x << ' ';
std::cout.put('\n');
}
}
Output
27 71 58 6 74 65 56 37 53 44 25 91 10 86 51 75 31 79 18 46
6 61 92 74 30 20 91 89 64 55 19 12 28 13 5 80 62 71 29 43
92 42 2 1 78 89 65 39 37 64 96 20 62 33 6 12 85 34 29 19
46 63 8 44 42 80 70 2 68 56 86 84 45 85 91 33 20 83 16 93
100 99 4 20 47 32 58 57 11 35 39 43 87 55 77 51 80 7 46 83
48 39 31 44 68 84 98 40 57 76 70 16 30 93 9 51 63 65 45 81
32 73 97 83 56 49 39 29 3 59 45 89 43 78 61 5 57 51 82 8
21 46 25 29 48 37 77 74 32 56 87 91 94 86 57 67 33 9 23 36
27 46 66 40 1 72 41 64 53 26 31 77 42 38 81 47 58 73 4 11
79 77 46 48 70 82 62 87 8 97 51 99 53 43 47 91 98 81 64 26
27 55 28 12 49 5 70 94 77 29 84 23 52 3 25 56 18 45 74 48
95 33 25 80 81 53 55 11 70 2 38 77 65 13 27 48 40 57 87 93
70 95 66 84 15 87 94 43 73 1 13 89 44 96 10 58 39 2 23 72
43 53 93 7 95 6 19 89 37 71 26 4 17 39 30 79 54 44 60 98
63 26 92 64 83 84 30 19 12 71 95 4 81 18 42 38 87 45 62 70
78 80 95 64 71 17 14 57 54 37 51 26 12 16 56 6 98 45 92 85
89 73 2 15 43 65 21 55 14 27 67 31 54 52 25 72 41 6 85 33
4 87 19 95 78 97 27 13 15 49 3 17 47 10 84 48 37 2 94 81
15 98 77 64 99 68 34 79 95 48 49 4 59 32 17 24 36 53 75 56
78 46 20 30 29 35 87 53 84 61 65 85 54 94 68 75 43 91 95 52
Each row above was a set of twenty elements take from the sequence of 1..100. No single row has duplicates (check if you want).
Caveat
This technique works wonderfully for either small domains or large result sets from larger domains. But it has its limits to consider.
For example: Once your potential domain reaches the point significant size (say, numbers in 1...1000000) and you want only small result sets (say, no larger than 100 elements), you're better off using a std::unordered_set and iterative probing similar to what you're doing now. The technique you use depends entirely on your performance goals and your usage patterns.
Counterexample: If you wanted a half-million unique elements shuffled from a million-element domain, the load/shuffle/resize technique will work well.
Ultimately you have to decide, and measure to confirm.
Some useful links about some of the things used here (bookmark this site, as it is absolute gold for information about C++):
std::vector
std::iota
std::random_device
std::mt19937
std::shuffle
From my view this function has problems.
It return the point of test1, which is allocated in the stack, which is invalid out of the scope of randomArray.
So if you change to malloc, this is allocated in heap, then it still valid when out of the scope of randomArray.
int *test1 = (int*) malloc(countOfRows* sizeof(int));
And you can using test1[x] to get the value of each int, for sure you should know the length of test1 is countOfRows.
Please don't forget to delete this point when it is not used...
Call this array is simple
int* values = randomArray(1000);
printf("%d\r\n",values[0]);
In the function randomArray() declare test1[] as a static int[].
return the array using pointers,
" return test1 "
in the main function use a pointer to access the return value
" int *ptr=randomArray(n) "

Getting WA in ANUGCD from Codechef March Long Contest

I am Getting WA in the Question GCD Condition from Codechef March Long Contest.
Kindly tell me what I've done wrong or some test case where the code produces Wrong answer.
Link for the Question
I Have used RMQ(Range maximum Query) for every prime number
for(i=0;i<limit;i++)
{
int sz=b[i].size();
if(!sz)continue;
int level=0;
cc[i].resize(sz);
for(j=0;j<sz;j++)cc[i][j].push_back(b[i][j]);//level 0
for(level=1;(1<<level)<=sz;level++)
{
for(j=0;j+(1<<level)<=sz;j++)
{
int c1=cc[i][j][level-1];
int c2=cc[i][j+(1<<(level-1))][level-1];
int mx=(a[c1]<a[c2])?c2:c1;
cc[i][j].push_back(mx);
}
}
}
firstly i have converted to a structure like the following:-
Example input:- 10 6 20 15 8
(b[i]-->stores the indices of factors of i)
b[2]--> 1,2,3,5
b[3]--> 2,4
b[5]--> 1,3,4
Now after implementing RMQ, it will be as follow:-
(cc[i][j][k] stores index of the largest element between b[i][j] and b[i][j+(2^k)-1])
cc[2][0]-->1,2,3,5
cc[2][1]-->1,3,3
cc[2][2]-->3
cc[3][0]-->2,4
cc[3][1]-->4
cc[5][0]-->1,3,4
cc[5][1]-->3
My Code
100 1
88 33 23 56 97 54 8 74 43 95 91 63 38 13 7 7 52 29 6 85 70 15 52 18 78 9 85 51 28 43 4 68 75 78 75 23 32 34 48 74 28 90 36 66 2 95 24 54 23 29 90 45 96 93 14 73 2 99 75 81 93 31 100 19 8 75 93 39 60 41 64 88 30 100 5 84 46 28 89 20 56 30 64 3 22 78 75 75 76 2 8 20 32 7 38 39 33 82 30 93
95 95 97
The output is -1 -1, but gcd(38, 95) = 19, so ans should be 38 1.
Replacing 'break' by 'continue' on line 75 gave AC :)

c++ rand() % 100 [closed]

This question is unlikely to help any future visitors; it is only relevant to a small geographic area, a specific moment in time, or an extraordinarily narrow situation that is not generally applicable to the worldwide audience of the internet. For help making this question more broadly applicable, visit the help center.
Closed 9 years ago.
im trying to fill an array with random 200 numbers that can very from 0-100. I get it populated except the last couple number are very odd.
here my code.
for (int i = 0; i < NUM_LIST_ELEMENTS; i++)
{
int j = rand() % 100;
list[i] = j;
}
my output comes out at follows
Original Arrays:
41 67 34 0 69 24 78 58 62 64 5 45 81 27 61 91 95 42 27 36 91 4 2 53 92 82 21 16 18
95 47 26 71 38 69 12 67 99 35 94 3 11 22 33 73 64 41 11 53 68 47 44 62 57 37 59 23 41
29 78 16 35 90 42 88 6 40 42 64 48 46 5 90 29 70 50 6 1 93 48 29 23 84 54 56 40 66
76 31 8 44 39 26 23 37 38 18 82 29 41 33 15 39 58 4 30 77 6 73 86 21 45 24 72 70 29
77 73 97 12 86 90 61 36 55 67 55 74 31 52 50 50 41 24 66 30 7 91 7 37 57 87 53 83 45
9 9 58 21 88 22 46 6 30 13 68 0 91 62 55 10 59 24 37 48 83 95 41 2 50 91 36 74 20
96 21 48 99 68 84 81 34 53 99 18 38 0 88 27 67 28 93 48 83 7 21 10 17 13 14-858993460
9 16 35 51 0 49 19 56 98 3 24 8 44 9 89 2 95 85 93 43 23 87 14 3 48 0 58 18 80
96 98 81 89 98 9 57 72 22 38 92 38 79 90 57 58 91 15 88 56 11 2 34 72 55 28 46 62 86
75 33 69 42 44 16 81 98 22 51 21 99 57 76 92 89 75 12 0 10 3 69 61 88 1 89 55 23 2
85 82 85 88 26 17 57 32 32 69 54 21 89 76 29 68 92 25 55 34 49 41 12 45 60 18 53 39 23
79 96 87 29 49 37 66 49 93 95 97 16 86 5 88 82 55 34 14 1 16 71 86 63 13 55 85 53 12
8 32 45 13 56 21 58 46 82 81 44 96 22 29 61 35 50 73 66 44 59 92 39 53 24 54 10 45 49
86 13 74 22 68 18 87 5 58 91 2 25 77 14 14 24 34 74 72 59 33 70 87 97 18 77-33686019
notice that last number in each array is really weird. Is there anything I can do to avoid this? btw this is two different arrays.
Thanks everyone that posted! I got it working!
You are reading one beyond the end of the array.
e.g. if you populate an array with 200 elements, you should write to and read from 0 to 199 not 0 to 200 or 1 to 200.
By the way - rand() % 100 will not make numbers from 0 to 100. It will make numbers from 0 to 99 only.
Also, as Randy Howard says (thanks), you can get a more even random generation by following the advice at http://www.azillionmonkeys.com/qed/random.html .
This is probably because there is something wrong with your code that prints the result. You might be looping from index 0 to 200, which has 201 items.
I counted your outputs and found there is 201 items, if the last 77-33686019 are actually 2 separate numbers.
If it's not that, you might have some printf/cout somewhere further down your code that actually prints some other value. To confirm this you can probably try printf ("\n"); right after your loop that outputs the array. If your negative number ends up on a different line, you'll know it's some other printf further down your code.
You might want to use int j = rand() % 101; instead so that you get 0 to 100. Your original code gives you the random range from 0 to 99.

Why doesn't Clojure let me define zero-padded numbers?

I'm trying to bind the following grid to a symbol
(def grid [08 02 22 97 38 15 00 40 00 75 04 05 07 78 52 12 50 77 91 08
49 49 99 40 17 81 18 57 60 87 17 40 98 43 69 48 04 56 62 00
81 49 31 73 55 79 14 29 93 71 40 67 53 88 30 03 49 13 36 65
52 70 95 23 04 60 11 42 69 24 68 56 01 32 56 71 37 02 36 91
22 31 16 71 51 67 63 89 41 92 36 54 22 40 40 28 66 33 13 80
24 47 32 60 99 03 45 02 44 75 33 53 78 36 84 20 35 17 12 50
32 98 81 28 64 23 67 10 26 38 40 67 59 54 70 66 18 38 64 70
67 26 20 68 02 62 12 20 95 63 94 39 63 08 40 91 66 49 94 21
24 55 58 05 66 73 99 26 97 17 78 78 96 83 14 88 34 89 63 72
21 36 23 09 75 00 76 44 20 45 35 14 00 61 33 97 34 31 33 95
78 17 53 28 22 75 31 67 15 94 03 80 04 62 16 14 09 53 56 92
16 39 05 42 96 35 31 47 55 58 88 24 00 17 54 24 36 29 85 57
86 56 00 48 35 71 89 07 05 44 44 37 44 60 21 58 51 54 17 58
19 80 81 68 05 94 47 69 28 73 92 13 86 52 17 77 04 89 55 40
04 52 08 83 97 35 99 16 07 97 57 32 16 26 26 79 33 27 98 66
88 36 68 87 57 62 20 72 03 46 33 67 46 55 12 32 63 93 53 69
04 42 16 73 38 25 39 11 24 94 72 18 08 46 29 32 40 62 76 36
20 69 36 41 72 30 23 88 34 62 99 69 82 67 59 85 74 04 36 16
20 73 35 29 78 31 90 01 74 31 49 71 48 86 81 16 23 57 05 54
01 70 54 71 83 51 54 69 16 92 33 48 61 43 52 01 89 19 67 48])
This yields Exception in thread "main" java.lang.NumberFormatException: Invalid number: 08 (11.clj:1). Why can't I do this in Clojure? Are there any workarounds?
Clarification
All I want to do is paste this grid somewhere and have it act as if there were no leading zeros, even if it takes a little coercion. I don't want to have to drop all of the zeros in my editor, I'd just like to paste it in there and have each number behave as if there were no leading zeros.
One other strange detail
The REPL seems to allow zero-padded numbers, but executing a .clj file with java -cp clojure.jar -i some_file.clj will throw the error.
Leading zeros imply an octal number, so 08 is not valid. Many programming languages use this convention, starting with C.
SPOILER ALERT:
Since you're solving a Project Euler problem, you might not want to read this, even though it's only about the "how to read in the data?" part of it...
The reason this happens is as explained in the other answers. The correct solution would be to embed the input in your code as a string -- with linebreaks! -- and use something like the following:
(->> the-string
(.split #"\n")
(map #(.split #"\s+" %))
(map (partial drop-while empty?))
;; this just doesn't care about the leading 0
(mapcat (partial map #(Integer/parseInt %)))
vec)
This should produce a vector of your numbers. For a two-dimentional vector, you could replace the mapcat with a regular map and put in an extra (map vec) before the final vec.
If you prefer to put the input in a separate file and have Clojure read it from there, replace the-string and (.split #"\n") with a call to line-seq on a reader on your file.x
numbers with a leading 0 are read as if they where in base 8 so any charcter not between 0-7 will not work. to fix this you can append 10r08 to explicity specify the base.
user> 10r08
8
user> 08
; Evaluation aborted.
This messes up your nice formatting though :( sorry about that. you could write a little macro to change this for a block if you want to preserve your nicely formatted code.
Regular expressions will remove leading zeros
(re-seq #"[1-9]+[0-9]*|0{2}" the-string)
The regex phrase breaks down as follows:
[1-9]+ ;; one or more repetitions of 1-9 (i.e. must start with 1-9)
[0-9]* ;; zeros are ok after the first non-zero number has been found
|0{2} ;; or if the above can't be found, just look for two zeros
A more general expression is
#"[1-9]+[0-9]*|(?<=\s)0+(?=\s)"
which does the same thing but in the 'or' portion it uses positive lookahead and lookbehind assertions to look for a sequence of one or more zeros preceded and followed by whitespace.
With the leading zeros stripped (map read-string (re-seq ....)) works just fine
Since it only took about 3 minutes to remove all leading zeroes, I'll just paste the above vector with the zeroes removed in case anyone else wants to copy/paste the euler problem.
(def grid [ 8 2 22 97 38 15 0 40 0 75 4 5 7 78 52 12 50 77 91 8
49 49 99 40 17 81 18 57 60 87 17 40 98 43 69 48 4 56 62 0
81 49 31 73 55 79 14 29 93 71 40 67 53 88 30 3 49 13 36 65
52 70 95 23 4 60 11 42 69 24 68 56 1 32 56 71 37 2 36 91
22 31 16 71 51 67 63 89 41 92 36 54 22 40 40 28 66 33 13 80
24 47 32 60 99 3 45 2 44 75 33 53 78 36 84 20 35 17 12 50
32 98 81 28 64 23 67 10 26 38 40 67 59 54 70 66 18 38 64 70
67 26 20 68 02 62 12 20 95 63 94 39 63 8 40 91 66 49 94 21
24 55 58 5 66 73 99 26 97 17 78 78 96 83 14 88 34 89 63 72
21 36 23 9 75 0 76 44 20 45 35 14 0 61 33 97 34 31 33 95
78 17 53 28 22 75 31 67 15 94 3 80 4 62 16 14 9 53 56 92
16 39 5 42 96 35 31 47 55 58 88 24 0 17 54 24 36 29 85 57
86 56 0 48 35 71 89 7 05 44 44 37 44 60 21 58 51 54 17 58
19 80 81 68 5 94 47 69 28 73 92 13 86 52 17 77 4 89 55 40
4 52 8 83 97 35 99 16 7 97 57 32 16 26 26 79 33 27 98 66
88 36 68 87 57 62 20 72 3 46 33 67 46 55 12 32 63 93 53 69
4 42 16 73 38 25 39 11 24 94 72 18 8 46 29 32 40 62 76 36
20 69 36 41 72 30 23 88 34 62 99 69 82 67 59 85 74 4 36 16
20 73 35 29 78 31 90 1 74 31 49 71 48 86 81 16 23 57 5 54
1 70 54 71 83 51 54 69 16 92 33 48 61 43 52 1 89 19 67 48])