Small Straight (Yahtzee) Algorithm - javascript

I have created a working javascript function to check an array of 5 numbers for a small straight, in a Yahtzee game I'm making. I've tested it to no end and I'm confident it works 100% of the time, but it is also probably the worst algorithm of all time in terms of being efficient. Here is what it looks like:
function calcSmstraight() {
var sum = 0;
var r = new Array();
var r2 = new Array();
var counter = 0;
var temp;
var bool = false;
var bool2 = false;
r[0] = document.getElementById('setKeep1').value;
r[1] = document.getElementById('setKeep2').value;
r[2] = document.getElementById('setKeep3').value;
r[3] = document.getElementById('setKeep4').value;
r[4] = document.getElementById('setKeep5').value;
// Move non-duplicates to new array
r2[0] = r[0];
for(var i=0; i<r.length; i++) {
for(var j=0; j<r2.length; j++) {
if(r[i] == r2[j]) {
bool2 = true; // Already in new list
}
}
// Add to new list if not already in it
if(!bool2) {
r2.push(r[i]);
}
bool2 = false;
}
// Make sure list has at least 4 different numbers
if(r2.length >= 4) {
// Sort dice from least to greatest
while(counter < r2.length) {
if(r2[counter] > r2[counter+1]) {
temp = r2[counter];
r2[counter] = r2[counter+1];
r2[counter+1] = temp;
counter = 0;
} else {
counter++;
}
}
// Check if the dice are in order
if(((r2[0] == (r2[1]-1)) && (r2[1] == (r2[2]-1)) && (r2[2] == (r2[3]-1)))
|| ((r2[1] == (r2[2]-1)) && (r2[2] == (r2[3]-1)) && (r2[3] == (r2[4]-1)))) {
bool = true;
}
}
if(bool) {
// If small straight give 30 points
sum = 30;
}
return sum;
}
My strategy is to:
1) Remove duplicates by adding numbers to a new array as they occur
2) Make sure the new array is at least 4 in length (4 different numbers)
3) Sort the array from least to greatest
4) Check if the first 4 OR last 4 (if 5 in length) numbers are in order
My question:
Does anyone know a way that I can improve this method? It seems ridiculously terrible to me but I can't think of a better way to do this and it at least works.

Given that you're implementing a Yahtzee game you presumably need to test for other patterns beyond just small straights, so it would be better to create the array of values before calling the function so that you can use them in all tests, rather than getting the values from the DOM elements inside the small straight test.
Anyway, here's the first way that came to my mind to test for a small straight within an array representing the values of five six-sided dice:
// assume r is an array with the values from the dice
r.sort();
if (/1234|2345|3456/.test(r.join("").replace(/(.)\1/,"$1") {
// is a small straight
}
Note that you can sort an array of numbers using this code:
r2.sort(function(a,b){return a-b;});
...but in your case the values in the array are strings because they came from the .value attribute of DOM elements, so a default string sort will work with r2.sort(). Either way you don't need your own sort routine, because JavaScript provides one.
EDIT: If you assume that you can just put the five values as a string as above you can implement tests for all possible combinations as a big if/else like this:
r.sort();
r = r.join("");
if (/(.)\1{4}/.test(r)) {
alert("Five of a Kind");
} else if (/(.)\1{3}/.test(r)) {
alert("Four of a Kind");
} else if (/(.)\1{2}(.)\2|(.)\3(.)\4{2}/.test(r)) {
alert("Full House");
} else if (/(.)\1{2}/.test(r)) {
alert("Three of a Kind");
} else if (/1234|2345|3456/.test( r.replace(/(.)\1/,"$1") ) {
alert("Small Straight");
} // etc.
Demo: http://jsfiddle.net/4Qzfw/

Why don't you just have a six-element array of booleans indicating whether a number is present, then check 1-4, 2-5, and 3-6 for being all true? In pseudocode:
numFlags = array(6);
foreach(dice)
numFlags[die.value-1] = true;
if(numFlags[0] && numFlags[1] && numFlags[2] && numFlags[3]) return true
//Repeat for 1-4 and 2-5
return false
This wouldn't be a useful algorithm if you were using million-sided dice, but for six-siders there are only three possible small straights to check for, so it's simple and straightforward.

I do not play Yahtzee, but I do play cards, and it would appear the algorithm might be similar. This routine, written in ActionScript (my JavaScript is a bit rusty) has been compiled but not tested. It should accept 5 cards for input, and return a message for either straights greater than 3 cards or pairs or higher.
private function checkCards(card1:int,card2:int,card3:int,card4:int,card5:int):String
{
// Assumes that the 5 cards have a value between 0-12 (Ace-King)
//The key to the routine is using the card values as pointers into an array of possible card values.
var aryCardValues:Array = new Array(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
aryCardValues[card1] += 1;
aryCardValues[card1] += 1;
aryCardValues[card1] += 1;
aryCardValues[card1] += 1;
aryCardValues[card1] += 1;
var aryCardNames:Array = new Array("Ace", "2", "3", "4", "5", "6", "7", "8", "9", "10", "Jack", "Queen", "King");
var strOutMessage:String;
var intCardCount:int = 0;
var strSeperator:String;
var strHighCard:String;
for (var i:int = 0;i < aryCardValues.length;i++)
{
//Check for runs of three of a kind or greater.
if (aryCardValues[i] >= 2)
{
strOutMessage = strOutMessage + strSeperator + i + "-" + aryCardNames[i] + "s";
strSeperator = " & ";
}
//Check for values in a straight.
if (aryCardValues[i] > 0)
{
intCardCount++;
if (intCardCount > 3)strHighCard = aryCardNames[i];
}
else
{
if (intCardCount < 3)intCardCount = 0;
}
}
if (intCardCount > 3) strOutMessage = intCardCount + " run " + strHighCard + " High."
return strOutMessage;
}
It may not be as concise as the regular expressions used above, but it might be more readable and easily modified. One change that could be made is to pass in an array of cards rather than discrete variables for each card.

Related

How do I check if 2 numbers are the same from Math.random [duplicate]

Can't seem to find an answer to this, say I have this:
setInterval(function() {
m = Math.floor(Math.random()*7);
$('.foo:nth-of-type('+m+')').fadeIn(300);
}, 300);
How do I make it so that random number doesn't repeat itself. For example if the random number is 2, I don't want 2 to come out again.
There are a number of ways you could achieve this.
Solution A:
If the range of numbers isn't large (let's say less than 10), you could just keep track of the numbers you've already generated. Then if you generate a duplicate, discard it and generate another number.
Solution B:
Pre-generate the random numbers, store them into an array and then go through the array. You could accomplish this by taking the numbers 1,2,...,n and then shuffle them.
shuffle = function(o) {
for(var j, x, i = o.length; i; j = parseInt(Math.random() * i), x = o[--i], o[i] = o[j], o[j] = x);
return o;
};
var randorder = shuffle([0,1,2,3,4,5,6]);
var index = 0;
setInterval(function() {
$('.foo:nth-of-type('+(randorder[index++])+')').fadeIn(300);
}, 300);
Solution C:
Keep track of the numbers available in an array. Randomly pick a number. Remove number from said array.
var randnums = [0,1,2,3,4,5,6];
setInterval(function() {
var m = Math.floor(Math.random()*randnums.length);
$('.foo:nth-of-type('+(randnums[m])+')').fadeIn(300);
randnums = randnums.splice(m,1);
}, 300);
You seem to want a non-repeating random number from 0 to 6, so similar to tskuzzy's answer:
var getRand = (function() {
var nums = [0,1,2,3,4,5,6];
var current = [];
function rand(n) {
return (Math.random() * n)|0;
}
return function() {
if (!current.length) current = nums.slice();
return current.splice(rand(current.length), 1);
}
}());
It will return the numbers 0 to 6 in random order. When each has been drawn once, it will start again.
could you try that,
setInterval(function() {
m = Math.floor(Math.random()*7);
$('.foo:nth-of-type(' + m + ')').fadeIn(300);
}, 300);
I like Neal's answer although this is begging for some recursion. Here it is in java, you'll still get the general idea. Note that you'll hit an infinite loop if you pull out more numbers than MAX, I could have fixed that but left it as is for clarity.
edit: saw neal added a while loop so that works great.
public class RandCheck {
private List<Integer> numbers;
private Random rand;
private int MAX = 100;
public RandCheck(){
numbers = new ArrayList<Integer>();
rand = new Random();
}
public int getRandomNum(){
return getRandomNumRecursive(getRand());
}
private int getRandomNumRecursive(int num){
if(numbers.contains(num)){
return getRandomNumRecursive(getRand());
} else {
return num;
}
}
private int getRand(){
return rand.nextInt(MAX);
}
public static void main(String[] args){
RandCheck randCheck = new RandCheck();
for(int i = 0; i < 100; i++){
System.out.println(randCheck.getRandomNum());
}
}
}
Generally my approach is to make an array containing all of the possible values and to:
Pick a random number <= the size of the array
Remove the chosen element from the array
Repeat steps 1-2 until the array is empty
The resulting set of numbers will contain all of your indices without repetition.
Even better, maybe something like this:
var numArray = [0,1,2,3,4,5,6];
numArray.shuffle();
Then just go through the items because shuffle will have randomized them and pop them off one at a time.
Here's a simple fix, if a little rudimentary:
if(nextNum == lastNum){
if (nextNum == 0){nextNum = 7;}
else {nextNum = nextNum-1;}
}
If the next number is the same as the last simply minus 1 unless the number is 0 (zero) and set it to any other number within your set (I chose 7, the highest index).
I used this method within the cycle function because the only stipulation on selecting a number was that is musn't be the same as the last one.
Not the most elegant or technically gifted solution, but it works :)
Use sets. They were introduced to the specification in ES6. A set is a data structure that represents a collection of unique values, so it cannot include any duplicate values. I needed 6 random, non-repeatable numbers ranging from 1-49. I started with creating a longer set with around 30 digits (if the values repeat the set will have less elements), converted the set to array and then sliced it's first 6 elements. Easy peasy. Set.length is by default undefined and it's useless that's why it's easier to convert it to an array if you need specific length.
let randomSet = new Set();
for (let index = 0; index < 30; index++) {
randomSet.add(Math.floor(Math.random() * 49) + 1)
};
let randomSetToArray = Array.from(randomSet).slice(0,6);
console.log(randomSet);
console.log(randomSetToArray);
An easy way to generate a list of different numbers, no matter the size or number:
function randomNumber(max) {
return Math.floor(Math.random() * max + 1);
}
const list = []
while(list.length < 10 ){
let nbr = randomNumber(500)
if(!list.find(el => el === nbr)) list.push(nbr)
}
console.log("list",list)
I would like to add--
var RecordKeeper = {};
SRandom = function () {
currTimeStamp = new Date().getTime();
if (RecordKeeper.hasOwnProperty(currTimeStamp)) {
RecordKeeper[currTimeStamp] = RecordKeeper[currTimeStamp] + 1;
return currTimeStamp.toString() + RecordKeeper[currTimeStamp];
}
else {
RecordKeeper[currTimeStamp] = 1;
return currTimeStamp.toString() + RecordKeeper[currTimeStamp];
}
}
This uses timestamp (every millisecond) to always generate a unique number.
you can do this. Have a public array of keys that you have used and check against them with this function:
function in_array(needle, haystack)
{
for(var key in haystack)
{
if(needle === haystack[key])
{
return true;
}
}
return false;
}
(function from: javascript function inArray)
So what you can do is:
var done = [];
setInterval(function() {
var m = null;
while(m == null || in_array(m, done)){
m = Math.floor(Math.random()*7);
}
done.push(m);
$('.foo:nth-of-type('+m+')').fadeIn(300);
}, 300);
This code will get stuck after getting all seven numbers so you need to make sure it exists after it fins them all.

Random lottery number generator

What I'm trying to do is generate 6 random numbers, five in a range of 1-45 and one in a range of 1-25 for a Greek lottery game (Tzoker). The first 5 numbers should be unique. By pressing a button, I want to add these numbers to a div using jQuery (I have some working code for this part).
I thought it would be pretty easy using a loop, but I've found myself unable to check if the number generated already exists. The loop would only contain the first 5 numbers, because the last number can be equal to one of the other 5.
Let me propose you some simpler solution.
Make a list of all numbers from 1 to 45.
Sort the list using Math.random (plus minus something, read the docs of Array.sort to find out) as the comparison function. You will get the list in random order.
Take 5 first items from the list.
Then, when you already have the numbers, put them all into your div.
This way you don't mix your logic (getting the numbers) with your presentation (putting stuff into the DOM).
I leave the implementation as an exercise for the reader. :)
Like this?
$(function() {
$('button').on('click', function(e) {
e.preventDefault();
var numArray = [];
while( numArray.length < 5 ) {
var number = Math.floor((Math.random() * 45 ) + 1);
if( $.inArray( number, numArray ) == -1 ) {
numArray.push( number );
}
}
numArray.push( Math.floor((Math.random() * 25 ) + 1) );
$('div').html( numArray.join("<br />") );
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button>Generate</button>
<div></div>
While this might be not exactly what you were asking for, if you would use lodash, this would be as simple as:
_.sample(_.range(1, 46), 5) // the 5 numbers from 1..45
_.random(1, 26) // one more from 1..25
This is why functional programming is so cool. You can read for example Javascript Allonge to find out more.
http://jsfiddle.net/015d05uu/
var tzoker = $("#tzoker");
var results = $("#results");
tzoker.click(function() {
results.empty();
var properResults = [];
var rand = 0;
var contains = false;
for (i = 1; i < 7; i++) {
do
{
(rand = Math.floor((Math.random() * (i != 6 ? 45 : 25)) + 1));
contains = properResults.indexOf(rand) > -1;
} while(contains)
results.append("<br />", rand, "<br />");
properResults.push(rand);
}
});
Here is the main idea of a solution. You can define the max value as a parameter for the random.
Then, check the existence of the item in a simple array with only the data you want.
You may use a general function which generates random numbers from 1 to maxValue, and adds them to an array only if they don't exist. Then, to display, cycle through the array items and append them to #randomNumbers.
HTML
<div id="randomNumbers"></div>
JS (with jQuery)
var randomNumbersArray = [];
$(function() {
generateRandomNumbers();
displayRandomNumbers();
});
function generateRandomNumbers() {
for (i = 0; i < 5; i++) {
generateRandomNumberFrom1To(45);
}
generateRandomNumberFrom1To(25);
}
function generateRandomNumberFrom1To(maxValue) {
var randomNumber;
do {
randomNumber = Math.ceil(Math.random() * maxValue);
} while ($.inArray(randomNumber, randomNumbersArray) > -1);
randomNumbersArray.push(randomNumber);
}
function displayRandomNumbers() {
for (i in randomNumbersArray) {
$("#randomNumbers").append(randomNumbersArray[i] + "<br>");
}
}

Can't figure out parseInt, even after research in JS and JQ [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question appears to be off-topic because it lacks sufficient information to diagnose the problem. Describe your problem in more detail or include a minimal example in the question itself.
Closed 8 years ago.
Improve this question
I have an object with a property containing a large string. This property has a value with random numbers generated earlier in the script in the format x , x , x , x ... (isn't and can't be an array because of other needs for the variable within the program) and so on. I am trying to get the sum of these numbers and my first thought was to use parseInt() to do this by splitting them all up then adding them together, but when I do this it only returns the first number. Is this what I should do but I'm just doing it wrong? Or is there another function that would make this easier?
The program is a blackjack game I'm making to see how well i understand everything I am learning.
Here is the function i am trying to make to see if the user busts when taking a hit (not much so far because i can't figure out the parseInt thing)
'
function checkBust() {
var total = parseInt(user.hand, 10);
}
'
the user object
'
var user = {
hand: dealUser()
};
'
and the functions to set the object property
function randomCard() {
// random number between 0 and 10
var j = Math.random() * 10;
// round that number into a var called card
var card = Math.round(j);
// if card is 0, assign a J Q or K by making a random number again
if (card === 0) {
//another random number
var k = Math.random() * 10;
// checks random number and assign J Q or K
if (k <= 4) {
card = 'J';
} else if (k <= 7) {
card = 'Q';
}
else {
card = 'K';
}
}
// value of the function is a single card
return card;
}
function dealUser() {
// empty array to store cards
var x = [];
// var to start for loop
var i = 0;
// start for loop
for (i; i < 2; i++) {
// add a random card to the i^th index of x
x[i] = randomCard();
}
// value for function is array of two cards x[0] , x[1]
var cards = x[0] + " , " + x[1];
return cards;
}
parseInt will stop parsing when it reaches a non numeric character.
parseInt('1234,5678', 10); // => 1234
// since a comma (,) is not a numeric character, everything after is ignored.
You have to split the string into an array of strings using the comma as the delimiter:
'1234,5678'.split(','); // => ['1234', '5678'];
Then parse each element of the array to convert them to numbers and then you can sum them.
Here's how I'd do it:
var nums = "1,2,3,4,5";
var sum = nums.split(',').reduce(function(memo, num) {
return memo + parseInt(num, 10);
}, 0);
console.log(sum); // => 15
That should work. See jsbin example.
Note the split parameter needs to match the delimiters you use in your string. for this example ',' is appropriate. For your example you might need /\s*,\s*/.
Unrelated
Since you provided an example of code I can see that you're spending a lot of effort attempting to duck punch and transform the values to the types you need instead of exposing the types in an object. Might I suggest:
function Stack(cards) {
this.cards = cards || [];
}
Stack.prototype.toString = function() {
return this.cards.join(' , ');
};
Stack.prototype.sum = function() {
return this.cards.reduce(function(memo, card) {
return memo + parseInt(card, 10);
}, 0);
};
function randomCard() {
return Math.floor(Math.random() * 13) + 1;
}
Stack.dealHand = function() {
var card1 = randomCard(), card2;
do { card2 = randomCard(); } while (card1 === card2);
return new Stack([card1, card2]);
};
// Example
var hand = Stack.dealHand();
console.log(hand + ' = ' + hand.sum()); // => '3 , 11 = 14'

Advice on how to code Luhn Credit Card validation with Javascript?

I'm pretty awful at Javascript as I've just started learning.
I'm doing a Luhn check for a 16-digit credit card.
It's driving me nuts and I'd just appreciate if someone looked over it and could give me some help.
<script>
var creditNum;
var valid = new Boolean(true);
creditNum = prompt("Enter your credit card number: ");
if((creditNum==null)||(creditNum=="")){
valid = false;
alert("Invalid Number!\nThere was no input.");
}else if(creditNum.length!=16){
valid = false;
alert("Invalid Number!\nThe number is the wrong length.");
}
//Luhn check
var c;
var digitOne;
var digitTwo;
var numSum;
for(i=0;i<16;i+2){
c = creditNum.slice(i,i+1);
if(c.length==2){
digitOne = c.slice(0,1);
digitTwo = c.slice(1,2);
numSum = numSum + (digitOne + digitTwo);
}else{
numSum = numSum + c;
}
}
if((numSum%10)!=0){
alert("Invalid Number!");
}else{
alert("Credit Card Accepted!");
}
</script>
The immediate problem in your code is your for loop. i+2 is not a proper third term. From the context, you're looking for i = i + 2, which you can write in shorthand as i += 2.
It seems your algorithm is "take the 16 digits, turn them into 8 pairs, add them together, and see if the sum is divisible by 10". If that's the case, you can massively simplify your loop - you never need to look at the tens' place, just the units' place.
Your loop could look like this and do the same thing:
for (i = 1; i < 16; i +=2) {
numSum += +creditNum[i];
}
Also, note that as long as you're dealing with a string, you don't need to slice anything at all - just use array notation to get each character.
I added a + in front of creditNum. One of the issues with javascript is that it will treat a string as a string, so if you have string "1" and string "3" and add them, you'll concatenate and get "13" instead of 4. The plus sign forces the string to be a number, so you'll get the right result.
The third term of the loop is the only blatant bug I see. I don't actually know the Luhn algorithm, so inferred the rest from the context of your code.
EDIT
Well, it would have helped if you had posted what the Luhn algorithm is. Chances are, if you can at least articulate it, you can help us help you code it.
Here's what you want.
// Luhn check
function luhnCheck(sixteenDigitString) {
var numSum = 0;
var value;
for (var i = 0; i < 16; ++i) {
if (i % 2 == 0) {
value = 2 * sixteenDigitString[i];
if (value >= 10) {
value = (Math.floor(value / 10) + value % 10);
}
} else {
value = +sixteenDigitString[i];
}
numSum += value;
}
return (numSum % 10 == 0);
}
alert(luhnCheck("4111111111111111"));
What this does is go through all the numbers, keeping the even indices as they are, but doubling the odd ones. If the doubling is more than nine, the values of the two digits are added together, as per the algorithm stated in wikipedia.
FIDDLE
Note: the number I tested with isn't my credit card number, but it's a well known number you can use that's known to pass a properly coded Luhn verification.
My below solution will work on AmEx also. I submitted it for a code test a while ago. Hope it helps :)
function validateCard(num){
var oddSum = 0;
var evenSum = 0;
var numToString = num.toString().split("");
for(var i = 0; i < numToString.length; i++){
if(i % 2 === 0){
if(numToString[i] * 2 >= 10){
evenSum += ((numToString[i] * 2) - 9 );
} else {
evenSum += numToString[i] * 2;
}
} else {
oddSum += parseInt(numToString[i]);
}
}
return (oddSum + evenSum) % 10 === 0;
}
console.log(validateCard(41111111111111111));
Enjoy - Mitch from https://spangle.com.au
#Spangle, when you're using even and odd here, you're already considering that index 0 is even? So you're doubling the digits at index 0, 2 and so on and not the second position, fourth and so on.. Is that intentional? It's returning inconsistent validations for some cards here compared with another algorithm I'm using. Try for example AmEx's 378282246310005.

Coming Up with a Good Algorithm for a Simple Idea

I need to come up with an algorithm that does the following:
Lets say you have an array of positive numbers (e.g. [1,3,7,0,0,9]) and you know beforehand their sum is 20.
You want to abstract some average amount from each number such that the new sum would be less by 7.
To do so, you must follow these rules:
you can only subtract integers
the resulting array must not have any negative values
you can not make any changes to the indices of the buckets.
The more uniformly the subtraction is distributed over the array the better.
Here is my attempt at an algorithm in JavaScript + underscore (which will probably make it n^2):
function distributeSubtraction(array, goal){
var sum = _.reduce(arr, function(x, y) { return x + y; }, 0);
if(goal < sum){
while(goal < sum && goal > 0){
var less = ~~(goal / _.filter(arr, _.identity).length); //length of array without 0s
arr = _.map(arr, function(val){
if(less > 0){
return (less < val) ? val - less : val; //not ideal, im skipping some!
} else {
if(goal > 0){ //again not ideal. giving preference to start of array
if(val > 0) {
goal--;
return val - 1;
}
} else {
return val;
}
}
});
if(goal > 0){
var newSum = _.reduce(arr, function(x, y) { return x + y; }, 0);
goal -= sum - newSum;
sum = newSum;
} else {
return arr;
}
}
} else if(goal == sum) {
return _.map(arr, function(){ return 0; });
} else {
return arr;
}
}
var goal = 7;
var arr = [1,3,7,0,0,9];
var newArray = distributeSubtraction(arr, goal);
//returned: [0, 1, 5, 0, 0, 7];
Well, that works but there must be a better way! I imagine the run time of this thing will be terrible with bigger arrays and bigger numbers.
edit: I want to clarify that this question is purely academic. Think of it like an interview question where you whiteboard something and the interviewer asks you how your algorithm would behave on a different type of a dataset.
It sounds like you want to subtract a weighted amount from each number. I.E you want to subtract X/sum * amount_to_subtract from each item. You would of course need to round the amount your subtracting. The problem is then making sure that you've subtracted the total correct amount. Also, this depends on your input: are you guaranteeing that that the amount you want to subtract can be subtracted? Here's a rough python implementation, (I think):
def uniform_array_reduction(inp, amount):
total = sum(inp)
if amount > total:
raise RuntimeError('Can\'t remove more than there is')
if amount == total: #special case
return [0] * len(inp)
removed = 0
output = []
for i in inp:
if removed < amount:
to_remove = int(round(float(i)/float(total)*float(amount)))
output.append(i - to_remove)
removed += to_remove
else:
output.append(i)
# if we didn't remove enough, just remove 1 from
# each element until we've hit our mark.
# shouldn't require more than one pass
while removed < amount:
for i in range(len(output)):
if output[i] > 0:
output[i] -= 1
removed += 1
if removed == amount:
break
return output
EDIT: I've fixed a few bugs in the code.
s = Sum(x) - required_sum
do:
a = ceil( s/number_of_non_zeros(x) )
For i=1 to length(x):
v = min(a, x[i], s)
x[i]-=v
s-=v
while s>0
This version needs no sorting.

Categories

Resources