How to generate nested tree of offsets based on index permutation C++ - c++

I got the following offsets which reset and go to the next offset if offset value hits 0xC. The last offset is always 0xC.
How do I generate the nested tree of offsets based on index.
The pattern goes like this
0,C = index 0
4,C = index 1
8,C = index 2
0,0,C = index 3
0,4,C = index 4
0,8,C = index 5
4,0,C = index 6
4,4,C = index 7
4,8,C = index 8
8,0,C = index 9
8,4,C = index 10
8,8,C = index 11
0,0,0,C = index 12
and so on and so on.

#include <stdio.h>
int main() {
int offset_0 = 0;
int offset_1 = 0;
int offset_2 = 0;
int offset_3 = 0;
int offset_4 = 0;
bool offset_0_activate = true;
bool offset_1_activate = false;
bool offset_2_activate = false;
bool offset_3_activate = false;
int index = 100;
for (int i = 0; i < index; i++) {
offset_0 += 4;
if (offset_0 == 0xC) {
offset_0 = 0;
offset_1 += 4;
}
if (offset_1 == 0xC) {
offset_1 = 0;
offset_2 += 4;
}
if (offset_2 == 0xC) {
offset_2 = 0;
offset_3 += 4;
}
if (offset_3 == 0xC) {
break;
}
printf("index = %d offset0 = %d offset1 = %d offset2 = %d offset3 = %d\n", i, offset_0, offset_1, offset_2, offset_3);
}
}

Related

Creating an X amount of rectangles which are not intersecting each other on a specified screen size

I managed with some help to know how when two rectangles are intersecting each other, from there it should be easy to make what i just said in the title but ...
So, short story of what i just did below:
Created a for loop from 1 to Number_of_Obstacles
In that for an random obstacle (rectangle/square) is created and it will be checked if it is overlaped with all other obstacles created from 0 to the loop contor (or in other words every obstacle stored in the vector)
Again, the doOverLap function works. Tested it with a square which i made a controller and other random rectangle created on the screen. It outputs in chat when i'm overlaping it and trust me, i overlaped it from all angles.
Here is a picture with the overlaping issue: https://imgur.com/a/ZzorOcD
bool doOverlap(A a, B b)
{
if (a.x1 > b.x2 || b.x1 > a.x2)
return false;
if (a.y1 > b.y2 || b.y1 > a.y2)
return false;
return true;
}
struct Obstacles {
int X, Y;
void Create_Random_Obstacles(Obstacles Obj[], int Numar_Obstacole)
{
srand(time(NULL));
A Rectangle_1;
B Rectangle_2;
/* To avoid rendering outside of the screen */
int X_Axis = X_RESOLUTION - 40;
int Y_Axis = Y_RESOLUTION - 40;
int obstacolX = rand() % X_Axis + 1;
int obstacolY = rand() % Y_Axis + 1;
Obj[0].X = obstacolX;
Obj[0].Y = obstacolY;
for (int i = 1; i < Numar_Obstacole; i++)
{
obstacolX = rand() % X_Axis + 1;
obstacolY = rand() % Y_Axis + 1;
Rectangle_1.x1 = obstacolX;
Rectangle_1.x2 = obstacolX + 40;
Rectangle_1.y1 = obstacolY;
Rectangle_1.y2 = obstacolY + 40;
for (int j = 0; j < i; j++) {
Rectangle_2.x1 = Obj[j].X;
Rectangle_2.x2 = Obj[j].X + 40;
Rectangle_2.y1 = Obj[j].Y;
Rectangle_2.y2 = Obj[j].Y + 40;
if (doOverlap(Rectangle_1, Rectangle_2))
{
std::cout << "Overlap\n";
}
else
{
Obj[i].X = obstacolX;
Obj[i].Y = obstacolY;
}
}
}
}
void Render(SDL_Renderer* renderer, Obstacles Obj[], int Numar_Obstacole) {
for (int i = 0; i < Numar_Obstacole; i++)
{
SDL_Rect r{ Obj[i].X, Obj[i].Y, 40, 40 };
SDL_SetRenderDrawColor(renderer, 255, 160, 15, 255);
SDL_RenderFillRect(renderer, &r);
}
}
};
Restart selection when collision occurs, something like:
bool Has_Overlap(const Obstacles& obj, const Obstacles* Objs, int Size)
{
B Rectangle_2;
Rectangle_2.x1 = obs.X;
Rectangle_2.x2 = obs.X + 40;
Rectangle_2.y1 = obs.Y;
Rectangle_2.y2 = obs.Y + 40;
for (int i = 0; i != Size; ++i) {
A Rectangle_1;
Rectangle_1.x1 = Obs[i].X;
Rectangle_1.x2 = Obs[i].X + 40;
Rectangle_1.y1 = Obs[i].Y;
Rectangle_1.y2 = Obs[i].Y + 40;
if (doOverlap(Rectangle_1, Rectangle_2)) {
return true;
}
}
return false;
}
void Create_Random_Obstacles(Obstacles* Objs, int Size)
{
/* To avoid rendering outside of the screen */
const int X_Axis = X_RESOLUTION - 40;
const int Y_Axis = Y_RESOLUTION - 40;
for (int i = 0; i < Size; i++)
{
do {
Objs[i].X = rand() % X_Axis + 1;
Objs[i].Y = rand() % Y_Axis + 1;
} while (Has_Overlap(Objs[i], Objs, i));
}
}

