Palindrome Reversal-Addition

19

Palindrome Reversal-Addition

Der Vorgang des Hinzufügens der Umkehrung ist der Vorgang, bei dem eine Zahl zur Umkehrung hinzugefügt wird, bis die erzeugte Zahl ein Palindrom ist. Wenn wir zum Beispiel mit 68 beginnen, wäre der Prozess:

68 + 86 => 154 + 451 => 605 + 506 => 1111

Wie Sie sehen, dauerte dies 3 Additionen, um zu einer palindromischen Zahl zu gelangen. Wenn wir anfangen 89würden, bräuchten wir 24 Stufen (die Sie hier sehen können ).

Der Weltrekord für die meisten Schritte, die unternommen wurden, bevor ein Palindrom erreicht wurde, liegt bei 261, was für die Zahl 1186060307891929990gilt und eine Zahl ergibt, die größer als 10 118 ist . Es gab jedoch einige Zahlen, für die wir kein Palindrom erhalten konnten. Diese werden Lychrel-Nummern genannt .

Da wir in Basis 10 arbeiten, können wir sie eigentlich nur als Kandidaten bezeichnen, da es keinen Beweis dafür gibt, dass diese Zahlen niemals ein Palindrom erreichen. Der kleinste Lychrel-Kandidat zur Basis 10 ist beispielsweise 196 und hat weit über eine Milliarde Iterationen durchlaufen. Wenn das Palindrom existiert, ist es viel größer als 10 10 8.77 . Wenn zum Vergleich so viele Einsen in Atome eingeschrieben wären, bräuchten wir 2.26772 × 10 588843575 Universen mit Atomen, um sie auszuschreiben, vorausgesetzt, sie existieren.

Deine Aufgabe

Erstellen Sie ein Programm oder eine Funktion, die eine Ganzzahleingabe akzeptiert und die Anzahl der Schritte ausgibt oder ausgibt, die zum Erreichen eines Palindroms erforderlich sind. Sie müssen sich nicht mit Lychrel-Kandidaten auseinandersetzen (dh Ihr Programm darf bei einem Lychrel-Kandidaten entweder einen Fehler auslösen oder für immer ausgeführt werden).

Testfälle:

                  f(0) => 0
                 f(11) => 0
                 f(89) => 24
                f(286) => 23
          f(196196871) => 45
         f(1005499526) => 109
f(1186060307891929990) => 261

Regeln

  1. Keine Standardlücken.

Boni

  1. Wenn Sie jeden formatierten Additionsschritt ausdrucken n + rev(n) = m, können Sie Ihre Punktzahl mit 0,75 multiplizieren . Die Summen sollten vor der Anzahl der Schritte ausgedruckt werden.
  2. Wenn Ihr Code erkennt, ob eine Zahl ein Lychrel-Kandidat ist, können Sie Ihre Punktzahl mit 0,85 multiplizieren . In diesem Fall ist es ausreichend anzunehmen, dass alles, was mehr als 261 Iterationen benötigt, ein Lychrel-Kandidat ist. Geben Sie entweder nichts zurück oder alles, was keine Zahl ist, die für eine korrekte Antwort gehalten werden kann (usw.: eine beliebige Zeichenfolge oder eine Zahl, die nicht im Bereich von 0 bis 261 liegt). Jeder Fehler zählt nicht als gültige Ausgabe (z. B. maximale Rekursionstiefe überschritten) und kann nicht für die Erkennung verwendet werden.
  3. Wenn Sie beide Boni erfüllen, multiplizieren Sie mit 0,6 .

Das ist , also gewinnt die geringste Anzahl von Bytes.


Dieses Code-Snippet zeigt eine Beispiellösung in Python 3 mit beiden Boni.

def do(n,c=0,s=''):
  m = str(n)
  o = m[::-1]
  if c > 261:
    return "Lychrel candidate"
  if m == o:
    print(s)
    return c
  else:
    d = int(m)+int(o)
    s+="%s + %s = %s"%(m,o,str(d))
    return do(d,c+1,s)
Kade
quelle
Related
Sp3000
1
Liegt der *0.6Bonus über den anderen? Oder ist es nur das?
Maltysen,
@Maltysen Nur die 0.6.
Kade,
Wenn die Summen ausdrucken sollten wir drucken 10 + 01 = 11oder 10 + 1 = 11oder ist es an uns?
Martin Ender
3
Kann ich für den Lychrel-Detektor ausdrucken 262?
Maltysen

