Storing input file into a 2d array C++ - c++

I have an input file that I would like to use by using cin.
My input file contains a list of 9x9 numbers, such as:
1 2 3 4 5 6 7 8 9
2 2 3 4 5 6 7 8 9
3 2 3 4 5 6 7 8 9
4 2 3 4 5 6 7 8 9
5 ...
6 ...
7 ...
8 ...
9 ...
I want to store these values into a 2d array, so they would look like:
int board[9][9] = {{1, 2, 3, 4, 5, 6, 7, 8, 9},
{2, 2, 3, 4, 5, 6, 7, 8, 9},
{3, 2, 3, 4, 5, 6, 7, 8, 9},
{4, 2, 3, 4, 5, 6, 7, 8, 9},
{5, 2, 3, 4, 5, 6, 7, 8, 9},
{6, 2, 3, 4, 5, 6, 7, 8, 9},
{7, 2, 3, 4, 5, 6, 7, 8, 9},
{8, 2, 3, 4, 5, 6, 7, 8, 9},
{9, 2, 3, 4, 5, 6, 7, 8, 9}};
I tried to do:
int board[9][9];
for (int i=0;i<9;i++) {
for (int j=0;j<9;j++) {
std::cin >> board[i][j];
}
}
However, I don't think it's working. I'm going to use them as inputs when I run my code.

This works for me in GCC 4.9.0 with C++11:
Sample Code:
#include <iostream>
int main() {
int board[9][9];
for (int i = 0; i < 9; i++) {
for (int j = 0; j < 9; j++) {
std::cin >> board[i][j];
}
}
for (int i = 0; i < 9; i++) {
for (int j = 0; j < 9; j++) {
std::cout << board[i][j];
}
std::cout << std::endl;
}
return 0;
}
You should change C array for std::vector or other container from STL, it provide a lot of benefice (automatic memory management, array bound check, etc...). If you could use C++11, the new range for loop is a big improvement too (syntactical and performance wise, it avoid error as off by one, incorrect bounds, etc...).
Here is a C++11 version:
#include <iostream>
#include <vector>
int main() {
typedef std::vector<int> row_t;
typedef std::vector<row_t> board_t;
board_t board(9, row_t(9));
for (auto& row : board) {
for (auto& cell : row) {
std::cin >> cell;
}
}
for (const auto& row : board) {
for (auto cell : row) {
std::cout << cell;
}
std::cout << std::endl;
}
return 0;
}

The inner loop is wrong, there you have j++ as the loop condition. And as in the first iteration j will be zero (which in C++ is the same as false) the loop will not iterate at all. Besides, the inner loop is missing a semicolon, so it shouldn't even compile.

Related

std::sort of vector of struct sorted by field where all are zeros causing different results for different length of vector

Hello I have this piece of code for sorting vector. Basically sorting vector of structure where at the start all elements of vector has score equal to 0. I thought that if all elements equals score 0 sort will keep for multiple sort but only when uint8_t length = 17; is under 17. It is probably caused by implementation of sort that 16 is somehow important for sorting.
reference code here https://www.onlinegdb.com/C_wj9_87L
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
typedef struct {
uint8_t index;
uint8_t score;
} test;
uint8_t length = 17;
int main()
{
std::vector<test> vec;
for (uint8_t i = 0; i < length; i++) {
vec.push_back({i, 0});
}
for (uint8_t j = 0; j < 3; j++) {
std::sort(vec.begin(), vec.end(), [](const test &m1, const test &m2) {
return m1.score > m2.score;
});
for (uint8_t i = 0; i < length; i++) {
std::cout << (int)vec[i].index << ", ";
}
std::cout << "\n";
}
return 0;
}
Result with uint8_t length = 17;
8, 16, 15, 14, 13, 12, 11, 10, 9, 0, 7, 6, 5, 4, 3, 2, 1,
9, 1, 2, 3, 4, 5, 6, 7, 0, 8, 10, 11, 12, 13, 14, 15, 16,
0, 16, 15, 14, 13, 12, 11, 10, 8, 9, 7, 6, 5, 4, 3, 2, 1,
Result with uint8_t length = 16;
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
Do you know what is going wrong here ?
Expected result is always same sort so indexes will remain its position.
Yeah the answer is stable_sort Thank you #Mat

