Dilema del acuario


31

Dilema del acuario

Un Disarium se define como un número cuyo:

la suma de sus dígitos alimentados con su posición respectiva es igual al número original


Su tarea :

Tienes una extraña obsesión con los números clasificados como un acuario. La necesidad de seguir los caminos del disarium es tan grande en usted que se niega a leer las páginas numeradas que no están en el acuario de cualquier libro. Tienes dos GRANDES problemas:

  1. Su profesor acaba de asignarle que lea su libro de texto de una página na otram
  2. Te golpeaste la cabeza muy fuerte la semana pasada y parece que no puedes recordar cómo determinar mediante programación si un número se considera un acuario.

El tiempo es esencial, por lo que el código para determinar las páginas que necesitará leer debe ser lo más breve posible.

Debe identificar todo el disuario dentro de un rango inclusivo de nhasta m.

Ejemplos de un acuario :

89 = 8 1 + 9 2

135 = 1 1 + 3 2 + 5 3

518 = 5 1 + 1 2 + 8 3

Este es el código de golf, por lo que gana el menor número de bytes.

Aquí está la secuencia completa de A032799 .


@Fatalize El rango es inclusivo, editaré la pregunta para reflejar esto.
CraigR8806

¿Hay límites garantizados en ny m? Hay un gran acuario (12157692622039623539), ¿deberían las respuestas poder identificarlo?
Lynn el

@ Lynn Dado que ya hay una serie de soluciones, diría que no debería haber límites en el rango.
CraigR8806

2
@Lynn. No hay disarium> 22 dígitos, por lo que, en cierto modo, el rango ya está acotado.
Físico loco

3
@MistahFiggins Vaya al enlace OEIS en la parte inferior de la pregunta. Encontrará una prueba que muestra que la secuencia de Disarium es de hecho finita.
CraigR8806

Respuestas:


11

Perl 6 , 40 39 bytes

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

Pruébalo en línea!

Cómo 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]

Horrible. Se acortará. Empieza a verse mejor

Aquí está mi intento recursivo (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)

¡Gracias a @Rod por guardar 4 bytes! rangea enumeratey así sucesivamente.


cambiando a enumerate, puedes usar int(n)en su lugarint(`x`[p])
Rod

7

Perl, 43 bytes

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

Pruébalo en línea!

Regex es realmente poderoso, muchachos.

Explicación

Lo primero que hace el código es leer dos enteros como entrada vía <>, y crea un rango del primero al segundo con ... Luego usa la mapfunción estándar para recorrer este rango y aplica el siguiente código a cada valor:say if$_==eval s/./+$&**$+[0]/gr . Esto parece galimatías, y lo es, pero esto es lo que realmente está sucediendo.

mapalmacena implícitamente su valor actual en la variable $_. Muchas funciones y operaciones de Perl usan este valor cuando no se da ninguna. Esto incluye expresiones regulares, como el s///operador de sustitución.

Hay cuatro partes en una expresión regular de sustitución:

  1. Cadena para ser manipulada. Normalmente, el operador =~se utiliza para aplicar una expresión regular a una cadena, pero si este operador está ausente, la expresión regular se aplica a la variable implícita $_, que contiene nuestro número actual a través de la mapfunción.
  2. Cadena para buscar. En este caso, estamos buscando cualquier carácter único que no sea de nueva línea, indicado por el comodín .. En efecto, estamos capturando cada dígito individual.
  3. Cadena para reemplazar con. Estamos sustituyendo un signo más +seguido de una expresión matemática, mezclada con algunas variables mágicas de Perl que hacen que todo sea mucho más fácil.

La variable escalar especial $&siempre contiene la totalidad de la última captura de expresiones regulares exitosa, que en este caso es un solo dígito. La variable de matriz especial @+siempre contiene una lista de compensaciones posteriores a la coincidencia para la última coincidencia exitosa, es decir, el índice del texto después de la coincidencia. $+[0]es el índice $_del texto que sigue inmediatamente $&. En el caso de 135, capturamos el dígito 1y el índice en135 del texto inmediatamente después (es decir, 35) es 1, que es nuestro exponente. Entonces, queremos elevar $&(1) a la potencia de $+[0](1) y obtener 1. Queremos elevar 3 a la potencia de 2 y obtener 9. Queremos elevar 5 a la potencia de 3 y obtener 125.

Si la entrada fue 135 , la cadena resultante es +1**1+3**2+5**3.

  1. Banderas modificadoras de expresiones regulares. Aquí estamos usando dos banderas regex - /gy /r. /gle dice al intérprete que continúe con los reemplazos después de encontrar el primero (de lo contrario, terminaríamos con +1**135). /rle dice al intérprete que no modifique la cadena original y, en su lugar, devuelva cuál sería la cadena después de los reemplazos. Esto es importante, porque de lo contrario, se sobrescribiría $_, y lo necesitamos para fines de comparación.

