Zwei Palindrome reichen nicht aus

24

Einige Zahlen, wie z. B. 14241 , sind Palindrome in Basis 10: Wenn Sie die Ziffern in umgekehrter Reihenfolge schreiben, erhalten Sie dieselbe Nummer.

Einige Zahlen sind die Summe von 2 Palindromen; Beispiel: 110=88+22 oder 2380=939+1441 .

Für andere Zahlen reichen 2 Palindrome nicht aus; Beispiel: 21 kann nicht als Summe von 2 Palindromen geschrieben werden. Das Beste, was Sie tun können, ist 3: 21=11+9+1 .

Schreiben Sie eine Funktion oder ein Programm, das eine Ganzzahleingabe annimmt nund die nth-Zahl ausgibt, die nicht als Summe von 2 Palindromen zerlegt werden kann. Dies entspricht OEIS A035137 .

Einzelne Ziffern (einschließlich 0) sind Palindrome.

Es gelten Standardregeln für Sequenzen:

  • Eingabe / Ausgabe ist flexibel
  • Sie können 0- oder 1-Indexierung verwenden
  • Sie können den ndritten oder den ersten Ausdruck noder eine unendliche Folge ausgeben

(Als Randnotiz: Alle ganzen Zahlen können als Summe von höchstens 3 Palindromen zerlegt werden .)

Testfälle (1-indiziert):

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

Das ist Code-Golf, also gewinnt die kürzeste Antwort.

Robin Ryder
quelle
2
Ist die unendliche Ausgabe nicht auch eine Standardoption für Sequenzen?
Unrelated String
@UnrelatedString Ja, das werde ich auch erlauben.
Robin Ryder
Related
Luis Mendo
2
@Abigail Bei einer positiven Ganzzahl nwird das n-te Mitglied der Sequenz OEIS An? Klingt vielversprechend ...
Val sagt Reinstate Monica
2
@Nit Definieren wir eine neue OEIS-Sequenz als (n) = die n-te OEIS-Sequenz, die in weniger Zeichen ausgedrückt werden kann als die am häufigsten verwendete Jelly-Funktion, die diese Sequenz generiert.
Am

Antworten:

13

JavaScript (ES6),  93 83 80  79 Byte

1 Byte dank @tsh gespeichert

Gibt den n ten Term mit einem Index zurück.

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

Probieren Sie es online!

Wie?

Mit n testen wir, ob 1kn so dass sowohl k als auch nk Palindrome sind. Wenn wir ein solches k , dann ist n die Summe von zwei Palindromen.

Der Trick dabei ist, k und nk gleichzeitig zu verarbeiten, indem eine einzelne Zeichenfolge getestet wird, die aus der Verkettung von k , nk und k .

Beispiel:

Für n=2380 :

  • wir erreichen schließlich k=1441 und nk=939
  • Wir testen die Zeichenfolge " 14419391441 " und stellen fest, dass es sich um ein Palindrom handelt

Kommentiert

NB: Dies ist eine Version ohne eval()für die Lesbarkeit.

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
quelle
i=>eval("for(n=k=1;k=(s=[...k+[n-k]+k])+''!=s.reverse()?k-1||i--&&++n:++n;);n")79 Bytes
tsh
Stattdessen i=>eval("...")können Sie mit ES6 i=>eval`...`2 Bytes sparen
VFDan,
Wenn keine Rückgabe angegeben ist, wird standardmäßig der letzte ausgewertete Ausdruck verwendet, sodass Sie den ;nam Ende stehenden entfernen können .
VFDan
@VFDan Der Back-Tick-Trick funktioniert nicht, eval()da er sein Argument nicht in eine Zeichenfolge umwandelt . Das Entfernen ;nwürde zu einem Syntaxfehler führen, und das Entfernen von nur nwürde die Funktion zurückgeben undefined.
Arnauld
12

Jelly ,  16 10  9 Bytes

-1 Byte danke an Erik den Outgolfer . Gibt die ersten n Terme aus.

2_ŒḂƇ⁺ṆƲ#

Probieren Sie es online!

