Знайдіть найгладше число


59

Ваше завдання полягає в тому, щоб знайти найгладше число в заданому діапазоні. Іншими словами, знайдіть число, найбільший простий коефіцієнт якого найменший.

Гладкий номер один , чий найбільший простий множник малий. Числа цього типу корисні для алгоритму швидкого перетворення Фур'є, криптоаналізу та інших застосувань.

Наприклад, у діапазоні 5, 6, 7, 8, 9, 108 найгладше число, тому що найбільший простий коефіцієнт 8 - 2, тоді як у всіх інших чисел простий коефіцієнт становить 3 або більше.

Вхід: Вхід буде двома додатними цілими числами, які визначають діапазон. Мінімальне допустиме ціле число в діапазоні - 2. Ви можете вибрати, чи буде діапазон всеосяжним, ексклюзивним, напівексклюзивним тощо, доки довільний діапазон може бути визначений у межах вашої мови. Ви можете приймати цифри за допомогою функції введення, stdin, аргументу командного рядка або будь-якого еквівалентного методу для вашої мови. Немає кодування додаткової інформації на вході.

Вихід: повернення, друк або еквівалент одне або більше цілих чисел у діапазоні введення, які є максимально рівними (мінімально найбільший коефіцієнт). Повернення кількох результатів необов’язкове, але якщо ви вирішите це зробити, результати повинні бути чітко розмежовані. Рідний вихідний формат прекрасний для отримання декількох результатів.

Будь ласка, вкажіть у своїй відповіді, як ви приймаєте інформацію та надаєте висновок.

Оцінка: Код гольфу. Підраховуйте за символами, якщо вони написані в ASCII, або 8 * байт / 7, якщо не в ASCII.

Тестові приклади:

Примітка. Це діапазони стилів Python, включаючи нижній, але не найвищий. Змініть відповідно до програми. Потрібен лише один результат.

smooth_range(5,11)
8
smooth_range(9,16)
9, 12
smooth_range(9,17)
16
smooth_range(157, 249)
162, 192, 216, 243
smooth_range(2001, 2014)
2002

Чи допустимі діапазони, вказані як (початок, довжина) замість (початок, кінець)?
CodesInChaos

1
@CodesInChaos Звичайно. Це стосується пункту "чи будь-що".
isaacg

3
Я не бачу сенсу штрафувати відповіді, що не стосуються ASCII. Простіше було б просто порахувати байти у всіх випадках.
nyuszika7h

1
@ nyuszika7h Ascii значно менший за байт - він використовує лише 7 біт. Тому я позначаю один символ на 7 біт і масштабую інші мови відповідно. Однак якщо мова не є ASCII, але може упакувати всі її символи в 7 біт, я не застосовуватиму доплату. Див. J / K проти APL. tl; dr Bytes простіше, але дає APL та ін. ін. тонка, але несправедлива перевага.
isaacg

3
@isaacg Ви заохочуєте створювати псевдо-мови за допомогою менших наборів символів. якщо ми набираємо 7-бітові набори символів, що відрізняються від 8-бітових наборів символів, хтось може упакувати більшість сучасних мов у 6 біт (64 символи отримують нам AZ, 0-9, жмень пробілів, 20 пунктуацій та кілька, щоб запасти) .
Спарр

Відповіді:


99

CJam - 13

q~,>{mfW=}$0=

Спробуйте це на http://cjam.aditsu.net/

Приклад введення: 2001 2014
Приклад виведення:2002

Пояснення:

q~зчитує та оцінює вхід, натискаючи 2 числа на стек (скажімо, min та max),
,робить масив [0 1 ... max-1]
>зрізає масив, починаючи з min, в результаті чого [min ... max-1]
{…}$сортує масив, використовуючи блок для обчислення ключа сортування,
mfотримує масив з усіма
W=простими множниками числа, для того , щоб отримувати останній елемент масиву (W = -1), отримуючи таким чином найбільший основний коефіцієнт, який буде використаний як ключ сортування
0=отримує перший елемент (відсортованого) масиву


38
Ну, мабуть, це все.
Ерік Треслер

5
Мені потрібно додати функцію факторизації до pyth.
isaacg

6
Ця мова є майстерною.
Бробін

8
Це так само, як просто витягнути HQ9 + s ** t, як це може бути, не ставши лазівкою. Дивовижно!
Інго Бюрк

25
ヽ ༼ ຈ ل͜ ຈ ༽ ノmfWхтось вирішив це за 13 годин .
Інтернети зроблені з Catz

66

Regex ( .NET PCRE смак), 183 129 байт

Не спробуйте цього вдома!

Це насправді не претендент на перемогу. Але Ерік Тресслер запропонував вирішити цю проблему нічим іншим, як регулярним виразом, і я не міг протистояти тому, щоб її іти. Це може бути можливим і в PCRE (і навіть коротше, див. Нижче), але я вибрав .NET, оскільки для мого рішення потрібні довільні відстані. Ось і ми:

(?<=^(1+),.*)(?=\1)(?=((11+)(?=.*(?=\3$)(?!(11+?)\4+$))(?=\3+$)|(?!(11+)\5+$)1+))(?!.+(?=\1)(?:(?!\2)|(?=((11+)(?=.*(?=\7$)(?!(11+?)\8+$))(?=\7+$)|(?!(11+)\9+$)1+)).*(?=\2$)(?=\6)))1+

