Say What You See

30

3

The "Look and say" or "Say what you see" sequence is a series of numbers where each describes the last.

1
11 (one one)
21 (two ones)
1211 (one two, one one)
111221 (one one, one two, two ones)
312211 (three ones, two twos, one one)

and on and on... https://oeis.org/A005150

Anyway, this is a regular code golf challenge (least byte count wins) to make a program that takes two arguments, an initial number and the amount of iterations. For example if you plugged in "1" and "2" the result would be "21". If you plugged in "2" and "4" the result would be "132112". Have fun!

HeyLlama

Posted 2016-02-02T23:33:55.803

Reputation: 431

2Can we receive/return a list of digits? – LegionMammal978 – 2016-02-02T23:38:30.970

5I'd close the older questions as dupes if necessary; this doesn't have the restrictions. – lirtosiast – 2016-02-02T23:43:34.987

4I don't see this as a duplicate. Both the previous look and say challenges were very restrictive (one with no numbers in the source code, the other with no named variables, named functions or named arguments). Very few languages will allow answers to the previous challenges that are also competitive here. – trichoplax – 2016-02-02T23:56:57.010

3Are we allowed to output as a list of numbers? – lirtosiast – 2016-02-03T00:23:57.293

3Discussion on meta about duplicates without restrictions – trichoplax – 2016-02-03T15:06:43.750

1Are the inputs meant to be strings or ints? – Ogaday – 2016-02-04T10:13:32.120

Three ones, two twos, and two ones??? The last line might be wrong. – iBug – 2017-07-07T04:50:07.570

Answers

9

Pyth, 10 8 bytes

-2 bytes by @FryAmTheEggman

ussrG8Qz

Explanation:

            Implicit: z=first line as string, Q=second line
u         the result of reducing lambda G:
  s s rG8   flattened run-length-encoded G
  Q       Q times
  z     starting with z

Try it here.

lirtosiast

Posted 2016-02-02T23:33:55.803

Reputation: 20 331

But at least I don't output brackets and commas; only spaces between the numbers :-P – Luis Mendo – 2016-02-03T00:43:03.310

2In Soviet Russia, ussrG8Qz – mbomb007 – 2017-02-01T17:27:12.450

8

CJam, 8 bytes

q~{se`}*

Input format is the initial number first, iterations second, separated by some whitespace.

Test it here.

Explanation

q~   e# Read and evaluate input, dumping both numbers on the stack.
{    e# Run this block once for each iteration...
  s  e#   Convert to string... in the first iteration this just stringifies the input
     e#   number again. In subsequent iterations it flattens and then stringifies the
     e#   array we get from the run-length encoding.
  e` e#   Run-length encode.
}*

The array is also flattened before being printed so the result is just the required number.

Martin Ender

Posted 2016-02-02T23:33:55.803

Reputation: 184 808

6

JavaScript, 57 bytes

F=(a,b)=>b?F(a.replace(/(.)\1*/g,c=>c.length+c[0]),b-1):a

Recursion works well for this problem. The first parameter is the initial number as a string, and the second is the number of iterations.

Mwr247

Posted 2016-02-02T23:33:55.803

Reputation: 3 494

You can save three bytes with a weird recursive curry: b=>F=a=>b--?F(a.replace(/(.)\1*/g,c=>c.length+c[0])):a Found that while golfing my answer before I realized it was pretty much identical to yours ;) – ETHproductions – 2017-02-01T12:32:47.790

4

R, 87 bytes

function(a,n){for(i in 1:n){r=rle(el(strsplit(a,"")));a=paste0(r$l,r$v,collapse="")};a}

Ungolfed & explained

f=function(a,n){
    for(i in 1:n){                      # For 1...n
        r=rle(el(strsplit(a,"")))       # Run length encoding
        a=paste0(r$l,r$v,collapse="")   # concatenate length vector and values vector and collapse
    };
    a                                   # print final result
}

Billywob

Posted 2016-02-02T23:33:55.803

Reputation: 3 363

4

MATL, 9 bytes

:"Y'wvX:!

Inputs are: number of iterations, initial number.

Try it online!

:      % implicit input: number of iterations. Create vector with that size
"      % for loop
  Y'   %   RLE. Pushes two arrays: elements and numbers of repetitions.
       %   First time implicitly asks for input: initial number
  w    %   swap
  v    %   concatenate vertically
  X:   %   linearize to column array
  !    %   transpose to row array
       % implicitly end loop
       % implicitly display

Luis Mendo

Posted 2016-02-02T23:33:55.803

Reputation: 87 464

If you can output as an array then Pyth has 8. – lirtosiast – 2016-02-03T00:24:20.430

@ThomasKwa Good point. I assumed it was possible – Luis Mendo – 2016-02-03T00:35:52.063

3

Haskell, 62 bytes

