cem 0.1.2 → 0.1.6

Sign up to get free protection for your applications and to get access to all the features.
Files changed (91) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +2 -1
  3. data/README.md +6 -18
  4. data/cem.gemspec +4 -3
  5. data/examples/aoc2018/.gitignore +2 -0
  6. data/examples/aoc2018/day1.rb +13 -0
  7. data/examples/aoc2018/day10.rb +61 -0
  8. data/examples/aoc2018/day11.rb +66 -0
  9. data/examples/aoc2018/day12.rb +61 -0
  10. data/examples/aoc2018/day13.rb +167 -0
  11. data/examples/aoc2018/day14.rb +31 -0
  12. data/examples/aoc2018/day14_2.rb +71 -0
  13. data/examples/aoc2018/day15.rb +271 -0
  14. data/examples/aoc2018/day16.rb +158 -0
  15. data/examples/aoc2018/day17.rb +203 -0
  16. data/examples/aoc2018/day18.rb +113 -0
  17. data/examples/aoc2018/day18_rspec.rb +131 -0
  18. data/examples/aoc2018/day19.rb +145 -0
  19. data/examples/aoc2018/day1_part2.rb +30 -0
  20. data/examples/aoc2018/day2.rb +20 -0
  21. data/examples/aoc2018/day20.rb +103 -0
  22. data/examples/aoc2018/day21.rb +158 -0
  23. data/examples/aoc2018/day21_v2.rb +137 -0
  24. data/examples/aoc2018/day21_v3.rb +157 -0
  25. data/examples/aoc2018/day21_v4.rb +141 -0
  26. data/examples/aoc2018/day22.rb +212 -0
  27. data/examples/aoc2018/day23.rb +148 -0
  28. data/examples/aoc2018/day24.rb +156 -0
  29. data/examples/aoc2018/day25.rb +52 -0
  30. data/examples/aoc2018/day2_2.rb +27 -0
  31. data/examples/aoc2018/day3.rb +71 -0
  32. data/examples/aoc2018/day4.rb +46 -0
  33. data/examples/aoc2018/day5.rb +23 -0
  34. data/examples/aoc2018/day5_part2.rb +29 -0
  35. data/examples/aoc2018/day6.rb +53 -0
  36. data/examples/aoc2018/day7.rb +110 -0
  37. data/examples/aoc2018/day8.rb +39 -0
  38. data/examples/aoc2018/day8_part2.rb +65 -0
  39. data/examples/aoc2018/day9.rb +51 -0
  40. data/examples/aoc2018/day9_circular.rb +125 -0
  41. data/examples/aoc2018/inputs/day10_input.txt +395 -0
  42. data/examples/aoc2018/inputs/day11_input.txt +1 -0
  43. data/examples/aoc2018/inputs/day12_input.txt +34 -0
  44. data/examples/aoc2018/inputs/day12_input2.txt +16 -0
  45. data/examples/aoc2018/inputs/day13_input.txt +150 -0
  46. data/examples/aoc2018/inputs/day13_test.txt +6 -0
  47. data/examples/aoc2018/inputs/day14_input.txt +1 -0
  48. data/examples/aoc2018/inputs/day15_input.txt +32 -0
  49. data/examples/aoc2018/inputs/day15_input10.txt +32 -0
  50. data/examples/aoc2018/inputs/day15_input11.txt +32 -0
  51. data/examples/aoc2018/inputs/day15_input12.txt +32 -0
  52. data/examples/aoc2018/inputs/day15_input13.txt +32 -0
  53. data/examples/aoc2018/inputs/day15_input14.txt +32 -0
  54. data/examples/aoc2018/inputs/day15_input2.txt +7 -0
  55. data/examples/aoc2018/inputs/day15_input3.txt +9 -0
  56. data/examples/aoc2018/inputs/day15_input4.txt +7 -0
  57. data/examples/aoc2018/inputs/day15_input5.txt +7 -0
  58. data/examples/aoc2018/inputs/day15_input6.txt +7 -0
  59. data/examples/aoc2018/inputs/day15_input7.txt +7 -0
  60. data/examples/aoc2018/inputs/day15_input8.txt +5 -0
  61. data/examples/aoc2018/inputs/day15_input9.txt +7 -0
  62. data/examples/aoc2018/inputs/day15_test.txt +9 -0
  63. data/examples/aoc2018/inputs/day16_input.txt +3865 -0
  64. data/examples/aoc2018/inputs/day17_input.txt +2229 -0
  65. data/examples/aoc2018/inputs/day17_input_test.txt +8 -0
  66. data/examples/aoc2018/inputs/day18_input.txt +50 -0
  67. data/examples/aoc2018/inputs/day18_test.txt +10 -0
  68. data/examples/aoc2018/inputs/day19_input.txt +48 -0
  69. data/examples/aoc2018/inputs/day1_input.txt +955 -0
  70. data/examples/aoc2018/inputs/day20_input.txt +1 -0
  71. data/examples/aoc2018/inputs/day21_input.txt +32 -0
  72. data/examples/aoc2018/inputs/day22_input.txt +2 -0
  73. data/examples/aoc2018/inputs/day23_input.txt +1000 -0
  74. data/examples/aoc2018/inputs/day23_input2.txt +9 -0
  75. data/examples/aoc2018/inputs/day24_input.txt +24 -0
  76. data/examples/aoc2018/inputs/day25_input.txt +1483 -0
  77. data/examples/aoc2018/inputs/day2_input.txt +250 -0
  78. data/examples/aoc2018/inputs/day3_input.txt +1233 -0
  79. data/examples/aoc2018/inputs/day4_input.txt +1140 -0
  80. data/examples/aoc2018/inputs/day5_input.txt +1 -0
  81. data/examples/aoc2018/inputs/day6_input.txt +50 -0
  82. data/examples/aoc2018/inputs/day7_input.txt +101 -0
  83. data/examples/aoc2018/inputs/day8_input.txt +1 -0
  84. data/examples/aoc2018/inputs/day9_input.txt +1 -0
  85. data/lib/cem/ccommon.rb +51 -6
  86. data/lib/cem/cflame/popen.rb +89 -0
  87. data/lib/cem/cflame.rb +2 -0
  88. data/lib/cem/cruzzles.rb +198 -50
  89. data/lib/cem/version.rb +1 -1
  90. data/lib/cem.rb +0 -6
  91. metadata +88 -22
data/lib/cem/cruzzles.rb CHANGED
@@ -7,10 +7,18 @@
7
7
  # - Some Numeric hackery
8
8
  #
9
9
 
10
- def min(a, b)
11
- return a <= b ? a : b
10
+ module Cem
11
+ def self.min(a, b)
12
+ return a <= b ? a : b
13
+ end
14
+
15
+ def self.max(a, b)
16
+ return a >= b ? a : b
17
+ end
12
18
  end
13
19
 
20
+ extend Cem
21
+
14
22
  class Numeric
15
23
  # Make all methods in Math module available as methods for numeric (e.g. 3.sqrt instead of Math.sqrt(3))
16
24
  Math.methods(false).each do |method|
@@ -37,6 +45,14 @@ Point2D = Struct.new("Point2D", :x, :y) {
37
45
  end
38
46
  end
39
47
 
48
+ def -(other)
49
+ if other.is_a? Array
50
+ other.map { |o| self - o }
51
+ else
52
+ Point2D.new(x - other.x, y - other.y)
53
+ end
54
+ end
55
+
40
56
  # Scalar multiplication
41
57
  def *(other)
42
58
  Point2D.new(x * other, y * other)
@@ -51,6 +67,10 @@ Point2D = Struct.new("Point2D", :x, :y) {
51
67
  return ((x - other.x) ** 2 + (y - other.y) ** 2).sqrt
52
68
  end
53
69
 
70
+ def area
71
+ return x * y
72
+ end
73
+
54
74
  def self.from_s(s)
55
75
 
56
76
  case s.upcase
@@ -67,30 +87,98 @@ Point2D = Struct.new("Point2D", :x, :y) {
67
87
  end
68
88
 
69
89
  end
90
+
91
+ # Returns the component-wise minimum as a new Point2D
92
+ #
93
+ # Point2D.new(5,2).min(Point2D.new(1,3)) == Point2D.new(1,2) -> true
94
+ #
95
+ def min(other)
96
+ return self if !other
97
+
98
+ if other.is_a? Array
99
+ other.reduce(self) { |min, o| min.min(o) }
100
+ else
101
+ Point2D.new(Cem.min(x, other.x), Cem.min(y, other.y))
102
+ end
103
+ end
104
+
105
+ # Returns the component-wise maximum as a new Point2D
106
+ #
107
+ # Point2D.new(5,2).min(Point2D.new(1,3)) == Point2D.new(5,3) -> true
108
+ #
109
+ def max(other)
110
+ return self if !other
111
+
112
+ if other.is_a? Array
113
+ other.reduce(self) { |max, o| max.max(o) }
114
+ else
115
+ Point2D.new(Cem.max(x, other.x), Cem.max(y, other.y))
116
+ end
117
+ end
118
+
119
+ # Returns the minimum and maximum coordinates of this and the given point/point array.
120
+ def minmax(other)
121
+ [self.min(other), self.max(other)]
122
+ end
123
+
124
+ # Returns the minimum and maximum coordinates of the point array.
125
+ def self.minmax(array)
126
+ return [nil, nil] if !array || array.size == 0
127
+
128
+ [array.reduce { |min, o| min.min(o) }, array.reduce { |max, o| max.max(o) } ]
129
+ end
130
+
131
+ def add!(other)
132
+ self.x += other.x
133
+ self.y += other.y
134
+ return self
135
+ end
70
136
 
71
137
  def left
72
- return self + Dir2D.LEFT
138
+ self + Dir2D::LEFT
73
139
  end
74
140
 
75
141
  def left!
76
- x += Dir2D.LEFT.x
77
- y += Dir2D.LEFT.y
78
- return self
142
+ add!(Dir2D::LEFT)
79
143
  end
80
144
 
145
+ def right
146
+ self + Dir2D::RIGHT
147
+ end
81
148
 
149
+ def right!
150
+ add!(Dir2D::RIGHT)
151
+ end
152
+
153
+ def up
154
+ self + Dir2D::UP
155
+ end
156
+
157
+ def up!
158
+ add!(Dir2D::UP)
159
+ end
160
+
161
+ def down
162
+ self + Dir2D::DOWN
163
+ end
164
+
165
+ def down!
166
+ add!(Dir2D::DOWN)
167
+ end
168
+
82
169
  def to_dir_bitmask
83
170
 
84
- if x == 0 && y == -1
171
+ case self
172
+ when Dir2D::N
85
173
  return 1
86
- elsif x == 1 && y == 0
174
+ when Dir2D::E
87
175
  return 2
88
- elsif x == 0 && y == 1
176
+ when Dir2D::S
89
177
  return 4
90
- elsif x == -1 && y == 0
178
+ when Dir2D::W
91
179
  return 8
92
180
  else
93
- raise self.p
181
+ raise "Only Dir2Ds can be converted to direction bitmask: #{self.inspect}"
94
182
  end
95
183
  end
96
184
 
@@ -98,25 +186,26 @@ Point2D = Struct.new("Point2D", :x, :y) {
98
186
 
99
187
  result = []
100
188
  if v & 1 > 0
101
- result << Point2D.new(0, -1)
189
+ result << Dir2D::N
102
190
  end
103
191
  if v & 2 > 0
104
- result << Point2D.new(1, 0)
192
+ result << Dir2D::E
105
193
  end
106
194
  if v & 4 > 0
107
- result << Point2D.new(0, 1)
195
+ result << Dir2D::S
108
196
  end
109
197
  if v & 8 > 0
110
- result << Point2D.new(-1, 0)
198
+ result << Dir2D::W
111
199
  end
112
200
  return result
113
201
  end
114
202
 
115
- # def <=>(other)
116
- # y == other.y ? x <=> other.x : y <=> other.y
117
- # end
203
+ def <=>(other)
204
+ y == other.y ? x <=> other.x : y <=> other.y
205
+ end
118
206
 
119
207
  def ==(other)
208
+ return false if !other.respond_to?(:x) || !other.respond_to?(:y)
120
209
  y == other.y && x == other.x
121
210
  end
122
211
  }
@@ -144,14 +233,14 @@ Seg2D = Struct.new("Seg2D", :p1, :p2) {
144
233
 
145
234
  }
146
235
 
147
- Dirs2D = [Point2D.new(0, -1), Point2D.new(1, 0), Point2D.new(0, 1), Point2D.new(-1, 0)]
148
-
149
236
  class Dir2D < Point2D
150
237
 
151
- N = UP = Dir2D.new( 0, -1)
152
- E = RIGHT = Dir2D.new( 1, 0)
153
- S = DOWN = Dir2D.new( 0, 1)
154
- W = LEFT = Dir2D.new(-1, 0)
238
+ N = UP = Dir2D.new( 0, -1).freeze
239
+ E = RIGHT = Dir2D.new( 1, 0).freeze
240
+ S = DOWN = Dir2D.new( 0, 1).freeze
241
+ W = LEFT = Dir2D.new(-1, 0).freeze
242
+
243
+ All = [N, E, S, W]
155
244
 
156
245
  #
157
246
  # Dir2D * Range = array of Dir2D
@@ -176,13 +265,13 @@ class Dir2D < Point2D
176
265
  def self.x(length=1)
177
266
  return vert(length) + hori(length)
178
267
  end
179
-
180
268
  end
181
-
269
+
270
+ Dirs2D = Dir2D::All
182
271
 
183
272
  class Grid
184
273
 
185
- attr_reader :data
274
+ attr_accessor :data
186
275
 
187
276
  def initialize(x, y, default=0, &block)
188
277
 
@@ -223,7 +312,7 @@ class Grid
223
312
  # @data = [[default] * x] * y
224
313
  end
225
314
  end
226
-
315
+
227
316
  def initialize_copy(orig)
228
317
  super
229
318
 
@@ -231,6 +320,43 @@ class Grid
231
320
  # Do custom initialization for self
232
321
  end
233
322
 
323
+ #
324
+ # Given a list of Point2D, will create a Grid that contains all points.
325
+ #
326
+ # By default the grid will be recentered using the 'bottomleft'-most point.
327
+ # Set :bounding_box to false to get coordinates transferred as is.
328
+ #
329
+ # By default all cells for which points are found are marked with an 'x'.
330
+ # Set :char to another character or supply a block which receives the point and should return the character to use.
331
+ #
332
+ # By default the empty cells are filled with spaces. Set :empty to something else to change this.
333
+ #
334
+ def self.from_points(point_array, bounding_box=true, char='x', empty=' ', &block)
335
+
336
+ min, max = Point2D.minmax(point_array)
337
+ if !bounding_box
338
+ min = Point2D.new(0,0)
339
+ end
340
+
341
+ result = Grid.new(max.x - min.x + 1, max.y - min.y + 1, empty)
342
+
343
+ point_array.each { |p|
344
+ result[p-min] = if block
345
+ block.call(p)
346
+ else
347
+ char
348
+ end
349
+ }
350
+
351
+ return result
352
+ end
353
+
354
+ # Mixin all methods which make sense:
355
+ # - Searching if all/any/none/one value matches something
356
+ append_from(Enumerable, :any?, :all?, :include?, :member?, :none?, :one?, :tally, :count)
357
+
358
+
359
+ # Finds the top-left (min), bottom-right (max) coordinates of this Grid using the given value 'null' as an indicator for an empty field.
234
360
  def minmax(null=nil)
235
361
  min = nil
236
362
  max = nil
@@ -282,10 +408,11 @@ class Grid
282
408
  return @data[y][x] = assign
283
409
  end
284
410
 
285
- def to_a
411
+ # Returns the underlying 2D array as a flattened array
412
+ def flatten
286
413
  return @data.flatten
287
- end
288
-
414
+ end
415
+
289
416
  #
290
417
  # Returns the Point2Ds in the directions NSEW as an array (no diagonals, see adja_index for this)
291
418
  #
@@ -345,7 +472,7 @@ class Grid
345
472
  result << Point2D.new(x-1,y-1)
346
473
  end
347
474
  result << Point2D.new(x-1,y)
348
- if y + 1 < @data.size - 1
475
+ if y + 1 < @data.size
349
476
  result << Point2D.new(x-1, y+1)
350
477
  end
351
478
  end
@@ -355,15 +482,15 @@ class Grid
355
482
 
356
483
  # result << Point2D.new(x,y)
357
484
 
358
- if y + 1 < @data.size - 1
485
+ if y + 1 < @data.size
359
486
  result << Point2D.new(x, y+1)
360
487
  end
361
- if x + 1 < @data[0].size - 1
488
+ if x + 1 < @data[0].size
362
489
  if y > 0
363
490
  result << Point2D.new(x+1,y-1)
364
491
  end
365
492
  result << Point2D.new(x+1,y)
366
- if y + 1 < @data.size - 1
493
+ if y + 1 < @data.size
367
494
  result << Point2D.new(x+1, y+1)
368
495
  end
369
496
  end
@@ -373,15 +500,14 @@ class Grid
373
500
  def to_s
374
501
  printBoard()
375
502
  end
376
-
377
-
378
- #
503
+
379
504
  # returns a copy of the underlying 2D array, with linking to the content (rather than dup the content also)
380
- #
381
505
  def to_a
382
506
  @data.map { |row| row.dup }
383
507
  end
384
508
 
509
+ # Returns access to the underlying 2D array.
510
+ # Caution: This is not a duplicate. Use to_a for this.
385
511
  def data
386
512
  @data
387
513
  end
@@ -391,24 +517,30 @@ class Grid
391
517
  #
392
518
  # If block has...
393
519
  # - one parameter, passes the cell value
394
- # - two parameters, passes y and x
520
+ # - two parameters, passes the coordinates as a Point2D and the cell value
395
521
  # - three parameteres, passes y, x and the cell value
396
522
  #
523
+ # If the block returns nil, the original value is kept.
524
+ #
397
525
  def map_a(&block)
398
526
 
399
527
  case block.arity
400
528
  when 1
401
- @data.map { |row| row.map { |value| block.call(value) } }
529
+ @data.map { |row| row.map { |value| block.call(value) || value } }
402
530
  when 2
403
- @data.each_with_index.map { |row, y| row.each_index.map { |x| block.call(y,x) } }
531
+ @data.each_with_index.map { |row, y| row.each_with_index.map { |value, x| block.call(Point2D.new(x, y), value) || value } }
404
532
  when 3
405
- @data.each_with_index.map { |row, y| row.each_with_index.map { |cell, x| block.call(y,x,cell) } }
533
+ @data.each_with_index.map { |row, y| row.each_with_index.map { |value, x| block.call(y, x, value) || value} }
406
534
  else
407
535
  raise
408
536
  end
409
537
 
410
538
  end
411
539
 
540
+ def map_a!(&block)
541
+ @data = map_a(&block)
542
+ end
543
+
412
544
  def each(&block)
413
545
  @data.each { |row|
414
546
  row.each { |cell|
@@ -451,10 +583,12 @@ class Grid
451
583
  @data.each_with_index { |l, y|
452
584
  l.each_with_index { |c, x|
453
585
 
454
- pos = Point2D.new(x,y)
455
-
456
- if overlay && overlay.has_key?(pos)
457
- result += overlay[pos]
586
+ if overlay
587
+ pos = Point2D.new(x,y)
588
+ if overlay.has_key?(pos)
589
+ result += overlay[pos]
590
+ end
591
+ next
458
592
  else
459
593
  result += c.to_s
460
594
  end
@@ -510,7 +644,21 @@ Point3D = Struct.new("Point3D", :x, :y, :z) {
510
644
  end
511
645
  end
512
646
  }
513
-
514
-
515
647
 
516
-
648
+ Point4D = Struct.new("Point4D", :x, :y, :z, :w) {
649
+
650
+ def manhattan(other=nil)
651
+ if other != nil
652
+ return (self - other).manhattan
653
+ end
654
+ return x.abs + y.abs + z.abs + w.abs
655
+ end
656
+
657
+ def -(other)
658
+ Point4D.new(x - other.x, y - other.y, z - other.z, w - other.w)
659
+ end
660
+
661
+ def to_s
662
+ "#{x}, #{y}, #{z}, #{w}"
663
+ end
664
+ }
data/lib/cem/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Cem
2
- VERSION = "0.1.2"
2
+ VERSION = "0.1.6"
3
3
  end
data/lib/cem.rb CHANGED
@@ -1,10 +1,4 @@
1
1
 
2
2
  require "cem/version"
3
3
  require "cem/ccommon"
4
- require "cem/cflame"
5
4
  require "cem/cruzzles"
6
-
7
- module Cem
8
- class Error < StandardError; end
9
- # Your code goes here...
10
- end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cem
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.2
4
+ version: 0.1.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - Christopher Özbek
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-06-10 00:00:00.000000000 Z
11
+ date: 2021-12-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -16,28 +16,28 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: '1.17'
19
+ version: '2.1'
20
20
  type: :development
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: '1.17'
26
+ version: '2.1'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: rake
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: '10.0'
33
+ version: '13.0'
34
34
  type: :development
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: '10.0'
40
+ version: '13.0'
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: rspec
43
43
  requirement: !ruby/object:Gem::Requirement
@@ -52,20 +52,6 @@ dependencies:
52
52
  - - "~>"
53
53
  - !ruby/object:Gem::Version
54
54
  version: '3.0'
55
- - !ruby/object:Gem::Dependency
56
- name: flammarion
57
- requirement: !ruby/object:Gem::Requirement
58
- requirements:
59
- - - "~>"
60
- - !ruby/object:Gem::Version
61
- version: '0.3'
62
- type: :runtime
63
- prerelease: false
64
- version_requirements: !ruby/object:Gem::Requirement
65
- requirements:
66
- - - "~>"
67
- - !ruby/object:Gem::Version
68
- version: '0.3'
69
55
  description: Christopher's Gem = My little helpers which I use in many projects.
70
56
  email:
71
57
  - christopher@oezbek.org
@@ -83,12 +69,93 @@ files:
83
69
  - bin/console
84
70
  - bin/setup
85
71
  - cem.gemspec
72
+ - examples/aoc2018/.gitignore
73
+ - examples/aoc2018/day1.rb
74
+ - examples/aoc2018/day10.rb
75
+ - examples/aoc2018/day11.rb
76
+ - examples/aoc2018/day12.rb
77
+ - examples/aoc2018/day13.rb
78
+ - examples/aoc2018/day14.rb
79
+ - examples/aoc2018/day14_2.rb
80
+ - examples/aoc2018/day15.rb
81
+ - examples/aoc2018/day16.rb
82
+ - examples/aoc2018/day17.rb
83
+ - examples/aoc2018/day18.rb
84
+ - examples/aoc2018/day18_rspec.rb
85
+ - examples/aoc2018/day19.rb
86
+ - examples/aoc2018/day1_part2.rb
87
+ - examples/aoc2018/day2.rb
88
+ - examples/aoc2018/day20.rb
89
+ - examples/aoc2018/day21.rb
90
+ - examples/aoc2018/day21_v2.rb
91
+ - examples/aoc2018/day21_v3.rb
92
+ - examples/aoc2018/day21_v4.rb
93
+ - examples/aoc2018/day22.rb
94
+ - examples/aoc2018/day23.rb
95
+ - examples/aoc2018/day24.rb
96
+ - examples/aoc2018/day25.rb
97
+ - examples/aoc2018/day2_2.rb
98
+ - examples/aoc2018/day3.rb
99
+ - examples/aoc2018/day4.rb
100
+ - examples/aoc2018/day5.rb
101
+ - examples/aoc2018/day5_part2.rb
102
+ - examples/aoc2018/day6.rb
103
+ - examples/aoc2018/day7.rb
104
+ - examples/aoc2018/day8.rb
105
+ - examples/aoc2018/day8_part2.rb
106
+ - examples/aoc2018/day9.rb
107
+ - examples/aoc2018/day9_circular.rb
108
+ - examples/aoc2018/inputs/day10_input.txt
109
+ - examples/aoc2018/inputs/day11_input.txt
110
+ - examples/aoc2018/inputs/day12_input.txt
111
+ - examples/aoc2018/inputs/day12_input2.txt
112
+ - examples/aoc2018/inputs/day13_input.txt
113
+ - examples/aoc2018/inputs/day13_test.txt
114
+ - examples/aoc2018/inputs/day14_input.txt
115
+ - examples/aoc2018/inputs/day15_input.txt
116
+ - examples/aoc2018/inputs/day15_input10.txt
117
+ - examples/aoc2018/inputs/day15_input11.txt
118
+ - examples/aoc2018/inputs/day15_input12.txt
119
+ - examples/aoc2018/inputs/day15_input13.txt
120
+ - examples/aoc2018/inputs/day15_input14.txt
121
+ - examples/aoc2018/inputs/day15_input2.txt
122
+ - examples/aoc2018/inputs/day15_input3.txt
123
+ - examples/aoc2018/inputs/day15_input4.txt
124
+ - examples/aoc2018/inputs/day15_input5.txt
125
+ - examples/aoc2018/inputs/day15_input6.txt
126
+ - examples/aoc2018/inputs/day15_input7.txt
127
+ - examples/aoc2018/inputs/day15_input8.txt
128
+ - examples/aoc2018/inputs/day15_input9.txt
129
+ - examples/aoc2018/inputs/day15_test.txt
130
+ - examples/aoc2018/inputs/day16_input.txt
131
+ - examples/aoc2018/inputs/day17_input.txt
132
+ - examples/aoc2018/inputs/day17_input_test.txt
133
+ - examples/aoc2018/inputs/day18_input.txt
134
+ - examples/aoc2018/inputs/day18_test.txt
135
+ - examples/aoc2018/inputs/day19_input.txt
136
+ - examples/aoc2018/inputs/day1_input.txt
137
+ - examples/aoc2018/inputs/day20_input.txt
138
+ - examples/aoc2018/inputs/day21_input.txt
139
+ - examples/aoc2018/inputs/day22_input.txt
140
+ - examples/aoc2018/inputs/day23_input.txt
141
+ - examples/aoc2018/inputs/day23_input2.txt
142
+ - examples/aoc2018/inputs/day24_input.txt
143
+ - examples/aoc2018/inputs/day25_input.txt
144
+ - examples/aoc2018/inputs/day2_input.txt
145
+ - examples/aoc2018/inputs/day3_input.txt
146
+ - examples/aoc2018/inputs/day4_input.txt
147
+ - examples/aoc2018/inputs/day5_input.txt
148
+ - examples/aoc2018/inputs/day6_input.txt
149
+ - examples/aoc2018/inputs/day7_input.txt
150
+ - examples/aoc2018/inputs/day8_input.txt
151
+ - examples/aoc2018/inputs/day9_input.txt
86
152
  - lib/cem.rb
87
153
  - lib/cem/ccommon.rb
88
154
  - lib/cem/cflame.rb
89
155
  - lib/cem/cflame/clickable_img.rb
90
156
  - lib/cem/cflame/missing_html.rb
91
157
  - lib/cem/cflame/p.rb
158
+ - lib/cem/cflame/popen.rb
92
159
  - lib/cem/cflame/progress.rb
93
160
  - lib/cem/cruzzles.rb
94
161
  - lib/cem/version.rb
@@ -115,8 +182,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
115
182
  - !ruby/object:Gem::Version
116
183
  version: '0'
117
184
  requirements: []
118
- rubyforge_project:
119
- rubygems_version: 2.7.6
185
+ rubygems_version: 3.1.4
120
186
  signing_key:
121
187
  specification_version: 4
122
188
  summary: Cem = Christopher's Common Helper Gem for Ruby.