32
\$\begingroup\$

Your challenge is to, given a positive integer n, count up to each digit of it, giving the effect of converging on it.

Basically, count up to the first digit of n by its place value (\$⌊\log_{10}\left(x\right)⌋\$). Then do the same for each subsequent digit, but with the values of the previous digits added.

Example implementation (animated):

function count(){
  let countTo = document.getElementById('number').value.toString().split``,output = document.getElementById('x');
  let numbers = [], accumulator = 0;
  countTo.map((value, index) => {
    for(let i = 0; i < +value; i++){
      accumulator += 10 ** (countTo.length - index - 1)
      numbers.push(accumulator)
    }
  });
  //document.getElementById('y').innerHTML = 'All values:<br>' + numbers.join`<br>`;
  (function next(){let nextVal = numbers.shift();if(nextVal){output.innerHTML = nextVal;setTimeout(next,300)}})()
}
p{font-family:monospace}
<label for=number>Number: </label><input id=number type=number> <button onclick=count()>Count!</button><p id=x></p><p id=y></p>

You should just return an array of numbers - for n=47:

10
20
30
40
41
42
43
44
45
46
47

You may optionally have leading zeroes. IO may be strings, numbers, digit lists, etc.

Testcases:

4 => [1, 2, 3, 4]
16 => [10, 11, 12, 13, 14, 15, 16]
35 => [10, 20, 30, 31, 32, 33, 34, 35]
103 => [100, 101, 102, 103]
320 => [100, 200, 300, 310, 320]
354 => [100, 200, 300, 310, 320, 330, 340, 350, 351, 352, 353, 354]
1000 => [1000]
1001 => [1000, 1001]
3495 => [1000, 2000, 3000, 3100, 3200, 3300, 3400, 3410, 3420, 3430, 3440, 3450, 3460, 3470, 3480, 3490, 3491, 3492, 3493, 3494, 3495]
4037 => [1000, 2000, 3000, 4000, 4010, 4020, 4030, 4031, 4032, 4033, 4034, 4035, 4036, 4037]
84958320573493 => [10000000000000, 20000000000000, 30000000000000, 40000000000000, 50000000000000, 60000000000000, 70000000000000, 80000000000000, 81000000000000, 82000000000000, 83000000000000, 84000000000000, 84100000000000, 84200000000000, 84300000000000, 84400000000000, 84500000000000, 84600000000000, 84700000000000, 84800000000000, 84900000000000, 84910000000000, 84920000000000, 84930000000000, 84940000000000, 84950000000000, 84951000000000, 84952000000000, 84953000000000, 84954000000000, 84955000000000, 84956000000000, 84957000000000, 84958000000000, 84958100000000, 84958200000000, 84958300000000, 84958310000000, 84958320000000, 84958320100000, 84958320200000, 84958320300000, 84958320400000, 84958320500000, 84958320510000, 84958320520000, 84958320530000, 84958320540000, 84958320550000, 84958320560000, 84958320570000, 84958320571000, 84958320572000, 84958320573000, 84958320573100, 84958320573200, 84958320573300, 84958320573400, 84958320573410, 84958320573420, 84958320573430, 84958320573440, 84958320573450, 84958320573460, 84958320573470, 84958320573480, 84958320573490, 84958320573491, 84958320573492, 84958320573493]
\$\endgroup\$
6
  • \$\begingroup\$ May we output each number in reverse? E.g. 47 -> ["01", "02", "03", "04", "14", "24", "34", "44", "54", "64", "74"]? \$\endgroup\$
    – pxeger
    Commented Dec 16, 2021 at 0:08
  • \$\begingroup\$ @pxeger I'ma say no to that one as it doesn't really fit within the intent of the challenge. \$\endgroup\$
    – emanresu A
    Commented Dec 16, 2021 at 0:13
  • \$\begingroup\$ Can the first output be 0? \$\endgroup\$
    – Xcali
    Commented Dec 16, 2021 at 21:57
  • \$\begingroup\$ @Xcali > You may optionally have leading zeroes \$\endgroup\$
    – emanresu A
    Commented Dec 16, 2021 at 22:50
  • 1
    \$\begingroup\$ @Deadcode That seems reasonable, sure. \$\endgroup\$
    – emanresu A
    Commented Mar 22, 2023 at 0:09

