Convert 2D array of points into 1D array - c++

I am struggling to convert a 2D array of points in a 1D array of ints. I wrote a wrapper class to do that for me (Array3D), which does the mapping for me with filling the underlying buffer, but it looks like the indexing is totally wrong, since when I print my 2D array and in comparison the buffer, it gives me different outputs.
The 2D point array has dimensions steps × number_of_robots. Therefore, the 1D buffer has
a length of steps × number_of_robots × 2.
Idea is that
buffer[index(x,y,0)] corresponds to points[index(x,y)].x
buffer[index(x,y,1)] corresponds to points[index(x,y)].y
The output is wrong, since it should be identical when I print out the 2D point array and the 1D buffer. I read the row of points from a file, and therefore, they totally should be identical.
The points are derived from the input read by a file. How that is done seems unimportant. Fact is, that the output of main.cpp is:
(0, 4) (0, 5) (1, 5) (2, 5) (2, 4) (3, 4) (2, 4) (2, 3) (2, 2)
(4, 0) (4, -1) (4, 0) (4, 1) (3, 1) (4, 1) (4, 2) (3, 2) (2, 2)
(0, 2) (0, 3) (1, 2) (2, 2) (2, 2) (3, 3) (2, 2) (2, 2) (2, 2)
(1, 2) (2, 2) (2, 2) (3, 3) (2, 2) (2, 2) (2, 2) (3, 3) (2, 2)
point.cpp
Point::Point(int a, int b) {
x = a;
y = b;
}
Array3D.cpp
template<class T>
int Array3D<T>::index(int x,int y, int z) {
return (x * ydim + y) * zdim + z;
}
template<class T>
T Array3D<T>::get( int x, int y, int z) {
return buffer[index(x,y,z)];
}
template<class T>
void Array3D<T>::set( int x, int y, int z ,T n) {
buffer[index(x,y,z)] = n;
}
Harvester.cpp
int Harvester::index(int t, int n) {
return t*number_of_robots + n;
}
void Harvester::extract(Array3D<int> *array) {
Point p;
for(int t = 0; t < steps; t++ ) {
for(int n = 0; n < number_of_robots; n++) {
p = data[index(t,n)];
array->set(t,n,0,p.x);
array->set(t,n,1,p.x);
}
}
}
void Harvester::read_points(string filename) {
string line;
ifstream input;
input.open(filename.c_str());
input >> number_of_robots;
int x, y;
for(int n = 0; n < number_of_robots; n++) {
if(input >> x >> y) {
data[index(0,n)].x = x;
data[index(0,n)].y = y;
//cout << x << " " << y << endl;
} else {
cout << "Your file is bad, and you should feel bad!";
return;
}
}
}
void Harvester::print_harvest() {
for (int n = 0; n < number_of_robots; n++) {
for (int t = 0; t < steps; t++) {
data[index(t,n)].dump();
}
cout << endl;
}
cout << endl;
}
robots_002.txt
2
0 4
4 0
main.cpp
int main() {
int mission_time;
int number_of_robots;
Point goal;
string path;
bool print = true;
int choice = 2;
mission_time = 8;
number_of_robots = 2;
goal.x = 2;
goal.y = 2;
path = "robots_002.txt";
int steps = mission_time + 1;
Harvester h(mission_time, number_of_robots, goal);
h.read_points("fixtures/" + path);
h.run();
int *buffer = new int[steps * number_of_robots * 2];
Array3D<int> arr(steps, number_of_robots, 2, buffer);
h.extract(&arr);
h.print_harvest();
for (int n = 0; n < number_of_robots; n++) {
for (int t = 0; t < steps; t++) {
printf("(%d, %d)\t", arr.get(t, n, 0), arr.get(t, n, 1));
}
cout << endl;
}
return 0;
}

still looking through but quick observation. In Harverster::extract, you are setting both to p.x
void Harvester::extract(Array3D<int> *array) {
Point p;
for(int t = 0; t < steps; t++ ) {
for(int n = 0; n < number_of_robots; n++) {
p = data[index(t,n)];
array->set(t,n,0,p.x);
array->set(t,n,1,p.x); //<-- im thinking you want this to be p.y
}
}
}

Related

Find the minimum difference of all possible pairs

