-
Notifications
You must be signed in to change notification settings - Fork 36
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
8b9951f
commit adbcd8d
Showing
46 changed files
with
3,844 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
\documentclass{article} | ||
\usepackage[utf8]{inputenc} | ||
|
||
\title{\large{\textsc{In-Class Day 15: Graphs and DFS}}} | ||
\date{} | ||
|
||
\usepackage{natbib} | ||
\usepackage{graphicx} | ||
\usepackage{amsmath} | ||
\usepackage{amsfonts} | ||
\usepackage{mathtools} | ||
\usepackage{hyperref} | ||
\usepackage[a4paper, portrait, margin=0.8in]{geometry} | ||
|
||
\usepackage{listings} | ||
|
||
|
||
\newcommand\perm[2][n]{\prescript{#1\mkern-2.5mu}{}P_{#2}} | ||
\newcommand\comb[2][n]{\prescript{#1\mkern-0.5mu}{}C_{#2}} | ||
\newcommand*{\field}[1]{\mathbb{#1}} | ||
|
||
\DeclarePairedDelimiter\ceil{\lceil}{\rceil} | ||
\DeclarePairedDelimiter\floor{\lfloor}{\rfloor} | ||
|
||
\newcommand{\Mod}[1]{\ (\text{mod}\ #1)} | ||
|
||
\begin{document} | ||
|
||
\maketitle | ||
|
||
\subsection*{} | ||
|
||
|
||
\begin{enumerate} | ||
|
||
|
||
%%%%% PROBLEM 1 %%%%% | ||
\item Given a directed graph, determine whether or not the graph is also a binary tree.\\ | ||
Hint: | ||
This is a valid graph, but not a valid tree.\\ | ||
\includegraphics[width=\textwidth/5]{disjointGraph.png} | ||
\\ | ||
|
||
|
||
Assume the following Graph API: | ||
|
||
\begin{lstlisting}[language=Java] | ||
void addEdge(int v, int w); | ||
List<Integer> vertices(); | ||
int numVertices(); | ||
int numEdges(); | ||
Iterable<Integer> getNeighbors(int v); | ||
boolean hasEdgeBetween(int v, int w); | ||
\end{lstlisting} | ||
|
||
|
||
\item You would like to install a piece of software, but you must first install the dependencies of that software before that software can be installed. These dependencies might also have dependencies. For example, in order to install $A$, you might need to install $B$ and $C$ first, but $B$ and $C$ both also need to install $D$ first. Your input will be a list of pairs (in this example, the input would be \texttt{[(A, B), (A, C), (B, D), (C, D)]}). Write an algorithm that will determine in what order to install all the dependencies. In this case, we can install $DBCA$ or $DCBA$. If there are circular dependencies, return \texttt{null}. If $D$ depends on $A$, then this software cannot be installed. | ||
|
||
\item You are given a map in the form of a 2-D array. The map will tell whether there exists land (1) or water (0) at that certain spot. Pieces of land are connected if they are adjacent to each other either horizontally or vertically (but not diagonally). Determine how many disjoint islands there are. For example, | ||
\begin{lstlisting} | ||
011100011100000 | ||
011100010000000 | ||
000111110000010 | ||
011000001000000 | ||
010100001110000 | ||
011100001110000 | ||
\end{lstlisting} | ||
represents 4 islands. | ||
|
||
\item You are given a combination lock with N-dials, each with M numbers ranging from 1-M. For example, you could have a lock with 4-dials where each dial is a number from 1-7. In each timestep, you can rotate any dial in either direction. For example, a lock currently at 4251 could be set to 5251, 3251, 4351, 4151, 4241, 4261, 4257, or 4252. You are also given a list of blocking combinations. At no time should your combination ever read out any number from the the list of blocking combinations. Given a starting and ending combination and a set of blocking combinations, determine if there is a way to get from the starting combination to the ending combination. | ||
\end{enumerate} | ||
|
||
\end{document} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
import java.util.ArrayList; | ||
import java.util.HashMap; | ||
import java.util.List; | ||
import java.util.Map; | ||
|
||
public class CoinsOnAClock { | ||
|
||
private static void solve(char[] clock, int i, Map<Character, Integer> coinsToCounts, Map<Character, Integer> coinsToValues, | ||
List<char[]> solutions) { | ||
boolean finished = true; | ||
for (int v : coinsToCounts.values()) | ||
if (v != 0) | ||
finished = false; | ||
if (finished) { | ||
char[] copy = new char[clock.length]; | ||
System.arraycopy(clock, 0, copy, 0, clock.length); | ||
solutions.add(copy); | ||
return; | ||
} | ||
if (clock[i] != '.') | ||
return; | ||
for (Map.Entry<Character, Integer> e : coinsToCounts.entrySet()) { | ||
if (e.getValue() > 0) { | ||
int coinVal = coinsToValues.get(e.getKey()); | ||
clock[i] = e.getKey(); // Place the coin | ||
int index = (i + coinVal) % clock.length; // Calculate the next index | ||
e.setValue(e.getValue() - 1); // decrease the remaining number of coins | ||
solve(clock, index, coinsToCounts, coinsToValues, solutions); // recursively solve the problem | ||
clock[i] = '.'; // Backtrack | ||
e.setValue(e.getValue() + 1); | ||
} | ||
} | ||
} | ||
|
||
public static List<char[]> coinsOnAClock(int pennies, int nickels, int dimes, int hoursInDay) { | ||
Map<Character, Integer> coinsToCounts = new HashMap<>(); | ||
coinsToCounts.put('p', pennies); | ||
coinsToCounts.put('n', nickels); | ||
coinsToCounts.put('d', dimes); | ||
Map<Character, Integer> coinsToValues = new HashMap<>(); | ||
coinsToValues.put('p', 1); | ||
coinsToValues.put('n', 5); | ||
coinsToValues.put('d', 10); | ||
char[] clock = new char[hoursInDay]; | ||
for (int i = 0; i < clock.length; i++) | ||
clock[i] = '.'; | ||
List<char[]> result = new ArrayList<>(); | ||
solve(clock, 0, coinsToCounts, coinsToValues, result); | ||
return result; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,132 @@ | ||
import java.util.*; | ||
|
||
public class Cryptarithmetic { | ||
|
||
// Do not modify this function (though feel free to use it) | ||
public static boolean validSolution(String S1, String S2, String S3, Map<Character, Integer> assignments) { | ||
return (stringToInt(S1, assignments) + stringToInt(S2, assignments) == stringToInt(S3, assignments)) | ||
&& assignments.get(S1.charAt(0)) != 0 | ||
&& assignments.get(S2.charAt(0)) != 0 | ||
&& assignments.get(S3.charAt(0)) != 0; | ||
} | ||
|
||
private static boolean validSoFar(String S1, String S2, String S3, Map<Character, Integer> assignments) { | ||
int i = S1.length() - 1; | ||
int j = S2.length() - 1; | ||
int k = S3.length() - 1; | ||
int s; | ||
int carry = 0; | ||
while ((i >= 0 || j >= 0 || k >= 0)) { | ||
s = carry; | ||
if (i >= 0) { | ||
if (!assignments.containsKey(S1.charAt(i))) break; | ||
s += assignments.get(S1.charAt(i)); | ||
} | ||
if (j >= 0) { | ||
if (!assignments.containsKey(S2.charAt(j))) break; | ||
s += assignments.get(S2.charAt(j)); | ||
} | ||
if (k >= 0) { | ||
if (!assignments.containsKey(S3.charAt(k))) break; | ||
if (assignments.get(S3.charAt(k)) != (s % 10)) return false; | ||
} | ||
carry = s / 10; | ||
i--; j--; k--; | ||
} | ||
return true; | ||
} | ||
|
||
|
||
private static Iterable<Integer> randomOrder() { | ||
List<Integer> l = Arrays.asList(0, 1, 2, 3, 4, 5, 6, 7, 8, 9); | ||
Collections.shuffle(l); | ||
return l; | ||
} | ||
|
||
private static int stringToInt(String s, Map<Character, Integer> assignments) { | ||
int i = 0; | ||
for (int j = 0; j < s.length(); j++) { | ||
i *= 10; | ||
i += assignments.get(s.charAt(j)); | ||
} | ||
return i; | ||
} | ||
|
||
private static LinkedList<Character> assignmentOrder(String S1, String S2, String S3) { | ||
LinkedList<Character> l = new LinkedList<>(); | ||
Set<Character> set = new HashSet<>(); | ||
int i = S1.length() - 1; | ||
int j = S2.length() - 1; | ||
int k = S3.length() - 1; | ||
while (i >= 0 || j >= 0 || k >= 0) { | ||
if (i >= 0 && !set.contains(S1.charAt(i))) { | ||
set.add(S1.charAt(i)); | ||
l.add(S1.charAt(i)); | ||
} | ||
if (j >= 0 && !set.contains(S2.charAt(j))) { | ||
set.add(S2.charAt(j)); | ||
l.add(S2.charAt(j)); | ||
} | ||
if (k >= 0 && !set.contains(S3.charAt(k))) { | ||
set.add(S3.charAt(k)); | ||
l.add(S3.charAt(k)); | ||
} | ||
i--; j--; k--; | ||
} | ||
return l; | ||
} | ||
|
||
private static boolean solveFaster(String S1, String S2, String S3, | ||
LinkedList<Character> unassigned, Map<Character, Integer> assignments) { | ||
if (!validSoFar(S1, S2, S3, assignments)) return false; | ||
if (unassigned.isEmpty()) return validSolution(S1, S2, S3, assignments); | ||
char c = unassigned.removeFirst(); | ||
for (int i: randomOrder()) { // try to assign it from 0-9 in a random order | ||
// make the assignment | ||
assignments.put(c, i); | ||
// if this assignment results in the puzzle being solved, return true, and don't unassign the character | ||
if (solveFaster(S1, S2, S3, unassigned, assignments)) return true; | ||
// otherwise, unassign the character | ||
assignments.remove(c); | ||
} | ||
unassigned.addFirst(c); | ||
return false; // if there was no assignment which solved the puzzle | ||
} | ||
|
||
private static boolean solve(String S1, String S2, String S3, | ||
Set<Character> unassigned, Map<Character, Integer> assignments) { | ||
if (unassigned.isEmpty()) return validSolution(S1, S2, S3, assignments); | ||
char c = unassigned.iterator().next(); // get an char from the unassigned characters | ||
unassigned.remove(c); | ||
for (int i: randomOrder()) { // try to assign it from 0-9 in a random order | ||
// make the assignment | ||
assignments.put(c, i); | ||
// if this assignment results in the puzzle being solved, return true, and don't unassign the character | ||
if (solve(S1, S2, S3, unassigned, assignments)) return true; | ||
// otherwise, unassign the character | ||
assignments.remove(c); | ||
} | ||
unassigned.add(c); | ||
return false; // if there was no assignment which solved the puzzle | ||
} | ||
|
||
// this solution is fast, is makes assignments from right-to-left, and stops early, per the README | ||
public static Map<Character, Integer> solvePuzzle(String S1, String S2, String S3) { | ||
LinkedList<Character> unassigned = assignmentOrder(S1, S2, S3); | ||
Map<Character, Integer> assignments = new HashMap<>(); | ||
solveFaster(S1, S2, S3, unassigned, assignments); | ||
return assignments; | ||
} | ||
|
||
|
||
// this version is much slower, brute force tries every assignment | ||
// public static Map<Character, Integer> solvePuzzle(String S1, String S2, String S3) { | ||
// Set<Character> unassigned = new HashSet<>(); | ||
// for (char c: S1.toCharArray()) unassigned.add(c); | ||
// for (char c: S2.toCharArray()) unassigned.add(c); | ||
// for (char c: S3.toCharArray()) unassigned.add(c); | ||
// Map<Character, Integer> assignments = new HashMap<>(); | ||
// solve(S1, S2, S3, unassigned, assignments); | ||
// return assignments; | ||
// } | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
import java.util.ArrayList; | ||
import java.util.List; | ||
|
||
public class NQueens { | ||
|
||
|
||
/** | ||
* Checks the 45° and 135° diagonals for an existing queen. For example, if the board is a 5x5 | ||
* and you call checkDiagonal(board, 3, 1), The positions checked for an existing queen are | ||
* marked below with an `x`. The location (3, 1) is marked with an `o`. | ||
* | ||
* ....x | ||
* ...x. | ||
* x.x.. | ||
* .o... | ||
* ..... | ||
* | ||
* Returns true if a Queen is found. | ||
* | ||
* Do not modify this function (the tests use it) | ||
*/ | ||
public static boolean checkDiagonal(char[][] board, int r, int c) { | ||
int y = r - 1; | ||
int x = c - 1; | ||
while (y >= 0 && x >= 0) { | ||
if (board[y][x] == 'Q') return true; | ||
x--; | ||
y--; | ||
} | ||
y = r - 1; | ||
x = c + 1; | ||
while (y >= 0 && x < board[0].length) { | ||
if (board[y][x] == 'Q') return true; | ||
x++; | ||
y--; | ||
} | ||
return false; | ||
} | ||
|
||
|
||
/** | ||
* Creates a deep copy of the input array and returns it | ||
*/ | ||
private static char[][] copyOf(char[][] A) { | ||
char[][] B = new char[A.length][A[0].length]; | ||
for (int i = 0; i < A.length; i++) | ||
System.arraycopy(A[i], 0, B[i], 0, A[0].length); | ||
return B; | ||
} | ||
|
||
private static void solve(List<char[][]> answers, char[][] board, | ||
boolean[] usedColumns, int rowNumber) { | ||
if (rowNumber == board.length) { | ||
answers.add(copyOf(board)); | ||
return; | ||
} | ||
char[] row = board[rowNumber]; | ||
for (int i = 0; i < row.length; i++) { | ||
if (!usedColumns[i] && !checkDiagonal(board, rowNumber, i)) { | ||
usedColumns[i] = true; | ||
board[rowNumber][i] = 'Q'; | ||
solve(answers, board, usedColumns, rowNumber + 1); | ||
usedColumns[i] = false; | ||
board[rowNumber][i] = '.'; | ||
} | ||
} | ||
|
||
} | ||
|
||
public static List<char[][]> nQueensSolutions(int n) { | ||
char[][] board = new char[n][n]; | ||
for (int i = 0; i < board.length; i++) { | ||
for (int j = 0; j < board[0].length; j++) { | ||
board[i][j] = '.'; | ||
} | ||
} | ||
List<char[][]> answers = new ArrayList<>(); | ||
solve(answers, board, new boolean[n], 0); | ||
return answers; | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
import java.util.HashSet; | ||
import java.util.LinkedList; | ||
import java.util.List; | ||
import java.util.Set; | ||
|
||
public class Permutations { | ||
|
||
private static void backtrack(LinkedList<Integer> curr, Set<Integer> unused, List<List<Integer>> subsets) { | ||
if (unused.isEmpty()) | ||
subsets.add(new LinkedList<>(curr)); | ||
for (int u : new LinkedList<>(unused)) { | ||
curr.addLast(u); | ||
unused.remove(u); | ||
backtrack(curr, unused, subsets); | ||
unused.add(u); | ||
curr.removeLast(); | ||
} | ||
} | ||
|
||
public static List<List<Integer>> permutations(List<Integer> A) { | ||
List<List<Integer>> permutations = new LinkedList<>(); | ||
Set<Integer> unused = new HashSet<>(A); | ||
backtrack(new LinkedList<>(), unused, permutations); | ||
return permutations; | ||
} | ||
|
||
} |
Oops, something went wrong.