Ich habe versucht, eine andere Idee zu entwickeln als ursprünglich. Lassen Sie uns den Denkprozess überprüfen:

  • Anfänglich funktionierte der Test wie folgt: Er erzeugte die ganzzahligen Partitionen dieser Zahl, filterte dann diejenigen heraus, die auch Nicht-Palindrome enthielten, und zählte dann, wie viele Listen mit der Länge 2 in Frage kamen. Dies war offensichtlich in Bezug auf die Codelänge nicht zu effizient.

  • Das Erzeugen der ganzzahligen Partitionen von N und das anschließende Filtern hatten zwei Hauptnachteile: Länge und Zeiteffizienz. Um dieses Problem zu lösen, dachte ich, ich werde zuerst eine Methode entwickeln, um nur zu generieren die Paare von ganzen Zahlen(x,y)zuN summieren(nicht alle Listen beliebiger Länge), mit der Bedingung, dass beide Zahlen palindrom sein müssen.

  • Trotzdem war ich mit der "klassischen" Vorgehensweise nicht zufrieden. Ich habe die Ansätze gewechselt: Anstatt Paare zu generieren , konzentrieren wir uns auf einzelne Palindrome . Auf diese Weise kann man einfach alle Palindrome x berechnenx untenN, und wennNx auch Palindrom ist, dann sind wir fertig.

Code-Erklärung

2_ŒḂƇ⁺ṆƲ # - Monadischer Link oder Volles Programm. Argument: n.
2 # - Ab 2 * finden Sie die ersten n Ganzzahlen, die ...
 _ŒḂƇ⁺ṆƲ - ... der Hilfslink. Aufschlüsselung (nennen Sie die aktuelle Ganzzahl N):
    Ƈ - Filter. Erstellt den Bereich [1 ... N] und behält nur die bei, die ...
  ŒḂ - ... sind Palindrome. Beispiel: 21 -> [1,2,3,4,5,6,7,8,9,11]
 _ - Subtrahiere jedes dieser Palindrome von N. Beispiel: 21 -> [20,19, ..., 12,10]
     ⁺ - Dupliziere den vorherigen Link (stelle es dir so vor, als gäbe es einen zusätzlichen ŒḂƇ
            statt ⁺). Dadurch bleiben nur die Palindrome in dieser Liste erhalten.
            Wenn die Liste nicht leer ist, bedeutet dies, dass wir ein Paar (x, Nx) gefunden haben
            enthält zwei Palindrome (und offensichtlich x + Nx = N, so dass sie zu N summieren).
      Ṇ - Logisches NICHT (wir suchen nach den ganzen Zahlen, für die diese Liste leer ist).
       Ʋ - Gruppieren Sie die letzten 4 Links (lassen Sie _ make im Grunde genommen als einzelne Monade agieren).

* Jede andere Ziffer, die nicht Null ist, funktioniert auch.

Mr. Xcoder
quelle
7

Jelly , 11 Bytes

⁵ŻŒḂ€aṚ$EƲ#

Probieren Sie es online!

Das vollständige Programm funktioniert ungefähr so:

  1. einstellen z auf den Eingang ein.
  2. Setze x auf 10 .
  3. Stellen Sie R auf [] .
  4. Prüfen Sie für jede ganze Zahl k von 0 bis einschließlich x , ob sowohl k als auch x - k palindrom sind.
  5. Wenn alle Elemente von L gleich sind (d. H. Wenn entweder alle möglichen Paare, die zu x summieren, beide Elemente palindromisch sind oder alle diese Paare höchstens eines ihrer Elemente palindromisch haben), setze z auf z - 1 und hänge x an bis R .
  6. Wenn z = 0 ist , kehre zurück R zurück und beende.
  7. Setze x auf x + 1 .
  8. Fahren Sie mit Schritt 4 fort.

Möglicherweise haben Sie den Verdacht, dass Schritt 5 nicht die Aufgabe erfüllt, die er erfüllen sollte. Wir sollten z wirklich nicht dekrementieren, wenn alle Paare diese Summe ergeben x palindrom sind. Wir können jedoch beweisen, dass dies niemals passieren wird:

k10kx 10 .

k(k,xk)k+(xk)=x , daher haben nicht alle Paare zwei Palindrome.

kk1kDFDLkDF=DL>0k1DFDLDL>0DL=DF-1DFk-1(k-1,x-(k-1)), woher (k1)+(x(k1))=k1+xk+1=x.

We conclude that, if we start with setting x to a value greater than or equal to 10, we can never have all pairs of non-negative integers that sum to x be pairs of palindromes.

