16
\$\begingroup\$

Background

The summary of a non-negative integer \$n\$ is the concatenation of all digits that appear in \$n\$ in increasing order, with each digit being preceded by the number of times it appears in \$n\$.

Some Examples:

n            -> summary(n)
1221         -> 2122 (2 ones, 2 twos)
1212         -> 2122 (2 ones, 2 twos)
912334       -> 1112231419 (1 one, 1 two, 2 threes, 1 four, 1 nine)
888888888888 -> 128 (12 eights)

The \$k\$-th order summary is result repeatedly applying the summary operation on a number \$k\$ times (i.e. \$2\$nd order summary of \$n\$ is summary(summary(n)), \$3\$rd order summary of \$n\$ is summary(summary(summary(n))), etc.).

Note: The \$0\$th order summary of a number is itself

Task

Write a program/function that outputs the \$k\$-th order summary of a non-negative integer \$n\$.

Scoring

This is so shortest bytes wins

Sample Testcases

n, k             -> answer
0, 1             -> 10
1, 10            -> 41122314
1221, 0          -> 1221
1221, 1          -> 2122
1212, 1          -> 2122
912334, 1        -> 1112231419
912334, 3        -> 412213141519
21322314, 1      -> 21322314
21322314, 123    -> 21322314
21322314, 2222   -> 21322314
888888888888, 1  -> 128
888888888888, 2  -> 111218
1888888888888, 1 -> 11128

Inspired by A005151

\$\endgroup\$
11
  • \$\begingroup\$ Similar question: codegolf.stackexchange.com/questions/70837/say-what-you-see \$\endgroup\$ Nov 6, 2021 at 4:12
  • 3
    \$\begingroup\$ Please add 1888888888888, 1 as a test case (outputs 11128) as my program failed for it (as will any method that concatenates by converting from base 10) \$\endgroup\$ Nov 6, 2021 at 4:25
  • 3
    \$\begingroup\$ Suggested test case: 21322314, anything -> 21322314 (a stable input). \$\endgroup\$
    – Arnauld
    Nov 6, 2021 at 15:02
  • 1
    \$\begingroup\$ Another interesting input is 9009 with a run of 21 distinct values before it starts repeating. \$\endgroup\$
    – Arnauld
    Nov 6, 2021 at 16:48
  • 1
    \$\begingroup\$ @KevinCruijssen, digit-lists are allowed. \$\endgroup\$ Nov 8, 2021 at 14:08

19 Answers 19

5
\$\begingroup\$

Vyxal, 7 bytes

