PageRenderTime 11ms CodeModel.GetById 1ms app.highlight 5ms RepoModel.GetById 1ms app.codeStats 1ms

/tutorial/pyramid.e

http://github.com/tybor/Liberty
Specman e | 218 lines | 187 code | 16 blank | 15 comment | 12 complexity | ba3a2146bfed2612af4ce3a310fda1ef MD5 | raw file
  1class PYRAMID
  2   --
  3   -- Solving the problem of the Pyramid for small pyramid only.
  4   --
  5   -- This program uses the back-tracking method.
  6   -- Its goal is to try to fill a pyramid by making a subtraction
  7   -- between two successive columns and to take its absolute value.
  8   -- The result is put on the next line.
  9   -- Example:
 10   --  6   14   15   3   13
 11   --    8    1   12  10
 12   --       7   11   2
 13   --         4    9
 14   --            5
 15   --
 16   -- See also pyramid2, which run faster than this first solution.
 17
 18insert
 19   ARGUMENTS
 20      redefine out_in_tagged_out_memory
 21      end
 22
 23create {ANY}
 24   make
 25
 26feature {ANY}
 27   size: INTEGER
 28
 29   make
 30      do
 31         if argument_count = 0 then
 32            std_output.put_string("Want to compute a small pyramid ?%N%
 33                                  %Enter a small number (> 1): ")
 34            std_output.flush
 35            std_input.read_integer
 36            size := std_input.last_integer
 37         else
 38            size := argument(1).to_integer
 39         end
 40         if size <= 1 then
 41            std_output.put_string("You feel sick ?%N")
 42         elseif size > biggest_one then
 43            std_output.put_string("Value too big for this method.%N")
 44         else
 45            create elem.make(1, max)
 46            if fill_up(1) then
 47               std_output.put_string("Full pyramid:%N")
 48               print_on(std_output)
 49            else
 50               std_output.put_string("Unable to fill_up such one.%N")
 51            end
 52         end
 53      end
 54
 55   max: INTEGER
 56      do
 57         Result := size * (size + 1) // 2
 58      end
 59
 60   out_in_tagged_out_memory
 61      local
 62         lig, col, nb: INTEGER
 63      do
 64         from
 65            lig := 1
 66            col := 1
 67            nb := 0
 68         until
 69            nb = max
 70         loop
 71            if col = 1 then
 72               tagged_out_memory.extend('%N')
 73            end
 74            elem.item(indice(lig, col)).append_in(tagged_out_memory)
 75            tagged_out_memory.append(" ")
 76            if col = size - lig + 1 then
 77               col := 1
 78               lig := lig + 1
 79            else
 80               col := col + 1
 81            end
 82
 83            nb := nb + 1
 84         end
 85         tagged_out_memory.extend('%N')
 86      end
 87
 88   belongs_to (nb: INTEGER): BOOLEAN
 89      require
 90         too_small: nb >= 1
 91         too_large: nb <= max
 92      local
 93         i: INTEGER; found: BOOLEAN
 94      do
 95         from
 96            i := 1
 97         until
 98            i > max or found
 99         loop
100            found := nb = elem.item(i)
101            i := i + 1
102         end
103         Result := found
104      end
105
106   propagate (col, val_column_1: INTEGER): BOOLEAN
107      require
108         val_column_1.in_range(1, max)
109         col.in_range(1, size)
110      local
111         stop: BOOLEAN; lig: INTEGER; val: INTEGER
112      do
113         if belongs_to(val_column_1) then
114            Result := False
115         else
116            from
117               elem.put(val_column_1, indice(1, col))
118               lig := 1
119               val := val_column_1
120               stop := False
121               Result := True
122            until
123               stop
124            loop
125               lig := lig + 1
126               if lig > col then
127                  stop := True
128               else
129                  val := val - elem.item(indice(lig - 1, col - lig + 1))
130                  val := val.abs
131                  if belongs_to(val) then
132                     clear_column(col)
133                     stop := True
134                     Result := False
135                  else
136                     elem.put(val, indice(lig, col - lig + 1))
137                  end
138               end
139            end
140         end
141      end
142
143   fill_up (col: INTEGER): BOOLEAN
144      require
145         col >= 1
146      local
147         stop: BOOLEAN; nb: INTEGER
148      do
149         if col > size then
150            Result := True
151         else
152            from
153               stop := False
154               nb := max
155            until
156               stop
157            loop
158               if belongs_to(nb) then
159                  nb := nb - 1
160                  stop := nb = 0
161               elseif propagate(col, nb) then
162                  if fill_up(col + 1) then
163                     stop := True
164                  else
165                     clear_column(col)
166                     nb := nb - 1
167                     stop := nb = 0
168                  end
169               else
170                  nb := nb - 1
171                  stop := nb = 0
172               end
173            end
174            Result := nb > 0
175         end
176      end
177
178feature {}
179   elem: ARRAY[INTEGER]
180
181   case_vide: INTEGER 0
182
183   biggest_one: INTEGER 10
184
185   indice (lig, col: INTEGER): INTEGER
186      require
187         lig_trop_petit: lig >= 1
188         lig_trop_grand: lig <= size
189         col_trop_petit: col >= 1
190         col_trop_grand: col <= size
191      local
192         l: INTEGER
193      do
194         l := size - lig + 1
195         Result := max - l * (l + 1) // 2 + col
196      ensure
197         Result >= 1
198         Result <= max
199      end
200
201   clear_column (col: INTEGER)
202      require
203         col >= 1
204         col <= size
205      local
206         lig: INTEGER
207      do
208         from
209            lig := 1
210         until
211            lig > col
212         loop
213            elem.put(case_vide, indice(lig, col - lig + 1))
214            lig := lig + 1
215         end
216      end
217
218end -- class PYRAMID