-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathday9.rb
107 lines (96 loc) · 2.75 KB
/
day9.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
# coding: utf-8
# http://AdventOfCode.com/
# --- Day 9: All in a Single Night ---
#
# Every year, Santa manages to deliver all of his presents in a single night.
#
# This year, however, he has some new locations to visit; his elves have provided him the
# distances between every pair of locations. He can start and end at any two (different) locations
# he wants, but he must visit each location exactly once. What is the shortest distance he can
# travel to achieve this?
#
# For example, given the following distances:
#
# London to Dublin = 464
# London to Belfast = 518
# Dublin to Belfast = 141
# The possible routes are therefore:
#
# Dublin -> London -> Belfast = 982
# London -> Dublin -> Belfast = 605
# London -> Belfast -> Dublin = 659
# Dublin -> Belfast -> London = 659
# Belfast -> Dublin -> London = 605
# Belfast -> London -> Dublin = 982
#
# The shortest of these is London -> Dublin -> Belfast = 605, and so the answer is 605 in this
# example.
#
# What is the distance of the shortest route?
#
# --- Part Two ---
#
# The next year, just to show off, Santa decides to take the route with the longest distance
# instead.
#
# He can still start and end at any two (different) locations he wants, and he still must visit
# each location exactly once.
#
# For example, given the distances above, the longest route would be 982
# via (for example) Dublin -> London -> Belfast.
#
# What is the distance of the longest route?
require_relative 'input'
day = /day(\d+)\.rb/.match(__FILE__)[1].to_i
input = <<-'EOF'
London to Dublin = 464
London to Belfast = 518
Dublin to Belfast = 141
EOF
input = Input.for_day(day)
# star 1
class Graph
require 'set'
def initialize
@graph = Hash.new {|h,k| h[k] = {}}
@cities = Set.new
end
def add_pair(a, b, distance)
@cities << a << b
@graph[a][b] = distance
@graph[b][a] = distance
end
def each_route
@cities.to_a.permutation.each {|route| yield route}
end
def route_length(*stops)
distance = 0
stops.each_cons(2) do |a,b|
distance += @graph[a][b]
end
distance
end
end
graph = Graph.new
input.each_line do |pair|
a, b, distance = /\A(\w+) to (\w+) = (\d+)\z/.match(pair.chomp).captures
graph.add_pair(a, b, distance.to_i)
end
shortest_route = nil
shortest_distance = nil
# star 2
longest_route = nil
longest_distance = nil
graph.each_route do |route|
distance = graph.route_length *route
if shortest_route.nil? || distance < shortest_distance
shortest_route = route.dup
shortest_distance = distance
end
if longest_route.nil? || distance > longest_distance
longest_route = route.dup
longest_distance = distance
end
end
puts "Shortest #{shortest_route.join(' -> ')} is #{shortest_distance}"
puts "Longest #{longest_route.join(' -> ')} is #{longest_distance}"