Ascending Pea Pattern generator

8

For those who are not familiarized with the Pea Pattern, it is a simple mathematical pattern.

There are multiple variations of this pattern, but we will focus in one:

Ascending Pea Pattern

It looks like this:

1
11
21
1112
3112
211213
...

It seems really hard to get the following line, but it is really easy. The way to get the next line is by counting the number of times a digit have repeated on the previous line (start counting with the lowest, to largest):

one
one one
two ones
one one, one two
three ones, one two
two ones, one two, one three
...

Requirements/Rules:

  • We will start at 1
  • It will be a snippet
  • There must be a way to specify the number of lines generates (e.g 5 will give the first 5 lines)
  • The code should be as short as possible
  • It must start counting from lowest to largest (the Ascending variation)

ajax333221

Posted 2012-01-14T18:42:41.937

Reputation: 3 188

I am new here, please tell me how can I improve. For example, should I specify a date limit? – ajax333221 – 2012-01-14T18:43:50.280

1You could specify whether you want a full program with I/O or a snippet is enough (or if you don't care.) But it looks well-specified enough at first glance. – J B – 2012-01-14T19:10:11.230

@JB Thanks for your enlightening words. I have updated my post – ajax333221 – 2012-01-14T19:54:40.753

Related: http://codegolf.stackexchange.com/questions/2323/look-and-say-sequence

– Joey Adams – 2012-01-15T02:00:26.783

The 13th iteration, and all subsequent iterations, are 21322314. Is this correct? – Joey Adams – 2012-01-15T02:15:51.080

@JoeyAdams That's what I get, and the wiki page linked above seems to confirm it. – Gareth – 2012-01-15T02:19:13.753

Answers

4

APL, 32 characters

⍪⌽({⍵,⍨,/{⌽⍵,+/⍵⍷d}¨⍳⌈/d←⊃⍵}⍣⎕)1

This generates lines starting from 0 (i.e. 0 generates 1, 1 generates 1 followed by 1 1, etc.), as specified by user input. I used Dyalog APL for this, and ⎕IO should be set to its default of 1.

Example:

      ⍪⌽({⍵,⍨,/{⌽⍵,+/⍵⍷d}¨⍳⌈/d←⊃⍵}⍣⎕)1
⎕:
      0
1

      ⍪⌽({⍵,⍨,/{⌽⍵,+/⍵⍷d}¨⍳⌈/d←⊃⍵}⍣⎕)1
⎕:
      13
               1 
             1 1 
             2 1 
         1 1 1 2 
         3 1 1 2 
     2 1 1 2 1 3 
     3 1 2 2 1 3 
     2 1 2 2 2 3 
     1 1 4 2 1 3 
 3 1 1 2 1 3 1 4 
 4 1 1 2 2 3 1 4 
 3 1 2 2 1 3 2 4 
 2 1 3 2 2 3 1 4 
 2 1 3 2 2 3 1 4

Once I get some more time, I'll write up an explanation. ⍨

Dillon Cower

Posted 2012-01-14T18:42:41.937

Reputation: 2 192

3

Python (2.x), 81 80 characters

l='1'
exec"print l;l=''.join(`l.count(k)`+k for k in sorted(set(l)))\n"*input()

All tips or comments welcome!

usage: python peapattern.py
15 # enter the number of iterations
1
11
21
1112
3112
211213
312213
212223
114213
31121314
41122314
31221324
21322314
21322314
21322314

ChristopheD

Posted 2012-01-14T18:42:41.937

Reputation: 1 599

2

J, 60 46 39 26 characters

1([:,(#,{.)/.~@/:~)@[&0~i.

Edit 3: Came up with a much nicer way of expressing this.

1([:;[:|."1[:/:~~.,.[:+/"1[:~.=)@[&0~i.

Edit 2: Finally found a way to move the argument to the end of the sequence and get rid of the unnecessary assignment stuff.

Previously:

p=.3 :'([:,[:|."1[:/:~~.,.[:+/"1[:~.=)^:(i.y)1

Edit 1: Fixes the output which should be y rows rather than the yth row. Also shortens things a bit. Shame about the 0s, can't seem to get rid of the damn things.

Usage:

   1([:,(#,{.)/.~@/:~)@[&0~i. 1
1

   1([:,(#,{.)/.~@/:~)@[&0~i. 6
1 0 0 0 0 0
1 1 0 0 0 0
2 1 0 0 0 0
1 1 1 2 0 0
3 1 1 2 0 0
2 1 1 2 1 3

   1([:,(#,{.)/.~@/:~)@[&0~i. 10
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 1 1 2 0 0 0 0
3 1 1 2 0 0 0 0
2 1 1 2 1 3 0 0
3 1 2 2 1 3 0 0
2 1 2 2 2 3 0 0
1 1 4 2 1 3 0 0
3 1 1 2 1 3 1 4

Admittedly the usage is uglier now, but prettiness isn't the name of the game here...

Gareth

Posted 2012-01-14T18:42:41.937

Reputation: 11 678

This will be hard to beat with any 'traditional language'. Maybe golfscript or similar is up to the task ;-) – ChristopheD – 2012-01-15T20:03:09.020

2

Perl, 83

I'm pretty sure some Perl guru could outdo this, but here goes:

$_++;$n=<>;for(;$n--;){print$_.$/;$r='';$r.=length($&).$1 while(s/(.)\1*//);$_=$r;}

Expanded:

$_++;$n=<>;

for(;$n--;)
{
    print $_.$/;

    $r='';$r .= length($&).$1 while (s/(.)\1*//);  # The magic
    $_=$r;
}

Number of rows is passed in via STDIN.

Mr. Llama

Posted 2012-01-14T18:42:41.937

Reputation: 2 387

Not quite a guru, I'm sure there are even shorter ways to be found, but 46 using pretty much the same method: Try it online!

– Dom Hastings – 2018-05-04T08:35:31.923

1

Jelly, 13 11 bytes (Feedback appreciated)

1ṢŒrUFƲСṖY

Try it online!

1ṢŒrUFƲСṖY
1     Ʋ         starting with 1, run these 4 links...
 ṢŒr            Ṣort the list and get the Œrun-length encoding of it,
    U           reverse each member of the RLE list (so it goes [repetitions, digit] instead of [digit, repetitions]),
     F          and Flatten the RLE list-of-lists to just a list of digits, which is the next number.
       С       do that (input) number of times,
         ṖY     Ṗop the last line off the output (an extra line is always calculated) and then print the numbers, separated by newlines.

Harry

Posted 2012-01-14T18:42:41.937

Reputation: 1 189

1U€ can just be U, it vectorizes down to the row level. Then you can save another byte inlining ṢŒrUF, using Ʋ (last 4 links as monad): 1ṢŒrUFƲСṖY – Lynn – 2018-05-04T14:46:41.900

Thanks again so much for the improvements @Lynn! Always nice to go from a string of 5+ links to 4 so you can use that quick. – Harry – 2018-05-04T17:29:38.307

1You're welcome! (Tiny note: ṢŒrU€FƲ would have worked just fine -- it rolls [, Œr, U€, F] into a monad. Maybe my use of "then" was a little misleading ^^; Similarly, in something like abc$de$fƲ will operate on the 4 links [a, bc$, de$, f] and roll them into a monad. This is the sense in which you can think of quicks as "parse-time stack operators": their outcome is pushed back onto a stack, and acts as if it were one link for future quicks.) – Lynn – 2018-05-04T22:05:03.940

1

@Lynn I see, thank you again! Getting a lot better at "counting" links now, was able to completely inline this answer and save a byte thanks to your comment!

– Harry – 2018-05-05T05:39:58.890

1

Haskell, 116

import Data.List
main=interact(unlines.map(show=<<).($iterate((>>=
 \x->[length x,head x]).group.sort)[1]).take.read)

Usage:

$ runhaskell pea.hs <<< 15
1
11
21
1112
3112
211213
312213
212223
114213
31121314
41122314
31221324
21322314
21322314
21322314

Joey Adams

Posted 2012-01-14T18:42:41.937

Reputation: 9 929

1

Common Lisp, 140 characters

(defun m(x)
  (labels((p(l n)
    (if(= 0 n)
       nil
       (cons l
             (p(loop for d in(sort(remove-duplicates l)#'<)
                  append(list(count d l)d))
               (1- n))))))
    (p'(1) x)))

This is Lisp, so the function returns a list of lists. (m x) generates X sublists.

Paul Richter

Posted 2012-01-14T18:42:41.937

Reputation: 770

1

Mathematica, 70

NestList[FromDigits@TakeWhile[DigitCount@#~Riffle~Range@9,#>0&]&,1,#]&

Mr.Wizard

Posted 2012-01-14T18:42:41.937

Reputation: 2 481