Erik the Outgolfer
quelle
Ah, beat me too it - first n terms saves 1 byte (I went for STDIN and ŻŒḂ€aṚ$Ṁ¬µ#
Jonathan Allan
@JonathanAllan Oh LOL didn't expect that. Anyway, somebody beat us both. :D
Erik the Outgolfer
For the proof, couldn't you just take the pair (10,x10), and use the fact that 10 is not a palindrome? Then the proof is one line.
Robin Ryder
@RobinRyder Yes, that's also possible. My proof is a generalization that contains this case as well (11 is a palindrome).
Erik the Outgolfer
3

Retina, 135 102 bytes

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

Try it online! Too slow for n of 10 or more. Explanation:

K`0

Start off by trying 0.

"$+"{

Repeat n times.

0L$`\d+
*__

Convert the current trial value to unary and increment it.

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

Create all pairs of non-negative integers that sum to the new trial value.

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

Repeat while there exists at least one pair containing two palindromic integers.

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

Increment and expand the trial value again.

0L`\d+

Extract the final value.

Neil
quelle
3

Haskell, 68 67 63 bytes

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

Returns an infinite sequence.

Collect all n where either a or n-a is not a palindrome for all a <- [0..n].

Try it online!

nimi
quelle
3

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

-3 bytes thanks to @NahuelFouilleul

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

Try it online!

Note: any could be replaced by grep and avoid the -M command line switch, but under the current scoring rules, that would cost one more byte.

Xcali
quelle
small improvement, -3bytes, using while instead of redo
Nahuel Fouilleul
And took one more off of that by eliminating the + after the while.
Xcali
3

R, 115 111 bytes

-4 thanks to 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]

Try it online!

Most of the work is packed into the function arguments to remove the {} for a multi-statement function call, and to reduce the brackets needed in defining the object r

Basic strategy is to find all palindromes up to a given bound (including 0), find all pairwise sums, and then take the n-th number not in that output.

The bound of n*1000 was chosen purely from an educated guess, so I encourage anyone proving/disproving it as a valid choice.

r=0:(n*1e3)can probably be improved with a more efficient bound.

Map(paste,Map(rev,strsplit(a,"")),collapse="")is ripped from Mark's answer here, and is just incredibly clever to me.

r[!r%in%outer(p,p,'+')][n]reads a little inefficient to me.

CriminallyVulgar
quelle
1
111 bytes just by rearranging a couple things.
Giuseppe
1

J, 57/60 bytes

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

Try it online!

The linked version adds 3 bytes for a total of 60 in order to save as a function that the footer can call.

In the REPL, this is avoided by calling directly:

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

Explanation

The general structure is that of this technique from an answer by 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

This saved a few bytes over my original looping technique, but since the core function is my first attempt at writing J, there is likely still a lot that can be improved.

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
quelle
That's an old format of mine, combining other tricks I learned since then produces a 41 char solution: 1&(_:1&((e.((*&(-:|.)&":"0>:)&i.-))+])+)*
miles
1

05AB1E, 15 12 bytes

°ÝDʒÂQ}ãOKIè

-3 bytes thanks to @Grimy.

0-indexed.
Very slow, so times out for most test cases.

Try it online or verify the first few cases by removing the .

Much faster previous 15 byter version:

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

1-indexed.

Try it online or output the first n values.

Explanation:

°Ý              # 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
quelle
1
12: °LDʒÂQ}ãOKIè (there's probably a better upper bound than 10^x for speed). I guess ∞DʒÂQ}ãOK is technically a 9, but it times out before the first output.
Grimmy
@Grimy Not sure if cartesian product works lazy-loaded on infinite lists. Anyway, as for the 12-byter, it's unfortunately incorrect. It does filter out integers that can be formed by summing 2 palindromes, but not integers that are palindromes themselves. Your sequence (without the trailing ) goes like: [1,21,32,43,54,65,76,87,98,111,131,141,151,...] but is supposed to go like [*,21,32,43,54,65,76,87,98,201,1031,1041,1051,1052,...] (the first 1/* can be ignored since we use 1-indexed input).
Kevin Cruijssen
1
@Grimy Hmm, I guess a straight-forward fix is changing the 1-based list L to 0-based.. :)
Kevin Cruijssen
0

Red, 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]

Try it online!

Returns n-th term, 1-indexed

Galen Ivanov
quelle
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

Try it online!

Inverting the palindrome checking saved 2 bytes :)

For reference the straight forward positive check (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
quelle
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

Was ist das Wort für Break the Loop? Es scheint, es ist ": verlassen", richtig? {k≡⌽k←⍕⍵}in p ist der Test für Palindrom. Diese obige Funktion in der Schleife speichert das gesamte in der Menge P gefundene Palindrom. Wenn für ein Element w von P iw auch in P ist, bedeutet dies, dass das i nicht richtig ist und wir das Inkrement i haben. Ergebnisse:

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