#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
#include <malloc.h>
#include <string.h>
#define FL __FILE__,__LINE__
#define PD printf("."); fflush(stdout)
#define tz(x) if(x){printf("\n%s:%d:5:Fail: %s is %d not zero.",FL,#x,x);}else PD;
#define tde(x,y) if(x!=y){printf("\n%s:%d:6:Fail: %s is %d not %d.",FL,#x,x,y);}else PD;
#define tse(x,y) if(strcmp(x,y)){printf("\n%s:%d:6:Fail: %s is %s not %s",FL,#x,x,y);}else PD;
int *parseline(char *s){
int *ret=calloc(strlen(s)+1,sizeof(int));
int count =0;
while(s!=NULL && *s!= '\0'){
char *n=strsep(&s," ");
if(n!=NULL){
ret[count]=atoi(n);
if(atoi(n)<1)abort();
count++;
}
}
ret[count]=0;
return ret;
}
int issafe(int *data){
if(data == NULL) return 0;
int dir=0;
for(int i=0;data[i]!=0;i++){
if(i>0){
if (abs(data[i]-data[i-1])>3 || data[i]==data[i-1]){
//printf(" unsafe data %d %d\n",data[i-1],data[i]);
return 0;
}
if(dir){
if(dir<0 && data[i]>data[i-1]){
//printf(" bad dir %d %d\n",data[i-1],data[i]);
return 0;
}else if(dir>0 && data[i]<data[i-1]){
//printf(" bad dir %d %d\n",data[i-1],data[i]);
return 0;
}
}else if(data[i]>data[i-1]){
dir=1;
}else{
dir=-1;
}
}
}
return 1;
}
int *adup(int *a){
int len=0;
for(len=0;a[len]!=0;len++);
len++;
int *b=calloc(len,sizeof(int));
for(int i=0; i<len;i++)b[i]=a[i];
return b;
}
int *del(int *data,int index){
if(data==NULL)abort();
if(data[index]==0)abort();
int len=0;
for(int i=index;data[i+1]!=0;i++){
data[i]=data[i+1];
len=i;
}
data[len+1]=0;
return data;
}
void printdata(int *data){
for(int i=0;data[i]!=0;i++){
printf("%d ",data[i]);
}
printf("\n");
}
int issafepdamp(int *data) {
if(issafe(data)) return 1;
for(int i=0;data[i+1]!=0;i++){
int * ddata = del(adup(data),i);
//printf("trying: "); printdata(ddata);
if(issafe(ddata)) {
free(ddata);
return 1;
}else{
free(ddata);
}
}
printf("unsafe: "); printdata(data);
return 0;
}
void test(void){
char *testcases[] = {
"7 6 4 2 1",
"1 2 7 8 9",
"9 7 6 2 1",
"1 3 2 4 5",
"8 6 4 4 1",
"1 3 6 7 9"
};
int testa[] = {1,0,0,0,0,1};
int testb[] = {1,0,0,1,1,1};
int count = 0;
char *s2=strdup(testcases[0]);
int *d=parseline(s2);
tde(d[4],1);
int *dd=adup(d);
int *data;
for(int i=0;dd[i]!=0;i++)tde(dd[i],d[i]);
del(dd,2);
for(int i=0;i<2;i++)tde(dd[i],d[i]);
for(int i=2;dd[i+1]!=0;i++)tde(dd[i],d[i+1]);
free(d); free(s2);free(dd);
for(unsigned int i=0; i<sizeof(testcases)/sizeof(char *); i++){
int *data;
char *s=strdup(testcases[i]);
int safe=issafe(data=parseline(s));
tde(safe,testa[i]);
count+=safe;
free(data);
free(s);
}
tde(count,2);
count = 0;
for(unsigned int i=0; i<sizeof(testcases)/sizeof(char *); i++){
char *s=strdup(testcases[i]);
int safe=issafepdamp(data=parseline(s));
tde(safe,testb[i]);
count+=safe;
free(data);
free(s);
}
tde(count,4);
/*char *dampsafe=strdup("9 11 9 7 6 3 5 1");
data=parseline(dampsafe);
tde(issafepdamp(data),1);
free(dampsafe);
free(data);
char *shortsafe=strdup("11 9 7 6 3 5 1");
data=parseline(shortsafe);
tde(issafe(data),1);
free(shortsafe);
free(data);
tde(1,1);
*/
}
int main() {
test();
int count = 0;
int countdamp = 0;
char buf[1024];
while(!feof(stdin)){
int *data=NULL;
fgets(buf,1024,stdin);
if(strlen(buf)>1){
data=parseline(buf);
count+=(issafe(data));
countdamp+=(issafepdamp(data));
free(data);
}
}
printf("\nAnswer: %d\n",count);
printf("\nAnswer2: %d\n",countdamp);
return 0;
}