Wednesday, January 23, 2013

Tuesday, January 22, 2013

Coursera

Completed Courses:

Cryptography I: Dan Boneh, Stanford University
Machine Learning: Andrew Ng, Stanford University
Computing for Data Analysis: Roger Peng, Johns Hopkins
Algorithms, Part I: Robert Sedgewick and Kevin Wayne,  Princeton University


Current Courses:

Game Theory: Matthew O. Jackson, Kevin Leyton-Brown and Yoav Shoham, Stanford University and the University of British Columbia
Introduction to Computer Networks: Arvind Krishnamurthy, David Wetherall and John Zahorjan, the University of Washington

My Experience:

Over the past few months, I have had the amazing opportunity of taking online college courses at Coursera.org. This site offers education for the sake of education alone. Actual professors post videos of lectures along with automatically graded homework assignments that anyone can access. I particularly enjoy it because it allows me to study subjects that simply are not available at my high school. Some courses are intended for college freshmen. Others are graduate level. I've tried several so far, and enjoyed every second. In some ways, even though the material is harder, I find it easier to learn when I don't have to worry about credits, prerequisites, or grades. I'm not ashamed to admit that I failed miserably in some classes that were too advanced for my experience, but I rose to the challenge in others.
Cryptography has fascinated me for years, and Coursera made it possible for me to taste the field, with a Stanford class taught by Professor Dan Boneh. For six weeks, I watched in-depth lectures and completed challenging problem sets. It was difficult to find the time on top of my typical high school coursework, but I finished successfully. I gained a new understanding of the subject matter and an incomparable sense of accomplishment. I'm incredibly grateful to Coursera and all the professors and universities involved for providing the courses I've completed so far and the ones I have yet to take. My curiosity is piqued and I'm ready to study such subjects for real as an undergraduate.

Statements of Accomplishment:



Algorithms, Part I did not issue a certificate.

CS50 Problem Set Example


Specification:


Essentially, the goal is to see if a word is in a dictionary in the fastest possible real-world time. When actually tested for speed, my program finished in 10th place out of 700 Harvard students; 20th if you count the teaching fellows' submissions.


My Solution:


/****************************************************************************
 * dictionary.c
 *
 * Victor Porras
 * Computer Science 50
 * Problem Set 5  *  * Implements a dictionary's functionality.
 * This is not the fastest version of this program, but it is the most
 * extensible and elegant. I hardcoded several parts of this to make the
 * BigBoard version faster, at the expense of readability and robust design.
 *
 * Some distribution code is necessary to compile and run this. See spec.
 ***************************************************************************/   #include <stdbool.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <ctype.h> #include <sys/types.h> #include <sys/stat.h> #include <unistd.h>   #include "dictionary.h"   #define LEVELS 4   // LEVEL dependent int dict[28][28][28][28][2]; char* raw; char** words; char w[46];   unsigned int sz = 0;   /**  * Returns true if word is in dictionary else false.  */ bool check(const char* word) {     if (sz == 0)         return false;         // preprocessing     // since I need to mess around with the characters in word, w is a non-const copy     // char* w = (char *) malloc(sizeof(char) * (LENGTH + 1));         // preparing the word size for later     int wsz;         // this makes EvRytHing lowercase     for (wsz = 0; word[wsz] != '\0'; wsz++)         w[wsz] = tolower(word[wsz]);             // gotta null terminate!     w[wsz] = '\0';         // the first LEVELS values of w must be sequential, ie a-z then z+1 z+2, so they can be used to access arrays     bool finished = false;     for (int x = 0; x < LEVELS; x++)     {         // check for corner cases         if (w[x] == '\'')             w[x] = 'z' + 1;         if (w[x] == '\0' || finished)         {             w[x] = 'z' + 2;             finished = true;         }         w[x] -= 'a';                     }     if (finished)         w[LEVELS] = '\0';         // LEVEL dependent     // time for binary search     int bottom  = dict[(int) w[0]][(int) w[1]][(int) w[2]][(int) w[3]][0];     int top     = dict[(int) w[0]][(int) w[1]][(int) w[2]][(int) w[3]][1];     int result  = 0;         // top is -1 when dict[...] has no pointer             while (top >= bottom)     {         result = strcmp(&(w[LEVELS]), words[(top + bottom)/2]);                 if (result == 0)             return true;         if (result > 0)             bottom = (top + bottom)/2 + 1;         else             top = (top + bottom)/2 - 1;     }         return false; }   /**  * Loads dictionary into memory.  Returns true if successful else false.  */ bool load(const char* dictionary) {     FILE* f = fopen(dictionary, "r");     if (f == NULL)         return false;         // LEVEL dependent     // sets up all the tops with -1     for (int i = 0; i < 28; i++)         for (int j = 0; j < 28; j++)             for (int k = 0; k < 28; k++)                 for (int l = 0; l < 28; l++)                     dict[i][j][k][l][1] = -1;         // gets the file size then allocates memory for it     struct stat st;     stat(dictionary, &st);     unsigned long fsz = st.st_size;     raw = (char*) malloc(fsz);         // it's much faster to read the data in one huge block than in many separate pieces     fread(raw, sizeof(char), fsz, f);         // sets up the data structures to hold the words themselves     int capacity = 262144;     words = malloc(sizeof(char*) * capacity);         // breaks the raw data into words     char* word = strtok(raw, "\n");         // LEVEL dependent     // This will store the first LEVELS letters of the previous word so the indices can be quickly found for similar words     char  old[LEVELS*2] = {27, 27, 27, 27};             // makes sure the file is not over     while (word != NULL)     {         // check if words[] is too big         // this runs in amortized linear time         if (sz == capacity)         {             capacity *= 2;             words = realloc(words, sizeof(char*) * capacity);         }                 if (strncmp(word, old, LEVELS))         {             strncpy(old, word, LEVELS);             bool finished = false;             for (int x = 0; x < LEVELS; x++)             {                 // check for corner cases                 if (word[x] == '\0' || finished)                 {                     old[LEVELS + x] = 27;                     finished = true;                 }                 else if (word[x] == '\'')                     old[LEVELS + x] = 26;                 else                     // put the indices in old                     old[LEVELS + x] = word[x] - 'a';             }               // set the bottom of the binary search range             dict[(int) old[LEVELS]][(int) old[LEVELS+1]][(int) old[LEVELS+2]][(int) old[LEVELS+3]][0] = sz;         }                     // truncate the word to the part after the indices         int wsz = strlen(word) - LEVELS;         if (wsz <= 0)             *word = '\0';         else             word = &(word[LEVELS]);                 // put word into the master array             words[sz] = word;                 // set the top of the binary search range         dict[(int) old[LEVELS]][(int) old[LEVELS+1]][(int) old[LEVELS+2]][(int) old[LEVELS+3]][1] = sz;                 sz++;                 // get the next word         word = strtok(NULL, "\n");     }         fclose(f);     return true; }   /**  * Returns number of words in dictionary if loaded else 0 if not yet loaded.  */ unsigned int size(void) {     return sz; }   /**  * Unloads dictionary from memory.  Returns true if successful else false.  */ bool unload(void) {     // makes sure that the memory has been malloc'd     if (raw == NULL)         return false;             // frees the big arrays that actually hold the values     free(words);     free(raw);     return true; }