Palindrome Ters Çevirme-Ekleme


19

Palindrome Ters Çevirme-Ekleme

Tersine Ekleme işlemi, oluşturulan sayı bir palindrom olana kadar bir sayının tersine eklendiği yerdir. Örneğin, 68 ile başlasak süreç şöyle olur:

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

Gördüğünüz gibi, bu palindromik bir sayıya ulaşmak için 3 ek aldı. Eğer başlasaydık89 olsaydık, 24 adıma ihtiyacımız olurdu (buradaki dökümü görebilirsiniz ).

Bir palindroma ulaşılmadan önce atılan en fazla adım için dünya rekoru 261'dir ve sayı için meydana gelir ve 118606030789192999010 118'den büyük bir sayı üretir . Ancak, bir palindrom alamadığımız oldukça az sayı var. Bunlara denir Lychrel numaraları .

Temel 10'da çalıştığımız için onlara sadece aday diyebiliriz, çünkü bu sayıların asla bir palindrom'a ulaşmadığına dair bir kanıt yoktur. Örneğin, en küçük baz-10 Lychrel adayı 196'dır ve bir milyardan fazla yinelemeden geçti. Palindrom varsa, 10 10 8.77'den çok daha büyüktür . Karşılaştırma olarak, atomlara birçok 1s yazıldıysa , var olduğunu varsayarak yazmak için 2.26772 × 10 588843575 atom değerinde evrene ihtiyacımız olurdu .

Senin görevin

Bir tamsayı girişi alan ve bir palindrom'a ulaşmak için gereken adım sayısını döndüren veya basan bir program veya işlev oluşturun. Lychrel adaylarıyla başa çıkmanız gerekmeyecektir (yani, bir Lychrel adayı verildiğinde programınızın bir hata atmasına veya sonsuza kadar çalışmasına izin verilir).

Test Durumları:

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

kurallar

  1. Standart boşluklar yok.

Bonuslar

  1. Biçimlendirilmiş her ekleme adımını yazdırırsanız n + rev(n) = m, puanınızı 0,75 ile çarpabilirsiniz . Toplamlar adım sayısından önce yazdırılmalıdır.
  2. Kodunuz bir sayının Lychrel adayı olup olmadığını tespit edebiliyorsa puanınızı 0,85 ile çarpabilirsiniz . Bu durumda, 261'den fazla yinelemeyi gerektiren herhangi bir şeyin bir Lychrel adayı olduğunu varsaymak yeterlidir. Ya hiçbir şey döndürmeyin, ya da doğru cevapla karıştırılabilecek bir sayı olmayan herhangi bir şey (vb: herhangi bir dize ya da 0-261 aralığında olmayan bir sayı). Herhangi bir hata geçerli çıkış olarak sayılmaz (örn. Maksimum tekrarlama derinliği aşılmıştır) ve algılamada kullanılamaz.
  3. Her iki ikramiyeyi de tamamlarsanız, 0,6 ile çarpın .

Bu , bu yüzden en az bayt sayısı kazanır.


Bu kod snippet'i, her iki bonus ile birlikte Python 3'te örnek bir çözüm gösterir.

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)


1
*0.6ikramiye üstünde diğerleri? Yoksa sadece bu mu?
Maltysen

@Maltysen Sadece 0.6.
Kade

Toplamları yazdırırken yazdırmalı mıyız 10 + 01 = 11yoksa 10 + 1 = 11bize mi kalmış?
Martin Ender

3
Lychrel dedektörü için çıktı alabilir miyim 262?
Maltysen

Yanıtlar:


8

Pyth, 12 bayt

f_I`~+Qs_`Q0

Çevrimiçi deneyin: Gösteri veya Test koşum takımı

Bu oldukça yeni bir özellik kullanıyor (sadece 17 saat).

açıklama

               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

Düzenle:

Kodu biraz değiştirdim. Eski sürüm

