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)
  • I am new here, please tell me how can I improve. For example, should I specify a date limit? – ajax333221 Jan 14 '12 at 18:43
  • 1
    You 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 Jan 14 '12 at 19:10
  • @JB Thanks for your enlightening words. I have updated my post – ajax333221 Jan 14 '12 at 19:54
  • The 13th iteration, and all subsequent iterations, are 21322314. Is this correct? – Joey Adams Jan 15 '12 at 2:15
up vote 4 down vote accepted

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. ⍨

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

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.

  • 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 May 4 at 8:35

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...

  • This will be hard to beat with any 'traditional language'. Maybe golfscript or similar is up to the task ;-) – ChristopheD Jan 15 '12 at 20:03

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

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.

Mathematica, 70

NestList[FromDigits@TakeWhile[DigitCount@#~Riffle~Range@9,#>0&]&,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.
  • 1
    U€ 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 May 4 at 14:46
  • 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 May 4 at 17:29
  • 1
    You'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 May 4 at 22:05
  • 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 May 5 at 5:39

Your Answer

 

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.