CS 371 - Introduction to Artificial Intelligence
Homework #1 |

0. Reading, Starter Code, Peg Solitaire, and the Buckets Problem: Read R&N Chapter 3 through section 3.4.5. Download and study the supplied starter code (documentation). Read more about the Peg Solitaire and Buckets problems here. Give special attention to the implementation of PegSolitaireNode and BucketsNode, as these will serve as models for a SearchNode you will extend later.

1. **Breadth-First Search**: Complete the implementation of the Breadth-First Search
(BFS) class
BreadthFirstSearcher by filling in code after the given comments (in-class).
Node children should enter the queue in the same order that they appear in the
list returned by the expand method. With this and other search algorithms
to come, test your implementation with both
PegSolitaireNode and
BucketsNode by uncommenting the appropriate lines in
SearchTest.

2. **Depth-First Search**: Complete the implementation of the Depth-First Search
(DFS) class
DepthFirstSearcher by filling in code after the given comments (in-class).
Node children should be pushed onto the stack in the same order that they appear
in the list returned by the expand method.

3. **Depth-Limited Search**: Implement Depth-Limited Search (DLS) class DepthLimitedSearcher by
modifying your DepthFirstSearcher to take an integer depth limit as the single
contructor parameter, and not expanding/pushing nodes beyond the depth limit.

4. **Iterative-Deepening Depth-First Search**: Implement Iterative-Deepening
Depth-First Search (IDDFS) class IterativeDeepeningDepthFirstSearcher by
creating a new Searcher class extension that performs depth-limited searches to
depth limits 1, 2, 3, etc. until successful. Remember that the node count
of this Searcher is the sum of the node counts of all depth-limited searches
performed.

5. **Recursive Depth-First Search**: In many applications of depth-first search,
it is simpler to express it as a recursive algorithm. (Using a different
model of a search node, this permits one to make/undo state changes easily.)
Implement Search class extension RecursiveDepthFirstSearcher that performs a
recursive depth-first search of each child in the order that they appear in the
list returned by the expand method. Note that this implementation
effectively visits a node's children in the *reverse* order that they
would be visited in the iterative stack-based implementation of DepthFirstSearcher.

6. **Designing a Reverse-Perfect-Shuffle Magic Trick**: Implement class ReversePerfectShuffleNode according to
this specification.
Read the comments with great care to understand the specification of each
Searcher method. In addition, you will add a main method that prints the
results of a search, revealing the means to perform a card magic trick of my
design. **The printed output of the main method should simply be a sequence
of printed states, one per line, from the initial state to the goal state.**

ReversePerfectShuffleNode is a class modeling perfect reverse (a.k.a. anti-faro) in- and out-shuffles in order to find a means of working the four top cards into the 5th, 10th, 15th, and 20th positions.
A perfect shuffle is one where the deck is cut perfectly in half and then "riffled" together alternating one card from each half like the teeth of a zipper before being pushed together.
This is considered to be one of the most difficult sleights of hand in card magic, and it allows the performer to control the positions of all cards in the deck, rearranging the permutation in unexpected ways.
There are two perfect shuffles that differ according to whether the first card down comes from the top or bottom half.
A perfect **out-shuffle** leaves the top card on top, that is, **outside** the deck.
A perfect **in-shuffle** leaves the top card at the second card, that is, **inside** the deck.

A reverse perfect shuffle is just the opposite. See Figure 3 from Magical Mathematics: The Mathematical Ideas That Animate Great Magic Tricks by Persi Diaconis and Ron Graham.
After alternating cards are separated into two halves, one half is placed atop
the other. While perfect shuffles are one of the most difficult sleights of hand, this simple process of alternate up- and down-jogging of cards can be performed by most anyone.
As before, a reverse perfect **out-shuffle** leaves the top card on top, that is, **outside** the deck.
A reverse perfect **in-shuffle** leaves the top card right after the middle
of the deck, that is, **inside** the deck.

Here is an example of an integer sequence undergoing two subsequent shuffles:

[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51] After out-shuffle: [0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40, 42, 44, 46, 48, 50, 1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41, 43, 45, 47, 49, 51] After subsequent in-shuffle: [2, 6, 10, 14, 18, 22, 26, 30, 34, 38, 42, 46, 50, 3, 7, 11, 15, 19, 23, 27, 31, 35, 39, 43, 47, 51, 0, 4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44, 48, 1, 5, 9, 13, 17, 21, 25, 29, 33, 37, 41, 45, 49]

Quiz/exam preview: While not required for this homework, look at the written exercises at http://cs.gettysburg.edu/~tneller/resources/ai-search/uninformed-java/index.html to get a sense of questions I commonly include on quizzes and exams.

Rubric:

- 2 points: Breadth-First Search
- 2 points: Depth-First Search
- 2 points: Depth-Limited Search
- 4 points: Iterative-Deepening Depth-First Search
- 4 points: Recursive Depth-First Search
- 6 points: Reverse Perfect Shuffle