I'm making a game where my character passes an object and when doing so the score counts up by one. The object is part of an array, and when I pass the first object the score counts up continuously. Here is what I have so far:
if (beardman.x >= tubes[i].x)
{
score++;
}
How would I re-write it so that the score just counts up by one?
What you could do is have a similar array and remove from that list like so:
//assume you have a copy of the tubes array called activeTubes.
if (beardman.x >= activeTubes[i].x)
{
score++;
activeTubes.splice( i, 1 );
}
Edit: I wanted to add that splice is known to be a fairly expensive operation as it shifts how the indices are stored in memory. That being said, if you are searching through a fairly large list a optimization to make would look like this:
//assume you have a copy of the tubes array called activeTubes.
if (activeTubes[i] && beardman.x >= activeTubes[i].x)
{
score++;
activeTubes[i] = null;
}
Or even from a for loop perspective:
var i:int;
for ( ; i < activeTubes.length; i++ ) {
//check if the index is null, if so continue.
if ( !activeTubes[i] ) { continue; }
if (beardman.x >= activeTubes[i].x)
{
score++;
activeTubes[i] = null;
}
}
Related
A kyu on codewars asks for the following:
Complete the method which accepts an array of integers, and returns
one of the following:
"yes, ascending" - if the numbers in the array are sorted in an
ascending order "yes, descending" - if the numbers in the array are
sorted in a descending order "no" - otherwise You can assume the array
will always be valid, and there will always be one correct answer.
I put together the following but run into "Caught unexpected signal: SIGSEGV (11). Invalid memory access" when testing. Can someone please explain the error to me and what part of the script triggers it?
#include <stdio.h>
char* isSortedAndHow(int* array, int arrayLength)
{
// Create an empty array where ascending or descending test results will be stored
int results[] = {};
int i;
// If the value is greater than the previous one add a 1, if smaller add a 0, if equal, add 1000
for (i = 1; array[i]; i++){
if (array[i] < array[i-1]){
results[i-1] = 0;
} else if (array[i] > array[i-1]) {
results[i-1] = 1;
} else {
results[i-1] = 1000;
}
}
// Add the value of all values in the results array and return the answer
int sum = 0;
for (i=0; results[i]; i++) {
sum = sum + results[i];
} if (sum == 0) {
return "yes, descending";
} else if (sum == (arrayLength - 1)) {
return "yes, ascending";
} else {
return "no";
}
}
The culprit is the line
int results[] = {};
You declare an array of int with a size of zero. Further down the code you try to write into that array: BOOM!
One possible solution is to allocate the array with the size arrayLength. But as commenters said, you don't need this array at all. Rethink your algorithm.
What i am trying to do is simple: i want to compare an entire line of an array in search of a set of variables in order like this:
var[2][]=={1,2,3,4,5} //all at the same time
instead of
var[2][0]==1 && var[2][1]==2 && var[2][2]==3 && var[2][3]==4 && var[2][4]==5 //one by one
or maybe
vartwo[4][3...7]==var[2][] ou vartwo[4][]==var[2][]
void main() {
int i,var[5];
puts("enter values:");
for(;i<5;i++) {
scanf("%d",&var[i]);
};
if(var[]=={1,1,1,0,0,0}) {
//do stuff
} else if (var[]=={1,2,3,5,2}) {
//do something else
}
.
.
.
} else {
//not found
}
}
is there any way i can do that?
Sorry to break but there is no way you can compare two arrays like the way you showed in C.
Simple old looping with element wise comparison is the way out.
for(size_t i = 0; i < len ; i++)
if( arr[i] == anotherarr[i] )
// same
memcmp is an option but unless you can ensure there will be no padding you can't use it reliably.
I have 2 arrays, 1 is a master (bookArray) and the other an update list (stockBooksArray). I use the loop below to import new data into waster array using a unique record (isbn) that exists in both arrays.
Is there a way to improve the performance of the loop below?
The update array can contain a different count to the master, sometimes more, sometimes less.
for i in 0...stockBooksArray.count {
let StockFiltered = stockBooksArray.filter{$0.isbn == bookArray[i].isbn}
if StockFiltered.count != 0 {
bookArray[i].stockAmount = StockFiltered[0].Stock
bookArray[i].unitCost = StockFiltered[0].Cost
bookArray[i].dues = StockFiltered[0].dues
bookArray[i].stockRRP = StockFiltered[0].RRP
}
}
Thanks,
Anthony
Yes there is. Right now you are looping through the bookArray array once for every stockBooksArray object. That's O(N*M) which is pretty bad.
Instead, if you can sort both arrays by ISBN, then you can step through both at the same time, visiting each element only once which would be O(N). Considerably faster, even if you include the time to sort them.
I threw the code below together pretty quick. It assumes that both arrays are sorted by isbn. I think you will find this considerably faster.
var j = 0
for book in stockBooksArray {
while bookArray[j].isbn < book.isbn && j < bookArray.count {
++j;
}
if j == bookArray.count {
break
}
else if bookArray[j].isbn == book.isbn {
bookArray[j].stockAmount = StockFiltered[0].Stock
bookArray[j].unitCost = StockFiltered[0].Cost
bookArray[j].dues = StockFiltered[0].dues
bookArray[j].stockRRP = StockFiltered[0].RRP
}
}
If you are just adding new ones you could get an NSMutableSet of the ISBNs for each, perform a set minusSet: operation removing the bookArray ISBNs from stockBooksArray and then just add the resulting ISBNs to bookArray.
Untested concept code, convert to Swift as needed:
NSMutableSet *stockBooksSet = NSMutableSet setWithArray:[stockBooksSet valueForKey:#"isbn"];
NSSet *booksSet = NSSet setWithArray:[bookArray valueForKey:#"isbn"];
[stockBooksSet minusSet: booksSet];
for (NSString *isbn in stockBooksSet) {
// add book with ism to booksSet
}
Updated code using Daniel T. method.
bookArray.sort { (lhs, rhs) in return lhs.isbn < rhs.isbn }
stockBooksArray.sort { (lhs, rhs) in return lhs.isbn < rhs.isbn }
var j = 0
for book in stockBooksArray {
while bookArray[j].isbn < book.isbn && j < bookArray.count {
++j
}
if j == bookArray.count {
break
}
else if bookArray[j].isbn == book.isbn {
bookArray[j].stockAmount = book.Stock
bookArray[j].unitCost = book.Cost
bookArray[j].dues = book.dues
bookArray[j].stockRRP = book.RRP
}
}
From 5-6 seconds on iPad2 to almost instant.
Many thanks,
Anthony
I am developing a game that has a winning combination array:
var allwinning = [
['000','010','020'],
['000','100','200'],
['000','001','002'],
['000','101','202'],
['000','011','022'],
['000','110','220']];
The player will need to pick more than 3 numbers randomly. If all numbers are within any of the combinations in allwinning, the player wins.
For example, if the player picks '111','110','000','220', the player will win because allwinning[5] has the combination['000','110','220'].
My question is, what is the best way to do this winning loop? I cannot figure out the optimum way to do this.
Currently, I have a playerpick array to keep what player had picked and possiblewin array:
var playerpick = new Array(['111','110','000','220']);
var playerpicksingle = playerpick[0];
var possiblewin = new Array([]);
Then I go through a loop to capture out the possible win combination first:
for(var i=0 ; i < allwinning.length - 1 ; i++)
{
for(var j=0 ; j <3 ; j++)
{
if(allwinning[i][j]==playerpicksingle)
{
possiblewin.Push(allwinning[i]);
}
}
}
Then I am stuck at this point. I really don't know what else to do.
I can think of two ways. One requires you to change your data structure and the other doesn't.
Without changes:
Sort the user input:
pickedNumbers.sort();
and start comparing. By sorting the values beforehand you know when you can back out and continue with the next set of numbers, i.e. you can back out early and don't have to compare all the values (in the average case).
function wins(picked, winning) {
var winningSet = [];
for (var i = 0; i < winning.length && winningSet.length < 3; i++) {
var set = winning[i];
winningSet = [];
var j = 0;
var k = 0;
while (j < set.length && k < picked.length && winningSet.length < 3) {
if (picked[k] === set[j]) {
winningSet.push(set[j]);
j++; // advance to next element in winning set
} else if (picked[k] > set[j]) {
// continue with the next set
break;
}
// maybe the next element in players picks will match
k++;
}
}
return winningSet.length === 3 ? winningSet : false;
}
The worst case scenario of this solution is O(n*m*l), but since the input is sorted, the average case will be better.
DEMO
With Array#some and Array#every the code becomes much more concise, though it looses the advantage of using sorted input. If your arrays are small it won't make a difference though:
function wins(picked, winning) {
return winning.some(function(set) {
return set.every(function(val) {
return picked.indexOf(val) !== -1;
});
});
}
It also won't give you the actual numbers that matched. The runtime is the same.
The second way would be to build some kind of trie instead of using an array of arrays:
var allwinning = {
'000': {
'010': {
'020': true
},
'100': {
'200': true
},
// ...
}
};
The structure should also be sorted, i.e. the keys of a level are all smaller then the keys of its sublevel etc.
Sort the user input as well and iterate over it. Whenever you found a matching key, you go one level deeper until you have three matches:
function wins(picked, winning) {
var winningSet = [];
for (var i = 0; i < picked.length && winningSet.length < 3; i++) {
if (picked[i] in winning) {
winningSet.push(picked[i]);
winning = winning[picked[i]];
}
}
return winningSet.length === 3 ? winningSet : false;
}
This solution has the worst case scenario of O(n), where n is the number of values the user picked (not taking into account the time it takes to test whether an object contains a specific property name. Often this is assumed to constant).
DEMO
How to find the integer occurring maximum number of times (mode) in an unsorted array of integers?
One O(nlogn) approach I could think of is to sort. Is there any other better approach?
Here's a basic outline of what you will be doing:
First sort the array - O(n logn) incase of a merge sort
Declare Count=1, Max_Count=1, Max_Value=arr[0]
Iterate through array starting at index 1
Compare each element with Previous element. Update the count, Max_Count if they are equal, else reset count back to 1
return Max_Count, Max_value
Time Complexity : O(n logn)+ O(n)
Space Complexity : InPlace , no hash table or hash map is required.
Here is the code:
public void Max_Occurrence(int[] arr)
{
int count=1;
int max_count =1;
int max_value = arr[0];
for(int i=1; i<arr.length ; i++)
{
if(arr[i-1] == arr[i])
{
count++;
if(max_count<count)
{
max_count = count;
max_value = arr[i];
}
}
else
{
count = 1;//changing from count++. As per the steps mentioned above it should be reset to count = 1. Suggested by an anonymous user
}
}
System.out.println("Result:"+max_value+" has occured "+max_count+"of times");
}
I think you want to find out element that has most occurences in the array -
if you don't care about memory, traverse the array once, increase count of each element in the hashtable. Then find the one with highest count. You'd need one traverse of array and one of the hashtable.
so in pseudocode:
hashtable hash;
foreach(element in array){
if(!hash.contains(element))
hash[element] = 1;
else
hash[element]++;
}
int max = 0;
max_element;
foreach(element in hash)
if(hash[element] > max)
{
max_element = element;
max = hash[element];
}
//max_element contains the maximum occuring one.
If you are using Linq you can do this
IEnumerable.Max();
You can use a hashtable with "the number in array" as key and "occurrences" as values.
Sample code be like this:
hashtable h;
for every entry in array
search hashtable
if present, increment num_occurrences
else, create new entry
Iterate over all the entries in hashtable and return one
with max num_occurrences
As searching in hash is considered O(1), the overall complexity will be O(n).
A special case of this problem is when the numbers in array are in a given range, in that case take another array of ints with size of maximum value in the original array,and use the index of new array as key and the number stored in this array as count of occurrences.
Return the index of the largest value in this array.
Try this.
class max_frequency
{
private int a[]=new int[20];
public void accept(int a1[])
{
a=a1;
}
public void sort()
{
int i,j,t;
for(i=0;i<20;i++)
{
for(j=i+1;j<20;j++)
{
if(a[i]>a[j])
{
t=a[i];
a[i]=a[j];
a[j]=t;
}
}
}
int count=1;
int max_count=1;
int max_value=0;
for(i=1;i<a.length;i++)
{
if(a[i-1]==a[i])
{
count++;
if(max_count<count)
{
max_count=count;
max_value=a[i];
}
}
else
{
count=1;
}
}
System.out.println("Result : "+max_value+ " has occured "+max_count+ " times");
}
}