Развернуть и Сжать


19

Возьмите положительное целое число К качестве входных данных. Начните с Nзнак равно1 и многократно увеличивайте N на наибольшую целую степень из десяти я , чтобы яN и я+NК .

Повторяйте до и возвращайте список всех промежуточных значений , включая как начальную и конечную .Nзнак равноКN1К

Во время этого процесса рост будет первоначально ограничен первым неравенством, а только потом последним; рост примет форму начального периода «расширения», в течение которого увеличивается на все большие степени, после чего следует период «контракта», в течение которого увеличивается на все меньшие степени для «увеличения» на правильный номер.NN

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

1 => [1]
10 => [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
321 => [1,  2,  3,  4,  5,  6,  7,  8,  9,
        10, 20, 30, 40, 50, 60, 70, 80, 90,
        100, 200, 300, 310, 320, 321]
1002 => [1,   2,   3,   4,   5,   6,   7,   8,   9,
         10,  20,  30,  40,  50,  60,  70,  80,  90,
         100, 200, 300, 400, 500, 600, 700, 800, 900,
         1000, 1001, 1002]

Это , поэтому выигрывает самый короткий ответ (в байтах).


2
Можем ли мы напечатать числа вместо возврата списка?
Адам

@ Adám Да, можно.
Esolanging Fruit

Ответы:


8

Haskell , 72 68 64 63 байта

f=(1!)
c!t|t==c=[c]|t>c=c:(c+10^(pred.length.show.min c$t-c))!t

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

Спасибо Sriotchilism O'Zaic за -4 байта!

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

f 321
[1,2,3,4,5,6,7,8,9,10,20,30,40,50,60,70,80,90,100,200,300,310,320,321]

объяснение

c!t         -- c=current number, t=target number
 |t==c=[c]  -- Target is reached, return last number
 |t>c=c:(c+10^(pred.length.show.min c$t-c))!t
      c:                                        -- Add current number to list
                                min c$t-c       -- The minimum of the current number, and the difference between the current number and the target
                    length.show.                -- The length of this number
               pred.                            -- Minus 1
           10^(                          )      -- Raise 10 to this power
         c+                                     -- Add that to the current number
        (                                 )!t   -- Recursion

4
Добро пожаловать в PPCG! Хороший первый ответ.
Арно

2
Я не знаю Haskell, но, возможно, любой из этих советов может помочь: советы по игре в гольф на Haskell и советы по игре в гольф на <все языки> . Но я согласен, хороший ответ. +1 от меня.
Кевин Круйссен

2
Добро пожаловать на сайт! Поскольку (^)приоритет выше, чем в (+)скобках вокруг (^)выражения. То же самое касается (!)и(:)
Wheat Wizard

1
pred.length.show.min c$t-cможно сократить до length(show.min c$t-c)-1. Анонимные функции приемлемы, поэтому вы можете отказаться от лидирующих, f=как описано в нашем руководстве по правилам игры в гольф на Хаскеле .
Лайкони

1
Вместо охранников, вы можете использовать только один случай и условное: c!t=c: if t>c then (c+10^(length(show.min c$t-c)-1))!t else []. Это позволяет применить этот совет, чтобы сохранить еще несколько байтов: попробуйте онлайн!
Лайкони

6

JavaScript (ES6), 50 байт

f=n=>n?[...f(n-(1+/(^10)?(0*$)/.exec(n)[2])),n]:[]

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

Как?

теория

Следующие шаги повторяются до Nзнак равно0 :

  • искать число К конечных нулей в десятичном представлении n
  • уменьшать k если N является точной степенью 10
  • вычесть Иксзнак равно10К из N

Реализация

Значение Икс напрямую вычисляется как строка со следующим выражением:

+---- leading '1'
|
1 + /(^10)?(0*$)/.exec(n)[2]
     \____/\___/
        |    |
        |    +---- trailing zeros (the capturing group that is appended to the leading '1')
        +--------- discard one zero if n starts with '10'

'10'10Nзнак равно1000Nзнак равно102300'10'


Замечательно, что вы можете выполнять итерацию «назад», отслеживая только одну переменную! Это немного запутанное , что вы используете kчто - то совершенно иное , чем в описании вызова (на самом деле ваш nявляется сочетанием параметров порядка nи kи ваши xих i.)
Ørjan Йохансен


2

Perl 6 , 48 41 байт

->\k{1,{$_+10**min($_,k-$_).comb/10}...k}

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

Объяснение:

->\k{                                   }  # Anonymous code block taking k
     1,                             ...k   # Start a sequence from 1 to k
       {                           }       # Where each element is
        $_+          # The previous element plus
           10**      # 10 to the power of
                           .comb     # The length of
               min($_,k-$_)          # The min of the current count and the remainder
                                /10  # Minus one

2

APL (Dyalog Unicode) , 30 байтов SBCS

Функция анонимного молчаливого префикса. Печатает числа в отдельных строках на стандартный вывод.

{⍺=⍵:⍺⋄⍺∇⍵+10*⌊/⌊10⍟⍵,⍺-⎕←⍵}∘1

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

{}∘1N

⍺=⍵КN

  К

  еще:

  ⎕←⍵N

  ⍺-К

  ⍵,N

  10⍟журнал10

   пол тех

  ⌊/ минимум из тех

  10* десять возведены в силу этого

  ⍵+N

  ⍺∇КN


2

05AB1E , 15 байтов

1[=ÐIαD_#‚ßg<°+

Порт @PaulMutser (первый) Haskell ответ «s , поэтому убедитесь , что upvote его !!

Попробуйте онлайн или проверьте все контрольные примеры .

Выводит числа, разделенные символом новой строки.
Если это должен быть список, я должен добавить 3 байта:

X[DˆÐIαD_#‚ßg<°+}¯

Попробуйте онлайн или проверьте все контрольные примеры .

Объяснение:

1             # Push a 1 to the stack
 [            # Start an infinite loop
  =           #  Print the current number with trailing newline (without popping it)
  Ð           #  Triplicate the current number
   Iα         #  Get the absolute difference with the input
     D        #  Duplicate that absolute difference
      _       #  If this difference is 0:
       #      #   Stop the infinite loop
      ‚ß      #  Pair it with the current number, and pop and push the minimum
        g   #  Calculate 10 to the power of the length of the minimum minus 1
           +  #  And add it to the current number



1

Пакет, 131 байт

@set/an=i=1
:e
@if %n%==%i%0 set i=%i%0
@echo %n%
:c
@set/an+=i
@if %n% leq %1 goto e
@set/an-=i,i/=10
@if %i% neq 0 goto c

Принимает ввод в качестве параметра командной строки и выводит список чисел в STDOUT. Объяснение:

@set/an=i=1

Начните с n=1иi=1 представляющих силу 10.

:e
@if %n%==%i%0 set i=%i%0

Умножьте iна 10, если nдостиг следующей степени 10.

@echo %n%

Выведите текущее значение n.

:c
@set/an+=i
@if %n% leq %1 goto e

Повторите, пока iможно добавить nбез превышения ввода.

@set/an-=i,i/=10

Восстановите предыдущее значение nи разделите iна 10.

@if %i% neq 0 goto c

Если iне равно нулю , то попробуйте добавить iк nснова.


1

R , 67 65 байт

-2 байта благодаря Джузеппе

k=scan();o=1;i=10^(k:0);while(T<k)o=c(o,T<-T+i[i<=T&i+T<=k][1]);o

Довольно просто Требуется набор из 10 степеней сверх того, что было бы необходимо в обратном порядке.i .

(Я бы предпочел использовать i=10^rev(0:log10(k))вместо, i=10^(k:0)так как последний вычислительно неэффективен, но гольф это гольф!).

Затем в цикле while применяет условия iи принимает первое (т.е. наибольшее); обновляет nи добавляет к выводу

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


1
Сохраните байт, используя Tвместо n; должно быть 2, но я не думаю, что TRUEэто приемлемый результат k=1, поэтому мы установили o=+T. Попытайся!
Джузеппе

2
Это ужасное кодирование, мне это нравится. кстати, я могу установить o=1и получить второй байт.
Аарон Хейман


1

Пип , 27 байт

Wa>Po+:y/t*Y1Ty>o|o+y>ay*:t

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

В псевдокоде:

a = args[0]
o = 1
print o
while a > o {
  y = 1
  till y > o || o + y > a
    y *= 10
  o += y / 10
  print o
}

Я очень доволен уловками игры в гольф, которые я смог применить, чтобы сократить этот алгоритм. Благодаря инициализации, обновлению и печати содержимого в заголовке цикла я смог избежать использования фигурных скобок для тела цикла. Там, вероятно, алгоритм игры в гольф, хотя.


0

Japt , 18 байт

ÆT±ApTmTnU)sÊÉÃf§U

Попытайся

ÆT±ApTmTnU)sÊÉÃf§U     :Implicit input of integer U
Æ                      :Map the range [0,U)
 T±                    :  Increment T (initially 0) by
   A                   :  10
    p                  :  Raised to the power of
     Tm                :    The minimum of T and
       TnU             :      T subtracted from U
          )            :    End minimum
           s           :    Convert to string
            Ê          :    Length
             É         :    Subtract 1
              Ã        :End map
               f       :Filter
                §U     :  Less than or equal to U


Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.