Project

General

Profile

Feature #9528 ยป the_code.rb

contains it all, including demo - martin_vahi (Martin Vahi), 11/09/2014 06:33 AM

 
1
#!/usr/bin/env ruby
2
#==========================================================================
3

    
4
def x_apply_binary_operator_t1(x_identity_element,ar_in,
5
   func_operator_that_might_be_noncommutative)
6
   # This code is is a slightly edited version of the
7
   # kibuvits_s_concat_array_of_strings(...) core.
8
   # The comments and explanations are mostly there.
9
   #
10
   # May be the following link works:
11
   # https://github.com/martinvahi/mmmv_devel_tools/blob/master/src/bonnet/lib/kibuvits_ruby_library/src/include/kibuvits_str_concat_array_of_strings.rb
12
   #
13
   # If the next link works properly, then there
14
   # might be some demos for string concatenation at
15
   # https://github.com/martinvahi/mmmv_notes/tree/master/mmmv_notes/phenomenon_scrutinization/string_concatenation
16
   #
17
   # The general idea is that from memory
18
   # allocation point of view multiplication
19
   # is similar to string concatenation. An example:
20
   #
21
   #     new_string="100"+"000" # == "100000"
22
   #     new_number= 100 *1000  # ==  100000
23
   #
24
   #------------------------------
25
   cl=ar_in.class
26
   if cl!=Array
27
      raise(Exception.new("ar_in.class=="+cl.to_s+
28
      ", but it is expected to be Array.\n"))
29
   end # if
30
   cl=func_operator_that_might_be_noncommutative.class
31
   if cl!=Proc
32
      raise(Exception.new("func_operator_that_might_be_noncommutative.class=="+cl.to_s+
33
      ", but it is expected to be Proc.\n"))
34
   end # if
35
   #------------------------------
36
   func_oper=func_operator_that_might_be_noncommutative
37
   i_n=ar_in.size
38
   if i_n<3
39
      if i_n==2
40
         x_out=func_oper.call(ar_in[0],ar_in[1])
41
         return x_out
42
      else
43
         if i_n==1
44
            # For the sake of consistency one
45
            # wants to make sure that the returned
46
            # string instance always differs from those
47
            # that are within the ar_in.
48
            x_out=func_oper.call(x_identity_element,ar_in[0])
49
            return x_out
50
         else # i_n==0
51
            x_out=x_identity_element
52
            return x_out
53
         end # if
54
      end # if
55
   end # if
56
   x_out=x_identity_element # needs to be inited to the x_identity_element
57
   ar_1=ar_in
58
   b_ar_1_equals_ar_in=true # to avoid modifying the received Array
59
   ar_2=Array.new
60
   b_take_from_ar_1=true
61
   b_not_ready=true
62
   i_reminder=nil
63
   i_loop=nil
64
   i_ar_in_len=nil
65
   i_ar_out_len=0 # code after the while loop needs a number
66
   x_1=nil
67
   x_2=nil
68
   x_3=nil
69
   i_2=nil
70
   while b_not_ready
71
      # The next if-statement is to avoid copying temporary
72
      # strings between the ar_1 and the ar_2.
73
      if b_take_from_ar_1
74
         i_ar_in_len=ar_1.size
75
         i_reminder=i_ar_in_len%2
76
         i_loop=(i_ar_in_len-i_reminder)/2
77
         i_loop.times do |i|
78
            i_2=i*2
79
            x_1=ar_1[i_2]
80
            x_2=ar_1[i_2+1]
81
            x_3=func_oper.call(x_1,x_2)
82
            ar_2<<x_3
83
         end # loop
84
         if i_reminder==1
85
            x_3=ar_1[i_ar_in_len-1]
86
            ar_2<<x_3
87
         end # if
88
         i_ar_out_len=ar_2.size
89
         if 1<i_ar_out_len
90
            if b_ar_1_equals_ar_in
91
               ar_1=Array.new
92
               b_ar_1_equals_ar_in=false
93
            else
94
               ar_1.clear
95
            end # if
96
         else
97
            b_not_ready=false
98
         end # if
99
      else # b_take_from_ar_1==false
100
         i_ar_in_len=ar_2.size
101
         i_reminder=i_ar_in_len%2
102
         i_loop=(i_ar_in_len-i_reminder)/2
103
         i_loop.times do |i|
104
            i_2=i*2
105
            x_1=ar_2[i_2]
106
            x_2=ar_2[i_2+1]
107
            x_3=func_oper.call(x_1,x_2)
108
            ar_1<<x_3
109
         end # loop
110
         if i_reminder==1
111
            x_3=ar_2[i_ar_in_len-1]
112
            ar_1<<x_3
113
         end # if
114
         i_ar_out_len=ar_1.size
115
         if 1<i_ar_out_len
116
            ar_2.clear
117
         else
118
            b_not_ready=false
119
         end # if
120
      end # if
121
      b_take_from_ar_1=!b_take_from_ar_1
122
   end # loop
