Dos palíndromos no son suficientes

24

Algunos números, como 14241 , son palíndromos en la base 10: si escribe los dígitos en orden inverso, obtiene el mismo número.

Algunos números son la suma de 2 palíndromos; por ejemplo, 110=88+22 , o 2380=939+1441 .

Para otros números, 2 palíndromos no son suficientes; por ejemplo, 21 no puede escribirse como la suma de 2 palíndromos, y lo mejor que puede hacer es 3: 21=11+9+1 .

Escriba una función o programa que tome la entrada entera ny genere el nnúmero th que no puede descomponerse como la suma de 2 palíndromos. Esto corresponde a OEIS A035137 .

Los dígitos individuales (incluido 0) son palíndromos.

Se aplican reglas estándar para secuencias:

  • entrada / salida es flexible
  • puede usar 0- o 1- indexación
  • puede generar el ntérmino th, o los primeros ntérminos, o una secuencia infinita

(Como nota al margen: todos los enteros se pueden descomponer como la suma de como máximo 3 palíndromos).

Casos de prueba (1 indexado):

1 -> 21
2 -> 32
10 -> 1031
16 -> 1061
40 -> 1103

Este es el código de golf, por lo que gana la respuesta más corta.

Robin Ryder
fuente
2
¿No es la salida infinita también una opción estándar para secuencias?
Cadena no relacionada
@UnrelatedString Sí, lo permitiré también.
Robin Ryder
Relacionado
Luis Mendo
2
@Abigail Dado un entero positivo n, imprime el enésimo miembro de la secuencia OEIS An? Suena prometedor ...
Val dice Reinstate Monica
2
@Nit definamos una nueva secuencia OEIS como a (n) = la enésima secuencia OEIS que puede expresarse en menos caracteres que la función Jelly más desarrollada que genera esa secuencia.
agtoever

Respuestas:

13

JavaScript (ES6),  93 83 80  79 bytes

Guardado 1 byte gracias a @tsh

Devuelve el n º plazo, 1-indexados.

i=>eval("for(n=k=1;k=(a=[...k+[n-k]+k])+''!=a.reverse()?k-1||--i&&++n:++n;);n")

Pruébalo en línea!

¿Cómo?

Dado n , probamos si existe 1kn manera que tanto k como nk sean palíndromos. Si encontramos tal k , entonces n es la suma de dos palíndromos.

El truco aquí es procesar k y nk al mismo tiempo probando una sola cadena hecha de la concatenación de k , nk y k .

Ejemplo:

Para n=2380 :

  • finalmente llegar a k=1441 y nk=939
  • probamos la cadena " 14419391441 " y descubrimos que es un palíndromo

Comentado

NB: Esta es una versión sin eval()legibilidad.

i => {                       // i = index of requested term (1-based)
  for(                       // for loop:
    n = k = 1;               //   start with n = k = 1
    k =                      //   update k:
      ( a =                  //     split and save in a[] ...
        [...k + [n - k] + k] //     ... the concatenation of k, n-k and k
      ) + ''                 //     coerce it back to a string
      != a.reverse() ?       //     if it's different from a[] reversed:
        k - 1                //       decrement k; if the result is zero:
          || --i             //         decrement i; if the result is not zero:
            && ++n           //           increment n (and update k to n)
                             //         (otherwise, exit the for loop)
      :                      //     else:
        ++n;                 //       increment n (and update k to n)
  );                         // end of for
  return n                   // n is the requested term; return it
}                            //
Arnauld
fuente
i=>eval("for(n=k=1;k=(s=[...k+[n-k]+k])+''!=s.reverse()?k-1||i--&&++n:++n;);n")79 bytes
tsh
En lugar de i=>eval("..."), ES6 le permite usar i=>eval`...`, ahorrando 2 bytes
VFDan
Además, si no se especifica ningún retorno, eval se predetermina a la última expresión evaluada, por lo que puede eliminarla ;nal final.
VFDan
@VFDan El truco de retroceso no funciona eval()porque no obliga su argumento a una cadena. Eliminar eliminaría ;nun error de sintaxis y eliminar solon la función undefined.
Arnauld
12

Jalea ,  16 10  9 bytes

-1 byte gracias a Erik the Outgolfer . Emite los primeros n términos.

2_ŒḂƇ⁺ṆƲ#

Pruébalo en línea!

