Складаються числа


23

Давайте визначимо функцію на натуральних числах , записаних у базі 10 цифр , таким чином:ndkdk1d1d0

Поки є рівні сусідні цифри , замініть їх на їх суму зліва направо. Якщо були такі цифри, повторіть ту саму процедуру.didi1di+di1

Іншими словами, в кожній ітерації ми жадібно беремо всі пари рівних суміжних цифр і замінюємо їх одночасно їх сумою (використовуючи саму ліву пару, якщо вони перетинаються).

Приклад

Візьмемо для прикладу :9988

  1. Першими сусідніми цифрами, які є рівними, є дві9
  2. Тому ми замінюємо їх на що дає нам9 + 9=181888
  3. Оскільки ми все ще перебуваємо в першій лівій правій стороні та ще було два s, нам потрібно спочатку замінити ці8
  4. Таким чином, ми отримуємо1816
  5. Щось змінилося, тому нам потрібно зробити ще одну ітерацію
  6. Але таких цифр немає, тому ми зупиняємось

Тому 9988th число в цій послідовності - 1816 .

Виклик

Перші 200 термінів:

0,1,2,3,4,5,6,7,8,9,10,2,12,13,14,15,16,17,18,19,20,21,4,23,24,25,26,27,28,29,30,31,32,6,34,35,36,37,38,39,40,41,42,43,8,45,46,47,48,49,50,51,52,53,54,10,56,57,58,59,60,61,62,63,64,65,12,67,68,69,70,71,72,73,74,75,76,14,78,79,80,81,82,83,84,85,86,87,16,89,90,91,92,93,94,95,96,97,98,18,10,101,102,103,104,105,106,107,108,109,20,21,4,23,24,25,26,27,28,29,120,121,14,123,124,125,126,127,128,129,130,131,132,16,134,135,136,137,138,139,140,141,142,143,18,145,146,147,148,149,150,151,152,153,154,20,156,157,158,159,160,161,162,163,164,165,4,167,168,169,170,171,172,173,174,175,176,24,178,179,180,181,182,183,184,185,186,187,26,189,190,191,192,193,194,195,196,197,198,28

Ваше завдання - генерувати таку послідовність

  • задано n , поверніть nth число у цій послідовності,
  • задано n , поверніть перші n чисел у цій послідовності
  • або генерувати послідовність безстроково.

Ви можете вибрати свою заявку, щоб використовувати або 0 або 1 індексинг, але вкажіть, який саме.

Тестові справи

Ви можете використовувати вищезазначені терміни, однак ось кілька великих:

222 -> 42
1633 -> 4
4488 -> 816
15519 -> 2019
19988 -> 2816
99999 -> 18189
119988 -> 21816
100001 -> 101
999999 -> 181818

Відповіді:




5

Желе , 11 байт

DŒg+2/€FVµ¡

Це надмірно повільна, повноцінна програма.

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

Альтернативна версія, 12 байт

DŒg+2/€FVµƬṪ

На один байт довше, але набагато швидше. Працює як програма або функція.

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

Як це працює

DŒg+2/€FVµƬṪ  Main link. Argument: n (integer)

         µ    Combine the previous links into a chain. Begin a new one.
D               Decimal; yield n's digit array in base 10.
 Œg             Group adjacent, identical digits into subarrays.
   +2/€         Map non-overlapping, pairwise sum over the subarrays.
                If there is an odd number of digits in a subarray, the
                last digit will remain untouched.
       F        Flatten; dump all sums and digits into a single array.
        V       Eval; turn the result into an integer.
          Ƭ   Execute the chain 'til the results are no longer unique.
              Return all unique results.
           Ṫ  Tail; extract the last result.

11-байтова версія робить те саме, за винятком того, що вона викликає посилання n разів для введення n , а не викликає її, поки не буде досягнуто фіксованої точки.


3
Це не зайве, якщо ви заощадите 1 байт :-)
Луїс Мендо

4

Haskell, 70 байт

until((==)=<<f)f
f(a:b:c)|a==b=show(2*read[a])++f c|1<2=a:f(b:c)
f a=a

Введення приймається як рядок.

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


