I'm quite new to F# and wanted to attempt to make a simple countdown; however, in the code below, it tells me there is something wrong with the "t..0".
let countdown x =
let mutable t = 10
for t..0 do
t=t-1
I want it to countdown in the terminal from 10 to 0.
There are three issues with your snippet. First, you do not need to decrement the t in a for loop - this happens automatically. Second, if you want a range like t .. 0 to go down, you need to specify -1 as the step. Also, your syntax for a for loop needs to define a variable (and you do not need to do this outside of the loop):
let countdown x =
for t in 10 .. -1 .. 0 do
printfn "Counting: %d" t
Tomas' answer shows the range syntax, but there's also the imperative syntax, analogous to for loops.
for i = 10 downto 1 do
printfn "Counting: %d" i
For counting up, use for i = 0 to 10.
Try this:
var i = 10;
var interval = setInterval( increment, 1000);
function increment(){
i = i - 1;
if(i <= -1) {
return
}
console.log(i);
}
Breakdown:
Where the countdown should start:
var i = 10;
The increment interval: (usually 1000ms)
var interval = setInterval( increment, 1000);
The actual countdown:
function increment(){
i = i - 1;
If counter goes into negative numbers, stop counting:
if(i <= -1) {
return
}
Write result in the console log:
}
console.log(i);
}
Related
I have got a working scala code for New Year Chaos problem in Hackerrank, but Im recieving timeout errors in some test cases
https://www.hackerrank.com/challenges/new-year-chaos/problem?h_l=interview&playlist_slugs%5B%5D=interview-preparation-kit&playlist_slugs%5B%5D=arrays
Please help me with optimization of below code:
def minimumBribes(q: Array[Int]){
val c = q.sorted
var swap = 0
var count_swap=0
import scala.util.control._
val loop = new Breaks
var temp = 0
var flag = true
loop.breakable
{
for (i <- q.length-1 to 0 by -1)
{
swap = 0
if (q(i) != i+1)
{
swap=i-q.indexOf(i+1)
if (swap > 2) {println("Too Chaotic");flag=false;loop.break()}
else
{
temp= q(q.indexOf(i+1))
q(q.indexOf(i+1)) = q(i-1)
q(i-1) = q(i)
q(i) = temp
count_swap += swap
if(q.deep == c.deep){
loop.break()
}
}
}
}
}
if (flag)println(count_swap)
}
To be honest I don't understand your implementation but
1) q.sorted could possibly already run out of time given that n is ~10^5.
2) q.sorted call is actually redundant since it's just a 1..n sequence.
3) using q.indexOf makes your algorithm O(n^2) complex. It's possible to solve it in linear time.
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.
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
Loop index (i) is not what I'm expecting when I use Protractor within a loop.
Symptoms:
Failed: Index out of bound. Trying to access element at index:'x', but there are only 'x' elements
or
Index is static and always equal to the last value
My code
for (var i = 0; i < MAX; ++i) {
getPromise().then(function() {
someArray[i] // 'i' always takes the value of 'MAX'
})
}
For example:
var expected = ['expect1', 'expect2', 'expect3'];
var els = element.all(by.css('selector'));
for (var i = 0; i < expected.length; ++i) {
els.get(i).getText().then(function(text) {
expect(text).toEqual(expected[i]); // Error: `i` is always 3.
})
}
or
var els = element.all(by.css('selector'));
for (var i = 0; i < 3; ++i) {
els.get(i).getText().then(function(text) {
if (text === 'should click') {
els.get(i).click(); // fails with "Failed: Index out of bound. Trying to access element at index:3, but there are only 3 elements"
}
})
}
or
var els = element.all(by.css('selector'));
els.then(function(rawelements) {
for (var i = 0; i < rawelements.length; ++i) {
rawelements[i].getText().then(function(text) {
if (text === 'should click') {
rawelements[i].click(); // fails with "Failed: Index out of bound. Trying to access element at index:'rawelements.length', but there are only 'rawelements.length' elements"
}
})
}
})
The reason this is happening is because protractor uses promises.
Read https://github.com/angular/protractor/blob/master/docs/control-flow.md
Promises (i.e. element(by...), element.all(by...)) execute their then functions when the underlying value becomes ready. What this means is that all the promises are first scheduled and then the then functions are run as the results become ready.
When you run something like this:
for (var i = 0; i < 3; ++i) {
console.log('1) i is: ', i);
getPromise().then(function() {
console.log('2) i is: ', i);
someArray[i] // 'i' always takes the value of 3
})
}
console.log('* finished looping. i is: ', i);
What happens is that getPromise().then(function() {...}) returns immediately, before the promise is ready and without executing the function inside the then. So first the loop runs through 3 times, scheduling all the getPromise() calls. Then, as the promises resolve, the corresponding thens are run.
The console would look something like this:
1) i is: 0 // schedules first `getPromise()`
1) i is: 1 // schedules second `getPromise()`
1) i is: 2 // schedules third `getPromise()`
* finished looping. i is: 3
2) i is: 3 // first `then` function runs, but i is already 3 now.
2) i is: 3 // second `then` function runs, but i is already 3 now.
2) i is: 3 // third `then` function runs, but i is already 3 now.
So, how do you run protractor in loops?
The general solution is closure. See JavaScript closure inside loops – simple practical example
for (var i = 0; i < 3; ++i) {
console.log('1) i is: ', i);
var func = (function() {
var j = i;
return function() {
console.log('2) j is: ', j);
someArray[j] // 'j' takes the values of 0..2
}
})();
getPromise().then(func);
}
console.log('* finished looping. i is: ', i);
But this is not that nice to read. Fortunately, you can also use protractor functions filter(fn), get(i), first(), last(), and the fact that expect is patched to take promises, to deal with this.
Going back to the examples provided earlier. The first example can be rewritten as:
var expected = ['expect1', 'expect2', 'expect3'];
var els = element.all(by.css('selector'));
for (var i = 0; i < expected.length; ++i) {
expect(els.get(i).getText()).toEqual(expected[i]); // note, the i is no longer in a `then` function and take the correct values.
}
The second and third example can be rewritten as:
var els = element.all(by.css('selector'));
els.filter(function(elem) {
return elem.getText().then(function(text) {
return text === 'should click';
});
}).click();
// note here we first used a 'filter' to select the appropriate elements, and used the fact that actions like `click` can act on an array to click all matching elements. The result is that we can stop using a for loop altogether.
In other words, protractor has many ways to iterate or access element i so that you don't need to use for loops and i. But if you must use for loops and i, you can use the closure solution.
Hank did a great job on answering this.
I wanted to also note another quick and dirty way to handle this. Just move the promise stuff to some external function and pass it the index.
For example if you want to log all the list items on the page at their respective index (from ElementArrayFinder) you could do something like this:
var log_at_index = function (matcher, index) {
return $$(matcher).get(index).getText().then(function (item_txt) {
return console.log('item[' + index + '] = ' + item_txt);
});
};
var css_match = 'li';
it('should log all items found with their index and displayed text', function () {
$$(css_match).count().then(function (total) {
for(var i = 0; i < total; i++)
log_at_index(css_match, i); // move promises to external function
});
});
This comes in handy when you need to do some fast debugging & easy to tweak for your own use.
I am NOT arguing with the logic or wisdom of the far more learned people discussing above. I write to point out that in the current version of Protractor within a function declared as async, a for loop like the below (which I was writing in typeScript, incorporating flowLog from #hetznercloud/protractor-test-helper, though I believe console.log would also work here) acts like what one might naively expect.
let inputFields = await element.all(by.tagName('input'));
let i: number;
flowLog('count = '+ inputFields.length);
for (i=0; i < inputFields.length; i++){
flowLog(i+' '+await inputFields[i].getAttribute('id')+' '+await inputFields[i].getAttribute('value'));
}
producing output like
count = 44
0 7f7ac149-749f-47fd-a871-e989a5bd378e 1
1 7f7ac149-749f-47fd-a871-e989a5bd3781 2
2 7f7ac149-749f-47fd-a871-e989a5bd3782 3
3 7f7ac149-749f-47fd-a871-e989a5bd3783 4
4 7f7ac149-749f-47fd-a871-e989a5bd3784 5
5 7f7ac149-749f-47fd-a871-e989a5bd3785 6
...
42 7f7ac149-749f-47fd-a871-e989a5bd376a 1
43 7f7ac149-749f-47fd-a871-e989a5bd376b 2
As I understand it, the await is key here, forcing the array to be resolved up front (so count is right) and the awaits within the loop cause each promise to be resolved before i is allowed to be incremented.
My intent here is to give readers options, not to question the above.
The easier way for doing this these days
it('test case', async () => {
let elems = element.all(selector)
for (let i=0; i < await elems.count(); i++) {
console.log(await elems.get(i).getText())
}
});
I have problem with this array thing I am doing. U can just plug in the code and run.
I need to have 2 things display out of the same array and which ever is picked gets kickedout from the array and stashed into another one.
One of the 2 things that are displaying out is picked at random and the other one goes in order it was put in.
So the logic I applied, or tried applying and is not working very well is..
Once the 2 things display out and if u pick the index count, no numbers change since the index count becomes subtracted by one, so the object after it gets pushed up.
but if the random choice is picked the index count moves up by one since it needs to keep moving...
The error i get is this:
TypeError: Error #2007: Parameter child must be non-null.
at flash.display::DisplayObjectContainer/addChild()
at Level3Torture_fla::MainTimeline/civilizedorder()[Level3Torture_fla.MainTimeline::frame1:87]
at Level3Torture_fla::MainTimeline/goNext()[Level3Torture_fla.MainTimeline::frame1:114]
at Level3Torture_fla::MainTimeline/switchpic()[Level3Torture_fla.MainTimeline::frame1:79]
This is the Code:
import flash.sampler.NewObjectSample;
import flash.display.Sprite;
import flash.events.MouseEvent;
var eating_breakfast:Sprite;
var walking:Sprite;
var swimming:Sprite;
var art:Sprite;
var choices:Array = new Array ();
//Sprite Creation
eating_breakfast = new Sprite ();
eating_breakfast.graphics.beginFill(0xE39D43);
eating_breakfast.graphics.drawRect(0,0,50,50);
eating_breakfast.graphics.endFill();
eating_breakfast.x = 50;
eating_breakfast.y = 50;
walking = new Sprite ();
walking.graphics.beginFill(0xC3266C);
walking.graphics.drawRect(0,0,50,50);
walking.graphics.endFill();
walking.x = 100;
walking.y = 100;
swimming = new Sprite ();
swimming.graphics.beginFill(0x48AFD1);
swimming.graphics.drawRect(0,0,50,50);
swimming.graphics.endFill();
swimming.x = 150;
swimming.y = 150;
art = new Sprite ();
art.graphics.beginFill(0xafdb44);
art.graphics.drawRect(0,0,50,50);
art.graphics.endFill();
art.x = 200;
art.y = 200;
//adding sprites into array
choices.push( eating_breakfast);
choices.push(walking);
choices.push(swimming);
choices.push(art);
var indexcount = 0;
var randomize:Number;
var storageArray: Array = new Array ();
civilizedorder();
randomizedorder();
this.addEventListener(MouseEvent.CLICK,switchpic);
//pick the target generated object
function switchpic(t:MouseEvent)
{
//for index count
if (t.target == choices[indexcount])
{
storageArray.push(choices[indexcount]);
removeChild(choices [indexcount]);
removeChild(choices [randomize]);
choices.splice(indexcount,1);
goNext();
};
// for randomize
if (t.target == choices[randomize])
{
storageArray.push(choices[randomize]);
removeChild(choices [indexcount]);
removeChild(choices [randomize]);
choices.splice(randomize,1);
indexcount++;
trace("The Index count is" + indexcount);
goNext();
}
}
//generates the index count object
function civilizedorder()
{
addChild(choices [indexcount]);
choices[indexcount].x = 300;
}
trace("The number of choices in the choice array is " + choices.length);
//generates the randomized object
function randomizedorder()
{
randomize = Math.floor(Math.random() * choices.length);
trace("the random number is" + randomize);
if (randomize == indexcount )
{
randomizedorder();
}
else
{
addChild(choices [randomize]);
}
}
//EDIT
function goNext()
{
trace("The storagearray has " + (storageArray.length));
if (choices.length < 0 || choices.length > 0)
{
if (indexcount > choices.length-1)
{
indexcount = choices.length - 1;
}
civilizedorder();
randomizedorder();
}
}
It is giving me a new error now. It's called StackOverflow. I am not entirely sure what is going wrong now.
EDIT: To add a conditional and check if you will be out of bounds for adding a child in this array, try this:
if(indexcount <= choices.length){
addChild(choices [indexcount]);
}
Try commenting out the splicing in the switchpic() method. That or re-add those values/sprite instances to the array.
I think that you've sliced from the "choices" array twice in the switchpic() method, and never actually add to the array ever again. So you'll eventually end up with an empty choices array. Hence the error.
In the second conditional, if (t.target == choices[randomize]), you increment indexcount, and then call goNext() which regenerates the randomize value to not equal the indexcount, but also tries to re-add a child sprite.
This could cause an array of 4 items to become 2 items, and then, possibly, randomize = 0, indexcount = 1. In the second pass, you might have an array of 0 items, with randomize = 0, indexcount = 1 and the error to occur.
Here's the flow, I imagine:
It looks like you're clicking on an instance of a sprite.
Then it calls switchpic(), which executes:
...
choices.splice(indexcount,1);
...
and then goNext()
which calls civilizedorder()
which executes:
...
addChild(choices [indexcount]);
...
you should check indexcount is never outside of 0-3 range.
in function goNext(), change the code as follows:
function goNext()
{
trace("The storagearray has " + (storageArray.length));
if(choices.length <> 0)
{
if(indexcount > choices.length-1)
indexcount = choices.length-1;
civilizedorder();
randomizedorder();
}
}