Números em colapso


23

Vamos definir a função a nos números naturais , escritos como base 10 dígitos , da seguinte maneira:ndkdk1d1d0

Contanto que haja dígitos adjacentes iguais , substitua-os pela soma da esquerda para a direita. Se houver esses dígitos, repita o mesmo procedimento.didi1di+di1

Em outras palavras, em cada iteração, tomamos avidamente todos os pares de dígitos adjacentes iguais e os substituímos por sua soma ao mesmo tempo (usando o par mais à esquerda, se eles se sobrepõem).

Exemplo

Vamos considerar por exemplo:9988

  1. Os primeiros dígitos adjacentes iguais são os dois9
  2. Então, nós os substituímos por que nos dá9 + 9=181888
  3. Como ainda estamos no primeiro percurso da esquerda para a direita e ainda havia dois s, precisamos primeiro substituí-los8
  4. Então obtemos1816
  5. Algo mudou, então precisamos fazer outra iteração
  6. Mas como não existem esses dígitos, paramos

Portanto, o número nessa sequência é .9988th1816

Desafio

Os primeiros 200 termos são:

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

Sua tarefa é gerar essa sequência, seja

  • dado , retorne o número nessa sequência,nnth
  • dado , retorne os primeiros números nessa sequênciann
  • ou gere a sequência indefinidamente.

Você pode escolher seu envio para usar indexação ou , mas especifique qual.01

Casos de teste

Você pode usar os termos acima, mas aqui estão alguns maiores:

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

Respostas:



5

Python 2 , 97 96 93 bytes

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

Experimente online!


Versão não regex:

Python 2 , 133 130 122 112 98 bytes

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

Experimente online!


5

Gelatina , 11 bytes

DŒg+2/€FVµ¡

Este é um programa desnecessariamente lento e completo.

Experimente online!

Versão alternativa, 12 bytes

DŒg+2/€FVµƬṪ

Um byte a mais, mas muito mais rápido. Funciona como um programa ou uma função.

Experimente online!

Como funciona

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.

A versão de 11 bytes faz o mesmo, exceto que chama o link n vezes para a entrada n , em vez de chamá-lo até que um ponto fixo seja alcançado.


3
Não é desnecessário se ele salva 1 byte :-)
Luis Mendo

4

Haskell, 70 bytes

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

A entrada é tomada como uma sequência.

Experimente online!


Não poupa nada até agora, mas com o mesmo comprimento você pode substituir a segunda cláusula por |x<-b:c=a:f xou mesmo f(a:c)=a:f c, caso uma ou outra possa realmente levar a uma melhoria :)
flawr 02/01

4

JavaScript, 48 47 46 bytes

Entrada e saída como seqüências de caracteres. Retorna o nthtermo da sequência.

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

Experimente online

  • 1 byte economizado graças a Arnauld
  • 1 byte salvo graças a tsh

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

Obrigado, @tsh. Não teria pensado nisso.
Shaggy

3

Perl 6 , 37 bytes

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

Experimente online!

Esta é uma função que gera o enésimo termo da sequência, dado n como argumento.

($_, { ... } ... * == *)é a sequência de alterações sucessivas no número de entrada, gerada pela expressão entre colchetes (uma simples substituição de regex) e interrompida quando * == *, ou seja, quando os dois últimos números na sequência são iguais. Em seguida, [*-1]assume apenas o elemento final dessa sequência como o valor de retorno.


Você pode salvar bytes removendo ==*e substituindo *-1por $_, pois sempre há menos que nsubstituições para um número n. 33 bytes
Jo King

3

Retina , 16 bytes

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

Experimente online! O link inclui casos de teste. Explicação:

+`

Repita até que a entrada pare de mudar.

(.)\1

Substitua pares de dígitos adjacentes ...

$.(2*$1*

... com o dobro do dígito. ( $1*gera uma sequência de $1 _s, 2*duplica isso e $.(leva o comprimento. Na verdade, o mecanismo Retina é mais inteligente que isso e apenas dobra $1.)


3

C # (.NET Core) , 231 , 203 , 200 , 196 , 192 bytes

EDIT: A função está agora em 185 bytes mais 18 para using System.Linq;

Obrigado ao BMO (pois 1> 0 é igual a true mais remoção de nova linha) e ao Sr. XCoder (pelas declarações f =! F)!

EDIT2: até 182 bytes mais 18, using System.Linqgraças à dana por compartilhar algumas dicas de golfe!

EDIT3: Agradecimentos à Modalidade de Ignorância pelo int [] -> var, remoção de curto-circuito && -> & e alteração do ToArray -> ToList! (178 bytes + 18 usando)

EDIT4: Modalidade de ignorância caiu 4 bytes alterando uma atribuição. Dummy me deveria contar! Mais uma vez obrigado: 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;};

Experimente online!




2

Japt v2.0a0 -h, 15 14 bytes

Retorna o nthtermo da sequência.

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

Tente

Isso deve funcionar para 10 bytes, mas parece haver um erro no método de substituição recursiva do Japt.

e/(.)\1/ÏÑ


2

05AB1E , 11 bytes

Δγε2ôSO}˜J

Experimente online ou verifique todos os casos de teste .

Explicação:

Δ             # 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

Wolfram Language 108 bytes

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

Explicação

IntegerDigits transforma o número de entrada em uma lista de seus dígitos.

Split agrupa dígitos repetidos consecutivos.

Partition[#, UpTo@2]&/@ divide execuções de dígitos semelhantes em listas de, no máximo, comprimentos de 2.

Flatten[...,1] elimina chaves ocasionais demais aninhadas - por exemplo, {{2,2}} se torna {2,2}

Total/@soma totais de dígitos emparelhados. Dígitos isolados não precisam ser somados.

ToString converte os totais (e dígitos isolados) em seqüências de caracteres.

""<> junta todas as seqüências de caracteres na lista.

ToExpression converte o resultado em um número inteiro.

...~FixedPoint~#& aplica a função até o resultado deixar de ser alterado.


2

C # (compilador interativo do Visual C #) com sinalizador /u:System.Text.RegularExpressions.Regex, 70 bytes

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

Saídas modificando a entrada. Recebe uma lista contendo uma sequência de caracteres para entrada.

Obrigado a @dana por jogar um total de 23 bytes!

Experimente online!


95 + 34 - 33 + 1 para o espaço extra necessário na linha de comando args, iirc
somente ASCII

Funções anônimas recursivas devem ser definidas primeiro, e a definição está incluída na contagem de bytes.
Realização da ignorância

Ah, é recursivo
somente ASCII

1
Agradável! Eu acho que posso diminuir um pouco mais
Modalidade de Ignorância

Essa é uma pontuação muito boa, considerando que é C # :)
dana

1

Limpo , 118 bytes

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

Experimente online!

Obtém o primeiro valor repetido ( limit) da lista infinita de aplicativos ( iterate) de um lambda executando uma única etapa do processo de recolhimento. Entrada tomada como a [Char].


1

Vermelho , 84 83 80 bytes

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

Experimente online!

Retorna o nthtermo da sequência.

Explicação:

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 # (compilador interativo do Visual C #) , 111 bytes

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

Experimente online!

MUITO crédito a @ASCIIOnly pelo golfe ~ 30;) No começo, nós dois estávamos postando atualizações simultaneamente, mas em algum momento ele claramente foi à cidade!

-2 graças a @EmbodimentOfIgnorance!

Menos código de golfe ...

// 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 - Good move :) (s[i++]-48)*2=>s[i++]*2-96
dana


Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.