VS Express dosen't compile the code properly (?) [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 3 years ago.
Improve this question
So I used to use Code::Blocks IDE, and like it a lot. Recently I switched to Visual Studio. I downloaded VS Express, it was 600mb and I can only use 1gb data per day, I don't have Wi-Fi, so I that was my only option.I inserted the same code that compiled properly in Code::Blocks in it , it took a few tweaks to make it work in VS, but when I finally check it, the output was totally different, Instead of a command line Tetris, it glitched and filled the command prompt with strange characters.
This is the code I tweaked a bit to make it work in VS:
#include <iostream>
#include <time.h>
#include <string>
#include <windows.h>
using namespace std;
int nScreenHeight = 30;
int nScreenWidth = 80;
int nFieldWidth = 10;
int nFieldHeight = 25;
unsigned char *pField = NULL;
wstring tetromine[7];
int currentPiece = 0;
int currentRotation = 0;
int currentX = (nFieldWidth/2);
int currentY = 0;
unsigned int score = 0;
int pieceCounter = 0;
int speed = 20;
int speedCounter = 0;
bool forcePieceDown =false;
bool key[4];
bool shiftGridDown = false;
int rotate(int px,int py,int r)
{
switch(r/90)
{
case 0:
return py*4+px;//0 degs
case 1:
return 12+py - (px*4);//90 degs
case 2:
return 15 - (py*4) - px;//180 degs
case 3:
return 3 - py + (px*4);//270 degs
}
return 0;
}
int doesPieceFit(int id,int rot, int x, int y)
{
for(int px = 0;px<4;px++){
for(int py = 0;py<4;py++){
int pi = rotate(px,py,rot);
int fi = (y+py) * nFieldWidth + (x+px);
if(x + px>= 0 && x+px < nFieldWidth){
if(tetromine[id][pi] == L'X' && pField[fi]!=0){
return false;
}
}
}
}
return true;
}
void lineCheck(){
bool line = true;
int lines = 0;
for(int y = 0; y<= nFieldHeight-1;y++){
for(int x = 1; x< nFieldWidth-1;x++){
if(pField[(y)*nFieldWidth+x]!=0){
line &= true;
} else line &= false;
}
if(line) lines++;
if(line){
for(int x = 1; x< nFieldWidth-1;x++){
pField[(y)*nFieldWidth+x] = 8;
}
}
}
}
int main()
{
//assets
tetromine[0].append(L"..X.");
tetromine[0].append(L"..X.");
tetromine[0].append(L"..X.");
tetromine[0].append(L"..X.");
tetromine[1].append(L"..X.");
tetromine[1].append(L".XX.");
tetromine[1].append(L".X..");
tetromine[1].append(L"....");
tetromine[2].append(L".X..");
tetromine[2].append(L".XX.");
tetromine[2].append(L"..X.");
tetromine[2].append(L"....");
tetromine[3].append(L"....");
tetromine[3].append(L".XX.");
tetromine[3].append(L".XX.");
tetromine[3].append(L"....");
tetromine[4].append(L"..X.");
tetromine[4].append(L".XX.");
tetromine[4].append(L"..X.");
tetromine[4].append(L"....");
tetromine[5].append(L"....");
tetromine[5].append(L".XX.");
tetromine[5].append(L"..X.");
tetromine[5].append(L"..X.");
tetromine[6].append(L"....");
tetromine[6].append(L".XX.");
tetromine[6].append(L".X..");
tetromine[6].append(L".X..");
pField = new unsigned char[nFieldWidth*nFieldHeight];
for(int x = 0; x<nFieldWidth; x++)
{
for(int y = 0; y<nFieldHeight; y++)
{
pField[y*nFieldWidth + x] = (x==0||x==nFieldWidth -1 || y == nFieldHeight - 1) ? 9 : 0;
}
}
char *screen = new char [nScreenWidth * nScreenHeight];
HANDLE hConsole = CreateConsoleScreenBuffer(GENERIC_READ | GENERIC_WRITE, 0, NULL, CONSOLE_TEXTMODE_BUFFER, NULL);
SetConsoleActiveScreenBuffer(hConsole);
DWORD dwBytesWritten = 0;
//Display frame
COORD here;
here.X = 0;
here.Y = 0;
WriteConsoleOutputCharacter(hConsole, (LPCWSTR)screen, nScreenWidth * nScreenHeight,here, &dwBytesWritten);
bool gameOver = false;
while(!gameOver)
{
Sleep(100);
speedCounter++;
if(speedCounter>=speed){
forcePieceDown = true;
speedCounter = 0;
} else {
forcePieceDown = false;
}
if(shiftGridDown){
score++;
for(int y = nFieldHeight-2;y > 0;y--){
for(int x = 1;x<nFieldWidth -1;x++){
if((pField[(y)*nFieldWidth+x]) != 0){
pField[(y+1)*nFieldWidth+x] = pField[(y)*nFieldWidth+x];
pField[(y)*nFieldWidth+x] = 0;
}
}
}
shiftGridDown = false;
lineCheck();
}
for(int x = 1; x< nFieldWidth-1;x++){
if(pField[(nFieldHeight-2)*nFieldWidth+x]==8){
pField[(nFieldHeight-2)*nFieldWidth+x]=0;
if(x==nFieldWidth-2){
shiftGridDown = true;
score+=100;
}
}
}
for(int k = 0;k<4;k++){ // R L D Z
key[k] = (0x8000 & GetAsyncKeyState((unsigned char)("DASZ"[k]))) != 0;
}
if(key[1]){
if(doesPieceFit(currentPiece,currentRotation,currentX-1,currentY)){
currentX = currentX-1;
}
}else if(key[0]){
if(doesPieceFit(currentPiece,currentRotation,currentX+1,currentY)){
currentX = currentX+1;
}
}if(key[2]){
speedCounter = speed;
}
if(key[3]&&doesPieceFit(currentPiece,currentRotation+90,currentX,currentY)){
(currentRotation+90<=270)?currentRotation+=90:currentRotation=0;
}
if(forcePieceDown){
if(doesPieceFit(currentPiece,currentRotation,currentX,currentY+1))
currentY++;
else {
//lock piece
pieceCounter++;
if(pieceCounter%5==0){
speed-=1;
}
for(int px = 0;px<4;px++){
for(int py = 0;py<4;py++){
if(tetromine[currentPiece][rotate(px,py,currentRotation)]==L'X'){
pField[(currentY+py)*nFieldWidth+(currentX+px)] = currentPiece+1;
}
}
}
score+=20;
//check lines
lineCheck();
//get next piece
currentX = nFieldWidth/2;
currentY = 0;
currentRotation = 0;
srand(time(0));
currentPiece = rand() % 7;
//check game over
gameOver = !doesPieceFit(currentPiece,currentRotation,currentX,currentY);
}
}
//draw field
for(int x = 0; x < nFieldWidth; x++)
{
for(int y = 0; y < nFieldHeight; y++)
{
screen[(y+2)*nScreenWidth + (x+ 2)] = L" xxxxxxx=#"[pField[y*nFieldWidth + x]];
}
}
//draw piece
for(int px = 0;px<4;px++){
for(int py = 0;py<4;py++){
if(tetromine[currentPiece][rotate(px,py,currentRotation)] == L'X'){
screen[(currentY+py+2)*nScreenWidth+(currentX+px+2)] = '+';
}
}
}
string s("Score -> ");
string num;
int tmp = score;
while(tmp!=0){
int rem = tmp%10;
tmp /= 10;
num = ((char)(48+rem)) + num;
}
s+=num;
for(int i = 0; i<s.size();i++){
screen[i] = s[i];
}
//display frame
WriteConsoleOutputCharacter(hConsole, (LPCWSTR)screen, nScreenWidth * nScreenHeight,here, &dwBytesWritten);
}
return 0;
}
This is the origional code :
#include <iostream>
#include <time.h>
#include <string>
#include <windows.h>
using namespace std;
int nScreenHeight = 30;
int nScreenWidth = 80;
int nFieldWidth = 10;
int nFieldHeight = 25;
unsigned char *pField = NULL;
wstring tetromine[7];
int currentPiece = 0;
int currentRotation = 0;
int currentX = (nFieldWidth/2);
int currentY = 0;
unsigned int score = 0;
int pieceCounter = 0;
int speed = 20;
int speedCounter = 0;
bool forcePieceDown =false;
bool key[4];
bool shiftGridDown = false;
int rotate(int px,int py,int r)
{
switch(r/90)
{
case 0:
return py*4+px;//0 degs
case 1:
return 12+py - (px*4);//90 degs
case 2:
return 15 - (py*4) - px;//180 degs
case 3:
return 3 - py + (px*4);//270 degs
}
return 0;
}
int doesPieceFit(int id,int rot, int x, int y)
{
for(int px = 0;px<4;px++){
for(int py = 0;py<4;py++){
int pi = rotate(px,py,rot);
int fi = (y+py) * nFieldWidth + (x+px);
if(x + px>= 0 && x+px < nFieldWidth){
if(tetromine[id][pi] == L'X' && pField[fi]!=0){
return false;
}
}
}
}
return true;
}
void lineCheck(){
bool line = true;
int lines = 0;
for(int y = 0; y<= nFieldHeight-1;y++){
for(int x = 1; x< nFieldWidth-1;x++){
if(pField[(y)*nFieldWidth+x]!=0){
line &= true;
} else line &= false;
}
if(line) lines++;
if(line){
for(int x = 1; x< nFieldWidth-1;x++){
pField[(y)*nFieldWidth+x] = 8;
}
}
}
}
int main()
{
//assets
tetromine[0].append(L"..X.");
tetromine[0].append(L"..X.");
tetromine[0].append(L"..X.");
tetromine[0].append(L"..X.");
tetromine[1].append(L"..X.");
tetromine[1].append(L".XX.");
tetromine[1].append(L".X..");
tetromine[1].append(L"....");
tetromine[2].append(L".X..");
tetromine[2].append(L".XX.");
tetromine[2].append(L"..X.");
tetromine[2].append(L"....");
tetromine[3].append(L"....");
tetromine[3].append(L".XX.");
tetromine[3].append(L".XX.");
tetromine[3].append(L"....");
tetromine[4].append(L"..X.");
tetromine[4].append(L".XX.");
tetromine[4].append(L"..X.");
tetromine[4].append(L"....");
tetromine[5].append(L"....");
tetromine[5].append(L".XX.");
tetromine[5].append(L"..X.");
tetromine[5].append(L"..X.");
tetromine[6].append(L"....");
tetromine[6].append(L".XX.");
tetromine[6].append(L".X..");
tetromine[6].append(L".X..");
pField = new unsigned char[nFieldWidth*nFieldHeight];
for(int x = 0; x<nFieldWidth; x++)
{
for(int y = 0; y<nFieldHeight; y++)
{
pField[y*nFieldWidth + x] = (x==0||x==nFieldWidth -1 || y == nFieldHeight - 1) ? 9 : 0;
}
}
char *screen = new char [nScreenWidth * nScreenHeight];
HANDLE hConsole = CreateConsoleScreenBuffer(GENERIC_READ | GENERIC_WRITE, 0, NULL, CONSOLE_TEXTMODE_BUFFER, NULL);
SetConsoleActiveScreenBuffer(hConsole);
DWORD dwBytesWritten = 0;
//Display frame
WriteConsoleOutputCharacter(hConsole, screen, nScreenWidth * nScreenHeight, {0,0}, &dwBytesWritten);
bool gameOver = false;
while(!gameOver)
{
Sleep(100);
speedCounter++;
if(speedCounter>=speed){
forcePieceDown = true;
speedCounter = 0;
} else {
forcePieceDown = false;
}
if(shiftGridDown){
score++;
for(int y = nFieldHeight-2;y > 0;y--){
for(int x = 1;x<nFieldWidth -1;x++){
if((pField[(y)*nFieldWidth+x]) != 0){
pField[(y+1)*nFieldWidth+x] = pField[(y)*nFieldWidth+x];
pField[(y)*nFieldWidth+x] = 0;
}
}
}
shiftGridDown = false;
lineCheck();
}
for(int x = 1; x< nFieldWidth-1;x++){
if(pField[(nFieldHeight-2)*nFieldWidth+x]==8){
pField[(nFieldHeight-2)*nFieldWidth+x]=0;
if(x==nFieldWidth-2){
shiftGridDown = true;
score+=100;
}
}
}
for(int k = 0;k<4;k++){ // R L D Z
key[k] = (0x8000 & GetAsyncKeyState((unsigned char)("DASZ"[k]))) != 0;
}
if(key[1]){
if(doesPieceFit(currentPiece,currentRotation,currentX-1,currentY)){
currentX = currentX-1;
}
}else if(key[0]){
if(doesPieceFit(currentPiece,currentRotation,currentX+1,currentY)){
currentX = currentX+1;
}
}if(key[2]){
speedCounter = speed;
}
if(key[3]&&doesPieceFit(currentPiece,currentRotation+90,currentX,currentY)){
(currentRotation+90<=270)?currentRotation+=90:currentRotation=0;
}
if(forcePieceDown){
if(doesPieceFit(currentPiece,currentRotation,currentX,currentY+1))
currentY++;
else {
//lock piece
pieceCounter++;
if(pieceCounter%5==0){
speed-=1;
}
for(int px = 0;px<4;px++){
for(int py = 0;py<4;py++){
if(tetromine[currentPiece][rotate(px,py,currentRotation)]==L'X'){
pField[(currentY+py)*nFieldWidth+(currentX+px)] = currentPiece+1;
}
}
}
score+=20;
//check lines
lineCheck();
//get next piece
currentX = nFieldWidth/2;
currentY = 0;
currentRotation = 0;
srand(time(0));
currentPiece = rand() % 7;
//check game over
gameOver = !doesPieceFit(currentPiece,currentRotation,currentX,currentY);
}
}
//draw field
for(int x = 0; x < nFieldWidth; x++)
{
for(int y = 0; y < nFieldHeight; y++)
{
screen[(y+2)*nScreenWidth + (x+ 2)] = L" xxxxxxx=#"[pField[y*nFieldWidth + x]];
}
}
//draw piece
for(int px = 0;px<4;px++){
for(int py = 0;py<4;py++){
if(tetromine[currentPiece][rotate(px,py,currentRotation)] == L'X'){
screen[(currentY+py+2)*nScreenWidth+(currentX+px+2)] = '+';
}
}
}
string s("Score -> ");
string num;
int tmp = score;
while(tmp!=0){
int rem = tmp%10;
tmp /= 10;
num = ((char)(48+rem)) + num;
}
s+=num;
for(int i = 0; i<s.size();i++){
screen[i] = s[i];
}
//display frame
WriteConsoleOutputCharacter(hConsole, screen, nScreenWidth * nScreenHeight, { 0, 0}, &dwBytesWritten);
}
return 0;
}
You have a mix of narrow and wide characters. The cast (LPCWSTR)screen in your call to WriteConsoleOutputCharacter is an indication something isn't right.
In this case, screen is a char but you want it to be wchar_t instead. You're already using wstring for tetromine, and L prefixed character strings. You just need to ensure the rest of the code is also using wide characters.

