Понеділок міні-гольф №4: JARVIS (просто ще один досить широкий набір цілих послідовностей)


22

Понеділок Міні-Гольф: Серія коротких питань із , розміщена (сподіваємось!) Кожного понеділка.
(Вибачте, що я запізнився знову; я вчора і сьогодні був далеко від свого комп’ютера.)

Нам програмістам (особливо кодерам-гольфістам) впевнені, що люблять довільні цілі послідовності. У нас навіть є цілий сайт, присвячений цим послідовностям, який наразі налічує близько 200 000 записів. У цьому виклику ми реалізуємо ще один набір цих послідовностей.

Виклик

Ваше завдання полягає в тому, щоб написати програму або функцію, яка займає ціле число N , і виводить послідовність базових 10 цілих чисел, де кожне наступне ціле число визначається таким чином:

  • Почніть з 1.
  • Для кожної цифри D у базі 10 представлення попереднього цілого числа:

    • Якщо D дорівнює 0, додайте його до поточного цілого числа.
    • В іншому випадку, необхідно помножити поточне число на D .

Деталі

  • Можна припустити, що 0 < N <2 31 .
  • Потрібно виводити кожне ціле число у послідовності, починаючи з вхідного числа, доки не буде досягнуто числа менше 10.
  • Вихідним може бути масив або рядок, розділений пробілами, комами, новими рядками або їх комбінацією.
  • Доступний пробіл та / або новий рядок, але не кінцева кома.
  • Ніколи не повинно бути жодних провідних нулів.

Приклади

Приклад 1: 77

Цей приклад досить простий:

77 = 1*7*7 = 49
49 = 1*4*9 = 36
36 = 1*3*6 = 18
18 = 1*1*8 = 8

Таким чином, правильний вихід є 77 49 36 18 8.

Приклад 2: 90

Тут ми маємо:

90 = 1*9+1 = 10
10 = 1*1+1 = 2

Тож вихід був би 90 10 2.

Приклад 3: 806

Прочитайте рівняння зліва направо:

806 = 1*8+1*6 = 54 (((1*8)+1)*6)
 54 = 1*5*4   = 20
 20 = 1*2+1   = 3

Вихід повинен бути 806 54 20 3.

Тестові кейси

Перше число у кожному рядку - це вхід, а повний рядок - очікуваний вихід.

77 49 36 18 8
90 10 2
249 72 14 4
806 54 20 3
1337 63 18 8
9999 6561 180 9
10000 5
8675309 45369 3240 25 10 2
9999999 4782969 217728 1568 240 9
1234567890 362881 2304 28 16 6

Для прикладу, ось наступні цілі цілі числа від 10 до 100:

Current | Next
--------+-----
     10 |  2
     11 |  1
     12 |  2
     13 |  3
     14 |  4
     15 |  5
     16 |  6
     17 |  7
     18 |  8
     19 |  9
     20 |  3
     21 |  2
     22 |  4
     23 |  6
     24 |  8
     25 | 10
     26 | 12
     27 | 14
     28 | 16
     29 | 18
     30 |  4
     31 |  3
     32 |  6
     33 |  9
     34 | 12
     35 | 15
     36 | 18
     37 | 21
     38 | 24
     39 | 27
     40 |  5
     41 |  4
     42 |  8
     43 | 12
     44 | 16
     45 | 20
     46 | 24
     47 | 28
     48 | 32
     49 | 36
     50 |  6
     51 |  5
     52 | 10
     53 | 15
     54 | 20
     55 | 25
     56 | 30
     57 | 35
     58 | 40
     59 | 45
     60 |  7
     61 |  6
     62 | 12
     63 | 18
     64 | 24
     65 | 30
     66 | 36
     67 | 42
     68 | 48
     69 | 54
     70 |  8
     71 |  7
     72 | 14
     73 | 21
     74 | 28
     75 | 35
     76 | 42
     77 | 49
     78 | 56
     79 | 63
     80 |  9
     81 |  8
     82 | 16
     83 | 24
     84 | 32
     85 | 40
     86 | 48
     87 | 56
     88 | 64
     89 | 72
     90 | 10
     91 |  9
     92 | 18
     93 | 27
     94 | 36
     95 | 45
     96 | 54
     97 | 63
     98 | 72
     99 | 81
    100 |  3

Ви можете знайти цей список розширений до 10000 тут .

Оцінка балів

