Понедельник Мини-гольф # 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 байт благодаря Денису

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

Это испытание похоже на то, что оно было сделано для функций сокращения Пита. Одно уменьшает цифры, другое уменьшает, пока значение не перестанет меняться, и мы в порядке.


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's', но также выводит его, поэтому я могу напечатать aи одновременно проверить, меньше ли оно, используя десять 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 с помощью Reduce, поэтому я хотел обойтись без него. Это должно быть вызвано с 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

Python, 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 которая печатает элементы последовательности в отдельных строках.

Ungolfed:

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)немного короче.
Деннис

@ Денис Отличные идеи, спасибо!
Алекс А.

1

Ruby 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 (для Джарвиса) - рекурсивная функция. r - список целых чисел результата.

протестировано в 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 () :)
Алекс Карлсен

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.