Вхід кодується як включний діапазон, розділений комами, де обидва числа задаються в одинарній позначці за допомогою 1s. Матч буде заднім числом S1, де Sнайгладше число в діапазоні. Краватки розриваються на користь найменшої кількості.

Отже другим прикладом із запитання буде наступна рядок (підкреслена відповідність)

111111111,1111111111111111
                 =========

Він ґрунтується на (на сьогоднішній день досить відомим) регулярному контрольному виразі , варіації якого вбудовані там колосально 6 разів.

Ось версія з використанням вільного пробілу та коментарів для тих, хто хоче знати, що відбувається.

# Note that the beginning of the match we're looking for is somewhere
# in the second part of the input.
(?<=^(1+),.*)          # Pick up the minimum range MIN in group 1
(?=\1)                 # Make sure there are at least MIN 1s ahead

                       # Now there will be N 1s ahead of the cursor
                       # where MIN <= N <= MAX.


(?=(                   # Find the largest prime factor of this number
                       # store it in group 2.
  (11+)                # Capture a potential prime factor P in group 3
  (?=                  # Check that it's prime
    .*(?=\3$)          # Move to a position where there are exactly 
                       # P 1s ahead
    (?!(11+?)\4+$)     # Check that the remaining 1s are not composite
  )
  (?=\3+$)             # Now check that P is a divisor of N.
|                      # This does not work for prime N, so we need a 
                       # separate check
  (?!(11+)\5+$)        # Make sure that N is prime.
  1+                   # Match N
))

(?!                    # Now we need to make sure that here is not 
                       # another (smaller) number M with a smaller 
                       # largest prime factor

  .+                   # Backtrack through all remaining positions
  (?=\1)               # Make sure there are still MIN 1s ahead

  (?:
    (?!\2)             # If M is itself less than P we fail 
                       # unconditionally.
  |                    # Else we compare the largest prime factors.
    (?=(               # This is the same as above, but it puts the
                       # prime factor Q in group 6.
      (11+)
      (?=
        .*(?=\7$)
        (?!(11+?)\8+$)
      )
      (?=\7+$)
    |
      (?!(11+)\9+$)
      1+
    ))
    .*(?=\2$)          # Move to a position where there are exactly 
                       # P 1s ahead
    (?=\6)             # Try to still match Q (which means that Q is
                       # less than P)
  )
)
1+                     # Grab all digits for the match

Ви можете перевірити його онлайн тут . Не намагайтеся, проте, занадто великі входи, я не даю жодних гарантій щодо продуктивності цього монстра.

Редагувати:

Я закінчив перенести це на PCRE (що вимагає лише двох кроків) і скоротити регулярний вираз майже на третину. Ось нова версія:

^(1+),.*?\K(?=\1)(?=((11+)(?=.*(?=\3$)(?!(11+?)\4+$))(?=\3+$)|(?!(11+)\5+$)1+))(?!.+(?=\1)(?:(?!\2)|(?=((?2))).*(?=\2$)(?=\6)))1+

Це по суті те саме, з двома змінами:

  • PCRE не підтримує довільну довжину (за якою я входив MINу групу 1). Однак, PCREіснує підтримка, \Kяка скидає початок матчу на поточну позицію курсору. Звідси (?<=^(1+),.*)стає ^(1+),.*?\K, що вже економить два байти.
  • Реальна економія виходить від функції рекурсії PCRE. Я фактично не використовую рекурсії, але ви можете використовувати (?n)для nповторного узгодження групи , подібно до виклику підпрограми. Оскільки оригінальний регулярний вираз містив код для знаходження найбільшого основного коефіцієнта вдвічі, я зміг замінити всю основну частину другого простою (?2).

37
Свята мати Божа
Ньюб

1
@Timwi Мені потрібно перевірити, що найбільший основний фактор (група 3чи 7) насправді є простим. Це вимагає, щоб після першого захоплення була ще одна копія фактора, що не було б для праймесів. Хоча я працюю над цим .NET, розміщуючи кудись там, щоб я міг трохи повернутись на перевірку, у коротшій версії PCRE це було б неможливо через відсутність огляду змінної довжини. Мабуть , можна скоротити цей біт, але я не думаю, що просто змінився +на *твори.
Мартін Ендер

2
@MartinEnder Привіт! Я думаю, ви вже давно вирішили цю проблему, але я просто займався серфінгом, побачив рішення для регулярних викидів, і не міг не зупинитись на вашому попередженні вгорі цієї публікації :) Мені важко переглядати код інших людей, тому, подивившись на ваш регулярний вираз і розгубившись, я спробував це з нуля і придумав таке: (.*),.*?\K(?=(..+)((?=((?(R)\6|\2))*$).*(?=\4$)(?!(..+)\5+$)))(?!.+(?=\1)(?=(..+)(?3)).*(?!\2)\6).+ 99 байт у PCRE. Крім того, я наткнувся на багато вашої роботи на цьому сайті і я великий шанувальник: D З нетерпінням чекаю боротьби з регулярними виразками в майбутньому!
jaytea

1
Я грав у гольф-код з цим коментарем, тому я просто вставлю доповнення сюди: ви можете зняти 4b \4$, вийнявши з лукахеда і наклеївши його після негативного пошуку, але це сильно впливає на продуктивність (кожна підгрупа цифр <= \ 4 перевіряється на сумісність, а не просто на самому \ 4) і не працює на більш тривалих входах.
jaytea

