cem 0.1.3 → 0.1.4

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 014d136cae33adc2f8715b45c280fb55f11242f7c70940d040bce1e545b97e7b
4
- data.tar.gz: fbbd2a832bbf96fa5f18c48557b4f081902657faeb57106e6a5227d73f409952
3
+ metadata.gz: a12790b597c9fd5c63fc14b855b964d32aeda5f968d612806e8d80697bbb37c4
4
+ data.tar.gz: 0acf18fd6f7dafe94553e55dca0e89c3304066b5ec85d1413187eb4afe6d7774
5
5
  SHA512:
6
- metadata.gz: c3a7fa8ba025117c5035abe10a58004d03d3db9741cd1b1c10d22d976112b7c94ad9e0807d0bf930d411768060ac8eb6c5a34718125fac8be1eb3c2dc5103ea3
7
- data.tar.gz: 2ac9b662fe5ef2aaf459d5c93dd7a5da5cbecb23260ae21bc201b75a294ec0defe121cbf39ccd9978af2595c9c116e756aac6edf68be64e4986923474ba9652a
6
+ metadata.gz: 4b8f6e808871a8b4197126f576940ca6a98daff481339ab4f9830316fecf2b4cab2d3bf7000b18ed39276731d2a431408dccfd799fc4ec784ac3901ade4f27eb
7
+ data.tar.gz: 142741554b2f214d0af5cbffbc0ecb9860ef9e7870697863af38eab01c3a811b3ac459cad093cc1b372962d7ba224beeb8c86a2bd58dc7f96c460e93bcbb4c43
data/.gitignore CHANGED
@@ -54,4 +54,5 @@ Gemfile.lock
54
54
  .rvmrc
55
55
 
56
56
  # Used by RuboCop. Remote config files pulled in from inherit_from directive.
57
- # .rubocop-https?--*
57
+ # .rubocop-https?--
58
+ .idea/
@@ -35,8 +35,8 @@ Gem::Specification.new do |spec|
35
35
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
36
36
  spec.require_paths = ["lib"]
37
37
 
38
- spec.add_development_dependency "bundler", "~> 1.17"
39
- spec.add_development_dependency "rake", "~> 10.0"
38
+ spec.add_development_dependency "bundler", "~> 2.1" # Was 1.17
39
+ spec.add_development_dependency "rake", "~> 13.0" # Was: 10.0
40
40
  spec.add_development_dependency "rspec", "~> 3.0"
41
41
 
42
42
  spec.add_runtime_dependency 'flammarion', '~> 0.3'