Traté de tener una idea diferente en comparación con mi enfoque original. Repasemos el proceso de pensamiento:

  • Inicialmente, la prueba funcionó de la siguiente manera: generó las particiones enteras de ese número, luego filtró las que también contenían no palíndromos, luego contó cuántas listas elegibles para longitud 2 había. Obviamente, esto no era demasiado eficiente en términos de longitud del código.

  • Generar las particiones enteras de N y luego filtrar tenía 2 desventajas principales: eficiencia de duración y tiempo. Para resolver ese problema, pensé que primero se me ocurriría un método para generar solo los pares de enteros (x,y) que sumen N (no todas las listas de longitud arbitraria) con la condición de que ambos números deben ser palíndromos.

  • Pero aún así, no estaba satisfecho con la "forma clásica" de hacer esto. Cambié los enfoques: en lugar de generar pares , hagamos que el programa se centre en palíndromos individuales . De esta manera, uno simplemente puede calcular todos los palíndromos x debajo de N , y si Nx también es palíndromo, entonces hemos terminado.

Explicación del Código

2_ŒḂƇ⁺ṆƲ # - Enlace monádico o programa completo. Argumento: n.
2 # - Comenzando en 2 * , encuentre los primeros n enteros que satisfagan ...
 _ŒḂƇ⁺ṆƲ - ... el enlace de ayuda. Desglose (llame al entero actual N):
    Ƈ - Filtro. Crea el rango [1 ... N] y solo mantiene aquellos que ...
  ŒḂ - ... son palíndromos. Ejemplo: 21 -> [1,2,3,4,5,6,7,8,9,11]
 _ - Resta cada uno de esos palíndromos de N. Ejemplo: 21 -> [20,19, ..., 12,10]
     ⁺ - Duplicar el enlace anterior (piense en ello como si hubiera un additional adicional
            en lugar de ⁺). Esto solo mantiene los palíndromos en esta lista.
            Si la lista no está vacía, eso significa que hemos encontrado un par (x, Nx) que
            contiene dos palíndromos (y obviamente x + Nx = N, por lo que suman N).
      Ṇ - NO lógico (estamos buscando los enteros para los que esta lista está vacía).
       Ʋ - Agrupe los últimos 4 enlaces (básicamente haga que _ŒḂƇ⁺Ṇ actúe como una sola mónada).

* Cualquier otro dígito distinto de cero funciona, para el caso.

Sr. Xcoder
fuente
7

Jalea , 11 bytes

⁵ŻŒḂ€aṚ$EƲ#

Pruébalo en línea!

El programa completo funciona más o menos así:

  1. Establezca z en la entrada.
  2. Establezca x en 10 .
  3. Establezca R en [] .
  4. Para cada número entero k desde 0 hasta x inclusive , verifique si k y x - k son palindrómicas.
  5. Si todos los elementos de L son iguales (es decir, si todos los pares posibles que suman x tienen ambos elementos palindrómicos, o todos estos pares tienen como máximo uno de sus elementos ser palindrómicos), establezca z en z - 1 y agregue x a R .
  6. Si z = 0 , devuelve R y finaliza.
  7. Establezca x en x + 1 .
  8. Ve al paso 4.

Puede sospechar que el paso 5 en realidad no hace el trabajo que debería. Realmente no deberíamos disminuir z si todos los pares que suman x son palindrómicos. Sin embargo, podemos demostrar que esto nunca sucederá:

k10kx

k(k,xk)k+(xk)=x

kk1kDFDLkDF=DL>0k1DFDLDL>0DL=DF1DFk1(k1,x(k1))(k1)+(x(k1))=k1+xk+1=x

Llegamos a la conclusión de que, si comenzamos estableciendo x en un valor mayor o igual a 10 , nunca podremos tener todos los pares de enteros no negativos que sumen a x sean pares de palíndromos.

