Concatenación decimal de cuadrados

24

Premisa

Una noche, solo estaba contemplando los números. Descubrí algo único sobre números como 7, 10, 12, 13 y más. Son cuadrados de cuadrados! Es decir, que al cuadrado, se componen de cuadrados en sí. El OEIS los llama cuadrados que son una concatenación decimal de dos o más cuadrados.

Ejemplos de tales números incluyen 7 (49 tiene 2 2 y 3 2 ) 13 (169 tiene 4 2 y 3 2 ) y 20 (400 tiene 2 2 y 0 2 ). Otros ejemplos incluyen 37, ya que 1369 es un término ya que puede dividirse como 1, 36 y 9. 1444 (38 2 ) es un término ya que puede dividirse como 1, 4, 4, 4. Pregunté sobre esto en matemáticas .SE, y fue nombrado después de mí!

Reto

Diseñe un programa que imprima números de TanMath. Dado el número n (comenzando en 1), imprima el enésimo número de TanMath, T (n).

Como ejemplo de código:

>> 1
>> 7

o

>> 4
>> 13

Implementación de Python de referencia (¡gracias @ MartinBüttner y @ Sp3000!):

from math import sqrt

n = input()

def r(digits, depth):
    z = len(digits)
    if z < 1:
        return (depth > 1)
    else:
        for i in range(1, z+1):
            t = int(digits[:i])
            if sqrt(t).is_integer() and r(digits[i:], depth+1):
                return True
        return False


i=0
t=0
while t < n:
    i += 1

    if r(str(i**2), 0):
        t += 1

print i

Aquí hay una lista de los primeros 100 números:

7 10 12 13 19 20 21 30 35 37 38 40 41 44 50 57 60 65 70 80 90 95 97 100 102 105 107 108 110 112 119 120 121 125 129 130 138 140 150 160 170 180 190 191 200 201 204 205 209 210 212 220 223 230 240 250 253 260 270 280 285 290 300 305 306 310 315 320 325 330 340 342 343 345 348 350 360 369 370 375 379 380 390 397 400 402 405 408 410 413 420 430 440 441 450 460 470 475 480 487

Este es un código de golf, por lo que gana el código más corto.

¡Buena suerte!

TanMath
fuente
38² también se puede escribir 12² y 2² por supuesto.
Neil
@Neil sí ... está en la lista de los primeros 100 números.
TanMath
Lo siento si te he confundido, pero solo estaba comentando tu elección de descomposición de 38² como 1² y 2² y 2² y 2².
Neil
@Neil oh ... ya veo. Lo dejaré así por ahora, creo que es obvio para otros que 12 ^ 2 pueden incluirse en la descomposición.
TanMath

Respuestas:

8

Pyth, 23 21 20 bytes

e.ff!-sMT^R2Z./`^Z2Q

¡Gracias a @isaacg por jugar golf en 1 byte!

Pruébalo en línea.

Cómo funciona

                      (implicit) Store the evaluated input in Q.
 .f                Q  Filter; find the first Q positive integers Z such that:
                ^Z2     Compute the square of Z.
               `        Cast to string.
             ./         Compute all partitions of the string.
   f                    Filter; find all partitions T such that:
      sMT                 Cast all elements of T to integer.
         ^R2Z             Compute the squares of all integers in [0, ..., Z-1].
     -                    Remove the squares from the integers in T.
    !                     Compute the logical NOT of the result. This returns True
                          iff all integers in T are squares of numbers less than Z.
                        Keep T if `!' returned True.
                      Keep Z if `!' returned True for at least one T.
e                     Retrieve the last of the Q matches.
Dennis
fuente
La complejidad del tiempo de ejecución es catastrófica. No recomiendo probar entradas de más de 60 con el intérprete en línea.
Dennis
El tes innecesario, porque ^R2Zno contendrá ^Z2. Es lo mismo que el rango de Python, no incluye el extremo superior.
isaacg
Sí, me di cuenta de eso tan pronto como leí tu respuesta. Eso fue un remanente del enfoque anterior ... ¡Gracias!
Dennis
De hecho, escribí que antes de ver tu publicación, mi Internet es muy lento y no vi tu actualización hasta después de que publiqué. No trato de atacarte ni nada.
isaacg
1
Sin preocupaciones. Asumí que era algo así. Me has ayudado muchas veces antes. (Y estoy íntimamente familiarizado con el problema de Internet lento.: P)
Dennis
5

Julia, 189 145 bytes

n->(c=m=0;while c<n m+=1;d=["$(m^2)"...];for p=partitions(d) d==[p...;]&&!any(√map(parse,map(join,p))%1.>0)&&endof(p)>1&&(c+=1;break)end;end;m)

Esto crea una función sin nombre que acepta un entero y devuelve un entero. Para llamarlo, dale un nombre, por ejemplo f=n->....

Sin golf:

