Розширення та контракт


19

Візьміть додаткове ціле k як вхідне. Почніть з n:=1 і багаторазово збільшуйте n на найбільшу цілу потужність десять i таку, що in та i+nk .

Повторюйте, поки n=k і поверніть список усіх проміжних значень n , включаючи початковий 1 і кінцевий k .

Під час цього процесу зростання спочатку буде обмежено першою нерівністю, а лише згодом другою; зростання буде мати форму початкового періоду "розширення", протягом якого n збільшується все більшими повноваженнями, а потім "контрактним" періодом, протягом якого n збільшується все меншими повноваженнями з метою "збільшення" на правильну кількість.

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

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

Спробуйте в Інтернеті!

Дякую сріотчілізму 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
Ласкаво просимо на сайт! Оскільки (^)пріоритет вищий, ніж (+)круглі дуги навколо (^)виразу не потрібні . Те саме стосується (!)і(:)
Пшеничний майстер

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 :

  • шукати число k кінцевих нулів у десятковому поданні n
  • декремент k якщо n - точна потужність 10
  • відняти x=10k від n

Впровадження

Значення x безпосередньо обчислюється як рядок із наступним виразом:

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

Функція анонімного негласного префікса. Друкує числа на окремих рядках до stdout.

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

Спробуйте в Інтернеті!

{}∘1n

⍺=⍵kn

  k

  ще:

  ⎕←⍵n

  ⍺-k

  ⍵,n

  10⍟log10

   пол ті

  ⌊/ мінімум таких

  10* десять підняли до сили того

  ⍵+n

  ⍺∇kn


2

05AB1E , 15 байт

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

Порт @PaulMutser (перший) Хаскелл відповідь , так що не забудьте підтримати його !!

Спробуйте в Інтернеті або перевірте всі тестові випадки .

Виводить нові рядки з обмеженим числом.
Якщо це повинен бути список, я повинен був додати 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)оскільки останнє обчислювально малоефективне, але гольф - це гольф!).

Потім через певний час, застосовує умови до 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.