30 Answers 30

18
\$\begingroup\$

Jelly, 9 bytes

DLḶU⁵*xDÄ

Try it online!

DL           Digits, length
  ḶU⁵*       Compute [10^(n-1), …, 10, 1]
      xD     Use the digits as repeat counts for this array
               e.g.   423 -> [100, 100, 100, 100,  10,  10,   1,   1,   1]
        Ä    Cumulative sum: [100, 200, 300, 400, 410, 420, 421, 422, 423]
\$\endgroup\$
2
  • 3
    \$\begingroup\$ Great approach! \$\endgroup\$
    – Luis Mendo
    Commented Dec 15, 2021 at 23:32
  • 2
    \$\begingroup\$ It's interesting how the bytecounts for parts of this approach differ between languages. For example, Vyxal takes three bytes to generate the powers, osabie takes four and Jelly takes six, but they all end up wiht the same total. \$\endgroup\$
    – emanresu A
    Commented Dec 16, 2021 at 0:41
12
\$\begingroup\$

JavaScript (ES6),  48  46 bytes

f=(n,k=1)=>n?n%k?[...f(n-k/10),n]:f(n,k*10):[]

Try it online!

How?

Instead of going from \$0\$ to \$n\$, we go from \$n\$ to \$0\$ and store the intermediate steps in reverse order.

At each step, we start with \$k=1\$ and recursively multiply \$k\$ by \$10\$ until \$n\bmod k\neq 0\$, which is a way to locate the least significant non-zero digit in \$n\$. We decrement this digit by subtracting \$k/10\$ from \$n\$ and repeat the process until \$n=0\$.


JavaScript (ES6), 49 bytes

This version expects a string and uses a lookahead assertion to locate and decrement the least significant non-zero digit.

f=n=>+n?[...f(n.replace(/.(?=0*$)/,c=>c-1)),n]:[]

Try it online!

\$\endgroup\$
8
\$\begingroup\$

05AB1E, 11 9 bytes

Thanks to @ovs for 2 bytes off, and to @KevinCruijssen for pointing out that the input can be an integer instead of an array

ā<R°¹ÅΓηO

Port of Lynn's answer.

Try it online!

\$\endgroup\$
3
  • 2
    \$\begingroup\$ gݨR can be shortened to ā<R (length range, decrement, reverse) and Å»+ can be ηO (prefixes, sum) \$\endgroup\$
    – ovs
    Commented Dec 16, 2021 at 0:05
  • \$\begingroup\$ Small FYI: your program also works with an integer-input instead of digit-list. :) \$\endgroup\$ Commented Dec 16, 2021 at 7:38
  • \$\begingroup\$ Thank you both! Edited \$\endgroup\$
    – Luis Mendo
    Commented Dec 16, 2021 at 9:01
7
\$\begingroup\$

APL (Dyalog Unicode), 13 bytes

Port of Lynn's solution – upvote that!

Anonymous prefix lambda, taking a digit list as argument and returning a numeric list. Requires 0-based indexing.

{+\⍵/10*⌽⍳≢⍵}

Try it online!

{} "dfn"; argument is :

+\ cumulative sum of…

⍵/ the argument numbers replicating the respective numbers in…

10* ten raised to the powers of…

 the reversed…

 indices in an array of size…

 tally of elements in…

 argument


Old solution: 24 17 bytes

−4 thanks to ovs

Full program. Prompts for digit list.

↑¨{⍺,,¨∘⍵⊃⌽⍺}/⍳¨⎕

Try it online!

 prompt for digit list

⍳¨ generate 1…n for each digit

{}/ reduce (from the right) using this lambda:

⊃⌽⍺ the last element of the left argument (lit. the first of the reverse)

,¨∘⍵ prepend that to each of the left argument elements

⍺, prepend the left argument to that

↑¨ combine each list of lists into a matrix, zero-padding on the right

