Balikkan dan kurangi

22

Deskripsi tantangan

Mari kita ambil bilangan bulat positif n, balikkan digitnya untuk mendapatkan rev(n)dan mendapatkan nilai absolut dari perbedaan dua angka ini: |n - rev(n)|(atau abs(n - rev(n))).

Contoh:

n = 5067 
rev(n) = 7605
|n - rev(n)| = |5067 - 7605| = |-2538| = 2538

Setelah mengulangi operasi ini berkali-kali, sebagian besar angka akan menjadi 0(sehingga mengakhiri loop) ...

5067 -> 2538 -> 5814 -> 1629 -> 7632 -> 5265 -> 360 -> 297 -> 495 -> 99 -> 0

... meskipun beberapa angka (seperti 1584) macet di loop tak terbatas:

1584 -> 3267 -> 4356 -> 2178 -> 6534 -> 2178 -> 6534 -> 2178 -> 6534 -> ...
                        ^ infinite loop starts here

Tugas Anda adalah menentukan apakah bilangan bulat yang diberikan macet di loop tak terbatas.

Deskripsi input

Bilangan bulat positif.

Deskripsi keluaran

Nilai kebenaran ( True, 1) jika nomor macet dalam infinite loop, nilai palsu ( False, 0) sebaliknya.

Catatan

  • Angka nol yang tertinggal harus dihilangkan. yaitu rev(5020) = 205.
  • Ingat bahwa ini adalah , jadi buat kode Anda sesingkat mungkin!
  • Urutan yang relevan: A072140
shooqie
sumber
Terkait Terkait
Martin Ender
Catatan yang menarik: adalah mungkin untuk membangun bilangan bulat panjang sewenang-wenang dengan periode pengulangan 2, seperti yang dijelaskan dalam komentar pada A072141 . Metode ini juga identik untuk periode lain, seperti 12, 14, 17, dan 22.
mbomb007

Jawaban:

18

Pyth, 5 byte

4 byte terima kasih kepada FryAmTheEggman

uas_`

Suite uji.

Nilai kebenaran adalah salah satu angka dalam loop.

Nilai falsey adalah 0.

Penjelasan

uas_`      Input:Q
uas_`GGQ   Implicit filling of variables.

u      Q   Set G as Q: do this repeatedly until result seen before: Set G as
 a             the absolute difference of
     G             G
    `              convert to string
   _               reverse
  s                convert to integer
      G        and G
Biarawati Bocor
sumber
Penggunaan variabel isi-otomatis yang bagus!
FryAmTheEggman
1
* penyalahgunaan - - - - -
Leaky Nun
Bagaimana cara kerjanya, untuk seseorang yang tidak tahu Pyth?
Fatalkan tanggal
3
bagaimana pyth begitu pendek namun masih dalam kisaran ASCII ._.
Downgoat
3
@Downgoat Karena itu adalah pyth.
Leaky Nun
11

Mathematica, 39 37 byte

