upload to gh

This commit is contained in:
specCon18 2024-05-15 16:59:36 -04:00
parent d9d8d06b8a
commit f2407a9587
33 changed files with 941 additions and 83 deletions

27
src/day1/ArrayList.ts Normal file
View file

@ -0,0 +1,27 @@
export default class ArrayList<T> {
public length: number;
constructor() {
}
prepend(item: T): void {
}
insertAt(item: T, idx: number): void {
}
append(item: T): void {
}
remove(item: T): T | undefined {
}
get(idx: number): T | undefined {
}
removeAt(idx: number): T | undefined {
}
}

View file

@ -0,0 +1,39 @@
export default function bfs(
graph: WeightedAdjacencyMatrix,
source: number,
needle: number): number[] | null {
const seen = new Array(graph.length).fill(false);
const prev = new Array(graph.length).fill(-1);
seen[source] = true;
const q:number[] = [source];
do{
const curr = q.shift() as number;
if(curr === needle){
break;
}
const adjs = graph[curr];
for(let i = 0; i < adjs.length; ++i){
if(adjs[i] === 0){
continue;
}
if(seen[i]){
continue;
}
seen[i] = true;
prev[i] = curr;
q.push(i);
}
seen[curr] = true;
} while(q.length);
//build it backwards
if(prev[needle] === -1){
return null;
}
let curr = needle;
const out: number[] = [];
while(prev[curr] !== -1){
out.push(curr);
curr = prev[curr];
}
return [source].concat(out.reverse());
}

16
src/day1/BTBFS.ts Normal file
View file

@ -0,0 +1,16 @@
export default function bfs(head: BinaryNode<number>, needle: number): boolean {
const q: (BinaryNode<number>|null)[] = [head];
while(q.length){
const curr = q.shift() as BinaryNode<number> | undefined | null;
if(!curr){
continue;
}
if (curr.value === needle){
return true;
}
q.push(curr.left);
q.push(curr.right);
}
return false;
}

16
src/day1/BTInOrder.ts Normal file
View file

@ -0,0 +1,16 @@
function walk(curr:BinaryNode<number> | null, path:number[]): number[]{
//Base Case
if(!curr){
return path;
}
//Recurse
walk(curr.left, path);
path.push(curr.value);
walk(curr.right, path);
//Post
return path;
}
export default function in_order_search(head: BinaryNode<number>): number[] {
return walk(head,[]);
}

16
src/day1/BTPostOrder.ts Normal file
View file

@ -0,0 +1,16 @@
function walk(curr:BinaryNode<number> | null, path:number[]): number[]{
//Base Case
if(!curr){
return path;
}
//Recurse
walk(curr.left, path);
walk(curr.right, path);
//Post
path.push(curr.value);
return path;
}
export default function post_order_search(head: BinaryNode<number>): number[] {
return walk(head,[]);
}

18
src/day1/BTPreOrder.ts Normal file
View file

@ -0,0 +1,18 @@
function walk(curr:BinaryNode<number> | null, path:number[]): number[]{
//Base Case
if(!curr){
return path;
}
//Pre
path.push(curr.value);
//Recurse
walk(curr.left, path);
walk(curr.right, path);
//Post
return path;
}
export default function pre_order_search(head: BinaryNode<number>): number[] {
return walk(head,[]);
}

View file

@ -0,0 +1,17 @@
export default function bs_list(haystack: number[], needle: number): boolean {
let low = 0;
let high = haystack.length;
do{
const midpoint = Math.floor(low+(high-low)/2);
const value = haystack[midpoint];
if (value === needle) {
return true;
}else if(value > needle) {
high = midpoint;
}else {
low = midpoint + 1;
};
}while(low<high);
return false;
}

11
src/day1/BubbleSort.ts Normal file
View file

@ -0,0 +1,11 @@
export default function bubble_sort(arr: number[]): void {
for(let i = 0; i< arr.length; i++){
for(let j = 0; j< arr.length - 1 - i; j++){
if(arr[j]>arr[j+1]){
const tmp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = tmp;
}
}
}
}

View file

@ -0,0 +1,12 @@
export default function compare(a: BinaryNode<number> | null, b: BinaryNode<number> | null): boolean {
if(a === null && b === null){
return true;
}
if(a === null || b === null){
return false;
}
if(a.value != b.value){
return false;
}
return compare(a.left,b.left) && compare(a.right,b.right);
}

35
src/day1/DFSGraphList.ts Normal file
View file

@ -0,0 +1,35 @@
function walk(graph: WeightedAdjacencyList, curr:number,needle:number, seen: boolean[], path: number[]):boolean{
if(seen[curr]){
return false;
}
seen[curr] = true;
//recursion time
//pre
path.push(curr);
if(curr===needle){
return true;
}
//recurse
const list = graph[curr];
for(let i = 0; i < list.length; ++i){
const edge = list[i];
if(walk(graph, edge.to, needle, seen, path )){
return true;
}
}
//post
path.pop();
return false;
}
export default function dfs(
graph: WeightedAdjacencyList,
source: number,
needle: number): number[] | null {
const seen: boolean[] = new Array(graph.length).fill(false);
const path: number[] = [];
walk(graph,source, needle, seen, path);
if (path.length === 0){
return null;
}
return path;
}

15
src/day1/DFSOnBST.ts Normal file
View file

@ -0,0 +1,15 @@
function search(curr: BinaryNode<number>|null, needle:number):boolean {
if(!curr){
return false;
}
if(curr.value === needle){
return true;
}
if(curr.value < needle){
return search(curr.right,needle);
}
return search(curr.left,needle);
}
export default function dfs(head: BinaryNode<number>, needle: number): boolean {
return search(head, needle);
}

47
src/day1/DijkstraList.ts Normal file
View file

@ -0,0 +1,47 @@
function hasUnvisited(seen:boolean[],dists:number[]): boolean{
return seen.some((s,i) => !s && dists[i] < Infinity);
}
function getLowestUnvisited(seen:boolean[],dists:number[]): number{
let idx = -1;
let lowestDistance = Infinity;
for(let i = 0; i < seen.length; ++i){
if(seen[i]){
continue;
}
if (lowestDistance > dists[i]){
lowestDistance = dists[i]
idx = i;
}
}
return idx;
}
export default function dijkstra_list(source: number, sink:number, arr:WeightedAdjacencyList):number[]{
const seen = new Array(arr.length).fill(false);
const prev = new Array(arr.length).fill(-1);
const dists = new Array(arr.length).fill(Infinity);
dists[source] = 0;
while(hasUnvisited(seen,dists)){
const curr = getLowestUnvisited(seen,dists);
seen[curr] = true;
const adjs = arr[curr];
for(let i = 0; i < adjs.length; ++i){
const edge = adjs[i];
if(seen[edge.to]){
continue;
}
const dist = dists[curr] + edge.weight;
if (dist < dists[edge.to]){
dists[edge.to] = dist;
prev[edge.to] = curr;
}
}
}
const out: number[] = [];
let curr = sink;
while(prev[curr] !== -1){
out.push(curr);
curr = prev[curr];
}
out.push(source);
return out.reverse();
}

View file

@ -0,0 +1,116 @@
type Node<T> = {
value:T,
prev?: Node<T>,
next?: Node<T>
}
export default class DoublyLinkedList<T> {
public length: number;
private head?: Node<T>;
private tail?: Node<T>;
constructor() {
this.length = 0;
this.head = undefined;
this.tail = undefined;
}
prepend(item: T): void {
const node = {value:item} as Node<T>;
this.length++;
if(!this.head){
this.head = this.tail = node;
return;
}
node.next = this.head;
this.head.prev = node;
this.head = node;
}
insertAt(item: T, idx: number): void {
if(idx > this.length){
throw new Error("Oh No Cannot insert outside of list");
}
if(idx === this.length){
this.append(item);
return;
}else if(idx === 0){
this.prepend(item);
return;
}
this.length++;
const curr = this.getAt(idx) as Node<T>;
const node = {value:item} as Node<T>;
node.next = curr;
node.prev = curr.prev;
curr.next = node;
if(node.prev){
node.prev.next = node;
}
}
append(item: T): void {
this.length++;
const node = {value:item} as Node<T>;
if(!this.tail){
this.head = this.tail = node;
return;
}
node.prev = this.tail;
this.tail.next = node;
this.tail = node;
}
// Could be improved by hash map to node values so that lookup is instant;
remove(item: T): T | undefined {
let curr = this.head;
for(let i = 0; curr && i < this.length; ++i){
//weve found the item
if(curr.value === item){
break;
}
curr = curr.next;
}
//if no curr then theres no item to remove
if(!curr){
return undefined;
}
return this.removeNode(curr);
}
get(idx: number): T | undefined {
return this.getAt(idx)?.value;
}
private getAt(idx:number): Node<T> | undefined {
let curr = this.head;
for(let i = 0; curr && i < idx; ++i){
curr = curr.next;
}
return curr;
};
private removeNode(node:Node<T>):T | undefined{
this.length--;
if(this.length === 0){
const out = this.head?.value;
this.head = this.tail = undefined;
return out;
}
if(node.prev){
node.prev.next = node.next;
}
if(node.next){
node.next.prev = node.prev;
}
if(node === this.head){
this.head = node.next;
}
if(node === this.tail){
this.tail = node.prev;
}
node.prev = node.next = undefined;
return node.value;
}
removeAt(idx: number): T | undefined {
const node = this.getAt(idx);
if(!node){
return undefined;
}
return this.removeNode(node);
}
}

