Dilema de Disarium


31

Dilema de Disarium

Um Disarium é definido como um número cujo:

a soma de seus dígitos alimentados com sua respectiva posição é igual ao número original


Sua tarefa :

Você tem uma estranha obsessão por números classificados como desarticulados. A necessidade de seguir os caminhos do disarium é tão grande em você que você se recusa a ler páginas numeradas que não sejam do disarium em um determinado livro. Você tem dois grandes problemas:

  1. Seu professor acabou de lhe designar para ler seu livro de uma página npara outram
  2. Você bateu a cabeça com muita força na semana passada e parece que não consegue se lembrar de como determinar programaticamente se um número é considerado um disário.

O tempo é essencial; portanto, o código para determinar as páginas que você precisará ler precisa ser o mais curto possível.

Você precisa identificar todas as disarium dentro de uma gama abrangente de nmeio m.

Exemplos de um disarium :

89 = 8 1 + 9 2

135 = 1 1 + 3 2 + 5 3

518 = 5 1 + 1 2 + 8 3

Isso é código-golfe, então o menor número de bytes vence!

Aqui está a sequência completa de A032799 .


@Fatalize O intervalo é inclusivo, editarei a pergunta para refletir isso.
precisa saber é o seguinte

Existem limites garantidos ne m? Existe um grande disário (12157692622039623539). As respostas devem ser capazes de identificá-lo?
Lynn

@ Lynn Dado que já existem várias soluções, eu diria que não deve haver limites no intervalo.
precisa saber é o seguinte

2
@Lynn. Não há disarium> 22 dígitos, portanto, de certa forma, o intervalo já está limitado.
Físico Louco

3
@MistahFiggins Acesse o link OEIS na parte inferior da pergunta. Você encontrará uma prova que mostra que a sequência do Disarium é realmente finita.
precisa saber é o seguinte

Respostas:


11

Perl 6 , 40 39 bytes

{grep {$_==sum .comb Z**1..*},$^a..$^b}

Experimente online!

Como funciona

{                                     }  # A lambda.
                              $^a..$^b   # Range between the two lambda arguments.
 grep {                     },           # Return numbers from that range which satisfy:
               .comb Z  1..*             #  Digits zipped with the sequence 1,2,3,...,
                      **                 #  with exponentiation operator applied to each pair,
           sum                           #  and those exponents summed,
       $_==                              #  equals the number.

8

Python2, 98 89 88 84 bytes

lambda n,m:[x for x in range(n,m+1)if sum(int(m)**-~p for p,m in enumerate(`x`))==x]

Horrível. Vai ficar mais curto. Começando a parecer melhor

Aqui está minha tentativa recursiva (86 bytes):

f=lambda n,m:[]if n>m else[n]*(sum(int(m)**-~p for p,m in enumerate(`n`))==n)+f(n+1,m)

Obrigado a @Rod por salvar 4 bytes! rangepara enumeratee assim por diante.


mudar para enumerate, você pode usar int(n)em vezint(`x`[p])
Rod

7

Perl, 43 bytes

map{say if$_==eval s/./+$&**$+[0]/gr}<>..<>

Experimente online!

Regex é realmente poderoso, pessoal.

Explicação

A primeira coisa que o código faz é ler dois números inteiros como entrada via <>e cria um intervalo do primeiro ao segundo com ... Em seguida, ele usa o padrão mapfunção para percorrer esta faixa, e aplica-se o seguinte código para cada valor: say if$_==eval s/./+$&**$+[0]/gr. Parece bobagem, e meio que é, mas aqui está o que realmente está acontecendo.

maparmazena implicitamente seu valor atual na variável $_. Muitas funções e operações perl usam esse valor quando nenhum é fornecido. Isso inclui expressões regulares, como o s///operador de substituição.

Há quatro partes em uma regex de substituição:

  1. String a ser manipulada. Normalmente, o operador =~é usado para aplicar uma regex a uma string, mas se esse operador estiver ausente, a regex será aplicada à variável implícita $_, que contém nosso número atual por meio da mapfunção
  2. String para procurar. Nesse caso, estamos procurando por qualquer caractere que não seja de nova linha, indicado pelo curinga .. Na verdade, estamos capturando cada dígito individual.
  3. String para substituir. Estamos substituindo um sinal de mais +seguido por uma expressão matemática, misturada com algumas variáveis ​​Perl mágicas que tornam tudo significativamente mais fácil.