Antworten:

8

Pyth, 12 Bytes

f_I`~+Qs_`Q0

Probieren Sie es online aus: Vorführ- oder Testgeschirr

Dies verwendet eine ziemlich neue Funktion (nur 17 Stunden alt).

Erläuterung

               implicit: Q = input number
f          0   repeat the following expression until it 
               evaluates to true and return the number of steps
         `Q       convert Q to string
        _         reverse the digits
       s          convert to int
     +Q           add Q
    ~             assign the result to Q
                  (this returns the old value of Q)
   `              convert the old value of Q to a string
 _I               and check if it's invariant under the operation reverse

bearbeiten:

Der Code wurde ein wenig geändert. Die alte Version war

fqKs_`Q~+QK0

Gleiche Byteanzahl, aber die neue ist viel cooler.

Jakube
quelle
Boni bei einer Punktzahl von 12. Viel Glück!
Dennis
@ Tennis Ihr Recht. Das war eine lächerliche Absicht. Das beste, was ich habe, ist 13.6 mit der Lychrel-Erkennung.
Jakube,
14

Python, 51

def f(n):r=int(str(n)[::-1]);return n-r and-~f(n+r)

Bei Python 2 können Backticks nicht ersetzt werden, str()da sie Lan longLiterale gebunden sind .

Hier ist eine alternative Version mit der Punktzahl 64 * 0,85 = 54,4 :

def f(n,c=262):r=int(str(n)[::-1]);return c*(n-r)and-~f(n+r,c-1)

Und eine alternative Version für Python 3 mit 88 * 0,6 = 52,8 :

def f(n,c=262):r=int(str(n)[::-1]);return c*(n-r)and-~f(n+r,print(n,'+',r,'=',n+r)or~-c)
Mitch Schwartz
quelle
1
Das ist einfach verrückt .. nette Arbeit!
Kade,
6

CJam, 23 22 20,4 Bytes

ri{__sW%i+}261*]{s_W%=}#

Der Code ist 24 Byte lang und gibt -1 für Lychrel-Kandidaten aus.

Probieren Sie es online aus.

Wie es funktioniert

ri                       e# Read an integer from STDIN.
  {       }261*          e# Do the following 261 times:
   __                    e#   Push two copies of the integer on the stack.
     sW%i                e#   Cast to string, reverse and cast back to integer.
         +               e#   Add the copy and the reversed copy of the integer.
               ]         e# Wrap all 262 results in an array.
                {     }# e# Push the index of the first element such that:
                 s       e#   The string representation equals...
                  _W%=   e#   the reversed string representation.

Wenn {}#erfolgreich, ist der Index auch die Anzahl der Schritte. Wenn das Array hingegen kein Palindrom enthält, {}#wird -1 gedrückt .

Dennis
quelle
5

Java, 200 × 0,6 = 120

import java.math.*;int f(BigInteger a){int s=-1;for(String b,c;(b=a+"").equals(c=new StringBuffer(b).reverse()+"")!=s++<999;)System.out.println(b+" + "+c+" = "+(a=a.add(new BigInteger(c))));return s;}

Dies ist eine einfache Schleife, die genau das tut, was auf der Schachtel steht, aber mit ein bisschen Golf. Kehrt 1000für Lychrel-Kandidaten zurück, um den Erkennungsbonus zu erhalten. Es stellte sich heraus, dass ich nicht zu viele Zeichen drucken konnte (zumindest für Java) und mir diesen Bonus auch schnappte. Das Beste, was ich ohne Bonuscode machen konnte, war 156, es hat sich also gelohnt.

Mit einigen Zeilenumbrüchen:

import java.math.*;
int f(BigInteger a){
    int s=-1;
    for(String b,c;(b=a+"").equals(c=new StringBuffer(b).reverse()+"")!=s++<999;)
        System.out.println(b+" + "+c+" = "+(a=a.add(new BigInteger(c))));
    return s;
}

Alte Antwort: 171 * 0,85 = 145,35 Bytes

import java.math.*;int f(BigInteger a){int s=-1;for(String b,c;(b=a+"").equals(c=new StringBuffer(b).reverse()+"")!=s++<262;)a=a.add(new BigInteger(c));return s>261?-1:s;}

Geobits
quelle
Ich schätze, Sie haben daran gearbeitet, während es noch in der Sandbox war: P Ich überdenke die Bonusbeträge, da ich selbst in Python (einer relativ prägnanten Sprache im Vergleich zu C # / Java) festgestellt habe, dass die Boni nicht helfen. Ich denke, ich werde es relativ zur Länge des Programms machen, damit Golfsprachen nicht mit einem Score von <10 Byte enden.
Kade,
Ich habe die Bonusregeln aktualisiert, sodass Ihre neue Punktzahl 145,35 beträgt :)
Kade
Speichern Sie ein Byte, entfernen Sie das Semikolon am Ende der zur Definition, es ist nicht erforderlich, also nachs++<999
Christopher Wirt
@ChristopherWirt In welchem ​​Compiler / welcher Version? Meins gibt einen Syntaxfehler ohne.
Geobits
5

Rubin, (80 + 2) * 0,6 = ~ 49,2

Mit Fahnen -nllaufen

p (0..261).find{$_[b=$_.reverse]||puts($_+' + '+b+' = '+$_="#{$_.to_i+b.to_i}")}

Die Ausgabe sieht aus wie

 $ ruby -nl lychrel.rb 
89
89 + 98 = 187
187 + 781 = 968
968 + 869 = 1837
1837 + 7381 = 9218
9218 + 8129 = 17347
17347 + 74371 = 91718
91718 + 81719 = 173437
173437 + 734371 = 907808
907808 + 808709 = 1716517
1716517 + 7156171 = 8872688
8872688 + 8862788 = 17735476
17735476 + 67453771 = 85189247
85189247 + 74298158 = 159487405
159487405 + 504784951 = 664272356
664272356 + 653272466 = 1317544822
1317544822 + 2284457131 = 3602001953
3602001953 + 3591002063 = 7193004016
7193004016 + 6104003917 = 13297007933
13297007933 + 33970079231 = 47267087164
47267087164 + 46178076274 = 93445163438
93445163438 + 83436154439 = 176881317877
176881317877 + 778713188671 = 955594506548
955594506548 + 845605495559 = 1801200002107
1801200002107 + 7012000021081 = 8813200023188
24

Bei Angabe von 196 werden die ersten 261 Additionsschritte und dann gedruckt nil.

Hier ist nichts zu schwierig. Wir prüfen, ob $_(was für die Eingabe initialisiert wird) die Umkehrung enthält, was nur möglich ist, wenn sie gleich sind, da sie die gleiche Größe haben. Wenn dies der Fall ist, drucken wir die Schrittnummer und beenden den Vorgang. Andernfalls zeigen wir den Additionsschritt an und führen ihn aus, wobei der neue Wert in gespeichert wird $_(ich kann leider nicht nur evaldie angezeigte Zeichenfolge, da sie eine umgekehrte Zahl mit einer nachgestellten 0 interpretiert als oktales Literal). putsGibt einen falschen Wert zurück, sodass die Schleife fortgesetzt wird.

Histokrat
quelle
" + #{b} = "Speichert ein Byte.
Mitch Schwartz
Und es scheint innerhalb der Regeln, die zu -llöschen, wenn wir die Nummer in eine Datei ohne abschließende Zeilenumbruch setzen und es in Pipe?
Mitch Schwartz
4

Pyth - 19 Bytes

Verwendet while-Schleife und einen Zähler. Es gibt wahrscheinlich einen kleineren Algorithmus als diesen, aber dieser ist ziemlich kurz.

Wnz_z=z`+szs_z=hZ;Z

