coffeescript for in bug? - coffeescript

On coffeescript loop 'for'
eg.
if 1 < x, code like below:
console.debug i for i in [1..0]
Generated code is:
var i;
for (i = 1; i >= 0; i--) {
console.debug(i);
}
if 1 > x,code like below:
console.debug i for i in [1..2]
Generated code is:
var i;
for (i = 1; i <= 2; i++) {
console.debug(i);
}
If i want write that javascript.How to ?
for(var i=1;i<=0;i++){
console.debug(i);
}
Because i don't know the condition is greater than left side or less than left side.
But i just want it i++
What's wrong with me?
EDIT BELOW:
For coffeescript's feature,I add condition before the loop or add condition on for loop.
eg:
if x - y >=1
console.debug i for i in [1..x-y]
or
console.debug i for i in [1..x-y] and x-y >=1
That's my way.Some one have good advice?

It looks like you want to do this:
console.debug i for i in [1..x-y] by 1
Which gets compiled to:
var i, _i, _ref;
for (i = _i = 1, _ref = x - y; _i <= _ref; i = _i += 1) {
console.debug(i);
}

for(var i=1;i<=0;i++){
console.debug(i);
}
is equivalent to
var i = 1;
while(true) {
console.debug(i);
i++;
}
which in coffeescript is written as
i = 1
while true
console.debug(i);
i++;

Related

How to create a layout that all its cells are initially empty and accessible by moving agents (such as equipment)?

In Copper Nickel Mine (Cloud) Simulation, In MinePanel Agent, there is a function Called setupTunnelLayout.
The original code in the above function is as following:
//create corridor of already empty rooms
`RoomBlock emptyRoom;
for ( int j = 0; j < nColumns; j++ ) {
emptyRoom = add_roomBlocks();
emptyRoom.jumpToCell( 0, j );
if ( j == nColumns - 1 )
emptyRoom.isStartBlock = true;
emptyRoom.isTunnel = true;
}`
But in my scenario all the cells are accessible initially, so all can be tunnel (path to move), not only the (0, j) row as the above example!
I was thinking I can change it as the followings; (1) or (2);
(1)
//create corridor of already empty rooms
RoomBlock emptyRoom;
for ( int j = 0; j < nColumns; j++ )
for (int i = 0; i < nRows; i++){
emptyRoom = add_roomBlocks();
emptyRoom.jumpToCell( 0, j );
emptyRoom.jumpToCell( i, 0 );
if ( j == nColumns - 1 )
emptyRoom.isStartBlock = true;
emptyRoom.isTunnel = true;
}
Or it can be like this;
(2)
//create corridor of already empty rooms
`RoomBlock emptyRoom;
for ( int j = 0; j < nColumns; j++ )
for (int i = 0; i < nRows; i++){
emptyRoom = add_roomBlocks();
emptyRoom.jumpToCell( i, j );
if ( j == nColumns - 1 )
emptyRoom.isStartBlock = true;
emptyRoom.isTunnel = true;
}`
'Can you please let me know if (1) or (2) are correct? Which one is preferred?
Thank you so much,
Neda.'
The second is preferable; there is no point jumping the agent to the column and then the row when you can directly move it to the exact cell coordinates.
In both cases though you are missing a closing } for your extra i loop (and you're missing an opening one in your second case).
//create corridor of already empty rooms
RoomBlock emptyRoom;
for (int j = 0; j < nColumns; j++) {
for (int i = 0; i < nRows; i++) {
emptyRoom = add_roomBlocks();
emptyRoom.jumpToCell(i, j);
if (j == nColumns - 1) {
emptyRoom.isStartBlock = true;
}
emptyRoom.isTunnel = true;
}
}
[I used the StackOverflow formatting to mark the full block as Java code. It's also best-practice (although AnyLogic doesn't do it many of their example models) to always use curly brackets for loops, etc. even if their body only has one line.]
Plus whether the change will do what you want or not obviously depends on the rest of the model and how it handles the grid of cells and tunnels.

Why does this quicksort function not work?