Una vez que se realiza la sustitución completa, obtenemos una expresión matemática, que se evalúa con la evalfunción. +1**1+3**2+5**3se evalúa en 1 + 9 + 125 = 135, que se compara con el número original 135. Como estos dos son iguales, el código imprime el número.


Hermosa solución (Tenga en cuenta que esto no funcionará, la primera entrada es 0, pero no estoy seguro de que importe). Unos pocos bytes para jugar al golf:map$_-eval s/./+$&**$+[0]/gr||say,<>..<>
Dada

Y "@+"es 1 byte más corto que $+[0]:)
Dada

7

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

¡Gracias a Arnauld por ahorrar 20B y a ETHProductions por ahorrar 6B!

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

Uso

Asigne la función a una variable y dele el mínimo y el máximo como argumentos. Ejemplo:

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

Salida

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

Golf adicional

Esto parece bastante bien, pero siempre hay margen de mejora ... creo.


Sí, eso es bastante más corto. ¡Gracias!
Luke

1
Puede cambiar d**(e+1)a d**-~epara guardar dos bytes.
ETHproductions

Gracias por el consejo, lo agregué. Solo 2 bytes más antes de vencer a Python ...
Lucas

Puedes usar en &lugar de &&. Un byte más para ir ...
Arnauld

Acabo de cambiar eso en mi copia local ... Supongo que fuiste más 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))

Función recursiva que sale a través de alert. Funciona en la Edición para desarrolladores de Firefox, que puede descargar en esta página . Las versiones anteriores de Firefox no son compatibles con el **operador, y ningún otro navegador es compatible con la [for(a of b)c]sintaxis.

Fragmento de prueba

Esto utiliza en .maplugar de una comprensión de matriz, y en Math.powlugar de **, por lo que debería funcionar en todos los navegadores que admitan ES6.


6

05AB1E , 12 bytes

Guardado 2 bytes gracias a Emigna

ŸvygLySmOyQ—

Pruébalo en línea!

Ÿ            # 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—debería 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)}

No es el enfoque más corto, pero sí uno muy lindo. Hay finitamente muchos acuarios; ver la página de OEIS para una buena prueba. Estos son todos ellos.


Este es el uso de codificación dura que es una laguna meta.codegolf.stackexchange.com/a/1063/55243 me recomienda cambiar su respuesta para adaptarse a la normativa estándar
George

55
No creo que esto viole la regla de codificación rígida, ya que el programa todavía "funciona" y la salida no está 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)]

Función sin nombre que toma ny m. Como siempre en R, dividir enteros en un vector de dígitos numéricos es tedioso y consume muchos bytes. Esto hace que la función sea relativamente lenta y solo funciona para enteros de 32 bits.


4

Jalea , 11 bytes

D*J$S⁼
rÇÐf

Pruébalo en línea!

¡Lo conseguí de 16 a 11, con ayuda de @miles!

Explicación:

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

Puedes usar Jpara obtener índices. Una forma más corta podría ser D*J$S⁼combinar sus dos enlaces en uno
millas

Llegué exactamente a esa conclusión hace unos 20 segundos. Thnx!
steenbergh

3

CJam , 23 bytes

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

Pruébalo en línea!

Explicación

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]

Espacio en blanco inútil después (i+1), pero esto no es un problema, cuando se deshace de los paréntesis haciendo -~i.
Yytsi

¡Eso haría que mi intento sea exactamente igual al suyo!
hashcode55

Casi. Tienes list('k'), que yo no tengo. Sin embargo, aún puede eliminar el espacio en blanco :)
Yytsi

3

Python 2 , 84 bytes

Un enfoque de programa completo, actualmente de la misma longitud que la solución 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

Pruébalo en línea!


Hmm Pensé en la respuesta casi exacta, pero descarté debido a la confusión con input(). ¡Muy agradable! +1.
Yytsi

3

Japt, 15 bytes

òV f_¥Zì £XpYÄÃx

¡Pruébelo en línea! Esta fue una colaboración entre @obarakon y yo.

Cómo 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

En la última versión de Japt, xacepta una función como argumento, lo que nos permite jugar a otro byte:

òV f_¥Zì x@XpYÄ

¡Pruébelo en línea!


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)

La implementación de la ecuación es terriblemente larga.


puede ahorrar un par de bytes haciendo(.pow(-(int v)48M)
cliffroot

2

TI-Basic, 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

No sabía que se permitiera la codificación rígida. :)
Abel Tom