123
   if i_ar_out_len==1
124
      if b_take_from_ar_1
125
         x_out=ar_1[0]
126
      else
127
         x_out=ar_2[0]
128
      end # if
129
   else
130
      # The x_out has been inited to "".
131
      if 0<i_ar_out_len
132
         raise Exception.new("This function is flawed."+
133
         "\n GUID='1e84a702-39cb-458b-8728-f24371c06ed7'\n\n")
134
      end # if
135
   end # if
136
   return x_out
137
end # x_apply_binary_operator_t1
138

    
139

    
140
def i_factorial_t1(i_n)
141
   if defined? KIBUVITS_b_DEBUG
142
      if KIBUVITS_b_DEBUG
143
         bn=binding()
144
         # Allowing the i_n to be a Bignum is a bit crazy in 2014,
145
         # but may be in the future that might not be that crazy.
146
         kibuvits_typecheck bn, [Fixnum,Bignum], i_n
147
         kibuvits_assert_is_smaller_than_or_equal_to(bn,0,i_n,
148
         "\n GUID='4289c481-1793-4f01-b3e5-e2700090bed7'\n\n")
149
      end # if
150
   else
151
      # It's up to the final implementers to figure out,
152
      # what, if any, input verification must take place here,
153
      # but, for the time being:
154
      cl=i_n.class
155
      if cl!=Fixnum
156
         if cl!=Bignum
157
            raise(Exception.new("i_n.class=="+cl.to_s+
158
            ", but it is expected to be of some whole number type."))
159
         end # if
160
      end # if
161
      if i_n<0
162
         raise(Exception.new("i_n=="+i_n.to_s+" < 0 ,"+
163
         "but factorials are defined for positive numbers."))
164
      end # if
165
   end # if
166
   i_out=1 # factorial(0)==1
167
   return i_out if i_n==0
168
   func_star=lambda do |x_a,x_b|
169
      x_out=x_a*x_b
170
      return x_out
171
   end # func_star
172
   ar_n=Array.new
173
   # For i_n==2, the ar_n==[0,1,2], ar_n.size==3 .
174
   # To avoid multiplication with 0, ar_n[0]==1 .
175
   # Therefore, for i_n==2, ar_n==[1,2] .
176
   i_n.times{|i| ar_n<<(i+1)} # i starts from 0
177
   x_identity_element=1
178
   i_out=x_apply_binary_operator_t1(
179
   x_identity_element,ar_n,func_star)
180
   return i_out
181
end # i_factorial_t1
182

    
183
class Fixnum
184
   def factorial
185
      i_out=i_factorial_t1(self)
186
      return i_out
187
   end # factorial
188
end # class Fixnum
189

    
190
class Bignum
191
   def factorial
192
      i_out=i_factorial_t1(self)
193
      return i_out
194
   end # factorial
195
end # class Bignum
196

    
197
#--------------------------------------------------------------------------
198

    
199
def i_factorial_old_style(i_n)
200
   i_factorial=1
201
   return i_factorial if (i_n==0)||(i_n==1)
202
   i_n.times do |i|
203
      i_factorial=i_factorial*(i+1)
204
   end # loop
205
   return i_factorial
206
end # i_factorial_old_style
207

    
208
if ARGV.size==0
209
   puts "\n\nFirst console argument must be a whole number.\n\n"
210
   exit
211
end # if
212
i_n=ARGV[0].to_i
213
b_both=false
214
b_old=true
215
b_old=false if 1<ARGV.size
216
b_both=true if ARGV.size==3
217

    
218
if b_old
219
   i_factorial=i_factorial_old_style(i_n)
220
   s_result=i_factorial.to_s
221
   if s_result.length<10
222
      puts "\n\n Factorial of "+i_n.to_s+" by the simplistic algorithm is:\n"+
223
      s_result+"\n\n"
224
   else
225
      puts "\n\n Factorial of "+i_n.to_s+" by the simplistic algorithm \n"+
226
      "has a length of "+s_result.length.to_s+"\n\n"
227
   end # if
228
else
229
   if b_both
230
      i_factorial_old=i_factorial_old_style(i_n)
231
      i_factorial_new=i_n.factorial
232
      if i_factorial_old!=i_factorial_new
233
         puts "\n\nThere's a flaw somewhere.\n\n"
234
      else
235
         puts "\n\nThe results of the proposed algorithm and the \n"+
236
         "simplistic algorithm match.\n\n"
237
      end # if
238
   else
239
      i_factorial=i_n.factorial
240
      s_result=i_factorial.to_s
241
      if s_result.length<10
242
         puts "\n\n Factorial of "+i_n.to_s+" by the proposed algorithm is:\n"+
243
         i_factorial.to_s+"\n\n"
244
      else
245
         puts "\n\n Factorial of "+i_n.to_s+" by the proposed algorithm \n"+
246
         "has a length of "+s_result.length.to_s+"\n\n"
247
      end # if
248
   end # if
249
end # if
250

    
251

    
252
#==========================================================================