void swap(Person* a, int i, int j) {
Person b;
b = a[i];
a[i] = a[j];
a[j] = b;
}
void quicksort(Person* a, int left, int right, PersonComparator cmp) {
if (left >= right) return; // 0 or 1 elements, recursion end
swap(a, left, (left + right) / 2); // move pivot element to left
int j = left;
for (int i = left + 1; i <= right; i++) {
if (i < left) {
swap(a, ++j, i);
}
// assert: v[i] < v[left] for i = left+1..j
}
swap(a, left, j); // move back pivot element
quicksort(a, left, j-1, cmp); // assert: v[i] < v[j] for i = left..j-1
quicksort(a, j+1, right, cmp); // assert: v[i] >= v[j] for i = j+1..right
}
I somehow have to get this "cmp" in there but I don't know where and how. Person* is a pointer to the struct Person btw.
You need to learn to use a debugger. Without that, you are lost. Run your code with a debugger and check where the code does something that you don't expect.
I suppose these lines:
for (int i = left + 1; i <= right; i++) {
if (i < left) {
won't do what you expect. It looks more like a question of "why would you think this might ever work", and not "why doesn't it work". Especially since you don't seem to be using the comparator at all.

How to write a non-C-like for-loop in Swift 2.2+?

I have updated Xcode (7.3) and there are a lot of changes; C-like for expressions will be deprecated. For a simple example,
for var i = 0; i <= array.count - 1; i++
{
//something with array[i]
}
How do I write this clear and simple C-like for-loop to be compliant with the new changes?
for var i = 0, j = 1; i <= array.count - 2 && j <= array.count - 1; i++, j++
{
//something with array[i] and array[j]
}
Update.
One more variant
for var i = 0; i <= <array.count - 1; i++
{
for var j = i + 1; j <= array.count - 1; j++
{
//something with array[i] and array[j]
}
}
And more ...
for var i = 0, j = 1, g = 2; i <= array.count - 3 && j <= array.count - 2 && g <= array.count - 1; i++, j++, g++
{
//something with array[i] and array[j] and array[g]
}
Update2 After several suggestions for me while loop is preferable universal substitution for all cases more complicated than the simple example of C-like for-loop (suitable for for in expression). No need every time to search for new approach.
For instance: Instead of
for var i = 0; i <= <array.count - 1; i++
{
for var j = i + 1; j <= array.count - 1; j++
{
//something with array[i] and array[j]
}
}
I can use
var i = 0
while i < array.count
{
var j = i + 1
while j < array.count
{
//something with array[i] and array[j]
j += 1
}
i += 1
}
charl's (old) answer will crash. You want 0..<array.count:
for index in 0..<array.count {
// ...
}
If you want something like your i/j loop you can use stride and get i's successor:
for i in 0.stride(through: array.count, by: 1) {
let j = i.successor()
// ...
}
Just make sure to check i.successor() in case you go out of bounds.
for var i = 0; i <= array.count - 1; i++ {
//something with array[i]
}
Here you don't need the element index at all, so you can simply
enumerate the array elements:
for elem in array {
// Do something with elem ...
}
for var i = 0, j = 1; i <= array.count - 2 && j <= array.count - 1; i++, j++ {
//something with array[i] and array[j]
}
To iterate over pairs of adjacent elements, use zip()
and dropFirst():
for (x, y) in zip(array, array.dropFirst()) {
// Do something with x and y ...
print(x, y)
}
Output:
1 2
2 3
3 4
4 5
For other distances, use dropFirst(n):
for (x, y) in zip(array, array.dropFirst(3)) {
// Do something with x and y ...
print(x, y)
}
Output:
1 4
2 5
There are probably many solutions to do
for var i = 0; i <= <array.count - 1; i++ {
for var j = i + 1; j <= array.count - 1; j++ {
//something with array[i] and array[j]
}
}
without a C-style for-loop, here is one:
for (index, x) in array.enumerate() {
for y in array.dropFirst(index + 1) {
print(x, y)
}
}
If you want to do something with subsequent pairs there are many other ways to do it.
Something like this would work...
var previousItem = array.first
for index in 1..<array.count {
let currentItem = array[index]
// do something with current and previous items
previousItem = currentItem
}
for (i, j) in zip(array.dropLast(), array.dropFirst())
{
// something
}
What you're really doing here is enumerating two parallel sequences. So, create those sequences and use zip to turn them into a single sequence.
Do enumeration
let suits = ["♠︎", "♥︎", "♣︎", "♦︎"]
for (i, suite) in suits.enumerate() {
// ...
}
or to compare neighbors
import Foundation
let suits = ["♠︎", "♥︎", "♣︎", "♦︎"]
for (i, suite1) in suits.enumerate() {
let j = i.successor()
if j < suits.count {
let suite2 = suits[j]
// ...
}
}
or zipping and enumerating
let suits = ["♠︎", "♥︎", "♣︎", "♦︎"]
let combination = zip(suits, suits.dropFirst())
for (i, (s1,s2)) in combination.enumerate() {
print("\(i): \(s1) \(s2)")
}
result
0: ♠︎ ♥︎
1: ♥︎ ♣︎
2: ♣︎ ♦︎
Worst case, you can convert it to a while loop.
var i = 0
var j = 1
while i <= array.count -2 && j <= array.count - 1 {
// something
i += 1
j += 1
}
-- EDIT --
Because you said, "while loop is preferable universal substitution for all cases more complicated than the simple example of C-like for-loop"... I feel the need to expand on my answer. I don't want to be responsible for a bunch of bad code...
In most cases, there is a simple for-in loop that can handle the situation:
for item in array {
// do something with item
}
for (item1, item2) in zip(array, array[1 ..< array.count]) {
// do something with item1 and item2
}
for (index, item1) in array.enumerate() {
for item2 in array[index + 1 ..< array.count] {
// do soemthing with item1 and item2
}
}
For your last case, you might be justified using a for look, but that is an extremely rare edge case.
Don't litter your code with for loops.
to compare neighbouring elements from the same array you can use
let arr = [1,2,2,5,2,2,3,3]
arr.reduce(nil) { (i, j)->Int? in
if let i = i {
print(i,"==",j,"is",i == j)
}
return j
}
it prints
1 == 2 is false
2 == 2 is true
2 == 5 is false
5 == 2 is false
2 == 2 is true
2 == 3 is false
3 == 3 is true
more 'generic' approach without using subscript but separate generators
let arr1 = [1,2,3,4,5,6,7,8,9,0]
var g1 = arr1.generate()
var g2 = (arr1.dropFirst(5) as AnySequence).generate()
var g3 = (arr1.dropFirst(6) as AnySequence).generate()
while true {
if let a1 = g1.next(),
let a2 = g2.next(),
let a3 = g3.next() {
print(a1,a2,a3)
} else {
break
}
}
/* prints
1 6 7
2 7 8
3 8 9
4 9 0
*/

How to print in the console that figure?

I want to print that in the console:
*
**
***
**
*
so, my code is:
Scanner input = new Scanner(System.in);
int n = input.nextInt();
char c = '*';
if (1 < n && n < 20) {
for (int row = 1; row <= n; row++) {
for (int col = 1; col <= row; col++) {
System.out.print(c);
}
System.out.println();
}
any proposals how to finish?
You want to print "* **". Write this:
System.out.print("* **");
If my answer is not that what you excpected, than give us more information. What is your actual problem. See StackOverflowFAQ
If n is your "*" length,below code:
if (1 < n && n < 20) {
for (int row = 1; row <= n; row++) {
for (int col = 1; col <= row; col++) {
System.out.print(c);
}
System.out.println();
}
for (int row =1; row <= n; row++) {
for (int col = n-row; col >0 ; col--) {
System.out.print(c);
}
System.out.println();
}
}

simple loop in coffeescript

I have this code:
count = $content.find('.post').length;
for x in [1...count]
/*
prev_el_height += $("#content .post:nth-child(" + x + ")").height();
*/
prev_el_height += $content.find(".post:nth-child(" + x + ")").height();
I expected this to turn into
for (x = 1; x < count; x++) { prev_el ... }
but it turns into this:
for (x = 1; 1 <= count ? x < count : x > count; 1 <= count ? x++ : x--) {
Can somebody please explain why?
EDIT: How do I get my expected syntax to output?
In CoffeeScript, you need to use the by keyword to specify the step of a loop. In your case:
for x in [1...count] by 1
...
You're asking to loop from 1 to count, but you're assuming that count will always be greater-than-or-equal-to one; the generated code doesn't make that assumption.
So if count is >= 1 then the loop counter is incremented each time:
for (x = 1; x < count; x++) { /* ... */ }
But if count is < 1 then the loop counter is decremented each time:
for (x = 1; x > count; x--) { /* ... */ }
Well, you want x to go from 1 to count. The code is checking whether count is bigger or smaller than 1.
If count is bigger than 1, then it has to increment x while it is smaller than count.
If count is smaller than 1, then it has to decrement x while it is bigger than count.
For future reference:
$('#content .post').each ->
prev_el_height += $(this).height()
Has the same effect, assuming :nth-child is equivalent to .eq(), and x going past the number the elements is a typo.