Last active
December 9, 2016 21:24
-
-
Save tdlm/267d93ba077946e17f7b60b03831fc71 to your computer and use it in GitHub Desktop.
Advent of Code
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/ruby | |
require "test/unit" | |
class GridMap | |
CARDINAL="NESW" | |
def initialize(directions) | |
@face = 'N' | |
@pointing = 0 | |
@x = 0 | |
@y = 0 | |
@directions = directions.split(', ') | |
end | |
def get_distance_from_origin | |
@directions.each do |move| | |
direction, steps = move.match(/([RL])(\d+)/i).captures | |
steps = steps.to_i | |
turn(direction) | |
step(steps) | |
end | |
return (@x).abs + (@y).abs | |
end | |
def turn(direction) | |
@pointing += 1 if direction == 'R' | |
@pointing -= 1 if direction == 'L' | |
@pointing = 0 if @pointing > 3 | |
@pointing = 3 if @pointing < 0 | |
@face = CARDINAL[@pointing] | |
end | |
def step(steps) | |
case @face | |
when 'N' | |
@y += steps | |
when 'S' | |
@y -= steps | |
when 'E' | |
@x += steps | |
when 'W' | |
@x -= steps | |
end | |
end | |
end | |
class TestGridMap < Test::Unit::TestCase | |
def test_one | |
mapper = GridMap.new('R2, L3') | |
assert_equal(5, mapper.get_distance_from_origin) | |
end | |
def test_two | |
mapper = GridMap.new('R2, R2, R2') | |
assert_equal(2, mapper.get_distance_from_origin) | |
end | |
def test_three | |
mapper = GridMap.new('R5, L5, R5, R3') | |
assert_equal(12, mapper.get_distance_from_origin) | |
end | |
def test_four | |
mapper = GridMap.new('R4, R5, L5, L5, L3, R2, R1, R1, L5, R5, R2, L1, L3, L4, R3, L1, L1, R2, R3, R3, R1, L3, L5, R3, R1, L1, R1, R2, L1, L4, L5, R4, R2, L192, R5, L2, R53, R1, L5, R73, R5, L5, R186, L3, L2, R1, R3, L3, L3, R1, L4, L2, R3, L5, R4, R3, R1, L1, R5, R2, R1, R1, R1, R3, R2, L1, R5, R1, L5, R2, L2, L4, R3, L1, R4, L5, R4, R3, L5, L3, R4, R2, L5, L5, R2, R3, R5, R4, R2, R1, L1, L5, L2, L3, L4, L5, L4, L5, L1, R3, R4, R5, R3, L5, L4, L3, L1, L4, R2, R5, R5, R4, L2, L4, R3, R1, L2, R5, L5, R1, R1, L1, L5, L5, L2, L1, R5, R2, L4, L1, R4, R3, L3, R1, R5, L1, L4, R2, L3, R5, R3, R1, L3') | |
assert_equal(250, mapper.get_distance_from_origin) | |
end | |
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/ruby | |
require "test/unit" | |
class KeypadLock | |
PADLOCK=[ '123', | |
'456', | |
'789' ] | |
def initialize(instructions) | |
@instructions = instructions.split("\n") | |
@pointer = 5 | |
@code = '' | |
end | |
def determine_code | |
@instructions.each do |instruction| | |
instruction.split('').each do |move| | |
move(move) | |
end | |
@code << @pointer.to_s | |
end | |
@code.to_i | |
end | |
def move(direction) | |
case direction | |
when 'U' | |
@pointer -= 3 if ![1, 2, 3].include?(@pointer) | |
when 'D' | |
@pointer += 3 if ![7, 8, 9].include?(@pointer) | |
when 'L' | |
@pointer -= 1 if ![1, 4, 7].include?(@pointer) | |
when 'R' | |
@pointer += 1 if ![3, 6, 9].include?(@pointer) | |
end | |
end | |
end | |
class TestPadLock < Test::Unit::TestCase | |
def test_one | |
instructions = "ULL\nRRDDD\nLURDL\nUUUUD" | |
padlock = KeypadLock.new(instructions) | |
code = padlock.determine_code | |
assert_equal(1985, code) | |
end | |
def test_two | |
instructions = "LLLUDRDLLULDUDLLRLUDURULDURRRRLLURLDLDDDULLDDUDLRDLRDUURRDUUDLLRUUDDLULURDLRDUUDUDRURULLLLDRULDDLRDDRDLRDDLURLDDUDLLUUDLRDDDDLULUUURRDLUUDDLULLURRRDULLUDUDRDRDDRLDLLRLRDDDRDLULLUULDLLLRRDDUURUURDLLDRRDDLRULDLLDRLLUDRRDLUUULDLURLLDDURRUULLLLLRLUDLDDLLLURRRDUDULRULULDDLLDLRDDDUULRLRDUURLURRUDDURRUUDUDLDDLDULDDDDDULRULRDLRLDLRDLDDLUDRDUUDLDUDUDLLLRLUUDRUDDDRDRURRLLLDLUULDUULRDLULLUURLDRRRLDRLUDRRURLDULULDRUDDULLLDRDLLULUDDDDRDRULDULRRRRDDRULDLRDU\nDLDDRRDLLDUURRLULLLLRDRLUDURLDRRDURRRRUUDDUDRRDDDRRLDDLDDLURDLDRLUDULDUDUUDDDLLULRRLLUDULLLUULDDRDDUDUUDULURULULLDRLRUURDRDDLRRUDRUULLLLURRUDRDULDDRURRURLLLLLRLLLRLLUDUDLRDLULDUDLULLLUUDLLDDDUDUDLLRRDLRDLLLRRLRUDRDUDRURLUUURULLDDDDLLURDULURRLLLRLRRULLRRRLUUULLLLRLRDUURRDUURLLLDRDURRRULDDUDRRDLRLDLLRUDDLLUDRLLUUDRLLLLLLUDLURLLRUDRUUUULDLUDULLDDDDRLURUURDDDURRRLRLUDUUDURDDDDRRLRDLURDDLLULDRDDURLLURULUUUUURDUUULDRRLLURRRRRLDDUULLRULLDLDLDLRRRDRLDRUUD\nRLDRRRURULDLUDLDUDLLDUUURRDUDDURULLRRDDULUUDRRRULRUURRRLUUULRDRUDRRLLRLURDLDRDRDLLUDRUULRUDRUDDRURLRLURRDDRRURUUDRRDDRURURUDUUUDUDRRLRDRUUURLLUUUDLRUUDDRDDDDLDRLRDUDDULDDLRLLRURLLURLDDLDLDDULLDDUUURDLRUDUUDLDURDDRUULDRDDRDDDUUUDRDRDDRRDRRDLRDRURDUDDLUUUDULLUULULULRDRUUDDURURDRRRRLUDLDUDURLDRURDLLUUUDLRRDRRURDDULULURLDUDDLUDLDDLLRLDULLULULURUURLDULUDLLUUDLDDULDRRDDUULLUDLDLLRDRDURDDURDDURLDDURUURLLRURURUDDURRDRLRLDDUUDUULRDLLURRRRULURULDUDUDDUDDRLLLDLURDUURUURLUULRRLDLULDDRLDDUURULURUDRD\nURLDDRLLRRLDRLLRRURURURDDLRRRUUUURULRRUUDLUDRULLDLRUDDLULRUULDULURLLRLLUDDUDLURDRRRRLURULRURRURRULRRRULDLLDDLRLUDULUUUDDUDDRRDDDDUULRRLDRRULULRDUURRLDDRDULDURUDUDDLDLLURDDLDDRUDUUUDUUURDLDUDUUULLDLRDULRRRDLLURLDLLULRDDULULURLRLUULRLLLDDDUDLLDLURRRULRDUDDLULUDRUDDURULRLRUDDURLLURULLURDRULDUDLDULRRDLDURLUURRDDUDDUDRURUDDURRUUDURUULLLLDDRDDDDDULUUDDURRULLDRRLRRRRRDDRUUDDDURDRDRUDDUULDUDRRDRULUURLURLUDUDULDDRDULDLRUUDLLLRRLRDRDDUUULRDUDLUDLURRDUURDULDRLLDRDULDUDUULRLLDLRLDLUUDLRUULDUUULDLRLRLUULLLLRLRDUDRUUDURLDUDRRURLRUDRRLRDDLRDDLDDUDDDRLRLLRLUUURLURRRLULRLLDRLRDDRRDRL\nDLLLLLLRLRDRUDLRLLRLDLRURRUURLDLDDDDDUDUULLLLRRLRRDUUDUDLULLRRDULUDLLULURLRULURUULRLURDUDLUDULULUUURLRUDULURULRURULURLRLDRRRRLUDLLDULLDDLLULUURRULRDURDUUDDDURRUDLLLLRLDLUDDULLDUDDURURURRRRULDULULUDDUUDRLRLLLDLLLUUUURUDUUDLDLLRLRDDUULLUURLDDLRRDRLULDLULRULDLDURLULUURRRUDLLRDLUDDULRULULUDDURDLUUURDUUURDUDURLUUDRLUDRULUDDRRDLUUDLLLRDDDDDDLDURDDLDRDLUUDRULLUDRDLDULLULDDRUUDRRLRURRUULLRLRDUUURRDRRDULDDULUUDDURLULRLRURLLRRR" | |
padlock = KeypadLock.new(instructions) | |
code = padlock.determine_code | |
assert_equal(56983, code) | |
end | |
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/ruby | |
require "test/unit" | |
class Triangler | |
attr_accessor :triangles | |
def initialize() | |
@triangles = [] | |
@possible = 0 | |
@column_a = [] | |
@column_b = [] | |
@column_c = [] | |
end | |
def read_triangles_from_file(file) | |
begin | |
@triangles = IO.readlines(file) | |
rescue Errno::ENOENT => e | |
return false | |
end | |
end | |
def read_triangles_vertically_from_file(file) | |
begin | |
lines = IO.readlines(file) | |
lines.each do |line| | |
a, b, c = line.strip.split(' ').map(&:to_i) | |
@column_a.push(a) | |
@column_b.push(b) | |
@column_c.push(c) | |
end | |
rescue Errno::ENOENT => e | |
return false | |
end | |
end | |
def determine_possible_triangles | |
@triangles.each do |triangle| | |
triangle_array = triangle.split(' ').map(&:to_i) | |
@possible += 1 if is_triangles_array_possible(triangle_array) | |
end | |
@possible | |
end | |
def determine_possible_vertical_triangles | |
@column_a.each_slice(3) { |triangle_array| @possible += 1 if is_triangles_array_possible(triangle_array) } | |
@column_b.each_slice(3) { |triangle_array| @possible += 1 if is_triangles_array_possible(triangle_array) } | |
@column_c.each_slice(3) { |triangle_array| @possible += 1 if is_triangles_array_possible(triangle_array) } | |
@possible | |
end | |
def is_triangles_array_possible(triangle_array) | |
z = triangle_array.delete_at(triangle_array.index(triangle_array.max)) | |
y = triangle_array.delete_at(triangle_array.index(triangle_array.max)) | |
x = triangle_array.pop | |
is_possible_triangle(x, y, z) | |
end | |
def is_possible_triangle(x, y, z) | |
z < (x + y) | |
end | |
end | |
class TestTriangles < Test::Unit::TestCase | |
def test_bad_file | |
triangler = Triangler.new | |
result = triangler.read_triangles_from_file('bad_file.txt') | |
assert_equal(false, result) | |
end | |
def test_good_file | |
triangler = Triangler.new | |
possible_triangles = 0 | |
if triangler.read_triangles_from_file('day3.input.txt') | |
possible_triangles = triangler.determine_possible_triangles | |
end | |
assert_equal(982, possible_triangles) | |
end | |
def test_good_vertical_file | |
triangler = Triangler.new | |
possible_triangles = 0 | |
if triangler.read_triangles_vertically_from_file('day3.input.txt') | |
possible_triangles = triangler.determine_possible_vertical_triangles | |
end | |
assert_equal(1826, possible_triangles) | |
end | |
def test_bad_triangle | |
triangler = Triangler.new | |
triangler.triangles = ['5 10 25'] | |
possible_triangles = triangler.determine_possible_triangles | |
assert_equal(0, possible_triangles) | |
end | |
def test_good_triangle | |
triangler = Triangler.new | |
triangler.triangles = ['5 10 11'] | |
possible_triangles = triangler.determine_possible_triangles | |
assert_equal(1, possible_triangles) | |
end | |
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/ruby | |
require "test/unit" | |
class Room | |
attr_accessor :sector_id | |
def initialize(room_key) | |
@name_encrypted, @sector_id, @checksum = Room.parse_room_key(room_key) | |
@sector_id = @sector_id.to_i | |
@alpha = "abcdefghijklmnopqrstuvwxyz" | |
end | |
def self.parse_room_key(room_key) | |
room_key.match(/([a-z-]+)-([0-9]+)\[([a-z]+)\]/).captures | |
end | |
def is_real_room | |
name_array = @name_encrypted.tr('-', '').split('').to_a.each_with_object(Hash.new(0)) { |e, h| h[e] += 1 ; h } | |
name_common = name_array.sort_by { |k,v| [-v,k] }.first(5).map { |k,v| k }.join('') | |
name_common == @checksum | |
end | |
def get_decrypted_name | |
decrypted_name = @name_encrypted.tr('-', ' ').split('').to_a | |
for i in 0..@sector_id-1 | |
decrypted_name.each_with_index do |char, idx| | |
next if char == ' ' | |
decrypted_name[idx] = @alpha[ ( @alpha.index(char) + 1) % 26 ] | |
end | |
end | |
decrypted_name.join('') | |
end | |
end | |
class RoomList | |
def initialize | |
@rooms = [] | |
end | |
def read_room_list_from_file(file) | |
begin | |
room_list = IO.readlines(file) | |
rescue Errno::ENOENT => e | |
return false | |
end | |
room_list.each do |room_key| | |
room = Room.new(room_key) | |
@rooms.push(room) | |
end | |
end | |
def add_room_from_room_key(room_key) | |
room = Room.new(room_key) | |
@rooms.push(room) | |
end | |
def get_sum_of_sector_ids | |
sector_id_sum = 0 | |
@rooms.each { |room| sector_id_sum += room.sector_id if room.is_real_room } | |
sector_id_sum | |
end | |
def get_sector_id_matching_name(name) | |
@rooms.each do |room| | |
return room.sector_id if name == room.get_decrypted_name | |
end | |
nil | |
end | |
end | |
class TestRoomList < Test::Unit::TestCase | |
def test_real_room | |
room = Room.new('aaaaa-bbb-z-y-x-123[abxyz]') | |
assert_equal(room.is_real_room, true) | |
end | |
def test_real_room_two | |
room = Room.new('a-b-c-d-e-f-g-h-987[abcde]') | |
assert_equal(room.is_real_room, true) | |
end | |
def test_real_room_three | |
room = Room.new('not-a-real-room-404[oarel]') | |
assert_equal(room.is_real_room, true) | |
end | |
def test_decoy_room | |
room = Room.new('totally-real-room-200[decoy]') | |
assert_equal(room.is_real_room, false) | |
end | |
def test_day4_input_sum_sector_ids | |
room_list = RoomList.new | |
room_list.read_room_list_from_file("day4.input.txt") | |
assert_equal(278221, room_list.get_sum_of_sector_ids) | |
end | |
def test_decrypt_name | |
room = Room.new('qzmt-zixmtkozy-ivhz-343[nonsense]') | |
assert_equal("very encrypted name", room.get_decrypted_name) | |
end | |
def test_bad_file | |
room_list = RoomList.new | |
result = room_list.read_room_list_from_file("bad_input.txt") | |
assert_equal(false, result) | |
end | |
def test_day4_decrypt_names | |
room_list = RoomList.new | |
room_list.read_room_list_from_file("day4.input.txt") | |
sector_id = room_list.get_sector_id_matching_name("northpole object storage") | |
assert_equal(267, sector_id) | |
end | |
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/ruby | |
require "digest" | |
require "test/unit" | |
class HexCracker | |
def initialize(input) | |
@key = input | |
@cracked_key = '' | |
end | |
def get_cracked_password | |
x = 0 | |
for i in 1..8 | |
while true | |
x += 1 | |
test_key = @key + x.to_s | |
hex_key = Digest::MD5.hexdigest test_key | |
if hex_key[0..4].to_s == '00000' | |
@cracked_key << hex_key[5].to_s | |
break | |
end | |
end | |
end | |
@cracked_key | |
end | |
def get_alternate_cracked_password | |
@cracked_key = ' ' | |
x = 0 | |
for i in 1..8 | |
while true | |
test_key = @key + x.to_s | |
hex_key = Digest::MD5.hexdigest test_key | |
idx = hex_key[5].to_i(16) | |
if hex_key[0..4].to_s == '00000' and idx < 8 and @cracked_key[idx] == ' ' | |
@cracked_key[idx] = hex_key[6].to_s | |
x += 1 | |
break | |
end | |
x += 1 | |
end | |
end | |
@cracked_key | |
end | |
end | |
class TestHexCracker < Test::Unit::TestCase | |
def test_known_password | |
hex_cracker = HexCracker.new('abc') | |
assert_equal('18f47a30', hex_cracker.get_cracked_password) | |
end | |
def test_puzzle_input | |
hex_cracker = HexCracker.new('ojvtpuvg') | |
assert_equal('4543c154', hex_cracker.get_cracked_password) | |
end | |
def test_known_password_two | |
hex_cracker = HexCracker.new('abc') | |
assert_equal('05ace8e3', hex_cracker.get_alternate_cracked_password) | |
end | |
def test_puzzle_input_two | |
hex_cracker = HexCracker.new('ojvtpuvg') | |
assert_equal('1050cbbd', hex_cracker.get_alternate_cracked_password) | |
end | |
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/ruby | |
require "test/unit" | |
class SignalUnjammer | |
def initialize(signal_pieces = nil) | |
@columns = [] | |
if !signal_pieces.nil? | |
parse_signal_pieces(signal_pieces.split("\n").to_a) | |
end | |
end | |
def read_signal_pieces_from_file(file) | |
begin | |
signal_pieces = IO.readlines(file).map(&:chomp) | |
parse_signal_pieces(signal_pieces) | |
rescue Errno::ENOENT => e | |
return false | |
end | |
@signals = signal_pieces | |
end | |
def parse_signal_pieces(signal_pieces) | |
signal_pieces.each_with_index do |line| | |
line.split('').each_with_index { |char, idx| @columns[idx] ||= [] ; @columns[idx].push(char) } | |
end | |
end | |
def unjam_repeat_signal | |
words = [] | |
@columns.each do |row| | |
tally_frequency = row.inject(Hash.new(0)) { |h, v| h[v] += 1 ; h } | |
words.push(row.max_by { |v| tally_frequency[v] }) | |
end | |
words.join('') | |
end | |
def unjam_repeat_signal_unlikely | |
words = [] | |
@columns.each do |row| | |
tally_frequency = row.inject(Hash.new(0)) { |h, v| h[v] += 1 ; h } | |
words.push(row.min_by { |v| tally_frequency[v] }) | |
end | |
words.join('') | |
end | |
end | |
class TestUnjammer < Test::Unit::TestCase | |
def test_one | |
signal_unjammer = SignalUnjammer.new("eedadn\ndrvtee\neandsr\nraavrd\natevrs\ntsrnev\nsdttsa\nrasrtv\nnssdts\nntnada\nsvetve\ntesnvt\nvntsnd\nvrdear\ndvrsen\nenarar") | |
assert_equal('easter', signal_unjammer.unjam_repeat_signal) | |
end | |
def test_two | |
signal_unjammer = SignalUnjammer.new | |
signal_unjammer.read_signal_pieces_from_file('day6.input.txt') | |
assert_equal('xdkzukcf', signal_unjammer.unjam_repeat_signal) | |
end | |
def test_three | |
signal_unjammer = SignalUnjammer.new("eedadn\ndrvtee\neandsr\nraavrd\natevrs\ntsrnev\nsdttsa\nrasrtv\nnssdts\nntnada\nsvetve\ntesnvt\nvntsnd\nvrdear\ndvrsen\nenarar") | |
assert_equal('advent', signal_unjammer.unjam_repeat_signal_unlikely) | |
end | |
def test_four | |
signal_unjammer = SignalUnjammer.new | |
signal_unjammer.read_signal_pieces_from_file('day6.input.txt') | |
assert_equal('cevsgyvd', signal_unjammer.unjam_repeat_signal_unlikely) | |
end | |
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/ruby | |
require "test/unit" | |
class String | |
def contains_abba | |
for i in 0..self.length-4 | |
return true if self[i] + self[i+1] == self[i+3] + self[i+2] and self[i+1] != self[i+3] | |
end | |
return false | |
end | |
def contains_bab | |
for i in 0..self.length-3 | |
return true if self[i] == self[i+2] and self[i] != self[i+1] | |
end | |
return false | |
end | |
def get_babs | |
babs = [] | |
for i in 0..self.length-3 | |
babs.push(self[i] + self[i+1] + self[i+2]) if self[i] == self[i+2] and self[i] != self[i+1] | |
end | |
babs | |
end | |
def flip_bab | |
self[1] + self[0] + self[1] | |
end | |
end | |
class IP | |
attr_accessor :address | |
def initialize(ip_address) | |
@address = ip_address | |
end | |
def get_hypernets | |
@address.scan(/\[([a-z]+)\]/).flatten | |
end | |
def get_supernets | |
@address.gsub(/\[([a-z]+)\]/, ' ').scan(/([a-z]+)/).flatten | |
end | |
def get_supernets_babs | |
babs = [] | |
get_supernets.each do |supernet| | |
supernet.get_babs.each do |bab| | |
babs.push(bab) | |
end | |
end | |
babs | |
end | |
def get_hypernets_babs | |
babs = [] | |
get_hypernets.each do |supernet| | |
supernet.get_babs.each do |bab| | |
babs.push(bab) | |
end | |
end | |
babs | |
end | |
def supports_tls | |
hypernets = get_hypernets | |
supernets = get_supernets | |
hypernets.each { |hypernet| return false if hypernet.contains_abba } | |
supernets.each { |supernet| return true if supernet.contains_abba } | |
return false | |
end | |
def supports_ssl | |
get_supernets_babs.each do |supernet| | |
return true if get_hypernets_babs.include?(supernet.flip_bab) | |
end | |
return false | |
end | |
end | |
class IPSet | |
def read_ip_set_from_file(file) | |
begin | |
@ip_set = IO.readlines(file).map(&:chomp) | |
count_valid_ips | |
rescue Errno::ENOENT => e | |
return false | |
end | |
end | |
def count_valid_ips | |
count = 0 | |
@ip_set.each do |ip_address| | |
ip = IP.new(ip_address) | |
count += 1 if ip.supports_tls | |
end | |
return count | |
end | |
def count_ssl_ips | |
count = 0 | |
@ip_set.each do |ip_address| | |
ip = IP.new(ip_address) | |
count += 1 if ip.supports_ssl | |
end | |
return count | |
end | |
end | |
class AbbaTest < Test::Unit::TestCase | |
def test_one | |
ip = IP.new('abba[mnop]qrst') | |
assert_equal(ip.supports_tls, true) | |
end | |
def test_two | |
ip = IP.new('abcd[bddb]xyyx') | |
assert_equal(ip.supports_tls, false) | |
end | |
def test_three | |
ip = IP.new('aaaa[qwer]tyui') | |
assert_equal(ip.supports_tls, false) | |
end | |
def test_four | |
ip = IP.new('ioxxoj[asdfgh]zxcvbn') | |
assert_equal(ip.supports_tls, true) | |
end | |
def test_variable_length | |
ip = IP.new('okcmoevreebuujjdl[nzonouoydhqlmxbyb]kzleqfmoglkipweur[rrtypikbmtkzegy]cmehcxntlavmojfw[tvvcithufoahlxby]') | |
assert_equal(ip.supports_tls, false) | |
end | |
def test_count_valid_ips | |
ip_set = IPSet.new | |
ip_set.read_ip_set_from_file('day7.input.txt') | |
assert_equal(ip_set.count_valid_ips, 110) | |
end | |
def test_bab_one | |
ip = IP.new('aba[bab]xyz') | |
assert_equal(ip.supports_ssl, true) | |
end | |
def test_bab_two | |
ip = IP.new('xyx[xyx]xyx') | |
assert_equal(ip.supports_ssl, false) | |
end | |
def test_bab_three | |
ip = IP.new('aaa[kek]eke') | |
assert_equal(ip.supports_ssl, true) | |
end | |
def test_bab_four | |
ip = IP.new('zazbz[bzb]cdb') | |
assert_equal(ip.supports_ssl, true) | |
end | |
def test_count_valid_ips | |
ip_set = IPSet.new | |
ip_set.read_ip_set_from_file('day7.input.txt') | |
assert_equal(ip_set.count_ssl_ips, 242) | |
end | |
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/ruby | |
require "test/unit" | |
class Grid | |
attr_accessor :grid, :width, :height | |
def initialize(width, height) | |
@grid = Array.new(height) { Array.new(width, 0) } | |
@width = width | |
@height = height | |
end | |
def print_grid | |
@grid.each do |row| | |
row.each do |cell| | |
print cell == 0 ? '.' : '#' | |
end | |
print "\n" | |
end | |
print "\n" | |
end | |
def draw_rectangle(x1, y1, x2, y2) | |
@grid.each_with_index do |row, y| | |
row.each_with_index do |cell, x| | |
@grid[y][x] = 1 if x >= x1 and x <= x2 and y >= y1 and y <= y2 | |
end | |
end | |
end | |
end | |
class Screen < Grid | |
def read_sequence_set_from_file(file) | |
begin | |
@sequence = IO.readlines(file).map(&:chomp) | |
parse_sequence_commands | |
rescue Errno::ENOENT => e | |
return false | |
end | |
end | |
def parse_sequence_commands | |
@sequence.each do |command| | |
if m = command.match(/^(rect) ([\d]+)x([\d]+)/) | |
action, width, height = m.captures | |
end | |
if m = command.match(/^(rotate row) y\=([\d]+) by ([\d]+)/) | |
action, y, distance = m.captures | |
end | |
if m = command.match(/^(rotate column) x\=([\d]+) by ([\d]+)/) | |
action, x, distance = m.captures | |
end | |
case action | |
when "rect" | |
draw_rect(width.to_i, height.to_i) | |
when "rotate row" | |
rotate_row_y(y.to_i, distance.to_i) | |
when "rotate column" | |
rotate_column_x(x.to_i, distance.to_i) | |
end | |
end | |
end | |
def draw_rect(width, height) | |
draw_rectangle(0, 0, width - 1, height - 1) | |
end | |
def rotate_column_x(x, distance) | |
for i in 1..distance | |
temp_column_x = [] | |
temp_column_x2 = [] | |
for y in 0..@height - 1 | |
temp_column_x.push(@grid[y][x]) | |
end | |
temp_column_x.each_with_index do |yoink, idx| | |
temp_column_x2.push(temp_column_x[idx - 1]) | |
end | |
temp_column_x2.each_with_index do |val, idx| | |
@grid[idx][x] = val | |
end | |
end | |
end | |
def rotate_row_y(y, distance) | |
for i in 1..distance | |
temp_row_y = [] | |
temp_row_y2 = [] | |
for x in 0..@width-1 | |
temp_row_y.push(@grid[y][x]) | |
end | |
temp_row_y.each_with_index do |val, idx| | |
temp_row_y2.push(temp_row_y[idx - 1]) | |
end | |
temp_row_y2.each_with_index do |val, idx| | |
@grid[y][idx] = val | |
end | |
end | |
end | |
def get_lit_pixels | |
count = 0 | |
@grid.each_with_index do |row, y| | |
row.each_with_index do |cell, x| | |
count += 1 if @grid[y][x] == 1 | |
end | |
end | |
count | |
end | |
end | |
class PixelTest < Test::Unit::TestCase | |
def test_one | |
screen = Screen.new(7, 3) | |
screen.draw_rect(3, 2) | |
screen.rotate_column_x(1, 1) | |
screen.rotate_row_y(0, 4) | |
screen.rotate_column_x(1, 1) | |
assert_equal(screen.get_lit_pixels, 6) | |
end | |
def test_two | |
screen = Screen.new(50, 6) | |
screen.read_sequence_set_from_file('day8.input.txt') | |
screen.print_grid | |
assert_equal(screen.get_lit_pixels, 106) | |
end | |
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/ruby | |
require "test/unit" | |
class Decompressor | |
attr_accessor :compressed | |
def initialize(compressed_string) | |
@compressed = compressed_string | |
@decompressed = "" | |
end | |
def decompress | |
pointer = 0 | |
while @compressed[pointer] != nil | |
instruction = '' | |
if @compressed[pointer] == '(' | |
while @compressed[pointer + 1] != ')' | |
pointer += 1 | |
instruction << @compressed[pointer] | |
end | |
# Move pointer beyond bracket | |
pointer += 2 | |
c, n = instruction.split('x').map(&:to_i) | |
copy_block = @compressed[pointer..pointer+(c-1)] | |
for x in pointer..pointer+(n-1) | |
@decompressed << copy_block | |
end | |
# Move pointer beyond copy point | |
pointer += c-1 | |
else | |
@decompressed << @compressed[pointer] | |
end | |
pointer += 1 | |
end | |
@decompressed | |
end | |
def unzip(s) | |
bracket = s.match(/\((\d+)x(\d+)\)/) | |
return s.length if bracket == nil | |
uz_position = s.index(bracket.to_s) | |
uz_size, uz_mult = bracket.captures.map(&:to_i) | |
i = uz_position + bracket.to_s.length | |
chunk = uz_position > 0 ? s[0 .. uz_position - 1] : '' | |
return chunk.length + unzip(s[i..i+(uz_size-1)]) * uz_mult + unzip(s[i+uz_size..-1]) | |
end | |
end | |
class DecompressorRun | |
def read_compressed_set_from_file(file) | |
begin | |
@compressed_set = IO.readlines(file).map(&:chomp) | |
rescue Errno::ENOENT => e | |
return false | |
end | |
end | |
def parse_compressed_set_and_return_length | |
length = 0 | |
@compressed_set.each do |compressed| | |
decompressor = Decompressor.new(compressed) | |
length += decompressor.decompress.length | |
end | |
length | |
end | |
def unzip_compressed_set_and_return_length | |
length = 0 | |
@compressed_set.each do |compressed| | |
decompressor = Decompressor.new(compressed) | |
length += decompressor.unzip(compressed) | |
end | |
length | |
end | |
end | |
class TestDecompressor < Test::Unit::TestCase | |
def test_one | |
decompressor = Decompressor.new('ADVENT') | |
assert_equal('ADVENT', decompressor.decompress) | |
end | |
def test_two | |
decompressor = Decompressor.new('A(1x5)BC') | |
assert_equal('ABBBBBC', decompressor.decompress) | |
end | |
def test_three | |
decompressor = Decompressor.new('(3x3)XYZ') | |
assert_equal('XYZXYZXYZ', decompressor.decompress) | |
end | |
def test_four | |
decompressor = Decompressor.new('A(2x2)BCD(2x2)EFG') | |
assert_equal('ABCBCDEFEFG', decompressor.decompress) | |
end | |
def test_five | |
decompressor = Decompressor.new('(6x1)(1x3)A') | |
assert_equal('(1x3)A', decompressor.decompress) | |
end | |
def test_six | |
decompressor = Decompressor.new('X(8x2)(3x3)ABCY') | |
assert_equal('X(3x3)ABC(3x3)ABCY', decompressor.decompress) | |
end | |
def test_seven | |
run = DecompressorRun.new | |
run.read_compressed_set_from_file('day9.input.txt') | |
assert_equal(183269, run.parse_compressed_set_and_return_length) | |
end | |
def test_eight | |
decompressor = Decompressor.new('(25x3)(3x3)ABC(2x3)XY(5x2)PQRSTX(18x9)(3x2)TWO(5x7)SEVEN') | |
assert_equal(445, decompressor.unzip(decompressor.compressed)) | |
end | |
def test_nine | |
run = DecompressorRun.new | |
run.read_compressed_set_from_file('day9.input.txt') | |
assert_equal(11317278863, run.unzip_compressed_set_and_return_length) | |
end | |
def test_one_alternate | |
decompressor = Decompressor.new('ADVENT') | |
assert_equal(6, decompressor.unzip(decompressor.compressed)) | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment