views:

146

answers:

5

How can I create a loop to output any given word like this:

...if the word is 'abcd'

a---
-b--
ab--
--c-
a-c-
-bc-
abc-
---d
a--d
-b-d
ab-d
--cd
a-cd
-bcd
abcd

in other words, letters appear in binary counter order

1000
0100
1100
0010
1010

etc.

Thanks

+1  A: 

Looks like you actually want the reverse of binary counting; i.e. for binary it would be

0001
0010
0011

but you're flipping it. Which is fine. The following code counts from 0 to the necessary number (16 for a four-letter word), gets the binary representation for each number, reverses it, and outputs the letters of your word for those places where there's a one in the binary representation.

function letterScroller(str) {
   var iterations = Math.pow(2,str.length);//iterate from 0 to 2**wordlength
   var result = "";
   for (i=0;i<iterations;i++) {
       //get the binary representation, pad it, and reverse it
       var bin = reverse(pad(i.toString(2), str.length));

       //loop through binary, adding character of word where there's a 1
       for (j=0;j<str.length;j++) {
           if (bin.charAt(j)=="1") {
               result += str.charAt(j)
           } else {
               result += "-";
           }
       }
       result += "<br />"; //separate lines with HTML line break
   }
   return result;
}

function pad(str, length) {
    while (str.length < length) {
       str="0" + str;
    }
    return str;
}

function reverse (str) {
  return str.split("").reverse().join("");
}
JacobM
Your reverse function is buggy
naugtur
I believe you, but can you give me an example of a potential bug? I'm getting the desired output.
JacobM
A: 

with KennyTM's code it can be done quite easily

String.prototype.reverse = function(){
splitext = this.split("");
revertext = splitext.reverse();
reversed = revertext.join("");
return reversed;
}

str='abcd'; //your string
for(var i=0;i<20;i++){ //a loop of numbers  
  var result='';

  var ii=i.toString(2).reverse();
  for(var q=0;q<Math.max(ii.length,str.length);q++){
    if(ii.charAt(q)=='1'){
      result+=str.charAt(q);
    }else{
      result+='-';
      }
  }      

 document.write(result+'<br>');
}

that was fun :) What do You need that for?

naugtur
I want to use it as a kind of progress indicator - like a spinner, but counting up...
rich13
If you replace the '20' with 'Math.pow(str.length,2)', you get the right number of loops...
rich13
+1  A: 
function doStuff(word) {
    var wordLength = word.length, num = 1 << wordLength;
    var i, bit, wordChars = word.split(""), chars;
    for (var i = 1; i < num; ++i) {
        chars = [];
        for (bit = 0; bit < wordLength; ++bit) {
            chars.push( i & 1 << bit ? wordChars[bit] : "-" );
        }
        console.log( chars.join("") );
    }
}

doStuff("abcd");
Tim Down
A: 

Here's the short version:

var string = 'abcd';
for (i = 1; i < Math.pow(string.length,2); i++) {
    str = "";
    for (j = 0; j < string.length; j++) {
        if (i & (1 << j)) 
            str += string[j];
        else
           str += "-";
    }
 console.log(str);
}

Enjoy!

Dan
+4  A: 
var i = 1;
console.log("abcd".replace(/./g, function(c,n) { 
   return (i & (1 << n)) ? c : '-';
}));

Just loop i from 1 to (2 ^ length) -1

Chetan Sastry
Haha, yours is even shorter! Nice. :)
Dan
sweet..........
stereofrog
this is a great one - short *and* sweet :-)
rich13
cool. If we were playing golf it'd be a hole in one :P +1!
naugtur