@AbelTom Bueno, realmente ayuda que esta serie solo tenga 20 términos. Además, la conversión de un número a una cadena en TI-Basic requiere muchos bytes. Solo otra solución sería para int(log(cada número y luego hacer los poderes. Quizás esto sea más corto, pero lo dudo.
Timtech

Ese método de entrada es muy inteligente pero un poco incompleto. Debe estar en FUNCmodo y la ventana debe configurarse para incluir su punto de entrada. No me parece lo suficientemente portátil.
Jakob

@JakobCornell De manera predeterminada, el cálculo está en FUNCmodo, aunque veo lo que dice sobre la resolución de entrada. Pero, este método es bastante común en el golf. Siempre podrías en su Prompt X,Ylugar.
Timtech

2

Haskell, 61 bytes

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

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

Verifique cada número ien el rango[n..m] . Los dígitos se extraen convirtiéndolos ien una cadena ( show) y haciendo que cada carácter sea una cadena de un elemento ( pure) que se convierte nuevamente en un entero ( read). Comprime esos elementos con [1..]la función ^y toma el sum.


2

PHP, 92 91 88 bytes

3 bytes guardados gracias @AlexHowansky

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

toma datos de los argumentos de la línea de comandos; imprime una coma final. Corre con -r.


1
Ahorre tres con for([,$n,$m]=$argv;$n<=$m;
Alex Howansky

Es extraño que la impresión funcione allí, pero el eco no. Supongo que porque echo no devuelve nada, ni siquiera nulo, por extraño que parezca.
Alex Howansky

@AlexHowansky: Está también extraño que "$n"[index]y "_$n"[index]errores de análisis al producto "89"[index]y $s="$n";$s[index]son perfectamente bien.
Tito el

Hmm, sí, eso parece extraño al principio, pero después de verificar los documentos, parece que dicen explícitamente que la función solo funciona para los literales de cadena.
Alex Howansky

Je je, bueno, esto funciona, pero probablemente no te ahorre bytes:("_$n")[index]
Alex Howansky

2

Mathematica, 59 bytes

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

Función sin nombre que toma dos argumentos enteros y devuelve una lista de enteros. (d=IntegerDigits@#)^Range@Length@dproduce la lista de dígitos de un número a las potencias apropiadas; Tr[...]==#detecta si la suma de esas potencias de dígitos es igual al 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

Respuesta 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 a nen un vector de sus dígitos, y 1:floor(log10(n))+1es un vector que contiene uno para el número de dígitos n. Gracias por iniciar sesión en el golf hasta una función anónima, ahorrando 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

Pruébalo en línea!Uso:5 ! 175

Esto comprueba cada número en el rango nde msi es un número de disarium y, por lo tanto, es bastante lento para grandesm .


Versión más rápida: (93 bytes)

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

Pruébalo en línea!


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

Encabezado que define pow en TIO porque por alguna razón no incluyó automáticamente pow. Mi computadora lo hizo, así que voy a rodar con eso.

Pruébalo en línea!


1

MATL , 16 bytes

&:"@tFYAtn:^s=?@

Pruébalo en línea!

&:        % 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

Batch solo tiene una aritmética de 32 bits que no tiene forma de comparar el último número de disarium, pero si insiste en las comparaciones de cadenas, entonces para 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]

Todavía no he tenido la oportunidad de ejecutar esto (hacerlo en mi teléfono).


Esto no funciona Sintaxis incorrecta y cuando se corrige, imprimirá solo valores booleanos. Comienza desde el exponente 0, que también es incorrecto. Además, no necesita los corchetes dentro sum.
Yytsi

Esto no está buscando números de disarios.
hashcode55

@ hashcode55, fijo (?)
Daniel

@ TuukkaX, creo que ahora debería funcionar
Daniel

No estoy en la computadora, pero esto debería imprimir una nueva línea en cada iteración, donde ihay un Disarium. No tengo idea de si esto está permitido, pero diría que no, ya que la salida se pone muy en blanco.
Yytsi

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: Cambiar el nombre de la variable de bucle de partir &a iguardados tres espacios.


Explicación

Para cada valor en el rango de entrada:

  • convertirlo a una cadena con +""
  • utilizar zipWithIndex para producir una lista de tuplas que contienen un carácter del dígito y su índice
  • doblar la lista devolviendo el valor int de cada carácter menos 48 (líneas hasta 0-9) a la potencia de su índice de lista más uno (para comenzar en ^ 1)
  • si el resultado coincide con la entrada, imprímalo

Comentarios

Finalmente pude aprender cómo foldy zipWithIndextrabajar. No estoy satisfecho con las intconversiones, pero estoy satisfecho con la brevedad de foldy zipWithIndex.


1

Octava, 88 87 bytes

Gracias a MattWH por guardar un 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)))

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

Explicación

@(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);}}

Versión sin golf:

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

}

Se puede acortar de alguna manera, pero no lo veo en este momento.

@TuukkaX Gracias por guardar 6 bytes.


Ambos n!=0se pueden cambiar a n.
Yytsi

Tienes razón, eso tiene 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;}

Explicación

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)))

Después de crear este código, se hace evidente que hay un número limitado de disarios, por lo que podría ser más factible verificarlos explícitamente en lugar de utilizar tanta comprensión de la lista que es difícil para las grandes entradas de esta solución.

Pruébalo en línea!

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.