Point-free look and say sequence

11

1

You are too make a program that take an integer as the input and outputs the first what ever that number was of the look and say sequence.

For example:

$ ./LAS
8
[1,11,21,1211,111221,312211,13112221,1113213211]

The exact way you output the list is unimportant, as long as users can distinctly see the different numbers of the sequence. Here is the catch though. You can't use any sort of user-defined variable.

For example:

  1. No variables, including scoped variables.
  2. When you have functions, they can not have a name. (Exception, if your language requires a main function or similar to work, you may have that function.)
  3. When you have functions, they can not have named arguments.

Also, you may not use a library with specific capabilities relating to the look and say sequence, and you can not access the network, or provide your program with any files (although it can generate and use its own.) This is code golf, so shortest code in characters wins!

PyRulez

Posted 2014-03-12T00:13:10.417

Reputation: 6 547

1What is "EXTREME POINT FREENESS"? – Justin – 2014-03-12T03:44:15.923

1

@Quincunx I had to look it up: http://stackoverflow.com/questions/944446/what-is-point-free-style-in-functional-programming

– Digital Trauma – 2014-03-12T05:37:51.960

Can you explain this rule: When you have functions, they can not have named arguments.? – n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳ – 2014-03-12T07:35:12.223

Same sequence, different code constraint – Peter Taylor – 2014-03-12T10:25:13.397

3@ n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳ In several languages (like the J language or stack/based languages like forth or postscript), functions don't have argument; they apply to some external context (a stack or arguments coming from an external scope). – Thomas Baruchel – 2014-03-12T11:54:32.587

Answers

6

GolfScript (31 chars)

~[]\{[1\{.2$={;\)}1if\}*].n@}*;

Adapted from my answer to a previous look-and-say question. This one has a less onerous restriction for functional languages, which allows saving 5 chars, but because most answers to the previous question can't be adapted (it's a crazily onerous restriction for non-functional languages) I don't think it makes sense to close it as a dupe.

Peter Taylor

Posted 2014-03-12T00:13:10.417

Reputation: 41 901

11

Haskell 206 Chars

import Data.List
import Control.Applicative
import Data.Function
main= readLn >>= print .(flip take (map read $ fix (("1":). map (concat .(map ((++)<$>(show . length)<*>((:[]). head))). group))::[Integer]))

It works by using the group function to group them into groups of equal things. Then it uses applicatives with functions to build a function that simultaneously reads the length, and appends it to with one the elements. It uses a fix and a map to create a recursive definition (point-free.) And there ya go.

PyRulez

Posted 2014-03-12T00:13:10.417

Reputation: 6 547

10

J (42 chars)

Point-free (also called tacit) programming is natural in J.