Probieren Sie es hier online aus .

Maltysen
quelle
Sehr klein! Gut gemacht :)
Kade
4

K, 25 Bytes

#1_{~x~|x}{$. x,"+",|x}\$

Nicht sehr elegant. Die Gesamtform ( {monad 1}{monad 2}\x) ist Ks Äquivalent zu einer allgemeinen "while" -Schleife, bei der die erste Monade die Haltebedingung und die zweite eine iterativ auf das Argument angewendete Funktion ist x. Die erste Monade ( {~x~|x}) ist die Negation der klassischen Phrase "ist xa Palindrom". Die zweite Monade verkettet einen String, der x plus die Umkehrung von x darstellt, wertet ihn aus und wandelt das Ergebnis dann zurück in einen String mit $.

Ein Probelauf mit Zwischenergebnissen:

  {~x~|x}{$. x,"+",|x}\$68
("68"
 "154"
 "605"
 "1111")

Eine formatierte Ausgabe, wie für den Bonus angefordert, wäre sehr umständlich und würde eine erhebliche Menge an Code hinzufügen.

JohnE
quelle
4

CJam, 23 Bytes

Wl{\)\__W%_@#\i@i+s\}g;

Noch ein paar Tage bis CJam, also bin ich ziemlich froh, zumindest in der gleichen Reichweite zu sein wie einige der Profis. :) Ich habe Martins Stringvergleichstrick verwendet, den er auch in den CJam-Hinweisen gepostet hat. Ich habe mir auch Dennis 'Lösung angesehen, um herauszufinden, wie man eine Saite umkehrt.

