Обратное и вычитать


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

Ваша задача - определить, застряло ли данное целое число в бесконечном цикле.

Описание ввода

Целое положительное число.

Описание вывода

Истинное значение ( True, 1), если число застряло в бесконечном цикле, ложное значение ( False, 0) в противном случае.

Заметки

  • Конечные нули должны быть опущены. то есть rev(5020) = 205.
  • Помните, что это , поэтому сделайте ваш код как можно короче!
  • Соответствующая последовательность: A072140


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

Ответы:


18

Pyth, 5 байт

4 байта благодаря FryAmTheEggman

uas_`

Тестирование.

Истинное значение - это одно из чисел в цикле.

Значение фальси есть 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
* оскорбление - - - - -
Лаки Монахиня

Как это работает, для кого-то, кто не знает Pyth?
Фатализировать

3
как pyth так короток, но все еще в диапазоне ASCII ._.
вниз

3
@ Downgoat, потому что это пит.
Утренняя монахиня

11

Mathematica, 39 37 байт

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

Просто применяет обратное / вычитаемое nвремя преобразования к входу nи затем проверяет, есть ли результат 0. Никогда не может потребоваться больше, чем 10nшаги, чтобы достичь цикла, потому что преобразование не может увеличить количество цифр, и есть 10nчисла меньше, чем цифры n. См. Доказательство Денниса о том, как уменьшить эту границу n.


10

Желе , 6 5 байт

ṚḌạµ¡

Попробуйте онлайн!

Задний план

Это использует @ MartinEnder это верхняя граница из 10n итераций и следующие наблюдения.

  1. Есть 9 × 10 k - 1 натуральных чисел n с k цифрами.

  2. Разность числа и его обратного всегда кратна 9 , поэтому только 10 k - 1 из них может произойти после первой итерации.

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

  4. Применяя те же рассуждения к конечному целому числу k - 1 цифр и т. Д., Требуется не более 9 × 10 k - 2 + 9 × 10 k - 2 +… ≤ 10 k - 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
Пиф побил Желе?
Утренняя монахиня

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;

Un-golfed

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». В противном случае давайте вернемся, назвав себя абсолютным значением вычитания после сковывания текущего значения в левый аргумент.


Пересчет решения Mathematica от Мартина Эндера будет показывать 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 k - 1 натуральных чисел n с k цифрами.

  2. Разность числа и его обратного всегда кратна 9 , поэтому только 10 k - 1 из них может произойти после первой итерации.

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

  4. Применяя те же рассуждения к конечному целому числу k - 1 цифр и т. Д., Требуется не более 9 × 10 k - 2 + 9 × 10 k - 2 +… ≤ 10 k - 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


Это официально (хорошее) злоупотребление бесконечной рекурсией.
Утренняя монахиня

return a and rev(a)
Утренняя монахиня

3
Разве невозможно получить RuntimeError из-за того, что рекурсия очень длинная, но не обязательно бесконечная?
Фатализировать

a=[n-x,x-n][n>x]
Дрянная Монахиня

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


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

Истинное значение - это число из цикла.
Ложное значение равно 0.

Попробуйте онлайн

Использует верхнюю границу, объясненную в ответе Желе Денниса.

Сохранено 2 байта благодаря @Adnan

В версии 7.9 05AB1E следующие 5-байтовые решения работают, как отмечено @Adnan

DFÂ-Ä

Хорошо, это немного странный гольф, но он DFÂ-Äработает в версии 7.9, но не в текущей версии. В текущей версии вам нужно сначала преобразовать его в тип int (как это DFÂï-Ä), но вы можете использовать версию 7.9, чтобы сделать ее 5 байтов: p.
Аднан

@ Adnan Не могу поверить, что я забыл о функции раздвоения. Я буду придерживаться текущей версии, хотя. Вы можете опубликовать 7,9 как отдельный ответ, если хотите. В противном случае я поставлю это как записку.
Эминья

Я, вероятно, не буду публиковать это, так как это всего лишь 1 байт от этого ответа: с.
Аднан

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

Отмечая, что я видел импорт и функции, выполненные ранее. пример
тыкать

Правда 1ли?
Утренняя монахиня

1
@LeakyNun 1 не считается правдой в java, но списки OP (True, 1) и (False, 0) являются приемлемыми выходными данными.
Ткните

@LeakyNun У Java даже есть чувство правды или ложности?
Нил

@Neil Java имеет смысл использовать синергетические возможности в условиях вертикального рынка - вот и все
кошка

1

Brachylog , 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 раз, поэтому вывод равен 0, если цикла нет,> 0 в противном случае. Денис уже доказал, что этого достаточно.

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


Хороший ответ, и добро пожаловать в PPCG! Обратите внимание, что для Perl параметры командной строки должны быть включены в ваш счетчик байтов, так что это не совсем 30 байтов.
AdmBorkBork

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

0

Matlab, 89 84 байта

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

Простой подход - складывает все числа и проверяет, появилось ли число раньше.

объяснение

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.