File size: 1,347 Bytes
9438a57
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
/**
 * Tutarı (kuruş, tam sayı) oranlara göre paylaştırır. Artan kuruşlar en büyük kalan
 * yöntemiyle dağıtılır (eşitlikte önce gelen pay); toplam her zaman korunur.
 */
export function allocate(amount: number, ratios: number[]): number[] {
  if (!Number.isInteger(amount) || amount < 0) throw new TypeError('amount negatif olmayan tam sayı (kuruş) olmalı');
  if (ratios.length === 0) throw new RangeError('en az bir oran gerekli');
  if (ratios.some((r) => r < 0)) throw new RangeError('oranlar negatif olamaz');
  const total = ratios.reduce((a, b) => a + b, 0);
  if (total === 0) throw new RangeError('oranların toplamı sıfır olamaz');

  const exact = ratios.map((r) => (amount * r) / total);
  const shares = exact.map((x) => Math.floor(x));
  const remainder = amount - shares.reduce((a, b) => a + b, 0);
  const order = exact
    .map((x, i) => ({ i, frac: x - Math.floor(x) }))
    .sort((a, b) => b.frac - a.frac || a.i - b.i);
  for (let k = 0; k < remainder; k++) shares[order[k].i] += 1;
  return shares;
}

/** Tutarı `parts` eşit paya böler; artan kuruşlar baştaki paylara gider. */
export function splitEvenly(amount: number, parts: number): number[] {
  if (!Number.isInteger(parts) || parts < 1) throw new RangeError('parts en az 1 olmalı');
  return allocate(amount, new Array(parts).fill(1));
}