├── .gitignore ├── Experiments ├── InlineASM.c ├── InlineASM.cpp ├── IntMain.c ├── PointerWeirdness.cpp ├── RuntimeAssemblyExecution.cpp ├── RuntimeAssemblyExecutionv2.cpp └── TravellingSalesmanProblem.ipynb ├── GraphSearch.cpp ├── HashTable.cpp ├── Heap.cpp ├── InfixCalculator.cpp ├── LICENSE ├── LinkedList.cpp ├── Palindrome.cpp ├── Punctuation.cpp ├── README.md ├── RedBlack.cpp ├── Reference-vs-Value.cpp ├── ReversibleStack.cpp ├── TicTacToe-Broken.cpp ├── TicTacToe.cpp ├── Vectors.cpp ├── ZuulGame.cpp ├── buildout ├── example-code ├── C Hash Table │ ├── hashtable.c │ ├── hashtable.h │ └── main.c └── RedBlack.cpp ├── friends-homework ├── CharleneSquare3.java ├── CharleneSquare4.java ├── JonahMusicReader.cpp ├── LanguageFamilyNode.class ├── LanguageFamilyNode.java ├── LanguageLearner.class ├── LanguageLearner.java ├── LanguagePredictor.class ├── LanguagePredictor.java ├── docs │ ├── test │ │ ├── 1.txt │ │ ├── 10.txt │ │ ├── 11.txt │ │ ├── 12.txt │ │ ├── 13.txt │ │ ├── 14.txt │ │ ├── 15.txt │ │ ├── 16.txt │ │ ├── 17.txt │ │ ├── 18.txt │ │ ├── 19.txt │ │ ├── 2.txt │ │ ├── 20.txt │ │ ├── 3.txt │ │ ├── 4.txt │ │ ├── 5.txt │ │ ├── 6.txt │ │ ├── 7.txt │ │ ├── 8.txt │ │ └── 9.txt │ └── train │ │ ├── eng │ │ ├── 1.txt │ │ ├── 10.txt │ │ ├── 11.txt │ │ ├── 12.txt │ │ ├── 13.txt │ │ ├── 14.txt │ │ ├── 15.txt │ │ ├── 16.txt │ │ ├── 17.txt │ │ ├── 18.txt │ │ ├── 19.txt │ │ ├── 2.txt │ │ ├── 20.txt │ │ ├── 3.txt │ │ ├── 4.txt │ │ ├── 5.txt │ │ ├── 6.txt │ │ ├── 7.txt │ │ ├── 8.txt │ │ └── 9.txt │ │ └── fre │ │ ├── 1.txt │ │ ├── 10.txt │ │ ├── 11.txt │ │ ├── 12.txt │ │ ├── 13.txt │ │ ├── 14.txt │ │ ├── 15.txt │ │ ├── 16.txt │ │ ├── 17.txt │ │ ├── 18.txt │ │ ├── 19.txt │ │ ├── 2.txt │ │ ├── 20.txt │ │ ├── 3.txt │ │ ├── 4.txt │ │ ├── 5.txt │ │ ├── 6.txt │ │ ├── 7.txt │ │ ├── 8.txt │ │ └── 9.txt ├── eng_vocab.txt └── fre_vocab.txt ├── graphsearch.txt ├── redblack.txt └── tutorials ├── A Quick Introduction to C++ by Tom Anderson.pdf ├── C++ Language Tutorial by Juan Soulie.pdf ├── CS11 Introduction to C++ Slideshow.pdf ├── TicTacToe C++ Tutorial - LiteratePrograms.html └── Understanding C++ An Accelerated Introduction.pdf /.gitignore: -------------------------------------------------------------------------------- 1 | *.pyc 2 | *.out 3 | .idea 4 | .__pycache__ 5 | -------------------------------------------------------------------------------- /Experiments/InlineASM.c: -------------------------------------------------------------------------------- 1 | #include 2 | #simdi 3 | #64 bit register scheme 4 | 5 | int output_a, output_b, input_a, input_b; 6 | 7 | void resetvals() { 8 | output_a = -1; // if you see -1 in the final program output, you know tha assembly did nothing 9 | output_b = -1; 10 | input_a = 0; 11 | input_b = 0; 12 | } 13 | 14 | void printout() { 15 | printf(" input_a=%i, input_b=%i\noutput_a=%i, output_b=%i\n\n", input_a, input_b, output_a, output_b); 16 | } 17 | 18 | int main(void) { 19 | 20 | /* movl $foo,%eax puts the address of variable foo into register %eax, but movl foo,%eax puts the contents of variable foo into register %eax. 21 | There are two %’s prefixed to the register name. This helps GCC to distinguish between the operands and registers. operands have a single % as prefix. 22 | 23 | The clobbered register %eax after the third colon tells GCC that the value of %eax is to be modified inside "asm", so GCC won’t use this register to store any other value. 24 | 25 | +---+--------------------+ 26 | | r | Register(s) | 27 | +---+--------------------+ 28 | | a | %eax, %ax, %al | 29 | | b | %ebx, %bx, %bl | 30 | | c | %ecx, %cx, %cl | 31 | | d | %edx, %dx, %dl | 32 | | S | %esi, %si | 33 | | D | %edi, %di | 34 | +---+--------------------+ 35 | */ 36 | 37 | resetvals(); 38 | input_a=2, input_b=3; 39 | __asm__( 40 | "movl %0, %2;" // move input_1 to output_1 41 | "movl %1, %3;" // move input_2 to output_2 42 | 43 | :"=r" (output_a) , "=i" (output_b) /* output */ 44 | :"r" (input_a) , "0" (input_b) /* input */ 45 | :"%eax" 46 | ); 47 | printout(); 48 | 49 | resetvals(); 50 | input_a=5, input_b=4; 51 | __asm__( 52 | "leal (%0,%0,1), %2;" 53 | 54 | :"=r" (output_a) /* output */ 55 | :"r" (input_a) , "r" (input_b) /* input */ 56 | :"%eax" /* clobbered register */ 57 | ); 58 | printout(); 59 | 60 | return 0; 61 | } 62 | 63 | 64 | 65 | 66 | 67 | /* 68 | 69 | balancing the stacjk = pushing and popping in reverse the proper number of pointers 70 | 71 | */ 72 | -------------------------------------------------------------------------------- /Experiments/InlineASM.cpp: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | 3 | int a = 10; 4 | int b; 5 | asm ("movl %1, %%eax; 6 | movl %%eax, %0;" 7 | :"=r"(b) /* output */ 8 | :"r"(a) /* input */ 9 | :"%eax" /* clobbered register */ 10 | ); 11 | 12 | 13 | return 0; 14 | } 15 | -------------------------------------------------------------------------------- /Experiments/IntMain.c: -------------------------------------------------------------------------------- 1 | // gcc -Wall wut.c -o main && ./main 2 | 3 | // computer jumps to main and begins executing, whether it's a function or variable! 4 | // this means we can encode our assembly bytes into numbers and stick them in main! 5 | const int main[] = { 6 | -443987883, 440, 113408, -1922629632, 7 | 4149, 899584, 84869120, 15544, 8 | 266023168, 1818576901, 1461743468, 1684828783, 9 | -1017312735 10 | }; 11 | -------------------------------------------------------------------------------- /Experiments/PointerWeirdness.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | 5 | using namespace std; 6 | 7 | int main () { 8 | int ints[10] = {0,1,2,3,4,5,6,7,8,9}; 9 | cout << 7[ints] << endl; 10 | cout << ints[8] << endl; 11 | // ints[7] is shorthand for *(ints+7) 12 | // so 7[ints] works because *(7+ints) is the same as *(ints+7) 13 | } 14 | -------------------------------------------------------------------------------- /Experiments/RuntimeAssemblyExecution.cpp: -------------------------------------------------------------------------------- 1 | /* Nick Sweeting 2014/02/13 2 | MIT License 3 | */ 4 | 5 | #include 6 | #include 7 | #include // isdigit (parsing for tokens/ops) 8 | #include // duh 9 | #include // cout 10 | #include 11 | #include 12 | using namespace std; 13 | 14 | typedef int(*vfuncp)(void); 15 | 16 | int crazy() { 17 | return 69; 18 | } 19 | void dummy() {} 20 | 21 | char shellcode[] = { 22 | 0xb8, 0x2a, 0x00, 0x00, 0x00, //mov $0x2a,%eax 23 | 0xc3 //retq 24 | }; 25 | 26 | int main () { 27 | // this works 28 | 29 | int test1[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9}; 30 | int *newtest3loc = (int *) malloc(sizeof(test1)); 31 | memcpy(newtest3loc, test1, sizeof(test1)); 32 | cout << "memcpy'ed arrays work fine: " << newtest3loc[2] << endl; 33 | 34 | // this too 35 | 36 | uintptr_t pageSize = 4096; 37 | uintptr_t shellcodeAddr = (uintptr_t)shellcode; 38 | uintptr_t pageAlignedAddr = shellcodeAddr & ~(pageSize-1); 39 | vfuncp shellcodeFn = (vfuncp)shellcode; 40 | 41 | mprotect((void*)pageAlignedAddr, 42 | (shellcodeAddr - pageAlignedAddr) + sizeof(shellcode), 43 | PROT_EXEC|PROT_WRITE|PROT_READ); 44 | 45 | cout << "calling runtime-copied mprotect'ed assembly works fine too: " << shellcodeFn() << endl; 46 | 47 | 48 | // what about this? 49 | 50 | void *crazyfuncloc = (void*)&crazy; 51 | void *dummyfuncloc = (void*)&dummy; 52 | 53 | unsigned long crazy_func_size = (unsigned long)dummyfuncloc - (unsigned long)crazyfuncloc; 54 | 55 | uintptr_t crazy_addr = (uintptr_t)crazy; 56 | uintptr_t page_aligned_crazy_addr = crazy_addr & ~(pageSize-1); 57 | vfuncp crazy_func = (vfuncp)crazy; 58 | 59 | mprotect((void*)page_aligned_crazy_addr, 60 | (crazy_addr - page_aligned_crazy_addr) + crazy_func_size, 61 | PROT_EXEC|PROT_WRITE|PROT_READ); 62 | 63 | cout << "calling a runtime-copied mprotect'ed normal function works fine: " << crazy_func() << endl; 64 | } 65 | -------------------------------------------------------------------------------- /Experiments/RuntimeAssemblyExecutionv2.cpp: -------------------------------------------------------------------------------- 1 | /* Nick Sweeting 2014/09/26 2 | Runtime function copying and execution 3 | MIT License 4 | */ 5 | 6 | #include // duh 7 | #include // cout 8 | #include // memcpy, mprotect 9 | using namespace std; 10 | 11 | const unsigned long page_size = 4096; 12 | 13 | int func(int a, int b) {return a+b;} 14 | void dummy() {} 15 | // assuming functions are sequential in memory: func_size = &dummy - &func 16 | 17 | typedef int(*funcp)(int, int); 18 | 19 | int main () { 20 | unsigned long func_size = (unsigned long)&dummy - (unsigned long)&func; // calculate func size at runtime 21 | 22 | unsigned long newmem_addr = (unsigned long) malloc(func_size); // allocate new memory to copy function into 23 | unsigned long page_aligned_newmem_addr = newmem_addr & ~(page_size-1); // calculate page_aligned address (memcpy takes normal addrs, but mprotect takes page_aligned addrs) 24 | 25 | memcpy((void*)newmem_addr, // to addr // copy the function to the new malloc'ed memory block 26 | (void*)&func, // from addr 27 | func_size); cout << "1. memcpy'ed " << func_size << " byte function from @" << (unsigned long)&func << " to @" << newmem_addr << endl; 28 | 29 | funcp copied_func = (funcp)newmem_addr; // create a func pointer to the function in the new location 30 | 31 | mprotect((void*)page_aligned_newmem_addr, // from addr // add execute access to the malloc'ed memory block holding the copied function 32 | func_size, // # of bytes 33 | PROT_EXEC); cout << "2. mprotect +PROT_EXEC'ed " << func_size << " bytes of memory from @" << newmem_addr << " through @" << newmem_addr+func_size << endl; 34 | 35 | int result = (*copied_func)(40,2); cout << "3. Result of executing copied function in new location: " << result << endl; 36 | } 37 | 38 | // I dont know the difference, but this and the version above both work: 39 | 40 | // mprotect((void*)page_aligned_newmem_addr, 41 | // (newmem_addr-page_aligned_newmem_addr)+func_size, 42 | // PROT_EXEC); 43 | -------------------------------------------------------------------------------- /Experiments/TravellingSalesmanProblem.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": 1, 6 | "metadata": { 7 | "collapsed": false 8 | }, 9 | "outputs": [ 10 | { 11 | "data": { 12 | "text/plain": [ 13 | "False" 14 | ] 15 | }, 16 | "execution_count": 1, 17 | "metadata": {}, 18 | "output_type": "execute_result" 19 | } 20 | ], 21 | "source": [ 22 | "2+2==5" 23 | ] 24 | }, 25 | { 26 | "cell_type": "code", 27 | "execution_count": 2, 28 | "metadata": { 29 | "collapsed": false 30 | }, 31 | "outputs": [], 32 | "source": [ 33 | "import matplotlib.pyplot as plt\n", 34 | " \n", 35 | "def plotTSP(path, points, num_iters=1):\n", 36 | " \n", 37 | " \"\"\"\n", 38 | " path: List of lists with the different orders in which the nodes are visited\n", 39 | " points: coordinates for the different nodes\n", 40 | " num_iters: number of paths that are in the path list\n", 41 | " \n", 42 | " \"\"\"\n", 43 | " \n", 44 | " # Unpack the primary TSP path and transform it into a list of ordered \n", 45 | " # coordinates\n", 46 | " \n", 47 | " x = []; y = []\n", 48 | " for i in paths[0]:\n", 49 | " x.append(points[i][0])\n", 50 | " y.append(points[i][1])\n", 51 | " \n", 52 | " plt.plot(x, y, 'co')\n", 53 | " \n", 54 | " # Set a scale for the arrow heads (there should be a reasonable default for this, WTF?)\n", 55 | " a_scale = float(max(x))/float(100)\n", 56 | " \n", 57 | " # Draw the older paths, if provided\n", 58 | " if num_iters > 1:\n", 59 | " \n", 60 | " for i in range(1, num_iters):\n", 61 | " \n", 62 | " # Transform the old paths into a list of coordinates\n", 63 | " xi = []; yi = [];\n", 64 | " for j in paths[i]:\n", 65 | " xi.append(points[j][0])\n", 66 | " yi.append(points[j][1])\n", 67 | " \n", 68 | " plt.arrow(xi[-1], yi[-1], (xi[0] - xi[-1]), (yi[0] - yi[-1]), \n", 69 | " head_width = a_scale, color = 'r', \n", 70 | " length_includes_head = True, ls = 'dashed',\n", 71 | " width = 0.001/float(num_iters))\n", 72 | " for i in range(0, len(x) - 1):\n", 73 | " plt.arrow(xi[i], yi[i], (xi[i+1] - xi[i]), (yi[i+1] - yi[i]),\n", 74 | " head_width = a_scale, color = 'r', length_includes_head = True,\n", 75 | " ls = 'dashed', width = 0.001/float(num_iters))\n", 76 | " \n", 77 | " # Draw the primary path for the TSP problem\n", 78 | " plt.arrow(x[-1], y[-1], (x[0] - x[-1]), (y[0] - y[-1]), head_width = a_scale, \n", 79 | " color ='g', length_includes_head=True)\n", 80 | " for i in range(0,len(x)-1):\n", 81 | " plt.arrow(x[i], y[i], (x[i+1] - x[i]), (y[i+1] - y[i]), head_width = a_scale,\n", 82 | " color = 'g', length_includes_head = True)\n", 83 | " \n", 84 | " #Set axis too slitghtly larger than the set of x and y\n", 85 | " plt.xlim(0, max(x)*1.1)\n", 86 | " plt.ylim(0, max(y)*1.1)\n", 87 | " plt.show()" 88 | ] 89 | }, 90 | { 91 | "cell_type": "code", 92 | "execution_count": 3, 93 | "metadata": { 94 | "collapsed": false 95 | }, 96 | "outputs": [], 97 | "source": [ 98 | " # Create a randomn list of coordinates, pack them into a list\n", 99 | " x_cor = [1, 8, 4, 9, 2, 1, 8]\n", 100 | " y_cor = [1, 2, 3, 4, 9, 5, 7]\n", 101 | " points = []\n", 102 | " for i in range(0, len(x_cor)):\n", 103 | " points.append((x_cor[i], y_cor[i]))\n", 104 | " \n", 105 | " # Create two paths, teh second with two values swapped to simulate a 2-OPT\n", 106 | " # Local Search operation\n", 107 | " path4 = [0, 1, 2, 3, 4, 5, 6]\n", 108 | " path3 = [0, 2, 1, 3, 4, 5, 6]\n", 109 | " path2 = [0, 2, 1, 3, 6, 5, 4]\n", 110 | " path1 = [0, 2, 1, 3, 6, 4, 5]\n", 111 | " \n", 112 | " # Pack the paths into a list\n", 113 | " paths = [path1, path2, path3, path4]\n", 114 | " \n", 115 | " # Run the function\n", 116 | " plotTSP(paths, points, 4)" 117 | ] 118 | }, 119 | { 120 | "cell_type": "code", 121 | "execution_count": 4, 122 | "metadata": { 123 | "collapsed": false 124 | }, 125 | "outputs": [], 126 | "source": [ 127 | "def rerun():\n", 128 | " x_cor = [1, 8, 4, 9, 2, 1, 8]\n", 129 | " y_cor = [1, 2, 3, 4, 9, 5, 7]\n", 130 | " points = []\n", 131 | " for i in range(0, len(x_cor)):\n", 132 | " points.append((x_cor[i], y_cor[i]))\n", 133 | " \n", 134 | " # Create two paths, teh second with two values swapped to simulate a 2-OPT\n", 135 | " # Local Search operation\n", 136 | " path4 = [0, 1, 2, 3, 4, 5, 6]\n", 137 | " path3 = [0, 2, 1, 3, 4, 5, 6]\n", 138 | " path2 = [0, 2, 1, 3, 6, 5, 4]\n", 139 | " path1 = [0, 2, 1, 3, 6, 4, 5]\n", 140 | " \n", 141 | " # Pack the paths into a list\n", 142 | " paths = [path1, path2, path3, path4]\n", 143 | " \n", 144 | " # Run the function\n", 145 | " plotTSP(paths, points, 4)" 146 | ] 147 | }, 148 | { 149 | "cell_type": "code", 150 | "execution_count": 5, 151 | "metadata": { 152 | "collapsed": false 153 | }, 154 | "outputs": [], 155 | "source": [ 156 | "rerun()" 157 | ] 158 | }, 159 | { 160 | "cell_type": "code", 161 | "execution_count": 6, 162 | "metadata": { 163 | "collapsed": false 164 | }, 165 | "outputs": [], 166 | "source": [ 167 | "rerun()" 168 | ] 169 | }, 170 | { 171 | "cell_type": "code", 172 | "execution_count": 7, 173 | "metadata": { 174 | "collapsed": false 175 | }, 176 | "outputs": [], 177 | "source": [ 178 | "def rerun():\n", 179 | " x_cor = [1, 2, 3, 4, 5, 6, 8]\n", 180 | " y_cor = [1, 2, 3, 4, 9, 5, 7]\n", 181 | " points = zip(x_cor, y_cor)\n", 182 | " \n", 183 | " # Create two paths, the second with two values swapped to simulate a 2-OPT\n", 184 | " # Local Search operation\n", 185 | " path4 = [0, 1, 2, 3, 4, 5, 6]\n", 186 | " path3 = [0, 2, 1, 3, 4, 5, 6]\n", 187 | " path2 = [0, 2, 1, 3, 6, 5, 4]\n", 188 | " path1 = [0, 2, 1, 3, 6, 4, 5]\n", 189 | " \n", 190 | " # Pack the paths into a list\n", 191 | " paths = [path1, path2, path3, path4]\n", 192 | " \n", 193 | " # Run the function\n", 194 | " plotTSP(paths, points, 4)" 195 | ] 196 | }, 197 | { 198 | "cell_type": "code", 199 | "execution_count": 8, 200 | "metadata": { 201 | "collapsed": false 202 | }, 203 | "outputs": [ 204 | { 205 | "ename": "IndexError", 206 | "evalue": "list index out of range", 207 | "output_type": "error", 208 | "traceback": [ 209 | "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", 210 | "\u001b[0;31mIndexError\u001b[0m Traceback (most recent call last)", 211 | "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mplotTSP\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m[\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;36m2\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m4\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", 212 | "\u001b[0;32m\u001b[0m in \u001b[0;36mplotTSP\u001b[0;34m(path, points, num_iters)\u001b[0m\n\u001b[1;32m 15\u001b[0m \u001b[0mx\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m[\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m;\u001b[0m \u001b[0my\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m[\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 16\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mi\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mpaths\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;36m0\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 17\u001b[0;31m \u001b[0mx\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mappend\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mpoints\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mi\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;36m0\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 18\u001b[0m \u001b[0my\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mappend\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mpoints\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mi\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 19\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n", 213 | "\u001b[0;31mIndexError\u001b[0m: list index out of range" 214 | ] 215 | } 216 | ], 217 | "source": [ 218 | "plotTSP([], [(1,2),(1,1)], 4)\n" 219 | ] 220 | }, 221 | { 222 | "cell_type": "code", 223 | "execution_count": null, 224 | "metadata": { 225 | "collapsed": false 226 | }, 227 | "outputs": [], 228 | "source": [ 229 | "plotTSP([], [(1,2),(1,1)], 1)" 230 | ] 231 | }, 232 | { 233 | "cell_type": "code", 234 | "execution_count": null, 235 | "metadata": { 236 | "collapsed": false 237 | }, 238 | "outputs": [], 239 | "source": [ 240 | "def rerun():\n", 241 | " x_cor = [1, 8, 4, 9, 2, 1, 8]\n", 242 | " y_cor = [1, 2, 3, 4, 9, 5, 7]\n", 243 | " points = []\n", 244 | " for i in range(0, len(x_cor)):\n", 245 | " points.append((x_cor[i], y_cor[i]))\n", 246 | " \n", 247 | " # Create two paths, teh second with two values swapped to simulate a 2-OPT\n", 248 | " # Local Search operation\n", 249 | " path4 = [0, 1, 2, 3, 4, 5, 6]\n", 250 | " path3 = [0, 2, 1, 3, 4, 5, 6]\n", 251 | " path2 = [0, 2, 1, 3, 6, 5, 4]\n", 252 | " path1 = [0, 2, 1, 3, 6, 4, 5]\n", 253 | " \n", 254 | " # Pack the paths into a list\n", 255 | " paths = [path1, path2, path3, path4]\n", 256 | " \n", 257 | " # Run the function\n", 258 | " plotTSP(paths, points, 4)\n", 259 | "\n", 260 | "plotTSP([], [(1,2),(1,1)], 1)" 261 | ] 262 | }, 263 | { 264 | "cell_type": "code", 265 | "execution_count": null, 266 | "metadata": { 267 | "collapsed": false 268 | }, 269 | "outputs": [], 270 | "source": [ 271 | "def rerun():\n", 272 | " x_cor = [1, 8, 4, 9, 2, 1, 8]\n", 273 | " y_cor = [1, 2, 3, 4, 9, 5, 7]\n", 274 | " points = []\n", 275 | " for i in range(0, len(x_cor)):\n", 276 | " points.append((x_cor[i], y_cor[i]))\n", 277 | " \n", 278 | " # Create two paths, teh second with two values swapped to simulate a 2-OPT\n", 279 | " # Local Search operation\n", 280 | " path4 = [0, 1, 2, 3, 4, 5, 6]\n", 281 | " path3 = [0, 2, 1, 3, 4, 5, 6]\n", 282 | " path2 = [0, 2, 1, 3, 6, 5, 4]\n", 283 | " path1 = [0, 2, 1, 3, 6, 4, 5]\n", 284 | " \n", 285 | " # Pack the paths into a list\n", 286 | " paths = [path1, path2, path3, path4]\n", 287 | " \n", 288 | " # Run the function\n", 289 | " plotTSP(paths, points, 4)" 290 | ] 291 | }, 292 | { 293 | "cell_type": "code", 294 | "execution_count": null, 295 | "metadata": { 296 | "collapsed": false 297 | }, 298 | "outputs": [], 299 | "source": [ 300 | "rerun().x_cor[0] = 20\n", 301 | "rerun()" 302 | ] 303 | }, 304 | { 305 | "cell_type": "code", 306 | "execution_count": null, 307 | "metadata": { 308 | "collapsed": false 309 | }, 310 | "outputs": [], 311 | "source": [] 312 | } 313 | ], 314 | "metadata": { 315 | "kernelspec": { 316 | "display_name": "Python 3", 317 | "language": "python", 318 | "name": "python3" 319 | }, 320 | "language_info": { 321 | "codemirror_mode": { 322 | "name": "ipython", 323 | "version": 3 324 | }, 325 | "file_extension": ".py", 326 | "mimetype": "text/x-python", 327 | "name": "python", 328 | "nbconvert_exporter": "python", 329 | "pygments_lexer": "ipython3", 330 | "version": "3.5.0" 331 | } 332 | }, 333 | "nbformat": 4, 334 | "nbformat_minor": 0 335 | } 336 | -------------------------------------------------------------------------------- /GraphSearch.cpp: -------------------------------------------------------------------------------- 1 | /* Nick Sweeting 2014/05/08 2 | Graph Creator 3 | MIT License 4 | g++ GraphSearch.cpp -o ./main && ./main 5 | 6 | A graph and breadth-first-search implemenation that can read vertices and edges from a file and print the adjacency table. 7 | */ 8 | 9 | #include 10 | #include // rand seed 11 | #include 12 | #include // vector of tokenized input 13 | #include // breadth-first search 14 | #include 15 | #include // file() 16 | #include 17 | using namespace std; 18 | 19 | #define LABEL first // we use a map to store vertex LABEL:VALUE, so for convenience I prefer to access them via vertex.LABEL & row.COLS instead of vertex.first and row.second 20 | #define VALUE second 21 | #define COLS second 22 | #define CONTAINS(obj, val) (obj.find(val) != obj.end()) // helper func because c++ has no 'in' keword, e.g. `val in obj` 23 | 24 | const string alphabet[36] = {"0","1","2","3","4","5","6","7","8","9","A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z"}; // for generating random graph vertex labels 25 | 26 | const string RED = "\033[1;31m"; 27 | const string YELLOW = "\033[1;33m"; 28 | const string ENDCOLOR = "\033[0m"; 29 | 30 | vector tokenize(string input, string delims=",; -") { 31 | vector tokens; 32 | size_t prev = 0, pos; 33 | // find next occurence of next delimiter after prev delimiter, then make a token using everything between those two positions 34 | while ((pos = input.find_first_of(delims, prev)) != string::npos) { 35 | if (pos > prev) 36 | tokens.push_back(input.substr(prev, pos-prev)); 37 | //tokens.push_back(input.substr(pos, 1)); // this adds the delimiter as a token as well, useful for catching operators as tokens (e.g. +-()*/^) 38 | prev = pos+1; 39 | } 40 | // catch trailing token after the last delimiter 41 | if (prev < input.length()) 42 | tokens.push_back(input.substr(prev, string::npos)); 43 | 44 | return tokens; 45 | } 46 | 47 | class Graph { 48 | private: 49 | typedef map list; // grid row 50 | typedef map matrix; // grid columns 51 | 52 | matrix adjTable; // init the adjacency table 53 | 54 | // get all verticies adjacent to a given vertex 55 | vector getAdjacent(string label) { 56 | vector adj; 57 | // iterate through that vertex's row in adjTable 58 | for (auto& vertex: adjTable[label]) { 59 | // push any vertecies (that arent the current one) where edge = 1 60 | if (*(vertex.VALUE) == 1 && vertex.LABEL != label) 61 | adj.push_back(vertex.LABEL); 62 | } 63 | return adj; 64 | } 65 | 66 | void updateEdge(string vertex1, string vertex2, int status) { 67 | // check to make sure both verticies exist 68 | if (!CONTAINS(adjTable, vertex1)) { 69 | cout << endl << RED << "[X] Vertex with label '" << vertex1 << "' does not exist." << ENDCOLOR << endl; 70 | return; 71 | } 72 | if (!CONTAINS(adjTable, vertex2)) { 73 | cout << endl << RED << "[X] Vertex with label '" << vertex2 << "' does not exist." << ENDCOLOR << endl; 74 | return; 75 | } 76 | // the adjTable is automatically consistent (A-B and B-A) 77 | *(adjTable[vertex1][vertex2]) = status; 78 | // *(adjTable[vertex2][vertex1]) = status; <- this is unecessary because both edges are pointers to the same int 79 | } 80 | 81 | public: 82 | Graph(int size=0) { 83 | // init a default graph with up to 36 verticies labeled A through Z 84 | for (int i=0; i < size && i < 37; i++) 85 | addVertex(alphabet[i]); 86 | } 87 | ~Graph() {} 88 | 89 | void addVertex(string label) { 90 | if (CONTAINS(adjTable, label)) { 91 | cout << endl << RED << "[X] Vertex with label '" << label << "' already exists." << ENDCOLOR << endl; 92 | return; 93 | } 94 | if (label == "" || label == " ") return; 95 | 96 | list new_adj_row; 97 | new_adj_row[label] = new int(0); // vertexes are always disconnected to themselves 98 | 99 | for (auto& vertex: adjTable) // seed the new adjacency table row with edges to all the other vertecies 100 | new_adj_row[vertex.LABEL] = new int(0); // new vertex starts disconnected to all the others 101 | 102 | adjTable[label] = new_adj_row; // add the new row to the adjTable 103 | 104 | for (auto& row: adjTable) // add a new column to all the other rows 105 | row.COLS[label] = new_adj_row[row.LABEL]; // re-use the pointers created above, so that both point to the same int 106 | } 107 | 108 | void removeVertex(string vertex) { 109 | if (!CONTAINS(adjTable, vertex)) { 110 | cout << endl << RED << "[X] Vertex with label '" << vertex << "' does not exist." << ENDCOLOR << endl; 111 | return; 112 | } 113 | adjTable.erase(vertex); // remove the vertex's row 114 | for (auto& row: adjTable) // remove the column from all the other rows 115 | row.COLS.erase(vertex); 116 | } 117 | 118 | void addEdge(string vertex1, string vertex2) { 119 | updateEdge(vertex1, vertex2, 1); 120 | } 121 | 122 | void removeEdge(string vertex1, string vertex2) { 123 | updateEdge(vertex1, vertex2, 0); 124 | } 125 | 126 | void breadthFirst(string start, string end) { 127 | if (!CONTAINS(adjTable, start)) { 128 | cout << endl << RED << "[X] Vertex with label '" << start << "' does not exist." << ENDCOLOR << endl; 129 | return; 130 | } 131 | if (!CONTAINS(adjTable, end)) { 132 | cout << endl << RED << "[X] Vertex with label '" << end << "' does not exist." << ENDCOLOR << endl; 133 | return; 134 | } 135 | if (start == end) { 136 | cout << YELLOW << "[√] Start and End are the same vertex! " << end << "-" << start << "" << ENDCOLOR << endl; 137 | return; 138 | } 139 | if (getAdjacent(start).empty() || getAdjacent(end).empty()) { 140 | cout << RED << "[X] Start or End is orphaned. No path exists." << ENDCOLOR << endl; 141 | return; 142 | } 143 | 144 | // begin with start, push all adjacent verticies to the queue, pop top of queue and repeat until end is found 145 | // the path is recorded using the tofrom array, which simply records how we got to each vertex 146 | // to get the path, start at tofrom[end], then call tofrom[tofrom[end]] to see the one before it and so on 147 | queue q; 148 | map tofrom; 149 | tofrom[start] = start; // set the beginning of the tofrom beadcrumb trail to the start vertex 150 | q.push(start); 151 | string root; 152 | while (q.size() > 0) { 153 | root = q.front(); q.pop(); 154 | for (string& next: getAdjacent(root)) { 155 | // if the next vertex has not already been visited, add it to the search queue 156 | if (!CONTAINS(tofrom, next)) { 157 | tofrom[next] = root; 158 | q.push(next); 159 | } 160 | // if the next vertex is the end vertex, stop searching 161 | if (next == end) { 162 | cout << endl << YELLOW << "[√] Found path! " << end; 163 | // follow the breadcrumbs back to the start to get the path 164 | string last = end; 165 | while (tofrom[last] != start) { 166 | last = tofrom[last]; 167 | cout << "-" << last; 168 | } 169 | cout << "-" << start << ENDCOLOR << endl << endl; 170 | return; 171 | } 172 | } 173 | } 174 | cout << RED << "[X] Path not found." << ENDCOLOR << endl; 175 | } 176 | 177 | void dijkstra(string vertex1, string vertex2) { 178 | // left as an excersize to the reader 179 | breadthFirst(vertex1, vertex2); 180 | } 181 | 182 | void printAdjTable() { 183 | cout << endl << " "; 184 | // print top labels 185 | for (auto& row: adjTable) 186 | cout << "|" << row.LABEL; 187 | cout << endl; 188 | // print each row 189 | for (auto& row: adjTable) { 190 | cout << row.LABEL << "|"; 191 | for (auto& col: row.COLS) 192 | cout << (*(col.VALUE) ? RED : YELLOW) << *(col.VALUE) << " " << ENDCOLOR; 193 | cout << endl; 194 | } 195 | cout << endl; 196 | } 197 | 198 | int size() { 199 | return adjTable.size(); 200 | } 201 | }; 202 | 203 | int main() { 204 | auto* graph = new Graph(); 205 | cout << "Will generate and map a graph. Points can be labeled and referenced using strings.\n[1] add verticies\n[2] remove verticies\n[3] add edges\n[4] remove edges\n[5] breadth-first shortest path\n[6] dijkstra's shortest path\n---\n[7] generate demo graph\n[8] read graph from file\n[0] quit\n\n"; 206 | int n; 207 | while (1) { 208 | graph->printAdjTable(); 209 | cout << "[#]:"; 210 | cin >> n; 211 | if (n == 1) { 212 | cout << "[i] Verticies to add\n e.g A,B,C,D,E :"; 213 | string intext; 214 | cin >> intext; cin.clear(); 215 | // tokenizing input allows them to enter multiple verticies on a single line 216 | vector tokens = tokenize(intext); 217 | for (string& vertex: tokens) 218 | graph->addVertex(vertex); 219 | } 220 | else if (n == 2) { 221 | cout << "[i] Verticies to remove\n e.g. A,C,D :"; 222 | string intext; 223 | cin >> intext; cin.clear(); 224 | vector tokens = tokenize(intext); 225 | for (string& vertex: tokens) 226 | graph->removeVertex(vertex); 227 | } 228 | else if (n == 3) { 229 | cout << "[i] Verticies to link\n e.g. A-E :"; 230 | string intext; 231 | cin >> intext; cin.clear(); 232 | vector tokens = tokenize(intext); 233 | if (tokens.size() == 2) 234 | graph->addEdge(tokens[0], tokens[1]); 235 | else 236 | cout << RED << "[X] Only two verticies can be linked." << ENDCOLOR << endl; 237 | } 238 | else if (n == 4) { 239 | cout << "[i] Verticies to unlink\n e.g A-B :"; 240 | string intext; 241 | cin >> intext; cin.clear(); 242 | vector tokens = tokenize(intext); 243 | if (tokens.size() == 2) 244 | graph->removeEdge(tokens[0], tokens[1]); 245 | else 246 | cout << RED << "[X] Only two verticies can be unlinked." << ENDCOLOR << endl; 247 | } 248 | else if (n == 5) { 249 | // breadth first path finding search 250 | cout << "[i] Path starting ending verticies\n e.g. A-Z :"; 251 | string intext; 252 | cin >> intext; cin.clear(); 253 | vector tokens = tokenize(intext); 254 | if (tokens.size() == 2) 255 | graph->breadthFirst(tokens[0], tokens[1]); 256 | else 257 | cout << RED << "[X] You can only find the path between two verticies." << ENDCOLOR << endl; 258 | } 259 | else if (n == 6) { 260 | // fake dijkstra's seach (it just uses breadth-first) 261 | cout << "[i] Path starting ending verticies\n e.g. A-Z :"; 262 | string intext; 263 | cin >> intext; cin.clear(); 264 | vector tokens = tokenize(intext); 265 | if (tokens.size() == 2) 266 | graph->dijkstra(tokens[0], tokens[1]); 267 | else 268 | cout << RED << "[X] You can only find the path between two verticies." << ENDCOLOR << endl; 269 | } 270 | else if (n == 7) { 271 | // generate a random demo board 272 | cout << "[i] Number of verticies to generate\n(enter 0 to leave graph unchanged):"; 273 | int verticies; 274 | cin >> verticies; cin.clear(); 275 | if (verticies < 37 && verticies > 0) 276 | *graph = Graph(verticies); 277 | else if (verticies > 37) 278 | cout << RED << "[X] Demo graph has a max of 36 vertices (because it uses the alphabet & numbers as labels)" << ENDCOLOR << endl; 279 | 280 | cout << "[i] Number of edges to randomly create\n(you need about 40 to reliably get a path from A-Z):"; 281 | int edges; 282 | cin >> edges; cin.clear(); 283 | verticies = graph->size(); 284 | srand(time(NULL)); // init random number seed from time 285 | if (edges <= verticies * verticies) { 286 | for (int i=0; iaddEdge(alphabet[rand() % verticies], alphabet[rand() % verticies]); 288 | } 289 | else 290 | cout << RED << "[X] Too many edges to fit on this graph." << ENDCOLOR << endl; 291 | } 292 | else if (n == 8) { 293 | // load board from a file 294 | string infile; 295 | cout << "[*] File must have a list of verticies separated by commas, a newline, then a list of comma separated vertex1-vertex2 edges." << endl; 296 | cout << "[i] Filename:"; 297 | cin >> infile; 298 | 299 | // set up file reading 300 | std::ifstream file(infile, std::ios::binary); 301 | std::streambuf* raw_buffer = file.rdbuf(); 302 | char* block = new char[65536]; // max file size 303 | raw_buffer->sgetn(block, 65536); 304 | string intext = ""; 305 | 306 | // read in verticies "A,B,C,D,E,F,G" 307 | int i=0; 308 | for (; i<65536; i++) { 309 | if (block[i] == '\n') break; 310 | intext += block[i]; 311 | } 312 | 313 | // add verticies 314 | vector tokens = tokenize(intext); 315 | if (tokens.empty()) 316 | cout << RED << "[X] No properly formatted verticies found (A,B,C,...) in file" << ENDCOLOR << endl; 317 | else { 318 | for (string& vertex: tokens) 319 | graph->addVertex(vertex); 320 | } 321 | 322 | // read in edges "A-B,B-C,C-D,D-F,F-E,C-G" 323 | intext = ""; i++; // re-using i so that we start where we left off (skipping the newline of course) 324 | for (; i<65536; i++) { 325 | if (block[i] == '\n') break; 326 | intext += block[i]; 327 | } 328 | 329 | // add edges 330 | vector links = tokenize(intext, ","); 331 | if (links.empty()) 332 | cout << RED << "[X] No properly formatted edges found (A-B,A-C,C-B,...) in file" << ENDCOLOR << endl; 333 | else { 334 | for (string& link_str: tokens) { 335 | vector link = tokenize(link_str, "-"); 336 | if (link.size() != 2) 337 | cout << RED << "[X] Incomplete link found: " << link[0] << "-" << endl; 338 | else 339 | graph->addEdge(link[0], link[1]); 340 | } 341 | } 342 | 343 | delete[] block; 344 | } 345 | else if (n == 0) return 0; 346 | else cout << RED << "[X] Enter the number of the command you're trying to run." << ENDCOLOR << endl; 347 | } 348 | } 349 | -------------------------------------------------------------------------------- /HashTable.cpp: -------------------------------------------------------------------------------- 1 | /* Nick Sweeting 2014/05/12 2 | Hash Map 3 | MIT License 4 | g++ HashTable.cpp -o main; and ./main 5 | 6 | A Hash-Table implementation that is used to store a list of students and their GPAs. 7 | TODO: fix SIGSEGV 8 | */ 9 | 10 | #include 11 | #include 12 | #include // rand seed 13 | #include // duh 14 | #include // vector of tokenized input 15 | #include // breadth-first search 16 | #include // cout 17 | #include // file() 18 | using namespace std; 19 | const string alphabet[26] = {"A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z"}; // for generating random words 20 | 21 | static const int magic = 0xF423F; 22 | 23 | vector tokenize(string input, string delims=",; -") { 24 | vector tokens; 25 | size_t prev = 0, pos; 26 | // find next occurence of next delimiter after prev delimiter, then make a token using everything between those two positions 27 | while ((pos = input.find_first_of(delims, prev)) != string::npos) { 28 | if (pos > prev) 29 | tokens.push_back(input.substr(prev, pos-prev)); 30 | //tokens.push_back(input.substr(pos, 1)); // this adds the delimiter as a token as well, useful for catching operators as tokens (e.g. +-()*/^) 31 | prev = pos+1; 32 | } 33 | // catch trailing token after the last delimiter 34 | if (prev < input.length()) 35 | tokens.push_back(input.substr(prev, string::npos)); 36 | 37 | return tokens; 38 | } 39 | 40 | class StudentHashTable { 41 | private: 42 | struct Student { 43 | char firstName[15]; 44 | char lastName[15]; 45 | double GPA; 46 | }; 47 | 48 | static const int magic = 0xF423F; 49 | Student* hashtable[magic]; 50 | int count; 51 | 52 | int hash(int key) { 53 | //hashtable_hash_fnv(key, magic); 54 | return key; 55 | } 56 | 57 | int hashtable_hash_fnv(void *key, int size){ 58 | unsigned int hval = 0x811c9dc5; 59 | unsigned int hval2 = magic; 60 | unsigned char *bp = (unsigned char *)key; 61 | unsigned char *be = bp + size; 62 | 63 | while (bp < be) { 64 | hval += (hval << 1) + (hval << 4) + (hval << 7) + (hval << 8) + (hval << 24); 65 | hval ^= (unsigned int)*bp++; 66 | } 67 | 68 | return (int)hval; 69 | } 70 | 71 | public: 72 | StudentHashTable() { 73 | count = 0; 74 | }; 75 | 76 | ~StudentHashTable() { 77 | empty(); 78 | }; 79 | 80 | Student* operator[](const int key) throw (const char *) { 81 | if (*(hashtable[hash(key)]->firstName)) 82 | return hashtable[hash(key)]; 83 | else 84 | return NULL; 85 | } 86 | 87 | void add(int key) { 88 | hashtable[key] = new Student; 89 | count++; 90 | } 91 | 92 | void remove(int key) { 93 | delete hashtable[hash(key)]; 94 | count--; 95 | } 96 | 97 | void clear() { 98 | for (int i=0; ifirstName)) 100 | remove(i); 101 | } 102 | if (count != 0) 103 | cout << "WARNING: INCONSISTENCY DETECTED. count off by " << count << endl; 104 | } 105 | 106 | void empty() { 107 | clear(); 108 | } 109 | 110 | int size() { 111 | return count; 112 | } 113 | 114 | void print() { 115 | for (int i=0; ifirstName)) 117 | cout << i << ": " << (*hashtable[i]).firstName << " " << (*hashtable[i]).lastName << " - " << (*hashtable[i]).GPA << endl; 118 | } 119 | } 120 | }; 121 | 122 | 123 | int main(int argc, char **argv) { 124 | StudentHashTable students; 125 | students.print(); 126 | students.add(458209); 127 | students.print(); 128 | students.add(458211); 129 | students.print(); 130 | students.remove(458209); 131 | students.print(); 132 | } 133 | -------------------------------------------------------------------------------- /Heap.cpp: -------------------------------------------------------------------------------- 1 | /* Nick Sweeting 2014/02/13 2 | Heap 3 | MIT License 4 | g++ Heap.cpp -o main; and ./main 5 | 6 | A heap implemented as a flat array using index math to access elements. 7 | */ 8 | 9 | #include 10 | #include // isdigit (parsing for tokens/ops) 11 | #include // duh 12 | #include // vector of tokenized input 13 | #include // cout 14 | #include // istringstream, setw 15 | #include // pow, sqrt 16 | using namespace std; 17 | 18 | const string delims = ",; "; 19 | 20 | int stoint(string input) { 21 | int i = 0; 22 | istringstream(string(input)) >> i; 23 | return i; 24 | } 25 | 26 | string itostring(int i) { 27 | std::stringstream out; 28 | out << i; 29 | return out.str(); 30 | } 31 | 32 | vector tokenize(string input) { 33 | vector tokens; 34 | size_t prev = 0, pos; 35 | // find next occurence of delimiter after prev delimiter, then append everything between those two positions 36 | while ((pos = input.find_first_of(delims, prev)) != string::npos) { 37 | if (pos > prev) 38 | tokens.push_back(stoint(input.substr(prev, pos-prev))); 39 | //tokens.push_back(stoint(input.substr(pos, 1))); // this adds the delimiter as a token as well, useful for catching operators as tokens (e.g. +-()*/^) 40 | prev = pos+1; 41 | } 42 | // catch trailing info after the last delimiter 43 | if (prev < input.length()) 44 | tokens.push_back(stoint(input.substr(prev, string::npos))); 45 | 46 | return tokens; 47 | } 48 | 49 | // Heap implemented with a flat array and index math (implicit data structure) 50 | class FHeap { 51 | // Math for flat heap indexes: 52 | // Left = (index*2)+1 53 | // Right = (index+1)*2 54 | // Parent = floor((index-1)/2) 55 | // Depth = floor(√(index)+0.5) (0 indexed depth where the root is at depth=0, next level down is depth=1, ...) 56 | 57 | private: 58 | int heap[80]; 59 | int heapsize; 60 | 61 | void sortbyparent(int index) { 62 | // recursive function that checks if(parent>current) {swap parent with current; then recurse with parent} 63 | if (index !=0) { 64 | int node = heap[index]; 65 | int parent = floor((index-1)/2); 66 | //cout << "parent: " << heap[parent] << " node: " << node; 67 | if (node > heap[parent]) { 68 | //cout << " SWAPPING"; 69 | heap[index] = heap[parent]; 70 | heap[parent] = node; 71 | } 72 | //cout << endl; 73 | sortbyparent(parent); 74 | } 75 | } 76 | 77 | void sortbychildren(int index) { 78 | // recursive function that checks if(left or right < current) {swap left or right with current; then recurse with left or right} 79 | int node = heap[index]; 80 | int left = (index*2)+1; 81 | int right = (index+1)*2; 82 | //cout << "parent: " << heap[parent] << " node: " << node; 83 | if (node < heap[left] || node < heap[right]) { 84 | if (heap[left] > heap[right]) { 85 | heap[index] = heap[left]; 86 | heap[left] = node; 87 | sortbychildren(left); 88 | } 89 | else { 90 | heap[index] = heap[right]; 91 | heap[right] = node; 92 | sortbychildren(right); 93 | } 94 | } 95 | } 96 | 97 | string offset(int idx) { 98 | string spaces = ""; 99 | int offset = int(floor(sqrt(heapsize-1)+0.5))-int(floor(sqrt(idx)+0.5)); 100 | for (int i=0;i> toaddtoheap; cin.clear(); 188 | 189 | vector tokens = tokenize(toaddtoheap); 190 | if (tokens.size() == 0) return 1; 191 | for (int i=0; i> toremovefromheap; cin.clear(); 200 | 201 | for (int i=0; i 12 | #include // isdigit 13 | #include 14 | #include // stack of tokens 15 | #include // vector of tokenized input 16 | #include // cout 17 | #include // istringstream 18 | #include // pow 19 | using namespace std; 20 | 21 | const string ops = "+-/*()^"; 22 | const string nums = "0123456789"; 23 | 24 | // binary tree node to hold tokens and their arguments 25 | struct node { 26 | string value; 27 | node *left; 28 | node *right; 29 | 30 | node(string val) { 31 | value = val; 32 | left = 0; 33 | right = 0; 34 | } 35 | }; 36 | 37 | // separate string "2+45(3-45*(2+3))" into tokens ["2", "+", "45", "*", "(", ...] and remove extra ()'s 38 | vector tokenize(string input) { 39 | // input = (2+45-34)+156-(2+5) 40 | // returns [(] [2] [+] [45] [-] [34] [)] [+] [156] [-] [(] [2] [+] [5] [)] 41 | vector tokens; 42 | 43 | int opens = 0; 44 | int closs = 0; 45 | for (int i=0; i prev) 59 | tokens.push_back(input.substr(prev, pos-prev)); 60 | tokens.push_back(input.substr(pos, 1)); 61 | prev = pos+1; 62 | } 63 | // if theres trailing info after the last delimiter 64 | if (prev < input.length()) 65 | tokens.push_back(input.substr(prev, string::npos)); 66 | 67 | tokens.push_back(")"); 68 | return tokens; 69 | } 70 | 71 | // look for y chars in x, if found return true 72 | bool is(string x, string y) { 73 | if (x.find_first_of(y) != string::npos) 74 | return true; 75 | else 76 | return false; 77 | } 78 | 79 | string prefix(node *token) { 80 | if (token->right && token->left) 81 | return "(" + token->value + " " + prefix(token->left) + " " + prefix(token->right) + ")"; 82 | else 83 | return token->value; 84 | } 85 | 86 | string postfix(node *token) { 87 | if (token->right && token->left) 88 | return "(" + postfix(token->left) + " " + postfix(token->right) + " " + token->value + ")"; 89 | else 90 | return token->value; 91 | } 92 | 93 | int stoint(string input) { 94 | int i = 0; 95 | istringstream(string(input)) >> i; 96 | return i; 97 | } 98 | 99 | int evaluate(node *token) { 100 | if (token->right && token->left) { 101 | if (token->value == "+") 102 | return (evaluate(token->left))+(evaluate(token->right)); 103 | else if (token->value == "-") 104 | return (evaluate(token->left))-(evaluate(token->right)); 105 | else if (token->value == "*") 106 | return (evaluate(token->left))*(evaluate(token->right)); 107 | else if (token->value == "/") 108 | return (evaluate(token->left))/(evaluate(token->right)); 109 | else if (token->value == "^") 110 | return (evaluate(token->left))*(evaluate(token->right)); 111 | } 112 | return stoint(token->value); 113 | } 114 | 115 | int main () { 116 | string infix, prepost; 117 | cout << "[i] Supported operators: " << ops << " each operator may have 2 and ONLY 2 arguments. Do not add extra ()s." << endl; 118 | cout << "[1] Input an expression in infix notation: " << endl; 119 | cin >> infix; 120 | cin.clear(); 121 | 122 | vector tokens = tokenize(infix); 123 | if (!(tokens.size())) 124 | return 1; 125 | 126 | stack stk; 127 | 128 | for (int i=0; ivalue == "(") 134 | stk.push(token); 135 | else if (token->value == ")"){ 136 | node *cur = stk.top(); stk.pop(); 137 | node *top = stk.top(); stk.pop(); 138 | while (top->value != "(") { 139 | top->right = cur; 140 | cur = top; 141 | top = stk.top(); stk.pop(); 142 | stk.push(cur); 143 | } 144 | } 145 | else if (is(token->value, nums)) { 146 | if (is(stk.top()->value, ops)) { 147 | node *op = stk.top(); stk.pop(); 148 | op->right = token; 149 | stk.push(op); 150 | } 151 | stk.push(token); 152 | } 153 | else if (!is(token->value, "()") && is(token->value, ops)) { 154 | // If token is an operator 155 | // top=pop, make top left child of node, push node 156 | node *left = stk.top(); stk.pop(); 157 | token->left = left; 158 | stk.push(token); 159 | } 160 | else { 161 | cout << "ERROR, weird token value: " << token->value << endl; 162 | } 163 | } 164 | 165 | cout << "[2] What format do you want your output? (pre/post):"; 166 | cin >> prepost; 167 | cin.clear(); 168 | 169 | if (prepost == "pre" || prepost == "p") { 170 | node *r = stk.top(); 171 | cout << prefix(stk.top()) << " = " << evaluate(stk.top()) << endl; 172 | } 173 | else if (prepost == "post" || prepost == "rpn") { 174 | node *r = stk.top(); 175 | cout << postfix(stk.top()) << " = " << evaluate(stk.top()) << endl; 176 | } 177 | else { 178 | cout << "[X] Invalid choice, please specify 'pre' or 'post' or 'rpn'." << endl; 179 | return 1; 180 | } 181 | 182 | return 0; 183 | } 184 | 185 | 186 | 187 | // INFIX -> POSTFIX 188 | 189 | // For each token { 190 | // If (token is a number) { 191 | // Add number to the output queue 192 | // } 193 | // 194 | // If (token is an operator eg +,-,*...) { 195 | // While (stk not empty AND stk top element is an operator) { 196 | // If ((token = left associative AND precedence <= stk top element) OR (token = right associative AND precedence < stk top element)) { 197 | // Pop stk onto the output queue. 198 | // Exit while loop. 199 | // } 200 | // } 201 | // Push token onto stk 202 | // } 203 | // 204 | // If (token is left bracket '(') { 205 | // Push token on to stk 206 | // } 207 | // 208 | // If (token is right bracket ')') { 209 | // While (stk not empty AND stk top element not a left bracket) { 210 | // Pop the stk onto output queue 211 | // } 212 | // Pop the stk 213 | // } 214 | // } 215 | // 216 | // While (stk not empty) { 217 | // Pop stk onto output queue 218 | // } 219 | 220 | // EVAL RPN 221 | // For each token { 222 | // If (token is a number) { 223 | // Push value onto stk 224 | // } 225 | 226 | // If (token is an operator) { 227 | // Pop 2 top values from the stk 228 | // Evaluate operator using popped values as args 229 | // Push result onto stk 230 | // } 231 | // } 232 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 Nick Sweeting 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | If the Author of the Software (the "Author") needs a place to crash and you have 16 | a sofa available, you should maybe give the Author a break and let him sleep on your couch. 17 | 18 | If you are caught in a dire situation wherein you only have enough time to save 19 | one person out of a group, and the Author is a member of that group, you must save the Author. 20 | 21 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 22 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 23 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 24 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 25 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 26 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 27 | SOFTWARE. 28 | -------------------------------------------------------------------------------- /LinkedList.cpp: -------------------------------------------------------------------------------- 1 | /* Nick Sweeting 2013/10/08 2 | Student List (OOP) 3 | MIT Licence 4 | 5 | A Linked List implemenation that is used to store a list of students. 6 | */ 7 | 8 | #include 9 | #include 10 | #include // for setprecision() 11 | #include 12 | using namespace std; 13 | 14 | // Linked List Implementation 15 | template class LList { 16 | private: 17 | struct node { 18 | Type value; 19 | node *next; 20 | node *prev; 21 | }; 22 | 23 | node *root; // Fixed start of list 24 | node *tail; // Fixed end of list 25 | node *conductor; // points to each node while looping over the whole list 26 | node *next_item; // points to the node after conductor (used when adding/removing) 27 | node *prev_item; // points to the node before conductor (used when adding/removing) 28 | int list_size; // number of nodes in the list, always kept up-to-date 29 | 30 | public: 31 | LList() {list_size = 0;} 32 | ~LList() {}; 33 | 34 | Type& operator[](const int location) throw (const char *) { 35 | // negative indecies work like they do in python 36 | // [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9] == 37 | // [-10, -9, -8, -7, -6, -5, -4, -3, -2, -1] 38 | if (location > list_size-1 || location < 0-list_size) throw "Invalid array access, index > array_size"; 39 | 40 | // SPECIAL CASE: fetch root 41 | if (location == 0 || location == -1-list_size) return root->value; 42 | // SPECIAL CASE: fetch tail 43 | else if (location == -1 || location == list_size-1) return tail->value; 44 | // fetch using positive index 45 | else if (location > 0) { 46 | conductor = root; 47 | int index = 0; 48 | while (conductor->next != 0) { 49 | conductor = conductor->next; 50 | index++; 51 | if (index == location) return conductor->value; 52 | } 53 | } 54 | // fetch using negative index 55 | else if (location < 0) { 56 | conductor = tail; 57 | int index = -1; 58 | while (conductor->prev != 0) { 59 | conductor = conductor->prev; 60 | index--; 61 | if (index == location) return conductor->value; 62 | } 63 | } 64 | throw "Error in code: node contains invalid value (happens when node == 0)."; 65 | } 66 | 67 | void add(int location, Type item) throw (const char *) { 68 | // SPECIAL CASE: change of root 69 | if (location == 0) { 70 | if (list_size == 0) { 71 | root = new node; 72 | tail = root; 73 | } 74 | else { 75 | root->prev = new node; 76 | root->prev->next = root; 77 | root = root->prev; 78 | } 79 | root->value = item; 80 | root->prev = 0; 81 | list_size++; 82 | } 83 | // SPECIAL CASE: change of tail 84 | else if (location == -1 || location == list_size) { 85 | if (list_size == 0) { 86 | root = new node; 87 | tail = root; 88 | } 89 | else { 90 | tail->next = new node; 91 | tail->next->prev = tail; 92 | tail = tail->next; 93 | } 94 | tail->value = item; 95 | tail->next = 0; 96 | list_size++; 97 | } 98 | // POSITIVE INDEX 99 | else if (location > 0 && location < list_size) { 100 | // ins x at idx 2 101 | // [ 0, 1, 2] --> [ 0, 1, 2, 3] 102 | // [ a, b, c] --> [ a, b, x, c] 103 | int index = 0; 104 | conductor = root; 105 | // stops one before the target index (in order to fetch mylist[inx]->prev) 106 | while (index < list_size+1) { 107 | if (index+1 == location) { 108 | next_item = conductor->next; 109 | prev_item = conductor; 110 | 111 | conductor->next = new node; 112 | conductor = conductor->next; 113 | conductor->next = next_item; 114 | conductor->prev = prev_item; 115 | conductor->prev->next = conductor; 116 | conductor->next->prev = conductor; 117 | conductor->value = item; 118 | list_size++; 119 | break; 120 | } 121 | conductor = conductor->next; 122 | index++; 123 | } 124 | } 125 | // NEGATIVE INDEX 126 | else if (location < 0 && location > -1-list_size) { 127 | int index = -1; 128 | conductor = tail; 129 | // ins x at idx -2 130 | // [ 0, 1, 2] --> [ 0, 1, 2, 3] 131 | // [-3, -2, -1] --> [-4, -3, -2, -1] 132 | // [ a, b, c] --> [ a, b, x, c] 133 | // stops one before the target index (in order to fetch mylist[inx]->next) 134 | while (index > -2-list_size) { 135 | if (index-1 == location) { 136 | prev_item = conductor->prev; 137 | next_item = conductor; 138 | 139 | conductor->prev = new node; 140 | conductor = conductor->prev; 141 | conductor->prev = prev_item; 142 | conductor->next = next_item; 143 | conductor->prev->next = conductor; 144 | conductor->next->prev = conductor; 145 | conductor->value = item; 146 | list_size++; 147 | 148 | break; 149 | } 150 | conductor = conductor->prev; 151 | index--; 152 | } 153 | } 154 | else throw "Invalid access, index > array_size."; 155 | } 156 | 157 | void add(Type item) { 158 | // add appends to the end of the list by default 159 | // to add to the head, do add(0, item) 160 | add(-1, item); 161 | } 162 | 163 | void remove(int location) throw (const char *) { 164 | // SPECIAL CASE: change of root 165 | if (location == 0 || location == -1-list_size) { 166 | if (list_size > 0) { 167 | node *nexttmp = root->next; 168 | delete root; 169 | root = nexttmp; 170 | list_size--; 171 | if (list_size > 0) root->prev = 0; 172 | } 173 | if (list_size < 2) { 174 | tail = root; 175 | } 176 | } 177 | // SPECIAL CASE: change of tail 178 | else if (location == -1 || location == list_size-1) { 179 | node *prevtmp = tail->prev; 180 | delete tail; 181 | tail = prevtmp; 182 | list_size--; 183 | if (list_size > 0) tail->next = 0; 184 | else if (list_size <= 1) root = tail; 185 | } 186 | // remove item at given positive index 187 | else if (location > 0 && location < list_size) { 188 | int index = 0; 189 | conductor = root; // The conductor starts at head and loops forward following node->next 190 | while (index < list_size) { 191 | if (index+1 == location) { 192 | if (index+2 < list_size) conductor->next->next->prev = conductor; 193 | node *tmpnext = conductor->next->next; 194 | delete conductor->next; 195 | conductor->next = tmpnext; 196 | list_size--; 197 | if (index == list_size-1) tail = conductor; 198 | break; 199 | } 200 | conductor = conductor->next; 201 | index++; 202 | } 203 | } 204 | // remove item at given negative index 205 | else if (location < 0 && location > -1-list_size) { 206 | int index = -1; 207 | conductor = tail; // The conductor starts at tail and loops back following node->prev 208 | while (index > -1-list_size) { 209 | if (index-1 == location) { 210 | if (index-1 > 0-list_size) conductor->prev->prev->next = conductor; 211 | node *tmpprev = conductor->prev->prev; 212 | delete conductor->prev; 213 | conductor->prev = tmpprev; 214 | list_size--; 215 | if (index == 0-list_size) root = conductor; 216 | break; 217 | } 218 | conductor = conductor->prev; 219 | index--; 220 | } 221 | } 222 | else throw "Invalid array access, index > array_size"; 223 | } 224 | 225 | int find(Type item) { 226 | int index = 0; 227 | conductor = root; // start at head and loop through node->next towards tail 228 | while (conductor != 0) { 229 | if (conductor->value == item) return index; 230 | conductor = conductor->next; 231 | index++; 232 | } 233 | return -1; 234 | } 235 | 236 | int reverse_find(Type item) { 237 | int index = -1; 238 | conductor = tail; // start at tail and loop through node->prev towards head 239 | while (conductor != 0) { 240 | if (conductor->value == item) return index; 241 | conductor = conductor->prev; 242 | index--; 243 | } 244 | return 1; 245 | } 246 | 247 | int size() {return list_size;} 248 | }; 249 | 250 | struct Student { 251 | string firstName; 252 | string lastName; 253 | int studentID; 254 | double GPA; 255 | }; 256 | 257 | void printStudents(LList students) { 258 | for (int i=0;i *students) { 264 | Student newStudent; 265 | 266 | cout << "First Name: "; 267 | cin >> newStudent.firstName; 268 | cout << "Last Name: "; 269 | cin >> newStudent.lastName; 270 | 271 | bool IDIsValid = false; 272 | while (!IDIsValid) { 273 | cout << "ID: "; 274 | cin >> newStudent.studentID; 275 | IDIsValid = true; 276 | 277 | for (int a=0; a < students->size(); a++) { 278 | if ((*students)[a].studentID == newStudent.studentID) { 279 | cout << "Student ID must be unique." << endl; 280 | IDIsValid = false; 281 | } 282 | } 283 | } 284 | 285 | cout << "GPA: "; 286 | cin >> newStudent.GPA; 287 | 288 | bool added = false; 289 | if (students->size() > 0) { 290 | for (int a=0; a<(students->size()); a++) { 291 | if (newStudent.studentID < (*students)[a].studentID) { 292 | students->add(a, newStudent); // inserts it at that position, shifting old value right (to [a+1]) 293 | added = true; 294 | break; 295 | } 296 | } 297 | } 298 | if (!added) students->add(newStudent); 299 | } 300 | 301 | void delStudent(LList *students) { 302 | int studentIDtoDel; 303 | cout << "ID of student to delete: "; 304 | cin >> studentIDtoDel; 305 | 306 | for (int a=0; a < students->size(); a++) { 307 | if ((*students)[a].studentID == studentIDtoDel) { 308 | students->remove(a); 309 | break; 310 | } 311 | } 312 | } 313 | 314 | int main() { 315 | LList students; 316 | string input; 317 | cout << "Commands: [add, delete, print, average, quit]" << endl; 318 | 319 | while (true) { 320 | cout << ">"; 321 | cin >> input; 322 | 323 | if (input == "ADD" || input == "a" || input == "add") addStudent(&students); 324 | else if (input == "PRINT" || input == "p" || input == "print") printStudents(students); 325 | else if (input == "DELETE" || input == "d" || input == "delete") delStudent(&students); 326 | else if (input == "AVERAGE" || input == "avg" || input == "average") { 327 | double average = 0; 328 | for (int a=0; a < students.size(); a++) average += students[a].GPA; 329 | average = average/students.size(); 330 | cout << "Average GPA of all students: " << setprecision(3) << average << endl; 331 | } 332 | else if (input == "QUIT" || input == "q" || input == "quit") return 0; 333 | } 334 | } 335 | 336 | -------------------------------------------------------------------------------- /Palindrome.cpp: -------------------------------------------------------------------------------- 1 | /* Nick Sweeting 2013/09/09 2 | Palindrome Detector C++ 3 | MIT License 4 | g++ Palindrome.cpp -o main; and ./main 5 | 6 | Takes input and removes puctuation and spaces, then checks to see if it's a palindrome or not. 7 | */ 8 | 9 | #include 10 | #include 11 | using namespace std; 12 | 13 | // returns true if input character q is puctuation, else false 14 | bool ispunctuation(char q) { 15 | char punct[31] = ".!-_? <>,$#@=+*&^$!;:'()[]{}|`"; 16 | int p; 17 | for (p=0;p<30;p++) if (q == punct[p]) return true; 18 | return false; 19 | } 20 | 21 | // returns int: # of characters in the input array 22 | int findlength(char input[]) { 23 | int i, length=0; 24 | for (i=0;i<80;i++) { 25 | if (input[i] != '\0') length++; 26 | else break; 27 | } 28 | //cout << "Length: " << length << endl; // uncomment cout lines like this one to get more verbose output 29 | return length; 30 | } 31 | 32 | // returns int: # of characters in the same position forwards & backwards 33 | int findequalcount(char input[], int length) { 34 | int equalcount = 0; 35 | int z; 36 | for (z=0;z 10 | #include 11 | #include 12 | 13 | using namespace std; 14 | 15 | const char punct[26] = " .!-_?<>,*&^$!;:'()[]{}|`"; 16 | 17 | bool ispunct(char q) { 18 | for (int p=0;p<25;p++) { 19 | if (q == punct[p]) return true; 20 | } 21 | return false; 22 | } 23 | 24 | int main() { 25 | if (ispunct(' ')) 26 | cout << "its punct" << endl; 27 | else 28 | cout << "not punct." << endl; 29 | } 30 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Homework Submissions for CS 163 (C++ & Data Structures) 2 | 3 | ### Usage: 4 | 5 | You can compile and run each assignment with the following command: 6 | 7 | ```bash 8 | /usr/bin/g++ AssignmentName.cpp -o main && ./main 9 | ``` 10 | 11 | ### Info: 12 | 13 | These are my homework submissions for my senior year compsci class (CS163) at Sunset High School. 14 | 15 | Included in the Experiments folder are some of my personal experiments into more advanced C++ techniques, such as 16 | runtime arbitrary assembly execution, and travelling salesman solver algorithms. 17 | 18 | I hate doing things the standard way where each assignment is split into lots of tiny header and source files, doing that is 19 | freaking ridiculous if the whole assignment is <300 lines. F the system, forget separate header files, put it all in one nicely commented file 20 | and you save everybody time. 21 | 22 | --------------------------------------------------------- 23 | These assignments were compiled and tested using: 24 | `Apple LLVM version 7.0.0 (clang-700.0.72)` 25 | `Target: x86_64-apple-darwin15.0.0` 26 | 27 | Please don't copy this code to cheat on your homework without at least reading it, and interpreting the logic to be your own. It's hard to refactor a program without understanding how it works, and you will gain a lot by spending the extra 10 minutes to understand it. 28 | 29 | MIT License - Nick Sweeting - 2015 30 | -------------------------------------------------------------------------------- /RedBlack.cpp: -------------------------------------------------------------------------------- 1 | /* Nick Sweeting 2014/03/20 2 | RedBlack 3 | MIT License 4 | g++ RedBlack.cpp -o main; and ./main 5 | 6 | A Red-Black Tree implementation that can read input from a file, show sorted values, and more. 7 | */ 8 | 9 | #include 10 | #include 11 | #include // pow, sqrt 12 | #include // isdigit (parsing for tokens/ops) 13 | #include // vector of tokenized input 14 | #include // breadth-first search 15 | #include // istringstream, setw 16 | #include 17 | #include // file() 18 | using namespace std; 19 | 20 | const string delims = ",; "; // for reading csv 21 | const int maxwidth = 240; // max terminal width for centering output 22 | 23 | #define RED 1 24 | #define BLACK 2 25 | 26 | struct node { 27 | int key; 28 | struct node *left, *right, *p; // p = parent 29 | int color; // RED || BLACK 30 | }; 31 | 32 | typedef struct node *nodep; // nodepointer 33 | struct node nil; 34 | nodep nilp = &nil; // instead of using NULL for comparisons we use a nil pointer, which is a pointer with a recursively defined left & right that point to itself 35 | 36 | // this is my first venture into functional-style c++ programming 37 | // i'm goind to try to implement redblack without using state 38 | // no size counter is kept, everything is a function that takes a tree as input and either returns a response or is called for a side effect (like printing to stdout) 39 | 40 | // x,y are like temp1, temp2; user input is stored in Z 41 | 42 | void sorted(nodep x) { 43 | if (x != nilp) { 44 | sorted(x->left); 45 | cout << x->key << ", "; 46 | sorted(x->right); 47 | } 48 | } 49 | 50 | nodep search(nodep root, int k) { 51 | if (root == nilp || root->key == k) 52 | return root; 53 | if (k < root->key) 54 | return search(root->left, k); 55 | else 56 | return search(root->right, k); 57 | } 58 | 59 | nodep min(nodep root) { 60 | while (root->left != nilp) 61 | root = root->left; 62 | return root; 63 | } 64 | 65 | nodep max(nodep root) { 66 | while (root->right != nilp) 67 | root = root->right; 68 | return root; 69 | } 70 | 71 | nodep after(nodep root, int x) { 72 | nodep temp = search(root, x); 73 | if (temp == nilp) { 74 | cout << "[X]" << x << " not in tree" << endl; 75 | return NULL; 76 | } 77 | if (temp->right != nilp) 78 | return min(temp->right); 79 | nodep y = temp->p; 80 | while (y != nilp && temp == y->right) { 81 | temp = y; 82 | y = y->p; 83 | } 84 | return y; 85 | } 86 | 87 | nodep before(nodep root, int x) { 88 | nodep temp = search(root, x); 89 | if (temp == nilp) { 90 | cout << "[X]" << x << " not in tree" << endl; 91 | return NULL; 92 | } 93 | if (temp->left != nilp) 94 | return max(temp->left); 95 | nodep y = temp->p; 96 | while (y != nilp && temp == y->left) { 97 | temp = y; 98 | y = y->p; 99 | } 100 | return y; 101 | } 102 | 103 | void rotateleft(nodep *treeroot, nodep x) { 104 | nodep y = x->right; 105 | x->right = y->left; 106 | if (y->left != nilp) 107 | y->left->p = x; 108 | y->p = x->p; 109 | if (x->p == nilp) 110 | *treeroot = y; 111 | else if (x->p->left == x) 112 | x->p->left = y; 113 | else 114 | x->p->right = y; 115 | y->left = x; 116 | x->p = y; 117 | } 118 | 119 | void rotateright(nodep *treeroot, nodep y) { 120 | nodep x = y->left; 121 | y->left = x->right; 122 | if (x->right != nilp) 123 | x->right->p = y; 124 | x->p = y->p; 125 | if (y->p == nilp) 126 | *treeroot = x; 127 | else if (y->p->left == y) 128 | y->p->left = x; 129 | else 130 | y->p->right = x; 131 | x->right = y; 132 | y->p = x; 133 | } 134 | 135 | void treeinsertfix(nodep *treeroot, nodep z) { 136 | while (z->p->color == RED) { 137 | if (z->p == z->p->p->left) { // parent parent 138 | nodep y = z->p->p->right; 139 | if (y->color == RED) { 140 | z->p->color = BLACK; 141 | y->color = BLACK; 142 | z->p->p->color = RED; 143 | z = z->p->p; 144 | } 145 | else { 146 | if (z == z->p->right) { 147 | z = z->p; 148 | rotateleft(treeroot,z); 149 | } 150 | z->p->color = BLACK; 151 | z->p->p->color = RED; 152 | rotateright(treeroot,z->p->p); 153 | } 154 | } 155 | else { 156 | nodep y = z->p->p->left; 157 | if (y->color == RED) { 158 | z->p->color = BLACK; 159 | y->color = BLACK; 160 | z->p->p->color = RED; 161 | z = z->p->p; 162 | } 163 | else { 164 | if (z == z->p->left) { 165 | z = z->p; 166 | rotateright(treeroot,z); 167 | } 168 | z->p->color = BLACK; 169 | z->p->p->color = RED; 170 | rotateleft(treeroot,z->p->p); 171 | } 172 | } 173 | } 174 | (*treeroot)->color = BLACK; 175 | } 176 | 177 | void treeinsert(nodep *treeroot, int z) { 178 | nodep Z = (nodep) malloc(sizeof(struct node)); // wohoho, I've discovered some new dangerous toys from C-land to play with 179 | Z->key = z; 180 | nodep y = nilp; 181 | nodep x = *treeroot; 182 | while (x != nilp) { 183 | y = x; 184 | if (Z->key < x->key) 185 | x = x->left; 186 | else 187 | x = x->right; 188 | } 189 | Z->p = y; 190 | if (y == nilp) 191 | *treeroot = Z; 192 | else if (Z->key < y->key) 193 | y->left = Z; 194 | else 195 | y->right = Z; 196 | Z->left = nilp; 197 | Z->right = nilp; 198 | Z->color = RED; 199 | treeinsertfix(treeroot,Z); 200 | } 201 | 202 | void treetransplant(nodep *treeroot, nodep u, nodep v) { 203 | if (u->p == nilp) 204 | *treeroot = v; 205 | else if (u == u->p->left) 206 | u->p->left = v; 207 | else 208 | u->p->right = v; 209 | v->p = u->p; 210 | } 211 | 212 | void treedeletefix(nodep *treeroot, nodep x) { 213 | while (x != *treeroot && x->color == BLACK) { 214 | if (x == x->p->left) { 215 | nodep w = x->p->right; 216 | if (w->color == RED) { 217 | w->color = BLACK; 218 | x->p->color = RED; 219 | rotateleft(treeroot,x->p); 220 | w = x->p->right; 221 | } 222 | if (w->left->color == BLACK && w->right->color == BLACK) { 223 | w->color = RED; 224 | x = x->p; 225 | } 226 | else { 227 | if (w->right->color == BLACK) { 228 | w->left->color = BLACK; 229 | w->color = RED; 230 | rotateright(treeroot,w); 231 | w = x->p->right; 232 | } 233 | w->color = x->p->color; 234 | x->p->color = BLACK; 235 | w->right->color = BLACK; 236 | rotateleft(treeroot,x->p); 237 | x = *treeroot; 238 | } 239 | } 240 | else { 241 | nodep w = x->p->left; 242 | if (w->color == RED) { 243 | w->color = BLACK; 244 | x->p->color = RED; 245 | rotateright(treeroot,x->p); 246 | w = x->p->left; 247 | } 248 | if (w->left->color == BLACK && w->right->color == BLACK) { 249 | w->color = RED; 250 | x = x->p; 251 | } 252 | else { 253 | if (w->left->color == BLACK) { 254 | w->right->color = BLACK; 255 | w->color = RED; 256 | rotateleft(treeroot,w); 257 | w = x->p->left; 258 | } 259 | w->color = x->p->color; 260 | x->p->color = BLACK; 261 | w->left->color = BLACK; 262 | rotateright(treeroot,x->p); 263 | x = *treeroot; 264 | } 265 | } 266 | } 267 | x->color = BLACK; 268 | } 269 | 270 | void treedelete(nodep *treeroot, int z) { 271 | nodep Z = search(*treeroot, z); 272 | if (Z == nilp) { 273 | cout << "[X] Node to be deleted not found" << endl; 274 | return; 275 | } 276 | nodep y = Z; 277 | int yoc = y->color; 278 | nodep x; 279 | if (Z->left == nilp) { 280 | x = Z->right; 281 | treetransplant(treeroot,Z,Z->right); 282 | } 283 | else if (Z->right == nilp) { 284 | x = Z->left; 285 | treetransplant(treeroot,Z,Z->left); 286 | } 287 | else { 288 | y = min(Z->right); 289 | yoc = y->color; 290 | x = y->right; 291 | if (y->p == Z) 292 | x->p = y; 293 | else { 294 | treetransplant(treeroot,y,y->right); 295 | y->right = Z->right; 296 | y->right->p = y; 297 | } 298 | treetransplant(treeroot,Z,y); 299 | y->left = Z->left; 300 | y->left->p = y; 301 | y->color = Z->color; 302 | } 303 | if (yoc == BLACK) 304 | treedeletefix(treeroot,x); 305 | } 306 | 307 | int stoint(string s) { 308 | int out = 0; 309 | istringstream(string(s)) >> out; 310 | return out; 311 | } 312 | 313 | string itostring(int i) { 314 | std::stringstream out; 315 | out << i; 316 | return out.str(); 317 | } 318 | 319 | vector tokenize(string input) { 320 | vector tokens; 321 | size_t prev = 0, pos; 322 | // find next occurence of next delimiter after prev delimiter, then make a token using everything between those two positions 323 | while ((pos = input.find_first_of(delims, prev)) != string::npos) { 324 | if (pos > prev) 325 | tokens.push_back(stoint(input.substr(prev, pos-prev))); 326 | //tokens.push_back(stoint(input.substr(pos, 1))); // this adds the delimiter as a token as well, useful for catching operators as tokens (e.g. +-()*/^) 327 | prev = pos+1; 328 | } 329 | // catch trailing token after the last delimiter 330 | if (prev < input.length()) 331 | tokens.push_back(stoint(input.substr(prev, string::npos))); 332 | 333 | return tokens; 334 | } 335 | 336 | void center(string centerstr) { 337 | int len = centerstr.length(); 338 | if (len > maxwidth) { 339 | centerstr = "..."; 340 | len = 3; 341 | } 342 | for (int i=0; icolor == RED) 353 | // nodestr = "\033[1;31m" + itostring(n->key)+"|R" + "\033[0m"; 354 | // else 355 | // nodestr = "\033[1;33m" + itostring(n->key)+"|B" + "\033[0m"; 356 | // return nodestr; 357 | // } 358 | 359 | string ntostring(nodep n) { 360 | string nodestr; 361 | if (n == nilp) 362 | nodestr = "NIL|B"; 363 | else if (n->color == RED) 364 | nodestr = itostring(n->key)+"|R"; 365 | else 366 | nodestr = itostring(n->key)+"|B"; 367 | return nodestr; 368 | } 369 | 370 | void visualize(nodep root) { 371 | queue q; 372 | 373 | q.push(root); 374 | q.push(0); 375 | 376 | string out = ""; 377 | 378 | while (q.size() > 1) { // one nullptr will always remain in the list. So test for size>1 379 | root=q.front(); 380 | q.pop(); 381 | if (!root) {center(out); out = ""; q.push(0); continue; } 382 | 383 | out += ntostring(root) + " "; 384 | 385 | if (root != nilp) { 386 | q.push(root->left); 387 | q.push(root->right); 388 | } 389 | } 390 | } 391 | 392 | int main () { 393 | nil.left = nil.right = nil.p = nilp; // magic 394 | nil.color = BLACK; // black magic 395 | nodep tree = nilp; // oh no! where did it go? 396 | // ^ inits the helpful nilp so that we can use it for comparisons 397 | int n; // sorcery! 398 | cout << "Will generate and balance a RedBlack tree, it can handle numbers between 0 and " << numeric_limits::max() << endl; 399 | cout << "[1] add\n[2] remove\n[3] find\n[4] sorted\n[5] min\n[6] max\n---\n[7] read file\n[8] visualize\n[9] link to python script\n[0] quit\n\n"; 400 | while (1) { 401 | cout << "[#]:"; 402 | cin >> n; 403 | if (n == 1) { 404 | cout << "[i] Numbers to add:"; 405 | string intext; 406 | cin >> intext; cin.clear(); 407 | vector tokens = tokenize(intext); 408 | for (int i=0; i> intext; cin.clear(); 415 | vector tokens = tokenize(intext); 416 | for (int i=0; i> num; cin.clear(); 423 | if (search(tree, num) == nilp) 424 | cout << "[X] " << num << " not found" << endl; 425 | else 426 | cout << "[√] " << num << " found" << endl; 427 | } 428 | else if (n == 4) { 429 | cout << "[<] "; 430 | sorted(tree); 431 | cout << endl; 432 | } 433 | else if (n == 5) { 434 | cout << "[-] " << min(tree)->key << endl; 435 | } 436 | else if (n == 6) { 437 | cout << "[+] " << max(tree)->key << endl; 438 | } 439 | else if (n == 7) { 440 | string infile; 441 | cout << "[i] Filename:"; 442 | cin >> infile; 443 | std::ifstream file(infile, std::ios::binary); 444 | std::streambuf* raw_buffer = file.rdbuf(); 445 | char* block = new char[65536]; // max file size 446 | raw_buffer->sgetn(block, 65536); 447 | string intext = ""; 448 | for (int i=0; i<65536; i++) 449 | intext += block[i]; 450 | vector tokens = tokenize(intext); 451 | if (tokens.size() == 1) 452 | cout << "[X] No CSV formatted input found (numbers delimited by , and/or ;)" << endl; 453 | else { 454 | for (int i=0; i> num; cin.clear(); 475 | nodep t = after(tree, num); 476 | if (t != NULL) 477 | cout << "[√] " << t->key << endl; 478 | } 479 | else if (n == 12) { 480 | cout << "[i] Find the number before this:"; 481 | int num; 482 | cin >> num; cin.clear(); 483 | nodep t = before(tree, num); 484 | if (t != NULL) 485 | cout << "[√]" << t->key << endl; 486 | } 487 | else 488 | cout << "[X] Enter the number of the command you're trying to run." << endl; 489 | } 490 | return 0; 491 | } 492 | -------------------------------------------------------------------------------- /Reference-vs-Value.cpp: -------------------------------------------------------------------------------- 1 | /* Nick Sweeting 2013/10/09 2 | References vs Values in C++ 3 | MIT License 4 | 5 | Takes input and removes puctuation and spaces, using two different methods. 6 | */ 7 | 8 | #include 9 | #include 10 | using namespace std; 11 | 12 | // returns true if input character q is puctuation, else false 13 | bool ispunctuation(char q) { 14 | char punct[31] = ".!-_? <>,$#@=+*&^$!;:'()[]{}|`"; 15 | int p; 16 | for (p=0;p<30;p++) if (q == punct[p]) return true; 17 | return false; 18 | } 19 | 20 | char* modifyAndCopy(char *raw_input) { 21 | // input cleanup 22 | char* newarray = new char[80]; 23 | int q, position = 0; 24 | for (q=0;q<80;q++) { 25 | if (ispunctuation(raw_input[q])) true; 26 | else { 27 | newarray[position] = raw_input[q]; 28 | position++; 29 | } 30 | } 31 | return newarray; 32 | } 33 | 34 | char* modifyInPlace(char *raw_input) { 35 | // input cleanup 36 | int q, position = 0; 37 | for (q=0;q<80;q++) { 38 | if (ispunctuation(raw_input[q])) true; 39 | else { 40 | raw_input[position] = raw_input[q]; 41 | position++; 42 | } 43 | } 44 | return raw_input; 45 | } 46 | 47 | int main() { 48 | // user input 49 | char raw_input[80] = {0}; 50 | cout << "Please input something with punctuation in it: "; 51 | cin.getline(raw_input,80); 52 | 53 | cout << "Modify and Copy: " << endl; 54 | cout << "Original: " << raw_input << endl; 55 | cout << "Modified: " << modifyAndCopy(raw_input) << endl << endl; 56 | 57 | cout << "Modify in Place: " << endl; 58 | cout << "Original: " << raw_input << endl; 59 | cout << "Modified: " << modifyInPlace(raw_input) << endl; 60 | } 61 | -------------------------------------------------------------------------------- /ReversibleStack.cpp: -------------------------------------------------------------------------------- 1 | /* Nick Sweeting 2014/12 2 | ReversibleStack 3 | MIT License 4 | g++ ReversibleStack.cpp -o main; and ./main inputfile.txt 5 | 6 | A reversible stack implemenation that reads commands 'push,pop,reverse,display' out of a file to build the stack. 7 | */ 8 | 9 | 10 | #include // needed to use NULL 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | using namespace std; 17 | 18 | class ReversibleStack { 19 | private: 20 | struct Node { 21 | int data; 22 | Node* next; 23 | }; 24 | 25 | public: 26 | Node* top; // making this public is not ideal, but makes it much easier to Reverse if we can get the top pointer directly 27 | 28 | ReversibleStack() { 29 | top = NULL; 30 | } 31 | 32 | ~ReversibleStack(){ 33 | Empty(); 34 | } 35 | 36 | void Push(int newval) { 37 | Node *tmp = new Node; // create new node tmp 38 | 39 | tmp->data = newval; // set new node value to x 40 | tmp->next = top; // points to old top of the ReversibleStack 41 | top = tmp; // now the top 42 | } 43 | 44 | int Pop() { 45 | if (IsEmpty()) return NULL; // if the list is empty, return NULL (this is very bad, we should return int*=NULL NOT int=NULL) 46 | int topVal = top->data; 47 | 48 | Node* oldTop = top; 49 | top = top->next; 50 | delete oldTop; 51 | 52 | return topVal; 53 | } 54 | 55 | int Top() { 56 | if (IsEmpty()) return NULL; 57 | return top->data; 58 | } 59 | 60 | void Reverse() { 61 | ReversibleStack* newStack = new ReversibleStack(); // have to use new to allocate new memory, otherwise it gets deleted when the function ends 62 | while (!IsEmpty()) newStack->Push(Pop()); 63 | Node* oldTop = top; 64 | top = newStack->top; // point top to the top of the new, reversed stack 65 | delete oldTop; // delete the old top which is now pointing to an empty stack 66 | } 67 | 68 | void Empty() { 69 | while (!IsEmpty()) Pop(); 70 | } 71 | 72 | int IsEmpty() { 73 | return (top == NULL); // checks if ReversibleStack is empty 74 | } 75 | }; 76 | 77 | void Display(ReversibleStack& stack) { 78 | // Implement this function (use only Push, Pop and IsEmpty member functions of stack) 79 | // After the function completes, the stack should be unmodified (see assignment instructions) 80 | 81 | // we make a new stack, the loop through the existing ones, popping off elements and putting them on the new stack 82 | // then we go through the new stack and pop them all off and put them back on the original one 83 | ReversibleStack newStack; 84 | while (!stack.IsEmpty()) { 85 | int value = stack.Pop(); 86 | cout << value << (stack.IsEmpty() ? "" :","); 87 | newStack.Push(value); 88 | } 89 | while(!newStack.IsEmpty()) { 90 | stack.Push(newStack.Pop()); 91 | } 92 | } 93 | 94 | int main(int argc, char* argv[]) { 95 | if (argc < 2) { 96 | cout << "Missing required argument for input file." << endl; 97 | return 1; // return nonzero for failure 98 | } 99 | 100 | ifstream inFile; 101 | inFile.open(argv[1], ifstream::in); 102 | 103 | if (!inFile.is_open()) { 104 | cout << "Could not open: " << argv[1] << endl; 105 | return 2; 106 | } 107 | 108 | ReversibleStack rs; 109 | string line; 110 | 111 | // Process the command on each line 112 | while (!inFile.eof()) { 113 | getline(inFile, line); 114 | 115 | if (line == "") { 116 | // do nothing, it's an empty line 117 | } 118 | else if (line.compare(0, 6, "header") == 0) { 119 | cout << "Name: Eric Chen ID: 11381898"; // Display the header line here, as the instructions describe 120 | } 121 | else if (line.compare(0, 4, "push") == 0) { 122 | int val = stoi(line.substr(5)); 123 | rs.Push(val); 124 | cout << "pushed: " << val; 125 | } 126 | else if (line.compare(0, 3, "pop") == 0) { 127 | cout << "popped: " << rs.Pop(); // pop and print the top item 128 | } 129 | else if (line.compare(0, 7, "isempty") == 0) { 130 | cout << "isempty: " << (rs.IsEmpty() ? "true": "false"); // print true if empty, otherwise false 131 | } 132 | else if (line.compare(0, 7, "reverse") == 0) { 133 | rs.Reverse(); 134 | cout << "reversed"; 135 | } 136 | else if (line.compare(0, 7, "display") == 0) { 137 | cout << "display: "; 138 | Display(rs); 139 | } 140 | else { 141 | cout << "Unknown command: " << line; 142 | } 143 | cout << endl; 144 | } 145 | 146 | inFile.close(); 147 | cout << "Done" << endl; 148 | return 0; // return 0 for success 149 | } 150 | -------------------------------------------------------------------------------- /TicTacToe-Broken.cpp: -------------------------------------------------------------------------------- 1 | /* Nick Sweeting 2013/09/09 2 | Tic Tac Toe in C++ (non OOP) 3 | MIT License 4 | g++ TicTacToe.cpp -o main && ./main 5 | 6 | An even buggier fork of my TicTacToe implementation, TODO: get it working. 7 | */ 8 | 9 | #include 10 | #include 11 | using namespace std; 12 | 13 | enum square {EMPTY=' ', O='O', X='X'}; // define a new enum "square" with 3 possible values (used for array board[]) 14 | 15 | square board[9] = {EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY}; // initialize the board with all empty squares 16 | //square board[9] = {X,O,O,O,X,O,X,O,X}; // initialize the board with X winning (debug only) 17 | //square board[9] = {O,O,X,O,O,X,X,X,O}; // initialize the board with O winning (debug only) 18 | //square board[9] = {X,O,X,O,O,X,X,X,O}; // initialize the board with a tie (debug only) 19 | 20 | int solutions[8][3] = {{0, 3, 6}, {1, 4, 7}, {2, 5, 8}, // vertical solutions 21 | {0, 1, 2}, {3, 4, 5}, {6, 7, 8}, // horizontal solutions 22 | {0, 4, 8}, {2, 4, 6}}; // diagonal solutions 23 | 24 | bool allow_skip = true; // allow the human to skip their turn and have the computer play itself (debug only) 25 | 26 | void print_help() { 27 | cout << "1|2|3" << endl; 28 | cout << "4|5|6" << endl; 29 | cout << "7|8|9" << endl; 30 | } 31 | 32 | // print current board highlighting last human move and last computer move (sorry for line noise, ansi escapes are ugly) 33 | void print_board(square board[9], int recent_human_move, int recent_computer_move) { 34 | string tmp_board[9]; 35 | for (int i=0; i<9; i++) { 36 | if (i == recent_human_move) 37 | tmp_board[i] = "\033[1;31m" + string(1,board[i]) + "\033[0m"; // red for human's last move (using ASCII escape codes) 38 | else if (i == recent_computer_move) 39 | tmp_board[i] = "\033[1;33m" + string(1,board[i]) + "\033[0m"; // yellow for computer's move 40 | else 41 | tmp_board[i] = string(1, board[i]); 42 | } 43 | cout << tmp_board[0] << '|' << tmp_board[1] << '|' << tmp_board[2] << endl; // X|O|X 44 | cout << tmp_board[3] << '|' << tmp_board[4] << '|' << tmp_board[5] << endl; // O|X|O 45 | cout << tmp_board[6] << '|' << tmp_board[7] << '|' << tmp_board[8] << endl; // X|O|X 46 | } 47 | 48 | // check to see if the game is over, return an int status 49 | int check_for_winner(square board[9]) { 50 | // returns int winner X=0, O=1, tie=2, unfinished=-1 51 | 52 | // check for win by a player 53 | int* s; 54 | for (int i=0; i<8; i++) { 55 | s = solutions[i]; 56 | if (board[s[0]] != EMPTY && board[s[0]] == board[s[1]] && board[s[1]] == board[s[2]]) 57 | return int(board[s[0]] == O); // all three squares in a solution are played by a player 58 | } 59 | 60 | // return -1 if any squares are empty (game unfinished) 61 | for (int b=0; b<9; b++) 62 | if (board[b] == EMPTY) 63 | return -1; 64 | 65 | return 2; // otherwise it's a tie 66 | } 67 | 68 | // checks move validity, and places the move if valid then returns the int move, if invalid returns -1 69 | int place_move(square board[9], int move, square player_symbol) { 70 | if (player_symbol == EMPTY || board[move] != EMPTY) 71 | return -1; 72 | else { 73 | board[move] = player_symbol; 74 | return move; 75 | } 76 | } 77 | 78 | // asks the human for input, then places the move if it's valid 79 | int human_move(square board[9], square human_symbol) { // returns the move made or -1 if invalid 80 | int move = -1; 81 | int input_square = -1; 82 | while (input_square == -1) { 83 | cout << "Which square do you pick: "; 84 | cin >> input_square; 85 | cin.clear(); // will cause infinite loop unless input buffer is cleared between inputs 86 | cin.ignore(numeric_limits::max(), '\n'); // must also ignore newlines from previous input 87 | 88 | if (input_square == 0 && allow_skip) 89 | return 0; 90 | 91 | if (input_square < 1 || input_square > 9) { 92 | cout << "\nYou idiot, type numbers between 1-9 only.\n"; 93 | input_square = -1; 94 | } 95 | else 96 | move = input_square-1; 97 | } 98 | 99 | int final_move = place_move(board, move, human_symbol); 100 | if (final_move == -1) { 101 | // if spot is taken 102 | cout << "\nPlacing an " << string(1, human_symbol) << " at " << move+1 << " is invalid.\n"; 103 | usleep(1000*500); 104 | return human_move(board, human_symbol); 105 | } 106 | else 107 | return final_move; 108 | } 109 | 110 | /* AI Functions: 111 | Alpha-Beta Pruning algorithm (Minimax) 112 | Big O worst case: O(|E|+|V|) -- type: depth-first 113 | */ 114 | 115 | // dumb AI for gameplay demonstration and debugging when minimax_ai is broken 116 | int fallback_ai(square board[9]) { 117 | // play center, then corners, then everything else 118 | int moves[9] = {4,0,2,6,8,1,3,5,7}; 119 | for (int i=0;i<9;i++) 120 | if (board[moves[i]] == EMPTY) 121 | return moves[i]; 122 | } 123 | 124 | // returns +1, 0, or -1 for scoring of the move to determine whether it helps the computer, human, or neither 125 | int judge_move(int winner, square current_player, square computer_symbol) { 126 | // handle ties straight off the bat 127 | if (winner == 2) 128 | return 0; 129 | 130 | // convert player symbol to int X=0, O=1 131 | int player = int(current_player == O); 132 | int score = (player == winner) ? 1 : -1; 133 | 134 | // flip score if computer is not player who placed move 135 | if (computer_symbol != current_player) 136 | score = -score; 137 | 138 | return score; 139 | } 140 | 141 | // calculates which moves are viable by seeing which squares are EMPTY, returns array of bools viable_squares[] 142 | bool* calc_viable(square board[9]) { 143 | bool *viable_squares = new bool[9]; 144 | 145 | for (int i=0; i<9; i++) 146 | viable_squares[i] = (board[i] == EMPTY); 147 | 148 | return viable_squares; 149 | } 150 | 151 | // the recursor function that plays out every possible game and calulates scores for each, places scores in the score[] int array 152 | void minimax_recursor(square *tmp_board, int score[9], square current_player, square computer_symbol) { 153 | bool *viable_squares = calc_viable(tmp_board); 154 | for (int m=0; m<9; m++) { 155 | if (viable_squares[m] == true) { 156 | tmp_board[m] = current_player; // place actual move on temporary board 157 | int winner = check_for_winner(tmp_board); 158 | if (winner == -1) { 159 | //cout << "Begin recurse for " << m+1 << endl; 160 | 161 | // flip flop the players 162 | if (current_player == X) 163 | current_player = O; 164 | else 165 | current_player = X; 166 | minimax_recursor(tmp_board, score, current_player, computer_symbol); 167 | tmp_board[m] = EMPTY; // undo move so simulation can continue 168 | if (current_player == X) 169 | current_player = O; 170 | else 171 | current_player = X; 172 | } 173 | else { 174 | //cout << "Score[" << m+1 << "] += " << judge_move(winner, current_player, computer_symbol) << endl; 175 | //print_board(tmp_board, -1, m); 176 | //score[m] += judge_move(winner, current_player, computer_symbol); 177 | int square_score = judge_move(winner, current_player, computer_symbol); 178 | if (score[m] >= 0 && square_score > 0) 179 | score[m] += square_score; 180 | 181 | else if (score[m] <= 0 && square_score < 0) 182 | score[m] = square_score; 183 | 184 | tmp_board[m] = EMPTY; // undo move so simulation can continue 185 | } 186 | } 187 | } 188 | } 189 | 190 | // starts the minimax_recursor with a starting set of viable_moves, chooses the move with the best score and returns int move_made 191 | int ai_move(square board[9], square computer_symbol) { 192 | // copy board into tmp_board to prevent direct modification during ranking 193 | square tmp_board[9]; 194 | for (int i=0; i<9; i++) 195 | tmp_board[i] = board[i]; 196 | 197 | cout << "starting AI" << endl; 198 | print_board(tmp_board, -1, -1); 199 | 200 | // score all the possible moves recursively 201 | int score[9] = {0,0,0,0,0,0,0,0,0}; 202 | minimax_recursor(tmp_board, score, computer_symbol, computer_symbol); 203 | 204 | int best_score[2] = {-1,0}; // position, score 205 | for (int y=0;y<9;y++) { 206 | cout << "Position: " << y+1 << ". Score: " << score[y] << endl; 207 | if (score[y] < best_score[1]) { 208 | best_score[0] = y; 209 | best_score[1] = score[y]; 210 | } 211 | } 212 | if (best_score[1] == 0) { 213 | for (int y=0;y<9;y++) { 214 | if (score[y] > best_score[1]) { 215 | best_score[0] = y; 216 | best_score[1] = score[y]; 217 | } 218 | } 219 | } 220 | 221 | int result = place_move(board, best_score[0], computer_symbol); 222 | if (result == -1) { 223 | cout << "\nMimixax Error: " << string(1, computer_symbol) << " at " << best_score[0]+1 << " is invalid.\n"; 224 | result = place_move(board, fallback_ai(board), computer_symbol); 225 | } 226 | cout << "Computer chose: " << result+1 << endl; 227 | return result; 228 | } 229 | 230 | int main () { 231 | // ask user to pick which symbol they want to use 232 | cout << "Choose your weapon (X/O): "; 233 | char tmp_human_symbol; 234 | cin >> tmp_human_symbol; 235 | cin.clear(); // will cause infinite loop unless input buffer is cleared between inputs 236 | 237 | square human_symbol, computer_symbol; 238 | if (tmp_human_symbol == 'x' || tmp_human_symbol == 'X') { 239 | human_symbol = X; 240 | computer_symbol = O; 241 | } 242 | else { 243 | human_symbol = O; 244 | computer_symbol = X; 245 | } 246 | 247 | print_help(); 248 | 249 | int recent_human_move, recent_computer_move = -1; 250 | 251 | // Game loop 252 | while (check_for_winner(board) == -1) { 253 | recent_human_move = human_move(board, human_symbol); 254 | if (check_for_winner(board) != -1) 255 | break; 256 | recent_computer_move = ai_move(board, computer_symbol); 257 | if (check_for_winner(board) != -1) 258 | break; 259 | print_board(board, recent_human_move, recent_computer_move); 260 | } 261 | 262 | // Endgame Text 263 | cout << endl; 264 | print_board(board, -1, -1); // print ending state of the board with no recent moves highlighted 265 | string winner; 266 | int end_result; 267 | end_result = check_for_winner(board); // its a tad innefficient to keep calling this every time, who cares, its only an extra 15ms 268 | 269 | if (human_symbol == X && end_result == 0) winner = "You won. (X)"; 270 | else if (human_symbol == O && end_result == 1) winner = "You won. (O)"; 271 | else if (computer_symbol == X && end_result == 0) winner = "Computer won. (X)"; 272 | else if (computer_symbol == O && end_result == 1) winner = "Computer won. (O)"; 273 | else winner = "It was a tie."; 274 | 275 | cout << "\nGame is over. " << winner << endl; 276 | 277 | return 0; 278 | } 279 | -------------------------------------------------------------------------------- /TicTacToe.cpp: -------------------------------------------------------------------------------- 1 | /* Nick Sweeting 2013/09/09 2 | Tic Tac Toe in C++ (non OOP) 3 | MIT Liscense 4 | g++ TicTacToe.cpp -o main && ./main 5 | 6 | The TicTacToe game. Human vs (buggy) minimax-based AI. 7 | */ 8 | 9 | #include 10 | #include 11 | using namespace std; 12 | 13 | enum square {EMPTY=' ', O='O', X='X'}; // define a new enum "square" with 3 possible values (used for array board[]) 14 | 15 | square board[9] = {EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY}; // initialize the board with all empty squares 16 | 17 | bool allow_skip = true; // allow the human to skip their turn and have the computer play itself (debug only) 18 | 19 | // print user help board showing square numbering 20 | void print_help() { 21 | cout << 1 << '|' << 2 << '|' << 3 << endl; // 1|2|3 22 | cout << 4 << '|' << 5 << '|' << 6 << endl; // 4|5|6 23 | cout << 7 << '|' << 8 << '|' << 9 << endl; // 7|8|9 24 | } 25 | 26 | // print current board highlighting last human move and last computer move (sorry for line noise, ansi escapes are ugly) 27 | void print_board(square board[9], int recent_human_move, int recent_computer_move) { 28 | string tmp_board[9]; 29 | for (int i=0; i<9; i++) { 30 | if (i == recent_human_move) tmp_board[i] = "\033[1;31m" + string(1,board[i]) + "\033[0m"; // red for human's last move (using ASCII escape codes) 31 | else if (i == recent_computer_move) tmp_board[i] = "\033[1;33m" + string(1,board[i]) + "\033[0m"; // yellow for computer's move 32 | else tmp_board[i] = string(1, board[i]); 33 | } 34 | cout << tmp_board[0] << '|' << tmp_board[1] << '|' << tmp_board[2] << endl; // X|O|X 35 | cout << tmp_board[3] << '|' << tmp_board[4] << '|' << tmp_board[5] << endl; // O|X|O 36 | cout << tmp_board[6] << '|' << tmp_board[7] << '|' << tmp_board[8] << endl; // X|O|X 37 | } 38 | 39 | // check to see if the game is over, return an int status 40 | int check_for_winner(square board[9]) { // returns int winner X=0, O=1, tie=2, unfinished=-1 41 | 42 | int solutions[8][3] = {{0, 3, 6}, // vertical solutions 43 | {1, 4, 7}, 44 | {2, 5, 8}, 45 | {0, 1, 2}, // horizontal solutions 46 | {3, 4, 5}, 47 | {6, 7, 8}, 48 | {0, 4, 8}, // diagonal solutions 49 | {2, 4, 6}}; 50 | 51 | // check for win by a player 52 | int index1, index2, index3; 53 | for (int i=0; i<8; i++){ 54 | index1 = solutions[i][0]; 55 | index2 = solutions[i][1]; 56 | index3 = solutions[i][2]; 57 | if (board[index1] == board[index2] && 58 | board[index2] == board[index3] && 59 | board[index1] != EMPTY) { 60 | return board[index1] == X ? 0 : 1; 61 | } 62 | } 63 | 64 | // check for a tie 65 | for (int b=0; b<9; b++) 66 | if (board[b] == EMPTY) 67 | return -1; // return -1 if any squares are empty (game unfinished) 68 | 69 | // if no winner is found, and squares are not empty, return tie 70 | return 2; 71 | } 72 | 73 | // checks move validity, and places the move if valid then returns the int move, if invalid returns -1 74 | int place_move(square board[9], int move, square player_symbol) { 75 | if (player_symbol == EMPTY) return -1; // placing an EMPTY is always invalid 76 | else if (board[move] != EMPTY) return -1; // placing your move where one already exists is always invalid 77 | else { 78 | board[move] = player_symbol; 79 | return move; 80 | } 81 | } 82 | 83 | // asks the human for input, then places the move if its valid 84 | int human_move(square board[9], square human_symbol) { // returns the move made or -1 if invalid 85 | int move = -1; 86 | int input_square = -1; 87 | while (input_square == -1) { 88 | cout << "Which square do you pick: "; 89 | cin >> input_square; 90 | cin.clear(); // will cause infinite loop unless input buffer is cleared between inputs 91 | 92 | if (input_square == 0 && allow_skip) 93 | return 0; 94 | 95 | if (input_square < 1 || input_square > 9) { 96 | cout << "\nYou idiot, type numbers between 1-9 only.\n"; 97 | input_square = -1; 98 | } 99 | else 100 | move = input_square-1; 101 | } 102 | 103 | int final_move = -1; 104 | final_move = place_move(board, move, human_symbol); 105 | if (final_move == -1) { 106 | cout << "\nPlacing an " << string(1, human_symbol) << " at " << move+1 << " is invalid.\n"; // if spot is taken 107 | return human_move(board, human_symbol); 108 | } 109 | else 110 | return final_move; 111 | } 112 | 113 | /* AI Functions: 114 | Alpha-Beta Pruning algorithm (Minimax) 115 | Big O worst case: O(|E|+|V|) -- type: depth-first 116 | */ 117 | 118 | // dumb AI for gameplay demonstration and debugging when minimax_ai is broken 119 | int fallback_ai(square board[9]) { 120 | int sorted_board[9] = {4,0,2,6,8,1,3,5,7}; // play center, then corners, then everything else 121 | for (int i=0;i<9;i++) 122 | if (board[sorted_board[i]] == EMPTY) 123 | return sorted_board[i]; 124 | return 4; 125 | } 126 | 127 | // returns +1, 0, or -1 for scoring of the move to determine whether it helps the computer, human, or neither 128 | int judge_move(int winner, square current_player, square computer_symbol) { 129 | if (winner == 2) return 0; // handle ties straight off the bat 130 | 131 | // convert player symbol to int for easier processing X=0, O=1 132 | int player = current_player == X ? 0 : 1; 133 | int score = winner == player ? 1 : -1; 134 | 135 | // flip score if computer is not player who placed move 136 | if (computer_symbol != current_player) 137 | score = 0 - score; 138 | return score; 139 | } 140 | 141 | // calculates which moves are viable by seeing which squares are EMPTY, returns array of bools viable_squares[] 142 | bool* calc_viable(square board[9]) { 143 | bool *viable_squares; 144 | viable_squares = new bool [9]; 145 | 146 | for (int i=0;i<9;i++) 147 | viable_squares[i] = board[i] == EMPTY; 148 | 149 | return viable_squares; 150 | } 151 | 152 | // the recursor function that plays out every possible game and calulates scores for each, places scores in the score[] int array 153 | void minimax_recursor(square *tmp_board, int score[9], square current_player, square computer_symbol) { 154 | bool *viable_squares = calc_viable(tmp_board); 155 | for (int m=0;m<9;m++) { 156 | if (viable_squares[m] == true) { 157 | tmp_board[m] = current_player; // place actual move on temporary board 158 | int winner = check_for_winner(tmp_board); 159 | if (winner == -1) { 160 | //cout << "Begin recurse for " << m+1 << endl; 161 | 162 | // flip flop the players 163 | current_player = current_player == X ? O : X; 164 | minimax_recursor(tmp_board, score, current_player, computer_symbol); 165 | tmp_board[m] = EMPTY; // undo move so simulation can continue 166 | current_player = current_player == X ? O : X; 167 | } 168 | else { 169 | //cout << "Score[" << m+1 << "] += " << judge_move(winner, current_player, computer_symbol) << endl; 170 | //print_board(tmp_board, -1, m); 171 | //score[m] += judge_move(winner, current_player, computer_symbol); 172 | int square_score = judge_move(winner, current_player, computer_symbol); 173 | if (score[m] >= 0 && square_score > 0) { 174 | score[m] += square_score; 175 | } 176 | else if (score[m] <= 0 && square_score < 0) { 177 | score[m] -= square_score; 178 | } 179 | tmp_board[m] = EMPTY; // undo move so simulation can continue 180 | } 181 | } 182 | } 183 | } 184 | 185 | // starts the minimax_recursor with a starting set of viable_moves, chooses the move with the best score and returns int move_made 186 | int ai_move(square board[9], square computer_symbol) { 187 | // copy board into tmp_board to prevent direct modification during ranking 188 | square tmp_board[] = {EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY}; 189 | for (int a=0;a<9;a++) tmp_board[a] = board[a]; 190 | 191 | cout << "starting AI" << endl; 192 | print_board(tmp_board, -1, -1); 193 | 194 | // score all the possible moves recursively 195 | int score[9] = {0,0,0,0,0,0,0,0,0}; 196 | minimax_recursor(tmp_board, score, computer_symbol, computer_symbol); 197 | 198 | int best_score[2] = {-1,0}; // position, score 199 | for (int y=0;y<9;y++) { 200 | cout << "Position: " << y+1 << ". Score: " << score[y] << endl; 201 | if (score[y] < best_score[1]) { 202 | best_score[0] = y; 203 | best_score[1] = score[y]; 204 | } 205 | } 206 | if (best_score[1] == 0) { 207 | for (int y=0;y<9;y++) { 208 | if (score[y] > best_score[1]) { 209 | best_score[0] = y; 210 | best_score[1] = score[y]; 211 | } 212 | } 213 | } 214 | 215 | int result = place_move(board, best_score[0], computer_symbol); 216 | if (result == -1) { 217 | cout << "\nMimixax Error: " << string(1, computer_symbol) << " at " << best_score[0]+1 << " is invalid.\n"; 218 | result = place_move(board, fallback_ai(board), computer_symbol); 219 | } 220 | cout << "Computer chose: " << result+1 << endl; 221 | return result; 222 | } 223 | 224 | int main () { 225 | // ask user to pick which symbol they want to use 226 | cout << "Choose your weapon (X/O): "; 227 | char tmp_human_symbol; 228 | cin >> tmp_human_symbol; 229 | cin.clear(); // will cause infinite loop unless input buffer is cleared between inputs 230 | 231 | square human_symbol, computer_symbol; 232 | if (tmp_human_symbol == 'x' || tmp_human_symbol == 'X') { 233 | human_symbol = X; 234 | computer_symbol = O; 235 | } 236 | else { 237 | human_symbol = O; 238 | computer_symbol = X; 239 | } 240 | 241 | print_help(); 242 | 243 | int recent_human_move, recent_computer_move = -1; 244 | 245 | // Game loop 246 | while (check_for_winner(board) == -1) { 247 | recent_human_move = human_move(board, human_symbol); 248 | if (check_for_winner(board) != -1) break; 249 | recent_computer_move = ai_move(board, computer_symbol); 250 | if (check_for_winner(board) != -1) break; 251 | print_board(board, recent_human_move, recent_computer_move); 252 | } 253 | 254 | // Endgame Text 255 | cout << endl; 256 | print_board(board, -1, -1); // print ending state of the board with no recent moves highlighted 257 | string winner; 258 | int end_result = check_for_winner(board); // its a tad innefficient to keep calling this every time, who cares, its only an extra 15ms 259 | if (human_symbol == X && end_result == 0) winner = "You won. (X)"; 260 | else if (human_symbol == O && end_result == 1) winner = "You won. (O)"; 261 | else if (computer_symbol == X && end_result == 0) winner = "Computer won. (X)"; 262 | else if (computer_symbol == O && end_result == 1) winner = "Computer won. (O)"; 263 | else winner = "It was a tie."; 264 | 265 | cout << "\nGame is over. " << winner << endl; 266 | 267 | return 0; 268 | } 269 | -------------------------------------------------------------------------------- /Vectors.cpp: -------------------------------------------------------------------------------- 1 | /* Nick Sweeting 2013/10/08 2 | Student List (OOP) 3 | MIT Lisence 4 | g++ Vectors.cpp -o main && ./main 5 | 6 | Example of using vectors to store a list of students and their GPAs. 7 | */ 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | using namespace std; 14 | 15 | struct Student { 16 | string firstName; 17 | string lastName; 18 | int studentID; 19 | double GPA; 20 | }; 21 | 22 | void printStudents(vector students) { 23 | for (int i=0;i addStudent(vector students) { 29 | 30 | Student newStudent; 31 | 32 | cout << "First Name: "; 33 | cin >> newStudent.firstName; 34 | cout << "Last Name: "; 35 | cin >> newStudent.lastName; 36 | cout << "ID: "; 37 | cin >> newStudent.studentID; 38 | cout << "GPA: "; 39 | cin >> newStudent.GPA; 40 | 41 | students.push_back(newStudent); 42 | 43 | return students; 44 | } 45 | 46 | vector delStudent(vector students) { 47 | int studentIDtoDel; 48 | cout << "ID of student to delete: "; 49 | cin >> studentIDtoDel; 50 | 51 | cout << "ID to delete: " << studentIDtoDel << endl; 52 | 53 | vector newStudents; 54 | for (int a=0; a < students.size(); a++) { 55 | if (students[a].studentID != studentIDtoDel) { 56 | newStudents.push_back(students[a]); 57 | } 58 | } 59 | 60 | return newStudents; 61 | } 62 | 63 | int main() { 64 | vector students; 65 | string input; 66 | 67 | while (true) { 68 | cout<<"Input operation: "; 69 | cin >> input; 70 | 71 | if (input == "ADD" || input == "a" || input == "add") { 72 | students = addStudent(students); 73 | } 74 | else if (input == "PRINT" || input == "p" || input == "print") { 75 | printStudents(students); 76 | } 77 | else if (input == "DELETE" || input == "d" || input == "delete") { 78 | students = delStudent(students); 79 | } 80 | else if (input == "QUIT" || input == "q" || input == "quit") { 81 | return 0; 82 | } 83 | } 84 | } 85 | 86 | -------------------------------------------------------------------------------- /ZuulGame.cpp: -------------------------------------------------------------------------------- 1 | /* Nick Sweeting 2013/10/09 2 | Zuul C++ (OOP) 3 | MIT License 4 | g++ ZuulGame.cpp -o main && ./main 5 | 6 | Interactive text-based adventure game with room navigation, items, and a story! 7 | */ 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | using namespace std; 16 | 17 | const int size = 20; // total number of rooms 18 | const int y_size = 5; // length of room map 19 | const int x_size = 4; // width of room map 20 | const int max_items = 15; // max items the player can carry 21 | const int house_pos = 0; // starting position (used in check_win and make_meal) 22 | const char* exit_names[4] = {"North", "East", "South", "West"}; 23 | 24 | class Item { 25 | public: 26 | Item(string inname) { 27 | name = inname; 28 | } 29 | ~Item() {}; 30 | 31 | string name; 32 | }; 33 | 34 | class BoardState { 35 | public: 36 | 37 | class Room { 38 | public: 39 | Room(string in_name) { 40 | name = in_name; 41 | isRoom = true; 42 | } 43 | 44 | ~Room() {}; 45 | 46 | void SetAttr(string inname, string indetails, bool inisRoom) { 47 | name = inname; 48 | details = indetails; 49 | isRoom = inisRoom; 50 | } 51 | 52 | string name; 53 | string details; 54 | bool isRoom; 55 | vector Items; 56 | }; 57 | 58 | int current_room; 59 | int size; 60 | int y_size; 61 | int x_size; 62 | vector Rooms; 63 | 64 | void AddRoom(Room o) { 65 | Rooms.push_back(o); 66 | } 67 | 68 | class Character { 69 | public: 70 | int curr_pos; 71 | string name; 72 | vector Backpack; 73 | 74 | Character() { 75 | curr_pos=0; 76 | }; 77 | 78 | ~Character() {}; 79 | }; 80 | 81 | Character Player; 82 | 83 | BoardState(int in_size, int in_y_size, int in_x_size) { 84 | size = in_size; y_size = in_y_size; x_size = in_x_size; 85 | 86 | Player = Character(); 87 | 88 | for (int q=0; q x_size-1 || x_pos < 0) return -1; 104 | if (y_pos > y_size-1 || y_pos < 0) return -1; 105 | 106 | return (y_pos*x_size)+x_pos; 107 | } 108 | 109 | bool IsRoom(int position) { 110 | if (position >= 0 && position < size) { 111 | return Rooms[position].isRoom; 112 | } 113 | else return false; 114 | } 115 | 116 | int* RoomDoors(int position) { 117 | int y_pos = RoomPos(position)[0]; 118 | int x_pos = RoomPos(position)[1]; 119 | 120 | int *doors = new int[4]; 121 | doors[0] = RoomIndex(y_pos-1, x_pos); // n 122 | doors[1] = RoomIndex(y_pos, x_pos+1); // e 123 | doors[2] = RoomIndex(y_pos+1, x_pos); // s 124 | doors[3] = RoomIndex(y_pos, x_pos-1); // w 125 | 126 | for (int l=0;l<4;l++) if (!IsRoom(doors[l])) doors[l] = -1; 127 | return doors; 128 | } 129 | 130 | void PickItem(BoardState &Game, int pos, string item_to_take) { 131 | for (int l=0; l items_to_win; 164 | 165 | void init(BoardState &Game) { 166 | // for random item positioning (Define room_info[], item_info[], and is_room[] first) 167 | 168 | // vector rnd(size); 169 | // for (int p=0;p items_in_room = Game.Rooms[house_pos].Items; 251 | int count = 0; 252 | for (int i=0;i meal = Game.Rooms[house_pos].Items; 263 | string finished_meal; 264 | for (int f=0;f -1) cout << exit_names[b] << " "; 291 | 292 | cout << endl << "Items: "; 293 | for (int m=0; m "; 306 | cin >> in; 307 | if (in == "p") { 308 | cout << endl << "To Pick up an item from the room, type it's name: "; 309 | string item_to_take; 310 | cin >> item_to_take; 311 | Game.PickItem(Game, curr_pos, item_to_take); 312 | } 313 | if (in == "d") { 314 | cout << endl << "To drop an item from your backpack into the room, type it's name: "; 315 | string item_to_drop; 316 | cin >> item_to_drop; 317 | Game.DropItem(Game, curr_pos, item_to_drop); 318 | } 319 | else if (in == "n" || in == "e" || in == "s" || in == "w") { 320 | int *doors = Game.RoomDoors(curr_pos); 321 | if (in == "n" && doors[0] > -1) Game.Player.curr_pos = doors[0]; 322 | if (in == "e" && doors[1] > -1) Game.Player.curr_pos = doors[1]; 323 | if (in == "s" && doors[2] > -1) Game.Player.curr_pos = doors[2]; 324 | if (in == "w" && doors[3] > -1) Game.Player.curr_pos = doors[3]; 325 | } 326 | else if (in == "q") return 0; 327 | cout << endl; 328 | 329 | // Check for game ending conditions 330 | if (check_win(Game, house_pos)) { 331 | cout << "Congrats! You're collected enough for a candlelight dinner for two." << endl; 332 | cout << "Your meal consists of: " << make_meal(Game, house_pos) << endl; 333 | return 0; 334 | } 335 | } 336 | return 0; 337 | } 338 | -------------------------------------------------------------------------------- /buildout: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pirate/Cpp-Data-Structures/901b0e867980fc78cd9717a333df0c149afbc12b/buildout -------------------------------------------------------------------------------- /example-code/C Hash Table/hashtable.c: -------------------------------------------------------------------------------- 1 | #include "hashtable.h" 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | int hashtable_find(hashtable_t *hashtable, int keyHash) 8 | { 9 | int i = 0; 10 | 11 | for (; i < hashtable->entry_count; i++) 12 | { 13 | if (hashtable->entries[i].keyHash == keyHash) 14 | return i; 15 | } 16 | 17 | return -1; 18 | } 19 | 20 | hashtableentry_t *hashtable_expand(hashtable_t *hashtable, int count) 21 | { 22 | int oldLen = hashtable->entry_count * sizeof(hashtableentry_t); 23 | 24 | if (count == 0) 25 | return (hashtableentry_t *)((char *)hashtable->entries + oldLen); 26 | 27 | hashtable->entry_count += count; 28 | if (hashtable->entry_count <= 0) 29 | { 30 | hashtable->entries = NULL; 31 | hashtable->entry_count = 0; 32 | return; 33 | } 34 | hashtable->entries = (hashtableentry_t *)realloc(hashtable->entries, hashtable->entry_count * sizeof(hashtableentry_t)); 35 | 36 | return (hashtableentry_t *)((char *)hashtable->entries + oldLen); 37 | } 38 | 39 | void hashtable_init(hashtable_t *hashtable, hashtable_hash_function hash, hashtable_len_function len) 40 | { 41 | if (!hashtable) 42 | return; 43 | 44 | hashtable->entries = NULL; 45 | hashtable->entry_count = 0; 46 | 47 | hashtable->hash = hash; 48 | hashtable->len = len; 49 | } 50 | 51 | void hashtable_destroy(hashtable_t *hashtable) 52 | { 53 | hashtable_clear(hashtable); 54 | } 55 | 56 | void hashtable_set(hashtable_t *hashtable, void *key, void *value) 57 | { 58 | int keyHash = hashtable->hash(key, hashtable->len(key)); 59 | hashtableentry_t *ptr; 60 | int i; 61 | 62 | if ((i = hashtable_find(hashtable, keyHash)) != -1) 63 | { 64 | hashtable->entries[i].value = value; 65 | return; 66 | } 67 | 68 | ptr = hashtable_expand(hashtable, 1); 69 | ptr->keyHash = keyHash; 70 | ptr->value = value; 71 | } 72 | 73 | int hashtable_get(hashtable_t *hashtable, void *key, void **value) 74 | { 75 | int keyHash = hashtable->hash(key, hashtable->len(key)); 76 | int i; 77 | 78 | if ((i = hashtable_find(hashtable, keyHash)) != -1) 79 | { 80 | if (value) 81 | *value = hashtable->entries[i].value; 82 | 83 | return 1; 84 | } 85 | 86 | return 0; 87 | } 88 | 89 | void hashtable_remove(hashtable_t *hashtable, void *key) 90 | { 91 | int keyHash = hashtable->hash(key, hashtable->len(key)); 92 | int i; 93 | 94 | if ((i = hashtable_find(hashtable, keyHash)) != -1) 95 | { 96 | int totalLen = (hashtable->entry_count - i) * sizeof(hashtableentry_t); 97 | 98 | if (totalLen > 0) 99 | memcpy(&hashtable->entries[i], &hashtable->entries[i + 1], totalLen); 100 | 101 | hashtable_expand(hashtable, -1); 102 | } 103 | } 104 | 105 | int hashtable_count(hashtable_t *hashtable) 106 | { 107 | return hashtable->entry_count; 108 | } 109 | 110 | void hashtable_clear(hashtable_t *hashtable) 111 | { 112 | if (hashtable->entries) 113 | { 114 | free(hashtable->entries); 115 | hashtable->entries = NULL; 116 | } 117 | 118 | hashtable->entry_count = 0; 119 | } 120 | 121 | int hashtable_hash_fnv(void *key, int size) 122 | { 123 | unsigned int hval = 0x811c9dc5; 124 | unsigned char *bp = (unsigned char *)key; 125 | unsigned char *be = bp + size; 126 | 127 | while (bp < be) 128 | { 129 | hval += (hval << 1) + (hval << 4) + (hval << 7) + (hval << 8) + (hval << 24); 130 | hval ^= (unsigned int)*bp++; 131 | } 132 | 133 | return (int)hval; 134 | } 135 | -------------------------------------------------------------------------------- /example-code/C Hash Table/hashtable.h: -------------------------------------------------------------------------------- 1 | #ifndef HASHTABLE_H 2 | #define HASHTABLE_H 3 | 4 | #ifdef __cplusplus 5 | extern "C" 6 | { 7 | #endif 8 | 9 | typedef int (*hashtable_hash_function)(void *key, int size); 10 | typedef int (*hashtable_len_function)(void *key); 11 | 12 | typedef struct 13 | { 14 | int keyHash; 15 | void *value; 16 | } hashtableentry_t; 17 | 18 | typedef struct 19 | { 20 | hashtableentry_t *entries; 21 | 22 | hashtable_hash_function hash; 23 | hashtable_len_function len; 24 | 25 | int entry_count; 26 | } hashtable_t; 27 | 28 | // Hashtable functions 29 | void hashtable_init(hashtable_t *hashtable, hashtable_hash_function hash, hashtable_len_function len); 30 | void hashtable_destroy(hashtable_t *hashtable); 31 | 32 | void hashtable_set(hashtable_t *hashtable, void *key, void *value); 33 | int hashtable_get(hashtable_t *hashtable, void *key, void **value); 34 | void hashtable_remove(hashtable_t *hashtable, void *key); 35 | 36 | int hashtable_count(hashtable_t *hashtable); 37 | void hashtable_clear(hashtable_t *hashtable); 38 | 39 | // General hash functions 40 | int hashtable_hash_fnv(void *key, int size); 41 | 42 | #ifdef __cplusplus 43 | } 44 | #endif 45 | 46 | #endif 47 | -------------------------------------------------------------------------------- /example-code/C Hash Table/main.c: -------------------------------------------------------------------------------- 1 | #include "hashtable.h" 2 | 3 | #include 4 | #include 5 | 6 | void do_tbl_print(hashtable_t *tbl, void *key) 7 | { 8 | void *value; 9 | 10 | if (!hashtable_get(tbl, key, &value) || value == NULL) 11 | value = "NULL"; 12 | 13 | printf("%s: %s\n", key, value); 14 | } 15 | 16 | int main(int argc, char **argv) 17 | { 18 | hashtable_t tbl; 19 | 20 | // init 21 | hashtable_init(&tbl, hashtable_hash_fnv, (hashtable_len_function)strlen); 22 | 23 | // populate 24 | hashtable_set(&tbl, "fulano", "32"); 25 | hashtable_set(&tbl, "ciclano", "64"); 26 | hashtable_set(&tbl, "derp", "herp"); 27 | hashtable_set(&tbl, "herp", "derp"); 28 | 29 | // retrieve pass 1 30 | printf("Pass 1:\n"); 31 | do_tbl_print(&tbl, "fulano"); 32 | do_tbl_print(&tbl, "ciclano"); 33 | do_tbl_print(&tbl, "derp"); 34 | do_tbl_print(&tbl, "herp"); 35 | printf("\n"); 36 | 37 | // remove some 38 | hashtable_remove(&tbl, "fulano"); 39 | 40 | // retrive pass 2 41 | printf("Pass 2:\n"); 42 | do_tbl_print(&tbl, "fulano"); 43 | do_tbl_print(&tbl, "ciclano"); 44 | do_tbl_print(&tbl, "derp"); 45 | do_tbl_print(&tbl, "herp"); 46 | printf("\n"); 47 | 48 | // remove some 49 | hashtable_remove(&tbl, "herp"); 50 | 51 | // retrive pass 3 52 | printf("Pass 3:\n"); 53 | do_tbl_print(&tbl, "fulano"); 54 | do_tbl_print(&tbl, "ciclano"); 55 | do_tbl_print(&tbl, "derp"); 56 | do_tbl_print(&tbl, "herp"); 57 | printf("\n"); 58 | 59 | // clear 60 | hashtable_clear(&tbl); 61 | 62 | // retrive pass 4 63 | printf("Pass 4:\n"); 64 | do_tbl_print(&tbl, "fulano"); 65 | do_tbl_print(&tbl, "ciclano"); 66 | do_tbl_print(&tbl, "derp"); 67 | do_tbl_print(&tbl, "herp"); 68 | printf("\n"); 69 | 70 | // destroy 71 | hashtable_destroy(&tbl); 72 | 73 | getchar(); 74 | 75 | return 0; 76 | } 77 | -------------------------------------------------------------------------------- /example-code/RedBlack.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #define RED 1 5 | #define BLACK 2 6 | 7 | struct node { 8 | int key; 9 | struct node *left, *right, *p; 10 | int color; 11 | }; 12 | 13 | typedef struct node *NODEPTR; 14 | struct node NIL; 15 | NODEPTR NILPTR = &NIL; 16 | 17 | void inorder(NODEPTR x) { 18 | if (x != NILPTR) { 19 | inorder(x->left); 20 | printf("%d ", x->key); 21 | inorder(x->right); 22 | } 23 | } 24 | 25 | NODEPTR search(NODEPTR root, int k) { 26 | if (root == NILPTR || root->key == k) 27 | return root; 28 | if (k < root->key) 29 | return search(root->left, k); 30 | else 31 | return search(root->right, k); 32 | } 33 | 34 | NODEPTR minimum(NODEPTR root) { 35 | while (root->left != NILPTR) 36 | root = root->left; 37 | return root; 38 | } 39 | 40 | NODEPTR maximum(NODEPTR root) { 41 | while (root->right != NILPTR) 42 | root = root->right; 43 | return root; 44 | } 45 | 46 | NODEPTR successor(NODEPTR root, int x) { 47 | NODEPTR temp = search(root, x); 48 | if (temp == NILPTR) { 49 | printf("%d not in tree\n", x); 50 | return temp; 51 | } 52 | if (temp->right != NILPTR) 53 | return minimum(temp->right); 54 | NODEPTR y = temp->p; 55 | while (y != NILPTR && temp == y->right) { 56 | temp = y; 57 | y = y->p; 58 | } 59 | return y; 60 | } 61 | 62 | NODEPTR predecessor(NODEPTR root, int x) { 63 | NODEPTR temp = search(root, x); 64 | if (temp == NILPTR) { 65 | printf("%d not in tree\n", x); 66 | return temp; 67 | } 68 | if (temp->left != NILPTR) 69 | return maximum(temp->left); 70 | NODEPTR y = temp->p; 71 | while (y != NILPTR && temp == y->left) { 72 | temp = y; 73 | y = y->p; 74 | } 75 | return y; 76 | } 77 | void leftrotate(NODEPTR *treeroot, NODEPTR x) { 78 | NODEPTR y = x->right; 79 | x->right = y->left; 80 | if (y->left != NILPTR) 81 | y->left->p = x; 82 | y->p = x->p; 83 | if (x->p == NILPTR) 84 | *treeroot = y; 85 | else if (x->p->left == x) 86 | x->p->left = y; 87 | else 88 | x->p->right = y; 89 | y->left = x; 90 | x->p = y; 91 | } 92 | 93 | void rightrotate(NODEPTR *treeroot, NODEPTR y) { 94 | NODEPTR x = y->left; 95 | y->left = x->right; 96 | if (x->right != NILPTR) 97 | x->right->p = y; 98 | x->p = y->p; 99 | if (y->p == NILPTR) 100 | *treeroot = x; 101 | else if (y->p->left == y) 102 | y->p->left = x; 103 | else 104 | y->p->right = x; 105 | x->right = y; 106 | y->p = x; 107 | } 108 | 109 | void rbinsertfixup(NODEPTR *treeroot, NODEPTR z) { 110 | while (z->p->color == RED) { 111 | if (z->p == z->p->p->left) { 112 | NODEPTR y = z->p->p->right; 113 | if (y->color == RED) { 114 | z->p->color = BLACK; 115 | y->color = BLACK; 116 | z->p->p->color = RED; 117 | z = z->p->p; 118 | } 119 | else { 120 | if (z == z->p->right) { 121 | z = z->p; 122 | leftrotate(treeroot,z); 123 | } 124 | z->p->color = BLACK; 125 | z->p->p->color = RED; 126 | rightrotate(treeroot,z->p->p); 127 | } 128 | } 129 | else { 130 | NODEPTR y = z->p->p->left; 131 | if (y->color == RED) { 132 | z->p->color = BLACK; 133 | y->color = BLACK; 134 | z->p->p->color = RED; 135 | z = z->p->p; 136 | } 137 | else { 138 | if (z == z->p->left) { 139 | z = z->p; 140 | rightrotate(treeroot,z); 141 | } 142 | z->p->color = BLACK; 143 | z->p->p->color = RED; 144 | leftrotate(treeroot,z->p->p); 145 | } 146 | } 147 | } 148 | (*treeroot)->color = BLACK; 149 | } 150 | 151 | void rbinsert(NODEPTR *treeroot, int z) { 152 | NODEPTR Z = (NODEPTR) malloc(sizeof(struct node)); 153 | Z->key = z; 154 | NODEPTR y = NILPTR; 155 | NODEPTR x = *treeroot; 156 | while (x != NILPTR) { 157 | y = x; 158 | if (Z->key < x->key) 159 | x = x->left; 160 | else 161 | x = x->right; 162 | } 163 | Z->p = y; 164 | if (y == NILPTR) 165 | *treeroot = Z; 166 | else if (Z->key < y->key) 167 | y->left = Z; 168 | else 169 | y->right = Z; 170 | Z->left = NILPTR; 171 | Z->right = NILPTR; 172 | Z->color = RED; 173 | rbinsertfixup(treeroot,Z); 174 | } 175 | 176 | void rbtransplant(NODEPTR *treeroot, NODEPTR u, NODEPTR v) { 177 | if (u->p == NILPTR) 178 | *treeroot = v; 179 | else if (u == u->p->left) 180 | u->p->left = v; 181 | else 182 | u->p->right = v; 183 | v->p = u->p; 184 | } 185 | 186 | void rbdeletefixup(NODEPTR *treeroot, NODEPTR x) { 187 | while (x != *treeroot && x->color == BLACK) { 188 | if (x == x->p->left) { 189 | NODEPTR w = x->p->right; 190 | if (w->color == RED) { 191 | w->color = BLACK; 192 | x->p->color = RED; 193 | leftrotate(treeroot,x->p); 194 | w = x->p->right; 195 | } 196 | if (w->left->color == BLACK && w->right->color == BLACK) { 197 | w->color = RED; 198 | x = x->p; 199 | } 200 | else { 201 | if (w->right->color == BLACK) { 202 | w->left->color = BLACK; 203 | w->color = RED; 204 | rightrotate(treeroot,w); 205 | w = x->p->right; 206 | } 207 | w->color = x->p->color; 208 | x->p->color = BLACK; 209 | w->right->color = BLACK; 210 | leftrotate(treeroot,x->p); 211 | x = *treeroot; 212 | } 213 | } 214 | else { 215 | NODEPTR w = x->p->left; 216 | if (w->color == RED) { 217 | w->color = BLACK; 218 | x->p->color = RED; 219 | rightrotate(treeroot,x->p); 220 | w = x->p->left; 221 | } 222 | if (w->left->color == BLACK && w->right->color == BLACK) { 223 | w->color = RED; 224 | x = x->p; 225 | } 226 | else { 227 | if (w->left->color == BLACK) { 228 | w->right->color = BLACK; 229 | w->color = RED; 230 | leftrotate(treeroot,w); 231 | w = x->p->left; 232 | } 233 | w->color = x->p->color; 234 | x->p->color = BLACK; 235 | w->left->color = BLACK; 236 | rightrotate(treeroot,x->p); 237 | x = *treeroot; 238 | } 239 | } 240 | } 241 | x->color = BLACK; 242 | } 243 | 244 | void rbdelete(NODEPTR *treeroot, int z) { 245 | NODEPTR Z = search(*treeroot, z); 246 | if (Z == NILPTR) { 247 | printf("Node to be deleted not found\n"); 248 | return; 249 | } 250 | NODEPTR y = Z; 251 | int yoc = y->color; 252 | NODEPTR x; 253 | if (Z->left == NILPTR) { 254 | x = Z->right; 255 | rbtransplant(treeroot,Z,Z->right); 256 | } 257 | else if (Z->right == NILPTR) { 258 | x = Z->left; 259 | rbtransplant(treeroot,Z,Z->left); 260 | } 261 | else { 262 | y = minimum(Z->right); 263 | yoc = y->color; 264 | x = y->right; 265 | if (y->p == Z) 266 | x->p = y; 267 | else { 268 | rbtransplant(treeroot,y,y->right); 269 | y->right = Z->right; 270 | y->right->p = y; 271 | } 272 | rbtransplant(treeroot,Z,y); 273 | y->left = Z->left; 274 | y->left->p = y; 275 | y->color = Z->color; 276 | } 277 | if (yoc == BLACK) 278 | rbdeletefixup(treeroot,x); 279 | } 280 | 281 | int main() 282 | { 283 | NIL.left = NIL.right = NIL.p = NILPTR; 284 | NIL.color = BLACK; 285 | NODEPTR tree = NILPTR; 286 | int n; 287 | while (1) { 288 | printf("1.Insert\n2.Search\n3.Inorder Walk\n4.Minimum\n5.Maximum\n6.Successor\n7.Predecessor\n8.Delete\n9.Exit\n"); 289 | scanf("%d", &n); 290 | if (n == 1) { 291 | printf("Enter any number:\n"); 292 | int num; 293 | scanf("%d", &num); 294 | rbinsert(&tree, num); 295 | } 296 | else if (n == 2) { 297 | printf("Enter the number to be search\n"); 298 | int num; 299 | scanf("%d", &num); 300 | if (search(tree, num) == NILPTR) 301 | printf("%d not found\n", num); 302 | else 303 | printf("%d found\n", num); 304 | } 305 | else if (n == 3) { 306 | inorder(tree); 307 | printf("\n"); 308 | } 309 | else if (n == 4) 310 | printf("%d\n", minimum(tree)->key); 311 | else if (n == 5) 312 | printf("%d\n", maximum(tree)->key); 313 | else if (n == 6) { 314 | printf("Enter the number whose successor needs to be found\n"); 315 | int num; 316 | scanf("%d", &num); 317 | NODEPTR t = successor(tree, num); 318 | if (t != NULL) 319 | printf("%d\n", t->key); 320 | } 321 | else if (n == 7) { 322 | printf("Enter the number whose predecessor needs to be found\n"); 323 | int num; 324 | scanf("%d", &num); 325 | NODEPTR t = predecessor(tree, num); 326 | if (t != NULL) 327 | printf("%d\n", t->key); 328 | } 329 | else if (n == 8) { 330 | printf("Enter the number to be deleted\n"); 331 | int num; 332 | scanf("%d", &num); 333 | rbdelete(&tree, num); 334 | } 335 | else 336 | break; 337 | } 338 | return 0; 339 | } 340 | -------------------------------------------------------------------------------- /friends-homework/CharleneSquare3.java: -------------------------------------------------------------------------------- 1 | public class Square3 { 2 | public static void main(String[] args) { 3 | int length = Integer.parseInt(args[0]); 4 | int x = Integer.parseInt(args[1]); 5 | int y = Integer.parseInt(args[2]); 6 | 7 | boolean inyaxis = true; 8 | 9 | while(inyaxis) { 10 | for (int yaxis = 15; yaxis>=0; yaxis--) { 11 | if (yaxis==15) { 12 | System.out.println("^"); 13 | } 14 | else if(yaxis==length-1){ 15 | for(int c=1; c<=length; c++){ 16 | System.out.print("|"); 17 | for(int d=0; dlength-1){ 39 | for(int j=1; j<=15-length-y; j++){ 40 | System.out.println("|"); 41 | } 42 | yaxis=length; 43 | } 44 | } 45 | } 46 | //x-axis 47 | for(int xaxis = 0; xaxis<=17; xaxis++){ 48 | if(xaxis==0){ 49 | System.out.print("+"); 50 | } 51 | else if(xaxis<16){ 52 | System.out.print("-"); 53 | } 54 | else if(xaxis==16 && x+length<=15){ 55 | System.out.println(">"); 56 | break; 57 | } 58 | else if(xaxis==16 && x+length>15){ 59 | for(int h=1; h<=length; h++){ 60 | System.out.print("-"); 61 | if(h==length){ 62 | System.out.println(">"); 63 | } 64 | } 65 | break; 66 | } 67 | } 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /friends-homework/CharleneSquare4.java: -------------------------------------------------------------------------------- 1 | public class Square4 { 2 | public static void main(String[] args) { 3 | int length = Integer.parseInt(args[0]) - 1; 4 | int x = Integer.parseInt(args[1]); 5 | int y = Integer.parseInt(args[2]); 6 | 7 | boolean inyaxis = true; 8 | 9 | // Stage 0. make sure the numbers are valid 10 | 11 | if (x < 0 || y < 0) { 12 | System.out.println("Numbers are invalid, you idiot! Only give starting co-ordinates > 0."); 13 | return; 14 | } 15 | 16 | // Stage 1. decide how big to make the grid to fit our square 17 | 18 | int gridSizeX = 15; 19 | int gridSizeY = 15; 20 | 21 | if (x+length > gridSizeX) { 22 | gridSizeX = x + length; 23 | } 24 | 25 | if (y+length > gridSizeY) { 26 | gridSizeY = y + length; 27 | } 28 | 29 | // Stage 3. Draw the top line of the grid (which is just a little arrow) 30 | System.out.println("^"); 31 | 32 | 33 | // Stage 4. Draw the body of the grid, from top down, left to right 34 | 35 | // start drawing top-down 36 | for (int currentY = gridSizeY; currentY >= 0; currentY--) { 37 | System.out.print("|"); 38 | for (int currentX = 0; currentX <= gridSizeX; currentX++) { 39 | // As we're moving our cursor from top-down left to right 40 | // we decide when to start drawing #'s and when to draw blank spaces 41 | 42 | // if we're lower than the top of the square, and higher than the bottom and 43 | // if we're to the right of the leftmost edge, and to the left of the rightmost edge 44 | if ((currentY <= y+length && currentY >= y) && (currentX >= x && currentX <= x+length)) { 45 | System.out.print("#"); // draw #s 46 | } 47 | else { 48 | System.out.print(" "); // otherwise, we're not inside the bounds of the square, so we just draw empty space as a placeholder 49 | } 50 | } 51 | System.out.println(""); // end the row with a new line 52 | } 53 | 54 | // Stage 5. Draw the bottom x axis, from left to right 55 | System.out.print("+"); 56 | for (int currentX = 0; currentX <= gridSizeX; currentX++) { 57 | System.out.print("-"); 58 | } 59 | System.out.println(">"); 60 | 61 | return; 62 | }; 63 | }; 64 | -------------------------------------------------------------------------------- /friends-homework/JonahMusicReader.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using namespace std; 5 | 6 | const string MUSIC_FOLDER = "/Users/squash/Desktop/Music"; 7 | 8 | 9 | // Helpers 10 | string get_user_input(string prompt) { 11 | cout << "[?] " << prompt; 12 | string input_str; 13 | getline(cin, input_str); 14 | return input_str; 15 | } 16 | 17 | bool folder_exists(string path) { 18 | return opendir(path.c_str()) != NULL; 19 | } 20 | 21 | void list_directory_contents(string path) { 22 | struct dirent *pent = NULL; 23 | DIR* pdir = opendir(path.c_str()); 24 | 25 | // iterate through all files in directory and print to cout 26 | while ((pent = (readdir(pdir)))) { 27 | if (pent == NULL) 28 | cout << "[X] Error occured while initializing pent info" << endl; 29 | 30 | string row = pent->d_name; 31 | 32 | if (row != "." && row != ".." && row != ".DS_Store") 33 | cout << pent->d_name << endl; 34 | } 35 | cout << endl; 36 | } 37 | 38 | void list_all_in_subdirectories(string path) { 39 | struct dirent *pent = NULL; 40 | DIR* pdir = opendir(path.c_str()); 41 | 42 | // iterate through all files in directory 43 | while ((pent = (readdir(pdir)))) { 44 | if (pent == NULL) 45 | cout << "[X] Error occured while initializing pent info" << endl; 46 | 47 | string row = pent->d_name; 48 | 49 | // for each subfolder, pass to list_dir_cont to print its contents 50 | if (row != "." && row != ".." && row != ".DS_Store") 51 | list_directory_contents(path + "/" + row); 52 | } 53 | } 54 | 55 | 56 | // Output printing 57 | void display_artists(string musicdir) { 58 | cout << "[i] Artists: " << endl; 59 | list_directory_contents(musicdir); 60 | } 61 | 62 | void display_albums(string musicdir, string artist_name) { 63 | cout << "[i] Albums by " << artist_name << ": " << endl; 64 | list_directory_contents(musicdir + "/" + artist_name); 65 | } 66 | 67 | void display_songs(string musicdir, string artist_name, string album_name) { 68 | if (album_name == "ALL") { 69 | cout << "[i] All songs by " << artist_name << ": " << endl; 70 | list_all_in_subdirectories(musicdir + "/" + artist_name); 71 | } else { 72 | cout << "[i] Songs by " << artist_name << " in " << album_name << ": " << endl; 73 | list_directory_contents(musicdir + "/" + artist_name + "/" + album_name); 74 | } 75 | } 76 | 77 | 78 | int main(int argc, const char* argv[]) { 79 | DIR* pdir = opendir(MUSIC_FOLDER.c_str()); 80 | if (pdir == NULL) { 81 | cout << "[X] Cannot find music directory: " << MUSIC_FOLDER << endl; 82 | return 1; 83 | } 84 | 85 | struct dirent *pent = NULL; 86 | 87 | display_artists(MUSIC_FOLDER); 88 | string chosen_artist = get_user_input( 89 | "Enter the artist you would like to listen to: "); 90 | 91 | if (!folder_exists(MUSIC_FOLDER + "/" + chosen_artist)) { 92 | cout << "[X] That artist doesn't exist!" << endl; 93 | return 1; 94 | } 95 | 96 | display_albums(MUSIC_FOLDER, chosen_artist); 97 | string chosen_album = get_user_input( 98 | "Enter the album you would like to listen to, or ALL for all songs: "); 99 | 100 | if (chosen_album != "ALL" && 101 | !folder_exists(MUSIC_FOLDER + "/" + chosen_artist + "/" + chosen_album)) { 102 | cout << "[X] That album doesn't exist!" << endl; 103 | return 1; 104 | } 105 | 106 | display_songs(MUSIC_FOLDER, chosen_artist, chosen_album); 107 | 108 | closedir(pdir); 109 | cout << "[√] Done!" << endl; 110 | return 0; 111 | } 112 | -------------------------------------------------------------------------------- /friends-homework/LanguageFamilyNode.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pirate/Cpp-Data-Structures/901b0e867980fc78cd9717a333df0c149afbc12b/friends-homework/LanguageFamilyNode.class -------------------------------------------------------------------------------- /friends-homework/LanguageFamilyNode.java: -------------------------------------------------------------------------------- 1 | import java.util.HashMap; 2 | import java.util.ArrayList; 3 | import java.util.Scanner; 4 | import java.io.*; 5 | 6 | public class LanguageFamilyNode { 7 | private String name; 8 | private ArrayList children; 9 | 10 | // name getter 11 | public String getName() { 12 | return name; 13 | } 14 | 15 | // children setter 16 | public void addChild(LanguageFamilyNode child) { 17 | children.add(child); 18 | } 19 | 20 | public void printAllDescendants() { 21 | // for each child in the list of children 22 | for (LanguageFamilyNode child : children) { 23 | // print the child's name, then print all of its chilren, indented slightly further 24 | System.out.println(child.getName()); 25 | child.printAllDescendants(" "); 26 | } 27 | } 28 | 29 | // overloaded to accept a prefix 30 | public void printAllDescendants(String prefix) { 31 | for (LanguageFamilyNode child : children) { 32 | System.out.println(prefix + child.getName()); 33 | // same as above but append the passed-in prefix to the usual two space4s 34 | child.printAllDescendants(" " + prefix); 35 | } 36 | } 37 | 38 | // constuctor 39 | public LanguageFamilyNode(String nodeName) { 40 | name = nodeName; 41 | // initialize children to an empty list 42 | children = new ArrayList(); 43 | } 44 | 45 | public static void main(String[] args) { 46 | // generate a few nodes, set up their higherarchy, then tell root to print its children 47 | System.out.println("Generating LanguageFamilyNode nodes..."); 48 | LanguageFamilyNode root = new LanguageFamilyNode("Germanic languages"); 49 | LanguageFamilyNode l1child1 = new LanguageFamilyNode("Germanic languages1"); 50 | LanguageFamilyNode l1child2 = new LanguageFamilyNode("Germanic languages2"); 51 | LanguageFamilyNode l1child3 = new LanguageFamilyNode("Germanic languages3"); 52 | LanguageFamilyNode l2child1 = new LanguageFamilyNode("English Family"); 53 | LanguageFamilyNode l3child1 = new LanguageFamilyNode("English"); 54 | 55 | System.out.println("Arranging higherarchy..."); 56 | l2child1.addChild(l3child1); 57 | l1child1.addChild(l2child1); 58 | root.addChild(l1child1); 59 | root.addChild(l1child2); 60 | root.addChild(l1child3); 61 | 62 | System.out.println("Finished tree:"); 63 | System.out.println(); 64 | root.printAllDescendants(" "); 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /friends-homework/LanguageLearner.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pirate/Cpp-Data-Structures/901b0e867980fc78cd9717a333df0c149afbc12b/friends-homework/LanguageLearner.class -------------------------------------------------------------------------------- /friends-homework/LanguageLearner.java: -------------------------------------------------------------------------------- 1 | import java.io.*; 2 | import java.util.HashMap; 3 | import java.util.ArrayList; 4 | import java.util.Collections; 5 | 6 | public class LanguageLearner { 7 | 8 | // take a line, and break it up into a list of words 9 | private ArrayList parseWords(String line) { 10 | ArrayList wordList = new ArrayList(); 11 | 12 | // split the line by spaces, then loop through each word 13 | for (String s : line.split(" ")) { 14 | if (s != null && !s.trim().isEmpty()) { 15 | // if the word is not null or emptystring, add it to the word list 16 | wordList.add(s); 17 | } 18 | } 19 | return wordList; 20 | } 21 | 22 | // takes filepath, returns array of lines 23 | private ArrayList readFile(String filepath) { 24 | BufferedReader in = null; 25 | ArrayList lineList = new ArrayList(); 26 | // try opening the file at filepath 27 | try { 28 | in = new BufferedReader(new FileReader(filepath)); 29 | String str; 30 | // while there are more lines 31 | while ((str = in.readLine()) != null) { 32 | // add each line to the list of lines 33 | lineList.add(str); 34 | } 35 | if (in != null) { 36 | in.close(); // close the file when we're finished with it 37 | } 38 | } catch (FileNotFoundException e) { 39 | System.out.println("File not found!"); 40 | } catch (IOException e) { 41 | System.out.println("Problem opening file!"); 42 | // print the exact error that occured 43 | e.printStackTrace(); 44 | } 45 | return lineList; 46 | } 47 | 48 | // takes directoryPath, returns array of allWords in whole directory 49 | private ArrayList readDirectory(String directoryPath, int nFiles) { 50 | ArrayList allWords = new ArrayList(); 51 | // loop nFiles times 52 | for (int i=1; i<=nFiles; i++) { 53 | // use int n to create the filepath e.g. "directoryname/1.txt" 54 | String filePath = directoryPath + "/" + Integer.toString(i) + ".txt"; 55 | 56 | // for each line in the file 57 | for (String line : readFile(filePath)) { 58 | // parse out individual words, then add them all to the allWords list 59 | allWords.addAll(parseWords(line)); 60 | } 61 | } 62 | 63 | return allWords; 64 | } 65 | 66 | // return a word frequency table build from nFiles in specified directoryPath 67 | public HashMap countWords(String directoryPath, int nFiles) { 68 | HashMap wordTable = new HashMap(); 69 | 70 | // for each word in the list of all words in the directory 71 | for (String word : readDirectory(directoryPath, nFiles)) { 72 | 73 | // check if it's already in our table 74 | Integer count = wordTable.get(word); 75 | 76 | if (count == null) { 77 | // if not, add it with 1 to start 78 | wordTable.put(word, 1); 79 | } else { 80 | // if we already have it, increment the frequency by 1 81 | wordTable.put(word, count+1); 82 | } 83 | } 84 | return wordTable; 85 | } 86 | 87 | // write a frequency hashmap to a file 88 | public void writeVocabulary(HashMap wordMap, String filepath) { 89 | ArrayList sortedKeys = new ArrayList(); 90 | // turn the hashmaps keys into an array, and add them to the sortedKeys list 91 | Collections.addAll(sortedKeys, wordMap.keySet().toArray(new String[0])); 92 | 93 | // sort the list in alphabetical order 94 | Collections.sort(sortedKeys, String.CASE_INSENSITIVE_ORDER); 95 | 96 | // try creating a file and writing to it 97 | try { 98 | PrintWriter writer = new PrintWriter(filepath, "UTF-8"); 99 | // for each word in the hashmap 100 | for (String key : sortedKeys) { 101 | // write "word 123\n" where 123 is the frequency 102 | writer.println(key + " " + Integer.toString(wordMap.get(key))); 103 | } 104 | writer.close(); 105 | } catch (FileNotFoundException e) { 106 | System.out.println("Invalid output path!"); 107 | } catch (UnsupportedEncodingException e) { 108 | System.out.println("Your system is insane, it doesn't support UTF-8."); 109 | } 110 | } 111 | 112 | // print out a frequency hashmap for a human to read 113 | public void printWordTable(HashMap wordMap) { 114 | for (String key : wordMap.keySet()) { 115 | // for each key in the hashmap, print word space frequency 116 | System.out.printf("%s %d\n", key, wordMap.get(key)); 117 | } 118 | } 119 | 120 | public static void main(String[] args) { 121 | LanguageLearner langLearner = new LanguageLearner(); 122 | 123 | // generate two word frequency hashmaps, one from 20 files in docs/train/eng and one from fre 124 | System.out.println("Reading wordsets:"); 125 | HashMap english = langLearner.countWords("docs/train/eng", 20); 126 | System.out.println(" docs/train/eng - size: " + Integer.toString(english.size())); 127 | HashMap french = langLearner.countWords("docs/train/fre", 20); 128 | System.out.println(" docs/train/fre - size: " + Integer.toString(french.size())); 129 | 130 | // print out the hashmaps for testing 131 | // System.out.println("English:"); 132 | // langLearner.printWordTable(english); 133 | // System.out.println(); 134 | // System.out.println("French:"); 135 | // langLearner.printWordTable(french); 136 | 137 | // write both hashmaps to files 138 | System.out.println("Wrote two word => frequency files:"); 139 | langLearner.writeVocabulary(english, "eng_vocab.txt"); 140 | System.out.println(" eng_vocab.txt"); 141 | langLearner.writeVocabulary(french, "fre_vocab.txt"); 142 | System.out.println(" fre_vocab.txt"); 143 | } 144 | } 145 | -------------------------------------------------------------------------------- /friends-homework/LanguagePredictor.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pirate/Cpp-Data-Structures/901b0e867980fc78cd9717a333df0c149afbc12b/friends-homework/LanguagePredictor.class -------------------------------------------------------------------------------- /friends-homework/LanguagePredictor.java: -------------------------------------------------------------------------------- 1 | import java.io.*; 2 | import java.util.HashMap; 3 | import java.util.ArrayList; 4 | 5 | public class LanguagePredictor { 6 | 7 | private ArrayList parseWords(String line) { 8 | ArrayList wordList = new ArrayList(); 9 | // for each word in the line split by spaces 10 | for (String s : line.split(" ")) { 11 | if (s != null && !s.trim().isEmpty()) { 12 | // if the word is not null or emptystring, add it to the word list 13 | wordList.add(s); 14 | } 15 | } 16 | return wordList; 17 | } 18 | 19 | // takes filepath, returns array of lines 20 | private ArrayList readFile(String filepath) { 21 | BufferedReader in = null; 22 | ArrayList lineList = new ArrayList(); 23 | // try opening the file at filepath 24 | try { 25 | in = new BufferedReader(new FileReader(filepath)); 26 | String str; 27 | // while there are more lines 28 | while ((str = in.readLine()) != null) { 29 | // add each line to the list of lines 30 | lineList.add(str); 31 | } 32 | if (in != null) { 33 | in.close(); // close the file when we're finished with it 34 | } 35 | } catch (FileNotFoundException e) { 36 | System.out.println("File not found!"); 37 | } catch (IOException e) { 38 | System.out.println("Problem opening file!"); 39 | // print the exact error that occured 40 | e.printStackTrace(); 41 | } 42 | return lineList; 43 | } 44 | 45 | public HashMap readVocabulary(String fileName) { 46 | HashMap wordMap = new HashMap(); 47 | 48 | // read the word frequency file back into a hashmap 49 | for (String line : readFile(fileName)) { 50 | // split each line into word & frequency, then add it to the hashmap with word as the key, and freq as the value 51 | wordMap.put(line.split(" ")[0], Integer.parseInt(line.split(" ")[1])); 52 | } 53 | return wordMap; 54 | } 55 | 56 | // classify the document based how many of the documentWords are eng or fre 57 | public String classifyDocument(HashMap engVocab, HashMap freVocab, ArrayList documentWords) { 58 | int engWords = 0; 59 | int freWords = 0; 60 | // count english and french words 61 | for (String word : documentWords) { 62 | // if the word is in the engVocab frequency table, it's english 63 | if (engVocab.get(word) != null) { 64 | engWords++; 65 | } 66 | // if it's in the french hashmap, it's french 67 | if (freVocab.get(word) != null) { 68 | freWords++; 69 | } 70 | // used two ifs instead of else if because a word could be both valid english and french 71 | } 72 | // determine whether there are more english or french words 73 | String decision; 74 | if (engWords > freWords) { 75 | decision = "English"; 76 | } 77 | else if (engWords < freWords) { 78 | decision = "French"; 79 | } 80 | else { 81 | decision = "Tie"; 82 | } 83 | // return the classification string 84 | return "English: " + Integer.toString(engWords) + " French: " + Integer.toString(freWords) + " Decision: " + decision; 85 | } 86 | 87 | public void classifyDocuments(HashMap engVocab, HashMap freVocab, String directory, int nFiles) { 88 | // loop nFiles times 89 | for (int i=1; i<=nFiles; i++) { 90 | // use int n to create the filepath e.g. "directoryname/1.txt" 91 | String file_path = directory + "/" + Integer.toString(i) + ".txt"; 92 | 93 | ArrayList documentWords = new ArrayList(); 94 | 95 | // read the file, and for each line in the file, add all the words on that line to the documentWords list 96 | for (String line : readFile(file_path)) { 97 | documentWords.addAll(parseWords(line)); 98 | } 99 | 100 | // classify the document based how many of the documentWords are eng or fre 101 | System.out.println(Integer.toString(i) + " " + classifyDocument(engVocab, freVocab, documentWords)); 102 | } 103 | } 104 | 105 | public static void main(String[] args) { 106 | LanguagePredictor langPredictor = new LanguagePredictor(); 107 | 108 | // read the files generated by LanguageLearner back into hashmaps 109 | System.out.println("Reading word => frequency files:"); 110 | HashMap english = langPredictor.readVocabulary("eng_vocab.txt"); 111 | System.out.println(" eng_vocab.txt - size: " + Integer.toString(english.size())); 112 | HashMap french = langPredictor.readVocabulary("fre_vocab.txt"); 113 | System.out.println(" fre_vocab.txt - size: " + Integer.toString(french.size())); 114 | 115 | // classify the first 20 files in the docs/test directory using the word frequency tables 116 | System.out.println("Classifying files in docs/test:"); 117 | langPredictor.classifyDocuments(english, french, "docs/test", 20); 118 | } 119 | 120 | /***************************************************************************** 121 | Put the output of classifyDocuments here, and a sentence to describe whether 122 | your program worked. 123 | 124 | 125 | 1 English: 29 French: 11 Decision: English 126 | 2 English: 78 French: 33 Decision: English 127 | 3 English: 148 French: 67 Decision: English 128 | 4 English: 370 French: 140 Decision: English 129 | 5 English: 91 French: 43 Decision: English 130 | 6 English: 206 French: 87 Decision: English 131 | 7 English: 60 French: 30 Decision: English 132 | 8 English: 204 French: 94 Decision: English 133 | 9 English: 74 French: 39 Decision: English 134 | 10 English: 570 French: 272 Decision: English 135 | 11 English: 66 French: 390 Decision: French 136 | 12 English: 21 French: 143 Decision: French 137 | 13 English: 23 French: 62 Decision: French 138 | 14 English: 46 French: 236 Decision: French 139 | 15 English: 38 French: 141 Decision: French 140 | 16 English: 20 French: 121 Decision: French 141 | 17 English: 41 French: 218 Decision: French 142 | 18 English: 86 French: 424 Decision: French 143 | 19 English: 21 French: 157 Decision: French 144 | 20 English: 44 French: 202 Decision: French 145 | 146 | 147 | It worked exactly as expected! (after lots of debugging haha) 148 | 149 | *****************************************************************************/ 150 | } 151 | -------------------------------------------------------------------------------- /friends-homework/docs/test/1.txt: -------------------------------------------------------------------------------- 1 | Dennyloanhead (aka D.L.H.) is a village located in the Falkirk council area, Central Scotland, that is between Head of Muir and Longcroft. 2 | The main features include the Crown Hotel and Casserta's chip shop. There is another pub called the Railway Inn. 3 | Famous people born or living in Dennyloanhead include Alex Totten (ex Falkirk manager). -------------------------------------------------------------------------------- /friends-homework/docs/test/10.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pirate/Cpp-Data-Structures/901b0e867980fc78cd9717a333df0c149afbc12b/friends-homework/docs/test/10.txt -------------------------------------------------------------------------------- /friends-homework/docs/test/11.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pirate/Cpp-Data-Structures/901b0e867980fc78cd9717a333df0c149afbc12b/friends-homework/docs/test/11.txt -------------------------------------------------------------------------------- /friends-homework/docs/test/12.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pirate/Cpp-Data-Structures/901b0e867980fc78cd9717a333df0c149afbc12b/friends-homework/docs/test/12.txt -------------------------------------------------------------------------------- /friends-homework/docs/test/13.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pirate/Cpp-Data-Structures/901b0e867980fc78cd9717a333df0c149afbc12b/friends-homework/docs/test/13.txt -------------------------------------------------------------------------------- /friends-homework/docs/test/14.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pirate/Cpp-Data-Structures/901b0e867980fc78cd9717a333df0c149afbc12b/friends-homework/docs/test/14.txt -------------------------------------------------------------------------------- /friends-homework/docs/test/15.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pirate/Cpp-Data-Structures/901b0e867980fc78cd9717a333df0c149afbc12b/friends-homework/docs/test/15.txt -------------------------------------------------------------------------------- /friends-homework/docs/test/16.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pirate/Cpp-Data-Structures/901b0e867980fc78cd9717a333df0c149afbc12b/friends-homework/docs/test/16.txt -------------------------------------------------------------------------------- /friends-homework/docs/test/17.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pirate/Cpp-Data-Structures/901b0e867980fc78cd9717a333df0c149afbc12b/friends-homework/docs/test/17.txt -------------------------------------------------------------------------------- /friends-homework/docs/test/18.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pirate/Cpp-Data-Structures/901b0e867980fc78cd9717a333df0c149afbc12b/friends-homework/docs/test/18.txt -------------------------------------------------------------------------------- /friends-homework/docs/test/19.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pirate/Cpp-Data-Structures/901b0e867980fc78cd9717a333df0c149afbc12b/friends-homework/docs/test/19.txt -------------------------------------------------------------------------------- /friends-homework/docs/test/2.txt: -------------------------------------------------------------------------------- 1 | The SIG Sauer SSG 2000 is a bolt-action, magazine fed rifle. 2 | Service use[edit] 3 | The SSG 2000 sniper rifle is a joint effort by Swiss company SIG Arms (now SAN Swiss Arms) and German company J.P.Sauer & Sohn. Production of the SSG 2000 started in 1989 and it is still in production. 4 | Description[edit] 5 | The SSG 2000 is derived from the Sauer 80/90 target rifle. It has a bolt action with rotating handle, but non-rotating bolt. When the handle is rotated to close the action, six lugs are driven onwards from the rear part of the bolt body to lock into the receiver. The action also features a loaded chamber indicator. The heavy barrel is hammer-forged and has a flash hider/muzzle brake unit installed. The wooden stock is adjustable. The trigger is two-stage. 6 | The SSG 2000 has no iron sights by default and is usually fitted with Schmidt & Bender X1.5-6x42 variable power or Zeiss Diatal ZA 8x56T fixed power telescope sight. 7 | Users[edit] 8 | -------------------------------------------------------------------------------- /friends-homework/docs/test/20.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pirate/Cpp-Data-Structures/901b0e867980fc78cd9717a333df0c149afbc12b/friends-homework/docs/test/20.txt -------------------------------------------------------------------------------- /friends-homework/docs/test/3.txt: -------------------------------------------------------------------------------- 1 | David Paul Dobkin is the Dean of the Faculty and Phillip Y. Goldman '86 Professor of Computer Science at Princeton University.[1] 2 | Dobkin was born February 29, 1948, in Pittsburgh, Pennsylvania. He received a B.S. from the Massachusetts Institute of Technology in 1970 and then moved to Harvard University for his graduate studies, receiving a Ph.D. in applied mathematics in 1973 under the supervision of Roger W. Brockett. 3 | He taught at Yale University and the University of Arizona before moving to Princeton in 1981.[2] He was initially appointed to the Department of Electrical Engineering and Computer Science at Princeton and was subsequently named one of the first professors of Computer Science when that department was formed in 1985.[3] In 1999, he became the first holder of the Goldman chair after its namesake donated two million dollars to the university.[4] He was chair of the Computer Science Department at Princeton from 1994 to 2003, and in 2003 was appointed Dean of the Faculty.[3] David Dobkin also chaired the governing board of The Geometry Center, a NSF-established research and education center at the University of Minnesota.[5] 4 | His Ph.D. students have included Michael Ian Shamos, Bernard Chazelle, and Diane Souvaine.[6] 5 | Dobkin has been on the editorial boards of eight journals.[7] His research has concerned computational geometry and computer graphics, and in 1997 he was selected as a Fellow of the Association for Computing Machinery for his contributions to both fields.[8] -------------------------------------------------------------------------------- /friends-homework/docs/test/4.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pirate/Cpp-Data-Structures/901b0e867980fc78cd9717a333df0c149afbc12b/friends-homework/docs/test/4.txt -------------------------------------------------------------------------------- /friends-homework/docs/test/5.txt: -------------------------------------------------------------------------------- 1 | Forton is a village and a civil parish in the Wyre District of the English county of Lancashire near the Forest of Bowland. It is near the A6 road, between the city of Lancaster and the town of Garstang. Its population is approximately 574. It has one school, Forton Primary School, several churches and one pub, the New Holly. 2 | Lancaster (Forton) services[edit] 3 | Main article: Lancaster (Forton) services 4 | Lancaster (Forton) services is a motorway service station near Forton, between junctions 32 and 33 of the M6 motorway in England. The nearest city is Lancaster, about seven miles (11 km) to the north. The station is operated by Moto. 5 | Notable people[edit] 6 | Tom Boardman, born in Forton on 15 October 1983, is a British auto racing driver. 7 | Thomas Walmsley Price (Artist) born in Forton on 26 April 1855 8 | Transport[edit] 9 | For transport there is the A6 road and the M6 motorway which has Lancaster (Forton) services on it. -------------------------------------------------------------------------------- /friends-homework/docs/test/6.txt: -------------------------------------------------------------------------------- 1 | Broad Street, along with High Street, Wine Street and Corn Street, is one of the four original streets that have made up the city of Bristol since Saxon times, when it was the burgh of Brycgstow.[1] 2 | Prior to the building of The Exchange merchants would set up their stalls on Broad Street. An old city gate stands at the bottom of the street, where it joins Quay Street.[2] 3 | Notable Architecture[edit] 4 | Going downhill from the junction with Corn Street, other notable buildings include Christ Church with St Ewen, designed and built by William Paty in the late 18th century, a former branch of the Bank of England designed by Charles R Cockerell in Greek Doric style, the Thistle Hotel, Bristol by Foster and Wood in Italian Renaissance, the Guildhall in Gothic style by Richard Shackleton Pope and the Art Nouveau Edward Everard printing works.[3] 5 | The printing works features a mural designed by W J Neatby depicting Gutenberg and William Morris, the founders of modern printing; a woman holding objects to represent Light and Truth and the spirit of Literature. It is made from Carrara- Ware marble tiles.[3] 6 | Tailor's Court is a small side lane leading off Broad Street. Here can be seen the Merchant Tailor's Guild Hall, built in 1740.[4] This area used to be full of lawyers' offices, but is now mostly student accommodation. The churchyard of St John the Baptist has an entrance here.[5] 7 | St John's Gate[edit] 8 | 9 | St John's Gate 10 | St John's Gate, which stands at the bottom of the street, is the last remaining part of the city wall, with Church of St John the Baptist built above it. The two side passages were created in the 1820s. Niches in the wall contain the figures Brennus and Belinus, according to legend they founded the city. Nearby St John's Conduit was originally built for the friary of the Carmelites but also supplied the people of Brandon Hill. The parishioners were allowed to use only the overflow from the system, and they took advantage of this again during the blitz of World War II when water mains had been damaged.[6] -------------------------------------------------------------------------------- /friends-homework/docs/test/7.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pirate/Cpp-Data-Structures/901b0e867980fc78cd9717a333df0c149afbc12b/friends-homework/docs/test/7.txt -------------------------------------------------------------------------------- /friends-homework/docs/test/8.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pirate/Cpp-Data-Structures/901b0e867980fc78cd9717a333df0c149afbc12b/friends-homework/docs/test/8.txt -------------------------------------------------------------------------------- /friends-homework/docs/test/9.txt: -------------------------------------------------------------------------------- 1 | ARO 10 was an off-road vehicle produced by ARO and manufactured in Romania. The ARO 24 Series got a "little brother" in 1980, the ARO 10 Series. While the ARO-24 can be classified as mid-size SUVs, the ARO 10 is about the size of a Jeep Wrangler. It was produced in many body trims, equipped with seven different engines (both gas and Diesel), and came in both 4x2 and 4x4 versions.[1] The ARO 10 was sold as the Dacia Duster in some international markets and as ACM Enduro x4 in Italy (assembled by ARO-Ciemme).[1] A model derived from ARO 10, named ARO Spartana, was also produced starting 1997. The last evolution of ARO 10, produced from 1999, was called ARO 10 Super, had a slight design revamp and was built on ARO 24 Series chassis.[2] 2 | -------------------------------------------------------------------------------- /friends-homework/docs/train/eng/1.txt: -------------------------------------------------------------------------------- 1 | 'Marrigudem is a Village and Grampanchayat in Nalgonda mandal (Nalgonda district) in the Indian state of Telangana. The main source of income for the villagers is from Agriculture. The village is about 3 kilometers from Nalgonda (District Headquarters). As the village is very close to Nalgonda town, Villagers mostly depend on Dairy for livelihood. A Neighboring Village Girkabavigudem comes under Marrigudem Panchayithi election. Marrigudem Village has Government High School (Class 1 to 10). 2 | The first citizen of Marrigudem village is its Sarpanch (President) who is elected every 5 years. The village is divided into 13 wards and each ward has its ward member elected every 5 years. -------------------------------------------------------------------------------- /friends-homework/docs/train/eng/10.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pirate/Cpp-Data-Structures/901b0e867980fc78cd9717a333df0c149afbc12b/friends-homework/docs/train/eng/10.txt -------------------------------------------------------------------------------- /friends-homework/docs/train/eng/11.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pirate/Cpp-Data-Structures/901b0e867980fc78cd9717a333df0c149afbc12b/friends-homework/docs/train/eng/11.txt -------------------------------------------------------------------------------- /friends-homework/docs/train/eng/12.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pirate/Cpp-Data-Structures/901b0e867980fc78cd9717a333df0c149afbc12b/friends-homework/docs/train/eng/12.txt -------------------------------------------------------------------------------- /friends-homework/docs/train/eng/13.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pirate/Cpp-Data-Structures/901b0e867980fc78cd9717a333df0c149afbc12b/friends-homework/docs/train/eng/13.txt -------------------------------------------------------------------------------- /friends-homework/docs/train/eng/14.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pirate/Cpp-Data-Structures/901b0e867980fc78cd9717a333df0c149afbc12b/friends-homework/docs/train/eng/14.txt -------------------------------------------------------------------------------- /friends-homework/docs/train/eng/15.txt: -------------------------------------------------------------------------------- 1 | The A Day at the Races Tour was a concert tour by the British rock band Queen, and supported their late 1976 album A Day at the Races. 2 | This tour was the first to use the song "Somebody to Love" and many others. "Brighton Rock" and "Bohemian Rhapsody" were performed in full for the first time. Also, singer Freddie Mercury performed a vocal canon to segue between "White Man" and "The Prophet's Song". 3 | The opening act on most of the North American leg was Thin Lizzy. In New York City, the concert at Madison Square Garden was sold out within moments of tickets going on sale.[1] 4 | The final two shows on the tour at Earls Court was filmed and is widely traded among fans. These shows were of note as the band used an expensive lighting rig in the shape of a crown for the very first time.[2] Both shows were also officially recorded on video and the first show was also released on many bootlegs in almost excellent quality. Both gigs included a Rock 'n' Roll Medley (this medley is also the only bootleg recording from the second night). 5 | -------------------------------------------------------------------------------- /friends-homework/docs/train/eng/16.txt: -------------------------------------------------------------------------------- 1 | Aghiles Slimani (born August 20, 1982) is a retired Algerian swimmer, who specialized in butterfly events.[1] Slimani qualified for two swimming events at the 2004 Summer Olympics in Athens, by posting FINA B-standard entry times of 55.40 (100 m butterfly) and 2:03.18 (200 m butterfly) from the World Championships in Barcelona, Spain.[2][3] In the 200 m butterfly, Slimani challenged seven other swimmers in heat two, including Olympic veteran Vladan Markovic of Serbia. He raced to sixth place and thirty-first overall by 0.16 of a second behind Markovic in 2:04.93.[4][5] In his second event, 100 m butterfly, Slimani placed forty-eighth on the morning's preliminaries. Swimming in heat three, he edged out Turkey's Onur Uras to take a seventh seed by fifteen hundredths of a second (0.15) in 56.22.[6][7] -------------------------------------------------------------------------------- /friends-homework/docs/train/eng/17.txt: -------------------------------------------------------------------------------- 1 | Gianluca Bortolami (born August 28, 1968) is an Italian former professional road racing cyclist. Bortolami's greatest feats was capturing the monumental classic Tour of Flanders in 2001 and winning the 1994 UCI Road World Cup season championship. 2 | Bortolami was born in Locate di Triulzi, province of Milan. He turned professional in 1990 and rode for Lampre. He finished 75th in the 2002 Tour de France, 46th in the 1997 Tour, 13th in the 1994 Tour with one stage win, and 73rd in the 1993 Tour. He was tested positive for cortisone in 2003 during Three Days of De Panne. He was suspended for six months by the Italian cycling federation.[1] 3 | -------------------------------------------------------------------------------- /friends-homework/docs/train/eng/18.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pirate/Cpp-Data-Structures/901b0e867980fc78cd9717a333df0c149afbc12b/friends-homework/docs/train/eng/18.txt -------------------------------------------------------------------------------- /friends-homework/docs/train/eng/19.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pirate/Cpp-Data-Structures/901b0e867980fc78cd9717a333df0c149afbc12b/friends-homework/docs/train/eng/19.txt -------------------------------------------------------------------------------- /friends-homework/docs/train/eng/2.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pirate/Cpp-Data-Structures/901b0e867980fc78cd9717a333df0c149afbc12b/friends-homework/docs/train/eng/2.txt -------------------------------------------------------------------------------- /friends-homework/docs/train/eng/20.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pirate/Cpp-Data-Structures/901b0e867980fc78cd9717a333df0c149afbc12b/friends-homework/docs/train/eng/20.txt -------------------------------------------------------------------------------- /friends-homework/docs/train/eng/3.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pirate/Cpp-Data-Structures/901b0e867980fc78cd9717a333df0c149afbc12b/friends-homework/docs/train/eng/3.txt -------------------------------------------------------------------------------- /friends-homework/docs/train/eng/4.txt: -------------------------------------------------------------------------------- 1 | The Potsdam Sandstone, more formally known as the Potsdam Group, is a geologic unit of mid-to-late Cambrian age found in Northern New York and northern Vermont and Quebec and Ontario. A well-cemented sandstone of nearly pure quartz, in the 19th century it was widely used in construction and in refractory linings for iron furnaces.[8] 2 | Name and type locality[edit] 3 | 4 | Potsdam Sandstone outcrop along the Raquette River 5 | The Potsdam Sandstone is named for its type locality in Potsdam, New York, where in 1838 Ebenezer Emmons described it in outcrops along the Raquette River.[9][10] 6 | Stratigraphic setting and lithology[edit] 7 | 8 | Unconformity at the base of the Potsdam Sandstone 9 | The Potsdam Sandstone lies unconformably on a surface of Precambrian metamorphic rock. It is the earliest unit in the marine-transgressive sedimentary rock sequence deposited during the early Paleozoic as sea level rose to gradually inundate the craton of the paleocontinent of Laurentia.[10][11][12] The rock, which is formed from sediments eroded off unvegetated terrestrial landscapes and deposited in near-shore coastal environments,[13] consists almost entirely of sand-size quartz grains held together by quartz cement.[8][11] It ranges in color from gray to tan, yellow, and red, with the colors imparted by small amounts of the red iron oxide mineral hematite, Fe2O3, and the yellow iron oxide mineral goethite, FeO(OH).[8] 10 | As sea level rose in the depositional environment, increasing amounts of carbonate minerals were deposited in the sediment, with the result that the unit grades upward into dolomitic sandstone in the upper Potsdam and then to sandy dolostone at the base of the overlying Theresa Formation.[8][12][14] 11 | Paleontology[edit] 12 | 13 | Protichnites in the lower Potsdam Sandstone. 14 | 15 | Diplocraterion in the upper Potsdam Sandstone. 16 | Fossil remains of whole animals are rare in the Potsdam Sandstone, but there are some significant occurrences of trace fossils. Trace fossils in the unit include both vertical burrows, such as Diplocraterion and Skolithos and horizontal trackways, such as Diplichnites, Protichnites, and Climactichnites.[11][15] In 1903, a 20-ton (18-tonne) slab of Potsdam Sandstone from Clinton County, New York, displaying tracks attributed to trilobites, was placed in the New York State Museum.[16] Fossil impressions of the whole bodies of jellyfish have also been found in the Potsdam.[11] 17 | Geographic occurrence[edit] 18 | In New York state, the Potsdam is found primarily north and west of the Adirondack Mountains. Outcrop exposures of the Potsdam Sandstone occur throughout the Saint Lawrence lowlands, western Lake Champlain Valley, and northern Mohawk Valley. Ausable Chasm, near Plattsburgh, has a continuous exposure of a section more than 160 metres (520 ft) thick.[11] The formation reaches its maximum thickness of about 450 metres (1,480 ft) in the northern Champlain lowland.[12] 19 | Uses in construction and industry[edit] 20 | In the 19th century, Potsdam Sandstone was highly regarded as a building material. There was extensive quarrying for Potsdam Sandstone in the Potsdam area, beginning in 1809.[3][8][17][18] Properties of the rock that give it value as a building material include high compressive strength, attractive reddish coloring, and resistance to weathering.[8][17][18] The rock also was said to be "soft and easy to carve" when freshly quarried but "extremely hard" and "weather-resistant" after exposure to the air, but modern geologists suggest that this is a misconception.[8][18] Potsdam Sandstone resists spalling when exposed to fire, making it highly suitable for use as a refractory for lining iron furnaces.[8][17] 21 | Local sandstone was used for many buildings in Potsdam, as well as for purposes such as gravestones and sidewalks.[3][18][19] Buildings in other cities constructed with this rock include Canada's House of Parliament in Ottawa, and the Cathedral of All Saints in Albany, New York.[18] Potsdam Sandstone and its stratigraphic equivalents also have been quarried for use as building stone at several sites in Quebec.[20] 22 | Stratigraphic equivalents and related units[edit] 23 | Stratigraphically equivalent and lithologically similar sandstone extends across the international border into Canada, although stratigraphic boundaries and nomenclature can differ.[11][12] In Ontario, the Nepean Sandstone was formerly called "Potsdam" and is regarded as a stratigraphic equivalent to the Potsdam Sandstone.[21][22][23] In Quebec, the Potsdam Group is recognized, consisting of the Covey Hill Formation and the Cairnside Formation, both of which are sandstones.[12] 24 | Historically the name "Potsdam sandstone" was also applied to various other North American sandstone bodies that directly overlie Precambrian crystalline rocks, including sandstones in Canada, Pennsylvania, Virginia, Iowa, Wisconsin, Minnesota, Michigan, and Indiana, and attempts were made to identify or correlate various rocks with the Potsdam formation.[23][24][25] The basal Cambrian sandstone formation in much of the upper Mississippi Valley and southern Great Lakes region is now designated the Mount Simon Sandstone and is, in turn, assigned to the Potsdam Supergroup, which takes its name from the Potsdam Sandstone.[24] Similar quartz arenite sandstone found in Wyoming was also identified historically as the "Potsdam sandstone."[25][26] -------------------------------------------------------------------------------- /friends-homework/docs/train/eng/5.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pirate/Cpp-Data-Structures/901b0e867980fc78cd9717a333df0c149afbc12b/friends-homework/docs/train/eng/5.txt -------------------------------------------------------------------------------- /friends-homework/docs/train/eng/6.txt: -------------------------------------------------------------------------------- 1 | The Laestrygonians (or Laestrygones, Laistrygones, Laistrygonians, Lestrygonians) are a tribe of giant cannibals from ancient Greek mythology. 2 | Mythology[edit] 3 | Odysseus, the main character of Homer's Odyssey, visited them during his journey back home to Ithaca. The giants ate many of Odysseus' men and destroyed eleven of his twelve ships by launching rocks from high cliffs. Odysseus' ship was not destroyed as it was hidden in a cove near shore. Everyone on Odysseus' ship survived the incident.[1] 4 | His soldiers, with a dozen ships, arrive at "the rocky stronghold of Lamos: Telepylus, the city of the Laestrygonians. 5 | Lamos is not mentioned again, perhaps being understood as the founder of the city or the name of the island on which the city is situated. In this land, a man who could do without sleep could earn double wages; once as a herdsman of cattle and another as a shepherd, as they worked by night as they did by day. The ships entered a harbor surrounded by steep cliffs, with a single entrance between two headlands. The captains took their ships inside and made them fast close to one another, where it was dead calm. 6 | Odysseus kept his own ship outside the harbor, moored to a rock. He climbed a high rock to reconnoiter, but could see nothing but some smoke rising from the ground. He sent two of his company and an attendant to investigate the inhabitants. The men followed a road and eventually met a young woman on her way to the Fountain of Artakia to fetch some water, who said she was a daughter of Antiphates, the king, and directed them to his house. However when they got there they found a gigantic woman, the wife of Antiphates who promptly called her husband, who immediately left the assembly of the people and upon arrival snatched up one of the men and killed him on the spot, presumably then drinking his blood (as it states in the Odyssey that he only met with the men with the intention of drinking their blood). The other two men, Eurylochus and Polites, ran away, but Antiphates raised an outcry, so that they were pursued by thousands of Laestrygonians, who are either giants or very large men and women. They threw vast rocks from the cliffs, smashing the ships, and speared the men like fish. Odysseus made his escape with his single ship due to the fact that it was not trapped in the harbor; the rest of his company was lost. The surviving crew went next to Aiaia, the island of Circe. 7 | Later Greeks believed that the Laestrygonians, as well as the Cyclopes, had once inhabited Sicily.[2][3] -------------------------------------------------------------------------------- /friends-homework/docs/train/eng/7.txt: -------------------------------------------------------------------------------- 1 | Oenothera pubescens, known commonly as the South American evening-primrose, is a plant in the evening primrose family native to the Southwestern U.S. (southeastern California, Arizona, New Mexico, and western Texas.) and Mexico; Meso- (Guatemala) and Western South America (Colombia, Ecuador, and Peru). It is used locally in folk medicine.[1] -------------------------------------------------------------------------------- /friends-homework/docs/train/eng/8.txt: -------------------------------------------------------------------------------- 1 | Edward "Eddie" Gleeson (born 1920) is an Irish retired hurler who played as a left corner-forward for the Tipperary senior team. 2 | Gleeson made his first appearance for the team during the 1945 championship and was a regular member of the starting fifteen for just two full seasons. During that time he won one All-Ireland medal and one Munster medal.[1][2] 3 | At club level Gleeson played with Thurles Sarsfields. -------------------------------------------------------------------------------- /friends-homework/docs/train/eng/9.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pirate/Cpp-Data-Structures/901b0e867980fc78cd9717a333df0c149afbc12b/friends-homework/docs/train/eng/9.txt -------------------------------------------------------------------------------- /friends-homework/docs/train/fre/1.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pirate/Cpp-Data-Structures/901b0e867980fc78cd9717a333df0c149afbc12b/friends-homework/docs/train/fre/1.txt -------------------------------------------------------------------------------- /friends-homework/docs/train/fre/10.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pirate/Cpp-Data-Structures/901b0e867980fc78cd9717a333df0c149afbc12b/friends-homework/docs/train/fre/10.txt -------------------------------------------------------------------------------- /friends-homework/docs/train/fre/11.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pirate/Cpp-Data-Structures/901b0e867980fc78cd9717a333df0c149afbc12b/friends-homework/docs/train/fre/11.txt -------------------------------------------------------------------------------- /friends-homework/docs/train/fre/12.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pirate/Cpp-Data-Structures/901b0e867980fc78cd9717a333df0c149afbc12b/friends-homework/docs/train/fre/12.txt -------------------------------------------------------------------------------- /friends-homework/docs/train/fre/13.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pirate/Cpp-Data-Structures/901b0e867980fc78cd9717a333df0c149afbc12b/friends-homework/docs/train/fre/13.txt -------------------------------------------------------------------------------- /friends-homework/docs/train/fre/14.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pirate/Cpp-Data-Structures/901b0e867980fc78cd9717a333df0c149afbc12b/friends-homework/docs/train/fre/14.txt -------------------------------------------------------------------------------- /friends-homework/docs/train/fre/15.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pirate/Cpp-Data-Structures/901b0e867980fc78cd9717a333df0c149afbc12b/friends-homework/docs/train/fre/15.txt -------------------------------------------------------------------------------- /friends-homework/docs/train/fre/16.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pirate/Cpp-Data-Structures/901b0e867980fc78cd9717a333df0c149afbc12b/friends-homework/docs/train/fre/16.txt -------------------------------------------------------------------------------- /friends-homework/docs/train/fre/17.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pirate/Cpp-Data-Structures/901b0e867980fc78cd9717a333df0c149afbc12b/friends-homework/docs/train/fre/17.txt -------------------------------------------------------------------------------- /friends-homework/docs/train/fre/18.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pirate/Cpp-Data-Structures/901b0e867980fc78cd9717a333df0c149afbc12b/friends-homework/docs/train/fre/18.txt -------------------------------------------------------------------------------- /friends-homework/docs/train/fre/19.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pirate/Cpp-Data-Structures/901b0e867980fc78cd9717a333df0c149afbc12b/friends-homework/docs/train/fre/19.txt -------------------------------------------------------------------------------- /friends-homework/docs/train/fre/2.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pirate/Cpp-Data-Structures/901b0e867980fc78cd9717a333df0c149afbc12b/friends-homework/docs/train/fre/2.txt -------------------------------------------------------------------------------- /friends-homework/docs/train/fre/20.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pirate/Cpp-Data-Structures/901b0e867980fc78cd9717a333df0c149afbc12b/friends-homework/docs/train/fre/20.txt -------------------------------------------------------------------------------- /friends-homework/docs/train/fre/3.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pirate/Cpp-Data-Structures/901b0e867980fc78cd9717a333df0c149afbc12b/friends-homework/docs/train/fre/3.txt -------------------------------------------------------------------------------- /friends-homework/docs/train/fre/4.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pirate/Cpp-Data-Structures/901b0e867980fc78cd9717a333df0c149afbc12b/friends-homework/docs/train/fre/4.txt -------------------------------------------------------------------------------- /friends-homework/docs/train/fre/5.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pirate/Cpp-Data-Structures/901b0e867980fc78cd9717a333df0c149afbc12b/friends-homework/docs/train/fre/5.txt -------------------------------------------------------------------------------- /friends-homework/docs/train/fre/6.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pirate/Cpp-Data-Structures/901b0e867980fc78cd9717a333df0c149afbc12b/friends-homework/docs/train/fre/6.txt -------------------------------------------------------------------------------- /friends-homework/docs/train/fre/7.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pirate/Cpp-Data-Structures/901b0e867980fc78cd9717a333df0c149afbc12b/friends-homework/docs/train/fre/7.txt -------------------------------------------------------------------------------- /friends-homework/docs/train/fre/8.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pirate/Cpp-Data-Structures/901b0e867980fc78cd9717a333df0c149afbc12b/friends-homework/docs/train/fre/8.txt -------------------------------------------------------------------------------- /friends-homework/docs/train/fre/9.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pirate/Cpp-Data-Structures/901b0e867980fc78cd9717a333df0c149afbc12b/friends-homework/docs/train/fre/9.txt -------------------------------------------------------------------------------- /graphsearch.txt: -------------------------------------------------------------------------------- 1 | A,B,C,D,E,F,G,H,I 2 | A-B,A-C,A-I,D-F,F-H,H-I,F-D,G-I,C-F 3 | -------------------------------------------------------------------------------- /redblack.txt: -------------------------------------------------------------------------------- 1 | 61,40,74,74,74,3,19,83,30,124,42,49,68,8,22,111,4,153,41,96,27,109,34,74,55,37,135,71,55,154,142,78,148,72,123,120,25,37,79,9,141,102,125,46,70,135,101,20,79,131,28,68,101,29,140,103,67,76,45,103,134,143,151,47,43,143,45,29,119,52,52,52,120,47,120,58,154,10,26,73,2,92,7,146,120,39,133,66,100,88,119,64,101,45,86,43,94,53,16,49, -------------------------------------------------------------------------------- /tutorials/A Quick Introduction to C++ by Tom Anderson.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pirate/Cpp-Data-Structures/901b0e867980fc78cd9717a333df0c149afbc12b/tutorials/A Quick Introduction to C++ by Tom Anderson.pdf -------------------------------------------------------------------------------- /tutorials/C++ Language Tutorial by Juan Soulie.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pirate/Cpp-Data-Structures/901b0e867980fc78cd9717a333df0c149afbc12b/tutorials/C++ Language Tutorial by Juan Soulie.pdf -------------------------------------------------------------------------------- /tutorials/CS11 Introduction to C++ Slideshow.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pirate/Cpp-Data-Structures/901b0e867980fc78cd9717a333df0c149afbc12b/tutorials/CS11 Introduction to C++ Slideshow.pdf -------------------------------------------------------------------------------- /tutorials/Understanding C++ An Accelerated Introduction.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pirate/Cpp-Data-Structures/901b0e867980fc78cd9717a333df0c149afbc12b/tutorials/Understanding C++ An Accelerated Introduction.pdf --------------------------------------------------------------------------------