Commit cc367136 authored by Torstein's avatar Torstein

Til forelesning

parent 251947dd
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" path="src"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>
<classpathentry kind="con" path="org.eclipse.jdt.junit.JUNIT_CONTAINER/4"/>
<classpathentry kind="output" path="bin"/>
</classpath>
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>inf101v16f12</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>
eclipse.preferences.version=1
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
org.eclipse.jdt.core.compiler.compliance=1.8
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.assertIdentifier=error
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
org.eclipse.jdt.core.compiler.source=1.8
package inf101v16f12.generators;
import inf101v16f12.util.IGenerator;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
public abstract class AbstractGenerator<T> implements IGenerator<T> {
private static final Random commonRandom = new Random();
@Override
public T generate() {
return generate(commonRandom);
}
@Override
public List<T> generateEquals(int n) {
return generateEquals(commonRandom, n);
}
@Override
public List<T> generateEquals(Random r, int n) {
long seed = r.nextLong();
List<T> list = new ArrayList<T>();
for (int i = 0; i < n; i++) {
list.add(generate(new Random(seed)));
}
return list;
}
}
package inf101v16f12.generators;
import java.util.Random;
import inf101v16f12.generators.AbstractGenerator;
import inf101v16f12.graph.Tree;
import inf101v16f12.graph.TreeNode;
public class TreeGenerator extends AbstractGenerator<Tree> {
public static final int MAXDEPTH = 10;
public static final int MAXBRANCH = 5;
@Override
public Tree generate(Random r) {
Tree t = new Tree();
int cdepth = 1 + r.nextInt(MAXDEPTH);
generateRec(cdepth, t.getRoot(), r);
return t;
}
private void generateRec(int depth, TreeNode root, Random r) {
if (depth <= 0)
return;
int childCount = 1 + r.nextInt(MAXBRANCH);
for (int i=0; i<childCount; i++) {
int cdepth = r.nextInt(depth);
TreeNode child = root.newChild();
generateRec(cdepth, child, r);
}
}
/**
* Will return a binary tree of given depth
*
* @param depth
* @return
*/
public Tree binary(int depth) {
Tree t = new Tree();
binaryRec(depth, t.getRoot());
return t;
}
private void binaryRec(int depth, TreeNode root) {
if (depth <= 0)
return;
for (int i=0; i<2; i++)
root.newChild();
for (TreeNode child : root.getChildren())
binaryRec(depth-1, child);
}
/**
* An example tree that looks like this:
*
* r
* / \
* a b
* | / | \
* aa ba bb bc
* |
* baa
*
*
* This tree has depth 4 (baa), maximum degree 4 (b),
* and has leaves {aa, baa, bb, bc}
*
* @return the example tree
*/
@SuppressWarnings("unused")
public Tree example() {
Tree t = new Tree();
TreeNode root = t.getRoot();
TreeNode a = root.newChild("a");
TreeNode b = root.newChild("b");
TreeNode aa = a.newChild("aa");
TreeNode ba = b.newChild("ba");
TreeNode bb = b.newChild("bb");
TreeNode bc = b.newChild("bc");
TreeNode baa = ba.newChild("baa");
return t;
}
}
package inf101v16f12.graph;
import java.util.ArrayList;
import java.util.List;
public class Tree {
private TreeNode root = new TreeNode(null, "r");
/**
* @return the root
*/
public TreeNode getRoot() {
return root;
}
/* (non-Javadoc)
* @see java.lang.Object#toString()
*/
@Override
public String toString() {
String s = "Tree [\n";
s = toStringRec(s, 1, this.root) + "]";
return s;
}
private static String toStringRec(String s, int indent, TreeNode root) {
s = s + new String(new char[indent*2]).replace("\0", " ");
s = s + root.getName() + "\n";
for (TreeNode child : root.getChildren())
s = toStringRec(s, indent+1, child);
return s;
}
/**
*
* @return the depth of the tree
*/
public int getDepth() {
return depthRec(this.root);
}
private static int depthRec(TreeNode root) {
int max = -1;
for (TreeNode child : root.getChildren()) {
max = Math.max(max, depthRec(child));
}
return 1 + max;
}
/**
*
* @return the leaves of the tree
*/
public List<TreeNode> getLeaves() {
List<TreeNode> leaves = new ArrayList<TreeNode> ();
getLeavesRec(leaves, this.root);
return leaves;
}
private static void getLeavesRec(List<TreeNode> leaves, TreeNode root) {
if (root.getChildren().isEmpty())
leaves.add(root);
else {
for (TreeNode child : root.getChildren())
getLeavesRec(leaves, child);
}
}
/**
*
* @return the maximum degree of any node in the tree
*/
public int maxDeg() {
return maxDegRec(this.root);
}
private static int maxDegRec(TreeNode root) {
int deg = root.getChildren().size();
for (TreeNode child : root.getChildren())
deg = Math.max(deg, 1+maxDegRec(child));
return deg;
}
/**
* Will return a node with the matching name, if found.
* If there is more than one node with the given name,
* an arbitrary (__not__ random) match will be returned.
*
* @param name of a node in the tree
* @return a node matching the name given
*/
public TreeNode findNode(String name) {
return findNode(name, this.root);
}
private TreeNode findNode(String name, TreeNode root) {
if (root.getName().equals(name))
return root;
for (TreeNode child : root.getChildren()) {
TreeNode hit = findNode(name, child);
if (hit != null)
return hit;
}
return null;
}
}
package inf101v16f12.graph;
import java.util.ArrayList;
import java.util.List;
public class TreeNode {
private static int nextName = 0;
private final int id = nextName++;
private final String name;
private final TreeNode parent;
private final List<TreeNode> children = new ArrayList<TreeNode>();
public TreeNode(TreeNode parent) {
this.parent = parent;
this.name = String.valueOf(this.id);
}
public TreeNode(TreeNode parent, String name) {
this.parent = parent;
this.name = name;
}
public TreeNode newChild() {
TreeNode child = new TreeNode(this);
this.children.add(child);
return child;
}
public TreeNode newChild(String name) {
TreeNode child = new TreeNode(this, name);
this.children.add(child);
return child;
}
/*
* (non-Javadoc)
*
* @see java.lang.Object#toString()
*/
@Override
public String toString() {
String children = "";
for (TreeNode child : this.children) {
children += child.name + ",";
}
return "TreeNode [name=" + name + ", parent=" + parent.name + ", children=" + children + "]";
}
/**
* @return the name
*/
public String getName() {
return this.name;
}
/**
* @return the name
*/
public int getId() {
return this.id;
}
/**
* @return the parent
*/
public TreeNode getParent() {
return this.parent;
}
/**
* @return the children
*/
public List<TreeNode> getChildren() {
return children;
}
}
package inf101v16f12.recursion;
public class Basic {
/**
* Test if the string is a palindrome. A palindrome is a sting which is the
* same both forwards and backwards
*
* @param s the string
* @return true if s is a palindrome, false otherwise
*/
public static boolean isPalindrome(String s) {
// Base case
if (s.length() <= 1)
return true;
// Recursive case
char first = s.charAt(0);
char last = s.charAt(s.length()-1);
return (first == last && isPalindrome(s.substring(1, s.length()-1)));
}
/**
* Reverses the string
*
* @param s the string
* @return the reverse string of s
*/
public static String reverse(String s) {
// Base case
if (s.length() <= 1)
return s;
// Recursive case
return reverse(s.substring(1)) + s.charAt(0);
}
/**
* Returns the sum of the digits (decimal notation)
*
* @param num the number
* @return sum of digits of num
*/
public static int sumOfDigits(int num) {
// Base case
if (num == 0)
return 0;
// Recursive cases
else if (num < 0)
return sumOfDigits(Math.abs(num));
else
return num%10 + sumOfDigits(num/10);
}
}
package inf101v16f12.recursion;
import java.io.File;
public class FileSystem {
public static void main(String[] args) {
File f = new File("/Users/torsteins/Dropbox/INF237-2015/problems/set7 - bruteforce");
listAll(f);
}
public static void listAll(File path) {
// Always: print Path
System.out.println(path.getAbsoluteFile());
// Base case: path is a file, so do not recurse
if (!path.isDirectory()) {
return;
}
// Recursive case
else {
for (File child : path.listFiles())
listAll(child);
}
}
public static void biggestFile(String path) {
//TODO
}
}
package inf101v16f12.recursion;
import java.util.ArrayList;
import java.util.List;
public class GameSolvers {
/**
* Tower of Hanoi
*
* The Tower of Hanoi is a mathematical game or puzzle. It consists of three
* rods, and a number of disks of different sizes which can slide onto any
* rod. The puzzle starts with the disks in a neat stack in ascending order
* of size on one rod, the smallest at the top, thus making a conical shape.
*
* The objective of the puzzle is to move the entire stack to another rod,
* obeying the following simple rules:
*
* - Only one disk can be moved at a time. - Each move consists of taking
* the upper disk from one of the stacks and placing it on top of another
* stack i.e. a disk can only be moved if it is the uppermost disk on a
* stack. - No disk may be placed on top of a smaller disk.
*
* (From Wikipedia, https://en.wikipedia.org/wiki/Tower_of_Hanoi)
*
*
* @param n
* the number of disks
* @return the number of steps to move the tower to another pin
*/
public static int towerOfHanoi(int n) {
System.out.println(
"Moving a Tower of Hanoi of height " + n + " from a to c");
return move(n, "a", "b", "c");
}
public static int move(int n, String from, String via, String to) {
if (n == 1) {
System.out.println("" + n + ": " + from + " -> " + to);
return 1;
}
int moves = 0;
moves += move(n - 1, from, to, via); // Move top of stack away
moves += 1; // Move the biggest piece to "to"
System.out.println("" + n + ": " + from + " -> " + to);
moves += move(n - 1, via, from, to); // Move top stack back again
return moves;
}
/**
* Yields a solution to the nQueens problem of placing n queens of an n by n
* chess board such that none of the queens can strike each other. A queen
* can strike another queen if they share the same row, column or diagonal
* on the board.
*
* The solution will be represented as a string of space-separated integers,
* where the first integer indicates the row of the queen placed in the
* first column, the second integer indicates the row of the queen placed in
* the second column etc.
*
* If no solution can be found, the function returns null.
*
* @param n
* the number of queens to be placed, the dimension of the board
* @return a list representing placements of queens
*/
public static List<Integer> nQueens(int n) {
List<Integer> placed = new ArrayList<Integer>();
return nQueens(n, placed);
}
private static List<Integer> nQueens(int n, List<Integer> placed) {
// Base cases
if (causeConflict(placed))
return null;
if (n == placed.size())
return placed;
// Recursive search
for (int row = 0; row < n; row++) {
placed.add(row);
List<Integer> res = nQueens(n, placed);
if (res != null)
return res;
placed.remove(placed.size() - 1);
}
return null;
}
private static boolean causeConflict(List<Integer> queens) {
if (queens.isEmpty())
return false;
int col = queens.size() - 1;
int row = queens.get(col);
for (int col2 = 0; col2 < col; col2++) {
int row2 = queens.get(col2);
if (row2 == row)
return true;
int drow = Math.abs(row - row2);
int dcol = col - col2;
if (drow == dcol)
return true;
}
return false;
}
// N-queens
// Subset sum
// Knapsack
// Edit distance
}
package inf101v16f12.recursion;
public class GraphFunctions {
// Vertex Cover in trees
}
package inf101v16f12.recursion;
public class MathFunctions {
/**
* Fibonacci
*
* The Fibonacci numbers are the numbers of the sequence defined by
* fib(0)=0, fib(1)=1 and fib(n)=fib(n-1)+fib(n-2) for n >= 2. The first few
* Fibonacci numbers are:
*
* 0, 1, 1, 2, 3, 5, 8, 13, ...
*
* This function will return
*
* @param n
* non-negative integer
* @return the n'th Fibonacci number
*/
public static int fib(int n) {
if (n == 0)
return 0;
if (n == 1)
return 1;
return fib(n - 1) + fib(n - 2);
}
/**
* Factorial
*
* The factorial number n! is defined as 1*2*3...*n for n >= 1. By
* definition, 0! = 1.
*
* @param n
* non-negative integer
* @return The factorial of n, n! = 1*2*3...*n
*/
public static int factorial(int n) {
return (n == 0) ? 1 : n * factorial(n - 1);
}
/**
* Power
*
* @param b
* base
* @param e
* exponent, non-negative integer
* @return n^k
*/
public static int power(int b, int e) {
return (e == 0) ? 1 : b * power(b, e - 1);
}
/**
* N choose R.
*
* The function nCr(n, r) returns how many possible combinations of r
* elements can be made out of a collection of size n. For example, given
* three (n=3) fruits, say an apple, an orange and a pear, there are three
* combinations of two (r=2) that can be drawn from this set: an apple and a
* pear; an apple and an orange; or a pear and an orange. Thus, nCr(3,
* 2)==3.
*
* Try writing the function __without__ calculating the factorial.
*
* Hint 1: By the definition, what happens when r>n? r==n? r==0?
*
* Hint 2: Suppose there are n different types of fruit, and that apples are
* one of them. Some of the possible combinations of fruit that can be made
* include apples, say x. Some combinations of fruit does __not__ contain
* apples, say y. Notice that then the total number of combinations is x+y.
* Can we calculate x and y recursively?
*
* Hint 3: If you are still stuck, look up the recurrence relation here:
* https://en.wikipedia.org/wiki/Binomial_coefficient#Recursive_formula
*
* @param n
* the size of the collection
* @param r
* the size of the combination
* @return the number of ways to pick r items from a collection of n items.
*/
public static int nCr(int n, int r) {
// TODO
return 0;
}
/**
* Bell numbers (very hard)
*
* In combinatorial mathematics, the Bell numbers count the number of
* partitions of a set. A partition of a set S is defined as a collection of
* nonempty, pairwise disjoint subsets of S whose union is S. For example,
* bell(3) = 5 because the 3-element set {a, b, c} can be partitioned in 5
* distinct ways:
*
* <ul>
* <li>{a}, {b}, {c}
* <li>{a}, {b, c}
* <li>{b}, {a, c}
* <li>{c}, {a, b}
* <li>{a, b, c}
* </ul>
*
* Starting with B0 = B1 = 1, the first few Bell numbers are: 1, 1, 2, 5,
* 15, 52, 203, 877, 4140, ...
*
* Hint 1: By the definition, notice the values of bell(0) and bell(1).
*
* Hint 2: Imagine that you are growing your set S by adding one element
* every time, and that you know the bell numbers for all the sets you have
* seen so far. The last element you added can be in a set of any size
* between 1 and n in a partition of S. If the size of the set containing
* the last element is k, can we then count how many partitions there are of
* this type?
*
* Hint 3: If you are stuck, look up the recurrence relation here:
* https://en.wikipedia.org/wiki/Bell_number#Summation_formulas
*
* @param n
* the size of a set S
* @return how many ways one can partition S
*/
public static int bell(int n) {
// TODO
return 0;
}
/**
* Greatest common denominator between two positive integers
*
* Using Euclid's algorithm to find the greatest common denominator between
* two numbers
*
* https://en.wikipedia.org/wiki/Euclidean_algorithm
*
* @param x
* positive integer
* @param y
* positive integer
* @return the greatest common divisor of x and y
*/
public static int gcd(int x, int y) {
if (y == 0)
return x;
return gcd(y, x % y);
}
}