The Most Challenging Interview Question

G

Garrett Smith

David said:
Stefan said:
I assume you meant splice - if you use delete, the loop direction
doesn't matter.

[...]
I suppose something like this:-
[...]

That's a little ugly. Could be re-factored in any number of ways.

How about a forward loop using splice?

function removeThrees(a) {
for(var i = 0; i < a.length; i++) {
if(a === 3) {
a.splice(i,1);
}
}
return a;
}

[...]
 
G

Garrett Smith

Garrett said:
David said:
Garrett said:
Dmitry A. Soshnikov wrote:
On 08.05.2010 23:56, Garrett Smith wrote:
David Mark wrote:
Garrett Smith wrote:
[...]


Like it or not, these things are industry standard. jQuery and Mootools,
in particular, seem to elicit a devotion that is part of the social.

s/social/meme
 
D

David Mark

Garrett said:
Garrett said:
David said:
Garrett Smith wrote:
Dmitry A. Soshnikov wrote:
On 08.05.2010 23:56, Garrett Smith wrote:
David Mark wrote:
Garrett Smith wrote:
[...]


Like it or not, these things are industry standard. jQuery and
Mootools, in particular, seem to elicit a devotion that is part of the
social.

s/social/meme

Doesn't really matter. Fads come and go. If I had to interview for
such a position, I could just point them to My Library. It does
everything the others do and more (with considerably more style). The
OO interface isn't that far off from the others (except that the
metaphors actually make sense). What's to argue? Are the others
somehow better because they required a million monkey effort spanning
several years? Do support clients really want to be ignored (roughly)
25% of the time and misled most of the rest?

If they really need proof, it's no further away than my SlickSpeed test,
which clearly demonstrates the futility of those "major" projects (and
CSS selector queries in general). Then there are the TaskSpeed results,
which demonstrate that the others are not only scatter-shot, but often
slow about it. And nobody sane could look at my Examples page and
conclude that they'd be better off using a jQuery or Mootools mish-mash.

I refuse to believe that everyone involved with this stuff is
irretrievably dense.
 
D

David Mark

Garrett Smith wrote:

[...]
How about a forward loop using splice?

function removeThrees(a) {
for(var i = 0; i < a.length; i++) {
if(a === 3) {
a.splice(i,1);
}
}
return a;
}


I just don't care to evaluate the length property each time through (or
to splice one member at a time), even in an example. And though
slightly longer, I consider mine to be easier to understand at a glance.
YMMV.

The strict comparison is a good idea in this case though.
 
M

Mike Duffy

Sorry, the answer is:

"One of its legs is both the same."

(and note the correct usage of "its" )

You guys 'quack me up' !

but enough already :(

Yeh, flock off!
 
G

Garrett Smith

David said:
Garrett Smith wrote:
[...]

I just don't care to evaluate the length property each time through (or
to splice one member at a time), even in an example. And though
slightly longer, I consider mine to be easier to understand at a glance.

It is not surprising that you would find your solution easier to
understand; you wrote it. However, it is longer and more complicated.
Although the while loop was very fast, it was not as fast as the for loop.

Cyclomatic complexity is number of decisions +1.

The while-loop based function has a while loop, a nested while loop, and
two decisions: `if` and ternary `?`. It has a count of 5.

The for loop with one decision has a count of 3.

If I am wrong about the cyclomatic complexity calculation, somebody
please correct me.

Neither are very complicated, but the for loop is shorter, simpler, and
more straightforward. It wins by a small margin.

The array filter approach not as fast, as is to be expected, however it
is the simplest of all, with cyclomatic complexity of 2.
YMMV.

The strict comparison is a good idea in this case though.

Making sure the code does what expected of it is the most important thing.
 
D

David Mark

Garrett said:
David said:
Garrett Smith wrote:
[...]

I just don't care to evaluate the length property each time through (or
to splice one member at a time), even in an example. And though
slightly longer, I consider mine to be easier to understand at a glance.

It is not surprising that you would find your solution easier to
understand; you wrote it. However, it is longer and more complicated.
Although the while loop was very fast, it was not as fast as the for loop.

Cyclomatic complexity is number of decisions +1.

The while-loop based function has a while loop, a nested while loop, and
two decisions: `if` and ternary `?`. It has a count of 5.

The for loop with one decision has a count of 3.

If I am wrong about the cyclomatic complexity calculation, somebody
please correct me.

Neither are very complicated, but the for loop is shorter, simpler, and
more straightforward. It wins by a small margin.

The array filter approach not as fast, as is to be expected, however it
is the simplest of all, with cyclomatic complexity of 2.

I think you are oversimplifying. For one, it depends very much on the
data in this case. Only way to be sure is to benchmark it with various
data sets. I can't say as I'm interested enough to do it though.
 
G

Garrett Smith

David said:
[...]
The array filter approach not as fast, as is to be expected, however it
is the simplest of all, with cyclomatic complexity of 2.

I think you are oversimplifying. For one, it depends very much on the
data in this case. Only way to be sure is to benchmark it with various
data sets. I can't say as I'm interested enough to do it though.
How does cyclomatic complexity depend on the data?

[1,2,3,4,5,2,4,21,7,4,2,8].filter(function(i){
return i !== 3;
});


I count one decision: i !== 3.
 
R

Ry Nohryb

Garrett Smith wrote:

[...]


How about a forward loop using splice?
function removeThrees(a) {
  for(var i = 0; i < a.length; i++) {
    if(a === 3) {
      a.splice(i,1);
    }
  }
  return a;
}