Erik el Outgolfer
fuente
Ah, se me adelantó también que - n primeros términos ahorra 1 byte (fui para STDIN yŻŒḂ€aṚ$Ṁ¬µ#
Jonathan Allan
@JonathanAllan Oh, LOL no esperaba eso. De todos modos, alguien nos ganó a los dos. : D
Erik the Outgolfer
(10,X-10)10
11
3

Retina , 135102 bytes

K`0
"$+"{0L$`\d+
*__
L$`
<$.'>$.`>
/<((.)*.?(?<-2>\2)*(?(2)$)>){2}/{0L$`\d+
*__
))L$`
<$.'>$.`>
0L`\d+

Pruébalo en línea! Demasiado lento para n10 o más. Explicación:

K`0

Comience probando 0.

"$+"{

Repite nveces.

0L$`\d+
*__

Convierta el valor de prueba actual en unario e increméntelo.

L$`
<$.'>$.`>

Cree todos los pares de enteros no negativos que sumen el nuevo valor de prueba.

/<((.)*.?(?<-2>\2)*(?(2)$)>){2}/{

Repita mientras exista al menos un par que contenga dos enteros palindrómicos.

0L$`\d+
*__
))L$`
<$.'>$.`>

Incremente y expanda el valor de prueba nuevamente.

0L`\d+

Extraer el valor final.

Neil
fuente
3

Haskell, 68 67 63 bytes

[n|n<-[1..],and[p a||p(n-a)|a<-[0..n]]]
p=((/=)=<<reverse).show

Devuelve una secuencia infinita.

Recoge todo ndonde sea ao n-ano sea un palíndromo para todos a <- [0..n].

Pruébalo en línea!

nimi
fuente
3

Perl 5 -MList::Util=any -p , 59 55 bytes

-3 bytes gracias a @NahuelFouilleul

++$\while(any{$\-reverse($\-$_)==reverse}0..$\)||--$_}{

Pruébalo en línea!

Nota: anypodría reemplazarse grepy evitar el -Mcambio de línea de comando, pero según las reglas de puntuación actuales, eso costaría un byte más.

Xcali
fuente
pequeña mejora, -3bytes , usando while en lugar de rehacer
Nahuel Fouilleul
Y tomé uno más de eso al eliminar el +después del while.
Xcali
3

R , 115 111 bytes

-4 gracias a Giuseppe

function(n,r=0:(n*1e3))r[!r%in%outer(p<-r[Map(Reduce,c(x<-paste0),Map(rev,strsplit(a<-x(r),"")))==a],p,'+')][n]

Pruébalo en línea!

La mayor parte del trabajo se empaqueta en los argumentos de la función para eliminar la {}llamada a una función de varias instrucciones y para reducir los corchetes necesarios para definir el objetor

La estrategia básica es encontrar todos los palíndromos hasta un límite dado (incluido 0), encontrar todas las sumas por pares y luego tomar el enésimo número que no está en esa salida.

El límite de n*1000fue elegido exclusivamente por una suposición educada, por lo que animo a cualquiera que lo pruebe / refute como una opción válida.

r=0:(n*1e3)Probablemente se puede mejorar con un límite más eficiente.

Map(paste,Map(rev,strsplit(a,"")),collapse="")está arrancado de la respuesta de Mark aquí , y es increíblemente inteligente para mí.

r[!r%in%outer(p,p,'+')][n]lee un poco ineficiente para mí.

Criminalmente vulgar
fuente
1
111 bytes simplemente reorganizando un par de cosas.
Giuseppe
1

J , 57/60 bytes

0(](>:^:(1&e.p e.]-p=:(#~(-:|.)&":&>)&i.&>:)^:_)&>:)^:[~]

Pruébalo en línea!

La versión vinculada agrega 3 bytes para un total de 60 para guardar como una función que el pie de página puede llamar.

En REPL, esto se evita llamando directamente:

   0(](>:^:(1 e.q e.]-q=:(#~(-:|.)&":&>)&i.&>:)^:_)&>:)^:[~] 1 2 10 16 40
21 32 1031 1061 1103

Explicación

La estructura general es la de esta técnica a partir de una respuesta de Miles :

(s(]f)^:[~]) n
          ]  Gets n
 s           The first value in the sequence
         ~   Commute the argument order, n is LHS and s is RHS
        [    Gets n
      ^:     Nest n times with an initial argument s
  (]f)         Compute f s
         Returns (f^n) s

Esto ahorró algunos bytes sobre mi técnica de bucle original, pero dado que la función principal es mi primer intento de escribir J, es probable que todavía haya muchas cosas que puedan mejorarse.

0(](>:^:(1&e.p e.]-p=:(#~(-:|.)&":&>)&i.&>:)^:_)&>:)^:[~]
0(]                                                 ^:[~] NB. Zero as the first term switches to one-indexing and saves a byte.
   (>:^:(1&e.p e.]-p=:(#~(-:|.)&":&>)&i.&>:)^:_)&>:)      NB. Monolithic step function.
                                                 >:       NB. Increment to skip current value.
   (>:^: <predicate>                        ^:_)          NB. Increment current value as long as predicate holds.
                   p=:(#~(-:|.)&":&>)&i.&>:               NB. Reused: get palindromes in range [0,current value].
                       #~(-:|.)&":&>                      NB. Coerce to strings keeping those that match their reverse.
                 ]-p                                      NB. Subtract all palindromes in range [0,current value] from current value.
    >:^:(1&e.p e.]-p                                      NB. Increment if at least one of these differences is itself a palindrome.
0xfordcomma
fuente
Ese es un formato antiguo mío, que combina otros trucos que aprendí desde entonces produce una solución de 41 caracteres:1&(_:1&((e.((*&(-:|.)&":"0>:)&i.-))+])+)*
millas
1

05AB1E , 15 12 bytes

°ÝDʒÂQ}ãOKIè

-3 bytes gracias a @Grimy .

0 indexado.
Muy lento, por lo que se agota el tiempo de espera para la mayoría de los casos de prueba.

Pruébelo en línea o verifique los primeros casos eliminando el .

Versión anterior de 15 bytes mucho más rápida:

µNÐLʒÂQ}-ʒÂQ}g_

1 indexado.

Pruébelo en línea o envíe el primeronortelos valores .

Explicación:

°Ý              # Create a list in the range [0, 10**input]
  D             # Duplicate this list
   ʒÂQ}         # Filter it to only keep palindromes
       ã        # Take the cartesian product with itself to create all possible pairs
        O       # Sum each pair
         K      # Remove all of these sums from the list we duplicated
          Iè    # Index the input-integer into it
                # (after which the result is output implicitly)

µ               # Loop until the counter variable is equal to the (implicit) input-integer
 NÐ             #  Push the loop-index three times
   L            #  Create a list in the range [1, N] with the last copy
    ʒÂQ}        #  Filter it to only keep palindromes
        -       #  Subtract each from N
         ʒÂQ}   #  Filter it again by palindromes
             g_ #  Check if the list is empty
                #   (and if it's truthy: increase the counter variable by 1 implicitly)
                # (after the loop: output the loop-index we triplicated implicitly as result)
Kevin Cruijssen
fuente
1
12: °LDʒÂQ}ãOKIè(probablemente hay un límite superior mejor que 10 ^ x para la velocidad). Supongo ∞DʒÂQ}ãOKque técnicamente es un 9, pero se agota antes de la primera salida.
Grimmy
@Grimy No estoy seguro si el producto cartesiano funciona con carga lenta en infinitas listas. De todos modos, en cuanto al 12-byter, desafortunadamente es incorrecto. Filtra enteros que se pueden formar sumando 2 palíndromos, pero no enteros que son palíndromos. Su secuencia (sin el final ) es como: [1,21,32,43,54,65,76,87,98,111,131,141,151,...]pero se supone que debe ser como [*,21,32,43,54,65,76,87,98,201,1031,1041,1051,1052,...](la primera 1/ *puede ignorarse ya que usamos una entrada indexada 1).
Kevin Cruijssen
1
@Grimy Hmm, supongo que una solución directa está cambiando la lista basada Len 1 a 0 .. :)
Kevin Cruijssen
0

Rojo , 142 bytes

func[n][i: 1 until[i: i + 1 r: on repeat k i[if all[(to""k)= reverse
to""k(s: to""i - k)= reverse copy s][r: off break]]if r[n: n - 1]n < 1]i]

Pruébalo en línea!

Devuelve el enésimo término, 1 indexado

Galen Ivanov
fuente
0

Python 3 , 107 bytes

p=lambda n:str(n)!=str(n)[::-1]
def f(n):
 m=1
 while n:m+=1;n-=all(p(k)+p(m-k)for k in range(m))
 return m

Pruébalo en línea!

Invertir la comprobación de palíndromo guardado 2 bytes :)

Como referencia, la verificación positiva directa (109 bytes):

p=lambda n:str(n)==str(n)[::-1]
def f(n):
 m=1
 while n:m+=1;n-=1-any(p(k)*p(m-k)for k in range(m))
 return m
movatica
fuente
0

APL (NARS), 486 bytes

r←f w;p;i;c;P;m;j
p←{k≡⌽k←⍕⍵}⋄i←c←0⋄P←r←⍬
:while c<w
    i+←1
    :if   p i⋄P←P,i⋄:continue⋄:endif
    m←≢P⋄j←1
    :while j≤m
         :if 1=p i-j⊃P⋄:leave⋄:endif
         j+←1
    :endwhile
    :if j=m+1⋄c+←1⋄r←i⋄:endif
:endwhile

¿Cuál es la palabra para romper el bucle? Parece que es ": vete", ¿verdad? {k≡⌽k←⍕⍵}en p es la prueba para palíndromo. Esta función anterior en el bucle almacena todo el palíndromo encontrado en el conjunto P, si para algún elemento w de P es tal que iw también está en P, esto significa que i no es correcto y tenemos un incremento i. Resultados:

  f 1
21
  f 2
32
  f 10
1031
  f 16
1061
  f 40
1103
  f 1000
4966
  f 1500
7536
RosLuP
fuente