Skip to content

Instantly share code, notes, and snippets.

@Hamled
Last active December 22, 2015 07:45
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Hamled/76f23076bd89ecf3e567 to your computer and use it in GitHub Desktop.
Save Hamled/76f23076bd89ecf3e567 to your computer and use it in GitHub Desktop.
Advent of Code 2015

Advent of Code 2015

http://adventofcode.com/

My Attempts

For this coding challenge/exercise I decided to restrict myself to only single-line responses. In order to achieve this I employ shell scripting to download the problem input, and Ruby code passed directly to an interpreter in order to transform it.

More important than the literal single-line nature of the code is the single "statement" aspect. I've prefered to use Ruby features and library methods that chain together, resulting in one long run-on expression. In doing so I've forced myself to think about the code as a sequence of data transformations that flow from one piece of the chain into the next.

A few Enumerable methods for many to many transformations (map and select), and many to one (inject and find) are the backbone of this style of programming, along with using basic arrays to structure data and destructing to access it again. In many Lisp-style languages this is the preferred way of designing your code.

Setup Instructions

The code examples in this Gist rely upon an "environment variable" (a variable within your bash terminal) called $ADVENT_TOKEN. This variable should be set to a value copied from your browser's cookie data for the Advent of Code site. You can set the environment variable in your terminal with the following command, it will remain set until you close the terminal:

export ADVENT_TOKEN=8e280b8ca1ff0cae4194b271df98a28cb31f929e5

The value 8e280b8c... can be found in Chrome with the following steps:

  1. Visit the Advent of Code website.
  2. Open the Developer Tools (Cmd + Option + I).
  3. Switch to the Resources tab.
  4. Open Cookies in the left-hand menu and select adventofcode.com
  5. Under the Value column in the right-hand pane, right-click on the entry for the row named 'session'.
  6. Select Copy.
