rendered paste body#include <stdio.h>#include <stdint.h>struct chunk { uint64_t n; uint8_t data[CHUNK_SIZE];};void xor_buf(uint8_t out, uint8_t a, uint8_t b){ long n = CHUNK_SIZE; while(n >= 8) { *(uint64_t*)out = *(uint64_t*)a ^ *(uint64_t*)b; out += 8; a += 8; b += 8; n -= 8; } while(n) { *out++ = *a++ ^ *b++; n--; }}long hamming_weight(uint8_t in){ long sum = 0; long n = CHUNK_SIZE; while(n >= sizeof(unsigned long long)) { sum += __builtin_popcountll(*(unsigned long long*)in); n -= sizeof(unsigned long long); in += sizeof(unsigned long long); } while(n) { sum += __builtin_popcount(*in); n--; in++; } return sum;}void compress(long nchunks){ struct chunk * chunks; long have_chunks; uint64_t read_chunks; long best_chunk_index, best_chunk_weight, this_chunk_weight; long i; uint8_t temp[CHUNK_SIZE]; chunks = malloc(sizeof(struct chunk) * nchunks); if(!chunks) { perror("malloc"); exit(1); } have_chunks = 0; read_chunks = 0; while(have_chunks < nchunks && (fread(chunks[have_chunks].data, CHUNK_SIZE, 1, stdin) == 1)) { chunks[have_chunks].n = read_chunks; have_chunks++; read_chunks++; } fwrite(chunks[0].data, CHUNK_SIZE, 1, stdout); while(have_chunks) { best_chunk_index = 0; for(i = 1; i < have_chunks; i++) { xor_buf(swap, chunks[0].data, chunks[i].data); this_chunk_weight = hamming_weight(swap); if(best_chunk_index == 0 || best_chunk_weight > this_chunk_weight) { best_chunk_index = i; best_chunk_weight = this_chunk_weight; if(best_chunk_weight == 0) break; } } fwrite(chunks[0].n, sizeof(chunks[0].n), 1, stdout); fwrite(chunks[best_chunk_index].n, sizeof(chunks[0].n), 1, stdout); fwrite(swap, CHUNK_SIZE, 1, stdout); chunks[0] = chunks[best_chunk_index]; if(!fread(chunks[best_chunk_index].data, CHUNK_SIZE, 1, stdin)) { chunks[best_chunk_index] = chunks[--have_chunks]; } else { chunks[best_chunk_index].n = read_chunks++; } }}