help rewriting in functional style

后端 未结 5 2201
再見小時候
再見小時候 2021-02-10 10:46

I\'m learning Scala as my first functional-ish language. As one of the problems, I was trying to find a functional way of generating the sequence S up to n places. S is defined

5条回答
  •  不要未来只要你来
    2021-02-10 11:14

    Here is a very direct "translation" of the definition of the Golomb seqence:

    val it = Iterator.iterate((1,1,Map(1->1,2->2))){ case (n,i,m) =>
        val c = m(n)
        if (c == 1) (n+1, i+1, m + (i -> n) - n)
        else (n, i+1, m + (i -> n) + (n -> (c-1)))
    }.map(_._1)
    
    println(it.take(10).toList)
    

    The tripel (n,i,m) contains the actual number n, the index i and a Map m, which contains how often an n must be repeated. When the counter in the Map for our n reaches 1, we increase n (and can drop n from the map, as it is not longer needed), else we just decrease n's counter in the map and keep n. In every case we add the new pair i -> n into the map, which will be used as counter later (when a subsequent n reaches the value of the current i).

    [Edit]

    Thinking about it, I realized that I don't need indexes and not even a lookup (because the "counters" are already in the "right" order), which means that I can replace the Map with a Queue:

    import collection.immutable.Queue
    
    val it = 1 #:: Iterator.iterate((2, 2, Queue[Int]())){
      case (n,1,q) => (n+1, q.head, q.tail + (n+1))
      case (n,c,q) => (n,c-1,q + n)
    }.map(_._1).toStream
    

    The Iterator works correctly when starting by 2, so I had to add a 1 at the beginning. The second tuple argument is now the counter for the current n (taken from the Queue). The current counter could be kept in the Queue as well, so we have only a pair, but then it's less clear what's going on due to the complicated Queue handling:

    val it = 1 #:: Iterator.iterate((2, Queue[Int](2))){
      case (n,q) if q.head == 1 => (n+1, q.tail + (n+1))
      case (n,q) => (n, ((q.head-1) +: q.tail) + n)
    }.map(_._1).toStream 
    

提交回复
热议问题