17
\$\begingroup\$

Write a function f(n,k) that displays the k-dimensional countdown from n.

A 1-dimensional countdown from 5 looks like

 54321

A 2-dimensional countdown from 5 looks like

 54321
 4321
 321
 21
 1

Finally, a 3-dimensional countdown from 5 looks like

 54321
 4321
 321
 21
 1
 4321
 321
 21
 1
 321
 21
 1
 21
 1
 1

Formal definition

The 1-dimensional countdown from any n is a single line with the digits n, n-1,...,1 concatenated (followed by a newline).

For any k, the k-dimensional countdown from 1 is the single line

 1

For n > 1 and k > 1, a k-dimensional countdown from n is a (k-1)-dimensional countdown from n followed by a k-dimensional countdown from n-1.

Input

Two positive integers k and n <= 9, in any format you choose.

Output

The k-dimensional countdown from n, with a newline after each 1-dimensional countdown. Extra newlines are permitted in the output.

Scoring

Standard golf scoring.

Bonus example

Here's an example with k > n, a 4-dimensional countdown from 3 (with extra comments that are not to be included in actual solutions):

 -- 3-dimensional countdown from 3
 321
 21
 1
 21
 1
 1
 -- 4-dimensional countdown from 2:
 ---- 3-dimensional countdown from 2:
 21
 1
 1
 ---- 4-dimensional countdown from 1:
 1  

Clarifications:

Digits on a line do not need to be adjacent, but they must be evenly-spaced.

You may write a full program instead of just a function, if you prefer.

\$\endgroup\$
5
  • \$\begingroup\$ I'm not sure I understand the test cases correctly. Are the 3D and 4D countdowns from 2 identical? \$\endgroup\$
    – Dennis
    Sep 4, 2016 at 3:19
  • 1
    \$\begingroup\$ @Dennis I think the intention is that 4D countdown from 2 = 3D countdown from 2 + 4D countdown from 1 \$\endgroup\$
    – Sp3000
    Sep 4, 2016 at 3:27
  • \$\begingroup\$ shouldn't it say 3d countdown from one? \$\endgroup\$ Sep 4, 2016 at 4:20
  • \$\begingroup\$ Extra newlines are permitted in the output. Does that refer to trailing newlines or can they occur anywhere? \$\endgroup\$
    – Dennis
    Sep 4, 2016 at 6:43
  • \$\begingroup\$ @Dennis Extra newlines can occur anywhere. Well, 543\n21 isn't okay, but after any '1' they're okay. \$\endgroup\$ Sep 4, 2016 at 12:41

12 Answers 12

15
\$\begingroup\$

Python, 60 bytes

f=lambda n,k:n>1<k and f(n,k-1)+f(n-1,k)or'987654321\n'[~n:]

Test it on Ideone.

How it works

The k-dimensional countdown from n can be defined with a single base case:

If n = 1 or k = 1, the output is n || n-1 || ... || 1 || ¶, where || indicates concatenation.

Using the recursive definition from the question, f(n,k) returns f(n,k-1)+f(n-1,k) if n > 1 and k > 1; otherwise it returns the last n + 1 characters from '987654321\n'.

\$\endgroup\$
2
  • \$\begingroup\$ Dennis is just too good. How did you do it though? \$\endgroup\$
    – clismique
    Sep 4, 2016 at 6:15
  • \$\begingroup\$ My only insight here was that you can combine both base cases. The rest is just a direct translation of the recursive definition. \$\endgroup\$
    – Dennis
    Sep 4, 2016 at 7:01
8
\$\begingroup\$

Jelly, 8 bytes

R¡UḌFṚp⁷

This is a full program that expects n and k as command-line arguments.

Try it online!

How it works

R¡UḌFṚp⁷  Main link. Left argument: n. Right argument: k

 ¡        Repeat the link to the left k times.
R           Range; map each integer j in the previous return value to [1, ..., j].
  U       Upend; reverse each 1-dimensional array in the result.
   Ḍ      Undecimal; convert each 1-dimensional array from base 10 to integer.
    F     Flatten the resulting array.
     Ṛ    Reverse the result.
      p⁷  Cartesian product with '\n'. (Join is weird for singleton arrays.)