Erläuterung:

W    Initialize counter, will keep this at bottom of stack.
     Start counting at -1 because the counter will be incremented in the
     last pass through the loop, when the palindrome is detected.
l    Get input.
{    Start block of while loop.
\)\  Increment counter. Need to swap before/after because it's one below top of stack.
__   Copy current value twice. Need 3 copies in total:
       * one for reversal
       * one for comparison
       * one for addition with reverse
W%   Reverse value.
_    Copy the reverse value once because we need 2 copies:
       * one for comparison
       * one for addition with original value
@    Rotate one copy of original value to top.
#    Test for non-equality with reverse, using Martin's trick.
\i   Swap reverse value to top, and convert it to int.
@i   Rotate remaining copy of original value to top, and convert it to int.
+s   Add the values, and convert result to string.
\    Swap, so that comparison result is at top of stack for while loop test.
}g   End of while loop.
;    Current value sits at top of stack. Pop it, leaving only counter.

Testen Sie es online

Reto Koradi
quelle
4

Julia, 129 120 Bytes * 0,6 = 72

i->(i=big(i);n=0;d=digits;while d(i)!=reverse(d(i))&&n<262 t=BigInt(join(d(i)));println(i," + ",t," = ",i+=t);n+=1end;n)

Dadurch wird eine unbenannte Funktion erstellt, die eine Ganzzahl als Eingabe verwendet und eine Ganzzahl zurückgibt, während jeder Schritt gedruckt wird. Lychrel-Kandidaten haben einen Rückgabewert von 262. Um dies zu nennen, geben Sie ihm einen Namen, zf=i->... .

Beachten Sie, dass diese Lösung ohne Code, der sich nur auf die Boni bezieht, 84 Byte beträgt.

Ungolfed + Erklärung:

function f(i)
    # Convert the input to a big integer
    i = big(i)

    # Initialize a step counter to 0
    n = 0

    # While the number is not a palindrome and we haven't exceeded 261 steps...
    while digits(i) != reverse(digits(i)) && n < 262

        # Get the reverse of the integer
        # Note that we aren't using reverse(); this is because digits()
        # returns an array of the digits in reverse order.
        t = BigInt(join(digits(i)))

        # Print the step and increment i
        println(i, " + ", t, " = ", i += t)

        # Count the step
        n += 1
    end

    # Return the number of steps or 262 for Lychrel candidates
    n
end

Beispiele:

julia> f(286)
286 + 682 = 968
968 + 869 = 1837
1837 + 7381 = 9218
9218 + 8129 = 17347
17347 + 74371 = 91718
91718 + 81719 = 173437
173437 + 734371 = 907808
907808 + 808709 = 1716517
1716517 + 7156171 = 8872688
8872688 + 8862788 = 17735476
17735476 + 67453771 = 85189247
85189247 + 74298158 = 159487405
159487405 + 504784951 = 664272356
664272356 + 653272466 = 1317544822
1317544822 + 2284457131 = 3602001953
3602001953 + 3591002063 = 7193004016
7193004016 + 6104003917 = 13297007933
13297007933 + 33970079231 = 47267087164
47267087164 + 46178076274 = 93445163438
93445163438 + 83436154439 = 176881317877
176881317877 + 778713188671 = 955594506548
955594506548 + 845605495559 = 1801200002107
1801200002107 + 7012000021081 = 8813200023188
23