function tanmath(n::Integer)
    # Initialize the number to check (c) and the nth TanMath
    # number (m) both to 0
    c = m = 0

    # While we've generated fewer than n TanMath numbers...
    while c < n
        # Increment the TanMath number
        m += 1

        # Get the digits of m^2 as characters
        d = ["$(m^2)"...]

        # Loop over the unordered partitions of the digits
        for p in partitions(d)
            # Convert the partition of digits to parsed numbers
            x = map(parse, map(join, p))

            # If the partition is in the correct order, none of the
            # square roots of the digits are non-integral, and p is
            # of length > 1...
            if d == [p...;] && !any(sqrt(x) % 1 .> 0) && endof(p) > 1
                # Increment the check
                c += 1

                # Leave the loop
                break
            end
        end
    end

    # Return the nth TanMath number
    return m
end

¡Gracias a Dennis por su ayuda e ideas y gracias a Glen O por guardar 44 bytes!

Alex A.
fuente
4

JavaScript ES6, 126 127

La implementación de referencia, convertida a Javascript con algún truco de golf.

Usando eval para evitar el retorno explícito.

Pruebe a ejecutar el fragmento a continuación en un navegador compatible con EcmaScript 6, con operador de propagación, parámetros predeterminados y funciones de flecha (uso Firefox)

F=n=>eval('for(i=t=0;t<n;t+=k([...i*i+""]))++i',k=(s,l=1,n="")=>s[0]?s.some((d,i)=>Math.sqrt(n+=d)%1?0:k(s.slice(i+1),l-1)):l)

// Less golfed

U=n=>{
  k = (s,l=1,n="") =>
    s[0]
    ? s.some((d,i) => 
             Math.sqrt(n+=d)%1 ? 0 : k(s.slice(i+1),l-1)
            )
    : l;
  for(i=t=0; t<n; ) {
    ++i;
    t += k([...i*i+""])
  }  
  return i
}

function test() { R.innerHTML=F(+I.value) }

test()
<input id=I value=100><button onclick='test()'>-></button>
<span id=R></span>

edc65
fuente
3

JavaScript (ES6), 143 bytes

f=n=>{for(i=c=0;c<n;c+=1<g(++i*i+""))g=s=>{for(var l=0;s[l++];)if(!(Math.sqrt(s.slice(0,l))%1)&&!s[l]|(r=!!g(s.slice(l))))return 1+r};return i}

Uso

f(100)
=> 487

Explicación

f=n=>{
  for(
    i=                     // i = current number to check
      c=0;                 // c = number of TanMath numbers found so far
    c<n;                   // keep looping until we have found the required TanMath number
    c+=1<                  // increment the count if it has multiple squares in the digits
      g(++i*i+"")          // check if the current number is a TanMath number
  )
    g=s=>{                 // this function is passed a number as a string and returns the
                           //     number of squares found (max 2) or undefined if 0
      for(var l=0;s[l++];) // loop through each digit
                           // ('var' is necessary because the function is recursive)
        if(
          !(Math.sqrt(     // check if the square root of the digits is a whole number
            s.slice(0,l)   // get the digits to check
          )%1)&&
          !s[l]|           // finish if there are no more digits left to check
          (r=!!            // r = true if number of squares in remaining digits > 0
            g(s.slice(l))  // get number of squares in remaining digits
          )
        )
          return 1+r       // return number of squares found
    };
  return i                 // return the number that the loop finished at
}
usuario81655
fuente
0

Lua, 148 bytes

c=...r=load"a=a or...==''for p=0,...and n-1or-1 do p='^'..p*p..'(.*)'r(p.match(...,p))end"n=-1repeat
n=n+1r(n*n)c,a=c-(a and 1or 0)until c<1print(n)

Se requiere Lua 5.3

$ lua program.lua 1
7
$ lua program.lua 10
37
$ lua program.lua 100
487
Egor Skriptunoff
fuente
0

Pitón 3, 283 243 bytes

Esta es una implementación de fuerza bruta. Sugerencias de golf bienvenidas.

from itertools import*
def t(n):
 a=m=0
 while a<n:m+=1;d=str(m*m);r=range(1,len(d));c=[i*i for i in range(m)];a+=any(all(p in c for p in q)for q in[[int(d[x:y])for x,y in zip((0,)+j,j+(None,))]for i in r for j in combinations(r,i)])
 return m

Sin golf:

import itertools
def tanmath(n):
    a = 0
    m = 0
    while a < n:
        m += 1
        d = str(m*m)
        squares = [i*i for i in range(m)]
        z = []
        # partitions code
        for i in range(1, len(d)):
            for j in itertools.combinations(range(1, len(d)), i):
                partition_indices = zip((0,)+j, j+(None,))
                z.append([int(d[x:y]) for x, y in partition_indices]
        # end partitions code
        if any(all(p in squares for p in q) for q in z):
            a += 1
    return m
Sherlock9
fuente