2

The goal is to write a function that generate Gray codes for a certain value.

Currently I have this :

def gray(i: Int): List[String] = {
    if(i == 0) List("")
    else {
      val l = gray(i - 1)
      (l map {"0" + _}) ::: (l map{"1" + _})
    }
}

Output for gray(3) : List(000, 001, 010, 011, 100, 101, 110, 111)

Then I have tried to construct this List with a for loop. Imagine that :

for n = 2, I will have :

def gray(i: Int): List[String] = {
    (for{a <- 0 to 1
         b <- 0 to 1} yield a+""+b).toList 
}

for n = 3, I will have :

def gray(i: Int): List[String] = {
    (for{a <- 0 to 1
         b <- 0 to 1
         c <- 0 to 1} yield a+""+b+""+c).toList 
  }

Obviously this doesn't take in account i, so I was wondering if we can build such a function which construct a custom for loop expression using i.

By construct I mean :

if i == 2, create 2 variables for the loop and yield them, if i == 3 then create 3 and yield them, etc.

Is is possible ? (I'm a beginner in Scala)

2
  • "The one-bit Gray code is G1 = (0, 1). " your base case is wrong? Commented Nov 5, 2013 at 11:48
  • @StefanKunze Why ? If you have one bit available I will get List(0,1) because l map {"0" + _}) ::: (l map{"1" + _} will return List("0") ::: List("1") Commented Nov 5, 2013 at 11:49

3 Answers 3

5
def gray(n: Integer): List[List[Char]] = {
    if (n == 0) List(List()) else
      for {
        c : List[Char] <- gray(n - 1)
        i : Char <- List('0', '1')
      } yield i :: c
  }                  //> gray: (n: Integer)List[List[Char]]

val of0 = gray(0)    //> of0  : List[List[Char]] = List(List())
val of1 = gray(1)    //> of1  : List[List[Char]] = List(List(0), List(1))
val of2 = gray(2)    //> of2  : List[List[Char]] = List(List(0, 0), List(1, 0), List(0, 1), List(1, 1))
...
Sign up to request clarification or add additional context in comments.

1 Comment

Ok but that's also use the recursion way. Anyway you got my +1 =)
3

The reason you are not able to do so is because the for expression has to be specified at compile time, where as the i is only available at runtime. One option to do so would be to use macros which generate the required for expression but even in that case you will have to call that macro by passing a constant integer (rather a int variable which only resolves at runtime)

1 Comment

Since I begin Scala I suppose I shouldn't worry about that and go for the first option ?
1

that should do the trick?

object GrayTest {

  def gray(i:Int):List[String] =
  {
    if (i == 0 ) List("")
    else {
      val l = gray(i-1)
      l.map("0" + _) ::: l.reverse.map("1"+_)
    }
  }

  def main(arg:Array[String]) =
  {
    println(gray(3))
  }

}

3 Comments

I already build this function. And why do you reverse the list ? I think you misunderstood my question.
from wikipedia: The binary-reflected Gray code list for n bits can be generated recursively from the list for n−1 bits by reflecting the list (i.e. listing the entries in reverse order), concatenating the original list with the reversed list, prefixing the entries in the original list with a binary 0, and then prefixing the entries in the reflected list with a binary 1
Ok well that's the definition, but that's definitely not answer my question.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.