math_expr 0.1.0 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
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