slippy_tiles_scorer 0.0.3 → 0.0.5

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: ce623fd11c56fc5615043d62fd196810c7c0caccd5f9d9789dfaa864954ed2ee
4
- data.tar.gz: 0b7296978405915b2ee53d79da2a8e8c0cc15445f2b71ce5e396ca5fc7af5a39
3
+ metadata.gz: 3a911e3fb4c9a3d30d90e52664a3619f2c208581a0a31ee938ab4c44444d9608
4
+ data.tar.gz: 8093375ef475c76b1c996b31335a7b151e850778c8cd9c285411b0d33926e7a7
5
5
  SHA512:
6
- metadata.gz: 746ffc5f6d06857aec00c471b3c671612debe31c22a2cdb1d73b1da3583ba253008cbea5e886addf44961019cd2435db6eccb7f70086f182e3cfa3440247a88a
7
- data.tar.gz: 7e6bacaaab5a06b40d0fee46a3494f436a96b04e042a90bae45ae567ab1860b99499999e66089a372be84d733ae4f15683316748ee1835604c3358acdb3b2da8
6
+ metadata.gz: ad02a2cbdda34c8976cdd4cea4a9d90c5c9b80afe3c77c55eec578f054de4c4d89272b1e10eaa47f253184ea96d4fa2716fc16873d7ae51dfe2bf836e47d61e4
7
+ data.tar.gz: c55a90cf772a57db236e2b182ac6853bc0137685ca92567c48883a1e897e05d5e0bb38bde02e50a63832793b117b1ba619c2bdf255530668fd51b4031d1d9d9d
data/.rubocop.yml CHANGED
@@ -1,5 +1,6 @@
1
1
  require:
2
2
  - rubocop-rake
3
+ plugins:
3
4
  - rubocop-performance
4
5
 
5
6
  AllCops:
data/CHANGELOG.md CHANGED
@@ -1,15 +1,21 @@
1
1
  ## [Unreleased]
2
2
 
