Зворотне і віднімання


22

Опис виклику

Візьмемо додатне ціле число n, обернемо його цифрами, щоб отримати rev(n)і отримати абсолютне значення різниці цих двох чисел: |n - rev(n)|(або abs(n - rev(n))).

Приклад:

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

Після повторення цієї операції достатньо разів, більшість чисел стане 0(таким чином, закінчуючи цикл) ...

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

... хоча деякі числа (як 1584) застрягають у нескінченному циклі:

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

Ваше завдання - визначити, чи задане ціле число застряє в нескінченному циклі.

Опис введення

Позитивне ціле число.

Опис виводу

Значення truthy ( True, 1), якщо число застрягає в нескінченному циклі, хибне значення ( False, 0) в іншому випадку.

Примітки

  • Кінцеві нулі повинні бути опущені. тобто rev(5020) = 205.
  • Пам'ятайте, що це , тому зробіть свій код якомога коротшим!
  • Відповідна послідовність: A072140


Цікава примітка: можна побудувати довільно довге ціле число з періодом циклу 2, як описано в коментарях до A072141 . Метод ідентичний і для інших періодів, як 12, 14, 17 та 22.
mbomb007

Відповіді:


18

Pyth, 5 байт

4 байти завдяки FryAmTheEggman

uas_`

Тестовий набір.

Значення truthy - це одне з чисел у циклі.

Значення фальси є 0.

Пояснення

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

Приємне використання змінних автозаповнення!
FryAmTheEggman

1
* зловживання - - - - -
Leaky Nun

Як це працює для того, хто не знає Pyth?
Фаталізувати

3
як pyth такий короткий, але все ще знаходиться в діапазоні ASCII ._.
Пуховик

3
@Downgoat Тому що це pyth.
Leaky Nun

11

Математика, 39 37 байт

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

Просто застосовує зворотні / віднімають nчаси перетворення до вхідних даних, nа потім перевіряє, чи є результат 0. Ніколи не може пройти більше 10nкроків, щоб дійти до циклу, оскільки перетворення не може збільшити кількість цифр, і є менше, ніж 10nчисла, не більше цифр, ніж n. Дивіться доказ Денніса про те, як зменшити цю межу n.


10

Желе , 6 5 байт

ṚḌạµ¡

Спробуйте в Інтернеті!

Фон

Для цього використовується верхня межа @ MartinEnder з 10n ітерацій та наступні спостереження.

  1. Є 9 × 10 к - 1 натуральних чисел n з k цифр.

  2. Різниця числа і його зворотного значення завжди кратна 9 , тому після першої ітерації може виникнути лише 10 к - 1 з них.

  3. З кратних більш ніж 10/10 втрачає цифру в наступній ітерації (для початківців усі, що починаються і закінчуються однаковими цифрами, і приблизно вдвічі більше, якщо перша цифра не є ні 1, ні 9 ), так потрібно ввести максимум 9 × 10 к - 2 або ввести цикл, або втратити цифру.

  4. Застосовуючи те ж міркування до кінцевого цілого числа k - 1 цифр тощо, потрібно ввести не більше 9 × 10 к - 2 + 9 × 10 к - 2 +… ≤ 10 к - 1 ≤ n ітерацій для введення циклу або досягти 0 .

Як це працює

ṚḌạµ¡  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.

11
Піт бив желе?
Leaky Nun

3
Ну, це краватка.
Денніс

Це не байти.
Мік

1
@mik Будь ласка, натисніть посилання байтів у заголовку.
Денніс

5

Oracle SQL 11.2, 136 байт

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;

Без гольфу

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

5

APL, 26 символів

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

Ми використовуємо лівий аргумент як акумулятор значень, які ми вже бачили. Ми ініціалізуємо його на "0", що є однією з двох умов припинення. Охоронець ⍵∊⍺:×⍵читається: "правильний аргумент - те, що ми вже бачили (а це включає нуль)? Якщо так, поверніть знак числа, тобто 1 або 0". В іншому випадку давайте повторимо, називаючи себе абсолютним значенням віднімання після катетування поточного значення лівому аргументу.


Переробка рішення Математики Мартіном Ендером триватиме 21 годин :

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

У ньому написано: "яка ознака результату після застосування бажаних 10n разів"?


4

Python 2, 50 байт

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

Перевірте це на Ideone .

Фон

Для цього використовується верхня межа @ MartinEnder з 10n ітерацій та наступні спостереження.

  1. Є 9 × 10 к - 1 натуральних чисел n з k цифр.

  2. Різниця числа і його зворотного значення завжди кратна 9 , тому після першої ітерації може виникнути лише 10 к - 1 з них.

  3. З кратних більш ніж 10/10 втрачає цифру в наступній ітерації (для початківців усі, що починаються і закінчуються однаковими цифрами, і приблизно вдвічі більше, якщо перша цифра не є ні 1, ні 9 ), так потрібно ввести максимум 9 × 10 к - 2 або ввести цикл, або втратити цифру.

  4. Застосовуючи те ж міркування до кінцевого цілого числа k - 1 цифр тощо, потрібно ввести не більше 9 × 10 к - 2 + 9 × 10 к - 2 +… ≤ 10 к - 1 ≤ n ітерацій для введення циклу або досягти 0 .



3

Python, 129 120 96 байт

Якщо виняток є винятком (зазвичай єдиним винятком, який можна кинути за допомогою цієї функції, є RuntimeError через нескінченну рекурсію), надрукуйте 1. В іншому випадку надрукуйте результат, 0.

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

Завдяки @LeakyNun
Завдяки @shooqie


Офіційно це (приємне) зловживання нескінченною рекурсією.
Leaky Nun

return a and rev(a)
Leaky Nun

3
Чи не можливо отримати RuntimeError через те, що рекурсія дуже тривала, не будучи обов'язково нескінченною?
Фаталізувати

a=[n-x,x-n][n>x]
Leaky Nun

Ви можете скоротити його різко: def rev(n):a=abs(n-int(str(n)[::-1]));return a and rev(a). Також назвіть метод чимось коротким (наприклад, rзамість rev)
shooqie

3

Пітона, 101 98 байт

Алгоритм роботи черепах і зайців.

Truthy - це будь-яке значення в циклі, Falsey - це 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

Ідей це!


3

Python 2, 85 84 83 байт

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

Ще одна відповідь Python. Він додає n до списку для кожної ітерації, і якщо n вже в списку, він виводить False. В іншому випадку воно працює до 0.

Дякуємо @NonlinearFruit за один байт.


1
Я вважаю, що print n<1працює (оскільки nце завжди є негативним), і це економить байт
NonlinearFruit

def f(n,L=[]):¶ if n<1or n in L:print n<1¶ else:f(abs(n-int(`n`[::-1])),L+[n])економить 5 байт
Leaky Nun

3

05AB1E, 11 8 6 байт

DFÂï-Ä

Пояснив

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

Значення Truthy - це число з циклу.
Значення фальшивки - 0.

Спробуйте в Інтернеті

Використовує верхню межу, пояснену у відповіді Дженніса «Желе»

Збережено 2 байти завдяки @Adnan

У версії 7.9 05AB1E працюють наступні 5-байтні рішення, як зазначає @Adnan

DFÂ-Ä

Гаразд, це трохи дивний гольф, але він DFÂ-Äпрацює у версії 7.9, але не в поточній версії. У поточній версії вам потрібно спочатку перетворити його в int (як це DFÂï-Ä), але ви можете використовувати версію 7.9, щоб зробити його 5 байтами: p.
Аднан

@Adnan Я не можу повірити, що забув про функцію біфуркації. Я притримуюсь поточної версії. Ви можете опублікувати 7.9 як окрему відповідь, якщо хочете. Інакше я поставлю це як замітку.
Емінья

Я, мабуть, не публікую його, оскільки це лише 1 байт від цієї відповіді: p.
Аднан

1

Java 7, 161 байт

Для цього потрібен імпорт, але я записав це як функцію. Кричите на мене в коментарях, якщо в цьому сценарії віддається перевага повноцінної програми. Виводить 1, якщо існує нескінченний цикл, і 0, якщо значення дорівнює 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;}

Зауваживши, що раніше я бачив імпорт та функції. приклад
Poke

Чи 1правда?
Лина монашка

1
@LeakyNun 1 не вважається правдою в Java, але списки OP (True, 1) і (False, 0) є прийнятними результатами.
Пукайте

@LeakyNun Чи у Java навіть є почуття правдивості чи хибності?
Ніл

@Neil Java має сенс використовувати синергетичні можливості у вертикальних ринкових контекстах - це все
кіт

1

Брахілог , 49 32 23 байт

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

Повертається trueдля нескінченних петель і в falseіншому випадку.

Це безсоромна адаптація алгоритму Мартина Ендера.

Попередня відповідь, 32 байти

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

Пояснення попередньої відповіді

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

0

PowerShell v2 +, 94 байти

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

Здійснює введення $n, запускає нескінченний forцикл, з $a=,0початковою умовою (для цього використовується оператор комах $aдля масиву з одного елемента 0). Це $aнаш масив уже бачених значень.

Кожна ітерація циклу ми перевіряємо if. Умова спочатку встановлює наступне значення $nвикористання реверсування рядків та [math]::Absвиклику .NET і перевіряє, чи вже це значення -in $a. Якщо так, ми виводимо $nі exit. В іншому випадку ми додамо це значення до масиву і продовжимо цикл.

Виводить 0для вхідних значень там, де він не переходить у нескінченний цикл (який є фальсиєю в PowerShell) і виводить значення там, де цикл зустрічався в іншому випадку (ненульові цілі числа - це правда). Наприклад, виходи 2178для введення 1584.


0

Haskell, 65 байт

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

Повертається 0за хибне та 1істинне. Приклад використання:([]#) 1584 ->1 .

Очевидний підхід: ведіть список з усіма результатами, які бачили дотепер. Обчисліть наступне число до тих пір, поки 0воно не буде в списку.


0

JavaScript (ES6), 75 байт

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

n<0?n=-n:nа n*=n>0||-1також працювати. Алгоритм дещо нагадує відповідь PowerShell, хоча це рекурсивна формулювання.


0

Рубін, 57 байт

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

Спочатку порожній масив hвідстежує раніше вражені значення. Ми повторюємо число, поки не потрапимо на попереднє значення, а потім перевіримо значення на останній ітерації. Оскільки 0 - це цикл 1, це буде 0, якщо і тільки якщо немає більшого циклу. Я беру додаткові 2 байти, щоб перетворити це на булевий, оскільки 0 є тривалістю в Ruby.


0

Perl 6  58 53 33  30 байт

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

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

Пояснення:

{ # 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
  )[ $_ ]
}

(спирається на попереднє зауваження, що цю трансформацію потрібно проводити лише більшість nразів)


0

Perl 5, 31 29 байт

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

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

Це повторює n=|n-rev(n)| n times, so output is 0 if there is no loop, >0 otherwise. Dennis already proved this is enough.

Нова версія використовує evalта xповторює оператор замість forциклу.


Приємна відповідь, і ласкаво просимо до PPCG! Зауважте, що для Perl параметри командного рядка повинні бути включені до вашого числа байтів, тому це не зовсім 30 байт.
AdmBorkBork

@TimmyD добре, +1 для -pопції, -lне потрібно для одного входу
mik

0

Матлаб, 89 84 байт

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

Simple approach - stacks all numbers and checks if a number appeared before.

Explanation

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)
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.