Если задано простое число P
больше чем 10
, ваша программа или функция должны выяснить свое правило делимости x
, определяемое как целое число с наименьшим абсолютным значением, которое дает кратное первоначального простого числа, умноженное на последнюю цифру простого числа и добавленное к остальной части оригинала. премьер.
пример
Учитывая вход 31
, последняя цифра 1
и остальная часть числа 3
. Таким образом, ваша программа должна найти целое число x
с минимальным абсолютным значением, 1*x + 3
кратным 31
. В этом случае x=-3
работает, поэтому программа или функция вернется -3
.
Учитывая вход 1000003
, последняя цифра 3
и остальная часть числа 100000
. Таким образом, ваша программа найдет, x=300001
потому 3*300001+100000 = 1000003
что это кратно 1000003
.
Математический фон
Значение x
может использоваться в качестве теста делимости. Если число N
делится на P
, то добавление x
умноженного на последнюю цифру числа N
к остальному N
даст кратное, P
если и только если N
делится на P
в первую очередь.
Ибо P=11
мы получаем x=-1
, что эквивалентно известному правилу делимости для 11
: число делится на 11
чередующиеся разности его цифр делится на 11
.
правила
- Вывод может быть в любой форме, которая четко кодирует как знак, так и значение вывода.
- Простое входное значение будет между 10 и 2 ^ 30.
- Вам не нужно обрабатывать, если вход не простое число или не находится в диапазоне.
- Вам не нужно обрабатывать, если оба
x
и-x
являются допустимыми выходами (не должно происходить). - Допускается грубая сила, но ценятся более креативные решения.
- Это код-гольф , поэтому выигрывает самый короткий код на каждом языке ! Не позволяйте ответам на языках гольфа отговаривать вас от публикации на других языках.
Тестовые случаи
Input Output
11 -1
13 4
17 -5
19 2
23 7
29 3
31 -3
37 -11
41 -4
43 13
47 -14
53 16
59 6
61 -6
67 -20
71 -7
73 22
79 8
83 25
89 9
97 -29
101 -10
103 31
107 -32
109 11
113 34
127 -38
131 -13
1000003 300001
2000003 600001
2999999 300000
9999991 -999999
источник
x
по абсолютной величине значение,10*x-1
которое делится на входные данные.(3 / (n % 5 * 2 - 5) * n + 1) / 10
и(n % 5 * 2 - 5^2) * n / 10 + 1
может найти минимальное абсолютное значение для чего-то вроде этого? Моей первой интуицией было бы вычислить наименьшее общее кратное, используя наибольший общий делитель, рассчитанный по алгоритму Евклида.x
, добавить ее и получить число, делимое наn
. Если затем умножить новое число на 10 и вычесть исходное число, оно все равно останется делимым наn
. Комментарий xnor тогда следует из некоторой алгебры. Следующим шагом является изменение формулы так, чтобы она имелаx
видn
: x =(k*n+1)/10
. Мы хотим , чтобы наименьшее абсолютноеx
так поэтому мы хотим , чтобы наименьшее абсолютноеk
, и это должно быть в зависимости от того один из-3
,-1
,1
или3
( в зависимости отn
«s последняя цифра) , что делает разделение точным.Ответы:
JavaScript (ES6),
322523 байта3/(n%5*2-5)
было бы написано,9/n(mod -10)
если бы у меня был доступ к сбалансированному делению по модулю. Изменить: Сохранено 2 байта благодаря @EgorSkriptunoffисточник
n=>((n%10*2%14-3)*n+1)/10
наn=>(3/(n%5*2-5)*n+1)/10
Python 2 , 27 байт
Попробуйте онлайн!
Операции выполняются слева направо:
(((n%5)*2)-5)^2
.Я использовал свой арифметический грубый форсер, чтобы найти выражение
n%5*2-5^2
для выполнения{1:-1,3:3,2:-3,4:1}[k]
, взяв отрицательную обратную величину остатка мод 5 в диапазон[-2..2]
.источник
3/(n%5*2-5)
такой же длины, как и(n%5*2-5^2)
.)n%5*2-6^3
. Я только посмотрел на длину выражения без паренов, тогда как3/(n%5*2-5)
на два символа длиннее, но экономит на внешних паренах из-за старшинства. Поиск выражений такой длины должен занять некоторое время. Этот вариант использования действительно предлагает опцию, чтобы найти выражения, которые могут быть использованы в данном контексте через их крайнюю операцию, имеющую достаточно высокий приоритет.Желе ,
108 байтПопробуйте онлайн!
Пояснения
источник
Брахилог , 14 байт
Попробуйте онлайн!
источник
Python 2 ,
695453 байтаИзменить: -15 байт благодаря @ Mr.Xcoder
Изменить: -1 байт с помощью рекурсии
Попробуйте онлайн!
источник
Python 2 ,
31 2927 байтПопробуйте онлайн!
источник
Japt ,
169 байтСохранено слишком много байтов благодаря наблюдению @xnor
Проверьте это онлайн! Может потребоваться несколько секунд на больших входах.
объяснение
источник
Java 8,
2321 байтПорт ответа @Seil JavaScrip (ES6) , но -2 байта благодаря @Nevay из-за неявного выделения целых чисел.
Попробуй это здесь.
источник
n->3/(n%5*2-5)*++n/10
Пайк , 12 байт
Попробуй это здесь!
источник
Pyth , 14 байт
Попробуй это здесь.
источник
Python 2 ,
4443 байта(Вычеркнуто 44 все еще 44.) Спасибо Fireflame241 за сохранение байта!
Попробуйте онлайн!
Существует ровно один номер между
0
иP-1
который является обратным10
. Но если этот обратныйu
случай больше, чемP/2
, то(u-P)
он также обратный, и имеет меньшее абсолютное значение, чемu
. Вот и получается, что мы действительно ищем уникальный номерx
между-P/2
иP/2
который является обратным к10
.Код выше делает именно это, начиная с (этажа)
P/2
и спускаясь вниз, пока не будет достигнут обратный. Это должно произойти для некоторого числа больше, чем-P/2
до тех пор,P
пока простое число больше, чем10
. Точнее, оно прекратится тогда и только тогда, когдаP
это взаимно10
.Изменить: На самом деле оказывается, что
x
гарантированно находится между-P/3
иP/3
, поэтому текущая версия начинается сP/3
и оттуда вниз. См. Раздел « Улучшенная граница» для объяснения этого.Математическое объяснение
Для меня не сразу было очевидно, почему тест делимости работает. Вот объяснение, на случай, если кому-то еще будет интересно.
Позвольте
P
быть простое число, больше, чем10
, чья последняя цифраb
. таким образомP = 10a + b
где
a > 0
и0 <= b < 10
. На самом делеb
либо1
,3
,7
, или9
, так как простое число , большее10
должно заканчиваться в одной из этих цифр.Теперь предположим
bx + a = 0 (mod P)
. потомa = -bx (mod P)
10a + b = 10(-bx) + b (mod P)
0 = 10(-bx) + b (mod P)
0 = b(1 - 10x) (mod P)
Поскольку
P
простое число, целые числаmod P
являются интегральной областью . Так что либоb = 0 (mod P)
, либо1 - 10x = 0 (mod P)
.Мы знаем
0 <= b < 10 < P
, так что еслиb = 0 (mod P)
тогдаb = 0
. Но мы сказали ,b
либо1
,3
,7
, или9
, так что это невозможно. Поэтому1 - 10x = 0 (mod P)
так10x = 1 (mod P)
. Другими словами,x
это обратное10
, по модулюP
.Теперь предположим, что
N
это неотрицательное целое число, последняя цифра которогоd
, поэтому уN = 10c + d.
нас есть цепочка эквивалентных утверждений:10c + d = 0 (mod P)
<==> 10xc + dx = 0 (mod P)
<==> c + dx = 0 (mod P)
QED.
Полезность?
Мне также было интересно, будет ли тест делимости (задан
N = 10c + d
, замененN
наdx + c
) действительно продуктивным на практике. Или, по крайней мере, надежно ли заменитьN
на число меньше, чемN
(в абсолютном значении)?Предположим
N = 10c + d
, гдеc >= 0
и0 <= d < 10
. Поэтому10c = N - d <= N
. По неравенству треугольника,|c + dx| <= |c| + |dx| = c + d|x| <= N/10 + d|x|
< N/10 + 10|x| <= N/10 + 10P/2 = N/10 + 5P
Таким образом, если
5P <= 9N/10
, тогда|c + dx| < N
.В частности, если
N >= 6P
, то|c + dx| < N
. Таким образом, учитывая ,P
мы начнем с расчета2P
,3P
...,6P
наряду сx
. Затем даетсяN
, мы проводим тест делимостных несколько раз , пока мы не достигнем числа меньше или равно6P
, и проверить , является ли результат любой из чисел0
,P
,2P
...,6P
.(Конечно, всякий раз, когда мы достигаем отрицательного числа, мы заменяем его его абсолютным значением, что хорошо, так
q
как делится наP
то и только если(-q)
есть.)Улучшенная граница
Я заметил, что
|x|/P
никогда не казалось близким1/2
. На самом деле казалось, что это всегда было меньше1/3
... или, при ближайшем рассмотрении, это всегда было очень близко к1/10
или3/10
. Самым большим, что он когда-либо получал4/13
(что случается, когдаP=13
иx=4
). С чего бы это?Позвольте
u
быть целым числом и предположим, что10u = kP + 1
для некоторого целогоk
, такu
что обратное10
, по модулюP
. Тогда мы также знаем, чтоk
это относительно простое число10
, такk(-P)
как эквивалентно по1
модулю10
.Теперь мы знаем, что все обратные по
10
модулюP
отличаются на кратныеP
, поэтому мы можем взять целое числоu
и либо добавить, либо вычесть кратныеP
по желанию, и результат всегда будет обратным к10
модулюP
. Предположим, мы решили вычестьP
изu
: мы получаем10(u - P) = 10u - 10P = kP + 1 - 10P
10(u - P) = (k - 10)P + 1
Другими словами, уменьшение (соответственно увеличение)
u
наP
соответствует уменьшению (увеличению)k
на10
. Мы хотим добавить / вычесть кратныеP
отu
до тех пор, пока левая часть не будет минимизирована по абсолютной величине; но левая сторона минимизируется именно тогда, когда правая сторона минимизирована, и поэтому мы хотим добавить / вычесть10
изk
пока правая рука не сворачивается в абсолютной величине.Но мы знаем , что это произойдет , когда
k
между-5
и5
, и , следовательно , (так какk
взаимно простое с10
) это означает , чтоk
либо-3
,-1
,1
или3
. (Это содержание комментария @ Neil к OP. Спасибо, Neil! )Таким образом , когда
|u|
минимизируется (т.е.u=x
), мы будем иметьx/P = u/P = k/10 + 1/(10P)
, гдеk
либо-3
,-1
,1
или3
. Поэтому|x|/P <= 3/10 + 1/(10P)
. Эквивалентно|x| <= (3P + 1)/10
.Далее, это неравенство строгое
P=11
, потому что уP=11
нас естьx=-1
иk=-1
. Наименьшее,P
для которого выполняется равенствоP=13
(гдеx=4
иk=3
).Поэтому самое большое, что
|x|/P
когда-либо получается3/10 + 1/(10*13)
, это потому, чтоP=13
это первое простое число, для которого мы имеемk=3
, и среди тех, у когоk=3
этот1/(10P)
термин самый большой, когдаP
он наименьший (т. Е. AtP=13
). Поэтому для всехP
у нас тоже есть|x|/P <= 3/10 + 1/130 = 4/13 < 1/3
. Это объясняет, почему в приведенном выше коде мы можем инициализировать,i = P/3
а не начинать сP/2
.Кроме того, теперь можно улучшить границы в разделе « Полезность » выше.
Лемма : давай
N = 10c + d
гдеc > 0
и0 <= d <= 9
. Потомc + d|x| < N/10 + 9(3P + 1)/10
. (Обратите внимание на строгое неравенство.)Доказательство леммы: по случаям. Дело I:
d = 0
такN = 10c
. Потомc + d|x| = c = N/10 < N/10 + 9(3P + 1)/10
.Случай II
0 < d <= 9
. Тогда10c = N - d < N
такc < N/10
. Следовательноc + d|x| < N/10 + d|x| <= N/10 + 9|x| <= N/10 + 9(3P + 1)/10
. QED.Таким образом, если
N > 3P
(иN = 10c + d
как прежде), то3P + 1 <= N
9(3P + 1)/10 <= 9N/10
N/10 + 9(3P + 1)/10 <= N
c + d|x| < N/10 + 9(3P + 1)/10 <= N
Так что, если
N > 3P
тогдаc + d|x| < N
.Таким образом, мы имеем только , чтобы найти
P
,2P
и3P
, наряду сx
. УчитываяN > 0
, в то время какN > 3P
мы заменимN
на|c + dx|
, который уменьшаетсяN
. В конце концов мы получимN <= 3P
; в этой точке мы останавливаемся и проверить , является лиN
равно ни одному из чисел0
,P
,2P
, или3P
.Мы не можем сделать лучше, чем
3P
в целом. Например, предположим,P = 13
иN = 39
такx = 4
. Затем заменаN
наdx + c = 9(4) + 3
листьяN
без изменений.источник
-1
за скобки: 43 байтаПробел , 92 байта
Обратите внимание, что синтаксис этого языка состоит из только из пробелов , поэтому каждый символ пробела здесь имеет префикс S, T или L (соответствующий пробелу, табуляции и переводу строки соответственно). Они могут быть удалены без потери функциональности, но они включены здесь для правильного отображения.
Попробуйте онлайн!
источник
Japt , 14 байт
Вдохновленный решением Нейла .
Проверьте это онлайн!
Объяснение:
источник
Пайк , 10 байт
Попробуй это здесь!
источник
Excel, 27 байт
Может быть введен в ячейку как
для 25 байтов, но Excel автообновления.
источник