Codegolf - Сворачивающиеся Числа

  • Автор темы KUGE
  • Обновлено
  • 22, Oct 2024
  • #1

Определим функцию a для натуральных чисел \$n\$, записанных в виде десятизначного числа \$d_k\; d_{k-1}\; \точка\; д_1\; d_0\$, следующим образом:

Если соседние цифры \$d_i\;d_{i-1}\$ равны, замените их суммой \$d_i+d_{i-1}\$ слева направо. Если такие цифры были, повторите ту же процедуру.

Другими словами, на каждой итерации мы жадно берем все пары одинаковых соседних цифр и заменяем их суммой одновременно (используя самую левую пару, если они перекрываются).

Пример

Возьмем, к примеру, \$\texttt{9988}\$:

  1. Первые соседние цифры, которые равны, — это две \$\texttt{9}\$
  2. Поэтому мы заменяем их на \$\texttt{9 + 9} = \texttt{18}\$, что дает нам \$\texttt{1888}\$
  3. Поскольку мы все еще находимся на первом обходе слева направо и еще было два \$\texttt{8}\$s, нам нужно сначала заменить эти
  4. Итак, мы получаем \$\texttt{1816}\$
  5. Что-то изменилось, поэтому нам нужно сделать еще одну итерацию
  6. Но таких цифр нет, поэтому остановимся

Следовательно, число \$9988^\text{th}\$ в этой последовательности равно \$1816\$.

Испытание

Первые 200 терминов:

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

Ваша задача — сгенерировать эту последовательность, либо

  • учитывая \$n\$, верните число \$n^\text{th}\$ в этой последовательности,
  • учитывая \$n\$, верните первые числа \$n\$ в этой последовательности
  • или генерировать последовательность бесконечно.

Вы можете выбрать для своей отправки индексацию \$0\$- или \$1\$, но укажите, какую именно.

Тестовые случаи

Вы можете использовать приведенные выше термины, однако вот несколько более крупных:

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

#код-гольф #последовательность #целое число

KUGE


Рег
27 Jul, 2014

Тем
85

Постов
166

Баллов
611
  • 26, Oct 2024
  • #3

Питон 2, 97 96 93 байт

// 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; }

Попробуйте онлайн!


Версия без регулярного выражения:

Питон 2, 133 130 122 112 98 байт

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;}

Попробуйте онлайн!

 

Er82


Рег
24 May, 2014

Тем
71

Постов
198

Баллов
573
  • 26, Oct 2024
  • #4

Желе, 11 байт

s=>{var t=s while(t!=(t="(\\d)\\1".r.replaceAllIn(t,m=>s"$m"(0)*2-96+""),t)._2){} t}

Это неоправданно медленная, насыщенная программа.

Попробуйте онлайн!

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

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 ]

На один байт длиннее, но гораздо быстрее. Работает как программа или функция.

Попробуйте онлайн!

Как это работает

nth

11-байтовая версия делает то же самое, но вызывает ссылку н раз для ввода н, вместо того, чтобы вызывать его до тех пор, пока не будет достигнута фиксированная точка.

 

Fff123458


Рег
06 Feb, 2011

Тем
70

Постов
189

Баллов
559
  • 26, Oct 2024
  • #6

JavaScript, 48 47 46 байт

Ввод и вывод в виде строк. Возвращает [Char] term of the sequence.

iterate

Попробуйте онлайн

  • 1 байт сэкономлен благодаря Арно
  • 1 байт сэкономлен благодаря tsh
 

Adexu124


Рег
31 Jul, 2014

Тем
62

Постов
205

Баллов
555
  • 26, Oct 2024
  • #7

Перл 6, 37 байт

limit

Попробуйте онлайн!

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

limit o iterate$o map digitToInt is the sequence of successive changes to the input number, generated by the bracketed expression (a simple regex substitution) and stopping when import StdEnv,Data.List $[a,b:t]|a==b=[1,(a*2)rem 10]%(1-a/5,1)++ $t=[a: $[b:t]] $l=l , то есть когда два последних числа в последовательности равны. Тогда s=>{for(;s[0]!=(s[0]=Replace(s[0],@"(.)\1",m=>m.Value[0]*2-96+"")););} takes just the final element of that sequence as the return value.

 

Biatrejeniayj35796


Рег
25 Oct, 2024

Тем
71

Постов
195

Баллов
570
  • 26, Oct 2024
  • #8

сетчатка, 16 байт

/u:System.Text.RegularExpressions.Regex

Попробуйте онлайн! Ссылка включает тестовые примеры. Объяснение:

...~FixedPoint~#&

Повторяйте до тех пор, пока ввод не перестанет меняться.