1
@jaytea Вибачте за те, що назавжди з вами звернувся з цим питанням. Оскільки ви написали річ з нуля, я думаю, ви повинні опублікувати окрему відповідь. Це чудова оцінка, і ви заслуговуєте на це заслуги. :)
Мартін Ендер

16

Регекс (аромат PCRE), 66 (65🐌) байт

Натхненно побачивши, що і Мартін Ендер, і джайтея , два геніальні гегеї , писали рішення для цього коду гольфу, я написав власні з нуля. Відомий регулярний контрольний вираз не відображається ніде в моєму рішенні.

Не читайте цього, якщо ви не хочете, щоб певна манія уніарної виразки була зіпсована вам. Якщо ви хочете зняти цю магію самостійно, я настійно рекомендую почати з вирішення деяких проблем у регулярному вираженні ECMAScript:

  1. Збігайте прості номери (якщо ви ще не знайомі з цим в регулярному виразі)
  2. Відповідайте повноваженням 2 (якщо ви цього ще не зробили). Або просто пропрацюйте свій шлях через Regex Golf , який включає Prime і Powers. Не забудьте зробити як класичний, так і Teukon набір проблем.
  3. Знайдіть найкоротший спосіб узгодження потужностей N, де N - деяка константа (тобто зазначена в регулярному вираженні, а не вхідній), яка може бути складовою (але не обов'язковою бути). Наприклад, відповідні сили 6.

  4. Знайдіть спосіб узгодження N-ї сили, де N деяка константа> = 2. Наприклад, відповідні ідеальні квадрати. (Для розминки відповідайте основним силам .)

  5. Збігайте правильні заяви множення. Зіставити трикутні числа.

  6. Зіставити числа Фібоначчі (якщо ти такий же божевільний, як і я), або якщо ти хочеш дотримуватися чогось коротшого, відповідати правильним твердженням експоненції (для розминки поверніть як відповідність логарифму в базі 2 потужністю 2 - бонус, зробіть те ж саме для будь-якого числа, округлюючи його скільки завгодно) або фактичні номери (для розминки, співставляйте первісні числа ).

  7. Зрівняйся з великою кількістю (якщо ти такий же божевільний, як і я)

  8. Обчисліть ірраціональне число на потрібну точність (наприклад, розділіть вхід на квадратний корінь на 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)


11

Пітон 2, 95

i=input()
for a in range(*i):
 s=a;p=2
 while~-a:b=a%p<1;p+=1-b;a/=p**b
 if p<i:i=p;j=s                                        
print j

Знаходить гладкість чисел шляхом пробного ділення, поки число не стане 1. iзберігає найменшу гладкість поки що, jзберігає число, яке дало цю гладкості.

Дякуємо @xnor за гольфів.


1
Це if/elseповинно бути короткотерміновим. Моя перша думка така b=a%p<1;p+=1-b;a/=p**b. Або виконавець, який виконує одне з двох у переплетеному рядку. Також, можливо, while~-aпрацює.
xnor

isaacg - я люблю цю відповідь! Який геніальний спосіб ви знайшли для пошуку найбільшого основного чинника! Я оновив свою відповідь, щоб запозичити ваш метод, з кредитом вам на метод.
Тодд Леман

Чудове рішення! Використовуючи s,p=a,2, i,j=p,s, @ ідеї XNOR, видаляючи надлишкову відступ і введення блокуватися, в один рядок дає 95 символів. Не впевнений, як ви придумали 98 ...
Фалько

цей код сповнений смайликів, :)
Розенталь,

@Falko ці дві зміни не зберігають жодних символів. 7-> 7.
isaacg

10

J, 22 20 19 символів