import Data.List
0%y=y
x%y=do x<-group$(x-1)%y;[length x,x!!0]

Try it online!

Post Rock Garf Hunter

Posted 2016-02-02T23:33:55.803

Reputation: 55 382

3

Perl 6, 63 bytes

say (@*ARGS[0],*.trans(/(.)$0*/=>{$/.chars~$0})…*)[@*ARGS[1]]

This is as short as I could get it for now, there might be some tricky flags that could reduce it, I'm not sure

Hotkeys

Posted 2016-02-02T23:33:55.803

Reputation: 1 015

3

Ruby, 63 bytes

A full program, since the question seems to ask for that. Takes input as command line arguments.

i,n=$*
n.to_i.times{i=i.gsub(/(.)\1*/){"#{$&.size}#$1"}}
puts i

No, gsub! can't be used, since the strings in $* are frozen :/

daniero

Posted 2016-02-02T23:33:55.803

Reputation: 17 193

Could you perhaps use the -p flag to save bytes? If you use it, gsub operates on a line of STDIN as if it were $_.gsub!. Then the command line argument is the iterations, so n,=$*, and the other input is read from STDIN. – Value Ink – 2016-12-24T05:18:21.587

3

Retina, 46 45 27 bytes

Martin did lots to help golf this.

+`(\d)(\1?)*(?=.*_)_?
$#2$1

Try it online

Takes input in the format:

<start><count>

<start> is the initial number.

<count> is in unary, all underscores, and is how many iterations are performed.

Single iteration, 20 16 bytes:

(\d)(\1?)*
$#2$1

mbomb007

Posted 2016-02-02T23:33:55.803

Reputation: 21 944

2

05AB1E, 9 bytes (Non-competing)

Corrected due to Emigna's comments, see below/edits.

F.¡vygyÙJ

Try it online!

Magic Octopus Urn

Posted 2016-02-02T23:33:55.803

Reputation: 19 422

1I think you missed the part about taking 2 arguments (initial number and number of iterations). Luckily you can just add F at the beginning and take the arguments as iterations,initialNo – Emigna – 2017-02-01T15:36:33.463

1And the byte lost by that could be regained by replacing Dgs with gy. – Emigna – 2017-02-01T15:39:33.703

@Emigna what's y do in that context? – Magic Octopus Urn – 2017-02-01T17:21:28.923

1Same as the first y, push the current value in the loop. So instead of duplicating y and swapping it to the top, you just push it again when you need it. – Emigna – 2017-02-01T21:19:37.313

@Emigna it should seem I still have a lot to learn haha. – Magic Octopus Urn – 2017-02-07T21:00:38.523

2

R, 61 57 bytes

-4 thanks to @JayCe, just when I was sure it couldn't be done any simpler!

f=function(a,n)`if`(n,f(t(sapply(rle(c(a)),c)),n-1),c(a))

Try it online!

J.Doe

Posted 2016-02-02T23:33:55.803

Reputation: 2 379

1

Slightly golfed: TIO

– JayCe – 2018-09-06T15:14:06.037

That t(sapply(z,c)) call is clever. – J.Doe – 2018-09-06T17:58:33.707

2

JavaScript ES6, 71 bytes

(m,n)=>[...Array(n)].map(_=>m=m.replace(/(.)\1*/g,x=>x.length+x[0]))&&m

Takes input as a string and a number.

ETHproductions

Posted 2016-02-02T23:33:55.803

Reputation: 47 880

('1',2) gives me 12, when it should be 21. Your length should come before the character in the replace. – Mwr247 – 2016-02-03T18:52:01.477

@Mwr247 Whoops, sorry. – ETHproductions – 2016-02-03T20:58:11.473

2

Perl 5, 50 bytes

$_=pop;for$i(1..pop){s/(.)\1*/length($&).$1/ge}say

The arguments are in reverse order (number of iterations then seed). Example:

> perl -E'$_=pop;for$i(1..pop){s/(.)\1*/length($&).$1/ge}say' 4 2
132112
> perl -E'$_=pop;for$i(1..pop){s/(.)\1*/length($&).$1/ge}say' 0 2
2
> perl -E'$_=pop;for$i(1..pop){s/(.)\1*/length($&).$1/ge}say' 2 0
1110
> perl -E'$_=pop;for$i(1..pop){s/(.)\1*/length($&).$1/ge}say' 1 10
1110
> perl -E'$_=pop;for$i(1..pop){s/(.)\1*/length($&).$1/ge}say' 11 1
3113112221232112111312211312113211

msh210

Posted 2016-02-02T23:33:55.803

Reputation: 3 094

As a subroutine, I can shave a byte by ending it with $_ instead of say, I suppose, but I haven't tested it. The current solution is a program. – msh210 – 2016-02-03T21:10:43.947

1

Jelly, 6 bytes (non-competing)

ŒrUFµ¡

Try it online!

           Implicit input: first argument.
     µ¡    Do this to it <second argument> times:
Œr            Run-length encode into [value, times] pairs
  U           Flip them
   F          Flatten list

Lynn

Posted 2016-02-02T23:33:55.803

Reputation: 55 648

1

Stax, 10 bytes

Çα▲ì4↔┌j█♀

Run and debug online!

Spent too many bytes on proper IO format ...

Explanation

Uses the unpacked version to explain.

DE|R{rm:f$e
D              Do `2nd parameter` times
 E             Convert number to digits
                   Starting from the `1st parmeter`
  |R           Convert to [element, count] pairs for each run
    {rm        Revert each pair
       :f      Flatten the array
         $     Convert array to string of digits
          e    Convert string of digits to integer

The essential part is D|R{rm:f(8 bytes).

If the first input can be taken as an array of digits, the whole program can be written in 9 bytes: Run and debug online!

Weijun Zhou

Posted 2016-02-02T23:33:55.803

Reputation: 3 396

1

Mathematica, 81 73 bytes

FromDigits@Nest[Flatten[(Tally/@Split@#)~Reverse~3]&,IntegerDigits@#,#2]&

A Simmons

Posted 2016-02-02T23:33:55.803

Reputation: 4 005

Prepend your code with four spaces to get it show up as code :) – Ogaday – 2016-02-04T11:50:59.460

0

SmileBASIC, 100 98 bytes

DEF S N,T?N
WHILE""<N
C=C+1C$=SHIFT(N)IF C$!=(N+@L)[0]THEN O$=O$+STR$(C)+C$C=0
WEND
S O$,T-T/T
END

Prints out all the steps. T/T is there to end the program when T is 0.

12Me21

Posted 2016-02-02T23:33:55.803

Reputation: 6 110

0

APL (Dyalog Classic), 22 bytes

{∊(≢,⊃)¨⍵⊂⍨1,2≠/⍵}⍣⎕,⎕

Try it online!

ngn

Posted 2016-02-02T23:33:55.803

Reputation: 11 449

0

K (ngn/k), 30 bytes

{y{,/{(#x;*x)}'(&~=':x)_x}/,x}

Try it online!

ngn

Posted 2016-02-02T23:33:55.803

Reputation: 11 449

0

Retina, 27 bytes

~(`^
K`
$
+`(.)\1$*¶$$.&$$1

