Перетворення чисел у "Не зовсім систему-значення"


11

Дозволяє створити систему чисел, де найбільша цифра у значенні n-го місця (рахуючи справа наліво) довжини числа m завжди дорівнює m - n + 1. Навести приклад найбільшого 5-значного числа, виражаемого в цій системі написано 12345. Окрім кількості доступних цифр для використання в певному місці, яка обмежена, всі інші збільшення є стандартними. А саме, коли цифра повинна перевищувати її межу цифр, ми додаємо її до наступної цифри.

Ось як було б представлено підрахунок у цій системі:

1; 10; 11; 12; 100; 101; 102; 103; 110; 111; 112; 113; 120; 121; 122; 123; 1000; 1001 ...

Ваше завдання - написати функцію, яка приймає стандартне базове число 10 і перетворить її в мою систему нумерації.

Краще коротший код. Шанс Бонне!

** Якщо вам знадобляться цифри після 9 (слід), ви можете використовувати літери, або ви можете повернути двозначний номер як елемент списку.

Випробування

10 -> 111
20 -> 1003
30 -> 1023
50 -> 1123
100 -> 10035
23116 -> 1234567
21977356 -> 123456789A

Останній випадок може бути неймовірно повільним, залежно від способу реалізації. Не потрібно його запускати, якщо це забирає занадто багато часу або використовує занадто багато пам'яті. Однак зауважте, що існують способи, щоб він швидко запускався та використовував мало пам'яті.


З огляду на ваш останній коментар, чи добре, якщо ми завжди повертаємо список із цифрами?
Грег Мартін

Так, це розумний спосіб дати вихід, якщо цифри є правильними
Андо Бандо,

1
Я отримую 100 -> 10035замість цього 100 -> 10033, чи можете ви перевірити?
Грег Мартін

@GregMartin 10035 здається правильним. Я робив свої розрахунки за ручку, а не за програмою, а значить, зробив помилку в обчисленні. Я думаю, у нас є комп’ютери для прямої уваги
Андо Бандо,

1
GB

Відповіді:


4

Математика, 64 байти

Part[Join@@Array[Tuples@Join[{{1}},Array[Range,#-1,3]-1]&,#],#]&

Безіменна функція, яка приймає позитивний цілий аргумент і повертає список цілих чисел.

Join[{{1}},Array[Range,#-1,3]-1]повертає вкладений список { {1}, {0,1,2}, {0,1,2,3}, ..., {0,1,...,#} }. Потім Tuplesповертає (відсортований) набір усіх кортежів, у яких знаходиться перший елемент {1}, чий другий елемент лежить {0,1,2}тощо; це #-значні числа в цій системі нумерації. Join@@Array[...,#]повертає масив усіх чисел у цій системі нумерації з максимум #цифрами та Part[...,#]витягує #таке число.

Це безнадійно повільно! Він працює на вході до 9. Для більшого введення тестуйте його, замінивши кінець ,#],#]&на ,Ceiling[0.9Log[#]]],#]&; це ставить більш реалістичне обмеження кількості цифр, необхідних для того, щоб пройти досить далеко в системі нумерації, щоб знайти потрібну.


3

Математика, 93 байти

Nest[#/.{x___,y_}:>{x,y+1}//.x:{y___,z_:0,w_,v___}/;w>Tr[1^x]-Tr[1^{v}]:>{y,z+1,0,v}&,{0},#]&

Чиста функція з першим аргументом #. Якщо вказано невід’ємне ціле число, воно виведе правильний список цифр (навіть обробляє 0правильно!).

Пояснення

Nest[f,expr,n]дає результат застосування fв expr nрази. У цьому випадку exprє списком {0}і nє вхідним цілим числом #. Функція fскладна:

# (* Starting with the input # *)
 /. (* Apply the following rule *)
   {x___,y_} (* If you see a list of the form {x___,y} *)
            :> (* replace it with *)
              {x,y+1} (* this *)
                     //. (* Now apply the following rule repeatedly until nothing changes *)
                        x:{y___,z_:0,w_,v___} (* If you see a list x starting with a sequence y of 0 or more elements, 
                                                 followed by an optional element z (default value of 0),
                                                 followed by an element w,
                                                 followed by a sequence v of 0 or more elements *)
                                             /; (* such that *)
                                               w>Tr[1^x]-Tr[1^{v}] (* w is greater than the length of x minus the length of {v} *)
                                                                  :> (* replace it with *)
                                                                    {y,z+1,0,v}& (* this *)

Приємне використання y___,z_:0для збільшення довжини списку!
Грег Мартін

2
@GregMartin JungHwan Min використовував його в подібній проблемі вчора.
ngenisis

3

Perl 6 , 38 байт

{map({|[X] 1,|map ^*,3..$_},1..*)[$_]}

Бере додатне ціле число і виводить список цілих чисел, що представляють цифри.

Пояснення:

{                                    }  # a lambda

 map({                    },1..*)       # for each number length from 0 to infinity,
                                        # offset by 1 to avoid a +1 in next step...

           1,|map ^*,3..$_              # generate the digit ranges, e.g.:
                                        #     length 0  ->  (1)  # bogus, but irrelevant
                                        #     length 1  ->  (1)
                                        #     length 2  ->  (1, 0..2)
                                        #     length 3  ->  (1, 0..2, 0..3)
                                        #     length 4  ->  (1, 0..2, 0..3, 0..4)

       [X]                              # take the cartesian product

      |                                 # slip the results into the outer sequence

                                 [$_]   # Index the sequence generated this way


1

Haskell, 65 байт

i(x:r)|x>length r=0:i r|1<2=1+x:r
i[]=[1]
reverse.(iterate i[]!!)

iзбільшує числа в системі числення з цифрами у зворотному порядку. iterateстворює нескінченний список усіх цих чисел, починаючи з нуля, який представлений символом []. Тоді все, що залишилося зробити, це взяти ( !!) потрібний номер і reverseце.

Останній рядок - це функція, а не визначення функції, тому вона не може відображатися як у файлі вихідного коду. Натомість, лише покладіть інші рядки у вихідний код та використовуйте останній рядок у інтерпретаторі (або прив’яжіть функцію до імені, попередньо додавши f=до останнього рядка).

Приклад використання:

*Main> reverse.(iterate i[]!!) $ 100
[1,0,0,3,5]

(8 байтів можна було б зберегти, якби [5,3,0,0,1]дозволено представити результат.)


1

Хаскелл, 49 байт

x=[1]:[n++[d]|n<-x,d<-[0..length n+1]]
(x!!).pred

Перший рядок є допоміжним визначенням, а другий оцінює функцію. Він бере ціле число і повертає список цілих чисел. Спробуйте в Інтернеті!

Пояснення

Я визначаю xяк нескінченний перелік уявлень, згаданий у тексті виклику; основна функція просто зменшує аргумент та індексує x. Перший рядок працює так:

x=                     -- The list of lists x contains
 [1]:                  -- the list [1], followed by
 [n++[d]|              -- integer d appended to list n, where
  n<-x,                -- n is drawn from x, and
  d<-[0..length n+1]]  -- the new "digit" d is drawn from this range.

Ви бачите, що xвизначено саме по собі, але Хаскелл лінивий, тому це не проблема.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.