// File: /workspace/github_c_makefile_star2_O2/Leeheng86[P]word2vec/distance.c
// Function: main
int main(int argc, char **argv) {
  FILE *f;
  char st1[max_size];
  char *bestw[N];
  char file_name[max_size], st[100][max_size];
  float dist, len, bestd[N], vec[max_size];
  long long words, size, a, b, c, d, cn, bi[100];
  char ch;
  float *M;
  char *vocab;
  if (argc < 2) {
    printf("Usage: ./distance <FILE>\nwhere FILE contains word projections in the BINARY FORMAT\n");
    return 0;
  }
  strcpy(file_name, argv[1]);
  f = fopen(file_name, "rb");
  if (f == NULL) {
    printf("Input file not found\n");
    return -1;
  }
  fscanf(f, "%lld", &words);
  fscanf(f, "%lld", &size);
  vocab = (char *)malloc((long long)words * max_w * sizeof(char));
  for (a = 0; a < N; a++) bestw[a] = (char *)malloc(max_size * sizeof(char));
  M = (float *)malloc((long long)words * (long long)size * sizeof(float));
  if (M == NULL) {
    printf("Cannot allocate memory: %lld MB    %lld  %lld\n", (long long)words * size * sizeof(float) / 1048576, words, size);
    return -1;
  }
  for (b = 0; b < words; b++) {
    a = 0;
    while (1) {
      vocab[b * max_w + a] = fgetc(f);
      if (feof(f) || (vocab[b * max_w + a] == ' ')) break;
      if ((a < max_w) && (vocab[b * max_w + a] != '\n')) a++;
    }
    vocab[b * max_w + a] = 0;
    for (a = 0; a < size; a++) fread(&M[a + b * size], sizeof(float), 1, f);
    len = 0;
    for (a = 0; a < size; a++) len += M[a + b * size] * M[a + b * size];
    len = sqrt(len);
    for (a = 0; a < size; a++) M[a + b * size] /= len;
  }
  fclose(f);
  while (1) {
    for (a = 0; a < N; a++) bestd[a] = 0;
    for (a = 0; a < N; a++) bestw[a][0] = 0;
    printf("Enter word or sentence (EXIT to break): ");
    a = 0;
    while (1) {
      st1[a] = fgetc(stdin);
      if ((st1[a] == '\n') || (a >= max_size - 1)) {
        st1[a] = 0;
        break;
      }
      a++;
    }
    if (!strcmp(st1, "EXIT")) break;
    cn = 0;
    b = 0;
    c = 0;
    while (1) {
      st[cn][b] = st1[c];
      b++;
      c++;
      st[cn][b] = 0;
      if (st1[c] == 0) break;
      if (st1[c] == ' ') {
        cn++;
        b = 0;
        c++;
      }
    }
    cn++;
    for (a = 0; a < cn; a++) {
      for (b = 0; b < words; b++) if (!strcmp(&vocab[b * max_w], st[a])) break;
      if (b == words) b = -1;
      bi[a] = b;
      printf("\nWord: %s  Position in vocabulary: %lld\n", st[a], bi[a]);
      if (b == -1) {
        printf("Out of dictionary word!\n");
        break;
      }
    }
    if (b == -1) continue;
    printf("\n                                              Word       Cosine distance\n------------------------------------------------------------------------\n");
    for (a = 0; a < size; a++) vec[a] = 0;
    for (b = 0; b < cn; b++) {
      if (bi[b] == -1) continue;
      for (a = 0; a < size; a++) vec[a] += M[a + bi[b] * size];
    }
    len = 0;
    for (a = 0; a < size; a++) len += vec[a] * vec[a];
    len = sqrt(len);
    for (a = 0; a < size; a++) vec[a] /= len;
    for (a = 0; a < N; a++) bestd[a] = -1;
    for (a = 0; a < N; a++) bestw[a][0] = 0;
    for (c = 0; c < words; c++) {
      a = 0;
      for (b = 0; b < cn; b++) if (bi[b] == c) a = 1;
      if (a == 1) continue;
      dist = 0;
      for (a = 0; a < size; a++) dist += vec[a] * M[a + c * size];
      for (a = 0; a < N; a++) {
        if (dist > bestd[a]) {
          for (d = N - 1; d > a; d--) {
            bestd[d] = bestd[d - 1];
            strcpy(bestw[d], bestw[d - 1]);
          }
          bestd[a] = dist;
          strcpy(bestw[a], &vocab[c * max_w]);
          break;
        }
      }
    }
    for (a = 0; a < N; a++) printf("%50s\t\t%f\n", bestw[a], bestd[a]);
  }
  return 0;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x34158, %rsp          # imm = 0x34158
cmpl $0x1, %edi
jg 0x1225
leaq 0xf47(%rip), %rdi       # 0x2160
callq 0x10b0
xorl %eax, %eax
jmp 0x180d
movq 0x8(%rsi), %rsi
leaq 0x2c40(%rsp), %rbx
movq %rbx, %rdi
callq 0x1040
leaq 0xdc8(%rip), %rsi       # 0x2008
movq %rbx, %rdi
callq 0x1070
testq %rax, %rax
je 0x17d7
movq %rax, %r12
leaq 0xdb0(%rip), %rbx       # 0x200b
xorl %r15d, %r15d
leaq 0x28(%rsp), %r14
movq %rax, %rdi
movq %rbx, %rsi
movq %r14, %rdx
xorl %eax, %eax
callq 0x10f0
movq %rsp, %rdx
movq %r12, %rdi
movq %rbx, %rsi
xorl %eax, %eax
callq 0x10f0
movq (%r14), %rbx
imulq $0x32, %rbx, %rdi
callq 0x1080
movq %rax, 0x18(%rsp)
cmpq $0x28, %r15
je 0x12b1
movl $0x7d0, %edi            # imm = 0x7D0
callq 0x1080
movq %rax, 0xd0(%rsp,%r15,8)
incq %r15
jmp 0x1294
movq (%rsp), %r15
movq %r15, %r14
imulq %rbx, %r14
leaq (,%r14,4), %rdi
callq 0x1080
testq %rax, %rax
je 0x17e5
movq %rax, 0x8(%rsp)
xorl %ebp, %ebp
pushq $0x4
popq %r13
pushq $0x1
popq %r15
xorl %eax, %eax
cmpq %rbx, %rax
jge 0x13f9
movq %rax, 0x20(%rsp)
imulq $0x32, %rax, %r14
addq 0x18(%rsp), %r14
xorl %r15d, %r15d
movq %r12, %rdi
callq 0x10d0
movl %eax, %ebx
movb %bl, (%r14,%r15)
movq %r12, %rdi
callq 0x10c0
cmpb $0x20, %bl
je 0x1333
testl %eax, %eax
jne 0x1333
cmpq $0x32, %r15
setb %al
cmpb $0xa, %bl
setne %cl
andb %al, %cl
movzbl %cl, %eax
addq %rax, %r15
jmp 0x12fd
movb $0x0, (%r14,%r15)
movq 0x8(%rsp), %rbx
xorl %r14d, %r14d
pushq $0x1
popq %r15
movq (%rsp), %rdi
cmpq %rdi, %r14
jge 0x136b
imulq %rbp, %rdi
addq %rbx, %rdi
movq %r13, %rsi
movq %r15, %rdx
movq %r12, %rcx
callq 0x10a0
incq %r14
addq $0x4, %rbx
jmp 0x1344
testq %rdi, %rdi
movl $0x0, %eax
cmovgq %rdi, %rax
imulq %rbp, %rdi
addq 0x8(%rsp), %rdi
xorps %xmm0, %xmm0
xorl %ecx, %ecx
cmpq %rcx, %rax
je 0x139c
movss (%rdi,%rcx,4), %xmm1
mulss %xmm1, %xmm1
addss %xmm1, %xmm0
incq %rcx
jmp 0x1385
ucomiss 0xc61(%rip), %xmm0      # 0x2004
jb 0x13ab
sqrtss %xmm0, %xmm0
jmp 0x13b0
callq 0x10e0
movq (%rsp), %rax
testq %rax, %rax
movl $0x0, %ecx
cmovgq %rax, %rcx
imulq %rbp, %rax
addq 0x8(%rsp), %rax
xorl %edx, %edx
cmpq %rdx, %rcx
je 0x13e3
movss (%rax,%rdx,4), %xmm1
divss %xmm0, %xmm1
movss %xmm1, (%rax,%rdx,4)
incq %rdx
jmp 0x13cb
movq 0x20(%rsp), %rax
incq %rax
movq 0x28(%rsp), %rbx
addq $0x4, %rbp
jmp 0x12e3
movq %r12, %rdi
callq 0x1050
movq 0x2bd8(%rip), %r13      # 0x3fe0
xorl %eax, %eax
cmpq $0x28, %rax
jne 0x1428
xorl %eax, %eax
cmpq $0x28, %rax
je 0x1432
movq 0xd0(%rsp,%rax,8), %rcx
movb $0x0, (%rcx)
incq %rax
jmp 0x1412
andl $0x0, 0x30(%rsp,%rax,4)
incq %rax
jmp 0x140a
leaq 0xc06(%rip), %rdi       # 0x203f
xorl %eax, %eax
callq 0x1030
xorl %ebx, %ebx
movq (%r13), %rdi
callq 0x10d0
movb %al, 0x530(%rsp,%rbx)
leaq 0x1(%rbx), %rcx
cmpb $0xa, %al
je 0x1466
cmpq $0x7cf, %rbx            # imm = 0x7CF
movq %rcx, %rbx
jb 0x1442
movb $0x0, 0x52f(%rsp,%rcx)
leaq 0x530(%rsp), %rbx
movq %rbx, %rdi
leaq 0xbe8(%rip), %rsi       # 0x2068
pushq $0x5
popq %rdx
callq 0x1060
testl %eax, %eax
je 0x121e
leaq 0x3411(%rsp), %rax
xorl %ecx, %ecx
xorl %edi, %edi
leaq (%rcx,%rbx), %rdx
incq %rdx
xorl %r12d, %r12d
movb -0x1(%rdx,%r12), %sil
movb %sil, -0x1(%rax,%r12)
movb $0x0, (%rax,%r12)
movzbl (%rdx,%r12), %esi
incq %r12
testl %esi, %esi
je 0x14d7
cmpl $0x20, %esi
jne 0x14a6
incq %rdi
addq $0x7d0, %rax            # imm = 0x7D0
addq %r12, %rcx
incq %rcx
jmp 0x149c
xorl %r13d, %r13d
movq %rdi, 0x10(%rsp)
cmpq %rdi, %r13
ja 0x1589
movq 0x28(%rsp), %r15
imulq $0x7d0, %r13, %rax      # imm = 0x7D0
leaq (%rsp,%rax), %rbp
addq $0x3410, %rbp           # imm = 0x3410
testq %r15, %r15
movl $0x0, %r12d
cmovgq %r15, %r12
movq 0x18(%rsp), %rbx
xorl %r14d, %r14d
cmpq %r14, %r12
je 0x1534
movq %rbx, %rdi
movq %rbp, %rsi
callq 0x1090
testl %eax, %eax
je 0x1531
incq %r14
addq $0x32, %rbx
jmp 0x1514
movq %r14, %r12
cmpq %r15, %r12
movq %r12, %rdx
pushq $-0x1
popq %rax
cmoveq %rax, %rdx
movq %rdx, 0x210(%rsp,%r13,8)
leaq 0xb1d(%rip), %rdi       # 0x206d
movq %rbp, %rsi
xorl %eax, %eax
callq 0x1030
incq %r13
cmpq %r15, %r12
pushq $0x1
popq %r15
movq 0x10(%rsp), %rdi
jne 0x14df
leaq 0xb2a(%rip), %rdi       # 0x20a0
callq 0x10b0
xorl %eax, %eax
movq 0x2a5c(%rip), %r13      # 0x3fe0
jmp 0x140a
movl $0x0, %eax
cmpq $-0x1, %r12
movq 0x8(%rsp), %r12
movq 0x2a42(%rip), %r13      # 0x3fe0
je 0x140a
leaq 0xb0d(%rip), %rdi       # 0x20b8
callq 0x10b0
movq 0x10(%rsp), %r8
movq (%rsp), %rcx
testq %rcx, %rcx
movl $0x0, %eax
cmovgq %rcx, %rax
xorl %edx, %edx
cmpq %rdx, %rax
je 0x15d9
andl $0x0, 0xd00(%rsp,%rdx,4)
incq %rdx
jmp 0x15c7
xorl %edx, %edx
cmpq %r8, %rdx
ja 0x161e
movq 0x210(%rsp,%rdx,8), %rsi
cmpq $-0x1, %rsi
je 0x1619
imulq %rcx, %rsi
leaq (%r12,%rsi,4), %rsi
xorl %edi, %edi
cmpq %rdi, %rax
je 0x1619
movss (%rsi,%rdi,4), %xmm0
addss 0xd00(%rsp,%rdi,4), %xmm0
movss %xmm0, 0xd00(%rsp,%rdi,4)
incq %rdi
jmp 0x15f8
incq %rdx
jmp 0x15db
xorps %xmm0, %xmm0
xorl %ecx, %ecx
cmpq %rcx, %rax
je 0x163e
movss 0xd00(%rsp,%rcx,4), %xmm1
mulss %xmm1, %xmm1
addss %xmm1, %xmm0
incq %rcx
jmp 0x1623
ucomiss 0x9bf(%rip), %xmm0      # 0x2004
jb 0x164d
sqrtss %xmm0, %xmm0
jmp 0x1657
callq 0x10e0
movq 0x10(%rsp), %r8
movq (%rsp), %rax
testq %rax, %rax
movl $0x0, %ecx
cmovleq %rcx, %rax
xorl %ecx, %ecx
cmpq %rcx, %rax
je 0x1689
movss 0xd00(%rsp,%rcx,4), %xmm1
divss %xmm0, %xmm1
movss %xmm1, 0xd00(%rsp,%rcx,4)
incq %rcx
jmp 0x1669
xorl %eax, %eax
cmpq $0x28, %rax
je 0x169e
movl $0xbf800000, 0x30(%rsp,%rax,4) # imm = 0xBF800000
incq %rax
jmp 0x168b
xorl %eax, %eax
cmpq $0x28, %rax
je 0x16b6
movq 0xd0(%rsp,%rax,8), %rcx
movb $0x0, (%rcx)
incq %rax
jmp 0x16a0
xorl %ebx, %ebx
xorl %ebp, %ebp
cmpq 0x28(%rsp), %rbp
jge 0x17a7
xorl %eax, %eax
xorl %ecx, %ecx
cmpq %r8, %rcx
ja 0x16df
cmpq %rbp, 0x210(%rsp,%rcx,8)
cmoveq %r15, %rax
incq %rcx
jmp 0x16c9
cmpq $0x1, %rax
je 0x179b
movq (%rsp), %rax
testq %rax, %rax
movl $0x0, %ecx
cmovgq %rax, %rcx
imulq %rbx, %rax
addq %r12, %rax
xorps %xmm1, %xmm1
xorl %edx, %edx
cmpq %rdx, %rcx
je 0x1721
movss 0xd00(%rsp,%rdx,4), %xmm0
mulss (%rax,%rdx,4), %xmm0
addss %xmm0, %xmm1
incq %rdx
jmp 0x1705
xorl %r14d, %r14d
cmpq $0x28, %r14
je 0x179b
ucomiss 0x30(%rsp,%r14,4), %xmm1
ja 0x1737
incq %r14
jmp 0x1724
pushq $0x27
popq %rax
movss %xmm1, 0x20(%rsp)
cmpq %r14, %rax
jbe 0x1775
leaq -0x1(%rax), %r15
movss 0x2c(%rsp,%rax,4), %xmm0
movss %xmm0, 0x30(%rsp,%rax,4)
movq 0xc8(%rsp,%rax,8), %rsi
movq 0xd0(%rsp,%rax,8), %rdi
callq 0x1040
movss 0x20(%rsp), %xmm1
movq %r15, %rax
jmp 0x1740
movss %xmm1, 0x30(%rsp,%r14,4)
movq 0xd0(%rsp,%r14,8), %rdi
imulq $0x32, %rbp, %rsi
addq 0x18(%rsp), %rsi
callq 0x1040
pushq $0x1
popq %r15
movq 0x10(%rsp), %r8
incq %rbp
addq $0x4, %rbx
jmp 0x16ba
xorl %ebx, %ebx
leaq 0x8e6(%rip), %r14       # 0x2096
cmpq $0x28, %rbx
je 0x1408
movq 0xd0(%rsp,%rbx,8), %rsi
cvtss2sd 0x30(%rsp,%rbx,4), %xmm0
movq %r14, %rdi
movb $0x1, %al
callq 0x1030
incq %rbx
jmp 0x17b0
leaq 0x96d(%rip), %rdi       # 0x214b
callq 0x10b0
jmp 0x180a
shrq $0x12, %r14
movabsq $0xfffffffffff, %rsi    # imm = 0xFFFFFFFFFFF
andq %r14, %rsi
leaq 0x813(%rip), %rdi       # 0x2010
movq %rbx, %rdx
movq %r15, %rcx
xorl %eax, %eax
callq 0x1030
pushq $-0x1
popq %rax
addq $0x34158, %rsp          # imm = 0x34158
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq