cem 0.1.4 → 0.1.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (66) hide show
  1. checksums.yaml +4 -4
  2. data/examples/aoc2018/.gitignore +2 -0
  3. data/examples/aoc2018/day10.rb +61 -0
  4. data/examples/aoc2018/day11.rb +66 -0
  5. data/examples/aoc2018/day12.rb +61 -0
  6. data/examples/aoc2018/day13.rb +167 -0
  7. data/examples/aoc2018/day14.rb +31 -0
  8. data/examples/aoc2018/day14_2.rb +71 -0
  9. data/examples/aoc2018/day15.rb +271 -0
  10. data/examples/aoc2018/day16.rb +158 -0
  11. data/examples/aoc2018/day17.rb +203 -0
  12. data/examples/aoc2018/day18.rb +113 -0
  13. data/examples/aoc2018/day18_rspec.rb +131 -0
  14. data/examples/aoc2018/day19.rb +145 -0
  15. data/examples/aoc2018/day20.rb +103 -0
  16. data/examples/aoc2018/day21.rb +158 -0
  17. data/examples/aoc2018/day21_v2.rb +137 -0
  18. data/examples/aoc2018/day21_v3.rb +157 -0
  19. data/examples/aoc2018/day21_v4.rb +141 -0
  20. data/examples/aoc2018/day22.rb +212 -0
  21. data/examples/aoc2018/day23.rb +148 -0
  22. data/examples/aoc2018/day24.rb +156 -0
  23. data/examples/aoc2018/day25.rb +52 -0
  24. data/examples/aoc2018/day9.rb +51 -0
  25. data/examples/aoc2018/day9_circular.rb +125 -0
  26. data/examples/aoc2018/inputs/day10_input.txt +395 -0
  27. data/examples/aoc2018/inputs/day11_input.txt +1 -0
  28. data/examples/aoc2018/inputs/day12_input.txt +34 -0
  29. data/examples/aoc2018/inputs/day12_input2.txt +16 -0
  30. data/examples/aoc2018/inputs/day13_input.txt +150 -0
  31. data/examples/aoc2018/inputs/day13_test.txt +6 -0
  32. data/examples/aoc2018/inputs/day14_input.txt +1 -0
  33. data/examples/aoc2018/inputs/day15_input.txt +32 -0
  34. data/examples/aoc2018/inputs/day15_input10.txt +32 -0
  35. data/examples/aoc2018/inputs/day15_input11.txt +32 -0
  36. data/examples/aoc2018/inputs/day15_input12.txt +32 -0
  37. data/examples/aoc2018/inputs/day15_input13.txt +32 -0
  38. data/examples/aoc2018/inputs/day15_input14.txt +32 -0
  39. data/examples/aoc2018/inputs/day15_input2.txt +7 -0
  40. data/examples/aoc2018/inputs/day15_input3.txt +9 -0
  41. data/examples/aoc2018/inputs/day15_input4.txt +7 -0
  42. data/examples/aoc2018/inputs/day15_input5.txt +7 -0
  43. data/examples/aoc2018/inputs/day15_input6.txt +7 -0
  44. data/examples/aoc2018/inputs/day15_input7.txt +7 -0
  45. data/examples/aoc2018/inputs/day15_input8.txt +5 -0
  46. data/examples/aoc2018/inputs/day15_input9.txt +7 -0
  47. data/examples/aoc2018/inputs/day15_test.txt +9 -0
  48. data/examples/aoc2018/inputs/day16_input.txt +3865 -0
  49. data/examples/aoc2018/inputs/day17_input.txt +2229 -0
  50. data/examples/aoc2018/inputs/day17_input_test.txt +8 -0
  51. data/examples/aoc2018/inputs/day18_input.txt +50 -0
  52. data/examples/aoc2018/inputs/day18_test.txt +10 -0
  53. data/examples/aoc2018/inputs/day19_input.txt +48 -0
  54. data/examples/aoc2018/inputs/day20_input.txt +1 -0
  55. data/examples/aoc2018/inputs/day21_input.txt +32 -0
  56. data/examples/aoc2018/inputs/day22_input.txt +2 -0
  57. data/examples/aoc2018/inputs/day23_input.txt +1000 -0
  58. data/examples/aoc2018/inputs/day23_input2.txt +9 -0
  59. data/examples/aoc2018/inputs/day24_input.txt +24 -0
  60. data/examples/aoc2018/inputs/day25_input.txt +1483 -0
  61. data/examples/aoc2018/inputs/day9_input.txt +1 -0
  62. data/lib/cem.rb +0 -6
  63. data/lib/cem/ccommon.rb +45 -0
  64. data/lib/cem/cruzzles.rb +93 -38
  65. data/lib/cem/version.rb +1 -1
  66. metadata +62 -2
@@ -0,0 +1 @@
1
+ 428 players; last marble is worth 70825 points
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
@@ -11,6 +11,28 @@ rescue LoadError
11
11
  require requireName
12
12
  end
13
13
 
14
+ #
15
+ # Puts+eql? == peql
16
+ # Performs a equal comparison and outputs the result to console in the form
17
+ #
18
+ # "#{msg}: Expected #{expected}, but got #{actual}"
19
+ #
20
+ # expected may be kept empty, in which case the msg is adjusted
21
+ #
22
+ def peql(actual, expected=:unknown_peql_token, msg=nil)
23
+
24
+ if expected == :unknown_peql_token
25
+ puts "#{msg}: Didn't know what to expect and got '#{actual}'"
26
+ else
27
+ if actual == expected
28
+ puts "#{msg}: Expected '#{expected}' and got it!"
29
+ else
30
+ puts "#{msg}: Expected '#{expected}', but got '#{actual}!"
31
+ end
32
+ end
33
+
34
+ end
35
+
14
36
  class File
15
37
 
16
38
  # Returns the first match of the given files
@@ -24,6 +46,29 @@ class File
24
46
  end
25
47
  end
26
48
 
49
+ class Module
50
+
51
+ # Append only the given methods from the given mod(ule)
52
+ # Adapted from: https://www.ruby-forum.com/t/partial-append-features/66728/12
53
+ # Why? Enumerable has too many methods to include at once.
54
+ def append_from( module_to_append_from, *methods_to_keep )
55
+ methods_to_keep.map! { |m| m.to_sym }
56
+
57
+ methods_to_remove = module_to_append_from.instance_methods(false) - methods_to_keep
58
+
59
+ new_mod = Module.new
60
+ new_mod.module_eval do
61
+ include module_to_append_from
62
+ methods_to_remove.each { |meth| undef_method meth }
63
+ end
64
+
65
+ # Sanity check:
66
+ check = methods_to_keep - new_mod.instance_methods(true)
67
+ raise "The following methods are not in the given module: #{check.inspect}" if !check.empty?
68
+
69
+ include new_mod
70
+ end
71
+ end
27
72
 
28
73
 
29
74
  class Array
@@ -128,29 +128,57 @@ Point2D = Struct.new("Point2D", :x, :y) {
128
128
  [array.reduce { |min, o| min.min(o) }, array.reduce { |max, o| max.max(o) } ]
129
129
  end
130
130
 
131
+ def add!(other)
132
+ self.x += other.x
133
+ self.y += other.y
134
+ return self
135
+ end
136
+
131
137
  def left
132
- return self + Dir2D.LEFT
138
+ self + Dir2D::LEFT
133
139
  end
134
140
 
135
141
  def left!
136
- x += Dir2D.LEFT.x
137
- y += Dir2D.LEFT.y
138
- return self
142
+ add!(Dir2D::LEFT)
139
143
  end
140
144
 
145
+ def right
146
+ self + Dir2D::RIGHT
147
+ end
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
141
164
 
165
+ def down!
166
+ add!(Dir2D::DOWN)
167
+ end
168
+
142
169
  def to_dir_bitmask
143
170
 
144
- if x == 0 && y == -1
171
+ case self
172
+ when Dir2D::N
145
173
  return 1
146
- elsif x == 1 && y == 0
174
+ when Dir2D::E
147
175
  return 2
148
- elsif x == 0 && y == 1
176
+ when Dir2D::S
149
177
  return 4
150
- elsif x == -1 && y == 0
178
+ when Dir2D::W
151
179
  return 8
152
180
  else
153
- raise self.p
181
+ raise "Only Dir2Ds can be converted to direction bitmask: #{self.inspect}"
154
182
  end
155
183
  end
156
184
 
@@ -158,16 +186,16 @@ Point2D = Struct.new("Point2D", :x, :y) {
158
186
 
159
187
  result = []
160
188
  if v & 1 > 0
161
- result << Point2D.new(0, -1)
189
+ result << Dir2D::N
162
190
  end
163
191
  if v & 2 > 0
164
- result << Point2D.new(1, 0)
192
+ result << Dir2D::E
165
193
  end
166
194
  if v & 4 > 0
167
- result << Point2D.new(0, 1)
195
+ result << Dir2D::S
168
196
  end
169
197
  if v & 8 > 0
170
- result << Point2D.new(-1, 0)
198
+ result << Dir2D::W
171
199
  end
172
200
  return result
173
201
  end
@@ -205,14 +233,14 @@ Seg2D = Struct.new("Seg2D", :p1, :p2) {
205
233
 
206
234
  }
207
235
 
208
- Dirs2D = [Point2D.new(0, -1), Point2D.new(1, 0), Point2D.new(0, 1), Point2D.new(-1, 0)]
209
-
210
236
  class Dir2D < Point2D
211
237
 
212
- N = UP = Dir2D.new( 0, -1)
213
- E = RIGHT = Dir2D.new( 1, 0)
214
- S = DOWN = Dir2D.new( 0, 1)
215
- 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]
216
244
 
217
245
  #
218
246
  # Dir2D * Range = array of Dir2D
@@ -237,13 +265,13 @@ class Dir2D < Point2D
237
265
  def self.x(length=1)
238
266
  return vert(length) + hori(length)
239
267
  end
240
-
241
268
  end
242
-
269
+
270
+ Dirs2D = Dir2D::All
243
271
 
244
272
  class Grid
245
273
 
246
- attr_reader :data
274
+ attr_accessor :data
247
275
 
248
276
  def initialize(x, y, default=0, &block)
249
277
 
@@ -323,6 +351,12 @@ class Grid
323
351
  return result
324
352
  end
325
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.
326
360
  def minmax(null=nil)
327
361
  min = nil
328
362
  max = nil
@@ -374,10 +408,11 @@ class Grid
374
408
  return @data[y][x] = assign
375
409
  end
376
410
 
377
- def to_a
411
+ # Returns the underlying 2D array as a flattened array
412
+ def flatten
378
413
  return @data.flatten
379
- end
380
-
414
+ end
415
+
381
416
  #
382
417
  # Returns the Point2Ds in the directions NSEW as an array (no diagonals, see adja_index for this)
383
418
  #
@@ -437,7 +472,7 @@ class Grid
437
472
  result << Point2D.new(x-1,y-1)
438
473
  end
439
474
  result << Point2D.new(x-1,y)
440
- if y + 1 < @data.size - 1
475
+ if y + 1 < @data.size
441
476
  result << Point2D.new(x-1, y+1)
442
477
  end
443
478
  end
@@ -447,15 +482,15 @@ class Grid
447
482
 
448
483
  # result << Point2D.new(x,y)
449
484
 
450
- if y + 1 < @data.size - 1
485
+ if y + 1 < @data.size
451
486
  result << Point2D.new(x, y+1)
452
487
  end
453
- if x + 1 < @data[0].size - 1
488
+ if x + 1 < @data[0].size
454
489
  if y > 0
455
490
  result << Point2D.new(x+1,y-1)
456
491
  end
457
492
  result << Point2D.new(x+1,y)
458
- if y + 1 < @data.size - 1
493
+ if y + 1 < @data.size
459
494
  result << Point2D.new(x+1, y+1)
460
495
  end
461
496
  end
@@ -466,13 +501,13 @@ class Grid
466
501
  printBoard()
467
502
  end
468
503
 
469
- #
470
504
  # returns a copy of the underlying 2D array, with linking to the content (rather than dup the content also)
471
- #
472
505
  def to_a
473
506
  @data.map { |row| row.dup }
474
507
  end
475
508
 
509
+ # Returns access to the underlying 2D array.
510
+ # Caution: This is not a duplicate. Use to_a for this.
476
511
  def data
477
512
  @data
478
513
  end
@@ -482,24 +517,30 @@ class Grid
482
517
  #
483
518
  # If block has...
484
519
  # - one parameter, passes the cell value
485
- # - two parameters, passes y and x
520
+ # - two parameters, passes the coordinates as a Point2D and the cell value
486
521
  # - three parameteres, passes y, x and the cell value
487
522
  #
523
+ # If the block returns nil, the original value is kept.
524
+ #
488
525
  def map_a(&block)
489
526
 
490
527
  case block.arity
491
528
  when 1
492
- @data.map { |row| row.map { |value| block.call(value) } }
529
+ @data.map { |row| row.map { |value| block.call(value) || value } }
493
530
  when 2
494
- @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 } }
495
532
  when 3
496
- @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} }
497
534
  else
498
535
  raise
499
536
  end
500
537
 
501
538
  end
502
539
 
540
+ def map_a!(&block)
541
+ @data = map_a(&block)
542
+ end
543
+
503
544
  def each(&block)
