Поиск базы Repdigit


21

Репдигиты это натуральное число , которое можно записать только повторяя ту же цифру. Например, 777это 7повторная цифра, поскольку она состоит исключительно из цифры, повторенной три раза.

Однако это не ограничивается просто десятичными (базовыми 10) числами:

  • Каждое число Мерсенна (в форме M n = 2 n -1 ) является повторным, если оно записано в двоичном виде (база 2).
  • Каждое число является тривиальным, если оно написано в унарном формате (база 1).
  • Каждое число nтакже может быть тривиально записано как повторная цифра 11в базе n-1(например, 17когда записано в шестнадцатеричном (основание 16) 11, и 3когда записано в двоичном (основание 2 также 11)).

Задача здесь состоит в том, чтобы найти другие базы, где введенный номер может быть повторным.

вход

Целое положительное число x > 3в любом удобном формате.

Выход

Положительное целое число bс , (x-1) > b > 1где представлением xв базе bявляется репдигитами.

  • Если такого не bсуществует, выведите 0или какое-то неверное значение.
  • Если таких bсуществует несколько , вы можете вывести любое или все из них.

правила

  • (x-1) > b > 1Ограничение , чтобы предотвратить тривиальные преобразования в Унарный или «вычитать одну» базу. Выходное число может быть записано в одинарной или любом удобной базе, но сама база не должна быть одной из тривиальных преобразований.
  • Ввод / вывод может быть любым подходящим способом .
  • Стандартные ограничения лазейки применяются.

Примеры

In --> Out
11 --> 0            (or other falsey value)
23 --> 0            (or other falsey value)
55 --> 10           (since 55 is 55 in base 10)
90 --> 14           (since 90 is 66 in base 14 ... 17, 29, 44 also allowed)
91 --> 9            (since 91 is 111 in base 9 ... 12 also allowed)

Можем ли мы предположить b ≤ 36(встроенные базовые функции преобразования многих языков не идут выше)?
Дверная ручка

2
@ Doorknob Предполагается, что рамки этой проблемы b ≤ 36 сильно ограничены, и все существующие ответы правильно обрабатывают большие базы, поэтому я собираюсь сказать нет, вы не можете принять верхнюю границу bза пределы того, что дано.
AdmBorkBork

Большинство чисел являются репигитами в некоторой базе. Например, 91 = 13 * 7, поэтому 77 на базе 12.
Нил

@Neil ... Это похоже на то, что ты что-то
делаешь

Ответы:


11

Желе, 11 9 байт

bRI¬P€TḊṖ

Возвращает список баз, который пуст (ложно), если его нет. Попробуйте онлайн!

Как это устроено

bRI¬P€TḊṖ  Main link. Argument: x (number)

 R         Range; yield [1, ..., x].
b          Base; convert x to base n, for each n in the range.
  I        Compute the increment (differences of successive values) of each array
           of base-n digits. This yields only 0's for a repdigit.
   ¬       Apply logical NOT to each increment.
    P€     Compute the product of all lists of increments.
      T    Get the indices of all truthy products.
       Ḋ   Discard the first index (1).
        Ṗ  Discard the last index (x - 1).

9

Pyth, 11 10

fqjQT)r2tQ

По-видимому, унарный Pyth qпроверяет список, который имеет все уникальные значения около 10 дней назад. Очевидно, что исследование ошибок Pyth улучшает результаты игры в гольф.

Фильтрует список, [2..input-1)если уникальный набор цифр ввода в этой базе имеет длину 1.

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

Объяснение:

r2tQ     ##  generate the python range from 2 to the input (Q) - 1
         ##  python range meaning inclusive lower and exclusive upper bounds
f        ##  filter that list with lambda T:
  jQT    ##  convert the input to base T
 q    )  ##  true if the resulting list digits has all equal elements

5

Рубин, 87 69 63 байта

->x{(2..x-2).find{|b|y=x;a=y%b;a=0if a!=y%b while(y/=b)>0;a>0}}

Мне пришлось реализовать конвертацию базы вручную, поскольку встроенные функции Ruby доходят только до 36 базы ...

Возвращает nilдля не найдено.