# Day 1 Part 1
puts (
gets.
#=> "))()())\n"
chomp.
#=> "))()())"
chars.
#=> [")", ")", "(", ")", "(", ")", ")"] <--+
# |
# +---------------------------------+
# V
map do |paren|
{')': -1, '(': 1}[paren.to_sym]
end.
#=> [-1, -1, 1, -1, 1, -1, -1]
inject(:+)) # Sum the array
#=> -3
# Day 1 Part 2
puts (
gets.
#=> "))()())\n"
chomp.
#=> "))()())"
chars.
#=> [")", ")", "(", ")", "(", ")", ")"] <--+
# |
# +---------------------------------+
# V
map do |paren|
{')': -1, '(': 1}[paren.to_sym]
end.
#=> [-1, -1, 1, -1, 1, -1, -1] >-----------+
# |
# |
# +-initial value-+ |
# | | |
# | +----------<<<-----|-----------+
# | +-init value|->>>--+ | |
# | | | | | |
# | | | +---<<<-----|-------+ |
# | | | | | | |
# ^ ^ V V V | |
inject([0, [0]]) do |(floor, history), direction|# | |
# | |
# | |
# +--------value for next iteration-----------|---+
# ^ ^
[(new_floor = floor + direction), history << new_floor]
end. # V V
# | |
# +--+ +------------------------+
# V V
#=> [-3, [0, -1, -2, -1, -2, -1, -2, -3]]
last.# ^
# |
# +---------+
# V
index do |floor|
floor < 0
end)
#=> 1
# Part 1
curl -s --cookie "session=$ADVENT_TOKEN" http://adventofcode.com/day/1/input | ruby adventofcode_2015_1-1.rb
curl -s --cookie "session=$ADVENT_TOKEN" http://adventofcode.com/day/1/input | ruby -e "puts gets.chomp.chars.map{|paren| {')':-1,'(':1}[paren.to_sym]}.inject(:+)"
# Part 2
curl -s --cookie "session=$ADVENT_TOKEN" http://adventofcode.com/day/1/input | ruby adventofcode_2015_1-2.rb
curl -s --cookie "session=$ADVENT_TOKEN" http://adventofcode.com/day/1/input | ruby -e "puts gets.chomp.chars.map{|paren| {')':-1,'(':1}[paren.to_sym]}.inject([0,[0]]){|(floor,history),direction| [(new_floor = floor + direction), history << new_floor]}.last.index{|floor| floor < 0}"
# Day 2 Part 1
puts (
$stdin.readlines.
#=> "15x9x27\n11x30x2\n"
map do |line|
line.
#=> "15x9x27\n" then "11x30x2\n"
chomp.
#=> "15x9x27" then "11x30x2"
split('x').
#=> ["15", "9", "27"] then
map {|dim| dim.to_i}.
#=> [15, 9, 27] then [11, 30, 2]
combination(2).
#=> [[15, 9], [15, 27], [9, 27]] then [[11, 30], [11, 2], [30, 2]]
# V V
# | |
# +--------+------------------------+
# V
map{|dims| dims.inject(:*)}.
# V
# |
# +------+-----------------------------+
# V V
#=> [15*9, 15*27, 9*27] = [135, 405, 243] then [11*30, 11*2, 30*2] = [330, 22, 60]
sort.
#=> [135, 243, 405] then [22, 60, 330]
# V V
# | |
# +---------------+-------+
# V
map.with_index do |side,i|
(i == 0 ? 3 : 2) * side# >
# V V V
# | | |
# +---------|---|-----+----------+
# | +-----+ +--------------+ |
# V V | |
#=> 135*3 then 243*2 then 405*2 | |
# | |
# +------------------|-+
# | +---------------+
# V V
#=> 22*3 then 60*2 then 330*2
# V V V
# | | |
# | | +--------+
# | +--------------+ |
# +-------------------+ | |
# | | |
end# V V V
#=> [405, 486, 810] then [66, 120, 660]
end.
#=> [[405, 486, 810], [66, 120, 660]
flatten.
#=> [405, 486, 810, 66, 120, 660]
inject(:+)) # Sum the array
#=> 2547
# Day 2 Part 2
# Note: This code is somewhat backwards, so evaluation actually starts in the middle.
puts (
$stdin.readlines.
#=> "15x9x27\n11x30x2\n"
map do |line|
# +-------------------------------------------------------------+
# | +--------------------------------------------+ |
# V V | |
(->(ribbon_dims,bow_dims) do # defines a lambda with two params | |
ribbon_dims. # | |
#=> [18, 30, 0] then [4, 22, 0] | |
inject(:+) + # Sum the array | |
#=> 48 then 26 # | |
bow_dims. # | |
#=> [9, 15, 27] then [2, 11, 30] | |
inject(:*) # Calculate array product | |
#=> 9*15*27 = 3645 then 2*11*30 = 660 | |
#=> 48+3645 = 3693 then 26+660 = 686 | |
# V V | |
# | | | |
# | +--------------------------------|--|-----+
# +---------------------------------------------------|--|--+ |
# | | | |
end)[ # The array indexing syntax here is actually calling the lambda defined above.
*( # The * here is destructing the two element list calculated below, into two parameters for the lambda call.
# | | | |
# | | | |
#################### | | V V
#### START HERE #### | | V V
#################### | | V V
line. # | | | |
#=> "15x9x27\n" then "11x30x2\n" | | | |
chomp. # ^ ^ | |
#=> "15x9x27" then "11x30x2" ^ ^ | |
split('x'). # ^ ^ | |
#=> ["15", "9", "27"] then ["11", "30", "2"] | | | |
map { |dim| dim.to_i }. # | | | |
#=> [15, 9, 27] then [11, 30, 2] | | | |
sort. # | | | |
#=> [9, 15, 27] then [2, 11, 30] | | | |
# V V | | | |
# | | | | | |
# +-----------------------+ | | | |
# | | | | |
# V | | | |
map.with_index do |dim,i| # | | | |
[(i < 2 ? 2 : 0) * dim, dim] # | | | |
# V V V | | | |
# | | | | | | |
# +------------+ | | | | V V
# | +-------------|----------+-----------+ | | V V
# | | +--------------------+ | | | V V
# V V | | | | | |
#=> [9*2, 9] then [15*2, 15] then [27*0, 27] | | | | | |
# +------+ | ^ ^ | |
# | +-----+ ^ ^ | |
# | | ^ ^ | |
# V V | | | |
#=> [2*2, 2] then [11*2, 11] then [30*0, 30] | | | |
# V V V | | | |
# | | | | | | |
# | | +-------------------+ | | | |
# | +--------------------------+ | | | | |
# +--------------------------------+ | | | | | |
# | | | | | | |
end. # V V V | | | |
#=> [[18, 9], [30, 15], [0, 27]] then [[4, 2], [22, 11], [0, 30]] | | | |
# V V V V V V | | | |
transpose)] # end lambda params | | | | | | | | | |
# | | | +-+ | | | | | |
# | +----|-+ | | | | | | |
# +-+ | | | | | | | | |
# | +-----+ | | | | | | | |
# | | +----|---|---+ | | | | |
# | | | | | +---+ | | | |
# | | | | | | | | | |
# V V V V V V | | | |
#=> [[18, 30, 0], [9, 15, 27]] then [[4, 22, 0], [2, 11, 30]] | | | |
# V ribbon_dims V bow_dims | | | |
# | | | | | |
# | +------------------------------------------+ | | |
# +------------------------------------------------------------+ | |
end. # | |
# +------------------------------------------------------------------+ |
# | +---------------------------------------------------------------+
# V V
#=> [3693, 686]
inject(:+)) # Sum the array
#=> 4379
# Part 1
curl -s --cookie "session=$ADVENT_TOKEN" http://adventofcode.com/day/2/input | ruby adventofcode_2015_2-1.rb
curl -s --cookie "session=$ADVENT_TOKEN" http://adventofcode.com/day/2/input | ruby -e "puts \$stdin.readlines.map{|line| line.chomp.split('x').map{|dim| dim.to_i}.combination(2).map{|dims| dims.inject(:*)}.sort.map.with_index{|side,i| 2 * side + (i == 0 ? side : 0)}}.flatten.inject(:+)"
# Part 2
curl -s --cookie "session=$ADVENT_TOKEN" http://adventofcode.com/day/2/input | ruby adventofcode_2015_2-2.rb
curl -s --cookie "session=$ADVENT_TOKEN" http://adventofcode.com/day/2/input | ruby -e "puts \$stdin.readlines.map{|line| (->(ribbon_dims,bow_dims){ribbon_dims.inject(:+) + bow_dims.inject(:*)})[*(line.chomp.split('x').map{|dim| dim.to_i}.sort.map.with_index{|dim,i| [(i < 2 ? 2 : 0) * dim, dim]}.transpose)]}.inject(:+)"
# Part 1
curl -s --cookie "session=$ADVENT_TOKEN" http://adventofcode.com/day/3/input | ruby -e "require 'set'; puts gets.chomp.chars.map{|direction| [[-1,0],[1,0],[0,-1],[0,1]]['<>v^'.index(direction)]}.inject([[0,0],Set.new]){|((loc_x,loc_y),houses),(dir_x,dir_y)| [(location = [loc_x + dir_x, loc_y + dir_y]), houses.add(location)]}.last.length"
# Part 2
curl -s --cookie "session=$ADVENT_TOKEN" http://adventofcode.com/day/3/input | ruby -e "require 'set'; puts gets.chomp.chars.map{|direction| [[-1,0],[1,0],[0,-1],[0,1]]['<>v^'.index(direction)]}.each_slice(2).to_a.transpose.map{|route| route.inject([[0,0],Set.new]){|((loc_x,loc_y),houses),(dir_x,dir_y)| [(location = [loc_x + dir_x, loc_y + dir_y]), houses.add(location)]}.last}.inject(:union).length"
#Academic tradition requires you to cite works you base your article on.
#When using programs that use GNU Parallel to process data for publication
#please cite:
#
# O. Tange (2011): GNU Parallel - The Command-Line Power Tool,
# ;login: The USENIX Magazine, February 2011:42-47.
#
#This helps funding further development; and it won't cost you a cent.
#If you pay 10000 EUR you should feel free to use GNU Parallel without citing.
# Part 1
START_NUM=1; STOP_NUM=1000000; ADVENT_KEY=`curl -s --cookie "session=$ADVENT_TOKEN" http://adventofcode.com/day/4/input`; time seq -f "$ADVENT_KEY%g" $START_NUM $STOP_NUM | parallel --will-cite "md5 -qs {} | sed 's/[0-9a-f]*/& {}/'" | awk /^0{5}/
# Part 2
START_NUM=1; STOP_NUM=1000000; ADVENT_KEY=`curl -s --cookie "session=$ADVENT_TOKEN" http://adventofcode.com/day/4/input`; time seq -f "$ADVENT_KEY%g" $START_NUM $STOP_NUM | parallel --will-cite "md5 -qs {} | sed 's/[0-9a-f]*/& {}/'" | awk /^0{6}/
# Part 1
curl -s --cookie "session=$ADVENT_TOKEN" http://adventofcode.com/day/5/input | ruby -e "puts \$stdin.readlines.select { |line| (vowels, double = 0, false) && (0...line.length).each { |i| (c, n = line[i], line[i+1]) && (vowels += /[aeiou]/.match(c) && 1 || 0) && ((double ||= c == n) || true) && (break false if %w(ab cd pq xy).include? line[i..i+1]) } && double && vowels >= 3 }.length"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment