Generation of an array of substring from a string in swift - arrays

I have a problem with generation of an array of substrings from a string in the following code
var primers=[String]()
var lengthOfPrimer = 20
var lentghOfText = str1.characters.count
var rest = lentghOfText - lengthOfPrimer
for var i = 0; i <= str1.characters.count; ++i
{
var temp = rest - i
var substring1 = str1.substringWithRange(Range<String.Index>(start: advance(str1.startIndex, i), end: advance(str1.endIndex, -temp)))
primers.append(substring1)
}
In playground I have the following error at the line with the substring1 code – Execution was interrupted: reason: EXC_BAD_INSTRUCTION (code=EXC 1386_INVOP, subcode=0x0.
In spite of error sign, I can see in playground the generated set of substrings in loop, but when I tried to use this code in program this code also did not work, What is wrong? What should I do?

Your error is coming from trying to advance the endIndex.
But how about something a little simpler? (Swift 2)
var first = str1.startIndex
var last = advance(first, 20 - 1, str1.endIndex)
while last != str1.endIndex {
primers.append(str1[first++ ... last++])
}
print("\n".join(primers))
// output:
// ACAAGATGCCATTGTCCCCC
// CAAGATGCCATTGTCCCCCG
// AAGATGCCATTGTCCCCCGG
// AGATGCCATTGTCCCCCGGC
// GATGCCATTGTCCCCCGGCC
// ATGCCATTGTCCCCCGGCCT
// TGCCATTGTCCCCCGGCCTC
// GCCATTGTCCCCCGGCCTCC
// CCATTGTCCCCCGGCCTCCT
// CATTGTCCCCCGGCCTCCTG
// ATTGTCCCCCGGCCTCCTGC
// TTGTCCCCCGGCCTCCTGCT
// ...
Or the for loop way:
for var first = str1.startIndex, last = advance(first, 20 - 1, str1.endIndex);
last != str1.endIndex;
++first, ++last
{
primers.append(str1[first...last])
}

for var i = 0; i <= str1.characters.count; ++i
Without getting into the rest of this code, this for loop is wrong. You are reading past the end of the string because you are using <= when you should be using <.
Also you are calling str1.characters.count in the loop even though you have that value in a variable, which is slow.
Try:
for var i = 0; i < lengthOfText; ++i

Related

Move Zeroes in Scala

I'm working on "Move Zeroes" of leetcode with scala. https://leetcode.com/problems/move-zeroes/description/
Given an array nums, write a function to move all 0's to the end of it while maintaining the relative order of the non-zero elements. You must do this in-place without making a copy of the array.
I have a solution which works well in IntelliJ but get the same Array with input while executing in Leetcode, also I'm not sure whether it is done in-place... Something wrong with my code ?
Thanks
def moveZeroes(nums: Array[Int]): Array[Int] = {
val lengthOrig = nums.length
val lengthFilfter = nums.filter(_ != 0).length
var numsWithoutZero = nums.filter(_ != 0)
var numZero = lengthOrig - lengthFilfter
while (numZero > 0){
numsWithoutZero = numsWithoutZero :+ 0
numZero = numZero - 1
}
numsWithoutZero
}
And one more thing: the template code given by leetcode returns Unit type but mine returns Array.
def moveZeroes(nums: Array[Int]): Unit = {
}
While I agree with #ayush, Leetcode is explicitly asking you to use mutable states. You need to update the input array so that it contains the changes. Also, they ask you to do that in a minimal number of operations.
So, while it is not idiomatic Scala code, I suggest you a solution allong these lines:
def moveZeroes(nums: Array[Int]): Unit = {
var i = 0
var lastNonZeroFoundAt = 0
while (i < nums.size) {
if(nums(i) != 0) {
nums(lastNonZeroFoundAt) = nums(i)
lastNonZeroFoundAt += 1
}
i += 1
i = lastNonZeroFoundAt
while(i < nums.size) {
nums(i) = 0
i += 1
}
}
As this is non-idomatic Scala, writing such code is not encouraged and thus, a little bit difficult to read. The C++ version that is shown in the solutions may actually be easier to read and help you to understand my code above:
void moveZeroes(vector<int>& nums) {
int lastNonZeroFoundAt = 0;
// If the current element is not 0, then we need to
// append it just in front of last non 0 element we found.
for (int i = 0; i < nums.size(); i++) {
if (nums[i] != 0) {
nums[lastNonZeroFoundAt++] = nums[i];
}
}
// After we have finished processing new elements,
// all the non-zero elements are already at beginning of array.
// We just need to fill remaining array with 0's.
for (int i = lastNonZeroFoundAt; i < nums.size(); i++) {
nums[i] = 0;
}
}
Your answer gives TLE (Time Limit Exceeded) error in LeetCode..I do not know what the criteria is for that to occur..However i see a lot of things in your code that are not perfect .
Pure functional programming discourages use of any mutable state and rather focuses on using val for everything.
I would try it this way --
def moveZeroes(nums: Array[Int]): Array[Int] = {
val nonZero = nums.filter(_ != 0)
val numZero = nums.length - nonZero.length
val zeros = Array.fill(numZero){0}
nonZero ++ zeros
}
P.S - This also gives TLE in Leetcode but still i guess in terms of being functional its better..Open for reviews though.

How to find all sequences of three in an array of values

first question ever here...
I am coding a simple 3-card poker hand evaluator and am having problems finding/extracting multiple "straights" (sequential series of values) from an array of values.
I need to extract and return EVERY straight the array possibly has. Here's an example:
(assume array is first sorted numerically incrementing)
myArray = [1h,2h,3c,3h,4c]
Possible three-value sequences are:
[1h,2h,3c]
[1h,2h,3h]
[2h,3c,4c]
[2h,3h,4c]
Here is my original code to find sequences of 3, where the array contains card objects with .value and .suit. For simplicity in this question I just put "2h" etc here:
private var _pokerHand = [1h,2h,3c,3h,4c];
private function getAllStraights(): Array
{
var foundStraights:Array = new Array();
for (var i: int = 0; i < (_handLength - 2); i++)
{
if ((_pokerHand[i].value - _pokerHand[i + 1].value) == 1 && (_pokerHand[i + 1].value - _pokerHand[i + 2].value) == 1)
{
trace("found a straight!");
foundStraights.push(new Array(_pokerHand[i], _pokerHand[i + 1], _pokerHand[i + 2]));
}
}
return foundStraights;
}
but it of course fails when there are value duplicates (like the 3's above). I cannot discard duplicates because they could be of different suits. I need every possible straight as in the example above. This allows me to run the straights through a "Flush" function to find "straight flush".
What array iteration technique am I missing?
This is an interesting problem. Given the popularity of poker games (and Flash) I'm sure this has been solved many times before, but I couldn't find an example online. Here's how I would approach it:
Look at it like a path finding problem.
Begin with every card in the hand as the start of a possible path (straight).
While there are possible straights:
Remove one from the list.
Find all the next valid steps, (could be none, or up to 4 following cards with the same value), and for each next valid step:
If it reaches the goal (completes a straight) add it to a list of found straights.
Otherwise add the possible straight with the next step back to the stack.
This seems to do what you want (Card object has .value as int):
private function getAllStraights(cards:Vector.<Card>, straightLength:uint = 3):Vector.<Vector.<Card>> {
var foundStraights:Vector.<Vector.<Card>> = new <Vector.<Card>>[];
var possibleStraights:Vector.<Vector.<Card>> = new <Vector.<Card>>[];
for each (var startingCard:Card in cards) {
possibleStraights.push(new <Card>[startingCard]);
}
while (possibleStraights.length) {
var possibleStraight:Vector.<Card> = possibleStraights.shift();
var lastCard:Card = possibleStraight[possibleStraight.length - 1];
var possibleNextCards:Vector.<Card> = new <Card>[];
for (var i:int = cards.indexOf(lastCard) + 1; i < cards.length; i++) {
var nextCard:Card = cards[i];
if (nextCard.value == lastCard.value)
continue;
if (nextCard.value == lastCard.value + 1)
possibleNextCards.push(nextCard);
else
break;
}
for each (var possibleNextCard:Card in possibleNextCards) {
var possibleNextStraight:Vector.<Card> = possibleStraight.slice().concat(new <Card>[possibleNextCard]);
if (possibleNextStraight.length == straightLength)
foundStraights.push(possibleNextStraight);
else
possibleStraights.push(possibleNextStraight);
}
}
return foundStraights;
}
Given [1♥,2♥,3♣,3♥,4♣] you get: [1♥,2♥,3♣], [1♥,2♥,3♥], [2♥,3♣,4♣], [2♥,3♥,4♣]
It gets really interesting when you have a lot of duplicates, like [1♥,1♣,1♦,1♠,2♥,2♣,3♦,3♠,4♣,4♦,4♥]. This gives you:
[1♥,2♥,3♦], [1♥,2♥,3♠], [1♥,2♣,3♦], [1♥,2♣,3♠], [1♣,2♥,3♦], [1♣,2♥,3♠], [1♣,2♣,3♦], [1♣,2♣,3♠], [1♦,2♥,3♦], [1♦,2♥,3♠], [1♦,2♣,3♦], [1♦,2♣,3♠], [1♠,2♥,3♦], [1♠,2♥,3♠], [1♠,2♣,3♦], [1♠,2♣,3♠], [2♥,3♦,4♣], [2♥,3♦,4♦], [2♥,3♦,4♥], [2♥,3♠,4♣], [2♥,3♠,4♦], [2♥,3♠,4♥], [2♣,3♦,4♣], [2♣,3♦,4♦], [2♣,3♦,4♥], [2♣,3♠,4♣], [2♣,3♠,4♦], [2♣,3♠,4♥]
I haven't checked this thoroughly but it looks right at a glance.

How to access individual variable inside of a 2d array Actionscript 3

Im trying to access an individual tile inside of my 2d array of tiles
Ive created my array like so:
private var map:Array = [[25,25]];
ive tried several ways including:
map[1][1] = 1;
all that does is give me this:
ReferenceError: Error #1056: Cannot create property 1 on Number.
ive also tried:
map[[1,1]] = 1;
nothing happends that I can tell
The only way that ive tried so far that gets me a result thats not an error is:
map[1,1] = 1;
The issue here is this selects the whole row.
Any help would be apreciated..thanks!
This is not correct way to create 2D array:
private var map:Array = [[25,25]];
This array contains one array which contains two elements. You can't address to the second element like this:
map[1][1] = 1;
because the second element (array) of map doesn't exist.
You can create 2D array this way:
var map:Array = [];
for (var i:int = 0; i < rows; i++)
{
map[i] = [];// this line adds new row to the 2D array
// To fill the array by zeros add next loop
for (var j:int = 0; j < cols; j++)
{
map[i][j] = 0;
}
}
To start, I think that to get the error mentioned in your question, your array should looks like this :
var map:Array = [
[25, 25], // map[0] = [25, 25] ( array of two elements )
35 // map[1] = 35 ( just a simple number )
];
So, if you write :
trace(typeof map[1]); // gives : number
You will get : number, and that's why you can not right : map[1][1] = value; and it's normal that you got the #1056 error.
Here, I don't know if you meant assign the value 1 to your 2nd 25 of map[0] or you want really add or edit map[1][1], in the 1st case, you can simply write :
map[0][1] = 1; // gives : map[0] = [25, 1]
In the 2nd case, you can do :
map[1] = [any_other_value, 1]; // gives : map[1] = [any_other_value, 1]
Last remark, forget that you got an error and suppose that your map array was just:
var map:Array = [
[25, 25]
];
Here, you can not also write map[1][1] = value;, why ? Let's use the same method :
trace(map[1]); // gives : undefined
So sure you can not add a property to an undefined, that's why when you write :
map[1][1] = value;
You will get an #1010 error : "undefined has no properties. ".
Of course here, we should firstly create map[1] :
map[1] = []; // or directly map[1] = [any_other_value, value]
And then :
map[1][1] = value;
Hope that can help.

Search a substring in an array of Strings in unityscript

I'm trying to search a substring in an array of Strings. I'm using the following code (in Unity3):
var obstacles = ["Border", "Boundary", "BoundaryFlame"];
var frontAvailable = true;
var leftAvailable = true;
var rightAvailable = true;
var hitFront: RaycastHit;
if (Physics.Raycast(transform.position, transform.position + transform.forward, hitFront, 1.5)) {
Debug.Log("I hit this in front: ");
Debug.Log(hitFront.collider.gameObject.name);
for (var i = 0; i < obstacles.length; i++)
{
if (obstacles[i].IndexOf(hitFront.collider.gameObject.name) > -1)
{
Debug.Log("Hit in front!");
frontAvailable = false;
}
}
}
The problem is, the Debug.Log shows Boundary(Clone). I've included Boundary in the array obstacles. Shouldn't below code set frontAvailable to false? Or did I make a mistake here?
In addition to Kolink's answer, your if is looking for Boundary(clone) at the beginning of Boundary, rather than the other way around. I think you're looking for:
if (hitFront.collider.gameObject.name.IndexOf(obstacles[i]) >= 0)
I think you need indexOf, not IndexOf. Assuming you're talking about the native string function.
In addition, indexOf returns -1 if there is no match, 0 if the match is at the start, 1, 2, 3... for further positions. So you need > -1 instead of > 0

Array is being NULL, don't know how

trace (suallar); - is written 2 times
1st time - HERE IT SHOWS ALL THE ELEMENTS OF THE ARRAY suallar
2nd time - BUT HERE THIS ARRAY SEEMS TO BE EMPTY, EVEN THOUGH I DIDN'T MANIPULATE WITH IT OR MAKE IT EQUAL TO ANYTHING I MANIPULATE WITH IN BETWEEN
var suallar:Array = new Array();
var i:int;
var cavablar:Array=new Array();
suallar.push(["sual1", "duz1", "sehv11", "sevh12", "sevh13","sevh14"]);
suallar.push(["sual2", "duz2", "sehv21", "sevh22","sevh23","sevh24" ]);
suallar.push(["sual3", "duz3", "sehv31", "sevh32","sevh33","sevh34"]);
suallar.push(["sual4", "duz4", "sehv41", "sevh42","sevh43","sevh44"]);
suallar.push(["sual5", "duz5", "sehv51", "sevh52","sevh53","sevh54"]);
var cavablar_temp:Array = suallar.concat();
for (i=0; i<suallar.length; i++){
cavablar_temp[i].shift();
}
trace (suallar);
for (i=0; i<suallar.length;i++){
var number_array:Array = cavablar_temp[i];
var final_array:Array = [];
var count_selected:int = 5;
for (var u = 0; u < count_selected; u++)
{
if (number_array.length == 0)
{
break;
}
else
{
final_array.push(number_array.splice(Math.floor(Math.random() * number_array.length), 1)[0]);
}
}
cavablar.push(final_array);}
trace(cavablar.join("\n"));
trace (suallar);
As per the Array.splice() documentation:
Adds elements to and removes elements from an array. This method modifies the array without making a copy.
When you do number_array.splice() in the middle of your loop, you're modifying the original arrays you pushed to suallar.
Take a look at Array.slice(), which returns a new array without modifying the original.

Resources