->x{      # anonymous lambda that takes one argument
(2..x-2)  # range of the possible bases to search over
.find{    # return the first element that satisfies the block, or nil if none
|b|       # b represents the base currently being tested
y=x;      # a temporary value to avoid mutating the original value of x
a=y%b;    # the first (well, last) digit in base b, which will be compared to

                   y/=b      # divide the number by the base
   if a!=y%b                 # if this digit does not match (is different)...
a=0                          # set a to a value representing "failure"
             while(    )>0;  # keep doing this until we get zero (no digits left)

a>0       # return whether a has maintained its original value (no digit change)
}}        # find then returns the first element for which this is true (or nil)

5

Python, 71 72 78 байт

lambda x:{b for b in range(2,x-1)for d in range(x)if x*~-b==x%b*~-b**d}

Нет рекурсии, просто пробует все базы и выводит набор тех, которые работают.

Заманчиво кодировать bи dодним числом, но для их извлечения требуется слишком много выражений в скобках. 77 байт:

lambda x:{k/x for k in range(2*x,x*x-x))if x*~-(k/x)==x%(k/x)*~-(k/x)**(k%x)}

72 байта:

f=lambda x,b=2:b*any(x*~-b==x%b*~-b**d for d in range(x))or f(x,b+1)%~-x

Выводит первое, bчто работает, или, 0если никто не делает.

Респ-блок xиз dцифр cв базе bимеет значение x==c*(b**d-1)/(b-1). Эквивалентно x*(b-1)==c*(b**d-1).

Значение cдолжно быть x%bпоследней цифрой. Хотя я не вижу способа dарифметического определения , поэтому код пробует все возможности, чтобы увидеть, работает ли какой-либо из них.

Сэкономили 5 байтов, скопировав трюк Денниса с выводом фальси при bдостижении x-1, взяв выход по модулю x-1. Еще один байт, спасенный от Денниса, напомнил мне, что возведение в степень необъяснимо имеет более высокий приоритет, чем ~.

Решение равной длины с inвместо any.

f=lambda x,b=2:b*(x*~-b in[x%b*~-b**d for d in range(x)])or f(x,b+1)%~-x

4

Рубин, 50 байтов

->n{(2..n-2).find{|b,i=n|i%b==(i/=b)%b ?redo:i<1}}

Я действительно хотел бы удалить это раздражающее пространство, но как новичок в ruby, я все еще совершенно незнаком с его синтаксическими причудами.


Причудливая изюминка в этом случае - b?это допустимое имя метода, поэтому вы не можете избавиться от пробела.
Иордания

4

Emojicode , 214 байт

(77 символов):

🐇🐹🍇🐇🐖🏁➡🚂🍇🍦b🍺🔲🗞🔷🔡😯🔤🔤🚂🍮i 2🍮n 0🔁◀i➖b 1🍇🍦v🔷🔡🚂b i🍊▶🐔🔫v🔪v 0 1📏v🍇🍮n i🍉🍫i🍉😀🔷🔡🚂n 9🍎0🍉🍉

Печать результатов в базе 9.

Я хотел пару месяцев играть в гольф кода с эмоджикодом, но язык только недавно стал достаточно стабильным, чтобы реально работать с 😉. В качестве бонуса, этот вопрос использует одну функциональность, в которой эмоджикод действительно хорош: представляет целые числа в других базах.

Ungolfed (👴 - это комментарий к строке в Emojicode)

🐇🐹🍇         👴 define main class "🐹"
  🐇🐖🏁➡🚂🍇  👴 define main method

    👴 read an integer from stdin, store it in frozen variable "b"
    🍦 b 🍺 🔲 🗞 🔷🔡😯🔤🔤 🚂

    🍮 i 2  👴 i = 2
    🍮 n 0  👴 n = 0

    🔁◀i➖b 1🍇     👴 while i < b - 1
      🍦 v 🔷🔡🚂b i  👴 v = the string representation of b in base i

      👴 Split v on every instance of the first character of v.
      👴 If the length of that list is greater than the actual length of v,
      👴 n = i
      🍊▶🐔🔫v🔪v 0 1📏v🍇
        🍮 n i
      🍉

      🍫 i  👴 increment i
    🍉
    😀 🔷🔡🚂 n 9  👴 represent n in base 9 instead of 10, to save a byte 😜
    🍎 0          👴 return error code 0
  🍉
🍉

4

Python 2, 79 байт