Try it online!

TwiNight

Posted 2016-02-02T23:33:55.803

Reputation: 4 187

0

Python 3.6, 100 98 93 bytes

import re
f=lambda s,n:n and eval("f'"+re.sub(r'((.)\2*)',r'{len("\1")}\2',f(s,n-1))+"'")or s

Try it online!

Note this creates a lambda that takes a string and an integer, and returns a string. Example: f('1', 5) == '312211'

Finds all repeated characters (((.)\2*) regex), makes a f-string out of their length and the character itself (r'{len("\1")}\2'), then evaluates it. Uses recursion on the counter (n and ...f(s,n-1)... or s) to avoid having to define a proper function and a loop.

BoppreH

Posted 2016-02-02T23:33:55.803

Reputation: 101

0

Python 3, 138 bytes

I used a recursive approach.

def g(a,b):
 if b<1:return a
 else:
  c,n=1,'';f,*a=str(a)+'_'
  for i in a:
   if i==f:c+=1
   else:n+=str(c)+f;f,c=i,1
  return g(n,b-1)

The function accepts two ints, a and b as described.

I'm amazed at how terse the entries here are! Maybe someone will come along with a better Python method too.

Ogaday

Posted 2016-02-02T23:33:55.803

Reputation: 471

0

Perl, 38 + 2 bytes

for$i(1..<>){s/(.)\1*/(length$&).$1/ge}

Requires the -p flag:

$ perl -pe'for$i(1..<>){s/(.)\1*/(length$&).$1/ge}' <<< $'1\n5'
312211

Input is a multi line string:

input number
numbers of iterations

If all the steps are required as well then we can change it to the following, which is 44 + 2 bytes:

$ perl -nE'for$i(1..<>){s/(.)\1*/(length$&).$1/ge,print}' <<< $'1\n5'
11
21
1211
111221
312211

andlrc

Posted 2016-02-02T23:33:55.803

Reputation: 1 613

0

Pylons, 11

i:At,{n,A}j

How it works:

i      # Get input from command line.
:A     # Initialize A
  t    # Set A to the top of the stack.
,      # Pop the top of the stack.
{      # Start a for loop.
 n     # Run length encode the stack.
  ,    # Seperate command and iteration
   A   # Repeat A times.
    }  # End for loop.
j      # Join the stack with '' and print it and then exit. 

Morgan Thrapp

Posted 2016-02-02T23:33:55.803

Reputation: 3 574