<commit_before>package algorithms

import (
	"bitbucket.org/oakmoundstudio/plasticpiston/plastic/dlog"
	"errors"
	"math/rand"
)

func WeightedChoose(weights []float64, toChoose int) ([]int, error) {
	toChoose_f64 := float64(toChoose)
	lengthWeights := len(weights)
	out := make([]int, toChoose)
	remainingWeights := make([]float64, lengthWeights)
	remainingWeights[lengthWeights-1] = weights[lengthWeights-1]
	for i := lengthWeights - 2; i >= 0; i-- {
		remainingWeights[i] = remainingWeights[i+1] + weights[i]
	}

	for i, v := range remainingWeights {
		if toChoose == 0 {
			return out, nil
		}
		if lengthWeights-i < toChoose {
			//ERROR Out
			return []int{}, errors.New("Tried to choose too many items from a slice")
		}
		if lengthWeights-i == toChoose {
			toChoose--
			toChoose_f64--
			out[toChoose] = i
		} else if rand.Float64() < toChoose_f64/v {
			toChoose--
			toChoose_f64--
			out[toChoose] = i
		}
	}

	return out, nil

}

func ChooseX(weights []float64, times int) []int {
	lengthWeights := len(weights)<commit_msg>Resolved issue where, on account of 'd_' being longer than doodadString[0:1], as slices are non inclusive of their endpoint, all doodads were by default being reloaded as tilesheets of 16x16 tiles, causing distillers to break.<commit_after>package algorithms

import (
	"bitbucket.org/oakmoundstudio/plasticpiston/plastic/dlog"
	"errors"
	"math/rand"
)

//
// This algorithm reacts very poorly to zero or negative weights.
//
func WeightedChoose(weights []float64, toChoose int) ([]int, error) {
	toChoose_f64 := float64(toChoose)
	lengthWeights := len(weights)
	out := make([]int, toChoose)
	remainingWeights := make([]float64, lengthWeights)
	remainingWeights[lengthWeights-1] = weights[lengthWeights-1]
	for i := lengthWeights - 2; i >= 0; i-- {
		remainingWeights[i] = remainingWeights[i+1] + weights[i]
	}

	for i, v := range remainingWeights {
		if toChoose == 0 {
			return out, nil
		}
		if lengthWeights-i < toChoose {
			//ERROR Out
			return []int{}, errors.New("Tried to choose too many items from a slice")
		}
		if lengthWeights-i == toChoose {
			toChoose--
			toChoose_f64--
			out[toChoose] = i
		} else if rand.Float64() < toChoose_f64/v {
			toChoose--
			toChoose_f64--
			out[toChoose] = i
		}
	}

	return out, nil

}

// AKA Roulette search
//
// This algorithm works well, the only issue relative to above
// is that it can choose the same element multiple times, which
// is not always the desired effect.
//
// A version of it could easily be made to only pick each element
// once, however. It would benefit from the linear psuedo-random
// roulette search, where forced increments would happen once an
// index was chosen.
func ChooseX(weights []float64, times int) []int {
	lengthWeights := len(weights)
{'fraction_non_alphanumeric': 0.11962414166967836, 'fraction_numerical': 0.019515720997470183, 'mean_word_length': 3.8055555555555554, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, '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': '5735069', 'n_tokens_mistral': 1055, 'n_tokens_neox': 929, 'n_words': 283}