f=lambda x,b=2:~-b*x in[i%b*~-b**(i/b)for i in range(b*x)]and b or f(x,-~b)%~-x

Попробуйте это на Ideone .

идея

Любая повторная цифра x базы b> 1 и цифры d <b удовлетворяет следующему.

условие

Поскольку d <b , карта (b, d) ↦ cb + d инъективно.

Кроме того, поскольку b, x> 1 , мы имеем c <x , поэтому cb + d <cb + b = (c + 1) b ≤ xb .

Это означает, что, чтобы найти подходящие значения для c и d для данного основания b , мы можем перебрать все i в [0,…, bx) и проверить, является ли (b - 1) x == (i% b) (b я / б - 1) .

Код

Именованная лямбда- f- проверка, находится ли (b - 1) x в множестве {(i% b) (b i / b - 1) | 0 ≤ i <bx} , начиная со значения b = 2 .

  • Если тест прошел успешно, мы вернемся b .

  • В противном случае мы снова вызываем f с теми же x и b, увеличенными на 1 .

Поскольку b может в конечном итоге достичь x - 1 , мы берем окончательный результат по модулю x - 1, чтобы вернуть 0 в этом случае. Обратите внимание, что этого не произойдет, если b = 2 удовлетворяет условию, поскольку оно возвращается без рекурсии. Однако вопрос гарантирует, что в этом случае b = 2 <x - 1 .


3

Perl 6, 45 43 42 байта

{grep 2..$^x-2: {[==] $x.polymod($_ xx*)}}

Объяснил (вроде)

Для справки, переменная $^xin { ... }- это то же самое, что и-> $x { ... }

{grep 2..$^x-2: {[==] $x.polymod($_ xx*)}}
{                                          # Anonymous function taking $x
 grep                                      # Return the all values in
      2..$^x-2: {                          # Range from 2 to $x - 2 satisfying:
                 [==]                      #     Reduce with ==:
                      $x.polymod(          #         (See below for polymod)
                                 $_ xx*    #         An infinite list containing
                                           #         the current value
                                       )}}

Polymod (TL; DR): $n.polymod($b xx *)выдает обратный список цифр / «цифр» для $nбазы$b

Polymod (для реального): метод polymod почти как более мощная версия функции python divmod. $n.polymod(*@args)делит $ n на каждое значение в * @ args, добавляя remainder ( $n mod $x) в список, который он возвращает, и используя частное для следующего деления. Я чувствую, что объяснил это плохо, поэтому вот несколько примеров (написанных на Perl 6, но достаточно понятных, чтобы понять большинство, я надеюсь):

12.polymod(7)    # returns (5, 1)
# Roughly equivalent to:
(12 mod 7, 12 div 7)

86400.polymod(60,60,24) # returns (0, 0, 0, 1)
# Roughly equivalent to (this will give you an array rather than a list):
my $n = 86400;
my @remainders; # Here lies the end result
for (60, 60, 24) -> $divisor {
    @remainders.push( $n mod $divisor );
    $n div= $divisor;
}
@remainders.push($n)

# This is essentially the base conversion algorithm everyone
# knows and loves rolled into a method.
# Given an infinite list of divisors, polymod keeps going until
# the remainder given is 0.     
0xDEADBEEF.polymod(16 xx *) # returns (15 14 14 11 13 10 14 13)
# Roughly equivalent to (but gives an array rather than a list):
my $n = 0xDEADBEEF;
my @remainders; # Here lies the end result
while $n > 0 {
    @remainders.push( $n mod 16 );
    $n div= 16;
}

1
На самом деле, поскольку вам разрешено выводить « любое или все » из допустимых значений, вы можете использовать grepметод вместо firstметода.
Брэд Гилберт b2gills

О, хороший улов, я пропустил это
Hotkeys

3

Дьялог АПЛ , 28 байт

 {b/⍨⍵{1=≢∪⍵⊥⍣¯1⊢⍺}¨b←1+⍳⍵-3}