\$\endgroup\$
2
  • \$\begingroup\$ Doesn't Y work in place of p⁷? \$\endgroup\$
    – miles
    Sep 13, 2016 at 1:00
  • \$\begingroup\$ Sort of. For 5, 1, it displays [54321]. \$\endgroup\$
    – Dennis
    Sep 13, 2016 at 1:08
5
\$\begingroup\$

Javascript, 40 38 37 bytes

Saved 1 bytes thanks to @edc65:

f=(n,k)=>k*n?f(n,k-1)+f(n-1,k):n||`
`

Previous answers

38 bytes thanks to @Neil:

f=(n,k)=>k&&n?f(n,k-1)+f(n-1,k):n||`
`

40 bytes:

f=(n,k)=>k&&n?f(n,k-1)+f(n-1,k):n?n:'\n'
\$\endgroup\$
7
  • 1
    \$\begingroup\$ Save one byte by using || instead of ?n:. Save another byte by using a literal newline inside `s instead of '\n'. \$\endgroup\$
    – Neil
    Sep 4, 2016 at 11:28
  • \$\begingroup\$ Best I could do without the extra newlines was 43: f=(n,k)=>n?(k?f(n,k-1):n)+f(n-1,k):k?``:`\n` \$\endgroup\$
    – Neil
    Sep 4, 2016 at 11:56
  • \$\begingroup\$ @Neil I'm using notepad++ to count bytes and the literal newline count as 2 char. \$\endgroup\$
    – Hedi
    Sep 4, 2016 at 12:43
  • \$\begingroup\$ Maybe you could try it in your browser scratchpad instead? \$\endgroup\$
    – Neil
    Sep 4, 2016 at 13:11
  • 1
    \$\begingroup\$ Clever, +1. But use * instead &&. \$\endgroup\$
    – edc65
    Sep 6, 2016 at 7:58
3
\$\begingroup\$

Python, 76 75 bytes

-1 byte thanks to @Sp3000

c=lambda n,k:k>1and'\n'.join(c(n-i,k-1)for i in range(n))or'987654321'[-n:]

Caries out the procedure as described in the OP: joins the decreasing n results for k-1 on newlines with a base of the recursion of the 'n...1' string when k is 1 (k not greater than 1 since we are guaranteed positive k input).

Test cases on ideone

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

Python, 86 81 80 bytes

o=lambda d,n:"987654321"[-n:]if d<2else"\n".join([o(d-1,n-x) for x in range(n)])

d is the number of dimensions, n is the countdown number.

Will post an explanation soon.

EDIT #1: Changed it to lambda.

EDIT #2: Saved 1 byte thanks to @DestructibleWatermelon.

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

Haskell, 57 bytes

n#1='\n':(show=<<[n,n-1..1])
1#_=1#1
n#k=n#(k-1)++(n-1)#k

Usage example: 5 # 3 -> "\n54321\n4321\n321\n21\n1\n4321\n321\n21\n1\n321\n21\n1\n21\n1\n1".

A direct implementation of the definition.

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

Racket 215 bytes

(define(g n k(s(number->string n)))(cond [(< k 2) n]
[else(define o(for/list((i(string-length s)))
(string->number(substring s i))))(for/list((x o))(g x(- k 1)))])) 
(define(f n k)(for-each println(flatten(g n k))))

Testing:

(f 54321 3)

54321
4321
321
21
1
4321
321
21
1
321
21
1
21
1
1
\$\endgroup\$
6
  • \$\begingroup\$ Umm... On 3D mode, why does 54321 appear twice? \$\endgroup\$ Sep 4, 2016 at 7:21
  • \$\begingroup\$ I am trying to sort out the issues. \$\endgroup\$
    – rnso
    Sep 4, 2016 at 7:42
  • \$\begingroup\$ @EʀɪᴋᴛʜᴇGᴏʟғᴇʀ The problem has been corrected. \$\endgroup\$
    – rnso
    Sep 5, 2016 at 17:43
  • \$\begingroup\$ Cool, and I also see you removed lots of whitespace! \$\endgroup\$ Sep 5, 2016 at 17:47
  • \$\begingroup\$ In Racket, using lambda (λ) is always less bytes than using define. Also, the input for n was specified to be a number for which you build the (range 1 n). See also about replacing your cond with an if, since you save bytes on the else. \$\endgroup\$
    – Steven H.
    Sep 6, 2016 at 3:12
2
\$\begingroup\$

J, 38 37 32 bytes

a:":@>@-.~&,0<@-."1~0&(](-i.)"0)

This is a function that takes k on the LHS and n on the RHS.

Saved 5 bytes with ideas from @Adám.

Usage

   f =: a:":@>@-.~&,0<@-."1~0&(](-i.)"0)
   3 f 5
5 4 3 2 1
4 3 2 1  
3 2 1    
2 1      
1        
4 3 2 1  
3 2 1    
2 1      
1        
3 2 1    
2 1      
1        
2 1      
1        
1

Explanation

a:":@>@-.~&,0<@-."1~0&(](-i.)"0)  Input: k on LHS, n on RHS
                    0&(        )  Repeat k times on initial value n
                        (   )"0   For each value x
                          i.        Make the range [0, x)
                         -          Subtract x from each to make the range [x, 1]
                       ]            Return the array of ranges
            0  -."1~              Remove the zeros from each row
             <@                   Box each row
          &,                      Flatten the array of boxes
a:     -.~                        Remove the empty boxes
     >@                           Unbox each
  ":@                             Convert it into a string and return
\$\endgroup\$
2
  • \$\begingroup\$ You should be able to use my approach. \$\endgroup\$
    – Adám
    Sep 5, 2016 at 17:37
  • \$\begingroup\$ @Adám Thanks, I'll try it out \$\endgroup\$
    – miles
    Sep 5, 2016 at 18:10
2
\$\begingroup\$

Dyalog APL, 18 bytes

Prompts for n, then for k.

~∘'0'⍤1⍕(⌽⍳)⍤0⍣⎕⊢⎕

~∘'0'⍤1 remove (~) the () zeros ('0') from the rows (⍤1) (padding with spaces as needed) of

the character representation of

(⌽⍳)⍤0⍣⎕ the reversed () count until () each scalar (⍤0), repeated () input () times

on

numeric input

TryAPL online!

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

C 93 Bytes

Iterative implementation.

m,i,j;f(n,k){for(;m<k+2;m++)for(j=0;j<n;j++){for(i=m;i<n-j;i++)printf("%d",n-j-i);puts("");}}

C 67 65 61 56 52 Bytes

Recursive implementation

f(n,k){n*k?f(n,k-1)+f(n-1,k):puts("987654321"+9-n);}
\$\endgroup\$
2
  • \$\begingroup\$ You can't declare strings without using char *, so your recursive implementation doesn't compile. But the solution is very easy and saves 4 bytes: just replace m inside the puts() call with "987654321". \$\endgroup\$
    – G. Sliepen
    Sep 9, 2016 at 10:06
  • \$\begingroup\$ I compiled using gcc (GCC) 3.4.4 (cygming special, gdc 0.12, using dmd 0.125). I think it's ok since I'm just converting from char* to int, however, since your solution is 4 bytes smaller I like it better. Thanks \$\endgroup\$
    – cleblanc
    Sep 9, 2016 at 13:36
1
\$\begingroup\$

Batch, 117 bytes

@setlocal
@set/an=%1-1,k=%2-1,p=n*k,s=987654321
@if %p%==0 (call echo %%s:~-%1%%)else call %0 %1 %k%&call %0 %n% %2

Port of Dennis♦'s Python answer.

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

Ruby, 56 bytes

f=->n,k{n>1&&k>1?[f[n,k-1],f[n-1,k]]:[*1..n].reverse*""}

Usage

When you display any solutions, you should use "Kernel#puts".

Example:

puts f[9,3]
\$\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.