<commit_before>function generate (target, range) {
  let arr = []

  while (target > 0) {
    let value = Math.floor(Math.random() * range)
    target -= value
    arr.push({ value })
  }

  return arr
}

function pad (i) {
  if (typeof i === 'number') {
    i = Math.round(i * 1000) / 1000
  }

  return ('          ' + i).slice(-10)
}

//
let strategies = [
  'bestof', 'maximal', 'minimal', 'random', 'proximal', // plain accumulative
  'blackmax', 'blackmin', 'blackrand', // blackjack & accumulative
  '../blackjack', '../accum', '../split', '../'
]

let modules = strategies.map(name => ({ name, f: require('./' + name) }))

function evaluate (algorithm, utxos, targets, feeRate) {
  const nTransactions = targets.length
  let cnc = targets.length
  let feeAccum = 0
  let nOutputs = 0
  let nInputs = 0
  let o = 0

  let utxoMap = {}

  function addUtxo (txo) {
    if (txo.external) return
    utxoMap[o] = { id: o, value: txo.value }

    ++o
    ++nOutputs
  }

  utxos.forEach(addUtxo)

  targets.forEach((target) => {
    let nowUtxos = []
    for (var id in utxoMap) {
      nowUtxos.push(utxoMap[id])
    }

    let { inputs, outputs, fee } = algorithm(nowUtxos, [target], feeRate)
    if (!inputs) return
    feeAccum += fee
    --cnc

    inputs.forEach(x => {
      ++nInputs
      delete utxoMap[x.id]
    })
    outputs.forEach(addUtxo)
  })

  return { feeAccum, nTransactions, nInputs, nOutputs, cnc }
}

let resultMap = {}

for (var m = 1; m < 5; ++m) {
  for (var l = 1; l < 3; ++l) {
    for (var k = 1; k < 3; ++k) {
      let feeRate = 56 / l
      let amount = 300000000 // 3BTC
      let utxos = generate(amount, 40000000 * k) // 0.4BTC max
      let outputs = generate(amount, 2000000 / m) // spend ~54USD max
      outputs.forEach(x => (x.external = true))

      console.log('UTXOS', utxos.length, 'Transactions', outputs.length)

      modules.forEach(({ name, f }) => {
        let x = evaluate(f, utxos, outputs, feeRate)

        if (!resultMap[name]) {
          resultMap[name] = x
          return
        }

        let y = resultMap[name]
        y.feeAccum += x.feeAccum
        y.nTransactions += x.nTransactions
        y.nInputs += x.nInputs
        y.nOutputs += x.nOutputs
        y.cnc += x.cnc
      })
    }
  }
}<commit_msg>stats: lower default number of utxos<commit_after>function generate (target, range) {
  let arr = []

  while (target > 0) {
    let value = Math.floor(Math.random() * range)
    target -= value
    arr.push({ value })
  }

  return arr
}

function pad (i) {
  if (typeof i === 'number') {
    i = Math.round(i * 1000) / 1000
  }

  return ('          ' + i).slice(-10)
}

//
let strategies = [
  'bestof', 'maximal', 'minimal', 'random', 'proximal', // plain accumulative
  'blackmax', 'blackmin', 'blackrand', // blackjack & accumulative
  '../blackjack', '../accum', '../split', '../'
]

let modules = strategies.map(name => ({ name, f: require('./' + name) }))

function evaluate (algorithm, utxos, targets, feeRate) {
  const nTransactions = targets.length
  let cnc = targets.length
  let feeAccum = 0
  let nOutputs = 0
  let nInputs = 0
  let o = 0

  let utxoMap = {}

  function addUtxo (txo) {
    if (txo.external) return
    utxoMap[o] = { id: o, value: txo.value }

    ++o
    ++nOutputs
  }

  utxos.forEach(addUtxo)

  targets.forEach((target) => {
    let nowUtxos = []
    for (var id in utxoMap) {
      nowUtxos.push(utxoMap[id])
    }

    let { inputs, outputs, fee } = algorithm(nowUtxos, [target], feeRate)
    if (!inputs) return
    feeAccum += fee
    --cnc

    inputs.forEach(x => {
      ++nInputs
      delete utxoMap[x.id]
    })
    outputs.forEach(addUtxo)
  })

  return { feeAccum, nTransactions, nInputs, nOutputs, cnc }
}

let resultMap = {}

for (var m = 1; m < 5; ++m) {
  for (var l = 1; l < 3; ++l) {
    for (var k = 1; k < 3; ++k) {
      let feeRate = 56 / l
      let amount = 300000000 // 3BTC
      let utxos = generate(amount, 20000000 * k) // 0.2BTC max
      let outputs = generate(amount, 2000000 / m) // spend ~54USD max
      outputs.forEach(x => (x.external = true))

      console.log('UTXOS', utxos.length, 'Transactions', outputs.length)

      modules.forEach(({ name, f }) => {
        let x = evaluate(f, utxos, outputs, feeRate)

        if (!resultMap[name]) {
          resultMap[name] = x
          return
        }

        let y = resultMap[name]
        y.feeAccum += x.feeAccum
        y.nTransactions += x.nTransactions
        y.nInputs += x.nInputs
        y.nOutputs += x.nOutputs
        y.cnc += x.cnc
      })
    }
  }
}
{'fraction_non_alphanumeric': 0.1585392521320796, 'fraction_numerical': 0.02274218237480866, 'mean_word_length': 2.2624821683309557, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 15, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 4, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '454569', 'n_tokens_mistral': 1769, 'n_tokens_neox': 1651, 'n_words': 423}