Це , тому найкоротший дійсний код у байтах виграє. Tiebreaker переходить до подання, яке першим дійшло до остаточного підрахунку байтів. Переможець буде обраний наступного понеділка, 19 жовтня. Удачі!

Редагувати: Вітаю переможця @isaacg , використовуючи Pyth ще раз на 14 байт !

Відповіді:


10

Pyth, 15 14 байт

.uu|*GHhGjNT1Q

1 байт завдяки Деннісу

Тестовий сюїт

Ця проблема відчуває, як це було зроблено для зниження функцій Pyth. Одне зменшення над цифрами, одне зменшення, поки значення перестане змінюватися, і ми добре.


2
|*GHhGекономить байт ?H*GHhG.
Денніс

4

PowerShell, 92 91 90 88 87 байт

($n=$args);while($n-gt9){$x=1;[char[]]"$n"|%{$x=if($y=$_-48){$x*$y}else{$x+1}};($n=$x)}

1
Це досить гладко, використовуючи (...)для використання автоматичного виводу ... Мені потрібно буде це пам'ятати у майбутньому.
AdmBorkBork

3

Піп , 28 25 23 байти

Tt>Pa{Y1FdaYy*d|y+1a:y}

Приймає число як аргумент командного рядка і виводить послідовність у послідовних рядках.

Пояснення:

                         a is cmdline arg; t is 10 (implicit)
Tt>Pa{                }  Loop till a<10, printing it each time the test is made:
      Y1                   Yank 1 into variable y
        Fda                For each digit d in a:
           Yy*d|y+1          If y*d is truthy (nonzero), yank it; otherwise, yank y+1
                   a:y     Assign value of y back to a

Тепер я радий, що Pкілька разів тому перейшов з заяви на оператора. Paце вираз, який оцінює значення a', але також виводить його, тому я можу друкувати aта одночасно перевіряти, чи не менше 10 використовується t>Pa.


3

CJam, 26 25 24 22 байт

riA,{_pAb{_2$*@)?}*j}j

або

ri{_pAb{_2$*@)?}*_9>}g

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

Як це працює

Обидві програми по суті роблять те саме; перший - рекурсивний підхід, другий - ітеративний. Я поясню перше, що вважаю цікавішим.

ri                     Read an integer from STDIN and push it on the stack.
  A,{               }j Initialize a memoized, recursive function j with the array
                       [0 ... 9] as "base cases". If j is called on an integer
                       below 10, it returns the element at that index of the base
                       cases (which is same integer) and does not execute the code
                       block. The base case array is filled with new values as j is
                       called again and again, but we do not use this feature.
     _p                Copy and print the integer on the stack.
       Ab              Convert it into its base-10 digits.
         {       }*    Fold; push the first digit, for each remaining digit:
          _2$*         Multiply copies of the accumulator and the current digit.
              @)       Increment the original accumulator.
                ?      Select the product if the digit is non-zero, else the sum.
                   j   Call j on the result.
                       If the result was less than 10, it is retrieved from the
                       base cases and pushed on the stack. CJam prints it before
                       exiting the program.

2

Мінколанг 0,7 , 52 46 байт

ndN((d25*%1R25*:)r11(x2~gd4&x1+!*I1-)dNd9`,?).

Woohoo вкладені петлі!

Пояснення

ndN     Takes integer input and outputs it
(       Starts overall loop

 (        Starts loop that separates top of stack into digits
  d25*%   Modulus by 10
  1R      Rotates stack 1 unit to the right
  25*:    Divides by 10
 )

 r11   Reverses stack and pushes two 1s; 1 for the dump and 1 for the multiply
 (     Starts the multiply/add loop
  x    Dumps top value

      -This top-of-stack dump is because
       while loops end when the stack is
       empty or the top of stack is 0. The
       top of stack is *not* popped for
       this conditional check, so if the loop
       continues, I need to dump the left-over
       from the previous iteration.

  2~gd    Gets next-to-last stack value and duplicates for the conditional
  4&      Jumps 4 spaces if top of stack is positive
   x1+!   Dumps the 0 leftover, adds 1 to top of stack, and jumps the multiply
   *      Multiplies the top two elements of stack
  I1-     Pushes length of stack - 1
 )        Exits the loop if top of stack is 0 (i.e., len(stack)=1)
 dN       Outputs as integer
 d9`,?    Jumps out of the loop if top of stack <=9
)
.    Stop.


2

Python 3, 74, 76 байт

Тут вже була відповідь Python із зменшенням, тому я хотів зробити без нього. Його слід називати за допомогою int.

