math_expr 0.1.0 → 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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e909048f6c47274b8c4661b73c856118ee04bb3790ac4f15f8d5d154e5493888
4
- data.tar.gz: d54004a17b72df3dbe951d396d2d476f6fa6e4be153f8d69298ab16187fbec39
3
+ metadata.gz: 106eec5ec34e60824dc64b24d8a3724594e23306c38590f54dd4910c77471403
4
+ data.tar.gz: f7454b2fec6dc03cc21360393fdc4ca5aea4b5eab0c0a583da6707bf886162d0
5
5
  SHA512:
6
- metadata.gz: 6952fb7b5010b46c42982bfe305199bc8c1307e2368d995d697e47c46caa2a409c3a06e052cd6f04a2e54c8014dbbcf295462735ab5353e6774681bfef61196e
7
- data.tar.gz: df65283ffd5cbd3d8d13ecaf58ac25e8026573420bb95952354467d17afc644c83cab59a71175a87b3841ec63f6593ec1cf203c4a8b40fa4cb08364ad08e5308
6
+ metadata.gz: 7b078aa5ab40eef674aa1a93e7d9d1088fcaba1a92d7650f561b0094fb30889df2ca3be260c0eb3ce2b4dc8268f0e60f0b9de24791daf10bc1dc98514ff20ebe
7
+ data.tar.gz: 9fd738aeccda623343ba4467dce8d17e501e0a304447a0ce5751c01235db9c83e945e365dbb494be2c8bddd8b749a302d806bc7a0a2b2f0f27bf36e5f7a182fb
data/.gitignore CHANGED
@@ -6,3 +6,4 @@
6
6
  /pkg/
7
7
  /spec/reports/
8
8
  /tmp/
9
+ *.gem
data/README.md CHANGED
@@ -1,15 +1,13 @@
1
1
  # MathExpression
2
2
 
3
- Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/math_expression`. To experiment with that code, run `bin/console` for an interactive prompt.
4
-
5
- TODO: Delete this and the text above, and describe your gem
3
+ Parses a mathematical expression from infix notation into reverse polish notation and produces a result.
6
4
 
7
5
  ## Installation
8
6
 
9
7
  Add this line to your application's Gemfile:
10
8
 
11
9
  ```ruby
12
- gem 'math_expression'
10
+ gem 'math_expr'
13
11
  ```
14
12
 
15
13
  And then execute:
@@ -18,11 +16,21 @@ And then execute:
18
16
 
19
17
  Or install it yourself as:
20
18
 
21
- $ gem install math_expression
19
+ $ gem install math_expr
22
20
 
23
21
  ## Usage
24
22
 
25
- TODO: Write usage instructions here
23
+ ```ruby
24
+ require 'math_expression/parser'
25
+
26
+ parser = MathExpression::Parser.new('4 + 5')
27
+
28
+ parser.to_tokens # => [{:type=>:number, :value=>4}, {:type=>:operator, :value=>"+"}, {:type=>:number, :value=>5}]
29
+
30
+ parser.to_postfix # => [4, 5, "+"]
31
+
32
+ parser.evaluate # => 9
33
+ ```
26
34
 
27
35
  ## Development
28
36
 
@@ -11,15 +11,20 @@ class MathExpression::Parser
11
11
 
12
12
  form_number = lambda do
13
13
  return if reading_number.empty?
14
- num = reading_number.join.to_i
14
+ num = reading_number.join.to_f
15
15
  tokens << { type: :number, value: num }
16
16
  reading_number = []
17
17
  end
18
18
 
19
- expression.chars.each do |character|
19
+ printable_chars = expression.chars.reject { |c| c == ' ' }
20
+
21
+ printable_chars.each do |character|
20
22
  if operator?(character)
21
23
  form_number.call
22
- tokens << { type: :operator, value: character}
24
+ tokens << { type: :operator, value: character }
25
+ elsif parenthesis?(character)
26
+ form_number.call
27
+ tokens << { type: :parenthesis, value: character }
23
28
  else
24
29
  reading_number << character
25
30
  end
@@ -33,19 +38,33 @@ class MathExpression::Parser
33
38
  operator_stack = []
34
39
 
35
40
  to_tokens.each do |token|
36
- case token[:type]
41
+ type, value = token[:type], token[:value]
42
+
43
+ case type
37
44
  when :number
38
- output_queue << token[:value]
45
+ output_queue << value
39
46
  when :operator
40
47
  loop do
41
48
  break if operator_stack.empty?
49
+ break if left_parenthesis?(operator_stack.last)
42
50
  operator_on_stack_precedence = operator_precedence(operator_stack.last)
43
- current_operator_precedence = operator_precedence(token[:value])
44
- break if operator_on_stack_precedence < current_operator_precedence
51
+ current_operator_precedence = operator_precedence(value)
52
+ break if operator_on_stack_precedence <= current_operator_precedence
45
53
 
46
54
  output_queue << operator_stack.pop
47
55
  end
48
- operator_stack.push(token[:value])
56
+ operator_stack.push(value)
57
+ when :parenthesis
58
+ if left_parenthesis?(value)
59
+ operator_stack.push(value)
60
+ else
61
+ while !left_parenthesis?(operator_stack.last)
62
+ output_queue << operator_stack.pop
63
+ end
64
+ if left_parenthesis?(operator_stack.last)
65
+ operator_stack.pop
66
+ end
67
+ end
49
68
  end
50
69
  end
51
70
  (output_queue + operator_stack.reverse)
@@ -63,9 +82,10 @@ class MathExpression::Parser
63
82
  when '*'
64
83
  stack.pop * stack.pop
65
84
  when '/'
66
- stack.pop / stack.pop
85
+ first, second = stack.pop, stack.pop
86
+ second / first
67
87
  else
68
- token.to_i
88
+ token.to_f
69
89
  end
70
90
  stack.push(result)
71
91
  end
@@ -74,19 +94,31 @@ class MathExpression::Parser
74
94
 
75
95
  private
76
96
 
77
- OPERATORS = %w(+ - * /).freeze
97
+ OPERATORS = {
98
+ '+' => 2,
99
+ '-' => 2,
100
+ '*' => 3,
101
+ '/' => 3,
102
+ }.freeze
78
103
 
79
104
  def operator?(token)
80
- OPERATORS.include?(token)
105
+ OPERATORS.keys.include?(token)
81
106
  end
82
107
 
83
108
  def operator_precedence(operator)
84
- {
85
- '+' => 2,
86
- '-' => 2,
87
- '*' => 3,
88
- '/' => 3,
89
- }.fetch(operator)
109
+ OPERATORS.fetch(operator)
110
+ end
111
+
112
+ def parenthesis?(token)
113
+ left_parenthesis?(token) || right_parenthesis?(token)
114
+ end
115
+
116
+ def left_parenthesis?(token)
117
+ token == '('
118
+ end
119
+
120
+ def right_parenthesis?(token)
121
+ token == ')'
90
122
  end
91
123
 
92
124
  attr_reader :expression
@@ -1,3 +1,3 @@
1
1
  module MathExpression
2
- VERSION = "0.1.0"
2
+ VERSION = "0.1.1"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: math_expr
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Inclooder
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-05-02 00:00:00.000000000 Z
11
+ date: 2020-05-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rspec