A variável escalar especial $&sempre contém a totalidade da última captura bem-sucedida de regex, que neste caso é um único dígito. A variável de matriz especial @+sempre contém uma lista de deslocamentos pós-correspondência para a última correspondência bem-sucedida, ou seja, o índice do texto após a correspondência. $+[0]é o índice $_do texto imediatamente a seguir $&. No caso de 135, capturamos o dígito 1e o índice 135do texto imediatamente depois (ou seja, 35) é 1, que é o nosso expoente. Então, queremos aumentar $&(1) a potência de $+[0](1) e obter 1. Queremos aumentar 3 à potência de 2 e obter 9. Queremos aumentar 5 à potência de 3 e obter 125.

Se a entrada foi 135, a sequência resultante é +1**1+3**2+5**3.

  1. Sinalizadores de modificação de regex. Aqui estamos usando dois sinalizadores de regex - /ge /r. /gdiz ao intérprete para continuar as substituições depois que a primeira for encontrada (caso contrário, acabaríamos com +1**135). /rdiz ao intérprete para não modificar a sequência original e, em vez disso, retorne o que seria após a substituição. Isso é importante, porque, caso contrário, ele seria substituído $_e precisamos dele para fins de comparação.

Depois que toda a substituição é concluída, obtemos uma expressão matemática, que é avaliada com a evalfunção +1**1+3**2+5**3é avaliado em 1 + 9 + 125 = 135, comparado com o número original 135. Como esses dois são iguais, o código imprime o número.


Bela solução. (Observe que isso não vai funcionar, a primeira entrada é 0, mas não tenho certeza se isso importa). Alguns bytes para o golfe:map$_-eval s/./+$&**$+[0]/gr||say,<>..<>
Dadá

E "@+"é 1 byte mais curto do que $+[0]:)
Dada

7

JavaScript (ES7), 105 91 89 88 83 79 82 81 bytes

Agradecemos a Arnauld por salvar 20B e a ETHProductions por salvar 6B!

a=>b=>[...Array(b).keys()].filter(c=>c>=a&([...c+''].map(d=>c-=d**++e,e=0),!c))

Uso

Atribua a função a uma variável e forneça o mínimo e o máximo como argumentos. Exemplo:

f=a=>b=>[...Array(b).keys()].filter(c=>c>=a&([...c+''].map(d=>c-=d**++e,e=0),!c))
f(0)(90)

Saída

[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 89]

Golfe adicional

Isso parece muito bom, mas sempre há espaço para melhorias ... eu acho.


Sim, isso é realmente um pouco mais curto. Obrigado!
Lucas

1
Você pode mudar d**(e+1)para d**-~esalvar dois bytes.
ETHproductions

Obrigado pela dica, acrescentou. Só mais 2 bytes antes de ter batido Python ...
Lucas

Você pode usar em &vez de &&. Mais um byte para ir ...
Arnauld

Acabei de mudar isso na minha cópia local ... Acho que você foi mais rápido.
Lucas

6

JavaScript (Firefox 52+), 68 bytes

f=(n,m)=>(e=0,[for(d of t=n+'')t-=d**++e],t||alert(n),n-m&&f(n+1,m))

Função recursiva que gera via alert. Funciona na Developer Edition do Firefox, que você pode baixar nesta página . As versões anteriores do Firefox não suportam o **operador e nenhum outro navegador suporta a [for(a of b)c]sintaxe.

Snippet de teste

Isso usa em .mapvez de uma compreensão de matriz e, em Math.powvez de **, deve funcionar em todos os navegadores que oferecem suporte ao ES6.


6

05AB1E , 12 bytes

Economizou 2 bytes graças a Emigna

ŸvygLySmOyQ—

Experimente online!

Ÿ            # push [a .. b]
 vy          # for each
   gL        # push [1 .. num digits]
     yS      # push [individual digits]
       m     # push [list of digits to the power of [1..num digits] ]
        O    # sum
         yQ— # print this value if equal

ŸvygLySmOyQ—deve funcionar para 12 bytes.
Emigna