3
+ - [#5](https://github.com/simonneutert/slippy_tiles_scorer/pull/5) - Reworks maximum-square detection with a sparse dynamic-programming algorithm. Adds validation for negative coordinates and minimum square sizes, and expands coverage for multiple and incomplete squares.
4
+ - [#4](https://github.com/simonneutert/slippy_tiles_scorer/pull/4) - Runs a benchmark before running the tests.
5
+ - [#3](https://github.com/simonneutert/slippy_tiles_scorer/pull/3) - 100 % test coverage: lines and branches. Adds a badge to the README. Adds gem release notes to the README.
6
+
3
7
  ## [0.0.3] - 2024-11-26
4
8
 
5
9
  - More tests, like a json file with test data.
6
10
  - The `Rakefile` can be used to run the tests and check the code style.
7
- - A CI pipeline runs the test suite and checks the code style for multiple Ruby versions >= v3.
11
+ - A CI pipeline runs the test suite and checks the code style for multiple Ruby
12
+ versions >= v3.
8
13
  - Rubocop was configured and some plugins were added to the `.rubocop.yml` file.
9
14
 
10
15
  ## [0.0.2] - 2024-11-26
11
16
 
12
- - The result `Hash` of `#clusters` under the key `:clusters` is now an array of `[x, y]` and `x` and `y` being integer values.
17
+ - The result `Hash` of `#clusters` under the key `:clusters` is now an array of
18
+ `[x, y]` and `x` and `y` being integer values.
13
19
 
14
20
  ## [0.0.1] - 2024-11-25
15
21
 
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Simon Neutert
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
data/README.md CHANGED
@@ -1,10 +1,11 @@
1
1
  # SlippyTilesScorer
2
2
 
3
- > [!NOTE]
4
- > This gem's API is not considered stable yet.
5
- > Things might change in the future.
3
+ > [!NOTE]\
4
+ > This gem's API is not considered stable yet. Things might change in the
5
+ > future.
6
6
 
7
- [![Gem Version](https://badge.fury.io/rb/slippy_tiles_scorer.svg)](https://badge.fury.io/rb/slippy_tiles_scorer) \
7
+ [![Gem Version](https://badge.fury.io/rb/slippy_tiles_scorer.svg)](https://badge.fury.io/rb/slippy_tiles_scorer)\
8
+ ![Coverage](https://github.com/simonneutert/slippy_tiles_scorer/blob/main/coverage_badge.svg)\
8
9
  [![Ruby](https://github.com/simonneutert/slippy_tiles_scorer/actions/workflows/main.yml/badge.svg)](https://github.com/simonneutert/slippy_tiles_scorer/actions/workflows/main.yml)
9
10
 
10
11
  Calculate scores of map tiles (x, y) on a map. The scores are total, (max)
@@ -12,6 +13,8 @@ clusters, and max squares.
12
13
 
13
14
  To experiment with that code, run `bin/console` for an interactive prompt.
14
15
 
16
+ Supports Ruby >= 3.0, JRuby >= 9.4 and latest TruffleRuby (with GraalVM).
17
+
15
18
  ## Installation
16
19
 
17
20
  Install the gem and add to the application's Gemfile by executing:
@@ -20,7 +23,8 @@ Install the gem and add to the application's Gemfile by executing:
20
23
  bundle add slippy_tiles_scorer
21
24
  ```
22
25
 
23
- If bundler is not being used to manage dependencies, install the gem by executing:
26
+ If bundler is not being used to manage dependencies, install the gem by
27
+ executing:
24
28
 
25
29
  ```bash
26
30
  gem install slippy_tiles_scorer
@@ -35,7 +39,7 @@ Find some examples below.
35
39
  A simple example of how to use the `TileScorer` class, when tinkering in a REPL.
36
40
 
37
41
  ```ruby
38
- require 'tile_scorer'
42
+ require 'slippy_tiles_scorer'
39
43
 
40
44
  collection_of_tiles = Set.new
41
45
  collection_of_tiles.add([0, 0])
@@ -75,7 +79,8 @@ tile_scorer.max_squares(min_size: 4) # => {:size=>0, top_left_tile_x_y=>#<Set: {
75
79
 
76
80
  ### Optimized
77
81
 
78
- An more computationally optimized example of how to use the `TileScorer` class, when using the code in production.
82
+ An more computationally optimized example of how to use the `TileScorer` class,
83
+ when using the code in production.
79
84
 
80
85
  ```ruby
81
86
  ### OPTIMIZE COMPUTATION ###
@@ -101,10 +106,46 @@ puts max_squares # =>[{:size=>3, top_left_tile_x_y=>#<Set: {[0, 0]}>}]
101
106
 
102
107
  ## Development
103
108
 
104
- After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
109
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run
110
+ `rake test` to run the tests. You can also run `bin/console` for an interactive
111
+ prompt that will allow you to experiment.
105
112
 
106
- To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and the created tag, and push the `.gem` file to [rubygems.org](https://rubygems.org).
113
+ To install this gem onto your local machine, run `bundle exec rake install`. To
114
+ release a new version, update the version number in `version.rb`, and then run
115
+ `bundle exec rake release`, which will create a git tag for the version, push
116
+ git commits and the created tag, and push the `.gem` file to
117
+ [rubygems.org](https://rubygems.org).
107
118
 
108
119
  ## Contributing
109
120
 
110
- Bug reports and pull requests are welcome on GitHub at https://github.com/simonneutert/slippy_tiles_scorer.
121
+ Bug reports and pull requests are welcome on GitHub at
122
+ https://github.com/simonneutert/slippy_tiles_scorer.
123
+
124
+ ## Release new Gem version
125
+
126
+ To release a new version of the gem, follow these steps:
127
+
128
+ ### Pre-release
129
+
130
+ 1. Make sure the tests pass and coverage badge is updated: `$ bundle exec rake`.
131
+ 2. Update the version number in `lib/slippy_tiles_scorer/version.rb`.
132
+ 3. Run `$ bundle install`.
133
+ 4. Check the `README.md` for correctness.
134
+ 5. Make sure the `CHANGELOG.md` is up to date.
135
+ 6. All changes are committed and pushed to the main branch.
136
+
137
+ ### Release
138
+
139
+ 1. Checkout the main branch: `$ git checkout main`.
140
+ 2. Run the tests: `$ bundle exec rake` (just for safety).
141
+ 3. Run `$ bundle exec rake release`.
142
+
143
+ ### Post-release
144
+
145
+ Still being on the main branch:
146
+
147
+ 1. Update the version number in `lib/slippy_tiles_scorer/version.rb` to the next
148
+ development version.
149
+ 2. Run `$ bundle install`.
150
+ 3. Commit the changes: `$ git commit -am "Bump version to vX.Y.Z"`.
151
+ 4. Push the changes: `$ git push`.
data/Rakefile CHANGED
@@ -4,9 +4,14 @@ require "bundler/gem_tasks"
4
4
  require "rubocop/rake_task"
5
5
  RuboCop::RakeTask.new
6
6
 
7
- task default: %i[test rubocop]
7
+ task default: %i[test rubocop copy_coverage]
8
8
 
9
9
  desc "Run tests"
10
10
  task :test do
11
11
  sh "ruby test_runner.rb"
12
12
  end
13
+
14
+ desc "Copy coverage report to public"
15
+ task :copy_coverage do
16
+ FileUtils.cp("coverage/coverage_badge_total.svg", "./coverage_badge.svg")
17
+ end
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "bundler/gem_tasks"
4
+ require "rubocop/rake_task"
5
+ RuboCop::RakeTask.new
6
+
7
+ task default: %i[test]
8
+
9
+ desc "Run tests"
10
+ task :test do
11
+ sh "ruby test_runner.rb"
12
+ end
@@ -0,0 +1,35 @@
1
+ <svg contentScriptType="text/ecmascript" contentStyleType="text/css" preserveAspectRatio="xMidYMid meet" version="1.0" height="20" width="120"
2
+ xmlns="http://www.w3.org/2000/svg"
3
+ xmlns:xlink="http://www.w3.org/1999/xlink">
4
+
5
+
6
+ <linearGradient id="smooth" x2="0" y2="120">
7
+ <stop offset="0" stop-color="#bbb" stop-opacity=".1"/>
8
+ <stop offset="1" stop-opacity=".1"/>
9
+ </linearGradient>
10
+ <clipPath id="round">
11
+ <rect height="20" width="120" rx="3" fill="#fff"/>
12
+ </clipPath>
13
+ <g clip-path="url(#round)">
14
+ <rect height="20" width="60" fill="#555"/>
15
+ <rect x="60" height="20" width="60" fill="#cccc00"/>
16
+ <rect height="20" width="120" fill="url(#smooth)"/>
17
+ </g>
18
+ <g fill="#fff" text-anchor="middle" font-family="Verdana,sans-serif" font-size="11">
19
+ <text x="30" y="15" fill="#010101" fill-opacity="0.3">
20
+ scov total
21
+ </text>
22
+ <text x="30" y="14">
23
+ scov total
24
+ </text>
25
+ </g>
26
+ <g fill="#fff" text-anchor="middle" font-family="Verdana,sans-serif" font-size="11">
27
+ <text x="90" y="15" fill="#010101" fill-opacity="0.3">
28
+ 100%
29
+ </text>
30
+ <text x="90" y="14">
31
+ 100%
32
+ </text>
33
+ </g>
34
+
35
+ </svg>
@@ -35,7 +35,7 @@ module SlippyTilesScorer
35
35
  todo = [start]
36
36
  broad_search!(todo, cluster)
37
37
 
38
- @clusters.push(cluster) if cluster.size.positive?
38
+ @clusters.push(cluster)
39
39
  cluster
40
40
  end
41
41
 
@@ -3,105 +3,155 @@
3
3
  require "set"
4
4
 
5
5
  module SlippyTilesScorer
6
- # finds the maximum square in a collection/tiles_x_y of points (x, y)
6
+ # Finds the maximum fully-filled square in a collection of x/y tiles.
7
7
  class MaxSquare
8
- attr_accessor :tiles_x_y
8
+ attr_reader :tiles_x_y
9
9
 
10
10
  def initialize(tiles_x_y: Set.new)
11
+ self.tiles_x_y = tiles_x_y
12
+ end
13
+
14
+ def tiles_x_y=(tiles_x_y)
11
15
  @tiles_x_y = tiles_x_y
12
- @tiles_lut = nil
16
+ @square_scores = nil
13
17
  end
14
18
 
15
- # @param min_size [Integer] The minimum size of the square, should be 3 or greater.
16
- # As the smallest square is 3x3 and therefor a cluster tile needs to be the center.
17
- # @return [Hash] The size of the square and the points of the square.
19
+ # Finds all largest fully-filled squares.
20
+ #
21
+ # @param min_size [Integer] Minimum square size to report.
22
+ # @return [Hash] Maximum size and its top-left tile coordinates.
18
23
  def max_squares(min_size: 3)
19
- @max_size_found = 0
20
- raise ArgumentError, "min_size must be 2 or greater" if min_size < 2
24
+ # Rebuild for every scoring run because tiles_x_y may be a mutable Set.
25
+ @square_scores = nil
21
26
 
22
- result = max_square_result(min_size: min_size)
23
- @max_size_found = 0
24
- @tiles_lut = nil
25
- result
27
+ max_square_result(min_size: min_size)
26
28
  end
27
29
 
28
- # @param min_size [Integer] The minimum size of the square, should be 3 or greater.
29
- # @return [Hash] The size of the square and the points of the square.
30
- def max_square_result(min_size: 3)
31
- result = { size: @max_size_found, top_left_tile_x_y: Set.new }
32
- @tiles_x_y.each do |(x, y)|
33
- raise ArgumentError, "x and y must be greater than or equal to 0" if x.negative? || y.negative?
30
+ # @param min_size [Integer] Minimum square size to report.
31
+ # @return [Hash] Maximum size and its top-left tile coordinates.
32
+ def max_square_result(min_size: 3) # rubocop:disable Metrics/MethodLength
33
+ raise ArgumentError, "min_size must be 2 or greater" if min_size < 2
34
34
 
35
- steps = max_square(x: x, y: y)
36
- result = track_result(result: result, steps: steps, x: x, y: y) if steps >= min_size
35
+ max_size = 0
36
+ top_left_tiles = Set.new
37
+
38
+ square_scores.each do |y, row|
39
+ row.each do |x, size|
40
+ next if size < min_size
41
+
42
+ if size > max_size
43
+ max_size = size
44
+ top_left_tiles.clear
45
+ top_left_tiles << [x, y]
46
+ elsif size == max_size
47
+ top_left_tiles << [x, y]
48
+ end
49
+ end
37
50
  end
38
- result
51
+
52
+ {
53
+ size: max_size,
54
+ top_left_tile_x_y: top_left_tiles
55
+ }
39
56
  end
40
57
 
41
- # @param x [Integer] The x coordinate of the top left tile.
42
- # @param y [Integer] The y coordinate of the top left tile.
43
- # @return [Integer] The size of the square.
58
+ # Returns the size of the largest fully-filled square whose
59
+ # top-left tile is x/y.
60
+ #
61
+ # @param x [Integer] X coordinate of the top-left tile.
62
+ # @param y [Integer] Y coordinate of the top-left tile.
63
+ # @return [Integer] Square size, or 0 if the tile does not exist.
44
64
  def max_square(x:, y:)
45
- steps = 1
46
- steps += 1 while steps_fulfilled?(x: x, y: y, steps: steps)
47
- steps
65
+ row = square_scores[y]
66
+
67
+ return 0 unless row
68
+
69
+ row[x] || 0
48
70
  end
49
71
 
50
- # @param x [Integer] The x coordinate of the top left tile.
51
- # @param y [Integer] The y coordinate of the top left tile.
52
- # @param steps [Integer] The size of the square.
53
- # @return [Boolean] True if all steps are fulfilled.
72
+ # Reports whether the square starting at x/y can grow beyond +steps+.
73
+ #
74
+ # For example:
75
+ # steps_fulfilled?(x: 0, y: 0, steps: 2)
76
+ #
77
+ # is true when a fully-filled square of at least 3x3 exists there.
78
+ #
79
+ # @param x [Integer] X coordinate of the top-left tile.
80
+ # @param y [Integer] Y coordinate of the top-left tile.
81
+ # @param steps [Integer] Current square size.
82
+ # @return [Boolean]
54
83
  def steps_fulfilled?(x:, y:, steps:)
55
- in_lut?(x: x + steps, y: y + steps) &&
56
- (0...steps).all? do |i|
57
- in_lut?(x: x + steps, y: y + i) &&
58
- in_lut?(x: x + i, y: y + steps)
59
- end
84
+ max_square(x: x, y: y) > steps
60
85
  end
61
86
 
62
87
  private
63
88
 
64
- # This is as fast as it gets! Do not implement `#nil?
89
+ # Builds a sparse dynamic-programming lookup.
90
+ #
91
+ # For every existing tile:
65
92
  #
66
- # @param x [Integer] The x coordinate of the top left tile.
67
- # @param y [Integer] The y coordinate of the top left tile.
68
- # @return [Boolean|Nil] True if the tile is in the tiles_lut.
69
- def in_lut?(x:, y:)
70
- unless @tiles_lut
71
- @tiles_lut = {}
72
- @tiles_x_y.each do |(x, y)|
73
- @tiles_lut[x] ||= {}
74
- @tiles_lut[x][y] = true
93
+ # score(x, y) =
94
+ # 1 + min(
95
+ # score(x + 1, y),
96
+ # score(x, y + 1),
97
+ # score(x + 1, y + 1)
98
+ # )
99
+ #
100
+ # A score of N guarantees that every tile in the N x N square
101
+ # beginning at x/y exists.
102
+ #
103
+ # @return [Hash<Integer, Hash<Integer, Integer>>]
104
+ def square_scores
105
+ @square_scores ||= build_square_scores
106
+ end
107
+
108
+ def build_square_scores # rubocop:disable Metrics/AbcSize,Metrics/CyclomaticComplexity,Metrics/MethodLength,Metrics/PerceivedComplexity
109
+ rows = {}
110
+
111
+ @tiles_x_y.each do |x, y|
112
+ if x.negative? || y.negative?
113
+ raise ArgumentError,
114
+ "x and y must be greater than or equal to 0"
75
115
  end
116
+
117
+ (rows[y] ||= []) << x
76
118
  end
77
- @tiles_lut.dig(x, y)
78
- end
79
119
 
80
- # @param result [Hash] The result hash.
81
- # @param steps [Integer] The size of the square.
82
- # @param x [Integer] The x coordinate of the top left tile.
83
- # @param y [Integer] The y coordinate of the top left tile.
84
- # @return [Hash] The updated result hash.
85
- def track_result(result:, steps:, x:, y:)
86
- if steps > @max_size_found
87
- @max_size_found = steps
88
- result = { size: @max_size_found, top_left_tile_x_y: Set.new }
89
- update_result!(result: result, steps: steps, x: x, y: y)
90
- elsif steps == @max_size_found
91
- update_result!(result: result, steps: steps, x: x, y: y)
120
+ scores = {}
121
+
122
+ next_row = nil
123
+ next_y = nil
124
+
125
+ rows.keys.sort.reverse_each do |y|
126
+ # A gap between rows means no square can continue downward.
127
+ next_row = nil unless next_y == y + 1
128
+
129
+ current_row = {}
130
+
131
+ rows[y].sort!.reverse_each do |x|
132
+ right = current_row[x + 1] || 0
133
+
134
+ if next_row
135
+ below = next_row[x] || 0
136
+ diagonal = next_row[x + 1] || 0
137
+ else
138
+ below = 0
139
+ diagonal = 0
140
+ end
141
+
142
+ # Avoid allocating [right, below, diagonal] for every tile.
143
+ min = [right, below].min
144
+ min = diagonal if diagonal < min
145
+
146
+ current_row[x] = min + 1
147
+ end
148
+
149
+ scores[y] = current_row
150
+ next_row = current_row
151
+ next_y = y
92
152
  end
93
- result
94
- end
95
153
 
96
- # @param result [Hash] The result hash.
97
- # @param steps [Integer] The size of the square.
98
- # @param x [Integer] The x coordinate of the top left tile.
99
- # @param y [Integer] The y coordinate of the top left tile.
100
- # @return [Hash] The updated result hash.
101
- def update_result!(result:, steps:, x:, y:)
102
- result[:size] = steps
103
- result[:top_left_tile_x_y] << [x, y]
104
- result
154
+ scores
105
155
  end
106
156
  end
107
157
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module SlippyTilesScorer
4
- VERSION = "0.0.3"
4
+ VERSION = "0.0.5"
5
5
  end
@@ -20,7 +20,7 @@ module SlippyTilesScorer
20
20
  return true if @tiles_x_y.empty?
21
21
  raise ArgumentError, "@tiles_x_y must be a Set" unless @tiles_x_y.is_a?(Set)
22
22
 
23
- set_of_arrays? && set_of_arrays_of_integers?
23
+ set_of_arrays_with_two_positive_integers?
24
24
  end
25
25
 
26
26
  def clusters(tiles_x_y: @tiles_x_y)
@@ -49,16 +49,13 @@ module SlippyTilesScorer
49
49
 
50
50
  private
51
51
 
52
- def set_of_arrays?
53
- return true if @tiles_x_y.all? { |point| point.is_a?(Array) && point.size == 2 }
52
+ def set_of_arrays_with_two_positive_integers?
53
+ return true if @tiles_x_y.all? do |points|
54
+ points.is_a?(Array) && points.size == 2 &&
55
+ points.all? { |point| point.is_a?(Integer) && point >= 0 }
56
+ end
54
57
 
55
- raise ArgumentError, "each point must be an array with two elements"
56
- end
57
-
58
- def set_of_arrays_of_integers?
59
- return true if @tiles_x_y.all? { |point| point.all?(Integer) }
60
-
61
- raise ArgumentError, "each point must be an array with two integers"
58
+ raise ArgumentError, "each point must be an array with two integers >= 0"
62
59
  end
63
60
  end
64
61
  end
data/mise.toml ADDED
@@ -0,0 +1,2 @@
1
+ [tools]
2
+ ruby = "jruby-10"
metadata CHANGED
@@ -1,14 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: slippy_tiles_scorer
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.3
4
+ version: 0.0.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Simon Neutert
8
- autorequire:
9
8
  bindir: exe
10
9
  cert_chain: []
11
- date: 2024-11-26 00:00:00.000000000 Z
10
+ date: 1980-01-02 00:00:00.000000000 Z
12
11
  dependencies:
13
12
  - !ruby/object:Gem::Dependency
14
13
  name: set
@@ -34,12 +33,16 @@ extra_rdoc_files: []
34
33
  files:
35
34
  - ".rubocop.yml"
36
35
  - CHANGELOG.md
36
+ - LICENSE
37
37
  - README.md
38
38
  - Rakefile
39
+ - Rakefile.alt-legacy
40
+ - coverage_badge.svg
39
41
  - lib/slippy_tiles_scorer.rb
40
42
  - lib/slippy_tiles_scorer/cluster.rb
41
43
  - lib/slippy_tiles_scorer/max_square.rb
42
44
  - lib/slippy_tiles_scorer/version.rb
45
+ - mise.toml
43
46
  - sig/slippy_tiles_scorer.rbs
44
47
  - test_helper.rb
45
48
  homepage: https://github.com/simonneutert/slippy_tiles_scorer
@@ -48,7 +51,6 @@ metadata:
48
51
  homepage_uri: https://github.com/simonneutert/slippy_tiles_scorer
49
52
  source_code_uri: https://github.com/simonneutert/slippy_tiles_scorer
50
53
  changelog_uri: https://github.com/simonneutert/slippy_tiles_scorer/blob/main/CHANGELOG.md
51
- post_install_message:
52
54
  rdoc_options: []
53
55
  require_paths:
54
56
  - lib
@@ -56,15 +58,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
56
58
  requirements:
57
59
  - - ">="
58
60
  - !ruby/object:Gem::Version
59
- version: 3.0.0
61
+ version: 3.3.0
60
62
  required_rubygems_version: !ruby/object:Gem::Requirement
61
63
  requirements:
62
64
  - - ">="
63
65
  - !ruby/object:Gem::Version
64
66
  version: '0'
65
67
  requirements: []
66
- rubygems_version: 3.5.22
67
- signing_key:
68
+ rubygems_version: 4.0.13
68
69
  specification_version: 4
69
70
  summary: A gem to score a set of slippy tiles.
70
71
  test_files: []