// compile with g++ -o stones stones.c // run it with say ./stones 0 // to get a solution for n=934*0+528, in general for n=934*t+528 #include #include #include #include using namespace std; #define H 13 int dxy[4][2]={{0,1},{1,0},{0,-1},{-1,0}}; int AMIN,AMAX; unordered_map>>coords; unordered_map values; bool check_abw(int val,int p){ return (val>=AMIN && val<=AMAX && (val-AMIN)%(24*H)==0 && (val/3-3*(2*p+1))%(6*H) != 3*H); } void set_value(int x,int y,int val){ string s=to_string(x)+" "+to_string(y); if(values.count(s)>0)return; values[s]=val; coords[val].push_back({x,y}); } void check_grid(void){ int maxk=1; for(auto it=coords.begin();it!=coords.end();++it) maxk=max(maxk,it->first); for(int k=2;k<=maxk;k++){ int size=coords[k].size(); if(size>1){printf("Error: k=%d appears %d times.\n",k,size);exit(1);} if(size==0){printf("Error: k=%d is not on the grid;\n",k);exit(1);} int x0=coords[k][0].first; int y0=coords[k][0].second; int sum=0; for(int u=-1;u<=1;u++)for(int v=-1;v<=1;v++)if(u!=0 || v!=0){ string st=to_string(x0+u)+" "+to_string(y0+v); if(values.count(st)>0 && values[st]=%d.\n",maxk,(int)coords[1].size(),(int)coords[1].size(),maxk); } void show_map(void){ int x0=INT_MAX,x1=INT_MIN,y0=INT_MAX,y1=INT_MIN; for(auto it=coords.begin();it!=coords.end();++it){ for(auto a:(it->second)){ x0=min(x0,a.first); x1=max(x1,a.first); y0=min(y0,a.second); y1=max(y1,a.second); } } FILE* fout; fout=fopen("stones_example.txt","w"); for(int y=y1;y>=y0;y--){ for(int x=x0;x<=x1;x++){ string s=to_string(x)+" "+to_string(y); if(values.count(s)>0)fprintf(fout,"%6d",values[s]); else fprintf(fout," "); } fprintf(fout,"\n"); } fclose(fout); fout=fopen("stones_coords.txt","w"); for(int k=1;;k++){ if(coords.count(k)==0)break; for(auto a:coords[k]) fprintf(fout,"%d (%d,%d)\n",k,a.first,a.second); } fclose(fout); } void add_house(int x,int y,int p,int dir,int val,int num_ones,bool set_ones=false,int change_dir=0){ int new_dir=(change_dir==0?1:3); if(num_ones<0){ num_ones=-num_ones; for(int i=1;i<=3*num_ones-1;i++){ set_value(x,y,val); if(i%3==2 && set_ones){ set_value(x+dxy[(dir+new_dir)%4][0],y+dxy[(dir+new_dir)%4][1],1); } x+=dxy[dir][0]; y+=dxy[dir][1]; val++; } return; } for(int i=1;i<=6*num_ones+1;i++){ if(i==1 && check_abw(4*val+12*H-4,p)){// point W set_value(x+dxy[(dir+new_dir)%4][0],y+dxy[(dir+new_dir)%4][1],4*val+12*H-3); } else if(i==3*num_ones && check_abw(2*val,p)){//point A set_value(x,y,2*val); } else if(i==3*num_ones+2 && check_abw(2*val-2,p)){//point B set_value(x,y,2*val); } if(i!=3*num_ones && i!=3*num_ones+2){ set_value(x,y,val); val++; } if(i<=3*num_ones && i%3==2 && set_ones){ set_value(x+dxy[(dir+new_dir)%4][0],y+dxy[(dir+new_dir)%4][1],1); } if(i==3*num_ones || i==3*num_ones+2){ dir=(dir+new_dir)%4; } x+=dxy[dir][0]; y+=dxy[dir][1]; } } int get_dir(int x,int p,int res){ if((x<3*p && res<3*H) || (x>3*p && res>3*H)) return 2; return 0; } void fun(int p){ AMIN=24*p+168; AMAX=36*p-216; add_house(0,0,p,0,1,p,true); set_value(1,-2,1); set_value(2,-1,6*p); set_value(2,-2,6*p+1); set_value(2,-3,6*p+2); // add main branches int dir,x0,y0,x; for(x=2*p+1;x<=6*p-2;x+=2*H){ x0=coords[x][0].first; y0=coords[x][0].second; if(x<=3*p){x0--;dir=3;} else {x0++;dir=1;} set_value(x0,y0,3*x); if(x<=3*p){x0--;y0++;} else {x0++;y0--;} int height=(x==6*p-23?H+1:H); add_house(x0,y0,p,dir,3*x+1,height,true); } int U[][2]={{0,0},{0,0},{2,0},{0,0},{0,0},{0,0},{2,0},{0,0},{0,0},{0,0}, {2,0},{0,0},{0,0},{0,0},{2,0},{0,0},{0,0},{0,0},{2,0},{0,0}, {0,0},{0,0},{2,0},{0,0},{0,0},{0,0},{2,0},{0,0},{0,0},{0,0}, {3,0},{0,0},{0,0},{0,0},{0,0},{0,0},{3,0},{0,0},{0,0},{0,0}, {0,0},{0,0},{3,0},{0,0},{0,0},{0,0},{0,0},{0,0},{2,0},{0,0}, {0,0},{0,0},{2,0},{0,0},{0,0},{0,0},{2,0},{0,0},{0,0},{0,0}, {2,0},{0,0},{0,0},{0,0},{2,0},{0,0},{0,0},{0,0},{2,0},{0,0}, {0,0},{0,0},{2,0},{0,0},{0,0},{0,0},{2,0},{0,0}}; int W[][2]={ // 1. block {0,0},{0,0},{2,0},{0,0},{0,0},{0,0},{2,0},{0,0},{0,0},{0,0}, {2,0},{0,0},{0,0},{0,0},{2,0},{0,0},{0,0},{0,0},{2,0},{0,0}, {0,0},{0,0},{2,0},{0,0},{0,0},{0,0},{2,0},{0,0},{0,0},{0,0}, {3,0},{0,0},{0,0},{0,0},{0,0},{0,0},{3,0},{0,0},{0,0},{0,0}, {0,0},{0,0},{-7,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{2,0}, {0,0},{0,0},{0,0},{2,0},{0,0},{0,0},{0,0},{2,0},{0,0},{0,0}, {0,0},{2,0},{0,0},{0,0},{0,0},{2,0},{0,0},{0,0},{0,0},{3,0}, {0,0},{0,0},{0,0},{0,0},{0,0},{3,0},{0,0},{0,0}, // 2. block {0,0},{0,0},{0,0},{3,0},{0,0},{0,0},{0,0},{0,0},{0,0},{2,0}, {0,0},{0,0},{0,0},{0,0},{2,0},{0,0},{0,0},{0,0},{2,0},{0,0}, {0,0},{0,0},{2,0},{0,0},{0,0},{0,0},{2,0},{0,0},{0,0},{0,0}, {2,0},{0,0},{0,0},{0,0},{-7,0},{0,0},{0,0},{0,0},{0,0},{0,0}, {0,0},{2,0},{0,0},{0,0},{0,0},{2,0},{0,0},{0,0},{0,0},{2,0}, {0,0},{0,0},{0,0},{2,0},{0,0},{0,0},{0,0},{2,0},{0,0},{0,0}, {0,0},{2,0},{0,0},{0,0},{0,0},{2,0},{0,0},{0,0},{0,0},{3,0}, {0,0},{0,0},{0,0},{0,0},{0,0},{3,0},{0,0},{0,0}, // 3. block {0,0},{0,0},{0,0},{2,0},{0,0},{0,0},{0,0},{2,0},{0,0},{0,0}, {0,0},{2,0},{0,0},{0,0},{0,0},{2,0},{0,0},{0,0},{0,0},{2,0}, {0,0},{0,0},{0,0},{2,0},{0,0},{0,0},{0,0},{2,0},{0,0},{0,0}, {0,0},{3,0},{0,0},{0,0},{0,0},{0,0},{0,0},{3,0},{0,0},{0,0}, {0,0},{0,0},{0,0},{2,0},{0,0},{0,0},{0,0},{2,0},{0,0},{0,0}, {0,0},{2,0},{0,0},{0,0},{0,0},{2,0},{0,0},{0,0},{0,0},{2,0}, {0,0},{0,0},{0,0},{2,0},{0,0},{0,0},{0,0},{2,0},{0,0},{0,0}, {0,0},{2,0},{0,0},{0,0},{0,0},{3,0},{0,0},{0,0}, // 4. block {0,0},{0,0},{0,0},{2,0},{0,0},{0,0},{0,0},{2,0},{0,0},{0,0}, {0,0},{2,0},{0,0},{0,0},{0,0},{2,0},{0,0},{0,0},{0,0},{2,0}, {0,0},{0,0},{0,0},{2,0},{0,0},{0,0},{0,0},{2,0},{0,0},{0,0}, {0,0},{2,0},{0,0},{0,0},{0,0},{3,0},{0,0},{0,0},{0,0},{0,0}, {0,0},{2,0},{0,0},{0,0},{0,0},{2,0},{0,0},{0,0},{0,0},{2,0}, {0,0},{0,0},{0,0},{3,0},{0,0},{0,0},{0,0},{0,0},{0,0},{3,0}, {0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{2,0},{0,0},{0,0},{0,0}, {2,0},{0,0},{0,0},{0,0},{3,0},{0,0},{0,0},{0,0}, // 5. block {0,0},{0,0},{2,0},{0,0},{0,0},{0,0},{2,0},{0,0},{0,0},{0,0}, {2,0},{0,0},{0,0},{0,0},{2,0},{0,0},{0,0},{0,0},{2,0},{0,0}, {0,0},{0,0},{2,0},{0,0},{0,0},{0,0},{2,0},{0,0},{0,0},{0,0}, {3,0},{0,0},{0,0},{0,0},{0,0},{0,0},{3,0},{0,0},{0,0},{0,0}, {0,0},{0,0},{-7,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{2,0}, {0,0},{0,0},{0,0},{2,0},{0,0},{0,0},{0,0},{2,0},{0,0},{0,0}, {0,0},{2,0},{0,0},{0,0},{0,0},{2,0},{0,0},{0,0},{0,0},{3,0}, {0,0},{0,0},{0,0},{0,0},{0,0},{3,0},{0,0},{0,0}, // 6. block {0,0},{0,0},{0,0},{2,0},{0,0},{0,0},{0,0},{3,0},{0,0},{0,0}, {0,0},{0,0},{0,0},{0,0},{2,0},{0,0},{0,0},{0,0},{2,0},{0,0}, {0,0},{0,0},{2,0},{0,0},{0,0},{0,0},{2,0},{0,0},{0,0},{0,0}, {2,0},{0,0},{0,0},{0,0},{-7,0},{0,0},{0,0},{0,0},{0,0},{0,0}, {0,0},{2,0},{0,0},{0,0},{0,0},{2,0},{0,0},{0,0},{0,0},{2,0}, {0,0},{0,0},{0,0},{2,0},{0,0},{0,0},{0,0},{2,0},{0,0},{0,0}, {0,0},{2,0},{0,0},{0,0},{0,0},{2,0},{0,0},{0,0},{0,0},{3,0}, {0,0},{0,0},{0,0},{0,0},{0,0},{3,0},{0,0},{0,0}, // 7. block {0,0},{0,0},{0,0},{2,0},{0,0},{0,0},{0,0},{2,0},{0,0},{0,0}, {0,0},{2,0},{0,0},{0,0},{0,0},{2,0},{0,0},{0,0},{0,0},{2,0}, {0,0},{0,0},{0,0},{2,0},{0,0},{0,0},{0,0},{2,0},{0,0},{0,0}, {0,0},{2,0},{0,0},{0,0},{0,0},{3,0},{0,0},{0,0},{0,0},{0,0}, {0,0},{2,0},{0,0},{0,0},{0,0},{2,0},{0,0},{0,0},{0,0},{2,0}, {0,0},{0,0},{0,0},{2,0},{0,0},{0,0},{0,0},{2,0},{0,0},{0,0}, {0,0},{2,0},{0,0},{0,0},{0,0},{2,0},{0,0},{0,0},{0,0},{3,0}, {0,0},{0,0},{0,0},{0,0},{0,0},{3,0},{0,0},{0,0}, // 8. block {0,0},{0,0},{0,0},{2,0},{0,0},{0,0},{0,0},{2,0},{0,0},{0,0}, {0,0},{2,0},{0,0},{0,0},{0,0},{2,0},{0,0},{0,0},{0,0},{2,0}, {0,0},{0,0},{0,0},{2,0},{0,0},{0,0},{0,0},{2,0},{0,0},{0,0}, {0,0},{2,0},{0,0},{0,0},{0,0},{3,0},{0,0},{0,0},{0,0},{0,0}, {0,0},{2,0},{0,0},{0,0},{0,0},{2,0},{0,0},{0,0},{0,0},{2,0}, {0,0},{0,0},{0,0},{2,0},{0,0},{0,0},{0,0},{2,0},{0,0},{0,0}, {0,0},{2,0},{0,0},{0,0},{0,0},{0,0},{2,0},{0,0},{0,0},{0,0}, {2,0},{0,0},{0,0},{0,0},{3,0},{0,0},{0,0},{0,0} }; int offset,it=0; bool changed=false; for(x=2*p+1;x<6*p-23 && 36*p-36*H-60>9*x;x+=2*H){ if(9*x+234<24*p+168 && 9*x+2*234>24*p+168){changed=true;offset=0;} for(int res=0;res<6*H;res++){ int v0,v1; if(!changed) {v0=U[res][0];v1=U[res][1];} else {v0=W[offset+res][0];v1=W[offset+res][1];} int count=v0; if(count==0)continue; x0=coords[3*x+res][0].first; y0=coords[3*x+res][0].second; dir=get_dir(x,p,res); x0+=dxy[dir][0]; y0+=dxy[dir][1]; set_value(x0,y0,9*x+3*res); x0+=v1*dxy[(dir+1)%4][0]; y0+=dxy[dir][1]; int direction=(res<3*H?0:1); if(count<0 && direction==1)direction=0; add_house(x0,y0,p,dir,9*x+3*res+1,count,true,direction); } if(changed){offset=(offset+6*H)%(48*H);it++;} } } int main(int argc, char** argv){ if(argc<2) {printf("Not found the input t number.\n");exit(1);} int t=atoi(argv[1]); if(t<0 || t>17) {printf("t should be in the [0,17] interval.\n");exit(1);} fun(156*t+97); check_grid(); show_map(); return 0; }