504
545
  @data.each { |row|
505
546
  row.each { |cell|
@@ -603,7 +644,21 @@ Point3D = Struct.new("Point3D", :x, :y, :z) {
603
644
  end
604
645
  end
605
646
  }
606
-
607
-
608
647
 
609
-
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
+ }
@@ -1,3 +1,3 @@
1
1
  module Cem
2
- VERSION = "0.1.4"
2
+ VERSION = "0.1.5"
3
3
  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.4
4
+ version: 0.1.5
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-07-01 00:00:00.000000000 Z
11
+ date: 2020-07-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -83,9 +83,31 @@ files:
83
83
  - bin/console
84
84
  - bin/setup
85
85
  - cem.gemspec
86
+ - examples/aoc2018/.gitignore
86
87
  - examples/aoc2018/day1.rb
88
+ - examples/aoc2018/day10.rb
89
+ - examples/aoc2018/day11.rb
90
+ - examples/aoc2018/day12.rb
91
+ - examples/aoc2018/day13.rb
92
+ - examples/aoc2018/day14.rb
93
+ - examples/aoc2018/day14_2.rb
94
+ - examples/aoc2018/day15.rb
95
+ - examples/aoc2018/day16.rb
96
+ - examples/aoc2018/day17.rb
97
+ - examples/aoc2018/day18.rb
98
+ - examples/aoc2018/day18_rspec.rb
99
+ - examples/aoc2018/day19.rb
87
100
  - examples/aoc2018/day1_part2.rb
88
101
  - examples/aoc2018/day2.rb
102
+ - examples/aoc2018/day20.rb
103
+ - examples/aoc2018/day21.rb
104
+ - examples/aoc2018/day21_v2.rb
105
+ - examples/aoc2018/day21_v3.rb
106
+ - examples/aoc2018/day21_v4.rb
107
+ - examples/aoc2018/day22.rb
108
+ - examples/aoc2018/day23.rb
109
+ - examples/aoc2018/day24.rb
110
+ - examples/aoc2018/day25.rb
89
111
  - examples/aoc2018/day2_2.rb
90
112
  - examples/aoc2018/day3.rb
91
113
  - examples/aoc2018/day4.rb
@@ -95,7 +117,44 @@ files:
95
117
  - examples/aoc2018/day7.rb
96
118
  - examples/aoc2018/day8.rb
97
119
  - examples/aoc2018/day8_part2.rb
120
+ - examples/aoc2018/day9.rb
121
+ - examples/aoc2018/day9_circular.rb
122
+ - examples/aoc2018/inputs/day10_input.txt
123
+ - examples/aoc2018/inputs/day11_input.txt
124
+ - examples/aoc2018/inputs/day12_input.txt
125
+ - examples/aoc2018/inputs/day12_input2.txt
126
+ - examples/aoc2018/inputs/day13_input.txt
127
+ - examples/aoc2018/inputs/day13_test.txt
128
+ - examples/aoc2018/inputs/day14_input.txt
129
+ - examples/aoc2018/inputs/day15_input.txt
130
+ - examples/aoc2018/inputs/day15_input10.txt
131
+ - examples/aoc2018/inputs/day15_input11.txt
132
+ - examples/aoc2018/inputs/day15_input12.txt
133
+ - examples/aoc2018/inputs/day15_input13.txt
134
+ - examples/aoc2018/inputs/day15_input14.txt
135
+ - examples/aoc2018/inputs/day15_input2.txt
136
+ - examples/aoc2018/inputs/day15_input3.txt
137
+ - examples/aoc2018/inputs/day15_input4.txt
138
+ - examples/aoc2018/inputs/day15_input5.txt
139
+ - examples/aoc2018/inputs/day15_input6.txt
140
+ - examples/aoc2018/inputs/day15_input7.txt
141
+ - examples/aoc2018/inputs/day15_input8.txt
142
+ - examples/aoc2018/inputs/day15_input9.txt
143
+ - examples/aoc2018/inputs/day15_test.txt
144
+ - examples/aoc2018/inputs/day16_input.txt
145
+ - examples/aoc2018/inputs/day17_input.txt
146
+ - examples/aoc2018/inputs/day17_input_test.txt
147
+ - examples/aoc2018/inputs/day18_input.txt
148
+ - examples/aoc2018/inputs/day18_test.txt
149
+ - examples/aoc2018/inputs/day19_input.txt
98
150
  - examples/aoc2018/inputs/day1_input.txt
151
+ - examples/aoc2018/inputs/day20_input.txt
152
+ - examples/aoc2018/inputs/day21_input.txt
153
+ - examples/aoc2018/inputs/day22_input.txt
154
+ - examples/aoc2018/inputs/day23_input.txt
155
+ - examples/aoc2018/inputs/day23_input2.txt
156
+ - examples/aoc2018/inputs/day24_input.txt
157
+ - examples/aoc2018/inputs/day25_input.txt
99
158
  - examples/aoc2018/inputs/day2_input.txt
100
159
  - examples/aoc2018/inputs/day3_input.txt
101
160
  - examples/aoc2018/inputs/day4_input.txt
@@ -103,6 +162,7 @@ files:
103
162
  - examples/aoc2018/inputs/day6_input.txt
104
163
  - examples/aoc2018/inputs/day7_input.txt
105
164
  - examples/aoc2018/inputs/day8_input.txt
165
+ - examples/aoc2018/inputs/day9_input.txt
106
166
  - lib/cem.rb
107
167
  - lib/cem/ccommon.rb
108
168
  - lib/cem/cflame.rb