Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 6 years ago.
Improve this question
A recursive puzzle You have been given a puzzle consisting of a row of squares each containing an integer, like this
The circle on the initial square is a marker that can move to other squares along the row. At each step in the puzzle, you may move the marker the number of squares indicated by the integer in the square it currently occupies. The marker may move either left or right along the row but may not move past either end. For example, the only legal first move is to move the marker three squares to the right because there is no room to move three spaces to the left. The goal of the puzzle is to move the marker to the 0 at the far end of the row. In this configuration, you can solve the puzzle by making the following set of moves:
https://i.stack.imgur.com/yUz3P.png
a. Write an algorithm void SolvePuzzle(int start, int squares[1..n]) that takes a starting position of the marker along with the array of squares. The algorithm should solve the puzzle from the starting configuration and display all moves required to reach the 0 at the end of the sequence. You may assume all the integers in the array are positive except for the last entry, the goal square, which is always zero. The values of the elements in the array must be the same after calling your function as they are beforehand, (which is to say if you change them during processing, you need to change them back!)
void SolvePuzzle(int start, int squares[]){
if(squares[start]==0)
return;
else{
cout<<squares[start]<<" ";
if(squares[start]%2==0)
SolvePuzzle( start+squares[start],squares);
else
SolvePuzzle( start-squares[start],squares);
}
}
int main(){
int arraytest[] = { 3, 6, 4, 1, 3, 4, 2, 5, 3, 0 };
SolvePuzzle(arraytest[0],arraytest);
return 0;
}
i solved like this but i need Correct mistakes in If statement
The problem you are facing, even if one could not really tell from your description, is that you don't really know if you have to move left or right to solve the puzzle.
The simplest approach is just try to go left, if it works you solved it, otherwise you go right. This means that you have to change your function, otherwise you cannot really return the right path or the answer.
It may appear like this:
#include <vector>
#include <iostream>
bool SolvePuzzle(int squares[], int size, int position,
std::vector<bool>& go_right_sol){
if(squares[position]==0){
return true;
}
int leftPos = position - squares[position];
int rightPos = position + squares[position];
if(rightPos < size && SolvePuzzle(squares, size, rightPos, go_right_sol)){
go_right_sol.insert(go_right_sol.begin(), true);
return true;
}
if(leftPos > 0 && SolvePuzzle(squares, size, leftPos, go_right_sol)){
go_right_sol.insert(go_right_sol.begin(), false);
return true;
}
return false;
}
int main(){
int arraytest[] = { 3, 6, 4, 1, 3, 4, 2, 5, 3, 0 };
int arraysize = 10;
std::vector<bool> solution;
SolvePuzzle(arraytest, arraysize, 0, solution);
for(int i = 0; i < solution.size(); i++){
std::cout << ((solution[i]) ? "right" : "left") << " - ";
}
std::cout << std::endl;
return 0;
}
Related
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 2 years ago.
Improve this question
I'm looking for a C++ way using vector to get all the diagonals of a (square) matrix, represented as a 2d vector.
matrix = [
[1,2,3,4],
[5,1,2,3],
[9,5,1,2]]
But I have trouble coming up with a way to generate all the diagonals. The output I'm looking for is:
"[9]", "[5, 5]", "[1, 1, 1]", "[2, 2, 2]", "[3, 3]", "[4]".
I found answers but all of them are in python. I need it in C++
The solution is rather straigt forward. I will first show the code and then explain it.
#include <iostream>
#include <vector>
using Matrix = std::vector<std::vector<int>>;
int main() {
Matrix matrix{
{1,2,3,4},
{5,1,2,3},
{9,5,1,2}
};
// Shortcut for the width and height of the matrix
const size_t width{ matrix.at(0).size() };
const size_t height{ matrix.size() };
// Set start row and start column
size_t startRow{ height-1 };
size_t startColumn{ 0 };
size_t column{};
// for all possible start positions
do {
// set the row and column values to the start values
size_t row{ startRow };
column = startColumn;
//Now go through the diagonal
do {
// Show current value
std::cout << matrix[row][column] << ' ';
// Set next position in the diagonal
++row; // Go one row down
++column; // Go one column to the right
// As long as we do not cross the border
} while ((row < height) && (column < width));
std::cout << '\n';
// Calculate new start row and start column
// If possible
if (startRow > 0) {
// Go up
--startRow;
}
else {
// Else go right
++startColumn;
}
} while (startColumn < width);
return 0;
}
So, we need to play a little bit with indices.
The indices for a diagonal are very simple. Simply start at a startPosition,then we increment the row and the column in each step, until we hit the border.
For the start positions of the diagonal, we will start at the low left border. Then we will keep the column and decrement the row. If the row is 0 then we go to the right, until we hit the border.
All this can be formulated very easily in C++.
I am currently working on a 15 puzzle programming assignment. My question here is about how I would go about swapping the empty tile with an adjacent tile.
So, for example, let's go with the initial setup board.
I have:
int originalBoard[4][4] = {
{1 , 2, 3, 4},
{5 , 6, 7, 8},
{9 ,10,11,12},
{13,14,15, 0}};
So here, the locations of 12, 15, and 0 (the empty tile) in the array are [3][4], [4][3], and [4][4] respectively. What would be a method of swapping 0 out with either 12 or 15?
What I had in mind for this was creating a loop that would keep track of the empty tile every time I made a move.
I believe an optimal method would be to have two functions. 1 that would update the location of the empty tile, and 1 to make the move.
So, right off the top of my head I would have:
void locateEmptyTile(int& blankRow, int& blankColumn, int originalBoard[4][4])
{
for (int row = 0; row < 4; row++)
{
for (int col = 0; col < 4; col++)
{
if (originalBoard[row][col] == 0)
{
blankRow = row;
blankColumn = col;
}
}
}
}
void move(int& blankRow, int& blankColumn, int originalBoard[4][4])
{
}
And in my main function I would have the variables: int blankRow and int blankColumn
Now, how would I take that data from locateEmptyTile and apply it into the move function in the relevant practical manner? The process does not currently connect within my head.
I appreciate any little bits of help.
If you're just asking for swap function you can use std::swap:
#include <algorithm> // until c++11
#include <utility> // since c++11
...
int m[3][3];
...
//somewhere in the code
std::swap(m[i][j], m[j][i]); // this swaps contents of two matrix cells
...
Or you can just write where you want to swap contents of two variables (in example int a and int b):
int temp = a;
a = b;
b = temp;
As you can see swapping is the same as with normal arrays, c++ does not know if you are swapping two matrix cells or two array elements, it just knows that you are swapping two memory blocks with certain type.
A basic swap concept (pre-C++11) is hold a temporary variable. Simply...
template<typename T, typename U>
void swap(T& lhs, U& rhs) {
T t = lhs;
lhs = rhs;
rhs = t;
}
So, you don't need to reference blankRow and blankCol, you just need to reference the values on the grid. Lets say that you want to swap what you know is blank positioned at (2, 1) with (2, 2)...
swap(originalBoard[2][1], originalBoard[2][2]);
... will swap the values within originalBoard.
If you are using C++11 or later, just use std::swap() to swap positions. That's exactly what it does.
If you would like originalBoard to be immutable an result in a totally different board, just copy it first before applying the switch.
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 6 years ago.
Improve this question
Given adjacency relation like
3 -> 4
1-> 3
Etc..
How do I construct a graph of it. I want a easier implementation which can be understood by a beginner. I know about self referential structures. Please help
Why don't you use Adjacency Matrix, it's pretty simple and easy.
Adjacency matrices are matrices which define relations between the vertices of a graph.
See in the example above, you have an edge going from vertex 1 to 2, so there is a 1 at the index [1][2] of adjacency matrix, similar is the case with [1][3] and so on.
And you don't have any edge going from 1 to 5, so there is a 0 at index [1][5], and so on.
You can also use Adjacency List, now go ahead and google it to have some understanding of how to use Adjacency Matrices and Adjacency Lists, and come back with some real problem then.
EDIT
I see, you don't have any understanding of how to implement a graph, let me write some examples for you using Adjacency Matrix.
I'm assuming that you know how to allocate a 2D array in c++.
Now, if you want to create an adjacency matrix for a graph containing n vertices, simply create a 2D array of size n x n and initialize all of the elements in it with 0.
int** createAdjacencyMatrix(int n){
int** graph = new int*[n];
for (int i = 0; i < n; i++){
graph[i] = new int[n];
for (int j = 0; j < n; j++){
graph[i][j] = 0;
}
}
return graph;
}
There you go, call this function, and you've created yourself an Adjacency Matrix.
int** graph = createAdjacencyMatrix(5);
Now, you can do whatever you want to do with your graph (For now, it doesn't have any edges).
To have edges in it, simply place 1 wherever you want to put an edge.
void putEdge(int** graph, int startFrom, int endAt, int totalVertices){
if (startFrom >= 1 && startFrom <= totalVertices && endAt >= 1 && endAt <= totalVertices){
graph[startFrom - 1][endAt - 1] = 1; // Because c++ uses 0 based indexing, so 1 will be stored at 0, 2 at 1 and so on.
}
}
Now, simply call this function, and add some edges to your graph.
So i'm gonna put some edges and create the above shown graph in it.
putEdge(graph, 1, 2, 5);
putEdge(graph, 1, 3, 5);
putEdge(graph, 1, 4, 5);
putEdge(graph, 2, 3, 5);
putEdge(graph, 3, 2, 5);
putEdge(graph, 5, 2, 5);
putEdge(graph, 4, 4, 5);
Now, you can do whatever you want with your graph, like should we calculate how many outgoing edges vertex 1 has?
For this, you can simply loop through the row 1
int noOfOutgoingEdges(int** graph, int vetex, int totalVertices){
if (vertex < 1 || vertex > totalVertices)
return -1;
int count = 0;
for (int i = 0; i < totalVertices; i++){
if (graph[vertex - 1][i] == 1)
count++;
}
return count;
}
At the end, you should de-allocate the allocated memory for adjacency graph.
void deallocateGraph(int** graph, int totalVertices){
for (int i = 0; i < totalVertices; i++)
delete[] graph[i];
delete[] graph;
}
So, i think by now, you'd have much better understanding.
I've implemented the graph with using just the functions, and passing adjacency matrix to them (my bad), I strongly recommend to implement the Graph in a class, which handles all of the Graph stuff itself, and you don't have to pass adjacency matrix to it, you shouldn't even have to know whether the Graph class is implemented using Adjacency Matrix or some other method (of course when using the class, not implementing it)
You class should be like this:
class Graph{
int** adjMatrix;
int totalVertices;
public:
Graph(int totalVertices);
void putEdge(int startFrom, int endAt);
int noOfOutgoingEdges(int vertex);
int noOfIncomingEdges(int vertex);
~Graph();
};
Now, go ahead and implement this class and add whatever functions you want in there.
Use proper abstraction level. You want to represent each node as an int with a set of neightbours ?
map<int, set<int>> neighbours {
{ 1, { 2, 3, 4} },
{ 2, { 3 }},
{ 3, { 2 }},
{ 4, { 4 }},
{ 5, { 2 }}
};
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 6 years ago.
Improve this question
So, I have a pretty good idea of how to implement the majority of the program. However, I am having a hard time coming up with an algorithm to add the hints of array locations adjacent to mines. The real trouble I am seeing is that the edge cases almost make it like you have two functions to deal with it (I have 20 line max on all functions). I know that from the position of the mine we want a loop to check row - 1 to row +1 and col -1 to col +1, but is it possible to do this in one function with the code I have for the game? If so, some advice would be great!
EDIT!
SO I think I have come up with the algorithm that works for all cases, but it is outputting bad info. I am pretty sure it is due to improper casting, but I am unable to see what's wrong.
Here are the two functions I wrote to add the hints:
void add_hints_chk(char ** game_board, int cur_row, int cur_col, int
rows, int cols)
{
int row_start = 0, row_end = 0, col_start = 0, col_end = 0;
if (cur_row - 1 < 0)
{
//Top edge case
row_start = 0;
}
else
{
row_start = cur_row - 1;
}
if (cur_row + 1 > rows - 1)
{
//bottom edge case
row_end = rows - 1;
}
else
{
row_end = cur_row + 1;
}
if (cur_col - 1 < 0)
{
//Left edge case
col_start = 0;
}
else
{
col_start = cur_col - 1;
}
if (cur_col - 1 > cols - 1)
{
//Right edge case
col_end = cols - 1;
}
else
{
col_end = cur_col + 1;
}
add_hints(game_board, row_start, row_end, col_start, col_end);
}
void add_hints(char **board, int row_start, int row_end, int col_start,
int col_end)
{
int tmp_int = 0;
for (int i = row_start; i <= row_end; i++)
{
for (int j = col_start; j <= col_end; j++)
{
if (board[i][j] != '*')
{
if (board[i][j] == ' ')
{
tmp_int = 1;
board[i][j] = (char)tmp_int;
}
else
{
tmp_int = (int)board[i][j];
tmp_int++;
board[i][j] += (char)tmp_int;
}
}
}
}
}
So, when I print the array, I get the little box with a q-mark in it. Am I converting tmp_int back to a char incorrectly?
There are different strategies to handle this. One simple strategy is creating a larger grid (add one line on each side) that is initialized with no bombs; make the board a view that hides the borders. With this strategy you know that you can step out of the game board without causing issues (since the data structure has an additional row).
Alternatively you can test whether the coordinates are within the valid range before calling the function that tests, or as the first step within that function.
Also you can consider precalculating the values for all of the map, whenever you add a bomb to the board during the pre-game phase, increment the counter of bombs in the vicinity for all of the surrounding positions. You can use either of the above approaches to handle the border conditions.
For any cell, C, there are 8 possible locations to check:
# # #
# C #
# # #
Before extracting data from the array, each outer location must be boundary checked.
You may be able to generalize, for example, if the value (column - 1) is out of bounds, you don't need to check 3 locations.
In your case, I would go with the brute force method and check each outer cell for boundary before accessing it. If profiling identifies this as the primary bottleneck, the come back and optimize it. Otherwise move on.
Edit 1: Being blunt
int C_left = C_column - 1;
int C_right = C_column + 1;
if (C_left >= 0)
{
// The left column can be accessed.
}
if (C_right < MAXIMUM_COLUMNS)
{
// The right columns can be accessed.
}
// Similarly for the rows.
I've been trying to do this shortest path problem and I realised that the way I was trying to it was almost completely wrong and that I have no idea to complete it.
The question requires you to find the shortest path from one point to another given a text file of input.
The input looks like this with the first value representing how many levels there are.
4
14 10 15
13 5 22
13 7 11
5
This would result in an answer of: 14+5+13+11+5=48
The question asks for the shortest path from the bottom left to the top right.
The way I have attempted to do this is to compare the values of either path possible and then add them to a sum. e.g the first step from the input I provided would compare 14 against 10 + 15. I ran into the problem that if both values are the same it will stuff up the rest of the working.
I hope this makes some sense.
Any suggestions on an algorithm to use or any sample code would be greatly appreciated.
Assume your data file is read into a 2D array of the form:
int weights[3][HEIGHT] = {
{14, 10, 15},
{13, 5, 22},
{13, 7, 11},
{X, 5, X}
};
where X can be anything, doesn't matter. For this I'm assuming positive weights and therefore there is never a need to consider a path that goes "down" a level.
In general you can say that the minimum cost is lesser of the following 2 costs:
1) The cost of rising a level: The cost of the path to the opposite side from 1 level below, plus the cost of coming up.
2) The cost of moving across a level : The cost of the path to the opposite from the same level, plus the cost of coming across.
int MinimumCost(int weight[3][HEIGHT]) {
int MinCosts[2][HEIGHT]; // MinCosts[0][Level] stores the minimum cost of reaching
// the left node of that level
// MinCosts[1][Level] stores the minimum cost of reaching
// the right node of that level
MinCosts[0][0] = 0; // cost nothing to get to the start
MinCosts[0][1] = weight[0][1]; // the cost of moving across the bottom
for (int level = 1; level < HEIGHT; level++) {
// cost of coming to left from below right
int LeftCostOneStep = MinCosts[1][level - 1] + weight[2][level - 1];
// cost of coming to left from below left then across
int LeftCostTwoStep = MinCosts[0][level - 1] + weight[0][level - 1] + weight[1][level];
MinCosts[0][level] = Min(LeftCostOneStep, LeftCostTwoStep);
// cost of coming to right from below left
int RightCostOneStep = MinCosts[0][level - 1] + weight[0][level - 1];
// cost of coming to right from below right then across
int RightCostTwoStep = MinCosts[1][level - 1] + weight[1][level - 1] + weight[1][level];
MinCosts[1][level] = Min(RightCostOneStep, RightCostTwoStep);
}
return MinCosts[1][HEIGHT - 1];
}
I haven't double checked the syntax, please only use it to get a general idea of how to solve the problem. You could also rewrite the algorithm so that MinCosts uses constant memory, MinCosts[2][2] and your whole algorithm could become a state machine.
You could also use dijkstra's algorithm to solve this, but that's a bit like killing a fly with a nuclear warhead.
My first idea was to represent the graph with a matrix and then run a DFS or Dijkstra to solve it. But for this given question, we can do better.
So, here is a possible solution of this problem that runs in O(n). 2*i means left node of level i and 2*i+1 means right node of level i. Read the comments in this solution for an explanation.
#include <stdio.h>
struct node {
int lup; // Cost to go to level up
int stay; // Cost to stay at this level
int dist; // Dist to top right node
};
int main() {
int N;
scanf("%d", &N);
struct node tab[2*N];
// Read input.
int i;
for (i = 0; i < N-1; i++) {
int v1, v2, v3;
scanf("%d %d %d", &v1, &v2, &v3);
tab[2*i].lup = v1;
tab[2*i].stay = tab[2*i+1].stay = v2;
tab[2*i+1].lup = v3;
}
int v;
scanf("%d", &v);
tab[2*i].stay = tab[2*i+1].stay = v;
// Now the solution:
// The last level is obvious:
tab[2*i+1].dist = 0;
tab[2*i].dist = v;
// Now, for each level, we compute the cost.
for (i = N - 2; i >= 0; i--) {
tab[2*i].dist = tab[2*i+3].dist + tab[2*i].lup;
tab[2*i+1].dist = tab[2*i+2].dist + tab[2*i+1].lup;
// Can we do better by staying at the same level ?
if (tab[2*i].dist > tab[2*i+1].dist + tab[2*i].stay) {
tab[2*i].dist = tab[2*i+1].dist + tab[2*i].stay;
}
if (tab[2*i+1].dist > tab[2*i].dist + tab[2*i+1].stay) {
tab[2*i+1].dist = tab[2*i].dist + tab[2*i+1].stay;
}
}
// Print result
printf("%d\n", tab[0].dist);
return 0;
}
(This code has been tested on the given example.)
Use a depth-first search and add only the minimum values. Then check which side is the shortest stair. If it's a graph problem look into a directed graph. For each stair you need 2 vertices. The cost from ladder to ladder can be something else.
The idea of a simple version of the algorithm is the following:
define a list of vertices (places where you can stay) and edges (walks you can do)
every vertex will have a list of edges connecting it to other vertices
for every edge store the walk length
for every vertex store a field with 1000000000 with the meaning "how long is the walk to here"
create a list of "active" vertices initialized with just the starting point
set the walk-distance field of starting vertex with 0 (you're here)
Now the search algorithm proceeds as
pick the (a) vertex from the "active list" with lowest walk_distance and remove it from the list
if the vertex is the destination you're done.
otherwise for each edge in that vertex compute the walk distance to the other_vertex as
new_dist = vertex.walk_distance + edge.length
check if the new distance is shorter than other_vertex.walk_distance and in this case update other_vertex.walk_distance to the new value and put that vertex in the "active list" if it's not already there.
repeat from 1
If you run out of nodes in the active list and never processed the destination vertex it means that there was no way to reach the destination vertex from the starting vertex.
For the data structure in C++ I'd use something like
struct Vertex {
double walk_distance;
std::vector<struct Edge *> edges;
...
};
struct Edge {
double length;
Vertex *a, *b;
...
void connect(Vertex *va, Vertex *vb) {
a = va; b = vb;
va->push_back(this); vb->push_back(this);
}
...
};
Then from the input I'd know that for n levels there are 2*n vertices needed (left and right side of each floor) and 2*(n-1) + n edges needed (one per each stair and one for each floor walk).
For each floor except the last you need to build three edges, for last floor only one.
I'd also allocate all edges and vertices in vectors first, fixing the pointers later (post-construction setup is an anti-pattern but here is to avoid problems with reallocations and still maintaining things very simple).
int n = number_of_levels;
std::vector<Vertex> vertices(2*n);
std::vector<Edge> edges(2*(n-1) + n);
for (int i=0; i<n-1; i++) {
Vertex& left = &vertices[i*2];
Vertex& right = &vertices[i*2 + 1];
Vertex& next_left = &vertices[(i+1)*2];
Vertex& next_right = &vertices[(i+1)*2 + 1];
Edge& dl_ur = &edges[i*3]; // down-left to up-right stair
Edge& dr_ul = &edges[i*3+1]; // down-right to up-left stair
Edge& floor = &edges[i*3+2];
dl_ur.connect(left, next_right);
dr_ul.connect(right, next_left);
floor.connect(left, right);
}
// Last floor
edges.back().connect(&vertex[2*n-2], &vertex[2*n-1]);
NOTE: untested code
EDIT
Of course this algorithm can solve a much more general problem where the set of vertices and edges is arbitrary (but lengths are non-negative).
For the very specific problem a much simpler algorithm is possible, that doesn't even need any data structure and that can instead compute the result on the fly while reading the input.
#include <iostream>
#include <algorithm>
int main(int argc, const char *argv[]) {
int n; std::cin >> n;
int l=0, r=1000000000;
while (--n > 0) {
int a, b, c; std::cin >> a >> b >> c;
int L = std::min(r+c, l+b+c);
int R = std::min(r+b+a, l+a);
l=L; r=R;
}
int b; std::cin >> b;
std::cout << std::min(r, l+b) << std::endl;
return 0;
}
The idea of this solution is quite simple:
l variable is the walk_distance for the left side of the floor
r variable is the walk_distance for the right side
Algorithm:
we initialize l=0 and r=1000000000 as we're on the left side
for all intermediate steps we read the three distances:
a is the length of the down-left to up-right stair
b is the length of the floor
c is the length of the down-right to up-left stair
we compute the walk_distance for left and right side of next floor
L is the minimum between r+c and l+b+c (either we go up starting from right side, or we go there first starting from left side)
R is the minimum betwen l+a and r+b+a (either we go up starting from left, or we start from right and cross the floor first)
for the last step we just need to chose what is the minimum between r and coming there from l by crossing the last floor