Nest[Abs[#-IntegerReverse@#]&,#,#]<1&

Cukup gunakan waktu transformasi mundur / kurangi nke input ndan kemudian periksa apakah hasilnya 0. Tidak pernah dapat mengambil lebih dari 10nlangkah untuk mencapai satu lingkaran, karena transformasi tidak dapat meningkatkan jumlah digit, dan ada lebih sedikit dari 10nangka dengan tidak ada lebih banyak digit daripada n. Lihat bukti Dennis tentang cara mengurangi keterikatan ini n.

Martin Ender
sumber
10

Jelly , 6 5 byte

ṚḌạµ¡

Cobalah online!

Latar Belakang

Ini menggunakan @ MartinEnder yang atas terikat dari 10n iterasi dan observasi berikut.

  1. Ada 9 × 10 k - 1 bilangan bulat positif n dengan k digit.

  2. Perbedaan angka dan kebalikannya selalu kelipatan 9 , jadi hanya 10 k - 1 dari mereka dapat terjadi setelah iterasi pertama.

  3. Dari kelipatannya, lebih dari 1/10 akan kehilangan satu digit di iterasi berikutnya (sebagai permulaan, semua yang dimulai dan diakhiri dengan digit yang sama, dan kira-kira dua kali lebih banyak jika digit pertama bukan angka 1 atau angka 9 ), jadi paling banyak dibutuhkan 9 × 10 k - 2 untuk memasukkan satu lingkaran atau kehilangan satu digit.

  4. Menerapkan alasan yang sama pada bilangan bulat k - 1 yang dihasilkan dan seterusnya, dibutuhkan paling banyak 9 × 10 k - 2 + 9 × 10 k - 2 +… ≤ 10 k - 1 ≤ n iterasi untuk memasukkan sebuah loop atau mencapai 0 .

Bagaimana itu bekerja

ṚḌạµ¡  Main link. Argument: n

   µ¡  Iteratively apply the chain to the left n times.
Ṛ      Reverse n (casts to digits).
 Ḍ     Undecimal; convert from base 10 to integer.
  ạ    Take the absolute difference of the result and the argument.
Dennis
sumber
11
Apakah Pyth mengalahkan Jelly?
Leaky Nun
3
Yah, itu dasi.
Dennis
Ini bukan byte.
mik
1
@mik Silakan klik tautan byte di header.
Dennis
5

Oracle SQL 11.2, 136 byte

WITH v(n)AS(SELECT :1 FROM DUAL UNION ALL SELECT ABS(n-REVERSE(n||''))FROM v WHERE n>0)CYCLE n SET c TO 0 DEFAULT 1 SELECT MIN(c)FROM v;

Tidak bermain golf

WITH v(n) AS
(
  SELECT :1 FROM DUAL
  UNION ALL
  SELECT ABS(n-REVERSE(n||''))FROM v WHERE n>0 
) CYCLE n SET c TO 0 DEFAULT 1
SELECT MIN(c)FROM v
Jeto
sumber
5

APL, 26 karakter

0∘{⍵∊⍺:×⍵⋄(⍺,⍵)∇|⍵-⍎⌽⍕⍵}

Kami menggunakan argumen kiri sebagai akumulator dari nilai yang telah kita lihat. Kami menginisialisasi ke "0", yang merupakan salah satu dari dua kondisi pemutusan. Penjaga ⍵∊⍺:×⍵itu terbaca: "apakah argumen yang benar sudah pernah kita lihat (dan itu termasuk nol)? Jika demikian kembalikan tanda angka, yaitu 1 atau 0". Kalau tidak, mari kita kambuh dengan menyebut diri kita dengan nilai absolut dari pengurangan setelah memiliki nilai saat ini untuk argumen kiri.


Sebuah penyusunan kembali solusi Mathematica oleh Martin Ender akan jam di 21 karakter :

 {×{|⍵-⍎⌽⍕⍵}⍣(10×⍵)⊣⍵}

Bunyinya: "apa tanda hasil setelah menerapkan 10n yang diinginkan kali"?

lstefano
sumber
4

Python 2, 50 byte

n=input()
exec'n=abs(n-int(`n`[::-1]));'*n
print n

Uji di Ideone .

Latar Belakang

Ini menggunakan @ MartinEnder yang atas terikat dari 10n iterasi dan observasi berikut.

  1. Ada 9 × 10 k - 1 bilangan bulat positif n dengan k digit.

  2. Perbedaan angka dan kebalikannya selalu kelipatan 9 , jadi hanya 10 k - 1 dari mereka dapat terjadi setelah iterasi pertama.

  3. Dari kelipatannya, lebih dari 1/10 akan kehilangan satu digit di iterasi berikutnya (sebagai permulaan, semua yang dimulai dan diakhiri dengan digit yang sama, dan kira-kira dua kali lebih banyak jika digit pertama bukan angka 1 atau angka 9 ), jadi paling banyak dibutuhkan 9 × 10 k - 2 untuk memasukkan satu lingkaran atau kehilangan satu digit.

  4. Menerapkan alasan yang sama pada bilangan bulat k - 1 yang dihasilkan dan seterusnya, dibutuhkan paling banyak 9 × 10 k - 2 + 9 × 10 k - 2 +… ≤ 10 k - 1 ≤ n iterasi untuk memasukkan sebuah loop atau mencapai 0 .

Dennis
sumber
4

CJam, 15 13 byte

ri_{_sW%i-z}*

Uji di sini.

Sama seperti jawaban Mathematica saya.

Martin Ender
sumber
3

Python, 129 120 96 byte

Jika pengecualian ditangkap (biasanya satu-satunya pengecualian yang dapat dilemparkan dengan fungsi ini adalah RuntimeError, karena rekursi tak terbatas), cetak 1. Jika tidak, cetak hasilnya, 0.

def r(n):a=abs(n-int(str(n)[::-1]));return a and r(a)
try:print(r(int(input())))
except:print(1)

Terima kasih kepada @LeakyNun
Terima kasih kepada @shooqie

TuxCrafting
sumber
Itu secara resmi penyalahgunaan rekursi tak terbatas (bagus).
Leaky Nun
return a and rev(a)
Leaky Nun
3
Apakah tidak mungkin untuk mendapatkan RuntimeError karena rekursi yang sangat lama tanpa itu tidak terbatas?
Fatalkan tanggal
a=[n-x,x-n][n>x]
Leaky Nun
Anda dapat mempersingkat secara drastis: def rev(n):a=abs(n-int(str(n)[::-1]));return a and rev(a). Juga, rrev
beri
3

Python, 101 98 byte

Algoritme kura-kura dan kelinci.

Kebenaran adalah nilai dalam loop, falsey adalah 0.

g=lambda n:abs(n-int(str(n)[::-1]))
def r(n):
    t=g(n);h=g(t)
    while t-h:h=g(g(h));t=g(t)
    return h

Ide itu!

Biarawati Bocor
sumber
3

Python 2, 85 84 83 byte

L=[]
def f(n,L=L):
    if n<1or n in L:print n<1
    else:L+=[n];f(abs(n-int(`n`[::-1])))

Jawaban Python lainnya. Ia menambahkan n ke daftar untuk setiap iterasi, dan jika n sudah ada dalam daftar, itu menghasilkan False. Kalau tidak, ia bekerja ke 0.

Terima kasih @NonlinearFruit untuk satu byte.

ahli atlasologi
sumber
1
Saya percaya print n<1bekerja (karena nselalu non-negatif) dan menyimpan byte
NonlinearFruit
def f(n,L=[]):¶ if n<1or n in L:print n<1¶ else:f(abs(n-int(`n`[::-1])),L+[n])menghemat 5 byte
Leaky Nun
3

05AB1E, 11 8 6 byte

DFÂï-Ä

Dijelaskan

DF          # input number of times do
  Â         # push current number and its reverse
   ï-       # convert reverse to int and subtract
     Ä      # absolute value
            # implicitly print after loop ends

Nilai kebenaran adalah angka dari loop.
Nilai falsy adalah 0.

Cobalah online

Menggunakan batas atas dijelaskan dalam jawaban Dennis 'Jelly

Disimpan 2 byte berkat @Adnan

Dalam versi 7.9 dari 05AB1E solusi 5-byte berikut berfungsi seperti dicatat oleh @Adnan

DFÂ-Ä
Emigna
sumber
Oke, ini sedikit aneh golf tetapi DFÂ-Äbekerja di versi 7.9 tetapi tidak di versi saat ini. Dalam versi saat ini, Anda harus mengonversinya menjadi int terlebih dahulu (seperti ini DFÂï-Ä), tetapi Anda dapat menggunakan versi 7.9 untuk membuatnya 5 byte: p.
Adnan
@ Adnan Saya tidak percaya saya lupa tentang fungsi bifurkasi. Saya akan tetap berpegang pada versi saat ini. Anda dapat memposting 7,9 sebagai jawaban terpisah jika Anda mau. Kalau tidak, saya akan meletakkannya sebagai catatan.
Emigna
Saya mungkin tidak akan mempostingnya, karena hanya berjarak 1 byte dari jawaban ini: hal.
Adnan
1

Java 7, 161 byte

Ini memerlukan impor tetapi saya menulisnya sebagai fungsi. Teriak padaku di komentar jika program lengkap lebih disukai dalam skenario ini. Output 1 jika ada loop tak terbatas dan 0 jika nilainya mencapai 0.

import java.util.*;int z(int a){int o,r,c=a;Set s=new HashSet();while(c!=0){for(r=0,o=c;o!=0;r=r*10+o%10,o/=10);c=Math.abs(c-r);if(!s.add(c))return 1;}return 0;}
Menyodok
sumber
Memperhatikan bahwa saya telah melihat impor dan fungsi dilakukan sebelumnya. contoh
Poke
Apakah itu benar 1?
Leaky Nun
1
@LeakyNun 1 tidak dianggap benar di java tetapi daftar OP (Benar, 1) dan (Salah, 0) sebagai output yang dapat diterima.
Poke
@ LeakyNun Apakah Java bahkan memiliki rasa kebenaran atau kepalsuan?
Neil
@Neil Java memiliki perasaan memanfaatkan peluang sinergis dalam konteks pasar vertikal - itu saja
cat
1

Brachylog , 49 32 23 byte

:10*N,?:N:{r:?-+.}itT'0

Pengembalian trueuntuk loop tak terbatas dan falsesebaliknya.

Ini adalah adaptasi yang tidak tahu malu dari algoritma Martin Ender.

Jawaban sebelumnya, 32 byte

g{tTr:T-+U(0!\;?:ImU;?:[U]c:1&)}

Penjelasan dari jawaban sebelumnya

g{                             } Call predicate with [Input] as input
  tT                             T is the last element of Input
    r:T-                         Subtract T from the reverse of T
        +U                       U is the absolute value of T
          (0!\                   If U is 0, return false
              ;                  Or
               ?:ImU             If U is in Input, return true
                    ;            Or
                     ?:[U]c:1&)  Recursive call with U concatenated to the Input
Fatalisasi
sumber
0

PowerShell v2 +, 94 byte

param($n)for($a=,0;){if(($n=[math]::Abs($n-(-join"$n"["$n".length..0])))-in$a){$n;exit}$a+=$n}

Mengambil input $n, memulai forloop tak terbatas , dengan $a=,0sebagai kondisi awal (ini menggunakan operator koma untuk mengatur $ake array dari satu elemen, 0). Ini $aadalah susunan nilai yang sudah terlihat.

Setiap iterasi loop kami periksa if. Kondisi pertama menetapkan nilai berikutnya $nmenggunakan pembalikan string dan [math]::Abspanggilan .NET, dan memeriksa apakah nilai itu sudah -in $a. Jika demikian, kami mengeluarkan $ndan exit. Jika tidak, kami menambahkan nilai itu ke array dan melanjutkan loop.

Output 0untuk nilai input di mana ia tidak masuk ke infinite loop (yang merupakan falsey di PowerShell) dan output nilai di mana loop ditemui sebaliknya (bilangan bulat nol benar). Misalnya, output 2178untuk input 1584.

AdmBorkBork
sumber
0

Haskell, 65 byte

_#0=0
a#n|elem n a=1|1<2=(n:a)#abs(n-(read$reverse$show n))
([]#)

Returns 0for False dan 1for True. Contoh penggunaan: ([]#) 1584-> 1.

Pendekatan yang jelas: buat daftar dengan semua hasil yang terlihat sejauh ini. Hitung nomor berikutnya sampai 0atau ada dalam daftar.

nimi
sumber
0

JavaScript (ES6), 75 byte

f=(n,...a)=>a.includes(n=n<0?-n:n)?n:f([...n+``].reverse().join``-n,n,...a)

n<0?n=-n:ndan n*=n>0||-1juga bekerja. Algoritma agak menyerupai jawaban PowerShell, meskipun ini adalah formulasi rekursif.

Neil
sumber
0

Ruby, 57 byte

->n,*h{h[n]=n=(n-"#{n}".reverse.to_i).abs until h[n];n>0}

Array yang awalnya kosong hmelacak nilai-nilai sebelumnya. Kami mengulangi angka hingga mencapai nilai sebelumnya, lalu memeriksa nilai pada iterasi terakhir. Karena 0 adalah siklus 1, itu akan menjadi 0 jika dan hanya jika tidak ada siklus yang lebih besar. Saya mengambil tambahan 2 byte untuk mengonversinya menjadi Boolean karena 0 benar di Ruby.

histokrat
sumber
0

Perl 6  58 53 33  30 byte

sub {$/=%;$^a,{return ?1 if $/{$_}++;abs $_-.flip}...0;?0}
{$/=%;?($_,{last if $/{$_}++;abs $_-.flip}...0)[*-1]}
{?($_,{abs $_-.flip}...0)[10**$_]}

{?($_,{abs $_-.flip}...0)[$_]}

Penjelasan:

{ # block lambda with implicit parameter $_

  # coerce the following to Bool
  # ( False for Nil or 0, True otherwise )
  ?

  (

    $_, # start a sequence with the input

    # block lambda with implicit parameter $_
    # subtracts the previous value in the sequence and its reverse
    # ( .flip is short for $_.flip where a term is expected )
    { abs $_ - .flip } 

    ... # repeat that lambda
    0   # until you get 0

  # get the element indexed with the block's input
  # may be 0, Nil, or a number that is part of a repeating sequence
  )[ $_ ]
}

(Bergantung pada pengamatan sebelumnya bahwa Anda hanya perlu melakukan transformasi ini paling banyak nkali)

Brad Gilbert b2gills
sumber
0

Perl 5, 31 29 byte

perl -pe'for$x(1..$_){$_=abs$_-reverse}'

perl -pe'eval"\$_=abs\$_-reverse;"x$_'

Iterates n=|n-rev(n)|n kali, jadi output adalah 0 jika tidak ada loop,> 0 sebaliknya. Dennis sudah membuktikan ini sudah cukup.

Versi baru menggunakan evaldan xmengulangi operator, bukan forloop.

mik
sumber
Jawaban yang bagus, dan selamat datang di PPCG! Perhatikan bahwa untuk Perl, opsi baris perintah harus dimasukkan dalam byte-count Anda, jadi ini tidak cukup 30 byte.
AdmBorkBork
@ TimmyD ok, +1 untuk -popsi, -ltidak perlu untuk input tunggal
mik
0

Matlab, 89 84 byte

n=input('');z=n;while n
z=abs(z-str2num(fliplr(num2str(z))));n=[n z]*all(n~=z);end
z

Pendekatan sederhana - menumpuk semua angka dan memeriksa apakah suatu angka muncul sebelumnya.

Penjelasan

n=input('');z=n;  -- take input, initiate z
while n           -- n is said to be positive
z=abs(z-str2num(fliplr(num2str(z)))) -- calculate the "reverse and substract"
n=[n z]           -- put the value at the end of the vector
       *all(n~=z) -- make the n all zeroes if z is previously in the vector (break the loop)
end
z                 -- print z (0 when not entered loop, >0 otherwise)
pajonk
sumber