mirror of
https://github.com/ossu/computer-science.git
synced 2026-04-11 14:21:57 +08:00
fundies2 complete
This commit is contained in:
parent
c5430695c2
commit
b93344da2f
@ -0,0 +1,12 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<classpath>
|
||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-11">
|
||||
<attributes>
|
||||
<attribute name="module" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="src" path="src"/>
|
||||
<classpathentry kind="lib" path="/Users/nathanhoward/Documents/Code/OSSU-CS/completedwork/core_programming/02_classbased_design/Jars/tester.jar"/>
|
||||
<classpathentry kind="lib" path="/Users/nathanhoward/Documents/Code/OSSU-CS/completedwork/core_programming/02_classbased_design/Jars/javalib.jar"/>
|
||||
<classpathentry kind="output" path="bin"/>
|
||||
</classpath>
|
||||
@ -0,0 +1,17 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>Assn10_Mazes</name>
|
||||
<comment></comment>
|
||||
<projects>
|
||||
</projects>
|
||||
<buildSpec>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.jdt.core.javabuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
||||
@ -0,0 +1,2 @@
|
||||
eclipse.preferences.version=1
|
||||
encoding/<project>=UTF-8
|
||||
@ -0,0 +1,11 @@
|
||||
eclipse.preferences.version=1
|
||||
org.eclipse.jdt.core.compiler.codegen.targetPlatform=11
|
||||
org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
|
||||
org.eclipse.jdt.core.compiler.compliance=11
|
||||
org.eclipse.jdt.core.compiler.debug.lineNumber=generate
|
||||
org.eclipse.jdt.core.compiler.debug.localVariable=generate
|
||||
org.eclipse.jdt.core.compiler.debug.sourceFile=generate
|
||||
org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled
|
||||
org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning
|
||||
org.eclipse.jdt.core.compiler.release=enabled
|
||||
org.eclipse.jdt.core.compiler.source=11
|
||||
@ -0,0 +1,126 @@
|
||||
import java.util.Deque;
|
||||
import java.util.ArrayDeque;
|
||||
import java.util.ArrayList;
|
||||
|
||||
// Represents a mutable collection of items
|
||||
interface ICollection<T> {
|
||||
// Is this collection empty?
|
||||
boolean isEmpty();
|
||||
// EFFECT: adds the item to the collection
|
||||
void add(T item);
|
||||
// Returns the first item of the collection
|
||||
// EFFECT: removes that first item
|
||||
T remove();
|
||||
}
|
||||
|
||||
// first in first out
|
||||
class Stack<T> implements ICollection<T> {
|
||||
Deque<T> contents;
|
||||
Stack() {
|
||||
this.contents = new ArrayDeque<T>();
|
||||
}
|
||||
public boolean isEmpty() {
|
||||
return this.contents.isEmpty();
|
||||
}
|
||||
public T remove() {
|
||||
return this.contents.removeLast();
|
||||
}
|
||||
public void add(T item) {
|
||||
this.contents.addFirst(item);
|
||||
}
|
||||
}
|
||||
|
||||
// last in last out
|
||||
class Queue<T> implements ICollection<T> {
|
||||
Deque<T> contents;
|
||||
Queue() {
|
||||
this.contents = new ArrayDeque<T>();
|
||||
}
|
||||
public boolean isEmpty() {
|
||||
return this.contents.isEmpty();
|
||||
}
|
||||
public T remove() {
|
||||
return this.contents.removeLast();
|
||||
}
|
||||
public void add(T item) {
|
||||
this.contents.addLast(item); // NOTE: Different from Stack!
|
||||
}
|
||||
}
|
||||
|
||||
// highest priority out
|
||||
class PriorityQueue<T> implements ICollection<T> {
|
||||
ArrayList<T> heap;
|
||||
IComparator<T> comp;
|
||||
PriorityQueue(ArrayList<T> inputList, IComparator<T> comp) {
|
||||
this.comp = comp;
|
||||
buildHeap(inputList);
|
||||
}
|
||||
PriorityQueue(IComparator<T> comp) {
|
||||
this(new ArrayList<T>(), comp);
|
||||
}
|
||||
void buildHeap(ArrayList<T> inputList) {
|
||||
this.heap = inputList;
|
||||
for (int i = inputList.size() - 1; i >= 0; i--) {
|
||||
this.downHeap(i);
|
||||
}
|
||||
}
|
||||
// swaps the parent and child items
|
||||
void swap(int parentIndex, int childIndex) {
|
||||
T temp = heap.get(parentIndex);
|
||||
heap.set(parentIndex, heap.get(childIndex));
|
||||
heap.set(childIndex, temp);
|
||||
}
|
||||
// recursively uses comp to compare child with parent
|
||||
// and swaps if child is higher priority
|
||||
void upHeap(int childIndex) {
|
||||
int parentIndex = (childIndex - 1) / 2;
|
||||
// comp will return >0 if left has higher priority than right
|
||||
// ergo swap when comp returns <0
|
||||
if (comp.compare(heap.get(parentIndex), heap.get(childIndex)) < 0) {
|
||||
this.swap(parentIndex, childIndex);
|
||||
this.upHeap(parentIndex);
|
||||
}
|
||||
}
|
||||
// recursively uses comp to compare parent with children
|
||||
// and swaps if child is higher priority
|
||||
void downHeap(int parentIndex) {
|
||||
this.downHeapMaxDepth(parentIndex, this.heap.size());
|
||||
}
|
||||
void downHeapMaxDepth(int parentIndex, int maxDepthIndex) {
|
||||
int leftChildIndex = 2 * parentIndex + 1;
|
||||
int rightChildIndex = 2 * parentIndex + 2;
|
||||
if (rightChildIndex < maxDepthIndex) {
|
||||
if (comp.compare(heap.get(leftChildIndex), heap.get(rightChildIndex)) > 0) {
|
||||
if (comp.compare(heap.get(parentIndex), heap.get(leftChildIndex)) < 0) {
|
||||
this.swap(parentIndex, leftChildIndex);
|
||||
this.downHeapMaxDepth(leftChildIndex, maxDepthIndex);
|
||||
}
|
||||
} else if (comp.compare(heap.get(parentIndex), heap.get(rightChildIndex)) < 0) {
|
||||
this.swap(parentIndex, rightChildIndex);
|
||||
this.downHeapMaxDepth(rightChildIndex, maxDepthIndex);
|
||||
}
|
||||
} else if (leftChildIndex < maxDepthIndex) {
|
||||
if (comp.compare(heap.get(parentIndex), heap.get(leftChildIndex)) < 0) {
|
||||
this.swap(parentIndex, leftChildIndex);
|
||||
this.downHeapMaxDepth(leftChildIndex, maxDepthIndex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Interface methods
|
||||
public boolean isEmpty() {
|
||||
return this.heap.isEmpty();
|
||||
}
|
||||
public void add(T item) {
|
||||
this.heap.add(item);
|
||||
this.upHeap(heap.size() - 1);
|
||||
}
|
||||
public T remove() {
|
||||
int lastIndex = this.heap.size() - 1;
|
||||
this.swap(0, lastIndex);
|
||||
T response = this.heap.remove(lastIndex);
|
||||
this.downHeap(0);
|
||||
return response;
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,44 @@
|
||||
interface IPred<T> {
|
||||
boolean apply(T t);
|
||||
}
|
||||
|
||||
interface IFunc<A, R> {
|
||||
R apply(A arg);
|
||||
}
|
||||
|
||||
interface IFunc2<A1, A2, R> {
|
||||
R apply(A1 arg1, A2 arg2);
|
||||
}
|
||||
|
||||
interface IComparator<T> {
|
||||
// Returns a negative number if t1 priority is less than t2 priority==-
|
||||
int compare(T t1, T t2);
|
||||
}
|
||||
|
||||
class ParentLargerInteger implements IComparator<Integer> {
|
||||
// returns true (>0) if left has higher priority (larger int)
|
||||
public int compare(Integer left, Integer right) {
|
||||
return left - right;
|
||||
}
|
||||
}
|
||||
|
||||
class ParentSmallerInteger implements IComparator<Integer> {
|
||||
// returns true (>0) if left has a higher priority (smaller int)
|
||||
public int compare(Integer left, Integer right) {
|
||||
return right - left;
|
||||
}
|
||||
}
|
||||
|
||||
class ParentLargerEdge implements IComparator<Hall> {
|
||||
// returns true (>0) if left edge has a higher priority (lower weight)
|
||||
public int compare(Hall left, Hall right) {
|
||||
return left.weight - right.weight;
|
||||
}
|
||||
}
|
||||
|
||||
class ParentSmallerEdge implements IComparator<Hall> {
|
||||
// returns true (>0) if left edge has a higher priority (higher weight)
|
||||
public int compare(Hall left, Hall right) {
|
||||
return right.weight - left.weight;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,213 @@
|
||||
import java.util.ArrayDeque;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Deque;
|
||||
import java.util.HashMap;
|
||||
import javalib.impworld.*;
|
||||
import java.awt.Color;
|
||||
import javalib.worldimages.*;
|
||||
import java.util.Random;
|
||||
|
||||
class Room {
|
||||
String name; // names are needed for Kruskal's algo
|
||||
ArrayList<Hall> neighborConnections;
|
||||
ArrayList<Hall> openHalls;
|
||||
int row, col;
|
||||
Room(String name, ArrayList<Hall> neighbors, ArrayList<Hall> openHalls, int row, int col) {
|
||||
this.name = name;
|
||||
this.neighborConnections = neighbors;
|
||||
this.openHalls = openHalls;
|
||||
this.row = row;
|
||||
this.col = col;
|
||||
}
|
||||
Room(String name, int row, int col) {
|
||||
this(name, new ArrayList<Hall>(), new ArrayList<Hall>(), row, col);
|
||||
}
|
||||
Room(int row, int col) {
|
||||
this(Integer.toString(row) + Integer.toString(col), new ArrayList<Hall>(),
|
||||
new ArrayList<Hall>(), row, col);
|
||||
}
|
||||
void addNeighbor(Hall e) {
|
||||
this.neighborConnections.add(e);
|
||||
}
|
||||
void addOpenHall(Hall e) {
|
||||
this.openHalls.add(e);
|
||||
}
|
||||
|
||||
void drawRoom(WorldScene scene, Color color) {
|
||||
scene.placeImageXY(
|
||||
new RectangleImage(
|
||||
MazeWorld.ROOM_SIZE_PX,
|
||||
MazeWorld.ROOM_SIZE_PX,
|
||||
OutlineMode.SOLID,
|
||||
color),
|
||||
col * (MazeWorld.ROOM_SIZE_PX + MazeWorld.WALL_SIZE_PX)
|
||||
+ (MazeWorld.ROOM_SIZE_PX + MazeWorld.WALL_SIZE_PX) / 2,
|
||||
row * (MazeWorld.ROOM_SIZE_PX + MazeWorld.WALL_SIZE_PX)
|
||||
+ (MazeWorld.ROOM_SIZE_PX + MazeWorld.WALL_SIZE_PX) / 2);
|
||||
}
|
||||
}
|
||||
|
||||
class Hall {
|
||||
String name; // names are needed for Kruskal's algo
|
||||
Room from, to;
|
||||
int weight; // random weights are used to facilitate maze gen
|
||||
Hall(String name, Room from, Room to, int weight) {
|
||||
this.name = name;
|
||||
this.from = from;
|
||||
this.to = to;
|
||||
this.weight = weight;
|
||||
from.addNeighbor(this);
|
||||
to.addNeighbor(this);
|
||||
}
|
||||
Hall(Room from, Room to, int weight) {
|
||||
this(from.name + to.name, from, to, weight);
|
||||
}
|
||||
|
||||
void drawHall(WorldScene scene) {
|
||||
scene.placeImageXY(
|
||||
new RectangleImage(
|
||||
MazeWorld.ROOM_SIZE_PX - 1,
|
||||
MazeWorld.ROOM_SIZE_PX - 1,
|
||||
OutlineMode.SOLID,
|
||||
MazeWorld.ROOM_COLOR),
|
||||
(from.col + to.col) * (MazeWorld.ROOM_SIZE_PX + MazeWorld.WALL_SIZE_PX) / 2
|
||||
+ (MazeWorld.ROOM_SIZE_PX + MazeWorld.WALL_SIZE_PX) / 2,
|
||||
(from.row + to.row) * (MazeWorld.ROOM_SIZE_PX + MazeWorld.WALL_SIZE_PX) / 2
|
||||
+ (MazeWorld.ROOM_SIZE_PX + MazeWorld.WALL_SIZE_PX) / 2);
|
||||
}
|
||||
}
|
||||
|
||||
class Maze {
|
||||
int width, height; // number of vertices across and down
|
||||
Random rand;
|
||||
|
||||
ArrayList<Room> rooms;
|
||||
ArrayList<Hall> routeTree;
|
||||
ArrayList<Room> searchTree;
|
||||
|
||||
Maze(int width, int height, Random rand) {
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
this.rand = rand;
|
||||
genVertsAndEdges();
|
||||
genRouteTree();
|
||||
}
|
||||
Maze(int size) {
|
||||
this(size, size, new Random());
|
||||
}
|
||||
Maze(int width, int height) {
|
||||
this(width, height, new Random());
|
||||
}
|
||||
Maze(int width, int height, int seed) {
|
||||
this(width, height, new Random(seed));
|
||||
}
|
||||
void genVertsAndEdges() {
|
||||
this.rooms = new ArrayList<Room>();
|
||||
// generate all the vertices
|
||||
for (int i = 0; i < width * height; i++) {
|
||||
Room v = new Room(Integer.toString(i), i / width, i % width);
|
||||
// connect to vertex to the left (right comes for free with next vertex)
|
||||
if (i % width != 0) {
|
||||
new Hall(this.rooms.get(i - 1), v, rand.nextInt(10));
|
||||
}
|
||||
// connect to vertex above (below comes for free)
|
||||
if (i >= width) {
|
||||
new Hall(this.rooms.get(i - width), v, rand.nextInt(10));
|
||||
}
|
||||
this.rooms.add(v);
|
||||
}
|
||||
}
|
||||
//Kruskal's Tree Algo
|
||||
void genRouteTree() {
|
||||
this.routeTree = new ArrayList<Hall>();
|
||||
|
||||
HashMap<String, String> setMap = new HashMap<String, String>();
|
||||
PriorityQueue<Hall> worklist = new PriorityQueue<Hall>(new ParentSmallerEdge());
|
||||
|
||||
for (Room v : this.rooms) {
|
||||
// initialize every node's representative to itself
|
||||
setMap.put(v.name, v.name);
|
||||
for (Hall e : v.neighborConnections) {
|
||||
// all edges in graph, sorted by edge weights
|
||||
worklist.add(e);
|
||||
}
|
||||
}
|
||||
Util u = new Util();
|
||||
while (!u.isOneTree(this.rooms, setMap)) {
|
||||
Hall lowestCostEdge = worklist.remove();
|
||||
if (u.sameTree(lowestCostEdge.from.name, lowestCostEdge.to.name, setMap)) {
|
||||
// discard this edge
|
||||
// they're already connected
|
||||
} else {
|
||||
routeTree.add(lowestCostEdge);
|
||||
u.union(setMap, lowestCostEdge.to.name, lowestCostEdge.from.name);
|
||||
}
|
||||
}
|
||||
for (Hall h : this.routeTree) {
|
||||
h.from.addOpenHall(h);
|
||||
h.to.addOpenHall(h);
|
||||
}
|
||||
}
|
||||
void breadthFirstSearch() {
|
||||
this.searchTree = findPath(
|
||||
this.rooms.get(0),
|
||||
this.rooms.get(rooms.size() - 1),
|
||||
new Queue<Room>());
|
||||
}
|
||||
void depthFirstSearch() {
|
||||
this.searchTree = findPath(
|
||||
this.rooms.get(0),
|
||||
this.rooms.get(rooms.size() - 1),
|
||||
new Stack<Room>());
|
||||
}
|
||||
ArrayList<Room> findPath(Room from, Room to, ICollection<Room> worklist) {
|
||||
ArrayList<Room> alreadySeen = new ArrayList<Room>();
|
||||
|
||||
// Initialize the worklist with the from vertex
|
||||
worklist.add(from);
|
||||
// As long as the worklist isn't empty...
|
||||
while (!worklist.isEmpty()) {
|
||||
Room next = worklist.remove();
|
||||
if (next.equals(to)) {
|
||||
return alreadySeen; // Success!
|
||||
} else if (alreadySeen.contains(next)) {
|
||||
// do nothing: we've already seen this one
|
||||
} else {
|
||||
// add all the neighbors of next to the worklist for further processing
|
||||
for (Hall h : next.neighborConnections) {
|
||||
worklist.add(h.to);
|
||||
}
|
||||
// add next to alreadySeen, since we're done with it
|
||||
alreadySeen.add(next);
|
||||
}
|
||||
}
|
||||
// We haven't found the to vertex, and there are no more to try
|
||||
throw new RuntimeException("Could not find a valid path");
|
||||
}
|
||||
|
||||
void drawMaze(WorldScene scene) {
|
||||
scene.placeImageXY(
|
||||
new RectangleImage(
|
||||
width * (MazeWorld.ROOM_SIZE_PX + MazeWorld.WALL_SIZE_PX),
|
||||
height * (MazeWorld.ROOM_SIZE_PX + MazeWorld.WALL_SIZE_PX),
|
||||
OutlineMode.SOLID,
|
||||
MazeWorld.WALL_COLOR),
|
||||
width * (MazeWorld.ROOM_SIZE_PX + MazeWorld.WALL_SIZE_PX) / 2,
|
||||
height * (MazeWorld.ROOM_SIZE_PX + MazeWorld.WALL_SIZE_PX) / 2);
|
||||
// draw each room slightly small
|
||||
Color roomColor = MazeWorld.ROOM_COLOR;
|
||||
for (Room r : this.rooms) {
|
||||
r.drawRoom(scene, roomColor);
|
||||
}
|
||||
for (Hall h : this.routeTree) {
|
||||
h.drawHall(scene);
|
||||
}
|
||||
}
|
||||
void drawSearchTree(WorldScene scene, int tickCount) {
|
||||
Color searchColor = MazeWorld.SEARCH_COLOR;
|
||||
for (int i = 0; i <= tickCount && i < this.searchTree.size(); i++) {
|
||||
this.searchTree.get(i).drawRoom(scene, searchColor);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,100 @@
|
||||
import tester.Tester;
|
||||
import java.util.Random;
|
||||
|
||||
class Examples {
|
||||
Random r314 = new Random(314);
|
||||
Room v0, v1;
|
||||
Hall e01;
|
||||
Maze m3;
|
||||
MazeWorld worldM3;
|
||||
MazeWorld worldM16;
|
||||
|
||||
void testConstructors(Tester t) {
|
||||
// test Vertex Constructor
|
||||
v0 = new Room(0, 0);
|
||||
t.checkExpect(v0.neighborConnections.size(), 0);
|
||||
v1 = new Room(0, 1);
|
||||
// test edge constructor incl adding edges to vertices
|
||||
e01 = new Hall(v0, v1, r314.nextInt(10));
|
||||
t.checkExpect(v0.neighborConnections.size(), 1);
|
||||
t.checkExpect(v1.neighborConnections.size(), 1);
|
||||
t.checkExpect(v0.neighborConnections.get(0), e01);
|
||||
t.checkExpect(v1.neighborConnections.get(0), e01);
|
||||
// test Maze constructor
|
||||
m3 = new Maze(3, 3, 314);
|
||||
// check all vertices were created
|
||||
t.checkExpect(m3.rooms.size(), 9);
|
||||
// check rooms were placed in correct location
|
||||
t.checkExpect(m3.rooms.get(0).row, 0);
|
||||
t.checkExpect(m3.rooms.get(0).col, 0);
|
||||
t.checkExpect(m3.rooms.get(1).row, 0);
|
||||
t.checkExpect(m3.rooms.get(1).col, 1);
|
||||
t.checkExpect(m3.rooms.get(2).row, 0);
|
||||
t.checkExpect(m3.rooms.get(2).col, 2);
|
||||
t.checkExpect(m3.rooms.get(3).row, 1);
|
||||
t.checkExpect(m3.rooms.get(3).col, 0);
|
||||
t.checkExpect(m3.rooms.get(4).row, 1);
|
||||
t.checkExpect(m3.rooms.get(4).col, 1);
|
||||
t.checkExpect(m3.rooms.get(5).row, 1);
|
||||
t.checkExpect(m3.rooms.get(5).col, 2);
|
||||
t.checkExpect(m3.rooms.get(6).row, 2);
|
||||
t.checkExpect(m3.rooms.get(6).col, 0);
|
||||
t.checkExpect(m3.rooms.get(7).row, 2);
|
||||
t.checkExpect(m3.rooms.get(7).col, 1);
|
||||
t.checkExpect(m3.rooms.get(8).row, 2);
|
||||
t.checkExpect(m3.rooms.get(8).col, 2);
|
||||
// check correct number of edges were created
|
||||
t.checkExpect(m3.rooms.get(0).neighborConnections.size(), 2);
|
||||
t.checkExpect(m3.rooms.get(1).neighborConnections.size(), 3);
|
||||
t.checkExpect(m3.rooms.get(2).neighborConnections.size(), 2);
|
||||
t.checkExpect(m3.rooms.get(3).neighborConnections.size(), 3);
|
||||
t.checkExpect(m3.rooms.get(4).neighborConnections.size(), 4);
|
||||
t.checkExpect(m3.rooms.get(5).neighborConnections.size(), 3);
|
||||
t.checkExpect(m3.rooms.get(6).neighborConnections.size(), 2);
|
||||
t.checkExpect(m3.rooms.get(7).neighborConnections.size(), 3);
|
||||
t.checkExpect(m3.rooms.get(8).neighborConnections.size(), 2);
|
||||
// check that edges connect the correct vertices
|
||||
t.checkExpect(m3.rooms.get(0).neighborConnections.get(0).to,
|
||||
m3.rooms.get(1));
|
||||
t.checkExpect(m3.rooms.get(0).neighborConnections.get(1).to,
|
||||
m3.rooms.get(3));
|
||||
t.checkExpect(m3.rooms.get(4).neighborConnections.get(0).from,
|
||||
m3.rooms.get(3));
|
||||
t.checkExpect(m3.rooms.get(4).neighborConnections.get(1).from,
|
||||
m3.rooms.get(1));
|
||||
t.checkExpect(m3.rooms.get(4).neighborConnections.get(2).to,
|
||||
m3.rooms.get(5));
|
||||
t.checkExpect(m3.rooms.get(4).neighborConnections.get(3).to,
|
||||
m3.rooms.get(7));
|
||||
t.checkExpect(m3.rooms.get(8).neighborConnections.get(0).from,
|
||||
m3.rooms.get(7));
|
||||
t.checkExpect(m3.rooms.get(8).neighborConnections.get(1).from,
|
||||
m3.rooms.get(5));
|
||||
// check that route tree was created
|
||||
t.checkExpect(m3.routeTree.size(), 8);
|
||||
t.checkExpect(m3.rooms.get(0).openHalls.get(0).to,
|
||||
m3.rooms.get(1));
|
||||
t.checkExpect(m3.rooms.get(1).openHalls.get(0).from,
|
||||
m3.rooms.get(0));
|
||||
t.checkExpect(m3.rooms.get(1).openHalls.get(1).to,
|
||||
m3.rooms.get(4));
|
||||
t.checkExpect(m3.rooms.get(1).openHalls.get(2).to,
|
||||
m3.rooms.get(2));
|
||||
t.checkExpect(m3.rooms.get(4).openHalls.get(0).from,
|
||||
m3.rooms.get(3));
|
||||
t.checkExpect(m3.rooms.get(4).openHalls.get(1).from,
|
||||
m3.rooms.get(1));
|
||||
|
||||
}
|
||||
|
||||
void init() {
|
||||
m3 = new Maze(3, 3, 314);
|
||||
worldM3 = new MazeWorld(m3);
|
||||
worldM16 = new MazeWorld(new Maze(16, 16, 314));
|
||||
}
|
||||
void testDrawMaze(Tester t) {
|
||||
init();
|
||||
worldM3.start();
|
||||
// worldM16.start();
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,65 @@
|
||||
import java.awt.Color;
|
||||
import javalib.impworld.World;
|
||||
import javalib.impworld.WorldScene;
|
||||
|
||||
class MazeWorld extends World {
|
||||
// Constants
|
||||
double TICKRATE = 1.0 / 2;
|
||||
static int ROOM_SIZE_PX = 64;
|
||||
static int WALL_SIZE_PX = 1;
|
||||
static Color ROOM_COLOR = Color.GRAY;
|
||||
static Color WALL_COLOR = Color.BLACK;
|
||||
static Color SEARCH_COLOR = Color.blue;
|
||||
|
||||
//Variables
|
||||
Maze maze;
|
||||
int tickCount;
|
||||
|
||||
MazeWorld(Maze maze) {
|
||||
this.maze = maze;
|
||||
this.tickCount = -1;
|
||||
}
|
||||
MazeWorld(int size) {
|
||||
this(new Maze(size));
|
||||
}
|
||||
MazeWorld(int cols, int rows) {
|
||||
this(new Maze(cols, rows));
|
||||
}
|
||||
void reset() {
|
||||
// reset maze to new random start
|
||||
}
|
||||
|
||||
void start() {
|
||||
this.bigBang(
|
||||
(WALL_SIZE_PX + ROOM_SIZE_PX) * maze.width,
|
||||
(WALL_SIZE_PX + ROOM_SIZE_PX) * maze.height);
|
||||
}
|
||||
public WorldScene makeScene() {
|
||||
WorldScene scene = new WorldScene(
|
||||
(MazeWorld.ROOM_SIZE_PX + MazeWorld.WALL_SIZE_PX) * this.maze.width,
|
||||
(MazeWorld.ROOM_SIZE_PX + MazeWorld.WALL_SIZE_PX) * this.maze.height);
|
||||
this.maze.drawMaze(scene);
|
||||
if (this.tickCount >= 0) {
|
||||
this.maze.drawSearchTree(scene, this.tickCount);
|
||||
}
|
||||
return scene;
|
||||
}
|
||||
public void onKeyEvent(String k) {
|
||||
switch (k) {
|
||||
case "r":
|
||||
this.tickCount = -1;
|
||||
reset();
|
||||
case "b":
|
||||
this.tickCount = 0;
|
||||
this.maze.breadthFirstSearch();
|
||||
case "d":
|
||||
this.tickCount = 0;
|
||||
this.maze.depthFirstSearch();
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
public void onTick() {
|
||||
this.tickCount++;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,53 @@
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
|
||||
class Util {
|
||||
Util() {}
|
||||
|
||||
boolean isOneTree(ArrayList<Room> vertices, HashMap<String, String> setMap) {
|
||||
// this seems wildly inefficient but it works
|
||||
for (Room v0 : vertices) {
|
||||
for (Room v1 : vertices) {
|
||||
if (!this.sameTree(v0.name, v1.name, setMap)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
boolean sameTree(String k1, String k2, HashMap<String, String> setMap) {
|
||||
return this.getStump(k1, setMap).equals(this.getStump(k2, setMap));
|
||||
// if (setMap.get(k1).equals(setMap.get(k2))) {
|
||||
// // easy answer
|
||||
// return true;
|
||||
// } else if (setMap.get(k1).equals(k1) &&
|
||||
// setMap.get(k2).equals(k2)) {
|
||||
// // if both nodes are part of their own sets they cannot be part
|
||||
// // of the same set
|
||||
// return false;
|
||||
// } else {
|
||||
// // run up the tree to see if it ends in the same tree
|
||||
// // i can climb both sides here because when we get to a stump
|
||||
// // the self reference will by definition create a loop that will
|
||||
// // be broken by conditional above
|
||||
// return sameTree(setMap.get(k1), setMap.get(k2), setMap);
|
||||
// }
|
||||
}
|
||||
String getStump(String nodeName, HashMap<String, String> setMap) {
|
||||
String nodeSet = setMap.get(nodeName);
|
||||
if (nodeName.equals(nodeSet)) {
|
||||
return nodeSet;
|
||||
} else {
|
||||
return getStump(nodeSet, setMap);
|
||||
}
|
||||
}
|
||||
void union(HashMap<String, String> setMap, String k1, String k2) {
|
||||
if (setMap.get(k2).equals(k2)) {
|
||||
// if k2 is stump of tree change to k1
|
||||
setMap.put(k2, this.getStump(k1, setMap));
|
||||
} else {
|
||||
// go up the tree to change stump's set to k1
|
||||
this.union(setMap, k1, setMap.get(k2));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,60 @@
|
||||
;; The first three lines of this file were inserted by DrRacket. They record metadata
|
||||
;; about the language level of this file in a form that our tools can easily process.
|
||||
#reader(lib "htdp-advanced-reader.ss" "lang")((modname Objects) (read-case-sensitive #t) (teachpacks ()) (htdp-settings #(#t constructor repeating-decimal #t #t none #f () #f)))
|
||||
;; An Object is [Itself Name Params -> Value]
|
||||
;; A Name is a symbol
|
||||
;; Params is [Listof Value]
|
||||
;; Itself is the object on which the method is being invoked
|
||||
|
||||
(define object
|
||||
(λ(this prop args)
|
||||
(error prop "No such property found")))
|
||||
(define (make-pos x y)
|
||||
(local [(define super object)]
|
||||
(λ(this prop args)
|
||||
(cond
|
||||
[(symbol=? prop 'x) x]
|
||||
[(symbol=? prop 'y) y]
|
||||
[(symbol=? prop 'dist-to-0)
|
||||
(sqrt (+ (sqr x) (sqr y)))]
|
||||
[(symbol=? prop 'closer-than)
|
||||
(local [(define that (first args))]
|
||||
(< (dot this 'dist-to-0 '()) (dot that 'dist-to-0 '())))]
|
||||
;; NEW:
|
||||
[else (super this prop args)]))))
|
||||
(define (make-3d-pos x y z)
|
||||
(local [(define super (make-pos x y))]
|
||||
(λ(this prop args)
|
||||
(cond
|
||||
[(symbol=? prop 'z) z]
|
||||
[(symbol=? prop 'dist-to-0)
|
||||
(sqrt (+ (sqr x) (sqr y) (sqr z)))]
|
||||
;; NEW:
|
||||
[else (super this prop args)]))))
|
||||
(define (dot obj prop args)
|
||||
;; Passes the object to itself
|
||||
(obj obj prop args))
|
||||
|
||||
(define my-pos1 (make-pos 3 4))
|
||||
(define my-pos2 (make-pos 6 8))
|
||||
(define my-pos3 (make-3d-pos 3 4 12))
|
||||
|
||||
(check-expect (dot my-pos1 'x '-) 3)
|
||||
(check-expect (dot my-pos2 'y '-) 8)
|
||||
(check-error (dot my-pos2 'z '-) "z: No such property found")
|
||||
|
||||
(check-expect (dot my-pos3 'z '-) 12)
|
||||
(check-error (dot my-pos3 'w '-) "w: No such property found")
|
||||
|
||||
(check-expect (dot my-pos1 'dist-to-0 '-) 5)
|
||||
(check-expect (dot my-pos2 'dist-to-0 '-) 10)
|
||||
(check-expect (dot my-pos3 'dist-to-0 '-) 13)
|
||||
|
||||
;; Test 1: (3,4) is closer to the origin than (6,8)
|
||||
(check-expect (dot my-pos1 'closer-than (list my-pos2)) true)
|
||||
;; Test 2: (6,8) is not closer to the origin than (3,4)
|
||||
(check-expect (dot my-pos2 'closer-than (list my-pos1)) false)
|
||||
;; Test 3: (6,8) is closer to the origin than (3,4,12)
|
||||
(check-expect (dot my-pos2 'closer-than (list my-pos3)) true)
|
||||
;; Test 4: (3,4,12) is not closer to the origin than (6,8)
|
||||
(check-expect (dot my-pos3 'closer-than (list my-pos2)) false)
|
||||
@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<classpath>
|
||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-11">
|
||||
<attributes>
|
||||
<attribute name="module" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="src" path="src"/>
|
||||
<classpathentry kind="lib" path="/Users/nathanhoward/Documents/Code/OSSU-CS/completedwork/core_programming/02_classbased_design/Jars/tester.jar"/>
|
||||
<classpathentry kind="output" path="bin"/>
|
||||
</classpath>
|
||||
@ -0,0 +1,17 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>Lect34_DynamicProg</name>
|
||||
<comment></comment>
|
||||
<projects>
|
||||
</projects>
|
||||
<buildSpec>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.jdt.core.javabuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
||||
@ -0,0 +1,2 @@
|
||||
eclipse.preferences.version=1
|
||||
encoding/<project>=UTF-8
|
||||
@ -0,0 +1,11 @@
|
||||
eclipse.preferences.version=1
|
||||
org.eclipse.jdt.core.compiler.codegen.targetPlatform=11
|
||||
org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
|
||||
org.eclipse.jdt.core.compiler.compliance=11
|
||||
org.eclipse.jdt.core.compiler.debug.lineNumber=generate
|
||||
org.eclipse.jdt.core.compiler.debug.localVariable=generate
|
||||
org.eclipse.jdt.core.compiler.debug.sourceFile=generate
|
||||
org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled
|
||||
org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning
|
||||
org.eclipse.jdt.core.compiler.release=enabled
|
||||
org.eclipse.jdt.core.compiler.source=11
|
||||
@ -0,0 +1,78 @@
|
||||
import tester.Tester;
|
||||
import java.util.ArrayList;
|
||||
|
||||
class Fibonacci {
|
||||
int fib(int n, String type) {
|
||||
switch (type) {
|
||||
case "recursive":
|
||||
return fib_recursive(n);
|
||||
case "memo":
|
||||
return fib_memo(n);
|
||||
case "loop":
|
||||
return fib_loop(n);
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
int fib_recursive(int n) {
|
||||
if (n == 0) {
|
||||
return 1;
|
||||
} else if (n == 1) {
|
||||
return 1;
|
||||
} else {
|
||||
return fib_recursive(n - 1) + fib_recursive(n - 2);
|
||||
}
|
||||
}
|
||||
int fib_memo(int n) {
|
||||
ArrayList<Integer> answers = new ArrayList<Integer>();
|
||||
answers.add(1); // Base cases: fib(0) = 1
|
||||
answers.add(1); // fib(1) = 1
|
||||
fibAcc(n, answers);
|
||||
return answers.get(n);
|
||||
}
|
||||
int fibAcc(int n, ArrayList<Integer> answers) {
|
||||
// Check for redundant computation
|
||||
if (answers.size() > n) {
|
||||
return answers.get(n);
|
||||
}
|
||||
// Compute the new things:
|
||||
if (n == 0) {
|
||||
return 1;
|
||||
} else if (n == 1) {
|
||||
return 1;
|
||||
} else {
|
||||
int ans = fibAcc(n - 1, answers) + fibAcc(n - 2, answers);
|
||||
answers.add(ans);
|
||||
return ans;
|
||||
}
|
||||
}
|
||||
int fib_loop(int n) {
|
||||
if (n == 0) {
|
||||
return 1;
|
||||
} else if (n == 1) {
|
||||
return 1;
|
||||
} else {
|
||||
int prev = 1;
|
||||
int cur = 2;
|
||||
for (int i = 2; i < n; i += 1) {
|
||||
int next = prev + cur;
|
||||
prev = cur;
|
||||
cur = next;
|
||||
}
|
||||
return cur;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class FibExamples {
|
||||
Fibonacci f = new Fibonacci();
|
||||
void testFib(Tester t) {
|
||||
// 1 1 2 3 5 8 13 21 34
|
||||
t.checkExpect(f.fib(5, "recursive"), 8);
|
||||
t.checkExpect(f.fib(8, "recursive"), 34);
|
||||
t.checkExpect(f.fib(5, "memo"), 8);
|
||||
t.checkExpect(f.fib(8, "memo"), 34);
|
||||
t.checkExpect(f.fib(5, "loop"), 8);
|
||||
t.checkExpect(f.fib(8, "loop"), 34);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,91 @@
|
||||
//import tester.Tester;
|
||||
//import java.util.ArrayList;
|
||||
//import java.util.Arrays;
|
||||
//
|
||||
//class Shoppers {
|
||||
// int bestScoreRecursive(ArrayList<Integer> scores, ArrayList<Integer> costs,
|
||||
// int curItemIndex, int remainingBudget) {
|
||||
// // Base case: no more items
|
||||
// if (curItemIndex >= scores.size()) {
|
||||
// return 0;
|
||||
// } else {
|
||||
// // Recursive case: take the better of...
|
||||
// return Math.max(
|
||||
// // this item
|
||||
// scores.get(curItemIndex) +
|
||||
// // score of the best item(s) below with remaining budget
|
||||
// bestScoreRecursive(scores, costs,
|
||||
// curItemIndex + 1,
|
||||
// remainingBudget - costs.get(curItemIndex)),
|
||||
// // or best item(s) below
|
||||
// bestScoreRecursive(scores, costs, curItemIndex + 1, remainingBudget));
|
||||
// }
|
||||
// }
|
||||
// int bestScoreMemo(ArrayList<Integer> scores, ArrayList<Integer> costs, int budget) {
|
||||
// ArrayList<ArrayList<Integer>> memos = new ArrayList<ArrayList<Integer>>();
|
||||
// // It's a bit easier to pre-fill the array with placeholders,
|
||||
// // than to try to dynamicalaly fill it during the algorithm itself.
|
||||
// for (int idx = 0; idx < scores.size(); idx += 1) {
|
||||
// ArrayList<Integer> vals = new ArrayList<Integer>();
|
||||
// for (int b = 0; b < budget; b += 1) {
|
||||
// vals.add(Integer.MAX_VALUE); // Placeholder value to mark invalid answers
|
||||
// }
|
||||
// memos.add(vals);
|
||||
// }
|
||||
// bestScoreMemoHelp(memos, scores, costs, 0, budget);
|
||||
// return memos.get(0).get(budget);
|
||||
// }
|
||||
// int bestScoreMemoHelp(ArrayList<ArrayList<Integer>> memos,
|
||||
// ArrayList<Integer> scores, ArrayList<Integer> costs,
|
||||
// int curItemIndex, int remainingBudget) {
|
||||
// // Lookup memoized answer:
|
||||
// if (memos.get(curItemIndex).get(remainingBudget) != Integer.MAX_VALUE) {
|
||||
// return memos.get(curItemIndex).get(remainingBudget);
|
||||
// }
|
||||
// // Base case: no more items
|
||||
// if (curItemIndex >= scores.size()) {
|
||||
// return 0;
|
||||
// } else {
|
||||
// // Recursive case: take the better of...
|
||||
// int ans = Math.max(
|
||||
// // Try buying this item
|
||||
// scores.get(curItemIndex) + bestScoreRecursive(memos, scores, costs,
|
||||
// curItemIndex + 1,
|
||||
// remainingBudget - costs.get(curItemIndex)),
|
||||
// // Skip buying this item
|
||||
// bestScoreRecursive(memos, scores, costs, curItemIndex + 1, remainingBudget));
|
||||
// memos.get(curItemIndex).set(remainingBudget, ans);
|
||||
// return ans;
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
//
|
||||
//class Examples {
|
||||
// Shoppers s;
|
||||
// ArrayList<Integer> scores0;
|
||||
// ArrayList<Integer> costs0;
|
||||
//
|
||||
// void init() {
|
||||
// s = new Shoppers();
|
||||
// scores0 = new ArrayList<Integer>(Arrays.asList(
|
||||
// 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10));
|
||||
// costs0 = new ArrayList<Integer>(Arrays.asList(
|
||||
// 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0));
|
||||
// // 10 0 10 10
|
||||
// // 9 1 19 9
|
||||
// // 8 2 27 7
|
||||
// // 7 3 34 4
|
||||
// // 6 4 40 0
|
||||
// // 5 5
|
||||
// // 4 6
|
||||
// // 3 7
|
||||
// // 2 8
|
||||
// // 1 9
|
||||
// // 0 10
|
||||
// }
|
||||
// void testBestScore(Tester t) {
|
||||
// init();
|
||||
// t.checkExpect(s.bestScoreRecursive(scores0, costs0, 0, 10), 40);
|
||||
// t.checkExpect(s.bestScoreMemo(scores0, costs0, 10), 40);
|
||||
// }
|
||||
//}
|
||||
Loading…
Reference in New Issue
Block a user