Регекс (аромат PCRE), 66 (65🐌) байт
Натхненно побачивши, що і Мартін Ендер, і джайтея , два геніальні гегеї , писали рішення для цього коду гольфу, я написав власні з нуля. Відомий регулярний контрольний вираз не відображається ніде в моєму рішенні.
Не читайте цього, якщо ви не хочете, щоб певна манія уніарної виразки була зіпсована вам. Якщо ви хочете зняти цю магію самостійно, я настійно рекомендую почати з вирішення деяких проблем у регулярному вираженні ECMAScript:
- Збігайте прості номери (якщо ви ще не знайомі з цим в регулярному виразі)
- Відповідайте повноваженням 2 (якщо ви цього ще не зробили). Або просто пропрацюйте свій шлях через Regex Golf , який включає Prime і Powers. Не забудьте зробити як класичний, так і Teukon набір проблем.
Знайдіть найкоротший спосіб узгодження потужностей N, де N - деяка константа (тобто зазначена в регулярному вираженні, а не вхідній), яка може бути складовою (але не обов'язковою бути). Наприклад, відповідні сили 6.
Знайдіть спосіб узгодження N-ї сили, де N деяка константа> = 2. Наприклад, відповідні ідеальні квадрати. (Для розминки відповідайте основним силам .)
Збігайте правильні заяви множення. Зіставити трикутні числа.
Зіставити числа Фібоначчі (якщо ти такий же божевільний, як і я), або якщо ти хочеш дотримуватися чогось коротшого, відповідати правильним твердженням експоненції (для розминки поверніть як відповідність логарифму в базі 2 потужністю 2 - бонус, зробіть те ж саме для будь-якого числа, округлюючи його скільки завгодно) або фактичні номери (для розминки, співставляйте первісні числа ).
Зрівняйся з великою кількістю (якщо ти такий же божевільний, як і я)
Обчисліть ірраціональне число на потрібну точність (наприклад, розділіть вхід на квадратний корінь на 2, повернувши округлий результат у відповідність)
(Механізм регулярного вираження, який я написав, може допомогти, оскільки це дуже швидко в одинарних математичних регексах і включає в себе одинарний режим числення, який може перевірити діапазони натуральних чисел (але також має режим рядків, який може оцінювати неонарські регекси, або одинарні з роздільниками). За замовчуванням він сумісний із ECMAScript, але має додаткові розширення (які можуть вибірково додавати підмножини PCRE, або навіть молекулярний пошук, те, що не має жодного іншого регекс-движка).)
В іншому випадку читайте далі, а також читайте цей GitHub Gist (попередження, багато спойлерів), який хронікує мандрівку підштовхування регулярного виразів ECMAScript для вирішення природних чисельних функцій, що збільшують труднощі (починаючи з набору головоломок Teukon, не всіх математичних, які викликали це подорож).
Як і у випадку з іншими рішеннями цієї задачі, вхід подається у вигляді двох чисел у біективних одинарних, розділених комою, що представляють собою інклюзивний діапазон. Повертається лише одне число. Регекс можна модифікувати, щоб повернути всі числа, що мають той самий найменший за величиною основний коефіцієнт, як окремі збіги, але для цього знадобиться перегляд відстані змінної довжини і або введення пошуку, \K
або повернення результату як захоплення замість відповідності.
Методика, що використовується тут для повторного неявного поділу на найменший простий коефіцієнт, ідентична тій, що використовується у рядках Match, довжина яких є четвертим відповіді на потужність, яку я опублікував деякий час назад.
Без зайвих прихильності:
((.+).*),(?!.*(?=\1)(((?=(..+)(\5+$))\6)*)(?!\2)).*(?=\1)\K(?3)\2$
Ви можете спробувати тут.
І безкоштовна версія з коментарями:
# No ^ anchor needed, because this algorithm always returns a
# match for valid input (in which the first number is less than
# or equal to the second number), and even in /g mode only one
# match can be returned. You can add an anchor to make it reject
# invalid ranges.
((.+).*), # \1 = low end of range; \2 = conjectured number that is the
# smallest number in the set of the largest prime factor of each
# number in the range; note, it is only in subsequent tests that
# this is implicitly confined to being prime.
# We shall do the rest of our work inside the "high end of range"
# number.
(?! # Assert that there is no number in the range whose largest prime
# factor is smaller than \2.
.*(?=\1) # Cycle tail through all numbers in the range, starting with \1.
( # Subroutine (?3):
# Find the largest prime factor of tail, and leave it in tail.
# It will both be evaluated here as-is, and later as an atomic
# subroutine call. As used here, it is not wrapped in an atomic
# group. Thus after the return from group 3, backtracking back
# into it can increase the value of tail – but this won't mess
# with the final result, because only making tail smaller could
# change a non-match into a match.
( # Repeatedly divide tail by its smallest prime factor, leaving
# only the largest prime factor at the end.
(?=(..+)(\5+$)) # \6 = tool to make tail = \5 = largest nontrivial factor of
# current tail, which is implicitly the result of dividing it
# by its smallest prime factor.
\6 # tail = \5
)*
)
(?!\2) # matches iff tail < \ 2
)
# now, pick a number in the range whose largest prime factor is \2
.*(?=\1) # Cycle tail through all numbers in the range, starting with \1.
\K # Set us up to return tail as the match.
(?3) # tail = largest prime factor of tail
\2$ # Match iff tail == \2, then return the number whose largest
# prime factor is \2 as the match.
Алгоритм можна легко перенести в ECMAScript, замінивши виклик підпрограми на копію підпрограми та повернувши збіг як групу захоплення замість використання \ K. Результат - 80 байт у довжину:
((x+)x*),(?!.*(?=\1)((?=(xx+)(\4+$))\5)*(?!\2)).*(?=\1)(((?=(xx+)(\8+$))\9)*\2$)
Спробуйте в Інтернеті!
Зауважте, що ((.+).*)
можна змінити ((.+)+)
, зменшивши розмір на 1 байт (від 66 до 65 байт ), не втрачаючи правильної функціональності, - але регекс експоненціально вибухає в повільності.
Спробуйте в Інтернеті! (79-байтна версія експоненціального уповільнення ECMAScript)