-
- #define _GNU_SOURCE
- #include <stdlib.h>
- #include <unistd.h>
- #include <string.h>
- #include <stdio.h>
-
- #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;
- }
-