({.@/:{:@q:)@(}.i.)

Напр

   2001 ({.@/: {:@q:)@(}. i.) 2014
2002

(Функції, що беруть два аргументи, інфіксуються в J.


Я також мав тріщину, але не зрозумів, що така відповідь. Все-таки:(#~ (= <./)@:(i:"1&1)@:*@:(_&q:))@:([ + i.@-~)
ɐɔıʇǝɥʇuʎs

Тут {:те саме, що >./і економить 1 байт.
випадкова

@randomra Ти маєш рацію - хороший дзвінок!
FireFly

Гарний. TIO, якщо ви хочете додати його: Спробуйте в Інтернеті!
Йона

9

Хаскелл, 96 94 93 86 80 символів

x%y|x<2=y|mod x y<1=div x y%y|0<1=x%(y+1)
a#b=snd$minimum$map(\x->(x%2,x))[a..b]

використання через GHCi (оболонка Haskell):

>5 # 9
8
>9 # 15
9

EDIT: тепер набагато простіший алгоритм.

це рішення включає обидва числа в діапазоні (так 8 # 9і 7 # 8обидва є 8)

пояснення:

функція (%) приймає два параметри, x і y. коли y дорівнює 2, функція повертає гладкість x.

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


ось неперероблена версія javascript з тим же алгоритмом:

function smoothness(n,p)
{
    p = p || 2
    if (x == 1)
        return p
    if (x % p == 0)
        return smoothness(x/p, p)
    else
        return smoothness(x,p+1);
}
function smoothnessRange(a, b)
{
    var minSmoothness = smoothness(a);
    var min=a;
    for(var i=a+1;i <= b;i++)
        if(minSmoothness > smoothness(i))
        {
            minSmoothness = smoothness(i)
            min = i
        }
    return min;
}

Чи можна було б псевдонім мінімум на щось коротше? Схоже, це врятувало б деяких персонажів.
isaacg

Я спробував це, але через обмеження мономорфізму він фактично коштує одного персонажа
гордий haskeller

Ви не можете просто зробити m = мінімум? Хаскелл поки що залишається загадкою.
isaacg

1
@isaacg Щоб обійти обмеження мономорфізму, потрібно було б написатиm l=minimum l
гордий haskeller

2
Я збирався опублікувати рішення Haskell, поки не побачив вашу, яка б'є навіть мою неповну версію ... +1
nyuszika7h

9

Математика, 61 45 39 символів

Range@##~MinimalBy~Last@*FactorInteger&

Дуже відверта реалізація специфікації як неназваної функції.

  • Отримайте асортимент (включно).
  • Фактор всіх цілих чисел.
  • Знайдіть мінімум, відсортований за найбільшим простим фактором.

8

Луа - 166 символів

У мене не було (поки!) Достатньо репутації, щоб коментувати рішення AndoDaan , але ось деякі вдосконалення його коду

a,b=io.read("*n","*n")s=b for i=a,b do f={}n=i d=2 while n>1 do while n%d<1 do f[#f+1]=d n=n/d end d=d+1 end p=math.max(unpack(f))if p<s then s=p c=i end end print(c)

Зміни:

  • То, n%d==0за n%d<1яким у цьому випадку рівнозначно
  • Вилучено пробіл
  • Замінено table.insert(f,d)на f[#f+1]=d ( #fкількість елементів f)

Ах, рада, що я зазирнула сюди. Ах, перші два я повинен був перевірити і зловити, але третє вдосконалення для мене нове (я маю на увазі зовсім інше, ніж те, до чого я звик). Це допоможе мені багато чого тут і знову на golf.shinh.com. Дякую!
AndoDaan

8

Bash + coreutils, 56 байт

seq $@|factor|sed 's/:.* / /'|sort -nk2|sed '1s/ .*//;q'

Вхід складається з рівно двох аргументів командного рядка (Спасибі @ nyuszika7h !!!). Вихід - це сингулярний результат, надрукований на STDOUT.

  • seq надає діапазон чисел, по одному на рядок, від аргументів командного рядка.
  • factorзчитує ці числа та виводить кожне число, за яким слідує двокрапка та відсортований список простих множників цього числа. Тож найбільший простий коефіцієнт знаходиться в кінці кожного рядка.
  • Перший sedвидаляє двокрапку та всі, крім останнього / найбільшого основного коефіцієнта, тому залишає список кожного числа (стовпець 1) та його найбільший простий коефіцієнт (стовпець 2).
  • sort чисельно в порядку збільшення за стовпцем 2.
  • Рядок підсумкових sedматчів 1 (число, чий найбільший простий коефіцієнт найменший у списку), видаляє все, включаючи і після першого пробілу, а потім закриває. sedавтоматично друкує результат цієї заміни перед тим, як закрити.

Вихід:

$ ./smooth.sh 9 15
12
$ ./smooth.sh 9 16
16
$ ./smooth.sh 157 249
162
$ ./smooth.sh 2001 2014
2002
$ 

Діапазони Примітка У цьому контексті з урахуванням обох кінцевих точок.


1
seq $@на 3 байти коротше, якщо можна припустити, що є лише два аргументи.
nyuszika7h

@ nyuszika7h Приємна ідея - дякую!
Цифрова травма

5

Пітон 2, 67

f=lambda R,F=1,i=2:[n for n in range(*R)if F**n%n<1]or f(R,F*i,i+1)

Думаючи про інший гольф, дав мені уявлення про новий алгоритм, щоб перевірити плавність, звідси пізня відповідь.

Основна факторизація факторіалу i!включає максимум саме праймери i. Отже, якщо nце добуток різних чіткостей, його гладкість (найбільший основний коефіцієнт) є найменшою, iдля якої nдільник i!. Для врахування неодноразових простих факторів n, ми можемо замість цього використовувати досить високу потужність i!. Зокрема, (i!)**nдостатньо.

Код намагається збільшити фактичні дані F=i!, оновлювані рекурсивно. Ми фільтруємо дільники Fв діапазоні вводу та виводимо їх, якщо такі є, і в іншому випадку переходимо до (i+1)!.

Тестовий випадок:

>> f([157, 249])
[162, 192, 216, 243]

4

C,  149   95

Відредагована відповідь:

Я не можу претендувати на кредит для цього рішення. Ця оновлена ​​відповідь запозичує прекрасний метод, який використовує isaacg у своєму рішенні Python. Я хотів побачити, чи можна записати це на C як вкладений for/ whileцикл без фігурних дужок, і це так!

R(a,b,n,q,p,m){for(;a<b;m=p<q?a:m,q=p<q?p:q,n=++a,p=2)while(n>1)if(n%p)p++;else n/=p;return m;}

Пояснення:

  • Функція R(a,b,n,q,p,m)сканує діапазон aдо b-1та повертає перше знайдене найгладше число. Виклик вимагає дотримання такого вигляду: R(a,b,a,b,2,0)так що змінні всередині функції ефективно ініціалізуєтьсянаступним чином : n=a;q=b;p=2;m=0;.

Оригінальна відповідь :

Це була моя оригінальна відповідь ...

P(n,f,p){for(;++f<n;)p=p&&n%f;return p;}
G(n,f){for(;--f>1;)if(n%f==0&&P(f,1,1))return f;}
R(a,b,p,n){for(;++p;)for(n=a;n<b;n++)if(G(n,n)==p)return n;}

Пояснення:

  • Функція P(n,f,p)перевіряє значення nпервинності і повертає true (ненульове значення), якщо nє простим або false (нуль), якщо nне є простим. fі pобидва повинні бути прийняті як 1.
  • Функція G(n,f)повертає найбільший основний фактор n. fповинні бути передані як n.
  • Функція R(a,b,p,n)сканує діапазон aдо b-1та повертає перше знайдене найгладше число. pповинні бути передані як 1. nможе мати будь-яке значення.

Тест-драйвер:

test(a,b){printf("smooth_range(%d, %d)\n%d\n",a,b,S(a,b,1,0));}
main(){test(5,11);test(9,16);test(9,17);test(157,249);test(2001,2014);}

Вихід:

smooth_range(5, 11)
8
smooth_range(9, 16)
9
smooth_range(9, 17)
16
smooth_range(157, 249)
162
smooth_range(2001, 2014)
2002

Я можу стверджувати, що це занепадає в пункті "Не кодуйте додаткову інформацію у вхідних даних".
Алхімік

@Alchymist - Ви можете мати рацію ... але я не думаю, що в псевдоаргументах є фактична додаткова інформація. Принаймні, не будь-яка інформація, яка є якусь підказку щодо відповіді.
Тодд Леман

4

Хаскелл - 120

import Data.List
import Data.Ord
x!y=(minimumBy(comparing(%2)))[x..y]
x%y|x<y=y|x`mod`y==0=(x`div`y)%y|otherwise=x%(y+1)

Приклад використання:

> 5 ! 10
8
> 9 ! 15
9
> 9 ! 16
16
> 157 ! 248
162
> 2001 ! 2013
2002

1
Ви не можете використовувати <1замість цього ==0?
dfeuer

Так, це було б приємне поліпшення. Є багато дрібниць, які можна зробити краще. На щастя, ця відповідь вже робить усі: codegolf.stackexchange.com/a/36461
Тейлор Фаусак

4

Q, 91 символів K, 78 символів

{(x+{where x=min x}{(-2#{x div 2+(where 0=x mod 2_til x)@0}\[{x>0};x])@0}'[(x)_til y+1])@0}

k, мабуть, поголить десяток символів

редагувати: справді трактування верхньої межі цього разу є невключною

{*:x+{&:x=min x}{*:-2#{6h$x%2+*:&:x={y*6h$x%y}[x]'[2_!x]}\[{x>0};x]}'[(x)_!y]}

4

Примітка. Ця відповідь недопустима.

Ця відповідь використовує кілька функцій Pyth, доданих після того, як було задано виклик.

Я додав ще одну нову функцію, називаючи унарний діапазон на двосторонній кортеж, що скорочує рішення на два символи до цього:

Піта , 7

hoePNUQ

Тепер введення прийнято розділяти комами. Решта ж.


У цій відповіді використовується функція Pyth, яка була додана після того, як було задано це питання, зокрема після перегляду чудового рішення CJam @ aditsu @ aditsu. Попри це, я хотів продемонструвати, що додавання цієї функції стало можливим. Особливістю є те P, що це функція arity-1, яка на цілому вході повертає список всіх простих факторів введення, відсортованих найменшим до найбільшого.

Піта , 9

hoePNrQvw

Використовує діапазони стилів Python, розділений новий рядок на STDIN. Виводить найменше рішення для STDOUT.

Пояснення:

      Q = eval(input())                         Implicit, because Q is present.
h     head(                                     First element of
 o         order_by(                            Sort, using lambda expression as key.
                    lambda N:                   Implicit in o
  e                          end(               Last element of
   PN                            pfact(N)),     List containing all prime factors of N.
  r                 range(                      Python-style range, lower inc, upper exc.
   Q                      Q,                    A variable, initialized as shown above.
   vw                     eval(input()))))      The second entry of the range, same way.

Тести:

$ newline='
'

$ echo "9${newline}16" | ./pyth.py -c 'hoePNrQvw'
9

$ echo "9${newline}17" | ./pyth.py -c 'hoePNrQvw'
16

$ echo "157${newline}249" | ./pyth.py -c 'hoePNrQvw'
162

$ echo "2001${newline}2014" | ./pyth.py -c 'hoePNrQvw'
2002

@ MartinBüttner Yep, як це запропонував його коментар до рішення
CJam

@ MartinBüttner Так, P, це нова функція. Я поставлю це у відповідь.
isaacg

1
Дозволено чи ні, не тільки мені це подобається, але я також вважаю, що ці короткі "макроси" читабельні, якщо звернути увагу - зрештою, вони перетворюються на прямий Python. Щось слід сказати для мови гольфу, яка є хорошою для гольфу, але не обов'язково пригнічує.
Kuba Ober

@KubaOber Спасибі, Кубе. Це завжди було моїм наміром писати Pyth, щоб зробити його максимально гольфним і читабельним. Я радий, що це працює.
isaacg

3

Луа - 176 символів

a,b=io.read("*n","*n")s=b for i=a,b do f={}n=i d=2 while n>1 do while n%d==0 do table.insert(f, d)n=n/d end d=d+1 end p=math.max(unpack(f))if p<s then s=p c=i end end print(c)

Я дійсно повинен припинити гольф в Луа. Немає сенсу.


14
ІМХО, кодовий гольф - це як бокс: є вагові класи. Дана мова може не виграти відверто, але це весело і освітлюючи гольф у межах цього класу / мови.
Майкл Пасха

3

Clojure - 173 170 символів

Я новачок Clojure. Гольф:

(defn g[x,d](if(and(= 0(mod x d))(.isProbablePrime(biginteger d) 1))d 0))(defn f[i](apply max-key(partial g i)(range 2(inc i))))(defn s[a,b](first(sort-by f(range a b))))

Проби:

Діапазони включають низький рівень, виключаючи високий клас: [a, b) Друкує лише одне з найгладших чисел, якщо їх зустрічається кілька.

(println (s 5 11))
(println (s 9 16))
(println (s 9 17))
(println (s 157, 249))
(println (s 2001, 2014))

врожайність:

bash$ java -jar clojure-1.6.0.jar range.clj
8
9
16
192
2002

Безголівки:

(defn g [x,d] (if (and (= 0(mod x d)) (.isProbablePrime (biginteger d) 1)) d 0))
(defn f [i] (apply max-key (partial g i) (range 2 (inc i))))
(defn s [a,b] (first (sort-by f (range a b))))

1
Діапазон, що включає нижній кінець і виключає високий кінець, зазвичай записується [a, b).
murgatroid99

так, дякую за замітку
Майкл Пасха

3

Рубі, 65 62

require'prime'
s=->a,b{(a..b).min_by{|x|x.prime_division[-1]}}

З вибаченнями за https://codegolf.stackexchange.com/a/36484/6828 , це гольф (і трохи спрощена) версія цього. Використовує інклюзивний діапазон, оскільки характер коротший.

1.9.3-p327 :004 > s[157,249]
 => 192 
1.9.3-p327 :005 > s[5,11]
 => 8 
1.9.3-p327 :006 > s[9,15]
 => 12 
1.9.3-p327 :007 > s[9,16]
 => 16 

І завдяки YenTheFirst за збереження трьох персонажів.


1
Ви можете фактично піти без [0], оскільки порівняння масиву надасть пріоритет першому елементу. Це дасть різні, але все-таки правильні результати.
YenTheFirst

3

C # LINQ: 317 303 289 262

using System.Linq;class P{static void Main(string[]a){System.Console.Write(Enumerable.Range(int.Parse(a[0]),int.Parse(a[1])).Select(i=>new{i,F=F(i)}).Aggregate((i,j)=>i.F<j.F?i:j).i);}static int F(int a){int b=1;for(;a>1;)if(a%++b<1)while(a%b<1)a/=b;return b;}}

Безголівки:

using System.Linq;

class P
{
  static void Main(string[]a)
  {
    System.Console.Write(
      Enumerable.Range(int.Parse(a[0]), int.Parse(a[1])) //create an enumerable of numbers containing our range (start, length)
        .Select(i => new { i, F = F(i) }) //make a sort of key value pair, with the key (i) being the number in question and the value (F) being the lowest prime factor
        .Aggregate((i, j) => i.F < j.F ? i : j).i); //somehow sort the array, I'm still not entirely sure how this works
  }
  static int F(int a)
  {
    int b=1;
    for(;a>1;)
      if(a%++b<1)
        while(a%b<1)
          a/=b;
    return b;
  }
}

Це займе старт і довжину з командного рядка і поверне найбільше плавне число.

Я використовував відповіді звідси і тут, щоб зробити свою відповідь.

Дякуємо VisualMelon за виправлення та гоління 12 байт! Я також позбувся дужок у if збереженні 2 байтів, і CodeInChaos вказав на явні речі, які я пропустив (ще раз дякую).


Пару дрібних речей загального призначення, ви можете зберегти 4 байти F, визначивши int bпоруч з m. У кількох місцях виконання порівняння a%b==0, а aй bзавжди позитивні ви можете вирізати байт для кожного, перевіряючи , якщо це менше , ніж 1 a%b<1. Ви також можете зберегти байт, збільшивши bйого в умові if, a%++b<0а не на, шляхом ініціалізації його до 1. Я також думаю, що в цьому випадку дешевше просто повністю кваліфікуватись System.Console.WriteLineта уникнути цього namespaceпункту.
VisualMelon

@VisualMelon Спасибі, оновлено з вашими ідеями :)
ldam

Річ m=...:m;потрапляє за межі циклу. Тому ви можете скинути m=0,і замінити return m;на return m=b>m?b:m;. Потім ви можете скинути m=...:m;цілу.
tomsmeding

Це може здатися дивним, але це - для мене менш редаговане, ніж CJam та J. Я думаю, що C # був розроблений як багатослівний, а спроби зробити його менш таким чином зробити його нечитабельним? Хм ....
Kuba Ober

Ні, я не згоден, LINQ схожий на демона, коли ти просто бачиш його тут і там і ніколи насправді з ним не граєш сам. Як тільки ви зрозумієте це, це дуже здорово :) З урахуванням сказаного, я все ще не повністю розумію, як Aggregateпрацює, я просто спробував це, побачивши його в іншій відповіді, щоб дістатися до мого нового об’єкта, а не до одного поля всередині нього, і це просто трапилося відмінно працювати :)
ldam

2

R, 83

library(gmp)
n=a:b
n[which.min(lapply(lapply(lapply(n,factorize),max),as.numeric))]

де призначено дно діапазону введення, aа верхній (включно) призначений b.

gmp- це пакет, який доступний на CRAN. Він став брудним, поки я не побачив цю абсурдну mfфункцію в CJam. Встановити, ввівши install.packages("gmp")в консолі.


1
Якщо ви використовуєте lapply3 рази, можливо, ви захочете його псевдонімом (тобто, l=lapplyа потім використовувати l(...). Так само, оскільки factorizeце єдина функція, яку ви використовуєте в пакеті, gmpяку ви можете використовувати gmp::factorizeзамість завантаження бібліотеки, а потім використання factorize. Таким чином, ваш код став би l=lapply;n=a:b;n[which.min(l(l(l(n,gmp::factorize),max),as.numeric))]69 байтами.
планнапус

2

PowerShell - 85

($args[0]..$args[1]|sort{$d=2
while($_-gt1){while(!($_%$d)){$m=$d;$_/=$d}$d++}$m})[0]

Це дозволить сортувати діапазон чисел (включно) на основі максимального проміжного коефіцієнта кожного номера. Він повертає найнижчий сортований елемент.

> smooth 5 10
8
> smooth 9 15
12
> smooth 9 16
16
> smooth 157 248
243
> smooth 2001 2013
2002

2

J - 16 знаків

Використовуючи ( початок , довжину ) стиль діапазону, як це дозволяють коментарі.

(0{+/:{:@q:@+)i.

Використовуватись як дієдіальне дієслово: лівий аргумент - початок , правий - довжина .

   5 (+)i. 6              NB. range
5 6 7 8 9 10
   5 (q:@+)i. 6           NB. prime factorizations
5 0 0
2 3 0
7 0 0
2 2 2
3 3 0
2 5 0
   5 ({:@q:@+)i. 6        NB. largest prime factors
5 3 7 2 3 5
   5 (+/:{:@q:@+)i. 6     NB. sort range by smallest factors
8 6 9 5 10 7
   5 (0{+/:{:@q:@+)i. 6   NB. take first entry
8
   f=:(0{+/:{:@q:@+)i.    NB. can also be named
   2001 f 13
2002

Рішення ( початок , кінець ) становить +2 символи і виключає кінець; включаючи кінець ще +2. Але на світлому боці це виглядає досить приємно, оскільки ми узгоджуємо всі {braces}.

(0{}./:{:@q:@}.)i.    NB. excluding
(0{}./:{:@q:@}.)1+i.  NB. including

2

Серйозно, 8 * 14/7 = 16 (неконкуренто)

,x;`yM`M;m@í@E

Серйозно було створено після цього виклику, але я хотів опублікувати цю відповідь, тому що це ілюструє тип викликів, на які серйозно добре.

Спробуйте в Інтернеті!

Пояснення:

,x;`yM`M;m@í@E
,x;             make two copies of range(a,b) (a,b = input())
   `  `M;       make two copies of the result of the map:
    yM            push maximum prime factor
         m@í    push index of minimum element from prime factors
            @E  push element from range with given index

2

Pyth , 7 байт

.mePbrF

Спробуйте тут!

[a,b)[a,b]}r

.mePbrF – Full program with arguments a and b.
     rF – Fold by half-inclusive range. Yields the integers in [a, b).
.m      – Values b in that list which give minimal results when applied f.
  ePb   – function / block f. 
   Pb   – Prime factors of b.
  e     – Last element. This is guaranteed to yield the largest, as they're sorted.

1

Кобра - 150

def f(r as vari int)
    x,y=r
    c,o=y,0
    for n in x:y,for m in n:0:-1
        p=1
        for l in 2:m,if m%l<1,p=0
        if n%m<=0<p
            if m<c,c,o=m,n
            break
    print o

Навіть не впевнений, чому я непокоївся, кобра просто не може тут змагатися.


1
Кобра виглядає ідентично пітону ... Які відмінності?
Бета-розпад

@BetaDecay Кобра - це те, що відбувається, коли ви надаєте C # синтаксис Python. Веб-сайт Cobra
Οurous

1

Рубін - 113 годин

Використання stdlib. Повертає один результат. Перевірено на рубіні 2.1.2.

require 'prime'
def smooth_range(a,b)
  (a...b).sort_by{|e|e.prime_division.flat_map{|f,p|[f]*p}.uniq.max}[0]
end

1
Ласкаво просимо до програмування головоломок та обміну коду для гольфу Code Дякуємо, що опублікували ваш результат. Оскільки це питання з кодовим гольфом, будь-ласка, включіть у свою відповідь кількість символів. Ви можете використовувати такий інструмент, як цей: javascriptkit.com/script/script2/charcount.shtml
isaacg

1

Perl (5,10+), 83

for(<>..<>){$n=$_;$p=2;$_%$p&&$p++or$_/=$p while$_>1;$m=$p,$r=$n if$p<$m||!$m}
say$r

(рядок лінії можна видалити). Бере дві кінцеві точки інклюзивного діапазону на двох рядках stdin (тому що <>дешевше, ніж доступ ARGV) і виводить найгладший для stdout. Якщо краватка є найгладшою, друкує найменшу. Можна було надрукувати найбільше ціною одного символу.

Алгоритм в основному є способом пошуку найбільшого основного чинника, хоча ми придумали його самостійно. Ця частина гольфує красиво до однієї заяви в перл, решта має більше накладних витрат, ніж хотілося б.

Слід виконувати під преамбулою perl -Eабо з її допомогою use 5.012. Якщо ви не можете цього зробити, замініть say$rна print$r,$/.


1

Пітон 2 (84)

f=lambda n,p=2:n>1and f(n/p**(n%p<1),p+(n%p>0))or p
print min(range(*input()),key=f)

@ рішення isaacg , але за minдопомогою функціональної клавіші замість явного знаходження мінімуму та рекурсивної функції, що грає роль ітерації.

Бігайте в Stackless Python, щоб уникнути меж рекурсії.

Використовувати парантезований стан виглядає марно (n%p<1), потім повторити його заперечення також у парантезах (n%p>0), але це було найкраще, що я отримав. Я спробував речі купу речей, але вони виявилися гіршими.

f(n/p**(n%p<1),p+(n%p>0))     # Current for comparison
f(*[n/p,n,p,p+1][n%p>0::2])
n%p and f(n,p+1)or f(n/p,p)
f(*n%p and[n,p+1]or[n/p,p])

Я вітаю будь-які покращення, які ви можете придумати.


1

Java 8 - 422 454 символи

Я вивчаю Java 8, і хотів би зробити цей знімок щодо Java (або навіть потоків Java 8).

Порівняно з іншими мовами, це жорстока, але цікава вправа.

Гольф:

import java.util.stream.*;import java.math.*;
class F{int v;int i;public int getV() { return v; }
F(int i){this.i = i;v=IntStream.range(2,i+1).map(j->((i%j==0)&&new BigInteger(""+j).isProbablePrime(1))?j:0).max().getAsInt();}}
public class T{
int s(int a, int b){return IntStream.range(a,b+1).boxed().map(F::new).sorted(java.util.Comparator.comparingInt(F::getV)).collect(java.util.stream.Collectors.toList()).get(0).i;}}

Безголівки:

import java.util.stream.*;
import java.math.*;

class F {
    int v;
    int i;
    public int getV() { return v; }
    F (int i) { 
        this.i = i;
        v = IntStream.range(2,i+1)
                     .map( j -> ((i%j==0) && 
                           new BigInteger(""+j).isProbablePrime(1))?j:0)
                     .max()
                     .getAsInt();
    }
}

public class T {
    int s(int a, int b) {
        return IntStream.range(a,b+1)
                    .boxed()
                    .map(F::new)
                    .sorted(java.util.Comparator.comparingInt(F::getV))
                    .collect(java.util.stream.Collectors.toList())
                    .get(0).i;
    }
}

Приклад запуску за допомогою:

public static void main(String[] s) {
    System.out.println(new T().s(157,249));
}

192

1

MATL ( неконкурентний ), 20 байт

Ця мова була розроблена після виклику

Діапазон включений на обох кінцях. Цифри приймаються як два окремі входи.

2$:t[]w"@YfX>v]4#X<)

Спробуйте в Інтернеті!

Пояснення

2$:          % implicitly input two numbers. Inclusive range
t            % duplicate                      
[]           % empty array
w            % swap elements in stack         
"            % for each                  
  @          %   push loop variable
  Yf         %   prime factors                  
  X>         %   maximum value
  v          %   vertical concatenation         
]            % end for each                         
4#X<         % arg min 
)            % index with this arg min into initial range of numbers

Я думаю, сьогодні це було б 17 байт &:[]y"@YfX>h]&X<)або, можливо, 16 :[]y"@YfX>h]&X<). &Дійсно була відмінна ідея (і я припускаю , yне був доступний тоді?).
sundar

І схоже, що трансляція Yfз префіксом 1 також тут була б корисною, але цього, мабуть, недостатньо, щоб вирішити, що це загальна ідея. :)
sundar

Так, це було на самому початку, так що немає yабо &. Подяка Suever за дуже корисну семантику останнього (моя початкова ідея полягала в тому, що вона означала «на один вхід більше, ніж за замовчуванням»). Якщо ми побачимо більше випадків, коли Yfз додаванням їх було б корисно, можливо, варто додати цю функцію. Проблема в тому, що є 34 відповіді, які використовуються Yf(відповідно до цього сценарію ), тому важко сказати
Луїс Мендо

1

Желе , 7 байт, оцінка = 7 ÷ 7 × 8 = 8, мова виклик після публікації

rÆfṀ$ÐṂ

Спробуйте в Інтернеті!

Приймає нижню та верхню кінцеві точки як два окремі аргументи. Виводить список усіх найгладших чисел у діапазоні. (Це може розглядатися як функція; в цьому випадку вихід є списком Jelly, або як повноцінною програмою; в цьому випадку для виводу використовується те саме представлення списку, що і JSON.)

Пояснення

Ті часи, коли ваша програма Jelly - це просто дослівний переклад специфікації ...

rÆfṀ$ÐṂ
r        Range from {first argument} to {second argument}
     ÐṂ  Return the elements which have the minimum
   Ṁ$      largest
 Æf          prime factor
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.