advent_of_ruby 0.3.5 → 0.4.0

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.
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
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ef827ae7d7d476a5cf69ba40c6c437225c413fddf45a619315e82b5b4afeef5b
4
- data.tar.gz: 0dc97c1311bd52c88912fbd00d23f54166f9fb5c76f01cde07cc49d02f1ae2f9
3
+ metadata.gz: f4db5ac03c4996b55be8989c0e5973f287c7be5fcbaeedefd4568350bc5a29f4
4
+ data.tar.gz: 05a6d94d750592b970bec93e67c44414b27cff73775d85bb2be8018bcd416707
5
5
  SHA512:
6
- metadata.gz: 12bf51e1a30e704ff8799d0e69d86c623acecd1aeb17d260842c936f0a3e899dae2bae52df7b6e6709c4af3bf48f4258d883aad7eced150e3259838b9cdf8d33
7
- data.tar.gz: 2eec5db6f2e168adc267385021d3fa130972c360a682b15d16d4b6c6deec9d7c25db37f77f71c95d6d289a18e097a16f7416498c1ff534c04731a204129283d0
6
+ metadata.gz: 0d62b25bbee82bc6bf42c625efd88d4eec2e5347bdc974abba9b2f40408be0993c677f2d2cd777af5c3c58ffe61ad5e3297f408283e4d330fdd9fca59c2fbff5
7
+ data.tar.gz: 4f823f1ed17fd5e798a5cf04d2a6996a16b63a600ebc6f414b1d52b1ec2eaae8e904ad1d60af9c5455105e45c732c2fa876d8f3d2c25556237a35f13bea9879d
@@ -0,0 +1 @@
1
+ --- []
@@ -0,0 +1,7 @@
1
+ ---
2
+ - :name: 01.rb
3
+ :url: https://github.com/ZogStriP/adventofcode/blob/main/2024
4
+ :solution: |-
5
+ a, b = $<.map { _1.split.map &:to_i }.transpose.map &:sort
6
+ p a.zip(b).sum { (_1 - _2).abs }
7
+ p a.sum { _1 * b.count(_1) }
@@ -0,0 +1 @@
1
+ --- []
@@ -0,0 +1,9 @@
1
+ ---
2
+ - :name: 02.rb
3
+ :url: https://github.com/ZogStriP/adventofcode/blob/main/2024
4
+ :solution: |-
5
+ l = $<.map { _1.split.map &:to_i }
6
+ def diff(l) = l.each_cons(2).map { _1 - _2 }
7
+ def safe(l) = diff(l).all? { (1..3) === _1 } || diff(l).all? { (-3..-1) === _1 }
8
+ p l.count { safe _1 }
9
+ p l.count { |l| l.combination(l.size - 1).any? { safe _1 } }
@@ -0,0 +1 @@
1
+ --- []
@@ -0,0 +1,7 @@
1
+ ---
2
+ - :name: 03.rb
3
+ :url: https://github.com/ZogStriP/adventofcode/blob/main/2024
4
+ :solution: |-
5
+ c = $<.read
6
+ p c.scan(/mul\((\d+),(\d+)\)/).sum { _1.to_i * _2.to_i }
7
+ p c.scan(/(d)o\(\)|(d)on't\(\)|mul\((\d+),(\d+)\)/).sum { _1.._2 ? _3.to_i * _4.to_i : 0 }
@@ -0,0 +1 @@
1
+ --- []
@@ -0,0 +1,15 @@
1
+ ---
2
+ - :name: 04.rb
3
+ :url: https://github.com/ZogStriP/adventofcode/blob/main/2024
4
+ :solution: |-
5
+ M = *$<
6
+ Y, X = 0...M.size, 0...M[0].size
7
+ D = [*-1..1].product([*-1..1]) - [[0, 0]]
8
+
9
+ def m(y, x, dy, dx) = @t.all? { Y === y && M[y][x] == _1 && (y += dy; x += dx) } ? 1 : 0
10
+
11
+ @t = "XMAS".chars
12
+ p D.sum { |dy, dx| Y.sum { |y| X.sum { |x| m(y, x, dy, dx) } } }
13
+
14
+ @t = "MAS".chars
15
+ p Y.sum { |y| X.sum { |x| [-1, 1].sum { |dy| m(y - dy, x - dy, dy, dy) } * [-1, 1].sum { |dx| m(y - dx, x + dx, dx, -dx) } } }
@@ -0,0 +1 @@
1
+ --- []
@@ -0,0 +1,16 @@
1
+ ---
2
+ - :name: 05.rb
3
+ :url: https://github.com/ZogStriP/adventofcode/blob/main/2024
4
+ :solution: |-
5
+ rules, pages = $<.read.split("\n\n").map &:split
6
+
7
+ R = {}
8
+ rules.map { a, b = _1.split ?|; (R[a] ||= []) << b }
9
+
10
+ y, n = pages
11
+ .map { _1.split ?, }
12
+ .partition { |p| (0...p.size).all? { (p[_1 + 1..] & R[p[_1]]).size == p.size - _1 - 1 } }
13
+
14
+ n.map! { _1.sort { |a, b| R[a].include?(b) ? -1 : R[b].include?(a) ? 1 : 0 } }
15
+
16
+ puts [y, n].map { |l| l.sum { _1[_1.size / 2].to_i } }
@@ -0,0 +1 @@
1
+ --- []
@@ -0,0 +1,38 @@
1
+ ---
2
+ - :name: 06.rb
3
+ :url: https://github.com/ZogStriP/adventofcode/blob/main/2024
4
+ :solution: |-
5
+ M = $<.map &:chop
6
+ Y, X = 0...M.size, 0...M[0].size
7
+
8
+ sy = sx = 0
9
+ Y.map { |y| X.map { |x| (sy = y; sx = x) if M[y][x][?^] } }
10
+
11
+ y, x, dy, dx, s = sy, sx, -1, 0, Set.new
12
+
13
+ while Y === y && X === x
14
+ s << [y, x]
15
+ dy, dx = dx, -dy while M[y + dy] && M[y + dy][x + dx] == ?#
16
+ y += dy; x += dx
17
+ end
18
+
19
+ p s.size
20
+
21
+ l = []
22
+
23
+ s.each { |yy, xx|
24
+ y, x, dy, dx, v = sy, sx, -1, 0, Set.new
25
+
26
+ loop {
27
+ break l << [y, x] if !v.add?([y, x, dy, dx])
28
+ ny, nx = y + dy, x + dx
29
+ break if !(Y === ny && X === nx)
30
+ if M[ny][nx][?#] || (ny == yy && nx == xx)
31
+ dy, dx = dx, -dy
32
+ else
33
+ y, x = ny, nx
34
+ end
35
+ }
36
+ }
37
+
38
+ p (l - [[sy, sx]]).size
@@ -0,0 +1 @@
1
+ --- []
@@ -0,0 +1,9 @@
1
+ ---
2
+ - :name: 07.rb
3
+ :url: https://github.com/ZogStriP/adventofcode/blob/main/2024
4
+ :solution: |-
5
+ E = $<.map { _1.scan(/\d+/).map &:to_i }
6
+ def s(n, i = 1, acc = 0) = acc > n[0] || i == n.size ? acc == n[0] : s(n, i + 1, acc * n[i]) || s(n, i + 1, acc + n[i])
7
+ def t(n, i = 1, acc = 0) = acc > n[0] || i == n.size ? acc == n[0] : t(n, i + 1, acc * n[i]) || t(n, i + 1, acc + n[i]) || t(n, i + 1, "#{acc}#{n[i]}".to_i)
8
+ p E.sum { s(_1) ? _1[0] : 0 }
9
+ p E.sum { t(_1) ? _1[0] : 0 }
@@ -0,0 +1 @@
1
+ --- []
@@ -0,0 +1,27 @@
1
+ ---
2
+ - :name: '08.rb'
3
+ :url: https://github.com/ZogStriP/adventofcode/blob/main/2024
4
+ :solution: |-
5
+ M = $<.map &:chop
6
+ Y, X = 0...M.size, 0...M[0].size
7
+
8
+ N = {}
9
+ Y.map { |y|
10
+ X.map { |x|
11
+ (N[M[y][x]] ||= []) << y + x * 1i if M[y][x] != ?.
12
+ }
13
+ }
14
+
15
+ A = Set.new
16
+ B = Set.new
17
+
18
+ N.each {
19
+ _2.permutation(2).each { |a, b|
20
+ 0.step { |s|
21
+ c = a - s * (b - a)
22
+ Y === c.real && X === c.imag ? (A << c if s == 1; B << c) : break
23
+ }
24
+ }
25
+ }
26
+
27
+ p A.size, B.size
@@ -0,0 +1 @@
1
+ --- []
@@ -0,0 +1 @@
1
+ --- []
@@ -0,0 +1 @@
1
+ --- []
@@ -0,0 +1 @@
1
+ --- []
@@ -0,0 +1 @@
1
+ --- []
@@ -0,0 +1 @@
1
+ --- []
@@ -0,0 +1 @@
1
+ --- []
@@ -0,0 +1 @@
1
+ --- []
@@ -0,0 +1 @@
1
+ --- []
@@ -0,0 +1 @@
1
+ --- []
@@ -0,0 +1 @@
1
+ --- []
@@ -0,0 +1 @@
1
+ --- []
@@ -0,0 +1 @@
1
+ --- []
@@ -0,0 +1 @@
1
+ --- []
@@ -0,0 +1 @@
1
+ --- []
@@ -0,0 +1 @@
1
+ --- []
@@ -0,0 +1 @@
1
+ --- []
@@ -0,0 +1 @@
1
+ --- []
@@ -0,0 +1 @@
1
+ --- []
@@ -0,0 +1 @@
1
+ --- []
@@ -0,0 +1 @@
1
+ --- []
@@ -0,0 +1 @@
1
+ --- []
@@ -0,0 +1 @@
1
+ --- []
@@ -0,0 +1 @@
1
+ --- []
@@ -0,0 +1 @@
1
+ --- []
@@ -0,0 +1 @@
1
+ --- []
@@ -0,0 +1 @@
1
+ --- []
@@ -0,0 +1 @@
1
+ --- []
@@ -0,0 +1 @@
1
+ --- []
@@ -0,0 +1 @@
1
+ --- []
@@ -0,0 +1 @@
1
+ --- []
@@ -0,0 +1 @@
1
+ --- []
@@ -0,0 +1 @@
1
+ --- []
@@ -0,0 +1 @@
1
+ --- []
@@ -0,0 +1 @@
1
+ --- []
@@ -0,0 +1 @@
1
+ --- []
@@ -0,0 +1 @@
1
+ --- []
@@ -0,0 +1 @@
1
+ --- []
@@ -0,0 +1 @@
1
+ --- []
@@ -0,0 +1 @@
1
+ --- []
@@ -0,0 +1 @@
1
+ --- []
@@ -0,0 +1 @@
1
+ --- []
@@ -0,0 +1 @@
1
+ --- []
@@ -0,0 +1 @@
1
+ --- []
@@ -0,0 +1 @@
1
+ --- []
@@ -0,0 +1 @@
1
+ --- []
@@ -0,0 +1 @@
1
+ --- []
@@ -0,0 +1 @@
1
+ --- []
@@ -0,0 +1 @@
1
+ --- []
@@ -0,0 +1 @@
1
+ --- []
@@ -0,0 +1 @@
1
+ --- []
@@ -0,0 +1 @@
1
+ --- []
@@ -0,0 +1 @@
1
+ --- []
@@ -0,0 +1 @@
1
+ --- []
@@ -0,0 +1 @@
1
+ --- []
@@ -0,0 +1 @@
1
+ --- []
@@ -0,0 +1 @@
1
+ --- []
@@ -0,0 +1 @@
1
+ --- []
@@ -0,0 +1,37 @@
1
+ ---
2
+ - :name: 01.rb
3
+ :url: https://github.com/ahorner/advent-of-code/blob/main/lib/2025
4
+ :solution: |-
5
+ START = 50
6
+ RANGE = 100
7
+
8
+ ROTATION_MATCHER = /([LR])(\d+)/
9
+ ROTATIONS = INPUT.split("\n").map do |line|
10
+ direction, steps = line.match(ROTATION_MATCHER).captures
11
+ [direction, steps.to_i]
12
+ end
13
+
14
+ def calculate_password(moves, click: false)
15
+ position = START
16
+ password = 0
17
+
18
+ moves.each do |(direction, steps)|
19
+ clicks = steps / RANGE +
20
+ ((direction == "L" && position != 0 && (position - (steps % RANGE)) <= 0) ? 1 : 0) +
21
+ ((direction == "R" && (position + (steps % RANGE)) >= RANGE) ? 1 : 0)
22
+
23
+ position += (direction == "L") ? -steps : steps
24
+ position %= RANGE
25
+
26
+ password += if click
27
+ clicks
28
+ else
29
+ (position == 0) ? 1 : 0
30
+ end
31
+ end
32
+
33
+ password
34
+ end
35
+
36
+ solve!("The password is:", calculate_password(ROTATIONS))
37
+ solve!("The password including clicks is:", calculate_password(ROTATIONS, click: true))
@@ -0,0 +1 @@
1
+ --- []
@@ -0,0 +1,41 @@
1
+ ---
2
+ - :name: 02.rb
3
+ :url: https://github.com/ahorner/advent-of-code/blob/main/lib/2025
4
+ :solution: |-
5
+ RANGES = INPUT.strip.split(",").map do |range|
6
+ range.split("-").map(&:to_i)
7
+ end
8
+
9
+ def repeats_at?(digits, size)
10
+ return false unless digits.length % size == 0
11
+
12
+ slices = digits.each_slice(size).to_a
13
+ slices.each_cons(2).all? { |a, b| a == b }
14
+ end
15
+
16
+ def repeats_once?(id)
17
+ digits = id.to_s.chars
18
+ return false unless digits.length.even?
19
+
20
+ repeats_at?(digits, digits.length / 2)
21
+ end
22
+
23
+ def repeats_any?(id)
24
+ digits = id.to_s.chars
25
+ midpoint = digits.length / 2
26
+
27
+ midpoint.downto(1).any? do |size|
28
+ repeats_at?(digits, size)
29
+ end
30
+ end
31
+
32
+ def sum_ids(ranges, &block)
33
+ ranges.sum do |(start_id, end_id)|
34
+ (start_id..end_id).sum do |id|
35
+ block.call(id) ? id : 0
36
+ end
37
+ end
38
+ end
39
+
40
+ solve!("The sum of invalid IDs is:", sum_ids(RANGES) { |id| repeats_once?(id) })
41
+ solve!("The sum of invalid IDs (with any sequence length) is:", sum_ids(RANGES) { |id| repeats_any?(id) })
@@ -0,0 +1 @@
1
+ --- []
@@ -0,0 +1,24 @@
1
+ ---
2
+ - :name: 03.rb
3
+ :url: https://github.com/ahorner/advent-of-code/blob/main/lib/2025
4
+ :solution: |-
5
+ BANKS = INPUT.split("\n").map { |bank| bank.chars.map(&:to_i) }
6
+
7
+ def joltage(bank, batteries: 2)
8
+ activations = []
9
+
10
+ loop do
11
+ remaining = batteries - activations.size
12
+ break if remaining <= 0
13
+
14
+ battery, index = bank[..-remaining].each_with_index.max_by(&:first)
15
+
16
+ bank = bank[(index + 1)..]
17
+ activations << battery
18
+ end
19
+
20
+ activations.join.to_i
21
+ end
22
+
23
+ solve!("The total output joltage for 2 batteries is:", BANKS.sum { |bank| joltage(bank) })
24
+ solve!("The total output joltage for 12 batteries is:", BANKS.sum { |bank| joltage(bank, batteries: 12) })
@@ -0,0 +1 @@
1
+ --- []
@@ -0,0 +1,39 @@
1
+ ---
2
+ - :name: 04.rb
3
+ :url: https://github.com/ahorner/advent-of-code/blob/main/lib/2025
4
+ :solution: |-
5
+ require "matrix"
6
+
7
+ MAP = INPUT.split("\n").each_with_index.each_with_object({}) do |(row, y), map|
8
+ row.chars.each_with_index do |cell, x|
9
+ map[Vector[x, y]] = cell
10
+ end
11
+ end
12
+
13
+ ADJACENCIES = (-1..1).to_a.product((-1..1).to_a).map { |dx, dy| Vector[dx, dy] } - [Vector[0, 0]]
14
+
15
+ def accessible_rolls(map)
16
+ map.select do |position, cell|
17
+ next false unless cell == "@"
18
+
19
+ neighboring_rolls = ADJACENCIES.count { |offset| map[offset + position] == "@" }
20
+ neighboring_rolls < 4
21
+ end
22
+ end
23
+
24
+ def clear(map)
25
+ removed = []
26
+
27
+ loop do
28
+ removable = accessible_rolls(map).keys
29
+ break if removable.empty?
30
+
31
+ map = map.except(*removable)
32
+ removed += removable
33
+ end
34
+
35
+ removed
36
+ end
37
+
38
+ solve!("The number of initially accessible rolls is:", accessible_rolls(MAP).size)
39
+ solve!("The total number of removable rolls is:", clear(MAP).size)
@@ -0,0 +1 @@
1
+ --- []
@@ -0,0 +1,48 @@
1
+ ---
2
+ - :name: 05.rb
3
+ :url: https://github.com/ahorner/advent-of-code/blob/main/lib/2025
4
+ :solution: |-
5
+ ranges, ingredients = input.split("\n\n")
6
+ ranges = ranges.split("\n").map do |line|
7
+ starts, ends = line.strip.split("-")
8
+ (starts.to_i..ends.to_i)
9
+ end
10
+
11
+ def condense_ranges(ranges)
12
+ remaining = ranges.dup.sort_by(&:begin)
13
+ condensed = []
14
+ current = remaining.shift
15
+
16
+ loop do
17
+ if remaining.empty?
18
+ condensed << current
19
+ break
20
+ end
21
+
22
+ condensable, remaining = remaining.partition do |range|
23
+ range.overlap?(current) || range.begin == current.end + 1
24
+ end
25
+
26
+ condensable.each do |range|
27
+ current = [current.begin, range.begin].min..[current.end, range.end].max
28
+ end
29
+
30
+ if condensable.empty?
31
+ condensed << current
32
+ current = remaining.shift
33
+ next
34
+ end
35
+ end
36
+
37
+ condensed
38
+ end
39
+
40
+ INGREDIENTS = ingredients.split("\n").map(&:to_i)
41
+ RANGES = condense_ranges(ranges)
42
+
43
+ def fresh?(ingredient)
44
+ RANGES.any? { |range| range.include?(ingredient) }
45
+ end
46
+
47
+ solve!("The number of fresh ingredients in the list is:", INGREDIENTS.count { |i| fresh?(i) })
48
+ solve!("The total number of fresh ingredients is:", RANGES.sum(&:size))
@@ -0,0 +1 @@
1
+ --- []
@@ -0,0 +1,44 @@
1
+ ---
2
+ - :name: 06.rb
3
+ :url: https://github.com/ahorner/advent-of-code/blob/main/lib/2025
4
+ :solution: |-
5
+ LINES = INPUT.split("\n")
6
+ PROBLEMS = LINES.map { |line| line.strip.split(/\s+/) }.transpose
7
+
8
+ def solve(problem)
9
+ numbers = problem[0..-2].map(&:to_i)
10
+ operator = problem[-1].to_sym
11
+ numbers.reduce(operator)
12
+ end
13
+
14
+ problem_totals = PROBLEMS.map { |problem| solve(problem) }
15
+ grand_total = problem_totals.sum
16
+
17
+ solve!("The grand total of problem solutions is:", grand_total)
18
+
19
+ def rtl_solve(lines)
20
+ maxy = lines.size
21
+ maxx = lines.max_by(&:size).size
22
+
23
+ total = 0
24
+ numbers = []
25
+ maxx.downto(0).each do |x|
26
+ number = ""
27
+ (0...maxy).each do |y|
28
+ case lines[y][x]
29
+ when /\d/
30
+ number << lines[y][x]
31
+ when "*", "+"
32
+ numbers << number.to_i
33
+ number = ""
34
+ total += numbers.reduce(lines[y][x].to_sym)
35
+ numbers = []
36
+ end
37
+ end
38
+ numbers << number.to_i unless number.empty?
39
+ end
40
+
41
+ total
42
+ end
43
+
44
+ solve!("The grand total (solving right-to-left) is:", rtl_solve(LINES))
@@ -0,0 +1 @@
1
+ --- []