Persistência aditiva


20

O código mais curto para passar todas as possibilidades vence.

Em matemática, a persistência de um número mede quantas vezes uma determinada operação deve ser aplicada aos seus dígitos até que certa condição fixa seja atingida. Você pode determinar a persistência aditiva de um número inteiro positivo adicionando os dígitos do número inteiro e repetindo. Você continuaria adicionando os dígitos da soma até encontrar um número de dígito único. O número de repetições necessárias para alcançar esse número de um dígito é a persistência aditiva desse número.

Exemplo usando 84523:

84523
8 + 4 + 5 + 2 + 3 = 22
2 + 2 = 4

It took two repetitions to find the single digit number.
So the additive persistence of 84523 is 2.

Você receberá uma sequência de números inteiros positivos dos quais precisa calcular a persistência aditiva. Cada linha conterá um número inteiro diferente para processar. A entrada pode estar em qualquer método de E / S padrão .

Para cada número inteiro, você deve gerar o número inteiro, seguido por um único espaço, seguido por sua persistência aditiva. Cada número inteiro processado deve estar em sua própria linha.

Casos de teste


Saída de Entrada

99999999999 3
10 1
8 0
19999999999999999999999 4
6234 2
74621 2
39 2
2677889 3
0 0

1
Seus casos de teste incluem alguns valores acima de 2 ^ 64, e sua especificação diz que o programa só precisa manipular valores de até 2 ^ 32. Pode valer a pena esclarecer isso.
Peter Taylor

@ Peter Taylor, esqueceu de remover esses limites. Se um programa puder lidar com a entrada que forneci, não deverá ter problemas com limites.
Kevin Brown

5
A persistência de 999999999999 não é 2 em vez de 3?
Eelvex 26/03

@ Evelex, essa foi uma alteração incorreta de última hora, eu acho. Fixo.
Kevin Brown

Várias respostas aqui não estão produzindo saída no stdout, mas usam a saída "interativa" de J retornando resultados após receber a entrada da linha de comando. (Isso inclui 2 outras respostas J e, suponho, a resposta K.) Isso é considerado legítimo? Porque eu posso lançar caracteres de 18 anos, se sim.
precisa

Respostas:


6

K - 29 caracteres

Input é um nome de arquivo passado como argumento, 29 caracteres, incluindo o nome do arquivo.

`0:{5:x,-1+#(+/10_vs)\x}'.:'0:"file"
  • 35 -> 31: Remova a função externa.
  • 31 -> 29: Remover parênteses.

1
-1+#=>#1_
streetster

4

Python 84 Chars

while 1:
 m=n=int(raw_input());c=0
 while n>9:c+=1;n=sum(map(int,str(n)))
 print m,c

Caso de desafio: 06234.. resultado um desafio bem sucedido :-)
Quixotic 26/03

@Debanjan Thanks. Corrigido.
FR0DDY 26/03


4

Python (93 bytes)

f=lambda n,c:n>9and f(sum(map(int,str(n))),c+1)or c
while 1:n=int(raw_input());print n,f(n,0)

eu acho que você pode remover o espaço entre 9e err ...and
st0le

@ st0le: Thanks :-)
Quixotic

e em input()vez de int(raw_input())...
st0le 28/03

@ st0le: Tente esta entrada com essa modificação: 06234.
Quixotic,

4

Casca , 10 15 bytes

+5 bytes para requisitos de E / S horríveis

m(wΓ·,LU¡oΣdr)¶

Experimente online!

Explicação

Para suportar várias entradas, precisamos usar m(₁r)¶(onde está a função que faz o cálculo interessante):

m(₁r)¶  -- expects newline-separated inputs: "x₁␤x₂␤…␤xₙ"
     ¶  -- split on newlines: ["x₁","x₂",…,"xₙ"]
m(  )   -- map over each string
 ( r)   -- | read integer: [x₁,x₂,…,xₙ]
 (₁ )   -- | apply the function described below

A função faz o seguinte:

wΓ·,LU¡(Σd)  -- input is an integer, eg: 1234
      ¡(  )  -- iterate the following forever and collect results in list:
       ( d)  -- | digits: [1,2,3,4]
       (Σ )  -- | sum: 10
             -- : [1234,10,1,1,1,…
     U       -- keep longest prefix until repetition: [1234,10,1]
 Γ           -- pattern match (x = first element (1234), xs = tail ([10,1])) with:
  · L        -- | length of xs: 2
   ,         -- | construct tuple: (1234,2)
w            -- join with space: "1234 2"

3

bash, 105 caracteres

while read x
do
for((i=0,z=x;x>9;i++))do
for((y=0;x>0;y+=x%10,x/=10))do :
done
x=$y
done
echo $z $i
done

Quase nenhum golfe realmente envolveu, mas não vejo como melhorá-lo.


3

Haskell - 114

s t n|n>9=s(t+1)$sum$map(read.(:[]))$show n|1>0=show t
f n=show n++" "++s 0n++"\n"
main=interact$(f.read=<<).lines

Você pode salvar 4 bytes usando puremais (:[])e definindo um operador em vez de s, experimentá-lo online!
ბიმო

3

Rubi, 85 caracteres

puts $<.map{|n|v=n.chop!;c=0;[c+=1,n="#{n.sum-n.size*48}"] while n[1];[v,c]*' '}*"\n"

Eu tive que pegar emprestada a idéia do "sum-size * 48" de Alex, porque é muito legal para perder (pelo menos em Ruby).


3

Golfscript, 40 caracteres

n%{.:${;${48-}%{+}*`:$,}%.,1>\1?+' '\n}%

