123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148 |
- <?php
- /**
- * Created by PhpStorm.
- * User: stanley-king
- * Date: 2017/4/20
- * Time: 下午5:12
- */
- namespace bonus;
- class scaler
- {
- const match_rate = 30;
- private $mMoneys;
- private $mMatchMoney;
- public function __construct($rates_moneys)
- {
- $this->mMatchMoney = 0;
- $moneys = [];
- foreach ($rates_moneys as $rate => $money)
- {
- if($rate == self::match_rate) {
- $this->mMatchMoney += $money;
- }
- else {
- $val = [];
- $val['rate'] = $rate;
- $val['amount'] = $money;
- $moneys[] = $val;
- }
- }
- uasort($moneys,['\bonus\scaler','rate_desc']);
- //todo modify usort
- $this->mMoneys = [];
- foreach ($moneys as $item) {
- $this->mMoneys[] = $item;
- }
- }
- private function match_money() {
- return $this->mMatchMoney * 100 / self::match_rate;
- }
- public function calc()
- {
- $total = $this->match_money();
- $count = count($this->mMoneys);
- if($count == 0) {
- return $this->format($total);
- }
- $max_rate = $this->mMoneys[0]['rate'];
- if($max_rate < self::match_rate) {
- return $this->format($total);
- }
- for($pos = $count - 1; $pos >= 0;)
- {
- $ret = $this->_calc($pos);
- if($ret == false) {
- $pos--;
- } else {
- $total += $ret;
- $total = intval($total * 100 + 0.5) / 100;
- return $this->format($total);
- }
- }
- return $this->format($total);
- }
- private function format($total)
- {
- $total = intval($total * 100 + 0.5);
- if($total == 0) {
- return false;
- }
- else {
- return $total / 100;
- }
- }
- private function _calc($pos)
- {
- $rate = $this->mMoneys[$pos]['rate'];
- $amount = $this->mMoneys[$pos]['amount'];
- $y = intval($amount * 100 + 0.5);
- if($rate > self::match_rate)
- { //满足条件,用0折扣红包抵扣
- $this->_calc_AB($pos + 1,$A,$B);
- return $B + ($A* 100 - self::match_rate * $B) / (self::match_rate);
- }
- else
- {
- $this->_calc_AB($pos,$A,$B);
- $need_amount = ($A * 100 - self::match_rate * $B) * $rate / ((self::match_rate - $rate) * 100);
- $x = intval($need_amount * 100 + 0.5);
- if($x < 0) { //此时达不到匹配的折扣率
- return false;
- }
- elseif($x == 0) { //前一个恰好抵扣
- return $B;
- }
- else
- {
- if($x <= $y) { //当前不满足全部抵扣
- return $B + ($x / $rate);
- }
- else { //当前还需要用0折扣红包抵扣
- $this->_calc_AB($pos + 1,$A,$B);
- return $B + ($A * 100 - self::match_rate * $B) / (self::match_rate);
- }
- }
- }
- }
- private function _calc_AB($pos,&$A,&$B)
- {
- $A = 0;
- for ($i = 0; $i < $pos; $i++) {
- $amount = $this->mMoneys[$i]['amount'];
- $A += $amount;
- }
- $B = 0;
- for ($i = 0; $i < $pos; $i++) {
- $amount = $this->mMoneys[$i]['amount'];
- $rate = $this->mMoneys[$i]['rate'];
- $B += $amount * 100 / $rate;
- }
- }
- static public function rate_desc($left,$right)
- {
- $t_l = intval($left['rate']);
- $t_r = intval($right['rate']);
- if($t_l > $t_r) return -1;
- elseif($t_l < $t_r) return 1;
- else return 0;
- }
- }
|