{... ... }анонимные функции , которые будут применены к x(представлено )
b←1+⍳⍵-3целым числам от 2 - ⍵-2 хранятся в виде b
⍵{... для каждого элемента в Ь ( ), применить функцию {... }с й как левый аргументом
⍵⊥⍣¯1⊢⍺конвертировать й к этой базе
1=≢∪1 равна бирке уникальной цифры?
b/⍨элементы b, где true (что существует только одна уникальная цифра).

Примеры случаев

Если базы не существует, выходные данные пусты (что неверно), что можно продемонстрировать с помощью этой программы:

 WhatIsEmpty
 →''/TRUE ⍝ goto (→) TRUE: if (/) emptystring ('')
 'False'
 →END       
TRUE:       
 'True'     
END:        

Это печатает «Ложь»


2

Pyth, 26 19 байтов

hMfql{eT1m,djQdr2tQ

Попробуй это здесь!

Добавлю объяснение после того, как я играю в гольф. Посмотрите на этот ответ для более короткой реализации и объяснения.


1
Спасибо, что напомнили мне, что я забыл дополнительные основания для 90и 91в моих примерах!
AdmBorkBork

2

MATL , 15 14 байтов

3-:Q"G@:YAd~?@

Это работает с текущей версией (14.0.0) языка / компилятора.

Если база не существует, вывод пуст (что ложно).

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

3-:Q    % take input x implicitly. Generate range of possible bases: [2,3,...,x-2]
"       % for each base b
  G     %   push input again
  @:    %   generate vector of (1-based) digits in base b: [1,2,...,b]
  YA    %   convert to that base
  d~    %   differences between consecutive digits; negate
  ?     %   if all values are true (that is, if all digits were equal)
    @   %     push that base
        %   end if implicitly
        % end for each implicitly
        % display implicitly

2

Mathematica, 55 байт

Cases[4~Range~#-2,a_/;Equal@@#~IntegerDigits~a]/.{}->0&

Анонимная функция, не слишком сложная. Просто отфильтровывает базы на основе репдитности.


2

Python 2, 75 байт

n=input()
b=1
while b<n-2:
 i=n;b+=1
 while i%b==i/b%b:i/=b
 if i<b:print b

Порт моего рубинового ответа. Печатает все действительные базы, если таковые имеются.


2

Юлия, 45 байт

n->filter(b->endof(∪(digits(n,b)))<2,2:n-2)

Это анонимная функция, которая принимает целое число и возвращает массив целых чисел. Чтобы вызвать его, присвойте его переменной. Он вернет все применимые базы или пустой массив. Нет проблем с большими базами.

Сначала мы генерируем включающий диапазон [2, n - 2], где n - вход. Затем мы filterперечисляем только целые числа b, для которых n в базе b имеет менее 2 уникальных цифр. Чтобы сделать это, для каждого целого числа b в диапазоне, мы получаем цифры n в базе b, используя массив digits, получаем уникальные элементы, используя , и получаем индекс последнего элемента (то есть длины), используя endof.


1

Брахилог , 12 байт

>>.ℕ₂≜&ḃ↙.=∧

Попробуйте онлайн! (как генератор!)

Принимает ввод через входную переменную и выводит базу через выходную переменную в том случае, если это возможно, в противном случае происходит сбой. В то же время он также работает как генератор, который выводит список всех баз, где этот список может быть пустым.

В идеале это может выглядеть примерно так ḃ↙.=&>>, возможно, жертвуя функциональностью генератора в такой форме или аналогичной (так как это в конечном итоге попадет в унарный код), но на данный момент 12 байтов - самый короткий, который я знаю, как его получить.

     ≜          Assign an integer value to
  .             the output variable
   ℕ₂           which is greater than or equal to 2
 >              and less than a number
>               which is less than the input.
      &         The input
       ḃ↙.      in base-(the output)
          =     is a repdigit.
           ∧    (which is not necessarily the output)


0

05AB1E , 7 байтов

ÍL¦ʒвÙg

Выводит все возможные значения или пустой список как ложное значение (хотя технически допустимые выходные данные также ложны, так как только 1 в 05AB1E верно, а все остальное ложно).

Попробуйте онлайн или проверьте все контрольные примеры .

Объяснение:

Í        # Decrease the (implicit) input-integer by 2
 L       # Create a list in the range [1, input-2]
  ¦      # Remove the first value to make the range [2, input-2]
   ʒ     # Filter this list by:
    в    #  Convert the (implicit) input to the base of the number we're filtering
     Ù   #  Uniquify it, leaving only distinct digits
      g  #  Get the length of this, which is truthy (1) if all digits were the same
         # (and then output the filtered list implicitly as result)

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.