#define node_num(n) n-graph #define EDGE_ALIGNMENT sizeof(struct edge) &-sizeof(struct edge) #define is_second_half(e) ((uintptr_t) e&EDGE_ALIGNMENT) #define other_half(e) is_second_half(e) ?e-1:e+1 #define BUCKET_SIZE 0200000 #define normalize(n) while(n!=NULL&&n->partner==NULL) n= n->next /*5:*/ #line 99 "./hierholzer.w" #include #include #include /*6:*/ #line 137 "./hierholzer.w" typedef struct edge*node; /*:6*//*7:*/ #line 161 "./hierholzer.w" struct edge{ struct edge*next; node*partner; }; /*:7*//*8:*/ #line 175 "./hierholzer.w" struct allocator{ size_t bucket_count,fill; struct edge**buckets; }; /*:8*/ #line 104 "./hierholzer.w" /*18:*/ #line 352 "./hierholzer.w" static node*nonempty_node(node*graph,size_t node_count) { size_t i; for(i= 0;i=node_count||to>=node_count){ fprintf(stderr,"input malformed\n"); goto cleanup; } /*16:*/ #line 298 "./hierholzer.w" { struct edge*epair; /*10:*/ #line 204 "./hierholzer.w" if(alloc.fill> BUCKET_SIZE-2) /*9:*/ #line 183 "./hierholzer.w" { struct edge**new_buckets= realloc(alloc.buckets,++alloc.bucket_count*sizeof*alloc.buckets); if(new_buckets!=NULL) alloc.buckets= new_buckets; else{ perror("allocation error"); goto cleanup; } if(alloc.buckets[alloc.bucket_count-1]= malloc(BUCKET_SIZE*sizeof**alloc.buckets),alloc.buckets[alloc.bucket_count-1]==NULL){ perror("allocation error"); goto cleanup; } alloc.fill= is_second_half(alloc.buckets[alloc.bucket_count-1])?1:0; } /*:9*/ #line 206 "./hierholzer.w" epair= alloc.buckets[alloc.bucket_count-1]+alloc.fill; alloc.fill+= 2; /*:10*/ #line 302 "./hierholzer.w" epair[0].next= graph[from]; epair[0].partner= graph+to; graph[from]= epair+0; epair[1].next= graph[to]; epair[1].partner= graph+from; graph[to]= epair+1; } /*:16*/ #line 270 "./hierholzer.w" } if(items!=EOF){ fprintf(stderr,"input malformed\n"); goto cleanup; } if(ferror(input_file)){ perror("input error"); goto cleanup; } } /*:14*/ #line 118 "./hierholzer.w" status= EXIT_SUCCESS; /*17:*/ #line 323 "./hierholzer.w" { struct edge*edg; size_t i,degree,odd_count= 0; for(i= 0;inext) degree++; if(degree%2!=0){ if(++odd_count<=2) path.partner= graph+i; else{ printf("-1\n"); goto cleanup; } } } if(path.partner==NULL) path.partner= nonempty_node(graph,node_count); if(path.partner==NULL){ printf("\n"); goto cleanup; } } /*:17*/ #line 120 "./hierholzer.w" /*19:*/ #line 369 "./hierholzer.w" { struct edge*chaser= &path; do{ /*20:*/ #line 382 "./hierholzer.w" { struct edge*leader,*chaser_next= chaser->next; for(leader= chaser;*leader->partner!=NULL;leader= leader->next){ leader->next= *leader->partner; /*21:*/ #line 401 "./hierholzer.w" { struct edge*back= other_half(leader->next); *back->partner= leader->next->next; normalize((*back->partner)); back->partner= NULL; normalize((*leader->next->partner)); } /*:21*/ #line 388 "./hierholzer.w" } leader->next= chaser_next; } /*:20*/ #line 373 "./hierholzer.w" /*22:*/ #line 413 "./hierholzer.w" while(chaser!=NULL&&*chaser->partner==NULL) chaser= chaser->next; /*:22*/ #line 374 "./hierholzer.w" }while(chaser!=NULL); } /*:19*/ #line 121 "./hierholzer.w" /*23:*/ #line 420 "./hierholzer.w" if(nonempty_node(graph,node_count)!=NULL){ printf("-1\n"); goto cleanup; } /*:23*/ #line 122 "./hierholzer.w" /*15:*/ #line 286 "./hierholzer.w" { struct edge*edg; printf("%tu",node_num(path.partner)); for(edg= path.next;edg!=NULL;edg= edg->next) printf(" %tu",node_num(edg->partner)); putchar('\n'); } /*:15*/ #line 123 "./hierholzer.w" cleanup: /*12:*/ #line 223 "./hierholzer.w" if(input_file!=NULL)fclose(input_file); /*11:*/ #line 212 "./hierholzer.w" { size_t i; for(i= 0;i