// File: ekg[P]tsvtools/tsvbootstrap.cpp
// Function: main
int main(int argc, char** argv) {

    if (argc < 2) {
        cerr << "usage: " << argv[0] << " -c sample_count -n sample_size" << endl
             << "bootstraps a new table by randomly sampling subsets of tab-separated" << endl
             << "records from stdin.  generates sample_count subsets of sample_size" << endl
             << "randomly selected from lines of input.  for each sampled subset, outputs." << endl
             << "a row of tab-separated averaged values for each value in the table." << endl;
        exit(1);
    }

    unsigned int sample_size = 1;
    unsigned int sample_count = 1;

    while (true) {
        static struct option long_options[] =
        {   
            {"sample-count", required_argument, 0, 'c'},
            {"sample-size",   required_argument, 0, 'n'},

        };
        int option_index = 0;

        int c = getopt_long (argc, argv, "n:c:", long_options, &option_index);

          if (c == -1)
            break;

          switch (c) {
            case 0:
            /* If this option set a flag, do nothing else now. */
            if (long_options[option_index].flag != 0)
              break;
            printf ("option %s", long_options[option_index].name);
            if (optarg)
              printf (" with arg %s", optarg);
            printf ("\n");
            break;

          case 'n':
            sample_size = atoi(optarg);
            break;

          case 'c':
            sample_count = atoi(optarg);
            break;

          default:
            abort();
            break;

        }
    }

    // seed prng with random bits from /dev/random
    fstream random;
    random.open("/dev/random", fstream::in);
    int seed;
    random.get((char*) &seed, sizeof(int));
    random.close();

    init_genrand(seed);


    string header;
    vector<string> header_fields;
    getline(cin, header);

    if (header.empty()) {
        cerr << "could not get header line" << endl;
        exit(1);
    }

    split(header, '\t', header_fields);
    vector<vector<double> > lines;

    map<string, unsigned int> counts;
    map<string, long double> totals;

    string line;
    getline(cin, line);
    while (!line.empty()) {
        vector<string> fields = split(line, '\t');
        int i = 0;
        vector<double> vals;
        for (vector<string>::iterator f = fields.begin(); f != fields.end(); ++f) {
            vals.push_back(atof(f->c_str()));
        }
        lines.push_back(vals);
        getline(cin, line);
    }

    cout << header << endl;

    for (int i = 0; i < sample_count; ++i) {
        vector<vector<double>* > subset = randomsubset(lines, sample_size);
        vector<double> avgs = subsetavg(subset);
        cout << join(avgs, "\t") << endl;
    }

    return 0;

}

