Послідовність додавання-множення-додавання


27

( Споріднене )

Враховуючи ціле число n > 1,
1) Побудуйте діапазон чисел n, n-1, n-2, ... 3, 2, 1та обчисліть суму
2) Візьміть окремі цифри цього числа та обчисліть добуток
3) Візьміть окремі цифри цього числа та обчисліть суму
4) Повторіть кроки 2 та 3, поки ви не досягти однієї цифри. Ця цифра є результатом.

Перші двадцять членів послідовності наведені нижче:

3, 6, 0, 5, 2, 7, 9, 2, 7, 9, 1, 9, 0, 0, 9, 6, 7, 0, 0, 6

Примітка. Ця послідовність НЕ в OEIS.

I / O та правила

  • Числа швидко отримують дуже великі розміри, тому рішення повинно мати можливість обробляти вхідні цифри до 100 000 без збоїв (це добре, якщо ваш код може обробити минуле).
  • Введення та вихід можуть бути надані будь-яким зручним методом .
  • Прийнятна або повна програма, або функція. Якщо функція, ви можете повернути вихід, а не надрукувати його.
  • Стандартні лазівки заборонені.
  • Це тому діють усі звичайні правила гольфу, і найкоротший код (у байтах) виграє.

Приклади

n     output
1234   9
3005   3
5007   5
9854   8
75849  8
100000 0

3
+1 для виклику послідовності, якого немає в OEIS
JAD

2
Щоразу, коли n ≤ 100000 , для отримання результату достатньо лише двох ітерацій кроків 2 та 3. Чи можемо ми скористатися цим чи повинен алгоритм, який ми обираємо, працювати для більших значень n ?
Денніс

2
@Dennis Алгоритм повинен працювати для будь-якого значення n. Розміщене рішення має працювати лише до n = 100000.
AdmBorkBork

3
Numbers will get very large quicklyні, це не так
l4m2

3
@ l4m2 Не вихід. Але 100000 + 99999 + ... + 1 = 5000050000 - це 33-розрядне число, яке у вашій вибраній мові може мати проблеми з поданням.
Денніс

Відповіді:


10

Python 2 , 77 72 71 62 60 байт

lambda n:reduce(lambda x,c:eval(c.join(`x`)),'*+'*n,-n*~n/2)

Дякуємо @xnor за те, що ти граєш на 2 байти!

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


Я просто перейшов на цикл for, але мені доведеться запам'ятати цей трюк на майбутнє.
Денніс

Де repeat until you reach a single digit?
Тит

2
@Titus Я просто виконую n ітерацій кроків 2 і 3, що завжди достатньо. Насправді, оскільки n ≤ 100000 , трьох ітерацій було б достатньо.
Денніс

Тепер, коли ви це згадуєте: насправді, найменший внесок, який потребував би трьох ітерацій, - це 236172; і це лише менше 1 мільйона.
Тит



4

Желе , 8 байт

RSDPDƲÐL

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

Повна програма (вона повертає однотонний масив, що містить результат, але дужки не видно в STDOUT).


Це найбільш "природний" відповідь желе, яку я ще бачив. Є лише 2 символи, що не належать до ASCII,
RedClover


Ну, не можемо ми тут не обговорювати, дякую. : P ТНБ може стати альтернативним місцем для обговорення цього питання, якщо не буде шуму. ;)
Ерік Аутгольфер

4

MATL , 15 13 байт

У данину Мові місяця :

:`sV!UpV!Utnq

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

Я не думаю, що існує простіший спосіб отримати цифри числа, ніж перетворити число в рядок V, потім його перенести !і перетворити цей вертикальний вектор назад в числовий U.

Збережено 2 байти завдяки самому Творцю 1 ! Я забув неявний кінець, тобто я міг усунути] , і замість того, щоб порівнювати кількість елементів 1, я міг би просто зменшити це значення і безпосередньо використовувати його як булеве значення.

Отже, пояснення виглядає так:

                 % Grab input n implicitly
:                % Range from 1 ... n inclusive
 `               % Do ... while
  s               % sum the vector
   V!U            % Convert the number to digits
      p           % Take the product of these digits
       V!U        % Convert the product into digits
          t       % Duplicate the result
           n      % Count the number of elements
            q     % Decrement the number of elements
                  % Loop until the number of elements is 1
                 % Implicit end

