[
  {
    "path": ".gitmodules",
    "content": "[submodule \"hw02/starter\"]\n\tpath = hw02/starter\n\turl = git@github.com:cis198-2016s/hw02.git\n\tbranch = master\n[submodule \"hw03/starter\"]\n\tpath = hw03/starter\n\turl = git@github.com:cis198-2016s/hw03.git\n\tbranch = master\n[submodule \"hw04/starter\"]\n\tpath = hw04/starter\n\turl = git@github.com:cis198-2016s/hw04.git\n\tbranch = master\n[submodule \"hw05/starter\"]\n\tpath = hw05/starter\n\turl = git@github.com:cis198-2016s/hw05.git\n\tbranch = master\n[submodule \"hw06/starter\"]\n\tpath = hw06/starter\n\turl = git@github.com:cis198-2016s/hw06.git\n\tbranch = master\n[submodule \"hw07/starter\"]\n\tpath = hw07/starter\n\turl = git@github.com:cis198-2016s/hw07.git\n\tbranch = master\n"
  },
  {
    "path": "final/README.md",
    "content": "# Final Project\n\nThis final project gives you the freedom to do whatever you've been dying to\ndo with this fancy new programming language you've just learned.\n\n## Schedule\n\n* Tue 3/29 - Ideas Due (on Piazza megathread) (for participation credit)\n* Thu 3/31 - Proposal Draft Due (PDF via email)\n* Fri 4/01 - Proposal Meeting (by appointment)\n* Wed 4/06 - Proposal Presentation (in class) (4 min)\n    * Please also send: final proposal, repository link, and documentation link.\n* Wed 4/13 - Milestone 1 Presentation (in class) (2 min)\n* Wed 4/20 - Milestone 2 Presentation (in class) (2 min)\n* Wed 4/27 - Final Presentation (in class) (6 min)\n* Wed 4/27 - Final Report (PDF via email)\n\n**IMPORTANT:** After your proposal is submitted, we want to talk to you before\nthe proposal presentation to discuss and finalize. There will be a sign-up\nsheet for meetings, probably on Friday, April 1.\n\n## Grading\n\nThis project is worth 40% of the final course grade.\n\n* 15%: Proposal and Presentation\n* 20%: Milestone 1 Presentation and Status\n* 20%: Milestone 2 Presentation and Status\n* 45%: Final Presentation, Status, and Report\n\n**Important:** \"Status\" grading will be based primarily on your documentation.\nSpend time on this and write in-depth documentation!\nYou'll need to use rustdoc to generate documentation before each presentation\n(see below: [Documentation](#documentation)).\n\n## Project Guidelines\n\n* Groups may be 1-3 people, 2 preferred. Collaborate via GitHub (obviously).\n  Make your own repository if applicable.\n\n* You can either make your own project or contribute to an existing open-source\n  project. If you do the latter, make sure that the project owners are okay\n  with this. They will expect very high-quality contributions - so don't drop a\n  half-done pull request on them.\n\n* If you make a new project, we _prefer_ (but don't require) things that\n  haven't been done in Rust before.\n\n* Your idea needs to be doable in 3 weeks. This will be all of your\n  198 work during those weeks, so schedule accordingly.\n\n* We expect you to do about (3 weeks * 0.5 credit) worth of work per person -\n  but what that means is subjective. More work will mean a more impressive\n  project - but it's much more important that you finish!\n\n* If your idea is in danger of being too big, you need to have a plan for how\n  to scale it back. Carve out a reasonable subset of the idea as your baseline,\n  and have additional goals on top of that.\n\n* We would really like your project to be open-source! You don't have to if you\n  really don't want to, but contributing to the Rust ecosystem is ideal.\n  You don't need to pick licensing immediately, but consider Apache and MIT.\n\n* If you have no ideas you like, you might consider putting out a call for\n  project ideas to the Rust community (e.g. via Reddit).\n  (If you take a community idea, your project must be open-source.)\n\n### Ideas\n\nThese are our ideas - none of them have been investigated and you don't\nhave to use any of them.\n\n* http://www.ncameron.org/rust.html\n* https://www.rust-lang.org/contribute.html\n* https://www.reddit.com/r/rust/comments/3bjl53/rust_language_project_ideas/\n* https://github.com/rust-lang/rust/blob/master/CONTRIBUTING.md\n* https://github.com/servo/servo/blob/master/CONTRIBUTING.md\n* https://github.com/rust-lang-nursery\n* https://github.com/redox-os/redox#contributing\n\n* Parallel computation (e.g. scientific computing or ray tracing)\n* Other fast scientific computing\n* Safe(!) bindings for a C API\n* Rewriting slow parts of other programs (e.g. Python/Ruby)\n* Some interesting distributed system\n* Some kind of game\n\n## Proposal Document\n\n* Your proposal document should be about 1 page. A Google Doc is recommended.\n  (But please submit as a PDF!)\n\n* List your group members.\n\n* Abstract: Your idea in a sentence or two. New project or contribution?\n\n* Open-source or not. If not, why?\n  You don't need to pick a license right now, but Apache and MIT are good.\n\n* Project outline: Your minimal goals, expected goals, and stretch goals.\n    * This should be detailed enough that we can judge the complexity and merit.\n    * Include appropriate technical details of each goal.\n\n* Tentative Schedule: Which goals do you want to finish each week? Milestone\n  presentations will be at the beginning of class each week.\n\n## Milestone Presentations\n\nThese will be very quick (~2 min). Just update us on your progress.\nYou may present documentation or markdown on GitHub. Send a link before\nclass so we can open it on the classroom computer.\n\nAll of your work must be in your repository by class time, including\nrustdoc documentation for the work you're presenting (see below).\nIf you're contributing, this means it should be in your fork.\n\n## Documentation\n\nIf you are working on a standalone project, you should have rustdocs\ndocumenting all of the work you've done so far,\nat each milestone and the final presentation. This doesn't mean documenting\nevery single function - but you need detailed documentation for the modules,\nfunctionality, and all important structs/functions.\n\n**Important:** Spend time on this and write in-depth documentation.\nIt will be a significant part of our grading!\n\nFor any general information, put it on your crate root module. You can use\nthis syntax for module documentation:\n\n```\n//! if you put this documentation comment style in a\n//! module, it will apply to the module itself instead\n//! of the thing after it\n```\n\nPlease host docs somewhere online. You can use\n[hosting on Eniac](http://www.seas.upenn.edu/cets/answers/webpage.html),\nor you may use a [GitHub Pages](https://pages.github.com/) project site.\n\nBy default, `cargo doc --no-deps` will export documentation for everything\n_public_ in your crate. However, for the project, you'll likely want to\nexport everything. To do this, use:\n\n```sh\ncargo rustdoc -- --no-defaults --passes collapse-docs --passes unindent-comments\n```\n\nHere is some [example rustdoc output](http://cis198-2016s.github.io/final-sample-rustdoc/webchat/).\nThis shows the output of the above command on our HW07 solution. Note that it\ndoesn't have any _module-level_ documentation - which will be most important\nfor you.\n\nIf you're contributing to another project, you should send us a compilation of\nthe documentation for everything **you** have written as part of your project.\n\nIf there is any additional extra information that you want\nto send to us but think doesn't belong in\nthe documentation, email it to us before your presentation.\n\n## Final Report\n\nWrite your report in markdown, and save it as `REPORT.md` in your repository\nroot, and we'll find it there. If you don't have a dedicated repository for\nthis project (e.g. you are forking another project) or you plan to immediately\npublicize your project, put the report in a [Gist](https://gist.github.com/)\nand email us the link. If you have screenshots or images, save them in the repo\nand embed them in `REPORT.md`.\n\nWe'll expect about 2-3 printed-pages-worth of info. Include whatever is\nappropriate or important for your project, such as:\n\n* Summary\n* Approximate time spent\n* Accomplishments\n* Components, structure, design decisions\n* Testing approach and results\n* Benchmarks\n* Limitations\n* Postmortem\n    * What went well\n    * What you would do differently\n* etc.\n\nIf your project would benefit from having a video, that would be great. You\ncan, e.g., record using [OBS](https://obsproject.com/) and upload to YouTube.\n\n**Your documentation is still a part of the final milestone grade.** Anything\nyou've written for documentation can be copied to your report if it's\nimportant. Make sure you have an appropriate amount of documentation. If you\nhave a ton of code but haven't written much documentation for it, your rustdoc\noutput will look very sparse and it'll be harder for us to tell how much you\nhave done. Comments don't count, as they don't appear in the rustdoc output.\n\nKeep in mind that if your repo is public, your report will be as well.\nIf you have any private feedback, email us.\n"
  },
  {
    "path": "hw00/README.md",
    "content": "# Homework 00: Hello Rust & Hello Cargo!\n\n**Due 2016-01-25, 11:59pm.**\n\nFor questions, please post on Piazza (Penn students) or Google Groups (other).\nLinks on homepage.\n\n#### Classroom for GitHub\n\nWe're using Classroom for GitHub, which manages private homework repositories\nfor students. To create your very own private homework repository (owned by\nus), click the link on the course Piazza.\n\nIf there is no starter code, such as in this homework, you can use Cargo to\ninitialize the git repository for you. See below. But first, Rust!\n\n## Installing Rust\n\nFor this homework, all you'll have to do is install the Rust compiler (rustc)\nand the Rust package manager (Cargo). We'll be using Rust v1.6 for this class.\n(Version 1.6 is set to be released next Thursday! This homework doesn't depend\non the version of Rust, so it's fine to get started early.)\n\nWe recommend using [multirust][multirust], a tool to manage multiple\ninstallations of Rust on your system. Multirust supports Linux, OS X, and\nWindows (via MSYS2). Unfortunately, there is no support for Windows if you are\nnot using MSYS2.\n\nMultirust maintains a user default toolchain version (stable, beta, or\nnightly). Run `multirust default stable` to set your user preference to stable.\nThis will also download the stable toolchain.\n\n**On Linux, OS X, or Windows+MSYS2:**\nInstall multirust by following the [instructions on their README][multirust].\nYou can also use your local friendly package manager.\n\n[multirust]: https://github.com/brson/multirust\n\n**On Windows (without MSYS2):** \nYou can either use the standard Rust installer from\n[the website](https://www.rust-lang.org/downloads.html), or you can use\nmultirust on Eniac.\n\n**On Eniac:**\nIf you don't want to install Rust,\nmultirust is also available on Eniac. Add this line to your `~/.bashrc` on\nEniac: `export PATH=$PATH:/home1/c/cis198/local/bin`\n\nTo check that Rust and Cargo are installed properly, run the following commands\nand make sure the output matches below:\n\n```\n$ rustc --version\nrustc 1.5.0 (3d7cd77e4 2015-12-04)\n$ cargo --version\ncargo 0.6.0-nightly (e1ed995 2015-10-22)\n```\n\nWhen version 1.6 is released next week, you should update your version of Rust,\nusing `multirust update stable`.\n\n## Hello, Rust!\n\nNow that Rust is ready to roll, let's write our first \"hello world\" program.\nCreate a file named `main.rs` and modify the code snippet below to print out\n\"Hello, \\<your name\\>!\".\n\n```rust\nfn main() {\n    let name = \"Ferris\"; // Ferris is the name of Rust's unofficial crustacean mascot\n    println!(\"Hello, {}!\", name);\n}\n```\n\nOnce you've created your program, compile it using `rustc main.rs` and run the\nresulting `main` binary to test it. Boom! You did it! You're a Rust programmer\nnow! 🎊🎉👍\n\n## Hello, Cargo!\n\nRust has a fantastic package and build manager, Cargo, which is modeled from\nyears of learning from other languages. Cargo handles all the gory build\nautomation and dependency management details for you, so that you don't have to\nworry about it when creating (or building or updating) a project.\n\nUsing `rustc` directly is fine for small projects, but Cargo really helps to\nremove a lot of the friction of manual project management. If you've ever used\n`rake` or `pip` for dependency management, Cargo is like those, plus all of the\nbuild power provided by a good `Makefile`.\n\nTo make a new project for homework 0, run the command\n`cargo new --bin hw00` (which will *create* the folder `hw00`).\n\nWhy `--bin`? We want this project to create a standalone executable, rather than\na library that can be rolled into other projects.\n\nIf you are not already in a git repository when you create your project, Cargo\nwill create a git repository (and `.gitignore`) for you. Then, you can add this\nyour GitHub repository as a git remote as follows:\n\n\n```\ngit remote add origin git@github.com:cis198-2016s/hw00-<username>.git\ngit push -u origin master\n```\n\nCargo creates this directory structure for you:\n\n```\nhw00\n├── Cargo.toml\n└── src\n    └── main.rs\n\n1 directory, 2 files\n```\n\nYou may notice that the `main.rs` file Cargo creates looks suspiciously\nsimilar to the \"Hello World\" code above. Since you've already written your\n\"Hello World\" program, move the file you created into `src`, and overwrite\nthe `main.rs` that Cargo generated.\n\nTo finish things off, let's build our project. Simply run `cargo build` from any\ndirectory in the project tree! You can run your executable with `cargo run`.\nPretty magic, huh?\n\n## Bonus: Configuration\n\nAdding to your personal environment setup is one of the many joys of starting\na new programming language. Rust has a pretty decent amount of support for being\nnew to the game.\n\nTake a look at [this list of editor configs][configs.md]. There are more\nunofficial or less-supported ones out there, so it's worth looking around. If\nyou aren't sure what to use, all three of your instructors use vim :)\n\n  [configs.md]: https://github.com/rust-lang/rust/blob/master/src/etc/CONFIGS.md\n\n## Submission\n\nCommit and push your work to the master branch of your Classroom for Github\nrepository for this HW. **Make sure it is visible on Github!** This is your\nsubmission. (Work must be in the master branch at the due time.)\n\nThat's it! ok bye get outta here :point_right:\n"
  },
  {
    "path": "hw01/README.md",
    "content": "# Homework 01: Rust Finger Exercises\n\n**Due ~~2016-01-27~~ 2016-01-28, 11:59pm.**\n\nFor questions, please post on Piazza (Penn students) or Google Groups (other).\nLinks on homepage.\n\n## Overview ##\n\nIn this assignment, you'll get your first crack at writing some short functions\nin a Rust library, building and testing using Cargo, and writing modules. This\nassignment isn't intended to be especially difficult, but will make sure you're\nset up properly in the Rust ecosystem, and will give you some good experience\nusing the Rust compiler.\n\n#### Classroom for GitHub\n\nWe're using Classroom for GitHub, which manages private homework repositories\nfor students. To create your very own private homework repository (owned by\nus), click this link:\n* https://classroom.github.com/assignment-invitations/d7a2cbae7d57de44e29c302c8e353a43\n\n## Provided Code ##\n\nJust one file, `tests_provided.rs`, which contains several test cases. We're\nasking you to write everything else from scratch, but we'll give you function\nsignatures below, as a starting point.\n\n## Part 01: Cargo ##\n\nDon't clone your GitHub repository just yet.\nTo start off, let's create a new Rust library: `cargo new hw01`.\n\nIf you are not already in a git repository when you create your project, Cargo\nwill create a git repository (and `.gitignore`) for you. Then, you can add this\nyour GitHub repository as a git remote, with something like:\n\n```\ngit remote add origin git@github.com:cis198-2016s/hw01-<username>.git\ngit push -u origin master\n```\n\n(If you're not using SSH for GitHub, you need to use the HTTPS URL of your\nrepository.)\n\nCargo creates this directory structure for you:\n\n```\nhw01\n├── .git/\n├── .gitignore\n├── Cargo.toml\n└── src\n    └── lib.rs\n```\n\nYou can build this project from anywhere in the project tree with\n`cargo build`. Remember to compile periodically as you work.\n\n### Modules ###\n\nBefore you go any further, a word on modules and crates.\n\nCrates are any Rust library or package. Modules are the inner logical sections\nof a crate.\n\nYou will want to organize each section of your crate into a different module,\nso consumers can only import the parts that they need. You could do this in\n`lib.rs`:\n\n```rust\npub mod problem1 {\n}\n\npub mod problem2 {\n}\n\npub mod problem3 {\n}\n\npub mod problem4 {\n}\n\n// ...\n```\n\nBut this gets unwieldy pretty fast. You can instead put these modules in\nseparate files:\n\n```\nhw01\n├── Cargo.toml\n└── src\n    ├── problem1.rs\n    ├── problem2.rs\n    ├── problem3.rs\n    ├── problem4.rs\n    └── lib.rs\n```\n\nEvery `.rs` file defines a module that is the same as its filename, so\n`problem1.rs` implicitly defines the module `problem1`.\n\nCrates are organized into trees of files, where one file is the root, typically\n`src/lib.rs` (or `src/main.rs`). To include a module, you need to declare it in\nthe crate root. To add `problem1` as a module, add the line `pub mod problem1;`\nto the top of `src/lib.rs`. (This is equivalent to defining a module in the\nfile itself, with `pub mod problem1 { ... }`.) Until you add this directive,\nCargo will not try to build `problem1` part of your crate. The `pub` keyword in\nthis directive exposes the module `problem1` to any other crate that imports\nyour library. You can omit `pub` to leave modules private; however, if a\nfunction is not exported or used internally, it will emit a dead code warning.\n\nWithin a module, all members (functions, types, submodules) are private by\ndefault. The `pub` keyword can also be used to make any of these available from\noutside of the module.\n\n```rust\n// problem1.rs\n\n/// Functions are private (only available to this module) by default.\n/// Use the `pub` keyword to mark this function as public.\npub fn sum(slice: &[i32]) -> i32 {\n    // ...\n}\n```\n\nThere are a few different ways to import items from a different module:\n\n1. To add `sum` to the scope of a file, add the line `use problem1::sum` to the\n   top of the file. You can call the function with `sum()`. Try to import only\n   what you need to use.\n\n2. To import multiple things from a module, use curly braces:\n   `use problem1::{sum, dedup};`\n\n3. To import all items from a module, write `use problem1::*`.\n\n4. To import an entire module, write `use problem1;`. This form requires you to\n   qualify members of the module with the module name (e.g. `problem1::sum()`).\n   This is more verbose but does not pollute the namespace of your scope.\n\nWe provided a `tests_provided.rs` file with a few test cases to start you off\nwith. You should add this to your library as a separate module, as you did with\neach `problemX` module (but the tests don't need to be `pub`).\n\nYou can read more about modules in the Rust book\n[here](https://doc.rust-lang.org/book/crates-and-modules.html).\n\n## Part 02: Basic Functions ##\n\n### Preface ###\n\nFor consistency, we ask that you put each problem into its own file, and name\nthe file as `problem1.rs`, etc. Remember to declare each module at the top of\n`lib.rs` as well!\n\n### Problem 01: Vector & Slice Manipulation ###\n\n*Vectors, iteration, pass-by-ref, mutability, function pointers.*\n\nCreate a new module in your library named `problem1` inside `problem1.rs`.\n\nTo get a first taste of basic Rust, complete the following three functions.\nNote that all of these functions take their arguments by reference, rather than\nby value.\n\nDon't use any of the standard library methods on the `Vec` class which implement\nthe target behavior, since using them would defeat the point of this exercise\n:). (However, basic functions such as `contains()` and `push()` are fine).\n\n```rust\n/// Computes the sum of all elements in the input i32 slice named `slice`\npub fn sum(slice: &[i32]) -> i32 {\n    // TODO\n    unimplemented!();\n}\n\n/// Deduplicates items in the input vector `vs`. Produces a vector containing\n/// the first instance of each distinct element of `vs`, preserving the\n/// original order.\npub fn dedup(vs: &Vec<i32>) -> Vec<i32> {\n    // TODO\n    unimplemented!();\n}\n\n/// Filters a vector `vs` using a predicate `pred` (a function from `i32` to\n/// `bool`). Returns a new vector containing only elements that satisfy `pred`.\npub fn filter(vs: &Vec<i32>, pred: &Fn(i32) -> bool) -> Vec<i32> {\n    // TODO\n    unimplemented!();\n}\n```\n\n#### Testing\n\nBefore you move on, take a look at `tests_provided.rs`.\n\nAt the top of this file, there's a `#![cfg(test)]` attribute. `cfg`, short for\n\"configuration\", is part of how Rust handles conditional compilation. This is\nsimilar to (but way better than) the use of `#ifdef`s and include guards in C.\nIn this case, `#![cfg(test)]` tells the compiler that this module is not to be\ncompiled unless the `--test` flag is used with `rustc` (`cargo test` adds this\nflag under the hood). This is handy because it means that you don't have to\nwaste time recompiling your tests every time you build unless you're actually\ngoing to run them.\n\nAll of the functions in `test.rs` are annotated with the `#[test]` attribute;\nthis tells the compiler that they're tests. Test functions must have the\nsignature `fn() -> ()`, or else they will not compile. Tests will be run when\nyou invoke `cargo test`.\n\nAny test which doesn't cause a `panic!` is considered to pass. You should use\n[`assert!`][assert] or [`assert_eq!`][assert_eq] to check guarantees and\nequality (respectively).\n\n[assert]: https://doc.rust-lang.org/std/macro.assert!.html\n[assert_eq]: https://doc.rust-lang.org/std/macro.assert_eq!.html\n\nAs an aside, the `cfg` attribute has many other uses, like knowing\nwhich OS or architecture you're compiling for.\n\nWe have provided a few tests to start you off with. You should add at least one\nnon-trivial test for each function that you implement. Write these in a new\nmodule, `tests_student.rs`, and declare the module in `lib.rs`.\n\n### Problem 02: Matrix Multiplication ###\n\n*Vectors, iteration, pass-by-reference, structs.*\n\nCreate a new module in your library named `problem2` inside `problem2.rs`.\n\nWe define a `Matrix` as a type alias to `Vec<Vec<f32>>`. Write a function that\ntakes in two `Matrix`es by reference and returns the product `mat1 * mat2`. The\nfunction signature is provided below.\n\nYou should make sure that the two input matrices are actually compatible.\nRemember that you can't multiply two matrices if the number of columns in the\nfirst matrix is not equal to the number of rows in the second matrix. Use\n`assert!` or `assert_eq!` to `panic!` if this condition is not met.\n\n(Of course, crashing is bad - we'll learn about fixing this later.)\n\n```rust\n/// Represents a matrix in row-major order\npub type Matrix = Vec<Vec<f32>>;\n\n/// Computes the product of the inputs `mat1` and `mat2`.\npub fn mat_mult(mat1: &Matrix, mat2: &Matrix) -> Matrix {\n    // TODO\n    unimplemented!();\n}\n```\n\n### Problem 03: Sieve of Eratosthenes ###\n\n*Vectors, iteration, mutability...*\n\nCreate a new module in your library named `problem3` inside `problem3.rs`.\n\nThe [Sieve of Eratosthenes](https://en.wikipedia.org/wiki/Sieve_of_Eratosthenes)\nis used to find all primes below some given number (`n`), and is an efficient\nway to find small primes.\n\nIterate through the numbers from `2` to `n`. For each number `i`:\n\n1. If `i` has been crossed-out from previous iterations, skip it.\n2. If `i` isn't crossed-out yet, then it is prime.\n   Cross-out all multiples of `i` from `i*i` to `n`. These are non-prime.\n\nHead over to the Wikipedia page for a more detailed description and some zesty\nexamples.\n\nYour function will take a number, `n`, and return a list of all prime numbers\nless than `n`. (Notice that you can't use a Rust array in this case, since you\ndon't know the length at compile time.)\n\n```rust\n/// Find all prime numbers less than `n`.\n/// For example, `sieve(7)` should return `[2, 3, 5]`\npub fn sieve(n: u32) -> Vec<u32> {\n    // TODO\n    unimplemented!();\n}\n```\n\n### Problem 04: Towers of Hanoi ###\n\n*Mutability, type aliases, vecs, tuples, enums.*\n\n[The Towers of Hanoi](https://en.wikipedia.org/wiki/Tower_of_Hanoi) is a\nclassical mathematics and computer science puzzle. Imagine you have three pegs,\none of which holds a stack of discs in increasing size from bottom to top. Your\ngoal is to move all of the discs from the first peg to the third peg, using the\nsecond peg as an intermediate. Your only restrictions are that you may only\nmove one disc at a time, and a disc may only be placed on a disc larger than it\n(or on an empty peg). Check out the Wikipedia page for more details and snazzy\nanimations.\n\nIn this instance, we've provided you with an enum type containing the possible\nnames of `Peg`s and a type alias defining a move between two pegs.\n\nThis function will take in a number of discs, and the names of the three\npegs, and return a vector of `Move`s.\n\n```rust\n/// #[derive(...)] statements define certain properties on the enum for you for\n/// free (printing, equality testing, the ability to copy values). More on this\n/// when we cover Enums in detail.\n\n/// You can use any of the variants of the `Peg` enum by writing `Peg::B`, etc.\n#[derive(Clone, Copy, Debug, Eq, PartialEq)]\npub enum Peg {\n    A,\n    B,\n    C,\n}\n\n/// A move between two pegs: (source, destination).\npub type Move = (Peg, Peg);\n\n/// Solves for the sequence of moves required to move all discs from `src` to\n/// `dst`.\npub fn hanoi(num_discs: u32, src: Peg, aux: Peg, dst: Peg) -> Vec<Move> {\n    // TODO\n    unimplemented!();\n}\n```\n\n## Submission\n\nCommit and push your work to the master branch of your Classroom for Github\nrepository for this HW. **Make sure it is visible on Github!** This is your\nsubmission. (Work must be in the master branch at the due time.)\n\nYour repository should look like this:\n\n```\n[git root]\n├── Cargo.toml\n└── src\n    ├── lib.rs\n    ├── problem1.rs\n    ├── problem2.rs\n    ├── problem3.rs\n    ├── problem4.rs\n    ├── tests_provided.rs [same as given]\n    └── tests_student.rs [your tests]\n```\n\n`cargo test` should run all of the tests in your homework. Make sure you have\nwritten at least one test for each function you have written.\n"
  },
  {
    "path": "hw01/tests_provided.rs",
    "content": "#![cfg(test)]\n\nuse problem1::{sum, dedup, filter};\nuse problem2::mat_mult;\nuse problem3::sieve;\nuse problem4::{hanoi, Peg};\n\n//\n// Problem 1\n//\n\n// Part 1\n\n#[test]\nfn test_sum_small() {\n    let array = [1,2,3,4,5];\n    assert_eq!(sum(&array), 15);\n}\n\n// Part 2\n\n#[test]\nfn test_dedup_small() {\n    let vs = vec![1,2,2,3,4,1];\n    assert_eq!(dedup(&vs), vec![1,2,3,4]);\n}\n\n// Part 3\n\nfn even_predicate(x: i32) -> bool {\n    (x % 2) == 0\n}\n\n#[test]\nfn test_filter_small() {\n    let vs = vec![1,2,3,4,5];\n    assert_eq!(filter(&vs, &even_predicate), vec![2,4]);\n}\n\n//\n// Problem 2\n//\n\n#[test]\nfn test_mat_mult_identity() {\n    let mut mat1 = vec![vec![0.;3]; 3];\n    for i in 0..mat1.len() {\n        mat1[i][i] = 1.;\n    }\n    let mat2 = vec![vec![5.;3]; 3];\n    let result = mat_mult(&mat1, &mat2);\n    for i in 0..result.len() {\n        for j in 0..result[i].len() {\n            assert_eq!(result[i][j], mat2[i][j]);\n        }\n    }\n}\n\n//\n// Problem 3\n//\n\n#[test]\nfn test_sieve_basic() {\n    assert_eq!(vec![2,3,5,7,11], sieve(12));\n}\n\n//\n// Problem 4\n//\n\n#[test]\nfn test_hanoi_1_disks() {\n    let result = hanoi(1, Peg::A, Peg::B, Peg::C);\n    assert_eq!(vec![(Peg::A, Peg::C)], result);\n    assert_eq!(1, result.len());\n}\n"
  },
  {
    "path": "hw02/README.md",
    "content": "# Homework 2: A Mediocre Binary Search Tree\n\n**Due 2016-02-03, 11:59pm.**\n\nFor questions, please post on Piazza (Penn students) or Google Groups (other).\nLinks on homepage.\n\n## Overview\nThis assignment is modeled after Alexis Beingessner (Gankro)'s [_Learning Rust\nWith Entirely Too Many Linked Lists_][TMLL] (herein referred to\nas TMLL, because that's much easier to pronounce, right?)\n\n[TMLL]: http://cglab.ca/~abeinges/blah/too-many-lists/book/\n\nEven though we're implementing a [BST][], you should read Chapters 1-2\n(introduction and first linked list); they're a great place to start.\nGankro's writing is really fun to read and the content is enlightening.\n\n[BST]: https://en.wikipedia.org/wiki/Binary_search_tree\n\n#### Classroom for GitHub\n\nWe're using Classroom for GitHub, which manages private homework repositories\nfor students. To create your very own private homework repository (owned by\nus), click this link:\n* https://classroom.github.com/assignment-invitations/9f6544879f4d5995f8a23cf35caf2133\n\n## Instructions\n\nWrite your implementation in the `src/first.rs` file. You'll also write tests\nin this file. The main file, `lib.rs`, is rather boring and done for you.\n\nYour code doesn't have to follow any exact interface, just the guidelines\nbelow. You'll write the data structure, `insert`, `search`, and tests.\n\nUnlike in HW1, if you create your repository using Classroom for GitHub (link\non Piazza), your Git repository will be pre-populated (you won't need to use\n`cargo new`). Just clone it to get going. (See the `starter` subrepo for the\nstarter repository contents.) You should edit `Cargo.toml` to add yourself as\nthe author.\n\n#### Aside: Clippy\n\n[Clippy][] is a compiler plugin which runs [lints][] on your code. It only\nworks in nightly Rust, however, so it's not enabled by default here. If you\nfeel like trying it out, switch to the nightly channel\n(e.g. `multirust override nightly` while inside the project directory),\nthen build with the `clippy` feature:\n\n```\ncargo build --features clippy\ncargo test --features clippy\n```\n\nThis is recommended as it will help catch some stylistic errors as you learn\nthe language. (But, for ease of grading, please be sure to submit code which\nworks on Rust stable.)\n\n[Clippy]: https://github.com/Manishearth/rust-clippy\n[lints]: https://en.wikipedia.org/wiki/Lint_%28software%29\n\n(If for some reason Clippy causes problems for your stable Rust build, just\nremove the `[dependencies]` and `[features]` sections from `Cargo.toml` and\nthe Clippy-related lines at the top of `lib.rs`.)\n\n### Implementation\n\nThis _roughly_ corresponds to\n[TMLL 2](http://cglab.ca/~abeinges/blah/too-many-lists/book/first.html).\nFor more details, refer there.\n\nAs in TMLL 2:\n\n* Write a `BST` type similar to the one in TMLL 2: a `pub struct` with a `root`\n  element of type `Link`. Implement `BST::new()` which creates an empty BST.\n    * This will be the only `pub struct`. The others are implementation\n      details.\n* Define `Link` as an `enum` with two instances: `Empty` and `More`, where\n  `More` contains a boxed `Node`.\n* Define `Node` as a `struct` containing an `i32` element. Instead of a single\n  `next` element, it should also contain two child `Link`s: `left` and `right`.\n* Add `#[derive(Debug)]` before each of the three types. This allows you to\n  debug-print a value, e.g.: `println!(\"{:?}\", bst);`\n    * Use `println!(\"{:#?}\", bst);` for multi-line, indented debug prints!\n    * To be able to see printed output of successful tests, use\n      `cargo test -- --nocapture`.\n\nNow, instead of TMLL's `push` and `pop`, we'll implement:\n\n* (`pub`) `bst.insert(i32) -> bool`: Insert an element into the BST. Return\n  true if successful, or false if the element was already in the BST.\n* (`pub`) `bst.search(i32) -> bool`: Search for an element in the BST. Return\n  true iff the element was found.\n\n#### Hints from our reference implementation\n\nYou should need: `struct`, `enum`, `impl`, `match`/`ref`/`ref mut`, `Box`,\n`&`/`&mut`, dereferencing (`*`).\n\nYou should not need: named lifetimes, `Option`, `Vec`, `use`.\n\nIn our reference implementation, `BST::insert` and `BST::search` are short\nfunctions which just call longer, recursive member functions of `Link`:\n\n* `link.insert(i32) -> bool` (~25 lines)\n  * If inserting into an empty link, place the element in this link (making it\n    no longer empty).\n  * If inserting into a non-empty link:\n    * return `false` if the element is in this node; otherwise,\n    * recurse to the left if the new value is less than the node's value\n    * recurse to the right if the new value is greater than the node's value\n  * You may not end up needing `mem::replace` like in TMLL.\n\n* `link.search(i32) -> bool` (~15 lines)\n  * If searching an empty link, return `false`; the element can't be found.\n  * If searching a non-empty link:\n    * return `true` if the element is in this node; otherwise,\n    * recurse to the left if the target value is less than the node's value\n    * recurse to the right if the target value is greater than the node's value\n\n### Tests\n\nYou can run tests with `cargo test`. To show any printed output of successful\ntests, use `cargo test -- --nocapture`.\n\nTests should be defined in the way specified in\n[TMLL 2.6](http://cglab.ca/~abeinges/blah/too-many-lists/book/first-test.html).\nThis keeps unit tests close to the code that they test.\n\n```rust\n#[cfg(test)]\nmod test {\n    use super::List;\n\n    #[test]\n    fn test_push_pop() {\n        // ...\n    }\n}\n```\n\nYou should test `search` and `insert` in various orders, for both true and\nfalse results. Use `assert!()` and/or `assert_eq!()`. They don't have\nto be any more complex than the tests in TMLL 2.6.\n\n### Submission\n\nJust like in homework 01, commit and push your work to the master branch of\nyour Classroom for Github repository for this HW. Make sure it is visible on\nGithub! This is your submission. (Work must be in the master branch at the due\ntime.)\n\n`cargo test` should work to run all of the tests in your homework on stable\nRust. Make sure you have written tests which cover every one of your functions.\n"
  },
  {
    "path": "hw03/README.md",
    "content": "# Homework 3: \"Iterating\" On Your Binary Search Tree\n\n**Due 2016-02-10, 11:59pm.**\n\nFor questions, please post on Piazza (Penn students) or Google Groups (other).\nLinks on homepage.\n\n## Overview\n\nThis assignment is modeled after Alexis Beingessner (Gankro)'s [_Learning Rust\nWith Entirely Too Many Linked Lists_][TMLL] (TMLL).\n\n[TMLL]: http://cglab.ca/~abeinges/blah/too-many-lists/book/\n\nThis time, you should look at Chapter 3. We won't do everything in there, but\nthe content is similar.\n\n#### Classroom for GitHub\n\nWe're using Classroom for GitHub, which manages private homework repositories\nfor students. To create your very own private homework repository (owned by\nus), click this link:\n* https://classroom.github.com/assignment-invitations/678e4f3868daaec525ce8f75f23fc53c \n\n## Instructions\n\nWrite your implementation and tests in `src/second.rs`. `lib.rs` is provided.\n\nAs before, your code doesn't have to follow an exact interface, but the\nfunction signatures provided will probably work best.\n\nYou'll likely want to start off with your solution for HW2 - a lot will carry\nover. You'll modify the data structure, `insert`, `search`, and the tests, and\nwrite the code necessary to turn your BST into various iterator types:\n`IntoIter`, `Iter`, and `IterMut`.\n\nLike in HW2, your GitHub repository will be pre-populated with a skeleton Cargo\nproject. You should edit `Cargo.toml` to add yourself as the author.\n\n### Implementation\n\nThis _roughly_ corresponds to\n[TMLL 3](http://cglab.ca/~abeinges/blah/too-many-lists/book/second.html).\nFor more details, refer there.\n\nWe will use:\n\n* `Option` and `take` (but *not* `map`).\n* Type aliases.\n* Generic type parameters (`BST<T>`) with trait bounds (`Ord`).\n* Named lifetimes and lifetime bounds on type parameters.\n* Traits, trait implementations, and associated types.\n* Iterators.\n\nWe'll essentially be modifying HW2, so you should copy `first.rs` over as\n`second.rs` in HW3.\n\n**NOTE:**\n\n[TMLL 3.1][] introduces `map` and anonymous functions and closures. Since we\nhaven't covered this in class, you can  use `match`es instead of closures\neverywhere in this assignment. However, you're welcome to use `map`/closures if\nyou want the extra practice - simple closures aren't hard.\n\n> Second, `match option { None => None, Some(x) => Some(y) }` is such an\n> incredibly common idiom that it was called `map`. `map` takes a function to\n> execute on `x` in the `Some(x)` to produce the `y` in `Some(y)`. We could\n> write a proper `fn` and pass it to `map`, but we'd much rather write what to\n> do *inline*.\n\n#### Details\n\nAs in TMLL 3:\n\n* Convert `BST` and `Link` to take a generic element `T` instead of `i32`.\n\n* Replace the `Link` type with a type alias for `Option<Box<Node<T>>>`, because\n  your life has felt strangely lacking in angle brackets recently. Then, update\n  all of the code which uses `Link`. You may not have used `mem::replace` in\n  HW2, in which case you won't need `take` yet.\n\n  * If you want, take a look through the [`Option` documentation][optdoc] to\n    find useful methods.\n\n[optdoc]: https://doc.rust-lang.org/std/option/enum.Option.html\n\n* Now that `Link` is a type alias and not a struct, you cannot directly `impl`\n  methods for it, because you don't own the type `Option`. However, you do not\n  feel constrained by the ~~silly~~ very serious and important rules that Rust\n  imposes on your life, so you can work around this by defining a generic trait\n  `InsertSearch<T>` which provides your two functions `insert(&mut self, e: T)\n  -> bool` and `search(&self, e: T) -> bool`.\n\n  * Proceed to exercise your unbounded power by implementing `InsertSearch`\n    for `Link<T>`, by adapting the functions you wrote for HW02 to be generic\n    over `T`. Make sure your old tests still pass.\n\n* Now you will transform your ordinary BST into an extraordinary BST iterator!\n  We're going to use the [`Iterator`] trait.\n\n  * Build yourself an `IntoIter` struct like the one in [TMLL 3.4][].\n\n    * Since this is a BST, and not a list, we're going to cheat a bit and\n      just iterate over the rightmost edge of the tree, since that's less\n      annoying. (If you feel like it, you can try doing an in-order\n      traversal of the tree instead. We can't guarantee that you can do it\n      with the material we have covered so far, so try the cheaty version\n      first!)\n\n    * Implement the [`Iterator`][] trait for `IntoIter`. This requires an\n      associated type, `type Item`, and an implementation of\n      `next(&mut self) -> Option<Self::Item>`.\n\n  * Instead of implementing `BST::into_iter` as a plain member function,\n    we're going to do something _way_ cooler:\n\n    * [`IntoIterator`][] is a trait with one method, `into_iter`. This is the\n      sugar that fuels Rust's `for` loops. Go ahead and `impl IntoIterator for\n      BST`. Don't forget: this trait requires you to declare associated types!\n      Read the [docs][`IntoIterator`] for the deets.\n\n[`Iterator`]: https://doc.rust-lang.org/std/iter/trait.Iterator.html\n[`IntoIterator`]: https://doc.rust-lang.org/std/iter/trait.IntoIterator.html\n\n  * BAM! Now your BST can harness the power of `for` loops. Try this:\n\n```rust\nlet mut bst = BST::new();\nbst.insert(1);\nbst.insert(2);\nbst.insert(3);\n\nfor elt in bst { // calls bst.into_iter()\n    println!(\"{}\", elt);\n}\n```\n\n  * But your power is yet incomplete. What about borrowed iteration? Implement\n    an `Iter` struct, as described in [TMLL 3.5][] (similar to `IntoIter`).\n\n    * Again, instead of implementing `BST::iter`, we're going to lord our\n      superiority over Gankro's tutorial and use `IntoIterator`. But you can't\n      just implement a trait _twice_ for the same struct; that would be absurd.\n      And confusing. It would break so many rules. Instead, we'll implement this\n      for `&BST`.\n      \n    * Again, iterate over the rightmost edge of the tree.\n\n    * You're going to need named lifetimes here! To start, you have to\n      implement `impl<'a, T> IntoIterator for &'a BST<T>`.\n\n    * This is what allows:\n\n```rust\nfor elt in &bst { // calls (&bst).into_iter()\n    println!(\"{}\", elt);\n}\n```\n\n  * Finally, we'll move on to [TMLL 3.6][], `IterMut`. You know what you need\n    to do.\n\n```rust\nfor elt in &mut bst { // calls (&mut bst).into_iter()\n    println!(\"{}\", elt);\n}\n```\n\n[TMLL 3.1]: http://cglab.ca/~abeinges/blah/too-many-lists/book/second-option.html\n[TMLL 3.4]: http://cglab.ca/~abeinges/blah/too-many-lists/book/second-into-iter.html\n[TMLL 3.5]: http://cglab.ca/~abeinges/blah/too-many-lists/book/second-iter.html\n[TMLL 3.6]: http://cglab.ca/~abeinges/blah/too-many-lists/book/second-iter-mut.html\n\n### Tests\n\nTest all three of your iterators. To do this, you should check two things:\n\n* For a BST `bst`, you should be able to compile a for loop over\n  `bst`, `&bst`, or `&mut bst`.\n\n* The values returned by the iterator should be correct. You can explictly\n  get an iterator (with, for example, `(&mut bst).into_iter()`), then\n  `assert_eq!` the values returned by `next()`.\n\n### Submission\n\nCommit and push your work to the master branch of your Classroom for Github\nrepository for this HW. Make sure it is visible on Github! This is your\nsubmission. (Work must be in the master branch at the due time.)\n\n`cargo test` should work to run all of the tests in your homework on stable\nRust. Make sure you have written tests which cover every one of your functions.\n\nIf you have any comments or feedback on this assignment, include them in the\nREADME of your submission.\n"
  },
  {
    "path": "hw04/README.md",
    "content": "# Homework 4: Reverse Polish ~~Sausage~~ Notation Calculator\n\n**Due 2016-02-17, 11:59pm.**\n\nFor questions, please post on Piazza (Penn students) or Google Groups (other).\nLinks on course homepage.\n\n## Overview\n\nReverse Polish notation, which is [not exactly][rpn] the reverse of Polish\nnotation, is a convention for mathematical expressions for ~~nerds~~\n~~hipsters~~ ~~enterprising young computer scientists~~ ~~bored students~~ you!\nImplementing an RPN calculator in Rust will cover several standard library\nmodules and common patterns.\n\n[rpn]: https://en.wikipedia.org/wiki/Reverse_Polish_notation#Explanation\n\nReverse Polish notation defines expressions with _postfix_ operators (`1 2 +`),\nrather than the typical _infix_ expression form (`1 + 2`). Postfix form is very\neasy to evaluate using a state machine with a stack data structure. When\nthe calculator encounters a numeric literal (`1`), it pushes the number onto the\nstack. When an operator (`+`) is encountered, the machine pops one or more\nnumbers off the stack, evaluates the expression, then pushes the result back\nonto the stack.\n\n#### Classroom for GitHub\n\nWe're using Classroom for GitHub, which manages private homework repositories\nfor students. To create your very own private homework repository (owned by\nus), click this link:\n* https://classroom.github.com/assignment-invitations/4247c727a1c77eb1982e03bc4083a574\n\n## Instructions\n\nWrite your calculator implementation in `rpn.rs`, and your parser\nimplementation in `parser.rs`. `main.rs` is provided. Hooray! You're finally\nwriting an executable program!\n\nLike in HW3, your GitHub repository will be pre-populated with a skeleton Cargo\nproject. You should edit `Cargo.toml` to add yourself as the author.\n\n##### Stack Element Types\n\nYour stack will support two types: `i32` and `bool`. We're starting you off with\na convenient enum to store these, `Elt`, in `rpn.rs`.\n\n##### Operators\n\nYou're only required to implement the following operations because ~~they're the\nones that won out in a fight~~ implementing all operations would be tedious:\n\n_Addition_ adds the top two elements of the stack, or type-errors on booleans.\n\n_Negation_ computes logical-not of booleans, and inverts the sign of integers.\n\n_Equality_ compares the top two elements and pushes a boolean onto the stack.\n\n_Swap_ reverses the order of the top two elements on the list.\n\n_Random_ pops a value off of the stack; if that value is an integer `x`, it will\nuse the `rand` library to generate a random number between `0` and `x` and push\nit onto the stack. Otherwise, it type-errors.\n\n_Quit_ exits the program.\n\nWe're providing an `Op` type to represent the various operators you may\nencounter in the wild, located in `rpn.rs`.\n\n##### Result Aliases\n\nWhen your calculator hits an error, it should exit. Conveniently, there's also a\nhandy-dandy provided `Error` enum which defines a few different types of\npossible errors: undeflow, type mismatch, syntax, IO, and quit (which is not an\nerror, but represents an exit value).\n\nBecause you're a good software engineer, you're going to create your own\n`Result` alias for use in your calculator. Use the provided `Error` enum in\n`rpn.rs` to define an alias over `std::result::Result` - a similar aliasing\ncan be seen in `std::io::Result`.\n\n##### External Crates: `rand`\n\n`rand` is a Rust library which is part of the `rust-nursery` project. (It had\npreviously been part of `std`, but was moved when Rust decided to downsize its\nstandard library.) Good thing Cargo makes it so easy to add dependencies!\n\nTo use `rand`, you'll need to add it as a dependency to your `Cargo.toml` file.\n[The guide][crates-guide] on crates.io (which hosts crates) explains how Cargo\nadds and manages project dependencies.\nYou can find name and version information on [the page for `rand` on\ncrates.io](https://crates.io/crates/rand)\n\n[crates-guide]: http://doc.crates.io/guide.html#adding-dependencies\n\nYou also need to declare it (`extern crate rand`) in your crate's\ntop-level file (`main.rs`) in order to import and use modules from `rand` in\nyour project.\n\n##### Stack API\n\nYou should define a `Stack` struct, which should define at least the following\npublic methods:\n\n```rust\n/// Creates a new Stack\npub fn new() -> Stack {\n    unimplemented!()\n}\n\n/// Pushes a value onto the stack.\npub fn push(&mut self, val: Elt) -> Result<()> {\n    unimplemented!()\n}\n\n/// Tries to pop a value off of the stack.\npub fn pop(&mut self) -> Result<Elt> {\n    unimplemented!()\n}\n\n/// Tries to evaluate an operator using values on the stack.\npub fn eval(&mut self, op: Op) -> Result<()> {\n    unimplemented!()\n}\n```\n\nYou may implement the internals of your stack however you like, but we'd suggest\nusing a `Vec`.\n\n##### Calculator API\n\nThe tokens your parser should recognize and their corresponding interpretations\nare as follows:\n\n| Input token | Action                 |\n| ----------- | ---------------------- |\n| any integer | push Elt::Int(integer) |\n| \"true\"      | push Elt::Bool(true)   |\n| \"false\"     | push Elt::Bool(false)  |\n| \"+\"         | eval Op::Add           |\n| \"~\"         | eval Op::Neg           |\n| \"<->\"       | eval Op::Swap          |\n| \"=\"         | eval Op::Eq            |\n| \"#\"         | eval Op::Rand          |\n| \"quit\"      | eval Op::Quit          |\n\nAny other input is considered an error. Your calculator can read multiple tokens\non a single line, and will evaluate them in order. You can parse strings into\nintegers by using `i32::from_str()`.\n\nWe started two functions in `parser.rs` for reading and manipulating input:\n\n`read_eval_print_loop` will do just what it says on the tin: reads from `stdin`,\nevaluates some tokens, and then prints out a result. This tin comes with some\n~~cookies~~ 🍰 stub code, which prints a prompt and then (`try!`s to) flush\n`stdout` so you can read input.\n\n`evaluate_line` is a helper function to `read_eval_print_loop`. It takes the\ninput `String` and your calculator's `stack` and evaluates the tokens in that\nline. Currently, it takes the input string, trims off whitespace from the ends,\nand creates a `SplitWhitespace` iterator over the string.\n\n## Tests\n\nTests have been provided in the starter code. You can add as many tests as you\nwant (but you don't need to write any). Obviously, you should test your\ncalculator by using it.\n\n## Submission\n\nCommit and push your work to the master branch of your Classroom for Github\nrepository for this HW. Make sure it is visible on Github! This is your\nsubmission. (Work must be in the master branch at the due time.)\n\n`cargo test` should work to run all of the tests in your homework on stable\nRust. Make sure you have written tests which cover every one of your functions.\n\nIf you have any comments or feedback on this assignment, include them in the\nREADME of your submission.\n"
  },
  {
    "path": "hw05/README.md",
    "content": "# Homework 05: The ~~Fun-Time Reference Sharing~~ _Darkest_ Dungeon\n### It's not just a phase, _Mom_!\n\n**Due Friday, 2016-02-26, 11:59pm.**\n\nFor questions, please post on Piazza (Penn students) or Google Groups (other).\nLinks on course homepage.\n\n## Overview\n\nYou have found yourself standing at the entrace of a large, mysterious,\n~~smelly~~ castle. You must have taken a wrong turn when you were wandering\nthrough that dark, imposing, werewolfy forest. Why were you doing that?\nNevermind, it's not relevant. Just go on inside. There's treasure. I think.\nThere's definitely at least gold. This wouldn't be an adventure game if you\ncouldn't even find gold!\n\nAhem. Let me try this again:\n\n> _Wander forth for promises of grand treasures hidden in glamorous bejeweled\nchests and decrepit iron maidens, dangerous traps filled with poisonous spikes.\nClimb over the forgotten corpses of the fallen adventurers who have come before\nyou yet were not as blessed with luck._\n\nWait, seriously, _where_ is that smell coming from?\n\n#### Classroom for GitHub\n\nWe're using Classroom for GitHub, which manages private homework repositories\nfor students. To create your very own private homework repository (owned by\nus), click this link:\n\n* https://classroom.github.com/assignment-invitations/d7fc86f713d77fa96deed930a9e75244\n\n## Instructions\n\n- In this assignment we are going to build a text adventure game!\n\nOkay, we lied. The castle doesn't exist yet. All you have is some poorly\nwritten down map that someone shoved into your hand earlier. They didn't even\ndraw it out properly! It's written in some weird... \"JSON\" format.\n\n- Finish the JSON parser. The provided code parses a JSON file to create a\n  series of rooms connected by hallways. See below for more detail.\n\n[*Look around you*][]. What can you see? Nothing! You haven't implemented eyes\nyet. That doesn't make any sense. What are you doing. Nevermind, nevermind. Stop\nasking questions.\n\n[*Look around you*]: https://www.youtube.com/watch?v=gaI6kBVyu00\n\n- Print out a description of a room when you enter it, containing  adjacent\n  rooms accessable from your current location.\n\nWe promised you gold, and so there shall be gold! Some of these rooms contain\ntreasure and glory! Chests contain gold; food provides nourishment and restores\nhealth. Be sure to look closely: some curios, such as iron maidens and fallen\nadventurers, contain yet more items within them.\n\nBut beware! There is danger afoot. When you encounter a spike trap or iron\nmaiden, it will deal damage to your person.\n\n- Use all items in a room when you enter it, and output to the player\n  ~~a tale of their misery~~ a description of what happened to them. All items are\n  handled immediately but death visits at the end of the turn, so it is possible\n  to take fatal damage from a spike trap but immediately cure yourself with a\n  fistful of food to avoid death. Gold is added to your inventory. Items can\n  only be used once, so they should be removed from a room once used.\n\nIt wouldn't be an adventure if you were stuck in the entrance. You'd probably\ndie of boredom before you even died of thirst.\n\n- Implement `go [destination]` to move from your current location to any\n  room connected by a hallway.\n\nNow that you have the freedom of movement, you've finally come to a great,\nterrible, disgusting realization. You've remembered the legend of *the Wumpus*.\n\nThe Wumpus is a large, repulsive, oozing monster from which that putrid smell\nemanates. The Wumpus will consume your being if you happen upon the room where\nit makes its lair. However, you are no defenseless peasant; you have prepared\nwith your mighty bow and arrow. If you shoot an arrow toward the room a Wumpus\nlies in, it will surely kill the Wumpus, because you are a mighty warrior and\nall of your arrows fly true. Or maybe because the Wumpus is so big you can't\npossibly miss.\n\n- Implement `shoot [destination]` to shoot an arrow into a room and kill the\n  Wumpus if it's there.\n\nWhen you've killed the Wumpus, congratulations! You have freed this castle from\nits terrible and malodorous curse. All the land rejoices in your honor. You are\ncrowned as the exalted ruler for the people whose lives you have saved. There is\nno end of riches and luxury for you. Or something. Maybe you just go home and\nsmell the roses.\n\n## Demo\n\nIf this doesn't make any sense, or you aren't familiar with text adventures, you\ncan play this game on Eniac:\n\n```rust\n~cis198/local/bin/hw05 ~cis198/local/share/hw05/castle.json\n```\n\n### How To Play\n\nAfter building your project, you can run it with `cargo run\n[castle_description.json]`. A sample castle is provided in `data/castle.json`.\n\nThe available commands are `go [room]`, `shoot [room]`, and `quit`. Quit prints\nyour score, whether or not you've won, and exits the game. Dying, when your\nhealth falls below 0, also results in exiting the game.\n\nPlayers have a location (`Rc<RefCell<Room>>`, health (`i32`), gold (`i32`), and\nan account of whether they won (`bool`). Players can `Go` or `Shoot` a room.\n\nMovement between rooms should be implemented by replacing the stored\n`Rc<RefCell<Room>>` owned by the player.\n\n### Castle Structure\n\nA room in this castle contains a name (`String`), a list of contents\n(`Vec<Curio>`), a list of halls (`Vec<Rc<Hall>>`), and the possibility of a\nWumpus (`bool`). Halls each connect two rooms (two\n`Option<Rc<RefCell<Room>>>`s).\n\nSee the provided JSON file (`data/castle.json)`: Rooms are defined by name, the\nnumber of randomly-generated curios, and whether the wumpus is in that room.\nHalls are defined as tuples (in as much as JSON allows tuples) between room\nnumbers. Rooms are numbered in the order they are defined. Room names should be\nunique.\n\nEach room contains a set of Curios. The generation of Curios for a given room is\nprovided. The JSON parsing is provided; you will start by finishing room and\nhallway generation.\n\n\n## Testing\n\nNo tests! Yay!\n\nWe're not providing any tests nor expecting that you write any. We'll grade your\ngame by simply playing it.\n\n## Writeup\n\nEdit the README in your project with a (brief!) explanation of how `Rc` and\n`RefCell` are used and why they are necessary in this game.\n\n## Make your game more game\n\nApply as much creativity as you want to your game. Add your own maps,\nflavortext, additional curios, miscellaneous player effects. Extremely arbitrary\nnumbers of brownie points (which can be redeemed for real brownies!) will be\ndistributed for making your game more fun.\n\nPlease do not edit the structure of Rooms and Halls. Otherwise, you're missing\nthe point of this assignment!\n\nHighlight any interesting additions that you've made in your README.\n\n## Submission\n\nCommit and push your work to the master branch of your Classroom for Github\nrepository for this HW. Make sure it is visible on Github! This is your\nsubmission. (Work must be in the master branch at the due time.)\n\nIf you have any comments or feedback on this assignment, include them in the\nREADME of your submission.\n"
  },
  {
    "path": "hw06/README.md",
    "content": "# Homework 6: BB-198 - A Bulletin Board System (BBS)\n\n**Due Sunday, 2016-03-06, 11:59pm.**\n\nThe internet is the beginning of the hyper-connected future. Isn't it great?\nWe're working to create a new _wireless_ social network, where people can\ncommunicate with their friends over the internet! We think the next big product\nin this space will be bulletin board systems, where people in all different\nplaces can gather and share information throughout the world.\n\nYou've recently been hired as an engineer. Welcome to the team! Since we've\nheard that you have a lot of experience using Rust, you've been given\nresponsibility for this BBS project that we've just started. Good luck!\n\n#### Classroom for GitHub\n\nWe're using Classroom for GitHub, which manages private homework repositories\nfor students. To create your very own private homework repository (owned by\nus), click this link:\n\n* https://classroom.github.com/assignment-invitations/c674a59f072e68a140e54599fcf35e8f\n\n## Background\n\n### [`hyper.rs`][]\n\n[`hyper.rs`]: http://hyper.rs\n\n> Hyper is a fast, modern HTTP implementation written in and for Rust. It is a\nlow-level typesafe abstraction over raw HTTP, providing an elegant layer over\n\"stringly-typed\" HTTP.\n\nHyper is the beginning of the future. Hyper contains both a server, which\nmanually handles requests that it receives, and a client, which can build HTTP\nrequests and parse HTTP responses. You will use both in this assignment.\n\nHyper uses OpenSSL, which means OpenSSL needs to be installed.\n\nOn OS X, you need to set environment variables telling Cargo where to find\nOpenSSL headers on your computer. Read\n[this StackOverflow post][osx_ssl_instructions] and follow the instructions.\n\n[osx_ssl_instructions]: http://stackoverflow.com/questions/34612395/openssl-crate-fails-compilation-on-mac-os-x-10-11\n\nOn Linux, you may need to install a development package for OpenSSL (this\nprovides OpenSSL's header files, so Hyper can link against them). On Ubuntu, you\ncan install this with `apt-get install libssl-dev`.\n\n## Instructions\n\n### lib\n\nWe're going to build this BBS in a library crate, so it can be easily deployed\nto others who want to use it. This crate will contain `lib.rs` as before, which\ndefines common functions and types used in the rest of your project.\nAdditionally, the crate contains several binaries (located in `src/bin`). Each binary\nis a standalone Rust file, which uses the library as if it were an external\ncrate.\n\nHere's what's defined in `lib.rs`:\n\n- `Message`: a struct representing a post on the bulletin board, containing the\n  username and their message.\n- `UserClient`: a struct storing a username, the server address they make posts\n  to, and a `hyper::Client`, which can be used to make multiple requests to a\n  server.\n  - `get_content`: a method which builds a GET request to the stored server\n  address.\n- Some constants which are shared between binaries.\n  - `SERVER_ADDR`, `BOT_ADDR`: the addresses that the server and bot will listen\n    on.\n  - `HTML_ADDR`: the addresses the BBS is visible at (i.e. the\n    address you'd visit with browser)\n  - `HTML_HEADER`, `HTML_DATA`, `HTML_FOOTER`: the local files which the server\n    uses to generate the page.\n\n### `bin/server`\n\nProvided: A basic web server which can respond to GET requests at\nhttp://127.0.0.1:1980 and serves a static web page. It generates this static web\npage by concatenating two files (the header, and footer).\n\n* You may need to change the port numbers from 1980 to others if you are working\n  on Eniac, to avoid colliding with other servers.\n\nThis is the _future_, though. Static webpages are so _nineties_. Add to the\nexisting request handler (`req_handler`) the ability to receive posts through\nPOST requests. The body of a POST request will contain a JSON-encoded `Message`\n(defined in `lib.rs`). You should append each post to the bulletin board's data\npage (`HTML_DATA`) when it's received. You should also update the GET request\nhandler to include the posted messages when it generates a page.\n\n* For more context on RESTful APIs and the difference between GET and POST\n  requests, you can read this [StackOverflow page][restful].\n\n[restful]: https://stackoverflow.com/questions/671118/what-exactly-is-restful-programming\n\nNotice that, since the `bbs` library is external to this server, you need to\ndeclare it with `extern crate bbs` at the top of your file, and import parts as\nneeded.\n\n### `bin/client`\n\nProvided: A client which initializes a user and makes a GET request to read the\ncurrent bulletin board.\n\n_Boring._ The user of this software should be able to post a message to the\nbulletin board. Otherwise, this wouldn't be an innovation at all!\n\nWe'd like to provide our users with a clean, modern command-line interface for\nmaking posts to our bulletin board. It's up to you to design this. For example,\nyou may retain the current command line interface (where the user specifies\ntheir username), and allow the user to post messages to the BBS by reading from\nstandard input.\n\n### `bin/bot`\n\nOh no! You've put all of this hard work in, and your bulletin board still\ndoesn't have any users. ~~Because you have no friends,~~ To help build activity\nand user interest, you decide to build a bot service which will automatically\nrespond to certain types of messages on the board. This is exactly the sort of\nfun, exciting feature that people are looking for on the Web.\n\nAdd a new binary to your BBS crate which contains a bot.\n\nThis bot listens for TCP connections on port 1981 (as defined in `lib.rs`).\nWhenever the server receives a new post, it will make new connection to this bot,\nrelaying the contents of the post. The bot will read the post and determine if\nit should respond.\n\nThis is the future, so of course your bot will have to be connected to the\ninternet. When the bot receives a message of the form \"choose x y z\", it will\nmake a query to random.org's [HTTP API][random-api], asking for a value between\n1 and the length of the options. You can use `hyper::client` to receive and\nparse these queries. Then, the bot should post a message back to the server with\nthe appropriate choice (e.g. for a value of 2, your bot would post the message\n\"y\"). Bam. Random.org. _The future_.\n\n* You can easily build these query URLs with a format string. A simple example\n  (as given [here][random-api]) will generate ten integers in base 10, between 1\n  and 6, returned as a plaintext page:\n  https://www.random.org/integers/?num=10&min=1&max=6&col=1&base=10&format=plain&rnd=new\n\nYou are the head engineer on this project, so you are free to build any sort of\nbot functionality you want. If you want to do something different, just explain\nwhat you've done in your README.\n\n[random-api]: https://www.random.org/clients/http/\n\n### Feature List\n\nTo recap, here are all the features you should implement:\n\n- In `server.rs`:\n  - Handle `POST` requests in `req_handler`\n  - Update the `GET` handler in `req_handler` to generate a page containing the\n      post data\n- In `client.rs`:\n  - Create a command-line interface to allow users to easily send data to the\n      server\n- In `bot.rs`:\n  - Listen on port 1981 for incoming TCP connections to determine if new posts\n      have been made to the BBS\n  - Create a function to randomly choose \"x\", \"y\", or \"z\" from posts of the form\n      \"choose x y z\" using random.org's HTTP API\n\n## Submission\n\nCommit and push your work to the master branch of your Classroom for Github\nrepository for this HW. Make sure it is visible on Github! This is your\nsubmission. (Work must be in the master branch at the deadline.)\n\nIf you have any comments or feedback on this assignment, include them in the\nREADME of your submission.\n"
  },
  {
    "path": "hw07/README.md",
    "content": "# Homework 7: A Multithreaded Chat System\n\n**Due Wednesday, 2016-03-23, 11:59pm.**\n\nOkay, you admit it - a BBS isn't exactly the most modern web technology of all\ntime. Inspired by the rising success of this newfangled \"AOL Instant Messenger\"\nthing all the kids are using, you've decided to make your own chat service!\n\nIn this homework, you'll write your own multithreaded, multi-user, IRC-esque\nchat service! And as a bonus, it'll run in the browser using WebSockets!\n\n#### Classroom for GitHub\n\nWe're using Classroom for GitHub, which manages private homework repositories\nfor students. To create your very own private homework repository (owned by\nus), click this link:\n\n* https://classroom.github.com/assignment-invitations/8380d7698ae30e972cf46d5c80daa2a8\n\n## Background\n\n**This assignment should work on [any modern browser](http://caniuse.com/#feat=websockets); tested on Firefox and Chrome.**\n\n### WebSockets\n\nWebSockets are a web technology for allowing JavaScript in webpages to connect \nback to servers using a bidirectional data stream. WebSockets behave very\nsimilarly to TCP streams (but are message-based).\n\nWe will be using the `rust-websocket` library. You'll definitely need to take\na look at some of the documentation and examples:\n\n* [GitHub repo](https://github.com/cyderize/rust-websocket)\n* [Documentation](http://cyderize.github.io/rust-websocket/doc/websocket/)\n* [Example server](https://github.com/cyderize/rust-websocket/blob/master/examples/server.rs)\n\n### Multithreaded Networking\n\nIn this assignment, we'll be using threads to easily handle several network\nclients at once. One way to do this is to create one thread for each client.\nAs clients connect, a thread is spawned to manage that particular connection:\n\n```rust\n// fn listen\nfor connection in server {\n    // Spawn a client_thread.\n}\n```\n\nIn this paradigm, each _client thread_ will _block_ as it waits for data to\ncome in from its respective client. This can be expressed very elegantly using\niterators: every time a message comes in, the loop runs once. When the channel\ncloses, the loop terminates.\n\n```rust\n// fn client_thread\nfor message in client_recv.incoming_messages() {\n    // Handle message; relay via MPSC channel.\n}\n```\n\nIn the _relay thread_, each message received via the MPSC channel should be\nsent to all of the clients (including the originator). Once again, iterators\nallow us to use the MPSC receiver very nicely:\n\n```rust\n// fn relay_thread\nfor action in relay_mpsc_recv {\n    // Send message to all clients.\n}\n```\n\n**Aside:** For many applications, the one-thread-per-client model does not work\nwell. For systems which will have many (thousands or more) clients, spawning\nthousands of threads is very inefficient. In these cases, a more complex system\nwill typically be used; for example, several threads (usually about one per\ncore) might run in a thread pool, where each _asynchronously_ handles many\nclients. That is, each thread will periodically poll for incoming data from\neach client (_non-blocking_), rather than waiting for incoming data from a\nsingle client (_blocking_). For `rust-websocket`, there is a discussion\n[here](https://github.com/cyderize/rust-websocket/issues/6).\n\n### IRC Principals\n\nIRC (Internet Relay Chat) operates on very simple principals:\n\n* Maintain a list of all of the currently connected clients.\n* For each message that comes in, relay it back out to all of the clients.\n\nWe won't be implementing IRC precisely, but we will use the \"relay\" idea.\n\n## Instructions\n\n`main.rs` and `webpage.rs` are provided for you; they just serve a static HTML\nwebpage over **port 1980**. To access this, just run the server (`cargo run`)\nand open [localhost:1980](http://localhost:1980/) in a web browser.\nThe static webpage is also written for you.\n\nYour job is to write `chatserver.rs`. In `chatserver::start`, you should spawn\na thread to listen for incoming WebSockets connections on **port 1981**.\nWe've also given you a (de)serializable `enum ChatAction` - don't modify this;\nthe JavaScript code depends on it!\n\n**Note:** The messages received-from and sent-to the client should be JSON\nobject strings with the same form as `rustc_serialize`'s serialization of the\n`ChatAction` type. This means you can `json::encode` `ChatAction`s to create\ntext to send to the web browser, and `json::decode` to turn the web browser's\nmessages into `ChatAction`s.\n\nThe [example server](https://github.com/cyderize/rust-websocket/blob/master/examples/server.rs)\nwill be an important resource - you'll use a lot of the same boilerplate code.\n(Note: we aren't using a protocol; the protocol response isn't necessary.)\n\nNow, go check out the comments left in `chatserver.rs`!\n\n## Submission\n\nCommit and push your work to the master branch of your Classroom for Github\nrepository for this HW. Make sure it is visible on Github! This is your\nsubmission. (Work must be in the master branch at the deadline.)\n\nIf you have any comments or feedback on this assignment, include them in the\nREADME of your submission or post on Piazza or the Google Group.\n"
  }
]