// Assembly:
subq $0x3f8, %rsp            # imm = 0x3F8
movl $0x0, 0x3f4(%rsp)
movl %edi, 0x3f0(%rsp)
movq %rsi, 0x3e8(%rsp)
cmpl $0x2, 0x3f0(%rsp)
jge 0x32f5
movq 0xddba(%rip), %rdi      # 0x10ff0
leaq 0x7e13(%rip), %rsi      # 0xb050
callq 0x2220
movq %rax, %rdi
movq 0x3e8(%rsp), %rax
movq (%rax), %rsi
callq 0x2220
movq %rax, %rdi
leaq 0x7df9(%rip), %rsi      # 0xb058
callq 0x2220
movq %rax, %rdi
movq 0xdd42(%rip), %rsi      # 0x10fb0
callq 0x2260
movq %rax, %rdi
leaq 0x7dfb(%rip), %rsi      # 0xb078
callq 0x2220
movq %rax, %rdi
movq 0xdd24(%rip), %rsi      # 0x10fb0
callq 0x2260
movq %rax, %rdi
leaq 0x7e22(%rip), %rsi      # 0xb0bd
callq 0x2220
movq %rax, %rdi
movq 0xdd06(%rip), %rsi      # 0x10fb0
callq 0x2260
movq %rax, %rdi
leaq 0x7e47(%rip), %rsi      # 0xb100
callq 0x2220
movq %rax, %rdi
movq 0xdce8(%rip), %rsi      # 0x10fb0
callq 0x2260
movq %rax, %rdi
leaq 0x7e73(%rip), %rsi      # 0xb14a
callq 0x2220
movq %rax, %rdi
movq 0xdcca(%rip), %rsi      # 0x10fb0
callq 0x2260
movl $0x1, %edi
callq 0x22c0
movl $0x1, 0x3e4(%rsp)
movl $0x1, 0x3e0(%rsp)
movl $0x0, 0x3dc(%rsp)
movl 0x3f0(%rsp), %edi
movq 0x3e8(%rsp), %rsi
leaq 0x7e7b(%rip), %rdx      # 0xb1a7
leaq 0xdf0d(%rip), %rcx      # 0x11240
leaq 0x3dc(%rsp), %r8
callq 0x2390
movl %eax, 0x3d8(%rsp)
cmpl $-0x1, 0x3d8(%rsp)
jne 0x3356
jmp 0x3440
movl 0x3d8(%rsp), %eax
movl %eax, 0x3c(%rsp)
testl %eax, %eax
je 0x3388
jmp 0x3367
movl 0x3c(%rsp), %eax
subl $0x63, %eax
je 0x341e
jmp 0x3376
movl 0x3c(%rsp), %eax
subl $0x6e, %eax
je 0x3406
jmp 0x3436
movslq 0x3dc(%rsp), %rcx
leaq 0xdea9(%rip), %rax      # 0x11240
shlq $0x5, %rcx
addq %rcx, %rax
cmpq $0x0, 0x10(%rax)
je 0x33aa
jmp 0x343b
movslq 0x3dc(%rsp), %rcx
leaq 0xde87(%rip), %rax      # 0x11240
shlq $0x5, %rcx
addq %rcx, %rax
movq (%rax), %rsi
leaq 0x7de2(%rip), %rdi      # 0xb1ac
movb $0x0, %al
callq 0x2030
movq 0xdbe0(%rip), %rax      # 0x10fb8
cmpq $0x0, (%rax)
je 0x33f6
movq 0xdbd3(%rip), %rax      # 0x10fb8
movq (%rax), %rsi
leaq 0x7dc7(%rip), %rdi      # 0xb1b6
movb $0x0, %al
callq 0x2030
leaq 0x7dc6(%rip), %rdi      # 0xb1c3
movb $0x0, %al
callq 0x2030
jmp 0x343b
movq 0xdbab(%rip), %rax      # 0x10fb8
movq (%rax), %rdi
callq 0x2340
movl %eax, 0x3e4(%rsp)
jmp 0x343b
movq 0xdb93(%rip), %rax      # 0x10fb8
movq (%rax), %rdi
callq 0x2340
movl %eax, 0x3e0(%rsp)
jmp 0x343b
callq 0x2100
jmp 0x330b
leaq 0x1c8(%rsp), %rdi
movq %rdi, 0x30(%rsp)
callq 0x22b0
movq 0x30(%rsp), %rdi
leaq 0x7d67(%rip), %rsi      # 0xb1c5
movl $0x8, %edx
callq 0x21f0
jmp 0x346a
leaq 0x1c8(%rsp), %rdi
leaq 0x1b8(%rsp), %rsi
movl $0x4, %edx
callq 0x2120
jmp 0x3486
leaq 0x1c8(%rsp), %rdi
callq 0x2040
jmp 0x3495
movslq 0x1b8(%rsp), %rdi
callq 0x2550
leaq 0x198(%rsp), %rdi
movq %rdi, 0x28(%rsp)
callq 0x2300
leaq 0x180(%rsp), %rdi
callq 0x3fa0
movq 0x28(%rsp), %rsi
movq 0xdb0b(%rip), %rdi      # 0x10fd8
callq 0x2070
jmp 0x34d4
leaq 0x198(%rsp), %rdi
callq 0x23a0
testb $0x1, %al
jne 0x34e7
jmp 0x3550
movq 0xdb02(%rip), %rdi      # 0x10ff0
leaq 0x7cdc(%rip), %rsi      # 0xb1d1
callq 0x2220
movq %rax, 0x20(%rsp)
jmp 0x3501
movq 0x20(%rsp), %rdi
movq 0xdaa3(%rip), %rsi      # 0x10fb0
callq 0x2260
jmp 0x3514
movl $0x1, %edi
callq 0x22c0
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x1c0(%rsp)
movl %eax, 0x1bc(%rsp)
jmp 0x394a
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x1c0(%rsp)
movl %eax, 0x1bc(%rsp)
jmp 0x3930
leaq 0x198(%rsp), %rdi
movl $0x9, %esi
leaq 0x180(%rsp), %rdx
callq 0x9570
jmp 0x356c
leaq 0x168(%rsp), %rdi
callq 0x3fb0
leaq 0x138(%rsp), %rdi
callq 0x3fc0
leaq 0x108(%rsp), %rdi
callq 0x3fd0
leaq 0xe8(%rsp), %rdi
movq %rdi, 0x18(%rsp)
callq 0x2300
movq 0x18(%rsp), %rsi
movq 0xda27(%rip), %rdi      # 0x10fd8
callq 0x2070
jmp 0x35b8
jmp 0x35ba
leaq 0xe8(%rsp), %rdi
callq 0x23a0
xorb $-0x1, %al
testb $0x1, %al
jne 0x35d2
jmp 0x3737
leaq 0xd0(%rsp), %rdi
leaq 0xe8(%rsp), %rsi
movl $0x9, %edx
callq 0x9680
jmp 0x35ee
movl $0x0, 0xcc(%rsp)
leaq 0xb0(%rsp), %rdi
callq 0x3970
leaq 0xd0(%rsp), %rdi
callq 0x3fe0
movq %rax, 0xa8(%rsp)
leaq 0xd0(%rsp), %rdi
callq 0x4050
movq %rax, 0xa0(%rsp)
leaq 0xa8(%rsp), %rdi
leaq 0xa0(%rsp), %rsi
callq 0x4010
testb $0x1, %al
jne 0x364e
jmp 0x36eb
leaq 0xa8(%rsp), %rdi
callq 0x4080
movq %rax, %rdi
callq 0x20c0
movq %rax, %rdi
callq 0x22e0
movsd %xmm0, 0x98(%rsp)
leaq 0xb0(%rsp), %rdi
leaq 0x98(%rsp), %rsi
callq 0x3c00
jmp 0x368b
jmp 0x368d
leaq 0xa8(%rsp), %rdi
callq 0x4090
jmp 0x361b
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x1c0(%rsp)
movl %eax, 0x1bc(%rsp)
jmp 0x38fc
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x1c0(%rsp)
movl %eax, 0x1bc(%rsp)
leaq 0xb0(%rsp), %rdi
callq 0x3c30
leaq 0xd0(%rsp), %rdi
callq 0x4120
jmp 0x38fc
leaq 0x168(%rsp), %rdi
leaq 0xb0(%rsp), %rsi
callq 0x40b0
jmp 0x3702
movq 0xd8cf(%rip), %rdi      # 0x10fd8
leaq 0xe8(%rsp), %rsi
callq 0x2070
jmp 0x3718
leaq 0xb0(%rsp), %rdi
callq 0x3c30
leaq 0xd0(%rsp), %rdi
callq 0x4120
jmp 0x35ba
movq 0xd88a(%rip), %rdi      # 0x10fc8
leaq 0x198(%rsp), %rsi
callq 0x21e0
movq %rax, 0x10(%rsp)
jmp 0x3752
movq 0x10(%rsp), %rdi
movq 0xd852(%rip), %rsi      # 0x10fb0
callq 0x2260
jmp 0x3765
movl $0x0, 0x94(%rsp)
movl 0x94(%rsp), %eax
cmpl 0x3e0(%rsp), %eax
jae 0x3887
movl 0x3e4(%rsp), %edx
leaq 0x78(%rsp), %rdi
leaq 0x168(%rsp), %rsi
callq 0x3050
jmp 0x379f
leaq 0x60(%rsp), %rdi
leaq 0x78(%rsp), %rsi
callq 0x2c40
jmp 0x37b0
leaq 0x7a34(%rip), %rdx      # 0xb1eb
leaq 0x40(%rsp), %rdi
leaq 0x60(%rsp), %rsi
callq 0x4180
jmp 0x37c8
movq 0xd7f9(%rip), %rdi      # 0x10fc8
leaq 0x40(%rsp), %rsi
callq 0x21e0
movq %rax, 0x8(%rsp)
jmp 0x37e0
movq 0x8(%rsp), %rdi
movq 0xd7c4(%rip), %rsi      # 0x10fb0
callq 0x2260
jmp 0x37f3
leaq 0x40(%rsp), %rdi
callq 0x2130
leaq 0x60(%rsp), %rdi
callq 0x3c30
leaq 0x78(%rsp), %rdi
callq 0x3f30
movl 0x94(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x94(%rsp)
jmp 0x3770
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x1c0(%rsp)
movl %eax, 0x1bc(%rsp)
jmp 0x387b
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x1c0(%rsp)
movl %eax, 0x1bc(%rsp)
jmp 0x3871
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x1c0(%rsp)
movl %eax, 0x1bc(%rsp)
leaq 0x40(%rsp), %rdi
callq 0x2130
leaq 0x60(%rsp), %rdi
callq 0x3c30
leaq 0x78(%rsp), %rdi
callq 0x3f30
jmp 0x38fc
movl $0x0, 0x3f4(%rsp)
leaq 0xe8(%rsp), %rdi
callq 0x2130
leaq 0x108(%rsp), %rdi
callq 0x42c0
leaq 0x138(%rsp), %rdi
callq 0x42d0
leaq 0x168(%rsp), %rdi
callq 0x42e0
leaq 0x180(%rsp), %rdi
callq 0x4120
leaq 0x198(%rsp), %rdi
callq 0x2130
leaq 0x1c8(%rsp), %rdi
callq 0x2080
movl 0x3f4(%rsp), %eax
addq $0x3f8, %rsp            # imm = 0x3F8
retq
leaq 0xe8(%rsp), %rdi
callq 0x2130
leaq 0x108(%rsp), %rdi
callq 0x42c0
leaq 0x138(%rsp), %rdi
callq 0x42d0
leaq 0x168(%rsp), %rdi
callq 0x42e0
leaq 0x180(%rsp), %rdi
callq 0x4120
leaq 0x198(%rsp), %rdi
callq 0x2130
leaq 0x1c8(%rsp), %rdi
callq 0x2080
movq 0x1c0(%rsp), %rdi
callq 0x23b0
nopw %cs:(%rax,%rax)
nop