@@ -0,0 +1,13 @@
1
+
2
+ #
3
+ # https://adventofcode.com/2018/day/1 Part 1
4
+ #
5
+ # Does not use any cem functions \o/
6
+ #
7
+
8
+ result = 0
9
+ File.read("inputs/day1_input.txt").each_line { |line|
10
+ result += line.to_i
11
+ }
12
+
13
+ puts result
@@ -0,0 +1,30 @@
1
+
2
+ #
3
+ # https://adventofcode.com/2018/day/1 Part 2
4
+ #
5
+ # Does not use any cem functions \o/ but did you know:
6
+ #
7
+ # - Set provides #[] as a class method: Set[1,2,3] is the same as Set.new() and then Set.add(...)
8
+ # - Set provides #add?() to add and check if the object added was already in the Set (returns nil in case).
9
+ #
10
+ # For example: Set[0,1].add?(1) => nil
11
+ #
12
+
13
+ require 'set'
14
+
15
+ cur = 0
16
+ seen_before = Set[0]
17
+
18
+ while true
19
+ File.read("inputs/day1_input.txt").each_line { |line|
20
+
21
+ cur += line.to_i
22
+
23
+ if !seen_before.add?(cur)
24
+ puts cur
25
+ exit
26
+ end
27
+ }
28
+ end
29
+
30
+ # Unreachable!
@@ -0,0 +1,20 @@
1
+
2
+ #
3
+ # https://adventofcode.com/2018/day/2
4
+ #
5
+ # Does not use any cem functions \o/
6
+ #
7
+ twice = 0
8
+ thrice = 0
9
+
10
+ chars = [*'a'..'z', *'A'..'Z']
11
+
12
+ File.read("inputs/day2_input.txt").each_line { |l|
13
+
14
+ twice += 1 if chars.any? { |c| l.count(c) == 2 }
15
+ thrice += 1 if chars.any? { |c| l.count(c) == 3 }
16
+
17
+ }
18
+
19
+ puts "1st star: #{twice * thrice}"
20
+
@@ -0,0 +1,27 @@
1
+
2
+ #
3
+ # https://adventofcode.com/2018/day/2 part 2
4
+ #
5
+ # Does not use any cem functions \o/
6
+
7
+ previous = ''
8
+ File.readlines("inputs/day2_input.txt").sort.each { |l|
9
+
10
+ mismatch = 0
11
+ s = ''
12
+ if previous != ''
13
+ l.split("").each_with_index { |c, i|
14
+ if previous[i] != c
15
+ mismatch += 1
16
+ else
17
+ s += c
18
+ end
19
+ }
20
+ end
21
+
22
+ if mismatch == 1
23
+ puts s
24
+ end
25
+
26
+ previous = l
27
+ }
@@ -0,0 +1,71 @@
1
+
2
+ #
3
+ # https://adventofcode.com/2018/day/3 part 1 and 2
4
+ #
5
+ # Demonstrates: Point2D, min(a,b), Array::with_progress
6
+ #
7
+ # Areas for improvement: Rect intersection
8
+
9
+ require 'set'
10
+ require 'cem'
11
+
12
+ claims = []
13
+ intersections = Set.new
14
+ doesIntersect = Set.new
15
+
16
+ Claim = Struct.new("Claim", :x, :y, :width, :height, :claimId)
17
+
18
+ File.readlines("inputs/day3_input.txt").with_progress.each { |l|
19
+
20
+ if l =~ /^\#(\d+) \@ (\d+),(\d+)\: (\d+)x(\d+)$/
21
+
22
+ claim = Claim.new($2.to_i, $3.to_i, $4.to_i, $5.to_i, $1.to_i)
23
+
24
+ claims.each { |other|
25
+
26
+ x = claim.x
27
+ y = claim.y
28
+ w = claim.width
29
+ h = claim.height
30
+
31
+ x2 = other.x
32
+ y2 = other.y
33
+ w2 = other.width
34
+ h2 = other.height
35
+
36
+ if x2 < x
37
+ x, x2 = x2, x
38
+ w, w2 = w2, w
39
+ end
40
+
41
+ if y2 < y
42
+ y, y2 = y2, y
43
+ h, h2 = h2, h
44
+ end
45
+
46
+ # puts "#{claim} - #{other}"
47
+
48
+ if x + w >= x2 && y + h >= y2
49
+
50
+ width = min(x2 + w2, x + w)
51
+ height = min(y2 + h2, y + h)
52
+
53
+ doesIntersect.add(other)
54
+ doesIntersect.add(claim)
55
+
56
+ for a in x2...width
57
+ for b in y2...height
58
+ # puts "#{a} #{b}"
59
+ intersections.add(Point2D.new(a,b))
60
+ end
61
+ end
62
+
63
+ end
64
+ }
65
+
66
+ claims << claim
67
+ end
68
+ }
69
+
70
+ puts "Part 1: #{intersections.size}"
71
+ puts "Part 2: #{claims.to_set.subtract(doesIntersect).first.claimId}"
@@ -0,0 +1,46 @@
1
+
2
+ #
3
+ # https://adventofcode.com/2018/day/4
4
+ #
5
+ # Does not use any cem functions \o/
6
+
7
+ Guard = Struct.new("Guard", :id, :total, :minutes)
8
+
9
+ guards = {}
10
+ guard = nil
11
+ asleep = nil
12
+
13
+ File.readlines("inputs/day4_input.txt", chomp: true).sort.each { |l|
14
+
15
+ if l =~ /Guard \#(\d+) begins shift$/
16
+
17
+ id = $1.to_i
18
+ guard = guards[id] ||= Guard.new(id, 0, [0] * 60)
19
+
20
+ elsif / 00:(?<minute>\d+)\] falls asleep$/ =~ l
21
+
22
+ asleep = minute.to_i
23
+
24
+ elsif l =~ / 00:(\d+)\] wakes up$/
25
+
26
+ awake = $1.to_i
27
+
28
+ guard.total += awake - asleep
29
+ (asleep...awake).each { |min|
30
+ guard.minutes[min] += 1
31
+ }
32
+
33
+ end
34
+ }
35
+
36
+ guard = (guards.values.sort_by {|g| g.total}).last
37
+ puts "Part1: #{guard.id * guard.minutes.each_with_index.max[1]}"
38
+
39
+ guard = (guards.values.sort_by {|g| g.minutes.each_with_index.max[0] }).last
40
+ puts "Part2: #{guard.id * guard.minutes.each_with_index.max[1]}"
41
+
42
+
43
+
44
+
45
+
46
+
@@ -0,0 +1,23 @@
1
+
2
+ #
3
+ # https://adventofcode.com/2018/day/5 Part 1
4
+ #
5
+ # Does not use any cem functions \o/ but did you know:
6
+ #
7
+ # - String#swapcase turns "Hello" into "hELLO"?
8
+ #
9
+
10
+ out = []
11
+
12
+ File.read("inputs/day5_input.txt").each_char { |c|
13
+
14
+ if out.empty? || out.last != c.swapcase
15
+ out << c
16
+ else
17
+ out.pop
18
+ end
19
+
20
+ }
21
+
22
+ puts out.join.size
23
+
@@ -0,0 +1,29 @@
1
+
2
+ #
3
+ # https://adventofcode.com/2018/day/5 Part 2
4
+ #
5
+ # Does not use any cem functions \o/ but did you know:
6
+ #
7
+ # - String#swapcase turns a Hello into hELLO?
8
+ # - Regex support 'i' for insensitive matches?
9
+ #
10
+
11
+ File.readlines("inputs/day5_input.txt").each { |line|
12
+
13
+ puts [*'a'..'z'].map { |delete|
14
+
15
+ out = []
16
+
17
+ line.gsub(/#{delete}/i, '').each_char { |c|
18
+ if out.empty? || out.last != c.swapcase
19
+ out << c
20
+ else
21
+ out.pop
22
+ end
23
+ }
24
+
25
+ out.join.size
26
+ }.min
27
+ }
28
+
29
+
@@ -0,0 +1,53 @@
1
+
2
+ #
3
+ # https://adventofcode.com/2018/day/6 Part 1 and 2
4
+ #
5
+ # Uses Point2D from cem
6
+
7
+ require 'cem'
8
+
9
+ out = {}
10
+ points = []
11
+ largestRegion = 0
12
+
13
+ File.readlines("inputs/day6_input.txt", chomp: true).each { |line|
14
+ if line =~ /^(\d+), (\d+)$/
15
+ v1 = $1.to_i
16
+ v2 = $2.to_i
17
+
18
+ points << Point2D.new(v1, v2)
19
+ end
20
+ }
21
+
22
+ minX, maxX = points.map { |p| p.x }.minmax
23
+ minY, maxY = points.map { |p| p.y }.minmax
24
+
25
+ (minX..maxX).each { |x|
26
+ (minY..maxY).each { |y|
27
+
28
+ coord = Point2D.new(x,y)
29
+
30
+ nearest = points.group_by { |p| p.manhattan(coord) }.min_by { |k,v| k }
31
+
32
+ # puts nearest.inspect
33
+ if nearest.last.size == 1
34
+ (out[nearest.last.first] ||= []) << coord
35
+ end
36
+
37
+ if points.sum { |p| p.manhattan(coord) } < 10000
38
+ largestRegion += 1
39
+ end
40
+ }
41
+ }
42
+
43
+ puts "Part 1"
44
+ puts out.max_by { |k,v|
45
+ if v.select { |coord| (coord.x == maxX || coord.x == minX || coord.y == maxY || coord.y == minY) }.empty?
46
+ v.size
47
+ else
48
+ 0 # don't care about infinite
49
+ end
50
+ }.last.size
51
+
52
+ puts "Part 2"
53
+ puts largestRegion
@@ -0,0 +1,110 @@
1
+
2
+ #
3
+ # https://adventofcode.com/2018/day/7 part 1 and 2
4
+ #
5
+ # Does not use any cem functions \o/
6
+ #
7
+
8
+ require 'set'
9
+
10
+ Worker = Struct.new("Worker", :readyAt, :workingOn)
11
+
12
+ def read
13
+ input = File.readlines("inputs/day7_input.txt", chomp: true)
14
+
15
+ @edges = {}
16
+ @chars = Set.new
17
+
18
+ input.each { |line|
19
+
20
+ if line =~ /^Step (.+) must be finished before step (.+) can begin.$/
21
+ to = $1
22
+ from = $2
23
+
24
+ @chars.add(to)
25
+ @chars.add(from)
26
+
27
+ (@edges[from] ||= []) << to
28
+ end
29
+
30
+ @chars.each { |c| @edges[c] ||= [] }
31
+ }
32
+ end
33
+
34
+ def anyWorkerReady
35
+ return @idleWorkers.size > 0
36
+ end
37
+
38
+ def availableWork
39
+ return @chars.select { |c| @edges.include?(c) && @edges[c].size == 0 }.sort
40
+ end
41
+
42
+ def anyWorkAvailable
43
+ return availableWork.size > 0
44
+ end
45
+
46
+ def timeStep
47
+
48
+ puts "#{@timeNow}: #{@busyWorkers.inspect}" if $DEBUG
49
+
50
+ w = @busyWorkers.min_by { |w| w.readyAt }
51
+ @timeNow = w.readyAt
52
+ @busyWorkers -= [w]
53
+ @idleWorkers += [w]
54
+
55
+ c = w.workingOn
56
+
57
+ @result += c
58
+
59
+ @edges.update(@edges) { |k,v|
60
+ v - [c]
61
+ }
62
+ end
63
+
64
+ def scheduleWork
65
+
66
+ nextTask = availableWork.first
67
+
68
+ w = @idleWorkers.pop
69
+ @busyWorkers += [w]
70
+ w.workingOn = nextTask
71
+ w.readyAt = @timeNow + 61 + nextTask.ord - 'A'.ord
72
+ @edges.delete(nextTask)
73
+
74
+ puts "Scheduling #{nextTask} to be ready at #{w.readyAt}" if $DEBUG
75
+
76
+ end
77
+
78
+ def process(parallelism)
79
+
80
+ read()
81
+
82
+ @timeNow = 0
83
+ @result = ""
84
+
85
+ @busyWorkers = []
86
+ @idleWorkers = []
87
+ parallelism.times { @idleWorkers << Worker.new(0, '') }
88
+
89
+ loop do
90
+
91
+ while (!anyWorkerReady || !anyWorkAvailable) && @busyWorkers.size > 0
92
+ timeStep
93
+ end
94
+
95
+ if !anyWorkAvailable
96
+ break
97
+ end
98
+
99
+ scheduleWork
100
+
101
+ end
102
+
103
+ puts "Parallelism: #{parallelism}"
104
+ puts @result
105
+ puts @timeNow
106
+
107
+ end
108
+
109
+ process(1)
110
+ process(5)