\$\endgroup\$
6
  • \$\begingroup\$ Mix can simplify things a lot here: {↓↑⊃{⍺,,¨∘⍵⊃⌽⍺}/⍳¨⍵} (The Split is probably not necessary and a train might be shorter) \$\endgroup\$
    – ovs
    Commented Dec 15, 2021 at 23:07
  • \$\begingroup\$ @ovs Embarrassing. Thank you. \$\endgroup\$
    – Adám
    Commented Dec 15, 2021 at 23:13
  • \$\begingroup\$ Symbol for symbol BQN translation: {+`𝕩/10⋆⌽1+↕≠𝕩} \$\endgroup\$
    – Razetime
    Commented Dec 16, 2021 at 12:54
  • \$\begingroup\$ @Razetime Markdown fail. \$\endgroup\$
    – Adám
    Commented Dec 16, 2021 at 12:55
  • \$\begingroup\$ @Razetime Tacit: +`⊢/10⋆1+⌽∘↕∘≠ \$\endgroup\$
    – Adám
    Commented Dec 16, 2021 at 12:56
7
\$\begingroup\$

Raku, 37 bytes

{[\R+] flat (10 X**^$_)Zxx.flip.comb}

Try it online!

An anonymous code block that takes a number and returns an array.

Explanation:

{                                   }  # Anonymous code block
            (10 X**^$_)                  # Generate powers of 10
                       Zxx               # Zip repeat each by
                          .flip.comb     # The reversed digits of the number
       flat                              # Flatten this list
 [ R+]                                   # Reduce by reverse addition
  \                                      # Keeping intermediate values
\$\endgroup\$
6
\$\begingroup\$

Jelly, 9 bytes

æḟ⁵ạƊƬINÄ

Try it online!

9 bytes sure seems to be special here.

     Ƭ       Collect results while unique from repeating:
   ạ         absolute difference from
æḟ⁵          greatest less than or equal power of 10.
        Ä    Take the cumulative sum of
      IN     each amount by which it decreased.

Jelly, 9 bytes

ọ⁵⁵*ạoµƬU

Try it online!

Conceived of independently from, but very similar to, Arnauld's solution.

      µƬ     Collect results while unique from repeating:
ọ⁵           How many times does 10 evenly divide it?
  ⁵*         Raise 10 to that power,
    ạ        take the absolute difference,
     o       and keep the previous value (ending the loop) if it's 0.
        U    Reverse.
\$\endgroup\$
5
\$\begingroup\$

Python 2, 58 57 bytes

f=lambda n,k=1:n%k and f(n-k/10)+[n]or n*[1]and f(n,k*10)

Attempt This Online!

Port of Arnauld's answer.

-1 thanks to @ovs

Python 2, 76 64 bytes

x=input()
c=0
i=len(x)
for d in x:i-=1;exec"c+=10**i;print c;"*d

Attempt This Online!

Port of Lynn's answer.

-12 thanks to @ovs


Python 2, 74 bytes

x=input()
o=[0]*len(x)
i=0
for d in x:
 while o[i]<d:o[i]+=1;print o
 i+=1

Attempt This Online!

\$\endgroup\$
1
  • \$\begingroup\$ 57 on the recursive function. And for the Port of Lynn's answer you can save some bytes by calculating and printing the cumulative sums directly without constructing an intermediate list. With exec this can be very close to the recursive function. \$\endgroup\$
    – ovs
    Commented Dec 16, 2021 at 10:26
5
\$\begingroup\$

R, 64 52 43 bytes

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

Edit: -12 bytes thanks to @Giuseppe.

function(d)cumsum(rep(10^(sum(d|1):1-1),d))

Try it online!

Yet another port of @Lynn's answer.

Takes input as a vector of digits.


R, 49 bytes

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

function(n)while(n>F)show(F<-F+10^(nchar(n-F)-1))

Try it online!

Direct approach inspired by @DLosc's answer.

\$\endgroup\$
2
  • \$\begingroup\$ 52 bytes \$\endgroup\$
    – Giuseppe
    Commented Dec 16, 2021 at 20:36
  • \$\begingroup\$ @Giuseppe - thanks - but I'm absolutely sure that I tried direct rep and got invalid times argument... but it works now... \$\endgroup\$
    – pajonk
    Commented Dec 16, 2021 at 20:44
4
\$\begingroup\$

Vyxal, 9 bytes

ẏ↵ṘZvƒẋf¦

Try it Online!

Jelly porting fun

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

Pip, 26 24 22 bytes

b:DQa#b?(fa).0ALa.\,bl

Requires a flag for nicely formatted list output; -p, -l, and -s are all good options. Replit! Or, Try it online!

Explanation

A recursive full program that returns a list:

b:DQa#b?(fa).0ALa.\,bl
    a                   The argument number
  DQ                    Dequeue the last digit
b:                      and assign it to local variable b
                        (In the base case, a was empty and b is now nil)
     #b?                If b is a digit (thus has a nonzero length):
        (fa)             Call the main function recursively on a
            .0           Concatenate 0 to the end of each number in the result
              AL         Append this list:
                a.        Concatenate a with each of
                  \,b     Inclusive range from 1 to b
                        Otherwise (b is nil):
                     l   Return empty list
\$\endgroup\$
4
\$\begingroup\$

QBasic, 51 bytes

INPUT n
WHILE n>g
g=g+10^(LEN(STR$(n-g))-2)
?g
WEND

Try it at Archive.org!

Explanation

We can calculate which digit we want to increment by getting the length of the difference between the input number n and the current number g:

 1234
-1210
=====
   24 -> length 2, increment by 10^1

Since QBasic's STR$ function adds a space to the front of nonnegative numbers, the power of 10 that we need is LEN minus 2. Thus, we add 10^(LEN(STR$(n-g))-2) to g, print g (? is a shortcut for PRINT), and loop until g and n are equal.

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

C (gcc), 74 bytes

a;g(x){a=0;f(x,1);}f(x,y){y<x&&f(x,y*10);for(;a+y<=x;)printf("%d ",a+=y);}

Try it online!

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

Perl 5 -F, 55 47 bytes

@a=(0)x@F;map{for$b(0..shift@F){$_=$b;say@a}}@a

Try it online!

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

brainfuck, 73 bytes

,[>-[-----<-<+>>]<++++<--->>>,]+<++++++++++[<]>>[-[<+[<<]>>[.>>]<[<<]]>>]

Try it online!

Treats this as a string processing task. At each step, we find the first digit that still needs to be incremented, increment it, and print the number.

Input loop
,[

  Place 48 in cell while subtracting 47 from input cell
  >-[-----<-<+>>]<++++<--->>>

Repeat until input exhausted
,]
If input number was 1024 we now have 48 2 48 1 48 3 48 5 0 (0)

Set up fake 0 digit at the end (to save bytes later)
+

Set up output LF
<++++++++++

Return to first input cell
[<]>>

This loop always starts at the first nonzero input cell remaining
Loop until done:
[

  Decrement digit
  -

  If cell is zero we just blanked an already "zero" digit so do nothing
  [

    Increment corresponding output digit
    <+

    Output entire number with LF
    [<<]>>[.>>]

    Return to input cell prior to first nonzero input cell
    <[<<]

  ]

  Move to first nonzero input cell
  >>

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

Scala, 105 101 92 bytes

i=>i.indices.flatMap(e=>Seq.fill(i(e)-48)(("1"+"0"*(i.size-1-e)).toLong)).scan(0L)(_+_).tail

Try it online!

\$\endgroup\$
4
  • \$\begingroup\$ You can use a lambda, by the way. \$\endgroup\$
    – user
    Commented Dec 24, 2021 at 21:39
  • \$\begingroup\$ @user yes, shaved 4 bytes by replacing def f with val f= which isn't counted. \$\endgroup\$
    – Kjetil S
    Commented Dec 25, 2021 at 12:19
  • 1
    \$\begingroup\$ You don’t need the type annotation either. Just put the type on f itself. \$\endgroup\$
    – user
    Commented Dec 25, 2021 at 14:14
  • 1
    \$\begingroup\$ @user, if you say so :) Saved 9 more bytes with your tip here. \$\endgroup\$
    – Kjetil S
    Commented Dec 26, 2021 at 21:47
3
\$\begingroup\$

JavaScript, 55 bytes

x=>eval("for(y=[x];x;)y=[x-=1+`${x}`.match`0+$`,...y]")

Try it online!

\$\endgroup\$
3
\$\begingroup\$

Retina 0.8.2, 25 bytes

^
$%'¶
1T`d`0d`.0*¶
}A`^0

Try it online! Link includes test cases (sorry the output is smashed together). Explanation:

^
$%'¶

Duplicate the first line.

1T`d`0d`.0*¶

Decrement the last nonzero digit on that line.

A`^0

Delete the first line if it's zero.

}`

Repeat until the first line had been reduced to zero.

\$\endgroup\$
3
\$\begingroup\$

MathGolf, 14 bytes

hrxúma\m*─Å+o;

Input as a digit-list.

Try it online.

Explanation:

h              # Push the length of the (implicit) input
 r             # Pop and push a list in the range [0,length)
  x            # Reverse it to (length,0]
   ú           # Convert each value in this list to 10**value
    ma         # Wrap each inner number into a list
      \        # Swap so the input-list is at the top
       m*      # Repeat each wrapped [10**v] that amount of times
         ─     # Flatten the list of lists
          Å    # Loop over this list, using 2 characters as inner code-block:
           +   #  Add the top two values on the stack together
            o  #  Print this number (without popping)
             ; # After the loop, discard the number (since MathGolf implicitly
               # outputs the entire stack after a program ends)
\$\endgroup\$
3
\$\begingroup\$

Python 3, 125 bytes

def f(x):
    s=c=int("1"+~-len(str(x))*"0")
    while s<=x//10*10:
        yield s;s+=c
    for i in range(1,x%10+1):yield i

Try it online!

\$\endgroup\$
3
  • \$\begingroup\$ I'm... not sure this works? \$\endgroup\$ Commented Dec 17, 2021 at 2:34
  • 1
    \$\begingroup\$ @UnrelatedString Ok... I'll try to fix it. \$\endgroup\$ Commented Dec 17, 2021 at 11:46
  • \$\begingroup\$ (By the way, the reason I tried running it in the first place is I was planning to suggest golfing for i in range(1,x%10+1):yield i to yield from range(1,x%10+1), in case something like that survives in the fix.) \$\endgroup\$ Commented Dec 17, 2021 at 11:56
3
\$\begingroup\$

PowerShell Core, 56 bytes

($args|%{0.."$_"-ne0|%{"$c$_"}
$c+=$_;$i++})|% *ht $i 48

Try it online!

Takes a number as a string using splatting in input and returns a list of numbers

-8 bytes thanks to mazzy !

\$\endgroup\$
2
  • 1
    \$\begingroup\$ Try it online! :) \$\endgroup\$
    – mazzy
    Commented Dec 16, 2021 at 19:27
  • 1
    \$\begingroup\$ Try it online!, where *ht is shortcut for PadRight \$\endgroup\$
    – mazzy
    Commented Dec 16, 2021 at 19:40
3
\$\begingroup\$

Wolfram Language (Mathematica), 49 44 43 41 bytes

If[#<1,{0},Max[p=10#0[.1#]]~Range~#⋃p]&

Try it online!

Includes one leading zero.

Range stops before the first number greater than the maximum. For example, Range[3.14] yields {1,2,3}.

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

Charcoal, 22 19 bytes

⭆θ⭆Iι⁺⭆◨⁺…θκ⊕λLθΣν¶

Try it online! Link is to verbose version of code. Explanation:

 θ                  Input string
⭆                   Map over digits and join
    ι               Current digit
   I                Cast to integer
  ⭆                 Map over implicit range and join
          θ         Input string
         …          Truncated to length
           κ        Outer index
        ⁺           Concatenated with
             λ      Inner value
            ⊕       Incremented
       ◨            Right pad with spaces to
              L     Length of
               θ    Input string
      ⭆             Map over characters and join
                 ν  Current character
                Σ   Change space to zero
     ⁺              Concatenated with
                  ¶ Literal newline
\$\endgroup\$
2
\$\begingroup\$

Pari/GP, 47 bytes

f(n)=if(n,concat(f(n-10^valuation(n,10)),n),[])

Try it online!

Port of @Arnauld's JavaScript answer.

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

Haskell, 60 bytes

c 0=[]
c x|(d,m)<-x`divMod`10=map(*10)(c d)++map(x-m+)[1..m]

Try it online!


Simple recursive solution, for example c 345 is equal to

map (*10) (f 34) ++ map (340+) [1..5]

34 is 345 `div` 10

5 is 345 `mod` 10

340 is 345 minus the remainder

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

Thunno D, \$ 20 \log_{256}(96) \approx \$ 16.46 bytes

LR10@rsZZeAuZOA*ESz(

Attempt This Online!

Input as a digit list.

Thunno, \$ 22 \log_{256}(96) \approx \$ 18.11 bytes

dDLR10@rsZZeAuZOA*ESz(

Attempt This Online!

Input as an integer.

Port of Lynn's Jelly answer.

Explanation

dD          # Get digits and duplicate
            # (Not needed in the first answer)
  LR        # Pop one and push the length range
    10@     # Pop and push 10 ** each
       rs   # Reverse and swap
         ZZ # Zip with the digits of the input
eAu         # Map over this list:
   ZO       #  Wrap the power of ten in a list
     A*     #  And repeat it the digit times
       E    # End map
        S   # Flatten the list
         z( # And push the cumulative sums
\$\endgroup\$
2
\$\begingroup\$

Nekomata, 11 bytes

¢DsCr↔~c¢b-

Attempt This Online!

Take 47 as an example.

¢DsCr↔~c¢b-
¢D              Convert the input to decimal digits.
                    47 becomes [4, 7]
  s             Non-deterministically choose a suffix of the list.
                    Possible suffixes are [4, 7], [7], [].
   C            Split the list into the head and the tail.
                    Possible heads are 4 and 7, and the corresponding tails are [7] and [].
    r           Range from 0 to the head minus 1.
                    4 becomes [0, 1, 2, 3], and 7 becomes [0, 1, 2, 3, 4, 5, 6].
     ↔          Reverse the range.
                    Possible results are [3, 2, 1, 0] and [6, 5, 4, 3, 2, 1, 0].
      ~         Non-deterministically choose an element from the range.
                    Possible elements are 3, 2, 1, 0, 6, 5, 4, 3, 2, 1, 0.
       c        Join the element with the tail.
                    Possible results are [3, 7], [2, 7], [1, 7], [0, 7], [6], [5], [4], [3], [2], [1], [0].
        ¢b      Convert the list to a base-10 number.
                    Possible results are 37, 27, 17, 7, 6, 5, 4, 3, 2, 1, 0.
          -     Subtract it from the input.
                    Possible results are 10, 20, 30, 40, 41, 42, 43, 44, 45, 46, 47.
                    The interpreter will print all of them.
\$\endgroup\$
2
\$\begingroup\$

Regex (.NET), 30 bytes

((?(1)\1{10}|x{9}))*x(?<=(x*))

Takes its input in unary, as a string of x characters whose length represents the number. Returns its output as the list of matches' \2 captures.

Try it online!

    # head + tail = N = input number; first match starts with head=0 and tail=N
# Subtract the largest possible power of 10 from tail
(               # \1 = the following, on each iteration (and on each
                #      iteration, add it to head and subtract it from tail):
    (?(1)       # Conditional on whether \1 is set; on the first iteration,
                # it is unset, and on all subsequent iterations it is set:
        \1{10}  # if \1 is set: \1 * 10
    |
        x{9}    # if \1 is unset: 9
    )
)*              # Iterate the above as many times as possible without preventing
                # the following from matching:
x               # Assert tail ≥ 1; head += 1; tail -= 1
(?<=(x*))       # Inside a lookbehind, \2 = head

Regex (Java / .NET), 33 bytes

(\1{10}|(?!\2)x{9}())*x(?<=(^x*))

Returns its output as the list of matches' \3 captures.

Try it online! - Java
Try it online! - .NET

This adds Java support to the 30 byte version by removing the use of the conditional, and hinting how far backwards to go inside the lookbehind.

Regex (.NET), 36 bytes

(((?<=^\3?)x{9}|\2{10})*x(?<=(x*)))*

Returns its output as the list of captures on the Balancing Group \3 stack.

Try it online!

    # head + tail = N = input number; first match starts with head=0 and tail=N
(
    # Subtract the largest possible power of 10 from tail
    (              # \1 = the following, on each iteration (and on each
                   #      iteration, add it to head and subtract it from tail):
        (?<=^\3?)  # Make sure this alternative is only used on the first
                   # iteration of this loop, by asserting that head == 0 on the
                   # first iteration of the outermost loop, or head == \3
                   # on subsequent iterations of the outermost loop.
        x{9}       # 9
    |
        \2{10}     # \2 * 10
    )*             # Iterate the above as many times as possible without
                   # preventing the following from matching:
    x              # Assert tail ≥ 1; head += 1; tail -= 1
    (?<=(x*))      # Inside a lookbehind, \3 = head (which is pushed onto the
                   # Group 3 capture stack)
)*                 # Iterate the above as many times as possible, minimum 0

Regex (Pythonregex / .NET), 41 40 bytes

((?=((?(3)\3{10}|x{9})))(\2))*x(?<=(x*))

Returns its output as the list of matches' \4 captures.

Attempt This Online! - Python (with regex)
Try it online! - .NET

This adds Pythonregex support to the 30 byte version, by replacing the use of the nested backreference \1 with copying a value back and forth between two forward-declared backreferences \2 and \3.

Regex (ECMAScript 2018 / Pythonregex / .NET), 41 bytes

(?=.*?(((x+)\3{8}(?=\3$))*x$))\1(?<=(x*))

Returns its output as the list of matches' \4 captures.

Try it online! - ECMAScript 2018
Attempt This Online! - Python (with regex)
Try it online! - .NET

    # head + tail = N = input number; first match starts with head=0 and tail=N
(?=                           # Atomic lookahead - whatever matches first is
                              # locked in.
    .*?                       # Subtract as little as possible from tail in
                              # order to satisfy the following:
    # Assert that tail is a power of 10, and capture it in \1.
    (                         # \1 = tail
        (
            (x+)\3{8}(?=\3$)  # Assert that 10 divides tail; tail /= 10
        )*                    # Iterate the above as many times as necessary
                              # (minimum 0) to satisfy the following:
        x$                    # Assert tail == 1
    )
)
\1                            # head += \1; tail -= \1
                              # (this applies also to the next match)
(?<=(x*))                     # Inside a lookbehind, \4 = head

Regex (ECMAScript 2018 / Java / Pythonregex / .NET), 42 bytes

(?=.*?(((x+)\3{8}(?=\3$))*x$))\1(?<=(^x*))

Try it online! - ECMAScript 2018
Try it online! - Java
Attempt This Online! - Python (with regex)
Try it online! - .NET

This adds Java support to the 41 byte version by hinting how far backwards to go inside the lookbehind.

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

Perl 5 -F -p, 63 bytes

//+push@a,map$a[-1]+$_*10**(@F-$'),1..$F[$_-1]for 1..@F;$_="@a"

Try it online!

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

Unlike my other regex answer, this outputs in reverse order, in order to support regex engines that are incapable of outputting it in ascending order.

The algorithm used here was conceived of independently from, but is very similar to, Arnauld's JavaScript answer (and therefore pxeger's Python answer) and Unrelated String's 2nd Jelly answer. Unlike those answers, it is impossible to reverse the order of the list before outputting it.

Regex (Perl / PCRE / .NET), 39 35 bytes

(?=((((?(3)\3{10}|x{9}))*x)\2*$))\2

Takes its input in unary, as a string of x characters whose length represents the number. Returns its output as the list of matches' \1 captures.

Try it online! - Perl
Try it online! - PCRE
Try it online! - .NET

    # on the first match, tail = N = input number
(?=
    (                       # \1 = tail (the return value)
        (                   # \2 = the largest power of 10 that divides tail
            (               # \3 = the following, on each iteration (and on each
                            #      iteration, subtract it from tail):
                (?(3)       # Conditional on whether \3 is set; on the first
                            # iteration, it is unset, and on all subsequent
                            # iterations it is set:
                    \3{10}  # if \3 is set: \3 * 10
                |
                    x{9}    # if \3 is unset: 9
                )
            )*              # Iterate the above as many times as possible
                            # without preventing the following from matching:
            x               # Assert tail ≥ 1; tail -= 1
        )
        \2*$                # Assert that \2 divides tail
    )
)
\2                          # tail -= \2, in preparation for the next match

It's impossible for regex flavors without variable-length lookbehind to output this sequence in ascending order. Emulating this with recursion and fixed-width lookbehind in Perl/PCRE doesn't work, because captures made inside a subroutine call are erased upon returning from the call. It's impossible even to guess what the capture will be before it's made using non-atomic lookahead in PCRE2, because there isn't enough room to capture that after the sequence has passed \$n/2\$.

Regex (Perl / Java / PCRE / .NET), 39 37 bytes

(?=(((\3{10}|(?!\4)x{9}())*x)\2*$))\2

Try it online! - Perl
Try it online! - Java
Try it online! - PCRE
Try it online! - .NET

This adds Java support to the 35 byte version by removing the use of the conditional.

Regex (Perl / Pythonregex / Ruby / PCRE / .NET), 45 bytes

(?=((((?=((?(5)\5{10}|x{9})))(\4))*x)\2*$))\2

Try it online! - Perl
Attempt This Online! - Python (with regex)
Try it online! - Ruby
Try it online! - PCRE
Try it online! - .NET

This adds Pythonregex and Ruby support to the 35 byte version, by replacing the use of the nested backreference \3 with copying a value back and forth between two forward-declared backreferences \4 and \5.

Regex (Perl / Java / Pythonregex / Ruby / PCRE / .NET), 47 bytes

(?=((((?=(\6{10}|(?!\5)x{9}()))(\4))*x)\2*$))\2

Try it online! - Perl
Try it online! - Python (with regex)
Try it online! - Ruby
Try it online! - PCRE
Try it online! - .NET

This attempts to add Java support to the 45 byte version by removing the use of the conditional (just like the 37 byte version does to the 35 byte version), but while it works on the other engines, it exposes a bug in Java's regex engine: Try it online! / Attempt This Online!

Regex (ECMAScript / Boost / Python or better), 54 52 bytes

(?=((|x+)\2*(?=(\2$|.*$\2))((x+)\5{8}(?=\5$))*x$))\3

Try it online! - ECMAScript
Try it online! - ECMAScript 2018
Try it online! - Perl
Try it online! - Java
Try it online! - Boost - only works with small numbers
Try it online! - Python
Attempt This Online! - Python (with regex)
Try it online! - Ruby
Try it online! - PCRE
Try it online! - .NET

(?=
    (                         # \1 = tail (the return value)
        (|x+)                 # \2 = 0 or the largest number that satisfies the
                              #      following, whichever matches first
        \2*                   # tail -= \2 * {any nonnegative integer}, to
                              # satisfy the following:
        (?=                   # Lookahead (atomic - first match is locked in)
            (                 # \3 = tail
                \2$           # Assert tail == \2
            |             # or...
                .*$\2         # Assert \2 == 0
            )
        )
        # Assert that tail is a power of 10
        (
            (x+)\5{8}(?=\5$)  # Assert that 10 divides tail; tail /= 10
        )*                    # Iterate the above as many times as necessary
                              # (minimum 0) to satisfy the following:
        x$                    # Assert tail == 1
    )
)
\3                            # tail -= \3, in preparation for the next match

Boost works fine with the previous 54 byte version: Try it online!

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

JavaScript (Node.js), 107 bytes (non-competitive)

I tried to do this challenge in JS with a "functional programming approach", without any recursive call and without regex, and it has become surprinsingly long!

I'm still quite new to JS, so does any of you see if this could this be shortened in some way while keeping this approach?

p=>[...p+=""].flatMap((a,i)=>(r=[...Array(a*=1)].map((b,j)=>(t*10+j+1)*10**(p.length-i-1)),t=t*10+a,r),t=0)

Try it online!

(I can ungolf it if this needs explanations)

\$\endgroup\$
2
  • 1
    \$\begingroup\$ Any reason this needs to be Non-competing? Looks fine to me :D \$\endgroup\$
    – ATaco
    Commented Mar 23, 2023 at 21:42
  • \$\begingroup\$ @ATaco Thank you :) I thought of it as an excuse for making this JS more than two times longer than all the other JS solutions because of the constraints i added ^^' So it's not as competitive as it could have been, but i still want to make it as short as possible using this approach! Do you think i should remove the non-competitive from the title? \$\endgroup\$
    – Fhuvi
    Commented Mar 24, 2023 at 10:10

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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