Це нічого не економить поки що, але з однаковою довжиною ви можете замінити другий пункт |x<-b:c=a:f x або навіть f(a:c)=a:f c, на випадок, якщо одне чи інше насправді може призвести до поліпшення :)
помилка

4

JavaScript, 48 47 46 байт

Введення та вихід у вигляді рядків. Повертає додаток nthпослідовності.

f=s=>s-(s=s.replace(/(.)\1/g,x=>x/5.5))?f(s):s

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

  • 1 байт збережено завдяки Арнольду
  • 1 байт збережено завдяки tsh

1
x[0]*2->x/5.5
tsh

Спасибі, @tsh. Не подумав би про це.
Кудлатий

3

Perl 6 , 37 байт

{($_,{S:g[(\d)$0]=2*$0}...*==*)[*-1]}

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

Це функція, яка генерує n-й член послідовності, поданий n як його аргумент.

($_, { ... } ... * == *)- це послідовність послідовних змін до вхідного числа, породжених скороченим виразом (проста підстановка зворотного вираження) і зупинки, коли * == *, якщо два останні числа в послідовності рівні. Тоді [*-1]дістає лише кінцевий елемент цієї послідовності як зворотне значення.


Ви можете зберегти байти шляху видалення ==*і заміни *-1з $_, так як завжди менше , ніж nдля заміни ряду n. 33 байти
Jo King

3

Сітківка , 16 байт

+`(.)\1
$.(2*$1*

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

+`

Повторюйте, поки вхід не перестане змінюватися.

(.)\1

Замініть пари сусідніх цифр ...

$.(2*$1*

... з подвійною цифрою. ( $1*генерує рядок $1 _s, 2*дублює це і $.(бере довжину. Насправді двигун Retina розумніший за нього і просто подвоюється $1.)


3

C # (.NET Core) , 231 , 203 , 200 , 196 , 192 байт

EDIT: Функція зараз становить 185 байт плюс 18 для using System.Linq;

Завдяки BMO (що 1> 0 дорівнює істині плюс вилучення нового рядка) та містеру XCoder (для f =! F висловлювань)!

EDIT2: до 182 байт плюс 18 для using System.Linq подяку за день за обмін кількома порадами для гольфу!

EDIT3: Завдяки втіленню невігластва для int [] -> var, видалення короткого замикання && -> & і зміна ToArray -> ToList! (178 байт + 18 за допомогою)

EDIT4: Утілення Незнання скинуло 4 байти, змінивши призначення. Манекен мені слід рахувати! Ще раз дякую: D

p=>{var f=1>0;while(f){var t=p.Select(n=>n-48).ToList();p="";f=!f;for(var j=0;j<t.Count;j++){if(j<t.Count-1&t[j]==t[1+j]){p+=t[j]+t[++j];f=!f;continue;}p+=t[j];}};return p;};

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




2

Japt v2.0a0 -h, 15 14 байт

Повертає додаток nthпослідовності.

Æ=s_r/(.)\1/ÏÑ

Спробуй це

Це повинно працювати на 10 байт, але, мабуть, є помилка в рекурсивному методі заміни Japt.

e/(.)\1/ÏÑ


2

05AB1E , 11 байт

Δγε2ôSO}˜J

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

Пояснення:

Δ             # Continue until the (implicit) input no longer changes:
 γ            #  Split the integer in chunks of the same adjacent digits
              #   i.e. 199999889 → [1,99999,88,9]
  ε     }     #  Map each to:
   2ô         #   Split it into parts of size 2
              #    i.e. 99999 → [99,99,9]
     S       #   Split each part into digits
              #    i.e. [99,99,9] → [[9,9],[9,9],[9]]
       O      #   And take the sum of each part
              #    i.e. [[9,9],[9,9],[9]] → [18,18,9]
         ˜    #  Flatten the list
              #   i.e. [[1],[18,18,9],[16],[9]] → [1,18,18,9,16,9]
          J   #  Join everything together
              #   i.e. [1,18,18,9,16,9] → 118189169
              # (And output the result implicitly at the end)
              #  i.e. output = 28189169

2

Мова Вольфрама 108 байт

