├── day04 ├── input ├── inputb ├── p1a.hs ├── p2a.hs ├── p1a.ex ├── p2a.ex ├── p1a.js ├── p2a.js ├── p2a.c ├── p1a.c ├── p1a.rs ├── p2a.rs ├── p1a.java └── p2a.java ├── day10 ├── input ├── p1a.hs ├── p2a.hs ├── p1b.rs ├── p2b.rs ├── p1a.ex ├── p2a.ex ├── p1a.rs ├── p2a.rs ├── p1a.java ├── p2a.java ├── p1a.c ├── p2a.c ├── p1b.c ├── p2b.c ├── p1c.c ├── p2c.c ├── p1d.c └── p2d.c ├── day11 ├── input ├── inputa ├── p1a.c ├── p2a.c ├── p1a.rs ├── p1a.hs ├── p2a.hs └── p2a.rs ├── .gitignore ├── day17 ├── inputa ├── input ├── p1a.rs ├── p1a.java ├── p2a.rs ├── p2a.java ├── p1a.c └── p2a.c ├── day01 ├── p1a.rb ├── p2a.rb ├── p1a.c ├── p1a.rs ├── p2a.c ├── p1a.js ├── p1a.go ├── p2a.go ├── p2a.rs ├── p2a.ex ├── p1a.ex ├── p2a.js ├── p1a.java ├── p1a.hs ├── p2a.hs └── p2a.java ├── day15 ├── input ├── inputa ├── p1a.java └── p2a.java ├── day12 ├── p1a.ex ├── p1a.java ├── p1a.rs ├── p1a.c ├── p2a.rs ├── p2a.c └── p2a.java ├── day08 ├── p2a.rs ├── p1a.hs ├── p2a.hs ├── p1a.ex ├── p2a.c ├── p2a.ex ├── p1a.c ├── p2a.java ├── p1a.rs └── p1a.java ├── day23 ├── input ├── p1a.ex └── p2a.ex ├── day03 ├── p1b.rb ├── p1a.ex ├── p1a.rb ├── p1a.rs ├── p2a.ex ├── p1a.hs ├── p2a.hs ├── p2a.rb ├── p2a.rs ├── p1a.js ├── p1a.c ├── p2a.js ├── p2a.c └── p1a.java ├── day05 ├── p2a.ex ├── p2a.js ├── p1a.js ├── p1a.ex ├── p2a.rs ├── p1a.rs ├── p1a.c ├── p2a.java ├── p2a.c ├── p1a.java ├── p1a.hs ├── p2a.hs ├── p1b.hs └── p2b.hs ├── day14 ├── input ├── inputa ├── p1a.java ├── p1a.ex ├── p2a.ex └── p2a.java ├── day02 ├── p2a.rb ├── p2a.ex ├── p1a.ex ├── p1a.rb ├── p2a.js ├── p1a.js ├── p1a.rs ├── p2a.rs ├── p2a.java ├── p1a.java ├── p1a.c ├── p2a.c ├── p2a.hs └── p1a.hs ├── day09 ├── input ├── inputb ├── p1a.hs └── p2a.hs ├── README.md ├── day20 ├── p2a.rs └── p1a.rs ├── day16 ├── p1a.ex ├── p2a.ex ├── p1a.rs ├── p1a.java ├── p2a.rs └── p2a.java ├── day19 ├── p1a.rs ├── p2a.rs └── p2b.rs ├── day06 ├── p1a.ex ├── p2a.ex ├── p2a.js ├── p1a.rs ├── p2a.rs ├── p1a.js ├── p1a.java └── p2a.java ├── day18 ├── p1a.rs ├── p2a.rs └── p2a.ex └── day07 └── p1a.java /day04/input: -------------------------------------------------------------------------------- 1 | ckczppom 2 | -------------------------------------------------------------------------------- /day04/inputb: -------------------------------------------------------------------------------- 1 | bgvyzdsv 2 | -------------------------------------------------------------------------------- /day10/input: -------------------------------------------------------------------------------- 1 | 3113322113 2 | -------------------------------------------------------------------------------- /day11/input: -------------------------------------------------------------------------------- 1 | hxbxwxba 2 | -------------------------------------------------------------------------------- /day11/inputa: -------------------------------------------------------------------------------- 1 | cqjxjnds 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !*/ 3 | !p[1-2][a-z].* 4 | !p[a-z].* 5 | !**/p[1-2][a-z].*/**/*.* 6 | !input 7 | !input[a-z] 8 | -------------------------------------------------------------------------------- /day17/inputa: -------------------------------------------------------------------------------- 1 | 43 2 | 3 3 | 4 4 | 10 5 | 21 6 | 44 7 | 4 8 | 6 9 | 47 10 | 41 11 | 34 12 | 17 13 | 17 14 | 44 15 | 36 16 | 31 17 | 46 18 | 9 19 | 27 20 | 38 21 | -------------------------------------------------------------------------------- /day17/input: -------------------------------------------------------------------------------- 1 | 33 2 | 14 3 | 18 4 | 20 5 | 45 6 | 35 7 | 16 8 | 35 9 | 1 10 | 13 11 | 18 12 | 13 13 | 50 14 | 44 15 | 48 16 | 6 17 | 24 18 | 41 19 | 30 20 | 42 21 | -------------------------------------------------------------------------------- /day01/p1a.rb: -------------------------------------------------------------------------------- 1 | def run 2 | file = File.open("input", "rb").read 3 | floor = 0 4 | 5 | file.split(//).each { |c| 6 | floor+=1 if c == '(' 7 | floor-=1 if c == ')' 8 | } 9 | 10 | puts "The instructions take you to floor #{floor}" 11 | end 12 | 13 | run 14 | -------------------------------------------------------------------------------- /day15/input: -------------------------------------------------------------------------------- 1 | Frosting: capacity 4, durability -2, flavor 0, texture 0, calories 5 2 | Candy: capacity 0, durability 5, flavor -1, texture 0, calories 8 3 | Butterscotch: capacity -1, durability 0, flavor 5, texture 0, calories 6 4 | Sugar: capacity 0, durability 0, flavor -2, texture 2, calories 1 5 | -------------------------------------------------------------------------------- /day15/inputa: -------------------------------------------------------------------------------- 1 | Sugar: capacity 3, durability 0, flavor 0, texture -3, calories 2 2 | Sprinkles: capacity -3, durability 3, flavor 0, texture 0, calories 9 3 | Candy: capacity -1, durability 0, flavor 4, texture 0, calories 1 4 | Chocolate: capacity 0, durability 0, flavor -2, texture 2, calories 8 5 | -------------------------------------------------------------------------------- /day01/p2a.rb: -------------------------------------------------------------------------------- 1 | def run 2 | file = File.open("input", "rb").read 3 | floor = 0 4 | 5 | file.split(//).each_with_index { |c, index| 6 | floor+=1 if c == '(' 7 | floor-=1 if c == ')' 8 | 9 | if floor == -1 10 | puts "Santa enters the basement at position #{index+1}" 11 | break 12 | end 13 | } 14 | end 15 | 16 | run 17 | -------------------------------------------------------------------------------- /day10/p1a.hs: -------------------------------------------------------------------------------- 1 | import Data.List (dropWhileEnd) 2 | import Data.Char (digitToInt) 3 | import Control.Arrow 4 | import Data.List (group) 5 | 6 | lookAndSay :: [Int] -> [Int] 7 | lookAndSay = concatMap (\ (l,x) -> [l,x]) . map (length &&& head) . group 8 | 9 | main = interact $ show . length . (!! 40) . iterate lookAndSay . map digitToInt . dropWhileEnd (== '\n') 10 | -------------------------------------------------------------------------------- /day10/p2a.hs: -------------------------------------------------------------------------------- 1 | import Data.List (dropWhileEnd) 2 | import Data.Char (digitToInt) 3 | import Control.Arrow 4 | import Data.List (group) 5 | 6 | lookAndSay :: [Int] -> [Int] 7 | lookAndSay = concatMap (\ (l,x) -> [l,x]) . map (length &&& head) . group 8 | 9 | main = interact $ show . length . (!! 50) . iterate lookAndSay . map digitToInt . dropWhileEnd (== '\n') 10 | -------------------------------------------------------------------------------- /day01/p1a.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main(void) { 4 | long floor = 0; 5 | unsigned char c = 0; 6 | while ((c = fgetc(stdin)) != '\n') { 7 | switch (c) { 8 | case '(': 9 | floor++; 10 | break; 11 | case ')': 12 | floor--; 13 | break; 14 | default: 15 | printf("Unsupported character.\n"); 16 | break; 17 | } 18 | } 19 | printf("Floor to go to: %ld.\n", floor); 20 | return 0; 21 | } 22 | -------------------------------------------------------------------------------- /day12/p1a.ex: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env elixir 2 | 3 | # by: steven critchfield 4 | # https://github.com/critch 5 | 6 | defmodule Advent12p1 do 7 | def calculate do 8 | {:ok, acc } = File.read("input") 9 | Regex.scan(~r/([\-0-9]+)/, acc) |> 10 | Stream.map(fn x -> String.to_integer(hd(x)) end) |> 11 | Enum.sum 12 | end 13 | end 14 | 15 | IO.puts "Sum of all numbers: " <> Integer.to_string(Advent12p1.calculate) 16 | -------------------------------------------------------------------------------- /day01/p1a.rs: -------------------------------------------------------------------------------- 1 | #![feature(io)] 2 | 3 | use std::io::{self, Read}; 4 | 5 | fn main() { 6 | let stdin = io::stdin(); 7 | let stdin = stdin.lock(); 8 | 9 | let mut current_floor = 0; 10 | 11 | for c in stdin.chars() { 12 | match c.expect("reading from stdin should succeed") { 13 | '(' => current_floor += 1, 14 | ')' => current_floor -= 1, 15 | _ => {}, 16 | } 17 | } 18 | 19 | println!("Floor: {}", current_floor); 20 | } 21 | -------------------------------------------------------------------------------- /day08/p2a.rs: -------------------------------------------------------------------------------- 1 | use std::io::{self, BufRead}; 2 | 3 | fn main() { 4 | let stdin = io::stdin(); 5 | let stdin = stdin.lock(); 6 | 7 | let mut chars_read = 0; 8 | let mut repr_size = 0; 9 | 10 | for line in stdin.lines() { 11 | let line = line.expect("reading from stdin should succeed"); 12 | 13 | chars_read += line.len(); 14 | repr_size += format!("{:?}", line).len(); 15 | } 16 | 17 | println!("Memory: {}", repr_size - chars_read); 18 | } 19 | -------------------------------------------------------------------------------- /day01/p2a.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main(void) { 4 | long floor = 0; 5 | unsigned long pos = 0; 6 | unsigned char c = 0; 7 | while ((c = fgetc(stdin)) != '\n') { 8 | pos++; 9 | switch (c) { 10 | case '(': 11 | floor++; 12 | break; 13 | case ')': 14 | floor--; 15 | break; 16 | default: 17 | puts("Unsupported character.\n"); 18 | break; 19 | } 20 | if (floor == -1) { 21 | printf("Position: %lu.\n", pos); 22 | break; 23 | } 24 | } 25 | return (pos == 0); 26 | } 27 | -------------------------------------------------------------------------------- /day23/input: -------------------------------------------------------------------------------- 1 | jio a, +22 2 | inc a 3 | tpl a 4 | tpl a 5 | tpl a 6 | inc a 7 | tpl a 8 | inc a 9 | tpl a 10 | inc a 11 | inc a 12 | tpl a 13 | inc a 14 | inc a 15 | tpl a 16 | inc a 17 | inc a 18 | tpl a 19 | inc a 20 | inc a 21 | tpl a 22 | jmp +19 23 | tpl a 24 | tpl a 25 | tpl a 26 | tpl a 27 | inc a 28 | inc a 29 | tpl a 30 | inc a 31 | tpl a 32 | inc a 33 | inc a 34 | tpl a 35 | inc a 36 | inc a 37 | tpl a 38 | inc a 39 | tpl a 40 | tpl a 41 | jio a, +8 42 | inc b 43 | jie a, +4 44 | tpl a 45 | inc a 46 | jmp +2 47 | hlf a 48 | jmp -7 49 | -------------------------------------------------------------------------------- /day01/p1a.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | // By Garrett Greenwood 3 | // Dec 2015 4 | // electricexploits.net 5 | 6 | var fs = require('fs'); 7 | 8 | String.prototype.count = function(term) { 9 | return Array.prototype.filter.call(this, function (x) { 10 | return x == term; 11 | }).length; 12 | } 13 | 14 | fs.readFile(process.argv[2], 'utf8', function(err, data) { 15 | if(err) { 16 | console.log("Error reading file"); 17 | return; 18 | } 19 | console.log(data.count('(') - data.count(')')); 20 | }); 21 | -------------------------------------------------------------------------------- /day03/p1b.rb: -------------------------------------------------------------------------------- 1 | def run 2 | file = File.open("input", "rb").read 3 | locs = [] 4 | x = y = 0 5 | 6 | # Already at 0,0 so push into locs 7 | locs.push([0,0]) 8 | 9 | file.split(//).each { |d| 10 | case d 11 | when '^' 12 | x += 1 13 | when 'v' 14 | x -= 1 15 | when '<' 16 | y -= 1 17 | when '>' 18 | y += 1 19 | else 20 | break 21 | end 22 | 23 | locs.push([x,y]) 24 | } 25 | 26 | total = locs.uniq.count 27 | puts "#{total} houses visited" 28 | end 29 | 30 | run 31 | -------------------------------------------------------------------------------- /day01/p1a.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "os" 6 | ) 7 | 8 | func countFloors(input string) (floor int) { 9 | floor = 0 10 | for _, char := range(input) { 11 | if char == '(' { 12 | floor++ 13 | } else { 14 | floor-- 15 | } 16 | } 17 | return 18 | } 19 | 20 | func main() { 21 | fd, err := os.Open(os.Args[1]) 22 | if err != nil { 23 | panic(fmt.Sprintf("open %s: %v", os.Args[1], err)) 24 | } 25 | 26 | var line string 27 | fmt.Fscanf(fd, "%s\n", &line) 28 | 29 | fmt.Println(countFloors(line)) 30 | } 31 | -------------------------------------------------------------------------------- /day05/p2a.ex: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env elixir 2 | 3 | # By: Steven Critchfield 4 | # https://github.com/critch 5 | 6 | defmodule Advent5p2 do 7 | def calculate do 8 | File.stream!("input") |> 9 | Stream.map(fn(x)-> String.strip(x) end) |> 10 | # xyx example 11 | Stream.filter(fn(x) -> String.match?(x, ~r/(\S)\S\1/) end) |> 12 | # two letter repeated structure 13 | Stream.filter(fn(x) -> String.match?(x, ~r/(\S\S).*\1/) end) |> 14 | Enum.map(fn(x) -> x end) |> 15 | Enum.count 16 | end 17 | end 18 | 19 | IO.puts "Nice String count: " <> Integer.to_string(Advent5p2.calculate) 20 | -------------------------------------------------------------------------------- /day01/p2a.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "os" 6 | ) 7 | 8 | func countFloors(input string) int { 9 | floor := 0 10 | for i, char := range(input) { 11 | if char == '(' { 12 | floor++ 13 | } else { 14 | floor-- 15 | } 16 | if floor == -1 { 17 | return i+1 18 | } 19 | } 20 | return -1 21 | } 22 | 23 | func main() { 24 | fd, err := os.Open(os.Args[1]) 25 | if err != nil { 26 | panic(fmt.Sprintf("open %s: %v", os.Args[1], err)) 27 | } 28 | 29 | var line string 30 | fmt.Fscanf(fd, "%s\n", &line) 31 | 32 | fmt.Println(countFloors(line)) 33 | } 34 | -------------------------------------------------------------------------------- /day03/p1a.ex: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env elixir 2 | 3 | # By: Steven Critchfield 4 | # https://github.com/critch 5 | 6 | defmodule Advent3p1 do 7 | def calculate do 8 | File.stream!("input",[],1) |> 9 | Stream.scan([0,0] , fn(x,y) -> move(x,y) end ) |> 10 | Stream.concat([[0,0]]) |> 11 | Stream.uniq |> 12 | Enum.count 13 | end 14 | 15 | def move("<", [x,y]), do: [x+1,y] 16 | def move(">", [x,y]), do: [x-1,y] 17 | def move("^", [x,y]), do: [x,y+1] 18 | def move("v", [x,y]), do: [x,y-1] 19 | def move(_,acc), do: acc 20 | end 21 | 22 | IO.puts "Houses visited: " <> Integer.to_string(Advent3p1.calculate) 23 | -------------------------------------------------------------------------------- /day01/p2a.rs: -------------------------------------------------------------------------------- 1 | #![feature(io)] 2 | 3 | use std::io::{self, Read}; 4 | 5 | fn main() { 6 | let stdin = io::stdin(); 7 | let stdin = stdin.lock(); 8 | 9 | let mut current_floor = 0; 10 | 11 | for (pos, c) in stdin.chars().enumerate() { 12 | match c.expect("reading from stdin should succeed") { 13 | '(' => current_floor += 1, 14 | ')' => current_floor -= 1, 15 | _ => {}, 16 | } 17 | 18 | if current_floor <= -1 { 19 | println!("Character: {}", pos + 1); 20 | return; 21 | } 22 | } 23 | 24 | panic!("never went below floor zero"); 25 | } 26 | -------------------------------------------------------------------------------- /day05/p2a.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | // By Garrett Greenwood 3 | // Dec 2015 4 | // electricexploits.net 5 | 6 | var fs = require('fs'); 7 | 8 | var reg_the_one = /(?=.*(..).*\1)(?=.*(.).\2)/; 9 | 10 | fs.readFile(process.argv[2], 'utf8', function(err, data) { 11 | if(err) { 12 | console.log("Error reading file"); 13 | return; 14 | } 15 | 16 | lines = data.split("\n").slice(0,1000); // Cut the last newline out 17 | total = 0; 18 | 19 | for(var x = 0; x < lines.length; x++) { 20 | if(reg_the_one.exec(lines[x])) { 21 | total++; 22 | } 23 | } 24 | console.log(total); 25 | }); 26 | -------------------------------------------------------------------------------- /day01/p2a.ex: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env elixir 2 | 3 | # By: Steven Critchfield 4 | # https://github.com/critch 5 | 6 | defmodule Advent1p2 do 7 | def calculate do 8 | File.stream!("input", [], 1) |> 9 | Stream.transform([0,0],fn(x,acc) -> loc(x,acc) end) |> 10 | Enum.fetch!(-1) 11 | end 12 | 13 | def loc(_, [-1, position]) do 14 | { :halt, [-1, position ] } 15 | end 16 | def loc("(", [floor, position]) do 17 | { [position+1], [floor+1, position+1] } 18 | end 19 | def loc(")", [floor, position]) do 20 | { [position+1], [floor-1, position+1] } 21 | end 22 | end 23 | 24 | IO.puts "Position: " <> Integer.to_string(Advent1p2.calculate) 25 | -------------------------------------------------------------------------------- /day08/p1a.hs: -------------------------------------------------------------------------------- 1 | {-# Language BangPatterns #-} 2 | 3 | import Data.Char (isSpace) 4 | import qualified Data.ByteString.Lazy.Char8 as B 5 | 6 | countEscape :: String -> Int 7 | countEscape = countEscape' 2 8 | countEscape' :: Int -> String -> Int 9 | countEscape' !x ('\\':'x':_:_:xs) = countEscape' (x + 3) xs 10 | countEscape' !x ('\\':'\\':xs) = countEscape' (x + 1) xs 11 | countEscape' !x ('\\':'"':xs) = countEscape' (x + 1) xs 12 | countEscape' !x (_:xs) = countEscape' x xs 13 | countEscape' !x [] = x 14 | 15 | showDifference :: String -> Int 16 | showDifference str = (length . show $ str) - length str 17 | 18 | main = interact $ show . sum . fmap countEscape . lines 19 | -------------------------------------------------------------------------------- /day04/p1a.hs: -------------------------------------------------------------------------------- 1 | {-# Language BangPatterns #-} 2 | 3 | import Data.Digest.Pure.MD5 (md5) 4 | import qualified Data.ByteString.Lazy.Char8 as B 5 | import Control.Arrow 6 | 7 | pairsWithNZeroes :: Int -> String -> [(String, String)] 8 | pairsWithNZeroes n = filter (startsWithNZeroes n . snd). map md5Pair . allInputs 9 | 10 | md5Pair :: String -> (String, String) 11 | md5Pair = (id &&& show . md5 . B.pack) 12 | 13 | allInputs :: String -> [String] 14 | allInputs input = map ((++) input . show) [1..] 15 | 16 | startsWithNZeroes :: Int -> String -> Bool 17 | startsWithNZeroes n = all (== '0') . take n 18 | 19 | main = interact $ fst . head . pairsWithNZeroes 5 . head . lines 20 | -------------------------------------------------------------------------------- /day04/p2a.hs: -------------------------------------------------------------------------------- 1 | {-# Language BangPatterns #-} 2 | 3 | import Data.Digest.Pure.MD5 (md5) 4 | import qualified Data.ByteString.Lazy.Char8 as B 5 | import Control.Arrow 6 | 7 | pairsWithNZeroes :: Int -> String -> [(String, String)] 8 | pairsWithNZeroes n = filter (startsWithNZeroes n . snd). map md5Pair . allInputs 9 | 10 | md5Pair :: String -> (String, String) 11 | md5Pair = (id &&& show . md5 . B.pack) 12 | 13 | allInputs :: String -> [String] 14 | allInputs input = map ((++) input . show) [1..] 15 | 16 | startsWithNZeroes :: Int -> String -> Bool 17 | startsWithNZeroes n = all (== '0') . take n 18 | 19 | main = interact $ fst . head . pairsWithNZeroes 6 . head . lines 20 | -------------------------------------------------------------------------------- /day08/p2a.hs: -------------------------------------------------------------------------------- 1 | {-# Language BangPatterns #-} 2 | 3 | import Data.Char (isSpace) 4 | import qualified Data.ByteString.Lazy.Char8 as B 5 | 6 | countEscape :: String -> Int 7 | countEscape = countEscape' 2 8 | countEscape' :: Int -> String -> Int 9 | countEscape' !x ('\\':'x':_:_:xs) = countEscape' (x + 3) xs 10 | countEscape' !x ('\\':'\\':xs) = countEscape' (x + 1) xs 11 | countEscape' !x ('\\':'"':xs) = countEscape' (x + 1) xs 12 | countEscape' !x (_:xs) = countEscape' x xs 13 | countEscape' !x [] = x 14 | 15 | showDifference :: String -> Int 16 | showDifference str = (length . show $ str) - length str 17 | 18 | main = interact $ show . sum . fmap showDifference . lines 19 | -------------------------------------------------------------------------------- /day12/p1a.java: -------------------------------------------------------------------------------- 1 | package adventofcode; 2 | 3 | import java.io.File; 4 | import java.io.FileNotFoundException; 5 | import java.util.Scanner; 6 | 7 | public class p1a { 8 | 9 | public static void main(String[] args) throws FileNotFoundException { 10 | Scanner s = new Scanner(new File("input")); 11 | int output = 0; 12 | 13 | String input = s.nextLine(); 14 | 15 | input = input.replaceAll("[\\[\\]\"{},:a-z]", " "); 16 | 17 | s = new Scanner(input); 18 | 19 | while(s.hasNext()){ 20 | output += s.nextInt(); 21 | } 22 | 23 | System.out.println("The sum is " + output + "."); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /day01/p1a.ex: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env elixir 2 | 3 | # By: Steven Critchfield 4 | # https://github.com/critch 5 | 6 | defmodule Advent1p1 do 7 | def calculate do 8 | File.stream!("input", [], 1) |> 9 | Stream.transform([0,0],fn(x,acc) -> loc(x,acc) end) |> 10 | Enum.fetch!(-1) 11 | end 12 | 13 | def loc(x, [floor, position]) when x == "(" do 14 | {[floor+1], [floor+1, position+1] } 15 | end 16 | def loc(x, [floor, position]) when x == ")"do 17 | {[floor-1], [floor-1, position+1] } 18 | end 19 | def loc(_, [floor, position]) do 20 | {[floor], [floor, position]} 21 | end 22 | end 23 | 24 | IO.puts "Floor to go to: " <> Integer.to_string(Advent1p1.calculate) 25 | -------------------------------------------------------------------------------- /day14/input: -------------------------------------------------------------------------------- 1 | Vixen can fly 8 km/s for 8 seconds, but then must rest for 53 seconds. 2 | Blitzen can fly 13 km/s for 4 seconds, but then must rest for 49 seconds. 3 | Rudolph can fly 20 km/s for 7 seconds, but then must rest for 132 seconds. 4 | Cupid can fly 12 km/s for 4 seconds, but then must rest for 43 seconds. 5 | Donner can fly 9 km/s for 5 seconds, but then must rest for 38 seconds. 6 | Dasher can fly 10 km/s for 4 seconds, but then must rest for 37 seconds. 7 | Comet can fly 3 km/s for 37 seconds, but then must rest for 76 seconds. 8 | Prancer can fly 9 km/s for 12 seconds, but then must rest for 97 seconds. 9 | Dancer can fly 37 km/s for 1 seconds, but then must rest for 36 seconds. 10 | -------------------------------------------------------------------------------- /day14/inputa: -------------------------------------------------------------------------------- 1 | Dancer can fly 27 km/s for 5 seconds, but then must rest for 132 seconds. 2 | Cupid can fly 22 km/s for 2 seconds, but then must rest for 41 seconds. 3 | Rudolph can fly 11 km/s for 5 seconds, but then must rest for 48 seconds. 4 | Donner can fly 28 km/s for 5 seconds, but then must rest for 134 seconds. 5 | Dasher can fly 4 km/s for 16 seconds, but then must rest for 55 seconds. 6 | Blitzen can fly 14 km/s for 3 seconds, but then must rest for 38 seconds. 7 | Prancer can fly 3 km/s for 21 seconds, but then must rest for 40 seconds. 8 | Comet can fly 18 km/s for 6 seconds, but then must rest for 103 seconds. 9 | Vixen can fly 18 km/s for 5 seconds, but then must rest for 84 seconds. 10 | -------------------------------------------------------------------------------- /day01/p2a.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | // By Garrett Greenwood 3 | // Dec 2015 4 | // electricexploits.net 5 | 6 | var fs = require('fs'); 7 | 8 | fs.readFile(process.argv[2], 'utf8', function(err, data) { 9 | if(err) { 10 | console.log("Error reading file"); 11 | return; 12 | } 13 | 14 | var floor = 0; 15 | 16 | for(var i = 0; i < data.length; i++) { 17 | if(data[i] == '(') { 18 | floor++; 19 | } else if(data[i] == ')') { 20 | floor--; 21 | } 22 | 23 | if(floor < 0) { 24 | console.log(i+1); 25 | return; 26 | } 27 | } 28 | 29 | console.log("Basement not found"); 30 | }); 31 | -------------------------------------------------------------------------------- /day02/p2a.rb: -------------------------------------------------------------------------------- 1 | def run 2 | file = File.open("input1", "rb").read 3 | file.gsub!(/\r\n?/, "\n") 4 | 5 | total = 0 6 | 7 | file.each_line { |line| 8 | perimeter = nil 9 | 10 | parts = line.split('x').map(&:to_i) 11 | length = parts[0] 12 | width = parts[1] 13 | height = parts[2] 14 | 15 | next if parts.count < 3 16 | 17 | vl = length * width * height 18 | 19 | parts.sort.first(2).each { |x| 20 | if perimeter.nil? 21 | perimeter = x 22 | else 23 | perimeter += x 24 | end 25 | } 26 | 27 | perimeter*=2 28 | 29 | total += vl += perimeter 30 | } 31 | 32 | puts "Total feet is #{total}" 33 | end 34 | 35 | run 36 | -------------------------------------------------------------------------------- /day03/p1a.rb: -------------------------------------------------------------------------------- 1 | def run 2 | file = File.open("input1", "rb").read 3 | total = 1 4 | data = [] 5 | a = b = 0 6 | 7 | file.split(//).each { |c| 8 | can_add = true 9 | 10 | case c 11 | when '^' 12 | a += 1 13 | when '<' 14 | b += 1 15 | when 'v' 16 | a -= 1 17 | when '>' 18 | b -= 1 19 | else 20 | break 21 | end 22 | 23 | data.each { |x| 24 | if a == x["a"] && b == x["b"] 25 | can_add = false 26 | end 27 | } 28 | 29 | if can_add 30 | total += 1 31 | data << {"a" => a, "b" => b} 32 | end 33 | } 34 | 35 | puts "#{total} houses received more than 1 present" 36 | end 37 | 38 | run 39 | -------------------------------------------------------------------------------- /day08/p1a.ex: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env elixir 2 | 3 | # By: Steven Critchfield 4 | # https://github.com/critch 5 | 6 | defmodule Advent8p1 do 7 | def calculate do 8 | [ wc, lwc] = File.stream!("input") |> 9 | Stream.map(fn(x)-> String.strip(x) end) |> 10 | Enum.reduce( [0,0], fn(x, acc) -> tweak(x,acc) end) 11 | IO.inspect([wc,lwc]) 12 | wc - lwc 13 | end 14 | 15 | def tweak(x, acc) do 16 | strlen = byte_size(x) 17 | str = Regex.replace(~r/(\\\"|\\x[0-9a-f][0-9a-f]|\\\\)/, x, "!") 18 | smaller = str |>String.length |> - 2 19 | [strlen + Enum.at(acc,0), Enum.at(acc,1) + smaller ] 20 | end 21 | end 22 | 23 | IO.puts "Difference in strings is: " <> Integer.to_string(Advent8p1.calculate) 24 | -------------------------------------------------------------------------------- /day02/p2a.ex: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env elixir 2 | 3 | # By: Steven Critchfield 4 | # https://github.com/critch 5 | 6 | defmodule Advent2p2 do 7 | def calculate do 8 | File.stream!("input") |> 9 | Stream.map(fn(x) -> String.strip(x) end) |> 10 | Stream.map(fn(x) -> split_str(x) end) |> 11 | Stream.map(fn(x) -> ribbon(x) end ) |> 12 | Enum.sum 13 | end 14 | 15 | def split_str(x) do 16 | String.split(x, "x") |> 17 | Enum.map(fn(c) -> String.to_integer(c) end) 18 | end 19 | 20 | def ribbon(c) do 21 | area = Enum.reduce(c, fn(x,acc) -> acc*x end) 22 | around = (Enum.sum(c) - Enum.max(c) )*2 23 | area+around 24 | end 25 | end 26 | 27 | IO.puts "Total size: " <> Integer.to_string(Advent2p2.calculate) 28 | -------------------------------------------------------------------------------- /day04/p1a.ex: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env elixir 2 | 3 | # By: Steven Critchfield 4 | # https://github.com/critch 5 | 6 | defmodule Advent4p1 do 7 | def calculate do 8 | puzzleinput = File.stream!("input") |> 9 | Stream.map(fn(x) -> String.strip x end) |> 10 | Enum.fetch!(-1) 11 | 12 | check(puzzleinput,1, ~r/^00000/) 13 | end 14 | 15 | def check( input,key,reg) do 16 | out = md5(input <> Integer.to_string(key)) 17 | unless String.match?(out,reg) do 18 | key = check(input, key+1, reg) 19 | end 20 | key 21 | end 22 | 23 | def md5(data) do 24 | :erlang.md5(data) |> 25 | Base.encode16(case: :lower) 26 | end 27 | end 28 | 29 | IO.puts "First successful key: " <> Integer.to_string(Advent4p1.calculate) 30 | -------------------------------------------------------------------------------- /day04/p2a.ex: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env elixir 2 | 3 | # By: Steven Critchfield 4 | # https://github.com/critch 5 | 6 | defmodule Advent4p2 do 7 | def calculate do 8 | puzzleinput = File.stream!("input") |> 9 | Stream.map(fn(x) -> String.strip x end) |> 10 | Enum.fetch!(-1) 11 | 12 | check(puzzleinput,1, ~r/^000000/) 13 | end 14 | 15 | def check( input,key,reg) do 16 | out = md5(input <> Integer.to_string(key)) 17 | unless String.match?(out,reg) do 18 | key = check(input, key+1, reg) 19 | end 20 | key 21 | end 22 | 23 | def md5(data) do 24 | :erlang.md5(data) |> 25 | Base.encode16(case: :lower) 26 | end 27 | end 28 | 29 | IO.puts "First successful key: " <> Integer.to_string(Advent4p2.calculate) 30 | -------------------------------------------------------------------------------- /day02/p1a.ex: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env elixir 2 | 3 | # By: Steven Critchfield 4 | # https://github.com/critch 5 | 6 | defmodule Advent2p1 do 7 | def calculate do 8 | File.stream!("input") |> 9 | Stream.map(fn(x) -> String.strip(x) end) |> 10 | Stream.map(fn(x) -> split_str(x) end) |> 11 | Stream.map(fn(x) -> area(x) end) |> 12 | Enum.sum 13 | end 14 | 15 | def split_str(x) do 16 | String.split(x, "x") |> 17 | Enum.map(fn(c) -> String.to_integer(c) end) 18 | end 19 | 20 | def area(u) do 21 | [x,y,z] = u 22 | size = [x*y, y*z, x*z]; 23 | 24 | [Enum.min(size)] ++ Enum.map(size, fn(x) -> x*2 end) |> 25 | Enum.sum 26 | end 27 | end 28 | 29 | IO.puts "Total Size: " <> Integer.to_string(Advent2p1.calculate) 30 | -------------------------------------------------------------------------------- /day03/p1a.rs: -------------------------------------------------------------------------------- 1 | #![feature(io)] 2 | 3 | use std::collections::HashSet; 4 | use std::io::{self, Read}; 5 | 6 | fn main() { 7 | let stdin = io::stdin(); 8 | let stdin = stdin.lock(); 9 | 10 | let mut visited = HashSet::new(); 11 | visited.insert((0, 0)); 12 | let mut current_x = 0; 13 | let mut current_y = 0; 14 | 15 | for c in stdin.chars() { 16 | match c.expect("reading from stdin should succeed") { 17 | '^' => current_y += 1, 18 | 'v' => current_y -= 1, 19 | '<' => current_x -= 1, 20 | '>' => current_x += 1, 21 | _ => {}, 22 | } 23 | 24 | visited.insert((current_x, current_y)); 25 | } 26 | 27 | println!("Visited: {}", visited.len()); 28 | } 29 | -------------------------------------------------------------------------------- /day01/p1a.java: -------------------------------------------------------------------------------- 1 | package adventofcode; 2 | 3 | import java.io.File; 4 | import java.io.FileNotFoundException; 5 | import java.util.Scanner; 6 | 7 | public class p1a { 8 | 9 | public static int move(String s){ 10 | int total = 0; 11 | char[] characters = s.toCharArray(); 12 | for(char c : characters){ 13 | if(c == '('){ 14 | total++; 15 | } 16 | else{ 17 | total--; 18 | } 19 | } 20 | return total; 21 | } 22 | 23 | public static void main(String[] args) throws FileNotFoundException { 24 | Scanner s = new Scanner(new File("input")); 25 | 26 | System.out.println("Santa ends up at floor " + move(s.next()) + "."); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /day03/p2a.ex: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env elixir 2 | 3 | # By: Steven Critchfield 4 | # https://github.com/critch 5 | 6 | defmodule Advent3p2 do 7 | def calculate do 8 | File.stream!("input",[],1) |> 9 | Stream.scan([1, [0,0],[0,0]] , fn(x,acc) -> m(x,acc) end ) |> 10 | Stream.concat([[1, [0,0],[0,0]]]) |> 11 | Stream.flat_map(fn([_,s,r]) -> [s,r] end) |> 12 | Stream.uniq |> 13 | Enum.count 14 | end 15 | 16 | def m(y,[1, s,r]), do: [2,move(y,s),r] 17 | def m(y,[2, s,r]), do: [1,s,move(y,r)] 18 | def move("<", [x,y]), do: [x+1,y] 19 | def move(">", [x,y]), do: [x-1,y] 20 | def move("^", [x,y]), do: [x,y+1] 21 | def move("v", [x,y]), do: [x,y-1] 22 | def move(_,acc), do: acc 23 | end 24 | 25 | IO.puts "Houses visited: " <> Integer.to_string(Advent3p2.calculate) 26 | -------------------------------------------------------------------------------- /day05/p1a.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | // By Garrett Greenwood 3 | // Dec 2015 4 | // electricexploits.net 5 | 6 | var fs = require('fs'); 7 | 8 | var reg_vowel = /([aeiou]).*?([aeiou]).*?([aeiou])/; 9 | var reg_double = /(.)\1/; 10 | var reg_bad = /(ab|cd|pq|xy)/; 11 | 12 | fs.readFile(process.argv[2], 'utf8', function(err, data) { 13 | if(err) { 14 | console.log("Error reading file"); 15 | return; 16 | } 17 | 18 | lines = data.split("\n").slice(0,1000); // Cut the last newline out 19 | total = 0; 20 | 21 | for(var x = 0; x < lines.length; x++) { 22 | line = lines[x]; 23 | if(reg_vowel.exec(line) && reg_double.exec(line) && !reg_bad.exec(line)) { 24 | total++; 25 | } 26 | } 27 | 28 | console.log(total); 29 | 30 | }); 31 | -------------------------------------------------------------------------------- /day08/p2a.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #define BUFFER 240 5 | 6 | unsigned char Count(char *); 7 | 8 | int main(void) 9 | { 10 | char input[BUFFER]; 11 | unsigned int str[2]; 12 | unsigned long sum = 0; 13 | while((fgets(input, BUFFER, stdin))) { 14 | if ((str[0] = strlen(input)-1)) { 15 | str[1] = Count(input); 16 | printf("strFull: %u, strPrint: %u\n", str[0], str[1]); 17 | sum += str[1] - str[0]; 18 | } 19 | } 20 | printf("Sum: %lu\n", sum); 21 | return 0; 22 | } 23 | 24 | unsigned char Count(char *in) 25 | { 26 | int i; 27 | unsigned char sum = 1; 28 | for (i = 0; i < strlen(in); i++) { 29 | switch (in[i]) { 30 | case '\\': 31 | case '"': 32 | sum++; 33 | break; 34 | } 35 | sum++; 36 | } 37 | return sum; 38 | } 39 | -------------------------------------------------------------------------------- /day01/p1a.hs: -------------------------------------------------------------------------------- 1 | {-# Language BangPatterns #-} 2 | 3 | import Data.List (span) 4 | 5 | -- Make Santa run through the floors based on a string. 6 | runFloors :: Integer -> String -> Integer 7 | runFloors !floor [] = floor 8 | runFloors !floor ('(':xs) = runFloors (floor + 1) xs 9 | runFloors !floor (')':xs) = runFloors (floor - 1) xs 10 | runFloors !floor (_:xs) = runFloors floor xs 11 | 12 | firstBasement :: Integer -> String -> Maybe Int 13 | firstBasement = firstBasement' 1 14 | where 15 | firstBasement' !pos !floor [] = Nothing 16 | firstBasement' !pos !floor ('(':xs) = firstBasement' (pos + 1) (floor + 1) xs 17 | firstBasement' !pos !floor (')':xs) 18 | | floor < 1 = Just pos 19 | | otherwise = firstBasement' (pos + 1) (floor - 1) xs 20 | 21 | main = interact $ show . runFloors 0 22 | -------------------------------------------------------------------------------- /day01/p2a.hs: -------------------------------------------------------------------------------- 1 | {-# Language BangPatterns #-} 2 | 3 | import Data.List (span) 4 | 5 | -- Make Santa run through the floors based on a string. 6 | runFloors :: Integer -> String -> Integer 7 | runFloors !floor [] = floor 8 | runFloors !floor ('(':xs) = runFloors (floor + 1) xs 9 | runFloors !floor (')':xs) = runFloors (floor - 1) xs 10 | runFloors !floor (_:xs) = runFloors floor xs 11 | 12 | firstBasement :: Integer -> String -> Maybe Int 13 | firstBasement = firstBasement' 1 14 | where 15 | firstBasement' !pos !floor [] = Nothing 16 | firstBasement' !pos !floor ('(':xs) = firstBasement' (pos + 1) (floor + 1) xs 17 | firstBasement' !pos !floor (')':xs) 18 | | floor < 1 = Just pos 19 | | otherwise = firstBasement' (pos + 1) (floor - 1) xs 20 | 21 | main = interact $ show . firstBasement 0 22 | -------------------------------------------------------------------------------- /day02/p1a.rb: -------------------------------------------------------------------------------- 1 | def get_surface_area l, w, h 2 | a = 2 * l * w 3 | b = 2 * w * h 4 | c = 2 * h * l 5 | return a + b + c 6 | end 7 | 8 | def run 9 | file = File.open("input1", "rb").read 10 | file.gsub!(/\r\n?/, "\n") 11 | 12 | total = 0 13 | 14 | file.each_line { |line| 15 | smallest = nil 16 | 17 | parts = line.split('x').map(&:to_i) 18 | length = parts[0] 19 | width = parts[1] 20 | height = parts[2] 21 | 22 | next if parts.count < 3 23 | 24 | sa = get_surface_area length, width, height 25 | 26 | parts.sort.first(2).each { |x| 27 | if smallest.nil? 28 | smallest = x 29 | else 30 | smallest *= x 31 | end 32 | } 33 | 34 | total += sa += smallest 35 | } 36 | 37 | puts "Total square feet is #{total}" 38 | end 39 | 40 | run 41 | -------------------------------------------------------------------------------- /day04/p1a.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | // By Garrett Greenwood 3 | // Dec 2015 4 | // electricexploits.net 5 | 6 | var fs = require('fs'); 7 | var crypto = require('crypto'); 8 | 9 | fs.readFile(process.argv[2], 'utf8', function(err, data) { 10 | if(err) { 11 | console.log("Error reading file"); 12 | return; 13 | } 14 | 15 | var md5 = crypto.createHash('md5'); 16 | 17 | input = data.split('\n')[0]; // Trim trailing endline 18 | 19 | for(x = 0; x < 1000000; x++) { 20 | if(x % 1000 == 0) 21 | console.log("Testing hash " + x); 22 | 23 | if(crypto.createHash('md5').update(input + x).digest('hex').slice(0,5) == '00000') { 24 | console.log("Hash found!"); 25 | console.log(x); 26 | return; 27 | } 28 | } 29 | }); 30 | -------------------------------------------------------------------------------- /day04/p2a.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | // By Garrett Greenwood 3 | // Dec 2015 4 | // electricexploits.net 5 | 6 | var fs = require('fs'); 7 | var crypto = require('crypto'); 8 | 9 | fs.readFile(process.argv[2], 'utf8', function(err, data) { 10 | if(err) { 11 | console.log("Error reading file"); 12 | return; 13 | } 14 | 15 | var md5 = crypto.createHash('md5'); 16 | 17 | input = data.split('\n')[0]; // Trim trailing endline 18 | 19 | for(x = 0; x < 1000000000; x++) { 20 | if(x % 100000 == 0) 21 | console.log("Testing hash " + x); 22 | 23 | if(crypto.createHash('md5').update(input + x).digest('hex').slice(0,6) == '000000') { 24 | console.log("Hash found!"); 25 | console.log(x); 26 | return; 27 | } 28 | } 29 | }); 30 | -------------------------------------------------------------------------------- /day09/input: -------------------------------------------------------------------------------- 1 | AlphaCentauri to Snowdin = 66 2 | AlphaCentauri to Tambi = 28 3 | AlphaCentauri to Faerun = 60 4 | AlphaCentauri to Norrath = 34 5 | AlphaCentauri to Straylight = 34 6 | AlphaCentauri to Tristram = 3 7 | AlphaCentauri to Arbre = 108 8 | Snowdin to Tambi = 22 9 | Snowdin to Faerun = 12 10 | Snowdin to Norrath = 91 11 | Snowdin to Straylight = 121 12 | Snowdin to Tristram = 111 13 | Snowdin to Arbre = 71 14 | Tambi to Faerun = 39 15 | Tambi to Norrath = 113 16 | Tambi to Straylight = 130 17 | Tambi to Tristram = 35 18 | Tambi to Arbre = 40 19 | Faerun to Norrath = 63 20 | Faerun to Straylight = 21 21 | Faerun to Tristram = 57 22 | Faerun to Arbre = 83 23 | Norrath to Straylight = 9 24 | Norrath to Tristram = 50 25 | Norrath to Arbre = 60 26 | Straylight to Tristram = 27 27 | Straylight to Arbre = 81 28 | Tristram to Arbre = 90 29 | -------------------------------------------------------------------------------- /day09/inputb: -------------------------------------------------------------------------------- 1 | Faerun to Tristram = 65 2 | Faerun to Tambi = 129 3 | Faerun to Norrath = 144 4 | Faerun to Snowdin = 71 5 | Faerun to Straylight = 137 6 | Faerun to AlphaCentauri = 3 7 | Faerun to Arbre = 149 8 | Tristram to Tambi = 63 9 | Tristram to Norrath = 4 10 | Tristram to Snowdin = 105 11 | Tristram to Straylight = 125 12 | Tristram to AlphaCentauri = 55 13 | Tristram to Arbre = 14 14 | Tambi to Norrath = 68 15 | Tambi to Snowdin = 52 16 | Tambi to Straylight = 65 17 | Tambi to AlphaCentauri = 22 18 | Tambi to Arbre = 143 19 | Norrath to Snowdin = 8 20 | Norrath to Straylight = 23 21 | Norrath to AlphaCentauri = 136 22 | Norrath to Arbre = 115 23 | Snowdin to Straylight = 101 24 | Snowdin to AlphaCentauri = 84 25 | Snowdin to Arbre = 96 26 | Straylight to AlphaCentauri = 107 27 | Straylight to Arbre = 14 28 | AlphaCentauri to Arbre = 46 29 | -------------------------------------------------------------------------------- /day02/p2a.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | // By Garrett Greenwood 3 | // Dec 2015 4 | // electricexploits.net 5 | 6 | var fs = require('fs'); 7 | 8 | function getNums(line) { 9 | return line.split('x').map(function(x) { 10 | return parseInt(x, 10); 11 | }).sort(function(a, b) { 12 | return a - b; 13 | }); 14 | } 15 | 16 | fs.readFile(process.argv[2], 'utf8', function(err, data) { 17 | if(err) { 18 | console.log("Error reading file"); 19 | return; 20 | } 21 | lines = data.split("\n").slice(0,1000); // Cut the last newline out 22 | 23 | total = 0; 24 | 25 | for(var i = 0; i < lines.length; i++) { 26 | line = lines[i]; 27 | nums = getNums(line); 28 | total += 2 * (nums[0] + nums[1]) + (nums[0] * nums[1] * nums[2]); 29 | } 30 | console.log(total); 31 | }); 32 | -------------------------------------------------------------------------------- /day03/p1a.hs: -------------------------------------------------------------------------------- 1 | {-# Language BangPatterns #-} 2 | 3 | import Data.List (group, scanl, sort, transpose) 4 | import Data.List.Split (chunksOf) 5 | 6 | housesWithGroup :: Int -> String -> Int 7 | housesWithGroup n = length . uniques . concat . map movePath . everyN n 8 | 9 | housesHit :: String -> Int 10 | housesHit = length . uniques . movePath 11 | 12 | movePath :: String -> [(Int, Int)] 13 | movePath = scanl move (0, 0) 14 | 15 | move :: (Int, Int) -> Char -> (Int, Int) 16 | move (!x, !y) '<' = (x - 1, y) 17 | move (!x, !y) '>' = (x + 1, y) 18 | move (!x, !y) '^' = (x, y - 1) 19 | move (!x, !y) 'v' = (x, y + 1) 20 | move (!x, !y) _ = (x, y) 21 | 22 | everyN :: Int -> [a] -> [[a]] 23 | everyN n = transpose . chunksOf n 24 | 25 | uniques :: (Eq a, Ord a) => [a] -> [a] 26 | uniques = map head . group . sort 27 | 28 | main = interact $ show . housesHit 29 | -------------------------------------------------------------------------------- /day03/p2a.hs: -------------------------------------------------------------------------------- 1 | {-# Language BangPatterns #-} 2 | 3 | import Data.List (group, scanl, sort, transpose) 4 | import Data.List.Split (chunksOf) 5 | 6 | housesWithGroup :: Int -> String -> Int 7 | housesWithGroup n = length . uniques . concat . map movePath . everyN n 8 | 9 | housesHit :: String -> Int 10 | housesHit = length . uniques . movePath 11 | 12 | movePath :: String -> [(Int, Int)] 13 | movePath = scanl move (0, 0) 14 | 15 | move :: (Int, Int) -> Char -> (Int, Int) 16 | move (!x, !y) '<' = (x - 1, y) 17 | move (!x, !y) '>' = (x + 1, y) 18 | move (!x, !y) '^' = (x, y - 1) 19 | move (!x, !y) 'v' = (x, y + 1) 20 | move (!x, !y) _ = (x, y) 21 | 22 | everyN :: Int -> [a] -> [[a]] 23 | everyN n = transpose . chunksOf n 24 | 25 | uniques :: (Eq a, Ord a) => [a] -> [a] 26 | uniques = map head . group . sort 27 | 28 | main = interact $ show . housesWithGroup 2 29 | -------------------------------------------------------------------------------- /day08/p2a.ex: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env elixir 2 | 3 | # By: Steven Critchfield 4 | # https://github.com/critch 5 | 6 | defmodule Advent8p2 do 7 | def calculate do 8 | [ wc, hwc] = File.stream!("input") |> 9 | Stream.map(fn(x)-> String.strip(x) end) |> 10 | Enum.reduce( [0,0], fn(x, acc) -> tweak(x,acc) end) 11 | IO.inspect([wc,hwc]) 12 | hwc - wc 13 | end 14 | 15 | def tweak(x, acc) do 16 | strlen = byte_size(x) 17 | str = Regex.replace(~r/(\\x[0-9a-f][0-9a-f]|\\\"|\\\\)/, x, fn(z) -> lookup(z) end) 18 | [strlen + Enum.at(acc,0), byte_size(str) + 4 + Enum.at(acc,1)] 19 | end 20 | def lookup(z) do 21 | cond do 22 | "\\\"" == z -> "!!!!" 23 | "\\\\" == z -> "!!!!" 24 | true -> "!!!!!" 25 | end 26 | end 27 | end 28 | 29 | IO.puts "Difference in strings is: " <> Integer.to_string(Advent8p2.calculate) 30 | -------------------------------------------------------------------------------- /day02/p1a.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | // By Garrett Greenwood 3 | // Dec 2015 4 | // electricexploits.net 5 | 6 | var fs = require('fs'); 7 | 8 | function getNums(line) { 9 | return line.split('x').map(function(x) { 10 | return parseInt(x, 10); 11 | }).sort(function(a, b) { 12 | return a - b; 13 | }); 14 | } 15 | 16 | fs.readFile(process.argv[2], 'utf8', function(err, data) { 17 | if(err) { 18 | console.log("Error reading file"); 19 | return; 20 | } 21 | lines = data.split("\n").slice(0,1000); // Cut the last newline out 22 | 23 | total = 0; 24 | 25 | for(var i = 0; i < lines.length; i++) { 26 | line = lines[i]; 27 | nums = getNums(line); 28 | total += 2 * (nums[0] * nums[1] + nums[1] * nums[2] + nums[0] * nums[2]) + (nums[0] * nums[1]); 29 | } 30 | console.log(total); 31 | }); 32 | -------------------------------------------------------------------------------- /day04/p2a.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #define BUFFER 80 5 | 6 | char HashComplies(unsigned char*, unsigned long); 7 | 8 | int main(void) 9 | { 10 | char str[BUFFER]; 11 | char curStr[BUFFER]; 12 | unsigned char curLen = 0; 13 | unsigned long i = 1; 14 | 15 | printf("Enter key: "); 16 | fgets(str, BUFFER, stdin); 17 | strtok(str, "\n"); 18 | while(1) { 19 | curLen = snprintf(curStr, BUFFER, "%s%lu", str, i); 20 | if (!HashComplies((unsigned char *)curStr, curLen)) { 21 | i++; 22 | } else { 23 | break; 24 | } 25 | } 26 | printf("First successful string: %s with %lu\n", curStr, i); 27 | return 0; 28 | } 29 | 30 | char HashComplies(unsigned char *str, unsigned long len) 31 | { 32 | unsigned char hash[MD5_DIGEST_LENGTH]; 33 | MD5(str, len, hash); 34 | return !hash[0] && !hash[1] && !hash[2]; 35 | } 36 | -------------------------------------------------------------------------------- /day12/p1a.rs: -------------------------------------------------------------------------------- 1 | //! This file is in the [cargo-script][1] format. 2 | //! 3 | //! [1]: https://github.com/DanielKeep/cargo-script 4 | //! 5 | //! ```cargo 6 | //! [dependencies] 7 | //! itertools = "^0.4" 8 | //! ``` 9 | 10 | #![feature(io, iter_arith)] 11 | 12 | #[macro_use] 13 | extern crate itertools; 14 | 15 | use itertools::Itertools; 16 | 17 | use std::io::{self, Read}; 18 | 19 | fn main() { 20 | let stdin = io::stdin(); 21 | let stdin = stdin.lock(); 22 | 23 | let res = stdin.chars() 24 | .map(|c| c.expect("reading from stdin should succeed")) 25 | .group_by_lazy(|c| *c == '-' || c.is_digit(10)).into_iter() 26 | .filter_map(|(like_num, item)| if like_num { Some(item) } else { None }) 27 | .filter_map(|s| s.collect::().parse::().ok()) 28 | .sum::(); 29 | 30 | println!("Sum: {}", res); 31 | } 32 | -------------------------------------------------------------------------------- /day04/p1a.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #define BUFFER 80 5 | 6 | char HashComplies(unsigned char*, unsigned long); 7 | 8 | int main(void) 9 | { 10 | char str[BUFFER]; 11 | char curStr[BUFFER]; 12 | unsigned char curLen = 0; 13 | unsigned long i = 1; 14 | 15 | printf("Enter key: "); 16 | fgets(str, BUFFER, stdin); 17 | strtok(str, "\n"); 18 | while(1) { 19 | curLen = snprintf(curStr, BUFFER, "%s%lu", str, i); 20 | if (!HashComplies((unsigned char *)curStr, curLen)) { 21 | i++; 22 | } else { 23 | break; 24 | } 25 | } 26 | printf("First successful string: %s with %lu\n", curStr, i); 27 | return 0; 28 | } 29 | 30 | char HashComplies(unsigned char *str, unsigned long len) 31 | { 32 | unsigned char hash[MD5_DIGEST_LENGTH]; 33 | MD5(str, len, hash); 34 | return !hash[0] && !hash[1] && !(hash[2] >> 4); 35 | } 36 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ### Advent Of Code solutions 2 | 3 | Got a solution? Put it in a pull request! I'll accept it so long as it's 4 | possibly a solution. 5 | 6 | Got a code critique? Same deal. Make your edits in a pull request and see what 7 | happens. 8 | 9 | Happy coding. 10 | 11 | ##### Naming convention 12 | The 1 or 2 in the name depends on part 1 or part 2. 13 | - p[1-2][a-z].[ext] - the code file. ext is c for C, cpp for C++, sh for POSIX sh... 14 | [a-z] are to differentiate between different solutions in the same 15 | language. 16 | - input[a-z]? - the input provided by the problem. Not all the inputs are the 17 | same. 18 | - p[1-2] - compiled binary. Not to be included in the repo, as per gitignore. 19 | 20 | ##### Disclaimer 21 | This repository and this organization are not in any way linked to 22 | [adventofcode.com](http://adventofcode.com/) except through sharing of a name. 23 | -------------------------------------------------------------------------------- /day08/p1a.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #define BUFFER 240 5 | 6 | unsigned char Count(char *); 7 | 8 | int main(void) 9 | { 10 | char input[BUFFER]; 11 | unsigned int str[2]; 12 | unsigned long sum = 0; 13 | while((fgets(input, BUFFER, stdin))) { 14 | if ((str[0] = strlen(input)-1)) { 15 | str[1] = Count(input); 16 | printf("strFull: %u, strPrint: %u\n", str[0], str[1]); 17 | sum += str[0] - str[1]; 18 | } 19 | } 20 | printf("Sum: %lu\n", sum); 21 | return 0; 22 | } 23 | 24 | unsigned char Count(char *in) 25 | { 26 | int i; 27 | unsigned char sum = 0; 28 | for (i = 1; i < strlen(in)-2; i++) { 29 | if (in[i] == '\\') { 30 | switch (in[i+1]) { 31 | case '\\': 32 | case '"': 33 | i++; 34 | break; 35 | case 'x': 36 | if (in[i+3]) { 37 | i+= 3; 38 | } 39 | } 40 | } 41 | sum++; 42 | } 43 | return sum; 44 | } 45 | -------------------------------------------------------------------------------- /day01/p2a.java: -------------------------------------------------------------------------------- 1 | package adventofcode; 2 | 3 | import java.io.File; 4 | import java.io.FileNotFoundException; 5 | import java.util.Scanner; 6 | 7 | public class p2a { 8 | 9 | public static int move(String s){ 10 | int total = 0; 11 | char[] characters = s.toCharArray(); 12 | for(int i = 0; i < characters.length; i++){ 13 | if(characters[i] == '('){ 14 | total++; 15 | } 16 | else{ 17 | total--; 18 | if(total < 0) { 19 | return i + 1; 20 | } 21 | } 22 | } 23 | return -1; 24 | } 25 | 26 | public static void main(String[] args) throws FileNotFoundException { 27 | Scanner s = new Scanner(new File("input")); 28 | 29 | System.out.println("Santa moves into the basement at index " + move(s.next()) + "."); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /day05/p1a.ex: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env elixir 2 | 3 | # By: Steven Critchfield 4 | # https://github.com/critch 5 | 6 | defmodule Advent5p1 do 7 | def calculate do 8 | File.stream!("input") |> 9 | Stream.map(fn(x)-> String.strip(x) end) |> 10 | Stream.filter(fn(x) -> bad_combo?(x) end) |> 11 | Stream.filter(fn(x) -> three_vowels(x) end) |> 12 | Stream.filter(fn(x) -> doubles(x) end) |> 13 | Enum.count 14 | end 15 | 16 | def bad_combo?(x), do: !String.contains?(x,["ab","cd","pq","xy"]) 17 | def doubles(x), do: Regex.match?(~r/([a-z])\1/, x) 18 | def is_a_vowel(x), do: Regex.match?(~r/(a|e|i|o|u)/, x) 19 | def three_or_more?(x), do: x>2 20 | 21 | def three_vowels(x) do 22 | String.codepoints(x) |> 23 | Stream.filter(fn(x)-> is_a_vowel(x) end) |> 24 | Enum.count |> 25 | three_or_more? 26 | end 27 | 28 | end 29 | 30 | IO.puts "Nice String count: " <> Integer.to_string(Advent5p1.calculate) 31 | -------------------------------------------------------------------------------- /day04/p1a.rs: -------------------------------------------------------------------------------- 1 | //! This file is in the [cargo-script][1] format. 2 | //! 3 | //! [1]: https://github.com/DanielKeep/cargo-script 4 | //! 5 | //! ```cargo 6 | //! [dependencies] 7 | //! rust-crypto = "^0.2" 8 | //! ``` 9 | 10 | extern crate crypto; 11 | 12 | use crypto::digest::Digest; 13 | use crypto::md5::Md5; 14 | 15 | use std::io::{self, Read}; 16 | 17 | fn main() { 18 | let stdin = io::stdin(); 19 | let stdin = stdin.lock(); 20 | let input = stdin.bytes() 21 | .map(|b| b.expect("reading from stdin should succeed")) 22 | .collect::>(); 23 | 24 | let mut md5 = Md5::new(); 25 | 26 | for i in 0.. { 27 | let i_repr = i.to_string(); 28 | 29 | md5.reset(); 30 | md5.input(&input[..]); 31 | md5.input(i_repr.as_bytes()); 32 | 33 | let hex = md5.result_str(); 34 | if &hex[0..5] == "00000" { 35 | println!("Number: {}", i); 36 | return; 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /day04/p2a.rs: -------------------------------------------------------------------------------- 1 | //! This file is in the [cargo-script][1] format. 2 | //! 3 | //! [1]: https://github.com/DanielKeep/cargo-script 4 | //! 5 | //! ```cargo 6 | //! [dependencies] 7 | //! rust-crypto = "^0.2" 8 | //! ``` 9 | 10 | extern crate crypto; 11 | 12 | use crypto::digest::Digest; 13 | use crypto::md5::Md5; 14 | 15 | use std::io::{self, Read}; 16 | 17 | fn main() { 18 | let stdin = io::stdin(); 19 | let stdin = stdin.lock(); 20 | let input = stdin.bytes() 21 | .map(|b| b.expect("reading from stdin should succeed")) 22 | .collect::>(); 23 | 24 | let mut md5 = Md5::new(); 25 | 26 | for i in 0.. { 27 | let i_repr = i.to_string(); 28 | 29 | md5.reset(); 30 | md5.input(&input[..]); 31 | md5.input(i_repr.as_bytes()); 32 | 33 | let hex = md5.result_str(); 34 | if &hex[0..6] == "000000" { 35 | println!("Number: {}", i); 36 | return; 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /day17/p1a.rs: -------------------------------------------------------------------------------- 1 | use std::io::{self, BufRead}; 2 | 3 | fn combinations(containers: &[i64], remaining: i64) -> i64 { 4 | let mut num_found = 0; 5 | 6 | for i in 0..containers.len() { 7 | if containers[i] == remaining { 8 | num_found += 1; 9 | } else if containers[i] < remaining { 10 | num_found += combinations(&containers[i + 1..], remaining - containers[i]); 11 | } 12 | } 13 | 14 | num_found 15 | } 16 | 17 | fn main() { 18 | let stdin = io::stdin(); 19 | let stdin = stdin.lock(); 20 | 21 | let mut container_sizes = Vec::new(); 22 | for line in stdin.lines() { 23 | container_sizes.push(line 24 | .expect("reading from stdin should succeed") 25 | .parse() 26 | .expect("the input should be correctly formatted")); 27 | } 28 | 29 | let num_ways = combinations(&container_sizes, 150); 30 | println!("# of ways: {}", num_ways); 31 | } 32 | -------------------------------------------------------------------------------- /day20/p2a.rs: -------------------------------------------------------------------------------- 1 | #![feature(io)] 2 | 3 | use std::collections::HashSet; 4 | use std::io::{self, Read}; 5 | 6 | fn main() { 7 | let stdin = io::stdin(); 8 | let stdin = stdin.lock(); 9 | 10 | let input = stdin.chars() 11 | .map(|c| c.expect("reading from stdin should succeed")) 12 | .collect::().parse::() 13 | .expect("the input should be properly formatted"); 14 | 15 | let mut minimum = 0; 16 | for i in 1.. { 17 | let mut seen = HashSet::new(); 18 | let mut sum = 0; 19 | for j in 1..((i as f64).sqrt() as u64 + 2) { 20 | if i % j == 0 { 21 | if i / j <= 50 && !seen.contains(&j) { sum += j * 11; seen.insert(j); } 22 | if j <= 50 && !seen.contains(&(i / j)) { sum += (i / j) * 11; seen.insert(i / j); } 23 | } 24 | } 25 | 26 | if sum >= input { 27 | minimum = i; 28 | break; 29 | } 30 | } 31 | 32 | println!("Minimum: {}", minimum); 33 | } 34 | -------------------------------------------------------------------------------- /day02/p1a.rs: -------------------------------------------------------------------------------- 1 | use std::cmp::min; 2 | use std::io::{self, BufRead}; 3 | 4 | fn main() { 5 | let stdin = io::stdin(); 6 | let stdin = stdin.lock(); 7 | 8 | let mut total_area = 0; 9 | 10 | for line in stdin.lines() { 11 | let line = line.expect("reading from stdin should succeed"); 12 | 13 | let nums = line.split('x') 14 | .map(|s| s.parse() 15 | .expect("the input should be correctly formatted")) 16 | .collect::>(); 17 | 18 | if nums.len() != 3 { 19 | panic!("the input should be correctly formatted") 20 | } 21 | 22 | let l = nums[0]; 23 | let w = nums[1]; 24 | let h = nums[2]; 25 | 26 | let lw = l * w; 27 | let wh = w * h; 28 | let hl = h * l; 29 | 30 | let surface_area = 2 * (lw + wh + hl); 31 | let min_side = min(lw, min(wh, hl)); 32 | 33 | total_area += surface_area + min_side; 34 | } 35 | 36 | println!("Total area: {}", total_area); 37 | } 38 | -------------------------------------------------------------------------------- /day05/p2a.rs: -------------------------------------------------------------------------------- 1 | use std::io::{self, BufRead}; 2 | 3 | fn main() { 4 | let stdin = io::stdin(); 5 | let stdin = stdin.lock(); 6 | 7 | let mut nice_strings = 0; 8 | 9 | for line in stdin.lines() { 10 | let line = line.expect("reading from stdin should succeed"); 11 | 12 | let has_repeat = line.as_bytes() 13 | .windows(2) 14 | .enumerate() 15 | .any(|(i, window)| { 16 | line.as_bytes() 17 | .windows(2) 18 | .enumerate() 19 | .any(|(j, other_window)| { 20 | (i as i64 - j as i64).abs() > 1 21 | && window == other_window 22 | }) 23 | }); 24 | let has_aba = line.chars() 25 | .zip(line.chars().skip(2)) 26 | .any(|(a, b)| a == b); 27 | 28 | if has_repeat && has_aba { 29 | nice_strings += 1; 30 | } 31 | } 32 | 33 | println!("Nice: {}", nice_strings); 34 | } 35 | -------------------------------------------------------------------------------- /day08/p2a.java: -------------------------------------------------------------------------------- 1 | package adventofcode; 2 | 3 | import java.io.File; 4 | import java.io.FileNotFoundException; 5 | import java.util.Scanner; 6 | 7 | public class p2a { 8 | 9 | public static int evaluate(String s){ 10 | char[] charArray = s.toCharArray(); 11 | int add = 2; 12 | for(int i = 0; i < charArray.length; i++){ 13 | if(charArray[i] == '\\' || charArray[i] == '\"'){ 14 | add++; 15 | } 16 | } 17 | 18 | return s.length() + add; 19 | } 20 | 21 | public static void main(String[] args) throws FileNotFoundException { 22 | 23 | int new_string = 0; 24 | int str_length = 0; 25 | 26 | Scanner s = new Scanner(new File("input")); 27 | 28 | while(s.hasNext()){ 29 | String str = s.nextLine(); 30 | new_string += evaluate(str); 31 | str_length += str.length(); 32 | } 33 | 34 | System.out.println("The difference is " + (new_string - str_length) + "."); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /day20/p1a.rs: -------------------------------------------------------------------------------- 1 | #![feature(io)] 2 | 3 | use std::collections::HashSet; 4 | use std::io::{self, Read}; 5 | 6 | fn main() { 7 | let stdin = io::stdin(); 8 | let stdin = stdin.lock(); 9 | 10 | let input = stdin.chars() 11 | .map(|c| c.expect("reading from stdin should succeed")) 12 | .collect::().parse::() 13 | .expect("the input should be properly formatted"); 14 | 15 | let expected_sum = input / 10; 16 | 17 | let mut minimum = 0; 18 | for i in 1.. { 19 | let mut seen = HashSet::new(); 20 | let mut sum = 0; 21 | for j in 1..((i as f64).sqrt() as u64 + 2) { 22 | if i % j == 0 { 23 | if !seen.contains(&j) { sum += j; seen.insert(j); } 24 | if !seen.contains(&(i / j)) { sum += i / j; seen.insert(i / j); } 25 | } 26 | } 27 | 28 | if sum >= expected_sum { 29 | minimum = i; 30 | break; 31 | } 32 | } 33 | 34 | println!("Minimum: {}", minimum); 35 | } 36 | -------------------------------------------------------------------------------- /day10/p1b.rs: -------------------------------------------------------------------------------- 1 | //! This file is in the [cargo-script][1] format. 2 | //! 3 | //! [1]: https://github.com/DanielKeep/cargo-script 4 | //! 5 | //! ```cargo 6 | //! [dependencies] 7 | //! itertools = "^0.4" 8 | //! ``` 9 | 10 | #![feature(io)] 11 | 12 | #[macro_use] 13 | extern crate itertools; 14 | 15 | use itertools::Itertools; 16 | 17 | use std::io::{self, Read}; 18 | 19 | fn rle(inp: Vec) -> Vec { 20 | let mut res = Vec::new(); 21 | 22 | for (key, group) in inp.into_iter().group_by_lazy(|i| *i).into_iter() { 23 | res.push(group.fold(0, |l, _| l + 1)); 24 | res.push(key); 25 | } 26 | 27 | res 28 | } 29 | 30 | fn main() { 31 | let stdin = io::stdin(); 32 | let stdin = stdin.lock(); 33 | let mut current_rle = stdin.chars() 34 | .map(|c| c.expect("reading from stdin should succeed") as u8 - '0' as u8) 35 | .collect::>(); 36 | 37 | for _ in 0..40 { 38 | current_rle = rle(current_rle); 39 | } 40 | 41 | println!("Length: {}", current_rle.len()); 42 | } 43 | -------------------------------------------------------------------------------- /day10/p2b.rs: -------------------------------------------------------------------------------- 1 | //! This file is in the [cargo-script][1] format. 2 | //! 3 | //! [1]: https://github.com/DanielKeep/cargo-script 4 | //! 5 | //! ```cargo 6 | //! [dependencies] 7 | //! itertools = "^0.4" 8 | //! ``` 9 | 10 | #![feature(io)] 11 | 12 | #[macro_use] 13 | extern crate itertools; 14 | 15 | use itertools::Itertools; 16 | 17 | use std::io::{self, Read}; 18 | 19 | fn rle(inp: Vec) -> Vec { 20 | let mut res = Vec::new(); 21 | 22 | for (key, group) in inp.into_iter().group_by_lazy(|i| *i).into_iter() { 23 | res.push(group.fold(0, |l, _| l + 1)); 24 | res.push(key); 25 | } 26 | 27 | res 28 | } 29 | 30 | fn main() { 31 | let stdin = io::stdin(); 32 | let stdin = stdin.lock(); 33 | let mut current_rle = stdin.chars() 34 | .map(|c| c.expect("reading from stdin should succeed") as u8 - '0' as u8) 35 | .collect::>(); 36 | 37 | for _ in 0..50 { 38 | current_rle = rle(current_rle); 39 | } 40 | 41 | println!("Length: {}", current_rle.len()); 42 | } 43 | -------------------------------------------------------------------------------- /day05/p1a.rs: -------------------------------------------------------------------------------- 1 | use std::io::{self, BufRead}; 2 | 3 | fn is_vowel(c: char) -> bool { 4 | c == 'a' || c == 'e' || c == 'i' || c == 'o' || c == 'u' 5 | } 6 | fn contains_bad_sequence(s: &str) -> bool { 7 | s.contains("ab") || s.contains("cd") || s.contains("pq") || s.contains("xy") 8 | } 9 | 10 | fn main() { 11 | let stdin = io::stdin(); 12 | let stdin = stdin.lock(); 13 | 14 | let mut nice_strings = 0; 15 | 16 | for line in stdin.lines() { 17 | let line = line.expect("reading from stdin should succeed"); 18 | 19 | let has_three_vowels = line.chars() 20 | .fold(0, |res, c| if is_vowel(c) { res + 1 } else { res }) >= 3; 21 | let has_double_appearance = line.chars() 22 | .zip(line.chars().skip(1)) 23 | .any(|(a, b)| a == b); 24 | let no_bad_sequences = !contains_bad_sequence(&line); 25 | 26 | if has_three_vowels && has_double_appearance && no_bad_sequences { 27 | nice_strings += 1; 28 | } 29 | } 30 | 31 | println!("Nice: {}", nice_strings); 32 | } 33 | -------------------------------------------------------------------------------- /day10/p1a.ex: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env elixir 2 | 3 | # by: steven critchfield 4 | # https://github.com/critch 5 | 6 | defmodule Advent10p1 do 7 | def calculate do 8 | x = File.stream!("input") |> Enum.map(fn(x) -> String.strip(x) end) |> Enum.fetch!(-1) 9 | iter = 40 10 | 11 | String.length(look_and_say(x,iter)) 12 | end 13 | 14 | def look_and_say(x,0) do 15 | x 16 | end 17 | def look_and_say(x,iter) do 18 | # recursion 19 | z = l_s(x) 20 | look_and_say(z,iter - 1) 21 | end 22 | def l_s(x) do 23 | val = String.codepoints(x) |> 24 | Enum.reduce({"",0,""}, fn(z, acc) -> l_s_r(z,acc) end) 25 | 26 | # flush final value 27 | l_s_r(" ", val) |> 28 | elem(2) 29 | end 30 | def l_s_r(z,acc) do 31 | cond do 32 | elem(acc,0) == "" -> { z, 1, "" } 33 | elem(acc,0) == z -> { z, elem(acc,1) + 1, elem(acc,2) } 34 | true -> { z, 1, elem(acc,2) <> Integer.to_string(elem(acc,1)) <> elem(acc,0) } 35 | end 36 | end 37 | end 38 | 39 | IO.puts "String length: " <> Integer.to_string(Advent10p1.calculate) 40 | -------------------------------------------------------------------------------- /day10/p2a.ex: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env elixir 2 | 3 | # by: steven critchfield 4 | # https://github.com/critch 5 | 6 | defmodule Advent10p2 do 7 | def calculate do 8 | x = File.stream!("input") |> Enum.map(fn(x) -> String.strip(x) end) |> Enum.fetch!(-1) 9 | iter = 50 10 | 11 | String.length(look_and_say(x,iter)) 12 | end 13 | 14 | def look_and_say(x,0) do 15 | x 16 | end 17 | def look_and_say(x,iter) do 18 | # recursion 19 | z = l_s(x) 20 | look_and_say(z,iter - 1) 21 | end 22 | def l_s(x) do 23 | val = String.codepoints(x) |> 24 | Enum.reduce({"",0,""}, fn(z, acc) -> l_s_r(z,acc) end) 25 | 26 | # flush final value 27 | l_s_r(" ", val) |> 28 | elem(2) 29 | end 30 | def l_s_r(z,acc) do 31 | cond do 32 | elem(acc,0) == "" -> { z, 1, "" } 33 | elem(acc,0) == z -> { z, elem(acc,1) + 1, elem(acc,2) } 34 | true -> { z, 1, elem(acc,2) <> Integer.to_string(elem(acc,1)) <> elem(acc,0) } 35 | end 36 | end 37 | end 38 | 39 | IO.puts "String length: " <> Integer.to_string(Advent10p2.calculate) 40 | -------------------------------------------------------------------------------- /day03/p2a.rb: -------------------------------------------------------------------------------- 1 | def run 2 | file = File.open("input1", "rb").read 3 | total = 0 4 | santa = [] 5 | robosanta = [] 6 | sa = sb = ra = rb = 0 7 | 8 | issanta = true 9 | 10 | file.split(//).each { |c| 11 | case c 12 | when '^' 13 | sa += 1 if issanta 14 | ra += 1 if !issanta 15 | when '<' 16 | sb += 1 if issanta 17 | rb += 1 if !issanta 18 | when 'v' 19 | sa -= 1 if issanta 20 | ra -= 1 if !issanta 21 | when '>' 22 | sb -= 1 if issanta 23 | rb -= 1 if !issanta 24 | else 25 | break 26 | end 27 | 28 | if issanta 29 | hash = {"sa" => sa, "sb" => sb} 30 | if !santa.include? hash and !robosanta.include? hash 31 | total += 1 32 | santa << hash 33 | end 34 | else 35 | hash = {"sa" => ra, "sb" => rb} 36 | if !santa.include? hash and !robosanta.include? hash 37 | total += 1 38 | robosanta << hash 39 | end 40 | end 41 | 42 | issanta = !issanta 43 | } 44 | 45 | puts "#{total} houses received more than 1 present" 46 | end 47 | 48 | run 49 | -------------------------------------------------------------------------------- /day02/p2a.rs: -------------------------------------------------------------------------------- 1 | use std::cmp::min; 2 | use std::io::{self, BufRead}; 3 | 4 | fn main() { 5 | let stdin = io::stdin(); 6 | let stdin = stdin.lock(); 7 | 8 | let mut total_length = 0; 9 | 10 | for line in stdin.lines() { 11 | let line = line.expect("reading from stdin should succeed"); 12 | 13 | let nums = line.split('x') 14 | .map(|s| s.parse() 15 | .expect("the input should be correctly formatted")) 16 | .collect::>(); 17 | 18 | if nums.len() != 3 { 19 | panic!("the input should be correctly formatted") 20 | } 21 | 22 | let l = nums[0]; 23 | let w = nums[1]; 24 | let h = nums[2]; 25 | 26 | let top_perimeter = 2 * (l + w); 27 | let front_perimeter = 2 * (w + h); 28 | let side_perimeter = 2 * (h + l); 29 | 30 | let min_perimeter = min(top_perimeter, min(front_perimeter, side_perimeter)); 31 | let bow_size = l * w * h; 32 | 33 | total_length += min_perimeter + bow_size; 34 | } 35 | 36 | println!("Total length: {}", total_length); 37 | } 38 | -------------------------------------------------------------------------------- /day08/p1a.rs: -------------------------------------------------------------------------------- 1 | use std::io::{self, BufRead}; 2 | 3 | fn parse_line(line: &str) -> usize { 4 | let line = &line[1..line.len() - 1]; 5 | 6 | let mut num_chars = 0; 7 | let mut is_escape_seq = false; 8 | let mut is_hex_escape = 0; 9 | for c in line.chars() { 10 | if is_escape_seq { 11 | is_escape_seq = false; 12 | 13 | if c == 'x' { 14 | is_hex_escape = 2; 15 | } 16 | } else if is_hex_escape > 0 { 17 | is_hex_escape -= 1; 18 | } else { 19 | is_escape_seq = c == '\\'; 20 | num_chars += 1; 21 | } 22 | } 23 | 24 | num_chars 25 | } 26 | 27 | fn main() { 28 | let stdin = io::stdin(); 29 | let stdin = stdin.lock(); 30 | 31 | let mut chars_read = 0; 32 | let mut memory_consumed = 0; 33 | 34 | for line in stdin.lines() { 35 | let line = line.expect("reading from stdin should succeed"); 36 | 37 | chars_read += line.len(); 38 | memory_consumed += parse_line(&line); 39 | } 40 | 41 | println!("Memory: {}", chars_read - memory_consumed); 42 | } 43 | -------------------------------------------------------------------------------- /day12/p1a.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | char *AddToString(char *, long long *, char); 6 | 7 | int main(void) 8 | { 9 | long long allocSize = 160; 10 | char *token; 11 | long long sum = 0; 12 | char c; 13 | char *splitOn = " \nabcdefghijklmnopqrstufwxyz\"[]{},:"; 14 | char *buffer = calloc(allocSize, sizeof(char)); 15 | while ((c = fgetc(stdin)) && !feof(stdin)) { 16 | buffer = AddToString(buffer, &allocSize, c); 17 | } 18 | token = strtok(buffer, splitOn); 19 | if (!token) { 20 | return 0; 21 | } 22 | do { 23 | sum += strtol(token, NULL, 10); 24 | } while ((token = strtok(NULL, splitOn))); 25 | printf("Sum: %lld\n", sum); 26 | return 0; 27 | } 28 | 29 | char *AddToString(char *str, long long *strAllocSize, char add) 30 | { 31 | long len = strlen(str); 32 | if (len + 2 >= *strAllocSize) { 33 | *strAllocSize *= 2; 34 | str = realloc(str, sizeof(char)*(*strAllocSize)); 35 | if (!str) { 36 | fprintf(stderr, "Out of memory for string!\n"); 37 | exit(1); 38 | } 39 | } 40 | if (str) { 41 | str[len] = add; 42 | str[len+1] = 0; 43 | } 44 | return str; 45 | } 46 | -------------------------------------------------------------------------------- /day05/p1a.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #define BUFFER 80 4 | 5 | char strNice(char *); 6 | 7 | int main(void) 8 | { 9 | char str[BUFFER]; 10 | unsigned long niceStrs = 0; 11 | 12 | while ((fgets(str, BUFFER, stdin) != NULL)) { 13 | strtok(str, "\n"); 14 | niceStrs += strNice(str); 15 | } 16 | printf("Nice strings: %lu\n", niceStrs); 17 | return 0; 18 | } 19 | 20 | char strNice(char *str) 21 | { 22 | unsigned char i = 0; 23 | char twoInRow = 0; 24 | unsigned char vowels = 0; 25 | unsigned char ruleBroken = 0; 26 | for ( ; i < strlen(str); i++) { 27 | switch (str[i]) { 28 | case 'a': 29 | ruleBroken = str[i+1] == 'b' ? 1 : ruleBroken; 30 | case 'e': 31 | case 'i': 32 | case 'o': 33 | case 'u': 34 | vowels++; 35 | break; 36 | case 'c': 37 | ruleBroken = str[i+1] == 'd' ? 1 : ruleBroken; 38 | break; 39 | case 'p': 40 | ruleBroken = str[i+1] == 'q' ? 1 : ruleBroken; 41 | break; 42 | case 'x': 43 | ruleBroken = str[i+1] == 'y' ? 1 : ruleBroken; 44 | break; 45 | } 46 | twoInRow = str[i] == str[i+1] ? 1 : twoInRow; 47 | } 48 | return twoInRow && vowels >= 3 && !ruleBroken; 49 | } 50 | -------------------------------------------------------------------------------- /day02/p2a.java: -------------------------------------------------------------------------------- 1 | package adventofcode; 2 | 3 | import java.io.File; 4 | import java.io.FileNotFoundException; 5 | import java.util.Scanner; 6 | 7 | public class p2a { 8 | 9 | public static int ribbon(String s){ 10 | String[] dimStrings = s.split("x"); 11 | 12 | int x = Integer.parseInt(dimStrings[0]); 13 | int y = Integer.parseInt(dimStrings[1]); 14 | int z = Integer.parseInt(dimStrings[2]); 15 | 16 | int total = x * y * z; 17 | 18 | if(x >= y && x >= z){ 19 | total += 2*(y + z); 20 | } 21 | else if(y >= z){ 22 | total += 2*(x + z); 23 | } 24 | else{ 25 | total += 2*(x + y); 26 | } 27 | 28 | return total; 29 | } 30 | 31 | public static void main(String[] args) throws FileNotFoundException { 32 | int total = 0; 33 | Scanner s = new Scanner(new File("input")); 34 | 35 | while(s.hasNext()){ 36 | total += ribbon(s.nextLine()); 37 | } 38 | 39 | System.out.println("You will need " + total + " feet of ribbon."); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /day05/p2a.java: -------------------------------------------------------------------------------- 1 | package adventofcode; 2 | 3 | import java.io.File; 4 | import java.io.FileNotFoundException; 5 | import java.util.Scanner; 6 | 7 | public class p2a { 8 | 9 | public static boolean isNice(String s){ 10 | char[] tester = s.toCharArray(); 11 | 12 | boolean sandwich = false; 13 | boolean pairSequence = false; 14 | 15 | for(int i = 0; i < tester.length - 2; i++){ 16 | if(tester[i] == tester[i + 2]){ 17 | sandwich = true; 18 | } 19 | if(s.substring(i + 2).contains(s.substring(i, i + 2))){ 20 | pairSequence = true; 21 | } 22 | } 23 | return sandwich && pairSequence; 24 | } 25 | 26 | public static void main(String[] args) throws FileNotFoundException { 27 | 28 | int count = 0; 29 | 30 | Scanner s = new Scanner(new File("input")); 31 | 32 | while(s.hasNext()){ 33 | if(isNice(s.nextLine())){ 34 | count++; 35 | } 36 | } 37 | 38 | System.out.println("There are " + count + " nice strings."); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /day14/p1a.java: -------------------------------------------------------------------------------- 1 | package adventofcode; 2 | 3 | import java.io.File; 4 | import java.io.FileNotFoundException; 5 | import java.util.Scanner; 6 | 7 | public class p1a { 8 | 9 | public static void main(String[] args) throws FileNotFoundException{ 10 | int distance = 0; 11 | int record = 0; 12 | String input; 13 | int speed, stamina, rest; 14 | String[] params; 15 | Scanner s = new Scanner(new File("input")); 16 | 17 | while(s.hasNext()){ 18 | input = s.nextLine(); 19 | 20 | params = input.split(" "); 21 | 22 | speed = Integer.parseInt(params[3]); 23 | stamina = Integer.parseInt(params[6]); 24 | rest = Integer.parseInt(params[13]); 25 | 26 | distance += (2503 / (stamina + rest)) * speed * stamina; 27 | distance += (2503 % (stamina + rest)) > stamina ? speed * stamina : (2503 % (stamina + rest)) * speed; 28 | 29 | if(distance > record){ 30 | record = distance; 31 | } 32 | 33 | distance = 0; 34 | } 35 | 36 | System.out.println("The maximum distance is " + record +"."); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /day08/p1a.java: -------------------------------------------------------------------------------- 1 | package adventofcode; 2 | 3 | import java.io.File; 4 | import java.io.FileNotFoundException; 5 | import java.util.Scanner; 6 | 7 | public class p1a { 8 | 9 | public static int evaluate(String s){ 10 | char[] charArray = s.toCharArray(); 11 | int subtract = 2; 12 | for(int i = 0; i < charArray.length - 1; i++){ 13 | if(charArray[i] == '\\' && (charArray[i + 1] == '\\' || charArray[i + 1] == '\"')){ 14 | subtract++; 15 | i++; 16 | } 17 | else if(charArray[i] == '\\' && charArray[i + 1] == 'x'){ 18 | subtract += 3; 19 | } 20 | } 21 | 22 | return s.length() - subtract; 23 | } 24 | 25 | public static void main(String[] args) throws FileNotFoundException { 26 | 27 | int code = 0; 28 | int memory = 0; 29 | 30 | Scanner s = new Scanner(new File("input")); 31 | 32 | while(s.hasNext()){ 33 | String str = s.nextLine(); 34 | memory += evaluate(str); 35 | code += str.length(); 36 | } 37 | 38 | System.out.println("The difference is " + (code - memory) + "."); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /day03/p2a.rs: -------------------------------------------------------------------------------- 1 | #![feature(io)] 2 | 3 | use std::collections::HashSet; 4 | use std::io::{self, Read}; 5 | 6 | fn main() { 7 | let stdin = io::stdin(); 8 | let stdin = stdin.lock(); 9 | 10 | let mut visited = HashSet::new(); 11 | visited.insert((0, 0)); 12 | let mut controlling_robot = false; 13 | let mut santa_x = 0; 14 | let mut santa_y = 0; 15 | let mut robot_x = 0; 16 | let mut robot_y = 0; 17 | 18 | for c in stdin.chars() { 19 | match c.expect("reading from stdin should succeed") { 20 | '^' => if controlling_robot { robot_y += 1 } else { santa_y += 1 }, 21 | 'v' => if controlling_robot { robot_y -= 1 } else { santa_y -= 1 }, 22 | '<' => if controlling_robot { robot_x -= 1 } else { santa_x -= 1 }, 23 | '>' => if controlling_robot { robot_x += 1 } else { santa_x += 1 }, 24 | _ => {}, 25 | } 26 | 27 | if controlling_robot { 28 | visited.insert((robot_x, robot_y)); 29 | } else { 30 | visited.insert((santa_x, santa_y)); 31 | } 32 | 33 | controlling_robot = !controlling_robot; 34 | } 35 | 36 | println!("Visited: {}", visited.len()); 37 | } 38 | -------------------------------------------------------------------------------- /day04/p1a.java: -------------------------------------------------------------------------------- 1 | package adventofcode; 2 | 3 | import java.security.MessageDigest; 4 | import java.security.NoSuchAlgorithmException; 5 | import javax.xml.bind.DatatypeConverter; 6 | 7 | public class p1a { 8 | 9 | static MessageDigest md5; 10 | 11 | static{ 12 | try{ 13 | md5 = MessageDigest.getInstance("MD5"); 14 | } 15 | catch(NoSuchAlgorithmException e){ 16 | System.out.println("Apparently MD5 doesn't exist."); 17 | } 18 | } 19 | 20 | public static String hash(String input, int answer){ 21 | 22 | byte[] src = (input + answer).getBytes(); 23 | String hex = DatatypeConverter.printHexBinary(md5.digest(src)); 24 | 25 | return hex; 26 | } 27 | 28 | public static void main(String[] args){ 29 | 30 | int answer = 1; 31 | String hash; 32 | 33 | while(true){ 34 | hash = Solution.hash("ckczppom", answer); 35 | if(hash.startsWith("00000")){ 36 | break; 37 | } 38 | answer++; 39 | } 40 | 41 | System.out.println("The answer is " + answer + ", producing hash " + hash + "."); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /day04/p2a.java: -------------------------------------------------------------------------------- 1 | package adventofcode; 2 | 3 | import java.security.MessageDigest; 4 | import java.security.NoSuchAlgorithmException; 5 | import javax.xml.bind.DatatypeConverter; 6 | 7 | public class p2a { 8 | 9 | static MessageDigest md5; 10 | 11 | static{ 12 | try{ 13 | md5 = MessageDigest.getInstance("MD5"); 14 | } 15 | catch(NoSuchAlgorithmException e){ 16 | System.out.println("Apparently MD5 doesn't exist."); 17 | } 18 | } 19 | 20 | public static String hash(String input, int answer){ 21 | 22 | byte[] src = (input + answer).getBytes(); 23 | String hex = DatatypeConverter.printHexBinary(md5.digest(src)); 24 | 25 | return hex; 26 | } 27 | 28 | public static void main(String[] args){ 29 | 30 | int answer = 1; 31 | String hash; 32 | 33 | while(true){ 34 | hash = Solution.hash("ckczppom", answer); 35 | if(hash.startsWith("000000")){ 36 | break; 37 | } 38 | answer++; 39 | } 40 | 41 | System.out.println("The answer is " + answer + ", producing hash " + hash + "."); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /day16/p1a.ex: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env elixir 2 | 3 | # by: steven critchfield 4 | # https://github.com/critch 5 | 6 | defmodule Advent16p1 do 7 | def calculate do 8 | valid = %{ 9 | "children" => 3, 10 | "cats" => 7, 11 | "samoyeds" => 2, 12 | "pomeranians" => 3, 13 | "akitas" => 0, 14 | "vizslas" => 0, 15 | "goldfish" => 5, 16 | "trees" => 3, 17 | "cars" => 2, 18 | "perfumes" => 1 19 | } 20 | File.stream!("input") |> 21 | Stream.map(fn(x) -> Regex.named_captures( 22 | ~r/Sue (?[0-9]+): (?[a-z]+): (?[0-9]+), (?[a-z]+): (?[0-9]+), (?[a-z]+): (?[0-9]+)/, 23 | x) 24 | end) |> 25 | Stream.filter(fn(x) -> check(x,1,valid) end) |> 26 | Stream.filter(fn(x) -> check(x,2,valid) end) |> 27 | Stream.filter(fn(x) -> check(x,3,valid) end) |> 28 | Enum.fetch!(-1) |> 29 | Map.fetch!("num") 30 | end 31 | 32 | 33 | def check(x,i,valid) do 34 | item = Map.fetch!(x,"i"<>Integer.to_string(i)) 35 | val = Map.fetch!(x,"v"<>Integer.to_string(i)) |> String.to_integer 36 | Map.fetch!(valid, item) == val 37 | end 38 | end 39 | 40 | IO.puts "Matched Sue: " <> Advent16p1.calculate 41 | -------------------------------------------------------------------------------- /day02/p1a.java: -------------------------------------------------------------------------------- 1 | package adventofcode; 2 | 3 | import java.io.File; 4 | import java.io.FileNotFoundException; 5 | import java.util.Scanner; 6 | 7 | public class p1a { 8 | 9 | public static int paper(String s){ 10 | String[] dimStrings = s.split("x"); 11 | 12 | int x = Integer.parseInt(dimStrings[0]); 13 | int y = Integer.parseInt(dimStrings[1]); 14 | int z = Integer.parseInt(dimStrings[2]); 15 | 16 | int dim1 = x * y; 17 | int dim2 = y * z; 18 | int dim3 = x * z; 19 | 20 | int total = 2*dim1 + 2*dim2 + 2*dim3; 21 | 22 | if(dim1 <= dim2 && dim1 <= dim3){ 23 | total += dim1; 24 | } 25 | else if(dim2 <= dim3){ 26 | total += dim2; 27 | } 28 | else{ 29 | total += dim3; 30 | } 31 | 32 | return total; 33 | } 34 | 35 | public static void main(String[] args) throws FileNotFoundException { 36 | int total = 0; 37 | Scanner s = new Scanner(new File("input")); 38 | 39 | while(s.hasNext()){ 40 | total += paper(s.nextLine()); 41 | } 42 | 43 | System.out.println("You will need " + total + " square feet of paper."); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /day19/p1a.rs: -------------------------------------------------------------------------------- 1 | use std::collections::{HashMap, HashSet}; 2 | use std::io::{self, BufRead}; 3 | 4 | fn parse_language(language: &[String]) -> HashMap> { 5 | let mut res = HashMap::new(); 6 | 7 | for item in language.iter() { 8 | let split = item.find(" => ").unwrap(); 9 | res.entry(item[0..split].to_owned()) 10 | .or_insert_with(Vec::new) 11 | .push(item[split + 4..].to_owned()); 12 | } 13 | 14 | res 15 | } 16 | 17 | fn main() { 18 | let stdin = io::stdin(); 19 | let stdin = stdin.lock(); 20 | 21 | let (language, input) = stdin.lines() 22 | .map(|line| line.expect("reading from stdin should succeed")) 23 | .partition::, _>(|line| line.find("=>").is_some()); 24 | let language = parse_language(&language); 25 | let ref input = input[1]; 26 | 27 | let mut seen_items = HashSet::new(); 28 | 29 | for (grapheme, replacements) in language.iter() { 30 | for (idx, _) in input.match_indices(grapheme) { 31 | for replacement in replacements { 32 | seen_items.insert(input[0..idx].to_owned() + replacement + &input[idx + grapheme.len()..]); 33 | } 34 | } 35 | } 36 | 37 | println!("# of ways: {}", seen_items.len()); 38 | } 39 | -------------------------------------------------------------------------------- /day02/p1a.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | unsigned long long CalcSize(unsigned int, unsigned int, unsigned int); 4 | 5 | int main(void) 6 | { 7 | unsigned long long total = 0; 8 | unsigned int dim[3], temp; 9 | char c; 10 | unsigned char i; 11 | temp = dim[0] = dim[1] = dim[2] = 0; 12 | while ((c = fgetc(stdin)) != EOF) { 13 | switch (c) { 14 | case '9': 15 | case '8': 16 | case '7': 17 | case '6': 18 | case '5': 19 | case '4': 20 | case '3': 21 | case '2': 22 | case '1': 23 | case '0': 24 | temp *= 10; 25 | temp += c-'0'; 26 | break; 27 | case 'x': 28 | case '\n': 29 | for (i = 0; dim[i] != 0; i++) { ; } 30 | dim[i] = temp; 31 | temp = 0; 32 | break; 33 | default: 34 | printf("Unknown character: %d\n", c); 35 | break; 36 | } 37 | if (c == '\n') { 38 | total += CalcSize(dim[0], dim[1], dim[2]); 39 | temp = dim[0] = dim[1] = dim[2] = 0; 40 | } 41 | } 42 | printf("Total size: %llu\n", total); 43 | return 0; 44 | } 45 | 46 | unsigned long long CalcSize(unsigned int w, unsigned int l, unsigned int h) 47 | { 48 | unsigned long long a = w*l; 49 | unsigned long long b = w*h; 50 | unsigned long long c = l*h; 51 | unsigned long long retVal = 2*a + 2*b + 2*c; 52 | unsigned long long smallest = a < b ? a : b; 53 | smallest = smallest < c ? smallest : c; 54 | retVal += smallest; 55 | return retVal; 56 | } 57 | -------------------------------------------------------------------------------- /day17/p1a.java: -------------------------------------------------------------------------------- 1 | package adventofcode; 2 | 3 | import java.io.File; 4 | import java.io.FileNotFoundException; 5 | import java.util.Scanner; 6 | 7 | public class p1a { 8 | 9 | static int[] bottles = new int[20]; 10 | static int total; 11 | 12 | public static void calculate(){ 13 | for(int i = 0; i < (int)Math.pow(2, 20); i++){ 14 | String unpadded = Integer.toBinaryString(i); 15 | checkPermutation("00000000000000000000".substring(unpadded.length()) + unpadded); 16 | } 17 | } 18 | 19 | public static void checkPermutation(String s){ 20 | char[] permutation = s.toCharArray(); 21 | int capacity = 0; 22 | 23 | for(int i = 0; i < 20; i++){ 24 | if(permutation[i] == '1'){ 25 | capacity += bottles[i]; 26 | } 27 | } 28 | if(capacity == 150){ 29 | total++; 30 | } 31 | } 32 | 33 | public static void main(String[] args) throws FileNotFoundException { 34 | Scanner s = new Scanner(new File("input")); 35 | 36 | for(int i = 0; i < 20; i++){ 37 | bottles[i] = Integer.parseInt(s.nextLine()); 38 | } 39 | 40 | calculate(); 41 | 42 | System.out.println("There are " + total + " ways to fill the bottles."); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /day02/p2a.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | unsigned long long CalcSize(unsigned int, unsigned int, unsigned int); 4 | 5 | int main(void) 6 | { 7 | unsigned long long total = 0; 8 | unsigned int dim[3], temp; 9 | char c; 10 | unsigned char i; 11 | temp = dim[0] = dim[1] = dim[2] = 0; 12 | while ((c = fgetc(stdin)) != EOF) { 13 | switch (c) { 14 | case '9': 15 | case '8': 16 | case '7': 17 | case '6': 18 | case '5': 19 | case '4': 20 | case '3': 21 | case '2': 22 | case '1': 23 | case '0': 24 | temp *= 10; 25 | temp += c-'0'; 26 | break; 27 | case 'x': 28 | case '\n': 29 | for (i = 0; dim[i] != 0; i++) { ; } 30 | dim[i] = temp; 31 | temp = 0; 32 | break; 33 | default: 34 | printf("Unknown character: %d\n", c); 35 | break; 36 | } 37 | if (c == '\n') { 38 | total += CalcSize(dim[0], dim[1], dim[2]); 39 | temp = dim[0] = dim[1] = dim[2] = 0; 40 | } 41 | } 42 | printf("Total size: %llu\n", total); 43 | return 0; 44 | } 45 | 46 | unsigned long long CalcSize(unsigned int w, unsigned int l, unsigned int h) 47 | { 48 | unsigned long long a = 2*l; 49 | unsigned long long b = 2*h; 50 | unsigned long long c = 2*w; 51 | unsigned long long retVal = w*l*h; 52 | if (a < b) { // Ugh. 53 | retVal += a; 54 | retVal += b < c ? b : c; 55 | } else { 56 | retVal += b; 57 | retVal += a < c ? a : c; 58 | } 59 | return retVal; 60 | } 61 | -------------------------------------------------------------------------------- /day10/p1a.rs: -------------------------------------------------------------------------------- 1 | #![feature(advanced_slice_patterns, io, slice_patterns)] 2 | 3 | use std::io::{self, Read}; 4 | use std::mem::swap; 5 | 6 | fn rle(mut inp: &[u8], storage: &mut Vec) { 7 | storage.clear(); 8 | 9 | while !inp.is_empty() { 10 | match inp { 11 | [ref x, ref y, ref z, rest..] if y == x && z == x => { 12 | storage.push(3); 13 | storage.push(*x); 14 | inp = rest; 15 | }, 16 | [ref x, ref y, rest..] if y == x => { 17 | storage.push(2); 18 | storage.push(*x); 19 | inp = rest; 20 | }, 21 | [ref x, rest..] => { 22 | storage.push(1); 23 | storage.push(*x); 24 | inp = rest; 25 | }, 26 | [] => unreachable!(), 27 | } 28 | } 29 | } 30 | 31 | fn main() { 32 | let stdin = io::stdin(); 33 | let stdin = stdin.lock(); 34 | 35 | // First run, convert the character sequence into an integer sequence 36 | let mut a = stdin.chars() 37 | .map(|c| c.expect("reading from stdin should succeed") as u8 - '0' as u8) 38 | .collect::>(); 39 | let mut b = Vec::new(); 40 | 41 | for _ in 0..40 { 42 | rle(&a, &mut b); 43 | swap(&mut a, &mut b); 44 | } 45 | 46 | println!("Length: {}", a.len()); 47 | } 48 | -------------------------------------------------------------------------------- /day10/p2a.rs: -------------------------------------------------------------------------------- 1 | #![feature(advanced_slice_patterns, io, slice_patterns)] 2 | 3 | use std::io::{self, Read}; 4 | use std::mem::swap; 5 | 6 | fn rle(mut inp: &[u8], storage: &mut Vec) { 7 | storage.clear(); 8 | 9 | while !inp.is_empty() { 10 | match inp { 11 | [ref x, ref y, ref z, rest..] if y == x && z == x => { 12 | storage.push(3); 13 | storage.push(*x); 14 | inp = rest; 15 | }, 16 | [ref x, ref y, rest..] if y == x => { 17 | storage.push(2); 18 | storage.push(*x); 19 | inp = rest; 20 | }, 21 | [ref x, rest..] => { 22 | storage.push(1); 23 | storage.push(*x); 24 | inp = rest; 25 | }, 26 | [] => unreachable!(), 27 | } 28 | } 29 | } 30 | 31 | fn main() { 32 | let stdin = io::stdin(); 33 | let stdin = stdin.lock(); 34 | 35 | // First run, convert the character sequence into an integer sequence 36 | let mut a = stdin.chars() 37 | .map(|c| c.expect("reading from stdin should succeed") as u8 - '0' as u8) 38 | .collect::>(); 39 | let mut b = Vec::new(); 40 | 41 | for _ in 0..50 { 42 | rle(&a, &mut b); 43 | swap(&mut a, &mut b); 44 | } 45 | 46 | println!("Length: {}", a.len()); 47 | } 48 | -------------------------------------------------------------------------------- /day03/p1a.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | // By Garrett Greenwood 3 | // Dec 2015 4 | // electricexploits.net 5 | 6 | var fs = require('fs'); 7 | 8 | function Location(x, y) { 9 | return { 10 | x: x, 11 | y: y, 12 | equals: function(loc) { 13 | return loc.x == this.x & loc.y == this.y; 14 | }, 15 | move: function(dir) { 16 | switch(dir) { 17 | case '^': return new Location(this.x, this.y + 1); 18 | case '>': return new Location(this.x + 1, this.y); 19 | case 'v': return new Location(this.x, this.y - 1); 20 | case '<': return new Location(this.x - 1, this.y); 21 | default: return new Location(0, 0); 22 | } 23 | } 24 | }; 25 | } 26 | 27 | function search(array, loc) { 28 | return array.filter(function(x) { 29 | return loc.equals(x); 30 | }).length; 31 | } 32 | 33 | fs.readFile(process.argv[2], 'utf8', function(err, data) { 34 | if(err) { 35 | console.log("Error reading file"); 36 | return; 37 | } 38 | 39 | cur = new Location(0, 0); 40 | 41 | locations = [cur]; 42 | 43 | for(var i = 0; i < data.length; i++) { 44 | cur = cur.move(data[i]); 45 | if(!search(locations, cur)) { 46 | locations.push(cur); 47 | } 48 | } 49 | console.log(locations.length); 50 | }); 51 | -------------------------------------------------------------------------------- /day16/p2a.ex: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env elixir 2 | 3 | # by: steven critchfield 4 | # https://github.com/critch 5 | 6 | defmodule Advent16p2 do 7 | def calculate do 8 | valid = %{ 9 | "children" => 3, 10 | "cats" => 7, 11 | "samoyeds" => 2, 12 | "pomeranians" => 3, 13 | "akitas" => 0, 14 | "vizslas" => 0, 15 | "goldfish" => 5, 16 | "trees" => 3, 17 | "cars" => 2, 18 | "perfumes" => 1 19 | } 20 | File.stream!("input") |> 21 | Stream.map(fn(x) -> Regex.named_captures( 22 | ~r/Sue (?[0-9]+): (?[a-z]+): (?[0-9]+), (?[a-z]+): (?[0-9]+), (?[a-z]+): (?[0-9]+)/, 23 | x) 24 | end) |> 25 | Stream.filter(fn(x) -> check(x,1,valid) end) |> 26 | Stream.filter(fn(x) -> check(x,2,valid) end) |> 27 | Stream.filter(fn(x) -> check(x,3,valid) end) |> 28 | Enum.fetch!(-1) |> 29 | Map.fetch!("num") 30 | end 31 | 32 | def check(x,i,valid) do 33 | item = Map.fetch!(x,"i"<>Integer.to_string(i)) 34 | val = Map.fetch!(x,"v"<>Integer.to_string(i)) |> String.to_integer 35 | cv = Map.fetch!(valid, item) 36 | cond do 37 | item == "cats" -> val > cv 38 | item == "trees" -> val > cv 39 | item == "goldfish" -> val < cv 40 | item == "pomeranians" -> val < cv 41 | true -> val == cv 42 | end 43 | end 44 | end 45 | 46 | IO.puts "Matched Sue: " <> Advent16p2.calculate 47 | -------------------------------------------------------------------------------- /day12/p2a.rs: -------------------------------------------------------------------------------- 1 | //! This file is in the [cargo-script][1] format. 2 | //! 3 | //! [1]: https://github.com/DanielKeep/cargo-script 4 | //! 5 | //! ```cargo 6 | //! [dependencies] 7 | //! serde = "^0.6" 8 | //! serde_json = "^0.6" 9 | //! ``` 10 | 11 | extern crate serde; 12 | extern crate serde_json; 13 | 14 | use serde_json::{Value, from_reader}; 15 | 16 | use std::io; 17 | 18 | fn sum_value(val: &Value) -> i64 { 19 | match val { 20 | &Value::I64(i) => i, 21 | &Value::U64(u) => u as i64, 22 | &Value::F64(f) => f as i64, 23 | &Value::Array(ref arr) => { 24 | let mut sum = 0; 25 | 26 | for item in arr.iter() { 27 | sum += sum_value(&item); 28 | } 29 | 30 | sum 31 | }, 32 | &Value::Object(ref obj) => { 33 | let mut sum = 0; 34 | 35 | for (_, item) in obj.iter() { 36 | if Some("red") == item.as_string() { 37 | return 0; 38 | } 39 | 40 | sum += sum_value(&item); 41 | } 42 | 43 | sum 44 | }, 45 | _ => 0, 46 | } 47 | } 48 | 49 | fn main() { 50 | let stdin = io::stdin(); 51 | let stdin = stdin.lock(); 52 | 53 | let input: Value = from_reader(stdin) 54 | .expect("the input should be properly formatted"); 55 | 56 | let sum = sum_value(&input); 57 | 58 | println!("Sum: {}", sum); 59 | } 60 | -------------------------------------------------------------------------------- /day10/p1a.java: -------------------------------------------------------------------------------- 1 | package adventofcode; 2 | 3 | import java.io.File; 4 | import java.io.FileNotFoundException; 5 | import java.util.ArrayList; 6 | import java.util.Scanner; 7 | 8 | public class p1a { 9 | 10 | public static ArrayList evaluate(ArrayList list){ 11 | ArrayList output = new ArrayList<>(); 12 | 13 | int currentNum = list.get(0); 14 | int count = 1; 15 | for(int i = 1; i < list.size(); i++){ 16 | if(list.get(i) != currentNum){ 17 | output.add(count); 18 | output.add(currentNum); 19 | currentNum = list.get(i); 20 | count = 1; 21 | } 22 | else{ 23 | count++; 24 | } 25 | } 26 | output.add(count); 27 | output.add(currentNum); 28 | return output; 29 | } 30 | 31 | public static void main(String[] args) throws FileNotFoundException { 32 | ArrayList input = new ArrayList<>(); 33 | 34 | Scanner s = new Scanner(new File("input10.txt")); 35 | s.useDelimiter(""); 36 | 37 | while(s.hasNext()){ 38 | input.add(s.nextInt()); 39 | } 40 | 41 | for(int i = 0; i < 40; i++){ 42 | input = evaluate(input); 43 | } 44 | 45 | System.out.println("The value is " + input.size() + "."); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /day10/p2a.java: -------------------------------------------------------------------------------- 1 | package adventofcode; 2 | 3 | import java.io.File; 4 | import java.io.FileNotFoundException; 5 | import java.util.ArrayList; 6 | import java.util.Scanner; 7 | 8 | public class p2a { 9 | 10 | public static ArrayList evaluate(ArrayList list){ 11 | ArrayList output = new ArrayList<>(); 12 | 13 | int currentNum = list.get(0); 14 | int count = 1; 15 | for(int i = 1; i < list.size(); i++){ 16 | if(list.get(i) != currentNum){ 17 | output.add(count); 18 | output.add(currentNum); 19 | currentNum = list.get(i); 20 | count = 1; 21 | } 22 | else{ 23 | count++; 24 | } 25 | } 26 | output.add(count); 27 | output.add(currentNum); 28 | return output; 29 | } 30 | 31 | public static void main(String[] args) throws FileNotFoundException { 32 | ArrayList input = new ArrayList<>(); 33 | 34 | Scanner s = new Scanner(new File("input10.txt")); 35 | s.useDelimiter(""); 36 | 37 | while(s.hasNext()){ 38 | input.add(s.nextInt()); 39 | } 40 | 41 | for(int i = 0; i < 50; i++){ 42 | input = evaluate(input); 43 | } 44 | 45 | System.out.println("The value is " + input.size() + "."); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /day14/p1a.ex: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env elixir 2 | 3 | # By: Steven Critchfield 4 | # https://github.com/critch 5 | 6 | defmodule Advent14p1 do 7 | def calculate do 8 | File.stream!("input") |> 9 | Enum.map(fn(x) -> Regex.scan(~r"^([a-zA-Z]+) can fly ([0-9]+) km/s for ([0-9]+) seconds, but then must rest for ([0-9]+) seconds.", x) |> hd |> tl end) |> 10 | Enum.map(fn([ name, speed, dur, rest]) -> 11 | [name, String.to_integer(speed), String.to_integer(dur), String.to_integer(rest), "moving", 0, 0] 12 | end) |> 13 | Enum.map(fn(x) -> 14 | Stream.iterate(x, fn(x) -> move_reindeer(x) end) |> 15 | Enum.take(2503) |> 16 | Enum.fetch!(-1) |> 17 | Enum.fetch!(-1) 18 | end) |> 19 | Enum.max 20 | end 21 | 22 | def move_reindeer(x) do 23 | [ name, speed, dur, rest, status, cur_dur, dist] = x 24 | if( status == "moving") do 25 | if(cur_dur == dur) do 26 | # switch to resting 27 | [ name, speed, dur, rest, "resting", 1, dist ] 28 | else 29 | # move along 30 | [ name, speed, dur, rest, status, cur_dur + 1, dist + speed] 31 | end 32 | else 33 | if( cur_dur == rest ) do 34 | [ name, speed, dur, rest, "moving", 1, dist + speed ] 35 | else 36 | [ name, speed, dur, rest, status, cur_dur + 1, dist ] 37 | end 38 | end 39 | end 40 | end 41 | 42 | IO.puts "Winning distance: " <> Integer.to_string(Advent14p1.calculate) 43 | -------------------------------------------------------------------------------- /day17/p2a.rs: -------------------------------------------------------------------------------- 1 | use std::io::{self, BufRead}; 2 | 3 | fn combinations(containers: &[i64], remaining: i64, num_used: usize, min_num_used: &mut usize, num_min_num_used: &mut usize) -> i64 { 4 | let mut num_found = 0; 5 | 6 | for i in 0..containers.len() { 7 | if containers[i] == remaining { 8 | num_found += 1; 9 | 10 | if num_used < *min_num_used { 11 | *min_num_used = num_used; 12 | *num_min_num_used = 1; 13 | } else if num_used == *min_num_used { 14 | *num_min_num_used += 1; 15 | } 16 | } else if containers[i] < remaining { 17 | num_found += combinations(&containers[i + 1..], remaining - containers[i], num_used + 1, min_num_used, num_min_num_used); 18 | } 19 | } 20 | 21 | num_found 22 | } 23 | 24 | fn main() { 25 | let stdin = io::stdin(); 26 | let stdin = stdin.lock(); 27 | 28 | let mut container_sizes = Vec::new(); 29 | for line in stdin.lines() { 30 | container_sizes.push(line 31 | .expect("reading from stdin should succeed") 32 | .parse() 33 | .expect("the input should be correctly formatted")); 34 | } 35 | 36 | let mut min_num_used = container_sizes.len(); 37 | let mut num_min_num_used = 0; 38 | combinations(&container_sizes, 150, 0, &mut min_num_used, &mut num_min_num_used); 39 | println!("# of smallest solutions: {}", num_min_num_used); 40 | } 41 | -------------------------------------------------------------------------------- /day03/p1a.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | 5 | struct house { 6 | long x; 7 | long y; 8 | struct house *next; 9 | }; 10 | 11 | char AddHouse(long, long, struct house *); 12 | void RemoveHouses(struct house *haus); 13 | 14 | int main(void) 15 | { 16 | struct house *current; 17 | current = (struct house *) malloc(sizeof(struct house)); 18 | *current = (struct house) {0,0,NULL}; 19 | char c; 20 | long x = 0, y = 0; 21 | unsigned long houses = 1; // The initial house. 22 | while ((c = fgetc(stdin)) != EOF) { 23 | switch (c) { 24 | case '^': 25 | y++; 26 | break; 27 | case 'v': 28 | y--; 29 | break; 30 | case '>': 31 | x++; 32 | break; 33 | case '<': 34 | x--; 35 | break; 36 | default: 37 | printf("Unknown character input: %c.\n", c); 38 | break; 39 | } 40 | houses += AddHouse(x,y,current); 41 | } 42 | printf("Houses visited: %lu\n", houses); 43 | RemoveHouses(current); 44 | return 0; 45 | } 46 | 47 | char AddHouse(long x, long y, struct house *haus) 48 | { 49 | while (haus->x != x || haus->y != y) { 50 | if (haus->next) { 51 | haus = haus->next; 52 | } else { 53 | haus->next = (struct house *) 54 | malloc(sizeof(struct house)); 55 | *(haus->next) = (struct house) {x,y,NULL}; 56 | return 1; 57 | } 58 | } 59 | return 0; 60 | } 61 | 62 | void RemoveHouses(struct house *haus) 63 | { 64 | struct house *cur, *old; 65 | cur = old = haus; 66 | while(cur->next) { 67 | old = cur; 68 | cur = cur->next; 69 | free(old); 70 | } 71 | return; 72 | } 73 | -------------------------------------------------------------------------------- /day17/p2a.java: -------------------------------------------------------------------------------- 1 | package adventofcode; 2 | 3 | import java.io.File; 4 | import java.io.FileNotFoundException; 5 | import java.util.Scanner; 6 | 7 | public class p2a { 8 | 9 | static int[] bottles = new int[20]; 10 | static int[] solutions = new int[20]; 11 | 12 | public static void calculate(){ 13 | for(int i = 0; i < (int)Math.pow(2, 20); i++){ 14 | String unpadded = Integer.toBinaryString(i); 15 | checkPermutation("00000000000000000000".substring(unpadded.length()) + unpadded); 16 | } 17 | } 18 | 19 | public static void checkPermutation(String s){ 20 | char[] permutation = s.toCharArray(); 21 | int capacity = 0; 22 | int count = 0; 23 | for(int i = 0; i < 20; i++){ 24 | if(permutation[i] == '1'){ 25 | capacity += bottles[i]; 26 | count++; 27 | } 28 | } 29 | if(capacity == 150){ 30 | solutions[count - 1]++; 31 | } 32 | } 33 | 34 | public static void main(String[] args) throws FileNotFoundException { 35 | Scanner s = new Scanner(new File("input")); 36 | 37 | for(int i = 0; i < 20; i++){ 38 | bottles[i] = Integer.parseInt(s.nextLine()); 39 | } 40 | 41 | calculate(); 42 | 43 | for(int i : solutions){ 44 | if(i != 0){ 45 | System.out.println("There are " + i + " ways to fill the bottles."); 46 | break; 47 | } 48 | } 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /day06/p1a.ex: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env elixir 2 | 3 | # By: Steven Critchfield 4 | # https://github.com/critch 5 | 6 | defmodule Advent6p1 do 7 | def calculate do 8 | File.stream!("input") |> 9 | Stream.map(fn(x) -> Regex.named_captures(~r/(?.+) (?[0-9]+),(?[0-9]+) through (?[0-9]+),(?[0-9]+)/, x) end) |> 10 | Enum.reduce(HashDict.new, fn(x,state) -> 11 | light(state, Map.get(x,"com"), [ 12 | String.to_integer(Map.get(x, "sx")), String.to_integer(Map.get(x, "sy")), 13 | String.to_integer(Map.get(x, "ex")), String.to_integer(Map.get(x, "ey")) 14 | ] ) 15 | end) |> 16 | HashDict.keys |> 17 | Enum.count 18 | end 19 | 20 | def light(state, "turn off", [sx,sy, ex,ey]) do 21 | Enum.reduce(sx..ex, state, fn(x, acc) -> 22 | Enum.reduce(sy..ey, acc, fn(y, acc) -> 23 | HashDict.delete(acc, [x,y]) 24 | end) 25 | end) 26 | end 27 | def light(state, "turn on", [sx,sy, ex,ey]) do 28 | Enum.reduce(sx..ex, state, fn(x, acc) -> 29 | Enum.reduce(sy..ey, acc, fn(y, acc) -> 30 | HashDict.put_new(acc,[x,y], 1) 31 | end) 32 | end) 33 | end 34 | def light(state, "toggle", [sx,sy, ex,ey]) do 35 | Enum.reduce(sx..ex, state, fn(x,acc) -> 36 | Enum.reduce(sy..ey, acc, fn(y,acc) -> 37 | if HashDict.has_key?(acc, [x,y]), 38 | do: HashDict.delete(acc, [x,y]), 39 | else: HashDict.put(acc, [x,y], 1) 40 | end ) 41 | end) 42 | end 43 | end 44 | 45 | IO.puts "Lights on: " <> Integer.to_string(Advent6p1.calculate) 46 | -------------------------------------------------------------------------------- /day11/p1a.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #define BUFFER 80 5 | 6 | int ContainsRow(char *, unsigned long); 7 | int NoConfusing(char *, unsigned long); 8 | int TwoPair(char *, unsigned long); 9 | void IncrementString(char *, unsigned long); 10 | 11 | int main(void) 12 | { 13 | char input[BUFFER]; 14 | unsigned long len; 15 | fgets(input, BUFFER, stdin); 16 | strtok(input, "\n"); 17 | len = strlen(input); 18 | while (!NoConfusing(input, len) || !ContainsRow(input, len) || 19 | !TwoPair(input, len)) { 20 | IncrementString(input, len); 21 | } 22 | printf("Next possible password: %s\n", input); 23 | return 0; 24 | } 25 | 26 | int ContainsRow(char *str, unsigned long len) 27 | { 28 | int i; 29 | for (i = 0; i < len-3; i++) { 30 | if (str[i]+1 == str[i+1] && str[i]+2 == str[i+2]) { 31 | return 1; 32 | } 33 | } 34 | return 0; 35 | } 36 | 37 | int NoConfusing(char *str, unsigned long len) 38 | { 39 | int i; 40 | for (i = 0; i < len; i++) { 41 | switch (str[i]) { 42 | case 'i': 43 | case 'o': 44 | case 'l': 45 | return 0; 46 | } 47 | } 48 | return 1; 49 | } 50 | 51 | int TwoPair(char *str, unsigned long len) 52 | { 53 | int pairs = 0; 54 | int i; 55 | for (i = 0; i < len-1; i++) { 56 | if (str[i] == str[i+1]) { 57 | pairs++; 58 | i++; 59 | } 60 | } 61 | return (pairs >= 2); 62 | } 63 | 64 | void IncrementString(char *str, unsigned long len) 65 | { 66 | int i; 67 | for (i = len-1; i > 0; i--) { 68 | if (str[i] >= 'z') { 69 | str[i-1]++; 70 | str[i] = 'a'; 71 | if (!(str[i-1] > 'z')) { 72 | return; 73 | } 74 | } else { 75 | str[i]++; 76 | return; 77 | } 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /day03/p2a.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | // By Garrett Greenwood 3 | // Dec 2015 4 | // electricexploits.net 5 | 6 | var fs = require('fs'); 7 | 8 | function Location(x, y) { 9 | return { 10 | x: x, 11 | y: y, 12 | equals: function(loc) { 13 | return loc.x == this.x & loc.y == this.y; 14 | }, 15 | move: function(dir) { 16 | switch(dir) { 17 | case '^': return new Location(this.x, this.y + 1); 18 | case '>': return new Location(this.x + 1, this.y); 19 | case 'v': return new Location(this.x, this.y - 1); 20 | case '<': return new Location(this.x - 1, this.y); 21 | default: return new Location(0, 0); 22 | } 23 | } 24 | }; 25 | } 26 | 27 | function search(array, loc) { 28 | return array.filter(function(x) { 29 | return loc.equals(x); 30 | }).length; 31 | } 32 | 33 | fs.readFile(process.argv[2], 'utf8', function(err, data) { 34 | if(err) { 35 | console.log("Error reading file"); 36 | return; 37 | } 38 | 39 | santa = new Location(0, 0); 40 | robot_santa = new Location(0, 0); 41 | 42 | // Need to replace this with a hashmap 43 | locations = [santa]; 44 | 45 | for(var i = 0; i < data.length/2; i++) { 46 | santa = santa.move(data[2 * i]); 47 | if(!search(locations, santa)) { 48 | locations.push(santa); 49 | } 50 | robot_santa = robot_santa.move(data[2 * i + 1]); 51 | if(!search(locations, robot_santa)) { 52 | locations.push(robot_santa); 53 | } 54 | } 55 | console.log(locations.length); 56 | }); 57 | -------------------------------------------------------------------------------- /day03/p2a.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | 5 | struct house { 6 | long x; 7 | long y; 8 | struct house *next; 9 | }; 10 | 11 | char AddHouse(long, long, struct house *); 12 | void RemoveHouses(struct house *haus); 13 | 14 | int main(void) 15 | { 16 | struct house *current; 17 | current = (struct house *) malloc(sizeof(struct house)); 18 | *current = (struct house) {0,0,NULL}; 19 | char c; 20 | long x[2], y[2]; 21 | x[0] = y[0] = x[1] = y[1] = 0; 22 | unsigned char roboOrReal = 0; 23 | unsigned long houses = 1; // The initial house. 24 | while ((c = fgetc(stdin)) != EOF) { 25 | switch (c) { 26 | case '^': 27 | y[roboOrReal]++; 28 | break; 29 | case 'v': 30 | y[roboOrReal]--; 31 | break; 32 | case '>': 33 | x[roboOrReal]++; 34 | break; 35 | case '<': 36 | x[roboOrReal]--; 37 | break; 38 | default: 39 | printf("Unknown character input: %c.\n", c); 40 | break; 41 | } 42 | houses += AddHouse(x[roboOrReal],y[roboOrReal],current); 43 | roboOrReal = !roboOrReal; 44 | } 45 | printf("Houses visited: %lu\n", houses); 46 | RemoveHouses(current); 47 | return 0; 48 | } 49 | 50 | char AddHouse(long x, long y, struct house *haus) 51 | { 52 | while (haus->x != x || haus->y != y) { 53 | if (haus->next) { 54 | haus = haus->next; 55 | } else { 56 | haus->next = (struct house *) 57 | malloc(sizeof(struct house)); 58 | *(haus->next) = (struct house) {x,y,NULL}; 59 | return 1; 60 | } 61 | } 62 | return 0; 63 | } 64 | 65 | void RemoveHouses(struct house *haus) 66 | { 67 | struct house *cur, *old; 68 | cur = old = haus; 69 | while(cur->next) { 70 | old = cur; 71 | cur = cur->next; 72 | free(old); 73 | } 74 | return; 75 | } 76 | -------------------------------------------------------------------------------- /day02/p2a.hs: -------------------------------------------------------------------------------- 1 | import Data.Char (isDigit) 2 | import Data.List (sort) 3 | 4 | wrappingPaper :: (Int, Int, Int) -> Int 5 | wrappingPaper dim = areaOfBox dim + areaOfSmallestSide dim 6 | 7 | areaOfBox :: (Int, Int, Int) -> Int 8 | areaOfBox (l, w, h) = 2 * (sum . map areaOfSide $ [(l, w), (w, h), (l, h)]) 9 | 10 | areaOfSmallestSide :: (Int, Int, Int) -> Int 11 | areaOfSmallestSide (l, w, h) = minimum . map areaOfSide $ [(l, w), (w, h), (l, h)] 12 | 13 | areaOfSide :: (Int, Int) -> Int 14 | areaOfSide (l, w) = l * w 15 | 16 | ribbon :: (Int, Int, Int) -> Int 17 | ribbon dim = ribbonAround dim + ribbonBow dim 18 | 19 | ribbonAround :: (Int, Int, Int) -> Int 20 | ribbonAround dim = sum . map (* 2) . minimumSides $ dim 21 | 22 | ribbonBow :: (Int, Int, Int) -> Int 23 | ribbonBow = volume 24 | 25 | minimumSides :: (Int, Int, Int) -> [Int] 26 | minimumSides (l, w, h) = take 2 . sort $ [l, w, h] 27 | 28 | volume :: (Int, Int, Int) -> Int 29 | volume (l, w, h) = l * w * h 30 | 31 | dimToTuple :: String -> (Int, Int, Int) 32 | dimToTuple = result 33 | where 34 | result dim 35 | | length (splitDimension dim) /= 3 = (0,0,0) 36 | | otherwise = resultingTuple dim 37 | splitDimension = splitAll 'x' 38 | intList dim = map (read . filter isDigit) $ splitDimension dim 39 | resultingTuple dim = case intList dim of 40 | [first, second, third] -> (first, second, third) 41 | 42 | splitAll :: Eq a => a -> [a] -> [[a]] 43 | splitAll _ [] = [[]] 44 | splitAll delim (x:xs) 45 | | x == delim = [] : splitAll delim xs 46 | | otherwise = (x:headList) : tailLists 47 | where 48 | (headList:tailLists) = splitAll delim xs 49 | 50 | main = interact $ show . sum . map (ribbon . dimToTuple) . lines 51 | -------------------------------------------------------------------------------- /day02/p1a.hs: -------------------------------------------------------------------------------- 1 | import Data.Char (isDigit) 2 | import Data.List (sort) 3 | 4 | wrappingPaper :: (Int, Int, Int) -> Int 5 | wrappingPaper dim = areaOfBox dim + areaOfSmallestSide dim 6 | 7 | areaOfBox :: (Int, Int, Int) -> Int 8 | areaOfBox (l, w, h) = 2 * (sum . map areaOfSide $ [(l, w), (w, h), (l, h)]) 9 | 10 | areaOfSmallestSide :: (Int, Int, Int) -> Int 11 | areaOfSmallestSide (l, w, h) = minimum . map areaOfSide $ [(l, w), (w, h), (l, h)] 12 | 13 | areaOfSide :: (Int, Int) -> Int 14 | areaOfSide (l, w) = l * w 15 | 16 | ribbon :: (Int, Int, Int) -> Int 17 | ribbon dim = ribbonAround dim + ribbonBow dim 18 | 19 | ribbonAround :: (Int, Int, Int) -> Int 20 | ribbonAround dim = sum . map (* 2) . minimumSides $ dim 21 | 22 | ribbonBow :: (Int, Int, Int) -> Int 23 | ribbonBow = volume 24 | 25 | minimumSides :: (Int, Int, Int) -> [Int] 26 | minimumSides (l, w, h) = take 2 . sort $ [l, w, h] 27 | 28 | volume :: (Int, Int, Int) -> Int 29 | volume (l, w, h) = l * w * h 30 | 31 | dimToTuple :: String -> (Int, Int, Int) 32 | dimToTuple = result 33 | where 34 | result dim 35 | | length (splitDimension dim) /= 3 = (0,0,0) 36 | | otherwise = resultingTuple dim 37 | splitDimension = splitAll 'x' 38 | intList dim = map (read . filter isDigit) $ splitDimension dim 39 | resultingTuple dim = case intList dim of 40 | [first, second, third] -> (first, second, third) 41 | 42 | splitAll :: Eq a => a -> [a] -> [[a]] 43 | splitAll _ [] = [[]] 44 | splitAll delim (x:xs) 45 | | x == delim = [] : splitAll delim xs 46 | | otherwise = (x:headList) : tailLists 47 | where 48 | (headList:tailLists) = splitAll delim xs 49 | 50 | main = interact $ show . sum . map (wrappingPaper . dimToTuple) . lines 51 | -------------------------------------------------------------------------------- /day11/p2a.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #define BUFFER 80 5 | #define NUM_TO_SKIP 1 6 | 7 | int ContainsRow(char *, unsigned long); 8 | int NoConfusing(char *, unsigned long); 9 | int TwoPair(char *, unsigned long); 10 | void IncrementString(char *, unsigned long); 11 | 12 | int main(void) 13 | { 14 | char input[BUFFER]; 15 | unsigned long len; 16 | int numFound = 0; 17 | fgets(input, BUFFER, stdin); 18 | strtok(input, "\n"); 19 | len = strlen(input); 20 | while (!NoConfusing(input, len) || !ContainsRow(input, len) || 21 | !TwoPair(input, len) || (numFound++) < NUM_TO_SKIP) { 22 | IncrementString(input, len); 23 | } 24 | printf("Next possible password: %s\n", input); 25 | return 0; 26 | } 27 | 28 | int ContainsRow(char *str, unsigned long len) 29 | { 30 | int i; 31 | for (i = 0; i < len-3; i++) { 32 | if (str[i]+1 == str[i+1] && str[i]+2 == str[i+2]) { 33 | return 1; 34 | } 35 | } 36 | return 0; 37 | } 38 | 39 | int NoConfusing(char *str, unsigned long len) 40 | { 41 | int i; 42 | for (i = 0; i < len; i++) { 43 | switch (str[i]) { 44 | case 'i': 45 | case 'o': 46 | case 'l': 47 | return 0; 48 | } 49 | } 50 | return 1; 51 | } 52 | 53 | int TwoPair(char *str, unsigned long len) 54 | { 55 | int pairs = 0; 56 | int i; 57 | for (i = 0; i < len-1; i++) { 58 | if (str[i] == str[i+1]) { 59 | pairs++; 60 | i++; 61 | } 62 | } 63 | return (pairs >= 2); 64 | } 65 | 66 | void IncrementString(char *str, unsigned long len) 67 | { 68 | int i; 69 | for (i = len-1; i > 0; i--) { 70 | if (str[i] >= 'z') { 71 | str[i-1]++; 72 | str[i] = 'a'; 73 | if (!(str[i-1] > 'z')) { 74 | return; 75 | } 76 | } else { 77 | str[i]++; 78 | return; 79 | } 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /day06/p2a.ex: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env elixir 2 | 3 | # By: Steven Critchfield 4 | # https://github.com/critch 5 | 6 | defmodule Advent6p2 do 7 | def calculate do 8 | File.stream!("input") |> 9 | Stream.map(fn(x) -> Regex.named_captures(~r/(?.+) (?[0-9]+),(?[0-9]+) through (?[0-9]+),(?[0-9]+)/, x) end) |> 10 | Enum.reduce(HashDict.new, fn(x,state) -> 11 | light(state, Map.get(x,"com"), [ 12 | String.to_integer(Map.get(x, "sx")), String.to_integer(Map.get(x, "sy")), 13 | String.to_integer(Map.get(x, "ex")), String.to_integer(Map.get(x, "ey")) 14 | ] ) 15 | end) |> 16 | HashDict.values |> 17 | Enum.sum 18 | end 19 | 20 | def light(state, "turn off", [sx,sy, ex,ey]) do 21 | Enum.reduce(sx..ex, state, fn(x, acc) -> 22 | Enum.reduce(sy..ey, acc, fn(y, acc) -> 23 | elem(HashDict.get_and_update(acc, [x,y], fn(a) -> {a, change_by(a,-1)} end), 1) 24 | end) 25 | end) 26 | end 27 | def light(state, "turn on", [sx,sy, ex,ey]) do 28 | Enum.reduce(sx..ex, state, fn(x, acc) -> 29 | Enum.reduce(sy..ey, acc, fn(y, acc) -> 30 | elem(HashDict.get_and_update(acc, [x,y], fn(a) -> {a, change_by(a,1)} end), 1) 31 | end) 32 | end) 33 | end 34 | def light(state, "toggle", [sx,sy, ex,ey]) do 35 | Enum.reduce(sx..ex, state, fn(x,acc) -> 36 | Enum.reduce(sy..ey, acc, fn(y,acc) -> 37 | elem(HashDict.get_and_update(acc, [x,y], fn(a) -> {a, change_by(a, 2) } end), 1) 38 | end) 39 | end) 40 | end 41 | def change_by(a,val) do 42 | if a == nil, do: a = 0 43 | a = a + val 44 | if a < 0, do: a = 0 45 | a 46 | end 47 | end 48 | 49 | IO.puts "Total brightness: " <> Integer.to_string(Advent6p2.calculate) 50 | -------------------------------------------------------------------------------- /day12/p2a.c: -------------------------------------------------------------------------------- 1 | /** 2 | * STRONGLY DEPENDS ON A JSON LIBRARY 3 | * The nxjson library is, at time of writing, on bitbucket. 4 | * The link follows 5 | * https://bitbucket.org/yarosla/nxjson 6 | * The source files (nxjson.c and nxjosn.h) are necessary to compile. 7 | */ 8 | #include 9 | #include 10 | #include 11 | #include "nxjson.h" 12 | 13 | char *AddToString(char *, long long *, char); 14 | long long SumJson(const nx_json *); 15 | 16 | int main(void) 17 | { 18 | long long allocSize = 160; 19 | const nx_json *json; 20 | char c; 21 | char *buffer = calloc(allocSize, sizeof(char)); 22 | while ((c = fgetc(stdin)) && !feof(stdin)) { 23 | buffer = AddToString(buffer, &allocSize, c); 24 | } 25 | json = nx_json_parse(buffer, NULL); 26 | printf("Sum: %lld\n", SumJson(json)); 27 | return 0; 28 | } 29 | 30 | char *AddToString(char *str, long long *strAllocSize, char add) 31 | { 32 | long len = strlen(str); 33 | if (len + 2 >= *strAllocSize) { 34 | *strAllocSize *= 2; 35 | str = realloc(str, sizeof(char)*(*strAllocSize)); 36 | if (!str) { 37 | fprintf(stderr, "Out of memory for string!\n"); 38 | exit(1); 39 | } 40 | } 41 | if (str) { 42 | str[len] = add; 43 | str[len+1] = 0; 44 | } 45 | return str; 46 | } 47 | 48 | long long SumJson(const nx_json *json) 49 | { 50 | long long retVal = 0; 51 | const nx_json *curSon = json; 52 | while (curSon) { 53 | switch (curSon->type) { 54 | case NX_JSON_OBJECT: 55 | case NX_JSON_ARRAY: 56 | retVal += SumJson(curSon->child); 57 | break; 58 | case NX_JSON_STRING: 59 | if (curSon->key && !strcmp(curSon->text_value, "red")) { 60 | return 0; 61 | } 62 | break; 63 | case NX_JSON_INTEGER: 64 | retVal += curSon->int_value; 65 | break; 66 | case NX_JSON_DOUBLE: 67 | case NX_JSON_BOOL: 68 | case NX_JSON_NULL: 69 | break; 70 | } 71 | curSon = curSon->next; 72 | } 73 | return retVal; 74 | } 75 | -------------------------------------------------------------------------------- /day18/p1a.rs: -------------------------------------------------------------------------------- 1 | #![feature(io, iter_arith)] 2 | 3 | use std::io::{self, Read}; 4 | use std::mem::swap; 5 | 6 | fn neighbors(cells: &[bool], x: i64, y: i64) -> usize { 7 | let mut count = 0; 8 | 9 | for &xoff in [-1, 0, 1].into_iter() { 10 | for &yoff in [-1, 0, 1].into_iter() { 11 | if xoff == 0 && yoff == 0 { 12 | continue; 13 | } 14 | if (xoff < 0 && x <= 0) || (xoff > 0 && x >= 99) { 15 | continue; 16 | } 17 | if (yoff < 0 && y <= 0) || (yoff > 0 && y >= 99) { 18 | continue; 19 | } 20 | 21 | if cells[(x + xoff) as usize * 100 + (y + yoff) as usize] { 22 | count += 1; 23 | } 24 | } 25 | } 26 | 27 | count 28 | } 29 | fn game_of_life(cells: &[bool], buffer: &mut [bool]) { 30 | for x in 0..100 { 31 | for y in 0..100 { 32 | let num_neighbors = neighbors(cells, x, y); 33 | 34 | let loc: usize = x as usize * 100 + y as usize; 35 | if cells[loc] { 36 | buffer[loc] = num_neighbors == 2 || num_neighbors == 3; 37 | } else { 38 | buffer[loc] = num_neighbors == 3; 39 | } 40 | } 41 | } 42 | } 43 | 44 | fn main() { 45 | let stdin = io::stdin(); 46 | let stdin = stdin.lock(); 47 | 48 | let mut cells = Vec::with_capacity(100 * 100); 49 | for c in stdin.chars() { 50 | match c.expect("reading from stdin should succeed") { 51 | '#' => cells.push(true), 52 | '.' => cells.push(false), 53 | _ => {}, 54 | } 55 | } 56 | let mut buffer = vec![false; 100 * 100]; 57 | 58 | for _ in 0..100 { 59 | game_of_life(&cells, &mut buffer); 60 | swap(&mut cells, &mut buffer); 61 | } 62 | 63 | let count = cells.into_iter().map(|b| if b { 1 } else { 0 }).sum::(); 64 | println!("Count: {}", count); 65 | } 66 | -------------------------------------------------------------------------------- /day10/p1a.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | char *GetLookAndSay(char *, long long *); 6 | char *AddToString(char *, long long *, char); 7 | 8 | int main(void) 9 | { 10 | int i = 0; 11 | long long allocSize = 160; 12 | char *buffer = calloc(allocSize, sizeof(char)); 13 | char *oldBuff; 14 | fgets(buffer, allocSize, stdin); 15 | for (i = 0; i < 40; i++) { 16 | oldBuff = buffer; 17 | buffer = GetLookAndSay(buffer, &allocSize); 18 | free(oldBuff); 19 | //printf("Buffer: %s\n", buffer); 20 | } 21 | printf("Final strlen: %lu\n", strlen(buffer)); 22 | return 0; 23 | } 24 | 25 | char *GetLookAndSay(char *in, long long *strAllocSize) 26 | { 27 | char curChar, curCount, tmpChar; 28 | int i; 29 | char *newStr = calloc(*strAllocSize, sizeof(char)); 30 | curChar = in[0]; 31 | curCount = 0; 32 | long long endlength = strlen(in)+1; 33 | for (i = 0; i < endlength && curChar >= 0; i++) { 34 | tmpChar = in[i]; 35 | //printf("Char is: %c\n", tmpChar); 36 | if (tmpChar != curChar || tmpChar == '\n') { 37 | //printf("Char change! Resetting\n"); 38 | newStr = AddToString(newStr, strAllocSize, '0' + curCount); 39 | newStr = AddToString(newStr, strAllocSize, curChar); 40 | curCount = 0; 41 | curChar = tmpChar == '\n' ? -1 : tmpChar; 42 | } 43 | if (tmpChar == curChar) { 44 | curCount++; 45 | } 46 | } 47 | return newStr; 48 | } 49 | 50 | char *AddToString(char *str, long long *strAllocSize, char add) 51 | { 52 | if (strlen(str) + 2 >= *strAllocSize) { 53 | ////printf("Alloc size before: %d\n", *strAllocSize); 54 | *strAllocSize *= 2; 55 | ////printf("Alloc size after: %d\n", *strAllocSize); 56 | str = realloc(str, sizeof(char)*(*strAllocSize)); 57 | if (!str) { 58 | fprintf(stderr, "Out of memory for string!\n"); 59 | exit(1); 60 | } 61 | ////printf("Ended realloc\n"); 62 | } 63 | if (str) { 64 | str[strlen(str)] = add; 65 | str[strlen(str)+1] = 0; 66 | } 67 | return str; 68 | } 69 | 70 | -------------------------------------------------------------------------------- /day10/p2a.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | char *GetLookAndSay(char *, long long *); 6 | char *AddToString(char *, long long *, char); 7 | 8 | int main(void) 9 | { 10 | int i = 0; 11 | long long allocSize = 160; 12 | char *buffer = calloc(allocSize, sizeof(char)); 13 | char *oldBuff; 14 | fgets(buffer, allocSize, stdin); 15 | for (i = 0; i < 50; i++) { 16 | oldBuff = buffer; 17 | buffer = GetLookAndSay(buffer, &allocSize); 18 | free(oldBuff); 19 | //printf("Buffer: %s\n", buffer); 20 | } 21 | printf("Final strlen: %lu\n", strlen(buffer)); 22 | return 0; 23 | } 24 | 25 | char *GetLookAndSay(char *in, long long *strAllocSize) 26 | { 27 | char curChar, curCount, tmpChar; 28 | int i; 29 | char *newStr = calloc(*strAllocSize, sizeof(char)); 30 | curChar = in[0]; 31 | curCount = 0; 32 | long long endlength = strlen(in)+1; 33 | for (i = 0; i < endlength && curChar >= 0; i++) { 34 | tmpChar = in[i]; 35 | //printf("Char is: %c\n", tmpChar); 36 | if (tmpChar != curChar || tmpChar == '\n') { 37 | //printf("Char change! Resetting\n"); 38 | newStr = AddToString(newStr, strAllocSize, '0' + curCount); 39 | newStr = AddToString(newStr, strAllocSize, curChar); 40 | curCount = 0; 41 | curChar = tmpChar == '\n' ? -1 : tmpChar; 42 | } 43 | if (tmpChar == curChar) { 44 | curCount++; 45 | } 46 | } 47 | return newStr; 48 | } 49 | 50 | char *AddToString(char *str, long long *strAllocSize, char add) 51 | { 52 | if (strlen(str) + 2 >= *strAllocSize) { 53 | ////printf("Alloc size before: %d\n", *strAllocSize); 54 | *strAllocSize *= 2; 55 | ////printf("Alloc size after: %d\n", *strAllocSize); 56 | str = realloc(str, sizeof(char)*(*strAllocSize)); 57 | if (!str) { 58 | fprintf(stderr, "Out of memory for string!\n"); 59 | exit(1); 60 | } 61 | ////printf("Ended realloc\n"); 62 | } 63 | if (str) { 64 | str[strlen(str)] = add; 65 | str[strlen(str)+1] = 0; 66 | } 67 | return str; 68 | } 69 | 70 | -------------------------------------------------------------------------------- /day09/p1a.hs: -------------------------------------------------------------------------------- 1 | {-# Language BangPatterns #-} 2 | 3 | import Control.Arrow 4 | import Control.Monad.State 5 | import qualified Data.Map as M 6 | import Data.Map (Map) 7 | import Data.List (permutations) 8 | 9 | newtype City = City String deriving (Ord, Eq, Show) 10 | type CityList = [(City, Int)] 11 | type Edge = (City, City, Int) 12 | type Path = [City] 13 | type EdgeList = [Edge] 14 | type CityMap = Map City CityList 15 | 16 | insertEdge :: CityMap -> City -> City -> Int -> CityMap 17 | insertEdge cities c1 c2 dist = foldr (\ (x1, x2) acc -> M.alter (addCityAlter x2 dist) x1 acc) cities [(c1, c2), (c2, c1)] 18 | 19 | addCityAlter :: City -> Int -> Maybe CityList -> Maybe CityList 20 | addCityAlter city dist (Just citylist) = Just $ addCity city dist citylist 21 | addCityAlter city dist Nothing = Just $ addCity city dist [] 22 | 23 | addCity :: City -> Int -> CityList -> CityList 24 | addCity city dist = (:) (city, dist) 25 | 26 | initCities :: EdgeList -> CityMap 27 | initCities = foldr (\ (x1, x2, dist) acc -> insertEdge acc x1 x2 dist) M.empty 28 | 29 | listEdges :: [String] -> EdgeList 30 | listEdges = map stringToEdge 31 | 32 | stringToEdge :: String -> Edge 33 | stringToEdge str = case (words str) of 34 | [city1Name, "to", city2Name, "=", dist] -> (City city1Name, City city2Name, read dist) 35 | _ -> undefined 36 | 37 | pathDistance :: CityMap -> Path -> Maybe Int 38 | pathDistance = pathDistance' 0 39 | pathDistance' :: Int -> CityMap -> Path -> Maybe Int 40 | pathDistance' x _ [] = Just x 41 | pathDistance' x _ [_] = Just x 42 | pathDistance' x cityMap (c1:c2:cities) = do 43 | distance <- lookup c2 (M.findWithDefault [] c1 cityMap) 44 | pathDistance' (x + distance) cityMap (c2:cities) 45 | 46 | allDistances :: CityMap -> [(Maybe Int, Path)] 47 | allDistances cityMap = map (pathDistance cityMap &&& id) allPaths 48 | where 49 | cities = M.keys cityMap 50 | allPaths = permutations cities 51 | 52 | main = interact $ show . minimum . allDistances . initCities . listEdges . lines 53 | -------------------------------------------------------------------------------- /day09/p2a.hs: -------------------------------------------------------------------------------- 1 | {-# Language BangPatterns #-} 2 | 3 | import Control.Arrow 4 | import Control.Monad.State 5 | import qualified Data.Map as M 6 | import Data.Map (Map) 7 | import Data.List (permutations) 8 | 9 | newtype City = City String deriving (Ord, Eq, Show) 10 | type CityList = [(City, Int)] 11 | type Edge = (City, City, Int) 12 | type Path = [City] 13 | type EdgeList = [Edge] 14 | type CityMap = Map City CityList 15 | 16 | insertEdge :: CityMap -> City -> City -> Int -> CityMap 17 | insertEdge cities c1 c2 dist = foldr (\ (x1, x2) acc -> M.alter (addCityAlter x2 dist) x1 acc) cities [(c1, c2), (c2, c1)] 18 | 19 | addCityAlter :: City -> Int -> Maybe CityList -> Maybe CityList 20 | addCityAlter city dist (Just citylist) = Just $ addCity city dist citylist 21 | addCityAlter city dist Nothing = Just $ addCity city dist [] 22 | 23 | addCity :: City -> Int -> CityList -> CityList 24 | addCity city dist = (:) (city, dist) 25 | 26 | initCities :: EdgeList -> CityMap 27 | initCities = foldr (\ (x1, x2, dist) acc -> insertEdge acc x1 x2 dist) M.empty 28 | 29 | listEdges :: [String] -> EdgeList 30 | listEdges = map stringToEdge 31 | 32 | stringToEdge :: String -> Edge 33 | stringToEdge str = case (words str) of 34 | [city1Name, "to", city2Name, "=", dist] -> (City city1Name, City city2Name, read dist) 35 | _ -> undefined 36 | 37 | pathDistance :: CityMap -> Path -> Maybe Int 38 | pathDistance = pathDistance' 0 39 | pathDistance' :: Int -> CityMap -> Path -> Maybe Int 40 | pathDistance' x _ [] = Just x 41 | pathDistance' x _ [_] = Just x 42 | pathDistance' x cityMap (c1:c2:cities) = do 43 | distance <- lookup c2 (M.findWithDefault [] c1 cityMap) 44 | pathDistance' (x + distance) cityMap (c2:cities) 45 | 46 | allDistances :: CityMap -> [(Maybe Int, Path)] 47 | allDistances cityMap = map (pathDistance cityMap &&& id) allPaths 48 | where 49 | cities = M.keys cityMap 50 | allPaths = permutations cities 51 | 52 | main = interact $ show . maximum . allDistances . initCities . listEdges . lines 53 | -------------------------------------------------------------------------------- /day16/p1a.rs: -------------------------------------------------------------------------------- 1 | use std::collections::HashMap; 2 | use std::io::{self, BufRead}; 3 | 4 | trait DropLast { 5 | fn drop_last(&self) -> &Self; 6 | } 7 | impl DropLast for str { 8 | fn drop_last(&self) -> &str { 9 | &self[0..self.len() - 1] 10 | } 11 | } 12 | 13 | fn parse_line(line: &str) -> HashMap { 14 | line.split_whitespace().skip(2).collect::>().chunks(2).map(|item| { 15 | let id = item[0].drop_last(); 16 | let val = item[1]; 17 | 18 | (id.to_owned(), (if val.find(',').is_some() { 19 | val.drop_last().parse() 20 | } else { 21 | val.parse() 22 | }).expect("the input should be properly formatted")) 23 | }).collect() 24 | } 25 | 26 | fn main() { 27 | let stdin = io::stdin(); 28 | let stdin = stdin.lock(); 29 | 30 | let mut sue_stats = Vec::new(); 31 | for line in stdin.lines() { 32 | sue_stats.push(parse_line(&line.expect("reading from stdin should succeed"))); 33 | } 34 | 35 | let mut mfcsam_readout = HashMap::new(); 36 | mfcsam_readout.insert("children".to_owned(), 3); 37 | mfcsam_readout.insert("cats".to_owned(), 7); 38 | mfcsam_readout.insert("samoyeds".to_owned(), 2); 39 | mfcsam_readout.insert("pomeranians".to_owned(), 3); 40 | mfcsam_readout.insert("akitas".to_owned(), 0); 41 | mfcsam_readout.insert("vizslas".to_owned(), 0); 42 | mfcsam_readout.insert("goldfish".to_owned(), 5); 43 | mfcsam_readout.insert("trees".to_owned(), 3); 44 | mfcsam_readout.insert("cars".to_owned(), 2); 45 | mfcsam_readout.insert("perfumes".to_owned(), 1); 46 | 47 | let mut matching_sues = sue_stats.into_iter() 48 | .enumerate() 49 | .filter(|&(_, ref stats)| { 50 | stats.into_iter().all(|(k, v)| { 51 | mfcsam_readout.get(k).unwrap() == v 52 | }) 53 | }).map(|(i, stats)| { 54 | (i + 1, stats) 55 | }); 56 | 57 | println!("Sue #: {}", matching_sues.next().unwrap().0); 58 | } 59 | -------------------------------------------------------------------------------- /day10/p1b.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | char *GetLookAndSay(char *, long long *); 6 | char *AddToString(char *, long long *, char, char); 7 | 8 | int main(void) 9 | { 10 | int i = 0; 11 | long long allocSize = 160; 12 | char *buffer = calloc(allocSize, sizeof(char)); 13 | char *oldBuff; 14 | fgets(buffer, allocSize, stdin); 15 | for (i = 0; i < 40; i++) { 16 | oldBuff = buffer; 17 | buffer = GetLookAndSay(buffer, &allocSize); 18 | free(oldBuff); 19 | //printf("Buffer: %s\n", buffer); 20 | } 21 | printf("Final strlen: %lu\n", strlen(buffer)); 22 | return 0; 23 | } 24 | 25 | char *GetLookAndSay(char *in, long long *strAllocSize) 26 | { 27 | char curChar, curCount, tmpChar; 28 | int i; 29 | char *newStr = calloc(*strAllocSize, sizeof(char)); 30 | curChar = in[0]; 31 | curCount = 0; 32 | long long endlength = strlen(in)+1; 33 | for (i = 0; i < endlength && curChar >= 0; i++) { 34 | tmpChar = in[i]; 35 | //printf("Char is: %c\n", tmpChar); 36 | if (tmpChar != curChar || tmpChar == '\n') { 37 | //printf("Char change! Resetting\n"); 38 | newStr = AddToString(newStr, strAllocSize, 39 | '0' + curCount, curChar); 40 | curCount = 0; 41 | curChar = tmpChar == '\n' ? -1 : tmpChar; 42 | } 43 | if (tmpChar == curChar) { 44 | curCount++; 45 | } 46 | } 47 | return newStr; 48 | } 49 | 50 | char *AddToString(char *str, long long *strAllocSize, char char1, char char2) 51 | { 52 | if (strlen(str) + 3 >= *strAllocSize) { 53 | ////printf("Alloc size before: %d\n", *strAllocSize); 54 | *strAllocSize *= 2; 55 | ////printf("Alloc size after: %d\n", *strAllocSize); 56 | str = realloc(str, sizeof(char)*(*strAllocSize)); 57 | if (!str) { 58 | fprintf(stderr, "Out of memory for string!\n"); 59 | exit(1); 60 | } 61 | ////printf("Ended realloc\n"); 62 | } 63 | if (str) { 64 | unsigned long long len = strlen(str); 65 | str[len] = char1; 66 | str[len+1] = char2; 67 | str[len+2] = 0; 68 | } 69 | return str; 70 | } 71 | 72 | -------------------------------------------------------------------------------- /day10/p2b.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | char *GetLookAndSay(char *, long long *); 6 | char *AddToString(char *, long long *, char, char); 7 | 8 | int main(void) 9 | { 10 | int i = 0; 11 | long long allocSize = 160; 12 | char *buffer = calloc(allocSize, sizeof(char)); 13 | char *oldBuff; 14 | fgets(buffer, allocSize, stdin); 15 | for (i = 0; i < 50; i++) { 16 | oldBuff = buffer; 17 | buffer = GetLookAndSay(buffer, &allocSize); 18 | free(oldBuff); 19 | //printf("Buffer: %s\n", buffer); 20 | } 21 | printf("Final strlen: %lu\n", strlen(buffer)); 22 | return 0; 23 | } 24 | 25 | char *GetLookAndSay(char *in, long long *strAllocSize) 26 | { 27 | char curChar, curCount, tmpChar; 28 | int i; 29 | char *newStr = calloc(*strAllocSize, sizeof(char)); 30 | curChar = in[0]; 31 | curCount = 0; 32 | long long endlength = strlen(in)+1; 33 | for (i = 0; i < endlength && curChar >= 0; i++) { 34 | tmpChar = in[i]; 35 | //printf("Char is: %c\n", tmpChar); 36 | if (tmpChar != curChar || tmpChar == '\n') { 37 | //printf("Char change! Resetting\n"); 38 | newStr = AddToString(newStr, strAllocSize, 39 | '0' + curCount, curChar); 40 | curCount = 0; 41 | curChar = tmpChar == '\n' ? -1 : tmpChar; 42 | } 43 | if (tmpChar == curChar) { 44 | curCount++; 45 | } 46 | } 47 | return newStr; 48 | } 49 | 50 | char *AddToString(char *str, long long *strAllocSize, char char1, char char2) 51 | { 52 | if (strlen(str) + 3 >= *strAllocSize) { 53 | ////printf("Alloc size before: %d\n", *strAllocSize); 54 | *strAllocSize *= 2; 55 | ////printf("Alloc size after: %d\n", *strAllocSize); 56 | str = realloc(str, sizeof(char)*(*strAllocSize)); 57 | if (!str) { 58 | fprintf(stderr, "Out of memory for string!\n"); 59 | exit(1); 60 | } 61 | ////printf("Ended realloc\n"); 62 | } 63 | if (str) { 64 | unsigned long long len = strlen(str); 65 | str[len] = char1; 66 | str[len+1] = char2; 67 | str[len+2] = 0; 68 | } 69 | return str; 70 | } 71 | 72 | -------------------------------------------------------------------------------- /day10/p1c.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | char *GetLookAndSay(char *, long long *); 6 | char *AddToString(char *, long long *, char, char); 7 | 8 | int main(void) 9 | { 10 | int i = 0; 11 | long long allocSize = 160; 12 | char *buffer = calloc(allocSize, sizeof(char)); 13 | char *oldBuff; 14 | fgets(buffer, allocSize, stdin); 15 | for (i = 0; i < 40; i++) { 16 | oldBuff = buffer; 17 | buffer = GetLookAndSay(buffer, &allocSize); 18 | free(oldBuff); 19 | //printf("Buffer: %s\n", buffer); 20 | } 21 | printf("Final strlen: %lu\n", strlen(buffer)); 22 | return 0; 23 | } 24 | 25 | char *GetLookAndSay(char *in, long long *strAllocSize) 26 | { 27 | char curChar, curCount, tmpChar; 28 | int i; 29 | char *newStr = calloc(*strAllocSize, sizeof(char)); 30 | curChar = *in; 31 | curCount = 0; 32 | long long endlength = strlen(in)+1; 33 | for (i = 0; i < endlength && curChar >= 0; i++) { 34 | tmpChar = *(in+i); 35 | //printf("Char is: %c\n", tmpChar); 36 | if (tmpChar != curChar || tmpChar == '\n') { 37 | //printf("Char change! Resetting\n"); 38 | newStr = AddToString(newStr, strAllocSize, 39 | '0' + curCount, curChar); 40 | curCount = 0; 41 | curChar = tmpChar == '\n' ? -1 : tmpChar; 42 | } 43 | if (tmpChar == curChar) { 44 | curCount++; 45 | } 46 | } 47 | return newStr; 48 | } 49 | 50 | char *AddToString(char *str, long long *strAllocSize, char char1, char char2) 51 | { 52 | if (strlen(str) + 3 >= *strAllocSize) { 53 | ////printf("Alloc size before: %d\n", *strAllocSize); 54 | *strAllocSize *= 2; 55 | ////printf("Alloc size after: %d\n", *strAllocSize); 56 | str = realloc(str, sizeof(char)*(*strAllocSize)); 57 | if (!str) { 58 | fprintf(stderr, "Out of memory for string!\n"); 59 | exit(1); 60 | } 61 | ////printf("Ended realloc\n"); 62 | } 63 | if (str) { 64 | unsigned long long len = strlen(str); 65 | *(str+len) = char1; 66 | *(str+len+1) = char2; 67 | *(str+len+2) = 0; 68 | } 69 | return str; 70 | } 71 | 72 | -------------------------------------------------------------------------------- /day10/p2c.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | char *GetLookAndSay(char *, long long *); 6 | char *AddToString(char *, long long *, char, char); 7 | 8 | int main(void) 9 | { 10 | int i = 0; 11 | long long allocSize = 160; 12 | char *buffer = calloc(allocSize, sizeof(char)); 13 | char *oldBuff; 14 | fgets(buffer, allocSize, stdin); 15 | for (i = 0; i < 50; i++) { 16 | oldBuff = buffer; 17 | buffer = GetLookAndSay(buffer, &allocSize); 18 | free(oldBuff); 19 | //printf("Buffer: %s\n", buffer); 20 | } 21 | printf("Final strlen: %lu\n", strlen(buffer)); 22 | return 0; 23 | } 24 | 25 | char *GetLookAndSay(char *in, long long *strAllocSize) 26 | { 27 | char curChar, curCount, tmpChar; 28 | int i; 29 | char *newStr = calloc(*strAllocSize, sizeof(char)); 30 | curChar = *in; 31 | curCount = 0; 32 | long long endlength = strlen(in)+1; 33 | for (i = 0; i < endlength && curChar >= 0; i++) { 34 | tmpChar = *(in+i); 35 | //printf("Char is: %c\n", tmpChar); 36 | if (tmpChar != curChar || tmpChar == '\n') { 37 | //printf("Char change! Resetting\n"); 38 | newStr = AddToString(newStr, strAllocSize, 39 | '0' + curCount, curChar); 40 | curCount = 0; 41 | curChar = tmpChar == '\n' ? -1 : tmpChar; 42 | } 43 | if (tmpChar == curChar) { 44 | curCount++; 45 | } 46 | } 47 | return newStr; 48 | } 49 | 50 | char *AddToString(char *str, long long *strAllocSize, char char1, char char2) 51 | { 52 | if (strlen(str) + 3 >= *strAllocSize) { 53 | ////printf("Alloc size before: %d\n", *strAllocSize); 54 | *strAllocSize *= 2; 55 | ////printf("Alloc size after: %d\n", *strAllocSize); 56 | str = realloc(str, sizeof(char)*(*strAllocSize)); 57 | if (!str) { 58 | fprintf(stderr, "Out of memory for string!\n"); 59 | exit(1); 60 | } 61 | ////printf("Ended realloc\n"); 62 | } 63 | if (str) { 64 | unsigned long long len = strlen(str); 65 | *(str+len) = char1; 66 | *(str+len+1) = char2; 67 | *(str+len+2) = 0; 68 | } 69 | return str; 70 | } 71 | 72 | -------------------------------------------------------------------------------- /day12/p2a.java: -------------------------------------------------------------------------------- 1 | package adventofcode; 2 | 3 | import java.io.File; 4 | import java.io.FileNotFoundException; 5 | import java.util.Arrays; 6 | import java.util.Scanner; 7 | 8 | public class p2a { 9 | 10 | public static char[] killRed(char[] c){ 11 | int level = 0; 12 | int index1 = 0; 13 | int index2 = 0; 14 | 15 | for(int i = 0; i < c.length; i++){ 16 | if(c[i] == ':' && c[i+1] == '"' && c[i+2] == 'r'){ 17 | for(int j = i; j > 0; j--){ 18 | if(c[j] == '}'){ 19 | level++; 20 | } 21 | else if(c[j] == '{' && level != 0){ 22 | level--; 23 | } 24 | else if(c[j] == '{' && level == 0){ 25 | index1 = j; 26 | break; 27 | } 28 | } 29 | for(int j = i; j < c.length; j++){ 30 | if(c[j] == '{'){ 31 | level++; 32 | } 33 | else if(c[j] == '}' && level != 0){ 34 | level--; 35 | } 36 | else if(c[j] == '}' && level == 0){ 37 | index2 = j; 38 | break; 39 | } 40 | } 41 | Arrays.fill(c, index1, index2 + 1, ' '); 42 | } 43 | } 44 | return c; 45 | } 46 | 47 | public static void main(String[] args) throws FileNotFoundException { 48 | Scanner s = new Scanner(new File("input")); 49 | int output = 0; 50 | 51 | String input = s.nextLine(); 52 | 53 | input = new String(killRed(input.toCharArray())); 54 | input = input.replaceAll("[\\[\\]\"{},:a-z]", " "); 55 | 56 | s = new Scanner(input); 57 | 58 | while(s.hasNext()){ 59 | output += s.nextInt(); 60 | } 61 | 62 | System.out.println("The sum is " + output + "."); 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /day17/p1a.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #define GOAL_SIZE 150 6 | 7 | struct person { 8 | char *name; 9 | struct animosity *likes; 10 | struct person *next; 11 | }; 12 | 13 | struct animosity { 14 | char *towards; 15 | long amount; 16 | struct animosity *next; 17 | }; 18 | 19 | char *AddToString(char *, long long *, char); 20 | long choose(long *, int, int, int); 21 | 22 | int main (void) 23 | { 24 | long long allocSize = 80; 25 | char *buffer = calloc(allocSize, sizeof(char)); 26 | int numAlloced = 2; 27 | long *vals = calloc(1, sizeof(long)); 28 | int numVals = 0; 29 | char c; 30 | while ((c = fgetc(stdin)) && !feof(stdin)){ 31 | if (c == '\n') { // POSIX!!!!!! 32 | vals[numVals++] = strtol(buffer, NULL, 10); 33 | if (numVals >= numAlloced) { 34 | numAlloced *= 2; 35 | vals = realloc(vals, numAlloced*sizeof(long)); 36 | } 37 | memset(buffer, 0, allocSize); 38 | } else { 39 | buffer = AddToString(buffer, &allocSize, c); 40 | } 41 | } 42 | printf("Arrangements: %ld\n", choose(vals, 0, numVals, 0)); 43 | return 0; 44 | } 45 | 46 | char *AddToString(char *str, long long *strAllocSize, char add) 47 | { 48 | long len = strlen(str); 49 | if (len + 2 >= *strAllocSize) { 50 | *strAllocSize *= 2; 51 | str = realloc(str, sizeof(char)*(*strAllocSize)); 52 | if (!str) { 53 | fprintf(stderr, "Out of memory for string!\n"); 54 | exit(1); 55 | } 56 | } 57 | if (str) { 58 | str[len] = add; 59 | str[len+1] = 0; 60 | } 61 | return str; 62 | } 63 | 64 | /* curr is the current index to choose and size is sizeof vals */ 65 | long choose(long *vals, int curr, int size, int curTotal) 66 | { 67 | long subMatches = 0; 68 | if (curTotal > GOAL_SIZE) { 69 | return 0; 70 | } else if (curTotal == GOAL_SIZE) { 71 | return 1; 72 | } 73 | if (curr == size-1) { // Final condition 74 | if (curTotal + vals[curr] == GOAL_SIZE) { 75 | return 1; 76 | } 77 | return 0; 78 | } 79 | subMatches += choose(vals, curr+1, size, curTotal); 80 | subMatches += choose(vals, curr+1, size, curTotal+vals[curr]); 81 | return subMatches; 82 | } 83 | -------------------------------------------------------------------------------- /day10/p1d.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | char *GetLookAndSay(char *, long long *); 6 | char *AddToString(char *, long long, long long *, char, char); 7 | 8 | int main(void) 9 | { 10 | int i = 0; 11 | long long allocSize = 160; 12 | char *buffer = calloc(allocSize, sizeof(char)); 13 | char *oldBuff; 14 | fgets(buffer, allocSize, stdin); 15 | for (i = 0; i < 40; i++) { 16 | oldBuff = buffer; 17 | buffer = GetLookAndSay(buffer, &allocSize); 18 | free(oldBuff); 19 | //printf("Buffer: %s\n", buffer); 20 | } 21 | printf("Final strlen: %lu\n", strlen(buffer)); 22 | return 0; 23 | } 24 | 25 | char *GetLookAndSay(char *in, long long *strAllocSize) 26 | { 27 | char curChar, curCount, tmpChar; 28 | int i; 29 | char *newStr = calloc(*strAllocSize, sizeof(char)); 30 | curChar = *in; 31 | curCount = 0; 32 | long long endlength = strlen(in)+1; 33 | long long strLength = 0; 34 | for (i = 0; i < endlength && curChar >= 0; i++) { 35 | tmpChar = *(in+i); 36 | //printf("Char is: %c\n", tmpChar); 37 | if (tmpChar != curChar || tmpChar == '\n') { 38 | //printf("Char change! Resetting\n"); 39 | newStr = AddToString(newStr, strLength, strAllocSize, 40 | '0' + curCount, curChar); 41 | strLength += 2; 42 | curCount = 0; 43 | curChar = tmpChar == '\n' ? -1 : tmpChar; 44 | } 45 | if (tmpChar == curChar) { 46 | curCount++; 47 | } 48 | } 49 | return newStr; 50 | } 51 | 52 | char *AddToString(char *str, long long strLength, long long *strAllocSize, 53 | char char1, char char2) 54 | { 55 | if (strLength + 3 >= *strAllocSize) { 56 | ////printf("Alloc size before: %d\n", *strAllocSize); 57 | *strAllocSize *= 2; 58 | ////printf("Alloc size after: %d\n", *strAllocSize); 59 | str = realloc(str, sizeof(char)*(*strAllocSize)); 60 | if (!str) { 61 | fprintf(stderr, "Out of memory for string!\n"); 62 | exit(1); 63 | } 64 | ////printf("Ended realloc\n"); 65 | } 66 | if (str) { 67 | unsigned long long len = strLength; 68 | *(str+len) = char1; 69 | *(str+len+1) = char2; 70 | *(str+len+2) = 0; 71 | } 72 | return str; 73 | } 74 | 75 | -------------------------------------------------------------------------------- /day10/p2d.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | char *GetLookAndSay(char *, long long *); 6 | char *AddToString(char *, long long, long long *, char, char); 7 | 8 | int main(void) 9 | { 10 | int i = 0; 11 | long long allocSize = 160; 12 | char *buffer = calloc(allocSize, sizeof(char)); 13 | char *oldBuff; 14 | fgets(buffer, allocSize, stdin); 15 | for (i = 0; i < 50; i++) { 16 | oldBuff = buffer; 17 | buffer = GetLookAndSay(buffer, &allocSize); 18 | free(oldBuff); 19 | //printf("Buffer: %s\n", buffer); 20 | } 21 | printf("Final strlen: %lu\n", strlen(buffer)); 22 | return 0; 23 | } 24 | 25 | char *GetLookAndSay(char *in, long long *strAllocSize) 26 | { 27 | char curChar, curCount, tmpChar; 28 | int i; 29 | char *newStr = calloc(*strAllocSize, sizeof(char)); 30 | curChar = *in; 31 | curCount = 0; 32 | long long endlength = strlen(in)+1; 33 | long long strLength = 0; 34 | for (i = 0; i < endlength && curChar >= 0; i++) { 35 | tmpChar = *(in+i); 36 | //printf("Char is: %c\n", tmpChar); 37 | if (tmpChar != curChar || tmpChar == '\n') { 38 | //printf("Char change! Resetting\n"); 39 | newStr = AddToString(newStr, strLength, strAllocSize, 40 | '0' + curCount, curChar); 41 | strLength += 2; 42 | curCount = 0; 43 | curChar = tmpChar == '\n' ? -1 : tmpChar; 44 | } 45 | if (tmpChar == curChar) { 46 | curCount++; 47 | } 48 | } 49 | return newStr; 50 | } 51 | 52 | char *AddToString(char *str, long long strLength, long long *strAllocSize, 53 | char char1, char char2) 54 | { 55 | if (strLength + 3 >= *strAllocSize) { 56 | ////printf("Alloc size before: %d\n", *strAllocSize); 57 | *strAllocSize *= 2; 58 | ////printf("Alloc size after: %d\n", *strAllocSize); 59 | str = realloc(str, sizeof(char)*(*strAllocSize)); 60 | if (!str) { 61 | fprintf(stderr, "Out of memory for string!\n"); 62 | exit(1); 63 | } 64 | ////printf("Ended realloc\n"); 65 | } 66 | if (str) { 67 | unsigned long long len = strLength; 68 | *(str+len) = char1; 69 | *(str+len+1) = char2; 70 | *(str+len+2) = 0; 71 | } 72 | return str; 73 | } 74 | 75 | -------------------------------------------------------------------------------- /day11/p1a.rs: -------------------------------------------------------------------------------- 1 | #![feature(io)] 2 | 3 | use std::io::{self, Read}; 4 | 5 | fn has_run(pass: &Vec) -> bool { 6 | let mut run_length = 1; 7 | let mut prev_val = pass[0]; 8 | 9 | for i in pass.iter().skip(1) { 10 | if *i == prev_val + 1 { 11 | run_length += 1; 12 | } else { 13 | run_length = 1; 14 | } 15 | 16 | if run_length >= 3 { 17 | return true; 18 | } 19 | 20 | prev_val = *i; 21 | } 22 | 23 | false 24 | } 25 | fn has_pairs(pass: &Vec) -> bool { 26 | let min_find = pass.windows(2) 27 | .enumerate() 28 | .filter(|&(_, p)| p[0] == p[1]) 29 | .min_by_key(|&(i, _)| i) 30 | .map(|(i, _)| i) 31 | .unwrap_or(0); 32 | let max_find = pass.windows(2) 33 | .enumerate() 34 | .filter(|&(_, p)| p[0] == p[1]) 35 | .max_by_key(|&(i, _)| i) 36 | .map(|(i, _)| i) 37 | .unwrap_or(0); 38 | 39 | (max_find - min_find) >= 2 40 | } 41 | 42 | fn passing(pass: &Vec) -> bool { 43 | has_run(pass) && has_pairs(pass) 44 | } 45 | fn increment_pass(pass: &mut Vec) { 46 | for i in 0..pass.len() { 47 | let i = pass.len() - i - 1; 48 | 49 | pass[i] = pass[i] + 1; 50 | 51 | if pass[i] == 'i' as u8 || pass[i] == 'o' as u8 || pass[i] == 'l' as u8 { 52 | pass[i] += 1; 53 | } 54 | 55 | if pass[i] >= 26 { 56 | pass[i] = 0; 57 | } else { 58 | break; 59 | } 60 | } 61 | } 62 | 63 | fn main() { 64 | let stdin = io::stdin(); 65 | let stdin = stdin.lock(); 66 | 67 | let mut current_pass = stdin.chars() 68 | .map(|c| c.expect("reading from stdin should succeed") as u8 - 'a' as u8) 69 | .collect::>(); 70 | 71 | while !passing(¤t_pass) { 72 | increment_pass(&mut current_pass); 73 | } 74 | 75 | println!("Pass: {}", String::from_utf8(current_pass.into_iter() 76 | .map(|c| c + 'a' as u8) 77 | .collect::>()).unwrap()); 78 | } 79 | -------------------------------------------------------------------------------- /day06/p2a.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | // By Garrett Greenwood 3 | // Dec 2015 4 | // electricexploits.net 5 | 6 | var fs = require('fs'); 7 | 8 | var re_off = /^turn off/; 9 | var re_on = /^turn on/; 10 | var re_toggle = /^toggle/; 11 | 12 | var re_numbers = /(\d+)[^\d]+?(\d+)[^\d]+?(\d+)[^\d]+?(\d+)/; 13 | 14 | function setLights(arr, coords, value) { 15 | var lowX = Math.min(coords[0], coords[2]); 16 | var highX = Math.max(coords[0], coords[2]); 17 | var lowY = Math.min(coords[1], coords[3]); 18 | var highY = Math.max(coords[1], coords[3]); 19 | for(var x = lowX; x <= highX; x++) { 20 | for(var y = lowY; y <= highY; y++) { 21 | arr[x][y] = Math.max(0, arr[x][y] + value); 22 | } 23 | } 24 | } 25 | 26 | fs.readFile(process.argv[2], 'utf8', function(err, data) { 27 | if(err) { 28 | console.log("Error reading file"); 29 | return; 30 | } 31 | 32 | lines = data.split("\n"); 33 | lines = lines.slice(0, lines.length - 1); // Cut the last newline out 34 | 35 | // Build the array of lights 36 | var arr = []; 37 | for(var x = 0; x < 1000; x++) { 38 | arr.push([]); 39 | for(var y = 0; y < 1000; y++) { 40 | arr[x].push(0); 41 | } 42 | } 43 | console.log("Lights initialized"); 44 | 45 | console.log("Computing inputs..."); 46 | for(var x = 0; x < lines.length; x++) { 47 | var line = lines[x]; 48 | var coords = re_numbers.exec(line).slice(1,5); 49 | if(re_off.exec(line)) { 50 | setLights(arr, coords, -1); 51 | } else if(re_on.exec(line)) { 52 | setLights(arr, coords, 1); 53 | } else if(re_toggle.exec(line)) { 54 | setLights(arr, coords, 2); 55 | } else { 56 | console.log(line + " NOT RECOGNIZED"); 57 | } 58 | } 59 | console.log("Computed inputs"); 60 | 61 | var count = 0; 62 | console.log("Counting lights..."); 63 | for(var x = 0; x < 1000; x++) { 64 | count += arr[x].reduce(function(a,b) { 65 | return a+b; 66 | }); 67 | } 68 | console.log(count); 69 | }); 70 | -------------------------------------------------------------------------------- /day16/p1a.java: -------------------------------------------------------------------------------- 1 | package adventofcode; 2 | 3 | import java.io.File; 4 | import java.io.FileNotFoundException; 5 | import java.util.Scanner; 6 | 7 | public class p1a { 8 | 9 | static int[] properties = {3, 7, 2, 3, 0, 0, 5, 3, 2, 1}; 10 | 11 | static boolean identifyAunt(String input){ 12 | String[] params = input.split(" "); 13 | 14 | int[] index = {indexProperties(params[2]), indexProperties(params[4]), indexProperties(params[6])}; 15 | int[] values = {Integer.parseInt(params[3].substring(0, 1)), Integer.parseInt(params[5].substring(0, 1)), Integer.parseInt(params[7])}; 16 | 17 | boolean isAunt = true; 18 | 19 | for(int i = 0; i < 3; i++){ 20 | if(!(properties[index[i]] == values[i])){ 21 | isAunt = false; 22 | } 23 | } 24 | return isAunt; 25 | } 26 | 27 | static int indexProperties(String property){ 28 | switch(property){ 29 | case "children:": 30 | return 0; 31 | case "cats:": 32 | return 1; 33 | case "samoyeds:": 34 | return 2; 35 | case "pomeranians:": 36 | return 3; 37 | case "akitas:": 38 | return 4; 39 | case "vizslas:": 40 | return 5; 41 | case "goldfish:": 42 | return 6; 43 | case "trees:": 44 | return 7; 45 | case "cars:": 46 | return 8; 47 | case "perfumes:": 48 | return 9; 49 | default: 50 | return -1; 51 | } 52 | } 53 | 54 | public static void main(String[] args) throws FileNotFoundException{ 55 | 56 | Scanner s = new Scanner(new File("input")); 57 | 58 | int aunt = 1; 59 | 60 | while(s.hasNext()){ 61 | if(identifyAunt(s.nextLine())){ 62 | break; 63 | } 64 | else{ 65 | aunt++; 66 | } 67 | } 68 | 69 | System.out.println("Aunt Sue " + aunt + " sent you the gift."); 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /day06/p1a.rs: -------------------------------------------------------------------------------- 1 | use std::io::{self, BufRead}; 2 | 3 | enum Command { 4 | TurnOn, Toggle, TurnOff 5 | } 6 | 7 | fn parse_tuple(tup: &str) -> (u32, u32) { 8 | let split = tup.find(',') 9 | .expect("the input should be properly formatted"); 10 | 11 | (tup[0..split].parse().expect("the input should be properly formatted"), 12 | tup[split + 1..].parse().expect("the input should be properly formatted")) 13 | } 14 | fn parse_command(line: &str) -> (Command, (u32, u32), (u32, u32)) { 15 | let split_start = line.find(" through ") 16 | .expect("the input should be properly formatted"); 17 | let split_end = split_start + 9; 18 | 19 | if &line[0..7] == "turn on" { 20 | (Command::TurnOn, 21 | parse_tuple(&line[8..split_start]), 22 | parse_tuple(&line[split_end..])) 23 | } else if &line[0..6] == "toggle" { 24 | (Command::Toggle, 25 | parse_tuple(&line[7..split_start]), 26 | parse_tuple(&line[split_end..])) 27 | } else if &line[0..8] == "turn off" { 28 | (Command::TurnOff, 29 | parse_tuple(&line[9..split_start]), 30 | parse_tuple(&line[split_end..])) 31 | } else { 32 | panic!("the input should be correctly formatted") 33 | } 34 | } 35 | 36 | fn main() { 37 | let stdin = io::stdin(); 38 | let stdin = stdin.lock(); 39 | 40 | let mut lights = vec![false; 1_000_000]; 41 | 42 | for line in stdin.lines() { 43 | let line = line.expect("reading from stdin should succeed"); 44 | 45 | let (command, min, max) = parse_command(&line); 46 | 47 | for x in min.0 .. max.0 + 1 { 48 | for y in min.1 .. max.1 + 1 { 49 | let idx = x as usize * 1000 + y as usize; 50 | 51 | match command { 52 | Command::TurnOn => lights[idx] = true, 53 | Command::Toggle => lights[idx] = !lights[idx], 54 | Command::TurnOff => lights[idx] = false, 55 | } 56 | } 57 | } 58 | } 59 | 60 | let num_lit = lights.into_iter() 61 | .fold(0, |amt, b| if b { amt + 1 } else { amt }); 62 | println!("Lit: {}", num_lit); 63 | } 64 | -------------------------------------------------------------------------------- /day05/p2a.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #define BUFFER 80 5 | 6 | char strNice(char *); 7 | int sortSet(const void *, const void *); 8 | char hasRepeatPair(char **, unsigned int); 9 | 10 | int main(void) 11 | { 12 | char str[BUFFER]; 13 | unsigned long niceStrs = 0; 14 | while ((fgets(str, BUFFER, stdin) != NULL)) { 15 | strtok(str, "\n"); 16 | niceStrs += strNice(str); 17 | } 18 | printf("Nice strings: %lu\n", niceStrs); 19 | return 0; 20 | } 21 | 22 | char strNice(char *str) 23 | { 24 | char **sets; 25 | int i, j; 26 | char lastChar; 27 | char withSeparation = 0, hasRepeat = 0; 28 | lastChar = 0; 29 | unsigned char length = strlen(str)-1; 30 | if (!(sets = (char **) malloc(length*sizeof(char *)))) { 31 | fprintf(stderr, "Unable to allocate memory.\n"); 32 | } 33 | for (i = 0; i < length; i++) { 34 | if (!(sets[i] = (char *) malloc(3*sizeof(char)))) { 35 | fprintf(stderr, "Unable to allocate memory.\n"); 36 | goto freemem; 37 | } 38 | } 39 | 40 | for (j = 0; j < length; j++) { 41 | sets[j][0] = str[j]; 42 | sets[j][1] = str[j+1]; 43 | sets[j][2] = j; 44 | if (str[j+1] == lastChar) { 45 | withSeparation = 1; 46 | } 47 | lastChar = str[j]; 48 | } 49 | 50 | hasRepeat = hasRepeatPair(sets, length); 51 | 52 | freemem: 53 | while (i > 0) { 54 | free(sets[--i]); 55 | } 56 | free(sets); 57 | return withSeparation && hasRepeat; 58 | } 59 | 60 | char hasRepeatPair(char **sets, unsigned int length) 61 | { 62 | unsigned int j, k, hasRepeat = 0; 63 | qsort(sets, length, sizeof(char*), sortSet); 64 | for (j = 0; j < length-1; j++) { 65 | for (k = j+1; k < length && !sortSet(&sets[j], &sets[k]) ; k++) { 66 | if ( sets[j][2]-1 != sets[k][2] && 67 | sets[j][2] != sets[k][2]-1) { 68 | hasRepeat = 1; 69 | } 70 | } 71 | } 72 | return hasRepeat; 73 | } 74 | 75 | int sortSet(const void *a, const void *b) 76 | { 77 | const char *valA = *(const char **)a; 78 | const char *valB = *(const char **)b; 79 | unsigned char i; 80 | for (i = 0; i < 2; i++) { 81 | if (valA[i] > valB[i]) { 82 | return 1; 83 | } else if (valA[i] < valB[i]) { 84 | return -1; 85 | } 86 | } 87 | return 0; 88 | } 89 | -------------------------------------------------------------------------------- /day06/p2a.rs: -------------------------------------------------------------------------------- 1 | use std::cmp::max as max_f; 2 | use std::io::{self, BufRead}; 3 | 4 | enum Command { 5 | TurnOn, Toggle, TurnOff 6 | } 7 | 8 | fn parse_tuple(tup: &str) -> (u32, u32) { 9 | let split = tup.find(',') 10 | .expect("the input should be properly formatted"); 11 | 12 | (tup[0..split].parse().expect("the input should be properly formatted"), 13 | tup[split + 1..].parse().expect("the input should be properly formatted")) 14 | } 15 | fn parse_command(line: &str) -> (Command, (u32, u32), (u32, u32)) { 16 | let split_start = line.find(" through ") 17 | .expect("the input should be properly formatted"); 18 | let split_end = split_start + 9; 19 | 20 | if &line[0..7] == "turn on" { 21 | (Command::TurnOn, 22 | parse_tuple(&line[8..split_start]), 23 | parse_tuple(&line[split_end..])) 24 | } else if &line[0..6] == "toggle" { 25 | (Command::Toggle, 26 | parse_tuple(&line[7..split_start]), 27 | parse_tuple(&line[split_end..])) 28 | } else if &line[0..8] == "turn off" { 29 | (Command::TurnOff, 30 | parse_tuple(&line[9..split_start]), 31 | parse_tuple(&line[split_end..])) 32 | } else { 33 | panic!("the input should be correctly formatted") 34 | } 35 | } 36 | 37 | fn main() { 38 | let stdin = io::stdin(); 39 | let stdin = stdin.lock(); 40 | 41 | let mut lights = vec![0i64; 1_000_000]; 42 | 43 | for line in stdin.lines() { 44 | let line = line.expect("reading from stdin should succeed"); 45 | 46 | let (command, min, max) = parse_command(&line); 47 | 48 | for x in min.0 .. max.0 + 1 { 49 | for y in min.1 .. max.1 + 1 { 50 | let idx = x as usize * 1000 + y as usize; 51 | 52 | match command { 53 | Command::TurnOn => lights[idx] += 1, 54 | Command::Toggle => lights[idx] += 2, 55 | Command::TurnOff => lights[idx] = max_f(0, lights[idx] - 1), 56 | } 57 | } 58 | } 59 | } 60 | 61 | let brightness = lights.into_iter() 62 | .fold(0, |amt, n| amt + n); 63 | println!("Brightness: {}", brightness); 64 | } 65 | -------------------------------------------------------------------------------- /day11/p1a.hs: -------------------------------------------------------------------------------- 1 | {-# Language BangPatterns #-} 2 | 3 | import Data.Function (fix) 4 | import Data.Char (isSpace) 5 | import Data.List (groupBy, group, isPrefixOf, tails) 6 | import Control.Arrow 7 | import Debug.Trace 8 | 9 | stepPassword :: String -> String 10 | stepPassword [] = [] 11 | stepPassword (x:xs) 12 | | x == 'z' = 'a' : stepPassword xs 13 | | otherwise = succ x : xs 14 | 15 | validPassword :: [(String -> Bool)] -> String -> Bool 16 | validPassword functions str = and . map ($ str) $ functions 17 | 18 | nextPassword :: [(String -> Bool)] -> String -> String 19 | nextPassword functions = head . filter (validPassword functions) . map reverse . iterate stepPassword . stepPassword . reverse 20 | 21 | validFunctions1 :: [(String -> Bool)] 22 | validFunctions1 = [straight, not . containsForbidden, nPairs 2] 23 | 24 | straight :: String -> Bool 25 | straight = or . map isStraight . windows 3 26 | where 27 | isStraight [_] = True 28 | isStraight [] = True 29 | isStraight (x:y:xs) 30 | | y == succ x = isStraight (y:xs) 31 | | otherwise = False 32 | 33 | containsForbidden :: String -> Bool 34 | containsForbidden str = and . map ($ str) $ [('i' `elem`), ('o' `elem`), ('l' `elem`)] 35 | 36 | nPairs :: Int -> String -> Bool 37 | nPairs n = (>= 2) . length . filter ((>= 2) . length) . splitLarge n . group 38 | where 39 | splitLarge :: Show a => Int -> [[a]] -> [[a]] 40 | splitLarge n list = concat . fix (splitLarge' n) . map (: []) $ list 41 | splitLarge' :: Show a => Int -> ([[[a]]] -> [[[a]]]) -> [[[a]]] -> [[[a]]] 42 | splitLarge' n rec listOfLists = if all (all ((<= n) . length)) listOfLists 43 | then listOfLists 44 | else rec . map ($ concat listOfLists) $ [filter (not . null) . map (take n), filter (not . null) . map (drop n)] 45 | 46 | -- Modified from pavolzetor's solution. 47 | windows :: Int -> [a] -> [[a]] 48 | windows n = filter (\x -> length x == n) . map (take n) . tails 49 | 50 | strip :: String -> String 51 | strip = rstrip . lstrip 52 | where 53 | lstrip = dropWhile isSpace 54 | rstrip = reverse . lstrip . reverse 55 | 56 | main = interact $ (!! 1) . iterate (nextPassword validFunctions1) . strip 57 | -------------------------------------------------------------------------------- /day11/p2a.hs: -------------------------------------------------------------------------------- 1 | {-# Language BangPatterns #-} 2 | 3 | import Data.Function (fix) 4 | import Data.Char (isSpace) 5 | import Data.List (groupBy, group, isPrefixOf, tails) 6 | import Control.Arrow 7 | import Debug.Trace 8 | 9 | stepPassword :: String -> String 10 | stepPassword [] = [] 11 | stepPassword (x:xs) 12 | | x == 'z' = 'a' : stepPassword xs 13 | | otherwise = succ x : xs 14 | 15 | validPassword :: [(String -> Bool)] -> String -> Bool 16 | validPassword functions str = and . map ($ str) $ functions 17 | 18 | nextPassword :: [(String -> Bool)] -> String -> String 19 | nextPassword functions = head . filter (validPassword functions) . map reverse . iterate stepPassword . stepPassword . reverse 20 | 21 | validFunctions1 :: [(String -> Bool)] 22 | validFunctions1 = [straight, not . containsForbidden, nPairs 2] 23 | 24 | straight :: String -> Bool 25 | straight = or . map isStraight . windows 3 26 | where 27 | isStraight [_] = True 28 | isStraight [] = True 29 | isStraight (x:y:xs) 30 | | y == succ x = isStraight (y:xs) 31 | | otherwise = False 32 | 33 | containsForbidden :: String -> Bool 34 | containsForbidden str = and . map ($ str) $ [('i' `elem`), ('o' `elem`), ('l' `elem`)] 35 | 36 | nPairs :: Int -> String -> Bool 37 | nPairs n = (>= 2) . length . filter ((>= 2) . length) . splitLarge n . group 38 | where 39 | splitLarge :: Show a => Int -> [[a]] -> [[a]] 40 | splitLarge n list = concat . fix (splitLarge' n) . map (: []) $ list 41 | splitLarge' :: Show a => Int -> ([[[a]]] -> [[[a]]]) -> [[[a]]] -> [[[a]]] 42 | splitLarge' n rec listOfLists = if all (all ((<= n) . length)) listOfLists 43 | then listOfLists 44 | else rec . map ($ concat listOfLists) $ [filter (not . null) . map (take n), filter (not . null) . map (drop n)] 45 | 46 | -- Modified from pavolzetor's solution. 47 | windows :: Int -> [a] -> [[a]] 48 | windows n = filter (\x -> length x == n) . map (take n) . tails 49 | 50 | strip :: String -> String 51 | strip = rstrip . lstrip 52 | where 53 | lstrip = dropWhile isSpace 54 | rstrip = reverse . lstrip . reverse 55 | 56 | main = interact $ (!! 2) . iterate (nextPassword validFunctions1) . strip 57 | -------------------------------------------------------------------------------- /day03/p1a.java: -------------------------------------------------------------------------------- 1 | package adventofcode; 2 | 3 | import java.io.File; 4 | import java.io.FileNotFoundException; 5 | import java.util.Scanner; 6 | 7 | public class p1a { 8 | 9 | static boolean[][] quad1 = new boolean[2048][2048]; 10 | static boolean[][] quad2 = new boolean[2048][2048]; 11 | static boolean[][] quad3 = new boolean[2048][2048]; 12 | static boolean[][] quad4 = new boolean[2048][2048]; 13 | static int x = 0; 14 | static int y = 0; 15 | 16 | public static boolean moveSanta(String direction){ 17 | switch(direction){ 18 | case "^": 19 | y++; 20 | break; 21 | case ">": 22 | x++; 23 | break; 24 | case "<": 25 | x--; 26 | break; 27 | case "v": 28 | y--; 29 | break; 30 | } 31 | if(x > -1 && y > -1){ 32 | if(!quad1[x][y]){ 33 | quad1[x][y] = true; 34 | return true; 35 | } 36 | } 37 | else if(x > -1 && y < 0){ 38 | if(!quad2[x][-y]){ 39 | quad2[x][-y] = true; 40 | return true; 41 | } 42 | } 43 | else if(x < 0 && y < 0){ 44 | if(!quad3[-x][-y]){ 45 | quad3[-x][-y] = true; 46 | return true; 47 | } 48 | } 49 | else if(x < 0 && y > -1){ 50 | if(!quad4[-x][y]){ 51 | quad4[-x][y] = true; 52 | return true; 53 | } 54 | } 55 | else{ 56 | System.out.println("Unhandled case: x = " + x + ", y = " + y); 57 | } 58 | return false; 59 | } 60 | 61 | public static void main(String[] args) throws FileNotFoundException{ 62 | int total = 1; 63 | quad1[0][0] = true; 64 | 65 | Scanner s = new Scanner(new File("input")); 66 | s.useDelimiter(""); 67 | 68 | while(s.hasNext()){ 69 | if(moveSanta(s.next())){ 70 | total++; 71 | } 72 | } 73 | 74 | System.out.println("Total number of houses visited: " + total); 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /day19/p2a.rs: -------------------------------------------------------------------------------- 1 | #![feature(negate_unsigned)] 2 | 3 | use std::collections::HashMap; 4 | use std::io::{self, BufRead}; 5 | 6 | fn parse_language(language: &[String]) -> HashMap> { 7 | let mut res = HashMap::new(); 8 | 9 | for item in language.iter() { 10 | let split = item.find(" => ").unwrap(); 11 | res.entry(item[0..split].to_owned()) 12 | .or_insert_with(Vec::new) 13 | .push(item[split + 4..].to_owned()); 14 | } 15 | 16 | res 17 | } 18 | 19 | fn path_len(language: &HashMap>, current: String, num_replacements: usize, lowest_replacements: &mut usize, seen: &mut HashMap) { 20 | if num_replacements > *seen.get(¤t).unwrap_or(&-1) || num_replacements > *lowest_replacements { 21 | return 22 | } 23 | seen.insert(current.clone(), num_replacements); 24 | 25 | for (grapheme, replacements) in language.iter() { 26 | for replacement in replacements { 27 | for (idx, _) in current.match_indices(replacement) { 28 | let new_str = current[0..idx].to_owned() + grapheme + ¤t[idx + replacement.len()..]; 29 | if new_str == "e" { 30 | if num_replacements + 1 < *lowest_replacements { 31 | println!("New record set: {}", num_replacements + 1); 32 | *lowest_replacements = num_replacements + 1; 33 | } 34 | } else { 35 | path_len(language, new_str, num_replacements + 1, lowest_replacements, seen); 36 | } 37 | } 38 | } 39 | } 40 | } 41 | 42 | fn main() { 43 | let stdin = io::stdin(); 44 | let stdin = stdin.lock(); 45 | 46 | let (language, input) = stdin.lines() 47 | .map(|line| line.expect("reading from stdin should succeed")) 48 | .partition::, _>(|line| line.find("=>").is_some()); 49 | let language = parse_language(&language); 50 | let ref input = input[1]; 51 | 52 | let mut lowest_replacements = -1; 53 | let mut seen = HashMap::new(); 54 | 55 | path_len(&language, input.clone(), 0, &mut lowest_replacements, &mut seen); 56 | println!("Shortest path: {}", lowest_replacements); 57 | } 58 | -------------------------------------------------------------------------------- /day18/p2a.rs: -------------------------------------------------------------------------------- 1 | #![feature(io, iter_arith)] 2 | 3 | use std::io::{self, Read}; 4 | use std::mem::swap; 5 | 6 | fn neighbors(cells: &[bool], x: i64, y: i64) -> usize { 7 | let mut count = 0; 8 | 9 | for &xoff in [-1, 0, 1].into_iter() { 10 | for &yoff in [-1, 0, 1].into_iter() { 11 | if xoff == 0 && yoff == 0 { 12 | continue; 13 | } 14 | if (xoff < 0 && x <= 0) || (xoff > 0 && x >= 99) { 15 | continue; 16 | } 17 | if (yoff < 0 && y <= 0) || (yoff > 0 && y >= 99) { 18 | continue; 19 | } 20 | 21 | if cells[(x + xoff) as usize * 100 + (y + yoff) as usize] { 22 | count += 1; 23 | } 24 | } 25 | } 26 | 27 | count 28 | } 29 | fn game_of_life(cells: &[bool], buffer: &mut [bool]) { 30 | for x in 0..100 { 31 | for y in 0..100 { 32 | let num_neighbors = neighbors(cells, x, y); 33 | 34 | let loc: usize = x as usize * 100 + y as usize; 35 | if cells[loc] { 36 | buffer[loc] = num_neighbors == 2 || num_neighbors == 3; 37 | } else { 38 | buffer[loc] = num_neighbors == 3; 39 | } 40 | } 41 | } 42 | 43 | buffer[0 * 100 + 0] = true; 44 | buffer[99 * 100 + 0] = true; 45 | buffer[0 * 100 + 99] = true; 46 | buffer[99 * 100 + 99] = true; 47 | } 48 | 49 | fn main() { 50 | let stdin = io::stdin(); 51 | let stdin = stdin.lock(); 52 | 53 | let mut cells = Vec::with_capacity(100 * 100); 54 | for c in stdin.chars() { 55 | match c.expect("reading from stdin should succeed") { 56 | '#' => cells.push(true), 57 | '.' => cells.push(false), 58 | _ => {}, 59 | } 60 | } 61 | let mut buffer = vec![false; 100 * 100]; 62 | 63 | cells[0 * 100 + 0] = true; 64 | cells[99 * 100 + 0] = true; 65 | cells[0 * 100 + 99] = true; 66 | cells[99 * 100 + 99] = true; 67 | 68 | for _ in 0..100 { 69 | game_of_life(&cells, &mut buffer); 70 | swap(&mut cells, &mut buffer); 71 | } 72 | 73 | let count = cells.into_iter().map(|b| if b { 1 } else { 0 }).sum::(); 74 | println!("Count: {}", count); 75 | } 76 | -------------------------------------------------------------------------------- /day05/p1a.java: -------------------------------------------------------------------------------- 1 | package adventofcode; 2 | 3 | import java.io.File; 4 | import java.io.FileNotFoundException; 5 | import java.util.Scanner; 6 | 7 | public class p1a { 8 | 9 | public static boolean isNice(String s){ 10 | char[] tester = s.toCharArray(); 11 | 12 | int vowels = 0; 13 | 14 | boolean threeVowels; 15 | boolean letterPair = false; 16 | 17 | for(int i = 0; i < tester.length; i++){ 18 | if(tester[i] == 'a' || tester[i] == 'e' || tester[i] == 'i' || tester[i] == 'o' || tester[i] == 'u'){ 19 | vowels++; 20 | } 21 | 22 | if(i < tester.length - 1){ 23 | if(tester[i] == tester[i + 1]){ 24 | letterPair = true; 25 | } 26 | 27 | switch(tester[i]){ 28 | case 'a': 29 | if(tester[i + 1] == 'b'){ 30 | return false; 31 | } 32 | break; 33 | case 'c': 34 | if(tester[i + 1] == 'd'){ 35 | return false; 36 | } 37 | break; 38 | case 'p': 39 | if(tester[i + 1] == 'q'){ 40 | return false; 41 | } 42 | break; 43 | case 'x': 44 | if(tester[i + 1] == 'y'){ 45 | return false; 46 | } 47 | break; 48 | } 49 | } 50 | } 51 | 52 | threeVowels = vowels > 2; 53 | 54 | return threeVowels && letterPair; 55 | } 56 | 57 | public static void main(String[] args) throws FileNotFoundException, InterruptedException{ 58 | 59 | int count = 0; 60 | 61 | Scanner s = new Scanner(new File("input")); 62 | 63 | while(s.hasNext()){ 64 | if(isNice(s.nextLine())){ 65 | count++; 66 | } 67 | } 68 | 69 | System.out.println("There are " + count + " nice strings."); 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /day11/p2a.rs: -------------------------------------------------------------------------------- 1 | #![feature(io)] 2 | 3 | use std::io::{self, Read}; 4 | 5 | fn has_run(pass: &Vec) -> bool { 6 | let mut run_length = 1; 7 | let mut prev_val = pass[0]; 8 | 9 | for i in pass.iter().skip(1) { 10 | if *i == prev_val + 1 { 11 | run_length += 1; 12 | } else { 13 | run_length = 1; 14 | } 15 | 16 | if run_length >= 3 { 17 | return true; 18 | } 19 | 20 | prev_val = *i; 21 | } 22 | 23 | false 24 | } 25 | fn has_pairs(pass: &Vec) -> bool { 26 | let min_find = pass.windows(2) 27 | .enumerate() 28 | .filter(|&(_, p)| p[0] == p[1]) 29 | .min_by_key(|&(i, _)| i) 30 | .map(|(i, _)| i) 31 | .unwrap_or(0); 32 | let max_find = pass.windows(2) 33 | .enumerate() 34 | .filter(|&(_, p)| p[0] == p[1]) 35 | .max_by_key(|&(i, _)| i) 36 | .map(|(i, _)| i) 37 | .unwrap_or(0); 38 | 39 | (max_find - min_find) >= 2 40 | } 41 | 42 | fn passing(pass: &Vec) -> bool { 43 | has_run(pass) && has_pairs(pass) 44 | } 45 | fn increment_pass(pass: &mut Vec) { 46 | for i in 0..pass.len() { 47 | let i = pass.len() - i - 1; 48 | 49 | pass[i] = pass[i] + 1; 50 | 51 | if pass[i] == 'i' as u8 || pass[i] == 'o' as u8 || pass[i] == 'l' as u8 { 52 | pass[i] += 1; 53 | } 54 | 55 | if pass[i] >= 26 { 56 | pass[i] = 0; 57 | } else { 58 | break; 59 | } 60 | } 61 | } 62 | 63 | fn main() { 64 | let stdin = io::stdin(); 65 | let stdin = stdin.lock(); 66 | 67 | let mut current_pass = stdin.chars() 68 | .map(|c| c.expect("reading from stdin should succeed") as u8 - 'a' as u8) 69 | .collect::>(); 70 | 71 | while !passing(¤t_pass) { 72 | increment_pass(&mut current_pass); 73 | } 74 | 75 | increment_pass(&mut current_pass); 76 | 77 | while !passing(¤t_pass) { 78 | increment_pass(&mut current_pass); 79 | } 80 | 81 | println!("Pass: {}", String::from_utf8(current_pass.into_iter() 82 | .map(|c| c + 'a' as u8) 83 | .collect::>()).unwrap()); 84 | } 85 | -------------------------------------------------------------------------------- /day05/p1a.hs: -------------------------------------------------------------------------------- 1 | {-# Language BangPatterns #-} 2 | 3 | import Data.List (findIndices, transpose, sort, group, groupBy, isPrefixOf, isInfixOf, subsequences) 4 | import Data.List.Split (chunksOf) 5 | import Control.Arrow 6 | 7 | countNice :: [(String -> Bool)] -> [String] -> Int 8 | countNice functions = length . filter (== True) . map (isNice functions) 9 | 10 | isNice :: [(String -> Bool)] -> String -> Bool 11 | isNice functions str = and . map ($ str) $ functions 12 | 13 | niceFunctions1 :: [(String -> Bool)] 14 | niceFunctions1 = [hasThreeVowels, hasDouble, not . hasForbiddenLetter] 15 | 16 | niceFunctions2 :: [(String -> Bool)] 17 | niceFunctions2 = [nPairs 2, hasPalindrome3] 18 | 19 | hasThreeVowels :: String -> Bool 20 | hasThreeVowels = (>= 3) . length . filter (`elem` ['a','e','i','o','u']) 21 | 22 | hasDouble :: Eq a => [a] -> Bool 23 | hasDouble = (>= 2) . maximum . map length . group 24 | 25 | hasForbiddenLetter :: String -> Bool 26 | hasForbiddenLetter str = or . map ($ str) $ isInfixOf <$> ["ab","cd", "pq", "xy"] 27 | 28 | nPairs :: Int -> String -> Bool 29 | nPairs n str = not . null . filter ((>= n) . length . map dropHalf . groupBy adjacent . snd) . map (id &&& (`substrIndices` str)) . uniques . filter (`isInfixOf` str) . filter ((== 2) . length) . subsequences $ str 30 | where 31 | differences ((!x):(!y):xs) = y - x : differences (y:xs) 32 | differences (_:[]) = [] 33 | differences [] = [] 34 | 35 | substrIndices :: Eq a => [a] -> [a] -> [Int] 36 | substrIndices = substrIndices' 0 37 | substrIndices' :: Eq a => Int -> [a] -> [a] -> [Int] 38 | substrIndices' _ [] _ = [] 39 | substrIndices' _ _ [] = [] 40 | substrIndices' n substr str@(_:xs) 41 | | length str < length substr = [] 42 | | substr `isPrefixOf` str = n : substrIndices' (n + 1) substr xs 43 | | otherwise = substrIndices' (n + 1) substr xs 44 | 45 | adjacent !x !y = succ x == y 46 | 47 | dropHalf xs = let l = length xs in drop (l `div` 2) xs 48 | 49 | hasPalindrome3 :: Eq a => [a] -> Bool 50 | hasPalindrome3 str = or . map (\ str -> str == reverse str) . filter (`isInfixOf` str) . filter ((== 3) . length) . subsequences $ str 51 | 52 | uniques :: Eq a => [a] -> [a] 53 | uniques = map head . group 54 | 55 | main = interact $ show . countNice niceFunctions1 . lines 56 | -------------------------------------------------------------------------------- /day05/p2a.hs: -------------------------------------------------------------------------------- 1 | {-# Language BangPatterns #-} 2 | 3 | import Data.List (findIndices, transpose, sort, group, groupBy, isPrefixOf, isInfixOf, subsequences) 4 | import Data.List.Split (chunksOf) 5 | import Control.Arrow 6 | 7 | countNice :: [(String -> Bool)] -> [String] -> Int 8 | countNice functions = length . filter (== True) . map (isNice functions) 9 | 10 | isNice :: [(String -> Bool)] -> String -> Bool 11 | isNice functions str = and . map ($ str) $ functions 12 | 13 | niceFunctions1 :: [(String -> Bool)] 14 | niceFunctions1 = [hasThreeVowels, hasDouble, not . hasForbiddenLetter] 15 | 16 | niceFunctions2 :: [(String -> Bool)] 17 | niceFunctions2 = [nPairs 2, hasPalindrome3] 18 | 19 | hasThreeVowels :: String -> Bool 20 | hasThreeVowels = (>= 3) . length . filter (`elem` ['a','e','i','o','u']) 21 | 22 | hasDouble :: Eq a => [a] -> Bool 23 | hasDouble = (>= 2) . maximum . map length . group 24 | 25 | hasForbiddenLetter :: String -> Bool 26 | hasForbiddenLetter str = or . map ($ str) $ isInfixOf <$> ["ab","cd", "pq", "xy"] 27 | 28 | nPairs :: Int -> String -> Bool 29 | nPairs n str = not . null . filter ((>= n) . length . map dropHalf . groupBy adjacent . snd) . map (id &&& (`substrIndices` str)) . uniques . filter (`isInfixOf` str) . filter ((== 2) . length) . subsequences $ str 30 | where 31 | differences ((!x):(!y):xs) = y - x : differences (y:xs) 32 | differences (_:[]) = [] 33 | differences [] = [] 34 | 35 | substrIndices :: Eq a => [a] -> [a] -> [Int] 36 | substrIndices = substrIndices' 0 37 | substrIndices' :: Eq a => Int -> [a] -> [a] -> [Int] 38 | substrIndices' _ [] _ = [] 39 | substrIndices' _ _ [] = [] 40 | substrIndices' n substr str@(_:xs) 41 | | length str < length substr = [] 42 | | substr `isPrefixOf` str = n : substrIndices' (n + 1) substr xs 43 | | otherwise = substrIndices' (n + 1) substr xs 44 | 45 | adjacent !x !y = succ x == y 46 | 47 | dropHalf xs = let l = length xs in drop (l `div` 2) xs 48 | 49 | hasPalindrome3 :: Eq a => [a] -> Bool 50 | hasPalindrome3 str = or . map (\ str -> str == reverse str) . filter (`isInfixOf` str) . filter ((== 3) . length) . subsequences $ str 51 | 52 | uniques :: Eq a => [a] -> [a] 53 | uniques = map head . group 54 | 55 | main = interact $ show . countNice niceFunctions2 . lines 56 | -------------------------------------------------------------------------------- /day14/p2a.ex: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env elixir 2 | 3 | # By: Steven Critchfield 4 | # https://github.com/critch 5 | 6 | defmodule Advent14p2 do 7 | def calculate do 8 | big_list = File.stream!("input") |> 9 | Enum.map(fn(x) -> Regex.scan(~r"^([a-zA-Z]+) can fly ([0-9]+) km/s for ([0-9]+) seconds, but then must rest for ([0-9]+) seconds.", x) |> hd |> tl end) |> 10 | Enum.map(fn([ _, speed, dur, rest]) -> 11 | [String.to_integer(speed), String.to_integer(dur), String.to_integer(rest), "moving", 0, 0] 12 | end) |> 13 | Stream.map( fn(x) -> race(x) end) |> Enum.to_list 14 | 15 | distances = List.zip( big_list) |> 16 | Stream.map(fn(x) -> Tuple.to_list(x) end ) |> 17 | Stream.map(fn(x) -> Enum.max(x) end) |> 18 | Enum.to_list 19 | 20 | List.zip([List.zip(big_list), distances]) |> 21 | List.delete_at(0) |> 22 | Enum.reduce([0,0,0,0,0,0,0,0,0], fn(x,acc) -> award_points(x,acc) end) |> 23 | Enum.with_index |> 24 | Enum.max_by( fn(x) -> elem(x,0) end ) |> 25 | elem(0) 26 | end 27 | 28 | def award_points(x,acc) do 29 | { dists, winning_dist } = x 30 | Tuple.to_list(dists) |> 31 | Enum.with_index |> 32 | Enum.reduce( {acc, winning_dist}, fn(z,a) -> { a_p(z,a), elem(a,1)} end ) |> 33 | elem(0) 34 | end 35 | 36 | def a_p(z,a) do 37 | {acc, win } = a 38 | if(elem(z,0) == win) do 39 | List.update_at(acc,elem(z,1), &(&1 + 1)) 40 | else 41 | acc 42 | end 43 | end 44 | def race(x) do 45 | Stream.iterate(x, fn(z) -> move_reindeer(z) end) |> 46 | Stream.map(fn(z) -> List.last(z) end) |> 47 | Enum.take(2503) 48 | end 49 | 50 | def move_reindeer(x) do 51 | [ speed, dur, rest, status, cur_dur, dist] = x 52 | if( status == "moving") do 53 | if(cur_dur == dur) do 54 | # switch to resting 55 | [ speed, dur, rest, "resting", 1, dist ] 56 | else 57 | # move along 58 | [speed, dur, rest, status, cur_dur + 1, dist + speed] 59 | end 60 | else 61 | if( cur_dur == rest ) do 62 | [speed, dur, rest, "moving", 1, dist + speed ] 63 | else 64 | [speed, dur, rest, status, cur_dur + 1, dist ] 65 | end 66 | end 67 | end 68 | end 69 | 70 | IO.puts "Winning points: " <> Integer.to_string(Advent14p2.calculate) 71 | -------------------------------------------------------------------------------- /day16/p2a.rs: -------------------------------------------------------------------------------- 1 | use std::collections::HashMap; 2 | use std::io::{self, BufRead}; 3 | 4 | trait DropLast { 5 | fn drop_last(&self) -> &Self; 6 | } 7 | impl DropLast for str { 8 | fn drop_last(&self) -> &str { 9 | &self[0..self.len() - 1] 10 | } 11 | } 12 | 13 | fn parse_line(line: &str) -> HashMap { 14 | line.split_whitespace().skip(2).collect::>().chunks(2).map(|item| { 15 | let id = item[0].drop_last(); 16 | let val = item[1]; 17 | 18 | (id.to_owned(), (if val.find(',').is_some() { 19 | val.drop_last().parse() 20 | } else { 21 | val.parse() 22 | }).expect("the input should be properly formatted")) 23 | }).collect() 24 | } 25 | 26 | fn main() { 27 | let stdin = io::stdin(); 28 | let stdin = stdin.lock(); 29 | 30 | let mut sue_stats = Vec::new(); 31 | for line in stdin.lines() { 32 | sue_stats.push(parse_line(&line.expect("reading from stdin should succeed"))); 33 | } 34 | 35 | let mut mfcsam_readout = HashMap::new(); 36 | mfcsam_readout.insert("children".to_owned(), 3); 37 | mfcsam_readout.insert("cats".to_owned(), 7); 38 | mfcsam_readout.insert("samoyeds".to_owned(), 2); 39 | mfcsam_readout.insert("pomeranians".to_owned(), 3); 40 | mfcsam_readout.insert("akitas".to_owned(), 0); 41 | mfcsam_readout.insert("vizslas".to_owned(), 0); 42 | mfcsam_readout.insert("goldfish".to_owned(), 5); 43 | mfcsam_readout.insert("trees".to_owned(), 3); 44 | mfcsam_readout.insert("cars".to_owned(), 2); 45 | mfcsam_readout.insert("perfumes".to_owned(), 1); 46 | 47 | let mut matching_sues = sue_stats.into_iter() 48 | .enumerate() 49 | .filter(|&(_, ref stats)| { 50 | stats.into_iter().all(|(k, v)| { 51 | if k == "cats" || k == "trees" { 52 | mfcsam_readout.get(k).unwrap() < v 53 | } else if k == "pomeranians" || k == "goldfish" { 54 | mfcsam_readout.get(k).unwrap() > v 55 | } else { 56 | mfcsam_readout.get(k).unwrap() == v 57 | } 58 | }) 59 | }).map(|(i, stats)| { 60 | (i + 1, stats) 61 | }); 62 | 63 | println!("Sue #: {}", matching_sues.next().unwrap().0); 64 | } 65 | -------------------------------------------------------------------------------- /day05/p1b.hs: -------------------------------------------------------------------------------- 1 | {-# Language BangPatterns #-} 2 | 3 | import Data.List (findIndices, transpose, sort, group, groupBy, isPrefixOf, isInfixOf, subsequences, tails) 4 | import Data.List.Split (chunksOf) 5 | import Control.Arrow 6 | 7 | countNice :: [(String -> Bool)] -> [String] -> Int 8 | countNice functions = length . filter (== True) . map (isNice functions) 9 | 10 | isNice :: [(String -> Bool)] -> String -> Bool 11 | isNice functions str = and . map ($ str) $ functions 12 | 13 | niceFunctions1 :: [(String -> Bool)] 14 | niceFunctions1 = [hasThreeVowels, hasDouble, not . hasForbiddenLetter] 15 | 16 | niceFunctions2 :: [(String -> Bool)] 17 | niceFunctions2 = [nPairs 2, hasPalindrome3] 18 | 19 | hasThreeVowels :: String -> Bool 20 | hasThreeVowels = (>= 3) . length . filter (`elem` ['a','e','i','o','u']) 21 | 22 | hasDouble :: Eq a => [a] -> Bool 23 | hasDouble = (>= 2) . maximum . map length . group 24 | 25 | hasForbiddenLetter :: String -> Bool 26 | hasForbiddenLetter str = or . map ($ str) $ isInfixOf <$> ["ab","cd", "pq", "xy"] 27 | 28 | nPairs :: Int -> String -> Bool 29 | nPairs n str = not . null . filter ((>= n) . length . map dropHalf . groupBy adjacent . snd) . map (id &&& (`substrIndices` str)) . uniques . windows 2 $ str 30 | where 31 | differences ((!x):(!y):xs) = y - x : differences (y:xs) 32 | differences (_:[]) = [] 33 | differences [] = [] 34 | 35 | substrIndices :: Eq a => [a] -> [a] -> [Int] 36 | substrIndices = substrIndices' 0 37 | substrIndices' :: Eq a => Int -> [a] -> [a] -> [Int] 38 | substrIndices' _ [] _ = [] 39 | substrIndices' _ _ [] = [] 40 | substrIndices' n substr str@(_:xs) 41 | | length str < length substr = [] 42 | | substr `isPrefixOf` str = n : substrIndices' (n + 1) substr xs 43 | | otherwise = substrIndices' (n + 1) substr xs 44 | 45 | adjacent !x !y = succ x == y 46 | 47 | dropHalf xs = let l = length xs in drop (l `div` 2) xs 48 | 49 | hasPalindrome3 :: Eq a => [a] -> Bool 50 | hasPalindrome3 str = or . map (\ str -> str == reverse str) . windows 3 $ str 51 | 52 | uniques :: Eq a => [a] -> [a] 53 | uniques = map head . group 54 | 55 | -- Modified from pavolzetor's solution. 56 | windows :: Int -> [a] -> [[a]] 57 | windows n = filter (\x -> length x == n) . map (take n) . tails 58 | 59 | main = interact $ show . countNice niceFunctions1 . lines 60 | -------------------------------------------------------------------------------- /day05/p2b.hs: -------------------------------------------------------------------------------- 1 | {-# Language BangPatterns #-} 2 | 3 | import Data.List (findIndices, transpose, sort, group, groupBy, isPrefixOf, isInfixOf, subsequences, tails) 4 | import Data.List.Split (chunksOf) 5 | import Control.Arrow 6 | 7 | countNice :: [(String -> Bool)] -> [String] -> Int 8 | countNice functions = length . filter (== True) . map (isNice functions) 9 | 10 | isNice :: [(String -> Bool)] -> String -> Bool 11 | isNice functions str = and . map ($ str) $ functions 12 | 13 | niceFunctions1 :: [(String -> Bool)] 14 | niceFunctions1 = [hasThreeVowels, hasDouble, not . hasForbiddenLetter] 15 | 16 | niceFunctions2 :: [(String -> Bool)] 17 | niceFunctions2 = [nPairs 2, hasPalindrome3] 18 | 19 | hasThreeVowels :: String -> Bool 20 | hasThreeVowels = (>= 3) . length . filter (`elem` ['a','e','i','o','u']) 21 | 22 | hasDouble :: Eq a => [a] -> Bool 23 | hasDouble = (>= 2) . maximum . map length . group 24 | 25 | hasForbiddenLetter :: String -> Bool 26 | hasForbiddenLetter str = or . map ($ str) $ isInfixOf <$> ["ab","cd", "pq", "xy"] 27 | 28 | nPairs :: Int -> String -> Bool 29 | nPairs n str = not . null . filter ((>= n) . length . map dropHalf . groupBy adjacent . snd) . map (id &&& (`substrIndices` str)) . uniques . windows 2 $ str 30 | where 31 | differences ((!x):(!y):xs) = y - x : differences (y:xs) 32 | differences (_:[]) = [] 33 | differences [] = [] 34 | 35 | substrIndices :: Eq a => [a] -> [a] -> [Int] 36 | substrIndices = substrIndices' 0 37 | substrIndices' :: Eq a => Int -> [a] -> [a] -> [Int] 38 | substrIndices' _ [] _ = [] 39 | substrIndices' _ _ [] = [] 40 | substrIndices' n substr str@(_:xs) 41 | | length str < length substr = [] 42 | | substr `isPrefixOf` str = n : substrIndices' (n + 1) substr xs 43 | | otherwise = substrIndices' (n + 1) substr xs 44 | 45 | adjacent !x !y = succ x == y 46 | 47 | dropHalf xs = let l = length xs in drop (l `div` 2) xs 48 | 49 | hasPalindrome3 :: Eq a => [a] -> Bool 50 | hasPalindrome3 str = or . map (\ str -> str == reverse str) . windows 3 $ str 51 | 52 | uniques :: Eq a => [a] -> [a] 53 | uniques = map head . group 54 | 55 | -- Modified from pavolzetor's solution. 56 | windows :: Int -> [a] -> [[a]] 57 | windows n = filter (\x -> length x == n) . map (take n) . tails 58 | 59 | main = interact $ show . countNice niceFunctions2 . lines 60 | -------------------------------------------------------------------------------- /day15/p1a.java: -------------------------------------------------------------------------------- 1 | package adventofcode; 2 | 3 | import java.io.File; 4 | import java.io.FileNotFoundException; 5 | import java.util.ArrayList; 6 | import java.util.Scanner; 7 | 8 | public class p1a { 9 | 10 | static ArrayList recipes = new ArrayList<>(); 11 | static int[][] properties = new int[4][5]; 12 | 13 | static{ 14 | for(int a = 0; a <= 100; a++){ 15 | for(int b = 0; b <= 100 - a; b++){ 16 | for(int c = 0; c <= 100 - a - b; c++){ 17 | recipes.add(new Integer[]{a, b, c, 100 - a - b - c}); 18 | } 19 | } 20 | } 21 | } 22 | 23 | static int calculateScore(Integer[] recipe){ 24 | int capacity = 0; 25 | int durability = 0; 26 | int flavor = 0; 27 | int texture = 0; 28 | 29 | for(int i = 0; i < 4; i++){ 30 | capacity += recipe[i] * properties[i][0]; 31 | durability += recipe[i] * properties[i][1]; 32 | flavor += recipe[i] * properties[i][2]; 33 | texture += recipe[i] * properties[i][3]; 34 | } 35 | 36 | if(capacity < 0 || durability < 0 || texture < 0 || flavor < 0){ 37 | return 0; 38 | } 39 | else{ 40 | return capacity * durability * texture * flavor; 41 | } 42 | } 43 | 44 | public static void main(String[] args) throws FileNotFoundException{ 45 | 46 | Scanner s = new Scanner(new File("input")); 47 | 48 | String input; 49 | String[] params; 50 | 51 | for(int i = 0; i < 4; i++){ 52 | input = s.nextLine(); 53 | params = input.split(" "); 54 | properties[i][0] = Integer.parseInt(params[2].replace(",", "")); 55 | properties[i][1] = Integer.parseInt(params[4].replace(",", "")); 56 | properties[i][2] = Integer.parseInt(params[6].replace(",", "")); 57 | properties[i][3] = Integer.parseInt(params[8].replace(",", "")); 58 | } 59 | 60 | int best = 0; 61 | int score; 62 | 63 | for(Integer[] i : recipes){ 64 | score = calculateScore(i); 65 | if(score > best){ 66 | best = score; 67 | } 68 | } 69 | 70 | System.out.println("The best recipe has " + best +" points."); 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /day17/p2a.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #define GOAL_SIZE 150 7 | 8 | struct person { 9 | char *name; 10 | struct animosity *likes; 11 | struct person *next; 12 | }; 13 | 14 | struct animosity { 15 | char *towards; 16 | long amount; 17 | struct animosity *next; 18 | }; 19 | 20 | char *AddToString(char *, long long *, char); 21 | long choose(long *, int, int, int, int); 22 | 23 | int main (void) 24 | { 25 | long long allocSize = 80; 26 | char *buffer = calloc(allocSize, sizeof(char)); 27 | int numAlloced = 2; 28 | long *vals = calloc(1, sizeof(long)); 29 | int numVals = 0; 30 | char c; 31 | while ((c = fgetc(stdin)) && !feof(stdin)){ 32 | if (c == '\n') { // POSIX!!!!!! 33 | vals[numVals++] = strtol(buffer, NULL, 10); 34 | if (numVals >= numAlloced) { 35 | numAlloced *= 2; 36 | vals = realloc(vals, numAlloced*sizeof(long)); 37 | } 38 | memset(buffer, 0, allocSize); 39 | } else { 40 | buffer = AddToString(buffer, &allocSize, c); 41 | } 42 | } 43 | choose(vals, 0, numVals, 0, 0); 44 | printf("Min number: %ld\n", choose(vals, 0, numVals, 0, 0)); 45 | return 0; 46 | } 47 | 48 | char *AddToString(char *str, long long *strAllocSize, char add) 49 | { 50 | long len = strlen(str); 51 | if (len + 2 >= *strAllocSize) { 52 | *strAllocSize *= 2; 53 | str = realloc(str, sizeof(char)*(*strAllocSize)); 54 | if (!str) { 55 | fprintf(stderr, "Out of memory for string!\n"); 56 | exit(1); 57 | } 58 | } 59 | if (str) { 60 | str[len] = add; 61 | str[len+1] = 0; 62 | } 63 | return str; 64 | } 65 | 66 | /* arr is the string, curr is to choose from and size is sizeof the vals */ 67 | long choose(long *vals, int curr, int size, int curTotal, int num) 68 | { 69 | static int smallest = INT_MAX; 70 | long subMatches = 0; 71 | if (curTotal > GOAL_SIZE || num > smallest) { 72 | return 0; 73 | } 74 | if (curTotal == GOAL_SIZE) { 75 | if (num < smallest) { 76 | smallest = num; 77 | } 78 | return 1; 79 | } 80 | if (num == smallest) { 81 | return 0; 82 | } 83 | if (curr == size-1) { // Final condition 84 | if (curTotal + vals[curr] == GOAL_SIZE) { 85 | return 1; 86 | } 87 | return 0; 88 | } 89 | subMatches += choose(vals, curr+1, size, curTotal, num); 90 | subMatches += choose(vals, curr+1, size, curTotal+vals[curr], num+1); 91 | return subMatches; 92 | } 93 | -------------------------------------------------------------------------------- /day19/p2b.rs: -------------------------------------------------------------------------------- 1 | #![feature(negate_unsigned)] 2 | 3 | use std::collections::{BinaryHeap, HashMap, HashSet}; 4 | use std::io::{self, BufRead}; 5 | 6 | fn parse_language(language: &[String]) -> HashMap> { 7 | let mut res = HashMap::new(); 8 | 9 | for item in language.iter() { 10 | let split = item.find(" => ").unwrap(); 11 | res.entry(item[0..split].to_owned()) 12 | .or_insert_with(Vec::new) 13 | .push(item[split + 4..].to_owned()); 14 | } 15 | 16 | res 17 | } 18 | 19 | fn path_len(language: &HashMap>, input: &str) -> usize { 20 | let mut seen = HashSet::new(); 21 | let mut q = BinaryHeap::new(); 22 | q.push((-(input.len() as isize), 0, input.to_owned())); 23 | 24 | let mut lowest_replacements = -1; 25 | while !q.is_empty() { 26 | let (_, num_replacements, current) = q.pop().unwrap(); 27 | 28 | if current == "e" { 29 | // We only add an item to the heap if num_replacements will be < lowest_replacements 30 | lowest_replacements = num_replacements as usize; 31 | println!("Reduced to electron in {} steps", lowest_replacements); 32 | continue; 33 | } 34 | 35 | seen.insert(current.clone()); 36 | 37 | for (grapheme, replacements) in language.iter() { 38 | for replacement in replacements { 39 | for (idx, _) in current.match_indices(replacement) { 40 | let new_str = current[0..idx].to_owned() + grapheme + ¤t[idx + replacement.len()..]; 41 | 42 | if !seen.contains(&new_str) && num_replacements + 1 < lowest_replacements { 43 | q.push((-(new_str.len() as isize), num_replacements + 1, new_str)); 44 | } 45 | } 46 | } 47 | } 48 | } 49 | 50 | lowest_replacements 51 | } 52 | 53 | fn main() { 54 | let stdin = io::stdin(); 55 | let stdin = stdin.lock(); 56 | 57 | let (language, input) = stdin.lines() 58 | .map(|line| line.expect("reading from stdin should succeed")) 59 | .partition::, _>(|line| line.find("=>").is_some()); 60 | let language = parse_language(&language); 61 | let ref input = input[1]; 62 | 63 | let lowest_replacements = path_len(&language, input); 64 | println!("Shortest path: {}", lowest_replacements); 65 | } 66 | -------------------------------------------------------------------------------- /day06/p1a.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | // By Garrett Greenwood 3 | // Dec 2015 4 | // electricexploits.net 5 | 6 | var fs = require('fs'); 7 | 8 | var re_off = /^turn off/; 9 | var re_on = /^turn on/; 10 | var re_toggle = /^toggle/; 11 | 12 | var re_numbers = /(\d+)[^\d]+?(\d+)[^\d]+?(\d+)[^\d]+?(\d+)/; 13 | 14 | function setLights(arr, coords, value) { 15 | var lowX = Math.min(coords[0], coords[2]); 16 | var highX = Math.max(coords[0], coords[2]); 17 | var lowY = Math.min(coords[1], coords[3]); 18 | var highY = Math.max(coords[1], coords[3]); 19 | for(var x = lowX; x <= highX; x++) { 20 | for(var y = lowY; y <= highY; y++) { 21 | arr[x][y] = value; 22 | } 23 | } 24 | } 25 | 26 | function toggleLights(arr, coords) { 27 | var lowX = Math.min(coords[0], coords[2]); 28 | var highX = Math.max(coords[0], coords[2]); 29 | var lowY = Math.min(coords[1], coords[3]); 30 | var highY = Math.max(coords[1], coords[3]); 31 | for(var x = lowX; x <= highX; x++) { 32 | for(var y = lowY; y <= highY; y++) { 33 | arr[x][y] = !arr[x][y]; 34 | } 35 | } 36 | } 37 | 38 | fs.readFile(process.argv[2], 'utf8', function(err, data) { 39 | if(err) { 40 | console.log("Error reading file"); 41 | return; 42 | } 43 | 44 | lines = data.split("\n"); 45 | lines = lines.slice(0, lines.length - 1); // Cut the last newline out 46 | 47 | // Build the array of lights 48 | var arr = []; 49 | for(var x = 0; x < 1000; x++) { 50 | arr.push([]); 51 | for(var y = 0; y < 1000; y++) { 52 | arr[x].push(false); 53 | } 54 | } 55 | console.log("Lights initialized"); 56 | 57 | console.log("Computing inputs..."); 58 | for(var x = 0; x < lines.length; x++) { 59 | var line = lines[x]; 60 | var coords = re_numbers.exec(line).slice(1,5); 61 | if(re_off.exec(line)) { 62 | setLights(arr, coords, false); 63 | } else if(re_on.exec(line)) { 64 | setLights(arr, coords, true); 65 | } else if(re_toggle.exec(line)) { 66 | toggleLights(arr, coords); 67 | } else { 68 | console.log(line + " NOT RECOGNIZED"); 69 | } 70 | } 71 | console.log("Computed inputs"); 72 | 73 | var count = 0; 74 | console.log("Counting lights..."); 75 | for(var x = 0; x < 1000; x++) { 76 | count += arr[x].reduce(function(a,b) { 77 | return a+b; 78 | }); 79 | } 80 | console.log(count); 81 | }); 82 | -------------------------------------------------------------------------------- /day15/p2a.java: -------------------------------------------------------------------------------- 1 | package adventofcode; 2 | 3 | import java.io.File; 4 | import java.io.FileNotFoundException; 5 | import java.util.ArrayList; 6 | import java.util.Scanner; 7 | 8 | public class p1a { 9 | 10 | static ArrayList recipes = new ArrayList<>(); 11 | static int[][] properties = new int[4][5]; 12 | 13 | static{ 14 | for(int a = 0; a <= 100; a++){ 15 | for(int b = 0; b <= 100 - a; b++){ 16 | for(int c = 0; c <= 100 - a - b; c++){ 17 | recipes.add(new Integer[]{a, b, c, 100 - a - b - c}); 18 | } 19 | } 20 | } 21 | } 22 | 23 | static int calculateScore(Integer[] recipe){ 24 | int capacity = 0; 25 | int durability = 0; 26 | int flavor = 0; 27 | int texture = 0; 28 | int calories = 0; 29 | 30 | for(int i = 0; i < 4; i++){ 31 | capacity += recipe[i] * properties[i][0]; 32 | durability += recipe[i] * properties[i][1]; 33 | flavor += recipe[i] * properties[i][2]; 34 | texture += recipe[i] * properties[i][3]; 35 | calories += recipe[i] * properties[i][4]; 36 | } 37 | 38 | if(capacity < 0 || durability < 0 || texture < 0 || flavor < 0 || calories != 500){ 39 | return 0; 40 | } 41 | else{ 42 | return capacity * durability * texture * flavor; 43 | } 44 | } 45 | 46 | public static void main(String[] args) throws FileNotFoundException{ 47 | 48 | Scanner s = new Scanner(new File("input")); 49 | 50 | String input; 51 | String[] params; 52 | 53 | for(int i = 0; i < 4; i++){ 54 | input = s.nextLine(); 55 | params = input.split(" "); 56 | properties[i][0] = Integer.parseInt(params[2].replace(",", "")); 57 | properties[i][1] = Integer.parseInt(params[4].replace(",", "")); 58 | properties[i][2] = Integer.parseInt(params[6].replace(",", "")); 59 | properties[i][3] = Integer.parseInt(params[8].replace(",", "")); 60 | properties[i][4] = Integer.parseInt(params[10]); 61 | } 62 | 63 | int best = 0; 64 | int score; 65 | 66 | for(Integer[] i : recipes){ 67 | score = calculateScore(i); 68 | if(score > best){ 69 | best = score; 70 | } 71 | } 72 | 73 | System.out.println("The best recipe has " + best +" points."); 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /day14/p2a.java: -------------------------------------------------------------------------------- 1 | package adventofcode; 2 | 3 | import java.io.File; 4 | import java.io.FileNotFoundException; 5 | import java.util.Scanner; 6 | 7 | public class p2a { 8 | 9 | static int[][] distances = new int[8][2504]; 10 | 11 | public static void main(String[] args) throws FileNotFoundException{ 12 | 13 | Scanner s = new Scanner(new File("input")); 14 | 15 | String input; 16 | String[] params; 17 | int speed, stamina, rest; 18 | int counter; 19 | boolean flying; 20 | int distance; 21 | 22 | for(int c = 0; c < 8; c++){ 23 | input = s.nextLine(); 24 | 25 | params = input.split(" "); 26 | 27 | speed = Integer.parseInt(params[3]); 28 | stamina = Integer.parseInt(params[6]); 29 | rest = Integer.parseInt(params[13]); 30 | 31 | counter = 0; 32 | flying = true; 33 | distance = 0; 34 | 35 | for(int i = 1; i < 2504; i++){ 36 | if(flying){ 37 | if(counter < stamina){ 38 | distance += speed; 39 | counter++; 40 | } 41 | else if(counter >= stamina){ 42 | flying = false; 43 | counter = 1; 44 | } 45 | } 46 | else{ 47 | if(counter < rest){ 48 | counter++; 49 | } 50 | else if(counter >= rest){ 51 | flying = true; 52 | distance += speed; 53 | counter = 1; 54 | } 55 | } 56 | distances[c][i] = distance; 57 | } 58 | } 59 | 60 | int record = 0; 61 | 62 | for(int i = 1; i < 2504; i++){ 63 | for(int[] j : distances){ 64 | if(j[i] > record){ 65 | record = j[i]; 66 | } 67 | } 68 | for(int[] j : distances){ 69 | if(j[i] == record){ 70 | j[0]++; 71 | } 72 | } 73 | record = 0; 74 | } 75 | 76 | for(int[] i : distances){ 77 | if(i[0] > record){ 78 | record = i[0]; 79 | } 80 | } 81 | 82 | System.out.println("The winning reindeer has " + record +" points."); 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /day06/p1a.java: -------------------------------------------------------------------------------- 1 | package adventofcode; 2 | 3 | import java.io.File; 4 | import java.io.FileNotFoundException; 5 | import java.util.Scanner; 6 | 7 | public class p1a { 8 | 9 | public static boolean[][] lights = new boolean[1000][1000]; 10 | 11 | public static void execute(String s){ 12 | String[] instructions = s.split(" "); 13 | int startX; 14 | int startY; 15 | int endX; 16 | int endY; 17 | 18 | if(instructions[0].equals("toggle")){ 19 | startX = Integer.parseInt(instructions[1].split(",")[0]); 20 | startY = Integer.parseInt(instructions[1].split(",")[1]); 21 | endX = Integer.parseInt(instructions[3].split(",")[0]); 22 | endY = Integer.parseInt(instructions[3].split(",")[1]); 23 | 24 | for(int i = startX; i <= endX; i++){ 25 | for(int j = startY; j <= endY; j++){ 26 | lights[i][j] = !lights[i][j]; 27 | } 28 | } 29 | } 30 | else if(instructions[0].equals("turn")){ 31 | startX = Integer.parseInt(instructions[2].split(",")[0]); 32 | startY = Integer.parseInt(instructions[2].split(",")[1]); 33 | endX = Integer.parseInt(instructions[4].split(",")[0]); 34 | endY = Integer.parseInt(instructions[4].split(",")[1]); 35 | 36 | if(instructions[1].equals("on")){ 37 | for(int i = startX; i <= endX; i++){ 38 | for(int j = startY; j <= endY; j++){ 39 | lights[i][j] = true; 40 | } 41 | } 42 | } 43 | else if(instructions[1].equals("off")){ 44 | for(int i = startX; i <= endX; i++){ 45 | for(int j = startY; j <= endY; j++){ 46 | lights[i][j] = false; 47 | } 48 | } 49 | } 50 | } 51 | } 52 | 53 | public static void main(String[] args) throws FileNotFoundException { 54 | 55 | int count = 0; 56 | 57 | Scanner s = new Scanner(new File("input")); 58 | 59 | while(s.hasNext()){ 60 | execute(s.nextLine()); 61 | } 62 | 63 | for(boolean[] b : lights){ 64 | for(boolean c : b){ 65 | if(c){ 66 | count++; 67 | } 68 | } 69 | } 70 | 71 | System.out.println("There are " + count + " lights on."); 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /day16/p2a.java: -------------------------------------------------------------------------------- 1 | package adventofcode; 2 | 3 | import java.io.File; 4 | import java.io.FileNotFoundException; 5 | import java.util.Scanner; 6 | 7 | public class p2a { 8 | 9 | static int[] properties = {3, 7, 2, 3, 0, 0, 5, 3, 2, 1}; 10 | 11 | static boolean identifyAunt(String input){ 12 | String[] params = input.split(" "); 13 | int[] index = {indexProperties(params[2]), indexProperties(params[4]), indexProperties(params[6])}; 14 | boolean isAunt = true; 15 | int[] values = {Integer.parseInt(params[3].substring(0, 1)), Integer.parseInt(params[5].substring(0, 1)), Integer.parseInt(params[7])}; 16 | 17 | for(int i = 0; i < 3; i++){ 18 | if(index[i] == 1 || index[i] == 7){ 19 | if(!(properties[index[i]] < values[i])){ 20 | isAunt = false; 21 | } 22 | } 23 | else if(index[i] == 3 || index[i] == 6){ 24 | if(!(properties[index[i]] > values[i])){ 25 | isAunt = false; 26 | } 27 | } 28 | else{ 29 | if(!(properties[index[i]] == values[i])){ 30 | isAunt = false; 31 | } 32 | } 33 | } 34 | return isAunt; 35 | } 36 | 37 | static int indexProperties(String property){ 38 | switch(property){ 39 | case "children:": 40 | return 0; 41 | case "cats:": 42 | return 1; 43 | case "samoyeds:": 44 | return 2; 45 | case "pomeranians:": 46 | return 3; 47 | case "akitas:": 48 | return 4; 49 | case "vizslas:": 50 | return 5; 51 | case "goldfish:": 52 | return 6; 53 | case "trees:": 54 | return 7; 55 | case "cars:": 56 | return 8; 57 | case "perfumes:": 58 | return 9; 59 | default: 60 | return -1; 61 | } 62 | } 63 | 64 | public static void main(String[] args) throws FileNotFoundException{ 65 | 66 | Scanner s = new Scanner(new File("input")); 67 | 68 | int aunt = 1; 69 | 70 | while(s.hasNext()){ 71 | if(identifyAunt(s.nextLine())){ 72 | break; 73 | } 74 | else{ 75 | aunt++; 76 | } 77 | } 78 | 79 | System.out.println("Aunt Sue " + aunt + " sent you the gift."); 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /day06/p2a.java: -------------------------------------------------------------------------------- 1 | package adventofcode; 2 | 3 | import java.io.File; 4 | import java.io.FileNotFoundException; 5 | import java.util.Scanner; 6 | 7 | public class p2a { 8 | 9 | public static int[][] lights = new int[1000][1000]; 10 | 11 | public static void execute(String s){ 12 | String[] instructions = s.split(" "); 13 | int startX; 14 | int startY; 15 | int endX; 16 | int endY; 17 | 18 | if(instructions[0].equals("toggle")){ 19 | startX = Integer.parseInt(instructions[1].split(",")[0]); 20 | startY = Integer.parseInt(instructions[1].split(",")[1]); 21 | endX = Integer.parseInt(instructions[3].split(",")[0]); 22 | endY = Integer.parseInt(instructions[3].split(",")[1]); 23 | 24 | for(int i = startX; i <= endX; i++){ 25 | for(int j = startY; j <= endY; j++){ 26 | lights[i][j] += 2; 27 | } 28 | } 29 | } 30 | else if(instructions[0].equals("turn")){ 31 | startX = Integer.parseInt(instructions[2].split(",")[0]); 32 | startY = Integer.parseInt(instructions[2].split(",")[1]); 33 | endX = Integer.parseInt(instructions[4].split(",")[0]); 34 | endY = Integer.parseInt(instructions[4].split(",")[1]); 35 | 36 | if(instructions[1].equals("on")){ 37 | for(int i = startX; i <= endX; i++){ 38 | for(int j = startY; j <= endY; j++){ 39 | lights[i][j]++; 40 | } 41 | } 42 | } 43 | else if(instructions[1].equals("off")){ 44 | for(int i = startX; i <= endX; i++){ 45 | for(int j = startY; j <= endY; j++){ 46 | if(lights[i][j] > 0){ 47 | lights[i][j]--; 48 | } 49 | } 50 | } 51 | } 52 | } 53 | } 54 | 55 | public static void main(String[] args) throws FileNotFoundException { 56 | 57 | int count = 0; 58 | 59 | Scanner s = new Scanner(new File("input")); 60 | 61 | while(s.hasNext()){ 62 | execute(s.nextLine()); 63 | } 64 | 65 | for(int[] b : lights){ 66 | for(int c : b){ 67 | if(c > 0){ 68 | count += c; 69 | } 70 | } 71 | } 72 | 73 | System.out.println("The brightness is " + count + "."); 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /day23/p1a.ex: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env elixir 2 | 3 | # By: Steven Critchfield 4 | # https://github.com/critch 5 | 6 | defmodule Advent23p1 do 7 | require Integer 8 | 9 | def calculate do 10 | prog = File.stream!("input") |> 11 | Stream.map(fn(x) -> String.strip(x) end ) |> 12 | Enum.map(fn(x) -> String.split(x, " ") end) 13 | 14 | Stream.cycle([1]) |> # dummy source to keep rest running 15 | Stream.transform([ prog, 0, 0, 0 ], fn(_,acc) -> do_work(acc) end) |> 16 | Enum.to_list |> 17 | Enum.fetch!(-1) 18 | end 19 | 20 | def do_work(state) do 21 | [prog, _, _, i] = state 22 | inst = Enum.fetch!(prog,i) 23 | ev = dw( Enum.fetch!(inst,0), inst, state) 24 | [_,_,b,i] = ev 25 | if i > Enum.count(prog)-1 do 26 | {:halt, state} 27 | else 28 | if( i < 1) do 29 | {:halt, state} 30 | else 31 | { [b], ev} 32 | end 33 | end 34 | end 35 | 36 | def dw("hlf", inst, state) do 37 | [_, reg] = inst 38 | [prog,a,b,i] = state 39 | if reg == "a" do 40 | [ prog, trunc(a/2), b, i+1] 41 | else 42 | [prog, a, trunc(b/2), i+1] 43 | end 44 | end 45 | def dw("tpl", inst, state) do 46 | [_, reg] = inst 47 | [prog, a,b,i] = state 48 | if reg == "a" do 49 | [prog, a*3, b, i+1] 50 | else 51 | [prog, a, b*3, i+1] 52 | end 53 | end 54 | def dw("inc", inst, state) do 55 | [_,reg] = inst 56 | [prog,a,b,i] = state 57 | if reg == "a" do 58 | [prog, a+1, b, i+1] 59 | else 60 | [prog, a, b+1, i+1] 61 | end 62 | end 63 | def dw("jmp", inst, state) do 64 | [_, dist ] = inst 65 | [prog,a,b,i] = state 66 | [prog, a, b, i+String.to_integer(dist)] 67 | end 68 | def dw("jie", inst, state) do 69 | [_,reg, dist] = inst 70 | dist = String.to_integer(dist) 71 | [prog,a,b,i] = state 72 | if reg == "a," do 73 | check = a 74 | else 75 | check = b 76 | end 77 | if Integer.is_even(check) do 78 | [prog, a, b, i+dist] 79 | else 80 | [prog, a, b, i+1] 81 | end 82 | end 83 | def dw("jio", inst, state) do 84 | [_,reg, dist] = inst 85 | dist = String.to_integer(dist) 86 | [prog,a,b,i] = state 87 | if reg == "a," do 88 | check = a 89 | else 90 | check = b 91 | end 92 | if check == 1 do 93 | [prog, a, b, i+dist] 94 | else 95 | [prog, a, b, i+1] 96 | end 97 | end 98 | end 99 | 100 | IO.puts "At end of program, Register b=" <> Integer.to_string(Advent23p1.calculate) 101 | -------------------------------------------------------------------------------- /day23/p2a.ex: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env elixir 2 | 3 | # By: Steven Critchfield 4 | # https://github.com/critch 5 | 6 | defmodule Advent23p2 do 7 | require Integer 8 | 9 | def calculate do 10 | prog = File.stream!("input") |> 11 | Stream.map(fn(x) -> String.strip(x) end ) |> 12 | Enum.map(fn(x) -> String.split(x, " ") end) 13 | 14 | Stream.cycle([1]) |> # dummy source to keep rest running 15 | Stream.transform([ prog, 1, 0, 0 ], fn(_,acc) -> do_work(acc) end) |> 16 | Enum.to_list |> 17 | Enum.fetch!(-1) 18 | end 19 | 20 | def do_work(state) do 21 | [prog, _, _, i] = state 22 | inst = Enum.fetch!(prog,i) 23 | ev = dw( Enum.fetch!(inst,0), inst, state) 24 | [_,_,b,i] = ev 25 | if i > Enum.count(prog)-1 do 26 | {:halt, state} 27 | else 28 | if( i < 1) do 29 | {:halt, state} 30 | else 31 | { [b], ev} 32 | end 33 | end 34 | end 35 | 36 | def dw("hlf", inst, state) do 37 | [_, reg] = inst 38 | [prog,a,b,i] = state 39 | if reg == "a" do 40 | [ prog, trunc(a/2), b, i+1] 41 | else 42 | [prog, a, trunc(b/2), i+1] 43 | end 44 | end 45 | def dw("tpl", inst, state) do 46 | [_, reg] = inst 47 | [prog, a,b,i] = state 48 | if reg == "a" do 49 | [prog, a*3, b, i+1] 50 | else 51 | [prog, a, b*3, i+1] 52 | end 53 | end 54 | def dw("inc", inst, state) do 55 | [_,reg] = inst 56 | [prog,a,b,i] = state 57 | if reg == "a" do 58 | [prog, a+1, b, i+1] 59 | else 60 | [prog, a, b+1, i+1] 61 | end 62 | end 63 | def dw("jmp", inst, state) do 64 | [_, dist ] = inst 65 | [prog,a,b,i] = state 66 | [prog, a, b, i+String.to_integer(dist)] 67 | end 68 | def dw("jie", inst, state) do 69 | [_,reg, dist] = inst 70 | dist = String.to_integer(dist) 71 | [prog,a,b,i] = state 72 | if reg == "a," do 73 | check = a 74 | else 75 | check = b 76 | end 77 | if Integer.is_even(check) do 78 | [prog, a, b, i+dist] 79 | else 80 | [prog, a, b, i+1] 81 | end 82 | end 83 | def dw("jio", inst, state) do 84 | [_,reg, dist] = inst 85 | dist = String.to_integer(dist) 86 | [prog,a,b,i] = state 87 | if reg == "a," do 88 | check = a 89 | else 90 | check = b 91 | end 92 | if check == 1 do 93 | [prog, a, b, i+dist] 94 | else 95 | [prog, a, b, i+1] 96 | end 97 | end 98 | end 99 | 100 | IO.puts "At end of program, Register b=" <> Integer.to_string(Advent23p2.calculate) 101 | -------------------------------------------------------------------------------- /day07/p1a.java: -------------------------------------------------------------------------------- 1 | package adventofcode; 2 | 3 | import java.io.File; 4 | import java.io.FileNotFoundException; 5 | import java.util.Scanner; 6 | 7 | public class p1a { 8 | 9 | static String[] commands = new String[339]; 10 | static int[] wires = new int[339]; 11 | 12 | public static int evaluate(String wire){ 13 | 14 | try{ 15 | return Integer.parseInt(wire); 16 | } 17 | catch(NumberFormatException e){} 18 | 19 | int position = getPosition(wire); 20 | 21 | if(wires[position] != 0){ 22 | return wires[position]; 23 | } 24 | 25 | else{ 26 | String command = commands[position]; 27 | String[] commandParts = command.split(" "); 28 | 29 | if(command.contains(" AND ")){ 30 | wires[position] = evaluate(commandParts[0]) & evaluate(commandParts[2]); 31 | } 32 | else if(command.contains(" OR ")){ 33 | wires[position] = evaluate(commandParts[0]) | evaluate(commandParts[2]); 34 | } 35 | else if(command.contains(" LSHIFT ")){ 36 | wires[position] = evaluate(commandParts[0]) << Integer.parseInt(commandParts[2]); 37 | } 38 | else if(command.contains(" RSHIFT ")){ 39 | wires[position] = evaluate(commandParts[0]) >> Integer.parseInt(commandParts[2]); 40 | } 41 | else if(command.contains("NOT ")){ 42 | wires[position] = ~evaluate(commandParts[1]); 43 | } 44 | else{ 45 | wires[position] = evaluate(commandParts[0]); 46 | } 47 | return wires[position]; 48 | } 49 | } 50 | 51 | public static int getPosition(String wire){ 52 | char[] twoChars = wire.toCharArray(); 53 | int multiplier; 54 | int additive; 55 | 56 | if(twoChars.length == 2){ 57 | multiplier = twoChars[0] == ' ' ? 0 : (byte)twoChars[0] - 96; 58 | additive = (byte)twoChars[1] - 97; 59 | return 26 * multiplier + additive; 60 | } 61 | else{ 62 | return (byte)twoChars[0] - 97; 63 | } 64 | } 65 | 66 | public static void main(String[] args) throws FileNotFoundException { 67 | 68 | Scanner s = new Scanner(new File("input")); 69 | 70 | while(s.hasNext()){ 71 | String command = s.nextLine(); 72 | int position = getPosition(command.substring(command.length() - 2)); 73 | commands[position] = command; 74 | } 75 | 76 | System.out.println("The value is " + evaluate("a") + "."); 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /day18/p2a.ex: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env elixir 2 | 3 | # By: Steven Critchfield 4 | # https://github.com/critch 5 | 6 | defmodule Advent18p2 do 7 | def calculate do 8 | state = File.stream!("input") |> 9 | Stream.map(fn(x) -> String.strip(x) end) |> 10 | Enum.join 11 | 12 | side = trunc :math.sqrt(String.length(state)) 13 | 14 | 1..100 |> 15 | Enum.reduce(state, fn(x,state) -> cycle(x,state, side) end) |> 16 | String.split("") |> 17 | Enum.filter(fn(x) -> x == "#" end)|> 18 | Enum.count 19 | end 20 | 21 | def cycle(x,state, side) do 22 | IO.puts("Starting cycle: #{x}") 23 | Stream.map(0..side-1, fn(x) -> Enum.map(0..side-1, fn(y) -> 24 | cond do 25 | x == 0 and y == 0 -> Task.async(fn() -> "#" end) 26 | x == side-1 and y == 0 -> Task.async(fn() -> "#" end) 27 | x == 0 and y == side-1 -> Task.async(fn() -> "#" end) 28 | x == side-1 and y == side-1 -> Task.async(fn() -> "#" end) 29 | true -> Task.async(fn() -> brute(state,x,y,side) end) 30 | end 31 | end) end) |> 32 | Stream.map(fn(w) -> Enum.map(w,fn(z) -> Task.await(z,5000000) end) end) |> 33 | Enum.join 34 | end 35 | 36 | def brute(state,x,y,side) do 37 | ind = index(x,y,side) 38 | cur = String.slice(state, ind..ind) 39 | 40 | neighbors = [top_row(state, x,y,side,ind), middle_row(state,x,y,side,ind), bottom_row(state,x,y,side,ind)] 41 | count = String.split(Enum.join(neighbors), "") |> 42 | Enum.filter(fn(x) -> x == "#" end) |> 43 | Enum.count 44 | 45 | cond do 46 | cur == "#" and count < 2 -> "." 47 | cur == "#" and count > 3 -> "." 48 | cur == "#" -> "#" 49 | cur == "." and count == 3 -> "#" 50 | cur == "." -> "." 51 | end 52 | end 53 | 54 | def index(x,y,side), do: x*side + y 55 | 56 | def top_row(state,x,y,side,ind) do 57 | cond do 58 | x == 0 -> "" 59 | y == 0 -> String.slice(state, ind-side..ind-side+1) 60 | y == side-1 -> String.slice(state, ind-side-1..ind-side) 61 | true -> String.slice(state, ind-side-1..ind-side+1) 62 | end 63 | end 64 | def middle_row(state,_,y,side,ind) do 65 | cond do 66 | y == 0 -> String.slice(state, ind+1..ind+1) 67 | y == side-1 -> String.slice(state, ind-1..ind-1) 68 | true -> String.slice(state, ind-1..ind-1) <> String.slice(state, ind+1..ind+1) 69 | end 70 | end 71 | def bottom_row(state,x,y,side,ind) do 72 | cond do 73 | x == side-1 -> "" 74 | y == 0 -> String.slice(state, ind+side..ind+side+1) 75 | y == side-1 -> String.slice(state, ind+side-1..ind+side) 76 | true -> String.slice(state, ind+side-1..ind+side+1) 77 | end 78 | end 79 | end 80 | 81 | IO.puts "Lights on: " <> Integer.to_string(Advent18p2.calculate) 82 | --------------------------------------------------------------------------------