91
src/day1/LRU.ts Normal file
View file

@ -0,0 +1,91 @@
type Node<T> = {
value:T
next?:Node<T>
prev?:Node<T>
}
function createNode<V>(value:V): Node<V>{
return {value};
}
export default class LRU<K, V> {
private length: number;
private head?: Node<V>;
private tail?: Node<V>;
private lookup: Map<K,Node<V>>;
private reverseLookup: Map<Node<V>,K>;
constructor(private capacity:number = 10) {
this.length = 0;
this.head = this.tail = undefined;
this.lookup = new Map<K, Node<V>>();
this.reverseLookup = new Map<Node<V>,K>();
}
update(key: K, value: V): void {
// Does the cache exist
let node = this.lookup.get(key);
if(!node){
node = createNode(value);
this.length++;
this.prepend(node);
this.trimCache();
this.lookup.set(key,node);
this.reverseLookup.set(node,key);
} else {
this.detach(node);
this.prepend(node);
node.value = value;
}
// if it doesn't we need to insert
// check capcacity and evict least used if over capacity
// if it does we need to update to the front of the list and update the value
}
get(key: K): V | undefined {
// Check that the cache exists
const node = this.lookup.get(key);
if(!node){
return undefined;
}
// Update the value we found and move it to the front
this.detach(node);
this.prepend(node);
// Return the value found or undefined if it doesnt exist
return node.value;
}
private detach(node: Node<V>){
if(node.prev){
node.prev.next = node.next;
}
if(node.next){
node.next.prev = node.prev;
}
//So we dont cut off our own head
if(this.head === node){
this.head = this.head.next;
}
if(this.tail === node){
this.tail = this.tail.prev;
}
node.next = undefined;
node.prev = undefined;
}
private prepend(node:Node<V>){
if(!this.head){
this.head = this.tail = node;
return;
}
node.next = this.head;
this.head.prev = node;
this.head = node;
}
private trimCache():void {
if(this.length <= this.capacity){
return;
}
const tail = this.tail as Node<V>;
this.detach(this.tail as Node<V>);
const key = this.reverseLookup.get(tail) as K;
this.lookup.delete(key);
this.reverseLookup.delete(tail);
this.length--;
}
}

View file

@ -0,0 +1,8 @@
export default function linear_search(haystack: number[], needle: number): boolean {
for (let i:number = 0; i < haystack.length; ++i){
if (haystack[i] === needle){
return true;
}
}
return false;
}

21
src/day1/Map.ts Normal file
View file

@ -0,0 +1,21 @@
export default class Map<T extends (string | number), V> {
constructor() {
}
get(key: T): V | undefined {
}
set(key: T, value: V): void {
}
delete(key: T): V | undefined {
}
size(): number {
}
}

51
src/day1/MazeSolver.ts Normal file
View file

@ -0,0 +1,51 @@
const dir = [
[-1,0],//left
[1,0],//right
[0,-1],//down
[0,1],//up
];
function walk(maze:string[], wall: string, curr: Point, end:Point, seen:boolean[][],path:Point[]):boolean{
//base case off map
if(curr.x < 0 || curr.x > maze[0].length || curr.y < 0 || curr.y >= maze.length){
return false;
};
if(maze[curr.y][curr.x] === wall){
return false;
};
if (curr.x === end.x && curr.y === end.y){
path.push(end)
return true;
};
if (seen[curr.y][curr.x]){
return false
}
//pre
seen[curr.y][curr.x] = true;
path.push(curr)
//recurse
for(let i = 0; i< dir.length; i++){
const [x,y] = dir[i]
if (walk(maze,wall,{
x: curr.x+x,
y: curr.y+y,
},end,seen,path)){
return true;
};
}
//post
path.pop()
return false;
};
export default function solve(maze: string[], wall: string, start: Point, end: Point): Point[] {
const seen:boolean[][] = [];
const path:Point[] = [];
for (let i = 0; i < maze.length; ++i){
seen.push(new Array(maze[0].length).fill(false));
}
walk(maze,wall,start,end,seen,path);
return path;
}

74
src/day1/MinHeap.ts Normal file
View file

