Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

More hints #123

Open
wants to merge 7 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 7 additions & 2 deletions labs/lab05/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -143,8 +143,10 @@ <h3 id="sample-execution-run-1">Sample Execution Run</h3>
<h3 id="submission-1">Submission</h3>
<p>You should submit your BST, any supporting C++ files, as well as a Makefile to compile everything into an <code>a.out</code> executable.</p>
<h3 id="hints-1">Hints</h3>
<p><strong>Private methods:</strong> Following the suggestion to implement private versions of all the public methods that take in BinaryNodes will help considerably. How should your public method interact with the private version? In other words, what node should the public method pass in?</p>
<p><strong>Passing pointers by reference:</strong> When a pointer is passed by reference, that allows us to change not only the data that the pointer is pointing to, but also <em>what the pointer is pointing to in the first place</em>. This is one option that allows you to change the structure of your tree without having to use parent pointers.</p>
<h4 id="use-private-methods">Use private methods</h4>
<p>Following the suggestion to implement private versions of all the public methods that take in BinaryNodes will help considerably. How should your public method interact with the private version? In other words, what node should the public method pass in?</p>
<h4 id="pass-pointers-by-reference">Pass pointers by reference</h4>
<p>When a pointer is passed by reference, that allows us to change not only the data that the pointer is pointing to, but also <em>what the pointer is pointing to in the first place</em>. This is one option that allows you to change the structure of your tree without having to use parent pointers.</p>
<hr />
<h2 id="post-lab-1">Post-lab</h2>
<p>The objective of this post-lab is to understand the run-time characteristics and trade-offs between normal Binary search trees and AVL trees. Your deliverable for this post-lab will be an AVL tree implementation.</p>
Expand Down Expand Up @@ -195,5 +197,8 @@ <h4 id="balancing">Balancing</h4>
endif
rotate right on node
endif</code></pre>
<h4 id="rotating">Rotating</h4>
<p>As was the case for Lab 2's insertion methods, it is extremely helpful to draw out how each node changes during the rotation <em>before</em> attempting to write the C++ implementation.</p>
<p>Did you take into account that the parent should now be pointing to a different node? What about the heights of each node?</p>
</body>
</html>
13 changes: 10 additions & 3 deletions labs/lab05/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -179,12 +179,14 @@ You should submit your BST, any supporting C++ files, as well as a Makefile to c

### Hints ###

**Private methods:** Following the suggestion to implement private
#### Use private methods ####
Following the suggestion to implement private
versions of all the public methods that take in BinaryNodes will help
considerably. How should your public method interact with the private
version? In other words, what node should the public method pass in?

**Passing pointers by reference:** When a pointer is passed by
#### Pass pointers by reference ####
When a pointer is passed by
reference, that allows us to change not only the data that the pointer
is pointing to, but also _what the pointer is pointing to in the first
place_. This is one option that allows you to change the structure of
Expand Down Expand Up @@ -242,7 +244,6 @@ You should submit your AVL tree, any supporting C++ files, and the Makefile.
### Hints ###

#### Balancing ####

`balance(AVLNode*& node)` is crucial for both insert and remove, but has many cases that you must account for. To help avoid potential issues, here is some pseudocode for the balance method that you may use:

```
Expand All @@ -262,3 +263,9 @@ balance(node):
rotate right on node
endif
```

#### Rotating ####
As was the case for Lab 2's insertion methods, it is extremely helpful to draw out how each node changes during the rotation _before_ attempting to write the C++ implementation.