1 ... з MATL, Луїс Мендо.


3

JavaScript (ES6), 60 байт

f=(n,k=n*++n/2)=>k>9?f(!n,eval([...k+''].join('*+'[+!n]))):k

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

Прокоментував

f = (                     // f = recursive function taking:
  n,                      //   n = original input
  k = n * ++n / 2         //   k = current value, initialized to sum(i=1..n)(i)
) =>                      //
  k > 9 ?                 // if k has more than 1 digit:
    f(                    //   recursive call to f() with:
      !n,                 //     a logical NOT applied to n
      eval(               //     the result of the expression built by:
        [...k + '']       //       turning k into a list of digits
        .join('*+'[+!n])  //       joining with '*' on even iterations or '+' on odd ones
      )                   //     end of eval()
    )                     //   end of recursive call
  :                       // else:
    k                     //   stop recursion and return the last value

Альтернативна версія, 59 байт (неконкурентна)

Нерекурсивна версія, яка працює лише для n <236172 . (Він охоплює запитуваний діапазон, але не кваліфікується як дійсний загальний алгоритм.)

n=>[...'*+*+'].map(o=>n=eval([...n+''].join(o)),n*=++n/2)|n

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


ваша основна версія розривається, коли N> = 77534568790. Вона працює, коли N = 7753456879; не впевнений, де саме знаходиться точка розриву. Звичайно, це не має значення, тому що вимога полягає лише в обробці до N = 100 000, тому я не впевнений, чому я написав це ....
Росс Прессер

1
@RossPresser Як приблизна оцінка, я б сказав, що це працює Number.MAX_SAFE_INTEGER ** 0.5 ~= 94906265.
Арнольд


2

Стакс , 14 13 10 байт

ñu┌↕a√äJ²┐

Запустіть і налагоджуйте його

Зробити це було досить весело. Цікаво, чи існує більш стислий спосіб зробити порівняння наприкінці.

Пояснення

|+wE:*E|+c9>                 # Full Program Unpacked
|+                           # Create range and sum it
   wE:*                      # Start loop, digitize number, product of digits
       E|+                   # Digitize number, sum digits
          c9>                # Duplicate, check length is = 1
                             # Otherwise loop back to the 'w' character

-1 байт завдяки ов

-3 байти завдяки Scrooble


2

R , 152 130 109 байт

function(w,x=w*(w+1)/2,y=prod(d(x)),z=sum(d(y)))"if"(z>9,f(,z),z)
d=function(x)x%/%10^(0:max(0,log10(x)))%%10

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

@Giuseppe знайшов 21 42 байт з різними R-речами, до яких я ще не звик, поряд із способом отримання цифр числа без примушування до рядка та назад та з меншою кількістю байтів!

# Old
d=function(x)strtoi(el(strsplit(paste(x),"")))
# New
d=function(x)x%/%10^(0:max(0,log10(x)))%%10

options(scipen=9) це потрібно для випадку 9854 для старої функції, тому що сцена першого продукту закінчується як 80000, який друкує R як 8e + 05.


А, бачу. Вихід наукової нотації. Гарний улов!
AdmBorkBork

1
Нарешті обійшов scipen: Спробуйте в Інтернеті ! Зауважте, що max(0,log10(x))це якщо x=0, то, log10(0)=-Infщо викликає помилку.
Джузеппе

1

Pyth , 11 байт

usj*FjGTTsS

Спробуйте тут!

usj * FjGTTsS - Повна програма. N = вхід.
          S - дальність. Вихід [1, N] ⋂ ℤ.
         s - сума.
u - Хоча жодна дві послідовні ітерації не дають однакового результату, виконайте (var: G):
   * FjGT - Цифровий продукт.
 sj T - Цифрова сума.

1

Вугілля деревне , 18 байт

≔Σ…·¹NθW›θ⁹≔ΣΠθθIθ

Спробуйте в Інтернеті! Посилання на багатослівну версію коду. Пояснення:

≔Σ…·¹Nθ

Підсумуйте цілі числа до введення.

 W›θ⁹≔ΣΠθθ

Хоча результат більший за 9, візьміть суму цифр добутку цифр.