@ -0,0 +1,74 @@
export default class MinHeap {
public length: number;
private data: number[];
constructor() {
this.data = [];
this.length = 0;
}
insert(value: number): void {
this.data[this.length] = value;
this.heapifyUp(this.length);
this.length++;
}
delete(): number {
if(this.length === 0){
return -1;
}
const out = this.data[0];
this.length--;
if(this.length === 0){
this.data = [];
return out;
}
this.data[0] = this.data[this.length];
this.heapifyDown(0);
return out;
}
private heapifyDown(idx:number):void{
const lIdx = this.leftChild(idx);
const rIdx = this.rightChild(idx);
if(idx >= this.length || lIdx >= this.length){
return;
}
const lV = this.data[lIdx];
const rV = this.data[rIdx];
const v = this.data[idx];
if(lV > rV && v > rV){
this.data[idx] = rV;
this.data[rIdx] = v;
this.heapifyDown(rIdx);
} else if(rV > lV && v > lV){
this.data[idx] = lV;
this.data[lIdx] = v;
this.heapifyDown(lIdx);
}
const minValue = this
}
private heapifyUp(idx:number):void{
if(idx === 0){
return;
}
const p = this.parent(idx);
const parenV = this.data[p];
const v = this.data[idx];
if(parenV > v){
this.data[idx] = parenV;
this.data[p] = v;
this.heapifyUp(p);
}
}
private parent(idx:number):number{
return Math.floor((idx - 1)/2);
}
private leftChild(idx:number):number{
return 2*idx+1;
}
private rightChild(idx:number):number{
return 2*idx+2;
}
}

46
src/day1/Queue.ts Normal file
View file

@ -0,0 +1,46 @@
type Node<T> = {
value: T,
next?: Node<T>,
};
export default class Queue<T> {
public length: number;
private head?: Node<T>;
private tail?: Node<T>;
constructor() {
this.head = this.tail = undefined;
this.length = 0;
}
enqueue(item: T): void {
const node = {value: item} as Node<T>;
this.length++;
if(!this.tail) {
this.tail = this.head = node;
return;
};
this.tail.next = node;
this.tail = node;
}
deque(): T | undefined {
if(!this.head) {
return undefined;
}
this.length--;
const head = this.head;
this.head = this.head.next;
//free memory
head.next = undefined;
if (this.length === 0){
this.tail = undefined;
}
return head.value;
}
peek(): T | undefined {
return this.head?.value;
}
}

27
src/day1/QuickSort.ts Normal file
View file

@ -0,0 +1,27 @@
function partition(arr:number[],lo:number,high:number):number{
const pivot = arr[high];
let idx = lo-1;
for(let i = lo; i<high; ++i){
if(arr[i] <= pivot){
idx++;
const tmp = arr[i];
arr[i] = arr[idx];
arr[idx] = tmp;
};
};
idx++;
arr[high] = arr[idx];
arr[idx] = pivot;
return idx;
}
function qs(arr:number[], lo:number, high:number): void {
if(lo >= high){
return;
}
const pivotIdx = partition(arr,lo,high);
qs(arr, lo, pivotIdx - 1);
qs(arr, pivotIdx + 1, high);
}
export default function quick_sort(arr: number[]): void {
qs(arr, 0, arr.length - 1);
}

View file

@ -0,0 +1,27 @@
export default class SinglyLinkedList<T> {
public length: number;
constructor() {
}
prepend(item: T): void {
}
insertAt(item: T, idx: number): void {
}
append(item: T): void {
}
remove(item: T): T | undefined {
}
get(idx: number): T | undefined {
}
removeAt(idx: number): T | undefined {
}
}

41
src/day1/Stack.ts Normal file
View file

@ -0,0 +1,41 @@
type Node<T> = {
value: T,
prev?: Node<T>
}
export default class Stack<T> {
public length: number;
private head?: Node<T>;
constructor() {
this.head = undefined;
this.length = 0;
}
push(item: T): void {
const node = {value:item} as Node<T>
this.length++;
if (!this.head){
this.head = node;
return;
}
node.prev = this.head;
this.head = node;
}
pop(): T | undefined {
this.length = Math.max(0,this.length - 1);
if (this.length === 0){
const head = this.head;
this.head = undefined;
return head?.value;
}
const head = this.head as Node<T>;
this.head = head.prev;
return head.value;
}
peek(): T | undefined {
return this.head?.value;
}
}

18
src/day1/Trie.ts Normal file
View file

@ -0,0 +1,18 @@
export default class Trie {
constructor() {
}
insert(item: string): void {
}
delete(item: string): void {
}
find(partial: string): string[] {
}
}

View file

@ -0,0 +1,16 @@
export default function two_crystal_balls(breaks: boolean[]): number {
const jump_amount = Math.floor(Math.sqrt(breaks.length));
let i = jump_amount;
for (; i<breaks.length; i+=jump_amount){
if(breaks[i]) {
break;
}
}
i -= jump_amount;
for (let j = 0; j<=jump_amount && i < breaks.length; ++j,++i) {
if(breaks[i]){
return i;
}
}
return - 1;
}