def j(n,m=1):
 print(n)
 if n>9:
  for d in str(n):m=m*int(d)or m+1
  j(m)

2

Пітон, 85 80 байт

def g(n):y=reduce(lambda i,x:i*int(x)or i+1,`n`,1);return[n]+(g(y)if n>9else[])

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


Ви можете зберегти два байти, використовуючи неназвану лямбда, тобто опустивши g=.
Олексій А.

1

К5 , 24 байти

(1{(x*y;x+1)@~y}/.:'$:)\

Збір списку елементів під час ітерації до фіксованої точки - саме те, що \робить оператор сканування . Під час кожної ітерації я спочатку додаю число до рядка, а потім оцінюю кожен символ ( .:'$:), розбиваючи число на його цифри. Потім я виконую скорочення (/ ), починаючи з 1 і використовуючи лямбда {(x*y;x+1)@~y}. У цьому випадку xє зменшувальним значенням і yє кожним наступним членом послідовності.

Дія:

  f: (1{(x*y;x+1)@~y}/.:'$:)\

  f'77 90 249 806 1337 9999 10000 8685309 9999999 1234567890
(77 49 36 18 8
 90 10 2
 249 72 14 4
 806 54 20 3
 1337 63 18 8
 9999 6561 180 9
 10000 5
 8685309 51849 1440 17 7
 9999999 4782969 217728 1568 240 9
 1234567890 362881 2304 28 16 6)

1

Джулія, 93 89 88 86 83 77 байт

f(n)=(println(n);if(d=n>9)for i=reverse(digits(n)) i<1?d+=1:d*=i end;f(d)end)

Це створює рекурсивну функцію, fяка друкує елементи послідовності на окремих рядках.

Безголівки:

function f(n::Int)
    println(n)
    if (d = n > 9)
        for i in reverse(digits(n))
            i < 1 ? d += 1 : d *= i
        end
        f(d)
    end
end

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

Збережено 6 байт завдяки Деннісу!


Слід n>9відповідати другому прикладу. Крім того, f(n)=(println(n);if(d=n>9)for i=reverse(digits(n)) i<1?d+=1:d*=i end;f(d)end)трохи коротше.
Денніс

@Dennis Чудові ідеї, дякую!
Олексій А.

1

Рубін 83 , 72 байти

Оригінал оголошено як функцію:

def f(d)loop{p d;break if d<10;d=d.to_s.bytes.inject(1){|r,i|i>48?r*(i-48):r+1}}end

Я намагався використовувати Enumerator.new але він використовує стільки байтів :-(

Поліпшено за допомогою рекурсії:

def f(d)p d;f(d.to_s.bytes.inject(1){|r,i|i>48?r*(i-48):r+1})if d>10 end

0

C # & LINQ, 165 146 байт

void j(int a){r.Add(a);var l=a.ToString().Select(d=>int.Parse(d.ToString()));int n=1;foreach(int i in l)n=i==0?n+1:n*i;if(n>9)j(n);else r.Add(n);}

j (для jarvis) - рекурсивна функція. r - Список int результату.

тестується в LINQPAD:

void Main()
{
    j(806);
    r.Dump();
}
List<int> r = new List<int>();

void j(int a){r.Add(a);var l=a.ToString().Select(d=>int.Parse(d.ToString()));int n=1;foreach(int i in l)n=i==0?n+1:n*i;if(n>9)j(n);else r.Add(n);}

Ви можете зберегти кілька байт, видаливши пробіли навколо операторів, наприклад, int n = 1можна int n=1тощо.
Алекс А.

Хороший улов @AlexA. зменшено до 146.
noisyass2

Ви також можете трохи заощадити, зробивши + "" замість a.tostring () :)
Alex Carlsen

0

Haskell, 71 байт

x!'0'=x+1
x!c=x*read[c]
g x|h>9=x:g h|1<2=[x,h]where h=foldl(!)1$show x

Використання: g 8675309-> [8675309,45369,3240,25,10,2].



0

Java 8, 148 байт

String f(int j){String s="";Function r=i->(""+i).chars().map(x->x-48).reduce(1,(x,y)->y>0?x*y:x+1);while((j=(int)r.apply(j))>9)s+=j+" ";return s+j;}

відформатовано

String f(int j) {
    String s = "";
    Function r = i -> ("" + i).chars().map(x -> x - 48).reduce(1, (x, y) -> y>0 ? x*y : x+1);
    while ((j = (int)r.apply(j)) > 9) s += j+" ";
    return s+j;
}

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