5

Python 3, 100 bytes

lambda n,m:{*range(10),89,135,175,518,598,1306,1676,2427,2646798,0xa8b8cd06890f2773}&{*range(n,m+1)}

Não é a abordagem mais curta, mas uma abordagem bem fofa. Existem muitos disários finitos; veja a página OEIS para uma boa prova. Estes são todos eles.


Este é o uso de codificar que é uma brecha meta.codegolf.stackexchange.com/a/1063/55243 I seria recomendado que você altere sua resposta para se encaixar com as regras padrão
george

5
Eu não acho que isso viole a regra de codificação embutida, pois o programa ainda "funciona" e a saída não é codificada.
Alex Howansky

4

R, 100 bytes

function(n,m,x=n:m)x[sapply(x,function(y)sum(as.integer(el(strsplit(c(y,""),"")))^(1:nchar(y)))==y)]

Função sem nome que leva ne m. Como sempre em R, dividir números inteiros em um vetor de dígitos numéricos é entediante e consome muitos bytes. Isso torna a função relativamente lenta e funciona apenas para números inteiros de 32 bits.


4

Gelatina , 11 bytes

D*J$S⁼
rÇÐf

Experimente online!

Isso diminuiu de 16 para 11, com a ajuda de @miles!

Explicação:

rÇÐf    Main link, arguments are m and n
r       Generate a list from m to n
 Ç      Invoke the helper link
  Ðf    And filter out all that don't return 1 on that link

D*J$S⁼  Helper link, determines if item is Disarium
D       Break input (the current item of our list in Main) into digits (135 --> [1, 3, 5])
  J$    Create a range from 1 to x, where x is the number of digits             [1, 2, 3]
 *      Raise each digit to the power of their respective index 
    S⁼  And return a 1 if the sum of powers is equal to the helper-link's input

Você pode usar Jpara obter índices. Um caminho mais curto pode ser D*J$S⁼para combinar seus dois links em um
milhas

Chegou exatamente a essa conclusão há cerca de 20 segundos. Thnx!
18717

3

CJam , 23 bytes

q~),\>{_Ab_,,:).#:+=},p

Experimente online!

Explicação

q~                      Get and eval all input
  ),\>                  Get the range between m and n, inclusive
      {                 For each number in the range...
       _Ab               Duplicate and get the list of digits
          _,,:)          Duplicate the list, take its length, make the range from 1 to length
               .#        Vectorize with exponentiation; computes first digit^1, second^2, etc
                 :+      Sum the results
                   =     Compare to the original number
                    },  Filter the range to only numbers for which the above block is true
                      p Print nicely


3

Python 2.X, 92 bytes

lambda m,n:[k for k in range(m,n+1)if sum(int(j)**(i+1) for i,j in enumerate(list(`k`)))==k]

Espaço em branco inútil depois (i+1), mas isso não é um problema, quando você se livra dos parênteses -~i.
Yytsi 19/01/19

Isso faria minha tentativa exatamente igual à sua!
precisa saber é o seguinte

Quase. Você tem list('k'), o que eu não tenho. No entanto, você ainda pode remover o espaço em branco :)
Yytsi

3

Python 2 , 84 bytes

Uma abordagem de programa completo, atualmente do mesmo tamanho que a solução lambda.

a,b=input()
while a<=b:
 t=p=0
 for x in`a`:p+=1;t+=int(x)**p
 if t==a:print a
 a+=1

Experimente online!


Hmm. Eu pensei sobre a resposta quase exata, mas descartada devido à confusão com input(). Muito agradável! +1.
Yytsi 19/01/19

3

Japonês, 15 bytes

òV f_¥Zì £XpYÄÃx

Teste online! Essa foi uma colaboração entre @obarakon e eu.

Como funciona

òV f_¥Zì £XpYÄÃx   // Implicit: U, V = input integers
òV                 // Create the inclusive range [U...V].
   f_              // Filter to only the items Z where...
               x   //   the sum of
      Zì           //   the decimal digits of Z,
         £XpYÄÃ    //   where each is raised to the power of (index + 1),
     ¥             //   is equal to Z.
                   // Implicit: output result of last expression