ToExpression[""<>ToString/@Total/@Flatten[Partition[#,UpTo@2]&/@Split@IntegerDigits@#,1]]&~FixedPoint~#&

Пояснення

IntegerDigits перетворює вхідне число у список його цифр.

Split групи послідовних повторних цифр.

Partition[#, UpTo@2]&/@ розбиває пробіли подібних цифр до списків довжиною не більше 2.

Flatten[...,1] виключає випадкові надмірно вкладені брекети - наприклад, {{2,2}} стає {2,2}

Total/@підсумовує парні цифри. Ізольовані цифри не потрібно підсумовувати.

ToString перетворює підсумки (та окремі цифри) у рядки.

""<> приєднується до всіх рядків у списку.

ToExpression перетворює результат у ціле число.

...~FixedPoint~#& застосовує функцію, поки результат не перестане змінюватися.


2

C # (Visual C # Interactive Compiler) з прапором /u:System.Text.RegularExpressions.Regex, 70 байт

s=>{for(;s[0]!=(s[0]=Replace(s[0],@"(.)\1",m=>m.Value[0]*2-96+"")););}

Виводи, змінюючи вхід. Входить у список, що містить один рядок для введення.

Дякуємо @dana за те, що займає цілі 23 байти!

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


95 + 34 - 33 + 1 для додаткового місця, необхідного для аргументів командного рядка, iirc
лише для ASCII

Рекурсивні анонімні функції повинні бути визначені спочатку, а визначення включене в число байтів.
Втілення Невідомості

О, це рекурсивно
лише ASCII

1
Приємно! Я думаю, що я можу це трохи зменшити
Втілення Невідомості

Це дуже хороший бал, враховуючи, що це C # :)
дата

1

Чистота , 118 байт

import StdEnv,Data.List
$[a,b:t]|a==b=[1,(a*2)rem 10]%(1-a/5,1)++ $t=[a: $[b:t]]
$l=l

limit o iterate$o map digitToInt

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

Бере перше повторне значення ( limit) з нескінченного списку застосувань ( iterate) лямбда, виконуючи один крок процесу згортання. Вхід, прийнятий як a [Char].


1

Червоний , 84 83 80 байт

func[n][if parse s: form n[to some change[copy d skip d](2 * do d)to end][f s]s]

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

Повертає nthпослідовності.

Пояснення:

Red[]
f: func [ n ] [
    if parse s: form n [  ; parse the input converted to a string
        to some change [  ; find and change one or more
            copy d skip   ; digit (in fact any character, no predefined character classes)
            d             ; followed by itself
        ] (2 * do d)      ; with its doubled numeric value 
        to end            ; go to the end of the string
    ] [ f s ]             ; call the function with the altered string if parse returned true
    s                     ; finally return the string 
]


1

C # (Visual C # Interactive Compiler) , 111 байт

s=>{var t=s;do{s=t;t="";for(int i=0;i<s.Length;)t+=s[i]%48*(s[i++]!=(s+0)[i]?1:2*++i/i);}while(t!=s);return t;}

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

ВЕЛИЧЕЗНА Кредит @ASCIIОдин лише для гольфу ~ 30;) Спочатку ми обидва розміщували оновлення одночасно, але в якийсь момент він явно поїхав у місто!

-2 завдяки @EmbodimentOfIgnorance!

Менше коду для гольфу ...

// s is the input as a string
s=>{
  // t is another string used
  // to hold intermediate results
  var t=s;
  // the algorithm repeatedly
  // processes s and saves the
  // result to t
  do{
    // copy the last result to s
    // and blank out t
    s=t;
    t="";
    // iterate over s
    for(int i=0;i<s.Length;)
      // append either 1 or 2 times
      // the current digit to t
      t+=s[i]%48*
        // compare the current digit
        // to the next digit. to prevent
        // an out-of-bounds exception,
        // append a 0 to s which either
        // gets ignored or collapses
        // to 0
        (s[i++]!=(s+0)[i]
          // if they are different, then
          // the multiplier is 1
          ?1
          // if they are the same, then
          // the multiplier is 2, and we
          // have to increment i
          :2*++i/i);
  }
  // continue this until the input
  // and output are the same
  while(t!=s);
  return t;
}



@ASCIIOnly - Хороший хід :) (s[i++]-48)*2=>s[i++]*2-96
Dana


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