Random numbers, prevent from being used more than once - Printable Version -Shoutbox (https://shoutbox.menthix.net) +-- Forum: MsgHelp Archive (/forumdisplay.php?fid=58) +--- Forum: Messenger Plus! for Live Messenger (/forumdisplay.php?fid=4) +---- Forum: Scripting (/forumdisplay.php?fid=39) +----- Thread: Random numbers, prevent from being used more than once (/showthread.php?tid=75840) Random numbers, prevent from being used more than once by stu on 07-03-2007 at 10:14 PM
Ok, so I got bored today and was thinking what else I could add to a script that I have been working on that displays a random lyric. What I want to do, is make it so that the random number that is generated is not repeated within a certain amount of number generations. So for example, the numer 7 is generated, and then that number cant be used again until 10 different numbers have been used. Something like that. RE: Random numbers, prevent from being used more than once by pollolibredegrasa on 07-03-2007 at 10:33 PM
Hmm, there are probably better ways to do this, but you could possibly do this using a multidimensional array... RE: Random numbers, prevent from being used more than once by foaly on 07-03-2007 at 10:34 PM
the easiest thing to do would be an array and a function like: RE: Random numbers, prevent from being used more than once by roflmao456 on 07-04-2007 at 03:15 AM
Create this at the top of your script: code: Then put this code to where the random thing is: code: i'm not sure if that will work.. RE: Random numbers, prevent from being used more than once by Volv on 07-04-2007 at 06:01 AM
I think foaly's is the simplest working code. RE: Random numbers, prevent from being used more than once by markee on 07-04-2007 at 02:17 PM
why use count at all when j will give you the same result? code: I did label a function which a lot of people are probably unfamiliar with, but it makes it a little more resource friendly as you can be calling the same function hundreds of times (there is a chance that it will never give you an answer and freeze your computer too.... but this is very limited, but more probable when you have a lot of lyrics and have gone through most of them). And I also added an if statement at the end to make sure that there is no case where there are no lyrics left... which would leave you with an infinite loop too. Furthermore, dynamic functions are a very wise idea and that is why I have made the random number based upon the array of lyrics rather than you having to do that manually when you update it. I hope you enjoy. EDIT: updated code due to Volv's post below RE: Random numbers, prevent from being used more than once by Volv on 07-04-2007 at 02:31 PM
markee, that code isn't very elegant and could be more optimised, but it also doesn't solve the initial problem =/ quote:'count' provides a means of allowing the lyric to be re-used after 10 different lyrics have been used as was requested: quote: RE: Random numbers, prevent from being used more than once by markee on 07-04-2007 at 02:35 PM
quote:well in that case then I just need to use a .pop on my selectedArray if the length is 10 and add the new one on.... not overly difficult. I'll edit my code above RE: Random numbers, prevent from being used more than once by foaly on 07-04-2007 at 04:00 PM
quote:this option maybe nicer... but it might be easier to use a function you understand... and I doubt the thread starter understands how exactly your function works... RE: Random numbers, prevent from being used more than once by stu on 07-04-2007 at 04:50 PM
Wow, thanks for the responses guys, didnt expect so many.. I'll give your suggestions all a try today and see what I come up with. A lot of it, I dont even understand though, like markee's code, lol. But I will give it a try anyways. RE: Random numbers, prevent from being used more than once by roflmao456 on 07-04-2007 at 05:22 PM
another suggestion: RE: Random numbers, prevent from being used more than once by Volv on 07-04-2007 at 05:47 PM
quote:The % operator is the modulo, it gives you the remainder when dividing by the number ie. the remainder when dividing count by 9. Because of the way that the function is coded, you should replace 9 with the number of lyrics you want to be displayed before you want repetition minus one (so if you want 20 lyrics you would do count%19). RE: Random numbers, prevent from being used more than once by CookieRevised on 07-05-2007 at 12:34 AM
What is being requested can be done in essentially just 3 steps/lines of code!! quote:Actualy foaly's method is not going to work, it is fatfreechicken's method which would be working. The method used by fatfreechicken (although a bit overcomplicated than it needs to be) is actually a very widely used method to generate a random set of numbers in such a way that no number will be drawn twice (or trice, quar...blah, whatever. )... foaly's method doesn't return anything if the randomly generated lyric already exists in the past 10 lines! His function would simply stop. And even if it was fixed to regenerate a new random number when the current one already exists instead of simply quiting (which I assume is what he wanted to do ), his method will be dead slow because in the worst case scenario his routine would take a very long time because it constantly draws a number/lyric which was already used before and thus it needs to regenerate a new one again. The bigger the ratio of uniqueness vs the number of lyrics is, the slower such a routine will become (eg: use his routine to generate lyrics out of 100 possible lyric lines where 99 continues lines can't have the same lyric... it would take a very long time). roflmao456's method simply fills some random items of an array (not even all items for that matter). markee's method is a variation on what I had done (though I didn't posted this yet because I was at work all day). But it is again overcomplicated and containes the big and slow 'regenerate until you have a valid number' kind of infinite loop like foaly.... ---------------------------------------------------------------------- quote:it wouldn't make a difference. ---------------------------------------------------------------------- Here is my method: (it might be possible that this is what fatfreechicken wanted to do in the first place though): You have an array full of all the possible lyric lines (to choose from). You have (currently an empty) array of used lyrics. STEP 1: Each time you draw a new random lyric line you remove that lyric line from your original array and add it to the array of used lyrics. Now your original array wont contain that lyric line anymore. And thus there is no need to check anything at all, you wont be able to choose it again anyways (= no unneeded and long loops like with foaly's method). STEP 2: Move the 10th element of the used lyrics array back to the original big array of lyrics (because you must be able to choose it again). DONE! Do this for as long as you want... The function would be instant, no loops at all! And it always makes sure you would have 10 different lines... thus no infinite loops, not even a slow 'check against all array elements' check... useable directly out of the box: code: EDIT: PS: stu, don't forget to use the var statement if you use/initialize a new variable inside a function. Not doing so will make that variable a global variable instead of a local variable. RE: Random numbers, prevent from being used more than once by stu on 07-05-2007 at 12:51 AM Ok, so like CookieRevised said, the suggestions made did not work.. so I guess its not just me not being able to get them to work, lol. Cookie, I will give yours a try now, it looks like I will need to make a few adjustments to it to make it work with my script though, so I'll let you know how that turns out, thanks RE: Random numbers, prevent from being used more than once by CookieRevised on 07-05-2007 at 12:55 AM
quote:I don't see what you need to adjust... The function GetRandomLyric() can be used without any modification, as long as your lyrics array is named 'arrLyrics'. The build-in lyrics array you have in your script (named Text[]) can simply be overwritten with the array read from the file (named Lines[]). You don't need two different arrays for that. Name them both arrLyrics[], stick in the routine I showed and you're done... PS: and make your 'FileToArray' code as a seperate function and let it simply return an array so you can do: if (which === 0) arrLyrics = FileToArray('C:\\quotes.txt')); or, to preserve the contents of the existing array also: if (which === 0) arrLyrics.concat(FileToArray('C:\\quotes.txt')) code: quote:they work, but it can be done in a much shorter and faster way. RE: Random numbers, prevent from being used more than once by stu on 07-05-2007 at 01:03 AM my array is called Text, so i renamed your code appropriately, as well as your random number variable, to Number, as it is in my code (I attached my code in one of my previous posts, if you havent seen it). So right now other then that, its just copied straight in, and it doesnt seem to be working, or returning any lyric for that matter, just undefined. Going to further look into it now.. RE: Random numbers, prevent from being used more than once by CookieRevised on 07-05-2007 at 01:32 AM
Seeing your code you need to do more than that... RE: Random numbers, prevent from being used more than once by stu on 07-05-2007 at 01:55 AM
Ok, so if I was to do it as you suggest, outside my personalMessage function I would check to see what which is.. But thats not how I want the script to work though. The reason the which statement is there, is for when the script calls the personalMessage function to get a new personal message, the function can choose, by using which, if its going to be a lyric, or using my example in the script, a joke. so instead of creating 3 functions, i just have the one. the 3 functions being one that gets called on when a new personal message is displayed that chooses either joke or lyric(which would be the which statement), and one for each, the lyric and joke. I want it to choose between a lyric and a joke each time that the script requests a new psm, and doing it outside of my function would not allow me to do so.. quote:No, I didnt plan on having the which variable user defined.. thats why it is set up like it is.. Anyways, I had a question. Where you have quote:Does that go inside my personalMessage function, or outside it like everything else? This is what the script debugging shows code:I added two more trace routines to show the arrays also. RE: Random numbers, prevent from being used more than once by CookieRevised on 07-05-2007 at 02:00 AM
quote:No, what I suggest is exactly how you want your script to work... What you do now is exactly the same as using 3 functions, only you grouped them together into a 'parent' function. So, that isn't putting 3 functions into 1, that is just grouping 3 functions... You're really making it difficult for yourself in the way you do it now quote:in that case you do not need the which checking, seperate arrays, and all that other stuff at all. Just concat the lyrics array with your quotes array and be done with it. In other words, you're REALLY making it WAY hard on yourself ... (and hence my initial suggestion to not alter my example routine at all but instead optimizing your code!). ------------------- In a nutshell you would have: code:Which is extremely shorter than what you have now.... GetAllLyrics() is called wherever you have your routine when the user changes the option from "quotes" to "lyrics" or to "both".... And if you never want to implement a feature where the user can choose from which arrays the random line should be taken, you could simply only use case 2 from GetAllLyrics(). Aka: concatenate all the arrays you're going to use FIRST. Once that is done you don't need to be bothered about stuff like if (which = x) or whatever else... ---------------------------------- quote:That is example code. Code to show how you would use the above functions... RE: Random numbers, prevent from being used more than once by stu on 07-05-2007 at 02:18 AM
Ok, Im not too worried about the which statement right now, its just redundant code in my script for right now, and I have actually just taken it out, I probably wont use it, but I was playing around with it earlier. But anyways, I still cant seem to get this to work.. all I am still getting is "undefined" for my lyric.. I have ttried putting your code straight in, and playing around with it, cant seem to get it. Havent tried quote:Yes, I could very well do that, and the reason I did not was that if, going by my example again, I used lyrics, and jokes, they would be displayed different, by adding in front of the lyric, and probably not adding anything to the joke. If i just had them all together, the jokes would also have in front of them.. that is why they are seperate... Also, I did try to change my initial code to match yours, but as far as I got it didnt work, and then you said something about using my code that I had already, so I changed it all back, lol. I think I am running around in circles. quote:Yes, I realize that is just example code, I was just trying to clarify if that would go inside my function or not, because it did not seem so when you originally posted it. RE: Random numbers, prevent from being used more than once by CookieRevised on 07-05-2007 at 02:32 AM
I think the problem you have is that you're thinking too much about seperate arrays and making it so that your code switches between arrays, checks stuff, etc.... You're focussing too much on that. Forget about all that. You only need 1 array to work with, nothing more. And that array should only be (re)created when the user enables the "change PSM to random line" feature of your script. quote:No it wouldn't. That's what I mean with "you're thinking to much about seperate arrays"... If you want to show "" in front of lyrics, then add "" to each lyric line when you create the array, not when you are showing stuff... So the array would contain: "quote one" "quote two" " lyric one" " lyric two" " joke one" " joke two" You don't need seperate arrays.... In that same matter you can instead add 1 character as an identifiers to each line you add to the array to indicate 'special stuff' to be done when you actually show a line (eg: "Q" for a quote, "L" for a lyric, etc). The point is: you're doing stuff inside the "show it" routine which should actually be done before you show it, not during it... RE: Random numbers, prevent from being used more than once by Volv on 07-05-2007 at 02:45 AM
quote:It works perfectly fine for generating the random number without repetition until 10 others have been selected. quote:Yes it does, it's a recursive function if you look closely. If the line exists it simply calls itself again until it returns a new number. quote:I already said this in the edit about 8 hours ago =/ Granted, the theory behind your idea is much more intelligent and efficient you shouldn't be dissing people's suggestions without first understanding them RE: Random numbers, prevent from being used more than once by stu on 07-05-2007 at 02:51 AM
Ok, true enough, if I want to take the extra time to change that now, and each future one as I add it. I am just going to leave that for now though. As I said, I have now cut out the which statement alltogether, and am using just the Text array so its not a huge deal right now, to me.. quote:I tried his method as well, but could not get that to work. If you think it can, that would be great if you could think of a way for me to figure it out, always better to know more than one method.. ___________________________________________________________ Ok, so I got it to display a lyric. when the lyric is chosen, it is removed from the array, and added into arrPrevious (but it only seems to stay there for one lyric, see debuging). After 10 lyrics though, they dont get added back into the original array. Here is what the script debugger shows.. As you can see, my Text array consists of 12 Tests.. quote: RE: Random numbers, prevent from being used more than once by CookieRevised on 07-05-2007 at 03:07 AM
quote:sorry for missing the recursive bit. quote: quote: quote:ermm.... first of all I'm not dissing anything, I'm trying to explain things. Big difference... Second, yes, I missed the recursive bit of foaly's method, but that is still not dissing or not understanding stuff. Seeing all the stuff I wrote in this thread I think it is clear I understand how the suggested stuff works. In fact, in that same first post of mine you quoted from, I also explained foaly's method and what disadvantage it has. The reason I missed the recursive bit was not because I don't understand what he wrote, it was because it I saw what "method" he used, not what exact "code" he wrote (hard to explain though). If I would be dissing stuff I wouldn't take the hours of time I already put into this to explain stuff... I would simply say it is crap or something (and thus wouldn't say anything at all)... :/ quote:You don't need to change all your saved files, you can do it inside the code when you create the array... If you read lines from a "jokes" file, add the smilie, if it is from a "lyrics" file, add the note, etc... quote:You've not copied the code exactly as I put it (or you changed stuff too much or in the wrong way)... RE: Random numbers, prevent from being used more than once by Volv on 07-05-2007 at 03:11 AM
quote: code:I don't take credit for this code - foaly's idea. and whenever you want to pick a random element from an array you just do: var myRandomLyrics = arrLyrics[GetIndex(arrLyrics,10)]; Where 10 is the number of lyrics after one has been chose which must be chosen before that lyric can be repeated. NOTE: You must still only ever have 1 array (as Cookie has pointed out) otherwise you will bump into problems. RE: Random numbers, prevent from being used more than once by stu on 07-05-2007 at 03:22 AM
Thanks Volv for the (foaly's) code, I'll try that out as well once I get Cookie's code working quote:Perhaps so, take a look. This is the code as I have it.. well, the main functions... code: RE: Random numbers, prevent from being used more than once by CookieRevised on 07-05-2007 at 03:36 AM remove quote:Do not (re)create/(re)read the array each time you wanna change the PSM. The array should be created only once, outside of personalMessage()... That's the major point I'm trying to make in all my posts... Instead put that line in the initializing code of your script or in the part where the user activates the PSM changing for the first time (if that is still in the code). PS: code:That debug line will never be executed since the function is ended before that line because of the statement 'return'. RE: Random numbers, prevent from being used more than once by stu on 07-05-2007 at 03:45 AM
Removing that line prevents a lyric from being displayed though, even when changing the array Text to ArrLyrics.. all I get then is undefined. RE: Random numbers, prevent from being used more than once by CookieRevised on 07-05-2007 at 03:47 AM
quote:Because you need to create the array first. Put that line in the initializing code of your script or in the part where the user activates the PSM changing for the first time (if that is still in the code). Thus outside of personalMessage()... again (no offense though!): You're constantly doing: 1) timer triggerd I) make new PSM a) create different arrays b) get random line from array You need to do: 1) create 1 array 2) timer triggerd I) make new PSM a) get random line from array RE: Random numbers, prevent from being used more than once by stu on 07-05-2007 at 03:55 AM lol, ok, so lets see if I get this right.. I should remove code:from my personalMessage function, but add it in where the script is first initialized from.. So that should be put in OnEvent_Signin(Email), and OnEvent_Initialize(MessengerStart). (Little bit off topic: I have copied most of this stuff from Toast Message, as it had a menu similiar to what I wanted, and then I tweaked it for myself. It has both of those functions doing the same thing, what exactly is the difference of them both, and do I really need both of them?) Edit: I think I would need to add it to the toggle function, that switches between on and off, as well Is my thinking now correct? I think this is all beginning to make sense to me now, lol. I really must thank you for all this help Edit2: So it does seem to work now, I added it to the three places mentioned above. It does make more sense having it that way, it just took a while to get it through my head, lol. Sorry for the difficulties, I blame it on myself currently being sick and not functioning properly, lol. RE: RE: Random numbers, prevent from being used more than once by CookieRevised on 07-05-2007 at 04:23 AM
quote:yes quote:Actually, you only need to add it once. Best to do this in the 'toggle' function. The OnEvent_Signin() and OnEvent_Initialize() just need to point to the toggle function also. Because I suspect you currently have the same code in those functions also.... This is again optimizing code in a logic way, splitting things up, instead of putting many same code all over the place. eg: code:something like that... In that way you only need to change stuff in one place. quote:You only need one of the two. The difference is only in what window it uses to get to the contactlist. RE: Random numbers, prevent from being used more than once by stu on 07-05-2007 at 04:30 AM
Ok, thanks a lot for the help Glad to finally get this working. I will work on optimizing my code further.. probably would explain why I couldnt get this working trying it myself, my array kept on getting erased, now I see why. RE: Random numbers, prevent from being used more than once by foaly on 07-05-2007 at 10:57 AM
Glad you got it to work... RE: Random numbers, prevent from being used more than once by stu on 07-05-2007 at 04:59 PM foaly, I just finished trying your code, it did seem to be working at first, but then it gave me an error in the script debugger quote:which is this line code: Also, it returned one undefined result, but I think that just has to do with the random number rounding up to a nonexistant number, as its using math.round in the code Volv provided, so thats no biggy to fix. But I think I am going to take your advice and just stick to Cookies code, so thanks a lot for the suggestion anyways RE: Random numbers, prevent from being used more than once by CookieRevised on 07-05-2007 at 11:39 PM
quote:Foaly used a recursive function. Recursive functions are functions which will call themselfs. eg: code:With such functions you can create very short code and/or do very fancy stuff. eg: - many highly optimized sorting routines like QuickSort routines are recursive. - It is also used in many arithmetic functions, eg: calculating the factorial of a number - And of course it is used a hell of a lot for creating Fractals. However, there is one massive disadvantage with recursive functions: they eat memory... That is: each time the function calls itself again, the operating system needs to preserve everything and initialize the function again. This preserving is done by temporarly placing everything from that function in memory, the so call 'stack space'. Only when an iteration of a function is ended, the temporary used stack space for that individual iteration is freed. And the problem is that stack space is very limited... So, if a function calls itself a bit too much, the operating system will run out of stack space, and you'll recieve that error... And because Foaly's method uses such a recursive function, it has the potential danger of running out of stack space, as you just experienced. This because it calls itself again each time it produces a random line which already exists in one of the x previous lines. I think I talked about this in one of my previous posts: This is mostly noticeable when the ratio between the number of unique lines and the total number of possible lines is very high. eg: you have 100 different lines to choose from and you don't want the same line to occur in a continues row of 99 lines. Foaly's function would in that case constantly call itself because the chance it picks an already existing line is extremely high (99/100). And the more the function calls itself, the more stack space it needs... Thus when you use recursive functions you need to test and use them with great care. PS: you can compare recursive functions with a 'todo list': After 5 minutes of being busy with a certain task, you start to work on another task and thus you put all the stuff from the first task in the 'busy' box. Then again after some time you start a third task, thus you put everything from task 2 in the 'busy' box on top of the stuff from the first task. Then after some times you start a 4th task, etc... Eventually the box will be full and you wont be able to put anything more in it... quote:indeed, it should be math.floor... math.round should never be used to generate a random number. |