Did you take into account that the parent should now be pointing to a different node?
What about the heights of each node?
9 changes: 5 additions & 4 deletions labs/lab06/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ <h3 id="overview">Overview</h3>
<li>Take in a dictionary file and grid file, in that order, using command line parameters</li>
<li>Read in a dictionary and store its words in a hash table
<ul>
<li>Which is implemented without using a vector of vectors or any STL hash table</li>
<li>Which is implemented without using a vector of vectors, <code>unordered_set</code>, or <code>unordered_map</code></li>
</ul></li>
<li>Read in a word search grid no larger than 500x500 and store it in an appropriate data structure</li>
<li>Output every word of length three or greater and its location in the grid
Expand All @@ -83,7 +83,7 @@ <h3 id="overview">Overview</h3>
<p>We are not as interested in how fast your program runs for the pre-lab; leave any optimizations for the post-lab.</p>
<h3 id="storing-the-dictionary">Storing the dictionary</h3>
<p>As there may be a large number of words in the dictionary, you will have to store those words in a hash table to facilitate efficient lookup.</p>
<p>You <strong>must</strong> write your own hash table for this lab. We leave the implementation up to you, as long as you do not use a vector of vectors or any STL hash table.</p>
<p>You <strong>must</strong> write your own hash table for this lab. We leave the implementation up to you, as long as you do not use a vector of vectors, <code>unordered_set</code>, or <code>unordered_map</code>.</p>
<h3 id="manipulating-the-grid">Manipulating the grid</h3>
<p><a href="code/getWordInGrid.cpp.html">getWordInGrid.cpp</a> (<a href="code/getWordInGrid.cpp">src</a>) provides two useful functions: <code>readInGrid()</code> and <code>getWordInGrid()</code>. The former reads in a grid file using C++ streams; the latter returns a word in a 2D grid of letters in a given direction.</p>
<p>You should make sure you understand how these functions work, as you will most likely be using them in your final program.</p>
Expand Down Expand Up @@ -119,8 +119,9 @@ <h4 id="that-hint-didnt-help-i-still-have-no-clue-how-to-start">That hint didn't
<p>Start off by reading in the dictionary and printing out all of its words. Then store those words in a hashtable (probably the STL one for now). Great, you have a dictionary now.</p>
<p>Next, read in the grid (use the functions in <code>getWordInGrid.cpp</code> to help you!). Plan out how to use the dictionary to find all the valid words in the grid. There are four variables that control what word is returned -- what does that imply in terms of loops?</p>
<p>At this point, hopefully you have enough to get you going.</p>
<h4 id="storing-the-grid">Storing the grid</h4>
<p>Creating a dynamic 2D array in C++ is more difficult than it should be -- one solution is to create a vector of vectors, but that is not the most efficient means to do it. For this lab, you can just create a 500x500 static array, and can assume that you will not have your program run on larger input grids. This is not very elegant, but it will work until we go over dynamic array creation in lecture.</p>
<h4 id="it-almost-works...but-now-im-getting-duplicate-words">It almost works...but now I'm getting duplicate words</h4>
<p>Take a closer look at the documentation for the <code>getWordInGrid</code> function!<br />
In particular, does it say anything about what it returns when it reaches the end of the grid? How might you account for that in your code?</p>
<h4 id="command-line-parameters">Command-line parameters</h4>
<p>Your program must be able to run successfully if started with <code>./a.out &lt;dictionary_file&gt; &lt;grid_file&gt;</code> and no input.</p>
<p>See the <a href="../../slides/04-arrays-bigoh.html">slide set on arrays</a> if you need a refresher on command-line parameters; you can also see the <a href="../../slides/code/04-arrays-bigoh/cmdlineparams.cpp.html">cmdlineparams.cpp</a> (<a href="../../slides/code/04-arrays-bigoh/cmdlineparams.cpp">src</a>) file.</p>
Expand Down
12 changes: 6 additions & 6 deletions labs/lab06/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ Your word search solver, implemented in `wordPuzzle.cpp`, should:

- Take in a dictionary file and grid file, in that order, using command line parameters
- Read in a dictionary and store its words in a hash table
- Which is implemented without using a vector of vectors or any STL hash table
- Which is implemented without using a vector of vectors, `unordered_set`, or `unordered_map`
- Read in a word search grid no larger than 500x500 and store it in an appropriate data structure
- Output every word of length three or greater and its location in the grid
- The required output format is described below
Expand All @@ -91,7 +91,7 @@ We are not as interested in how fast your program runs for the pre-lab; leave an
As there may be a large number of words in the dictionary, you will have to store those words in a hash table to facilitate efficient lookup.

You **must** write your own hash table for this lab.
We leave the implementation up to you, as long as you do not use a vector of vectors or any STL hash table.
We leave the implementation up to you, as long as you do not use a vector of vectors, `unordered_set`, or `unordered_map`.

### Manipulating the grid ###

Expand Down Expand Up @@ -161,10 +161,10 @@ There are four variables that control what word is returned -- what does that im

At this point, hopefully you have enough to get you going.

#### Storing the grid ####
Creating a dynamic 2D array in C++ is more difficult than it should be -- one solution is to create a vector of vectors, but that is not the most efficient means to do it.
For this lab, you can just create a 500x500 static array, and can assume that you will not have your program run on larger input grids.
This is not very elegant, but it will work until we go over dynamic array creation in lecture.
#### It almost works...but now I'm getting duplicate words ####
Take a closer look at the documentation for the `getWordInGrid` function!\
In particular, does it say anything about what it returns when it reaches the end of the grid?
How might you account for that in your code?