3

J - 45 caracteres

Lê a partir de stdin

(,' ',[:":@<:@#+/&.:("."0)^:a:)&><;._2(1!:1)3

Eu estava tentando ^:a:me usar, mas não consegui encontrar a documentação adequada ... alguma dica?
Eelvex 26/03

1
A entrada do dicionário para u ^: n tem informações sobre o seu uso, mas é um pouco densa. ^: a: é como qualquer outra chamada ao poder, mas coleta os resultados e termina quando o argumento para chamadas consecutivas é o mesmo (converge).
Isawdrones

1
@Eelvex FWIW eu descobri a:através do ^:a:truque no J Reference Card [PDF]
JB

@JB: Essa é a única referência ^:a:que eu sabia: D
Eelvex 27/03

@Eelvex Oh. Eu tive a experiência oposta então. Descobri a funcionalidade no dicionário e a usei como uma variante ^:(<'')inicialmente (provavelmente para Kaprekar), até que a vi no cartão e aprendi sobre a:a ocasião.
JB

3

c - 519

(ou 137, se você me creditar pela estrutura ...)

Em vez de resolver apenas essa operação, decidi produzir uma estrutura para resolver todos os problemas de persistência .

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef char*(*O)(char*);
char*b(char*s){long long int v=0,i,l=0;char*t=0;l=strlen(s);t=malloc(l+2);
for(i=0;i<l;i++)v+=s[i]-'0';snprintf(t,l+2,"%lld",v);return t;}
int a(char**s,O o){int r;char*n;n=o(*s);r=!strcmp(*s,n);free(*s);
*s=n;return r;}
int main(int c, char**v){size_t l, m=0;char *d,*n=0;O o=b;FILE*f=stdin;
while(((l=getline(&n,&m,f))>1)&&!feof(f)){int i=0;n=strsep(&n,"\n");
d=strdup(n);while(!a(&n,o))i++;printf("%s %d\n",d,i);free(d);free(n);n=0;m=0;}}

Somente as duas linhas a partir de char*bsão exclusivas para esse problema.

Ele trata a entrada como strings, o que significa que os "0" iniciais não são strip antes do estágio de saída.

O item acima teve comentários, verificação e relatório de erros e leitura de arquivos (a entrada deve vir da entrada padrão) dividida em:

/* persistence.c
 *
 * A general framework for finding the "persistence" of input strings
 * on opperations.
 *
 * Persistence is defined as the number of times we must apply
 *
 *    value_n+1 <-- Opperation(value_n)
 *
 * before we first reach a fixed point.
 */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "../getline.h"

/* A function pointer type for operations */
typedef char*(op_func)(char*);
typedef op_func* op_ptr;
/* Op functions must
 * + Accept the signature above
 * + return a point to a newly allocated buffer containing the updated str
 */

char* addop(char*s){
  int i,l=0;
  long long int v=0;
  char *t=NULL;
  /* protect against bad input */
  if (NULL==s) return s;
  /* allocate the new buffer */
  l = strlen(s);
  t = malloc(l+2);
  if (NULL==t) return t;
  /* walk the characters of the original adding as we go */
  for (i=0; i<l; i++) v += s[i]-'0';
  //fprintf(stderr,"   '%s' (%d) yields %lld\n",s,l,v);
  snprintf(t,l+2,"%lld",v);
  //fprintf(stderr,"   %lld is converted to '%s'\n",v,t);
  return t;
}

/* Apply op(str), return true if the argument is a fixed point fo
 * falsse otherwise,
 */ 
int apply(char**str, op_ptr op){ 
  int r;
  char*nstr;
  /* protect against bad input */
  if ( NULL==op ) exit(1); 
  if ( NULL==*str ) exit(4); 
  /* apply */
  nstr = op(*str); 
  /* test for bad output */
  if ( NULL==nstr ) exit(2); 
  r = !strcmp(*str,nstr); 
  /* free previous buffer, and reasign the new one */
  free(*str); 
  *str = nstr; 
  return r; 
}

int main(int argc, char**argv){
  size_t len, llen=0;
  char *c,*line=NULL;
  op_ptr op=addop;
  FILE *f=stdin;
  if (argc > 1) f = fopen(argv[1],"r");
  while( ((len=getline(&line,&llen,f))>1) && line!=NULL && !feof(f) ){
    int i=0;
    line=strsep(&line,"\n"); // Strip the ending newline
    /* keep a copy for later */
    c = strdup(line);
    /* count necessary applications */
    while(!apply(&line,op)) i++;
    printf("%s %d\n",c,i);
    /* memory management */
    free(c);
    free(line);
    line=NULL;
    llen=0;
  }
}

Um pouco mais poderia ser salvo se estivéssemos dispostos a vazar memória como uma peneira. Da mesma forma, com #defineretorno e coisas do gênero, mas neste momento não me importo de torná-lo mais feio.



2

J, 74 caracteres

i=:<;._2(1!:1)3
i&((],' ',":@(0 i.~9<[:".([:":[:+/"."0)^:(i.9)))@>@{~)i.#i

Edições

  • (86 → 83) Alguns caps[: para Ats@
  • (83 → 79) Parênteses desnecessários
  • (79 → 75) Alterando0". para ".simplificar as coisas
  • (75 → 74) Melhor corte

Por exemplo

i=:<;._2(1!:1)3
74621
39
2677889
0
i&((],' ',":@(0 i.~9<[:".([:":[:+/"."0)^:(i.9)))@>@{~)i.#i
74621 2  
39 2     
2677889 3
0 0  

A saída está formatada incorretamente para várias entradas. Veja "espaço único"
Jesse Millikan 27/03

@ Jessé: não vejo nada de errado. Você poderia escrever um exemplo, por favor?
Eelvex 27/03

Não faço ideia, estou vendo coisas que acho.
precisa

1

Eu acho que isso é o melhor que posso encontrar.

Ruby 101 Chars

f=->(n){n.sum-n.size*48}
$<.each{|l|i=0;i+=1 while(i+=1;n=f[(n||l.chop!).to_s])>10
puts "#{l} #{i}"}

Na verdade, pique! em vez de chomp! me dá uma economia de um personagem. 97 caracteres.
precisa

Acabei de jogar mais golfe - 91 caracteres.
precisa

1

Pari / GP 101 Chars

s(n)=r=0;while(n>0,r+=n%10;n\=10);r
f(n)=c=0;while(n>9,c++;n=s(n));c
while(n=input(),print(n," ",f(n)))

Infelizmente, não há função de entrada para o GP, então acho que falta a parte IO. :( Corrigido: Obrigado Eelvex! :)


Claro que existe: input():)
Eelvex 26/03

@Eelvex, pronto. :)
st0le

1

Javascript - 95

i=prompt();while(i>9){i=''+i;t=0;for(j=0;j<i.length;j++)t+=parseInt(i.charAt(j));i=t;}alert(t);

EDIT: Whoops não faz as multi-linhas


1
Só notei que isso não é gerado corretamente.
Kevin Brown

1

J, 78

f=:[:+/"."0&":
r=:>:@$:@f`0:@.(=f)
(4(1!:2)~LF,~[:":@([,r)".@,&'x');._2(1!:1)3

Solução recursiva. Lê de stdin. Escreve para stdout , então me dê uma folga - são necessários 18 caracteres extras.


1

Perl - 77 caracteres

sub'_{split//,shift;@_<2?0:1+_(eval join'+',@_)}chop,print$_,$",(_$_),$/for<>

1

JavaScript , 57 47 bytes

-10 bytes graças a @ l4m2!

f=(s,c=0)=>s>9?f(eval([...s+""].join`+`),++c):c

Experimente online!


f=(s,c=0)=>s>9?f([...s+""].reduce((x,y)=>x*1+y*1),++c):c
L4m2

f=(s,c=0)=>s>9?f([...s+""].reduce((x,y)=>x- -y),++c):c
L4m2 5/05

1
f=(s,c=0)=>s>9?f(eval([...s+""].join`+`)),++c):c
L4m2 5/05

@ l4m2 Obrigado! s>9e evalforam ótimas idéias. Eu acho que você tinha um parênteses extra lá, totalizando 10 bytes que você me salvou :-) #
Oliver Oliver

Observe a estrita E / S;) #
Shaggy

1

05AB1E , 13 bytes

ε.µΔSO¼}¾}<ø»

Insira como uma lista de números inteiros.

Experimente online.

Explicação:

ε     # Map each integer in the (implicit) input to:
    #  Reset the counter variable to 0
 Δ    #  Loop until the integer no longer changes:
  S   #   Convert it to a list of digits
   O  #   And take the sum of those
  ¼   #   Increase the counter variable by 1
    #  After the inner loop: Push the counter variable
}<    # After the map: decrease each value by 1
  ø   # Zip/transpose it with the (implicit) input to create a paired list
   »  # Join each pair by a space, and then each string by newlines
      # (after which the result is output implicitly)

1

MathGolf , 11 bytes

hÅ_Σ]▀£(k ?

Experimente online!

Incrivelmente ineficiente, mas não nos importamos com isso. Basicamente, usando o fato de que a persistência aditiva de um número é menor ou igual ao próprio número.

Usa o fato de que a persistência aditiva é menor ou igual ao número de dígitos do número. Agora passa em todos os casos de teste com facilidade.

O formato de entrada, embora abaixo do ideal para alguns idiomas, é realmente o método padrão de receber vários casos de teste como entrada no MathGolf. Cada linha da entrada é processada como sua própria execução do programa e a saída é separada por uma nova linha para cada execução.

Explicação (usando n = 6234)

h             push length of number without popping (6234, 4)
 Å            loop 4 times using next 2 operators
  _           duplicate TOS
   Σ          get the digit sum
    ]         wrap stack in array
              this gives the array [6234, 15, 6, 6, 6]
     ▀        unique elements of string/list ([6234, 15, 6])
      £       length of array/string with pop (3)
       (      decrement (2)
        k ?   push input, space, and rotate top 3 elements to produce output (6234 2)

1

K (ngn / k) , 16 bytes

Solução:

{x,#1_(+/10\)\x} 

Experimente online!

Explicação:

{x,#1_(+/10\)\x} / the solution
{              } / lambda taking implicit x
      (     )\x  / iterate until convergence
         10\     / split into base-10 (123 => 1 2 3)
       +/        / sum
    1_           / drop first result (iterate returns input as first result)
   #             / count length of result
 x,              / prepend x (original input)


0

scala 173:

def s(n:BigInt):BigInt=if(n<=9)n else n%10+s(n/10)
def d(n:BigInt):Int=if(n<10)0 else 1+d(s(n))
Iterator.continually(readInt).takeWhile(_>0).foreach(i=>println(i+" "+d(i)))



0

Python 3 , 82 bytes

while 1:f=lambda n:n//10and 1+f(sum(map(int,str(n))));i=input();print(i,f(int(i)))

0

Tcl , 95 bytes

proc P {v n\ 0} {set V $v
while \$v>9 {set v [expr [join [split $v ""] +]]
incr n}
puts $V\ $n}

Experimente online!


3
Porque a próxima resposta mais novo é um completo 6 anos de idade, que eu acho que é antes TIO existia
fənɛtɪk

0

Japonês , 28 bytes

Ë+S+(@D=X©A<D©ì x ªD D<AÃa÷
Ë                            // Map over the inputs and return each, followed by
 +S+                         // a space, followed by the number's persistence.
      D=     ©ì x            // To find it, fold the number up
        X©A<D     ªD         // if we can (handles unfoldable cases),
    (@               D<AÃa   // until it can't be folded up any further.
                          ÷ // Then, join everything up with newlines.

Experimente online!


0

PHP, 72 + 1 bytes

+1 para -Rsinalizador.

for($i=0,$a=$argn;$a>9;$i++)$a=array_sum(str_split($a));echo"$argn $i
";

Corra como cano com -R.

  • executar o PHP como pipe executará o código uma vez para cada linha de entrada
  • mas não desmarca variáveis ​​entre elas; então $ideve ser inicializado.
    (Além disso, não imprimiria nada em vez de 0dígitos únicos sem a inicialização.)

0

Bash + coreutils, 83 bytes

[ $1 -le 9 ]&&exit $2
let x=$2+1
for z in `fold -w1<<<$1`
do let y+=$z
done
a $y $x

Experimente online!

Deve ser salvo em um script chamado ae colocado no sistema PATH, como se chama recursivamente. Recebe entrada da linha de comando, como a 1999. Retorna pelo código de saída.

O TIO tem algumas limitações sobre o que você pode fazer com um script; portanto, há algum código padrão para fazer isso rodar no cabeçalho.

Imprime um erro stderrpara entrada maior do que os números inteiros do bash podem suportar, mas, como o cálculo real é feito com seqüências de caracteres, ele ainda dá o resultado certo de qualquer maneira.

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.