In one of the largest cities in Bytland, Bytesburg, construction of the second stage of the metro is underway. During the construction of the first stage, N stations were built that were not interconnected. According to the master plan, the metro in Bytesburg should consist of no more than two lines. each metro line is straight. The president of the company responsible for laying the lines wants to make sure that no more than two metro lines can be laid, so that all stations built lie on at least one of the two
Exaple 1
input:
6
0 1
1 1
2 1
0 2
1 3
2 2
output:
no
Example 2
input:
6
2 2
4 6
1 0
2 1
6 1
1 1
output:
yes
I wrote the code, but on the seventh test on the testing system, it gives the wrong answer. Help me please. This is my code:
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
struct line {
int k, b;
bool x = false;
long long c = 0;
};
int n;
vector<line> lines;
vector<pair<int, int>> p;
bool Is3PointsOnLine(pair<float, float> p1, pair<float, float> p2, pair<float, float> p3) {
return ((p3.first - p1.first)*(p2.second - p1.second) == (p3.second - p1.second)*(p2.first - p1.first));
}
bool PointIsOnLine(line l, int x, int y) {
if (!l.x) {
if (y == ((l.k * x) + l.b))
return true;
}
else {
if (x == l.b)
return true;
}
return false;
}
line f(pair<int, int> c1, pair<int, int> c2) {
int x1 = c1.first;
int y1 = c1.second;
int x2 = c2.first;
int y2 = c2.second;
line ans;
if (x2 != x1) {
ans.k = (y2 - y1) / (x2 - x1);//fix
ans.b = -(x1 * y2 - x1 * y1 - x2 * y1 + x1 * y1) / (x2 - x1);
ans.x = false;
ans.c = 0;
}
else {
ans.k = 0;
ans.b = x1;
ans.x = true;
ans.c = 0;
}
return ans;
}
int a() {
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
if (j != i) {
for (int k = 0; k < n; k++) {
if ((k != i) && (k != j) && (Is3PointsOnLine(p[i], p[j], p[k]))) {
lines.push_back(f(p[i], p[j]));
return 0;
}
}
}
}
}
}
int main() {
cin >> n;
p.resize(n);
vector<int> not_used;
for (int i = 0; i < n; i++)
cin >> p[i].first >> p[i].second;
if (n < 5) {
cout << "yes";
return 0;
}
else {
a();
if (lines.size() == 0) {
cout << "no";
return 0;
}
pair<int, int> e = { -8,-8 };
for (int i = 0; i < n; i++) {
if (PointIsOnLine(lines[0], p[i].first, p[i].second)) {
lines[0].c++;
}
else if (e.first == -8) {
e.first = i;
}
else if (e.second == -8) {
e.second = i;
lines.push_back(f(p[e.first], p[e.second]));
for (int j = 0; j <= i; j++) {
if (PointIsOnLine(lines[1], p[j].first, p[j].second)) {
lines[1].c++;
}
}
e = { -5,-5 };
}
else if (PointIsOnLine(lines[1], p[i].first, p[i].second)) {
lines[1].c++;
}
else {
cout << "no";
return 0;
}
}
if (lines[0].c+1 >= n && e.first != -2 && e.second == -8) {
cout << "yes";
return 0;
}
else if (lines[0].c + lines[1].c >= n) {
cout << "yes";
return 0;
}
else {
cout << "no";
return 0;
}
}
return 0;
}
Code v2
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
struct line {
pair<int, int> p1, p2;
long long c = 0;
};
int n;
vector<line> lines;
vector<pair<int, int>> p;
bool Is3PointsOnLine(pair<float, float> p1, pair<float, float> p2, pair<float, float> p3) {
return ((p3.first - p1.first)*(p2.second - p1.second) == (p3.second - p1.second)*(p2.first - p1.first));
}
//лежит ли точка на прямой
bool PointIsOnLine(line l, int x, int y) {
return Is3PointsOnLine(l.p1, l.p2, {x , y});
}
int a() {
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
if (j != i) {
for (int k = 0; k < n; k++) {
if ((k != i) && (k != j) && (Is3PointsOnLine(p[i], p[j], p[k]))) {
line sdafsadf;
sdafsadf.p1 = p[i]; sdafsadf.p2 = p[j];
lines.push_back(sdafsadf);
return 0;
}
}
}
}
}
}
int main() {
cin >> n;
p.resize(n);
vector<int> not_used;
for (int i = 0; i < n; i++)
cin >> p[i].first >> p[i].second;
if (n < 5) {
cout << "yes";
return 0;
}
else {
//ищем первую прямую
a();
if (lines.size() == 0) {
cout << "no";
return 0;
}
pair<int, int> e = { -8,-8 };
for (int i = 0; i < n; i++) {
if (PointIsOnLine(lines[0], p[i].first, p[i].second)) {
lines[0].c++;
}
else if (e.first == -8) {
e.first = i;
}
else if (e.second == -8) {
e.second = i;
line sdafsadf;
sdafsadf.p1 = p[e.first]; sdafsadf.p2 = p[e.second];
lines.push_back(sdafsadf);
for (int j = 0; j <= i; j++) {
if (PointIsOnLine(lines[1], p[j].first, p[j].second)) {
lines[1].c++;
}
}
e = { -5,-5 };
}
else if (PointIsOnLine(lines[1], p[i].first, p[i].second)) {
lines[1].c++;
}
else {
cout << "no";
return 0;
}
}
if (lines[0].c+1 >= n && e.first != -2 && e.second == -8) {
cout << "yes";
return 0;
}
else if ((lines[0].c + lines[1].c >= n) && (lines[0].p1 != lines[1].p1) && (lines[0].p1 != lines[1].p2) && (lines[0].p2 != lines[1].p1) && (lines[0].p2 != lines[1].p2)) {
cout << "yes";
return 0;
}
else {
cout << "no";
return 0;
}
}
return 0;
}
Your function f is horribly broken because it uses integer division. Then everything after that which relies on k and b, including PointIsOnLine, will give wrong results. Is3PointsOnLine seems ok, change your line struct to store two points, not slope+intercept, and then PointInOnLine can just call Is3PointsOnLine.
I'm amazed that you passed any non-trivial test cases with such a bug.
This also will not work
if (lines[0].c + lines[1].c >= n)
because you aren't testing that lines[1] isn't a duplicate of lines[0].
Also, you can reach lines[0].c + lines[1].c == n and still miss one station completely, if another station lies at the intersection of the lines and gets double-counted.
Related
Me and my group is making a game for our project and I keep running into this error, after some testing, it looks like it happens at the end of the main function. I have no idea how this happen as most of the code is from our teacher, we need to fix the intentional bugs placed by him and add additional functionalities.
This is the code:
#include <winuser.h>
#include <iostream>
#include <time.h>
#include <conio.h>
#include <thread>
using namespace std;
#define MAX_CAR 5
#define MAX_CAR_LENGTH 40
#define MAX_SPEED 3
POINT** X;
POINT Y;
int cnt = 0;
int MOVING;
int SPEED;
int HEIGHT_CONSOLE = 29, WIDTH_CONSOLE = 119;
bool STATE;
void FixConsoleWindow() {
HWND consoleWindow = GetConsoleWindow();
LONG_PTR style = GetWindowLongPtr(consoleWindow, GWL_STYLE);
style = style & ~(WS_MAXIMIZEBOX) & ~(WS_THICKFRAME);
SetWindowLongPtr(consoleWindow, GWL_STYLE, style);
}
void GotoXY(int x, int y) {
COORD coord;
coord.X = x;
coord.Y = y;
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), coord);
}
void ResetData() {
MOVING = 'D';
SPEED = 1;
Y = { 18, 19 };
if (X == NULL) {
X = new POINT * [MAX_CAR];
for (int i = 0; i < MAX_CAR; i++) {
X[i] = new POINT[MAX_CAR_LENGTH];
}
for (int i = 0; i < MAX_CAR; i++) {
int temp = rand() % (WIDTH_CONSOLE - MAX_CAR_LENGTH) + 1;
for (int j = 0; j < MAX_CAR_LENGTH; j++) {
X[i][j].x = temp + j;
X[i][j].y = 2 + 5 * i;
}
}
}
}
void DrawBoard(int x, int y, int width, int height, int curPosX = 0, int curPosY = 0) {
GotoXY(x, y);
for (int i = 1; i < width; i++) {
cout << 'X';
}
cout << 'X';
GotoXY(x, height + y);
for (int i = 1; i < width; i++) {
cout << 'X';
}
cout << 'X';
for (int i = y + 1; i < height + y; i++) {
GotoXY(x, i);
cout << 'X';
GotoXY(x + width, i);
cout << 'X';
}
GotoXY(curPosX, curPosY);
}
void StartGame() {
system("cls");
ResetData();
DrawBoard(0, 0, WIDTH_CONSOLE, HEIGHT_CONSOLE);
STATE = true;
}
void GabageCollect() {
for (int i = 0; i < MAX_CAR; i++) {
delete[] X[i];
}
delete[] X;
}
void ExitGame(HANDLE t) {
GabageCollect();
system("cls");
TerminateThread(t, 0);
}
void PauseGame(HANDLE t) {
SuspendThread(t);
}
void ProcessDeath() {
STATE = false;
GotoXY(0, HEIGHT_CONSOLE + 2);
cout << "Dead, type y to continue or any key to exit";
}
void ProcessFinish(POINT& p) {
SPEED == MAX_SPEED ? SPEED = 1 : SPEED++;
p = { 18,19 };
MOVING = 'D';
}
void DrawCars() {
for (int i = 0; i < MAX_CAR; i++) {
for (int j = 0; j < MAX_CAR_LENGTH; j++) {
GotoXY(X[i][j].x, X[i][j].y);
std::cout << '.';
}
}
}
void DrawPlayer(const POINT& p, char s) {
GotoXY(p.x, p.y);
cout << s;
}
bool IsImpact(const POINT& p) //d=Y.y p = Y
{
if (p.y == 1 || p.y == 19) return false;
for (int i = 0; i < MAX_CAR; i++)
{
for (int j = 0; j < MAX_CAR_LENGTH; j++)
{
if (p.x == X[i][j].x && p.y == X[i][j].y) return true;
}
}
return false;
}
void MoveCars(int x1, int y1)
{
for (int i = 1; i < MAX_CAR; i += 2)
{
cnt = 0;
do
{
cnt++;
for (int j = 0; j < MAX_CAR_LENGTH - 1; j++)
{
X[i][j] = X[i][j + 1];
}
X[i][MAX_CAR_LENGTH - 1].x + 1 == WIDTH_CONSOLE + x1 ? X[i][MAX_CAR_LENGTH - 1].x = 1 : X[i][MAX_CAR_LENGTH - 1].x++;
} while (cnt < SPEED);
}
for (int i = 0; i < MAX_CAR; i += 2)
{
cnt = 0;
do
{
cnt++;
for (int j = MAX_CAR_LENGTH - 1; j > 0; j--)
{
X[i][j] = X[i][j - 1];
}
X[i][0].x - 1 == 0 + x1 ? X[i][0].x = WIDTH_CONSOLE + x1 - 1 : X[i][0].x--;
} while (cnt < SPEED);
}
}
void EraseCars()
{
for (int i = 0; i < MAX_CAR; i += 2)
{
cnt = 0;
do
{
GotoXY(X[i][MAX_CAR_LENGTH - 1 - cnt].x, X[i][MAX_CAR_LENGTH - 1 - cnt].y);
cout << " ";
cnt++;
} while (cnt < SPEED);
}
for (int i = 1; i < MAX_CAR; i += 2)
{
cnt = 0;
do
{
GotoXY(X[i][0 + cnt].x, X[i][0 + cnt].y);
cout << " ";
cnt++;
} while (cnt < SPEED);
}
}
void MoveRight()
{
if (Y.x < WIDTH_CONSOLE - 1)
{
DrawPlayer(Y, ' ');
Y.x++;
DrawPlayer(Y, 'Y');
}
}
void MoveLeft()
{
if (Y.x > 1)
{
DrawPlayer(Y, ' ');
Y.x--;
DrawPlayer(Y, 'Y');
}
}
void MoveDown()
{
if (Y.y < HEIGHT_CONSOLE - 1)
{
DrawPlayer(Y, ' ');
Y.y++;
DrawPlayer(Y, 'Y');
}
}
void MoveUp()
{
if (Y.y > 1)
{
DrawPlayer(Y, ' ');
Y.y--;
DrawPlayer(Y, 'Y');
}
}
void SubThread()
{
while (1)
{
if (STATE)
{
switch (MOVING)
{
case 'A':
MoveLeft();
break;
case 'D':
MoveRight();
break;
case'W':
MoveUp();
break;
case'S':
MoveDown();
break;
}
MOVING = ' ';
EraseCars();
MoveCars(0, 0);
DrawCars();
if (IsImpact(Y))
{
ProcessDeath();
}
if (Y.y == 1)
{
ProcessFinish(Y);
Sleep(50);
}
}
}
}
void main()
{
int temp;
FixConsoleWindow();
srand(time(NULL));
StartGame();
thread t1(SubThread);
while (1)
{
temp = toupper(_getch());
if (STATE == 1)
{
EraseCars();
if (temp == 27)
{
ExitGame(t1.native_handle());
break;
}
else if (temp == 'P')
{
PauseGame(t1.native_handle());
temp = toupper(_getch());
if (temp == 'B')
ResumeThread((HANDLE)t1.native_handle());
}
else
{
if (temp == 'D' || temp == 'A' || temp == 'W' || temp == 'S')
{
MOVING = temp;
}
}
}
else
{
if (temp == 'Y') StartGame();
else
{
ExitGame(t1.native_handle());
break;
}
}
}
}
And this is the image of the error: https://imgur.com/PGJJX2w
Basically, this is a crossing road game, every time you go to the top, it saves the location and you cannot go that location again (still working on this), game finish when you run into the cars (lines of dots as of the moment). Thanks in advance
You created a std::thread object here:
thread t1(SubThread);
but you didn't call join() nor detach() for that.
This causes that std::terminate() is called (the program aborts) when the object is destructed.
Call t1.join() if you want to wait until the thread ends or t1.detach() if you want to let the thread run freely before returning from the main() function.
Another option is using CreateThread() directly instead of std::thread to create threads. This may be better because you are using t1.native_handle() for operations on the thread.
I am trying to create a c++ unbeatable tic tac toe AI. after watching several videos on the topic i thought I had it all figured out. An error pops up on the screen saying "Expression: vector subscript out of range". I believe the error is coming from the availableMoves() function. however I do not know why.
The game itself works fine. any help would be appreciated.
#include <iostream>
#include <vector>
#include <ctime>
bool in(std::vector<int> v, int element)
{
for (int i = 0; i < v.size(); i++)
{
if (element == v[i])
{
return true;
}
}
return false;
}
class Board
{
private:
char board[3][3] = { {'1', '2', '3'}, {'4', '5', '6'}, {'7', '8', '9'} };
public:
void displayBoard()
{
std::cout << "___________________" << std::endl;
for (int i = 0; i < 3; i++)
{
std::cout << "| ";
for (int j = 0; j < 3; j++)
{
std::cout << board[i][j] << " | ";
}
std::cout << std::endl;
}
std::cout << "___________________" << std::endl;
}
std::vector<int> availableMoves()
{
std::vector<int> moves;
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 3; j++)
{
if (board[i][j] != 'X' && board[i][j] != 'O')
{
moves.push_back(i * 3 + j);
}
}
}
return moves;
}
void move(int choice, char mark)
{
int y = choice / 3;
int x = choice - y * 3;
board[y][x] = mark;
}
void revert(int choice)
{
int y = choice / 3;
int x = choice - y * 3;
board[y][x] = (char)choice + 48;
}
int checkWin()
{
for (int i = 0; i < 3; i++)
{
if (board[i][0] == board[i][1] && board[i][1] == board[i][2])
{
if (board[i][0] == 'X')
{
return 1;
}
else if (board[i][0] == 'O')
{
return -1;
}
}
}
for (int i = 0; i < 3; i++)
{
if (board[0][i] == board[1][i] && board[1][i] == board[2][i])
{
if (board[0][i] == 'X')
{
return 1;
}
else if (board[0][i] == 'O')
{
return -1;
}
}
}
if (board[0][0] == board[1][1] && board[1][1] == board[2][2])
{
if (board[0][0] == 'X')
{
return 1;
}
else if (board[0][0] == 'O')
{
return -1;
}
}
if (board[0][2] == board[1][1] && board[1][1] == board[2][0])
{
if (board[0][2] == 'X')
{
return 1;
}
else if (board[0][2] == 'O')
{
return -1;
}
}
return 0;
}
int evaluate()
{
return (checkWin() * -1) * (availableMoves().size() + 1);
}
Board& operator=(Board& b)
{
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 3; j++)
{
board[i][j] = b.board[i][j];
}
}
return (*this);
}
};
class TicTacToe
{
private:
Board board;
int turn;
int searches = 0;
public:
TicTacToe()
{
std::srand(time(0));
turn = std::rand() % 2;
}
int minimax(int depth, Board curBoard, bool is_max)
{
searches++;
if (depth == 0 || curBoard.checkWin() != 0)
{
return board.evaluate();
}
if (is_max)
{
int max_eval = -2147483647;
for (int i = 0; i < curBoard.availableMoves().size(); i++)
{
curBoard.move(curBoard.availableMoves()[i], 'O');
depth -= 1;
int eval = minimax(depth, curBoard, false);
curBoard.revert(curBoard.availableMoves()[i]);
if (eval > max_eval)
{
max_eval = eval;
}
}
return max_eval;
}
if (!is_max)
{
int min_eval = 2147483647;
for (int i = 0; i < curBoard.availableMoves().size(); i++)
{
curBoard.move(curBoard.availableMoves()[i], 'X');
depth -= 1;
int eval = minimax(depth, curBoard, true);
curBoard.revert(curBoard.availableMoves()[i]);
if (eval < min_eval)
{
min_eval = eval;
}
}
return min_eval;
}
}
void game()
{
while (board.checkWin() == 0 && board.availableMoves().size() != 0)
{
board.displayBoard();
if (turn % 2 == 0)
{
std::cout << std::endl;
int choice;
std::cout << "Enter Your Move: ";
std::cin >> choice;
choice -= 1;
while (!in(board.availableMoves(), choice))
{
std::cout << "Enter A Valid Move: ";
std::cin >> choice;
}
board.move(choice, 'X');
std::cout << std::endl;
turn++;
}
board.displayBoard();
if (board.checkWin() != 0)
{
break;
}
if (turn % 2 == 1)
{
int ai = minimax(9 - (turn % 2), board, true);
std::cout << searches;
std::cin.get();
turn++;
}
}
if (board.checkWin() == 1)
{
std::cout << "You Won" << std::endl;
}
else if (board.checkWin() == -1)
{
std::cout << "You Lost" << std::endl;
}
else
{
std::cout << "Tie" << std::endl;
}
std::cout << "Would You Like To Play Again Y/N: ";
char playAgain;
std::cin >> playAgain;
if (playAgain == 'Y')
{
Board newBoard;
board = newBoard;
game();
}
}
};
int main()
{
TicTacToe ticTacToe;
ticTacToe.game();
}
Do you know how to debug? If not, you should definitely learn this, it's pretty helpful. But here's some things I found out.
The problem is not in availableMoves(), but in minimax(), more precisely in line 215, where the program calls curBoard. revert(curBoard. availableMoves()[i]).
void revert(int choice)
{
int y = choice / 3;
int x = choice - y * 3;
board[y][x] = (char)choice + 48;
}
for (int i = 0; i < curBoard.availableMoves().size(); i++)
{
curBoard.move(curBoard.availableMoves()[i], 'X');
depth -= 1;
int eval = minimax(depth, curBoard, true);
curBoard.revert(curBoard.availableMoves()[i]);
if (eval < min_eval)
{
min_eval = eval;
}
}
The error happens in the function revert, but I am not sure why. Maybe availableMoves also returns something wrong. Variable i is permanently 0 in the for-loop. So it is possible that there is something wrong at position 0 of the vector moves, which revert cannot handle. Try debugging yourself, maybe you'll find the problem.
My program should read input as an integer for the length followed by (sufficiently) parenthesized floats and simple operators and output the value of the expression. For example, if the input were 11 1 + 2 ^ 3 / 4 * 5 - 6, the result should be equal to (1 + (((2 ^ 3) / 4) * 5)) - 6, or 5. However, even when I input 5 1 + 2 + 3, the output is 5 instead of 6. I think this might be because of the many vector assignments, in particular the marked line (I found this while debugging).
My code (sorry if it is not self explanatory):
#include <iostream>
#include <string>
#include <vector>
#include <cmath>
using namespace std;
float op(char op, float x, float y)
{
switch (op)
{
case '+':
{
return x+y;
break;
}
case '-':
{
return x-y;
break;
}
case '*':
{
return x*y;
break;
}
case '/':
{
return x/y;
break;
}
case '^':
{
return pow(x,y);
break;
}
default:
{
cout << "Error: bad input ";
return 0;
}
}
}
float nopars(vector<string> stack, int stackl, vector<char> ops, int opsr)
{
int len = stackl, opsrr = opsr;
vector<string> nstack, nnstack;
vector<char> nops = ops, nnops;
nstack = stack;
while (opsrr != 0)
{
string s1 (1, nops[0]);
for (int i = 0; i < len; i++)
{
if (nstack[i] == s1)
{
for (int j = 0; j < len - 2; j++)
{
nnstack = {};
if (j == i-1)
{
nnstack.push_back(to_string(op(nops[0], stof(nstack[i-1]), stof(nstack[i+1]))));
}
else if (j < i-1)
{
nnstack.push_back(nstack[j]);
}
else if (j > i-1)
{
nnstack.push_back(nstack[j+2]);
}
}
len = len - 2;
nstack = nnstack; //I think this is wrong?
i--;
}
}
nnops = {};
for (int i = 0; i < opsr-1; i++)
{
nnops.push_back(nops[i+1]);
}
opsrr--;
nops = nnops;
}
return stof(nstack[0]);
}
float all(vector<string> stack, int stackl, vector<char> ops, int opsr)
{
int t1 = 0, t2 = 0;
int len = stackl;
int nprs;
vector<string> nstack, nnstack, nstck;
nstack = stack;
while (true)
{
nprs = 0;
for (int i = 0; i < len; i++)
{
if (nstack[i] == "(")
{
nprs = 1;
t1 = i;
}
else if (nstack[i] == ")")
{
nprs = 1;
t2 = i;
nstck = {};
for (int j = t1 + 1; j < t2; j++)
{
nstck.push_back(nstack[j]);
}
for (int j = 0; j < len - t2 + t1; j++)
{
if (j == t1)
{
nnstack.push_back(to_string(nopars(nstck, t2-t1-1, ops, opsr)));
}
else if (j < t1)
{
nnstack.push_back(nstack[j]);
}
else if (j > t1)
{
nnstack.push_back(nstack[j+t2-t1]);
}
}
len = len - t2 + t1;
break;
}
}
if (nprs == 0)
{
break;
}
nstack = nnstack;
}
return nopars(nstack, len, ops, opsr);
}
void calculate()
{
vector<string> stack;
int stackl;
string t;
cin >> stackl;
for (int i = 0; i < stackl; i++)
{
cin >> t;
stack.push_back(t);
}
cout << all(stack, stackl, {'^', '/', '*', '-', '+'}, 5);
}
int main()
{
calculate();
return 0;
}
A binary recurrent LL parser
#include <iostream>
#include <string>
#include <sstream>
#include <functional>
#include <iterator>
#include <cmath>
#include <map>
using namespace std;
using T = float;
map< int, map<std::string, std::function<T(const T&, const T&)> > > m_foo =
{ {1, { { "+", std::plus<T>() }, { "-", std::minus<T>() } } },
{2, { { "*", std::multiplies<T>() }, { "/", std::divides<T>() } } },
{3, { { "^", powf } } } };
T calc_ll(istream_iterator<string>& t, int level) {
if ( !m_foo.contains(level) ) return std::stof(*t++);
auto result = calc_ll(t, level+1);
auto l = m_foo[level];
while ( l.find(*t) != l.end() ) {
auto foo = l.find(*t)->second;
result = foo(result, calc_ll(++t, level+1) );
}
return result;
}
int main()
{
std::stringstream ss(std::string("1 + 2 ^ 3 / 4 * 5 - 6"));
auto t = istream_iterator<string>(ss);
cout << "result : " << calc_ll( t, 1 );
return 0;
}
link https://godbolt.org/z/9vPMGn
It seems the error is in the unintentionally repeated declaration nnstack = {}.
#include <iostream>
#include <string>
#include <vector>
#include <cmath>
using namespace std;
float op(char op, float x, float y)
{
switch (op)
{
case '+':
{
return x+y;
break;
}
case '-':
{
return x-y;
break;
}
case '*':
{
return x*y;
break;
}
case '/':
{
return x/y;
break;
}
case '^':
{
return pow(x,y);
break;
}
default:
{
cout << "Error: bad input ";
return 0;
}
}
}
float nopars(vector<string> stack, int stackl, vector<char> ops, int opsr)
{
int len = stackl, opsrr = opsr;
vector<string> nstack, nnstack;
vector<char> nops = ops, nnops;
nstack = stack;
while (opsrr != 0)
{
string s1 (1, nops[0]);
for (int i = 0; i < len; i++)
{
if (nstack[i] == s1)
{
nnstack = {}; //this was missing
for (int j = 0; j < len - 2; j++)
{
//nnstack = {}; //this was misplaced
if (j == i-1)
{
nnstack.push_back(to_string(op(nops[0], stof(nstack[i-1]), stof(nstack[i+1]))));
}
else if (j < i-1)
{
nnstack.push_back(nstack[j]);
}
else if (j > i-1)
{
nnstack.push_back(nstack[j+2]);
}
}
len = len - 2;
nstack = nnstack;
i--;
}
}
nnops = {};
for (int i = 0; i < opsr-1; i++)
{
nnops.push_back(nops[i+1]);
}
opsrr--;
nops = nnops;
}
return stof(nstack[0]);
}
float all(vector<string> stack, int stackl, vector<char> ops, int opsr)
{
int t1 = 0, t2 = 0;
int len = stackl;
int nprs;
vector<string> nstack, nnstack, nstck;
nstack = stack;
while (true)
{
nprs = 0;
for (int i = 0; i < len; i++)
{
if (nstack[i] == "(")
{
nprs = 1;
t1 = i;
}
else if (nstack[i] == ")")
{
nprs = 1;
t2 = i;
nstck = {};
for (int j = t1 + 1; j < t2; j++)
{
nstck.push_back(nstack[j]);
}
for (int j = 0; j < len - t2 + t1; j++)
{
if (j == t1)
{
nnstack.push_back(to_string(nopars(nstck, t2-t1-1, ops, opsr)));
}
else if (j < t1)
{
nnstack.push_back(nstack[j]);
}
else if (j > t1)
{
nnstack.push_back(nstack[j+t2-t1]);
}
}
len = len - t2 + t1;
break;
}
}
if (nprs == 0)
{
break;
}
nstack = nnstack;
}
return nopars(nstack, len, ops, opsr);
}
void calculate()
{
vector<string> stack;
int stackl;
string t;
cin >> stackl;
for (int i = 0; i < stackl; i++)
{
cin >> t;
stack.push_back(t);
}
cout << all(stack, stackl, {'^', '/', '*', '-', '+'}, 5);
}
int main()
{
calculate();
return 0;
}
I've been working on a program in one of my college classes. I have been having trouble with the implementation of my LRU code as it is not displaying any errors or anything, but compiles. There are two parts. The main that we input the values into, which we then specify which algorithm we want to use to find page faults. I know the main works, along with the FIFO algorithm, but I'm not getting anything with my LRU code (It compiles and "runs" but displays nothing as if I did not click to use the algorithm). Can anyone help me figure out what is wrong?
main.cpp
#include <iostream>
#include <string>
//#include "fifo.cpp"
#include "lru.cpp"
//#include "optimal.cpp"
using namespace std;
int main() {
// List of different variables
string pagestring;
int fs,pn[50], n;
// Prompt for page references
cout<<"Virtual Memory Simulation\nBy blah\n----------\nEnter the number of pages : " << endl;
cin >> n;
cout<<"\n-------------\nPlease enter a list of page numbers separated by commas.\n"<< endl;
cin>>pagestring;
// algorithm to use
char algo;
while (true) {
// Prompt algorithm to use
cout<<"----------\nPlease select an algorithm to use.\n\n1: First-In-First-Out (FIFO)\n2: Least-Recently-Used (LRU)\n3: Optimal\n0: Quit\n"<<endl;
cin>>algo;
if (algo == '1') {
//fifo(pagestring);
}
else if (algo == '2'){
LRU_Execute(pagestring, n);
}
else if (algo == '3'){
cout<<"Optimal Not yet coded"<<endl;
}
else if (algo == '0'){
break;
}
else {
cout<<"Invalid choice. Please try again."<<endl;
}
}
cout<<"Goodbye!!"<<endl;
};
LRU.cpp
#include <iostream>
#include <string>
using namespace std;
class pra
{
int fs,z;
int frame[50], frame1[50][2], pn[50], n, cnt, p, x;
public:
pra();
void init(string pagestring);
void getdata(string pagestring, int n);
void lru(int* pn, int n, string pagestring);
};
pra::pra()
{
int i;
for (i = 0; i < fs; i++)
{
frame[i] = -1;
}
for (i = 0; i < fs; i++)
{
frame1[i][0] = -1;
frame1[i][1] = 0;
}
p = 0;
cnt = 0;
}
void pra::init(string pagestring)
{
int i;
for (i = 0; i < fs; i++)
{
frame[i] = -1;
}
for (i = 0; i < fs; i++)
{
frame1[i][0] = -1;
frame1[i][1] = 0;
}
p = 0;
cnt = 0;
}
void pra::getdata(string pagestring, int n)
{
fs=3;
// index to loop through input string
int i = 0;
// current input string character
char z = pagestring[i];
int x = 0;
//cout << "\nEnter the page numbers : ";
while (z != '\0'){
// skip over commas and spaces
if (!(z == ',')) {
pn[x] = z;
x++;
// cout<<pn[x]<<"-This is pn[x]\n";
}
z = pagestring[++i];
}
//cout<<pn[x]<<"-This is pn[x] AGAIN\n";
this->lru(pn, n, pagestring);
}
void pra::lru(int* pn, int n, string pagestring)
{
init(pagestring);
int ind = 0, fault = 0, pi = 0, j, fn;
char i, z;
p = 0;
cnt = 0;
int min;
cout<<n<<"---"<<i<<" - "<<j<<" - "<<" - "<<fn<<" - "<<z;
for (i = 0; i < fs; i++)
{
frame1[i][0] = -1;
frame1[i][1] = 0;
}
pi = 0;
for (i = 0; i < n; i++)
{
j = 0;
if (ind > fs - 1)
ind = 0;
fault = 1;
min = 999;
while (j < fs)
{
if (frame1[j][0] = pn[pi])
{
fault = 0;
p++;
frame1[j][1] = p;
goto l2;
}
if (frame1[j][1] < min)
{
min = frame1[j][1];
fn = j;
}
j++;
}
j = 0;
while (j < fs)
{
if (frame1[j][0] = -1)
{
fault = 1;
fn = j;
goto l2;
}
j++;
}
ind++;
l2:
if (fault == 1)
{
p++;
frame1[fn][0] = pn[pi];
frame1[fn][1] = p;
cnt++;
}
cout << "\nElement: " << pn[pi];
pi++;
for (z = 0; z < fs; z++)
{
cout << "\t" << frame1[z][0];
}
if (fault == 1)
cout << "\t**Page Fault**";
else
cout << "\t--No Page Fault--";
}
cout << "\nTotal number of page faults: " << cnt;
cout << "\n";
}
void LRU_Execute(string pagestring, int n)
{
pra p;
int j, fault = 0, i, pi, z, fn, ind = 0, ans, ch;
p.getdata(pagestring, n);
//p.lru();
while (ans == 1);
//return 1;
}
There is the problem:
The first man 'g' (who starts first) has to reach the final box 'e', so that the second man 'l' (whenever he do) could't catch the first man. The men can go left, right, up, down or can stay.
For example:
Input:
6 7
RRRRRRR
R_e___R
R_____R
R_RRR_R
R_gRl_R
RRRRRRR
The answer is "YES" because there is the way (Left, Up, Up, Up, Right).
How this problem can be implemented?
I'm using BFS and DFS.
Here is my code
#include <iostream>
#include <algorithm>
#include <stack>
#include <math.h>
#include <cstring>
#include <map>
#include <queue>
using namespace std;
const int MAX = 32;
char a[MAX][MAX];
int used[MAX][MAX], m1[MAX][MAX], m2[MAX][MAX];;
int movesx[8] = {-1, 1, 0, 0};
int movesy[8] = { 0, 0, -1, 1};
int n, m, c = 0, flag = 0;
struct pc {
int x, y;
};
pc li, ga, fi;
queue <pc> q;
void BFS1(pc v) {
pc from, to;
memset(m1,0,sizeof(m1)); m1[v.y][v.x] = 0;
memset(used, 0, sizeof(used));
q.push(v); used[v.y][v.x] = 1;
while(!q.empty())
{
from = q.front(); q.pop();
for(int i = 0; i < 4; ++i) {
int x = from.x + movesy[i], y = from.y + movesx[i];
if( (a[y][x] == ' ' || a[y][x] == 'g' ) && !used[y][x]) {
used[y][x] = 1;
m1[y][x] = m1[from.y][from.x] + 1;
pc temp;
temp.x = x;
temp.y = y;
q.push(temp);
}
}
}
}
void BFS2(pc v) {
pc from, to;
memset(m2,0,sizeof(m2)); m2[v.y][v.x] = 0;
memset(used, 0, sizeof(used));
q.push(v); used[v.y][v.x] = 1;
while(!q.empty())
{
from = q.front(); q.pop();
for(int i = 0; i < 4; ++i) {
int y = from.y + movesy[i], x = from.x + movesx[i];
if( (a[y][x] == ' ' || a[y][x] == 'l' ) && !used[y][x]) {
used[y][x] = 1;
m2[y][x] = m2[from.y][from.x] + 1;
pc temp;
temp.x = x;
temp.y = y;
q.push(temp);
}
}
}
}
void DFS(pc v) {
used[v.y][v.x] = 1;
for(int i = 0; i < 4; ++i) {
int x = v.x + movesx[i], y = v.y + movesy[i];
if(a[y][x] == 'e') {
c = 1;
flag = 1;
return;
}
if( (a[y][x] == ' ' ) && !used[y][x] && m2[y][x] < m1[y][x] && flag == 0 ) {
pc temp;
temp.x = x;
temp.y = y;
DFS(temp);
}
}
}
int main() {
c = 0, flag = 0;
memset(used, 0, sizeof(used));
memset(a, 'R', sizeof(a));
cin >> n >> m;
string s;
getline(cin, s);
for(int i = 0; i < n; ++i) {
getline(cin, s);
for(int j = 0; j < m; ++j) {
a[i][j] = s[j];
if(a[i][j] == 'g') {
ga.x = j;
ga.y = i;
}
else if(a[i][j] == 'l') {
li.x = j;
li.y = i;
}
else continue;
}
}
BFS1(li);
BFS2(ga);
memset(used, 0, sizeof(used));
DFS(ga);
if(c == 1) {
cout << "YES" << endl;
}
else {
cout << "NO" << endl;
}
}
Here is the second code:
#include <iostream>
#include <algorithm>
#include <stack>
#include <math.h>
#include <cstring>
#include <map>
#include <queue>
using namespace std;
const int MAX = 32;
char a[MAX][MAX];
int used[MAX][MAX], m1[MAX][MAX], m2[MAX][MAX];;
int an[1002][MAX][MAX];
int movesx[8] = {-1, 1, 0, 0, 0};
int movesy[8] = { 0, 0, -1, 1, 0};
int n, m, c = 0, flag = 0;
struct pc {
int x, y;
};
pc li, ga;
void functionD() {
for(int z = 1; z <= 1000; ++z) {
for(int i = 0; i < n; ++i) {
for(int j = 0; j < n; ++j) {
if(an[z - 1][i][j] == 1) {
int x, y;
for(int k = 0; k < 5; ++k) {
x = j + movesx[k];
y = i + movesy[k];
if(x < m && y < n && x >= 0 && y >= 0) {
if(a[y][x] != 'R' && a[y][x] != 'e') {
an[z][y][x] = 1;
}
}
}
}
}
}
}
}
void DFS(pc v, int k) {
used[v.y][v.x] = 1;
for(int i = 0; i < 5; ++i) {
int x = v.x + movesx[i], y = v.y + movesy[i];
if(a[y][x] == 'e') {
c = 1;
flag = 1;
return;
}
if(an[k][y][x] == 0 && a[y][x] != 'R' && !used[y][x] && flag == 0 && k <= 1000) {
pc temp;
temp.x = x;
temp.y = y;
DFS(temp, k + 1);
}
}
}
int main() {
int nn; cin >> nn;
for(int z = 0; z < nn; ++z) {
c = 0, flag = 0;
memset(used, 0, sizeof(used));
memset(a, 'R', sizeof(a));
cin >> n >> m;
string s;
getline(cin, s);
for(int i = 0; i < n; ++i) {
getline(cin, s);
for(int j = 0; j < m; ++j) {
a[i][j] = s[j];
if(a[i][j] == 'g') {
ga.x = j;
ga.y = i;
}
else if(a[i][j] == 'l') {
li.x = j;
li.y = i;
}
}
}
an[0][li.y][li.x] = 1;
functionD();
DFS(ga, 1);
if(c == 1) {
cout << "YES" << endl;
}
else {
cout << "NO" << endl;
}
}
}
EDIT (By Jarod42):
I found a tricky map which failed:
9 9
RRRRRRRRR
R...Rg..R
R.RlRRR.R
R.R...R.R
R.RRR.R.R
R.Re....R
R.R.RRR.R
R.......R
RRRRRRRRR
l cannot protect both accesses to e.
or even simpler
RRRRRRRRRR
R...RRRRRR
R.R...RRRR
RlReR...gR
R.R...RRRR
R...RRRRRR
RRRRRRRRRR
You have first to create a map distance from each accesses to e.
Then it is a minmax (or alpha-beta):
if g current position in one map-distance is less than l current position is same map-distance, g wins.
if l has less or equal distance in all maps distance, g loses.
else g has to use one of its valid map to reach the goal, l counters with its maps (or stands).
(Note: g has no reasons to stand as l may do the same and we are at the same point).
(Edit: Note: in provided link, it seems that the secure path has to be chosen statically, so the dynamic part (3rd bullet) is a loose for g)
There is no need for the DFS. Just test whether l can reach e before g can. If he can, then he can catch g, otherwise g wins.
(And beware of redundancy in your code; BFS1 and BFS 2 are almost identical, and could be combined into a single function.)
EDIT: The OP has added (a link to) new information: l cannot enter e.
The correction to this algorithm is obvious, if inelegant. Consider the rooms surrounding e; if there is one that g can reach before l, then g wins.
There may be other catches in the linked problem statement; the OP can state the problem he wants answered in the question itself. We don't like "link only" questions here.