Odliczanie wymiarowe

17

Napisz funkcję f (n, k), która wyświetla k-wymiarowe odliczanie od n.

Wygląda jednowymiarowe odliczanie z 5

 54321

Wygląda na 2-wymiarowe odliczanie z 5

 54321
 4321
 321
 21
 1

Wreszcie wygląda trójwymiarowe odliczanie z 5

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

Formalna definicja

1-wymiarowe odliczanie z dowolnego n jest pojedynczą linią z cyframi n, n-1, ..., 1 połączonymi (po których następuje nowa linia).

Dla każdego k odliczanie k-wymiarowe od 1 jest pojedynczą linią

 1

Dla n> 1 i k> 1 odliczanie k-wymiarowe od n jest odliczaniem wymiarowym (k-1) od n, a następnie odliczanie k-wymiarowe od n-1.

Wejście

Dwie dodatnie liczby całkowite k i n = 9, w dowolnym wybranym formacie.

Wynik

Odliczanie k-wymiarowe od n, z nową linią po każdym odliczaniu 1-wymiarowym. Dodatkowe znaki nowej linii są dozwolone w danych wyjściowych.

Punktacja

Standardowa punktacja golfowa.

Przykład bonusu

Oto przykład z k> n, 4-wymiarowym odliczaniem od 3 (z dodatkowymi komentarzami, których nie należy uwzględniać w rzeczywistych rozwiązaniach):

 -- 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  

Wyjaśnienia:

Cyfry na linii nie muszą sąsiadować, ale muszą być równomiernie rozmieszczone.

Jeśli wolisz, możesz napisać pełny program zamiast tylko funkcji.

Eric Tressler
źródło
Nie jestem pewien, czy poprawnie rozumiem przypadki testowe. Czy odliczanie 3D i 4D z 2 jest identyczne?
Dennis
1
@ Dennis Myślę, że intencją jest, aby odliczanie 4D od 2 = odliczanie 3D od 2 + 4D od 1
Sp3000
czy nie powinno to oznaczać odliczania 3d od jednego?
Destructible Lemon
Dodatkowe znaki nowej linii są dozwolone w danych wyjściowych. Czy odnosi się to do końcowych znaków nowej linii, czy może wystąpić gdziekolwiek?
Dennis
@Dennis Dodatkowe znaki nowej linii mogą wystąpić wszędzie. Cóż, 543 \ n21 nie jest w porządku, ale po „1” są w porządku.
Eric Tressler,

Odpowiedzi:

15

Python, 60 bajtów

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

Przetestuj na Ideone .

Jak to działa

K wymiarową odliczanie z N może być określona w jednym przypadku podstawowego:

Jeśli n = 1 lub k = 1 , wynikiem jest n || n-1 || ... || 1 || ¶ , gdzie || wskazuje na konkatenację.

Używając definicji rekurencyjnej z pytania f(n,k)zwraca, f(n,k-1)+f(n-1,k)jeśli n> 1 i k> 1 ; w przeciwnym razie zwraca ostatnie n + 1 znaków '987654321\n'.

Dennis
źródło
Dennis jest po prostu zbyt dobry. Jak to zrobiłeś?
clismique
Mój jedyny wgląd tutaj był taki, że można łączyć oba przypadki podstawowe. Reszta to tylko bezpośrednie tłumaczenie definicji rekurencyjnej.
Dennis,
8

Galaretka , 8 bajtów

R¡UḌFṚp⁷

Jest to pełny program, który oczekuje n i k jako argumentów wiersza poleceń.

Wypróbuj online!

Jak to działa

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.)
Dennis
źródło
Nie Ydziała zamiast p⁷?
mile
Raczej. Na 5, 1, wyświetla [54321].
Dennis
5

JavaScript, 40 38 37 bajtów

Zapisano 1 bajt dzięki @ edc65:

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

Poprzednie odpowiedzi

38 bajtów dzięki @Neil:

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

40 bajtów:

