I am writing an app to simulate the nba lottery. I have already written the codes to generate the random combinations, and assigned them to each team.
Here is my method to simulate the drawings and assign the draft positions to each team. standingsArray is an array of Team items of type ObjectWrapper, with values of name, seed, wins, losses, draft position exc... for each team. So basically what Im doing is I have 14 balls and randomly choose 4 balls, which constitute a combination (order doesn't matter). So essentially there are a total of 1001 total possible combinations, but one is thrown out. (you can ignore the first while loop because that is just there so that the thrown out combination isnt selected). A number of combinations is assigned to the 14 lottery teams based on record (250 for worst team, 199 for second worst exc...). The argument in my method standingsArray already has the number of possibilities assigned to each team. Next, I randomly pull 4 balls from the total possibilities, and the team with that combination gets the first pick. But because all the combinations for that team selected cant be chosen again for the second pick, I have to remove all of those combinations, but that is very complicated so instead, i make a new array called tempPossibilities which appends all the combinations for every team except the one just selected, which then allows me to generate a new combination to select from.
However, I am getting an error at this line for j in 0...(standingsArray[i].possibilities?.count)!-1{ It says bad instruction error, and I cannot figure out why I am getting this error. And what else doesnt make sense is that the for loop works and the tempPossibilities array is fully populated with the correct amount of combinations (without the lottery team), even though the error happens at the for loop?
Code is below: any help is appreciated, thank you, and sorry for the really long paragraph
func setDraftPositions(var standingsArray: [Team])->[Team]{
var lottery: [Team]=[]
var totalPossibilities: [[Int]]=combosOfLength(14, m: 4)
var tempPossibilities = []
var rand = Int(arc4random_uniform(UInt32(totalPossibilities.count)))
var draw = totalPossibilities[rand]
while (draw==(unused?.first)!) {
rand = Int(arc4random_uniform(UInt32(totalPossibilities.count)))
draw = totalPossibilities[rand]
}
s: for x in 0...13{
for a in 0...(standingsArray[x].possibilities?.count)!-1{
if(draw==standingsArray[x].possibilities![a]){
standingsArray[x].setDraftingPosition(1)
standingsArray[x].isLottery=true;
lottery.append(standingsArray[x])
for i in 0...(standingsArray.count-1) {
if(standingsArray[i].firstName != standingsArray[x].firstName!) {
for j in 0... (standingsArray[i].possibilities?.count)!-1{ //ERROR is happening here
tempPossibilities.append(standingsArray[i].possibilities![j])
}
}
}
standingsArray.removeAtIndex(x)
break s;
}
}
}
(repeat this for the next 2 picks)
Try this:
for j in 0...(standingsArray[i].possibilities?.count)!-1{
should be written like this:
for j in 0...(standingsArray[i].possibilities?.count)! - 1{
it needs proper spacing.
Related
I've got a SpatRaster of (150 x 150 x 1377) that shows temporal evolution of precipitations. Each layer is a given hour in a 2-month interval, but some hours are missing, and the dataset isn't continuous. The layers names are strings as "YYYYMMDDhhmm".
I need to find the mean value every three hours even on whole intervals or on missing-data intervals. On entire ones I want to average three data and on missing-data ones I would like to average two of them or, if two are missing, to select the unique value as the averaged one.
How can I use data names to select how to act?
I've already tried this code but I'm averaging on three continuous layers by index and not by hours. How can I convert names in DateTime form from "tidyverse" in order to use rollapply() to see if two steps back I find the DateTime I am expecting? Is there any other method to check this out?
HSAF=rast(c((paste0(resfolder, "HSAF_final1_5.tif")),(paste0(resfolder, "HSAF_final6_10.tif")),(paste0(resfolder, "HSAF_final11_15.tif")),
(paste0(resfolder, "HSAF_final16_20.tif")),(paste0(resfolder, "HSAF_final21_25.tif")),(paste0(resfolder, "HSAF_final26_30.tif")),
(paste0(resfolder, "HSAF_final31_N04.tif")),(paste0(resfolder, "HSAF_finalN05_N08.tif")),(paste0(resfolder, "HSAF_finalN09_N13.tif")),
(paste0(resfolder, "HSAF_finalN14_N18.tif")),(paste0(resfolder, "HSAF_finalN19_N23.tif")),(paste0(resfolder, "HSAF_finalN24_N28.tif")),
(paste0(resfolder, "HSAF_finalN29_N30.tif"))))
index=names(HSAF)
j=2
for (i in seq(1,3, by=3))
{third_el<- HSAF[index[i+j]]
second_el <- HSAF[index[i+j-1]]
first_el<- HSAF[index[i+j-2]]
newraster<- c(first_el, second_el, third_el)
newraster<- mean(newraster, filename=paste0(tempfile(), ".tif"))
names(newraster)<- paste0(index[i+j-2],index[i+j-1],index[i+j])
}
for (i in seq(4,1374 , by=3))
{ third_el<- HSAF[index[i+j]]
second_el <- HSAF[index[i+j-1]]
first_el<- HSAF[index[i+j-2]]
subraster<- c(first_el, second_el, third_el)
subraster<- mean(subraster, filename=paste0(tempfile(), ".tif"))
names(subraster)<- paste0(index[i+j-2],index[i+j-1],index[i+j])
add(newraster)<- subraster
}
Thanks for reading my first question. I'm just starting out with google sheets to please bear with me.
Here is the sheet I'm working with
So,this sheet if for a game I play and we assign guild attacks based on power levels. I'm looking to create a function or script and put it in Column O. I'd like this function to compare Column F to a specific cell in Column M and then return the user associated with Column F that is >= than the specific cell in Column M. Like this enter image description here
I highlighted the first three as an example.
I can obviously do this manually but I takes time, and was looking to automate this process so it becomes more efficient. I've tried Vlookups, MATCH, IF and I've been unsuccessful. Any help would be greatly appreciated. Again, I'm just a beginner with google sheets so please go easy on me. :)
Solution
As you metioned that you would also be happy with an scripted solution I have created this script that I believe solves your issue. It has comments explaining step by step how it works:
function myFunction() {
// Get our sheet
var ss = SpreadsheetApp.getActive().getSheetByName('Automate Test');
// Get the values of the ranges of F and M. Flat will convert the 2D array we get from getValues() into a 1D one which is easier to work with
var valuesF = ss.getRange('F2:F16').getValues().flat();
var valuesD = ss.getRange('D2:D16').getValues().flat();
var valuesM = ss.getRange('M2:M16').getValues().flat();
var valuesN = ss.getRange('N17:N31').getValues().flat();
// We will iterate through all the players in column M to find their opponents
for(i=0;i<valuesM.length;i++){
// We create an empty array to be filled with the list of possible opponents to then choose a random one of the list
var playersHigherEqual = [];
// Iterate through the opponent list
for(j=0;j<valuesF.length;j++){
// If the opponent meets the condition
if(valuesF[j]>= valuesM[i]){
// Add it to the array of possible opponents
playersHigherEqual.push(ss.getRange(j+2, 2).getValue());
}
}
//Finally we will set the opponent by choosing a random one out of the list. Note that i+2 is because the arrays start from 0
ss.getRange(i+2, 15).setValue(playersHigherEqual[Math.floor(Math.random()*playersHigherEqual.length)]);
}
// We will iterate through all the players in column M to find their opponents
for(i=0;i<valuesN.length;i++){
// We create an empty array to be filled with the list of possible opponents to then choose a random one of the list
var playersHigherEqual = [];
// Iterate through the opponent list
for(j=0;j<valuesD.length;j++){
// If the opponent meets the condition
if(valuesD[j]>= valuesN[i]){
// Add it to the array of possible opponents
playersHigherEqual.push(ss.getRange(j+2, 2).getValue());
}
}
//Finally we will set the opponent by choosing a random one out of the list. Note that i+2 is because the arrays start from 0
ss.getRange(i+17, 15).setValue(playersHigherEqual[Math.floor(Math.random()*playersHigherEqual.length)]);
}
}
Please let me know if you also need a sheet formula solution for this question. For more information about Apps Script check out the documentation.
I hope this has helped you. Let me know if you need anything else or if you did not understood something. :)
I am trying to sort out a performance issue in doing a data restore on iOS (i.e. data exists in a table, then I update some of it from a flat file backup). My actual case is 1250 times slower on iOS than Windows. I started with the raindrops example from Dexie.bulkPut, which does not exhibit this behavior (it's slower, but only by about 15%, and gradually modified it to be more like what I need to do.
What I have found is that if my table has a single compound key, I can bulkPut the data twice, and it takes nearly the same amount of time both times. But if there are two compound keys, the second write takes about the same time on the computer, but much, much longer on iOS (times in seconds).
Windows Windows iOS iOS
Records First write Second write First write Second write
20,000 2.393 1.904 5.057 131.127
40,000 5.231 3.941 9.533 509.616
60,000 7.808 8.331 14.188 1205.181
Here is my test program:
var db = new Dexie("test");
db.delete().then(function() {
db.version(1).stores({
raindrops: '[matrix+row+col], [matrix+done]'
});
db.open();
var t1 = new Date();
var drops = [];
for (var i=0;i<20000;++i) { // make a matrix
drops.push({matrix: 0, row: Math.floor(i/100)+1, col: i % 100 +1, done: i%2});
}
db.raindrops.bulkPut(drops).then(function(lastKey) {
t2 = new Date();
console.log("Time in seconds " + (t2.getTime() - t1.getTime())/1000);
db.raindrops.bulkPut(drops).then(function(lastKey) {
t3 = new Date();
console.log("Reputting -- Time in seconds " + (t3.getTime() - t2.getTime())/1000);
});
});
});
I am wondering if anyone has any suggestions. I need that second index but I also need for people to be able to do a restore in finite time (my users are not very careful about clearing browser data). Is there any chance of this performance improving? The fact that it's so much better for Windows suggests that it doesn't HAVE to be that way. Or is there a way I could drop the second index before doing a restore and then re-indexing? Done is 0 or 1 and that index is there so I can get a quick count of records with done set (or not set), but maybe it would be better to count manually.
Sorry about the wordy title, I couldn't think how best to phrase this. (if anyone has a better title idea for the underlying principle let me know!)
So, I've got 2 arrays for a 'random workout app'. In the 'generate workout' function, I'm generating a random number of exercises, picking them at random, and then assigning a number of reps to each exercise (again, randomly).
I've got it working fine but there are some exercises that suit a high number of reps (push ups might suit an arc4random between 10 - 30 say) and some that suit a low number of reps (a 1 mile run would suit an arc 4 random between 1 - 5 say).
In creating my workout, I now need to essentially check "if the exercise element in position [0] belongs to the 'low reps array' use reps key X, if it belongs to 'high reps array' use reps key Y.
I think I can do the random number generating bit but I'm massively stuck on the whole checking piece.
Here's my code (with pseudo code explaining in a bit more context hopefully what I'm trying to achieve)
let highRepsArray = ["push ups", "star jumps", "watch tv"]
let lowRepsArray = ["500m row", "3 mile run", "lift a truck"]
let finalExerciseArray = highRepsArray + lowRepsArray
//create function for number of exercises in this specific workout
func generateNewWorkout() -> (randomExerciseArray:Set<String>, randomRepsArray:[Int]) {
let randomKey = Int(arc4random_uniform(4) + 3)
var workoutSet = Set<String>()
let possibleExercises = finalExerciseArray
var repsSet = [Int]()
while workoutSet.count < (randomKey) {
let randomIndex = Int(arc4random_uniform(UInt32(possibleExercises.count)))
workoutSet.insert(possibleExercises[randomIndex])
}
//generate the reps array by counting through the same random key used to generate the number of exercises
while repsSet.count < (randomKey) {
//here's what i can't work out!
IF THE EXERCISE AT POSITION [0] IS IN EXERCISEARRAY1 THEN CHOOSE A RANDOM NUMBER FROM 1 - 10, IF IN EXERCISE ARRAY2 CHOOSE FROM 5 - 10 AND APPEND IT IN THAT POSITION
IF THE EXERCISE AT POSITION [1] IS IN EXERCISEARRAY1 THEN CHOOSE A RANDOM NUMBER FROM 1 - 10, IF IN EXERCISE ARRAY2 CHOOSE FROM 5 - 10 AND APPEND IT IN THAT POSITION
//append the rep number into the array - here it's just the same range for every exercise, but I need to split this out as above
repsSet.append(Int(arc4random_uniform(20)+10))
}
This is nearly the last thing I need to do that I can't workout before my app is finished so hoping someone can help! :-)
Your model is wrong for your needs. You need to use a custom struct that holds the exercise name AND the suitable range of reps. It is then trivial to generate a random number from within that range.
So I am importing passages from a book into my application. I am giving all the passages in a given book the class Passage. i.e. Passage.all
I do have many books so I also have a class Book. Therefore, when I am finding all the passages from one book I call:
Passage.where(book_id: self.book_id)
When I use the where method, does it preserve the "natural order", which Passage.all would generally return. If not, I could change the code to:
Passage.where(book_id: self.book_id).order("created_at ASC")
Anyway, I then proceed to write this code:
a = Passage.where(book_id: self.book_id)
b = a.index(self)+1
self.passage_number = b
[first line: returns all the passages in the book]
[second line: returns their number in the array + 1 to account for the 0 starting value thing (pardon the colloquialism)]
[third line: assigns that index value to the passage number]
Ultimately, I am trying to compute passage numbers, without having to hard code them.
SO WHAT'S MY ISSUE? Right now I am getting three passage #3's, and two passage #4's. My last passage is this:
Passage.last.passage_number = 217
Passage.where(book_id: 5).count = 241
It is skipping numbers and incorrectly indexing, so I think I need to code a better method! What's a better way to index an array in this context?
There is no such thing as "natural order": without an order clause Passage.all may return things in any order the database wants (which could depend on things like location of items on disk, query plan etc).
The first and last methods are special in that they order by id if your relation does not already have an order applied to it.
If you need things in a specific order then add an order clause.