Example: chessboard has 64 fields, starting from 1 in top uppermost left box,
row 2, column 2 means its 10th box,
row 4, column 2 means its 26th box .....so on
Formula, trick to determine Row_column no from box number or vice versa?
I guess you mean that you have 8 boxes on each row?
This might do the trick:
#include <iostream>
#include <cmath>
const int totalNrOfBoxes = 64;
const float nrOfRows = std::sqrt(totalNrOfBoxes);
std::pair<int, int> getRowAndColumn(int boxNumber) {
int rowNumber = std::ceil(boxNumber / nrOfRows);
int columnNumber = (boxNumber - 1) % (int) nrOfRows; // we do -1 to avoid getting 0 when the boxNr is 8 or 16 or 32 for example
columnNumber += 1; // we add one number to the column number because we removed one from the box number
return std::make_pair(rowNumber, columnNumber);
}
int main()
{
std::pair<int, int> rowAndColumn = getRowAndColumn(11);
std::pair<int, int> rowAndColumn2 = getRowAndColumn(64);
std::pair<int, int> rowAndColumn3 = getRowAndColumn(1);
std::pair<int, int> rowAndColumn4 = getRowAndColumn(34);
std::pair<int, int> rowAndColumn5 = getRowAndColumn(7);
std::cout << rowAndColumn.first << " " << rowAndColumn.second << std::endl;
std::cout << rowAndColumn2.first << " " << rowAndColumn2.second << std::endl;
std::cout << rowAndColumn3.first << " " << rowAndColumn3.second << std::endl;
std::cout << rowAndColumn4.first << " " << rowAndColumn4.second << std::endl;
std::cout << rowAndColumn5.first << " " << rowAndColumn5.second << std::endl;
}
gives us the following output:
2 3
8 8
1 1
5 2
1 7
So basically what we do to determine the row number, is to divide the given box number by the number of rows, and take the ceil (finds the closest integer not less than n) out of that. Example: 26 / 8 = 3.25. We know that 26 is on the 4th row, so we need to take the closest integer not less than 3.25 which is 4.
For the column number we take the remainder. So for example with 12 it would return 4. The problem is that we start counting boxes at 1, so 16 % 8 would return 0, while we do want to get a value of 8. So that is why we say boxNumber - 1 (15 % 8 which returns 7) and add 1.
Related
I'm doing some algorithmics problem and I'm having trouble with managing functions, vectors and strings in C++.
I have to find a concrete path in a matrix and for that, I need to have all the different paths, so I decided to use a function. This function will check where to continue to search. Here is the code of the function:
vector<string> get_all_paths(string actual, int rows, int columns, int col_actual, int row_prev) {
vector<string> solutions;
int row_actual = (rows+row_prev-1)%rows;
for (int i = 0; i < 3; i++) {
cout << col_actual << " " << row_actual << "\n";
//cout << (dp[row_prev][col_actual+1] - matrix[row_prev][col_actual+1]) << " " << dp[row_actual][col_actual] << "\n";
if( (dp[row_prev][col_actual+1] - matrix[row_prev][col_actual+1]) == dp[row_actual][col_actual] ) {
if (col_actual > 0) {
//cout << "--" << actual << " " << row_actual << "\n";
string branch = actual + to_string(row_actual+1) + " ";
solutions = get_best_path(branch, rows, columns, col_actual-1, row_actual);
//cout << ".." << actual << "\n";
} else {
//cout << actual << " " << row_actual << "\n";
cout << actual << "\n";
string branch = actual.c_str();
branch += to_string(row_actual+1);
cout << branch << "\n";
solutions.push_back( branch );
break;
}
}
row_actual = (row_actual+1)%rows;
}
for(auto i : solutions) cout << "--" << i << "\n";
return solutions;
}
And here is the call to the method:
vector<string> solutions;
for (int i = 0; i < rows; i++) {
if (dp[i][cols-1] == min_path) {
cout << "................\n";
solutions = get_best_path( (to_string(i+1)+" "), rows, cols, cols-2, i);
for(auto i : solutions) {
reverse(i.begin(), i.end());
cout << i << "\n";
}
cout << "xxxxxxxxxxxxxxx\n";
}
}
The thing is that I'm getting three paths for a given example, which is correct, but they are all the same string, which is the last path or the last change done in variable branch.
Maybe I'm mixing a lot of concepts and maybe this has been answered a lot of times, but I've searched this and got nothing.
EDIT: I'm not getting three paths from the function, just the last one, but when printing inside the function the paths i do have three inside that function all with the same value, sorry about that.
EDIT2: The idea of the problem is to find the minimum cost path in a given matrix and, if there are more than 1, the one that is the smallest lexicographically. So given a matrix:
5 4
9 1 9 9
1 9 9 9
9 9 9 9
1 1 1 1
9 9 1 9
My approach is to use dp as a matrix with the dynamic programming results and then i try to recreate all the paths in the function above.
In this case, the dp matrix is:
9 2 11 12
1 10 11 20
9 10 11 12
1 2 3 4
9 10 3 12
And so, the best paths are:
4 4 4 4
4 5 4 4
2 1 5 4
And the one correct is the last one.
Inside my function i do get the different paths and i add them to the vector of results, but then i lose them when searching for more.
Thanks for the time if you have read this :D!
Well I think the problem is here
solutions = get_best_path(branch, rows, columns, col_actual-1, row_actual);
because that assignment replaces any solutions you might have found so far. Instead you should append any solutions returned to any that you've found so far. In other words something like this
vector<string> tmp = get_best_path(branch, rows, columns, col_actual-1, row_actual);
solutions.insert(solutions.end(), tmp.begin(), tmp.end());
But this is just intuition, I haven't tested anything.
I wanna create a custom data type which uses 5 bits. Max value is 20 (10100) and min value is 0 (00000). I couldn't imagine how could I accomplish that. So I decided ask your helps...
And it should do arithmetics like:
note n = 15;
note x = 5;
std::cout << n + x << std::endl; //Should print 20
std::cout << n-x << std::endl; //Should print 10
Regards & thanks for your efforts!..
How can I write code to generate a random number that falls between two different ranges?
Example: Generate a random number that is between 5 and 7 or between 10 and 12. Possible outcomes are 5, 6, 7, 10, 11, or 12.
UPDATE Second implementation added below
If you want to make this generic, you'll have to code it.
Two options come to mind:
discrete_distribution (just feed it 5,6,7,10,11,12)
generate numbers [0..6) and index into an array int arr[]={5,6,7,10,11,12}
The second:
Live On Coliru
#include <random>
#include <iostream>
int main()
{
using namespace std;
vector<int> arr = {5,6,7,10,11,12};
mt19937 prng { random_device {} () };
uniform_int_distribution<> dist(0, arr.size()-1);
int i = 10;
while (i--)
std::cout << arr[dist(prng)] << " ";
}
Prints
5 5 6 12 11 6 11 12 5 12
Or, similar of course
UPDATE
An alternative implementation that will scale for many segments or large segments, by using Boost Interval Container Library to efficiently represent the intervals that make up the domain:
Live On Coliru
template <typename T = int>
struct uniform_draw {
using set = boost::icl::interval_set<T>;
using ival = typename set::interval_type::type;
uniform_draw(std::initializer_list<ival> data)
: set_(make_set(data)), dist_(0, set_.size() - 1)
{ }
friend std::ostream& operator<<(std::ostream& os, uniform_draw const& ud) {
return os << ud.set_ << " (#samples:" << ud.set_.size() << ")";
}
template <typename Engine>
T operator()(Engine& engine) {
uintmax_t index = dist_(engine);
std::cout << " - index: " << index << " against " << set_ << "\n";
// I think this can be optimized. I just don't know how to elegantly do that / yet
for (auto& iv : set_) {
std::cout << " - index: " << index << " against " << iv << "\n";
if (index > size(iv)) {
index -= size(iv);
} else {
return iv.lower() + index;
}
}
throw std::range_error("uniform_draw");
}
private:
set make_set(std::initializer_list<ival> data) {
set r;
for (auto& el : data)
r.insert(el);
return r;
}
set const set_;
std::uniform_int_distribution<T> dist_; // TODO make_unsigned<T>?
};
Use it like your usual distribution:
mt19937 mt { random_device {} () };
uniform_draw<int> dist { {5, 7}, {10, 12} };
std::cout << dist << "\n";
for (int i = 0; i < 10; ++i)
std::cout << "RESULT: " << dist(mt) << "\n";
Prints e.g.:
{[5,7)[10,12)} (#samples:4)
7 7 6 11 6 6 7 7 7 6
Pick a random number 0 or 1. If this number is 0, pick a random number in the first range, otherwise pick a random number in the second range.
If you want each number in the two ranges to have equal probability, you could weight the first decision based on the sizes of the two ranges.
I see two ways to do this. Let's say your two ranges are [minA, maxA] and [minB, maxB] where maxA < minB (if not just swap the two ranges)
Solution 1:
1) Generate a random number X in [minA, maxB] first
2) if X falls (maxA,minB) goto 1)
3) At this point X is the output
Solution 2 (more efficient especially if the gap between the two ranges is big):
1) rangeA = maxA - minA, rangeB = maxB - minB;
2) generate a random number X within [0,rangeA+rangeB]
3) if X < rangeA then output minA+X else minB+X
How can this code...
vector<double> _pc;
vector<int> _documentClassIds;
[...]
someMemberFunction(vector<int> const & documentIds) {
cout << "_pc[0] = "<< _pc[0]<<endl;
cout << "_pc[1] = "<< _pc[1]<<endl;
cout << "documentIds.size() = " << documentIds.size()<<endl;
// Normalize
for (auto documentId : documentIds)
_pc[_documentClassIds[documentId]] =
_pc[_documentClassIds[documentId]] / documentIds.size();
cout << "_pc[0] = "<< _pc[0]<<endl;
cout << "_pc[1] = "<< _pc[1]<<endl;
}
produce this output?
_pc[0] = 3
_pc[1] = 3
documentIds.size() = 6
_pc[0] = 0.0138889
_pc[1] = 0.0138889
I'm not sure what you think the problem is.
You have six document IDs, so your for loop runs six times. Each time it runs, it divides one of your _pc array values by six.
Since 0.0138888... is 3 divided by 216 (6^3), the calculations seem correct.
It's obvious that the selection of which _pc array entry to divide is equally distibuted so that each gets divided three times, so each ends up as:
(((3 / 6) / 6) / 6) => 0.013888...
Does the interval_map (in icl) library provide support for deletion? Can I look up the range based on iterator and delete the range?
============ party.cpp from boost example ===============
partyp->add( // add and element
make_pair(
interval<ptime>::right_open(
time_from_string("2008-05-20 19:30"),
time_from_string("2008-05-20 23:00")),
mary_harry));
party += // element addition can also be done via operator +=
make_pair(
interval<ptime>::right_open(
time_from_string("2008-05-20 20:10"),
time_from_string("2008-05-21 00:00")),
diana_susan);
party +=
make_pair(
interval<ptime>::right_open(
time_from_string("2008-05-20 22:15"),
time_from_string("2008-05-21 00:30")),
peter);
==========
My question is can i add a remove statement like
party -=
interval<ptime>::right_open(
time_from_string("2008-05-20 20:10"),
time_from_string("2008-05-21 00:00"));
I just want to remove the range. Any method is fine.
I know this is an old post, but I had the same question and I've finally found an answer.
Looking at the docs I would guess that the Subtractability of an interval_map and the aggregate on overlap capabilities guarantee that the substraction works as a delete operation.
It turned out to be a very fruitful concept to propagate the addition
or subtraction to the interval_map's associated values in cases where
the insertion of an interval value pair into an interval_map resulted
in a collision of the inserted interval value pair with interval value
pairs, that are already in the interval_map. This operation
propagation is called aggregate on overlap.
Let's say I have to match intervals of unix timestamps to some record ids (integers).
Working from this answer I've come up with this MWE:
// interval_map_mwe.cpp
#include <map>
#include <set>
#include <climits>
#include <boost/icl/interval.hpp>
#include <boost/icl/interval_map.hpp>
// Set of IDs that cover a time interval
typedef std::set<unsigned int> IDSet_t;
// interval tree from intervals of timestamps to a set of ids
typedef boost::icl::interval_map<time_t, IDSet_t> IMap_t;
// a time interval
typedef boost::icl::interval<time_t> Interval_t;
#include <iostream>
// from https://stackoverflow.com/a/22027957
inline std::ostream& operator<< (std::ostream& S, const IDSet_t& X)
{
S << '(';
for (IDSet_t::const_iterator it = X.begin(); it != X.end(); ++it) {
if (it != X.begin()) {
S << ',';
}
S << *it;
}
S << ')';
return S;
}
int main(int argc, const char *argv[])
{
(void)argc; // suppress warning
(void)argv; // suppress warning
IMap_t m;
IDSet_t s;
s.insert(1);
s.insert(2);
m += std::make_pair(Interval_t::right_open(100, 200), s);
s = IDSet_t();
s.insert(3);
s.insert(4);
m += std::make_pair(Interval_t::right_open(200, 300), s);
s = IDSet_t();
s.insert(5);
s.insert(6);
m += std::make_pair(Interval_t::right_open(150, 250), s);
std::cout << "Initial map: " << std::endl;
std::cout << m << std::endl;
// find operation
IMap_t::const_iterator it = m.find(175);
std::cout << "Interval that covers 175: ";
std::cout << it->first << std::endl;
std::cout << "Ids in interval: " << it->second << std::endl;
// partially remove 5 from interval (160,180)
s = IDSet_t();
s.insert(5);
m -= std::make_pair(Interval_t::right_open(160, 180), s);
std::cout << "map with 5 partially removed:" << std::endl;
std::cout << m << std::endl;
// completelly remove 6
s = IDSet_t();
s.insert(6);
// Note: maybe the range of the interval could be shorter if you can somehow obtain the minimum and maximum times
m -= std::make_pair(Interval_t::right_open(0, UINT_MAX), s);
std::cout << "map without 6: " << std::endl;
std::cout << m << std::endl;
// remove a time interval
m -= Interval_t::right_open(160, 170);
std::cout << "map with time span removed: " << std::endl;
std::cout << m << std::endl;
return 0;
}
Compiling with g++ 4.4.7:
g++ -Wall -Wextra -std=c++98 -I /usr/include/boost148/ interval_map_mwe.cpp
The output I get is
Initial map:
{([100,150)->{1 2 })([150,200)->{1 2 5 6 })([200,250)->{3 4 5 6 })([250,300)->{3 4 })}
Interval that covers 175: [150,200)
Ids in interval: (1,2,5,6)
map with 5 partially removed:
{([100,150)->{1 2 })([150,160)->{1 2 5 6 })([160,180)->{1 2 6 })([180,200)->{1 2 5 6 })([200,250)->{3 4 5 6 })([250,300)->{3 4 })}
map without 6:
{([100,150)->{1 2 })([150,160)->{1 2 5 })([160,180)->{1 2 })([180,200)->{1 2 5 })([200,250)->{3 4 5 })([250,300)->{3 4 })}
map with time span removed:
{([100,150)->{1 2 })([150,160)->{1 2 5 })([170,180)->{1 2 })([180,200)->{1 2 5 })([200,250)->{3 4 5 })([250,300)->{3 4 })}
Note: The numbers in the MWE can be considered random. I find it easier to reason about the example with small numbers.