# Stacked digit staircases

Given positive integers $w$ and $h$ output $w$ columns and $h$ rows of text as described below.

The first row begins with 11 0s, the second row with 10 1s, third with nine 2s and so on down the the tenth row with two 9s. On each of these first ten rows, following the initial run of consecutive digits, the next lowest digit appears two times before the second next lowest digit appears two times, with this pattern repeating forever. If a run of 0s occurs, the digits after it are always 9s.

Rows below the tenth row are the same as the row immediately above it but shifted to the right by one. The new digit that appears is the same as the previous leftmost digit if it was not next to another instance of itself. Otherwise it is the next highest digit (cycling from 9 back to 0).

The first $11\times10$ elements are as follows:

00000000000
11111111110
22222222211
33333333221
44444443322
55555544332
66666554433
77776655443
88877665544
99887766554


Here is an image with colored text to make the pattern more clear. If you need to produce fewer columns/rows then you should simply crop the above text.

If you need to produce more columns/rows than this, existing staircases should be extended. If more columns/rows adds new staircases of consecutive digits, digits should be cyclicly chosen from the integers. Thus for input $(15,13)$ the output should be

000000000009988
111111111100998
222222222110099
333333332211009
444444433221100
555555443322110
666665544332211
777766554433221
888776655443322
998877665544332
099887766554433
009988776655443
100998877665544


Here is an image of this text with color: ### Rules

• Output can be given by any convenient method.
• Either a full program or a function are acceptable. If a function, you can return the output rather than printing it.
• You can return a list of lines if you prefer.
• You can return a 2D array of digits or list of lists of digits if you prefer.
• Standard loopholes disallowed.

Shortest code wins.

### Test cases

Input is taken as $(w,h)$ for the test cases.

1,1
0

3,2
000
111

20,1
00000000000998877665

11,10
00000000000
11111111110
22222222211
33333333221
44444443322
55555544332
66666554433
77776655443
88877665544
99887766554

15,13
000000000009988
111111111100998
222222222110099
333333332211009
444444433221100
555555443322110
666665544332211
777766554433221
888776655443322
998877665544332
099887766554433
009988776655443
100998877665544

• I don't really understand the pattern. Could you explain the pattern concretely rather than expecting it to be extrapolated from examples. Some people find examples helpful but I don't really see exactly how the pattern follows from the examples. – Post Rock Garf Hunter Jul 14 '18 at 8:10
• @WW Thanks, I added a bit more thorough explanation at the top – dylnan Jul 14 '18 at 14:18
• Interestingly now that we have TeX you can actually make the colored grid in text. Test: $\color{red}{1234}$ – qwr Jul 14 '18 at 19:59
• @qwr oh nice, didn’t know we could do that. What command did you do it with? – dylnan Jul 14 '18 at 23:47
• \color{red}{text} I believe – qwr Jul 15 '18 at 2:27

# Python 3, 94937877 74 bytes

