#define OLC_PGE_HEADLESS
#define OLC_PGE_APPLICATION
#include "pixelGameEngine.h"

using namespace olc;

struct Data{
    long value; //Number.
    int position; //Current position in the list.
};

int main()
{
	std::ifstream file("input");
    std::vector<Data*>originalSet;
    std::vector<Data*>newSet;
    while (file.good()){
        std::string line;
        std::getline(file,line);
        //std::cout<<line<<std::endl;
        if (line.length()>0){
            Data*data=new Data{std::atoi(line.c_str())*811589153l,(int)originalSet.size()};
            originalSet.push_back(data);
            newSet.push_back(data);
        }
    }
    std::cout<<std::endl;
            for (int i=0;i<newSet.size();i++){
                if (i!=0){
                    std::cout<<",";
                }
                std::cout<<newSet[i]->value<<" ["<<newSet[i]->position<<"]";
            }
    std::cout<<std::endl;
    for (int j=0;j<10;j++){
        for (int i=0;i<originalSet.size();i++){
            Data*val=originalSet[i];
            int pos=val->position;
            Data*temp=newSet[pos];
            long shift=(val->value)%(long)(originalSet.size()-1l);
            std::cout<<"Shift value is "<<shift<<std::endl;
            while (shift!=0){
                if (shift>0){
                    //Move it to the right of the list.
                    int newPos=(pos+1)%newSet.size();
                    /*std::cout<<"  Swap "<<newSet[pos]->value<<" ["<<newSet[pos]->position<<"]";
                    std::cout<<"  with "<<newSet[newPos]->value<<" ["<<newSet[newPos]->position<<"]"<<std::endl;*/
                    newSet[pos]=newSet[newPos];
                    newSet[newPos]=temp;
                    newSet[newPos]->position=newPos;
                    newSet[pos]->position=pos;
                    shift--;
                    pos=newPos;
                } else {
                    //Move it to the left of the list.
                    int newPos=pos-1;
                    if (newPos<0){
                        newPos=newSet.size()-1;
                    }   
                    /*std::cout<<"  Swap "<<newSet[pos]->value<<" ["<<newSet[pos]->position<<"]";
                    std::cout<<"  with "<<newSet[newPos]->value<<" ["<<newSet[newPos]->position<<"]";*/
                    newSet[pos]=newSet[newPos];
                    newSet[newPos]=temp;
                    newSet[newPos]->position=newPos;
                    newSet[pos]->position=pos;
                    shift++;
                    pos=newPos;
                }
            }
            /*std::cout<<std::endl;
            for (int i=0;i<newSet.size();i++){
                if (i!=0){
                    std::cout<<",";
                }
                std::cout<<newSet[i]->value<<" ["<<newSet[i]->position<<"]";
            }
            std::cout<<std::endl;*/
        }
        std::cout<<std::endl;
        std::cout<<"Round "<<j+1<<std::endl;
        for (int i=0;i<newSet.size();i++){
            if (i!=0){
                std::cout<<",";
            }
            std::cout<<newSet[i]->value<<" ["<<newSet[i]->position<<"]";
        }
        std::cout<<std::endl;
    }

    Data*zeroVal;

    for (int i=0;i<newSet.size();i++){
        if (newSet[i]->value==0){
            zeroVal=newSet[i];
            break;
        }
    }

    int offset=(zeroVal->position+1000)%newSet.size();
    int offset2=(zeroVal->position+2000)%newSet.size();
    int offset3=(zeroVal->position+3000)%newSet.size();

    std::cout<<"1000: "<<newSet[offset]->value<<std::endl;
    std::cout<<"2000: "<<newSet[offset2]->value<<std::endl;
    std::cout<<"3000: "<<newSet[offset3]->value<<std::endl;

    long sum=newSet[offset]->value+newSet[offset2]->value+newSet[offset3]->value;
    std::cout<<"Sum: "<<sum<<std::endl;
    

	return 0;
}
