Можно показать, что положительные рациональные числа нумеруются с помощью следующего процесса:
- Ноль имеет порядковый номер 0
- Расположите другие числа в сетке так, чтобы строка a, столбец b содержала a / b
- Постройте диагональный зигзаг сверху справа внизу слева
- Ведите счет уникальных чисел, встречающихся вдоль зигзага
Вот картина зигзага:
Итак, числа встречаются в порядке
1/1, 2/1, 1/2, 1/3, 2/2, 3/1, 4/1, 3/2, 2/3, 1/4, 1/5, 2/4, 3/3, 4/2, 5/1, 6/1, 5/2, 4/3, 3/4, 2/5, 1/6, 1/7, 2/6, 3/5, 4/4, 5/3 ...
И упрощенные, уникальные числа встречаются
1, 2, 1/2, 1/3, 3, 4, 3/2, 2/3, 1/4, 1/5, 5, 6, 5/2, 4/3, 3/4, 2/5, 1/6, 1/7, 3/5, 5/3, ...
Вызов:
- Если даны два целых числа больше нуля p и q , выведите порядковое число p / q
- р и q не обязательно взаимно просты
- Самый короткий код выигрывает
- Стандартные лазейки запрещены
Тестовые случаи:
Вот первые 24 встреченных рациональных числа и желаемый результат для каждого:
1/1: 1
2/1: 2
1/2: 3
1/3: 4
2/2: 1
3/1: 5
4/1: 6
3/2: 7
2/3: 8
1/4: 9
1/5: 10
2/4: 3
3/3: 1
4/2: 2
5/1: 11
6/1: 12
5/2: 13
4/3: 14
3/4: 15
2/5: 16
1/6: 17
1/7: 18
2/6: 4
3/5: 19
И, для дальнейших тестов, вот 200 первых положительных рациональных чисел в порядке:
1, 2, 1/2, 1/3, 3, 4, 3/2, 2/3, 1/4, 1/5,
5, 6, 5/2, 4/3, 3/4, 2/5, 1/6, 1/7, 3/5, 5/3,
7, 8, 7/2, 5/4, 4/5, 2/7, 1/8, 1/9, 3/7, 7/3,
9, 10, 9/2, 8/3, 7/4, 6/5, 5/6, 4/7, 3/8, 2/9,
1/10, 1/11, 5/7, 7/5, 11, 12, 11/2, 10/3, 9/4, 8/5,
7/6, 6/7, 5/8, 4/9, 3/10, 2/11, 1/12, 1/13, 3/11, 5/9,
9/5, 11/3, 13, 14, 13/2, 11/4, 8/7, 7/8, 4/11, 2/13,
1/14, 1/15, 3/13, 5/11, 7/9, 9/7, 11/5, 13/3, 15, 16,
15/2, 14/3, 13/4, 12/5, 11/6, 10/7, 9/8, 8/9, 7/10, 6/11,
5/12, 4/13, 3/14, 2/15, 1/16, 1/17, 5/13, 7/11, 11/7, 13/5,
17, 18, 17/2, 16/3, 15/4, 14/5, 13/6, 12/7, 11/8, 10/9,
9/10, 8/11, 7/12, 6/13, 5/14, 4/15, 3/16, 2/17, 1/18, 1/19,
3/17, 7/13, 9/11, 11/9, 13/7, 17/3, 19, 20, 19/2, 17/4,
16/5, 13/8, 11/10, 10/11, 8/13, 5/16, 4/17, 2/19, 1/20, 1/21,
3/19, 5/17, 7/15, 9/13, 13/9, 15/7, 17/5, 19/3, 21, 22,
21/2, 20/3, 19/4, 18/5, 17/6, 16/7, 15/8, 14/9, 13/10, 12/11,
11/12, 10/13, 9/14, 8/15, 7/16, 6/17, 5/18, 4/19, 3/20, 2/21,
1/22, 1/23, 5/19, 7/17, 11/13, 13/11, 17/7, 19/5, 23, 24,
23/2, 22/3, 21/4, 19/6, 18/7, 17/8, 16/9, 14/11, 13/12, 12/13,
11/14, 9/16, 8/17, 7/18, 6/19, 4/21, 3/22, 2/23, 1/24, 1/25
Прикоснитесь к обратному вопросу , где первый ход опущен, поэтому вы не можете использовать ответы для создания дополнительных тестовых случаев.
Ответы:
Желе ,
2120 байтВероятно, побиваемый количеством байтов, используя некоторую умную математику ...
Монадическая ссылка, принимающая список,
[p,q]
который возвращает назначенное натуральное числоp/q
.Попробуйте онлайн! Или посмотрите набор тестов .
Как?
Прежде всего обратите внимание, что встречающаяся N- я диагональ содержит все рациональные числа сетки, для которых сумма числителя и знаменателя равна N + 1 , поэтому, учитывая функцию, которая сводит
[p,q]
пару к простейшей форме ([p/gcd(p,q),q/gcd(p,q)]
), мы можем построить диагонали до нужно быть *, уменьшить все записи, дедуплицировать и найти индекс упрощенного ввода.* на самом деле еще один здесь, чтобы сохранить байт
источник
Perl 6 ,
9490 байтПроверь это
Проверь это
Это в основном генерирует всю последовательность значений и останавливается, когда находит совпадение.
Expanded:
({1…($+=2)…1}…*)
генерирует бесконечную последовательность числителей (|(…)
используется выше для выравнивания)(1,{1…(($||=1)+=2)…1}…*)
генерирует бесконечную последовательность знаменателейисточник
Python 2 ,
157144137134126125 байтПопробуйте онлайн!
4 байта сохранены благодаря г-ну Xcoder ; 1 байт от Джонатона Фреха .
Как отметил г-н Xcoder, в Python 3 мы можем сделать немного лучше, поскольку, среди прочего, целочисленное деление по умолчанию выводит результаты, и мы можем легче распаковать
list
s:Python 3 , 117 байт
Попробуйте онлайн!
источник
**(j%-2|1)
иp-~q
.+1
в конце, так как1,1
"должен" дать1
, а не0
.Python 3 ,
157,146,140133 байтаПопробуйте онлайн!
выиграл 11 байтов благодаря Джонатану Фреху
выиграл еще 6 байтов, а затем 7 благодаря Chas Brown
источник
range(max(p,q)+1)
наrange(p+q)
.{*a}
вместоset(a)
.J,
41,35, 30 байтов-11 байт благодаря FrownyFrog
Попробуйте онлайн!
оригинальный 41 байт пост с объяснением
ungolfed
объяснение
Попробуйте онлайн!
источник
1+~.@;@([:<@|.`</.%~/~)@(1+i.@*)i.%
%i.~0~.@,@,[:]`|./.[:%/~1+i.@*
Python 3, 121 байт
источник
Ржавчина, 244 байта
Я создал простую формулу, чтобы найти «простой» порядковый номер «простого» зигзага без ограничений головоломки, используя формулы треугольных чисел: https://www.mathsisfun.com/algebra/triangular-numbers.html . Это было изменено по модулю 2, чтобы учесть, что зигзаги переворачивают свое направление в каждом диагональном ряду головоломки. Это функция h ()
Тогда для основного трюка этой головоломки: как не считать определенные повторяющиеся значения, такие как 3/3 против 1/1, 4/2 против 2/1, в зигзагообразной тропе. Я запустил 1-200 примеров и заметил разницу между простым зигзагообразным треугольным счетчиком и рисунком, который желает загадка. Шаблон «пропущенных» чисел - 5, 12, 13, 14, 23 и т. Д., Что привело к попаданию в OEIS. Это один из описанных Робертом Пнем, в https://oeis.org/A076537 , чтобы «дедуплицировать» числа типа 3/3, 4/2 и 1/1, вы можете проверить, является ли GCD> 1 для х, у всех «предыдущих» ординалов в зигзаге. Это циклы for, а g () - это gcd.
Я предполагаю, что с некоторыми встроенными gcd это было бы короче, но я вроде не мог найти его очень легко (я немного новичок в Rust, и Integer меня смутил), и мне нравится тот факт, что этот использует прямую целочисленную арифметику, и нет встроенных или библиотек любого рода.
источник
JavaScript (ES6), 86 байт
Принимает ввод в синтаксисе карри
(p)(q)
.Попробуйте онлайн!
источник
Javascript, 79 байт
(Я новичок в коде игры в гольф, так что это, вероятно, можно легко улучшить)
объяснение
источник
(3,5)
должно привести к19
(не24
) , так как(1,1)==(2,2)==(3,3)
,(2,4)==(1,2)
,(4,2)==(2,1)
и(2,6)==(1,3)
. (т. е.(2,2)
должно привести к1
не5
, и т. д ...)