diff --git a/.editorconfig b/.editorconfig deleted file mode 100644 index 72d51b560..000000000 --- a/.editorconfig +++ /dev/null @@ -1,126 +0,0 @@ -############################### -# Core EditorConfig Options # -############################### -root = true -# All files -[*] -indent_style = space - -# XML project files -[*.{csproj,vbproj,vcxproj,vcxproj.filters,proj,projitems,shproj}] -indent_size = 2 - -# XML config files -[*.{props,targets,ruleset,config,nuspec,resx,vsixmanifest,vsct}] -indent_size = 2 - -# Code files -[*.{cs,csx,vb,vbx}] -indent_size = 4 -insert_final_newline = true -charset = utf-8-bom -############################### -# .NET Coding Conventions # -############################### -[*.{cs,vb}] -# Organize usings -dotnet_sort_system_directives_first = true -# this. preferences -dotnet_style_qualification_for_field = false:silent -dotnet_style_qualification_for_property = false:silent -dotnet_style_qualification_for_method = false:silent -dotnet_style_qualification_for_event = false:silent -# Language keywords vs BCL types preferences -dotnet_style_predefined_type_for_locals_parameters_members = true:silent -dotnet_style_predefined_type_for_member_access = true:silent -# Parentheses preferences -dotnet_style_parentheses_in_arithmetic_binary_operators = always_for_clarity:silent -dotnet_style_parentheses_in_relational_binary_operators = always_for_clarity:silent -dotnet_style_parentheses_in_other_binary_operators = always_for_clarity:silent -dotnet_style_parentheses_in_other_operators = never_if_unnecessary:silent -# Modifier preferences -dotnet_style_require_accessibility_modifiers = for_non_interface_members:silent -dotnet_style_readonly_field = true:suggestion -# Expression-level preferences -dotnet_style_object_initializer = true:suggestion -dotnet_style_collection_initializer = true:suggestion -dotnet_style_explicit_tuple_names = true:suggestion -dotnet_style_null_propagation = true:suggestion -dotnet_style_coalesce_expression = true:suggestion -dotnet_style_prefer_is_null_check_over_reference_equality_method = true:silent -dotnet_style_prefer_inferred_tuple_names = true:suggestion -dotnet_style_prefer_inferred_anonymous_type_member_names = true:suggestion -dotnet_style_prefer_auto_properties = true:silent -dotnet_style_prefer_conditional_expression_over_assignment = true:silent -dotnet_style_prefer_conditional_expression_over_return = true:silent -############################### -# Naming Conventions # -############################### -# Style Definitions -dotnet_naming_style.pascal_case_style.capitalization = pascal_case -# Use PascalCase for constant fields -dotnet_naming_rule.constant_fields_should_be_pascal_case.severity = suggestion -dotnet_naming_rule.constant_fields_should_be_pascal_case.symbols = constant_fields -dotnet_naming_rule.constant_fields_should_be_pascal_case.style = pascal_case_style -dotnet_naming_symbols.constant_fields.applicable_kinds = field -dotnet_naming_symbols.constant_fields.applicable_accessibilities = * -dotnet_naming_symbols.constant_fields.required_modifiers = const -############################### -# C# Coding Conventions # -############################### -[*.cs] -# var preferences -csharp_style_var_for_built_in_types = true:silent -csharp_style_var_when_type_is_apparent = true:silent -csharp_style_var_elsewhere = true:silent -# Expression-bodied members -csharp_style_expression_bodied_methods = false:silent -csharp_style_expression_bodied_constructors = false:silent -csharp_style_expression_bodied_operators = false:silent -csharp_style_expression_bodied_properties = true:silent -csharp_style_expression_bodied_indexers = true:silent -csharp_style_expression_bodied_accessors = true:silent -# Pattern matching preferences -csharp_style_pattern_matching_over_is_with_cast_check = true:suggestion -csharp_style_pattern_matching_over_as_with_null_check = true:suggestion -# Null-checking preferences -csharp_style_throw_expression = true:suggestion -csharp_style_conditional_delegate_call = true:suggestion -# Modifier preferences -csharp_preferred_modifier_order = public,private,protected,internal,file,static,extern,new,virtual,abstract,sealed,override,readonly,unsafe,required,volatile,async:suggestion -# Expression-level preferences -csharp_prefer_braces = true:silent -csharp_style_deconstructed_variable_declaration = true:suggestion -csharp_prefer_simple_default_expression = true:suggestion -csharp_style_prefer_local_over_anonymous_function = true:suggestion -csharp_style_inlined_variable_declaration = true:suggestion -############################### -# C# Formatting Rules # -############################### -# New line preferences -csharp_new_line_before_open_brace = false -csharp_new_line_before_else = false -csharp_new_line_before_catch = false -csharp_new_line_before_finally = false -csharp_new_line_before_members_in_object_initializers = false -csharp_new_line_before_members_in_anonymous_types = false -csharp_new_line_between_query_expression_clauses = false -# Indentation preferences -csharp_indent_case_contents = true -csharp_indent_switch_labels = true -csharp_indent_labels = flush_left -# Space preferences -csharp_space_after_cast = false -csharp_space_after_keywords_in_control_flow_statements = true -csharp_space_between_method_call_parameter_list_parentheses = false -csharp_space_between_method_declaration_parameter_list_parentheses = false -csharp_space_between_parentheses = false -csharp_space_before_colon_in_inheritance_clause = true -csharp_space_after_colon_in_inheritance_clause = true -csharp_space_around_binary_operators = before_and_after -csharp_space_between_method_declaration_empty_parameter_list_parentheses = false -csharp_space_between_method_call_name_and_opening_parenthesis = false -csharp_space_between_method_call_empty_parameter_list_parentheses = false -# Wrapping preferences -csharp_preserve_single_line_statements = true -csharp_preserve_single_line_blocks = true \ No newline at end of file diff --git a/.gitattributes b/.gitattributes deleted file mode 100644 index 989d37c12..000000000 --- a/.gitattributes +++ /dev/null @@ -1 +0,0 @@ -**/input.in filter=git-crypt diff=git-crypt diff --git a/.github/workflows/update-docs.yaml b/.github/workflows/update-docs.yaml deleted file mode 100644 index 62acdb9ae..000000000 --- a/.github/workflows/update-docs.yaml +++ /dev/null @@ -1,53 +0,0 @@ -name: Update Docs - -on: - push: - branches: - - master - -jobs: - update-docs: - runs-on: ubuntu-latest - - permissions: - # Give the default GITHUB_TOKEN write permission to commit and push the - # added or changed files to the repository. - contents: write - - steps: - - name: Checkout repository - uses: actions/checkout@v3 - - - name: Configure Git - run: | - # Configure Git - git config --global user.name "github-actions[bot]" - git config --global user.email "github-actions[bot]@users.noreply.github.com" - - - name: Set up Node.js - uses: actions/setup-node@v3 - with: - node-version: '16' # Update based on your project's requirements - - - name: Build - run: | - cd docs; - npm install - cd .. - ls -la - node docs/build.js - - - - name: Checkout docs repository - uses: actions/checkout@v3 - with: - path: distr - ref: docs - - - name: Deploy docs - run: | - rsync -av --exclude='.git/' --del build/ distr/ - cd distr - git add . - git commit -m "Update docs on $(date)" - git push --force origin docs diff --git a/.gitignore b/.gitignore index f96db2252..1746e3269 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,2 @@ bin obj -aoc-crypt.key -docs/node_modules -build diff --git a/.vscode/launch.json b/.vscode/launch.json index 86b12f55e..b1d3018a7 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -11,7 +11,7 @@ "request": "launch", "preLaunchTask": "build", // If you have changed target frameworks, make sure to update the program path. - "program": "${workspaceFolder}/bin/Debug/net9.0/adventofcode.dll", + "program": "${workspaceFolder}/bin/Debug/net7.0/adventofcode.dll", "args": ["${relativeFileDirname}"], "cwd": "${workspaceFolder}", // For more information about the 'console' field, see https://github.com/OmniSharp/omnisharp-vscode/blob/master/debugger-launchjson.md#console-terminal-window diff --git a/2015/Day01/README.md b/2015/Day01/README.md index e6654b029..bfd951a30 100644 --- a/2015/Day01/README.md +++ b/2015/Day01/README.md @@ -1,6 +1,38 @@ +original source: [https://adventofcode.com/2015/day/1](https://adventofcode.com/2015/day/1) ## --- Day 1: Not Quite Lisp --- Santa was hoping for a white Christmas, but his weather machine's "snow" function is powered by stars, and he's fresh out! To save Christmas, he needs you to collect fifty stars by December 25th. Collect stars by helping Santa solve puzzles. Two puzzles will be made available on each day in the Advent calendar; the second puzzle is unlocked when you complete the first. Each puzzle grants one star. Good luck! -_Visit the website for the full story and [full puzzle](https://adventofcode.com/2015/day/1) description._ +Here's an easy puzzle to warm you up. + +Santa is trying to deliver presents in a large apartment building, but he can't find the right floor - the directions he got are a little confusing. He starts on the ground floor (floor 0) and then follows the instructions one character at a time. + +An opening parenthesis, (, means he should go up one floor, and a closing parenthesis, ), means he should go down one floor. + +The apartment building is very tall, and the basement is very deep; he will never find the top or bottom floors. + +For example: + + + - (()) and ()() both result in floor 0. + - ((( and (()(()( both result in floor 3. + - ))((((( also results in floor 3. + - ()) and ))( both result in floor -1 (the first basement level). + - ))) and )())()) both result in floor -3. + +To what floor do the instructions take Santa? + + +## --- Part Two --- +Now, given the same instructions, find the position of the first character that causes him to enter the basement (floor -1). The first character in the instructions has position 1, the second character has position 2, and so on. + +For example: + + + - ) causes him to enter the basement at character position 1. + - ()()) causes him to enter the basement at character position 5. + +What is the position of the character that causes Santa to first enter the basement? + + diff --git a/2015/Day01/illustration.jpeg b/2015/Day01/illustration.jpeg deleted file mode 100644 index 999d41141..000000000 Binary files a/2015/Day01/illustration.jpeg and /dev/null differ diff --git a/2015/Day01/input.in b/2015/Day01/input.in index efdae0d4d..1855a96b9 100644 Binary files a/2015/Day01/input.in and b/2015/Day01/input.in differ diff --git a/2015/Day02/README.md b/2015/Day02/README.md index 91b468e7c..945f77abf 100644 --- a/2015/Day02/README.md +++ b/2015/Day02/README.md @@ -1,6 +1,29 @@ +original source: [https://adventofcode.com/2015/day/2](https://adventofcode.com/2015/day/2) ## --- Day 2: I Was Told There Would Be No Math --- The elves are running low on wrapping paper, and so they need to submit an order for more. They have a list of the dimensions (length `l`, width `w`, and height `h`) of each present, and only want to order exactly as much as they need. Fortunately, every present is a box (a perfect [right rectangular prism](https://en.wikipedia.org/wiki/Cuboid#Rectangular_cuboid)), which makes calculating the required wrapping paper for each gift a little easier: find the surface area of the box, which is `2*l*w + 2*w*h + 2*h*l`. The elves also need a little extra paper for each present: the area of the smallest side. -Read the [full puzzle](https://adventofcode.com/2015/day/2). \ No newline at end of file +For example: + + + - A present with dimensions `2x3x4` requires `2*6 + 2*12 + 2*8 = 52` square feet of wrapping paper plus `6` square feet of slack, for a total of `58` square feet. + - A present with dimensions `1x1x10` requires `2*1 + 2*10 + 2*10 = 42` square feet of wrapping paper plus `1` square foot of slack, for a total of `43` square feet. + +All numbers in the elves' list are in feet. How many total *square feet of wrapping paper* should they order? + + +## --- Part Two --- +The elves are also running low on ribbon. Ribbon is all the same width, so they only have to worry about the length they need to order, which they would again like to be exact. + +The ribbon required to wrap a present is the shortest distance around its sides, or the smallest perimeter of any one face. Each present also requires a bow made out of ribbon as well; the feet of ribbon required for the perfect bow is equal to the cubic feet of volume of the present. Don't ask how they tie the bow, though; they'll never tell. + +For example: + + + - A present with dimensions `2x3x4` requires `2+2+3+3 = 10` feet of ribbon to wrap the present plus `2*3*4 = 24` feet of ribbon for the bow, for a total of `34` feet. + - A present with dimensions `1x1x10` requires `1+1+1+1 = 4` feet of ribbon to wrap the present plus `1*1*10 = 10` feet of ribbon for the bow, for a total of `14` feet. + +How many total *feet of ribbon* should they order? + + diff --git a/2015/Day02/illustration.jpeg b/2015/Day02/illustration.jpeg deleted file mode 100644 index 23432437a..000000000 Binary files a/2015/Day02/illustration.jpeg and /dev/null differ diff --git a/2015/Day02/input.in b/2015/Day02/input.in index ee590c717..2f04474ab 100644 Binary files a/2015/Day02/input.in and b/2015/Day02/input.in differ diff --git a/2015/Day03/README.md b/2015/Day03/README.md index 06678a506..39d702484 100644 --- a/2015/Day03/README.md +++ b/2015/Day03/README.md @@ -1,6 +1,31 @@ +original source: [https://adventofcode.com/2015/day/3](https://adventofcode.com/2015/day/3) ## --- Day 3: Perfectly Spherical Houses in a Vacuum --- Santa is delivering presents to an infinite two-dimensional grid of houses. He begins by delivering a present to the house at his starting location, and then an elf at the North Pole calls him via radio and tells him where to move next. Moves are always exactly one house to the north (`^`), south (`v`), east (`>`), or west (`<`). After each move, he delivers another present to the house at his new location. -Read the [full puzzle](https://adventofcode.com/2015/day/3). \ No newline at end of file +However, the elf back at the north pole has had a little too much eggnog, and so his directions are a little off, and Santa ends up visiting some houses more than once. How many houses receive *at least one present*? + +For example: + + + - `>` delivers presents to `2` houses: one at the starting location, and one to the east. + - `^>v<` delivers presents to `4` houses in a square, including twice to the house at his starting/ending location. + - `^v^v^v^v^v` delivers a bunch of presents to some very lucky children at only `2` houses. + + +## --- Part Two --- +The next year, to speed up the process, Santa creates a robot version of himself, *Robo-Santa*, to deliver presents with him. + +Santa and Robo-Santa start at the same location (delivering two presents to the same starting house), then take turns moving based on instructions from the elf, who is eggnoggedly reading from the same script as the previous year. + +This year, how many houses receive *at least one present*? + +For example: + + + - `^v` delivers presents to `3` houses, because Santa goes north, and then Robo-Santa goes south. + - `^>v<` now delivers presents to `3` houses, and Santa and Robo-Santa end up back where they started. + - `^v^v^v^v^v` now delivers presents to `11` houses, with Santa going one direction and Robo-Santa going the other. + + diff --git a/2015/Day03/illustration.jpeg b/2015/Day03/illustration.jpeg deleted file mode 100644 index 60cacbd93..000000000 Binary files a/2015/Day03/illustration.jpeg and /dev/null differ diff --git a/2015/Day03/input.in b/2015/Day03/input.in index 065d2f825..a5954e780 100644 Binary files a/2015/Day03/input.in and b/2015/Day03/input.in differ diff --git a/2015/Day04/README.md b/2015/Day04/README.md index a52193422..839c51a61 100644 --- a/2015/Day04/README.md +++ b/2015/Day04/README.md @@ -1,6 +1,17 @@ +original source: [https://adventofcode.com/2015/day/4](https://adventofcode.com/2015/day/4) ## --- Day 4: The Ideal Stocking Stuffer --- Santa needs help [mining](https://en.wikipedia.org/wiki/Bitcoin#Mining) some AdventCoins (very similar to [bitcoins](https://en.wikipedia.org/wiki/Bitcoin)) to use as gifts for all the economically forward-thinking little girls and boys. To do this, he needs to find [MD5](https://en.wikipedia.org/wiki/MD5) hashes which, in [hexadecimal](https://en.wikipedia.org/wiki/Hexadecimal), start with at least *five zeroes*. The input to the MD5 hash is some secret key (your puzzle input, given below) followed by a number in decimal. To mine AdventCoins, you must find Santa the lowest positive number (no leading zeroes: `1`, `2`, `3`, ...) that produces such a hash. -Read the [full puzzle](https://adventofcode.com/2015/day/4). \ No newline at end of file +For example: + + + - If your secret key is `abcdef`, the answer is `609043`, because the MD5 hash of `abcdef609043` starts with five zeroes (`000001dbbfa...`), and it is the lowest such number to do so. + - If your secret key is `pqrstuv`, the lowest number it combines with to make an MD5 hash starting with five zeroes is `1048970`; that is, the MD5 hash of `pqrstuv1048970` looks like `000006136ef...`. + + +## --- Part Two --- +Now find one that starts with *six zeroes*. + + diff --git a/2015/Day04/Solution.cs b/2015/Day04/Solution.cs index a487524e2..7197c88dd 100644 --- a/2015/Day04/Solution.cs +++ b/2015/Day04/Solution.cs @@ -1,6 +1,5 @@ using System.Collections.Concurrent; using System.Linq; -using System.Collections.Generic; using System.Security.Cryptography; using System.Text; using System.Threading.Tasks; @@ -17,7 +16,7 @@ int ParallelFind(string input, string prefix) { var q = new ConcurrentQueue(); Parallel.ForEach( - Numbers(), + Enumerable.Range(0, int.MaxValue), () => MD5.Create(), (i, state, md5) => { var hashBytes = md5.ComputeHash(Encoding.ASCII.GetBytes(input + i)); @@ -34,9 +33,4 @@ int ParallelFind(string input, string prefix) { return q.Min(); } - IEnumerable Numbers() { - for (int i=0; ;i++) { - yield return i; - } - } } diff --git a/2015/Day04/illustration.jpeg b/2015/Day04/illustration.jpeg deleted file mode 100644 index 243d89a1b..000000000 Binary files a/2015/Day04/illustration.jpeg and /dev/null differ diff --git a/2015/Day04/input.in b/2015/Day04/input.in index 7f2ce7a96..d75e0dcd7 100644 Binary files a/2015/Day04/input.in and b/2015/Day04/input.in differ diff --git a/2015/Day05/README.md b/2015/Day05/README.md index 0c3382404..15274b7f4 100644 --- a/2015/Day05/README.md +++ b/2015/Day05/README.md @@ -1,6 +1,43 @@ +original source: [https://adventofcode.com/2015/day/5](https://adventofcode.com/2015/day/5) ## --- Day 5: Doesn't He Have Intern-Elves For This? --- Santa needs help figuring out which strings in his text file are naughty or nice. A *nice string* is one with all of the following properties: -Read the [full puzzle](https://adventofcode.com/2015/day/5). \ No newline at end of file + + - It contains at least three vowels (`aeiou` only), like `aei`, `xazegov`, or `aeiouaeiouaeiou`. + - It contains at least one letter that appears twice in a row, like `xx`, `abcdde` (`dd`), or `aabbccdd` (`aa`, `bb`, `cc`, or `dd`). + - It does *not* contain the strings `ab`, `cd`, `pq`, or `xy`, even if they are part of one of the other requirements. + +For example: + + + - `ugknbfddgicrmopn` is nice because it has at least three vowels (`u...i...o...`), a double letter (`...dd...`), and none of the disallowed substrings. + - `aaa` is nice because it has at least three vowels and a double letter, even though the letters used by different rules overlap. + - `jchzalrnumimnmhp` is naughty because it has no double letter. + - `haegwjzuvuyypxyu` is naughty because it contains the string `xy`. + - `dvszwmarrgswjxmb` is naughty because it contains only one vowel. + +How many strings are nice? + + +## --- Part Two --- +Realizing the error of his ways, Santa has switched to a better model of determining whether a string is naughty or nice. None of the old rules apply, as they are all clearly ridiculous. + +Now, a nice string is one with all of the following properties: + + + - It contains a pair of any two letters that appears at least twice in the string without overlapping, like `xyxy` (`xy`) or `aabcdefgaa` (`aa`), but not like `aaa` (`aa`, but it overlaps). + - It contains at least one letter which repeats with exactly one letter between them, like `xyx`, `abcdefeghi` (`efe`), or even `aaa`. + +For example: + + + - `qjhvhtzxzqqjkmpb` is nice because is has a pair that appears twice (`qj`) and a letter that repeats with exactly one letter between them (`zxz`). + - `xxyxx` is nice because it has a pair that appears twice and a letter that repeats with one between, even though the letters used by each rule overlap. + - `uurcxstgmygtbstg` is naughty because it has a pair (`tg`) but no repeat with a single letter between them. + - `ieodomkazucvgmuy` is naughty because it has a repeating letter with one between (`odo`), but no pair that appears twice. + +How many strings are nice under these new rules? + + diff --git a/2015/Day05/illustration.jpeg b/2015/Day05/illustration.jpeg deleted file mode 100644 index 8ba151e3c..000000000 Binary files a/2015/Day05/illustration.jpeg and /dev/null differ diff --git a/2015/Day05/input.in b/2015/Day05/input.in index 78609b050..a9b6e779f 100644 Binary files a/2015/Day05/input.in and b/2015/Day05/input.in differ diff --git a/2015/Day06/README.md b/2015/Day06/README.md index bc54a864c..9ad79d8bf 100644 --- a/2015/Day06/README.md +++ b/2015/Day06/README.md @@ -1,6 +1,40 @@ +original source: [https://adventofcode.com/2015/day/6](https://adventofcode.com/2015/day/6) ## --- Day 6: Probably a Fire Hazard --- Because your neighbors keep defeating you in the holiday house decorating contest year after year, you've decided to deploy one million lights in a 1000x1000 grid. Furthermore, because you've been especially nice this year, Santa has mailed you instructions on how to display the ideal lighting configuration. -Read the [full puzzle](https://adventofcode.com/2015/day/6). \ No newline at end of file + +Lights in your grid are numbered from 0 to 999 in each direction; the lights at each corner are at `0,0`, `0,999`, `999,999`, and `999,0`. The instructions include whether to `turn on`, `turn off`, or `toggle` various inclusive ranges given as coordinate pairs. Each coordinate pair represents opposite corners of a rectangle, inclusive; a coordinate pair like `0,0 through 2,2` therefore refers to 9 lights in a 3x3 square. The lights all start turned off. +To defeat your neighbors this year, all you have to do is set up your lights by doing the instructions Santa sent you in order. + +For example: + + + - `turn on 0,0 through 999,999` would turn on (or leave on) every light. + - `toggle 0,0 through 999,0` would toggle the first line of 1000 lights, turning off the ones that were on, and turning on the ones that were off. + - `turn off 499,499 through 500,500` would turn off (or leave off) the middle four lights. + +After following the instructions, *how many lights are lit*? + + +## --- Part Two --- +You just finish implementing your winning light pattern when you realize you mistranslated Santa's message from Ancient Nordic Elvish. + +The light grid you bought actually has individual brightness controls; each light can have a brightness of zero or more. The lights all start at zero. + +The phrase `turn on` actually means that you should increase the brightness of those lights by `1`. + +The phrase `turn off` actually means that you should decrease the brightness of those lights by `1`, to a minimum of zero. + +The phrase `toggle` actually means that you should increase the brightness of those lights by `2`. + +What is the *total brightness* of all lights combined after following Santa's instructions? + +For example: + + + - `turn on 0,0 through 0,0` would increase the total brightness by `1`. + - `toggle 0,0 through 999,999` would increase the total brightness by `2000000`. + + diff --git a/2015/Day06/illustration.jpeg b/2015/Day06/illustration.jpeg deleted file mode 100644 index 3b62f677b..000000000 Binary files a/2015/Day06/illustration.jpeg and /dev/null differ diff --git a/2015/Day06/input.in b/2015/Day06/input.in index be73cadf4..df10465d6 100644 Binary files a/2015/Day06/input.in and b/2015/Day06/input.in differ diff --git a/2015/Day07/README.md b/2015/Day07/README.md index 7a4b1c9a3..a4455815d 100644 --- a/2015/Day07/README.md +++ b/2015/Day07/README.md @@ -1,6 +1,51 @@ +original source: [https://adventofcode.com/2015/day/7](https://adventofcode.com/2015/day/7) ## --- Day 7: Some Assembly Required --- This year, Santa brought little Bobby Tables a set of wires and [bitwise logic gates](https://en.wikipedia.org/wiki/Bitwise_operation)! Unfortunately, little Bobby is a little under the recommended age range, and he needs help assembling the circuit. Each wire has an identifier (some lowercase letters) and can carry a [16-bit](https://en.wikipedia.org/wiki/16-bit) signal (a number from `0` to `65535`). A signal is provided to each wire by a gate, another wire, or some specific value. Each wire can only get a signal from one source, but can provide its signal to multiple destinations. A gate provides no signal until all of its inputs have a signal. -Read the [full puzzle](https://adventofcode.com/2015/day/7). \ No newline at end of file +The included instructions booklet describes how to connect the parts together: `x AND y -> z` means to connect wires `x` and `y` to an AND gate, and then connect its output to wire `z`. + +For example: + + + - `123 -> x` means that the signal `123` is provided to wire `x`. + - `x AND y -> z` means that the [bitwise AND](https://en.wikipedia.org/wiki/Bitwise_operation#AND) of wire `x` and wire `y` is provided to wire `z`. + - `p LSHIFT 2 -> q` means that the value from wire `p` is [left-shifted](https://en.wikipedia.org/wiki/Logical_shift) by `2` and then provided to wire `q`. + - `NOT e -> f` means that the [bitwise complement](https://en.wikipedia.org/wiki/Bitwise_operation#NOT) of the value from wire `e` is provided to wire `f`. + +Other possible gates include `OR` ([bitwise OR](https://en.wikipedia.org/wiki/Bitwise_operation#OR)) and `RSHIFT` ([right-shift](https://en.wikipedia.org/wiki/Logical_shift)). If, for some reason, you'd like to *emulate* the circuit instead, almost all programming languages (for example, [C](https://en.wikipedia.org/wiki/Bitwise_operations_in_C), [JavaScript](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Bitwise_Operators), or [Python](https://wiki.python.org/moin/BitwiseOperators)) provide operators for these gates. + +For example, here is a simple circuit: + +``` +123 -> x +456 -> y +x AND y -> d +x OR y -> e +x LSHIFT 2 -> f +y RSHIFT 2 -> g +NOT x -> h +NOT y -> i +``` + +After it is run, these are the signals on the wires: + +``` +d: 72 +e: 507 +f: 492 +g: 114 +h: 65412 +i: 65079 +x: 123 +y: 456 +``` + +In little Bobby's kit's instructions booklet (provided as your puzzle input), what signal is ultimately provided to *wire `a`*? + + +## --- Part Two --- +Now, take the signal you got on wire `a`, override wire `b` to that signal, and reset the other wires (including wire `a`). What new signal is ultimately provided to wire `a`? + + diff --git a/2015/Day07/input.in b/2015/Day07/input.in index 21197948f..1b7dfc90f 100644 Binary files a/2015/Day07/input.in and b/2015/Day07/input.in differ diff --git a/2015/Day08/README.md b/2015/Day08/README.md index acd31d5fc..96a564da8 100644 --- a/2015/Day08/README.md +++ b/2015/Day08/README.md @@ -1,6 +1,37 @@ +original source: [https://adventofcode.com/2015/day/8](https://adventofcode.com/2015/day/8) ## --- Day 8: Matchsticks --- Space on the sleigh is limited this year, and so Santa will be bringing his list as a digital copy. He needs to know how much space it will take up when stored. It is common in many programming languages to provide a way to escape special characters in strings. For example, [C](https://en.wikipedia.org/wiki/Escape_sequences_in_C), [JavaScript](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String), [Perl](http://perldoc.perl.org/perlop.html#Quote-and-Quote-like-Operators), [Python](https://docs.python.org/2.0/ref/strings.html), and even [PHP](http://php.net/manual/en/language.types.string.php#language.types.string.syntax.double) handle special characters in very similar ways. -Read the [full puzzle](https://adventofcode.com/2015/day/8). \ No newline at end of file +However, it is important to realize the difference between the number of characters *in the code representation of the string literal* and the number of characters *in the in-memory string itself*. + +For example: + + + - `""` is `2` characters of code (the two double quotes), but the string contains zero characters. + - `"abc"` is `5` characters of code, but `3` characters in the string data. + - `"aaa\"aaa"` is `10` characters of code, but the string itself contains six "a" characters and a single, escaped quote character, for a total of `7` characters in the string data. + - `"\x27"` is `6` characters of code, but the string itself contains just one - an apostrophe (`'`), escaped using hexadecimal notation. + +Santa's list is a file that contains many double-quoted string literals, one on each line. The only escape sequences used are `\\` (which represents a single backslash), `\"` (which represents a lone double-quote character), and `\x` plus two hexadecimal characters (which represents a single character with that ASCII code). + +Disregarding the whitespace in the file, what is *the number of characters of code for string literals* minus *the number of characters in memory for the values of the strings* in total for the entire file? + +For example, given the four strings above, the total number of characters of string code (`2 + 5 + 10 + 6 = 23`) minus the total number of characters in memory for string values (`0 + 3 + 7 + 1 = 11`) is `23 - 11 = 12`. + + +## --- Part Two --- +Now, let's go the other way. In addition to finding the number of characters of code, you should now *encode each code representation as a new string* and find the number of characters of the new encoded representation, including the surrounding double quotes. + +For example: + + + - `""` encodes to `"\"\""`, an increase from `2` characters to `6`. + - `"abc"` encodes to `"\"abc\""`, an increase from `5` characters to `9`. + - `"aaa\"aaa"` encodes to `"\"aaa\\\"aaa\""`, an increase from `10` characters to `16`. + - `"\x27"` encodes to `"\"\\x27\""`, an increase from `6` characters to `11`. + +Your task is to find *the total number of characters to represent the newly encoded strings* minus *the number of characters of code in each original string literal*. For example, for the strings above, the total encoded length (`6 + 9 + 16 + 11 = 42`) minus the characters in the original code representation (`23`, just like in the first part of this puzzle) is `42 - 23 = 19`. + + diff --git a/2015/Day08/input.in b/2015/Day08/input.in index a37076b5a..3e5be6553 100644 Binary files a/2015/Day08/input.in and b/2015/Day08/input.in differ diff --git a/2015/Day09/README.md b/2015/Day09/README.md index 9ea9bfada..a29da3479 100644 --- a/2015/Day09/README.md +++ b/2015/Day09/README.md @@ -1,6 +1,40 @@ +original source: [https://adventofcode.com/2015/day/9](https://adventofcode.com/2015/day/9) ## --- Day 9: All in a Single Night --- Every year, Santa manages to deliver all of his presents in a single night. This year, however, he has some new locations to visit; his elves have provided him the distances between every pair of locations. He can start and end at any two (different) locations he wants, but he must visit each location exactly once. What is the *shortest distance* he can travel to achieve this? -Read the [full puzzle](https://adventofcode.com/2015/day/9). \ No newline at end of file +For example, given the following distances: + +``` +London to Dublin = 464 +London to Belfast = 518 +Dublin to Belfast = 141 +``` + +The possible routes are therefore: + +``` +Dublin -> London -> Belfast = 982 +London -> Dublin -> Belfast = 605 +London -> Belfast -> Dublin = 659 +Dublin -> Belfast -> London = 659 +Belfast -> Dublin -> London = 605 +Belfast -> London -> Dublin = 982 +``` + +The shortest of these is `London -> Dublin -> Belfast = 605`, and so the answer is `605` in this example. + +What is the distance of the shortest route? + + +## --- Part Two --- +The next year, just to show off, Santa decides to take the route with the *longest distance* instead. + +He can still start and end at any two (different) locations he wants, and he still must visit each location exactly once. + +For example, given the distances above, the longest route would be `982` via (for example) `Dublin -> London -> Belfast`. + +What is the distance of the longest route? + + diff --git a/2015/Day09/input.in b/2015/Day09/input.in index 9873e3051..a56f5e253 100644 Binary files a/2015/Day09/input.in and b/2015/Day09/input.in differ diff --git a/2015/Day10/README.md b/2015/Day10/README.md index e09b557f0..8099a370c 100644 --- a/2015/Day10/README.md +++ b/2015/Day10/README.md @@ -1,6 +1,24 @@ +original source: [https://adventofcode.com/2015/day/10](https://adventofcode.com/2015/day/10) ## --- Day 10: Elves Look, Elves Say --- Today, the Elves are playing a game called [look-and-say](https://en.wikipedia.org/wiki/Look-and-say_sequence). They take turns making sequences by reading aloud the previous sequence and using that reading as the next sequence. For example, `211` is read as "one two, two ones", which becomes `1221` (`1` `2`, `2` `1`s). Look-and-say sequences are generated iteratively, using the previous value as input for the next step. For each step, take the previous value, and replace each run of digits (like `111`) with the number of digits (`3`) followed by the digit itself (`1`). -Read the [full puzzle](https://adventofcode.com/2015/day/10). \ No newline at end of file +For example: + + + - `1` becomes `11` (`1` copy of digit `1`). + - `11` becomes `21` (`2` copies of digit `1`). + - `21` becomes `1211` (one `2` followed by one `1`). + - `1211` becomes `111221` (one `1`, one `2`, and two `1`s). + - `111221` becomes `312211` (three `1`s, two `2`s, and one `1`). + +Starting with the digits in your puzzle input, apply this process 40 times. What is *the length of the result*? + + +## --- Part Two --- +Neat, right? You might also enjoy hearing [John Conway talking about this sequence](https://www.youtube.com/watch?v=ea7lJkEhytA) (that's Conway of *Conway's Game of Life* fame). + +Now, starting again with the digits in your puzzle input, apply this process *50* times. What is *the length of the new result*? + + diff --git a/2015/Day10/input.in b/2015/Day10/input.in index 33556dd98..067b0ee67 100644 Binary files a/2015/Day10/input.in and b/2015/Day10/input.in differ diff --git a/2015/Day11/README.md b/2015/Day11/README.md index f2d68ae2a..2471f1feb 100644 --- a/2015/Day11/README.md +++ b/2015/Day11/README.md @@ -1,6 +1,31 @@ +original source: [https://adventofcode.com/2015/day/11](https://adventofcode.com/2015/day/11) ## --- Day 11: Corporate Policy --- Santa's previous password expired, and he needs help choosing a new one. To help him remember his new password after the old one expires, Santa has devised a method of coming up with a password based on the previous one. Corporate policy dictates that passwords must be exactly eight lowercase letters (for security reasons), so he finds his new password by *incrementing* his old password string repeatedly until it is valid. -Read the [full puzzle](https://adventofcode.com/2015/day/11). \ No newline at end of file +Incrementing is just like counting with numbers: `xx`, `xy`, `xz`, `ya`, `yb`, and so on. Increase the rightmost letter one step; if it was `z`, it wraps around to `a`, and repeat with the next letter to the left until one doesn't wrap around. + +Unfortunately for Santa, a new Security-Elf recently started, and he has imposed some additional password requirements: + + + - Passwords must include one increasing straight of at least three letters, like `abc`, `bcd`, `cde`, and so on, up to `xyz`. They cannot skip letters; `abd` doesn't count. + - Passwords may not contain the letters `i`, `o`, or `l`, as these letters can be mistaken for other characters and are therefore confusing. + - Passwords must contain at least two different, non-overlapping pairs of letters, like `aa`, `bb`, or `zz`. + +For example: + + + - `hijklmmn` meets the first requirement (because it contains the straight `hij`) but fails the second requirement requirement (because it contains `i` and `l`). + - `abbceffg` meets the third requirement (because it repeats `bb` and `ff`) but fails the first requirement. + - `abbcegjk` fails the third requirement, because it only has one double letter (`bb`). + - The next password after `abcdefgh` is `abcdffaa`. + - The next password after `ghijklmn` is `ghjaabcc`, because you eventually skip all the passwords that start with `ghi...`, since `i` is not allowed. + +Given Santa's current password (your puzzle input), what should his *next password* be? + + +## --- Part Two --- +Santa's password expired again. What's the next one? + + diff --git a/2015/Day11/input.in b/2015/Day11/input.in index cf3823d95..5915be7bb 100644 Binary files a/2015/Day11/input.in and b/2015/Day11/input.in differ diff --git a/2015/Day12/README.md b/2015/Day12/README.md index 45ad4b14e..b0863b30f 100644 --- a/2015/Day12/README.md +++ b/2015/Day12/README.md @@ -1,6 +1,31 @@ +original source: [https://adventofcode.com/2015/day/12](https://adventofcode.com/2015/day/12) ## --- Day 12: JSAbacusFramework.io --- Santa's Accounting-Elves need help balancing the books after a recent order. Unfortunately, their accounting software uses a peculiar storage format. That's where you come in. They have a [JSON](http://json.org/) document which contains a variety of things: arrays (`[1,2,3]`), objects (`{"a":1, "b":2}`), numbers, and strings. Your first job is to simply find all of the *numbers* throughout the document and add them together. -Read the [full puzzle](https://adventofcode.com/2015/day/12). \ No newline at end of file +For example: + + + - `[1,2,3]` and `{"a":2,"b":4}` both have a sum of `6`. + - `[[[3]]]` and `{"a":{"b":4},"c":-1}` both have a sum of `3`. + - `{"a":[-1,1]}` and `[-1,{"a":1}]` both have a sum of `0`. + - `[]` and `{}` both have a sum of `0`. + +You will not encounter any strings containing numbers. + +What is the *sum of all numbers* in the document? + + +## --- Part Two --- +Uh oh - the Accounting-Elves have realized that they double-counted everything *red*. + +Ignore any object (and all of its children) which has any property with the value `"red"`. Do this only for objects (`{...}`), not arrays (`[...]`). + + + - `[1,2,3]` still has a sum of `6`. + - `[1,{"c":"red","b":2},3]` now has a sum of `4`, because the middle object is ignored. + - `{"d":"red","e":[1,2,3,4],"f":5}` now has a sum of `0`, because the entire structure is ignored. + - `[1,"red",5]` has a sum of `6`, because `"red"` in an array has no effect. + + diff --git a/2015/Day12/input.in b/2015/Day12/input.in index 6bce44176..d813484c5 100644 Binary files a/2015/Day12/input.in and b/2015/Day12/input.in differ diff --git a/2015/Day13/README.md b/2015/Day13/README.md index c126f8ae3..5eeb7bdfa 100644 --- a/2015/Day13/README.md +++ b/2015/Day13/README.md @@ -1,6 +1,48 @@ +original source: [https://adventofcode.com/2015/day/13](https://adventofcode.com/2015/day/13) ## --- Day 13: Knights of the Dinner Table --- In years past, the holiday feast with your family hasn't gone so well. Not everyone gets along! This year, you resolve, will be different. You're going to find the *optimal seating arrangement* and avoid all those awkward conversations. You start by writing up a list of everyone invited and the amount their happiness would increase or decrease if they were to find themselves sitting next to each other person. You have a circular table that will be just big enough to fit everyone comfortably, and so each person will have exactly two neighbors. -Read the [full puzzle](https://adventofcode.com/2015/day/13). \ No newline at end of file +For example, suppose you have only four attendees planned, and you calculate their potential happiness as follows: + +``` +Alice would gain 54 happiness units by sitting next to Bob. +Alice would lose 79 happiness units by sitting next to Carol. +Alice would lose 2 happiness units by sitting next to David. +Bob would gain 83 happiness units by sitting next to Alice. +Bob would lose 7 happiness units by sitting next to Carol. +Bob would lose 63 happiness units by sitting next to David. +Carol would lose 62 happiness units by sitting next to Alice. +Carol would gain 60 happiness units by sitting next to Bob. +Carol would gain 55 happiness units by sitting next to David. +David would gain 46 happiness units by sitting next to Alice. +David would lose 7 happiness units by sitting next to Bob. +David would gain 41 happiness units by sitting next to Carol. +``` + +Then, if you seat Alice next to David, Alice would lose `2` happiness units (because David talks so much), but David would gain `46` happiness units (because Alice is such a good listener), for a total change of `44`. + +If you continue around the table, you could then seat Bob next to Alice (Bob gains `83`, Alice gains `54`). Finally, seat Carol, who sits next to Bob (Carol gains `60`, Bob loses `7`) and David (Carol gains `55`, David gains `41`). The arrangement looks like this: + +``` + +41 +46 ++55 David -2 +Carol Alice ++60 Bob +54 + -7 +83 +``` + +After trying every other seating arrangement in this hypothetical scenario, you find that this one is the most optimal, with a total change in happiness of `330`. + +What is the *total change in happiness* for the optimal seating arrangement of the actual guest list? + + +## --- Part Two --- +In all the commotion, you realize that you forgot to seat yourself. At this point, you're pretty apathetic toward the whole thing, and your happiness wouldn't really go up or down regardless of who you sit next to. You assume everyone else would be just as ambivalent about sitting next to you, too. + +So, add yourself to the list, and give all happiness relationships that involve you a score of `0`. + +What is the *total change in happiness* for the optimal seating arrangement that actually includes yourself? + + diff --git a/2015/Day13/input.in b/2015/Day13/input.in index 67565872d..35be3572e 100644 Binary files a/2015/Day13/input.in and b/2015/Day13/input.in differ diff --git a/2015/Day14/README.md b/2015/Day14/README.md index c731da059..28fead086 100644 --- a/2015/Day14/README.md +++ b/2015/Day14/README.md @@ -1,6 +1,31 @@ +original source: [https://adventofcode.com/2015/day/14](https://adventofcode.com/2015/day/14) ## --- Day 14: Reindeer Olympics --- This year is the Reindeer Olympics! Reindeer can fly at high speeds, but must rest occasionally to recover their energy. Santa would like to know which of his reindeer is fastest, and so he has them race. Reindeer can only either be *flying* (always at their top speed) or *resting* (not moving at all), and always spend whole seconds in either state. -Read the [full puzzle](https://adventofcode.com/2015/day/14). \ No newline at end of file +For example, suppose you have the following Reindeer: + + + - Comet can fly *14 km/s for 10 seconds*, but then must rest for *127 seconds*. + - Dancer can fly *16 km/s for 11 seconds*, but then must rest for *162 seconds*. + +After one second, Comet has gone 14 km, while Dancer has gone 16 km. After ten seconds, Comet has gone 140 km, while Dancer has gone 160 km. On the eleventh second, Comet begins resting (staying at 140 km), and Dancer continues on for a total distance of 176 km. On the 12th second, both reindeer are resting. They continue to rest until the 138th second, when Comet flies for another ten seconds. On the 174th second, Dancer flies for another 11 seconds. + +In this example, after the 1000th second, both reindeer are resting, and Comet is in the lead at *`1120`* km (poor Dancer has only gotten `1056` km by that point). So, in this situation, Comet would win (if the race ended at 1000 seconds). + +Given the descriptions of each reindeer (in your puzzle input), after exactly `2503` seconds, *what distance has the winning reindeer traveled*? + + +## --- Part Two --- +Seeing how reindeer move in bursts, Santa decides he's not pleased with the old scoring system. + +Instead, at the end of each second, he awards one point to the reindeer currently in the lead. (If there are multiple reindeer tied for the lead, they each get one point.) He keeps the traditional 2503 second time limit, of course, as doing otherwise would be entirely ridiculous. + +Given the example reindeer from above, after the first second, Dancer is in the lead and gets one point. He stays in the lead until several seconds into Comet's second burst: after the 140th second, Comet pulls into the lead and gets his first point. Of course, since Dancer had been in the lead for the 139 seconds before that, he has accumulated 139 points by the 140th second. + +After the 1000th second, Dancer has accumulated *`689`* points, while poor Comet, our old champion, only has `312`. So, with the new scoring system, Dancer would win (if the race ended at 1000 seconds). + +Again given the descriptions of each reindeer (in your puzzle input), after exactly `2503` seconds, *how many points does the winning reindeer have*? + + diff --git a/2015/Day14/input.in b/2015/Day14/input.in index c32701b9d..6cf5489fb 100644 Binary files a/2015/Day14/input.in and b/2015/Day14/input.in differ diff --git a/2015/Day15/README.md b/2015/Day15/README.md index b6a9deacf..9c00aa682 100644 --- a/2015/Day15/README.md +++ b/2015/Day15/README.md @@ -1,6 +1,44 @@ +original source: [https://adventofcode.com/2015/day/15](https://adventofcode.com/2015/day/15) ## --- Day 15: Science for Hungry People --- Today, you set out on the task of perfecting your milk-dunking cookie recipe. All you have to do is find the right balance of ingredients. Your recipe leaves room for exactly 100 teaspoons of ingredients. You make a list of the remaining ingredients you could use to finish the recipe (your puzzle input) and their properties per teaspoon: -Read the [full puzzle](https://adventofcode.com/2015/day/15). \ No newline at end of file + + - capacity (how well it helps the cookie absorb milk) + - durability (how well it keeps the cookie intact when full of milk) + - flavor (how tasty it makes the cookie) + - texture (how it improves the feel of the cookie) + - calories (how many calories it adds to the cookie) + +You can only measure ingredients in whole-teaspoon amounts accurately, and you have to be accurate so you can reproduce your results in the future. The total score of a cookie can be found by adding up each of the properties (negative totals become 0) and then multiplying together everything except calories. + +For instance, suppose you have these two ingredients: + +
+Butterscotch: capacity -1, durability -2, flavor 6, texture 3, calories 8
+Cinnamon: capacity 2, durability 3, flavor -2, texture -1, calories 3
+
+
+ +Then, choosing to use 44 teaspoons of butterscotch and 56 teaspoons of cinnamon (because the amounts of each ingredient must add up to 100) would result in a cookie with the following properties: + + + - A capacity of 44*-1 + 56*2 = 68 + - A durability of 44*-2 + 56*3 = 80 + - A flavor of 44*6 + 56*-2 = 152 + - A texture of 44*3 + 56*-1 = 76 + +Multiplying these together (68 * 80 * 152 * 76, ignoring calories for now) results in a total score of 62842880, which happens to be the best score possible given these ingredients. If any properties had produced a negative total, it would have instead become zero, causing the whole score to multiply to zero. + +Given the ingredients in your kitchen and their properties, what is the total score of the highest-scoring cookie you can make? + + +## --- Part Two --- +Your cookie recipe becomes wildly popular! Someone asks if you can make another recipe that has exactly 500 calories per cookie (so they can use it as a meal replacement). Keep the rest of your award-winning process the same (100 teaspoons, same ingredients, same scoring system). + +For example, given the ingredients above, if you had instead selected 40 teaspoons of butterscotch and 60 teaspoons of cinnamon (which still adds to 100), the total calorie count would be 40*8 + 60*3 = 500. The total score would go down, though: only 57600000, the best you can do in such trying circumstances. + +Given the ingredients in your kitchen and their properties, what is the total score of the highest-scoring cookie you can make with a calorie total of 500? + + diff --git a/2015/Day15/input.in b/2015/Day15/input.in index 2a15a4bdf..6281182fe 100644 Binary files a/2015/Day15/input.in and b/2015/Day15/input.in differ diff --git a/2015/Day16/README.md b/2015/Day16/README.md index 2af56e4cf..e5c9c53ed 100644 --- a/2015/Day16/README.md +++ b/2015/Day16/README.md @@ -1,6 +1,47 @@ +original source: [https://adventofcode.com/2015/day/16](https://adventofcode.com/2015/day/16) ## --- Day 16: Aunt Sue --- Your Aunt Sue has given you a wonderful gift, and you'd like to send her a thank you card. However, there's a small problem: she signed it "From, Aunt Sue". You have 500 Aunts named "Sue". -Read the [full puzzle](https://adventofcode.com/2015/day/16). \ No newline at end of file +So, to avoid sending the card to the wrong person, you need to figure out which Aunt Sue (which you conveniently number 1 to 500, for sanity) gave you the gift. You open the present and, as luck would have it, good ol' Aunt Sue got you a My First Crime Scene Analysis Machine! Just what you wanted. Or needed, as the case may be. + +The My First Crime Scene Analysis Machine (MFCSAM for short) can detect a few specific compounds in a given sample, as well as how many distinct kinds of those compounds there are. According to the instructions, these are what the MFCSAM can detect: + + + - `children`, by human DNA age analysis. + - `cats`. It doesn't differentiate individual breeds. + - Several seemingly random breeds of dog: `[samoyeds](https://en.wikipedia.org/wiki/Samoyed_%28dog%29)`, `[pomeranians](https://en.wikipedia.org/wiki/Pomeranian_%28dog%29)`, `[akitas](https://en.wikipedia.org/wiki/Akita_%28dog%29)`, and `[vizslas](https://en.wikipedia.org/wiki/Vizsla)`. + - `goldfish`. No other kinds of fish. + - `trees`, all in one group. + - `cars`, presumably by exhaust or gasoline or something. + - `perfumes`, which is handy, since many of your Aunts Sue wear a few kinds. + +In fact, many of your Aunts Sue have many of these. You put the wrapping from the gift into the MFCSAM. It beeps inquisitively at you a few times and then prints out a message on [ticker tape](https://en.wikipedia.org/wiki/Ticker_tape): + +``` +children: 3 +cats: 7 +samoyeds: 2 +pomeranians: 3 +akitas: 0 +vizslas: 0 +goldfish: 5 +trees: 3 +cars: 2 +perfumes: 1 +``` + +You make a list of the things you can remember about each Aunt Sue. Things missing from your list aren't zero - you simply don't remember the value. + +What is the *number* of the Sue that got you the gift? + + +## --- Part Two --- +As you're about to send the thank you note, something in the MFCSAM's instructions catches your eye. Apparently, it has an outdated [retroencabulator](https://www.youtube.com/watch?v=RXJKdh1KZ0w), and so the output from the machine isn't exact values - some of them indicate ranges. + +In particular, the `cats` and `trees` readings indicates that there are *greater than* that many (due to the unpredictable nuclear decay of cat dander and tree pollen), while the `pomeranians` and `goldfish` readings indicate that there are *fewer than* that many (due to the modial interaction of magnetoreluctance). + +What is the *number* of the real Aunt Sue? + + diff --git a/2015/Day16/input.in b/2015/Day16/input.in index 88299f18a..ddaeefc31 100644 Binary files a/2015/Day16/input.in and b/2015/Day16/input.in differ diff --git a/2015/Day17/README.md b/2015/Day17/README.md index b38b90141..0b1d1f9be 100644 --- a/2015/Day17/README.md +++ b/2015/Day17/README.md @@ -1,6 +1,25 @@ +original source: [https://adventofcode.com/2015/day/17](https://adventofcode.com/2015/day/17) ## --- Day 17: No Such Thing as Too Much --- The elves bought too much eggnog again - `150` liters this time. To fit it all into your refrigerator, you'll need to move it into smaller containers. You take an inventory of the capacities of the available containers. For example, suppose you have containers of size `20`, `15`, `10`, `5`, and `5` liters. If you need to store `25` liters, there are four ways to do it: -Read the [full puzzle](https://adventofcode.com/2015/day/17). \ No newline at end of file + + - `15` and `10` + - `20` and `5` (the first `5`) + - `20` and `5` (the second `5`) + - `15`, `5`, and `5` + +Filling all containers entirely, how many different *combinations of containers* can exactly fit all `150` liters of eggnog? + + +## --- Part Two --- +While playing with all the containers in the kitchen, another load of eggnog arrives! The shipping and receiving department is requesting as many containers as you can spare. + +Find the minimum number of containers that can exactly fit all `150` liters of eggnog. *How many different ways* can you fill that number of containers and still hold exactly `150` litres? + +In the example above, the minimum number of containers was two. There were three ways to use that many containers, and so the answer there would be `3`. + + + + diff --git a/2015/Day17/input.in b/2015/Day17/input.in index ebbf7e7ad..09ebd4694 100644 Binary files a/2015/Day17/input.in and b/2015/Day17/input.in differ diff --git a/2015/Day18/README.md b/2015/Day18/README.md index 05f646e0c..e18d65281 100644 --- a/2015/Day18/README.md +++ b/2015/Day18/README.md @@ -1,6 +1,136 @@ +original source: [https://adventofcode.com/2015/day/18](https://adventofcode.com/2015/day/18) ## --- Day 18: Like a GIF For Your Yard --- After the [million lights incident](6), the fire code has gotten stricter: now, at most ten thousand lights are allowed. You arrange them in a 100x100 grid. Never one to let you down, Santa again mails you instructions on the ideal lighting configuration. With so few lights, he says, you'll have to resort to *animation*. -Read the [full puzzle](https://adventofcode.com/2015/day/18). \ No newline at end of file +Start by setting your lights to the included initial configuration (your puzzle input). A `#` means "on", and a `.` means "off". + +Then, animate your grid in steps, where each step decides the next configuration based on the current one. Each light's next state (either on or off) depends on its current state and the current states of the eight lights adjacent to it (including diagonals). Lights on the edge of the grid might have fewer than eight neighbors; the missing ones always count as "off". + +For example, in a simplified 6x6 grid, the light marked `A` has the neighbors numbered `1` through `8`, and the light marked `B`, which is on an edge, only has the neighbors marked `1` through `5`: + +``` +1B5... +234... +...... +..123. +..8A4. +..765. +``` + +The state a light should have next is based on its current state (on or off) plus the *number of neighbors that are on*: + + + - A light which is *on* stays on when `2` or `3` neighbors are on, and turns off otherwise. + - A light which is *off* turns on if exactly `3` neighbors are on, and stays off otherwise. + +All of the lights update simultaneously; they all consider the same current state before moving to the next. + +Here's a few steps from an example configuration of another 6x6 grid: + +``` +Initial state: +.#.#.# +...##. +#....# +..#... +#.#..# +####.. + +After 1 step: +..##.. +..##.# +...##. +...... +#..... +#.##.. + +After 2 steps: +..###. +...... +..###. +...... +.#.... +.#.... + +After 3 steps: +...#.. +...... +...#.. +..##.. +...... +...... + +After 4 steps: +...... +...... +..##.. +..##.. +...... +...... +``` + +After `4` steps, this example has four lights on. + +In your grid of 100x100 lights, given your initial configuration, *how many lights are on after 100 steps*? + + +## --- Part Two --- +You flip the instructions over; Santa goes on to point out that this is all just an implementation of [Conway's Game of Life](https://en.wikipedia.org/wiki/Conway's_Game_of_Life). At least, it was, until you notice that something's wrong with the grid of lights you bought: four lights, one in each corner, are *stuck on* and can't be turned off. The example above will actually run like this: + +``` +Initial state: +##.#.# +...##. +#....# +..#... +#.#..# +####.# + +After 1 step: +#.##.# +####.# +...##. +...... +#...#. +#.#### + +After 2 steps: +#..#.# +#....# +.#.##. +...##. +.#..## +##.### + +After 3 steps: +#...## +####.# +..##.# +...... +##.... +####.# + +After 4 steps: +#.#### +#....# +...#.. +.##... +#..... +#.#..# + +After 5 steps: +##.### +.##..# +.##... +.##... +#.#... +##...# +``` + +After `5` steps, this example now has `17` lights on. + +In your grid of 100x100 lights, given your initial configuration, but with the four corners always in the *on* state, *how many lights are on after 100 steps*? + + diff --git a/2015/Day18/input.in b/2015/Day18/input.in index 9c8fa75ed..e91a2a7e2 100644 Binary files a/2015/Day18/input.in and b/2015/Day18/input.in differ diff --git a/2015/Day19/README.md b/2015/Day19/README.md index 143c9b75b..bb0eae480 100644 --- a/2015/Day19/README.md +++ b/2015/Day19/README.md @@ -1,6 +1,61 @@ +original source: [https://adventofcode.com/2015/day/19](https://adventofcode.com/2015/day/19) ## --- Day 19: Medicine for Rudolph --- Rudolph the Red-Nosed Reindeer is sick! His nose isn't shining very brightly, and he needs medicine. Red-Nosed Reindeer biology isn't similar to regular reindeer biology; Rudolph is going to need custom-made medicine. Unfortunately, Red-Nosed Reindeer chemistry isn't similar to regular reindeer chemistry, either. -Read the [full puzzle](https://adventofcode.com/2015/day/19). \ No newline at end of file +The North Pole is equipped with a Red-Nosed Reindeer nuclear fusion/fission plant, capable of constructing any Red-Nosed Reindeer molecule you need. It works by starting with some input molecule and then doing a series of *replacements*, one per step, until it has the right molecule. + +However, the machine has to be calibrated before it can be used. Calibration involves determining the number of molecules that can be generated in one step from a given starting point. + +For example, imagine a simpler machine that supports only the following replacements: + +``` +H => HO +H => OH +O => HH +``` + +Given the replacements above and starting with `HOH`, the following molecules could be generated: + + + - `HOOH` (via `H => HO` on the first `H`). + - `HOHO` (via `H => HO` on the second `H`). + - `OHOH` (via `H => OH` on the first `H`). + - `HOOH` (via `H => OH` on the second `H`). + - `HHHH` (via `O => HH`). + +So, in the example above, there are `4` *distinct* molecules (not five, because `HOOH` appears twice) after one replacement from `HOH`. Santa's favorite molecule, `HOHOHO`, can become `7` *distinct* molecules (over nine replacements: six from `H`, and three from `O`). + +The machine replaces without regard for the surrounding characters. For example, given the string `H2O`, the transition `H => OO` would result in `OO2O`. + +Your puzzle input describes all of the possible replacements and, at the bottom, the medicine molecule for which you need to calibrate the machine. *How many distinct molecules can be created* after all the different ways you can do one replacement on the medicine molecule? + + +## --- Part Two --- +Now that the machine is calibrated, you're ready to begin molecule fabrication. + +Molecule fabrication always begins with just a single electron, `e`, and applying replacements one at a time, just like the ones during calibration. + +For example, suppose you have the following replacements: + +``` +e => H +e => O +H => HO +H => OH +O => HH +``` + +If you'd like to make `HOH`, you start with `e`, and then make the following replacements: + + + - `e => O` to get `O` + - `O => HH` to get `HH` + - `H => OH` (on the second `H`) to get `HOH` + +So, you could make `HOH` after *`3` steps*. Santa's favorite molecule, `HOHOHO`, can be made in *`6` steps*. + +How long will it take to make the medicine? Given the available *replacements* and the *medicine molecule* in your puzzle input, what is the *fewest number of steps* to go from `e` to the medicine molecule? + + diff --git a/2015/Day19/input.in b/2015/Day19/input.in index e9fd053f8..b0515c05a 100644 Binary files a/2015/Day19/input.in and b/2015/Day19/input.in differ diff --git a/2015/Day20/README.md b/2015/Day20/README.md index 7948d8a4b..f07f7a25b 100644 --- a/2015/Day20/README.md +++ b/2015/Day20/README.md @@ -1,6 +1,38 @@ +original source: [https://adventofcode.com/2015/day/20](https://adventofcode.com/2015/day/20) ## --- Day 20: Infinite Elves and Infinite Houses --- To keep the Elves busy, Santa has them deliver some presents by hand, door-to-door. He sends them down a street with infinite houses numbered sequentially: `1`, `2`, `3`, `4`, `5`, and so on. Each Elf is assigned a number, too, and delivers presents to houses based on that number: -Read the [full puzzle](https://adventofcode.com/2015/day/20). \ No newline at end of file + + - The first Elf (number `1`) delivers presents to every house: `1`, `2`, `3`, `4`, `5`, .... + - The second Elf (number `2`) delivers presents to every second house: `2`, `4`, `6`, `8`, `10`, .... + - Elf number `3` delivers presents to every third house: `3`, `6`, `9`, `12`, `15`, .... + +There are infinitely many Elves, numbered starting with `1`. Each Elf delivers presents equal to *ten times* his or her number at each house. + +So, the first nine houses on the street end up like this: + +``` +House 1 got 10 presents. +House 2 got 30 presents. +House 3 got 40 presents. +House 4 got 70 presents. +House 5 got 60 presents. +House 6 got 120 presents. +House 7 got 80 presents. +House 8 got 150 presents. +House 9 got 130 presents. +``` + +The first house gets `10` presents: it is visited only by Elf `1`, which delivers `1 * 10 = 10` presents. The fourth house gets `70` presents, because it is visited by Elves `1`, `2`, and `4`, for a total of `10 + 20 + 40 = 70` presents. + +What is the *lowest house number* of the house to get at least as many presents as the number in your puzzle input? + + +## --- Part Two --- +The Elves decide they don't want to visit an infinite number of houses. Instead, each Elf will stop after delivering presents to `50` houses. To make up for it, they decide to deliver presents equal to *eleven times* their number at each house. + +With these changes, what is the new *lowest house number* of the house to get at least as many presents as the number in your puzzle input? + + diff --git a/2015/Day20/input.in b/2015/Day20/input.in index 70de3846e..f0d833616 100644 Binary files a/2015/Day20/input.in and b/2015/Day20/input.in differ diff --git a/2015/Day21/README.md b/2015/Day21/README.md index b35a9cffb..16083551f 100644 --- a/2015/Day21/README.md +++ b/2015/Day21/README.md @@ -1,6 +1,60 @@ +original source: [https://adventofcode.com/2015/day/21](https://adventofcode.com/2015/day/21) ## --- Day 21: RPG Simulator 20XX --- Little Henry Case got a new video game for Christmas. It's an [RPG](https://en.wikipedia.org/wiki/Role-playing_video_game), and he's stuck on a boss. He needs to know what equipment to buy at the shop. He hands you the [controller](https://en.wikipedia.org/wiki/Game_controller). In this game, the player (you) and the enemy (the boss) take turns attacking. The player always goes first. Each attack reduces the opponent's hit points by at least `1`. The first character at or below `0` hit points loses. -Read the [full puzzle](https://adventofcode.com/2015/day/21). \ No newline at end of file +Damage dealt by an attacker each turn is equal to the attacker's damage score minus the defender's armor score. An attacker always does at least `1` damage. So, if the attacker has a damage score of `8`, and the defender has an armor score of `3`, the defender loses `5` hit points. If the defender had an armor score of `300`, the defender would still lose `1` hit point. + +Your damage score and armor score both start at zero. They can be increased by buying items in exchange for gold. You start with no items and have as much gold as you need. Your total damage or armor is equal to the sum of those stats from all of your items. You have *100 hit points*. + +Here is what the item shop is selling: + +``` +Weapons: Cost Damage Armor +Dagger 8 4 0 +Shortsword 10 5 0 +Warhammer 25 6 0 +Longsword 40 7 0 +Greataxe 74 8 0 + +Armor: Cost Damage Armor +Leather 13 0 1 +Chainmail 31 0 2 +Splintmail 53 0 3 +Bandedmail 75 0 4 +Platemail 102 0 5 + +Rings: Cost Damage Armor +Damage +1 25 1 0 +Damage +2 50 2 0 +Damage +3 100 3 0 +Defense +1 20 0 1 +Defense +2 40 0 2 +Defense +3 80 0 3 +``` + +You must buy exactly one weapon; no dual-wielding. Armor is optional, but you can't use more than one. You can buy 0-2 rings (at most one for each hand). You must use any items you buy. The shop only has one of each item, so you can't buy, for example, two rings of Damage +3. + +For example, suppose you have `8` hit points, `5` damage, and `5` armor, and that the boss has `12` hit points, `7` damage, and `2` armor: + + + - The player deals `5-2 = 3` damage; the boss goes down to 9 hit points. + - The boss deals `7-5 = 2` damage; the player goes down to 6 hit points. + - The player deals `5-2 = 3` damage; the boss goes down to 6 hit points. + - The boss deals `7-5 = 2` damage; the player goes down to 4 hit points. + - The player deals `5-2 = 3` damage; the boss goes down to 3 hit points. + - The boss deals `7-5 = 2` damage; the player goes down to 2 hit points. + - The player deals `5-2 = 3` damage; the boss goes down to 0 hit points. + +In this scenario, the player wins! (Barely.) + +You have *100 hit points*. The boss's actual stats are in your puzzle input. What is *the least amount of gold you can spend* and still win the fight? + + +## --- Part Two --- +Turns out the shopkeeper is working with the boss, and can persuade you to buy whatever items he wants. The other rules still apply, and he still only has one of each item. + +What is the *most* amount of gold you can spend and still *lose* the fight? + + diff --git a/2015/Day21/input.in b/2015/Day21/input.in index 86a205cfd..e74905192 100644 Binary files a/2015/Day21/input.in and b/2015/Day21/input.in differ diff --git a/2015/Day22/README.md b/2015/Day22/README.md index 26a245daa..a2659cf82 100644 --- a/2015/Day22/README.md +++ b/2015/Day22/README.md @@ -1,6 +1,125 @@ +original source: [https://adventofcode.com/2015/day/22](https://adventofcode.com/2015/day/22) ## --- Day 22: Wizard Simulator 20XX --- Little Henry Case decides that defeating bosses with [swords and stuff](21) is boring. Now he's playing the game with a wizard. Of course, he gets stuck on another boss and needs your help again. In this version, combat still proceeds with the player and the boss taking alternating turns. The player still goes first. Now, however, you don't get any equipment; instead, you must choose one of your spells to cast. The first character at or below `0` hit points loses. -Read the [full puzzle](https://adventofcode.com/2015/day/22). \ No newline at end of file +Since you're a wizard, you don't get to wear armor, and you can't attack normally. However, since you do *magic damage*, your opponent's armor is ignored, and so the boss effectively has zero armor as well. As before, if armor (from a spell, in this case) would reduce damage below `1`, it becomes `1` instead - that is, the boss' attacks always deal at least `1` damage. + +On each of your turns, you must select one of your spells to cast. If you cannot afford to cast any spell, you lose. Spells cost *mana*; you start with *500* mana, but have no maximum limit. You must have enough mana to cast a spell, and its cost is immediately deducted when you cast it. Your spells are Magic Missile, Drain, Shield, Poison, and Recharge. + + + - *Magic Missile* costs `53` mana. It instantly does `4` damage. + - *Drain* costs `73` mana. It instantly does `2` damage and heals you for `2` hit points. + - *Shield* costs `113` mana. It starts an *effect* that lasts for `6` turns. While it is active, your armor is increased by `7`. + - *Poison* costs `173` mana. It starts an *effect* that lasts for `6` turns. At the start of each turn while it is active, it deals the boss `3` damage. + - *Recharge* costs `229` mana. It starts an *effect* that lasts for `5` turns. At the start of each turn while it is active, it gives you `101` new mana. + +*Effects* all work the same way. Effects apply at the start of both the player's turns and the boss' turns. Effects are created with a timer (the number of turns they last); at the start of each turn, after they apply any effect they have, their timer is decreased by one. If this decreases the timer to zero, the effect ends. You cannot cast a spell that would start an effect which is already active. However, effects can be started on the same turn they end. + +For example, suppose the player has `10` hit points and `250` mana, and that the boss has `13` hit points and `8` damage: + +``` +-- Player turn -- +- Player has 10 hit points, 0 armor, 250 mana +- Boss has 13 hit points +Player casts Poison. + +-- Boss turn -- +- Player has 10 hit points, 0 armor, 77 mana +- Boss has 13 hit points +Poison deals 3 damage; its timer is now 5. +Boss attacks for 8 damage. + +-- Player turn -- +- Player has 2 hit points, 0 armor, 77 mana +- Boss has 10 hit points +Poison deals 3 damage; its timer is now 4. +Player casts Magic Missile, dealing 4 damage. + +-- Boss turn -- +- Player has 2 hit points, 0 armor, 24 mana +- Boss has 3 hit points +Poison deals 3 damage. This kills the boss, and the player wins. +``` + +Now, suppose the same initial conditions, except that the boss has `14` hit points instead: + +``` +-- Player turn -- +- Player has 10 hit points, 0 armor, 250 mana +- Boss has 14 hit points +Player casts Recharge. + +-- Boss turn -- +- Player has 10 hit points, 0 armor, 21 mana +- Boss has 14 hit points +Recharge provides 101 mana; its timer is now 4. +Boss attacks for 8 damage! + +-- Player turn -- +- Player has 2 hit points, 0 armor, 122 mana +- Boss has 14 hit points +Recharge provides 101 mana; its timer is now 3. +Player casts Shield, increasing armor by 7. + +-- Boss turn -- +- Player has 2 hit points, 7 armor, 110 mana +- Boss has 14 hit points +Shield's timer is now 5. +Recharge provides 101 mana; its timer is now 2. +Boss attacks for 8 - 7 = 1 damage! + +-- Player turn -- +- Player has 1 hit point, 7 armor, 211 mana +- Boss has 14 hit points +Shield's timer is now 4. +Recharge provides 101 mana; its timer is now 1. +Player casts Drain, dealing 2 damage, and healing 2 hit points. + +-- Boss turn -- +- Player has 3 hit points, 7 armor, 239 mana +- Boss has 12 hit points +Shield's timer is now 3. +Recharge provides 101 mana; its timer is now 0. +Recharge wears off. +Boss attacks for 8 - 7 = 1 damage! + +-- Player turn -- +- Player has 2 hit points, 7 armor, 340 mana +- Boss has 12 hit points +Shield's timer is now 2. +Player casts Poison. + +-- Boss turn -- +- Player has 2 hit points, 7 armor, 167 mana +- Boss has 12 hit points +Shield's timer is now 1. +Poison deals 3 damage; its timer is now 5. +Boss attacks for 8 - 7 = 1 damage! + +-- Player turn -- +- Player has 1 hit point, 7 armor, 167 mana +- Boss has 9 hit points +Shield's timer is now 0. +Shield wears off, decreasing armor by 7. +Poison deals 3 damage; its timer is now 4. +Player casts Magic Missile, dealing 4 damage. + +-- Boss turn -- +- Player has 1 hit point, 0 armor, 114 mana +- Boss has 2 hit points +Poison deals 3 damage. This kills the boss, and the player wins. +``` + +You start with *50 hit points* and *500 mana points*. The boss's actual stats are in your puzzle input. What is the *least amount of mana* you can spend and still win the fight? (Do not include mana recharge effects as "spending" negative mana.) + + +## --- Part Two --- +On the next run through the game, you increase the difficulty to *hard*. + +At the start of each *player turn* (before any other effects apply), you lose `1` hit point. If this brings you to or below `0` hit points, you lose. + +With the same starting stats for you and the boss, what is the *least amount of mana* you can spend and still win the fight? + + diff --git a/2015/Day22/input.in b/2015/Day22/input.in index c3d03ea5f..db93bd09a 100644 Binary files a/2015/Day22/input.in and b/2015/Day22/input.in differ diff --git a/2015/Day23/README.md b/2015/Day23/README.md index 03c6983b0..3b3556deb 100644 --- a/2015/Day23/README.md +++ b/2015/Day23/README.md @@ -1,6 +1,34 @@ +original source: [https://adventofcode.com/2015/day/23](https://adventofcode.com/2015/day/23) ## --- Day 23: Opening the Turing Lock --- Little Jane Marie just got her very first computer for Christmas from some unknown benefactor. It comes with instructions and an example program, but the computer itself seems to be malfunctioning. She's curious what the program does, and would like you to help her run it. The manual explains that the computer supports two [registers](https://en.wikipedia.org/wiki/Processor_register) and six [instructions](https://en.wikipedia.org/wiki/Instruction_set) (truly, it goes on to remind the reader, a state-of-the-art technology). The registers are named `a` and `b`, can hold any [non-negative integer](https://en.wikipedia.org/wiki/Natural_number), and begin with a value of `0`. The instructions are as follows: -Read the [full puzzle](https://adventofcode.com/2015/day/23). \ No newline at end of file + + - `hlf r` sets register `r` to *half* its current value, then continues with the next instruction. + - `tpl r` sets register `r` to *triple* its current value, then continues with the next instruction. + - `inc r` *increments* register `r`, adding `1` to it, then continues with the next instruction. + - `jmp offset` is a *jump*; it continues with the instruction `offset` away *relative to itself*. + - `jie r, offset` is like `jmp`, but only jumps if register `r` is *even* ("jump if even"). + - `jio r, offset` is like `jmp`, but only jumps if register `r` is `1` ("jump if *one*", not odd). + +All three jump instructions work with an *offset* relative to that instruction. The offset is always written with a prefix `+` or `-` to indicate the direction of the jump (forward or backward, respectively). For example, `jmp +1` would simply continue with the next instruction, while `jmp +0` would continuously jump back to itself forever. + +The program exits when it tries to run an instruction beyond the ones defined. + +For example, this program sets `a` to `2`, because the `jio` instruction causes it to skip the `tpl` instruction: + +``` +inc a +jio a, +2 +tpl a +inc a +``` + +What is *the value in register `b`* when the program in your puzzle input is finished executing? + + +## --- Part Two --- +The unknown benefactor is *very* thankful for releasi-- er, helping little Jane Marie with her computer. Definitely not to distract you, what is the value in register `b` after the program is finished executing if register `a` starts as `1` instead? + + diff --git a/2015/Day23/input.in b/2015/Day23/input.in index a34fa99f1..79d96248e 100644 Binary files a/2015/Day23/input.in and b/2015/Day23/input.in differ diff --git a/2015/Day24/README.md b/2015/Day24/README.md index c00ce7cf2..2c1c9f643 100644 --- a/2015/Day24/README.md +++ b/2015/Day24/README.md @@ -1,6 +1,60 @@ +original source: [https://adventofcode.com/2015/day/24](https://adventofcode.com/2015/day/24) ## --- Day 24: It Hangs in the Balance --- It's Christmas Eve, and Santa is loading up the sleigh for this year's deliveries. However, there's one small problem: he can't get the sleigh to balance. If it isn't balanced, he can't defy physics, and nobody gets presents this year. No pressure. -Read the [full puzzle](https://adventofcode.com/2015/day/24). \ No newline at end of file +Santa has provided you a list of the weights of every package he needs to fit on the sleigh. The packages need to be split into *three groups of exactly the same weight*, and every package has to fit. The first group goes in the passenger compartment of the sleigh, and the second and third go in containers on either side. Only when all three groups weigh exactly the same amount will the sleigh be able to fly. Defying physics has rules, you know! + +Of course, that's not the only problem. The first group - the one going in the passenger compartment - needs *as few packages as possible* so that Santa has some legroom left over. It doesn't matter how many packages are in either of the other two groups, so long as all of the groups weigh the same. + +Furthermore, Santa tells you, if there are multiple ways to arrange the packages such that the fewest possible are in the first group, you need to choose the way where the first group has *the smallest quantum entanglement* to reduce the chance of any "complications". The quantum entanglement of a group of packages is the [product](https://en.wikipedia.org/wiki/Product_%28mathematics%29) of their weights, that is, the value you get when you multiply their weights together. Only consider quantum entanglement if the first group has the fewest possible number of packages in it and all groups weigh the same amount. + +For example, suppose you have ten packages with weights `1` through `5` and `7` through `11`. For this situation, some of the unique first groups, their quantum entanglements, and a way to divide the remaining packages are as follows: + +``` +Group 1; Group 2; Group 3 +11 9 (QE= 99); 10 8 2; 7 5 4 3 1 +10 9 1 (QE= 90); 11 7 2; 8 5 4 3 +10 8 2 (QE=160); 11 9; 7 5 4 3 1 +10 7 3 (QE=210); 11 9; 8 5 4 2 1 +10 5 4 1 (QE=200); 11 9; 8 7 3 2 +10 5 3 2 (QE=300); 11 9; 8 7 4 1 +10 4 3 2 1 (QE=240); 11 9; 8 7 5 +9 8 3 (QE=216); 11 7 2; 10 5 4 1 +9 7 4 (QE=252); 11 8 1; 10 5 3 2 +9 5 4 2 (QE=360); 11 8 1; 10 7 3 +8 7 5 (QE=280); 11 9; 10 4 3 2 1 +8 5 4 3 (QE=480); 11 9; 10 7 2 1 +7 5 4 3 1 (QE=420); 11 9; 10 8 2 +``` + +Of these, although `10 9 1` has the smallest quantum entanglement (`90`), the configuration with only two packages, `11 9`, in the passenger compartment gives Santa the most legroom and wins. In this situation, the quantum entanglement for the ideal configuration is therefore `99`. Had there been two configurations with only two packages in the first group, the one with the smaller quantum entanglement would be chosen. + +What is the *quantum entanglement* of the first group of packages in the ideal configuration? + + +## --- Part Two --- +That's weird... the sleigh still isn't balancing. + +"Ho ho ho", Santa muses to himself. "I forgot the trunk". + +Balance the sleigh again, but this time, separate the packages into *four groups* instead of three. The other constraints still apply. + +Given the example packages above, this would be some of the new unique first groups, their quantum entanglements, and one way to divide the remaining packages: + +``` + +11 4 (QE=44); 10 5; 9 3 2 1; 8 7 +10 5 (QE=50); 11 4; 9 3 2 1; 8 7 +9 5 1 (QE=45); 11 4; 10 3 2; 8 7 +9 4 2 (QE=72); 11 3 1; 10 5; 8 7 +9 3 2 1 (QE=54); 11 4; 10 5; 8 7 +8 7 (QE=56); 11 4; 10 5; 9 3 2 1 +``` + +Of these, there are three arrangements that put the minimum (two) number of packages in the first group: `11 4`, `10 5`, and `8 7`. Of these, `11 4` has the lowest quantum entanglement, and so it is selected. + +Now, what is the *quantum entanglement* of the first group of packages in the ideal configuration? + + diff --git a/2015/Day24/input.in b/2015/Day24/input.in index 3d36932f3..502fad752 100644 Binary files a/2015/Day24/input.in and b/2015/Day24/input.in differ diff --git a/2015/Day25/README.md b/2015/Day25/README.md index 9107dfdd5..cbb486578 100644 --- a/2015/Day25/README.md +++ b/2015/Day25/README.md @@ -1,6 +1,57 @@ +original source: [https://adventofcode.com/2015/day/25](https://adventofcode.com/2015/day/25) ## --- Day 25: Let It Snow --- Merry Christmas! Santa is booting up his weather machine; looks like you might get a [white Christmas](1) after all. The weather machine beeps! On the console of the machine is a copy protection message asking you to [enter a code from the instruction manual](https://en.wikipedia.org/wiki/Copy_protection#Early_video_games). Apparently, it refuses to run unless you give it that code. No problem; you'll just look up the code in the-- -Read the [full puzzle](https://adventofcode.com/2015/day/25). \ No newline at end of file +"Ho ho ho", Santa ponders aloud. "I can't seem to find the manual." + +You look up the support number for the manufacturer and give them a call. Good thing, too - that 49th star wasn't going to earn itself. + +"Oh, that machine is quite old!", they tell you. "That model went out of support six minutes ago, and we just finished shredding all of the manuals. I bet we can find you the code generation algorithm, though." + +After putting you on hold for twenty minutes (your call is *very* important to them, it reminded you repeatedly), they finally find an engineer that remembers how the code system works. + +The codes are printed on an infinite sheet of paper, starting in the top-left corner. The codes are filled in by diagonals: starting with the first row with an empty first box, the codes are filled in diagonally up and to the right. This process repeats until the [infinite paper is covered](https://en.wikipedia.org/wiki/Cantor's_diagonal_argument). So, the first few codes are filled in in this order: + +``` + | 1 2 3 4 5 6 +---+---+---+---+---+---+---+ + 1 | 1 3 6 10 15 21 + 2 | 2 5 9 14 20 + 3 | 4 8 13 19 + 4 | 7 12 18 + 5 | 11 17 + 6 | 16 +``` + +For example, the 12th code would be written to row `4`, column `2`; the 15th code would be written to row `1`, column `5`. + +The voice on the other end of the phone continues with how the codes are actually generated. The first code is `20151125`. After that, each code is generated by taking the previous one, multiplying it by `252533`, and then keeping the remainder from dividing that value by `33554393`. + +So, to find the second code (which ends up in row `2`, column `1`), start with the previous value, `20151125`. Multiply it by `252533` to get `5088824049625`. Then, divide that by `33554393`, which leaves a remainder of `31916031`. That remainder is the second code. + +"Oh!", says the voice. "It looks like we missed a scrap from one of the manuals. Let me read it to you." You write down his numbers: + +``` + | 1 2 3 4 5 6 +---+---------+---------+---------+---------+---------+---------+ + 1 | 20151125 18749137 17289845 30943339 10071777 33511524 + 2 | 31916031 21629792 16929656 7726640 15514188 4041754 + 3 | 16080970 8057251 1601130 7981243 11661866 16474243 + 4 | 24592653 32451966 21345942 9380097 10600672 31527494 + 5 | 77061 17552253 28094349 6899651 9250759 31663883 + 6 | 33071741 6796745 25397450 24659492 1534922 27995004 +``` + +"Now remember", the voice continues, "that's not even all of the first few numbers; for example, you're missing the one at 7,1 that would come before 6,2. But, it should be enough to let your-- oh, it's time for lunch! Bye!" The call disconnects. + +Santa looks nervous. Your puzzle input contains the message on the machine's console. *What code do you give the machine?* + + +## --- Part Two --- +The machine springs to life, then falls silent again. It beeps. "Insufficient fuel", the console reads. "*Fifty stars* are required before proceeding. *One star* is available." + +..."one star is available"? You check the fuel tank; sure enough, a lone star sits at the bottom, awaiting its friends. Looks like you need to provide 49 yourself. + + diff --git a/2015/Day25/input.in b/2015/Day25/input.in index d4c53d3dd..08d9d8f8b 100644 Binary files a/2015/Day25/input.in and b/2015/Day25/input.in differ diff --git a/2015/README.md b/2015/README.md index a98cc6d87..e642371f9 100644 --- a/2015/README.md +++ b/2015/README.md @@ -1,4 +1,6 @@ + # Advent of Code (2015) Check out https://adventofcode.com/2015. + diff --git a/2015/SplashScreen.cs b/2015/SplashScreen.cs index 64c664e9c..1277b4ae5 100644 --- a/2015/SplashScreen.cs +++ b/2015/SplashScreen.cs @@ -1,3 +1,4 @@ + using System; namespace AdventOfCode.Y2015; @@ -8,507 +9,491 @@ public void Show() { var color = Console.ForegroundColor; Write(0xcc00, false, " ▄█▄ ▄▄█ ▄ ▄ ▄▄▄ ▄▄ ▄█▄ ▄▄▄ ▄█ ▄▄ ▄▄▄ ▄▄█ ▄▄▄\n █▄█ █ █ █ █ █▄█ █ █ █ █ █ █▄ "); - Write(0xcc00, false, " █ █ █ █ █ █▄█\n █ █ █▄█ ▀▄▀ █▄▄ █ █ █▄ █▄█ █ █▄ █▄█ █▄█ █▄▄ {:year 2015}\n "); - Write(0xcc00, false, "\n "); - Write(0xffff66, true, "| \n \\|/ "); - Write(0xffff66, true, "\n --*-- "); - Write(0xcccccc, true, "25 "); - Write(0xffff66, true, "**\n "); - Write(0x9900, false, " >"); - Write(0xff9900, true, "o"); - Write(0x9900, false, "< "); - Write(0xcccccc, false, "24 "); - Write(0xffff66, false, "**\n "); - Write(0x9900, false, " >>"); - Write(0x66ff, true, "O"); - Write(0x9900, false, "<< "); - Write(0xcccccc, false, "23 "); - Write(0xffff66, false, "**\n "); - Write(0x9900, false, " >"); - Write(0xff9900, true, "o"); - Write(0x9900, false, ">>>"); - Write(0xff0000, true, "@"); - Write(0x9900, false, "< "); - Write(0xcccccc, false, "22 "); - Write(0xffff66, false, "**\n "); - Write(0x9900, false, " >"); - Write(0xff0000, true, "@"); - Write(0x9900, false, "<<"); - Write(0xffff66, true, "*"); - Write(0x9900, false, "<"); - Write(0x66ff, true, "O"); - Write(0x9900, false, "<< "); - Write(0xcccccc, false, "21 "); - Write(0xffff66, false, "**\n "); - Write(0x9900, false, " >>"); - Write(0xff9900, true, "o"); - Write(0x9900, false, ">>"); - Write(0x66ff, true, "O"); - Write(0x9900, false, ">"); - Write(0xff0000, true, "@"); - Write(0x9900, false, "<<< "); - Write(0xcccccc, false, "20 "); - Write(0xffff66, false, "**\n "); - Write(0x9900, false, " >"); - Write(0xff9900, true, "o"); - Write(0x9900, false, ">"); - Write(0xff9900, true, "o"); - Write(0x9900, false, ">"); - Write(0x66ff, true, "O"); - Write(0x9900, false, ">>"); - Write(0xff0000, true, "@"); - Write(0x9900, false, "<<<< "); - Write(0xcccccc, false, "19 "); - Write(0xffff66, false, "**\n "); - Write(0x9900, false, " >>"); - Write(0xff9900, true, "o"); - Write(0x9900, false, "<<<"); - Write(0x66ff, true, "O"); - Write(0x9900, false, "<"); - Write(0xff9900, true, "o"); - Write(0x9900, false, ">"); - Write(0xffff66, true, "*"); - Write(0x9900, false, "<"); - Write(0xffff66, true, "*"); - Write(0x9900, false, "<< "); - Write(0xcccccc, false, "18 "); - Write(0xffff66, false, "**\n "); - Write(0x9900, false, " >"); - Write(0xff0000, true, "@"); - Write(0x9900, false, ">>>"); - Write(0xff9900, true, "o"); - Write(0x9900, false, ">>>"); - Write(0xff0000, true, "@"); - Write(0x9900, false, ">"); - Write(0xff9900, true, "o"); - Write(0x9900, false, "<<"); - Write(0x66ff, true, "O"); - Write(0x9900, false, "<< "); - Write(0xcccccc, false, "17 "); - Write(0xffff66, false, "**\n "); - Write(0x9900, false, " >>"); - Write(0xffff66, true, "*"); - Write(0x9900, false, ">>"); - Write(0x66ff, true, "O"); - Write(0x9900, false, ">"); - Write(0xff0000, true, "@"); - Write(0x9900, false, ">>>"); - Write(0xffff66, true, "*"); - Write(0x9900, false, "<<<"); - Write(0xff9900, true, "o"); - Write(0x9900, false, ">"); - Write(0x66ff, true, "O"); - Write(0x9900, false, "< "); - Write(0xcccccc, false, "16 "); - Write(0xffff66, false, "**\n "); - Write(0x9900, false, " >>"); - Write(0xff0000, true, "@"); - Write(0x9900, false, ">>"); - Write(0xff9900, true, "o"); - Write(0x9900, false, ">"); - Write(0xffff66, true, "*"); - Write(0x9900, false, ">>>"); - Write(0xff0000, true, "@"); - Write(0x9900, false, "<<<"); - Write(0x66ff, true, "O"); - Write(0x9900, false, "<"); - Write(0x66ff, true, "O"); - Write(0x9900, false, "<<< "); - Write(0xcccccc, false, "15 "); - Write(0xffff66, false, "**\n "); - Write(0x9900, false, " >>"); - Write(0xff0000, true, "@"); - Write(0x9900, false, "<<"); - Write(0xff9900, true, "o"); - Write(0x9900, false, "<<<"); - Write(0xff0000, true, "@"); - Write(0x9900, false, ">>"); - Write(0xffff66, true, "*"); - Write(0x9900, false, "<<"); - Write(0xff0000, true, "@"); - Write(0x9900, false, ">"); - Write(0xff0000, true, "@"); - Write(0x9900, false, ">"); - Write(0xff0000, true, "@"); - Write(0x9900, false, ">"); - Write(0x66ff, true, "O"); - Write(0x9900, false, "< "); - Write(0xcccccc, false, "14 "); - Write(0xffff66, false, "**\n "); - Write(0x9900, false, " >"); - Write(0xffff66, true, "*"); - Write(0x9900, false, "<<"); - Write(0x66ff, true, "O"); - Write(0x9900, false, ">>>"); - Write(0xffff66, true, "*"); - Write(0x9900, false, "<<"); - Write(0xffff66, true, "*"); - Write(0x9900, false, "<"); - Write(0xff0000, true, "@"); - Write(0x9900, false, "<"); - Write(0x66ff, true, "O"); - Write(0x9900, false, "<<<"); - Write(0x66ff, true, "O"); - Write(0x9900, false, "<<"); - Write(0x66ff, true, "O"); - Write(0x9900, false, "<< "); - Write(0xcccccc, false, "13 "); - Write(0xffff66, false, "**\n "); - Write(0x9900, false, " >"); - Write(0xff0000, true, "@"); - Write(0x9900, false, ">>>"); - Write(0xff9900, true, "o"); - Write(0x9900, false, ">>>"); - Write(0xff0000, true, "@"); - Write(0x9900, false, "<"); - Write(0xff9900, true, "o"); - Write(0x9900, false, ">>"); - Write(0xff0000, true, "@"); - Write(0x9900, false, "<<"); - Write(0x66ff, true, "O"); - Write(0x9900, false, ">>>"); - Write(0x66ff, true, "O"); - Write(0x9900, false, "<<<"); - Write(0xff9900, true, "o"); - Write(0x9900, false, "< "); - Write(0xcccccc, false, "12 "); - Write(0xffff66, false, "**\n "); - Write(0x9900, false, " >"); - Write(0xff9900, true, "o"); - Write(0x9900, false, ">"); - Write(0x66ff, true, "O"); - Write(0x9900, false, "<"); - Write(0xff0000, true, "@"); - Write(0x9900, false, "<<<"); - Write(0xff9900, true, "o"); - Write(0x9900, false, "<"); - Write(0xffff66, true, "*"); - Write(0x9900, false, ">"); - Write(0xff0000, true, "@"); - Write(0x9900, false, "<<"); - Write(0x66ff, true, "O"); - Write(0x9900, false, "<<<"); - Write(0x66ff, true, "O"); - Write(0x9900, false, ">>>"); - Write(0xffff66, true, "*"); - Write(0x9900, false, ">"); - Write(0x66ff, true, "O"); - Write(0x9900, false, "<< "); - Write(0xcccccc, false, "11 "); - Write(0xffff66, false, "**\n "); - Write(0x9900, false, " >"); - Write(0xff0000, true, "@"); - Write(0x9900, false, ">"); - Write(0xffff66, true, "*"); - Write(0x9900, false, ">>>"); - Write(0xff9900, true, "o"); - Write(0x9900, false, ">>"); - Write(0xff0000, true, "@"); - Write(0x9900, false, "<"); - Write(0x66ff, true, "O"); - Write(0x9900, false, ">"); - Write(0xff9900, true, "o"); - Write(0x9900, false, ">"); - Write(0xff0000, true, "@"); - Write(0x9900, false, "<"); - Write(0x66ff, true, "O"); - Write(0x9900, false, ">>>"); - Write(0xff0000, true, "@"); - Write(0x9900, false, ">"); - Write(0xffff66, true, "*"); - Write(0x9900, false, ">"); - Write(0xff9900, true, "o"); - Write(0x9900, false, "<<"); - Write(0x66ff, true, "O"); - Write(0x9900, false, "< "); - Write(0xcccccc, false, "10 "); - Write(0xffff66, false, "**\n "); - Write(0x9900, false, " >>"); - Write(0xff0000, true, "@"); - Write(0x9900, false, ">>>"); - Write(0xffff66, true, "*"); - Write(0x9900, false, ">>"); - Write(0xff9900, true, "o"); - Write(0x9900, false, "<"); - Write(0x66ff, true, "O"); - Write(0x9900, false, ">>>"); - Write(0xff9900, true, "o"); - Write(0x9900, false, ">"); - Write(0xff9900, true, "o"); - Write(0x9900, false, ">>"); - Write(0xff9900, true, "o"); - Write(0x9900, false, ">"); - Write(0x66ff, true, "O"); - Write(0x9900, false, "<<<"); - Write(0xffff66, true, "*"); - Write(0x9900, false, "<<<"); - Write(0x66ff, true, "O"); - Write(0x9900, false, "<< "); - Write(0xcccccc, false, " 9 "); - Write(0xffff66, false, "**\n "); - Write(0x9900, false, " >>"); - Write(0xff0000, true, "@"); - Write(0x9900, false, "<"); - Write(0xff9900, true, "o"); - Write(0x9900, false, ">>"); - Write(0x66ff, true, "O"); - Write(0x9900, false, ">"); - Write(0x66ff, true, "O"); - Write(0x9900, false, "<"); - Write(0xffff66, true, "*"); - Write(0x9900, false, "<<"); - Write(0x66ff, true, "O"); - Write(0x9900, false, ">"); - Write(0x66ff, true, "O"); - Write(0x9900, false, ">>"); - Write(0xffff66, true, "*"); - Write(0x9900, false, "<"); - Write(0xffff66, true, "*"); - Write(0x9900, false, "<"); - Write(0xff9900, true, "o"); - Write(0x9900, false, "<<<"); - Write(0xffff66, true, "*"); - Write(0x9900, false, ">"); - Write(0xffff66, true, "*"); - Write(0x9900, false, "<"); - Write(0xff9900, true, "o"); - Write(0x9900, false, ">"); - Write(0xff9900, true, "o"); - Write(0x9900, false, "< "); - Write(0xcccccc, false, " 8 "); - Write(0xffff66, false, "**\n "); - Write(0x9900, false, " >>"); - Write(0x66ff, true, "O"); - Write(0x9900, false, "<"); - Write(0x66ff, true, "O"); - Write(0x9900, false, "<"); - Write(0xff9900, true, "o"); - Write(0x9900, false, "<<"); - Write(0xff9900, true, "o"); - Write(0x9900, false, ">>"); - Write(0xff0000, true, "@"); - Write(0x9900, false, ">>"); - Write(0xff9900, true, "o"); - Write(0x9900, false, "<<"); - Write(0xffff66, true, "*"); - Write(0x9900, false, "<<<"); - Write(0xff9900, true, "o"); - Write(0x9900, false, ">>>"); - Write(0x66ff, true, "O"); - Write(0x9900, false, "<"); - Write(0xff9900, true, "o"); - Write(0x9900, false, "<<"); - Write(0xff9900, true, "o"); - Write(0x9900, false, ">"); - Write(0xffff66, true, "*"); - Write(0x9900, false, "<"); - Write(0xff0000, true, "@"); - Write(0x9900, false, "< "); - Write(0xcccccc, false, " 7 "); - Write(0xffff66, false, "**\n "); - Write(0x9900, false, " >>"); - Write(0xff0000, true, "@"); - Write(0x9900, false, "<"); - Write(0xff9900, true, "o"); - Write(0x9900, false, ">>>"); - Write(0x66ff, true, "O"); - Write(0x9900, false, ">"); - Write(0x66ff, true, "O"); - Write(0x9900, false, "<"); - Write(0xff9900, true, "o"); - Write(0x9900, false, ">>"); - Write(0x66ff, true, "O"); - Write(0x9900, false, "<<<"); - Write(0xffff66, true, "*"); - Write(0x9900, false, "<"); - Write(0xff9900, true, "o"); - Write(0x9900, false, "<<"); - Write(0xff9900, true, "o"); - Write(0x9900, false, "<<"); - Write(0xffff66, true, "*"); - Write(0x9900, false, "<<"); - Write(0x66ff, true, "O"); - Write(0x9900, false, "<<"); - Write(0xff0000, true, "@"); - Write(0x9900, false, ">>>"); - Write(0xff9900, true, "o"); - Write(0x9900, false, "< "); - Write(0xcccccc, false, " 6 "); - Write(0xffff66, false, "**\n "); - Write(0x9900, false, " >>"); - Write(0xff0000, true, "@"); - Write(0x9900, false, ">>>"); - Write(0x66ff, true, "O"); - Write(0x9900, false, ">"); - Write(0xff0000, true, "@"); - Write(0x9900, false, ">"); - Write(0xffff66, true, "*"); - Write(0x9900, false, "<<<"); - Write(0xff9900, true, "o"); - Write(0x9900, false, ">"); - Write(0xffff66, true, "*"); - Write(0x9900, false, ">"); - Write(0xff9900, true, "o"); - Write(0x9900, false, "<"); - Write(0xff9900, true, "o"); - Write(0x9900, false, ">>"); - Write(0xff0000, true, "@"); - Write(0x9900, false, "<<<"); - Write(0xff0000, true, "@"); - Write(0x9900, false, "<<"); - Write(0xffff66, true, "*"); - Write(0x9900, false, ">>"); - Write(0xff0000, true, "@"); - Write(0x9900, false, "<"); - Write(0x66ff, true, "O"); - Write(0x9900, false, "<<"); - Write(0xffff66, true, "*"); - Write(0x9900, false, "<< "); - Write(0xcccccc, false, " 5 "); - Write(0xffff66, false, "**\n "); - Write(0x9900, false, " >>"); - Write(0x66ff, true, "O"); - Write(0x9900, false, "<<"); - Write(0x66ff, true, "O"); - Write(0x9900, false, "<<<"); - Write(0xffff66, true, "*"); - Write(0x9900, false, "<"); - Write(0xffff66, true, "*"); - Write(0x9900, false, "<<<"); - Write(0xffff66, true, "*"); - Write(0x9900, false, "<<"); - Write(0x66ff, true, "O"); - Write(0x9900, false, "<<"); - Write(0xff0000, true, "@"); - Write(0x9900, false, "<<"); - Write(0xff9900, true, "o"); - Write(0x9900, false, ">>"); - Write(0xffff66, true, "*"); - Write(0x9900, false, ">>"); - Write(0xff0000, true, "@"); - Write(0x9900, false, "<"); - Write(0x66ff, true, "O"); - Write(0x9900, false, "<<"); - Write(0xff9900, true, "o"); - Write(0x9900, false, "<<"); - Write(0xff0000, true, "@"); - Write(0x9900, false, "<<<< "); - Write(0xcccccc, false, " 4 "); - Write(0xffff66, false, "**\n "); - Write(0x9900, false, " >"); - Write(0xff0000, true, "@"); - Write(0x9900, false, "<<"); - Write(0x66ff, true, "O"); - Write(0x9900, false, "<"); - Write(0xff0000, true, "@"); - Write(0x9900, false, ">>"); - Write(0x66ff, true, "O"); - Write(0x9900, false, ">>>"); - Write(0xffff66, true, "*"); - Write(0x9900, false, "<<"); - Write(0xff9900, true, "o"); - Write(0x9900, false, ">>>"); - Write(0xffff66, true, "*"); - Write(0x9900, false, ">"); - Write(0xff0000, true, "@"); - Write(0x9900, false, "<<"); - Write(0x66ff, true, "O"); - Write(0x9900, false, ">"); - Write(0x66ff, true, "O"); - Write(0x9900, false, ">"); - Write(0xffff66, true, "*"); - Write(0x9900, false, "<"); - Write(0x66ff, true, "O"); - Write(0x9900, false, ">>>"); - Write(0x66ff, true, "O"); - Write(0x9900, false, ">>"); - Write(0xff9900, true, "o"); - Write(0x9900, false, ">>>"); - Write(0xff0000, true, "@"); - Write(0x9900, false, "<< "); - Write(0xcccccc, false, " 3 "); - Write(0xffff66, false, "**\n "); - Write(0x9900, false, " >>"); - Write(0xff0000, true, "@"); - Write(0x9900, false, "<"); - Write(0xff0000, true, "@"); - Write(0x9900, false, ">"); - Write(0xff9900, true, "o"); - Write(0x9900, false, "<<"); - Write(0xff9900, true, "o"); - Write(0x9900, false, "<<<"); - Write(0xff9900, true, "o"); - Write(0x9900, false, ">>>"); - Write(0x66ff, true, "O"); - Write(0x9900, false, "<"); - Write(0xff0000, true, "@"); - Write(0x9900, false, "<<"); - Write(0xffff66, true, "*"); - Write(0x9900, false, ">"); - Write(0xffff66, true, "*"); - Write(0x9900, false, ">>>"); - Write(0xffff66, true, "*"); - Write(0x9900, false, "<"); - Write(0xff0000, true, "@"); - Write(0x9900, false, "<"); - Write(0xff0000, true, "@"); - Write(0x9900, false, ">>>"); - Write(0xffff66, true, "*"); - Write(0x9900, false, "<"); - Write(0xffff66, true, "*"); - Write(0x9900, false, ">"); - Write(0x66ff, true, "O"); - Write(0x9900, false, "<"); - Write(0xff0000, true, "@"); - Write(0x9900, false, ">>"); - Write(0x66ff, true, "O"); - Write(0x9900, false, "< "); - Write(0xcccccc, false, " 2 "); - Write(0xffff66, false, "**\n "); - Write(0x9900, false, ">>"); - Write(0xffff66, true, "*"); - Write(0x9900, false, ">>"); - Write(0xff0000, true, "@"); - Write(0x9900, false, ">"); - Write(0xffff66, true, "*"); - Write(0x9900, false, "<<<"); - Write(0xffff66, true, "*"); - Write(0x9900, false, "<<"); - Write(0xff0000, true, "@"); - Write(0x9900, false, ">>"); - Write(0x66ff, true, "O"); - Write(0x9900, false, "<"); - Write(0xffff66, true, "*"); - Write(0x9900, false, "<<"); - Write(0xffff66, true, "*"); - Write(0x9900, false, "<<"); - Write(0xffff66, true, "*"); - Write(0x9900, false, ">>>"); - Write(0xff9900, true, "o"); - Write(0x9900, false, ">>>"); - Write(0xff0000, true, "@"); - Write(0x9900, false, "<<"); - Write(0x66ff, true, "O"); - Write(0x9900, false, "<"); - Write(0xffff66, true, "*"); - Write(0x9900, false, "<"); - Write(0xffff66, true, "*"); - Write(0x9900, false, ">>"); - Write(0xffff66, true, "*"); - Write(0x9900, false, "<<"); - Write(0xff9900, true, "o"); - Write(0x9900, false, "<< "); - Write(0xcccccc, false, " 1 "); - Write(0xffff66, false, "**\n "); - Write(0xcccccc, false, " | | \n | | "); - Write(0xcccccc, false, " \n _ _ __ ___|___|___ __ _ _ \n "); - Write(0xcccccc, false, " \n"); - + Write(0xcc00, false, " █ █ █ █ █ █▄█\n █ █ █▄█ ▀▄▀ █▄▄ █ █ █▄ █▄█ █ █▄ █▄█ █▄█ █▄▄ $year = 2015\n "); + Write(0xcc00, false, "\n "); + Write(0xffff66, true, "| \n \\|/ "); + Write(0xffff66, true, "\n --*-- "); + Write(0xcccccc, true, "25 "); + Write(0xffff66, true, "**\n "); + Write(0x9900, false, " >"); + Write(0xff9900, true, "o"); + Write(0x9900, false, "< "); + Write(0xcccccc, false, "24 "); + Write(0xffff66, false, "**\n "); + Write(0x9900, false, " >"); + Write(0x66ff, true, "O"); + Write(0x9900, false, "<<< "); + Write(0xcccccc, false, "23 "); + Write(0xffff66, false, "**\n "); + Write(0x9900, false, " >>"); + Write(0xffff66, true, "*"); + Write(0x9900, false, "<<"); + Write(0x66ff, true, "O"); + Write(0x9900, false, "< "); + Write(0xcccccc, false, "22 "); + Write(0xffff66, false, "**\n "); + Write(0x9900, false, " >>"); + Write(0xff0000, true, "@"); + Write(0x9900, false, "<"); + Write(0xff9900, true, "o"); + Write(0x9900, false, "<<<< "); + Write(0xcccccc, false, "21 "); + Write(0xffff66, false, "**\n "); + Write(0x9900, false, " >"); + Write(0xffff66, true, "*"); + Write(0x9900, false, ">>"); + Write(0xff9900, true, "o"); + Write(0x9900, false, ">"); + Write(0xff0000, true, "@"); + Write(0x9900, false, ">"); + Write(0xffff66, true, "*"); + Write(0x9900, false, "<< "); + Write(0xcccccc, false, "20 "); + Write(0xffff66, false, "**\n "); + Write(0x9900, false, " >>"); + Write(0xff9900, true, "o"); + Write(0x9900, false, ">"); + Write(0xff9900, true, "o"); + Write(0x9900, false, "<"); + Write(0x66ff, true, "O"); + Write(0x9900, false, "<"); + Write(0xff9900, true, "o"); + Write(0x9900, false, "<<"); + Write(0xff0000, true, "@"); + Write(0x9900, false, "< "); + Write(0xcccccc, false, "19 "); + Write(0xffff66, false, "**\n "); + Write(0x9900, false, " >>"); + Write(0xff9900, true, "o"); + Write(0x9900, false, ">"); + Write(0x66ff, true, "O"); + Write(0x9900, false, "<"); + Write(0x66ff, true, "O"); + Write(0x9900, false, ">"); + Write(0xff0000, true, "@"); + Write(0x9900, false, "<<"); + Write(0xffff66, true, "*"); + Write(0x9900, false, "<<< "); + Write(0xcccccc, false, "18 "); + Write(0xffff66, false, "**\n "); + Write(0x9900, false, " >"); + Write(0xff9900, true, "o"); + Write(0x9900, false, "<"); + Write(0x66ff, true, "O"); + Write(0x9900, false, "<"); + Write(0x66ff, true, "O"); + Write(0x9900, false, ">>"); + Write(0xff9900, true, "o"); + Write(0x9900, false, "<"); + Write(0xff0000, true, "@"); + Write(0x9900, false, "<<"); + Write(0x66ff, true, "O"); + Write(0x9900, false, "<"); + Write(0xffff66, true, "*"); + Write(0x9900, false, "< "); + Write(0xcccccc, false, "17 "); + Write(0xffff66, false, "**\n "); + Write(0x9900, false, " >"); + Write(0x66ff, true, "O"); + Write(0x9900, false, ">>"); + Write(0xffff66, true, "*"); + Write(0x9900, false, "<"); + Write(0xff0000, true, "@"); + Write(0x9900, false, "<"); + Write(0xff9900, true, "o"); + Write(0x9900, false, ">"); + Write(0xff0000, true, "@"); + Write(0x9900, false, ">>>"); + Write(0x66ff, true, "O"); + Write(0x9900, false, "<<"); + Write(0x66ff, true, "O"); + Write(0x9900, false, "< "); + Write(0xcccccc, false, "16 "); + Write(0xffff66, false, "**\n "); + Write(0x9900, false, " >>"); + Write(0x66ff, true, "O"); + Write(0x9900, false, ">>>"); + Write(0xff0000, true, "@"); + Write(0x9900, false, ">>"); + Write(0xffff66, true, "*"); + Write(0x9900, false, ">>"); + Write(0xff9900, true, "o"); + Write(0x9900, false, ">>>"); + Write(0xff0000, true, "@"); + Write(0x9900, false, "<"); + Write(0x66ff, true, "O"); + Write(0x9900, false, "<< "); + Write(0xcccccc, false, "15 "); + Write(0xffff66, false, "**\n "); + Write(0x9900, false, " >>"); + Write(0xff9900, true, "o"); + Write(0x9900, false, ">>"); + Write(0xff9900, true, "o"); + Write(0x9900, false, ">"); + Write(0xff9900, true, "o"); + Write(0x9900, false, ">"); + Write(0xff9900, true, "o"); + Write(0x9900, false, "<<<"); + Write(0xff9900, true, "o"); + Write(0x9900, false, ">"); + Write(0xffff66, true, "*"); + Write(0x9900, false, "<<<"); + Write(0xff0000, true, "@"); + Write(0x9900, false, ">"); + Write(0xffff66, true, "*"); + Write(0x9900, false, "< "); + Write(0xcccccc, false, "14 "); + Write(0xffff66, false, "**\n "); + Write(0x9900, false, " >>"); + Write(0x66ff, true, "O"); + Write(0x9900, false, "<<<"); + Write(0xff9900, true, "o"); + Write(0x9900, false, "<"); + Write(0xff9900, true, "o"); + Write(0x9900, false, ">>"); + Write(0x66ff, true, "O"); + Write(0x9900, false, "<"); + Write(0xff0000, true, "@"); + Write(0x9900, false, "<<"); + Write(0xff9900, true, "o"); + Write(0x9900, false, ">>>"); + Write(0xffff66, true, "*"); + Write(0x9900, false, "<<<< "); + Write(0xcccccc, false, "13 "); + Write(0xffff66, false, "**\n "); + Write(0x9900, false, " >>"); + Write(0xff9900, true, "o"); + Write(0x9900, false, ">"); + Write(0xff9900, true, "o"); + Write(0x9900, false, ">>"); + Write(0xff0000, true, "@"); + Write(0x9900, false, "<<"); + Write(0x66ff, true, "O"); + Write(0x9900, false, ">>"); + Write(0xffff66, true, "*"); + Write(0x9900, false, "<<"); + Write(0xff0000, true, "@"); + Write(0x9900, false, "<"); + Write(0x66ff, true, "O"); + Write(0x9900, false, ">>>"); + Write(0xff0000, true, "@"); + Write(0x9900, false, "<<<< "); + Write(0xcccccc, false, "12 "); + Write(0xffff66, false, "**\n "); + Write(0x9900, false, " >>"); + Write(0xff9900, true, "o"); + Write(0x9900, false, ">"); + Write(0xff0000, true, "@"); + Write(0x9900, false, ">"); + Write(0xffff66, true, "*"); + Write(0x9900, false, ">>"); + Write(0xffff66, true, "*"); + Write(0x9900, false, ">>>"); + Write(0xff9900, true, "o"); + Write(0x9900, false, "<<<"); + Write(0x66ff, true, "O"); + Write(0x9900, false, ">>>"); + Write(0xff9900, true, "o"); + Write(0x9900, false, "<"); + Write(0xff9900, true, "o"); + Write(0x9900, false, ">>>"); + Write(0x66ff, true, "O"); + Write(0x9900, false, "< "); + Write(0xcccccc, false, "11 "); + Write(0xffff66, false, "**\n "); + Write(0x9900, false, " >"); + Write(0x66ff, true, "O"); + Write(0x9900, false, "<<"); + Write(0xffff66, true, "*"); + Write(0x9900, false, ">"); + Write(0xffff66, true, "*"); + Write(0x9900, false, ">>"); + Write(0xff0000, true, "@"); + Write(0x9900, false, "<<<"); + Write(0xffff66, true, "*"); + Write(0x9900, false, ">>"); + Write(0xff9900, true, "o"); + Write(0x9900, false, "<"); + Write(0xffff66, true, "*"); + Write(0x9900, false, "<<<"); + Write(0xffff66, true, "*"); + Write(0x9900, false, "<"); + Write(0xff9900, true, "o"); + Write(0x9900, false, ">>>"); + Write(0x66ff, true, "O"); + Write(0x9900, false, "<< "); + Write(0xcccccc, false, "10 "); + Write(0xffff66, false, "**\n "); + Write(0x9900, false, " >>"); + Write(0x66ff, true, "O"); + Write(0x9900, false, ">"); + Write(0xff9900, true, "o"); + Write(0x9900, false, "<"); + Write(0xffff66, true, "*"); + Write(0x9900, false, ">"); + Write(0x66ff, true, "O"); + Write(0x9900, false, "<"); + Write(0xff0000, true, "@"); + Write(0x9900, false, ">>"); + Write(0xff9900, true, "o"); + Write(0x9900, false, "<"); + Write(0xffff66, true, "*"); + Write(0x9900, false, ">>>"); + Write(0xff0000, true, "@"); + Write(0x9900, false, ">>>"); + Write(0xff0000, true, "@"); + Write(0x9900, false, "<<<"); + Write(0xffff66, true, "*"); + Write(0x9900, false, ">>"); + Write(0xff0000, true, "@"); + Write(0x9900, false, "<< "); + Write(0xcccccc, false, " 9 "); + Write(0xffff66, false, "**\n "); + Write(0x9900, false, " >"); + Write(0xff0000, true, "@"); + Write(0x9900, false, ">>"); + Write(0xff9900, true, "o"); + Write(0x9900, false, "<<"); + Write(0xff9900, true, "o"); + Write(0x9900, false, ">>"); + Write(0xffff66, true, "*"); + Write(0x9900, false, ">"); + Write(0xff9900, true, "o"); + Write(0x9900, false, "<"); + Write(0xff9900, true, "o"); + Write(0x9900, false, "<<"); + Write(0x66ff, true, "O"); + Write(0x9900, false, ">>"); + Write(0xffff66, true, "*"); + Write(0x9900, false, "<<<"); + Write(0x66ff, true, "O"); + Write(0x9900, false, "<"); + Write(0xff9900, true, "o"); + Write(0x9900, false, ">>>"); + Write(0xff9900, true, "o"); + Write(0x9900, false, "<"); + Write(0xff9900, true, "o"); + Write(0x9900, false, "<< "); + Write(0xcccccc, false, " 8 "); + Write(0xffff66, false, "**\n "); + Write(0x9900, false, " >>"); + Write(0xffff66, true, "*"); + Write(0x9900, false, ">>"); + Write(0xffff66, true, "*"); + Write(0x9900, false, "<<"); + Write(0x66ff, true, "O"); + Write(0x9900, false, ">>>"); + Write(0xff0000, true, "@"); + Write(0x9900, false, "<"); + Write(0xff9900, true, "o"); + Write(0x9900, false, "<"); + Write(0x66ff, true, "O"); + Write(0x9900, false, ">>>"); + Write(0xff0000, true, "@"); + Write(0x9900, false, "<<<"); + Write(0x66ff, true, "O"); + Write(0x9900, false, "<"); + Write(0xff0000, true, "@"); + Write(0x9900, false, ">>"); + Write(0x66ff, true, "O"); + Write(0x9900, false, ">>"); + Write(0x66ff, true, "O"); + Write(0x9900, false, ">>"); + Write(0xff9900, true, "o"); + Write(0x9900, false, "< "); + Write(0xcccccc, false, " 7 "); + Write(0xffff66, false, "**\n "); + Write(0x9900, false, " >>"); + Write(0xff9900, true, "o"); + Write(0x9900, false, ">"); + Write(0xffff66, true, "*"); + Write(0x9900, false, ">>>"); + Write(0xffff66, true, "*"); + Write(0x9900, false, "<"); + Write(0xffff66, true, "*"); + Write(0x9900, false, ">"); + Write(0xffff66, true, "*"); + Write(0x9900, false, "<<<"); + Write(0xff0000, true, "@"); + Write(0x9900, false, "<<<"); + Write(0xffff66, true, "*"); + Write(0x9900, false, ">>>"); + Write(0xff9900, true, "o"); + Write(0x9900, false, "<<"); + Write(0xffff66, true, "*"); + Write(0x9900, false, ">>"); + Write(0xff0000, true, "@"); + Write(0x9900, false, ">"); + Write(0xff9900, true, "o"); + Write(0x9900, false, ">>"); + Write(0xff0000, true, "@"); + Write(0x9900, false, "<<< "); + Write(0xcccccc, false, " 6 "); + Write(0xffff66, false, "**\n "); + Write(0x9900, false, " >>"); + Write(0xff9900, true, "o"); + Write(0x9900, false, ">>>"); + Write(0xff0000, true, "@"); + Write(0x9900, false, "<<<"); + Write(0xff9900, true, "o"); + Write(0x9900, false, ">>"); + Write(0x66ff, true, "O"); + Write(0x9900, false, "<<<"); + Write(0xffff66, true, "*"); + Write(0x9900, false, "<<"); + Write(0xffff66, true, "*"); + Write(0x9900, false, ">>"); + Write(0xff9900, true, "o"); + Write(0x9900, false, ">"); + Write(0x66ff, true, "O"); + Write(0x9900, false, ">>"); + Write(0xff9900, true, "o"); + Write(0x9900, false, ">"); + Write(0xff9900, true, "o"); + Write(0x9900, false, ">>"); + Write(0x66ff, true, "O"); + Write(0x9900, false, "<<<"); + Write(0x66ff, true, "O"); + Write(0x9900, false, "<<< "); + Write(0xcccccc, false, " 5 "); + Write(0xffff66, false, "**\n "); + Write(0x9900, false, " >"); + Write(0xff0000, true, "@"); + Write(0x9900, false, "<"); + Write(0xffff66, true, "*"); + Write(0x9900, false, ">"); + Write(0xff0000, true, "@"); + Write(0x9900, false, ">"); + Write(0xff0000, true, "@"); + Write(0x9900, false, ">"); + Write(0xff9900, true, "o"); + Write(0x9900, false, "<<"); + Write(0xffff66, true, "*"); + Write(0x9900, false, ">"); + Write(0xff0000, true, "@"); + Write(0x9900, false, "<"); + Write(0xffff66, true, "*"); + Write(0x9900, false, "<<"); + Write(0x66ff, true, "O"); + Write(0x9900, false, "<<<"); + Write(0xffff66, true, "*"); + Write(0x9900, false, "<<"); + Write(0xff9900, true, "o"); + Write(0x9900, false, "<<<"); + Write(0x66ff, true, "O"); + Write(0x9900, false, ">"); + Write(0xff9900, true, "o"); + Write(0x9900, false, "<<<"); + Write(0xffff66, true, "*"); + Write(0x9900, false, "<<<"); + Write(0xff9900, true, "o"); + Write(0x9900, false, "<< "); + Write(0xcccccc, false, " 4 "); + Write(0xffff66, false, "**\n "); + Write(0x9900, false, " >"); + Write(0xff0000, true, "@"); + Write(0x9900, false, "<<<"); + Write(0xffff66, true, "*"); + Write(0x9900, false, "<<"); + Write(0xff9900, true, "o"); + Write(0x9900, false, ">>>"); + Write(0xffff66, true, "*"); + Write(0x9900, false, ">>>"); + Write(0xffff66, true, "*"); + Write(0x9900, false, ">>>"); + Write(0xff9900, true, "o"); + Write(0x9900, false, "<<<"); + Write(0xffff66, true, "*"); + Write(0x9900, false, "<<"); + Write(0xff9900, true, "o"); + Write(0x9900, false, ">"); + Write(0xff9900, true, "o"); + Write(0x9900, false, ">>"); + Write(0xffff66, true, "*"); + Write(0x9900, false, "<<"); + Write(0xff9900, true, "o"); + Write(0x9900, false, "<<"); + Write(0xff0000, true, "@"); + Write(0x9900, false, ">>"); + Write(0x66ff, true, "O"); + Write(0x9900, false, "<<< "); + Write(0xcccccc, false, " 3 "); + Write(0xffff66, false, "**\n "); + Write(0x9900, false, " >>"); + Write(0xff0000, true, "@"); + Write(0x9900, false, "<"); + Write(0xffff66, true, "*"); + Write(0x9900, false, ">>"); + Write(0xffff66, true, "*"); + Write(0x9900, false, ">"); + Write(0xff0000, true, "@"); + Write(0x9900, false, "<"); + Write(0xff9900, true, "o"); + Write(0x9900, false, ">>>"); + Write(0xff0000, true, "@"); + Write(0x9900, false, ">>>"); + Write(0xffff66, true, "*"); + Write(0x9900, false, "<"); + Write(0xff9900, true, "o"); + Write(0x9900, false, "<<<"); + Write(0xff9900, true, "o"); + Write(0x9900, false, "<<"); + Write(0x66ff, true, "O"); + Write(0x9900, false, "<<<"); + Write(0xff0000, true, "@"); + Write(0x9900, false, ">>"); + Write(0x66ff, true, "O"); + Write(0x9900, false, "<<<"); + Write(0xff0000, true, "@"); + Write(0x9900, false, ">>"); + Write(0x66ff, true, "O"); + Write(0x9900, false, "<"); + Write(0x66ff, true, "O"); + Write(0x9900, false, "<< "); + Write(0xcccccc, false, " 2 "); + Write(0xffff66, false, "**\n "); + Write(0x9900, false, ">>"); + Write(0xff0000, true, "@"); + Write(0x9900, false, "<"); + Write(0xff9900, true, "o"); + Write(0x9900, false, "<<<"); + Write(0xffff66, true, "*"); + Write(0x9900, false, "<"); + Write(0xffff66, true, "*"); + Write(0x9900, false, ">>"); + Write(0xff9900, true, "o"); + Write(0x9900, false, ">"); + Write(0xff0000, true, "@"); + Write(0x9900, false, ">"); + Write(0xff9900, true, "o"); + Write(0x9900, false, "<<<"); + Write(0xff9900, true, "o"); + Write(0x9900, false, ">>>"); + Write(0xff0000, true, "@"); + Write(0x9900, false, ">>"); + Write(0xffff66, true, "*"); + Write(0x9900, false, "<<"); + Write(0xff9900, true, "o"); + Write(0x9900, false, ">>"); + Write(0xffff66, true, "*"); + Write(0x9900, false, ">>>"); + Write(0xffff66, true, "*"); + Write(0x9900, false, "<"); + Write(0xff0000, true, "@"); + Write(0x9900, false, ">>>"); + Write(0x66ff, true, "O"); + Write(0x9900, false, "<<<< "); + Write(0xcccccc, false, " 1 "); + Write(0xffff66, false, "**\n "); + Write(0xcccccc, false, " | | \n | | "); + Write(0xcccccc, false, " \n _ _ __ ___|___|___ __ _ _ \n "); + Write(0xcccccc, false, " \n"); + Console.ForegroundColor = color; Console.WriteLine(); } - private static void Write(int rgb, bool bold, string text){ + private static void Write(int rgb, bool bold, string text){ Console.Write($"\u001b[38;2;{(rgb>>16)&255};{(rgb>>8)&255};{rgb&255}{(bold ? ";1" : "")}m{text}"); - } -} \ No newline at end of file + } +} diff --git a/2015/calendar.svg b/2015/calendar.svg index 40356baaa..433f90f6f 100644 --- a/2015/calendar.svg +++ b/2015/calendar.svg @@ -1,51 +1,51 @@ - - + + ▄█▄ ▄▄█ ▄ ▄ ▄▄▄ ▄▄ ▄█▄  ▄▄▄ ▄█  ▄▄ ▄▄▄ ▄▄█ ▄▄▄ █▄█ █ █ █ █ █▄█ █ █ █   █ █ █▄  █  █ █ █ █ █▄█ -█ █ █▄█ ▀▄▀ █▄▄ █ █ █▄  █▄█ █   █▄ █▄█ █▄█ █▄▄  {:year 2015} +█ █ █▄█ ▀▄▀ █▄▄ █ █ █▄  █▄█ █   █▄ █▄█ █▄█ █▄▄  $year = 2015                           |                                                       \|/                               -                      --*--                        25 ** -                       >o<                         24 ** -                      >>O<<                        23 ** -                     >o>>>@<                       22 ** -                    >@<<*<O<<                      21 ** -                   >>o>>O>@<<<                     20 ** -                  >o>o>O>>@<<<<                    19 ** -                 >>o<<<O<o>*<*<<                   18 ** -                >@>>>o>>>@>o<<O<<                  17 ** -               >>*>>O>@>>>*<<<o>O<                 16 ** -              >>@>>o>*>>>@<<<O<O<<<                15 ** -             >>@<<o<<<@>>*<<@>@>@>O<               14 ** -            >*<<O>>>*<<*<@<O<<<O<<O<<              13 ** -           >@>>>o>>>@<o>>@<<O>>>O<<<o<             12 ** -          >o>O<@<<<o<*>@<<O<<<O>>>*>O<<            11 ** -         >@>*>>>o>>@<O>o>@<O>>>@>*>o<<O<           10 ** -        >>@>>>*>>o<O>>>o>o>>o>O<<<*<<<O<<           9 ** -       >>@<o>>O>O<*<<O>O>>*<*<o<<<*>*<o>o<          8 ** -      >>O<O<o<<o>>@>>o<<*<<<o>>>O<o<<o>*<@<         7 ** -     >>@<o>>>O>O<o>>O<<<*<o<<o<<*<<O<<@>>>o<        6 ** -    >>@>>>O>@>*<<<o>*>o<o>>@<<<@<<*>>@<O<<*<<       5 ** -   >>O<<O<<<*<*<<<*<<O<<@<<o>>*>>@<O<<o<<@<<<<      4 ** -  >@<<O<@>>O>>>*<<o>>>*>@<<O>O>*<O>>>O>>o>>>@<<     3 ** - >>@<@>o<<o<<<o>>>O<@<<*>*>>>*<@<@>>>*<*>O<@>>O<    2 ** ->>*>>@>*<<<*<<@>>O<*<<*<<*>>>o>>>@<<O<*<*>>*<<o<<   1 ** +                      --*--                        25 ** +                       >o<                         24 ** +                      >O<<<                        23 ** +                     >>*<<O<                       22 ** +                    >>@<o<<<<                      21 ** +                   >*>>o>@>*<<                     20 ** +                  >>o>o<O<o<<@<                    19 ** +                 >>o>O<O>@<<*<<<                   18 ** +                >o<O<O>>o<@<<O<*<                  17 ** +               >O>>*<@<o>@>>>O<<O<                 16 ** +              >>O>>>@>>*>>o>>>@<O<<                15 ** +             >>o>>o>o>o<<<o>*<<<@>*<               14 ** +            >>O<<<o<o>>O<@<<o>>>*<<<<              13 ** +           >>o>o>>@<<O>>*<<@<O>>>@<<<<             12 ** +          >>o>@>*>>*>>>o<<<O>>>o<o>>>O<            11 ** +         >O<<*>*>>@<<<*>>o<*<<<*<o>>>O<<           10 ** +        >>O>o<*>O<@>>o<*>>>@>>>@<<<*>>@<<           9 ** +       >@>>o<<o>>*>o<o<<O>>*<<<O<o>>>o<o<<          8 ** +      >>*>>*<<O>>>@<o<O>>>@<<<O<@>>O>>O>>o<         7 ** +     >>o>*>>>*<*>*<<<@<<<*>>>o<<*>>@>o>>@<<<        6 ** +    >>o>>>@<<<o>>O<<<*<<*>>o>O>>o>o>>O<<<O<<<       5 ** +   >@<*>@>@>o<<*>@<*<<O<<<*<<o<<<O>o<<<*<<<o<<      4 ** +  >@<<<*<<o>>>*>>>*>>>o<<<*<<o>o>>*<<o<<@>>O<<<     3 ** + >>@<*>>*>@<o>>>@>>>*<o<<<o<<O<<<@>>O<<<@>>O<O<<    2 ** +>>@<o<<<*<*>>o>@>o<<<o>>>@>>*<<o>>*>>>*<@>>>O<<<<   1 **                       |   |                                                    |   |                              -           _  _ __ ___|___|___ __ _  _                   +           _  _ __ ___|___|___ __ _  _                   - \ No newline at end of file + \ No newline at end of file diff --git a/2016/Day01/README.md b/2016/Day01/README.md index 4c302f2ce..2b6c1e8e6 100644 --- a/2016/Day01/README.md +++ b/2016/Day01/README.md @@ -1,6 +1,30 @@ +original source: [https://adventofcode.com/2016/day/1](https://adventofcode.com/2016/day/1) ## --- Day 1: No Time for a Taxicab --- Santa's sleigh uses a very high-precision clock to guide its movements, and the clock's oscillator is regulated by stars. Unfortunately, the stars have been stolen... by the Easter Bunny. To save Christmas, Santa needs you to retrieve all fifty stars by December 25th. Collect stars by solving puzzles. Two puzzles will be made available on each day in the Advent calendar; the second puzzle is unlocked when you complete the first. Each puzzle grants one star. Good luck! -_Visit the website for the full story and [full puzzle](https://adventofcode.com/2016/day/1) description._ +You're airdropped near Easter Bunny Headquarters in a city somewhere. "Near", unfortunately, is as close as you can get - the instructions on the Easter Bunny Recruiting Document the Elves intercepted start here, and nobody had time to work them out further. + +The Document indicates that you should start at the given coordinates (where you just landed) and face North. Then, follow the provided sequence: either turn left (L) or right (R) 90 degrees, then walk forward the given number of blocks, ending at a new intersection. + +There's no time to follow such ridiculous instructions on foot, though, so you take a moment and work out the destination. Given that you can only walk on the [street grid of the city](https://en.wikipedia.org/wiki/Taxicab_geometry), how far is the shortest path to the destination? + +For example: + + + - Following R2, L3 leaves you 2 blocks East and 3 blocks North, or 5 blocks away. + - R2, R2, R2 leaves you 2 blocks due South of your starting position, which is 2 blocks away. + - R5, L5, R5, R3 leaves you 12 blocks away. + +How many blocks away is Easter Bunny HQ? + + +## --- Part Two --- +Then, you notice the instructions continue on the back of the Recruiting Document. Easter Bunny HQ is actually at the first location you visit twice. + +For example, if your instructions are R8, R4, R4, R8, the first location you visit twice is 4 blocks away, due East. + +How many blocks away is the first location you visit twice? + + diff --git a/2016/Day01/input.in b/2016/Day01/input.in index 687ec0109..94fce73c0 100644 Binary files a/2016/Day01/input.in and b/2016/Day01/input.in differ diff --git a/2016/Day02/README.md b/2016/Day02/README.md index 345a8b762..3f7b63bfa 100644 --- a/2016/Day02/README.md +++ b/2016/Day02/README.md @@ -1,6 +1,61 @@ +original source: [https://adventofcode.com/2016/day/2](https://adventofcode.com/2016/day/2) ## --- Day 2: Bathroom Security --- You arrive at *Easter Bunny Headquarters* under cover of darkness. However, you left in such a rush that you forgot to use the bathroom! Fancy office buildings like this one usually have keypad locks on their bathrooms, so you search the front desk for the code. "In order to improve security," the document you find says, "bathroom codes will no longer be written down. Instead, please memorize and follow the procedure below to access the bathrooms." -Read the [full puzzle](https://adventofcode.com/2016/day/2). \ No newline at end of file +The document goes on to explain that each button to be pressed can be found by starting on the previous button and moving to adjacent buttons on the keypad: `U` moves up, `D` moves down, `L` moves left, and `R` moves right. Each line of instructions corresponds to one button, starting at the previous button (or, for the first line, *the "5" button*); press whatever button you're on at the end of each line. If a move doesn't lead to a button, ignore it. + +You can't hold it much longer, so you decide to figure out the code as you walk to the bathroom. You picture a keypad like this: + +``` +1 2 3 +4 5 6 +7 8 9 +``` + +Suppose your instructions are: + +``` +ULL +RRDDD +LURDL +UUUUD +``` + + + - You start at "5" and move up (to "2"), left (to "1"), and left (you can't, and stay on "1"), so the first button is `1`. + - Starting from the previous button ("1"), you move right twice (to "3") and then down three times (stopping at "9" after two moves and ignoring the third), ending up with `9`. + - Continuing from "9", you move left, up, right, down, and left, ending with `8`. + - Finally, you move up four times (stopping at "2"), then down once, ending with `5`. + +So, in this example, the bathroom code is `1985`. + +Your puzzle input is the instructions from the document you found at the front desk. What is the *bathroom code*? + + +## --- Part Two --- + +You finally arrive at the bathroom (it's a several minute walk from the lobby so visitors can behold the many fancy conference rooms and water coolers on this floor) and go to punch in the code. Much to your bladder's dismay, the keypad is not at all like you imagined it. Instead, you are confronted with the result of hundreds of man-hours of bathroom-keypad-design meetings: + +``` + 1 + 2 3 4 +5 6 7 8 9 + A B C + D +``` + +You still start at "5" and stop when you're at an edge, but given the same instructions as above, the outcome is very different: + + + - You start at "5" and don't move at all (up and left are both edges), ending at `5`. + - Continuing from "5", you move right twice and down three times (through "6", "7", "B", "D", "D"), ending at `D`. + - Then, from "D", you move five more times (through "D", "B", "C", "C", "B"), ending at `B`. + - Finally, after five more moves, you end at `3`. + +So, given the actual keypad layout, the code would be `5DB3`. + +Using the same instructions in your puzzle input, what is the correct *bathroom code*? + + diff --git a/2016/Day02/input.in b/2016/Day02/input.in index df0dff54a..e133bb645 100644 Binary files a/2016/Day02/input.in and b/2016/Day02/input.in differ diff --git a/2016/Day03/README.md b/2016/Day03/README.md index cd2bf19f7..cd1bf8693 100644 --- a/2016/Day03/README.md +++ b/2016/Day03/README.md @@ -1,6 +1,30 @@ +original source: [https://adventofcode.com/2016/day/3](https://adventofcode.com/2016/day/3) ## --- Day 3: Squares With Three Sides --- Now that you can think clearly, you move deeper into the labyrinth of hallways and office furniture that makes up this part of Easter Bunny HQ. This must be a graphic design department; the walls are covered in specifications for triangles. Or are they? -Read the [full puzzle](https://adventofcode.com/2016/day/3). \ No newline at end of file +The design document gives the side lengths of each triangle it describes, but... `5 10 25`? Some of these aren't triangles. You can't help but mark the impossible ones. + +In a valid triangle, the sum of any two sides must be larger than the remaining side. For example, the "triangle" given above is impossible, because `5 + 10` is not larger than `25`. + +In your puzzle input, *how many* of the listed triangles are *possible*? + + +## --- Part Two --- +Now that you've helpfully marked up their design documents, it occurs to you that triangles are specified in groups of three *vertically*. Each set of three numbers in a column specifies a triangle. Rows are unrelated. + +For example, given the following specification, numbers with the same hundreds digit would be part of the same triangle: + +``` +101 301 501 +102 302 502 +103 303 503 +201 401 601 +202 402 602 +203 403 603 +``` + +In your puzzle input, and instead reading by columns, *how many* of the listed triangles are *possible*? + + diff --git a/2016/Day03/input.in b/2016/Day03/input.in index 84fc5ad53..065758086 100644 Binary files a/2016/Day03/input.in and b/2016/Day03/input.in differ diff --git a/2016/Day04/README.md b/2016/Day04/README.md index 39105dd2f..84004a1c0 100644 --- a/2016/Day04/README.md +++ b/2016/Day04/README.md @@ -1,6 +1,31 @@ +original source: [https://adventofcode.com/2016/day/4](https://adventofcode.com/2016/day/4) ## --- Day 4: Security Through Obscurity --- Finally, you come across an information kiosk with a list of rooms. Of course, the list is encrypted and full of decoy data, but the instructions to decode the list are barely hidden nearby. Better remove the decoy data first. Each room consists of an encrypted name (lowercase letters separated by dashes) followed by a dash, a sector ID, and a checksum in square brackets. -Read the [full puzzle](https://adventofcode.com/2016/day/4). \ No newline at end of file +A room is real (not a decoy) if the checksum is the five most common letters in the encrypted name, in order, with ties broken by alphabetization. For example: + + + - `aaaaa-bbb-z-y-x-123[abxyz]` is a real room because the most common letters are `a` (5), `b` (3), and then a tie between `x`, `y`, and `z`, which are listed alphabetically. + - `a-b-c-d-e-f-g-h-987[abcde]` is a real room because although the letters are all tied (1 of each), the first five are listed alphabetically. + - `not-a-real-room-404[oarel]` is a real room. + - `totally-real-room-200[decoy]` is not. + +Of the real rooms from the list above, the sum of their sector IDs is `1514`. + +What is the *sum of the sector IDs of the real rooms*? + + +## --- Part Two --- +With all the decoy data out of the way, it's time to decrypt this list and get moving. + +The room names are encrypted by a state-of-the-art [shift cipher](https://en.wikipedia.org/wiki/Caesar_cipher), which is nearly unbreakable without the right software. However, the information kiosk designers at Easter Bunny HQ were not expecting to deal with a master cryptographer like yourself. + +To decrypt a room name, rotate each letter forward through the alphabet a number of times equal to the room's sector ID. `A` becomes `B`, `B` becomes `C`, `Z` becomes `A`, and so on. Dashes become spaces. + +For example, the real name for `qzmt-zixmtkozy-ivhz-343` is `very encrypted name`. + +*What is the sector ID* of the room where North Pole objects are stored? + + diff --git a/2016/Day04/input.in b/2016/Day04/input.in index c951db70c..c80cd7b19 100644 Binary files a/2016/Day04/input.in and b/2016/Day04/input.in differ diff --git a/2016/Day05/README.md b/2016/Day05/README.md index e510a6e67..51944b377 100644 --- a/2016/Day05/README.md +++ b/2016/Day05/README.md @@ -1,6 +1,39 @@ +original source: [https://adventofcode.com/2016/day/5](https://adventofcode.com/2016/day/5) ## --- Day 5: How About a Nice Game of Chess? --- You are faced with a security door designed by Easter Bunny engineers that seem to have acquired most of their security knowledge by watching [hacking](https://en.wikipedia.org/wiki/Hackers_(film)) [movies](https://en.wikipedia.org/wiki/WarGames). The *eight-character password* for the door is generated one character at a time by finding the [MD5](https://en.wikipedia.org/wiki/MD5) hash of some Door ID (your puzzle input) and an increasing integer index (starting with `0`). -Read the [full puzzle](https://adventofcode.com/2016/day/5). \ No newline at end of file +A hash indicates the *next character* in the password if its [hexadecimal](https://en.wikipedia.org/wiki/Hexadecimal) representation starts with *five zeroes*. If it does, the sixth character in the hash is the next character of the password. + +For example, if the Door ID is `abc`: + + + - The first index which produces a hash that starts with five zeroes is `3231929`, which we find by hashing `abc3231929`; the sixth character of the hash, and thus the first character of the password, is `1`. + - `5017308` produces the next interesting hash, which starts with `000008f82...`, so the second character of the password is `8`. + - The third time a hash starts with five zeroes is for `abc5278568`, discovering the character `f`. + +In this example, after continuing this search a total of eight times, the password is `18f47a30`. + +Given the actual Door ID, *what is the password*? + + +## --- Part Two --- +As the door slides open, you are presented with a second door that uses a slightly more inspired security mechanism. Clearly unimpressed by the last version (in what movie is the password decrypted *in order*?!), the Easter Bunny engineers have worked out [a better solution](https://www.youtube.com/watch?v=NHWjlCaIrQo&t=25). + +Instead of simply filling in the password from left to right, the hash now also indicates the *position* within the password to fill. You still look for hashes that begin with five zeroes; however, now, the *sixth* character represents the *position* (`0`-`7`), and the *seventh* character is the character to put in that position. + +A hash result of `000001f` means that `f` is the *second* character in the password. Use only the *first result* for each position, and ignore invalid positions. + +For example, if the Door ID is `abc`: + + + - The first interesting hash is from `abc3231929`, which produces `0000015...`; so, `5` goes in position `1`: `_5______`. + - In the previous method, `5017308` produced an interesting hash; however, it is ignored, because it specifies an invalid position (`8`). + - The second interesting hash is at index `5357525`, which produces `000004e...`; so, `e` goes in position `4`: `_5__e___`. + +You almost choke on your popcorn as the final character falls into place, producing the password `05ace8e3`. + +Given the actual Door ID and this new method, *what is the password*? Be extra proud of your solution if it uses a cinematic "decrypting" animation. + + diff --git a/2016/Day05/Solution.cs b/2016/Day05/Solution.cs index d050541bd..8294a3fcf 100644 --- a/2016/Day05/Solution.cs +++ b/2016/Day05/Solution.cs @@ -1,7 +1,5 @@ -using System; using System.Collections.Concurrent; using System.Collections.Generic; -using System.Globalization; using System.Linq; using System.Security.Cryptography; using System.Text; @@ -10,52 +8,51 @@ namespace AdventOfCode.Y2016.Day05; [ProblemName("How About a Nice Game of Chess?")] -class Solution : Solver -{ +class Solution : Solver { - public object PartOne(string input) - { - return string.Join("", Hashes(input).Select(hash => hash[5]).Take(8)); + public object PartOne(string input) { + var st = ""; + foreach (var hash in Hashes(input)) { + st += hash[2].ToString("x"); + if (st.Length == 8) { + break; + } + } + return st; } - public object PartTwo(string input) - { - var res = new char[8]; + public object PartTwo(string input) { + var chars = Enumerable.Range(0, 8).Select(_ => (char)255).ToArray(); var found = 0; - foreach (var hash in Hashes(input)) - { - var idx = hash[5] - '0'; - if (0 <= idx && idx < 8 && res[idx] == 0) - { - res[idx] = hash[6]; - found++; - if (found == 8) { - break; + foreach (var hash in Hashes(input)) { + if (hash[2] < 8) { + var i = hash[2]; + if (chars[i] == 255) { + chars[i] = hash[3].ToString("x2")[0]; + found++; + if (found == 8) { + break; + } } + } - } - return string.Join("", res); + return string.Join("", chars); } - public IEnumerable Hashes(string input) - { + public IEnumerable Hashes(string input) { - for (var i = 0; i < int.MaxValue; i++) - { - var q = new ConcurrentQueue<(int i, string hash)>(); + for (var i = 0; i < int.MaxValue; i++) { + var q = new ConcurrentQueue<(int i, byte[] hash)>(); Parallel.ForEach( - NumbersFrom(i), + Enumerable.Range(i, int.MaxValue - i), () => MD5.Create(), - (i, state, md5) => - { + (i, state, md5) => { var hash = md5.ComputeHash(Encoding.ASCII.GetBytes(input + i)); - var hashString = string.Join("", hash.Select(x => x.ToString("x2"))); - if (hashString.StartsWith("00000")) - { - q.Enqueue((i, hashString)); + if (hash[0] == 0 && hash[1] == 0 && hash[2] < 16) { + q.Enqueue((i, hash)); state.Stop(); } return md5; @@ -67,9 +64,4 @@ public IEnumerable Hashes(string input) yield return item.hash; } } - - IEnumerable NumbersFrom(int i) - { - for (;;) yield return i++; - } } diff --git a/2016/Day05/input.in b/2016/Day05/input.in index b5738f5d8..a9c42a42e 100644 Binary files a/2016/Day05/input.in and b/2016/Day05/input.in differ diff --git a/2016/Day06/README.md b/2016/Day06/README.md index d93688e72..fea2ad691 100644 --- a/2016/Day06/README.md +++ b/2016/Day06/README.md @@ -1,6 +1,42 @@ +original source: [https://adventofcode.com/2016/day/6](https://adventofcode.com/2016/day/6) ## --- Day 6: Signals and Noise --- Something is jamming your communications with Santa. Fortunately, your signal is only partially jammed, and protocol in situations like this is to switch to a simple [repetition code](https://en.wikipedia.org/wiki/Repetition_code) to get the message through. In this model, the same message is sent repeatedly. You've recorded the repeating message signal (your puzzle input), but the data seems quite corrupted - almost too badly to recover. *Almost*. -Read the [full puzzle](https://adventofcode.com/2016/day/6). \ No newline at end of file +All you need to do is figure out which character is most frequent for each position. For example, suppose you had recorded the following messages: + +``` +eedadn +drvtee +eandsr +raavrd +atevrs +tsrnev +sdttsa +rasrtv +nssdts +ntnada +svetve +tesnvt +vntsnd +vrdear +dvrsen +enarar +``` + +The most common character in the first column is `e`; in the second, `a`; in the third, `s`, and so on. Combining these characters returns the error-corrected message, `easter`. + +Given the recording in your puzzle input, *what is the error-corrected version* of the message being sent? + + +## --- Part Two --- +Of course, that *would* be the message - if you hadn't agreed to use a *modified repetition code* instead. + +In this modified code, the sender instead transmits what looks like random data, but for each character, the character they actually want to send is *slightly less likely* than the others. Even after signal-jamming noise, you can look at the letter distributions in each column and choose the *least common* letter to reconstruct the original message. + +In the above example, the least common character in the first column is `a`; in the second, `d`, and so on. Repeating this process for the remaining characters produces the original message, `advent`. + +Given the recording in your puzzle input and this new decoding methodology, *what is the original message* that Santa is trying to send? + + diff --git a/2016/Day06/input.in b/2016/Day06/input.in index 9873339f3..f2d83a79f 100644 Binary files a/2016/Day06/input.in and b/2016/Day06/input.in differ diff --git a/2016/Day07/README.md b/2016/Day07/README.md index 089886307..8dec7d175 100644 --- a/2016/Day07/README.md +++ b/2016/Day07/README.md @@ -1,6 +1,33 @@ +original source: [https://adventofcode.com/2016/day/7](https://adventofcode.com/2016/day/7) ## --- Day 7: Internet Protocol Version 7 --- While snooping around the local network of EBHQ, you compile a list of [IP addresses](https://en.wikipedia.org/wiki/IP_address) (they're IPv7, of course; [IPv6](https://en.wikipedia.org/wiki/IPv6) is much too limited). You'd like to figure out which IPs support *TLS* (transport-layer snooping). An IP supports TLS if it has an Autonomous Bridge Bypass Annotation, or *ABBA*. An ABBA is any four-character sequence which consists of a pair of two different characters followed by the reverse of that pair, such as `xyyx` or `abba`. However, the IP also must not have an ABBA within any hypernet sequences, which are contained by *square brackets*. -Read the [full puzzle](https://adventofcode.com/2016/day/7). \ No newline at end of file +For example: + + + - `abba[mnop]qrst` supports TLS (`abba` outside square brackets). + - `abcd[bddb]xyyx` does *not* support TLS (`bddb` is within square brackets, even though `xyyx` is outside square brackets). + - `aaaa[qwer]tyui` does *not* support TLS (`aaaa` is invalid; the interior characters must be different). + - `ioxxoj[asdfgh]zxcvbn` supports TLS (`oxxo` is outside square brackets, even though it's within a larger string). + +*How many IPs* in your puzzle input support TLS? + + +## --- Part Two --- +You would also like to know which IPs support *SSL* (super-secret listening). + +An IP supports SSL if it has an Area-Broadcast Accessor, or *ABA*, anywhere in the supernet sequences (outside any square bracketed sections), and a corresponding Byte Allocation Block, or *BAB*, anywhere in the hypernet sequences. An ABA is any three-character sequence which consists of the same character twice with a different character between them, such as `xyx` or `aba`. A corresponding BAB is the same characters but in reversed positions: `yxy` and `bab`, respectively. + +For example: + + + - `aba[bab]xyz` supports SSL (`aba` outside square brackets with corresponding `bab` within square brackets). + - `xyx[xyx]xyx` does *not* support SSL (`xyx`, but no corresponding `yxy`). + - `aaa[kek]eke` supports SSL (`eke` in supernet with corresponding `kek` in hypernet; the `aaa` sequence is not related, because the interior character must be different). + - `zazbz[bzb]cdb` supports SSL (`zaz` has no corresponding `aza`, but `zbz` has a corresponding `bzb`, even though `zaz` and `zbz` overlap). + +*How many IPs* in your puzzle input support SSL? + + diff --git a/2016/Day07/input.in b/2016/Day07/input.in index ec26a4f10..d50f36cdd 100644 Binary files a/2016/Day07/input.in and b/2016/Day07/input.in differ diff --git a/2016/Day08/README.md b/2016/Day08/README.md index 6f22b40ab..50c12f772 100644 --- a/2016/Day08/README.md +++ b/2016/Day08/README.md @@ -1,6 +1,58 @@ +original source: [https://adventofcode.com/2016/day/8](https://adventofcode.com/2016/day/8) ## --- Day 8: Two-Factor Authentication --- You come across a door implementing what you can only assume is an implementation of [two-factor authentication](https://en.wikipedia.org/wiki/Multi-factor_authentication) after a long game of [requirements](https://en.wikipedia.org/wiki/Requirement) [telephone](https://en.wikipedia.org/wiki/Chinese_whispers). To get past the door, you first swipe a keycard (no problem; there was one on a nearby desk). Then, it displays a code on a [little screen](https://www.google.com/search?q=tiny+lcd&tbm=isch), and you type that code on a keypad. Then, presumably, the door unlocks. -Read the [full puzzle](https://adventofcode.com/2016/day/8). \ No newline at end of file +Unfortunately, the screen has been smashed. After a few minutes, you've taken everything apart and figured out how it works. Now you just have to work out what the screen *would* have displayed. + +The magnetic strip on the card you swiped encodes a series of instructions for the screen; these instructions are your puzzle input. The screen is *`50` pixels wide and `6` pixels tall*, all of which start *off*, and is capable of three somewhat peculiar operations: + + + - `rect AxB` turns *on* all of the pixels in a rectangle at the top-left of the screen which is `A` wide and `B` tall. + - `rotate row y=A by B` shifts all of the pixels in row `A` (0 is the top row) *right* by `B` pixels. Pixels that would fall off the right end appear at the left end of the row. + - `rotate column x=A by B` shifts all of the pixels in column `A` (0 is the left column) *down* by `B` pixels. Pixels that would fall off the bottom appear at the top of the column. + +For example, here is a simple sequence on a smaller screen: + + + - `rect 3x2` creates a small rectangle in the top-left corner: +``` +###.... +###.... +....... +``` + + - `rotate column x=1 by 1` rotates the second column down by one pixel: +``` +#.#.... +###.... +.#..... +``` + + - `rotate row y=0 by 4` rotates the top row right by four pixels: +``` +....#.# +###.... +.#..... +``` + + - `rotate column x=1 by 1` again rotates the second column down by one pixel, causing the bottom pixel to wrap back to the top: +``` +.#..#.# +#.#.... +.#..... +``` + + +As you can see, this display technology is extremely powerful, and will soon dominate the tiny-code-displaying-screen market. That's what the advertisement on the back of the display tries to convince you, anyway. + +There seems to be an intermediate check of the voltage used by the display: after you swipe your card, if the screen did work, *how many pixels should be lit?* + + +## --- Part Two --- +You notice that the screen is only capable of displaying capital letters; in the font it uses, each letter is `5` pixels wide and `6` tall. + +After you swipe your card, *what code is the screen trying to display?* + + diff --git a/2016/Day08/input.in b/2016/Day08/input.in index 09aee8aee..cdc78427c 100644 Binary files a/2016/Day08/input.in and b/2016/Day08/input.in differ diff --git a/2016/Day09/README.md b/2016/Day09/README.md index 594534d99..2487c3213 100644 --- a/2016/Day09/README.md +++ b/2016/Day09/README.md @@ -1,6 +1,39 @@ +original source: [https://adventofcode.com/2016/day/9](https://adventofcode.com/2016/day/9) ## --- Day 9: Explosives in Cyberspace --- Wandering around a secure area, you come across a datalink port to a new part of the network. After briefly scanning it for interesting files, you find one file in particular that catches your attention. It's compressed with an experimental format, but fortunately, the documentation for the format is nearby. The format compresses a sequence of characters. Whitespace is ignored. To indicate that some sequence should be repeated, a marker is added to the file, like `(10x2)`. To decompress this marker, take the subsequent `10` characters and repeat them `2` times. Then, continue reading the file *after* the repeated data. The marker itself is not included in the decompressed output. -Read the [full puzzle](https://adventofcode.com/2016/day/9). \ No newline at end of file +If parentheses or other characters appear within the data referenced by a marker, that's okay - treat it like normal data, not a marker, and then resume looking for markers after the decompressed section. + +For example: + + + - `ADVENT` contains no markers and decompresses to itself with no changes, resulting in a decompressed length of `6`. + - `A(1x5)BC` repeats only the `B` a total of `5` times, becoming `ABBBBBC` for a decompressed length of `7`. + - `(3x3)XYZ` becomes `XYZXYZXYZ` for a decompressed length of `9`. + - `A(2x2)BCD(2x2)EFG` doubles the `BC` and `EF`, becoming `ABCBCDEFEFG` for a decompressed length of `11`. + - `(6x1)(1x3)A` simply becomes `(1x3)A` - the `(1x3)` looks like a marker, but because it's within a data section of another marker, it is not treated any differently from the `A` that comes after it. It has a decompressed length of `6`. + - `X(8x2)(3x3)ABCY` becomes `X(3x3)ABC(3x3)ABCY` (for a decompressed length of `18`), because the decompressed data from the `(8x2)` marker (the `(3x3)ABC`) is skipped and not processed further. + +What is the *decompressed length* of the file (your puzzle input)? Don't count whitespace. + + +## --- Part Two --- +Apparently, the file actually uses *version two* of the format. + +In version two, the only difference is that markers within decompressed data *are* decompressed. This, the documentation explains, provides much more substantial compression capabilities, allowing many-gigabyte files to be stored in only a few kilobytes. + +For example: + + + - `(3x3)XYZ` still becomes `XYZXYZXYZ`, as the decompressed section contains no markers. + - `X(8x2)(3x3)ABCY` becomes `XABCABCABCABCABCABCY`, because the decompressed data from the `(8x2)` marker is then further decompressed, thus triggering the `(3x3)` marker twice for a total of six `ABC` sequences. + - `(27x12)(20x12)(13x14)(7x10)(1x12)A` decompresses into a string of `A` repeated `241920` times. + - `(25x3)(3x3)ABC(2x3)XY(5x2)PQRSTX(18x9)(3x2)TWO(5x7)SEVEN` becomes `445` characters long. + +Unfortunately, the computer you brought probably doesn't have enough memory to actually decompress the file; you'll have to *come up with another way* to get its decompressed length. + +What is the *decompressed length* of the file using this improved format? + + diff --git a/2016/Day09/input.in b/2016/Day09/input.in index 84798735c..3ccde7816 100644 Binary files a/2016/Day09/input.in and b/2016/Day09/input.in differ diff --git a/2016/Day10/README.md b/2016/Day10/README.md index d03015e16..d0a9854cd 100644 --- a/2016/Day10/README.md +++ b/2016/Day10/README.md @@ -1,6 +1,36 @@ +original source: [https://adventofcode.com/2016/day/10](https://adventofcode.com/2016/day/10) ## --- Day 10: Balance Bots --- You come upon a factory in which many robots are [zooming around](https://www.youtube.com/watch?v=JnkMyfQ5YfY&t=40) handing small microchips to each other. Upon closer examination, you notice that each bot only proceeds when it has *two* microchips, and once it does, it gives each one to a different bot or puts it in a marked "output" bin. Sometimes, bots take microchips from "input" bins, too. -Read the [full puzzle](https://adventofcode.com/2016/day/10). \ No newline at end of file +Inspecting one of the microchips, it seems like they each contain a single number; the bots must use some logic to decide what to do with each chip. You access the local control computer and download the bots' instructions (your puzzle input). + +Some of the instructions specify that a specific-valued microchip should be given to a specific bot; the rest of the instructions indicate what a given bot should do with its *lower-value* or *higher-value* chip. + +For example, consider the following instructions: + +``` +value 5 goes to bot 2 +bot 2 gives low to bot 1 and high to bot 0 +value 3 goes to bot 1 +bot 1 gives low to output 1 and high to bot 0 +bot 0 gives low to output 2 and high to output 0 +value 2 goes to bot 2 +``` + + + - Initially, bot `1` starts with a value-`3` chip, and bot `2` starts with a value-`2` chip and a value-`5` chip. + - Because bot `2` has two microchips, it gives its lower one (`2`) to bot `1` and its higher one (`5`) to bot `0`. + - Then, bot `1` has two microchips; it puts the value-`2` chip in output `1` and gives the value-`3` chip to bot `0`. + - Finally, bot `0` has two microchips; it puts the `3` in output `2` and the `5` in output `0`. + +In the end, output bin `0` contains a value-`5` microchip, output bin `1` contains a value-`2` microchip, and output bin `2` contains a value-`3` microchip. In this configuration, bot number *`2`* is responsible for comparing value-`5` microchips with value-`2` microchips. + +Based on your instructions, *what is the number of the bot* that is responsible for comparing value-`61` microchips with value-`17` microchips? + + +## --- Part Two --- +What do you get if you *multiply together the values* of one chip in each of outputs `0`, `1`, and `2`? + + diff --git a/2016/Day10/input.in b/2016/Day10/input.in index 4c8c4256a..ca6cead76 100644 Binary files a/2016/Day10/input.in and b/2016/Day10/input.in differ diff --git a/2016/Day11/README.md b/2016/Day11/README.md index eaac04c4a..d25f60209 100644 --- a/2016/Day11/README.md +++ b/2016/Day11/README.md @@ -1,6 +1,149 @@ +original source: [https://adventofcode.com/2016/day/11](https://adventofcode.com/2016/day/11) ## --- Day 11: Radioisotope Thermoelectric Generators --- You come upon a column of four floors that have been entirely sealed off from the rest of the building except for a small dedicated lobby. There are some radiation warnings and a big sign which reads "Radioisotope Testing Facility". According to the project status board, this facility is currently being used to experiment with [Radioisotope Thermoelectric Generators](https://en.wikipedia.org/wiki/Radioisotope_thermoelectric_generator) (RTGs, or simply "generators") that are designed to be paired with specially-constructed microchips. Basically, an RTG is a highly radioactive rock that generates electricity through heat. -Read the [full puzzle](https://adventofcode.com/2016/day/11). \ No newline at end of file +The experimental RTGs have poor radiation containment, so they're dangerously radioactive. The chips are prototypes and don't have normal radiation shielding, but they do have the ability to *generate an electromagnetic radiation shield when powered*. Unfortunately, they can *only* be powered by their corresponding RTG. An RTG powering a microchip is still dangerous to other microchips. + +In other words, if a chip is ever left in the same area as another RTG, and it's not connected to its own RTG, the chip will be *fried*. Therefore, it is assumed that you will follow procedure and keep chips connected to their corresponding RTG when they're in the same room, and away from other RTGs otherwise. + +These microchips sound very interesting and useful to your current activities, and you'd like to try to retrieve them. The fourth floor of the facility has an assembling machine which can make a self-contained, shielded computer for you to take with you - that is, if you can bring it all of the RTGs and microchips. + +Within the radiation-shielded part of the facility (in which it's safe to have these pre-assembly RTGs), there is an elevator that can move between the four floors. Its capacity rating means it can carry at most yourself and two RTGs or microchips in any combination. (They're rigged to some heavy diagnostic equipment - the assembling machine will detach it for you.) As a security measure, the elevator will only function if it contains at least one RTG or microchip. The elevator always stops on each floor to recharge, and this takes long enough that the items within it and the items on that floor can irradiate each other. (You can prevent this if a Microchip and its Generator end up on the same floor in this way, as they can be connected while the elevator is recharging.) + +You make some notes of the locations of each component of interest (your puzzle input). Before you don a hazmat suit and start moving things around, you'd like to have an idea of what you need to do. + +When you enter the containment area, you and the elevator will start on the first floor. + +For example, suppose the isolated area has the following arrangement: + +``` +The first floor contains a hydrogen-compatible microchip and a lithium-compatible microchip. +The second floor contains a hydrogen generator. +The third floor contains a lithium generator. +The fourth floor contains nothing relevant. +``` + +As a diagram (`F#` for a Floor number, `E` for Elevator, `H` for Hydrogen, `L` for Lithium, `M` for Microchip, and `G` for Generator), the initial state looks like this: + +``` +F4 . . . . . +F3 . . . LG . +F2 . HG . . . +F1 E . HM . LM +``` + +Then, to get everything up to the assembling machine on the fourth floor, the following steps could be taken: + + + - Bring the Hydrogen-compatible Microchip to the second floor, which is safe because it can get power from the Hydrogen Generator: +``` +F4 . . . . . +F3 . . . LG . +F2 E HG HM . . +F1 . . . . LM +``` + + - Bring both Hydrogen-related items to the third floor, which is safe because the Hydrogen-compatible microchip is getting power from its generator: +``` +F4 . . . . . +F3 E HG HM LG . +F2 . . . . . +F1 . . . . LM +``` + + - Leave the Hydrogen Generator on floor three, but bring the Hydrogen-compatible Microchip back down with you so you can still use the elevator: +``` +F4 . . . . . +F3 . HG . LG . +F2 E . HM . . +F1 . . . . LM +``` + + - At the first floor, grab the Lithium-compatible Microchip, which is safe because Microchips don't affect each other: +``` +F4 . . . . . +F3 . HG . LG . +F2 . . . . . +F1 E . HM . LM +``` + + - Bring both Microchips up one floor, where there is nothing to fry them: +``` +F4 . . . . . +F3 . HG . LG . +F2 E . HM . LM +F1 . . . . . +``` + + - Bring both Microchips up again to floor three, where they can be temporarily connected to their corresponding generators while the elevator recharges, preventing either of them from being fried: +``` +F4 . . . . . +F3 E HG HM LG LM +F2 . . . . . +F1 . . . . . +``` + + - Bring both Microchips to the fourth floor: +``` +F4 E . HM . LM +F3 . HG . LG . +F2 . . . . . +F1 . . . . . +``` + + - Leave the Lithium-compatible microchip on the fourth floor, but bring the Hydrogen-compatible one so you can still use the elevator; this is safe because although the Lithium Generator is on the destination floor, you can connect Hydrogen-compatible microchip to the Hydrogen Generator there: +``` +F4 . . . . LM +F3 E HG HM LG . +F2 . . . . . +F1 . . . . . +``` + + - Bring both Generators up to the fourth floor, which is safe because you can connect the Lithium-compatible Microchip to the Lithium Generator upon arrival: +``` +F4 E HG . LG LM +F3 . . HM . . +F2 . . . . . +F1 . . . . . +``` + + - Bring the Lithium Microchip with you to the third floor so you can use the elevator: +``` +F4 . HG . LG . +F3 E . HM . LM +F2 . . . . . +F1 . . . . . +``` + + - Bring both Microchips to the fourth floor: +``` +F4 E HG HM LG LM +F3 . . . . . +F2 . . . . . +F1 . . . . . +``` + + +In this arrangement, it takes `11` steps to collect all of the objects at the fourth floor for assembly. (Each elevator stop counts as one step, even if nothing is added to or removed from it.) + +In your situation, what is the *minimum number of steps* required to bring all of the objects to the fourth floor? + + +## --- Part Two --- +You step into the cleanroom separating the lobby from the isolated area and put on the hazmat suit. + +Upon entering the isolated containment area, however, you notice some extra parts on the first floor that weren't listed on the record outside: + + + - An elerium generator. + - An elerium-compatible microchip. + - A dilithium generator. + - A dilithium-compatible microchip. + +These work just like the other generators and microchips. You'll have to get them up to assembly as well. + +What is the *minimum number of steps* required to bring all of the objects, including these four new ones, to the fourth floor? + + diff --git a/2016/Day11/input.in b/2016/Day11/input.in index 70310eded..2c3c55528 100644 Binary files a/2016/Day11/input.in and b/2016/Day11/input.in differ diff --git a/2016/Day12/README.md b/2016/Day12/README.md index 8783e7dc1..9434274f4 100644 --- a/2016/Day12/README.md +++ b/2016/Day12/README.md @@ -1,6 +1,42 @@ +original source: [https://adventofcode.com/2016/day/12](https://adventofcode.com/2016/day/12) ## --- Day 12: Leonardo's Monorail --- You finally reach the top floor of this building: a garden with a slanted glass ceiling. Looks like there are no more stars to be had. While sitting on a nearby bench amidst some [tiger lilies](https://www.google.com/search?q=tiger+lilies&tbm=isch), you manage to decrypt some of the files you extracted from the servers downstairs. -Read the [full puzzle](https://adventofcode.com/2016/day/12). \ No newline at end of file +According to these documents, Easter Bunny HQ isn't just this building - it's a collection of buildings in the nearby area. They're all connected by a local monorail, and there's another building not far from here! Unfortunately, being night, the monorail is currently not operating. + +You remotely connect to the monorail control systems and discover that the boot sequence expects a password. The password-checking logic (your puzzle input) is easy to extract, but the code it uses is strange: it's assembunny code designed for the [new computer](11) you just assembled. You'll have to execute the code and get the password. + +The assembunny code you've extracted operates on four [registers](https://en.wikipedia.org/wiki/Processor_register) (`a`, `b`, `c`, and `d`) that start at `0` and can hold any [integer](https://en.wikipedia.org/wiki/Integer). However, it seems to make use of only a few [instructions](https://en.wikipedia.org/wiki/Instruction_set): + + + - `cpy x y` *copies* `x` (either an integer or the *value* of a register) into register `y`. + - `inc x` *increases* the value of register `x` by one. + - `dec x` *decreases* the value of register `x` by one. + - `jnz x y` *jumps* to an instruction `y` away (positive means forward; negative means backward), but only if `x` is *not zero*. + +The `jnz` instruction moves relative to itself: an offset of `-1` would continue at the previous instruction, while an offset of `2` would *skip over* the next instruction. + +For example: + +``` +cpy 41 a +inc a +inc a +dec a +jnz a 2 +dec a +``` + +The above code would set register `a` to `41`, increase its value by `2`, decrease its value by `1`, and then skip the last `dec a` (because `a` is not zero, so the `jnz a 2` skips it), leaving register `a` at `42`. When you move past the last instruction, the program halts. + +After executing the assembunny code in your puzzle input, *what value is left in register `a`?* + + +## --- Part Two --- +As you head down the fire escape to the monorail, you notice it didn't start; register `c` needs to be initialized to the position of the ignition key. + +If you instead *initialize register `c` to be `1`*, what value is now left in register `a`? + + diff --git a/2016/Day12/input.in b/2016/Day12/input.in index e4a51aade..b74bbbccf 100644 Binary files a/2016/Day12/input.in and b/2016/Day12/input.in differ diff --git a/2016/Day13/README.md b/2016/Day13/README.md index 37cfc68bf..0c425b69d 100644 --- a/2016/Day13/README.md +++ b/2016/Day13/README.md @@ -1,6 +1,53 @@ +original source: [https://adventofcode.com/2016/day/13](https://adventofcode.com/2016/day/13) ## --- Day 13: A Maze of Twisty Little Cubicles --- You arrive at the first floor of this new building to discover a much less welcoming environment than the shiny atrium of the last one. Instead, you are in a maze of twisty little cubicles, all alike. Every location in this area is addressed by a pair of non-negative integers (`x,y`). Each such coordinate is either a wall or an open space. You can't move diagonally. The cube maze starts at `0,0` and seems to extend infinitely toward *positive* `x` and `y`; negative values are *invalid*, as they represent a location outside the building. You are in a small waiting area at `1,1`. -Read the [full puzzle](https://adventofcode.com/2016/day/13). \ No newline at end of file +While it seems chaotic, a nearby morale-boosting poster explains, the layout is actually quite logical. You can determine whether a given `x,y` coordinate will be a wall or an open space using a simple system: + + + - Find `x*x + 3*x + 2*x*y + y + y*y`. + - Add the office designer's favorite number (your puzzle input). + - Find the [binary representation](https://en.wikipedia.org/wiki/Binary_number) of that sum; count the *number* of [bits](https://en.wikipedia.org/wiki/Bit) that are `1`. + + - If the number of bits that are `1` is *even*, it's an *open space*. + - If the number of bits that are `1` is *odd*, it's a *wall*. + + + +For example, if the office designer's favorite number were `10`, drawing walls as `#` and open spaces as `.`, the corner of the building containing `0,0` would look like this: + +``` + 0123456789 +0 .#.####.## +1 ..#..#...# +2 #....##... +3 ###.#.###. +4 .##..#..#. +5 ..##....#. +6 #...##.### +``` + +Now, suppose you wanted to reach `7,4`. The shortest route you could take is marked as `O`: + +``` + 0123456789 +0 .#.####.## +1 .O#..#...# +2 #OOO.##... +3 ###O#.###. +4 .##OO#OO#. +5 ..##OOO.#. +6 #...##.### +``` + +Thus, reaching `7,4` would take a minimum of `11` steps (starting from your current location, `1,1`). + +What is the *fewest number of steps required* for you to reach `31,39`? + + +## --- Part Two --- +*How many locations* (distinct `x,y` coordinates, including your starting location) can you reach in at most `50` steps? + + diff --git a/2016/Day13/input.in b/2016/Day13/input.in index c12c644c8..dda50873c 100644 Binary files a/2016/Day13/input.in and b/2016/Day13/input.in differ diff --git a/2016/Day14/README.md b/2016/Day14/README.md index 5d0c9057c..171a74127 100644 --- a/2016/Day14/README.md +++ b/2016/Day14/README.md @@ -1,6 +1,55 @@ +original source: [https://adventofcode.com/2016/day/14](https://adventofcode.com/2016/day/14) ## --- Day 14: One-Time Pad --- In order to communicate securely with Santa while you're on this mission, you've been using a [one-time pad](https://en.wikipedia.org/wiki/One-time_pad) that you [generate](https://en.wikipedia.org/wiki/Security_through_obscurity) using a pre-agreed algorithm. Unfortunately, you've run out of keys in your one-time pad, and so you need to generate some more. To generate keys, you first get a stream of random data by taking the [MD5](https://en.wikipedia.org/wiki/MD5) of a pre-arranged [salt](https://en.wikipedia.org/wiki/Salt_(cryptography)) (your puzzle input) and an increasing integer index (starting with `0`, and represented in decimal); the resulting MD5 hash should be represented as a string of *lowercase* hexadecimal digits. -Read the [full puzzle](https://adventofcode.com/2016/day/14). \ No newline at end of file +However, not all of these MD5 hashes are *keys*, and you need `64` new keys for your one-time pad. A hash is a key *only if*: + + + - It contains *three* of the same character in a row, like `777`. Only consider the first such triplet in a hash. + - One of the next `1000` hashes in the stream contains that same character *five* times in a row, like `77777`. + +Considering future hashes for five-of-a-kind sequences does not cause those hashes to be skipped; instead, regardless of whether the current hash is a key, always resume testing for keys starting with the very next hash. + +For example, if the pre-arranged salt is `abc`: + + + - The first index which produces a triple is `18`, because the MD5 hash of `abc18` contains `...cc38887a5...`. However, index `18` does not count as a key for your one-time pad, because none of the next thousand hashes (index `19` through index `1018`) contain `88888`. + - The next index which produces a triple is `39`; the hash of `abc39` contains `eee`. It is also the first key: one of the next thousand hashes (the one at index 816) contains `eeeee`. + - None of the next six triples are keys, but the one after that, at index `92`, is: it contains `999` and index `200` contains `99999`. + - Eventually, index `22728` meets all of the criteria to generate the `64`th key. + +So, using our example salt of `abc`, index `22728` produces the `64`th key. + +Given the actual salt in your puzzle input, *what index* produces your `64`th one-time pad key? + + +## --- Part Two --- +Of course, in order to make this process [even more secure](https://en.wikipedia.org/wiki/MD5#Security), you've also implemented [key stretching](https://en.wikipedia.org/wiki/Key_stretching). + +Key stretching forces attackers to spend more time generating hashes. Unfortunately, it forces everyone else to spend more time, too. + +To implement key stretching, whenever you generate a hash, before you use it, you first find the MD5 hash of that hash, then the MD5 hash of *that* hash, and so on, a total of *`2016` additional hashings*. Always use lowercase hexadecimal representations of hashes. + +For example, to find the stretched hash for index `0` and salt `abc`: + + + - Find the MD5 hash of `abc0`: `577571be4de9dcce85a041ba0410f29f`. + - Then, find the MD5 hash of that hash: `eec80a0c92dc8a0777c619d9bb51e910`. + - Then, find the MD5 hash of that hash: `16062ce768787384c81fe17a7a60c7e3`. + - ...repeat many times... + - Then, find the MD5 hash of that hash: `a107ff634856bb300138cac6568c0f24`. + +So, the stretched hash for index `0` in this situation is `a107ff...`. In the end, you find the original hash (one use of MD5), then find the hash-of-the-previous-hash `2016` times, for a total of `2017` uses of MD5. + +The rest of the process remains the same, but now the keys are entirely different. Again for salt `abc`: + + + - The first triple (`222`, at index `5`) has no matching `22222` in the next thousand hashes. + - The second triple (`eee`, at index `10`) hash a matching `eeeee` at index `89`, and so it is the first key. + - Eventually, index `22551` produces the `64`th key (triple `fff` with matching `fffff` at index `22859`. + +Given the actual salt in your puzzle input and using `2016` extra MD5 calls of key stretching, *what index* now produces your `64`th one-time pad key? + + diff --git a/2016/Day14/input.in b/2016/Day14/input.in index fa1a5b352..f7f11ad90 100644 Binary files a/2016/Day14/input.in and b/2016/Day14/input.in differ diff --git a/2016/Day15/README.md b/2016/Day15/README.md index e0930ef41..7bcd0d064 100644 --- a/2016/Day15/README.md +++ b/2016/Day15/README.md @@ -1,6 +1,37 @@ +original source: [https://adventofcode.com/2016/day/15](https://adventofcode.com/2016/day/15) ## --- Day 15: Timing is Everything --- The halls open into an interior plaza containing a large kinetic sculpture. The sculpture is in a sealed enclosure and seems to involve a set of identical spherical capsules that are carried to the top and allowed to [bounce through the maze](https://youtu.be/IxDoO9oODOk?t=177) of spinning pieces. Part of the sculpture is even interactive! When a button is pressed, a capsule is dropped and tries to fall through slots in a set of rotating discs to finally go through a little hole at the bottom and come out of the sculpture. If any of the slots aren't aligned with the capsule as it passes, the capsule bounces off the disc and soars away. You feel compelled to get one of those capsules. -Read the [full puzzle](https://adventofcode.com/2016/day/15). \ No newline at end of file +The discs pause their motion each second and come in different sizes; they seem to each have a fixed number of positions at which they stop. You decide to call the position with the slot 0, and count up for each position it reaches next. + +Furthermore, the discs are spaced out so that after you push the button, one second elapses before the first disc is reached, and one second elapses as the capsule passes from one disc to the one below it. So, if you push the button at time=100, then the capsule reaches the top disc at time=101, the second disc at time=102, the third disc at time=103, and so on. + +The button will only drop a capsule at an integer time - no fractional seconds allowed. + +For example, at time=0, suppose you see the following arrangement: + +
+Disc #1 has 5 positions; at time=0, it is at position 4.
+Disc #2 has 2 positions; at time=0, it is at position 1.
+
+
+ +If you press the button exactly at time=0, the capsule would start to fall; it would reach the first disc at time=1. Since the first disc was at position 4 at time=0, by time=1 it has ticked one position forward. As a five-position disc, the next position is 0, and the capsule falls through the slot. + +Then, at time=2, the capsule reaches the second disc. The second disc has ticked forward two positions at this point: it started at position 1, then continued to position 0, and finally ended up at position 1 again. Because there's only a slot at position 0, the capsule bounces away. + +If, however, you wait until time=5 to push the button, then when the capsule reaches each disc, the first disc will have ticked forward 5+1 = 6 times (to position 0), and the second disc will have ticked forward 5+2 = 7 times (also to position 0). In this case, the capsule would fall through the discs and come out of the machine. + +However, your situation has more than two discs; you've noted their positions in your puzzle input. What is the first time you can press the button to get a capsule? + + +## --- Part Two --- +After getting the first capsule (it contained a star! what great fortune!), the machine detects your success and begins to rearrange itself. + +When it's done, the discs are back in their original configuration as if it were time=0 again, but a new disc with 11 positions and starting at position 0 has appeared exactly one second below the previously-bottom disc. + +With this new disc, and counting again starting from time=0 with the configuration in your puzzle input, what is the first time you can press the button to get another capsule? + + diff --git a/2016/Day15/input.in b/2016/Day15/input.in index d98a91e50..c5d50198a 100644 Binary files a/2016/Day15/input.in and b/2016/Day15/input.in differ diff --git a/2016/Day16/README.md b/2016/Day16/README.md index e5a6546ce..ff8b06be0 100644 --- a/2016/Day16/README.md +++ b/2016/Day16/README.md @@ -1,6 +1,59 @@ +original source: [https://adventofcode.com/2016/day/16](https://adventofcode.com/2016/day/16) ## --- Day 16: Dragon Checksum --- You're done scanning this part of the network, but you've left traces of your presence. You need to overwrite some disks with random-looking data to cover your tracks and update the local security system with a new checksum for those disks. For the data to not be suspicious, it needs to have certain properties; purely random data will be detected as tampering. To generate appropriate random data, you'll need to use a modified [dragon curve](https://en.wikipedia.org/wiki/Dragon_curve). -Read the [full puzzle](https://adventofcode.com/2016/day/16). \ No newline at end of file +Start with an appropriate initial state (your puzzle input). Then, so long as you don't have enough data yet to fill the disk, repeat the following steps: + + + - Call the data you have at this point "a". + - Make a copy of "a"; call this copy "b". + - Reverse the order of the characters in "b". + - In "b", replace all instances of `0` with `1` and all `1`s with `0`. + - The resulting data is "a", then a single `0`, then "b". + +For example, after a single step of this process, + + + - `1` becomes `100`. + - `0` becomes `001`. + - `11111` becomes `11111000000`. + - `111100001010` becomes `1111000010100101011110000`. + +Repeat these steps until you have enough data to fill the desired disk. + +Once the data has been generated, you also need to create a checksum of that data. Calculate the checksum *only* for the data that fits on the disk, even if you generated more data than that in the previous step. + +The checksum for some given data is created by considering each non-overlapping *pair* of characters in the input data. If the two characters match (`00` or `11`), the next checksum character is a `1`. If the characters do not match (`01` or `10`), the next checksum character is a `0`. This should produce a new string which is exactly half as long as the original. If the length of the checksum is *even*, repeat the process until you end up with a checksum with an *odd* length. + +For example, suppose we want to fill a disk of length `12`, and when we finally generate a string of at least length `12`, the first `12` characters are `110010110100`. To generate its checksum: + + + - Consider each pair: `11`, `00`, `10`, `11`, `01`, `00`. + - These are same, same, different, same, different, same, producing `110101`. + - The resulting string has length `6`, which is *even*, so we repeat the process. + - The pairs are `11` (same), `01` (different), `01` (different). + - This produces the checksum `100`, which has an *odd* length, so we stop. + +Therefore, the checksum for `110010110100` is `100`. + +Combining all of these steps together, suppose you want to fill a disk of length `20` using an initial state of `10000`: + + + - Because `10000` is too short, we first use the modified dragon curve to make it longer. + - After one round, it becomes `10000011110` (`11` characters), still too short. + - After two rounds, it becomes `10000011110010000111110` (`23` characters), which is enough. + - Since we only need `20`, but we have `23`, we get rid of all but the first `20` characters: `10000011110010000111`. + - Next, we start calculating the checksum; after one round, we have `0111110101`, which `10` characters long (*even*), so we continue. + - After two rounds, we have `01100`, which is `5` characters long (*odd*), so we are done. + +In this example, the correct checksum would therefore be `01100`. + +The first disk you have to fill has length `272`. Using the initial state in your puzzle input, *what is the correct checksum*? + + +## --- Part Two --- +The second disk you have to fill has length `35651584`. Again using the initial state in your puzzle input, *what is the correct checksum* for this disk? + + diff --git a/2016/Day16/input.in b/2016/Day16/input.in index 6d0d69381..f8e6224bc 100644 Binary files a/2016/Day16/input.in and b/2016/Day16/input.in differ diff --git a/2016/Day17/README.md b/2016/Day17/README.md index 7cc530e50..cae6b5e24 100644 --- a/2016/Day17/README.md +++ b/2016/Day17/README.md @@ -1,3 +1,4 @@ +original source: [https://adventofcode.com/2016/day/17](https://adventofcode.com/2016/day/17) ## --- Day 17: Two Steps Forward --- You're trying to access a secure vault protected by a `4x4` grid of small rooms connected by doors. You start in the top-left room (marked `S`), and you can access the vault (marked `V`) once you reach the bottom-right room: @@ -13,4 +14,42 @@ You're trying to access a secure vault protected by a `4x4` grid of small rooms ####### V ``` -Read the [full puzzle](https://adventofcode.com/2016/day/17). \ No newline at end of file +Fixed walls are marked with `#`, and doors are marked with `-` or `|`. + +The doors in your *current room* are either open or closed (and locked) based on the hexadecimal [MD5](https://en.wikipedia.org/wiki/MD5) hash of a passcode (your puzzle input) followed by a sequence of uppercase characters representing the *path you have taken so far* (`U` for up, `D` for down, `L` for left, and `R` for right). + +Only the first four characters of the hash are used; they represent, respectively, the doors *up, down, left, and right* from your current position. Any `b`, `c`, `d`, `e`, or `f` means that the corresponding door is *open*; any other character (any number or `a`) means that the corresponding door is *closed and locked*. + +To access the vault, all you need to do is reach the bottom-right room; reaching this room opens the vault and all doors in the maze. + +For example, suppose the passcode is `hijkl`. Initially, you have taken no steps, and so your path is empty: you simply find the MD5 hash of `hijkl` alone. The first four characters of this hash are `ced9`, which indicate that up is open (`c`), down is open (`e`), left is open (`d`), and right is closed and locked (`9`). Because you start in the top-left corner, there are no "up" or "left" doors to be open, so your only choice is *down*. + +Next, having gone only one step (down, or `D`), you find the hash of `hijkl*D*`. This produces `f2bc`, which indicates that you can go back up, left (but that's a wall), or right. Going right means hashing `hijkl*DR*` to get `5745` - all doors closed and locked. However, going *up* instead is worthwhile: even though it returns you to the room you started in, your path would then be `DU`, opening a *different set of doors*. + +After going `DU` (and then hashing `hijkl*DU*` to get `528e`), only the right door is open; after going `DUR`, all doors lock. (Fortunately, your actual passcode is not `hijkl`). + +Passcodes actually used by Easter Bunny Vault Security do allow access to the vault if you know the right path. For example: + + + - If your passcode were `ihgpwlah`, the shortest path would be `DDRRRD`. + - With `kglvqrro`, the shortest path would be `DDUDRLRRUDRD`. + - With `ulqzkmiv`, the shortest would be `DRURDRUDDLLDLUURRDULRLDUUDDDRR`. + +Given your vault's passcode, *what is the shortest path* (the actual path, not just the length) to reach the vault? + + +## --- Part Two --- +You're curious how robust this security solution really is, and so you decide to find longer and longer paths which still provide access to the vault. You remember that paths always end the first time they reach the bottom-right room (that is, they can never pass through it, only end in it). + +For example: + + + - If your passcode were `ihgpwlah`, the longest path would take `370` steps. + - With `kglvqrro`, the longest path would be `492` steps long. + - With `ulqzkmiv`, the longest path would be `830` steps long. + + + +What is the *length of the longest path* that reaches the vault? + + diff --git a/2016/Day17/input.in b/2016/Day17/input.in index a868569aa..02562b2a2 100644 Binary files a/2016/Day17/input.in and b/2016/Day17/input.in differ diff --git a/2016/Day18/README.md b/2016/Day18/README.md index aa4737079..a9019d4ce 100644 --- a/2016/Day18/README.md +++ b/2016/Day18/README.md @@ -1,6 +1,65 @@ +original source: [https://adventofcode.com/2016/day/18](https://adventofcode.com/2016/day/18) ## --- Day 18: Like a Rogue --- As you enter this room, you hear a loud click! Some of the tiles in the floor here seem to be pressure plates for [traps](https://nethackwiki.com/wiki/Trap), and the trap you just triggered has run out of... whatever it tried to do to you. You doubt you'll be so lucky next time. Upon closer examination, the traps and safe tiles in this room seem to follow a pattern. The tiles are arranged into rows that are all the same width; you take note of the safe tiles (`.`) and traps (`^`) in the first row (your puzzle input). -Read the [full puzzle](https://adventofcode.com/2016/day/18). \ No newline at end of file +The type of tile (trapped or safe) in each row is based on the types of the tiles in the same position, and to either side of that position, in the previous row. (If either side is off either end of the row, it counts as "safe" because there isn't a trap embedded in the wall.) + +For example, suppose you know the first row (with tiles marked by letters) and want to determine the next row (with tiles marked by numbers): + +``` +ABCDE +12345 +``` + +The type of tile `2` is based on the types of tiles `A`, `B`, and `C`; the type of tile `5` is based on tiles `D`, `E`, and an imaginary "safe" tile. Let's call these three tiles from the previous row the *left*, *center*, and *right* tiles, respectively. Then, a new tile is a *trap* only in one of the following situations: + + + - Its *left* and *center* tiles are traps, but its *right* tile is not. + - Its *center* and *right* tiles are traps, but its *left* tile is not. + - Only its *left* tile is a trap. + - Only its *right* tile is a trap. + +In any other situation, the new tile is safe. + +Then, starting with the row `..^^.`, you can determine the next row by applying those rules to each new tile: + + + - The leftmost character on the next row considers the left (nonexistent, so we assume "safe"), center (the first `.`, which means "safe"), and right (the second `.`, also "safe") tiles on the previous row. Because all of the trap rules require a trap in at least one of the previous three tiles, the first tile on this new row is also safe, `.`. + - The second character on the next row considers its left (`.`), center (`.`), and right (`^`) tiles from the previous row. This matches the fourth rule: only the right tile is a trap. Therefore, the next tile in this new row is a trap, `^`. + - The third character considers `.^^`, which matches the second trap rule: its center and right tiles are traps, but its left tile is not. Therefore, this tile is also a trap, `^`. + - The last two characters in this new row match the first and third rules, respectively, and so they are both also traps, `^`. + +After these steps, we now know the next row of tiles in the room: `.^^^^`. Then, we continue on to the next row, using the same rules, and get `^^..^`. After determining two new rows, our map looks like this: + +``` +..^^. +.^^^^ +^^..^ +``` + +Here's a larger example with ten tiles per row and ten rows: + +``` +.^^.^.^^^^ +^^^...^..^ +^.^^.^.^^. +..^^...^^^ +.^^^^.^^.^ +^^..^.^^.. +^^^^..^^^. +^..^^^^.^^ +.^^^..^.^^ +^^.^^^..^^ +``` + +In ten rows, this larger example has `38` safe tiles. + +Starting with the map in your puzzle input, in a total of `40` rows (including the starting row), *how many safe tiles* are there? + + +## --- Part Two --- +*How many safe tiles* are there in a total of `400000` rows? + + diff --git a/2016/Day18/input.in b/2016/Day18/input.in index ca1d62f7f..2036710b5 100644 Binary files a/2016/Day18/input.in and b/2016/Day18/input.in differ diff --git a/2016/Day19/README.md b/2016/Day19/README.md index 5bfdef034..94579f038 100644 --- a/2016/Day19/README.md +++ b/2016/Day19/README.md @@ -1,6 +1,75 @@ +original source: [https://adventofcode.com/2016/day/19](https://adventofcode.com/2016/day/19) ## --- Day 19: An Elephant Named Joseph --- The Elves contact you over a highly secure emergency channel. Back at the North Pole, the Elves are busy misunderstanding [White Elephant parties](https://en.wikipedia.org/wiki/White_elephant_gift_exchange). Each Elf brings a present. They all sit in a circle, numbered starting with position `1`. Then, starting with the first Elf, they take turns stealing all the presents from the Elf to their left. An Elf with no presents is removed from the circle and does not take turns. -Read the [full puzzle](https://adventofcode.com/2016/day/19). \ No newline at end of file +For example, with five Elves (numbered `1` to `5`): + +``` + 1 +5 2 + 4 3 +``` + + + - Elf `1` takes Elf `2`'s present. + - Elf `2` has no presents and is skipped. + - Elf `3` takes Elf `4`'s present. + - Elf `4` has no presents and is also skipped. + - Elf `5` takes Elf `1`'s two presents. + - Neither Elf `1` nor Elf `2` have any presents, so both are skipped. + - Elf `3` takes Elf `5`'s three presents. + +So, with *five* Elves, the Elf that sits starting in position `3` gets all the presents. + +With the number of Elves given in your puzzle input, *which Elf gets all the presents?* + + +## --- Part Two --- +Realizing the folly of their present-exchange rules, the Elves agree to instead steal presents from the Elf *directly across the circle*. If two Elves are across the circle, the one on the left (from the perspective of the stealer) is stolen from. The other rules remain unchanged: Elves with no presents are removed from the circle entirely, and the other elves move in slightly to keep the circle evenly spaced. + +For example, with five Elves (again numbered `1` to `5`): + + + - The Elves sit in a circle; Elf `1` goes first: +``` + *1* +5 2 + 4 3 +``` + + - Elves `3` and `4` are across the circle; Elf `3`'s present is stolen, being the one to the left. Elf `3` leaves the circle, and the rest of the Elves move in: +``` + *1* 1 +5 2 --> 5 2 + 4 - 4 +``` + + - Elf `2` steals from the Elf directly across the circle, Elf `5`: +``` + 1 1 +- *2* --> 2 + 4 4 +``` + + - Next is Elf `4` who, choosing between Elves `1` and `2`, steals from Elf `1`: +``` + - 2 + 2 --> + *4* 4 +``` + + - Finally, Elf `2` steals from Elf `4`: +``` + *2* + --> 2 + - +``` + + +So, with *five* Elves, the Elf that sits starting in position `2` gets all the presents. + +With the number of Elves given in your puzzle input, *which Elf now gets all the presents?* + + diff --git a/2016/Day19/input.in b/2016/Day19/input.in index e1bea95a1..a64cd1961 100644 Binary files a/2016/Day19/input.in and b/2016/Day19/input.in differ diff --git a/2016/Day20/README.md b/2016/Day20/README.md index f91a56fec..3f573cdc3 100644 --- a/2016/Day20/README.md +++ b/2016/Day20/README.md @@ -1,6 +1,23 @@ +original source: [https://adventofcode.com/2016/day/20](https://adventofcode.com/2016/day/20) ## --- Day 20: Firewall Rules --- You'd like to set up a small hidden computer here so you can use it to get back into the network later. However, the corporate firewall only allows communication with certain external [IP addresses](https://en.wikipedia.org/wiki/IPv4#Addressing). You've retrieved the list of blocked IPs from the firewall, but the list seems to be messy and poorly maintained, and it's not clear which IPs are allowed. Also, rather than being written in [dot-decimal](https://en.wikipedia.org/wiki/Dot-decimal_notation) notation, they are written as plain [32-bit integers](https://en.wikipedia.org/wiki/32-bit), which can have any value from `0` through `4294967295`, inclusive. -Read the [full puzzle](https://adventofcode.com/2016/day/20). \ No newline at end of file +For example, suppose only the values `0` through `9` were valid, and that you retrieved the following blacklist: + +``` +5-8 +0-2 +4-7 +``` + +The blacklist specifies ranges of IPs (inclusive of both the start and end value) that are *not* allowed. Then, the only IPs that this firewall allows are `3` and `9`, since those are the only numbers not in any range. + +Given the list of blocked IPs you retrieved from the firewall (your puzzle input), *what is the lowest-valued IP* that is not blocked? + + +## --- Part Two --- +*How many IPs* are allowed by the blacklist? + + diff --git a/2016/Day20/input.in b/2016/Day20/input.in index 06143dbaf..f809e5407 100644 Binary files a/2016/Day20/input.in and b/2016/Day20/input.in differ diff --git a/2016/Day21/README.md b/2016/Day21/README.md index a38e2892c..c730dacac 100644 --- a/2016/Day21/README.md +++ b/2016/Day21/README.md @@ -1,6 +1,37 @@ +original source: [https://adventofcode.com/2016/day/21](https://adventofcode.com/2016/day/21) ## --- Day 21: Scrambled Letters and Hash --- The computer system you're breaking into uses a weird scrambling function to store its passwords. It shouldn't be much trouble to create your own scrambled password so you can add it to the system; you just have to implement the scrambler. The scrambling function is a series of operations (the exact list is provided in your puzzle input). Starting with the password to be scrambled, apply each operation in succession to the string. The individual operations behave as follows: -Read the [full puzzle](https://adventofcode.com/2016/day/21). \ No newline at end of file + + - `swap position X with position Y` means that the letters at indexes `X` and `Y` (counting from `0`) should be *swapped*. + - `swap letter X with letter Y` means that the letters `X` and `Y` should be *swapped* (regardless of where they appear in the string). + - `rotate left/right X steps` means that the whole string should be *rotated*; for example, one right rotation would turn `abcd` into `dabc`. + - `rotate based on position of letter X` means that the whole string should be *rotated to the right* based on the *index* of letter `X` (counting from `0`) as determined *before* this instruction does any rotations. Once the index is determined, rotate the string to the right one time, plus a number of times equal to that index, plus one additional time if the index was at least `4`. + - `reverse positions X through Y` means that the span of letters at indexes `X` through `Y` (including the letters at `X` and `Y`) should be *reversed in order*. + - `move position X to position Y` means that the letter which is at index `X` should be *removed* from the string, then *inserted* such that it ends up at index `Y`. + +For example, suppose you start with `abcde` and perform the following operations: + + + - `swap position 4 with position 0` swaps the first and last letters, producing the input for the next step, `ebcda`. + - `swap letter d with letter b` swaps the positions of `d` and `b`: `edcba`. + - `reverse positions 0 through 4` causes the entire string to be reversed, producing `abcde`. + - `rotate left 1 step` shifts all letters left one position, causing the first letter to wrap to the end of the string: `bcdea`. + - `move position 1 to position 4` removes the letter at position `1` (`c`), then inserts it at position `4` (the end of the string): `bdeac`. + - `move position 3 to position 0` removes the letter at position `3` (`a`), then inserts it at position `0` (the front of the string): `abdec`. + - `rotate based on position of letter b` finds the index of letter `b` (`1`), then rotates the string right once plus a number of times equal to that index (`2`): `ecabd`. + - `rotate based on position of letter d` finds the index of letter `d` (`4`), then rotates the string right once, plus a number of times equal to that index, plus an additional time because the index was at least `4`, for a total of `6` right rotations: `decab`. + +After these steps, the resulting scrambled password is `decab`. + +Now, you just need to generate a new scrambled password and you can access the system. Given the list of scrambling operations in your puzzle input, *what is the result of scrambling `abcdefgh`*? + + +## --- Part Two --- +You scrambled the password correctly, but you discover that you [can't actually modify](https://en.wikipedia.org/wiki/File_system_permissions) the [password file](https://en.wikipedia.org/wiki/Passwd) on the system. You'll need to un-scramble one of the existing passwords by reversing the scrambling process. + +What is the un-scrambled version of the scrambled password `fbgdceah`? + + diff --git a/2016/Day21/input.in b/2016/Day21/input.in index 859177f85..ebd7d523c 100644 Binary files a/2016/Day21/input.in and b/2016/Day21/input.in differ diff --git a/2016/Day22/README.md b/2016/Day22/README.md index 152ace850..dd1c7280b 100644 --- a/2016/Day22/README.md +++ b/2016/Day22/README.md @@ -1,6 +1,126 @@ +original source: [https://adventofcode.com/2016/day/22](https://adventofcode.com/2016/day/22) ## --- Day 22: Grid Computing --- You gain access to a massive storage cluster arranged in a grid; each storage node is only connected to the four nodes directly adjacent to it (three if the node is on an edge, two if it's in a corner). You can directly access data *only* on node `/dev/grid/node-x0-y0`, but you can perform some limited actions on the other nodes: -Read the [full puzzle](https://adventofcode.com/2016/day/22). \ No newline at end of file + + - You can get the disk usage of all nodes (via [`df`](https://en.wikipedia.org/wiki/Df_(Unix)#Example)). The result of doing this is in your puzzle input. + - You can instruct a node to *move* (not copy) *all* of its data to an adjacent node (if the destination node has enough space to receive the data). The sending node is left empty after this operation. + +Nodes are named by their position: the node named `node-x10-y10` is adjacent to nodes `node-x9-y10`, `node-x11-y10`, `node-x10-y9`, and `node-x10-y11`. + +Before you begin, you need to understand the arrangement of data on these nodes. Even though you can only move data between directly connected nodes, you're going to need to rearrange a lot of the data to get access to the data you need. Therefore, you need to work out how you might be able to shift data around. + +To do this, you'd like to count the number of *viable pairs* of nodes. A viable pair is any two nodes (A,B), *regardless of whether they are directly connected*, such that: + + + - Node A is *not* empty (its `Used` is not zero). + - Nodes A and B are *not the same* node. + - The data on node A (its `Used`) *would fit* on node B (its `Avail`). + +*How many viable pairs* of nodes are there? + + +## --- Part Two --- +Now that you have a better understanding of the grid, it's time to get to work. + +Your goal is to gain access to the data which begins in the node with `y=0` and the *highest `x`* (that is, the node in the top-right corner). + +For example, suppose you have the following grid: + +``` +Filesystem Size Used Avail Use% +/dev/grid/node-x0-y0 10T 8T 2T 80% +/dev/grid/node-x0-y1 11T 6T 5T 54% +/dev/grid/node-x0-y2 32T 28T 4T 87% +/dev/grid/node-x1-y0 9T 7T 2T 77% +/dev/grid/node-x1-y1 8T 0T 8T 0% +/dev/grid/node-x1-y2 11T 7T 4T 63% +/dev/grid/node-x2-y0 10T 6T 4T 60% +/dev/grid/node-x2-y1 9T 8T 1T 88% +/dev/grid/node-x2-y2 9T 6T 3T 66% +``` + +In this example, you have a storage grid `3` nodes wide and `3` nodes tall. The node you can access directly, `node-x0-y0`, is almost full. The node containing the data you want to access, `node-x2-y0` (because it has `y=0` and the highest `x` value), contains 6 [terabytes](https://en.wikipedia.org/wiki/Terabyte) of data - enough to fit on your node, if only you could make enough space to move it there. + +Fortunately, `node-x1-y1` looks like it has enough free space to enable you to move some of this data around. In fact, it seems like all of the nodes have enough space to hold any node's data (except `node-x0-y2`, which is much larger, very full, and not moving any time soon). So, initially, the grid's capacities and connections look like this: + +``` +( 8T/10T) -- 7T/ 9T -- [ 6T/10T] + | | | + 6T/11T -- 0T/ 8T -- 8T/ 9T + | | | + 28T/32T -- 7T/11T -- 6T/ 9T +``` + +The node you can access directly is in parentheses; the data you want starts in the node marked by square brackets. + +In this example, most of the nodes are interchangable: they're full enough that no other node's data would fit, but small enough that their data could be moved around. Let's draw these nodes as `.`. The exceptions are the empty node, which we'll draw as `_`, and the very large, very full node, which we'll draw as `#`. Let's also draw the goal data as `G`. Then, it looks like this: + +``` +(.) . G + . _ . + # . . +``` + +The goal is to move the data in the top right, `G`, to the node in parentheses. To do this, we can issue some commands to the grid and rearrange the data: + + + - Move data from `node-y0-x1` to `node-y1-x1`, leaving node `node-y0-x1` empty: +``` +(.) _ G + . . . + # . . +``` + + - Move the goal data from `node-y0-x2` to `node-y0-x1`: +``` +(.) G _ + . . . + # . . +``` + + - At this point, we're quite close. However, we have no deletion command, so we have to move some more data around. So, next, we move the data from `node-y1-x2` to `node-y0-x2`: +``` +(.) G . + . . _ + # . . +``` + + - Move the data from `node-y1-x1` to `node-y1-x2`: +``` +(.) G . + . _ . + # . . +``` + + - Move the data from `node-y1-x0` to `node-y1-x1`: +``` +(.) G . + _ . . + # . . +``` + + - Next, we can free up space on our node by moving the data from `node-y0-x0` to `node-y1-x0`: +``` +(_) G . + . . . + # . . +``` + + + - Finally, we can access the goal data by moving the it from `node-y0-x1` to `node-y0-x0`: +``` +(G) _ . + . . . + # . . +``` + + + +So, after `7` steps, we've accessed the data we want. Unfortunately, each of these moves takes time, and we need to be efficient: + +*What is the fewest number of steps* required to move your goal data to `node-x0-y0`? + + diff --git a/2016/Day22/input.in b/2016/Day22/input.in index 1c0570dda..878a6b267 100644 Binary files a/2016/Day22/input.in and b/2016/Day22/input.in differ diff --git a/2016/Day23/README.md b/2016/Day23/README.md index 6312da7fa..7e43ab965 100644 --- a/2016/Day23/README.md +++ b/2016/Day23/README.md @@ -1,6 +1,58 @@ +original source: [https://adventofcode.com/2016/day/23](https://adventofcode.com/2016/day/23) ## --- Day 23: Safe Cracking --- This is one of the top floors of the nicest tower in EBHQ. The Easter Bunny's private office is here, complete with a safe hidden behind a painting, and who *wouldn't* hide a star in a safe behind a painting? The safe has a digital screen and keypad for code entry. A sticky note attached to the safe has a password hint on it: "eggs". The painting is of a large rabbit coloring some eggs. You see `7`. -Read the [full puzzle](https://adventofcode.com/2016/day/23). \ No newline at end of file +When you go to type the code, though, nothing appears on the display; instead, the keypad comes apart in your hands, apparently having been smashed. Behind it is some kind of socket - one that matches a connector in your [prototype computer](11)! You pull apart the smashed keypad and extract the logic circuit, plug it into your computer, and plug your computer into the safe. + +Now, you just need to figure out what output the keypad would have sent to the safe. You extract the [assembunny code](12) from the logic chip (your puzzle input). + +The code looks like it uses *almost* the same architecture and instruction set that the [monorail computer](12) used! You should be able to *use the same assembunny interpreter* for this as you did there, but with one new instruction: + +`tgl x` *toggles* the instruction `x` away (pointing at instructions like `jnz` does: positive means forward; negative means backward): + + + - For *one-argument* instructions, `inc` becomes `dec`, and all other one-argument instructions become `inc`. + - For *two-argument* instructions, `jnz` becomes `cpy`, and all other two-instructions become `jnz`. + - The arguments of a toggled instruction are *not affected*. + - If an attempt is made to toggle an instruction outside the program, *nothing happens*. + - If toggling produces an *invalid instruction* (like `cpy 1 2`) and an attempt is later made to execute that instruction, *skip it instead*. + - If `tgl` toggles *itself* (for example, if `a` is `0`, `tgl a` would target itself and become `inc a`), the resulting instruction is not executed until the next time it is reached. + +For example, given this program: + +``` +cpy 2 a +tgl a +tgl a +tgl a +cpy 1 a +dec a +dec a +``` + + + - `cpy 2 a` initializes register `a` to `2`. + - The first `tgl a` toggles an instruction `a` (`2`) away from it, which changes the third `tgl a` into `inc a`. + - The second `tgl a` also modifies an instruction `2` away from it, which changes the `cpy 1 a` into `jnz 1 a`. + - The fourth line, which is now `inc a`, increments `a` to `3`. + - Finally, the fifth line, which is now `jnz 1 a`, jumps `a` (`3`) instructions ahead, skipping the `dec a` instructions. + +In this example, the final value in register `a` is `3`. + +The rest of the electronics seem to place the keypad entry (the number of eggs, `7`) in register `a`, run the code, and then send the value left in register `a` to the safe. + +*What value* should be sent to the safe? + + +## --- Part Two --- +The safe doesn't open, but it *does* make several angry noises to express its frustration. + +You're quite sure your logic is working correctly, so the only other thing is... you check the painting again. As it turns out, colored eggs are still eggs. Now you count `12`. + +As you run the program with this new input, the prototype computer begins to *overheat*. You wonder what's taking so long, and whether the lack of any instruction more powerful than "add one" has anything to do with it. Don't bunnies usually *multiply*? + +Anyway, *what value* should actually be sent to the safe? + + diff --git a/2016/Day23/input.in b/2016/Day23/input.in index ea5304016..37b4dac6f 100644 Binary files a/2016/Day23/input.in and b/2016/Day23/input.in differ diff --git a/2016/Day24/README.md b/2016/Day24/README.md index ca42bf3f9..03ad41f1a 100644 --- a/2016/Day24/README.md +++ b/2016/Day24/README.md @@ -1,6 +1,39 @@ +original source: [https://adventofcode.com/2016/day/24](https://adventofcode.com/2016/day/24) ## --- Day 24: Air Duct Spelunking --- You've finally met your match; the doors that provide access to the roof are locked tight, and all of the controls and related electronics are inaccessible. You simply can't reach them. The robot that cleans the air ducts, however, *can*. -Read the [full puzzle](https://adventofcode.com/2016/day/24). \ No newline at end of file +It's not a very fast little robot, but you reconfigure it to be able to interface with some of the exposed wires that have been routed through the [HVAC](https://en.wikipedia.org/wiki/HVAC) system. If you can direct it to each of those locations, you should be able to bypass the security controls. + +You extract the duct layout for this area from some blueprints you acquired and create a map with the relevant locations marked (your puzzle input). `0` is your current location, from which the cleaning robot embarks; the other numbers are (in *no particular order*) the locations the robot needs to visit at least once each. Walls are marked as `#`, and open passages are marked as `.`. Numbers behave like open passages. + +For example, suppose you have a map like the following: + +``` +########### +#0.1.....2# +#.#######.# +#4.......3# +########### +``` + +To reach all of the points of interest as quickly as possible, you would have the robot take the following path: + + + - `0` to `4` (`2` steps) + - `4` to `1` (`4` steps; it can't move diagonally) + - `1` to `2` (`6` steps) + - `2` to `3` (`2` steps) + +Since the robot isn't very fast, you need to find it the *shortest route*. This path is the fewest steps (in the above example, a total of `14`) required to start at `0` and then visit every other location at least once. + +Given your actual map, and starting from location `0`, what is the *fewest number of steps* required to visit every non-`0` number marked on the map at least once? + + +## --- Part Two --- +Of course, if you leave the cleaning robot somewhere weird, someone is bound to notice. + +What is the fewest number of steps required to start at `0`, visit every non-`0` number marked on the map at least once, and then *return to `0`*? + + diff --git a/2016/Day24/input.in b/2016/Day24/input.in index 5051464fd..3b3bade27 100644 Binary files a/2016/Day24/input.in and b/2016/Day24/input.in differ diff --git a/2016/Day25/README.md b/2016/Day25/README.md index 268d84818..c5e743775 100644 --- a/2016/Day25/README.md +++ b/2016/Day25/README.md @@ -1,6 +1,36 @@ +original source: [https://adventofcode.com/2016/day/25](https://adventofcode.com/2016/day/25) ## --- Day 25: Clock Signal --- You open the door and find yourself on the roof. The city sprawls away from you for miles and miles. There's not much time now - it's already Christmas, but you're nowhere near the North Pole, much too far to deliver these stars to the sleigh in time. -Read the [full puzzle](https://adventofcode.com/2016/day/25). \ No newline at end of file +However, maybe the *huge antenna* up here can offer a solution. After all, the sleigh doesn't need the stars, exactly; it needs the timing data they provide, and you happen to have a massive signal generator right here. + +You connect the stars you have to your prototype computer, connect that to the antenna, and begin the transmission. + +Nothing happens. + +You call the service number printed on the side of the antenna and quickly explain the situation. "I'm not sure what kind of equipment you have connected over there," he says, "but you need a clock signal." You try to explain that this is a signal for a clock. + +"No, no, a [clock signal](https://en.wikipedia.org/wiki/Clock_signal) - timing information so the antenna computer knows how to read the data you're sending it. An endless, alternating pattern of `0`, `1`, `0`, `1`, `0`, `1`, `0`, `1`, `0`, `1`...." He trails off. + +You ask if the antenna can handle a clock signal at the frequency you would need to use for the data from the stars. "There's *no way* it can! The only antenna we've installed capable of *that* is on top of a top-secret Easter Bunny installation, and you're *definitely* not-" You hang up the phone. + +You've extracted the antenna's clock signal generation [assembunny](12) code (your puzzle input); it looks mostly compatible with code you worked on [just recently](23). + +This antenna code, being a signal generator, uses one extra instruction: + + + - `out x` *transmits* `x` (either an integer or the *value* of a register) as the next value for the clock signal. + +The code takes a value (via register `a`) that describes the signal to generate, but you're not sure how it's used. You'll have to find the input to produce the right signal through experimentation. + +*What is the lowest positive integer* that can be used to initialize register `a` and cause the code to output a clock signal of `0`, `1`, `0`, `1`... repeating forever? + + +## --- Part Two --- +The antenna is ready. Now, all you need is the *fifty stars* required to generate the signal for the sleigh, but you don't have enough. + +You look toward the sky in desperation... suddenly noticing that a lone star has been installed at the top of the antenna! Only *49 more* to go. + + diff --git a/2016/Day25/input.in b/2016/Day25/input.in index 98d287199..8038270ba 100644 Binary files a/2016/Day25/input.in and b/2016/Day25/input.in differ diff --git a/2016/README.md b/2016/README.md index d3ef6bd90..8212cc07f 100644 --- a/2016/README.md +++ b/2016/README.md @@ -1,4 +1,6 @@ + # Advent of Code (2016) Check out https://adventofcode.com/2016. + diff --git a/2016/SplashScreen.cs b/2016/SplashScreen.cs index 04fac5852..33cb596bf 100644 --- a/2016/SplashScreen.cs +++ b/2016/SplashScreen.cs @@ -1,3 +1,4 @@ + using System; namespace AdventOfCode.Y2016; @@ -8,258 +9,258 @@ public void Show() { var color = Console.ForegroundColor; Write(0xcc00, false, " ▄█▄ ▄▄█ ▄ ▄ ▄▄▄ ▄▄ ▄█▄ ▄▄▄ ▄█ ▄▄ ▄▄▄ ▄▄█ ▄▄▄\n █▄█ █ █ █ █ █▄█ █ █ █ █ █ █▄ "); - Write(0xcc00, false, " █ █ █ █ █ █▄█\n █ █ █▄█ ▀▄▀ █▄▄ █ █ █▄ █▄█ █ █▄ █▄█ █▄█ █▄▄ // 2016\n \n "); - Write(0xcc00, false, " "); - Write(0xffff66, true, "( ( ( ( ((*)) ) ) ) ) \n "); - Write(0x666666, false, " | \n +-|---+ "); - Write(0x666666, false, " \n / | /| \n "); - Write(0x666666, false, " +-----+ | \n |"); - Write(0x333333, false, "::"); - Write(0xffff66, true, ":"); - Write(0x333333, false, "::"); - Write(0x666666, false, "| | "); - Write(0xcccccc, false, "25 "); - Write(0xffff66, false, "**\n "); - Write(0x666666, false, " +----+ |"); - Write(0x333333, false, "::"); - Write(0x9900, true, ":"); - Write(0x333333, false, "::"); - Write(0x666666, false, "| |---+ +-----------+ "); - Write(0xcccccc, false, "24 "); - Write(0xffff66, false, "**\n "); - Write(0x666666, false, " / / \\ |"); - Write(0x333333, false, ":"); - Write(0x9900, true, ":::"); - Write(0x333333, false, ":"); - Write(0x666666, false, "| | /| / \\\\\\\\\\\\ [] /| "); - Write(0xcccccc, false, "23 "); - Write(0xffff66, false, "**\n "); - Write(0x666666, false, " / / / \\|"); - Write(0x9900, true, ":::::"); - Write(0x666666, false, "| | / | / \\\\\\\\\\\\ [] / | "); - Write(0xcccccc, false, "22 "); - Write(0xffff66, false, "**\n "); - Write(0x666666, false, " / / / / \\"); - Write(0x333333, false, "::"); - Write(0x553322, true, ":"); - Write(0x333333, false, "::"); - Write(0x666666, false, "|/ / | +-----------+ | "); - Write(0xcccccc, false, "21 "); - Write(0xffff66, false, "**\n "); - Write(0x666666, false, " +----+ / / / \\------+ ------|"); - Write(0x333333, false, "::::"); - Write(0x66ff, true, ":"); - Write(0x333333, false, ":"); - Write(0x66ff, true, ":"); - Write(0x333333, false, "::::"); - Write(0x666666, false, "| | "); - Write(0xcccccc, false, "20 "); - Write(0xffff66, false, "**\n "); - Write(0x666666, false, " |-----\\ / / / \\=====| ------|"); - Write(0x333333, false, ":"); - Write(0x66ff, true, ":"); - Write(0x333333, false, ":::"); - Write(0x66ff, true, ":"); - Write(0x333333, false, ":::"); - Write(0x66ff, true, ":"); - Write(0x333333, false, ":"); - Write(0x666666, false, "| | "); - Write(0xcccccc, false, "19 "); - Write(0xffff66, false, "**\n "); - Write(0x666666, false, " |------\\ / / / \\====| | |"); - Write(0x66ff, true, ":::"); - Write(0x333333, false, ":"); - Write(0x66ff, true, ":::"); - Write(0x333333, false, ":"); - Write(0x66ff, true, ":::"); - Write(0x666666, false, "| | "); - Write(0xcccccc, false, "18 "); - Write(0xffff66, false, "**\n "); - Write(0x666666, false, " |-------\\ / / / +===| | |"); - Write(0x333333, false, ":::"); - Write(0x66ff, true, ":"); - Write(0x333333, false, ":::"); - Write(0x66ff, true, ":"); - Write(0x333333, false, ":::"); - Write(0x666666, false, "| | "); - Write(0xcccccc, false, "17 "); - Write(0xffff66, false, "**\n "); - Write(0x666666, false, " |--------\\ / / /|===| | |"); - Write(0x333333, false, ":::"); - Write(0x66ff, true, ":"); - Write(0x333333, false, ":::"); - Write(0x66ff, true, ":"); - Write(0x333333, false, ":::"); - Write(0x666666, false, "| | "); - Write(0xcccccc, false, "16 "); - Write(0xffff66, false, "**\n "); - Write(0x666666, false, " |---------\\ / / |===| | /|"); - Write(0x66ff, true, ":::"); - Write(0x333333, false, ":"); - Write(0x66ff, true, ":::"); - Write(0x333333, false, ":"); - Write(0x66ff, true, ":::"); - Write(0x666666, false, "| | "); - Write(0xcccccc, false, "15 "); - Write(0xffff66, false, "**\n "); - Write(0x666666, false, " |----------\\ / |===| / //|"); - Write(0x333333, false, ":"); - Write(0x66ff, true, ":"); - Write(0x333333, false, ":::"); - Write(0x66ff, true, ":"); - Write(0x333333, false, ":::"); - Write(0x66ff, true, ":"); - Write(0x333333, false, ":"); - Write(0x666666, false, "| / "); - Write(0xcccccc, false, "14 "); - Write(0xffff66, false, "**\n "); - Write(0x666666, false, " +-----------+ |===| / //||"); - Write(0x333333, false, "::::"); - Write(0x66ff, true, ":"); - Write(0x333333, false, ":"); - Write(0x66ff, true, ":"); - Write(0x333333, false, "::::"); - Write(0x666666, false, "|/ "); - Write(0xcccccc, false, "13 "); - Write(0xffff66, false, "**\n "); - Write(0x666666, false, " |"); - Write(0xff0000, true, ":"); - Write(0x333333, false, ":"); - Write(0xff0000, true, ":"); - Write(0x333333, false, "::::::::"); - Write(0x666666, false, "| |===|/__//___________________ "); - Write(0xcccccc, false, "12 "); - Write(0xffff66, false, "**\n "); - Write(0x666666, false, " |"); - Write(0xff0000, true, ":::"); - Write(0x333333, false, ":"); - Write(0x9900, true, ":::"); - Write(0x333333, false, "::::"); - Write(0x666666, false, "| |______//|_____...._________ "); - Write(0xcccccc, false, "11 "); - Write(0xffff66, false, "**\n "); - Write(0x666666, false, " |"); - Write(0xff0000, true, ":"); - Write(0x333333, false, ":"); - Write(0xff0000, true, ":"); - Write(0x333333, false, ":"); - Write(0x9900, true, ":"); - Write(0x333333, false, ":"); - Write(0x9900, true, ":"); - Write(0x333333, false, "::::"); - Write(0x666666, false, "| | //| ____/ /_/___ "); - Write(0xcccccc, false, "10 "); - Write(0xffff66, false, "**\n "); - Write(0x666666, false, " ---|"); - Write(0x333333, false, "::::"); - Write(0x9900, true, ":::"); - Write(0x333333, false, "::::"); - Write(0x666666, false, "| |--------|[][]|_|[][]_\\------ "); - Write(0xcccccc, false, " 9 "); - Write(0xffff66, false, "**\n "); - Write(0x666666, false, "----|"); - Write(0x333333, false, "::"); - Write(0xff0000, true, ":"); - Write(0x333333, false, ":"); - Write(0xff0000, true, ":"); - Write(0x333333, false, "::::::"); - Write(0x666666, false, "| |--------------------------- "); - Write(0xcccccc, false, " 8 "); - Write(0xffff66, false, "**\n "); - Write(0x666666, false, " || |"); - Write(0x333333, false, "::"); - Write(0xff0000, true, ":::"); - Write(0x333333, false, ":"); - Write(0x9900, true, ":::"); - Write(0x333333, false, "::"); - Write(0x666666, false, "| | //| || / / / || || "); - Write(0xcccccc, false, " 7 "); - Write(0xffff66, false, "**\n "); - Write(0x666666, false, " || |"); - Write(0x333333, false, "::"); - Write(0xff0000, true, ":"); - Write(0x333333, false, ":"); - Write(0xff0000, true, ":"); - Write(0x333333, false, ":"); - Write(0x9900, true, ":"); - Write(0x333333, false, ":"); - Write(0x9900, true, ":"); - Write(0x333333, false, "::"); - Write(0x666666, false, "| | //| || / / || "); - Write(0xffff66, true, "*"); - Write(0x666666, false, " || "); - Write(0xcccccc, false, " 6 "); - Write(0xffff66, false, "**\n "); - Write(0x666666, false, " |"); - Write(0x333333, false, "::::::"); - Write(0x9900, true, ":::"); - Write(0x333333, false, "::"); - Write(0x666666, false, "| |//| / / / "); - Write(0x9900, false, ">"); - Write(0xff9900, true, "o"); - Write(0x9900, false, "< "); - Write(0xcccccc, false, " 5 "); - Write(0xffff66, false, "**\n "); - Write(0x666666, false, " |"); - Write(0x333333, false, "::::"); - Write(0xff0000, true, ":"); - Write(0x333333, false, ":"); - Write(0xff0000, true, ":"); - Write(0x333333, false, "::::"); - Write(0x666666, false, "| //| / / ___"); - Write(0x9900, false, ">"); - Write(0xff0000, true, "@"); - Write(0x9900, false, ">"); - Write(0x66ff, true, "O"); - Write(0x9900, false, "<"); - Write(0x666666, false, "____ "); - Write(0xcccccc, false, " 4 "); - Write(0xffff66, false, "**\n "); - Write(0x666666, false, " |"); - Write(0x333333, false, "::::"); - Write(0xff0000, true, ":::"); - Write(0x333333, false, ":"); - Write(0x9900, true, ":::"); - Write(0x666666, false, "| //| / / / / "); - Write(0x9900, false, ">"); - Write(0x66ff, true, "O"); - Write(0x9900, false, ">"); - Write(0xff9900, true, "o"); - Write(0x9900, false, "<"); - Write(0xff0000, true, "@"); - Write(0x9900, false, "<"); - Write(0x666666, false, " / "); - Write(0xcccccc, false, " 3 "); - Write(0xffff66, false, "**\n "); - Write(0x666666, false, " |"); - Write(0x333333, false, "::::"); - Write(0xff0000, true, ":"); - Write(0x333333, false, ":"); - Write(0xff0000, true, ":"); - Write(0x333333, false, ":"); - Write(0x9900, true, ":"); - Write(0x333333, false, ":"); - Write(0x9900, true, ":"); - Write(0x666666, false, "| //| / / / "); - Write(0xaaaaaa, false, "_| |_"); - Write(0x666666, false, " / "); - Write(0xcccccc, false, " 2 "); - Write(0xffff66, false, "**\n "); - Write(0x666666, false, " |"); - Write(0x333333, false, "::::::::"); - Write(0x9900, true, ":::"); - Write(0x666666, false, "|//| / / / /___________/ "); - Write(0xcccccc, false, " 1 "); - Write(0xffff66, false, "**\n "); - Write(0x666666, false, " ==============//======+...+==================== \n - - - - - - -// - - -/ / - -"); - Write(0x666666, false, " - - - - - - - - \n ==============//|============================== \n "); - Write(0x666666, false, " //| \n \n"); - + Write(0xcc00, false, " █ █ █ █ █ █▄█\n █ █ █▄█ ▀▄▀ █▄▄ █ █ █▄ █▄█ █ █▄ █▄█ █▄█ █▄▄ // 2016\n \n "); + Write(0xcc00, false, " "); + Write(0xffff66, true, "( ( ( ( ((*)) ) ) ) ) \n "); + Write(0x666666, false, " | \n +-|---+ "); + Write(0x666666, false, " \n / | /| \n "); + Write(0x666666, false, " +-----+ | \n |"); + Write(0x333333, false, "::"); + Write(0xffff66, true, ":"); + Write(0x333333, false, "::"); + Write(0x666666, false, "| | "); + Write(0xcccccc, false, "25 "); + Write(0xffff66, false, "**\n "); + Write(0x666666, false, " +----+ |"); + Write(0x333333, false, "::"); + Write(0x9900, true, ":"); + Write(0x333333, false, "::"); + Write(0x666666, false, "| |---+ +-----------+ "); + Write(0xcccccc, false, "24 "); + Write(0xffff66, false, "**\n "); + Write(0x666666, false, " / / \\ |"); + Write(0x333333, false, ":"); + Write(0x9900, true, ":::"); + Write(0x333333, false, ":"); + Write(0x666666, false, "| | /| / \\\\\\\\\\\\ [] /| "); + Write(0xcccccc, false, "23 "); + Write(0xffff66, false, "**\n "); + Write(0x666666, false, " / / / \\|"); + Write(0x9900, true, ":::::"); + Write(0x666666, false, "| | / | / \\\\\\\\\\\\ [] / | "); + Write(0xcccccc, false, "22 "); + Write(0xffff66, false, "**\n "); + Write(0x666666, false, " / / / / \\"); + Write(0x333333, false, "::"); + Write(0x553322, true, ":"); + Write(0x333333, false, "::"); + Write(0x666666, false, "|/ / | +-----------+ | "); + Write(0xcccccc, false, "21 "); + Write(0xffff66, false, "**\n "); + Write(0x666666, false, " +----+ / / / \\------+ ------|"); + Write(0x333333, false, "::::"); + Write(0x66ff, true, ":"); + Write(0x333333, false, ":"); + Write(0x66ff, true, ":"); + Write(0x333333, false, "::::"); + Write(0x666666, false, "| | "); + Write(0xcccccc, false, "20 "); + Write(0xffff66, false, "**\n "); + Write(0x666666, false, " |-----\\ / / / \\=====| ------|"); + Write(0x333333, false, ":"); + Write(0x66ff, true, ":"); + Write(0x333333, false, ":::"); + Write(0x66ff, true, ":"); + Write(0x333333, false, ":::"); + Write(0x66ff, true, ":"); + Write(0x333333, false, ":"); + Write(0x666666, false, "| | "); + Write(0xcccccc, false, "19 "); + Write(0xffff66, false, "**\n "); + Write(0x666666, false, " |------\\ / / / \\====| | |"); + Write(0x66ff, true, ":::"); + Write(0x333333, false, ":"); + Write(0x66ff, true, ":::"); + Write(0x333333, false, ":"); + Write(0x66ff, true, ":::"); + Write(0x666666, false, "| | "); + Write(0xcccccc, false, "18 "); + Write(0xffff66, false, "**\n "); + Write(0x666666, false, " |-------\\ / / / +===| | |"); + Write(0x333333, false, ":::"); + Write(0x66ff, true, ":"); + Write(0x333333, false, ":::"); + Write(0x66ff, true, ":"); + Write(0x333333, false, ":::"); + Write(0x666666, false, "| | "); + Write(0xcccccc, false, "17 "); + Write(0xffff66, false, "**\n "); + Write(0x666666, false, " |--------\\ / / /|===| | |"); + Write(0x333333, false, ":::"); + Write(0x66ff, true, ":"); + Write(0x333333, false, ":::"); + Write(0x66ff, true, ":"); + Write(0x333333, false, ":::"); + Write(0x666666, false, "| | "); + Write(0xcccccc, false, "16 "); + Write(0xffff66, false, "**\n "); + Write(0x666666, false, " |---------\\ / / |===| | /|"); + Write(0x66ff, true, ":::"); + Write(0x333333, false, ":"); + Write(0x66ff, true, ":::"); + Write(0x333333, false, ":"); + Write(0x66ff, true, ":::"); + Write(0x666666, false, "| | "); + Write(0xcccccc, false, "15 "); + Write(0xffff66, false, "**\n "); + Write(0x666666, false, " |----------\\ / |===| / //|"); + Write(0x333333, false, ":"); + Write(0x66ff, true, ":"); + Write(0x333333, false, ":::"); + Write(0x66ff, true, ":"); + Write(0x333333, false, ":::"); + Write(0x66ff, true, ":"); + Write(0x333333, false, ":"); + Write(0x666666, false, "| / "); + Write(0xcccccc, false, "14 "); + Write(0xffff66, false, "**\n "); + Write(0x666666, false, " +-----------+ |===| / //||"); + Write(0x333333, false, "::::"); + Write(0x66ff, true, ":"); + Write(0x333333, false, ":"); + Write(0x66ff, true, ":"); + Write(0x333333, false, "::::"); + Write(0x666666, false, "|/ "); + Write(0xcccccc, false, "13 "); + Write(0xffff66, false, "**\n "); + Write(0x666666, false, " |"); + Write(0xff0000, true, ":"); + Write(0x333333, false, ":"); + Write(0xff0000, true, ":"); + Write(0x333333, false, "::::::::"); + Write(0x666666, false, "| |===|/__//___________________ "); + Write(0xcccccc, false, "12 "); + Write(0xffff66, false, "**\n "); + Write(0x666666, false, " |"); + Write(0xff0000, true, ":::"); + Write(0x333333, false, ":"); + Write(0x9900, true, ":::"); + Write(0x333333, false, "::::"); + Write(0x666666, false, "| |______//|_____...._________ "); + Write(0xcccccc, false, "11 "); + Write(0xffff66, false, "**\n "); + Write(0x666666, false, " |"); + Write(0xff0000, true, ":"); + Write(0x333333, false, ":"); + Write(0xff0000, true, ":"); + Write(0x333333, false, ":"); + Write(0x9900, true, ":"); + Write(0x333333, false, ":"); + Write(0x9900, true, ":"); + Write(0x333333, false, "::::"); + Write(0x666666, false, "| | //| ____/ /_/___ "); + Write(0xcccccc, false, "10 "); + Write(0xffff66, false, "**\n "); + Write(0x666666, false, " ---|"); + Write(0x333333, false, "::::"); + Write(0x9900, true, ":::"); + Write(0x333333, false, "::::"); + Write(0x666666, false, "| |--------|[][]|_|[][]_\\------ "); + Write(0xcccccc, false, " 9 "); + Write(0xffff66, false, "**\n "); + Write(0x666666, false, "----|"); + Write(0x333333, false, "::"); + Write(0xff0000, true, ":"); + Write(0x333333, false, ":"); + Write(0xff0000, true, ":"); + Write(0x333333, false, "::::::"); + Write(0x666666, false, "| |--------------------------- "); + Write(0xcccccc, false, " 8 "); + Write(0xffff66, false, "**\n "); + Write(0x666666, false, " || |"); + Write(0x333333, false, "::"); + Write(0xff0000, true, ":::"); + Write(0x333333, false, ":"); + Write(0x9900, true, ":::"); + Write(0x333333, false, "::"); + Write(0x666666, false, "| | //| || / / / || || "); + Write(0xcccccc, false, " 7 "); + Write(0xffff66, false, "**\n "); + Write(0x666666, false, " || |"); + Write(0x333333, false, "::"); + Write(0xff0000, true, ":"); + Write(0x333333, false, ":"); + Write(0xff0000, true, ":"); + Write(0x333333, false, ":"); + Write(0x9900, true, ":"); + Write(0x333333, false, ":"); + Write(0x9900, true, ":"); + Write(0x333333, false, "::"); + Write(0x666666, false, "| | //| || / / || "); + Write(0xffff66, true, "*"); + Write(0x666666, false, " || "); + Write(0xcccccc, false, " 6 "); + Write(0xffff66, false, "**\n "); + Write(0x666666, false, " |"); + Write(0x333333, false, "::::::"); + Write(0x9900, true, ":::"); + Write(0x333333, false, "::"); + Write(0x666666, false, "| |//| / / / "); + Write(0x9900, false, ">"); + Write(0xff9900, true, "o"); + Write(0x9900, false, "< "); + Write(0xcccccc, false, " 5 "); + Write(0xffff66, false, "**\n "); + Write(0x666666, false, " |"); + Write(0x333333, false, "::::"); + Write(0xff0000, true, ":"); + Write(0x333333, false, ":"); + Write(0xff0000, true, ":"); + Write(0x333333, false, "::::"); + Write(0x666666, false, "| //| / / ___"); + Write(0x9900, false, ">"); + Write(0xff0000, true, "@"); + Write(0x9900, false, ">"); + Write(0x66ff, true, "O"); + Write(0x9900, false, "<"); + Write(0x666666, false, "____ "); + Write(0xcccccc, false, " 4 "); + Write(0xffff66, false, "**\n "); + Write(0x666666, false, " |"); + Write(0x333333, false, "::::"); + Write(0xff0000, true, ":::"); + Write(0x333333, false, ":"); + Write(0x9900, true, ":::"); + Write(0x666666, false, "| //| / / / / "); + Write(0x9900, false, ">"); + Write(0x66ff, true, "O"); + Write(0x9900, false, ">"); + Write(0xff9900, true, "o"); + Write(0x9900, false, "<"); + Write(0xff0000, true, "@"); + Write(0x9900, false, "<"); + Write(0x666666, false, " / "); + Write(0xcccccc, false, " 3 "); + Write(0xffff66, false, "**\n "); + Write(0x666666, false, " |"); + Write(0x333333, false, "::::"); + Write(0xff0000, true, ":"); + Write(0x333333, false, ":"); + Write(0xff0000, true, ":"); + Write(0x333333, false, ":"); + Write(0x9900, true, ":"); + Write(0x333333, false, ":"); + Write(0x9900, true, ":"); + Write(0x666666, false, "| //| / / / "); + Write(0xaaaaaa, false, "_| |_"); + Write(0x666666, false, " / "); + Write(0xcccccc, false, " 2 "); + Write(0xffff66, false, "**\n "); + Write(0x666666, false, " |"); + Write(0x333333, false, "::::::::"); + Write(0x9900, true, ":::"); + Write(0x666666, false, "|//| / / / /___________/ "); + Write(0xcccccc, false, " 1 "); + Write(0xffff66, false, "**\n "); + Write(0x666666, false, " ==============//======+...+==================== \n - - - - - - -// - - -/ / - -"); + Write(0x666666, false, " - - - - - - - - \n ==============//|============================== \n "); + Write(0x666666, false, " //| \n \n"); + Console.ForegroundColor = color; Console.WriteLine(); } - private static void Write(int rgb, bool bold, string text){ + private static void Write(int rgb, bool bold, string text){ Console.Write($"\u001b[38;2;{(rgb>>16)&255};{(rgb>>8)&255};{rgb&255}{(bold ? ";1" : "")}m{text}"); - } -} \ No newline at end of file + } +} diff --git a/2016/calendar.svg b/2016/calendar.svg index 001a5323e..cf103d895 100644 --- a/2016/calendar.svg +++ b/2016/calendar.svg @@ -1,15 +1,15 @@ - - + + ▄█▄ ▄▄█ ▄ ▄ ▄▄▄ ▄▄ ▄█▄  ▄▄▄ ▄█  ▄▄ ▄▄▄ ▄▄█ ▄▄▄ █▄█ █ █ █ █ █▄█ █ █ █   █ █ █▄  █  █ █ █ █ █▄█ @@ -20,36 +20,36 @@                   +-|---+                                                 /  |  /|                                                +-----+ |                                -                |:::::| |                          25 ** -        +----+  |:::::| |---+      +-----------+   24 ** -       /    / \ |:::::| |  /|     / \\\\\\ [] /|   23 ** -      /    / / \|:::::| | / |    / \\\\\\ [] / |   22 ** -     /    / / / \:::::|/ /  |   +-----------+  |   21 ** -    +----+ / / / \------+ ------|:::::::::::|  |   20 ** -    |-----\ / / / \=====| ------|:::::::::::|  |   19 ** -    |------\ / / / \====|   |   |:::::::::::|  |   18 ** -    |-------\ / / / +===|   |   |:::::::::::|  |   17 ** -    |--------\ / / /|===|   |   |:::::::::::|  |   16 ** -    |---------\ / / |===|   |  /|:::::::::::|  |   15 ** -    |----------\ /  |===|  /  //|:::::::::::| /    14 ** -    +-----------+   |===| /  //||:::::::::::|/     13 ** -    |:::::::::::|   |===|/__//___________________  12 ** -    |:::::::::::|   |______//|_____...._________   11 ** -    |:::::::::::|   |     //| ____/ /_/___         10 ** - ---|:::::::::::|   |--------|[][]|_|[][]_\------   9 ** -----|:::::::::::|   |---------------------------    8 ** - || |:::::::::::|   |  //| ||  / / / ||      ||     7 ** - || |:::::::::::|   | //|  || /   /  ||  *   ||     6 ** -    |:::::::::::|   |//|     / / /      >o<         5 ** -    |:::::::::::|   //|     /   /   ___>@>O<____    4 ** -    |:::::::::::|  //|     / / /   /  >O>o<@<  /    3 ** -    |:::::::::::| //|     /   /   /    _| |_  /     2 ** -    |:::::::::::|//|     / / /   /___________/      1 ** +                |:::::| |                          25 ** +        +----+  |:::::| |---+      +-----------+   24 ** +       /    / \ |:::::| |  /|     / \\\\\\ [] /|   23 ** +      /    / / \|:::::| | / |    / \\\\\\ [] / |   22 ** +     /    / / / \:::::|/ /  |   +-----------+  |   21 ** +    +----+ / / / \------+ ------|:::::::::::|  |   20 ** +    |-----\ / / / \=====| ------|:::::::::::|  |   19 ** +    |------\ / / / \====|   |   |:::::::::::|  |   18 ** +    |-------\ / / / +===|   |   |:::::::::::|  |   17 ** +    |--------\ / / /|===|   |   |:::::::::::|  |   16 ** +    |---------\ / / |===|   |  /|:::::::::::|  |   15 ** +    |----------\ /  |===|  /  //|:::::::::::| /    14 ** +    +-----------+   |===| /  //||:::::::::::|/     13 ** +    |:::::::::::|   |===|/__//___________________  12 ** +    |:::::::::::|   |______//|_____...._________   11 ** +    |:::::::::::|   |     //| ____/ /_/___         10 ** + ---|:::::::::::|   |--------|[][]|_|[][]_\------   9 ** +----|:::::::::::|   |---------------------------    8 ** + || |:::::::::::|   |  //| ||  / / / ||      ||     7 ** + || |:::::::::::|   | //|  || /   /  ||  *   ||     6 ** +    |:::::::::::|   |//|     / / /      >o<         5 ** +    |:::::::::::|   //|     /   /   ___>@>O<____    4 ** +    |:::::::::::|  //|     / / /   /  >O>o<@<  /    3 ** +    |:::::::::::| //|     /   /   /    _| |_  /     2 ** +    |:::::::::::|//|     / / /   /___________/      1 **   ==============//======+...+====================          - - - - - - -// - - -/   / - - - - - - - - - -         ==============//|==============================          -             //|                                         +             //|                                         - \ No newline at end of file + \ No newline at end of file diff --git a/2017/Day01/README.md b/2017/Day01/README.md index ceb540a18..b9f981871 100644 --- a/2017/Day01/README.md +++ b/2017/Day01/README.md @@ -1,6 +1,42 @@ +original source: [https://adventofcode.com/2017/day/1](https://adventofcode.com/2017/day/1) ## --- Day 1: Inverse Captcha --- The night before Christmas, one of Santa's Elves calls you in a panic. "The printer's broken! We can't print the Naughty or Nice List!" By the time you make it to sub-basement 17, there are only a few minutes until midnight. "We have a big problem," she says; "there must be almost fifty bugs in this system, but nothing else can print The List. Stand in this square, quick! There's no time to explain; if you can convince them to pay you in stars, you'll be able to--" She pulls a lever and the world goes blurry. When your eyes can focus again, everything seems a lot more pixelated than before. She must have sent you inside the computer! You check the system clock: 25 milliseconds until midnight. With that much time, you should be able to collect all fifty stars by December 25th. -_Visit the website for the full story and [full puzzle](https://adventofcode.com/2017/day/1) description._ +Collect stars by solving puzzles. Two puzzles will be made available on each ~~day~~ millisecond in the Advent calendar; the second puzzle is unlocked when you complete the first. Each puzzle grants one star. Good luck! + +You're standing in a room with "digitization quarantine" written in LEDs along one wall. The only door is locked, but it includes a small interface. "Restricted Area - Strictly No Digitized Users Allowed." + +It goes on to explain that you may only leave by solving a [captcha](https://en.wikipedia.org/wiki/CAPTCHA) to prove you're not a human. Apparently, you only get one millisecond to solve the captcha: too fast for a normal human, but it feels like hours to you. + +The captcha requires you to review a sequence of digits (your puzzle input) and find the sum of all digits that match the next digit in the list. The list is circular, so the digit after the last digit is the first digit in the list. + +For example: + + + - 1122 produces a sum of 3 (1 + 2) because the first digit (1) matches the second digit and the third digit (2) matches the fourth digit. + - 1111 produces 4 because each digit (all 1) matches the next. + - 1234 produces 0 because no digit matches the next. + - 91212129 produces 9 because the only digit that matches the next one is the last digit, 9. + +What is the solution to your captcha? + + +## --- Part Two --- +You notice a progress bar that jumps to 50% completion. Apparently, the door isn't yet satisfied, but it did emit a star as encouragement. The instructions change: + +Now, instead of considering the next digit, it wants you to consider the digit halfway around the circular list. That is, if your list contains 10 items, only include a digit in your sum if the digit 10/2 = 5 steps forward matches it. Fortunately, your list has an even number of elements. + +For example: + + + - 1212 produces 6: the list contains 4 items, and all four digits match the digit 2 items ahead. + - 1221 produces 0, because every comparison is between a 1 and a 2. + - 123425 produces 4, because both 2s match each other, but no other digit has a match. + - 123123 produces 12. + - 12131415 produces 4. + +What is the solution to your new captcha? + + diff --git a/2017/Day01/input.in b/2017/Day01/input.in index a2138c7ab..2b1f7768f 100644 Binary files a/2017/Day01/input.in and b/2017/Day01/input.in differ diff --git a/2017/Day02/README.md b/2017/Day02/README.md index f2bb4b766..e007cf40b 100644 --- a/2017/Day02/README.md +++ b/2017/Day02/README.md @@ -1,6 +1,49 @@ +original source: [https://adventofcode.com/2017/day/2](https://adventofcode.com/2017/day/2) ## --- Day 2: Corruption Checksum --- As you walk through the door, a glowing humanoid shape yells in your direction. "You there! Your state appears to be idle. Come help us repair the corruption in this spreadsheet - if we take another millisecond, we'll have to display an hourglass cursor!" The spreadsheet consists of rows of apparently-random numbers. To make sure the recovery process is on the right track, they need you to calculate the spreadsheet's *checksum*. For each row, determine the difference between the largest value and the smallest value; the checksum is the sum of all of these differences. -Read the [full puzzle](https://adventofcode.com/2017/day/2). \ No newline at end of file +For example, given the following spreadsheet: + +``` +5 1 9 5 +7 5 3 +2 4 6 8 +``` + + + - The first row's largest and smallest values are `9` and `1`, and their difference is `8`. + - The second row's largest and smallest values are `7` and `3`, and their difference is `4`. + - The third row's difference is `6`. + +In this example, the spreadsheet's checksum would be `8 + 4 + 6 = 18`. + +*What is the checksum* for the spreadsheet in your puzzle input? + + +## --- Part Two --- +"Great work; looks like we're on the right track after all. Here's a *star* for your effort." However, the program seems a little worried. Can programs *be* worried? + +"Based on what we're seeing, it looks like all the User wanted is some information about the *evenly divisible values* in the spreadsheet. Unfortunately, none of us are equipped for that kind of calculation - most of us specialize in bitwise operations." + +It sounds like the goal is to find the only two numbers in each row where one evenly divides the other - that is, where the result of the division operation is a whole number. They would like you to find those numbers on each line, divide them, and add up each line's result. + +For example, given the following spreadsheet: + +``` +5 9 2 8 +9 4 7 3 +3 8 6 5 +``` + + + - In the first row, the only two numbers that evenly divide are `8` and `2`; the result of this division is `4`. + - In the second row, the two numbers are `9` and `3`; the result is `3`. + - In the third row, the result is `2`. + +In this example, the sum of the results would be `4 + 3 + 2 = 9`. + +What is the *sum of each row's result* in your puzzle input? + + diff --git a/2017/Day02/input.in b/2017/Day02/input.in index e09ace427..ff84c807e 100644 Binary files a/2017/Day02/input.in and b/2017/Day02/input.in differ diff --git a/2017/Day03/README.md b/2017/Day03/README.md index 8bf5afc07..2040b18ef 100644 --- a/2017/Day03/README.md +++ b/2017/Day03/README.md @@ -1,6 +1,52 @@ +original source: [https://adventofcode.com/2017/day/3](https://adventofcode.com/2017/day/3) ## --- Day 3: Spiral Memory --- You come across an experimental new kind of memory stored on an infinite two-dimensional grid. Each square on the grid is allocated in a spiral pattern starting at a location marked `1` and then counting up while spiraling outward. For example, the first few squares are allocated like this: -Read the [full puzzle](https://adventofcode.com/2017/day/3). \ No newline at end of file +``` +17 16 15 14 13 +18 5 4 3 12 +19 6 1 2 11 +20 7 8 9 10 +21 22 23---> ... +``` + +While this is very space-efficient (no squares are skipped), requested data must be carried back to square `1` (the location of the only access port for this memory system) by programs that can only move up, down, left, or right. They always take the shortest path: the [Manhattan Distance](https://en.wikipedia.org/wiki/Taxicab_geometry) between the location of the data and square `1`. + +For example: + + + - Data from square `1` is carried `0` steps, since it's at the access port. + - Data from square `12` is carried `3` steps, such as: down, left, left. + - Data from square `23` is carried only `2` steps: up twice. + - Data from square `1024` must be carried `31` steps. + +*How many steps* are required to carry the data from the square identified in your puzzle input all the way to the access port? + + +## --- Part Two --- +As a stress test on the system, the programs here clear the grid and then store the value `1` in square `1`. Then, in the same allocation order as shown above, they store the sum of the values in all adjacent squares, including diagonals. + +So, the first few squares' values are chosen as follows: + + + - Square `1` starts with the value `1`. + - Square `2` has only one adjacent filled square (with value `1`), so it also stores `1`. + - Square `3` has both of the above squares as neighbors and stores the sum of their values, `2`. + - Square `4` has all three of the aforementioned squares as neighbors and stores the sum of their values, `4`. + - Square `5` only has the first and fourth squares as neighbors, so it gets the value `5`. + +Once a square is written, its value does not change. Therefore, the first few squares would receive the following values: + +``` +147 142 133 122 59 +304 5 4 2 57 +330 10 1 1 54 +351 11 23 25 26 +362 747 806---> ... +``` + +What is the *first value written* that is *larger* than your puzzle input? + + diff --git a/2017/Day03/input.in b/2017/Day03/input.in index 799a453dc..232509ee5 100644 Binary files a/2017/Day03/input.in and b/2017/Day03/input.in differ diff --git a/2017/Day04/README.md b/2017/Day04/README.md index 1c942d90a..95fb9c63f 100644 --- a/2017/Day04/README.md +++ b/2017/Day04/README.md @@ -1,6 +1,31 @@ +original source: [https://adventofcode.com/2017/day/4](https://adventofcode.com/2017/day/4) ## --- Day 4: High-Entropy Passphrases --- A new system policy has been put in place that requires all accounts to use a *passphrase* instead of simply a pass*word*. A passphrase consists of a series of words (lowercase letters) separated by spaces. To ensure security, a valid passphrase must contain no duplicate words. -Read the [full puzzle](https://adventofcode.com/2017/day/4). \ No newline at end of file +For example: + + + - `aa bb cc dd ee` is valid. + - `aa bb cc dd aa` is not valid - the word `aa` appears more than once. + - `aa bb cc dd aaa` is valid - `aa` and `aaa` count as different words. + +The system's full passphrase list is available as your puzzle input. *How many passphrases are valid?* + + +## --- Part Two --- +For added security, yet another system policy has been put in place. Now, a valid passphrase must contain no two words that are anagrams of each other - that is, a passphrase is invalid if any word's letters can be rearranged to form any other word in the passphrase. + +For example: + + + - `abcde fghij` is a valid passphrase. + - `abcde xyz ecdab` is not valid - the letters from the third word can be rearranged to form the first word. + - `a ab abc abd abf abj` is a valid passphrase, because *all* letters need to be used when forming another word. + - `iiii oiii ooii oooi oooo` is valid. + - `oiii ioii iioi iiio` is not valid - any of these words can be rearranged to form any other word. + +Under this new system policy, *how many passphrases are valid?* + + diff --git a/2017/Day04/input.in b/2017/Day04/input.in index a2a581f41..dc46914f7 100644 Binary files a/2017/Day04/input.in and b/2017/Day04/input.in differ diff --git a/2017/Day05/README.md b/2017/Day05/README.md index 838976f6a..58e0a5de5 100644 --- a/2017/Day05/README.md +++ b/2017/Day05/README.md @@ -1,6 +1,41 @@ +original source: [https://adventofcode.com/2017/day/5](https://adventofcode.com/2017/day/5) ## --- Day 5: A Maze of Twisty Trampolines, All Alike --- An urgent interrupt arrives from the CPU: it's trapped in a maze of jump instructions, and it would like assistance from any programs with spare cycles to help find the exit. The message includes a list of the offsets for each jump. Jumps are relative: `-1` moves to the previous instruction, and `2` skips the next one. Start at the first instruction in the list. The goal is to follow the jumps until one leads *outside* the list. -Read the [full puzzle](https://adventofcode.com/2017/day/5). \ No newline at end of file +In addition, these instructions are a little strange; after each jump, the offset of that instruction increases by `1`. So, if you come across an offset of `3`, you would move three instructions forward, but change it to a `4` for the next time it is encountered. + +For example, consider the following list of jump offsets: + +``` +0 +3 +0 +1 +-3 +``` + +Positive jumps ("forward") move downward; negative jumps move upward. For legibility in this example, these offset values will be written all on one line, with the current instruction marked in parentheses. The following steps would be taken before an exit is found: + + + - `(0) 3  0  1  -3 ` - *before* we have taken any steps. + - `(1) 3  0  1  -3 ` - jump with offset `0` (that is, don't jump at all). Fortunately, the instruction is then incremented to `1`. + - ` 2 (3) 0  1  -3 ` - step forward because of the instruction we just modified. The first instruction is incremented again, now to `2`. + - ` 2  4  0  1 (-3)` - jump all the way to the end; leave a `4` behind. + - ` 2 (4) 0  1  -2 ` - go back to where we just were; increment `-3` to `-2`. + - ` 2  5  0  1  -2 ` - jump `4` steps forward, escaping the maze. + +In this example, the exit is reached in `5` steps. + +*How many steps* does it take to reach the exit? + + +## --- Part Two --- +Now, the jumps are even stranger: after each jump, if the offset was *three or more*, instead *decrease* it by `1`. Otherwise, increase it by `1` as before. + +Using this rule with the above example, the process now takes `10` steps, and the offset values after finding the exit are left as `2 3 2 3 -1`. + +*How many steps* does it now take to reach the exit? + + diff --git a/2017/Day05/input.in b/2017/Day05/input.in index a6f2d41e0..9a15026f9 100644 Binary files a/2017/Day05/input.in and b/2017/Day05/input.in differ diff --git a/2017/Day06/README.md b/2017/Day06/README.md index a3a4fd7ba..96f8c8808 100644 --- a/2017/Day06/README.md +++ b/2017/Day06/README.md @@ -1,6 +1,33 @@ +original source: [https://adventofcode.com/2017/day/6](https://adventofcode.com/2017/day/6) ## --- Day 6: Memory Reallocation --- A debugger program here is having an issue: it is trying to repair a memory reallocation routine, but it keeps getting stuck in an infinite loop. In this area, there are sixteen memory banks; each memory bank can hold any number of *blocks*. The goal of the reallocation routine is to balance the blocks between the memory banks. -Read the [full puzzle](https://adventofcode.com/2017/day/6). \ No newline at end of file +The reallocation routine operates in cycles. In each cycle, it finds the memory bank with the most blocks (ties won by the lowest-numbered memory bank) and redistributes those blocks among the banks. To do this, it removes all of the blocks from the selected bank, then moves to the next (by index) memory bank and inserts one of the blocks. It continues doing this until it runs out of blocks; if it reaches the last memory bank, it wraps around to the first one. + +The debugger would like to know how many redistributions can be done before a blocks-in-banks configuration is produced that *has been seen before*. + +For example, imagine a scenario with only four memory banks: + + + - The banks start with `0`, `2`, `7`, and `0` blocks. The third bank has the most blocks, so it is chosen for redistribution. + - Starting with the next bank (the fourth bank) and then continuing to the first bank, the second bank, and so on, the `7` blocks are spread out over the memory banks. The fourth, first, and second banks get two blocks each, and the third bank gets one back. The final result looks like this: `2 4 1 2`. + - Next, the second bank is chosen because it contains the most blocks (four). Because there are four memory banks, each gets one block. The result is: `3 1 2 3`. + - Now, there is a tie between the first and fourth memory banks, both of which have three blocks. The first bank wins the tie, and its three blocks are distributed evenly over the other three banks, leaving it with none: `0 2 3 4`. + - The fourth bank is chosen, and its four blocks are distributed such that each of the four banks receives one: `1 3 4 1`. + - The third bank is chosen, and the same thing happens: `2 4 1 2`. + +At this point, we've reached a state we've seen before: `2 4 1 2` was already seen. The infinite loop is detected after the fifth block redistribution cycle, and so the answer in this example is `5`. + +Given the initial block counts in your puzzle input, *how many redistribution cycles* must be completed before a configuration is produced that has been seen before? + + +## --- Part Two --- +Out of curiosity, the debugger would also like to know the size of the loop: starting from a state that has already been seen, how many block redistribution cycles must be performed before that same state is seen again? + +In the example above, `2 4 1 2` is seen again after four cycles, and so the answer in that example would be `4`. + +*How many cycles* are in the infinite loop that arises from the configuration in your puzzle input? + + diff --git a/2017/Day06/input.in b/2017/Day06/input.in index 90d310c5a..517243634 100644 Binary files a/2017/Day06/input.in and b/2017/Day06/input.in differ diff --git a/2017/Day07/README.md b/2017/Day07/README.md index 5d8adfa75..8ea8c8000 100644 --- a/2017/Day07/README.md +++ b/2017/Day07/README.md @@ -1,6 +1,72 @@ +original source: [https://adventofcode.com/2017/day/7](https://adventofcode.com/2017/day/7) ## --- Day 7: Recursive Circus --- Wandering further through the circuits of the computer, you come upon a tower of programs that have gotten themselves into a bit of trouble. A recursive algorithm has gotten out of hand, and now they're balanced precariously in a large tower. One program at the bottom supports the entire tower. It's holding a large disc, and on the disc are balanced several more sub-towers. At the bottom of these sub-towers, standing on the bottom disc, are other programs, each holding *their* own disc, and so on. At the very tops of these sub-sub-sub-...-towers, many programs stand simply keeping the disc below them balanced but with no disc of their own. -Read the [full puzzle](https://adventofcode.com/2017/day/7). \ No newline at end of file +You offer to help, but first you need to understand the structure of these towers. You ask each program to yell out their *name*, their *weight*, and (if they're holding a disc) the *names of the programs immediately above them* balancing on that disc. You write this information down (your puzzle input). Unfortunately, in their panic, they don't do this in an orderly fashion; by the time you're done, you're not sure which program gave which information. + +For example, if your list is the following: + +``` +pbga (66) +xhth (57) +ebii (61) +havc (66) +ktlj (57) +fwft (72) -> ktlj, cntj, xhth +qoyq (66) +padx (45) -> pbga, havc, qoyq +tknk (41) -> ugml, padx, fwft +jptl (61) +ugml (68) -> gyxo, ebii, jptl +gyxo (61) +cntj (57) +``` + +...then you would be able to recreate the structure of the towers that looks like this: + +``` + gyxo + / + ugml - ebii + / \ + | jptl + | + | pbga + / / +tknk --- padx - havc + \ \ + | qoyq + | + | ktlj + \ / + fwft - cntj + \ + xhth +``` + +In this example, `tknk` is at the bottom of the tower (the *bottom program*), and is holding up `ugml`, `padx`, and `fwft`. Those programs are, in turn, holding up other programs; in this example, none of those programs are holding up any other programs, and are all the tops of their own towers. (The actual tower balancing in front of you is much larger.) + +Before you're ready to help them, you need to make sure your information is correct. *What is the name of the bottom program?* + + +## --- Part Two --- +The programs explain the situation: they can't get down. Rather, they *could* get down, if they weren't expending all of their energy trying to keep the tower balanced. Apparently, one program has the *wrong weight*, and until it's fixed, they're stuck here. + +For any program holding a disc, each program standing on that disc forms a sub-tower. Each of those sub-towers are supposed to be the same weight, or the disc itself isn't balanced. The weight of a tower is the sum of the weights of the programs in that tower. + +In the example above, this means that for `ugml`'s disc to be balanced, `gyxo`, `ebii`, and `jptl` must all have the same weight, and they do: `61`. + +However, for `tknk` to be balanced, each of the programs standing on its disc *and all programs above it* must each match. This means that the following sums must all be the same: + + + - `ugml` + (`gyxo` + `ebii` + `jptl`) = 68 + (61 + 61 + 61) = 251 + - `padx` + (`pbga` + `havc` + `qoyq`) = 45 + (66 + 66 + 66) = 243 + - `fwft` + (`ktlj` + `cntj` + `xhth`) = 72 + (57 + 57 + 57) = 243 + +As you can see, `tknk`'s disc is unbalanced: `ugml`'s stack is heavier than the other two. Even though the nodes above `ugml` are balanced, `ugml` itself is too heavy: it needs to be `8` units lighter for its stack to weigh `243` and keep the towers balanced. If this change were made, its weight would be `60`. + +Given that exactly one program is the wrong weight, *what would its weight need to be* to balance the entire tower? + + diff --git a/2017/Day07/input.in b/2017/Day07/input.in index 0f1f687ea..b74e00e71 100644 Binary files a/2017/Day07/input.in and b/2017/Day07/input.in differ diff --git a/2017/Day08/README.md b/2017/Day08/README.md index b8a09384d..0873dd695 100644 --- a/2017/Day08/README.md +++ b/2017/Day08/README.md @@ -1,6 +1,32 @@ +original source: [https://adventofcode.com/2017/day/8](https://adventofcode.com/2017/day/8) ## --- Day 8: I Heard You Like Registers --- You receive a signal directly from the CPU. Because of your recent assistance with [jump instructions](5), it would like you to compute the result of a series of unusual register instructions. Each instruction consists of several parts: the register to modify, whether to increase or decrease that register's value, the amount by which to increase or decrease it, and a condition. If the condition fails, skip the instruction without modifying the register. The registers all start at `0`. The instructions look like this: -Read the [full puzzle](https://adventofcode.com/2017/day/8). \ No newline at end of file +``` +b inc 5 if a > 1 +a inc 1 if b < 5 +c dec -10 if a >= 1 +c inc -20 if c == 10 +``` + +These instructions would be processed as follows: + + + - Because `a` starts at `0`, it is not greater than `1`, and so `b` is not modified. + - `a` is increased by `1` (to `1`) because `b` is less than `5` (it is `0`). + - `c` is decreased by `-10` (to `10`) because `a` is now greater than or equal to `1` (it is `1`). + - `c` is increased by `-20` (to `-10`) because `c` is equal to `10`. + +After this process, the largest value in any register is `1`. + +You might also encounter `<=` (less than or equal to) or `!=` (not equal to). However, the CPU doesn't have the bandwidth to tell you what all the registers are named, and leaves that to you to determine. + +*What is the largest value in any register* after completing the instructions in your puzzle input? + + +## --- Part Two --- +To be safe, the CPU also needs to know *the highest value held in any register during this process* so that it can decide how much memory to allocate to these operations. For example, in the above instructions, the highest value ever held was `10` (in register `c` after the third instruction was evaluated). + + diff --git a/2017/Day08/input.in b/2017/Day08/input.in index 94afcf93d..6f2de6441 100644 Binary files a/2017/Day08/input.in and b/2017/Day08/input.in differ diff --git a/2017/Day09/README.md b/2017/Day09/README.md index 03e6ad6b8..585c7addd 100644 --- a/2017/Day09/README.md +++ b/2017/Day09/README.md @@ -1,6 +1,67 @@ +original source: [https://adventofcode.com/2017/day/9](https://adventofcode.com/2017/day/9) ## --- Day 9: Stream Processing --- A large stream blocks your path. According to the locals, it's not safe to cross the stream at the moment because it's full of *garbage*. You look down at the stream; rather than water, you discover that it's a *stream of characters*. You sit for a while and record part of the stream (your puzzle input). The characters represent *groups* - sequences that begin with `{` and end with `}`. Within a group, there are zero or more other things, separated by commas: either another *group* or *garbage*. Since groups can contain other groups, a `}` only closes the *most-recently-opened unclosed group* - that is, they are nestable. Your puzzle input represents a single, large group which itself contains many smaller ones. -Read the [full puzzle](https://adventofcode.com/2017/day/9). \ No newline at end of file +Sometimes, instead of a group, you will find *garbage*. Garbage begins with `<` and ends with `>`. Between those angle brackets, almost any character can appear, including `{` and `}`. *Within* garbage, `<` has no special meaning. + +In a futile attempt to clean up the garbage, some program has *canceled* some of the characters within it using `!`: inside garbage, *any* character that comes after `!` should be *ignored*, including `<`, `>`, and even another `!`. + +You don't see any characters that deviate from these rules. Outside garbage, you only find well-formed groups, and garbage always terminates according to the rules above. + +Here are some self-contained pieces of garbage: + + + - `<>`, empty garbage. + - ``, garbage containing random characters. + - `<<<<>`, because the extra `<` are ignored. + - `<{!>}>`, because the first `>` is canceled. + - ``, because the second `!` is canceled, allowing the `>` to terminate the garbage. + - `>`, because the second `!` and the first `>` are canceled. + - `<{o"i!a,<{i`, which ends at the first `>`. + +Here are some examples of whole streams and the number of groups they contain: + + + - `{}`, `1` group. + - `{{{}}}`, `3` groups. + - `{{},{}}`, also `3` groups. + - `{{{},{},{{}}}}`, `6` groups. + - `{<{},{},{{}}>}`, `1` group (which itself contains garbage). + - `{,,,}`, `1` group. + - `{{},{},{},{}}`, `5` groups. + - `{{},{},{},{}}`, `2` groups (since all but the last `>` are canceled). + +Your goal is to find the total score for all groups in your input. Each group is assigned a *score* which is one more than the score of the group that immediately contains it. (The outermost group gets a score of `1`.) + + + - `{}`, score of `1`. + - `{{{}}}`, score of `1 + 2 + 3 = 6`. + - `{{},{}}`, score of `1 + 2 + 2 = 5`. + - `{{{},{},{{}}}}`, score of `1 + 2 + 3 + 3 + 3 + 4 = 16`. + - `{,,,}`, score of `1`. + - `{{},{},{},{}}`, score of `1 + 2 + 2 + 2 + 2 = 9`. + - `{{},{},{},{}}`, score of `1 + 2 + 2 + 2 + 2 = 9`. + - `{{},{},{},{}}`, score of `1 + 2 = 3`. + +*What is the total score* for all groups in your input? + + +## --- Part Two --- +Now, you're ready to remove the garbage. + +To prove you've removed it, you need to count all of the characters within the garbage. The leading and trailing `<` and `>` don't count, nor do any canceled characters or the `!` doing the canceling. + + + - `<>`, `0` characters. + - ``, `17` characters. + - `<<<<>`, `3` characters. + - `<{!>}>`, `2` characters. + - ``, `0` characters. + - `>`, `0` characters. + - `<{o"i!a,<{i`, `10` characters. + +*How many non-canceled characters are within the garbage* in your puzzle input? + + diff --git a/2017/Day09/input.in b/2017/Day09/input.in index 2de7e7361..2e84e1b3d 100644 Binary files a/2017/Day09/input.in and b/2017/Day09/input.in differ diff --git a/2017/Day10/README.md b/2017/Day10/README.md index 525202279..a2ff9a964 100644 --- a/2017/Day10/README.md +++ b/2017/Day10/README.md @@ -1,6 +1,83 @@ +original source: [https://adventofcode.com/2017/day/10](https://adventofcode.com/2017/day/10) ## --- Day 10: Knot Hash --- You come across some programs that are trying to implement a software emulation of a hash based on knot-tying. The hash these programs are implementing isn't very strong, but you decide to help them anyway. You make a mental note to remind the Elves later not to invent their own cryptographic functions. This hash function simulates tying a knot in a circle of string with 256 marks on it. Based on the input to be hashed, the function repeatedly selects a span of string, brings the ends together, and gives the span a half-twist to reverse the order of the marks within it. After doing this many times, the order of the marks is used to build the resulting hash. -Read the [full puzzle](https://adventofcode.com/2017/day/10). \ No newline at end of file +``` + 4--5 pinch 4 5 4 1 + / \ 5,0,1 / \/ \ twist / \ / \ +3 0 --> 3 0 --> 3 X 0 + \ / \ /\ / \ / \ / + 2--1 2 1 2 5 +``` + +To achieve this, begin with a *list* of numbers from `0` to `255`, a *current position* which begins at `0` (the first element in the list), a *skip size* (which starts at `0`), and a sequence of *lengths* (your puzzle input). Then, for each length: + + + - *Reverse* the order of that *length* of elements in the *list*, starting with the element at the *current position*. + - *Move* the *current position* forward by that *length* plus the *skip size*. + - *Increase* the *skip size* by one. + +The *list* is circular; if the *current position* and the *length* try to reverse elements beyond the end of the list, the operation reverses using as many extra elements as it needs from the front of the list. If the *current position* moves past the end of the list, it wraps around to the front. *Lengths* larger than the size of the *list* are invalid. + +Here's an example using a smaller list: + +Suppose we instead only had a circular list containing five elements, `0, 1, 2, 3, 4`, and were given input lengths of `3, 4, 1, 5`. + + + - The list begins as `[0] 1 2 3 4` (where square brackets indicate the *current position*). + - The first length, `3`, selects `([0] 1 2) 3 4` (where parentheses indicate the sublist to be reversed). + - After reversing that section (`0 1 2` into `2 1 0`), we get `([2] 1 0) 3 4`. + - Then, the *current position* moves forward by the *length*, `3`, plus the *skip size*, 0: `2 1 0 [3] 4`. Finally, the *skip size* increases to `1`. + + + - The second length, `4`, selects a section which wraps: `2 1) 0 ([3] 4`. + - The sublist `3 4 2 1` is reversed to form `1 2 4 3`: `4 3) 0 ([1] 2`. + - The *current position* moves forward by the *length* plus the *skip size*, a total of `5`, causing it not to move because it wraps around: `4 3 0 [1] 2`. The *skip size* increases to `2`. + + + - The third length, `1`, selects a sublist of a single element, and so reversing it has no effect. + - The *current position* moves forward by the *length* (`1`) plus the *skip size* (`2`): `4 [3] 0 1 2`. The *skip size* increases to `3`. + + + - The fourth length, `5`, selects every element starting with the second: `4) ([3] 0 1 2`. Reversing this sublist (`3 0 1 2 4` into `4 2 1 0 3`) produces: `3) ([4] 2 1 0`. + - Finally, the *current position* moves forward by `8`: `3 4 2 1 [0]`. The *skip size* increases to `4`. + +In this example, the first two numbers in the list end up being `3` and `4`; to check the process, you can multiply them together to produce `12`. + +However, you should instead use the standard list size of `256` (with values `0` to `255`) and the sequence of *lengths* in your puzzle input. Once this process is complete, *what is the result of multiplying the first two numbers in the list*? + + +## --- Part Two --- +The logic you've constructed forms a single *round* of the *Knot Hash* algorithm; running the full thing requires many of these rounds. Some input and output processing is also required. + +First, from now on, your input should be taken not as a list of numbers, but as a string of bytes instead. Unless otherwise specified, convert characters to bytes using their [ASCII codes](https://en.wikipedia.org/wiki/ASCII#Printable_characters). This will allow you to handle arbitrary ASCII strings, and it also ensures that your input lengths are never larger than `255`. For example, if you are given `1,2,3`, you should convert it to the ASCII codes for each character: `49,44,50,44,51`. + +Once you have determined the sequence of lengths to use, add the following lengths to the end of the sequence: `17, 31, 73, 47, 23`. For example, if you are given `1,2,3`, your final sequence of lengths should be `49,44,50,44,51,17,31,73,47,23` (the ASCII codes from the input string combined with the standard length suffix values). + +Second, instead of merely running one *round* like you did above, run a total of `64` rounds, using the same *length* sequence in each round. The *current position* and *skip size* should be preserved between rounds. For example, if the previous example was your first round, you would start your second round with the same *length* sequence (`3, 4, 1, 5, 17, 31, 73, 47, 23`, now assuming they came from ASCII codes and include the suffix), but start with the previous round's *current position* (`4`) and *skip size* (`4`). + +Once the rounds are complete, you will be left with the numbers from `0` to `255` in some order, called the *sparse hash*. Your next task is to reduce these to a list of only `16` numbers called the *dense hash*. To do this, use numeric bitwise [XOR](https://en.wikipedia.org/wiki/Bitwise_operation#XOR) to combine each consecutive block of `16` numbers in the sparse hash (there are `16` such blocks in a list of `256` numbers). So, the first element in the dense hash is the first sixteen elements of the sparse hash XOR'd together, the second element in the dense hash is the second sixteen elements of the sparse hash XOR'd together, etc. + +For example, if the first sixteen elements of your sparse hash are as shown below, and the XOR operator is `^`, you would calculate the first output number like this: + +``` +65 ^ 27 ^ 9 ^ 1 ^ 4 ^ 3 ^ 40 ^ 50 ^ 91 ^ 7 ^ 6 ^ 0 ^ 2 ^ 5 ^ 68 ^ 22 = 64 +``` + +Perform this operation on each of the sixteen blocks of sixteen numbers in your sparse hash to determine the sixteen numbers in your dense hash. + +Finally, the standard way to represent a Knot Hash is as a single [hexadecimal](https://en.wikipedia.org/wiki/Hexadecimal) string; the final output is the dense hash in hexadecimal notation. Because each number in your dense hash will be between `0` and `255` (inclusive), always represent each number as two hexadecimal digits (including a leading zero as necessary). So, if your first three numbers are `64, 7, 255`, they correspond to the hexadecimal numbers `40, 07, ff`, and so the first six characters of the hash would be `4007ff`. Because every Knot Hash is sixteen such numbers, the hexadecimal representation is always `32` hexadecimal digits (`0`-`f`) long. +Here are some example hashes: + + + - The empty string becomes `a2582a3a0e66e6e86e3812dcb672a272`. + - `AoC 2017` becomes `33efeb34ea91902bb2f59c9920caa6cd`. + - `1,2,3` becomes `3efbe78a8d82f29979031a4aa0b16a9d`. + - `1,2,4` becomes `63960835bcdc130f0b66d7ff4f6a5a8e`. + +Treating your puzzle input as a string of ASCII characters, *what is the Knot Hash of your puzzle input?* Ignore any leading or trailing whitespace you might encounter. + + + diff --git a/2017/Day10/input.in b/2017/Day10/input.in index 960b72aab..8493759d3 100644 Binary files a/2017/Day10/input.in and b/2017/Day10/input.in differ diff --git a/2017/Day11/README.md b/2017/Day11/README.md index 5e1c4b600..43681250f 100644 --- a/2017/Day11/README.md +++ b/2017/Day11/README.md @@ -1,6 +1,35 @@ +original source: [https://adventofcode.com/2017/day/11](https://adventofcode.com/2017/day/11) ## --- Day 11: Hex Ed --- Crossing the bridge, you've barely reached the other side of the stream when a program comes up to you, clearly in distress. "It's my child process," she says, "he's gotten lost in an infinite grid!" Fortunately for her, you have plenty of experience with infinite grids. -Read the [full puzzle](https://adventofcode.com/2017/day/11). \ No newline at end of file +Unfortunately for you, it's a [hex grid](https://en.wikipedia.org/wiki/Hexagonal_tiling). + +The hexagons ("hexes") in this grid are aligned such that adjacent hexes can be found to the north, northeast, southeast, south, southwest, and northwest: + +``` + \ n / +nw +--+ ne + / \ +-+ +- + \ / +sw +--+ se + / s \ +``` + +You have the path the child process took. Starting where he started, you need to determine the fewest number of steps required to reach him. (A "step" means to move from the hex you are in to any adjacent hex.) + +For example: + + + - `ne,ne,ne` is `3` steps away. + - `ne,ne,sw,sw` is `0` steps away (back where you started). + - `ne,ne,s,s` is `2` steps away (`se,se`). + - `se,sw,se,sw,sw` is `3` steps away (`s,s,sw`). + + +## --- Part Two --- +*How many steps away* is the *furthest* he ever got from his starting position? + + diff --git a/2017/Day11/input.in b/2017/Day11/input.in index b630af35f..33bba05b8 100644 Binary files a/2017/Day11/input.in and b/2017/Day11/input.in differ diff --git a/2017/Day12/README.md b/2017/Day12/README.md index ac03ac73b..797022158 100644 --- a/2017/Day12/README.md +++ b/2017/Day12/README.md @@ -1,6 +1,49 @@ +original source: [https://adventofcode.com/2017/day/12](https://adventofcode.com/2017/day/12) ## --- Day 12: Digital Plumber --- Walking along the memory banks of the stream, you find a small village that is experiencing a little confusion: some programs can't communicate with each other. Programs in this village communicate using a fixed system of *pipes*. Messages are passed between programs using these pipes, but most programs aren't connected to each other directly. Instead, programs pass messages between each other until the message reaches the intended recipient. -Read the [full puzzle](https://adventofcode.com/2017/day/12). \ No newline at end of file +For some reason, though, some of these messages aren't ever reaching their intended recipient, and the programs suspect that some pipes are missing. They would like you to investigate. + +You walk through the village and record the ID of each program and the IDs with which it can communicate directly (your puzzle input). Each program has one or more programs with which it can communicate, and these pipes are bidirectional; if `8` says it can communicate with `11`, then `11` will say it can communicate with `8`. + +You need to figure out how many programs are in the group that contains program ID `0`. + +For example, suppose you go door-to-door like a travelling salesman and record the following list: + +``` +0 <-> 2 +1 <-> 1 +2 <-> 0, 3, 4 +3 <-> 2, 4 +4 <-> 2, 3, 6 +5 <-> 6 +6 <-> 4, 5 +``` + +In this example, the following programs are in the group that contains program ID `0`: + + + - Program `0` by definition. + - Program `2`, directly connected to program `0`. + - Program `3` via program `2`. + - Program `4` via program `2`. + - Program `5` via programs `6`, then `4`, then `2`. + - Program `6` via programs `4`, then `2`. + +Therefore, a total of `6` programs are in this group; all but program `1`, which has a pipe that connects it to itself. + +*How many programs* are in the group that contains program ID `0`? + + +## --- Part Two --- +There are more programs than just the ones in the group containing program ID `0`. The rest of them have no way of reaching that group, and still might have no way of reaching each other. + +A *group* is a collection of programs that can all communicate via pipes either directly or indirectly. The programs you identified just a moment ago are all part of the same group. Now, they would like you to determine the total number of groups. + +In the example above, there were `2` groups: one consisting of programs `0,2,3,4,5,6`, and the other consisting solely of program `1`. + +*How many groups are there* in total? + + diff --git a/2017/Day12/input.in b/2017/Day12/input.in index 0e252b630..cf5f503fb 100644 Binary files a/2017/Day12/input.in and b/2017/Day12/input.in differ diff --git a/2017/Day13/README.md b/2017/Day13/README.md index f3f247c6d..393d377ae 100644 --- a/2017/Day13/README.md +++ b/2017/Day13/README.md @@ -1,6 +1,291 @@ +original source: [https://adventofcode.com/2017/day/13](https://adventofcode.com/2017/day/13) ## --- Day 13: Packet Scanners --- You need to cross a vast *firewall*. The firewall consists of several layers, each with a *security scanner* that moves back and forth across the layer. To succeed, you must not be detected by a scanner. By studying the firewall briefly, you are able to record (in your puzzle input) the *depth* of each layer and the *range* of the scanning area for the scanner within it, written as `depth: range`. Each layer has a thickness of exactly `1`. A layer at depth `0` begins immediately inside the firewall; a layer at depth `1` would start immediately after that. -Read the [full puzzle](https://adventofcode.com/2017/day/13). \ No newline at end of file +For example, suppose you've recorded the following: + +``` +0: 3 +1: 2 +4: 4 +6: 4 +``` + +This means that there is a layer immediately inside the firewall (with range `3`), a second layer immediately after that (with range `2`), a third layer which begins at depth `4` (with range `4`), and a fourth layer which begins at depth 6 (also with range `4`). Visually, it might look like this: + +``` + 0 1 2 3 4 5 6 +[ ] [ ] ... ... [ ] ... [ ] +[ ] [ ] [ ] [ ] +[ ] [ ] [ ] + [ ] [ ] +``` + +Within each layer, a security scanner moves back and forth within its range. Each security scanner starts at the top and moves down until it reaches the bottom, then moves up until it reaches the top, and repeats. A security scanner takes *one picosecond* to move one step. Drawing scanners as `S`, the first few picoseconds look like this: + +``` + +Picosecond 0: + 0 1 2 3 4 5 6 +[S] [S] ... ... [S] ... [S] +[ ] [ ] [ ] [ ] +[ ] [ ] [ ] + [ ] [ ] + +Picosecond 1: + 0 1 2 3 4 5 6 +[ ] [ ] ... ... [ ] ... [ ] +[S] [S] [S] [S] +[ ] [ ] [ ] + [ ] [ ] + +Picosecond 2: + 0 1 2 3 4 5 6 +[ ] [S] ... ... [ ] ... [ ] +[ ] [ ] [ ] [ ] +[S] [S] [S] + [ ] [ ] + +Picosecond 3: + 0 1 2 3 4 5 6 +[ ] [ ] ... ... [ ] ... [ ] +[S] [S] [ ] [ ] +[ ] [ ] [ ] + [S] [S] +``` + +Your plan is to hitch a ride on a packet about to move through the firewall. The packet will travel along the top of each layer, and it moves at *one layer per picosecond*. Each picosecond, the packet moves one layer forward (its first move takes it into layer 0), and then the scanners move one step. If there is a scanner at the top of the layer *as your packet enters it*, you are *caught*. (If a scanner moves into the top of its layer while you are there, you are *not* caught: it doesn't have time to notice you before you leave.) If you were to do this in the configuration above, marking your current position with parentheses, your passage through the firewall would look like this: + +``` +Initial state: + 0 1 2 3 4 5 6 +[S] [S] ... ... [S] ... [S] +[ ] [ ] [ ] [ ] +[ ] [ ] [ ] + [ ] [ ] + +Picosecond 0: + 0 1 2 3 4 5 6 +(S) [S] ... ... [S] ... [S] +[ ] [ ] [ ] [ ] +[ ] [ ] [ ] + [ ] [ ] + + 0 1 2 3 4 5 6 +( ) [ ] ... ... [ ] ... [ ] +[S] [S] [S] [S] +[ ] [ ] [ ] + [ ] [ ] + + +Picosecond 1: + 0 1 2 3 4 5 6 +[ ] ( ) ... ... [ ] ... [ ] +[S] [S] [S] [S] +[ ] [ ] [ ] + [ ] [ ] + + 0 1 2 3 4 5 6 +[ ] (S) ... ... [ ] ... [ ] +[ ] [ ] [ ] [ ] +[S] [S] [S] + [ ] [ ] + + +Picosecond 2: + 0 1 2 3 4 5 6 +[ ] [S] (.) ... [ ] ... [ ] +[ ] [ ] [ ] [ ] +[S] [S] [S] + [ ] [ ] + + 0 1 2 3 4 5 6 +[ ] [ ] (.) ... [ ] ... [ ] +[S] [S] [ ] [ ] +[ ] [ ] [ ] + [S] [S] + + +Picosecond 3: + 0 1 2 3 4 5 6 +[ ] [ ] ... (.) [ ] ... [ ] +[S] [S] [ ] [ ] +[ ] [ ] [ ] + [S] [S] + + 0 1 2 3 4 5 6 +[S] [S] ... (.) [ ] ... [ ] +[ ] [ ] [ ] [ ] +[ ] [S] [S] + [ ] [ ] + + +Picosecond 4: + 0 1 2 3 4 5 6 +[S] [S] ... ... ( ) ... [ ] +[ ] [ ] [ ] [ ] +[ ] [S] [S] + [ ] [ ] + + 0 1 2 3 4 5 6 +[ ] [ ] ... ... ( ) ... [ ] +[S] [S] [S] [S] +[ ] [ ] [ ] + [ ] [ ] + + +Picosecond 5: + 0 1 2 3 4 5 6 +[ ] [ ] ... ... [ ] (.) [ ] +[S] [S] [S] [S] +[ ] [ ] [ ] + [ ] [ ] + + 0 1 2 3 4 5 6 +[ ] [S] ... ... [S] (.) [S] +[ ] [ ] [ ] [ ] +[S] [ ] [ ] + [ ] [ ] + + +Picosecond 6: + 0 1 2 3 4 5 6 +[ ] [S] ... ... [S] ... (S) +[ ] [ ] [ ] [ ] +[S] [ ] [ ] + [ ] [ ] + + 0 1 2 3 4 5 6 +[ ] [ ] ... ... [ ] ... ( ) +[S] [S] [S] [S] +[ ] [ ] [ ] + [ ] [ ] +``` + +In this situation, you are *caught* in layers `0` and `6`, because your packet entered the layer when its scanner was at the top when you entered it. You are *not* caught in layer `1`, since the scanner moved into the top of the layer once you were already there. + +The *severity* of getting caught on a layer is equal to its *depth* multiplied by its *range*. (Ignore layers in which you do not get caught.) The severity of the whole trip is the sum of these values. In the example above, the trip severity is `0*3 + 6*4 = *24*`. + +Given the details of the firewall you've recorded, if you leave immediately, *what is the severity of your whole trip*? + + +## --- Part Two --- +Now, you need to pass through the firewall without being caught - easier said than done. + +You can't control the speed of the packet, but you can *delay* it any number of picoseconds. For each picosecond you delay the packet before beginning your trip, all security scanners move one step. You're not in the firewall during this time; you don't enter layer `0` until you stop delaying the packet. + +In the example above, if you delay `10` picoseconds (picoseconds `0` - `9`), you won't get caught: + +``` +State after delaying: + 0 1 2 3 4 5 6 +[ ] [S] ... ... [ ] ... [ ] +[ ] [ ] [ ] [ ] +[S] [S] [S] + [ ] [ ] + +Picosecond 10: + 0 1 2 3 4 5 6 +( ) [S] ... ... [ ] ... [ ] +[ ] [ ] [ ] [ ] +[S] [S] [S] + [ ] [ ] + + 0 1 2 3 4 5 6 +( ) [ ] ... ... [ ] ... [ ] +[S] [S] [S] [S] +[ ] [ ] [ ] + [ ] [ ] + + +Picosecond 11: + 0 1 2 3 4 5 6 +[ ] ( ) ... ... [ ] ... [ ] +[S] [S] [S] [S] +[ ] [ ] [ ] + [ ] [ ] + + 0 1 2 3 4 5 6 +[S] (S) ... ... [S] ... [S] +[ ] [ ] [ ] [ ] +[ ] [ ] [ ] + [ ] [ ] + + +Picosecond 12: + 0 1 2 3 4 5 6 +[S] [S] (.) ... [S] ... [S] +[ ] [ ] [ ] [ ] +[ ] [ ] [ ] + [ ] [ ] + + 0 1 2 3 4 5 6 +[ ] [ ] (.) ... [ ] ... [ ] +[S] [S] [S] [S] +[ ] [ ] [ ] + [ ] [ ] + + +Picosecond 13: + 0 1 2 3 4 5 6 +[ ] [ ] ... (.) [ ] ... [ ] +[S] [S] [S] [S] +[ ] [ ] [ ] + [ ] [ ] + + 0 1 2 3 4 5 6 +[ ] [S] ... (.) [ ] ... [ ] +[ ] [ ] [ ] [ ] +[S] [S] [S] + [ ] [ ] + + +Picosecond 14: + 0 1 2 3 4 5 6 +[ ] [S] ... ... ( ) ... [ ] +[ ] [ ] [ ] [ ] +[S] [S] [S] + [ ] [ ] + + 0 1 2 3 4 5 6 +[ ] [ ] ... ... ( ) ... [ ] +[S] [S] [ ] [ ] +[ ] [ ] [ ] + [S] [S] + + +Picosecond 15: + 0 1 2 3 4 5 6 +[ ] [ ] ... ... [ ] (.) [ ] +[S] [S] [ ] [ ] +[ ] [ ] [ ] + [S] [S] + + 0 1 2 3 4 5 6 +[S] [S] ... ... [ ] (.) [ ] +[ ] [ ] [ ] [ ] +[ ] [S] [S] + [ ] [ ] + + +Picosecond 16: + 0 1 2 3 4 5 6 +[S] [S] ... ... [ ] ... ( ) +[ ] [ ] [ ] [ ] +[ ] [S] [S] + [ ] [ ] + + 0 1 2 3 4 5 6 +[ ] [ ] ... ... [ ] ... ( ) +[S] [S] [S] [S] +[ ] [ ] [ ] + [ ] [ ] +``` + +Because all smaller delays would get you caught, the fewest number of picoseconds you would need to delay to get through safely is `10`. + +*What is the fewest number of picoseconds* that you need to delay the packet to pass through the firewall without being caught? + + diff --git a/2017/Day13/input.in b/2017/Day13/input.in index 04007867a..6e11fd677 100644 Binary files a/2017/Day13/input.in and b/2017/Day13/input.in differ diff --git a/2017/Day14/README.md b/2017/Day14/README.md index e57cab07d..279842ef7 100644 --- a/2017/Day14/README.md +++ b/2017/Day14/README.md @@ -1,6 +1,55 @@ +original source: [https://adventofcode.com/2017/day/14](https://adventofcode.com/2017/day/14) ## --- Day 14: Disk Defragmentation --- Suddenly, a scheduled job activates the system's [disk defragmenter](https://en.wikipedia.org/wiki/Defragmentation). Were the situation different, you might [sit and watch it for a while](https://www.youtube.com/watch?v=kPv1gQ5Rs8A&t=37), but today, you just don't have that kind of time. It's soaking up valuable system resources that are needed elsewhere, and so the only option is to help it finish its task as soon as possible. The disk in question consists of a 128x128 grid; each square of the grid is either *free* or *used*. On this disk, the state of the grid is tracked by the bits in a sequence of [knot hashes](10). -Read the [full puzzle](https://adventofcode.com/2017/day/14). \ No newline at end of file +A total of 128 knot hashes are calculated, each corresponding to a single row in the grid; each hash contains 128 bits which correspond to individual grid squares. Each bit of a hash indicates whether that square is *free* (`0`) or *used* (`1`). + +The hash inputs are a key string (your puzzle input), a dash, and a number from `0` to `127` corresponding to the row. For example, if your key string were `flqrgnkx`, then the first row would be given by the bits of the knot hash of `flqrgnkx-0`, the second row from the bits of the knot hash of `flqrgnkx-1`, and so on until the last row, `flqrgnkx-127`. + +The output of a knot hash is traditionally represented by 32 hexadecimal digits; each of these digits correspond to 4 bits, for a total of `4 * 32 = 128` bits. To convert to bits, turn each hexadecimal digit to its equivalent binary value, high-bit first: `0` becomes `0000`, `1` becomes `0001`, `e` becomes `1110`, `f` becomes `1111`, and so on; a hash that begins with `a0c2017...` in hexadecimal would begin with `10100000110000100000000101110000...` in binary. + +Continuing this process, the *first 8 rows and columns* for key `flqrgnkx` appear as follows, using `#` to denote used squares, and `.` to denote free ones: + +``` +##.#.#..--> +.#.#.#.# +....#.#. +#.#.##.# +.##.#... +##..#..# +.#...#.. +##.#.##.--> +| | +V V +``` + +In this example, `8108` squares are used across the entire 128x128 grid. + +Given your actual key string, *how many squares are used*? + + +## --- Part Two --- +Now, all the defragmenter needs to know is the number of *regions*. A region is a group of *used* squares that are all *adjacent*, not including diagonals. Every used square is in exactly one region: lone used squares form their own isolated regions, while several adjacent squares all count as a single region. + +In the example above, the following nine regions are visible, each marked with a distinct digit: + +``` +11.2.3..--> +.1.2.3.4 +....5.6. +7.8.55.9 +.88.5... +88..5..8 +.8...8.. +88.8.88.--> +| | +V V +``` + +Of particular interest is the region marked `8`; while it does not appear contiguous in this small view, all of the squares marked `8` are connected when considering the whole 128x128 grid. In total, in this example, `1242` regions are present. + +*How many regions* are present given your key string? + + diff --git a/2017/Day14/input.in b/2017/Day14/input.in index eb4843fa4..81b6a1082 100644 Binary files a/2017/Day14/input.in and b/2017/Day14/input.in differ diff --git a/2017/Day15/README.md b/2017/Day15/README.md index caa4832bf..986c27b6d 100644 --- a/2017/Day15/README.md +++ b/2017/Day15/README.md @@ -1,6 +1,110 @@ +original source: [https://adventofcode.com/2017/day/15](https://adventofcode.com/2017/day/15) ## --- Day 15: Dueling Generators --- Here, you encounter a pair of dueling generators. The generators, called generator A and generator B, are trying to agree on a sequence of numbers. However, one of them is malfunctioning, and so the sequences don't always match. As they do this, a judge waits for each of them to generate its next value, compares the lowest 16 bits of both values, and keeps track of the number of times those parts of the values match. -Read the [full puzzle](https://adventofcode.com/2017/day/15). \ No newline at end of file +The generators both work on the same principle. To create its next value, a generator will take the previous value it produced, multiply it by a factor (generator A uses 16807; generator B uses 48271), and then keep the remainder of dividing that resulting product by 2147483647. That final remainder is the value it produces next. + +To calculate each generator's first value, it instead uses a specific starting value as its "previous value" (as listed in your puzzle input). + +For example, suppose that for starting values, generator A uses 65, while generator B uses 8921. Then, the first five pairs of generated values are: + +
+--Gen. A--  --Gen. B--
+   1092455   430625591
+1181022009  1233683848
+ 245556042  1431495498
+1744312007   137874439
+1352636452   285222916
+
+
+ +In binary, these pairs are (with generator A's value first in each pair): + +
+00000000000100001010101101100111
+00011001101010101101001100110111
+
+01000110011001001111011100111001
+01001001100010001000010110001000
+
+00001110101000101110001101001010
+01010101010100101110001101001010
+
+01100111111110000001011011000111
+00001000001101111100110000000111
+
+01010000100111111001100000100100
+00010001000000000010100000000100
+
+
+ +Here, you can see that the lowest (here, rightmost) 16 bits of the third value match: 1110001101001010. Because of this one match, after processing these five pairs, the judge would have added only 1 to its total. + +To get a significant sample, the judge would like to consider 40 million pairs. (In the example above, the judge would eventually find a total of 588 pairs that match in their lowest 16 bits.) + +After 40 million pairs, what is the judge's final count? + + +## --- Part Two --- +In the interest of trying to align a little better, the generators get more picky about the numbers they actually give to the judge. + +They still generate values in the same way, but now they only hand a value to the judge when it meets their criteria: + + + - Generator A looks for values that are multiples of 4. + - Generator B looks for values that are multiples of 8. + +Each generator functions completely independently: they both go through values entirely on their own, only occasionally handing an acceptable value to the judge, and otherwise working through the same sequence of values as before until they find one. + +The judge still waits for each generator to provide it with a value before comparing them (using the same comparison method as before). It keeps track of the order it receives values; the first values from each generator are compared, then the second values from each generator, then the third values, and so on. + +Using the example starting values given above, the generators now produce the following first five values each: + +
+--Gen. A--  --Gen. B--
+1352636452  1233683848
+1992081072   862516352
+ 530830436  1159784568
+1980017072  1616057672
+ 740335192   412269392
+
+
+ +These values have the following corresponding binary values: + +
+01010000100111111001100000100100
+01001001100010001000010110001000
+
+01110110101111001011111010110000
+00110011011010001111010010000000
+
+00011111101000111101010001100100
+01000101001000001110100001111000
+
+01110110000001001010100110110000
+01100000010100110001010101001000
+
+00101100001000001001111001011000
+00011000100100101011101101010000
+
+
+ +Unfortunately, even though this change makes more bits similar on average, none of these values' lowest 16 bits match. Now, it's not until the 1056th pair that the judge finds the first match: + +
+--Gen. A--  --Gen. B--
+1023762912   896885216
+
+00111101000001010110000111100000
+00110101011101010110000111100000
+
+
+ +This change makes the generators much slower, and the judge is getting impatient; it is now only willing to consider 5 million pairs. (Using the values from the example above, after five million pairs, the judge would eventually find a total of 309 pairs that match in their lowest 16 bits.) + +After 5 million pairs, but using this new generator logic, what is the judge's final count? + + diff --git a/2017/Day15/input.in b/2017/Day15/input.in index a5e775638..99a802901 100644 Binary files a/2017/Day15/input.in and b/2017/Day15/input.in differ diff --git a/2017/Day16/README.md b/2017/Day16/README.md index 5fea82b4c..ca7b84edb 100644 --- a/2017/Day16/README.md +++ b/2017/Day16/README.md @@ -1,6 +1,41 @@ +original source: [https://adventofcode.com/2017/day/16](https://adventofcode.com/2017/day/16) ## --- Day 16: Permutation Promenade --- You come upon a very unusual sight; a group of programs here appear to be [dancing](https://www.youtube.com/watch?v=lyZQPjUT5B4&t=53). There are sixteen programs in total, named `a` through `p`. They start by standing in a line: `a` stands in position `0`, `b` stands in position `1`, and so on until `p`, which stands in position `15`. -Read the [full puzzle](https://adventofcode.com/2017/day/16). \ No newline at end of file +The programs' *dance* consists of a sequence of *dance moves*: + + + - *Spin*, written `sX`, makes `X` programs move from the end to the front, but maintain their order otherwise. (For example, `s3` on `abcde` produces `cdeab`). + - *Exchange*, written `xA/B`, makes the programs at positions `A` and `B` swap places. + - *Partner*, written `pA/B`, makes the programs named `A` and `B` swap places. + +For example, with only five programs standing in a line (`abcde`), they could do the following dance: + + + - `s1`, a spin of size `1`: `eabcd`. + - `x3/4`, swapping the last two programs: `eabdc`. + - `pe/b`, swapping programs `e` and `b`: `baedc`. + +After finishing their dance, the programs end up in order `baedc`. +You watch the dance for a while and record their dance moves (your puzzle input). *In what order are the programs standing* after their dance? + + + + +## --- Part Two --- +Now that you're starting to get a feel for the dance moves, you turn your attention to *the dance as a whole*. + +Keeping the positions they ended up in from their previous dance, the programs perform it again and again: including the first dance, a total of *one billion* (`1000000000`) times. + +In the example above, their second dance would *begin* with the order `baedc`, and use the same dance moves: + + + - `s1`, a spin of size `1`: `cbaed`. + - `x3/4`, swapping the last two programs: `cbade`. + - `pe/b`, swapping programs `e` and `b`: `ceadb`. + +*In what order are the programs standing* after their billion dances? + + diff --git a/2017/Day16/input.in b/2017/Day16/input.in index bca792491..afac7a443 100644 Binary files a/2017/Day16/input.in and b/2017/Day16/input.in differ diff --git a/2017/Day17/README.md b/2017/Day17/README.md index 470b36a6a..5d523d793 100755 --- a/2017/Day17/README.md +++ b/2017/Day17/README.md @@ -1,6 +1,51 @@ +original source: [https://adventofcode.com/2017/day/17](https://adventofcode.com/2017/day/17) ## --- Day 17: Spinlock --- Suddenly, whirling in the distance, you notice what looks like a massive, pixelated hurricane: a deadly [spinlock](https://en.wikipedia.org/wiki/Spinlock). This spinlock isn't just consuming computing power, but memory, too; vast, digital mountains are being ripped from the ground and consumed by the vortex. If you don't move quickly, fixing that printer will be the least of your problems. -Read the [full puzzle](https://adventofcode.com/2017/day/17). \ No newline at end of file +This spinlock's algorithm is simple but efficient, quickly consuming everything in its path. It starts with a circular buffer containing only the value `0`, which it marks as the *current position*. It then steps forward through the circular buffer some number of steps (your puzzle input) before inserting the first new value, `1`, after the value it stopped on. The inserted value becomes the *current position*. Then, it steps forward from there the same number of steps, and wherever it stops, inserts after it the second new value, `2`, and uses that as the new *current position* again. + +It repeats this process of *stepping forward*, *inserting a new value*, and *using the location of the inserted value as the new current position* a total of `*2017*` times, inserting `2017` as its final operation, and ending with a total of `2018` values (including `0`) in the circular buffer. + +For example, if the spinlock were to step `3` times per insert, the circular buffer would begin to evolve like this (using parentheses to mark the current position after each iteration of the algorithm): + + + - `(0)`, the initial state before any insertions. + - `0 (1)`: the spinlock steps forward three times (`0`, `0`, `0`), and then inserts the first value, `1`, after it. `1` becomes the current position. + - `0 (2) 1`: the spinlock steps forward three times (`0`, `1`, `0`), and then inserts the second value, `2`, after it. `2` becomes the current position. + - `0  2 (3) 1`: the spinlock steps forward three times (`1`, `0`, `2`), and then inserts the third value, `3`, after it. `3` becomes the current position. + +And so on: + + + - `0  2 (4) 3  1` + - `0 (5) 2  4  3  1` + - `0  5  2  4  3 (6) 1` + - `0  5 (7) 2  4  3  6  1` + - `0  5  7  2  4  3 (8) 6  1` + - `0 (9) 5  7  2  4  3  8  6  1` + +Eventually, after 2017 insertions, the section of the circular buffer near the last insertion looks like this: + +``` +1512 1134 151 (2017) 638 1513 851 +``` + +Perhaps, if you can identify the value that will ultimately be *after* the last value written (`2017`), you can short-circuit the spinlock. In this example, that would be `638`. + +*What is the value after `2017`* in your completed circular buffer? + + +## --- Part Two --- +The spinlock does not short-circuit. Instead, it gets *more* angry. At least, you assume that's what happened; it's spinning significantly faster than it was a moment ago. + +You have good news and bad news. + +The good news is that you have improved calculations for how to stop the spinlock. They indicate that you actually need to identify *the value after `0`* in the current state of the circular buffer. + +The bad news is that while you were determining this, the spinlock has just finished inserting its fifty millionth value (`50000000`). + +*What is the value after `0`* the moment `50000000` is inserted? + + diff --git a/2017/Day17/input.in b/2017/Day17/input.in index 680907958..47eb669ba 100755 Binary files a/2017/Day17/input.in and b/2017/Day17/input.in differ diff --git a/2017/Day18/README.md b/2017/Day18/README.md index 5dad72bb5..d9ee665f1 100755 --- a/2017/Day18/README.md +++ b/2017/Day18/README.md @@ -1,6 +1,79 @@ +original source: [https://adventofcode.com/2017/day/18](https://adventofcode.com/2017/day/18) ## --- Day 18: Duet --- You discover a tablet containing some strange assembly code labeled simply "[Duet](https://en.wikipedia.org/wiki/Duet)". Rather than bother the sound card with it, you decide to run the code yourself. Unfortunately, you don't see any documentation, so you're left to figure out what the instructions mean on your own. It seems like the assembly is meant to operate on a set of *registers* that are each named with a single letter and that can each hold a single [integer](https://en.wikipedia.org/wiki/Integer). You suppose each register should start with a value of `0`. -Read the [full puzzle](https://adventofcode.com/2017/day/18). \ No newline at end of file +There aren't that many instructions, so it shouldn't be hard to figure out what they do. Here's what you determine: + + + - `snd X` *plays a sound* with a frequency equal to the value of `X`. + - `set X Y` *sets* register `X` to the value of `Y`. + - `add X Y` *increases* register `X` by the value of `Y`. + - `mul X Y` sets register `X` to the result of *multiplying* the value contained in register `X` by the value of `Y`. + - `mod X Y` sets register `X` to the *remainder* of dividing the value contained in register `X` by the value of `Y` (that is, it sets `X` to the result of `X` [modulo](https://en.wikipedia.org/wiki/Modulo_operation) `Y`). + - `rcv X` *recovers* the frequency of the last sound played, but only when the value of `X` is not zero. (If it is zero, the command does nothing.) + - `jgz X Y` *jumps* with an offset of the value of `Y`, but only if the value of `X` is *greater than zero*. (An offset of `2` skips the next instruction, an offset of `-1` jumps to the previous instruction, and so on.) + +Many of the instructions can take either a register (a single letter) or a number. The value of a register is the integer it contains; the value of a number is that number. + +After each *jump* instruction, the program continues with the instruction to which the *jump* jumped. After any other instruction, the program continues with the next instruction. Continuing (or jumping) off either end of the program terminates it. + +For example: + +``` +set a 1 +add a 2 +mul a a +mod a 5 +snd a +set a 0 +rcv a +jgz a -1 +set a 1 +jgz a -2 +``` + + + - The first four instructions set `a` to `1`, add `2` to it, square it, and then set it to itself modulo `5`, resulting in a value of `4`. + - Then, a sound with frequency `4` (the value of `a`) is played. + - After that, `a` is set to `0`, causing the subsequent `rcv` and `jgz` instructions to both be skipped (`rcv` because `a` is `0`, and `jgz` because `a` is not greater than `0`). + - Finally, `a` is set to `1`, causing the next `jgz` instruction to activate, jumping back two instructions to another jump, which jumps again to the `rcv`, which ultimately triggers the *recover* operation. + +At the time the *recover* operation is executed, the frequency of the last sound played is `4`. + +*What is the value of the recovered frequency* (the value of the most recently played sound) the *first* time a `rcv` instruction is executed with a non-zero value? + + +## --- Part Two --- +As you congratulate yourself for a job well done, you notice that the documentation has been on the back of the tablet this entire time. While you actually got most of the instructions correct, there are a few key differences. This assembly code isn't about sound at all - it's meant to be run *twice at the same time*. + +Each running copy of the program has its own set of registers and follows the code independently - in fact, the programs don't even necessarily run at the same speed. To coordinate, they use the *send* (`snd`) and *receive* (`rcv`) instructions: + + + - `snd X` *sends* the value of `X` to the other program. These values wait in a queue until that program is ready to receive them. Each program has its own message queue, so a program can never receive a message it sent. + - `rcv X` *receives* the next value and stores it in register `X`. If no values are in the queue, the program *waits for a value to be sent to it*. Programs do not continue to the next instruction until they have received a value. Values are received in the order they are sent. + +Each program also has its own *program ID* (one `0` and the other `1`); the register `p` should begin with this value. + +For example: + +``` +snd 1 +snd 2 +snd p +rcv a +rcv b +rcv c +rcv d +``` + +Both programs begin by sending three values to the other. Program `0` sends `1, 2, 0`; program `1` sends `1, 2, 1`. Then, each program receives a value (both `1`) and stores it in `a`, receives another value (both `2`) and stores it in `b`, and then each receives the program ID of the other program (program `0` receives `1`; program `1` receives `0`) and stores it in `c`. Each program now sees a different value in its own copy of register `c`. + +Finally, both programs try to `rcv` a *fourth* time, but no data is waiting for either of them, and they reach a *deadlock*. When this happens, both programs terminate. + +It should be noted that it would be equally valid for the programs to run at different speeds; for example, program `0` might have sent all three values and then stopped at the first `rcv` before program `1` executed even its first instruction. + +Once both of your programs have terminated (regardless of what caused them to do so), *how many times did program `1` send a value*? + + diff --git a/2017/Day18/input.in b/2017/Day18/input.in index d009c685d..90173aea5 100755 Binary files a/2017/Day18/input.in and b/2017/Day18/input.in differ diff --git a/2017/Day19/README.md b/2017/Day19/README.md index 51bf41e1f..c9071a10c 100644 --- a/2017/Day19/README.md +++ b/2017/Day19/README.md @@ -1,6 +1,63 @@ +original source: [https://adventofcode.com/2017/day/19](https://adventofcode.com/2017/day/19) ## --- Day 19: A Series of Tubes --- Somehow, a network packet got lost and ended up here. It's trying to follow a routing diagram (your puzzle input), but it's confused about where to go. Its starting point is just off the top of the diagram. Lines (drawn with `|`, `-`, and `+`) show the path it needs to take, starting by going down onto the only line connected to the top of the diagram. It needs to follow this path until it reaches the end (located somewhere within the diagram) and stop there. -Read the [full puzzle](https://adventofcode.com/2017/day/19). \ No newline at end of file +Sometimes, the lines cross over each other; in these cases, it needs to continue going the same direction, and only turn left or right when there's no other option. In addition, someone has left *letters* on the line; these also don't change its direction, but it can use them to keep track of where it's been. For example: + +``` + | + | +--+ + A | C + F---|----E|--+ + | | | D + +B-+ +--+ + +``` + +Given this diagram, the packet needs to take the following path: + + + - Starting at the only line touching the top of the diagram, it must go down, pass through `A`, and continue onward to the first `+`. + - Travel right, up, and right, passing through `B` in the process. + - Continue down (collecting `C`), right, and up (collecting `D`). + - Finally, go all the way left through `E` and stopping at `F`. + +Following the path to the end, the letters it sees on its path are `ABCDEF`. + +The little packet looks up at you, hoping you can help it find the way. *What letters will it see* (in the order it would see them) if it follows the path? (The routing diagram is very wide; make sure you view it without line wrapping.) + + +## --- Part Two --- +The packet is curious how many steps it needs to go. + +For example, using the same routing diagram from the example above... + +``` + | + | +--+ + A | C + F---|--|-E---+ + | | | D + +B-+ +--+ + +``` + +...the packet would go: + + + - `6` steps down (including the first line at the top of the diagram). + - `3` steps right. + - `4` steps up. + - `3` steps right. + - `4` steps down. + - `3` steps right. + - `2` steps up. + - `13` steps left (including the `F` it stops on). + +This would result in a total of `38` steps. + +*How many steps* does the packet need to go? + + diff --git a/2017/Day19/input.in b/2017/Day19/input.in index 5dff2031d..e5946cfe9 100644 Binary files a/2017/Day19/input.in and b/2017/Day19/input.in differ diff --git a/2017/Day20/README.md b/2017/Day20/README.md index 5f187c427..260c9f7a1 100644 --- a/2017/Day20/README.md +++ b/2017/Day20/README.md @@ -1,6 +1,71 @@ +original source: [https://adventofcode.com/2017/day/20](https://adventofcode.com/2017/day/20) ## --- Day 20: Particle Swarm --- Suddenly, the GPU contacts you, asking for help. Someone has asked it to simulate *too many particles*, and it won't be able to finish them all in time to render the next frame at this rate. It transmits to you a buffer (your puzzle input) listing each particle in order (starting with particle `0`, then particle `1`, particle `2`, and so on). For each particle, it provides the `X`, `Y`, and `Z` coordinates for the particle's position (`p`), velocity (`v`), and acceleration (`a`), each in the format ``. -Read the [full puzzle](https://adventofcode.com/2017/day/20). \ No newline at end of file +Each tick, all particles are updated simultaneously. A particle's properties are updated in the following order: + + + - Increase the `X` velocity by the `X` acceleration. + - Increase the `Y` velocity by the `Y` acceleration. + - Increase the `Z` velocity by the `Z` acceleration. + - Increase the `X` position by the `X` velocity. + - Increase the `Y` position by the `Y` velocity. + - Increase the `Z` position by the `Z` velocity. + +Because of seemingly tenuous rationale involving [z-buffering](https://en.wikipedia.org/wiki/Z-buffering), the GPU would like to know which particle will stay closest to position `<0,0,0>` in the long term. Measure this using the [Manhattan distance](https://en.wikipedia.org/wiki/Taxicab_geometry), which in this situation is simply the sum of the absolute values of a particle's `X`, `Y`, and `Z` position. + +For example, suppose you are only given two particles, both of which stay entirely on the X-axis (for simplicity). Drawing the current states of particles `0` and `1` (in that order) with an adjacent a number line and diagram of current `X` positions (marked in parenthesis), the following would take place: + +``` +p=< 3,0,0>, v=< 2,0,0>, a=<-1,0,0> -4 -3 -2 -1 0 1 2 3 4 +p=< 4,0,0>, v=< 0,0,0>, a=<-2,0,0> (0)(1) + +p=< 4,0,0>, v=< 1,0,0>, a=<-1,0,0> -4 -3 -2 -1 0 1 2 3 4 +p=< 2,0,0>, v=<-2,0,0>, a=<-2,0,0> (1) (0) + +p=< 4,0,0>, v=< 0,0,0>, a=<-1,0,0> -4 -3 -2 -1 0 1 2 3 4 +p=<-2,0,0>, v=<-4,0,0>, a=<-2,0,0> (1) (0) + +p=< 3,0,0>, v=<-1,0,0>, a=<-1,0,0> -4 -3 -2 -1 0 1 2 3 4 +p=<-8,0,0>, v=<-6,0,0>, a=<-2,0,0> (0) +``` + +At this point, particle `1` will never be closer to `<0,0,0>` than particle `0`, and so, in the long run, particle `0` will stay closest. + +*Which particle will stay closest to position `<0,0,0>`* in the long term? + + +## --- Part Two --- +To simplify the problem further, the GPU would like to remove any particles that *collide*. Particles collide if their positions ever *exactly match*. Because particles are updated simultaneously, *more than two particles* can collide at the same time and place. Once particles collide, they are removed and cannot collide with anything else after that tick. + +For example: + +``` +p=<-6,0,0>, v=< 3,0,0>, a=< 0,0,0> +p=<-4,0,0>, v=< 2,0,0>, a=< 0,0,0> -6 -5 -4 -3 -2 -1 0 1 2 3 +p=<-2,0,0>, v=< 1,0,0>, a=< 0,0,0> (0) (1) (2) (3) +p=< 3,0,0>, v=<-1,0,0>, a=< 0,0,0> + +p=<-3,0,0>, v=< 3,0,0>, a=< 0,0,0> +p=<-2,0,0>, v=< 2,0,0>, a=< 0,0,0> -6 -5 -4 -3 -2 -1 0 1 2 3 +p=<-1,0,0>, v=< 1,0,0>, a=< 0,0,0> (0)(1)(2) (3) +p=< 2,0,0>, v=<-1,0,0>, a=< 0,0,0> + +p=< 0,0,0>, v=< 3,0,0>, a=< 0,0,0> +p=< 0,0,0>, v=< 2,0,0>, a=< 0,0,0> -6 -5 -4 -3 -2 -1 0 1 2 3 +p=< 0,0,0>, v=< 1,0,0>, a=< 0,0,0> X (3) +p=< 1,0,0>, v=<-1,0,0>, a=< 0,0,0> + +------destroyed by collision------ +------destroyed by collision------ -6 -5 -4 -3 -2 -1 0 1 2 3 +------destroyed by collision------ (3) +p=< 0,0,0>, v=<-1,0,0>, a=< 0,0,0> +``` + +In this example, particles `0`, `1`, and `2` are simultaneously destroyed at the time and place marked `X`. On the next tick, particle `3` passes through unharmed. + +*How many particles are left* after all collisions are resolved? + + diff --git a/2017/Day20/input.in b/2017/Day20/input.in index 7c61f4550..4358fa7ff 100644 Binary files a/2017/Day20/input.in and b/2017/Day20/input.in differ diff --git a/2017/Day21/README.md b/2017/Day21/README.md index e949862b9..6855fa56f 100644 --- a/2017/Day21/README.md +++ b/2017/Day21/README.md @@ -1,6 +1,112 @@ +original source: [https://adventofcode.com/2017/day/21](https://adventofcode.com/2017/day/21) ## --- Day 21: Fractal Art --- You find a program trying to generate some art. It uses a strange process that involves repeatedly enhancing the detail of an image through a set of rules. The image consists of a two-dimensional square grid of pixels that are either on (`#`) or off (`.`). The program always begins with this pattern: -Read the [full puzzle](https://adventofcode.com/2017/day/21). \ No newline at end of file +``` +.#. +..# +### +``` + +Because the pattern is both `3` pixels wide and `3` pixels tall, it is said to have a *size* of `3`. + +Then, the program repeats the following process: + + + - If the size is evenly divisible by `2`, break the pixels up into `2x2` squares, and convert each `2x2` square into a `3x3` square by following the corresponding *enhancement rule*. + - Otherwise, the size is evenly divisible by `3`; break the pixels up into `3x3` squares, and convert each `3x3` square into a `4x4` square by following the corresponding *enhancement rule*. + +Because each square of pixels is replaced by a larger one, the image gains pixels and so its *size* increases. + +The artist's book of enhancement rules is nearby (your puzzle input); however, it seems to be missing rules. The artist explains that sometimes, one must *rotate* or *flip* the input pattern to find a match. (Never rotate or flip the output pattern, though.) Each pattern is written concisely: rows are listed as single units, ordered top-down, and separated by slashes. For example, the following rules correspond to the adjacent patterns: + +``` +../.# = .. + .# + + .#. +.#./..#/### = ..# + ### + + #..# +#..#/..../#..#/.##. = .... + #..# + .##. +``` + +When searching for a rule to use, rotate and flip the pattern as necessary. For example, all of the following patterns match the same rule: + +``` +.#. .#. #.. ### +..# #.. #.# ..# +### ### ##. .#. +``` + +Suppose the book contained the following two rules: + +``` +../.# => ##./#../... +.#./..#/### => #..#/..../..../#..# +``` + +As before, the program begins with this pattern: + +``` +.#. +..# +### +``` + +The size of the grid (`3`) is not divisible by `2`, but it is divisible by `3`. It divides evenly into a single square; the square matches the second rule, which produces: + +``` +#..# +.... +.... +#..# +``` + +The size of this enhanced grid (`4`) is evenly divisible by `2`, so that rule is used. It divides evenly into four squares: + +``` +#.|.# +..|.. +--+-- +..|.. +#.|.# +``` + +Each of these squares matches the same rule (`../.# => ##./#../...`), three of which require some flipping and rotation to line up with the rule. The output for the rule is the same in all four cases: + +``` +##.|##. +#..|#.. +...|... +---+--- +##.|##. +#..|#.. +...|... +``` + +Finally, the squares are joined into a new grid: + +``` +##.##. +#..#.. +...... +##.##. +#..#.. +...... +``` + +Thus, after `2` iterations, the grid contains `12` pixels that are *on*. + +*How many pixels stay on* after `5` iterations? + + +## --- Part Two --- +*How many pixels stay on* after `18` iterations? + + diff --git a/2017/Day21/input.in b/2017/Day21/input.in index 8ef156364..5ae047112 100644 Binary files a/2017/Day21/input.in and b/2017/Day21/input.in differ diff --git a/2017/Day22/README.md b/2017/Day22/README.md index 8355477fd..ea06bb2d2 100644 --- a/2017/Day22/README.md +++ b/2017/Day22/README.md @@ -1,5 +1,225 @@ +original source: [https://adventofcode.com/2017/day/22](https://adventofcode.com/2017/day/22) ## --- Day 22: Sporifica Virus --- Diagnostics indicate that the local *grid computing cluster* has been contaminated with the *Sporifica Virus*. The grid computing cluster is a seemingly-infinite two-dimensional grid of compute nodes. Each node is either *clean* or *infected* by the virus. -Read the [full puzzle](https://adventofcode.com/2017/day/22). \ No newline at end of file +To [prevent overloading](https://en.wikipedia.org/wiki/Morris_worm#The_mistake) the nodes (which would render them useless to the virus) or detection by system administrators, exactly one *virus carrier* moves through the network, infecting or cleaning nodes as it moves. The virus carrier is always located on a single node in the network (the *current node*) and keeps track of the *direction* it is facing. + +To avoid detection, the virus carrier works in bursts; in each burst, it *wakes up*, does some *work*, and goes back to *sleep*. The following steps are all executed *in order* one time each burst: + + + - If the *current node* is *infected*, it turns to its *right*. Otherwise, it turns to its *left*. (Turning is done in-place; the *current node* does not change.) + - If the *current node* is *clean*, it becomes *infected*. Otherwise, it becomes *cleaned*. (This is done *after* the node is considered for the purposes of changing direction.) + - The virus carrier [moves](https://www.youtube.com/watch?v=2vj37yeQQHg) *forward* one node in the direction it is facing. + +Diagnostics have also provided a *map of the node infection status* (your puzzle input). *Clean* nodes are shown as `.`; *infected* nodes are shown as `#`. This map only shows the center of the grid; there are many more nodes beyond those shown, but none of them are currently infected. + +The virus carrier begins in the middle of the map facing *up*. + +For example, suppose you are given a map like this: + +``` +..# +#.. +... +``` + +Then, the middle of the infinite grid looks like this, with the virus carrier's position marked with `[ ]`: + +``` +. . . . . . . . . +. . . . . . . . . +. . . . . . . . . +. . . . . # . . . +. . . #[.]. . . . +. . . . . . . . . +. . . . . . . . . +. . . . . . . . . +``` + +The virus carrier is on a *clean* node, so it turns *left*, *infects* the node, and moves left: + +``` +. . . . . . . . . +. . . . . . . . . +. . . . . . . . . +. . . . . # . . . +. . .[#]# . . . . +. . . . . . . . . +. . . . . . . . . +. . . . . . . . . +``` + +The virus carrier is on an *infected* node, so it turns *right*, *cleans* the node, and moves up: + +``` +. . . . . . . . . +. . . . . . . . . +. . . . . . . . . +. . .[.]. # . . . +. . . . # . . . . +. . . . . . . . . +. . . . . . . . . +. . . . . . . . . +``` + +Four times in a row, the virus carrier finds a *clean*, *infects* it, turns *left*, and moves forward, ending in the same place and still facing up: + +``` +. . . . . . . . . +. . . . . . . . . +. . . . . . . . . +. . #[#]. # . . . +. . # # # . . . . +. . . . . . . . . +. . . . . . . . . +. . . . . . . . . +``` + +Now on the same node as before, it sees an infection, which causes it to turn *right*, *clean* the node, and move forward: + +``` +. . . . . . . . . +. . . . . . . . . +. . . . . . . . . +. . # .[.]# . . . +. . # # # . . . . +. . . . . . . . . +. . . . . . . . . +. . . . . . . . . +``` + +After the above actions, a total of `7` bursts of activity had taken place. Of them, `5` bursts of activity caused an infection. + +After a total of `70`, the grid looks like this, with the virus carrier facing up: + +``` +. . . . . # # . . +. . . . # . . # . +. . . # . . . . # +. . # . #[.]. . # +. . # . # . . # . +. . . . . # # . . +. . . . . . . . . +. . . . . . . . . +``` + +By this time, `41` bursts of activity caused an infection (though most of those nodes have since been cleaned). + +After a total of `10000` bursts of activity, `5587` bursts will have caused an infection. + +Given your actual map, after `10000` bursts of activity, *how many bursts cause a node to become infected*? (Do not count nodes that begin infected.) + + +## --- Part Two --- +As you go to remove the virus from the infected nodes, it *evolves* to resist your attempt. + +Now, before it infects a clean node, it will *weaken* it to disable your defenses. If it encounters an infected node, it will instead *flag* the node to be cleaned in the future. So: + + + - *Clean* nodes become *weakened*. + - *Weakened* nodes become *infected*. + - *Infected* nodes become *flagged*. + - *Flagged* nodes become *clean*. + +Every node is always in exactly one of the above states. + +The virus carrier still functions in a similar way, but now uses the following logic during its bursts of action: + + + - Decide which way to turn based on the *current node*: + + - If it is *clean*, it turns *left*. + - If it is *weakened*, it does *not* turn, and will continue moving in the same direction. + - If it is *infected*, it turns *right*. + - If it is *flagged*, it *reverses* direction, and will go back the way it came. + + + - Modify the state of the *current node*, as described above. + - The virus carrier moves *forward* one node in the direction it is facing. + +Start with the same map (still using `.` for *clean* and `#` for infected) and still with the virus carrier starting in the middle and facing *up*. + +Using the same initial state as the previous example, and drawing *weakened* as `W` and *flagged* as `F`, the middle of the infinite grid looks like this, with the virus carrier's position again marked with `[ ]`: + +``` +. . . . . . . . . +. . . . . . . . . +. . . . . . . . . +. . . . . # . . . +. . . #[.]. . . . +. . . . . . . . . +. . . . . . . . . +. . . . . . . . . +``` + +This is the same as before, since no initial nodes are *weakened* or *flagged*. The virus carrier is on a clean node, so it still turns left, instead *weakens* the node, and moves left: + +``` +. . . . . . . . . +. . . . . . . . . +. . . . . . . . . +. . . . . # . . . +. . .[#]W . . . . +. . . . . . . . . +. . . . . . . . . +. . . . . . . . . +``` + +The virus carrier is on an infected node, so it still turns right, instead *flags* the node, and moves up: + +``` +. . . . . . . . . +. . . . . . . . . +. . . . . . . . . +. . .[.]. # . . . +. . . F W . . . . +. . . . . . . . . +. . . . . . . . . +. . . . . . . . . +``` + +This process repeats three more times, ending on the previously-flagged node and facing right: + +``` +. . . . . . . . . +. . . . . . . . . +. . . . . . . . . +. . W W . # . . . +. . W[F]W . . . . +. . . . . . . . . +. . . . . . . . . +. . . . . . . . . +``` + +Finding a flagged node, it reverses direction and *cleans* the node: + +``` +. . . . . . . . . +. . . . . . . . . +. . . . . . . . . +. . W W . # . . . +. .[W]. W . . . . +. . . . . . . . . +. . . . . . . . . +. . . . . . . . . +``` + +The *weakened* node becomes infected, and it continues in the same direction: + +``` +. . . . . . . . . +. . . . . . . . . +. . . . . . . . . +. . W W . # . . . +.[.]# . W . . . . +. . . . . . . . . +. . . . . . . . . +. . . . . . . . . +``` + +Of the first `100` bursts, `26` will result in *infection*. Unfortunately, another feature of this evolved virus is *speed*; of the first `10000000` bursts, `2511944` will result in *infection*. + +Given your actual map, after `10000000` bursts of activity, *how many bursts cause a node to become infected*? (Do not count nodes that begin infected.) + + diff --git a/2017/Day22/Solution.cs b/2017/Day22/Solution.cs index 9494c0bf2..4b5571bcc 100644 --- a/2017/Day22/Solution.cs +++ b/2017/Day22/Solution.cs @@ -14,8 +14,8 @@ enum State { class Solution : Solver { public object PartOne(string input) => - Iterate(input, 10000, - (state, drow, dcol) => + Iterate(input, 10000, + (state, drow, dcol) => state switch { State.Clean => (State.Infected, -dcol, drow), State.Infected => (State.Clean, dcol, -drow), @@ -24,8 +24,8 @@ public object PartOne(string input) => ); public object PartTwo(string input) => - Iterate(input, 10000000, - (state, drow, dcol) => + Iterate(input, 10000000, + (state, drow, dcol) => state switch { State.Clean => (State.Weakened, -dcol, drow), State.Weakened => (State.Infected, drow, dcol), @@ -48,14 +48,14 @@ int Iterate(string input, int iterations, Func reboot printer +Error: That command requires *priority 50*. You currently have *priority 0*. +You must deposit *50 stars* to increase your priority to the required level. +``` + +The console flickers for a moment, and then prints another message: + +``` +*Star* accepted. +You must deposit *49 stars* to increase your priority to the required level. +``` + +The *garbage collector* winks at you, then continues sweeping. + + diff --git a/2017/Day25/input.in b/2017/Day25/input.in index b0a778b4a..0e81e5f24 100644 Binary files a/2017/Day25/input.in and b/2017/Day25/input.in differ diff --git a/2017/README.md b/2017/README.md index 33861dcbc..0d7fa30de 100644 --- a/2017/README.md +++ b/2017/README.md @@ -1,4 +1,6 @@ + # Advent of Code (2017) Check out https://adventofcode.com/2017.
+ diff --git a/2017/SplashScreen.cs b/2017/SplashScreen.cs index fb4ba3fb2..1ee0b2d44 100644 --- a/2017/SplashScreen.cs +++ b/2017/SplashScreen.cs @@ -1,3 +1,4 @@ + using System; namespace AdventOfCode.Y2017; @@ -8,210 +9,209 @@ public void Show() { var color = Console.ForegroundColor; Write(0xcc00, false, " ▄█▄ ▄▄█ ▄ ▄ ▄▄▄ ▄▄ ▄█▄ ▄▄▄ ▄█ ▄▄ ▄▄▄ ▄▄█ ▄▄▄\n █▄█ █ █ █ █ █▄█ █ █ █ █ █ █▄ "); - Write(0xcc00, false, " █ █ █ █ █ █▄█\n █ █ █▄█ ▀▄▀ █▄▄ █ █ █▄ █▄█ █ █▄ █▄█ █▄█ █▄▄ {'year': 2017}\n "); - Write(0xcc00, false, " \n "); - Write(0x999999, false, "|O| "); - Write(0xcccccc, false, " Naughty | Nice "); - Write(0x999999, false, "|O| \n |O| "); - Write(0xcccccc, false, "-------------------+------------------- "); - Write(0x999999, false, "|O| \n |O| "); - Write(0xcccccc, false, "The Easter Bunny | encse "); - Write(0x999999, false, "|O| \n |O| "); - Write(0xcccccc, false, "Martin Galese | Szabolcs Sipos "); - Write(0x999999, false, "|O| \n |O| "); - Write(0xcccccc, false, "Balázs Dankó | wesen "); - Write(0x999999, false, "|O| \n |O| "); - Write(0xcccccc, false, "Gábor Gyebnár | Daniel Willenson "); - Write(0x999999, false, "|O| \n |O| "); - Write(0xcccccc, false, "Woodrow Hedberg | gkatai "); - Write(0x999999, false, "|O| \n "); - Write(0xcccccc, false, ".-----------------------------------------------. \n | "); - Write(0x666666, false, "┌───────────────o┌"); - Write(0xffff66, true, "*"); - Write(0x666666, false, "───────"); - Write(0xaaaaaa, false, "[─]"); - Write(0x666666, false, "────┐o─────────┐ "); - Write(0xcccccc, false, "| 25 "); - Write(0xffff66, false, "**\n "); - Write(0xcccccc, false, "| "); - Write(0x666666, false, "└──────"); - Write(0x9900, false, "oTo"); - Write(0x666666, false, "───────┘└────"); - Write(0xffff66, true, "*"); - Write(0x666666, false, "┌o┌────┐┌┘┌─────────┤ "); - Write(0xcccccc, false, "| 24 "); - Write(0xffff66, false, "**\n "); - Write(0xcccccc, false, "| "); - Write(0xffff66, true, "*"); - Write(0x666666, false, "───────────────────"); - Write(0x66ff, false, "|("); - Write(0x666666, false, "─┘├─┘┌──o└┘┌┴──────┐o─┘ "); - Write(0xcccccc, false, "| 23 "); - Write(0xffff66, false, "**\n "); - Write(0xcccccc, false, "| "); - Write(0x666666, false, "└───"); - Write(0xff0000, false, "┤|├"); - Write(0x666666, false, "───┬┴┴┴┴┬────"); - Write(0xffff66, true, "*"); - Write(0x666666, false, "┌─o│o─┴─────┴──────o└──┐ "); - Write(0xcccccc, false, "| 22 "); - Write(0xffff66, false, "**\n "); - Write(0xcccccc, false, "| "); - Write(0xffff66, true, "*"); - Write(0x666666, false, "─"); - Write(0xaaaaaa, false, "[─]"); - Write(0x666666, false, "─"); - Write(0xaaaaaa, false, "[─]"); - Write(0x666666, false, "─┤ DY├────┘└──┴────"); - Write(0xff9900, false, "∧∧∧"); - Write(0x666666, false, "────────────┤ "); - Write(0xcccccc, false, "| 21 "); - Write(0xffff66, false, "**\n "); - Write(0xcccccc, false, "| "); - Write(0x666666, false, "├─────────┤ EP├─────┐┌──"); - Write(0xff9900, false, "∧∧∧"); - Write(0x666666, false, "──"); - Write(0x990099, false, "┤[]├"); - Write(0x666666, false, "───┐┌─"); - Write(0xffff66, true, "*"); - Write(0x666666, false, "o──┘ "); - Write(0xcccccc, false, "| 20 "); - Write(0xffff66, false, "**\n "); - Write(0xcccccc, false, "| "); - Write(0x666666, false, "└─────────┤ CT├────┬┘│V┌────┬──────o└┴o└───"); - Write(0xffff66, true, "* "); - Write(0xcccccc, false, "| 19 "); - Write(0xffff66, false, "**\n "); - Write(0xcccccc, false, "| "); - Write(0x666666, false, "┌─────────┤ RR├o───┘┌┘└┴──o┌┘"); - Write(0xffff66, true, "*"); - Write(0x666666, false, "─────┬┴┴┴┬───┘ "); - Write(0xcccccc, false, "| 18 "); - Write(0xffff66, false, "**\n "); - Write(0xcccccc, false, "| "); - Write(0x666666, false, "├─────────┤ ├─────┘o┬────┘┌┘┌────┤ 30├───"); - Write(0xffff66, true, "* "); - Write(0xcccccc, false, "| 17 "); - Write(0xffff66, false, "**\n "); - Write(0xcccccc, false, "| "); - Write(0x666666, false, "│o┬─┐"); - Write(0xffff66, true, "*"); - Write(0x666666, false, "────┼┬┬┬┬┴───"); - Write(0xff9900, false, "∧∧∧"); - Write(0x666666, false, "─┘┌───┐└─┴────┤ 29├┐┌─┘ "); - Write(0xcccccc, false, "| 16 "); - Write(0xffff66, false, "**\n "); - Write(0xcccccc, false, "| "); - Write(0x666666, false, "└─┘┌┘└───"); - Write(0xffff66, true, "*"); - Write(0x666666, false, "└┬┴┴┴┴┬───────┘o──┴──────┐┤ 83├┘└─┐ "); - Write(0xcccccc, false, "| 15 "); - Write(0xffff66, false, "**\n "); - Write(0xcccccc, false, "| "); - Write(0x666666, false, "┌──┘┌───o└─┤ ├──┐┌───────"); - Write(0xffff66, true, "*"); - Write(0x666666, false, "o─────┴┤ P6├───┘ "); - Write(0xcccccc, false, "| 14 "); - Write(0xffff66, false, "**\n "); - Write(0xcccccc, false, "| "); - Write(0x666666, false, "└┬──┘┌─"); - Write(0x9900, false, "oTo"); - Write(0x666666, false, "─┤ ├─o└┘┌─────o└───────┴┬┬┬┴───"); - Write(0xffff66, true, "* "); - Write(0xcccccc, false, "| 13 "); - Write(0xffff66, false, "**\n "); - Write(0xcccccc, false, "| "); - Write(0x666666, false, "o┘┌──┘┌────┤ v17├────┴─┐"); - Write(0xffff66, true, "*"); - Write(0x666666, false, "──"); - Write(0xaaaaaa, false, "[─]"); - Write(0x666666, false, "─────────┐┌───┤ "); - Write(0xcccccc, false, "| 12 "); - Write(0xffff66, false, "**\n "); - Write(0xcccccc, false, "| "); - Write(0x666666, false, "┌─┘┌┴┴┴┴┴┬─┴┬┬┬┬┴──"); - Write(0x66ff, false, "|("); - Write(0x666666, false, "──┘└──────"); - Write(0xffff66, true, "*"); - Write(0x666666, false, "┌─o┌───┘└─┐V│ "); - Write(0xcccccc, false, "| 11 "); - Write(0xffff66, false, "**\n "); - Write(0xcccccc, false, "| "); - Write(0x666666, false, "└──┤ ├"); - Write(0xffff66, true, "*"); - Write(0x666666, false, "──────"); - Write(0xff9900, false, "∧∧∧"); - Write(0x666666, false, "───────────┘└──┴──────┘└┘ "); - Write(0xcccccc, false, "| 10 "); - Write(0xffff66, false, "**\n "); - Write(0xcccccc, false, "| "); - Write(0x666666, false, "┌──┤ ├┘┌─────"); - Write(0xff9900, false, "∧∧∧"); - Write(0x666666, false, "───────┐┌───────────────"); - Write(0xffff66, true, "* "); - Write(0xcccccc, false, "| 9 "); - Write(0xffff66, false, "**\n "); - Write(0xcccccc, false, "| "); - Write(0x666666, false, "└──┤ 5 ├─┴─────o"); - Write(0xffff66, true, "*"); - Write(0x666666, false, "───────┐└┴o┌─────────"); - Write(0x66ff, false, "|("); - Write(0x666666, false, "──┤ "); - Write(0xcccccc, false, "| 8 "); - Write(0xffff66, false, "**\n "); - Write(0xcccccc, false, "| "); - Write(0x666666, false, "┌"); - Write(0xffff66, true, "*"); - Write(0x666666, false, "─┤ 1P├────────┘o──"); - Write(0x66ff, false, "|("); - Write(0x666666, false, "──┴───┘o─────┬─o┌───┘ "); - Write(0xcccccc, false, "| 7 "); - Write(0xffff66, false, "**\n "); - Write(0xcccccc, false, "| "); - Write(0x666666, false, "│└─┤ 2B├────────────────────────"); - Write(0xffff66, true, "*"); - Write(0x666666, false, "┌─┘┌─┘o──┐ "); - Write(0xcccccc, false, "| 6 "); - Write(0xffff66, false, "**\n "); - Write(0xcccccc, false, "| "); - Write(0x666666, false, "└──┴┬┬┬┬┬┴───┐┌──o┌──────┐"); - Write(0xffff66, true, "*"); - Write(0x666666, false, "───────┘└──┴─────┘ "); - Write(0xcccccc, false, "| 5 "); - Write(0xffff66, false, "**\n "); - Write(0xcccccc, false, "| "); - Write(0x666666, false, "V┌───────────┘└───┴───o┌─┘└──────┐┌────────"); - Write(0xffff66, true, "*"); - Write(0x666666, false, "o "); - Write(0xcccccc, false, "| 4 "); - Write(0xffff66, false, "**\n "); - Write(0xcccccc, false, "| "); - Write(0x666666, false, "└┴───"); - Write(0xff0000, false, "┤|├"); - Write(0x666666, false, "──────────────┐└──┬───o┌─┘└┐"); - Write(0xffff66, true, "*"); - Write(0x666666, false, "─┐┌──┐└┐ "); - Write(0xcccccc, false, "| 3 "); - Write(0xffff66, false, "**\n "); - Write(0xcccccc, false, "| "); - Write(0x666666, false, "┌─────────────o┌──────┴───┘"); - Write(0xffff66, true, "*"); - Write(0x666666, false, "──┐└───┘└┐│└─┐└─┤ "); - Write(0xcccccc, false, "| 2 "); - Write(0xffff66, false, "**\n "); - Write(0xcccccc, false, "| "); - Write(0x666666, false, "└──────────────┴─────o"); - Write(0xffff66, true, "*"); - Write(0x666666, false, "────┘o─┴──────┘└──┘o─┘ "); - Write(0xcccccc, false, "| 1 "); - Write(0xffff66, false, "**\n "); - Write(0xcccccc, false, "'-----------------------------------------------' \n \n"); - + Write(0xcc00, false, " █ █ █ █ █ █▄█\n █ █ █▄█ ▀▄▀ █▄▄ █ █ █▄ █▄█ █ █▄ █▄█ █▄█ █▄▄ 0x0000 | 2017\n "); + Write(0xcc00, false, " \n "); + Write(0x999999, false, "|O| "); + Write(0xcccccc, false, " Naughty | Nice "); + Write(0x999999, false, "|O| \n |O| "); + Write(0xcccccc, false, "-------------------+------------------- "); + Write(0x999999, false, "|O| \n |O| "); + Write(0xcccccc, false, "The Easter Bunny | encse "); + Write(0x999999, false, "|O| \n |O| "); + Write(0xcccccc, false, "lizthegrey | Kevin Yap "); + Write(0x999999, false, "|O| \n |O| "); + Write(0xcccccc, false, "Mihai Maruseac | Jean-Noël Monette "); + Write(0x999999, false, "|O| \n |O| "); + Write(0xcccccc, false, "jweinberg | Joe LeGasse "); + Write(0x999999, false, "|O| \n |O| "); + Write(0xcccccc, false, "zenithlight | Christopher Lorton "); + Write(0x999999, false, "|O| \n "); + Write(0xcccccc, false, ".-----------------------------------------------. \n | "); + Write(0x666666, false, "o──────┬───────"); + Write(0xaaaaaa, false, "[─]"); + Write(0x666666, false, "──────┐┌┬──o┌─────────"); + Write(0x9900, false, "oTo"); + Write(0x666666, false, "─"); + Write(0xffff66, true, "* "); + Write(0xcccccc, false, "| 25 "); + Write(0xffff66, false, "**\n "); + Write(0xcccccc, false, "| "); + Write(0x666666, false, "┌──────┘┌─────────┬────o││└───┘o┐"); + Write(0xffff66, true, "*"); + Write(0x666666, false, "────"); + Write(0x9900, false, "oTo"); + Write(0x666666, false, "───┘ "); + Write(0xcccccc, false, "| 24 "); + Write(0xffff66, false, "**\n "); + Write(0xcccccc, false, "| "); + Write(0x666666, false, "├─────┐o┴────────┐└─────┘│o──┬──┘└───"); + Write(0xff0000, false, "┤|├"); + Write(0x666666, false, "────"); + Write(0xffff66, true, "* "); + Write(0xcccccc, false, "| 23 "); + Write(0xffff66, false, "**\n "); + Write(0xcccccc, false, "| "); + Write(0x666666, false, "└────o└────────┐o┴──────o└┐┌─┘"); + Write(0xffff66, true, "*"); + Write(0x666666, false, "─────────────┘ "); + Write(0xcccccc, false, "| 22 "); + Write(0xffff66, false, "**\n "); + Write(0xcccccc, false, "| "); + Write(0x666666, false, "┌───────────"); + Write(0x66ff, false, "|("); + Write(0x666666, false, "─┘┌─────────┘└─┐└────"); + Write(0x66ff, false, "|("); + Write(0x666666, false, "───────"); + Write(0xffff66, true, "* "); + Write(0xcccccc, false, "| 21 "); + Write(0xffff66, false, "**\n "); + Write(0xcccccc, false, "| "); + Write(0x666666, false, "├───────────"); + Write(0x990099, false, "┤[]├"); + Write(0x666666, false, "┴────────────┴───o"); + Write(0xffff66, true, "*"); + Write(0x666666, false, "───"); + Write(0x66ff, false, "|("); + Write(0x666666, false, "────┤ "); + Write(0xcccccc, false, "| 20 "); + Write(0xffff66, false, "**\n "); + Write(0xcccccc, false, "| "); + Write(0x666666, false, "└───────┬┴┴┴┬o"); + Write(0xffff66, true, "*"); + Write(0x666666, false, "──────────"); + Write(0xff0000, false, "┤|├"); + Write(0x666666, false, "──────┘┌───┬───o│ "); + Write(0xcccccc, false, "| 19 "); + Write(0xffff66, false, "**\n "); + Write(0xcccccc, false, "| "); + Write(0xffff66, true, "*"); + Write(0x666666, false, "───────┤ ├┐└─────"); + Write(0x66ff, false, "|("); + Write(0x666666, false, "─────────┐┌──┘o─┐└────┘ "); + Write(0xcccccc, false, "| 18 "); + Write(0xffff66, false, "**\n "); + Write(0xcccccc, false, "| "); + Write(0x666666, false, "└──────"); + Write(0xffff66, true, "*"); + Write(0x666666, false, "┤ ├└───┐┌──"); + Write(0xff9900, false, "∧∧∧"); + Write(0x666666, false, "─"); + Write(0xff0000, false, "┤|├"); + Write(0x666666, false, "───┘└─────┴┐o───┐ "); + Write(0xcccccc, false, "| 17 "); + Write(0xffff66, false, "**\n "); + Write(0xcccccc, false, "| "); + Write(0x666666, false, "┌─"); + Write(0xffff66, true, "*"); + Write(0x666666, false, "────┘┤ ├───┬┘├┴┴┴┴┬──"); + Write(0xaaaaaa, false, "[─]"); + Write(0x666666, false, "────┐┌───o└─┐┌─┘ "); + Write(0xcccccc, false, "| 16 "); + Write(0xffff66, false, "**\n "); + Write(0xcccccc, false, "| "); + Write(0x666666, false, "└o└─────┴┬┬┬┴──"); + Write(0xffff66, true, "*"); + Write(0x666666, false, "└─┤ ├─┬┴┴┴┴┴┬─┘└────┐┌┘└─┐ "); + Write(0xcccccc, false, "| 15 "); + Write(0xffff66, false, "**\n "); + Write(0xcccccc, false, "| "); + Write(0xffff66, true, "*"); + Write(0x666666, false, "──────────────┘┌─┤NAND├─┤ 4├─┐┌──┬─┘└───┤ "); + Write(0xcccccc, false, "| 14 "); + Write(0xffff66, false, "**\n "); + Write(0xcccccc, false, "| "); + Write(0x666666, false, "└──────"); + Write(0xffff66, true, "*"); + Write(0x666666, false, "o───────┴─┤GATE├─┤ 3├─┼┴┴┴┤┌─────┘ "); + Write(0xcccccc, false, "| 13 "); + Write(0xffff66, false, "**\n "); + Write(0xcccccc, false, "| "); + Write(0xffff66, true, "*"); + Write(0x666666, false, "──"); + Write(0xff0000, false, "┤|├"); + Write(0x666666, false, "─┘┌─────────┴┬┬┬┬┘┌┤ V0├o┤ ├└┐┌──┬o "); + Write(0xcccccc, false, "| 12 "); + Write(0xffff66, false, "**\n "); + Write(0xcccccc, false, "| "); + Write(0x666666, false, "├──────"); + Write(0xffff66, true, "*"); + Write(0x666666, false, "└───────┬───┴o└┐└┤ R0├─┤ A├o│├─o└┐ "); + Write(0xcccccc, false, "| 11 "); + Write(0xffff66, false, "**\n "); + Write(0xcccccc, false, "| "); + Write(0x666666, false, "└─────o└───────"); + Write(0xffff66, true, "*"); + Write(0x666666, false, "└─┐┌───┴o┤ ├─┤ L├─┘=┌──┘ "); + Write(0xcccccc, false, "| 10 "); + Write(0xffff66, false, "**\n "); + Write(0xcccccc, false, "| "); + Write(0xffff66, true, "*"); + Write(0x666666, false, "────┬┴┴┴┴┬────┘┌─┘└─────┴┬┬┬┬┬┴┐┤ U├──┐└──┐ "); + Write(0xcccccc, false, "| 9 "); + Write(0xffff66, false, "**\n "); + Write(0xcccccc, false, "| "); + Write(0x666666, false, "├────┤ ├─"); + Write(0xffff66, true, "*"); + Write(0x666666, false, "o──┴─┐┌─────────┴─┐└┴┬┬┬┴──┘┌──┘ "); + Write(0xcccccc, false, "| 8 "); + Write(0xffff66, false, "**\n "); + Write(0xcccccc, false, "| "); + Write(0x666666, false, "└─o"); + Write(0xffff66, true, "*"); + Write(0x666666, false, "─┤PR2A├┐└────┐=└┐o──────┬──┘o┐┌┘o────┴──┐ "); + Write(0xcccccc, false, "| 7 "); + Write(0xffff66, false, "**\n "); + Write(0xcccccc, false, "| "); + Write(0x666666, false, "┌──┘┌┤ 03G├┴─────┘┌"); + Write(0xffff66, true, "*"); + Write(0x666666, false, "└─────┬┐└────┤└─────────┤ "); + Write(0xcccccc, false, "| 6 "); + Write(0xffff66, false, "**\n "); + Write(0xcccccc, false, "| "); + Write(0x666666, false, "├───┴┴┬┬┬┬┴───"); + Write(0xff9900, false, "∧∧∧"); + Write(0x666666, false, "─┘└─"); + Write(0x990099, false, "┤[]├"); + Write(0xffff66, true, "*"); + Write(0x666666, false, "│└──┐o─┴─────────o│ "); + Write(0xcccccc, false, "| 5 "); + Write(0xffff66, false, "**\n "); + Write(0xcccccc, false, "| "); + Write(0x666666, false, "└┐o┐"); + Write(0xffff66, true, "*"); + Write(0x666666, false, "─────────"); + Write(0xff9900, false, "∧∧∧"); + Write(0x666666, false, "────────┘└┐o┐└─────────────┘ "); + Write(0xcccccc, false, "| 4 "); + Write(0xffff66, false, "**\n "); + Write(0xcccccc, false, "| "); + Write(0x666666, false, "o┴─┘└──────────"); + Write(0xffff66, true, "*"); + Write(0x666666, false, "┌────┬────o└─┴┐┌──────┐o────┐ "); + Write(0xcccccc, false, "| 3 "); + Write(0xffff66, false, "**\n "); + Write(0xcccccc, false, "| "); + Write(0xffff66, true, "*"); + Write(0x666666, false, "──────────────┘└───o└─┬─────┐│└─┐┌──┐└─────┤ "); + Write(0xcccccc, false, "| 2 "); + Write(0xffff66, false, "**\n "); + Write(0xcccccc, false, "| "); + Write(0x666666, false, "└───────────"); + Write(0x66ff, false, "|("); + Write(0x666666, false, "─"); + Write(0xff9900, false, "∧∧∧"); + Write(0x666666, false, "────"); + Write(0xffff66, true, "*"); + Write(0x666666, false, "└────o└┴──┘└─o└──────┘ "); + Write(0xcccccc, false, "| 1 "); + Write(0xffff66, false, "**\n "); + Write(0xcccccc, false, "'-----------------------------------------------' \n \n"); + Console.ForegroundColor = color; Console.WriteLine(); } - private static void Write(int rgb, bool bold, string text){ + private static void Write(int rgb, bool bold, string text){ Console.Write($"\u001b[38;2;{(rgb>>16)&255};{(rgb>>8)&255};{rgb&255}{(bold ? ";1" : "")}m{text}"); - } -} \ No newline at end of file + } +} diff --git a/2017/calendar.svg b/2017/calendar.svg index 8c532d567..8d60d9172 100644 --- a/2017/calendar.svg +++ b/2017/calendar.svg @@ -1,55 +1,55 @@ - - - + + + ▄█▄ ▄▄█ ▄ ▄ ▄▄▄ ▄▄ ▄█▄  ▄▄▄ ▄█  ▄▄ ▄▄▄ ▄▄█ ▄▄▄ █▄█ █ █ █ █ █▄█ █ █ █   █ █ █▄  █  █ █ █ █ █▄█ -█ █ █▄█ ▀▄▀ █▄▄ █ █ █▄  █▄█ █   █▄ █▄█ █▄█ █▄▄  {'year': 2017} +█ █ █▄█ ▀▄▀ █▄▄ █ █ █▄  █▄█ █   █▄ █▄█ █▄█ █▄▄  0x0000 | 2017   -|O|        Naughty      |        Nice         |O|        -|O|  -------------------+-------------------  |O|        -|O|  The Easter Bunny   | encse               |O|        -|O|  Martin Galese      | Szabolcs Sipos      |O|        -|O|  Balázs Dankó       | wesen               |O|        -|O|  Gábor Gyebnár      | Daniel Willenson    |O|        -|O|  Woodrow Hedberg    | gkatai              |O|        -.-----------------------------------------------.        -| o*[]o |  25 ** -| oTo*o |  24 ** -| *|(oo |  23 ** -| |*ooo |  22 ** -| *[][]  DY |  21 ** -|   EP[]*o |  20 ** -|   CTVoo* |  19 ** -|   RRoo* |  18 ** -|     o 30* |  17 ** -| o* 29 |  16 ** -| *o 83 |  15 ** -| o    *o P6 |  14 ** -| oTo    oo* |  13 ** -| o v17*[] |  12 ** -| |(*oV |  11 ** -|      * |  10 ** -|      * |   9 ** -|    5 o*o|( |   8 ** -| *   1Po|(oo |   7 ** -|    2B*o |   6 ** -| o* |   5 ** -| Vo*o |   4 ** -| |o* |   3 ** -| o* |   2 ** -| o*oo |   1 ** -'-----------------------------------------------'        +|O|        Naughty      |        Nice         |O|        +|O|  -------------------+-------------------  |O|        +|O|  The Easter Bunny   | encse               |O|        +|O|  lizthegrey         | Kevin Yap           |O|        +|O|  Mihai Maruseac     | Jean-Noël Monette   |O|        +|O|  jweinberg          | Joe LeGasse         |O|        +|O|  zenithlight        | Christopher Lorton  |O|        +.-----------------------------------------------.        +| o[]ooTo* |  25 ** +| oo*oTo |  24 ** +| oo|* |  23 ** +| ooo* |  22 ** +| |(|(* |  21 ** +| []o*|( |  20 ** +| o*|o |  19 ** +| *   |(o |  18 ** +| *   |o |  17 ** +| *   []o |  16 ** +| o*     |  15 ** +| *NAND    4 |  14 ** +| *oGATE    3 |  13 ** +| *|   V0o   o |  12 ** +| *o   R0  Aoo |  11 ** +| o*o       L= |  10 ** +| *  U |   9 ** +|     *o |   8 ** +| o*PR2A=ooo |   7 ** +|  03G* |   6 ** +| []*oo |   5 ** +| o*o |   4 ** +| o*oo |   3 ** +| *o |   2 ** +| |(*oo |   1 ** +'-----------------------------------------------'        - \ No newline at end of file + \ No newline at end of file diff --git a/2018/Day01/README.md b/2018/Day01/README.md index 8ccecebb9..51dad7315 100644 --- a/2018/Day01/README.md +++ b/2018/Day01/README.md @@ -1,6 +1,59 @@ +original source: [https://adventofcode.com/2018/day/1](https://adventofcode.com/2018/day/1) ## --- Day 1: Chronal Calibration --- "We've detected some temporal anomalies," one of Santa's Elves at the Temporal Anomaly Research and Detection Instrument Station tells you. She sounded pretty worried when she called you down here. "At 500-year intervals into the past, someone has been changing Santa's history!" "The good news is that the changes won't propagate to our time stream for another 25 days, and we have a device" - she attaches something to your wrist - "that will let you fix the changes with no such propagation delay. It's configured to send you 500 years further into the past every few days; that was the best we could do on such short notice." -_Visit the website for the full story and [full puzzle](https://adventofcode.com/2018/day/1) description._ +"The bad news is that we are detecting roughly fifty anomalies throughout time; the device will indicate fixed anomalies with stars. The other bad news is that we only have one device and you're the best person for the job! Good lu--" She taps a button on the device and you suddenly feel like you're falling. To save Christmas, you need to get all fifty stars by December 25th. + +Collect stars by solving puzzles. Two puzzles will be made available on each day in the Advent calendar; the second puzzle is unlocked when you complete the first. Each puzzle grants one star. Good luck! + +After feeling like you've been falling for a few minutes, you look at the device's tiny screen. "Error: Device must be calibrated before first use. Frequency drift detected. Cannot maintain destination lock." Below the message, the device shows a sequence of changes in frequency (your puzzle input). A value like +6 means the current frequency increases by 6; a value like -3 means the current frequency decreases by 3. + +For example, if the device displays frequency changes of +1, -2, +3, +1, then starting from a frequency of zero, the following changes would occur: + + + - Current frequency  0, change of +1; resulting frequency  1. + - Current frequency  1, change of -2; resulting frequency -1. + - Current frequency -1, change of +3; resulting frequency  2. + - Current frequency  2, change of +1; resulting frequency  3. + +In this example, the resulting frequency is 3. + +Here are other example situations: + + + - +1, +1, +1 results in  3 + - +1, +1, -2 results in  0 + - -1, -2, -3 results in -6 + +Starting with a frequency of zero, what is the resulting frequency after all of the changes in frequency have been applied? + + +## --- Part Two --- +You notice that the device repeats the same frequency change list over and over. To calibrate the device, you need to find the first frequency it reaches twice. + +For example, using the same list of changes above, the device would loop as follows: + + + - Current frequency  0, change of +1; resulting frequency  1. + - Current frequency  1, change of -2; resulting frequency -1. + - Current frequency -1, change of +3; resulting frequency  2. + - Current frequency  2, change of +1; resulting frequency  3. + - (At this point, the device continues from the start of the list.) + - Current frequency  3, change of +1; resulting frequency  4. + - Current frequency  4, change of -2; resulting frequency  2, which has already been seen. + +In this example, the first frequency reached twice is 2. Note that your device might need to repeat its list of frequency changes many times before a duplicate frequency is found, and that duplicates might be found while in the middle of processing the list. + +Here are other examples: + + + - +1, -1 first reaches 0 twice. + - +3, +3, +4, -2, -4 first reaches 10 twice. + - -6, +3, +8, +5, -6 first reaches 5 twice. + - +7, +7, -2, -7, -4 first reaches 14 twice. + +What is the first frequency your device reaches twice? + + diff --git a/2018/Day01/input.in b/2018/Day01/input.in index 8103c3057..15d2c6e20 100644 Binary files a/2018/Day01/input.in and b/2018/Day01/input.in differ diff --git a/2018/Day02/README.md b/2018/Day02/README.md index 920cce933..dccfa211d 100644 --- a/2018/Day02/README.md +++ b/2018/Day02/README.md @@ -1,6 +1,48 @@ +original source: [https://adventofcode.com/2018/day/2](https://adventofcode.com/2018/day/2) ## --- Day 2: Inventory Management System --- You stop falling through time, catch your breath, and check the screen on the device. "Destination reached. Current Year: 1518. Current Location: North Pole Utility Closet 83N10." You made it! Now, to find those anomalies. Outside the utility closet, you hear footsteps and a voice. "...I'm not sure either. But now that so many people have chimneys, maybe he could sneak in that way?" Another voice responds, "Actually, we've been working on a new kind of *suit* that would let him fit through tight spaces like that. But, I heard that a few days ago, they lost the prototype fabric, the design plans, everything! Nobody on the team can even seem to remember important details of the project!" -Read the [full puzzle](https://adventofcode.com/2018/day/2). \ No newline at end of file +"Wouldn't they have had enough fabric to fill several boxes in the warehouse? They'd be stored together, so the box IDs should be similar. Too bad it would take forever to search the warehouse for *two similar box IDs*..." They walk too far away to hear any more. + +Late at night, you sneak to the warehouse - who knows what kinds of paradoxes you could cause if you were discovered - and use your fancy wrist device to quickly scan every box and produce a list of the likely candidates (your puzzle input). + +To make sure you didn't miss any, you scan the likely candidate boxes again, counting the number that have an ID containing *exactly two of any letter* and then separately counting those with *exactly three of any letter*. You can multiply those two counts together to get a rudimentary [checksum](https://en.wikipedia.org/wiki/Checksum) and compare it to what your device predicts. + +For example, if you see the following box IDs: + + + - `abcdef` contains no letters that appear exactly two or three times. + - `bababc` contains two `a` and three `b`, so it counts for both. + - `abbcde` contains two `b`, but no letter appears exactly three times. + - `abcccd` contains three `c`, but no letter appears exactly two times. + - `aabcdd` contains two `a` and two `d`, but it only counts once. + - `abcdee` contains two `e`. + - `ababab` contains three `a` and three `b`, but it only counts once. + +Of these box IDs, four of them contain a letter which appears exactly twice, and three of them contain a letter which appears exactly three times. Multiplying these together produces a checksum of `4 * 3 = 12`. + +*What is the checksum* for your list of box IDs? + + +## --- Part Two --- +Confident that your list of box IDs is complete, you're ready to find the boxes full of prototype fabric. + +The boxes will have IDs which differ by exactly one character at the same position in both strings. For example, given the following box IDs: + +``` +abcde +fghij +klmno +pqrst +fguij +axcye +wvxyz +``` + +The IDs `abcde` and `axcye` are close, but they differ by two characters (the second and fourth). However, the IDs `fghij` and `fguij` differ by exactly one character, the third (`h` and `u`). Those must be the correct boxes. + +*What letters are common between the two correct box IDs?* (In the example above, this is found by removing the differing character from either ID, producing `fgij`.) + + diff --git a/2018/Day02/input.in b/2018/Day02/input.in index dc37cf34f..cdcf84ba7 100644 Binary files a/2018/Day02/input.in and b/2018/Day02/input.in differ diff --git a/2018/Day03/README.md b/2018/Day03/README.md index cc4dad2c6..099b90d08 100644 --- a/2018/Day03/README.md +++ b/2018/Day03/README.md @@ -1,6 +1,62 @@ +original source: [https://adventofcode.com/2018/day/3](https://adventofcode.com/2018/day/3) ## --- Day 3: No Matter How You Slice It --- The Elves managed to locate the chimney-squeeze prototype fabric for Santa's suit (thanks to someone who helpfully wrote its box IDs on the wall of the warehouse in the middle of the night). Unfortunately, anomalies are still affecting them - nobody can even agree on how to *cut* the fabric. The whole piece of fabric they're working on is a very large square - at least `1000` inches on each side. -Read the [full puzzle](https://adventofcode.com/2018/day/3). \ No newline at end of file +Each Elf has made a *claim* about which area of fabric would be ideal for Santa's suit. All claims have an ID and consist of a single rectangle with edges parallel to the edges of the fabric. Each claim's rectangle is defined as follows: + + + - The number of inches between the left edge of the fabric and the left edge of the rectangle. + - The number of inches between the top edge of the fabric and the top edge of the rectangle. + - The width of the rectangle in inches. + - The height of the rectangle in inches. + +A claim like `#123 @ 3,2: 5x4` means that claim ID `123` specifies a rectangle `3` inches from the left edge, `2` inches from the top edge, `5` inches wide, and `4` inches tall. Visually, it claims the square inches of fabric represented by `#` (and ignores the square inches of fabric represented by `.`) in the diagram below: + +``` +........... +........... +...#####... +...#####... +...#####... +...#####... +........... +........... +........... +``` + +The problem is that many of the claims *overlap*, causing two or more claims to cover part of the same areas. For example, consider the following claims: + +``` +#1 @ 1,3: 4x4 +#2 @ 3,1: 4x4 +#3 @ 5,5: 2x2 +``` + +Visually, these claim the following areas: + +``` +........ +...2222. +...2222. +.11XX22. +.11XX22. +.111133. +.111133. +........ +``` + +The four square inches marked with `X` are claimed by *both `1` and `2`*. (Claim `3`, while adjacent to the others, does not overlap either of them.) + +If the Elves all proceed with their own plans, none of them will have enough fabric. *How many square inches of fabric are within two or more claims?* + + +## --- Part Two --- +Amidst the chaos, you notice that exactly one claim doesn't overlap by even a single square inch of fabric with any other claim. If you can somehow draw attention to it, maybe the Elves will be able to make Santa's suit after all! + +For example, in the claims above, only claim `3` is intact after all claims are made. + +*What is the ID of the only claim that doesn't overlap?* + + diff --git a/2018/Day03/input.in b/2018/Day03/input.in index ad9827ff8..c98e5a018 100644 Binary files a/2018/Day03/input.in and b/2018/Day03/input.in differ diff --git a/2018/Day04/README.md b/2018/Day04/README.md index 043e4e5a5..b8ee6f39b 100644 --- a/2018/Day04/README.md +++ b/2018/Day04/README.md @@ -1,6 +1,66 @@ +original source: [https://adventofcode.com/2018/day/4](https://adventofcode.com/2018/day/4) ## --- Day 4: Repose Record --- You've sneaked into another supply closet - this time, it's across from the prototype suit manufacturing lab. You need to sneak inside and fix the issues with the suit, but there's a guard stationed outside the lab, so this is as close as you can safely get. As you search the closet for anything that might help, you discover that you're not the first person to want to sneak in. Covering the walls, someone has spent an hour starting every midnight for the past few months secretly observing this guard post! They've been writing down the ID of *the one guard on duty that night* - the Elves seem to have decided that one guard was enough for the overnight shift - as well as when they fall asleep or wake up while at their post (your puzzle input). -Read the [full puzzle](https://adventofcode.com/2018/day/4). \ No newline at end of file +For example, consider the following records, which have already been organized into chronological order: + +``` +[1518-11-01 00:00] Guard #10 begins shift +[1518-11-01 00:05] falls asleep +[1518-11-01 00:25] wakes up +[1518-11-01 00:30] falls asleep +[1518-11-01 00:55] wakes up +[1518-11-01 23:58] Guard #99 begins shift +[1518-11-02 00:40] falls asleep +[1518-11-02 00:50] wakes up +[1518-11-03 00:05] Guard #10 begins shift +[1518-11-03 00:24] falls asleep +[1518-11-03 00:29] wakes up +[1518-11-04 00:02] Guard #99 begins shift +[1518-11-04 00:36] falls asleep +[1518-11-04 00:46] wakes up +[1518-11-05 00:03] Guard #99 begins shift +[1518-11-05 00:45] falls asleep +[1518-11-05 00:55] wakes up +``` + +Timestamps are written using `year-month-day hour:minute` format. The guard falling asleep or waking up is always the one whose shift most recently started. Because all asleep/awake times are during the midnight hour (`00:00` - `00:59`), only the minute portion (`00` - `59`) is relevant for those events. + +Visually, these records show that the guards are asleep at these times: + +``` +Date ID Minute + 000000000011111111112222222222333333333344444444445555555555 + 012345678901234567890123456789012345678901234567890123456789 +11-01 #10 .....####################.....#########################..... +11-02 #99 ........................................##########.......... +11-03 #10 ........................#####............................... +11-04 #99 ....................................##########.............. +11-05 #99 .............................................##########..... +``` + +The columns are Date, which shows the month-day portion of the relevant day; ID, which shows the guard on duty that day; and Minute, which shows the minutes during which the guard was asleep within the midnight hour. (The Minute column's header shows the minute's ten's digit in the first row and the one's digit in the second row.) Awake is shown as `.`, and asleep is shown as `#`. + +Note that guards count as asleep on the minute they fall asleep, and they count as awake on the minute they wake up. For example, because Guard #10 wakes up at 00:25 on 1518-11-01, minute 25 is marked as awake. + +If you can figure out the guard most likely to be asleep at a specific time, you might be able to trick that guard into working tonight so you can have the best chance of sneaking in. You have two strategies for choosing the best guard/minute combination. + +*Strategy 1:* Find the guard that has the most minutes asleep. What minute does that guard spend asleep the most? + +In the example above, Guard #10 spent the most minutes asleep, a total of 50 minutes (20+25+5), while Guard #99 only slept for a total of 30 minutes (10+10+10). Guard #*10* was asleep most during minute *24* (on two days, whereas any other minute the guard was asleep was only seen on one day). + +While this example listed the entries in chronological order, your entries are in the order you found them. You'll need to organize them before they can be analyzed. + +*What is the ID of the guard you chose multiplied by the minute you chose?* (In the above example, the answer would be `10 * 24 = 240`.) + + +## --- Part Two --- +*Strategy 2:* Of all guards, which guard is most frequently asleep on the same minute? + +In the example above, Guard #*99* spent minute *45* asleep more than any other guard or minute - three times in total. (In all other cases, any guard spent any minute asleep at most twice.) + +*What is the ID of the guard you chose multiplied by the minute you chose?* (In the above example, the answer would be `99 * 45 = 4455`.) + + diff --git a/2018/Day04/input.in b/2018/Day04/input.in index 3675066b8..aba0f2c3d 100644 Binary files a/2018/Day04/input.in and b/2018/Day04/input.in differ diff --git a/2018/Day05/README.md b/2018/Day05/README.md index 09a32c2e7..9699efa23 100644 --- a/2018/Day05/README.md +++ b/2018/Day05/README.md @@ -1,6 +1,48 @@ +original source: [https://adventofcode.com/2018/day/5](https://adventofcode.com/2018/day/5) ## --- Day 5: Alchemical Reduction --- You've managed to sneak in to the prototype suit manufacturing lab. The Elves are making decent progress, but are still struggling with the suit's size reduction capabilities. While the very latest in 1518 alchemical technology might have solved their problem eventually, you can do better. You scan the chemical composition of the suit's material and discover that it is formed by extremely long [polymers](https://en.wikipedia.org/wiki/Polymer) (one of which is available as your puzzle input). -Read the [full puzzle](https://adventofcode.com/2018/day/5). \ No newline at end of file +The polymer is formed by smaller *units* which, when triggered, react with each other such that two adjacent units of the same type and opposite polarity are destroyed. Units' types are represented by letters; units' polarity is represented by capitalization. For instance, `r` and `R` are units with the same type but opposite polarity, whereas `r` and `s` are entirely different types and do not react. + +For example: + + + - In `aA`, `a` and `A` react, leaving nothing behind. + - In `abBA`, `bB` destroys itself, leaving `aA`. As above, this then destroys itself, leaving nothing. + - In `abAB`, no two adjacent units are of the same type, and so nothing happens. + - In `aabAAB`, even though `aa` and `AA` are of the same type, their polarities match, and so nothing happens. + +Now, consider a larger example, `dabAcCaCBAcCcaDA`: + +``` +dabA*cC*aCBAcCcaDA The first 'cC' is removed. +dab*Aa*CBAcCcaDA This creates 'Aa', which is removed. +dabCBA*cCc*aDA Either 'cC' or 'Cc' are removed (the result is the same). +dabCBAcaDA No further actions can be taken. +``` + +After all possible reactions, the resulting polymer contains *10 units*. + +*How many units remain after fully reacting the polymer you scanned?* (Note: in this puzzle and others, the input is large; if you copy/paste your input, make sure you get the whole thing.) + + +## --- Part Two --- +Time to improve the polymer. + +One of the unit types is causing problems; it's preventing the polymer from collapsing as much as it should. Your goal is to figure out which unit type is causing the most problems, remove all instances of it (regardless of polarity), fully react the remaining polymer, and measure its length. + +For example, again using the polymer `dabAcCaCBAcCcaDA` from above: + + + - Removing all `A`/`a` units produces `dbcCCBcCcD`. Fully reacting this polymer produces `dbCBcD`, which has length 6. + - Removing all `B`/`b` units produces `daAcCaCAcCcaDA`. Fully reacting this polymer produces `daCAcaDA`, which has length 8. + - Removing all `C`/`c` units produces `dabAaBAaDA`. Fully reacting this polymer produces `daDA`, which has length 4. + - Removing all `D`/`d` units produces `abAcCaCBAcCcaA`. Fully reacting this polymer produces `abCBAc`, which has length 6. + +In this example, removing all `C`/`c` units was best, producing the answer *4*. + +*What is the length of the shortest polymer you can produce* by removing all units of exactly one type and fully reacting the result? + + diff --git a/2018/Day05/input.in b/2018/Day05/input.in index c23e0782e..0fec35f2d 100644 Binary files a/2018/Day05/input.in and b/2018/Day05/input.in differ diff --git a/2018/Day06/README.md b/2018/Day06/README.md index 47db579bb..ee1d138fc 100644 --- a/2018/Day06/README.md +++ b/2018/Day06/README.md @@ -1,6 +1,98 @@ +original source: [https://adventofcode.com/2018/day/6](https://adventofcode.com/2018/day/6) ## --- Day 6: Chronal Coordinates --- The device on your wrist beeps several times, and once again you feel like you're falling. "Situation critical," the device announces. "Destination indeterminate. Chronal interference detected. Please specify new target coordinates." -Read the [full puzzle](https://adventofcode.com/2018/day/6). \ No newline at end of file +The device then produces a list of coordinates (your puzzle input). Are they places it thinks are safe or dangerous? It recommends you check manual page 729. The Elves did not give you a manual. + +*If they're dangerous,* maybe you can minimize the danger by finding the coordinate that gives the largest distance from the other points. + +Using only the [Manhattan distance](https://en.wikipedia.org/wiki/Taxicab_geometry), determine the *area* around each coordinate by counting the number of [integer](https://en.wikipedia.org/wiki/Integer) X,Y locations that are *closest* to that coordinate (and aren't *tied in distance* to any other coordinate). + +Your goal is to find the size of the *largest area* that isn't infinite. For example, consider the following list of coordinates: + +``` +1, 1 +1, 6 +8, 3 +3, 4 +5, 5 +8, 9 +``` + +If we name these coordinates `A` through `F`, we can draw them on a grid, putting `0,0` at the top left: + +``` +.......... +.A........ +.......... +........C. +...D...... +.....E.... +.B........ +.......... +.......... +........F. +``` + +This view is partial - the actual grid extends infinitely in all directions. Using the Manhattan distance, each location's closest coordinate can be determined, shown here in lowercase: + +``` +aaaaa.cccc +a*A*aaa.cccc +aaaddecccc +aadddecc*C*c +..d*D*deeccc +bb.de*E*eecc +b*B*b.eeee.. +bbb.eeefff +bbb.eeffff +bbb.ffff*F*f +``` + +Locations shown as `.` are equally far from two or more coordinates, and so they don't count as being closest to any. + +In this example, the areas of coordinates A, B, C, and F are infinite - while not shown here, their areas extend forever outside the visible grid. However, the areas of coordinates D and E are finite: D is closest to 9 locations, and E is closest to 17 (both including the coordinate's location itself). Therefore, in this example, the size of the largest area is *17*. + +*What is the size of the largest area* that isn't infinite? + + +## --- Part Two --- +On the other hand, *if the coordinates are safe*, maybe the best you can do is try to find a *region* near as many coordinates as possible. + +For example, suppose you want the sum of the [Manhattan distance](https://en.wikipedia.org/wiki/Taxicab_geometry) to all of the coordinates to be *less than 32*. For each location, add up the distances to all of the given coordinates; if the total of those distances is less than 32, that location is within the desired region. Using the same coordinates as above, the resulting region looks like this: + +``` +.......... +.A........ +.......... +...#*#*#..C. +..#D###... +..###E#... +.B.###.... +.......... +.......... +........F. +``` + +In particular, consider the highlighted location `4,3` located at the top middle of the region. Its calculation is as follows, where `abs()` is the [absolute value](https://en.wikipedia.org/wiki/Absolute_value) function: + + + - Distance to coordinate A: `abs(4-1) + abs(3-1) =  5` + - Distance to coordinate B: `abs(4-1) + abs(3-6) =  6` + - Distance to coordinate C: `abs(4-8) + abs(3-3) =  4` + - Distance to coordinate D: `abs(4-3) + abs(3-4) =  2` + - Distance to coordinate E: `abs(4-5) + abs(3-5) =  3` + - Distance to coordinate F: `abs(4-8) + abs(3-9) = 10` + - Total distance: `5 + 6 + 4 + 2 + 3 + 10 = 30` + +Because the total distance to all coordinates (`30`) is less than 32, the location is *within* the region. + +This region, which also includes coordinates D and E, has a total size of *16*. + +Your actual region will need to be much larger than this example, though, instead including all locations with a total distance of less than *10000*. + +*What is the size of the region containing all locations which have a total distance to all given coordinates of less than 10000?* + + diff --git a/2018/Day06/input.in b/2018/Day06/input.in index 54e5710fd..e07e4ab45 100644 Binary files a/2018/Day06/input.in and b/2018/Day06/input.in differ diff --git a/2018/Day07/README.md b/2018/Day07/README.md index 2dd1cc983..c276ae386 100644 --- a/2018/Day07/README.md +++ b/2018/Day07/README.md @@ -1,6 +1,84 @@ +original source: [https://adventofcode.com/2018/day/7](https://adventofcode.com/2018/day/7) ## --- Day 7: The Sum of Its Parts --- You find yourself standing on a snow-covered coastline; apparently, you landed a little off course. The region is too hilly to see the North Pole from here, but you do spot some Elves that seem to be trying to unpack something that washed ashore. It's quite cold out, so you decide to risk creating a paradox by asking them for directions. "Oh, are you the search party?" Somehow, you can understand whatever Elves from the year 1018 speak; you assume it's [Ancient Nordic Elvish](/2015/day/6). Could the device on your wrist also be a translator? "Those clothes don't look very warm; take this." They hand you a heavy coat. -Read the [full puzzle](https://adventofcode.com/2018/day/7). \ No newline at end of file +"We do need to find our way back to the North Pole, but we have higher priorities at the moment. You see, believe it or not, this box contains something that will solve all of Santa's transportation problems - at least, that's what it looks like from the pictures in the instructions." It doesn't seem like they can read whatever language it's in, but you can: "Sleigh kit. Some assembly required." + +"'Sleigh'? What a wonderful name! You must help us assemble this 'sleigh' at once!" They start excitedly pulling more parts out of the box. + +The instructions specify a series of *steps* and requirements about which steps must be finished before others can begin (your puzzle input). Each step is designated by a single letter. For example, suppose you have the following instructions: + +``` +Step C must be finished before step A can begin. +Step C must be finished before step F can begin. +Step A must be finished before step B can begin. +Step A must be finished before step D can begin. +Step B must be finished before step E can begin. +Step D must be finished before step E can begin. +Step F must be finished before step E can begin. +``` + +Visually, these requirements look like this: + +``` + + -->A--->B-- + / \ \ +C -->D----->E + \ / + ---->F----- +``` + +Your first goal is to determine the order in which the steps should be completed. If more than one step is ready, choose the step which is first alphabetically. In this example, the steps would be completed as follows: + + + - Only *`C`* is available, and so it is done first. + - Next, both `A` and `F` are available. *`A`* is first alphabetically, so it is done next. + - Then, even though `F` was available earlier, steps `B` and `D` are now also available, and *`B`* is the first alphabetically of the three. + - After that, only `D` and `F` are available. `E` is not available because only some of its prerequisites are complete. Therefore, *`D`* is completed next. + - *`F`* is the only choice, so it is done next. + - Finally, *`E`* is completed. + +So, in this example, the correct order is *`CABDFE`*. + +*In what order should the steps in your instructions be completed?* + + +## --- Part Two --- +As you're about to begin construction, four of the Elves offer to help. "The sun will set soon; it'll go faster if we work together." Now, you need to account for multiple people working on steps simultaneously. If multiple steps are available, workers should still begin them in alphabetical order. + +Each step takes 60 seconds plus an amount corresponding to its letter: A=1, B=2, C=3, and so on. So, step A takes `60+1=61` seconds, while step Z takes `60+26=86` seconds. No time is required between steps. + +To simplify things for the example, however, suppose you only have help from one Elf (a total of two workers) and that each step takes 60 fewer seconds (so that step A takes 1 second and step Z takes 26 seconds). Then, using the same instructions as above, this is how each second would be spent: + +``` +Second Worker 1 Worker 2 Done + 0 C . + 1 C . + 2 C . + 3 A F C + 4 B F CA + 5 B F CA + 6 D F CAB + 7 D F CAB + 8 D F CAB + 9 D . CABF + 10 E . CABFD + 11 E . CABFD + 12 E . CABFD + 13 E . CABFD + 14 E . CABFD + 15 . . CABFDE +``` + +Each row represents one second of time. The Second column identifies how many seconds have passed as of the beginning of that second. Each worker column shows the step that worker is currently doing (or `.` if they are idle). The Done column shows completed steps. + +Note that the order of the steps has changed; this is because steps now take time to finish and multiple workers can begin multiple steps simultaneously. + +In this example, it would take *15* seconds for two workers to complete these steps. + +With *5* workers and the *60+ second* step durations described above, *how long will it take to complete all of the steps?* + + diff --git a/2018/Day07/input.in b/2018/Day07/input.in index 414e2d7a2..702dcba34 100644 Binary files a/2018/Day07/input.in and b/2018/Day07/input.in differ diff --git a/2018/Day08/README.md b/2018/Day08/README.md index 8e314227d..c57df8de9 100644 --- a/2018/Day08/README.md +++ b/2018/Day08/README.md @@ -1,6 +1,63 @@ +original source: [https://adventofcode.com/2018/day/8](https://adventofcode.com/2018/day/8) ## --- Day 8: Memory Maneuver --- The sleigh is much easier to pull than you'd expect for something its weight. Unfortunately, neither you nor the Elves know which way the North Pole is from here. You check your wrist device for anything that might help. It seems to have some kind of navigation system! Activating the navigation system produces more bad news: "Failed to start navigation system. Could not read software license file." -Read the [full puzzle](https://adventofcode.com/2018/day/8). \ No newline at end of file +The navigation system's license file consists of a list of numbers (your puzzle input). The numbers define a data structure which, when processed, produces some kind of [tree](https://en.wikipedia.org/wiki/Tree_(data_structure)) that can be used to calculate the license number. + +The *tree* is made up of *nodes*; a single, outermost node forms the tree's *root*, and it contains all other nodes in the tree (or contains nodes that contain nodes, and so on). + +Specifically, a node consists of: + + + - A *header*, which is always exactly two numbers: + + - The quantity of child nodes. + - The quantity of metadata entries. + + - Zero or more *child nodes* (as specified in the header). + - One or more *metadata entries* (as specified in the header). + +Each child node is itself a node that has its own header, child nodes, and metadata. For example: + +``` +2 3 0 3 10 11 12 1 1 0 1 99 2 1 1 2 +A---------------------------------- + B----------- C----------- + D----- +``` + +In this example, each node of the tree is also marked with an underline starting with a letter for easier identification. In it, there are four nodes: + + + - `A`, which has `2` child nodes (`B`, `C`) and `3` metadata entries (`1`, `1`, `2`). + - `B`, which has `0` child nodes and `3` metadata entries (`10`, `11`, `12`). + - `C`, which has `1` child node (`D`) and `1` metadata entry (`2`). + - `D`, which has `0` child nodes and `1` metadata entry (`99`). + +The first check done on the license file is to simply add up all of the metadata entries. In this example, that sum is `1+1+2+10+11+12+2+99=*138*`. + +*What is the sum of all metadata entries?* + + +## --- Part Two --- +The second check is slightly more complicated: you need to find the value of the root node (`A` in the example above). + +The *value of a node* depends on whether it has child nodes. + +If a node has *no child nodes*, its value is the sum of its metadata entries. So, the value of node `B` is `10+11+12=33`, and the value of node `D` is `99`. + +However, if a node *does have child nodes*, the metadata entries become indexes which refer to those child nodes. A metadata entry of `1` refers to the first child node, `2` to the second, `3` to the third, and so on. The value of this node is the sum of the values of the child nodes referenced by the metadata entries. If a referenced child node does not exist, that reference is skipped. A child node can be referenced multiple time and counts each time it is referenced. A metadata entry of `0` does not refer to any child node. + +For example, again using the above nodes: + + + - Node `C` has one metadata entry, `2`. Because node `C` has only one child node, `2` references a child node which does not exist, and so the value of node `C` is `0`. + - Node `A` has three metadata entries: `1`, `1`, and `2`. The `1` references node `A`'s first child node, `B`, and the `2` references node `A`'s second child node, `C`. Because node B has a value of `33` and node `C` has a value of `0`, the value of node `A` is `33+33+0=*66*`. + +So, in this example, the value of the root node is `66`. + +*What is the value of the root node?* + + diff --git a/2018/Day08/input.in b/2018/Day08/input.in index 01888be79..6122a2b4a 100644 Binary files a/2018/Day08/input.in and b/2018/Day08/input.in differ diff --git a/2018/Day09/README.md b/2018/Day09/README.md index 750be53b5..a0ba94431 100644 --- a/2018/Day09/README.md +++ b/2018/Day09/README.md @@ -1,6 +1,63 @@ +original source: [https://adventofcode.com/2018/day/9](https://adventofcode.com/2018/day/9) ## --- Day 9: Marble Mania --- You talk to the Elves while you wait for your navigation system to initialize. To pass the time, they introduce you to their favorite [marble](https://en.wikipedia.org/wiki/Marble_(toy)) game. The Elves play this game by taking turns arranging the marbles in a *circle* according to very particular rules. The marbles are numbered starting with `0` and increasing by `1` until every marble has a number. -Read the [full puzzle](https://adventofcode.com/2018/day/9). \ No newline at end of file +First, the marble numbered `0` is placed in the circle. At this point, while it contains only a single marble, it is still a circle: the marble is both clockwise from itself and counter-clockwise from itself. This marble is designated the *current marble*. + +Then, each Elf takes a turn placing the *lowest-numbered remaining marble* into the circle between the marbles that are `1` and `2` marbles *clockwise* of the current marble. (When the circle is large enough, this means that there is one marble between the marble that was just placed and the current marble.) The marble that was just placed then becomes the *current marble*. + +However, if the marble that is about to be placed has a number which is a multiple of `23`, *something entirely different happens*. First, the current player keeps the marble they would have placed, adding it to their *score*. In addition, the marble `7` marbles *counter-clockwise* from the current marble is *removed* from the circle and *also* added to the current player's score. The marble located immediately *clockwise* of the marble that was removed becomes the new *current marble*. + +For example, suppose there are 9 players. After the marble with value `0` is placed in the middle, each player (shown in square brackets) takes a turn. The result of each of those turns would produce circles of marbles like this, where clockwise is to the right and the resulting current marble is in parentheses: + +``` +[-] *(0)* +[1] 0* (1)* +[2] 0* (2)* 1 +[3] 0 2 1* (3)* +[4] 0* (4)* 2 1 3 +[5] 0 4 2* (5)* 1 3 +[6] 0 4 2 5 1* (6)* 3 +[7] 0 4 2 5 1 6 3* (7)* +[8] 0* (8)* 4 2 5 1 6 3 7 +[9] 0 8 4* (9)* 2 5 1 6 3 7 +[1] 0 8 4 9 2*(10)* 5 1 6 3 7 +[2] 0 8 4 9 2 10 5*(11)* 1 6 3 7 +[3] 0 8 4 9 2 10 5 11 1*(12)* 6 3 7 +[4] 0 8 4 9 2 10 5 11 1 12 6*(13)* 3 7 +[5] 0 8 4 9 2 10 5 11 1 12 6 13 3*(14)* 7 +[6] 0 8 4 9 2 10 5 11 1 12 6 13 3 14 7*(15)* +[7] 0*(16)* 8 4 9 2 10 5 11 1 12 6 13 3 14 7 15 +[8] 0 16 8*(17)* 4 9 2 10 5 11 1 12 6 13 3 14 7 15 +[9] 0 16 8 17 4*(18)* 9 2 10 5 11 1 12 6 13 3 14 7 15 +[1] 0 16 8 17 4 18 9*(19)* 2 10 5 11 1 12 6 13 3 14 7 15 +[2] 0 16 8 17 4 18 9 19 2*(20)*10 5 11 1 12 6 13 3 14 7 15 +[3] 0 16 8 17 4 18 9 19 2 20 10*(21)* 5 11 1 12 6 13 3 14 7 15 +[4] 0 16 8 17 4 18 9 19 2 20 10 21 5*(22)*11 1 12 6 13 3 14 7 15 +[5] 0 16 8 17 4 18*(19)* 2 20 10 21 5 22 11 1 12 6 13 3 14 7 15 +[6] 0 16 8 17 4 18 19 2*(24)*20 10 21 5 22 11 1 12 6 13 3 14 7 15 +[7] 0 16 8 17 4 18 19 2 24 20*(25)*10 21 5 22 11 1 12 6 13 3 14 7 15 +``` + +The goal is to be the *player with the highest score* after the last marble is used up. Assuming the example above ends after the marble numbered `25`, the winning score is `23+9=*32*` (because player 5 kept marble `23` and removed marble `9`, while no other player got any points in this very short example game). + +Here are a few more examples: + + + - `10` players; last marble is worth `1618` points: high score is *`8317`* + - `13` players; last marble is worth `7999` points: high score is *`146373`* + - `17` players; last marble is worth `1104` points: high score is *`2764`* + - `21` players; last marble is worth `6111` points: high score is *`54718`* + - `30` players; last marble is worth `5807` points: high score is *`37305`* + +*What is the winning Elf's score?* + + +## --- Part Two --- +Amused by the speed of your answer, the Elves are curious: + +*What would the winning Elf's score be if the number of the last marble were 100 times larger?* + + diff --git a/2018/Day09/input.in b/2018/Day09/input.in index ec6953af2..fa06400e0 100644 Binary files a/2018/Day09/input.in and b/2018/Day09/input.in differ diff --git a/2018/Day10/README.md b/2018/Day10/README.md index 867a88d43..f8e8081c4 100644 --- a/2018/Day10/README.md +++ b/2018/Day10/README.md @@ -1,6 +1,155 @@ +original source: [https://adventofcode.com/2018/day/10](https://adventofcode.com/2018/day/10) ## --- Day 10: The Stars Align --- It's no use; your navigation system simply isn't capable of providing walking directions in the arctic circle, and certainly not in 1018. The Elves suggest an alternative. In times like these, North Pole rescue operations will arrange points of light in the sky to guide missing Elves back to base. Unfortunately, the message is easy to miss: the points move slowly enough that it takes hours to align them, but have so much momentum that they only stay aligned for a second. If you blink at the wrong time, it might be hours before another message appears. -Read the [full puzzle](https://adventofcode.com/2018/day/10). \ No newline at end of file +You can see these points of light floating in the distance, and record their position in the sky and their velocity, the relative change in position per second (your puzzle input). The coordinates are all given from your perspective; given enough time, those positions and velocities will move the points into a cohesive message! + +Rather than wait, you decide to fast-forward the process and calculate what the points will eventually spell. + +For example, suppose you note the following points: + +``` +position=< 9, 1> velocity=< 0, 2> +position=< 7, 0> velocity=<-1, 0> +position=< 3, -2> velocity=<-1, 1> +position=< 6, 10> velocity=<-2, -1> +position=< 2, -4> velocity=< 2, 2> +position=<-6, 10> velocity=< 2, -2> +position=< 1, 8> velocity=< 1, -1> +position=< 1, 7> velocity=< 1, 0> +position=<-3, 11> velocity=< 1, -2> +position=< 7, 6> velocity=<-1, -1> +position=<-2, 3> velocity=< 1, 0> +position=<-4, 3> velocity=< 2, 0> +position=<10, -3> velocity=<-1, 1> +position=< 5, 11> velocity=< 1, -2> +position=< 4, 7> velocity=< 0, -1> +position=< 8, -2> velocity=< 0, 1> +position=<15, 0> velocity=<-2, 0> +position=< 1, 6> velocity=< 1, 0> +position=< 8, 9> velocity=< 0, -1> +position=< 3, 3> velocity=<-1, 1> +position=< 0, 5> velocity=< 0, -1> +position=<-2, 2> velocity=< 2, 0> +position=< 5, -2> velocity=< 1, 2> +position=< 1, 4> velocity=< 2, 1> +position=<-2, 7> velocity=< 2, -2> +position=< 3, 6> velocity=<-1, -1> +position=< 5, 0> velocity=< 1, 0> +position=<-6, 0> velocity=< 2, 0> +position=< 5, 9> velocity=< 1, -2> +position=<14, 7> velocity=<-2, 0> +position=<-3, 6> velocity=< 2, -1> +``` + +Each line represents one point. Positions are given as `` pairs: X represents how far left (negative) or right (positive) the point appears, while Y represents how far up (negative) or down (positive) the point appears. + +At `0` seconds, each point has the position given. Each second, each point's velocity is added to its position. So, a point with velocity `<1, -2>` is moving to the right, but is moving upward twice as quickly. If this point's initial position were `<3, 9>`, after `3` seconds, its position would become `<6, 3>`. + +Over time, the points listed above would move like this: + +``` +Initially: +........#............. +................#..... +.........#.#..#....... +...................... +#..........#.#.......# +...............#...... +....#................. +..#.#....#............ +.......#.............. +......#............... +...#...#.#...#........ +....#..#..#.........#. +.......#.............. +...........#..#....... +#...........#......... +...#.......#.......... + +After 1 second: +...................... +...................... +..........#....#...... +........#.....#....... +..#.........#......#.. +...................... +......#............... +....##.........#...... +......#.#............. +.....##.##..#......... +........#.#........... +........#...#.....#... +..#...........#....... +....#.....#.#......... +...................... +...................... + +After 2 seconds: +...................... +...................... +...................... +..............#....... +....#..#...####..#.... +...................... +........#....#........ +......#.#............. +.......#...#.......... +.......#..#..#.#...... +....#....#.#.......... +.....#...#...##.#..... +........#............. +...................... +...................... +...................... + +After 3 seconds: +...................... +...................... +...................... +...................... +......#...#..###...... +......#...#...#....... +......#...#...#....... +......#####...#....... +......#...#...#....... +......#...#...#....... +......#...#...#....... +......#...#..###...... +...................... +...................... +...................... +...................... + +After 4 seconds: +...................... +...................... +...................... +............#......... +........##...#.#...... +......#.....#..#...... +.....#..##.##.#....... +.......##.#....#...... +...........#....#..... +..............#....... +....#......#...#...... +.....#.....##......... +...............#...... +...............#...... +...................... +...................... +``` + +After 3 seconds, the message appeared briefly: `*HI*`. Of course, your message will be much longer and will take many more seconds to appear. + +*What message will eventually appear in the sky?* + + +## --- Part Two --- +Good thing you didn't have to wait, because that would have taken a long time - much longer than the `*3*` seconds in the example above. + +Impressed by your sub-hour communication capabilities, the Elves are curious: *exactly how many seconds would they have needed to wait for that message to appear?* + + diff --git a/2018/Day10/input.in b/2018/Day10/input.in index e85ff3932..4682695d0 100644 Binary files a/2018/Day10/input.in and b/2018/Day10/input.in differ diff --git a/2018/Day11/README.md b/2018/Day11/README.md index 8f32d908b..a408531c8 100644 --- a/2018/Day11/README.md +++ b/2018/Day11/README.md @@ -1,6 +1,80 @@ +original source: [https://adventofcode.com/2018/day/11](https://adventofcode.com/2018/day/11) ## --- Day 11: Chronal Charge --- You watch the Elves and their sleigh fade into the distance as they head toward the North Pole. Actually, you're the one fading. The falling sensation returns. -Read the [full puzzle](https://adventofcode.com/2018/day/11). \ No newline at end of file +The low fuel warning light is illuminated on your wrist-mounted device. Tapping it once causes it to project a hologram of the situation: a *300x300* grid of fuel cells and their current power levels, some negative. You're not sure what negative power means in the context of time travel, but it can't be good. + +Each fuel cell has a coordinate ranging *from 1 to 300* in both the X (horizontal) and Y (vertical) direction. In `X,Y` notation, the top-left cell is `1,1`, and the top-right cell is `300,1`. + +The interface lets you select *any 3x3 square* of fuel cells. To increase your chances of getting to your destination, you decide to choose the 3x3 square with the *largest total power*. + +The power level in a given fuel cell can be found through the following process: + + + - Find the fuel cell's *rack ID*, which is its *X coordinate plus 10*. + - Begin with a power level of the *rack ID* times the *Y coordinate*. + - Increase the power level by the value of the *grid serial number* (your puzzle input). + - Set the power level to itself multiplied by the *rack ID*. + - Keep only the *hundreds digit* of the power level (so `12*3*45` becomes `3`; numbers with no hundreds digit become `0`). + - *Subtract 5* from the power level. + +For example, to find the power level of the fuel cell at `3,5` in a grid with serial number `8`: + + + - The rack ID is `3 + 10 = *13*`. + - The power level starts at `13 * 5 = *65*`. + - Adding the serial number produces `65 + 8 = *73*`. + - Multiplying by the rack ID produces `73 * 13 = *949*`. + - The hundreds digit of `*9*49` is `*9*`. + - Subtracting 5 produces `9 - 5 = *4*`. + +So, the power level of this fuel cell is `*4*`. + +Here are some more example power levels: + + + - Fuel cell at  `122,79`, grid serial number `57`: power level `-5`. + - Fuel cell at `217,196`, grid serial number `39`: power level  `0`. + - Fuel cell at `101,153`, grid serial number `71`: power level  `4`. + +Your goal is to find the 3x3 square which has the largest total power. The square must be entirely within the 300x300 grid. Identify this square using the `X,Y` coordinate of its *top-left fuel cell*. For example: + +For grid serial number `18`, the largest total 3x3 square has a top-left corner of `*33,45*` (with a total power of `29`); these fuel cells appear in the middle of this 5x5 region: + +``` +-2 -4 4 4 4 +-4 * 4 4 4 *-5 + 4 * 3 3 4 *-4 + 1 * 1 2 4 *-3 +-1 0 2 -5 -2 +``` + +For grid serial number `42`, the largest 3x3 square's top-left is `*21,61*` (with a total power of `30`); they are in the middle of this region: + +``` +-3 4 2 2 2 +-4 * 4 3 3 * 4 +-5 * 3 3 4 *-4 + 4 * 3 3 4 *-3 + 3 3 3 -5 -1 +``` + +*What is the `X,Y` coordinate of the top-left fuel cell of the 3x3 square with the largest total power?* + + +## --- Part Two --- +You discover a dial on the side of the device; it seems to let you select a square of *any size*, not just 3x3. Sizes from 1x1 to 300x300 are supported. + +Realizing this, you now must find the *square of any size with the largest total power*. Identify this square by including its size as a third parameter after the top-left coordinate: a 9x9 square with a top-left corner of `3,5` is identified as `3,5,9`. + +For example: + + + - For grid serial number `18`, the largest total square (with a total power of `113`) is 16x16 and has a top-left corner of `90,269`, so its identifier is `*90,269,16*`. + - For grid serial number `42`, the largest total square (with a total power of `119`) is 12x12 and has a top-left corner of `232,251`, so its identifier is `*232,251,12*`. + +*What is the `X,Y,size` identifier of the square with the largest total power?* + + diff --git a/2018/Day11/input.in b/2018/Day11/input.in index 77e59ecee..21ad3efd9 100644 Binary files a/2018/Day11/input.in and b/2018/Day11/input.in differ diff --git a/2018/Day12/README.md b/2018/Day12/README.md index 267227936..4b1069225 100644 --- a/2018/Day12/README.md +++ b/2018/Day12/README.md @@ -1,6 +1,81 @@ +original source: [https://adventofcode.com/2018/day/12](https://adventofcode.com/2018/day/12) ## --- Day 12: Subterranean Sustainability --- The year 518 is significantly more underground than your history books implied. Either that, or you've arrived in a vast cavern network under the North Pole. After exploring a little, you discover a long tunnel that contains a row of small pots as far as you can see to your left and right. A few of them contain plants - someone is trying to grow things in these geothermally-heated caves. -Read the [full puzzle](https://adventofcode.com/2018/day/12). \ No newline at end of file +The pots are numbered, with `0` in front of you. To the left, the pots are numbered `-1`, `-2`, `-3`, and so on; to the right, `1`, `2`, `3`.... Your puzzle input contains a list of pots from `0` to the right and whether they do (`#`) or do not (`.`) currently contain a plant, the *initial state*. (No other pots currently contain plants.) For example, an initial state of `#..##....` indicates that pots `0`, `3`, and `4` currently contain plants. + +Your puzzle input also contains some notes you find on a nearby table: someone has been trying to figure out how these plants *spread* to nearby pots. Based on the notes, for each generation of plants, a given pot has or does not have a plant based on whether that pot (and the two pots on either side of it) had a plant in the last generation. These are written as `LLCRR => N`, where `L` are pots to the left, `C` is the current pot being considered, `R` are the pots to the right, and `N` is whether the current pot will have a plant in the next generation. For example: + + + - A note like `..#.. => .` means that a pot that contains a plant but with no plants within two pots of it will not have a plant in it during the next generation. + - A note like `##.## => .` means that an empty pot with two plants on each side of it will remain empty in the next generation. + - A note like `.##.# => #` means that a pot has a plant in a given generation if, in the previous generation, there were plants in that pot, the one immediately to the left, and the one two pots to the right, but not in the ones immediately to the right and two to the left. + +It's not clear what these plants are for, but you're sure it's important, so you'd like to make sure the current configuration of plants is sustainable by determining what will happen after *`20` generations*. + +For example, given the following input: + +``` +initial state: #..#.#..##......###...### + +...## => # +..#.. => # +.#... => # +.#.#. => # +.#.## => # +.##.. => # +.#### => # +#.#.# => # +#.### => # +##.#. => # +##.## => # +###.. => # +###.# => # +####. => # +``` + +For brevity, in this example, only the combinations which do produce a plant are listed. (Your input includes all possible combinations.) Then, the next 20 generations will look like this: + +``` + 1 2 3 + 0 0 0 0 + 0: ...#..#.#..##......###...###........... + 1: ...#...#....#.....#..#..#..#........... + 2: ...##..##...##....#..#..#..##.......... + 3: ..#.#...#..#.#....#..#..#...#.......... + 4: ...#.#..#...#.#...#..#..##..##......... + 5: ....#...##...#.#..#..#...#...#......... + 6: ....##.#.#....#...#..##..##..##........ + 7: ...#..###.#...##..#...#...#...#........ + 8: ...#....##.#.#.#..##..##..##..##....... + 9: ...##..#..#####....#...#...#...#....... +10: ..#.#..#...#.##....##..##..##..##...... +11: ...#...##...#.#...#.#...#...#...#...... +12: ...##.#.#....#.#...#.#..##..##..##..... +13: ..#..###.#....#.#...#....#...#...#..... +14: ..#....##.#....#.#..##...##..##..##.... +15: ..##..#..#.#....#....#..#.#...#...#.... +16: .#.#..#...#.#...##...#...#.#..##..##... +17: ..#...##...#.#.#.#...##...#....#...#... +18: ..##.#.#....#####.#.#.#...##...##..##.. +19: .#..###.#..#.#.#######.#.#.#..#.#...#.. +20: .#....##....#####...#######....#.#..##. +``` + +The generation is shown along the left, where `0` is the initial state. The pot numbers are shown along the top, where `0` labels the center pot, negative-numbered pots extend to the left, and positive pots extend toward the right. Remember, the initial state begins at pot `0`, which is not the leftmost pot used in this example. + +After one generation, only seven plants remain. The one in pot `0` matched the rule looking for `..#..`, the one in pot `4` matched the rule looking for `.#.#.`, pot `9` matched `.##..`, and so on. + +In this example, after 20 generations, the pots shown as `#` contain plants, the furthest left of which is pot `-2`, and the furthest right of which is pot `34`. Adding up all the numbers of plant-containing pots after the 20th generation produces `*325*`. + +*After `20` generations, what is the sum of the numbers of all pots which contain a plant?* + + +## --- Part Two --- +You realize that 20 generations aren't enough. After all, these plants will need to last another 1500 years to even reach your timeline, not to mention your future. + +*After fifty billion (`50000000000`) generations, what is the sum of the numbers of all pots which contain a plant?* + + diff --git a/2018/Day12/input.in b/2018/Day12/input.in index f94e0da77..a0e8bc4ca 100644 Binary files a/2018/Day12/input.in and b/2018/Day12/input.in differ diff --git a/2018/Day13/README.md b/2018/Day13/README.md index 14747d94f..48bfbb995 100644 --- a/2018/Day13/README.md +++ b/2018/Day13/README.md @@ -1,6 +1,221 @@ +original source: [https://adventofcode.com/2018/day/13](https://adventofcode.com/2018/day/13) ## --- Day 13: Mine Cart Madness --- A crop of this size requires significant logistics to transport produce, soil, fertilizer, and so on. The Elves are very busy pushing things around in *carts* on some kind of rudimentary system of tracks they've come up with. Seeing as how cart-and-track systems don't appear in recorded history for another 1000 years, the Elves seem to be making this up as they go along. They haven't even figured out how to avoid collisions yet. -Read the [full puzzle](https://adventofcode.com/2018/day/13). \ No newline at end of file +You map out the tracks (your puzzle input) and see where you can help. + +Tracks consist of straight paths (`|` and `-`), curves (`/` and `\`), and intersections (`+`). Curves connect exactly two perpendicular pieces of track; for example, this is a closed loop: + +``` +/----\ +| | +| | +\----/ +``` + +Intersections occur when two perpendicular paths cross. At an intersection, a cart is capable of turning left, turning right, or continuing straight. Here are two loops connected by two intersections: + +``` +/-----\ +| | +| /--+--\ +| | | | +\--+--/ | + | | + \-----/ +``` + +Several *carts* are also on the tracks. Carts always face either up (`^`), down (`v`), left (`<`), or right (`>`). (On your initial map, the track under each cart is a straight path matching the direction the cart is facing.) + +Each time a cart has the option to turn (by arriving at any intersection), it turns *left* the first time, goes *straight* the second time, turns *right* the third time, and then repeats those directions starting again with *left* the fourth time, *straight* the fifth time, and so on. This process is independent of the particular intersection at which the cart has arrived - that is, the cart has no per-intersection memory. + +Carts all move at the same speed; they take turns moving a single step at a time. They do this based on their *current location*: carts on the top row move first (acting from left to right), then carts on the second row move (again from left to right), then carts on the third row, and so on. Once each cart has moved one step, the process repeats; each of these loops is called a *tick*. + +For example, suppose there are two carts on a straight track: + +``` +| | | | | +v | | | | +| v v | | +| | | v X +| | ^ ^ | +^ ^ | | | +| | | | | +``` + + +First, the top cart moves. It is facing down (`v`), so it moves down one square. Second, the bottom cart moves. It is facing up (`^`), so it moves up one square. Because all carts have moved, the first tick ends. Then, the process repeats, starting with the first cart. The first cart moves down, then the second cart moves up - right into the first cart, colliding with it! (The location of the crash is marked with an `X`.) This ends the second and last tick. + +Here is a longer example: + +``` +/->-\ +| | /----\ +| /-+--+-\ | +| | | | v | +\-+-/ \-+--/ + \------/ + +/-->\ +| | /----\ +| /-+--+-\ | +| | | | | | +\-+-/ \->--/ + \------/ + +/---v +| | /----\ +| /-+--+-\ | +| | | | | | +\-+-/ \-+>-/ + \------/ + +/---\ +| v /----\ +| /-+--+-\ | +| | | | | | +\-+-/ \-+->/ + \------/ + +/---\ +| | /----\ +| /->--+-\ | +| | | | | | +\-+-/ \-+--^ + \------/ + +/---\ +| | /----\ +| /-+>-+-\ | +| | | | | ^ +\-+-/ \-+--/ + \------/ + +/---\ +| | /----\ +| /-+->+-\ ^ +| | | | | | +\-+-/ \-+--/ + \------/ + +/---\ +| | /----< +| /-+-->-\ | +| | | | | | +\-+-/ \-+--/ + \------/ + +/---\ +| | /---<\ +| /-+--+>\ | +| | | | | | +\-+-/ \-+--/ + \------/ + +/---\ +| | /--<-\ +| /-+--+-v | +| | | | | | +\-+-/ \-+--/ + \------/ + +/---\ +| | /-<--\ +| /-+--+-\ | +| | | | v | +\-+-/ \-+--/ + \------/ + +/---\ +| | /<---\ +| /-+--+-\ | +| | | | | | +\-+-/ \-<--/ + \------/ + +/---\ +| | v----\ +| /-+--+-\ | +| | | | | | +\-+-/ \<+--/ + \------/ + +/---\ +| | /----\ +| /-+--v-\ | +| | | | | | +\-+-/ ^-+--/ + \------/ + +/---\ +| | /----\ +| /-+--+-\ | +| | | X | | +\-+-/ \-+--/ + \------/ +``` + +After following their respective paths for a while, the carts eventually crash. To help prevent crashes, you'd like to know *the location of the first crash*. Locations are given in `X,Y` coordinates, where the furthest left column is `X=0` and the furthest top row is `Y=0`: + +``` + 111 + 0123456789012 +0/---\ +1| | /----\ +2| /-+--+-\ | +3| | | X | | +4\-+-/ \-+--/ +5 \------/ +``` + +In this example, the location of the first crash is `*7,3*`. + + +## --- Part Two --- +There isn't much you can do to prevent crashes in this ridiculous system. However, by predicting the crashes, the Elves know where to be in advance and *instantly remove the two crashing carts* the moment any crash occurs. + +They can proceed like this for a while, but eventually, they're going to run out of carts. It could be useful to figure out where the last cart that *hasn't* crashed will end up. + +For example: + +``` +/>-<\ +| | +| /<+-\ +| | | v +\>+/ + +/---\ +| | +| v-+-\ +| | | | +\-+-/ | + | | + ^---^ + +/---\ +| | +| /-+-\ +| v | | +\-+-/ | + ^ ^ + \---/ + +/---\ +| | +| /-+-\ +| | | | +\-+-/ *^* + | | + \---/ +``` + +After four very expensive crashes, a tick ends with only one cart remaining; its final location is `*6,4*`. + +*What is the location of the last cart* at the end of the first tick where it is the only cart left? + + diff --git a/2018/Day13/input.in b/2018/Day13/input.in index 921dc501f..9a558a203 100644 Binary files a/2018/Day13/input.in and b/2018/Day13/input.in differ diff --git a/2018/Day14/README.md b/2018/Day14/README.md index 69452d3ed..7bf24830c 100644 --- a/2018/Day14/README.md +++ b/2018/Day14/README.md @@ -1,6 +1,58 @@ +original source: [https://adventofcode.com/2018/day/14](https://adventofcode.com/2018/day/14) ## --- Day 14: Chocolate Charts --- You finally have a chance to look at all of the produce moving around. Chocolate, cinnamon, mint, chili peppers, nutmeg, vanilla... the Elves must be growing these plants to make *hot chocolate*! As you realize this, you hear a conversation in the distance. When you go to investigate, you discover two Elves in what appears to be a makeshift underground kitchen/laboratory. The Elves are trying to come up with the ultimate hot chocolate recipe; they're even maintaining a scoreboard which tracks the quality *score* (`0`-`9`) of each recipe. -Read the [full puzzle](https://adventofcode.com/2018/day/14). \ No newline at end of file +Only two recipes are on the board: the first recipe got a score of `3`, the second, `7`. Each of the two Elves has a *current recipe*: the first Elf starts with the first recipe, and the second Elf starts with the second recipe. + +To create new recipes, the two Elves combine their current recipes. This creates new recipes from the *digits of the sum* of the current recipes' scores. With the current recipes' scores of `3` and `7`, their sum is `10`, and so two new recipes would be created: the first with score `1` and the second with score `0`. If the current recipes' scores were `2` and `3`, the sum, `5`, would only create one recipe (with a score of `5`) with its single digit. + +The new recipes are added to the end of the scoreboard in the order they are created. So, after the first round, the scoreboard is `3, 7, 1, 0`. + +After all new recipes are added to the scoreboard, each Elf picks a new current recipe. To do this, the Elf steps forward through the scoreboard a number of recipes equal to *1 plus the score of their current recipe*. So, after the first round, the first Elf moves forward `1 + 3 = 4` times, while the second Elf moves forward `1 + 7 = 8` times. If they run out of recipes, they loop back around to the beginning. After the first round, both Elves happen to loop around until they land on the same recipe that they had in the beginning; in general, they will move to different recipes. + +Drawing the first Elf as parentheses and the second Elf as square brackets, they continue this process: + +``` +(3)[7] +(3)[7] 1 0 + 3 7 1 [0](1) 0 + 3 7 1 0 [1] 0 (1) +(3) 7 1 0 1 0 [1] 2 + 3 7 1 0 (1) 0 1 2 [4] + 3 7 1 [0] 1 0 (1) 2 4 5 + 3 7 1 0 [1] 0 1 2 (4) 5 1 + 3 (7) 1 0 1 0 [1] 2 4 5 1 5 + 3 7 1 0 1 0 1 2 [4](5) 1 5 8 + 3 (7) 1 0 1 0 1 2 4 5 1 5 8 [9] + 3 7 1 0 1 0 1 [2] 4 (5) 1 5 8 9 1 6 + 3 7 1 0 1 0 1 2 4 5 [1] 5 8 9 1 (6) 7 + 3 7 1 0 (1) 0 1 2 4 5 1 5 [8] 9 1 6 7 7 + 3 7 [1] 0 1 0 (1) 2 4 5 1 5 8 9 1 6 7 7 9 + 3 7 1 0 [1] 0 1 2 (4) *5 1 5 8 9 1 6 7 7 9* 2 +``` + +The Elves think their skill will improve after making a few recipes (your puzzle input). However, that could take ages; you can speed this up considerably by identifying *the scores of the ten recipes* after that. For example: + + + - If the Elves think their skill will improve after making `9` recipes, the scores of the ten recipes *after* the first nine on the scoreboard would be `5158916779` (highlighted in the last line of the diagram). + - After `5` recipes, the scores of the next ten would be `0124515891`. + - After `18` recipes, the scores of the next ten would be `9251071085`. + - After `2018` recipes, the scores of the next ten would be `5941429882`. + +*What are the scores of the ten recipes immediately after the number of recipes in your puzzle input?* + + +## --- Part Two --- +As it turns out, you got the Elves' plan backwards. They actually want to know how many recipes appear on the scoreboard to the left of the first recipes whose scores are the digits from your puzzle input. + + + - `51589` first appears after `9` recipes. + - `01245` first appears after `5` recipes. + - `92510` first appears after `18` recipes. + - `59414` first appears after `2018` recipes. + +*How many recipes appear on the scoreboard to the left of the score sequence in your puzzle input?* + + diff --git a/2018/Day14/input.in b/2018/Day14/input.in index 342edb5ac..4a50d5cec 100644 Binary files a/2018/Day14/input.in and b/2018/Day14/input.in differ diff --git a/2018/Day15/README.md b/2018/Day15/README.md index ffa44ddd5..56ac94e76 100644 --- a/2018/Day15/README.md +++ b/2018/Day15/README.md @@ -1,6 +1,420 @@ +original source: [https://adventofcode.com/2018/day/15](https://adventofcode.com/2018/day/15) ## --- Day 15: Beverage Bandits --- Having perfected their hot chocolate, the Elves have a new problem: the [Goblins](https://en.wikipedia.org/wiki/Goblin) that live in these caves will do anything to steal it. Looks like they're here for a fight. You scan the area, generating a map of the walls (#), open cavern (.), and starting position of every Goblin (G) and Elf (E) (your puzzle input). -Read the [full puzzle](https://adventofcode.com/2018/day/15). \ No newline at end of file +Combat proceeds in rounds; in each round, each unit that is still alive takes a turn, resolving all of its actions before the next unit's turn begins. On each unit's turn, it tries to move into range of an enemy (if it isn't already) and then attack (if it is in range). + +All units are very disciplined and always follow very strict combat rules. Units never move or attack diagonally, as doing so would be dishonorable. When multiple choices are equally valid, ties are broken in reading order: top-to-bottom, then left-to-right. For instance, the order in which units take their turns within a round is the reading order of their starting positions in that round, regardless of the type of unit or whether other units have moved after the round started. For example: + +
+                 would take their
+These units:   turns in this order:
+  #######           #######
+  #.G.E.#           #.1.2.#
+  #E.G.E#           #3.4.5#
+  #.G.E.#           #.6.7.#
+  #######           #######
+
+
+ +Each unit begins its turn by identifying all possible targets (enemy units). If no targets remain, combat ends. + +Then, the unit identifies all of the open squares (.) that are in range of each target; these are the squares which are adjacent (immediately up, down, left, or right) to any target and which aren't already occupied by a wall or another unit. Alternatively, the unit might already be in range of a target. If the unit is not already in range of a target, and there are no open squares which are in range of a target, the unit ends its turn. + +If the unit is already in range of a target, it does not move, but continues its turn with an attack. Otherwise, since it is not in range of a target, it moves. + +To move, the unit first considers the squares that are in range and determines which of those squares it could reach in the fewest steps. A step is a single movement to any adjacent (immediately up, down, left, or right) open (.) square. Units cannot move into walls or other units. The unit does this while considering the current positions of units and does not do any prediction about where units will be later. If the unit cannot reach (find an open path to) any of the squares that are in range, it ends its turn. If multiple squares are in range and tied for being reachable in the fewest steps, the square which is first in reading order is chosen. For example: + +
+Targets:      In range:     Reachable:    Nearest:      Chosen:
+#######       #######       #######       #######       #######
+#E..G.#       #E.?G?#       #E.@G.#       #E.!G.#       #E.+G.#
+#...#.#  -->  #.?.#?#  -->  #.@.#.#  -->  #.!.#.#  -->  #...#.#
+#.G.#G#       #?G?#G#       #@G@#G#       #!G.#G#       #.G.#G#
+#######       #######       #######       #######       #######
+
+
+ +In the above scenario, the Elf has three targets (the three Goblins): + + + - Each of the Goblins has open, adjacent squares which are in range (marked with a ? on the map). + - Of those squares, four are reachable (marked @); the other two (on the right) would require moving through a wall or unit to reach. + - Three of these reachable squares are nearest, requiring the fewest steps (only 2) to reach (marked !). + - Of those, the square which is first in reading order is chosen (+). + +The unit then takes a single step toward the chosen square along the shortest path to that square. If multiple steps would put the unit equally closer to its destination, the unit chooses the step which is first in reading order. (This requires knowing when there is more than one shortest path so that you can consider the first step of each such path.) For example: + +
+In range:     Nearest:      Chosen:       Distance:     Step:
+#######       #######       #######       #######       #######
+#.E...#       #.E...#       #.E...#       #4E212#       #..E..#
+#...?.#  -->  #...!.#  -->  #...+.#  -->  #32101#  -->  #.....#
+#..?G?#       #..!G.#       #...G.#       #432G2#       #...G.#
+#######       #######       #######       #######       #######
+
+
+ +The Elf sees three squares in range of a target (?), two of which are nearest (!), and so the first in reading order is chosen (+). Under "Distance", each open square is marked with its distance from the destination square; the two squares to which the Elf could move on this turn (down and to the right) are both equally good moves and would leave the Elf 2 steps from being in range of the Goblin. Because the step which is first in reading order is chosen, the Elf moves right one square. + +Here's a larger example of movement: + +
+Initially:
+#########
+#G..G..G#
+#.......#
+#.......#
+#G..E..G#
+#.......#
+#.......#
+#G..G..G#
+#########
+
+After 1 round:
+#########
+#.G...G.#
+#...G...#
+#...E..G#
+#.G.....#
+#.......#
+#G..G..G#
+#.......#
+#########
+
+After 2 rounds:
+#########
+#..G.G..#
+#...G...#
+#.G.E.G.#
+#.......#
+#G..G..G#
+#.......#
+#.......#
+#########
+
+After 3 rounds:
+#########
+#.......#
+#..GGG..#
+#..GEG..#
+#G..G...#
+#......G#
+#.......#
+#.......#
+#########
+
+
+ +Once the Goblins and Elf reach the positions above, they all are either in range of a target or cannot find any square in range of a target, and so none of the units can move until a unit dies. + +After moving (or if the unit began its turn in range of a target), the unit attacks. + +To attack, the unit first determines all of the targets that are in range of it by being immediately adjacent to it. If there are no such targets, the unit ends its turn. Otherwise, the adjacent target with the fewest hit points is selected; in a tie, the adjacent target with the fewest hit points which is first in reading order is selected. + +The unit deals damage equal to its attack power to the selected target, reducing its hit points by that amount. If this reduces its hit points to 0 or fewer, the selected target dies: its square becomes . and it takes no further turns. + +Each unit, either Goblin or Elf, has 3 attack power and starts with 200 hit points. + +For example, suppose the only Elf is about to attack: + +
+       HP:            HP:
+G....  9       G....  9  
+..G..  4       ..G..  4  
+..EG.  2  -->  ..E..     
+..G..  2       ..G..  2  
+...G.  1       ...G.  1  
+
+
+ +The "HP" column shows the hit points of the Goblin to the left in the corresponding row. The Elf is in range of three targets: the Goblin above it (with 4 hit points), the Goblin to its right (with 2 hit points), and the Goblin below it (also with 2 hit points). Because three targets are in range, the ones with the lowest hit points are selected: the two Goblins with 2 hit points each (one to the right of the Elf and one below the Elf). Of those, the Goblin first in reading order (the one to the right of the Elf) is selected. The selected Goblin's hit points (2) are reduced by the Elf's attack power (3), reducing its hit points to -1, killing it. + +After attacking, the unit's turn ends. Regardless of how the unit's turn ends, the next unit in the round takes its turn. If all units have taken turns in this round, the round ends, and a new round begins. + +The Elves look quite outnumbered. You need to determine the outcome of the battle: the number of full rounds that were completed (not counting the round in which combat ends) multiplied by the sum of the hit points of all remaining units at the moment combat ends. (Combat only ends when a unit finds no targets during its turn.) + +Below is an entire sample combat. Next to each map, each row's units' hit points are listed from left to right. + +
+Initially:
+#######   
+#.G...#   G(200)
+#...EG#   E(200), G(200)
+#.#.#G#   G(200)
+#..G#E#   G(200), E(200)
+#.....#   
+#######   
+
+After 1 round:
+#######   
+#..G..#   G(200)
+#...EG#   E(197), G(197)
+#.#G#G#   G(200), G(197)
+#...#E#   E(197)
+#.....#   
+#######   
+
+After 2 rounds:
+#######   
+#...G.#   G(200)
+#..GEG#   G(200), E(188), G(194)
+#.#.#G#   G(194)
+#...#E#   E(194)
+#.....#   
+#######   
+
+Combat ensues; eventually, the top Elf dies:
+
+After 23 rounds:
+#######   
+#...G.#   G(200)
+#..G.G#   G(200), G(131)
+#.#.#G#   G(131)
+#...#E#   E(131)
+#.....#   
+#######   
+
+After 24 rounds:
+#######   
+#..G..#   G(200)
+#...G.#   G(131)
+#.#G#G#   G(200), G(128)
+#...#E#   E(128)
+#.....#   
+#######   
+
+After 25 rounds:
+#######   
+#.G...#   G(200)
+#..G..#   G(131)
+#.#.#G#   G(125)
+#..G#E#   G(200), E(125)
+#.....#   
+#######   
+
+After 26 rounds:
+#######   
+#G....#   G(200)
+#.G...#   G(131)
+#.#.#G#   G(122)
+#...#E#   E(122)
+#..G..#   G(200)
+#######   
+
+After 27 rounds:
+#######   
+#G....#   G(200)
+#.G...#   G(131)
+#.#.#G#   G(119)
+#...#E#   E(119)
+#...G.#   G(200)
+#######   
+
+After 28 rounds:
+#######   
+#G....#   G(200)
+#.G...#   G(131)
+#.#.#G#   G(116)
+#...#E#   E(113)
+#....G#   G(200)
+#######   
+
+More combat ensues; eventually, the bottom Elf dies:
+
+After 47 rounds:
+#######   
+#G....#   G(200)
+#.G...#   G(131)
+#.#.#G#   G(59)
+#...#.#   
+#....G#   G(200)
+#######   
+
+
+ +Before the 48th round can finish, the top-left Goblin finds that there are no targets remaining, and so combat ends. So, the number of full rounds that were completed is 47, and the sum of the hit points of all remaining units is 200+131+59+200 = 590. From these, the outcome of the battle is 47 * 590 = 27730. + +Here are a few example summarized combats: + +
+#######       #######
+#G..#E#       #...#E#   E(200)
+#E#E.E#       #E#...#   E(197)
+#G.##.#  -->  #.E##.#   E(185)
+#...#E#       #E..#E#   E(200), E(200)
+#...E.#       #.....#
+#######       #######
+
+Combat ends after 37 full rounds
+Elves win with 982 total hit points left
+Outcome: 37 * 982 = 36334
+
+
+ +
+#######       #######   
+#E..EG#       #.E.E.#   E(164), E(197)
+#.#G.E#       #.#E..#   E(200)
+#E.##E#  -->  #E.##.#   E(98)
+#G..#.#       #.E.#.#   E(200)
+#..E#.#       #...#.#   
+#######       #######   
+
+Combat ends after 46 full rounds
+Elves win with 859 total hit points left
+Outcome: 46 * 859 = 39514
+
+
+ +
+#######       #######   
+#E.G#.#       #G.G#.#   G(200), G(98)
+#.#G..#       #.#G..#   G(200)
+#G.#.G#  -->  #..#..#   
+#G..#.#       #...#G#   G(95)
+#...E.#       #...G.#   G(200)
+#######       #######   
+
+Combat ends after 35 full rounds
+Goblins win with 793 total hit points left
+Outcome: 35 * 793 = 27755
+
+
+ +
+#######       #######   
+#.E...#       #.....#   
+#.#..G#       #.#G..#   G(200)
+#.###.#  -->  #.###.#   
+#E#G#G#       #.#.#.#   
+#...#G#       #G.G#G#   G(98), G(38), G(200)
+#######       #######   
+
+Combat ends after 54 full rounds
+Goblins win with 536 total hit points left
+Outcome: 54 * 536 = 28944
+
+
+ +
+#########       #########   
+#G......#       #.G.....#   G(137)
+#.E.#...#       #G.G#...#   G(200), G(200)
+#..##..G#       #.G##...#   G(200)
+#...##..#  -->  #...##..#   
+#...#...#       #.G.#...#   G(200)
+#.G...G.#       #.......#   
+#.....G.#       #.......#   
+#########       #########   
+
+Combat ends after 20 full rounds
+Goblins win with 937 total hit points left
+Outcome: 20 * 937 = 18740
+
+
+ +What is the outcome of the combat described in your puzzle input? + + +## --- Part Two --- +According to your calculations, the Elves are going to lose badly. Surely, you won't mess up the timeline too much if you give them just a little advanced technology, right? + +You need to make sure the Elves not only win, but also suffer no losses: even the death of a single Elf is unacceptable. + +However, you can't go too far: larger changes will be more likely to permanently alter spacetime. + +So, you need to find the outcome of the battle in which the Elves have the lowest integer attack power (at least 4) that allows them to win without a single death. The Goblins always have an attack power of 3. + +In the first summarized example above, the lowest attack power the Elves need to win without losses is 15: + +
+#######       #######
+#.G...#       #..E..#   E(158)
+#...EG#       #...E.#   E(14)
+#.#.#G#  -->  #.#.#.#
+#..G#E#       #...#.#
+#.....#       #.....#
+#######       #######
+
+Combat ends after 29 full rounds
+Elves win with 172 total hit points left
+Outcome: 29 * 172 = 4988
+
+
+ +In the second example above, the Elves need only 4 attack power: + +
+#######       #######
+#E..EG#       #.E.E.#   E(200), E(23)
+#.#G.E#       #.#E..#   E(200)
+#E.##E#  -->  #E.##E#   E(125), E(200)
+#G..#.#       #.E.#.#   E(200)
+#..E#.#       #...#.#
+#######       #######
+
+Combat ends after 33 full rounds
+Elves win with 948 total hit points left
+Outcome: 33 * 948 = 31284
+
+
+ +In the third example above, the Elves need 15 attack power: + +
+#######       #######
+#E.G#.#       #.E.#.#   E(8)
+#.#G..#       #.#E..#   E(86)
+#G.#.G#  -->  #..#..#
+#G..#.#       #...#.#
+#...E.#       #.....#
+#######       #######
+
+Combat ends after 37 full rounds
+Elves win with 94 total hit points left
+Outcome: 37 * 94 = 3478
+
+
+ +In the fourth example above, the Elves need 12 attack power: + +
+#######       #######
+#.E...#       #...E.#   E(14)
+#.#..G#       #.#..E#   E(152)
+#.###.#  -->  #.###.#
+#E#G#G#       #.#.#.#
+#...#G#       #...#.#
+#######       #######
+
+Combat ends after 39 full rounds
+Elves win with 166 total hit points left
+Outcome: 39 * 166 = 6474
+
+
+ +In the last example above, the lone Elf needs 34 attack power: + +
+#########       #########   
+#G......#       #.......#   
+#.E.#...#       #.E.#...#   E(38)
+#..##..G#       #..##...#   
+#...##..#  -->  #...##..#   
+#...#...#       #...#...#   
+#.G...G.#       #.......#   
+#.....G.#       #.......#   
+#########       #########   
+
+Combat ends after 30 full rounds
+Elves win with 38 total hit points left
+Outcome: 30 * 38 = 1140
+
+
+ +After increasing the Elves' attack power until it is just barely enough for them to win without any Elves dying, what is the outcome of the combat described in your puzzle input? + + diff --git a/2018/Day15/input.in b/2018/Day15/input.in index 0ea43d55c..867d0aa68 100644 Binary files a/2018/Day15/input.in and b/2018/Day15/input.in differ diff --git a/2018/Day16/README.md b/2018/Day16/README.md index 0c41ed9df..59403e204 100644 --- a/2018/Day16/README.md +++ b/2018/Day16/README.md @@ -1,6 +1,88 @@ +original source: [https://adventofcode.com/2018/day/16](https://adventofcode.com/2018/day/16) ## --- Day 16: Chronal Classification --- As you see the Elves defend their hot chocolate successfully, you go back to falling through time. This is going to become a problem. If you're ever going to return to your own time, you need to understand how this device on your wrist works. You have a little while before you reach your next destination, and with a bit of trial and error, you manage to pull up a programming manual on the device's tiny screen. -Read the [full puzzle](https://adventofcode.com/2018/day/16). \ No newline at end of file +According to the manual, the device has four [registers](https://en.wikipedia.org/wiki/Hardware_register) (numbered `0` through `3`) that can be manipulated by [instructions](https://en.wikipedia.org/wiki/Instruction_set_architecture#Instructions) containing one of 16 opcodes. The registers start with the value `0`. + +Every instruction consists of four values: an *opcode*, two *inputs* (named `A` and `B`), and an *output* (named `C`), in that order. The opcode specifies the behavior of the instruction and how the inputs are interpreted. The output, `C`, is always treated as a register. + +In the opcode descriptions below, if something says "*value `A`*", it means to take the number given as `A` *literally*. (This is also called an "immediate" value.) If something says "*register `A`*", it means to use the number given as `A` to read from (or write to) the *register with that number*. So, if the opcode `addi` adds register `A` and value `B`, storing the result in register `C`, and the instruction `addi 0 7 3` is encountered, it would add `7` to the value contained by register `0` and store the sum in register `3`, never modifying registers `0`, `1`, or `2` in the process. + +Many opcodes are similar except for how they interpret their arguments. The opcodes fall into seven general categories: + +Addition: + + + - `addr` (add register) stores into register `C` the result of adding register `A` and register `B`. + - `addi` (add immediate) stores into register `C` the result of adding register `A` and value `B`. + +Multiplication: + + + - `mulr` (multiply register) stores into register `C` the result of multiplying register `A` and register `B`. + - `muli` (multiply immediate) stores into register `C` the result of multiplying register `A` and value `B`. + +[Bitwise AND](https://en.wikipedia.org/wiki/Bitwise_AND): + + + - `banr` (bitwise AND register) stores into register `C` the result of the bitwise AND of register `A` and register `B`. + - `bani` (bitwise AND immediate) stores into register `C` the result of the bitwise AND of register `A` and value `B`. + +[Bitwise OR](https://en.wikipedia.org/wiki/Bitwise_OR): + + + - `borr` (bitwise OR register) stores into register `C` the result of the bitwise OR of register `A` and register `B`. + - `bori` (bitwise OR immediate) stores into register `C` the result of the bitwise OR of register `A` and value `B`. + +Assignment: + + + - `setr` (set register) copies the contents of register `A` into register `C`. (Input `B` is ignored.) + - `seti` (set immediate) stores value `A` into register `C`. (Input `B` is ignored.) + +Greater-than testing: + + + - `gtir` (greater-than immediate/register) sets register `C` to `1` if value `A` is greater than register `B`. Otherwise, register `C` is set to `0`. + - `gtri` (greater-than register/immediate) sets register `C` to `1` if register `A` is greater than value `B`. Otherwise, register `C` is set to `0`. + - `gtrr` (greater-than register/register) sets register `C` to `1` if register `A` is greater than register `B`. Otherwise, register `C` is set to `0`. + +Equality testing: + + + - `eqir` (equal immediate/register) sets register `C` to `1` if value `A` is equal to register `B`. Otherwise, register `C` is set to `0`. + - `eqri` (equal register/immediate) sets register `C` to `1` if register `A` is equal to value `B`. Otherwise, register `C` is set to `0`. + - `eqrr` (equal register/register) sets register `C` to `1` if register `A` is equal to register `B`. Otherwise, register `C` is set to `0`. + +Unfortunately, while the manual gives the *name* of each opcode, it doesn't seem to indicate the *number*. However, you can monitor the CPU to see the contents of the registers before and after instructions are executed to try to work them out. Each opcode has a number from `0` through `15`, but the manual doesn't say which is which. For example, suppose you capture the following sample: + +``` +Before: [3, 2, 1, 1] +9 2 1 2 +After: [3, 2, 2, 1] +``` + +This sample shows the effect of the instruction `9 2 1 2` on the registers. Before the instruction is executed, register `0` has value `3`, register `1` has value `2`, and registers `2` and `3` have value `1`. After the instruction is executed, register `2`'s value becomes `2`. + +The instruction itself, `9 2 1 2`, means that opcode `9` was executed with `A=2`, `B=1`, and `C=2`. Opcode `9` could be any of the 16 opcodes listed above, but only three of them behave in a way that would cause the result shown in the sample: + + + - Opcode `9` could be `mulr`: register `2` (which has a value of `1`) times register `1` (which has a value of `2`) produces `2`, which matches the value stored in the output register, register `2`. + - Opcode `9` could be `addi`: register `2` (which has a value of `1`) plus value `1` produces `2`, which matches the value stored in the output register, register `2`. + - Opcode `9` could be `seti`: value `2` matches the value stored in the output register, register `2`; the number given for `B` is irrelevant. + +None of the other opcodes produce the result captured in the sample. Because of this, the sample above *behaves like three opcodes*. + +You collect many of these samples (the first section of your puzzle input). The manual also includes a small test program (the second section of your puzzle input) - you can *ignore it for now*. + +Ignoring the opcode numbers, *how many samples in your puzzle input behave like three or more opcodes?* + + +## --- Part Two --- +Using the samples you collected, work out the number of each opcode and execute the test program (the second section of your puzzle input). + +*What value is contained in register `0` after executing the test program?* + + diff --git a/2018/Day16/input.in b/2018/Day16/input.in index 75cac132a..9b004c04e 100644 Binary files a/2018/Day16/input.in and b/2018/Day16/input.in differ diff --git a/2018/Day17/README.md b/2018/Day17/README.md index 16a5873ac..38d4bdc86 100644 --- a/2018/Day17/README.md +++ b/2018/Day17/README.md @@ -1,6 +1,179 @@ +original source: [https://adventofcode.com/2018/day/17](https://adventofcode.com/2018/day/17) ## --- Day 17: Reservoir Research --- You arrive in the year 18. If it weren't for the coat you got in 1018, you would be very cold: the North Pole base hasn't even been constructed. Rather, it hasn't been constructed *yet*. The Elves are making a little progress, but there's not a lot of liquid water in this climate, so they're getting very dehydrated. Maybe there's more underground? -Read the [full puzzle](https://adventofcode.com/2018/day/17). \ No newline at end of file +You scan a two-dimensional vertical slice of the ground nearby and discover that it is mostly *sand* with veins of *clay*. The scan only provides data with a granularity of *square meters*, but it should be good enough to determine how much water is trapped there. In the scan, `x` represents the distance to the right, and `y` represents the distance down. There is also a *spring of water* near the surface at `x=500, y=0`. The scan identifies *which square meters are clay* (your puzzle input). + +For example, suppose your scan shows the following veins of clay: + +``` +x=495, y=2..7 +y=7, x=495..501 +x=501, y=3..7 +x=498, y=2..4 +x=506, y=1..2 +x=498, y=10..13 +x=504, y=10..13 +y=13, x=498..504 +``` + +Rendering clay as `#`, sand as `.`, and the water spring as `+`, and with `x` increasing to the right and `y` increasing downward, this becomes: + +``` + 44444455555555 + 99999900000000 + 45678901234567 + 0 ......+....... + 1 ............#. + 2 .#..#.......#. + 3 .#..#..#...... + 4 .#..#..#...... + 5 .#.....#...... + 6 .#.....#...... + 7 .#######...... + 8 .............. + 9 .............. +10 ....#.....#... +11 ....#.....#... +12 ....#.....#... +13 ....#######... +``` + +The spring of water will produce water *forever*. Water can move through sand, but is blocked by clay. Water *always moves down* when possible, and spreads to the left and right otherwise, filling space that has clay on both sides and falling out otherwise. + +For example, if five squares of water are created, they will flow downward until they reach the clay and settle there. Water that has come to rest is shown here as `~`, while sand through which water has passed (but which is now dry again) is shown as `|`: + +``` +......+....... +......|.....#. +.#..#.|.....#. +.#..#.|#...... +.#..#.|#...... +.#....|#...... +.#~~~~~#...... +.#######...... +.............. +.............. +....#.....#... +....#.....#... +....#.....#... +....#######... +``` + +Two squares of water can't occupy the same location. If another five squares of water are created, they will settle on the first five, filling the clay reservoir a little more: + +``` +......+....... +......|.....#. +.#..#.|.....#. +.#..#.|#...... +.#..#.|#...... +.#~~~~~#...... +.#~~~~~#...... +.#######...... +.............. +.............. +....#.....#... +....#.....#... +....#.....#... +....#######... +``` + +Water pressure does not apply in this scenario. If another four squares of water are created, they will stay on the right side of the barrier, and no water will reach the left side: + +``` +......+....... +......|.....#. +.#..#.|.....#. +.#..#~~#...... +.#..#~~#...... +.#~~~~~#...... +.#~~~~~#...... +.#######...... +.............. +.............. +....#.....#... +....#.....#... +....#.....#... +....#######... +``` + +At this point, the top reservoir overflows. While water can reach the tiles above the surface of the water, it cannot settle there, and so the next five squares of water settle like this: + +``` +......+....... +......|.....#. +.#..#*|*|||...#. +.#..#~~#|..... +.#..#~~#|..... +.#~~~~~#|..... +.#~~~~~#|..... +.#######|..... +........|..... +........|..... +....#...|.#... +....#...|.#... +....#~~~~~#... +....#######... +``` + +Note especially the leftmost `|`: the new squares of water can reach this tile, but cannot stop there. Instead, eventually, they all fall to the right and settle in the reservoir below. + +After 10 more squares of water, the bottom reservoir is also full: + +``` +......+....... +......|.....#. +.#..#||||...#. +.#..#~~#|..... +.#..#~~#|..... +.#~~~~~#|..... +.#~~~~~#|..... +.#######|..... +........|..... +........|..... +....#~~~~~#... +....#~~~~~#... +....#~~~~~#... +....#######... +``` + +Finally, while there is nowhere left for the water to settle, it can reach a few more tiles before overflowing beyond the bottom of the scanned data: + +``` +......+....... (line not counted: above minimum y value) +......|.....#. +.#..#||||...#. +.#..#~~#|..... +.#..#~~#|..... +.#~~~~~#|..... +.#~~~~~#|..... +.#######|..... +........|..... +...|||||||||.. +...|#~~~~~#|.. +...|#~~~~~#|.. +...|#~~~~~#|.. +...|#######|.. +...|.......|.. (line not counted: below maximum y value) +...|.......|.. (line not counted: below maximum y value) +...|.......|.. (line not counted: below maximum y value) +``` + +How many tiles can be reached by the water? *To prevent counting forever*, ignore tiles with a `y` coordinate smaller than the smallest `y` coordinate in your scan data or larger than the largest one. Any `x` coordinate is valid. In this example, the lowest `y` coordinate given is `1`, and the highest is `13`, causing the water spring (in row `0`) and the water falling off the bottom of the render (in rows `14` through infinity) to be ignored. + +So, in the example above, counting both water at rest (`~`) and other sand tiles the water can hypothetically reach (`|`), the total number of tiles the water can reach is `*57*`. + +*How many tiles can the water reach* within the range of `y` values in your scan? + + +## --- Part Two --- +After a very long time, the water spring will run dry. How much water will be retained? + +In the example above, water that won't eventually drain out is shown as `~`, a total of `*29*` tiles. + +*How many water tiles are left* after the water spring stops producing water and all remaining water not at rest has drained? + + diff --git a/2018/Day17/input.in b/2018/Day17/input.in index 47120cff7..988a8b289 100644 Binary files a/2018/Day17/input.in and b/2018/Day17/input.in differ diff --git a/2018/Day18/README.md b/2018/Day18/README.md index 10baaa900..66420ad69 100644 --- a/2018/Day18/README.md +++ b/2018/Day18/README.md @@ -1,6 +1,166 @@ +original source: [https://adventofcode.com/2018/day/18](https://adventofcode.com/2018/day/18) ## --- Day 18: Settlers of The North Pole --- On the outskirts of the North Pole base construction project, many Elves are collecting lumber. The lumber collection area is 50 acres by 50 acres; each acre can be either *open ground* (`.`), *trees* (`|`), or a *lumberyard* (`#`). You take a scan of the area (your puzzle input). -Read the [full puzzle](https://adventofcode.com/2018/day/18). \ No newline at end of file +Strange magic is at work here: each minute, the landscape looks entirely different. In exactly *one minute*, an open acre can fill with trees, a wooded acre can be converted to a lumberyard, or a lumberyard can be cleared to open ground (the lumber having been sent to other projects). + +The change to each acre is based entirely on *the contents of that acre* as well as *the number of open, wooded, or lumberyard acres adjacent to it* at the start of each minute. Here, "adjacent" means any of the eight acres surrounding that acre. (Acres on the edges of the lumber collection area might have fewer than eight adjacent acres; the missing acres aren't counted.) + +In particular: + + + - An *open* acre will become filled with *trees* if *three or more* adjacent acres contained trees. Otherwise, nothing happens. + - An acre filled with *trees* will become a *lumberyard* if *three or more* adjacent acres were lumberyards. Otherwise, nothing happens. + - An acre containing a *lumberyard* will remain a *lumberyard* if it was adjacent to *at least one other lumberyard and at least one acre containing trees*. Otherwise, it becomes *open*. + +These changes happen across all acres *simultaneously*, each of them using the state of all acres at the beginning of the minute and changing to their new form by the end of that same minute. Changes that happen during the minute don't affect each other. + +For example, suppose the lumber collection area is instead only 10 by 10 acres with this initial configuration: + +``` +Initial state: +.#.#...|#. +.....#|##| +.|..|...#. +..|#.....# +#.#|||#|#| +...#.||... +.|....|... +||...#|.#| +|.||||..|. +...#.|..|. + +After 1 minute: +.......##. +......|### +.|..|...#. +..|#||...# +..##||.|#| +...#||||.. +||...|||.. +|||||.||.| +|||||||||| +....||..|. + +After 2 minutes: +.......#.. +......|#.. +.|.|||.... +..##|||..# +..###|||#| +...#|||||. +|||||||||. +|||||||||| +|||||||||| +.||||||||| + +After 3 minutes: +.......#.. +....|||#.. +.|.||||... +..###|||.# +...##|||#| +.||##||||| +|||||||||| +|||||||||| +|||||||||| +|||||||||| + +After 4 minutes: +.....|.#.. +...||||#.. +.|.#||||.. +..###||||# +...###||#| +|||##||||| +|||||||||| +|||||||||| +|||||||||| +|||||||||| + +After 5 minutes: +....|||#.. +...||||#.. +.|.##||||. +..####|||# +.|.###||#| +|||###|||| +|||||||||| +|||||||||| +|||||||||| +|||||||||| + +After 6 minutes: +...||||#.. +...||||#.. +.|.###|||. +..#.##|||# +|||#.##|#| +|||###|||| +||||#||||| +|||||||||| +|||||||||| +|||||||||| + +After 7 minutes: +...||||#.. +..||#|##.. +.|.####||. +||#..##||# +||##.##|#| +|||####||| +|||###|||| +|||||||||| +|||||||||| +|||||||||| + +After 8 minutes: +..||||##.. +..|#####.. +|||#####|. +||#...##|# +||##..###| +||##.###|| +|||####||| +||||#||||| +|||||||||| +|||||||||| + +After 9 minutes: +..||###... +.||#####.. +||##...##. +||#....### +|##....##| +||##..###| +||######|| +|||###|||| +|||||||||| +|||||||||| + +After 10 minutes: +.||##..... +||###..... +||##...... +|##.....## +|##.....## +|##....##| +||##.####| +||#####||| +||||#||||| +|||||||||| +``` + +After 10 minutes, there are `37` wooded acres and `31` lumberyards. Multiplying the number of wooded acres by the number of lumberyards gives the total *resource value* after ten minutes: `37 * 31 = *1147*`. + +*What will the total resource value of the lumber collection area be after 10 minutes?* + + +## --- Part Two --- +This important natural resource will need to last for at least thousands of years. Are the Elves collecting this lumber sustainably? + +*What will the total resource value of the lumber collection area be after 1000000000 minutes?* + + diff --git a/2018/Day18/input.in b/2018/Day18/input.in index 5babc989e..c5a08e93a 100644 Binary files a/2018/Day18/input.in and b/2018/Day18/input.in differ diff --git a/2018/Day19/README.md b/2018/Day19/README.md index b2070b233..7930f7a49 100644 --- a/2018/Day19/README.md +++ b/2018/Day19/README.md @@ -1,6 +1,58 @@ +original source: [https://adventofcode.com/2018/day/19](https://adventofcode.com/2018/day/19) ## --- Day 19: Go With The Flow --- With the Elves well on their way constructing the North Pole base, you turn your attention back to understanding the inner workings of programming the device. You can't help but notice that the [device's opcodes](16) don't contain any *flow control* like jump instructions. The device's [manual](16) goes on to explain: -Read the [full puzzle](https://adventofcode.com/2018/day/19). \ No newline at end of file +"In programs where flow control is required, the [instruction pointer](https://en.wikipedia.org/wiki/Program_counter) can be *bound to a register* so that it can be manipulated directly. This way, `setr`/`seti` can function as absolute jumps, `addr`/`addi` can function as relative jumps, and other opcodes can cause truly fascinating effects." + +This mechanism is achieved through a declaration like `#ip 1`, which would modify register `1` so that accesses to it let the program indirectly access the instruction pointer itself. To compensate for this kind of binding, there are now *six* registers (numbered `0` through `5`); the five not bound to the instruction pointer behave as normal. Otherwise, the same rules apply as [the last time you worked with this device](16). + +When the *instruction pointer* is bound to a register, its value is written to that register just before each instruction is executed, and the value of that register is written back to the instruction pointer immediately after each instruction finishes execution. Afterward, move to the next instruction by adding one to the instruction pointer, even if the value in the instruction pointer was just updated by an instruction. (Because of this, instructions must effectively set the instruction pointer to the instruction *before* the one they want executed next.) + +The instruction pointer is `0` during the first instruction, `1` during the second, and so on. If the instruction pointer ever causes the device to attempt to load an instruction outside the instructions defined in the program, the program instead immediately halts. The instruction pointer starts at `0`. + +It turns out that this new information is already proving useful: the CPU in the device is not very powerful, and a background process is occupying most of its time. You dump the background process' declarations and instructions to a file (your puzzle input), making sure to use the names of the opcodes rather than the numbers. + +For example, suppose you have the following program: + +``` +#ip 0 +seti 5 0 1 +seti 6 0 2 +addi 0 1 0 +addr 1 2 3 +setr 1 0 0 +seti 8 0 4 +seti 9 0 5 +``` + +When executed, the following instructions are executed. Each line contains the value of the instruction pointer at the time the instruction started, the values of the six registers before executing the instructions (in square brackets), the instruction itself, and the values of the six registers after executing the instruction (also in square brackets). + +``` +ip=0 [0, 0, 0, 0, 0, 0] seti 5 0 1 [0, 5, 0, 0, 0, 0] +ip=1 [1, 5, 0, 0, 0, 0] seti 6 0 2 [1, 5, 6, 0, 0, 0] +ip=2 [2, 5, 6, 0, 0, 0] addi 0 1 0 [3, 5, 6, 0, 0, 0] +ip=4 [4, 5, 6, 0, 0, 0] setr 1 0 0 [5, 5, 6, 0, 0, 0] +ip=6 [6, 5, 6, 0, 0, 0] seti 9 0 5 [6, 5, 6, 0, 0, 9] +``` + +In detail, when running this program, the following events occur: + + + - The first line (`#ip 0`) indicates that the instruction pointer should be bound to register `0` in this program. This is not an instruction, and so the value of the instruction pointer does not change during the processing of this line. + - The instruction pointer contains `0`, and so the first instruction is executed (`seti 5 0 1`). It updates register `0` to the current instruction pointer value (`0`), sets register `1` to `5`, sets the instruction pointer to the value of register `0` (which has no effect, as the instruction did not modify register `0`), and then adds one to the instruction pointer. + - The instruction pointer contains `1`, and so the second instruction, `seti 6 0 2`, is executed. This is very similar to the instruction before it: `6` is stored in register `2`, and the instruction pointer is left with the value `2`. + - The instruction pointer is `2`, which points at the instruction `addi 0 1 0`. This is like a *relative jump*: the value of the instruction pointer, `2`, is loaded into register `0`. Then, `addi` finds the result of adding the value in register `0` and the value `1`, storing the result, `3`, back in register `0`. Register `0` is then copied back to the instruction pointer, which will cause it to end up `1` larger than it would have otherwise and skip the next instruction (`addr 1 2 3`) entirely. Finally, `1` is added to the instruction pointer. + - The instruction pointer is `4`, so the instruction `setr 1 0 0` is run. This is like an *absolute jump*: it copies the value contained in register `1`, `5`, into register `0`, which causes it to end up in the instruction pointer. The instruction pointer is then incremented, leaving it at `6`. + - The instruction pointer is `6`, so the instruction `seti 9 0 5` stores `9` into register `5`. The instruction pointer is incremented, causing it to point outside the program, and so the program ends. + +*What value is left in register `0`* when the background process halts? + + +## --- Part Two --- +A new background process immediately spins up in its place. It appears identical, but on closer inspection, you notice that *this time, register `0` started with the value `1`*. + +*What value is left in register `0`* when this new background process halts? + + diff --git a/2018/Day19/input.in b/2018/Day19/input.in index 07bc89717..99698801d 100644 Binary files a/2018/Day19/input.in and b/2018/Day19/input.in differ diff --git a/2018/Day20/README.md b/2018/Day20/README.md index 195e256fe..d1836d96d 100644 --- a/2018/Day20/README.md +++ b/2018/Day20/README.md @@ -1,6 +1,164 @@ +original source: [https://adventofcode.com/2018/day/20](https://adventofcode.com/2018/day/20) ## --- Day 20: A Regular Map --- While you were learning about instruction pointers, the Elves made considerable progress. When you look up, you discover that the North Pole base construction project has completely surrounded you. The area you are in is made up entirely of *rooms* and *doors*. The rooms are arranged in a grid, and rooms only connect to adjacent rooms when a door is present between them. -Read the [full puzzle](https://adventofcode.com/2018/day/20). \ No newline at end of file +For example, drawing rooms as `.`, walls as `#`, doors as `|` or `-`, your current position as `X`, and where north is up, the area you're in might look like this: + +``` +##### +#.|.# +#-### +#.|X# +##### +``` + +You get the attention of a passing construction Elf and ask for a map. "I don't have time to draw out a map of this place - it's *huge*. Instead, I can give you directions to *every room in the facility*!" He writes down some directions on a piece of parchment and runs off. In the example above, the instructions might have been `^WNE$`, a [regular expression](https://en.wikipedia.org/wiki/Regular_expression) or "*regex*" (your puzzle input). + +The regex matches routes (like `WNE` for "west, north, east") that will take you from your current room through various doors in the facility. In aggregate, the routes will take you through *every door in the facility at least once*; mapping out all of these routes will let you build a proper map and find your way around. + +`^` and `$` are at the beginning and end of your regex; these just mean that the regex doesn't match anything outside the routes it describes. (Specifically, `^` matches the start of the route, and `$` matches the end of it.) These characters will not appear elsewhere in the regex. + +The rest of the regex matches various sequences of the characters `N` (north), `S` (south), `E` (east), and `W` (west). In the example above, `^WNE$` matches only one route, `WNE`, which means you can move *west, then north, then east* from your current position. Sequences of letters like this always match that exact route in the same order. + +Sometimes, the route can *branch*. A branch is given by a *list of options* separated by pipes (`|`) and wrapped in parentheses. So, `^N(E|W)N$` contains a branch: after going north, you must choose to go *either east or west* before finishing your route by going north again. By tracing out the possible routes after branching, you can determine where the doors are and, therefore, where the rooms are in the facility. + +For example, consider this regex: `^ENWWW(NEEE|SSE(EE|N))$` + +This regex begins with `ENWWW`, which means that from your current position, all routes must begin by moving east, north, and then west three times, in that order. After this, there is a branch. Before you consider the branch, this is what you know about the map so far, with doors you aren't sure about marked with a `?`: + +``` +#?#?#?#?# +?.|.|.|.? +#?#?#?#-# + ?X|.? + #?#?# +``` + +After this point, there is `(NEEE|SSE(EE|N))`. This gives you exactly two options: `NEEE` and `SSE(EE|N)`. By following `NEEE`, the map now looks like this: + +``` +#?#?#?#?# +?.|.|.|.? +#-#?#?#?# +?.|.|.|.? +#?#?#?#-# + ?X|.? + #?#?# +``` + +Now, only `SSE(EE|N)` remains. Because it is in the same parenthesized group as `NEEE`, it starts from the same room `NEEE` started in. It states that starting from that point, there exist doors which will allow you to move south twice, then east; this ends up at another branch. After that, you can either move east twice or north once. This information fills in the rest of the doors: + +``` +#?#?#?#?# +?.|.|.|.? +#-#?#?#?# +?.|.|.|.? +#-#?#?#-# +?.?.?X|.? +#-#-#?#?# +?.|.|.|.? +#?#?#?#?# +``` + +Once you've followed all possible routes, you know the remaining unknown parts are all walls, producing a finished map of the facility: + +``` +######### +#.|.|.|.# +#-####### +#.|.|.|.# +#-#####-# +#.#.#X|.# +#-#-##### +#.|.|.|.# +######### +``` + +Sometimes, a list of options can have an *empty option*, like `(NEWS|WNSE|)`. This means that routes at this point could effectively skip the options in parentheses and move on immediately. For example, consider this regex and the corresponding map: + +``` +^ENNWSWW(NEWS|)SSSEEN(WNSE|)EE(SWEN|)NNN$ + +########### +#.|.#.|.#.# +#-###-#-#-# +#.|.|.#.#.# +#-#####-#-# +#.#.#X|.#.# +#-#-#####-# +#.#.|.|.|.# +#-###-###-# +#.|.|.#.|.# +########### +``` + +This regex has one main route which, at three locations, can optionally include additional detours and be valid: `(NEWS|)`, `(WNSE|)`, and `(SWEN|)`. Regardless of which option is taken, the route continues from the position it is left at after taking those steps. So, for example, this regex matches all of the following routes (and more that aren't listed here): + + + - `ENNWSWWSSSEENEENNN` + - `ENNWSWW*NEWS*SSSEENEENNN` + - `ENNWSWW*NEWS*SSSEENEE*SWEN*NNN` + - `ENNWSWWSSSEEN*WNSE*EENNN` + +By following the various routes the regex matches, a full map of all of the doors and rooms in the facility can be assembled. + +To get a sense for the size of this facility, you'd like to determine which room is *furthest* from you: specifically, you would like to find the room for which the *shortest path to that room would require passing through the most doors*. + + + - In the first example (`^WNE$`), this would be the north-east corner `*3*` doors away. + - In the second example (`^ENWWW(NEEE|SSE(EE|N))$`), this would be the south-east corner `*10*` doors away. + - In the third example (`^ENNWSWW(NEWS|)SSSEEN(WNSE|)EE(SWEN|)NNN$`), this would be the north-east corner `*18*` doors away. + +Here are a few more examples: + +``` +Regex: ^ESSWWN(E|NNENN(EESS(WNSE|)SSS|WWWSSSSE(SW|NNNE)))$ +Furthest room requires passing 23 doors + +############# +#.|.|.|.|.|.# +#-#####-###-# +#.#.|.#.#.#.# +#-#-###-#-#-# +#.#.#.|.#.|.# +#-#-#-#####-# +#.#.#.#X|.#.# +#-#-#-###-#-# +#.|.#.|.#.#.# +###-#-###-#-# +#.|.#.|.|.#.# +############# +``` + +``` +Regex: ^WSSEESWWWNW(S|NENNEEEENN(ESSSSW(NWSW|SSEN)|WSWWN(E|WWS(E|SS))))$ +Furthest room requires passing 31 doors + +############### +#.|.|.|.#.|.|.# +#-###-###-#-#-# +#.|.#.|.|.#.#.# +#-#########-#-# +#.#.|.|.|.|.#.# +#-#-#########-# +#.#.#.|X#.|.#.# +###-#-###-#-#-# +#.|.#.#.|.#.|.# +#-###-#####-### +#.|.#.|.|.#.#.# +#-#-#####-#-#-# +#.#.|.|.|.#.|.# +############### +``` + +*What is the largest number of doors you would be required to pass through to reach a room?* That is, find the room for which the shortest path from your starting location to that room would require passing through the most doors; what is the fewest doors you can pass through to reach it? + + +## --- Part Two --- +Okay, so the facility is *big*. + +*How many rooms have a shortest path from your current location that pass through at least `1000` doors?* + + diff --git a/2018/Day20/input.in b/2018/Day20/input.in index 84ee2d7a1..e4f0cfaf9 100644 Binary files a/2018/Day20/input.in and b/2018/Day20/input.in differ diff --git a/2018/Day21/README.md b/2018/Day21/README.md index f7558e4d8..6f26f0a28 100644 --- a/2018/Day21/README.md +++ b/2018/Day21/README.md @@ -1,6 +1,31 @@ +original source: [https://adventofcode.com/2018/day/21](https://adventofcode.com/2018/day/21) ## --- Day 21: Chronal Conversion --- You should have been watching where you were going, because as you wander the new North Pole base, you trip and fall into a very deep hole! Just kidding. You're falling through time again. -Read the [full puzzle](https://adventofcode.com/2018/day/21). \ No newline at end of file +If you keep up your current pace, you should have resolved all of the temporal anomalies by the next time the device activates. Since you have very little interest in browsing history in 500-year increments for the rest of your life, you need to find a way to get back to your present time. + +After a little research, you discover two important facts about the behavior of the device: + +First, you discover that the device is hard-wired to always send you back in time in 500-year increments. Changing this is probably not feasible. + +Second, you discover the *activation system* (your puzzle input) for the time travel module. Currently, it appears to *run forever without halting*. + +If you can cause the activation system to *halt* at a specific moment, maybe you can make the device send you so far back in time that you cause an [integer underflow](https://cwe.mitre.org/data/definitions/191.html) *in time itself* and wrap around back to your current time! + +The device executes the program as specified in [manual section one](16) and [manual section two](19). + +Your goal is to figure out how the program works and cause it to halt. You can only control *register `0`*; every other register begins at `0` as usual. + +Because time travel is a dangerous activity, the activation system begins with a few instructions which verify that *bitwise AND* (via `bani`) does a *numeric* operation and *not* an operation as if the inputs were interpreted as strings. If the test fails, it enters an infinite loop re-running the test instead of allowing the program to execute normally. If the test passes, the program continues, and assumes that *all other bitwise operations* (`banr`, `bori`, and `borr`) also interpret their inputs as *numbers*. (Clearly, the Elves who wrote this system were worried that someone might introduce a bug while trying to emulate this system with a scripting language.) + +*What is the lowest non-negative integer value for register `0` that causes the program to halt after executing the fewest instructions?* (Executing the same instruction multiple times counts as multiple instructions executed.) + + +## --- Part Two --- +In order to determine the timing window for your underflow exploit, you also need an upper bound: + +*What is the lowest non-negative integer value for register `0` that causes the program to halt after executing the most instructions?* (The program must actually halt; running forever does not count as halting.) + + diff --git a/2018/Day21/Solution.cs b/2018/Day21/Solution.cs index f7ed345ae..c762cecca 100644 --- a/2018/Day21/Solution.cs +++ b/2018/Day21/Solution.cs @@ -1,65 +1,112 @@ using System; using System.Collections.Generic; +using System.IO; using System.Linq; +using System.Reflection; +using System.Runtime.Loader; +using System.Text; +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.CSharp; +using Microsoft.CodeAnalysis.Emit; namespace AdventOfCode.Y2018.Day21; [ProblemName("Chronal Conversion")] class Solution : Solver { - public object PartOne(string input) => Run(input).First(); - public object PartTwo(string input) => Run(input).Last(); + public object PartOne(string input) => Run("one", input).First(); + public object PartTwo(string input) => Run("two", input).Last(); - public IEnumerable Run(string input) { - var breakpoint = 28; - var seen = new List(); + IEnumerable Run(string name, string input) { + var run = Compile>(name, input, new int[]{28}); - foreach (var regs in Trace(input, breakpoint)) { - if (seen.Contains(regs[3])) { + var seen = new List(); + foreach(var r in run(new int[] { 0, 0, 0, 0, 0, 0 })){ + if (seen.Contains(r[3])) { break; } - seen.Add(regs[3]); - yield return regs[3]; + seen.Add(r[3]); + yield return r[3]; } } - public IEnumerable Trace(string input, int breakpoint) { - var lines = input.Split("\n"); - var ipReg = int.Parse(lines.First().Split(" ")[1]); - var program = lines.Skip(1).Select(Compile).ToArray(); - var regs = new long[] { 0, 0, 0, 0, 0, 0 }; + public Func Compile(string name, string input, int[] breakpoints) { + var code = CompileToCSharp(input, breakpoints); + var tree = SyntaxFactory.ParseSyntaxTree(code); + var systemRefLocation = typeof(object).GetTypeInfo().Assembly.Location; + var systemReference = MetadataReference.CreateFromFile(systemRefLocation); + var compilation = CSharpCompilation.Create(name) + .WithOptions(new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary)) + .AddReferences(systemReference) + .AddSyntaxTrees(tree); - while (true) { - if (regs[ipReg] == breakpoint) { - yield return regs; + var ms = new MemoryStream(); + EmitResult compilationResult = compilation.Emit(ms); + if (compilationResult.Success) { + ms.Seek(0, SeekOrigin.Begin); + var asm = AssemblyLoadContext.Default.LoadFromStream(ms); + var m = asm.GetType("RoslynCore.Helper").GetMethod("Run"); + return (Func)Delegate.CreateDelegate(typeof(Func), null, m); + } else { + foreach (Diagnostic codeIssue in compilationResult.Diagnostics) { + string issue = $"ID: {codeIssue.Id}, Message: {codeIssue.GetMessage()}, Location: { codeIssue.Location.GetLineSpan()}, Severity: { codeIssue.Severity}"; + Console.WriteLine(issue); } - program[regs[ipReg]](regs); - regs[ipReg]++; + + throw new Exception(); } } - Action Compile(string line) { - var parts = line.Split(" "); - var op = parts[0]; - var args = parts.Skip(1).Select(long.Parse).ToArray(); - return op switch { - "addr" => regs => regs[args[2]] = regs[args[0]] + regs[args[1]], - "addi" => regs => regs[args[2]] = regs[args[0]] + args[1], - "mulr" => regs => regs[args[2]] = regs[args[0]] * regs[args[1]], - "muli" => regs => regs[args[2]] = regs[args[0]] * args[1], - "banr" => regs => regs[args[2]] = regs[args[0]] & regs[args[1]], - "bani" => regs => regs[args[2]] = regs[args[0]] & args[1], - "borr" => regs => regs[args[2]] = regs[args[0]] | regs[args[1]], - "bori" => regs => regs[args[2]] = regs[args[0]] | args[1], - "setr" => regs => regs[args[2]] = regs[args[0]], - "seti" => regs => regs[args[2]] = args[0], - "gtir" => regs => regs[args[2]] = args[0] > regs[args[1]] ? 1 : 0, - "gtri" => regs => regs[args[2]] = regs[args[0]] > args[1] ? 1 : 0, - "gtrr" => regs => regs[args[2]] = regs[args[0]] > regs[args[1]] ? 1 : 0, - "eqir" => regs => regs[args[2]] = args[0] == regs[args[1]] ? 1 : 0, - "eqri" => regs => regs[args[2]] = regs[args[0]] == args[1] ? 1 : 0, - "eqrr" => regs => regs[args[2]] = regs[args[0]] == regs[args[1]] ? 1 : 0, - _ => throw new ArgumentException() - }; + string CompileToCSharp(string input, int[] breakpoints) { + var ipReg = int.Parse(input.Split("\n").First().Substring("#ip ".Length)); + var srcLines = input.Split("\n").Skip(1).ToArray(); + + var compiledStatements = new StringBuilder(); + + for (var ip = 0; ip < srcLines.Length; ip++) { + var line = srcLines[ip]; + var parts = line.Split(";")[0].Trim().Split(" "); + var stm = parts.Skip(1).Select(int.Parse).ToArray(); + var compiledStm = parts[0] switch { + "addr" => $"r[{stm[2]}] = r[{stm[0]}] + r[{stm[1]}]", + "addi" => $"r[{stm[2]}] = r[{stm[0]}] + {stm[1]}", + "mulr" => $"r[{stm[2]}] = r[{stm[0]}] * r[{stm[1]}]", + "muli" => $"r[{stm[2]}] = r[{stm[0]}] * {stm[1]}", + "banr" => $"r[{stm[2]}] = r[{stm[0]}] & r[{stm[1]}]", + "bani" => $"r[{stm[2]}] = r[{stm[0]}] & {stm[1]}", + "borr" => $"r[{stm[2]}] = r[{stm[0]}] | r[{stm[1]}]", + "bori" => $"r[{stm[2]}] = r[{stm[0]}] | {stm[1]}", + "setr" => $"r[{stm[2]}] = r[{stm[0]}]", + "seti" => $"r[{stm[2]}] = {stm[0]}", + "gtir" => $"r[{stm[2]}] = {stm[0]} > r[{stm[1]}] ? 1 : 0", + "gtri" => $"r[{stm[2]}] = r[{stm[0]}] > {stm[1]} ? 1 : 0", + "gtrr" => $"r[{stm[2]}] = r[{stm[0]}] > r[{stm[1]}] ? 1 : 0", + "eqir" => $"r[{stm[2]}] = {stm[0]} == r[{stm[1]}] ? 1 : 0", + "eqri" => $"r[{stm[2]}] = r[{stm[0]}] == {stm[1]} ? 1 : 0", + "eqrr" => $"r[{stm[2]}] = r[{stm[0]}] == r[{stm[1]}] ? 1 : 0", + _ => throw new ArgumentException() + }; + var brk = breakpoints.Contains(ip) ? "yield return r;" : ""; + compiledStatements.AppendLine($"\t\tcase {ip}: {brk} {compiledStm}; r[{ipReg}]++; break;"); + } + + return $@" + using System; + using System.Collections.Generic; + namespace RoslynCore + {{ + public static class Helper + {{ + public static IEnumerable Run(int[] r) {{ + while(true) {{ + switch (r[{ipReg}]) {{ + {compiledStatements.ToString()} + }} + }} + }} + }} + }} + "; } + } diff --git a/2018/Day21/input.in b/2018/Day21/input.in index 157525118..59a47ab7f 100644 Binary files a/2018/Day21/input.in and b/2018/Day21/input.in differ diff --git a/2018/Day22/README.md b/2018/Day22/README.md index 37a01eb08..8154ba766 100644 --- a/2018/Day22/README.md +++ b/2018/Day22/README.md @@ -1,6 +1,346 @@ +original source: [https://adventofcode.com/2018/day/22](https://adventofcode.com/2018/day/22) ## --- Day 22: Mode Maze --- This is it, your final stop: the year -483. It's snowing and dark outside; the only light you can see is coming from a small cottage in the distance. You make your way there and knock on the door. A portly man with a large, white beard answers the door and invites you inside. For someone living near the North Pole in -483, he must not get many visitors, but he doesn't act surprised to see you. Instead, he offers you some milk and cookies. -Read the [full puzzle](https://adventofcode.com/2018/day/22). \ No newline at end of file +After talking for a while, he asks a favor of you. His friend hasn't come back in a few hours, and he's not sure where he is. Scanning the region briefly, you discover one life signal in a cave system nearby; his friend must have taken shelter there. The man asks if you can go there to retrieve his friend. + +The cave is divided into square *regions* which are either dominantly *rocky*, *narrow*, or *wet* (called its *type*). Each region occupies exactly one *coordinate* in `X,Y` format where `X` and `Y` are integers and zero or greater. (Adjacent regions can be the same type.) + +The scan (your puzzle input) is not very detailed: it only reveals the *depth* of the cave system and the *coordinates of the target*. However, it does not reveal the type of each region. The mouth of the cave is at `0,0`. + +The man explains that due to the unusual geology in the area, there is a method to determine any region's type based on its *erosion level*. The erosion level of a region can be determined from its *geologic index*. The geologic index can be determined using the first rule that applies from the list below: + + + - The region at `0,0` (the mouth of the cave) has a geologic index of `0`. + - The region at the coordinates of the target has a geologic index of `0`. + - If the region's `Y` coordinate is `0`, the geologic index is its `X` coordinate times `16807`. + - If the region's `X` coordinate is `0`, the geologic index is its `Y` coordinate times `48271`. + - Otherwise, the region's geologic index is the result of multiplying the erosion *levels* of the regions at `X-1,Y` and `X,Y-1`. + +A region's *erosion level* is its *geologic index* plus the cave system's *depth*, all [modulo](https://en.wikipedia.org/wiki/Modulo_operation) `20183`. Then: + + + - If the *erosion level modulo `3`* is `0`, the region's type is *rocky*. + - If the *erosion level modulo `3`* is `1`, the region's type is *wet*. + - If the *erosion level modulo `3`* is `2`, the region's type is *narrow*. + +For example, suppose the cave system's depth is `510` and the target's coordinates are `10,10`. Using `%` to represent the modulo operator, the cavern would look as follows: + + + - At `0,0`, the geologic index is `0`. The erosion level is `(0 + 510) % 20183 = 510`. The type is `510 % 3 = 0`, *rocky*. + - At `1,0`, because the `Y` coordinate is `0`, the geologic index is `1 * 16807 = 16807`. The erosion level is `(16807 + 510) % 20183 = 17317`. The type is `17317 % 3 = 1`, *wet*. + - At `0,1`, because the `X` coordinate is `0`, the geologic index is ` 1 * 48271 = 48271`. The erosion level is `(48271 + 510) % 20183 = 8415`. The type is `8415 % 3 = 0`, *rocky*. + - At `1,1`, neither coordinate is `0` and it is not the coordinate of the target, so the geologic index is the erosion level of `0,1` (`8415`) times the erosion level of `1,0` (`17317`), `8415 * 17317 = 145722555`. The erosion level is `(145722555 + 510) % 20183 = 1805`. The type is `1805 % 3 = 2`, *narrow*. + - At `10,10`, because they are the target's coordinates, the geologic index is `0`. The erosion level is `(0 + 510) % 20183 = 510`. The type is `510 % 3 = 0`, *rocky*. + +Drawing this same cave system with rocky as `.`, wet as `=`, narrow as `|`, the mouth as `M`, the target as `T`, with `0,0` in the top-left corner, `X` increasing to the right, and `Y` increasing downward, the top-left corner of the map looks like this: + +``` +*M*=.|=.|.|=.|=|=. +.|=|=|||..|.=... +.==|....||=..|== +=.|....|.==.|==. +=|..==...=.|==.. +=||.=.=||=|=..|= +|.=.===|||..=..| +|..==||=.|==|=== +.=..===..=|.|||. +.======|||=|=.|= +.===|=|===*T*===|| +=|||...|==..|=.| +=.=|=.=..=.||==| +||=|=...|==.=|== +|=.=||===.|||=== +||.|==.|.|.||=|| +``` + +Before you go in, you should determine the *risk level* of the area. For the the rectangle that has a top-left corner of region `0,0` and a bottom-right corner of the region containing the target, add up the risk level of each individual region: `0` for rocky regions, `1` for wet regions, and `2` for narrow regions. + +In the cave system above, because the mouth is at `0,0` and the target is at `10,10`, adding up the risk level of all regions with an `X` coordinate from `0` to `10` and a `Y` coordinate from `0` to `10`, this total is `*114*`. + +*What is the total risk level for the smallest rectangle that includes `0,0` and the target's coordinates?* + + +## --- Part Two --- +Okay, it's time to go rescue the man's friend. + +As you leave, he hands you some tools: a *torch* and some *climbing gear*. You can't equip both tools at once, but you can choose to use *neither*. + +Tools can only be used in certain regions: + + + - In *rocky* regions, you can use the *climbing gear* or the *torch*. You cannot use *neither* (you'll likely slip and fall). + - In *wet* regions, you can use the *climbing gear* or *neither* tool. You cannot use the *torch* (if it gets wet, you won't have a light source). + - In *narrow* regions, you can use the *torch* or *neither* tool. You cannot use the *climbing gear* (it's too bulky to fit). + +You start at `0,0` (the mouth of the cave) with *the torch equipped* and must reach the target coordinates as quickly as possible. The regions with negative `X` or `Y` are solid rock and cannot be traversed. The fastest route might involve entering regions beyond the `X` or `Y` coordinate of the target. + +You can *move to an adjacent region* (up, down, left, or right; never diagonally) if your currently equipped tool allows you to enter that region. Moving to an adjacent region takes *one minute*. (For example, if you have the *torch* equipped, you can move between *rocky* and *narrow* regions, but cannot enter *wet* regions.) + +You can *change your currently equipped tool or put both away* if your new equipment would be valid for your current region. Switching to using the *climbing gear*, *torch*, or *neither* always takes *seven minutes*, regardless of which tools you start with. (For example, if you are in a *rocky* region, you can switch from the *torch* to the *climbing gear*, but you cannot switch to *neither*.) + +Finally, once you reach the target, you need the *torch* equipped before you can find him in the dark. The target is always in a *rocky* region, so if you arrive there with *climbing gear* equipped, you will need to spend seven minutes switching to your torch. + +For example, using the same cave system as above, starting in the top left corner (`0,0`) and moving to the bottom right corner (the target, `10,10`) as quickly as possible, one possible route is as follows, with your current position marked `X`: + +``` +Initially: +*X*=.|=.|.|=.|=|=. +.|=|=|||..|.=... +.==|....||=..|== +=.|....|.==.|==. +=|..==...=.|==.. +=||.=.=||=|=..|= +|.=.===|||..=..| +|..==||=.|==|=== +.=..===..=|.|||. +.======|||=|=.|= +.===|=|===T===|| +=|||...|==..|=.| +=.=|=.=..=.||==| +||=|=...|==.=|== +|=.=||===.|||=== +||.|==.|.|.||=|| + +Down: +M=.|=.|.|=.|=|=. +*X*|=|=|||..|.=... +.==|....||=..|== +=.|....|.==.|==. +=|..==...=.|==.. +=||.=.=||=|=..|= +|.=.===|||..=..| +|..==||=.|==|=== +.=..===..=|.|||. +.======|||=|=.|= +.===|=|===T===|| +=|||...|==..|=.| +=.=|=.=..=.||==| +||=|=...|==.=|== +|=.=||===.|||=== +||.|==.|.|.||=|| + +Right: +M=.|=.|.|=.|=|=. +.*X*=|=|||..|.=... +.==|....||=..|== +=.|....|.==.|==. +=|..==...=.|==.. +=||.=.=||=|=..|= +|.=.===|||..=..| +|..==||=.|==|=== +.=..===..=|.|||. +.======|||=|=.|= +.===|=|===T===|| +=|||...|==..|=.| +=.=|=.=..=.||==| +||=|=...|==.=|== +|=.=||===.|||=== +||.|==.|.|.||=|| + +Switch from using the torch to neither tool: +M=.|=.|.|=.|=|=. +.*X*=|=|||..|.=... +.==|....||=..|== +=.|....|.==.|==. +=|..==...=.|==.. +=||.=.=||=|=..|= +|.=.===|||..=..| +|..==||=.|==|=== +.=..===..=|.|||. +.======|||=|=.|= +.===|=|===T===|| +=|||...|==..|=.| +=.=|=.=..=.||==| +||=|=...|==.=|== +|=.=||===.|||=== +||.|==.|.|.||=|| + +Right 3: +M=.|=.|.|=.|=|=. +.|=|*X*|||..|.=... +.==|....||=..|== +=.|....|.==.|==. +=|..==...=.|==.. +=||.=.=||=|=..|= +|.=.===|||..=..| +|..==||=.|==|=== +.=..===..=|.|||. +.======|||=|=.|= +.===|=|===T===|| +=|||...|==..|=.| +=.=|=.=..=.||==| +||=|=...|==.=|== +|=.=||===.|||=== +||.|==.|.|.||=|| + +Switch from using neither tool to the climbing gear: +M=.|=.|.|=.|=|=. +.|=|*X*|||..|.=... +.==|....||=..|== +=.|....|.==.|==. +=|..==...=.|==.. +=||.=.=||=|=..|= +|.=.===|||..=..| +|..==||=.|==|=== +.=..===..=|.|||. +.======|||=|=.|= +.===|=|===T===|| +=|||...|==..|=.| +=.=|=.=..=.||==| +||=|=...|==.=|== +|=.=||===.|||=== +||.|==.|.|.||=|| + +Down 7: +M=.|=.|.|=.|=|=. +.|=|=|||..|.=... +.==|....||=..|== +=.|....|.==.|==. +=|..==...=.|==.. +=||.=.=||=|=..|= +|.=.===|||..=..| +|..==||=.|==|=== +.=..*X*==..=|.|||. +.======|||=|=.|= +.===|=|===T===|| +=|||...|==..|=.| +=.=|=.=..=.||==| +||=|=...|==.=|== +|=.=||===.|||=== +||.|==.|.|.||=|| + +Right: +M=.|=.|.|=.|=|=. +.|=|=|||..|.=... +.==|....||=..|== +=.|....|.==.|==. +=|..==...=.|==.. +=||.=.=||=|=..|= +|.=.===|||..=..| +|..==||=.|==|=== +.=..=*X*=..=|.|||. +.======|||=|=.|= +.===|=|===T===|| +=|||...|==..|=.| +=.=|=.=..=.||==| +||=|=...|==.=|== +|=.=||===.|||=== +||.|==.|.|.||=|| + +Down 3: +M=.|=.|.|=.|=|=. +.|=|=|||..|.=... +.==|....||=..|== +=.|....|.==.|==. +=|..==...=.|==.. +=||.=.=||=|=..|= +|.=.===|||..=..| +|..==||=.|==|=== +.=..===..=|.|||. +.======|||=|=.|= +.===|=|===T===|| +=|||.*X*.|==..|=.| +=.=|=.=..=.||==| +||=|=...|==.=|== +|=.=||===.|||=== +||.|==.|.|.||=|| + +Right: +M=.|=.|.|=.|=|=. +.|=|=|||..|.=... +.==|....||=..|== +=.|....|.==.|==. +=|..==...=.|==.. +=||.=.=||=|=..|= +|.=.===|||..=..| +|..==||=.|==|=== +.=..===..=|.|||. +.======|||=|=.|= +.===|=|===T===|| +=|||..*X*|==..|=.| +=.=|=.=..=.||==| +||=|=...|==.=|== +|=.=||===.|||=== +||.|==.|.|.||=|| + +Down: +M=.|=.|.|=.|=|=. +.|=|=|||..|.=... +.==|....||=..|== +=.|....|.==.|==. +=|..==...=.|==.. +=||.=.=||=|=..|= +|.=.===|||..=..| +|..==||=.|==|=== +.=..===..=|.|||. +.======|||=|=.|= +.===|=|===T===|| +=|||...|==..|=.| +=.=|=.*X*..=.||==| +||=|=...|==.=|== +|=.=||===.|||=== +||.|==.|.|.||=|| + +Right 4: +M=.|=.|.|=.|=|=. +.|=|=|||..|.=... +.==|....||=..|== +=.|....|.==.|==. +=|..==...=.|==.. +=||.=.=||=|=..|= +|.=.===|||..=..| +|..==||=.|==|=== +.=..===..=|.|||. +.======|||=|=.|= +.===|=|===T===|| +=|||...|==..|=.| +=.=|=.=..=*X*||==| +||=|=...|==.=|== +|=.=||===.|||=== +||.|==.|.|.||=|| + +Up 2: +M=.|=.|.|=.|=|=. +.|=|=|||..|.=... +.==|....||=..|== +=.|....|.==.|==. +=|..==...=.|==.. +=||.=.=||=|=..|= +|.=.===|||..=..| +|..==||=.|==|=== +.=..===..=|.|||. +.======|||=|=.|= +.===|=|===*X*===|| +=|||...|==..|=.| +=.=|=.=..=.||==| +||=|=...|==.=|== +|=.=||===.|||=== +||.|==.|.|.||=|| + +Switch from using the climbing gear to the torch: +M=.|=.|.|=.|=|=. +.|=|=|||..|.=... +.==|....||=..|== +=.|....|.==.|==. +=|..==...=.|==.. +=||.=.=||=|=..|= +|.=.===|||..=..| +|..==||=.|==|=== +.=..===..=|.|||. +.======|||=|=.|= +.===|=|===*X*===|| +=|||...|==..|=.| +=.=|=.=..=.||==| +||=|=...|==.=|== +|=.=||===.|||=== +||.|==.|.|.||=|| +``` + +This is tied with other routes as the *fastest way to reach the target*: `*45*` minutes. In it, `21` minutes are spent switching tools (three times, seven minutes each) and the remaining `24` minutes are spent moving. + +*What is the fewest number of minutes you can take to reach the target?* + + diff --git a/2018/Day22/input.in b/2018/Day22/input.in index b30a77446..e2e94a0cf 100644 Binary files a/2018/Day22/input.in and b/2018/Day22/input.in differ diff --git a/2018/Day23/README.md b/2018/Day23/README.md index 9557f08ef..e49ca4497 100644 --- a/2018/Day23/README.md +++ b/2018/Day23/README.md @@ -1,6 +1,67 @@ +original source: [https://adventofcode.com/2018/day/23](https://adventofcode.com/2018/day/23) ## --- Day 23: Experimental Emergency Teleportation --- Using your torch to search the darkness of the rocky cavern, you finally locate the man's friend: a small *reindeer*. You're not sure how it got so far in this cave. It looks sick - too sick to walk - and too heavy for you to carry all the way back. Sleighs won't be invented for another 1500 years, of course. -Read the [full puzzle](https://adventofcode.com/2018/day/23). \ No newline at end of file +The only option is *experimental emergency teleportation*. + +You hit the "experimental emergency teleportation" button on the device and push *I accept the risk* on no fewer than 18 different warning messages. Immediately, the device deploys hundreds of tiny *nanobots* which fly around the cavern, apparently assembling themselves into a very specific *formation*. The device lists the `X,Y,Z` position (`pos`) for each nanobot as well as its *signal radius* (`r`) on its tiny screen (your puzzle input). + +Each nanobot can transmit signals to any integer coordinate which is a distance away from it *less than or equal to* its signal radius (as measured by [Manhattan distance](https://en.wikipedia.org/wiki/Taxicab_geometry)). Coordinates a distance away of less than or equal to a nanobot's signal radius are said to be *in range* of that nanobot. + +Before you start the teleportation process, you should determine which nanobot is the *strongest* (that is, which has the largest signal radius) and then, for that nanobot, the *total number of nanobots that are in range* of it, *including itself*. + +For example, given the following nanobots: + +``` +pos=<0,0,0>, r=4 +pos=<1,0,0>, r=1 +pos=<4,0,0>, r=3 +pos=<0,2,0>, r=1 +pos=<0,5,0>, r=3 +pos=<0,0,3>, r=1 +pos=<1,1,1>, r=1 +pos=<1,1,2>, r=1 +pos=<1,3,1>, r=1 +``` + +The strongest nanobot is the first one (position `0,0,0`) because its signal radius, `4` is the largest. Using that nanobot's location and signal radius, the following nanobots are in or out of range: + + + - The nanobot at `0,0,0` is distance `0` away, and so it is *in range*. + - The nanobot at `1,0,0` is distance `1` away, and so it is *in range*. + - The nanobot at `4,0,0` is distance `4` away, and so it is *in range*. + - The nanobot at `0,2,0` is distance `2` away, and so it is *in range*. + - The nanobot at `0,5,0` is distance `5` away, and so it is *not* in range. + - The nanobot at `0,0,3` is distance `3` away, and so it is *in range*. + - The nanobot at `1,1,1` is distance `3` away, and so it is *in range*. + - The nanobot at `1,1,2` is distance `4` away, and so it is *in range*. + - The nanobot at `1,3,1` is distance `5` away, and so it is *not* in range. + +In this example, in total, `*7*` nanobots are in range of the nanobot with the largest signal radius. + +Find the nanobot with the largest signal radius. *How many nanobots are in range* of its signals? + + +## --- Part Two --- +Now, you just need to figure out where to position yourself so that you're actually teleported when the nanobots activate. + +To increase the probability of success, you need to find the coordinate which puts you *in range of the largest number of nanobots*. If there are multiple, choose one *closest to your position* (`0,0,0`, measured by manhattan distance). + +For example, given the following nanobot formation: + +``` +pos=<10,12,12>, r=2 +pos=<12,14,12>, r=2 +pos=<16,12,12>, r=4 +pos=<14,14,14>, r=6 +pos=<50,50,50>, r=200 +pos=<10,10,10>, r=5 +``` + +Many coordinates are in range of some of the nanobots in this formation. However, only the coordinate `12,12,12` is in range of the most nanobots: it is in range of the first five, but is not in range of the nanobot at `10,10,10`. (All other coordinates are in range of fewer than five nanobots.) This coordinate's distance from `0,0,0` is `*36*`. + +Find the coordinates that are in range of the largest number of nanobots. *What is the shortest manhattan distance between any of those points and `0,0,0`?* + + diff --git a/2018/Day23/input.in b/2018/Day23/input.in index caf7024a6..0f771fa82 100644 Binary files a/2018/Day23/input.in and b/2018/Day23/input.in differ diff --git a/2018/Day24/README.md b/2018/Day24/README.md index 8b9e7ab6f..0f84a0874 100644 --- a/2018/Day24/README.md +++ b/2018/Day24/README.md @@ -1,6 +1,355 @@ +original source: [https://adventofcode.com/2018/day/24](https://adventofcode.com/2018/day/24) ## --- Day 24: Immune System Simulator 20XX --- After [a weird buzzing noise](https://www.youtube.com/watch?v=NDVjLt_QHL8&t=7), you appear back at the man's cottage. He seems relieved to see his friend, but quickly notices that the little reindeer caught some kind of cold while out exploring. The portly man explains that this reindeer's immune system isn't similar to regular reindeer immune systems: -Read the [full puzzle](https://adventofcode.com/2018/day/24). \ No newline at end of file +The *immune system* and the *infection* each have an army made up of several *groups*; each *group* consists of one or more identical *units*. The armies repeatedly *fight* until only one army has units remaining. + +*Units* within a group all have the same *hit points* (amount of damage a unit can take before it is destroyed), *attack damage* (the amount of damage each unit deals), an *attack type*, an *initiative* (higher initiative units attack first and win ties), and sometimes *weaknesses* or *immunities*. Here is an example group: + +``` +18 units each with 729 hit points (weak to fire; immune to cold, slashing) + with an attack that does 8 radiation damage at initiative 10 +``` + +Each group also has an *effective power*: the number of units in that group multiplied by their attack damage. The above group has an effective power of `18 * 8 = 144`. Groups never have zero or negative units; instead, the group is removed from combat. + +Each *fight* consists of two phases: *target selection* and *attacking*. + +During the *target selection* phase, each group attempts to choose one target. In decreasing order of effective power, groups choose their targets; in a tie, the group with the higher initiative chooses first. The attacking group chooses to target the group in the enemy army to which it would deal the most damage (after accounting for weaknesses and immunities, but not accounting for whether the defending group has enough units to actually receive all of that damage). + +If an attacking group is considering two defending groups to which it would deal equal damage, it chooses to target the defending group with the largest effective power; if there is still a tie, it chooses the defending group with the highest initiative. If it cannot deal any defending groups damage, it does not choose a target. Defending groups can only be chosen as a target by one attacking group. + +At the end of the target selection phase, each group has selected zero or one groups to attack, and each group is being attacked by zero or one groups. + +During the *attacking* phase, each group deals damage to the target it selected, if any. Groups attack in decreasing order of initiative, regardless of whether they are part of the infection or the immune system. (If a group contains no units, it cannot attack.) + +The damage an attacking group deals to a defending group depends on the attacking group's attack type and the defending group's immunities and weaknesses. By default, an attacking group would deal damage equal to its *effective power* to the defending group. However, if the defending group is *immune* to the attacking group's attack type, the defending group instead takes *no damage*; if the defending group is *weak* to the attacking group's attack type, the defending group instead takes *double damage*. + +The defending group only loses *whole units* from damage; damage is always dealt in such a way that it kills the most units possible, and any remaining damage to a unit that does not immediately kill it is ignored. For example, if a defending group contains `10` units with `10` hit points each and receives `75` damage, it loses exactly `7` units and is left with `3` units at full health. + +After the fight is over, if both armies still contain units, a new fight begins; combat only ends once one army has lost all of its units. + +For example, consider the following armies: + +``` +Immune System: +17 units each with 5390 hit points (weak to radiation, bludgeoning) with + an attack that does 4507 fire damage at initiative 2 +989 units each with 1274 hit points (immune to fire; weak to bludgeoning, + slashing) with an attack that does 25 slashing damage at initiative 3 + +Infection: +801 units each with 4706 hit points (weak to radiation) with an attack + that does 116 bludgeoning damage at initiative 1 +4485 units each with 2961 hit points (immune to radiation; weak to fire, + cold) with an attack that does 12 slashing damage at initiative 4 +``` + +If these armies were to enter combat, the following fights, including details during the target selection and attacking phases, would take place: + +``` +Immune System: +Group 1 contains 17 units +Group 2 contains 989 units +Infection: +Group 1 contains 801 units +Group 2 contains 4485 units + +Infection group 1 would deal defending group 1 185832 damage +Infection group 1 would deal defending group 2 185832 damage +Infection group 2 would deal defending group 2 107640 damage +Immune System group 1 would deal defending group 1 76619 damage +Immune System group 1 would deal defending group 2 153238 damage +Immune System group 2 would deal defending group 1 24725 damage + +Infection group 2 attacks defending group 2, killing 84 units +Immune System group 2 attacks defending group 1, killing 4 units +Immune System group 1 attacks defending group 2, killing 51 units +Infection group 1 attacks defending group 1, killing 17 units +``` + +``` +Immune System: +Group 2 contains 905 units +Infection: +Group 1 contains 797 units +Group 2 contains 4434 units + +Infection group 1 would deal defending group 2 184904 damage +Immune System group 2 would deal defending group 1 22625 damage +Immune System group 2 would deal defending group 2 22625 damage + +Immune System group 2 attacks defending group 1, killing 4 units +Infection group 1 attacks defending group 2, killing 144 units +``` + +``` +Immune System: +Group 2 contains 761 units +Infection: +Group 1 contains 793 units +Group 2 contains 4434 units + +Infection group 1 would deal defending group 2 183976 damage +Immune System group 2 would deal defending group 1 19025 damage +Immune System group 2 would deal defending group 2 19025 damage + +Immune System group 2 attacks defending group 1, killing 4 units +Infection group 1 attacks defending group 2, killing 143 units +``` + +``` +Immune System: +Group 2 contains 618 units +Infection: +Group 1 contains 789 units +Group 2 contains 4434 units + +Infection group 1 would deal defending group 2 183048 damage +Immune System group 2 would deal defending group 1 15450 damage +Immune System group 2 would deal defending group 2 15450 damage + +Immune System group 2 attacks defending group 1, killing 3 units +Infection group 1 attacks defending group 2, killing 143 units +``` + +``` +Immune System: +Group 2 contains 475 units +Infection: +Group 1 contains 786 units +Group 2 contains 4434 units + +Infection group 1 would deal defending group 2 182352 damage +Immune System group 2 would deal defending group 1 11875 damage +Immune System group 2 would deal defending group 2 11875 damage + +Immune System group 2 attacks defending group 1, killing 2 units +Infection group 1 attacks defending group 2, killing 142 units +``` + +``` +Immune System: +Group 2 contains 333 units +Infection: +Group 1 contains 784 units +Group 2 contains 4434 units + +Infection group 1 would deal defending group 2 181888 damage +Immune System group 2 would deal defending group 1 8325 damage +Immune System group 2 would deal defending group 2 8325 damage + +Immune System group 2 attacks defending group 1, killing 1 unit +Infection group 1 attacks defending group 2, killing 142 units +``` + +``` +Immune System: +Group 2 contains 191 units +Infection: +Group 1 contains 783 units +Group 2 contains 4434 units + +Infection group 1 would deal defending group 2 181656 damage +Immune System group 2 would deal defending group 1 4775 damage +Immune System group 2 would deal defending group 2 4775 damage + +Immune System group 2 attacks defending group 1, killing 1 unit +Infection group 1 attacks defending group 2, killing 142 units +``` + +``` +Immune System: +Group 2 contains 49 units +Infection: +Group 1 contains 782 units +Group 2 contains 4434 units + +Infection group 1 would deal defending group 2 181424 damage +Immune System group 2 would deal defending group 1 1225 damage +Immune System group 2 would deal defending group 2 1225 damage + +Immune System group 2 attacks defending group 1, killing 0 units +Infection group 1 attacks defending group 2, killing 49 units +``` + +``` +Immune System: +No groups remain. +Infection: +Group 1 contains 782 units +Group 2 contains 4434 units +``` + +In the example above, the winning army ends up with `782 + 4434 = *5216*` units. + +You scan the reindeer's condition (your puzzle input); the white-bearded man looks nervous. As it stands now, *how many units would the winning army have*? + + +## --- Part Two --- +Things aren't looking good for the reindeer. The man asks whether more milk and cookies would help you think. + +If only you could give the reindeer's immune system a boost, you might be able to change the outcome of the combat. + +A *boost* is an integer increase in immune system units' attack damage. For example, if you were to boost the above example's immune system's units by `1570`, the armies would instead look like this: + +``` +Immune System: +17 units each with 5390 hit points (weak to radiation, bludgeoning) with + an attack that does *6077* fire damage at initiative 2 +989 units each with 1274 hit points (immune to fire; weak to bludgeoning, + slashing) with an attack that does *1595* slashing damage at initiative 3 + +Infection: +801 units each with 4706 hit points (weak to radiation) with an attack + that does 116 bludgeoning damage at initiative 1 +4485 units each with 2961 hit points (immune to radiation; weak to fire, + cold) with an attack that does 12 slashing damage at initiative 4 +``` + +With this boost, the combat proceeds differently: + +``` +Immune System: +Group 2 contains 989 units +Group 1 contains 17 units +Infection: +Group 1 contains 801 units +Group 2 contains 4485 units + +Infection group 1 would deal defending group 2 185832 damage +Infection group 1 would deal defending group 1 185832 damage +Infection group 2 would deal defending group 1 53820 damage +Immune System group 2 would deal defending group 1 1577455 damage +Immune System group 2 would deal defending group 2 1577455 damage +Immune System group 1 would deal defending group 2 206618 damage + +Infection group 2 attacks defending group 1, killing 9 units +Immune System group 2 attacks defending group 1, killing 335 units +Immune System group 1 attacks defending group 2, killing 32 units +Infection group 1 attacks defending group 2, killing 84 units +``` + +``` +Immune System: +Group 2 contains 905 units +Group 1 contains 8 units +Infection: +Group 1 contains 466 units +Group 2 contains 4453 units + +Infection group 1 would deal defending group 2 108112 damage +Infection group 1 would deal defending group 1 108112 damage +Infection group 2 would deal defending group 1 53436 damage +Immune System group 2 would deal defending group 1 1443475 damage +Immune System group 2 would deal defending group 2 1443475 damage +Immune System group 1 would deal defending group 2 97232 damage + +Infection group 2 attacks defending group 1, killing 8 units +Immune System group 2 attacks defending group 1, killing 306 units +Infection group 1 attacks defending group 2, killing 29 units +``` + +``` +Immune System: +Group 2 contains 876 units +Infection: +Group 2 contains 4453 units +Group 1 contains 160 units + +Infection group 2 would deal defending group 2 106872 damage +Immune System group 2 would deal defending group 2 1397220 damage +Immune System group 2 would deal defending group 1 1397220 damage + +Infection group 2 attacks defending group 2, killing 83 units +Immune System group 2 attacks defending group 2, killing 427 units +``` + +After a few fights... + +``` +Immune System: +Group 2 contains 64 units +Infection: +Group 2 contains 214 units +Group 1 contains 19 units + +Infection group 2 would deal defending group 2 5136 damage +Immune System group 2 would deal defending group 2 102080 damage +Immune System group 2 would deal defending group 1 102080 damage + +Infection group 2 attacks defending group 2, killing 4 units +Immune System group 2 attacks defending group 2, killing 32 units +``` + +``` +Immune System: +Group 2 contains 60 units +Infection: +Group 1 contains 19 units +Group 2 contains 182 units + +Infection group 1 would deal defending group 2 4408 damage +Immune System group 2 would deal defending group 1 95700 damage +Immune System group 2 would deal defending group 2 95700 damage + +Immune System group 2 attacks defending group 1, killing 19 units +``` + +``` +Immune System: +Group 2 contains 60 units +Infection: +Group 2 contains 182 units + +Infection group 2 would deal defending group 2 4368 damage +Immune System group 2 would deal defending group 2 95700 damage + +Infection group 2 attacks defending group 2, killing 3 units +Immune System group 2 attacks defending group 2, killing 30 units +``` + +After a few more fights... + +``` +Immune System: +Group 2 contains 51 units +Infection: +Group 2 contains 40 units + +Infection group 2 would deal defending group 2 960 damage +Immune System group 2 would deal defending group 2 81345 damage + +Infection group 2 attacks defending group 2, killing 0 units +Immune System group 2 attacks defending group 2, killing 27 units +``` + +``` +Immune System: +Group 2 contains 51 units +Infection: +Group 2 contains 13 units + +Infection group 2 would deal defending group 2 312 damage +Immune System group 2 would deal defending group 2 81345 damage + +Infection group 2 attacks defending group 2, killing 0 units +Immune System group 2 attacks defending group 2, killing 13 units +``` + +``` +Immune System: +Group 2 contains 51 units +Infection: +No groups remain. +``` + +This boost would allow the immune system's armies to win! It would be left with `*51*` units. + +You don't even know *how* you could boost the reindeer's immune system or what effect it might have, so you need to be cautious and find the *smallest boost* that would allow the immune system to win. + +*How many units does the immune system have left* after getting the smallest boost it needs to win? + + diff --git a/2018/Day24/input.in b/2018/Day24/input.in index 211b05595..4b6a81098 100644 Binary files a/2018/Day24/input.in and b/2018/Day24/input.in differ diff --git a/2018/Day25/README.md b/2018/Day25/README.md index 9d1c5fc54..bc548bfa2 100644 --- a/2018/Day25/README.md +++ b/2018/Day25/README.md @@ -1,6 +1,99 @@ +original source: [https://adventofcode.com/2018/day/25](https://adventofcode.com/2018/day/25) ## --- Day 25: Four-Dimensional Adventure --- The reindeer's symptoms are getting worse, and neither you nor the white-bearded man have a solution. At least the reindeer has a warm place to rest: a small bed near where you're sitting. As you reach down, the reindeer looks up at you, accidentally bumping a button on your wrist-mounted device with its nose in the process - a button labeled *"help"*. -Read the [full puzzle](https://adventofcode.com/2018/day/25). \ No newline at end of file +"Hello, and welcome to the Time Travel Support Hotline! If you are lost in time and space, press 1. If you are trapped in a time paradox, press 2. If you need help caring for a sick reindeer, press 3. If you--" + +*Beep.* + +A few seconds later, you hear a new voice. "Hello; please state the nature of your reindeer." You try to describe the situation. + +"Just a moment, I think I can remotely run a diagnostic scan." A beam of light projects from the device and sweeps over the reindeer a few times. + +"Okay, it looks like your reindeer is very low on magical energy; it should fully recover if we can fix that. Let me check your timeline for a source.... Got one. There's actually a powerful source of magical energy about 1000 years forward from you, and at roughly your position, too! It looks like... hot chocolate? Anyway, you should be able to travel there to pick some up; just don't forget a mug! Is there anything else I can help you with today?" + +You explain that your device isn't capable of going forward in time. "I... see. That's tricky. Well, according to this information, your device should have the necessary hardware to open a small portal and send some hot chocolate back to you. You'll need a list of *fixed points in spacetime*; I'm transmitting it to you now." + +"You just need to align your device to the constellations of fixed points so that it can lock on to the destination and open the portal. Let me look up how much hot chocolate that breed of reindeer needs." + +"It says here that your particular reindeer is-- this can't be right, it says there's only one like that in the universe! But THAT means that you're--" You disconnect the call. + +The list of fixed points in spacetime (your puzzle input) is a set of four-dimensional coordinates. To align your device, acquire the hot chocolate, and save the reindeer, you just need to find the *number of constellations* of points in the list. + +Two points are in the same *constellation* if their manhattan distance apart is *no more than 3* or if they can form a chain of points, each a manhattan distance no more than 3 from the last, between the two of them. (That is, if a point is close enough to a constellation, it "joins" that constellation.) For example: + +``` + 0,0,0,0 + 3,0,0,0 + 0,3,0,0 + 0,0,3,0 + 0,0,0,3 + 0,0,0,6 + 9,0,0,0 +12,0,0,0 +``` + +In the above list, the first six points form a single constellation: `0,0,0,0` is exactly distance `3` from the next four, and the point at `0,0,0,6` is connected to the others by being `3` away from `0,0,0,3`, which is already in the constellation. The bottom two points, `9,0,0,0` and `12,0,0,0` are in a separate constellation because no point is close enough to connect them to the first constellation. So, in the above list, the number of constellations is `*2*`. (If a point at `6,0,0,0` were present, it would connect `3,0,0,0` and `9,0,0,0`, merging all of the points into a single giant constellation instead.) + +In this example, the number of constellations is `4`: + +``` +-1,2,2,0 +0,0,2,-2 +0,0,0,-2 +-1,2,0,0 +-2,-2,-2,2 +3,0,2,-1 +-1,3,2,2 +-1,0,-1,0 +0,2,1,-2 +3,0,0,0 +``` + +In this one, it's `3`: + +``` +1,-1,0,1 +2,0,-1,0 +3,2,-1,0 +0,0,3,1 +0,0,-1,-1 +2,3,-2,0 +-2,2,0,0 +2,-2,0,-1 +1,-1,0,-1 +3,2,0,2 +``` + +Finally, in this one, it's `8`: + +``` +1,-1,-1,-2 +-2,-2,0,1 +0,2,1,3 +-2,3,-2,1 +0,2,3,-2 +-1,-1,1,-2 +0,-2,-1,0 +-2,2,3,-1 +1,2,2,0 +-1,-2,0,-2 +``` + +The portly man nervously strokes his white beard. It's time to get that hot chocolate. + +*How many constellations are formed by the fixed points in spacetime?* + + +## --- Part Two --- +A small glowing portal opens above the mug you prepared and just enough hot chocolate streams in to fill it. You suspect the reindeer has never encountered hot chocolate before, but seems to enjoy it anyway. You hope it works. + +It's time to start worrying about that *integer underflow in time itself* you [set up a few days ago](21). You check the status of the device: "Insufficient chronal energy for activation. Energy required: *50 stars*." + +The reindeer bumps the device with its nose. + +"Energy required: *49 stars*." + + diff --git a/2018/Day25/input.in b/2018/Day25/input.in index 9f40980a4..24ec3b69e 100644 Binary files a/2018/Day25/input.in and b/2018/Day25/input.in differ diff --git a/2018/README.md b/2018/README.md index 1d7ec08e1..ad9b93160 100644 --- a/2018/README.md +++ b/2018/README.md @@ -1,4 +1,6 @@ + # Advent of Code (2018) Check out https://adventofcode.com/2018. + diff --git a/2018/SplashScreen.cs b/2018/SplashScreen.cs index 56bcdf187..144ab8e5d 100644 --- a/2018/SplashScreen.cs +++ b/2018/SplashScreen.cs @@ -1,3 +1,4 @@ + using System; namespace AdventOfCode.Y2018; @@ -8,163 +9,163 @@ public void Show() { var color = Console.ForegroundColor; Write(0xcc00, false, " ▄█▄ ▄▄█ ▄ ▄ ▄▄▄ ▄▄ ▄█▄ ▄▄▄ ▄█ ▄▄ ▄▄▄ ▄▄█ ▄▄▄\n █▄█ █ █ █ █ █▄█ █ █ █ █ █ █▄ "); - Write(0xcc00, false, " █ █ █ █ █ █▄█\n █ █ █▄█ ▀▄▀ █▄▄ █ █ █▄ █▄█ █ █▄ █▄█ █▄█ █▄▄ 0x0000 | 2018\n "); - Write(0xcc00, false, " \n "); - Write(0xcccccc, false, ". . . . . 25 "); - Write(0xffff66, false, "**\n "); - Write(0xcccccc, false, ". . . . "); - Write(0x886655, false, "\\ / "); - Write(0xcccccc, false, ". 24 "); - Write(0xffff66, false, "**\n "); - Write(0xcccccc, false, ". . "); - Write(0x886655, false, "\\_\\_\\|_/__/ "); - Write(0xcccccc, false, "23 "); - Write(0xffff66, false, "**\n "); - Write(0xcccccc, false, ". . . "); - Write(0xff0000, true, "o"); - Write(0x886655, false, "-_/"); - Write(0xcccccc, false, ".()"); - Write(0x886655, false, "__------- "); - Write(0xcccccc, false, "22 "); - Write(0xffff66, false, "**\n "); - Write(0xcccccc, false, ". . "); - Write(0xffff66, true, "* "); - Write(0x886655, false, "\\____ "); - Write(0xcccccc, false, "21 "); - Write(0xffff66, false, "**\n "); - Write(0xcccccc, false, ". "); - Write(0xff0000, false, "|"); - Write(0xcccccc, false, "\\| \\_"); - Write(0x886655, false, "\\_ "); - Write(0xcccccc, false, "___ / 20 "); - Write(0xffff66, false, "**\n "); - Write(0xcccccc, false, ". |"); - Write(0xff0000, false, "\\| "); - Write(0x886655, false, "/ | || "); - Write(0xcccccc, false, "19 "); - Write(0xffff66, false, "**\n "); - Write(0xcccccc, false, ". "); - Write(0x66ff, false, "_________"); - Write(0xff0000, false, "|"); - Write(0xcccccc, false, "\\|"); - Write(0x66ff, false, "_________ "); - Write(0x886655, false, "/ | || "); - Write(0xcccccc, false, "18 "); - Write(0xffff66, false, "**\n "); - Write(0x66ff, false, "___----- "); - Write(0xcccccc, false, "########### ##### "); - Write(0x66ff, false, "-----___ "); - Write(0xcccccc, false, "17 "); - Write(0xffff66, false, "**\n "); - Write(0x66ff, false, "___--- "); - Write(0xcccccc, false, "### ##### ######### ##### "); - Write(0x66ff, false, "---___ "); - Write(0xcccccc, false, "16 "); - Write(0xffff66, false, "**\n "); - Write(0xcccccc, false, ") )) ) ) __"); - Write(0xff0000, false, "__ "); - Write(0xcccccc, false, "15 "); - Write(0xffff66, false, "**\n "); - Write(0xff0000, false, ".-"); - Write(0xcccccc, false, "("); - Write(0xff0000, false, "-"); - Write(0xcccccc, false, "(("); - Write(0xff0000, false, "-. "); - Write(0x9900, false, ".--"); - Write(0xcccccc, false, "("); - Write(0x9900, false, "-"); - Write(0xcccccc, false, "("); - Write(0x9900, false, "-. "); - Write(0xff0000, false, "/ "); - Write(0xcccccc, false, "_"); - Write(0xff0000, false, "\\ "); - Write(0xcccccc, false, "\\ 14 "); - Write(0xffff66, false, "**\n "); - Write(0xff0000, false, "'------'_ "); - Write(0x9900, false, "'------'_ "); - Write(0xff0000, false, "|"); - Write(0xcccccc, false, "/| |/"); - Write(0xff0000, false, "| "); - Write(0xcccccc, false, "13 "); - Write(0xffff66, false, "**\n "); - Write(0xff0000, false, "| | ) "); - Write(0x9900, false, "| | ) "); - Write(0xcccccc, false, "|_| "); - Write(0xff0000, false, "|/"); - Write(0xcccccc, false, "| 12 "); - Write(0xffff66, false, "**\n "); - Write(0xff0000, false, "| |/ "); - Write(0x9900, false, "| |/ "); - Write(0xcccccc, false, "|/"); - Write(0xff0000, false, "| "); - Write(0xcccccc, false, "11 "); - Write(0xffff66, false, "**\n "); - Write(0xff0000, false, "'------' "); - Write(0x9900, false, "'------' "); - Write(0xff0000, false, "|/"); - Write(0xcccccc, false, "| 10 "); - Write(0xffff66, false, "**\n "); - Write(0xff0000, false, "_ __ "); - Write(0xcccccc, false, "|/"); - Write(0xff0000, false, "| "); - Write(0xcccccc, false, " 9 "); - Write(0xffff66, false, "**\n "); - Write(0xff0000, false, ".---_ _ "); - Write(0x880000, false, "| "); - Write(0xff0000, false, "|\\__"); - Write(0x880000, false, "/"); - Write(0xff0000, false, "_/) |/"); - Write(0xcccccc, false, "| 8 "); - Write(0xffff66, false, "**\n "); - Write(0xff0000, false, "/ "); - Write(0x880000, false, "/ "); - Write(0xff0000, false, "/\\| "); - Write(0x999999, false, "__ "); - Write(0x880000, false, ") "); - Write(0xff0000, false, ")__ "); - Write(0x880000, false, "_|"); - Write(0xff0000, false, "_| / "); - Write(0xcccccc, false, "|/"); - Write(0xff0000, false, "| "); - Write(0xcccccc, false, " 7 "); - Write(0xffff66, false, "**\n "); - Write(0xff0000, false, "/ "); - Write(0x880000, false, "/ | "); - Write(0xff0000, false, "\\ "); - Write(0xffff66, true, "* "); - Write(0x999999, false, "/ / \\ "); - Write(0x880000, false, "( "); - Write(0xff0000, false, "( \\_"); - Write(0x880000, false, "/"); - Write(0xff0000, false, "_/ / |/"); - Write(0xcccccc, false, "| 6 "); - Write(0xffff66, false, "**\n "); - Write(0xff0000, false, "/ "); - Write(0x880000, false, "/ \\ "); - Write(0xff0000, false, "\\ "); - Write(0x999999, false, "| | \\/ "); - Write(0x880000, false, "\\_"); - Write(0xff0000, false, "\\____________/ "); - Write(0xcccccc, false, "|_| 5 "); - Write(0xffff66, false, "**\n "); - Write(0xff0000, false, "/ "); - Write(0x880000, false, "/ / \\ "); - Write(0xff0000, false, "\\ "); - Write(0x999999, false, "\\_\\______X_____X_____X_, "); - Write(0xcccccc, false, " 4 "); - Write(0xffff66, false, "**\n "); - Write(0xcccccc, false, "./~~~~~~~~~~~\\. 3 "); - Write(0xffff66, false, "**\n "); - Write(0xcccccc, false, "( .\",^. -\". '.~ ) 2 "); - Write(0xffff66, false, "**\n "); - Write(0xcccccc, false, "_'~~~~~~~~~~~~~'_________ ___ __ _ _ _ _ 1 "); - Write(0xffff66, false, "**\n \n"); - + Write(0xcc00, false, " █ █ █ █ █ █▄█\n █ █ █▄█ ▀▄▀ █▄▄ █ █ █▄ █▄█ █ █▄ █▄█ █▄█ █▄▄ $year = 2018\n "); + Write(0xcc00, false, "\n "); + Write(0xcccccc, false, ". . . . . 25 "); + Write(0xffff66, false, "**\n "); + Write(0xcccccc, false, ". . . . "); + Write(0x886655, false, "\\ / "); + Write(0xcccccc, false, ". 24 "); + Write(0xffff66, false, "**\n "); + Write(0xcccccc, false, ". . "); + Write(0x886655, false, "\\_\\_\\|_/__/ "); + Write(0xcccccc, false, "23 "); + Write(0xffff66, false, "**\n "); + Write(0xcccccc, false, ". . . "); + Write(0xff0000, true, "o"); + Write(0x886655, false, "-_/"); + Write(0xcccccc, false, ".()"); + Write(0x886655, false, "__------- "); + Write(0xcccccc, false, "22 "); + Write(0xffff66, false, "**\n "); + Write(0xcccccc, false, ". . "); + Write(0xffff66, true, "* "); + Write(0x886655, false, "\\____ "); + Write(0xcccccc, false, "21 "); + Write(0xffff66, false, "**\n "); + Write(0xcccccc, false, ". "); + Write(0xff0000, false, "|"); + Write(0xcccccc, false, "\\| \\_"); + Write(0x886655, false, "\\_ "); + Write(0xcccccc, false, "___ / 20 "); + Write(0xffff66, false, "**\n "); + Write(0xcccccc, false, ". |"); + Write(0xff0000, false, "\\| "); + Write(0x886655, false, "/ | || "); + Write(0xcccccc, false, "19 "); + Write(0xffff66, false, "**\n "); + Write(0xcccccc, false, ". "); + Write(0x66ff, false, "_________"); + Write(0xff0000, false, "|"); + Write(0xcccccc, false, "\\|"); + Write(0x66ff, false, "_________ "); + Write(0x886655, false, "/ | || "); + Write(0xcccccc, false, "18 "); + Write(0xffff66, false, "**\n "); + Write(0x66ff, false, "___----- "); + Write(0xcccccc, false, "########### ##### "); + Write(0x66ff, false, "-----___ "); + Write(0xcccccc, false, "17 "); + Write(0xffff66, false, "**\n "); + Write(0x66ff, false, "___--- "); + Write(0xcccccc, false, "### ##### ######### ##### "); + Write(0x66ff, false, "---___ "); + Write(0xcccccc, false, "16 "); + Write(0xffff66, false, "**\n "); + Write(0xcccccc, false, ") )) ) ) __"); + Write(0xff0000, false, "__ "); + Write(0xcccccc, false, "15 "); + Write(0xffff66, false, "**\n "); + Write(0xff0000, false, ".-"); + Write(0xcccccc, false, "("); + Write(0xff0000, false, "-"); + Write(0xcccccc, false, "(("); + Write(0xff0000, false, "-. "); + Write(0x9900, false, ".--"); + Write(0xcccccc, false, "("); + Write(0x9900, false, "-"); + Write(0xcccccc, false, "("); + Write(0x9900, false, "-. "); + Write(0xff0000, false, "/ "); + Write(0xcccccc, false, "_"); + Write(0xff0000, false, "\\ "); + Write(0xcccccc, false, "\\ 14 "); + Write(0xffff66, false, "**\n "); + Write(0xff0000, false, "'------'_ "); + Write(0x9900, false, "'------'_ "); + Write(0xff0000, false, "|"); + Write(0xcccccc, false, "/| |/"); + Write(0xff0000, false, "| "); + Write(0xcccccc, false, "13 "); + Write(0xffff66, false, "**\n "); + Write(0xff0000, false, "| | ) "); + Write(0x9900, false, "| | ) "); + Write(0xcccccc, false, "|_| "); + Write(0xff0000, false, "|/"); + Write(0xcccccc, false, "| 12 "); + Write(0xffff66, false, "**\n "); + Write(0xff0000, false, "| |/ "); + Write(0x9900, false, "| |/ "); + Write(0xcccccc, false, "|/"); + Write(0xff0000, false, "| "); + Write(0xcccccc, false, "11 "); + Write(0xffff66, false, "**\n "); + Write(0xff0000, false, "'------' "); + Write(0x9900, false, "'------' "); + Write(0xff0000, false, "|/"); + Write(0xcccccc, false, "| 10 "); + Write(0xffff66, false, "**\n "); + Write(0xff0000, false, "_ __ "); + Write(0xcccccc, false, "|/"); + Write(0xff0000, false, "| "); + Write(0xcccccc, false, " 9 "); + Write(0xffff66, false, "**\n "); + Write(0xff0000, false, ".---_ _ "); + Write(0x880000, false, "| "); + Write(0xff0000, false, "|\\__"); + Write(0x880000, false, "/"); + Write(0xff0000, false, "_/) |/"); + Write(0xcccccc, false, "| 8 "); + Write(0xffff66, false, "**\n "); + Write(0xff0000, false, "/ "); + Write(0x880000, false, "/ "); + Write(0xff0000, false, "/\\| "); + Write(0x999999, false, "__ "); + Write(0x880000, false, ") "); + Write(0xff0000, false, ")__ "); + Write(0x880000, false, "_|"); + Write(0xff0000, false, "_| / "); + Write(0xcccccc, false, "|/"); + Write(0xff0000, false, "| "); + Write(0xcccccc, false, " 7 "); + Write(0xffff66, false, "**\n "); + Write(0xff0000, false, "/ "); + Write(0x880000, false, "/ | "); + Write(0xff0000, false, "\\ "); + Write(0xffff66, true, "* "); + Write(0x999999, false, "/ / \\ "); + Write(0x880000, false, "( "); + Write(0xff0000, false, "( \\_"); + Write(0x880000, false, "/"); + Write(0xff0000, false, "_/ / |/"); + Write(0xcccccc, false, "| 6 "); + Write(0xffff66, false, "**\n "); + Write(0xff0000, false, "/ "); + Write(0x880000, false, "/ \\ "); + Write(0xff0000, false, "\\ "); + Write(0x999999, false, "| | \\/ "); + Write(0x880000, false, "\\_"); + Write(0xff0000, false, "\\____________/ "); + Write(0xcccccc, false, "|_| 5 "); + Write(0xffff66, false, "**\n "); + Write(0xff0000, false, "/ "); + Write(0x880000, false, "/ / \\ "); + Write(0xff0000, false, "\\ "); + Write(0x999999, false, "\\_\\______X_____X_____X_, "); + Write(0xcccccc, false, " 4 "); + Write(0xffff66, false, "**\n "); + Write(0xcccccc, false, "./~~~~~~~~~~~\\. 3 "); + Write(0xffff66, false, "**\n "); + Write(0xcccccc, false, "( .\",^. -\". '.~ ) 2 "); + Write(0xffff66, false, "**\n "); + Write(0xcccccc, false, "_'~~~~~~~~~~~~~'_________ ___ __ _ _ _ _ 1 "); + Write(0xffff66, false, "**\n \n"); + Console.ForegroundColor = color; Console.WriteLine(); } - private static void Write(int rgb, bool bold, string text){ + private static void Write(int rgb, bool bold, string text){ Console.Write($"\u001b[38;2;{(rgb>>16)&255};{(rgb>>8)&255};{rgb&255}{(bold ? ";1" : "")}m{text}"); - } -} \ No newline at end of file + } +} diff --git a/2018/calendar.svg b/2018/calendar.svg index 341b34a67..dcce84fe2 100644 --- a/2018/calendar.svg +++ b/2018/calendar.svg @@ -1,46 +1,46 @@ - - - + + + ▄█▄ ▄▄█ ▄ ▄ ▄▄▄ ▄▄ ▄█▄  ▄▄▄ ▄█  ▄▄ ▄▄▄ ▄▄█ ▄▄▄ █▄█ █ █ █ █ █▄█ █ █ █   █ █ █▄  █  █ █ █ █ █▄█ -█ █ █▄█ ▀▄▀ █▄▄ █ █ █▄  █▄█ █   █▄ █▄█ █▄█ █▄▄  0x0000 | 2018 +█ █ █▄█ ▀▄▀ █▄▄ █ █ █▄  █▄█ █   █▄ █▄█ █▄█ █▄▄  $year = 2018   -     .         .         .        .        .       25 ** - .        .         .        .       \  /      .   24 ** -              .         .         \_\_\|_/__/      23 ** -       .         .            .  o-_/.()__-------  22 ** -   .       .            *         \____            21 ** -               .       |\|            \_\_ ___  /  20 ** -       .               |\|              / |   ||   19 ** -  .           _________|\|_________    /  |   ||   18 ** -      ___-----  ###########  ##### -----___        17 ** -___---  ###  #####    #########  #####     ---___  16 ** -      ) ))          ) )                    ____    15 ** -   .-(-((-.     .--(-(-.                  / _\ \   14 ** -   '------'_    '------'_                |/|  |/|  13 ** -   |      | )   |      | )               |_|  |/|  12 ** -   |      |/    |      |/                     |/|  11 ** -   '------'     '------'                      |/|  10 ** -                                   _     __   |/|   9 ** -        .---_             _       | |\__/_/)  |/|   8 ** -       / / /\|      __   ) )__   _|_|     /   |/|   7 ** -     / / | \ *    / / \ ( (   \_/_/      /    |/|   6 ** -    /  /  \ \    | | \/  \_\____________/     |_|   5 ** -   / /  / \  \    \_\______X_____X_____X_,          4 ** - ./~~~~~~~~~~~\.                                    3 ** -( .",^. -". '.~ )                                   2 ** -_'~~~~~~~~~~~~~'_________ ___ __ _  _   _    _      1 ** +     .         .         .        .        .       25 ** + .        .         .        .       \  /      .   24 ** +              .         .         \_\_\|_/__/      23 ** +       .         .            .  o-_/.()__-------  22 ** +   .       .            *         \____            21 ** +               .       |\|            \_\_ ___  /  20 ** +       .               |\|              / |   ||   19 ** +  .           _________|\|_________    /  |   ||   18 ** +      ___-----  ###########  ##### -----___        17 ** +___---  ###  #####    #########  #####     ---___  16 ** +      ) ))          ) )                    ____    15 ** +   .-(-((-.     .--(-(-.                  / _\ \   14 ** +   '------'_    '------'_                |/|  |/|  13 ** +   |      | )   |      | )               |_|  |/|  12 ** +   |      |/    |      |/                     |/|  11 ** +   '------'     '------'                      |/|  10 ** +                                   _     __   |/|   9 ** +        .---_             _       | |\__/_/)  |/|   8 ** +       / / /\|      __   ) )__   _|_|     /   |/|   7 ** +     / / | \ *    / / \ ( (   \_/_/      /    |/|   6 ** +    /  /  \ \    | | \/  \_\____________/     |_|   5 ** +   / /  / \  \    \_\______X_____X_____X_,          4 ** + ./~~~~~~~~~~~\.                                    3 ** +( .",^. -". '.~ )                                   2 ** +_'~~~~~~~~~~~~~'_________ ___ __ _  _   _    _      1 ** - \ No newline at end of file + \ No newline at end of file diff --git a/2019/Day01/README.md b/2019/Day01/README.md index 0cca1558b..510a7e65f 100644 --- a/2019/Day01/README.md +++ b/2019/Day01/README.md @@ -1,6 +1,40 @@ +original source: [https://adventofcode.com/2019/day/1](https://adventofcode.com/2019/day/1) ## --- Day 1: The Tyranny of the Rocket Equation --- Santa has become stranded at the edge of the Solar System while delivering presents to other planets! To accurately calculate his position in space, safely align his warp drive, and return to Earth in time to save Christmas, he needs you to bring him measurements from fifty stars. Collect stars by solving puzzles. Two puzzles will be made available on each day in the Advent calendar; the second puzzle is unlocked when you complete the first. Each puzzle grants one star. Good luck! -_Visit the website for the full story and [full puzzle](https://adventofcode.com/2019/day/1) description._ +The Elves quickly load you into a spacecraft and prepare to launch. + +At the first Go / No Go poll, every Elf is Go until the Fuel Counter-Upper. They haven't determined the amount of fuel required yet. + +Fuel required to launch a given module is based on its mass. Specifically, to find the fuel required for a module, take its mass, divide by three, round down, and subtract 2. + +For example: + + + - For a mass of 12, divide by 3 and round down to get 4, then subtract 2 to get 2. + - For a mass of 14, dividing by 3 and rounding down still yields 4, so the fuel required is also 2. + - For a mass of 1969, the fuel required is 654. + - For a mass of 100756, the fuel required is 33583. + +The Fuel Counter-Upper needs to know the total fuel requirement. To find it, individually calculate the fuel needed for the mass of each module (your puzzle input), then add together all the fuel values. + +What is the sum of the fuel requirements for all of the modules on your spacecraft? + + +## --- Part Two --- +During the second Go / No Go poll, the Elf in charge of the Rocket Equation Double-Checker stops the launch sequence. Apparently, you forgot to include additional fuel for the fuel you just added. + +Fuel itself requires fuel just like a module - take its mass, divide by three, round down, and subtract 2. However, that fuel also requires fuel, and that fuel requires fuel, and so on. Any mass that would require negative fuel should instead be treated as if it requires zero fuel; the remaining mass, if any, is instead handled by wishing really hard, which has no mass and is outside the scope of this calculation. + +So, for each module mass, calculate its fuel and add it to the total. Then, treat the fuel amount you just calculated as the input mass and repeat the process, continuing until a fuel requirement is zero or negative. For example: + + + - A module of mass 14 requires 2 fuel. This fuel requires no further fuel (2 divided by 3 and rounded down is 0, which would call for a negative fuel), so the total fuel required is still just 2. + - At first, a module of mass 1969 requires 654 fuel. Then, this fuel requires 216 more fuel (654 / 3 - 2). 216 then requires 70 more fuel, which requires 21 fuel, which requires 5 fuel, which requires no further fuel. So, the total fuel required for a module of mass 1969 is 654 + 216 + 70 + 21 + 5 = 966. + - The fuel required by a module of mass 100756 and its fuel is: 33583 + 11192 + 3728 + 1240 + 411 + 135 + 43 + 12 + 2 = 50346. + +What is the sum of the fuel requirements for all of the modules on your spacecraft when also taking into account the mass of the added fuel? (Calculate the fuel requirements for each module separately, then add them all up at the end.) + + diff --git a/2019/Day01/input.in b/2019/Day01/input.in index 2db97c2a8..e5a50620c 100644 Binary files a/2019/Day01/input.in and b/2019/Day01/input.in differ diff --git a/2019/Day02/README.md b/2019/Day02/README.md index d7c41c9ef..c7a84d94a 100644 --- a/2019/Day02/README.md +++ b/2019/Day02/README.md @@ -1,6 +1,82 @@ +original source: [https://adventofcode.com/2019/day/2](https://adventofcode.com/2019/day/2) ## --- Day 2: 1202 Program Alarm --- On the way to your [gravity assist](https://en.wikipedia.org/wiki/Gravity_assist) around the Moon, your ship computer beeps angrily about a "[1202 program alarm](https://www.hq.nasa.gov/alsj/a11/a11.landing.html#1023832)". On the radio, an Elf is already explaining how to handle the situation: "Don't worry, that's perfectly norma--" The ship computer [bursts into flames](https://en.wikipedia.org/wiki/Halt_and_Catch_Fire). You notify the Elves that the computer's [magic smoke](https://en.wikipedia.org/wiki/Magic_smoke) seems to have escaped. "That computer ran *Intcode* programs like the gravity assist program it was working on; surely there are enough spare parts up there to build a new Intcode computer!" -Read the [full puzzle](https://adventofcode.com/2019/day/2). \ No newline at end of file +An Intcode program is a list of [integers](https://en.wikipedia.org/wiki/Integer) separated by commas (like `1,0,0,3,99`). To run one, start by looking at the first integer (called position `0`). Here, you will find an *opcode* - either `1`, `2`, or `99`. The opcode indicates what to do; for example, `99` means that the program is finished and should immediately halt. Encountering an unknown opcode means something went wrong. + +Opcode `1` *adds* together numbers read from two positions and stores the result in a third position. The three integers *immediately after* the opcode tell you these three positions - the first two indicate the *positions* from which you should read the input values, and the third indicates the *position* at which the output should be stored. + +For example, if your Intcode computer encounters `1,10,20,30`, it should read the values at positions `10` and `20`, add those values, and then overwrite the value at position `30` with their sum. + +Opcode `2` works exactly like opcode `1`, except it *multiplies* the two inputs instead of adding them. Again, the three integers after the opcode indicate *where* the inputs and outputs are, not their values. + +Once you're done processing an opcode, *move to the next one* by stepping forward `4` positions. + +For example, suppose you have the following program: + +``` +1,9,10,3,2,3,11,0,99,30,40,50 +``` + +For the purposes of illustration, here is the same program split into multiple lines: + +``` +1,9,10,3, +2,3,11,0, +99, +30,40,50 +``` + +The first four integers, `1,9,10,3`, are at positions `0`, `1`, `2`, and `3`. Together, they represent the first opcode (`1`, addition), the positions of the two inputs (`9` and `10`), and the position of the output (`3`). To handle this opcode, you first need to get the values at the input positions: position `9` contains `30`, and position `10` contains `40`. *Add* these numbers together to get `70`. Then, store this value at the output position; here, the output position (`3`) is *at* position `3`, so it overwrites itself. Afterward, the program looks like this: + +``` +1,9,10,*70*, +2,3,11,0, +99, +30,40,50 +``` + +Step forward `4` positions to reach the next opcode, `2`. This opcode works just like the previous, but it multiplies instead of adding. The inputs are at positions `3` and `11`; these positions contain `70` and `50` respectively. Multiplying these produces `3500`; this is stored at position `0`: + +``` +*3500*,9,10,70, +2,3,11,0, +99, +30,40,50 +``` + +Stepping forward `4` more positions arrives at opcode `99`, halting the program. + +Here are the initial and final states of a few more small programs: + + + - `1,0,0,0,99` becomes `*2*,0,0,0,99` (`1 + 1 = 2`). + - `2,3,0,3,99` becomes `2,3,0,*6*,99` (`3 * 2 = 6`). + - `2,4,4,5,99,0` becomes `2,4,4,5,99,*9801*` (`99 * 99 = 9801`). + - `1,1,1,4,99,5,6,0,99` becomes `*30*,1,1,4,*2*,5,6,0,99`. + +Once you have a working computer, the first step is to restore the gravity assist program (your puzzle input) to the "1202 program alarm" state it had just before the last computer caught fire. To do this, *before running the program*, replace position `1` with the value `12` and replace position `2` with the value `2`. *What value is left at position `0`* after the program halts? + + +## --- Part Two --- +"Good, the new computer seems to be working correctly! *Keep it nearby* during this mission - you'll probably use it again. Real Intcode computers support many more features than your new one, but we'll let you know what they are as you need them." + +"However, your current priority should be to complete your gravity assist around the Moon. For this mission to succeed, we should settle on some terminology for the parts you've already built." + +Intcode programs are given as a list of integers; these values are used as the initial state for the computer's *memory*. When you run an Intcode program, make sure to start by initializing memory to the program's values. A position in memory is called an *address* (for example, the first value in memory is at "address 0"). + +Opcodes (like `1`, `2`, or `99`) mark the beginning of an *instruction*. The values used immediately after an opcode, if any, are called the instruction's *parameters*. For example, in the instruction `1,2,3,4`, `1` is the opcode; `2`, `3`, and `4` are the parameters. The instruction `99` contains only an opcode and has no parameters. + +The address of the current instruction is called the *instruction pointer*; it starts at `0`. After an instruction finishes, the instruction pointer increases by *the number of values in the instruction*; until you add more instructions to the computer, this is always `4` (`1` opcode + `3` parameters) for the add and multiply instructions. (The halt instruction would increase the instruction pointer by `1`, but it halts the program instead.) + +"With terminology out of the way, we're ready to proceed. To complete the gravity assist, you need to *determine what pair of inputs produces the output `19690720`*." + +The inputs should still be provided to the program by replacing the values at addresses `1` and `2`, just like before. In this program, the value placed in address `1` is called the *noun*, and the value placed in address `2` is called the *verb*. Each of the two input values will be between `0` and `99`, inclusive. + +Once the program has halted, its output is available at address `0`, also just like before. Each time you try a pair of inputs, make sure you first *reset the computer's memory to the values in the program* (your puzzle input) - in other words, don't reuse memory from a previous attempt. + +Find the input *noun* and *verb* that cause the program to produce the output `19690720`. *What is `100 * noun + verb`?* (For example, if `noun=12` and `verb=2`, the answer would be `1202`.) + + diff --git a/2019/Day02/input.in b/2019/Day02/input.in index 3cff00467..e416fb09e 100644 Binary files a/2019/Day02/input.in and b/2019/Day02/input.in differ diff --git a/2019/Day03/README.md b/2019/Day03/README.md index a2d766739..65613a39b 100644 --- a/2019/Day03/README.md +++ b/2019/Day03/README.md @@ -1,6 +1,86 @@ +original source: [https://adventofcode.com/2019/day/3](https://adventofcode.com/2019/day/3) ## --- Day 3: Crossed Wires --- The gravity assist was successful, and you're well on your way to the Venus refuelling station. During the rush back on Earth, the fuel management system wasn't completely installed, so that's next on the priority list. Opening the front panel reveals a jumble of wires. Specifically, *two wires* are connected to a central port and extend outward on a grid. You trace the path each wire takes as it leaves the central port, one wire per line of text (your puzzle input). -Read the [full puzzle](https://adventofcode.com/2019/day/3). \ No newline at end of file +The wires twist and turn, but the two wires occasionally cross paths. To fix the circuit, you need to *find the intersection point closest to the central port*. Because the wires are on a grid, use the [Manhattan distance](https://en.wikipedia.org/wiki/Taxicab_geometry) for this measurement. While the wires do technically cross right at the central port where they both start, this point does not count, nor does a wire count as crossing with itself. + +For example, if the first wire's path is `R8,U5,L5,D3`, then starting from the central port (`o`), it goes right `8`, up `5`, left `5`, and finally down `3`: + +``` +........... +........... +........... +....+----+. +....|....|. +....|....|. +....|....|. +.........|. +.o-------+. +........... +``` + +Then, if the second wire's path is `U7,R6,D4,L4`, it goes up `7`, right `6`, down `4`, and left `4`: + +``` +........... +.+-----+... +.|.....|... +.|..+--X-+. +.|..|..|.|. +.|.-*X*--+.|. +.|..|....|. +.|.......|. +.o-------+. +........... +``` + +These wires cross at two locations (marked `X`), but the lower-left one is closer to the central port: its distance is `3 + 3 = 6`. + +Here are a few more examples: + + + - `R75,D30,R83,U83,L12,D49,R71,U7,L72 +U62,R66,U55,R34,D71,R55,D58,R83` = distance `159` + - `R98,U47,R26,D63,R33,U87,L62,D20,R33,U53,R51 +U98,R91,D20,R16,D67,R40,U7,R15,U6,R7` = distance `135` + +*What is the Manhattan distance* from the central port to the closest intersection? + + +## --- Part Two --- +It turns out that this circuit is very timing-sensitive; you actually need to *minimize the signal delay*. + +To do this, calculate the *number of steps* each wire takes to reach each intersection; choose the intersection where the *sum of both wires' steps* is lowest. If a wire visits a position on the grid multiple times, use the steps value from the *first* time it visits that position when calculating the total value of a specific intersection. + +The number of steps a wire takes is the total number of grid squares the wire has entered to get to that location, including the intersection being considered. Again consider the example from above: + +``` +........... +.+-----+... +.|.....|... +.|..+--X-+. +.|..|..|.|. +.|.-X--+.|. +.|..|....|. +.|.......|. +.o-------+. +........... +``` + +In the above example, the intersection closest to the central port is reached after `8+5+5+2 = *20*` steps by the first wire and `7+6+4+3 = *20*` steps by the second wire for a total of `20+20 = *40*` steps. + +However, the top-right intersection is better: the first wire takes only `8+5+2 = *15*` and the second wire takes only `7+6+2 = *15*`, a total of `15+15 = *30*` steps. + +Here are the best steps for the extra examples from above: + + + - `R75,D30,R83,U83,L12,D49,R71,U7,L72 +U62,R66,U55,R34,D71,R55,D58,R83` = `610` steps + - `R98,U47,R26,D63,R33,U87,L62,D20,R33,U53,R51 +U98,R91,D20,R16,D67,R40,U7,R15,U6,R7` = `410` steps + +*What is the fewest combined steps the wires must take to reach an intersection?* + + diff --git a/2019/Day03/input.in b/2019/Day03/input.in index e840a410a..8acc0f837 100644 Binary files a/2019/Day03/input.in and b/2019/Day03/input.in differ diff --git a/2019/Day04/README.md b/2019/Day04/README.md index 1145b177d..86ce6c205 100644 --- a/2019/Day04/README.md +++ b/2019/Day04/README.md @@ -1,6 +1,35 @@ +original source: [https://adventofcode.com/2019/day/4](https://adventofcode.com/2019/day/4) ## --- Day 4: Secure Container --- You arrive at the Venus fuel depot only to discover it's protected by a password. The Elves had written the password on a sticky note, but someone threw it out. However, they do remember a few key facts about the password: -Read the [full puzzle](https://adventofcode.com/2019/day/4). \ No newline at end of file + + - It is a six-digit number. + - The value is within the range given in your puzzle input. + - Two adjacent digits are the same (like `22` in `1*22*345`). + - Going from left to right, the digits *never decrease*; they only ever increase or stay the same (like `111123` or `135679`). + +Other than the range rule, the following are true: + + + - `111111` meets these criteria (double `11`, never decreases). + - `2234*50*` does not meet these criteria (decreasing pair of digits `50`). + - `123789` does not meet these criteria (no double). + +*How many different passwords* within the range given in your puzzle input meet these criteria? + + +## --- Part Two --- +An Elf just remembered one more important detail: the two adjacent matching digits *are not part of a larger group of matching digits*. + +Given this additional criterion, but still ignoring the range rule, the following are now true: + + + - `112233` meets these criteria because the digits never decrease and all repeated digits are exactly two digits long. + - `123*444*` no longer meets the criteria (the repeated `44` is part of a larger group of `444`). + - `111122` meets the criteria (even though `1` is repeated more than twice, it still contains a double `22`). + +*How many different passwords* within the range given in your puzzle input meet all of the criteria? + + diff --git a/2019/Day04/input.in b/2019/Day04/input.in index 079b7dd74..4d7fa7f98 100644 Binary files a/2019/Day04/input.in and b/2019/Day04/input.in differ diff --git a/2019/Day05/README.md b/2019/Day05/README.md index b3908d680..e7c2cefda 100644 --- a/2019/Day05/README.md +++ b/2019/Day05/README.md @@ -1,6 +1,102 @@ +original source: [https://adventofcode.com/2019/day/5](https://adventofcode.com/2019/day/5) ## --- Day 5: Sunny with a Chance of Asteroids --- You're starting to sweat as the ship makes its way toward Mercury. The Elves suggest that you get the air conditioner working by upgrading your ship computer to support the Thermal Environment Supervision Terminal. The Thermal Environment Supervision Terminal (TEST) starts by running a *diagnostic program* (your puzzle input). The TEST diagnostic program will run on [your existing Intcode computer](2) after a few modifications: -Read the [full puzzle](https://adventofcode.com/2019/day/5). \ No newline at end of file +*First*, you'll need to add *two new instructions*: + + + - Opcode `3` takes a single integer as *input* and saves it to the address given by its only parameter. For example, the instruction `3,50` would take an input value and store it at address `50`. + - Opcode `4` *outputs* the value of its only parameter. For example, the instruction `4,50` would output the value at address `50`. + +Programs that use these instructions will come with documentation that explains what should be connected to the input and output. The program `3,0,4,0,99` outputs whatever it gets as input, then halts. + +*Second*, you'll need to add support for *parameter modes*: + +Each parameter of an instruction is handled based on its parameter mode. Right now, your ship computer already understands parameter mode `0`, *position mode*, which causes the parameter to be interpreted as a *position* - if the parameter is `50`, its value is *the value stored at address `50` in memory*. Until now, all parameters have been in position mode. + +Now, your ship computer will also need to handle parameters in mode `1`, *immediate mode*. In immediate mode, a parameter is interpreted as a *value* - if the parameter is `50`, its value is simply *`50`*. + +Parameter modes are stored in the same value as the instruction's opcode. The opcode is a two-digit number based only on the ones and tens digit of the value, that is, the opcode is the rightmost two digits of the first value in an instruction. Parameter modes are single digits, one per parameter, read right-to-left from the opcode: the first parameter's mode is in the hundreds digit, the second parameter's mode is in the thousands digit, the third parameter's mode is in the ten-thousands digit, and so on. Any missing modes are `0`. + +For example, consider the program `1002,4,3,4,33`. + +The first instruction, `1002,4,3,4`, is a *multiply* instruction - the rightmost two digits of the first value, `02`, indicate opcode `2`, multiplication. Then, going right to left, the parameter modes are `0` (hundreds digit), `1` (thousands digit), and `0` (ten-thousands digit, not present and therefore zero): + +``` +ABCDE + 1002 + +DE - two-digit opcode, 02 == opcode 2 + C - mode of 1st parameter, 0 == position mode + B - mode of 2nd parameter, 1 == immediate mode + A - mode of 3rd parameter, 0 == position mode, + omitted due to being a leading zero +``` + +This instruction multiplies its first two parameters. The first parameter, `4` in position mode, works like it did before - its value is the value stored at address `4` (`33`). The second parameter, `3` in immediate mode, simply has value `3`. The result of this operation, `33 * 3 = 99`, is written according to the third parameter, `4` in position mode, which also works like it did before - `99` is written to address `4`. + +Parameters that an instruction writes to will *never be in immediate mode*. + +*Finally*, some notes: + + + - It is important to remember that the instruction pointer should increase by *the number of values in the instruction* after the instruction finishes. Because of the new instructions, this amount is no longer always `4`. + - Integers can be negative: `1101,100,-1,4,0` is a valid program (find `100 + -1`, store the result in position `4`). + +The TEST diagnostic program will start by requesting from the user the ID of the system to test by running an *input* instruction - provide it `1`, the ID for the ship's air conditioner unit. + +It will then perform a series of diagnostic tests confirming that various parts of the Intcode computer, like parameter modes, function correctly. For each test, it will run an *output* instruction indicating how far the result of the test was from the expected value, where `0` means the test was successful. Non-zero outputs mean that a function is not working correctly; check the instructions that were run before the output instruction to see which one failed. + +Finally, the program will output a *diagnostic code* and immediately halt. This final output isn't an error; an output followed immediately by a halt means the program finished. If all outputs were zero except the diagnostic code, the diagnostic program ran successfully. + +After providing `1` to the only input instruction and passing all the tests, *what diagnostic code does the program produce?* + + +## --- Part Two --- +The air conditioner comes online! Its cold air feels good for a while, but then the TEST alarms start to go off. Since the air conditioner can't vent its heat anywhere but back into the spacecraft, it's actually making the air inside the ship *warmer*. + +Instead, you'll need to use the TEST to extend the [thermal radiators](https://en.wikipedia.org/wiki/Spacecraft_thermal_control). Fortunately, the diagnostic program (your puzzle input) is already equipped for this. Unfortunately, your Intcode computer is not. + +Your computer is only missing a few opcodes: + + + - Opcode `5` is *jump-if-true*: if the first parameter is *non-zero*, it sets the instruction pointer to the value from the second parameter. Otherwise, it does nothing. + - Opcode `6` is *jump-if-false*: if the first parameter *is zero*, it sets the instruction pointer to the value from the second parameter. Otherwise, it does nothing. + - Opcode `7` is *less than*: if the first parameter is *less than* the second parameter, it stores `1` in the position given by the third parameter. Otherwise, it stores `0`. + - Opcode `8` is *equals*: if the first parameter is *equal to* the second parameter, it stores `1` in the position given by the third parameter. Otherwise, it stores `0`. + +Like all instructions, these instructions need to support *parameter modes* as described above. + +Normally, after an instruction is finished, the instruction pointer increases by the number of values in that instruction. *However*, if the instruction modifies the instruction pointer, that value is used and the instruction pointer is *not automatically increased*. + +For example, here are several programs that take one input, compare it to the value `8`, and then produce one output: + + + - `3,9,8,9,10,9,4,9,99,-1,8` - Using *position mode*, consider whether the input is *equal to* `8`; output `1` (if it is) or `0` (if it is not). + - `3,9,7,9,10,9,4,9,99,-1,8` - Using *position mode*, consider whether the input is *less than* `8`; output `1` (if it is) or `0` (if it is not). + - `3,3,1108,-1,8,3,4,3,99` - Using *immediate mode*, consider whether the input is *equal to* `8`; output `1` (if it is) or `0` (if it is not). + - `3,3,1107,-1,8,3,4,3,99` - Using *immediate mode*, consider whether the input is *less than *`8`; output `1` (if it is) or `0` (if it is not). + +Here are some jump tests that take an input, then output `0` if the input was zero or `1` if the input was non-zero: + + + - `3,12,6,12,15,1,13,14,13,4,13,99,-1,0,1,9` (using *position mode*) + - `3,3,1105,-1,9,1101,0,0,12,4,12,99,1` (using *immediate mode*) + +Here's a larger example: + +``` +3,21,1008,21,8,20,1005,20,22,107,8,21,20,1006,20,31, +1106,0,36,98,0,0,1002,21,125,20,4,20,1105,1,46,104, +999,1105,1,46,1101,1000,1,20,4,20,1105,1,46,98,99 +``` + +The above example program uses an input instruction to ask for a single number. The program will then output `999` if the input value is below `8`, output `1000` if the input value is equal to `8`, or output `1001` if the input value is greater than `8`. + +This time, when the TEST diagnostic program runs its input instruction to get the ID of the system to test, *provide it `5`*, the ID for the ship's thermal radiator controller. This diagnostic test suite only outputs one number, the *diagnostic code*. + +*What is the diagnostic code for system ID `5`?* + + diff --git a/2019/Day05/input.in b/2019/Day05/input.in index 0d4db2def..5715d4bcb 100644 Binary files a/2019/Day05/input.in and b/2019/Day05/input.in differ diff --git a/2019/Day06/README.md b/2019/Day06/README.md index 44651a79a..5d9340383 100644 --- a/2019/Day06/README.md +++ b/2019/Day06/README.md @@ -1,6 +1,122 @@ +original source: [https://adventofcode.com/2019/day/6](https://adventofcode.com/2019/day/6) ## --- Day 6: Universal Orbit Map --- You've landed at the Universal Orbit Map facility on Mercury. Because navigation in space often involves transferring between orbits, the orbit maps here are useful for finding efficient routes between, for example, you and Santa. You download a map of the local orbits (your puzzle input). Except for the universal Center of Mass (`COM`), every object in space is in orbit around exactly one other object. An [orbit](https://en.wikipedia.org/wiki/Orbit) looks roughly like this: -Read the [full puzzle](https://adventofcode.com/2019/day/6). \ No newline at end of file +``` + \ + \ + | + | +AAA--> o o <--BBB + | + | + / + / +``` + +In this diagram, the object `BBB` is in orbit around `AAA`. The path that `BBB` takes around `AAA` (drawn with lines) is only partly shown. In the map data, this orbital relationship is written `AAA)BBB`, which means "`BBB` is in orbit around `AAA`". + +Before you use your map data to plot a course, you need to make sure it wasn't corrupted during the download. To verify maps, the Universal Orbit Map facility uses *orbit count checksums* - the total number of *direct orbits* (like the one shown above) and *indirect orbits*. + + +Whenever `A` orbits `B` and `B` orbits `C`, then `A` *indirectly orbits* `C`. This chain can be any number of objects long: if `A` orbits `B`, `B` orbits `C`, and `C` orbits `D`, then `A` indirectly orbits `D`. +For example, suppose you have the following map: + +``` +COM)B +B)C +C)D +D)E +E)F +B)G +G)H +D)I +E)J +J)K +K)L +``` + +Visually, the above map of orbits looks like this: + +``` + G - H J - K - L + / / +COM - B - C - D - E - F + \ + I +``` + +In this visual representation, when two objects are connected by a line, the one on the right directly orbits the one on the left. + +Here, we can count the total number of orbits as follows: + + + - `D` directly orbits `C` and indirectly orbits `B` and `COM`, a total of `3` orbits. + - `L` directly orbits `K` and indirectly orbits `J`, `E`, `D`, `C`, `B`, and `COM`, a total of `7` orbits. + - `COM` orbits nothing. + +The total number of direct and indirect orbits in this example is `*42*`. + +*What is the total number of direct and indirect orbits* in your map data? + + +## --- Part Two --- +Now, you just need to figure out how many *orbital transfers* you (`YOU`) need to take to get to Santa (`SAN`). + +You start at the object `YOU` are orbiting; your destination is the object `SAN` is orbiting. An orbital transfer lets you move from any object to an object orbiting or orbited by that object. + +For example, suppose you have the following map: + +``` +COM)B +B)C +C)D +D)E +E)F +B)G +G)H +D)I +E)J +J)K +K)L +K)YOU +I)SAN +``` + +Visually, the above map of orbits looks like this: + +``` + *YOU* + */* + G - H *J - K* - L + / */* +COM - B - C - *D - E* - F + *\* + *I - SAN* +``` + +In this example, `YOU` are in orbit around `K`, and `SAN` is in orbit around `I`. To move from `K` to `I`, a minimum of `4` orbital transfers are required: + + + - `K` to `J` + - `J` to `E` + - `E` to `D` + - `D` to `I` + +Afterward, the map of orbits looks like this: + +``` + G - H J - K - L + / / +COM - B - C - D - E - F + \ + I - SAN + *\* + *YOU* +``` + +*What is the minimum number of orbital transfers required* to move from the object `YOU` are orbiting to the object `SAN` is orbiting? (Between the objects they are orbiting - *not* between `YOU` and `SAN`.) + + diff --git a/2019/Day06/input.in b/2019/Day06/input.in index f2e87ab51..3e21de8e1 100644 Binary files a/2019/Day06/input.in and b/2019/Day06/input.in differ diff --git a/2019/Day07/README.md b/2019/Day07/README.md index d25f07a2a..1e76119ad 100644 --- a/2019/Day07/README.md +++ b/2019/Day07/README.md @@ -1,6 +1,99 @@ +original source: [https://adventofcode.com/2019/day/7](https://adventofcode.com/2019/day/7) ## --- Day 7: Amplification Circuit --- Based on the navigational maps, you're going to need to send more power to your ship's thrusters to reach Santa in time. To do this, you'll need to configure a series of [amplifiers](https://en.wikipedia.org/wiki/Amplifier) already installed on the ship. There are five amplifiers connected in series; each one receives an input signal and produces an output signal. They are connected such that the first amplifier's output leads to the second amplifier's input, the second amplifier's output leads to the third amplifier's input, and so on. The first amplifier's input value is `0`, and the last amplifier's output leads to your ship's thrusters. -Read the [full puzzle](https://adventofcode.com/2019/day/7). \ No newline at end of file +``` + O-------O O-------O O-------O O-------O O-------O +0 ->| Amp A |->| Amp B |->| Amp C |->| Amp D |->| Amp E |-> (to thrusters) + O-------O O-------O O-------O O-------O O-------O +``` + +The Elves have sent you some *Amplifier Controller Software* (your puzzle input), a program that should run on your [existing Intcode computer](5). Each amplifier will need to run a copy of the program. + +When a copy of the program starts running on an amplifier, it will first use an input instruction to ask the amplifier for its current *phase setting* (an integer from `0` to `4`). Each phase setting is used *exactly once*, but the Elves can't remember which amplifier needs which phase setting. + +The program will then call another input instruction to get the amplifier's input signal, compute the correct output signal, and supply it back to the amplifier with an output instruction. (If the amplifier has not yet received an input signal, it waits until one arrives.) + +Your job is to *find the largest output signal that can be sent to the thrusters* by trying every possible combination of phase settings on the amplifiers. Make sure that memory is not shared or reused between copies of the program. + +For example, suppose you want to try the phase setting sequence `3,1,2,4,0`, which would mean setting amplifier `A` to phase setting `3`, amplifier `B` to setting `1`, `C` to `2`, `D` to `4`, and `E` to `0`. Then, you could determine the output signal that gets sent from amplifier `E` to the thrusters with the following steps: + + + - Start the copy of the amplifier controller software that will run on amplifier `A`. At its first input instruction, provide it the amplifier's phase setting, `3`. At its second input instruction, provide it the input signal, `0`. After some calculations, it will use an output instruction to indicate the amplifier's output signal. + - Start the software for amplifier `B`. Provide it the phase setting (`1`) and then whatever output signal was produced from amplifier `A`. It will then produce a new output signal destined for amplifier `C`. + - Start the software for amplifier `C`, provide the phase setting (`2`) and the value from amplifier `B`, then collect its output signal. + - Run amplifier `D`'s software, provide the phase setting (`4`) and input value, and collect its output signal. + - Run amplifier `E`'s software, provide the phase setting (`0`) and input value, and collect its output signal. + +The final output signal from amplifier `E` would be sent to the thrusters. However, this phase setting sequence may not have been the best one; another sequence might have sent a higher signal to the thrusters. + +Here are some example programs: + + + - Max thruster signal *`43210`* (from phase setting sequence `4,3,2,1,0`): +``` +3,15,3,16,1002,16,10,16,1,16,15,15,4,15,99,0,0 +``` + + - Max thruster signal *`54321`* (from phase setting sequence `0,1,2,3,4`): +``` +3,23,3,24,1002,24,10,24,1002,23,-1,23, +101,5,23,23,1,24,23,23,4,23,99,0,0 +``` + + - Max thruster signal *`65210`* (from phase setting sequence `1,0,4,3,2`): +``` +3,31,3,32,1002,32,10,32,1001,31,-2,31,1007,31,0,33, +1002,33,7,33,1,33,31,31,1,32,31,31,4,31,99,0,0,0 +``` + + +Try every combination of phase settings on the amplifiers. *What is the highest signal that can be sent to the thrusters?* + + +## --- Part Two --- +It's no good - in this configuration, the amplifiers can't generate a large enough output signal to produce the thrust you'll need. The Elves quickly talk you through rewiring the amplifiers into a *feedback loop*: + +``` + O-------O O-------O O-------O O-------O O-------O +0 -+->| Amp A |->| Amp B |->| Amp C |->| Amp D |->| Amp E |-. + | O-------O O-------O O-------O O-------O O-------O | + | | + '--------------------------------------------------------+ + | + v + (to thrusters) +``` + +Most of the amplifiers are connected as they were before; amplifier `A`'s output is connected to amplifier `B`'s input, and so on. *However,* the output from amplifier `E` is now connected into amplifier `A`'s input. This creates the feedback loop: the signal will be sent through the amplifiers *many times*. + +In feedback loop mode, the amplifiers need *totally different phase settings*: integers from `5` to `9`, again each used exactly once. These settings will cause the Amplifier Controller Software to repeatedly take input and produce output many times before halting. Provide each amplifier its phase setting at its first input instruction; all further input/output instructions are for signals. + +Don't restart the Amplifier Controller Software on any amplifier during this process. Each one should continue receiving and sending signals until it halts. + +All signals sent or received in this process will be between pairs of amplifiers except the very first signal and the very last signal. To start the process, a `0` signal is sent to amplifier `A`'s input *exactly once*. + +Eventually, the software on the amplifiers will halt after they have processed the final loop. When this happens, the last output signal from amplifier `E` is sent to the thrusters. Your job is to *find the largest output signal that can be sent to the thrusters* using the new phase settings and feedback loop arrangement. + +Here are some example programs: + + + - Max thruster signal *`139629729`* (from phase setting sequence `9,8,7,6,5`): +``` +3,26,1001,26,-4,26,3,27,1002,27,2,27,1,27,26, +27,4,27,1001,28,-1,28,1005,28,6,99,0,0,5 +``` + + - Max thruster signal *`18216`* (from phase setting sequence `9,7,8,5,6`): +``` +3,52,1001,52,-5,52,3,53,1,52,56,54,1007,54,5,55,1005,55,26,1001,54, +-5,54,1105,1,12,1,53,54,53,1008,54,0,55,1001,55,1,55,2,53,55,53,4, +53,1001,56,-1,56,1005,56,6,99,0,0,0,0,10 +``` + + +Try every combination of the new phase settings on the amplifier feedback loop. *What is the highest signal that can be sent to the thrusters?* + + diff --git a/2019/Day07/input.in b/2019/Day07/input.in index 85edf7132..4c51e833e 100644 Binary files a/2019/Day07/input.in and b/2019/Day07/input.in differ diff --git a/2019/Day08/README.md b/2019/Day08/README.md index 50bec7cf7..5e7173b40 100644 --- a/2019/Day08/README.md +++ b/2019/Day08/README.md @@ -1,6 +1,66 @@ +original source: [https://adventofcode.com/2019/day/8](https://adventofcode.com/2019/day/8) ## --- Day 8: Space Image Format --- The Elves' spirits are lifted when they realize you have an opportunity to reboot one of their Mars rovers, and so they are curious if you would spend a brief sojourn on Mars. You land your ship near the rover. When you reach the rover, you discover that it's already in the process of rebooting! It's just waiting for someone to enter a [BIOS](https://en.wikipedia.org/wiki/BIOS) password. The Elf responsible for the rover takes a picture of the password (your puzzle input) and sends it to you via the Digital Sending Network. -Read the [full puzzle](https://adventofcode.com/2019/day/8). \ No newline at end of file +Unfortunately, images sent via the Digital Sending Network aren't encoded with any normal encoding; instead, they're encoded in a special Space Image Format. None of the Elves seem to remember why this is the case. They send you the instructions to decode it. + +Images are sent as a series of digits that each represent the color of a single pixel. The digits fill each row of the image left-to-right, then move downward to the next row, filling rows top-to-bottom until every pixel of the image is filled. + +Each image actually consists of a series of identically-sized *layers* that are filled in this way. So, the first digit corresponds to the top-left pixel of the first layer, the second digit corresponds to the pixel to the right of that on the same layer, and so on until the last digit, which corresponds to the bottom-right pixel of the last layer. + +For example, given an image `3` pixels wide and `2` pixels tall, the image data `123456789012` corresponds to the following image layers: + +``` +Layer 1: 123 + 456 + +Layer 2: 789 + 012 +``` + +The image you received is *`25` pixels wide and `6` pixels tall*. + +To make sure the image wasn't corrupted during transmission, the Elves would like you to find the layer that contains the *fewest `0` digits*. On that layer, what is *the number of `1` digits multiplied by the number of `2` digits?* + + +## --- Part Two --- +Now you're ready to decode the image. The image is rendered by stacking the layers and aligning the pixels with the same positions in each layer. The digits indicate the color of the corresponding pixel: `0` is black, `1` is white, and `2` is transparent. + +The layers are rendered with the first layer in front and the last layer in back. So, if a given position has a transparent pixel in the first and second layers, a black pixel in the third layer, and a white pixel in the fourth layer, the final image would have a *black* pixel at that position. + +For example, given an image `2` pixels wide and `2` pixels tall, the image data `0222112222120000` corresponds to the following image layers: + +``` +Layer 1: *0*2 + 22 + +Layer 2: 1*1* + 22 + +Layer 3: 22 + *1*2 + +Layer 4: 00 + 0*0* +``` + +Then, the full image can be found by determining the top visible pixel in each position: + + + - The top-left pixel is *black* because the top layer is `0`. + - The top-right pixel is *white* because the top layer is `2` (transparent), but the second layer is `1`. + - The bottom-left pixel is *white* because the top two layers are `2`, but the third layer is `1`. + - The bottom-right pixel is *black* because the only visible pixel in that position is `0` (from layer 4). + +So, the final image looks like this: + +``` +01 +10 +``` + +*What message is produced after decoding your image?* + + diff --git a/2019/Day08/input.in b/2019/Day08/input.in index 546534d70..dd31a271a 100644 Binary files a/2019/Day08/input.in and b/2019/Day08/input.in differ diff --git a/2019/Day09/README.md b/2019/Day09/README.md index e063ad056..b72209a49 100644 --- a/2019/Day09/README.md +++ b/2019/Day09/README.md @@ -1,6 +1,53 @@ +original source: [https://adventofcode.com/2019/day/9](https://adventofcode.com/2019/day/9) ## --- Day 9: Sensor Boost --- You've just said goodbye to the rebooted rover and left Mars when you receive a faint distress signal coming from the asteroid belt. It must be the Ceres monitoring station! In order to lock on to the signal, you'll need to boost your sensors. The Elves send up the latest *BOOST* program - Basic Operation Of System Test. -Read the [full puzzle](https://adventofcode.com/2019/day/9). \ No newline at end of file +While BOOST (your puzzle input) is capable of boosting your sensors, for tenuous safety reasons, it refuses to do so until the computer it runs on passes some checks to demonstrate it is a *complete Intcode computer*. + +[Your existing Intcode computer](5) is missing one key feature: it needs support for parameters in *relative mode*. + +Parameters in mode `2`, *relative mode*, behave very similarly to parameters in *position mode*: the parameter is interpreted as a position. Like position mode, parameters in relative mode can be read from or written to. + +The important difference is that relative mode parameters don't count from address `0`. Instead, they count from a value called the *relative base*. The *relative base* starts at `0`. + +The address a relative mode parameter refers to is itself *plus* the current *relative base*. When the relative base is `0`, relative mode parameters and position mode parameters with the same value refer to the same address. + +For example, given a relative base of `50`, a relative mode parameter of `-7` refers to memory address `50 + -7 = *43*`. + +The relative base is modified with the *relative base offset* instruction: + + + - Opcode `9` *adjusts the relative base* by the value of its only parameter. The relative base increases (or decreases, if the value is negative) by the value of the parameter. + +For example, if the relative base is `2000`, then after the instruction `109,19`, the relative base would be `2019`. If the next instruction were `204,-34`, then the value at address `1985` would be output. + +Your Intcode computer will also need a few other capabilities: + + + - The computer's available memory should be much larger than the initial program. Memory beyond the initial program starts with the value `0` and can be read or written like any other memory. (It is invalid to try to access memory at a negative address, though.) + - The computer should have support for large numbers. Some instructions near the beginning of the BOOST program will verify this capability. + +Here are some example programs that use these features: + + + - `109,1,204,-1,1001,100,1,100,1008,100,16,101,1006,101,0,99` takes no input and produces a [copy of itself](https://en.wikipedia.org/wiki/Quine_(computing)) as output. + - `1102,34915192,34915192,7,4,7,99,0` should output a 16-digit number. + - `104,1125899906842624,99` should output the large number in the middle. + +The BOOST program will ask for a single input; run it in test mode by providing it the value `1`. It will perform a series of checks on each opcode, output any opcodes (and the associated parameter modes) that seem to be functioning incorrectly, and finally output a BOOST keycode. + +Once your Intcode computer is fully functional, the BOOST program should report no malfunctioning opcodes when run in test mode; it should only output a single value, the BOOST keycode. *What BOOST keycode does it produce?* + + +## --- Part Two --- +*You now have a complete Intcode computer.* + +Finally, you can lock on to the Ceres distress signal! You just need to boost your sensors using the BOOST program. + +The program runs in sensor boost mode by providing the input instruction the value `2`. Once run, it will boost the sensors automatically, but it might take a few seconds to complete the operation on slower hardware. In sensor boost mode, the program will output a single value: *the coordinates of the distress signal*. + +Run the BOOST program in sensor boost mode. *What are the coordinates of the distress signal?* + + diff --git a/2019/Day09/input.in b/2019/Day09/input.in index 53b584655..233a9794a 100644 Binary files a/2019/Day09/input.in and b/2019/Day09/input.in differ diff --git a/2019/Day10/README.md b/2019/Day10/README.md index 049647f0e..0df798568 100644 --- a/2019/Day10/README.md +++ b/2019/Day10/README.md @@ -1,6 +1,199 @@ +original source: [https://adventofcode.com/2019/day/10](https://adventofcode.com/2019/day/10) ## --- Day 10: Monitoring Station --- You fly into the asteroid belt and reach the Ceres monitoring station. The Elves here have an emergency: they're having trouble tracking all of the asteroids and can't be sure they're safe. The Elves would like to build a new monitoring station in a nearby area of space; they hand you a map of all of the asteroids in that region (your puzzle input). -Read the [full puzzle](https://adventofcode.com/2019/day/10). \ No newline at end of file +The map indicates whether each position is empty (`.`) or contains an asteroid (`#`). The asteroids are much smaller than they appear on the map, and every asteroid is exactly in the center of its marked position. The asteroids can be described with `X,Y` coordinates where `X` is the distance from the left edge and `Y` is the distance from the top edge (so the top-left corner is `0,0` and the position immediately to its right is `1,0`). + +Your job is to figure out which asteroid would be the best place to build a *new monitoring station*. A monitoring station can *detect* any asteroid to which it has *direct line of sight* - that is, there cannot be another asteroid *exactly* between them. This line of sight can be at any angle, not just lines aligned to the grid or diagonally. The *best* location is the asteroid that can *detect* the largest number of other asteroids. + +For example, consider the following map: + +``` +.#..# +..... +##### +....# +...*#*# +``` + +The best location for a new monitoring station on this map is the highlighted asteroid at `3,4` because it can detect `8` asteroids, more than any other location. (The only asteroid it cannot detect is the one at `1,0`; its view of this asteroid is blocked by the asteroid at `2,2`.) All other asteroids are worse locations; they can detect `7` or fewer other asteroids. Here is the number of other asteroids a monitoring station on each asteroid could detect: + +``` +.7..7 +..... +67775 +....7 +...87 +``` + +Here is an asteroid (`#`) and some examples of the ways its line of sight might be blocked. If there were another asteroid at the location of a capital letter, the locations marked with the corresponding lowercase letter would be blocked and could not be detected: + +``` +#......... +...A...... +...B..a... +.EDCG....a +..F.c.b... +.....c.... +..efd.c.gb +.......c.. +....f...c. +...e..d..c +``` + +Here are some larger examples: + + + - Best is `5,8` with `33` other asteroids detected: + +``` +......#.#. +#..#.#.... +..#######. +.#.#.###.. +.#..#..... +..#....#.# +#..#....#. +.##.#..### +##...*#*..#. +.#....#### +``` + + - Best is `1,2` with `35` other asteroids detected: + +``` +#.#...#.#. +.###....#. +.*#*....#... +##.#.#.#.# +....#.#.#. +.##..###.# +..#...##.. +..##....## +......#... +.####.###. +``` + + - Best is `6,3` with `41` other asteroids detected: + +``` +.#..#..### +####.###.# +....###.#. +..###.*#*#.# +##.##.#.#. +....###..# +..#.#..#.# +#..#.#.### +.##...##.# +.....#.#.. +``` + + - Best is `11,13` with `210` other asteroids detected: + +``` +.#..##.###...####### +##.############..##. +.#.######.########.# +.###.#######.####.#. +#####.##.#.##.###.## +..#####..#.######### +#################### +#.####....###.#.#.## +##.################# +#####.##.###..####.. +..######..##.####### +####.##.####...##..# +.#####..#.######.### +##...#.####*#*#####... +#.##########.####### +.####.#.###.###.#.## +....##.##.###..##### +.#.#.###########.### +#.#.#.#####.####.### +###.##.####.##.#..## +``` + + +Find the best location for a new monitoring station. *How many other asteroids can be detected from that location?* + + +## --- Part Two --- +Once you give them the coordinates, the Elves quickly deploy an Instant Monitoring Station to the location and discover the worst: there are simply too many asteroids. + +The only solution is *complete vaporization by giant laser*. + +Fortunately, in addition to an asteroid scanner, the new monitoring station also comes equipped with a giant rotating laser perfect for vaporizing asteroids. The laser starts by pointing *up* and always rotates *clockwise*, vaporizing any asteroid it hits. + +If multiple asteroids are *exactly* in line with the station, the laser only has enough power to vaporize *one* of them before continuing its rotation. In other words, the same asteroids that can be *detected* can be vaporized, but if vaporizing one asteroid makes another one detectable, the newly-detected asteroid won't be vaporized until the laser has returned to the same position by rotating a full 360 degrees. + +For example, consider the following map, where the asteroid with the new monitoring station (and laser) is marked `X`: + +``` +.#....#####...#.. +##...##.#####..## +##...#...#.#####. +..#.....X...###.. +..#.#.....#....## +``` + +The first nine asteroids to get vaporized, in order, would be: + +``` +.#....###*2**4*...#.. +##...##.*1**3*#*6**7*..*9*# +##...#...*5*.*8*####. +..#.....X...###.. +..#.#.....#....## +``` + +Note that some asteroids (the ones behind the asteroids marked `1`, `5`, and `7`) won't have a chance to be vaporized until the next full rotation. The laser continues rotating; the next nine to be vaporized are: + +``` +.#....###.....#.. +##...##...#.....# +##...#......*1**2**3**4*. +..#.....X...*5*##.. +..#.*9*.....*8*....*7**6* +``` + +The next nine to be vaporized are then: + +``` +.*8*....###.....#.. +*5**6*...*9*#...#.....# +*3**4*...*7*........... +..*2*.....X....##.. +..*1*.............. +``` + +Finally, the laser completes its first full rotation (`1` through `3`), a second rotation (`4` through `8`), and vaporizes the last asteroid (`9`) partway through its third rotation: + +``` +......*2**3**4*.....*6*.. +......*1*...*5*.....*7* +................. +........X....*8**9*.. +................. +``` + +In the large example above (the one with the best monitoring station location at `11,13`): + + + - The 1st asteroid to be vaporized is at `11,12`. + - The 2nd asteroid to be vaporized is at `12,1`. + - The 3rd asteroid to be vaporized is at `12,2`. + - The 10th asteroid to be vaporized is at `12,8`. + - The 20th asteroid to be vaporized is at `16,0`. + - The 50th asteroid to be vaporized is at `16,9`. + - The 100th asteroid to be vaporized is at `10,16`. + - The 199th asteroid to be vaporized is at `9,6`. + - *The 200th asteroid to be vaporized is at `8,2`.* + - The 201st asteroid to be vaporized is at `10,9`. + - The 299th and final asteroid to be vaporized is at `11,1`. + +The Elves are placing bets on which will be the *200th* asteroid to be vaporized. Win the bet by determining which asteroid that will be; *what do you get if you multiply its X coordinate by `100` and then add its Y coordinate?* (For example, `8,2` becomes *`802`*.) + + diff --git a/2019/Day10/input.in b/2019/Day10/input.in index 546434ef7..defc14888 100644 Binary files a/2019/Day10/input.in and b/2019/Day10/input.in differ diff --git a/2019/Day11/README.md b/2019/Day11/README.md index b9a2b021d..c7b8d3346 100644 --- a/2019/Day11/README.md +++ b/2019/Day11/README.md @@ -1,6 +1,85 @@ +original source: [https://adventofcode.com/2019/day/11](https://adventofcode.com/2019/day/11) ## --- Day 11: Space Police --- On the way to Jupiter, you're [pulled over](https://www.youtube.com/watch?v=KwY28rpyKDE) by the *Space Police*. "Attention, unmarked spacecraft! You are in violation of Space Law! All spacecraft must have a clearly visible *registration identifier*! You have 24 hours to comply or be sent to [Space Jail](https://www.youtube.com/watch?v=BVn1oQL9sWg&t=5)!" -Read the [full puzzle](https://adventofcode.com/2019/day/11). \ No newline at end of file +Not wanting to be sent to Space Jail, you radio back to the Elves on Earth for help. Although it takes almost three hours for their reply signal to reach you, they send instructions for how to power up the *emergency hull painting robot* and even provide a small [Intcode program](9) (your puzzle input) that will cause it to paint your ship appropriately. + +There's just one problem: you don't have an emergency hull painting robot. + +You'll need to build a new emergency hull painting robot. The robot needs to be able to move around on the grid of square panels on the side of your ship, detect the color of its current panel, and paint its current panel *black* or *white*. (All of the panels are currently *black*.) + +The Intcode program will serve as the brain of the robot. The program uses input instructions to access the robot's camera: provide `0` if the robot is over a *black* panel or `1` if the robot is over a *white* panel. Then, the program will output two values: + + + - First, it will output a value indicating the *color to paint the panel* the robot is over: `0` means to paint the panel *black*, and `1` means to paint the panel *white*. + - Second, it will output a value indicating the *direction the robot should turn*: `0` means it should turn *left 90 degrees*, and `1` means it should turn *right 90 degrees*. + +After the robot turns, it should always move *forward exactly one panel*. The robot starts facing *up*. + +The robot will continue running for a while like this and halt when it is finished drawing. Do not restart the Intcode computer inside the robot during this process. + +For example, suppose the robot is about to start running. Drawing black panels as `.`, white panels as `#`, and the robot pointing the direction it is facing (`< ^ > v`), the initial state and region near the robot looks like this: + +``` +..... +..... +..^.. +..... +..... +``` + +The panel under the robot (not visible here because a `^` is shown instead) is also black, and so any input instructions at this point should be provided `0`. Suppose the robot eventually outputs `1` (paint white) and then `0` (turn left). After taking these actions and moving forward one panel, the region now looks like this: + +``` +..... +..... +.<#.. +..... +..... +``` + +Input instructions should still be provided `0`. Next, the robot might output `0` (paint black) and then `0` (turn left): + +``` +..... +..... +..#.. +.v... +..... +``` + +After more outputs (`1,0`, `1,0`): + +``` +..... +..... +..^.. +.##.. +..... +``` + +The robot is now back where it started, but because it is now on a white panel, input instructions should be provided `1`. After several more outputs (`0,1`, `1,0`, `1,0`), the area looks like this: + +``` +..... +..<#. +...#. +.##.. +..... +``` + +Before you deploy the robot, you should probably have an estimate of the area it will cover: specifically, you need to know the *number of panels it paints at least once*, regardless of color. In the example above, the robot painted *`6` panels* at least once. (It painted its starting panel twice, but that panel is [still only counted once](https://www.youtube.com/watch?v=KjsSvjA5TuE); it also never painted the panel it ended on.) + +Build a new emergency hull painting robot and run the Intcode program on it. *How many panels does it paint at least once?* + + +## --- Part Two --- +You're not sure what it's trying to paint, but it's definitely not a *registration identifier*. The Space Police are getting impatient. + +Checking your external ship cameras again, you notice a white panel marked "emergency hull painting robot starting panel". The rest of the panels are *still black*, but it looks like the robot was expecting to *start on a white panel*, not a black one. + +Based on the Space Law Space Brochure that the Space Police attached to one of your windows, a valid registration identifier is always *eight capital letters*. After starting the robot on a single *white panel* instead, *what registration identifier does it paint* on your hull? + + diff --git a/2019/Day11/input.in b/2019/Day11/input.in index bffe73d76..19cd3bde3 100644 Binary files a/2019/Day11/input.in and b/2019/Day11/input.in differ diff --git a/2019/Day12/README.md b/2019/Day12/README.md index 28ab5b8a6..8298f7f32 100644 --- a/2019/Day12/README.md +++ b/2019/Day12/README.md @@ -1,6 +1,242 @@ +original source: [https://adventofcode.com/2019/day/12](https://adventofcode.com/2019/day/12) ## --- Day 12: The N-Body Problem --- The space near Jupiter is not a very safe place; you need to be careful of a [big distracting red spot](https://en.wikipedia.org/wiki/Great_Red_Spot), extreme [radiation](https://en.wikipedia.org/wiki/Magnetosphere_of_Jupiter), and a [whole lot of moons](https://en.wikipedia.org/wiki/Moons_of_Jupiter#List) swirling around. You decide to start by tracking the four largest moons: *Io*, *Europa*, *Ganymede*, and *Callisto*. After a brief scan, you calculate the *position of each moon* (your puzzle input). You just need to *simulate their motion* so you can avoid them. -Read the [full puzzle](https://adventofcode.com/2019/day/12). \ No newline at end of file +Each moon has a 3-dimensional position (`x`, `y`, and `z`) and a 3-dimensional velocity. The position of each moon is given in your scan; the `x`, `y`, and `z` velocity of each moon starts at `0`. + +Simulate the motion of the moons in *time steps*. Within each time step, first update the velocity of every moon by applying *gravity*. Then, once all moons' velocities have been updated, update the position of every moon by applying *velocity*. Time progresses by one step once all of the positions are updated. + +To apply *gravity*, consider every *pair* of moons. On each axis (`x`, `y`, and `z`), the velocity of each moon changes by *exactly +1 or -1* to pull the moons together. For example, if Ganymede has an `x` position of `3`, and Callisto has a `x` position of `5`, then Ganymede's `x` velocity *changes by +1* (because `5 > 3`) and Callisto's `x` velocity *changes by -1* (because `3 < 5`). However, if the positions on a given axis are the same, the velocity on that axis *does not change* for that pair of moons. + +Once all gravity has been applied, apply *velocity*: simply add the velocity of each moon to its own position. For example, if Europa has a position of `x=1, y=2, z=3` and a velocity of `x=-2, y=0,z=3`, then its new position would be `x=-1, y=2, z=6`. This process does not modify the velocity of any moon. + +For example, suppose your scan reveals the following positions: + +``` + + + + +``` + +Simulating the motion of these moons would produce the following: + +``` +After 0 steps: +pos=, vel= +pos=, vel= +pos=, vel= +pos=, vel= + +After 1 step: +pos=, vel= +pos=, vel= +pos=, vel= +pos=, vel= + +After 2 steps: +pos=, vel= +pos=, vel= +pos=, vel= +pos=, vel= + +After 3 steps: +pos=, vel= +pos=, vel= +pos=, vel= +pos=, vel= + +After 4 steps: +pos=, vel= +pos=, vel= +pos=, vel= +pos=, vel= + +After 5 steps: +pos=, vel= +pos=, vel= +pos=, vel= +pos=, vel= + +After 6 steps: +pos=, vel= +pos=, vel= +pos=, vel= +pos=, vel= + +After 7 steps: +pos=, vel= +pos=, vel= +pos=, vel= +pos=, vel= + +After 8 steps: +pos=, vel= +pos=, vel= +pos=, vel= +pos=, vel= + +After 9 steps: +pos=, vel= +pos=, vel= +pos=, vel= +pos=, vel= + +After 10 steps: +pos=, vel= +pos=, vel= +pos=, vel= +pos=, vel= +``` + +Then, it might help to calculate the *total energy in the system*. The total energy for a single moon is its *potential energy* multiplied by its *kinetic energy*. A moon's *potential energy* is the sum of the [absolute values](https://en.wikipedia.org/wiki/Absolute_value) of its `x`, `y`, and `z` position coordinates. A moon's *kinetic energy* is the sum of the absolute values of its velocity coordinates. Below, each line shows the calculations for a moon's potential energy (`pot`), kinetic energy (`kin`), and total energy: + +``` +Energy after 10 steps: +pot: 2 + 1 + 3 = 6; kin: 3 + 2 + 1 = 6; total: 6 * 6 = 36 +pot: 1 + 8 + 0 = 9; kin: 1 + 1 + 3 = 5; total: 9 * 5 = 45 +pot: 3 + 6 + 1 = 10; kin: 3 + 2 + 3 = 8; total: 10 * 8 = 80 +pot: 2 + 0 + 4 = 6; kin: 1 + 1 + 1 = 3; total: 6 * 3 = 18 +Sum of total energy: 36 + 45 + 80 + 18 = *179* +``` + +In the above example, adding together the total energy for all moons after 10 steps produces the total energy in the system, `*179*`. + +Here's a second example: + +``` + + + + +``` + +Every ten steps of simulation for 100 steps produces: + +``` +After 0 steps: +pos=, vel= +pos=, vel= +pos=, vel= +pos=, vel= + +After 10 steps: +pos=, vel= +pos=, vel= +pos=, vel= +pos=, vel= + +After 20 steps: +pos=, vel= +pos=, vel= +pos=, vel= +pos=, vel= + +After 30 steps: +pos=, vel= +pos=, vel= +pos=, vel= +pos=, vel= + +After 40 steps: +pos=, vel= +pos=, vel= +pos=, vel= +pos=, vel= + +After 50 steps: +pos=, vel= +pos=, vel= +pos=, vel= +pos=, vel= + +After 60 steps: +pos=, vel= +pos=, vel= +pos=, vel= +pos=, vel= + +After 70 steps: +pos=, vel= +pos=, vel= +pos=, vel= +pos=, vel= + +After 80 steps: +pos=, vel= +pos=, vel= +pos=, vel= +pos=, vel= + +After 90 steps: +pos=, vel= +pos=, vel= +pos=, vel= +pos=, vel= + +After 100 steps: +pos=, vel= +pos=, vel= +pos=, vel= +pos=, vel= + +Energy after 100 steps: +pot: 8 + 12 + 9 = 29; kin: 7 + 3 + 0 = 10; total: 29 * 10 = 290 +pot: 13 + 16 + 3 = 32; kin: 3 + 11 + 5 = 19; total: 32 * 19 = 608 +pot: 29 + 11 + 1 = 41; kin: 3 + 7 + 4 = 14; total: 41 * 14 = 574 +pot: 16 + 13 + 23 = 52; kin: 7 + 1 + 1 = 9; total: 52 * 9 = 468 +Sum of total energy: 290 + 608 + 574 + 468 = *1940* +``` + +*What is the total energy in the system* after simulating the moons given in your scan for `1000` steps? + + +## --- Part Two --- +All this drifting around in space makes you wonder about the nature of the universe. Does history really repeat itself? You're curious whether the moons will ever return to a previous state. + +Determine *the number of steps* that must occur before all of the moons' *positions and velocities* exactly match a previous point in time. + +For example, the first example above takes `2772` steps before they exactly match a previous point in time; it eventually returns to the initial state: + +``` +After 0 steps: +pos=, vel= +pos=, vel= +pos=, vel= +pos=, vel= + +After 2770 steps: +pos=, vel= +pos=, vel= +pos=, vel= +pos=, vel= + +After 2771 steps: +pos=, vel= +pos=, vel= +pos=, vel= +pos=, vel= + +After 2772 steps: +pos=, vel= +pos=, vel= +pos=, vel= +pos=, vel= +``` + +Of course, the universe might last for a *very long time* before repeating. Here's a copy of the second example from above: + +``` + + + + +``` + +This set of initial positions takes `4686774924` steps before it repeats a previous state! Clearly, you might need to *find a more efficient way to simulate the universe*. + +*How many steps does it take* to reach the first state that exactly matches a previous state? + + diff --git a/2019/Day12/input.in b/2019/Day12/input.in index 0e1994f1a..8e4819db0 100644 Binary files a/2019/Day12/input.in and b/2019/Day12/input.in differ diff --git a/2019/Day13/README.md b/2019/Day13/README.md index dfb52a5c1..767f0cd83 100644 --- a/2019/Day13/README.md +++ b/2019/Day13/README.md @@ -1,6 +1,35 @@ +original source: [https://adventofcode.com/2019/day/13](https://adventofcode.com/2019/day/13) ## --- Day 13: Care Package --- As you ponder the solitude of space and the ever-increasing three-hour roundtrip for messages between you and Earth, you notice that the Space Mail Indicator Light is blinking. To help keep you sane, the Elves have sent you a care package. It's a new game for the ship's [arcade cabinet](https://en.wikipedia.org/wiki/Arcade_cabinet)! Unfortunately, the arcade is *all the way* on the other end of the ship. Surely, it won't be hard to build your own - the care package even comes with schematics. -Read the [full puzzle](https://adventofcode.com/2019/day/13). \ No newline at end of file +The arcade cabinet runs [Intcode](9) software like the game the Elves sent (your puzzle input). It has a primitive screen capable of drawing square *tiles* on a grid. The software draws tiles to the screen with output instructions: every three output instructions specify the `x` position (distance from the left), `y` position (distance from the top), and `tile id`. The `tile id` is interpreted as follows: + + + - `0` is an *empty* tile. No game object appears in this tile. + - `1` is a *wall* tile. Walls are indestructible barriers. + - `2` is a *block* tile. Blocks can be broken by the ball. + - `3` is a *horizontal paddle* tile. The paddle is indestructible. + - `4` is a *ball* tile. The ball moves diagonally and bounces off objects. + +For example, a sequence of output values like `1,2,3,6,5,4` would draw a *horizontal paddle* tile (`1` tile from the left and `2` tiles from the top) and a *ball* tile (`6` tiles from the left and `5` tiles from the top). + +Start the game. *How many block tiles are on the screen when the game exits?* + + +## --- Part Two --- +The game didn't run because you didn't put in any quarters. Unfortunately, you did not bring any quarters. Memory address `0` represents the number of quarters that have been inserted; set it to `2` to play for free. + +The arcade cabinet has a [joystick](https://en.wikipedia.org/wiki/Joystick) that can move left and right. The software reads the position of the joystick with input instructions: + + + - If the joystick is in the *neutral position*, provide `0`. + - If the joystick is *tilted to the left*, provide `-1`. + - If the joystick is *tilted to the right*, provide `1`. + +The arcade cabinet also has a [segment display](https://en.wikipedia.org/wiki/Display_device#Segment_displays) capable of showing a single number that represents the player's current score. When three output instructions specify `X=-1, Y=0`, the third output instruction is not a tile; the value instead specifies the new score to show in the segment display. For example, a sequence of output values like `-1,0,12345` would show `12345` as the player's current score. + +Beat the game by breaking all the blocks. *What is your score after the last block is broken?* + + diff --git a/2019/Day13/input.in b/2019/Day13/input.in index 157e70a9d..3af9123ac 100644 Binary files a/2019/Day13/input.in and b/2019/Day13/input.in differ diff --git a/2019/Day14/README.md b/2019/Day14/README.md index 49e4fe406..59f8fa168 100644 --- a/2019/Day14/README.md +++ b/2019/Day14/README.md @@ -1,6 +1,119 @@ +original source: [https://adventofcode.com/2019/day/14](https://adventofcode.com/2019/day/14) ## --- Day 14: Space Stoichiometry --- As you approach the rings of Saturn, your ship's *low fuel* indicator turns on. There isn't any fuel here, but the rings have plenty of raw material. Perhaps your ship's Inter-Stellar Refinery Union brand *nanofactory* can turn these raw materials into fuel. You ask the nanofactory to produce a list of the *reactions* it can perform that are relevant to this process (your puzzle input). Every reaction turns some quantities of specific *input chemicals* into some quantity of an *output chemical*. Almost every *chemical* is produced by exactly one reaction; the only exception, `ORE`, is the raw material input to the entire process and is not produced by a reaction. -Read the [full puzzle](https://adventofcode.com/2019/day/14). \ No newline at end of file +You just need to know how much `*ORE*` you'll need to collect before you can produce one unit of `*FUEL*`. + +Each reaction gives specific quantities for its inputs and output; reactions cannot be partially run, so only whole integer multiples of these quantities can be used. (It's okay to have leftover chemicals when you're done, though.) For example, the reaction `1 A, 2 B, 3 C => 2 D` means that exactly 2 units of chemical `D` can be produced by consuming exactly 1 `A`, 2 `B` and 3 `C`. You can run the full reaction as many times as necessary; for example, you could produce 10 `D` by consuming 5 `A`, 10 `B`, and 15 `C`. + +Suppose your nanofactory produces the following list of reactions: + +``` +10 ORE => 10 A +1 ORE => 1 B +7 A, 1 B => 1 C +7 A, 1 C => 1 D +7 A, 1 D => 1 E +7 A, 1 E => 1 FUEL +``` + +The first two reactions use only `ORE` as inputs; they indicate that you can produce as much of chemical `A` as you want (in increments of 10 units, each 10 costing 10 `ORE`) and as much of chemical `B` as you want (each costing 1 `ORE`). To produce 1 `FUEL`, a total of *31* `ORE` is required: 1 `ORE` to produce 1 `B`, then 30 more `ORE` to produce the 7 + 7 + 7 + 7 = 28 `A` (with 2 extra `A` wasted) required in the reactions to convert the `B` into `C`, `C` into `D`, `D` into `E`, and finally `E` into `FUEL`. (30 `A` is produced because its reaction requires that it is created in increments of 10.) + +Or, suppose you have the following list of reactions: + +``` +9 ORE => 2 A +8 ORE => 3 B +7 ORE => 5 C +3 A, 4 B => 1 AB +5 B, 7 C => 1 BC +4 C, 1 A => 1 CA +2 AB, 3 BC, 4 CA => 1 FUEL +``` + +The above list of reactions requires *165* `ORE` to produce 1 `FUEL`: + + + - Consume 45 `ORE` to produce 10 `A`. + - Consume 64 `ORE` to produce 24 `B`. + - Consume 56 `ORE` to produce 40 `C`. + - Consume 6 `A`, 8 `B` to produce 2 `AB`. + - Consume 15 `B`, 21 `C` to produce 3 `BC`. + - Consume 16 `C`, 4 `A` to produce 4 `CA`. + - Consume 2 `AB`, 3 `BC`, 4 `CA` to produce 1 `FUEL`. + +Here are some larger examples: + + + - *13312* `ORE` for 1 `FUEL`: + +``` +157 ORE => 5 NZVS +165 ORE => 6 DCFZ +44 XJWVT, 5 KHKGT, 1 QDVJ, 29 NZVS, 9 GPVTF, 48 HKGWZ => 1 FUEL +12 HKGWZ, 1 GPVTF, 8 PSHF => 9 QDVJ +179 ORE => 7 PSHF +177 ORE => 5 HKGWZ +7 DCFZ, 7 PSHF => 2 XJWVT +165 ORE => 2 GPVTF +3 DCFZ, 7 NZVS, 5 HKGWZ, 10 PSHF => 8 KHKGT +``` + + - *180697* `ORE` for 1 `FUEL`: + +``` +2 VPVL, 7 FWMGM, 2 CXFTF, 11 MNCFX => 1 STKFG +17 NVRVD, 3 JNWZP => 8 VPVL +53 STKFG, 6 MNCFX, 46 VJHF, 81 HVMC, 68 CXFTF, 25 GNMV => 1 FUEL +22 VJHF, 37 MNCFX => 5 FWMGM +139 ORE => 4 NVRVD +144 ORE => 7 JNWZP +5 MNCFX, 7 RFSQX, 2 FWMGM, 2 VPVL, 19 CXFTF => 3 HVMC +5 VJHF, 7 MNCFX, 9 VPVL, 37 CXFTF => 6 GNMV +145 ORE => 6 MNCFX +1 NVRVD => 8 CXFTF +1 VJHF, 6 MNCFX => 4 RFSQX +176 ORE => 6 VJHF +``` + + - *2210736* `ORE` for 1 `FUEL`: + +``` +171 ORE => 8 CNZTR +7 ZLQW, 3 BMBT, 9 XCVML, 26 XMNCP, 1 WPTQ, 2 MZWV, 1 RJRHP => 4 PLWSL +114 ORE => 4 BHXH +14 VRPVC => 6 BMBT +6 BHXH, 18 KTJDG, 12 WPTQ, 7 PLWSL, 31 FHTLT, 37 ZDVW => 1 FUEL +6 WPTQ, 2 BMBT, 8 ZLQW, 18 KTJDG, 1 XMNCP, 6 MZWV, 1 RJRHP => 6 FHTLT +15 XDBXC, 2 LTCX, 1 VRPVC => 6 ZLQW +13 WPTQ, 10 LTCX, 3 RJRHP, 14 XMNCP, 2 MZWV, 1 ZLQW => 1 ZDVW +5 BMBT => 4 WPTQ +189 ORE => 9 KTJDG +1 MZWV, 17 XDBXC, 3 XCVML => 2 XMNCP +12 VRPVC, 27 CNZTR => 2 XDBXC +15 KTJDG, 12 BHXH => 5 XCVML +3 BHXH, 2 VRPVC => 7 MZWV +121 ORE => 7 VRPVC +7 XCVML => 6 RJRHP +5 BHXH, 4 VRPVC => 5 LTCX +``` + + +Given the list of reactions in your puzzle input, *what is the minimum amount of `ORE` required to produce exactly 1 `FUEL`?* + + +## --- Part Two --- +After collecting `ORE` for a while, you check your cargo hold: *1 trillion* (*1000000000000*) units of `ORE`. + +*With that much ore*, given the examples above: + + + - The 13312 `ORE`-per-`FUEL` example could produce *82892753* `FUEL`. + - The 180697 `ORE`-per-`FUEL` example could produce *5586022* `FUEL`. + - The 2210736 `ORE`-per-`FUEL` example could produce *460664* `FUEL`. + +Given 1 trillion `ORE`, *what is the maximum amount of `FUEL` you can produce?* + + diff --git a/2019/Day14/input.in b/2019/Day14/input.in index 929a13c2c..46d010b6b 100644 Binary files a/2019/Day14/input.in and b/2019/Day14/input.in differ diff --git a/2019/Day15/README.md b/2019/Day15/README.md index 0f0aa0e4e..4deb5d598 100644 --- a/2019/Day15/README.md +++ b/2019/Day15/README.md @@ -1,6 +1,163 @@ +original source: [https://adventofcode.com/2019/day/15](https://adventofcode.com/2019/day/15) ## --- Day 15: Oxygen System --- Out here in deep space, many things can go wrong. Fortunately, many of those things have indicator lights. Unfortunately, one of those lights is lit: the oxygen system for part of the ship has failed! According to the readouts, the oxygen system must have failed days ago after a rupture in oxygen tank two; that section of the ship was automatically sealed once oxygen levels went dangerously low. A single remotely-operated repair droid is your only option for fixing the oxygen system. -Read the [full puzzle](https://adventofcode.com/2019/day/15). \ No newline at end of file +The Elves' care package included an [Intcode](9) program (your puzzle input) that you can use to remotely control the repair droid. By running that program, you can direct the repair droid to the oxygen system and fix the problem. + +The remote control program executes the following steps in a loop forever: + + + - Accept a movement command via an input instruction. + - Send the movement command to the repair droid. + - Wait for the repair droid to finish the movement operation. + - Report on the status of the repair droid via an output instruction. + +Only four movement commands are understood: north (1), south (2), west (3), and east (4). Any other command is invalid. The movements differ in direction, but not in distance: in a long enough east-west hallway, a series of commands like 4,4,4,4,3,3,3,3 would leave the repair droid back where it started. + +The repair droid can reply with any of the following status codes: + + + - 0: The repair droid hit a wall. Its position has not changed. + - 1: The repair droid has moved one step in the requested direction. + - 2: The repair droid has moved one step in the requested direction; its new position is the location of the oxygen system. + +You don't know anything about the area around the repair droid, but you can figure it out by watching the status codes. + +For example, we can draw the area using D for the droid, # for walls, . for locations the droid can traverse, and empty space for unexplored locations. Then, the initial state looks like this: + +
+      
+      
+   D  
+      
+      
+
+
+ +To make the droid go north, send it 1. If it replies with 0, you know that location is a wall and that the droid didn't move: + +
+      
+   #  
+   D  
+      
+      
+
+
+ +To move east, send 4; a reply of 1 means the movement was successful: + +
+      
+   #  
+   .D 
+      
+      
+
+
+ +Then, perhaps attempts to move north (1), south (2), and east (4) are all met with replies of 0: + +
+      
+   ## 
+   .D#
+    # 
+      
+
+
+ +Now, you know the repair droid is in a dead end. Backtrack with 3 (which you already know will get a reply of 1 because you already know that location is open): + +
+      
+   ## 
+   D.#
+    # 
+      
+
+
+ +Then, perhaps west (3) gets a reply of 0, south (2) gets a reply of 1, south again (2) gets a reply of 0, and then west (3) gets a reply of 2: + +
+      
+   ## 
+  #..#
+  D.# 
+   #  
+
+
+ +Now, because of the reply of 2, you know you've found the oxygen system! In this example, it was only 2 moves away from the repair droid's starting position. + +What is the fewest number of movement commands required to move the repair droid from its starting position to the location of the oxygen system? + + +## --- Part Two --- +You quickly repair the oxygen system; oxygen gradually fills the area. + +Oxygen starts in the location containing the repaired oxygen system. It takes one minute for oxygen to spread to all open locations that are adjacent to a location that already contains oxygen. Diagonal locations are not adjacent. + +In the example above, suppose you've used the droid to explore the area fully and have the following map (where locations that currently contain oxygen are marked O): + +
+ ##   
+#..## 
+#.#..#
+#.O.# 
+ ###  
+
+
+ +Initially, the only location which contains oxygen is the location of the repaired oxygen system. However, after one minute, the oxygen spreads to all open (.) locations that are adjacent to a location containing oxygen: + +
+ ##   
+#..## 
+#.#..#
+#OOO# 
+ ###  
+
+
+ +After a total of two minutes, the map looks like this: + +
+ ##   
+#..## 
+#O#O.#
+#OOO# 
+ ###  
+
+
+ +After a total of three minutes: + +
+ ##   
+#O.## 
+#O#OO#
+#OOO# 
+ ###  
+
+
+ +And finally, the whole region is full of oxygen after a total of four minutes: + +
+ ##   
+#OO## 
+#O#OO#
+#OOO# 
+ ###  
+
+
+ +So, in this example, all locations contain oxygen after 4 minutes. + +Use the repair droid to get a complete map of the area. How many minutes will it take to fill with oxygen? + + diff --git a/2019/Day15/input.in b/2019/Day15/input.in index 62aa67426..3a7a90f94 100644 Binary files a/2019/Day15/input.in and b/2019/Day15/input.in differ diff --git a/2019/Day16/README.md b/2019/Day16/README.md index 719505721..696a371f8 100644 --- a/2019/Day16/README.md +++ b/2019/Day16/README.md @@ -1,6 +1,93 @@ +original source: [https://adventofcode.com/2019/day/16](https://adventofcode.com/2019/day/16) ## --- Day 16: Flawed Frequency Transmission --- You're 3/4ths of the way through the [gas giants](https://en.wikipedia.org/wiki/Gas_giant). Not only do roundtrip signals to Earth take five hours, but the signal quality is quite bad as well. You can clean up the signal with the Flawed Frequency Transmission algorithm, or *FFT*. As input, FFT takes a list of numbers. In the signal you received (your puzzle input), each number is a single digit: data like `15243` represents the sequence `1`, `5`, `2`, `4`, `3`. -Read the [full puzzle](https://adventofcode.com/2019/day/16). \ No newline at end of file +FFT operates in repeated *phases*. In each phase, a new list is constructed with the same length as the input list. This new list is also used as the input for the next phase. + +Each element in the new list is built by multiplying every value in the input list by a value in a repeating *pattern* and then adding up the results. So, if the input list were `9, 8, 7, 6, 5` and the pattern for a given element were `1, 2, 3`, the result would be `9*1 + 8*2 + 7*3 + 6*1 + 5*2` (with each input element on the left and each value in the repeating pattern on the right of each multiplication). Then, only the ones digit is kept: `38` becomes `8`, `-17` becomes `7`, and so on. + +While each element in the output array uses all of the same input array elements, the actual repeating pattern to use depends on *which output element* is being calculated. The base pattern is `0, 1, 0, -1`. Then, repeat each value in the pattern a number of times equal to the *position in the output list* being considered. Repeat once for the first element, twice for the second element, three times for the third element, and so on. So, if the third element of the output list is being calculated, repeating the values would produce: `0, 0, 0, 1, 1, 1, 0, 0, 0, -1, -1, -1`. + +When applying the pattern, skip the very first value exactly once. (In other words, offset the whole pattern left by one.) So, for the second element of the output list, the actual pattern used would be: `0, 1, 1, 0, 0, -1, -1, 0, 0, 1, 1, 0, 0, -1, -1, ...`. + +After using this process to calculate each element of the output list, the phase is complete, and the output list of this phase is used as the new input list for the next phase, if any. + +Given the input signal `12345678`, below are four phases of FFT. Within each phase, each output digit is calculated on a single line with the result at the far right; each multiplication operation shows the input digit on the left and the pattern value on the right: + +``` +Input signal: 12345678 + +1*1 + 2*0 + 3*-1 + 4*0 + 5*1 + 6*0 + 7*-1 + 8*0 = 4 +1*0 + 2*1 + 3*1 + 4*0 + 5*0 + 6*-1 + 7*-1 + 8*0 = 8 +1*0 + 2*0 + 3*1 + 4*1 + 5*1 + 6*0 + 7*0 + 8*0 = 2 +1*0 + 2*0 + 3*0 + 4*1 + 5*1 + 6*1 + 7*1 + 8*0 = 2 +1*0 + 2*0 + 3*0 + 4*0 + 5*1 + 6*1 + 7*1 + 8*1 = 6 +1*0 + 2*0 + 3*0 + 4*0 + 5*0 + 6*1 + 7*1 + 8*1 = 1 +1*0 + 2*0 + 3*0 + 4*0 + 5*0 + 6*0 + 7*1 + 8*1 = 5 +1*0 + 2*0 + 3*0 + 4*0 + 5*0 + 6*0 + 7*0 + 8*1 = 8 + +After 1 phase: 48226158 + +4*1 + 8*0 + 2*-1 + 2*0 + 6*1 + 1*0 + 5*-1 + 8*0 = 3 +4*0 + 8*1 + 2*1 + 2*0 + 6*0 + 1*-1 + 5*-1 + 8*0 = 4 +4*0 + 8*0 + 2*1 + 2*1 + 6*1 + 1*0 + 5*0 + 8*0 = 0 +4*0 + 8*0 + 2*0 + 2*1 + 6*1 + 1*1 + 5*1 + 8*0 = 4 +4*0 + 8*0 + 2*0 + 2*0 + 6*1 + 1*1 + 5*1 + 8*1 = 0 +4*0 + 8*0 + 2*0 + 2*0 + 6*0 + 1*1 + 5*1 + 8*1 = 4 +4*0 + 8*0 + 2*0 + 2*0 + 6*0 + 1*0 + 5*1 + 8*1 = 3 +4*0 + 8*0 + 2*0 + 2*0 + 6*0 + 1*0 + 5*0 + 8*1 = 8 + +After 2 phases: 34040438 + +3*1 + 4*0 + 0*-1 + 4*0 + 0*1 + 4*0 + 3*-1 + 8*0 = 0 +3*0 + 4*1 + 0*1 + 4*0 + 0*0 + 4*-1 + 3*-1 + 8*0 = 3 +3*0 + 4*0 + 0*1 + 4*1 + 0*1 + 4*0 + 3*0 + 8*0 = 4 +3*0 + 4*0 + 0*0 + 4*1 + 0*1 + 4*1 + 3*1 + 8*0 = 1 +3*0 + 4*0 + 0*0 + 4*0 + 0*1 + 4*1 + 3*1 + 8*1 = 5 +3*0 + 4*0 + 0*0 + 4*0 + 0*0 + 4*1 + 3*1 + 8*1 = 5 +3*0 + 4*0 + 0*0 + 4*0 + 0*0 + 4*0 + 3*1 + 8*1 = 1 +3*0 + 4*0 + 0*0 + 4*0 + 0*0 + 4*0 + 3*0 + 8*1 = 8 + +After 3 phases: 03415518 + +0*1 + 3*0 + 4*-1 + 1*0 + 5*1 + 5*0 + 1*-1 + 8*0 = 0 +0*0 + 3*1 + 4*1 + 1*0 + 5*0 + 5*-1 + 1*-1 + 8*0 = 1 +0*0 + 3*0 + 4*1 + 1*1 + 5*1 + 5*0 + 1*0 + 8*0 = 0 +0*0 + 3*0 + 4*0 + 1*1 + 5*1 + 5*1 + 1*1 + 8*0 = 2 +0*0 + 3*0 + 4*0 + 1*0 + 5*1 + 5*1 + 1*1 + 8*1 = 9 +0*0 + 3*0 + 4*0 + 1*0 + 5*0 + 5*1 + 1*1 + 8*1 = 4 +0*0 + 3*0 + 4*0 + 1*0 + 5*0 + 5*0 + 1*1 + 8*1 = 9 +0*0 + 3*0 + 4*0 + 1*0 + 5*0 + 5*0 + 1*0 + 8*1 = 8 + +After 4 phases: 01029498 +``` + +Here are the first eight digits of the final output list after 100 phases for some larger inputs: + + + - `80871224585914546619083218645595` becomes `24176176`. + - `19617804207202209144916044189917` becomes `73745418`. + - `69317163492948606335995924319873` becomes `52432133`. + +After *100* phases of FFT, *what are the first eight digits in the final output list?* + + +## --- Part Two --- +Now that your FFT is working, you can decode the *real signal*. + +The real signal is your puzzle input *repeated 10000 times*. Treat this new signal as a single input list. Patterns are still calculated as before, and 100 phases of FFT are still applied. + +The *first seven digits* of your initial input signal also represent the *message offset*. The message offset is the location of the eight-digit message in the final output list. Specifically, the message offset indicates *the number of digits to skip* before reading the eight-digit message. For example, if the first seven digits of your initial input signal were `1234567`, the eight-digit message would be the eight digits after skipping 1,234,567 digits of the final output list. Or, if the message offset were `7` and your final output list were `98765432109876543210`, the eight-digit message would be `21098765`. (Of course, your real message offset will be a seven-digit number, not a one-digit number like `7`.) + +Here is the eight-digit message in the final output list after 100 phases. The message offset given in each input has been highlighted. (Note that the inputs given below are repeated 10000 times to find the actual starting input lists.) + + + - `*0303673*2577212944063491565474664` becomes `84462026`. + - `*0293510*9699940807407585447034323` becomes `78725270`. + - `*0308177*0884921959731165446850517` becomes `53553731`. + +After repeating your input signal 10000 times and running 100 phases of FFT, *what is the eight-digit message embedded in the final output list?* + + diff --git a/2019/Day16/input.in b/2019/Day16/input.in index 745b563e4..68cecfd2d 100644 Binary files a/2019/Day16/input.in and b/2019/Day16/input.in differ diff --git a/2019/Day17/README.md b/2019/Day17/README.md index 4bd898a5d..1077776c4 100644 --- a/2019/Day17/README.md +++ b/2019/Day17/README.md @@ -1,6 +1,135 @@ +original source: [https://adventofcode.com/2019/day/17](https://adventofcode.com/2019/day/17) ## --- Day 17: Set and Forget --- An early warning system detects an incoming [solar flare](https://en.wikipedia.org/wiki/Solar_flare) and automatically activates the ship's electromagnetic shield. Unfortunately, this has cut off the Wi-Fi for many small robots that, unaware of the impending danger, are now trapped on exterior scaffolding on the unsafe side of the shield. To rescue them, you'll have to act quickly! The only tools at your disposal are some wired cameras and a small vacuum robot currently asleep at its charging station. The video quality is poor, but the vacuum robot has a needlessly bright LED that makes it easy to spot no matter where it is. -Read the [full puzzle](https://adventofcode.com/2019/day/17). \ No newline at end of file +An [Intcode](9) program, the *Aft Scaffolding Control and Information Interface* (ASCII, your puzzle input), provides access to the cameras and the vacuum robot. Currently, because the vacuum robot is asleep, you can only access the cameras. + +Running the ASCII program on your Intcode computer will provide the current view of the scaffolds. This is output, purely coincidentally, as [ASCII code](https://simple.wikipedia.org/wiki/ASCII): `35` means `#`, `46` means `.`, `10` starts a [new line](https://en.wikipedia.org/wiki/Newline#In_programming_languages) of output below the current one, and so on. (Within a line, characters are drawn left-to-right.) + +In the camera output, `#` represents a scaffold and `.` represents open space. The vacuum robot is visible as `^`, `v`, `<`, or `>` depending on whether it is facing up, down, left, or right respectively. When drawn like this, the vacuum robot is *always on a scaffold*; if the vacuum robot ever walks off of a scaffold and begins *tumbling through space uncontrollably*, it will instead be visible as `X`. + +In general, the scaffold forms a path, but it sometimes loops back onto itself. For example, suppose you can see the following view from the cameras: + +``` +..#.......... +..#.......... +#######...### +#.#...#...#.# +############# +..#...#...#.. +..#####...^.. +``` + +Here, the vacuum robot, `^` is facing up and sitting at one end of the scaffold near the bottom-right of the image. The scaffold continues up, loops across itself several times, and ends at the top-left of the image. + +The first step is to calibrate the cameras by getting the *alignment parameters* of some well-defined points. Locate all *scaffold intersections*; for each, its alignment parameter is the distance between its left edge and the left edge of the view multiplied by the distance between its top edge and the top edge of the view. Here, the intersections from the above image are marked `O`: + +``` +..#.......... +..#.......... +##O####...### +#.#...#...#.# +##O###O###O## +..#...#...#.. +..#####...^.. +``` + +For these intersections: + + + - The top-left intersection is `2` units from the left of the image and `2` units from the top of the image, so its alignment parameter is `2 * 2 = *4*`. + - The bottom-left intersection is `2` units from the left and `4` units from the top, so its alignment parameter is `2 * 4 = *8*`. + - The bottom-middle intersection is `6` from the left and `4` from the top, so its alignment parameter is `*24*`. + - The bottom-right intersection's alignment parameter is `*40*`. + +To calibrate the cameras, you need the *sum of the alignment parameters*. In the above example, this is `*76*`. + +Run your ASCII program. *What is the sum of the alignment parameters* for the scaffold intersections? + + +## --- Part Two --- +Now for the tricky part: notifying all the other robots about the solar flare. The vacuum robot can do this automatically if it gets into range of a robot. However, you can't see the other robots on the camera, so you need to be thorough instead: you need to make the vacuum robot *visit every part of the scaffold at least once*. + +The vacuum robot normally wanders randomly, but there isn't time for that today. Instead, you can *override its movement logic* with new rules. + +Force the vacuum robot to wake up by changing the value in your ASCII program at address `0` from `1` to `*2*`. When you do this, you will be automatically prompted for the new movement rules that the vacuum robot should use. The ASCII program will use input instructions to receive them, but they need to be provided as ASCII code; end each line of logic with a single newline, ASCII code `10`. + +First, you will be prompted for the *main movement routine*. The main routine may only call the *movement functions*: `A`, `B`, or `C`. Supply the movement functions to use as ASCII text, separating them with commas (`,`, ASCII code `44`), and ending the list with a newline (ASCII code `10`). For example, to call `A` twice, then alternate between `B` and `C` three times, provide the string `A,A,B,C,B,C,B,C` and then a newline. + +Then, you will be prompted for each *movement function*. Movement functions may use `L` to *turn left*, `R` to *turn right*, or a number to *move forward* that many units. Movement functions may not call other movement functions. Again, separate the actions with commas and end the list with a newline. For example, to move forward `10` units, turn left, move forward `8` units, turn right, and finally move forward `6` units, provide the string `10,L,8,R,6` and then a newline. + +Finally, you will be asked whether you want to see a *continuous video feed*; provide either `y` or `n` and a newline. Enabling the continuous video feed can help you see what's going on, but it also requires a significant amount of processing power, and may even cause your Intcode computer to overheat. + +Due to the limited amount of memory in the vacuum robot, the ASCII definitions of the main routine and the movement functions may each contain *at most 20 characters*, not counting the newline. + +For example, consider the following camera feed: + +``` +#######...##### +#.....#...#...# +#.....#...#...# +......#...#...# +......#...###.# +......#.....#.# +^########...#.# +......#.#...#.# +......######### +........#...#.. +....#########.. +....#...#...... +....#...#...... +....#...#...... +....#####...... +``` + +In order for the vacuum robot to *visit every part of the scaffold at least once*, one path it could take is: + +``` +R,8,R,8,R,4,R,4,R,8,L,6,L,2,R,4,R,4,R,8,R,8,R,8,L,6,L,2``` + +Without the memory limit, you could just supply this whole string to function `A` and have the main routine call `A` once. However, you'll need to split it into smaller parts. + +One approach is: + + + - *Main routine: `A,B,C,B,A,C`* +(ASCII input: `65`, `44`, `66`, `44`, `67`, `44`, `66`, `44`, `65`, `44`, `67`, `10`) + - *Function `A`:   `R,8,R,8`* +(ASCII input: `82`, `44`, `56`, `44`, `82`, `44`, `56`, `10`) + - *Function `B`:   `R,4,R,4,R,8`* +(ASCII input: `82`, `44`, `52`, `44`, `82`, `44`, `52`, `44`, `82`, `44`, `56`, `10`) + - *Function `C`:   `L,6,L,2`* +(ASCII input: `76`, `44`, `54`, `44`, `76`, `44`, `50`, `10`) + +Visually, this would break the desired path into the following parts: + +``` +A, B, C, B, A, C +R,8,R,8, R,4,R,4,R,8, L,6,L,2, R,4,R,4,R,8, R,8,R,8, L,6,L,2 + +CCCCCCA...BBBBB +C.....A...B...B +C.....A...B...B +......A...B...B +......A...CCC.B +......A.....C.B +^AAAAAAAA...C.B +......A.A...C.B +......AAAAAA#AB +........A...C.. +....BBBB#BBBB.. +....B...A...... +....B...A...... +....B...A...... +....BBBBA...... +``` + +Of course, the scaffolding outside your ship is much more complex. + +As the vacuum robot finds other robots and notifies them of the impending solar flare, it also can't help but leave them squeaky clean, collecting any space dust it finds. Once it finishes the programmed set of movements, assuming it hasn't drifted off into space, the cleaning robot will return to its docking station and report the amount of space dust it collected as a large, non-ASCII value in a single output instruction. + +After visiting every part of the scaffold at least once, *how much dust does the vacuum robot report it has collected?* + + diff --git a/2019/Day17/input.in b/2019/Day17/input.in index b98176f73..a2fbf0dce 100644 Binary files a/2019/Day17/input.in and b/2019/Day17/input.in differ diff --git a/2019/Day18/README.md b/2019/Day18/README.md index 21878042c..d28897b42 100644 --- a/2019/Day18/README.md +++ b/2019/Day18/README.md @@ -1,6 +1,294 @@ +original source: [https://adventofcode.com/2019/day/18](https://adventofcode.com/2019/day/18) ## --- Day 18: Many-Worlds Interpretation --- As you approach Neptune, a planetary security system detects you and activates a giant [tractor beam](https://en.wikipedia.org/wiki/Tractor_beam) on [Triton](https://en.wikipedia.org/wiki/Triton_(moon))! You have no choice but to land. A scan of the local area reveals only one interesting feature: a massive underground vault. You generate a map of the tunnels (your puzzle input). The tunnels are too narrow to move diagonally. -Read the [full puzzle](https://adventofcode.com/2019/day/18). \ No newline at end of file +Only one *entrance* (marked `@`) is present among the *open passages* (marked `.`) and *stone walls* (`#`), but you also detect an assortment of *keys* (shown as lowercase letters) and *doors* (shown as uppercase letters). Keys of a given letter open the door of the same letter: `a` opens `A`, `b` opens `B`, and so on. You aren't sure which key you need to disable the tractor beam, so you'll need to *collect all of them*. + +For example, suppose you have the following map: + +``` +######### +#b.A.@.a# +######### +``` + +Starting from the entrance (`@`), you can only access a large door (`A`) and a key (`a`). Moving toward the door doesn't help you, but you can move `2` steps to collect the key, unlocking `A` in the process: + +``` +######### +#b.....@# +######### +``` + +Then, you can move `6` steps to collect the only other key, `b`: + +``` +######### +#@......# +######### +``` + +So, collecting every key took a total of `*8*` steps. + +Here is a larger example: + +``` +######################## +#f.D.E.e.C.b.A.@.a.B.c.# +######################.# +#d.....................# +######################## +``` + +The only reasonable move is to take key `a` and unlock door `A`: + +``` +######################## +#f.D.E.e.C.b.....@.B.c.# +######################.# +#d.....................# +######################## +``` + +Then, do the same with key `b`: + +``` +######################## +#f.D.E.e.C.@.........c.# +######################.# +#d.....................# +######################## +``` + +...and the same with key `c`: + +``` +######################## +#f.D.E.e.............@.# +######################.# +#d.....................# +######################## +``` + +Now, you have a choice between keys `d` and `e`. While key `e` is closer, collecting it now would be slower in the long run than collecting key `d` first, so that's the best choice: + +``` +######################## +#f...E.e...............# +######################.# +#@.....................# +######################## +``` + +Finally, collect key `e` to unlock door `E`, then collect key `f`, taking a grand total of `*86*` steps. + +Here are a few more examples: + + + - ``` +######################## +#...............b.C.D.f# +#.###################### +#.....@.a.B.c.d.A.e.F.g# +######################## +``` + +Shortest path is `132` steps: `b`, `a`, `c`, `d`, `f`, `e`, `g` + + - ``` +################# +#i.G..c...e..H.p# +########.######## +#j.A..b...f..D.o# +########@######## +#k.E..a...g..B.n# +########.######## +#l.F..d...h..C.m# +################# +``` + +Shortest paths are `136` steps; +one is: `a`, `f`, `b`, `j`, `g`, `n`, `h`, `d`, `l`, `o`, `e`, `p`, `c`, `i`, `k`, `m` + + - ``` +######################## +#@..............ac.GI.b# +###d#e#f################ +###A#B#C################ +###g#h#i################ +######################## +``` + +Shortest paths are `81` steps; one is: `a`, `c`, `f`, `i`, `d`, `g`, `b`, `e`, `h` + + +*How many steps is the shortest path that collects all of the keys?* + + +## --- Part Two --- +You arrive at the vault only to discover that there is not one vault, but *four* - each with its own entrance. + +On your map, find the area in the middle that looks like this: + +``` +... +.@. +... +``` + +Update your map to instead use the correct data: + +``` +@#@ +### +@#@ +``` + +This change will split your map into four separate sections, each with its own entrance: + +``` +####### ####### +#a.#Cd# #a.#Cd# +##...## ##*@#@*## +##.@.## --> ##*###*## +##...## ##*@#@*## +#cB#Ab# #cB#Ab# +####### ####### +``` + +Because some of the keys are for doors in other vaults, it would take much too long to collect all of the keys by yourself. Instead, you deploy four remote-controlled robots. Each starts at one of the entrances (`@`). + +Your goal is still to *collect all of the keys in the fewest steps*, but now, each robot has its own position and can move independently. You can only remotely control a single robot at a time. Collecting a key instantly unlocks any corresponding doors, regardless of the vault in which the key or door is found. + +For example, in the map above, the top-left robot first collects key `a`, unlocking door `A` in the bottom-right vault: + +``` +####### +#@.#Cd# +##.#@## +####### +##@#@## +#cB#.b# +####### +``` + +Then, the bottom-right robot collects key `b`, unlocking door `B` in the bottom-left vault: + +``` +####### +#@.#Cd# +##.#@## +####### +##@#.## +#c.#.@# +####### +``` + +Then, the bottom-left robot collects key `c`: + +``` +####### +#@.#.d# +##.#@## +####### +##.#.## +#@.#.@# +####### +``` + +Finally, the top-right robot collects key `d`: + +``` +####### +#@.#.@# +##.#.## +####### +##.#.## +#@.#.@# +####### +``` + +In this example, it only took `*8*` steps to collect all of the keys. + +Sometimes, multiple robots might have keys available, or a robot might have to wait for multiple keys to be collected: + +``` +############### +#d.ABC.#.....a# +######@#@###### +############### +######@#@###### +#b.....#.....c# +############### +``` + +First, the top-right, bottom-left, and bottom-right robots take turns collecting keys `a`, `b`, and `c`, a total of `6 + 6 + 6 = 18` steps. Then, the top-left robot can access key `d`, spending another `6` steps; collecting all of the keys here takes a minimum of `*24*` steps. + +Here's a more complex example: + +``` +############# +#DcBa.#.GhKl# +#.###@#@#I### +#e#d#####j#k# +###C#@#@###J# +#fEbA.#.FgHi# +############# +``` + + + - Top-left robot collects key `a`. + - Bottom-left robot collects key `b`. + - Top-left robot collects key `c`. + - Bottom-left robot collects key `d`. + - Top-left robot collects key `e`. + - Bottom-left robot collects key `f`. + - Bottom-right robot collects key `g`. + - Top-right robot collects key `h`. + - Bottom-right robot collects key `i`. + - Top-right robot collects key `j`. + - Bottom-right robot collects key `k`. + - Top-right robot collects key `l`. + +In the above example, the fewest steps to collect all of the keys is `*32*`. + +Here's an example with more choices: + +``` +############# +#g#f.D#..h#l# +#F###e#E###.# +#dCba@#@BcIJ# +############# +#nK.L@#@G...# +#M###N#H###.# +#o#m..#i#jk.# +############# +``` + +One solution with the fewest steps is: + + + - Top-left robot collects key `e`. + - Top-right robot collects key `h`. + - Bottom-right robot collects key `i`. + - Top-left robot collects key `a`. + - Top-left robot collects key `b`. + - Top-right robot collects key `c`. + - Top-left robot collects key `d`. + - Top-left robot collects key `f`. + - Top-left robot collects key `g`. + - Bottom-right robot collects key `k`. + - Bottom-right robot collects key `j`. + - Top-right robot collects key `l`. + - Bottom-left robot collects key `n`. + - Bottom-left robot collects key `m`. + - Bottom-left robot collects key `o`. + +This example requires at least `*72*` steps to collect all keys. + +After updating your map and using the remote-controlled robots, *what is the fewest steps necessary to collect all of the keys?* + + diff --git a/2019/Day18/input.in b/2019/Day18/input.in index d736bce82..123b7c740 100644 Binary files a/2019/Day18/input.in and b/2019/Day18/input.in differ diff --git a/2019/Day19/README.md b/2019/Day19/README.md index a0a240e7a..113218a28 100644 --- a/2019/Day19/README.md +++ b/2019/Day19/README.md @@ -1,6 +1,82 @@ +original source: [https://adventofcode.com/2019/day/19](https://adventofcode.com/2019/day/19) ## --- Day 19: Tractor Beam --- Unsure of the state of Santa's ship, you borrowed the tractor beam technology from Triton. Time to test it out. When you're safely away from anything else, you activate the tractor beam, but nothing happens. It's hard to tell whether it's working if there's nothing to use it on. Fortunately, your ship's drone system can be configured to deploy a drone to specific coordinates and then check whether it's being pulled. There's even an [Intcode](9) program (your puzzle input) that gives you access to the drone system. -Read the [full puzzle](https://adventofcode.com/2019/day/19). \ No newline at end of file +The program uses two input instructions to request the *X and Y position* to which the drone should be deployed. Negative numbers are invalid and will confuse the drone; all numbers should be *zero or positive*. + +Then, the program will output whether the drone is *stationary* (`0`) or *being pulled by something* (`1`). For example, the coordinate X=`0`, Y=`0` is directly in front of the tractor beam emitter, so the drone control program will always report `1` at that location. + +To better understand the tractor beam, it is important to *get a good picture* of the beam itself. For example, suppose you scan the 10x10 grid of points closest to the emitter: + +``` + X + 0-> 9 + 0#......... + |.#........ + v..##...... + ...###.... + ....###... +Y .....####. + ......#### + ......#### + .......### + 9........## +``` + +In this example, the *number of points affected by the tractor beam* in the 10x10 area closest to the emitter is `*27*`. + +However, you'll need to scan a larger area to *understand the shape* of the beam. *How many points are affected by the tractor beam in the 50x50 area closest to the emitter?* (For each of X and Y, this will be `0` through `49`.) + + +## --- Part Two --- +You aren't sure how large Santa's ship is. You aren't even sure if you'll need to use this thing on Santa's ship, but it doesn't hurt to be prepared. You figure Santa's ship might fit in a *100x100* square. + +The beam gets wider as it travels away from the emitter; you'll need to be a minimum distance away to fit a square of that size into the beam fully. (Don't rotate the square; it should be aligned to the same axes as the drone grid.) + +For example, suppose you have the following tractor beam readings: + +``` +#....................................... +.#...................................... +..##.................................... +...###.................................. +....###................................. +.....####............................... +......#####............................. +......######............................ +.......#######.......................... +........########........................ +.........#########...................... +..........#########..................... +...........##########................... +...........############................. +............############................ +.............#############.............. +..............##############............ +...............###############.......... +................###############......... +................#################....... +.................########*O*OOOOOOOOO..... +..................#######OOOOOOOOOO#.... +...................######OOOOOOOOOO###.. +....................#####OOOOOOOOOO##### +.....................####OOOOOOOOOO##### +.....................####OOOOOOOOOO##### +......................###OOOOOOOOOO##### +.......................##OOOOOOOOOO##### +........................#OOOOOOOOOO##### +.........................OOOOOOOOOO##### +..........................############## +..........................############## +...........................############# +............................############ +.............................########### +``` + +In this example, the *10x10* square closest to the emitter that fits entirely within the tractor beam has been marked `O`. Within it, the point closest to the emitter (the only highlighted `*O*`) is at X=`25`, Y=`20`. + +Find the *100x100* square closest to the emitter that fits entirely within the tractor beam; within that square, find the point closest to the emitter. *What value do you get if you take that point's X coordinate, multiply it by `10000`, then add the point's Y coordinate?* (In the example above, this would be `250020`.) + + diff --git a/2019/Day19/input.in b/2019/Day19/input.in index bca68256b..b50dd1d64 100644 Binary files a/2019/Day19/input.in and b/2019/Day19/input.in differ diff --git a/2019/Day20/README.md b/2019/Day20/README.md index 3fe880d51..7991b7245 100644 --- a/2019/Day20/README.md +++ b/2019/Day20/README.md @@ -1,6 +1,212 @@ +original source: [https://adventofcode.com/2019/day/20](https://adventofcode.com/2019/day/20) ## --- Day 20: Donut Maze --- You notice a strange pattern on the surface of Pluto and land nearby to get a closer look. Upon closer inspection, you realize you've come across one of the famous space-warping mazes of the long-lost Pluto civilization! Because there isn't much space on Pluto, the civilization that used to live here thrived by inventing a method for folding spacetime. Although the technology is no longer understood, mazes like this one provide a small glimpse into the daily life of an ancient Pluto citizen. -Read the [full puzzle](https://adventofcode.com/2019/day/20). \ No newline at end of file +This maze is shaped like a [donut](https://en.wikipedia.org/wiki/Torus). Portals along the inner and outer edge of the donut can instantly teleport you from one side to the other. For example: + +``` + A + A + #######.######### + #######.........# + #######.#######.# + #######.#######.# + #######.#######.# + ##### B ###.# +BC...## C ###.# + ##.## ###.# + ##...DE F ###.# + ##### G ###.# + #########.#####.# +DE..#######...###.# + #.#########.###.# +FG..#########.....# + ###########.##### + Z + Z +``` + +This map of the maze shows solid walls (`#`) and open passages (`.`). Every maze on Pluto has a start (the open tile next to `AA`) and an end (the open tile next to `ZZ`). Mazes on Pluto also have portals; this maze has three pairs of portals: `BC`, `DE`, and `FG`. When on an open tile next to one of these labels, a single step can take you to the other tile with the same label. (You can only walk on `.` tiles; labels and empty space are not traversable.) + +One path through the maze doesn't require any portals. Starting at `AA`, you could go down 1, right 8, down 12, left 4, and down 1 to reach `ZZ`, a total of 26 steps. + +However, there is a shorter path: You could walk from `AA` to the inner `BC` portal (4 steps), warp to the outer `BC` portal (1 step), walk to the inner `DE` (6 steps), warp to the outer `DE` (1 step), walk to the outer `FG` (4 steps), warp to the inner `FG` (1 step), and finally walk to `ZZ` (6 steps). In total, this is only *23* steps. + +Here is a larger example: + +``` + A + A + #################.############# + #.#...#...................#.#.# + #.#.#.###.###.###.#########.#.# + #.#.#.......#...#.....#.#.#...# + #.#########.###.#####.#.#.###.# + #.............#.#.....#.......# + ###.###########.###.#####.#.#.# + #.....# A C #.#.#.# + ####### S P #####.# + #.#...# #......VT + #.#.#.# #.##### + #...#.# YN....#.# + #.###.# #####.# +DI....#.# #.....# + #####.# #.###.# +ZZ......# QG....#..AS + ###.### ####### +JO..#.#.# #.....# + #.#.#.# ###.#.# + #...#..DI BU....#..LF + #####.# #.##### +YN......# VT..#....QG + #.###.# #.###.# + #.#...# #.....# + ###.### J L J #.#.### + #.....# O F P #.#...# + #.###.#####.#.#####.#####.###.# + #...#.#.#...#.....#.....#.#...# + #.#####.###.###.#.#.#########.# + #...#.#.....#...#.#.#.#.....#.# + #.###.#####.###.###.#.#.####### + #.#.........#...#.............# + #########.###.###.############# + B J C + U P P +``` + +Here, `AA` has no direct path to `ZZ`, but it does connect to `AS` and `CP`. By passing through `AS`, `QG`, `BU`, and `JO`, you can reach `ZZ` in *58* steps. + +In your maze, *how many steps does it take to get from the open tile marked `AA` to the open tile marked `ZZ`?* + + +## --- Part Two --- +Strangely, the exit isn't open when you reach it. Then, you remember: the ancient Plutonians were famous for building *recursive spaces*. + +The marked connections in the maze aren't portals: they *physically connect* to a larger or smaller copy of the maze. Specifically, the labeled tiles around the inside edge actually connect to a smaller copy of the same maze, and the smaller copy's inner labeled tiles connect to yet a *smaller* copy, and so on. + +When you enter the maze, you are at the outermost level; when at the outermost level, only the outer labels `AA` and `ZZ` function (as the start and end, respectively); all other outer labeled tiles are effectively walls. At any other level, `AA` and `ZZ` count as walls, but the other outer labeled tiles bring you one level outward. + +Your goal is to find a path through the maze that brings you back to `ZZ` at the outermost level of the maze. + +In the first example above, the shortest path is now the loop around the right side. If the starting level is `0`, then taking the previously-shortest path would pass through `BC` (to level `1`), `DE` (to level `2`), and `FG` (back to level `1`). Because this is not the outermost level, `ZZ` is a wall, and the only option is to go back around to `BC`, which would only send you even deeper into the recursive maze. + +In the second example above, there is no path that brings you to `ZZ` at the outermost level. + +Here is a more interesting example: + +``` + Z L X W C + Z P Q B K + ###########.#.#.#.#######.############### + #...#.......#.#.......#.#.......#.#.#...# + ###.#.#.#.#.#.#.#.###.#.#.#######.#.#.### + #.#...#.#.#...#.#.#...#...#...#.#.......# + #.###.#######.###.###.#.###.###.#.####### + #...#.......#.#...#...#.............#...# + #.#########.#######.#.#######.#######.### + #...#.# F R I Z #.#.#.# + #.###.# D E C H #.#.#.# + #.#...# #...#.# + #.###.# #.###.# + #.#....OA WB..#.#..ZH + #.###.# #.#.#.# +CJ......# #.....# + ####### ####### + #.#....CK #......IC + #.###.# #.###.# + #.....# #...#.# + ###.### #.#.#.# +XF....#.# RF..#.#.# + #####.# ####### + #......CJ NM..#...# + ###.#.# #.###.# +RE....#.# #......RF + ###.### X X L #.#.#.# + #.....# F Q P #.#.#.# + ###.###########.###.#######.#########.### + #.....#...#.....#.......#...#.....#.#...# + #####.#.###.#######.#######.###.###.#.#.# + #.......#.......#.#.#.#.#...#...#...#.#.# + #####.###.#####.#.#.#.#.###.###.#.###.### + #.......#.....#.#...#...............#...# + #############.#.#.###.################### + A O F N + A A D M +``` + +One shortest path through the maze is the following: + + + - Walk from `AA` to `XF` (16 steps) + - Recurse into level 1 through `XF` (1 step) + - Walk from `XF` to `CK` (10 steps) + - Recurse into level 2 through `CK` (1 step) + - Walk from `CK` to `ZH` (14 steps) + - Recurse into level 3 through `ZH` (1 step) + - Walk from `ZH` to `WB` (10 steps) + - Recurse into level 4 through `WB` (1 step) + - Walk from `WB` to `IC` (10 steps) + - Recurse into level 5 through `IC` (1 step) + - Walk from `IC` to `RF` (10 steps) + - Recurse into level 6 through `RF` (1 step) + - Walk from `RF` to `NM` (8 steps) + - Recurse into level 7 through `NM` (1 step) + - Walk from `NM` to `LP` (12 steps) + - Recurse into level 8 through `LP` (1 step) + - Walk from `LP` to `FD` (24 steps) + - Recurse into level 9 through `FD` (1 step) + - Walk from `FD` to `XQ` (8 steps) + - Recurse into level 10 through `XQ` (1 step) + - Walk from `XQ` to `WB` (4 steps) + - Return to level 9 through `WB` (1 step) + - Walk from `WB` to `ZH` (10 steps) + - Return to level 8 through `ZH` (1 step) + - Walk from `ZH` to `CK` (14 steps) + - Return to level 7 through `CK` (1 step) + - Walk from `CK` to `XF` (10 steps) + - Return to level 6 through `XF` (1 step) + - Walk from `XF` to `OA` (14 steps) + - Return to level 5 through `OA` (1 step) + - Walk from `OA` to `CJ` (8 steps) + - Return to level 4 through `CJ` (1 step) + - Walk from `CJ` to `RE` (8 steps) + - Return to level 3 through `RE` (1 step) + - Walk from `RE` to `IC` (4 steps) + - Recurse into level 4 through `IC` (1 step) + - Walk from `IC` to `RF` (10 steps) + - Recurse into level 5 through `RF` (1 step) + - Walk from `RF` to `NM` (8 steps) + - Recurse into level 6 through `NM` (1 step) + - Walk from `NM` to `LP` (12 steps) + - Recurse into level 7 through `LP` (1 step) + - Walk from `LP` to `FD` (24 steps) + - Recurse into level 8 through `FD` (1 step) + - Walk from `FD` to `XQ` (8 steps) + - Recurse into level 9 through `XQ` (1 step) + - Walk from `XQ` to `WB` (4 steps) + - Return to level 8 through `WB` (1 step) + - Walk from `WB` to `ZH` (10 steps) + - Return to level 7 through `ZH` (1 step) + - Walk from `ZH` to `CK` (14 steps) + - Return to level 6 through `CK` (1 step) + - Walk from `CK` to `XF` (10 steps) + - Return to level 5 through `XF` (1 step) + - Walk from `XF` to `OA` (14 steps) + - Return to level 4 through `OA` (1 step) + - Walk from `OA` to `CJ` (8 steps) + - Return to level 3 through `CJ` (1 step) + - Walk from `CJ` to `RE` (8 steps) + - Return to level 2 through `RE` (1 step) + - Walk from `RE` to `XQ` (14 steps) + - Return to level 1 through `XQ` (1 step) + - Walk from `XQ` to `FD` (8 steps) + - Return to level 0 through `FD` (1 step) + - Walk from `FD` to `ZZ` (18 steps) + +This path takes a total of *396* steps to move from `AA` at the outermost layer to `ZZ` at the outermost layer. + +In your maze, when accounting for recursion, *how many steps does it take to get from the open tile marked `AA` to the open tile marked `ZZ`, both at the outermost layer?* + + diff --git a/2019/Day20/input.in b/2019/Day20/input.in index 3ad350028..40ce47f83 100644 Binary files a/2019/Day20/input.in and b/2019/Day20/input.in differ diff --git a/2019/Day21/README.md b/2019/Day21/README.md index 48998e112..a4cbe59a0 100644 --- a/2019/Day21/README.md +++ b/2019/Day21/README.md @@ -1,6 +1,112 @@ +original source: [https://adventofcode.com/2019/day/21](https://adventofcode.com/2019/day/21) ## --- Day 21: Springdroid Adventure --- You lift off from Pluto and start flying in the direction of Santa. While experimenting further with the tractor beam, you accidentally pull an asteroid directly into your ship! It deals significant damage to your hull and causes your ship to begin tumbling violently. -Read the [full puzzle](https://adventofcode.com/2019/day/21). \ No newline at end of file +You can send a droid out to investigate, but the tumbling is causing enough [artificial gravity](https://en.wikipedia.org/wiki/Artificial_gravity) that one wrong step could send the droid through a hole in the hull and flying out into space. + +The clear choice for this mission is a droid that can *jump* over the holes in the hull - a *springdroid*. + +You can use an [Intcode](9) program (your puzzle input) running on an [ASCII-capable](17) computer to [program](https://en.wikipedia.org/wiki/Programmable_read-only_memory) the springdroid. However, springdroids don't run Intcode; instead, they run a simplified assembly language called *springscript*. + +While a springdroid is certainly capable of navigating the artificial gravity and giant holes, it has one downside: it can only remember at most *15* springscript instructions. + +The springdroid will move forward automatically, constantly thinking about *whether to jump*. The springscript program defines the logic for this decision. + +Springscript programs only use [Boolean values](https://en.wikipedia.org/wiki/Boolean_data_type), not numbers or strings. Two registers are available: `T`, the *temporary value* register, and `J`, the *jump* register. If the jump register is *true* at the end of the springscript program, the springdroid will try to jump. Both of these registers start with the value *false*. + +Springdroids have a sensor that can detect *whether there is ground* at various distances in the direction it is facing; these values are provided in *read-only registers*. Your springdroid can detect ground at four distances: one tile away (`A`), two tiles away (`B`), three tiles away (`C`), and four tiles away (`D`). If there is ground at the given distance, the register will be *true*; if there is a hole, the register will be *false*. + +There are only *three instructions* available in springscript: + + + - `AND X Y` sets `Y` to *true* if both `X` and `Y` are *true*; otherwise, it sets `Y` to *false*. + - `OR X Y` sets `Y` to *true* if at least one of `X` or `Y` is *true*; otherwise, it sets `Y` to *false*. + - `NOT X Y` sets `Y` to *true* if `X` is *false*; otherwise, it sets `Y` to *false*. + +In all three instructions, the second argument (`Y`) needs to be a *writable register* (either `T` or `J`). The first argument (`X`) can be *any register* (including `A`, `B`, `C`, or `D`). + +For example, the one-instruction program `NOT A J` means "if the tile immediately in front of me is not ground, jump". + +Or, here is a program that jumps if a three-tile-wide hole (with ground on the other side of the hole) is detected: + +``` +NOT A J +NOT B T +AND T J +NOT C T +AND T J +AND D J +``` + +The Intcode program expects ASCII inputs and outputs. It will begin by displaying a prompt; then, input the desired instructions one per line. End each line with a newline (ASCII code `10`). *When you have finished entering your program*, provide the command `WALK` followed by a newline to instruct the springdroid to begin surveying the hull. + +If the springdroid *falls into space*, an ASCII rendering of the last moments of its life will be produced. In these, `@` is the springdroid, `#` is hull, and `.` is empty space. For example, suppose you program the springdroid like this: + +``` +NOT D J +WALK +``` + +This one-instruction program sets `J` to *true* if and only if there is no ground four tiles away. In other words, it attempts to jump into any hole it finds: + +``` +................. +................. +*@*................ +#####.########### + +................. +................. +.*@*............... +#####.########### + +................. +..*@*.............. +................. +#####.########### + +...*@*............. +................. +................. +#####.########### + +................. +....*@*............ +................. +#####.########### + +................. +................. +.....*@*........... +#####.########### + +................. +................. +................. +#####*@*########### +``` + +However, if the springdroid successfully makes it across, it will use an output instruction to indicate the *amount of damage to the hull* as a single giant integer outside the normal ASCII range. + +Program the springdroid with logic that allows it to survey the hull without falling into space. *What amount of hull damage does it report?* + + +## --- Part Two --- +There are many areas the springdroid can't reach. You flip through the manual and discover a way to *increase its sensor range*. + +Instead of ending your springcode program with `WALK`, use `RUN`. Doing this will enable *extended sensor mode*, capable of sensing ground up to *nine tiles away*. This data is available in *five new read-only registers*: + + + - Register `E` indicates whether there is ground *five* tiles away. + - Register `F` indicates whether there is ground *six* tiles away. + - Register `G` indicates whether there is ground *seven* tiles away. + - Register `H` indicates whether there is ground *eight* tiles away. + - Register `I` indicates whether there is ground *nine* tiles away. + +All other functions remain the same. + +Successfully survey the rest of the hull by ending your program with `RUN`. *What amount of hull damage does the springdroid now report?* + + diff --git a/2019/Day21/input.in b/2019/Day21/input.in index e71d327cc..3ced3cd82 100644 Binary files a/2019/Day21/input.in and b/2019/Day21/input.in differ diff --git a/2019/Day22/README.md b/2019/Day22/README.md index f72411e68..bdad2cd74 100644 --- a/2019/Day22/README.md +++ b/2019/Day22/README.md @@ -1,6 +1,176 @@ +original source: [https://adventofcode.com/2019/day/22](https://adventofcode.com/2019/day/22) ## --- Day 22: Slam Shuffle --- There isn't much to do while you wait for the droids to repair your ship. At least you're drifting in the right direction. You decide to practice a new [card shuffle](https://en.wikipedia.org/wiki/Shuffling) you've been working on. Digging through the ship's storage, you find a deck of *space cards*! Just like any deck of space cards, there are 10007 cards in the deck numbered `0` through `10006`. The deck must be new - they're still in *factory order*, with `0` on the top, then `1`, then `2`, and so on, all the way through to `10006` on the bottom. -Read the [full puzzle](https://adventofcode.com/2019/day/22). \ No newline at end of file +You've been practicing three different *techniques* that you use while shuffling. Suppose you have a deck of only 10 cards (numbered `0` through `9`): + +*To `deal into new stack`*, create a new stack of cards by dealing the top card of the deck onto the top of the new stack repeatedly until you run out of cards: + +``` +Top Bottom +0 1 2 3 4 5 6 7 8 9 Your deck + New stack + + 1 2 3 4 5 6 7 8 9 Your deck + 0 New stack + + 2 3 4 5 6 7 8 9 Your deck + 1 0 New stack + + 3 4 5 6 7 8 9 Your deck + 2 1 0 New stack + +Several steps later... + + 9 Your deck + 8 7 6 5 4 3 2 1 0 New stack + + Your deck +9 8 7 6 5 4 3 2 1 0 New stack +``` + +Finally, pick up the new stack you've just created and use it as the deck for the next technique. + +*To `cut N` cards*, take the top `N` cards off the top of the deck and move them as a single unit to the bottom of the deck, retaining their order. For example, to `cut 3`: + +``` +Top Bottom +0 1 2 3 4 5 6 7 8 9 Your deck + + 3 4 5 6 7 8 9 Your deck +0 1 2 Cut cards + +3 4 5 6 7 8 9 Your deck + 0 1 2 Cut cards + +3 4 5 6 7 8 9 0 1 2 Your deck +``` + +You've also been getting pretty good at a version of this technique where `N` is negative! In that case, cut (the absolute value of) `N` cards from the bottom of the deck onto the top. For example, to `cut -4`: + +``` +Top Bottom +0 1 2 3 4 5 6 7 8 9 Your deck + +0 1 2 3 4 5 Your deck + 6 7 8 9 Cut cards + + 0 1 2 3 4 5 Your deck +6 7 8 9 Cut cards + +6 7 8 9 0 1 2 3 4 5 Your deck +``` + +*To `deal with increment N`*, start by clearing enough space on your table to lay out all of the cards individually in a long line. Deal the top card into the leftmost position. Then, move `N` positions to the right and deal the next card there. If you would move into a position past the end of the space on your table, wrap around and keep counting from the leftmost card again. Continue this process until you run out of cards. + +For example, to `deal with increment 3`: + +``` + +0 1 2 3 4 5 6 7 8 9 Your deck +. . . . . . . . . . Space on table +^ Current position + +Deal the top card to the current position: + + 1 2 3 4 5 6 7 8 9 Your deck +0 . . . . . . . . . Space on table +^ Current position + +Move the current position right 3: + + 1 2 3 4 5 6 7 8 9 Your deck +0 . . . . . . . . . Space on table + ^ Current position + +Deal the top card: + + 2 3 4 5 6 7 8 9 Your deck +0 . . 1 . . . . . . Space on table + ^ Current position + +Move right 3 and deal: + + 3 4 5 6 7 8 9 Your deck +0 . . 1 . . 2 . . . Space on table + ^ Current position + +Move right 3 and deal: + + 4 5 6 7 8 9 Your deck +0 . . 1 . . 2 . . 3 Space on table + ^ Current position + +Move right 3, wrapping around, and deal: + + 5 6 7 8 9 Your deck +0 . 4 1 . . 2 . . 3 Space on table + ^ Current position + +And so on: + +0 7 4 1 8 5 2 9 6 3 Space on table +``` + +Positions on the table which already contain cards are still counted; they're not skipped. Of course, this technique is carefully designed so it will never put two cards in the same position or leave a position empty. + +Finally, collect the cards on the table so that the leftmost card ends up at the top of your deck, the card to its right ends up just below the top card, and so on, until the rightmost card ends up at the bottom of the deck. + +The complete shuffle process (your puzzle input) consists of applying many of these techniques. Here are some examples that combine techniques; they all start with a *factory order* deck of 10 cards: + +``` +deal with increment 7 +deal into new stack +deal into new stack +Result: 0 3 6 9 2 5 8 1 4 7 +``` + +``` +cut 6 +deal with increment 7 +deal into new stack +Result: 3 0 7 4 1 8 5 2 9 6 +``` + +``` +deal with increment 7 +deal with increment 9 +cut -2 +Result: 6 3 0 7 4 1 8 5 2 9 +``` + +``` +deal into new stack +cut -2 +deal with increment 7 +cut 8 +cut -4 +deal with increment 7 +cut 3 +deal with increment 9 +deal with increment 3 +cut -1 +Result: 9 2 5 8 1 4 7 0 3 6 +``` + +Positions within the deck count from `0` at the top, then `1` for the card immediately below the top card, and so on to the bottom. (That is, cards start in the position matching their number.) + +After shuffling your *factory order* deck of 10007 cards, *what is the position of card `2019`?* + + +## --- Part Two --- +After a while, you realize your shuffling skill won't improve much more with merely a single deck of cards. You ask every 3D printer on the ship to make you some more cards while you check on the ship repairs. While reviewing the work the droids have finished so far, you think you see [Halley's Comet](https://en.wikipedia.org/wiki/Halley%27s_Comet) fly past! + +When you get back, you discover that the 3D printers have combined their power to create for you a single, giant, brand new, *factory order* deck of *`119315717514047` space cards*. + +Finally, a deck of cards worthy of shuffling! + +You decide to apply your complete shuffle process (your puzzle input) to the deck *`101741582076661` times in a row*. + +You'll need to be careful, though - one wrong move with this many cards and you might *overflow* your entire ship! + +After shuffling your new, giant, *factory order* deck that many times, *what number is on the card that ends up in position `2020`?* + + diff --git a/2019/Day22/input.in b/2019/Day22/input.in index 0eab6218e..0f3313602 100644 Binary files a/2019/Day22/input.in and b/2019/Day22/input.in differ diff --git a/2019/Day23/README.md b/2019/Day23/README.md index eeb65d376..e9b127fcb 100644 --- a/2019/Day23/README.md +++ b/2019/Day23/README.md @@ -1,6 +1,31 @@ +original source: [https://adventofcode.com/2019/day/23](https://adventofcode.com/2019/day/23) ## --- Day 23: Category Six --- The droids have finished repairing as much of the ship as they can. Their report indicates that this was a *Category 6* disaster - not because it was that bad, but because it destroyed the stockpile of [Category 6](https://en.wikipedia.org/wiki/Category_6_cable) network cables as well as most of the ship's network infrastructure. You'll need to *rebuild the network from scratch*. -Read the [full puzzle](https://adventofcode.com/2019/day/23). \ No newline at end of file +The computers on the network are standard [Intcode](9) computers that communicate by sending *packets* to each other. There are `50` of them in total, each running a copy of the same *Network Interface Controller* (NIC) software (your puzzle input). The computers have *network addresses* `0` through `49`; when each computer boots up, it will request its network address via a single input instruction. Be sure to give each computer a unique network address. + +Once a computer has received its network address, it will begin doing work and communicating over the network by sending and receiving *packets*. All packets contain *two values* named `X` and `Y`. Packets sent to a computer are queued by the recipient and read in the order they are received. + +To *send* a packet to another computer, the NIC will use *three output instructions* that provide the *destination address* of the packet followed by its `X` and `Y` values. For example, three output instructions that provide the values `10`, `20`, `30` would send a packet with `X=20` and `Y=30` to the computer with address `10`. + +To *receive* a packet from another computer, the NIC will use an *input instruction*. If the incoming packet queue is *empty*, provide `-1`. Otherwise, provide the `X` value of the next packet; the computer will then use a second input instruction to receive the `Y` value for the same packet. Once both values of the packet are read in this way, the packet is removed from the queue. + +Note that these input and output instructions never [block](https://en.wikipedia.org/wiki/Blocking_(computing)). Specifically, output instructions do not wait for the sent packet to be received - the computer might send multiple packets before receiving any. Similarly, input instructions do not wait for a packet to arrive - if no packet is waiting, input instructions should receive `-1`. + +Boot up all `50` computers and attach them to your network. *What is the `Y` value of the first packet sent to address `255`?* + + +## --- Part Two --- +Packets sent to address `255` are handled by a device called a NAT (Not Always Transmitting). The NAT is responsible for managing power consumption of the network by blocking certain packets and watching for idle periods in the computers. + +If a packet would be sent to address `255`, the NAT receives it instead. The NAT remembers only the *last* packet it receives; that is, the data in each packet it receives overwrites the NAT's packet memory with the new packet's `X` and `Y` values. + +The NAT also monitors all computers on the network. If all computers have *empty incoming packet queues* and are *continuously trying to receive packets* without sending packets, the network is considered *idle*. + +Once the network is idle, the NAT sends *only the last packet it received* to address `0`; this will cause the computers on the network to resume activity. In this way, the NAT can throttle power consumption of the network when the ship needs power in other areas. + +Monitor packets released to the computer at address `0` by the NAT. *What is the first `Y` value delivered by the NAT to the computer at address `0` twice in a row?* + + diff --git a/2019/Day23/input.in b/2019/Day23/input.in index 088494653..4c1bd5493 100644 Binary files a/2019/Day23/input.in and b/2019/Day23/input.in differ diff --git a/2019/Day24/README.md b/2019/Day24/README.md index 0571ab9cb..198fd9e40 100644 --- a/2019/Day24/README.md +++ b/2019/Day24/README.md @@ -1,6 +1,243 @@ +original source: [https://adventofcode.com/2019/day/24](https://adventofcode.com/2019/day/24) ## --- Day 24: Planet of Discord --- You land on [Eris](https://en.wikipedia.org/wiki/Eris_(dwarf_planet)), your last stop before reaching Santa. As soon as you do, your sensors start picking up strange life forms moving around: Eris is infested with [bugs](https://www.nationalgeographic.org/thisday/sep9/worlds-first-computer-bug/)! With an over 24-hour roundtrip for messages between you and Earth, you'll have to deal with this problem on your own. Eris isn't a very large place; a scan of the entire area fits into a 5x5 grid (your puzzle input). The scan shows *bugs* (`#`) and *empty spaces* (`.`). -Read the [full puzzle](https://adventofcode.com/2019/day/24). \ No newline at end of file +Each *minute*, The bugs live and die based on the number of bugs in the *four adjacent tiles*: + + + - A bug *dies* (becoming an empty space) unless there is *exactly one* bug adjacent to it. + - An empty space *becomes infested* with a bug if *exactly one or two* bugs are adjacent to it. + +Otherwise, a bug or empty space remains the same. (Tiles on the edges of the grid have fewer than four adjacent tiles; the missing tiles count as empty space.) This process happens in every location *simultaneously*; that is, within the same minute, the number of adjacent bugs is counted for every tile first, and then the tiles are updated. + +Here are the first few minutes of an example scenario: + +``` +Initial state: +....# +#..#. +#..## +..#.. +#.... + +After 1 minute: +#..#. +####. +###.# +##.## +.##.. + +After 2 minutes: +##### +....# +....# +...#. +#.### + +After 3 minutes: +#.... +####. +...## +#.##. +.##.# + +After 4 minutes: +####. +....# +##..# +..... +##... +``` + +To understand the nature of the bugs, watch for the first time a layout of bugs and empty spaces *matches any previous layout*. In the example above, the first layout to appear twice is: + +``` +..... +..... +..... +#.... +.#... +``` + +To calculate the *biodiversity rating* for this layout, consider each tile left-to-right in the top row, then left-to-right in the second row, and so on. Each of these tiles is worth biodiversity points equal to *increasing powers of two*: 1, 2, 4, 8, 16, 32, and so on. Add up the biodiversity points for tiles with bugs; in this example, the 16th tile (`32768` points) and 22nd tile (`2097152` points) have bugs, a total biodiversity rating of `*2129920*`. + +*What is the biodiversity rating for the first layout that appears twice?* + + +## --- Part Two --- +After careful analysis, one thing is certain: *you have no idea where all these bugs are coming from*. + +Then, you remember: Eris is an old [Plutonian](20) settlement! Clearly, the bugs are coming from recursively-folded space. + +This 5x5 grid is *only one* level in an *infinite* number of recursion levels. The tile in the middle of the grid is actually another 5x5 grid, the grid in your scan is contained as the middle tile of a larger 5x5 grid, and so on. Two levels of grids look like this: + +``` + | | | | + | | | | + | | | | +-----+-----+---------+-----+----- + | | | | + | | | | + | | | | +-----+-----+---------+-----+----- + | | | | | | | | + | |-+-+-+-+-| | + | | | | | | | | + | |-+-+-+-+-| | + | | | |?| | | | + | |-+-+-+-+-| | + | | | | | | | | + | |-+-+-+-+-| | + | | | | | | | | +-----+-----+---------+-----+----- + | | | | + | | | | + | | | | +-----+-----+---------+-----+----- + | | | | + | | | | + | | | | +``` + +(To save space, some of the tiles are not drawn to scale.) Remember, this is only a small part of the infinitely recursive grid; there is a 5x5 grid that contains this diagram, and a 5x5 grid that contains that one, and so on. Also, the `?` in the diagram contains another 5x5 grid, which itself contains another 5x5 grid, and so on. + +The scan you took (your puzzle input) shows where the bugs are *on a single level* of this structure. The middle tile of your scan is empty to accommodate the recursive grids within it. Initially, no other levels contain bugs. + +Tiles still count as *adjacent* if they are directly *up, down, left, or right* of a given tile. Some tiles have adjacent tiles at a recursion level above or below its own level. For example: + +``` + | | | | + 1 | 2 | 3 | 4 | 5 + | | | | +-----+-----+---------+-----+----- + | | | | + 6 | 7 | 8 | 9 | 10 + | | | | +-----+-----+---------+-----+----- + | |A|B|C|D|E| | + | |-+-+-+-+-| | + | |F|G|H|I|J| | + | |-+-+-+-+-| | + 11 | 12 |K|L|?|N|O| 14 | 15 + | |-+-+-+-+-| | + | |P|Q|R|S|T| | + | |-+-+-+-+-| | + | |U|V|W|X|Y| | +-----+-----+---------+-----+----- + | | | | + 16 | 17 | 18 | 19 | 20 + | | | | +-----+-----+---------+-----+----- + | | | | + 21 | 22 | 23 | 24 | 25 + | | | | +``` + + + - Tile 19 has four adjacent tiles: 14, 18, 20, and 24. + - Tile G has four adjacent tiles: B, F, H, and L. + - Tile D has four adjacent tiles: 8, C, E, and I. + - Tile E has four adjacent tiles: 8, D, 14, and J. + - Tile 14 has *eight* adjacent tiles: 9, E, J, O, T, Y, 15, and 19. + - Tile N has *eight* adjacent tiles: I, O, S, and five tiles within the sub-grid marked `?`. + +The rules about bugs living and dying are the same as before. + +For example, consider the same initial state as above: + +``` +....# +#..#. +#.?## +..#.. +#.... +``` + +The center tile is drawn as `?` to indicate the next recursive grid. Call this level 0; the grid within this one is level 1, and the grid that contains this one is level -1. Then, after *ten* minutes, the grid at each level would look like this: + +``` +Depth -5: +..#.. +.#.#. +..?.# +.#.#. +..#.. + +Depth -4: +...#. +...## +..?.. +...## +...#. + +Depth -3: +#.#.. +.#... +..?.. +.#... +#.#.. + +Depth -2: +.#.## +....# +..?.# +...## +.###. + +Depth -1: +#..## +...## +..?.. +...#. +.#### + +Depth 0: +.#... +.#.## +.#?.. +..... +..... + +Depth 1: +.##.. +#..## +..?.# +##.## +##### + +Depth 2: +###.. +##.#. +#.?.. +.#.## +#.#.. + +Depth 3: +..### +..... +#.?.. +#.... +#...# + +Depth 4: +.###. +#..#. +#.?.. +##.#. +..... + +Depth 5: +####. +#..#. +#.?#. +####. +..... +``` + +In this example, after 10 minutes, a total of `*99*` bugs are present. + +Starting with your scan, *how many bugs are present after 200 minutes?* + + diff --git a/2019/Day24/input.in b/2019/Day24/input.in index ce82b25d5..2207476f0 100644 Binary files a/2019/Day24/input.in and b/2019/Day24/input.in differ diff --git a/2019/Day25/README.md b/2019/Day25/README.md index 09c087c2b..964e202b5 100644 --- a/2019/Day25/README.md +++ b/2019/Day25/README.md @@ -1,6 +1,39 @@ +original source: [https://adventofcode.com/2019/day/25](https://adventofcode.com/2019/day/25) ## --- Day 25: Cryostasis --- As you approach Santa's ship, your sensors report two important details: First, that you might be too late: the internal temperature is `-40` degrees. -Read the [full puzzle](https://adventofcode.com/2019/day/25). \ No newline at end of file +Second, that one faint life signature is somewhere on the ship. + +The airlock door is locked with a code; your best option is to send in a small droid to investigate the situation. You attach your ship to Santa's, break a small hole in the hull, and let the droid run in before you seal it up again. Before your ship starts freezing, you detach your ship and set it to automatically stay within range of Santa's ship. + +This droid can follow basic instructions and report on its surroundings; you can communicate with it through an [Intcode](9) program (your puzzle input) running on an [ASCII-capable](17) computer. + +As the droid moves through its environment, it will describe what it encounters. When it says `Command?`, you can give it a single instruction terminated with a newline (ASCII code `10`). Possible instructions are: + + + - *Movement* via `north`, `south`, `east`, or `west`. + - To *take* an item the droid sees in the environment, use the command `take `. For example, if the droid reports seeing a `red ball`, you can pick it up with `take red ball`. + - To *drop* an item the droid is carrying, use the command `drop `. For example, if the droid is carrying a `green ball`, you can drop it with `drop green ball`. + - To get a *list of all of the items* the droid is currently carrying, use the command `inv` (for "inventory"). + +Extra spaces or other characters aren't allowed - instructions must be provided precisely. + +Santa's ship is a *Reindeer-class starship*; these ships use pressure-sensitive floors to determine the identity of droids and crew members. The standard configuration for these starships is for all droids to weigh exactly the same amount to make them easier to detect. If you need to get past such a sensor, you might be able to reach the correct weight by carrying items from the environment. + +Look around the ship and see if you can find the *password for the main airlock*. + + +## --- Part Two --- +As you move through the main airlock, the air inside the ship is already heating up to reasonable levels. Santa explains that he didn't notice you coming because he was just taking a quick nap. The ship wasn't frozen; he just had the thermostat set to "North Pole". + +You make your way over to the navigation console. It beeps. "Status: Stranded. Please supply measurements from *49 stars* to recalibrate." + +"49 stars? But the Elves told me you needed fifty--" + +Santa just smiles and nods his head toward the window. There, in the distance, you can see the center of the Solar System: the Sun! + +The navigation console beeps again. + + diff --git a/2019/Day25/input.in b/2019/Day25/input.in index 379c826d2..6e431d6c9 100644 Binary files a/2019/Day25/input.in and b/2019/Day25/input.in differ diff --git a/2019/README.md b/2019/README.md index 27bdfaccb..4bd1241ac 100644 --- a/2019/README.md +++ b/2019/README.md @@ -1,4 +1,6 @@ + # Advent of Code (2019) Check out https://adventofcode.com/2019. + diff --git a/2019/SplashScreen.cs b/2019/SplashScreen.cs index 9025b076f..9e68101b8 100644 --- a/2019/SplashScreen.cs +++ b/2019/SplashScreen.cs @@ -1,3 +1,4 @@ + using System; namespace AdventOfCode.Y2019; @@ -8,178 +9,185 @@ public void Show() { var color = Console.ForegroundColor; Write(0xcc00, false, " ▄█▄ ▄▄█ ▄ ▄ ▄▄▄ ▄▄ ▄█▄ ▄▄▄ ▄█ ▄▄ ▄▄▄ ▄▄█ ▄▄▄\n █▄█ █ █ █ █ █▄█ █ █ █ █ █ █▄ "); - Write(0xcc00, false, " █ █ █ █ █ █▄█\n █ █ █▄█ ▀▄▀ █▄▄ █ █ █▄ █▄█ █ █▄ █▄█ █▄█ █▄▄ sub y{2019}\n \n"); - Write(0xcc00, false, " "); - Write(0x666666, false, " ''.. ':. '. "); - Write(0xcccccc, false, "25 "); - Write(0xffff66, false, "**\n "); - Write(0x666666, false, "....... "); - Write(0x333333, false, "."); - Write(0x666666, false, " ''. '. "); - Write(0xbebcbc, true, ". "); - Write(0xcccccc, false, "24 "); - Write(0xffff66, false, "**\n "); - Write(0x333333, false, "."); - Write(0x666666, false, " '''''... ''. '. "); - Write(0x333333, false, "."); - Write(0x666666, false, " ' "); - Write(0xcccccc, false, "23 "); - Write(0xffff66, false, "**\n "); - Write(0x666666, false, " ''.. '. '. "); - Write(0xffffff, true, ". "); - Write(0xcccccc, false, "22 "); - Write(0xffff66, false, "**\n "); - Write(0x666666, false, "...... "); - Write(0x333333, false, "."); - Write(0x666666, false, " ''."); - Write(0x333333, false, ". ."); - Write(0x666666, false, " '. "); - Write(0x333333, false, "."); - Write(0x666666, false, " '. "); - Write(0xcccccc, false, "21 "); - Write(0xffff66, false, "**\n "); - Write(0x666666, false, " ''''... "); - Write(0x333333, false, "."); - Write(0x666666, false, "'. "); - Write(0x333333, false, "."); - Write(0x666666, false, " '. : "); - Write(0xcdc1b2, true, ". "); - Write(0x333333, false, ". "); - Write(0xcccccc, false, "20 "); - Write(0xffff66, false, "**\n "); - Write(0x666666, false, " ''.. '. "); - Write(0x333333, false, "."); - Write(0x666666, false, " '."); - Write(0x333333, false, "."); - Write(0x666666, false, " '. "); - Write(0xcccccc, false, "19 "); - Write(0xffff66, false, "**\n "); - Write(0x666666, false, "..... ''. '. '. '"); - Write(0x456efe, true, "o "); - Write(0x333333, false, ". "); - Write(0xcccccc, false, "18 "); - Write(0xffff66, false, "**\n "); - Write(0x666666, false, " ''''... '. '. ': '."); - Write(0x333333, false, ". "); - Write(0xcccccc, false, "17 "); - Write(0xffff66, false, "**\n "); - Write(0x333333, false, "."); - Write(0x666666, false, " '.. '. '. "); - Write(0xbee4e7, true, "o"); - Write(0x333333, false, "."); - Write(0x666666, false, " : "); - Write(0xcccccc, false, "16 "); - Write(0xffff66, false, "**\n "); - Write(0x333333, false, ". ."); - Write(0x666666, false, " '. '. "); - Write(0x333333, false, "."); - Write(0x666666, false, " '. "); - Write(0x333333, false, "."); - Write(0x666666, false, " : : "); - Write(0xcccccc, false, "15 "); - Write(0xffff66, false, "**\n "); - Write(0x666666, false, "'''''... '. "); - Write(0x333333, false, ". ."); - Write(0x666666, false, " '. "); - Write(0xebc982, true, "(O)"); - Write(0x666666, false, " : '. "); - Write(0xcccccc, false, "14 "); - Write(0xffff66, false, "**\n "); - Write(0x333333, false, "."); - Write(0x666666, false, " ''.. '. '. "); - Write(0x333333, false, ".."); - Write(0x666666, false, " '. '. : "); - Write(0xcccccc, false, "13 "); - Write(0xffff66, false, "**\n "); - Write(0x666666, false, "''''... '. '. '"); - Write(0xd2beab, true, "O"); - Write(0x666666, false, " '. : :"); - Write(0x333333, false, ". "); - Write(0xcccccc, false, "12 "); - Write(0xffff66, false, "**\n "); - Write(0x666666, false, " ''. '."); - Write(0x333333, false, ". ."); - Write(0x666666, false, " : '. : '. : "); - Write(0xcccccc, false, "11 "); - Write(0xffff66, false, "**\n "); - Write(0x666666, false, "'''''.. '. '. "); - Write(0x333333, false, ". . "); - Write(0xbabdb6, true, "."); - Write(0x666666, false, " : "); - Write(0x333333, false, "."); - Write(0x666666, false, " '. : '. "); - Write(0xcccccc, false, "10 "); - Write(0xffff66, false, "**\n "); - Write(0x666666, false, " '. '. '. '. "); - Write(0x333333, false, "."); - Write(0x666666, false, " : : : : "); - Write(0xcccccc, false, " 9 "); - Write(0xffff66, false, "**\n "); - Write(0x666666, false, " : '."); - Write(0x333333, false, ". "); - Write(0xf7a859, true, ". "); - Write(0x333333, false, "."); - Write(0x666666, false, " : :"); - Write(0x333333, false, "."); - Write(0x666666, false, " : : : "); - Write(0xcccccc, false, " 8 "); - Write(0xffff66, false, "**\n "); - Write(0x666666, false, "'''. "); - Write(0x333333, false, "."); - Write(0x666666, false, ":"); - Write(0x333333, false, "."); - Write(0x666666, false, " : :"); - Write(0x333333, false, "."); - Write(0x666666, false, " : : : : : "); - Write(0xcccccc, false, " 7 "); - Write(0xffff66, false, "**\n "); - Write(0xffff66, true, "* "); - Write(0xbebcbe, true, "."); - Write(0x666666, false, " : : : : : : "); - Write(0x333333, false, "."); - Write(0x666666, false, " : : "); - Write(0xcccccc, false, " 6 "); - Write(0xffff66, false, "**\n "); - Write(0x666666, false, "...' "); - Write(0x333333, false, "."); - Write(0x666666, false, ": : : : "); - Write(0x333333, false, "."); - Write(0x666666, false, ": : "); - Write(0x333333, false, "."); - Write(0x666666, false, ": : "); - Write(0xcccccc, false, " 5 "); - Write(0xffff66, false, "**\n "); - Write(0x333333, false, ". "); - Write(0xe3e2e0, true, "."); - Write(0x333333, false, "."); - Write(0x666666, false, " .' : : : : : : "); - Write(0xcccccc, false, " 4 "); - Write(0xffff66, false, "**\n "); - Write(0x666666, false, " .' .' .' "); - Write(0x333333, false, "."); - Write(0x666666, false, " .' : : : : "); - Write(0xcccccc, false, " 3 "); - Write(0xffff66, false, "**\n "); - Write(0x666666, false, ".....'' "); - Write(0x91a5bd, true, "."); - Write(0x666666, false, "' .' : : .' "); - Write(0x333333, false, "."); - Write(0x666666, false, " : .' "); - Write(0xcccccc, false, " 2 "); - Write(0xffff66, false, "**\n "); - Write(0x666666, false, " ..' .' : "); - Write(0x333333, false, "."); - Write(0x666666, false, " .' : .'"); - Write(0x333333, false, "."); - Write(0x666666, false, " : "); - Write(0xcccccc, false, " 1 "); - Write(0xffff66, false, "**\n \n"); - + Write(0xcc00, false, " █ █ █ █ █ █▄█\n █ █ █▄█ ▀▄▀ █▄▄ █ █ █▄ █▄█ █ █▄ █▄█ █▄█ █▄▄ $year = 2019\n "); + Write(0xcc00, false, "\n "); + Write(0x666666, false, " ''.. ':. '. "); + Write(0x333333, false, ". "); + Write(0xcccccc, false, "25 "); + Write(0xffff66, false, "**\n "); + Write(0x666666, false, "....... "); + Write(0x333333, false, ".."); + Write(0x666666, false, " ''. '. "); + Write(0x333333, false, ". "); + Write(0xbebcbc, true, ". "); + Write(0xcccccc, false, "24 "); + Write(0xffff66, false, "**\n "); + Write(0x666666, false, " '''''... "); + Write(0x333333, false, "."); + Write(0x666666, false, " ''. '. "); + Write(0x333333, false, "."); + Write(0x666666, false, " ' "); + Write(0xcccccc, false, "23 "); + Write(0xffff66, false, "**\n "); + Write(0x333333, false, "."); + Write(0x666666, false, " ''.. '. '. "); + Write(0xffffff, true, ". "); + Write(0xcccccc, false, "22 "); + Write(0xffff66, false, "**\n "); + Write(0x666666, false, "...... ''. '. "); + Write(0x333333, false, "."); + Write(0x666666, false, " '. "); + Write(0xcccccc, false, "21 "); + Write(0xffff66, false, "**\n "); + Write(0x333333, false, ".."); + Write(0x666666, false, " ''''... '. '."); + Write(0x333333, false, "."); + Write(0x666666, false, " : "); + Write(0xcdc1b2, true, ". "); + Write(0xcccccc, false, "20 "); + Write(0xffff66, false, "**\n "); + Write(0x666666, false, " ''.. "); + Write(0x333333, false, ". ."); + Write(0x666666, false, "'. "); + Write(0x333333, false, "."); + Write(0x666666, false, " '. "); + Write(0x333333, false, "."); + Write(0x666666, false, "'. "); + Write(0xcccccc, false, "19 "); + Write(0xffff66, false, "**\n "); + Write(0x666666, false, "..... ''. "); + Write(0x333333, false, "."); + Write(0x666666, false, " '. "); + Write(0x333333, false, "."); + Write(0x666666, false, "'. '"); + Write(0x456efe, true, "o "); + Write(0xcccccc, false, "18 "); + Write(0xffff66, false, "**\n "); + Write(0x333333, false, "."); + Write(0x666666, false, " ''''... '. '. ': '. "); + Write(0xcccccc, false, "17 "); + Write(0xffff66, false, "**\n "); + Write(0x333333, false, "."); + Write(0x666666, false, " '.. "); + Write(0x333333, false, "."); + Write(0x666666, false, " '. '. "); + Write(0xbee4e7, true, "o"); + Write(0x666666, false, " : "); + Write(0xcccccc, false, "16 "); + Write(0xffff66, false, "**\n "); + Write(0x666666, false, " '. '. '. : : "); + Write(0xcccccc, false, "15 "); + Write(0xffff66, false, "**\n "); + Write(0x666666, false, "'''''... '. "); + Write(0x333333, false, "."); + Write(0x666666, false, " '. "); + Write(0xebc982, true, "(O)"); + Write(0x666666, false, " : '. "); + Write(0xcccccc, false, "14 "); + Write(0xffff66, false, "**\n "); + Write(0x666666, false, " ''.. '. '. '. "); + Write(0x333333, false, "."); + Write(0x666666, false, " '. :"); + Write(0x333333, false, ". "); + Write(0xcccccc, false, "13 "); + Write(0xffff66, false, "**\n "); + Write(0x666666, false, "''''..."); + Write(0x333333, false, "."); + Write(0x666666, false, " '. "); + Write(0x333333, false, "."); + Write(0x666666, false, " '. '"); + Write(0xd2beab, true, "O"); + Write(0x666666, false, " '. : : "); + Write(0xcccccc, false, "12 "); + Write(0xffff66, false, "**\n "); + Write(0x666666, false, " ''. '. : '. : '. : "); + Write(0xcccccc, false, "11 "); + Write(0xffff66, false, "**\n "); + Write(0x666666, false, "'''''.. '. '. "); + Write(0x333333, false, ". "); + Write(0xbabdb6, true, "."); + Write(0x333333, false, ". ."); + Write(0x666666, false, " : '. : '. "); + Write(0xcccccc, false, "10 "); + Write(0xffff66, false, "**\n "); + Write(0x333333, false, ".."); + Write(0x666666, false, " '. '. '. '. : : : : "); + Write(0xcccccc, false, " 9 "); + Write(0xffff66, false, "**\n "); + Write(0x333333, false, ". ."); + Write(0x666666, false, " : '. "); + Write(0x333333, false, ". "); + Write(0xf7a859, true, ". "); + Write(0x333333, false, "."); + Write(0x666666, false, " : : "); + Write(0x333333, false, "."); + Write(0x666666, false, " : "); + Write(0x333333, false, "."); + Write(0x666666, false, " : : "); + Write(0xcccccc, false, " 8 "); + Write(0xffff66, false, "**\n "); + Write(0x666666, false, "'''. "); + Write(0x333333, false, ".."); + Write(0x666666, false, " : : : : : : "); + Write(0x333333, false, ". ."); + Write(0x666666, false, ": : "); + Write(0xcccccc, false, " 7 "); + Write(0xffff66, false, "**\n "); + Write(0xffff66, true, "* "); + Write(0xbebcbe, true, ". "); + Write(0x333333, false, "."); + Write(0x666666, false, ": : : "); + Write(0x333333, false, "."); + Write(0x666666, false, ": : : "); + Write(0x333333, false, "."); + Write(0x666666, false, ": : "); + Write(0xcccccc, false, " 6 "); + Write(0xffff66, false, "**\n "); + Write(0x666666, false, "...' : : : : : "); + Write(0x333333, false, "."); + Write(0x666666, false, " : : "); + Write(0x333333, false, "."); + Write(0x666666, false, " : "); + Write(0xcccccc, false, " 5 "); + Write(0xffff66, false, "**\n "); + Write(0xe3e2e0, true, "."); + Write(0x666666, false, " .' : "); + Write(0x333333, false, "."); + Write(0x666666, false, " : : "); + Write(0x333333, false, "."); + Write(0x666666, false, " : : : "); + Write(0xcccccc, false, " 4 "); + Write(0xffff66, false, "**\n "); + Write(0x666666, false, " .' .' "); + Write(0x333333, false, "."); + Write(0x666666, false, ".' .' : : : : "); + Write(0xcccccc, false, " 3 "); + Write(0xffff66, false, "**\n "); + Write(0x666666, false, ".....'' "); + Write(0x333333, false, "."); + Write(0x91a5bd, true, "."); + Write(0x666666, false, "' "); + Write(0x333333, false, "."); + Write(0x666666, false, " .' : :"); + Write(0x333333, false, "."); + Write(0x666666, false, " .' : "); + Write(0x333333, false, "."); + Write(0x666666, false, " .' "); + Write(0xcccccc, false, " 2 "); + Write(0xffff66, false, "**\n "); + Write(0x666666, false, " ..' .' :"); + Write(0x333333, false, "."); + Write(0x666666, false, " .' "); + Write(0x333333, false, "."); + Write(0x666666, false, " : .' : "); + Write(0xcccccc, false, " 1 "); + Write(0xffff66, false, "**\n \n"); + Console.ForegroundColor = color; Console.WriteLine(); } - private static void Write(int rgb, bool bold, string text){ + private static void Write(int rgb, bool bold, string text){ Console.Write($"\u001b[38;2;{(rgb>>16)&255};{(rgb>>8)&255};{rgb&255}{(bold ? ";1" : "")}m{text}"); - } -} \ No newline at end of file + } +} diff --git a/2019/calendar.svg b/2019/calendar.svg index 171bad8d6..80ce35dab 100644 --- a/2019/calendar.svg +++ b/2019/calendar.svg @@ -1,46 +1,46 @@ - - - + + + ▄█▄ ▄▄█ ▄ ▄ ▄▄▄ ▄▄ ▄█▄  ▄▄▄ ▄█  ▄▄ ▄▄▄ ▄▄█ ▄▄▄ █▄█ █ █ █ █ █▄█ █ █ █   █ █ █▄  █  █ █ █ █ █▄█ -█ █ █▄█ ▀▄▀ █▄▄ █ █ █▄  █▄█ █   █▄ █▄█ █▄█ █▄▄  sub y{2019} +█ █ █▄█ ▀▄▀ █▄▄ █ █ █▄  █▄█ █   █▄ █▄█ █▄█ █▄▄  $year = 2019   -                   ''..     ':.              '.    25 ** -.......    .           ''.     '.              .   24 ** -.      '''''...           ''.    '.  .          '  23 ** -               ''..          '.    '. .            22 ** -......      .      ''.. .      '. .  '.            21 ** -      ''''...        .'.       . '.    : .  .      20 ** -             ''..       '.    .    '..  '.         19 ** -.....            ''.      '.        '.   'o    .   18 ** -     ''''...        '.      '.       ':   '..      17 ** - .          '..       '.      '.       o.   :      16 ** -        .   .  '.       '.   . '.   .   :    :     15 ** -'''''...         '.  . . '.     (O)      :   '.    14 ** -    .   ''..       '.     '.  .. '.      '.   :    13 ** -''''...     '.      '.     'O     '.      :    :.  12 ** -       ''.    '.. .   :     '.     :      '.   :   11 ** -'''''..   '.   '. .  . .     :  .  '.      :   '.  10 ** -       '.  '.   '.     '.  .  :     :      :    :   9 ** -         :  '..  . .    :     :.    :       :   :   8 ** -'''.     .:. :   :.     :     :     :       :   :   7 ** - * .      :  :   :      :     :     :   .   :   :   6 ** -...'     .:  :   :      :    .:     :      .:   :   5 ** -       . .. .'   :      :     :     :       :   :   4 ** -       .'  .'   .'  .  .'     :     :      :    :   3 ** -.....''   .'   .'      :     :     .' .    :   .'   2 ** -       ..'    .'      :  .  .'     :      .'.  :    1 ** +                   ''..     ':.              '. .  25 ** +.......  ..            ''.     '.      .       .   24 ** +       '''''...    .      ''.    '.      .      '  23 ** +  .            ''..          '.    '. .            22 ** +......             ''.         '.  . '.            21 ** + ..   ''''...         '.         '..   : .         20 ** +             ''..  .   .'.       . '.  .'.         19 ** +.....            ''.    . '.       .'.   'o        18 ** +.    ''''...        '.      '.       ':   '.       17 ** + .          '..     . '.      '.       o    :      16 ** +               '.       '.     '.       :    :     15 ** +'''''...         '.    . '.     (O)      :   '.    14 ** +        ''..       '.     '.     '.  .   '.   :.   13 ** +''''....    '.    . '.     'O     '.      :    :   12 ** +       ''.    '.      :     '.     :      '.   :   11 ** +'''''..   '.   '.   .  .. .  :     '.      :   '.  10 ** +    .. '.  '.   '.     '.     :     :      :    :   9 ** +. .      :  '. . .   .  :     :  .  :     . :   :   8 ** +'''.  ..  :  :   :      :     :     : .    .:   :   7 ** + * .     .:  :   :     .:     :     :      .:   :   6 ** +...'      :  :   :      :     :   . :       : . :   5 ** +         .  .'   :  .   :     :  .  :       :   :   4 ** +       .'  .'  ..'     .'     :     :      :    :   3 ** +.....''  ... .'      :     :.    .'      : . .'   2 ** +       ..'    .'      :.    .' .   :      .'   :    1 ** - \ No newline at end of file + \ No newline at end of file diff --git a/2020/Day01/README.md b/2020/Day01/README.md index afa2c5f0e..25dac7d0d 100644 --- a/2020/Day01/README.md +++ b/2020/Day01/README.md @@ -1,6 +1,39 @@ +original source: [https://adventofcode.com/2020/day/1](https://adventofcode.com/2020/day/1) ## --- Day 1: Report Repair --- After saving Christmas [five years in a row](/events), you've decided to take a vacation at a nice resort on a tropical island. Surely, Christmas will go on without you. The tropical island has its own currency and is entirely cash-only. The gold coins used there have a little picture of a starfish; the locals just call them stars. None of the currency exchanges seem to have heard of them, but somehow, you'll need to find fifty of these coins by the time you arrive so you can pay the deposit on your room. -_Visit the website for the full story and [full puzzle](https://adventofcode.com/2020/day/1) description._ +To save your vacation, you need to get all fifty stars by December 25th. + +Collect stars by solving puzzles. Two puzzles will be made available on each day in the Advent calendar; the second puzzle is unlocked when you complete the first. Each puzzle grants one star. Good luck! + +Before you leave, the Elves in accounting just need you to fix your expense report (your puzzle input); apparently, something isn't quite adding up. + +Specifically, they need you to find the two entries that sum to 2020 and then multiply those two numbers together. + +For example, suppose your expense report contained the following: + +
+1721
+979
+366
+299
+675
+1456
+
+
+ +In this list, the two entries that sum to 2020 are 1721 and 299. Multiplying them together produces 1721 * 299 = 514579, so the correct answer is 514579. + +Of course, your expense report is much larger. Find the two entries that sum to 2020; what do you get if you multiply them together? + + +## --- Part Two --- +The Elves in accounting are thankful for your help; one of them even offers you a starfish coin they had left over from a past vacation. They offer you a second one if you can find three numbers in your expense report that meet the same criteria. + +Using the above example again, the three entries that sum to 2020 are 979, 366, and 675. Multiplying them together produces the answer, 241861950. + +In your expense report, what is the product of the three entries that sum to 2020? + + diff --git a/2020/Day01/input.in b/2020/Day01/input.in index 498aa0d3f..7b7f47a2f 100644 Binary files a/2020/Day01/input.in and b/2020/Day01/input.in differ diff --git a/2020/Day02/README.md b/2020/Day02/README.md index 0b731664f..fa0649861 100644 --- a/2020/Day02/README.md +++ b/2020/Day02/README.md @@ -1,6 +1,43 @@ +original source: [https://adventofcode.com/2020/day/2](https://adventofcode.com/2020/day/2) ## --- Day 2: Password Philosophy --- Your flight departs in a few days from the coastal airport; the easiest way down to the coast from here is via [toboggan](https://en.wikipedia.org/wiki/Toboggan). The shopkeeper at the North Pole Toboggan Rental Shop is having a bad day. "Something's wrong with our computers; we can't log in!" You ask if you can take a look. -Read the [full puzzle](https://adventofcode.com/2020/day/2). \ No newline at end of file +Their password database seems to be a little corrupted: some of the passwords wouldn't have been allowed by the Official Toboggan Corporate Policy that was in effect when they were chosen. + +To try to debug the problem, they have created a list (your puzzle input) of passwords (according to the corrupted database) and the corporate policy when that password was set. + +For example, suppose you have the following list: + +
+1-3 a: abcde
+1-3 b: cdefg
+2-9 c: ccccccccc
+
+
+ +Each line gives the password policy and then the password. The password policy indicates the lowest and highest number of times a given letter must appear for the password to be valid. For example, 1-3 a means that the password must contain a at least 1 time and at most 3 times. + +In the above example, 2 passwords are valid. The middle password, cdefg, is not; it contains no instances of b, but needs at least 1. The first and third passwords are valid: they contain one a or nine c, both within the limits of their respective policies. + +How many passwords are valid according to their policies? + + +## --- Part Two --- +While it appears you validated the passwords correctly, they don't seem to be what the Official Toboggan Corporate Authentication System is expecting. + +The shopkeeper suddenly realizes that he just accidentally explained the password policy rules from his old job at the sled rental place down the street! The Official Toboggan Corporate Policy actually works a little differently. + +Each policy actually describes two positions in the password, where 1 means the first character, 2 means the second character, and so on. (Be careful; Toboggan Corporate Policies have no concept of "index zero"!) Exactly one of these positions must contain the given letter. Other occurrences of the letter are irrelevant for the purposes of policy enforcement. + +Given the same example list from above: + + + - 1-3 a: abcde is valid: position 1 contains a and position 3 does not. + - 1-3 b: cdefg is invalid: neither position 1 nor position 3 contains b. + - 2-9 c: ccccccccc is invalid: both position 2 and position 9 contain c. + +How many passwords are valid according to the new interpretation of the policies? + + diff --git a/2020/Day02/input.in b/2020/Day02/input.in index b43c90dc0..bb32789e6 100644 Binary files a/2020/Day02/input.in and b/2020/Day02/input.in differ diff --git a/2020/Day03/README.md b/2020/Day03/README.md index 79e2a72a7..ffe9f4dbc 100644 --- a/2020/Day03/README.md +++ b/2020/Day03/README.md @@ -1,6 +1,83 @@ +original source: [https://adventofcode.com/2020/day/3](https://adventofcode.com/2020/day/3) ## --- Day 3: Toboggan Trajectory --- With the toboggan login problems resolved, you set off toward the airport. While travel by toboggan might be easy, it's certainly not safe: there's very minimal steering and the area is covered in trees. You'll need to see which angles will take you near the fewest trees. Due to the local geology, trees in this area only grow on exact integer coordinates in a grid. You make a map (your puzzle input) of the open squares (.) and trees (#) you can see. For example: -Read the [full puzzle](https://adventofcode.com/2020/day/3). \ No newline at end of file +
+..##.......
+#...#...#..
+.#....#..#.
+..#.#...#.#
+.#...##..#.
+..#.##.....
+.#.#.#....#
+.#........#
+#.##...#...
+#...##....#
+.#..#...#.#
+
+
+ +These aren't the only trees, though; due to something you read about once involving arboreal genetics and biome stability, the same pattern repeats to the right many times: + +
+..##.........##.........##.........##.........##.........##.......  --->
+#...#...#..#...#...#..#...#...#..#...#...#..#...#...#..#...#...#..
+.#....#..#..#....#..#..#....#..#..#....#..#..#....#..#..#....#..#.
+..#.#...#.#..#.#...#.#..#.#...#.#..#.#...#.#..#.#...#.#..#.#...#.#
+.#...##..#..#...##..#..#...##..#..#...##..#..#...##..#..#...##..#.
+..#.##.......#.##.......#.##.......#.##.......#.##.......#.##.....  --->
+.#.#.#....#.#.#.#....#.#.#.#....#.#.#.#....#.#.#.#....#.#.#.#....#
+.#........#.#........#.#........#.#........#.#........#.#........#
+#.##...#...#.##...#...#.##...#...#.##...#...#.##...#...#.##...#...
+#...##....##...##....##...##....##...##....##...##....##...##....#
+.#..#...#.#.#..#...#.#.#..#...#.#.#..#...#.#.#..#...#.#.#..#...#.#  --->
+
+
+ +You start on the open square (.) in the top-left corner and need to reach the bottom (below the bottom-most row on your map). + +The toboggan can only follow a few specific slopes (you opted for a cheaper model that prefers rational numbers); start by counting all the trees you would encounter for the slope right 3, down 1: + +From your starting position at the top-left, check the position that is right 3 and down 1. Then, check the position that is right 3 and down 1 from there, and so on until you go past the bottom of the map. + +The locations you'd check in the above example are marked here with O where there was an open square and X where there was a tree: + +
+..##.........##.........##.........##.........##.........##.......  --->
+#..O#...#..#...#...#..#...#...#..#...#...#..#...#...#..#...#...#..
+.#....X..#..#....#..#..#....#..#..#....#..#..#....#..#..#....#..#.
+..#.#...#O#..#.#...#.#..#.#...#.#..#.#...#.#..#.#...#.#..#.#...#.#
+.#...##..#..X...##..#..#...##..#..#...##..#..#...##..#..#...##..#.
+..#.##.......#.X#.......#.##.......#.##.......#.##.......#.##.....  --->
+.#.#.#....#.#.#.#.O..#.#.#.#....#.#.#.#....#.#.#.#....#.#.#.#....#
+.#........#.#........X.#........#.#........#.#........#.#........#
+#.##...#...#.##...#...#.X#...#...#.##...#...#.##...#...#.##...#...
+#...##....##...##....##...#X....##...##....##...##....##...##....#
+.#..#...#.#.#..#...#.#.#..#...X.#.#..#...#.#.#..#...#.#.#..#...#.#  --->
+
+
+ +In this example, traversing the map using this slope would cause you to encounter 7 trees. + +Starting at the top-left corner of your map and following a slope of right 3 and down 1, how many trees would you encounter? + + +## --- Part Two --- +Time to check the rest of the slopes - you need to minimize the probability of a sudden arboreal stop, after all. + +Determine the number of trees you would encounter if, for each of the following slopes, you start at the top-left corner and traverse the map all the way to the bottom: + + + - Right 1, down 1. + - Right 3, down 1. (This is the slope you already checked.) + - Right 5, down 1. + - Right 7, down 1. + - Right 1, down 2. + +In the above example, these slopes would find 2, 7, 3, 4, and 2 tree(s) respectively; multiplied together, these produce the answer 336. + +What do you get if you multiply together the number of trees encountered on each of the listed slopes? + + diff --git a/2020/Day03/input.in b/2020/Day03/input.in index 4eb1a39f2..6727b2a4d 100644 Binary files a/2020/Day03/input.in and b/2020/Day03/input.in differ diff --git a/2020/Day04/README.md b/2020/Day04/README.md index cd23630f4..4ebaeb54d 100644 --- a/2020/Day04/README.md +++ b/2020/Day04/README.md @@ -1,6 +1,135 @@ +original source: [https://adventofcode.com/2020/day/4](https://adventofcode.com/2020/day/4) ## --- Day 4: Passport Processing --- You arrive at the airport only to realize that you grabbed your North Pole Credentials instead of your passport. While these documents are extremely similar, North Pole Credentials aren't issued by a country and therefore aren't actually valid documentation for travel in most of the world. It seems like you're not the only one having problems, though; a very long line has formed for the automatic passport scanners, and the delay could upset your travel itinerary. -Read the [full puzzle](https://adventofcode.com/2020/day/4). \ No newline at end of file +Due to some questionable network security, you realize you might be able to solve both of these problems at the same time. + +The automatic passport scanners are slow because they're having trouble detecting which passports have all required fields. The expected fields are as follows: + + + - byr (Birth Year) + - iyr (Issue Year) + - eyr (Expiration Year) + - hgt (Height) + - hcl (Hair Color) + - ecl (Eye Color) + - pid (Passport ID) + - cid (Country ID) + +Passport data is validated in batch files (your puzzle input). Each passport is represented as a sequence of key:value pairs separated by spaces or newlines. Passports are separated by blank lines. + +Here is an example batch file containing four passports: + +
+ecl:gry pid:860033327 eyr:2020 hcl:#fffffd
+byr:1937 iyr:2017 cid:147 hgt:183cm
+
+iyr:2013 ecl:amb cid:350 eyr:2023 pid:028048884
+hcl:#cfa07d byr:1929
+
+hcl:#ae17e1 iyr:2013
+eyr:2024
+ecl:brn pid:760753108 byr:1931
+hgt:179cm
+
+hcl:#cfa07d eyr:2025 pid:166559648
+iyr:2011 ecl:brn hgt:59in
+
+
+ +The first passport is valid - all eight fields are present. The second passport is invalid - it is missing hgt (the Height field). + +The third passport is interesting; the only missing field is cid, so it looks like data from North Pole Credentials, not a passport at all! Surely, nobody would mind if you made the system temporarily ignore missing cid fields. Treat this "passport" as valid. + +The fourth passport is missing two fields, cid and byr. Missing cid is fine, but missing any other field is not, so this passport is invalid. + +According to the above rules, your improved system would report 2 valid passports. + +Count the number of valid passports - those that have all required fields. Treat cid as optional. In your batch file, how many passports are valid? + + +## --- Part Two --- +The line is moving more quickly now, but you overhear airport security talking about how passports with invalid data are getting through. Better add some data validation, quick! + +You can continue to ignore the cid field, but each other field has strict rules about what values are valid for automatic validation: + + + - byr (Birth Year) - four digits; at least 1920 and at most 2002. + - iyr (Issue Year) - four digits; at least 2010 and at most 2020. + - eyr (Expiration Year) - four digits; at least 2020 and at most 2030. + - hgt (Height) - a number followed by either cm or in: + + - If cm, the number must be at least 150 and at most 193. + - If in, the number must be at least 59 and at most 76. + + + - hcl (Hair Color) - a # followed by exactly six characters 0-9 or a-f. + - ecl (Eye Color) - exactly one of: amb blu brn gry grn hzl oth. + - pid (Passport ID) - a nine-digit number, including leading zeroes. + - cid (Country ID) - ignored, missing or not. + +Your job is to count the passports where all required fields are both present and valid according to the above rules. Here are some example values: + +
+byr valid:   2002
+byr invalid: 2003
+
+hgt valid:   60in
+hgt valid:   190cm
+hgt invalid: 190in
+hgt invalid: 190
+
+hcl valid:   #123abc
+hcl invalid: #123abz
+hcl invalid: 123abc
+
+ecl valid:   brn
+ecl invalid: wat
+
+pid valid:   000000001
+pid invalid: 0123456789
+
+
+ +Here are some invalid passports: + +
+eyr:1972 cid:100
+hcl:#18171d ecl:amb hgt:170 pid:186cm iyr:2018 byr:1926
+
+iyr:2019
+hcl:#602927 eyr:1967 hgt:170cm
+ecl:grn pid:012533040 byr:1946
+
+hcl:dab227 iyr:2012
+ecl:brn hgt:182cm pid:021572410 eyr:2020 byr:1992 cid:277
+
+hgt:59cm ecl:zzz
+eyr:2038 hcl:74454a iyr:2023
+pid:3556412378 byr:2007
+
+
+ +Here are some valid passports: + +
+pid:087499704 hgt:74in ecl:grn iyr:2012 eyr:2030 byr:1980
+hcl:#623a2f
+
+eyr:2029 ecl:blu cid:129 byr:1989
+iyr:2014 pid:896056539 hcl:#a97842 hgt:165cm
+
+hcl:#888785
+hgt:164cm byr:2001 iyr:2015 cid:88
+pid:545766238 ecl:hzl
+eyr:2022
+
+iyr:2010 hgt:158cm hcl:#b6652a ecl:blu byr:1944 eyr:2021 pid:093154719
+
+
+ +Count the number of valid passports - those that have all required fields and valid values. Continue to treat cid as optional. In your batch file, how many passports are valid? + + diff --git a/2020/Day04/input.in b/2020/Day04/input.in index f84e2c10e..fa39bc7b7 100644 Binary files a/2020/Day04/input.in and b/2020/Day04/input.in differ diff --git a/2020/Day05/README.md b/2020/Day05/README.md index 79b2dec02..398d967dd 100644 --- a/2020/Day05/README.md +++ b/2020/Day05/README.md @@ -1,6 +1,56 @@ +original source: [https://adventofcode.com/2020/day/5](https://adventofcode.com/2020/day/5) ## --- Day 5: Binary Boarding --- You board your plane only to discover a new problem: you dropped your boarding pass! You aren't sure which seat is yours, and all of the flight attendants are busy with the flood of people that suddenly made it through passport control. You write a quick program to use your phone's camera to scan all of the nearby boarding passes (your puzzle input); perhaps you can find your seat through process of elimination. -Read the [full puzzle](https://adventofcode.com/2020/day/5). \ No newline at end of file +Instead of [zones or groups](https://www.youtube.com/watch?v=oAHbLRjF0vo), this airline uses binary space partitioning to seat people. A seat might be specified like FBFBBFFRLR, where F means "front", B means "back", L means "left", and R means "right". + +The first 7 characters will either be F or B; these specify exactly one of the 128 rows on the plane (numbered 0 through 127). Each letter tells you which half of a region the given seat is in. Start with the whole list of rows; the first letter indicates whether the seat is in the front (0 through 63) or the back (64 through 127). The next letter indicates which half of that region the seat is in, and so on until you're left with exactly one row. + +For example, consider just the first seven characters of FBFBBFFRLR: + + + - Start by considering the whole range, rows 0 through 127. + - F means to take the lower half, keeping rows 0 through 63. + - B means to take the upper half, keeping rows 32 through 63. + - F means to take the lower half, keeping rows 32 through 47. + - B means to take the upper half, keeping rows 40 through 47. + - B keeps rows 44 through 47. + - F keeps rows 44 through 45. + - The final F keeps the lower of the two, row 44. + +The last three characters will be either L or R; these specify exactly one of the 8 columns of seats on the plane (numbered 0 through 7). The same process as above proceeds again, this time with only three steps. L means to keep the lower half, while R means to keep the upper half. + +For example, consider just the last 3 characters of FBFBBFFRLR: + + + - Start by considering the whole range, columns 0 through 7. + - R means to take the upper half, keeping columns 4 through 7. + - L means to take the lower half, keeping columns 4 through 5. + - The final R keeps the upper of the two, column 5. + +So, decoding FBFBBFFRLR reveals that it is the seat at row 44, column 5. + +Every seat also has a unique seat ID: multiply the row by 8, then add the column. In this example, the seat has ID 44 * 8 + 5 = 357. + +Here are some other boarding passes: + + + - BFFFBBFRRR: row 70, column 7, seat ID 567. + - FFFBBBFRRR: row 14, column 7, seat ID 119. + - BBFFBBFRLL: row 102, column 4, seat ID 820. + +As a sanity check, look through your list of boarding passes. What is the highest seat ID on a boarding pass? + + +## --- Part Two --- +Ding! The "fasten seat belt" signs have turned on. Time to find your seat. + +It's a completely full flight, so your seat should be the only missing boarding pass in your list. However, there's a catch: some of the seats at the very front and back of the plane don't exist on this aircraft, so they'll be missing from your list as well. + +Your seat wasn't at the very front or back, though; the seats with IDs +1 and -1 from yours will be in your list. + +What is the ID of your seat? + + diff --git a/2020/Day05/input.in b/2020/Day05/input.in index addba3135..17dfa0b17 100644 Binary files a/2020/Day05/input.in and b/2020/Day05/input.in differ diff --git a/2020/Day06/README.md b/2020/Day06/README.md index f1f605931..e2e62ead5 100644 --- a/2020/Day06/README.md +++ b/2020/Day06/README.md @@ -1,6 +1,92 @@ +original source: [https://adventofcode.com/2020/day/6](https://adventofcode.com/2020/day/6) ## --- Day 6: Custom Customs --- As your flight approaches the regional airport where you'll switch to a much larger plane, [customs declaration forms](https://en.wikipedia.org/wiki/Customs_declaration) are distributed to the passengers. The form asks a series of 26 yes-or-no questions marked a through z. All you need to do is identify the questions for which anyone in your group answers "yes". Since your group is just you, this doesn't take very long. -Read the [full puzzle](https://adventofcode.com/2020/day/6). \ No newline at end of file +However, the person sitting next to you seems to be experiencing a language barrier and asks if you can help. For each of the people in their group, you write down the questions for which they answer "yes", one per line. For example: + +
+abcx
+abcy
+abcz
+
+
+ +In this group, there are 6 questions to which anyone answered "yes": a, b, c, x, y, and z. (Duplicate answers to the same question don't count extra; each question counts at most once.) + +Another group asks for your help, then another, and eventually you've collected answers from every group on the plane (your puzzle input). Each group's answers are separated by a blank line, and within each group, each person's answers are on a single line. For example: + +
+abc
+
+a
+b
+c
+
+ab
+ac
+
+a
+a
+a
+a
+
+b
+
+
+ +This list represents answers from five groups: + + + - The first group contains one person who answered "yes" to 3 questions: a, b, and c. + - The second group contains three people; combined, they answered "yes" to 3 questions: a, b, and c. + - The third group contains two people; combined, they answered "yes" to 3 questions: a, b, and c. + - The fourth group contains four people; combined, they answered "yes" to only 1 question, a. + - The last group contains one person who answered "yes" to only 1 question, b. + +In this example, the sum of these counts is 3 + 3 + 3 + 1 + 1 = 11. + +For each group, count the number of questions to which anyone answered "yes". What is the sum of those counts? + + +## --- Part Two --- +As you finish the last group's customs declaration, you notice that you misread one word in the instructions: + +You don't need to identify the questions to which anyone answered "yes"; you need to identify the questions to which everyone answered "yes"! + +Using the same example as above: + +
+abc
+
+a
+b
+c
+
+ab
+ac
+
+a
+a
+a
+a
+
+b
+
+
+ +This list represents answers from five groups: + + + - In the first group, everyone (all 1 person) answered "yes" to 3 questions: a, b, and c. + - In the second group, there is no question to which everyone answered "yes". + - In the third group, everyone answered yes to only 1 question, a. Since some people did not answer "yes" to b or c, they don't count. + - In the fourth group, everyone answered yes to only 1 question, a. + - In the fifth group, everyone (all 1 person) answered "yes" to 1 question, b. + +In this example, the sum of these counts is 3 + 0 + 1 + 1 + 1 = 6. + +For each group, count the number of questions to which everyone answered "yes". What is the sum of those counts? + + diff --git a/2020/Day06/input.in b/2020/Day06/input.in index 62ced6e23..ecd89a095 100644 Binary files a/2020/Day06/input.in and b/2020/Day06/input.in differ diff --git a/2020/Day07/README.md b/2020/Day07/README.md index a3323abd5..6e3f1972d 100644 --- a/2020/Day07/README.md +++ b/2020/Day07/README.md @@ -1,6 +1,71 @@ +original source: [https://adventofcode.com/2020/day/7](https://adventofcode.com/2020/day/7) ## --- Day 7: Handy Haversacks --- You land at the regional airport in time for your next flight. In fact, it looks like you'll even have time to grab some food: all flights are currently delayed due to issues in luggage processing. Due to recent aviation regulations, many rules (your puzzle input) are being enforced about bags and their contents; bags must be color-coded and must contain specific quantities of other color-coded bags. Apparently, nobody responsible for these regulations considered how long they would take to enforce! -Read the [full puzzle](https://adventofcode.com/2020/day/7). \ No newline at end of file +For example, consider the following rules: + +
+light red bags contain 1 bright white bag, 2 muted yellow bags.
+dark orange bags contain 3 bright white bags, 4 muted yellow bags.
+bright white bags contain 1 shiny gold bag.
+muted yellow bags contain 2 shiny gold bags, 9 faded blue bags.
+shiny gold bags contain 1 dark olive bag, 2 vibrant plum bags.
+dark olive bags contain 3 faded blue bags, 4 dotted black bags.
+vibrant plum bags contain 5 faded blue bags, 6 dotted black bags.
+faded blue bags contain no other bags.
+dotted black bags contain no other bags.
+
+
+ +These rules specify the required contents for 9 bag types. In this example, every faded blue bag is empty, every vibrant plum bag contains 11 bags (5 faded blue and 6 dotted black), and so on. + +You have a shiny gold bag. If you wanted to carry it in at least one other bag, how many different bag colors would be valid for the outermost bag? (In other words: how many colors can, eventually, contain at least one shiny gold bag?) + +In the above rules, the following options would be available to you: + + + - A bright white bag, which can hold your shiny gold bag directly. + - A muted yellow bag, which can hold your shiny gold bag directly, plus some other bags. + - A dark orange bag, which can hold bright white and muted yellow bags, either of which could then hold your shiny gold bag. + - A light red bag, which can hold bright white and muted yellow bags, either of which could then hold your shiny gold bag. + +So, in this example, the number of bag colors that can eventually contain at least one shiny gold bag is 4. + +How many bag colors can eventually contain at least one shiny gold bag? (The list of rules is quite long; make sure you get all of it.) + + +## --- Part Two --- +It's getting pretty expensive to fly these days - not because of ticket prices, but because of the ridiculous number of bags you need to buy! + +Consider again your shiny gold bag and the rules from the above example: + + + - faded blue bags contain 0 other bags. + - dotted black bags contain 0 other bags. + - vibrant plum bags contain 11 other bags: 5 faded blue bags and 6 dotted black bags. + - dark olive bags contain 7 other bags: 3 faded blue bags and 4 dotted black bags. + +So, a single shiny gold bag must contain 1 dark olive bag (and the 7 bags within it) plus 2 vibrant plum bags (and the 11 bags within each of those): 1 + 1*7 + 2 + 2*11 = 32 bags! + +Of course, the actual rules have a small chance of going several levels deeper than this example; be sure to count all of the bags, even if the nesting becomes topologically impractical! + +Here's another example: + +
+shiny gold bags contain 2 dark red bags.
+dark red bags contain 2 dark orange bags.
+dark orange bags contain 2 dark yellow bags.
+dark yellow bags contain 2 dark green bags.
+dark green bags contain 2 dark blue bags.
+dark blue bags contain 2 dark violet bags.
+dark violet bags contain no other bags.
+
+
+ +In this example, a single shiny gold bag must contain 126 other bags. + +How many individual bags are required inside your single shiny gold bag? + + diff --git a/2020/Day07/input.in b/2020/Day07/input.in index 992861ef5..c05cffd84 100644 Binary files a/2020/Day07/input.in and b/2020/Day07/input.in differ diff --git a/2020/Day08/README.md b/2020/Day08/README.md index d59bf37f6..1af283114 100644 --- a/2020/Day08/README.md +++ b/2020/Day08/README.md @@ -1,6 +1,98 @@ +original source: [https://adventofcode.com/2020/day/8](https://adventofcode.com/2020/day/8) ## --- Day 8: Handheld Halting --- Your flight to the major airline hub reaches cruising altitude without incident. While you consider checking the in-flight menu for one of those drinks that come with a little umbrella, you are interrupted by the kid sitting next to you. Their [handheld game console](https://en.wikipedia.org/wiki/Handheld_game_console) won't turn on! They ask if you can take a look. -Read the [full puzzle](https://adventofcode.com/2020/day/8). \ No newline at end of file +You narrow the problem down to a strange infinite loop in the boot code (your puzzle input) of the device. You should be able to fix it, but first you need to be able to run the code in isolation. + +The boot code is represented as a text file with one instruction per line of text. Each instruction consists of an operation (acc, jmp, or nop) and an argument (a signed number like +4 or -20). + + + - acc increases or decreases a single global value called the accumulator by the value given in the argument. For example, acc +7 would increase the accumulator by 7. The accumulator starts at 0. After an acc instruction, the instruction immediately below it is executed next. + - jmp jumps to a new instruction relative to itself. The next instruction to execute is found using the argument as an offset from the jmp instruction; for example, jmp +2 would skip the next instruction, jmp +1 would continue to the instruction immediately below it, and jmp -20 would cause the instruction 20 lines above to be executed next. + - nop stands for No OPeration - it does nothing. The instruction immediately below it is executed next. + +For example, consider the following program: + +
+nop +0
+acc +1
+jmp +4
+acc +3
+jmp -3
+acc -99
+acc +1
+jmp -4
+acc +6
+
+
+ +These instructions are visited in this order: + +
+nop +0  | 1
+acc +1  | 2, 8(!)
+jmp +4  | 3
+acc +3  | 6
+jmp -3  | 7
+acc -99 |
+acc +1  | 4
+jmp -4  | 5
+acc +6  |
+
+
+ +First, the nop +0 does nothing. Then, the accumulator is increased from 0 to 1 (acc +1) and jmp +4 sets the next instruction to the other acc +1 near the bottom. After it increases the accumulator from 1 to 2, jmp -4 executes, setting the next instruction to the only acc +3. It sets the accumulator to 5, and jmp -3 causes the program to continue back at the first acc +1. + +This is an infinite loop: with this sequence of jumps, the program will run forever. The moment the program tries to run any instruction a second time, you know it will never terminate. + +Immediately before the program would run an instruction a second time, the value in the accumulator is 5. + +Run your copy of the boot code. Immediately before any instruction is executed a second time, what value is in the accumulator? + + +## --- Part Two --- +After some careful analysis, you believe that exactly one instruction is corrupted. + +Somewhere in the program, either a jmp is supposed to be a nop, or a nop is supposed to be a jmp. (No acc instructions were harmed in the corruption of this boot code.) + +The program is supposed to terminate by attempting to execute an instruction immediately after the last instruction in the file. By changing exactly one jmp or nop, you can repair the boot code and make it terminate correctly. + +For example, consider the same program from above: + +
+nop +0
+acc +1
+jmp +4
+acc +3
+jmp -3
+acc -99
+acc +1
+jmp -4
+acc +6
+
+
+ +If you change the first instruction from nop +0 to jmp +0, it would create a single-instruction infinite loop, never leaving that instruction. If you change almost any of the jmp instructions, the program will still eventually find another jmp instruction and loop forever. + +However, if you change the second-to-last instruction (from jmp -4 to nop -4), the program terminates! The instructions are visited in this order: + +
+nop +0  | 1
+acc +1  | 2
+jmp +4  | 3
+acc +3  |
+jmp -3  |
+acc -99 |
+acc +1  | 4
+nop -4  | 5
+acc +6  | 6
+
+
+ +After the last instruction (acc +6), the program terminates by attempting to run the instruction below the last instruction in the file. With this change, after the program terminates, the accumulator contains the value 8 (acc +1, acc +1, acc +6). + +Fix the program so that it terminates normally by changing exactly one jmp (to nop) or nop (to jmp). What is the value of the accumulator after the program terminates? + + diff --git a/2020/Day08/input.in b/2020/Day08/input.in index f89763dda..bdc7017ad 100644 Binary files a/2020/Day08/input.in and b/2020/Day08/input.in differ diff --git a/2020/Day09/README.md b/2020/Day09/README.md index 5a67e3bca..9ce2ad3f0 100644 --- a/2020/Day09/README.md +++ b/2020/Day09/README.md @@ -1,6 +1,92 @@ +original source: [https://adventofcode.com/2020/day/9](https://adventofcode.com/2020/day/9) ## --- Day 9: Encoding Error --- With your neighbor happily enjoying their video game, you turn your attention to an open data port on the little screen in the seat in front of you. Though the port is non-standard, you manage to connect it to your computer through the clever use of several paperclips. Upon connection, the port outputs a series of numbers (your puzzle input). -Read the [full puzzle](https://adventofcode.com/2020/day/9). \ No newline at end of file +The data appears to be encrypted with the eXchange-Masking Addition System (XMAS) which, conveniently for you, is an old cypher with an important weakness. + +XMAS starts by transmitting a preamble of 25 numbers. After that, each number you receive should be the sum of any two of the 25 immediately previous numbers. The two numbers will have different values, and there might be more than one such pair. + +For example, suppose your preamble consists of the numbers 1 through 25 in a random order. To be valid, the next number must be the sum of two of those numbers: + + + - 26 would be a valid next number, as it could be 1 plus 25 (or many other pairs, like 2 and 24). + - 49 would be a valid next number, as it is the sum of 24 and 25. + - 100 would not be valid; no two of the previous 25 numbers sum to 100. + - 50 would also not be valid; although 25 appears in the previous 25 numbers, the two numbers in the pair must be different. + +Suppose the 26th number is 45, and the first number (no longer an option, as it is more than 25 numbers ago) was 20. Now, for the next number to be valid, there needs to be some pair of numbers among 1-19, 21-25, or 45 that add up to it: + + + - 26 would still be a valid next number, as 1 and 25 are still within the previous 25 numbers. + - 65 would not be valid, as no two of the available numbers sum to it. + - 64 and 66 would both be valid, as they are the result of 19+45 and 21+45 respectively. + +Here is a larger example which only considers the previous 5 numbers (and has a preamble of length 5): + +
+35
+20
+15
+25
+47
+40
+62
+55
+65
+95
+102
+117
+150
+182
+127
+219
+299
+277
+309
+576
+
+
+ +In this example, after the 5-number preamble, almost every number is the sum of two of the previous 5 numbers; the only number that does not follow this rule is 127. + +The first step of attacking the weakness in the XMAS data is to find the first number in the list (after the preamble) which is not the sum of two of the 25 numbers before it. What is the first number that does not have this property? + + +## --- Part Two --- +The final step in breaking the XMAS encryption relies on the invalid number you just found: you must find a contiguous set of at least two numbers in your list which sum to the invalid number from step 1. + +Again consider the above example: + +
+35
+20
+15
+25
+47
+40
+62
+55
+65
+95
+102
+117
+150
+182
+127
+219
+299
+277
+309
+576
+
+
+ +In this list, adding up all of the numbers from 15 through 40 produces the invalid number from step 1, 127. (Of course, the contiguous set of numbers in your actual list might be much longer.) + +To find the encryption weakness, add together the smallest and largest number in this contiguous range; in this example, these are 15 and 47, producing 62. + +What is the encryption weakness in your XMAS-encrypted list of numbers? + + diff --git a/2020/Day09/input.in b/2020/Day09/input.in index 59a243f0a..5d625e51d 100644 Binary files a/2020/Day09/input.in and b/2020/Day09/input.in differ diff --git a/2020/Day10/README.md b/2020/Day10/README.md index 9d44928ce..79d9a3df1 100644 --- a/2020/Day10/README.md +++ b/2020/Day10/README.md @@ -1,6 +1,154 @@ +original source: [https://adventofcode.com/2020/day/10](https://adventofcode.com/2020/day/10) ## --- Day 10: Adapter Array --- Patched into the aircraft's data port, you discover weather forecasts of a massive tropical storm. Before you can figure out whether it will impact your vacation plans, however, your device suddenly turns off! Its battery is dead. -Read the [full puzzle](https://adventofcode.com/2020/day/10). \ No newline at end of file +You'll need to plug it in. There's only one problem: the charging outlet near your seat produces the wrong number of jolts. Always prepared, you make a list of all of the joltage adapters in your bag. + +Each of your joltage adapters is rated for a specific output joltage (your puzzle input). Any given adapter can take an input 1, 2, or 3 jolts lower than its rating and still produce its rated output joltage. + +In addition, your device has a built-in joltage adapter rated for 3 jolts higher than the highest-rated adapter in your bag. (If your adapter list were 3, 9, and 6, your device's built-in adapter would be rated for 12 jolts.) + +Treat the charging outlet near your seat as having an effective joltage rating of 0. + +Since you have some time to kill, you might as well test all of your adapters. Wouldn't want to get to your resort and realize you can't even charge your device! + +If you use every adapter in your bag at once, what is the distribution of joltage differences between the charging outlet, the adapters, and your device? + +For example, suppose that in your bag, you have adapters with the following joltage ratings: + +
+16
+10
+15
+5
+1
+11
+7
+19
+6
+12
+4
+
+
+ +With these adapters, your device's built-in joltage adapter would be rated for 19 + 3 = 22 jolts, 3 higher than the highest-rated adapter. + +Because adapters can only connect to a source 1-3 jolts lower than its rating, in order to use every adapter, you'd need to choose them like this: + + + - The charging outlet has an effective rating of 0 jolts, so the only adapters that could connect to it directly would need to have a joltage rating of 1, 2, or 3 jolts. Of these, only one you have is an adapter rated 1 jolt (difference of 1). + - From your 1-jolt rated adapter, the only choice is your 4-jolt rated adapter (difference of 3). + - From the 4-jolt rated adapter, the adapters rated 5, 6, or 7 are valid choices. However, in order to not skip any adapters, you have to pick the adapter rated 5 jolts (difference of 1). + - Similarly, the next choices would need to be the adapter rated 6 and then the adapter rated 7 (with difference of 1 and 1). + - The only adapter that works with the 7-jolt rated adapter is the one rated 10 jolts (difference of 3). + - From 10, the choices are 11 or 12; choose 11 (difference of 1) and then 12 (difference of 1). + - After 12, only valid adapter has a rating of 15 (difference of 3), then 16 (difference of 1), then 19 (difference of 3). + - Finally, your device's built-in adapter is always 3 higher than the highest adapter, so its rating is 22 jolts (always a difference of 3). + +In this example, when using every adapter, there are 7 differences of 1 jolt and 5 differences of 3 jolts. + +Here is a larger example: + +
+28
+33
+18
+42
+31
+14
+46
+20
+48
+47
+24
+23
+49
+45
+19
+38
+39
+11
+1
+32
+25
+35
+8
+17
+7
+9
+4
+2
+34
+10
+3
+
+
+ +In this larger example, in a chain that uses all of the adapters, there are 22 differences of 1 jolt and 10 differences of 3 jolts. + +Find a chain that uses all of your adapters to connect the charging outlet to your device's built-in adapter and count the joltage differences between the charging outlet, the adapters, and your device. What is the number of 1-jolt differences multiplied by the number of 3-jolt differences? + + +## --- Part Two --- +To completely determine whether you have enough adapters, you'll need to figure out how many different ways they can be arranged. Every arrangement needs to connect the charging outlet to your device. The previous rules about when adapters can successfully connect still apply. + +The first example above (the one that starts with 16, 10, 15) supports the following arrangements: + +
+(0), 1, 4, 5, 6, 7, 10, 11, 12, 15, 16, 19, (22)
+(0), 1, 4, 5, 6, 7, 10, 12, 15, 16, 19, (22)
+(0), 1, 4, 5, 7, 10, 11, 12, 15, 16, 19, (22)
+(0), 1, 4, 5, 7, 10, 12, 15, 16, 19, (22)
+(0), 1, 4, 6, 7, 10, 11, 12, 15, 16, 19, (22)
+(0), 1, 4, 6, 7, 10, 12, 15, 16, 19, (22)
+(0), 1, 4, 7, 10, 11, 12, 15, 16, 19, (22)
+(0), 1, 4, 7, 10, 12, 15, 16, 19, (22)
+
+
+ +(The charging outlet and your device's built-in adapter are shown in parentheses.) Given the adapters from the first example, the total number of arrangements that connect the charging outlet to your device is 8. + +The second example above (the one that starts with 28, 33, 18) has many arrangements. Here are a few: + +
+(0), 1, 2, 3, 4, 7, 8, 9, 10, 11, 14, 17, 18, 19, 20, 23, 24, 25, 28, 31,
+32, 33, 34, 35, 38, 39, 42, 45, 46, 47, 48, 49, (52)
+
+(0), 1, 2, 3, 4, 7, 8, 9, 10, 11, 14, 17, 18, 19, 20, 23, 24, 25, 28, 31,
+32, 33, 34, 35, 38, 39, 42, 45, 46, 47, 49, (52)
+
+(0), 1, 2, 3, 4, 7, 8, 9, 10, 11, 14, 17, 18, 19, 20, 23, 24, 25, 28, 31,
+32, 33, 34, 35, 38, 39, 42, 45, 46, 48, 49, (52)
+
+(0), 1, 2, 3, 4, 7, 8, 9, 10, 11, 14, 17, 18, 19, 20, 23, 24, 25, 28, 31,
+32, 33, 34, 35, 38, 39, 42, 45, 46, 49, (52)
+
+(0), 1, 2, 3, 4, 7, 8, 9, 10, 11, 14, 17, 18, 19, 20, 23, 24, 25, 28, 31,
+32, 33, 34, 35, 38, 39, 42, 45, 47, 48, 49, (52)
+
+(0), 3, 4, 7, 10, 11, 14, 17, 20, 23, 25, 28, 31, 34, 35, 38, 39, 42, 45,
+46, 48, 49, (52)
+
+(0), 3, 4, 7, 10, 11, 14, 17, 20, 23, 25, 28, 31, 34, 35, 38, 39, 42, 45,
+46, 49, (52)
+
+(0), 3, 4, 7, 10, 11, 14, 17, 20, 23, 25, 28, 31, 34, 35, 38, 39, 42, 45,
+47, 48, 49, (52)
+
+(0), 3, 4, 7, 10, 11, 14, 17, 20, 23, 25, 28, 31, 34, 35, 38, 39, 42, 45,
+47, 49, (52)
+
+(0), 3, 4, 7, 10, 11, 14, 17, 20, 23, 25, 28, 31, 34, 35, 38, 39, 42, 45,
+48, 49, (52)
+
+
+ +In total, this set of adapters can connect the charging outlet to your device in 19208 distinct arrangements. + +You glance back down at your bag and try to remember why you brought so many adapters; there must be more than a trillion valid ways to arrange them! Surely, there must be an efficient way to count the arrangements. + +What is the total number of distinct ways you can arrange the adapters to connect the charging outlet to your device? + + diff --git a/2020/Day10/input.in b/2020/Day10/input.in index 759c3b340..f7374a05d 100644 Binary files a/2020/Day10/input.in and b/2020/Day10/input.in differ diff --git a/2020/Day11/README.md b/2020/Day11/README.md index a63684e2a..80458b89a 100644 --- a/2020/Day11/README.md +++ b/2020/Day11/README.md @@ -1,6 +1,259 @@ +original source: [https://adventofcode.com/2020/day/11](https://adventofcode.com/2020/day/11) ## --- Day 11: Seating System --- Your plane lands with plenty of time to spare. The final leg of your journey is a ferry that goes directly to the tropical island where you can finally start your vacation. As you reach the waiting area to board the ferry, you realize you're so early, nobody else has even arrived yet! By modeling the process people use to choose (or abandon) their seat in the waiting area, you're pretty sure you can predict the best place to sit. You make a quick map of the seat layout (your puzzle input). -Read the [full puzzle](https://adventofcode.com/2020/day/11). \ No newline at end of file +The seat layout fits neatly on a grid. Each position is either floor (.), an empty seat (L), or an occupied seat (#). For example, the initial seat layout might look like this: + +
+L.LL.LL.LL
+LLLLLLL.LL
+L.L.L..L..
+LLLL.LL.LL
+L.LL.LL.LL
+L.LLLLL.LL
+..L.L.....
+LLLLLLLLLL
+L.LLLLLL.L
+L.LLLLL.LL
+
+
+ +Now, you just need to model the people who will be arriving shortly. Fortunately, people are entirely predictable and always follow a simple set of rules. All decisions are based on the number of occupied seats adjacent to a given seat (one of the eight positions immediately up, down, left, right, or diagonal from the seat). The following rules are applied to every seat simultaneously: + + + - If a seat is empty (L) and there are no occupied seats adjacent to it, the seat becomes occupied. + - If a seat is occupied (#) and four or more seats adjacent to it are also occupied, the seat becomes empty. + - Otherwise, the seat's state does not change. + +Floor (.) never changes; seats don't move, and nobody sits on the floor. + +After one round of these rules, every seat in the example layout becomes occupied: + +
+#.##.##.##
+#######.##
+#.#.#..#..
+####.##.##
+#.##.##.##
+#.#####.##
+..#.#.....
+##########
+#.######.#
+#.#####.##
+
+
+ +After a second round, the seats with four or more occupied adjacent seats become empty again: + +
+#.LL.L#.##
+#LLLLLL.L#
+L.L.L..L..
+#LLL.LL.L#
+#.LL.LL.LL
+#.LLLL#.##
+..L.L.....
+#LLLLLLLL#
+#.LLLLLL.L
+#.#LLLL.##
+
+
+ +This process continues for three more rounds: + +
+#.##.L#.##
+#L###LL.L#
+L.#.#..#..
+#L##.##.L#
+#.##.LL.LL
+#.###L#.##
+..#.#.....
+#L######L#
+#.LL###L.L
+#.#L###.##
+
+
+ +
+#.#L.L#.##
+#LLL#LL.L#
+L.L.L..#..
+#LLL.##.L#
+#.LL.LL.LL
+#.LL#L#.##
+..L.L.....
+#L#LLLL#L#
+#.LLLLLL.L
+#.#L#L#.##
+
+
+ +
+#.#L.L#.##
+#LLL#LL.L#
+L.#.L..#..
+#L##.##.L#
+#.#L.LL.LL
+#.#L#L#.##
+..L.L.....
+#L#L##L#L#
+#.LLLLLL.L
+#.#L#L#.##
+
+
+ +At this point, something interesting happens: the chaos stabilizes and further applications of these rules cause no seats to change state! Once people stop moving around, you count 37 occupied seats. + +Simulate your seating area by applying the seating rules repeatedly until no seats change state. How many seats end up occupied? + + +## --- Part Two --- +As soon as people start to arrive, you realize your mistake. People don't just care about adjacent seats - they care about the first seat they can see in each of those eight directions! + +Now, instead of considering just the eight immediately adjacent seats, consider the first seat in each of those eight directions. For example, the empty seat below would see eight occupied seats: + +
+.......#.
+...#.....
+.#.......
+.........
+..#L....#
+....#....
+.........
+#........
+...#.....
+
+
+ +The leftmost empty seat below would only see one empty seat, but cannot see any of the occupied ones: + +
+.............
+.L.L.#.#.#.#.
+.............
+
+
+ +The empty seat below would see no occupied seats: + +
+.##.##.
+#.#.#.#
+##...##
+...L...
+##...##
+#.#.#.#
+.##.##.
+
+
+ +Also, people seem to be more tolerant than you expected: it now takes five or more visible occupied seats for an occupied seat to become empty (rather than four or more from the previous rules). The other rules still apply: empty seats that see no occupied seats become occupied, seats matching no rule don't change, and floor never changes. + +Given the same starting layout as above, these new rules cause the seating area to shift around as follows: + +
+L.LL.LL.LL
+LLLLLLL.LL
+L.L.L..L..
+LLLL.LL.LL
+L.LL.LL.LL
+L.LLLLL.LL
+..L.L.....
+LLLLLLLLLL
+L.LLLLLL.L
+L.LLLLL.LL
+
+
+ +
+#.##.##.##
+#######.##
+#.#.#..#..
+####.##.##
+#.##.##.##
+#.#####.##
+..#.#.....
+##########
+#.######.#
+#.#####.##
+
+
+ +
+#.LL.LL.L#
+#LLLLLL.LL
+L.L.L..L..
+LLLL.LL.LL
+L.LL.LL.LL
+L.LLLLL.LL
+..L.L.....
+LLLLLLLLL#
+#.LLLLLL.L
+#.LLLLL.L#
+
+
+ +
+#.L#.##.L#
+#L#####.LL
+L.#.#..#..
+##L#.##.##
+#.##.#L.##
+#.#####.#L
+..#.#.....
+LLL####LL#
+#.L#####.L
+#.L####.L#
+
+
+ +
+#.L#.L#.L#
+#LLLLLL.LL
+L.L.L..#..
+##LL.LL.L#
+L.LL.LL.L#
+#.LLLLL.LL
+..L.L.....
+LLLLLLLLL#
+#.LLLLL#.L
+#.L#LL#.L#
+
+
+ +
+#.L#.L#.L#
+#LLLLLL.LL
+L.L.L..#..
+##L#.#L.L#
+L.L#.#L.L#
+#.L####.LL
+..#.#.....
+LLL###LLL#
+#.LLLLL#.L
+#.L#LL#.L#
+
+
+ +
+#.L#.L#.L#
+#LLLLLL.LL
+L.L.L..#..
+##L#.#L.L#
+L.L#.LL.L#
+#.LLLL#.LL
+..#.L.....
+LLL###LLL#
+#.LLLLL#.L
+#.L#LL#.L#
+
+
+ +Again, at this point, people stop shifting around and the seating area reaches equilibrium. Once this occurs, you count 26 occupied seats. + +Given the new visibility method and the rule change for occupied seats becoming empty, once equilibrium is reached, how many seats end up occupied? + + diff --git a/2020/Day11/input.in b/2020/Day11/input.in index e47a1f52c..7e491f467 100644 Binary files a/2020/Day11/input.in and b/2020/Day11/input.in differ diff --git a/2020/Day12/README.md b/2020/Day12/README.md index 5a856ba51..80377a84d 100644 --- a/2020/Day12/README.md +++ b/2020/Day12/README.md @@ -1,6 +1,74 @@ +original source: [https://adventofcode.com/2020/day/12](https://adventofcode.com/2020/day/12) ## --- Day 12: Rain Risk --- Your ferry made decent progress toward the island, but the storm came in faster than anyone expected. The ferry needs to take evasive actions! Unfortunately, the ship's navigation computer seems to be malfunctioning; rather than giving a route directly to safety, it produced extremely circuitous instructions. When the captain uses the [PA system](https://en.wikipedia.org/wiki/Public_address_system) to ask if anyone can help, you quickly volunteer. -Read the [full puzzle](https://adventofcode.com/2020/day/12). \ No newline at end of file +The navigation instructions (your puzzle input) consists of a sequence of single-character actions paired with integer input values. After staring at them for a few minutes, you work out what they probably mean: + + + - Action N means to move north by the given value. + - Action S means to move south by the given value. + - Action E means to move east by the given value. + - Action W means to move west by the given value. + - Action L means to turn left the given number of degrees. + - Action R means to turn right the given number of degrees. + - Action F means to move forward by the given value in the direction the ship is currently facing. + +The ship starts by facing east. Only the L and R actions change the direction the ship is facing. (That is, if the ship is facing east and the next instruction is N10, the ship would move north 10 units, but would still move east if the following action were F.) + +For example: + +
+F10
+N3
+F7
+R90
+F11
+
+
+ +These instructions would be handled as follows: + + + - F10 would move the ship 10 units east (because the ship starts by facing east) to east 10, north 0. + - N3 would move the ship 3 units north to east 10, north 3. + - F7 would move the ship another 7 units east (because the ship is still facing east) to east 17, north 3. + - R90 would cause the ship to turn right by 90 degrees and face south; it remains at east 17, north 3. + - F11 would move the ship 11 units south to east 17, south 8. + +At the end of these instructions, the ship's [Manhattan distance](https://en.wikipedia.org/wiki/Manhattan_distance) (sum of the absolute values of its east/west position and its north/south position) from its starting position is 17 + 8 = 25. + +Figure out where the navigation instructions lead. What is the Manhattan distance between that location and the ship's starting position? + + +## --- Part Two --- +Before you can give the destination to the captain, you realize that the actual action meanings were printed on the back of the instructions the whole time. + +Almost all of the actions indicate how to move a waypoint which is relative to the ship's position: + + + - Action N means to move the waypoint north by the given value. + - Action S means to move the waypoint south by the given value. + - Action E means to move the waypoint east by the given value. + - Action W means to move the waypoint west by the given value. + - Action L means to rotate the waypoint around the ship left (counter-clockwise) the given number of degrees. + - Action R means to rotate the waypoint around the ship right (clockwise) the given number of degrees. + - Action F means to move forward to the waypoint a number of times equal to the given value. + +The waypoint starts 10 units east and 1 unit north relative to the ship. The waypoint is relative to the ship; that is, if the ship moves, the waypoint moves with it. + +For example, using the same instructions as above: + + + - F10 moves the ship to the waypoint 10 times (a total of 100 units east and 10 units north), leaving the ship at east 100, north 10. The waypoint stays 10 units east and 1 unit north of the ship. + - N3 moves the waypoint 3 units north to 10 units east and 4 units north of the ship. The ship remains at east 100, north 10. + - F7 moves the ship to the waypoint 7 times (a total of 70 units east and 28 units north), leaving the ship at east 170, north 38. The waypoint stays 10 units east and 4 units north of the ship. + - R90 rotates the waypoint around the ship clockwise 90 degrees, moving it to 4 units east and 10 units south of the ship. The ship remains at east 170, north 38. + - F11 moves the ship to the waypoint 11 times (a total of 44 units east and 110 units south), leaving the ship at east 214, south 72. The waypoint stays 4 units east and 10 units south of the ship. + +After these operations, the ship's Manhattan distance from its starting position is 214 + 72 = 286. + +Figure out where the navigation instructions actually lead. What is the Manhattan distance between that location and the ship's starting position? + + diff --git a/2020/Day12/input.in b/2020/Day12/input.in index 87a53ff58..e10642dfe 100644 Binary files a/2020/Day12/input.in and b/2020/Day12/input.in differ diff --git a/2020/Day13/README.md b/2020/Day13/README.md index 358e65ddb..34c0c72e4 100644 --- a/2020/Day13/README.md +++ b/2020/Day13/README.md @@ -1,6 +1,127 @@ +original source: [https://adventofcode.com/2020/day/13](https://adventofcode.com/2020/day/13) ## --- Day 13: Shuttle Search --- Your ferry can make it safely to a nearby port, but it won't get much further. When you call to book another ship, you discover that no ships embark from that port to your vacation island. You'll need to get from the port to the nearest airport. Fortunately, a shuttle bus service is available to bring you from the sea port to the airport! Each bus has an ID number that also indicates how often the bus leaves for the airport. -Read the [full puzzle](https://adventofcode.com/2020/day/13). \ No newline at end of file +Bus schedules are defined based on a timestamp that measures the number of minutes since some fixed reference point in the past. At timestamp 0, every bus simultaneously departed from the sea port. After that, each bus travels to the airport, then various other locations, and finally returns to the sea port to repeat its journey forever. + +The time this loop takes a particular bus is also its ID number: the bus with ID 5 departs from the sea port at timestamps 0, 5, 10, 15, and so on. The bus with ID 11 departs at 0, 11, 22, 33, and so on. If you are there when the bus departs, you can ride that bus to the airport! + +Your notes (your puzzle input) consist of two lines. The first line is your estimate of the earliest timestamp you could depart on a bus. The second line lists the bus IDs that are in service according to the shuttle company; entries that show x must be out of service, so you decide to ignore them. + +To save time once you arrive, your goal is to figure out the earliest bus you can take to the airport. (There will be exactly one such bus.) + +For example, suppose you have the following notes: + +
+939
+7,13,x,x,59,x,31,19
+
+
+ +Here, the earliest timestamp you could depart is 939, and the bus IDs in service are 7, 13, 59, 31, and 19. Near timestamp 939, these bus IDs depart at the times marked D: + +
+time   bus 7   bus 13  bus 59  bus 31  bus 19
+929      .       .       .       .       .
+930      .       .       .       D       .
+931      D       .       .       .       D
+932      .       .       .       .       .
+933      .       .       .       .       .
+934      .       .       .       .       .
+935      .       .       .       .       .
+936      .       D       .       .       .
+937      .       .       .       .       .
+938      D       .       .       .       .
+939      .       .       .       .       .
+940      .       .       .       .       .
+941      .       .       .       .       .
+942      .       .       .       .       .
+943      .       .       .       .       .
+944      .       .       D       .       .
+945      D       .       .       .       .
+946      .       .       .       .       .
+947      .       .       .       .       .
+948      .       .       .       .       .
+949      .       D       .       .       .
+
+
+ +The earliest bus you could take is bus ID 59. It doesn't depart until timestamp 944, so you would need to wait 944 - 939 = 5 minutes before it departs. Multiplying the bus ID by the number of minutes you'd need to wait gives 295. + +What is the ID of the earliest bus you can take to the airport multiplied by the number of minutes you'll need to wait for that bus? + + +## --- Part Two --- +The shuttle company is running a contest: one gold coin for anyone that can find the earliest timestamp such that the first bus ID departs at that time and each subsequent listed bus ID departs at that subsequent minute. (The first line in your input is no longer relevant.) + +For example, suppose you have the same list of bus IDs as above: + +
+7,13,x,x,59,x,31,19
+
+ +An x in the schedule means there are no constraints on what bus IDs must depart at that time. + +This means you are looking for the earliest timestamp (called t) such that: + + + - Bus ID 7 departs at timestamp t. + - Bus ID 13 departs one minute after timestamp t. + - There are no requirements or restrictions on departures at two or three minutes after timestamp t. + - Bus ID 59 departs four minutes after timestamp t. + - There are no requirements or restrictions on departures at five minutes after timestamp t. + - Bus ID 31 departs six minutes after timestamp t. + - Bus ID 19 departs seven minutes after timestamp t. + +The only bus departures that matter are the listed bus IDs at their specific offsets from t. Those bus IDs can depart at other times, and other bus IDs can depart at those times. For example, in the list above, because bus ID 19 must depart seven minutes after the timestamp at which bus ID 7 departs, bus ID 7 will always also be departing with bus ID 19 at seven minutes after timestamp t. + +In this example, the earliest timestamp at which this occurs is 1068781: + +
+time     bus 7   bus 13  bus 59  bus 31  bus 19
+1068773    .       .       .       .       .
+1068774    D       .       .       .       .
+1068775    .       .       .       .       .
+1068776    .       .       .       .       .
+1068777    .       .       .       .       .
+1068778    .       .       .       .       .
+1068779    .       .       .       .       .
+1068780    .       .       .       .       .
+1068781    D       .       .       .       .
+1068782    .       D       .       .       .
+1068783    .       .       .       .       .
+1068784    .       .       .       .       .
+1068785    .       .       D       .       .
+1068786    .       .       .       .       .
+1068787    .       .       .       D       .
+1068788    D       .       .       .       D
+1068789    .       .       .       .       .
+1068790    .       .       .       .       .
+1068791    .       .       .       .       .
+1068792    .       .       .       .       .
+1068793    .       .       .       .       .
+1068794    .       .       .       .       .
+1068795    D       D       .       .       .
+1068796    .       .       .       .       .
+1068797    .       .       .       .       .
+
+
+ +In the above example, bus ID 7 departs at timestamp 1068788 (seven minutes after t). This is fine; the only requirement on that minute is that bus ID 19 departs then, and it does. + +Here are some other examples: + + + - The earliest timestamp that matches the list 17,x,13,19 is 3417. + - 67,7,59,61 first occurs at timestamp 754018. + - 67,x,7,59,61 first occurs at timestamp 779210. + - 67,7,x,59,61 first occurs at timestamp 1261476. + - 1789,37,47,1889 first occurs at timestamp 1202161486. + +However, with so many bus IDs in your list, surely the actual earliest timestamp will be larger than 100000000000000! + +What is the earliest timestamp such that all of the listed bus IDs depart at offsets matching their positions in the list? + + diff --git a/2020/Day13/input.in b/2020/Day13/input.in index d5be0d5c9..3d3e1d30e 100644 Binary files a/2020/Day13/input.in and b/2020/Day13/input.in differ diff --git a/2020/Day14/README.md b/2020/Day14/README.md index c5e356207..e8a16d304 100644 --- a/2020/Day14/README.md +++ b/2020/Day14/README.md @@ -1,6 +1,125 @@ +original source: [https://adventofcode.com/2020/day/14](https://adventofcode.com/2020/day/14) ## --- Day 14: Docking Data --- As your ferry approaches the sea port, the captain asks for your help again. The computer system that runs this port isn't compatible with the docking program on the ferry, so the docking parameters aren't being correctly initialized in the docking program's memory. After a brief inspection, you discover that the sea port's computer system uses a strange [bitmask](https://en.wikipedia.org/wiki/Mask_(computing)) system in its initialization program. Although you don't have the correct decoder chip handy, you can emulate it in software! -Read the [full puzzle](https://adventofcode.com/2020/day/14). \ No newline at end of file +The initialization program (your puzzle input) can either update the bitmask or write a value to memory. Values and memory addresses are both 36-bit unsigned integers. For example, ignoring bitmasks for a moment, a line like mem[8] = 11 would write the value 11 to memory address 8. + +The bitmask is always given as a string of 36 bits, written with the most significant bit (representing 2^35) on the left and the least significant bit (2^0, that is, the 1s bit) on the right. The current bitmask is applied to values immediately before they are written to memory: a 0 or 1 overwrites the corresponding bit in the value, while an X leaves the bit in the value unchanged. + +For example, consider the following program: + +
+mask = XXXXXXXXXXXXXXXXXXXXXXXXXXXXX1XXXX0X
+mem[8] = 11
+mem[7] = 101
+mem[8] = 0
+
+
+ +This program starts by specifying a bitmask (mask = ....). The mask it specifies will overwrite two bits in every written value: the 2s bit is overwritten with 0, and the 64s bit is overwritten with 1. + +The program then attempts to write the value 11 to memory address 8. By expanding everything out to individual bits, the mask is applied as follows: + +
+value:  000000000000000000000000000000001011  (decimal 11)
+mask:   XXXXXXXXXXXXXXXXXXXXXXXXXXXXX1XXXX0X
+result: 000000000000000000000000000001001001  (decimal 73)
+
+
+ +So, because of the mask, the value 73 is written to memory address 8 instead. Then, the program tries to write 101 to address 7: + +
+value:  000000000000000000000000000001100101  (decimal 101)
+mask:   XXXXXXXXXXXXXXXXXXXXXXXXXXXXX1XXXX0X
+result: 000000000000000000000000000001100101  (decimal 101)
+
+
+ +This time, the mask has no effect, as the bits it overwrote were already the values the mask tried to set. Finally, the program tries to write 0 to address 8: + +
+value:  000000000000000000000000000000000000  (decimal 0)
+mask:   XXXXXXXXXXXXXXXXXXXXXXXXXXXXX1XXXX0X
+result: 000000000000000000000000000001000000  (decimal 64)
+
+
+ +64 is written to address 8 instead, overwriting the value that was there previously. + +To initialize your ferry's docking program, you need the sum of all values left in memory after the initialization program completes. (The entire 36-bit address space begins initialized to the value 0 at every address.) In the above example, only two values in memory are not zero - 101 (at address 7) and 64 (at address 8) - producing a sum of 165. + +Execute the initialization program. What is the sum of all values left in memory after it completes? + + +## --- Part Two --- +For some reason, the sea port's computer system still can't communicate with your ferry's docking program. It must be using version 2 of the decoder chip! + +A version 2 decoder chip doesn't modify the values being written at all. Instead, it acts as a [memory address decoder](https://www.youtube.com/watch?v=PvfhANgLrm4). Immediately before a value is written to memory, each bit in the bitmask modifies the corresponding bit of the destination memory address in the following way: + + + - If the bitmask bit is 0, the corresponding memory address bit is unchanged. + - If the bitmask bit is 1, the corresponding memory address bit is overwritten with 1. + - If the bitmask bit is X, the corresponding memory address bit is floating. + +A floating bit is not connected to anything and instead fluctuates unpredictably. In practice, this means the floating bits will take on all possible values, potentially causing many memory addresses to be written all at once! + +For example, consider the following program: + +
+mask = 000000000000000000000000000000X1001X
+mem[42] = 100
+mask = 00000000000000000000000000000000X0XX
+mem[26] = 1
+
+
+ +When this program goes to write to memory address 42, it first applies the bitmask: + +
+address: 000000000000000000000000000000101010  (decimal 42)
+mask:    000000000000000000000000000000X1001X
+result:  000000000000000000000000000000X1101X
+
+
+ +After applying the mask, four bits are overwritten, three of which are different, and two of which are floating. Floating bits take on every possible combination of values; with two floating bits, four actual memory addresses are written: + +
+000000000000000000000000000000011010  (decimal 26)
+000000000000000000000000000000011011  (decimal 27)
+000000000000000000000000000000111010  (decimal 58)
+000000000000000000000000000000111011  (decimal 59)
+
+
+ +Next, the program is about to write to memory address 26 with a different bitmask: + +
+address: 000000000000000000000000000000011010  (decimal 26)
+mask:    00000000000000000000000000000000X0XX
+result:  00000000000000000000000000000001X0XX
+
+
+ +This results in an address with three floating bits, causing writes to eight memory addresses: + +
+000000000000000000000000000000010000  (decimal 16)
+000000000000000000000000000000010001  (decimal 17)
+000000000000000000000000000000010010  (decimal 18)
+000000000000000000000000000000010011  (decimal 19)
+000000000000000000000000000000011000  (decimal 24)
+000000000000000000000000000000011001  (decimal 25)
+000000000000000000000000000000011010  (decimal 26)
+000000000000000000000000000000011011  (decimal 27)
+
+
+ +The entire 36-bit address space still begins initialized to the value 0 at every address, and you still need the sum of all values left in memory at the end of the program. In this example, the sum is 208. + +Execute the initialization program using an emulator for a version 2 decoder chip. What is the sum of all values left in memory after it completes? + + diff --git a/2020/Day14/input.in b/2020/Day14/input.in index 5ee6d12fb..e7977bf3e 100644 Binary files a/2020/Day14/input.in and b/2020/Day14/input.in differ diff --git a/2020/Day15/README.md b/2020/Day15/README.md index 5ac8db2cb..062bb178e 100644 --- a/2020/Day15/README.md +++ b/2020/Day15/README.md @@ -1,6 +1,60 @@ +original source: [https://adventofcode.com/2020/day/15](https://adventofcode.com/2020/day/15) ## --- Day 15: Rambunctious Recitation --- You catch the airport shuttle and try to book a new flight to your vacation island. Due to the storm, all direct flights have been cancelled, but a route is available to get around the storm. You take it. While you wait for your flight, you decide to check in with the Elves back at the North Pole. They're playing a memory game and are ever so excited to explain the rules! -Read the [full puzzle](https://adventofcode.com/2020/day/15). \ No newline at end of file +In this game, the players take turns saying numbers. They begin by taking turns reading from a list of starting numbers (your puzzle input). Then, each turn consists of considering the most recently spoken number: + + + - If that was the first time the number has been spoken, the current player says 0. + - Otherwise, the number had been spoken before; the current player announces how many turns apart the number is from when it was previously spoken. + +So, after the starting numbers, each turn results in that player speaking aloud either 0 (if the last number is new) or an age (if the last number is a repeat). + +For example, suppose the starting numbers are 0,3,6: + + + - Turn 1: The 1st number spoken is a starting number, 0. + - Turn 2: The 2nd number spoken is a starting number, 3. + - Turn 3: The 3rd number spoken is a starting number, 6. + - Turn 4: Now, consider the last number spoken, 6. Since that was the first time the number had been spoken, the 4th number spoken is 0. + - Turn 5: Next, again consider the last number spoken, 0. Since it had been spoken before, the next number to speak is the difference between the turn number when it was last spoken (the previous turn, 4) and the turn number of the time it was most recently spoken before then (turn 1). Thus, the 5th number spoken is 4 - 1, 3. + - Turn 6: The last number spoken, 3 had also been spoken before, most recently on turns 5 and 2. So, the 6th number spoken is 5 - 2, 3. + - Turn 7: Since 3 was just spoken twice in a row, and the last two turns are 1 turn apart, the 7th number spoken is 1. + - Turn 8: Since 1 is new, the 8th number spoken is 0. + - Turn 9: 0 was last spoken on turns 8 and 4, so the 9th number spoken is the difference between them, 4. + - Turn 10: 4 is new, so the 10th number spoken is 0. + +(The game ends when the Elves get sick of playing or dinner is ready, whichever comes first.) + +Their question for you is: what will be the 2020th number spoken? In the example above, the 2020th number spoken will be 436. + +Here are a few more examples: + + + - Given the starting numbers 1,3,2, the 2020th number spoken is 1. + - Given the starting numbers 2,1,3, the 2020th number spoken is 10. + - Given the starting numbers 1,2,3, the 2020th number spoken is 27. + - Given the starting numbers 2,3,1, the 2020th number spoken is 78. + - Given the starting numbers 3,2,1, the 2020th number spoken is 438. + - Given the starting numbers 3,1,2, the 2020th number spoken is 1836. + +Given your starting numbers, what will be the 2020th number spoken? + + +## --- Part Two --- +Impressed, the Elves issue you a challenge: determine the 30000000th number spoken. For example, given the same starting numbers as above: + + + - Given 0,3,6, the 30000000th number spoken is 175594. + - Given 1,3,2, the 30000000th number spoken is 2578. + - Given 2,1,3, the 30000000th number spoken is 3544142. + - Given 1,2,3, the 30000000th number spoken is 261214. + - Given 2,3,1, the 30000000th number spoken is 6895259. + - Given 3,2,1, the 30000000th number spoken is 18. + - Given 3,1,2, the 30000000th number spoken is 362. + +Given your starting numbers, what will be the 30000000th number spoken? + + diff --git a/2020/Day15/input.in b/2020/Day15/input.in index 1522fa3f9..6557303f7 100644 Binary files a/2020/Day15/input.in and b/2020/Day15/input.in differ diff --git a/2020/Day16/README.md b/2020/Day16/README.md index 60aa6b76e..2bf48c8d1 100644 --- a/2020/Day16/README.md +++ b/2020/Day16/README.md @@ -1,6 +1,76 @@ +original source: [https://adventofcode.com/2020/day/16](https://adventofcode.com/2020/day/16) ## --- Day 16: Ticket Translation --- As you're walking to yet another connecting flight, you realize that one of the legs of your re-routed trip coming up is on a high-speed train. However, the train ticket you were given is in a language you don't understand. You should probably figure out what it says before you get to the train station after the next flight. Unfortunately, you can't actually read the words on the ticket. You can, however, read the numbers, and so you figure out the fields these tickets must have and the valid ranges for values in those fields. -Read the [full puzzle](https://adventofcode.com/2020/day/16). \ No newline at end of file +You collect the rules for ticket fields, the numbers on your ticket, and the numbers on other nearby tickets for the same train service (via the airport security cameras) together into a single document you can reference (your puzzle input). + +The rules for ticket fields specify a list of fields that exist somewhere on the ticket and the valid ranges of values for each field. For example, a rule like class: 1-3 or 5-7 means that one of the fields in every ticket is named class and can be any value in the ranges 1-3 or 5-7 (inclusive, such that 3 and 5 are both valid in this field, but 4 is not). + +Each ticket is represented by a single line of comma-separated values. The values are the numbers on the ticket in the order they appear; every ticket has the same format. For example, consider this ticket: + +
+.--------------------------------------------------------.
+| ????: 101    ?????: 102   ??????????: 103     ???: 104 |
+|                                                        |
+| ??: 301  ??: 302             ???????: 303      ??????? |
+| ??: 401  ??: 402           ???? ????: 403    ????????? |
+'--------------------------------------------------------'
+
+
+ +Here, ? represents text in a language you don't understand. This ticket might be represented as 101,102,103,104,301,302,303,401,402,403; of course, the actual train tickets you're looking at are much more complicated. In any case, you've extracted just the numbers in such a way that the first number is always the same specific field, the second number is always a different specific field, and so on - you just don't know what each position actually means! + +Start by determining which tickets are completely invalid; these are tickets that contain values which aren't valid for any field. Ignore your ticket for now. + +For example, suppose you have the following notes: + +
+class: 1-3 or 5-7
+row: 6-11 or 33-44
+seat: 13-40 or 45-50
+
+your ticket:
+7,1,14
+
+nearby tickets:
+7,3,47
+40,4,50
+55,2,20
+38,6,12
+
+
+ +It doesn't matter which position corresponds to which field; you can identify invalid nearby tickets by considering only whether tickets contain values that are not valid for any field. In this example, the values on the first nearby ticket are all valid for at least one field. This is not true of the other three nearby tickets: the values 4, 55, and 12 are are not valid for any field. Adding together all of the invalid values produces your ticket scanning error rate: 4 + 55 + 12 = 71. + +Consider the validity of the nearby tickets you scanned. What is your ticket scanning error rate? + + +## --- Part Two --- +Now that you've identified which tickets contain invalid values, discard those tickets entirely. Use the remaining valid tickets to determine which field is which. + +Using the valid ranges for each field, determine what order the fields appear on the tickets. The order is consistent between all tickets: if seat is the third field, it is the third field on every ticket, including your ticket. + +For example, suppose you have the following notes: + +
+class: 0-1 or 4-19
+row: 0-5 or 8-19
+seat: 0-13 or 16-19
+
+your ticket:
+11,12,13
+
+nearby tickets:
+3,9,18
+15,1,5
+5,14,9
+
+
+ +Based on the nearby tickets in the above example, the first position must be row, the second position must be class, and the third position must be seat; you can conclude that in your ticket, class is 12, row is 11, and seat is 13. + +Once you work out which field is which, look for the six fields on your ticket that start with the word departure. What do you get if you multiply those six values together? + + diff --git a/2020/Day16/input.in b/2020/Day16/input.in index a63ca86a8..9f7314d01 100644 Binary files a/2020/Day16/input.in and b/2020/Day16/input.in differ diff --git a/2020/Day17/README.md b/2020/Day17/README.md index 77aab7398..f477ce111 100644 --- a/2020/Day17/README.md +++ b/2020/Day17/README.md @@ -1,6 +1,408 @@ +original source: [https://adventofcode.com/2020/day/17](https://adventofcode.com/2020/day/17) ## --- Day 17: Conway Cubes --- As your flight slowly drifts through the sky, the Elves at the Mythical Information Bureau at the North Pole contact you. They'd like some help debugging a malfunctioning experimental energy source aboard one of their super-secret imaging satellites. The experimental energy source is based on cutting-edge technology: a set of Conway Cubes contained in a pocket dimension! When you hear it's having problems, you can't help but agree to take a look. -Read the [full puzzle](https://adventofcode.com/2020/day/17). \ No newline at end of file +The pocket dimension contains an infinite 3-dimensional grid. At every integer 3-dimensional coordinate (x,y,z), there exists a single cube which is either active or inactive. + +In the initial state of the pocket dimension, almost all cubes start inactive. The only exception to this is a small flat region of cubes (your puzzle input); the cubes in this region start in the specified active (#) or inactive (.) state. + +The energy source then proceeds to boot up by executing six cycles. + +Each cube only ever considers its neighbors: any of the 26 other cubes where any of their coordinates differ by at most 1. For example, given the cube at x=1,y=2,z=3, its neighbors include the cube at x=2,y=2,z=2, the cube at x=0,y=2,z=3, and so on. + +During a cycle, all cubes simultaneously change their state according to the following rules: + + + - If a cube is active and exactly 2 or 3 of its neighbors are also active, the cube remains active. Otherwise, the cube becomes inactive. + - If a cube is inactive but exactly 3 of its neighbors are active, the cube becomes active. Otherwise, the cube remains inactive. + +The engineers responsible for this experimental energy source would like you to simulate the pocket dimension and determine what the configuration of cubes should be at the end of the six-cycle boot process. + +For example, consider the following initial state: + +
+.#.
+..#
+###
+
+
+ +Even though the pocket dimension is 3-dimensional, this initial state represents a small 2-dimensional slice of it. (In particular, this initial state defines a 3x3x1 region of the 3-dimensional space.) + +Simulating a few cycles from this initial state produces the following configurations, where the result of each cycle is shown layer-by-layer at each given z coordinate (and the frame of view follows the active cells in each cycle): + +
+Before any cycles:
+
+z=0
+.#.
+..#
+###
+
+
+After 1 cycle:
+
+z=-1
+#..
+..#
+.#.
+
+z=0
+#.#
+.##
+.#.
+
+z=1
+#..
+..#
+.#.
+
+
+After 2 cycles:
+
+z=-2
+.....
+.....
+..#..
+.....
+.....
+
+z=-1
+..#..
+.#..#
+....#
+.#...
+.....
+
+z=0
+##...
+##...
+#....
+....#
+.###.
+
+z=1
+..#..
+.#..#
+....#
+.#...
+.....
+
+z=2
+.....
+.....
+..#..
+.....
+.....
+
+
+After 3 cycles:
+
+z=-2
+.......
+.......
+..##...
+..###..
+.......
+.......
+.......
+
+z=-1
+..#....
+...#...
+#......
+.....##
+.#...#.
+..#.#..
+...#...
+
+z=0
+...#...
+.......
+#......
+.......
+.....##
+.##.#..
+...#...
+
+z=1
+..#....
+...#...
+#......
+.....##
+.#...#.
+..#.#..
+...#...
+
+z=2
+.......
+.......
+..##...
+..###..
+.......
+.......
+.......
+
+
+ +After the full six-cycle boot process completes, 112 cubes are left in the active state. + +Starting with your given initial configuration, simulate six cycles. How many cubes are left in the active state after the sixth cycle? + + +## --- Part Two --- +For some reason, your simulated results don't match what the experimental energy source engineers expected. Apparently, the pocket dimension actually has four spatial dimensions, not three. + +The pocket dimension contains an infinite 4-dimensional grid. At every integer 4-dimensional coordinate (x,y,z,w), there exists a single cube (really, a hypercube) which is still either active or inactive. + +Each cube only ever considers its neighbors: any of the 80 other cubes where any of their coordinates differ by at most 1. For example, given the cube at x=1,y=2,z=3,w=4, its neighbors include the cube at x=2,y=2,z=3,w=3, the cube at x=0,y=2,z=3,w=4, and so on. + +The initial state of the pocket dimension still consists of a small flat region of cubes. Furthermore, the same rules for cycle updating still apply: during each cycle, consider the number of active neighbors of each cube. + +For example, consider the same initial state as in the example above. Even though the pocket dimension is 4-dimensional, this initial state represents a small 2-dimensional slice of it. (In particular, this initial state defines a 3x3x1x1 region of the 4-dimensional space.) + +Simulating a few cycles from this initial state produces the following configurations, where the result of each cycle is shown layer-by-layer at each given z and w coordinate: + +
+Before any cycles:
+
+z=0, w=0
+.#.
+..#
+###
+
+
+After 1 cycle:
+
+z=-1, w=-1
+#..
+..#
+.#.
+
+z=0, w=-1
+#..
+..#
+.#.
+
+z=1, w=-1
+#..
+..#
+.#.
+
+z=-1, w=0
+#..
+..#
+.#.
+
+z=0, w=0
+#.#
+.##
+.#.
+
+z=1, w=0
+#..
+..#
+.#.
+
+z=-1, w=1
+#..
+..#
+.#.
+
+z=0, w=1
+#..
+..#
+.#.
+
+z=1, w=1
+#..
+..#
+.#.
+
+
+After 2 cycles:
+
+z=-2, w=-2
+.....
+.....
+..#..
+.....
+.....
+
+z=-1, w=-2
+.....
+.....
+.....
+.....
+.....
+
+z=0, w=-2
+###..
+##.##
+#...#
+.#..#
+.###.
+
+z=1, w=-2
+.....
+.....
+.....
+.....
+.....
+
+z=2, w=-2
+.....
+.....
+..#..
+.....
+.....
+
+z=-2, w=-1
+.....
+.....
+.....
+.....
+.....
+
+z=-1, w=-1
+.....
+.....
+.....
+.....
+.....
+
+z=0, w=-1
+.....
+.....
+.....
+.....
+.....
+
+z=1, w=-1
+.....
+.....
+.....
+.....
+.....
+
+z=2, w=-1
+.....
+.....
+.....
+.....
+.....
+
+z=-2, w=0
+###..
+##.##
+#...#
+.#..#
+.###.
+
+z=-1, w=0
+.....
+.....
+.....
+.....
+.....
+
+z=0, w=0
+.....
+.....
+.....
+.....
+.....
+
+z=1, w=0
+.....
+.....
+.....
+.....
+.....
+
+z=2, w=0
+###..
+##.##
+#...#
+.#..#
+.###.
+
+z=-2, w=1
+.....
+.....
+.....
+.....
+.....
+
+z=-1, w=1
+.....
+.....
+.....
+.....
+.....
+
+z=0, w=1
+.....
+.....
+.....
+.....
+.....
+
+z=1, w=1
+.....
+.....
+.....
+.....
+.....
+
+z=2, w=1
+.....
+.....
+.....
+.....
+.....
+
+z=-2, w=2
+.....
+.....
+..#..
+.....
+.....
+
+z=-1, w=2
+.....
+.....
+.....
+.....
+.....
+
+z=0, w=2
+###..
+##.##
+#...#
+.#..#
+.###.
+
+z=1, w=2
+.....
+.....
+.....
+.....
+.....
+
+z=2, w=2
+.....
+.....
+..#..
+.....
+.....
+
+
+ +After the full six-cycle boot process completes, 848 cubes are left in the active state. + +Starting with your given initial configuration, simulate six cycles in a 4-dimensional space. How many cubes are left in the active state after the sixth cycle? + + diff --git a/2020/Day17/input.in b/2020/Day17/input.in index 0ffd26405..d8b9ae9ff 100644 Binary files a/2020/Day17/input.in and b/2020/Day17/input.in differ diff --git a/2020/Day18/README.md b/2020/Day18/README.md index f6419792d..93c1fcc4e 100644 --- a/2020/Day18/README.md +++ b/2020/Day18/README.md @@ -1,6 +1,74 @@ +original source: [https://adventofcode.com/2020/day/18](https://adventofcode.com/2020/day/18) ## --- Day 18: Operation Order --- As you look out the window and notice a heavily-forested continent slowly appear over the horizon, you are interrupted by the child sitting next to you. They're curious if you could help them with their math homework. Unfortunately, it seems like this "math" [follows different rules](https://www.youtube.com/watch?v=3QtRK7Y2pPU&t=15) than you remember. -Read the [full puzzle](https://adventofcode.com/2020/day/18). \ No newline at end of file +The homework (your puzzle input) consists of a series of expressions that consist of addition (+), multiplication (*), and parentheses ((...)). Just like normal math, parentheses indicate that the expression inside must be evaluated before it can be used by the surrounding expression. Addition still finds the sum of the numbers on both sides of the operator, and multiplication still finds the product. + +However, the rules of operator precedence have changed. Rather than evaluating multiplication before addition, the operators have the same precedence, and are evaluated left-to-right regardless of the order in which they appear. + +For example, the steps to evaluate the expression 1 + 2 * 3 + 4 * 5 + 6 are as follows: + +
+1 + 2 * 3 + 4 * 5 + 6
+  3   * 3 + 4 * 5 + 6
+      9   + 4 * 5 + 6
+         13   * 5 + 6
+             65   + 6
+                 71
+
+
+ +Parentheses can override this order; for example, here is what happens if parentheses are added to form 1 + (2 * 3) + (4 * (5 + 6)): + +
+1 + (2 * 3) + (4 * (5 + 6))
+1 +    6    + (4 * (5 + 6))
+     7      + (4 * (5 + 6))
+     7      + (4 *   11   )
+     7      +     44
+            51
+
+
+ +Here are a few more examples: + + + - 2 * 3 + (4 * 5) becomes 26. + - 5 + (8 * 3 + 9 + 3 * 4 * 3) becomes 437. + - 5 * 9 * (7 * 3 * 3 + 9 * 3 + (8 + 6 * 4)) becomes 12240. + - ((2 + 4 * 9) * (6 + 9 * 8 + 6) + 6) + 2 + 4 * 2 becomes 13632. + +Before you can help with the homework, you need to understand it yourself. Evaluate the expression on each line of the homework; what is the sum of the resulting values? + + +## --- Part Two --- +You manage to answer the child's questions and they finish part 1 of their homework, but get stuck when they reach the next section: advanced math. + +Now, addition and multiplication have different precedence levels, but they're not the ones you're familiar with. Instead, addition is evaluated before multiplication. + +For example, the steps to evaluate the expression 1 + 2 * 3 + 4 * 5 + 6 are now as follows: + +
+1 + 2 * 3 + 4 * 5 + 6
+  3   * 3 + 4 * 5 + 6
+  3   *   7   * 5 + 6
+  3   *   7   *  11
+     21       *  11
+         231
+
+
+ +Here are the other examples from above: + + + - 1 + (2 * 3) + (4 * (5 + 6)) still becomes 51. + - 2 * 3 + (4 * 5) becomes 46. + - 5 + (8 * 3 + 9 + 3 * 4 * 3) becomes 1445. + - 5 * 9 * (7 * 3 * 3 + 9 * 3 + (8 + 6 * 4)) becomes 669060. + - ((2 + 4 * 9) * (6 + 9 * 8 + 6) + 6) + 2 + 4 * 2 becomes 23340. + +What do you get if you add up the results of evaluating the homework problems using these new rules? + + diff --git a/2020/Day18/input.in b/2020/Day18/input.in index 13bc4762b..3b04a70a4 100644 Binary files a/2020/Day18/input.in and b/2020/Day18/input.in differ diff --git a/2020/Day19/README.md b/2020/Day19/README.md index 84fc34e56..107943e97 100644 --- a/2020/Day19/README.md +++ b/2020/Day19/README.md @@ -1,6 +1,154 @@ +original source: [https://adventofcode.com/2020/day/19](https://adventofcode.com/2020/day/19) ## --- Day 19: Monster Messages --- You land in an airport surrounded by dense forest. As you walk to your high-speed train, the Elves at the Mythical Information Bureau contact you again. They think their satellite has collected an image of a sea monster! Unfortunately, the connection to the satellite is having problems, and many of the messages sent back from the satellite have been corrupted. They sent you a list of the rules valid messages should obey and a list of received messages they've collected so far (your puzzle input). -Read the [full puzzle](https://adventofcode.com/2020/day/19). \ No newline at end of file +The rules for valid messages (the top part of your puzzle input) are numbered and build upon each other. For example: + +
+0: 1 2
+1: "a"
+2: 1 3 | 3 1
+3: "b"
+
+
+ +Some rules, like 3: "b", simply match a single character (in this case, b). + +The remaining rules list the sub-rules that must be followed; for example, the rule 0: 1 2 means that to match rule 0, the text being checked must match rule 1, and the text after the part that matched rule 1 must then match rule 2. + +Some of the rules have multiple lists of sub-rules separated by a pipe (|). This means that at least one list of sub-rules must match. (The ones that match might be different each time the rule is encountered.) For example, the rule 2: 1 3 | 3 1 means that to match rule 2, the text being checked must match rule 1 followed by rule 3 or it must match rule 3 followed by rule 1. + +Fortunately, there are no loops in the rules, so the list of possible matches will be finite. Since rule 1 matches a and rule 3 matches b, rule 2 matches either ab or ba. Therefore, rule 0 matches aab or aba. + +Here's a more interesting example: + +
+0: 4 1 5
+1: 2 3 | 3 2
+2: 4 4 | 5 5
+3: 4 5 | 5 4
+4: "a"
+5: "b"
+
+
+ +Here, because rule 4 matches a and rule 5 matches b, rule 2 matches two letters that are the same (aa or bb), and rule 3 matches two letters that are different (ab or ba). + +Since rule 1 matches rules 2 and 3 once each in either order, it must match two pairs of letters, one pair with matching letters and one pair with different letters. This leaves eight possibilities: aaab, aaba, bbab, bbba, abaa, abbb, baaa, or babb. + +Rule 0, therefore, matches a (rule 4), then any of the eight options from rule 1, then b (rule 5): aaaabb, aaabab, abbabb, abbbab, aabaab, aabbbb, abaaab, or ababbb. + +The received messages (the bottom part of your puzzle input) need to be checked against the rules so you can determine which are valid and which are corrupted. Including the rules and the messages together, this might look like: + +
+0: 4 1 5
+1: 2 3 | 3 2
+2: 4 4 | 5 5
+3: 4 5 | 5 4
+4: "a"
+5: "b"
+
+ababbb
+bababa
+abbbab
+aaabbb
+aaaabbb
+
+
+ +Your goal is to determine the number of messages that completely match rule 0. In the above example, ababbb and abbbab match, but bababa, aaabbb, and aaaabbb do not, producing the answer 2. The whole message must match all of rule 0; there can't be extra unmatched characters in the message. (For example, aaaabbb might appear to match rule 0 above, but it has an extra unmatched b on the end.) + +How many messages completely match rule 0? + + +## --- Part Two --- +As you look over the list of messages, you realize your matching rules aren't quite right. To fix them, completely replace rules 8: 42 and 11: 42 31 with the following: + +
+8: 42 | 42 8
+11: 42 31 | 42 11 31
+
+
+ +This small change has a big impact: now, the rules do contain loops, and the list of messages they could hypothetically match is infinite. You'll need to determine how these changes affect which messages are valid. + +Fortunately, many of the rules are unaffected by this change; it might help to start by looking at which rules always match the same set of values and how those rules (especially rules 42 and 31) are used by the new versions of rules 8 and 11. + +(Remember, you only need to handle the rules you have; building a solution that could handle any hypothetical combination of rules would be [significantly more difficult](https://en.wikipedia.org/wiki/Formal_grammar).) + +For example: + +
+42: 9 14 | 10 1
+9: 14 27 | 1 26
+10: 23 14 | 28 1
+1: "a"
+11: 42 31
+5: 1 14 | 15 1
+19: 14 1 | 14 14
+12: 24 14 | 19 1
+16: 15 1 | 14 14
+31: 14 17 | 1 13
+6: 14 14 | 1 14
+2: 1 24 | 14 4
+0: 8 11
+13: 14 3 | 1 12
+15: 1 | 14
+17: 14 2 | 1 7
+23: 25 1 | 22 14
+28: 16 1
+4: 1 1
+20: 14 14 | 1 15
+3: 5 14 | 16 1
+27: 1 6 | 14 18
+14: "b"
+21: 14 1 | 1 14
+25: 1 1 | 1 14
+22: 14 14
+8: 42
+26: 14 22 | 1 20
+18: 15 15
+7: 14 5 | 1 21
+24: 14 1
+
+abbbbbabbbaaaababbaabbbbabababbbabbbbbbabaaaa
+bbabbbbaabaabba
+babbbbaabbbbbabbbbbbaabaaabaaa
+aaabbbbbbaaaabaababaabababbabaaabbababababaaa
+bbbbbbbaaaabbbbaaabbabaaa
+bbbababbbbaaaaaaaabbababaaababaabab
+ababaaaaaabaaab
+ababaaaaabbbaba
+baabbaaaabbaaaababbaababb
+abbbbabbbbaaaababbbbbbaaaababb
+aaaaabbaabaaaaababaa
+aaaabbaaaabbaaa
+aaaabbaabbaaaaaaabbbabbbaaabbaabaaa
+babaaabbbaaabaababbaabababaaab
+aabbbbbaabbbaaaaaabbbbbababaaaaabbaaabba
+
+
+ +Without updating rules 8 and 11, these rules only match three messages: bbabbbbaabaabba, ababaaaaaabaaab, and ababaaaaabbbaba. + +However, after updating rules 8 and 11, a total of 12 messages match: + + + - bbabbbbaabaabba + - babbbbaabbbbbabbbbbbaabaaabaaa + - aaabbbbbbaaaabaababaabababbabaaabbababababaaa + - bbbbbbbaaaabbbbaaabbabaaa + - bbbababbbbaaaaaaaabbababaaababaabab + - ababaaaaaabaaab + - ababaaaaabbbaba + - baabbaaaabbaaaababbaababb + - abbbbabbbbaaaababbbbbbaaaababb + - aaaaabbaabaaaaababaa + - aaaabbaabbaaaaaaabbbabbbaaabbaabaaa + - aabbbbbaabbbaaaaaabbbbbababaaaaabbaaabba + +After updating rules 8 and 11, how many messages completely match rule 0? + + diff --git a/2020/Day19/input.in b/2020/Day19/input.in index ee4e83cb5..c41dfe27c 100644 Binary files a/2020/Day19/input.in and b/2020/Day19/input.in differ diff --git a/2020/Day20/README.md b/2020/Day20/README.md index 61638dbef..cc61a4c1f 100644 --- a/2020/Day20/README.md +++ b/2020/Day20/README.md @@ -1,6 +1,288 @@ +original source: [https://adventofcode.com/2020/day/20](https://adventofcode.com/2020/day/20) ## --- Day 20: Jurassic Jigsaw --- The high-speed train leaves the forest and quickly carries you south. You can even see a desert in the distance! Since you have some spare time, you might as well see if there was anything interesting in the image the Mythical Information Bureau satellite captured. After decoding the satellite messages, you discover that the data actually contains many small images created by the satellite's camera array. The camera array consists of many cameras; rather than produce a single square image, they produce many smaller square image tiles that need to be reassembled back into a single image. -Read the [full puzzle](https://adventofcode.com/2020/day/20). \ No newline at end of file +Each camera in the camera array returns a single monochrome image tile with a random unique ID number. The tiles (your puzzle input) arrived in a random order. + +Worse yet, the camera array appears to be malfunctioning: each image tile has been rotated and flipped to a random orientation. Your first task is to reassemble the original image by orienting the tiles so they fit together. + +To show how the tiles should be reassembled, each tile's image data includes a border that should line up exactly with its adjacent tiles. All tiles have this border, and the border lines up exactly when the tiles are both oriented correctly. Tiles at the edge of the image also have this border, but the outermost edges won't line up with any other tiles. + +For example, suppose you have the following nine tiles: + +
+Tile 2311:
+..##.#..#.
+##..#.....
+#...##..#.
+####.#...#
+##.##.###.
+##...#.###
+.#.#.#..##
+..#....#..
+###...#.#.
+..###..###
+
+Tile 1951:
+#.##...##.
+#.####...#
+.....#..##
+#...######
+.##.#....#
+.###.#####
+###.##.##.
+.###....#.
+..#.#..#.#
+#...##.#..
+
+Tile 1171:
+####...##.
+#..##.#..#
+##.#..#.#.
+.###.####.
+..###.####
+.##....##.
+.#...####.
+#.##.####.
+####..#...
+.....##...
+
+Tile 1427:
+###.##.#..
+.#..#.##..
+.#.##.#..#
+#.#.#.##.#
+....#...##
+...##..##.
+...#.#####
+.#.####.#.
+..#..###.#
+..##.#..#.
+
+Tile 1489:
+##.#.#....
+..##...#..
+.##..##...
+..#...#...
+#####...#.
+#..#.#.#.#
+...#.#.#..
+##.#...##.
+..##.##.##
+###.##.#..
+
+Tile 2473:
+#....####.
+#..#.##...
+#.##..#...
+######.#.#
+.#...#.#.#
+.#########
+.###.#..#.
+########.#
+##...##.#.
+..###.#.#.
+
+Tile 2971:
+..#.#....#
+#...###...
+#.#.###...
+##.##..#..
+.#####..##
+.#..####.#
+#..#.#..#.
+..####.###
+..#.#.###.
+...#.#.#.#
+
+Tile 2729:
+...#.#.#.#
+####.#....
+..#.#.....
+....#..#.#
+.##..##.#.
+.#.####...
+####.#.#..
+##.####...
+##..#.##..
+#.##...##.
+
+Tile 3079:
+#.#.#####.
+.#..######
+..#.......
+######....
+####.#..#.
+.#...#.##.
+#.#####.##
+..#.###...
+..#.......
+..#.###...
+
+
+ +By rotating, flipping, and rearranging them, you can find a square arrangement that causes all adjacent borders to line up: + +
+#...##.#.. ..###..### #.#.#####.
+..#.#..#.# ###...#.#. .#..######
+.###....#. ..#....#.. ..#.......
+###.##.##. .#.#.#..## ######....
+.###.##### ##...#.### ####.#..#.
+.##.#....# ##.##.###. .#...#.##.
+#...###### ####.#...# #.#####.##
+.....#..## #...##..#. ..#.###...
+#.####...# ##..#..... ..#.......
+#.##...##. ..##.#..#. ..#.###...
+
+#.##...##. ..##.#..#. ..#.###...
+##..#.##.. ..#..###.# ##.##....#
+##.####... .#.####.#. ..#.###..#
+####.#.#.. ...#.##### ###.#..###
+.#.####... ...##..##. .######.##
+.##..##.#. ....#...## #.#.#.#...
+....#..#.# #.#.#.##.# #.###.###.
+..#.#..... .#.##.#..# #.###.##..
+####.#.... .#..#.##.. .######...
+...#.#.#.# ###.##.#.. .##...####
+
+...#.#.#.# ###.##.#.. .##...####
+..#.#.###. ..##.##.## #..#.##..#
+..####.### ##.#...##. .#.#..#.##
+#..#.#..#. ...#.#.#.. .####.###.
+.#..####.# #..#.#.#.# ####.###..
+.#####..## #####...#. .##....##.
+##.##..#.. ..#...#... .####...#.
+#.#.###... .##..##... .####.##.#
+#...###... ..##...#.. ...#..####
+..#.#....# ##.#.#.... ...##.....
+
+
+ +For reference, the IDs of the above tiles are: + +
+1951    2311    3079
+2729    1427    2473
+2971    1489    1171
+
+
+ +To check that you've assembled the image correctly, multiply the IDs of the four corner tiles together. If you do this with the assembled tiles from the example above, you get 1951 * 3079 * 2971 * 1171 = 20899048083289. + +Assemble the tiles into an image. What do you get if you multiply together the IDs of the four corner tiles? + + +## --- Part Two --- +Now, you're ready to check the image for sea monsters. + +The borders of each tile are not part of the actual image; start by removing them. + +In the example above, the tiles become: + +
+.#.#..#. ##...#.# #..#####
+###....# .#....#. .#......
+##.##.## #.#.#..# #####...
+###.#### #...#.## ###.#..#
+##.#.... #.##.### #...#.##
+...##### ###.#... .#####.#
+....#..# ...##..# .#.###..
+.####... #..#.... .#......
+
+#..#.##. .#..###. #.##....
+#.####.. #.####.# .#.###..
+###.#.#. ..#.#### ##.#..##
+#.####.. ..##..## ######.#
+##..##.# ...#...# .#.#.#..
+...#..#. .#.#.##. .###.###
+.#.#.... #.##.#.. .###.##.
+###.#... #..#.##. ######..
+
+.#.#.### .##.##.# ..#.##..
+.####.## #.#...## #.#..#.#
+..#.#..# ..#.#.#. ####.###
+#..####. ..#.#.#. ###.###.
+#####..# ####...# ##....##
+#.##..#. .#...#.. ####...#
+.#.###.. ##..##.. ####.##.
+...###.. .##...#. ..#..###
+
+
+ +Remove the gaps to form the actual image: + +
+.#.#..#.##...#.##..#####
+###....#.#....#..#......
+##.##.###.#.#..######...
+###.#####...#.#####.#..#
+##.#....#.##.####...#.##
+...########.#....#####.#
+....#..#...##..#.#.###..
+.####...#..#.....#......
+#..#.##..#..###.#.##....
+#.####..#.####.#.#.###..
+###.#.#...#.######.#..##
+#.####....##..########.#
+##..##.#...#...#.#.#.#..
+...#..#..#.#.##..###.###
+.#.#....#.##.#...###.##.
+###.#...#..#.##.######..
+.#.#.###.##.##.#..#.##..
+.####.###.#...###.#..#.#
+..#.#..#..#.#.#.####.###
+#..####...#.#.#.###.###.
+#####..#####...###....##
+#.##..#..#...#..####...#
+.#.###..##..##..####.##.
+...###...##...#...#..###
+
+
+ +Now, you're ready to search for sea monsters! Because your image is monochrome, a sea monster will look like this: + +
+                  # 
+#    ##    ##    ###
+ #  #  #  #  #  #   
+
+
+ +When looking for this pattern in the image, the spaces can be anything; only the # need to match. Also, you might need to rotate or flip your image before it's oriented correctly to find sea monsters. In the above image, after flipping and rotating it to the appropriate orientation, there are two sea monsters (marked with O): + +
+.####...#####..#...###..
+#####..#..#.#.####..#.#.
+.#.#...#.###...#.##.O#..
+#.O.##.OO#.#.OO.##.OOO##
+..#O.#O#.O##O..O.#O##.##
+...#.#..##.##...#..#..##
+#.##.#..#.#..#..##.#.#..
+.###.##.....#...###.#...
+#.####.#.#....##.#..#.#.
+##...#..#....#..#...####
+..#.##...###..#.#####..#
+....#.##.#.#####....#...
+..##.##.###.....#.##..#.
+#...#...###..####....##.
+.#.##...#.##.#.#.###...#
+#.###.#..####...##..#...
+#.###...#.##...#.##O###.
+.O##.#OO.###OO##..OOO##.
+..O#.O..O..O.#O##O##.###
+#.#..##.########..#..##.
+#.#####..#.#...##..#....
+#....##..#.#########..##
+#...#.....#..##...###.##
+#..###....##.#...##.##.#
+
+
+ +Determine how rough the waters are in the sea monsters' habitat by counting the number of # that are not part of a sea monster. In the above example, the habitat's water roughness is 273. + +How many # are not part of a sea monster? + + diff --git a/2020/Day20/input.in b/2020/Day20/input.in index 97e975f2f..6b475f8bd 100644 Binary files a/2020/Day20/input.in and b/2020/Day20/input.in differ diff --git a/2020/Day21/README.md b/2020/Day21/README.md index 5eda168ce..a8fac4c7d 100644 --- a/2020/Day21/README.md +++ b/2020/Day21/README.md @@ -1,6 +1,42 @@ +original source: [https://adventofcode.com/2020/day/21](https://adventofcode.com/2020/day/21) ## --- Day 21: Allergen Assessment --- You reach the train's last stop and the closest you can get to your vacation island without getting wet. There aren't even any boats here, but nothing can stop you now: you build a raft. You just need a few days' worth of food for your journey. You don't speak the local language, so you can't read any ingredients lists. However, sometimes, allergens are listed in a language you do understand. You should be able to use this information to determine which ingredient contains which allergen and work out which foods are safe to take with you on your trip. -Read the [full puzzle](https://adventofcode.com/2020/day/21). \ No newline at end of file +You start by compiling a list of foods (your puzzle input), one food per line. Each line includes that food's ingredients list followed by some or all of the allergens the food contains. + +Each allergen is found in exactly one ingredient. Each ingredient contains zero or one allergen. Allergens aren't always marked; when they're listed (as in (contains nuts, shellfish) after an ingredients list), the ingredient that contains each listed allergen will be somewhere in the corresponding ingredients list. However, even if an allergen isn't listed, the ingredient that contains that allergen could still be present: maybe they forgot to label it, or maybe it was labeled in a language you don't know. + +For example, consider the following list of foods: + +
+mxmxvkd kfcds sqjhc nhms (contains dairy, fish)
+trh fvjkl sbzzf mxmxvkd (contains dairy)
+sqjhc fvjkl (contains soy)
+sqjhc mxmxvkd sbzzf (contains fish)
+
+
+ +The first food in the list has four ingredients (written in a language you don't understand): mxmxvkd, kfcds, sqjhc, and nhms. While the food might contain other allergens, a few allergens the food definitely contains are listed afterward: dairy and fish. + +The first step is to determine which ingredients can't possibly contain any of the allergens in any food in your list. In the above example, none of the ingredients kfcds, nhms, sbzzf, or trh can contain an allergen. Counting the number of times any of these ingredients appear in any ingredients list produces 5: they all appear once each except sbzzf, which appears twice. + +Determine which ingredients cannot possibly contain any of the allergens in your list. How many times do any of those ingredients appear? + + +## --- Part Two --- +Now that you've isolated the inert ingredients, you should have enough information to figure out which ingredient contains which allergen. + +In the above example: + + + - mxmxvkd contains dairy. + - sqjhc contains fish. + - fvjkl contains soy. + +Arrange the ingredients alphabetically by their allergen and separate them by commas to produce your canonical dangerous ingredient list. (There should not be any spaces in your canonical dangerous ingredient list.) In the above example, this would be mxmxvkd,sqjhc,fvjkl. + +Time to stock your raft with supplies. What is your canonical dangerous ingredient list? + + diff --git a/2020/Day21/input.in b/2020/Day21/input.in index 069732cb8..9301dc45a 100644 Binary files a/2020/Day21/input.in and b/2020/Day21/input.in differ diff --git a/2020/Day22/README.md b/2020/Day22/README.md index 07b3f0bf0..0744a25aa 100644 --- a/2020/Day22/README.md +++ b/2020/Day22/README.md @@ -1,6 +1,395 @@ +original source: [https://adventofcode.com/2020/day/22](https://adventofcode.com/2020/day/22) ## --- Day 22: Crab Combat --- It only takes a few hours of sailing the ocean on a raft for boredom to sink in. Fortunately, you brought a small deck of [space cards](/2019/day/22)! You'd like to play a game of Combat, and there's even an opponent available: a small crab that climbed aboard your raft before you left. Fortunately, it doesn't take long to teach the crab the rules. -Read the [full puzzle](https://adventofcode.com/2020/day/22). \ No newline at end of file +Before the game starts, split the cards so each player has their own deck (your puzzle input). Then, the game consists of a series of rounds: both players draw their top card, and the player with the higher-valued card wins the round. The winner keeps both cards, placing them on the bottom of their own deck so that the winner's card is above the other card. If this causes a player to have all of the cards, they win, and the game ends. + +For example, consider the following starting decks: + +
+Player 1:
+9
+2
+6
+3
+1
+
+Player 2:
+5
+8
+4
+7
+10
+
+
+ +This arrangement means that player 1's deck contains 5 cards, with 9 on top and 1 on the bottom; player 2's deck also contains 5 cards, with 5 on top and 10 on the bottom. + +The first round begins with both players drawing the top card of their decks: 9 and 5. Player 1 has the higher card, so both cards move to the bottom of player 1's deck such that 9 is above 5. In total, it takes 29 rounds before a player has all of the cards: + +
+-- Round 1 --
+Player 1's deck: 9, 2, 6, 3, 1
+Player 2's deck: 5, 8, 4, 7, 10
+Player 1 plays: 9
+Player 2 plays: 5
+Player 1 wins the round!
+
+-- Round 2 --
+Player 1's deck: 2, 6, 3, 1, 9, 5
+Player 2's deck: 8, 4, 7, 10
+Player 1 plays: 2
+Player 2 plays: 8
+Player 2 wins the round!
+
+-- Round 3 --
+Player 1's deck: 6, 3, 1, 9, 5
+Player 2's deck: 4, 7, 10, 8, 2
+Player 1 plays: 6
+Player 2 plays: 4
+Player 1 wins the round!
+
+-- Round 4 --
+Player 1's deck: 3, 1, 9, 5, 6, 4
+Player 2's deck: 7, 10, 8, 2
+Player 1 plays: 3
+Player 2 plays: 7
+Player 2 wins the round!
+
+-- Round 5 --
+Player 1's deck: 1, 9, 5, 6, 4
+Player 2's deck: 10, 8, 2, 7, 3
+Player 1 plays: 1
+Player 2 plays: 10
+Player 2 wins the round!
+
+...several more rounds pass...
+
+-- Round 27 --
+Player 1's deck: 5, 4, 1
+Player 2's deck: 8, 9, 7, 3, 2, 10, 6
+Player 1 plays: 5
+Player 2 plays: 8
+Player 2 wins the round!
+
+-- Round 28 --
+Player 1's deck: 4, 1
+Player 2's deck: 9, 7, 3, 2, 10, 6, 8, 5
+Player 1 plays: 4
+Player 2 plays: 9
+Player 2 wins the round!
+
+-- Round 29 --
+Player 1's deck: 1
+Player 2's deck: 7, 3, 2, 10, 6, 8, 5, 9, 4
+Player 1 plays: 1
+Player 2 plays: 7
+Player 2 wins the round!
+
+
+== Post-game results ==
+Player 1's deck: 
+Player 2's deck: 3, 2, 10, 6, 8, 5, 9, 4, 7, 1
+
+
+ +Once the game ends, you can calculate the winning player's score. The bottom card in their deck is worth the value of the card multiplied by 1, the second-from-the-bottom card is worth the value of the card multiplied by 2, and so on. With 10 cards, the top card is worth the value on the card multiplied by 10. In this example, the winning player's score is: + +
+   3 * 10
++  2 *  9
++ 10 *  8
++  6 *  7
++  8 *  6
++  5 *  5
++  9 *  4
++  4 *  3
++  7 *  2
++  1 *  1
+= 306
+
+
+ +So, once the game ends, the winning player's score is 306. + +Play the small crab in a game of Combat using the two decks you just dealt. What is the winning player's score? + + +## --- Part Two --- +You lost to the small crab! Fortunately, crabs aren't very good at recursion. To defend your honor as a Raft Captain, you challenge the small crab to a game of Recursive Combat. + +Recursive Combat still starts by splitting the cards into two decks (you offer to play with the same starting decks as before - it's only fair). Then, the game consists of a series of rounds with a few changes: + + + - Before either player deals a card, if there was a previous round in this game that had exactly the same cards in the same order in the same players' decks, the game instantly ends in a win for player 1. Previous rounds from other games are not considered. (This prevents infinite games of Recursive Combat, which everyone agrees is a bad idea.) + - Otherwise, this round's cards must be in a new configuration; the players begin the round by each drawing the top card of their deck as normal. + - If both players have at least as many cards remaining in their deck as the value of the card they just drew, the winner of the round is determined by playing a new game of Recursive Combat (see below). + - Otherwise, at least one player must not have enough cards left in their deck to recurse; the winner of the round is the player with the higher-value card. + +As in regular Combat, the winner of the round (even if they won the round by winning a sub-game) takes the two cards dealt at the beginning of the round and places them on the bottom of their own deck (again so that the winner's card is above the other card). Note that the winner's card might be the lower-valued of the two cards if they won the round due to winning a sub-game. If collecting cards by winning the round causes a player to have all of the cards, they win, and the game ends. + +Here is an example of a small game that would loop forever without the infinite game prevention rule: + +
+Player 1:
+43
+19
+
+Player 2:
+2
+29
+14
+
+
+ +During a round of Recursive Combat, if both players have at least as many cards in their own decks as the number on the card they just dealt, the winner of the round is determined by recursing into a sub-game of Recursive Combat. (For example, if player 1 draws the 3 card, and player 2 draws the 7 card, this would occur if player 1 has at least 3 cards left and player 2 has at least 7 cards left, not counting the 3 and 7 cards that were drawn.) + +To play a sub-game of Recursive Combat, each player creates a new deck by making a copy of the next cards in their deck (the quantity of cards copied is equal to the number on the card they drew to trigger the sub-game). During this sub-game, the game that triggered it is on hold and completely unaffected; no cards are removed from players' decks to form the sub-game. (For example, if player 1 drew the 3 card, their deck in the sub-game would be copies of the next three cards in their deck.) + +Here is a complete example of gameplay, where Game 1 is the primary game of Recursive Combat: + +
+=== Game 1 ===
+
+-- Round 1 (Game 1) --
+Player 1's deck: 9, 2, 6, 3, 1
+Player 2's deck: 5, 8, 4, 7, 10
+Player 1 plays: 9
+Player 2 plays: 5
+Player 1 wins round 1 of game 1!
+
+-- Round 2 (Game 1) --
+Player 1's deck: 2, 6, 3, 1, 9, 5
+Player 2's deck: 8, 4, 7, 10
+Player 1 plays: 2
+Player 2 plays: 8
+Player 2 wins round 2 of game 1!
+
+-- Round 3 (Game 1) --
+Player 1's deck: 6, 3, 1, 9, 5
+Player 2's deck: 4, 7, 10, 8, 2
+Player 1 plays: 6
+Player 2 plays: 4
+Player 1 wins round 3 of game 1!
+
+-- Round 4 (Game 1) --
+Player 1's deck: 3, 1, 9, 5, 6, 4
+Player 2's deck: 7, 10, 8, 2
+Player 1 plays: 3
+Player 2 plays: 7
+Player 2 wins round 4 of game 1!
+
+-- Round 5 (Game 1) --
+Player 1's deck: 1, 9, 5, 6, 4
+Player 2's deck: 10, 8, 2, 7, 3
+Player 1 plays: 1
+Player 2 plays: 10
+Player 2 wins round 5 of game 1!
+
+-- Round 6 (Game 1) --
+Player 1's deck: 9, 5, 6, 4
+Player 2's deck: 8, 2, 7, 3, 10, 1
+Player 1 plays: 9
+Player 2 plays: 8
+Player 1 wins round 6 of game 1!
+
+-- Round 7 (Game 1) --
+Player 1's deck: 5, 6, 4, 9, 8
+Player 2's deck: 2, 7, 3, 10, 1
+Player 1 plays: 5
+Player 2 plays: 2
+Player 1 wins round 7 of game 1!
+
+-- Round 8 (Game 1) --
+Player 1's deck: 6, 4, 9, 8, 5, 2
+Player 2's deck: 7, 3, 10, 1
+Player 1 plays: 6
+Player 2 plays: 7
+Player 2 wins round 8 of game 1!
+
+-- Round 9 (Game 1) --
+Player 1's deck: 4, 9, 8, 5, 2
+Player 2's deck: 3, 10, 1, 7, 6
+Player 1 plays: 4
+Player 2 plays: 3
+Playing a sub-game to determine the winner...
+
+=== Game 2 ===
+
+-- Round 1 (Game 2) --
+Player 1's deck: 9, 8, 5, 2
+Player 2's deck: 10, 1, 7
+Player 1 plays: 9
+Player 2 plays: 10
+Player 2 wins round 1 of game 2!
+
+-- Round 2 (Game 2) --
+Player 1's deck: 8, 5, 2
+Player 2's deck: 1, 7, 10, 9
+Player 1 plays: 8
+Player 2 plays: 1
+Player 1 wins round 2 of game 2!
+
+-- Round 3 (Game 2) --
+Player 1's deck: 5, 2, 8, 1
+Player 2's deck: 7, 10, 9
+Player 1 plays: 5
+Player 2 plays: 7
+Player 2 wins round 3 of game 2!
+
+-- Round 4 (Game 2) --
+Player 1's deck: 2, 8, 1
+Player 2's deck: 10, 9, 7, 5
+Player 1 plays: 2
+Player 2 plays: 10
+Player 2 wins round 4 of game 2!
+
+-- Round 5 (Game 2) --
+Player 1's deck: 8, 1
+Player 2's deck: 9, 7, 5, 10, 2
+Player 1 plays: 8
+Player 2 plays: 9
+Player 2 wins round 5 of game 2!
+
+-- Round 6 (Game 2) --
+Player 1's deck: 1
+Player 2's deck: 7, 5, 10, 2, 9, 8
+Player 1 plays: 1
+Player 2 plays: 7
+Player 2 wins round 6 of game 2!
+The winner of game 2 is player 2!
+
+...anyway, back to game 1.
+Player 2 wins round 9 of game 1!
+
+-- Round 10 (Game 1) --
+Player 1's deck: 9, 8, 5, 2
+Player 2's deck: 10, 1, 7, 6, 3, 4
+Player 1 plays: 9
+Player 2 plays: 10
+Player 2 wins round 10 of game 1!
+
+-- Round 11 (Game 1) --
+Player 1's deck: 8, 5, 2
+Player 2's deck: 1, 7, 6, 3, 4, 10, 9
+Player 1 plays: 8
+Player 2 plays: 1
+Player 1 wins round 11 of game 1!
+
+-- Round 12 (Game 1) --
+Player 1's deck: 5, 2, 8, 1
+Player 2's deck: 7, 6, 3, 4, 10, 9
+Player 1 plays: 5
+Player 2 plays: 7
+Player 2 wins round 12 of game 1!
+
+-- Round 13 (Game 1) --
+Player 1's deck: 2, 8, 1
+Player 2's deck: 6, 3, 4, 10, 9, 7, 5
+Player 1 plays: 2
+Player 2 plays: 6
+Playing a sub-game to determine the winner...
+
+=== Game 3 ===
+
+-- Round 1 (Game 3) --
+Player 1's deck: 8, 1
+Player 2's deck: 3, 4, 10, 9, 7, 5
+Player 1 plays: 8
+Player 2 plays: 3
+Player 1 wins round 1 of game 3!
+
+-- Round 2 (Game 3) --
+Player 1's deck: 1, 8, 3
+Player 2's deck: 4, 10, 9, 7, 5
+Player 1 plays: 1
+Player 2 plays: 4
+Playing a sub-game to determine the winner...
+
+=== Game 4 ===
+
+-- Round 1 (Game 4) --
+Player 1's deck: 8
+Player 2's deck: 10, 9, 7, 5
+Player 1 plays: 8
+Player 2 plays: 10
+Player 2 wins round 1 of game 4!
+The winner of game 4 is player 2!
+
+...anyway, back to game 3.
+Player 2 wins round 2 of game 3!
+
+-- Round 3 (Game 3) --
+Player 1's deck: 8, 3
+Player 2's deck: 10, 9, 7, 5, 4, 1
+Player 1 plays: 8
+Player 2 plays: 10
+Player 2 wins round 3 of game 3!
+
+-- Round 4 (Game 3) --
+Player 1's deck: 3
+Player 2's deck: 9, 7, 5, 4, 1, 10, 8
+Player 1 plays: 3
+Player 2 plays: 9
+Player 2 wins round 4 of game 3!
+The winner of game 3 is player 2!
+
+...anyway, back to game 1.
+Player 2 wins round 13 of game 1!
+
+-- Round 14 (Game 1) --
+Player 1's deck: 8, 1
+Player 2's deck: 3, 4, 10, 9, 7, 5, 6, 2
+Player 1 plays: 8
+Player 2 plays: 3
+Player 1 wins round 14 of game 1!
+
+-- Round 15 (Game 1) --
+Player 1's deck: 1, 8, 3
+Player 2's deck: 4, 10, 9, 7, 5, 6, 2
+Player 1 plays: 1
+Player 2 plays: 4
+Playing a sub-game to determine the winner...
+
+=== Game 5 ===
+
+-- Round 1 (Game 5) --
+Player 1's deck: 8
+Player 2's deck: 10, 9, 7, 5
+Player 1 plays: 8
+Player 2 plays: 10
+Player 2 wins round 1 of game 5!
+The winner of game 5 is player 2!
+
+...anyway, back to game 1.
+Player 2 wins round 15 of game 1!
+
+-- Round 16 (Game 1) --
+Player 1's deck: 8, 3
+Player 2's deck: 10, 9, 7, 5, 6, 2, 4, 1
+Player 1 plays: 8
+Player 2 plays: 10
+Player 2 wins round 16 of game 1!
+
+-- Round 17 (Game 1) --
+Player 1's deck: 3
+Player 2's deck: 9, 7, 5, 6, 2, 4, 1, 10, 8
+Player 1 plays: 3
+Player 2 plays: 9
+Player 2 wins round 17 of game 1!
+The winner of game 1 is player 2!
+
+
+== Post-game results ==
+Player 1's deck: 
+Player 2's deck: 7, 5, 6, 2, 4, 1, 10, 8, 9, 3
+
+
+ +After the game, the winning player's score is calculated from the cards they have in their original deck using the same rules as regular Combat. In the above game, the winning player's score is 291. + +Defend your honor as Raft Captain by playing the small crab in a game of Recursive Combat using the same two decks as before. What is the winning player's score? + + diff --git a/2020/Day22/input.in b/2020/Day22/input.in index 831915344..d57117dd9 100644 Binary files a/2020/Day22/input.in and b/2020/Day22/input.in differ diff --git a/2020/Day23/README.md b/2020/Day23/README.md index 7f505c698..a58c288b9 100644 --- a/2020/Day23/README.md +++ b/2020/Day23/README.md @@ -1,6 +1,95 @@ +original source: [https://adventofcode.com/2020/day/23](https://adventofcode.com/2020/day/23) ## --- Day 23: Crab Cups --- The small crab challenges you to a game! The crab is going to mix up some cups, and you have to predict where they'll end up. The cups will be arranged in a circle and labeled clockwise (your puzzle input). For example, if your labeling were 32415, there would be five cups in the circle; going clockwise around the circle from the first cup, the cups would be labeled 3, 2, 4, 1, 5, and then back to 3 again. -Read the [full puzzle](https://adventofcode.com/2020/day/23). \ No newline at end of file +Before the crab starts, it will designate the first cup in your list as the current cup. The crab is then going to do 100 moves. + +Each move, the crab does the following actions: + + + - The crab picks up the three cups that are immediately clockwise of the current cup. They are removed from the circle; cup spacing is adjusted as necessary to maintain the circle. + - The crab selects a destination cup: the cup with a label equal to the current cup's label minus one. If this would select one of the cups that was just picked up, the crab will keep subtracting one until it finds a cup that wasn't just picked up. If at any point in this process the value goes below the lowest value on any cup's label, it wraps around to the highest value on any cup's label instead. + - The crab places the cups it just picked up so that they are immediately clockwise of the destination cup. They keep the same order as when they were picked up. + - The crab selects a new current cup: the cup which is immediately clockwise of the current cup. + +For example, suppose your cup labeling were 389125467. If the crab were to do merely 10 moves, the following changes would occur: + +
+-- move 1 --
+cups: (3) 8  9  1  2  5  4  6  7 
+pick up: 8, 9, 1
+destination: 2
+
+-- move 2 --
+cups:  3 (2) 8  9  1  5  4  6  7 
+pick up: 8, 9, 1
+destination: 7
+
+-- move 3 --
+cups:  3  2 (5) 4  6  7  8  9  1 
+pick up: 4, 6, 7
+destination: 3
+
+-- move 4 --
+cups:  7  2  5 (8) 9  1  3  4  6 
+pick up: 9, 1, 3
+destination: 7
+
+-- move 5 --
+cups:  3  2  5  8 (4) 6  7  9  1 
+pick up: 6, 7, 9
+destination: 3
+
+-- move 6 --
+cups:  9  2  5  8  4 (1) 3  6  7 
+pick up: 3, 6, 7
+destination: 9
+
+-- move 7 --
+cups:  7  2  5  8  4  1 (9) 3  6 
+pick up: 3, 6, 7
+destination: 8
+
+-- move 8 --
+cups:  8  3  6  7  4  1  9 (2) 5 
+pick up: 5, 8, 3
+destination: 1
+
+-- move 9 --
+cups:  7  4  1  5  8  3  9  2 (6)
+pick up: 7, 4, 1
+destination: 5
+
+-- move 10 --
+cups: (5) 7  4  1  8  3  9  2  6 
+pick up: 7, 4, 1
+destination: 3
+
+-- final --
+cups:  5 (8) 3  7  4  1  9  2  6 
+
+
+ +In the above example, the cups' values are the labels as they appear moving clockwise around the circle; the current cup is marked with ( ). + +After the crab is done, what order will the cups be in? Starting after the cup labeled 1, collect the other cups' labels clockwise into a single string with no extra characters; each number except 1 should appear exactly once. In the above example, after 10 moves, the cups clockwise from 1 are labeled 9, 2, 6, 5, and so on, producing 92658374. If the crab were to complete all 100 moves, the order after cup 1 would be 67384529. + +Using your labeling, simulate 100 moves. What are the labels on the cups after cup 1? + + +## --- Part Two --- +Due to what you can only assume is a mistranslation (you're not exactly fluent in Crab), you are quite surprised when the crab starts arranging many cups in a circle on your raft - one million (1000000) in total. + +Your labeling is still correct for the first few cups; after that, the remaining cups are just numbered in an increasing fashion starting from the number after the highest number in your list and proceeding one by one until one million is reached. (For example, if your labeling were 54321, the cups would be numbered 5, 4, 3, 2, 1, and then start counting up from 6 until one million is reached.) In this way, every number from one through one million is used exactly once. + +After discovering where you made the mistake in translating Crab Numbers, you realize the small crab isn't going to do merely 100 moves; the crab is going to do ten million (10000000) moves! + +The crab is going to hide your stars - one each - under the two cups that will end up immediately clockwise of cup 1. You can have them if you predict what the labels on those cups will be when the crab is finished. + +In the above example (389125467), this would be 934001 and then 159792; multiplying these together produces 149245887792. + +Determine which two cups will end up immediately clockwise of cup 1. What do you get if you multiply their labels together? + + diff --git a/2020/Day23/input.in b/2020/Day23/input.in index 32bcef7d0..f925d7678 100644 Binary files a/2020/Day23/input.in and b/2020/Day23/input.in differ diff --git a/2020/Day24/README.md b/2020/Day24/README.md index 614c04ba5..c8efdcf9c 100644 --- a/2020/Day24/README.md +++ b/2020/Day24/README.md @@ -1,6 +1,89 @@ +original source: [https://adventofcode.com/2020/day/24](https://adventofcode.com/2020/day/24) ## --- Day 24: Lobby Layout --- Your raft makes it to the tropical island; it turns out that the small crab was an excellent navigator. You make your way to the resort. As you enter the lobby, you discover a small problem: the floor is being renovated. You can't even reach the check-in desk until they've finished installing the new tile floor. -Read the [full puzzle](https://adventofcode.com/2020/day/24). \ No newline at end of file +The tiles are all hexagonal; they need to be arranged in a [hex grid](https://en.wikipedia.org/wiki/Hexagonal_tiling) with a very specific color pattern. Not in the mood to wait, you offer to help figure out the pattern. + +The tiles are all white on one side and black on the other. They start with the white side facing up. The lobby is large enough to fit whatever pattern might need to appear there. + +A member of the renovation crew gives you a list of the tiles that need to be flipped over (your puzzle input). Each line in the list identifies a single tile that needs to be flipped by giving a series of steps starting from a reference tile in the very center of the room. (Every line starts from the same reference tile.) + +Because the tiles are hexagonal, every tile has six neighbors: east, southeast, southwest, west, northwest, and northeast. These directions are given in your list, respectively, as e, se, sw, w, nw, and ne. A tile is identified by a series of these directions with no delimiters; for example, esenee identifies the tile you land on if you start at the reference tile and then move one tile east, one tile southeast, one tile northeast, and one tile east. + +Each time a tile is identified, it flips from white to black or from black to white. Tiles might be flipped more than once. For example, a line like esew flips a tile immediately adjacent to the reference tile, and a line like nwwswee flips the reference tile itself. + +Here is a larger example: + +
+sesenwnenenewseeswwswswwnenewsewsw
+neeenesenwnwwswnenewnwwsewnenwseswesw
+seswneswswsenwwnwse
+nwnwneseeswswnenewneswwnewseswneseene
+swweswneswnenwsewnwneneseenw
+eesenwseswswnenwswnwnwsewwnwsene
+sewnenenenesenwsewnenwwwse
+wenwwweseeeweswwwnwwe
+wsweesenenewnwwnwsenewsenwwsesesenwne
+neeswseenwwswnwswswnw
+nenwswwsewswnenenewsenwsenwnesesenew
+enewnwewneswsewnwswenweswnenwsenwsw
+sweneswneswneneenwnewenewwneswswnese
+swwesenesewenwneswnwwneseswwne
+enesenwswwswneneswsenwnewswseenwsese
+wnwnesenesenenwwnenwsewesewsesesew
+nenewswnwewswnenesenwnesewesw
+eneswnwswnwsenenwnwnwwseeswneewsenese
+neswnwewnwnwseenwseesewsenwsweewe
+wseweeenwnesenwwwswnew
+
+
+ +In the above example, 10 tiles are flipped once (to black), and 5 more are flipped twice (to black, then back to white). After all of these instructions have been followed, a total of 10 tiles are black. + +Go through the renovation crew's list and determine which tiles they need to flip. After all of the instructions have been followed, how many tiles are left with the black side up? + + +## --- Part Two --- +The tile floor in the lobby is meant to be a living art exhibit. Every day, the tiles are all flipped according to the following rules: + + + - Any black tile with zero or more than 2 black tiles immediately adjacent to it is flipped to white. + - Any white tile with exactly 2 black tiles immediately adjacent to it is flipped to black. + +Here, tiles immediately adjacent means the six tiles directly touching the tile in question. + +The rules are applied simultaneously to every tile; put another way, it is first determined which tiles need to be flipped, then they are all flipped at the same time. + +In the above example, the number of black tiles that are facing up after the given number of days has passed is as follows: + +
+Day 1: 15
+Day 2: 12
+Day 3: 25
+Day 4: 14
+Day 5: 23
+Day 6: 28
+Day 7: 41
+Day 8: 37
+Day 9: 49
+Day 10: 37
+
+Day 20: 132
+Day 30: 259
+Day 40: 406
+Day 50: 566
+Day 60: 788
+Day 70: 1106
+Day 80: 1373
+Day 90: 1844
+Day 100: 2208
+
+
+ +After executing this process a total of 100 times, there would be 2208 black tiles facing up. + +How many tiles will be black after 100 days? + + diff --git a/2020/Day24/input.in b/2020/Day24/input.in index 69fd51927..a3c95793d 100644 Binary files a/2020/Day24/input.in and b/2020/Day24/input.in differ diff --git a/2020/Day25/README.md b/2020/Day25/README.md index 1ee9fb87d..ccf5d8e45 100644 --- a/2020/Day25/README.md +++ b/2020/Day25/README.md @@ -1,6 +1,58 @@ +original source: [https://adventofcode.com/2020/day/25](https://adventofcode.com/2020/day/25) ## --- Day 25: Combo Breaker --- You finally reach the check-in desk. Unfortunately, their registration systems are currently offline, and they cannot check you in. Noticing the look on your face, they quickly add that tech support is already on the way! They even created all the room keys this morning; you can take yours now and give them your room deposit once the registration system comes back online. The room key is a small [RFID](https://en.wikipedia.org/wiki/Radio-frequency_identification) card. Your room is on the 25th floor and the elevators are also temporarily out of service, so it takes what little energy you have left to even climb the stairs and navigate the halls. You finally reach the door to your room, swipe your card, and - beep - the light turns red. -Read the [full puzzle](https://adventofcode.com/2020/day/25). \ No newline at end of file +Examining the card more closely, you discover a phone number for tech support. + +"Hello! How can we help you today?" You explain the situation. + +"Well, it sounds like the card isn't sending the right command to unlock the door. If you go back to the check-in desk, surely someone there can reset it for you." Still catching your breath, you describe the status of the elevator and the exact number of stairs you just had to climb. + +"I see! Well, your only other option would be to reverse-engineer the cryptographic handshake the card does with the door and then inject your own commands into the data stream, but that's definitely impossible." You thank them for their time. + +Unfortunately for the door, you know a thing or two about cryptographic handshakes. + +The handshake used by the card and the door involves an operation that transforms a subject number. To transform a subject number, start with the value 1. Then, a number of times called the loop size, perform the following steps: + + + - Set the value to itself multiplied by the subject number. + - Set the value to the remainder after dividing the value by 20201227. + +The card always uses a specific, secret loop size when it transforms a subject number. The door always uses a different, secret loop size. + +The cryptographic handshake works like this: + + + - The card transforms the subject number of 7 according to the card's secret loop size. The result is called the card's public key. + - The door transforms the subject number of 7 according to the door's secret loop size. The result is called the door's public key. + - The card and door use the wireless RFID signal to transmit the two public keys (your puzzle input) to the other device. Now, the card has the door's public key, and the door has the card's public key. Because you can eavesdrop on the signal, you have both public keys, but neither device's loop size. + - The card transforms the subject number of the door's public key according to the card's loop size. The result is the encryption key. + - The door transforms the subject number of the card's public key according to the door's loop size. The result is the same encryption key as the card calculated. + +If you can use the two public keys to determine each device's loop size, you will have enough information to calculate the secret encryption key that the card and door use to communicate; this would let you send the unlock command directly to the door! + +For example, suppose you know that the card's public key is 5764801. With a little trial and error, you can work out that the card's loop size must be 8, because transforming the initial subject number of 7 with a loop size of 8 produces 5764801. + +Then, suppose you know that the door's public key is 17807724. By the same process, you can determine that the door's loop size is 11, because transforming the initial subject number of 7 with a loop size of 11 produces 17807724. + +At this point, you can use either device's loop size with the other device's public key to calculate the encryption key. Transforming the subject number of 17807724 (the door's public key) with a loop size of 8 (the card's loop size) produces the encryption key, 14897079. (Transforming the subject number of 5764801 (the card's public key) with a loop size of 11 (the door's loop size) produces the same encryption key: 14897079.) + +What encryption key is the handshake trying to establish? + + +## --- Part Two --- +The light turns green and the door unlocks. As you collapse onto the bed in your room, your pager goes off! + +"It's an emergency!" the Elf calling you explains. "The [soft serve](https://en.wikipedia.org/wiki/Soft_serve) machine in the cafeteria on sub-basement 7 just failed and you're the only one that knows how to fix it! We've already dispatched a reindeer to your location to pick you up." + +You hear the sound of hooves landing on your balcony. + +The reindeer carefully explores the contents of your room while you figure out how you're going to pay the 50 stars you owe the resort before you leave. Noticing that you look concerned, the reindeer wanders over to you; you see that it's carrying a small pouch. + +"Sorry for the trouble," a note in the pouch reads. Sitting at the bottom of the pouch is a gold coin with a little picture of a starfish on it. + +Looks like you only needed 49 stars after all. + + diff --git a/2020/Day25/input.in b/2020/Day25/input.in index 44406a1f4..d08846f1e 100644 Binary files a/2020/Day25/input.in and b/2020/Day25/input.in differ diff --git a/2020/README.md b/2020/README.md index 6e92a1b05..909ac8d77 100644 --- a/2020/README.md +++ b/2020/README.md @@ -1,4 +1,6 @@ + # Advent of Code (2020) Check out https://adventofcode.com/2020. + diff --git a/2020/SplashScreen.cs b/2020/SplashScreen.cs index 0152b71a8..cbd79a46e 100644 --- a/2020/SplashScreen.cs +++ b/2020/SplashScreen.cs @@ -1,3 +1,4 @@ + using System; namespace AdventOfCode.Y2020; @@ -8,8 +9,8 @@ public void Show() { var color = Console.ForegroundColor; Write(0xcc00, false, " ▄█▄ ▄▄█ ▄ ▄ ▄▄▄ ▄▄ ▄█▄ ▄▄▄ ▄█ ▄▄ ▄▄▄ ▄▄█ ▄▄▄\n █▄█ █ █ █ █ █▄█ █ █ █ █ █ █▄ "); - Write(0xcc00, false, " █ █ █ █ █ █▄█\n █ █ █▄█ ▀▄▀ █▄▄ █ █ █▄ █▄█ █ █▄ █▄█ █▄█ █▄▄ /* 2020 */\n \n "); - Write(0xcc00, false, " "); + Write(0xcc00, false, " █ █ █ █ █ █▄█\n █ █ █▄█ ▀▄▀ █▄▄ █ █ █▄ █▄█ █ █▄ █▄█ █▄█ █▄▄ 0x0000 | 2020\n "); + Write(0xcc00, false, " \n "); Write(0xccccff, false, ".........."); Write(0xff0000, false, "|"); Write(0xccccff, false, ".......... "); @@ -232,7 +233,7 @@ public void Show() { Console.WriteLine(); } - private static void Write(int rgb, bool bold, string text){ + private static void Write(int rgb, bool bold, string text){ Console.Write($"\u001b[38;2;{(rgb>>16)&255};{(rgb>>8)&255};{rgb&255}{(bold ? ";1" : "")}m{text}"); - } -} \ No newline at end of file + } +} diff --git a/2020/calendar.svg b/2020/calendar.svg index 645d8f67e..e81df0d3f 100644 --- a/2020/calendar.svg +++ b/2020/calendar.svg @@ -1,4 +1,4 @@ - + stars. -_Visit the website for the full story and [full puzzle](https://adventofcode.com/2021/day/1) description._ +Your instincts tell you that in order to save Christmas, you'll need to get all fifty stars by December 25th. + +Collect stars by solving puzzles. Two puzzles will be made available on each day in the Advent calendar; the second puzzle is unlocked when you complete the first. Each puzzle grants one star. Good luck! + +As the submarine drops below the surface of the ocean, it automatically performs a sonar sweep of the nearby sea floor. On a small screen, the sonar sweep report (your puzzle input) appears: each line is a measurement of the sea floor depth as the sweep looks further and further away from the submarine. + +For example, suppose you had the following report: + +
+199
+200
+208
+210
+200
+207
+240
+269
+260
+263
+
+
+ +This report indicates that, scanning outward from the submarine, the sonar sweep found depths of 199, 200, 208, 210, and so on. + +The first order of business is to figure out how quickly the depth increases, just so you know what you're dealing with - you never know if the keys will get carried into deeper water by an ocean current or a fish or something. + +To do this, count the number of times a depth measurement increases from the previous measurement. (There is no measurement before the first measurement.) In the example above, the changes are as follows: + +
+199 (N/A - no previous measurement)
+200 (increased)
+208 (increased)
+210 (increased)
+200 (decreased)
+207 (increased)
+240 (increased)
+269 (increased)
+260 (decreased)
+263 (increased)
+
+
+ +In this example, there are 7 measurements that are larger than the previous measurement. + +How many measurements are larger than the previous measurement? + + +## --- Part Two --- +Considering every single measurement isn't as useful as you expected: there's just too much noise in the data. + +Instead, consider sums of a three-measurement sliding window. Again considering the above example: + +
+199  A      
+200  A B    
+208  A B C  
+210    B C D
+200  E   C D
+207  E F   D
+240  E F G  
+269    F G H
+260      G H
+263        H
+
+
+ +Start by comparing the first and second three-measurement windows. The measurements in the first window are marked A (199, 200, 208); their sum is 199 + 200 + 208 = 607. The second window is marked B (200, 208, 210); its sum is 618. The sum of measurements in the second window is larger than the sum of the first, so this first comparison increased. + +Your goal now is to count the number of times the sum of measurements in this sliding window increases from the previous sum. So, compare A with B, then compare B with C, then C with D, and so on. Stop when there aren't enough measurements left to create a new three-measurement sum. + +In the above example, the sum of each three-measurement window is as follows: + +
+A: 607 (N/A - no previous sum)
+B: 618 (increased)
+C: 618 (no change)
+D: 617 (decreased)
+E: 647 (increased)
+F: 716 (increased)
+G: 769 (increased)
+H: 792 (increased)
+
+
+ +In this example, there are 5 sums that are larger than the previous sum. + +Consider sums of a three-measurement sliding window. How many sums are larger than the previous sum? + + diff --git a/2021/Day01/input.in b/2021/Day01/input.in index 15940121c..db4871bd6 100644 Binary files a/2021/Day01/input.in and b/2021/Day01/input.in differ diff --git a/2021/Day02/README.md b/2021/Day02/README.md index c4ac01b53..e901d7d40 100644 --- a/2021/Day02/README.md +++ b/2021/Day02/README.md @@ -1,6 +1,70 @@ +original source: [https://adventofcode.com/2021/day/2](https://adventofcode.com/2021/day/2) ## --- Day 2: Dive! --- Now, you need to figure out how to pilot this thing. It seems like the submarine can take a series of commands like forward 1, down 2, or up 3: -Read the [full puzzle](https://adventofcode.com/2021/day/2). \ No newline at end of file + + - forward X increases the horizontal position by X units. + - down X increases the depth by X units. + - up X decreases the depth by X units. + +Note that since you're on a submarine, down and up affect your depth, and so they have the opposite result of what you might expect. + +The submarine seems to already have a planned course (your puzzle input). You should probably figure out where it's going. For example: + +
+forward 5
+down 5
+forward 8
+up 3
+down 8
+forward 2
+
+
+ +Your horizontal position and depth both start at 0. The steps above would then modify them as follows: + + + - forward 5 adds 5 to your horizontal position, a total of 5. + - down 5 adds 5 to your depth, resulting in a value of 5. + - forward 8 adds 8 to your horizontal position, a total of 13. + - up 3 decreases your depth by 3, resulting in a value of 2. + - down 8 adds 8 to your depth, resulting in a value of 10. + - forward 2 adds 2 to your horizontal position, a total of 15. + +After following these instructions, you would have a horizontal position of 15 and a depth of 10. (Multiplying these together produces 150.) + +Calculate the horizontal position and depth you would have after following the planned course. What do you get if you multiply your final horizontal position by your final depth? + + +## --- Part Two --- +Based on your calculations, the planned course doesn't seem to make any sense. You find the submarine manual and discover that the process is actually slightly more complicated. + +In addition to horizontal position and depth, you'll also need to track a third value, aim, which also starts at 0. The commands also mean something entirely different than you first thought: + + + - down X increases your aim by X units. + - up X decreases your aim by X units. + - forward X does two things: + - It increases your horizontal position by X units. + - It increases your depth by your aim multiplied by X. + + +Again note that since you're on a submarine, down and up do the opposite of what you might expect: "down" means aiming in the positive direction. + +Now, the above example does something different: + + + - forward 5 adds 5 to your horizontal position, a total of 5. Because your aim is 0, your depth does not change. + - down 5 adds 5 to your aim, resulting in a value of 5. + - forward 8 adds 8 to your horizontal position, a total of 13. Because your aim is 5, your depth increases by 8*5=40. + - up 3 decreases your aim by 3, resulting in a value of 2. + - down 8 adds 8 to your aim, resulting in a value of 10. + - forward 2 adds 2 to your horizontal position, a total of 15. Because your aim is 10, your depth increases by 2*10=20 to a total of 60. + +After following these new instructions, you would have a horizontal position of 15 and a depth of 60. (Multiplying these produces 900.) + +Using this new interpretation of the commands, calculate the horizontal position and depth you would have after following the planned course. What do you get if you multiply your final horizontal position by your final depth? + + diff --git a/2021/Day02/input.in b/2021/Day02/input.in index 0b939332d..fcc2020ed 100644 Binary files a/2021/Day02/input.in and b/2021/Day02/input.in differ diff --git a/2021/Day03/README.md b/2021/Day03/README.md index 51e5a146b..3f909c78a 100644 --- a/2021/Day03/README.md +++ b/2021/Day03/README.md @@ -1,6 +1,78 @@ +original source: [https://adventofcode.com/2021/day/3](https://adventofcode.com/2021/day/3) ## --- Day 3: Binary Diagnostic --- The submarine has been making some odd creaking noises, so you ask it to produce a diagnostic report just in case. The diagnostic report (your puzzle input) consists of a list of binary numbers which, when decoded properly, can tell you many useful things about the conditions of the submarine. The first parameter to check is the power consumption. -Read the [full puzzle](https://adventofcode.com/2021/day/3). \ No newline at end of file +You need to use the binary numbers in the diagnostic report to generate two new binary numbers (called the gamma rate and the epsilon rate). The power consumption can then be found by multiplying the gamma rate by the epsilon rate. + +Each bit in the gamma rate can be determined by finding the most common bit in the corresponding position of all numbers in the diagnostic report. For example, given the following diagnostic report: + +
+00100
+11110
+10110
+10111
+10101
+01111
+00111
+11100
+10000
+11001
+00010
+01010
+
+
+ +Considering only the first bit of each number, there are five 0 bits and seven 1 bits. Since the most common bit is 1, the first bit of the gamma rate is 1. + +The most common second bit of the numbers in the diagnostic report is 0, so the second bit of the gamma rate is 0. + +The most common value of the third, fourth, and fifth bits are 1, 1, and 0, respectively, and so the final three bits of the gamma rate are 110. + +So, the gamma rate is the binary number 10110, or 22 in decimal. + +The epsilon rate is calculated in a similar way; rather than use the most common bit, the least common bit from each position is used. So, the epsilon rate is 01001, or 9 in decimal. Multiplying the gamma rate (22) by the epsilon rate (9) produces the power consumption, 198. + +Use the binary numbers in your diagnostic report to calculate the gamma rate and epsilon rate, then multiply them together. What is the power consumption of the submarine? (Be sure to represent your answer in decimal, not binary.) + + +## --- Part Two --- +Next, you should verify the life support rating, which can be determined by multiplying the oxygen generator rating by the CO2 scrubber rating. + +Both the oxygen generator rating and the CO2 scrubber rating are values that can be found in your diagnostic report - finding them is the tricky part. Both values are located using a similar process that involves filtering out values until only one remains. Before searching for either rating value, start with the full list of binary numbers from your diagnostic report and consider just the first bit of those numbers. Then: + + + - Keep only numbers selected by the bit criteria for the type of rating value for which you are searching. Discard numbers which do not match the bit criteria. + - If you only have one number left, stop; this is the rating value for which you are searching. + - Otherwise, repeat the process, considering the next bit to the right. + +The bit criteria depends on which type of rating value you want to find: + + + - To find oxygen generator rating, determine the most common value (0 or 1) in the current bit position, and keep only numbers with that bit in that position. If 0 and 1 are equally common, keep values with a 1 in the position being considered. + - To find CO2 scrubber rating, determine the least common value (0 or 1) in the current bit position, and keep only numbers with that bit in that position. If 0 and 1 are equally common, keep values with a 0 in the position being considered. + +For example, to determine the oxygen generator rating value using the same example diagnostic report from above: + + + - Start with all 12 numbers and consider only the first bit of each number. There are more 1 bits (7) than 0 bits (5), so keep only the 7 numbers with a 1 in the first position: 11110, 10110, 10111, 10101, 11100, 10000, and 11001. + - Then, consider the second bit of the 7 remaining numbers: there are more 0 bits (4) than 1 bits (3), so keep only the 4 numbers with a 0 in the second position: 10110, 10111, 10101, and 10000. + - In the third position, three of the four numbers have a 1, so keep those three: 10110, 10111, and 10101. + - In the fourth position, two of the three numbers have a 1, so keep those two: 10110 and 10111. + - In the fifth position, there are an equal number of 0 bits and 1 bits (one each). So, to find the oxygen generator rating, keep the number with a 1 in that position: 10111. + - As there is only one number left, stop; the oxygen generator rating is 10111, or 23 in decimal. + +Then, to determine the CO2 scrubber rating value from the same example above: + + + - Start again with all 12 numbers and consider only the first bit of each number. There are fewer 0 bits (5) than 1 bits (7), so keep only the 5 numbers with a 0 in the first position: 00100, 01111, 00111, 00010, and 01010. + - Then, consider the second bit of the 5 remaining numbers: there are fewer 1 bits (2) than 0 bits (3), so keep only the 2 numbers with a 1 in the second position: 01111 and 01010. + - In the third position, there are an equal number of 0 bits and 1 bits (one each). So, to find the CO2 scrubber rating, keep the number with a 0 in that position: 01010. + - As there is only one number left, stop; the CO2 scrubber rating is 01010, or 10 in decimal. + +Finally, to find the life support rating, multiply the oxygen generator rating (23) by the CO2 scrubber rating (10) to get 230. + +Use the binary numbers in your diagnostic report to calculate the oxygen generator rating and CO2 scrubber rating, then multiply them together. What is the life support rating of the submarine? (Be sure to represent your answer in decimal, not binary.) + + diff --git a/2021/Day03/input.in b/2021/Day03/input.in index 46287174b..922d55694 100644 Binary files a/2021/Day03/input.in and b/2021/Day03/input.in differ diff --git a/2021/Day04/README.md b/2021/Day04/README.md index cd24ccd66..51e55b1ee 100644 --- a/2021/Day04/README.md +++ b/2021/Day04/README.md @@ -1,6 +1,83 @@ +original source: [https://adventofcode.com/2021/day/4](https://adventofcode.com/2021/day/4) ## --- Day 4: Giant Squid --- You're already almost 1.5km (almost a mile) below the surface of the ocean, already so deep that you can't see any sunlight. What you can see, however, is a giant squid that has attached itself to the outside of your submarine. Maybe it wants to play [bingo](https://en.wikipedia.org/wiki/Bingo_(American_version))? -Read the [full puzzle](https://adventofcode.com/2021/day/4). \ No newline at end of file +Bingo is played on a set of boards each consisting of a 5x5 grid of numbers. Numbers are chosen at random, and the chosen number is marked on all boards on which it appears. (Numbers may not appear on all boards.) If all numbers in any row or any column of a board are marked, that board wins. (Diagonals don't count.) + +The submarine has a bingo subsystem to help passengers (currently, you and the giant squid) pass the time. It automatically generates a random order in which to draw numbers and a random set of boards (your puzzle input). For example: + +
+7,4,9,5,11,17,23,2,0,14,21,24,10,16,13,6,15,25,12,22,18,20,8,19,3,26,1
+
+22 13 17 11  0
+ 8  2 23  4 24
+21  9 14 16  7
+ 6 10  3 18  5
+ 1 12 20 15 19
+
+ 3 15  0  2 22
+ 9 18 13 17  5
+19  8  7 25 23
+20 11 10 24  4
+14 21 16 12  6
+
+14 21 17 24  4
+10 16 15  9 19
+18  8 23 26 20
+22 11 13  6  5
+ 2  0 12  3  7
+
+
+ +After the first five numbers are drawn (7, 4, 9, 5, and 11), there are no winners, but the boards are marked as follows (shown here adjacent to each other to save space): + +
+22 13 17 11  0         3 15  0  2 22        14 21 17 24  4
+ 8  2 23  4 24         9 18 13 17  5        10 16 15  9 19
+21  9 14 16  7        19  8  7 25 23        18  8 23 26 20
+ 6 10  3 18  5        20 11 10 24  4        22 11 13  6  5
+ 1 12 20 15 19        14 21 16 12  6         2  0 12  3  7
+
+
+ +After the next six numbers are drawn (17, 23, 2, 0, 14, and 21), there are still no winners: + +
+22 13 17 11  0         3 15  0  2 22        14 21 17 24  4
+ 8  2 23  4 24         9 18 13 17  5        10 16 15  9 19
+21  9 14 16  7        19  8  7 25 23        18  8 23 26 20
+ 6 10  3 18  5        20 11 10 24  4        22 11 13  6  5
+ 1 12 20 15 19        14 21 16 12  6         2  0 12  3  7
+
+
+ +Finally, 24 is drawn: + +
+22 13 17 11  0         3 15  0  2 22        14 21 17 24  4
+ 8  2 23  4 24         9 18 13 17  5        10 16 15  9 19
+21  9 14 16  7        19  8  7 25 23        18  8 23 26 20
+ 6 10  3 18  5        20 11 10 24  4        22 11 13  6  5
+ 1 12 20 15 19        14 21 16 12  6         2  0 12  3  7
+
+
+ +At this point, the third board wins because it has at least one complete row or column of marked numbers (in this case, the entire top row is marked: 14 21 17 24 4). + +The score of the winning board can now be calculated. Start by finding the sum of all unmarked numbers on that board; in this case, the sum is 188. Then, multiply that sum by the number that was just called when the board won, 24, to get the final score, 188 * 24 = 4512. + +To guarantee victory against the giant squid, figure out which board will win first. What will your final score be if you choose that board? + + +## --- Part Two --- +On the other hand, it might be wise to try a different strategy: let the giant squid win. + +You aren't sure how many bingo boards a giant squid could play at once, so rather than waste time counting its arms, the safe thing to do is to figure out which board will win last and choose that one. That way, no matter which boards it picks, it will win for sure. + +In the above example, the second board is the last to win, which happens after 13 is eventually called and its middle column is completely marked. If you were to keep playing until this point, the second board would have a sum of unmarked numbers equal to 148 for a final score of 148 * 13 = 1924. + +Figure out which board will win last. Once it wins, what would its final score be? + + diff --git a/2021/Day04/input.in b/2021/Day04/input.in index f185fe414..033baa23a 100644 Binary files a/2021/Day04/input.in and b/2021/Day04/input.in differ diff --git a/2021/Day05/README.md b/2021/Day05/README.md index a565ae1cb..9b975f7a2 100644 --- a/2021/Day05/README.md +++ b/2021/Day05/README.md @@ -1,6 +1,81 @@ +original source: [https://adventofcode.com/2021/day/5](https://adventofcode.com/2021/day/5) ## --- Day 5: Hydrothermal Venture --- You come across a field of [hydrothermal vents](https://en.wikipedia.org/wiki/Hydrothermal_vent) on the ocean floor! These vents constantly produce large, opaque clouds, so it would be best to avoid them if possible. They tend to form in lines; the submarine helpfully produces a list of nearby lines of vents (your puzzle input) for you to review. For example: -Read the [full puzzle](https://adventofcode.com/2021/day/5). \ No newline at end of file +
+0,9 -> 5,9
+8,0 -> 0,8
+9,4 -> 3,4
+2,2 -> 2,1
+7,0 -> 7,4
+6,4 -> 2,0
+0,9 -> 2,9
+3,4 -> 1,4
+0,0 -> 8,8
+5,5 -> 8,2
+
+
+ +Each line of vents is given as a line segment in the format x1,y1 -> x2,y2 where x1,y1 are the coordinates of one end the line segment and x2,y2 are the coordinates of the other end. These line segments include the points at both ends. In other words: + + + - An entry like 1,1 -> 1,3 covers points 1,1, 1,2, and 1,3. + - An entry like 9,7 -> 7,7 covers points 9,7, 8,7, and 7,7. + +For now, only consider horizontal and vertical lines: lines where either x1 = x2 or y1 = y2. + +So, the horizontal and vertical lines from the above list would produce the following diagram: + +
+.......1..
+..1....1..
+..1....1..
+.......1..
+.112111211
+..........
+..........
+..........
+..........
+222111....
+
+
+ +In this diagram, the top left corner is 0,0 and the bottom right corner is 9,9. Each position is shown as the number of lines which cover that point or . if no line covers that point. The top-left pair of 1s, for example, comes from 2,2 -> 2,1; the very bottom row is formed by the overlapping lines 0,9 -> 5,9 and 0,9 -> 2,9. + +To avoid the most dangerous areas, you need to determine the number of points where at least two lines overlap. In the above example, this is anywhere in the diagram with a 2 or larger - a total of 5 points. + +Consider only horizontal and vertical lines. At how many points do at least two lines overlap? + + +## --- Part Two --- +Unfortunately, considering only horizontal and vertical lines doesn't give you the full picture; you need to also consider diagonal lines. + +Because of the limits of the hydrothermal vent mapping system, the lines in your list will only ever be horizontal, vertical, or a diagonal line at exactly 45 degrees. In other words: + + + - An entry like 1,1 -> 3,3 covers points 1,1, 2,2, and 3,3. + - An entry like 9,7 -> 7,9 covers points 9,7, 8,8, and 7,9. + +Considering all lines from the above example would now produce the following diagram: + +
+1.1....11.
+.111...2..
+..2.1.111.
+...1.2.2..
+.112313211
+...1.2....
+..1...1...
+.1.....1..
+1.......1.
+222111....
+
+
+ +You still need to determine the number of points where at least two lines overlap. In the above example, this is still anywhere in the diagram with a 2 or larger - now a total of 12 points. + +Consider all of the lines. At how many points do at least two lines overlap? + + diff --git a/2021/Day05/input.in b/2021/Day05/input.in index cc16d6461..a081008d5 100644 Binary files a/2021/Day05/input.in and b/2021/Day05/input.in differ diff --git a/2021/Day06/README.md b/2021/Day06/README.md index 238ac092f..40f4b6ed0 100644 --- a/2021/Day06/README.md +++ b/2021/Day06/README.md @@ -1,6 +1,69 @@ +original source: [https://adventofcode.com/2021/day/6](https://adventofcode.com/2021/day/6) ## --- Day 6: Lanternfish --- The sea floor is getting steeper. Maybe the sleigh keys got carried this way? A massive school of glowing [lanternfish](https://en.wikipedia.org/wiki/Lanternfish) swims past. They must spawn quickly to reach such large numbers - maybe exponentially quickly? You should model their growth rate to be sure. -Read the [full puzzle](https://adventofcode.com/2021/day/6). \ No newline at end of file +Although you know nothing about this specific species of lanternfish, you make some guesses about their attributes. Surely, each lanternfish creates a new lanternfish once every 7 days. + +However, this process isn't necessarily synchronized between every lanternfish - one lanternfish might have 2 days left until it creates another lanternfish, while another might have 4. So, you can model each fish as a single number that represents the number of days until it creates a new lanternfish. + +Furthermore, you reason, a new lanternfish would surely need slightly longer before it's capable of producing more lanternfish: two more days for its first cycle. + +So, suppose you have a lanternfish with an internal timer value of 3: + + + - After one day, its internal timer would become 2. + - After another day, its internal timer would become 1. + - After another day, its internal timer would become 0. + - After another day, its internal timer would reset to 6, and it would create a new lanternfish with an internal timer of 8. + - After another day, the first lanternfish would have an internal timer of 5, and the second lanternfish would have an internal timer of 7. + +A lanternfish that creates a new fish resets its timer to 6, not 7 (because 0 is included as a valid timer value). The new lanternfish starts with an internal timer of 8 and does not start counting down until the next day. + +Realizing what you're trying to do, the submarine automatically produces a list of the ages of several hundred nearby lanternfish (your puzzle input). For example, suppose you were given the following list: + +
+3,4,3,1,2
+
+ +This list means that the first fish has an internal timer of 3, the second fish has an internal timer of 4, and so on until the fifth fish, which has an internal timer of 2. Simulating these fish over several days would proceed as follows: + +
+Initial state: 3,4,3,1,2
+After  1 day:  2,3,2,0,1
+After  2 days: 1,2,1,6,0,8
+After  3 days: 0,1,0,5,6,7,8
+After  4 days: 6,0,6,4,5,6,7,8,8
+After  5 days: 5,6,5,3,4,5,6,7,7,8
+After  6 days: 4,5,4,2,3,4,5,6,6,7
+After  7 days: 3,4,3,1,2,3,4,5,5,6
+After  8 days: 2,3,2,0,1,2,3,4,4,5
+After  9 days: 1,2,1,6,0,1,2,3,3,4,8
+After 10 days: 0,1,0,5,6,0,1,2,2,3,7,8
+After 11 days: 6,0,6,4,5,6,0,1,1,2,6,7,8,8,8
+After 12 days: 5,6,5,3,4,5,6,0,0,1,5,6,7,7,7,8,8
+After 13 days: 4,5,4,2,3,4,5,6,6,0,4,5,6,6,6,7,7,8,8
+After 14 days: 3,4,3,1,2,3,4,5,5,6,3,4,5,5,5,6,6,7,7,8
+After 15 days: 2,3,2,0,1,2,3,4,4,5,2,3,4,4,4,5,5,6,6,7
+After 16 days: 1,2,1,6,0,1,2,3,3,4,1,2,3,3,3,4,4,5,5,6,8
+After 17 days: 0,1,0,5,6,0,1,2,2,3,0,1,2,2,2,3,3,4,4,5,7,8
+After 18 days: 6,0,6,4,5,6,0,1,1,2,6,0,1,1,1,2,2,3,3,4,6,7,8,8,8,8
+
+
+ +Each day, a 0 becomes a 6 and adds a new 8 to the end of the list, while each other number decreases by 1 if it was present at the start of the day. + +In this example, after 18 days, there are a total of 26 fish. After 80 days, there would be a total of 5934. + +Find a way to simulate lanternfish. How many lanternfish would there be after 80 days? + + +## --- Part Two --- +Suppose the lanternfish live forever and have unlimited food and space. Would they take over the entire ocean? + +After 256 days in the example above, there would be a total of 26984457539 lanternfish! + +How many lanternfish would there be after 256 days? + + diff --git a/2021/Day06/input.in b/2021/Day06/input.in index 17a86be23..149e1e26b 100644 Binary files a/2021/Day06/input.in and b/2021/Day06/input.in differ diff --git a/2021/Day07/README.md b/2021/Day07/README.md index e8c136e7c..763e680af 100644 --- a/2021/Day07/README.md +++ b/2021/Day07/README.md @@ -1,6 +1,63 @@ +original source: [https://adventofcode.com/2021/day/7](https://adventofcode.com/2021/day/7) ## --- Day 7: The Treachery of Whales --- A giant [whale](https://en.wikipedia.org/wiki/Sperm_whale) has decided your submarine is its next meal, and it's much faster than you are. There's nowhere to run! Suddenly, a swarm of crabs (each in its own tiny submarine - it's too deep for them otherwise) zooms in to rescue you! They seem to be preparing to blast a hole in the ocean floor; sensors indicate a massive underground cave system just beyond where they're aiming! -Read the [full puzzle](https://adventofcode.com/2021/day/7). \ No newline at end of file +The crab submarines all need to be aligned before they'll have enough power to blast a large enough hole for your submarine to get through. However, it doesn't look like they'll be aligned before the whale catches you! Maybe you can help? + +There's one major catch - crab submarines can only move horizontally. + +You quickly make a list of the horizontal position of each crab (your puzzle input). Crab submarines have limited fuel, so you need to find a way to make all of their horizontal positions match while requiring them to spend as little fuel as possible. + +For example, consider the following horizontal positions: + +
+16,1,2,0,4,2,7,1,2,14
+
+ +This means there's a crab with horizontal position 16, a crab with horizontal position 1, and so on. + +Each change of 1 step in horizontal position of a single crab costs 1 fuel. You could choose any horizontal position to align them all on, but the one that costs the least fuel is horizontal position 2: + + + - Move from 16 to 2: 14 fuel + - Move from 1 to 2: 1 fuel + - Move from 2 to 2: 0 fuel + - Move from 0 to 2: 2 fuel + - Move from 4 to 2: 2 fuel + - Move from 2 to 2: 0 fuel + - Move from 7 to 2: 5 fuel + - Move from 1 to 2: 1 fuel + - Move from 2 to 2: 0 fuel + - Move from 14 to 2: 12 fuel + +This costs a total of 37 fuel. This is the cheapest possible outcome; more expensive outcomes include aligning at position 1 (41 fuel), position 3 (39 fuel), or position 10 (71 fuel). + +Determine the horizontal position that the crabs can align to using the least fuel possible. How much fuel must they spend to align to that position? + + +## --- Part Two --- +The crabs don't seem interested in your proposed solution. Perhaps you misunderstand crab engineering? + +As it turns out, crab submarine engines don't burn fuel at a constant rate. Instead, each change of 1 step in horizontal position costs 1 more unit of fuel than the last: the first step costs 1, the second step costs 2, the third step costs 3, and so on. + +As each crab moves, moving further becomes more expensive. This changes the best horizontal position to align them all on; in the example above, this becomes 5: + + + - Move from 16 to 5: 66 fuel + - Move from 1 to 5: 10 fuel + - Move from 2 to 5: 6 fuel + - Move from 0 to 5: 15 fuel + - Move from 4 to 5: 1 fuel + - Move from 2 to 5: 6 fuel + - Move from 7 to 5: 3 fuel + - Move from 1 to 5: 10 fuel + - Move from 2 to 5: 6 fuel + - Move from 14 to 5: 45 fuel + +This costs a total of 168 fuel. This is the new cheapest possible outcome; the old alignment position (2) now costs 206 fuel instead. + +Determine the horizontal position that the crabs can align to using the least fuel possible so they can make you an escape route! How much fuel must they spend to align to that position? + + diff --git a/2021/Day07/input.in b/2021/Day07/input.in index 15a51df75..9c3acf637 100644 Binary files a/2021/Day07/input.in and b/2021/Day07/input.in differ diff --git a/2021/Day08/README.md b/2021/Day08/README.md index 526d9304a..dd9c7bf8e 100644 --- a/2021/Day08/README.md +++ b/2021/Day08/README.md @@ -1,6 +1,145 @@ +original source: [https://adventofcode.com/2021/day/8](https://adventofcode.com/2021/day/8) ## --- Day 8: Seven Segment Search --- You barely reach the safety of the cave when the whale smashes into the cave mouth, collapsing it. Sensors indicate another exit to this cave at a much greater depth, so you have no choice but to press on. As your submarine slowly makes its way through the cave system, you notice that the four-digit [seven-segment displays](https://en.wikipedia.org/wiki/Seven-segment_display) in your submarine are malfunctioning; they must have been damaged during the escape. You'll be in a lot of trouble without them, so you'd better figure out what's wrong. -Read the [full puzzle](https://adventofcode.com/2021/day/8). \ No newline at end of file +Each digit of a seven-segment display is rendered by turning on or off any of seven segments named a through g: + +
+  0:      1:      2:      3:      4:
+ aaaa    ....    aaaa    aaaa    ....
+b    c  .    c  .    c  .    c  b    c
+b    c  .    c  .    c  .    c  b    c
+ ....    ....    dddd    dddd    dddd
+e    f  .    f  e    .  .    f  .    f
+e    f  .    f  e    .  .    f  .    f
+ gggg    ....    gggg    gggg    ....
+
+  5:      6:      7:      8:      9:
+ aaaa    aaaa    aaaa    aaaa    aaaa
+b    .  b    .  .    c  b    c  b    c
+b    .  b    .  .    c  b    c  b    c
+ dddd    dddd    ....    dddd    dddd
+.    f  e    f  .    f  e    f  .    f
+.    f  e    f  .    f  e    f  .    f
+ gggg    gggg    ....    gggg    gggg
+
+
+ +So, to render a 1, only segments c and f would be turned on; the rest would be off. To render a 7, only segments a, c, and f would be turned on. + +The problem is that the signals which control the segments have been mixed up on each display. The submarine is still trying to display numbers by producing output on signal wires a through g, but those wires are connected to segments randomly. Worse, the wire/segment connections are mixed up separately for each four-digit display! (All of the digits within a display use the same connections, though.) + +So, you might know that only signal wires b and g are turned on, but that doesn't mean segments b and g are turned on: the only digit that uses two segments is 1, so it must mean segments c and f are meant to be on. With just that information, you still can't tell which wire (b/g) goes to which segment (c/f). For that, you'll need to collect more information. + +For each display, you watch the changing signals for a while, make a note of all ten unique signal patterns you see, and then write down a single four digit output value (your puzzle input). Using the signal patterns, you should be able to work out which pattern corresponds to which digit. + +For example, here is what you might see in a single entry in your notes: + +
+acedgfb cdfbe gcdfa fbcad dab cefabd cdfgeb eafb cagedb ab |
+cdfeb fcadb cdfeb cdbaf
+
+ +(The entry is wrapped here to two lines so it fits; in your notes, it will all be on a single line.) + +Each entry consists of ten unique signal patterns, a | delimiter, and finally the four digit output value. Within an entry, the same wire/segment connections are used (but you don't know what the connections actually are). The unique signal patterns correspond to the ten different ways the submarine tries to render a digit using the current wire/segment connections. Because 7 is the only digit that uses three segments, dab in the above example means that to render a 7, signal lines d, a, and b are on. Because 4 is the only digit that uses four segments, eafb means that to render a 4, signal lines e, a, f, and b are on. + +Using this information, you should be able to work out which combination of signal wires corresponds to each of the ten digits. Then, you can decode the four digit output value. Unfortunately, in the above example, all of the digits in the output value (cdfeb fcadb cdfeb cdbaf) use five segments and are more difficult to deduce. + +For now, focus on the easy digits. Consider this larger example: + +
+be cfbegad cbdgef fgaecd cgeb fdcge agebfd fecdb fabcd edb |
+fdgacbe cefdb cefbgd gcbe
+edbfga begcd cbg gc gcadebf fbgde acbgfd abcde gfcbed gfec |
+fcgedb cgb dgebacf gc
+fgaebd cg bdaec gdafb agbcfd gdcbef bgcad gfac gcb cdgabef |
+cg cg fdcagb cbg
+fbegcd cbd adcefb dageb afcb bc aefdc ecdab fgdeca fcdbega |
+efabcd cedba gadfec cb
+aecbfdg fbg gf bafeg dbefa fcge gcbea fcaegb dgceab fcbdga |
+gecf egdcabf bgf bfgea
+fgeab ca afcebg bdacfeg cfaedg gcfdb baec bfadeg bafgc acf |
+gebdcfa ecba ca fadegcb
+dbcfg fgd bdegcaf fgec aegbdf ecdfab fbedc dacgb gdcebf gf |
+cefg dcbef fcge gbcadfe
+bdfegc cbegaf gecbf dfcage bdacg ed bedf ced adcbefg gebcd |
+ed bcgafe cdgba cbgef
+egadfb cdbfeg cegd fecab cgb gbdefca cg fgcdab egfdb bfceg |
+gbdfcae bgc cg cgb
+gcafb gcf dcaebfg ecagb gf abcdeg gaef cafbge fdbac fegbdc |
+fgae cfgab fg bagce
+
+
+ +Because the digits 1, 4, 7, and 8 each use a unique number of segments, you should be able to tell which combinations of signals correspond to those digits. Counting only digits in the output values (the part after | on each line), in the above example, there are 26 instances of digits that use a unique number of segments (highlighted above). + +In the output values, how many times do digits 1, 4, 7, or 8 appear? + + +## --- Part Two --- +Through a little deduction, you should now be able to determine the remaining digits. Consider again the first example above: + +
+acedgfb cdfbe gcdfa fbcad dab cefabd cdfgeb eafb cagedb ab |
+cdfeb fcadb cdfeb cdbaf
+
+ +After some careful analysis, the mapping between signal wires and segments only make sense in the following configuration: + +
+ dddd
+e    a
+e    a
+ ffff
+g    b
+g    b
+ cccc
+
+
+ +So, the unique signal patterns would correspond to the following digits: + + + - acedgfb: 8 + - cdfbe: 5 + - gcdfa: 2 + - fbcad: 3 + - dab: 7 + - cefabd: 9 + - cdfgeb: 6 + - eafb: 4 + - cagedb: 0 + - ab: 1 + +Then, the four digits of the output value can be decoded: + + + - cdfeb: 5 + - fcadb: 3 + - cdfeb: 5 + - cdbaf: 3 + +Therefore, the output value for this entry is 5353. + +Following this same process for each entry in the second, larger example above, the output value of each entry can be determined: + + + - fdgacbe cefdb cefbgd gcbe: 8394 + - fcgedb cgb dgebacf gc: 9781 + - cg cg fdcagb cbg: 1197 + - efabcd cedba gadfec cb: 9361 + - gecf egdcabf bgf bfgea: 4873 + - gebdcfa ecba ca fadegcb: 8418 + - cefg dcbef fcge gbcadfe: 4548 + - ed bcgafe cdgba cbgef: 1625 + - gbdfcae bgc cg cgb: 8717 + - fgae cfgab fg bagce: 4315 + +Adding all of the output values in this larger example produces 61229. + +For each entry, determine all of the wire/segment connections and decode the four-digit output values. What do you get if you add up all of the output values? + + diff --git a/2021/Day08/input.in b/2021/Day08/input.in index adba44a98..0b6b26e80 100644 Binary files a/2021/Day08/input.in and b/2021/Day08/input.in differ diff --git a/2021/Day09/README.md b/2021/Day09/README.md index e7684e0c1..38c7e67c7 100644 --- a/2021/Day09/README.md +++ b/2021/Day09/README.md @@ -1,6 +1,84 @@ +original source: [https://adventofcode.com/2021/day/9](https://adventofcode.com/2021/day/9) ## --- Day 9: Smoke Basin --- These caves seem to be [lava tubes](https://en.wikipedia.org/wiki/Lava_tube). Parts are even still volcanically active; small hydrothermal vents release smoke into the caves that slowly settles like rain. If you can model how the smoke flows through the caves, you might be able to avoid it and be that much safer. The submarine generates a heightmap of the floor of the nearby caves for you (your puzzle input). -Read the [full puzzle](https://adventofcode.com/2021/day/9). \ No newline at end of file +Smoke flows to the lowest point of the area it's in. For example, consider the following heightmap: + +
+2199943210
+3987894921
+9856789892
+8767896789
+9899965678
+
+
+ +Each number corresponds to the height of a particular location, where 9 is the highest and 0 is the lowest a location can be. + +Your first goal is to find the low points - the locations that are lower than any of its adjacent locations. Most locations have four adjacent locations (up, down, left, and right); locations on the edge or corner of the map have three or two adjacent locations, respectively. (Diagonal locations do not count as adjacent.) + +In the above example, there are four low points, all highlighted: two are in the first row (a 1 and a 0), one is in the third row (a 5), and one is in the bottom row (also a 5). All other locations on the heightmap have some lower adjacent location, and so are not low points. + +The risk level of a low point is 1 plus its height. In the above example, the risk levels of the low points are 2, 1, 6, and 6. The sum of the risk levels of all low points in the heightmap is therefore 15. + +Find all of the low points on your heightmap. What is the sum of the risk levels of all low points on your heightmap? + + +## --- Part Two --- +Next, you need to find the largest basins so you know what areas are most important to avoid. + +A basin is all locations that eventually flow downward to a single low point. Therefore, every low point has a basin, although some basins are very small. Locations of height 9 do not count as being in any basin, and all other locations will always be part of exactly one basin. + +The size of a basin is the number of locations within the basin, including the low point. The example above has four basins. + +The top-left basin, size 3: + +
+2199943210
+3987894921
+9856789892
+8767896789
+9899965678
+
+
+ +The top-right basin, size 9: + +
+2199943210
+3987894921
+9856789892
+8767896789
+9899965678
+
+
+ +The middle basin, size 14: + +
+2199943210
+3987894921
+9856789892
+8767896789
+9899965678
+
+
+ +The bottom-right basin, size 9: + +
+2199943210
+3987894921
+9856789892
+8767896789
+9899965678
+
+
+ +Find the three largest basins and multiply their sizes together. In the above example, this is 9 * 14 * 9 = 1134. + +What do you get if you multiply together the sizes of the three largest basins? + + diff --git a/2021/Day09/input.in b/2021/Day09/input.in index 606fffcb1..a6cf1a92f 100644 Binary files a/2021/Day09/input.in and b/2021/Day09/input.in differ diff --git a/2021/Day10/README.md b/2021/Day10/README.md index b54a19720..dab0771b2 100644 --- a/2021/Day10/README.md +++ b/2021/Day10/README.md @@ -1,3 +1,4 @@ +original source: [https://adventofcode.com/2021/day/10](https://adventofcode.com/2021/day/10) ## --- Day 10: Syntax Scoring --- You ask the submarine to determine the best route out of the deep-sea cave, but it only replies: @@ -5,4 +6,108 @@ You ask the submarine to determine the best route out of the deep-sea cave, but Syntax error in navigation subsystem on line: all of them -Read the [full puzzle](https://adventofcode.com/2021/day/10). \ No newline at end of file +All of them?! The damage is worse than you thought. You bring up a copy of the navigation subsystem (your puzzle input). + +The navigation subsystem syntax is made of several lines containing chunks. There are one or more chunks on each line, and chunks contain zero or more other chunks. Adjacent chunks are not separated by any delimiter; if one chunk stops, the next chunk (if any) can immediately start. Every chunk must open and close with one of four legal pairs of matching characters: + + + - If a chunk opens with (, it must close with ). + - If a chunk opens with [, it must close with ]. + - If a chunk opens with {, it must close with }. + - If a chunk opens with <, it must close with >. + +So, () is a legal chunk that contains no other chunks, as is []. More complex but valid chunks include ([]), {()()()}, <([{}])>, [<>({}){}[([])<>]], and even (((((((((()))))))))). + +Some lines are incomplete, but others are corrupted. Find and discard the corrupted lines first. + +A corrupted line is one where a chunk closes with the wrong character - that is, where the characters it opens and closes with do not form one of the four legal pairs listed above. + +Examples of corrupted chunks include (], {()()()>, (((()))}, and <([]){()}[{}]). Such a chunk can appear anywhere within a line, and its presence causes the whole line to be considered corrupted. + +For example, consider the following navigation subsystem: + +
+[({(<(())[]>[[{[]{<()<>>
+[(()[<>])]({[<{<<[]>>(
+{([(<{}[<>[]}>{[]{[(<()>
+(((({<>}<{<{<>}{[]{[]{}
+[[<[([]))<([[{}[[()]]]
+[{[{({}]{}}([{[{{{}}([]
+{<[[]]>}<{[{[{[]{()[[[]
+[<(<(<(<{}))><([]([]()
+<{([([[(<>()){}]>(<<{{
+<{([{{}}[<[[[<>{}]]]>[]]
+
+
+ +Some of the lines aren't corrupted, just incomplete; you can ignore these lines for now. The remaining five lines are corrupted: + + + - {([(<{}[<>[]}>{[]{[(<()> - Expected ], but found } instead. + - [[<[([]))<([[{}[[()]]] - Expected ], but found ) instead. + - [{[{({}]{}}([{[{{{}}([] - Expected ), but found ] instead. + - [<(<(<(<{}))><([]([]() - Expected >, but found ) instead. + - <{([([[(<>()){}]>(<<{{ - Expected ], but found > instead. + +Stop at the first incorrect closing character on each corrupted line. + +Did you know that syntax checkers actually have contests to see who can get the high score for syntax errors in a file? It's true! To calculate the syntax error score for a line, take the first illegal character on the line and look it up in the following table: + + + - ): 3 points. + - ]: 57 points. + - }: 1197 points. + - >: 25137 points. + +In the above example, an illegal ) was found twice (2*3 = 6 points), an illegal ] was found once (57 points), an illegal } was found once (1197 points), and an illegal > was found once (25137 points). So, the total syntax error score for this file is 6+57+1197+25137 = 26397 points! + +Find the first illegal character in each corrupted line of the navigation subsystem. What is the total syntax error score for those errors? + + +## --- Part Two --- +Now, discard the corrupted lines. The remaining lines are incomplete. + +Incomplete lines don't have any incorrect characters - instead, they're missing some closing characters at the end of the line. To repair the navigation subsystem, you just need to figure out the sequence of closing characters that complete all open chunks in the line. + +You can only use closing characters (), ], }, or >), and you must add them in the correct order so that only legal pairs are formed and all chunks end up closed. + +In the example above, there are five incomplete lines: + + + - [({(<(())[]>[[{[]{<()<>> - Complete by adding }}]])})]. + - [(()[<>])]({[<{<<[]>>( - Complete by adding )}>]}). + - (((({<>}<{<{<>}{[]{[]{} - Complete by adding }}>}>)))). + - {<[[]]>}<{[{[{[]{()[[[] - Complete by adding ]]}}]}]}>. + - <{([{{}}[<[[[<>{}]]]>[]] - Complete by adding ])}>. + +Did you know that autocomplete tools also have contests? It's true! The score is determined by considering the completion string character-by-character. Start with a total score of 0. Then, for each character, multiply the total score by 5 and then increase the total score by the point value given for the character in the following table: + + + - ): 1 point. + - ]: 2 points. + - }: 3 points. + - >: 4 points. + +So, the last completion string above - ])}> - would be scored as follows: + + + - Start with a total score of 0. + - Multiply the total score by 5 to get 0, then add the value of ] (2) to get a new total score of 2. + - Multiply the total score by 5 to get 10, then add the value of ) (1) to get a new total score of 11. + - Multiply the total score by 5 to get 55, then add the value of } (3) to get a new total score of 58. + - Multiply the total score by 5 to get 290, then add the value of > (4) to get a new total score of 294. + +The five lines' completion strings have total scores as follows: + + + - }}]])})] - 288957 total points. + - )}>]}) - 5566 total points. + - }}>}>)))) - 1480781 total points. + - ]]}}]}]}> - 995444 total points. + - ])}> - 294 total points. + +Autocomplete tools are an odd bunch: the winner is found by sorting all of the scores and then taking the middle score. (There will always be an odd number of scores to consider.) In this example, the middle score is 288957 because there are the same number of scores smaller and larger than it. + +Find the completion string for each incomplete line, score the completion strings, and sort the scores. What is the middle score? + + diff --git a/2021/Day10/input.in b/2021/Day10/input.in index dd0e3ff58..adeda779e 100644 Binary files a/2021/Day10/input.in and b/2021/Day10/input.in differ diff --git a/2021/Day11/README.md b/2021/Day11/README.md index f8375dbd7..9f8648643 100644 --- a/2021/Day11/README.md +++ b/2021/Day11/README.md @@ -1,6 +1,363 @@ +original source: [https://adventofcode.com/2021/day/11](https://adventofcode.com/2021/day/11) ## --- Day 11: Dumbo Octopus --- You enter a large cavern full of rare bioluminescent [dumbo octopuses](https://www.youtube.com/watch?v=eih-VSaS2g0)! They seem to not like the Christmas lights on your submarine, so you turn them off for now. There are 100 octopuses arranged neatly in a 10 by 10 grid. Each octopus slowly gains energy over time and flashes brightly for a moment when its energy is full. Although your lights are off, maybe you could navigate through the cave without disturbing the octopuses if you could predict when the flashes of light will happen. -Read the [full puzzle](https://adventofcode.com/2021/day/11). \ No newline at end of file +Each octopus has an energy level - your submarine can remotely measure the energy level of each octopus (your puzzle input). For example: + +
+5483143223
+2745854711
+5264556173
+6141336146
+6357385478
+4167524645
+2176841721
+6882881134
+4846848554
+5283751526
+
+
+ +The energy level of each octopus is a value between 0 and 9. Here, the top-left octopus has an energy level of 5, the bottom-right one has an energy level of 6, and so on. + +You can model the energy levels and flashes of light in steps. During a single step, the following occurs: + + + - First, the energy level of each octopus increases by 1. + - Then, any octopus with an energy level greater than 9 flashes. This increases the energy level of all adjacent octopuses by 1, including octopuses that are diagonally adjacent. If this causes an octopus to have an energy level greater than 9, it also flashes. This process continues as long as new octopuses keep having their energy level increased beyond 9. (An octopus can only flash at most once per step.) + - Finally, any octopus that flashed during this step has its energy level set to 0, as it used all of its energy to flash. + +Adjacent flashes can cause an octopus to flash on a step even if it begins that step with very little energy. Consider the middle octopus with 1 energy in this situation: + +
+Before any steps:
+11111
+19991
+19191
+19991
+11111
+
+After step 1:
+34543
+40004
+50005
+40004
+34543
+
+After step 2:
+45654
+51115
+61116
+51115
+45654
+
+
+ +An octopus is highlighted when it flashed during the given step. + +Here is how the larger example above progresses: + +
+Before any steps:
+5483143223
+2745854711
+5264556173
+6141336146
+6357385478
+4167524645
+2176841721
+6882881134
+4846848554
+5283751526
+
+After step 1:
+6594254334
+3856965822
+6375667284
+7252447257
+7468496589
+5278635756
+3287952832
+7993992245
+5957959665
+6394862637
+
+After step 2:
+8807476555
+5089087054
+8597889608
+8485769600
+8700908800
+6600088989
+6800005943
+0000007456
+9000000876
+8700006848
+
+After step 3:
+0050900866
+8500800575
+9900000039
+9700000041
+9935080063
+7712300000
+7911250009
+2211130000
+0421125000
+0021119000
+
+After step 4:
+2263031977
+0923031697
+0032221150
+0041111163
+0076191174
+0053411122
+0042361120
+5532241122
+1532247211
+1132230211
+
+After step 5:
+4484144000
+2044144000
+2253333493
+1152333274
+1187303285
+1164633233
+1153472231
+6643352233
+2643358322
+2243341322
+
+After step 6:
+5595255111
+3155255222
+3364444605
+2263444496
+2298414396
+2275744344
+2264583342
+7754463344
+3754469433
+3354452433
+
+After step 7:
+6707366222
+4377366333
+4475555827
+3496655709
+3500625609
+3509955566
+3486694453
+8865585555
+4865580644
+4465574644
+
+After step 8:
+7818477333
+5488477444
+5697666949
+4608766830
+4734946730
+4740097688
+6900007564
+0000009666
+8000004755
+6800007755
+
+After step 9:
+9060000644
+7800000976
+6900000080
+5840000082
+5858000093
+6962400000
+8021250009
+2221130009
+9111128097
+7911119976
+
+After step 10:
+0481112976
+0031112009
+0041112504
+0081111406
+0099111306
+0093511233
+0442361130
+5532252350
+0532250600
+0032240000
+
+
+ + +After step 10, there have been a total of 204 flashes. Fast forwarding, here is the same configuration every 10 steps: + + +
+After step 20:
+3936556452
+5686556806
+4496555690
+4448655580
+4456865570
+5680086577
+7000009896
+0000000344
+6000000364
+4600009543
+
+After step 30:
+0643334118
+4253334611
+3374333458
+2225333337
+2229333338
+2276733333
+2754574565
+5544458511
+9444447111
+7944446119
+
+After step 40:
+6211111981
+0421111119
+0042111115
+0003111115
+0003111116
+0065611111
+0532351111
+3322234597
+2222222976
+2222222762
+
+After step 50:
+9655556447
+4865556805
+4486555690
+4458655580
+4574865570
+5700086566
+6000009887
+8000000533
+6800000633
+5680000538
+
+After step 60:
+2533334200
+2743334640
+2264333458
+2225333337
+2225333338
+2287833333
+3854573455
+1854458611
+1175447111
+1115446111
+
+After step 70:
+8211111164
+0421111166
+0042111114
+0004211115
+0000211116
+0065611111
+0532351111
+7322235117
+5722223475
+4572222754
+
+After step 80:
+1755555697
+5965555609
+4486555680
+4458655580
+4570865570
+5700086566
+7000008666
+0000000990
+0000000800
+0000000000
+
+After step 90:
+7433333522
+2643333522
+2264333458
+2226433337
+2222433338
+2287833333
+2854573333
+4854458333
+3387779333
+3333333333
+
+After step 100:
+0397666866
+0749766918
+0053976933
+0004297822
+0004229892
+0053222877
+0532222966
+9322228966
+7922286866
+6789998766
+
+
+ +After 100 steps, there have been a total of 1656 flashes. + +Given the starting energy levels of the dumbo octopuses in your cavern, simulate 100 steps. How many total flashes are there after 100 steps? + + +## --- Part Two --- +It seems like the individual flashes aren't bright enough to navigate. However, you might have a better option: the flashes seem to be synchronizing! + +In the example above, the first time all octopuses flash simultaneously is step 195: + +
+After step 193:
+5877777777
+8877777777
+7777777777
+7777777777
+7777777777
+7777777777
+7777777777
+7777777777
+7777777777
+7777777777
+
+After step 194:
+6988888888
+9988888888
+8888888888
+8888888888
+8888888888
+8888888888
+8888888888
+8888888888
+8888888888
+8888888888
+
+After step 195:
+0000000000
+0000000000
+0000000000
+0000000000
+0000000000
+0000000000
+0000000000
+0000000000
+0000000000
+0000000000
+
+
+ +If you can calculate the exact moments when the octopuses will all flash simultaneously, you should be able to navigate through the cavern. What is the first step during which all octopuses flash? + + diff --git a/2021/Day11/input.in b/2021/Day11/input.in index 6cb93ba2c..fc72e51cd 100644 Binary files a/2021/Day11/input.in and b/2021/Day11/input.in differ diff --git a/2021/Day12/README.md b/2021/Day12/README.md index 45761534a..71c778e5c 100644 --- a/2021/Day12/README.md +++ b/2021/Day12/README.md @@ -1,6 +1,170 @@ +original source: [https://adventofcode.com/2021/day/12](https://adventofcode.com/2021/day/12) ## --- Day 12: Passage Pathing --- With your submarine's subterranean subsystems subsisting suboptimally, the only way you're getting out of this cave anytime soon is by finding a path yourself. Not just a path - the only way to know if you've found the best path is to find all of them. Fortunately, the sensors are still mostly working, and so you build a rough map of the remaining caves (your puzzle input). For example: -Read the [full puzzle](https://adventofcode.com/2021/day/12). \ No newline at end of file +
+start-A
+start-b
+A-c
+A-b
+b-d
+A-end
+b-end
+
+
+ +This is a list of how all of the caves are connected. You start in the cave named start, and your destination is the cave named end. An entry like b-d means that cave b is connected to cave d - that is, you can move between them. + +So, the above cave system looks roughly like this: + +
+    start
+    /   \
+c--A-----b--d
+    \   /
+     end
+
+
+ +Your goal is to find the number of distinct paths that start at start, end at end, and don't visit small caves more than once. There are two types of caves: big caves (written in uppercase, like A) and small caves (written in lowercase, like b). It would be a waste of time to visit any small cave more than once, but big caves are large enough that it might be worth visiting them multiple times. So, all paths you find should visit small caves at most once, and can visit big caves any number of times. + +Given these rules, there are 10 paths through this example cave system: + +
+start,A,b,A,c,A,end
+start,A,b,A,end
+start,A,b,end
+start,A,c,A,b,A,end
+start,A,c,A,b,end
+start,A,c,A,end
+start,A,end
+start,b,A,c,A,end
+start,b,A,end
+start,b,end
+
+
+ +(Each line in the above list corresponds to a single path; the caves visited by that path are listed in the order they are visited and separated by commas.) + +Note that in this cave system, cave d is never visited by any path: to do so, cave b would need to be visited twice (once on the way to cave d and a second time when returning from cave d), and since cave b is small, this is not allowed. + +Here is a slightly larger example: + +
+dc-end
+HN-start
+start-kj
+dc-start
+dc-HN
+LN-dc
+HN-end
+kj-sa
+kj-HN
+kj-dc
+
+
+ +The 19 paths through it are as follows: + +
+start,HN,dc,HN,end
+start,HN,dc,HN,kj,HN,end
+start,HN,dc,end
+start,HN,dc,kj,HN,end
+start,HN,end
+start,HN,kj,HN,dc,HN,end
+start,HN,kj,HN,dc,end
+start,HN,kj,HN,end
+start,HN,kj,dc,HN,end
+start,HN,kj,dc,end
+start,dc,HN,end
+start,dc,HN,kj,HN,end
+start,dc,end
+start,dc,kj,HN,end
+start,kj,HN,dc,HN,end
+start,kj,HN,dc,end
+start,kj,HN,end
+start,kj,dc,HN,end
+start,kj,dc,end
+
+
+ +Finally, this even larger example has 226 paths through it: + +
+fs-end
+he-DX
+fs-he
+start-DX
+pj-DX
+end-zg
+zg-sl
+zg-pj
+pj-he
+RW-he
+fs-DX
+pj-RW
+zg-RW
+start-pj
+he-WI
+zg-he
+pj-fs
+start-RW
+
+
+ +How many paths through this cave system are there that visit small caves at most once? + + +## --- Part Two --- +After reviewing the available paths, you realize you might have time to visit a single small cave twice. Specifically, big caves can be visited any number of times, a single small cave can be visited at most twice, and the remaining small caves can be visited at most once. However, the caves named start and end can only be visited exactly once each: once you leave the start cave, you may not return to it, and once you reach the end cave, the path must end immediately. + +Now, the 36 possible paths through the first example above are: + +
+start,A,b,A,b,A,c,A,end
+start,A,b,A,b,A,end
+start,A,b,A,b,end
+start,A,b,A,c,A,b,A,end
+start,A,b,A,c,A,b,end
+start,A,b,A,c,A,c,A,end
+start,A,b,A,c,A,end
+start,A,b,A,end
+start,A,b,d,b,A,c,A,end
+start,A,b,d,b,A,end
+start,A,b,d,b,end
+start,A,b,end
+start,A,c,A,b,A,b,A,end
+start,A,c,A,b,A,b,end
+start,A,c,A,b,A,c,A,end
+start,A,c,A,b,A,end
+start,A,c,A,b,d,b,A,end
+start,A,c,A,b,d,b,end
+start,A,c,A,b,end
+start,A,c,A,c,A,b,A,end
+start,A,c,A,c,A,b,end
+start,A,c,A,c,A,end
+start,A,c,A,end
+start,A,end
+start,b,A,b,A,c,A,end
+start,b,A,b,A,end
+start,b,A,b,end
+start,b,A,c,A,b,A,end
+start,b,A,c,A,b,end
+start,b,A,c,A,c,A,end
+start,b,A,c,A,end
+start,b,A,end
+start,b,d,b,A,c,A,end
+start,b,d,b,A,end
+start,b,d,b,end
+start,b,end
+
+
+ +The slightly larger example above now has 103 paths through it, and the even larger example now has 3509 paths through it. + +Given these new rules, how many paths through this cave system are there? + + diff --git a/2021/Day12/input.in b/2021/Day12/input.in index 55154692f..bc8429c26 100644 Binary files a/2021/Day12/input.in and b/2021/Day12/input.in differ diff --git a/2021/Day13/README.md b/2021/Day13/README.md index 15367b70b..72b79da08 100644 --- a/2021/Day13/README.md +++ b/2021/Day13/README.md @@ -1,6 +1,139 @@ +original source: [https://adventofcode.com/2021/day/13](https://adventofcode.com/2021/day/13) ## --- Day 13: Transparent Origami --- You reach another volcanically active part of the cave. It would be nice if you could do some kind of thermal imaging so you could tell ahead of time which caves are too hot to safely enter. Fortunately, the submarine seems to be equipped with a thermal camera! When you activate it, you are greeted with: -Read the [full puzzle](https://adventofcode.com/2021/day/13). \ No newline at end of file +
+Congratulations on your purchase! To activate this infrared thermal imaging
+camera system, please enter the code found on page 1 of the manual.
+
+
+ +Apparently, the Elves have never used this feature. To your surprise, you manage to find the manual; as you go to open it, page 1 falls out. It's a large sheet of [transparent paper](https://en.wikipedia.org/wiki/Transparency_(projection))! The transparent paper is marked with random dots and includes instructions on how to fold it up (your puzzle input). For example: + +
+6,10
+0,14
+9,10
+0,3
+10,4
+4,11
+6,0
+6,12
+4,1
+0,13
+10,12
+3,4
+3,0
+8,4
+1,10
+2,14
+8,10
+9,0
+
+fold along y=7
+fold along x=5
+
+
+ +The first section is a list of dots on the transparent paper. 0,0 represents the top-left coordinate. The first value, x, increases to the right. The second value, y, increases downward. So, the coordinate 3,0 is to the right of 0,0, and the coordinate 0,7 is below 0,0. The coordinates in this example form the following pattern, where # is a dot on the paper and . is an empty, unmarked position: + +
+...#..#..#.
+....#......
+...........
+#..........
+...#....#.#
+...........
+...........
+...........
+...........
+...........
+.#....#.##.
+....#......
+......#...#
+#..........
+#.#........
+
+
+ +Then, there is a list of fold instructions. Each instruction indicates a line on the transparent paper and wants you to fold the paper up (for horizontal y=... lines) or left (for vertical x=... lines). In this example, the first fold instruction is fold along y=7, which designates the line formed by all of the positions where y is 7 (marked here with -): + +
+...#..#..#.
+....#......
+...........
+#..........
+...#....#.#
+...........
+...........
+-----------
+...........
+...........
+.#....#.##.
+....#......
+......#...#
+#..........
+#.#........
+
+
+ +Because this is a horizontal line, fold the bottom half up. Some of the dots might end up overlapping after the fold is complete, but dots will never appear exactly on a fold line. The result of doing this fold looks like this: + +
+#.##..#..#.
+#...#......
+......#...#
+#...#......
+.#.#..#.###
+...........
+...........
+
+
+ +Now, only 17 dots are visible. + +Notice, for example, the two dots in the bottom left corner before the transparent paper is folded; after the fold is complete, those dots appear in the top left corner (at 0,0 and 0,1). Because the paper is transparent, the dot just below them in the result (at 0,3) remains visible, as it can be seen through the transparent paper. + +Also notice that some dots can end up overlapping; in this case, the dots merge together and become a single dot. + +The second fold instruction is fold along x=5, which indicates this line: + +
+#.##.|#..#.
+#...#|.....
+.....|#...#
+#...#|.....
+.#.#.|#.###
+.....|.....
+.....|.....
+
+
+ +Because this is a vertical line, fold left: + +
+#####
+#...#
+#...#
+#...#
+#####
+.....
+.....
+
+
+ +The instructions made a square! + +The transparent paper is pretty big, so for now, focus on just completing the first fold. After the first fold in the example above, 17 dots are visible - dots that end up overlapping after the fold is completed count as a single dot. + +How many dots are visible after completing just the first fold instruction on your transparent paper? + + +## --- Part Two --- +Finish folding the transparent paper according to the instructions. The manual says the code is always eight capital letters. + +What code do you use to activate the infrared thermal imaging camera system? + + diff --git a/2021/Day13/input.in b/2021/Day13/input.in index f942127fe..21702d0ec 100644 Binary files a/2021/Day13/input.in and b/2021/Day13/input.in differ diff --git a/2021/Day14/README.md b/2021/Day14/README.md index 8c52bcfe8..ab6d0d6a3 100644 --- a/2021/Day14/README.md +++ b/2021/Day14/README.md @@ -1,6 +1,69 @@ +original source: [https://adventofcode.com/2021/day/14](https://adventofcode.com/2021/day/14) ## --- Day 14: Extended Polymerization --- The incredible pressures at this depth are starting to put a strain on your submarine. The submarine has [polymerization](https://en.wikipedia.org/wiki/Polymerization) equipment that would produce suitable materials to reinforce the submarine, and the nearby volcanically-active caves should even have the necessary input elements in sufficient quantities. The submarine manual contains instructions for finding the optimal polymer formula; specifically, it offers a polymer template and a list of pair insertion rules (your puzzle input). You just need to work out what polymer would result after repeating the pair insertion process a few times. -Read the [full puzzle](https://adventofcode.com/2021/day/14). \ No newline at end of file +For example: + +
+NNCB
+
+CH -> B
+HH -> N
+CB -> H
+NH -> C
+HB -> C
+HC -> B
+HN -> C
+NN -> C
+BH -> H
+NC -> B
+NB -> B
+BN -> B
+BB -> N
+BC -> B
+CC -> N
+CN -> C
+
+
+ +The first line is the polymer template - this is the starting point of the process. + +The following section defines the pair insertion rules. A rule like AB -> C means that when elements A and B are immediately adjacent, element C should be inserted between them. These insertions all happen simultaneously. + +So, starting with the polymer template NNCB, the first step simultaneously considers all three pairs: + + + - The first pair (NN) matches the rule NN -> C, so element C is inserted between the first N and the second N. + - The second pair (NC) matches the rule NC -> B, so element B is inserted between the N and the C. + - The third pair (CB) matches the rule CB -> H, so element H is inserted between the C and the B. + +Note that these pairs overlap: the second element of one pair is the first element of the next pair. Also, because all pairs are considered simultaneously, inserted elements are not considered to be part of a pair until the next step. + +After the first step of this process, the polymer becomes NCNBCHB. + +Here are the results of a few steps using the above rules: + +
+Template:     NNCB
+After step 1: NCNBCHB
+After step 2: NBCCNBBBCBHCB
+After step 3: NBBBCNCCNBBNBNBBCHBHHBCHB
+After step 4: NBBNBNBBCCNBCNCCNBBNBBNBBBNBBNBBCBHCBHHNHCBBCBHCB
+
+
+ +This polymer grows quickly. After step 5, it has length 97; After step 10, it has length 3073. After step 10, B occurs 1749 times, C occurs 298 times, H occurs 161 times, and N occurs 865 times; taking the quantity of the most common element (B, 1749) and subtracting the quantity of the least common element (H, 161) produces 1749 - 161 = 1588. + +Apply 10 steps of pair insertion to the polymer template and find the most and least common elements in the result. What do you get if you take the quantity of the most common element and subtract the quantity of the least common element? + + +## --- Part Two --- +The resulting polymer isn't nearly strong enough to reinforce the submarine. You'll need to run more steps of the pair insertion process; a total of 40 steps should do it. + +In the above example, the most common element is B (occurring 2192039569602 times) and the least common element is H (occurring 3849876073 times); subtracting these produces 2188189693529. + +Apply 40 steps of pair insertion to the polymer template and find the most and least common elements in the result. What do you get if you take the quantity of the most common element and subtract the quantity of the least common element? + + diff --git a/2021/Day14/input.in b/2021/Day14/input.in index 1998430c7..b72378938 100644 Binary files a/2021/Day14/input.in and b/2021/Day14/input.in differ diff --git a/2021/Day15/README.md b/2021/Day15/README.md index 6093959ce..2be636b1b 100644 --- a/2021/Day15/README.md +++ b/2021/Day15/README.md @@ -1,6 +1,176 @@ +original source: [https://adventofcode.com/2021/day/15](https://adventofcode.com/2021/day/15) ## --- Day 15: Chiton --- You've almost reached the exit of the cave, but the walls are getting closer together. Your submarine can barely still fit, though; the main problem is that the walls of the cave are covered in [chitons](https://en.wikipedia.org/wiki/Chiton), and it would be best not to bump any of them. The cavern is large, but has a very low ceiling, restricting your motion to two dimensions. The shape of the cavern resembles a square; a quick scan of chiton density produces a map of risk level throughout the cave (your puzzle input). For example: -Read the [full puzzle](https://adventofcode.com/2021/day/15). \ No newline at end of file +
+1163751742
+1381373672
+2136511328
+3694931569
+7463417111
+1319128137
+1359912421
+3125421639
+1293138521
+2311944581
+
+
+ +You start in the top left position, your destination is the bottom right position, and you cannot move diagonally. The number at each position is its risk level; to determine the total risk of an entire path, add up the risk levels of each position you enter (that is, don't count the risk level of your starting position unless you enter it; leaving it adds no risk to your total). + +Your goal is to find a path with the lowest total risk. In this example, a path with the lowest total risk is highlighted here: + +
+1163751742
+1381373672
+2136511328
+3694931569
+7463417111
+1319128137
+1359912421
+3125421639
+1293138521
+2311944581
+
+
+ +The total risk of this path is 40 (the starting position is never entered, so its risk is not counted). + +What is the lowest total risk of any path from the top left to the bottom right? + + +## --- Part Two --- +Now that you know how to find low-risk paths in the cave, you can try to find your way out. + +The entire cave is actually five times larger in both dimensions than you thought; the area you originally scanned is just one tile in a 5x5 tile area that forms the full map. Your original map tile repeats to the right and downward; each time the tile repeats to the right or downward, all of its risk levels are 1 higher than the tile immediately up or left of it. However, risk levels above 9 wrap back around to 1. So, if your original map had some position with a risk level of 8, then that same position on each of the 25 total tiles would be as follows: + +
+8 9 1 2 3
+9 1 2 3 4
+1 2 3 4 5
+2 3 4 5 6
+3 4 5 6 7
+
+
+ +Each single digit above corresponds to the example position with a value of 8 on the top-left tile. Because the full map is actually five times larger in both dimensions, that position appears a total of 25 times, once in each duplicated tile, with the values shown above. + +Here is the full five-times-as-large version of the first example above, with the original map in the top left corner highlighted: + +
+11637517422274862853338597396444961841755517295286
+13813736722492484783351359589446246169155735727126
+21365113283247622439435873354154698446526571955763
+36949315694715142671582625378269373648937148475914
+74634171118574528222968563933317967414442817852555
+13191281372421239248353234135946434524615754563572
+13599124212461123532357223464346833457545794456865
+31254216394236532741534764385264587549637569865174
+12931385212314249632342535174345364628545647573965
+23119445813422155692453326671356443778246755488935
+22748628533385973964449618417555172952866628316397
+24924847833513595894462461691557357271266846838237
+32476224394358733541546984465265719557637682166874
+47151426715826253782693736489371484759148259586125
+85745282229685639333179674144428178525553928963666
+24212392483532341359464345246157545635726865674683
+24611235323572234643468334575457944568656815567976
+42365327415347643852645875496375698651748671976285
+23142496323425351743453646285456475739656758684176
+34221556924533266713564437782467554889357866599146
+33859739644496184175551729528666283163977739427418
+35135958944624616915573572712668468382377957949348
+43587335415469844652657195576376821668748793277985
+58262537826937364893714847591482595861259361697236
+96856393331796741444281785255539289636664139174777
+35323413594643452461575456357268656746837976785794
+35722346434683345754579445686568155679767926678187
+53476438526458754963756986517486719762859782187396
+34253517434536462854564757396567586841767869795287
+45332667135644377824675548893578665991468977611257
+44961841755517295286662831639777394274188841538529
+46246169155735727126684683823779579493488168151459
+54698446526571955763768216687487932779859814388196
+69373648937148475914825958612593616972361472718347
+17967414442817852555392896366641391747775241285888
+46434524615754563572686567468379767857948187896815
+46833457545794456865681556797679266781878137789298
+64587549637569865174867197628597821873961893298417
+45364628545647573965675868417678697952878971816398
+56443778246755488935786659914689776112579188722368
+55172952866628316397773942741888415385299952649631
+57357271266846838237795794934881681514599279262561
+65719557637682166874879327798598143881961925499217
+71484759148259586125936169723614727183472583829458
+28178525553928963666413917477752412858886352396999
+57545635726865674683797678579481878968159298917926
+57944568656815567976792667818781377892989248891319
+75698651748671976285978218739618932984172914319528
+56475739656758684176786979528789718163989182927419
+67554889357866599146897761125791887223681299833479
+
+
+ +Equipped with the full map, you can now find a path from the top left corner to the bottom right corner with the lowest total risk: + +
+11637517422274862853338597396444961841755517295286
+13813736722492484783351359589446246169155735727126
+21365113283247622439435873354154698446526571955763
+36949315694715142671582625378269373648937148475914
+74634171118574528222968563933317967414442817852555
+13191281372421239248353234135946434524615754563572
+13599124212461123532357223464346833457545794456865
+31254216394236532741534764385264587549637569865174
+12931385212314249632342535174345364628545647573965
+23119445813422155692453326671356443778246755488935
+22748628533385973964449618417555172952866628316397
+24924847833513595894462461691557357271266846838237
+32476224394358733541546984465265719557637682166874
+47151426715826253782693736489371484759148259586125
+85745282229685639333179674144428178525553928963666
+24212392483532341359464345246157545635726865674683
+24611235323572234643468334575457944568656815567976
+42365327415347643852645875496375698651748671976285
+23142496323425351743453646285456475739656758684176
+34221556924533266713564437782467554889357866599146
+33859739644496184175551729528666283163977739427418
+35135958944624616915573572712668468382377957949348
+43587335415469844652657195576376821668748793277985
+58262537826937364893714847591482595861259361697236
+96856393331796741444281785255539289636664139174777
+35323413594643452461575456357268656746837976785794
+35722346434683345754579445686568155679767926678187
+53476438526458754963756986517486719762859782187396
+34253517434536462854564757396567586841767869795287
+45332667135644377824675548893578665991468977611257
+44961841755517295286662831639777394274188841538529
+46246169155735727126684683823779579493488168151459
+54698446526571955763768216687487932779859814388196
+69373648937148475914825958612593616972361472718347
+17967414442817852555392896366641391747775241285888
+46434524615754563572686567468379767857948187896815
+46833457545794456865681556797679266781878137789298
+64587549637569865174867197628597821873961893298417
+45364628545647573965675868417678697952878971816398
+56443778246755488935786659914689776112579188722368
+55172952866628316397773942741888415385299952649631
+57357271266846838237795794934881681514599279262561
+65719557637682166874879327798598143881961925499217
+71484759148259586125936169723614727183472583829458
+28178525553928963666413917477752412858886352396999
+57545635726865674683797678579481878968159298917926
+57944568656815567976792667818781377892989248891319
+75698651748671976285978218739618932984172914319528
+56475739656758684176786979528789718163989182927419
+67554889357866599146897761125791887223681299833479
+
+
+ +The total risk of this path is 315 (the starting position is still never entered, so its risk is not counted). + +Using the full map, what is the lowest total risk of any path from the top left to the bottom right? + + diff --git a/2021/Day15/input.in b/2021/Day15/input.in index f73b0e2ab..71eeceda1 100644 Binary files a/2021/Day15/input.in and b/2021/Day15/input.in differ diff --git a/2021/Day16/README.md b/2021/Day16/README.md index a3b16b0be..34e110135 100644 --- a/2021/Day16/README.md +++ b/2021/Day16/README.md @@ -1,6 +1,143 @@ +original source: [https://adventofcode.com/2021/day/16](https://adventofcode.com/2021/day/16) ## --- Day 16: Packet Decoder --- As you leave the cave and reach open waters, you receive a transmission from the Elves back on the ship. The transmission was sent using the Buoyancy Interchange Transmission System (BITS), a method of packing numeric expressions into a binary sequence. Your submarine's computer has saved the transmission in [hexadecimal](https://en.wikipedia.org/wiki/Hexadecimal) (your puzzle input). -Read the [full puzzle](https://adventofcode.com/2021/day/16). \ No newline at end of file +The first step of decoding the message is to convert the hexadecimal representation into binary. Each character of hexadecimal corresponds to four bits of binary data: + +
+0 = 0000
+1 = 0001
+2 = 0010
+3 = 0011
+4 = 0100
+5 = 0101
+6 = 0110
+7 = 0111
+8 = 1000
+9 = 1001
+A = 1010
+B = 1011
+C = 1100
+D = 1101
+E = 1110
+F = 1111
+
+
+ +The BITS transmission contains a single packet at its outermost layer which itself contains many other packets. The hexadecimal representation of this packet might encode a few extra 0 bits at the end; these are not part of the transmission and should be ignored. + +Every packet begins with a standard header: the first three bits encode the packet version, and the next three bits encode the packet type ID. These two values are numbers; all numbers encoded in any packet are represented as binary with the most significant bit first. For example, a version encoded as the binary sequence 100 represents the number 4. + +Packets with type ID 4 represent a literal value. Literal value packets encode a single binary number. To do this, the binary number is padded with leading zeroes until its length is a multiple of four bits, and then it is broken into groups of four bits. Each group is prefixed by a 1 bit except the last group, which is prefixed by a 0 bit. These groups of five bits immediately follow the packet header. For example, the hexadecimal string D2FE28 becomes: + +
+110100101111111000101000
+VVVTTTAAAAABBBBBCCCCC
+
+
+ +Below each bit is a label indicating its purpose: + + + - The three bits labeled V (110) are the packet version, 6. + - The three bits labeled T (100) are the packet type ID, 4, which means the packet is a literal value. + - The five bits labeled A (10111) start with a 1 (not the last group, keep reading) and contain the first four bits of the number, 0111. + - The five bits labeled B (11110) start with a 1 (not the last group, keep reading) and contain four more bits of the number, 1110. + - The five bits labeled C (00101) start with a 0 (last group, end of packet) and contain the last four bits of the number, 0101. + - The three unlabeled 0 bits at the end are extra due to the hexadecimal representation and should be ignored. + +So, this packet represents a literal value with binary representation 011111100101, which is 2021 in decimal. + +Every other type of packet (any packet with a type ID other than 4) represent an operator that performs some calculation on one or more sub-packets contained within. Right now, the specific operations aren't important; focus on parsing the hierarchy of sub-packets. + +An operator packet contains one or more packets. To indicate which subsequent binary data represents its sub-packets, an operator packet can use one of two modes indicated by the bit immediately after the packet header; this is called the length type ID: + + + - If the length type ID is 0, then the next 15 bits are a number that represents the total length in bits of the sub-packets contained by this packet. + - If the length type ID is 1, then the next 11 bits are a number that represents the number of sub-packets immediately contained by this packet. + +Finally, after the length type ID bit and the 15-bit or 11-bit field, the sub-packets appear. + +For example, here is an operator packet (hexadecimal string 38006F45291200) with length type ID 0 that contains two sub-packets: + +
+00111000000000000110111101000101001010010001001000000000
+VVVTTTILLLLLLLLLLLLLLLAAAAAAAAAAABBBBBBBBBBBBBBBB
+
+
+ + + - The three bits labeled V (001) are the packet version, 1. + - The three bits labeled T (110) are the packet type ID, 6, which means the packet is an operator. + - The bit labeled I (0) is the length type ID, which indicates that the length is a 15-bit number representing the number of bits in the sub-packets. + - The 15 bits labeled L (000000000011011) contain the length of the sub-packets in bits, 27. + - The 11 bits labeled A contain the first sub-packet, a literal value representing the number 10. + - The 16 bits labeled B contain the second sub-packet, a literal value representing the number 20. + +After reading 11 and 16 bits of sub-packet data, the total length indicated in L (27) is reached, and so parsing of this packet stops. + +As another example, here is an operator packet (hexadecimal string EE00D40C823060) with length type ID 1 that contains three sub-packets: + +
+11101110000000001101010000001100100000100011000001100000
+VVVTTTILLLLLLLLLLLAAAAAAAAAAABBBBBBBBBBBCCCCCCCCCCC
+
+
+ + + - The three bits labeled V (111) are the packet version, 7. + - The three bits labeled T (011) are the packet type ID, 3, which means the packet is an operator. + - The bit labeled I (1) is the length type ID, which indicates that the length is a 11-bit number representing the number of sub-packets. + - The 11 bits labeled L (00000000011) contain the number of sub-packets, 3. + - The 11 bits labeled A contain the first sub-packet, a literal value representing the number 1. + - The 11 bits labeled B contain the second sub-packet, a literal value representing the number 2. + - The 11 bits labeled C contain the third sub-packet, a literal value representing the number 3. + +After reading 3 complete sub-packets, the number of sub-packets indicated in L (3) is reached, and so parsing of this packet stops. + +For now, parse the hierarchy of the packets throughout the transmission and add up all of the version numbers. + +Here are a few more examples of hexadecimal-encoded transmissions: + + + - 8A004A801A8002F478 represents an operator packet (version 4) which contains an operator packet (version 1) which contains an operator packet (version 5) which contains a literal value (version 6); this packet has a version sum of 16. + - 620080001611562C8802118E34 represents an operator packet (version 3) which contains two sub-packets; each sub-packet is an operator packet that contains two literal values. This packet has a version sum of 12. + - C0015000016115A2E0802F182340 has the same structure as the previous example, but the outermost packet uses a different length type ID. This packet has a version sum of 23. + - A0016C880162017C3686B18A3D4780 is an operator packet that contains an operator packet that contains an operator packet that contains five literal values; it has a version sum of 31. + +Decode the structure of your hexadecimal-encoded BITS transmission; what do you get if you add up the version numbers in all packets? + + +## --- Part Two --- +Now that you have the structure of your transmission decoded, you can calculate the value of the expression it represents. + +Literal values (type ID 4) represent a single number as described above. The remaining type IDs are more interesting: + + + - Packets with type ID 0 are sum packets - their value is the sum of the values of their sub-packets. If they only have a single sub-packet, their value is the value of the sub-packet. + - Packets with type ID 1 are product packets - their value is the result of multiplying together the values of their sub-packets. If they only have a single sub-packet, their value is the value of the sub-packet. + - Packets with type ID 2 are minimum packets - their value is the minimum of the values of their sub-packets. + - Packets with type ID 3 are maximum packets - their value is the maximum of the values of their sub-packets. + - Packets with type ID 5 are greater than packets - their value is 1 if the value of the first sub-packet is greater than the value of the second sub-packet; otherwise, their value is 0. These packets always have exactly two sub-packets. + - Packets with type ID 6 are less than packets - their value is 1 if the value of the first sub-packet is less than the value of the second sub-packet; otherwise, their value is 0. These packets always have exactly two sub-packets. + - Packets with type ID 7 are equal to packets - their value is 1 if the value of the first sub-packet is equal to the value of the second sub-packet; otherwise, their value is 0. These packets always have exactly two sub-packets. + +Using these rules, you can now work out the value of the outermost packet in your BITS transmission. + +For example: + + + - C200B40A82 finds the sum of 1 and 2, resulting in the value 3. + - 04005AC33890 finds the product of 6 and 9, resulting in the value 54. + - 880086C3E88112 finds the minimum of 7, 8, and 9, resulting in the value 7. + - CE00C43D881120 finds the maximum of 7, 8, and 9, resulting in the value 9. + - D8005AC2A8F0 produces 1, because 5 is less than 15. + - F600BC2D8F produces 0, because 5 is not greater than 15. + - 9C005AC2F8F0 produces 0, because 5 is not equal to 15. + - 9C0141080250320F1802104A08 produces 1, because 1 + 3 = 2 * 2. + +What do you get if you evaluate the expression represented by your hexadecimal-encoded BITS transmission? + + diff --git a/2021/Day16/Solution.cs b/2021/Day16/Solution.cs index 9bf73b3ef..d401121ed 100644 --- a/2021/Day16/Solution.cs +++ b/2021/Day16/Solution.cs @@ -20,7 +20,6 @@ int GetTotalVersion(Packet packet) => // recursively evaluate the packet and its contents based on the type tag for part 2: long Evaluate(Packet packet) { - var parts = packet.packets.Select(Evaluate).ToArray(); return packet.type switch { 0 => parts.Sum(), diff --git a/2021/Day16/input.in b/2021/Day16/input.in index a243b333d..36cb0f5f7 100644 Binary files a/2021/Day16/input.in and b/2021/Day16/input.in differ diff --git a/2021/Day17/README.md b/2021/Day17/README.md index 52983df0e..335d0cd72 100644 --- a/2021/Day17/README.md +++ b/2021/Day17/README.md @@ -1,6 +1,151 @@ +original source: [https://adventofcode.com/2021/day/17](https://adventofcode.com/2021/day/17) ## --- Day 17: Trick Shot --- You finally decode the Elves' message. HI, the message says. You continue searching for the sleigh keys. Ahead of you is what appears to be a large [ocean trench](https://en.wikipedia.org/wiki/Oceanic_trench). Could the keys have fallen into it? You'd better send a probe to investigate. -Read the [full puzzle](https://adventofcode.com/2021/day/17). \ No newline at end of file +The probe launcher on your submarine can fire the probe with any [integer](https://en.wikipedia.org/wiki/Integer) velocity in the x (forward) and y (upward, or downward if negative) directions. For example, an initial x,y velocity like 0,10 would fire the probe straight up, while an initial velocity like 10,-1 would fire the probe forward at a slight downward angle. + +The probe's x,y position starts at 0,0. Then, it will follow some trajectory by moving in steps. On each step, these changes occur in the following order: + + + - The probe's x position increases by its x velocity. + - The probe's y position increases by its y velocity. + - Due to drag, the probe's x velocity changes by 1 toward the value 0; that is, it decreases by 1 if it is greater than 0, increases by 1 if it is less than 0, or does not change if it is already 0. + - Due to gravity, the probe's y velocity decreases by 1. + +For the probe to successfully make it into the trench, the probe must be on some trajectory that causes it to be within a target area after any step. The submarine computer has already calculated this target area (your puzzle input). For example: + +
+target area: x=20..30, y=-10..-5
+
+ +This target area means that you need to find initial x,y velocity values such that after any step, the probe's x position is at least 20 and at most 30, and the probe's y position is at least -10 and at most -5. + +Given this target area, one initial velocity that causes the probe to be within the target area after any step is 7,2: + +
+.............#....#............
+.......#..............#........
+...............................
+S........................#.....
+...............................
+...............................
+...........................#...
+...............................
+....................TTTTTTTTTTT
+....................TTTTTTTTTTT
+....................TTTTTTTT#TT
+....................TTTTTTTTTTT
+....................TTTTTTTTTTT
+....................TTTTTTTTTTT
+
+
+ +In this diagram, S is the probe's initial position, 0,0. The x coordinate increases to the right, and the y coordinate increases upward. In the bottom right, positions that are within the target area are shown as T. After each step (until the target area is reached), the position of the probe is marked with #. (The bottom-right # is both a position the probe reaches and a position in the target area.) + +Another initial velocity that causes the probe to be within the target area after any step is 6,3: + +
+...............#..#............
+...........#........#..........
+...............................
+......#..............#.........
+...............................
+...............................
+S....................#.........
+...............................
+...............................
+...............................
+.....................#.........
+....................TTTTTTTTTTT
+....................TTTTTTTTTTT
+....................TTTTTTTTTTT
+....................TTTTTTTTTTT
+....................T#TTTTTTTTT
+....................TTTTTTTTTTT
+
+
+ +Another one is 9,0: + +
+S........#.....................
+.................#.............
+...............................
+........................#......
+...............................
+....................TTTTTTTTTTT
+....................TTTTTTTTTT#
+....................TTTTTTTTTTT
+....................TTTTTTTTTTT
+....................TTTTTTTTTTT
+....................TTTTTTTTTTT
+
+
+ +One initial velocity that doesn't cause the probe to be within the target area after any step is 17,-4: + +
+S..............................................................
+...............................................................
+...............................................................
+...............................................................
+.................#.............................................
+....................TTTTTTTTTTT................................
+....................TTTTTTTTTTT................................
+....................TTTTTTTTTTT................................
+....................TTTTTTTTTTT................................
+....................TTTTTTTTTTT..#.............................
+....................TTTTTTTTTTT................................
+...............................................................
+...............................................................
+...............................................................
+...............................................................
+................................................#..............
+...............................................................
+...............................................................
+...............................................................
+...............................................................
+...............................................................
+...............................................................
+..............................................................#
+
+
+ +The probe appears to pass through the target area, but is never within it after any step. Instead, it continues down and to the right - only the first few steps are shown. + +If you're going to fire a highly scientific probe out of a super cool probe launcher, you might as well do it with style. How high can you make the probe go while still reaching the target area? + +In the above example, using an initial velocity of 6,9 is the best you can do, causing the probe to reach a maximum y position of 45. (Any higher initial y velocity causes the probe to overshoot the target area entirely.) + +Find the initial velocity that causes the probe to reach the highest y position and still eventually be within the target area after any step. What is the highest y position it reaches on this trajectory? + + +## --- Part Two --- +Maybe a fancy trick shot isn't the best idea; after all, you only have one probe, so you had better not miss. + +To get the best idea of what your options are for launching the probe, you need to find every initial velocity that causes the probe to eventually be within the target area after any step. + +In the above example, there are 112 different initial velocity values that meet these criteria: + +
+23,-10  25,-9   27,-5   29,-6   22,-6   21,-7   9,0     27,-7   24,-5
+25,-7   26,-6   25,-5   6,8     11,-2   20,-5   29,-10  6,3     28,-7
+8,0     30,-6   29,-8   20,-10  6,7     6,4     6,1     14,-4   21,-6
+26,-10  7,-1    7,7     8,-1    21,-9   6,2     20,-7   30,-10  14,-3
+20,-8   13,-2   7,3     28,-8   29,-9   15,-3   22,-5   26,-8   25,-8
+25,-6   15,-4   9,-2    15,-2   12,-2   28,-9   12,-3   24,-6   23,-7
+25,-10  7,8     11,-3   26,-7   7,1     23,-9   6,0     22,-10  27,-6
+8,1     22,-8   13,-4   7,6     28,-6   11,-4   12,-4   26,-9   7,4
+24,-10  23,-8   30,-8   7,0     9,-1    10,-1   26,-5   22,-9   6,5
+7,5     23,-6   28,-10  10,-2   11,-1   20,-9   14,-2   29,-7   13,-3
+23,-5   24,-8   27,-9   30,-7   28,-5   21,-10  7,9     6,6     21,-5
+27,-10  7,2     30,-9   21,-8   22,-7   24,-9   20,-6   6,9     29,-5
+8,-2    27,-8   30,-5   24,-7
+
+
+ +How many distinct initial velocity values cause the probe to be within the target area after any step? + + diff --git a/2021/Day17/input.in b/2021/Day17/input.in index 430f4cb91..124287840 100644 Binary files a/2021/Day17/input.in and b/2021/Day17/input.in differ diff --git a/2021/Day18/README.md b/2021/Day18/README.md index 4a42b45bb..8147afdf4 100644 --- a/2021/Day18/README.md +++ b/2021/Day18/README.md @@ -1,6 +1,221 @@ +original source: [https://adventofcode.com/2021/day/18](https://adventofcode.com/2021/day/18) ## --- Day 18: Snailfish --- You descend into the ocean trench and encounter some [snailfish](https://en.wikipedia.org/wiki/Snailfish). They say they saw the sleigh keys! They'll even tell you which direction the keys went if you help one of the smaller snailfish with his math homework. Snailfish numbers aren't like regular numbers. Instead, every snailfish number is a pair - an ordered list of two elements. Each element of the pair can be either a regular number or another pair. -Read the [full puzzle](https://adventofcode.com/2021/day/18). \ No newline at end of file +Pairs are written as [x,y], where x and y are the elements within the pair. Here are some example snailfish numbers, one snailfish number per line: + +
+[1,2]
+[[1,2],3]
+[9,[8,7]]
+[[1,9],[8,5]]
+[[[[1,2],[3,4]],[[5,6],[7,8]]],9]
+[[[9,[3,8]],[[0,9],6]],[[[3,7],[4,9]],3]]
+[[[[1,3],[5,3]],[[1,3],[8,7]]],[[[4,9],[6,9]],[[8,2],[7,3]]]]
+
+
+ +This snailfish homework is about addition. To add two snailfish numbers, form a pair from the left and right parameters of the addition operator. For example, [1,2] + [[3,4],5] becomes [[1,2],[[3,4],5]]. + +There's only one problem: snailfish numbers must always be reduced, and the process of adding two snailfish numbers can result in snailfish numbers that need to be reduced. + +To reduce a snailfish number, you must repeatedly do the first action in this list that applies to the snailfish number: + + + - If any pair is nested inside four pairs, the leftmost such pair explodes. + - If any regular number is 10 or greater, the leftmost such regular number splits. + +Once no action in the above list applies, the snailfish number is reduced. + +During reduction, at most one action applies, after which the process returns to the top of the list of actions. For example, if split produces a pair that meets the explode criteria, that pair explodes before other splits occur. + +To explode a pair, the pair's left value is added to the first regular number to the left of the exploding pair (if any), and the pair's right value is added to the first regular number to the right of the exploding pair (if any). Exploding pairs will always consist of two regular numbers. Then, the entire exploding pair is replaced with the regular number 0. + +Here are some examples of a single explode action: + + + - [[[[[9,8],1],2],3],4] becomes [[[[0,9],2],3],4] (the 9 has no regular number to its left, so it is not added to any regular number). + - [7,[6,[5,[4,[3,2]]]]] becomes [7,[6,[5,[7,0]]]] (the 2 has no regular number to its right, and so it is not added to any regular number). + - [[6,[5,[4,[3,2]]]],1] becomes [[6,[5,[7,0]]],3]. + - [[3,[2,[1,[7,3]]]],[6,[5,[4,[3,2]]]]] becomes [[3,[2,[8,0]]],[9,[5,[4,[3,2]]]]] (the pair [3,2] is unaffected because the pair [7,3] is further to the left; [3,2] would explode on the next action). + - [[3,[2,[8,0]]],[9,[5,[4,[3,2]]]]] becomes [[3,[2,[8,0]]],[9,[5,[7,0]]]]. + +To split a regular number, replace it with a pair; the left element of the pair should be the regular number divided by two and rounded down, while the right element of the pair should be the regular number divided by two and rounded up. For example, 10 becomes [5,5], 11 becomes [5,6], 12 becomes [6,6], and so on. + +Here is the process of finding the reduced result of [[[[4,3],4],4],[7,[[8,4],9]]] + [1,1]: + +
+after addition: [[[[[4,3],4],4],[7,[[8,4],9]]],[1,1]]
+after explode:  [[[[0,7],4],[7,[[8,4],9]]],[1,1]]
+after explode:  [[[[0,7],4],[15,[0,13]]],[1,1]]
+after split:    [[[[0,7],4],[[7,8],[0,13]]],[1,1]]
+after split:    [[[[0,7],4],[[7,8],[0,[6,7]]]],[1,1]]
+after explode:  [[[[0,7],4],[[7,8],[6,0]]],[8,1]]
+
+
+ +Once no reduce actions apply, the snailfish number that remains is the actual result of the addition operation: [[[[0,7],4],[[7,8],[6,0]]],[8,1]]. + +The homework assignment involves adding up a list of snailfish numbers (your puzzle input). The snailfish numbers are each listed on a separate line. Add the first snailfish number and the second, then add that result and the third, then add that result and the fourth, and so on until all numbers in the list have been used once. + +For example, the final sum of this list is [[[[1,1],[2,2]],[3,3]],[4,4]]: + +
+[1,1]
+[2,2]
+[3,3]
+[4,4]
+
+
+ +The final sum of this list is [[[[3,0],[5,3]],[4,4]],[5,5]]: + +
+[1,1]
+[2,2]
+[3,3]
+[4,4]
+[5,5]
+
+
+ +The final sum of this list is [[[[5,0],[7,4]],[5,5]],[6,6]]: + +
+[1,1]
+[2,2]
+[3,3]
+[4,4]
+[5,5]
+[6,6]
+
+
+ +Here's a slightly larger example: + +
+[[[0,[4,5]],[0,0]],[[[4,5],[2,6]],[9,5]]]
+[7,[[[3,7],[4,3]],[[6,3],[8,8]]]]
+[[2,[[0,8],[3,4]]],[[[6,7],1],[7,[1,6]]]]
+[[[[2,4],7],[6,[0,5]]],[[[6,8],[2,8]],[[2,1],[4,5]]]]
+[7,[5,[[3,8],[1,4]]]]
+[[2,[2,2]],[8,[8,1]]]
+[2,9]
+[1,[[[9,3],9],[[9,0],[0,7]]]]
+[[[5,[7,4]],7],1]
+[[[[4,2],2],6],[8,7]]
+
+
+ +The final sum [[[[8,7],[7,7]],[[8,6],[7,7]]],[[[0,7],[6,6]],[8,7]]] is found after adding up the above snailfish numbers: + +
+  [[[0,[4,5]],[0,0]],[[[4,5],[2,6]],[9,5]]]
++ [7,[[[3,7],[4,3]],[[6,3],[8,8]]]]
+= [[[[4,0],[5,4]],[[7,7],[6,0]]],[[8,[7,7]],[[7,9],[5,0]]]]
+
+  [[[[4,0],[5,4]],[[7,7],[6,0]]],[[8,[7,7]],[[7,9],[5,0]]]]
++ [[2,[[0,8],[3,4]]],[[[6,7],1],[7,[1,6]]]]
+= [[[[6,7],[6,7]],[[7,7],[0,7]]],[[[8,7],[7,7]],[[8,8],[8,0]]]]
+
+  [[[[6,7],[6,7]],[[7,7],[0,7]]],[[[8,7],[7,7]],[[8,8],[8,0]]]]
++ [[[[2,4],7],[6,[0,5]]],[[[6,8],[2,8]],[[2,1],[4,5]]]]
+= [[[[7,0],[7,7]],[[7,7],[7,8]]],[[[7,7],[8,8]],[[7,7],[8,7]]]]
+
+  [[[[7,0],[7,7]],[[7,7],[7,8]]],[[[7,7],[8,8]],[[7,7],[8,7]]]]
++ [7,[5,[[3,8],[1,4]]]]
+= [[[[7,7],[7,8]],[[9,5],[8,7]]],[[[6,8],[0,8]],[[9,9],[9,0]]]]
+
+  [[[[7,7],[7,8]],[[9,5],[8,7]]],[[[6,8],[0,8]],[[9,9],[9,0]]]]
++ [[2,[2,2]],[8,[8,1]]]
+= [[[[6,6],[6,6]],[[6,0],[6,7]]],[[[7,7],[8,9]],[8,[8,1]]]]
+
+  [[[[6,6],[6,6]],[[6,0],[6,7]]],[[[7,7],[8,9]],[8,[8,1]]]]
++ [2,9]
+= [[[[6,6],[7,7]],[[0,7],[7,7]]],[[[5,5],[5,6]],9]]
+
+  [[[[6,6],[7,7]],[[0,7],[7,7]]],[[[5,5],[5,6]],9]]
++ [1,[[[9,3],9],[[9,0],[0,7]]]]
+= [[[[7,8],[6,7]],[[6,8],[0,8]]],[[[7,7],[5,0]],[[5,5],[5,6]]]]
+
+  [[[[7,8],[6,7]],[[6,8],[0,8]]],[[[7,7],[5,0]],[[5,5],[5,6]]]]
++ [[[5,[7,4]],7],1]
+= [[[[7,7],[7,7]],[[8,7],[8,7]]],[[[7,0],[7,7]],9]]
+
+  [[[[7,7],[7,7]],[[8,7],[8,7]]],[[[7,0],[7,7]],9]]
++ [[[[4,2],2],6],[8,7]]
+= [[[[8,7],[7,7]],[[8,6],[7,7]]],[[[0,7],[6,6]],[8,7]]]
+
+
+ +To check whether it's the right answer, the snailfish teacher only checks the magnitude of the final sum. The magnitude of a pair is 3 times the magnitude of its left element plus 2 times the magnitude of its right element. The magnitude of a regular number is just that number. + +For example, the magnitude of [9,1] is 3*9 + 2*1 = 29; the magnitude of [1,9] is 3*1 + 2*9 = 21. Magnitude calculations are recursive: the magnitude of [[9,1],[1,9]] is 3*29 + 2*21 = 129. + +Here are a few more magnitude examples: + + + - [[1,2],[[3,4],5]] becomes 143. + - [[[[0,7],4],[[7,8],[6,0]]],[8,1]] becomes 1384. + - [[[[1,1],[2,2]],[3,3]],[4,4]] becomes 445. + - [[[[3,0],[5,3]],[4,4]],[5,5]] becomes 791. + - [[[[5,0],[7,4]],[5,5]],[6,6]] becomes 1137. + - [[[[8,7],[7,7]],[[8,6],[7,7]]],[[[0,7],[6,6]],[8,7]]] becomes 3488. + +So, given this example homework assignment: + +
+[[[0,[5,8]],[[1,7],[9,6]]],[[4,[1,2]],[[1,4],2]]]
+[[[5,[2,8]],4],[5,[[9,9],0]]]
+[6,[[[6,2],[5,6]],[[7,6],[4,7]]]]
+[[[6,[0,7]],[0,9]],[4,[9,[9,0]]]]
+[[[7,[6,4]],[3,[1,3]]],[[[5,5],1],9]]
+[[6,[[7,3],[3,2]]],[[[3,8],[5,7]],4]]
+[[[[5,4],[7,7]],8],[[8,3],8]]
+[[9,3],[[9,9],[6,[4,9]]]]
+[[2,[[7,7],7]],[[5,8],[[9,3],[0,2]]]]
+[[[[5,2],5],[8,[3,7]]],[[5,[7,5]],[4,4]]]
+
+
+ +The final sum is: + +
+[[[[6,6],[7,6]],[[7,7],[7,0]]],[[[7,7],[7,7]],[[7,8],[9,9]]]]
+
+ +The magnitude of this final sum is 4140. + +Add up all of the snailfish numbers from the homework assignment in the order they appear. What is the magnitude of the final sum? + + +## --- Part Two --- +You notice a second question on the back of the homework assignment: + +What is the largest magnitude you can get from adding only two of the snailfish numbers? + +Note that snailfish addition is not [commutative](https://en.wikipedia.org/wiki/Commutative_property) - that is, x + y and y + x can produce different results. + +Again considering the last example homework assignment above: + +
+[[[0,[5,8]],[[1,7],[9,6]]],[[4,[1,2]],[[1,4],2]]]
+[[[5,[2,8]],4],[5,[[9,9],0]]]
+[6,[[[6,2],[5,6]],[[7,6],[4,7]]]]
+[[[6,[0,7]],[0,9]],[4,[9,[9,0]]]]
+[[[7,[6,4]],[3,[1,3]]],[[[5,5],1],9]]
+[[6,[[7,3],[3,2]]],[[[3,8],[5,7]],4]]
+[[[[5,4],[7,7]],8],[[8,3],8]]
+[[9,3],[[9,9],[6,[4,9]]]]
+[[2,[[7,7],7]],[[5,8],[[9,3],[0,2]]]]
+[[[[5,2],5],[8,[3,7]]],[[5,[7,5]],[4,4]]]
+
+
+ +The largest magnitude of the sum of any two snailfish numbers in this list is 3993. This is the magnitude of [[2,[[7,7],7]],[[5,8],[[9,3],[0,2]]]] + [[[0,[5,8]],[[1,7],[9,6]]],[[4,[1,2]],[[1,4],2]]], which reduces to [[[[7,8],[6,6]],[[6,0],[7,7]]],[[[7,8],[8,8]],[[7,9],[0,6]]]]. + +What is the largest magnitude of any sum of two different snailfish numbers from the homework assignment? + + diff --git a/2021/Day18/input.in b/2021/Day18/input.in index 28b247a44..73719bdb4 100644 Binary files a/2021/Day18/input.in and b/2021/Day18/input.in differ diff --git a/2021/Day19/README.md b/2021/Day19/README.md index 5c4ee5380..b8dfa2ffd 100644 --- a/2021/Day19/README.md +++ b/2021/Day19/README.md @@ -1,6 +1,405 @@ +original source: [https://adventofcode.com/2021/day/19](https://adventofcode.com/2021/day/19) ## --- Day 19: Beacon Scanner --- As your [probe](17) drifted down through this area, it released an assortment of beacons and scanners into the water. It's difficult to navigate in the pitch black open waters of the ocean trench, but if you can build a map of the trench using data from the scanners, you should be able to safely reach the bottom. The beacons and scanners float motionless in the water; they're designed to maintain the same position for long periods of time. Each scanner is capable of detecting all beacons in a large cube centered on the scanner; beacons that are at most 1000 units away from the scanner in each of the three axes (x, y, and z) have their precise position determined relative to the scanner. However, scanners cannot detect other scanners. The submarine has automatically summarized the relative positions of beacons detected by each scanner (your puzzle input). -Read the [full puzzle](https://adventofcode.com/2021/day/19). \ No newline at end of file +For example, if a scanner is at x,y,z coordinates 500,0,-500 and there are beacons at -500,1000,-1500 and 1501,0,-500, the scanner could report that the first beacon is at -1000,1000,-1000 (relative to the scanner) but would not detect the second beacon at all. + +Unfortunately, while each scanner can report the positions of all detected beacons relative to itself, the scanners do not know their own position. You'll need to determine the positions of the beacons and scanners yourself. + +The scanners and beacons map a single contiguous 3d region. This region can be reconstructed by finding pairs of scanners that have overlapping detection regions such that there are at least 12 beacons that both scanners detect within the overlap. By establishing 12 common beacons, you can precisely determine where the scanners are relative to each other, allowing you to reconstruct the beacon map one scanner at a time. + +For a moment, consider only two dimensions. Suppose you have the following scanner reports: + +
+--- scanner 0 ---
+0,2
+4,1
+3,3
+
+--- scanner 1 ---
+-1,-1
+-5,0
+-2,1
+
+
+ +Drawing x increasing rightward, y increasing upward, scanners as S, and beacons as B, scanner 0 detects this: + +
+...B.
+B....
+....B
+S....
+
+
+ +Scanner 1 detects this: + +
+...B..
+B....S
+....B.
+
+
+ +For this example, assume scanners only need 3 overlapping beacons. Then, the beacons visible to both scanners overlap to produce the following complete map: + +
+...B..
+B....S
+....B.
+S.....
+
+
+ +Unfortunately, there's a second problem: the scanners also don't know their rotation or facing direction. Due to magnetic alignment, each scanner is rotated some integer number of 90-degree turns around all of the x, y, and z axes. That is, one scanner might call a direction positive x, while another scanner might call that direction negative y. Or, two scanners might agree on which direction is positive x, but one scanner might be upside-down from the perspective of the other scanner. In total, each scanner could be in any of 24 different orientations: facing positive or negative x, y, or z, and considering any of four directions "up" from that facing. + +For example, here is an arrangement of beacons as seen from a scanner in the same position but in different orientations: + +
+--- scanner 0 ---
+-1,-1,1
+-2,-2,2
+-3,-3,3
+-2,-3,1
+5,6,-4
+8,0,7
+
+--- scanner 0 ---
+1,-1,1
+2,-2,2
+3,-3,3
+2,-1,3
+-5,4,-6
+-8,-7,0
+
+--- scanner 0 ---
+-1,-1,-1
+-2,-2,-2
+-3,-3,-3
+-1,-3,-2
+4,6,5
+-7,0,8
+
+--- scanner 0 ---
+1,1,-1
+2,2,-2
+3,3,-3
+1,3,-2
+-4,-6,5
+7,0,8
+
+--- scanner 0 ---
+1,1,1
+2,2,2
+3,3,3
+3,1,2
+-6,-4,-5
+0,7,-8
+
+
+ +By finding pairs of scanners that both see at least 12 of the same beacons, you can assemble the entire map. For example, consider the following report: + +
+--- scanner 0 ---
+404,-588,-901
+528,-643,409
+-838,591,734
+390,-675,-793
+-537,-823,-458
+-485,-357,347
+-345,-311,381
+-661,-816,-575
+-876,649,763
+-618,-824,-621
+553,345,-567
+474,580,667
+-447,-329,318
+-584,868,-557
+544,-627,-890
+564,392,-477
+455,729,728
+-892,524,684
+-689,845,-530
+423,-701,434
+7,-33,-71
+630,319,-379
+443,580,662
+-789,900,-551
+459,-707,401
+
+--- scanner 1 ---
+686,422,578
+605,423,415
+515,917,-361
+-336,658,858
+95,138,22
+-476,619,847
+-340,-569,-846
+567,-361,727
+-460,603,-452
+669,-402,600
+729,430,532
+-500,-761,534
+-322,571,750
+-466,-666,-811
+-429,-592,574
+-355,545,-477
+703,-491,-529
+-328,-685,520
+413,935,-424
+-391,539,-444
+586,-435,557
+-364,-763,-893
+807,-499,-711
+755,-354,-619
+553,889,-390
+
+--- scanner 2 ---
+649,640,665
+682,-795,504
+-784,533,-524
+-644,584,-595
+-588,-843,648
+-30,6,44
+-674,560,763
+500,723,-460
+609,671,-379
+-555,-800,653
+-675,-892,-343
+697,-426,-610
+578,704,681
+493,664,-388
+-671,-858,530
+-667,343,800
+571,-461,-707
+-138,-166,112
+-889,563,-600
+646,-828,498
+640,759,510
+-630,509,768
+-681,-892,-333
+673,-379,-804
+-742,-814,-386
+577,-820,562
+
+--- scanner 3 ---
+-589,542,597
+605,-692,669
+-500,565,-823
+-660,373,557
+-458,-679,-417
+-488,449,543
+-626,468,-788
+338,-750,-386
+528,-832,-391
+562,-778,733
+-938,-730,414
+543,643,-506
+-524,371,-870
+407,773,750
+-104,29,83
+378,-903,-323
+-778,-728,485
+426,699,580
+-438,-605,-362
+-469,-447,-387
+509,732,623
+647,635,-688
+-868,-804,481
+614,-800,639
+595,780,-596
+
+--- scanner 4 ---
+727,592,562
+-293,-554,779
+441,611,-461
+-714,465,-776
+-743,427,-804
+-660,-479,-426
+832,-632,460
+927,-485,-438
+408,393,-506
+466,436,-512
+110,16,151
+-258,-428,682
+-393,719,612
+-211,-452,876
+808,-476,-593
+-575,615,604
+-485,667,467
+-680,325,-822
+-627,-443,-432
+872,-547,-609
+833,512,582
+807,604,487
+839,-516,451
+891,-625,532
+-652,-548,-490
+30,-46,-14
+
+
+ +Because all coordinates are relative, in this example, all "absolute" positions will be expressed relative to scanner 0 (using the orientation of scanner 0 and as if scanner 0 is at coordinates 0,0,0). + +Scanners 0 and 1 have overlapping detection cubes; the 12 beacons they both detect (relative to scanner 0) are at the following coordinates: + +
+-618,-824,-621
+-537,-823,-458
+-447,-329,318
+404,-588,-901
+544,-627,-890
+528,-643,409
+-661,-816,-575
+390,-675,-793
+423,-701,434
+-345,-311,381
+459,-707,401
+-485,-357,347
+
+
+ +These same 12 beacons (in the same order) but from the perspective of scanner 1 are: + +
+686,422,578
+605,423,415
+515,917,-361
+-336,658,858
+-476,619,847
+-460,603,-452
+729,430,532
+-322,571,750
+-355,545,-477
+413,935,-424
+-391,539,-444
+553,889,-390
+
+
+ +Because of this, scanner 1 must be at 68,-1246,-43 (relative to scanner 0). + +Scanner 4 overlaps with scanner 1; the 12 beacons they both detect (relative to scanner 0) are: + +
+459,-707,401
+-739,-1745,668
+-485,-357,347
+432,-2009,850
+528,-643,409
+423,-701,434
+-345,-311,381
+408,-1815,803
+534,-1912,768
+-687,-1600,576
+-447,-329,318
+-635,-1737,486
+
+
+ +So, scanner 4 is at -20,-1133,1061 (relative to scanner 0). + +Following this process, scanner 2 must be at 1105,-1205,1229 (relative to scanner 0) and scanner 3 must be at -92,-2380,-20 (relative to scanner 0). + +The full list of beacons (relative to scanner 0) is: + +
+-892,524,684
+-876,649,763
+-838,591,734
+-789,900,-551
+-739,-1745,668
+-706,-3180,-659
+-697,-3072,-689
+-689,845,-530
+-687,-1600,576
+-661,-816,-575
+-654,-3158,-753
+-635,-1737,486
+-631,-672,1502
+-624,-1620,1868
+-620,-3212,371
+-618,-824,-621
+-612,-1695,1788
+-601,-1648,-643
+-584,868,-557
+-537,-823,-458
+-532,-1715,1894
+-518,-1681,-600
+-499,-1607,-770
+-485,-357,347
+-470,-3283,303
+-456,-621,1527
+-447,-329,318
+-430,-3130,366
+-413,-627,1469
+-345,-311,381
+-36,-1284,1171
+-27,-1108,-65
+7,-33,-71
+12,-2351,-103
+26,-1119,1091
+346,-2985,342
+366,-3059,397
+377,-2827,367
+390,-675,-793
+396,-1931,-563
+404,-588,-901
+408,-1815,803
+423,-701,434
+432,-2009,850
+443,580,662
+455,729,728
+456,-540,1869
+459,-707,401
+465,-695,1988
+474,580,667
+496,-1584,1900
+497,-1838,-617
+527,-524,1933
+528,-643,409
+534,-1912,768
+544,-627,-890
+553,345,-567
+564,392,-477
+568,-2007,-577
+605,-1665,1952
+612,-1593,1893
+630,319,-379
+686,-3108,-505
+776,-3184,-501
+846,-3110,-434
+1135,-1161,1235
+1243,-1093,1063
+1660,-552,429
+1693,-557,386
+1735,-437,1738
+1749,-1800,1813
+1772,-405,1572
+1776,-675,371
+1779,-442,1789
+1780,-1548,337
+1786,-1538,337
+1847,-1591,415
+1889,-1729,1762
+1994,-1805,1792
+
+
+ +In total, there are 79 beacons. + +Assemble the full map of beacons. How many beacons are there? + + +## --- Part Two --- +Sometimes, it's a good idea to appreciate just how big the ocean is. Using the [Manhattan distance](https://en.wikipedia.org/wiki/Taxicab_geometry), how far apart do the scanners get? + +In the above example, scanners 2 (1105,-1205,1229) and 3 (-92,-2380,-20) are the largest Manhattan distance apart. In total, they are 1197 + 1175 + 1249 = 3621 units apart. + +What is the largest Manhattan distance between any two scanners? + + diff --git a/2021/Day19/input.in b/2021/Day19/input.in index 3fec76663..e98790859 100644 Binary files a/2021/Day19/input.in and b/2021/Day19/input.in differ diff --git a/2021/Day20/README.md b/2021/Day20/README.md index 0bf43a48c..03b4d9537 100644 --- a/2021/Day20/README.md +++ b/2021/Day20/README.md @@ -1,6 +1,133 @@ +original source: [https://adventofcode.com/2021/day/20](https://adventofcode.com/2021/day/20) ## --- Day 20: Trench Map --- With the scanners fully deployed, you turn their attention to mapping the floor of the ocean trench. When you get back the image from the scanners, it seems to just be random noise. Perhaps you can combine an image enhancement algorithm and the input image (your puzzle input) to clean it up a little. -Read the [full puzzle](https://adventofcode.com/2021/day/20). \ No newline at end of file +For example: + +
+..#.#..#####.#.#.#.###.##.....###.##.#..###.####..#####..#....#..#..##..##
+#..######.###...####..#..#####..##..#.#####...##.#.#..#.##..#.#......#.###
+.######.###.####...#.##.##..#..#..#####.....#.#....###..#.##......#.....#.
+.#..#..##..#...##.######.####.####.#.#...#.......#..#.#.#...####.##.#.....
+.#..#...##.#.##..#...##.#.##..###.#......#.#.......#.#.#.####.###.##...#..
+...####.#..#..#.##.#....##..#.####....##...##..#...#......#.#.......#.....
+..##..####..#...#.#.#...##..#.#..###..#####........#..####......#..#
+
+#..#.
+#....
+##..#
+..#..
+..###
+
+
+ +The first section is the image enhancement algorithm. It is normally given on a single line, but it has been wrapped to multiple lines in this example for legibility. The second section is the input image, a two-dimensional grid of light pixels (#) and dark pixels (.). + +The image enhancement algorithm describes how to enhance an image by simultaneously converting all pixels in the input image into an output image. Each pixel of the output image is determined by looking at a 3x3 square of pixels centered on the corresponding input image pixel. So, to determine the value of the pixel at (5,10) in the output image, nine pixels from the input image need to be considered: (4,9), (4,10), (4,11), (5,9), (5,10), (5,11), (6,9), (6,10), and (6,11). These nine input pixels are combined into a single binary number that is used as an index in the image enhancement algorithm string. + +For example, to determine the output pixel that corresponds to the very middle pixel of the input image, the nine pixels marked by [...] would need to be considered: + +
+# . . # .
+#[. . .].
+#[# . .]#
+.[. # .].
+. . # # #
+
+
+ +Starting from the top-left and reading across each row, these pixels are ..., then #.., then .#.; combining these forms ...#...#.. By turning dark pixels (.) into 0 and light pixels (#) into 1, the binary number 000100010 can be formed, which is 34 in decimal. + +The image enhancement algorithm string is exactly 512 characters long, enough to match every possible 9-bit binary number. The first few characters of the string (numbered starting from zero) are as follows: + +
+0         10        20        30  34    40        50        60        70
+|         |         |         |   |     |         |         |         |
+..#.#..#####.#.#.#.###.##.....###.##.#..###.####..#####..#....#..#..##..##
+
+
+ +In the middle of this first group of characters, the character at index 34 can be found: #. So, the output pixel in the center of the output image should be #, a light pixel. + +This process can then be repeated to calculate every pixel of the output image. + +Through advances in imaging technology, the images being operated on here are infinite in size. Every pixel of the infinite output image needs to be calculated exactly based on the relevant pixels of the input image. The small input image you have is only a small region of the actual infinite input image; the rest of the input image consists of dark pixels (.). For the purposes of the example, to save on space, only a portion of the infinite-sized input and output images will be shown. + +The starting input image, therefore, looks something like this, with more dark pixels (.) extending forever in every direction not shown here: + +
+...............
+...............
+...............
+...............
+...............
+.....#..#......
+.....#.........
+.....##..#.....
+.......#.......
+.......###.....
+...............
+...............
+...............
+...............
+...............
+
+
+ +By applying the image enhancement algorithm to every pixel simultaneously, the following output image can be obtained: + +
+...............
+...............
+...............
+...............
+.....##.##.....
+....#..#.#.....
+....##.#..#....
+....####..#....
+.....#..##.....
+......##..#....
+.......#.#.....
+...............
+...............
+...............
+...............
+
+
+ +Through further advances in imaging technology, the above output image can also be used as an input image! This allows it to be enhanced a second time: + +
+...............
+...............
+...............
+..........#....
+....#..#.#.....
+...#.#...###...
+...#...##.#....
+...#.....#.#...
+....#.#####....
+.....#.#####...
+......##.##....
+.......###.....
+...............
+...............
+...............
+
+
+ +Truly incredible - now the small details are really starting to come through. After enhancing the original input image twice, 35 pixels are lit. + +Start with the original input image and apply the image enhancement algorithm twice, being careful to account for the infinite size of the images. How many pixels are lit in the resulting image? + + +## --- Part Two --- +You still can't quite make out the details in the image. Maybe you just didn't [enhance](https://en.wikipedia.org/wiki/Kernel_(image_processing)) it enough. + +If you enhance the starting input image in the above example a total of 50 times, 3351 pixels are lit in the final output image. + +Start again with the original input image and apply the image enhancement algorithm 50 times. How many pixels are lit in the resulting image? + + diff --git a/2021/Day20/input.in b/2021/Day20/input.in index d06c07c68..574baecee 100644 Binary files a/2021/Day20/input.in and b/2021/Day20/input.in differ diff --git a/2021/Day21/README.md b/2021/Day21/README.md index 017a374ff..8ae392991 100644 --- a/2021/Day21/README.md +++ b/2021/Day21/README.md @@ -1,6 +1,59 @@ +original source: [https://adventofcode.com/2021/day/21](https://adventofcode.com/2021/day/21) ## --- Day 21: Dirac Dice --- There's not much to do as you slowly descend to the bottom of the ocean. The submarine computer challenges you to a nice game of Dirac Dice. This game consists of a single [die](https://en.wikipedia.org/wiki/Dice), two [pawns](https://en.wikipedia.org/wiki/Glossary_of_board_games#piece), and a game board with a circular track containing ten spaces marked 1 through 10 clockwise. Each player's starting space is chosen randomly (your puzzle input). Player 1 goes first. -Read the [full puzzle](https://adventofcode.com/2021/day/21). \ No newline at end of file +Players take turns moving. On each player's turn, the player rolls the die three times and adds up the results. Then, the player moves their pawn that many times forward around the track (that is, moving clockwise on spaces in order of increasing value, wrapping back around to 1 after 10). So, if a player is on space 7 and they roll 2, 2, and 1, they would move forward 5 times, to spaces 8, 9, 10, 1, and finally stopping on 2. + +After each player moves, they increase their score by the value of the space their pawn stopped on. Players' scores start at 0. So, if the first player starts on space 7 and rolls a total of 5, they would stop on space 2 and add 2 to their score (for a total score of 2). The game immediately ends as a win for any player whose score reaches at least 1000. + +Since the first game is a practice game, the submarine opens a compartment labeled deterministic dice and a 100-sided die falls out. This die always rolls 1 first, then 2, then 3, and so on up to 100, after which it starts over at 1 again. Play using this die. + +For example, given these starting positions: + +
+Player 1 starting position: 4
+Player 2 starting position: 8
+
+
+ +This is how the game would go: + + + - Player 1 rolls 1+2+3 and moves to space 10 for a total score of 10. + - Player 2 rolls 4+5+6 and moves to space 3 for a total score of 3. + - Player 1 rolls 7+8+9 and moves to space 4 for a total score of 14. + - Player 2 rolls 10+11+12 and moves to space 6 for a total score of 9. + - Player 1 rolls 13+14+15 and moves to space 6 for a total score of 20. + - Player 2 rolls 16+17+18 and moves to space 7 for a total score of 16. + - Player 1 rolls 19+20+21 and moves to space 6 for a total score of 26. + - Player 2 rolls 22+23+24 and moves to space 6 for a total score of 22. + +...after many turns... + + + - Player 2 rolls 82+83+84 and moves to space 6 for a total score of 742. + - Player 1 rolls 85+86+87 and moves to space 4 for a total score of 990. + - Player 2 rolls 88+89+90 and moves to space 3 for a total score of 745. + - Player 1 rolls 91+92+93 and moves to space 10 for a final score, 1000. + +Since player 1 has at least 1000 points, player 1 wins and the game ends. At this point, the losing player had 745 points and the die had been rolled a total of 993 times; 745 * 993 = 739785. + +Play a practice game using the deterministic 100-sided die. The moment either player wins, what do you get if you multiply the score of the losing player by the number of times the die was rolled during the game? + + +## --- Part Two --- +Now that you're warmed up, it's time to play the real game. + +A second compartment opens, this time labeled Dirac dice. Out of it falls a single three-sided die. + +As you experiment with the die, you feel a little strange. An informational brochure in the compartment explains that this is a quantum die: when you roll it, the universe splits into multiple copies, one copy for each possible outcome of the die. In this case, rolling the die always splits the universe into three copies: one where the outcome of the roll was 1, one where it was 2, and one where it was 3. + +The game is played the same as before, although to prevent things from getting too far out of hand, the game now ends when either player's score reaches at least 21. + +Using the same starting positions as in the example above, player 1 wins in 444356092776315 universes, while player 2 merely wins in 341960390180808 universes. + +Using your given starting positions, determine every possible outcome. Find the player that wins in more universes; in how many universes does that player win? + + diff --git a/2021/Day21/input.in b/2021/Day21/input.in index 0b2fc3507..af8c8ae73 100644 Binary files a/2021/Day21/input.in and b/2021/Day21/input.in differ diff --git a/2021/Day22/README.md b/2021/Day22/README.md index d28c86ec4..49c27da82 100644 --- a/2021/Day22/README.md +++ b/2021/Day22/README.md @@ -1,6 +1,197 @@ +original source: [https://adventofcode.com/2021/day/22](https://adventofcode.com/2021/day/22) ## --- Day 22: Reactor Reboot --- Operating at these extreme ocean depths has overloaded the submarine's reactor; it needs to be rebooted. The reactor core is made up of a large 3-dimensional grid made up entirely of cubes, one cube per integer 3-dimensional coordinate (x,y,z). Each cube can be either on or off; at the start of the reboot process, they are all off. (Could it be an old model of a reactor you've seen [before](/2020/day/17)?) -Read the [full puzzle](https://adventofcode.com/2021/day/22). \ No newline at end of file +To reboot the reactor, you just need to set all of the cubes to either on or off by following a list of reboot steps (your puzzle input). Each step specifies a [cuboid](https://en.wikipedia.org/wiki/Cuboid) (the set of all cubes that have coordinates which fall within ranges for x, y, and z) and whether to turn all of the cubes in that cuboid on or off. + +For example, given these reboot steps: + +
+on x=10..12,y=10..12,z=10..12
+on x=11..13,y=11..13,z=11..13
+off x=9..11,y=9..11,z=9..11
+on x=10..10,y=10..10,z=10..10
+
+
+ +The first step (on x=10..12,y=10..12,z=10..12) turns on a 3x3x3 cuboid consisting of 27 cubes: + + + - 10,10,10 + - 10,10,11 + - 10,10,12 + - 10,11,10 + - 10,11,11 + - 10,11,12 + - 10,12,10 + - 10,12,11 + - 10,12,12 + - 11,10,10 + - 11,10,11 + - 11,10,12 + - 11,11,10 + - 11,11,11 + - 11,11,12 + - 11,12,10 + - 11,12,11 + - 11,12,12 + - 12,10,10 + - 12,10,11 + - 12,10,12 + - 12,11,10 + - 12,11,11 + - 12,11,12 + - 12,12,10 + - 12,12,11 + - 12,12,12 + +The second step (on x=11..13,y=11..13,z=11..13) turns on a 3x3x3 cuboid that overlaps with the first. As a result, only 19 additional cubes turn on; the rest are already on from the previous step: + + + - 11,11,13 + - 11,12,13 + - 11,13,11 + - 11,13,12 + - 11,13,13 + - 12,11,13 + - 12,12,13 + - 12,13,11 + - 12,13,12 + - 12,13,13 + - 13,11,11 + - 13,11,12 + - 13,11,13 + - 13,12,11 + - 13,12,12 + - 13,12,13 + - 13,13,11 + - 13,13,12 + - 13,13,13 + +The third step (off x=9..11,y=9..11,z=9..11) turns off a 3x3x3 cuboid that overlaps partially with some cubes that are on, ultimately turning off 8 cubes: + + + - 10,10,10 + - 10,10,11 + - 10,11,10 + - 10,11,11 + - 11,10,10 + - 11,10,11 + - 11,11,10 + - 11,11,11 + +The final step (on x=10..10,y=10..10,z=10..10) turns on a single cube, 10,10,10. After this last step, 39 cubes are on. + +The initialization procedure only uses cubes that have x, y, and z positions of at least -50 and at most 50. For now, ignore cubes outside this region. + +Here is a larger example: + +
+on x=-20..26,y=-36..17,z=-47..7
+on x=-20..33,y=-21..23,z=-26..28
+on x=-22..28,y=-29..23,z=-38..16
+on x=-46..7,y=-6..46,z=-50..-1
+on x=-49..1,y=-3..46,z=-24..28
+on x=2..47,y=-22..22,z=-23..27
+on x=-27..23,y=-28..26,z=-21..29
+on x=-39..5,y=-6..47,z=-3..44
+on x=-30..21,y=-8..43,z=-13..34
+on x=-22..26,y=-27..20,z=-29..19
+off x=-48..-32,y=26..41,z=-47..-37
+on x=-12..35,y=6..50,z=-50..-2
+off x=-48..-32,y=-32..-16,z=-15..-5
+on x=-18..26,y=-33..15,z=-7..46
+off x=-40..-22,y=-38..-28,z=23..41
+on x=-16..35,y=-41..10,z=-47..6
+off x=-32..-23,y=11..30,z=-14..3
+on x=-49..-5,y=-3..45,z=-29..18
+off x=18..30,y=-20..-8,z=-3..13
+on x=-41..9,y=-7..43,z=-33..15
+on x=-54112..-39298,y=-85059..-49293,z=-27449..7877
+on x=967..23432,y=45373..81175,z=27513..53682
+
+
+ +The last two steps are fully outside the initialization procedure area; all other steps are fully within it. After executing these steps in the initialization procedure region, 590784 cubes are on. + +Execute the reboot steps. Afterward, considering only cubes in the region x=-50..50,y=-50..50,z=-50..50, how many cubes are on? + + +## --- Part Two --- +Now that the initialization procedure is complete, you can reboot the reactor. + +Starting with all cubes off, run all of the reboot steps for all cubes in the reactor. + +Consider the following reboot steps: + +
+on x=-5..47,y=-31..22,z=-19..33
+on x=-44..5,y=-27..21,z=-14..35
+on x=-49..-1,y=-11..42,z=-10..38
+on x=-20..34,y=-40..6,z=-44..1
+off x=26..39,y=40..50,z=-2..11
+on x=-41..5,y=-41..6,z=-36..8
+off x=-43..-33,y=-45..-28,z=7..25
+on x=-33..15,y=-32..19,z=-34..11
+off x=35..47,y=-46..-34,z=-11..5
+on x=-14..36,y=-6..44,z=-16..29
+on x=-57795..-6158,y=29564..72030,z=20435..90618
+on x=36731..105352,y=-21140..28532,z=16094..90401
+on x=30999..107136,y=-53464..15513,z=8553..71215
+on x=13528..83982,y=-99403..-27377,z=-24141..23996
+on x=-72682..-12347,y=18159..111354,z=7391..80950
+on x=-1060..80757,y=-65301..-20884,z=-103788..-16709
+on x=-83015..-9461,y=-72160..-8347,z=-81239..-26856
+on x=-52752..22273,y=-49450..9096,z=54442..119054
+on x=-29982..40483,y=-108474..-28371,z=-24328..38471
+on x=-4958..62750,y=40422..118853,z=-7672..65583
+on x=55694..108686,y=-43367..46958,z=-26781..48729
+on x=-98497..-18186,y=-63569..3412,z=1232..88485
+on x=-726..56291,y=-62629..13224,z=18033..85226
+on x=-110886..-34664,y=-81338..-8658,z=8914..63723
+on x=-55829..24974,y=-16897..54165,z=-121762..-28058
+on x=-65152..-11147,y=22489..91432,z=-58782..1780
+on x=-120100..-32970,y=-46592..27473,z=-11695..61039
+on x=-18631..37533,y=-124565..-50804,z=-35667..28308
+on x=-57817..18248,y=49321..117703,z=5745..55881
+on x=14781..98692,y=-1341..70827,z=15753..70151
+on x=-34419..55919,y=-19626..40991,z=39015..114138
+on x=-60785..11593,y=-56135..2999,z=-95368..-26915
+on x=-32178..58085,y=17647..101866,z=-91405..-8878
+on x=-53655..12091,y=50097..105568,z=-75335..-4862
+on x=-111166..-40997,y=-71714..2688,z=5609..50954
+on x=-16602..70118,y=-98693..-44401,z=5197..76897
+on x=16383..101554,y=4615..83635,z=-44907..18747
+off x=-95822..-15171,y=-19987..48940,z=10804..104439
+on x=-89813..-14614,y=16069..88491,z=-3297..45228
+on x=41075..99376,y=-20427..49978,z=-52012..13762
+on x=-21330..50085,y=-17944..62733,z=-112280..-30197
+on x=-16478..35915,y=36008..118594,z=-7885..47086
+off x=-98156..-27851,y=-49952..43171,z=-99005..-8456
+off x=2032..69770,y=-71013..4824,z=7471..94418
+on x=43670..120875,y=-42068..12382,z=-24787..38892
+off x=37514..111226,y=-45862..25743,z=-16714..54663
+off x=25699..97951,y=-30668..59918,z=-15349..69697
+off x=-44271..17935,y=-9516..60759,z=49131..112598
+on x=-61695..-5813,y=40978..94975,z=8655..80240
+off x=-101086..-9439,y=-7088..67543,z=33935..83858
+off x=18020..114017,y=-48931..32606,z=21474..89843
+off x=-77139..10506,y=-89994..-18797,z=-80..59318
+off x=8476..79288,y=-75520..11602,z=-96624..-24783
+on x=-47488..-1262,y=24338..100707,z=16292..72967
+off x=-84341..13987,y=2429..92914,z=-90671..-1318
+off x=-37810..49457,y=-71013..-7894,z=-105357..-13188
+off x=-27365..46395,y=31009..98017,z=15428..76570
+off x=-70369..-16548,y=22648..78696,z=-1892..86821
+on x=-53470..21291,y=-120233..-33476,z=-44150..38147
+off x=-93533..-4276,y=-16170..68771,z=-104985..-24507
+
+
+ +After running the above reboot steps, 2758514936282235 cubes are on. (Just for fun, 474140 of those are also in the initialization procedure region.) + +Starting again with all cubes off, execute all reboot steps. Afterward, considering all cubes, how many cubes are on? + + diff --git a/2021/Day22/input.in b/2021/Day22/input.in index b3fe3fb0a..801923e3d 100644 Binary files a/2021/Day22/input.in and b/2021/Day22/input.in differ diff --git a/2021/Day23/README.md b/2021/Day23/README.md index a3534977a..331c46c1b 100644 --- a/2021/Day23/README.md +++ b/2021/Day23/README.md @@ -1,6 +1,369 @@ +original source: [https://adventofcode.com/2021/day/23](https://adventofcode.com/2021/day/23) ## --- Day 23: Amphipod --- A group of [amphipods](https://en.wikipedia.org/wiki/Amphipoda) notice your fancy submarine and flag you down. "With such an impressive shell," one amphipod says, "surely you can help us with a question that has stumped our best scientists." They go on to explain that a group of timid, stubborn amphipods live in a nearby burrow. Four types of amphipods live there: Amber (A), Bronze (B), Copper (C), and Desert (D). They live in a burrow that consists of a hallway and four side rooms. The side rooms are initially full of amphipods, and the hallway is initially empty. -Read the [full puzzle](https://adventofcode.com/2021/day/23). \ No newline at end of file +They give you a diagram of the situation (your puzzle input), including locations of each amphipod (A, B, C, or D, each of which is occupying an otherwise open space), walls (#), and open space (.). + +For example: + +
+#############
+#...........#
+###B#C#B#D###
+  #A#D#C#A#
+  #########
+
+
+ +The amphipods would like a method to organize every amphipod into side rooms so that each side room contains one type of amphipod and the types are sorted A-D going left to right, like this: + +
+#############
+#...........#
+###A#B#C#D###
+  #A#B#C#D#
+  #########
+
+
+ +Amphipods can move up, down, left, or right so long as they are moving into an unoccupied open space. Each type of amphipod requires a different amount of energy to move one step: Amber amphipods require 1 energy per step, Bronze amphipods require 10 energy, Copper amphipods require 100, and Desert ones require 1000. The amphipods would like you to find a way to organize the amphipods that requires the least total energy. + +However, because they are timid and stubborn, the amphipods have some extra rules: + + + - Amphipods will never stop on the space immediately outside any room. They can move into that space so long as they immediately continue moving. (Specifically, this refers to the four open spaces in the hallway that are directly above an amphipod starting position.) + - Amphipods will never move from the hallway into a room unless that room is their destination room and that room contains no amphipods which do not also have that room as their own destination. If an amphipod's starting room is not its destination room, it can stay in that room until it leaves the room. (For example, an Amber amphipod will not move from the hallway into the right three rooms, and will only move into the leftmost room if that room is empty or if it only contains other Amber amphipods.) + - Once an amphipod stops moving in the hallway, it will stay in that spot until it can move into a room. (That is, once any amphipod starts moving, any other amphipods currently in the hallway are locked in place and will not move again until they can move fully into a room.) + +In the above example, the amphipods can be organized using a minimum of 12521 energy. One way to do this is shown below. + +Starting configuration: + +
+#############
+#...........#
+###B#C#B#D###
+  #A#D#C#A#
+  #########
+
+
+ +One Bronze amphipod moves into the hallway, taking 4 steps and using 40 energy: + +
+#############
+#...B.......#
+###B#C#.#D###
+  #A#D#C#A#
+  #########
+
+
+ +The only Copper amphipod not in its side room moves there, taking 4 steps and using 400 energy: + +
+#############
+#...B.......#
+###B#.#C#D###
+  #A#D#C#A#
+  #########
+
+
+ +A Desert amphipod moves out of the way, taking 3 steps and using 3000 energy, and then the Bronze amphipod takes its place, taking 3 steps and using 30 energy: + +
+#############
+#.....D.....#
+###B#.#C#D###
+  #A#B#C#A#
+  #########
+
+
+ +The leftmost Bronze amphipod moves to its room using 40 energy: + +
+#############
+#.....D.....#
+###.#B#C#D###
+  #A#B#C#A#
+  #########
+
+
+ +Both amphipods in the rightmost room move into the hallway, using 2003 energy in total: + +
+#############
+#.....D.D.A.#
+###.#B#C#.###
+  #A#B#C#.#
+  #########
+
+
+ +Both Desert amphipods move into the rightmost room using 7000 energy: + +
+#############
+#.........A.#
+###.#B#C#D###
+  #A#B#C#D#
+  #########
+
+
+ +Finally, the last Amber amphipod moves into its room, using 8 energy: + +
+#############
+#...........#
+###A#B#C#D###
+  #A#B#C#D#
+  #########
+
+
+ +What is the least energy required to organize the amphipods? + + +## --- Part Two --- +As you prepare to give the amphipods your solution, you notice that the diagram they handed you was actually folded up. As you unfold it, you discover an extra part of the diagram. + +Between the first and second lines of text that contain amphipod starting positions, insert the following lines: + +
+  #D#C#B#A#
+  #D#B#A#C#
+
+
+ +So, the above example now becomes: + +
+#############
+#...........#
+###B#C#B#D###
+  #D#C#B#A#
+  #D#B#A#C#
+  #A#D#C#A#
+  #########
+
+
+ +The amphipods still want to be organized into rooms similar to before: + +
+#############
+#...........#
+###A#B#C#D###
+  #A#B#C#D#
+  #A#B#C#D#
+  #A#B#C#D#
+  #########
+
+
+ +In this updated example, the least energy required to organize these amphipods is 44169: + +
+#############
+#...........#
+###B#C#B#D###
+  #D#C#B#A#
+  #D#B#A#C#
+  #A#D#C#A#
+  #########
+
+#############
+#..........D#
+###B#C#B#.###
+  #D#C#B#A#
+  #D#B#A#C#
+  #A#D#C#A#
+  #########
+
+#############
+#A.........D#
+###B#C#B#.###
+  #D#C#B#.#
+  #D#B#A#C#
+  #A#D#C#A#
+  #########
+
+#############
+#A........BD#
+###B#C#.#.###
+  #D#C#B#.#
+  #D#B#A#C#
+  #A#D#C#A#
+  #########
+
+#############
+#A......B.BD#
+###B#C#.#.###
+  #D#C#.#.#
+  #D#B#A#C#
+  #A#D#C#A#
+  #########
+
+#############
+#AA.....B.BD#
+###B#C#.#.###
+  #D#C#.#.#
+  #D#B#.#C#
+  #A#D#C#A#
+  #########
+
+#############
+#AA.....B.BD#
+###B#.#.#.###
+  #D#C#.#.#
+  #D#B#C#C#
+  #A#D#C#A#
+  #########
+
+#############
+#AA.....B.BD#
+###B#.#.#.###
+  #D#.#C#.#
+  #D#B#C#C#
+  #A#D#C#A#
+  #########
+
+#############
+#AA...B.B.BD#
+###B#.#.#.###
+  #D#.#C#.#
+  #D#.#C#C#
+  #A#D#C#A#
+  #########
+
+#############
+#AA.D.B.B.BD#
+###B#.#.#.###
+  #D#.#C#.#
+  #D#.#C#C#
+  #A#.#C#A#
+  #########
+
+#############
+#AA.D...B.BD#
+###B#.#.#.###
+  #D#.#C#.#
+  #D#.#C#C#
+  #A#B#C#A#
+  #########
+
+#############
+#AA.D.....BD#
+###B#.#.#.###
+  #D#.#C#.#
+  #D#B#C#C#
+  #A#B#C#A#
+  #########
+
+#############
+#AA.D......D#
+###B#.#.#.###
+  #D#B#C#.#
+  #D#B#C#C#
+  #A#B#C#A#
+  #########
+
+#############
+#AA.D......D#
+###B#.#C#.###
+  #D#B#C#.#
+  #D#B#C#.#
+  #A#B#C#A#
+  #########
+
+#############
+#AA.D.....AD#
+###B#.#C#.###
+  #D#B#C#.#
+  #D#B#C#.#
+  #A#B#C#.#
+  #########
+
+#############
+#AA.......AD#
+###B#.#C#.###
+  #D#B#C#.#
+  #D#B#C#.#
+  #A#B#C#D#
+  #########
+
+#############
+#AA.......AD#
+###.#B#C#.###
+  #D#B#C#.#
+  #D#B#C#.#
+  #A#B#C#D#
+  #########
+
+#############
+#AA.......AD#
+###.#B#C#.###
+  #.#B#C#.#
+  #D#B#C#D#
+  #A#B#C#D#
+  #########
+
+#############
+#AA.D.....AD#
+###.#B#C#.###
+  #.#B#C#.#
+  #.#B#C#D#
+  #A#B#C#D#
+  #########
+
+#############
+#A..D.....AD#
+###.#B#C#.###
+  #.#B#C#.#
+  #A#B#C#D#
+  #A#B#C#D#
+  #########
+
+#############
+#...D.....AD#
+###.#B#C#.###
+  #A#B#C#.#
+  #A#B#C#D#
+  #A#B#C#D#
+  #########
+
+#############
+#.........AD#
+###.#B#C#.###
+  #A#B#C#D#
+  #A#B#C#D#
+  #A#B#C#D#
+  #########
+
+#############
+#..........D#
+###A#B#C#.###
+  #A#B#C#D#
+  #A#B#C#D#
+  #A#B#C#D#
+  #########
+
+#############
+#...........#
+###A#B#C#D###
+  #A#B#C#D#
+  #A#B#C#D#
+  #A#B#C#D#
+  #########
+
+
+ +Using the initial configuration from the full diagram, what is the least energy required to organize the amphipods? + + diff --git a/2021/Day23/input.in b/2021/Day23/input.in index b5f7295a2..bfe890dc6 100644 Binary files a/2021/Day23/input.in and b/2021/Day23/input.in differ diff --git a/2021/Day24/README.md b/2021/Day24/README.md index fe492dc74..057a87524 100644 --- a/2021/Day24/README.md +++ b/2021/Day24/README.md @@ -1,6 +1,78 @@ +original source: [https://adventofcode.com/2021/day/24](https://adventofcode.com/2021/day/24) ## --- Day 24: Arithmetic Logic Unit --- [Magic smoke](https://en.wikipedia.org/wiki/Magic_smoke) starts leaking from the submarine's [arithmetic logic unit](https://en.wikipedia.org/wiki/Arithmetic_logic_unit) (ALU). Without the ability to perform basic arithmetic and logic functions, the submarine can't produce cool patterns with its Christmas lights! It also can't navigate. Or run the oxygen system. -Read the [full puzzle](https://adventofcode.com/2021/day/24). \ No newline at end of file +Don't worry, though - you probably have enough oxygen left to give you enough time to build a new ALU. + +The ALU is a four-dimensional processing unit: it has integer variables w, x, y, and z. These variables all start with the value 0. The ALU also supports six instructions: + + + - inp a - Read an input value and write it to variable a. + - add a b - Add the value of a to the value of b, then store the result in variable a. + - mul a b - Multiply the value of a by the value of b, then store the result in variable a. + - div a b - Divide the value of a by the value of b, truncate the result to an integer, then store the result in variable a. (Here, "truncate" means to round the value toward zero.) + - mod a b - Divide the value of a by the value of b, then store the remainder in variable a. (This is also called the [modulo](https://en.wikipedia.org/wiki/Modulo_operation) operation.) + - eql a b - If the value of a and b are equal, then store the value 1 in variable a. Otherwise, store the value 0 in variable a. + +In all of these instructions, a and b are placeholders; a will always be the variable where the result of the operation is stored (one of w, x, y, or z), while b can be either a variable or a number. Numbers can be positive or negative, but will always be integers. + +The ALU has no jump instructions; in an ALU program, every instruction is run exactly once in order from top to bottom. The program halts after the last instruction has finished executing. + +(Program authors should be especially cautious; attempting to execute div with b=0 or attempting to execute mod with a<0 or b<=0 will cause the program to crash and might even damage the ALU. These operations are never intended in any serious ALU program.) + +For example, here is an ALU program which takes an input number, negates it, and stores it in x: + +
+inp x
+mul x -1
+
+
+ +Here is an ALU program which takes two input numbers, then sets z to 1 if the second input number is three times larger than the first input number, or sets z to 0 otherwise: + +
+inp z
+inp x
+mul z 3
+eql z x
+
+
+ +Here is an ALU program which takes a non-negative integer as input, converts it into binary, and stores the lowest (1's) bit in z, the second-lowest (2's) bit in y, the third-lowest (4's) bit in x, and the fourth-lowest (8's) bit in w: + +
+inp w
+add z w
+mod z 2
+div w 2
+add y w
+mod y 2
+div w 2
+add x w
+mod x 2
+div w 2
+mod w 2
+
+
+ +Once you have built a replacement ALU, you can install it in the submarine, which will immediately resume what it was doing when the ALU failed: validating the submarine's model number. To do this, the ALU will run the MOdel Number Automatic Detector program (MONAD, your puzzle input). + +Submarine model numbers are always fourteen-digit numbers consisting only of digits 1 through 9. The digit 0 cannot appear in a model number. + +When MONAD checks a hypothetical fourteen-digit model number, it uses fourteen separate inp instructions, each expecting a single digit of the model number in order of most to least significant. (So, to check the model number 13579246899999, you would give 1 to the first inp instruction, 3 to the second inp instruction, 5 to the third inp instruction, and so on.) This means that when operating MONAD, each input instruction should only ever be given an integer value of at least 1 and at most 9. + +Then, after MONAD has finished running all of its instructions, it will indicate that the model number was valid by leaving a 0 in variable z. However, if the model number was invalid, it will leave some other non-zero value in z. + +MONAD imposes additional, mysterious restrictions on model numbers, and legend says the last copy of the MONAD documentation was eaten by a [tanuki](https://en.wikipedia.org/wiki/Japanese_raccoon_dog). You'll need to figure out what MONAD does some other way. + +To enable as many submarine features as possible, find the largest valid fourteen-digit model number that contains no 0 digits. What is the largest model number accepted by MONAD? + + +## --- Part Two --- +As the submarine starts booting up things like the [Retro Encabulator](https://www.youtube.com/watch?v=RXJKdh1KZ0w), you realize that maybe you don't need all these submarine features after all. + +What is the smallest model number accepted by MONAD? + + diff --git a/2021/Day24/input.in b/2021/Day24/input.in index b6a2cb888..4b01afbd8 100644 Binary files a/2021/Day24/input.in and b/2021/Day24/input.in differ diff --git a/2021/Day25/README.md b/2021/Day25/README.md index 3ec000011..535df1776 100644 --- a/2021/Day25/README.md +++ b/2021/Day25/README.md @@ -1,6 +1,333 @@ +original source: [https://adventofcode.com/2021/day/25](https://adventofcode.com/2021/day/25) ## --- Day 25: Sea Cucumber --- This is it: the bottom of the ocean trench, the last place the sleigh keys could be. Your submarine's experimental antenna still isn't boosted enough to detect the keys, but they must be here. All you need to do is reach the seafloor and find them. At least, you'd touch down on the seafloor if you could; unfortunately, it's completely covered by two large herds of [sea cucumbers](https://en.wikipedia.org/wiki/Sea_cucumber), and there isn't an open space large enough for your submarine. -Read the [full puzzle](https://adventofcode.com/2021/day/25). \ No newline at end of file +You suspect that the Elves must have done this before, because just then you discover the phone number of a deep-sea marine biologist on a handwritten note taped to the wall of the submarine's cockpit. + +"Sea cucumbers? Yeah, they're probably hunting for food. But don't worry, they're predictable critters: they move in perfectly straight lines, only moving forward when there's space to do so. They're actually quite polite!" + +You explain that you'd like to predict when you could land your submarine. + +"Oh that's easy, they'll eventually pile up and leave enough space for-- wait, did you say submarine? And the only place with that many sea cucumbers would be at the very bottom of the Mariana--" You hang up the phone. + +There are two herds of sea cucumbers sharing the same region; one always moves east (>), while the other always moves south (v). Each location can contain at most one sea cucumber; the remaining locations are empty (.). The submarine helpfully generates a map of the situation (your puzzle input). For example: + +
+v...>>.vv>
+.vv>>.vv..
+>>.>v>...v
+>>v>>.>.v.
+v>v.vv.v..
+>.>>..v...
+.vv..>.>v.
+v.v..>>v.v
+....v..v.>
+
+
+ +Every step, the sea cucumbers in the east-facing herd attempt to move forward one location, then the sea cucumbers in the south-facing herd attempt to move forward one location. When a herd moves forward, every sea cucumber in the herd first simultaneously considers whether there is a sea cucumber in the adjacent location it's facing (even another sea cucumber facing the same direction), and then every sea cucumber facing an empty location simultaneously moves into that location. + +So, in a situation like this: + +
+...>>>>>...
+
+ +After one step, only the rightmost sea cucumber would have moved: + +
+...>>>>.>..
+
+ +After the next step, two sea cucumbers move: + +
+...>>>.>.>.
+
+ +During a single step, the east-facing herd moves first, then the south-facing herd moves. So, given this situation: + +
+..........
+.>v....v..
+.......>..
+..........
+
+
+ +After a single step, of the sea cucumbers on the left, only the south-facing sea cucumber has moved (as it wasn't out of the way in time for the east-facing cucumber on the left to move), but both sea cucumbers on the right have moved (as the east-facing sea cucumber moved out of the way of the south-facing sea cucumber): + +
+..........
+.>........
+..v....v>.
+..........
+
+
+ +Due to strong water currents in the area, sea cucumbers that move off the right edge of the map appear on the left edge, and sea cucumbers that move off the bottom edge of the map appear on the top edge. Sea cucumbers always check whether their destination location is empty before moving, even if that destination is on the opposite side of the map: + +
+Initial state:
+...>...
+.......
+......>
+v.....>
+......>
+.......
+..vvv..
+
+After 1 step:
+..vv>..
+.......
+>......
+v.....>
+>......
+.......
+....v..
+
+After 2 steps:
+....v>.
+..vv...
+.>.....
+......>
+v>.....
+.......
+.......
+
+After 3 steps:
+......>
+..v.v..
+..>v...
+>......
+..>....
+v......
+.......
+
+After 4 steps:
+>......
+..v....
+..>.v..
+.>.v...
+...>...
+.......
+v......
+
+
+ +To find a safe place to land your submarine, the sea cucumbers need to stop moving. Again consider the first example: + +
+Initial state:
+v...>>.vv>
+.vv>>.vv..
+>>.>v>...v
+>>v>>.>.v.
+v>v.vv.v..
+>.>>..v...
+.vv..>.>v.
+v.v..>>v.v
+....v..v.>
+
+After 1 step:
+....>.>v.>
+v.v>.>v.v.
+>v>>..>v..
+>>v>v>.>.v
+.>v.v...v.
+v>>.>vvv..
+..v...>>..
+vv...>>vv.
+>.v.v..v.v
+
+After 2 steps:
+>.v.v>>..v
+v.v.>>vv..
+>v>.>.>.v.
+>>v>v.>v>.
+.>..v....v
+.>v>>.v.v.
+v....v>v>.
+.vv..>>v..
+v>.....vv.
+
+After 3 steps:
+v>v.v>.>v.
+v...>>.v.v
+>vv>.>v>..
+>>v>v.>.v>
+..>....v..
+.>.>v>v..v
+..v..v>vv>
+v.v..>>v..
+.v>....v..
+
+After 4 steps:
+v>..v.>>..
+v.v.>.>.v.
+>vv.>>.v>v
+>>.>..v>.>
+..v>v...v.
+..>>.>vv..
+>.v.vv>v.v
+.....>>vv.
+vvv>...v..
+
+After 5 steps:
+vv>...>v>.
+v.v.v>.>v.
+>.v.>.>.>v
+>v>.>..v>>
+..v>v.v...
+..>.>>vvv.
+.>...v>v..
+..v.v>>v.v
+v.v.>...v.
+
+...
+
+After 10 steps:
+..>..>>vv.
+v.....>>.v
+..v.v>>>v>
+v>.>v.>>>.
+..v>v.vv.v
+.v.>>>.v..
+v.v..>v>..
+..v...>v.>
+.vv..v>vv.
+
+...
+
+After 20 steps:
+v>.....>>.
+>vv>.....v
+.>v>v.vv>>
+v>>>v.>v.>
+....vv>v..
+.v.>>>vvv.
+..v..>>vv.
+v.v...>>.v
+..v.....v>
+
+...
+
+After 30 steps:
+.vv.v..>>>
+v>...v...>
+>.v>.>vv.>
+>v>.>.>v.>
+.>..v.vv..
+..v>..>>v.
+....v>..>v
+v.v...>vv>
+v.v...>vvv
+
+...
+
+After 40 steps:
+>>v>v..v..
+..>>v..vv.
+..>>>v.>.v
+..>>>>vvv>
+v.....>...
+v.v...>v>>
+>vv.....v>
+.>v...v.>v
+vvv.v..v.>
+
+...
+
+After 50 steps:
+..>>v>vv.v
+..v.>>vv..
+v.>>v>>v..
+..>>>>>vv.
+vvv....>vv
+..v....>>>
+v>.......>
+.vv>....v>
+.>v.vv.v..
+
+...
+
+After 55 steps:
+..>>v>vv..
+..v.>>vv..
+..>>v>>vv.
+..>>>>>vv.
+v......>vv
+v>v....>>v
+vvv...>..>
+>vv.....>.
+.>v.vv.v..
+
+After 56 steps:
+..>>v>vv..
+..v.>>vv..
+..>>v>>vv.
+..>>>>>vv.
+v......>vv
+v>v....>>v
+vvv....>.>
+>vv......>
+.>v.vv.v..
+
+After 57 steps:
+..>>v>vv..
+..v.>>vv..
+..>>v>>vv.
+..>>>>>vv.
+v......>vv
+v>v....>>v
+vvv.....>>
+>vv......>
+.>v.vv.v..
+
+After 58 steps:
+..>>v>vv..
+..v.>>vv..
+..>>v>>vv.
+..>>>>>vv.
+v......>vv
+v>v....>>v
+vvv.....>>
+>vv......>
+.>v.vv.v..
+
+
+ +In this example, the sea cucumbers stop moving after 58 steps. + +Find somewhere safe to land your submarine. What is the first step on which no sea cucumbers move? + + +## --- Part Two --- +Suddenly, the experimental antenna control console lights up: + +
+Sleigh keys detected!
+
+ +According to the console, the keys are directly under the submarine. You landed right on them! Using a robotic arm on the submarine, you move the sleigh keys into the airlock. + +Now, you just need to get them to Santa in time to save Christmas! You check your clock - it is Christmas. There's no way you can get them back to the surface in time. + +Just as you start to lose hope, you notice a button on the sleigh keys: remote start. You can start the sleigh from the bottom of the ocean! You just need some way to boost the signal from the keys so it actually reaches the sleigh. Good thing the submarine has that experimental antenna! You'll definitely need 50 stars to boost it that far, though. + +The experimental antenna control console lights up again: + +
+Energy source detected.
+Integrating energy source from device "sleigh keys"...done.
+Installing device drivers...done.
+Recalibrating experimental antenna...done.
+Boost strength due to matching signal phase: 1 star
+
+
+ +Only 49 stars to go. + + diff --git a/2021/Day25/input.in b/2021/Day25/input.in index 3cce93f11..5f7e1bec8 100644 Binary files a/2021/Day25/input.in and b/2021/Day25/input.in differ diff --git a/2021/README.md b/2021/README.md index c0b9cc240..692c54269 100644 --- a/2021/README.md +++ b/2021/README.md @@ -1,4 +1,6 @@ + # Advent of Code (2021) Check out https://adventofcode.com/2021. + diff --git a/2021/SplashScreen.cs b/2021/SplashScreen.cs index 525ef555c..f8a0e3fb1 100644 --- a/2021/SplashScreen.cs +++ b/2021/SplashScreen.cs @@ -1,3 +1,4 @@ + using System; namespace AdventOfCode.Y2021; @@ -8,35 +9,35 @@ public void Show() { var color = Console.ForegroundColor; Write(0xcc00, false, " ▄█▄ ▄▄█ ▄ ▄ ▄▄▄ ▄▄ ▄█▄ ▄▄▄ ▄█ ▄▄ ▄▄▄ ▄▄█ ▄▄▄\n █▄█ █ █ █ █ █▄█ █ █ █ █ █ █▄ "); - Write(0xcc00, false, " █ █ █ █ █ █▄█\n █ █ █▄█ ▀▄▀ █▄▄ █ █ █▄ █▄█ █ █▄ █▄█ █▄█ █▄▄ int y = 2021;\n "); - Write(0xcc00, false, " \n "); + Write(0xcc00, false, " █ █ █ █ █ █▄█\n █ █ █▄█ ▀▄▀ █▄▄ █ █ █▄ █▄█ █ █▄ █▄█ █▄█ █▄▄ /* 2021 */\n \n "); + Write(0xcc00, false, " "); Write(0xc8ff, false, "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ "); Write(0xcccccc, false, " 1 "); Write(0xffff66, false, "**\n "); - Write(0xb5ed, false, " . . . . '.. . . ... "); - Write(0xffffff, false, ". "); - Write(0xb5ed, false, " ."); - Write(0x9933, true, ". "); + Write(0xb5ed, false, " . . . "); + Write(0xffffff, false, ". "); + Write(0xff00ff, true, ". "); Write(0xa47a4d, false, "..'''' "); Write(0xcccccc, false, " 2 "); Write(0xffff66, false, "**\n "); - Write(0xa2db, false, " . . . . ' "); + Write(0xa2db, false, ". . . "); Write(0xffffff, false, ". "); - Write(0xa2db, false, " '"); - Write(0x66ff, true, ". "); - Write(0x9933, true, ". "); + Write(0xa2db, false, ". ."); + Write(0xff00ff, true, ". "); + Write(0x66ff, true, "."); + Write(0xa2db, false, ". "); Write(0xa47a4d, false, ": "); Write(0xcccccc, false, " 3 "); Write(0xffff66, false, "**\n "); - Write(0x91cc, false, " . . .. . . ."); - Write(0x9933, true, ". "); + Write(0x91cc, false, ". . .. . . .. . . "); + Write(0xff0000, true, ". "); Write(0xffffff, false, ".' "); - Write(0xff9900, true, ". "); + Write(0xff00ff, true, ". "); Write(0xa47a4d, false, "....' "); Write(0xcccccc, false, " 4 "); Write(0xffff66, false, "**\n "); - Write(0x85c0, false, " . . . ."); - Write(0xff00ff, true, ". "); + Write(0x85c0, false, " ' . . "); + Write(0xff0000, true, ". "); Write(0xc74c30, false, "."); Write(0xff0000, false, "."); Write(0xffffff, false, "|\\"); @@ -45,117 +46,112 @@ public void Show() { Write(0xa47a4d, false, "'' "); Write(0xcccccc, false, " 5 "); Write(0xffff66, false, "**\n "); - Write(0x79b5, false, ".'~ ' . . . "); - Write(0xff0000, true, ". "); + Write(0x79b5, false, ". . ' ~ .. "); + Write(0xff00ff, true, ". "); Write(0xa47a4d, false, ": "); Write(0xcccccc, false, " 6 "); Write(0xffff66, false, "**\n "); - Write(0x6daa, false, " ' . . ' . . . "); - Write(0xff0000, true, "."); + Write(0x6daa, false, " ' . "); + Write(0xff9900, true, "."); Write(0xa47a4d, false, ":' "); Write(0xcccccc, false, " 7 "); Write(0xffff66, false, "**\n "); - Write(0x619f, false, "' . . .. .' .. "); - Write(0xff9900, true, "."); + Write(0x619f, false, ". . . . . "); + Write(0x66ff, true, "."); Write(0xa47a4d, false, "'''''..... .."); Write(0xc74c30, false, "."); Write(0xff0000, false, ". "); Write(0xcccccc, false, " 8 "); Write(0xffff66, false, "**\n "); - Write(0x5a98, false, " ' . . . . "); + Write(0x5a98, false, " .. . . '. "); Write(0xa47a4d, false, ":'.."); - Write(0x9933, true, ". "); + Write(0xff00ff, true, ". "); Write(0xa47a4d, false, ".."); - Write(0x9933, true, ". "); - Write(0x66ff, true, "."); + Write(0x66ff, true, ". "); + Write(0xff00ff, true, "."); Write(0xa47a4d, false, "''"); - Write(0x66ff, true, ". "); + Write(0xff00ff, true, ". "); Write(0xff0000, false, "': "); Write(0xcccccc, false, " 9 "); Write(0xffff66, false, "**\n "); - Write(0x5291, false, " . '. "); + Write(0x5291, false, " . . .' . . . "); Write(0xa47a4d, false, ": '' ''''.. "); - Write(0xff9900, true, ". "); - Write(0x66ff, true, "."); + Write(0x66ff, true, ". ."); Write(0xc74c30, false, "'"); Write(0xa47a4d, false, ". "); Write(0xcccccc, false, "10 "); Write(0xffff66, false, "**\n "); - Write(0x4a8a, false, " . . ' . "); + Write(0x4a8a, false, " ... . . . . "); Write(0xa47a4d, false, ": '..'."); - Write(0x9933, true, "."); + Write(0xff00ff, true, "."); Write(0xa47a4d, false, ": "); Write(0xcccccc, false, "11 "); Write(0xffff66, false, "**\n "); - Write(0x4282, false, " ' . .. "); + Write(0x4282, false, " .. . . . . "); Write(0xa47a4d, false, ": :'''.. ..'"); - Write(0x9933, true, "."); + Write(0xff9900, true, "."); Write(0xa47a4d, false, ": "); Write(0xcccccc, false, "12 "); Write(0xffff66, false, "**\n "); - Write(0x3b7b, false, "' ' . . . . "); + Write(0x3b7b, false, " '~ . . . "); Write(0xa47a4d, false, ".' ..''"); - Write(0xff9900, true, ". "); - Write(0xff00ff, true, ". "); + Write(0x66ff, true, ". "); + Write(0x9933, true, ". "); Write(0xa47a4d, false, "'''"); - Write(0xff9900, true, "."); + Write(0xff0000, true, "."); Write(0xa47a4d, false, "...: "); Write(0xcccccc, false, "13 "); Write(0xffff66, false, "**\n "); - Write(0x3374, false, "' . .' . . ' "); + Write(0x3374, false, " . . "); Write(0xa47a4d, false, ": ...''"); - Write(0xff9900, true, ". "); + Write(0x66ff, true, ". "); Write(0xa47a4d, false, "..': "); Write(0xff0000, false, "."); Write(0xc74c30, false, "."); Write(0xa47a4d, false, "..' "); Write(0xcccccc, false, "14 "); Write(0xffff66, false, "**\n "); - Write(0x2e6f, false, " ' . .. . "); - Write(0xff9900, true, "."); - Write(0x2e6f, false, ". "); + Write(0x2e6f, false, " '' . "); + Write(0x66ff, true, "."); + Write(0x2e6f, false, " ."); Write(0x66ff, true, ". "); Write(0xa47a4d, false, ":'"); - Write(0xff0000, true, "."); + Write(0xff9900, true, "."); Write(0xa47a4d, false, "...''' "); Write(0xc74c30, false, "'"); Write(0xff0000, false, "'' "); Write(0xcccccc, false, "15 "); Write(0xffff66, false, "**\n "); Write(0xa47a4d, false, "'.'. "); - Write(0x296b, false, " . "); - Write(0xff9900, true, "."); + Write(0x296b, false, " .' ."); + Write(0x9933, true, "."); Write(0xa47a4d, false, ":'. ....' "); Write(0xcccccc, false, "16 "); Write(0xffff66, false, "**\n "); Write(0xa47a4d, false, ": "); - Write(0x2566, false, " . "); - Write(0x66ff, true, "."); - Write(0x2566, false, ". "); + Write(0x2566, false, "' . "); + Write(0xff0000, true, ". "); Write(0xa47a4d, false, ": ' "); Write(0xcccccc, false, "17 "); Write(0xffff66, false, "**\n "); Write(0x584338, false, ": "); - Write(0x2062, false, " . "); - Write(0xff9900, true, ". "); + Write(0x2062, false, " . . "); + Write(0xff00ff, true, ". "); Write(0x584338, false, "..' "); Write(0xcccccc, false, "18 "); Write(0xffff66, false, "**\n "); - Write(0x584338, false, "'. "); - Write(0x1b5e, false, " . "); - Write(0xff0000, true, ". "); + Write(0x584338, false, "'. "); + Write(0xff00ff, true, ". "); Write(0x584338, false, ": "); Write(0xcccccc, false, "19 "); Write(0xffff66, false, "**\n "); - Write(0x584338, false, "'. "); - Write(0x1759, false, ". . "); + Write(0x584338, false, "'. "); Write(0x66ff, true, ". "); Write(0x584338, false, ": "); Write(0xcccccc, false, "20 "); Write(0xffff66, false, "**\n "); - Write(0x584338, false, ": "); - Write(0x1255, false, ". "); - Write(0x66ff, true, ". "); + Write(0x584338, false, ": "); + Write(0xff00ff, true, ". "); Write(0x584338, false, ": "); Write(0xcccccc, false, "21 "); Write(0xffff66, false, "**\n "); @@ -165,13 +161,14 @@ public void Show() { Write(0x584338, false, ": "); Write(0xcccccc, false, "22 "); Write(0xffff66, false, "**\n "); - Write(0x584338, false, ": "); - Write(0xff9900, true, "."); + Write(0x584338, false, ": "); + Write(0x94c, false, ". "); + Write(0x9933, true, "."); Write(0x584338, false, ".' "); Write(0xcccccc, false, "23 "); Write(0xffff66, false, "**\n "); Write(0x584338, false, ": "); - Write(0xff9900, true, ". "); + Write(0x66ff, true, ". "); Write(0x584338, false, ".' "); Write(0xcccccc, false, "24 "); Write(0xffff66, false, "**\n "); @@ -183,7 +180,7 @@ public void Show() { Console.WriteLine(); } - private static void Write(int rgb, bool bold, string text){ + private static void Write(int rgb, bool bold, string text){ Console.Write($"\u001b[38;2;{(rgb>>16)&255};{(rgb>>8)&255};{rgb&255}{(bold ? ";1" : "")}m{text}"); - } -} \ No newline at end of file + } +} diff --git a/2021/calendar.svg b/2021/calendar.svg index 00500cbb7..28b14d767 100644 --- a/2021/calendar.svg +++ b/2021/calendar.svg @@ -1,4 +1,4 @@ - + star fruit that only grows deep in the jungle. The Elves have brought you on their annual expedition to the grove where the fruit grows. To supply enough magical energy, the expedition needs to retrieve a minimum of fifty stars by December 25th. Although the Elves assure you that the grove has plenty of fruit, you decide to grab any fruit you see along the way, just in case. -_Visit the website for the full story and [full puzzle](https://adventofcode.com/2022/day/1) description._ +Collect stars by solving puzzles. Two puzzles will be made available on each day in the Advent calendar; the second puzzle is unlocked when you complete the first. Each puzzle grants one star. Good luck! + +The jungle must be too overgrown and difficult to navigate in vehicles or access from the air; the Elves' expedition traditionally goes on foot. As your boats approach land, the Elves begin taking inventory of their supplies. One important consideration is food - in particular, the number of Calories each Elf is carrying (your puzzle input). + +The Elves take turns writing down the number of Calories contained by the various meals, snacks, rations, etc. that they've brought with them, one item per line. Each Elf separates their own inventory from the previous Elf's inventory (if any) by a blank line. + +For example, suppose the Elves finish writing their items' Calories and end up with the following list: + +
+1000
+2000
+3000
+
+4000
+
+5000
+6000
+
+7000
+8000
+9000
+
+10000
+
+
+ +This list represents the Calories of the food carried by five Elves: + + + - The first Elf is carrying food with 1000, 2000, and 3000 Calories, a total of 6000 Calories. + - The second Elf is carrying one food item with 4000 Calories. + - The third Elf is carrying food with 5000 and 6000 Calories, a total of 11000 Calories. + - The fourth Elf is carrying food with 7000, 8000, and 9000 Calories, a total of 24000 Calories. + - The fifth Elf is carrying one food item with 10000 Calories. + +In case the Elves get hungry and need extra snacks, they need to know which Elf to ask: they'd like to know how many Calories are being carried by the Elf carrying the most Calories. In the example above, this is 24000 (carried by the fourth Elf). + +Find the Elf carrying the most Calories. How many total Calories is that Elf carrying? + + +## --- Part Two --- +By the time you calculate the answer to the Elves' question, they've already realized that the Elf carrying the most Calories of food might eventually run out of snacks. + +To avoid this unacceptable situation, the Elves would instead like to know the total Calories carried by the top three Elves carrying the most Calories. That way, even if one of those Elves runs out of snacks, they still have two backups. + +In the example above, the top three Elves are the fourth Elf (with 24000 Calories), then the third Elf (with 11000 Calories), then the fifth Elf (with 10000 Calories). The sum of the Calories carried by these three elves is 45000. + +Find the top three Elves carrying the most Calories. How many Calories are those Elves carrying in total? + + diff --git a/2022/Day01/input.in b/2022/Day01/input.in index d53279bef..ff47b8a72 100644 Binary files a/2022/Day01/input.in and b/2022/Day01/input.in differ diff --git a/2022/Day02/README.md b/2022/Day02/README.md index a25c2f63c..53d0bc35b 100644 --- a/2022/Day02/README.md +++ b/2022/Day02/README.md @@ -1,6 +1,50 @@ +original source: [https://adventofcode.com/2022/day/2](https://adventofcode.com/2022/day/2) ## --- Day 2: Rock Paper Scissors --- The Elves begin to set up camp on the beach. To decide whose tent gets to be closest to the snack storage, a giant [Rock Paper Scissors](https://en.wikipedia.org/wiki/Rock_paper_scissors) tournament is already in progress. Rock Paper Scissors is a game between two players. Each game contains many rounds; in each round, the players each simultaneously choose one of Rock, Paper, or Scissors using a hand shape. Then, a winner for that round is selected: Rock defeats Scissors, Scissors defeats Paper, and Paper defeats Rock. If both players choose the same shape, the round instead ends in a draw. -Read the [full puzzle](https://adventofcode.com/2022/day/2). \ No newline at end of file +Appreciative of your help yesterday, one Elf gives you an encrypted strategy guide (your puzzle input) that they say will be sure to help you win. "The first column is what your opponent is going to play: A for Rock, B for Paper, and C for Scissors. The second column--" Suddenly, the Elf is called away to help with someone's tent. + +The second column, you reason, must be what you should play in response: X for Rock, Y for Paper, and Z for Scissors. Winning every time would be suspicious, so the responses must have been carefully chosen. + +The winner of the whole tournament is the player with the highest score. Your total score is the sum of your scores for each round. The score for a single round is the score for the shape you selected (1 for Rock, 2 for Paper, and 3 for Scissors) plus the score for the outcome of the round (0 if you lost, 3 if the round was a draw, and 6 if you won). + +Since you can't be sure if the Elf is trying to help you or trick you, you should calculate the score you would get if you were to follow the strategy guide. + +For example, suppose you were given the following strategy guide: + +
+A Y
+B X
+C Z
+
+
+ +This strategy guide predicts and recommends the following: + + + - In the first round, your opponent will choose Rock (A), and you should choose Paper (Y). This ends in a win for you with a score of 8 (2 because you chose Paper + 6 because you won). + - In the second round, your opponent will choose Paper (B), and you should choose Rock (X). This ends in a loss for you with a score of 1 (1 + 0). + - The third round is a draw with both players choosing Scissors, giving you a score of 3 + 3 = 6. + +In this example, if you were to follow the strategy guide, you would get a total score of 15 (8 + 1 + 6). + +What would your total score be if everything goes exactly according to your strategy guide? + + +## --- Part Two --- +The Elf finishes helping with the tent and sneaks back over to you. "Anyway, the second column says how the round needs to end: X means you need to lose, Y means you need to end the round in a draw, and Z means you need to win. Good luck!" + +The total score is still calculated in the same way, but now you need to figure out what shape to choose so the round ends as indicated. The example above now goes like this: + + + - In the first round, your opponent will choose Rock (A), and you need the round to end in a draw (Y), so you also choose Rock. This gives you a score of 1 + 3 = 4. + - In the second round, your opponent will choose Paper (B), and you choose Rock so you lose (X) with a score of 1 + 0 = 1. + - In the third round, you will defeat your opponent's Scissors with Rock for a score of 1 + 6 = 7. + +Now that you're correctly decrypting the ultra top secret strategy guide, you would get a total score of 12. + +Following the Elf's instructions for the second column, what would your total score be if everything goes exactly according to your strategy guide? + + diff --git a/2022/Day02/input.in b/2022/Day02/input.in index d72a808b5..cb4efdf57 100644 Binary files a/2022/Day02/input.in and b/2022/Day02/input.in differ diff --git a/2022/Day03/README.md b/2022/Day03/README.md index a94f9ec2d..7050eaa60 100644 --- a/2022/Day03/README.md +++ b/2022/Day03/README.md @@ -1,6 +1,75 @@ +original source: [https://adventofcode.com/2022/day/3](https://adventofcode.com/2022/day/3) ## --- Day 3: Rucksack Reorganization --- One Elf has the important job of loading all of the [rucksacks](https://en.wikipedia.org/wiki/Rucksack) with supplies for the jungle journey. Unfortunately, that Elf didn't quite follow the packing instructions, and so a few items now need to be rearranged. Each rucksack has two large compartments. All items of a given type are meant to go into exactly one of the two compartments. The Elf that did the packing failed to follow this rule for exactly one item type per rucksack. -Read the [full puzzle](https://adventofcode.com/2022/day/3). \ No newline at end of file +The Elves have made a list of all of the items currently in each rucksack (your puzzle input), but they need your help finding the errors. Every item type is identified by a single lowercase or uppercase letter (that is, a and A refer to different types of items). + +The list of items for each rucksack is given as characters all on a single line. A given rucksack always has the same number of items in each of its two compartments, so the first half of the characters represent items in the first compartment, while the second half of the characters represent items in the second compartment. + +For example, suppose you have the following list of contents from six rucksacks: + +
+vJrwpWtwJgWrhcsFMMfFFhFp
+jqHRNqRjqzjGDLGLrsFMfFZSrLrFZsSL
+PmmdzqPrVvPwwTWBwg
+wMqvLMZHhHMvwLHjbvcjnnSBnvTQFn
+ttgJtRGJQctTZtZT
+CrZsJsPPZsGzwwsLwLmpwMDw
+
+
+ + + - The first rucksack contains the items vJrwpWtwJgWrhcsFMMfFFhFp, which means its first compartment contains the items vJrwpWtwJgWr, while the second compartment contains the items hcsFMMfFFhFp. The only item type that appears in both compartments is lowercase p. + - The second rucksack's compartments contain jqHRNqRjqzjGDLGL and rsFMfFZSrLrFZsSL. The only item type that appears in both compartments is uppercase L. + - The third rucksack's compartments contain PmmdzqPrV and vPwwTWBwg; the only common item type is uppercase P. + - The fourth rucksack's compartments only share item type v. + - The fifth rucksack's compartments only share item type t. + - The sixth rucksack's compartments only share item type s. + +To help prioritize item rearrangement, every item type can be converted to a priority: + + + - Lowercase item types a through z have priorities 1 through 26. + - Uppercase item types A through Z have priorities 27 through 52. + +In the above example, the priority of the item type that appears in both compartments of each rucksack is 16 (p), 38 (L), 42 (P), 22 (v), 20 (t), and 19 (s); the sum of these is 157. + +Find the item type that appears in both compartments of each rucksack. What is the sum of the priorities of those item types? + + +## --- Part Two --- +As you finish identifying the misplaced items, the Elves come to you with another issue. + +For safety, the Elves are divided into groups of three. Every Elf carries a badge that identifies their group. For efficiency, within each group of three Elves, the badge is the only item type carried by all three Elves. That is, if a group's badge is item type B, then all three Elves will have item type B somewhere in their rucksack, and at most two of the Elves will be carrying any other item type. + +The problem is that someone forgot to put this year's updated authenticity sticker on the badges. All of the badges need to be pulled out of the rucksacks so the new authenticity stickers can be attached. + +Additionally, nobody wrote down which item type corresponds to each group's badges. The only way to tell which item type is the right one is by finding the one item type that is common between all three Elves in each group. + +Every set of three lines in your list corresponds to a single group, but each group can have a different badge item type. So, in the above example, the first group's rucksacks are the first three lines: + +
+vJrwpWtwJgWrhcsFMMfFFhFp
+jqHRNqRjqzjGDLGLrsFMfFZSrLrFZsSL
+PmmdzqPrVvPwwTWBwg
+
+
+ +And the second group's rucksacks are the next three lines: + +
+wMqvLMZHhHMvwLHjbvcjnnSBnvTQFn
+ttgJtRGJQctTZtZT
+CrZsJsPPZsGzwwsLwLmpwMDw
+
+
+ +In the first group, the only item type that appears in all three rucksacks is lowercase r; this must be their badges. In the second group, their badge item type must be Z. + +Priorities for these items must still be found to organize the sticker attachment efforts: here, they are 18 (r) for the first group and 52 (Z) for the second group. The sum of these is 70. + +Find the item type that corresponds to the badges of each three-Elf group. What is the sum of the priorities of those item types? + + diff --git a/2022/Day03/input.in b/2022/Day03/input.in index c05cdfe70..1e9f1dd2f 100644 Binary files a/2022/Day03/input.in and b/2022/Day03/input.in differ diff --git a/2022/Day04/README.md b/2022/Day04/README.md index 12dcd50de..23edc31eb 100644 --- a/2022/Day04/README.md +++ b/2022/Day04/README.md @@ -1,6 +1,69 @@ +original source: [https://adventofcode.com/2022/day/4](https://adventofcode.com/2022/day/4) ## --- Day 4: Camp Cleanup --- Space needs to be cleared before the last supplies can be unloaded from the ships, and so several Elves have been assigned the job of cleaning up sections of the camp. Every section has a unique ID number, and each Elf is assigned a range of section IDs. However, as some of the Elves compare their section assignments with each other, they've noticed that many of the assignments overlap. To try to quickly find overlaps and reduce duplicated effort, the Elves pair up and make a big list of the section assignments for each pair (your puzzle input). -Read the [full puzzle](https://adventofcode.com/2022/day/4). \ No newline at end of file +For example, consider the following list of section assignment pairs: + +
+2-4,6-8
+2-3,4-5
+5-7,7-9
+2-8,3-7
+6-6,4-6
+2-6,4-8
+
+
+ +For the first few pairs, this list means: + + + - Within the first pair of Elves, the first Elf was assigned sections 2-4 (sections 2, 3, and 4), while the second Elf was assigned sections 6-8 (sections 6, 7, 8). + - The Elves in the second pair were each assigned two sections. + - The Elves in the third pair were each assigned three sections: one got sections 5, 6, and 7, while the other also got 7, plus 8 and 9. + +This example list uses single-digit section IDs to make it easier to draw; your actual list might contain larger numbers. Visually, these pairs of section assignments look like this: + +
+.234.....  2-4
+.....678.  6-8
+
+.23......  2-3
+...45....  4-5
+
+....567..  5-7
+......789  7-9
+
+.2345678.  2-8
+..34567..  3-7
+
+.....6...  6-6
+...456...  4-6
+
+.23456...  2-6
+...45678.  4-8
+
+
+ +Some of the pairs have noticed that one of their assignments fully contains the other. For example, 2-8 fully contains 3-7, and 6-6 is fully contained by 4-6. In pairs where one assignment fully contains the other, one Elf in the pair would be exclusively cleaning sections their partner will already be cleaning, so these seem like the most in need of reconsideration. In this example, there are 2 such pairs. + +In how many assignment pairs does one range fully contain the other? + + +## --- Part Two --- +It seems like there is still quite a bit of duplicate work planned. Instead, the Elves would like to know the number of pairs that overlap at all. + +In the above example, the first two pairs (2-4,6-8 and 2-3,4-5) don't overlap, while the remaining four pairs (5-7,7-9, 2-8,3-7, 6-6,4-6, and 2-6,4-8) do overlap: + + + - 5-7,7-9 overlaps in a single section, 7. + - 2-8,3-7 overlaps all of the sections 3 through 7. + - 6-6,4-6 overlaps in a single section, 6. + - 2-6,4-8 overlaps in sections 4, 5, and 6. + +So, in this example, the number of overlapping assignment pairs is 4. + +In how many assignment pairs do the ranges overlap? + + diff --git a/2022/Day04/input.in b/2022/Day04/input.in index be3ffb735..c84044f51 100644 Binary files a/2022/Day04/input.in and b/2022/Day04/input.in differ diff --git a/2022/Day05/README.md b/2022/Day05/README.md index 0ed9547fd..813d8d04b 100644 --- a/2022/Day05/README.md +++ b/2022/Day05/README.md @@ -1,6 +1,138 @@ +original source: [https://adventofcode.com/2022/day/5](https://adventofcode.com/2022/day/5) ## --- Day 5: Supply Stacks --- The expedition can depart as soon as the final supplies have been unloaded from the ships. Supplies are stored in stacks of marked crates, but because the needed supplies are buried under many other crates, the crates need to be rearranged. The ship has a giant cargo crane capable of moving crates between stacks. To ensure none of the crates get crushed or fall over, the crane operator will rearrange them in a series of carefully-planned steps. After the crates are rearranged, the desired crates will be at the top of each stack. -Read the [full puzzle](https://adventofcode.com/2022/day/5). \ No newline at end of file +The Elves don't want to interrupt the crane operator during this delicate procedure, but they forgot to ask her which crate will end up where, and they want to be ready to unload them as soon as possible so they can embark. + +They do, however, have a drawing of the starting stacks of crates and the rearrangement procedure (your puzzle input). For example: + +
+    [D]    
+[N] [C]    
+[Z] [M] [P]
+ 1   2   3 
+
+move 1 from 2 to 1
+move 3 from 1 to 3
+move 2 from 2 to 1
+move 1 from 1 to 2
+
+
+ +In this example, there are three stacks of crates. Stack 1 contains two crates: crate Z is on the bottom, and crate N is on top. Stack 2 contains three crates; from bottom to top, they are crates M, C, and D. Finally, stack 3 contains a single crate, P. + +Then, the rearrangement procedure is given. In each step of the procedure, a quantity of crates is moved from one stack to a different stack. In the first step of the above rearrangement procedure, one crate is moved from stack 2 to stack 1, resulting in this configuration: + +
+[D]        
+[N] [C]    
+[Z] [M] [P]
+ 1   2   3 
+
+
+ +In the second step, three crates are moved from stack 1 to stack 3. Crates are moved one at a time, so the first crate to be moved (D) ends up below the second and third crates: + +
+        [Z]
+        [N]
+    [C] [D]
+    [M] [P]
+ 1   2   3
+
+
+ +Then, both crates are moved from stack 2 to stack 1. Again, because crates are moved one at a time, crate C ends up below crate M: + +
+        [Z]
+        [N]
+[M]     [D]
+[C]     [P]
+ 1   2   3
+
+
+ +Finally, one crate is moved from stack 1 to stack 2: + +
+        [Z]
+        [N]
+        [D]
+[C] [M] [P]
+ 1   2   3
+
+
+ +The Elves just need to know which crate will end up on top of each stack; in this example, the top crates are C in stack 1, M in stack 2, and Z in stack 3, so you should combine these together and give the Elves the message CMZ. + +After the rearrangement procedure completes, what crate ends up on top of each stack? + + +## --- Part Two --- +As you watch the crane operator expertly rearrange the crates, you notice the process isn't following your prediction. + +Some mud was covering the writing on the side of the crane, and you quickly wipe it away. The crane isn't a CrateMover 9000 - it's a CrateMover 9001. + +The CrateMover 9001 is notable for many new and exciting features: air conditioning, leather seats, an extra cup holder, and the ability to pick up and move multiple crates at once. + +Again considering the example above, the crates begin in the same configuration: + +
+    [D]    
+[N] [C]    
+[Z] [M] [P]
+ 1   2   3 
+
+
+ +Moving a single crate from stack 2 to stack 1 behaves the same as before: + +
+[D]        
+[N] [C]    
+[Z] [M] [P]
+ 1   2   3 
+
+
+ +However, the action of moving three crates from stack 1 to stack 3 means that those three moved crates stay in the same order, resulting in this new configuration: + +
+        [D]
+        [N]
+    [C] [Z]
+    [M] [P]
+ 1   2   3
+
+
+ +Next, as both crates are moved from stack 2 to stack 1, they retain their order as well: + +
+        [D]
+        [N]
+[C]     [Z]
+[M]     [P]
+ 1   2   3
+
+
+ +Finally, a single crate is still moved from stack 1 to stack 2, but now it's crate C that gets moved: + +
+        [D]
+        [N]
+        [Z]
+[M] [C] [P]
+ 1   2   3
+
+
+ +In this example, the CrateMover 9001 has put the crates in a totally different order: MCD. + +Before the rearrangement process finishes, update your simulation so that the Elves know where they should stand to be ready to unload the final supplies. After the rearrangement procedure completes, what crate ends up on top of each stack? + + diff --git a/2022/Day05/input.in b/2022/Day05/input.in index fbba47b11..33b0fd699 100644 Binary files a/2022/Day05/input.in and b/2022/Day05/input.in differ diff --git a/2022/Day06/README.md b/2022/Day06/README.md index e58f42a31..dc4ed6881 100644 --- a/2022/Day06/README.md +++ b/2022/Day06/README.md @@ -1,6 +1,54 @@ +original source: [https://adventofcode.com/2022/day/6](https://adventofcode.com/2022/day/6) ## --- Day 6: Tuning Trouble --- The preparations are finally complete; you and the Elves leave camp on foot and begin to make your way toward the star fruit grove. As you move through the dense undergrowth, one of the Elves gives you a handheld device. He says that it has many fancy features, but the most important one to set up right now is the communication system. -Read the [full puzzle](https://adventofcode.com/2022/day/6). \ No newline at end of file +However, because he's heard you have [significant](/2016/day/6) [experience](/2016/day/25) [dealing](/2019/day/7) [with](/2019/day/9) [signal-based](/2019/day/16) [systems](/2021/day/25), he convinced the other Elves that it would be okay to give you their one malfunctioning device - surely you'll have no problem fixing it. + +As if inspired by comedic timing, the device emits a few colorful sparks. + +To be able to communicate with the Elves, the device needs to lock on to their signal. The signal is a series of seemingly-random characters that the device receives one at a time. + +To fix the communication system, you need to add a subroutine to the device that detects a start-of-packet marker in the datastream. In the protocol being used by the Elves, the start of a packet is indicated by a sequence of four characters that are all different. + +The device will send your subroutine a datastream buffer (your puzzle input); your subroutine needs to identify the first position where the four most recently received characters were all different. Specifically, it needs to report the number of characters from the beginning of the buffer to the end of the first such four-character marker. + +For example, suppose you receive the following datastream buffer: + +
+mjqjpqmgbljsphdztnvjfqwrcgsmlb
+
+ +After the first three characters (mjq) have been received, there haven't been enough characters received yet to find the marker. The first time a marker could occur is after the fourth character is received, making the most recent four characters mjqj. Because j is repeated, this isn't a marker. + +The first time a marker appears is after the seventh character arrives. Once it does, the last four characters received are jpqm, which are all different. In this case, your subroutine should report the value 7, because the first start-of-packet marker is complete after 7 characters have been processed. + +Here are a few more examples: + + + - bvwbjplbgvbhsrlpgdmjqwftvncz: first marker after character 5 + - nppdvjthqldpwncqszvftbrmjlhg: first marker after character 6 + - nznrnfrfntjfmvfwmzdfjlvtqnbhcprsg: first marker after character 10 + - zcfzfwzzqfrljwzlrfnpqdbhtmscgvjw: first marker after character 11 + +How many characters need to be processed before the first start-of-packet marker is detected? + + +## --- Part Two --- +Your device's communication system is correctly detecting packets, but still isn't working. It looks like it also needs to look for messages. + +A start-of-message marker is just like a start-of-packet marker, except it consists of 14 distinct characters rather than 4. + +Here are the first positions of start-of-message markers for all of the above examples: + + + - mjqjpqmgbljsphdztnvjfqwrcgsmlb: first marker after character 19 + - bvwbjplbgvbhsrlpgdmjqwftvncz: first marker after character 23 + - nppdvjthqldpwncqszvftbrmjlhg: first marker after character 23 + - nznrnfrfntjfmvfwmzdfjlvtqnbhcprsg: first marker after character 29 + - zcfzfwzzqfrljwzlrfnpqdbhtmscgvjw: first marker after character 26 + +How many characters need to be processed before the first start-of-message marker is detected? + + diff --git a/2022/Day06/input.in b/2022/Day06/input.in index 4addfad05..842f18ba7 100644 Binary files a/2022/Day06/input.in and b/2022/Day06/input.in differ diff --git a/2022/Day07/README.md b/2022/Day07/README.md index dab501f18..addf39b5b 100644 --- a/2022/Day07/README.md +++ b/2022/Day07/README.md @@ -1,6 +1,119 @@ +original source: [https://adventofcode.com/2022/day/7](https://adventofcode.com/2022/day/7) ## --- Day 7: No Space Left On Device --- You can hear birds chirping and raindrops hitting leaves as the expedition proceeds. Occasionally, you can even hear much louder sounds in the distance; how big do the animals get out here, anyway? The device the Elves gave you has problems with more than just its communication system. You try to run a system update: -Read the [full puzzle](https://adventofcode.com/2022/day/7). \ No newline at end of file +
+$ system-update --please --pretty-please-with-sugar-on-top
+Error: No space left on device
+
+
+ +Perhaps you can delete some files to make space for the update? + +You browse around the filesystem to assess the situation and save the resulting terminal output (your puzzle input). For example: + +
+$ cd /
+$ ls
+dir a
+14848514 b.txt
+8504156 c.dat
+dir d
+$ cd a
+$ ls
+dir e
+29116 f
+2557 g
+62596 h.lst
+$ cd e
+$ ls
+584 i
+$ cd ..
+$ cd ..
+$ cd d
+$ ls
+4060174 j
+8033020 d.log
+5626152 d.ext
+7214296 k
+
+
+ +The filesystem consists of a tree of files (plain data) and directories (which can contain other directories or files). The outermost directory is called /. You can navigate around the filesystem, moving into or out of directories and listing the contents of the directory you're currently in. + +Within the terminal output, lines that begin with $ are commands you executed, very much like some modern computers: + + + - cd means change directory. This changes which directory is the current directory, but the specific result depends on the argument: + + - cd x moves in one level: it looks in the current directory for the directory named x and makes it the current directory. + - cd .. moves out one level: it finds the directory that contains the current directory, then makes that directory the current directory. + - cd / switches the current directory to the outermost directory, /. + + + - ls means list. It prints out all of the files and directories immediately contained by the current directory: + + - 123 abc means that the current directory contains a file named abc with size 123. + - dir xyz means that the current directory contains a directory named xyz. + + + +Given the commands and output in the example above, you can determine that the filesystem looks visually like this: + +
+- / (dir)
+  - a (dir)
+    - e (dir)
+      - i (file, size=584)
+    - f (file, size=29116)
+    - g (file, size=2557)
+    - h.lst (file, size=62596)
+  - b.txt (file, size=14848514)
+  - c.dat (file, size=8504156)
+  - d (dir)
+    - j (file, size=4060174)
+    - d.log (file, size=8033020)
+    - d.ext (file, size=5626152)
+    - k (file, size=7214296)
+
+
+ +Here, there are four directories: / (the outermost directory), a and d (which are in /), and e (which is in a). These directories also contain files of various sizes. + +Since the disk is full, your first step should probably be to find directories that are good candidates for deletion. To do this, you need to determine the total size of each directory. The total size of a directory is the sum of the sizes of the files it contains, directly or indirectly. (Directories themselves do not count as having any intrinsic size.) + +The total sizes of the directories above can be found as follows: + + + - The total size of directory e is 584 because it contains a single file i of size 584 and no other directories. + - The directory a has total size 94853 because it contains files f (size 29116), g (size 2557), and h.lst (size 62596), plus file i indirectly (a contains e which contains i). + - Directory d has total size 24933642. + - As the outermost directory, / contains every file. Its total size is 48381165, the sum of the size of every file. + +To begin, find all of the directories with a total size of at most 100000, then calculate the sum of their total sizes. In the example above, these directories are a and e; the sum of their total sizes is 95437 (94853 + 584). (As in this example, this process can count files more than once!) + +Find all of the directories with a total size of at most 100000. What is the sum of the total sizes of those directories? + + +## --- Part Two --- +Now, you're ready to choose a directory to delete. + +The total disk space available to the filesystem is 70000000. To run the update, you need unused space of at least 30000000. You need to find a directory you can delete that will free up enough space to run the update. + +In the example above, the total size of the outermost directory (and thus the total amount of used space) is 48381165; this means that the size of the unused space must currently be 21618835, which isn't quite the 30000000 required by the update. Therefore, the update still requires a directory with total size of at least 8381165 to be deleted before it can run. + +To achieve this, you have the following options: + + + - Delete directory e, which would increase unused space by 584. + - Delete directory a, which would increase unused space by 94853. + - Delete directory d, which would increase unused space by 24933642. + - Delete directory /, which would increase unused space by 48381165. + +Directories e and a are both too small; deleting them would not free up enough space. However, directories d and / are both big enough! Between these, choose the smallest: d, increasing unused space by 24933642. + +Find the smallest directory that, if deleted, would free up enough space on the filesystem to run the update. What is the total size of that directory? + + diff --git a/2022/Day07/input.in b/2022/Day07/input.in index 4e7063aff..efd90442f 100644 Binary files a/2022/Day07/input.in and b/2022/Day07/input.in differ diff --git a/2022/Day08/README.md b/2022/Day08/README.md index 95d1ac8d8..a59a7f0a9 100644 --- a/2022/Day08/README.md +++ b/2022/Day08/README.md @@ -1,6 +1,85 @@ +original source: [https://adventofcode.com/2022/day/8](https://adventofcode.com/2022/day/8) ## --- Day 8: Treetop Tree House --- The expedition comes across a peculiar patch of tall trees all planted carefully in a grid. The Elves explain that a previous expedition planted these trees as a reforestation effort. Now, they're curious if this would be a good location for a [tree house](https://en.wikipedia.org/wiki/Tree_house). First, determine whether there is enough tree cover here to keep a tree house hidden. To do this, you need to count the number of trees that are visible from outside the grid when looking directly along a row or column. -Read the [full puzzle](https://adventofcode.com/2022/day/8). \ No newline at end of file +The Elves have already launched a [quadcopter](https://en.wikipedia.org/wiki/Quadcopter) to generate a map with the height of each tree (your puzzle input). For example: + +
+30373
+25512
+65332
+33549
+35390
+
+
+ +Each tree is represented as a single digit whose value is its height, where 0 is the shortest and 9 is the tallest. + +A tree is visible if all of the other trees between it and an edge of the grid are shorter than it. Only consider trees in the same row or column; that is, only look up, down, left, or right from any given tree. + +All of the trees around the edge of the grid are visible - since they are already on the edge, there are no trees to block the view. In this example, that only leaves the interior nine trees to consider: + + + - The top-left 5 is visible from the left and top. (It isn't visible from the right or bottom since other trees of height 5 are in the way.) + - The top-middle 5 is visible from the top and right. + - The top-right 1 is not visible from any direction; for it to be visible, there would need to only be trees of height 0 between it and an edge. + - The left-middle 5 is visible, but only from the right. + - The center 3 is not visible from any direction; for it to be visible, there would need to be only trees of at most height 2 between it and an edge. + - The right-middle 3 is visible from the right. + - In the bottom row, the middle 5 is visible, but the 3 and 4 are not. + +With 16 trees visible on the edge and another 5 visible in the interior, a total of 21 trees are visible in this arrangement. + +Consider your map; how many trees are visible from outside the grid? + + +## --- Part Two --- +Content with the amount of tree cover available, the Elves just need to know the best spot to build their tree house: they would like to be able to see a lot of trees. + +To measure the viewing distance from a given tree, look up, down, left, and right from that tree; stop if you reach an edge or at the first tree that is the same height or taller than the tree under consideration. (If a tree is right on the edge, at least one of its viewing distances will be zero.) + +The Elves don't care about distant trees taller than those found by the rules above; the proposed tree house has large [eaves](https://en.wikipedia.org/wiki/Eaves) to keep it dry, so they wouldn't be able to see higher than the tree house anyway. + +In the example above, consider the middle 5 in the second row: + +
+30373
+25512
+65332
+33549
+35390
+
+
+ + + - Looking up, its view is not blocked; it can see 1 tree (of height 3). + - Looking left, its view is blocked immediately; it can see only 1 tree (of height 5, right next to it). + - Looking right, its view is not blocked; it can see 2 trees. + - Looking down, its view is blocked eventually; it can see 2 trees (one of height 3, then the tree of height 5 that blocks its view). + +A tree's scenic score is found by multiplying together its viewing distance in each of the four directions. For this tree, this is 4 (found by multiplying 1 * 1 * 2 * 2). + +However, you can do even better: consider the tree of height 5 in the middle of the fourth row: + +
+30373
+25512
+65332
+33549
+35390
+
+
+ + + - Looking up, its view is blocked at 2 trees (by another tree with a height of 5). + - Looking left, its view is not blocked; it can see 2 trees. + - Looking down, its view is also not blocked; it can see 1 tree. + - Looking right, its view is blocked at 2 trees (by a massive tree of height 9). + +This tree's scenic score is 8 (2 * 2 * 1 * 2); this is the ideal spot for the tree house. + +Consider each tree on your map. What is the highest scenic score possible for any tree? + + diff --git a/2022/Day08/input.in b/2022/Day08/input.in index a78bc6205..e1f1f475e 100644 Binary files a/2022/Day08/input.in and b/2022/Day08/input.in differ diff --git a/2022/Day09/README.md b/2022/Day09/README.md index 632053f96..f3448ab9a 100644 --- a/2022/Day09/README.md +++ b/2022/Day09/README.md @@ -1,6 +1,715 @@ +original source: [https://adventofcode.com/2022/day/9](https://adventofcode.com/2022/day/9) ## --- Day 9: Rope Bridge --- This rope bridge creaks as you walk along it. You aren't sure how old it is, or whether it can even support your weight. It seems to support the Elves just fine, though. The bridge spans a gorge which was carved out by the massive river far below you. -Read the [full puzzle](https://adventofcode.com/2022/day/9). \ No newline at end of file +You step carefully; as you do, the ropes stretch and twist. You decide to distract yourself by modeling rope physics; maybe you can even figure out where not to step. + +Consider a rope with a knot at each end; these knots mark the head and the tail of the rope. If the head moves far enough away from the tail, the tail is pulled toward the head. + +Due to nebulous reasoning involving [Planck lengths](https://en.wikipedia.org/wiki/Planck_units#Planck_length), you should be able to model the positions of the knots on a two-dimensional grid. Then, by following a hypothetical series of motions (your puzzle input) for the head, you can determine how the tail will move. + +Due to the aforementioned Planck lengths, the rope must be quite short; in fact, the head (H) and tail (T) must always be touching (diagonally adjacent and even overlapping both count as touching): + +
+....
+.TH.
+....
+
+....
+.H..
+..T.
+....
+
+...
+.H. (H covers T)
+...
+
+
+ +If the head is ever two steps directly up, down, left, or right from the tail, the tail must also move one step in that direction so it remains close enough: + +
+.....    .....    .....
+.TH.. -> .T.H. -> ..TH.
+.....    .....    .....
+
+...    ...    ...
+.T.    .T.    ...
+.H. -> ... -> .T.
+...    .H.    .H.
+...    ...    ...
+
+
+ +Otherwise, if the head and tail aren't touching and aren't in the same row or column, the tail always moves one step diagonally to keep up: + +
+.....    .....    .....
+.....    ..H..    ..H..
+..H.. -> ..... -> ..T..
+.T...    .T...    .....
+.....    .....    .....
+
+.....    .....    .....
+.....    .....    .....
+..H.. -> ...H. -> ..TH.
+.T...    .T...    .....
+.....    .....    .....
+
+
+ +You just need to work out where the tail goes as the head follows a series of motions. Assume the head and the tail both start at the same position, overlapping. + +For example: + +
+R 4
+U 4
+L 3
+D 1
+R 4
+D 1
+L 5
+R 2
+
+
+ +This series of motions moves the head right four steps, then up four steps, then left three steps, then down one step, and so on. After each step, you'll need to update the position of the tail if the step means the head is no longer adjacent to the tail. Visually, these motions occur as follows (s marks the starting position as a reference point): + +
+== Initial State ==
+
+......
+......
+......
+......
+H.....  (H covers T, s)
+
+== R 4 ==
+
+......
+......
+......
+......
+TH....  (T covers s)
+
+......
+......
+......
+......
+sTH...
+
+......
+......
+......
+......
+s.TH..
+
+......
+......
+......
+......
+s..TH.
+
+== U 4 ==
+
+......
+......
+......
+....H.
+s..T..
+
+......
+......
+....H.
+....T.
+s.....
+
+......
+....H.
+....T.
+......
+s.....
+
+....H.
+....T.
+......
+......
+s.....
+
+== L 3 ==
+
+...H..
+....T.
+......
+......
+s.....
+
+..HT..
+......
+......
+......
+s.....
+
+.HT...
+......
+......
+......
+s.....
+
+== D 1 ==
+
+..T...
+.H....
+......
+......
+s.....
+
+== R 4 ==
+
+..T...
+..H...
+......
+......
+s.....
+
+..T...
+...H..
+......
+......
+s.....
+
+......
+...TH.
+......
+......
+s.....
+
+......
+....TH
+......
+......
+s.....
+
+== D 1 ==
+
+......
+....T.
+.....H
+......
+s.....
+
+== L 5 ==
+
+......
+....T.
+....H.
+......
+s.....
+
+......
+....T.
+...H..
+......
+s.....
+
+......
+......
+..HT..
+......
+s.....
+
+......
+......
+.HT...
+......
+s.....
+
+......
+......
+HT....
+......
+s.....
+
+== R 2 ==
+
+......
+......
+.H....  (H covers T)
+......
+s.....
+
+......
+......
+.TH...
+......
+s.....
+
+
+ +After simulating the rope, you can count up all of the positions the tail visited at least once. In this diagram, s again marks the starting position (which the tail also visited) and # marks other positions the tail visited: + +
+..##..
+...##.
+.####.
+....#.
+s###..
+
+
+ +So, there are 13 positions the tail visited at least once. + +Simulate your complete hypothetical series of motions. How many positions does the tail of the rope visit at least once? + + +## --- Part Two --- +A rope snaps! Suddenly, the river is getting a lot closer than you remember. The bridge is still there, but some of the ropes that broke are now whipping toward you as you fall through the air! + +The ropes are moving too quickly to grab; you only have a few seconds to choose how to arch your body to avoid being hit. Fortunately, your simulation can be extended to support longer ropes. + +Rather than two knots, you now must simulate a rope consisting of ten knots. One knot is still the head of the rope and moves according to the series of motions. Each knot further down the rope follows the knot in front of it using the same rules as before. + +Using the same series of motions as the above example, but with the knots marked H, 1, 2, ..., 9, the motions now occur as follows: + +
+== Initial State ==
+
+......
+......
+......
+......
+H.....  (H covers 1, 2, 3, 4, 5, 6, 7, 8, 9, s)
+
+== R 4 ==
+
+......
+......
+......
+......
+1H....  (1 covers 2, 3, 4, 5, 6, 7, 8, 9, s)
+
+......
+......
+......
+......
+21H...  (2 covers 3, 4, 5, 6, 7, 8, 9, s)
+
+......
+......
+......
+......
+321H..  (3 covers 4, 5, 6, 7, 8, 9, s)
+
+......
+......
+......
+......
+4321H.  (4 covers 5, 6, 7, 8, 9, s)
+
+== U 4 ==
+
+......
+......
+......
+....H.
+4321..  (4 covers 5, 6, 7, 8, 9, s)
+
+......
+......
+....H.
+.4321.
+5.....  (5 covers 6, 7, 8, 9, s)
+
+......
+....H.
+....1.
+.432..
+5.....  (5 covers 6, 7, 8, 9, s)
+
+....H.
+....1.
+..432.
+.5....
+6.....  (6 covers 7, 8, 9, s)
+
+== L 3 ==
+
+...H..
+....1.
+..432.
+.5....
+6.....  (6 covers 7, 8, 9, s)
+
+..H1..
+...2..
+..43..
+.5....
+6.....  (6 covers 7, 8, 9, s)
+
+.H1...
+...2..
+..43..
+.5....
+6.....  (6 covers 7, 8, 9, s)
+
+== D 1 ==
+
+..1...
+.H.2..
+..43..
+.5....
+6.....  (6 covers 7, 8, 9, s)
+
+== R 4 ==
+
+..1...
+..H2..
+..43..
+.5....
+6.....  (6 covers 7, 8, 9, s)
+
+..1...
+...H..  (H covers 2)
+..43..
+.5....
+6.....  (6 covers 7, 8, 9, s)
+
+......
+...1H.  (1 covers 2)
+..43..
+.5....
+6.....  (6 covers 7, 8, 9, s)
+
+......
+...21H
+..43..
+.5....
+6.....  (6 covers 7, 8, 9, s)
+
+== D 1 ==
+
+......
+...21.
+..43.H
+.5....
+6.....  (6 covers 7, 8, 9, s)
+
+== L 5 ==
+
+......
+...21.
+..43H.
+.5....
+6.....  (6 covers 7, 8, 9, s)
+
+......
+...21.
+..4H..  (H covers 3)
+.5....
+6.....  (6 covers 7, 8, 9, s)
+
+......
+...2..
+..H1..  (H covers 4; 1 covers 3)
+.5....
+6.....  (6 covers 7, 8, 9, s)
+
+......
+...2..
+.H13..  (1 covers 4)
+.5....
+6.....  (6 covers 7, 8, 9, s)
+
+......
+......
+H123..  (2 covers 4)
+.5....
+6.....  (6 covers 7, 8, 9, s)
+
+== R 2 ==
+
+......
+......
+.H23..  (H covers 1; 2 covers 4)
+.5....
+6.....  (6 covers 7, 8, 9, s)
+
+......
+......
+.1H3..  (H covers 2, 4)
+.5....
+6.....  (6 covers 7, 8, 9, s)
+
+
+ +Now, you need to keep track of the positions the new tail, 9, visits. In this example, the tail never moves, and so it only visits 1 position. However, be careful: more types of motion are possible than before, so you might want to visually compare your simulated rope to the one above. + +Here's a larger example: + +
+R 5
+U 8
+L 8
+D 3
+R 17
+D 10
+L 25
+U 20
+
+
+ +These motions occur as follows (individual steps are not shown): + +
+== Initial State ==
+
+..........................
+..........................
+..........................
+..........................
+..........................
+..........................
+..........................
+..........................
+..........................
+..........................
+..........................
+..........................
+..........................
+..........................
+..........................
+...........H..............  (H covers 1, 2, 3, 4, 5, 6, 7, 8, 9, s)
+..........................
+..........................
+..........................
+..........................
+..........................
+
+== R 5 ==
+
+..........................
+..........................
+..........................
+..........................
+..........................
+..........................
+..........................
+..........................
+..........................
+..........................
+..........................
+..........................
+..........................
+..........................
+..........................
+...........54321H.........  (5 covers 6, 7, 8, 9, s)
+..........................
+..........................
+..........................
+..........................
+..........................
+
+== U 8 ==
+
+..........................
+..........................
+..........................
+..........................
+..........................
+..........................
+..........................
+................H.........
+................1.........
+................2.........
+................3.........
+...............54.........
+..............6...........
+.............7............
+............8.............
+...........9..............  (9 covers s)
+..........................
+..........................
+..........................
+..........................
+..........................
+
+== L 8 ==
+
+..........................
+..........................
+..........................
+..........................
+..........................
+..........................
+..........................
+........H1234.............
+............5.............
+............6.............
+............7.............
+............8.............
+............9.............
+..........................
+..........................
+...........s..............
+..........................
+..........................
+..........................
+..........................
+..........................
+
+== D 3 ==
+
+..........................
+..........................
+..........................
+..........................
+..........................
+..........................
+..........................
+..........................
+.........2345.............
+........1...6.............
+........H...7.............
+............8.............
+............9.............
+..........................
+..........................
+...........s..............
+..........................
+..........................
+..........................
+..........................
+..........................
+
+== R 17 ==
+
+..........................
+..........................
+..........................
+..........................
+..........................
+..........................
+..........................
+..........................
+..........................
+..........................
+................987654321H
+..........................
+..........................
+..........................
+..........................
+...........s..............
+..........................
+..........................
+..........................
+..........................
+..........................
+
+== D 10 ==
+
+..........................
+..........................
+..........................
+..........................
+..........................
+..........................
+..........................
+..........................
+..........................
+..........................
+..........................
+..........................
+..........................
+..........................
+..........................
+...........s.........98765
+.........................4
+.........................3
+.........................2
+.........................1
+.........................H
+
+== L 25 ==
+
+..........................
+..........................
+..........................
+..........................
+..........................
+..........................
+..........................
+..........................
+..........................
+..........................
+..........................
+..........................
+..........................
+..........................
+..........................
+...........s..............
+..........................
+..........................
+..........................
+..........................
+H123456789................
+
+== U 20 ==
+
+H.........................
+1.........................
+2.........................
+3.........................
+4.........................
+5.........................
+6.........................
+7.........................
+8.........................
+9.........................
+..........................
+..........................
+..........................
+..........................
+..........................
+...........s..............
+..........................
+..........................
+..........................
+..........................
+..........................
+
+
+
+ +Now, the tail (9) visits 36 positions (including s) at least once: + +
+..........................
+..........................
+..........................
+..........................
+..........................
+..........................
+..........................
+..........................
+..........................
+#.........................
+#.............###.........
+#............#...#........
+.#..........#.....#.......
+..#..........#.....#......
+...#........#.......#.....
+....#......s.........#....
+.....#..............#.....
+......#............#......
+.......#..........#.......
+........#........#........
+.........########.........
+
+
+ +Simulate your complete series of motions on a larger rope with ten knots. How many positions does the tail of the rope visit at least once? + + diff --git a/2022/Day09/input.in b/2022/Day09/input.in index 41d5b2cd2..514b93e5d 100644 Binary files a/2022/Day09/input.in and b/2022/Day09/input.in differ diff --git a/2022/Day10/README.md b/2022/Day10/README.md index a779db6f6..d9df61cdb 100644 --- a/2022/Day10/README.md +++ b/2022/Day10/README.md @@ -1,6 +1,341 @@ +original source: [https://adventofcode.com/2022/day/10](https://adventofcode.com/2022/day/10) ## --- Day 10: Cathode-Ray Tube --- You avoid the ropes, plunge into the river, and swim to shore. The Elves yell something about meeting back up with them upriver, but the river is too loud to tell exactly what they're saying. They finish crossing the bridge and disappear from view. -Read the [full puzzle](https://adventofcode.com/2022/day/10). \ No newline at end of file +Situations like this must be why the Elves prioritized getting the communication system on your handheld device working. You pull it out of your pack, but the amount of water slowly draining from a big crack in its screen tells you it probably won't be of much immediate use. + +Unless, that is, you can design a replacement for the device's video system! It seems to be some kind of [cathode-ray tube](https://en.wikipedia.org/wiki/Cathode-ray_tube) screen and simple CPU that are both driven by a precise clock circuit. The clock circuit ticks at a constant rate; each tick is called a cycle. + +Start by figuring out the signal being sent by the CPU. The CPU has a single register, X, which starts with the value 1. It supports only two instructions: + + + - addx V takes two cycles to complete. After two cycles, the X register is increased by the value V. (V can be negative.) + - noop takes one cycle to complete. It has no other effect. + +The CPU uses these instructions in a program (your puzzle input) to, somehow, tell the screen what to draw. + +Consider the following small program: + +
+noop
+addx 3
+addx -5
+
+
+ +Execution of this program proceeds as follows: + + + - At the start of the first cycle, the noop instruction begins execution. During the first cycle, X is 1. After the first cycle, the noop instruction finishes execution, doing nothing. + - At the start of the second cycle, the addx 3 instruction begins execution. During the second cycle, X is still 1. + - During the third cycle, X is still 1. After the third cycle, the addx 3 instruction finishes execution, setting X to 4. + - At the start of the fourth cycle, the addx -5 instruction begins execution. During the fourth cycle, X is still 4. + - During the fifth cycle, X is still 4. After the fifth cycle, the addx -5 instruction finishes execution, setting X to -1. + +Maybe you can learn something by looking at the value of the X register throughout execution. For now, consider the signal strength (the cycle number multiplied by the value of the X register) during the 20th cycle and every 40 cycles after that (that is, during the 20th, 60th, 100th, 140th, 180th, and 220th cycles). + +For example, consider this larger program: + +
+addx 15
+addx -11
+addx 6
+addx -3
+addx 5
+addx -1
+addx -8
+addx 13
+addx 4
+noop
+addx -1
+addx 5
+addx -1
+addx 5
+addx -1
+addx 5
+addx -1
+addx 5
+addx -1
+addx -35
+addx 1
+addx 24
+addx -19
+addx 1
+addx 16
+addx -11
+noop
+noop
+addx 21
+addx -15
+noop
+noop
+addx -3
+addx 9
+addx 1
+addx -3
+addx 8
+addx 1
+addx 5
+noop
+noop
+noop
+noop
+noop
+addx -36
+noop
+addx 1
+addx 7
+noop
+noop
+noop
+addx 2
+addx 6
+noop
+noop
+noop
+noop
+noop
+addx 1
+noop
+noop
+addx 7
+addx 1
+noop
+addx -13
+addx 13
+addx 7
+noop
+addx 1
+addx -33
+noop
+noop
+noop
+addx 2
+noop
+noop
+noop
+addx 8
+noop
+addx -1
+addx 2
+addx 1
+noop
+addx 17
+addx -9
+addx 1
+addx 1
+addx -3
+addx 11
+noop
+noop
+addx 1
+noop
+addx 1
+noop
+noop
+addx -13
+addx -19
+addx 1
+addx 3
+addx 26
+addx -30
+addx 12
+addx -1
+addx 3
+addx 1
+noop
+noop
+noop
+addx -9
+addx 18
+addx 1
+addx 2
+noop
+noop
+addx 9
+noop
+noop
+noop
+addx -1
+addx 2
+addx -37
+addx 1
+addx 3
+noop
+addx 15
+addx -21
+addx 22
+addx -6
+addx 1
+noop
+addx 2
+addx 1
+noop
+addx -10
+noop
+noop
+addx 20
+addx 1
+addx 2
+addx 2
+addx -6
+addx -11
+noop
+noop
+noop
+
+
+ +The interesting signal strengths can be determined as follows: + + + - During the 20th cycle, register X has the value 21, so the signal strength is 20 * 21 = 420. (The 20th cycle occurs in the middle of the second addx -1, so the value of register X is the starting value, 1, plus all of the other addx values up to that point: 1 + 15 - 11 + 6 - 3 + 5 - 1 - 8 + 13 + 4 = 21.) + - During the 60th cycle, register X has the value 19, so the signal strength is 60 * 19 = 1140. + - During the 100th cycle, register X has the value 18, so the signal strength is 100 * 18 = 1800. + - During the 140th cycle, register X has the value 21, so the signal strength is 140 * 21 = 2940. + - During the 180th cycle, register X has the value 16, so the signal strength is 180 * 16 = 2880. + - During the 220th cycle, register X has the value 18, so the signal strength is 220 * 18 = 3960. + +The sum of these signal strengths is 13140. + +Find the signal strength during the 20th, 60th, 100th, 140th, 180th, and 220th cycles. What is the sum of these six signal strengths? + + +## --- Part Two --- +It seems like the X register controls the horizontal position of a [sprite](https://en.wikipedia.org/wiki/Sprite_(computer_graphics)). Specifically, the sprite is 3 pixels wide, and the X register sets the horizontal position of the middle of that sprite. (In this system, there is no such thing as "vertical position": if the sprite's horizontal position puts its pixels where the CRT is currently drawing, then those pixels will be drawn.) + +You count the pixels on the CRT: 40 wide and 6 high. This CRT screen draws the top row of pixels left-to-right, then the row below that, and so on. The left-most pixel in each row is in position 0, and the right-most pixel in each row is in position 39. + +Like the CPU, the CRT is tied closely to the clock circuit: the CRT draws a single pixel during each cycle. Representing each pixel of the screen as a #, here are the cycles during which the first and last pixel in each row are drawn: + +
+Cycle   1 -> ######################################## <- Cycle  40
+Cycle  41 -> ######################################## <- Cycle  80
+Cycle  81 -> ######################################## <- Cycle 120
+Cycle 121 -> ######################################## <- Cycle 160
+Cycle 161 -> ######################################## <- Cycle 200
+Cycle 201 -> ######################################## <- Cycle 240
+
+
+ +So, by [carefully](https://en.wikipedia.org/wiki/Racing_the_Beam) [timing](https://www.youtube.com/watch?v=sJFnWZH5FXc) the CPU instructions and the CRT drawing operations, you should be able to determine whether the sprite is visible the instant each pixel is drawn. If the sprite is positioned such that one of its three pixels is the pixel currently being drawn, the screen produces a lit pixel (#); otherwise, the screen leaves the pixel dark (.). + +The first few pixels from the larger example above are drawn as follows: + +
+Sprite position: ###.....................................
+
+Start cycle   1: begin executing addx 15
+During cycle  1: CRT draws pixel in position 0
+Current CRT row: #
+
+During cycle  2: CRT draws pixel in position 1
+Current CRT row: ##
+End of cycle  2: finish executing addx 15 (Register X is now 16)
+Sprite position: ...............###......................
+
+Start cycle   3: begin executing addx -11
+During cycle  3: CRT draws pixel in position 2
+Current CRT row: ##.
+
+During cycle  4: CRT draws pixel in position 3
+Current CRT row: ##..
+End of cycle  4: finish executing addx -11 (Register X is now 5)
+Sprite position: ....###.................................
+
+Start cycle   5: begin executing addx 6
+During cycle  5: CRT draws pixel in position 4
+Current CRT row: ##..#
+
+During cycle  6: CRT draws pixel in position 5
+Current CRT row: ##..##
+End of cycle  6: finish executing addx 6 (Register X is now 11)
+Sprite position: ..........###...........................
+
+Start cycle   7: begin executing addx -3
+During cycle  7: CRT draws pixel in position 6
+Current CRT row: ##..##.
+
+During cycle  8: CRT draws pixel in position 7
+Current CRT row: ##..##..
+End of cycle  8: finish executing addx -3 (Register X is now 8)
+Sprite position: .......###..............................
+
+Start cycle   9: begin executing addx 5
+During cycle  9: CRT draws pixel in position 8
+Current CRT row: ##..##..#
+
+During cycle 10: CRT draws pixel in position 9
+Current CRT row: ##..##..##
+End of cycle 10: finish executing addx 5 (Register X is now 13)
+Sprite position: ............###.........................
+
+Start cycle  11: begin executing addx -1
+During cycle 11: CRT draws pixel in position 10
+Current CRT row: ##..##..##.
+
+During cycle 12: CRT draws pixel in position 11
+Current CRT row: ##..##..##..
+End of cycle 12: finish executing addx -1 (Register X is now 12)
+Sprite position: ...........###..........................
+
+Start cycle  13: begin executing addx -8
+During cycle 13: CRT draws pixel in position 12
+Current CRT row: ##..##..##..#
+
+During cycle 14: CRT draws pixel in position 13
+Current CRT row: ##..##..##..##
+End of cycle 14: finish executing addx -8 (Register X is now 4)
+Sprite position: ...###..................................
+
+Start cycle  15: begin executing addx 13
+During cycle 15: CRT draws pixel in position 14
+Current CRT row: ##..##..##..##.
+
+During cycle 16: CRT draws pixel in position 15
+Current CRT row: ##..##..##..##..
+End of cycle 16: finish executing addx 13 (Register X is now 17)
+Sprite position: ................###.....................
+
+Start cycle  17: begin executing addx 4
+During cycle 17: CRT draws pixel in position 16
+Current CRT row: ##..##..##..##..#
+
+During cycle 18: CRT draws pixel in position 17
+Current CRT row: ##..##..##..##..##
+End of cycle 18: finish executing addx 4 (Register X is now 21)
+Sprite position: ....................###.................
+
+Start cycle  19: begin executing noop
+During cycle 19: CRT draws pixel in position 18
+Current CRT row: ##..##..##..##..##.
+End of cycle 19: finish executing noop
+
+Start cycle  20: begin executing addx -1
+During cycle 20: CRT draws pixel in position 19
+Current CRT row: ##..##..##..##..##..
+
+During cycle 21: CRT draws pixel in position 20
+Current CRT row: ##..##..##..##..##..#
+End of cycle 21: finish executing addx -1 (Register X is now 20)
+Sprite position: ...................###..................
+
+
+ +Allowing the program to run to completion causes the CRT to produce the following image: + +
+##..##..##..##..##..##..##..##..##..##..
+###...###...###...###...###...###...###.
+####....####....####....####....####....
+#####.....#####.....#####.....#####.....
+######......######......######......####
+#######.......#######.......#######.....
+
+
+ +Render the image given by your program. What eight capital letters appear on your CRT? + + diff --git a/2022/Day10/input.in b/2022/Day10/input.in index a8df5acdf..b531dcaf2 100644 Binary files a/2022/Day10/input.in and b/2022/Day10/input.in differ diff --git a/2022/Day11/README.md b/2022/Day11/README.md index 4af3f099e..2ad6a2f54 100644 --- a/2022/Day11/README.md +++ b/2022/Day11/README.md @@ -1,6 +1,328 @@ +original source: [https://adventofcode.com/2022/day/11](https://adventofcode.com/2022/day/11) ## --- Day 11: Monkey in the Middle --- As you finally start making your way upriver, you realize your pack is much lighter than you remember. Just then, one of the items from your pack goes flying overhead. Monkeys are playing [Keep Away](https://en.wikipedia.org/wiki/Keep_away) with your missing things! To get your stuff back, you need to be able to predict where the monkeys will throw your items. After some careful observation, you realize the monkeys operate based on how worried you are about each item. -Read the [full puzzle](https://adventofcode.com/2022/day/11). \ No newline at end of file +You take some notes (your puzzle input) on the items each monkey currently has, how worried you are about those items, and how the monkey makes decisions based on your worry level. For example: + +
+Monkey 0:
+  Starting items: 79, 98
+  Operation: new = old * 19
+  Test: divisible by 23
+    If true: throw to monkey 2
+    If false: throw to monkey 3
+
+Monkey 1:
+  Starting items: 54, 65, 75, 74
+  Operation: new = old + 6
+  Test: divisible by 19
+    If true: throw to monkey 2
+    If false: throw to monkey 0
+
+Monkey 2:
+  Starting items: 79, 60, 97
+  Operation: new = old * old
+  Test: divisible by 13
+    If true: throw to monkey 1
+    If false: throw to monkey 3
+
+Monkey 3:
+  Starting items: 74
+  Operation: new = old + 3
+  Test: divisible by 17
+    If true: throw to monkey 0
+    If false: throw to monkey 1
+
+
+ +Each monkey has several attributes: + + + - Starting items lists your worry level for each item the monkey is currently holding in the order they will be inspected. + - Operation shows how your worry level changes as that monkey inspects an item. (An operation like new = old * 5 means that your worry level after the monkey inspected the item is five times whatever your worry level was before inspection.) + - Test shows how the monkey uses your worry level to decide where to throw an item next. + + - If true shows what happens with an item if the Test was true. + - If false shows what happens with an item if the Test was false. + + + +After each monkey inspects an item but before it tests your worry level, your relief that the monkey's inspection didn't damage the item causes your worry level to be divided by three and rounded down to the nearest integer. + +The monkeys take turns inspecting and throwing items. On a single monkey's turn, it inspects and throws all of the items it is holding one at a time and in the order listed. Monkey 0 goes first, then monkey 1, and so on until each monkey has had one turn. The process of each monkey taking a single turn is called a round. + +When a monkey throws an item to another monkey, the item goes on the end of the recipient monkey's list. A monkey that starts a round with no items could end up inspecting and throwing many items by the time its turn comes around. If a monkey is holding no items at the start of its turn, its turn ends. + +In the above example, the first round proceeds as follows: + +
+Monkey 0:
+  Monkey inspects an item with a worry level of 79.
+    Worry level is multiplied by 19 to 1501.
+    Monkey gets bored with item. Worry level is divided by 3 to 500.
+    Current worry level is not divisible by 23.
+    Item with worry level 500 is thrown to monkey 3.
+  Monkey inspects an item with a worry level of 98.
+    Worry level is multiplied by 19 to 1862.
+    Monkey gets bored with item. Worry level is divided by 3 to 620.
+    Current worry level is not divisible by 23.
+    Item with worry level 620 is thrown to monkey 3.
+Monkey 1:
+  Monkey inspects an item with a worry level of 54.
+    Worry level increases by 6 to 60.
+    Monkey gets bored with item. Worry level is divided by 3 to 20.
+    Current worry level is not divisible by 19.
+    Item with worry level 20 is thrown to monkey 0.
+  Monkey inspects an item with a worry level of 65.
+    Worry level increases by 6 to 71.
+    Monkey gets bored with item. Worry level is divided by 3 to 23.
+    Current worry level is not divisible by 19.
+    Item with worry level 23 is thrown to monkey 0.
+  Monkey inspects an item with a worry level of 75.
+    Worry level increases by 6 to 81.
+    Monkey gets bored with item. Worry level is divided by 3 to 27.
+    Current worry level is not divisible by 19.
+    Item with worry level 27 is thrown to monkey 0.
+  Monkey inspects an item with a worry level of 74.
+    Worry level increases by 6 to 80.
+    Monkey gets bored with item. Worry level is divided by 3 to 26.
+    Current worry level is not divisible by 19.
+    Item with worry level 26 is thrown to monkey 0.
+Monkey 2:
+  Monkey inspects an item with a worry level of 79.
+    Worry level is multiplied by itself to 6241.
+    Monkey gets bored with item. Worry level is divided by 3 to 2080.
+    Current worry level is divisible by 13.
+    Item with worry level 2080 is thrown to monkey 1.
+  Monkey inspects an item with a worry level of 60.
+    Worry level is multiplied by itself to 3600.
+    Monkey gets bored with item. Worry level is divided by 3 to 1200.
+    Current worry level is not divisible by 13.
+    Item with worry level 1200 is thrown to monkey 3.
+  Monkey inspects an item with a worry level of 97.
+    Worry level is multiplied by itself to 9409.
+    Monkey gets bored with item. Worry level is divided by 3 to 3136.
+    Current worry level is not divisible by 13.
+    Item with worry level 3136 is thrown to monkey 3.
+Monkey 3:
+  Monkey inspects an item with a worry level of 74.
+    Worry level increases by 3 to 77.
+    Monkey gets bored with item. Worry level is divided by 3 to 25.
+    Current worry level is not divisible by 17.
+    Item with worry level 25 is thrown to monkey 1.
+  Monkey inspects an item with a worry level of 500.
+    Worry level increases by 3 to 503.
+    Monkey gets bored with item. Worry level is divided by 3 to 167.
+    Current worry level is not divisible by 17.
+    Item with worry level 167 is thrown to monkey 1.
+  Monkey inspects an item with a worry level of 620.
+    Worry level increases by 3 to 623.
+    Monkey gets bored with item. Worry level is divided by 3 to 207.
+    Current worry level is not divisible by 17.
+    Item with worry level 207 is thrown to monkey 1.
+  Monkey inspects an item with a worry level of 1200.
+    Worry level increases by 3 to 1203.
+    Monkey gets bored with item. Worry level is divided by 3 to 401.
+    Current worry level is not divisible by 17.
+    Item with worry level 401 is thrown to monkey 1.
+  Monkey inspects an item with a worry level of 3136.
+    Worry level increases by 3 to 3139.
+    Monkey gets bored with item. Worry level is divided by 3 to 1046.
+    Current worry level is not divisible by 17.
+    Item with worry level 1046 is thrown to monkey 1.
+
+
+ +After round 1, the monkeys are holding items with these worry levels: + +
+Monkey 0: 20, 23, 27, 26
+Monkey 1: 2080, 25, 167, 207, 401, 1046
+Monkey 2: 
+Monkey 3: 
+
+
+ +Monkeys 2 and 3 aren't holding any items at the end of the round; they both inspected items during the round and threw them all before the round ended. + +This process continues for a few more rounds: + +
+After round 2, the monkeys are holding items with these worry levels:
+Monkey 0: 695, 10, 71, 135, 350
+Monkey 1: 43, 49, 58, 55, 362
+Monkey 2: 
+Monkey 3: 
+
+After round 3, the monkeys are holding items with these worry levels:
+Monkey 0: 16, 18, 21, 20, 122
+Monkey 1: 1468, 22, 150, 286, 739
+Monkey 2: 
+Monkey 3: 
+
+After round 4, the monkeys are holding items with these worry levels:
+Monkey 0: 491, 9, 52, 97, 248, 34
+Monkey 1: 39, 45, 43, 258
+Monkey 2: 
+Monkey 3: 
+
+After round 5, the monkeys are holding items with these worry levels:
+Monkey 0: 15, 17, 16, 88, 1037
+Monkey 1: 20, 110, 205, 524, 72
+Monkey 2: 
+Monkey 3: 
+
+After round 6, the monkeys are holding items with these worry levels:
+Monkey 0: 8, 70, 176, 26, 34
+Monkey 1: 481, 32, 36, 186, 2190
+Monkey 2: 
+Monkey 3: 
+
+After round 7, the monkeys are holding items with these worry levels:
+Monkey 0: 162, 12, 14, 64, 732, 17
+Monkey 1: 148, 372, 55, 72
+Monkey 2: 
+Monkey 3: 
+
+After round 8, the monkeys are holding items with these worry levels:
+Monkey 0: 51, 126, 20, 26, 136
+Monkey 1: 343, 26, 30, 1546, 36
+Monkey 2: 
+Monkey 3: 
+
+After round 9, the monkeys are holding items with these worry levels:
+Monkey 0: 116, 10, 12, 517, 14
+Monkey 1: 108, 267, 43, 55, 288
+Monkey 2: 
+Monkey 3: 
+
+After round 10, the monkeys are holding items with these worry levels:
+Monkey 0: 91, 16, 20, 98
+Monkey 1: 481, 245, 22, 26, 1092, 30
+Monkey 2: 
+Monkey 3: 
+
+...
+
+After round 15, the monkeys are holding items with these worry levels:
+Monkey 0: 83, 44, 8, 184, 9, 20, 26, 102
+Monkey 1: 110, 36
+Monkey 2: 
+Monkey 3: 
+
+...
+
+After round 20, the monkeys are holding items with these worry levels:
+Monkey 0: 10, 12, 14, 26, 34
+Monkey 1: 245, 93, 53, 199, 115
+Monkey 2: 
+Monkey 3: 
+
+
+ +Chasing all of the monkeys at once is impossible; you're going to have to focus on the two most active monkeys if you want any hope of getting your stuff back. Count the total number of times each monkey inspects items over 20 rounds: + +
+Monkey 0 inspected items 101 times.
+Monkey 1 inspected items 95 times.
+Monkey 2 inspected items 7 times.
+Monkey 3 inspected items 105 times.
+
+
+ +In this example, the two most active monkeys inspected items 101 and 105 times. The level of monkey business in this situation can be found by multiplying these together: 10605. + +Figure out which monkeys to chase by counting how many items they inspect over 20 rounds. What is the level of monkey business after 20 rounds of stuff-slinging simian shenanigans? + + +## --- Part Two --- +You're worried you might not ever get your items back. So worried, in fact, that your relief that a monkey's inspection didn't damage an item no longer causes your worry level to be divided by three. + +Unfortunately, that relief was all that was keeping your worry levels from reaching ridiculous levels. You'll need to find another way to keep your worry levels manageable. + +At this rate, you might be putting up with these monkeys for a very long time - possibly 10000 rounds! + +With these new rules, you can still figure out the monkey business after 10000 rounds. Using the same example above: + +
+== After round 1 ==
+Monkey 0 inspected items 2 times.
+Monkey 1 inspected items 4 times.
+Monkey 2 inspected items 3 times.
+Monkey 3 inspected items 6 times.
+
+== After round 20 ==
+Monkey 0 inspected items 99 times.
+Monkey 1 inspected items 97 times.
+Monkey 2 inspected items 8 times.
+Monkey 3 inspected items 103 times.
+
+== After round 1000 ==
+Monkey 0 inspected items 5204 times.
+Monkey 1 inspected items 4792 times.
+Monkey 2 inspected items 199 times.
+Monkey 3 inspected items 5192 times.
+
+== After round 2000 ==
+Monkey 0 inspected items 10419 times.
+Monkey 1 inspected items 9577 times.
+Monkey 2 inspected items 392 times.
+Monkey 3 inspected items 10391 times.
+
+== After round 3000 ==
+Monkey 0 inspected items 15638 times.
+Monkey 1 inspected items 14358 times.
+Monkey 2 inspected items 587 times.
+Monkey 3 inspected items 15593 times.
+
+== After round 4000 ==
+Monkey 0 inspected items 20858 times.
+Monkey 1 inspected items 19138 times.
+Monkey 2 inspected items 780 times.
+Monkey 3 inspected items 20797 times.
+
+== After round 5000 ==
+Monkey 0 inspected items 26075 times.
+Monkey 1 inspected items 23921 times.
+Monkey 2 inspected items 974 times.
+Monkey 3 inspected items 26000 times.
+
+== After round 6000 ==
+Monkey 0 inspected items 31294 times.
+Monkey 1 inspected items 28702 times.
+Monkey 2 inspected items 1165 times.
+Monkey 3 inspected items 31204 times.
+
+== After round 7000 ==
+Monkey 0 inspected items 36508 times.
+Monkey 1 inspected items 33488 times.
+Monkey 2 inspected items 1360 times.
+Monkey 3 inspected items 36400 times.
+
+== After round 8000 ==
+Monkey 0 inspected items 41728 times.
+Monkey 1 inspected items 38268 times.
+Monkey 2 inspected items 1553 times.
+Monkey 3 inspected items 41606 times.
+
+== After round 9000 ==
+Monkey 0 inspected items 46945 times.
+Monkey 1 inspected items 43051 times.
+Monkey 2 inspected items 1746 times.
+Monkey 3 inspected items 46807 times.
+
+== After round 10000 ==
+Monkey 0 inspected items 52166 times.
+Monkey 1 inspected items 47830 times.
+Monkey 2 inspected items 1938 times.
+Monkey 3 inspected items 52013 times.
+
+
+ +After 10000 rounds, the two most active monkeys inspected items 52166 and 52013 times. Multiplying these together, the level of monkey business in this situation is now 2713310158. + +Worry levels are no longer divided by three after each item is inspected; you'll need to find another way to keep your worry levels manageable. Starting again from the initial state in your puzzle input, what is the level of monkey business after 10000 rounds? + + diff --git a/2022/Day11/input.in b/2022/Day11/input.in index 45757b6fe..79e7808ce 100644 Binary files a/2022/Day11/input.in and b/2022/Day11/input.in differ diff --git a/2022/Day12/README.md b/2022/Day12/README.md index e9b806206..0ef5d6034 100644 --- a/2022/Day12/README.md +++ b/2022/Day12/README.md @@ -1,6 +1,71 @@ +original source: [https://adventofcode.com/2022/day/12](https://adventofcode.com/2022/day/12) ## --- Day 12: Hill Climbing Algorithm --- You try contacting the Elves using your handheld device, but the river you're following must be too low to get a decent signal. You ask the device for a heightmap of the surrounding area (your puzzle input). The heightmap shows the local area from above broken into a grid; the elevation of each square of the grid is given by a single lowercase letter, where a is the lowest elevation, b is the next-lowest, and so on up to the highest elevation, z. -Read the [full puzzle](https://adventofcode.com/2022/day/12). \ No newline at end of file +Also included on the heightmap are marks for your current position (S) and the location that should get the best signal (E). Your current position (S) has elevation a, and the location that should get the best signal (E) has elevation z. + +You'd like to reach E, but to save energy, you should do it in as few steps as possible. During each step, you can move exactly one square up, down, left, or right. To avoid needing to get out your climbing gear, the elevation of the destination square can be at most one higher than the elevation of your current square; that is, if your current elevation is m, you could step to elevation n, but not to elevation o. (This also means that the elevation of the destination square can be much lower than the elevation of your current square.) + +For example: + +
+Sabqponm
+abcryxxl
+accszExk
+acctuvwj
+abdefghi
+
+
+ +Here, you start in the top-left corner; your goal is near the middle. You could start by moving down or right, but eventually you'll need to head toward the e at the bottom. From there, you can spiral around to the goal: + +
+v..v<<<<
+>v.vv<<^
+.>vv>E^^
+..v>>>^^
+..>>>>>^
+
+
+ +In the above diagram, the symbols indicate whether the path exits each square moving up (^), down (v), left (<), or right (>). The location that should get the best signal is still E, and . marks unvisited squares. + +This path reaches the goal in 31 steps, the fewest possible. + +What is the fewest steps required to move from your current position to the location that should get the best signal? + + +## --- Part Two --- +As you walk up the hill, you suspect that the Elves will want to turn this into a hiking trail. The beginning isn't very scenic, though; perhaps you can find a better starting point. + +To maximize exercise while hiking, the trail should start as low as possible: elevation a. The goal is still the square marked E. However, the trail should still be direct, taking the fewest steps to reach its goal. So, you'll need to find the shortest path from any square at elevation a to the square marked E. + +Again consider the example from above: + +
+Sabqponm
+abcryxxl
+accszExk
+acctuvwj
+abdefghi
+
+
+ +Now, there are six choices for starting position (five marked a, plus the square marked S that counts as being at elevation a). If you start at the bottom-left square, you can reach the goal most quickly: + +
+...v<<<<
+...vv<<^
+...v>E^^
+.>v>>>^^
+>^>>>>>^
+
+
+ +This path reaches the goal in only 29 steps, the fewest possible. + +What is the fewest steps required to move starting from any square with elevation a to the location that should get the best signal? + + diff --git a/2022/Day12/input.in b/2022/Day12/input.in index 3d0235a30..45dff51cf 100644 Binary files a/2022/Day12/input.in and b/2022/Day12/input.in differ diff --git a/2022/Day13/README.md b/2022/Day13/README.md index 9f7528ec9..0678f29d0 100644 --- a/2022/Day13/README.md +++ b/2022/Day13/README.md @@ -1,6 +1,163 @@ +original source: [https://adventofcode.com/2022/day/13](https://adventofcode.com/2022/day/13) ## --- Day 13: Distress Signal --- You climb the hill and again try contacting the Elves. However, you instead receive a signal you weren't expecting: a distress signal. Your handheld device must still not be working properly; the packets from the distress signal got decoded out of order. You'll need to re-order the list of received packets (your puzzle input) to decode the message. -Read the [full puzzle](https://adventofcode.com/2022/day/13). \ No newline at end of file +Your list consists of pairs of packets; pairs are separated by a blank line. You need to identify how many pairs of packets are in the right order. + +For example: + +
+[1,1,3,1,1]
+[1,1,5,1,1]
+
+[[1],[2,3,4]]
+[[1],4]
+
+[9]
+[[8,7,6]]
+
+[[4,4],4,4]
+[[4,4],4,4,4]
+
+[7,7,7,7]
+[7,7,7]
+
+[]
+[3]
+
+[[[]]]
+[[]]
+
+[1,[2,[3,[4,[5,6,7]]]],8,9]
+[1,[2,[3,[4,[5,6,0]]]],8,9]
+
+
+ +Packet data consists of lists and integers. Each list starts with [, ends with ], and contains zero or more comma-separated values (either integers or other lists). Each packet is always a list and appears on its own line. + +When comparing two values, the first value is called left and the second value is called right. Then: + + + - If both values are integers, the lower integer should come first. If the left integer is lower than the right integer, the inputs are in the right order. If the left integer is higher than the right integer, the inputs are not in the right order. Otherwise, the inputs are the same integer; continue checking the next part of the input. + - If both values are lists, compare the first value of each list, then the second value, and so on. If the left list runs out of items first, the inputs are in the right order. If the right list runs out of items first, the inputs are not in the right order. If the lists are the same length and no comparison makes a decision about the order, continue checking the next part of the input. + - If exactly one value is an integer, convert the integer to a list which contains that integer as its only value, then retry the comparison. For example, if comparing [0,0,0] and 2, convert the right value to [2] (a list containing 2); the result is then found by instead comparing [0,0,0] and [2]. + +Using these rules, you can determine which of the pairs in the example are in the right order: + +
+== Pair 1 ==
+- Compare [1,1,3,1,1] vs [1,1,5,1,1]
+  - Compare 1 vs 1
+  - Compare 1 vs 1
+  - Compare 3 vs 5
+    - Left side is smaller, so inputs are in the right order
+
+== Pair 2 ==
+- Compare [[1],[2,3,4]] vs [[1],4]
+  - Compare [1] vs [1]
+    - Compare 1 vs 1
+  - Compare [2,3,4] vs 4
+    - Mixed types; convert right to [4] and retry comparison
+    - Compare [2,3,4] vs [4]
+      - Compare 2 vs 4
+        - Left side is smaller, so inputs are in the right order
+
+== Pair 3 ==
+- Compare [9] vs [[8,7,6]]
+  - Compare 9 vs [8,7,6]
+    - Mixed types; convert left to [9] and retry comparison
+    - Compare [9] vs [8,7,6]
+      - Compare 9 vs 8
+        - Right side is smaller, so inputs are not in the right order
+
+== Pair 4 ==
+- Compare [[4,4],4,4] vs [[4,4],4,4,4]
+  - Compare [4,4] vs [4,4]
+    - Compare 4 vs 4
+    - Compare 4 vs 4
+  - Compare 4 vs 4
+  - Compare 4 vs 4
+  - Left side ran out of items, so inputs are in the right order
+
+== Pair 5 ==
+- Compare [7,7,7,7] vs [7,7,7]
+  - Compare 7 vs 7
+  - Compare 7 vs 7
+  - Compare 7 vs 7
+  - Right side ran out of items, so inputs are not in the right order
+
+== Pair 6 ==
+- Compare [] vs [3]
+  - Left side ran out of items, so inputs are in the right order
+
+== Pair 7 ==
+- Compare [[[]]] vs [[]]
+  - Compare [[]] vs []
+    - Right side ran out of items, so inputs are not in the right order
+
+== Pair 8 ==
+- Compare [1,[2,[3,[4,[5,6,7]]]],8,9] vs [1,[2,[3,[4,[5,6,0]]]],8,9]
+  - Compare 1 vs 1
+  - Compare [2,[3,[4,[5,6,7]]]] vs [2,[3,[4,[5,6,0]]]]
+    - Compare 2 vs 2
+    - Compare [3,[4,[5,6,7]]] vs [3,[4,[5,6,0]]]
+      - Compare 3 vs 3
+      - Compare [4,[5,6,7]] vs [4,[5,6,0]]
+        - Compare 4 vs 4
+        - Compare [5,6,7] vs [5,6,0]
+          - Compare 5 vs 5
+          - Compare 6 vs 6
+          - Compare 7 vs 0
+            - Right side is smaller, so inputs are not in the right order
+
+
+ +What are the indices of the pairs that are already in the right order? (The first pair has index 1, the second pair has index 2, and so on.) In the above example, the pairs in the right order are 1, 2, 4, and 6; the sum of these indices is 13. + +Determine which pairs of packets are already in the right order. What is the sum of the indices of those pairs? + + +## --- Part Two --- +Now, you just need to put all of the packets in the right order. Disregard the blank lines in your list of received packets. + +The distress signal protocol also requires that you include two additional divider packets: + +
+[[2]]
+[[6]]
+
+
+ +Using the same rules as before, organize all packets - the ones in your list of received packets as well as the two divider packets - into the correct order. + +For the example above, the result of putting the packets in the correct order is: + +
+[]
+[[]]
+[[[]]]
+[1,1,3,1,1]
+[1,1,5,1,1]
+[[1],[2,3,4]]
+[1,[2,[3,[4,[5,6,0]]]],8,9]
+[1,[2,[3,[4,[5,6,7]]]],8,9]
+[[1],4]
+[[2]]
+[3]
+[[4,4],4,4]
+[[4,4],4,4,4]
+[[6]]
+[7,7,7]
+[7,7,7,7]
+[[8,7,6]]
+[9]
+
+
+ +Afterward, locate the divider packets. To find the decoder key for this distress signal, you need to determine the indices of the two divider packets and multiply them together. (The first packet is at index 1, the second packet is at index 2, and so on.) In this example, the divider packets are 10th and 14th, and so the decoder key is 140. + +Organize all of the packets into the correct order. What is the decoder key for the distress signal? + + diff --git a/2022/Day13/input.in b/2022/Day13/input.in index 6b9afc4f3..944ded3c2 100644 Binary files a/2022/Day13/input.in and b/2022/Day13/input.in differ diff --git a/2022/Day14/README.md b/2022/Day14/README.md index 556d598a3..8e8b73d3a 100644 --- a/2022/Day14/README.md +++ b/2022/Day14/README.md @@ -1,6 +1,192 @@ +original source: [https://adventofcode.com/2022/day/14](https://adventofcode.com/2022/day/14) ## --- Day 14: Regolith Reservoir --- The distress signal leads you to a giant waterfall! Actually, hang on - the signal seems like it's coming from the waterfall itself, and that doesn't make any sense. However, you do notice a little path that leads behind the waterfall. Correction: the distress signal leads you behind a giant waterfall! There seems to be a large cave system here, and the signal definitely leads further inside. -Read the [full puzzle](https://adventofcode.com/2022/day/14). \ No newline at end of file +As you begin to make your way deeper underground, you feel the ground rumble for a moment. Sand begins pouring into the cave! If you don't quickly figure out where the sand is going, you could quickly become trapped! + +Fortunately, your [familiarity](/2018/day/17) with analyzing the path of falling material will come in handy here. You scan a two-dimensional vertical slice of the cave above you (your puzzle input) and discover that it is mostly air with structures made of rock. + +Your scan traces the path of each solid rock structure and reports the x,y coordinates that form the shape of the path, where x represents distance to the right and y represents distance down. Each path appears as a single line of text in your scan. After the first point of each path, each point indicates the end of a straight horizontal or vertical line to be drawn from the previous point. For example: + +
+498,4 -> 498,6 -> 496,6
+503,4 -> 502,4 -> 502,9 -> 494,9
+
+
+ +This scan means that there are two paths of rock; the first path consists of two straight lines, and the second path consists of three straight lines. (Specifically, the first path consists of a line of rock from 498,4 through 498,6 and another line of rock from 498,6 through 496,6.) + +The sand is pouring into the cave from point 500,0. + +Drawing rock as #, air as ., and the source of the sand as +, this becomes: + +
+
+  4     5  5
+  9     0  0
+  4     0  3
+0 ......+...
+1 ..........
+2 ..........
+3 ..........
+4 ....#...##
+5 ....#...#.
+6 ..###...#.
+7 ........#.
+8 ........#.
+9 #########.
+
+
+ +Sand is produced one unit at a time, and the next unit of sand is not produced until the previous unit of sand comes to rest. A unit of sand is large enough to fill one tile of air in your scan. + +A unit of sand always falls down one step if possible. If the tile immediately below is blocked (by rock or sand), the unit of sand attempts to instead move diagonally one step down and to the left. If that tile is blocked, the unit of sand attempts to instead move diagonally one step down and to the right. Sand keeps moving as long as it is able to do so, at each step trying to move down, then down-left, then down-right. If all three possible destinations are blocked, the unit of sand comes to rest and no longer moves, at which point the next unit of sand is created back at the source. + +So, drawing sand that has come to rest as o, the first unit of sand simply falls straight down and then stops: + +
+......+...
+..........
+..........
+..........
+....#...##
+....#...#.
+..###...#.
+........#.
+......o.#.
+#########.
+
+
+ +The second unit of sand then falls straight down, lands on the first one, and then comes to rest to its left: + +
+......+...
+..........
+..........
+..........
+....#...##
+....#...#.
+..###...#.
+........#.
+.....oo.#.
+#########.
+
+
+ +After a total of five units of sand have come to rest, they form this pattern: + +
+......+...
+..........
+..........
+..........
+....#...##
+....#...#.
+..###...#.
+......o.#.
+....oooo#.
+#########.
+
+
+ +After a total of 22 units of sand: + +
+......+...
+..........
+......o...
+.....ooo..
+....#ooo##
+....#ooo#.
+..###ooo#.
+....oooo#.
+...ooooo#.
+#########.
+
+
+ +Finally, only two more units of sand can possibly come to rest: + +
+......+...
+..........
+......o...
+.....ooo..
+....#ooo##
+...o#ooo#.
+..###ooo#.
+....oooo#.
+.o.ooooo#.
+#########.
+
+
+ +Once all 24 units of sand shown above have come to rest, all further sand flows out the bottom, falling into the endless void. Just for fun, the path any new sand takes before falling forever is shown here with ~: + +
+.......+...
+.......~...
+......~o...
+.....~ooo..
+....~#ooo##
+...~o#ooo#.
+..~###ooo#.
+..~..oooo#.
+.~o.ooooo#.
+~#########.
+~..........
+~..........
+~..........
+
+
+ +Using your scan, simulate the falling sand. How many units of sand come to rest before sand starts flowing into the abyss below? + + +## --- Part Two --- +You realize you misread the scan. There isn't an endless void at the bottom of the scan - there's floor, and you're standing on it! + +You don't have time to scan the floor, so assume the floor is an infinite horizontal line with a y coordinate equal to two plus the highest y coordinate of any point in your scan. + +In the example above, the highest y coordinate of any point is 9, and so the floor is at y=11. (This is as if your scan contained one extra rock path like -infinity,11 -> infinity,11.) With the added floor, the example above now looks like this: + +
+        ...........+........
+        ....................
+        ....................
+        ....................
+        .........#...##.....
+        .........#...#......
+        .......###...#......
+        .............#......
+        .............#......
+        .....#########......
+        ....................
+<-- etc #################### etc -->
+
+
+ +To find somewhere safe to stand, you'll need to simulate falling sand until a unit of sand comes to rest at 500,0, blocking the source entirely and stopping the flow of sand into the cave. In the example above, the situation finally looks like this after 93 units of sand come to rest: + +
+............o............
+...........ooo...........
+..........ooooo..........
+.........ooooooo.........
+........oo#ooo##o........
+.......ooo#ooo#ooo.......
+......oo###ooo#oooo......
+.....oooo.oooo#ooooo.....
+....oooooooooo#oooooo....
+...ooo#########ooooooo...
+..ooooo.......ooooooooo..
+#########################
+
+
+ +Using your scan, simulate the falling sand until the source of the sand becomes blocked. How many units of sand come to rest? + + diff --git a/2022/Day14/input.in b/2022/Day14/input.in index 63006eac6..c693f8f04 100644 Binary files a/2022/Day14/input.in and b/2022/Day14/input.in differ diff --git a/2022/Day15/README.md b/2022/Day15/README.md index 02671e443..6462cb7d5 100644 --- a/2022/Day15/README.md +++ b/2022/Day15/README.md @@ -1,6 +1,124 @@ +original source: [https://adventofcode.com/2022/day/15](https://adventofcode.com/2022/day/15) ## --- Day 15: Beacon Exclusion Zone --- You feel the ground rumble again as the distress signal leads you to a large network of subterranean tunnels. You don't have time to search them all, but you don't need to: your pack contains a set of deployable sensors that you imagine were originally built to locate lost Elves. The sensors aren't very powerful, but that's okay; your handheld device indicates that you're close enough to the source of the distress signal to use them. You pull the emergency sensor system out of your pack, hit the big button on top, and the sensors zoom off down the tunnels. -Read the [full puzzle](https://adventofcode.com/2022/day/15). \ No newline at end of file +Once a sensor finds a spot it thinks will give it a good reading, it attaches itself to a hard surface and begins monitoring for the nearest signal source beacon. Sensors and beacons always exist at integer coordinates. Each sensor knows its own position and can determine the position of a beacon precisely; however, sensors can only lock on to the one beacon closest to the sensor as measured by the [Manhattan distance](https://en.wikipedia.org/wiki/Taxicab_geometry). (There is never a tie where two beacons are the same distance to a sensor.) + +It doesn't take long for the sensors to report back their positions and closest beacons (your puzzle input). For example: + +
+Sensor at x=2, y=18: closest beacon is at x=-2, y=15
+Sensor at x=9, y=16: closest beacon is at x=10, y=16
+Sensor at x=13, y=2: closest beacon is at x=15, y=3
+Sensor at x=12, y=14: closest beacon is at x=10, y=16
+Sensor at x=10, y=20: closest beacon is at x=10, y=16
+Sensor at x=14, y=17: closest beacon is at x=10, y=16
+Sensor at x=8, y=7: closest beacon is at x=2, y=10
+Sensor at x=2, y=0: closest beacon is at x=2, y=10
+Sensor at x=0, y=11: closest beacon is at x=2, y=10
+Sensor at x=20, y=14: closest beacon is at x=25, y=17
+Sensor at x=17, y=20: closest beacon is at x=21, y=22
+Sensor at x=16, y=7: closest beacon is at x=15, y=3
+Sensor at x=14, y=3: closest beacon is at x=15, y=3
+Sensor at x=20, y=1: closest beacon is at x=15, y=3
+
+
+ +So, consider the sensor at 2,18; the closest beacon to it is at -2,15. For the sensor at 9,16, the closest beacon to it is at 10,16. + +Drawing sensors as S and beacons as B, the above arrangement of sensors and beacons looks like this: + +
+               1    1    2    2
+     0    5    0    5    0    5
+ 0 ....S.......................
+ 1 ......................S.....
+ 2 ...............S............
+ 3 ................SB..........
+ 4 ............................
+ 5 ............................
+ 6 ............................
+ 7 ..........S.......S.........
+ 8 ............................
+ 9 ............................
+10 ....B.......................
+11 ..S.........................
+12 ............................
+13 ............................
+14 ..............S.......S.....
+15 B...........................
+16 ...........SB...............
+17 ................S..........B
+18 ....S.......................
+19 ............................
+20 ............S......S........
+21 ............................
+22 .......................B....
+
+
+ +This isn't necessarily a comprehensive map of all beacons in the area, though. Because each sensor only identifies its closest beacon, if a sensor detects a beacon, you know there are no other beacons that close or closer to that sensor. There could still be beacons that just happen to not be the closest beacon to any sensor. Consider the sensor at 8,7: + +
+               1    1    2    2
+     0    5    0    5    0    5
+-2 ..........#.................
+-1 .........###................
+ 0 ....S...#####...............
+ 1 .......#######........S.....
+ 2 ......#########S............
+ 3 .....###########SB..........
+ 4 ....#############...........
+ 5 ...###############..........
+ 6 ..#################.........
+ 7 .#########S#######S#........
+ 8 ..#################.........
+ 9 ...###############..........
+10 ....B############...........
+11 ..S..###########............
+12 ......#########.............
+13 .......#######..............
+14 ........#####.S.......S.....
+15 B........###................
+16 ..........#SB...............
+17 ................S..........B
+18 ....S.......................
+19 ............................
+20 ............S......S........
+21 ............................
+22 .......................B....
+
+
+ +This sensor's closest beacon is at 2,10, and so you know there are no beacons that close or closer (in any positions marked #). + +None of the detected beacons seem to be producing the distress signal, so you'll need to work out where the distress beacon is by working out where it isn't. For now, keep things simple by counting the positions where a beacon cannot possibly be along just a single row. + +So, suppose you have an arrangement of beacons and sensors like in the example above and, just in the row where y=10, you'd like to count the number of positions a beacon cannot possibly exist. The coverage from all sensors near that row looks like this: + +
+                 1    1    2    2
+       0    5    0    5    0    5
+ 9 ...#########################...
+10 ..####B######################..
+11 .###S#############.###########.
+
+
+ +In this example, in the row where y=10, there are 26 positions where a beacon cannot be present. + +Consult the report from the sensors you just deployed. In the row where y=2000000, how many positions cannot contain a beacon? + + +## --- Part Two --- +Your handheld device indicates that the distress signal is coming from a beacon nearby. The distress beacon is not detected by any sensor, but the distress beacon must have x and y coordinates each no lower than 0 and no larger than 4000000. + +To isolate the distress beacon's signal, you need to determine its tuning frequency, which can be found by multiplying its x coordinate by 4000000 and then adding its y coordinate. + +In the example above, the search space is smaller: instead, the x and y coordinates can each be at most 20. With this reduced search area, there is only a single position that could have a beacon: x=14, y=11. The tuning frequency for this distress beacon is 56000011. + +Find the only possible position for the distress beacon. What is its tuning frequency? + + diff --git a/2022/Day15/input.in b/2022/Day15/input.in index 3eb58d8d4..346776287 100644 Binary files a/2022/Day15/input.in and b/2022/Day15/input.in differ diff --git a/2022/Day16/README.md b/2022/Day16/README.md index d6a429ff4..8769c3d69 100644 --- a/2022/Day16/README.md +++ b/2022/Day16/README.md @@ -1,6 +1,237 @@ +original source: [https://adventofcode.com/2022/day/16](https://adventofcode.com/2022/day/16) ## --- Day 16: Proboscidea Volcanium --- The sensors have led you to the origin of the distress signal: yet another handheld device, just like the one the Elves gave you. However, you don't see any Elves around; instead, the device is surrounded by elephants! They must have gotten lost in these tunnels, and one of the elephants apparently figured out how to turn on the distress signal. The ground rumbles again, much stronger this time. What kind of cave is this, exactly? You scan the cave with your handheld device; it reports mostly igneous rock, some ash, pockets of pressurized gas, magma... this isn't just a cave, it's a volcano! -Read the [full puzzle](https://adventofcode.com/2022/day/16). \ No newline at end of file +You need to get the elephants out of here, quickly. Your device estimates that you have 30 minutes before the volcano erupts, so you don't have time to go back out the way you came in. + +You scan the cave for other options and discover a network of pipes and pressure-release valves. You aren't sure how such a system got into a volcano, but you don't have time to complain; your device produces a report (your puzzle input) of each valve's flow rate if it were opened (in pressure per minute) and the tunnels you could use to move between the valves. + +There's even a valve in the room you and the elephants are currently standing in labeled AA. You estimate it will take you one minute to open a single valve and one minute to follow any tunnel from one valve to another. What is the most pressure you could release? + +For example, suppose you had the following scan output: + +
+Valve AA has flow rate=0; tunnels lead to valves DD, II, BB
+Valve BB has flow rate=13; tunnels lead to valves CC, AA
+Valve CC has flow rate=2; tunnels lead to valves DD, BB
+Valve DD has flow rate=20; tunnels lead to valves CC, AA, EE
+Valve EE has flow rate=3; tunnels lead to valves FF, DD
+Valve FF has flow rate=0; tunnels lead to valves EE, GG
+Valve GG has flow rate=0; tunnels lead to valves FF, HH
+Valve HH has flow rate=22; tunnel leads to valve GG
+Valve II has flow rate=0; tunnels lead to valves AA, JJ
+Valve JJ has flow rate=21; tunnel leads to valve II
+
+
+ +All of the valves begin closed. You start at valve AA, but it must be damaged or jammed or something: its flow rate is 0, so there's no point in opening it. However, you could spend one minute moving to valve BB and another minute opening it; doing so would release pressure during the remaining 28 minutes at a flow rate of 13, a total eventual pressure release of 28 * 13 = 364. Then, you could spend your third minute moving to valve CC and your fourth minute opening it, providing an additional 26 minutes of eventual pressure release at a flow rate of 2, or 52 total pressure released by valve CC. + +Making your way through the tunnels like this, you could probably open many or all of the valves by the time 30 minutes have elapsed. However, you need to release as much pressure as possible, so you'll need to be methodical. Instead, consider this approach: + +
+== Minute 1 ==
+No valves are open.
+You move to valve DD.
+
+== Minute 2 ==
+No valves are open.
+You open valve DD.
+
+== Minute 3 ==
+Valve DD is open, releasing 20 pressure.
+You move to valve CC.
+
+== Minute 4 ==
+Valve DD is open, releasing 20 pressure.
+You move to valve BB.
+
+== Minute 5 ==
+Valve DD is open, releasing 20 pressure.
+You open valve BB.
+
+== Minute 6 ==
+Valves BB and DD are open, releasing 33 pressure.
+You move to valve AA.
+
+== Minute 7 ==
+Valves BB and DD are open, releasing 33 pressure.
+You move to valve II.
+
+== Minute 8 ==
+Valves BB and DD are open, releasing 33 pressure.
+You move to valve JJ.
+
+== Minute 9 ==
+Valves BB and DD are open, releasing 33 pressure.
+You open valve JJ.
+
+== Minute 10 ==
+Valves BB, DD, and JJ are open, releasing 54 pressure.
+You move to valve II.
+
+== Minute 11 ==
+Valves BB, DD, and JJ are open, releasing 54 pressure.
+You move to valve AA.
+
+== Minute 12 ==
+Valves BB, DD, and JJ are open, releasing 54 pressure.
+You move to valve DD.
+
+== Minute 13 ==
+Valves BB, DD, and JJ are open, releasing 54 pressure.
+You move to valve EE.
+
+== Minute 14 ==
+Valves BB, DD, and JJ are open, releasing 54 pressure.
+You move to valve FF.
+
+== Minute 15 ==
+Valves BB, DD, and JJ are open, releasing 54 pressure.
+You move to valve GG.
+
+== Minute 16 ==
+Valves BB, DD, and JJ are open, releasing 54 pressure.
+You move to valve HH.
+
+== Minute 17 ==
+Valves BB, DD, and JJ are open, releasing 54 pressure.
+You open valve HH.
+
+== Minute 18 ==
+Valves BB, DD, HH, and JJ are open, releasing 76 pressure.
+You move to valve GG.
+
+== Minute 19 ==
+Valves BB, DD, HH, and JJ are open, releasing 76 pressure.
+You move to valve FF.
+
+== Minute 20 ==
+Valves BB, DD, HH, and JJ are open, releasing 76 pressure.
+You move to valve EE.
+
+== Minute 21 ==
+Valves BB, DD, HH, and JJ are open, releasing 76 pressure.
+You open valve EE.
+
+== Minute 22 ==
+Valves BB, DD, EE, HH, and JJ are open, releasing 79 pressure.
+You move to valve DD.
+
+== Minute 23 ==
+Valves BB, DD, EE, HH, and JJ are open, releasing 79 pressure.
+You move to valve CC.
+
+== Minute 24 ==
+Valves BB, DD, EE, HH, and JJ are open, releasing 79 pressure.
+You open valve CC.
+
+== Minute 25 ==
+Valves BB, CC, DD, EE, HH, and JJ are open, releasing 81 pressure.
+
+== Minute 26 ==
+Valves BB, CC, DD, EE, HH, and JJ are open, releasing 81 pressure.
+
+== Minute 27 ==
+Valves BB, CC, DD, EE, HH, and JJ are open, releasing 81 pressure.
+
+== Minute 28 ==
+Valves BB, CC, DD, EE, HH, and JJ are open, releasing 81 pressure.
+
+== Minute 29 ==
+Valves BB, CC, DD, EE, HH, and JJ are open, releasing 81 pressure.
+
+== Minute 30 ==
+Valves BB, CC, DD, EE, HH, and JJ are open, releasing 81 pressure.
+
+
+ +This approach lets you release the most pressure possible in 30 minutes with this valve layout, 1651. + +Work out the steps to release the most pressure in 30 minutes. What is the most pressure you can release? + + +## --- Part Two --- +You're worried that even with an optimal approach, the pressure released won't be enough. What if you got one of the elephants to help you? + +It would take you 4 minutes to teach an elephant how to open the right valves in the right order, leaving you with only 26 minutes to actually execute your plan. Would having two of you working together be better, even if it means having less time? (Assume that you teach the elephant before opening any valves yourself, giving you both the same full 26 minutes.) + +In the example above, you could teach the elephant to help you as follows: + +
+== Minute 1 ==
+No valves are open.
+You move to valve II.
+The elephant moves to valve DD.
+
+== Minute 2 ==
+No valves are open.
+You move to valve JJ.
+The elephant opens valve DD.
+
+== Minute 3 ==
+Valve DD is open, releasing 20 pressure.
+You open valve JJ.
+The elephant moves to valve EE.
+
+== Minute 4 ==
+Valves DD and JJ are open, releasing 41 pressure.
+You move to valve II.
+The elephant moves to valve FF.
+
+== Minute 5 ==
+Valves DD and JJ are open, releasing 41 pressure.
+You move to valve AA.
+The elephant moves to valve GG.
+
+== Minute 6 ==
+Valves DD and JJ are open, releasing 41 pressure.
+You move to valve BB.
+The elephant moves to valve HH.
+
+== Minute 7 ==
+Valves DD and JJ are open, releasing 41 pressure.
+You open valve BB.
+The elephant opens valve HH.
+
+== Minute 8 ==
+Valves BB, DD, HH, and JJ are open, releasing 76 pressure.
+You move to valve CC.
+The elephant moves to valve GG.
+
+== Minute 9 ==
+Valves BB, DD, HH, and JJ are open, releasing 76 pressure.
+You open valve CC.
+The elephant moves to valve FF.
+
+== Minute 10 ==
+Valves BB, CC, DD, HH, and JJ are open, releasing 78 pressure.
+The elephant moves to valve EE.
+
+== Minute 11 ==
+Valves BB, CC, DD, HH, and JJ are open, releasing 78 pressure.
+The elephant opens valve EE.
+
+(At this point, all valves are open.)
+
+== Minute 12 ==
+Valves BB, CC, DD, EE, HH, and JJ are open, releasing 81 pressure.
+
+...
+
+== Minute 20 ==
+Valves BB, CC, DD, EE, HH, and JJ are open, releasing 81 pressure.
+
+...
+
+== Minute 26 ==
+Valves BB, CC, DD, EE, HH, and JJ are open, releasing 81 pressure.
+
+
+ +With the elephant helping, after 26 minutes, the best you could do would release a total of 1707 pressure. + +With you and an elephant working together for 26 minutes, what is the most pressure you could release? + + diff --git a/2022/Day16/input.in b/2022/Day16/input.in index f01ccf0c6..6bd72d9b6 100644 Binary files a/2022/Day16/input.in and b/2022/Day16/input.in differ diff --git a/2022/Day17/README.md b/2022/Day17/README.md index 01faa7ee4..29eb8aa0f 100644 --- a/2022/Day17/README.md +++ b/2022/Day17/README.md @@ -1,6 +1,359 @@ +original source: [https://adventofcode.com/2022/day/17](https://adventofcode.com/2022/day/17) ## --- Day 17: Pyroclastic Flow --- Your handheld device has located an alternative exit from the cave for you and the elephants. The ground is rumbling almost continuously now, but the strange valves bought you some time. It's definitely getting warmer in here, though. The tunnels eventually open into a very tall, narrow chamber. Large, oddly-shaped rocks are falling into the chamber from above, presumably due to all the rumbling. If you can't work out where the rocks will fall next, you might be crushed! -Read the [full puzzle](https://adventofcode.com/2022/day/17). \ No newline at end of file +The five types of rocks have the following peculiar shapes, where # is rock and . is empty space: + +
+####
+
+.#.
+###
+.#.
+
+..#
+..#
+###
+
+#
+#
+#
+#
+
+##
+##
+
+
+ +The rocks fall in the order shown above: first the - shape, then the + shape, and so on. Once the end of the list is reached, the same order repeats: the - shape falls first, sixth, 11th, 16th, etc. + +The rocks don't spin, but they do get pushed around by jets of hot gas coming out of the walls themselves. A quick scan reveals the effect the jets of hot gas will have on the rocks as they fall (your puzzle input). + +For example, suppose this was the jet pattern in your cave: + +
+>>><<><>><<<>><>>><<<>>><<<><<<>><>><<>>
+
+
+ +In jet patterns, < means a push to the left, while > means a push to the right. The pattern above means that the jets will push a falling rock right, then right, then right, then left, then left, then right, and so on. If the end of the list is reached, it repeats. + +The tall, vertical chamber is exactly seven units wide. Each rock appears so that its left edge is two units away from the left wall and its bottom edge is three units above the highest rock in the room (or the floor, if there isn't one). + +After a rock appears, it alternates between being pushed by a jet of hot gas one unit (in the direction indicated by the next symbol in the jet pattern) and then falling one unit down. If any movement would cause any part of the rock to move into the walls, floor, or a stopped rock, the movement instead does not occur. If a downward movement would have caused a falling rock to move into the floor or an already-fallen rock, the falling rock stops where it is (having landed on something) and a new rock immediately begins falling. + +Drawing falling rocks with @ and stopped rocks with #, the jet pattern in the example above manifests as follows: + +
+The first rock begins falling:
+|..@@@@.|
+|.......|
+|.......|
+|.......|
++-------+
+
+Jet of gas pushes rock right:
+|...@@@@|
+|.......|
+|.......|
+|.......|
++-------+
+
+Rock falls 1 unit:
+|...@@@@|
+|.......|
+|.......|
++-------+
+
+Jet of gas pushes rock right, but nothing happens:
+|...@@@@|
+|.......|
+|.......|
++-------+
+
+Rock falls 1 unit:
+|...@@@@|
+|.......|
++-------+
+
+Jet of gas pushes rock right, but nothing happens:
+|...@@@@|
+|.......|
++-------+
+
+Rock falls 1 unit:
+|...@@@@|
++-------+
+
+Jet of gas pushes rock left:
+|..@@@@.|
++-------+
+
+Rock falls 1 unit, causing it to come to rest:
+|..####.|
++-------+
+
+A new rock begins falling:
+|...@...|
+|..@@@..|
+|...@...|
+|.......|
+|.......|
+|.......|
+|..####.|
++-------+
+
+Jet of gas pushes rock left:
+|..@....|
+|.@@@...|
+|..@....|
+|.......|
+|.......|
+|.......|
+|..####.|
++-------+
+
+Rock falls 1 unit:
+|..@....|
+|.@@@...|
+|..@....|
+|.......|
+|.......|
+|..####.|
++-------+
+
+Jet of gas pushes rock right:
+|...@...|
+|..@@@..|
+|...@...|
+|.......|
+|.......|
+|..####.|
++-------+
+
+Rock falls 1 unit:
+|...@...|
+|..@@@..|
+|...@...|
+|.......|
+|..####.|
++-------+
+
+Jet of gas pushes rock left:
+|..@....|
+|.@@@...|
+|..@....|
+|.......|
+|..####.|
++-------+
+
+Rock falls 1 unit:
+|..@....|
+|.@@@...|
+|..@....|
+|..####.|
++-------+
+
+Jet of gas pushes rock right:
+|...@...|
+|..@@@..|
+|...@...|
+|..####.|
++-------+
+
+Rock falls 1 unit, causing it to come to rest:
+|...#...|
+|..###..|
+|...#...|
+|..####.|
++-------+
+
+A new rock begins falling:
+|....@..|
+|....@..|
+|..@@@..|
+|.......|
+|.......|
+|.......|
+|...#...|
+|..###..|
+|...#...|
+|..####.|
++-------+
+
+
+ +The moment each of the next few rocks begins falling, you would see this: + +
+|..@....|
+|..@....|
+|..@....|
+|..@....|
+|.......|
+|.......|
+|.......|
+|..#....|
+|..#....|
+|####...|
+|..###..|
+|...#...|
+|..####.|
++-------+
+
+|..@@...|
+|..@@...|
+|.......|
+|.......|
+|.......|
+|....#..|
+|..#.#..|
+|..#.#..|
+|#####..|
+|..###..|
+|...#...|
+|..####.|
++-------+
+
+|..@@@@.|
+|.......|
+|.......|
+|.......|
+|....##.|
+|....##.|
+|....#..|
+|..#.#..|
+|..#.#..|
+|#####..|
+|..###..|
+|...#...|
+|..####.|
++-------+
+
+|...@...|
+|..@@@..|
+|...@...|
+|.......|
+|.......|
+|.......|
+|.####..|
+|....##.|
+|....##.|
+|....#..|
+|..#.#..|
+|..#.#..|
+|#####..|
+|..###..|
+|...#...|
+|..####.|
++-------+
+
+|....@..|
+|....@..|
+|..@@@..|
+|.......|
+|.......|
+|.......|
+|..#....|
+|.###...|
+|..#....|
+|.####..|
+|....##.|
+|....##.|
+|....#..|
+|..#.#..|
+|..#.#..|
+|#####..|
+|..###..|
+|...#...|
+|..####.|
++-------+
+
+|..@....|
+|..@....|
+|..@....|
+|..@....|
+|.......|
+|.......|
+|.......|
+|.....#.|
+|.....#.|
+|..####.|
+|.###...|
+|..#....|
+|.####..|
+|....##.|
+|....##.|
+|....#..|
+|..#.#..|
+|..#.#..|
+|#####..|
+|..###..|
+|...#...|
+|..####.|
++-------+
+
+|..@@...|
+|..@@...|
+|.......|
+|.......|
+|.......|
+|....#..|
+|....#..|
+|....##.|
+|....##.|
+|..####.|
+|.###...|
+|..#....|
+|.####..|
+|....##.|
+|....##.|
+|....#..|
+|..#.#..|
+|..#.#..|
+|#####..|
+|..###..|
+|...#...|
+|..####.|
++-------+
+
+|..@@@@.|
+|.......|
+|.......|
+|.......|
+|....#..|
+|....#..|
+|....##.|
+|##..##.|
+|######.|
+|.###...|
+|..#....|
+|.####..|
+|....##.|
+|....##.|
+|....#..|
+|..#.#..|
+|..#.#..|
+|#####..|
+|..###..|
+|...#...|
+|..####.|
++-------+
+
+
+ +To prove to the elephants your simulation is accurate, they want to know how tall the tower will get after 2022 rocks have stopped (but before the 2023rd rock begins falling). In this example, the tower of rocks will be 3068 units tall. + +How many units tall will the tower of rocks be after 2022 rocks have stopped falling? + + +## --- Part Two --- +The elephants are not impressed by your simulation. They demand to know how tall the tower will be after 1000000000000 rocks have stopped! Only then will they feel confident enough to proceed through the cave. + +In the example above, the tower would be 1514285714288 units tall! + +How tall will the tower be after 1000000000000 rocks have stopped? + + diff --git a/2022/Day17/input.in b/2022/Day17/input.in index e90b84848..adbc38cc4 100644 Binary files a/2022/Day17/input.in and b/2022/Day17/input.in differ diff --git a/2022/Day18/README.md b/2022/Day18/README.md index 638baaf1f..9774b2edf 100644 --- a/2022/Day18/README.md +++ b/2022/Day18/README.md @@ -1,6 +1,46 @@ +original source: [https://adventofcode.com/2022/day/18](https://adventofcode.com/2022/day/18) ## --- Day 18: Boiling Boulders --- You and the elephants finally reach fresh air. You've emerged near the base of a large volcano that seems to be actively erupting! Fortunately, the lava seems to be flowing away from you and toward the ocean. Bits of lava are still being ejected toward you, so you're sheltering in the cavern exit a little longer. Outside the cave, you can see the lava landing in a pond and hear it loudly hissing as it solidifies. -Read the [full puzzle](https://adventofcode.com/2022/day/18). \ No newline at end of file +Depending on the specific compounds in the lava and speed at which it cools, it might be forming [obsidian](https://en.wikipedia.org/wiki/Obsidian)! The cooling rate should be based on the surface area of the lava droplets, so you take a quick scan of a droplet as it flies past you (your puzzle input). + +Because of how quickly the lava is moving, the scan isn't very good; its resolution is quite low and, as a result, it approximates the shape of the lava droplet with 1x1x1 cubes on a 3D grid, each given as its x,y,z position. + +To approximate the surface area, count the number of sides of each cube that are not immediately connected to another cube. So, if your scan were only two adjacent cubes like 1,1,1 and 2,1,1, each cube would have a single side covered and five sides exposed, a total surface area of 10 sides. + +Here's a larger example: + +
+2,2,2
+1,2,2
+3,2,2
+2,1,2
+2,3,2
+2,2,1
+2,2,3
+2,2,4
+2,2,6
+1,2,5
+3,2,5
+2,1,5
+2,3,5
+
+
+ +In the above example, after counting up all the sides that aren't connected to another cube, the total surface area is 64. + +What is the surface area of your scanned lava droplet? + + +## --- Part Two --- +Something seems off about your calculation. The cooling rate depends on exterior surface area, but your calculation also included the surface area of air pockets trapped in the lava droplet. + +Instead, consider only cube sides that could be reached by the water and steam as the lava droplet tumbles into the pond. The steam will expand to reach as much as possible, completely displacing any air on the outside of the lava droplet but never expanding diagonally. + +In the larger example above, exactly one cube of air is trapped within the lava droplet (at 2,2,5), so the exterior surface area of the lava droplet is 58. + +What is the exterior surface area of your scanned lava droplet? + + diff --git a/2022/Day18/input.in b/2022/Day18/input.in index ba1b7efca..93bfca022 100644 Binary files a/2022/Day18/input.in and b/2022/Day18/input.in differ diff --git a/2022/Day19/README.md b/2022/Day19/README.md index a4de31aed..766ed008a 100644 --- a/2022/Day19/README.md +++ b/2022/Day19/README.md @@ -1,6 +1,389 @@ +original source: [https://adventofcode.com/2022/day/19](https://adventofcode.com/2022/day/19) ## --- Day 19: Not Enough Minerals --- Your scans show that the lava did indeed form obsidian! The wind has changed direction enough to stop sending lava droplets toward you, so you and the elephants exit the cave. As you do, you notice a collection of [geodes](https://en.wikipedia.org/wiki/Geode) around the pond. Perhaps you could use the obsidian to create some geode-cracking robots and break them open? -Read the [full puzzle](https://adventofcode.com/2022/day/19). \ No newline at end of file +To collect the obsidian from the bottom of the pond, you'll need waterproof obsidian-collecting robots. Fortunately, there is an abundant amount of clay nearby that you can use to make them waterproof. + +In order to harvest the clay, you'll need special-purpose clay-collecting robots. To make any type of robot, you'll need ore, which is also plentiful but in the opposite direction from the clay. + +Collecting ore requires ore-collecting robots with big drills. Fortunately, you have exactly one ore-collecting robot in your pack that you can use to kickstart the whole operation. + +Each robot can collect 1 of its resource type per minute. It also takes one minute for the robot factory (also conveniently from your pack) to construct any type of robot, although it consumes the necessary resources available when construction begins. + +The robot factory has many blueprints (your puzzle input) you can choose from, but once you've configured it with a blueprint, you can't change it. You'll need to work out which blueprint is best. + +For example: + +
+Blueprint 1:
+  Each ore robot costs 4 ore.
+  Each clay robot costs 2 ore.
+  Each obsidian robot costs 3 ore and 14 clay.
+  Each geode robot costs 2 ore and 7 obsidian.
+
+Blueprint 2:
+  Each ore robot costs 2 ore.
+  Each clay robot costs 3 ore.
+  Each obsidian robot costs 3 ore and 8 clay.
+  Each geode robot costs 3 ore and 12 obsidian.
+
+
+ +(Blueprints have been line-wrapped here for legibility. The robot factory's actual assortment of blueprints are provided one blueprint per line.) + +The elephants are starting to look hungry, so you shouldn't take too long; you need to figure out which blueprint would maximize the number of opened geodes after 24 minutes by figuring out which robots to build and when to build them. + +Using blueprint 1 in the example above, the largest number of geodes you could open in 24 minutes is 9. One way to achieve that is: + +
+== Minute 1 ==
+1 ore-collecting robot collects 1 ore; you now have 1 ore.
+
+== Minute 2 ==
+1 ore-collecting robot collects 1 ore; you now have 2 ore.
+
+== Minute 3 ==
+Spend 2 ore to start building a clay-collecting robot.
+1 ore-collecting robot collects 1 ore; you now have 1 ore.
+The new clay-collecting robot is ready; you now have 1 of them.
+
+== Minute 4 ==
+1 ore-collecting robot collects 1 ore; you now have 2 ore.
+1 clay-collecting robot collects 1 clay; you now have 1 clay.
+
+== Minute 5 ==
+Spend 2 ore to start building a clay-collecting robot.
+1 ore-collecting robot collects 1 ore; you now have 1 ore.
+1 clay-collecting robot collects 1 clay; you now have 2 clay.
+The new clay-collecting robot is ready; you now have 2 of them.
+
+== Minute 6 ==
+1 ore-collecting robot collects 1 ore; you now have 2 ore.
+2 clay-collecting robots collect 2 clay; you now have 4 clay.
+
+== Minute 7 ==
+Spend 2 ore to start building a clay-collecting robot.
+1 ore-collecting robot collects 1 ore; you now have 1 ore.
+2 clay-collecting robots collect 2 clay; you now have 6 clay.
+The new clay-collecting robot is ready; you now have 3 of them.
+
+== Minute 8 ==
+1 ore-collecting robot collects 1 ore; you now have 2 ore.
+3 clay-collecting robots collect 3 clay; you now have 9 clay.
+
+== Minute 9 ==
+1 ore-collecting robot collects 1 ore; you now have 3 ore.
+3 clay-collecting robots collect 3 clay; you now have 12 clay.
+
+== Minute 10 ==
+1 ore-collecting robot collects 1 ore; you now have 4 ore.
+3 clay-collecting robots collect 3 clay; you now have 15 clay.
+
+== Minute 11 ==
+Spend 3 ore and 14 clay to start building an obsidian-collecting robot.
+1 ore-collecting robot collects 1 ore; you now have 2 ore.
+3 clay-collecting robots collect 3 clay; you now have 4 clay.
+The new obsidian-collecting robot is ready; you now have 1 of them.
+
+== Minute 12 ==
+Spend 2 ore to start building a clay-collecting robot.
+1 ore-collecting robot collects 1 ore; you now have 1 ore.
+3 clay-collecting robots collect 3 clay; you now have 7 clay.
+1 obsidian-collecting robot collects 1 obsidian; you now have 1 obsidian.
+The new clay-collecting robot is ready; you now have 4 of them.
+
+== Minute 13 ==
+1 ore-collecting robot collects 1 ore; you now have 2 ore.
+4 clay-collecting robots collect 4 clay; you now have 11 clay.
+1 obsidian-collecting robot collects 1 obsidian; you now have 2 obsidian.
+
+== Minute 14 ==
+1 ore-collecting robot collects 1 ore; you now have 3 ore.
+4 clay-collecting robots collect 4 clay; you now have 15 clay.
+1 obsidian-collecting robot collects 1 obsidian; you now have 3 obsidian.
+
+== Minute 15 ==
+Spend 3 ore and 14 clay to start building an obsidian-collecting robot.
+1 ore-collecting robot collects 1 ore; you now have 1 ore.
+4 clay-collecting robots collect 4 clay; you now have 5 clay.
+1 obsidian-collecting robot collects 1 obsidian; you now have 4 obsidian.
+The new obsidian-collecting robot is ready; you now have 2 of them.
+
+== Minute 16 ==
+1 ore-collecting robot collects 1 ore; you now have 2 ore.
+4 clay-collecting robots collect 4 clay; you now have 9 clay.
+2 obsidian-collecting robots collect 2 obsidian; you now have 6 obsidian.
+
+== Minute 17 ==
+1 ore-collecting robot collects 1 ore; you now have 3 ore.
+4 clay-collecting robots collect 4 clay; you now have 13 clay.
+2 obsidian-collecting robots collect 2 obsidian; you now have 8 obsidian.
+
+== Minute 18 ==
+Spend 2 ore and 7 obsidian to start building a geode-cracking robot.
+1 ore-collecting robot collects 1 ore; you now have 2 ore.
+4 clay-collecting robots collect 4 clay; you now have 17 clay.
+2 obsidian-collecting robots collect 2 obsidian; you now have 3 obsidian.
+The new geode-cracking robot is ready; you now have 1 of them.
+
+== Minute 19 ==
+1 ore-collecting robot collects 1 ore; you now have 3 ore.
+4 clay-collecting robots collect 4 clay; you now have 21 clay.
+2 obsidian-collecting robots collect 2 obsidian; you now have 5 obsidian.
+1 geode-cracking robot cracks 1 geode; you now have 1 open geode.
+
+== Minute 20 ==
+1 ore-collecting robot collects 1 ore; you now have 4 ore.
+4 clay-collecting robots collect 4 clay; you now have 25 clay.
+2 obsidian-collecting robots collect 2 obsidian; you now have 7 obsidian.
+1 geode-cracking robot cracks 1 geode; you now have 2 open geodes.
+
+== Minute 21 ==
+Spend 2 ore and 7 obsidian to start building a geode-cracking robot.
+1 ore-collecting robot collects 1 ore; you now have 3 ore.
+4 clay-collecting robots collect 4 clay; you now have 29 clay.
+2 obsidian-collecting robots collect 2 obsidian; you now have 2 obsidian.
+1 geode-cracking robot cracks 1 geode; you now have 3 open geodes.
+The new geode-cracking robot is ready; you now have 2 of them.
+
+== Minute 22 ==
+1 ore-collecting robot collects 1 ore; you now have 4 ore.
+4 clay-collecting robots collect 4 clay; you now have 33 clay.
+2 obsidian-collecting robots collect 2 obsidian; you now have 4 obsidian.
+2 geode-cracking robots crack 2 geodes; you now have 5 open geodes.
+
+== Minute 23 ==
+1 ore-collecting robot collects 1 ore; you now have 5 ore.
+4 clay-collecting robots collect 4 clay; you now have 37 clay.
+2 obsidian-collecting robots collect 2 obsidian; you now have 6 obsidian.
+2 geode-cracking robots crack 2 geodes; you now have 7 open geodes.
+
+== Minute 24 ==
+1 ore-collecting robot collects 1 ore; you now have 6 ore.
+4 clay-collecting robots collect 4 clay; you now have 41 clay.
+2 obsidian-collecting robots collect 2 obsidian; you now have 8 obsidian.
+2 geode-cracking robots crack 2 geodes; you now have 9 open geodes.
+
+
+ +However, by using blueprint 2 in the example above, you could do even better: the largest number of geodes you could open in 24 minutes is 12. + +Determine the quality level of each blueprint by multiplying that blueprint's ID number with the largest number of geodes that can be opened in 24 minutes using that blueprint. In this example, the first blueprint has ID 1 and can open 9 geodes, so its quality level is 9. The second blueprint has ID 2 and can open 12 geodes, so its quality level is 24. Finally, if you add up the quality levels of all of the blueprints in the list, you get 33. + +Determine the quality level of each blueprint using the largest number of geodes it could produce in 24 minutes. What do you get if you add up the quality level of all of the blueprints in your list? + + +## --- Part Two --- +While you were choosing the best blueprint, the elephants found some food on their own, so you're not in as much of a hurry; you figure you probably have 32 minutes before the wind changes direction again and you'll need to get out of range of the erupting volcano. + +Unfortunately, one of the elephants ate most of your blueprint list! Now, only the first three blueprints in your list are intact. + +In 32 minutes, the largest number of geodes blueprint 1 (from the example above) can open is 56. One way to achieve that is: + +
+== Minute 1 ==
+1 ore-collecting robot collects 1 ore; you now have 1 ore.
+
+== Minute 2 ==
+1 ore-collecting robot collects 1 ore; you now have 2 ore.
+
+== Minute 3 ==
+1 ore-collecting robot collects 1 ore; you now have 3 ore.
+
+== Minute 4 ==
+1 ore-collecting robot collects 1 ore; you now have 4 ore.
+
+== Minute 5 ==
+Spend 4 ore to start building an ore-collecting robot.
+1 ore-collecting robot collects 1 ore; you now have 1 ore.
+The new ore-collecting robot is ready; you now have 2 of them.
+
+== Minute 6 ==
+2 ore-collecting robots collect 2 ore; you now have 3 ore.
+
+== Minute 7 ==
+Spend 2 ore to start building a clay-collecting robot.
+2 ore-collecting robots collect 2 ore; you now have 3 ore.
+The new clay-collecting robot is ready; you now have 1 of them.
+
+== Minute 8 ==
+Spend 2 ore to start building a clay-collecting robot.
+2 ore-collecting robots collect 2 ore; you now have 3 ore.
+1 clay-collecting robot collects 1 clay; you now have 1 clay.
+The new clay-collecting robot is ready; you now have 2 of them.
+
+== Minute 9 ==
+Spend 2 ore to start building a clay-collecting robot.
+2 ore-collecting robots collect 2 ore; you now have 3 ore.
+2 clay-collecting robots collect 2 clay; you now have 3 clay.
+The new clay-collecting robot is ready; you now have 3 of them.
+
+== Minute 10 ==
+Spend 2 ore to start building a clay-collecting robot.
+2 ore-collecting robots collect 2 ore; you now have 3 ore.
+3 clay-collecting robots collect 3 clay; you now have 6 clay.
+The new clay-collecting robot is ready; you now have 4 of them.
+
+== Minute 11 ==
+Spend 2 ore to start building a clay-collecting robot.
+2 ore-collecting robots collect 2 ore; you now have 3 ore.
+4 clay-collecting robots collect 4 clay; you now have 10 clay.
+The new clay-collecting robot is ready; you now have 5 of them.
+
+== Minute 12 ==
+Spend 2 ore to start building a clay-collecting robot.
+2 ore-collecting robots collect 2 ore; you now have 3 ore.
+5 clay-collecting robots collect 5 clay; you now have 15 clay.
+The new clay-collecting robot is ready; you now have 6 of them.
+
+== Minute 13 ==
+Spend 2 ore to start building a clay-collecting robot.
+2 ore-collecting robots collect 2 ore; you now have 3 ore.
+6 clay-collecting robots collect 6 clay; you now have 21 clay.
+The new clay-collecting robot is ready; you now have 7 of them.
+
+== Minute 14 ==
+Spend 3 ore and 14 clay to start building an obsidian-collecting robot.
+2 ore-collecting robots collect 2 ore; you now have 2 ore.
+7 clay-collecting robots collect 7 clay; you now have 14 clay.
+The new obsidian-collecting robot is ready; you now have 1 of them.
+
+== Minute 15 ==
+2 ore-collecting robots collect 2 ore; you now have 4 ore.
+7 clay-collecting robots collect 7 clay; you now have 21 clay.
+1 obsidian-collecting robot collects 1 obsidian; you now have 1 obsidian.
+
+== Minute 16 ==
+Spend 3 ore and 14 clay to start building an obsidian-collecting robot.
+2 ore-collecting robots collect 2 ore; you now have 3 ore.
+7 clay-collecting robots collect 7 clay; you now have 14 clay.
+1 obsidian-collecting robot collects 1 obsidian; you now have 2 obsidian.
+The new obsidian-collecting robot is ready; you now have 2 of them.
+
+== Minute 17 ==
+Spend 3 ore and 14 clay to start building an obsidian-collecting robot.
+2 ore-collecting robots collect 2 ore; you now have 2 ore.
+7 clay-collecting robots collect 7 clay; you now have 7 clay.
+2 obsidian-collecting robots collect 2 obsidian; you now have 4 obsidian.
+The new obsidian-collecting robot is ready; you now have 3 of them.
+
+== Minute 18 ==
+2 ore-collecting robots collect 2 ore; you now have 4 ore.
+7 clay-collecting robots collect 7 clay; you now have 14 clay.
+3 obsidian-collecting robots collect 3 obsidian; you now have 7 obsidian.
+
+== Minute 19 ==
+Spend 3 ore and 14 clay to start building an obsidian-collecting robot.
+2 ore-collecting robots collect 2 ore; you now have 3 ore.
+7 clay-collecting robots collect 7 clay; you now have 7 clay.
+3 obsidian-collecting robots collect 3 obsidian; you now have 10 obsidian.
+The new obsidian-collecting robot is ready; you now have 4 of them.
+
+== Minute 20 ==
+Spend 2 ore and 7 obsidian to start building a geode-cracking robot.
+2 ore-collecting robots collect 2 ore; you now have 3 ore.
+7 clay-collecting robots collect 7 clay; you now have 14 clay.
+4 obsidian-collecting robots collect 4 obsidian; you now have 7 obsidian.
+The new geode-cracking robot is ready; you now have 1 of them.
+
+== Minute 21 ==
+Spend 3 ore and 14 clay to start building an obsidian-collecting robot.
+2 ore-collecting robots collect 2 ore; you now have 2 ore.
+7 clay-collecting robots collect 7 clay; you now have 7 clay.
+4 obsidian-collecting robots collect 4 obsidian; you now have 11 obsidian.
+1 geode-cracking robot cracks 1 geode; you now have 1 open geode.
+The new obsidian-collecting robot is ready; you now have 5 of them.
+
+== Minute 22 ==
+Spend 2 ore and 7 obsidian to start building a geode-cracking robot.
+2 ore-collecting robots collect 2 ore; you now have 2 ore.
+7 clay-collecting robots collect 7 clay; you now have 14 clay.
+5 obsidian-collecting robots collect 5 obsidian; you now have 9 obsidian.
+1 geode-cracking robot cracks 1 geode; you now have 2 open geodes.
+The new geode-cracking robot is ready; you now have 2 of them.
+
+== Minute 23 ==
+Spend 2 ore and 7 obsidian to start building a geode-cracking robot.
+2 ore-collecting robots collect 2 ore; you now have 2 ore.
+7 clay-collecting robots collect 7 clay; you now have 21 clay.
+5 obsidian-collecting robots collect 5 obsidian; you now have 7 obsidian.
+2 geode-cracking robots crack 2 geodes; you now have 4 open geodes.
+The new geode-cracking robot is ready; you now have 3 of them.
+
+== Minute 24 ==
+Spend 2 ore and 7 obsidian to start building a geode-cracking robot.
+2 ore-collecting robots collect 2 ore; you now have 2 ore.
+7 clay-collecting robots collect 7 clay; you now have 28 clay.
+5 obsidian-collecting robots collect 5 obsidian; you now have 5 obsidian.
+3 geode-cracking robots crack 3 geodes; you now have 7 open geodes.
+The new geode-cracking robot is ready; you now have 4 of them.
+
+== Minute 25 ==
+2 ore-collecting robots collect 2 ore; you now have 4 ore.
+7 clay-collecting robots collect 7 clay; you now have 35 clay.
+5 obsidian-collecting robots collect 5 obsidian; you now have 10 obsidian.
+4 geode-cracking robots crack 4 geodes; you now have 11 open geodes.
+
+== Minute 26 ==
+Spend 2 ore and 7 obsidian to start building a geode-cracking robot.
+2 ore-collecting robots collect 2 ore; you now have 4 ore.
+7 clay-collecting robots collect 7 clay; you now have 42 clay.
+5 obsidian-collecting robots collect 5 obsidian; you now have 8 obsidian.
+4 geode-cracking robots crack 4 geodes; you now have 15 open geodes.
+The new geode-cracking robot is ready; you now have 5 of them.
+
+== Minute 27 ==
+Spend 2 ore and 7 obsidian to start building a geode-cracking robot.
+2 ore-collecting robots collect 2 ore; you now have 4 ore.
+7 clay-collecting robots collect 7 clay; you now have 49 clay.
+5 obsidian-collecting robots collect 5 obsidian; you now have 6 obsidian.
+5 geode-cracking robots crack 5 geodes; you now have 20 open geodes.
+The new geode-cracking robot is ready; you now have 6 of them.
+
+== Minute 28 ==
+2 ore-collecting robots collect 2 ore; you now have 6 ore.
+7 clay-collecting robots collect 7 clay; you now have 56 clay.
+5 obsidian-collecting robots collect 5 obsidian; you now have 11 obsidian.
+6 geode-cracking robots crack 6 geodes; you now have 26 open geodes.
+
+== Minute 29 ==
+Spend 2 ore and 7 obsidian to start building a geode-cracking robot.
+2 ore-collecting robots collect 2 ore; you now have 6 ore.
+7 clay-collecting robots collect 7 clay; you now have 63 clay.
+5 obsidian-collecting robots collect 5 obsidian; you now have 9 obsidian.
+6 geode-cracking robots crack 6 geodes; you now have 32 open geodes.
+The new geode-cracking robot is ready; you now have 7 of them.
+
+== Minute 30 ==
+Spend 2 ore and 7 obsidian to start building a geode-cracking robot.
+2 ore-collecting robots collect 2 ore; you now have 6 ore.
+7 clay-collecting robots collect 7 clay; you now have 70 clay.
+5 obsidian-collecting robots collect 5 obsidian; you now have 7 obsidian.
+7 geode-cracking robots crack 7 geodes; you now have 39 open geodes.
+The new geode-cracking robot is ready; you now have 8 of them.
+
+== Minute 31 ==
+Spend 2 ore and 7 obsidian to start building a geode-cracking robot.
+2 ore-collecting robots collect 2 ore; you now have 6 ore.
+7 clay-collecting robots collect 7 clay; you now have 77 clay.
+5 obsidian-collecting robots collect 5 obsidian; you now have 5 obsidian.
+8 geode-cracking robots crack 8 geodes; you now have 47 open geodes.
+The new geode-cracking robot is ready; you now have 9 of them.
+
+== Minute 32 ==
+2 ore-collecting robots collect 2 ore; you now have 8 ore.
+7 clay-collecting robots collect 7 clay; you now have 84 clay.
+5 obsidian-collecting robots collect 5 obsidian; you now have 10 obsidian.
+9 geode-cracking robots crack 9 geodes; you now have 56 open geodes.
+
+
+ +However, blueprint 2 from the example above is still better; using it, the largest number of geodes you could open in 32 minutes is 62. + +You no longer have enough blueprints to worry about quality levels. Instead, for each of the first three blueprints, determine the largest number of geodes you could open; then, multiply these three values together. + +Don't worry about quality levels; instead, just determine the largest number of geodes you could open using each of the first three blueprints. What do you get if you multiply these numbers together? + + diff --git a/2022/Day19/input.in b/2022/Day19/input.in index e1861b7f3..bb0f1d73e 100644 Binary files a/2022/Day19/input.in and b/2022/Day19/input.in differ diff --git a/2022/Day20/README.md b/2022/Day20/README.md index 6a7c0a971..a39bbccab 100644 --- a/2022/Day20/README.md +++ b/2022/Day20/README.md @@ -1,6 +1,115 @@ +original source: [https://adventofcode.com/2022/day/20](https://adventofcode.com/2022/day/20) ## --- Day 20: Grove Positioning System --- It's finally time to meet back up with the Elves. When you try to contact them, however, you get no reply. Perhaps you're out of range? You know they're headed to the grove where the star fruit grows, so if you can figure out where that is, you should be able to meet back up with them. -Read the [full puzzle](https://adventofcode.com/2022/day/20). \ No newline at end of file +Fortunately, your handheld device has a file (your puzzle input) that contains the grove's coordinates! Unfortunately, the file is encrypted - just in case the device were to fall into the wrong hands. + +Maybe you can decrypt it? + +When you were still back at the camp, you overheard some Elves talking about coordinate file encryption. The main operation involved in decrypting the file is called mixing. + +The encrypted file is a list of numbers. To mix the file, move each number forward or backward in the file a number of positions equal to the value of the number being moved. The list is circular, so moving a number off one end of the list wraps back around to the other end as if the ends were connected. + +For example, to move the 1 in a sequence like 4, 5, 6, 1, 7, 8, 9, the 1 moves one position forward: 4, 5, 6, 7, 1, 8, 9. To move the -2 in a sequence like 4, -2, 5, 6, 7, 8, 9, the -2 moves two positions backward, wrapping around: 4, 5, 6, 7, 8, -2, 9. + +The numbers should be moved in the order they originally appear in the encrypted file. Numbers moving around during the mixing process do not change the order in which the numbers are moved. + +Consider this encrypted file: + +
+1
+2
+-3
+3
+-2
+0
+4
+
+
+ +Mixing this file proceeds as follows: + +
+Initial arrangement:
+1, 2, -3, 3, -2, 0, 4
+
+1 moves between 2 and -3:
+2, 1, -3, 3, -2, 0, 4
+
+2 moves between -3 and 3:
+1, -3, 2, 3, -2, 0, 4
+
+-3 moves between -2 and 0:
+1, 2, 3, -2, -3, 0, 4
+
+3 moves between 0 and 4:
+1, 2, -2, -3, 0, 3, 4
+
+-2 moves between 4 and 1:
+1, 2, -3, 0, 3, 4, -2
+
+0 does not move:
+1, 2, -3, 0, 3, 4, -2
+
+4 moves between -3 and 0:
+1, 2, -3, 4, 0, 3, -2
+
+
+ +Then, the grove coordinates can be found by looking at the 1000th, 2000th, and 3000th numbers after the value 0, wrapping around the list as necessary. In the above example, the 1000th number after 0 is 4, the 2000th is -3, and the 3000th is 2; adding these together produces 3. + +Mix your encrypted file exactly once. What is the sum of the three numbers that form the grove coordinates? + + +## --- Part Two --- +The grove coordinate values seem nonsensical. While you ponder the mysteries of Elf encryption, you suddenly remember the rest of the decryption routine you overheard back at camp. + +First, you need to apply the decryption key, 811589153. Multiply each number by the decryption key before you begin; this will produce the actual list of numbers to mix. + +Second, you need to mix the list of numbers ten times. The order in which the numbers are mixed does not change during mixing; the numbers are still moved in the order they appeared in the original, pre-mixed list. (So, if -3 appears fourth in the original list of numbers to mix, -3 will be the fourth number to move during each round of mixing.) + +Using the same example as above: + +
+Initial arrangement:
+811589153, 1623178306, -2434767459, 2434767459, -1623178306, 0, 3246356612
+
+After 1 round of mixing:
+0, -2434767459, 3246356612, -1623178306, 2434767459, 1623178306, 811589153
+
+After 2 rounds of mixing:
+0, 2434767459, 1623178306, 3246356612, -2434767459, -1623178306, 811589153
+
+After 3 rounds of mixing:
+0, 811589153, 2434767459, 3246356612, 1623178306, -1623178306, -2434767459
+
+After 4 rounds of mixing:
+0, 1623178306, -2434767459, 811589153, 2434767459, 3246356612, -1623178306
+
+After 5 rounds of mixing:
+0, 811589153, -1623178306, 1623178306, -2434767459, 3246356612, 2434767459
+
+After 6 rounds of mixing:
+0, 811589153, -1623178306, 3246356612, -2434767459, 1623178306, 2434767459
+
+After 7 rounds of mixing:
+0, -2434767459, 2434767459, 1623178306, -1623178306, 811589153, 3246356612
+
+After 8 rounds of mixing:
+0, 1623178306, 3246356612, 811589153, -2434767459, 2434767459, -1623178306
+
+After 9 rounds of mixing:
+0, 811589153, 1623178306, -2434767459, 3246356612, 2434767459, -1623178306
+
+After 10 rounds of mixing:
+0, -2434767459, 1623178306, 3246356612, -1623178306, 2434767459, 811589153
+
+
+ +The grove coordinates can still be found in the same way. Here, the 1000th number after 0 is 811589153, the 2000th is 2434767459, and the 3000th is -1623178306; adding these together produces 1623178306. + +Apply the decryption key and mix your encrypted file ten times. What is the sum of the three numbers that form the grove coordinates? + + diff --git a/2022/Day20/input.in b/2022/Day20/input.in index c78f4a139..d58ca8bbd 100644 Binary files a/2022/Day20/input.in and b/2022/Day20/input.in differ diff --git a/2022/Day21/README.md b/2022/Day21/README.md index cb5007081..0b47c5bcc 100644 --- a/2022/Day21/README.md +++ b/2022/Day21/README.md @@ -1,6 +1,61 @@ +original source: [https://adventofcode.com/2022/day/21](https://adventofcode.com/2022/day/21) ## --- Day 21: Monkey Math --- The [monkeys](11) are back! You're worried they're going to try to steal your stuff again, but it seems like they're just holding their ground and making various monkey noises at you. Eventually, one of the elephants realizes you don't speak monkey and comes over to interpret. As it turns out, they overheard you talking about trying to find the grove; they can show you a shortcut if you answer their riddle. -Read the [full puzzle](https://adventofcode.com/2022/day/21). \ No newline at end of file +Each monkey is given a job: either to yell a specific number or to yell the result of a math operation. All of the number-yelling monkeys know their number from the start; however, the math operation monkeys need to wait for two other monkeys to yell a number, and those two other monkeys might also be waiting on other monkeys. + +Your job is to work out the number the monkey named root will yell before the monkeys figure it out themselves. + +For example: + +
+root: pppw + sjmn
+dbpl: 5
+cczh: sllz + lgvd
+zczc: 2
+ptdq: humn - dvpt
+dvpt: 3
+lfqf: 4
+humn: 5
+ljgn: 2
+sjmn: drzm * dbpl
+sllz: 4
+pppw: cczh / lfqf
+lgvd: ljgn * ptdq
+drzm: hmdt - zczc
+hmdt: 32
+
+
+ +Each line contains the name of a monkey, a colon, and then the job of that monkey: + + + - A lone number means the monkey's job is simply to yell that number. + - A job like aaaa + bbbb means the monkey waits for monkeys aaaa and bbbb to yell each of their numbers; the monkey then yells the sum of those two numbers. + - aaaa - bbbb means the monkey yells aaaa's number minus bbbb's number. + - Job aaaa * bbbb will yell aaaa's number multiplied by bbbb's number. + - Job aaaa / bbbb will yell aaaa's number divided by bbbb's number. + +So, in the above example, monkey drzm has to wait for monkeys hmdt and zczc to yell their numbers. Fortunately, both hmdt and zczc have jobs that involve simply yelling a single number, so they do this immediately: 32 and 2. Monkey drzm can then yell its number by finding 32 minus 2: 30. + +Then, monkey sjmn has one of its numbers (30, from monkey drzm), and already has its other number, 5, from dbpl. This allows it to yell its own number by finding 30 multiplied by 5: 150. + +This process continues until root yells a number: 152. + +However, your actual situation involves considerably more monkeys. What number will the monkey named root yell? + + +## --- Part Two --- +Due to some kind of monkey-elephant-human mistranslation, you seem to have misunderstood a few key details about the riddle. + +First, you got the wrong job for the monkey named root; specifically, you got the wrong math operation. The correct operation for monkey root should be =, which means that it still listens for two numbers (from the same two monkeys as before), but now checks that the two numbers match. + +Second, you got the wrong monkey for the job starting with humn:. It isn't a monkey - it's you. Actually, you got the job wrong, too: you need to figure out what number you need to yell so that root's equality check passes. (The number that appears after humn: in your input is now irrelevant.) + +In the above example, the number you need to yell to pass root's equality test is 301. (This causes root to get the same number, 150, from both of its monkeys.) + +What number do you yell to pass root's equality test? + + diff --git a/2022/Day21/input.in b/2022/Day21/input.in index 5bfa1ab05..e59652dcc 100644 Binary files a/2022/Day21/input.in and b/2022/Day21/input.in differ diff --git a/2022/Day22/README.md b/2022/Day22/README.md index 5345553d8..cb7af1faf 100644 --- a/2022/Day22/README.md +++ b/2022/Day22/README.md @@ -1,6 +1,173 @@ +original source: [https://adventofcode.com/2022/day/22](https://adventofcode.com/2022/day/22) ## --- Day 22: Monkey Map --- The monkeys take you on a surprisingly easy trail through the jungle. They're even going in roughly the right direction according to your handheld device's Grove Positioning System. As you walk, the monkeys explain that the grove is protected by a force field. To pass through the force field, you have to enter a password; doing so involves tracing a specific path on a strangely-shaped board. -Read the [full puzzle](https://adventofcode.com/2022/day/22). \ No newline at end of file +At least, you're pretty sure that's what you have to do; the elephants aren't exactly fluent in monkey. + +The monkeys give you notes that they took when they last saw the password entered (your puzzle input). + +For example: + +
+        ...#
+        .#..
+        #...
+        ....
+...#.......#
+........#...
+..#....#....
+..........#.
+        ...#....
+        .....#..
+        .#......
+        ......#.
+
+10R5L5R10L4R5L5
+
+
+ +The first half of the monkeys' notes is a map of the board. It is comprised of a set of open tiles (on which you can move, drawn .) and solid walls (tiles which you cannot enter, drawn #). + +The second half is a description of the path you must follow. It consists of alternating numbers and letters: + + + - A number indicates the number of tiles to move in the direction you are facing. If you run into a wall, you stop moving forward and continue with the next instruction. + - A letter indicates whether to turn 90 degrees clockwise (R) or counterclockwise (L). Turning happens in-place; it does not change your current tile. + +So, a path like 10R5 means "go forward 10 tiles, then turn clockwise 90 degrees, then go forward 5 tiles". + +You begin the path in the leftmost open tile of the top row of tiles. Initially, you are facing to the right (from the perspective of how the map is drawn). + +If a movement instruction would take you off of the map, you wrap around to the other side of the board. In other words, if your next tile is off of the board, you should instead look in the direction opposite of your current facing as far as you can until you find the opposite edge of the board, then reappear there. + +For example, if you are at A and facing to the right, the tile in front of you is marked B; if you are at C and facing down, the tile in front of you is marked D: + +
+        ...#
+        .#..
+        #...
+        ....
+...#.D.....#
+........#...
+B.#....#...A
+.....C....#.
+        ...#....
+        .....#..
+        .#......
+        ......#.
+
+
+ +It is possible for the next tile (after wrapping around) to be a wall; this still counts as there being a wall in front of you, and so movement stops before you actually wrap to the other side of the board. + +By drawing the last facing you had with an arrow on each tile you visit, the full path taken by the above example looks like this: + +
+        >>v#    
+        .#v.    
+        #.v.    
+        ..v.    
+...#...v..v#    
+>>>v...>#.>>    
+..#v...#....    
+...>>>>v..#.    
+        ...#....
+        .....#..
+        .#......
+        ......#.
+
+
+ +To finish providing the password to this strange input device, you need to determine numbers for your final row, column, and facing as your final position appears from the perspective of the original map. Rows start from 1 at the top and count downward; columns start from 1 at the left and count rightward. (In the above example, row 1, column 1 refers to the empty space with no tile on it in the top-left corner.) Facing is 0 for right (>), 1 for down (v), 2 for left (<), and 3 for up (^). The final password is the sum of 1000 times the row, 4 times the column, and the facing. + +In the above example, the final row is 6, the final column is 8, and the final facing is 0. So, the final password is 1000 * 6 + 4 * 8 + 0: 6032. + +Follow the path given in the monkeys' notes. What is the final password? + + +## --- Part Two --- +As you reach the force field, you think you hear some Elves in the distance. Perhaps they've already arrived? + +You approach the strange input device, but it isn't quite what the monkeys drew in their notes. Instead, you are met with a large cube; each of its six faces is a square of 50x50 tiles. + +To be fair, the monkeys' map does have six 50x50 regions on it. If you were to carefully fold the map, you should be able to shape it into a cube! + +In the example above, the six (smaller, 4x4) faces of the cube are: + +
+        1111
+        1111
+        1111
+        1111
+222233334444
+222233334444
+222233334444
+222233334444
+        55556666
+        55556666
+        55556666
+        55556666
+
+
+ +You still start in the same position and with the same facing as before, but the wrapping rules are different. Now, if you would walk off the board, you instead proceed around the cube. From the perspective of the map, this can look a little strange. In the above example, if you are at A and move to the right, you would arrive at B facing down; if you are at C and move down, you would arrive at D facing up: + +
+        ...#
+        .#..
+        #...
+        ....
+...#.......#
+........#..A
+..#....#....
+.D........#.
+        ...#..B.
+        .....#..
+        .#......
+        ..C...#.
+
+
+ +Walls still block your path, even if they are on a different face of the cube. If you are at E facing up, your movement is blocked by the wall marked by the arrow: + +
+        ...#
+        .#..
+     -->#...
+        ....
+...#..E....#
+........#...
+..#....#....
+..........#.
+        ...#....
+        .....#..
+        .#......
+        ......#.
+
+
+ +Using the same method of drawing the last facing you had with an arrow on each tile you visit, the full path taken by the above example now looks like this: + +
+        >>v#    
+        .#v.    
+        #.v.    
+        ..v.    
+...#..^...v#    
+.>>>>>^.#.>>    
+.^#....#....    
+.^........#.    
+        ...#..v.
+        .....#v.
+        .#v<<<<.
+        ..v...#.
+
+
+ +The final password is still calculated from your final position and facing from the perspective of the map. In this example, the final row is 5, the final column is 7, and the final facing is 3, so the final password is 1000 * 5 + 4 * 7 + 3 = 5031. + +Fold the map into a cube, then follow the path given in the monkeys' notes. What is the final password? + + diff --git a/2022/Day22/input.in b/2022/Day22/input.in index 4f4bab86d..2ae873a02 100644 Binary files a/2022/Day22/input.in and b/2022/Day22/input.in differ diff --git a/2022/Day23/README.md b/2022/Day23/README.md index 1f35f8265..b8e09a2ce 100644 --- a/2022/Day23/README.md +++ b/2022/Day23/README.md @@ -1,6 +1,255 @@ +original source: [https://adventofcode.com/2022/day/23](https://adventofcode.com/2022/day/23) ## --- Day 23: Unstable Diffusion --- You enter a large crater of gray dirt where the grove is supposed to be. All around you, plants you imagine were expected to be full of fruit are instead withered and broken. A large group of Elves has formed in the middle of the grove. "...but this volcano has been dormant for months. Without ash, the fruit can't grow!" -Read the [full puzzle](https://adventofcode.com/2022/day/23). \ No newline at end of file +You look up to see a massive, snow-capped mountain towering above you. + +"It's not like there are other active volcanoes here; we've looked everywhere." + +"But our scanners show active magma flows; clearly it's going somewhere." + +They finally notice you at the edge of the grove, your pack almost overflowing from the random star fruit you've been collecting. Behind you, elephants and monkeys explore the grove, looking concerned. Then, the Elves recognize the ash cloud slowly spreading above your recent detour. + +"Why do you--" "How is--" "Did you just--" + +Before any of them can form a complete question, another Elf speaks up: "Okay, new plan. We have almost enough fruit already, and ash from the plume should spread here eventually. If we quickly plant new seedlings now, we can still make it to the extraction point. Spread out!" + +The Elves each reach into their pack and pull out a tiny plant. The plants rely on important nutrients from the ash, so they can't be planted too close together. + +There isn't enough time to let the Elves figure out where to plant the seedlings themselves; you quickly scan the grove (your puzzle input) and note their positions. + +For example: + +
+....#..
+..###.#
+#...#.#
+.#...##
+#.###..
+##.#.##
+.#..#..
+
+
+ +The scan shows Elves # and empty ground .; outside your scan, more empty ground extends a long way in every direction. The scan is oriented so that north is up; orthogonal directions are written N (north), S (south), W (west), and E (east), while diagonal directions are written NE, NW, SE, SW. + +The Elves follow a time-consuming process to figure out where they should each go; you can speed up this process considerably. The process consists of some number of rounds during which Elves alternate between considering where to move and actually moving. + +During the first half of each round, each Elf considers the eight positions adjacent to themself. If no other Elves are in one of those eight positions, the Elf does not do anything during this round. Otherwise, the Elf looks in each of four directions in the following order and proposes moving one step in the first valid direction: + + + - If there is no Elf in the N, NE, or NW adjacent positions, the Elf proposes moving north one step. + - If there is no Elf in the S, SE, or SW adjacent positions, the Elf proposes moving south one step. + - If there is no Elf in the W, NW, or SW adjacent positions, the Elf proposes moving west one step. + - If there is no Elf in the E, NE, or SE adjacent positions, the Elf proposes moving east one step. + +After each Elf has had a chance to propose a move, the second half of the round can begin. Simultaneously, each Elf moves to their proposed destination tile if they were the only Elf to propose moving to that position. If two or more Elves propose moving to the same position, none of those Elves move. + +Finally, at the end of the round, the first direction the Elves considered is moved to the end of the list of directions. For example, during the second round, the Elves would try proposing a move to the south first, then west, then east, then north. On the third round, the Elves would first consider west, then east, then north, then south. + +As a smaller example, consider just these five Elves: + +
+.....
+..##.
+..#..
+.....
+..##.
+.....
+
+
+ +The northernmost two Elves and southernmost two Elves all propose moving north, while the middle Elf cannot move north and proposes moving south. The middle Elf proposes the same destination as the southwest Elf, so neither of them move, but the other three do: + +
+..##.
+.....
+..#..
+...#.
+..#..
+.....
+
+
+ +Next, the northernmost two Elves and the southernmost Elf all propose moving south. Of the remaining middle two Elves, the west one cannot move south and proposes moving west, while the east one cannot move south or west and proposes moving east. All five Elves succeed in moving to their proposed positions: + +
+.....
+..##.
+.#...
+....#
+.....
+..#..
+
+
+ +Finally, the southernmost two Elves choose not to move at all. Of the remaining three Elves, the west one proposes moving west, the east one proposes moving east, and the middle one proposes moving north; all three succeed in moving: + +
+..#..
+....#
+#....
+....#
+.....
+..#..
+
+
+ +At this point, no Elves need to move, and so the process ends. + +The larger example above proceeds as follows: + +
+== Initial State ==
+..............
+..............
+.......#......
+.....###.#....
+...#...#.#....
+....#...##....
+...#.###......
+...##.#.##....
+....#..#......
+..............
+..............
+..............
+
+== End of Round 1 ==
+..............
+.......#......
+.....#...#....
+...#..#.#.....
+.......#..#...
+....#.#.##....
+..#..#.#......
+..#.#.#.##....
+..............
+....#..#......
+..............
+..............
+
+== End of Round 2 ==
+..............
+.......#......
+....#.....#...
+...#..#.#.....
+.......#...#..
+...#..#.#.....
+.#...#.#.#....
+..............
+..#.#.#.##....
+....#..#......
+..............
+..............
+
+== End of Round 3 ==
+..............
+.......#......
+.....#....#...
+..#..#...#....
+.......#...#..
+...#..#.#.....
+.#..#.....#...
+.......##.....
+..##.#....#...
+...#..........
+.......#......
+..............
+
+== End of Round 4 ==
+..............
+.......#......
+......#....#..
+..#...##......
+...#.....#.#..
+.........#....
+.#...###..#...
+..#......#....
+....##....#...
+....#.........
+.......#......
+..............
+
+== End of Round 5 ==
+.......#......
+..............
+..#..#.....#..
+.........#....
+......##...#..
+.#.#.####.....
+...........#..
+....##..#.....
+..#...........
+..........#...
+....#..#......
+..............
+
+
+ +After a few more rounds... + +
+== End of Round 10 ==
+.......#......
+...........#..
+..#.#..#......
+......#.......
+...#.....#..#.
+.#......##....
+.....##.......
+..#........#..
+....#.#..#....
+..............
+....#..#..#...
+..............
+
+
+ +To make sure they're on the right track, the Elves like to check after round 10 that they're making good progress toward covering enough ground. To do this, count the number of empty ground tiles contained by the smallest rectangle that contains every Elf. (The edges of the rectangle should be aligned to the N/S/E/W directions; the Elves do not have the patience to calculate arbitrary rectangles.) In the above example, that rectangle is: + +
+......#.....
+..........#.
+.#.#..#.....
+.....#......
+..#.....#..#
+#......##...
+....##......
+.#........#.
+...#.#..#...
+............
+...#..#..#..
+
+
+ +In this region, the number of empty ground tiles is 110. + +Simulate the Elves' process and find the smallest rectangle that contains the Elves after 10 rounds. How many empty ground tiles does that rectangle contain? + + +## --- Part Two --- +It seems you're on the right track. Finish simulating the process and figure out where the Elves need to go. How many rounds did you save them? + +In the example above, the first round where no Elf moved was round 20: + +
+.......#......
+....#......#..
+..#.....#.....
+......#.......
+...#....#.#..#
+#.............
+....#.....#...
+..#.....#.....
+....#.#....#..
+.........#....
+....#......#..
+.......#......
+
+
+ +Figure out where the Elves need to go. What is the number of the first round where no Elf moves? + + diff --git a/2022/Day23/input.in b/2022/Day23/input.in index d3a51ed87..0a173b3cb 100644 Binary files a/2022/Day23/input.in and b/2022/Day23/input.in differ diff --git a/2022/Day24/README.md b/2022/Day24/README.md index 9f6df318c..094e6b748 100644 --- a/2022/Day24/README.md +++ b/2022/Day24/README.md @@ -1,6 +1,278 @@ +original source: [https://adventofcode.com/2022/day/24](https://adventofcode.com/2022/day/24) ## --- Day 24: Blizzard Basin --- With everything replanted for next year (and with elephants and monkeys to tend the grove), you and the Elves leave for the extraction point. Partway up the mountain that shields the grove is a flat, open area that serves as the extraction point. It's a bit of a climb, but nothing the expedition can't handle. -Read the [full puzzle](https://adventofcode.com/2022/day/24). \ No newline at end of file +At least, that would normally be true; now that the mountain is covered in snow, things have become more difficult than the Elves are used to. + +As the expedition reaches a valley that must be traversed to reach the extraction site, you find that strong, turbulent winds are pushing small blizzards of snow and sharp ice around the valley. It's a good thing everyone packed warm clothes! To make it across safely, you'll need to find a way to avoid them. + +Fortunately, it's easy to see all of this from the entrance to the valley, so you make a map of the valley and the blizzards (your puzzle input). For example: + +
+#.#####
+#.....#
+#>....#
+#.....#
+#...v.#
+#.....#
+#####.#
+
+
+ +The walls of the valley are drawn as #; everything else is ground. Clear ground - where there is currently no blizzard - is drawn as .. Otherwise, blizzards are drawn with an arrow indicating their direction of motion: up (^), down (v), left (<), or right (>). + +The above map includes two blizzards, one moving right (>) and one moving down (v). In one minute, each blizzard moves one position in the direction it is pointing: + +
+#.#####
+#.....#
+#.>...#
+#.....#
+#.....#
+#...v.#
+#####.#
+
+
+ +Due to conservation of blizzard energy, as a blizzard reaches the wall of the valley, a new blizzard forms on the opposite side of the valley moving in the same direction. After another minute, the bottom downward-moving blizzard has been replaced with a new downward-moving blizzard at the top of the valley instead: + +
+#.#####
+#...v.#
+#..>..#
+#.....#
+#.....#
+#.....#
+#####.#
+
+
+ +Because blizzards are made of tiny snowflakes, they pass right through each other. After another minute, both blizzards temporarily occupy the same position, marked 2: + +
+#.#####
+#.....#
+#...2.#
+#.....#
+#.....#
+#.....#
+#####.#
+
+
+ +After another minute, the situation resolves itself, giving each blizzard back its personal space: + +
+#.#####
+#.....#
+#....>#
+#...v.#
+#.....#
+#.....#
+#####.#
+
+
+ +Finally, after yet another minute, the rightward-facing blizzard on the right is replaced with a new one on the left facing the same direction: + +
+#.#####
+#.....#
+#>....#
+#.....#
+#...v.#
+#.....#
+#####.#
+
+
+ +This process repeats at least as long as you are observing it, but probably forever. + +Here is a more complex example: + +
+#.######
+#>>.<^<#
+#.<..<<#
+#>v.><>#
+#<^v^^>#
+######.#
+
+
+ +Your expedition begins in the only non-wall position in the top row and needs to reach the only non-wall position in the bottom row. On each minute, you can move up, down, left, or right, or you can wait in place. You and the blizzards act simultaneously, and you cannot share a position with a blizzard. + +In the above example, the fastest way to reach your goal requires 18 steps. Drawing the position of the expedition as E, one way to achieve this is: + +
+Initial state:
+#E######
+#>>.<^<#
+#.<..<<#
+#>v.><>#
+#<^v^^>#
+######.#
+
+Minute 1, move down:
+#.######
+#E>3.<.#
+#<..<<.#
+#>2.22.#
+#>v..^<#
+######.#
+
+Minute 2, move down:
+#.######
+#.2>2..#
+#E^22^<#
+#.>2.^>#
+#.>..<.#
+######.#
+
+Minute 3, wait:
+#.######
+#<^<22.#
+#E2<.2.#
+#><2>..#
+#..><..#
+######.#
+
+Minute 4, move up:
+#.######
+#E<..22#
+#<<.<..#
+#<2.>>.#
+#.^22^.#
+######.#
+
+Minute 5, move right:
+#.######
+#2Ev.<>#
+#<.<..<#
+#.^>^22#
+#.2..2.#
+######.#
+
+Minute 6, move right:
+#.######
+#>2E<.<#
+#.2v^2<#
+#>..>2>#
+#<....>#
+######.#
+
+Minute 7, move down:
+#.######
+#.22^2.#
+#E<2.#
+#>>v<>.#
+#>....<#
+######.#
+
+Minute 8, move left:
+#.######
+#.<>2^.#
+#.E<<.<#
+#.22..>#
+#.2v^2.#
+######.#
+
+Minute 9, move up:
+#.######
+#<E2>>.#
+#.<<.<.#
+#>2>2^.#
+#.v><^.#
+######.#
+
+Minute 10, move right:
+#.######
+#.2E.>2#
+#<2v2^.#
+#<>.>2.#
+#..<>..#
+######.#
+
+Minute 11, wait:
+#.######
+#2^E^2>#
+#2#
+#.<..>.#
+######.#
+
+Minute 12, move down:
+#.######
+#>>.<^<#
+#.<E.<<#
+#>v.><>#
+#<^v^^>#
+######.#
+
+Minute 13, move down:
+#.######
+#.>3.<.#
+#<..<<.#
+#>2E22.#
+#>v..^<#
+######.#
+
+Minute 14, move right:
+#.######
+#.2>2..#
+#.^22^<#
+#.>2E^>#
+#.>..<.#
+######.#
+
+Minute 15, move right:
+#.######
+#<^<22.#
+#.2<.2.#
+#><2>E.#
+#..><..#
+######.#
+
+Minute 16, move right:
+#.######
+#.<..22#
+#<<.<..#
+#<2.>>E#
+#.^22^.#
+######.#
+
+Minute 17, move down:
+#.######
+#2.v.<>#
+#<.<..<#
+#.^>^22#
+#.2..2E#
+######.#
+
+Minute 18, move down:
+#.######
+#>2.<.<#
+#.2v^2<#
+#>..>2>#
+#<....>#
+######E#
+
+
+ +What is the fewest number of minutes required to avoid the blizzards and reach the goal? + + +## --- Part Two --- +As the expedition reaches the far side of the valley, one of the Elves looks especially dismayed: + +He forgot his snacks at the entrance to the valley! + +Since you're so good at dodging blizzards, the Elves humbly request that you go back for his snacks. From the same initial conditions, how quickly can you make it from the start to the goal, then back to the start, then back to the goal? + +In the above example, the first trip to the goal takes 18 minutes, the trip back to the start takes 23 minutes, and the trip back to the goal again takes 13 minutes, for a total time of 54 minutes. + +What is the fewest number of minutes required to reach the goal, go back to the start, then reach the goal again? + + diff --git a/2022/Day24/input.in b/2022/Day24/input.in index def762768..16086a253 100644 Binary files a/2022/Day24/input.in and b/2022/Day24/input.in differ diff --git a/2022/Day25/README.md b/2022/Day25/README.md index 72f7a26e8..040b57fed 100644 --- a/2022/Day25/README.md +++ b/2022/Day25/README.md @@ -1,6 +1,118 @@ +original source: [https://adventofcode.com/2022/day/25](https://adventofcode.com/2022/day/25) ## --- Day 25: Full of Hot Air --- As the expedition finally reaches the extraction point, several large [hot air balloons](https://en.wikipedia.org/wiki/Hot_air_balloon) drift down to meet you. Crews quickly start unloading the equipment the balloons brought: many hot air balloon kits, some fuel tanks, and a fuel heating machine. The fuel heating machine is a new addition to the process. When this mountain was a volcano, the ambient temperature was more reasonable; now, it's so cold that the fuel won't work at all without being warmed up first. -Read the [full puzzle](https://adventofcode.com/2022/day/25). \ No newline at end of file +The Elves, seemingly in an attempt to make the new machine feel welcome, have already attached a pair of [googly eyes](https://en.wikipedia.org/wiki/Googly_eyes) and started calling it "Bob". + +To heat the fuel, Bob needs to know the total amount of fuel that will be processed ahead of time so it can correctly calibrate heat output and flow rate. This amount is simply the sum of the fuel requirements of all of the hot air balloons, and those fuel requirements are even listed clearly on the side of each hot air balloon's burner. + +You assume the Elves will have no trouble adding up some numbers and are about to go back to figuring out which balloon is yours when you get a tap on the shoulder. Apparently, the fuel requirements use numbers written in a format the Elves don't recognize; predictably, they'd like your help deciphering them. + +You make a list of all of the fuel requirements (your puzzle input), but you don't recognize the number format either. For example: + +
+1=-0-2
+12111
+2=0=
+21
+2=01
+111
+20012
+112
+1=-1=
+1-12
+12
+1=
+122
+
+
+ +Fortunately, Bob is labeled with a support phone number. Not to be deterred, you call and ask for help. + +"That's right, just supply the fuel amount to the-- oh, for more than one burner? No problem, you just need to add together our Special Numeral-Analogue Fuel Units. Patent pending! They're way better than normal numbers for--" + +You mention that it's quite cold up here and ask if they can skip ahead. + +"Okay, our Special Numeral-Analogue Fuel Units - SNAFU for short - are sort of like normal numbers. You know how starting on the right, normal numbers have a ones place, a tens place, a hundreds place, and so on, where the digit in each place tells you how many of that value you have?" + +"SNAFU works the same way, except it uses powers of five instead of ten. Starting from the right, you have a ones place, a fives place, a twenty-fives place, a one-hundred-and-twenty-fives place, and so on. It's that easy!" + +You ask why some of the digits look like - or = instead of "digits". + +"You know, I never did ask the engineers why they did that. Instead of using digits four through zero, the digits are 2, 1, 0, minus (written -), and double-minus (written =). Minus is worth -1, and double-minus is worth -2." + +"So, because ten (in normal numbers) is two fives and no ones, in SNAFU it is written 20. Since eight (in normal numbers) is two fives minus two ones, it is written 2=." + +"You can do it the other direction, too. Say you have the SNAFU number 2=-01. That's 2 in the 625s place, = (double-minus) in the 125s place, - (minus) in the 25s place, 0 in the 5s place, and 1 in the 1s place. (2 times 625) plus (-2 times 125) plus (-1 times 25) plus (0 times 5) plus (1 times 1). That's 1250 plus -250 plus -25 plus 0 plus 1. 976!" + +"I see here that you're connected via our premium uplink service, so I'll transmit our handy SNAFU brochure to you now. Did you need anything else?" + +You ask if the fuel will even work in these temperatures. + +"Wait, it's how cold? There's no way the fuel - or any fuel - would work in those conditions! There are only a few places in the-- where did you say you are again?" + +Just then, you notice one of the Elves pour a few drops from a snowflake-shaped container into one of the fuel tanks, thank the support representative for their time, and disconnect the call. + +The SNAFU brochure contains a few more examples of decimal ("normal") numbers and their SNAFU counterparts: + +
+  Decimal          SNAFU
+        1              1
+        2              2
+        3             1=
+        4             1-
+        5             10
+        6             11
+        7             12
+        8             2=
+        9             2-
+       10             20
+       15            1=0
+       20            1-0
+     2022         1=11-2
+    12345        1-0---0
+314159265  1121-1110-1=0
+
+
+ +Based on this process, the SNAFU numbers in the example above can be converted to decimal numbers as follows: + +
+ SNAFU  Decimal
+1=-0-2     1747
+ 12111      906
+  2=0=      198
+    21       11
+  2=01      201
+   111       31
+ 20012     1257
+   112       32
+ 1=-1=      353
+  1-12      107
+    12        7
+    1=        3
+   122       37
+
+
+ +In decimal, the sum of these numbers is 4890. + +As you go to input this number on Bob's console, you discover that some buttons you expected are missing. Instead, you are met with buttons labeled =, -, 0, 1, and 2. Bob needs the input value expressed as a SNAFU number, not in decimal. + +Reversing the process, you can determine that for the decimal number 4890, the SNAFU number you need to supply to Bob's console is 2=-1=0. + +The Elves are starting to get cold. What SNAFU number do you supply to Bob's console? + + +## --- Part Two --- +The hot air balloons quickly carry you to the North Pole. As soon as you land, most of the expedition is escorted directly to a small building attached to the reindeer stables. + +The head smoothie chef has just finished warming up the industrial-grade smoothie blender as you arrive. It will take 50 stars to fill the blender. The expedition Elves turn their attention to you, and you begin emptying the fruit from your pack onto the table. + +As you do, a very young Elf - one you recognize from the expedition team - approaches the table and holds up a single star fruit he found. The head smoothie chef places it in the blender. + +Only 49 stars to go. + + diff --git a/2022/Day25/Solution.cs b/2022/Day25/Solution.cs index dee3f9749..ed08a1d46 100644 --- a/2022/Day25/Solution.cs +++ b/2022/Day25/Solution.cs @@ -15,7 +15,7 @@ public object PartOne(string input) => ); // This is just string to number conversion in base 5 - // with the two special digits that's worth -2 and -1. + // with the two special digits that worth -2 and -1. long SnafuToLong(string snafu) { long res = 0L; foreach (var digit in snafu) { diff --git a/2022/Day25/input.in b/2022/Day25/input.in index 5aea1b822..ba52ef9ff 100644 Binary files a/2022/Day25/input.in and b/2022/Day25/input.in differ diff --git a/2022/README.md b/2022/README.md index d43fe552e..c5f2bc5cb 100644 --- a/2022/README.md +++ b/2022/README.md @@ -1,4 +1,6 @@ + # Advent of Code (2022) Check out https://adventofcode.com/2022. + diff --git a/2022/SplashScreen.cs b/2022/SplashScreen.cs index 115bf10cc..0f4a54a0a 100644 --- a/2022/SplashScreen.cs +++ b/2022/SplashScreen.cs @@ -1,3 +1,4 @@ + using System; namespace AdventOfCode.Y2022; @@ -8,8 +9,8 @@ public void Show() { var color = Console.ForegroundColor; Write(0xcc00, false, " ▄█▄ ▄▄█ ▄ ▄ ▄▄▄ ▄▄ ▄█▄ ▄▄▄ ▄█ ▄▄ ▄▄▄ ▄▄█ ▄▄▄\n █▄█ █ █ █ █ █▄█ █ █ █ █ █ █▄ "); - Write(0xcc00, false, " █ █ █ █ █ █▄█\n █ █ █▄█ ▀▄▀ █▄▄ █ █ █▄ █▄█ █ █▄ █▄█ █▄█ █▄▄ $year = 2022\n "); - Write(0xcc00, false, "\n "); + Write(0xcc00, false, " █ █ █ █ █ █▄█\n █ █ █▄█ ▀▄▀ █▄▄ █ █ █▄ █▄█ █ █▄ █▄█ █▄█ █▄▄ int y = 2022;\n "); + Write(0xcc00, false, " \n "); Write(0x630031, false, " - "); Write(0xffffff, false, "/\\"); Write(0x630031, false, " - - - - - - - \n "); @@ -25,431 +26,424 @@ public void Show() { Write(0xcccccc, false, "25 "); Write(0xffff66, false, "**\n "); Write(0xaaaaaa, false, "/"); - Write(0x7fbd39, false, "@"); - Write(0x488813, false, "#"); + Write(0x7fbd39, false, "@@"); Write(0xaaaaaa, false, "\\ /\\"); - Write(0x488813, false, "@"); + Write(0x4d8b03, false, "#"); Write(0xaaaaaa, false, "\\"); + Write(0x427322, false, "#@"); + Write(0x488813, false, "@"); Write(0x7fbd39, false, "@"); Write(0x4d8b03, false, "@"); - Write(0x7fbd39, false, "@"); - Write(0x427322, false, "#"); + Write(0x427322, false, "@"); + Write(0x1461f, false, "@"); Write(0x4d8b03, false, "@"); - Write(0x488813, false, "@@##"); Write(0x7fbd39, false, "#"); + Write(0x488813, false, "@"); + Write(0x4d8b03, false, "#"); Write(0x427322, false, "@"); - Write(0x7fbd39, false, "#"); + Write(0x7fbd39, false, "##@"); + Write(0x1461f, false, "@"); + Write(0x427322, false, "@@"); Write(0x488813, false, "@"); + Write(0x427322, false, "@"); Write(0x7fbd39, false, "@"); - Write(0x4d8b03, false, "@"); - Write(0x488813, false, "#"); - Write(0x427322, false, "#"); + Write(0x488813, false, "@"); Write(0x7fbd39, false, "#"); - Write(0x1461f, false, "@"); + Write(0x488813, false, "@@#@"); Write(0x427322, false, "#"); - Write(0x488813, false, "#"); - Write(0x7fbd39, false, "#"); - Write(0x4d8b03, false, "#"); - Write(0x427322, false, "@"); - Write(0x4d8b03, false, "@"); - Write(0x1461f, false, "#"); - Write(0x4d8b03, false, "@@"); + Write(0x488813, false, "@@"); + Write(0x1461f, false, "@"); + Write(0x488813, false, "@@"); Write(0x427322, false, "@"); - Write(0x1461f, false, "@#"); Write(0x4d8b03, false, "@"); - Write(0x1461f, false, "@"); - Write(0x4d8b03, false, "#@"); - Write(0x488813, false, "##"); - Write(0x1461f, false, "@ "); + Write(0x488813, false, "#"); + Write(0x4d8b03, false, "## "); Write(0xcccccc, false, "24 "); Write(0xffff66, false, "**\n "); - Write(0x1461f, false, "@"); - Write(0x4d8b03, false, "@"); + Write(0x488813, false, "@#"); + Write(0x7fbd39, false, "@."); + Write(0x1461f, false, "' "); + Write(0x4d8b03, false, "'"); + Write(0x7fbd39, false, "."); + Write(0x427322, false, "#"); Write(0x488813, false, "@"); - Write(0x4d8b03, false, "."); - Write(0x427322, false, "'"); - Write(0x7fbd39, false, " '."); - Write(0x1461f, false, "@"); - Write(0x7fbd39, false, "@"); - Write(0x488813, false, "#"); + Write(0x427322, false, "#"); Write(0x7fbd39, false, "@"); + Write(0x427322, false, "#"); + Write(0x4d8b03, false, "@"); + Write(0x427322, false, "#"); + Write(0x488813, false, "@"); + Write(0x7fbd39, false, "@#"); + Write(0x488813, false, "@@"); Write(0x427322, false, "@"); - Write(0x7fbd39, false, "@"); + Write(0x4d8b03, false, "@"); Write(0x427322, false, "@"); - Write(0x488813, false, "##@"); - Write(0x7fbd39, false, "@"); - Write(0x1461f, false, "@"); - Write(0x488813, false, "#"); + Write(0x488813, false, "@"); Write(0x4d8b03, false, "@"); - Write(0x488813, false, "#"); Write(0x427322, false, "@"); + Write(0x488813, false, "#"); + Write(0x427322, false, "#"); + Write(0x488813, false, "@"); + Write(0x7fbd39, false, "#@#"); + Write(0x488813, false, "@"); Write(0x1461f, false, "@"); - Write(0x4d8b03, false, "@"); Write(0x7fbd39, false, "#"); - Write(0x488813, false, "@"); Write(0x427322, false, "@"); - Write(0x4d8b03, false, "#"); - Write(0x427322, false, "@@@"); + Write(0x488813, false, "@"); + Write(0x7fbd39, false, "@@"); Write(0x4d8b03, false, "@"); - Write(0x7fbd39, false, "@"); Write(0x427322, false, "#"); - Write(0x488813, false, "@"); - Write(0x4d8b03, false, "#"); Write(0x7fbd39, false, "@"); - Write(0x1461f, false, "@"); - Write(0x4d8b03, false, "@"); - Write(0x488813, false, "@"); - Write(0x4d8b03, false, "#"); - Write(0x488813, false, "##@"); - Write(0x427322, false, "@"); - Write(0x7fbd39, false, "#"); - Write(0x427322, false, "@ "); + Write(0x427322, false, "##"); + Write(0x4d8b03, false, "@@@"); + Write(0x427322, false, "@# "); Write(0xcccccc, false, "23 "); Write(0xffff66, false, "**\n "); - Write(0x4d8b03, false, "@"); + Write(0x427322, false, "@@"); Write(0x488813, false, "@"); + Write(0x427322, false, "'"); + Write(0x488813, false, ". "); + Write(0x4d8b03, false, "."); + Write(0x427322, false, "'"); + Write(0x4d8b03, false, "#@"); Write(0x427322, false, "@"); - Write(0x7fbd39, false, "'. "); - Write(0x4d8b03, false, ".'"); - Write(0x1461f, false, "@"); - Write(0x427322, false, "@"); - Write(0x4d8b03, false, "@@"); + Write(0x1461f, false, "#"); Write(0xd0b376, false, "."); - Write(0x427322, false, "@"); - Write(0x7fbd39, false, "@"); - Write(0x1461f, false, "@"); - Write(0x488813, false, "@@"); - Write(0x7fbd39, false, "@"); - Write(0x4d8b03, false, "@"); - Write(0x7fbd39, false, "@#"); - Write(0x488813, false, "@"); + Write(0x1461f, false, "#"); + Write(0x427322, false, "#"); + Write(0x1461f, false, "#"); Write(0x4d8b03, false, "#"); + Write(0x1461f, false, "#"); + Write(0x4d8b03, false, "@"); Write(0x427322, false, "#"); Write(0x7fbd39, false, "#"); Write(0x1461f, false, "@"); Write(0x4d8b03, false, "@"); - Write(0x427322, false, "@"); + Write(0x488813, false, "@"); + Write(0x4d8b03, false, "#@"); Write(0x7fbd39, false, "@"); - Write(0x488813, false, "@@"); - Write(0x4d8b03, false, "@"); - Write(0x427322, false, "#"); Write(0x4d8b03, false, "@"); + Write(0x427322, false, "@#"); Write(0x488813, false, "@"); - Write(0x4d8b03, false, "#"); - Write(0x488813, false, "@#"); - Write(0x4d8b03, false, "@@"); - Write(0xffffff, false, "()))"); - Write(0x7fbd39, false, "@"); + Write(0x1461f, false, "#"); + Write(0x4d8b03, false, "@"); + Write(0x427322, false, "@@"); + Write(0x7fbd39, false, "#"); + Write(0x1461f, false, "@"); + Write(0x488813, false, "#"); Write(0x427322, false, "@"); + Write(0x7fbd39, false, "@"); + Write(0x1461f, false, "@"); + Write(0xffffff, false, "()))"); + Write(0x427322, false, "@@"); Write(0x7fbd39, false, "#"); - Write(0x4d8b03, false, "@ "); + Write(0x488813, false, "@ "); Write(0xcccccc, false, "22 "); Write(0xffff66, false, "**\n "); - Write(0x4d8b03, false, "@"); - Write(0x488813, false, "@@"); + Write(0x488813, false, "@#"); + Write(0x427322, false, "@@"); + Write(0x488813, false, "@"); Write(0x7fbd39, false, "@"); - Write(0x427322, false, "@"); + Write(0x4d8b03, false, "#"); + Write(0x1461f, false, "@"); + Write(0x7fbd39, false, "#"); + Write(0x488813, false, "#"); Write(0x7fbd39, false, "@"); - Write(0x427322, false, "#"); + Write(0x4d8b03, false, "#"); + Write(0x488813, false, "@"); + Write(0x1461f, false, "#"); + Write(0x488813, false, "#"); Write(0x7fbd39, false, "@"); Write(0x4d8b03, false, "@"); - Write(0x488813, false, "#"); - Write(0x427322, false, "@"); - Write(0x7fbd39, false, "#"); + Write(0x7fbd39, false, "@"); + Write(0xd0b376, false, "."); Write(0x488813, false, "@"); + Write(0x7fbd39, false, "@@"); + Write(0x427322, false, "@"); Write(0x7fbd39, false, "@"); Write(0x4d8b03, false, "@"); + Write(0x7fbd39, false, "#@"); Write(0x427322, false, "#"); - Write(0x1461f, false, "@"); - Write(0x4d8b03, false, "@"); - Write(0xd0b376, false, "."); Write(0x4d8b03, false, "@"); Write(0x7fbd39, false, "#"); - Write(0x488813, false, "#"); + Write(0x427322, false, "#"); Write(0x4d8b03, false, "#"); - Write(0x1461f, false, "#"); - Write(0x4d8b03, false, "@"); - Write(0x427322, false, "@"); - Write(0x7fbd39, false, "#"); + Write(0x427322, false, "#"); Write(0x4d8b03, false, "@"); - Write(0x427322, false, "@"); - Write(0x488813, false, "#"); - Write(0x7fbd39, false, "@"); Write(0x1461f, false, "#"); - Write(0x488813, false, "@"); - Write(0x427322, false, "#"); + Write(0x4d8b03, false, "@#"); Write(0x1461f, false, "@"); - Write(0x488813, false, "#"); + Write(0x488813, false, "#@"); + Write(0x4d8b03, false, "@"); Write(0x7fbd39, false, "#"); - Write(0x488813, false, "@@"); + Write(0x488813, false, "@##"); Write(0x427322, false, "#"); - Write(0x488813, false, "@"); - Write(0x427322, false, "@"); - Write(0x7fbd39, false, "##"); - Write(0x427322, false, "#"); - Write(0x7fbd39, false, "@"); - Write(0x685c46, false, "|"); - Write(0x7fbd39, false, "@"); - Write(0x427322, false, "# "); + Write(0x4d8b03, false, "@@"); + Write(0x7fbd39, false, "@ "); Write(0xcccccc, false, "21 "); Write(0xffff66, false, "**\n "); - Write(0x7fbd39, false, "@"); - Write(0x488813, false, "#"); - Write(0x427322, false, "@"); - Write(0x488813, false, "#"); - Write(0x7fbd39, false, "#"); - Write(0xd0b376, false, "."); + Write(0x7fbd39, false, "@@"); Write(0x427322, false, "@"); + Write(0x4d8b03, false, "@"); Write(0x488813, false, "@"); - Write(0x1461f, false, "@"); + Write(0xd0b376, false, "."); Write(0x488813, false, "@"); - Write(0x7fbd39, false, "#"); - Write(0x4d8b03, false, "@"); - Write(0x7fbd39, false, "#"); + Write(0x427322, false, "#"); Write(0x488813, false, "#"); - Write(0x427322, false, "#@"); - Write(0x7fbd39, false, "@"); - Write(0x427322, false, "@"); - Write(0x488813, false, "@"); - Write(0x4d8b03, false, "#"); Write(0x7fbd39, false, "@"); + Write(0x427322, false, "@@"); Write(0x4d8b03, false, "#"); - Write(0x7fbd39, false, "#"); + Write(0x427322, false, "@@"); Write(0x488813, false, "@"); + Write(0x1461f, false, "@"); + Write(0x488813, false, "@##"); + Write(0x427322, false, "#"); + Write(0x1461f, false, "@"); + Write(0x488813, false, "@"); + Write(0x7fbd39, false, "@"); Write(0xd0b376, false, "."); + Write(0x7fbd39, false, "#@"); Write(0x1461f, false, "#"); - Write(0x4d8b03, false, "#"); - Write(0x488813, false, "@"); Write(0x5eabb4, false, "~~"); - Write(0x488813, false, "@"); - Write(0x7fbd39, false, "@#"); - Write(0x1461f, false, "@"); Write(0x427322, false, "@"); - Write(0x1461f, false, "@"); - Write(0x488813, false, "#"); - Write(0x427322, false, "#@#"); - Write(0x488813, false, "#"); Write(0x1461f, false, "#"); - Write(0x7fbd39, false, "@"); - Write(0x427322, false, "@"); - Write(0x4d8b03, false, "#"); - Write(0x1461f, false, "@"); Write(0x4d8b03, false, "@"); - Write(0x488813, false, "@# "); - Write(0xcccccc, false, "20 "); - Write(0xffff66, false, "**\n "); - Write(0x488813, false, "@@"); + Write(0x427322, false, "#"); + Write(0x488813, false, "@"); Write(0x4d8b03, false, "@"); - Write(0x7fbd39, false, "#"); - Write(0x685c46, false, "|"); Write(0x7fbd39, false, "@"); - Write(0x488813, false, "@#"); - Write(0x427322, false, "@"); + Write(0x1461f, false, "@"); Write(0x7fbd39, false, "@"); + Write(0x488813, false, "#"); Write(0x4d8b03, false, "#"); + Write(0x1461f, false, "@"); + Write(0x488813, false, "#"); Write(0x427322, false, "@"); + Write(0x1461f, false, "##"); + Write(0x427322, false, "#"); Write(0x488813, false, "#"); - Write(0x5eabb4, false, "."); + Write(0x7fbd39, false, "@ "); + Write(0xcccccc, false, "20 "); + Write(0xffff66, false, "**\n "); Write(0x427322, false, "@"); - Write(0x488813, false, "@"); - Write(0x7fbd39, false, "#"); + Write(0x7fbd39, false, "@"); + Write(0x1461f, false, "#@"); + Write(0x4d8b03, false, "@"); + Write(0x488813, false, "#"); Write(0x4d8b03, false, "@"); Write(0x7fbd39, false, "@"); - Write(0x427322, false, "@@#"); + Write(0x427322, false, "##"); Write(0x488813, false, "@"); Write(0x7fbd39, false, "@"); + Write(0x427322, false, "@"); + Write(0x5eabb4, false, "."); + Write(0x1461f, false, "#"); Write(0x4d8b03, false, "@"); - Write(0x1461f, false, "@@"); - Write(0x5eabb4, false, "~~~~ "); - Write(0xaaaaaa, false, ".~'"); - Write(0x7fbd39, false, "#"); + Write(0x488813, false, "@@"); Write(0x4d8b03, false, "#"); Write(0x7fbd39, false, "@"); - Write(0x1461f, false, "@"); Write(0x488813, false, "@"); - Write(0x7fbd39, false, "#@"); - Write(0x4d8b03, false, "#@#"); - Write(0x488813, false, "@@"); - Write(0x1461f, false, "#"); - Write(0x427322, false, "@ "); - Write(0xcccccc, false, "19 "); - Write(0xffff66, false, "**\n "); - Write(0x4d8b03, false, "@"); - Write(0x427322, false, "#"); - Write(0x7fbd39, false, "@@"); - Write(0x4d8b03, false, "#"); Write(0x427322, false, "@"); Write(0x488813, false, "@"); + Write(0x7fbd39, false, "#"); + Write(0x488813, false, "@@"); + Write(0x7fbd39, false, "@"); + Write(0x5eabb4, false, "~~~~ "); + Write(0xaaaaaa, false, ".~'"); + Write(0x427322, false, "#"); + Write(0x7fbd39, false, "@"); Write(0x4d8b03, false, "@"); - Write(0x7fbd39, false, "@@"); + Write(0x427322, false, "@"); Write(0x488813, false, "#"); - Write(0x4d8b03, false, "#"); + Write(0x4d8b03, false, "@"); + Write(0x1461f, false, "@"); Write(0x7fbd39, false, "@"); - Write(0x427322, false, "@"); - Write(0x5eabb4, false, "."); - Write(0x4d8b03, false, "@@"); + Write(0x427322, false, "#"); + Write(0x4d8b03, false, "@"); + Write(0x7fbd39, false, "@"); + Write(0x4d8b03, false, "@"); Write(0x7fbd39, false, "@"); + Write(0x4d8b03, false, "@ "); + Write(0xcccccc, false, "19 "); + Write(0xffff66, false, "**\n "); + Write(0x4d8b03, false, "@"); + Write(0x427322, false, "##"); Write(0x488813, false, "#"); Write(0x427322, false, "@"); Write(0x488813, false, "@"); - Write(0x7fbd39, false, "@#"); - Write(0x427322, false, "@@@"); + Write(0x7fbd39, false, "#@"); + Write(0x488813, false, "#"); + Write(0x1461f, false, "#"); + Write(0x427322, false, "@"); + Write(0x4d8b03, false, "@@#"); + Write(0x5eabb4, false, "."); + Write(0x7fbd39, false, "#"); + Write(0x488813, false, "@"); + Write(0x427322, false, "@"); + Write(0x4d8b03, false, "#"); + Write(0x427322, false, "@"); + Write(0x7fbd39, false, "#"); + Write(0x4d8b03, false, "#@"); + Write(0x7fbd39, false, "#"); + Write(0x427322, false, "@"); Write(0x4d8b03, false, "@"); - Write(0x7fbd39, false, "@"); + Write(0x427322, false, "#@"); Write(0x5eabb4, false, "~~ "); Write(0xaaaaaa, false, "/"); Write(0xe6410b, false, "~"); Write(0xaaaaaa, false, "\\ "); - Write(0x488813, false, "@@"); - Write(0x7fbd39, false, "@"); + Write(0x488813, false, "#"); + Write(0x7fbd39, false, "#"); + Write(0x427322, false, "@"); + Write(0x7fbd39, false, "@@"); + Write(0x427322, false, "@"); + Write(0x4d8b03, false, "@"); + Write(0x488813, false, "@"); + Write(0x427322, false, "#"); + Write(0x488813, false, "#@"); Write(0x427322, false, "@"); Write(0x488813, false, "#"); - Write(0x7fbd39, false, "@"); - Write(0x488813, false, "#@@"); - Write(0x7fbd39, false, "@#"); - Write(0x427322, false, "@#@ "); + Write(0x4d8b03, false, "@ "); Write(0xcccccc, false, "18 "); Write(0xffff66, false, "**\n "); - Write(0x7fbd39, false, "#@"); - Write(0x4d8b03, false, "@"); + Write(0x427322, false, "@@"); + Write(0x4d8b03, false, "#"); Write(0x7fbd39, false, "#"); Write(0xd0b376, false, "."); - Write(0x1461f, false, "#"); - Write(0x427322, false, "@"); - Write(0x488813, false, "@"); - Write(0x7fbd39, false, "@"); - Write(0x488813, false, "@"); - Write(0x4d8b03, false, "#"); - Write(0x488813, false, "@"); - Write(0x427322, false, "@"); Write(0x4d8b03, false, "@"); + Write(0x427322, false, "#"); + Write(0x7fbd39, false, "@"); + Write(0x1461f, false, "#@"); Write(0x427322, false, "@"); + Write(0x1461f, false, "@"); + Write(0x488813, false, "#@"); + Write(0x7fbd39, false, "@"); Write(0x5eabb4, false, ".."); - Write(0x4d8b03, false, "@@"); - Write(0x7fbd39, false, "#@"); Write(0x488813, false, "#"); - Write(0x7fbd39, false, "#"); Write(0x427322, false, "#"); - Write(0x488813, false, "@"); Write(0x4d8b03, false, "@"); Write(0x7fbd39, false, "#"); - Write(0x427322, false, "@"); - Write(0x488813, false, "@ "); + Write(0x488813, false, "@"); + Write(0x7fbd39, false, "@"); + Write(0x427322, false, "#"); + Write(0x1461f, false, "#"); + Write(0x7fbd39, false, "@"); + Write(0x488813, false, "#"); + Write(0x4d8b03, false, "@"); + Write(0x488813, false, "# "); Write(0xaaaaaa, false, "/ "); Write(0xe6410b, false, "/ "); Write(0xaaaaaa, false, "\\ "); - Write(0x4d8b03, false, "#"); - Write(0x7fbd39, false, "#"); - Write(0x488813, false, "@"); - Write(0x427322, false, "@"); + Write(0x7fbd39, false, "@"); Write(0x4d8b03, false, "@"); + Write(0x427322, false, "@"); + Write(0x7fbd39, false, "@"); + Write(0x1461f, false, "@"); + Write(0x7fbd39, false, "@"); + Write(0x4d8b03, false, "@#"); Write(0x488813, false, "#"); - Write(0x1461f, false, "#@"); - Write(0x4d8b03, false, "@"); - Write(0x488813, false, "@"); - Write(0x4d8b03, false, "@@# "); + Write(0x427322, false, "#"); + Write(0x7fbd39, false, "@"); + Write(0x427322, false, "@# "); Write(0xcccccc, false, "17 "); Write(0xffff66, false, "**\n "); - Write(0x427322, false, "@"); - Write(0x7fbd39, false, "#"); + Write(0x427322, false, "#"); Write(0x488813, false, "#"); + Write(0x427322, false, "@"); + Write(0x7fbd39, false, "@@"); Write(0x4d8b03, false, "@"); - Write(0x7fbd39, false, "@#"); - Write(0x488813, false, "@"); - Write(0x7fbd39, false, "@@@@"); - Write(0x4d8b03, false, "#"); Write(0x7fbd39, false, "@"); Write(0x427322, false, "@"); + Write(0x7fbd39, false, "#@"); + Write(0x488813, false, "#@"); + Write(0x427322, false, "@"); Write(0x4d8b03, false, "@"); + Write(0x1461f, false, "#"); Write(0x7fbd39, false, "@"); Write(0x5eabb4, false, ".."); - Write(0x488813, false, "#"); Write(0x4d8b03, false, "@"); - Write(0x1461f, false, "#"); - Write(0x4d8b03, false, "@@"); - Write(0x427322, false, "@"); - Write(0x1461f, false, "@"); + Write(0x7fbd39, false, "@"); Write(0x488813, false, "@"); + Write(0x7fbd39, false, "@"); + Write(0x4d8b03, false, "##"); + Write(0x7fbd39, false, "@"); + Write(0x488813, false, "#"); + Write(0x1461f, false, "@"); Write(0x427322, false, "@"); - Write(0x4d8b03, false, "#"); - Write(0x488813, false, "@"); + Write(0x4d8b03, false, "@"); Write(0xaaaaaa, false, "/ "); Write(0xe6410b, false, "/ \\ "); Write(0xaaaaaa, false, "\\"); Write(0x427322, false, "@"); - Write(0x7fbd39, false, "@@"); - Write(0x427322, false, "@"); - Write(0x7fbd39, false, "@"); - Write(0x488813, false, "@"); - Write(0x7fbd39, false, "#"); - Write(0x427322, false, "#"); - Write(0x7fbd39, false, "#"); - Write(0x427322, false, "@"); Write(0x4d8b03, false, "@"); - Write(0x1461f, false, "@"); - Write(0x4d8b03, false, "@ "); - Write(0xcccccc, false, "16 "); - Write(0xffff66, false, "**\n "); - Write(0x488813, false, "#"); - Write(0x7fbd39, false, "#"); + Write(0x427322, false, "#"); Write(0x4d8b03, false, "#"); + Write(0x427322, false, "@@"); + Write(0x1461f, false, "@@"); Write(0x488813, false, "@"); - Write(0x7fbd39, false, "#"); - Write(0x4d8b03, false, "@"); Write(0x427322, false, "@@"); + Write(0x1461f, false, "#"); + Write(0x427322, false, "# "); + Write(0xcccccc, false, "16 "); + Write(0xffff66, false, "**\n "); Write(0x488813, false, "@"); - Write(0x4d8b03, false, "@"); - Write(0x488813, false, "#"); + Write(0x7fbd39, false, "@"); + Write(0x427322, false, "#"); Write(0x7fbd39, false, "#"); - Write(0x488813, false, "#"); + Write(0x427322, false, "@"); + Write(0x4d8b03, false, "@"); + Write(0x427322, false, "#"); Write(0x7fbd39, false, "@"); + Write(0x488813, false, "@"); + Write(0x427322, false, "@#"); Write(0x1461f, false, "@"); - Write(0x4d8b03, false, "_"); - Write(0x5eabb4, false, ".~."); - Write(0x427322, false, "_"); - Write(0x7fbd39, false, "@"); + Write(0x7fbd39, false, "#@"); Write(0x488813, false, "#"); + Write(0x427322, false, "_"); + Write(0x5eabb4, false, ".~."); + Write(0x4d8b03, false, "_"); Write(0x427322, false, "@"); - Write(0x4d8b03, false, "@"); - Write(0x488813, false, "#"); Write(0x4d8b03, false, "#"); - Write(0x7fbd39, false, "@#"); + Write(0x1461f, false, "@"); + Write(0x4d8b03, false, "@"); + Write(0x1461f, false, "@"); + Write(0x7fbd39, false, "#"); + Write(0x4d8b03, false, "@"); + Write(0x427322, false, "@"); Write(0xaaaaaa, false, ".'"); Write(0xe6410b, false, "/\\"); Write(0xaaaaaa, false, ".'"); Write(0xe6410b, false, "~"); Write(0xaaaaaa, false, ". "); - Write(0x488813, false, "@"); - Write(0x4d8b03, false, "@"); - Write(0x427322, false, "@"); - Write(0x488813, false, "@"); - Write(0x4d8b03, false, "@@"); - Write(0x488813, false, "@"); - Write(0x7fbd39, false, "@"); - Write(0x427322, false, "@"); - Write(0x4d8b03, false, "@@# "); + Write(0x488813, false, "#"); + Write(0x427322, false, "@@"); + Write(0x7fbd39, false, "#@"); + Write(0x1461f, false, "#"); + Write(0x7fbd39, false, "##"); + Write(0x427322, false, "###"); + Write(0x1461f, false, "@ "); Write(0xcccccc, false, "15 "); Write(0xffff66, false, "**\n "); - Write(0x4d8b03, false, "@@"); - Write(0x488813, false, "@"); + Write(0x427322, false, "#@"); + Write(0x7fbd39, false, "@"); Write(0xd0b376, false, "."); + Write(0x4d8b03, false, "@"); + Write(0x427322, false, "#"); Write(0x1461f, false, "@"); - Write(0x7fbd39, false, "@"); - Write(0x488813, false, "@"); - Write(0x7fbd39, false, "@"); - Write(0x427322, false, "@"); + Write(0x4d8b03, false, "@"); Write(0x488813, false, "@"); Write(0x427322, false, "@"); - Write(0x1461f, false, "#"); Write(0x488813, false, "#"); - Write(0x4d8b03, false, "#"); - Write(0x1461f, false, "@ "); + Write(0x7fbd39, false, "#"); + Write(0x488813, false, "#"); + Write(0x427322, false, "@@ "); Write(0xffffff, false, "||| "); Write(0x7fbd39, false, "@"); - Write(0x4d8b03, false, "#@"); - Write(0x488813, false, "@#"); - Write(0x4d8b03, false, "@"); Write(0x427322, false, "@"); + Write(0x685c46, false, "|"); + Write(0x488813, false, "@"); + Write(0x427322, false, "@@"); + Write(0x7fbd39, false, "@"); Write(0xaaaaaa, false, "'."); Write(0xe6410b, false, "~"); Write(0xaaaaaa, false, ".'"); @@ -457,205 +451,201 @@ public void Show() { Write(0xaaaaaa, false, ". "); Write(0xe6410b, false, "\\"); Write(0xaaaaaa, false, "'."); - Write(0x427322, false, "@"); - Write(0x7fbd39, false, "@"); + Write(0x488813, false, "@@#"); Write(0x427322, false, "#"); Write(0x4d8b03, false, "#"); Write(0x7fbd39, false, "@"); - Write(0x1461f, false, "@"); - Write(0x427322, false, "#"); - Write(0x488813, false, "@"); Write(0x427322, false, "@"); - Write(0x488813, false, "#"); - Write(0x7fbd39, false, "# "); + Write(0x1461f, false, "@@@"); + Write(0x4d8b03, false, "@ "); Write(0xcccccc, false, "14 "); Write(0xffff66, false, "**\n "); - Write(0x4d8b03, false, "@"); + Write(0x7fbd39, false, "@@"); + Write(0x488813, false, "@"); Write(0x7fbd39, false, "@"); Write(0x427322, false, "@"); - Write(0x4d8b03, false, "@"); - Write(0x1461f, false, "@"); + Write(0x488813, false, "@"); + Write(0x4d8b03, false, "##"); + Write(0x488813, false, "@"); Write(0x7fbd39, false, "@"); - Write(0x1461f, false, "@#"); - Write(0x4d8b03, false, "@"); Write(0x488813, false, "#"); - Write(0x1461f, false, "@"); - Write(0x427322, false, "@@"); - Write(0x488813, false, "@"); + Write(0x7fbd39, false, "@"); + Write(0x4d8b03, false, "@@"); + Write(0x7fbd39, false, "#"); Write(0x4d8b03, false, "@"); - Write(0x1461f, false, "#"); Write(0xffffff, false, "~~~"); - Write(0x1461f, false, "#"); - Write(0x427322, false, "@"); + Write(0x7fbd39, false, "@"); + Write(0x427322, false, "##"); + Write(0x488813, false, "@"); + Write(0x685c46, false, "|"); + Write(0x427322, false, "@@"); Write(0x488813, false, "@"); - Write(0x4d8b03, false, "@#"); - Write(0x488813, false, "#"); Write(0x427322, false, "@"); - Write(0x7fbd39, false, "#"); - Write(0x4d8b03, false, "@"); Write(0xaaaaaa, false, "' ..'.'."); Write(0xe6410b, false, "\\"); Write(0xaaaaaa, false, ". . "); - Write(0x7fbd39, false, "#"); + Write(0x7fbd39, false, "@"); + Write(0x488813, false, "@"); + Write(0x4d8b03, false, "@"); Write(0x427322, false, "@"); + Write(0x488813, false, "@"); Write(0x4d8b03, false, "@"); - Write(0x7fbd39, false, "#"); - Write(0x427322, false, "#"); - Write(0x4d8b03, false, "#"); - Write(0x7fbd39, false, "@@ "); + Write(0x7fbd39, false, "@"); + Write(0x488813, false, "@ "); Write(0xcccccc, false, "13 "); Write(0xffff66, false, "**\n "); - Write(0x427322, false, "@"); - Write(0x488813, false, "@"); - Write(0x427322, false, "@"); - Write(0x488813, false, "@"); Write(0x1461f, false, "@"); - Write(0x488813, false, "#@"); - Write(0x4d8b03, false, "@@@@"); - Write(0x488813, false, "@"); + Write(0x7fbd39, false, "@"); Write(0x1461f, false, "@"); + Write(0x7fbd39, false, "#"); + Write(0x4d8b03, false, "@@"); + Write(0x1461f, false, "@"); + Write(0x427322, false, "#"); + Write(0x4d8b03, false, "@"); + Write(0x427322, false, "@"); + Write(0x4d8b03, false, "#@"); Write(0x7fbd39, false, "@"); + Write(0x427322, false, "#"); Write(0x5eabb4, false, ".~~."); - Write(0x427322, false, "@"); - Write(0x488813, false, "#@"); - Write(0x1461f, false, "#"); - Write(0x7fbd39, false, "#"); + Write(0x4d8b03, false, "@"); + Write(0x7fbd39, false, "@"); + Write(0x488813, false, "@"); + Write(0x7fbd39, false, "@"); + Write(0x488813, false, "@"); + Write(0x4d8b03, false, "@"); + Write(0x427322, false, "#"); + Write(0x488813, false, "@"); + Write(0x4d8b03, false, "@"); Write(0x488813, false, "@"); Write(0x7fbd39, false, "#@"); - Write(0x4d8b03, false, "#"); + Write(0x4d8b03, false, "@"); Write(0x7fbd39, false, "#"); - Write(0x4d8b03, false, "##"); - Write(0x488813, false, "@"); - Write(0x7fbd39, false, "@"); Write(0x1461f, false, "@"); Write(0xaaaaaa, false, " .'."); Write(0xe6410b, false, "~~~"); Write(0xaaaaaa, false, "' "); - Write(0x7fbd39, false, "@"); + Write(0x488813, false, "@"); Write(0xaaaaaa, false, "'"); + Write(0x4d8b03, false, "@"); Write(0x1461f, false, "@"); - Write(0x4d8b03, false, "#"); - Write(0x427322, false, "@"); - Write(0x7fbd39, false, "#@ "); + Write(0x427322, false, "@#"); + Write(0x4d8b03, false, "# "); Write(0xcccccc, false, "12 "); Write(0xffff66, false, "**\n "); - Write(0x4d8b03, false, "#"); + Write(0x4d8b03, false, "@"); + Write(0x427322, false, "@@"); + Write(0xd0b376, false, "."); + Write(0x488813, false, "@"); + Write(0x427322, false, "@"); Write(0x7fbd39, false, "#"); + Write(0x488813, false, "@"); Write(0x1461f, false, "@"); - Write(0xd0b376, false, "."); + Write(0x427322, false, "@"); + Write(0x4d8b03, false, "#"); Write(0x7fbd39, false, "@"); - Write(0x427322, false, "#"); - Write(0x4d8b03, false, "@"); - Write(0x1461f, false, "@"); + Write(0x5eabb4, false, ".~~."); + Write(0x4d8b03, false, "@@"); + Write(0x488813, false, "@"); Write(0x7fbd39, false, "@"); - Write(0x1461f, false, "@"); + Write(0x488813, false, "#"); + Write(0x7fbd39, false, "#@"); Write(0x427322, false, "@"); Write(0x4d8b03, false, "@"); - Write(0x5eabb4, false, ".~~."); Write(0x7fbd39, false, "@"); - Write(0x427322, false, "@"); - Write(0x7fbd39, false, "@@"); - Write(0x427322, false, "#"); - Write(0x488813, false, "@"); + Write(0x4d8b03, false, "#"); Write(0x7fbd39, false, "@@"); - Write(0x427322, false, "##"); - Write(0x1461f, false, "@"); Write(0x4d8b03, false, "@"); Write(0x7fbd39, false, "#"); - Write(0x4d8b03, false, "#"); - Write(0x427322, false, "##"); - Write(0x4d8b03, false, "@"); - Write(0x7fbd39, false, "@ "); + Write(0x427322, false, "@"); + Write(0x7fbd39, false, "@@ "); Write(0xe6410b, false, "~~~~~"); Write(0xaaaaaa, false, ".."); - Write(0x7fbd39, false, "@"); - Write(0x4d8b03, false, "@"); - Write(0x427322, false, "##"); + Write(0x488813, false, "@"); Write(0x7fbd39, false, "#"); - Write(0x1461f, false, "# "); + Write(0x427322, false, "#"); + Write(0x7fbd39, false, "@"); + Write(0x427322, false, "@@ "); Write(0xcccccc, false, "11 "); Write(0xffff66, false, "**\n "); - Write(0x7fbd39, false, "##"); - Write(0x488813, false, "#"); + Write(0x4d8b03, false, "#"); + Write(0x7fbd39, false, "#@"); Write(0xd0b376, false, "."); - Write(0x1461f, false, "#"); - Write(0x4d8b03, false, "@"); - Write(0x427322, false, "@"); - Write(0x1461f, false, "@"); + Write(0x7fbd39, false, "#@@@@"); Write(0x427322, false, "@"); - Write(0x7fbd39, false, "@"); - Write(0x488813, false, "#"); + Write(0x4d8b03, false, "@"); Write(0x5eabb4, false, ".~~."); - Write(0x7fbd39, false, "@"); - Write(0x4d8b03, false, "@#"); - Write(0x427322, false, "#@"); - Write(0x488813, false, "##"); + Write(0x488813, false, "#@"); Write(0x427322, false, "@"); - Write(0x4d8b03, false, "@"); - Write(0x488813, false, "#"); - Write(0x427322, false, "#"); - Write(0x7fbd39, false, "@"); - Write(0x4d8b03, false, "#"); - Write(0x488813, false, "@@"); + Write(0x1461f, false, "#"); + Write(0x488813, false, "@"); + Write(0x1461f, false, "#"); Write(0x4d8b03, false, "#"); - Write(0x7fbd39, false, "@"); - Write(0x427322, false, "@"); + Write(0x1461f, false, "#"); + Write(0x488813, false, "@"); + Write(0x7fbd39, false, "#"); + Write(0x488813, false, "@"); + Write(0x4d8b03, false, "@"); + Write(0x488813, false, "@"); + Write(0x7fbd39, false, "#"); + Write(0x488813, false, "@"); + Write(0x7fbd39, false, "#"); + Write(0x427322, false, "@@"); Write(0xaaaaaa, false, ".'"); Write(0xe6410b, false, "/ ~~~ \\"); Write(0xaaaaaa, false, "' "); - Write(0x488813, false, "@#"); - Write(0x427322, false, "@"); Write(0x7fbd39, false, "@"); - Write(0x4d8b03, false, "@ "); + Write(0x4d8b03, false, "#"); + Write(0x427322, false, "@"); + Write(0x488813, false, "@# "); Write(0xcccccc, false, "10 "); Write(0xffff66, false, "**\n "); - Write(0x1461f, false, "@"); + Write(0x427322, false, "@"); Write(0x7fbd39, false, "@"); - Write(0x427322, false, "#"); - Write(0x488813, false, "#"); + Write(0x488813, false, "@#"); Write(0xd0b376, false, "."); - Write(0x488813, false, "@"); - Write(0x427322, false, "@ "); + Write(0x488813, false, "#"); + Write(0x1461f, false, "@ "); Write(0xaaaaaa, false, "_"); Write(0xd0b376, false, "|%%%=%%|"); Write(0xaaaaaa, false, "_ "); - Write(0x488813, false, "@#"); - Write(0x7fbd39, false, "@"); - Write(0x427322, false, "#@"); - Write(0x4d8b03, false, "@"); - Write(0x7fbd39, false, "@#"); Write(0x488813, false, "@"); + Write(0x4d8b03, false, "#@"); Write(0x427322, false, "@"); - Write(0x7fbd39, false, "@"); - Write(0x488813, false, "@"); + Write(0x1461f, false, "#"); Write(0x4d8b03, false, "#"); + Write(0x488813, false, "@@"); + Write(0x427322, false, "#"); + Write(0x488813, false, "@"); + Write(0x4d8b03, false, "@"); + Write(0x488813, false, "@"); + Write(0x427322, false, "@"); Write(0xaaaaaa, false, ". "); Write(0xe6410b, false, "~ /"); Write(0xaaaaaa, false, "' .'"); Write(0xe6410b, false, "/\\"); Write(0xaaaaaa, false, "."); Write(0x488813, false, "@"); - Write(0x4d8b03, false, "@"); - Write(0x7fbd39, false, "@"); - Write(0x4d8b03, false, "@"); - Write(0x7fbd39, false, "# "); + Write(0x427322, false, "@"); + Write(0x488813, false, "#@@ "); Write(0xcccccc, false, " 9 "); Write(0xffff66, false, "**\n "); - Write(0x4d8b03, false, "#@"); - Write(0x488813, false, "@@"); - Write(0x1461f, false, "#"); + Write(0x7fbd39, false, "@"); + Write(0x488813, false, "#@"); + Write(0x7fbd39, false, "#"); + Write(0x488813, false, "@"); Write(0xd0b376, false, ".."); Write(0xaaaaaa, false, "/ \\"); Write(0x5eabb4, false, ".~~."); Write(0xaaaaaa, false, "/ \\"); Write(0xd0b376, false, "....."); - Write(0x488813, false, "@@"); - Write(0x427322, false, "#"); - Write(0x488813, false, "@"); Write(0x4d8b03, false, "#"); - Write(0x488813, false, "#"); + Write(0x488813, false, "@"); + Write(0x7fbd39, false, "@"); + Write(0x488813, false, "@"); + Write(0x7fbd39, false, "@"); Write(0x4d8b03, false, "@"); - Write(0x427322, false, "@@"); + Write(0x427322, false, "@#"); + Write(0x1461f, false, "#"); Write(0xaaaaaa, false, "' "); Write(0xe6410b, false, "/\\"); Write(0xaaaaaa, false, ".''"); @@ -663,36 +653,37 @@ public void Show() { Write(0xaaaaaa, false, "' "); Write(0xe6410b, false, "\\"); Write(0xaaaaaa, false, "' "); - Write(0x427322, false, "@"); - Write(0x1461f, false, "@"); - Write(0x7fbd39, false, "# "); + Write(0x4d8b03, false, "#"); + Write(0x7fbd39, false, "## "); Write(0xcccccc, false, " 8 "); Write(0xffff66, false, "**\n "); - Write(0x1461f, false, "@"); - Write(0x488813, false, "@"); + Write(0x1461f, false, "#"); + Write(0x427322, false, "#"); + Write(0x488813, false, "#"); Write(0x427322, false, "@"); - Write(0x488813, false, "@"); - Write(0x7fbd39, false, "@#@"); - Write(0x427322, false, "@@"); - Write(0x488813, false, "@"); + Write(0x1461f, false, "#"); + Write(0x4d8b03, false, "@"); Write(0x1461f, false, "@"); - Write(0x5eabb4, false, ".~~."); + Write(0x7fbd39, false, "#"); + Write(0x488813, false, "@#"); Write(0x4d8b03, false, "#"); - Write(0x427322, false, "#"); - Write(0x1461f, false, "#"); + Write(0x5eabb4, false, ".~~."); Write(0x488813, false, "@"); + Write(0x427322, false, "@"); + Write(0x488813, false, "@"); + Write(0x4d8b03, false, "@"); + Write(0x7fbd39, false, "@"); Write(0x4d8b03, false, "@"); Write(0x7fbd39, false, "#"); Write(0x427322, false, "@"); Write(0x7fbd39, false, "@"); - Write(0x488813, false, "@"); Write(0xd0b376, false, "."); - Write(0x4d8b03, false, "@@"); - Write(0x1461f, false, "@"); + Write(0x7fbd39, false, "@"); Write(0x4d8b03, false, "@"); - Write(0x488813, false, "@"); + Write(0x1461f, false, "@"); + Write(0x427322, false, "@"); + Write(0x488813, false, "@#"); Write(0x7fbd39, false, "@"); - Write(0x488813, false, "@"); Write(0xaaaaaa, false, "'."); Write(0xe6410b, false, "/"); Write(0xaaaaaa, false, "."); @@ -704,30 +695,29 @@ public void Show() { Write(0xaaaaaa, false, " '. "); Write(0xcccccc, false, " 7 "); Write(0xffff66, false, "**\n "); - Write(0x427322, false, "@"); + Write(0x1461f, false, "@"); Write(0x488813, false, "@"); + Write(0x7fbd39, false, "@"); Write(0x4d8b03, false, "@"); - Write(0x427322, false, "#"); - Write(0x4d8b03, false, "@"); - Write(0x427322, false, "#"); - Write(0x488813, false, "@#"); + Write(0x7fbd39, false, "##"); + Write(0x488813, false, "@"); Write(0x427322, false, "@"); - Write(0x1461f, false, "#"); - Write(0x7fbd39, false, "@@"); - Write(0x5eabb4, false, ".~~."); - Write(0x7fbd39, false, "@@"); + Write(0x1461f, false, "@"); Write(0x4d8b03, false, "@"); Write(0x7fbd39, false, "@"); - Write(0x427322, false, "@"); Write(0x4d8b03, false, "@"); + Write(0x5eabb4, false, ".~~."); + Write(0x7fbd39, false, "@@"); Write(0x488813, false, "@"); - Write(0xd0b376, false, ".."); - Write(0x4d8b03, false, "@"); + Write(0x4d8b03, false, "#"); + Write(0x1461f, false, "@#"); Write(0x685c46, false, "|"); + Write(0xd0b376, false, ".."); Write(0x488813, false, "@"); - Write(0x7fbd39, false, "@"); - Write(0x488813, false, "@"); - Write(0x1461f, false, "#"); + Write(0x1461f, false, "@"); + Write(0x488813, false, "@@"); + Write(0x427322, false, "#"); + Write(0x4d8b03, false, "@"); Write(0xaaaaaa, false, "' "); Write(0xe6410b, false, "~"); Write(0xaaaaaa, false, ". "); @@ -739,49 +729,48 @@ public void Show() { Write(0xaaaaaa, false, ". "); Write(0xcccccc, false, " 6 "); Write(0xffff66, false, "**\n "); - Write(0x488813, false, "@"); - Write(0x1461f, false, "@"); Write(0x488813, false, "#"); - Write(0x4d8b03, false, "#"); + Write(0x4d8b03, false, "@"); + Write(0x7fbd39, false, "#"); + Write(0x4d8b03, false, "@"); + Write(0x427322, false, "@"); Write(0x488813, false, "@"); - Write(0x7fbd39, false, "##"); - Write(0x4d8b03, false, "#"); Write(0x7fbd39, false, "@"); - Write(0x4d8b03, false, "@"); - Write(0x1461f, false, "@"); - Write(0x427322, false, "@@"); + Write(0x1461f, false, "@@"); + Write(0x427322, false, "@"); + Write(0x488813, false, "#"); + Write(0x427322, false, "@#"); Write(0x5eabb4, false, ".~~."); - Write(0x7fbd39, false, "#"); + Write(0x4d8b03, false, "@"); Write(0x427322, false, "@"); Write(0xd0b376, false, "."); Write(0xeeeeee, false, "/\\"); Write(0xd0b376, false, ".'"); - Write(0x427322, false, "@@"); - Write(0x1461f, false, "#"); - Write(0x488813, false, "##"); - Write(0x4d8b03, false, "@"); Write(0x488813, false, "@"); + Write(0x4d8b03, false, "#"); Write(0x1461f, false, "@"); + Write(0x4d8b03, false, "@"); + Write(0x488813, false, "@"); + Write(0x427322, false, "@"); + Write(0x1461f, false, "#"); + Write(0x488813, false, "#"); Write(0xaaaaaa, false, "'.' .'"); Write(0xe6410b, false, "/"); Write(0xaaaaaa, false, "."); - Write(0x488813, false, "@"); + Write(0x4d8b03, false, "@"); Write(0xaaaaaa, false, ". "); Write(0xe6410b, false, "/"); Write(0xaaaaaa, false, "'."); Write(0xe6410b, false, "~~~ "); Write(0xcccccc, false, " 5 "); Write(0xffff66, false, "**\n "); - Write(0x7fbd39, false, "#"); - Write(0x685c46, false, "|"); - Write(0x4d8b03, false, "@"); + Write(0x4d8b03, false, "@#@"); + Write(0x488813, false, "@"); + Write(0x4d8b03, false, "@#"); Write(0x427322, false, "@"); - Write(0x1461f, false, "@"); Write(0x4d8b03, false, "@"); - Write(0x7fbd39, false, "@"); - Write(0x4d8b03, false, "@@"); - Write(0x488813, false, "#"); - Write(0x7fbd39, false, "@"); + Write(0x427322, false, "@@"); + Write(0x488813, false, "@"); Write(0xd0b376, false, ".'"); Write(0x5eabb4, false, " ~ "); Write(0xd0b376, false, "'."); @@ -789,10 +778,12 @@ public void Show() { Write(0xd0b376, false, "'."); Write(0xeeeeee, false, "/\\"); Write(0xd0b376, false, "' ."); + Write(0x4d8b03, false, "@"); + Write(0x488813, false, "@"); Write(0x7fbd39, false, "@"); - Write(0x4d8b03, false, "#@"); - Write(0x427322, false, "@@"); - Write(0x7fbd39, false, "@@"); + Write(0x4d8b03, false, "@@"); + Write(0x427322, false, "@"); + Write(0x7fbd39, false, "#"); Write(0xaaaaaa, false, "' "); Write(0xe6410b, false, "/\\"); Write(0xaaaaaa, false, " . "); @@ -800,23 +791,24 @@ public void Show() { Write(0xaaaaaa, false, "'. ..' "); Write(0xcccccc, false, " 4 "); Write(0xffff66, false, "**\n "); - Write(0x4d8b03, false, "@"); + Write(0x427322, false, "@@"); + Write(0x1461f, false, "@"); + Write(0x488813, false, "#"); + Write(0x4d8b03, false, "#@"); Write(0x7fbd39, false, "#"); - Write(0x488813, false, "@"); - Write(0x4d8b03, false, "@"); Write(0x427322, false, "@"); - Write(0x4d8b03, false, "@"); - Write(0x7fbd39, false, "#@@"); + Write(0x4d8b03, false, "#"); Write(0xd0b376, false, "_/"); Write(0x5eabb4, false, " ~ ~ "); Write(0xd0b376, false, "\\ ' '. '.'."); - Write(0x1461f, false, "#"); - Write(0x4d8b03, false, "@@@ "); + Write(0x7fbd39, false, "#@"); + Write(0x427322, false, "#"); + Write(0x4d8b03, false, "# "); Write(0xe6410b, false, "/ \\ \\ "); - Write(0x427322, false, "@"); Write(0x488813, false, "@"); - Write(0x7fbd39, false, "@"); - Write(0x427322, false, "@ "); + Write(0x427322, false, "@"); + Write(0x4d8b03, false, "@"); + Write(0x7fbd39, false, "@ "); Write(0xcccccc, false, " 3 "); Write(0xffff66, false, "**\n "); Write(0xd0b376, false, "-~------'"); @@ -832,7 +824,7 @@ public void Show() { Console.WriteLine(); } - private static void Write(int rgb, bool bold, string text){ + private static void Write(int rgb, bool bold, string text){ Console.Write($"\u001b[38;2;{(rgb>>16)&255};{(rgb>>8)&255};{rgb&255}{(bold ? ";1" : "")}m{text}"); - } -} \ No newline at end of file + } +} diff --git a/2022/calendar.svg b/2022/calendar.svg index 7b4b0c60b..fe3a33d50 100644 --- a/2022/calendar.svg +++ b/2022/calendar.svg @@ -1,4 +1,4 @@ - + fifty stars by December 25th. - -_Visit the website for the full story and [full puzzle](https://adventofcode.com/2023/day/1) description._ diff --git a/2023/Day01/Solution.cs b/2023/Day01/Solution.cs deleted file mode 100644 index f2757dd57..000000000 --- a/2023/Day01/Solution.cs +++ /dev/null @@ -1,34 +0,0 @@ -namespace AdventOfCode.Y2023.Day01; - -using System.Linq; -using System.Text.RegularExpressions; - -[ProblemName("Trebuchet?!")] -class Solution : Solver { - - public object PartOne(string input) => - Solve(input, @"\d"); - - public object PartTwo(string input) => - Solve(input, @"\d|one|two|three|four|five|six|seven|eight|nine"); - - int Solve(string input, string rx) => ( - from line in input.Split("\n") - let first = Regex.Match(line, rx) - let last = Regex.Match(line, rx, RegexOptions.RightToLeft) - select ParseMatch(first.Value) * 10 + ParseMatch(last.Value) - ).Sum(); - - int ParseMatch(string st) => st switch { - "one" => 1, - "two" => 2, - "three" => 3, - "four" => 4, - "five" => 5, - "six" => 6, - "seven" => 7, - "eight" => 8, - "nine" => 9, - var d => int.Parse(d) - }; -} diff --git a/2023/Day01/illustration.jpeg b/2023/Day01/illustration.jpeg deleted file mode 100644 index 2764a9495..000000000 Binary files a/2023/Day01/illustration.jpeg and /dev/null differ diff --git a/2023/Day01/input.in b/2023/Day01/input.in deleted file mode 100644 index 39a4d9fd9..000000000 Binary files a/2023/Day01/input.in and /dev/null differ diff --git a/2023/Day01/input.refout b/2023/Day01/input.refout deleted file mode 100644 index 1ba50a3f0..000000000 --- a/2023/Day01/input.refout +++ /dev/null @@ -1,2 +0,0 @@ -55447 -54706 \ No newline at end of file diff --git a/2023/Day02/README.md b/2023/Day02/README.md deleted file mode 100644 index 38fee8d3d..000000000 --- a/2023/Day02/README.md +++ /dev/null @@ -1,6 +0,0 @@ -## --- Day 2: Cube Conundrum --- -The task description is copyrighted, but it's available [here](https://adventofcode.com/2023/day/2). - -Ok, now we are on track. The hardest part of this problem is the parsing, but I introduced a helper that can extract a number in the context of some regular expression which works like a breeze. What's more, we only need to keep track of the maximum of the red, green and blue boxes, so our `Game` struct becomes just four integers. - -The actual _algorithm_ for Part 1 and Part 2 is very simple, and linq makes it quite readable as well. diff --git a/2023/Day02/Solution.cs b/2023/Day02/Solution.cs deleted file mode 100644 index a6f6a541e..000000000 --- a/2023/Day02/Solution.cs +++ /dev/null @@ -1,39 +0,0 @@ -namespace AdventOfCode.Y2023.Day02; - -using System.Collections.Generic; -using System.Linq; -using System.Text.RegularExpressions; - -record Game(int id, int red, int green, int blue); - -[ProblemName("Cube Conundrum")] -class Solution : Solver { - - public object PartOne(string input) => ( - from line in input.Split("\n") - let game = ParseGame(line) - where game.red <= 12 && game.green <= 13 && game.blue <= 14 - select game.id - ).Sum(); - - public object PartTwo(string input) => ( - from line in input.Split("\n") - let game = ParseGame(line) - select game.red * game.green * game.blue - ).Sum(); - - // no need to keep track of the individual rounds in a game, just return - // the maximum of the red, green, blue boxes - Game ParseGame(string line) => - new Game( - ParseInts(line, @"Game (\d+)").First(), - ParseInts(line, @"(\d+) red").Max(), - ParseInts(line, @"(\d+) green").Max(), - ParseInts(line, @"(\d+) blue").Max() - ); - - // extracts integers from a string identified by a single regex group. - IEnumerable ParseInts(string st, string rx) => - from m in Regex.Matches(st, rx) - select int.Parse(m.Groups[1].Value); -} diff --git a/2023/Day02/illustration.jpeg b/2023/Day02/illustration.jpeg deleted file mode 100644 index 78bdd14ad..000000000 Binary files a/2023/Day02/illustration.jpeg and /dev/null differ diff --git a/2023/Day02/input.in b/2023/Day02/input.in deleted file mode 100644 index b84b045ef..000000000 Binary files a/2023/Day02/input.in and /dev/null differ diff --git a/2023/Day02/input.refout b/2023/Day02/input.refout deleted file mode 100644 index 8b837a188..000000000 --- a/2023/Day02/input.refout +++ /dev/null @@ -1,2 +0,0 @@ -2076 -70950 \ No newline at end of file diff --git a/2023/Day03/README.md b/2023/Day03/README.md deleted file mode 100644 index ad0fcf171..000000000 --- a/2023/Day03/README.md +++ /dev/null @@ -1,12 +0,0 @@ -## --- Day 3: Gear Ratios --- -Let's revisit the problem description [here](https://adventofcode.com/2023/day/3). - -There are multiple ways to footgun ourselves with this one, if somebody is not -careful with the parser. I solved this problem using regular expressions. First I -searched for all numbers and symbols, then collected those that were -adjacent to each other. - -I did the same trick in Part 2, but now searched for all gear symbols (`*`) and -filtered out those that are adjacent to exactly two numbers. - -Probably the hardest part is to tell if two matches are adjacent or not. diff --git a/2023/Day03/Solution.cs b/2023/Day03/Solution.cs deleted file mode 100644 index 4d216e2d1..000000000 --- a/2023/Day03/Solution.cs +++ /dev/null @@ -1,56 +0,0 @@ -namespace AdventOfCode.Y2023.Day03; - -using System; -using System.Linq; -using System.Text.RegularExpressions; - -[ProblemName("Gear Ratios")] -class Solution : Solver { - - // Introduce a Parse function that returns the interesting 'blocks' of texts - // and positions using a regex. Then just filter and match these according - // to the problem spec. - - public object PartOne(string input) { - var rows = input.Split("\n"); - var symbols = Parse(rows, new Regex(@"[^.0-9]")); - var nums = Parse(rows, new Regex(@"\d+")); - - return ( - from n in nums - where symbols.Any(s => Adjacent(s, n)) - select n.Int - ).Sum(); - } - - public object PartTwo(string input) { - var rows = input.Split("\n"); - var gears = Parse(rows, new Regex(@"\*")); - var numbers = Parse(rows, new Regex(@"\d+")); - - return ( - from g in gears - let neighbours = from n in numbers where Adjacent(n, g) select n.Int - where neighbours.Count() == 2 - select neighbours.First() * neighbours.Last() - ).Sum(); - } - - // checks that the parts are touching each other, i.e. rows are within 1 - // step and also the columns (using https://stackoverflow.com/a/3269471). - bool Adjacent(Part p1, Part p2) => - Math.Abs(p2.Irow - p1.Irow) <= 1 && - p1.Icol <= p2.Icol + p2.Text.Length && - p2.Icol <= p1.Icol + p1.Text.Length; - - // returns the matches of rx with its coordinates - Part[] Parse(string[] rows, Regex rx) => ( - from irow in Enumerable.Range(0, rows.Length) - from match in rx.Matches(rows[irow]) - select new Part(match.Value, irow, match.Index) - ).ToArray(); -} - -record Part(string Text, int Irow, int Icol) { - public int Int => int.Parse(Text); -} diff --git a/2023/Day03/illustration.jpeg b/2023/Day03/illustration.jpeg deleted file mode 100644 index c31a3973a..000000000 Binary files a/2023/Day03/illustration.jpeg and /dev/null differ diff --git a/2023/Day03/input.in b/2023/Day03/input.in deleted file mode 100644 index bc09e2783..000000000 Binary files a/2023/Day03/input.in and /dev/null differ diff --git a/2023/Day03/input.refout b/2023/Day03/input.refout deleted file mode 100644 index 7b8c558ce..000000000 --- a/2023/Day03/input.refout +++ /dev/null @@ -1,2 +0,0 @@ -520019 -75519888 \ No newline at end of file diff --git a/2023/Day04/README.md b/2023/Day04/README.md deleted file mode 100644 index 74724c9ce..000000000 --- a/2023/Day04/README.md +++ /dev/null @@ -1,11 +0,0 @@ -## --- Day 4: Scratchcards --- -The original problem description is available [here](https://adventofcode.com/2023/day/4). - -An other day! In Part 1 we need to determine how many _winning_ numbers we have -in a scratch card, this is simple enough. - -Part 2 can be treated in a very-very bad way if somebody doesn't notice that it's -nothing else but a loop!. We start with a single card #1 and see how many -cards we are winning, this will generate some new cards of id 2, 3 and so. Then move -to card(s) #2 and continue this process until the end of the list. Return -the number of all cards we dealt with. diff --git a/2023/Day04/Solution.cs b/2023/Day04/Solution.cs deleted file mode 100644 index ddffbb15f..000000000 --- a/2023/Day04/Solution.cs +++ /dev/null @@ -1,40 +0,0 @@ -namespace AdventOfCode.Y2023.Day04; - -using System; -using System.Linq; -using System.Text.RegularExpressions; - -record Card(int matches); - -[ProblemName("Scratchcards")] -class Solution : Solver { - - public object PartOne(string input) => ( - from line in input.Split("\n") - let card = ParseCard(line) - where card.matches > 0 - select Math.Pow(2, card.matches - 1) - ).Sum(); - - // Quite imperatively, just walk over the cards keeping track of the counts. - public object PartTwo(string input) { - var cards = input.Split("\n").Select(ParseCard).ToArray(); - var counts = cards.Select(_ => 1).ToArray(); - - for (var i = 0; i < cards.Length; i++) { - var (card, count) = (cards[i], counts[i]); - for (var j = 0; j < card.matches; j++) { - counts[i + j + 1] += count; - } - } - return counts.Sum(); - } - - // Only the match count is relevant for a card - Card ParseCard(string line) { - var parts = line.Split(':', '|'); - var l = from m in Regex.Matches(parts[1], @"\d+") select m.Value; - var r = from m in Regex.Matches(parts[2], @"\d+") select m.Value; - return new Card(l.Intersect(r).Count()); - } -} diff --git a/2023/Day04/illustration.jpeg b/2023/Day04/illustration.jpeg deleted file mode 100644 index 04e0b6e6d..000000000 Binary files a/2023/Day04/illustration.jpeg and /dev/null differ diff --git a/2023/Day04/input.in b/2023/Day04/input.in deleted file mode 100644 index b51722da4..000000000 Binary files a/2023/Day04/input.in and /dev/null differ diff --git a/2023/Day04/input.refout b/2023/Day04/input.refout deleted file mode 100644 index 47ee47a63..000000000 --- a/2023/Day04/input.refout +++ /dev/null @@ -1,2 +0,0 @@ -21558 -10425665 \ No newline at end of file diff --git a/2023/Day05/README.md b/2023/Day05/README.md deleted file mode 100644 index f46ab5529..000000000 --- a/2023/Day05/README.md +++ /dev/null @@ -1,10 +0,0 @@ -## --- Day 5: If You Give A Seed A Fertilizer --- -Visit the Advent of Code website for the problem statement [here](https://adventofcode.com/2023/day/5). - -A more tricky problem today. We have a set of numbers that need to be transformed by a series of maps, then we need to return the minimum of all outcomes. - -This might sound simple, but Part 2 transforms it to a more interesting problem where the inputs are not numbers but ranges. Our maps split the ranges into other ranges, so a lot of special cases and possible off-by-one errors appear on the horizon. - -I created a function that deals with just one map but multiple ranges. The ranges are fed into a `queue` and I process them one by one. There are just three possiblites: the map tells nothing about the range, it maps the range to a single range or some _cutting_ is required. The first cases are simply enough, only the last one is interesting. It can happen that our range need to be cut into 2, 3, 4 or even more parts, so this would be hard to handle in a single step. So what I did was simply just make a single cut that generates two new ranges and add these back to the queue. They will be taken care about later. At the end they will be cut enough times so that the parts can be processed by one of the two simple cases above. - -Having a function to do the heavy lifting, I can push all ranges though all the maps easily, then take the minimum of the result. diff --git a/2023/Day05/Solution.cs b/2023/Day05/Solution.cs deleted file mode 100644 index a4e79f69a..000000000 --- a/2023/Day05/Solution.cs +++ /dev/null @@ -1,78 +0,0 @@ -namespace AdventOfCode.Y2023.Day05; - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text.RegularExpressions; - -record Range(long begin, long end); - -[ProblemName("If You Give A Seed A Fertilizer")] -class Solution : Solver { - - public object PartOne(string input) => Solve(input, PartOneRanges); - public object PartTwo(string input) => Solve(input, PartTwoRanges); - - long Solve(string input, Func, IEnumerable> parseSeeds) { - var blocks = input.Split("\n\n"); - var seedRanges = parseSeeds(ParseNumbers(blocks[0])).ToList(); - var maps = blocks.Skip(1).Select(ParseMap).ToArray(); - - // Project each range through the series of maps, this will result some - // new ranges. Return the leftmost value (minimum) of these. - return maps.Aggregate(seedRanges, Project).Select(r => r.begin).Min(); - } - - List Project(List inputRanges, Dictionary map) { - var input = new Queue(inputRanges); - var output = new List(); - - while (input.Any()) { - var range = input.Dequeue(); - // If no entry intersects our range -> just add it to the output. - // If an entry completely contains the range -> add after mapping. - // Otherwise, some entry partly covers the range. In this case 'chop' - // the range into two halfs getting rid of the intersection. The new - // pieces are added back to the queue for further processing and will be - // ultimately consumed by the first two cases. - var src = map.Keys.FirstOrDefault(src => Intersects(src, range)); - if (src == null) { - output.Add(range); - } else if (src.begin <= range.begin && range.end <= src.end) { - var dst = map[src]; - var shift = dst.begin - src.begin; - output.Add(new Range(range.begin + shift, range.end + shift)); - } else if (range.begin < src.begin) { - input.Enqueue(new Range(range.begin, src.begin - 1)); - input.Enqueue(new Range(src.begin, range.end)); - } else { - input.Enqueue(new Range(range.begin, src.end)); - input.Enqueue(new Range(src.end + 1, range.end)); - } - } - return output; - } - - // see https://stackoverflow.com/a/3269471 - bool Intersects(Range r1, Range r2) => r1.begin <= r2.end && r2.begin <= r1.end; - - // consider each number as a range of 1 length - IEnumerable PartOneRanges(IEnumerable numbers) => - from n in numbers select new Range(n, n); - - // chunk is a great way to iterate over the pairs of numbers - IEnumerable PartTwoRanges(IEnumerable numbers) => - from n in numbers.Chunk(2) select new Range(n[0], n[0] + n[1] - 1); - - IEnumerable ParseNumbers(string input) => - from m in Regex.Matches(input, @"\d+") select long.Parse(m.Value); - - Dictionary ParseMap(string input) => ( - from line in input.Split("\n").Skip(1) - let parts = ParseNumbers(line).ToArray() - select new KeyValuePair( - new Range(parts[1], parts[2] + parts[1] - 1), - new Range(parts[0], parts[2] + parts[0] - 1)) - ).ToDictionary(); -} - diff --git a/2023/Day05/illustration.jpeg b/2023/Day05/illustration.jpeg deleted file mode 100644 index 228173ece..000000000 Binary files a/2023/Day05/illustration.jpeg and /dev/null differ diff --git a/2023/Day05/input.in b/2023/Day05/input.in deleted file mode 100644 index 750c9fa34..000000000 Binary files a/2023/Day05/input.in and /dev/null differ diff --git a/2023/Day05/input.refout b/2023/Day05/input.refout deleted file mode 100644 index 5948e332e..000000000 --- a/2023/Day05/input.refout +++ /dev/null @@ -1,2 +0,0 @@ -806029445 -59370572 \ No newline at end of file diff --git a/2023/Day06/README.md b/2023/Day06/README.md deleted file mode 100644 index 474ec2d20..000000000 --- a/2023/Day06/README.md +++ /dev/null @@ -1,10 +0,0 @@ -## --- Day 6: Wait For It --- -If you are not familiar with the problem, you can read it [here](https://adventofcode.com/2023/day/6). - -This has been a simple problem, could be solved even with brute forcing, but I went the -maths path and implemented a quadratic equation solver instead. - -It's easy to compute how far our boat moves if we wait for `x` ms at the beginning. -The solution to this equation tells us the `x`-es for which we break the record distance. - -Part 2 is just Part 1 with bigger numbers. diff --git a/2023/Day06/Solution.cs b/2023/Day06/Solution.cs deleted file mode 100644 index 2527f5238..000000000 --- a/2023/Day06/Solution.cs +++ /dev/null @@ -1,51 +0,0 @@ -namespace AdventOfCode.Y2023.Day06; - -using System; -using System.Linq; -using System.Text.RegularExpressions; - -[ProblemName("Wait For It")] -class Solution : Solver { - - public object PartOne(string input) => Solve(input); - public object PartTwo(string input) => Solve(input.Replace(" ", "")); - - long Solve(string input) { - var rows = input.Split("\n"); - var times = Parse(rows[0]); - var records = Parse(rows[1]); - - var res = 1L; - for (var i = 0; i < times.Length; i++) { - res *= WinningMoves(times[i], records[i]); - } - return res; - } - - long WinningMoves(long time, long record) { - // If we wait x ms, our boat moves `(time - x) * x` millimeters. - // This breaks the record when `(time - x) * x > record` - // or `-x^2 + time * x - record > 0`. - - // get the roots first - var (x1, x2) = SolveEq(-1, time, -record); - - // integers in between the roots - var maxX = (long)Math.Ceiling(x2) - 1; - var minX = (long)Math.Floor(x1) + 1; - return maxX - minX + 1; - } - - // solves ax^2 + bx + c = 0 (supposing two different roots) - (double, double) SolveEq(long a, long b, long c) { - var d = Math.Sqrt(b * b - 4 * a * c); - var x1 = (-b - d) / (2 * a); - var x2 = (-b + d) / (2 * a); - return (Math.Min(x1, x2), Math.Max(x1, x2)); - } - - long[] Parse(string input) => ( - from m in Regex.Matches(input, @"\d+") - select long.Parse(m.Value) - ).ToArray(); -} diff --git a/2023/Day06/illustration.jpeg b/2023/Day06/illustration.jpeg deleted file mode 100644 index 04ff19cd6..000000000 Binary files a/2023/Day06/illustration.jpeg and /dev/null differ diff --git a/2023/Day06/input.in b/2023/Day06/input.in deleted file mode 100644 index 0b9bbe9b0..000000000 Binary files a/2023/Day06/input.in and /dev/null differ diff --git a/2023/Day06/input.refout b/2023/Day06/input.refout deleted file mode 100644 index 578621b2f..000000000 --- a/2023/Day06/input.refout +++ /dev/null @@ -1,2 +0,0 @@ -1710720 -35349468 \ No newline at end of file diff --git a/2023/Day07/README.md b/2023/Day07/README.md deleted file mode 100644 index 284290c62..000000000 --- a/2023/Day07/README.md +++ /dev/null @@ -1,11 +0,0 @@ -## --- Day 7: Camel Cards --- -Those who need a refresh can read the problem [here](https://adventofcode.com/2023/day/7). - -We are playing ~poker~ Camel Cards today! In Part 1 we need to evalute hands and put them in order. Each -hand has what I call a pattern value: five of a kind, poker, full house, three of a kind, double -pair or pair and some individual card value such as: 1, 2, ..., J, Q, K, or A. - -Pattern value becomes one number, card value becomes an other number then let linq do the ordering for me. - -Part 2 is not much different, but the individual card value changes, and `J` becomes -a joker that can replace any other cards. I made a shortcut here and just reused the functions from Part 1. diff --git a/2023/Day07/Solution.cs b/2023/Day07/Solution.cs deleted file mode 100644 index ed51ade2b..000000000 --- a/2023/Day07/Solution.cs +++ /dev/null @@ -1,50 +0,0 @@ -namespace AdventOfCode.Y2023.Day07; - -using System; -using System.Collections.Generic; -using System.Linq; - -[ProblemName("Camel Cards")] -class Solution : Solver { - - // Each 'hand' gets points based on the card's individual value and - // pattern value. - - public object PartOne(string input) => Solve(input, Part1Points); - public object PartTwo(string input) => Solve(input, Part2Points); - - (long, long) Part1Points(string hand) => - (PatternValue(hand), CardValue(hand, "123456789TJQKA")); - - (long, long) Part2Points(string hand) { - var cards = "J123456789TQKA"; - var patternValue = - cards.Select(ch => PatternValue(hand.Replace('J', ch))).Max(); - return (patternValue, CardValue(hand, cards)); - } - - // map cards to their indices in cardOrder. E.g. for 123456789TJQKA - // A8A8A becomes (13)(7)(13)(7)(13), 9A34Q becomes (8)(13)(2)(3)(11) - long CardValue(string hand, string cardOrder) => - Pack(hand.Select(card => cardOrder.IndexOf(card))); - - // map cards to the number of their occurrences in the hand then order them - // such thatA8A8A becomes 33322, 9A34Q becomes 11111 and K99AA becomes 22221 - long PatternValue(string hand) => - Pack(hand.Select(card => hand.Count(x => x == card)).OrderDescending()); - - long Pack(IEnumerable numbers) => - numbers.Aggregate(1L, (a, v) => (a * 256) + v); - - int Solve(string input, Func getPoints) { - var bidsByRanking = ( - from line in input.Split("\n") - let hand = line.Split(" ")[0] - let bid = int.Parse(line.Split(" ")[1]) - orderby getPoints(hand) - select bid - ); - - return bidsByRanking.Select((bid, rank) => (rank + 1) * bid).Sum(); - } -} diff --git a/2023/Day07/illustration.jpeg b/2023/Day07/illustration.jpeg deleted file mode 100644 index beb93d335..000000000 Binary files a/2023/Day07/illustration.jpeg and /dev/null differ diff --git a/2023/Day07/input.in b/2023/Day07/input.in deleted file mode 100644 index 9eb0cdbec..000000000 Binary files a/2023/Day07/input.in and /dev/null differ diff --git a/2023/Day07/input.refout b/2023/Day07/input.refout deleted file mode 100644 index 4c8a6a1f8..000000000 --- a/2023/Day07/input.refout +++ /dev/null @@ -1,2 +0,0 @@ -251806792 -252113488 \ No newline at end of file diff --git a/2023/Day08/README.md b/2023/Day08/README.md deleted file mode 100644 index b460559c3..000000000 --- a/2023/Day08/README.md +++ /dev/null @@ -1,13 +0,0 @@ -## --- Day 8: Haunted Wasteland --- -The task description is copyrighted, but it's available [here](https://adventofcode.com/2023/day/8). - -We need to implement some process that is called _wandering around the desert_ and it's essentially a -series of dictionary lookups that lead to other dictionary lookups. - -Pretty dry as I'm writing it down, but the point is that after some iterations we get from AAA to ZZZ. -Part 1 asks for the number of steps needed for that. - -Part 2 gives it a spin and is asking us to start from all nodes that end with the letter A at once, -and continue _wandering around_ in parallel until we reach Z nodes simultanously in every path! - -Obviously, this would take ages to wait out, but fortunately the input is specially crafted so that we can take the least common multiplier of the length of the individual loops and return just that. diff --git a/2023/Day08/Solution.cs b/2023/Day08/Solution.cs deleted file mode 100644 index bcbaa1b62..000000000 --- a/2023/Day08/Solution.cs +++ /dev/null @@ -1,46 +0,0 @@ -namespace AdventOfCode.Y2023.Day08; - -using System.Linq; -using System.Text.RegularExpressions; -using Map = System.Collections.Generic.Dictionary; - -[ProblemName("Haunted Wasteland")] -class Solution : Solver { - - public object PartOne(string input) => Solve(input, "AAA", "ZZZ"); - public object PartTwo(string input) => Solve(input, "A", "Z"); - - long Solve(string input, string aMarker, string zMarker) { - var blocks = input.Split("\n\n"); - var dirs = blocks[0]; - var map = ParseMap(blocks[1]); - - // From each start node calculate the steps to the first Z node, then - // suppose that if we continue wandering around in the desert the - /// distance between the Z nodes is always the same. - // The input was set up this way, which justifies the use of LCM in - // computing the final result. - return map.Keys - .Where(w => w.EndsWith(aMarker)) - .Select(w => StepsToZ(w, zMarker, dirs, map)) - .Aggregate(1L, Lcm); - } - - long Lcm(long a, long b) => a * b / Gcd(a, b); - long Gcd(long a, long b) => b == 0 ? a : Gcd(b, a % b); - - long StepsToZ(string current, string zMarker, string dirs, Map map) { - var i = 0; - while (!current.EndsWith(zMarker)) { - var dir = dirs[i % dirs.Length]; - current = dir == 'L' ? map[current].Left : map[current].Right; - i++; - } - return i; - } - - Map ParseMap(string input) => - input.Split("\n") - .Select(line => Regex.Matches(line, "[A-Z]+")) - .ToDictionary(m => m[0].Value, m => (m[1].Value, m[2].Value)); -} diff --git a/2023/Day08/illustration.jpeg b/2023/Day08/illustration.jpeg deleted file mode 100644 index f4243ea87..000000000 Binary files a/2023/Day08/illustration.jpeg and /dev/null differ diff --git a/2023/Day08/input.in b/2023/Day08/input.in deleted file mode 100644 index 5957b65fa..000000000 Binary files a/2023/Day08/input.in and /dev/null differ diff --git a/2023/Day08/input.refout b/2023/Day08/input.refout deleted file mode 100644 index 0b408f523..000000000 --- a/2023/Day08/input.refout +++ /dev/null @@ -1,2 +0,0 @@ -14893 -10241191004509 \ No newline at end of file diff --git a/2023/Day09/README.md b/2023/Day09/README.md deleted file mode 100644 index c7e7b925b..000000000 --- a/2023/Day09/README.md +++ /dev/null @@ -1,9 +0,0 @@ -## --- Day 9: Mirage Maintenance --- -Let's revisit the problem description [here](https://adventofcode.com/2023/day/9). - -We are implementing an _extrapolation_ algorithm that reminds me to my -university years when we did Newton interpolation, or was it Lagrange? I don't -remember anymore, but it was using a similar algorithm to this. - -Part 1 and Part 2 differs only in the direction of the extrapolation, and one -can be implemented using the other, just like I did it below. diff --git a/2023/Day09/Solution.cs b/2023/Day09/Solution.cs deleted file mode 100644 index ccdd7e07d..000000000 --- a/2023/Day09/Solution.cs +++ /dev/null @@ -1,29 +0,0 @@ -namespace AdventOfCode.Y2023.Day09; - -using System; -using System.Linq; - -[ProblemName("Mirage Maintenance")] -class Solution : Solver { - - public object PartOne(string input) => Solve(input, ExtrapolateRight); - public object PartTwo(string input) => Solve(input, ExtrapolateLeft); - - long Solve(string input, Func extrapolate) => - input.Split("\n").Select(ParseNumbers).Select(extrapolate).Sum(); - - long[] ParseNumbers(string line) => - line.Split(" ").Select(long.Parse).ToArray(); - - // It's a common trick to zip a sequence with the skipped version of itself - long[] Diff(long[] numbers) => - numbers.Zip(numbers.Skip(1)).Select(p => p.Second - p.First).ToArray(); - - // I went a bit further and recurse until there are no numbers left. It's - // more compact this way and doesn't affect the runtime much. - long ExtrapolateRight(long[] numbers) => - !numbers.Any() ? 0 : ExtrapolateRight(Diff(numbers)) + numbers.Last(); - - long ExtrapolateLeft(long[] numbers) => - ExtrapolateRight(numbers.Reverse().ToArray()); -} diff --git a/2023/Day09/illustration.jpeg b/2023/Day09/illustration.jpeg deleted file mode 100644 index aa73a2304..000000000 Binary files a/2023/Day09/illustration.jpeg and /dev/null differ diff --git a/2023/Day09/input.in b/2023/Day09/input.in deleted file mode 100644 index f1eab021d..000000000 Binary files a/2023/Day09/input.in and /dev/null differ diff --git a/2023/Day09/input.refout b/2023/Day09/input.refout deleted file mode 100644 index 3722f18b4..000000000 --- a/2023/Day09/input.refout +++ /dev/null @@ -1,2 +0,0 @@ -2101499000 -1089 \ No newline at end of file diff --git a/2023/Day10/README.md b/2023/Day10/README.md deleted file mode 100644 index 258eb534c..000000000 --- a/2023/Day10/README.md +++ /dev/null @@ -1,9 +0,0 @@ -## --- Day 10: Pipe Maze --- -The original problem description is available [here](https://adventofcode.com/2023/day/10). - -In Part 1 we had to find the length of a loop that was defined by a funky ASCII -art pipe network that even used J, and F characters for the turns. - -Part 2 asked to compute the area of the loop, I implemented ray casting -for this one. There are lots of other ways to solve this, a similar problem -and different algorithm can be found in Day 18. diff --git a/2023/Day10/Solution.cs b/2023/Day10/Solution.cs deleted file mode 100644 index 5a5574182..000000000 --- a/2023/Day10/Solution.cs +++ /dev/null @@ -1,91 +0,0 @@ -namespace AdventOfCode.Y2023.Day10; - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Numerics; -using Map = System.Collections.Generic.Dictionary; - -[ProblemName("Pipe Maze")] -class Solution : Solver { - static readonly Complex Up = -Complex.ImaginaryOne; - static readonly Complex Down = Complex.ImaginaryOne; - static readonly Complex Left = -Complex.One; - static readonly Complex Right = Complex.One; - static readonly Complex[] Dirs = [Up, Right, Down, Left]; - - static readonly Dictionary Exits = new Dictionary{ - {'7', [Left, Down] }, - {'F', [Right, Down]}, - {'L', [Up, Right]}, - {'J', [Up, Left]}, - {'|', [Up, Down]}, - {'-', [Left, Right]}, - {'S', [Up, Down, Left, Right]}, - {'.', []}, - }; - - public object PartOne(string input) { - var map = ParseMap(input); - var loop = LoopPositions(map); - return loop.Count / 2; - } - - public object PartTwo(string input) { - var map = ParseMap(input); - var loop = LoopPositions(map); - return map.Keys.Count(position => Inside(position, map, loop)); - } - - // Returns the positions that make up the loop containing 'S' - HashSet LoopPositions(Map map) { - var position = map.Keys.Single(k => map[k] == 'S'); - var positions = new HashSet(); - - // pick a direction connected to a neighbour - var dir = Dirs.First(dir => Exits[map[position + dir]].Contains(-dir)); - - for (; ; ) { - positions.Add(position); - position += dir; - if (map[position] == 'S') { - break; - } - dir = Exits[map[position]].Single(exit => exit != -dir); - } - return positions; - } - - // Check if position is inside the loop using ray casting algorithm - bool Inside(Complex position, Map map, HashSet loop) { - // Imagine a small elf starting from the top half of a cell and moving - // to the left jumping over the pipes it encounters. It needs to jump - // over only 'vertically' oriented pipes leading upwards, since it runs - // in the top of the row. Each jump flips the "inside" variable. - - if (loop.Contains(position)) { - return false; - } - - var inside = false; - position += Left; - while (map.ContainsKey(position)) { - if (loop.Contains(position) && Exits[map[position]].Contains(Up)) { - inside = !inside; - } - position += Left; - } - return inside; - } - - Map ParseMap(string input) { - var rows = input.Split("\n"); - return ( - from irow in Enumerable.Range(0, rows.Length) - from icol in Enumerable.Range(0, rows[0].Length) - let pos = new Complex(icol, irow) - let cell = rows[irow][icol] - select new KeyValuePair(pos, cell) - ).ToDictionary(); - } -} diff --git a/2023/Day10/illustration.jpeg b/2023/Day10/illustration.jpeg deleted file mode 100644 index 032b77df4..000000000 Binary files a/2023/Day10/illustration.jpeg and /dev/null differ diff --git a/2023/Day10/input.in b/2023/Day10/input.in deleted file mode 100644 index c14d4cdbf..000000000 Binary files a/2023/Day10/input.in and /dev/null differ diff --git a/2023/Day10/input.refout b/2023/Day10/input.refout deleted file mode 100644 index 021280b74..000000000 --- a/2023/Day10/input.refout +++ /dev/null @@ -1,2 +0,0 @@ -6613 -511 \ No newline at end of file diff --git a/2023/Day11/README.md b/2023/Day11/README.md deleted file mode 100644 index 25ac9d866..000000000 --- a/2023/Day11/README.md +++ /dev/null @@ -1,11 +0,0 @@ -## --- Day 11: Cosmic Expansion --- -Visit the Advent of Code website for the problem statement[here](https://adventofcode.com/2023/day/11). - -A pretty simple problem for today. We had to compute the sum of the pairwise Manhattan distances -of each galaxies (`#` symbols) in a map. - -The twist is that moving accross some columns or rows of the map is worths double distance points -(one million in Part 2). But it was not hard to incorporate this into our distance function. - -I did it this way, but we should mention that since we are computing the distance over each pair, and all operations are commutative and associative, it's probably possible to reorder things a bit which can result in a more efficient algorithm. - diff --git a/2023/Day11/Solution.cs b/2023/Day11/Solution.cs deleted file mode 100644 index f7ea4403b..000000000 --- a/2023/Day11/Solution.cs +++ /dev/null @@ -1,52 +0,0 @@ -namespace AdventOfCode.Y2023.Day11; - -using System; -using System.Collections.Generic; -using System.Linq; - -record Position(int irow, int icol); - -[ProblemName("Cosmic Expansion")] -class Solution : Solver { - - public object PartOne(string input) => Solve(input, 1); - public object PartTwo(string input) => Solve(input, 999999); - - long Solve(string input, int expansion) { - var map = input.Split("\n"); - - Func isRowEmpty = EmptyRows(map).ToHashSet().Contains; - Func isColEmpty = EmptyCols(map).ToHashSet().Contains; - - var galaxies = FindAll(map, '#'); - return ( - from g1 in galaxies - from g2 in galaxies - select - Distance(g1.irow, g2.irow, expansion, isRowEmpty) + - Distance(g1.icol, g2.icol, expansion, isColEmpty) - ).Sum() / 2; - } - - long Distance(int i1, int i2, int expansion, Func isEmpty) { - var a = Math.Min(i1, i2); - var d = Math.Abs(i1 - i2); - return d + expansion * Enumerable.Range(a, d).Count(isEmpty); - } - - IEnumerable EmptyRows(string[] map) => - from irow in Enumerable.Range(0, map.Length) - where map[irow].All(ch => ch == '.') - select irow; - - IEnumerable EmptyCols(string[] map) => - from icol in Enumerable.Range(0, map[0].Length) - where map.All(row => row[icol] == '.') - select icol; - - IEnumerable FindAll(string[] map, char ch) => - from irow in Enumerable.Range(0, map.Length) - from icol in Enumerable.Range(0, map[0].Length) - where map[irow][icol] == ch - select new Position(irow, icol); -} diff --git a/2023/Day11/illustration.jpeg b/2023/Day11/illustration.jpeg deleted file mode 100644 index 542eb6e96..000000000 Binary files a/2023/Day11/illustration.jpeg and /dev/null differ diff --git a/2023/Day11/input.in b/2023/Day11/input.in deleted file mode 100644 index 8ed93ddcc..000000000 Binary files a/2023/Day11/input.in and /dev/null differ diff --git a/2023/Day11/input.refout b/2023/Day11/input.refout deleted file mode 100644 index 3afa29a0c..000000000 --- a/2023/Day11/input.refout +++ /dev/null @@ -1,2 +0,0 @@ -9795148 -650672493820 \ No newline at end of file diff --git a/2023/Day12/README.md b/2023/Day12/README.md deleted file mode 100644 index c5e3c6722..000000000 --- a/2023/Day12/README.md +++ /dev/null @@ -1,12 +0,0 @@ -## --- Day 12: Hot Springs --- -If you are not familiar with the problem, you can read i [here](https://adventofcode.com/2023/day/12). - -A day of memoized functions / dynamic programming. Each line of the input has some pattern (string) and constraints (numbers). Going over the pattern we need to figure out what should be put in the place of the ? symbols so that it satisfies the constraints on the right. How many ways are to satisfy all conditions? - -This cries out for recursion, you can find the details below. - -In Part 2 the input is transformed to something bigger with a process -called `unfolding`. It's the same question as before, the sole -purpose of the unfolding is to force us adding memoization to the -algorithm we came up with in Part 1. - diff --git a/2023/Day12/Solution.cs b/2023/Day12/Solution.cs deleted file mode 100644 index 4207d0786..000000000 --- a/2023/Day12/Solution.cs +++ /dev/null @@ -1,95 +0,0 @@ -namespace AdventOfCode.Y2023.Day12; - -using System; -using System.Collections.Immutable; -using System.Linq; -using Cache = System.Collections.Generic.Dictionary< - (string, System.Collections.Immutable.ImmutableStack), long>; - -[ProblemName("Hot Springs")] -class Solution : Solver { - - public object PartOne(string input) => Solve(input, 1); - public object PartTwo(string input) => Solve(input, 5); - - // After unfolding the input we process it line by line computing the possible - // combinations for each. We use memoized recursion to speed up PartTwo. - // - // The computation is recursive by nature, and goes over the pattern and numbers - // in tandem branching on '?' symbols and consuming as much of dead springs - // as dictated by the next number when a '#' is found. The symbol that follows - // a dead range needs special treatment: it cannot be a '#', and if it was a '?' - // we should consider it as a '.' according to the problem statement. - // - // I like to use immutable datastructures when dealing with problems that - // involves backtracking, it's not immediately obvious from the solution below - // but using a mutable stack or list would cause a lot of headache. - - long Solve(string input, int repeat) => ( - from line in input.Split("\n") - let parts = line.Split(" ") - let pattern = Unfold(parts[0], '?', repeat) - let numString = Unfold(parts[1], ',', repeat) - let nums = numString.Split(',').Select(int.Parse) - select - Compute(pattern, ImmutableStack.CreateRange(nums.Reverse()), new Cache()) - ).Sum(); - - string Unfold(string st, char join, int unfold) => - string.Join(join, Enumerable.Repeat(st, unfold)); - - long Compute(string pattern, ImmutableStack nums, Cache cache) { - if (!cache.ContainsKey((pattern, nums))) { - cache[(pattern, nums)] = Dispatch(pattern, nums, cache); - } - return cache[(pattern, nums)]; - } - - long Dispatch(string pattern, ImmutableStack nums, Cache cache) { - return pattern.FirstOrDefault() switch { - '.' => ProcessDot(pattern, nums, cache), - '?' => ProcessQuestion(pattern, nums, cache), - '#' => ProcessHash(pattern, nums, cache), - _ => ProcessEnd(pattern, nums, cache), - }; - } - - long ProcessEnd(string _, ImmutableStack nums, Cache __) { - // no numbers left at the end of pattern -> good - return nums.Any() ? 0 : 1; - } - - long ProcessDot(string pattern, ImmutableStack nums, Cache cache) { - // consume one spring and recurse - return Compute(pattern[1..], nums, cache); - } - - long ProcessQuestion(string pattern, ImmutableStack nums, Cache cache) { - // recurse both ways - return Compute("." + pattern[1..], nums, cache) + - Compute("#" + pattern[1..], nums, cache); - } - - long ProcessHash(string pattern, ImmutableStack nums, Cache cache) { - // take the first number and consume that many dead springs, recurse - - if (!nums.Any()) { - return 0; // no more numbers left, this is no good - } - - var n = nums.Peek(); - nums = nums.Pop(); - - var potentiallyDead = pattern.TakeWhile(s => s == '#' || s == '?').Count(); - - if (potentiallyDead < n) { - return 0; // not enough dead springs - } else if (pattern.Length == n) { - return Compute("", nums, cache); - } else if (pattern[n] == '#') { - return 0; // dead spring follows the range -> not good - } else { - return Compute(pattern[(n + 1)..], nums, cache); - } - } -} diff --git a/2023/Day12/illustration.jpeg b/2023/Day12/illustration.jpeg deleted file mode 100644 index 21c6ccdb3..000000000 Binary files a/2023/Day12/illustration.jpeg and /dev/null differ diff --git a/2023/Day12/input.in b/2023/Day12/input.in deleted file mode 100644 index c3211f2b3..000000000 Binary files a/2023/Day12/input.in and /dev/null differ diff --git a/2023/Day12/input.refout b/2023/Day12/input.refout deleted file mode 100644 index 0bf985d39..000000000 --- a/2023/Day12/input.refout +++ /dev/null @@ -1,2 +0,0 @@ -7307 -3415570893842 \ No newline at end of file diff --git a/2023/Day13/README.md b/2023/Day13/README.md deleted file mode 100644 index 5ed6b2d66..000000000 --- a/2023/Day13/README.md +++ /dev/null @@ -1,11 +0,0 @@ -## --- Day 13: Point of Incidence --- -Those who need a refresh can read the problem [here](https://adventofcode.com/2023/day/13). - -A mirror is hidden somewhere in a rectangular board (our input). Some of the _rocks_ in the picture are just reflections. -The problem doesn't specify if the mirror is put horizontal or vertical, but we know that it's across the -board from one end to the other and it is not necessarly in the middle. - -Pretty much following the description, I created a function that tries all possible placements and computes how many errors (smudges - using the problem's terminology) were if the mirror was placed right there. Then just selected the one that had zero errors. - -The second half of the problem asked for the very same thing but this time there was one `smudge` in the reflected image. - diff --git a/2023/Day13/Solution.cs b/2023/Day13/Solution.cs deleted file mode 100644 index 075485fcc..000000000 --- a/2023/Day13/Solution.cs +++ /dev/null @@ -1,58 +0,0 @@ -namespace AdventOfCode.Y2023.Day13; - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Numerics; -using Map = System.Collections.Generic.Dictionary; - -[ProblemName("Point of Incidence")] -class Solution : Solver { - - Complex Right = 1; - Complex Down = Complex.ImaginaryOne; - Complex Ortho(Complex dir) => dir == Right ? Down : Right; - - public object PartOne(string input) => Solve(input, 0); - public object PartTwo(string input) => Solve(input, 1); - - double Solve(string input, int allowedSmudges) => ( - from block in input.Split("\n\n") - let map = ParseMap(block) - select GetScore(map, allowedSmudges) - ).Sum(); - - // place a mirror along the edges of the map, find the one with the allowed smudges - double GetScore(Map map, int allowedSmudges) => ( - from dir in new Complex[] { Right, Down } - from mirror in Positions(map, dir, dir) - where FindSmudges(map, mirror, dir) == allowedSmudges - select mirror.Real + 100 * mirror.Imaginary - ).First(); - - // cast a ray from each postion along the mirror and count the smudges - int FindSmudges(Map map, Complex mirror, Complex rayDir) => ( - from ray0 in Positions(map, mirror, Ortho(rayDir)) - let rayA = Positions(map, ray0, rayDir) - let rayB = Positions(map, ray0 - rayDir, -rayDir) - select Enumerable.Zip(rayA, rayB).Count(p => map[p.First] != map[p.Second]) - ).Sum(); - - // allowed positions of the map from 'start' going in 'dir' - IEnumerable Positions(Map map, Complex start, Complex dir) { - for (var pos = start; map.ContainsKey(pos); pos += dir) { - yield return pos; - } - } - - Map ParseMap(string input) { - var rows = input.Split("\n"); - return ( - from irow in Enumerable.Range(0, rows.Length) - from icol in Enumerable.Range(0, rows[0].Length) - let pos = new Complex(icol, irow) - let cell = rows[irow][icol] - select new KeyValuePair(pos, cell) - ).ToDictionary(); - } -} diff --git a/2023/Day13/illustration.jpeg b/2023/Day13/illustration.jpeg deleted file mode 100644 index 034cf2d83..000000000 Binary files a/2023/Day13/illustration.jpeg and /dev/null differ diff --git a/2023/Day13/input.in b/2023/Day13/input.in deleted file mode 100644 index 689e6f0fc..000000000 Binary files a/2023/Day13/input.in and /dev/null differ diff --git a/2023/Day13/input.refout b/2023/Day13/input.refout deleted file mode 100644 index 54d5efd6d..000000000 --- a/2023/Day13/input.refout +++ /dev/null @@ -1,2 +0,0 @@ -33356 -28475 \ No newline at end of file diff --git a/2023/Day14/README.md b/2023/Day14/README.md deleted file mode 100644 index fc7f2eb7b..000000000 --- a/2023/Day14/README.md +++ /dev/null @@ -1,12 +0,0 @@ -## --- Day 14: Parabolic Reflector Dish --- -The task description is copyrighted, but it's available [here](https://adventofcode.com/2023/day/14). - -We are playing Boulder Dash today, but instead of moving a character on the screen -we tilt the `screen` itself and move all the boulders at once. The task asks us to implement tilting -in each directions (North, South, East and West), but I just implemented North and kept rotating -the board by 90 degrees. - -Then we start tilting like crazy - four billion times. When you see _iterate for <a big number>_ you immediately start looking for some repetition. This is not different with today's problem either. In just about a hundred steps the board enters into a loop, so we can jump -over the rest of the tilting work and just read the result out from the list of states we collected. - - diff --git a/2023/Day14/Solution.cs b/2023/Day14/Solution.cs deleted file mode 100644 index 7bc97947b..000000000 --- a/2023/Day14/Solution.cs +++ /dev/null @@ -1,86 +0,0 @@ -namespace AdventOfCode.Y2023.Day14; - -using System; -using System.Collections.Generic; -using System.Linq; -using Map = char[][]; - -[ProblemName("Parabolic Reflector Dish")] -class Solution : Solver { - - public object PartOne(string input) => - Measure(Tilt(Parse(input))); - - public object PartTwo(string input) => - Measure(Iterate(Parse(input), Cycle, 1_000_000_000)); - - Map Parse(string input) => ( - from l in input.Split('\n') select l.ToCharArray() - ).ToArray(); - - int Crow(char[][] map) => map.Length; - int Ccol(char[][] map) => map[0].Length; - - Map Iterate(Map map, Func cycle, int count) { - // The usual trick: keep iterating until we find a loop, make a shortcut - // and read the result from the accumulated history. - var history = new List(); - while (count > 0) { - map = cycle(map); - count--; - - var mapString = string.Join("\n", map.Select(l=> new string(l))); - var idx = history.IndexOf(mapString); - if (idx < 0) { - history.Add(mapString); - } else { - var loopLength = history.Count - idx; - var remainder = count % loopLength; - return Parse(history[idx + remainder]); - } - } - return map; - } - - Map Cycle(Map map) { - for (var i = 0; i < 4; i++) { - map = Rotate(Tilt(map)); - } - return map; - } - - // Tilt the map to the North, so that the 'O' tiles roll to the top. - Map Tilt(Map map) { - for (var icol = 0; icol < Ccol(map); icol++) { - var irowT = 0; // tells where to roll up the next 'O' tile - for (var irowS = 0; irowS < Crow(map); irowS++) { - if (map[irowS][icol] == '#') { - irowT = irowS + 1; - } else if (map[irowS][icol] == 'O') { - map[irowS][icol] = '.'; - map[irowT][icol] = 'O'; - irowT++; - } - } - } - return map; - } - - // Ugly coordinate magic, turns the map 90º clockwise - Map Rotate(Map src) { - var dst = new char[Crow(src)][]; - for (var irow = 0; irow < Ccol(src); irow++) { - dst[irow] = new char[Ccol(src)]; - for (var icol = 0; icol < Crow(src); icol++) { - dst[irow][icol] = src[Crow(src) - icol - 1][irow]; - } - } - return dst; - } - - // returns the cummulated distances of 'O' tiles from the bottom of the map - int Measure(Map map) => - map.Select((row, irow) => - (Crow(map) - irow) * row.Count(ch => ch == 'O') - ).Sum(); -} \ No newline at end of file diff --git a/2023/Day14/illustration.jpeg b/2023/Day14/illustration.jpeg deleted file mode 100644 index 3d5dbea0f..000000000 Binary files a/2023/Day14/illustration.jpeg and /dev/null differ diff --git a/2023/Day14/input.in b/2023/Day14/input.in deleted file mode 100644 index 56cc8b19b..000000000 Binary files a/2023/Day14/input.in and /dev/null differ diff --git a/2023/Day14/input.refout b/2023/Day14/input.refout deleted file mode 100644 index 6e343562a..000000000 --- a/2023/Day14/input.refout +++ /dev/null @@ -1,2 +0,0 @@ -109596 -96105 \ No newline at end of file diff --git a/2023/Day15/README.md b/2023/Day15/README.md deleted file mode 100644 index a714668cb..000000000 --- a/2023/Day15/README.md +++ /dev/null @@ -1,15 +0,0 @@ -## --- Day 15: Lens Library --- -Let's revisit the problem description [here](https://adventofcode.com/2023/day/15). - -Part 1 was super simple. What's funny is that I saw a similar hash algorithm yesterday -in someone else's solution, where he stored the hashes of the visited states instead -of serializing it as a whole. - -For the second part, I created a function that applies one statement to -an array of boxes at hand. The signature is set up so that I can use it to Aggregate -all steps seeded with an initial set of 256 empty boxes. We are transforming boxes -to boxes while applying the steps in a row. The function passed as the third argument -is used to extract the computing power from the final state of the box array. - -I'm describing it in a functional way, but there is no purity under the hood. We -are working with and modifying the same box objects during the process. diff --git a/2023/Day15/Solution.cs b/2023/Day15/Solution.cs deleted file mode 100644 index 6c5b4d1e9..000000000 --- a/2023/Day15/Solution.cs +++ /dev/null @@ -1,48 +0,0 @@ -namespace AdventOfCode.Y2023.Day15; - -using System.Collections.Generic; -using System.Linq; -using Boxes = System.Collections.Generic.List[]; - -record Lens(string label, int focalLength); -record Step(string label, int? focalLength); - -[ProblemName("Lens Library")] -class Solution : Solver { - - public object PartOne(string input) => input.Split(',').Select(Hash).Sum(); - - // "funcionally imperative of imperatively functional", only for 🎄 - public object PartTwo(string input) => - ParseSteps(input).Aggregate(MakeBoxes(256), UpdateBoxes, GetFocusingPower); - - Boxes UpdateBoxes(Boxes boxes, Step step) { - var box = boxes[Hash(step.label)]; - var ilens = box.FindIndex(lens => lens.label == step.label); - - if (!step.focalLength.HasValue && ilens >= 0) { - box.RemoveAt(ilens); - } else if (step.focalLength.HasValue && ilens >= 0) { - box[ilens] = new Lens(step.label, step.focalLength.Value); - } else if (step.focalLength.HasValue && ilens < 0) { - box.Add(new Lens(step.label, step.focalLength.Value)); - } - return boxes; - } - - IEnumerable ParseSteps(string input) => - from item in input.Split(',') - let parts = item.Split('-', '=') - select new Step(parts[0], parts[1] == "" ? null : int.Parse(parts[1])); - - Boxes MakeBoxes(int count) => - Enumerable.Range(0, count).Select(_ => new List()).ToArray(); - - int GetFocusingPower(Boxes boxes) => ( - from ibox in Enumerable.Range(0, boxes.Length) - from ilens in Enumerable.Range(0, boxes[ibox].Count) - select (ibox + 1) * (ilens + 1) * boxes[ibox][ilens].focalLength - ).Sum(); - - int Hash(string st) => st.Aggregate(0, (ch, a) => (ch + a) * 17 % 256); -} diff --git a/2023/Day15/illustration.jpeg b/2023/Day15/illustration.jpeg deleted file mode 100644 index a338e9416..000000000 Binary files a/2023/Day15/illustration.jpeg and /dev/null differ diff --git a/2023/Day15/input.in b/2023/Day15/input.in deleted file mode 100644 index e433a2052..000000000 Binary files a/2023/Day15/input.in and /dev/null differ diff --git a/2023/Day15/input.refout b/2023/Day15/input.refout deleted file mode 100644 index 6ec9969c6..000000000 --- a/2023/Day15/input.refout +++ /dev/null @@ -1,2 +0,0 @@ -519603 -244342 \ No newline at end of file diff --git a/2023/Day16/README.md b/2023/Day16/README.md deleted file mode 100644 index 52e619a8b..000000000 --- a/2023/Day16/README.md +++ /dev/null @@ -1,15 +0,0 @@ -## --- Day 16: The Floor Will Be Lava --- -The original problem description is available [here](https://adventofcode.com/2023/day/16). - -I was a bit worried when I saw Part 1, because it let the window open for a complicated optimization -for Part 2. But it just turned out to be the same thing as Part 1 iterated along the edges of the map. - -I went with the proven strategy and represented the map as a dictionary indexed by complex numbers. It's -easy to check the bounds, and changing positions is just complex arithmetic. - -At first I created a long switch case to determine how a beam changes its way when encountering -mirrors and splitters, but it turns out that in many cases it just continues in the same direction. -Splitting can be handled in just two lines for the vertical and horizontal case. Finally my choice of -the coordinate system makes turning around mirrors very simple: the coordinates flip when the mirror -is facing `\` and just an additional multiplication by -1 is needed for the `/` case. - diff --git a/2023/Day16/Solution.cs b/2023/Day16/Solution.cs deleted file mode 100644 index 4341bda5a..000000000 --- a/2023/Day16/Solution.cs +++ /dev/null @@ -1,78 +0,0 @@ -namespace AdventOfCode.Y2023.Day16; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Numerics; -using Map = System.Collections.Generic.Dictionary; -using Beam = (System.Numerics.Complex pos, System.Numerics.Complex dir); - -[ProblemName("The Floor Will Be Lava")] -class Solution : Solver { - - static readonly Complex Up = -Complex.ImaginaryOne; - static readonly Complex Down = Complex.ImaginaryOne; - static readonly Complex Left = -Complex.One; - static readonly Complex Right = Complex.One; - - public object PartOne(string input) => - EnergizedCells(ParseMap(input), (Complex.Zero, Right)); - - public object PartTwo(string input) { - var map = ParseMap(input); - return (from beam in StartBeams(map) select EnergizedCells(map, beam)).Max(); - } - - // follow the beam in the map and return the energized cell count. - int EnergizedCells(Map map, Beam beam) { - - // this is essentially just a flood fill algorithm. - var q = new Queue([beam]); - var seen = new HashSet(); - - while (q.TryDequeue(out beam)) { - seen.Add(beam); - foreach (var dir in Exits(map[beam.pos], beam.dir)) { - var pos = beam.pos + dir; - if (map.ContainsKey(pos) && !seen.Contains((pos, dir))) { - q.Enqueue((pos, dir)); - } - } - } - - return seen.Select(beam => beam.pos).Distinct().Count(); - } - - // go around the edges (top, right, bottom, left order) of the map - // and return the inward pointing directions - IEnumerable StartBeams(Map map) { - var br = map.Keys.MaxBy(pos => pos.Imaginary + pos.Real); - return [ - ..from pos in map.Keys where pos.Real == 0 select (pos, Down), - ..from pos in map.Keys where pos.Real == br.Real select (pos, Left), - ..from pos in map.Keys where pos.Imaginary == br.Imaginary select (pos, Up), - ..from pos in map.Keys where pos.Imaginary == 0 select (pos, Right), - ]; - } - - // using a dictionary helps with bounds check (simply containskey): - Map ParseMap(string input) { - var lines = input.Split('\n'); - return ( - from irow in Enumerable.Range(0, lines.Length) - from icol in Enumerable.Range(0, lines[0].Length) - let cell = lines[irow][icol] - let pos = new Complex(icol, irow) - select new KeyValuePair(pos, cell) - ).ToDictionary(); - } - - // the 'exit' direction(s) of the given cell when entered by a beam moving in 'dir' - // we have some special cases for mirrors and spliters, the rest keeps the direction - Complex[] Exits(char cell, Complex dir) => cell switch { - '-' when dir == Up || dir == Down => [Left, Right], - '|' when dir == Left || dir == Right => [Up, Down], - '/' => [-new Complex(dir.Imaginary, dir.Real)], - '\\' => [new Complex(dir.Imaginary, dir.Real)], - _ => [dir] - }; -} \ No newline at end of file diff --git a/2023/Day16/illustration.jpeg b/2023/Day16/illustration.jpeg deleted file mode 100644 index bd921cad4..000000000 Binary files a/2023/Day16/illustration.jpeg and /dev/null differ diff --git a/2023/Day16/input.in b/2023/Day16/input.in deleted file mode 100644 index 54c266772..000000000 Binary files a/2023/Day16/input.in and /dev/null differ diff --git a/2023/Day16/input.refout b/2023/Day16/input.refout deleted file mode 100644 index be1b44a9f..000000000 --- a/2023/Day16/input.refout +++ /dev/null @@ -1,2 +0,0 @@ -7623 -8244 \ No newline at end of file diff --git a/2023/Day17/README.md b/2023/Day17/README.md deleted file mode 100644 index ec0988c79..000000000 --- a/2023/Day17/README.md +++ /dev/null @@ -1,12 +0,0 @@ -## --- Day 17: Clumsy Crucible --- -Visit the Advent of Code website for the problem statement [here](https://adventofcode.com/2023/day/17). - -Part 1 and Part 2 differ only in the rules for the small and ultra crucibles. And it turns -out those can be represented by just two integers: one for the minimum steps the crucible -needs to move forward before it can make a turn (or stop), and an other one that puts an -upper limit on the distance it can go in a straight line. - -The algorithmic part is a pretty standard graph search implemented with a priority queue. -If you've seen one, you've seen them all. We are starting from the top left corner with the -only `goal` state in the bottom right. Since we are minimizing for heatloss, we can use -that as the priority of the queue items. diff --git a/2023/Day17/Solution.cs b/2023/Day17/Solution.cs deleted file mode 100644 index 08db1b1d4..000000000 --- a/2023/Day17/Solution.cs +++ /dev/null @@ -1,70 +0,0 @@ -namespace AdventOfCode.Y2023.Day17; - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Numerics; -using Map = System.Collections.Generic.Dictionary; - -record Crucible(Complex pos, Complex dir, int straight); - -[ProblemName("Clumsy Crucible")] -class Solution : Solver { - - public object PartOne(string input) => Heatloss(input, 0, 3); - public object PartTwo(string input) => Heatloss(input, 4, 10); - - // Graph search using a priority queue. We can simply store the heatloss in - // the priority. - int Heatloss(string input, int minStraight, int maxStraight) { - var map = ParseMap(input); - var goal = map.Keys.MaxBy(pos => pos.Imaginary + pos.Real); - var q = new PriorityQueue(); - - // initial direction: right or down - q.Enqueue(new Crucible(pos: 0, dir: 1, straight: 0), 0); - q.Enqueue(new Crucible(pos: 0, dir: Complex.ImaginaryOne, straight: 0), 0); - - var seen = new HashSet(); - while (q.TryDequeue(out var crucible, out var heatloss)) { - if (crucible.pos == goal && crucible.straight >= minStraight) { - return heatloss; - } - foreach (var next in Moves(crucible, minStraight, maxStraight)) { - if (map.ContainsKey(next.pos) && !seen.Contains(next)) { - seen.Add(next); - q.Enqueue(next, heatloss + map[next.pos]); - } - } - } - throw new Exception(); - } - - // returns possible next states based on the rules - IEnumerable Moves(Crucible c, int minStraight, int maxStraight) { - if (c.straight < maxStraight) { - yield return c with { - pos = c.pos + c.dir, - straight = c.straight + 1 - }; - } - - if (c.straight >= minStraight) { - var dir = c.dir * Complex.ImaginaryOne; - yield return new Crucible(c.pos + dir, dir, 1); - yield return new Crucible(c.pos - dir, -dir, 1); - } - } - - // using a dictionary helps with bounds check (simply containskey): - Map ParseMap(string input) { - var lines = input.Split('\n'); - return ( - from irow in Enumerable.Range(0, lines.Length) - from icol in Enumerable.Range(0, lines[0].Length) - let cell = int.Parse(lines[irow].Substring(icol, 1)) - let pos = new Complex(icol, irow) - select new KeyValuePair(pos, cell) - ).ToDictionary(); - } -} \ No newline at end of file diff --git a/2023/Day17/illustration.jpeg b/2023/Day17/illustration.jpeg deleted file mode 100644 index 8c04f08d7..000000000 Binary files a/2023/Day17/illustration.jpeg and /dev/null differ diff --git a/2023/Day17/input.in b/2023/Day17/input.in deleted file mode 100644 index 706ddbce2..000000000 Binary files a/2023/Day17/input.in and /dev/null differ diff --git a/2023/Day17/input.refout b/2023/Day17/input.refout deleted file mode 100644 index 702b1c1fe..000000000 --- a/2023/Day17/input.refout +++ /dev/null @@ -1,2 +0,0 @@ -767 -904 \ No newline at end of file diff --git a/2023/Day18/README.md b/2023/Day18/README.md deleted file mode 100644 index ba58b5b0c..000000000 --- a/2023/Day18/README.md +++ /dev/null @@ -1,24 +0,0 @@ -## --- Day 18: Lavaduct Lagoon --- -If you are not familiar with the problem, you can read it [here](https://adventofcode.com/2023/day/18). - -Both parts ask for the integer area covered by some polygon. But it -wouldn't be Advent of Code, if the polygon came in the form of coordinates. -First we are dealing with some odd _dig_ instruction list with _hex colors_. - -The polygon in Part 1 is much smaller and one can use any algorithm from flood fill -to ray casting, but Part 2 makes it clear that we need to pull out the bigger guns. - -I heard about the [Shoelace formula](https://en.wikipedia.org/wiki/Shoelace_formula), but haven't used it in practice yet. I knew -that I can calculate the (signed) area of a polygon by summing up some determinants -using the neighbouring vertices. But I haven't heard about [Pick's theorem](https://en.wikipedia.org/wiki/Pick%27s_theorem) before, so -it made me think for a while to extend this idea to return the _integer_ area instead -of the _real_ one. - -Having solved Part 1 I could somehow guess the right formula involving _half the -boundary plus 1_, which sounds just _right_ and was enough for Part 2, then still -being puzzled I went to the solution thread and read about Pick. - -Pick's theorem connects the area returned by the Shoelace formula with the number -of _interior points_ and _points in the boundary_. The problem asked for the sum of these. - -I give myself an extra ⭐ for learning something today. diff --git a/2023/Day18/Solution.cs b/2023/Day18/Solution.cs deleted file mode 100644 index 95547af27..000000000 --- a/2023/Day18/Solution.cs +++ /dev/null @@ -1,68 +0,0 @@ -namespace AdventOfCode.Y2023.Day18; - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Numerics; - -[ProblemName("Lavaduct Lagoon")] -class Solution : Solver { - - public object PartOne(string input) => Area(Steps1(input)); - public object PartTwo(string input) => Area(Steps2(input)); - - IEnumerable Steps1(string input) => - from line in input.Split('\n') - let parts = line.Split(' ') - let dir = parts[0] switch { - "R" => Complex.One, - "U" => -Complex.ImaginaryOne, - "L" => -Complex.One, - "D" => Complex.ImaginaryOne, - _ => throw new Exception() - } - let dist = int.Parse(parts[1]) - select dir * dist; - - IEnumerable Steps2(string input) => - from line in input.Split('\n') - let hex = line.Split(' ')[2] - let dir = hex[7] switch { - '0' => Complex.One, - '1' => -Complex.ImaginaryOne, - '2' => -Complex.One, - '3' => Complex.ImaginaryOne, - _ => throw new Exception() - } - let dist = Convert.ToInt32(hex[2..7], 16) - select dir * dist; - - // We are using a combination of the shoelace formula with Pick's theorem - double Area(IEnumerable steps) { - var vertices = Vertices(steps).ToList(); - - // Shoelace formula https://en.wikipedia.org/wiki/Shoelace_formula - var shiftedVertices = vertices.Skip(1).Append(vertices[0]); - var shoelaces = - from points in vertices.Zip(shiftedVertices) - let p1 = points.First - let p2 = points.Second - select p1.Real * p2.Imaginary - p1.Imaginary * p2.Real; - var area = Math.Abs(shoelaces.Sum()) / 2; - - // Pick's theorem https://en.wikipedia.org/wiki/Pick%27s_theorem - var boundary = steps.Select(x => x.Magnitude).Sum(); - var interior = area - boundary / 2 + 1; - - // Integer area - return boundary + interior; - } - - IEnumerable Vertices(IEnumerable steps) { - var pos = Complex.Zero; - foreach (var step in steps) { - pos += step; - yield return pos; - } - } -} \ No newline at end of file diff --git a/2023/Day18/illustration.jpeg b/2023/Day18/illustration.jpeg deleted file mode 100644 index 2d45b35ee..000000000 Binary files a/2023/Day18/illustration.jpeg and /dev/null differ diff --git a/2023/Day18/input.in b/2023/Day18/input.in deleted file mode 100644 index 265d68ef7..000000000 Binary files a/2023/Day18/input.in and /dev/null differ diff --git a/2023/Day18/input.refout b/2023/Day18/input.refout deleted file mode 100644 index 1cd59a4b6..000000000 --- a/2023/Day18/input.refout +++ /dev/null @@ -1,2 +0,0 @@ -42317 -83605563360288 \ No newline at end of file diff --git a/2023/Day19/README.md b/2023/Day19/README.md deleted file mode 100644 index 87fc6516b..000000000 --- a/2023/Day19/README.md +++ /dev/null @@ -1,26 +0,0 @@ -## --- Day 19: Aplenty --- -Those who need a refresh can read the problem [here](https://adventofcode.com/2023/day/19). - -Part 1 is an _implementation_ challenge, where you need to model some virtual -machine following certain rules. I jumped on that and wrote it while sipping my -morning coffee. But this is Day 19 and there _has to be a twist_. We got a totally -different challenge for the second half. It's like opening your calendar and -finding two chocolates instead of one. Yay! - -Part 2 looks frightening first, but not for a seasoned Advent of Coder with -multiple dimension travels behind his back. It's asking for the volume of a -hypercube. Don't believe? Think about it. We start from a 4000 x 4000 x 4000 x 4000 -cube and slice it up to smaller parts based on the conditions we are given. -(It becomes more of a hyperectangle during this process, but let's not be picky -about names.) At the end we get to some smallish cubes which are either -_Accepted_ or fully _Rejected_. This algorithm is a bit -similar to what we did in Day 5 and I tried to code it like that. - -Just follow the instructions precisely and Part 2 is tamed. To clean things up a -bit, we can even reuse this to implement Part 1. (So much about our nice -interpreter from the morning.) Go over the list of parts as they were tiny -1 x 1 x 1 x 1 cubes and check if they are accepted or not. - -The code is the longest I've written so far, but it's hopefully readable -after this introduction. - diff --git a/2023/Day19/Solution.cs b/2023/Day19/Solution.cs deleted file mode 100644 index c6841d723..000000000 --- a/2023/Day19/Solution.cs +++ /dev/null @@ -1,109 +0,0 @@ -namespace AdventOfCode.Y2023.Day19; - -using System; -using System.Collections.Generic; -using System.Collections.Immutable; -using System.Linq; -using System.Text.RegularExpressions; -using System.Numerics; -using Rules = System.Collections.Generic.Dictionary; -using Cube = System.Collections.Immutable.ImmutableArray; - -record Range(int begin, int end); -record Cond(int dim, char op, int num, string state); - -[ProblemName("Aplenty")] -class Solution : Solver { - - // Part 1 can be understood in the context of Part 2. Part 2 asks to compute - // the accepted volume of a four dimensional hypercube. It has some elaborate - // way to slice up the cube parallel to its edges to smaller and smaller pieces - // and decide if the final sub-sub cubes are accepted or not. Our Part 2 - // algorithm follows these rules and returns the 'accepted'volume we are - // looking for. - - // We can use this algorithm to solve Part 1 starting from unit sized cubes - // and checking if they are fully accepted or not. - - public object PartOne(string input) { - var parts = input.Split("\n\n"); - var rules = ParseRules(parts[0]); - return ( - from cube in ParseUnitCube(parts[1]) - where AcceptedVolume(rules, cube) == 1 - select cube.Select(r => r.begin).Sum() - ).Sum(); - } - - public object PartTwo(string input) { - var parts = input.Split("\n\n"); - var rules = ParseRules(parts[0]); - var cube = Enumerable.Repeat(new Range(1, 4000), 4).ToImmutableArray(); - return AcceptedVolume(rules, cube); - } - - BigInteger AcceptedVolume(Rules rules, Cube cube) { - var q = new Queue<(Cube cube, string state)>(); - q.Enqueue((cube, "in")); - - BigInteger res = 0; - while (q.Any()) { - (cube, var state) = q.Dequeue(); - if (cube.Any(coord => coord.end < coord.begin)) { - continue; // cube is empty - } else if (state == "R") { - continue; // cube is rejected - } else if (state == "A") { - res += Volume(cube); // cube is accepted - } else { - foreach (var stm in rules[state].Split(",")) { - Cond cond = TryParseCond(stm); - if (cond == null) { - q.Enqueue((cube, stm)); - } else if (cond.op == '<') { - var (cube1, cube2) = CutCube(cube, cond.dim, cond.num - 1); - q.Enqueue((cube1, cond.state)); - cube = cube2; - } else if (cond?.op == '>') { - var (cube1, cube2) = CutCube(cube, cond.dim, cond.num); - cube = cube1; - q.Enqueue((cube2, cond.state)); - } - } - } - } - return res; - } - - BigInteger Volume(Cube cube) => - cube.Aggregate(BigInteger.One, (m, r) => m * (r.end - r.begin + 1)); - - // Cuts a cube along the specified dimension, other dimensions are unaffected. - (Cube lo, Cube hi) CutCube(Cube cube, int dim, int num) { - var r = cube[dim]; - return ( - cube.SetItem(dim, r with { end = Math.Min(num, r.end) }), - cube.SetItem(dim, r with { begin = Math.Max(r.begin, num + 1) }) - ); - } - - Cond TryParseCond(string st) => - st.Split('<', '>', ':') switch { - ["x", var num, var state] => new Cond(0, st[1], int.Parse(num), state), - ["m", var num, var state] => new Cond(1, st[1], int.Parse(num), state), - ["a", var num, var state] => new Cond(2, st[1], int.Parse(num), state), - ["s", var num, var state] => new Cond(3, st[1], int.Parse(num), state), - _ => null - }; - - Rules ParseRules(string input) => ( - from line in input.Split('\n') - let parts = line.Split('{', '}') - select new KeyValuePair(parts[0], parts[1]) - ).ToDictionary(); - - IEnumerable ParseUnitCube(string input) => - from line in input.Split('\n') - let nums = Regex.Matches(line, @"\d+").Select(m => int.Parse(m.Value)) - select nums.Select(n => new Range(n, n)).ToImmutableArray(); -} \ No newline at end of file diff --git a/2023/Day19/illustration.jpeg b/2023/Day19/illustration.jpeg deleted file mode 100644 index bc8956993..000000000 Binary files a/2023/Day19/illustration.jpeg and /dev/null differ diff --git a/2023/Day19/input.in b/2023/Day19/input.in deleted file mode 100644 index b5033d617..000000000 Binary files a/2023/Day19/input.in and /dev/null differ diff --git a/2023/Day19/input.refout b/2023/Day19/input.refout deleted file mode 100644 index 438c2f996..000000000 --- a/2023/Day19/input.refout +++ /dev/null @@ -1,2 +0,0 @@ -346230 -124693661917133 \ No newline at end of file diff --git a/2023/Day20/README.md b/2023/Day20/README.md deleted file mode 100644 index 607ee92ad..000000000 --- a/2023/Day20/README.md +++ /dev/null @@ -1,24 +0,0 @@ -## --- Day 20: Pulse Propagation --- -The task description is copyrighted, but it's available [here](https://adventofcode.com/2023/day/20). - -I modeled Part 1 following the description closely. I didn't want to introduce separate -classes for the gate types, instead created just one Gate type with a function parameter that defines the inner logic. It basically tells what should be emitted when a signal comes in the gate's input. - -Building on this, I defined factory functions for each -gate type (Nand, FlipFlop and Repeater). I know that this is -Elf logic, but it's 🎄, what did you expect? - -I added a function that triggers the button and executes all the logic until things settle down. -It returns all signals that were emitted, so that I can work with them in both parts. - -I think Part 1 doesn't need more explanation. Part 2 however, is a different beast. It's a _reverse -engineering_ problem. We need to tell how many times the button is to be pressed until a -single _high_ value is emitted to the `rx` gate. The catch is that we need to understand a -bit what's happening, because just blindly pressing the button will not terminate in a reasonable time. - -I layed out the graph using Graphviz to see what's going on. This immediately showed that -`broadcaster` feeds four different subgraphs. These work in isolation and a Nand gate -connects their output into `rx`. Further investigation shows that each subgraph runs in a loop -that has prime length (at least for my input). We just need to multiply -them to solve the second half of the problem. - diff --git a/2023/Day20/Solution.cs b/2023/Day20/Solution.cs deleted file mode 100644 index 7840377b2..000000000 --- a/2023/Day20/Solution.cs +++ /dev/null @@ -1,112 +0,0 @@ -namespace AdventOfCode.Y2023.Day20; - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text.RegularExpressions; -using Signal = (string sender, string receiver, bool value); - -record Gate(string[] inputs, Func> handle); - -[ProblemName("Pulse Propagation")] -class Solution : Solver { - - public object PartOne(string input) { - var gates = ParseGates(input); - var values = ( - from _ in Enumerable.Range(0, 1000) - from signal in Trigger(gates) - select signal.value - ).ToArray(); - return values.Count(v => v) * values.Count(v => !v); - } - - public object PartTwo(string input) { - // The input has a special structure. Broadcaster feeds 4 disconnected - // substructures which are channeled into a single nand gate at the end. - // The nand gate is connected into rx. I checked that the substructures - // work in a loop, that has prime length. Just need to multiply them all. - var gates = ParseGates(input); - var nand = gates["rx"].inputs.Single(); - var branches = gates[nand].inputs; - return branches.Aggregate(1L, (m, branch) => m * LoopLength(input, branch)); - } - - int LoopLength(string input, string output) { - var gates = ParseGates(input); - for (var i = 1; ; i++) { - var signals = Trigger(gates); - if (signals.Any(s => s.sender == output && s.value)) { - return i; - } - } - } - - // emits a button press, executes until things settle down and returns - // all signals for investigation. - IEnumerable Trigger(Dictionary gates) { - var q = new Queue(); - q.Enqueue(new Signal("button", "broadcaster", false)); - - while (q.TryDequeue(out var signal)) { - yield return signal; - - var handler = gates[signal.receiver]; - foreach (var signalT in handler.handle(signal)) { - q.Enqueue(signalT); - } - } - } - - Dictionary ParseGates(string input) { - input += "\nrx ->"; // an extra rule for rx with no output - - var descriptions = - from line in input.Split('\n') - let words = Regex.Matches(line, "\\w+").Select(m => m.Value).ToArray() - select (kind: line[0], name: words.First(), outputs: words[1..]); - - var inputs = (string name) => ( - from d in descriptions where d.outputs.Contains(name) select d.name - ).ToArray(); - - return descriptions.ToDictionary( - d => d.name, - d => d.kind switch { - '&' => NandGate(d.name, inputs(d.name), d.outputs), - '%' => FlipFlop(d.name, inputs(d.name), d.outputs), - _ => Repeater(d.name, inputs(d.name), d.outputs) - } - ); - } - - Gate NandGate(string name, string[] inputs, string[] outputs) { - // initially assign low value for each input: - var state = inputs.ToDictionary(input => input, _ => false); - - return new Gate(inputs, (Signal signal) => { - state[signal.sender] = signal.value; - var value = !state.Values.All(b => b); - return outputs.Select(o => new Signal(name, o, value)); - }); - } - - Gate FlipFlop(string name, string[] inputs, string[] outputs) { - var state = false; - - return new Gate(inputs, (Signal signal) => { - if (!signal.value) { - state = !state; - return outputs.Select(o => new Signal(name, o, state)); - } else { - return []; - } - }); - } - - Gate Repeater(string name, string[] inputs, string[] outputs) { - return new Gate(inputs, (Signal s) => - from o in outputs select new Signal(name, o, s.value) - ); - } -} \ No newline at end of file diff --git a/2023/Day20/illustration.jpeg b/2023/Day20/illustration.jpeg deleted file mode 100644 index 772a67c58..000000000 Binary files a/2023/Day20/illustration.jpeg and /dev/null differ diff --git a/2023/Day20/input.in b/2023/Day20/input.in deleted file mode 100644 index 9c8a997b9..000000000 Binary files a/2023/Day20/input.in and /dev/null differ diff --git a/2023/Day20/input.refout b/2023/Day20/input.refout deleted file mode 100644 index 92c71f358..000000000 --- a/2023/Day20/input.refout +++ /dev/null @@ -1,2 +0,0 @@ -949764474 -243221023462303 \ No newline at end of file diff --git a/2023/Day21/README.md b/2023/Day21/README.md deleted file mode 100644 index e92e3fc0b..000000000 --- a/2023/Day21/README.md +++ /dev/null @@ -1,46 +0,0 @@ -## --- Day 21: Step Counter --- -Let's revisit the problem description [here](https://adventofcode.com/2023/day/21). - -At first I solved this with carefully maintaining the number of different -tiles (the 131x131 regions that repeat indefinitely) after each step. It -turns out that there are only nine tile categories based on the direction -closest to the starting point. The elf can go straight left, up, right -and down and reach the next tile without obstacles. This is a special -property of the input. - -Each tile in a category can be in a few hundred different states. The -first one (what I call the _seed_) is the point where the elf enters the -tile. This can be the center of an edge or one of its corners. After -seeding, the tile _ages_ on its own pace. Thanks to an other property of -the input, tiles are not affected by their neighbourhood. Aging continues -until a tile _grows_ up, when it starts to oscillate between just two -states back and forth. - -My first solution involved a 9 by 260 matrix containing the number of -tiles in each state. I implemented the aging process and carefully -computed when to seed new tiles for each category. - -It turns out that if we are looking at only steps where `n = 131 * k + 65` -we can compute how many tiles are in each position of the matrix. -I haven't gone through this whole process, just checked a few examples -until I convinced myself that each and every item in the matrix is either -constant or a linear or quadratic function of n. - -This is not that hard to see as it sounds. After some lead in at the -beginning, things start to work like this: in each batch of 131 steps a -set of center tiles and a set of corner styles is generated. -Always 4 center tiles come in, but corner tiles are linear in `n: 1,2,3...` -That is the grown up population for center tiles must be linear in `n`, -and quadratic for the corners (can be computed using triangular numbers). - -If we know the active positions for each tile category and state, we -can multiply it with the number of tiles and sum it up to get the result. -This all means that if we reorganize the equations we get to a form of: - -``` - a * n^2 + b * n + c if n = k * 131 + 65 -``` - -We just need to compute this polynom for 3 values and interpolate. -Finally evaluate for `n = 26501365` which happens to be `202300 * 131 + 65` -to get the final result. diff --git a/2023/Day21/Solution.cs b/2023/Day21/Solution.cs deleted file mode 100644 index 57702b2a9..000000000 --- a/2023/Day21/Solution.cs +++ /dev/null @@ -1,68 +0,0 @@ -namespace AdventOfCode.Y2023.Day21; - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Numerics; - -[ProblemName("Step Counter")] -class Solution : Solver { - - public object PartOne(string input) => Steps(ParseMap(input)).ElementAt(64); - public object PartTwo(string input) { - // Exploiting some nice properties of the input it reduces to quadratic - // interpolation over 3 points: k * 131 + 65 for k = 0, 1, 2 - // I used the Newton method. - var steps = Steps(ParseMap(input)).Take(328).ToArray(); - - (decimal x0, decimal y0) = (65, steps[65]); - (decimal x1, decimal y1) = (196, steps[196]); - (decimal x2, decimal y2) = (327, steps[327]); - - decimal y01 = (y1 - y0) / (x1 - x0); - decimal y12 = (y2 - y1) / (x2 - x1); - decimal y012 = (y12 - y01) / (x2 - x0); - - var n = 26501365; - return decimal.Round(y0 + y01 * (n - x0) + y012 * (n - x0) * (n - x1)); - } - - // walks around and returns the number of available positions at each step - IEnumerable Steps(HashSet map) { - var positions = new HashSet { new Complex(65, 65) }; - while(true) { - yield return positions.Count; - positions = Step(map, positions); - } - } - - HashSet Step(HashSet map, HashSet positions) { - Complex[] dirs = [1, -1, Complex.ImaginaryOne, -Complex.ImaginaryOne]; - - var res = new HashSet(); - foreach (var pos in positions) { - foreach (var dir in dirs) { - var posT = pos + dir; - var tileCol = Mod(posT.Real, 131); - var tileRow = Mod(posT.Imaginary, 131); - if (map.Contains(new Complex(tileCol, tileRow))) { - res.Add(posT); - } - } - } - return res; - } - - // the double % takes care of negative numbers - double Mod(double n, int m) => ((n % m) + m) % m; - - HashSet ParseMap(string input) { - var lines = input.Split("\n"); - return ( - from irow in Enumerable.Range(0, lines.Length) - from icol in Enumerable.Range(0, lines[0].Length) - where lines[irow][icol] != '#' - select new Complex(icol, irow) - ).ToHashSet(); - } -} diff --git a/2023/Day21/illustration.jpeg b/2023/Day21/illustration.jpeg deleted file mode 100644 index 843c9e1ce..000000000 Binary files a/2023/Day21/illustration.jpeg and /dev/null differ diff --git a/2023/Day21/input.in b/2023/Day21/input.in deleted file mode 100644 index 85de8fe42..000000000 Binary files a/2023/Day21/input.in and /dev/null differ diff --git a/2023/Day21/input.refout b/2023/Day21/input.refout deleted file mode 100644 index 3904a7379..000000000 --- a/2023/Day21/input.refout +++ /dev/null @@ -1,2 +0,0 @@ -3751 -619407349431167 \ No newline at end of file diff --git a/2023/Day22/README.md b/2023/Day22/README.md deleted file mode 100644 index 074a83e8e..000000000 --- a/2023/Day22/README.md +++ /dev/null @@ -1,19 +0,0 @@ -## --- Day 22: Sand Slabs --- -The original problem description is available -[here](https://adventofcode.com/2023/day/22). - -We deserved a simple one today. I started with a function that applies gravity to -the blocks. It orders them in ascending Z order then just runs over the list and -pushes each block down as much as possible. The result is a nicely packed jenga tower. - -Several helper strucures were introduced to make things easier. I have a `Range` and -a `Block` with some helpers like `IntersectsXY` that tells if the X-Y projection of -two blocks are in cover. - -I also created a function that returns the _support structure_ of our model at hand, -so that I can tell the upper and lower neighbours of each block easily. - -The eye catching _Kaboom_ function goes over the input and selects each block for -desintegration. It calculates the number of blocks that start falling when this -single block disappears. The result is a list of integers, which can be used -to answer both questions for today. diff --git a/2023/Day22/Solution.cs b/2023/Day22/Solution.cs deleted file mode 100644 index af46562ca..000000000 --- a/2023/Day22/Solution.cs +++ /dev/null @@ -1,102 +0,0 @@ -namespace AdventOfCode.Y2023.Day22; - -using System; -using System.Collections.Generic; -using System.Linq; - -record Range(int begin, int end); -record Block(Range x, Range y, Range z) { - public int Top => z.end; - public int Bottom => z.begin; -} -record Supports( - Dictionary> blocksAbove, - Dictionary> blocksBelow -); - -[ProblemName("Sand Slabs")] -class Solution : Solver { - - public object PartOne(string input) => Kaboom(input).Count(x => x == 0); - public object PartTwo(string input) => Kaboom(input).Sum(); - - // desintegrates the blocks one by one and returns how many blocks would - // start falling because of that. - IEnumerable Kaboom(string input) { - var blocks = Fall(ParseBlocks(input)); - var supports = GetSupports(blocks); - - foreach (var desintegratedBlock in blocks) { - var q = new Queue(); - q.Enqueue(desintegratedBlock); - - var falling = new HashSet(); - while (q.TryDequeue(out var block)) { - falling.Add(block); - - var blocksStartFalling = - from blockT in supports.blocksAbove[block] - where supports.blocksBelow[blockT].IsSubsetOf(falling) - select blockT; - - foreach (var blockT in blocksStartFalling) { - q.Enqueue(blockT); - } - } - yield return falling.Count - 1; // -1: desintegratedBlock doesn't count - } - } - - // applies 'gravity' to the blocks. - Block[] Fall(Block[] blocks) { - - // sort them in Z first so that we can work in bottom to top order - blocks = blocks.OrderBy(block => block.Bottom).ToArray(); - - for (var i = 0; i < blocks.Length; i++) { - var newBottom = 1; - for (var j = 0; j < i; j++) { - if (IntersectsXY(blocks[i], blocks[j])) { - newBottom = Math.Max(newBottom, blocks[j].Top + 1); - } - } - var fall = blocks[i].Bottom - newBottom; - blocks[i] = blocks[i] with { - z = new Range(blocks[i].Bottom - fall, blocks[i].Top - fall) - }; - } - return blocks; - } - - // calculate upper and lower neighbours for each block - Supports GetSupports(Block[] blocks) { - var blocksAbove = blocks.ToDictionary(b => b, _ => new HashSet()); - var blocksBelow = blocks.ToDictionary(b => b, _ => new HashSet()); - for (var i = 0; i < blocks.Length; i++) { - for (var j = i + 1; j < blocks.Length; j++) { - var zNeighbours = blocks[j].Bottom == 1 + blocks[i].Top; - if (zNeighbours && IntersectsXY(blocks[i], blocks[j])) { - blocksBelow[blocks[j]].Add(blocks[i]); - blocksAbove[blocks[i]].Add(blocks[j]); - } - } - } - return new Supports(blocksAbove, blocksBelow); - } - - bool IntersectsXY(Block blockA, Block blockB) => - Intersects(blockA.x, blockB.x) && Intersects(blockA.y, blockB.y); - - // see https://stackoverflow.com/a/3269471 - bool Intersects(Range r1, Range r2) => r1.begin <= r2.end && r2.begin <= r1.end; - - Block[] ParseBlocks(string input) => ( - from line in input.Split('\n') - let numbers = line.Split(',','~').Select(int.Parse).ToArray() - select new Block( - x: new Range(numbers[0], numbers[3]), - y: new Range(numbers[1], numbers[4]), - z: new Range(numbers[2], numbers[5]) - ) - ).ToArray(); -} \ No newline at end of file diff --git a/2023/Day22/illustration.jpeg b/2023/Day22/illustration.jpeg deleted file mode 100644 index 135992b9f..000000000 Binary files a/2023/Day22/illustration.jpeg and /dev/null differ diff --git a/2023/Day22/input.in b/2023/Day22/input.in deleted file mode 100644 index 004f71c7a..000000000 Binary files a/2023/Day22/input.in and /dev/null differ diff --git a/2023/Day22/input.refout b/2023/Day22/input.refout deleted file mode 100644 index 6edcd6304..000000000 --- a/2023/Day22/input.refout +++ /dev/null @@ -1,2 +0,0 @@ -503 -98431 \ No newline at end of file diff --git a/2023/Day23/README.md b/2023/Day23/README.md deleted file mode 100644 index 43bc27740..000000000 --- a/2023/Day23/README.md +++ /dev/null @@ -1,26 +0,0 @@ -## --- Day 23: A Long Walk --- -Visit the Advent of Code website for the problem statement [here](https://adventofcode.com/2023/day/23). - -Today's problem looked frightening first, because it's asking for the _longest_ -path between two points of a map. Shortest path is a no brainer with _Dijkstra_ -or whatever _graph search_, but I don't know about an efficient way to calculate -the longest one. I have a feeling that it is somehow related to the _Hamiltonian path_ -which is NP-complete, so there might not even exists a super efficient algorithm to -solve today's problem in the generic case. - -But this is a puzzle, so let's get to it. I decided to convert the problem from -map traversal to graph traversal first. Created _nodes_ from the _crossroads_ of -the map (those tiles that connect 3 or more `"."` cells). Also assigned a node to -the entry and one to the exit. - -Two nodes become _connected_ if there is a _road_ between them. That is, they are -reachable following the _path_ in the map without visiting other crossroads in -between. - -This reduced the problem quite a bit. In my case it went down to about 30 nodes -and 120 edges for Part 2. Part 1 is even smaller with 60 edges or so. - -This graph is small enough to solve it using _dynamic programming_ with a _cache_. -Since we have just 30+ nodes, I represented them as _powers of 2_ and a set of -these became a _bitset_ stored in a _long_. - diff --git a/2023/Day23/Solution.cs b/2023/Day23/Solution.cs deleted file mode 100644 index 6a21dfd27..000000000 --- a/2023/Day23/Solution.cs +++ /dev/null @@ -1,129 +0,0 @@ -namespace AdventOfCode.Y2023.Day23; - -using System; -using System.Collections.Generic; -using System.Numerics; -using System.Linq; -using Map = System.Collections.Generic.Dictionary; -using Node = long; -record Edge(Node start, Node end, int distance); - -[ProblemName("A Long Walk")] -class Solution : Solver { - - // Instead of dealing with the 'map' tiles directly, we convert it to a graph. - // Nodes: the entry tile, the exit and the crossroad tiles. - // Edges: two nodes are connected if there is a direct path between them that - // doesn't contain crossroads. - // This reduces a problem to ~30 nodes and 120 edges for the Part 2 case - // which can be solved using a dynamic programming approach. - - static readonly Complex Up = -Complex.ImaginaryOne; - static readonly Complex Down = Complex.ImaginaryOne; - static readonly Complex Left = -1; - static readonly Complex Right = 1; - static readonly Complex[] Dirs = [Up, Down, Left, Right]; - - Dictionary exits = new() { - ['<'] = [Left], - ['>'] = [Right], - ['^'] = [Up], - ['v'] = [Down], - ['.'] = Dirs, - ['#'] = [] - }; - - public object PartOne(string input) => Solve(input); - public object PartTwo(string input) => Solve(RemoveSlopes(input)); - - string RemoveSlopes(string st) => - string.Join("", st.Select(ch => ">v<^".Contains(ch) ? '.' : ch)); - - int Solve(string input) { - var (nodes, edges) = MakeGraph(input); - var (start, goal) = (nodes.First(), nodes.Last()); - - // Dynamic programming using a cache, 'visited' is a bitset of 'nodes'. - var cache = new Dictionary<(Node, long), int>(); - int LongestPath(Node node, long visited) { - if (node == goal) { - return 0; - } else if ((visited & node) != 0) { - return int.MinValue; // small enough to represent '-infinity' - } - var key = (node, visited); - if (!cache.ContainsKey(key)) { - cache[key] = edges - .Where(e => e.start == node) - .Select(e => e.distance + LongestPath(e.end, visited | node)) - .Max(); - } - return cache[key]; - } - return LongestPath(start, 0); - } - - (Node[], Edge[]) MakeGraph(string input) { - var map = ParseMap(input); - - // row-major order: 'entry' node comes first and 'exit' is last - var nodePos = ( - from pos in map.Keys - orderby pos.Imaginary, pos.Real - where IsFree(map, pos) && !IsRoad(map, pos) - select pos - ).ToArray(); - - var nodes = ( - from i in Enumerable.Range(0, nodePos.Length) select 1L << i - ).ToArray(); - - var edges = ( - from i in Enumerable.Range(0, nodePos.Length) - from j in Enumerable.Range(0, nodePos.Length) - where i != j - let distance = Distance(map, nodePos[i], nodePos[j]) - where distance > 0 - select new Edge(nodes[i], nodes[j], distance) - ).ToArray(); - - return (nodes, edges); - } - - // Length of the road between two crossroads; -1 if not neighbours - int Distance(Map map, Complex crossroadA, Complex crossroadB) { - var q = new Queue<(Complex, int)>(); - q.Enqueue((crossroadA, 0)); - - var visited = new HashSet { crossroadA }; - while (q.Any()) { - var (pos, dist) = q.Dequeue(); - foreach (var dir in exits[map[pos]]) { - var posT = pos + dir; - if (posT == crossroadB) { - return dist + 1; - } else if (IsRoad(map, posT) && !visited.Contains(posT)) { - visited.Add(posT); - q.Enqueue((posT, dist + 1)); - } - } - } - return -1; - } - - bool IsFree(Map map, Complex p) => - map.ContainsKey(p) && map[p] != '#'; - - bool IsRoad(Map map, Complex p) => - IsFree(map, p) && Dirs.Count(d => IsFree(map, p + d)) == 2; - - Map ParseMap(string input) { - var lines = input.Split('\n'); - return ( - from irow in Enumerable.Range(0, lines.Length) - from icol in Enumerable.Range(0, lines[0].Length) - let pos = new Complex(icol, irow) - select new KeyValuePair(pos, lines[irow][icol]) - ).ToDictionary(); - } -} diff --git a/2023/Day23/illustration.jpeg b/2023/Day23/illustration.jpeg deleted file mode 100644 index cdd403505..000000000 Binary files a/2023/Day23/illustration.jpeg and /dev/null differ diff --git a/2023/Day23/input.in b/2023/Day23/input.in deleted file mode 100644 index 223573511..000000000 Binary files a/2023/Day23/input.in and /dev/null differ diff --git a/2023/Day23/input.refout b/2023/Day23/input.refout deleted file mode 100644 index 26a431634..000000000 --- a/2023/Day23/input.refout +++ /dev/null @@ -1,2 +0,0 @@ -2238 -6398 \ No newline at end of file diff --git a/2023/Day24/README.md b/2023/Day24/README.md deleted file mode 100644 index 2fdc0380b..000000000 --- a/2023/Day24/README.md +++ /dev/null @@ -1,27 +0,0 @@ -## --- Day 24: Never Tell Me The Odds --- -If you are not familiar with the problem, you can read it [here](https://adventofcode.com/2023/day/24). - -A bit unexpectedly we are given a geometry problem that requires floating -point numbers. I don't remember if this was ever needed in Advent of Code. - -Part 1 asks to find the intesection of two 2 dimensional lines. This is -simple enough, but .Net doesn't have a built in matrix library, so I had to -inline everything that was needed. Part 2 was much more interesting. We have -to find a position and velocity of a _stone_ that hits all particles provided in -the input. The particles move in a 3D line now. - -I solved this first using the Chinese Remainder Theorem, but I didn't like it -because it was totally independent of Part 1, almost like two different problems. -I went looking around in others' solutions until I found a good one that is easy -to follow. - -The idea is that we try to guess the speed of our stone (a for loop), then assuming -that it is the right velocity create a new reference frame that moves with -that speed. The stone doesn't move in this frame, it has some fixed coordinates -somewhere. Now transform each particle into this reference frame as well. Since the -stone is not moving, if we properly guessed the speed, we find that each particle -meets at the _same_ point. This must be the stone's location. - -We can reuse code from Part 1, just need to project everything to the XY -plane first to compute the stone's `(x,y)` position, then do the same in the XZ -or YZ plane to get `z` as well. diff --git a/2023/Day24/Solution.cs b/2023/Day24/Solution.cs deleted file mode 100644 index f9f8e1fb4..000000000 --- a/2023/Day24/Solution.cs +++ /dev/null @@ -1,117 +0,0 @@ -namespace AdventOfCode.Y2023.Day24; - -using System; -using System.Linq; -using System.Text.RegularExpressions; -using System.Data; - -record Vec2(decimal x0, decimal x1); -record Vec3(decimal x0, decimal x1, decimal x2); -record Particle2(Vec2 pos, Vec2 vel); -record Particle3(Vec3 pos, Vec3 vel); - -[ProblemName("Never Tell Me The Odds")] -class Solution : Solver { - - public object PartOne(string input) { - var particles = Project(ParseParticles(input), v => (v.x0, v.x1)); - - var inRange = (decimal d) => 2e14m <= d && d <= 4e14m; - - var inFuture = (Particle2 p, Vec2 pos) => - Math.Sign(pos.x0 - p.pos.x0) == Math.Sign(p.vel.x0); - - var res = 0; - for (var i = 0; i < particles.Length; i++) { - for (var j = i + 1; j < particles.Length; j++) { - var pos = Intersection(particles[i], particles[j]); - if (pos != null && - inRange(pos.x0) && - inRange(pos.x1) && - inFuture(particles[i], pos) && - inFuture(particles[j], pos) - ) { - res++; - } - } - } - return res; - } - - public object PartTwo(string input) { - var particles = ParseParticles(input); - var stoneXY = Solve2D(Project(particles, vec => (vec.x0, vec.x1))); - var stoneXZ = Solve2D(Project(particles, vec => (vec.x0, vec.x2))); - return Math.Round(stoneXY.x0 + stoneXY.x1 + stoneXZ.x1); - } - - Vec2 Solve2D(Particle2[] particles) { - // We try to guess the speed of our stone (a for loop), then supposing - // that it is the right velocity we create a new reference frame that - // moves with that speed. The stone doesn't move in this frame, it has - // some fixed unknown coordinates. Now transform each particle into - // this reference frame as well. Since the stone is not moving, if we - // properly guessed the speed, we find that each particle meets at the - // same point. This must be the stone's location. - - var translateV = (Particle2 p, Vec2 vel) => - new Particle2(p.pos, new Vec2(p.vel.x0 - vel.x0, p.vel.x1 - vel.x1)); - - var s = 500; //arbitrary limits for the brute force that worked for me. - for (var v1 = -s; v1 < s; v1++) { - for (var v2 = -s; v2 < s; v2++) { - var vel = new Vec2(v1, v2); - - // p0 and p1 are linearly independent (for me) => stone != null - var stone = Intersection( - translateV(particles[0], vel), - translateV(particles[1], vel) - ); - - if (particles.All(p => Hits(translateV(p, vel), stone))) { - return stone; - } - } - } - throw new Exception(); - } - - bool Hits(Particle2 p, Vec2 pos) { - var d = (pos.x0 - p.pos.x0) * p.vel.x1 - (pos.x1 - p.pos.x1) * p.vel.x0; - return Math.Abs(d) < (decimal)0.0001; - } - - Vec2 Intersection(Particle2 p1, Particle2 p2) { - // this would look way better if I had a matrix library at my disposal. - var determinant = p1.vel.x0 * p2.vel.x1 - p1.vel.x1 * p2.vel.x0; - if (determinant == 0) { - return null; //particles don't meet - } - - var b0 = p1.vel.x0 * p1.pos.x1 - p1.vel.x1 * p1.pos.x0; - var b1 = p2.vel.x0 * p2.pos.x1 - p2.vel.x1 * p2.pos.x0; - - return new ( - (p2.vel.x0 * b0 - p1.vel.x0 * b1) / determinant, - (p2.vel.x1 * b0 - p1.vel.x1 * b1) / determinant - ); - } - - Particle3[] ParseParticles(string input) => [.. - from line in input.Split('\n') - let v = ParseNum(line) - select new Particle3(new (v[0], v[1], v[2]), new (v[3], v[4], v[5])) - ]; - - decimal[] ParseNum(string l) => [.. - from m in Regex.Matches(l, @"-?\d+") select decimal.Parse(m.Value) - ]; - - // Project particles to a 2D plane: - Particle2[] Project(Particle3[] ps, Func proj) => [.. - from p in ps select new Particle2( - new Vec2(proj(p.pos).Item1, proj(p.pos).Item2), - new Vec2(proj(p.vel).Item1, proj(p.vel).Item2) - ) - ]; -} diff --git a/2023/Day24/illustration.jpeg b/2023/Day24/illustration.jpeg deleted file mode 100644 index 77f5b727e..000000000 Binary files a/2023/Day24/illustration.jpeg and /dev/null differ diff --git a/2023/Day24/input.in b/2023/Day24/input.in deleted file mode 100644 index c624e433f..000000000 Binary files a/2023/Day24/input.in and /dev/null differ diff --git a/2023/Day24/input.refout b/2023/Day24/input.refout deleted file mode 100644 index 0c308e399..000000000 --- a/2023/Day24/input.refout +++ /dev/null @@ -1,2 +0,0 @@ -27732 -641619849766168 \ No newline at end of file diff --git a/2023/Day25/README.md b/2023/Day25/README.md deleted file mode 100644 index b74bd4b54..000000000 --- a/2023/Day25/README.md +++ /dev/null @@ -1,30 +0,0 @@ -## --- Day 25: Snowverload --- -Those who need a refresh can read the problem [here](https://adventofcode.com/2023/day/25). - -This is our last day and these are historically not very hard. The puzzle is asking us -to cut an undirected graph into two components by removing only three edges. I had -absolutely no idea how to do that in an effective way, so it was time to consult the -literature. Soon enough I found [Karger's algorithm](https://en.wikipedia.org/wiki/Karger%27s_algorithm) -on Wikipedia. - -It's a randomized algorithm that works on non-weighted, undirected graphs like ours. -It finds _some cut_ which is not necessarily minimal, but there is a good chance -that it finds the minimal one in a few tries. _This is the Elf way!_ - -Karger's is not hard to implement, but I'm not used to do this kind of things lately, -so I spent quite a lot of time getting it right. One mistake was that I didn't -add the edges in the reverse direction: the input contains them only in one way. Then it was not obvious what to do with multiple edges between two nodes, because the algorithm needs to create these. -But it has started to work and I just let it do its thing in a loop and it really -found a cut with 3 edges in a few milliseconds. - -It was easy to extend the algorithm to return the sizes of the two components as well. -Part 1 asks for the product of these. Part 2 is a meta puzzle, it requires to complete -all other challenges from the previous days, but I already finished those, so I can -conclude season today (Dec 25th). - -Thanks for joining me! If you find this work useful or want to get in touch -(even just saying hello), find me on [Github](https://github.com/encse) or -[Twitter](https://twitter.com/encse). - -Psst! There is game [hidden](game) in this site. - diff --git a/2023/Day25/Solution.cs b/2023/Day25/Solution.cs deleted file mode 100644 index fe67e85d4..000000000 --- a/2023/Day25/Solution.cs +++ /dev/null @@ -1,94 +0,0 @@ -namespace AdventOfCode.Y2023.Day25; - -using System; -using System.Collections.Generic; -using System.Linq; - -[ProblemName("Snowverload")] -class Solution : Solver { - - public object PartOne(string input) { - Random r = new Random(25); - - // run Karger's algorithm until it finds a cut with 3 edges - var (cutSize, c1, c2) = FindCut(input, r); - while (cutSize != 3) { - (cutSize, c1, c2) = FindCut(input, r); - } - return c1 * c2; - } - - // https://en.wikipedia.org/wiki/Karger%27s_algorithm - // Karger's algorithm finds a cut of a graph and returns its size. - // It's not necessarily the minimal cut, because it's a randomized algorithm - // but it's 'likely' to find the minimal cut in reasonable time. - // The algorithm is extended to return the sizes of the two components - // separated by the cut as well. - (int size, int c1, int c2) FindCut(string input, Random r) { - var graph = Parse(input); - var componentSize = graph.Keys.ToDictionary(k => k, _ => 1); - - // updates backreferences of oldNode to point to newNode - var rebind = (string oldNode, string newNode) => { - foreach (var n in graph[oldNode]) { - while (graph[n].Remove(oldNode)) { - graph[n].Add(newNode); - } - } - }; - - for (var id = 0; graph.Count > 2; id++) { - // decrease the the number of nodes by one. First select two nodes u - // and v connected with an edge. Introduce a new node that inherits - // every edge going out of these (excluding the edges between them). - // Set the new nodes' component size to the sum of the component - // sizes of u and v. Remove u and v from the graph. - var u = graph.Keys.ElementAt(r.Next(graph.Count)); - var v = graph[u][r.Next(graph[u].Count)]; - - var merged = "merge-" + id; - graph[merged] = [ - ..from n in graph[u] where n != v select n, - ..from n in graph[v] where n != u select n - ]; - rebind(u, merged); - rebind(v, merged); - - componentSize[merged] = componentSize[u] + componentSize[v]; - - graph.Remove(u); - graph.Remove(v); - } - - // two nodes remain with some edges between them, the number of those - // edges equals to the size of the cut. Component size tells the number - // of nodes in the two sides created by the cut. - var nodeA = graph.Keys.First(); - var nodeB = graph.Keys.Last(); - return (graph[nodeA].Count(), componentSize[nodeA], componentSize[nodeB]); - } - - // returns an adjacency list representation of the input. Edges are recorded - // both ways, unlike in the input which contains them in one direction only. - Dictionary> Parse(string input) { - var graph = new Dictionary>(); - - var registerEdge = (string u, string v) => { - if (!graph.ContainsKey(u)) { - graph[u] = new(); - } - graph[u].Add(v); - }; - - foreach (var line in input.Split('\n')) { - var parts = line.Split(": "); - var u = parts[0]; - var nodes = parts[1].Split(' '); - foreach (var v in nodes) { - registerEdge(u, v); - registerEdge(v, u); - } - } - return graph; - } -} diff --git a/2023/Day25/illustration.jpeg b/2023/Day25/illustration.jpeg deleted file mode 100644 index 42399f317..000000000 Binary files a/2023/Day25/illustration.jpeg and /dev/null differ diff --git a/2023/Day25/input.in b/2023/Day25/input.in deleted file mode 100644 index 5dd3aa864..000000000 Binary files a/2023/Day25/input.in and /dev/null differ diff --git a/2023/Day25/input.refout b/2023/Day25/input.refout deleted file mode 100644 index f80cbd205..000000000 --- a/2023/Day25/input.refout +++ /dev/null @@ -1 +0,0 @@ -514786 \ No newline at end of file diff --git a/2023/README.md b/2023/README.md deleted file mode 100644 index 4fd5bc286..000000000 --- a/2023/README.md +++ /dev/null @@ -1,4 +0,0 @@ -# Advent of Code (2023) -Check out https://adventofcode.com/2023. - - diff --git a/2023/SplashScreen.cs b/2023/SplashScreen.cs deleted file mode 100644 index d5f9a011a..000000000 --- a/2023/SplashScreen.cs +++ /dev/null @@ -1,242 +0,0 @@ -using System; - -namespace AdventOfCode.Y2023; - -class SplashScreenImpl : SplashScreen { - - public void Show() { - - var color = Console.ForegroundColor; - Write(0xcc00, false, " ▄█▄ ▄▄█ ▄ ▄ ▄▄▄ ▄▄ ▄█▄ ▄▄▄ ▄█ ▄▄ ▄▄▄ ▄▄█ ▄▄▄\n █▄█ █ █ █ █ █▄█ █ █ █ █ █ █▄ "); - Write(0xcc00, false, " █ █ █ █ █ █▄█\n █ █ █▄█ ▀▄▀ █▄▄ █ █ █▄ █▄█ █ █▄ █▄█ █▄█ █▄▄ $year = 2023\n "); - Write(0xcc00, false, "\n "); - Write(0xa25151, false, "...'''''''''... \n .'' "); - Write(0xdf2308, true, "~"); - Write(0xa5a8af, false, "/\\"); - Write(0xffff66, true, "* "); - Write(0xdf2308, true, "~~~~ "); - Write(0xa5a8af, false, "/\\ "); - Write(0xa25151, false, "''. "); - Write(0xcccccc, false, "14 "); - Write(0xffff66, false, "**\n "); - Write(0xa25151, false, ".' "); - Write(0xa5a8af, false, "/\\/\\ "); - Write(0xdf2308, true, "~~~~~~~~ "); - Write(0xffff66, true, "* "); - Write(0xa5a8af, false, "/"); - Write(0xdf2308, true, "~"); - Write(0xa5a8af, false, "\\ "); - Write(0xa25151, false, "'. "); - Write(0xcccccc, false, "15 "); - Write(0xffff66, false, "**\n "); - Write(0xd4dde4, false, "... "); - Write(0xa25151, false, ":"); - Write(0xdf2308, true, "~~~~~~~~~ "); - Write(0xa5a8af, false, "/\\ "); - Write(0xdf2308, true, "~~~~"); - Write(0xa5a8af, false, "/ "); - Write(0xffff66, true, "* "); - Write(0xa5a8af, false, "\\ "); - Write(0xa25151, false, ": "); - Write(0xcccccc, false, "16 "); - Write(0xffff66, false, "**\n "); - Write(0xd4dde4, false, ".''....' '.."); - Write(0xa25151, false, "'."); - Write(0xdf2308, true, "~~~~"); - Write(0xa5a8af, false, "/\\"); - Write(0xffff66, true, "*"); - Write(0xa5a8af, false, "/\\ "); - Write(0xdf2308, true, "~ "); - Write(0xa5a8af, false, "/\\ /\\ "); - Write(0xa25151, false, ".' "); - Write(0xcccccc, false, "13 "); - Write(0xffff66, false, "**\n "); - Write(0xd4dde4, false, "'.ZZ"); - Write(0xdf2308, true, "~ ~ "); - Write(0xffff66, true, "* "); - Write(0xdf2308, true, "~~~~"); - Write(0xa25151, false, ". "); - Write(0xa5a8af, false, "/\\ /\\ /\\ "); - Write(0xa25151, false, "..' "); - Write(0xcccccc, false, "17 "); - Write(0xffff66, false, "**\n "); - Write(0xd4dde4, false, ".'''' ZZ"); - Write(0xffff66, true, "* "); - Write(0xd4dde4, false, ".'''.[]"); - Write(0xdf2308, true, "~~~"); - Write(0xd4dde4, false, "'"); - Write(0xa25151, false, "'''.........''' "); - Write(0xcccccc, false, "12 "); - Write(0xffff66, false, "**\n "); - Write(0xd4dde4, false, "'.... "); - Write(0xdf2308, true, "~ "); - Write(0xd4dde4, false, "'...' "); - Write(0xffff66, true, "*"); - Write(0xd4dde4, false, "[]....' "); - Write(0xcccccc, false, "18 "); - Write(0xffff66, false, "**\n "); - Write(0xd4dde4, false, ".'"); - Write(0xffff66, true, "* "); - Write(0xdf2308, true, "~ "); - Write(0xd4dde4, false, "[^^^] '. "); - Write(0xcccccc, false, "11 "); - Write(0xffff66, false, "**\n "); - Write(0xd4dde4, false, "'..''''."); - Write(0xffff66, true, "*"); - Write(0xd4dde4, false, ".''''..'"); - Write(0xe3b585, false, "' ''... "); - Write(0xcccccc, false, "10 "); - Write(0xffff66, false, "**\n "); - Write(0xe3b585, false, "."); - Write(0xd4dde4, false, "'''"); - Write(0xe3b585, false, "~ ~ ~ "); - Write(0xd4dde4, false, ". "); - Write(0xffff66, true, "* "); - Write(0x6b4d3b, false, "### "); - Write(0xe3b585, false, "''. "); - Write(0xcccccc, false, "19 "); - Write(0xffff66, false, "**\n "); - Write(0xe3b585, false, ".' ~ "); - Write(0xcc00, false, ","); - Write(0xffff66, true, "* "); - Write(0xe3b585, false, "~ "); - Write(0xd4dde4, false, "'\", "); - Write(0xe3b585, false, "~ "); - Write(0x6b4d3b, false, "##### "); - Write(0xe3b585, false, "'. "); - Write(0xcccccc, false, " 9 "); - Write(0xffff66, false, "**\n "); - Write(0xe3b585, false, ": ~ "); - Write(0xcc00, false, "'"); - Write(0x5555bb, false, "(~)"); - Write(0xcc00, false, ", "); - Write(0xe3b585, false, "~ "); - Write(0xffff66, true, "* "); - Write(0xe3b585, false, "~ ~ ~ "); - Write(0x6b4d3b, false, "### "); - Write(0xe3b585, false, ": "); - Write(0xcccccc, false, " 8 "); - Write(0xffff66, false, "**\n "); - Write(0xe3b585, false, "'. ~ "); - Write(0xcc00, false, "\" ' "); - Write(0xe3b585, false, "~ ~ ~ "); - Write(0xffff66, true, "* "); - Write(0xe3b585, false, "~~~"); - Write(0x6b4d3b, false, "## "); - Write(0xe3b585, false, ".' "); - Write(0xcccccc, false, "20 "); - Write(0xffff66, false, "**\n "); - Write(0xe3b585, false, "'.. ~ ~ "); - Write(0xffff66, true, "* "); - Write(0xe3b585, false, "~ "); - Write(0x6b4d3b, false, "####"); - Write(0xe3b585, false, "~~~~'"); - Write(0xcc00, false, ".'''''''''... "); - Write(0xcccccc, false, " 7 "); - Write(0xffff66, false, "**\n "); - Write(0xe3b585, false, "'''.........'''"); - Write(0xcc00, false, "' "); - Write(0x5555bb, false, "~ "); - Write(0xcc00, false, ".'"); - Write(0xffff66, true, "*"); - Write(0xcc00, false, ". "); - Write(0x5555bb, false, "~ "); - Write(0xcc00, false, ".. ''. "); - Write(0xcccccc, false, " 6 "); - Write(0xffff66, false, "**\n "); - Write(0xcc00, false, ".' "); - Write(0x5555bb, false, "~ "); - Write(0xe3b585, false, ".. "); - Write(0xcc00, false, "'...' "); - Write(0x5555bb, false, "~"); - Write(0xcc00, false, "'"); - Write(0xffff66, true, "* "); - Write(0xcc00, false, "'."); - Write(0x5555bb, false, "~ "); - Write(0xcc00, false, "'. "); - Write(0xcccccc, false, "21 "); - Write(0xffff66, false, "**\n "); - Write(0x5555bb, false, "~~ "); - Write(0xe3b585, false, ".~~~'. "); - Write(0x5555bb, false, "~ "); - Write(0xcc00, false, "'. "); - Write(0xffff66, true, "*"); - Write(0xcc00, false, "'."); - Write(0x5555bb, false, "~ "); - Write(0xcc00, false, ": "); - Write(0xcccccc, false, " 5 "); - Write(0xffff66, false, "**\n "); - Write(0xffffff, false, "...''''"); - Write(0x5555bb, false, "~~~"); - Write(0xe3b585, false, "'"); - Write(0xffff66, true, "*"); - Write(0xe3b585, false, "~~.' "); - Write(0xcc00, false, ".''."); - Write(0x5555bb, false, "~ "); - Write(0xcc00, false, "'..' .' "); - Write(0xcccccc, false, "22 "); - Write(0xffff66, false, "**\n "); - Write(0xffffff, false, ".'' "); - Write(0xccccff, false, "- - "); - Write(0xcc00, false, "'.. "); - Write(0x5555bb, false, "~"); - Write(0xcc00, false, "..'"); - Write(0xffff66, true, "* "); - Write(0xcc00, false, "'. "); - Write(0x5555bb, false, "~ "); - Write(0xcc00, false, "..' "); - Write(0xcccccc, false, " 4 "); - Write(0xffff66, false, "**\n "); - Write(0xffffff, false, ".' "); - Write(0xffff66, true, "* "); - Write(0xccccff, false, "- "); - Write(0xffffff, false, "/\\ "); - Write(0xccccff, false, "- "); - Write(0xcc00, false, "'''.."); - Write(0xd4dde4, false, "/"); - Write(0xcc00, false, "......''' "); - Write(0xcccccc, false, "23 "); - Write(0xffff66, false, "**\n "); - Write(0xffffff, false, ": "); - Write(0xccccff, false, "- - - "); - Write(0xffff66, true, "* "); - Write(0xffffff, false, "/\\ "); - Write(0xccccff, false, "-"); - Write(0xd4dde4, false, "/ "); - Write(0xffffff, false, ": "); - Write(0xcccccc, false, "25 "); - Write(0xffff66, false, "**\n "); - Write(0xffffff, false, "'. "); - Write(0xccccff, false, "- "); - Write(0xffff66, true, "* "); - Write(0xffffff, false, "/\\ "); - Write(0xccccff, false, "- - "); - Write(0xd4dde4, false, "/ "); - Write(0xffffff, false, ".' "); - Write(0xcccccc, false, "24 "); - Write(0xffff66, false, "**\n "); - Write(0xffffff, false, "'.. "); - Write(0xccccff, false, "- - "); - Write(0xffff66, true, "*"); - Write(0xffffff, false, "..' "); - Write(0xcccccc, false, " 3 "); - Write(0xffff66, false, "**\n "); - Write(0x9b715b, false, "----@ "); - Write(0xffffff, false, "'''.."); - Write(0xffff66, true, "*"); - Write(0xffffff, false, "......''' "); - Write(0xcccccc, false, " 2 "); - Write(0xffff66, false, "**\n "); - Write(0xffff66, true, "* "); - Write(0x9b715b, false, "! /^\\ "); - Write(0xcccccc, false, " 1 "); - Write(0xffff66, false, "**\n \n"); - - Console.ForegroundColor = color; - Console.WriteLine(); - } - - private static void Write(int rgb, bool bold, string text){ - Console.Write($"\u001b[38;2;{(rgb>>16)&255};{(rgb>>8)&255};{rgb&255}{(bold ? ";1" : "")}m{text}"); - } -} \ No newline at end of file diff --git a/2023/calendar.svg b/2023/calendar.svg deleted file mode 100644 index e515150c5..000000000 --- a/2023/calendar.svg +++ /dev/null @@ -1,47 +0,0 @@ - - - - -▄█▄ ▄▄█ ▄ ▄ ▄▄▄ ▄▄ ▄█▄  ▄▄▄ ▄█  ▄▄ ▄▄▄ ▄▄█ ▄▄▄ -█▄█ █ █ █ █ █▄█ █ █ █   █ █ █▄  █  █ █ █ █ █▄█ -█ █ █▄█ ▀▄▀ █▄▄ █ █ █▄  █▄█ █   █▄ █▄█ █▄█ █▄▄  $year = 2023 -  -                     ...'''''''''...                     -                  .'' ~/\* ~~~~  /\ ''.            14 ** -                .' /\/\ ~~~~~~~~ * /~\ '.          15 ** -           ...  :~~~~~~~~~ /\ ~~~~/ * \ :          16 ** -    .''....' '..'.~~~~/\*/\ ~  /\   /\ .'          13 ** -    '.ZZ~   ~ * ~~~~.   /\  /\   /\ ..'            17 ** -.'''' ZZ* .'''.[]~~~''''.........'''               12 ** -'.... ~   '...'  *[]....'                          18 ** -    .'*  ~   [^^^] '.                              11 ** -    '..''''.*.''''..'' ''...                       10 ** -          .'''~ ~ ~ . * ### ''.                    19 ** -        .' ~  ,* ~ '", ~ ##### '.                   9 ** -        : ~ '(~), ~ * ~ ~ ~ ### :                   8 ** -        '. ~ " ' ~ ~ ~ * ~~~## .'                  20 ** -          '.. ~ ~ * ~ ####~~~~'.'''''''''...        7 ** -             '''.........'''' ~ .'*. ~  ..  ''.     6 ** -                        .' ~ .. '...' ~'* '.~  '.  21 ** -                        ~~ .~~~'. ~     '. *'.~ :   5 ** -                 ...''''~~~'*~~.'  .''.~  '..' .'  22 ** -              .''   -   - '..  ~..'*   '. ~ ..'     4 ** -            .' * -    /\ -   '''../......'''       23 ** -            :  -   -  - * /\    -/  :              25 ** -            '.    - *  /\ -   - /  .'              24 ** -              '..    -     -   *..'                 3 ** -    ----@        '''..*......'''                    2 ** -  * ! /^\                                           1 ** - - - - \ No newline at end of file diff --git a/2024/Day01/README.md b/2024/Day01/README.md deleted file mode 100644 index da9b18efa..000000000 --- a/2024/Day01/README.md +++ /dev/null @@ -1,6 +0,0 @@ -## --- Day 1: Historian Hysteria --- -The Chief Historian is always present for the big Christmas sleigh launch, but nobody has seen him in months! Last anyone heard, he was visiting locations that are historically significant to the North Pole; a group of Senior Historians has asked you to accompany them as they check the places they think he was most likely to visit. - -As each location is checked, they will mark it on their list with a star. They figure the Chief Historian must be in one of the first fifty places they'll look, so in order to save Christmas, you need to help them get fifty stars on their list before Santa takes off on December 25th. - -_Visit the website for the full story and [full puzzle](https://adventofcode.com/2024/day/1) description._ diff --git a/2024/Day01/Solution.cs b/2024/Day01/Solution.cs deleted file mode 100644 index 3b440af39..000000000 --- a/2024/Day01/Solution.cs +++ /dev/null @@ -1,29 +0,0 @@ -namespace AdventOfCode.Y2024.Day01; - -using System; -using System.Collections.Generic; -using System.Collections.Immutable; -using System.Linq; - -[ProblemName("Historian Hysteria")] -class Solution : Solver { - - public object PartOne(string input) => - // go over the sorted columns pairwise and sum the difference of the pairs - Enumerable.Zip(Column(input, 0), Column(input, 1)) - .Select(p => Math.Abs(p.First - p.Second)) - .Sum(); - - public object PartTwo(string input) { - // sum the elements of the left column weighted by its occurrences in the right - // ⭐ .Net 9 comes with a new CountBy function - var weights = Column(input, 1).CountBy(x=>x).ToDictionary(); - return Column(input, 0).Select(num => weights.GetValueOrDefault(num) * num).Sum(); - } - - IEnumerable Column(string input, int column) => - from line in input.Split("\n") - let nums = line.Split(" ").Select(int.Parse).ToArray() - orderby nums[column] - select nums[column]; -} diff --git a/2024/Day01/illustration.jpeg b/2024/Day01/illustration.jpeg deleted file mode 100644 index c5dbd40d7..000000000 Binary files a/2024/Day01/illustration.jpeg and /dev/null differ diff --git a/2024/Day01/input.in b/2024/Day01/input.in deleted file mode 100644 index 8eba02d04..000000000 Binary files a/2024/Day01/input.in and /dev/null differ diff --git a/2024/Day01/input.refout b/2024/Day01/input.refout deleted file mode 100644 index 85ba5a423..000000000 --- a/2024/Day01/input.refout +++ /dev/null @@ -1,2 +0,0 @@ -2904518 -18650129 \ No newline at end of file diff --git a/2024/Day02/README.md b/2024/Day02/README.md deleted file mode 100644 index ba6e3516b..000000000 --- a/2024/Day02/README.md +++ /dev/null @@ -1,10 +0,0 @@ -## --- Day 2: Red-Nosed Reports --- -Fortunately, the first location The Historians want to search isn't a long walk from the Chief Historian's office. - -While the _Red-Nosed Reindeer nuclear fusion/fission plant_ appears to contain no sign of the Chief Historian, the engineers there run up to you as soon as they see you. Apparently, they still talk about the time Rudolph was saved through molecular synthesis from a single electron. - -_Visit the website for the full story and [puzzle](https://adventofcode.com/2024/day/2) description._ - -I created a function to check the validity of a single input line. This is achieved using the usual method of _zipping_ the input with itself to generate a list of consecutive pairs. The next step involves checking the monotonicity condition (either increasing or decreasing) for each pair. - -The second part of the problem is addressed with another helper function. This function takes an input sequence and generates attenuated versions of it in all possible ways, by omitting _zero_ or _one_ elements from the sample. \ No newline at end of file diff --git a/2024/Day02/Solution.cs b/2024/Day02/Solution.cs deleted file mode 100644 index 8f07d7144..000000000 --- a/2024/Day02/Solution.cs +++ /dev/null @@ -1,36 +0,0 @@ -namespace AdventOfCode.Y2024.Day02; - -using System; -using System.Collections.Generic; -using System.Linq; - -[ProblemName("Red-Nosed Reports")] -class Solution : Solver { - - public object PartOne(string input) => - ParseSamples(input).Count(Valid); - - public object PartTwo(string input) => - ParseSamples(input).Count(samples => Attenuate(samples).Any(Valid)); - - IEnumerable ParseSamples(string input) => - from line in input.Split("\n") - let samples = line.Split(" ").Select(int.Parse) - select samples.ToArray(); - - // Generates all possible variations of the input sequence by omitting - // either zero or one element from it. - IEnumerable Attenuate(int[] samples) => - from i in Enumerable.Range(0, samples.Length+1) - let before = samples.Take(i - 1) - let after = samples.Skip(i) - select Enumerable.Concat(before, after).ToArray(); - - // Checks the monothinicity condition by examining consecutive elements - bool Valid(int[] samples) { - var pairs = Enumerable.Zip(samples, samples.Skip(1)); - return - pairs.All(p => 1 <= p.Second - p.First && p.Second - p.First <= 3) || - pairs.All(p => 1 <= p.First - p.Second && p.First - p.Second <= 3); - } -} diff --git a/2024/Day02/illustration.jpeg b/2024/Day02/illustration.jpeg deleted file mode 100644 index cebc32454..000000000 Binary files a/2024/Day02/illustration.jpeg and /dev/null differ diff --git a/2024/Day02/input.in b/2024/Day02/input.in deleted file mode 100644 index 2ceeb0950..000000000 Binary files a/2024/Day02/input.in and /dev/null differ diff --git a/2024/Day02/input.refout b/2024/Day02/input.refout deleted file mode 100644 index 2e38115b0..000000000 --- a/2024/Day02/input.refout +++ /dev/null @@ -1,2 +0,0 @@ -202 -271 \ No newline at end of file diff --git a/2024/Day03/README.md b/2024/Day03/README.md deleted file mode 100644 index c437cf887..000000000 --- a/2024/Day03/README.md +++ /dev/null @@ -1,8 +0,0 @@ -## --- Day 3: Mull It Over --- -"Our computers are having issues, so I have no idea if we have any Chief Historians in stock! You're welcome to check the warehouse, though," says the mildly flustered shopkeeper at the [North Pole Toboggan Rental Shop](/2020/day/2). The Historians head out to take a look. - -The shopkeeper turns to you. "Any chance you can see why our computers are having issues again?" - -_Visit the website for the full story and [puzzle](https://adventofcode.com/2024/day/3) description._ - -I took a functional approach today. Regular expressions are ugly beasts, I normally try avoid them. Fortunately, we're not writing production code here. Otherwise... everything is just a fold if you look at it from a distance. diff --git a/2024/Day03/Solution.cs b/2024/Day03/Solution.cs deleted file mode 100644 index 292cf926f..000000000 --- a/2024/Day03/Solution.cs +++ /dev/null @@ -1,29 +0,0 @@ -namespace AdventOfCode.Y2024.Day03; - -using System.Linq; -using System.Text.RegularExpressions; - -[ProblemName("Mull It Over")] -class Solution : Solver { - - public object PartOne(string input) => Solve(input, @"mul\((\d{1,3}),(\d{1,3})\)"); - - public object PartTwo(string input) => Solve(input, @"mul\((\d{1,3}),(\d{1,3})\)|don't\(\)|do\(\)"); - - long Solve(string input, string rx) { - // overly functionaly approach... - var matches = Regex.Matches(input, rx, RegexOptions.Multiline); - return matches.Aggregate( - (enabled: true, res: 0L), - (acc, m) => - (m.Value, acc.res, acc.enabled) switch { - ("don't()", _, _) => (false, acc.res), - ("do()", _, _) => (true, acc.res), - (_, var res, true) => - (true, res + int.Parse(m.Groups[1].Value) * int.Parse(m.Groups[2].Value)), - _ => acc - }, - acc => acc.res - ); - } -} \ No newline at end of file diff --git a/2024/Day03/illustration.jpeg b/2024/Day03/illustration.jpeg deleted file mode 100644 index e19c0a13b..000000000 Binary files a/2024/Day03/illustration.jpeg and /dev/null differ diff --git a/2024/Day03/input.in b/2024/Day03/input.in deleted file mode 100644 index 46d2a13b9..000000000 Binary files a/2024/Day03/input.in and /dev/null differ diff --git a/2024/Day03/input.refout b/2024/Day03/input.refout deleted file mode 100644 index b4d21cde1..000000000 --- a/2024/Day03/input.refout +++ /dev/null @@ -1,2 +0,0 @@ -165225049 -108830766 \ No newline at end of file diff --git a/2024/Day04/README.md b/2024/Day04/README.md deleted file mode 100644 index 830b6cf4e..000000000 --- a/2024/Day04/README.md +++ /dev/null @@ -1,11 +0,0 @@ -## --- Day 4: Ceres Search --- -"Looks like the Chief's not here. Next!" One of The Historians pulls out a device and pushes the only button on it. After a brief flash, you recognize the interior of the __Ceres monitoring station__! -As the search for the Chief continues, a small Elf who lives on the station tugs on your shirt; she'd like to know if you could help her with her word search. She only has to find one word: XMAS. - -_Visit the website for the full story and [puzzle](https://adventofcode.com/2024/day/4) description._ - -I employed my proven tactic of converting the input into a dictionary, using coordinates as keys. This approach makes it straightforward to iterate over the keys and check whether they fall within the bounds of the map. - -Representing coordinates with complex numbers is another effective technique for handling steps in various directions. - -The algorithm itself is a straightforward brute-force check of all starting positions and reading orders. diff --git a/2024/Day04/Solution.cs b/2024/Day04/Solution.cs deleted file mode 100644 index b5cfcc9fd..000000000 --- a/2024/Day04/Solution.cs +++ /dev/null @@ -1,61 +0,0 @@ -namespace AdventOfCode.Y2024.Day04; - -using System; -using System.Collections.Generic; -using System.Collections.Immutable; -using System.Numerics; -using System.Linq; - -using Map = System.Collections.Immutable.ImmutableDictionary; - -[ProblemName("Ceres Search")] -class Solution : Solver { - - Complex Up = -Complex.ImaginaryOne; - Complex Down = Complex.ImaginaryOne; - Complex Left = -1; - Complex Right = 1; - - public object PartOne(string input) { - var mat = GetMap(input); - return ( - from pt in mat.Keys - from dir in new[] { Right, Right + Down, Down + Left, Down} - where Matches(mat, pt, dir, "XMAS") - select 1 - ).Count(); - } - - public object PartTwo(string input) { - var mat = GetMap(input); - return ( - from pt in mat.Keys - where - Matches(mat, pt + Up + Left, Down + Right, "MAS") && - Matches(mat, pt + Down + Left, Up + Right, "MAS") - select 1 - ).Count(); - } - - // check if the pattern (or its reverse) can be read in the given direction - // starting from pt - bool Matches(Map map, Complex pt, Complex dir, string pattern) { - var chars = Enumerable.Range(0, pattern.Length) - .Select(i => map.GetValueOrDefault(pt + i * dir)) - .ToArray(); - return - Enumerable.SequenceEqual(chars, pattern) || - Enumerable.SequenceEqual(chars, pattern.Reverse()); - } - - // store the points in a dictionary so that we can iterate over them and - // to easily deal with points outside the area using GetValueOrDefault - Map GetMap(string input) { - var map = input.Split("\n"); - return ( - from y in Enumerable.Range(0, map.Length) - from x in Enumerable.Range(0, map[0].Length) - select new KeyValuePair(Complex.ImaginaryOne * y + x, map[y][x]) - ).ToImmutableDictionary(); - } -} \ No newline at end of file diff --git a/2024/Day04/illustration.jpeg b/2024/Day04/illustration.jpeg deleted file mode 100644 index a5fdc0918..000000000 Binary files a/2024/Day04/illustration.jpeg and /dev/null differ diff --git a/2024/Day04/input.in b/2024/Day04/input.in deleted file mode 100644 index 9f76d332e..000000000 Binary files a/2024/Day04/input.in and /dev/null differ diff --git a/2024/Day04/input.refout b/2024/Day04/input.refout deleted file mode 100644 index 947b78a71..000000000 --- a/2024/Day04/input.refout +++ /dev/null @@ -1,2 +0,0 @@ -2414 -1871 \ No newline at end of file diff --git a/2024/Day05/README.md b/2024/Day05/README.md deleted file mode 100644 index 6f40cba61..000000000 --- a/2024/Day05/README.md +++ /dev/null @@ -1,12 +0,0 @@ -## --- Day 5: Print Queue --- -Satisfied with their search on Ceres, the squadron of scholars suggests subsequently scanning the stationery stacks of sub-basement 17. - -The North Pole printing department is busier than ever this close to Christmas, and while The Historians continue their search of this historically significant facility, an Elf operating a **very familiar printer** beckons you over. - -The Elf must recognize you, because they waste no time explaining that the new sleigh launch safety manual updates won't print correctly. Failure to update the safety manuals would be dire indeed, so you offer your services. - -_Visit the website for the full story and [puzzle](https://adventofcode.com/2024/day/5) description._ - -The constraints in both my input and the provided sample input define a total ordering of the pages, which I leveraged in my solution. (*) I implemented a custom parser that returns the list of updates to be printed and a page comparison function. That's all we need. In `Part1`, we check which updates are in the correct order, while in `Part2`, we handle the remaining updates by applying .NET's built-in `OrderBy` function with our custom comparer. - -(*) others say that the ordering is not total, in fact there are loops in it. But it was not an issue for the update lines we need to sort. So the thing below works only because of the Elf magic of X-mas. diff --git a/2024/Day05/Solution.cs b/2024/Day05/Solution.cs deleted file mode 100644 index e25ef7a09..000000000 --- a/2024/Day05/Solution.cs +++ /dev/null @@ -1,40 +0,0 @@ -namespace AdventOfCode.Y2024.Day05; - -using System.Collections.Generic; -using System.Linq; - -[ProblemName("Print Queue")] -class Solution : Solver { - - public object PartOne(string input) { - var (updates, comparer) = Parse(input); - return updates - .Where(pages => Sorted(pages, comparer)) - .Sum(GetMiddlePage); - } - - public object PartTwo(string input) { - var (updates, comparer) = Parse(input); - return updates - .Where(pages => !Sorted(pages, comparer)) - .Select(pages => pages.OrderBy(p => p, comparer).ToArray()) - .Sum(GetMiddlePage); - } - - (string[][] updates, Comparer) Parse(string input) { - var parts = input.Split("\n\n"); - - var ordering = new HashSet(parts[0].Split("\n")); - var comparer = - Comparer.Create((p1, p2) => ordering.Contains(p1 + "|" + p2) ? -1 : 1); - - var updates = parts[1].Split("\n").Select(line => line.Split(",")).ToArray(); - return (updates, comparer); - } - - int GetMiddlePage(string[] nums) => int.Parse(nums[nums.Length / 2]); - - bool Sorted(string[] pages, Comparer comparer) => - Enumerable.SequenceEqual(pages, pages.OrderBy(x=>x, comparer)); - -} diff --git a/2024/Day05/illustration.jpeg b/2024/Day05/illustration.jpeg deleted file mode 100644 index d270b7fa4..000000000 Binary files a/2024/Day05/illustration.jpeg and /dev/null differ diff --git a/2024/Day05/input.in b/2024/Day05/input.in deleted file mode 100644 index 258e15c8b..000000000 Binary files a/2024/Day05/input.in and /dev/null differ diff --git a/2024/Day05/input.refout b/2024/Day05/input.refout deleted file mode 100644 index 4d6180ed3..000000000 --- a/2024/Day05/input.refout +++ /dev/null @@ -1,2 +0,0 @@ -4790 -6319 \ No newline at end of file diff --git a/2024/Day06/README.md b/2024/Day06/README.md deleted file mode 100644 index 2a908234f..000000000 --- a/2024/Day06/README.md +++ /dev/null @@ -1,14 +0,0 @@ -## --- Day 6: Guard Gallivant --- -The Historians use their fancy __device__ again, this time to whisk you all away to the North Pole prototype suit manufacturing lab... in the year __1518__! It turns out that having direct access to history is very convenient for a group of historians. - -You still have to be careful of time paradoxes, and so it will be important to avoid anyone from 1518 while The Historians search for the Chief. Unfortunately, a single guard is patrolling this part of the lab. - -_Visit the website for the full story and [puzzle](https://adventofcode.com/2024/day/6) description._ - -This has been a straightforward implementation challenge. I wrote a `Walk` function that tracks the guard's movement and returns the visited locations. It also determines whether the guard enters a loop or exits the grid. `Part1` utilizes only the location information, while `Part2` adds blockers along the guard's path and counts the instances where he starts walking in a cycle. - -To make a 90º turn in 2D you need swap the coordinates and multiply _one_ of them by -1. The turn can be clockwise or counterclockwise, it depends on which coordinate was multiplied. - -Here we use complex numbers to represent coordinates, and we get the same effect by simply multiplying with ImaginaryOne or `i`. `-i` turns right, and `i` to left (but this depends on how you draw your coordinate system of course, 'i' points upwards in mine). - -It's not complicated at all, but if sounds a bit magical to You, try it out on a few vectors by hand. diff --git a/2024/Day06/Solution.cs b/2024/Day06/Solution.cs deleted file mode 100644 index 9b493893e..000000000 --- a/2024/Day06/Solution.cs +++ /dev/null @@ -1,63 +0,0 @@ -namespace AdventOfCode.Y2024.Day06; - -using System; -using System.Collections.Generic; -using System.Collections.Immutable; -using System.Linq; -using System.Numerics; -using Map = System.Collections.Immutable.ImmutableDictionary; - -[ProblemName("Guard Gallivant")] -class Solution : Solver { - - Complex Up = Complex.ImaginaryOne; - Complex TurnRight = -Complex.ImaginaryOne; - - public object PartOne(string input) { - var (map, start) = Parse(input); - return Walk(map, start).positions.Count(); - } - - public object PartTwo(string input) { - var (map, start) = Parse(input); - // try a blocker in each locations visited by the guard counting the loops - return Walk(map, start).positions - .AsParallel() - .Count(pos => Walk(map.SetItem(pos, '#'), start).isLoop); - - } - - // returns the positions visited when starting from 'pos', isLoop is set if the - // guard enters a cycle. - (IEnumerable positions, bool isLoop) Walk(Map map, Complex pos) { - var seen = new HashSet<(Complex pos, Complex dir)>(); - var dir = Up; - while (map.ContainsKey(pos) && !seen.Contains((pos, dir))) { - seen.Add((pos, dir)); - if (map.GetValueOrDefault(pos + dir) == '#') { - dir *= TurnRight; - } else { - pos += dir; - } - } - return ( - positions: seen.Select(s => s.pos).Distinct(), - isLoop: seen.Contains((pos, dir)) - ); - } - - // store the grid in a dictionary, to make bounds checks and navigation simple - // start represents the starting postion of the guard - (Map map, Complex start) Parse(string input) { - var lines = input.Split("\n"); - var map = ( - from y in Enumerable.Range(0, lines.Length) - from x in Enumerable.Range(0, lines[0].Length) - select new KeyValuePair(-Up * y + x, lines[y][x]) - ).ToImmutableDictionary(); - - var start = map.First(x => x.Value == '^').Key; - - return (map, start); - } -} \ No newline at end of file diff --git a/2024/Day06/illustration.jpeg b/2024/Day06/illustration.jpeg deleted file mode 100644 index 62e5e4349..000000000 Binary files a/2024/Day06/illustration.jpeg and /dev/null differ diff --git a/2024/Day06/input.in b/2024/Day06/input.in deleted file mode 100644 index 6d740e90a..000000000 Binary files a/2024/Day06/input.in and /dev/null differ diff --git a/2024/Day06/input.refout b/2024/Day06/input.refout deleted file mode 100644 index cd63e0fc5..000000000 --- a/2024/Day06/input.refout +++ /dev/null @@ -1,2 +0,0 @@ -4789 -1304 \ No newline at end of file diff --git a/2024/Day07/README.md b/2024/Day07/README.md deleted file mode 100644 index 902b0774d..000000000 --- a/2024/Day07/README.md +++ /dev/null @@ -1,12 +0,0 @@ -## --- Day 7: Bridge Repair --- -The Historians take you to a familiar _rope bridge_ over a river in the middle of a jungle. The Chief isn't on this side of the bridge, though; maybe he's on the other side? - -When you go to cross the bridge, you notice a group of engineers trying to repair it. (Apparently, it breaks pretty frequently.) You won't be able to cross until it's fixed. - -_Visit the website for the full story and [puzzle](https://adventofcode.com/2024/day/7) description._ - -It's time to pull out the recursion guns. I introduced a checker logic that goes through the numbers in one line of input and tries all possible operators on the accumulated result to reach the target. - -The common logic that parses the input and executes the checker was extracted into a single `Solve` function, but I found it more readable to have distinct checkers for the two parts of the problem. - -Everything runs in about a second, but since it's just a single line, I couldn't stand and added an optimization in `Check2` to exit early when the accumulated result exceeds the target. diff --git a/2024/Day07/Solution.cs b/2024/Day07/Solution.cs deleted file mode 100644 index 2cb0af10a..000000000 --- a/2024/Day07/Solution.cs +++ /dev/null @@ -1,41 +0,0 @@ -namespace AdventOfCode.Y2024.Day07; - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text.RegularExpressions; - -[ProblemName("Bridge Repair")] -class Solution : Solver { - - public object PartOne(string input) => Filter(input, Check1).Sum(); - public object PartTwo(string input) => Filter(input, Check2).Sum(); - - // returns those calibrations that are valid according to the checker - private IEnumerable Filter(string input, Func, bool> check) => - from line in input.Split("\n") - let parts = Regex.Matches(line, @"\d+").Select(m=>long.Parse(m.Value)) - let target = parts.First() - let nums = parts.Skip(1).ToList() - where check(target, nums[0], nums[1..]) - select target; - - // separate checkers provided for the two parts, these recursive functions go - // over the numbers and use all allowed operators to update the accumulated result. - // at the end of the recursion we simply check if we reached the target - private bool Check1(long target, long acc, List nums) => - nums switch { - [] => target == acc, - _ => Check1(target, acc * nums[0], nums[1..]) || - Check1(target, acc + nums[0], nums[1..]) - }; - - private bool Check2(long target, long acc, List nums) => - nums switch { - _ when acc > target => false, // optimization: early exit from deadend - [] => target == acc, - _ => Check2(target, long.Parse($"{acc}{nums[0]}"), nums[1..]) || - Check2(target, acc * nums[0], nums[1..]) || - Check2(target, acc + nums[0], nums[1..]) - }; -} diff --git a/2024/Day07/illustration.jpeg b/2024/Day07/illustration.jpeg deleted file mode 100644 index f08fd6f20..000000000 Binary files a/2024/Day07/illustration.jpeg and /dev/null differ diff --git a/2024/Day07/input.in b/2024/Day07/input.in deleted file mode 100644 index 723bf50a4..000000000 Binary files a/2024/Day07/input.in and /dev/null differ diff --git a/2024/Day07/input.refout b/2024/Day07/input.refout deleted file mode 100644 index 7a69a12ba..000000000 --- a/2024/Day07/input.refout +++ /dev/null @@ -1,2 +0,0 @@ -6231007345478 -333027885676693 \ No newline at end of file diff --git a/2024/Day08/README.md b/2024/Day08/README.md deleted file mode 100644 index fcfa0971a..000000000 --- a/2024/Day08/README.md +++ /dev/null @@ -1,14 +0,0 @@ -## --- Day 8: Resonant Collinearity --- -You find yourselves on the _roof_ of a top-secret Easter Bunny installation. - -While The Historians do their thing, you take a look at the familiar huge antenna. Much to your surprise, it seems to have been reconfigured to emit a signal that makes people 0.1% more likely to buy Easter Bunny brand Imitation Mediocre Chocolate as a Christmas gift! Unthinkable! - -_Visit the website for the full story and [puzzle](https://adventofcode.com/2024/day/8) description._ - -Continuing the steps I started yesterday, I extracted a common function (`GetUniquePositions`) that takes a parameter to generate antinode positions, representing the difference between part one and part two. - -`getAntinodes` returns the antinode positions of srcAntenna on the dstAntenna side. It doesn’t need to be symmetric — i.e., it doesn’t have to return the antinodes on the srcAntenna side — because GetUniquePositions will call it with the parameters swapped as well. This allows us to handle only one direction at a time. - -The generators are fairly straightforward: I simply take steps in the direction determined by the antennas, starting from the destination. Since I represented coordinates using complex numbers again, there’s no need for any special handling on the algebra side, regular + and - operations work. - -The `GetAntinodes` delegate is introduced only for documentation purposes. It looks better to my eyes than an ugly `Func<>` with four type parameters would in `GetUniquePositions`-s signature. diff --git a/2024/Day08/Solution.cs b/2024/Day08/Solution.cs deleted file mode 100644 index e3c4c4695..000000000 --- a/2024/Day08/Solution.cs +++ /dev/null @@ -1,66 +0,0 @@ -namespace AdventOfCode.Y2024.Day08; - -using System; -using System.Collections.Generic; -using System.Collections.Immutable; -using System.Linq; -using System.Numerics; - -using Map = System.Collections.Immutable.ImmutableDictionary; - -[ProblemName("Resonant Collinearity")] -class Solution : Solver { - public object PartOne(string input) => GetUniquePositions(input, GetAntinodes1).Count(); - public object PartTwo(string input) => GetUniquePositions(input, GetAntinodes2).Count(); - - HashSet GetUniquePositions(string input, GetAntinodes getAntinodes) { - var map = GetMap(input); - - var antennaLocations = ( - from pos in map.Keys - where char.IsAsciiLetterOrDigit(map[pos]) - select pos - ).ToArray(); - - return ( - from srcAntenna in antennaLocations - from dstAntenna in antennaLocations - where srcAntenna != dstAntenna && map[srcAntenna] == map[dstAntenna] - from antinode in getAntinodes(srcAntenna, dstAntenna, map) - select antinode - ).ToHashSet(); - } - - // returns the antinode positions of srcAntenna on the dstAntenna side - delegate IEnumerable GetAntinodes(Complex srcAntenna, Complex dstAntenna, Map map); - - // in part 1 we just look at the immediate neighbour - IEnumerable GetAntinodes1(Complex srcAntenna, Complex dstAntenna, Map map) { - var dir = dstAntenna - srcAntenna; - var antinote = dstAntenna + dir; - if (map.Keys.Contains(antinote)) { - yield return antinote; - } - } - - // in part 2 this becomes a cycle, plus dstAntenna is also a valid position now - IEnumerable GetAntinodes2(Complex srcAntenna, Complex dstAntenna, Map map) { - var dir = dstAntenna - srcAntenna; - var antinote = dstAntenna; - while (map.Keys.Contains(antinote)) { - yield return antinote; - antinote += dir; - } - } - - // store the points in a dictionary so that we can iterate over them and - // to easily deal with points outside the area using GetValueOrDefault - Map GetMap(string input) { - var map = input.Split("\n"); - return ( - from y in Enumerable.Range(0, map.Length) - from x in Enumerable.Range(0, map[0].Length) - select new KeyValuePair(x - y * Complex.ImaginaryOne, map[y][x]) - ).ToImmutableDictionary(); - } -} \ No newline at end of file diff --git a/2024/Day08/illustration.jpeg b/2024/Day08/illustration.jpeg deleted file mode 100644 index c15028cbf..000000000 Binary files a/2024/Day08/illustration.jpeg and /dev/null differ diff --git a/2024/Day08/input.in b/2024/Day08/input.in deleted file mode 100644 index 8b2c34647..000000000 Binary files a/2024/Day08/input.in and /dev/null differ diff --git a/2024/Day08/input.refout b/2024/Day08/input.refout deleted file mode 100644 index fb3dee4bd..000000000 --- a/2024/Day08/input.refout +++ /dev/null @@ -1,2 +0,0 @@ -247 -861 \ No newline at end of file diff --git a/2024/Day09/README.md b/2024/Day09/README.md deleted file mode 100644 index be72beecb..000000000 --- a/2024/Day09/README.md +++ /dev/null @@ -1,10 +0,0 @@ -## --- Day 9: Disk Fragmenter --- -Another push of the button leaves you in the familiar hallways of some friendly _amphipods_! Good thing you each somehow got your own personal mini submarine. The Historians jet away in search of the Chief, mostly by driving directly into walls. - -While The Historians quickly figure out how to pilot these things, you notice an amphipod in the corner struggling with his computer. He's trying to make more contiguous free space by compacting all of the files, but his program isn't working; you offer to help. - -_Visit the website for the full story and [puzzle](https://adventofcode.com/2024/day/9) description._ - -I'm taking a break from using LINQ today and turning my attention to the low-level world of linked lists instead. I discovered a way to express both paths using a single `CompactFs` function with a `fragmentsEnabled` parameter. `CompactFs` operates with two pointers, `i` and `j`, which define the scan range we’re working on. `i` starts at the beginning of the disk, while `j` starts at the end and moves backward. When `i` points to a free space and `j` points to a used space, we call `RelocateBlock`, which moves `j` (or parts of `j`, depending on whether fragmentation is enabled) to a free space found after `i`. - -The rest involves careful pointer arithmetic and linked list management, where I aim to avoid overwriting the data I’ll need in the next line. I find this surprisingly hard to get right when working with linked lists... diff --git a/2024/Day09/Solution.cs b/2024/Day09/Solution.cs deleted file mode 100644 index 0622a6368..000000000 --- a/2024/Day09/Solution.cs +++ /dev/null @@ -1,78 +0,0 @@ -namespace AdventOfCode.Y2024.Day09; - -using System.Linq; - -using Fs = System.Collections.Generic.LinkedList; -using Node = System.Collections.Generic.LinkedListNode; -record struct Block(int fileId, int length) { } - -[ProblemName("Disk Fragmenter")] -class Solution : Solver { - - public object PartOne(string input) => Checksum(CompactFs(Parse(input), fragmentsEnabled: true)); - - public object PartTwo(string input) => Checksum(CompactFs(Parse(input), fragmentsEnabled: false)); - - // moves used blocks of the filesystem towards the beginning of the disk using RelocateBlock - Fs CompactFs(Fs fs, bool fragmentsEnabled) { - var (i, j) = (fs.First, fs.Last); - while (i != j) { - if (i.Value.fileId != -1) { - i = i.Next; - } else if (j.Value.fileId == -1) { - j = j.Previous; - } else { - RelocateBlock(fs, i, j, fragmentsEnabled); - j = j.Previous; - } - } - return fs; - } - - // Relocates the contents of block `j` to a free space starting after the given node `start`. - // - Searches for the first suitable free block after `start`. - // - If a block of equal size is found, `j` is moved entirely to that block. - // - If a larger block is found, part of it is used for `j`, and the remainder is split into - // a new free block. - // - If a smaller block is found and fragmentation is enabled, a portion of `j` is moved to fit, - // leaving the remainder in place. - void RelocateBlock(Fs fs, Node start, Node j, bool fragmentsEnabled) { - for (var i = start; i != j; i = i.Next) { - if (i.Value.fileId != -1) { - // noop - } else if (i.Value.length == j.Value.length) { - (i.Value, j.Value) = (j.Value, i.Value); - return; - } else if (i.Value.length > j.Value.length) { - var d = i.Value.length - j.Value.length; - i.Value = j.Value; - j.Value = j.Value with { fileId = -1 }; - fs.AddAfter(i, new Block(-1, d)); - return; - } else if (i.Value.length < j.Value.length && fragmentsEnabled) { - var d = j.Value.length - i.Value.length; - i.Value = i.Value with { fileId = j.Value.fileId }; - j.Value = j.Value with { length = d }; - fs.AddAfter(j, new Block(-1, i.Value.length)); - } - } - } - - long Checksum(Fs fs) { - var res = 0L; - var l = 0; - for (var i = fs.First; i != null; i = i.Next) { - for (var k = 0; k < i.Value.length; k++) { - if (i.Value.fileId != -1) { - res += l * i.Value.fileId; - } - l++; - } - } - return res; - } - - Fs Parse(string input) { - return new Fs(input.Select((ch, i) => new Block(i % 2 == 1 ? -1 : i / 2, ch - '0'))); - } -} diff --git a/2024/Day09/illustration.jpeg b/2024/Day09/illustration.jpeg deleted file mode 100644 index 7e5c69dd3..000000000 Binary files a/2024/Day09/illustration.jpeg and /dev/null differ diff --git a/2024/Day09/input.in b/2024/Day09/input.in deleted file mode 100644 index 8e4220afb..000000000 Binary files a/2024/Day09/input.in and /dev/null differ diff --git a/2024/Day09/input.refout b/2024/Day09/input.refout deleted file mode 100644 index 59f6af771..000000000 --- a/2024/Day09/input.refout +++ /dev/null @@ -1,2 +0,0 @@ -6448989155953 -6476642796832 \ No newline at end of file diff --git a/2024/Day10/README.md b/2024/Day10/README.md deleted file mode 100644 index e0d8711b7..000000000 --- a/2024/Day10/README.md +++ /dev/null @@ -1,14 +0,0 @@ -## --- Day 10: Hoof It --- -You all arrive at a _Lava Production Facility_ on a floating island in the sky. As the others begin to search the massive industrial complex, you feel a small nose boop your leg and look down to discover a reindeer wearing a hard hat. - -The reindeer is holding a book titled "Lava Island Hiking Guide". However, when you open the book, you discover that most of it seems to have been scorched by lava! As you're about to ask how you can help, the reindeer brings you a blank [topographic map](https://en.wikipedia.org/wiki/Topographic_map) of the surrounding area (your puzzle input) and looks up at you excitedly. - -_Visit the website for the full story and [puzzle](https://adventofcode.com/2024/day/10) description._ - -Today's problem is surprisingly straightforward compared to yesterday's pointer juggling. We finally get to use our favorite queue data structure to implement a flood fill. I saw this coming... - -As usual, we use a dictionary with complex numbers to parse the input. The meat of the solution is in `GetTrailsFrom`, which returns all trails starting at a specific trailhead. - -The difference between `Part 1` and `Part 2` lies in how distinct trails are defined. I decided to return all trails keyed by their trailheads in `GetAllTrails` and delegate the distinctness logic to `PartOne` and `PartTwo`. - -A nice and easy task for today! diff --git a/2024/Day10/Solution.cs b/2024/Day10/Solution.cs deleted file mode 100644 index 1b882279f..000000000 --- a/2024/Day10/Solution.cs +++ /dev/null @@ -1,59 +0,0 @@ -namespace AdventOfCode.Y2024.Day10; - -using System; -using System.Collections.Generic; -using System.Collections.Immutable; -using System.Linq; -using System.Numerics; - -using Map = System.Collections.Immutable.ImmutableDictionary; - -[ProblemName("Hoof It")] -class Solution : Solver { - - Complex Up = Complex.ImaginaryOne; - Complex Down = -Complex.ImaginaryOne; - Complex Left = -1; - Complex Right = 1; - - public object PartOne(string input) => GetAllTrails(input).Sum(t => t.Value.Distinct().Count()); - public object PartTwo(string input) => GetAllTrails(input).Sum(t => t.Value.Count()); - - Dictionary> GetAllTrails(string input) { - var map = GetMap(input); - return GetTrailHeads(map).ToDictionary(t => t, t => GetTrailsFrom(map, t)); - } - - IEnumerable GetTrailHeads(Map map) => map.Keys.Where(pos => map[pos] == '0'); - - List GetTrailsFrom(Map map, Complex trailHead) { - // standard floodfill algorithm using a queue - var positions = new Queue(); - positions.Enqueue(trailHead); - var trails = new List(); - while (positions.Any()) { - var point = positions.Dequeue(); - if (map[point] == '9') { - trails.Add(point); - } else { - foreach (var dir in new[] { Up, Down, Left, Right }) { - if (map.GetValueOrDefault(point + dir) == map[point] + 1) { - positions.Enqueue(point + dir); - } - } - } - } - return trails; - } - - // store the points in a dictionary so that we can iterate over them and - // to easily deal with points outside the area using GetValueOrDefault - Map GetMap(string input) { - var map = input.Split("\n"); - return ( - from y in Enumerable.Range(0, map.Length) - from x in Enumerable.Range(0, map[0].Length) - select new KeyValuePair(x + y * Down, map[y][x]) - ).ToImmutableDictionary(); - } -} diff --git a/2024/Day10/illustration.jpeg b/2024/Day10/illustration.jpeg deleted file mode 100644 index 4c66aecd0..000000000 Binary files a/2024/Day10/illustration.jpeg and /dev/null differ diff --git a/2024/Day10/input.in b/2024/Day10/input.in deleted file mode 100644 index c5e8a9c7c..000000000 Binary files a/2024/Day10/input.in and /dev/null differ diff --git a/2024/Day10/input.refout b/2024/Day10/input.refout deleted file mode 100644 index 2f0670b4a..000000000 --- a/2024/Day10/input.refout +++ /dev/null @@ -1,2 +0,0 @@ -674 -1372 \ No newline at end of file diff --git a/2024/Day11/README.md b/2024/Day11/README.md deleted file mode 100644 index 4d9b8030a..000000000 --- a/2024/Day11/README.md +++ /dev/null @@ -1,14 +0,0 @@ -## --- Day 11: Plutonian Pebbles --- -The ancient civilization on _Pluto_ was known for its ability to manipulate spacetime, and while The Historians explore their infinite corridors, you've noticed a strange set of physics-defying stones. - -At first glance, they seem like normal stones: they're arranged in a perfectly straight line, and each stone has a number engraved on it. - -_Visit the website for the full story and [puzzle](https://adventofcode.com/2024/day/11) description._ - -Today is all about dynamic programming and cached calculations. Our goal is to determine the number of stones based on specific rules derived from the numbers engraved on them. Without careful optimization, this process can quickly spiral out of control. - -To address this, I encoded the stone generation logic inside the `Eval` function and added a cache to prevent exponential growth. - -I discovered the `ConcurrentDictionary` class, which includes a convenient `GetOrAdd` method. While this functionality is missing in regular `Dictionary` variants, it allows the caching logic to be neatly encapsulated in a single place. I decided to "abuse" it a bit here, even though my solution doesn’t involve any concurrency at all. - -There is an iterative approach to solving this problem as well, which progresses one blink at a time while keeping track of how many times each number occurs at each step. Working through this approach is left as an exercise for the reader. \ No newline at end of file diff --git a/2024/Day11/Solution.cs b/2024/Day11/Solution.cs deleted file mode 100644 index f5bb4786b..000000000 --- a/2024/Day11/Solution.cs +++ /dev/null @@ -1,38 +0,0 @@ -namespace AdventOfCode.Y2024.Day11; - -using System.Linq; - -using Cache = System.Collections.Concurrent.ConcurrentDictionary<(string, int), long>; - -[ProblemName("Plutonian Pebbles")] -class Solution : Solver { - - public object PartOne(string input) => StoneCount(input, 25); - - public object PartTwo(string input) => StoneCount(input, 75); - - long StoneCount(string input, int blinks) { - var cache = new Cache(); - return input.Split(" ").Sum(n => Eval(long.Parse(n), blinks, cache)); - } - - // Recursively calculates the total number of stones generated by a single engravement (n) - // after a specified number of blinks. Uses caching to optimize and prevent exponential - // computation by storing intermediate results. - long Eval(long n, int blinks, Cache cache) => - cache.GetOrAdd((n.ToString(), blinks), key => - key switch { - (_, 0) => 1, - - ("0", _) => - Eval(1, blinks - 1, cache), - - (var st, _) when st.Length % 2 == 0 => - Eval(long.Parse(st[0..(st.Length / 2)]), blinks - 1, cache) + - Eval(long.Parse(st[(st.Length / 2)..]), blinks - 1, cache), - - _ => - Eval(2024 * n, blinks - 1, cache) - } - ); -} \ No newline at end of file diff --git a/2024/Day11/illustration.jpeg b/2024/Day11/illustration.jpeg deleted file mode 100644 index 04d52a2c8..000000000 Binary files a/2024/Day11/illustration.jpeg and /dev/null differ diff --git a/2024/Day11/input.in b/2024/Day11/input.in deleted file mode 100644 index 5a4dfc848..000000000 Binary files a/2024/Day11/input.in and /dev/null differ diff --git a/2024/Day11/input.refout b/2024/Day11/input.refout deleted file mode 100644 index 75b88057d..000000000 --- a/2024/Day11/input.refout +++ /dev/null @@ -1,2 +0,0 @@ -189547 -224577979481346 \ No newline at end of file diff --git a/2024/Day12/README.md b/2024/Day12/README.md deleted file mode 100644 index d8fdb2ff0..000000000 --- a/2024/Day12/README.md +++ /dev/null @@ -1,31 +0,0 @@ -## --- Day 12: Garden Groups --- -Why not search for the Chief Historian near the _gardener_ and his _massive farm_? There's plenty of food, so The Historians grab something to eat while they search. - -You're about to settle near a complex arrangement of garden plots when some Elves ask if you can lend a hand. They'd like to set up fences around each region of garden plots, but they can't figure out how much fence they need to order or how much it will cost. They hand you a map (your puzzle input) of the garden plots. - -_Visit the website for the full story and [puzzle](https://adventofcode.com/2024/day/12) description._ - -One can sense that the difficulty has ramped up today with a more complex problem involving area and perimeter calculations. - -First we determine the connected components (regions) of plants of the same type. This is done by picking a position of the -garden and applying a standard flood-fill algorithm to it. The result is a _region_. As we process each region, we carefully -remove all affected positions and then pick an untouched position to repeat the process. In a few iterations, the entire -garden is associated with the correct regions. The size of the regions corresponds to the _area_ in question. This logic -is implemented in the `GetRegions` function below. - -The second part of the problem, however, is more intriguing: how do we calculate the lengths of the fences? In part 1, this is -relatively simple because we just iterate through each region and count the neighboring cells that belong to a different regions. -This tells how many fence is needed. Unfortunately, this logic doesn't work for part 2... - -I attempted to implement a "walk-around" approach, which involves finding a fence segment and tracing it like a line-following -robot while counting the turns. The challenge with this approach is that some regions have holes, that require fences as well -and I didnt want to implement hole finding. - -Later realized that it is probably more straightforward to collect the fence segments along straight lines scanning the garden -from top to bottom an right to left. This is how I solved the problem. - -Finally went to reddit and read the hint: the number of segments equal to the number of corners... In other words difference -between part 1 and 2 is very small. In part 1 we are building an edge detector which becomes a corner detector in part 2. I changed -my implementation to that. - -This concludes our day 12. I'll take an extra ⭐ for learning something new again. diff --git a/2024/Day12/Solution.cs b/2024/Day12/Solution.cs deleted file mode 100644 index f169d9a40..000000000 --- a/2024/Day12/Solution.cs +++ /dev/null @@ -1,113 +0,0 @@ -namespace AdventOfCode.Y2024.Day12; - -using System; -using System.Collections.Generic; -using System.Collections.Immutable; -using System.Linq; -using System.Numerics; - -using Region = System.Collections.Generic.HashSet; - -[ProblemName("Garden Groups")] -class Solution : Solver { - - Complex Up = Complex.ImaginaryOne; - Complex Down = -Complex.ImaginaryOne; - Complex Left = -1; - Complex Right = 1; - - public object PartOne(string input) => CalculateFencePrice(input, FindEdges); - - public object PartTwo(string input) => CalculateFencePrice(input, FindCorners); - - int CalculateFencePrice(string input, MeasurePerimeter measure){ - var regions = GetRegions(input); - var res = 0; - foreach (var region in regions.Values.Distinct()) { - var perimeter = 0; - foreach (var pt in region) { - perimeter += measure(regions, pt); - } - res += region.Count() * perimeter; - } - return res; - } - - delegate int MeasurePerimeter(Dictionary map, Complex pt); - - int FindEdges(Dictionary map, Complex pt) { - var res = 0; - var region = map[pt]; - foreach (var du in new[] { Right, Down, Left, Up}) { - // x. - if (map.GetValueOrDefault(pt + du) != region) { - res++; - } - } - return res; - } - - int FindCorners(Dictionary map, Complex pt) { - var res = 0; - var region = map[pt]; - - // check the 4 corner types - foreach (var (du, dv) in new[] { (Up, Right), (Right, Down), (Down, Left), (Left, Up) }) { - // .. - // x. convex corner - if (map.GetValueOrDefault(pt + du) != region && - map.GetValueOrDefault(pt + dv) != region - ) { - res++; - } - - // x. - // xx concave corner - if (map.GetValueOrDefault(pt + du) == region && - map.GetValueOrDefault(pt + dv) == region && - map.GetValueOrDefault(pt + du + dv) != region - ) { - res++; - } - } - return res; - } - - // Maps the positions of plants in a garden to their corresponding regions, grouping plants - // of the same type into contiguous regions. - Dictionary GetRegions(string input) { - var lines = input.Split("\n"); - var garden = ( - from y in Enumerable.Range(0, lines.Length) - from x in Enumerable.Range(0, lines[0].Length) - select new KeyValuePair(x + y * Down, lines[y][x]) - ).ToDictionary(); - - // go over the positions of the garden and use a floodfill to determine the region - var res = new Dictionary(); - var positions = garden.Keys.ToHashSet(); - while (positions.Any()) { - var pivot = positions.First(); - var region = new Region { pivot }; - - var q = new Queue(); - q.Enqueue(pivot); - - var plant = garden[pivot]; - - while (q.Any()) { - var point = q.Dequeue(); - res[point] = region; - positions.Remove(point); - foreach (var dir in new[] { Up, Down, Left, Right }) { - if (!region.Contains(point + dir) && garden.GetValueOrDefault(point + dir) == plant) { - region.Add(point + dir); - q.Enqueue(point + dir); - } - } - } - } - return res; - } - -} diff --git a/2024/Day12/illustration.jpeg b/2024/Day12/illustration.jpeg deleted file mode 100644 index 62c1d43f1..000000000 Binary files a/2024/Day12/illustration.jpeg and /dev/null differ diff --git a/2024/Day12/input.in b/2024/Day12/input.in deleted file mode 100644 index 87382f822..000000000 Binary files a/2024/Day12/input.in and /dev/null differ diff --git a/2024/Day12/input.refout b/2024/Day12/input.refout deleted file mode 100644 index 03255f67a..000000000 --- a/2024/Day12/input.refout +++ /dev/null @@ -1,2 +0,0 @@ -1374934 -841078 \ No newline at end of file diff --git a/2024/Day13/README.md b/2024/Day13/README.md deleted file mode 100644 index 12fb1f33f..000000000 --- a/2024/Day13/README.md +++ /dev/null @@ -1,8 +0,0 @@ -## --- Day 13: Claw Contraption --- -Next up: the [lobby](/2020/day/24) of a resort on a tropical island. The Historians take a moment to admire the hexagonal floor tiles before spreading out. - -Fortunately, it looks like the resort has a new [arcade](https://en.wikipedia.org/wiki/Amusement_arcade)! Maybe you can win some prizes from the [claw machines](https://en.wikipedia.org/wiki/Claw_machine)? - -_Visit the website for the full story and [puzzle](https://adventofcode.com/2024/day/13) description._ - -We got a math problem today. The movements triggered by buttons A, B and the target position P form a linear equation that we can solve for the two unknowns: the number of button presses. Using math terms, if _i_ and _j_ marks the number of button presses, we are to solve `A * i + B * j = P`. This is simple enough to do using [Cramer's rule](https://en.wikipedia.org/wiki/Cramer%27s_rule), especially with two dimensional vectors. In this case the determinats can be computed with a simple cross product. We should not forget about the special cases: A and B can be parallel (didn't occur in my input), and the solution needs to be non negative integer for _i_ and _j_. \ No newline at end of file diff --git a/2024/Day13/Solution.cs b/2024/Day13/Solution.cs deleted file mode 100644 index a37e1f094..000000000 --- a/2024/Day13/Solution.cs +++ /dev/null @@ -1,46 +0,0 @@ -namespace AdventOfCode.Y2024.Day13; - -using System.Collections.Generic; -using System.Linq; -using System.Text.RegularExpressions; -using Machine = (Vec2 a, Vec2 b, Vec2 p); - -record struct Vec2(long x, long y); - -[ProblemName("Claw Contraption")] -class Solution : Solver { - - public object PartOne(string input) => Parse(input).Sum(GetPrize); - public object PartTwo(string input) => Parse(input, shift: 10000000000000).Sum(GetPrize); - - long GetPrize(Machine m) { - var (a, b, p) = m; - - // solve a * i + b * j = p for i and j using Cramer's rule - var i = Det(p, b) / Det(a, b); - var j = Det(a, p) / Det(a, b); - - // return the prize when a non negative _integer_ solution is found - if (i >= 0 && j >= 0 && a.x * i + b.x * j == p.x && a.y * i + b.y * j == p.y) { - return 3 * i + j; - } else { - return 0; - } - } - - long Det(Vec2 a, Vec2 b) => a.x * b.y - a.y * b.x; - - IEnumerable Parse(string input, long shift=0) { - var blocks = input.Split("\n\n"); - foreach (var block in blocks) { - var nums = - Regex.Matches(block, @"\d+", RegexOptions.Multiline) - .Select(m => int.Parse(m.Value)) - .Chunk(2).Select(p => new Vec2(p[0], p[1])) - .ToArray(); - - nums[2] = new Vec2(nums[2].x + shift, nums[2].y + shift); - yield return (nums[0], nums[1], nums[2]); - } - } -} \ No newline at end of file diff --git a/2024/Day13/illustration.jpeg b/2024/Day13/illustration.jpeg deleted file mode 100644 index a62957630..000000000 Binary files a/2024/Day13/illustration.jpeg and /dev/null differ diff --git a/2024/Day13/input.in b/2024/Day13/input.in deleted file mode 100644 index 10f78d949..000000000 Binary files a/2024/Day13/input.in and /dev/null differ diff --git a/2024/Day13/input.refout b/2024/Day13/input.refout deleted file mode 100644 index 78a92a9e3..000000000 --- a/2024/Day13/input.refout +++ /dev/null @@ -1,2 +0,0 @@ -32041 -95843948914827 \ No newline at end of file diff --git a/2024/Day14/README.md b/2024/Day14/README.md deleted file mode 100644 index 9c226b17a..000000000 --- a/2024/Day14/README.md +++ /dev/null @@ -1,50 +0,0 @@ -## --- Day 14: Restroom Redoubt --- -One of The Historians needs to use the bathroom; fortunately, you know there's a bathroom near an unvisited location on their list, and so you're all quickly teleported directly to the lobby of Easter Bunny Headquarters. - -Unfortunately, EBHQ seems to have "improved" bathroom security again after your last [visit](/2016/day/2). The area outside the bathroom is swarming with robots! - -_Visit the website for the full story and [full puzzle](https://adventofcode.com/2024/day/14) description._ - -A nice simulation challenge for today. `Part 1` was straightforward: iterate 100 times and count the robots in the different quadrants. - -I’d bet many of us anticipated some `least common multiple` or `Chinese Remainder Theorem` magic for `Part 2`, but Eric threw us a curveball by making us search for a Christmas tree pattern in the robot’s movement. - -The expected output wasn’t clearly specified — other than the fact that it should resemble a Christmas tree. I wrote a plot function to display the robot’s locations on the screen, dumped everything into a long file, and manually inspected it in my editor. - -Later, to automate this process, decided to search for a longer horizontal '####' pattern in the output: - -``` - ############################### - # # # # - # # # - # # # - # # # # - # # # - # ### # # - # ##### # - # # ####### # - # # ######### # # - # ##### # - # # ####### # - # ######### # - # ########### # - # ############# # # # - # ######### # - # # ########### # # - # # ############# # - # ############### # # # - # ################# # # - # ############# # - # ############### # - # ################# # - # ################### # - # # ##################### # - # ### # - # ### # # - # # ### # # - # # # - # # # - # # # - # # # # - # ############################### -``` \ No newline at end of file diff --git a/2024/Day14/Solution.cs b/2024/Day14/Solution.cs deleted file mode 100644 index 72850bf90..000000000 --- a/2024/Day14/Solution.cs +++ /dev/null @@ -1,69 +0,0 @@ -namespace AdventOfCode.Y2024.Day14; - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Text.RegularExpressions; -record struct Vec2(int x, int y); -record struct Robot(Vec2 pos, Vec2 vel); - -[ProblemName("Restroom Redoubt")] -class Solution : Solver { - const int width = 101; - const int height = 103; - - // run the simulation for 100 steps and count the robots in the different quadrants. - public object PartOne(string input) => - Simulate(input) - .ElementAt(100) - .CountBy(GetQuadrant) - .Where(group => group.Key.x != 0 && group.Key.y != 0) - .Aggregate(1, (acc, group) => acc * group.Value); - - // I figured that the xmas tree pattern has a long horizontal ### pattern in it - public object PartTwo(string input) => - Simulate(input) - .TakeWhile(robots => !Plot(robots).Contains("#################")) - .Count(); - - // an infinite simulation of robot movement - IEnumerable Simulate(string input) { - var robots = Parse(input).ToArray(); - while (true) { - yield return robots; - robots = robots.Select(Step).ToArray(); - } - } - - // advance a robot by its velocity taking care of the 'teleportation' - Robot Step(Robot robot) => robot with {pos = AddWithWrapAround(robot.pos, robot.vel) }; - - // returns the direction (-1/0/1) of the robot to the center of the room - Vec2 GetQuadrant(Robot robot) => - new Vec2(Math.Sign(robot.pos.x - width / 2), Math.Sign(robot.pos.y - height / 2)); - - Vec2 AddWithWrapAround(Vec2 a, Vec2 b) => - new Vec2((a.x + b.x + width) % width, (a.y + b.y + height) % height); - - // shows the robot locations in the room - string Plot(IEnumerable robots) { - var res = new char[height, width]; - foreach (var robot in robots) { - res[robot.pos.y, robot.pos.x] = '#'; - } - var sb = new StringBuilder(); - for (var y = 0; y < height; y++) { - for (var x = 0; x < width; x++) { - sb.Append(res[y, x] == '#' ? "#" : " "); - } - sb.AppendLine(); - } - return sb.ToString(); - } - - IEnumerable Parse(string input) => - from line in input.Split("\n") - let nums = Regex.Matches(line, @"-?\d+").Select(m => int.Parse(m.Value)).ToArray() - select new Robot(new Vec2(nums[0], nums[1]), new Vec2(nums[2], nums[3])); -} \ No newline at end of file diff --git a/2024/Day14/illustration.jpeg b/2024/Day14/illustration.jpeg deleted file mode 100644 index 1fdaa3615..000000000 Binary files a/2024/Day14/illustration.jpeg and /dev/null differ diff --git a/2024/Day14/input.in b/2024/Day14/input.in deleted file mode 100644 index 28019ec95..000000000 Binary files a/2024/Day14/input.in and /dev/null differ diff --git a/2024/Day14/input.refout b/2024/Day14/input.refout deleted file mode 100644 index 34259b6fe..000000000 --- a/2024/Day14/input.refout +++ /dev/null @@ -1,2 +0,0 @@ -231019008 -8280 \ No newline at end of file diff --git a/2024/Day15/README.md b/2024/Day15/README.md deleted file mode 100644 index 0e8fd4eb6..000000000 --- a/2024/Day15/README.md +++ /dev/null @@ -1,14 +0,0 @@ -## --- Day 15: Warehouse Woes --- -You appear back inside your own mini submarine! Each Historian drives their mini submarine in a different direction; maybe the Chief has his own submarine down here somewhere as well? - -You look up to see a vast school of [lanternfish](/2021/day/6) swimming past you. On closer inspection, they seem quite anxious, so you drive your mini submarine over to see if you can help. - -_Visit the website for the full story and [full puzzle](https://adventofcode.com/2024/day/15) description._ - -A nice Sokoban-style puzzle for the weekend! The main difference is that in the original Sokoban, the robot could push only a single box, not multiple boxes. This adds complexity to both parts of the puzzle. However, it’s not that difficult to handle... I moved the hard parts into the `TryToStep` function that takes the map, a position, and a direction, then attempts to make a move in that direction. - -If the position corresponds to the robot or a box, the function checks whether the neighboring cell is free or can be made free by pushing boxes in the given direction. The .NET API sometimes uses the `TryToDoX` pattern, where a function returns a boolean result and provides an `out` parameter. I reused this pattern here. On success, the updated map is returned via the `ref` parameter. If the move fails, the map remains unchanged. - -The real challenge lies in `part 2`, where recursion needs to branch whenever the robot pushes more than one box at a time. In such cases, we must invoke `TryToStep` for each box. Due to the recursive nature of the algorithm, it’s possible for one branch to succeed while the other fails. When this happens, the entire map must be reset to its original state before we pop from the recursion. This could be quite tricky to manage unless you make copies of the dictionary that holds the state — or, as I did, use an immutable dictionary instead. - -I’m not entirely satisfied with the "if-ladder" structure of the `TryToStep` function, but for now, I don’t have a better idea to handle all the cases in a more readable way. diff --git a/2024/Day15/Solution.cs b/2024/Day15/Solution.cs deleted file mode 100644 index 35261aa50..000000000 --- a/2024/Day15/Solution.cs +++ /dev/null @@ -1,110 +0,0 @@ -namespace AdventOfCode.Y2024.Day15; - -using System; -using System.Collections.Generic; -using System.Collections.Immutable; -using System.Linq; -using System.Numerics; - -using Map = System.Collections.Immutable.IImmutableDictionary; - -[ProblemName("Warehouse Woes")] -class Solution : Solver { - - static Complex Up = -Complex.ImaginaryOne; - static Complex Down = Complex.ImaginaryOne; - static Complex Left = -1; - static Complex Right = 1; - - public object PartOne(string input) => Solve(input); - public object PartTwo(string input) => Solve(ScaleUp(input)); - - public double Solve(string input) { - var (map, steps) = Parse(input); - - var robot = map.Keys.Single(k => map[k] == '@'); - foreach (var dir in steps) { - if (TryToStep(ref map, robot, dir)) { - robot += dir; - } - } - - return map.Keys - .Where(k => map[k] == '[' || map[k] == 'O') - .Sum(box => box.Real + 100 * box.Imaginary); - } - - // Attempts to move the robot in the given direction on the map, pushing boxes as necessary. - // If the move is successful, the map is updated to reflect the new positions and the function returns true. - // Otherwise, the map remains unchanged and the function returns false. - bool TryToStep(ref Map map, Complex pos, Complex dir) { - var mapOrig = map; - - if (map[pos] == '.') { - return true; - } else if (map[pos] == 'O' || map[pos] == '@') { - if (TryToStep(ref map, pos + dir, dir)) { - map = map - .SetItem(pos + dir, map[pos]) - .SetItem(pos, '.'); - return true; - } - } else if (map[pos] == ']') { - return TryToStep(ref map, pos + Left, dir); - } else if (map[pos] == '[') { - if (dir == Left) { - if (TryToStep(ref map, pos + Left, dir)) { - map = map - .SetItem(pos + Left, '[') - .SetItem(pos, ']') - .SetItem(pos + Right, '.'); - return true; - } - } else if (dir == Right) { - if (TryToStep(ref map, pos + 2 * Right, dir)) { - map = map - .SetItem(pos, '.') - .SetItem(pos + Right, '[') - .SetItem(pos + 2 * Right, ']'); - return true; - } - } else { - if (TryToStep(ref map, pos + dir, dir) && TryToStep(ref map, pos + Right + dir, dir)) { - map = map - .SetItem(pos, '.') - .SetItem(pos + Right, '.') - .SetItem(pos + dir, '[') - .SetItem(pos + dir + Right, ']'); - return true; - } - } - } - - map = mapOrig; - return false; - } - - string ScaleUp(string input) => - input.Replace("#", "##").Replace(".", "..").Replace("O", "[]").Replace("@", "@."); - - (Map, Complex[]) Parse(string input) { - var blocks = input.Split("\n\n"); - var lines = blocks[0].Split("\n"); - var map = ( - from y in Enumerable.Range(0, lines.Length) - from x in Enumerable.Range(0, lines[0].Length) - select new KeyValuePair(x + y * Down, lines[y][x]) - ).ToImmutableDictionary(); - - var steps = blocks[1].ReplaceLineEndings("").Select(ch => - ch switch { - '^' => Up, - '<' => Left, - '>' => Right, - 'v' => Down, - _ => throw new Exception() - }); - - return (map, steps.ToArray()); - } -} diff --git a/2024/Day15/illustration.jpeg b/2024/Day15/illustration.jpeg deleted file mode 100644 index 75f133b4a..000000000 Binary files a/2024/Day15/illustration.jpeg and /dev/null differ diff --git a/2024/Day15/input.in b/2024/Day15/input.in deleted file mode 100644 index 4641e0ca4..000000000 Binary files a/2024/Day15/input.in and /dev/null differ diff --git a/2024/Day15/input.refout b/2024/Day15/input.refout deleted file mode 100644 index 2c35fe07a..000000000 --- a/2024/Day15/input.refout +++ /dev/null @@ -1,2 +0,0 @@ -1476771 -1468005 \ No newline at end of file diff --git a/2024/Day16/README.md b/2024/Day16/README.md deleted file mode 100644 index 160ab57ff..000000000 --- a/2024/Day16/README.md +++ /dev/null @@ -1,12 +0,0 @@ -## --- Day 16: Reindeer Maze --- -It's time again for the _Reindeer Olympics_! This year, the big event is the Reindeer Maze, where the Reindeer compete for the lowest score. - -You and The Historians arrive to search for the Chief right as the event is about to start. It wouldn't hurt to watch a little, right? - -_Visit the website for the full story and [full puzzle](https://adventofcode.com/2024/day/16) description._ - -I spent hell a lot of time on this one. I’m not sure why, because I had a good understanding of what to do for both parts. `Part 1` went reasonably well: I quickly used a priority queue based approach to find the shortest path from the `start` state to the `goal`. - -For `Part 2`, I tried a few dead ends, because I overcomplicate things as usual. But I found the right direction after about half an hour. The idea is to split the problem into two halves. First, we compute the optimal distances from every tile and direction to the goal node. This can be found using _Dijskstra's algorithm_. - -Once I have the distances, I can start an other round, now working forward from the start position and using a flood-fill-like algorithm to discover the positions on the shortest path. This is easy to do with the distance map as a guide. I maintain the 'remaining score' along the path, and just need to check if the distance from a potential next state equals to the score I still have to use. This logic can be found in the `FindBestSpots` function. diff --git a/2024/Day16/Solution.cs b/2024/Day16/Solution.cs deleted file mode 100644 index 89f5bd78e..000000000 --- a/2024/Day16/Solution.cs +++ /dev/null @@ -1,98 +0,0 @@ -namespace AdventOfCode.Y2024.Day16; - -using System; -using System.Collections.Generic; -using System.Collections.Immutable; -using System.Linq; -using System.Numerics; -using AngleSharp.Common; -using Map = System.Collections.Generic.Dictionary; -using State = (System.Numerics.Complex pos, System.Numerics.Complex dir); - -[ProblemName("Reindeer Maze")] -class Solution : Solver { - - static readonly Complex North = -Complex.ImaginaryOne; - static readonly Complex South = Complex.ImaginaryOne; - static readonly Complex West = -1; - static readonly Complex East = 1; - - public object PartOne(string input) => FindBestScore(GetMap(input)); - public object PartTwo(string input) => FindBestSpots(GetMap(input)); - - int FindBestScore(Map map) => Dijkstra(map, Goal(map))[Start(map)]; - - int FindBestSpots(Map map) { - var dist = Dijkstra(map, Goal(map)); - var start = Start(map); - - // track the shortest paths using the distance map as guideline. - var q = new PriorityQueue(); - q.Enqueue(start, dist[start]); - - var bestSpots = new HashSet { start }; - while (q.TryDequeue(out var state, out var remainingScore)) { - foreach (var (next, score) in Steps(map, state, forward: true)) { - var nextRemainingScore = remainingScore - score; - if (!bestSpots.Contains(next) && dist[next] == nextRemainingScore) { - bestSpots.Add(next); - q.Enqueue(next, nextRemainingScore); - } - } - } - return bestSpots.DistinctBy(state => state.pos).Count(); - } - - Dictionary Dijkstra(Map map, Complex goal) { - // Dijkstra algorithm; works backwards from the goal, returns the - // distances to _all_ tiles and directions. - var dist = new Dictionary(); - - var q = new PriorityQueue(); - foreach (var dir in new[]{North, East, West, South}) { - q.Enqueue((goal, dir), 0); - dist[(goal, dir)] = 0; - } - - while (q.TryDequeue(out var cur, out var totalDistance)) { - foreach (var (next, score) in Steps(map, cur, forward: false)) { - var nextCost = totalDistance + score; - if (nextCost < dist.GetOrDefault(next, int.MaxValue)) { - q.Remove(next, out _, out _, null); - dist[next] = nextCost; - q.Enqueue(next, nextCost); - } - } - } - return dist; - } - - // returns the possible next or previous states and the associated costs for a given state. - // in forward mode we scan the possible states from the start state towards the goal. - // in backward mode we are working backwards from the goal to the start. - IEnumerable<(State, int cost)> Steps(Map map, State state, bool forward) { - foreach (var dir in new[]{North, East, West, South}) { - if (dir == state.dir) { - var pos = forward ? state.pos + dir : state.pos - dir; - if (map.GetValueOrDefault(pos) != '#') { - yield return ((pos, dir), 1); - } - } else if (dir != -state.dir) { - yield return ((state.pos, dir), 1000); - } - } - } - - // store the points in a dictionary so that we can iterate over them and - // to easily deal with points outside the area using GetValueOrDefault - Map GetMap(string input) { - var map = input.Split("\n"); - return ( - from y in Enumerable.Range(0, map.Length) - from x in Enumerable.Range(0, map[0].Length) - select new KeyValuePair(x + y * South, map[y][x]) - ).ToDictionary(); - } - Complex Goal(Map map) => map.Keys.Single(k => map[k] == 'E'); - State Start(Map map) => (map.Keys.Single(k => map[k] == 'S'), East); -} \ No newline at end of file diff --git a/2024/Day16/illustration.jpeg b/2024/Day16/illustration.jpeg deleted file mode 100644 index 2e27f1e4b..000000000 Binary files a/2024/Day16/illustration.jpeg and /dev/null differ diff --git a/2024/Day16/input.in b/2024/Day16/input.in deleted file mode 100644 index 44464bc38..000000000 Binary files a/2024/Day16/input.in and /dev/null differ diff --git a/2024/Day16/input.refout b/2024/Day16/input.refout deleted file mode 100644 index 6d050d07f..000000000 --- a/2024/Day16/input.refout +++ /dev/null @@ -1,2 +0,0 @@ -130536 -1024 \ No newline at end of file diff --git a/2024/Day17/README.md b/2024/Day17/README.md deleted file mode 100644 index dcddf5cf2..000000000 --- a/2024/Day17/README.md +++ /dev/null @@ -1,27 +0,0 @@ -## --- Day 17: Chronospatial Computer --- -The Historians push the button on their strange device, but this time, you all just feel like you're _falling_. - -"Situation critical", the device announces in a familiar voice. "Bootstrapping process failed. Initializing debugger...." - -_Visit the website for the full story and [full puzzle](https://adventofcode.com/2024/day/17) description._ - -I'm not a big fan of _disassembly_ tasks, but they come up almost every year. The first part of the problem, which -I _actually_ liked, was to write an interpreter for an elvish computer (i.e. one with a weird instruction set). This -is really easy to do with a simple for loop and switching on the different opcodes. - -The second half was a bit harder, as I had to understand what's going on in the program. We had to generate inputs that -would force the program to print out its own source. Well, a _quine_ is a computer program that takes no input and -produces a copy of its own source code as its only output. Although our program was not a real quine, I couldn't help -but smile when I read the problem description in the morning. - -Fortunately, the algorithm was not that complicated once I realized that the _next output number_ depends only on the -_lowest few bits_ of the input. Then the input gets shifted by a small amount, and this continues until the end. - -There is _some interconnection_ between the consecutive numbers, so one cannot just calculate the result independently -for each. But I was able to come up with a _recursive solution_ that generates the input _backwards_. Once we know the -higher bits, we can try all combinations for the next 3 bits, and so on down to the first bit. - -As an added bonus I implemented (part of) the emulator in [VIC-20 BASIC](https://hu.wikipedia.org/wiki/Commodore_VIC-20). -This is how it runs the second sample that prints out its own source code. - -![vic20.gif](vic20.gif) \ No newline at end of file diff --git a/2024/Day17/Solution.cs b/2024/Day17/Solution.cs deleted file mode 100644 index b5e44d86e..000000000 --- a/2024/Day17/Solution.cs +++ /dev/null @@ -1,70 +0,0 @@ -namespace AdventOfCode.Y2024.Day17; - -using System.Collections.Generic; -using System.Linq; -using System.Text.RegularExpressions; - -[ProblemName("Chronospatial Computer")] -class Solution : Solver { - - enum Opcode { - Adv, Bxl, Bst, Jnz, Bxc, Out, Bdv, Cdv - } - - public object PartOne(string input) { - var (state, program) = Parse(input); - return string.Join(",", Run(state, program)); - } - public object PartTwo(string input) { - var (_, program) = Parse(input); - return GenerateA(program, program).Min(); - } - - List Run(List state, List program) { - var combo = (int op) => op < 4 ? op : state[op - 4]; - var res = new List(); - for (var ip = 0; ip < program.Count; ip += 2) { - switch ((Opcode)program[ip], (int)program[ip + 1]) { - case (Opcode.Adv, var op): state[0] = state[0] >> (int)combo(op); break; - case (Opcode.Bdv, var op): state[1] = state[0] >> (int)combo(op); break; - case (Opcode.Cdv, var op): state[2] = state[0] >> (int)combo(op); break; - case (Opcode.Bxl, var op): state[1] = state[1] ^ op; break; - case (Opcode.Bst, var op): state[1] = combo(op) % 8; break; - case (Opcode.Jnz, var op): ip = state[0] == 0 ? ip : op - 2; break; - case (Opcode.Bxc, var op): state[1] = state[1] ^ state[2]; break; - case (Opcode.Out, var op): res.Add(combo(op) % 8); break; - } - } - return res; - } - - /* - Determines register A for the given output. The search works recursively and in - reverse order, starting from the last number to be printed and ending with the first. - */ - IEnumerable GenerateA(List program, List output) { - if (!output.Any()) { - yield return 0; - yield break; - } - - foreach (var ah in GenerateA(program, output[1..])) { - for (var al = 0; al < 8; al++) { - var a = ah * 8 + al; - if (Run([a, 0, 0], program).SequenceEqual(output)) { - yield return a; - } - } - } - } - - (List state, List program) Parse(string input) { - var blocks = input.Split("\n\n").Select(ParseNums).ToArray(); - return (blocks[0], blocks[1]); - } - - List ParseNums(string st) => - Regex.Matches(st, @"\d+", RegexOptions.Multiline) - .Select(m => long.Parse(m.Value)) - .ToList(); -} \ No newline at end of file diff --git a/2024/Day17/illustration.jpeg b/2024/Day17/illustration.jpeg deleted file mode 100644 index 001875746..000000000 Binary files a/2024/Day17/illustration.jpeg and /dev/null differ diff --git a/2024/Day17/input.in b/2024/Day17/input.in deleted file mode 100644 index 593be0de4..000000000 Binary files a/2024/Day17/input.in and /dev/null differ diff --git a/2024/Day17/input.refout b/2024/Day17/input.refout deleted file mode 100644 index fa0a5d5c9..000000000 --- a/2024/Day17/input.refout +++ /dev/null @@ -1,2 +0,0 @@ -1,5,0,5,2,0,1,3,5 -236581108670061 \ No newline at end of file diff --git a/2024/Day17/vic20.gif b/2024/Day17/vic20.gif deleted file mode 100644 index ab0829883..000000000 Binary files a/2024/Day17/vic20.gif and /dev/null differ diff --git a/2024/Day18/README.md b/2024/Day18/README.md deleted file mode 100644 index 3f8903f0a..000000000 --- a/2024/Day18/README.md +++ /dev/null @@ -1,8 +0,0 @@ -## --- Day 18: RAM Run --- -You and The Historians look a lot more pixelated than you remember. You're _inside a computer_ at the North Pole! - -Just as you're about to check out your surroundings, a program runs up to you. "This region of memory isn't safe! The User misunderstood what a [pushdown automaton](https://en.wikipedia.org/wiki/Pushdown_automaton) is and their algorithm is pushing whole bytes down on top of us! Run!" - -_Visit the website for the full story and [full puzzle](https://adventofcode.com/2024/day/18) description._ - -We got a simple path finding problem for today. I implemented a _binary search_ for the second part. \ No newline at end of file diff --git a/2024/Day18/Solution.cs b/2024/Day18/Solution.cs deleted file mode 100644 index bc9747461..000000000 --- a/2024/Day18/Solution.cs +++ /dev/null @@ -1,64 +0,0 @@ -namespace AdventOfCode.Y2024.Day18; - -using System.Collections.Generic; -using System.Linq; -using System.Text.RegularExpressions; -using System.Numerics; -using AngleSharp.Common; - -[ProblemName("RAM Run")] -class Solution : Solver { - - public object PartOne(string input) => Distance(GetBlocks(input).Take(1024)); - - public object PartTwo(string input) { - // find the first block position that will cut off the goal position - // we can use a binary search for this - - var blocks = GetBlocks(input); - var (lo, hi) = (0, blocks.Length); - while (hi - lo > 1) { - var m = (lo + hi) / 2; - if (Distance(blocks.Take(m)) == null) { - hi = m; - } else { - lo = m; - } - } - return $"{blocks[lo].Real},{blocks[lo].Imaginary}"; - } - - int? Distance(IEnumerable blocks) { - // our standard priority queue based path finding - - var size = 70; - var (start, goal) = (0, size + size * Complex.ImaginaryOne); - var blocked = blocks.Concat(start).ToHashSet(); - - var q = new PriorityQueue(); - q.Enqueue(start, 0); - while (q.TryDequeue(out var pos, out var dist)) { - if (pos == goal) { - return dist; - } - - foreach (var dir in new[] { 1, -1, Complex.ImaginaryOne, -Complex.ImaginaryOne }) { - var posT = pos + dir; - if (!blocked.Contains(posT) && - 0 <= posT.Imaginary && posT.Imaginary <= size && - 0 <= posT.Real && posT.Real <= size - ) { - q.Enqueue(posT, dist + 1); - blocked.Add(posT); - } - } - } - return null; - } - - Complex[] GetBlocks(string input) => ( - from line in input.Split("\n") - let nums = Regex.Matches(line, @"\d+").Select(m => int.Parse(m.Value)).ToArray() - select nums[0] + nums[1] * Complex.ImaginaryOne - ).ToArray(); -} \ No newline at end of file diff --git a/2024/Day18/illustration.jpeg b/2024/Day18/illustration.jpeg deleted file mode 100644 index 12a134ec2..000000000 Binary files a/2024/Day18/illustration.jpeg and /dev/null differ diff --git a/2024/Day18/input.in b/2024/Day18/input.in deleted file mode 100644 index bc02b11cd..000000000 Binary files a/2024/Day18/input.in and /dev/null differ diff --git a/2024/Day18/input.refout b/2024/Day18/input.refout deleted file mode 100644 index db6793b1f..000000000 --- a/2024/Day18/input.refout +++ /dev/null @@ -1,2 +0,0 @@ -338 -20,44 \ No newline at end of file diff --git a/2024/Day19/README.md b/2024/Day19/README.md deleted file mode 100644 index 91ef262a7..000000000 --- a/2024/Day19/README.md +++ /dev/null @@ -1,15 +0,0 @@ -## --- Day 19: Linen Layout --- -Today, The Historians take you up to the _hot springs_ on Gear Island! Very [suspiciously](https://www.youtube.com/watch?v=ekL881PJMjI), absolutely nothing goes wrong as they begin their careful search of the vast field of helixes. - -Could this finally be your chance to visit the [onsen](https://en.wikipedia.org/wiki/Onsen) next door? Only one way to find out. - -_Visit the website for the full story and [full puzzle](https://adventofcode.com/2024/day/19) description._ - -I initially thought that I would be able to entirely solve today's problem using regular expressions. This worked for Part 1, but unfortunately, the regex library can only determine whether a pattern matches a string — it cannot return the number of ways the match can occur. Not that it’s its job anyway... - -I had to implement the search function myself. It’s a simple recursive function that iterates through all towels and tries to match them to the beginning of the pattern. If a match is found, it continues recursively with the remaining pattern until the entire pattern becomes an empty string, which signifies a complete match. - -Of course, this approach would never terminate as-is, it needs to be converted into a cached function. Thankfully, this is straightforward to do using a _ConcurrentDictionary_, which I discovered earlier this year. By utilizing the _GetOrAdd_ method of -the _ConcurrentDictionary_ class, one can simply wrap the uncached logic inside a lambda and call it a day. - -It’s very similar to Python’s cached function decorators, albeit with the caveat of having to pass an additional 'cache' argument at the end of the parameter list. But since we’re in the world of C#, we have to work with what it offers. diff --git a/2024/Day19/Solution.cs b/2024/Day19/Solution.cs deleted file mode 100644 index 952efada5..000000000 --- a/2024/Day19/Solution.cs +++ /dev/null @@ -1,37 +0,0 @@ -namespace AdventOfCode.Y2024.Day19; - -using System; -using System.Collections.Generic; -using System.Linq; - -using Cache = System.Collections.Concurrent.ConcurrentDictionary; - -[ProblemName("Linen Layout")] -class Solution : Solver { - - public object PartOne(string input) => MatchCounts(input).Count(c => c != 0); - - public object PartTwo(string input) => MatchCounts(input).Sum(); - - IEnumerable MatchCounts(string input) { - var blocks = input.Split("\n\n"); - var towels = blocks[0].Split(", "); - return - from pattern in blocks[1].Split("\n") - select MatchCount(towels, pattern, new Cache()); - } - - // computes the number of ways the pattern can be build up from the towels. - // works recursively by matching the prefix of the pattern with each towel. - // a full match is found when the pattern becomes empty. the cache is applied - // to _drammatically_ speed up execution - long MatchCount(string[] towels, string pattern, Cache cache) => - cache.GetOrAdd(pattern, (pattern) => - pattern switch { - "" => 1, - _ => towels - .Where(pattern.StartsWith) - .Sum(towel => MatchCount(towels, pattern[towel.Length ..], cache)) - } - ); -} \ No newline at end of file diff --git a/2024/Day19/illustration.jpeg b/2024/Day19/illustration.jpeg deleted file mode 100644 index 6a4aa3f54..000000000 Binary files a/2024/Day19/illustration.jpeg and /dev/null differ diff --git a/2024/Day19/input.in b/2024/Day19/input.in deleted file mode 100644 index c718fe1b3..000000000 Binary files a/2024/Day19/input.in and /dev/null differ diff --git a/2024/Day19/input.refout b/2024/Day19/input.refout deleted file mode 100644 index 92770631d..000000000 --- a/2024/Day19/input.refout +++ /dev/null @@ -1,2 +0,0 @@ -333 -678536865274732 \ No newline at end of file diff --git a/2024/Day20/README.md b/2024/Day20/README.md deleted file mode 100644 index 76d9ad9bb..000000000 --- a/2024/Day20/README.md +++ /dev/null @@ -1,22 +0,0 @@ -## --- Day 20: Race Condition --- -The Historians are quite pixelated again. This time, a massive, black building looms over you - you're _right outside_ the CPU! - -While The Historians get to work, a nearby program sees that you're idle and challenges you to a race. Apparently, you've arrived just in time for the frequently-held race condition festival! - -_Visit the website for the full story and [full puzzle](https://adventofcode.com/2024/day/20) description._ - -The problem included a small but crucial hint: _there is only a single path from the start to the end_. Moreover, there are no dead ends in the input; it's just a single, continuous trace. - -The definition of _cheating_ was super hard to understand. I have to admit that instead, I used my intuition and used a more simple definition: in cheat mode you can step to any cell within the distance of 2 (or 20 for the second part). This really worked. - -I created a function that returns the points of the track in finish to start order. This way, the _index_ of an item in the array corresponds to its distance to the finish line. - -Then, I go over the path. For each position, the number of possible cheats is calculated by checking what happens if we are trying to make a shortcut to any other positions around. - -There are a number of cases to consider: -- the target position is too far away. This happens when its Manhattan distance is greater than the allowed _cheat_ limit -- the target is within range, but actually further away from the finish than we are (the saving is negative). -- the target is within range, closer to the finish, but the saving is still less than 100 -- the target is within range, and the saving is at least 100 - -We need to determine the number of good cheats for each position _add_ them up. I used Parallel LINQ here, as the regular sequential one took significantly more time. diff --git a/2024/Day20/Solution.cs b/2024/Day20/Solution.cs deleted file mode 100644 index d56acd386..000000000 --- a/2024/Day20/Solution.cs +++ /dev/null @@ -1,59 +0,0 @@ -namespace AdventOfCode.Y2024.Day20; - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Numerics; - -[ProblemName("Race Condition")] -class Solution : Solver { - - public object PartOne(string input) => Solve(input, 2); - public object PartTwo(string input) => Solve(input, 20); - - int Solve(string input, int cheat) { - var path = GetPath(input); - var indices = Enumerable.Range(0, path.Length).ToArray(); - - // sum up the worthy cheats for each index along the path - var cheatsFromI = (int i) => ( - from j in indices[0..i] - let dist = Manhattan(path[i], path[j]) - let saving = i - (j + dist) - where dist <= cheat && saving >= 100 - select 1 - ).Sum(); - - // parallel is gold today, it gives us an 3-4x boost - return indices.AsParallel().Select(cheatsFromI).Sum(); - } - - int Manhattan(Complex a, Complex b) => - (int)(Math.Abs(a.Imaginary - b.Imaginary) + Math.Abs(a.Real - b.Real)); - - // Follow the path from finish to start, supposed that there is a single track in the input. - // The index of a position in the returned array equals to its distance from the finish - Complex[] GetPath(string input) { - var lines = input.Split("\n"); - var map = ( - from y in Enumerable.Range(0, lines.Length) - from x in Enumerable.Range(0, lines[0].Length) - select new KeyValuePair(x + y * Complex.ImaginaryOne, lines[y][x]) - ).ToDictionary(); - - Complex[] dirs = [-1, 1, Complex.ImaginaryOne, -Complex.ImaginaryOne]; - - var start = map.Keys.Single(k => map[k] == 'S'); - var goal = map.Keys.Single(k => map[k] == 'E'); - - var (prev, cur) = ((Complex?)null, goal); - var res = new List { cur }; - - while (cur != start) { - var dir = dirs.Single(dir => map[cur + dir] != '#' && cur + dir != prev); - (prev, cur) = (cur, cur + dir); - res.Add(cur); - } - return res.ToArray(); - } -} \ No newline at end of file diff --git a/2024/Day20/illustration.jpeg b/2024/Day20/illustration.jpeg deleted file mode 100644 index dc1389f34..000000000 Binary files a/2024/Day20/illustration.jpeg and /dev/null differ diff --git a/2024/Day20/input.in b/2024/Day20/input.in deleted file mode 100644 index 3a67ed17b..000000000 Binary files a/2024/Day20/input.in and /dev/null differ diff --git a/2024/Day20/input.refout b/2024/Day20/input.refout deleted file mode 100644 index a7c19236d..000000000 --- a/2024/Day20/input.refout +++ /dev/null @@ -1,2 +0,0 @@ -1384 -1008542 \ No newline at end of file diff --git a/2024/Day21/README.md b/2024/Day21/README.md deleted file mode 100644 index a10d58bb1..000000000 --- a/2024/Day21/README.md +++ /dev/null @@ -1,23 +0,0 @@ -## --- Day 21: Keypad Conundrum --- -As you teleport onto Santa's _Reindeer-class starship_, The Historians begin to panic: someone from their search party is missing. A quick life-form scan by the ship's computer reveals that when the missing Historian teleported, he arrived in another part of the ship. - -The door to that area is locked, but the computer can't open it; it can only be opened by physically typing the door codes (your puzzle input) on the numeric keypad on the door. - -_Visit the website for the full story and [full puzzle](https://adventofcode.com/2024/day/21) description._ - -This is the problem that sets casual players apart competitors. I had a hard time solving it. I think I was on track, but -I just couldn't visualize the whole idea of robots controlling robots controlling robots. I love recursion, but just -cannot mentally follow multiple layers of indirection. Anyway. I could solve it in the evening hours, so I'm still on track with _Advent of Code 2024_. - -It was clear from the exponential growth demonstrated by _part 1_ that I wont be able to generate the final string to -be entered. Luckily the problem asked only for the length of it. (Which makes it really artifical: how would the elves enter -such a long key?) - -I created a function called `EncodeKeys` which takes a sequence of keys to be pressed and an array of keypads, and returns the length of the shortest sequence needed to enter the given keys. An empty keypad array means that the sequence is simply entered by a human and no further encoding is needed. Otherwise, the sequence is entered by a robot that needs to be programmed using its keypad. In this case the keys are encoded using the first keypad in the array (the robot's keypad), character by character using _EncodeKey_ which will recursively call back to `EncodeKeys` with the rest of the keypads. - -The `_EncodeKey_` helper function is used to move the robot from position _A_ to position _B_ on the keypad and press the button. Usually, _A_ and _B_ are not in the same row and column, so the movement has both a horizontal and a vertical part. We could go both ways: horizontal first then vertical, or the other way around, and we need to check which movement results in fewer key presses. Lastly, we should not forget that the robot's hand should never move over the empty space `' '`. - -Since every key sequence we need to enter ends with a button press `'A'`, we can always be sure that the robot will stay over the `'A'` button at the end. Since it initially starts over the `'A'` key as well, we have an invariant: at the beginning and the end of `EncodeKeys`, the robot is over the `'A'` key. It can move around while entering the keys, but the invariant holds when it finishes. - -This is great because we don't have to keep track of it! The `Cache` used by `EncodeKey` doesn't need to care about the robot's position recursively. All it depends on is the current robot's position, the position of the next key to be entered, and the number of keypads left in the recursion. This reduces the problem space quite a bit and gives us a well-performing algorithm. - diff --git a/2024/Day21/Solution.cs b/2024/Day21/Solution.cs deleted file mode 100644 index 99cf4d96f..000000000 --- a/2024/Day21/Solution.cs +++ /dev/null @@ -1,94 +0,0 @@ -namespace AdventOfCode.Y2024.Day21; - -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.Linq; - -using Cache = System.Collections.Concurrent.ConcurrentDictionary<(char currentKey, char nextKey, int depth), long>; -using Keypad = System.Collections.Generic.Dictionary; -record struct Vec2(int x, int y); - -[ProblemName("Keypad Conundrum")] -class Solution : Solver { - - public object PartOne(string input) => Solve(input, 2); - - public object PartTwo(string input) => Solve(input, 25); - - long Solve(string input, int depth) { - var keypad1 = ParseKeypad("789\n456\n123\n 0A"); - var keypad2 = ParseKeypad(" ^A\n"); - var keypads = Enumerable.Repeat(keypad2, depth).Prepend(keypad1).ToArray(); - - var cache = new Cache(); - var res = 0L; - - foreach (var line in input.Split("\n")) { - var num = int.Parse(line[..^1]); - res += num * EncodeKeys(line, keypads, cache); - } - return res; - } - - // Determines the length of the shortest sequence that is needed to enter the given - // keys. An empty keypad array means that the sequence is simply entered by a human - // and no further encoding is needed. Otherwise the sequence is entered by a robot - // which needs to be programmed. In practice this means that the keys are encoded - // using the robots keypad (the first keypad), generating an other sequence of keys. - // This other sequence is then recursively encoded using the rest of the keypads. - long EncodeKeys(string keys, Keypad[] keypads, Cache cache) { - if (keypads.Length == 0) { - return keys.Length; - } else { - // invariant: the robot starts and finishes by pointing at the 'A' key - var currentKey = 'A'; - var length = 0L; - - foreach (var nextKey in keys) { - length += EncodeKey(currentKey, nextKey, keypads, cache); - // while the sequence is entered the current key changes accordingly - currentKey = nextKey; - } - - // at the end the current key should be reset to 'A' - Debug.Assert(currentKey == 'A', "The robot should point at the 'A' key"); - return length; - } - } - long EncodeKey(char currentKey, char nextKey, Keypad[] keypads, Cache cache) => - cache.GetOrAdd((currentKey, nextKey, keypads.Length), _ => { - var keypad = keypads[0]; - - var currentPos = keypad.Single(kvp => kvp.Value == currentKey).Key; - var nextPos = keypad.Single(kvp => kvp.Value == nextKey).Key; - - var dy = nextPos.y - currentPos.y; - var vert = new string(dy < 0 ? 'v' : '^', Math.Abs(dy)); - - var dx = nextPos.x - currentPos.x; - var horiz = new string(dx < 0 ? '<' : '>', Math.Abs(dx)); - - var cost = long.MaxValue; - // we can usually go vertical first then horizontal or vica versa, - // but we should check for the extra condition and don't position - // the robot over the ' ' key: - if (keypad[new Vec2(currentPos.x, nextPos.y)] != ' ') { - cost = Math.Min(cost, EncodeKeys($"{vert}{horiz}A", keypads[1..], cache)); - } - - if (keypad[new Vec2(nextPos.x, currentPos.y)] != ' ') { - cost = Math.Min(cost, EncodeKeys($"{horiz}{vert}A", keypads[1..], cache)); - } - return cost; - }); - - Keypad ParseKeypad(string keypad) { - var lines = keypad.Split("\n"); - return ( - from y in Enumerable.Range(0, lines.Length) - from x in Enumerable.Range(0, lines[0].Length) - select new KeyValuePair(new Vec2(x, -y), lines[y][x]) - ).ToDictionary(); - } -} \ No newline at end of file diff --git a/2024/Day21/illustration.jpeg b/2024/Day21/illustration.jpeg deleted file mode 100644 index 00430c919..000000000 Binary files a/2024/Day21/illustration.jpeg and /dev/null differ diff --git a/2024/Day21/input.in b/2024/Day21/input.in deleted file mode 100644 index a7fdffcf2..000000000 Binary files a/2024/Day21/input.in and /dev/null differ diff --git a/2024/Day21/input.refout b/2024/Day21/input.refout deleted file mode 100644 index 5aa4febc5..000000000 --- a/2024/Day21/input.refout +++ /dev/null @@ -1,2 +0,0 @@ -176650 -217698355426872 \ No newline at end of file diff --git a/2024/Day22/README.md b/2024/Day22/README.md deleted file mode 100644 index 4358da5ea..000000000 --- a/2024/Day22/README.md +++ /dev/null @@ -1,11 +0,0 @@ -## --- Day 22: Monkey Market --- -As you're all teleported deep into the jungle, a _monkey_ steals The Historians' device! You'll need get it back while The Historians are looking for the Chief. - -The monkey that stole the device seems willing to trade it, but only in exchange for an absurd number of bananas. Your only option is to buy bananas on the Monkey Exchange Market. - -_Visit the website for the full story and [full puzzle](https://adventofcode.com/2024/day/22) description._ - -A refreshing challenge after yesterday's hard one. I created a secret number generator function that returns the 2001 numbers for each seller (the initial one and the 2000 additional). This is enough for _Part 1_. - -For _Part 2_ I maintain the dictionary of buying options for each potential sequence the monkey can recognize with the -combined amount of bananas this would generate from all sellers. \ No newline at end of file diff --git a/2024/Day22/Solution.cs b/2024/Day22/Solution.cs deleted file mode 100644 index 6a81e92de..000000000 --- a/2024/Day22/Solution.cs +++ /dev/null @@ -1,60 +0,0 @@ -namespace AdventOfCode.Y2024.Day22; - -using System.Collections.Generic; -using System.Collections.Immutable; -using System.Linq; - -[ProblemName("Monkey Market")] -class Solution : Solver { - - public object PartOne(string input) { - return GetNums(input).Select(x => (long)SecretNumbers(x).Last()).Sum(); - } - - public object PartTwo(string input) { - // create a dictionary of all buying options then select the one with the most banana: - - var buyingOptions = new Dictionary<(int,int,int,int), int>(); - - foreach (var num in GetNums(input)) { - var optionsBySeller = BuyingOptions(num); - foreach (var seq in optionsBySeller.Keys) { - buyingOptions[seq] = buyingOptions.GetValueOrDefault(seq) + optionsBySeller[seq]; - } - } - return buyingOptions.Values.Max(); - } - - Dictionary<(int,int,int,int), int> BuyingOptions(int seed) { - var bananasSold = Bananas(seed).ToArray(); - var buyingOptions = new Dictionary<(int,int,int,int), int>(); - - // a sliding window of 5 elements over the sold bananas defines the sequence the monkey - // will recognize. add the first occurrence of each sequence to the buyingOptions dictionary - // with the corresponding banana count - var diff = Diff(bananasSold); - for (var i = 0; i < bananasSold.Length - 4; i++) { - var seq = (diff[i], diff[i+1], diff[i+2], diff[i+3]); - if (!buyingOptions.ContainsKey(seq)) { - buyingOptions[seq] = bananasSold[i+4]; - } - } - return buyingOptions; - } - int[] Bananas(int seed) => SecretNumbers(seed).Select(n => n % 10).ToArray(); - - int[] Diff(IEnumerable x) => x.Zip(x.Skip(1)).Select(p => p.Second - p.First).ToArray(); - - IEnumerable SecretNumbers(int seed) { - var mixAndPrune = (int a, int b) => (a ^ b) & 0xffffff; - - yield return seed; - for (var i = 0; i < 2000; i++) { - seed = mixAndPrune(seed, seed << 6); - seed = mixAndPrune(seed, seed >> 5); - seed = mixAndPrune(seed, seed << 11); - yield return seed; - } - } - IEnumerable GetNums(string input) => input.Split("\n").Select(int.Parse); -} \ No newline at end of file diff --git a/2024/Day22/illustration.jpeg b/2024/Day22/illustration.jpeg deleted file mode 100644 index d0ba24944..000000000 Binary files a/2024/Day22/illustration.jpeg and /dev/null differ diff --git a/2024/Day22/input.in b/2024/Day22/input.in deleted file mode 100644 index c00da3dae..000000000 Binary files a/2024/Day22/input.in and /dev/null differ diff --git a/2024/Day22/input.refout b/2024/Day22/input.refout deleted file mode 100644 index 895648653..000000000 --- a/2024/Day22/input.refout +++ /dev/null @@ -1,2 +0,0 @@ -18525593556 -2089 \ No newline at end of file diff --git a/2024/Day23/README.md b/2024/Day23/README.md deleted file mode 100644 index 1bc05ba21..000000000 --- a/2024/Day23/README.md +++ /dev/null @@ -1,10 +0,0 @@ -## --- Day 23: LAN Party --- -As The Historians wander around a secure area at Easter Bunny HQ, you come across posters for a [LAN party](https://en.wikipedia.org/wiki/LAN_party) scheduled for today! Maybe you can find it; you connect to a nearby _datalink port_ and download a map of the local network (your puzzle input). - -The network map provides a list of every connection between two computers. For example: - -_Visit the website for the full story and [full puzzle](https://adventofcode.com/2024/day/23) description._ - -We tackled a graph algorithm problem today, where we had to find maximal cliques in an undirected graph. The literature provides [efficient algorithms](https://en.wikipedia.org/wiki/Bron%E2%80%93Kerbosch_algorithm) for this problem, but our graph is not too large, so we can use a straightforward "poor man's" strategy as well. - -I started with the _seed_ components, that is single element components for each node. Then, I proceeded to _grow_ these components by adding a single node to them in all possible ways. I can put this in a loop, to get components with size 2, 3, 4, etc. _Part 1_ asks for the number of components that have 3 nodes and have at least one node starting with 't'. _Part 2_ asks for the biggest component that cannot be grown anymore. \ No newline at end of file diff --git a/2024/Day23/Solution.cs b/2024/Day23/Solution.cs deleted file mode 100644 index e43da8f65..000000000 --- a/2024/Day23/Solution.cs +++ /dev/null @@ -1,56 +0,0 @@ -namespace AdventOfCode.Y2024.Day23; - -using System; -using System.Collections.Generic; -using System.Collections.Immutable; -using System.Linq; -using Graph = System.Collections.Generic.Dictionary>; -using Component = string; - -[ProblemName("LAN Party")] -class Solution : Solver { - public object PartOne(string input) { - var g = GetGraph(input); - var components = g.Keys.ToHashSet(); - components = Grow(g, components); - components = Grow(g, components); - return components.Count(c => Members(c).Any(m => m.StartsWith("t"))); - } - - public object PartTwo(string input) { - var g = GetGraph(input); - var components = g.Keys.ToHashSet(); - while (components.Count > 1) { - components = Grow(g, components); - } - return components.Single(); - } - - HashSet Grow(Graph g, HashSet components) => ( - from c in components.AsParallel() - let members = Members(c) - from neighbour in members.SelectMany(m => g[m]).Distinct() - where !members.Contains(neighbour) - where members.All(m => g[neighbour].Contains(m)) - select Extend(c, neighbour) - ).ToHashSet(); - - IEnumerable Members(Component c) => - c.Split(","); - Component Extend(Component c, string item) => - string.Join(",", Members(c).Append(item).OrderBy(x=>x)); - - Graph GetGraph(string input) { - var edges = - from line in input.Split("\n") - let nodes = line.Split("-") - from edge in new []{(nodes[0], nodes[1]), (nodes[1], nodes[0])} - select (From: edge.Item1, To: edge.Item2); - - return ( - from e in edges - group e by e.From into g - select (g.Key, g.Select(e => e.To).ToHashSet()) - ).ToDictionary(); - } -} \ No newline at end of file diff --git a/2024/Day23/illustration.jpeg b/2024/Day23/illustration.jpeg deleted file mode 100644 index 1a3da9908..000000000 Binary files a/2024/Day23/illustration.jpeg and /dev/null differ diff --git a/2024/Day23/input.in b/2024/Day23/input.in deleted file mode 100644 index 2233d6e98..000000000 Binary files a/2024/Day23/input.in and /dev/null differ diff --git a/2024/Day23/input.refout b/2024/Day23/input.refout deleted file mode 100644 index 18bc5052a..000000000 --- a/2024/Day23/input.refout +++ /dev/null @@ -1,2 +0,0 @@ -1368 -dd,ig,il,im,kb,kr,pe,ti,tv,vr,we,xu,zi \ No newline at end of file diff --git a/2024/Day24/README.md b/2024/Day24/README.md deleted file mode 100644 index 5c708fc50..000000000 --- a/2024/Day24/README.md +++ /dev/null @@ -1,21 +0,0 @@ -## --- Day 24: Crossed Wires --- -You and The Historians arrive at the edge of a _large grove_ somewhere in the jungle. After the last incident, the Elves installed a small device that monitors the fruit. While The Historians search the grove, one of them asks if you can take a look at the monitoring device; apparently, it's been malfunctioning recently. - -The device seems to be trying to produce a number through some boolean logic gates. Each gate has two inputs and one output. The gates all operate on values that are either true (1) or false (0). - -_Visit the website for the full story and [full puzzle](https://adventofcode.com/2024/day/24) description._ - -The first half of the problem was a familiar logic circuit evaluator, we have done this before. I really liked the second part, although I don't have a super generic solution for it. I generated a graph from my input using Graphviz, then realized that the circuit tries to implement a Ripple-carry adder. - -A single full adder consists of two half adders: - -![half adder](halfadder.png) - -Which are chained one after the other like this to get a Ripple-carry adder: - -![full adder](adder.png) - -I took the images from [build-electronic-circuits.com](https://www.build-electronic-circuits.com/full-adder/). - -I implemented this logic in my 'fix' method. I start with the inputs x01 and y01 and try to identify the gates for the individual steps. Where I found an error, I manually checked my input to figure out what went wrong. I had just two different -kind of errors which can be corrected by the fixer. \ No newline at end of file diff --git a/2024/Day24/Solution.cs b/2024/Day24/Solution.cs deleted file mode 100644 index 0eed31740..000000000 --- a/2024/Day24/Solution.cs +++ /dev/null @@ -1,101 +0,0 @@ -namespace AdventOfCode.Y2024.Day24; - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text.RegularExpressions; -using Circuit = System.Collections.Generic.Dictionary; - -record struct Gate(string in1, string kind, string in2); - -[ProblemName("Crossed Wires")] -class Solution : Solver { - - public object PartOne(string input) { - var (inputs, circuit) = Parse(input); - - var outputs = from label in circuit.Keys where label.StartsWith("z") select label; - - var res = 0L; - foreach (var label in outputs.OrderByDescending(label=>label)) { - res = res * 2 + Eval(label, circuit, inputs); - } - return res; - } - - int Eval(string label, Circuit circuit, Dictionary inputs) { - if (inputs.TryGetValue(label, out var res)) { - return res; - } else { - return circuit[label] switch { - Gate(var in1, "AND", var in2) => Eval(in1, circuit, inputs) & Eval(in2, circuit, inputs), - Gate(var in1, "OR", var in2) => Eval(in1, circuit, inputs) | Eval(in2, circuit, inputs), - Gate(var in1, "XOR", var in2) => Eval(in1, circuit, inputs) ^ Eval(in2, circuit, inputs), - _ => throw new Exception(circuit[label].ToString()), - }; - } - } - - public object PartTwo(string input) { - var circuit = Parse(input).circuit; - return string.Join(",", Fix(circuit).OrderBy(label => label)); - } - - // the circuit should define a full adder for two 44 bit numbers - // this fixer is specific to my input. - IEnumerable Fix(Circuit circuit) { - var cin = Output(circuit, "x00", "AND", "y00"); - for (var i = 1; i < 45; i++) { - var x = $"x{i:D2}"; - var y = $"y{i:D2}"; - var z = $"z{i:D2}"; - - var xor1 = Output(circuit, x, "XOR", y); - var and1 = Output(circuit, x, "AND", y); - var xor2 = Output(circuit, cin, "XOR", xor1); - var and2 = Output(circuit, cin, "AND", xor1); - - if (xor2 == null && and2 == null) { - return SwapAndFix(circuit, xor1, and1); - } - - var carry = Output(circuit, and1, "OR", and2); - if (xor2 != z) { - return SwapAndFix(circuit, z, xor2); - } else { - cin = carry; - } - } - return []; - } - - IEnumerable SwapAndFix(Circuit circuit, string out1, string out2) { - (circuit[out1], circuit[out2]) = (circuit[out2], circuit[out1]); - return Fix(circuit).Concat([out1, out2]); - } - - string Output(Circuit circuit, string x, string kind, string y) => - circuit.SingleOrDefault(pair => - (pair.Value.in1 == x && pair.Value.kind == kind && pair.Value.in2 == y) || - (pair.Value.in1 == y && pair.Value.kind == kind && pair.Value.in2 == x) - ).Key; - - (Dictionary inputs, Circuit circuit) Parse(string input) { - var inputs = new Dictionary(); - var circuit = new Circuit(); - - var blocks = input.Split("\n\n"); - - foreach (var line in blocks[0].Split("\n")) { - var parts = line.Split(": "); - inputs.Add(parts[0], int.Parse(parts[1])); - } - - foreach (var line in blocks[1].Split("\n")) { - var parts = Regex.Matches(line, "[a-zA-z0-9]+").Select(m => m.Value).ToArray(); - circuit.Add(parts[3], new Gate(in1: parts[0], kind: parts[1], in2: parts[2])); - } - return (inputs, circuit); - } - -} \ No newline at end of file diff --git a/2024/Day24/adder.png b/2024/Day24/adder.png deleted file mode 100644 index 9b21c1063..000000000 Binary files a/2024/Day24/adder.png and /dev/null differ diff --git a/2024/Day24/halfadder.png b/2024/Day24/halfadder.png deleted file mode 100644 index 76cdb3d92..000000000 Binary files a/2024/Day24/halfadder.png and /dev/null differ diff --git a/2024/Day24/illustration.jpeg b/2024/Day24/illustration.jpeg deleted file mode 100644 index 322a5b212..000000000 Binary files a/2024/Day24/illustration.jpeg and /dev/null differ diff --git a/2024/Day24/input.in b/2024/Day24/input.in deleted file mode 100644 index 2df3714a9..000000000 Binary files a/2024/Day24/input.in and /dev/null differ diff --git a/2024/Day24/input.refout b/2024/Day24/input.refout deleted file mode 100644 index bf2c0f14a..000000000 --- a/2024/Day24/input.refout +++ /dev/null @@ -1,2 +0,0 @@ -61495910098126 -css,cwt,gdd,jmv,pqt,z05,z09,z37 \ No newline at end of file diff --git a/2024/Day25/README.md b/2024/Day25/README.md deleted file mode 100644 index a4042b8c3..000000000 --- a/2024/Day25/README.md +++ /dev/null @@ -1,6 +0,0 @@ -## --- Day 25: Code Chronicle --- -Out of ideas and time, The Historians agree that they should go back to check the Chief Historian's office one last time, just in case he went back there without you noticing. - -When you get there, you are surprised to discover that the door to his office is locked! You can hear someone inside, but knocking yields no response. The locks on this floor are all fancy, expensive, virtual versions of [five-pin tumbler locks](https://en.wikipedia.org/wiki/Pin_tumbler_lock), so you contact North Pole security to see if they can help open the door. - -_Visit the website for the full story and [full puzzle](https://adventofcode.com/2024/day/25) description._ diff --git a/2024/Day25/Solution.cs b/2024/Day25/Solution.cs deleted file mode 100644 index 16046d22f..000000000 --- a/2024/Day25/Solution.cs +++ /dev/null @@ -1,24 +0,0 @@ -namespace AdventOfCode.Y2024.Day25; - -using System; -using System.Linq; - -[ProblemName("Code Chronicle")] -class Solution : Solver { - - public object PartOne(string input) { - int[] parsePattern(string[] lines) => - Enumerable.Range(0, lines[0].Length).Select(x => - Enumerable.Range(0, lines.Length).Count(y => lines[y][x] == '#') - ).ToArray(); - - bool match(int[] k, int[] l) => - Enumerable.Range(0, k.Length).All(i => k[i] + l[i] <= 7); - - var patterns = input.Split("\n\n").Select(b => b.Split("\n")); - var keys = patterns.Where(p => p[0][0] == '.').Select(parsePattern).ToList(); - var locks = patterns.Where(p => p[0][0] == '#').Select(parsePattern).ToList(); - - return keys.Sum(k => locks.Count(l => match(l, k))); - } -} \ No newline at end of file diff --git a/2024/Day25/illustration.jpeg b/2024/Day25/illustration.jpeg deleted file mode 100644 index a7665d28e..000000000 Binary files a/2024/Day25/illustration.jpeg and /dev/null differ diff --git a/2024/Day25/input.in b/2024/Day25/input.in deleted file mode 100644 index 9c008e4e5..000000000 Binary files a/2024/Day25/input.in and /dev/null differ diff --git a/2024/Day25/input.refout b/2024/Day25/input.refout deleted file mode 100644 index ddc2c2009..000000000 --- a/2024/Day25/input.refout +++ /dev/null @@ -1 +0,0 @@ -3242 \ No newline at end of file diff --git a/2024/README.md b/2024/README.md deleted file mode 100644 index e4d82c85c..000000000 --- a/2024/README.md +++ /dev/null @@ -1,4 +0,0 @@ -# Advent of Code (2024) -Check out https://adventofcode.com/2024. - - diff --git a/2024/SplashScreen.cs b/2024/SplashScreen.cs deleted file mode 100644 index e29c3095b..000000000 --- a/2024/SplashScreen.cs +++ /dev/null @@ -1,370 +0,0 @@ -using System; - -namespace AdventOfCode.Y2024; - -class SplashScreenImpl : SplashScreen { - - public void Show() { - - var color = Console.ForegroundColor; - Write(0xcc00, false, " ▄█▄ ▄▄█ ▄ ▄ ▄▄▄ ▄▄ ▄█▄ ▄▄▄ ▄█ ▄▄ ▄▄▄ ▄▄█ ▄▄▄\n █▄█ █ █ █ █ █▄█ █ █ █ █ █ █▄ "); - Write(0xcc00, false, " █ █ █ █ █ █▄█\n █ █ █▄█ ▀▄▀ █▄▄ █ █ █▄ █▄█ █ █▄ █▄█ █▄█ █▄▄ /* 2024 */\n \n "); - Write(0xcc00, false, " "); - Write(0x888888, false, " .-----. .------------------. \n "); - Write(0xcccccc, false, ".--'"); - Write(0xe3b585, false, "~ ~ ~"); - Write(0xcccccc, false, "| .-' "); - Write(0xffff66, true, "* "); - Write(0x886655, false, "\\ / "); - Write(0xcccccc, false, "'-. 1 "); - Write(0xffff66, false, "**\n "); - Write(0xcccccc, false, ".--'"); - Write(0xe3b585, false, "~ "); - Write(0xcc00, false, ","); - Write(0xffff66, true, "* "); - Write(0xe3b585, false, "~ "); - Write(0xcccccc, false, "| | "); - Write(0x9900, false, ">"); - Write(0xff9900, true, "o"); - Write(0x9900, false, "< "); - Write(0x886655, false, "\\_\\_\\|_/__/ "); - Write(0xcccccc, false, "| 2 "); - Write(0xffff66, false, "**\n "); - Write(0xcccccc, false, ".---'"); - Write(0xe3b585, false, ": ~ "); - Write(0xcc00, false, "'"); - Write(0x5555bb, false, "(~)"); - Write(0xcc00, false, ", "); - Write(0xe3b585, false, "~"); - Write(0xcccccc, false, "| | "); - Write(0x9900, false, ">"); - Write(0xff0000, true, "@"); - Write(0x9900, false, ">"); - Write(0x66ff, true, "O"); - Write(0x9900, false, "< "); - Write(0xff0000, true, "o"); - Write(0x886655, false, "-_/"); - Write(0xcccccc, false, ".()"); - Write(0x886655, false, "__------"); - Write(0xcccccc, false, "| 3 "); - Write(0xffff66, false, "**\n "); - Write(0xcccccc, false, "|"); - Write(0x4d8b03, false, "@"); - Write(0x5eabb4, false, ".."); - Write(0x4d8b03, false, "@"); - Write(0xe3b585, false, "'. ~ "); - Write(0xcc00, false, "\" ' "); - Write(0xe3b585, false, "~ "); - Write(0xcccccc, false, "| |"); - Write(0x9900, false, ">"); - Write(0x66ff, true, "O"); - Write(0x9900, false, ">"); - Write(0xff9900, true, "o"); - Write(0x9900, false, "<"); - Write(0xff0000, true, "@"); - Write(0x9900, false, "< "); - Write(0x886655, false, "\\____ "); - Write(0xcc00, false, ".'"); - Write(0xcccccc, false, "| 4 "); - Write(0xffff66, false, "**\n "); - Write(0xcccccc, false, "|"); - Write(0x488813, false, "_"); - Write(0x5eabb4, false, ".~."); - Write(0x488813, false, "_"); - Write(0x7fbd39, false, "@"); - Write(0xe3b585, false, "'.. ~ ~ "); - Write(0xffff66, true, "*"); - Write(0xcccccc, false, "| | "); - Write(0xaaaaaa, false, "_| |_ "); - Write(0xcccccc, false, "..\\_"); - Write(0x886655, false, "\\_ "); - Write(0xcc00, false, "..'"); - Write(0xffff66, true, "* "); - Write(0xcccccc, false, "| 5 "); - Write(0xffff66, false, "**\n "); - Write(0xcccccc, false, "| "); - Write(0xffffff, false, "||| "); - Write(0x427322, false, "@ "); - Write(0xe3b585, false, "'''..."); - Write(0xcccccc, false, "| |"); - Write(0xa25151, false, "... "); - Write(0xcccccc, false, ".' '."); - Write(0xcc00, false, "'''.."); - Write(0xd4dde4, false, "/"); - Write(0xcc00, false, ".."); - Write(0xcccccc, false, "| 6 "); - Write(0xffff66, false, "**\n "); - Write(0xcccccc, false, "|"); - Write(0x1461f, false, "@"); - Write(0xffffff, false, "~~~"); - Write(0x488813, false, "@"); - Write(0x4d8b03, false, "@##"); - Write(0x7fbd39, false, "@"); - Write(0x4d8b03, false, "# "); - Write(0x427322, false, "@# "); - Write(0xcccccc, false, "| |"); - Write(0xa5a8af, false, "/\\ "); - Write(0xa25151, false, "''. "); - Write(0xcccccc, false, "| | "); - Write(0xccccff, false, "-"); - Write(0xd4dde4, false, "/ "); - Write(0xffffff, false, ":"); - Write(0xcccccc, false, "| 7 "); - Write(0xffff66, false, "**\n "); - Write(0xcccccc, false, "|"); - Write(0x5eabb4, false, "~~."); - Write(0xcccccc, false, ".--."); - Write(0x666666, false, " _____ "); - Write(0xcccccc, false, "| |"); - Write(0xffff66, true, "* "); - Write(0xa5a8af, false, "/"); - Write(0xdf2308, true, "~"); - Write(0xa5a8af, false, "\\ "); - Write(0xa25151, false, "'."); - Write(0xcccccc, false, "| | "); - Write(0xccccff, false, "- "); - Write(0xd4dde4, false, "/ "); - Write(0xffffff, false, ".'"); - Write(0xcccccc, false, "| 8 "); - Write(0xffff66, false, "**\n "); - Write(0xcccccc, false, "'---' |"); - Write(0x666666, false, "|[][]_\\-"); - Write(0xcccccc, false, "| |"); - Write(0xdf2308, true, "~"); - Write(0xa5a8af, false, "/ "); - Write(0xffff66, true, "* "); - Write(0xa5a8af, false, "\\ "); - Write(0xa25151, false, ":"); - Write(0xcccccc, false, "| | "); - Write(0xffff66, true, "*"); - Write(0xffffff, false, "..' "); - Write(0xcccccc, false, "| 9 "); - Write(0xffff66, false, "**\n "); - Write(0xcccccc, false, "|"); - Write(0x666666, false, "------- "); - Write(0xcccccc, false, "| | "); - Write(0xa5a8af, false, "/\\ "); - Write(0xa25151, false, ".'"); - Write(0xcccccc, false, "| |"); - Write(0xffffff, false, "'''"); - Write(0xc8ff, false, "~~~~~"); - Write(0xcccccc, false, "| 10 "); - Write(0xffff66, false, "**\n "); - Write(0xcccccc, false, "|"); - Write(0xccccff, false, "......."); - Write(0xff0000, false, "|"); - Write(0xcccccc, false, "| |"); - Write(0xa5a8af, false, "/\\ "); - Write(0xa25151, false, "..' "); - Write(0xcccccc, false, "| | "); - Write(0xb5ed, false, ". "); - Write(0xffffff, false, ". "); - Write(0xb5ed, false, "."); - Write(0xcccccc, false, "| 11 "); - Write(0xffff66, false, "**\n "); - Write(0xcccccc, false, "| "); - Write(0xffffff, false, "- - "); - Write(0xcccccc, false, "| |"); - Write(0xa25151, false, "'''"); - Write(0x333333, false, "::"); - Write(0xffff66, true, ":"); - Write(0x333333, false, "::"); - Write(0xcccccc, false, "| | "); - Write(0xffffff, false, ". "); - Write(0xa2db, false, ". ."); - Write(0xff0000, true, "."); - Write(0xcccccc, false, "| 12 "); - Write(0xffff66, false, "**\n "); - Write(0xcccccc, false, "|"); - Write(0xffffff, false, "'. - -"); - Write(0xcccccc, false, "| | "); - Write(0x333333, false, "::"); - Write(0x9900, true, ":"); - Write(0x333333, false, "::"); - Write(0xcccccc, false, "| |"); - Write(0x66ff, true, ". "); - Write(0xffffff, false, ".' "); - Write(0x9933, true, ". "); - Write(0x91cc, false, "."); - Write(0xcccccc, false, "| 13 "); - Write(0xffff66, false, "**\n "); - Write(0xcccccc, false, "|"); - Write(0xcc00, false, "..."); - Write(0xffffff, false, "'..''"); - Write(0xcccccc, false, "| |"); - Write(0xffffff, true, ". "); - Write(0x333333, false, ".:"); - Write(0x9900, true, ":::"); - Write(0x333333, false, ":"); - Write(0xcccccc, false, "| |"); - Write(0xc74c30, false, "."); - Write(0xff0000, false, "."); - Write(0xffffff, false, "|\\"); - Write(0xff0000, false, "."); - Write(0xc74c30, false, "."); - Write(0xa47a4d, false, "''"); - Write(0xcccccc, false, "| 14 "); - Write(0xffff66, false, "**\n "); - Write(0xcccccc, false, "|"); - Write(0xcc00, false, ". ''. "); - Write(0xcccccc, false, "| |"); - Write(0x666666, false, ". "); - Write(0x9900, true, ":::::"); - Write(0xcccccc, false, "| |"); - Write(0x666666, false, "──┬┴┴┴┬─"); - Write(0xcccccc, false, "| 15 "); - Write(0xffff66, false, "**\n "); - Write(0xcccccc, false, "| "); - Write(0xcc00, false, "'."); - Write(0x5555bb, false, "~ "); - Write(0xcc00, false, "'."); - Write(0xcccccc, false, "| |"); - Write(0x666666, false, " : "); - Write(0x333333, false, "::"); - Write(0x553322, true, ":"); - Write(0x333333, false, "::"); - Write(0xcccccc, false, "| |"); - Write(0x666666, false, "──┤AoC├o"); - Write(0xcccccc, false, "| 16 "); - Write(0xffff66, false, "**\n "); - Write(0xcccccc, false, "|"); - Write(0xcc00, false, ". "); - Write(0xffff66, true, "*"); - Write(0xcc00, false, "'."); - Write(0x5555bb, false, "~ "); - Write(0xcc00, false, ":"); - Write(0xcccccc, false, "| |"); - Write(0x666666, false, " '. "); - Write(0xcccccc, false, "| |"); - Write(0x666666, false, "┬o┤ten├─"); - Write(0xcccccc, false, "| 17 "); - Write(0xffff66, false, "**\n "); - Write(0xcccccc, false, "| "); - Write(0xcc00, false, "'..' .'"); - Write(0xcccccc, false, "| |"); - Write(0x666666, false, " '"); - Write(0x456efe, true, "o "); - Write(0xcccccc, false, "| |"); - Write(0x666666, false, "┘"); - Write(0xffff66, true, "*"); - Write(0x666666, false, "┤yrs├─"); - Write(0xcccccc, false, "| 18 "); - Write(0xffff66, false, "**\n "); - Write(0xcccccc, false, "| "); - Write(0x5555bb, false, "~ "); - Write(0xcc00, false, "..' "); - Write(0xcccccc, false, "| |"); - Write(0x666666, false, ": '."); - Write(0x333333, false, ".."); - Write(0xcccccc, false, "| |"); - Write(0x666666, false, "─┘├┬┬┬┴─"); - Write(0xcccccc, false, "| 19 "); - Write(0xffff66, false, "**\n "); - Write(0xcccccc, false, "|"); - Write(0xcc00, false, "'''"); - Write(0xcccccc, false, ")) | | "); - Write(0xbee4e7, true, "o "); - Write(0xffff66, true, "*"); - Write(0x666666, false, " : "); - Write(0xcccccc, false, "'. .'"); - Write(0x666666, false, "──┘"); - Write(0x9900, false, ">>"); - Write(0xff9900, true, "o"); - Write(0x9900, false, "<<"); - Write(0xcccccc, false, "| 20 "); - Write(0xffff66, false, "**\n "); - Write(0xcccccc, false, ".------'"); - Write(0x66ff, false, ".-"); - Write(0xcccccc, false, "(("); - Write(0x66ff, false, "---."); - Write(0xcccccc, false, "'------. |"); - Write(0x666666, false, " :"); - Write(0xff0000, false, "|"); - Write(0xcccccc, false, "\\| "); - Write(0x333399, false, "~ "); - Write(0x9900ff, false, "_"); - Write(0xcccccc, false, "'' "); - Write(0x9900ff, false, "O> "); - Write(0x9900, false, ">>"); - Write(0xff0000, true, "@"); - Write(0x9900, false, "<"); - Write(0xff9900, true, "o"); - Write(0x9900, false, "<"); - Write(0xcccccc, false, "| 21 "); - Write(0xffff66, false, "**\n "); - Write(0xcccccc, false, "| "); - Write(0xff0000, false, ".---_ "); - Write(0x66ff, false, "'------'_ "); - Write(0xaaaaaa, false, ".~' "); - Write(0xcccccc, false, "| | |"); - Write(0xff0000, false, "\\|"); - Write(0x9900ff, false, "\\ / \\ /"); - Write(0x333399, false, "~ "); - Write(0x9900, false, ">"); - Write(0xff0000, true, "@"); - Write(0x9900, false, "<<"); - Write(0xffff66, true, "*"); - Write(0x9900, false, "<"); - Write(0x66ff, true, "O"); - Write(0xcccccc, false, "| 22 "); - Write(0xffff66, false, "**\n "); - Write(0xcccccc, false, "|"); - Write(0xff0000, false, "/ "); - Write(0x880000, false, "/ "); - Write(0xff0000, false, "/\\|"); - Write(0x66ff, false, "| | )"); - Write(0xaaaaaa, false, "/"); - Write(0xe6410b, false, "~"); - Write(0xaaaaaa, false, "\\ "); - Write(0xcccccc, false, "| |"); - Write(0x66ff, false, "___"); - Write(0xff0000, false, "|"); - Write(0xcccccc, false, "\\|"); - Write(0x66ff, false, "________"); - Write(0x9900, false, ">"); - Write(0x66ff, true, "O"); - Write(0x9900, false, ">>"); - Write(0xff9900, true, "o"); - Write(0x9900, false, ">>"); - Write(0xff9900, true, "o"); - Write(0xcccccc, false, "| 23 "); - Write(0xffff66, false, "**\n "); - Write(0xcccccc, false, "|"); - Write(0x880000, false, "/ | "); - Write(0xff0000, false, "\\ "); - Write(0xffff66, true, "*"); - Write(0x66ff, false, "| |/"); - Write(0xaaaaaa, false, "/ "); - Write(0xe6410b, false, "/ "); - Write(0xaaaaaa, false, "\\ "); - Write(0xcccccc, false, "| | "); - Write(0x9b715b, false, "----@ "); - Write(0xaaaaaa, false, "_"); - Write(0xd0b376, false, "|%%%=%%|"); - Write(0xaaaaaa, false, "_ "); - Write(0xcccccc, false, "| 24 "); - Write(0xffff66, false, "**\n "); - Write(0xcccccc, false, "|"); - Write(0x880000, false, "/ \\ "); - Write(0xff0000, false, "\\ "); - Write(0x66ff, false, "'------'"); - Write(0xaaaaaa, false, "/ "); - Write(0xe6410b, false, "/ \\ "); - Write(0xaaaaaa, false, "\\"); - Write(0xcccccc, false, "| '-."); - Write(0x9b715b, false, "! /^\\ "); - Write(0xaaaaaa, false, "/ \\"); - Write(0x5eabb4, false, ".~~."); - Write(0xaaaaaa, false, "/ \\"); - Write(0xcccccc, false, ".-' 25 "); - Write(0xffff66, false, "**\n "); - Write(0x888888, false, "'----------------------' '------------------' \n \n"); - - Console.ForegroundColor = color; - Console.WriteLine(); - } - - private static void Write(int rgb, bool bold, string text){ - Console.Write($"\u001b[38;2;{(rgb>>16)&255};{(rgb>>8)&255};{rgb&255}{(bold ? ";1" : "")}m{text}"); - } -} \ No newline at end of file diff --git a/2024/calendar.svg b/2024/calendar.svg deleted file mode 100644 index 576f4919f..000000000 --- a/2024/calendar.svg +++ /dev/null @@ -1,48 +0,0 @@ - - - - -▄█▄ ▄▄█ ▄ ▄ ▄▄▄ ▄▄ ▄█▄  ▄▄▄ ▄█  ▄▄ ▄▄▄ ▄▄█ ▄▄▄ -█▄█ █ █ █ █ █▄█ █ █ █   █ █ █▄  █  █ █ █ █ █▄█ -█ █ █▄█ ▀▄▀ █▄▄ █ █ █▄  █▄█ █   █▄ █▄█ █▄█ █▄▄  /* 2024 */ -  -          .-----.          .------------------.          -       .--'~ ~ ~|        .-' *       \  /     '-.   1 ** -    .--'~  ,* ~ |        |  >o<   \_\_\|_/__/   |   2 ** -.---': ~ '(~), ~|        | >@>O< o-_/.()__------|   3 ** -|@..@'. ~ " ' ~ |        |>O>o<@< \____       .'|   4 ** -|_.~._@'.. ~ ~ *|        | _| |_    ..\_\_ ..'* |   5 ** -| ||| @   '''...|        |...     .'  '.'''../..|   6 ** -|@~~~@@##@# @#  |        |/\ ''.  |    |   -/  :|   7 ** -|~~..--. _____  |        |* /~\ '.|    | - /  .'|   8 ** -'---'  ||[][]_\-|        |~/ * \ :|    |  *..'  |   9 ** -       |------- |        |   /\ .'|    |'''~~~~~|  10 ** -       |.......||        |/\ ..'  |    | . .   .|  11 ** -       |  -  -  |        |''':::::|    |  . . ..|  12 ** -       |'. -   -|        |   :::::|    |. .' . .|  13 ** -       |...'..''|        |. .:::::|    |..|\..''|  14 ** -       |.  ''.  |        |.  :::::|    ||  15 ** -       | '.~  '.|        | : :::::|    |AoCo|  16 ** -       |. *'.~ :|        |  '.    |    |oten|  17 ** -       | '..' .'|        |   'o   |    |*yrs|  18 ** -       | ~ ..'  |        |:   '...|    ||  19 ** -       |'''))   |        | o  * : '.  .'>>o<<|  20 ** -.------'.-((---.'------. |  :|\| ~ _'' O> >>@<o<|  21 ** -| .---_ '------'_  .~' | |   |\|\ / \ /~ >@<<*<O|  22 ** -|/ / /\||      | )/~\  | |___|\|________>O>>o>>o|  23 ** -|/ | \ *|      |// / \ | |  ----@  _|%%%=%%|_   |  24 ** -|/  \ \ '------'/ / \ \| '-.! /^\ /  \.~~./  \.-'  25 ** -'----------------------'   '------------------'          - - - - \ No newline at end of file diff --git a/App.cs b/App.cs index 75d69d14d..5afe69b0c 100644 --- a/App.cs +++ b/App.cs @@ -56,22 +56,22 @@ var tsolversSelected = tsolvers.First(tsolver => SolverExtensions.Year(tsolver) == year && SolverExtensions.Day(tsolver) == day); - return () => Runner.RunAll(true, true, true, GetSolvers(tsolversSelected)); + return () => Runner.RunAll(GetSolvers(tsolversSelected)); }) ?? Command(args, Args("[0-9]+"), m => { var year = int.Parse(m[0]); var tsolversSelected = tsolvers.Where(tsolver => SolverExtensions.Year(tsolver) == year); - return () => Runner.RunAll(true, true, true, GetSolvers(tsolversSelected.ToArray())); + return () => Runner.RunAll(GetSolvers(tsolversSelected.ToArray())); }) ?? Command(args, Args("([0-9]+)/all"), m => { var year = int.Parse(m[0]); var tsolversSelected = tsolvers.Where(tsolver => SolverExtensions.Year(tsolver) == year); - return () => Runner.RunAll(true, true, true, GetSolvers(tsolversSelected.ToArray())); + return () => Runner.RunAll(GetSolvers(tsolversSelected.ToArray())); }) ?? Command(args, Args("all"), m => { - return () => Runner.RunAll(true, true, true, GetSolvers(tsolvers)); + return () => Runner.RunAll(GetSolvers(tsolvers)); }) ?? Command(args, Args("today"), m => { var dt = DateTime.UtcNow.AddHours(-5); @@ -82,17 +82,26 @@ SolverExtensions.Day(tsolver) == dt.Day); return () => - Runner.RunAll(true, true, true, GetSolvers(tsolversSelected)); + Runner.RunAll(GetSolvers(tsolversSelected)); } else { throw new AocCommuncationError("Event is not active. This option works in Dec 1-25 only)"); } }) ?? Command(args, Args("calendars"), _ => { - return () => Runner.RunAll(false, true, false, GetSolvers(tsolvers)); - }) ?? - Command(args, Args("loc"), _ => { - return () => Runner.RunAll(false, false, true, GetSolvers(tsolvers)); + return () => { + var tsolversSelected = ( + from tsolver in tsolvers + group tsolver by SolverExtensions.Year(tsolver) into g + orderby SolverExtensions.Year(g.First()) descending + select g.First() + ).ToArray(); + + var solvers = GetSolvers(tsolversSelected); + foreach (var solver in solvers) { + solver.SplashScreen().Show(); + } + }; }) ?? new Action(() => { Console.WriteLine(Usage.Get()); @@ -100,8 +109,8 @@ try { action(); -} catch (AggregateException a) { - if (a.InnerExceptions.Count == 1 && a.InnerException is AocCommuncationError) { +} catch (AggregateException a){ + if (a.InnerExceptions.Count == 1 && a.InnerException is AocCommuncationError){ Console.WriteLine(a.InnerException.Message); } else { throw; @@ -122,8 +131,8 @@ Action Command(string[] args, string[] regexes, Func parse) { } try { - return parse(matches.SelectMany(m => - m.Groups.Count > 1 ? m.Groups.Cast().Skip(1).Select(g => g.Value) + return parse(matches.SelectMany(m => + m.Groups.Count > 1 ? m.Groups.Cast().Skip(1).Select(g => g.Value) : new[] { m.Value } ).ToArray()); } catch { @@ -137,37 +146,35 @@ string[] Args(params string[] regex) { class Usage { public static string Get() { - return $""" - Usage: dotnet run [arguments] - 1) To run the solutions and admire your advent calendar: + return $@" + > Usage: dotnet run [arguments] + > 1) To run the solutions and admire your advent calendar: - [year]/[day|all] Solve the specified problems - today Shortcut to the above - [year] Solve the whole year - all Solve everything + > [year]/[day|all] Solve the specified problems + > today Shortcut to the above + > [year] Solve the whole year + > all Solve everything - calendars Show the calendars - loc Show the line of code charts + > calendars Show the calendars - 2) To start working on new problems: - login to https://adventofcode.com, then copy your session cookie, and export - it in your console like this + > 2) To start working on new problems: + > login to https://adventofcode.com, then copy your session cookie, and export + > it in your console like this - export SESSION=73a37e9a72a... + > export SESSION=73a37e9a72a... - then run the app with + > then run the app with - update [year]/[day] Prepares a folder for the given day, updates the input, - the readme and creates a solution template. - update today Shortcut to the above. + > update [year]/[day] Prepares a folder for the given day, updates the input, + > the readme and creates a solution template. + > update today Shortcut to the above. - 3) To upload your answer: - set up your SESSION variable as above. + > 3) To upload your answer: + > set up your SESSION variable as above. - upload [year]/[day] Upload the answer for the selected year and day. - upload today Shortcut to the above. + > upload [year]/[day] Upload the answer for the selected year and day. + > upload today Shortcut to the above. - 4) Don't forget to tip the maintainer https://github.com/sponsors/encse. - """; + > ".StripMargin("> "); } } diff --git a/LICENSE.txt b/LICENSE.txt index e381440e0..d9cdf0629 100644 --- a/LICENSE.txt +++ b/LICENSE.txt @@ -1,20 +1,24 @@ Copyright (c) 2019 David Nemeth Cs. -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: +The license applies to all source code and configuration incluced in +the repository. It doesn't apply to advent of code problem statements +and input files. For the license conditions of those please contact the +original author at https://adventofcode.com. -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. \ No newline at end of file +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/Lib/CheckGitCrypt.cs b/Lib/CheckGitCrypt.cs deleted file mode 100644 index 9b7c76d5d..000000000 --- a/Lib/CheckGitCrypt.cs +++ /dev/null @@ -1,39 +0,0 @@ -using System; -using System.IO; -using System.Linq; -using System.Text; - -class GitCrypt { - public static void Check() { - if (!File.Exists(".git/git-crypt/keys/default")) { - Console.WriteLine( - """ - Repository is not unlocked. You need to install and configure git-crypt. - Check out the README file. - """); - Environment.Exit(1); - } - } - - public static void CheckFile(string file) { - using (FileStream fileStream = new FileStream(file, FileMode.Open, FileAccess.Read)) { - fileStream.Seek(1, SeekOrigin.Begin); - byte[] buffer = new byte[8]; - int bytesRead = fileStream.Read(buffer, 0, buffer.Length); - - // If the file is smaller than the requested byte count, resize the array - if (bytesRead < buffer.Length) { - return; - } - - if (Encoding.ASCII.GetBytes("GITCRYPT").SequenceEqual(buffer)) { - Console.WriteLine( - $""" - File '{file}' is encrypted. You need to install and configure git-crypt. - Check out the README file. - """); - Environment.Exit(1); - } - } - } -} \ No newline at end of file diff --git a/Lib/Generator/ReadmeGenerator.cs b/Lib/Generator/ReadmeGenerator.cs index 5b88fe66a..422dbe323 100644 --- a/Lib/Generator/ReadmeGenerator.cs +++ b/Lib/Generator/ReadmeGenerator.cs @@ -1,15 +1,78 @@ +using System.Linq; using AdventOfCode.Model; namespace AdventOfCode.Generator; +class ProjectReadmeGenerator { + public string Generate(int firstYear, int lastYear) { + + return $@" + > # Advent of Code ({firstYear}-{lastYear}) + > C# solutions to the Advent of Code problems. + > Check out https://adventofcode.com. + > + > + > + > The goal is to keep my C# knowledge fresh and to follow the latest changes of the language. + > + > Everything is self contained. I don't use any libraries to make things short or predefined algorithms + > to parameterize. Just stick to what .Net provides. Each problem is solved by plain C# classes without any 'base' to derive from. + > The solvers have different entry points for part 1 and 2. There is no local state, part 2 starts from scratch, + > but code sharing between part 1 and 2 is important to me. (Unless it makes things hard to read.) + > + > I prefer to use functional style, local or anonymous functions, immutability and linq over the state manipulation + > style of oop, but I'm not very strict about this. Whatever I see fit for the problem. + > + > One thing that you will not see much in C# projects is K&R indentation. Sorry about that... + > + > The way I solve the puzzles should be pretty consistent during an event but there are small changes over + > the years as I find something new or forget about stuff I learned last year. + > + > I try to keep things tight and golf the solution to a certain level, but don't want to overgolf it. (Sometimes I fail.) + > + > There aren't many comments, but if I find that the solution is not straightforward, the algorithm has a name, or it is + > using some special property of the input I might explain it in a line or two. + > + > You can browse my solutions as they are or fork the repo, remove everything and use just the lib part to + > start working on your own. The framework part is pretty stable and you get testing, scaffolding etc for free. + > + > ## Dependencies + + > - This project is based on `.NET 7` and `C# 11`. It should work on Windows, Linux and OS-X. + > - `AngleSharp` is used for problem download. + + > ## Running + + > To run the project: + + > 1. Install .NET Core + > 2. Clone the repo + > 3. Get help with `dotnet run` + > ``` + > {Usage.Get()} + > ``` + + > ## Working in Visual Studio Code + > If you prefer, you can work directly in VSCode as well. + + > Open the command Palette (⇧ ⌘ P), select `Tasks: Run Task` then e.g. `update today`. + > + > Work on part 1. Check the solution with the `upload today` task. Continue with part 2. + > + > **Note:** this feature relies on the ""Memento Inputs"" extension to store your session cookie, you need + > to set it up in advance from the Command Palette with `Install Extensions`. + > ".StripMargin("> "); + } +} + class ReadmeGeneratorForYear { public string Generate(Calendar calendar) { - return $""" - # Advent of Code ({calendar.Year}) - Check out https://adventofcode.com/{calendar.Year}. + return $@" + > # Advent of Code ({calendar.Year}) + > Check out https://adventofcode.com/{calendar.Year}. - + > - """; + > ".StripMargin("> "); } } diff --git a/Lib/Generator/SolutionTemplateGenerator.cs b/Lib/Generator/SolutionTemplateGenerator.cs index 8b67a4ed3..023f785c2 100644 --- a/Lib/Generator/SolutionTemplateGenerator.cs +++ b/Lib/Generator/SolutionTemplateGenerator.cs @@ -4,28 +4,26 @@ namespace AdventOfCode.Generator; class SolutionTemplateGenerator { public string Generate(Problem problem) { - return $$""" - namespace AdventOfCode.Y{{problem.Year}}.Day{{problem.Day:00}}; - - using System; - using System.Collections.Generic; - using System.Collections.Immutable; - using System.Linq; - using System.Text.RegularExpressions; - using System.Text; - using System.Numerics; - - [ProblemName("{{problem.Title}}")] - class Solution : Solver { - - public object PartOne(string input) { - return 0; - } - - public object PartTwo(string input) { - return 0; - } - } - """; + return $@"using System; + |using System.Collections.Generic; + |using System.Collections.Immutable; + |using System.Linq; + |using System.Text.RegularExpressions; + |using System.Text; + | + |namespace AdventOfCode.Y{problem.Year}.Day{problem.Day.ToString("00")}; + | + |[ProblemName(""{problem.Title}"")] + |class Solution : Solver {{ + | + | public object PartOne(string input) {{ + | return 0; + | }} + | + | public object PartTwo(string input) {{ + | return 0; + | }} + |}} + |".StripMargin(); } } diff --git a/Lib/Generator/SplashScreenGenerator.cs b/Lib/Generator/SplashScreenGenerator.cs index 050b2c8ee..2479376eb 100644 --- a/Lib/Generator/SplashScreenGenerator.cs +++ b/Lib/Generator/SplashScreenGenerator.cs @@ -8,26 +8,26 @@ namespace AdventOfCode.Generator; class SplashScreenGenerator { public string Generate(Calendar calendar) { string calendarPrinter = CalendarPrinter(calendar); - return $$""" - using System; - - namespace AdventOfCode.Y{{calendar.Year}}; - - class SplashScreenImpl : SplashScreen { - - public void Show() { - - var color = Console.ForegroundColor; - {{calendarPrinter.Indent(12)}} - Console.ForegroundColor = color; - Console.WriteLine(); - } - - private static void Write(int rgb, bool bold, string text){ - Console.Write($"\u001b[38;2;{(rgb>>16)&255};{(rgb>>8)&255};{rgb&255}{(bold ? ";1" : "")}m{text}"); - } - } - """; + return $@" + |using System; + | + |namespace AdventOfCode.Y{calendar.Year}; + | + |class SplashScreenImpl : SplashScreen {{ + | + | public void Show() {{ + | + | var color = Console.ForegroundColor; + | {calendarPrinter.Indent(12)} + | Console.ForegroundColor = color; + | Console.WriteLine(); + | }} + | + | private static void Write(int rgb, bool bold, string text){{ + | Console.Write($""\u001b[38;2;{{(rgb>>16)&255}};{{(rgb>>8)&255}};{{rgb&255}}{{(bold ? "";1"" : """")}}m{{text}}""); + | }} + |}} + |".StripMargin(); } private string CalendarPrinter(Calendar calendar) { diff --git a/Lib/Model/Calendar.cs b/Lib/Model/Calendar.cs index 2d6fcc714..119fd5d68 100644 --- a/Lib/Model/Calendar.cs +++ b/Lib/Model/Calendar.cs @@ -5,7 +5,6 @@ using System.Text.RegularExpressions; using System.Text; using AngleSharp.Dom; -using System.Globalization; namespace AdventOfCode.Model; @@ -98,7 +97,7 @@ public static Calendar Parse(int year, IDocument document) { foreach (var textNode in GetText(calendar)) { var text = textNode.Text(); var style = textNode.ParentElement.ComputeCurrentStyle(); - var rgbaColor = !string.IsNullOrEmpty(style["color"]) ? style["color"]: "rgba(204,204,204,1)"; + var rgbaColor = style["color"]; var bold = !string.IsNullOrEmpty(style["text-shadow"]); if (style["position"] == "absolute" || @@ -112,7 +111,7 @@ public static Calendar Parse(int year, IDocument document) { var m = Regex.Match(widthSpec, "[.0-9]+"); if (m.Success) { - var width = double.Parse(m.Value, CultureInfo.InvariantCulture) * 1.7; + var width = double.Parse(m.Value) * 1.7; var c = (int)Math.Round(width - text.Length, MidpointRounding.AwayFromZero); if (c > 0) { text += new string(' ', c); diff --git a/Lib/Model/Problem.cs b/Lib/Model/Problem.cs index b1ae3a94f..e4a279106 100644 --- a/Lib/Model/Problem.cs +++ b/Lib/Model/Problem.cs @@ -16,36 +16,11 @@ class Problem { public static Problem Parse(int year, int day, string url, IDocument document, string input) { - var md = ParseMdIntro(document, 2, url); - - var answers = ParseAnswers(document); - var title = document.QuerySelector("h2").TextContent; - - var match = Regex.Match(title, ".*: (.*) ---"); - if (match.Success) { - title = match.Groups[1].Value; - } - return new Problem {Year = year, Day = day, Title = title, ContentMd = md, Input = input, Answers = answers.ToArray() }; - } - - static string ParseMdIntro(IDocument document, int paragraphs, string url) { - var article = ParseMd(document).Split("\n\n").ToList(); - article = article.Take(Math.Min(paragraphs, article.Count)).ToList(); - article.Add($"_Visit the website for the full story and [full puzzle]({url}) description._\n"); - return string.Join("\n\n", article); - } - - static string ParseMd(IDocument document) { - var md = ""; + var md = $"original source: [{url}]({url})\n"; + var answers = new List(); foreach (var article in document.QuerySelectorAll("article")) { md += UnparseList("", article) + "\n"; - } - return md; - } - static List ParseAnswers(IDocument document) { - var answers = new List(); - foreach (var article in document.QuerySelectorAll("article")) { var answerNode = article.NextSibling; while (answerNode != null && !( answerNode.NodeName == "P" @@ -60,7 +35,13 @@ static List ParseAnswers(IDocument document) { answers.Add(code.TextContent); } } - return answers; + var title = document.QuerySelector("h2").TextContent; + + var match = Regex.Match(title, ".*: (.*) ---"); + if (match.Success) { + title = match.Groups[1].Value; + } + return new Problem {Year = year, Day = day, Title = title, ContentMd = md, Input = input, Answers = answers.ToArray() }; } static string UnparseList(string sep, INode element) { diff --git a/Lib/Ocr.cs b/Lib/Ocr.cs index 21511c9aa..fa6dcad04 100644 --- a/Lib/Ocr.cs +++ b/Lib/Ocr.cs @@ -28,29 +28,29 @@ public override string ToString() { var width = lines[0].Length; var height = lines.Length; - var smallAlphabet = """ - A B C E F G H I J K L O P R S U Y Z - ## ### ## #### #### ## # # ### ## # # # ## ### ### ### # # # ##### - # # # # # # # # # # # # # # # # # # # # # # # # # # # # # - # # ### # ### ### # #### # # ## # # # # # # # # # # # # # - #### # # # # # # ## # # # # # # # # # ### ### ## # # # # - # # # # # # # # # # # # # # # # # # # # # # # # # # # # - # # ### ## #### # ### # # ### ## # # #### ## # # # ### ## # #### - """.Split('\n'); - - var largeAlphabet = """ - A B C E F G H J K L N P R X Z - ## ##### #### ###### ###### #### # # ### # # # # # ##### ##### # # ###### - # # # # # # # # # # # # # # # # ## # # # # # # # # - # # # # # # # # # # # # # # ## # # # # # # # # - # # # # # # # # # # # # # # # # # # # # # # # # - # # ##### # ##### ##### # ###### # ## # # # # ##### ##### ## # - ###### # # # # # # ### # # # ## # # # # # # # ## # - # # # # # # # # # # # # # # # # # # # # # # # # - # # # # # # # # # # # # # # # # # ## # # # # # # - # # # # # # # # # ## # # # # # # # # ## # # # # # # - # # ##### #### ###### # ### # # # ### # # ###### # # # # # # # ###### - """.Split('\n'); + var smallAlphabet = StripMargin(@" + | A B C E F G H I J K L O P R S U Y Z + | ## ### ## #### #### ## # # ### ## # # # ## ### ### ### # # # ##### + | # # # # # # # # # # # # # # # # # # # # # # # # # # # # # + | # # ### # ### ### # #### # # ## # # # # # # # # # # # # # + | #### # # # # # # ## # # # # # # # # # ### ### ## # # # # + | # # # # # # # # # # # # # # # # # # # # # # # # # # # # + | # # ### ## #### # ### # # ### ## # # #### ## # # # ### ## # #### + "); + + var largeAlphabet = StripMargin(@" + | A B C E F G H J K L N P R X Z + | ## ##### #### ###### ###### #### # # ### # # # # # ##### ##### # # ###### + | # # # # # # # # # # # # # # # # ## # # # # # # # # + | # # # # # # # # # # # # # # ## # # # # # # # # + | # # # # # # # # # # # # # # # # # # # # # # # # + | # # ##### # ##### ##### # ###### # ## # # # # ##### ##### ## # + | ###### # # # # # # ### # # # ## # # # # # # # ## # + | # # # # # # # # # # # # # # # # # # # # # # # # + | # # # # # # # # # # # # # # # # # ## # # # # # # + | # # # # # # # # # ## # # # # # # # # ## # # # # # # + | # # ##### #### ###### # ### # # # ### # # ###### # # # # # # # ###### + "); var charMap = lines.Length == smallAlphabet.Length - 1 ? smallAlphabet : @@ -66,6 +66,12 @@ A B C E F G H J K L return res; } + string[] StripMargin(string st) => ( + from line in Regex.Split(st, "\r?\n") + where Regex.IsMatch(line, @"^\s*\| ") + select Regex.Replace(line, @"^\s* \| ", "") + ).ToArray(); + public string Detect(string[] text, int icolLetter, int charWidth, int charHeight, string[] charMap) { var textRect = GetRect(text, icolLetter, 0, charWidth, charHeight); diff --git a/Lib/Runner.cs b/Lib/Runner.cs index 4ae3e3792..e3e45e5d8 100644 --- a/Lib/Runner.cs +++ b/Lib/Runner.cs @@ -4,7 +4,6 @@ using System.Linq; using System.Reflection; using System.Diagnostics; -using System.Text.RegularExpressions; namespace AdventOfCode; @@ -75,15 +74,6 @@ public static SplashScreen SplashScreen(this Solver solver) { .Single(t => Year(t) == solver.Year()); return (SplashScreen)Activator.CreateInstance(tsplashScreen); } - - public static int Sloc(this Solver solver) { - var file = solver.WorkingDir() + "/Solution.cs"; - if (File.Exists(file)) { - var solution = File.ReadAllText(file); - return Regex.Matches(solution, @"\n").Count; - } - return -1; - } } record SolverResult(string[] answers, string[] errors); @@ -91,7 +81,6 @@ record SolverResult(string[] answers, string[] errors); class Runner { private static string GetNormalizedInput(string file) { - GitCrypt.CheckFile(file); var input = File.ReadAllText(file); // on Windows we have "\r\n", not sure if this causes more harm or not @@ -150,50 +139,35 @@ public static SolverResult RunSolver(Solver solver) { return new SolverResult(answers.ToArray(), errors.ToArray()); } - public static void RunAll(bool executeSolvers, bool showSplashScreen, bool showLocChart, params Solver[] solvers) { - + public static void RunAll(params Solver[] solvers) { var errors = new List(); var lastYear = -1; - List<(int day, int sloc)> slocs = new (); foreach (var solver in solvers) { - if (lastYear != solver.Year()) { - if (showLocChart){ - SlocChart.Show(lastYear, slocs); - } - slocs.Clear(); - - if (showSplashScreen){ - solver.SplashScreen().Show(); - } + solver.SplashScreen().Show(); lastYear = solver.Year(); } - slocs.Add((solver.Day(), solver.Sloc())); - if (executeSolvers){ - var result = RunSolver(solver); - WriteLine(); - errors.AddRange(result.errors); - } - } - if (showLocChart){ - SlocChart.Show(lastYear, slocs); + + var result = RunSolver(solver); WriteLine(); + errors.AddRange(result.errors); } + WriteLine(); + if (errors.Any()) { WriteLine(ConsoleColor.Red, "Errors:\n" + string.Join("\n", errors)); } - - WriteLine(ConsoleColor.Yellow, "Please support the maintainer: https://github.com/sponsors/encse"); - WriteLine(); } private static void WriteLine(ConsoleColor color = ConsoleColor.Gray, string text = "") { - Terminal.WriteLine(color, text); + Write(color, text + "\n"); } private static void Write(ConsoleColor color = ConsoleColor.Gray, string text = "") { - Terminal.Write(color, text); + var c = Console.ForegroundColor; + Console.ForegroundColor = color; + Console.Write(text); + Console.ForegroundColor = c; } - } diff --git a/Lib/SlocChart.cs b/Lib/SlocChart.cs deleted file mode 100644 index f4a667a77..000000000 --- a/Lib/SlocChart.cs +++ /dev/null @@ -1,83 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using Microsoft.VisualBasic; - -namespace AdventOfCode; - - -class SlocChart { - public static void Show(int year, List<(int day, int sloc)> slocs) { - if (slocs.Count < 2) { - return; - } - - - var chars = "█▁▂▃▄▅▆▇"; - var max = slocs.Max(sloc => sloc.sloc); - var min = slocs.Min(sloc => sloc.sloc); - var total = slocs.Sum(sloc => sloc.sloc); - - Console.WriteLine($" {year } in code lines total: {total} max: {max} min: {min}"); - Console.WriteLine(""); - - - var columns = new List>(); - - var icol = 0; - var prevSloc = -1; - foreach (var sloc in slocs) { - icol++; - var col = new List(); - var h = sloc.sloc; - - var color = - h > 200 ? ConsoleColor.Red : - h > 100 ? ConsoleColor.Yellow : - ConsoleColor.DarkGray; - h /= 2; - - if (Math.Abs(prevSloc - sloc.sloc) > 20 || prevSloc < 100 && sloc.sloc < 100) { - var slocSt = sloc.sloc.ToString(); - col.Add(slocSt.WithColor(ConsoleColor.White)); - } - prevSloc = sloc.sloc; - if (h % chars.Length != 0) { - var ch = chars[h % chars.Length]; - col.Add($"{ch}{ch}".WithColor(color)); - h -= h % chars.Length; - } - while (h >= 0) { - var ch = chars[0]; - col.Add($"{ch}{ch}".WithColor(color)); - h -= chars.Length; - } - col.Add(sloc.day.ToString().PadLeft(2, ' ').WithColor(ConsoleColor.White)); - var w = 3; - col = col.Select(r => r.st.PadLeft(w).WithColor(r.c)).ToList(); - columns.Add(col); - } - - var rows = new List>(); - var height = columns.Select(col => col.Count).Max(); - for (var irow = 0; irow < height; irow++) { - var row = new List(); - foreach (var col in columns) { - var color = col.Count > irow ? col[col.Count - irow - 1].c : ConsoleColor.Gray; - var st = col.Count > irow ? col[col.Count - irow - 1].st : ""; - var w = col.Select(r => r.st.Length).Max(); - st = st.PadLeft(w); - row.Add(st.WithColor(color)); - } - rows.Insert(0, row); - } - - foreach (var row in rows) { - foreach (var item in row) { - Terminal.Write(item.c, item.st); - } - Console.WriteLine(); - } - Console.WriteLine(""); - } -} \ No newline at end of file diff --git a/Lib/StringExtensions.cs b/Lib/StringExtensions.cs index 86a7248c0..a0509e206 100644 --- a/Lib/StringExtensions.cs +++ b/Lib/StringExtensions.cs @@ -1,10 +1,16 @@ -using System; using System.Linq; using System.Text.RegularExpressions; namespace AdventOfCode; public static class StringExtensions { + public static string StripMargin(this string st, string margin = "|") { + return string.Join("\n", + from line in Regex.Split(st, "\r?\n") + select Regex.Replace(line, @"^\s*"+Regex.Escape(margin), "") + ); + } + public static string Indent(this string st, int l, bool firstLine = false) { var indent = new string(' ', l); var res = string.Join("\n" + new string(' ', l), @@ -13,9 +19,4 @@ select Regex.Replace(line, @"^\s*\|", "") ); return firstLine ? indent + res : res; } - public static ColoredString WithColor(this string st, ConsoleColor c) { - return new ColoredString(c, st); - } } - -public record ColoredString(ConsoleColor c, string st); diff --git a/Lib/Terminal.cs b/Lib/Terminal.cs deleted file mode 100644 index 6f9a3d1d9..000000000 --- a/Lib/Terminal.cs +++ /dev/null @@ -1,36 +0,0 @@ - -using System; - -class Terminal { - public static void WriteLine(ConsoleColor color = ConsoleColor.Gray, string text = "") { - Write(color, text + "\n"); - } - public static void Write(ConsoleColor color = ConsoleColor.Gray, string text = "") { - - Console.Write($"\u001b[{ToAnsiColorCode(color)}"); - Console.Write(text); - Console.Write("\u001b[0m"); - } - - private static string ToAnsiColorCode(ConsoleColor color) { - switch(color) { - case ConsoleColor.Black: return "30m"; - case ConsoleColor.DarkRed: return "31m"; - case ConsoleColor.DarkGreen: return "32m"; - case ConsoleColor.DarkYellow: return "33m"; - case ConsoleColor.DarkBlue: return "34m"; - case ConsoleColor.DarkMagenta: return "35m"; - case ConsoleColor.DarkCyan: return "36m"; - case ConsoleColor.DarkGray: return "37m"; - case ConsoleColor.Gray: return "90m"; - case ConsoleColor.Red: return "91m"; - case ConsoleColor.Green: return "92m"; - case ConsoleColor.Yellow: return "93m"; - case ConsoleColor.Blue: return "94m"; - case ConsoleColor.Magenta: return "95m"; - case ConsoleColor.Cyan: return "96m"; - case ConsoleColor.White: return "97m"; - } - throw new Exception($"unhandled color code {color}"); - } -} \ No newline at end of file diff --git a/Lib/Updater.cs b/Lib/Updater.cs index 62d2dde2a..803fe1caa 100644 --- a/Lib/Updater.cs +++ b/Lib/Updater.cs @@ -18,7 +18,6 @@ namespace AdventOfCode; class Updater { public async Task Update(int year, int day) { - GitCrypt.Check(); var session = GetSession(); var baseAddress = new Uri("https://adventofcode.com/"); @@ -49,6 +48,7 @@ public async Task Update(int year, int day) { years = new int[] { year }; } + UpdateProjectReadme(years.Min(), years.Max()); UpdateReadmeForYear(calendar); UpdateSplashScreen(calendar); UpdateReadmeForDay(problem); @@ -204,6 +204,11 @@ void UpdateSolutionTemplate(Problem problem) { } } + void UpdateProjectReadme(int firstYear, int lastYear) { + var file = Path.Combine("README.md"); + WriteFile(file, new ProjectReadmeGenerator().Generate(firstYear, lastYear)); + } + void UpdateReadmeForYear(Calendar calendar) { var file = Path.Combine(SolverExtensions.WorkingDir(calendar.Year), "README.md"); WriteFile(file, new ReadmeGeneratorForYear().Generate(calendar)); diff --git a/README.md b/README.md index 8b616b4f6..33878dbac 100644 --- a/README.md +++ b/README.md @@ -1,18 +1,84 @@ - # Advent of Code (2015-2024) - C# solutions to the [Advent of Code](https://adventofcode.com) problems. - +# Advent of Code (2015-2022) +C# solutions to the Advent of Code problems. +Check out https://adventofcode.com. - I'm making a [website](https://aoc.csokavar.hu) out of this. - - A lot of effort goes into my solutions to present things in an easy to understand and elegant way. Clarity first also means less emphasis on speed, but I try to balance it until each puzzle's runtime fits into a second. - - The framework I'm using is freely available and it's pretty streamlined by now. You can start with the - https://github.com/encse/adventofcode-template repository. + - Like what you see? Consider [sponsoring](https://github.com/sponsors/encse) me. +The goal is to keep my C# knowledge fresh and to follow the latest changes of the language. - ## Dependencies - - Based on `.NET 9` and `C# 13`. - - `AngleSharp` is used for problem download. - - git-crypt to store the input files in an encrypted form +Everything is self contained. I don't use any libraries to make things short or predefined algorithms +to parameterize. Just stick to what .Net provides. Each problem is solved by plain C# classes without any 'base' to derive from. +The solvers have different entry points for part 1 and 2. There is no local state, part 2 starts from scratch, +but code sharing between part 1 and 2 is important to me. (Unless it makes things hard to read.) + +I prefer to use functional style, local or anonymous functions, immutability and linq over the state manipulation +style of oop, but I'm not very strict about this. Whatever I see fit for the problem. + +One thing that you will not see much in C# projects is K&R indentation. Sorry about that... + +The way I solve the puzzles should be pretty consistent during an event but there are small changes over +the years as I find something new or forget about stuff I learned last year. + +I try to keep things tight and golf the solution to a certain level, but don't want to overgolf it. (Sometimes I fail.) + +There aren't many comments, but if I find that the solution is not straightforward, the algorithm has a name, or it is +using some special property of the input I might explain it in a line or two. + +You can browse my solutions as they are or fork the repo, remove everything and use just the lib part to +start working on your own. The framework part is pretty stable and you get testing, scaffolding etc for free. + +## Dependencies + +- This project is based on `.NET 7` and `C# 11`. It should work on Windows, Linux and OS-X. +- `AngleSharp` is used for problem download. + +## Running + +To run the project: + +1. Install .NET Core +2. Clone the repo +3. Get help with `dotnet run` +``` + +Usage: dotnet run [arguments] +1) To run the solutions and admire your advent calendar: + + [year]/[day|all] Solve the specified problems + today Shortcut to the above + [year] Solve the whole year + all Solve everything + + calendars Show the calendars + +2) To start working on new problems: +login to https://adventofcode.com, then copy your session cookie, and export +it in your console like this + + export SESSION=73a37e9a72a... + +then run the app with + + update [year]/[day] Prepares a folder for the given day, updates the input, + the readme and creates a solution template. + update today Shortcut to the above. + +3) To upload your answer: +set up your SESSION variable as above. + + upload [year]/[day] Upload the answer for the selected year and day. + upload today Shortcut to the above. + + +``` + +## Working in Visual Studio Code +If you prefer, you can work directly in VSCode as well. + + Open the command Palette (⇧ ⌘ P), select `Tasks: Run Task` then e.g. `update today`. + + Work on part 1. Check the solution with the `upload today` task. Continue with part 2. + + **Note:** this feature relies on the "Memento Inputs" extension to store your session cookie, you need + to set it up in advance from the Command Palette with `Install Extensions`. diff --git a/adventofcode.csproj b/adventofcode.csproj index 426add6a1..7be918ac7 100755 --- a/adventofcode.csproj +++ b/adventofcode.csproj @@ -1,13 +1,15 @@ Exe - net9.0 - 13 + net7.0 + 11 true - false + + + \ No newline at end of file diff --git a/adventofcode.sln b/adventofcode.sln deleted file mode 100644 index d16351e79..000000000 --- a/adventofcode.sln +++ /dev/null @@ -1,25 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 17 -VisualStudioVersion = 17.5.002.0 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "adventofcode", "adventofcode.csproj", "{0311BBC7-3D97-4391-B294-89A21ED184D7}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Any CPU = Debug|Any CPU - Release|Any CPU = Release|Any CPU - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {0311BBC7-3D97-4391-B294-89A21ED184D7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {0311BBC7-3D97-4391-B294-89A21ED184D7}.Debug|Any CPU.Build.0 = Debug|Any CPU - {0311BBC7-3D97-4391-B294-89A21ED184D7}.Release|Any CPU.ActiveCfg = Release|Any CPU - {0311BBC7-3D97-4391-B294-89A21ED184D7}.Release|Any CPU.Build.0 = Release|Any CPU - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection - GlobalSection(ExtensibilityGlobals) = postSolution - SolutionGuid = {830E1FB4-A083-4DC8-A157-2C1AC6B9F285} - EndGlobalSection -EndGlobal diff --git a/docs/build.js b/docs/build.js deleted file mode 100644 index 4a0efdc78..000000000 --- a/docs/build.js +++ /dev/null @@ -1,185 +0,0 @@ -const fs = require('fs'); -const path = require('path'); -const marked = require('marked'); - - -function media(dir){ - const files = fs.readdirSync(dir); - return files.filter(file => - path.extname(file).toLowerCase() === '.gif' || - path.extname(file).toLowerCase() === '.png' - ).map(file => path.join(dir, file)); -} - -function* findReadmes(dir) { - const entries = fs.readdirSync(dir, { withFileTypes: true }); - - for (const entry of entries) { - const fullPath = path.join(dir, entry.name); - - if (entry.isDirectory()) { - const match = fullPath.match(/(\d{4})\/Day(\d{1,2})/i); - if (match) { - const year = parseInt(match[1], 10); - const day = parseInt(match[2], 10); - - // Check the directory for a readme.md file - const readmePath = path.join(fullPath, 'README.md'); - const solutionPath = path.join(fullPath, 'Solution.cs'); - const illustrationPath = path.join(fullPath, 'illustration.jpeg'); - if (fs.existsSync(readmePath) && fs.existsSync(solutionPath)) { - - const rawContent = fs.readFileSync(readmePath, 'utf8'); - - let name = ''; - const match = rawContent.match(/^## --- Day \d+: (.+?) ---/); - if (match) { - name = match[1]; - } - - let lines = rawContent.split('\n'); - while (lines.length > 0) { - let line = lines.shift(); - if (line.match(/^## --- Day \d+: (.+?) ---/)) { - break; - } - } - - - yield { - year, - day, - path: readmePath, - name: name, - notes: marked.parse(lines.join('\n')), - code: fs.readFileSync(solutionPath, 'utf8'), - illustration: fs.existsSync(illustrationPath) ? illustrationPath : 'docs/elf.jpeg', - media: media(fullPath) - }; - } - } - - // Recursively search within this directory - yield* findReadmes(fullPath); - } - } -} - - -function copyDirectory(src, dest) { - if (!fs.existsSync(src)) { - throw new Error(`Source directory does not exist: ${src}`); - } - - if (!fs.existsSync(dest)) { - fs.mkdirSync(dest, { recursive: true }); - } - - const items = fs.readdirSync(src); - - items.forEach(item => { - const srcPath = path.join(src, item); - const destPath = path.join(dest, item); - - if (fs.statSync(srcPath).isDirectory()) { - copyDirectory(srcPath, destPath); - } else { - fs.copyFileSync(srcPath, destPath); - } - }); - }; - - -function loadTemplate(templatePath) { - return fs.readFileSync(templatePath, 'utf8'); -} - - -function fillTemplate(template, replacements) { - return template.replace(/{{\s*([\w-]+)\s*}}/g, (_, key) => replacements[key] || ''); -} - -function generateYearPicker(year, day, yearToDays) { - let options = ''; - for (let y of Object.keys(yearToDays).sort()){ - let lastDay = yearToDays[y][yearToDays[y].length-1]; - let target = `/${y}/${lastDay}/` - options += `${y}` - } - - return ` - `; -} - -function generateDayPicker(year, day, yearToDays) { - let res = ''; - for (i = 1; i <= yearToDays[year].length; i++) { - const link = `${i.toString().padStart(2, '0')}`; - res += i == day ? `${link}` : `${link}`; - } - return res; -} - -function escapeHtml(st) { - const map = { - '&': '&', - '<': '<', - '>': '>', - '"': '"', - "'": ''' - }; - return st.replace(/[&<>"']/g, (char) => map[char]); -} - -const template = loadTemplate('docs/template.html'); -const redirectTemplate = loadTemplate('docs/redirect_template.html') - -const yearToDays = {}; -for (const { year, day } of findReadmes('.')) { - if (!yearToDays[year]) { - yearToDays[year] = []; - } - yearToDays[year].push(day); -} - -for(const year of Object.keys(yearToDays)){ - yearToDays[year] = yearToDays[year].sort((a,b) => a-b); -} - -const lastYear = Math.max(...Object.keys(yearToDays)) -const lastDay = Math.max(...yearToDays[lastYear]); - -copyDirectory('docs/static', 'build'); - -const filledRedirectTemplate = fillTemplate(redirectTemplate, { - 'default-page': `/${lastYear}/${lastDay}/`, -}); - -fs.writeFileSync(path.join('build', 'index.html'), filledRedirectTemplate); - -const currentYear = new Date().getFullYear(); -// Iterate over readme.md files and print filled templates -for (const { year, day, name, notes, code, illustration, media } of findReadmes('.')) { - const filledHtml = fillTemplate(template, { - url: `https://aoc.csokavar.hu/${year}/${day}/`, - 'problem-id': `${year}/${day}`, - 'problem-name': `${name}`, - 'year-picker': generateYearPicker(year,day, yearToDays), - 'day-picker': generateDayPicker(year, day, yearToDays), - 'current-year': `${currentYear}`, - notes, - code: escapeHtml(code), - }); - const dst = `build/${year}/${day}`; - fs.mkdirSync(dst, { recursive: true }); - fs.writeFileSync(path.join(dst, 'index.html'), filledHtml); - fs.copyFileSync(illustration, path.join(dst, 'illustration.jpeg')); - for(let file of media) { - fs.copyFileSync(file, path.join(dst, path.basename(file))); - } -} - diff --git a/docs/elf.jpeg b/docs/elf.jpeg deleted file mode 100644 index d61c3abb0..000000000 Binary files a/docs/elf.jpeg and /dev/null differ diff --git a/docs/package-lock.json b/docs/package-lock.json deleted file mode 100644 index a398ad371..000000000 --- a/docs/package-lock.json +++ /dev/null @@ -1,28 +0,0 @@ -{ - "name": "docs", - "version": "1.0.0", - "lockfileVersion": 3, - "requires": true, - "packages": { - "": { - "name": "docs", - "version": "1.0.0", - "license": "ISC", - "dependencies": { - "marked": "^15.0.3" - } - }, - "node_modules/marked": { - "version": "15.0.3", - "resolved": "https://registry.npmjs.org/marked/-/marked-15.0.3.tgz", - "integrity": "sha512-Ai0cepvl2NHnTcO9jYDtcOEtVBNVYR31XnEA3BndO7f5As1wzpcOceSUM8FDkNLJNIODcLpDTWay/qQhqbuMvg==", - "license": "MIT", - "bin": { - "marked": "bin/marked.js" - }, - "engines": { - "node": ">= 18" - } - } - } -} diff --git a/docs/package.json b/docs/package.json deleted file mode 100644 index d90559306..000000000 --- a/docs/package.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "name": "docs", - "version": "1.0.0", - "main": "build.js", - "scripts": { - "test": "echo \"Error: no test specified\" && exit 1" - }, - "author": "", - "license": "ISC", - "description": "", - "dependencies": { - "marked": "^15.0.3" - } -} diff --git a/docs/redirect_template.html b/docs/redirect_template.html deleted file mode 100644 index cc99add5e..000000000 --- a/docs/redirect_template.html +++ /dev/null @@ -1,10 +0,0 @@ - - - diff --git a/docs/static/404.html b/docs/static/404.html deleted file mode 100644 index 9c931b102..000000000 --- a/docs/static/404.html +++ /dev/null @@ -1,2 +0,0 @@ - - diff --git a/docs/static/CNAME b/docs/static/CNAME deleted file mode 100644 index dfac70bb5..000000000 --- a/docs/static/CNAME +++ /dev/null @@ -1 +0,0 @@ -aoc.csokavar.hu \ No newline at end of file diff --git a/docs/static/android-chrome-192x192.png b/docs/static/android-chrome-192x192.png deleted file mode 100644 index 00444eee3..000000000 Binary files a/docs/static/android-chrome-192x192.png and /dev/null differ diff --git a/docs/static/android-chrome-512x512.png b/docs/static/android-chrome-512x512.png deleted file mode 100644 index ac878c39a..000000000 Binary files a/docs/static/android-chrome-512x512.png and /dev/null differ diff --git a/docs/static/apple-touch-icon.png b/docs/static/apple-touch-icon.png deleted file mode 100644 index bf6729c6a..000000000 Binary files a/docs/static/apple-touch-icon.png and /dev/null differ diff --git a/docs/static/browserconfig.xml b/docs/static/browserconfig.xml deleted file mode 100644 index b3930d0f0..000000000 --- a/docs/static/browserconfig.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - #da532c - - - diff --git a/docs/static/favicon-16x16.png b/docs/static/favicon-16x16.png deleted file mode 100644 index ca6fbddd6..000000000 Binary files a/docs/static/favicon-16x16.png and /dev/null differ diff --git a/docs/static/favicon-32x32.png b/docs/static/favicon-32x32.png deleted file mode 100644 index d4fac82eb..000000000 Binary files a/docs/static/favicon-32x32.png and /dev/null differ diff --git a/docs/static/favicon.ico b/docs/static/favicon.ico deleted file mode 100644 index 70d3d947b..000000000 Binary files a/docs/static/favicon.ico and /dev/null differ diff --git a/docs/static/mstile-150x150.png b/docs/static/mstile-150x150.png deleted file mode 100644 index f1d02c0d4..000000000 Binary files a/docs/static/mstile-150x150.png and /dev/null differ diff --git a/docs/static/safari-pinned-tab.svg b/docs/static/safari-pinned-tab.svg deleted file mode 100644 index 46cebff23..000000000 --- a/docs/static/safari-pinned-tab.svg +++ /dev/null @@ -1,110 +0,0 @@ - - - - -Created by potrace 1.14, written by Peter Selinger 2001-2017 - - - - - - - - - - diff --git a/docs/static/site.webmanifest b/docs/static/site.webmanifest deleted file mode 100644 index b20abb7cb..000000000 --- a/docs/static/site.webmanifest +++ /dev/null @@ -1,19 +0,0 @@ -{ - "name": "", - "short_name": "", - "icons": [ - { - "src": "/android-chrome-192x192.png", - "sizes": "192x192", - "type": "image/png" - }, - { - "src": "/android-chrome-512x512.png", - "sizes": "512x512", - "type": "image/png" - } - ], - "theme_color": "#ffffff", - "background_color": "#ffffff", - "display": "standalone" -} diff --git a/docs/template.html b/docs/template.html deleted file mode 100644 index a512a3981..000000000 --- a/docs/template.html +++ /dev/null @@ -1,314 +0,0 @@ - - - - - - - - - - - - - - - - - - Advent of Code {{problem-id}} '{{problem-name}}'' in C# by encse - - - - - - - - - - - - - - -
-
{{year-picker}}
-
{{day-picker}}
-
-
-
-
- -
- -
-

Advent of Code

-

{{problem-id}}

-

{{problem-name}}

-

in C#

-

-

by encse

-
- -
- -
-
{{notes}}
-
{{code}}
-

Please ☆ my repo if you like it!

-
- -
-
- © {{current-year}} - Advent of Code is a registered trademark in the US - Images provided by Bing image creator -
- - - - - - - - \ No newline at end of file diff --git a/omnisharp.json b/omnisharp.json new file mode 100644 index 000000000..bbf2d9c5f --- /dev/null +++ b/omnisharp.json @@ -0,0 +1,23 @@ +{ + "FormattingOptions": { + "UseTabs": false, + "TabSize": 4, + "IndentationSize": 4, + "EnableEditorConfigSupport": false, + "NewLineForCatch": false, + "NewLineForClausesInQuery": false, + "NewLineForElse": false, + "NewLineForFinally": false, + "NewLineForMembersInAnonymousTypes": false, + "NewLineForMembersInObjectInit": false, + "NewLinesForBracesInAccessors": false, + "NewLinesForBracesInAnonymousMethods": false, + "NewLinesForBracesInAnonymousTypes": false, + "NewLinesForBracesInControlBlocks": false, + "NewLinesForBracesInLambdaExpressionBody": false, + "NewLinesForBracesInMethods": false, + "NewLinesForBracesInObjectCollectionArrayInitializers": false, + "NewLinesForBracesInProperties": false, + "NewLinesForBracesInTypes": false + } +} \ No newline at end of file