advent_of_ruby 0.3.5 → 0.3.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of advent_of_ruby might be problematic. Click here for more details.

Files changed (212) hide show
  1. checksums.yaml +4 -4
  2. data/data/solutions/github/ZogStriP/2024/01_1.yml +1 -0
  3. data/data/solutions/github/ZogStriP/2024/01_2.yml +7 -0
  4. data/data/solutions/github/ZogStriP/2024/02_1.yml +1 -0
  5. data/data/solutions/github/ZogStriP/2024/02_2.yml +9 -0
  6. data/data/solutions/github/ZogStriP/2024/03_1.yml +1 -0
  7. data/data/solutions/github/ZogStriP/2024/03_2.yml +7 -0
  8. data/data/solutions/github/ZogStriP/2024/04_1.yml +1 -0
  9. data/data/solutions/github/ZogStriP/2024/04_2.yml +15 -0
  10. data/data/solutions/github/ZogStriP/2024/05_1.yml +1 -0
  11. data/data/solutions/github/ZogStriP/2024/05_2.yml +16 -0
  12. data/data/solutions/github/ZogStriP/2024/06_1.yml +1 -0
  13. data/data/solutions/github/ZogStriP/2024/06_2.yml +38 -0
  14. data/data/solutions/github/ZogStriP/2024/07_1.yml +1 -0
  15. data/data/solutions/github/ZogStriP/2024/07_2.yml +9 -0
  16. data/data/solutions/github/ZogStriP/2024/08_1.yml +1 -0
  17. data/data/solutions/github/ZogStriP/2024/08_2.yml +27 -0
  18. data/data/solutions/github/ZogStriP/2024/09_1.yml +1 -0
  19. data/data/solutions/github/ZogStriP/2024/09_2.yml +1 -0
  20. data/data/solutions/github/ZogStriP/2024/10_1.yml +1 -0
  21. data/data/solutions/github/ZogStriP/2024/10_2.yml +1 -0
  22. data/data/solutions/github/ZogStriP/2024/11_1.yml +1 -0
  23. data/data/solutions/github/ZogStriP/2024/11_2.yml +1 -0
  24. data/data/solutions/github/ZogStriP/2024/12_1.yml +1 -0
  25. data/data/solutions/github/ZogStriP/2024/12_2.yml +1 -0
  26. data/data/solutions/github/ZogStriP/2024/13_1.yml +1 -0
  27. data/data/solutions/github/ZogStriP/2024/13_2.yml +1 -0
  28. data/data/solutions/github/ZogStriP/2024/14_1.yml +1 -0
  29. data/data/solutions/github/ZogStriP/2024/14_2.yml +1 -0
  30. data/data/solutions/github/ZogStriP/2024/15_1.yml +1 -0
  31. data/data/solutions/github/ZogStriP/2024/15_2.yml +1 -0
  32. data/data/solutions/github/ZogStriP/2024/16_1.yml +1 -0
  33. data/data/solutions/github/ZogStriP/2024/16_2.yml +1 -0
  34. data/data/solutions/github/ZogStriP/2024/17_1.yml +1 -0
  35. data/data/solutions/github/ZogStriP/2024/17_2.yml +1 -0
  36. data/data/solutions/github/ZogStriP/2024/18_1.yml +1 -0
  37. data/data/solutions/github/ZogStriP/2024/18_2.yml +1 -0
  38. data/data/solutions/github/ZogStriP/2024/19_1.yml +1 -0
  39. data/data/solutions/github/ZogStriP/2024/19_2.yml +1 -0
  40. data/data/solutions/github/ZogStriP/2024/20_1.yml +1 -0
  41. data/data/solutions/github/ZogStriP/2024/20_2.yml +1 -0
  42. data/data/solutions/github/ZogStriP/2024/21_1.yml +1 -0
  43. data/data/solutions/github/ZogStriP/2024/21_2.yml +1 -0
  44. data/data/solutions/github/ZogStriP/2024/22_1.yml +1 -0
  45. data/data/solutions/github/ZogStriP/2024/22_2.yml +1 -0
  46. data/data/solutions/github/ZogStriP/2024/23_1.yml +1 -0
  47. data/data/solutions/github/ZogStriP/2024/23_2.yml +1 -0
  48. data/data/solutions/github/ZogStriP/2024/24_1.yml +1 -0
  49. data/data/solutions/github/ZogStriP/2024/24_2.yml +1 -0
  50. data/data/solutions/github/ZogStriP/2024/25_1.yml +1 -0
  51. data/data/solutions/github/ZogStriP/2025/01_1.yml +1 -0
  52. data/data/solutions/github/ZogStriP/2025/01_2.yml +1 -0
  53. data/data/solutions/github/ZogStriP/2025/02_1.yml +1 -0
  54. data/data/solutions/github/ZogStriP/2025/02_2.yml +1 -0
  55. data/data/solutions/github/ZogStriP/2025/03_1.yml +1 -0
  56. data/data/solutions/github/ZogStriP/2025/03_2.yml +1 -0
  57. data/data/solutions/github/ZogStriP/2025/04_1.yml +1 -0
  58. data/data/solutions/github/ZogStriP/2025/04_2.yml +1 -0
  59. data/data/solutions/github/ZogStriP/2025/05_1.yml +1 -0
  60. data/data/solutions/github/ZogStriP/2025/05_2.yml +1 -0
  61. data/data/solutions/github/ZogStriP/2025/06_1.yml +1 -0
  62. data/data/solutions/github/ZogStriP/2025/06_2.yml +1 -0
  63. data/data/solutions/github/ZogStriP/2025/07_1.yml +1 -0
  64. data/data/solutions/github/ZogStriP/2025/07_2.yml +1 -0
  65. data/data/solutions/github/ZogStriP/2025/08_1.yml +1 -0
  66. data/data/solutions/github/ZogStriP/2025/08_2.yml +1 -0
  67. data/data/solutions/github/ZogStriP/2025/09_1.yml +1 -0
  68. data/data/solutions/github/ZogStriP/2025/09_2.yml +1 -0
  69. data/data/solutions/github/ZogStriP/2025/10_1.yml +1 -0
  70. data/data/solutions/github/ZogStriP/2025/10_2.yml +1 -0
  71. data/data/solutions/github/ZogStriP/2025/11_1.yml +1 -0
  72. data/data/solutions/github/ZogStriP/2025/11_2.yml +1 -0
  73. data/data/solutions/github/ZogStriP/2025/12_1.yml +1 -0
  74. data/data/solutions/github/ZogStriP/2025/12_2.yml +1 -0
  75. data/data/solutions/github/ahorner/2025/01_1.yml +1 -0
  76. data/data/solutions/github/ahorner/2025/01_2.yml +37 -0
  77. data/data/solutions/github/ahorner/2025/02_1.yml +1 -0
  78. data/data/solutions/github/ahorner/2025/02_2.yml +41 -0
  79. data/data/solutions/github/ahorner/2025/03_1.yml +1 -0
  80. data/data/solutions/github/ahorner/2025/03_2.yml +24 -0
  81. data/data/solutions/github/ahorner/2025/04_1.yml +1 -0
  82. data/data/solutions/github/ahorner/2025/04_2.yml +39 -0
  83. data/data/solutions/github/ahorner/2025/05_1.yml +1 -0
  84. data/data/solutions/github/ahorner/2025/05_2.yml +48 -0
  85. data/data/solutions/github/ahorner/2025/06_1.yml +1 -0
  86. data/data/solutions/github/ahorner/2025/06_2.yml +44 -0
  87. data/data/solutions/github/ahorner/2025/07_1.yml +1 -0
  88. data/data/solutions/github/ahorner/2025/07_2.yml +56 -0
  89. data/data/solutions/github/ahorner/2025/08_1.yml +1 -0
  90. data/data/solutions/github/ahorner/2025/08_2.yml +59 -0
  91. data/data/solutions/github/ahorner/2025/09_1.yml +1 -0
  92. data/data/solutions/github/ahorner/2025/09_2.yml +101 -0
  93. data/data/solutions/github/ahorner/2025/10_1.yml +1 -0
  94. data/data/solutions/github/ahorner/2025/10_2.yml +72 -0
  95. data/data/solutions/github/ahorner/2025/11_1.yml +1 -0
  96. data/data/solutions/github/ahorner/2025/11_2.yml +45 -0
  97. data/data/solutions/github/ahorner/2025/12_1.yml +1 -0
  98. data/data/solutions/github/eregon/2025/01_1.yml +17 -0
  99. data/data/solutions/github/eregon/2025/01_2.yml +14 -0
  100. data/data/solutions/github/eregon/2025/02_1.yml +22 -0
  101. data/data/solutions/github/eregon/2025/02_2.yml +58 -0
  102. data/data/solutions/github/eregon/2025/03_1.yml +13 -0
  103. data/data/solutions/github/eregon/2025/03_2.yml +13 -0
  104. data/data/solutions/github/eregon/2025/04_1.yml +14 -0
  105. data/data/solutions/github/eregon/2025/04_2.yml +16 -0
  106. data/data/solutions/github/eregon/2025/05_1.yml +1 -0
  107. data/data/solutions/github/eregon/2025/05_2.yml +1 -0
  108. data/data/solutions/github/eregon/2025/06_1.yml +1 -0
  109. data/data/solutions/github/eregon/2025/06_2.yml +1 -0
  110. data/data/solutions/github/eregon/2025/07_1.yml +1 -0
  111. data/data/solutions/github/eregon/2025/07_2.yml +1 -0
  112. data/data/solutions/github/eregon/2025/08_1.yml +1 -0
  113. data/data/solutions/github/eregon/2025/08_2.yml +1 -0
  114. data/data/solutions/github/eregon/2025/09_1.yml +1 -0
  115. data/data/solutions/github/eregon/2025/09_2.yml +1 -0
  116. data/data/solutions/github/eregon/2025/10_1.yml +1 -0
  117. data/data/solutions/github/eregon/2025/10_2.yml +1 -0
  118. data/data/solutions/github/eregon/2025/11_1.yml +1 -0
  119. data/data/solutions/github/eregon/2025/11_2.yml +1 -0
  120. data/data/solutions/github/eregon/2025/12_1.yml +1 -0
  121. data/data/solutions/github/erikw/2025/01_1.yml +1 -0
  122. data/data/solutions/github/erikw/2025/01_2.yml +1 -0
  123. data/data/solutions/github/erikw/2025/02_1.yml +1 -0
  124. data/data/solutions/github/erikw/2025/02_2.yml +1 -0
  125. data/data/solutions/github/erikw/2025/03_1.yml +1 -0
  126. data/data/solutions/github/erikw/2025/03_2.yml +1 -0
  127. data/data/solutions/github/erikw/2025/04_1.yml +1 -0
  128. data/data/solutions/github/erikw/2025/04_2.yml +1 -0
  129. data/data/solutions/github/erikw/2025/05_1.yml +1 -0
  130. data/data/solutions/github/erikw/2025/05_2.yml +1 -0
  131. data/data/solutions/github/erikw/2025/06_1.yml +1 -0
  132. data/data/solutions/github/erikw/2025/06_2.yml +1 -0
  133. data/data/solutions/github/erikw/2025/07_1.yml +1 -0
  134. data/data/solutions/github/erikw/2025/07_2.yml +1 -0
  135. data/data/solutions/github/erikw/2025/08_1.yml +1 -0
  136. data/data/solutions/github/erikw/2025/08_2.yml +1 -0
  137. data/data/solutions/github/erikw/2025/09_1.yml +1 -0
  138. data/data/solutions/github/erikw/2025/09_2.yml +1 -0
  139. data/data/solutions/github/erikw/2025/10_1.yml +1 -0
  140. data/data/solutions/github/erikw/2025/10_2.yml +1 -0
  141. data/data/solutions/github/erikw/2025/11_1.yml +1 -0
  142. data/data/solutions/github/erikw/2025/11_2.yml +1 -0
  143. data/data/solutions/github/erikw/2025/12_1.yml +1 -0
  144. data/data/solutions/github/erikw/2025/12_2.yml +1 -0
  145. data/data/solutions/github/gchan/2025/01_1.yml +25 -0
  146. data/data/solutions/github/gchan/2025/01_2.yml +32 -0
  147. data/data/solutions/github/gchan/2025/02_1.yml +18 -0
  148. data/data/solutions/github/gchan/2025/02_2.yml +21 -0
  149. data/data/solutions/github/gchan/2025/03_1.yml +15 -0
  150. data/data/solutions/github/gchan/2025/03_2.yml +23 -0
  151. data/data/solutions/github/gchan/2025/04_1.yml +27 -0
  152. data/data/solutions/github/gchan/2025/04_2.yml +40 -0
  153. data/data/solutions/github/gchan/2025/05_1.yml +20 -0
  154. data/data/solutions/github/gchan/2025/05_2.yml +36 -0
  155. data/data/solutions/github/gchan/2025/06_1.yml +11 -0
  156. data/data/solutions/github/gchan/2025/06_2.yml +28 -0
  157. data/data/solutions/github/gchan/2025/07_1.yml +33 -0
  158. data/data/solutions/github/gchan/2025/07_2.yml +29 -0
  159. data/data/solutions/github/gchan/2025/08_1.yml +48 -0
  160. data/data/solutions/github/gchan/2025/08_2.yml +48 -0
  161. data/data/solutions/github/gchan/2025/09_1.yml +16 -0
  162. data/data/solutions/github/gchan/2025/09_2.yml +60 -0
  163. data/data/solutions/github/gchan/2025/10_1.yml +49 -0
  164. data/data/solutions/github/gchan/2025/10_2.yml +154 -0
  165. data/data/solutions/github/gchan/2025/11_1.yml +43 -0
  166. data/data/solutions/github/gchan/2025/11_2.yml +33 -0
  167. data/data/solutions/github/gchan/2025/12_1.yml +51 -0
  168. data/data/solutions/reddit/ruby/2017/06.yml +0 -2
  169. data/data/solutions/reddit/ruby/2020/02.yml +0 -1
  170. data/data/solutions/reddit/ruby/2024/02.yml +0 -1
  171. data/data/solutions/reddit/ruby/2025/01.yml +187 -0
  172. data/data/solutions/reddit/ruby/2025/02.yml +185 -0
  173. data/data/solutions/reddit/ruby/2025/03.yml +369 -0
  174. data/data/solutions/reddit/ruby/2025/04.yml +217 -0
  175. data/data/solutions/reddit/ruby/2025/05.yml +324 -0
  176. data/data/solutions/reddit/ruby/2025/06.yml +246 -0
  177. data/data/solutions/reddit/ruby/2025/07.yml +213 -0
  178. data/data/solutions/reddit/ruby/2025/08.yml +73 -0
  179. data/data/solutions/reddit/ruby/2025/09.yml +26 -0
  180. data/data/solutions/reddit/ruby/2025/10.yml +73 -0
  181. data/data/solutions/reddit/ruby/2025/11.yml +69 -0
  182. data/data/solutions/reddit/ruby/2025/12.yml +1 -0
  183. data/lib/arb/arb.rb +0 -5
  184. data/lib/arb/cli/bootstrap.rb +1 -1
  185. data/lib/arb/cli/commit.rb +1 -1
  186. data/lib/arb/cli/progress.rb +4 -8
  187. data/lib/arb/cli/run.rb +1 -1
  188. data/lib/arb/cli/shared/git.rb +3 -4
  189. data/lib/arb/cli/shared/year_day_validator.rb +3 -8
  190. data/lib/arb/files/spec.rb +2 -2
  191. data/lib/arb/util.rb +58 -0
  192. data/lib/arb/version.rb +1 -1
  193. metadata +184 -23
  194. data/lib/download_solutions/api/github/repos.rb +0 -54
  195. data/lib/download_solutions/api/github.rb +0 -164
  196. data/lib/download_solutions/api/reddit/add_missing_replies.rb +0 -43
  197. data/lib/download_solutions/api/reddit/clean_bodies.rb +0 -64
  198. data/lib/download_solutions/api/reddit/filter_by_language.rb +0 -32
  199. data/lib/download_solutions/api/reddit/get_initial_response.rb +0 -30
  200. data/lib/download_solutions/api/reddit/get_serial_comments.rb +0 -145
  201. data/lib/download_solutions/api/reddit/megathread_ids.rb +0 -19
  202. data/lib/download_solutions/api/reddit/params.rb +0 -40
  203. data/lib/download_solutions/api/reddit/reject_unwanted_replies.rb +0 -31
  204. data/lib/download_solutions/api/reddit/remove_ids.rb +0 -26
  205. data/lib/download_solutions/api/reddit/remove_language_tags.rb +0 -29
  206. data/lib/download_solutions/api/reddit.rb +0 -101
  207. data/lib/download_solutions/cli/cli/shared.rb +0 -35
  208. data/lib/download_solutions/cli/github.rb +0 -107
  209. data/lib/download_solutions/cli/reddit.rb +0 -64
  210. data/lib/download_solutions/download_solutions.rb +0 -18
  211. data/lib/download_solutions/reverse_markdown/converters/br.rb +0 -15
  212. data/lib/download_solutions/reverse_markdown/converters/pre.rb +0 -46
@@ -0,0 +1,25 @@
1
+ ---
2
+ - :name: day-01-part-1.rb
3
+ :url: https://github.com/gchan/advent-of-code-ruby/blob/main/2025/day-01
4
+ :solution: |-
5
+ rotations = input.split("\n")
6
+
7
+ position = 50
8
+ count_zero = 0
9
+
10
+ rotations.each do |rotation|
11
+ direction, distance = rotation.scan(/[LR]+|\d+/)
12
+ distance = distance.to_i
13
+
14
+ case direction
15
+ when "L"
16
+ position -= distance
17
+ when "R"
18
+ position += distance
19
+ end
20
+
21
+ position %= 100
22
+ count_zero += 1 if position == 0
23
+ end
24
+
25
+ puts count_zero
@@ -0,0 +1,32 @@
1
+ ---
2
+ - :name: day-01-part-2.rb
3
+ :url: https://github.com/gchan/advent-of-code-ruby/blob/main/2025/day-01
4
+ :solution: |-
5
+ rotations = input.split("\n")
6
+
7
+ position = 50
8
+ count_zero = 0
9
+
10
+ rotations.each do |rotation|
11
+ direction, distance = rotation.scan(/[LR]+|\d+/)
12
+ distance = distance.to_i
13
+
14
+ case direction
15
+ when "L"
16
+ if position == 0
17
+ count_zero += (distance / 100)
18
+ elsif distance >= position
19
+ count_zero += 1 + (distance - position) / 100
20
+ end
21
+
22
+ position -= distance
23
+ when "R"
24
+ count_zero += (position + distance) / 100
25
+
26
+ position += distance
27
+ end
28
+
29
+ position %= 100
30
+ end
31
+
32
+ puts count_zero
@@ -0,0 +1,18 @@
1
+ ---
2
+ - :name: day-02-part-1.rb
3
+ :url: https://github.com/gchan/advent-of-code-ruby/blob/main/2025/day-02
4
+ :solution: |-
5
+ ranges = input.split(?,)
6
+
7
+ ranges.sum { |range|
8
+ min, max = range.split(?-).map(&:to_i)
9
+
10
+ (min..max)
11
+ .select { |n|
12
+ str = n.to_s
13
+ mid = str.length / 2
14
+
15
+ str.length.even? && str[0...mid] == str[mid..-1]
16
+ }
17
+ .sum
18
+ }.tap { puts _1}
@@ -0,0 +1,21 @@
1
+ ---
2
+ - :name: day-02-part-2.rb
3
+ :url: https://github.com/gchan/advent-of-code-ruby/blob/main/2025/day-02
4
+ :solution: |-
5
+ ranges.sum { |range|
6
+ min, max = range.split(?-).map(&:to_i)
7
+
8
+ (min..max)
9
+ .select { |n|
10
+ str = n.to_s
11
+
12
+ length = str.length
13
+
14
+ (1...length)
15
+ .select { length % _1 == 0 }
16
+ .any? { |i|
17
+ str.match?(/\A(#{str[0...i]})+\z/)
18
+ }
19
+ }
20
+ .sum
21
+ }.tap { puts _1}
@@ -0,0 +1,15 @@
1
+ ---
2
+ - :name: day-03-part-1.rb
3
+ :url: https://github.com/gchan/advent-of-code-ruby/blob/main/2025/day-03
4
+ :solution: |-
5
+ banks = input.split("\n").map(&:chars).map { _1.map(&:to_i) }
6
+
7
+ banks.sum { |bank|
8
+ tens, idx = bank[0...-1]
9
+ .each.with_index
10
+ .max_by { |value, _idx| value }
11
+
12
+ ones = bank[(idx + 1)..-1].max
13
+
14
+ tens * 10 + ones
15
+ }.tap { puts _1 }
@@ -0,0 +1,23 @@
1
+ ---
2
+ - :name: day-03-part-2.rb
3
+ :url: https://github.com/gchan/advent-of-code-ruby/blob/main/2025/day-03
4
+ :solution: |-
5
+ banks = input.split("\n").map(&:chars).map { _1.map(&:to_i) }
6
+
7
+ banks.sum { |bank|
8
+ digits = []
9
+ target_digits = 12
10
+ idx = 0
11
+
12
+ while digits.size < target_digits
13
+ digit, rel_idx = bank[idx..(-target_digits + digits.size)]
14
+ .each.with_index
15
+ .max_by { |value, _idx| value }
16
+
17
+ idx += rel_idx + 1
18
+
19
+ digits << digit
20
+ end
21
+
22
+ digits.join.to_i
23
+ }.tap { puts _1 }
@@ -0,0 +1,27 @@
1
+ ---
2
+ - :name: day-04-part-1.rb
3
+ :url: https://github.com/gchan/advent-of-code-ruby/blob/main/2025/day-04
4
+ :solution: |-
5
+ grid = input.split("\n").map.map(&:chars)
6
+
7
+ count = 0
8
+
9
+ grid.each_with_index do |row, x|
10
+ row.each_with_index do |char, y|
11
+ next if char == ?.
12
+
13
+ neighbours = 0
14
+ (x - 1..x+ 1).each do |r|
15
+ (y - 1..y+ 1).each do |c|
16
+ next if r == x && c == y
17
+ next if r < 0 || r >= grid.length
18
+ next if c < 0 || c >= grid[0].length
19
+ neighbours += 1 if grid[r][c] != ?.
20
+ end
21
+ end
22
+
23
+ count += 1 if neighbours < 4
24
+ end
25
+ end
26
+
27
+ puts count
@@ -0,0 +1,40 @@
1
+ ---
2
+ - :name: day-04-part-2.rb
3
+ :url: https://github.com/gchan/advent-of-code-ruby/blob/main/2025/day-04
4
+ :solution: |-
5
+ grid = input.split("\n").map.map(&:chars)
6
+
7
+ to_remove = []
8
+ removed_count = 0
9
+ stop = false
10
+
11
+ while !stop
12
+ grid.each_with_index do |row, x|
13
+ row.each_with_index do |char, y|
14
+ next if char == ?.
15
+
16
+ neighbours = 0
17
+ (x - 1..x + 1).each do |r|
18
+ (y - 1..y + 1).each do |c|
19
+ next if r == x && c == y
20
+ next if r < 0 || r >= grid.length
21
+ next if c < 0 || c >= grid[0].length
22
+
23
+ neighbours += 1 if grid[r][c] != ?.
24
+ end
25
+ end
26
+
27
+ to_remove << [x, y] if neighbours < 4
28
+ end
29
+ end
30
+
31
+ to_remove.each do |x, y|
32
+ grid[x][y] = ?.
33
+ end
34
+
35
+ removed_count += to_remove.length
36
+ stop = to_remove.empty?
37
+ to_remove = []
38
+ end
39
+
40
+ puts removed_count
@@ -0,0 +1,20 @@
1
+ ---
2
+ - :name: day-05-part-1.rb
3
+ :url: https://github.com/gchan/advent-of-code-ruby/blob/main/2025/day-05
4
+ :solution: |-
5
+ ranges, ids = input.split("\n\n")
6
+
7
+ fresh = ranges
8
+ .each_line
9
+ .map { |line|
10
+ line
11
+ .split("-")
12
+ .map(&:to_i)
13
+ .then { Range.new(_1, _2) }
14
+ }
15
+
16
+ ids
17
+ .each_line
18
+ .map(&:to_i)
19
+ .count { |id| fresh.any? { |range| range.include?(id) } }
20
+ .tap { |count| puts count }
@@ -0,0 +1,36 @@
1
+ ---
2
+ - :name: day-05-part-2.rb
3
+ :url: https://github.com/gchan/advent-of-code-ruby/blob/main/2025/day-05
4
+ :solution: |-
5
+ ranges, ids = input.split("\n\n")
6
+
7
+ fresh = ranges
8
+ .each_line
9
+ .map { |line|
10
+ line
11
+ .split("-")
12
+ .map(&:to_i)
13
+ .then { Range.new(_1, _2) }
14
+ }
15
+ .sort_by(&:begin)
16
+
17
+ reduced_fresh = []
18
+
19
+ current = fresh.shift
20
+
21
+ while current
22
+ next_range = fresh.first
23
+
24
+ if next_range && current.end >= next_range.begin
25
+ current = Range.new(current.begin, [current.end, next_range.end].max)
26
+ fresh.shift
27
+ else
28
+ reduced_fresh << current
29
+ current = fresh.shift
30
+ end
31
+ end
32
+
33
+ reduced_fresh
34
+ .map { _1.end - _1.begin + 1 }
35
+ .sum
36
+ .tap { puts _1}
@@ -0,0 +1,11 @@
1
+ ---
2
+ - :name: day-06-part-1.rb
3
+ :url: https://github.com/gchan/advent-of-code-ruby/blob/main/2025/day-06
4
+ :solution: |-
5
+ input
6
+ .each_line
7
+ .map(&:split)
8
+ .transpose
9
+ .map { _1[0...-1].map(&:to_i).inject(_1[-1]) }
10
+ .sum
11
+ .tap { puts _1 }
@@ -0,0 +1,28 @@
1
+ ---
2
+ - :name: day-06-part-2.rb
3
+ :url: https://github.com/gchan/advent-of-code-ruby/blob/main/2025/day-06
4
+ :solution: |-
5
+ lines = input.each_line.to_a
6
+
7
+ lines.last.strip
8
+ .chars
9
+ .each_with_index
10
+ .select { |char, _idx| char != " " }
11
+ .map { _2 } # get indices of operators
12
+ .<<(lines.map(&:length).max)
13
+ .each_cons(2)
14
+ # Build ranges from the start of the current range to end of the previous
15
+ # range minus one (to account for space)
16
+ .map { _1..(_2 - 2) }
17
+ .map { |range|
18
+ lines[0...-1]
19
+ .map { _1[range] }
20
+ .map { _1.ljust(range.size, " ") }
21
+ .map(&:chars)
22
+ .transpose
23
+ .map(&:join)
24
+ .map(&:to_i)
25
+ .inject(lines.last[range.begin])
26
+ }
27
+ .sum
28
+ .tap { puts _1 }
@@ -0,0 +1,33 @@
1
+ ---
2
+ - :name: day-07-part-1.rb
3
+ :url: https://github.com/gchan/advent-of-code-ruby/blob/main/2025/day-07
4
+ :solution: |-
5
+ lines = input
6
+ .each_line
7
+ .each_slice(2) # skip every second line
8
+ .map(&:first)
9
+
10
+ beams = [
11
+ lines.first.index("S")
12
+ ]
13
+
14
+ splits = 0
15
+
16
+ lines[1..-1].each do |line|
17
+ new_beams = []
18
+
19
+ beams.each do |beam|
20
+ if line[beam] == ?^
21
+ splits += 1
22
+
23
+ new_beams << beam - 1
24
+ new_beams << beam + 1
25
+ else
26
+ new_beams << beam
27
+ end
28
+ end
29
+
30
+ beams = new_beams.uniq
31
+ end
32
+
33
+ puts splits
@@ -0,0 +1,29 @@
1
+ ---
2
+ - :name: day-07-part-2.rb
3
+ :url: https://github.com/gchan/advent-of-code-ruby/blob/main/2025/day-07
4
+ :solution: |-
5
+ lines = input
6
+ .each_line
7
+ .each_slice(2) # skip every second line
8
+ .map(&:first)
9
+
10
+ beams = {
11
+ lines.first.index("S") => 1
12
+ }
13
+
14
+ lines[1..-1].each do |line|
15
+ new_beams = Hash.new(0)
16
+
17
+ beams.each do |beam, count|
18
+ if line[beam] == ?^
19
+ new_beams[beam - 1] += count
20
+ new_beams[beam + 1] += count
21
+ else
22
+ new_beams[beam] += count
23
+ end
24
+ end
25
+
26
+ beams = new_beams
27
+ end
28
+
29
+ puts beams.values.sum
@@ -0,0 +1,48 @@
1
+ ---
2
+ - :name: day-08-part-1.rb
3
+ :url: https://github.com/gchan/advent-of-code-ruby/blob/main/2025/day-08
4
+ :solution: |-
5
+ boxes = input.split("\n")
6
+ .map { |line| line.split(?,).map(&:to_i) }
7
+
8
+ sets = []
9
+ set_lookup = {}
10
+
11
+ closest_pairs = boxes
12
+ .combination(2)
13
+ .sort_by { |box1, box2|
14
+ box1.zip(box2)
15
+ .map { |a, b| a - b }
16
+ .map { _1 * _1}
17
+ .sum
18
+ .**(0.5)
19
+ }
20
+
21
+ 1000.times do |i|
22
+ closest = closest_pairs.shift
23
+ box1, box2 = closest
24
+
25
+ if set_lookup[box1] && set_lookup[box2] && set_lookup[box1] == set_lookup[box2]
26
+ next
27
+ end
28
+
29
+ closest_sets = closest.map { |box| set_lookup[box] }.compact
30
+
31
+ if closest_sets.empty?
32
+ set = Set.new(closest)
33
+ sets << set
34
+ closest.each { set_lookup[_1] = set }
35
+ elsif closest_sets.size == 1
36
+ set = closest_sets.first
37
+ closest.each { |box| set.add(box); set_lookup[box] = set }
38
+ else # merge sets
39
+ set = Set.new
40
+ closest_sets.each { set.merge(_1) }
41
+ closest_sets.each { sets.delete(_1) }
42
+
43
+ set.each { |box| set_lookup[box] = set }
44
+ sets << set
45
+ end
46
+ end
47
+
48
+ puts sets.map(&:size).sort.last(3).reduce(:*)
@@ -0,0 +1,48 @@
1
+ ---
2
+ - :name: day-08-part-2.rb
3
+ :url: https://github.com/gchan/advent-of-code-ruby/blob/main/2025/day-08
4
+ :solution: |-
5
+ boxes = input.split("\n")
6
+ .map { |line| line.split(?,).map(&:to_i) }
7
+
8
+ sets = []
9
+ set_lookup = {}
10
+
11
+ closest_pairs = boxes
12
+ .combination(2)
13
+ .sort_by { |box1, box2|
14
+ box1.zip(box2)
15
+ .map { |a, b| a - b }
16
+ .map { _1 * _1}
17
+ .sum
18
+ .**(0.5)
19
+ }
20
+
21
+ while sets.map(&:size).sum < boxes.size
22
+ closest = closest_pairs.shift
23
+ box1, box2 = closest
24
+
25
+ if set_lookup[box1] && set_lookup[box2] && set_lookup[box1] == set_lookup[box2]
26
+ next
27
+ end
28
+
29
+ closest_sets = closest.map { |box| set_lookup[box] }.compact
30
+
31
+ if closest_sets.empty?
32
+ set = Set.new(closest)
33
+ sets << set
34
+ closest.each { set_lookup[_1] = set }
35
+ elsif closest_sets.size == 1
36
+ set = closest_sets.first
37
+ closest.each { |box| set.add(box); set_lookup[box] = set }
38
+ else # merge sets
39
+ set = Set.new
40
+ closest_sets.each { set.merge(_1) }
41
+ closest_sets.each { sets.delete(_1) }
42
+
43
+ set.each { |box| set_lookup[box] = set }
44
+ sets << set
45
+ end
46
+ end
47
+
48
+ puts box1[0] * box2[0]
@@ -0,0 +1,16 @@
1
+ ---
2
+ - :name: day-09-part-1.rb
3
+ :url: https://github.com/gchan/advent-of-code-ruby/blob/main/2025/day-09
4
+ :solution: |-
5
+ tiles = input
6
+ .split(/\n|,/)
7
+ .map(&:to_i)
8
+ .each_slice(2)
9
+ .to_a
10
+
11
+ tiles.combination(2).lazy
12
+ .map { |(x1, y1), (x2, y2)|
13
+ ((x1 - x2).abs + 1) * ((y1 - y2).abs + 1)
14
+ }
15
+ .max
16
+ .tap { puts _1 }
@@ -0,0 +1,60 @@
1
+ ---
2
+ - :name: day-09-part-2.rb
3
+ :url: https://github.com/gchan/advent-of-code-ruby/blob/main/2025/day-09
4
+ :solution: |-
5
+ tiles = input
6
+ .split(/\n|,/)
7
+ .map(&:to_i)
8
+ .each_slice(2)
9
+ .to_a
10
+
11
+ # Build compressed coordinate mapping
12
+ unique_xs = tiles.map(&:first).uniq.sort
13
+ unique_ys = tiles.map(&:last).uniq.sort
14
+
15
+ x_map = unique_xs.each_with_index.to_h
16
+ y_map = unique_ys.each_with_index.to_h
17
+
18
+ # Compressed tiles
19
+ compressed_tiles = tiles.map { |x, y| [x_map[x], y_map[y]] }
20
+
21
+ def build_edge_lookup(tiles, axis:)
22
+ other_axis = 1 - axis
23
+
24
+ tiles
25
+ .group_by { _1[axis] }
26
+ .values
27
+ .map(&:sort)
28
+ .flatten(1)
29
+ .each_slice(2)
30
+ .to_a
31
+ .group_by { _1.first[axis] }
32
+ .transform_values { _1.map { |pair| pair.map { |p| p[other_axis] } } }
33
+ end
34
+
35
+ vertical_edge_lookup = build_edge_lookup(compressed_tiles, axis: 0)
36
+ horizontal_edge_lookup = build_edge_lookup(compressed_tiles, axis: 1)
37
+
38
+ # Find max area rectangle without edges inside
39
+ def edges_inside?(range, lookup, c1, c2)
40
+ range.any? do |i|
41
+ lookup[i]&.any? { |e1, e2| (c1 >= e1 && c1 < e2) || (c2 > e1 && c2 <= e2) }
42
+ end
43
+ end
44
+
45
+ tiles.combination(2).lazy
46
+ .map { |(x1, y1), (x2, y2)|
47
+ area = ((x1 - x2).abs + 1) * ((y1 - y2).abs + 1)
48
+
49
+ cx1, cx2 = [x_map[x1], x_map[x2]].sort
50
+ cy1, cy2 = [y_map[y1], y_map[y2]].sort
51
+
52
+ [area, [cx1, cy1], [cx2, cy2]]
53
+ }
54
+ .reject { |_area, (cx1, cy1), (cx2, cy2)|
55
+ edges_inside?((cx1 + 1)...cx2, vertical_edge_lookup, cy1, cy2) ||
56
+ edges_inside?((cy1 + 1)...cy2, horizontal_edge_lookup, cx1, cx2)
57
+ }
58
+ .map(&:first)
59
+ .max
60
+ .tap { puts _1 }
@@ -0,0 +1,49 @@
1
+ ---
2
+ - :name: day-10-part-1.rb
3
+ :url: https://github.com/gchan/advent-of-code-ruby/blob/main/2025/day-10
4
+ :solution: |-
5
+ machines = input.split("\n").map { _1.split(/(?<=\]) | (?=\{)/) }
6
+ .map! { |lights, buttons, _joltage|
7
+ lights = lights.chars[1...-1].map { _1 == "#" ? 1 : 0 }
8
+
9
+ buttons = buttons
10
+ .scan(/
11
+ \( # Opening parenthesis
12
+ (\d[,\d+]*) # One or more digits separated by commas
13
+ \) # Closing parenthesis
14
+ /x)
15
+ .flatten
16
+ .map { _1.split(",").map(&:to_i) }
17
+
18
+ [lights, buttons]
19
+ }
20
+
21
+ machines
22
+ .map { |lights, buttons|
23
+ # BFS
24
+ queue = [[Array.new(lights.size, 0), 0]]
25
+ visited = Set.new
26
+
27
+ until queue.empty?
28
+ state, presses = queue.shift
29
+
30
+ next if visited.include?(state)
31
+ visited.add(state)
32
+
33
+ if state == lights
34
+ count = presses
35
+ break
36
+ end
37
+
38
+ buttons.each do |button|
39
+ new_state = state.dup
40
+ button.each { |pos| new_state[pos] ^= 1 }
41
+
42
+ queue << [new_state, presses + 1]
43
+ end
44
+ end
45
+
46
+ count
47
+ }
48
+ .sum
49
+ .tap { puts _1 }