// File: CMU-SAFARI[P]optimal-seed-solver/testBasicSolver.cc
// Function: main
int main(int argc, const char* argv[]) {
	int frequency;
	map <int, unsigned long long> frequencyCounter;

	BasicSolver solver;

	if (argc != 3) {
		cerr << "USAGE: ./testOptimalSolver <Tree File> <Read File>" << endl;
		exit(1);
	}

	cout << "Loading tree " << argv[1] << " into memory.\n";
	solver.loadTree(argv[1]);
	cout << "Finished loading. \n";

	int seedNum;
	//cout << "Please input number of seeds: ";
	cin >> seedNum;

	int seedLength;

	ifstream readFile;
	readFile.open(argv[2]);
	string read;
	
	char benchFileName[80];
	strcpy(benchFileName, argv[2]);
	char* benchName = strtok(benchFileName, ".");
	
	ofstream output;
	output.open( (string(benchName) + string(".analyzeBasic") ).c_str() );

	while (seedNum > 0) {	
		//cout << "Please input seed length: ";
		cin >> seedLength;
		
		frequencyCounter.clear();

		//Start reading the file
		readFile.clear();
		readFile.seekg(0, ios::beg);

		//Name
		getline(readFile, read);
		//Read
		getline(readFile, read);
		//cout << "DNA: " << read << endl;
		solver.init(read.length(), seedNum, seedLength);

		//Solve
		frequency = solver.solveDNA(read);
		if (frequencyCounter.find(frequency) == frequencyCounter.end() )
			frequencyCounter[frequency] = 1;
		else
			frequencyCounter[frequency]++;

		//Trash
		getline(readFile, read);
		getline(readFile, read);
			
		//Name
		getline(readFile, read);

		while (!readFile.eof()) {
			//Read
			getline(readFile, read);
			//cout << "DNA: " << read << endl;

			//Solve
			if (read.find('N') == string::npos) {
				frequency = solver.solveDNA(read);
				if (frequencyCounter.find(frequency) == frequencyCounter.end() )
					frequencyCounter[frequency] = 1;
				else
					frequencyCounter[frequency]++;
			}

			//Trash
			getline(readFile, read);
			getline(readFile, read);
			
			//Name
			getline(readFile, read);
		}

		cout << "seedNum: " << seedNum << " | seedLength: " << seedLength << endl;
		output << "seedNum: " << seedNum << " | seedLength: " << seedLength << endl;
		for (map<int, unsigned long long>::iterator iter = frequencyCounter.begin(); iter != frequencyCounter.end(); iter++)
			output << iter->first << ": " << iter->second << endl;

		cin >> seedNum;
	}
	
	return 0;
}

// Assembly:
subq $0xa38, %rsp            # imm = 0xA38
movl $0x0, 0xa34(%rsp)
movl %edi, 0xa30(%rsp)
movq %rsi, 0xa28(%rsp)
leaq 0x9f0(%rsp), %rdi
callq 0x4360
leaq 0x688(%rsp), %rdi
callq 0x5e60
jmp 0x38ad
cmpl $0x3, 0xa30(%rsp)
je 0x3926
movq 0x17732(%rip), %rdi     # 0x1aff0
leaq 0xf73f(%rip), %rsi      # 0x13004
callq 0x32a0
movq %rax, 0xd8(%rsp)
jmp 0x38d4
movq 0xd8(%rsp), %rdi
movq 0x176d5(%rip), %rsi     # 0x1afb8
callq 0x32f0
jmp 0x38ea
movl $0x1, %edi
callq 0x3380
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x680(%rsp)
movl %eax, 0x67c(%rsp)
jmp 0x4343
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x680(%rsp)
movl %eax, 0x67c(%rsp)
jmp 0x4336
movq 0x1769b(%rip), %rdi     # 0x1afc8
leaq 0xf703(%rip), %rsi      # 0x13037
callq 0x32a0
movq %rax, 0xd0(%rsp)
jmp 0x3943
movq 0xd0(%rsp), %rdi
movq 0xa28(%rsp), %rax
movq 0x8(%rax), %rsi
callq 0x32a0
movq %rax, 0xc8(%rsp)
jmp 0x3966
movq 0xc8(%rsp), %rdi
leaq 0xf6d0(%rip), %rsi      # 0x13045
callq 0x32a0
jmp 0x397c
movq 0xa28(%rsp), %rax
movq 0x8(%rax), %rax
movq %rax, 0xb8(%rsp)
leaq 0x657(%rsp), %rdi
movq %rdi, 0xc0(%rsp)
callq 0x35a0
movq 0xb8(%rsp), %rsi
movq 0xc0(%rsp), %rdx
leaq 0x658(%rsp), %rdi
callq 0x4370
jmp 0x39c4
leaq 0x688(%rsp), %rdi
leaq 0x658(%rsp), %rsi
callq 0x5e90
jmp 0x39db
leaq 0x658(%rsp), %rdi
callq 0x31b0
leaq 0x657(%rsp), %rdi
callq 0x3310
movq 0x175cc(%rip), %rdi     # 0x1afc8
leaq 0xf651(%rip), %rsi      # 0x13054
callq 0x32a0
jmp 0x3a0a
movq 0x175c7(%rip), %rdi     # 0x1afd8
leaq 0x650(%rsp), %rsi
callq 0x31a0
jmp 0x3a20
leaq 0x440(%rsp), %rdi
callq 0x3350
jmp 0x3a2f
movq 0xa28(%rsp), %rax
movq 0x10(%rax), %rsi
leaq 0x440(%rsp), %rdi
movl $0x8, %edx
callq 0x31c0
jmp 0x3a4f
leaq 0x420(%rsp), %rdi
callq 0x3450
movq 0xa28(%rsp), %rax
movq 0x10(%rax), %rsi
leaq 0x3d0(%rsp), %rdi
movq %rdi, 0xb0(%rsp)
callq 0x3290
movq 0xb0(%rsp), %rdi
leaq 0xfac1(%rip), %rsi      # 0x1354d
callq 0x34c0
movq %rax, 0x3c8(%rsp)
leaq 0x1c8(%rsp), %rdi
callq 0x3540
jmp 0x3aa8
movq 0x3c8(%rsp), %rax
movq %rax, 0xa0(%rsp)
leaq 0x187(%rsp), %rdi
movq %rdi, 0xa8(%rsp)
callq 0x35a0
movq 0xa0(%rsp), %rsi
movq 0xa8(%rsp), %rdx
leaq 0x188(%rsp), %rdi
callq 0x4370
jmp 0x3aec
leaq 0x15f(%rsp), %rdi
movq %rdi, 0x98(%rsp)
callq 0x35a0
movq 0x98(%rsp), %rdx
leaq 0xf558(%rip), %rsi      # 0x13068
leaq 0x160(%rsp), %rdi
callq 0x4370
jmp 0x3b1f
leaq 0x1a8(%rsp), %rdi
leaq 0x188(%rsp), %rsi
leaq 0x160(%rsp), %rdx
callq 0x4430
jmp 0x3b3e
leaq 0x1a8(%rsp), %rdi
callq 0x3130
movq %rax, %rsi
leaq 0x1c8(%rsp), %rdi
movl $0x10, %edx
callq 0x3050
jmp 0x3b62
leaq 0x1a8(%rsp), %rdi
callq 0x31b0
leaq 0x160(%rsp), %rdi
callq 0x31b0
leaq 0x15f(%rsp), %rdi
callq 0x3310
leaq 0x188(%rsp), %rdi
callq 0x31b0
leaq 0x187(%rsp), %rdi
callq 0x3310
cmpl $0x0, 0x650(%rsp)
jle 0x42b4
movq 0x17420(%rip), %rdi     # 0x1afd8
leaq 0x64c(%rsp), %rsi
callq 0x31a0
jmp 0x3bc7
leaq 0x9f0(%rsp), %rdi
callq 0x4520
movq 0x440(%rsp), %rax
movq -0x18(%rax), %rax
leaq 0x440(%rsp,%rax), %rdi
xorl %esi, %esi
callq 0x3520
jmp 0x3bf1
xorl %edx, %edx
movl %edx, %esi
leaq 0x440(%rsp), %rdi
callq 0x3440
jmp 0x3c04
leaq 0x440(%rsp), %rdi
leaq 0x420(%rsp), %rsi
callq 0x30a0
jmp 0x3c1b
leaq 0x440(%rsp), %rdi
leaq 0x420(%rsp), %rsi
callq 0x30a0
jmp 0x3c32
leaq 0x420(%rsp), %rdi
callq 0x34a0
movl %eax, %esi
movl 0x650(%rsp), %edx
movl 0x64c(%rsp), %ecx
leaq 0x688(%rsp), %rdi
callq 0x5f00
jmp 0x3c5e
leaq 0x138(%rsp), %rdi
leaq 0x420(%rsp), %rsi
callq 0x3140
jmp 0x3c75
leaq 0x688(%rsp), %rdi
leaq 0x138(%rsp), %rsi
callq 0x5f40
movl %eax, 0x94(%rsp)
jmp 0x3c93
movl 0x94(%rsp), %eax
movl %eax, 0xa24(%rsp)
leaq 0x138(%rsp), %rdi
callq 0x31b0
leaq 0x9f0(%rsp), %rdi
leaq 0xa24(%rsp), %rsi
callq 0x4550
movq %rax, 0x88(%rsp)
jmp 0x3ccd
movq 0x88(%rsp), %rax
movq %rax, 0x130(%rsp)
leaq 0x9f0(%rsp), %rdi
callq 0x4580
movq %rax, 0x128(%rsp)
leaq 0x130(%rsp), %rdi
leaq 0x128(%rsp), %rsi
callq 0x4530
testb $0x1, %al
jne 0x3d10
jmp 0x3e99
leaq 0x9f0(%rsp), %rdi
leaq 0xa24(%rsp), %rsi
callq 0x45b0
movq %rax, 0x80(%rsp)
jmp 0x3d2f
movq 0x80(%rsp), %rax
movq $0x1, (%rax)
jmp 0x3ec4
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x680(%rsp)
movl %eax, 0x67c(%rsp)
jmp 0x3d7a
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x680(%rsp)
movl %eax, 0x67c(%rsp)
leaq 0x658(%rsp), %rdi
callq 0x31b0
leaq 0x657(%rsp), %rdi
callq 0x3310
jmp 0x4336
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x680(%rsp)
movl %eax, 0x67c(%rsp)
jmp 0x4329
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x680(%rsp)
movl %eax, 0x67c(%rsp)
jmp 0x431c
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x680(%rsp)
movl %eax, 0x67c(%rsp)
jmp 0x3e48
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x680(%rsp)
movl %eax, 0x67c(%rsp)
jmp 0x3e2e
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x680(%rsp)
movl %eax, 0x67c(%rsp)
jmp 0x3e21
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x680(%rsp)
movl %eax, 0x67c(%rsp)
leaq 0x1a8(%rsp), %rdi
callq 0x31b0
leaq 0x160(%rsp), %rdi
callq 0x31b0
leaq 0x15f(%rsp), %rdi
callq 0x3310
leaq 0x188(%rsp), %rdi
callq 0x31b0
leaq 0x187(%rsp), %rdi
callq 0x3310
jmp 0x430f
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x680(%rsp)
movl %eax, 0x67c(%rsp)
jmp 0x430f
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x680(%rsp)
movl %eax, 0x67c(%rsp)
leaq 0x138(%rsp), %rdi
callq 0x31b0
jmp 0x430f
leaq 0x9f0(%rsp), %rdi
leaq 0xa24(%rsp), %rsi
callq 0x45b0
movq %rax, 0x78(%rsp)
jmp 0x3eb5
movq 0x78(%rsp), %rax
movq (%rax), %rcx
addq $0x1, %rcx
movq %rcx, (%rax)
leaq 0x440(%rsp), %rdi
leaq 0x420(%rsp), %rsi
callq 0x30a0
jmp 0x3edb
leaq 0x440(%rsp), %rdi
leaq 0x420(%rsp), %rsi
callq 0x30a0
jmp 0x3ef2
leaq 0x440(%rsp), %rdi
leaq 0x420(%rsp), %rsi
callq 0x30a0
jmp 0x3f09
jmp 0x3f0b
movq 0x440(%rsp), %rax
movq -0x18(%rax), %rax
leaq 0x440(%rsp,%rax), %rdi
callq 0x35d0
movb %al, 0x77(%rsp)
jmp 0x3f2a
movb 0x77(%rsp), %al
xorb $-0x1, %al
testb $0x1, %al
jne 0x3f39
jmp 0x40da
leaq 0x440(%rsp), %rdi
leaq 0x420(%rsp), %rsi
callq 0x30a0
jmp 0x3f50
leaq 0x420(%rsp), %rdi
movl $0x4e, %esi
xorl %eax, %eax
movl %eax, %edx
callq 0x33f0
cmpq $-0x1, %rax
jne 0x4090
leaq 0x108(%rsp), %rdi
leaq 0x420(%rsp), %rsi
callq 0x3140
jmp 0x3f87
leaq 0x688(%rsp), %rdi
leaq 0x108(%rsp), %rsi
callq 0x5f40
movl %eax, 0x70(%rsp)
jmp 0x3fa2
movl 0x70(%rsp), %eax
movl %eax, 0xa24(%rsp)
leaq 0x108(%rsp), %rdi
callq 0x31b0
leaq 0x9f0(%rsp), %rdi
leaq 0xa24(%rsp), %rsi
callq 0x4550
movq %rax, 0x68(%rsp)
jmp 0x3fd6
movq 0x68(%rsp), %rax
movq %rax, 0x100(%rsp)
leaq 0x9f0(%rsp), %rdi
callq 0x4580
movq %rax, 0xf8(%rsp)
leaq 0x100(%rsp), %rdi
leaq 0xf8(%rsp), %rsi
callq 0x4530
testb $0x1, %al
jne 0x4013
jmp 0x4063
leaq 0x9f0(%rsp), %rdi
leaq 0xa24(%rsp), %rsi
callq 0x45b0
movq %rax, 0x60(%rsp)
jmp 0x402f
movq 0x60(%rsp), %rax
movq $0x1, (%rax)
jmp 0x408e
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x680(%rsp)
movl %eax, 0x67c(%rsp)
leaq 0x108(%rsp), %rdi
callq 0x31b0
jmp 0x430f
leaq 0x9f0(%rsp), %rdi
leaq 0xa24(%rsp), %rsi
callq 0x45b0
movq %rax, 0x58(%rsp)
jmp 0x407f
movq 0x58(%rsp), %rax
movq (%rax), %rcx
addq $0x1, %rcx
movq %rcx, (%rax)
jmp 0x4090
leaq 0x440(%rsp), %rdi
leaq 0x420(%rsp), %rsi
callq 0x30a0
jmp 0x40a7
leaq 0x440(%rsp), %rdi
leaq 0x420(%rsp), %rsi
callq 0x30a0
jmp 0x40be
leaq 0x440(%rsp), %rdi
leaq 0x420(%rsp), %rsi
callq 0x30a0
jmp 0x40d5
jmp 0x3f0b
movq 0x16ee7(%rip), %rdi     # 0x1afc8
leaq 0xef8e(%rip), %rsi      # 0x13076
callq 0x32a0
movq %rax, 0x50(%rsp)
jmp 0x40f4
movq 0x50(%rsp), %rdi
movl 0x650(%rsp), %esi
callq 0x3570
movq %rax, 0x48(%rsp)
jmp 0x410c
movq 0x48(%rsp), %rdi
leaq 0xef68(%rip), %rsi      # 0x13080
callq 0x32a0
movq %rax, 0x40(%rsp)
jmp 0x4124
movq 0x40(%rsp), %rdi
movl 0x64c(%rsp), %esi
callq 0x3570
movq %rax, 0x38(%rsp)
jmp 0x413c
movq 0x38(%rsp), %rdi
movq 0x16e70(%rip), %rsi     # 0x1afb8
callq 0x32f0
jmp 0x414f
leaq 0xef20(%rip), %rsi      # 0x13076
leaq 0x1c8(%rsp), %rdi
callq 0x32a0
movq %rax, 0x30(%rsp)
jmp 0x416a
movq 0x30(%rsp), %rdi
movl 0x650(%rsp), %esi
callq 0x3570
movq %rax, 0x28(%rsp)
jmp 0x4182
movq 0x28(%rsp), %rdi
leaq 0xeef2(%rip), %rsi      # 0x13080
callq 0x32a0
movq %rax, 0x20(%rsp)
jmp 0x419a
movq 0x20(%rsp), %rdi
movl 0x64c(%rsp), %esi
callq 0x3570
movq %rax, 0x18(%rsp)
jmp 0x41b2
movq 0x18(%rsp), %rdi
movq 0x16dfa(%rip), %rsi     # 0x1afb8
callq 0x32f0
jmp 0x41c5
leaq 0x9f0(%rsp), %rdi
callq 0x46a0
movq %rax, 0xf0(%rsp)
leaq 0x9f0(%rsp), %rdi
callq 0x4580
movq %rax, 0xe8(%rsp)
leaq 0xf0(%rsp), %rdi
leaq 0xe8(%rsp), %rsi
callq 0x46d0
testb $0x1, %al
jne 0x420d
jmp 0x4299
leaq 0xf0(%rsp), %rdi
callq 0x46f0
movl (%rax), %esi
leaq 0x1c8(%rsp), %rdi
callq 0x3570
movq %rax, 0x10(%rsp)
jmp 0x4230
movq 0x10(%rsp), %rdi
leaq 0xf36b(%rip), %rsi      # 0x135a7
callq 0x32a0
movq %rax, 0x8(%rsp)
jmp 0x4248
leaq 0xf0(%rsp), %rdi
callq 0x46f0
movq 0x8(%rsp), %rdi
movq 0x8(%rax), %rsi
callq 0x3280
movq %rax, (%rsp)
jmp 0x4269
movq (%rsp), %rdi
movq 0x16d44(%rip), %rsi     # 0x1afb8
callq 0x32f0
jmp 0x427b
jmp 0x427d
leaq 0xf0(%rsp), %rdi
xorl %esi, %esi
callq 0x4710
movq %rax, 0xe0(%rsp)
jmp 0x41da
movq 0x16d38(%rip), %rdi     # 0x1afd8
leaq 0x650(%rsp), %rsi
callq 0x31a0
jmp 0x42af
jmp 0x3ba3
movl $0x0, 0xa34(%rsp)
leaq 0x1c8(%rsp), %rdi
callq 0x3490
leaq 0x420(%rsp), %rdi
callq 0x31b0
leaq 0x440(%rsp), %rdi
callq 0x30e0
leaq 0x688(%rsp), %rdi
callq 0x5e80
leaq 0x9f0(%rsp), %rdi
callq 0x4750
movl 0xa34(%rsp), %eax
addq $0xa38, %rsp            # imm = 0xA38
retq
leaq 0x1c8(%rsp), %rdi
callq 0x3490
leaq 0x420(%rsp), %rdi
callq 0x31b0
leaq 0x440(%rsp), %rdi
callq 0x30e0
leaq 0x688(%rsp), %rdi
callq 0x5e80
leaq 0x9f0(%rsp), %rdi
callq 0x4750
movq 0x680(%rsp), %rdi
callq 0x3590
nopl (%rax)