I just don't care to evaluate the length property each time through (or
to splice one member at a time), even in an example.  And though
slightly longer, I consider mine to be easier to understand at a glance.
 YMMV.

The strict comparison is a good idea in this case though.


Hey, that code skips over any item coming after a 3... geniuses!
 
R

Ry Nohryb

(...)
function removeThrees(array) {
   var b = a.slice(),
       j = 0,
       i = j,
       el;
   for(; i < b.length; i++) {
     el = b;
     if(el !== 3) {
       a[j++] = el;
     }
   }
   a.length = j;
   return a;

}

I can't see how using `splice` in a forwards loop would be a problem at
all. I find that approach to be easy to understand and I use it in my
own code.


LOL. No wonder the FAQ is as it is.

function removeThrees (a) {
var i= 0;
while (i < a.length) a === 3 ? a.splice(i, 1) : i++;
return a;
}
 
D

David Mark

Ry said:
Garrett Smith wrote:

[...]


How about a forward loop using splice?
function removeThrees(a) {
for(var i = 0; i < a.length; i++) {
if(a === 3) {
a.splice(i,1);
}
}
return a;
}

I just don't care to evaluate the length property each time through (or
to splice one member at a time), even in an example. And though
slightly longer, I consider mine to be easier to understand at a glance.
YMMV.

The strict comparison is a good idea in this case though.


Hey, that code skips over any item coming after a 3... geniuses!


I didn't write it (or review it), jackass!
 
D

David Mark

Garrett said:
David said:
Garrett said:
David Mark wrote:
Garrett Smith wrote:
[...]
The array filter approach not as fast, as is to be expected, however it
is the simplest of all, with cyclomatic complexity of 2.

I think you are oversimplifying. For one, it depends very much on the
data in this case. Only way to be sure is to benchmark it with various
data sets. I can't say as I'm interested enough to do it though.
How does cyclomatic complexity depend on the data?

[1,2,3,4,5,2,4,21,7,4,2,8].filter(function(i){
return i !== 3;
});

I was referring to your assertion (apparently based on this principle)
that yours was faster than mine, which is an oversimplified
generalization. It clearly depends on the data.
 
D

David Mark

Ry said:
(...)
function removeThrees(array) {
var b = a.slice(),
j = 0,
i = j,
el;
for(; i < b.length; i++) {
el = b;
if(el !== 3) {
a[j++] = el;
}
}
a.length = j;
return a;

}

I can't see how using `splice` in a forwards loop would be a problem at
all. I find that approach to be easy to understand and I use it in my
own code.


LOL. No wonder the FAQ is as it is.

function removeThrees (a) {
var i= 0;
while (i < a.length) a === 3 ? a.splice(i, 1) : i++;
return a;
}


Terrible. Don't use the ternary operator in that fashion.
 
R

Ry Nohryb

Ry said:
function removeThrees (a) {
  var i= 0;
  while (i < a.length) a === 3 ? a.splice(i, 1) : i++;
  return a;
}


Terrible.  Don't use the ternary operator in that fashion.


Yeah, the ternary operator was not designed to remove threes.
 
V

VK

In the first case it is static in VBA sense.

Ahgr... Got mixed up with those endless "static" meanings... Static in
Java sense of course, meaning that all instances of a given class
share the same single method instance provided by the constructor.
 
N

nick

[...]
Ry said:
[...]
function removeThrees (a) {
  var i= 0;
  while (i < a.length) a === 3 ? a.splice(i, 1) : i++;
  return a;
}

Terrible.  Don't use the ternary operator in that fashion.

Why not?

I'm not trying to sound rude, I am genuinely curious. I have almost
never seen the ternary operator used other than to the right of an
assignment operator, with the exception of two times, both recently...
once just now, and once in VK's ggNoSpam.

I just double-checked whether this kind of thing works in C++; it
seems to work fine there too.

So, I'm curious why you say not to do it. Is it because it's an
unusual thing to do and therefor difficult to read, or for a more
technical reason? I think I would naturally avoid using it like that
(not as part of an assignment), but only because it's something you
just don't see a lot.

For sparse arrays, I like:

function removeThrees (a) {
for (var i=0; i<a.length;)
if (a===3) a.splice(i, 1); else i++;
return a;
}

For dense arrays, this will also work:

function removeThrees (a) {
var i=0, e;
while (typeof (e=a)!='undefined')
if (e===3) a.splice(i, 1); else i++;
return a;
}
 
N

nick

Stylistically the long condition with the ternary operation is harder to
read.

Thanks, I figured it was something like that.
For sparse arrays, I like:
  function removeThrees (a) {
    for (var i=0; i<a.length;)
      if (a===3) a.splice(i, 1); else i++;
    return a;
  }


That fixes the consecutive threes bug in the one I wrote (ouch).


Yeah, I thought that looked a little too short when you wrote it, I'm
glad someone checked it ;)
For dense arrays, this will also work: [...]
Another try:
function removeThrees (a) {
   var i=0;
   while (i in a) {
     if (a === 3) {
       a.splice(i, 1);
     } else {
       i++;
     }
   }
   return a;}


'in' does seem a lot better there than the typeof undefined check.

What about combining the sparse and dense methods together like this?
Might be useful if evaluating 'x.length' happens to be slower than
evaluating 'y in x'. Also will work with array-like objects with no
length property (like the dense method), although that's probably not
really too useful.

function removeThrees (a) {
for (var i=0; i in a || i < a.length)
if (a===3) a.splice(i, 1); else i++;
return a;
}
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,079
Messages
2,570,574
Members
47,205
Latest member
ElwoodDurh

Latest Threads

Top