fundies2 complete

This commit is contained in:
Nathan Howard 2026-01-07 09:32:02 -08:00
parent c5430695c2
commit b93344da2f
17 changed files with 913 additions and 0 deletions

View File

@ -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>

View File

@ -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>

View File

@ -0,0 +1,2 @@
eclipse.preferences.version=1
encoding/<project>=UTF-8

View File

@ -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

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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);
}
}
}

View File

@ -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();
}
}

View File

@ -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++;
}
}

View File

@ -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));
}
}
}

View File

@ -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)

View File

@ -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>

View File

@ -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>

View File

@ -0,0 +1,2 @@
eclipse.preferences.version=1
encoding/<project>=UTF-8

View File

@ -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

View File

@ -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);
}
}

View File

@ -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);
// }
//}