lambda x,y:[[[(j-i+10)//2%10,j][j+i<9]for i in range(x)]for j in range(y)]

-1 byte from dylnan

-15 bytes by returning a list of lists instead of printing from xnor

-1 byte by switching the order of the (j-i+10)//2%10 and j parts of the if-else

-3 bytes from Jo King by changing the if-else to a list.

Try it online!

• Using a lambda function saves a byte: TIO – dylnan Jul 13 '18 at 22:35
• @dylnan Thanks! – pizzapants184 Jul 13 '18 at 22:37
• The challenge allows outputting lists of lists of digits, so it looks like you don't need to do any printing or joining. – xnor Jul 14 '18 at 1:42

# C (gcc), 101100 99 bytes

s,t;a(i,r){for(t=~0;++t<r;puts(""))for(s=0;s<i;putchar(48+(t+(s>10-t)*(10*s+9-(s+++t-11)/2))%10));}


Try it online!

• -1 byte Try it online! printf("%d", -> putchar(48+ – pizzapants184 Jul 13 '18 at 22:10
• @pizzapants184 Thanks a lot. – Jonathan Frech Jul 13 '18 at 22:11
• @ceilingcat Unfortunately no. – Jonathan Frech Dec 19 '18 at 7:41

# Canvas, 14 bytes

［⁷｛¹∔⁶＋»¹ｍ◂＠］］


Try it here!

While making this I noticed in several places I had negative modulos in Canvas (here, it meant that » - floor div 2 - rounded towards 0). The previous 18 byte answer that worked without fixes doesn't work anymore (because I only save main.js between versions) but TIO still has the old version

Explanation:

[            ]  for 1..input
⁷{         ]     for 1..2nd input
¹∔               subtract from this loop counter the outer loops one
»            divide by 2, rounded to -∞
¹m          minimum of that & the outer loops counter
◂@        in the string "0123456789", get the xth char, 1-indexed


# Charcoal, 20 17 bytes

Ｅη⭆θ﹪⌊⟦ι÷⁺⁻ιλχ²⟧χ


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

 η                  Height
Ｅ                   Map over implicit range
θ                Width
⭆                 Map over implicit range and join
⁻ιλ       Subtract column from row
÷     ²     Integer divide by 2
ι            Current row
⌊⟦        ⟧    Take the minimum
﹪           χ   Modulo by 10
Implicitly print each row on its own line


Edit: Saved 3 bytes by switching to @dzaima's algorithm.

# Jelly, 14 bytes

_@þ:2+6«"J$’%⁵  A dyadic link taking $w$ on the left and $h$ on the right which yields a list of lists of digits. Try it online! Or see a (post-formatted) test-suite. ### How? _@þ:2+6«"J$’%⁵ - Link: integer w, integer h
þ            - outer product using (i.e. [[f(i,j) for i in 1..w] for j in 1..h]):
_@             -   subtraction with swapped arguments (i.e. f(i,j): j-i)
-   e.g. the 4th row is [3, 2, 1, 0,-1,-2,-3,-4,-5,-6,-7,-8,-9,-10,-11,...]
:2          - integer divide by two (vectorises)
-                       [1, 1, 0, 0,-1,-1,-2,-2,-3,-3,-4,-4,-5,-5,-6,...]
-                       [7, 7, 6, 6, 5, 5, 4, 4, 3, 3, 2, 2, 1, 1, 0,...]
J     -   range of length -> [1,2,3,...,h]
"      -   zip with:
«       -     minimum (vectorises)
-                       [4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 2, 2, 1, 1, 0,...]
’   - decrement (vectorises)
-                       [3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 1, 1, 0, 0,-1,...]
⁵ - literal ten
%  - modulo (vectorises)
-                       [3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 1, 1, 0, 0, 9,...]


# Kotlin, 78 bytes

{w:Int,h:Int->List(h){r->List(w){c->if(c<11-r)r%10
else(r+9*((c-9+r)/2))%10}}}


Try it online!

# Jelly, 19 bytes

Uses a very similar approach to pizzapants' and Neil's. Saved 1 byte thanks to Jonathan Allan.

p’Ḣ_/HḞ+ʋS<9Ɗ?€5s%⁵


Try it online!

_/HḞ+5


This is a monadic link (the Jelly equivalent of a single argument function), that can be invoked from the next link using the quick Ç. It takes a list of two integers and does the following on it:

_/


Reduce by subtraction.

HḞ+5%⁵


Floor its halve to an integer and add 5, then take it modulo 10.

p’ḢÇS<9Ɗ?€s


This is a dyadic link (the Jelly equivalent of a two-argument function), that can be invoked from the next link using the ç quick. It takes two integers $x$ and $y$ and performs the following:

p’


Cartesian product of their ranges, and then subtract $1$ from each integer in that list. It is equivalent to $([0, x)\cap \mathbb{Z}) \times ([0, y)\cap \mathbb{Z})$.

S<9Ɗ?€


And for each of the pair in the Cartesian product, if their sum is less than 9, then:

Ḣ


Retrieve the head of the pair (first element). Otherwise,

Ç


Call the helper link (explained above) on the pair.

s%⁵


Finally, split the resulting list into chunks of length $y$ and take each mod 10.

• You can move the mod 10 to the end and then in-line the helper to save a byte -- either as a dyad with p’Ḣ_/HḞ+ʋS<9Ɗ?€5s%⁵ or p’Ḣ_/:2+ʋS<9Ɗ?€5s%⁵, or as a monad with p’Ḣ_/:2+5ƲS<9Ɗ?€s%⁵ – Jonathan Allan Jul 15 '18 at 0:28