Iθ

Відкиньте результат у рядок і неявно роздрукуйте його.


1

Гая , 8 байт

┅⟨Σ₸∨Π⟩°

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

Старе пояснення (перш ніж виправити помилку, яка є виною Гаї IMO: P):

┅⟨ΣΠ⟩ ° - Повна програма. N = вхід.
┅ - дальність. Натисніть [1, N] ⋂ ℤ до стеку.
 ⟨⟩ ° - Хоча жодна дві послідовні ітерації не дають однакового результату, виконайте такі дії:
  Σ - Сума (або цифрова сума, якщо вона застосовується до цілого числа).
   Π - Цифровий продукт.

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


┅⟨ΣΠ⟩°зберігає байт.
Денніс

Це не працює для значень. Цифрова сума дорівнює 0, наприклад4
Джо Кінг

@JoKing Виправлено, дякую, що помітили це. На жаль, у Геї чомусь беруть цифри 0результатів []:(
містер Xcoder

1

F #, 175 байт

let d n=seq{for i in(string n).ToCharArray() do yield string i|>uint64}
let c n=
 let mutable r=Seq.sum{1UL..n}
 while r>9UL do r<-d r|>Seq.reduce(fun a x->x*a)|>d|>Seq.sum
 r

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

Єдине застереження до функції полягає в тому, що вхідне значення повинно бути типу uint64.

Ungolfed це трохи так:

let d n=seq{for i in(string n).ToCharArray() do yield string i|>uint64}

let c n =
 let mutable r = Seq.sum {1UL..n}
 while r > 9UL do
  r<-d r
  |> Seq.reduce(fun a x->x*a)
  |> d
  |> Seq.sum
 r

Функція d nперетворює число nв цифри його компонентів. Спочатку він перетворюється на рядок, потім отримує кожен символ у рядку. Кожен символ повинен бути перетворений назад у рядок, інакше символи будуть перетворені на їх ASCII значення замість їх "реальних" значень.

c nФункція є основною функцією, з в nякості початкового значення. У цій функції r- наше робоче значення. whileЦикл виконує наступні дії :

  • Перетворити rв його складові цифри ( d r).
  • Отримайте добуток усіх цих цифр. При цьому використовується Seq.reduceфункція, яка приймає функцію із накопиченим значенням ( a) та наступним значенням у послідовності ( x), і в цьому випадку повертає продукт. Початкове значення - це перший елемент у послідовності.
  • Перетворіть це значення продукту в його цифри компонента ( d).
  • Підсумуйте цифри раніше, і призначте це r.

1

Befunge, 136 байт

101p&::*+2/>:82+%01g*01p82+/:#v_$01gv
X      v_v# #:/+82p10+g10%+82: <p100<
v:g10$ >#<#^                 #<^
>82+/#v_.@
      >101p^

Ви можете спробувати тут .

Хоча не всі перекладачі мають достатньо великий розмір комірок, він працює з невеликою кількістю для майже будь-кого там. Для більшої кількості nвам може знадобитися перекладач на зразок BefunExec .


1

Gol> <> , 35 33 байт

1AY:P*2,TYMR*YR+:a(?Bt
:a(qlBaSD$

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

-2 байти Джо Кінга.

Широке використання функцій та неявних нескінченних циклів.

Приклад повної програми та як вона працює

1AGIE;GN
2AY:P*2,YlMR*YlR+:a(?B8R!
:a(?BaSD$

<main program>
1AG       Register row 1 as function G
   IE;    Take number input; halt on EOF
      GN  Call G and print the result as number
          Repeat indefinitely

<function G>
2AY            Register row 2 as function Y
   :P*2,       Sum of 1 to n
        Y      Call Y (break into digits)
         lMR*  Product
Y              Call Y
 lR+           Sum (an implicit zero is used)
    :a(?B      Return if the result is less than 10
         8R!   Skip initial 8 commands
               Repeat indefinitely

<function Y>
:a(?B      Return if the top is less than 10
     aSD   Divmod by 10; [... n] => [... n/10 n%10]
        $  Swap top two, so the "div" goes to the top


1

Japt, 16 14 13 байт

_ì ×ìx}gN®õ x

Спробуй це


Пояснення

                  :Implicit input of integer U
         ®        :Map
        N         :The array of inputs (which just contains U)
          õ       :  Range [1,U]
            x     :  Reduce by addition
_     }g          :Take the last element of N, run it through the following function and push the result to N
                  : Repeat U times and then return the last element of N
 ì                :  Split to an array of digits
   ×              :  Reduce by multiplication
    ìx            :  Split to an array of digits and reduce by addition

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

Дякую, @Nit. Має бути, коротший шлях.
Кудлатий

@Nit, зрозумів! Все-таки переконаний, що має бути коротший шлях.
Кудлатий


0

PHP 7, 89 байт

for($a=$argn*-~+$argn/2;$a>9;)$a=array_sum(($s=str_split)(array_product($s($a))));echo$a;

Запустіть як трубу -rабо спробуйте в Інтернеті .

  • PHP завжди приймає введення як рядок, тому я повинен використовувати +для передачі int, ~щоб працювати так, як хотів.
  • Попередній приріст не спрацював: де б я не ставлю, це вплине на обидва операнди.
  • Але: не має значення, якщо одна цифра має місце до або після ітерації (додаткові ітерації нічого не змінить); тому я можу використовувати for()замість цього do ... while().
  • Для вбудованого призначення імені функції потрібен PHP 7 або новішої версії.
    Для більш старого PHP потрібен ще один байт: for($s=str_split,$a=...;$a>9;)$a=array_sum($s(...));
    (Якщо присвоєння str_splitзмінної взагалі не витратить ще один байт.)



0

PowerShell Core , 91 101 93 байт

Function F($a){$o=$a*($a+1)/2;1,2|%{$o=[char[]]"$([char[]]"$o"-join'*'|iex)"-join'+'|iex};$o}

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

Недоладжений трохи ...

Function F ($a)
{
    $o=$a*($a+1)/2;
    1..2 | % {
        $o = [char[]]"$o"-join '*' | iex;
        $o = [char[]]"$o"-join '+' | iex;
    }
    $o | Write-Output
}

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

iexпсевдонім, для Invoke-Commandякого оцінюється рядок, переданий у позицію першого параму.

Редагувати: За запитом @AdmBorkBork , я додав заголовок функції до кількості байтів. Крім того, я трохи зробив математику і зрозумів, що верхня межа кількості ітерацій є< log log 10^6 < log 6 < 2 це збереження ще шести байтів.

Редагувати x2: @AdmBorkBork знайшов більш короткий спосіб перетворення цілого числа в математичний вираз, а потім запропонував передати його iex. Це зберегло 8 байт. Дякую!


Приємно бачити ще один PowerSheller! Однак я думаю, що вам потрібно включити визначення функції Function F($a){ }у свій байт. Однак, ви повинні бути в змозі зберегти деякі, використовуючи [char[]]замість -split''-ne'', я думаю.
AdmBorkBork

[char[]]1234=Ӓ, що недійсне; Я, можливо, зможу змусити його працювати, але це не очевидно лише зараз. Дякую за пропозицію!
Джефф Фріман

Вибачте, що я не зрозумів - [char[]]"$o"і |iexшвидше iex( ).
AdmBorkBork

Ця порада збрила 8% мого коду. Дивовижно. Спасибі!
Джефф Фріман



0

Java 8, 129 байт

n->{long r=1,i=n;for(;i>1;r+=i--);for(;r>9;r=(i+"").chars().map(p->p-48).sum(),i=1)for(int s:(r+"").getBytes())i*=s-48;return r;}

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

Пояснення:

n->{            // Method with integer parameter and long return-type
  long r=1,     //  Result-long, starting at 1
       i=n;     //  Temp integer, starting at the input `n`
  for(;i>1;     //  Loop as long as `i` is not 1 yet
      r+=i--);  //   And increase `r` by `i`
  for(;r>9      //  Loop as long as `r` is not a single digit yet
      ;         //    After every iteration:
       r=(i+"").chars().map(p->p-48).sum(),
                //     Set `r` to the sum of digits of `i`
       i=1)     //     And reset `i` to 1
    for(int s:(r+"").getBytes())i*=s-48;
                //    Set `i` to the product of the digits of `r`
  return r;}    //  Return `r` as result

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