julia> f(1186060307891929990)
(steps omitted)
261

julia> f(196)
(steps omitted)
262

julia> f(11)
0

2 Bytes gespart dank Geobits!

Alex A.
quelle
4

CJam, 24 Bytes

0q{__W%#}{_W%~\~+s\)\}w;

Teste es hier.

Erläuterung

0q     e# Push a zero (the counter) and read input.
{      e# While this block leaves something truthy on the stack...
  __   e#   Make two copies of the current number (as a string).
  W%   e#   Reverse the second copy.
  #    e#   Check that they are not equal.
}{     e# ... run this block.
  _W%  e#   Make a copy of the current number and reverse it.
  ~\~  e#   Evaluate both N and its reverse.
  +s   e#   Add them and turn the sum into a string.
  \)\  e#   Pull up the counter, increment it, and push it back down again.
}w
;      e# Discard the palindrome to leave the counter on the stack.

In diesem Tipp finden Sie weitere Informationen dazu, warum #die String-Ungleichheit überprüft werden kann .

Martin Ender
quelle
Ihre Antwort wurde vor dem Posten nicht angezeigt. Das ist eine kluge Verwendung von #.
Dennis
2

Haskell, 66 53 Bytes

r=reverse.show
f x|show x==r x=0|1<2=1+f(x+read(r x))

Anwendungsbeispiel:

*Main> map f [0,11,89,286,196196871,1005499526,1186060307891929990]
[0,0,24,23,45,109,261]
nimi
quelle
Ich habe Haskell noch nie benutzt, aber könnten Sie das tun r=reverse x? Das würde Ihre zweite Zeile in ändern f x|x==r=0|1<2=1+f(show$read x+read(r))und 2 Bytes sparen.
Kade,
@ Vioz-: Nein, das ist nicht möglich, da xwäre es nicht im Umfang. Allerdings f x|x==r=0 .... read(r)) where r=reverse xfunktionieren würde, aber es ist mehr.
Nimi
2

Clojure, 94 Bytes

(fn[x](#(let[r(bigint(apply str(reverse(str %1))))] (if(= %1 r)%2(recur(+ %1 r)(inc %2))))x 0))

Dies ist mein erster Versuch, Golf zu codieren. Bitte sagen Sie mir, wenn ich etwas falsch mache.

Mit einigen Leerzeichen:

(fn [x]
(#(let [r (bigint (apply str (reverse (str %1))))]
  (if (= %1 r) %2 (recur (+ %1 r) (inc %2)))) x 0))

Einfache Rekursion der inneren Funktion. Es werden zwei Argumente benötigt, die Ganzzahl %1und ein Index %2. Ob%1 es sich um ein Palindrom handelt, wird der Index zurückgegeben. Ansonsten ruft sich die Funktion mit der Summe und dem inkrementierten Index auf. Die äußere Funktion initialisiert den Index mit Null.

Eine Probe:

repl=> ((fn[x](#(let[r(bigint(apply str(reverse(str %1))))](if(= %1 r)%2(recur(+ %1 r)(inc %2))))x 0)) 1186060307891929990)
261
max0r
quelle
1

Boost.Build, 304 Bytes

Nicht wirklich eine Sprache. Trotzdem cool.

import sequence ;
import regex ;
rule r ( n ) {
m = "([0-9]?)" ;
return [ sequence.join [ sequence.reverse [ regex.match "$(m)$(m)$(m)$(m)$(m)$(m)$(m)$(m)$(m)" : $(n) ] ] : "" ] ;
}
rule x ( n ) {
i = 0 ;
while $(n) != [ r $(n) ] {
n = [ CALC $(n) + [ r $(n) ] ] ;
i = [ CALC $(i) + 1 ] ;
}
echo $(i) ;
}

Ganz einfach, abgesehen von dem ausgeklügelten, auf Regex basierenden Hack, mit dem ich die Saite umgedreht habe.

kirbyfan64sos
quelle
1

Rubin, 44

f=->n{n==(r=n.to_s.reverse.to_i)?0:f[n+r]+1}

Benötigt Ruby 1.9 oder höher für die ->Lambda-Syntax.

Mitch Schwartz
quelle