Given 3 numeric sorted arrays:
int[] a;
int[] b;
int[] c;
It is necessary to find three numbers whose difference is minimal:
(a_i- b_j)^2 + (b_j - c_k)^2 + (a_i - c_k)^2 -> min
For examle:
int[] a = {7, 10, 12};
int[] b = {3, 4, 6, 9};
int[] c = {1, 2, 5, 8};
Result should be 7 6 8 (or 7 6 5) because (7 - 6)^2 + (6 - 5)^2 + (7 - 5)^2 = 6 = min
What is the best approach to this problem?
I`ve tried to use 3 variables and increment them depending on the minimum term, but unsuccessfully.
Here is my algorithm written in C++:
void printThreeClosest(int[] a, int[] b, int[] c) {
int64_t diff = (a[0] - b[0]) * (a[0] - b[0]) +
(b[0] - c[0]) * (b[0] - c[0]) +
(a[0] - c[0]) * (a[0] - c[0]);
int i_res = 0, j_res = 0, k_res = 0, i = 0, j = 0, k = 0;
while (i < a.size() && j < b.size() && k < c.size()) {
int first_term = (a[i] - b[j]) * (a[i] - b[j]);
int second_term = (b[j] - c[k]) * (b[j] - c[k]);
int third_term = (a[i] - c[k]) * (a[i] - c[k]);
int min_term = std::min(a[i], std::min(b[j], c[k]));
int64_t current_diff = first_term + second_term + third_term;
if (current_diff < diff) {
diff = current_diff;
i_res = i, j_res = j, k_res = k;
}
if (diff == 0) {
break;
}
if (first_term == min_term) {
++k;
} else if (second_term == min_term) {
++i;
} else {
++j;
}
}
std::cout << a[i_res] << " " << b[j_res] << " " << c[k_res] << "\n";
}
IMO, the straight-forward, but O(n^3) solution may be this:
void printThreeClosest(int[] a, int[] b, int[] c) {
int minVal = -1;
int resa, int resb, int resc;
for(int i=0; i<a.length && minVal != 0; i++) {
int x = a[i];
for(int j=0; j<b.length && minVal != 0; j++) {
int y = b[j];
for(int k=0; k<c.length && minVal != 0; k++) {
int z = c[k];
int sumOfSqr = ( ((x-y)*(x-y)) + ((y-z)*(y-z)) + ((z-x)*(z-x)) );
if (minVal < 0) {
minVal = sumOfSqr;
resa=x; resb=y; resc=z;
} else if (sumOfSqr < minVal) {
minVal = sumOfSqr;
resa=x; resb=y; resc=z;
}
}
}
};
std::cout << resa << ' ' << resb << ' ' << resc << std::endl;
}
This solution implemented in Javascript for quick testing is below:
const a = [7, 10, 12];
const b = [3, 4, 6, 9];
const c = [1, 2, 5, 8];
let minVal = -1;
let result = [];
const sumOfSquares = (x, y, z) => ( ((x-y)*(x-y)) + ((y-z)*(y-z)) + ((x-z)*(x-z)) );
for (let i=0; i < a.length && minVal !== 0; i++) {
for (let j=0; j < b.length && minVal !== 0; j++) {
for (let k=0; k < c.length && minVal !== 0; k++) {
const tempSum = sumOfSquares(a[i], b[j], c[k]);
if (minVal < 0) {
minVal = tempSum;
result = [a[i], b[j], c[k]];
} else if (tempSum < minVal) {
minVal = tempSum;
result = [a[i], b[j], c[k]];
}
}
}
}
console.log('result: ', result);

c++ - reading and writing a large bmp file

I have to create a program in c++ (standard libraries only) that detects edges with Sobel operator on a bmp photo and writes the result to the output bmp file (no need to create it, just to write into a previously created file). To do so I have to read an input bmp file and put it into a dynamic 2x2 array. Reading must be done in two different modes (picked up by an user) - first one is to read whole image into a memory in a dynamic array, second one is to read an image piece by piece (pieces with set size). I have no idea how to do a second mode, i guess it has to somehow read an exact number of lines from an input file, use a sobel on them and put them together in an output file, but i have no idea how to implement it. can you tell me how to start it?
this is some code that i've made, it's incomplete since i have to do a second mode but the first one is done (the Sobel operator code was taken from Dwayne Phillips' book about processing images in C, so it's more C-like)
#include <iostream>
#include <fstream>
using namespace std;
typedef unsigned char byte_t; //krotszy zapis
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////// BMP STRUCTS ////////////////////////////////////////////////////////////////////////////
struct BITMAPFILEHEADER {
byte_t bfType[2];
byte_t bfSize[4];
byte_t bfReserved1[2];
byte_t bfReserved2[2];
byte_t bfOffBits[4];
};
struct BITMAPINFOHEADER {
byte_t biSize[4];
byte_t biWidth[4];
byte_t biHeight[4];
byte_t biPlanes[2];
byte_t biBitCount[2];
byte_t biCompression[4];
byte_t biSizeImage[4];
byte_t biXpelsPerMeter[4];
byte_t biYpelsPerMeter[4];
byte_t biCrlUses[4];
byte_t biCrlImportant[4];
};
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////// SOBEL MASKS ////////////////////////////////////////////////////////////////////////////////////////
short mask_0[3][3] = { //S1
{ 1, 2, 1},
{ 0, 0, 0},
{-1, -2, -1} };
short mask_1[3][3] = { //S2
{ 2, 1, 0},
{ 1, 0, -1},
{ 0, -1, -2} };
short mask_2[3][3] = { //S3
{ 1, 0, -1},
{ 2, 0, -2},
{ 1, 0, -1} };
short mask_3[3][3] = { //S4
{ 0, -1, -2},
{ 1, 0, -1},
{ 2, 1, 0} };
short mask_4[3][3] = { //S5 (-S1)
{-1, -2, -1},
{ 0, 0, 0},
{ 1, 2, 1} };
short mask_5[3][3] = { //S6 (-S2)
{-2, -1, 0},
{-1, 0, 1},
{ 0, 1, 2} };
short mask_6[3][3] = { //S7 (-S3)
{-1, 0, 1},
{-2, 0, 2},
{-1, 0, 1} };
short mask_7[3][3] = { //S8 (-S4)
{ 0, 1, 2},
{-1, 0, 1},
{-2, -1, 0} };
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////// BASIC FUNCTIONS ///////////////////////////////////////////////////////////////////////////////////
int wordValue(byte_t* t) //value of 2 byte long variable
{
return t[0] + t[1] * 256;
}
int dwordValue(byte_t* t) //value of 4 byte long variable
{
return t[0] + t[1] * 256 + t[2] * 256 * 256 + t[3] * 256 * 256 * 256;
}
int menudisplay()
{
cout << "<------------------------------------- OPERATOR SOBELA - PROJEKT -------------------------------- >" << endl;
cout << "< Welcome at Sobel! >" << endl;
cout << "< Sobel detects edges in BMP files. >" << endl;
cout << "< It has two modes: >" << endl;
cout << "< 1. Reading whole image into a RAM >" << endl;
cout << "< 2. Reading an image piece by piece (for big files) >" << endl;
cout << "< To pick a mode, just enter 1 or 2. >" << endl;
cout << "< Then enter a name of an input file with .bmp. >" << endl;
cout << "< Later enter a name of an output value with .bmp. >" << endl;
cout << "< Have fun! >" << endl;
cout << "<----------------------- ----------------------->" << endl << endl;
cout << "Your choice: ";
}
void menuservice()
{
menudisplay();
powrot:
int a;
cin >> a;
switch (a)
{
case 1:
save_to_bmp();
break;
case 2:
/*pieces of image*/
break;
default:
cout << "Bad choice! Pick a mode once again: ";
goto powrot;
break;
}
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////// BMP READING //////////////////////////////////////////////////////////////////////////////////
void readBFH(ifstream& ifs, BITMAPFILEHEADER& bfh) //reading bfh
{
ifs.read((char*)&(bfh.bfType), sizeof(bfh.bfType));
ifs.read((char*)&(bfh.bfSize), sizeof(bfh.bfSize));
ifs.read((char*)&(bfh.bfReserved1), sizeof(bfh.bfReserved1));
ifs.read((char*)&(bfh.bfReserved2), sizeof(bfh.bfReserved2));
ifs.read((char*)&(bfh.bfOffBits), sizeof(bfh.bfOffBits));
}
void readBIH(ifstream& ifs, BITMAPINFOHEADER& bih) //reading bih
{
ifs.read((char*)&(bih.biSize), sizeof(bih.biSize));
ifs.read((char*)&(bih.biWidth), sizeof(bih.biWidth));
ifs.read((char*)&(bih.biHeight), sizeof(bih.biHeight));
ifs.read((char*)&(bih.biPlanes), sizeof(bih.biPlanes));
ifs.read((char*)&(bih.biBitCount), sizeof(bih.biBitCount));
ifs.read((char*)&(bih.biCompression), sizeof(bih.biCompression));
ifs.read((char*)&(bih.biSizeImage), sizeof(bih.biSizeImage));
ifs.read((char*)&(bih.biXpelsPerMeter), sizeof(bih.biXpelsPerMeter));
ifs.read((char*)&(bih.biYpelsPerMeter), sizeof(bih.biYpelsPerMeter));
ifs.read((char*)&(bih.biCrlUses), sizeof(bih.biCrlUses));
ifs.read((char*)&(bih.biCrlImportant), sizeof(bih.biCrlImportant));
}
void writeBFH(ofstream& ofs, BITMAPFILEHEADER& bfh) //zapisywanie naglowka pliku
{
ofs.write((char*)&(bfh.bfType), sizeof(bfh.bfType));
ofs.write((char*)&(bfh.bfSize), sizeof(bfh.bfSize));
ofs.write((char*)&(bfh.bfReserved1), sizeof(bfh.bfReserved1));
ofs.write((char*)&(bfh.bfReserved2), sizeof(bfh.bfReserved2));
ofs.write((char*)&(bfh.bfOffBits), sizeof(bfh.bfOffBits));
}
void writeBIH(ofstream& ofs, BITMAPINFOHEADER& bih) //writing bih
{
ofs.write((char*)&(bih.biSize), sizeof(bih.biSize));
ofs.write((char*)&(bih.biWidth), sizeof(bih.biWidth));
ofs.write((char*)&(bih.biHeight), sizeof(bih.biHeight));
ofs.write((char*)&(bih.biPlanes), sizeof(bih.biPlanes));
ofs.write((char*)&(bih.biBitCount), sizeof(bih.biBitCount));
ofs.write((char*)&(bih.biCompression), sizeof(bih.biCompression));
ofs.write((char*)&(bih.biSizeImage), sizeof(bih.biSizeImage));
ofs.write((char*)&(bih.biXpelsPerMeter), sizeof(bih.biXpelsPerMeter));
ofs.write((char*)&(bih.biYpelsPerMeter), sizeof(bih.biYpelsPerMeter));
ofs.write((char*)&(bih.biCrlUses), sizeof(bih.biCrlUses));
ofs.write((char*)&(bih.biCrlImportant), sizeof(bih.biCrlImportant));
}
void displaydata(BITMAPFILEHEADER bfh, BITMAPINFOHEADER bih) //displaying data
{
cout << "Input file data:" << endl;
cout << "<---------------------------------------->";
cout << "File length: " << dwordValue(bfh.bfSize) << endl;
cout << "Header size: " << dwordValue(bih.biSize) << endl;
cout << "Image width: " << dwordValue(bih.biWidth) << endl;
cout << "Image height: " << dwordValue(bih.biHeight) << endl;
cout << "Image size: " << dwordValue(bih.biSizeImage) << endl;
cout << "Real amount of picture's bytes: " << dwordValue(bih.biSizeImage) - dwordValue(bfh.bfOffBits) << endl;
cout << "Zeros per row: " << zerosPerRow(bfh, bih) << endl;
}
int zerosPerRow(BITMAPFILEHEADER bfh, BITMAPINFOHEADER bih)
{
int realsize = dwordValue(bih.biSizeImage) - dwordValue(bfh.bfOffBits);
int height = dwordValue(bih.biHeight);
int width = dwordValue(bih.biWidth);
int zeros = 0;
if (width % 4 != 0)
{
int bytesPerRow = width * 3;
zeros = (bytesPerRow / 4 + 1) * 4 - bytesPerRow;
}
return zeros;
}
void save_to_bmp()
{
char infile[100];
char outfile[100];
cout << "Enter input file: ";
cin >> infile;
cout << "Enter output file: ";
cin >> outfile;
ifstream ifs(infile, ios::binary); //input stream
ofstream ofs(outfile, ios::binary); //output stream
BITMAPFILEHEADER bfh;
BITMAPINFOHEADER bih;
if (!ifs.is_open() || !ofs.is_open())
{
cerr << "Opening error!";
save_to_bmp();
}
else {
readBFH(ifs, bfh);
readBIH(ifs, bih);
writeBFH(ofs, bfh);
writeBIH(ofs, bih);
displaydata(bfh, bih);
/*reading values of pixels*/
unsigned char p; //value of a single pixel
short** the_image; //input image array
the_image = new short* [dwordValue(bih.biWidth)];
for (int i = 0; i < dwordValue(bih.biWidth); i++)
{
the_image[i] = new short [dwordValue(bih.biHeight)];
}
short** out_image; //output image array
out_image = new short* [dwordValue(bih.biWidth)];
for (int i = 0; i < dwordValue(bih.biWidth); i++)
{
out_image[i] = new short[dwordValue(bih.biHeight)];
}
for (int i = 0; i < dwordValue(bih.biHeight); i++)
{
for (int j = 0; j < dwordValue(bih.biWidth); j++)
{
for (int n = 0; n < 2; n++)
{
ifs.read((char*)&p, sizeof(char));
ofs.write((char*)&p, sizeof(char));
}
the_image[i][j] = (short)p;
out_image[i][j] = (short)p;
}
}
/*zera*/
for (int i = 0; i < zerosPerRow(bfh, bih); i++)
{
ifs.read((char*)&p, sizeof(char));
ofs.write((char*)&p, sizeof(char));
}
sobel(the_image, out_image, dwordValue(bih.biWidth), dwordValue(bih.biHeight), dwordValue(bih.biBitCount));
for (int i = 0; i < dwordValue(bih.biWidth); i++)
{
delete[] the_image[i];
the_image[i] = NULL;
}
delete[] the_image;
the_image = NULL;
ifs.close();
ofs.close();
char a;
cout << "File has been read. Enter anything to exit program";
cin >> a;
system("cls");
}
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////// SOBEL CODE //////////////////////////////////////////////////////////////////////////////////////
short** image, ** out_image;
long rows, cols, bits_per_pixel;
int perform_convolution(short** image, short** out_image, long rows, long cols, long bits_per_pixel)
{
char response[80];
int a, b, i, is_present, j, sum;
short max, min, new_hi, new_low;
new_hi = 250;
new_low = 16;
if (bits_per_pixel == 4) {
new_hi = 10;
new_low = 3;
}
min = 0;
max = 255;
if (bits_per_pixel == 4)
max = 16;
/*cleaning an output array*/
for (i = 0; i < rows; i++)
for (j = 0; j < cols; j++)
out_image[i][j] = 0;
printf("\n ");
for (i = 1; i < rows - 1; i++) {
if ((i % 10) == 0) { printf("%4d", i); }
for (j = 1; j < cols - 1; j++) {
/*convolution*/
/*kierunek 0*/
sum = 0;
for (a = -1; a < 2; a++) {
for (b = -1; b < 2; b++) {
sum = sum + image[i + a][j + b] *
mask_0[a + 1][b + 1];
}
}
if (sum > max) sum = max;
if (sum < 0) sum = 0;
if (sum > out_image[i][j])
out_image[i][j] = sum;
/*kierunek 1*/
sum = 0;
for (a = -1; a < 2; a++) {
for (b = -1; b < 2; b++) {
sum = sum + image[i + a][j + b] * mask_1[a + 1][b + 1];
}
}
if (sum > max) sum = max;
if (sum < 0) sum = 0;
if (sum > out_image[i][j])
out_image[i][j] = sum;
/*kierunek 2*/
sum = 0;
for (a = -1; a < 2; a++) {
for (b = -1; b < 2; b++) {
sum = sum + image[i + a][j + b] * mask_2[a + 1][b + 1];
}
}
if (sum > max) sum = max;
if (sum < 0) sum = 0;
if (sum > out_image[i][j])
out_image[i][j] = sum;
/*kierunek 3*/
sum = 0;
for (a = -1; a < 2; a++) {
for (b = -1; b < 2; b++) {
sum = sum + image[i + a][j + b] * mask_3[a + 1][b + 1];
}
}
if (sum > max) sum = max;
if (sum < 0) sum = 0;
if (sum > out_image[i][j])
out_image[i][j] = sum;
/*kierunek 4*/
sum = 0;
for (a = -1; a < 2; a++) {
for (b = -1; b < 2; b++) {
sum = sum + image[i + a][j + b] * mask_4[a + 1][b + 1];
}
}
if (sum > max) sum = max;
if (sum < 0) sum = 0;
if (sum > out_image[i][j])
out_image[i][j] = sum;
/*kierunek 5*/
sum = 0;
for (a = -1; a < 2; a++) {
for (b = -1; b < 2; b++) {
sum = sum + image[i + a][j + b] * mask_5[a + 1][b + 1];
}
}
if (sum > max) sum = max;
if (sum < 0) sum = 0;
if (sum > out_image[i][j])
out_image[i][j] = sum;
/*kierunek 6*/
sum = 0;
for (a = -1; a < 2; a++) {
for (b = -1; b < 2; b++) {
sum = sum + image[i + a][j + b] * mask_6[a + 1][b + 1];
}
}
if (sum > max) sum = max;
if (sum < 0) sum = 0;
if (sum > out_image[i][j])
out_image[i][j] = sum;
/*kierunek 7*/
sum = 0;
for (a = -1; a < 2; a++) {
for (b = -1; b < 2; b++) {
sum = sum + image[i + a][j + b] * mask_7[a + 1][b + 1];
}
}
if (sum > max) sum = max;
if (sum < 0) sum = 0;
if (sum > out_image[i][j])
out_image[i][j] = sum;
}
}
return(1);
}
int fix_edges(short** im, int w, long rows, long cols)
{
int i, j;
for (i = w; i > 0; i--) {
im[i - 1][i - 1] = im[i][i];
im[i - 1][cols - (i - 1)] = im[i][cols - 1 - (i - 1)];
im[rows - (i - 1)][i - 1] = im[rows - 1 - (i - 1)][i];
im[rows - (i - 1)][cols - (i - 1)] = im[rows - 1 - (i - 1)][cols - 1 - (i - 1)];
}
for (i = 0; i < rows; i++) {
for (j = w; j > 0; j--) {
im[i][j - 1] = im[i][j];
im[i][cols - j] = im[i][cols - j - 1];
}
}
for (j = 0; j < cols; j++) {
for (i = w; i > 0; i--) {
im[i - 1][j] = im[i][j];
im[rows - i][j] = im[rows - i - 1][j];
}
}
return(1);
}
int sobel(short** the_image, short** out_image, long rows, long cols, long bits_per_pixel) //wykrywanie krawedzi operatorem sobela
{
perform_convolution(the_image, out_image, rows, cols, bits_per_pixel);
fix_edges(out_image, 1, rows, cols);
return(1);
}
int main()
{
menuservice();
return 0;
}

Converting a char in a string array to float

I'm working on a project which takes a string input from the user of coordinates.
example of input:
"Polygons = [(1, 1), (4, 1), (4, 5), (3,5), (1, 5); (5,3), (3, 4), (6, 4), (6, 12), (3, 12)]"
One of the functions that I am making is checking the minimum/maximum X, which is clearly any number after a "(", however the problem that's bugging me is converting what's after the ( into a float to use it in calculations and number comparisons.
#include <iostream>
#include "string"
#include <stdlib.h>
#include <cstdlib>
using namespace std;
//Using a constant string for testing
string Polygon_Input = "Polygons = [(1, 1), (4, 1), (4, 5), (3,5), (1, 5); (5,3), (3, 4), (6, 4), (6, 12), (3, 12)]";
string Operation;
float Min_X = 9999;
int main()
{
getline(cin, Operation);
if (Operation == "Minimum_X")
{
for (int i; i <= Polygon_Input.length(); i++)
{
if (Polygon_Input[i] == '(')
{
float X = Polygon_Input[i + 1];
if (X < Min_X)
{
Min_X = X;
}
}
}
cout << Min_X;
}
That's not working, it always prints out 49 as Min_X
I also tried the same code with one modification, but still doesn't work.
if (Polygon_Input[i] == '(')
{
string X_As_String = Polygon_Input.substr(i + 1, i + 1);
float X = atof(X_As_String.c_str());
if (X < Min_X)
{
Min_X = X;
}
First of all, there are several problems in your code.
float Min_X = 9999;
The minimum value must be in the list. Initialize the first element as the minimum value and compare it with the rest.
if (X < Min_X)
The value X is int whereas Min_X is float. Don't compare int with float. Declare both as float and then cast if you would like an integer number.
for (int i=0; i <= Polygon_Input.length(); i++)
Pay attention to <=. It should be <.
Now the solution for your problem is
//#include <limits> // no need for this
#include <iostream>
#include <string>
#include <cstdlib>
#include <cstdlib>
using namespace std;
//Using a constant string for testing
string Polygon_Input = "Polygons = [(1, 1), (4, 1), (4, 5), (3,5), (1, 5); (5,3), (3, 4), (6, 4), (6, 12), (3, 12)]";
string Operation("Minimum_X");
//float Min_X = 9999; ?????? Why
float Min_X;
bool flag(true);
int main()
{
//getline(cin, Operation); // commented out for test
if (Operation == "Minimum_X")
{
for (int i=0; i < Polygon_Input.size(); i++)
{
if ( Polygon_Input[i] == '(' )
{
// extract X values (i.e. the first co-ordinate of a point )
std::string temp = Polygon_Input.substr(i+1, Polygon_Input.find_first_of(",",i)-i-1 );
// convert strig to float
float X = std::stof(temp);
// store first element and compare it with the rest
if(flag){
Min_X = X;
flag=false;
}
// int X = Polygon_Input[i + 1] - '0'; ????? What is this?
if (X < Min_X)
{
Min_X = X;
}
}
}
cout << Min_X << endl;
}
return 0;
}
The output is
1
which the minimum X value in the list. This code handles float values as well (i.e. (3.45, 4)). Try different values for checking.

How to solve another version of Kakuro

The problem is, in a table of (h+1)*(w+1),the first row contains w values: a[1] ... a[w] which fill in the 2rd ... (w+1)th column. The first column contains h values: b[1] ... b[h] which fill in the 2rd ... (h+1)th row. sum(a[i]) is equal to sum(b[i]).
The question is to give one possible solution: result, so that sum(result[i][K]) for a certain K, is equal to a[i] with result[i][K] != result[j][K] (i != j and 0 < i < h+1). And the same rule for rows. PS: All the integers are positive.
For example:
a[] = {10, 3, 3}, b[] = {9, 7}
// 10 3 3
// 9 6 2 1
// 7 4 1 2
result = {6, 2, 1;
4, 1, 2}
It is like Kakuro but not the same. I cannot figure out which algorithm to apply, if anyone knows how to solve it, please give me some help. Thanks a lot.
You can always solve your problem with backtracking. Basic idea here: from top-to-bottom and left-to-right try a valid value in the partially filled table, backtrack when this value doesn't lead to a solution.
Minimal example in C++ with annotated solve:
#include <algorithm>
#include <iostream>
#include <iterator>
#include <memory>
class Problem {
public:
template<class AIter, class BIter>
Problem(AIter abegin, AIter aend, BIter bbegin, BIter bend)
: m_width(std::distance(abegin, aend))
, m_height(std::distance(bbegin, bend))
, m_table(new int[(m_width + 1) * (m_height + 1)])
{
std::fill(m_table.get(), m_table.get() + (m_width + 1) * (m_height + 1), 0);
for(size_t i = 0; i < m_width; ++i)
m_table[i + 1] = *abegin++;
for(size_t j = 0; j < m_height; ++j)
m_table[(j + 1) * (m_width + 1)] = *bbegin++;
}
bool Solve() { return solve(0, 0); }
int operator()(size_t i, size_t j) const;
private:
int a(size_t i) const { return m_table[i + 1]; }
int b(size_t j) const { return m_table[(j + 1) * (m_width + 1)]; }
int get(size_t i, size_t j) const { return m_table[(j + 1) * (m_width + 1) + i + 1]; }
void set(size_t i, size_t j, int value) { m_table[(j + 1) * (m_width + 1) + i + 1] = value; }
int colSum(size_t i) const;
int rowSum(size_t j) const;
bool solve(size_t i, size_t j);
size_t m_width, m_height;
std::unique_ptr<int[]> m_table; // (width + 1) x (height + 1)
};
int Problem::colSum(size_t i) const {
int sum = 0;
for(size_t j = 0; j < m_height; ++j)
sum += get(i, j);
return sum;
}
int Problem::rowSum(size_t j) const {
int sum = 0;
for(size_t i = 0; i < m_width; ++i)
sum += get(i, j);
return sum;
}
// solves column-wise using backtracking
bool Problem::solve(size_t i, size_t j) {
size_t width = m_width, height = m_height;
// past last column?
if(i >= width) {
// found solution
return true;
}
// remainder in column and row
int remColSum = a(i) - colSum(i);
int remRowSum = b(j) - rowSum(j);
// early break
if(remColSum <= 0 || remRowSum <= 0)
return false;
// starting at the minimal required value (1 or remColSum if on last row)
int startValue = j + 1 < height ? 1 : remColSum;
// remaining row sum cannot support the starting value
if(remRowSum < startValue)
return false;
// end value minimum remaining sum
int endValue = remColSum < remRowSum ? remColSum : remRowSum;
// on last element must equal starting value
if(i + 1 == width && j + 1 == height && startValue != endValue)
return false;
// column-wise i.e. next cell is (i, j + 1) wrapped
int nextI = i + (j + 1) / height;
int nextJ = (j + 1) % height;
for(int value = startValue; value <= endValue; ++value) {
bool valid = true;
// check row up to i
for(size_t u = 0; u < i && valid; ++u)
valid = (get(u, j) != value);
// check column up to j
for(size_t v = 0; v < j && valid; ++v)
valid = (get(i, v) != value);
if(!valid) {
// value is invalid in partially filled table
continue;
}
// value produces a valid, partially filled table, now try recursing
set(i, j, value);
// upon first solution break
if(solve(nextI, nextJ))
return true;
}
// upon failure backtrack
set(i, j, 0);
return false;
}
int Problem::operator()(size_t i, size_t j) const {
return get(i, j);
}
int main() {
int a[] = { 10, 3, 3 };
int b[] = { 9, 7 };
size_t width = sizeof(a) / sizeof(*a);
size_t height = sizeof(b) / sizeof(*b);
Problem problem(a, a + width, b, b + height);
if(!problem.Solve()) {
std::cout << "No solution" << std::endl;
}
for(size_t j = 0; j < height; ++j) {
if(j == 0) {
std::cout << " ";
for(size_t i = 0; i < width; ++i)
std::cout << " " << a[i];
std::cout << std::endl;
}
std::cout << b[j];
for(size_t i = 0; i < width; ++i) {
int value = problem(i, j);
if(value == 0)
std::cout << " ";
else
std::cout << " " << value;
}
std::cout << std::endl;
}
return 0;
}

How to initialize static member array with a result of a function?

I'm translating such fragment of this Python file to C++:
SIDE = 3
LINES = []
for y in range(SIDE):
row = tuple((x, y) for x in range(SIDE))
LINES.append(row)
for x in range(SIDE):
col = tuple((x, y) for y in range(SIDE))
LINES.append(col)
LINES.append(tuple((x, x) for x in range(SIDE)))
LINES.append(tuple((SIDE - x - 1, x) for x in range(SIDE)))
LINES holds (x, y) coordinates of possible lines in Tic Tac Toe game. So for SIDE = 3 it holds:
[((0, 0), (1, 0), (2, 0)),
((0, 1), (1, 1), (2, 1)),
((0, 2), (1, 2), (2, 2)),
((0, 0), (0, 1), (0, 2)),
((1, 0), (1, 1), (1, 2)),
((2, 0), (2, 1), (2, 2)),
((0, 0), (1, 1), (2, 2)),
((2, 0), (1, 1), (0, 2))]
SIDE value can change.
What I've tried
Performance is crucial (that's why I reached for C++), so I would like to calculate LINES only once. Thus, I've chosen to implement LINES as a static member of the class TicTacToeState.
I started with such code:
static char init_lines() {
return 'a';
}
class TicTacToeState {
static char LINES;
};
char TicTacToeState::LINES = init_lines();
It works. How to change LINES to an array? Maybe vector will be better? With pairs?
Maybe static member is not the best choice, maybe there is an easier way?
How would you translate it to C++?
We know the size of LINES, it's always 2 * SIDE + 2.
Special requirement
All C++ code must be in one .cpp file, no headers. Why? Because this is fragment of a library for bot competitions and it's typical that you can submit only one file.
In C++ you can initialize static array members using group initialization
static int a[10] = {5}; //this will initialize first position item with 5 and rest with 0s
static char b[2] = {'b', 'b'};
static int c[2][2] = { {1,1}, {1,2} };
int main()
{
cout<< a[0] << endl; //output: 5
cout<< a[1] << endl; //output: 0
cout<< b[0] << endl; //output: b
cout<< c[0][1] << endl; //output: 1
}
Although the fact is you need to know size of the array not like in Python's list that are dynamically
If you need to insert to the table values calculated dynamically the best way to do this is to create factory method
static int** fact(int width, int height)
{
int** a;
a = new int*[width]; //we can do it when it is DYNAMIC array!
a[0] = new int[height];
a[1] = new int[height];
for(int i = 0; i < width; i++)
for(int k = 0; k < height; k++)
a[i][k] = i*k;
return a;
}
static int** c = fact(2, 2); //you can call it with your SIDE var
int main()
{
cout<< c[1][1] << endl; //output: 1
}
Of course you can process it in loops
The same approach will be proper when you will decide to use std Vector class which is equvalent of Python's dynamic list
I suppose you could do this using a lambda function like this:
#include <vector>
#include <iostream>
const auto SIDE = 3U;
struct coord
{
unsigned x;
unsigned y;
coord(unsigned x, unsigned y): x(x), y(y) {}
};
static const auto lines = [] // lambda function
{
// returned data structure
std::vector<std::vector<coord>> lines;
for(auto y = 0U; y < SIDE; ++y)
{
lines.emplace_back(); // add a new line to back()
for(auto x = 0U; x < SIDE; ++x)
lines.back().emplace_back(x, y); // add a new coord to that line
}
for(auto x = 0U; x < SIDE; ++x)
{
lines.emplace_back();
for(auto y = 0U; y < SIDE; ++y)
lines.back().emplace_back(x, y);
}
lines.emplace_back();
for(auto i = 0U; i < SIDE; ++i)
lines.back().emplace_back(i, i);
lines.emplace_back();
for(auto i = 0U; i < SIDE; ++i)
lines.back().emplace_back(SIDE - i - 1, i);
return lines;
}(); // NOTE: () is important to run the lambda function
int main()
{
for(auto const& line: lines)
{
std::cout << "(";
for(auto const& coord: line)
std::cout << "(" << coord.x << ", " << coord.y << ")";
std::cout << ")\n";
}
}
Output:
((0, 0)(1, 0)(2, 0))
((0, 1)(1, 1)(2, 1))
((0, 2)(1, 2)(2, 2))
((0, 0)(0, 1)(0, 2))
((1, 0)(1, 1)(1, 2))
((2, 0)(2, 1)(2, 2))
((0, 0)(1, 1)(2, 2))
((2, 0)(1, 1)(0, 2))