f=(n,k)=>k&&n?f(n,k-1)+f(n-1,k):n?n:'\n'
Hedi
źródło
1
Zaoszczędź jeden bajt, używając ||zamiast ?n:. Zapisz kolejny bajt, używając dosłownego nowego wiersza wewnątrz `s zamiast '\n'.
Neil
Najlepsze, co mogłem zrobić bez dodatkowych nowych linii, to 43:f=(n,k)=>n?(k?f(n,k-1):n)+f(n-1,k):k?``:`\n`
Neil
@Neil Używam notatnika ++ do liczenia bajtów, a dosłowny znak nowej linii liczy się jako 2 znaki.
Hedi
Może zamiast tego możesz wypróbować go w swoim notatniku przeglądarki?
Neil
1
Sprytny, +1. Ale użyj *zamiast tego &&.
edc65,
3

Python, 76 75 bajtów

-1 bajt dzięki @ Sp3000

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

Wykonuje procedurę opisaną w PO: łączy malejące nwyniki dla k-1nowych wierszy z podstawą rekurencji 'n...1'ciągu, gdy kjest 1( knie większa niż, 1ponieważ mamy zagwarantowany pozytywny kwkład).

Testuj przypadki na ideone

Jonathan Allan
źródło
3

Python, 86 81 80 bajtów

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

djest liczbą wymiarów, njest liczbą odliczania.

Wkrótce opublikuje wyjaśnienie.

EDYCJA 1: Zmieniłem ją na lambda.

EDYCJA 2: Zapisano 1 bajt dzięki @DestructibleWatermelon.

clismique
źródło
3

Haskell, 57 bajtów

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

Przykład użycia: 5 # 3-> "\n54321\n4321\n321\n21\n1\n4321\n321\n21\n1\n321\n21\n1\n21\n1\n1".

Bezpośrednie wdrożenie definicji.

nimi
źródło
2

Rakieta 215 bajtów

(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))))

Testowanie:

(f 54321 3)

54321
4321
321
21
1
4321
321
21
1
321
21
1
21
1
1
rnso
źródło
Umm ... Dlaczego w trybie 3D 54321pojawia się dwa razy?
Erik the Outgolfer
Próbuję rozwiązać problemy.
rnso
@ EʀɪᴋᴛʜᴇGᴏʟғᴇʀ Problem został rozwiązany.
rnso
Fajnie, i widzę, że usunąłeś wiele białych znaków!
Erik the Outgolfer
W Racket użycie lambda ( λ) jest zawsze mniej bajtów niż użycie define. Ponadto dane wejściowe dla nokreślono jako liczbę, dla której budujesz (range 1 n). Zobacz także o zamianie twojego condna if, ponieważ zapisujesz bajty w else.
Steven H.
2

J, 38 37 32 bajty

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

Jest to funkcja, która bierze k na LHS i n na RHS.

Zapisano 5 bajtów z pomysłami z @ Adám.

Stosowanie

   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

Wyjaśnienie

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
mile
źródło
Powinieneś być w stanie wykorzystać moje podejście .
Adám
@ Adám Dzięki, wypróbuję to
mile
2

Dyalog APL , 18 bajtów

Monituje o n , a następnie o k .

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

~∘'0'⍤1usuń ( ~) zera ( '0') z wierszy ( ⍤1) (wypełnienie spacjami w razie potrzeby) z

reprezentacja postaci

(⌽⍳)⍤0⍣⎕odwrócone ( ) liczą do ( ) każdego czasu skalarnego ( ⍤0), powtarzanego ( ) wejścia ( )

na

wprowadzanie numeryczne

Wypróbuj APL online!

Adám
źródło
2

C 93 bajtów

Iteracyjna implementacja.

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 bajtów

Implementacja rekurencyjna

f(n,k){n*k?f(n,k-1)+f(n-1,k):puts("987654321"+9-n);}
cleblanc
źródło
Nie można deklarować ciągów bez użycia znaku char *, więc twoja rekurencyjna implementacja się nie kompiluje. Ale rozwiązanie jest bardzo łatwe i pozwala zaoszczędzić 4 bajty: wystarczy zamienić mwewnątrz puts()połączenia na "987654321".
G. Sliepen,
Kompilowałem za pomocą gcc (GCC) 3.4.4 (cygming special, gdc 0.12, używając dmd 0.125). Myślę, że to w porządku, ponieważ właśnie przekształcam z char * na int, jednak ponieważ twoje rozwiązanie jest o 4 bajty mniejsze, bardziej mi się podoba. Dzięki
cleblanc,
1

Partia, 117 bajtów

@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

Odpowiedź Portona Dennisa na Python.

Neil
źródło
1

Rubinowy, 56 bajtów

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

Stosowanie

Kiedy wyświetlasz jakieś rozwiązania, powinieneś użyć „Kernel # puts”.

Przykład:

puts f[9,3]
cia_rana
źródło