Размерный отсчет

17

Напишите функцию f (n, k), которая отображает k-мерный отсчет от n.

1-мерный отсчет от 5 выглядит как

 54321

2-мерный отсчет от 5 выглядит как

 54321
 4321
 321
 21
 1

Наконец, 3-мерный отсчет от 5 выглядит как

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

Формальное определение

1-мерный обратный отсчет от любого n представляет собой одну строку с объединенными цифрами n, n-1, ..., 1 (за которыми следует новая строка).

Для любого k k-мерный отсчет от 1 - это одна строка

 1

Для n> 1 и k> 1 k-мерный обратный отсчет от n является (k-1) -мерным обратным отсчетом от n, за которым следует k-мерный обратный отсчет от n-1.

вход

Два натуральных числа k и n <= 9 в любом формате, который вы выберете.

Выход

K-мерный отсчет от n, с новой строкой после каждого 1-мерного отсчета. Дополнительные символы новой строки разрешены в выходных данных.

счет

Стандартные оценки в гольф.

Бонус пример

Вот пример с k> n, четырехмерным обратным отсчетом от 3 (с дополнительными комментариями, которые не должны быть включены в реальные решения):

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

Разъяснения:

Цифры в строке не обязательно должны быть соседними, но они должны быть равномерно распределены.

Вы можете написать полную программу вместо просто функции, если хотите.

Эрик Тресслер
источник
Я не уверен, что правильно понимаю контрольные примеры. 3D и 4D обратный отсчет от 2 идентичны?
Деннис
1
@ Денис Я думаю, что намерение состоит в том, чтобы 4D отсчет от 2 = 3D отсчет от 2 + 4D отсчет от 1
Sp3000
не должен ли он сказать 3d отсчет от одного?
Разрушаемый Лимон
Дополнительные символы новой строки разрешены в выходных данных. Относится ли это к завершающим символам новой строки или они могут появляться где угодно?
Деннис
@Dennis Дополнительные переводы строк могут встречаться где угодно. Ну, 543 \ n21 не в порядке, но после любой '1' они в порядке.
Эрик Тресслер

Ответы:

15

Python, 60 байт

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

Проверьте это на Ideone .

Как это устроено

К - мерный отсчет от п может быть определен с помощью одного базового случая:

Если n = 1 или k = 1 , на выходе получается n || n-1 || ... || 1 || ¶ , где || указывает на конкатенацию.

Используя рекурсивное определение из вопроса, f(n,k)возвращает, f(n,k-1)+f(n-1,k)если n> 1 и k> 1 ; в противном случае он возвращает последние n + 1 символов из '987654321\n'.

Деннис
источник
Деннис просто слишком хорош. Как ты это сделал?
clismique
Мое единственное понимание здесь состояло в том, что вы можете объединить оба базовых случая. Все остальное - просто прямой перевод рекурсивного определения.
Деннис
8

Желе , 8 байт

R¡UḌFṚp⁷

Это полная программа, которая ожидает n и k в качестве аргументов командной строки.

Попробуйте онлайн!

Как это устроено

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.)
Деннис
источник
Не Yработает вместо p⁷?
миль
Вроде. Для 5, 1, это отображает [54321].
Деннис
5

Javascript, 40 38 37 байт

Сохранено 1 байт благодаря @ edc65:

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

Предыдущие ответы

38 байтов благодаря @Neil:

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

40 байтов:

f=(n,k)=>k&&n?f(n,k-1)+f(n-1,k):n?n:'\n'
Хеди
источник
1
Сохраните один байт, используя ||вместо ?n:. Сохраните другой байт, используя буквальный символ новой строки внутри `s вместо '\n'.
Нил,
Лучшее, что я мог обойтись без дополнительных новых строк, было 43:f=(n,k)=>n?(k?f(n,k-1):n)+f(n-1,k):k?``:`\n`
Нил
@Neil Я использую notepad ++ для подсчета байтов и буквального перевода строки как 2 символа.
Хеди
Может быть, вы могли бы попробовать это в блокноте браузера?
Нил
1
Умный, +1. Но используйте *вместо этого &&.
edc65
3

Python, 76 75 байт

-1 байт благодаря @ Sp3000

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

Выполняет процедуру, описанную в OP: объединяет убывающие nрезультаты для k-1на новых строках с базой рекурсии 'n...1'строки, когда kесть 1(k не больше, 1так как нам гарантирован положительный kввод).

Тестовые случаи на ideone

Джонатан Аллан
источник
3

Python, 86 81 80 байт

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

d это число измерений, n это номер обратного отсчета.

Скоро выложу объяснение.

РЕДАКТИРОВАТЬ # 1: изменил его на лямбда.

РЕДАКТИРОВАТЬ # 2: Сохранено 1 байт благодаря @DestructibleWatermelon.

clismique
источник
3

Haskell, 57 байт

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

Пример использования: 5 # 3-> "\n54321\n4321\n321\n21\n1\n4321\n321\n21\n1\n321\n21\n1\n21\n1\n1".

Прямая реализация определения.

Ними
источник
2

Ракетка 215 байт

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

Тестирование:

(f 54321 3)

54321
4321
321
21
1
4321
321
21
1
321
21
1
21
1
1
rnso
источник
Ммм ... В режиме 3D, почему 54321появляется дважды?
Эрик Outgolfer
Я пытаюсь разобраться в проблемах.
rnso
@ EʀɪᴋᴛʜᴇGᴏʟғᴇʀ Проблема была исправлена.
rnso
Круто, и я также вижу, что вы удалили много пробелов!
Эрик Outgolfer
В Racket использование lambda ( λ) всегда меньше байтов, чем использование define. Кроме того, вход для nбыл указан как число, для которого вы строите (range 1 n). Смотрите также о замене вашего condна if, так как вы сохраняете байты на else.
Стивен Х.
2

J, 38 37 32 байта

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

Это функция, которая принимает k на LHS и n на RHS.

Сохранено 5 байтов с идеями от @ Adám.

использование

   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

объяснение

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
миль
источник
Вы должны быть в состоянии использовать мой подход .
Адам
@ Adám Спасибо, попробую
миль
2

Дьялог АПЛ , 18 байт

Запрашивает для n , затем для k .

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

~∘'0'⍤1удалить ( ~) нули ( '0') из строк (⍤1 ) (заполнение пробелами по мере необходимости)

символьное представление

(⌽⍳)⍤0⍣⎕обратный ( ) отсчет до ( ) каждого скалярного ( ⍤0), повторного ( ) ввода ( ) раз

на

числовой ввод

Попробуй APL онлайн!

Адам
источник
2

C 93 байта

Итеративная реализация.

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("");}}

С 67 65 61 56 52 байт

Рекурсивная реализация

f(n,k){n*k?f(n,k-1)+f(n-1,k):puts("987654321"+9-n);}
cleblanc
источник
Вы не можете объявлять строки без использования char *, поэтому ваша рекурсивная реализация не компилируется. Но решение очень простое и экономит 4 байта: просто замените mвнутри puts()вызова на "987654321".
Г. Слипен
Я скомпилировал, используя gcc (GCC) 3.4.4 (специальный cygming, gdc 0.12, используя dmd 0.125). Я думаю, что это нормально, так как я просто конвертирую из char * в int, так как ваше решение на 4 байта меньше, мне оно нравится больше. Спасибо
cleblanc 9.09.16
1

Пакет, 117 байт

@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

Порт Денис ♦ Python ответ.

Нил
источник
1

Рубин, 56 байт

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

использование

Когда вы отображаете какие-либо решения, вы должны использовать «Kernel # put».

Пример:

puts f[9,3]
cia_rana
источник