## Look And Say

### March 15, 2011

This exercise is a celebration of the Standard Prelude. Function `look-and-say`

returns the next number in the sequence:

`(define (look-and-say n)`

(define (flip x) (cons (cdr x) (car x)))

(undigits (flatten (map flip (uniq-c = (digits n))))))

If that looks tricky, it helps to break it down in stages. For instance, to compute the successor of 1211, working from the inside out:

**digits n**: `(1 2 1 1)`

**uniq-c =**: `((1 . 1) (2 . 1) (1 . 2))`

**map flip**: `((1 . 1) (1 . 2) (2 . 1))`

**flatten**: `(1 1 1 2 2 1)`

**undigits**: `111221`

Then it is easy to compute the first *n* terms of the sequence:

`(define (look-and-say-sequence n)`

(iterate n look-and-say 1))

Here’s the output:

`> (look-and-say-sequence 10)`

(1 11 21 1211 111221 312211 13112221 1113213211

31131211131221 13211311123113112211)

We used `iterate`

, `flatten`

, `uniq-c`

, `digits`

and `undigits`

from the Standard Prelude. You can run the program at http://programmingpraxis.codepad.org/XC60i6ec.

Here’s a quick solution in ghci:

Prelude> import Data.List

Prelude Data.List> let n = concatMap (\x -> (show $ length x) ++ [head x]) . group

Prelude Data.List> take 10 $ iterate n “1”

[“1″,”11″,”21″,”1211″,”111221″,”312211″,”13112221″,”1113213211″,”31131211131221″,”13211311123113112211”]

My Haskell solution (see http://bonsaicode.wordpress.com/2011/03/15/programming-praxis-look-and-say/ for a version with comments):

[…] today’s Programming Praxis exercise, our task is to generate the Look and Say sequence (1, 11, 21, 1211, […]

A Python solution:

Using the

`groupby()`

function from Python’s itertools module:Looks like Dave beat me to it :-) I should have refreshed the page before posting.

Clojure solution:

(defn lookandsay [s]

(mapcat (juxt count first)

(partition-by identity s)))

(take 10 (iterate lookandsay [1]))

A listless solution, integer to integer, in Scheme.

Output using iterate from that Standard Prelude.

Because Sloane’s is a catalogue of integer sequences, I wrote a generator that return successive integers of the sequence.

My first version is basically the same as Webb’s and Graham’s above, so I also did a second version using the regular expression library.

I was somewhat suprised that the second version appears to be slightly faster, based on using the timeit module.

My try in REXX

[…] autre petit exercice de Programming Praxis, programmer la suite Look and Say. Ce n’est pas très difficile : import Data.List import […]

My Haskell solution

in scala:

def lookAndSay(previous:List[Int]) : Stream[List[Int]] = {

def next(num : List[Int]) : List[Int] = num match {

case Nil => Nil

case head :: Nil => 1 :: head :: Nil

case head :: tail => {

val size = (num takeWhile{_ == head}).size

List(size, head) ::: next(num.drop(size))

}

}

val x = next(previous)

x #:: lookAndSay(x)

}

lookAndSay(1::Nil) take 10 foreach (println _)

Here’s a JS solution. I’ve only been programming for about a year, mostly JS and PHP. Going to attempt a PHP version next, then subsequently, ajax-ify it.

Look and Say Sequence

var start = false;

var result;

function lookSay(int, repeat) {

for (t=1; t<=repeat; t++) {

if (!start) {

start = int;

result = start+"”;

}

newNumber = “”;

digit = start.charAt(0);

count = 1;

for (var i = 1; i < start.length; i++) {

if (digit == start.charAt(i)) {

count++;

}

else {

newNumber = newNumber + count + digit;

digit = start.charAt(i);

count = 1;

}

}

start = newNumber + count + digit;

if (t == repeat) {

result+=start;

document.getElementById('result').innerHTML=result;

start = false;

result = '';

}

else {

result +=start+"”;

}

}

}

function returnResult() {

s = document.getElementById(‘start’).value;

r = document.getElementById(‘repeat’).value;

lookSay(s, r);

}

Start Integer:

Repeat Amount:

Submit

A Scheme solution using lists is:

A ruby version:

sloane = [1]

puts sloane.inspect

8.times.each do |iteration|

new_sloane = []

rep_digit = 1

last_sum = sloane.inject(0) do |sum, digit|

next sum + 1 if digit == rep_digit

new_sloane << rep_digit

new_sloane << sum

rep_digit = digit

1

end

new_sloane << rep_digit

new_sloane << last_sum

puts sloane.replace(new_sloane).reverse.inspect

end

[/sourcecode]

Mine in F#

Here is a solution in Factor:

http://re-factor.blogspot.com/2011/03/look-and-say.html

For the curious, Factor looks like this:

: look-and-say ( n — n’ )

number>string [ = ] monotonic-split [

[ length ] [ first ] bi "%d%c" sprintf

] map concat string>number ;

is anybody have solution in c plz upload here

Rohit, check my website link here for a version in C. Please note that it is NOT written for clarity. But it is in C, and it works. Increase the ‘M’ constant if you want more numbers in the series; for example, 1000000 gives you the first 49 terms.