Concatenazione decimale dei quadrati


24

Premessa

Una notte, stavo solo riflettendo sui numeri. Ho scoperto qualcosa di unico su numeri come 7, 10, 12, 13 e altri. Sono quadrati di quadrati! Significa che, quando sono quadrati, sono composti da quadrati stessi. L'OEIS li chiama Quadrati che sono una concatenazione decimale di due o più quadrati.

Esempi di tali numeri includono 7 (49 ha 2 2 e 3 2 ) 13 (169 ha 4 2 e 3 2 ) e 20 (400 ha 2 2 e 0 2 ). Altri esempi includono 37, poiché 1369 è un termine in quanto può essere partizionato come 1, 36 e 9. 1444 (38 2 ) è un termine in quanto può essere partizionato come 1, 4, 4, 4. Ho chiesto questo su Math .SE, e prende il nome da me!

Sfida

Progetta un programma che stampa i numeri TanMath. Dato il numero n (a partire da 1), stampa l'ennesimo numero TanMath, T (n).

Come esempio di codice:

>> 1
>> 7

o

>> 4
>> 13

Implementazione di Python di riferimento (grazie a @ MartinBüttner e @ 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

Ecco un elenco dei primi 100 numeri:

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 112 120 120 121 125 129 130 138 140 150 160 170 180 190 191 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

Questo è un codice golf, quindi vince il codice più corto!

In bocca al lupo!


Naturalmente anche 38² possono essere scritti 12² e 2².
Neil,

@Neil si ... cÈ nella lista dei primi 100 numeri.
TanMath,

Scusa se ti ho confuso, ma stavo solo commentando la tua scelta di decomposizione di 38² come 1² e 2² e 2² e 2².
Neil,

@Neil oh .. capisco. Per ora lo lascerò così, penso che sia ovvio per gli altri che 12 ^ 2 possa essere incluso nella decomposizione.
TanMath,

Risposte:


8

Pyth, 23 21 20 byte

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

Grazie a @isaacg per il golf off 1 byte!

Provalo online.

Come funziona

                      (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.

La complessità del tempo di esecuzione è catastrofica. Non consiglio di provare input oltre i 60 con l'interprete online.
Dennis,

Non tè necessario, perché ^R2Znon conterrà ^Z2. È uguale alla gamma di Python, non include la fascia alta.
isaacg,

Sì, ho capito che non appena ho letto la tua risposta. È stato un residuo dell'approccio precedente ... Grazie!
Dennis,

In realtà ho scritto che prima di vedere il tuo post, la mia Internet è molto lenta e non ho visto il tuo aggiornamento fino a dopo che ho pubblicato. Non sto cercando di beccarti o altro.
isaacg,

1
Nessun problema. Ho pensato che fosse qualcosa del genere. Mi hai aiutato molte volte prima. (E ho una profonda conoscenza del problema di Internet lenta.: P)
Dennis,

5

Julia, 189 145 byte

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)

Ciò crea una funzione senza nome che accetta un numero intero e restituisce un numero intero. Per chiamarlo, dagli un nome, ad es f=n->....

Ungolfed:

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

Grazie a Dennis per l'aiuto e le idee e grazie a Glen O per aver salvato 44 byte!


4

JavaScript ES6, 126 127

L'implementazione di riferimento, convertita in Javascript con qualche trucco da golf.

Utilizzo di eval per evitare il ritorno esplicito.

Prova a eseguire lo snippet di seguito in un browser compatibile con EcmaScript 6, con operatore di diffusione, parametri predefiniti e funzioni freccia (utilizzo 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>


3

JavaScript (ES6), 143 byte

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

Spiegazione

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
}

0

Lua, 148 byte

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)

È richiesto Lua 5.3

$ lua program.lua 1
7
$ lua program.lua 10
37
$ lua program.lua 100
487

0

Python 3, 283 243 byte

Questa è un'implementazione a forza bruta. Suggerimenti di golf benvenuti.

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

Ungolfed:

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
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.