(søeRf∑

Try it Online!

(       # k times...
 s      # Sort 
  øe    # Run length encode
    R   # Reverse each
     f  # Flatten
      ∑ # Sum
\$\endgroup\$
5
\$\begingroup\$

Jelly, 8 bytes

ṢŒrUFVµ¡

Try it online!

Credit to hyper-neutrino for the µ trick, and for telling me I was wrong :P

Full program. Takes n then k on the command line

How it works

ṢŒrUFVµ¡ - Main link. Takes n on the left, k on the right
      µ  - Last links as a monadic chain f(n):
Ṣ        -   Sort the digits of n
 Œr      -   Run length encode
   UF    -   Reverse each and flatten
     V   -   Eval as a single number
       ¡ - Iterate f(n) k times
\$\endgroup\$
5
\$\begingroup\$

Proton, 67 bytes

f=(n,k)=>k?f("".join(str(n.count(x))+x for x:sorted(set(n))),k-1):n

Try it online!

Python 3, 78 bytes

f=lambda n,k:k and f("".join(str(n.count(x))+x for x in sorted({*n})),k-1)or n

Try it online!

-7 bytes thanks to Mukundan314

\$\endgroup\$
3
  • \$\begingroup\$ -7 byte for the python solution \$\endgroup\$ Nov 6, 2021 at 5:01
  • \$\begingroup\$ @Mukundan314 Ah, nice! Thanks \$\endgroup\$
    – hyper-neutrino
    Nov 6, 2021 at 5:03
  • \$\begingroup\$ Do you really need the str in the Proton function? Seems to work fine without it \$\endgroup\$
    – ovs
    Nov 6, 2021 at 11:02
5
\$\begingroup\$

Wolfram Language (Mathematica), 55 bytes

ToString@#2<>#&@@@Sort@Tally@Characters@#<>""&~Nest~##&

Try it online!

Input ["n", k].

\$\endgroup\$
4
\$\begingroup\$

JavaScript (ES6), 73 bytes

Expects (k)(n), where n is given as a string. Returns a string.

k=>g=n=>k--?g([...n].sort().join``.replace(/(.)\1*/g,s=>s.length+s[0])):n

Try it online!

Commented

k =>                 // outer function taking k
g = n =>             // inner recursive function taking n as a string
  k-- ?              // decrement k; if it was not 0:
    g(               //   do a recursive call:
      [...n]         //     split n into a list of digits
      .sort()        //     sort this list in ascending order
      .join``        //     join the digits again
      .replace(      //     replace ...
        /(.)\1*/g,   //       ... runs of consecutive identical digits ...
        s =>         //       ... with:
          s.length + //         the number of occurrences
          s[0]       //         followed by the digit
      )              //     end of replace()
    )                //   end of recursive call
  :                  // else:
    n                //   we're done: return n
\$\endgroup\$
1
  • \$\begingroup\$ Love it. I've never considered using ` join`` ` in place of join('') before. I'm going to have to start doing that in my own code. \$\endgroup\$
    – dx_over_dt
    May 12 at 22:07
3
\$\begingroup\$

Husk, 15 bytes

d!¡oṁoṁd§eL←kDd

Try it online!

Order is taken 1-indexed.

Explanation

d!¡oṁoṁd§eL←kDd
              d digits
  ¡             apply the following repeatedly and collect results:
            kD   group digits into lists
    ṁ            map each list and join:
        §e        two element list with:
          L        length
           ←       first element
     oṁd          convert each to individual digits 
 !              index into that using order
d               convert back to integer.

\$\endgroup\$
2
  • \$\begingroup\$ You program fails for n = 1888888888888, k = 1 (2 if 1 indexed) \$\endgroup\$ Nov 6, 2021 at 4:47
  • \$\begingroup\$ fixed it. my bad. \$\endgroup\$
    – Razetime
    Nov 6, 2021 at 5:10
2
\$\begingroup\$

R, 94 bytes

Or R>=4.1, 87 bytes by replacing the word function with \.

function(n,k){while(k<-k-1)n=Reduce(paste0,c(rbind(r<-table(el(strsplit(n,""))),names(r))));n}

Try it online!

Expects n as a string and k 1-indexed. Outputs a string.

Creates table of digits and interleaves resulting values (counts) with their names (digits) using this trick from SO.

The rest is just string manipulation which is quite cumbersome in R.


Recursive approach results in the same byte-count:

R, 94 bytes

Or R>=4.1, 87 bytes by replacing the word function with \.

f=function(n,k)"if"(k,f(Reduce(paste0,c(rbind(r<-table(el(strsplit(n,""))),names(r)))),k-1),n)

Try it online!

Here k is 0-indexed.

\$\endgroup\$
2
\$\begingroup\$

Retina, 25 bytes

1A`
"$+"{O`.
(.)\1*
$.&$1

Try it online! Takes input in the order k, n. No test suite due to the program's use of history. Explanation:

1A`

Delete k from the input.

"$+"{`

Retrieve k from the history and repeat the rest of the program k times.

O`.

Sort the digits in ascending order.

(.)\1*
$.&$1

Precede each distinct digit by its count.

The best I could do in # Retina 0.8.2 is 45 bytes:

,\d+
$*_
{O`.(?=.*_)
(\d)\1*(?=.*_)
$.&$1
_$

Try it online! Link includes test cases. Explanation:

,\d+
$*_

Convert k to unary, using _ because they sort after digits, saving a byte.

{`

Repeat (until k is zero, at which point the loop converges).

O`.(?=.*_)

If k is not zero, sort the digits in ascending order. (If k>1, k is also sorted, but it always sorts after digits.)

(\d)\1*(?=.*_)
$.&$1

If k is not zero, precede each distinct digit by its count.

_$

If k is not zero, then decrement k.

\$\endgroup\$
2
\$\begingroup\$

Ruby, 74 66 bytes

->n,k{k.times{a=n.chars
n=(a|a).sort.map{|d|[a.count(d),d]}*''}
n}

Try it online!

  • Thanks to @ovs for actually golfing thus saving 8 Bytes!
    .uniq => a|a and join by *'' instead of appending values

  • takes n as string, k as int

  • reconstruct n by appending each (count,digit) k times

  • uses a=n.split n='' instead of a,n=n.chars,'' which is the same byte count

\$\endgroup\$
1
  • 1
    \$\begingroup\$ (a|a) is a byte shorter than a.uniq and building n by joining a nested array saves a few more bytes: Try it online! \$\endgroup\$
    – ovs
    Nov 6, 2021 at 16:38
2
\$\begingroup\$

Raku, 44 bytes

{($^a,{[R~] .comb.Bag{~9...0}:kv}...*)[$^k]}

Try it online!

  • ($^a, { ... } ... *)[$^k] selects the $^k-th element of the infinite sequence starting with $^a, where $^a and $^k are the first and second arguments to the function, respectively. The bracketed expression is an anonymous function that generates each summary number from the previous one, passed as $_.
  • .comb splits the number $_ into its (string) digits.
  • .Bag assembles those digits into a Bag--a set with multiplicity.
  • {~9...0} slices into that bag with the digits from 9 to 0. The leading ~ stringifies the 9 and gives us a sequence of strings, not numbers. (The Bag knows the difference.)
  • The :kv adverb on the slicing subscript {...} does two things: it returns a flat list of key-value pairs (ie, each digit along with its multiplicity, in order from 9 to 0), and it omits elements from the slice which don't exist in the Bag.
  • [R~] reduces that list with the operator R~, which is the Reversed string concatenation operator ~. That gives us the required summary of the previous number in the series.
\$\endgroup\$
2
\$\begingroup\$

05AB1E, 9 8 7 bytes

F{Åγøí˜J

-1 byte thanks to a tip of @ovs

Inputs in the order \$k,n\$. Outputs as a digit-list (unless \$k=0\$, in which case it outputs \$n\$ as is - although we could take input \$n\$ as digit-list as well to be consistent).

Try it online or verify all test cases.

Explanation:

F        # Loop the first (implicit) input amount of times:
 {       #  Sort the digits of the current number
         #  (which is the second implicit input-integer in the first iteration)
  Åγ     #  Pop and run-length encode, pushing a list of digits and a list of lengths
         #  separated to the stack
    ø    #  Create pairs of these two lists
     í   #  Reverse each pair
      S  #  Convert the list of integer-pairs to a flattened list of digits
         # (after which the result is output implicitly)
\$\endgroup\$
2
  • \$\begingroup\$ I think Åγ should be able to save a byte here \$\endgroup\$
    – ovs
    Nov 8, 2021 at 9:32
  • \$\begingroup\$ @ovs EDIT: I'm an idiot.. it pushes both lists separated :/ Thanks for -1 \$\endgroup\$ Nov 8, 2021 at 10:09
2
\$\begingroup\$

PowerShell Core, 73 bytes

param($n,$k)for(;$k--){$n=-join("$n"|% t*y|group|%{$_.Count,$_.Name})}
$n

Try it online!

Same byte count using $ofs: Try it online!

Takes two integer parameters and returns a string or an integer

\$\endgroup\$
1
\$\begingroup\$

Charcoal, 18 bytes

FN≔⭆Φ⭆χκ№ηκ⁺№ηκκηη

Try it online! Link is to verbose version of code. Takes input in the order k, n. Explanation:

FN

Input k and loop that many times.

≔⭆Φ⭆χκ№ηκ⁺№ηκκη

Filter the characters 0-9 that are present in n, prefixing them with their count and joining the result.

η

Output the final value of n.

\$\endgroup\$
1
\$\begingroup\$

Excel (Insider Beta), 108 bytes

=LAMBDA(q,k,IF(k,LET(a,f(q,k-1),x,SEQUENCE(10)-1,y,LEN(a)-LEN(SUBSTITUTE(a,x,"")),CONCAT(FILTER(y&x,y))),q))

Link to Spreadsheet

Set name f equal to the above formula. Spreadsheet requires Insider Beta version of Excel to work currently because of LAMBDA.

Explanation

=LAMBDA(q,k,
IF(k,                                      # if k <> 0 then
     LET(a,f(q,k-1),                       #   a = f(q,k-1) 
         x,SEQUENCE(10)-1,                 #   x = [0..9]
         y,LEN(a)-LEN(SUBSTITUTE(a,x,"")), #   y = count of each x in a
         CONCAT(FILTER(y&x,y)))            #   concatenate y&x if y > 0 
     ,q))                                  # else q
\$\endgroup\$
1
\$\begingroup\$

Core Maude, 354 bytes

mod R is pr LIST{Nat}+ CONVERSION . ops k s : Nat Nat ~> Nat . op f : Nat
~> String . var N K : Nat . var X Y :[Nat]. eq k(N,0)= N . eq k(N,s K)=
k(rat(f(s(N,0 0 0 0 0 0 0 0 0 0)),10),K). eq s(0,X)= X . ceq s(N,X K Y)=
s(N quo 10,X(s K)Y)if size(X)= N rem 10[owise]. eq f(nil)= "" . eq f(X 0)=
f(X). eq f(X s N)= f(X)+ string(10 * s N + size(X),10). endm

The result is obtained by reducing the k function with \$n\$ and \$k\$.

Example Session

Maude> red k(1, 10) .  --- Expected: 41122314
result NzNat: 41122314
Maude> red k(1221, 0) .  --- Expected: 1221
result NzNat: 1221
Maude> red k(1221, 1) .  --- Expected: 2122
result NzNat: 2122
Maude> red k(1212, 1) .  --- Expected: 2122
result NzNat: 2122
Maude> red k(912334, 1) .  --- Expected: 1112231419
result NzNat: 1112231419
Maude> red k(912334, 3) .  --- Expected: 412213141519
result NzNat: 412213141519
Maude> red k(21322314, 1) .  --- Expected: 21322314
result NzNat: 21322314
Maude> red k(21322314, 123) .  --- Expected: 21322314
result NzNat: 21322314
Maude> red k(21322314, 2222) .  --- Expected: 21322314
result NzNat: 21322314
Maude> red k(888888888888, 1) .  --- Expected: 128
result NzNat: 128
Maude> red k(888888888888, 2) .  --- Expected: 111218
result NzNat: 111218
Maude> red k(1888888888888, 1) .  --- Expected: 11128
result NzNat: 11128

Ungolfed

mod R is
    pr LIST{Nat} + CONVERSION .

    ops k s : Nat Nat ~> Nat .
    op f : Nat ~> String .

    var N K : Nat .
    var X Y : [Nat] .

    eq k(N, 0) = N .
    eq k(N, s K) = k(rat(f(s(N, 0 0 0 0 0 0 0 0 0 0)), 10), K) .

    eq s(0, X) = X .
    ceq s(N, X K Y) = s(N quo 10, X (s K) Y) if size(X) = N rem 10 [owise] .

    eq f(nil) = "" .
    eq f(X 0) = f(X) .
    eq f(X s N) = f(X) + string(10 * s N + size(X), 10) .
endm

Maude doesn't have logarithms for integers, only for floating-point numbers, so the only good way I could find to "concatenate" integers is to convert them to strings, concatenate, and convert back.

Core Maude + Cheating, 331 bytes

mod R is pr CONVERSION . ops k s : Nat Nat -> Nat . op f : Nat Nat -> String
. var N K S : Nat . eq k(N,0)= N . eq k(N,s K)= k(rat(f(0,s(N,0)),10),K). eq
s(0,S)= S . eq s(N,S)= s(N quo 10,S + 512 ^(N rem 10))[owise]. eq f(10,S)=
"" . eq f(N,S)= if(S & 511)> 0 then string(10 *(S & 511)+ N,10)else "" fi +
f(s N,S >> 9)[owise]. endm

Ungolfed

mod R is
    pr CONVERSION .

    ops k s : Nat Nat -> Nat .
    op f : Nat Nat -> String .

    var N K S : Nat .

    eq k(N, 0) = N .
    eq k(N, s K) = k(rat(f(0, s(N, 0)), 10), K) .

    eq s(0, S) = S .
    eq s(N, S) = s(N quo 10, S + 512 ^ (N rem 10)) [owise] .

    eq f(10, S) = "" .
    eq f(N, S) = if (S & 511) > 0 then string(10 * (S & 511) + N, 10) else "" fi + f(s N, S >> 9) [owise] .
endm

If we make the small assumption that no digit occurs more than 511 times, we can avoid having to import LIST and keep the intermediate summary packed in an integer with 9 bits per digit tracked. The bit size is sort of arbitrary since Maude has unbounded integers, so I picked 9 bits to avoid paying 4 extra bytes for 10 and 1024.

\$\endgroup\$
1
\$\begingroup\$

C (gcc), 112 \$\cdots\$ 123 125 bytes

f(n,k){int c[10]={!n},t=n,i=-1,l;for(;t;t/=10)++c[t%10];for(;i++<9;t=l?i+l*10+t*exp10(l=log10(l)+2):t)l=c[i];n=k?f(t,k-1):n;}

Try it online!

Saved a 2 bytes thanks to ceilingcat!!!
Added 21 bytes to fix an error kindly pointed out by Arnauld.
Saved 8 bytes thanks to att!!!
Added 2 bytes to handle \$n=0\$.

\$\endgroup\$
13
  • \$\begingroup\$ Hello! I posted mine instead of suggesting because I think it's slightly different approach, Idk if I have to apologize but I feel so because usually I suggest, but sometimes I'm greedy and don't want to give away my codes :-p \$\endgroup\$
    – AZTECCO
    Nov 7, 2021 at 10:33
  • \$\begingroup\$ @AZTECCO Yeah, I've noticed you started doing that now. If you post a C answer before I do I either help you or refrain from posting in that challenge. \$\endgroup\$
    – Noodle9
    Nov 7, 2021 at 12:44
  • \$\begingroup\$ Wait.. I coded it completely on my own without see yours before, that's the main reason I choose to post separately.. If you feel I compete with you well it's right, that's a competition after all, but if I golf your answer then I suggest instead of posting separately.. That's for sure. \$\endgroup\$
    – AZTECCO
    Nov 7, 2021 at 12:56
  • \$\begingroup\$ Btw since I have to steal your pow(log10..) to correct my answer I live my attempt at your disposal as a suggestion Try it online! \$\endgroup\$
    – AZTECCO
    Nov 7, 2021 at 12:59
  • \$\begingroup\$ in the future feel free to post your own answer if you find a different and better approach, I think it's fine and interesting to compete in the same language, and it happens to other languages too. :) \$\endgroup\$
    – AZTECCO
    Nov 7, 2021 at 13:04
1
\$\begingroup\$

Perl 5, 72 bytes

sub g{($c,$d)=@_;$c=join"",map{(@e=$c=~/$_/g)?@e.$_:""}0..9for 1..$d;$c}

Try it online!

Ungolfed:

sub g{
    ($c, $d) = @_;
    for (1 .. $d) {
        $c = join('', map {(@e = $c =~ /$_/g) ? @e . $_ : ""} 0 .. 9);
    }
    $c;
}
\$\endgroup\$
1
\$\begingroup\$

C (gcc), 121 125 117 116 bytes

E=10,r,c,t,i;g(n,k){for(;k--;n=n?r:E)for(r=i=0;i<E;r=c?r*E*E+c*E+i:r,i++)for(c=0,t=n;t;t/=E)r*=t%E-i||++c%E?:E;r=n;}

Try it online!

  • Saved 1 thanks to @ceilingcat
  • Fixed: now works with n=0 , k>0 as required.

Try it uint64_t

\$\endgroup\$
0
0
\$\begingroup\$

Lua, 112 bytes

Chunk function (can be executed using loadstring(code)("42",0)). Expects n as a string and k as either number or string. Doesn't play well with TIO; replace the return n with print(n) to test.

n,k=...for _=1,k do m=""for j=1,9 do c=""..#n:gsub("[^"..j.."]","")m=m..(c>"0"and c..j or"")end n=m end return n

Try it online!

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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