,@:((#,{.);.1~(1,}.~:}:))&.>^:(<`((<1)"_))

That's a function, to use it you write the code, a space, and the input number. For example,

   ,@:((#,{.);.1~(1,}.~:}:))&.>^:(<`((<1)"_)) 8
┌─┬───┬───┬───────┬───────────┬───────────┬───────────────┬───────────────────┐
│1│1 1│2 1│1 2 1 1│1 1 1 2 2 1│3 1 2 2 1 1│1 3 1 1 2 2 2 1│1 1 1 3 2 1 3 2 1 1│
└─┴───┴───┴───────┴───────────┴───────────┴───────────────┴───────────────────┘

Notice the pretty boxes in the output.

Addendum: Here are a couple of "cheats" I was too bashful to use at first, but now that I've seen other use them first...

  • Here's a 36 char version with a different "calling convention": replace 8 with the number of terms you want.

    ,@:((#,{.);.1~(1,}.~:}:))&.>^:(<8)<1
    
  • And if having extra zeroes in the output is OK, here's a 32 char version:

    ,@:((#,{.);.1~(1,}.~:}:))^:(<8)1
    

Omar

Posted 2014-03-12T00:13:10.417

Reputation: 1 154

7

GolfScript, 36 chars

~([1]\{.[0\{.2$=!{0\.}*;\)\}/](;}*]`

Variables are pretty rarely used in GolfScript, and this task certainly doesn't need them. Input is on stdin, output to stdout. For example, the input 8 gives the output:

[[1] [1 1] [2 1] [1 2 1 1] [1 1 1 2 2 1] [3 1 2 2 1 1] [1 3 1 1 2 2 2 1] [1 1 1 3 2 1 3 2 1 1]]

I may write a detailed explanation of this code later, but at least you can easily tell that it uses no variables by the fact that it doesn't include the variable assignment operator : anywhere.

Ilmari Karonen

Posted 2014-03-12T00:13:10.417

Reputation: 19 513

6

Bash and coreutils, 111 73 chars

eval echo 1\|`yes 'tee -a o|fold -1|uniq -c|(tr -dc 0-9;echo)|'|sed $1q`:

uniq -c is doing the heavy lifting to produce the next number in the sequence. yes, sed and eval create the necessary number of repeats of the processing pipeline. The rest is just formatting.

Output is placed in a file called o.:

$ ./looksay.sh 8
ubuntu@ubuntu:~$ cat o
1
11
21
1211
111221
312211
13112221
1113213211
$ 

Digital Trauma

Posted 2014-03-12T00:13:10.417

Reputation: 64 644

6

Haskell, 118 chars (80 without imports)

import Data.List
import Control.Monad
main=readLn>>=print.flip take(iterate(ap((++).show.length)(take 1)<=<group)"1")

Niklas B.

Posted 2014-03-12T00:13:10.417

Reputation: 477

4

Mathematica, 65 chars

FromDigits/@NestList[Flatten@Reverse[Tally/@Split@#,3]&,{1},#-1]&

Example:

FromDigits/@NestList[Flatten@Reverse[Tally/@Split@#,3]&,{1},#-1]&[8]

{1, 11, 21, 1211, 111221, 312211, 13112221, 1113213211}

alephalpha

Posted 2014-03-12T00:13:10.417

Reputation: 23 988

3

J, 37 characters

1([:,((1,2&(~:/\))(#,{.);.1]))@[&0~i.

Based on my answer to the Pea Pattern question. There may be some potential for shortening here. Usage is as for the other J answer:

   1([:,((1,2&(~:/\))(#,{.);.1]))@[&0~i. 7
1 0 0 0 0 0 0 0
1 1 0 0 0 0 0 0
2 1 0 0 0 0 0 0
1 2 1 1 0 0 0 0
1 1 1 2 2 1 0 0
3 1 2 2 1 1 0 0
1 3 1 1 2 2 2 1

It also has the extra zeroes problem my pea pattern answer had.

Gareth

Posted 2014-03-12T00:13:10.417

Reputation: 11 678

Ah, there's more than one previous question, and more answers from that one can be copied to this one without any tweaks at all than from the question I found. I'm almost convinced to vote to close as dupe. – Peter Taylor – 2014-03-12T12:32:50.773

@PeterTaylor The Pea pattern one is slightly different in that you have to sort the numbers in the previous line before creating the next. – Gareth – 2014-03-12T12:35:21.023

2

Perl 6: 63 53 characters

say (1,*.subst(/(\d)$0*/,{.chars~.[0]},:g)...*)[^get]

Create a lazy list of the Look and Say sequence (1,*.subst(/(\d)$0*/,{.chars~.[0]},:g)...*), and then get as many elements as specified by the user ([^get], which is an array subscript and means [0..(get-1)]), and say them all.

The lazy list works by first taking 1, then to generate each successive number, it takes the last one it found and substitutes all the sequences of the same digit, as matched by /(\d)$0*/, and replaces them with {how many}+{what digit}, or .chars~.[0].

The only variables in this code are $0, the first capture of the match, and the implicit, topical $_ variable that bare .methods call, and neither of these are user-defined.

Mouq

Posted 2014-03-12T00:13:10.417

Reputation: 906

1

GolfScript, 57 43 chars

My own approach. Ended up longer than the existing one sadly =(.

~[1 9]{.);p[{...1<^0=?.@(\@(>.,(}do 0=]}@*;

Sample output for stdin of 8:

[1]
[1 1]
[2 1]
[1 2 1 1]
[1 1 1 2 2 1]
[3 1 2 2 1 1]
[1 3 1 1 2 2 2 1]
[1 1 1 3 2 1 3 2 1 1]

Alternate version w/out the 9 sentinel, yet it's longer at 47 characters. I suspect it has more potential:

~[1]{.p[{...1<^.{0=?.@(\@(>1}{;,\0=0}if}do]}@*;

Claudiu

Posted 2014-03-12T00:13:10.417

Reputation: 3 870

1

Scala 178

(0 to Console.in.readLine.toInt).map(i=>Function.chain(List.fill[String=>String](i)(y=>(('0',0,"")/:(y+" ")){case((a,b,c),d)=>if(d==a)(a,b+1,c)else(d,1,c+b+a)}._3.drop(2)))("1"))

Ben Reich

Posted 2014-03-12T00:13:10.417

Reputation: 1 577

1I'm pretty sure that the i in i=> is a variable. – Peter Taylor – 2014-11-14T17:14:33.940

1

Dyalog APL, 35 characters

(⊢,⊂∘∊∘((≢,⊃)¨⊃⊂⍨2≢/0,⊃)∘⌽)⍣(⎕-1)⊢1

is evaluated input. In the link I've replaced it with 8, as tryapl.org does not allow user input.

No named variables (a←1), no named functions (f←{}), no arguments (, ).

Only composition of functions:

  • monadic operators—each:, reduce:f/, commute:f⍨
  • dyadic operators—power:f⍣n, compose:f∘g
  • forks—(f g h)B ←→ (f B)g(h B); A(f g h)B ←→ (A f B)g(A h B)
  • atops—(f g)B ←→ f(g B); A(f g)B ←→ f(A g B)
  • 4-trains (fork-atops)—(f g h k) ←→ (f (g h k))

Primitive functions used:

  • right:A⊢B ←→ B
  • reverse:⌽B
  • first:⊃B
  • concatenate:A,B
  • not match:A≢B, count:≢B
  • enclose:⊂B, partition:A⊂B
  • flatten:∊B

In tryapl.org, if you remove the trailing ⊢1, which is the argument to this massive composed thing, you can see a diagram of how it's parsed:

     ⍣               
   ┌─┴─┐             
 ┌─┼─┐ 7             
 ⊢ , ∘               
    ┌┴┐              
    ∘ ⌽              
 ┌──┴───┐            
 ∘    ┌─┴─┐          
┌┴┐   ¨ ┌─┼───┐      
⊂ ∊ ┌─┘ ⊃ ⍨ ┌─┼───┐  
  ┌─┼─┐ ┌─┘ 2 / ┌─┼─┐
  ≢ , ⊃ ⊂   ┌─┘ 0 , ⊃
            ≢

ngn

Posted 2014-03-12T00:13:10.417

Reputation: 11 449

0

J 66 (with I/O)

".@(_5}&',@((#,&:":{.);.1~1&(0})&(~:_1|.]))^:(<X)":1')@{.&.stdin''

without IO, scores 43:

NB. change the 8 for the number of numbers you'd want
,@((#,&:":{.);.1~1&(0})&(~:_1|.]))^:(<8)'1'

Funny question to pose yourself, when is the first 9 to show up?

jpjacobs

Posted 2014-03-12T00:13:10.417

Reputation: 3 440

Never look at the integer sequence page. – PyRulez – 2014-03-12T20:04:08.937

Ok, I see. Then ... why so? – jpjacobs – 2014-03-12T21:59:15.053

Nice trick in the IO version of replacing the X by the input in a string and then calling eval! – Omar – 2014-03-13T13:24:26.783

As for the funny question: isn't it pretty clear you only ever have 1, 2 & 3? I mean to get a 4 or higher, in the previous step you'd need four consecutive equal digits, xaaaay, but that can't happen since you'd be saying a further step earlier you saw "x a's, a a's" or "a a's, a a's". – Omar – 2014-03-13T13:41:13.883