ToExpression

Заменить пары соседних цифр...

""<>

... с удвоенной цифрой. ( ToString generates a string of Total/@ Flatten[...,1] s, Partition[#, UpTo@2]&/@ дублирует это, и Split takes the length. Actually, the Retina engine is cleverer than that and just doubles IntegerDigits .)

 

Margo2007


Рег
29 Aug, 2007

Тем
70

Постов
197

Баллов
567
  • 26, Oct 2024
  • #9

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

РЕДАКТИРОВАТЬ: функция теперь имеет размер 185 байт плюс 18 для ToExpression[""<>ToString/@Total/@Flatten[Partition[#,UpTo@2]&/@Split@IntegerDigits@#,1]]&~FixedPoint~#&

Спасибо BMO (за то, что 1>0 равно true плюс удаление новой строки) и Mr. XCoder (за операторы f=!f)!

EDIT2: до 182 байт плюс 18 для Δ # 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 thanks to dana for sharing a few golf tips!

EDIT3: Спасибо Embodiment of Ignorance за int[] -> var, устранение короткого замыкания && -> & и изменение ToArray -> ToList! (178 байт + 18 использований)

EDIT4: Воплощение незнания уменьшило 4 байта, изменив назначение. Дура, мне надо было посчитать! Еще раз спасибо :D

Δγε2ôSO}˜J

Попробуйте онлайн!

 

Makenmani


Рег
21 Mar, 2020

Тем
86

Постов
182

Баллов
672
  • 26, Oct 2024
  • #11

AnfettaBody


Рег
15 Jan, 2014

Тем
66

Постов
183

Баллов
523
  • 26, Oct 2024
  • #12

05AB1E, 11 байты

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;};

Попробуйте онлайн или проверить все тестовые случаи.

Объяснение:

using System.Linq ||answer||

Язык Wolfram 108 байт

using System.Linq;

Объяснение

$1 transforms the input number into a list of its digits.

$.( groups consecutive repeated digits.

2* breaks runs of like digits into lists of, at most, lengths of 2.

_ eliminates occasional overly-nested braces--e.g., {{2,2}} becomes {2,2}

$1 sums totals of paired digits. Isolated digits need not be summed.

$1* converts the totals (and isolated digits) to strings.

$.(2*$1* joins all the strings in the list.

(.)\1 converts the outcome to an integer.

+` applies the function until the result ceases to change.

 

IJohnNasonewt44


Рег
07 Mar, 2009

Тем
83

Постов
187

Баллов
642
  • 26, Oct 2024
  • #14

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

* == * ($_, { ... } ... * == *)

Попробуйте онлайн!

Принимает первое повторяющееся значение ( {($_,{S:g[(\d)$0]=2*$0}...*==*)[*-1]} ) from the infinite list of applications ( f=s=>s-(s=s.replace(/(.)\1/g,x=>x/5.5))?f(s):s ) лямбды, выполняющей один шаг процесса сжатия. Ввод принимается как nth .

 

Proka1


Рег
16 Jan, 2010

Тем
58

Постов
196

Баллов
536
  • 26, Oct 2024
  • #15

Красный, 84 83 80 байт

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

Попробуйте онлайн!

Возвращает 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. term of the sequence.

Объяснение:

DŒg+2/€FVµƬṪ ||answer||

Скала, 84 байта

DŒg+2/€FVµ¡

Попробуйте онлайн!

 

Huyu890


Рег
24 Nov, 2009

Тем
81

Постов
194

Баллов
619
  • 26, Oct 2024
  • #16

C# (интерактивный компилятор Visual C#), 111 байт

def f(n): r='';s=n while s:a=1+(s[0]==s[1:2]);r+=`int(s[0])*a`;s=s[a:] return r!=n and f(r)or r

Попробуйте онлайн!

ОГРОМНАЯ благодарность @ASCIIOnly за игру в гольф ~30 ;) Сначала мы оба публиковали обновления одновременно, но в какой-то момент он явно уехал в город!

-2 спасибо @EmbodimentOfIgnorance!

Меньше гольф-кода...

def f(n):r=re.sub(r'(.)\1',lambda m:`int(m.group(1))*2`,n);return r!=n and f(r)or r import re ||answer||

Шелуха, 15 байт

def t(z):j=z and(z[0]==z[1:2])+1;return[str(int(z[0])*j),*t(z[j:])]if j else'' def c(n):r="".join(t(n));return r!=n and c(r)or r

Попробуйте онлайн!

 

SashaMalikov


Рег
02 Nov, 2008

Тем
75

Постов
195

Баллов
580
Тем
403,760
Комментарии
400,028
Опыт
2,418,908

Интересно