HareNiemeyer

Examples:



#( 12 45 32 12 45) mskFitViaHNTo: 150 precision: 0  -> (12.0 46.0 33.0 13.0 46.0)

#( 12.2 45.4 32.1 12.1 45.8) mskFitViaHNTo: 150 precision: 1  -> (12.4 46.1 32.6 12.3 46.6)

#( 12 45 32 12 45) mskFitViaHNTo: 150 precision: 4  -> (12.3288 46.2329 32.8767 12.3287 46.2329)



!SequenceableCollection publicMethods !

mskFitViaHNTo: newSum precision: digits
 "^ This methods calculates a new sequence of values, which new sum fits
  into the integer argument newSum

  Examples:
   (#( 12 45 32 12 45) mskFitViaHNTo: 150 precision: 4 ) mskGetTotalSum = 150
   (#( 12.0 45.0 32.0 12.0 45.0) mskFitViaHNTo: 150 precision: 4 ) mskGetTotalSum = 150

   #( 12 32) mskFitViaHNTo: 0 precision: 23
 "


 | newResult targetSum oldSum sortedList sumDifference multiplier |

 "we change the values according to the precision one would like to have"
 multiplier := 10 raisedTo: digits.
 targetSum := newSum * multiplier.
 oldSum := self mskGetTotalSum * multiplier.

 "special case - if we have the new total sum of 0 we return a vector of 0"
 (oldSum = 0 or: [  targetSum = 0 ]) ifTrue:[ ^(self class new: self size) atAllPut: 0].

 newResult := (self class new: self size).
 1 to: self size do: [ :anIndex |
  newResult at: anIndex put: ((self at: anIndex) * multiplier)
 ].

 sortedList := SortedCollection sortBlock: [ :a1 :a2 | a1 last > a2 last ].

 1 to: self size do: [ :anIndex |
  | newValue |
  newValue := (targetSum * (newResult at: anIndex) / oldSum) asFloat.
  newResult at: anIndex put: newValue truncated.
  sortedList add: (Array with: anIndex with: newValue fractionPart).
 ].

 sumDifference := targetSum - newResult mskGetTotalSum.
 1 to: sumDifference do: [ :index |
  | newResultIndex |

  newResultIndex := (sortedList at: index) first.
  newResult at: newResultIndex put: ((newResult at: newResultIndex)  + 1).
 ].

 1 to: newResult size do: [ :anIndex |
  newResult at: anIndex put: (((newResult at: anIndex)  / multiplier)) asFloat
 ].

 ^newResult!

mskGetTotalSum
 "^ returns the total sum of number held in the receiver

  Examples:
   #( 12 45 32 12 45) mskGetTotalSum





 "


 ^self inject: 0 into: [ :sum :each | sum + each ]! !
This entry was posted in Smalltalk. Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s