Задний план
Наибольший общий делитель ( для краткости gcd ) - это удобная математическая функция, поскольку она имеет много полезных свойств. Одним из них является личность Безу : если d = gcd(a, b)
, то существуют целые числа x
и y
такие, что d = x*a + y*b
. В этой задаче ваша задача состоит в том, чтобы визуализировать это свойство с помощью простого искусства ASCII.
вход
Ваши входы два положительных целых чисел a
и b
, приведенные в любом приемлемом формате. Вы также можете использовать унарные входные данные (повторы одного печатного символа ASCII по вашему выбору), но вы должны быть последовательными и использовать один и тот же формат для обоих входных данных. Входные данные могут быть в любом порядке, и они могут быть равны.
Выход
Ваш вывод представляет собой строку s
длины lcm(a, b) + 1
( lcm обозначает наименьшее общее кратное). Символы s
представляют целые числа от 0
до lcm(a, b)
. Символ s[i]
является строчным, o
если i
кратен a
или b
, и период в .
противном случае. Обратите внимание, что ноль кратен каждому числу. Теперь, из - за идентичности Безу, будет по крайней мере одна пара символов o
в s
которых расстояние точно gcd(a, b)
. Крайняя левая такая пара должна быть заменена заглавными O
s; это окончательный результат.
пример
Рассмотрим входы a = 4
и b = 6
. Тогда у нас gcd(a, b) = 2
и lcm(a, b) = 12
, значит, длина s
будет 13
. Кратные a
и b
выделены следующим образом:
0 1 2 3 4 5 6 7 8 9 10 11 12
o . . . o . o . o . . . o
Есть две пары o
s с расстоянием два, но мы заменим только самые левые с O
s, поэтому окончательный результат
o...O.O.o...o
Правила и оценки
Вы можете написать полную программу или функцию. Побеждает меньшее количество байтов, и стандартные лазейки запрещены.
Контрольные примеры
1 1 -> OO
2 2 -> O.O
1 3 -> OOoo
4 1 -> OOooo
2 6 -> O.O.o.o
2 3 -> o.OOo.o
10 2 -> O.O.o.o.o.o
4 5 -> o...OO..o.o.o..oo...o
8 6 -> o.....O.O...o...o.o.....o
12 15 -> o...........O..O........o.....o.....o........o..o...........o
19 15 -> o..............o...o..........o.......o......o...........o..o..............OO.............o....o.........o........o.....o............o.o..............o.o............o.....o........o.........o....o.............oo..............o..o...........o......o.......o..........o...o..............o
.
,o
илиO
.) Или же он должен быть1
? Или0
?Ответы:
Джольф, 52 байта
Я разделю этот код на две части.
Попробуй это здесь!
источник
Юлия,
11111010710396 байтЭто функция, которая принимает два целых числа и возвращает строку.
Ungolfed:
Сохранил байт благодаря Ними!
источник
Сетчатка ,
112109999491 байтЯ думаю, что она не очень конкурентоспособна, но теория чисел в Retina всегда довольно забавная. :)
Вводит в виде одинарных чисел, используя
.
в качестве одинарной цифры.Попробуйте онлайн.
объяснение
Это вставляет
.
и пробел перед входом. Это в конечном итоге станет выходом.Это добавляет LCM
a
иb
к строке. Так как у нас уже.
есть, мы в конечном итогеlcm(a,b)+1
. Это достигается путем многократного добавленияb
до тех пор, покаa
не будет разделен этот новый префикс. Мы записываемa
в группу один, а затем проверяем, можем ли мы достичь начала строки, сопоставляя этот захват хотя бы один раз.b
затем вставляется в строку через редко используемый,$'
который вставляет все после совпадения в подстановку.Этот соответствует символам в положениях, которые разделены
a
илиb
. Он использует тот факт, что результат является симметричным: посколькуlcm(a,b)
он делится на обаa
иb
идет влево, вычитая экземплярыa
илиb
выдает тот же шаблон, что и вправо0
, добавляя их. Первый взгляд вперед просто захватываетa
иb
. Второе предпросмотр проверяет наличие несколькихa
или каждогоb
символа перед первым пробелом.Как указано в Википедии, в дополнение к личности Безу это также верно, что
Это означает, что GCD будет соответствовать кратчайшему промежутку между двумя
o
s на выходе. Так что нам вообще не нужно искать GCD. Вместо этого мы просто ищем первый случай кратчайшего разрыва.o(\.*)o
сопоставляет пробел кандидата и фиксирует его ширину в группе 1. Затем мы пытаемся достичь первого пробела, чередуя обратную ссылку на группу 1 иo
s (с необязательными дополнительными.
s). Если есть более короткий разрыв справа, это не будет соответствовать, потому что мы не можем преодолеть этот разрыв с помощью обратной ссылки. Как только все дальнейшие промежутки будут по крайней мере такими же широкими, как и текущий, это совпадет. Мы фиксируем конец строки LCM в группу 2 и сопоставляем остаток строки с.*
. Мы пишем в верхнем регистреO
s (с промежутком между ними), а также оставшуюся часть строки LCM, но отбросьте все, начиная с пробела, чтобы удалитьa
иb
из конечного результата.источник
(\.*)
=>(a*)
.
более поздний, который стоит четыре байта (а избавление от побегов спасает только 3).𝔼𝕊𝕄𝕚𝕟, 50 символов / 90 байтов
Try it here (Firefox only).
Должен быть способ играть в гольф дальше!
объяснение
Это основной двухфазный алгоритм. Это на самом деле довольно просто.
Фаза 1
Сначала мы создаем диапазон от 0 до LCM + 1. Затем мы отображаем его, проверяя, является ли какой-либо из входных факторов фактором текущего элемента в диапазоне. Если это так, мы заменим этот элемент на
o
; в противном случае мы заменим его на.
. Присоединение к ней дает нам серию точек и точек, которые мы можем перейти ко второй фазе.Фаза 2
Это всего лишь одна большая функция замены. Регулярное выражение создается как
o[dots]o
, где количество точек определяется GCD-1. Поскольку это регулярное выражение не является глобальным, оно будет соответствовать только первому вхождению. После этого совпадение заменяется сO[dots]O
помощью функции toUpperCase.источник
MATL , 72 байта
Использует версию 6.0.0 , которая является более ранней, чем эта проблема. Код работает в Matlab и в Octave.
пример
объяснение
Я понятия не имею, как это работает. Я просто набрал символы случайным образом. Я думаю, что есть какая-то свертка.
Изменить: попробуйте онлайн! Код в ссылке был немного изменен, чтобы соответствовать изменениям в языке (по состоянию на 2 июня 2016 года).
источник
Japt , 83 байта
Еще не полностью в гольф ... И не хочет играть в гольф: /
источник
r
вместо$.replace($
?Javascript,
170164161153145141136 байтЭто довольно долго ....
Демо , явно определенные переменные, потому что интерпретатор использует строгий режим.
источник
i%a<1||i%b<1?'o':'.'
наi%a&&i%b?'.':'o'
[...Array((d=a*b/(c=(g=(a,b)=>b?g(b,a%b):a)(a,b)))+1).keys()].map(i=>i%a&&i%b?'.':'o')
экономит два байта (Я также пытался использовать индексирование строк для создания '.' И 'o', но это на самом деле стоит два байта.)Python 2,
217200191 байтЭто немного тупо, но это работает. Любые советы по игре в гольф приветствуются,
особенно если вы знаете, как решить этуПонял!s[i] = s[v] = "o"
проблему, с которой я столкнулся, где это переписало бы "О"Ungolfed:
источник