Why I'm getting different results from GNU g++ and VC++

I'm trying to solve this problem in C++:
"Given a sequence S of integers, find a number of increasing sequences I such that every two consecutive elements in I appear in S, but on the opposite sides of the first element of I."
This is the code I've developed:
#include<iostream>
#include<set>
#include<vector>
using namespace std;
struct Element {
long long height;
long long acc;
long long con;
};
bool fncomp(Element* lhs, Element* rhs) {
return lhs->height < rhs->height;
}
int solution(vector<int> &H) {
// set up
int N = (int)H.size();
if (N == 0 || N == 1) return N;
long long sol = 0;
// build trees
bool(*fn_pt)(Element*, Element*) = fncomp;
set<Element*, bool(*)(Element*, Element*)> rightTree(fn_pt), leftTree(fn_pt);
set<Element*, bool(*)(Element*, Element*)>::iterator ri, li;
for (int i = 0; i < N; i++) {
Element* e = new Element;
e->acc = 0;
e->con = 0;
e->height = H[i];
rightTree.insert(e);
}
//tree elements set up
ri = --rightTree.end();
Element* elem = *ri;
elem->con = 1;
elem->acc = 1;
while (elem->height > H[0]) {
Element* succ = elem;
ri--;
elem = *ri;
elem->con = 1;
elem->acc = succ->acc + 1;
}
rightTree.erase(ri);
elem->con = elem->acc;
leftTree.insert(elem);
sol += elem->acc;
// main loop
Element* pE = new Element;
for (int j = 1; j < (N - 1); j++) {
// bad case
if (H[j] < H[j - 1]) {
///////
Element* nE = new Element;
nE->height = H[j];
pE->height = H[j - 1];
rightTree.erase(nE);
leftTree.insert(nE);
///////
li = leftTree.lower_bound(pE);
long ltAcc = (*li)->acc;
li--;
///////
ri = rightTree.lower_bound(pE);
long rtAcc = 0;
if (ri != rightTree.end()) rtAcc = (*ri)->acc;
ri--;
///////
while (ri != (--rightTree.begin()) && (*ri)->height > H[j]) {
if (fncomp(*ri, *li)) {
(*li)->con = rtAcc + 1;
(*li)->acc = rtAcc + 1 + ltAcc;
ltAcc = (*li)->acc;
--li;
}
else {
(*ri)->con = ltAcc + 1;
(*ri)->acc = ltAcc + 1 + rtAcc;
rtAcc = (*ri)->acc;
--ri;
}
}
while ((*li)->height > H[j]) {
(*li)->con = rtAcc + 1;
(*li)->acc = rtAcc + 1 + ltAcc;
ltAcc = (*li)->acc;
--li;
}
(*li)->con = rtAcc + 1;
(*li)->acc = rtAcc + 1 + ltAcc;
sol += (*li)->acc;
}
// good case
else {
Element* nE = new Element;
nE->height = H[j];
ri = rightTree.upper_bound(nE);
li = leftTree.upper_bound(nE);
rightTree.erase(nE);
if (li == leftTree.end() && ri == rightTree.end()) {
nE->con = 1;
nE->acc = 1;
}
else if (li != leftTree.end() && ri == rightTree.end()) {
nE->con = 1;
nE->acc = 1 + (*li)->acc;
}
else if (li == leftTree.end() && ri != rightTree.end()) {
nE->con = (*ri)->acc + 1;
nE->acc = nE->con;
}
else {
nE->con = (*ri)->acc + 1;
nE->acc = nE->con + (*li)->acc;
}
leftTree.insert(nE);
sol += nE->acc;
}
}
// final step
li = leftTree.upper_bound(*rightTree.begin());
while (li != leftTree.end()) {
sol++;
li++;
}
sol++;
return (int)(sol % 1000000007);
}
int main(int argc, char* argv[]) {
vector<int> H = { 13, 2, 5 };
cout << "sol: " << solution(H) << endl;
system("pause");
}
The main function calls solution(vector<int> H). The point is, when the argument has the particular value of H = {13, 2, 5} the VC++ compiled program give an output value of 7 (which is the correct one), but the GNU g++ compiled program give an output value of 5 (also clang compiled program behave like this).
I'm using this website, among others, for testing different compilers
http://rextester.com/l/cpp_online_compiler_gcc
I've tried to figure out the reason for this wierd behaviour but didn't found any relevant info. Only one post treat a similar problem:
Different results VS C++ and GNU g++
and that's why I'm using long long types in the code, but the problem persists.
The problem was decrementing the start-of-sequence --rightTree.begin()
As I found VC++ and GNU g++ does not behave the same way on above operation. Here is the code that shows the difference, adapted from http://www.cplusplus.com/forum/general/84609/:
#include<iostream>
#include<set>
using namespace std;
struct Element {
long long height;
long long acc;
long long con;
};
bool fncomp(Element* lhs, Element* rhs) {
return lhs->height < rhs->height;
}
int main(){
bool(*fn_pt)(Element*, Element*) = fncomp;
set<Element*, bool(*)(Element*, Element*)> rightTree(fn_pt);
set<Element*, bool(*)(Element*, Element*)>::iterator ri;
ri = rightTree.begin();
--ri;
++ri;
if(ri == rightTree.begin()) cout << "it works!" << endl;
}