Product modulo random numbers

A prime p is fixed. A sequence of n numbers is given, each from 1 to p - 1. It is known that the numbers in the sequence are chosen randomly, equally likely and independently from each other. Choose some numbers from the sequence so that their product, taken modulo p, is equal to the given number x. If no numbers are selected, the product is considered equal to one.
Input:
The first line contains three integers separated by spaces: the length of the sequence n, the prime number p and the desired value x
(n=100, 2<=p<=10^9, 0<x<p)
Next, n integers are written, separated by spaces or line breaks: the sequence a1, a2,. . ., an
(0 <ai <p)
Output:
Print the numbers from the sequence whose product modulo p is equal to x. The order in which numbers are displayed is not important. If there are several possible answers, print any of them
Example:
INPUT:
100 11 4
9 6 1 1 10 4 9 10 3 1 10 1 6 8 3 3 9 8
10 3 7 7 1 3 3 1 5 2 10 4 1 5 6 7 2 6
2 8 3 3 6 7 6 3 1 5 10 2 2 10 9 6 8 6
2 10 3 2 7 4 3 2 8 6 4 1 7 2 10 8 4 9
7 9 8 7 4 7 3 2 8 2 3 7 1 5 2 10 7 1 8
6 4 10 10 3 6 10 2 1
OUTPUT:
4 6 10 9
My solution:
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int main()
{
int n,p,x,y,m,k,tmp;
vector<int> v;
cin >> n >> p >> x;
for (int i = 0; i<n; i++){
cin >> tmp;
v.push_back(tmp);
}
sort(v.begin(), v.end());
v.erase(v.begin(), upper_bound(v.begin(), v.end(), 1));
k=-1;
while(1){
k++;
m = 1;
y = x+p*k;;
vector<int> res;
for (int i = 0; i<n; i++){
if (y == 1) break;
if ( y%v[i] == 0){
res.push_back(v[i]);
m*=v[i];
m%=p;
y = y/v[i];
}
}
if (m==x) {
for (int i = 0; i<res.size(); i++){
cout << res[i] << " ";
}
break;
}
}
return 0;
}
In my solution, I used condition (y=x+k*p, where y is the product of numbers in the answer, and k is some kind of natural number). And also iterated over the value k.
This solution sometimes goes beyond the allotted time. Please tell me a more correct algorithm.
I would consider a backtracking routine over the hashed multiset of the input list. Since p is a prime, at any point we can consider if the current multiple, m, has (multiplicative_inverse(m, p) * x) % p in our multiset (https://en.wikipedia.org/wiki/Multiplicative_inverse). If it exists, we're done. Otherwise, try multiplying either by the same number we are currently visiting in the multiset, or by the next one (keep the result of the multiplication modulo p).
Please see comment below for a link to example code in Python. The example you gave has trivial solutions so it would be helpful to have some non-trivial, as well as challenging examples to test and refine on. Please also clarify if more than one number is expected in the output.
You can use dynamic programming approach. It requires O(p) memory cells and O(p*n) loop iterations. There is possible several optimization (to exclude processing input duplicates, or print longest/shortest selection chain). Following is simplest and basic DP-program, demonstrating this approach.
#include <stdio.h>
#include <stdlib.h>
int data[] = {
9, 6, 1, 1, 10, 4, 9, 10, 3, 1, 10, 1, 6, 8, 3, 3, 9, 8,
10, 3, 7, 7, 1, 3, 3, 1, 5, 2, 10, 4, 1, 5, 6, 7, 2, 6,
2, 8, 3, 3, 6, 7, 6, 3, 1, 5, 10, 2, 2, 10, 9, 6, 8, 6,
2, 10, 3, 2, 7, 4, 3, 2, 8, 6, 4, 1, 7, 2, 10, 8, 4, 9,
7, 9, 8, 7, 4, 7, 3, 2, 8, 2, 3, 7, 1, 5, 2, 10, 7, 1, 8,
6, 4, 10, 10, 3, 6, 10, 2, 1
};
struct elm {
int val; // Value
int prev; // from which elemet we come to this
int n; // add loop cound for prevent multiple use same val
};
void printsol(int n, int p, int x, const int *in) {
struct elm *dp = (struct elm *)calloc(p, sizeof(struct elm));
int i, j;
for(i = 0; i < n; i++) // add initial elements into DP array
dp[in[i]].val = in[i];
for(i = 0; i < n; i++) { // add elements, one by one, to DP array
if(dp[in[i]].val <= 1) // skip secondary "1" multipliers
continue;
for(j = 1; j < p; j++)
if(dp[j].val != 0 && dp[j].n < i) {
int y = ((long)j * in[i]) % p;
dp[y].val = in[i]; // current value, for printout
dp[y].prev = j; // reference to prev element
dp[y].n = n; // loop num, for prevent double reuse
if(x == y && dp[x].n > 0) {
// targed reached - print result, by iterate linklist
int mul = 1;
while(x != 0) {
printf(" %d ", dp[x].val);
mul *= dp[x].val; mul %= p;
x = dp[x].prev;
}
printf("; mul=%d\n", mul);
free(dp);
return;
}
} // for+if
} // for i
free(dp);
}
int main(int argc, char **argv) {
printsol(100, 11, 4, data);
return 0;
}

Why is this dynamic array implementation slower than std::vector<T>?

Bellow is a simple template array implementation using malloc and realloc
Stepping through with a debugger, there were less code steps than vector.
However, when timing using std::chrono, std::vector is still faster.
Why is this?
(Compiling using gnu cc v9)
#include <../array.hpp>
#include <../console.hpp>
#include <vector>
int main() {
console::time("array");
array<int> a { 1, 2, 3, 4, 5, 6, 7 };
console::timeEnd("array");
for (unsigned int i = 0; i < a.size(); i++) {
console::log(std::to_string(a[i]));
}
array<int> b { 1, 2, 3, 4, 5, 6, 8 };
if (a != b) {
console::log("a != b");
}
array<int> c { 1, 2, 3, 4, 5, 6, 7 };
if (a == c) {
console::log("a == c");
}
console::time("std::vector");
vector<int> v { 1, 2, 3, 4, 5, 6, 7 };
console::timeEnd("std::vector");
for (unsigned int i = 0; i < v.size(); i++) {
console::log(std::to_string(v[i]));
}
return 0;
};
array: 27µs - timer ended
1
2
3
4
5
6
7
a != b
a == c
std::vector: 2655ns - timer ended
1
2
3
4
5
6
7
Full implementation [here](https://gist.github.com/universefullofthings/ac933d64158217478a02df7bdcc8f319?.

C++: std::map, find cycles, algorithm

Suppose the following data structure:
std::map <int, std::vector<int> > M,
where val is represented by the sequence of vertices of the graph, and the key is the first vertex of the sequence. For example
{1} {1, 8, 12, 7}
{4} {4, 3, 5}
{7} {7, 9, 13, 18, 0, 2}
{2} {2, 11, 1}
{5} {5, 17, 10, 4}
{9} {9, 6, 19, 14}
{14} {14, 15, 9}
How to find all cycles (analogous start and end vertex) from the segments {}
C1: {1 8 12 7} {7 9 13 18 0 2} {2 11 1}
C2: {4 3 5} {5 17 10 4}
C3: {9 6 19 14} {14, 15, 9}
and how to avoid the duplicate sequence of segments, with the low time complexity (map may contain hundreds of thousands of sequences). Any cycle may contain n segments {}, where n>=1.
The initialization phase:
std::map <int, std::vector <int> > M;
M[1] = std::vector<int>{ 1, 8, 12, 7 };
M[4] = std::vector<int>{ 4, 3, 5 };
M[7] = std::vector<int>{ 7, 9, 13, 18, 0, 2 };
M[2] = std::vector<int>{ 2, 11, 1 };
M[5] = std::vector<int>{ 5, 17, 10, 4 };
M[9] = std::vector<int>{ 9, 6, 19, 14 };
M[14] = std::vector<int>{ 14, 15, 9 };
The draft of the algorithm:
std::vector<std::vector <int> > R;
for (auto im = M.begin(); im != M.end();)
{
std::vector<int> r, ri = im->second;
for(;;)
{
r.insert(r.end(), ri.begin(), ri.end());
ri = M[r.back()];
im = M.erase(M.find(im->first));
if (r.back() == r.front()) break;
}
R.push_back(r);
}
Unfortunately, the repeated deletion represents an expensive operation... I hope, there is a more beautiful and efficient solution :-)
Thanks for your help...
First, your inner loop needs to be a function (what if the paths don't cycle?)
Then, declare failure if either
The end node is numerically less than the start node (could be a cycle, but is not a canonical, so we won't print this shifted version)
The end node isn't found in the master table of paths
And that leads to a solution:
bool try_follow(int from, std::vector<int>& result)
{
int current = from;
while (true) {
auto path = M.find(current);
if (path == M.end()) return false;
current = path->second.back();
if (current < from) return false;
result.insert(result.end(), path->second.begin()+1, path->second.end());
if (current == from) return true;
}
}
int main(void)
{
for( auto& kvp : M )
{
std::vector<int> x;
if (try_follow(kvp.first, x)) {
std::cout << kvp.first;
for( int y : x )
std::cout << " - " << y;
std::cout << std::endl;
}
}
}
Demo: https://rextester.com/DWWZ9457
My first crack:
for (auto it : M)
{
if (it.first < it.second.back() && it.second.front() == M[it.second.back()].back())
std::cout << "Cycle between " << it.first << " and " << it.second.back() << '\n';
}
Won't find cycles that involve 3+ paths, of course.

Sorting 2D Vector Array Based On a Column

I have a 2d vector array which contains :
row id r b main
1 0 26 3
2 1 11 2
3 1 46 4
4 2 26 1
5 3 11 2
I want to sort every row based on its "main"-column value
smaller "main"-column.
smaller value => the entire row should be on the top.
if there is tow rows or more and there "main"-column have the same value, I want to check "r"-column.
smaller value => the entire row should be on the top.
after sorting it will look like this:
row id r b main
4 2 26 1
2 1 11 2
5 3 11 2
1 0 26 3
3 1 46 4
Try using std::sort like
using int_arr = std::array<int, 4>;
std::sort(std::begin(arr), std::end(arr), [](const int_arr& a, const int_arr& b){
return a[3] != b[3] ? a[3] < b[3] : a[1] < b[1];
});
Demo
#include <iostream>
#include <array>
#include <algorithm>
int main() {
using int_arr = std::array<int, 4>;
int_arr arr[5] = {
{1, 0, 26, 3},
{2, 1, 11, 2},
{3, 1, 46, 4},
{4, 2, 26, 1},
{5, 3, 11, 2}
};
for(const auto& i_arr : arr) {
for(const auto& i : i_arr)
std::cout<< i <<", ";
std::cout << "\n";
}
std::cout << "**************\n";
std::sort(std::begin(arr), std::end(arr), [](const int_arr& a, const int_arr& b){
return a[3] != b[3] ? a[3] < b[3] : a[1] < b[1];
});
for(const auto& i_arr : arr) {
for(const auto& i : i_arr)
std::cout<< i <<", ";
std::cout << "\n";
}
}
OutPut
1, 0, 26, 3,
2, 1, 11, 2,
3, 1, 46, 4,
4, 2, 26, 1,
5, 3, 11, 2,
**************
4, 2, 26, 1,
2, 1, 11, 2,
5, 3, 11, 2,
1, 0, 26, 3,
3, 1, 46, 4,