#### Command-line parameters ####
Your program must be able to run successfully if started with `./a.out <dictionary_file> <grid_file>` and no input.
Expand Down
7 changes: 4 additions & 3 deletions labs/lab09-64bit/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -88,9 +88,8 @@ <h3 id="testing-and-timing">Testing and timing</h3>
<p>You should use an appropriate precision number to make sure you don't report zero when you divide the total time by the number of runs. Your timer code should only include the loop of <em>n</em> times that calls the routine with <em>x</em> as the parameter. Nothing else (including the print statement) should be inside the timer code.</p>
<h3 id="optimization">Optimization</h3>
<p>Now that you can time your program, you will need to optimize it as much as possible. Any optimization is valid, as long as it computes the correct result, is still a recursive subroutine, and follows the C calling convention. The grade on this pre-lab will be based both on the correctness of the subroutine and the optimizations included.</p>
<p>What optimizations do you use?</p>
<p>Put the optimizations used as a comment in the beginning of your assembly file. Here are a few suggestions:</p>
<ul>
<li>First, try to figure out how you can write the same routine using fewer x86 instructions. x86 has lots of complex instructions that can be used for this purpose -- Google is your friend, here.</li>
<li><code>lea</code> can quickly add and multiply numbers in one instruction.</li>
<li>Multiplication and division are expensive. Try to use bit shifts whenever possible -- <code>4*x+x</code> is likely to be faster than <code>5*x</code>, as the former can be optimized to <code>x &lt;&lt; 2 + x</code>.</li>
<li>Branching slows down the execution speed of a program as the branch condition must be checked every iteration. As much as possible, eliminate branching (if/else statements, loops, etc.). For loops, consider <a href="http://en.wikipedia.org/wiki/Loop_unrolling">loop unrolling</a>.</li>
Expand All @@ -99,7 +98,6 @@ <h3 id="optimization">Optimization</h3>
<li>Reduce the registers that are backed up to the stack in the calling convention</li>
<li>Many optimizations are listed <a href="http://en.wikipedia.org/wiki/Category:Compiler_optimizations">here</a>, but most would not apply to this one program.</li>
</ul>
<p>You will need to include at least one optimization beyond just figuring out how to write your subroutine with fewer instructions. You should put the optimizations used as a comment in the beginning of your assembly file.</p>
<p>Note that we, too, can write the function in C++ and compile it with <code>clang++ -O2 -S -mllvm --x86-asm-syntax=intel</code>. And we will be looking at that assembly code when we grade the pre-lab. If you write your program this way, it constitutes an honor violation, so please hand-code the assembly yourself.</p>
<p><strong>You must list, as comments in your assembly file, the optimizations that you used!</strong> Just a brief description of what optimizations you used is fine.</p>
<h3 id="sample-execution-run">Sample Execution Run</h3>
Expand All @@ -109,6 +107,9 @@ <h3 id="sample-execution-run">Sample Execution Run</h3>
Iterations: 25</code></pre>
<h3 id="different-architectures">Different Architectures</h3>
<p>See the <a href="../lab08/index.html">last lab</a> for details, but all code must be submitted to run under Linux, which is the platform that does the compilation on the submission system.</p>
<h3 id="hints">Hints</h3>
<h4 id="no-hints-yet...">No hints yet...</h4>
<p>We haven't noticed anything that we feel warrants a hint. If you think something belongs here, please let the professors know!</p>
<hr />
<h2 id="in-lab-1">In-lab</h2>
<h3 id="complete-the-c-tutorials-exercise-program">Complete the C tutorial's exercise program</h3>
Expand Down
12 changes: 8 additions & 4 deletions labs/lab09-64bit/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -103,9 +103,9 @@ You should use an appropriate precision number to make sure you don't report zer

Now that you can time your program, you will need to optimize it as much as possible. Any optimization is valid, as long as it computes the correct result, is still a recursive subroutine, and follows the C calling convention. The grade on this pre-lab will be based both on the correctness of the subroutine and the optimizations included.

What optimizations do you use?
Put the optimizations used as a comment in the beginning of your assembly file.
Here are a few suggestions:

- First, try to figure out how you can write the same routine using fewer x86 instructions. x86 has lots of complex instructions that can be used for this purpose -- Google is your friend, here.
- `lea` can quickly add and multiply numbers in one instruction.
- Multiplication and division are expensive. Try to use bit shifts whenever possible -- `4*x+x` is likely to be faster than `5*x`, as the former can be optimized to `x << 2 + x`.
- Branching slows down the execution speed of a program as the branch condition must be checked every iteration. As much as possible, eliminate branching (if/else statements, loops, etc.). For loops, consider [loop unrolling](http://en.wikipedia.org/wiki/Loop_unrolling).
Expand All @@ -114,8 +114,6 @@ What optimizations do you use?
- Reduce the registers that are backed up to the stack in the calling convention
- Many optimizations are listed [here](http://en.wikipedia.org/wiki/Category:Compiler_optimizations), but most would not apply to this one program.

You will need to include at least one optimization beyond just figuring out how to write your subroutine with fewer instructions. You should put the optimizations used as a comment in the beginning of your assembly file.

Note that we, too, can write the function in C++ and compile it with `clang++ -O2 -S -mllvm --x86-asm-syntax=intel`. And we will be looking at that assembly code when we grade the pre-lab. If you write your program this way, it constitutes an honor violation, so please hand-code the assembly yourself.

**You must list, as comments in your assembly file, the optimizations that you used!** Just a brief description of what optimizations you used is fine.
Expand All @@ -134,6 +132,12 @@ Iterations: 25

See the [last lab](../lab08/index.html) for details, but all code must be submitted to run under Linux, which is the platform that does the compilation on the submission system.

### Hints ###

#### No hints yet... ####
We haven't noticed anything that we feel warrants a hint.
If you think something belongs here, please let the professors know!

------------------------------------------------------------

In-lab
Expand Down
7 changes: 5 additions & 2 deletions labs/lab11/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -139,8 +139,6 @@ <h3 id="how-to-proceed">How to proceed</h3>
</ol>
<p>Your final program should should print out the shortest path as the last thing printed. You can print out multiple paths as you find the shortest one, but you should <strong>NOT</strong> print out <em>every</em> path you try.</p>
<p>Note that you are determining a cycle of cities to visit. So if your cycle has the cities in reverse, then it's still a valid solution.</p>
<h3 id="getting-your-itinerary-correct">Getting your itinerary correct</h3>
<p>The starting city is <strong>not to be permuted</strong>, as you will always start (and end) at that city. It's the <em>other</em> cities that are going to be permuted through the calls to <code>next_permutation()</code>.</p>
<h3 id="timing-your-code">Timing your code</h3>
<p>Keep in mind that as you increase the size of the city tour, the running time increases exponentially. Modern-day computers can probably compute about 200,000 routes per second (with well written and optimized code). Our 10-route cycle took 18 seconds. A 15 route cycle would take 2.5 months. A 20 route cycle would take 385,734 years! Realistically, you shouldn't be trying anything with an itinerary greater than 9 or 10.</p>
<p>And when you are planning on testing long paths, you should really compile your code with the <code>-O2</code> compiler option. It can speed up the program by a factor of two.</p>
Expand Down Expand Up @@ -174,6 +172,11 @@ <h3 id="sample-output">Sample output</h3>
<p>Your final program needs to both be able to compile and run with the specified command-line parameters.</p>
<h3 id="makefile-1">Makefile</h3>
<p>Your Makefile should have <strong>only one</strong> target, which you can name anything you want. This target should do <strong>two</strong> things: compile your code, and run doxygen. You can have two tabbed lines after the target specifier, which is the easiest way to accomplish this. In other words, we are just going to call <code>make</code>, and we want it to both compile your code and create your doxygen documentation. The in-lab Makefile should have the same dual-purpose target.</p>
<h3 id="hints">Hints</h3>
<h4 id="getting-your-itinerary-correct">Getting your itinerary correct</h4>
<p>The starting city is <strong>not to be permuted</strong>, as you will always start (and end) at that city. It's the <em>other</em> cities that are going to be permuted through the calls to <code>next_permutation()</code>.</p>
<h4 id="getting-your-itinerary-correct-part-2">Getting your itinerary correct, part 2</h4>
<p><code>next_permutation</code> assumes that it started out with a sorted vector! Did you sort your itinerary before starting to permute it?</p>
<hr />
<h2 id="post-lab-1">Post-lab</h2>
<p>Consider the <a href="https://en.wikipedia.org/wiki/15_puzzle">Sliding 8-Puzzle</a> game, depicted in the image below. If you'd like, you can play the puzzle <a href="http://www.artbylogic.com/puzzles/numSlider/numberShuffle.htm?rows=3&amp;cols=3&amp;sqr=1">HERE</a> to get a better sense for how the game works.</p>
Expand Down
Loading