Consistent monotonic subsequence

I have problem with this algorithm. It should search for longest consistent and monotonic subsequence and sum of it. If there are few subsequense with the same length it should return the first one.
It should work as monotonic function - http://en.wikipedia.org/wiki/Monotonic_function
For input : 1 1 7 3 2 0 0 4 5 5 6 2 1
the result is : 6 20 - so it works.
But for input : 23 34 11 5 23 90 11 10 15 12 28 49
the result is : 3 113 - but should be 3 50
I feel that the problem is in switching between increasing and decreasing case. Any idea?
code :
#include <stdio.h>
#define gc getchar
void scan_integer(unsigned long long int* o)
{
register unsigned long long int c = gc();
int x = 0;
for (; ((c<48 || c>57)); c = gc());
for (; c>47 && c<58; c = gc()) {
x = (x << 1) + (x << 3) + c - 48;
}
*o = x;
}
int main(){
unsigned long long int current_value, last_value, sum_increasing, sum_decreasing, length_increasing, length_decreasing, max_length, max_sum, is_increasing;
bool equal = false;
scan_integer(&current_value);
last_value = 0;
sum_increasing = current_value;
sum_decreasing = current_value;
length_increasing = 1;
length_decreasing = 1;
max_length = 1;
max_sum = current_value;
is_increasing = 0;
while (!feof(stdin))
{
last_value = current_value;
scan_integer(&current_value);
if (current_value == last_value){
sum_increasing += current_value;
sum_decreasing += current_value;
length_increasing += 1;
length_decreasing += 1;
equal = true;
}
else {
if (current_value > last_value){
sum_increasing += current_value;
length_increasing += 1;
if (equal == true){
length_decreasing = 1;
sum_decreasing = 0;
equal = false;
}
if (is_increasing < 0){
sum_increasing += last_value;
if (length_decreasing > max_length){
max_length = length_decreasing;
max_sum = sum_decreasing;
}
sum_decreasing = 0;
length_decreasing = 1;
}
is_increasing = 1;
}
else {
sum_decreasing += current_value;
length_decreasing += 1;
if (equal == true){
length_increasing = 1;
sum_increasing = 0;
equal = false;
}
if (is_increasing == 1){
sum_decreasing += last_value;
if (length_increasing > max_length){
max_length = length_increasing;
max_sum = sum_increasing;
}
sum_increasing = 0;
length_increasing = 1;
}
is_increasing = -1;
}
}
}
printf("%llu %llu", max_length, max_sum);
return 0;
}
I see a problem in the code, in this part:
is_increasing = 1; // here
// Did you mean to write a continue here?
}
else {
sum_decreasing += current_value;
length_decreasing += 1;
if (equal == true){
length_increasing = 1;
sum_increasing = 0;
equal = false;
}
if (is_increasing == 1){
sum_decreasing += last_value;
if (length_increasing > max_length){
max_length = length_increasing;
max_sum = sum_increasing;
}
sum_increasing = 0;
length_increasing = 1;
}
is_increasing = -1; // Or you might want to put this inside of the else above
If I understand correctly, 'is_increasing = -1' at the bottom completely invalidates the setting of it in the true condition of the if statemen (at the top of the code above). That's why, In the "else" that handles decreasing sequences 'is_increasing' always has the value of '-1' and such sequences never get saved as good sequences.
I put some codes in the code I copied and pasted. I think that handling the codition at which two numbers in sequence might need a little more care than those comments, but this should set you in the right direction.
Let me know if this helps.

C++ Not Counting white beands

I need some help. I'm writing a code in C++ that will ultimately take a random string passed in, and it will do a break at every point in the string, and it will count the number of colors to the right and left of the break (r, b, and w). Here's the catch, the w can be either r or b when it breaks or when the strong passes it ultimately making it a hybrid. My problem is when the break is implemented and there is a w immediately to the left or right I can't get the program to go find the fist b or r. Can anyone help me?
#include <stdio.h>
#include "P2Library.h"
void doubleNecklace(char neck[], char doubleNeck[], int size);
int findMaxBeads(char neck2[], int size);
#define SIZE 7
void main(void)
{
char necklace[SIZE];
char necklace2[2 * SIZE];
int brk;
int maxBeads;
int leftI, rightI, leftCount = 0, rightCount=0, totalCount, maxCount = 0;
char leftColor, rightColor;
initNecklace(necklace, SIZE);
doubleNecklace(necklace, necklace2, SIZE);
maxBeads = findMaxBeads(necklace2, SIZE * 2);
checkAnswer(necklace, SIZE, maxBeads);
printf("The max number of beads is %d\n", maxBeads);
}
int findMaxBeads(char neck2[], int size)
{
int brk;
int maxBeads;
int leftI, rightI, leftCount = 0, rightCount=0, totalCount, maxCount = 0;
char leftColor, rightColor;
for(brk = 0; brk < 2 * SIZE - 1; brk++)
{
leftCount = rightCount = 0;
rightI = brk;
rightColor = neck2[rightI];
if(rightI == 'w')
{
while(rightI == 'w')
{
rightI++;
}
rightColor = neck2[rightI];
}
rightI = brk;
while(neck2[rightI] == rightColor || neck2[rightI] == 'w')
{
rightCount++;
rightI++;
}
if(brk > 0)
{
leftI = brk - 1;
leftColor = neck2[leftI];
if(leftI == 'w')
{
while(leftI == 'w')
{
leftI--;
}
leftColor = neck2[leftI];
}
leftI = brk - 1;
while(leftI >= 0 && neck2[leftI] == leftColor || neck2[leftI] == 'w')
{
leftCount++;
leftI--;
}
}
totalCount = leftCount + rightCount;
if(totalCount > maxCount)
{
maxCount = totalCount;
}
}
return maxCount;
}
void doubleNecklace(char neck[], char doubleNeck[], int size)
{
int i;
for(i = 0; i < size; i++)
{
doubleNeck[i] = neck[i];
doubleNeck[i+size] = neck[i];
}
}
I didn't study the code in detail, but something is not symmetric: in the for loop, the "left" code has an if but the "right" code doesn't. Maybe you should remove that -1 in the for condition and add it as an if for the "right" code:
for(brk = 0; brk < 2 * SIZE; brk++)
{
leftCount = rightCount = 0;
if (brk < 2 * SIZE - 1)
{
rightI = brk;
rightColor = neck2[rightI];
//...
}
if(brk > 0)
{
leftI = brk - 1;
leftColor = neck2[leftI];
//...
}
//...
Just guessing, though... :-/
Maybe you should even change those < for <=.