digits_solver 0.1.1
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 +7 -0
- data/.rspec +3 -0
- data/.rubocop.yml +13 -0
- data/Gemfile +12 -0
- data/README.md +34 -0
- data/Rakefile +12 -0
- data/digits_solver.gemspec +39 -0
- data/exe/find_nydigits_solutions +36 -0
- data/lib/digits_solver/error.rb +4 -0
- data/lib/digits_solver/problem_statement.rb +26 -0
- data/lib/digits_solver/solution.rb +72 -0
- data/lib/digits_solver/solution_set.rb +76 -0
- data/lib/digits_solver/strategies/base.rb +77 -0
- data/lib/digits_solver/strategies/brute_force.rb +36 -0
- data/lib/digits_solver/version.rb +5 -0
- data/lib/digits_solver.rb +44 -0
- data/sig/digits_solver.rbs +4 -0
- metadata +90 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: b539861e0a6120403802c85ac9fb08960aa17c7064687064269a2b59b6213f3d
|
4
|
+
data.tar.gz: c0a746b1c33a7866ed10b39e51ae672806f723b01336b81f63b0563a3b45fd05
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: dd7f9d5a8c08a0ad227aa02f1adbdf12b331b69a9e068f8a1586d9e2867766b5bd6eed8c1d7bae93b57cabb310d6f637397aedf9471a5a2aecf1e07b88bea120
|
7
|
+
data.tar.gz: 0dcb86378227e3184e92b63af05fcd3b2cf210d18e0c3e1e4d92bbe973f333c68a47567ae2ba9bd023906fe673426353052e7a0f86d2c2752932e02875c646d3
|
data/.rspec
ADDED
data/.rubocop.yml
ADDED
data/Gemfile
ADDED
data/README.md
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
# DigitsSolver
|
2
|
+
|
3
|
+
This is basically a coding exercice.
|
4
|
+
|
5
|
+
The goal of this gem is to solve puzzles à-la [NY Times Digits game](https://www.nytimes.com/games/digits). You may
|
6
|
+
actually know this game under a different name. In France this looks like the calculation part of a 40 year old TV
|
7
|
+
show named 'Les chiffres et les lettres'...
|
8
|
+
|
9
|
+
This gem implements a brute-force approach to solve the problem but is ready to host alternative strategies.
|
10
|
+
|
11
|
+
|
12
|
+
## Installation
|
13
|
+
|
14
|
+
$ gem install digits_solver
|
15
|
+
|
16
|
+
## Usage
|
17
|
+
|
18
|
+
This gem provides an executable named `find_nydigits_solutions`.
|
19
|
+
|
20
|
+
* First argument is the target number.
|
21
|
+
* All subsequent arguments are the numbers to be used in calculations to reach the target.
|
22
|
+
|
23
|
+
ex:
|
24
|
+
|
25
|
+
```
|
26
|
+
$ find_nydigits_solutions 437 3 5 7 13 20 25
|
27
|
+
Trying to find 437
|
28
|
+
A best solution has been found (total of 67 found).
|
29
|
+
Solved in 4 operations:
|
30
|
+
=> 5 * 7 = 35
|
31
|
+
=> 35 - 13 = 22
|
32
|
+
=> 22 * 20 = 440
|
33
|
+
=> 440 - 3 = 437
|
34
|
+
```
|
data/Rakefile
ADDED
@@ -0,0 +1,39 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "lib/digits_solver/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |spec|
|
6
|
+
spec.name = "digits_solver"
|
7
|
+
spec.version = DigitsSolver::VERSION
|
8
|
+
spec.authors = ["Laurent B."]
|
9
|
+
spec.email = ["lbnetid+rb@gmail.com"]
|
10
|
+
|
11
|
+
spec.summary = "Solves NYTimes Digits puzzle."
|
12
|
+
spec.description = "Finds solutions to the NYTimes Digits game."
|
13
|
+
spec.homepage = "https://gitlab.com/coding_exercices/digits_solver"
|
14
|
+
spec.required_ruby_version = ">= 2.6.0"
|
15
|
+
|
16
|
+
spec.metadata["allowed_push_host"] = "https://rubygems.org"
|
17
|
+
|
18
|
+
spec.metadata["homepage_uri"] = spec.homepage
|
19
|
+
spec.metadata["source_code_uri"] = spec.homepage
|
20
|
+
|
21
|
+
# Specify which files should be added to the gem when it is released.
|
22
|
+
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
23
|
+
spec.files = Dir.chdir(__dir__) do
|
24
|
+
`git ls-files -z`.split("\x0").reject do |f|
|
25
|
+
(f == __FILE__) || f.match(%r{\A(?:(?:bin|test|spec|features)/|\.(?:git|circleci)|appveyor)})
|
26
|
+
end
|
27
|
+
end
|
28
|
+
spec.bindir = "exe"
|
29
|
+
spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
|
30
|
+
spec.require_paths = ["lib"]
|
31
|
+
|
32
|
+
# Uncomment to register a new dependency of your gem
|
33
|
+
# spec.add_dependency "example-gem", "~> 1.0"
|
34
|
+
spec.add_development_dependency 'pry'
|
35
|
+
spec.add_development_dependency 'rspec'
|
36
|
+
|
37
|
+
# For more information and examples about making a new gem, check out our
|
38
|
+
# guide at: https://bundler.io/guides/creating_gem.html
|
39
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# coding: utf-8
|
3
|
+
|
4
|
+
require 'rubygems'
|
5
|
+
require 'bundler/setup'
|
6
|
+
require 'digits_solver'
|
7
|
+
|
8
|
+
def help(out = STDOUT)
|
9
|
+
out.puts <<EOM
|
10
|
+
To run this program:
|
11
|
+
|
12
|
+
find_nydigits_solution <number to find> <space separated list of numbers>
|
13
|
+
|
14
|
+
This program will solve if possible the NY Digits puzzle.
|
15
|
+
EOM
|
16
|
+
end
|
17
|
+
|
18
|
+
begin
|
19
|
+
raise DigitsSolver::Error, 'Invalid parameters' unless ARGV.size >= 3 && ARGV.size <= 7
|
20
|
+
|
21
|
+
target = ARGV.shift.to_i
|
22
|
+
draw = ARGV.map do |val|
|
23
|
+
raise DigitsSolver::Error, 'Invalid parameters (candidate figures) ! ' unless val == val.to_i.to_s
|
24
|
+
|
25
|
+
val.to_i
|
26
|
+
end
|
27
|
+
puts "Trying to find #{target}"
|
28
|
+
solutions = DigitsSolver.solve_for target, *draw
|
29
|
+
raise DigitsSolver::Error, %q[Couldn't find any solution !] if solutions.sorted_solutions.empty?
|
30
|
+
|
31
|
+
puts "A best solution has been found (total of #{solutions.size} possible solutions found)."
|
32
|
+
puts solutions.best_solution
|
33
|
+
rescue => e
|
34
|
+
STDERR.puts e.message
|
35
|
+
help STDERR
|
36
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
module DigitsSolver
|
3
|
+
class ProblemStatement
|
4
|
+
|
5
|
+
attr_reader :target_number
|
6
|
+
|
7
|
+
def draw
|
8
|
+
@draw.dup
|
9
|
+
end
|
10
|
+
|
11
|
+
def initialize(target_number_or_problem_statement, *draw)
|
12
|
+
@target_number, @draw = if target_number_or_problem_statement.is_a? DigitsSolver::ProblemStatement
|
13
|
+
[target_number_or_problem_statement.target_number, target_number_or_problem_statement.draw]
|
14
|
+
else
|
15
|
+
[target_number_or_problem_statement, draw]
|
16
|
+
end
|
17
|
+
DigitsSolver.logger.info "The target is #{target_number}"
|
18
|
+
DigitsSolver.logger.info "The draw is #{draw.inspect}"
|
19
|
+
end
|
20
|
+
|
21
|
+
def max_operations_number
|
22
|
+
@max_operations_number ||= @draw.size - 1
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,72 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
module DigitsSolver
|
3
|
+
|
4
|
+
class Solution
|
5
|
+
|
6
|
+
include DigitsSolver::Strategies::Base
|
7
|
+
|
8
|
+
attr_reader :problem_statement, :operands, :operations_to_apply
|
9
|
+
|
10
|
+
def initialize(problem_statement, operands, operations_to_apply)
|
11
|
+
raise DigitsSolver::Error, "Invalid problem statement" unless problem_statement.is_a? DigitsSolver::ProblemStatement
|
12
|
+
unless operands.size == operations_to_apply.size + 1
|
13
|
+
raise DigitsSolver::Error, "Invalid solution #{operands.inspect} => #{operations_to_apply.inspect}"
|
14
|
+
end
|
15
|
+
|
16
|
+
DigitsSolver.logger.info "New solution: #{self.inspect}"
|
17
|
+
|
18
|
+
@problem_statement = problem_statement
|
19
|
+
@operands = operands
|
20
|
+
@operations_to_apply = operations_to_apply
|
21
|
+
end
|
22
|
+
|
23
|
+
def ==(other_solution)
|
24
|
+
(operations_to_apply == other_solution.operations_to_apply) && (operands == other_solution.operands)
|
25
|
+
end
|
26
|
+
|
27
|
+
def to_s
|
28
|
+
res = ["Solved in #{operations_to_apply.size} operation#{operations_to_apply.size <= 1 ? '' : 's'}:"]
|
29
|
+
res.concat to_operation_lines
|
30
|
+
res.join "\n"
|
31
|
+
end
|
32
|
+
|
33
|
+
def to_operation_lines
|
34
|
+
res = []
|
35
|
+
operations_to_apply.each.with_index.reduce(operands.first) do |acc, (operation, idx)|
|
36
|
+
computed_result = apply_operation_to_operands operation, acc, operands[idx + 1]
|
37
|
+
res << format(' => %u %s %u = %u',
|
38
|
+
acc,
|
39
|
+
DigitsSolver::Strategies::Base::OPERATIONS[operation],
|
40
|
+
operands[idx + 1],
|
41
|
+
computed_result)
|
42
|
+
computed_result
|
43
|
+
end
|
44
|
+
res
|
45
|
+
end
|
46
|
+
|
47
|
+
def pretty_print(pp)
|
48
|
+
pp.object_address_group(self) do
|
49
|
+
pp.breakable
|
50
|
+
pp.text "Solution: '#{to_evaluable_code} = #{problem_statement.target_number}'"
|
51
|
+
pp.text ','
|
52
|
+
pp.breakable
|
53
|
+
pp.seplist(self.instance_variables) do |v|
|
54
|
+
pp.text "#{v}="
|
55
|
+
pp.pp self.instance_variable_get v
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
def to_evaluable_code
|
61
|
+
res = operations_to_apply.each.with_index.reduce(operands.first) do |res, (operation, idx)|
|
62
|
+
op1 = res
|
63
|
+
op2 = operands[idx + 1]
|
64
|
+
format_string = operation == :multiply ? '%s %s %u' : '(%s %s %u)'
|
65
|
+
format(format_string, op1, DigitsSolver::Strategies::Base::OPERATIONS[operation], op2)
|
66
|
+
end
|
67
|
+
res[-1] == ')' ? res[1...-1] : res
|
68
|
+
end
|
69
|
+
|
70
|
+
end
|
71
|
+
|
72
|
+
end
|
@@ -0,0 +1,76 @@
|
|
1
|
+
module DigitsSolver
|
2
|
+
|
3
|
+
class SolutionSet
|
4
|
+
|
5
|
+
include Enumerable
|
6
|
+
|
7
|
+
DEFAULT_STRATEGY = DigitsSolver::Strategies::BruteForce
|
8
|
+
attr_reader :problem_statement, :strategy
|
9
|
+
|
10
|
+
class << self
|
11
|
+
|
12
|
+
def solve_for(problem_statement, strategy: DEFAULT_STRATEGY)
|
13
|
+
extend strategy
|
14
|
+
solutions = solve(problem_statement)
|
15
|
+
new problem_statement, solutions, strategy
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
19
|
+
|
20
|
+
def each(&block)
|
21
|
+
solutions.each(&block)
|
22
|
+
end
|
23
|
+
|
24
|
+
def sorted_solutions
|
25
|
+
indexed_solutions.keys
|
26
|
+
.sort { |a, b| a.size <=> b.size }
|
27
|
+
.map { |k| indexed_solutions[k] }
|
28
|
+
.flatten
|
29
|
+
end
|
30
|
+
|
31
|
+
def best_solution(nb = 1)
|
32
|
+
res = indexed_solutions.keys
|
33
|
+
.sort { |a, b| a.size <=> b.size }
|
34
|
+
.take(nb)
|
35
|
+
.map { |k| indexed_solutions[k] }
|
36
|
+
.flatten
|
37
|
+
.take(nb)
|
38
|
+
nb == 1 ? res.first : res
|
39
|
+
end
|
40
|
+
alias best_solutions best_solution
|
41
|
+
|
42
|
+
def size
|
43
|
+
solutions.size
|
44
|
+
end
|
45
|
+
|
46
|
+
private
|
47
|
+
|
48
|
+
attr_reader :solutions, :indexed_solutions
|
49
|
+
|
50
|
+
def <<(solution)
|
51
|
+
return nil if solutions.include? solution
|
52
|
+
|
53
|
+
solutions << solution
|
54
|
+
indexed_solutions[solution.operands] ||= []
|
55
|
+
indexed_solutions[solution.operands] << solution
|
56
|
+
solutions
|
57
|
+
end
|
58
|
+
|
59
|
+
def initialize(problem_statement, solutions, strategy)
|
60
|
+
raise DigitsSolver::Error, "Invalid problem statement" unless problem_statement.is_a? DigitsSolver::ProblemStatement
|
61
|
+
|
62
|
+
@problem_statement = problem_statement
|
63
|
+
@strategy = strategy
|
64
|
+
|
65
|
+
@indexed_solutions = {}
|
66
|
+
@solutions = []
|
67
|
+
|
68
|
+
solutions.each do |solution|
|
69
|
+
self << solution
|
70
|
+
end
|
71
|
+
|
72
|
+
end
|
73
|
+
|
74
|
+
end
|
75
|
+
|
76
|
+
end
|
@@ -0,0 +1,77 @@
|
|
1
|
+
module DigitsSolver
|
2
|
+
module Strategies
|
3
|
+
|
4
|
+
module Base
|
5
|
+
|
6
|
+
class OperationError < StandardError; end
|
7
|
+
|
8
|
+
OPERATIONS = {
|
9
|
+
plus: :+,
|
10
|
+
minus: :-,
|
11
|
+
multiply: :*,
|
12
|
+
divide: :/
|
13
|
+
}.freeze
|
14
|
+
|
15
|
+
def solve(_)
|
16
|
+
raise DigitsSolver::Error 'You should not be there !'
|
17
|
+
end
|
18
|
+
|
19
|
+
protected
|
20
|
+
|
21
|
+
def possible_operations_for_ordered_draw(max_operations_number)
|
22
|
+
nb_operations = OPERATIONS.size
|
23
|
+
ops_a = OPERATIONS.to_a
|
24
|
+
number_of_possibilities = nb_operations ** max_operations_number
|
25
|
+
|
26
|
+
DigitsSolver.logger.info "number of operations permutations: #{number_of_possibilities}, nb op: #{nb_operations}"
|
27
|
+
|
28
|
+
(0...number_of_possibilities).map do |i|
|
29
|
+
i.to_s(nb_operations)
|
30
|
+
.ljust(max_operations_number, '0')
|
31
|
+
.chars
|
32
|
+
.map { |operation_index_str| ops_a[operation_index_str.to_i].first }
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def apply_operations_chain_to_ordered_draw(operations_chain, ordered_draw, problem_statement)
|
37
|
+
operations_chain.each.with_index.reduce(ordered_draw.first) do |acc, (operation, idx)|
|
38
|
+
cur_op_res = apply_operation_to_operands(operation, acc, ordered_draw[idx + 1])
|
39
|
+
if cur_op_res == problem_statement.target_number
|
40
|
+
ops = operations_chain.take(idx + 1)
|
41
|
+
operands = ordered_draw.take(idx + 2)
|
42
|
+
yield DigitsSolver::Solution.new(problem_statement, operands, ops)
|
43
|
+
break
|
44
|
+
end
|
45
|
+
cur_op_res
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def apply_operation_to_operands (operation, operand1, operand2)
|
50
|
+
res = send(operation, operand1, operand2)
|
51
|
+
DigitsSolver.logger.debug "#{operand1} #{OPERATIONS[operation]} #{operand2} = #{res}"
|
52
|
+
res
|
53
|
+
end
|
54
|
+
|
55
|
+
def plus(a, b)
|
56
|
+
a + b
|
57
|
+
end
|
58
|
+
|
59
|
+
def minus(a, b)
|
60
|
+
raise DigitsSolver::Strategies::Base::OperationError, "#{a} - #{b} is not allowed as result would be negative" unless a >= b
|
61
|
+
|
62
|
+
a - b
|
63
|
+
end
|
64
|
+
|
65
|
+
def multiply(a, b)
|
66
|
+
a * b
|
67
|
+
end
|
68
|
+
|
69
|
+
def divide(a, b)
|
70
|
+
raise DigitsSolver::Strategies::Base::OperationError, "#{a} / #{b} is not allowed as result would not be an integer" unless a % b == 0
|
71
|
+
|
72
|
+
a / b
|
73
|
+
end
|
74
|
+
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
module DigitsSolver
|
2
|
+
module Strategies
|
3
|
+
|
4
|
+
module BruteForce
|
5
|
+
|
6
|
+
include DigitsSolver::Strategies::Base
|
7
|
+
|
8
|
+
def solve(problem_statement)
|
9
|
+
solutions = []
|
10
|
+
draw = problem_statement.draw
|
11
|
+
possible_operations = possible_operations_for_ordered_draw problem_statement.max_operations_number
|
12
|
+
# DigitsSolver.logger.debug possible_operations.inspect
|
13
|
+
|
14
|
+
draw.permutation.map do |ordered_draw|
|
15
|
+
|
16
|
+
DigitsSolver.logger.debug ordered_draw.inspect
|
17
|
+
possible_operations.each do |operations_chain|
|
18
|
+
DigitsSolver.logger.debug operations_chain.inspect
|
19
|
+
begin
|
20
|
+
apply_operations_chain_to_ordered_draw(operations_chain, ordered_draw, problem_statement) do |valid_solution|
|
21
|
+
solutions << valid_solution
|
22
|
+
end
|
23
|
+
rescue DigitsSolver::Strategies::Base::OperationError => dsboe
|
24
|
+
DigitsSolver.logger.debug "#{ordered_draw.inspect} => #{operations_chain.inspect} is discarded because #{dsboe.message}"
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
29
|
+
DigitsSolver.logger.info "Solutions: #{solutions.inspect}"
|
30
|
+
solutions
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "digits_solver/version"
|
4
|
+
require_relative "digits_solver/error"
|
5
|
+
require_relative "digits_solver/problem_statement"
|
6
|
+
require_relative "digits_solver/strategies/base"
|
7
|
+
require_relative "digits_solver/strategies/brute_force"
|
8
|
+
require_relative "digits_solver/solution"
|
9
|
+
require_relative 'digits_solver/solution_set'
|
10
|
+
|
11
|
+
module DigitsSolver
|
12
|
+
class Error < StandardError; end
|
13
|
+
|
14
|
+
class DummyLogger
|
15
|
+
private
|
16
|
+
|
17
|
+
def respond_to_missing?(method_name, *_)
|
18
|
+
return true if %i[debug info warn error fatal].include? method_name
|
19
|
+
|
20
|
+
super
|
21
|
+
end
|
22
|
+
|
23
|
+
def method_missing(method_name, *args)
|
24
|
+
return if %i[debug info warn error fatal].include? method_name
|
25
|
+
|
26
|
+
super
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
# Your code goes here...
|
31
|
+
|
32
|
+
def self.solve_for(target_number, *draw)
|
33
|
+
problem_statement = DigitsSolver::ProblemStatement.new target_number, *draw
|
34
|
+
DigitsSolver::SolutionSet.solve_for problem_statement
|
35
|
+
end
|
36
|
+
|
37
|
+
def self.logger
|
38
|
+
@logger ||= DigitsSolver::DummyLogger.new
|
39
|
+
end
|
40
|
+
|
41
|
+
def self.logger=(logger)
|
42
|
+
@logger = logger
|
43
|
+
end
|
44
|
+
end
|
metadata
ADDED
@@ -0,0 +1,90 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: digits_solver
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Laurent B.
|
8
|
+
autorequire:
|
9
|
+
bindir: exe
|
10
|
+
cert_chain: []
|
11
|
+
date: 2023-05-01 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: pry
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rspec
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
description: Finds solutions to the NYTimes Digits game.
|
42
|
+
email:
|
43
|
+
- lbnetid+rb@gmail.com
|
44
|
+
executables:
|
45
|
+
- find_nydigits_solutions
|
46
|
+
extensions: []
|
47
|
+
extra_rdoc_files: []
|
48
|
+
files:
|
49
|
+
- ".rspec"
|
50
|
+
- ".rubocop.yml"
|
51
|
+
- Gemfile
|
52
|
+
- README.md
|
53
|
+
- Rakefile
|
54
|
+
- digits_solver.gemspec
|
55
|
+
- exe/find_nydigits_solutions
|
56
|
+
- lib/digits_solver.rb
|
57
|
+
- lib/digits_solver/error.rb
|
58
|
+
- lib/digits_solver/problem_statement.rb
|
59
|
+
- lib/digits_solver/solution.rb
|
60
|
+
- lib/digits_solver/solution_set.rb
|
61
|
+
- lib/digits_solver/strategies/base.rb
|
62
|
+
- lib/digits_solver/strategies/brute_force.rb
|
63
|
+
- lib/digits_solver/version.rb
|
64
|
+
- sig/digits_solver.rbs
|
65
|
+
homepage: https://gitlab.com/coding_exercices/digits_solver
|
66
|
+
licenses: []
|
67
|
+
metadata:
|
68
|
+
allowed_push_host: https://rubygems.org
|
69
|
+
homepage_uri: https://gitlab.com/coding_exercices/digits_solver
|
70
|
+
source_code_uri: https://gitlab.com/coding_exercices/digits_solver
|
71
|
+
post_install_message:
|
72
|
+
rdoc_options: []
|
73
|
+
require_paths:
|
74
|
+
- lib
|
75
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
76
|
+
requirements:
|
77
|
+
- - ">="
|
78
|
+
- !ruby/object:Gem::Version
|
79
|
+
version: 2.6.0
|
80
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
81
|
+
requirements:
|
82
|
+
- - ">="
|
83
|
+
- !ruby/object:Gem::Version
|
84
|
+
version: '0'
|
85
|
+
requirements: []
|
86
|
+
rubygems_version: 3.3.26
|
87
|
+
signing_key:
|
88
|
+
specification_version: 4
|
89
|
+
summary: Solves NYTimes Digits puzzle.
|
90
|
+
test_files: []
|