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\$
  • \$\begingroup\$ I'm not sure I understand the test cases correctly. Are the 3D and 4D countdowns from 2 identical? \$\endgroup\$ – Dennis Sep 4 '16 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 '16 at 3:27
  • \$\begingroup\$ shouldn't it say 3d countdown from one? \$\endgroup\$ – Destructible Lemon Sep 4 '16 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 '16 at 6:43
  • \$\begingroup\$ @Dennis Extra newlines can occur anywhere. Well, 543\n21 isn't okay, but after any '1' they're okay. \$\endgroup\$ – Eric Tressler Sep 4 '16 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\$
  • \$\begingroup\$ Dennis is just too good. How did you do it though? \$\endgroup\$ – Qwerp-Derp Sep 4 '16 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 '16 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\$
  • \$\begingroup\$ Doesn't Y work in place of p⁷? \$\endgroup\$ – miles Sep 13 '16 at 1:00
  • \$\begingroup\$ Sort of. For 5, 1, it displays [54321]. \$\endgroup\$ – Dennis Sep 13 '16 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\$
  • 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 '16 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 '16 at 11:56
  • \$\begingroup\$ @Neil I'm using notepad++ to count bytes and the literal newline count as 2 char. \$\endgroup\$ – Hedi Sep 4 '16 at 12:43
  • \$\begingroup\$ Maybe you could try it in your browser scratchpad instead? \$\endgroup\$ – Neil Sep 4 '16 at 13:11
  • 1
    \$\begingroup\$ Clever, +1. But use * instead &&. \$\endgroup\$ – edc65 Sep 6 '16 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\$
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\$
  • \$\begingroup\$ Umm... On 3D mode, why does 54321 appear twice? \$\endgroup\$ – Erik the Outgolfer Sep 4 '16 at 7:21
  • \$\begingroup\$ I am trying to sort out the issues. \$\endgroup\$ – rnso Sep 4 '16 at 7:42
  • \$\begingroup\$ @EʀɪᴋᴛʜᴇGᴏʟғᴇʀ The problem has been corrected. \$\endgroup\$ – rnso Sep 5 '16 at 17:43
  • \$\begingroup\$ Cool, and I also see you removed lots of whitespace! \$\endgroup\$ – Erik the Outgolfer Sep 5 '16 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 '16 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\$
  • \$\begingroup\$ You should be able to use my approach. \$\endgroup\$ – Adám Sep 5 '16 at 17:37
  • \$\begingroup\$ @Adám Thanks, I'll try it out \$\endgroup\$ – miles Sep 5 '16 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\$
  • \$\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 '16 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 '16 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.