/tutorial/pyramid.e

http://github.com/tybor/Liberty · Specman e · 218 lines · 187 code · 16 blank · 15 comment · 12 complexity · ba3a2146bfed2612af4ce3a310fda1ef MD5 · raw file

  1. class 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. insert
  18. ARGUMENTS
  19. redefine out_in_tagged_out_memory
  20. end
  21. create {ANY}
  22. make
  23. feature {ANY}
  24. size: INTEGER
  25. make
  26. do
  27. if argument_count = 0 then
  28. std_output.put_string("Want to compute a small pyramid ?%N%
  29. %Enter a small number (> 1): ")
  30. std_output.flush
  31. std_input.read_integer
  32. size := std_input.last_integer
  33. else
  34. size := argument(1).to_integer
  35. end
  36. if size <= 1 then
  37. std_output.put_string("You feel sick ?%N")
  38. elseif size > biggest_one then
  39. std_output.put_string("Value too big for this method.%N")
  40. else
  41. create elem.make(1, max)
  42. if fill_up(1) then
  43. std_output.put_string("Full pyramid:%N")
  44. print_on(std_output)
  45. else
  46. std_output.put_string("Unable to fill_up such one.%N")
  47. end
  48. end
  49. end
  50. max: INTEGER
  51. do
  52. Result := size * (size + 1) // 2
  53. end
  54. out_in_tagged_out_memory
  55. local
  56. lig, col, nb: INTEGER
  57. do
  58. from
  59. lig := 1
  60. col := 1
  61. nb := 0
  62. until
  63. nb = max
  64. loop
  65. if col = 1 then
  66. tagged_out_memory.extend('%N')
  67. end
  68. elem.item(indice(lig, col)).append_in(tagged_out_memory)
  69. tagged_out_memory.append(" ")
  70. if col = size - lig + 1 then
  71. col := 1
  72. lig := lig + 1
  73. else
  74. col := col + 1
  75. end
  76. nb := nb + 1
  77. end
  78. tagged_out_memory.extend('%N')
  79. end
  80. belongs_to (nb: INTEGER): BOOLEAN
  81. require
  82. too_small: nb >= 1
  83. too_large: nb <= max
  84. local
  85. i: INTEGER; found: BOOLEAN
  86. do
  87. from
  88. i := 1
  89. until
  90. i > max or found
  91. loop
  92. found := nb = elem.item(i)
  93. i := i + 1
  94. end
  95. Result := found
  96. end
  97. propagate (col, val_column_1: INTEGER): BOOLEAN
  98. require
  99. val_column_1.in_range(1, max)
  100. col.in_range(1, size)
  101. local
  102. stop: BOOLEAN; lig: INTEGER; val: INTEGER
  103. do
  104. if belongs_to(val_column_1) then
  105. Result := False
  106. else
  107. from
  108. elem.put(val_column_1, indice(1, col))
  109. lig := 1
  110. val := val_column_1
  111. stop := False
  112. Result := True
  113. until
  114. stop
  115. loop
  116. lig := lig + 1
  117. if lig > col then
  118. stop := True
  119. else
  120. val := val - elem.item(indice(lig - 1, col - lig + 1))
  121. val := val.abs
  122. if belongs_to(val) then
  123. clear_column(col)
  124. stop := True
  125. Result := False
  126. else
  127. elem.put(val, indice(lig, col - lig + 1))
  128. end
  129. end
  130. end
  131. end
  132. end
  133. fill_up (col: INTEGER): BOOLEAN
  134. require
  135. col >= 1
  136. local
  137. stop: BOOLEAN; nb: INTEGER
  138. do
  139. if col > size then
  140. Result := True
  141. else
  142. from
  143. stop := False
  144. nb := max
  145. until
  146. stop
  147. loop
  148. if belongs_to(nb) then
  149. nb := nb - 1
  150. stop := nb = 0
  151. elseif propagate(col, nb) then
  152. if fill_up(col + 1) then
  153. stop := True
  154. else
  155. clear_column(col)
  156. nb := nb - 1
  157. stop := nb = 0
  158. end
  159. else
  160. nb := nb - 1
  161. stop := nb = 0
  162. end
  163. end
  164. Result := nb > 0
  165. end
  166. end
  167. feature {}
  168. elem: ARRAY[INTEGER]
  169. case_vide: INTEGER 0
  170. biggest_one: INTEGER 10
  171. indice (lig, col: INTEGER): INTEGER
  172. require
  173. lig_trop_petit: lig >= 1
  174. lig_trop_grand: lig <= size
  175. col_trop_petit: col >= 1
  176. col_trop_grand: col <= size
  177. local
  178. l: INTEGER
  179. do
  180. l := size - lig + 1
  181. Result := max - l * (l + 1) // 2 + col
  182. ensure
  183. Result >= 1
  184. Result <= max
  185. end
  186. clear_column (col: INTEGER)
  187. require
  188. col >= 1
  189. col <= size
  190. local
  191. lig: INTEGER
  192. do
  193. from
  194. lig := 1
  195. until
  196. lig > col
  197. loop
  198. elem.put(case_vide, indice(lig, col - lig + 1))
  199. lig := lig + 1
  200. end
  201. end
  202. end -- class PYRAMID