diff --git a/graph.cr b/graph.cr deleted file mode 100644 index 9eae6e6..0000000 --- a/graph.cr +++ /dev/null @@ -1,48 +0,0 @@ -class Graph(A) - def initialize - @edges = {} of A => Set({A, Int32}) - end - - def add_edge(f, t, c = 1) - @edges[f] ||= Set({A, Int32}).new - @edges[f] << {t, c} - end - - def add_biedge(f, t, c = 1) - add_edge(f, t, c) - add_edge(t, f, c) - end - - def find_path(f, t) - visited = Set(A).new - candidates = Set { f } - distances = {f => 0} - prev = {} of A => A - - while !candidates.empty? - candidate = candidates.min_by { |c| distances[c] } - break if candidate == t - visited << candidate - candidates.delete candidate - dist = distances[candidate] - - @edges.fetch(candidate, Set({A, Int32}).new).each do |e| - node, cost = e - new_dist = dist + cost - candidates << node unless visited.includes? node - next if (old_dist = distances[node]?) && old_dist < new_dist - distances[node] = new_dist - prev[node] = candidate - end - end - - backtrack = t - path = [t] of A - while backtrack != f - return nil unless prev_bt = prev[backtrack]? - path << prev_bt - backtrack = prev_bt - end - {path.reverse!, distances[t]} - end -end diff --git a/heap.cr b/heap.cr deleted file mode 100644 index cc106b9..0000000 --- a/heap.cr +++ /dev/null @@ -1,83 +0,0 @@ -class Array(T) - def bubble_up(i, &cmp) - return if i >= size - while i != 0 - j = (i-1)//2 - break if yield self[i], self[j] - self[i], self[j] = self[j], self[i] - i = j - end - end - - def percalate_down(i, &cmp) - while i*2+1 < size - j1, j2 = i*2+1, i*2+2 - v1 = self[j1] - v2 = self[j2]? - if v2 && (yield v1, v2) && (yield self[i], v2) - self[j2], self[i] = self[i], v2 - i = j2 - elsif yield self[i], v1 - self[j1], self[i] = self[i], v1 - i = j1 - else - break - end - end - end - - def heapify(&cmp : T,T -> Bool) - size.times do |i| - i = size - i - 1 - bubble_up(i, &cmp) - end - self - end - - def heapify - heapify do |i,j| - i < j - end - end - - def heap_push(v, &cmp : T,T -> Bool) - self << v - bubble_up(size - 1, &cmp) - end - - def heap_push(v) - heap_push(v) do |i,j| - i < j - end - end - - def heap_pop(&cmp : T,T -> Bool) - self[0], self[size-1] = self[size-1], self[0] - v = pop - percalate_down(0, &cmp) - v - end - - def heap_pop - heap_pop do |i, j| - i < j - end - end - - def is_heap?(&cmp : T,T -> Bool) - (size-1).times do |i| - i = size - i - 1 - vi = self[i] - vp = self[(i-1)//2] - return false unless (yield self[i], self[(i-1)//2]) || vi == vp - end - return true - end - - def is_heap? - is_heap? do |i,j| - i < j - end - end - -end diff --git a/knapsack.cr b/knapsack.cr deleted file mode 100644 index 8f2d5d1..0000000 --- a/knapsack.cr +++ /dev/null @@ -1,39 +0,0 @@ -class Array(T) - def knapsack(budget, &cv : T -> {Int32,Int32}) - cost_values = map &cv - - memo = {} of {Int32, Int32} => Int32 - bt = {} of {Int32, Int32} => Bool - compute = uninitialized Int32, Int32 -> Int32 - compute = ->(size : Int32, budget : Int32) { - if m = memo[{size, budget}]? - return m - end - return memo[{size, budget}] = 0 if size == 0 - - cost, value = cost_values[size-1] - no_val = compute.call(size-1, budget) - yes_val = (budget < cost) ? 0 : compute.call(size-1, budget - cost) + value - - if yes_val > no_val - bt[{size, budget}] = true - return yes_val - else - bt[{size, budget}] = false - return no_val - end - } - - value = compute.call(size, budget) - i = size - items = [] of T - while i != 0 - if bt[{i, budget}] - items << self[i-1] - budget -= cost_values[i-1][0] - end - i -= 1 - end - {value, items} - end -end diff --git a/shard.yml b/shard.yml new file mode 100644 index 0000000..1e854a8 --- /dev/null +++ b/shard.yml @@ -0,0 +1,13 @@ +name: advent-2020 +version: 0.1.0 + +authors: + - your-name-here + +dependencies: + advent: + git: https://dev.danilafe.com/Advent-of-Code/advent + +crystal: 0.35.1 + +license: MIT