Skip to content

Commit

Permalink
added solutions
Browse files Browse the repository at this point in the history
  • Loading branch information
CleanestMink126 committed Apr 27, 2019
1 parent 8b9951f commit adbcd8d
Show file tree
Hide file tree
Showing 46 changed files with 3,844 additions and 0 deletions.
73 changes: 73 additions & 0 deletions graphs/day00/pset.tex
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}
51 changes: 51 additions & 0 deletions graphs/day01/soln/CoinsOnAClock.java
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;
}
}
132 changes: 132 additions & 0 deletions graphs/day01/soln/Cryptarithmetic.java
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;
// }
}
82 changes: 82 additions & 0 deletions graphs/day01/soln/NQueens.java
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;
}

}
27 changes: 27 additions & 0 deletions graphs/day01/soln/Permutations.java
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;
}

}
Loading

0 comments on commit adbcd8d

Please sign in to comment.