#define _GNU_SOURCE #include #include #include #include #define CHUNK_SIZE 40000000 #define LINES_CHUNK_SIZE 100000 #define BUF_SIZE 160000 void dump(char *buffer, int size) { while (size>0) { int w = write(1, buffer, size); buffer+=w; size-=w; } } static inline char * dumpstr(char *buffer, char *current, char *word, int len) { int capacity = buffer+BUF_SIZE-current; if (len > capacity) { dump(buffer, current - buffer); current = buffer; } for (int i=0;i < len; i++) { *current = word[i]; current++; } return current; } int main() { // INPUT reading char *buf = malloc(CHUNK_SIZE); int size = CHUNK_SIZE; { char *s = buf; int left = CHUNK_SIZE; while(1){ int n = read(0, s, left); if(n == 0) break; s += n; left -= n; if(left == 0) { int tmp = size; size += CHUNK_SIZE; left = CHUNK_SIZE; buf=realloc(buf, size); s = buf + tmp; } } *s = '\n'; *(s+1) = '\0'; } char **w = NULL; ssize_t *o = NULL; int k = 0; { char *s = buf; int is_word = 0; while (*s) { if (k % LINES_CHUNK_SIZE == 0) { w = realloc(w, k+LINES_CHUNK_SIZE); o = realloc(o, (k+LINES_CHUNK_SIZE)*sizeof(ssize_t)); } switch (*s) { case ' ': if (is_word) { o[k] = s-w[k]; is_word = 0; k++; } break; case '\r': if (is_word) { o[k] = s-w[k]; is_word = 0; k++; } break; case '\n': if (is_word) { o[k] = s-w[k]; is_word = 0; k++; } break; default: if (!is_word) { w[k] = s; is_word = 1; } } s++; } } char out_buf[BUF_SIZE]; char *s = out_buf; for(int i = 0; i < k; i+=2) for(int j = 1; j < k; j+=2){ s=dumpstr(out_buf,s,w[i],o[i]); s=dumpstr(out_buf,s,w[j],o[j]); s=dumpstr(out_buf,s,"\n",1); } dump(out_buf, s - out_buf); return 0; }