Na versão mais recente do Japt, xaceita uma função como argumento, o que nos permite obter outro byte:

òV f_¥Zì x@XpYÄ

Teste online!


2

Clojure, 107 bytes

#(for[i(range %(inc %2)):when(=(int(apply +(map(fn[i v](Math/pow(-(int v)48)(inc i)))(range)(str i))))i)]i)

A implementação da equação é terrivelmente longa.


pode salvar um par de bytes, fazendo(.pow(-(int v)48M)
cliffroot

2

TI-Básico, 85 bytes

Input 
For(I,X,Y
If I<=9 or sum(I={89,135,175,518,598,1306,1676,2427,2646798,12157692622039623539
Disp I
End

Eu não sabia que a codificação embutida era permitida. :)
Abel Tom

@AbelTom Bem, realmente ajuda que esta série tenha apenas 20 termos. Além disso, a conversão de número em sequência na TI-Basic leva muitos bytes. Somente outra solução seria para int(log(todos os números e, depois, fazer os poderes. Talvez isso seja mais curto, mas duvido.
Timtech 19/01/19

Esse método de entrada é muito inteligente, mas meio superficial. Você precisa estar no FUNCmodo e a janela deve ser configurada para incluir seu ponto de entrada. Não parece portátil o suficiente para mim.
Jakob

@JakobCornell Por padrão, o calc está no FUNCmodo, embora eu veja o que você está dizendo sobre a resolução de entrada. Mas, esse método é bastante comum no golfe. Você sempre poderia em Prompt X,Yvez disso.
Timtech 20/01

2

Haskell, 61 bytes

n#m=[i|i<-[n..m],i==sum(zipWith(^)(read.pure<$>show i)[1..])]

Exemplo de uso 5 # 600-> [5,6,7,8,9,89,135,175,518,598].

Verifique cada número ino intervalo [n..m]. Os dígitos são extraídos transformando i- se em uma string ( show) e tornando cada caracter uma string de um elemento ( pure) que é transformada em um número inteiro novamente ( read). Feche esses elementos de números com [1..]a função ^e pegue o sum.


2

PHP, 92 91 88 bytes

3 bytes salvos graças @AlexHowansky

for([,$n,$m]=$argv;$n<=$m;$s-$n++?:print"$s,")for($i=$s=0;_>$b=($n._)[$i++];)$s+=$b**$i;

recebe entrada de argumentos de linha de comando; imprime uma vírgula à direita. Corra com -r.


1
Salve três comfor([,$n,$m]=$argv;$n<=$m;
Alex Howansky

Estranho que a impressão funcione lá, mas o eco não. Eu acho que porque o eco não retorna nada - nem mesmo nulo, estranhamente.
Alex Howansky

@AlexHowansky: É também estranho que "$n"[index]e "_$n"[index]erros de produtos de análise durante "89"[index]e $s="$n";$s[index]são perfeitamente bem.
Titus

Hmm, sim, isso parece estranho no começo, mas depois de verificar os documentos, parece que eles dizem explicitamente que o recurso funciona apenas para literais de strings.
Alex Howansky

Heh heh bem, isso funciona, mas provavelmente não economiza bytes:("_$n")[index]
Alex Howansky

2

Mathematica, 59 bytes

Select[Range@##,Tr[(d=IntegerDigits@#)^Range@Length@d]==#&]&

Função sem nome, recebendo dois argumentos inteiros e retornando uma lista de números inteiros. (d=IntegerDigits@#)^Range@Length@dproduz a lista de dígitos de um número para as potências apropriadas; Tr[...]==#detecta se a soma desses dígitos é igual ao número original.


2

MATLAB, 88 73 bytes

@(n,m)find(arrayfun(@(n)n==sum((num2str(n)-48).^(1:log10(n)+1)),n:m))+n-1

Resposta original:

function g(n,m);a=n:m;a(arrayfun(@(n)n==sum((num2str(n)-'0').^(1:floor(log10(n))+1)),a))

num2str(n)-'0'divide um nem um vetor de seus dígitos e 1:floor(log10(n))+1é um vetor que mantém um no número de dígitos n. Graças a registrar o golfe em uma função anônima, economizando 15 bytes.


1

Haskell , 82 76 75 bytes

n!m=[x|x<-[n..m],x==x#(length.show)x]
0#i=0
n#i=(div n 10)#(i-1)+mod n 10^i

Experimente online! Uso:5 ! 175

Isso verifica cada número no intervalo npara msaber se é um número de disarium e, portanto, é bastante lento para grandes m.


Versão mais rápida: (93 bytes)

n!m=[x|x<-[0..9]++[89,135,175,518,598,1306,1676,2427,2646798,12157692622039623539],x>=n,x<=m]

Experimente online!


1

C (gcc) , 136 bytes

r[]={0,0};f(n){if(n)f(n/10),r[1]=pow((n%10),*r)+r[1]+.5,r[0]++;else*r=1,r[1]=0;}g(m,x){for(;m<=x;m++){f(m);if(m==r[1])printf("%d,",m);}}

Cabeçalho que define pow no TIO porque, por algum motivo, ele não inclui automaticamente o pow. Meu computador funcionou, então eu vou continuar com isso.

Experimente online!


1

MATL , 16 bytes

&:"@tFYAtn:^s=?@

Experimente online!

&:        % Input two n, m implicitly. Push array [n n+1 ... m]
"         % For each k in that array
  @       %   Push k
  tFYA    %   Duplicate. Convert to decimal digits
  tn:     %   Duplicate. Push [1 2 ... d], where d is the number of digits
  ^       %   Element-wise power
  s       %   Sum of array
  =       %   Compare with previous copy of k: is it equal?
  ?       %   If so
    @     %     Push k
          %   End, implicit
          % End, implicit
          % Display stack, implicit

1

Lote, 115 bytes

@for %%d in (0 1 2 3 4 5 6 7 8 9 89 135 175 518 598 1306 1676 2427 2646798)do @if %%d geq %1 if %%d leq %2 echo %%d

O lote possui apenas aritmética de 32 bits, que não tem como comparar o último número do disarium, mas se você insistir em comparações de cadeias, terá 402 bytes:

@echo off
for %%d in (0 1 2 3 4 5 6 7 8 9 89 135 175 518 598 1306 1676 2427 2646798 12157692622039623539)do call:c %1 %%d&&call:c %%d %2&&echo %%d
exit/b
:c
call:p %1 %2
set r=%s%
call:p %2 %1
:g
if %r:~,1% lss %s:~,1% exit/b0
if %r:~,1% gtr %s:~,1% exit/b1
if %r%==%s% exit/b0
set r=%r:~1%
set s=%s:~1%
goto g
:p
set s=%1
set t=%2
:l
set s=0%s%
set t=%t:~1%
if not "%t%"=="" goto l

1

Python 2, 100 bytes

for i in range(input(),input()+1):x=sum(int(`i`[n])**-~n for n in range(len(`i`)));print("",x)[x==i]

Ainda não tive a chance de executar isso (fazendo isso no meu telefone).


Isso não funciona. Sintaxe incorreta e, quando corrigida, imprimiria apenas valores booleanos. Inicia a partir do expoente 0, que também está incorreto. Além disso, você não precisa dos colchetes internos sum.
Yytsi 19/01/19

Isso não está verificando os números do disarium.
precisa saber é o seguinte

@ hashcode55, fixo (?)
Daniel

@TuukkaX, agora ele deve funcionar eu acho
Daniel

Não estou no computador, mas isso deve imprimir uma nova linha em cada iteração, onde iestá um Disarium. Não tenho idéia se isso é permitido, mas eu diria que não, pois a saída fica muito em branco.
Yytsi 19/01/19

1

Scala, 132 129 bytes

(% :Int,^ :Int)=>for(i<- %to^)if(((0/:(i+"").zipWithIndex)((z,f)=>{z+BigInt(f._1.toInt-48).pow(f._2+1).intValue}))==i)println(i)

129 editar: Alterar o nome da variável do loop for de &para itrês espaços salvos.


Explicação

Para cada valor no intervalo de entrada:

  • convertê-lo em uma string com +""
  • use zipWithIndexpara produzir uma lista de tuplas contendo um caractere do dígito e seu índice
  • dobre a lista retornando o valor int de cada caractere menos 48 (linhas até 0-9) à potência do seu índice de lista mais um (para começar em ^ 1)
  • se o resultado corresponder à entrada, imprima-a

Comentários

Finalmente comecei a aprender como folde zipWithIndextrabalhar. Estou descontente com as intconversões, mas estou satisfeito com a sucessão de folde zipWithIndex.


1

Oitava, 88 87 bytes

Agradecimentos a MattWH por salvar um byte (f (x) -48 vs f (x) - '0')

@(n,m,f=@num2str,a=n:m)a(a==cell2mat(arrayfun(@(x){sum((f(x)-48).^(1:nnz(f(x))))},a)))

Para correr:

>> f=@(n,m,f=@num2str,a=n:m)a(a==cell2mat(arrayfun(@(x){sum((f(x)-'0').^(1:nnz(f(x))))},a))) 
>> f(0,1000)
ans = 
      1     2     3     4     5     6     7     8     9    89   135   175   518   598

Explicação

@(n,m,                                              % Create an anonymous function and pass it n and m as paramteres
    f=@num2str,                                     % Will be using the num2str mehtod twice, set the variable f to the handle to save on bytes
        a=n:m)                                      % Create a vector 'a' and populate it with the numbers n through m
            a(a==                                   % Logically index into a, where the values of a match Disarium numbers
                cell2mat(                           % Convert the cell array returned by arrayfun into a matrix, so we can use it in the logical index
                    arrayfun(@(x){                  % Call the following function on every element of a, using the index named 'x'
                        sum(                        % Sum the matrix that results from the following computation
                            (f(x)-'0')              % Convert the value at index x into a string, then break it into a matrix by subtracting the string '0'.
                                                    % This results in the matrix [1 3 5] for the number 135.
                                .^                  % Compute the element-wise power with the following matrix
                                    (1:nnz(f(x)))   % Create a matrix with the range 1 to the length of the number at index x. This results in the matrix 
                                                    % [1 2 3] for the number 135.
                        )                           % Closes the sum statement
                    },a)                            % Closes the arrayfun statement, passing the matrix a to be operated on
                )
            )

1

C 175 169 bytes

f(a,b){for(j=a;j<b;j++){n,i=0,x=0;s=0;n=j;while(n!=0){n/=10;i++;}a[i];n=j;while(n!=0){a[i-x-1]=n%10;n/=10;x++;}for(x=0;x<i;x++)s+=(int)pow(a[x],x+1);if(j==s)printf("%d ",s);}}

Versão não destruída:

void f(int a, int b)
{

  for(int j=a; j<b;j++)
  {
    int n,i=0,x=0;
    int s=0;
    n=j;

   //Convert each number from 'n' to 'm' and store it in an int array 
   while(n)
   {
     n/=10;
     i++;     
   }
   int a[i]; 

   n=j;       
   while(n)
   {
    a[i-x-1]=n%10;
    n/=10;
    x++;     
   }

  //Calculate sum of digits powered with their respective position
  for(x=0;x<i;x++)
   s+=(int)pow(a[x], x+1);

   //Print Desarium
   if(j==s)
    printf("%d ", sum);     
 }

}

Pode ser reduzido de alguma forma, mas não vejo no momento.

@TuukkaX Obrigado por salvar 6 bytes.


Ambos n!=0podem ser alterados para n.
Yytsi 19/01/19

Você está certo, isso faz sentido!
Abel Tom

0

Java

s->{long i=0,j=0,c,d;for(;j!=s;){String []f=Long.toString(i).split("");for(d=0,c=0;d<f.length;)c+=Math.pow(Long.valueOf(f[d]),++d);if(i==c)j++;}return i;}

Explicação

s    - index
i    - iteration variable
j    - matches
c    - sum of each digit^its index
d    - index of digit in i

0

Python 3: 131 bytes

n=int(input())
m=int(input())
R=[x for x in range(n,m+1)]
O=[sum(map(int,str(x)))for x in R]
F=[(x**(O.index(x)))for x in O]
L=[x for x in F for w in R if x==w]
print(list(set(L)))

Depois de criar esse código, tornou-se aparente que há um número limitado de desariums; portanto, pode ser mais viável checá-los explicitamente, em vez de usar tanta compreensão de lista que é difícil para grandes entradas nessa solução.

Experimente online!

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.