fqKs_`Q~+QK0

Aynı bayt sayımı, ancak yenisi çok daha serin.


12 puanında Bonuslar. İyi şanslar!
Dennis

@Dennis Hakkınız. Bu çok saçma bir niyetti. En iyi ben Lychrel algılama kullanarak 13.6 olduğunu.
Jakube

14

Python, 51

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

Python 2 için backticks yerini alamaz str()çünkü Lekli longdeğişmezleri.

İşte 64 * 0.85 = 54.4 puanlı alternatif bir sürüm :

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

Ve Python 3 için 88 * 0.6 = 52.8 puanlı alternatif bir sürüm :

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)

1
Bu sadece çılgınca .. iyi iş çıkardın!
Kade

6

CJam, 23 22 20,4 bayt

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

Kod 24 bayt uzunluğunda ve -1 yazdırıyor Lychrel adayları için .

Çevrimiçi deneyin.

Nasıl çalışır

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.

{}#Başarılı olursa , dizin aynı zamanda adım sayısıdır. Öte yandan, bir dizi bir palindrom içermiyorsa, {}#itecektir -1 .


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;}

Bu, kutuda söylediklerini yapan basit bir döngü, ancak bazı golf eklendi. 1000Tespit bonusu almak için Lychrel adaylarına geri döner. Baskı yapabildiğim ortaya çıktıÇok fazla karakter (en azından Java için) ve bu bonusu da takabildim. Bonus kodu olmadan yapabileceğim en iyi 156, bu yüzden buna değer oldu.

Bazı satır sonları ile:

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;
}

Eski Cevap: 171 * 0.85 = 145.35 bayt

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;}


Sanırım hala kum havuzundayken bu konuda çalıştınız: P Bonus miktarlarını yeniden düşünüyorum, çünkü Python'da bile (C # / Java ile karşılaştırıldığında nispeten özlü bir dil) fark ettim. Bence bu programın uzunluğuna göre ayarlayacağım, böylece golf dilleri <10 baytlık bir puanla sonuçlanmayacak.
Kade

Bonus kurallarını güncelledim, bu yüzden yeni skorun 145.35 :)
Kade

Bir bayt kaydedin, tanımın sonunda noktalı virgül kaldırın, gerekli değildir, bu yüzden sonras++<999
Christopher Wirt

@ChristopherWirt Hangi derleyicide / sürümde? Benimki olmadan bir sözdizimi hatası veriyor.
Geobits

5

Yakut, (80 + 2) * 0.6 = ~ 49.2

Bayraklarla -nlkoş

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

Çıktı şuna benzer

 $ 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

196 verilirse, ilk 261 ekleme adımını ve ardından yazdırır nil.

Burada çok zor bir şey yok. Biz kontrol$_(Girdi için başlatılan) tersini içerip içermediğini , bu ancak aynı boyutta oldukları için eşit olmaları durumunda mümkündür. Öyleyse, adım numarasını yazdırırız ve çıkarız, aksi takdirde, yeni değeri saklayarak ekleme adımını görüntüler ve yürütürüz $_(Maalesef evalgörüntülediğim dizeyi izleyemiyorum çünkü izleyen bir sayıyı izleyen 0 ile yorumlar sekizli bir değişmez olarak). putsdöngü devam etmek için bir falsey değeri döndürür.


" + #{b} = "bir bayt kaydeder.
Mitch Schwartz

Ve -lsayıyı sondaki bir satırsonu olmadan bir dosyaya koyar ve içine sokarsak , kurallar dahilinde görünüyor ?
Mitch Schwartz

4

Pyth - 19 bayt

While döngüsü ve bir sayaç kullanır. Muhtemelen bundan daha küçük bir algoritma vardır, ancak bu oldukça kısadır.

Wnz_z=z`+szs_z=hZ;Z

Burada çevrimiçi deneyin .


Gerçekten çok küçük! Aferin :)
Kade

4

K, 25 bayt

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

Çok zarif değil. Genel form ( {monad 1}{monad 2}\x), K'nin genel "while" döngüsüne eşdeğeridir; burada birinci monad, durma koşulu ve ikincisi, argümana yinelemeli olarak uygulanan bir işlevdir x. İlk monad ( {~x~|x}) klasik "xa palindrome" ifadesinin olumsuzlanmasıdır. İkinci monad, x artı x'in tersini temsil eden bir dizeyi birleştirir, değerlendirir ve ardından sonucu bir dizeye dönüştürür.$ .

Ara sonuçları gösteren örnek bir çalışma:

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

Bonus için istendiği gibi biçimlendirilmiş çıktılar yapmak çok beceriksiz olur ve önemli miktarda kod ekler.


4

CJam, 23 bayt

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

CJam'a sadece birkaç gün kaldığından, en azından bazı profesyonellerle aynı aralıkta olduğum için oldukça mutluyum. :) Ben de CJam ipuçlarında yayınlanmıştır Martin dize karşılaştırma hile kullandın. Bir ipin nasıl tersine çevrileceğini bulmak için Dennis'in çözümüne de baktım.

Açıklama:

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.

Çevrimiçi test edin


4

Julia, 129 120 bayt * 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)

Bu, bir tamsayıyı girdi olarak alan ve bir tamsayıyı döndüren adsız bir işlev oluşturur ve bu arada her adımı yazdırır. Lychrel adaylarının dönüş değeri 262'dir f=i->.... Buna bir isim verin, örn .

Sadece ikramiye ile ilgili kodu atlamanın bu çözümün 84 bayt olacağını unutmayın.

Ungolfed + açıklaması:

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

Örnekler:

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

Geobits sayesinde 2 bayt tasarruf!


4

CJam, 24 bayt

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

Burada test edin.

açıklama

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.

#Dize eşitsizliğini neden kontrol etmek için kullanılabileceği hakkında daha fazla bilgi için bu ipucuna bakın .


Göndermeden önce cevabınızı görmedim. Bu akıllıca bir kullanım #.
Dennis

2

Haskell, 66 53 bayt

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

Kullanım örneği:

*Main> map f [0,11,89,286,196196871,1005499526,1186060307891929990]
[0,0,24,23,45,109,261]

Haskell'i daha önce hiç kullanmadım, ama yapabilir r=reverse xmisin? Bu, ikinci satırınızı f x|x==r=0|1<2=1+f(show$read x+read(r))2 bayt olarak değiştirir ve kaydeder.
Kade

@ Vioz-: Hayır, bu mümkün değil, çünkü xkapsamda olmazdı. Ancak, f x|x==r=0 .... read(r)) where r=reverse xişe yarar, ama daha uzun.
nimi

2

Clojure, 94 bayt

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

Bu benim golf kodlamadaki ilk denemem, bu yüzden lütfen yanlış bir şey yapıp yapmadığımı söyle.

Bazı boşluklarla:

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

İç fonksiyonun basit özyineleme. İki argüman alır, tamsayı%1 ve bir dizin olmak%2 . Eğer%1 bir palindrom olup, endeks döndürülmeden. Aksi takdirde, işlev kendisini toplam ve artan dizinle çağırır. Dış işlev dizini sıfırla başlatır.

Bir örnek:

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

1

Boost.Build, 304 bayt

Aslında bir dil değil. Hala havalı.

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) ;
}

Oldukça basit, ipi tersine çevirmek için kullanılan ayrıntılı regex tabanlı kesmek dışında.


1

Yakut, 44

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

->Lambda sözdizimi için Ruby 1.9 veya üstü gerekir .

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.