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


17

Формула

Візьмемо для прикладу число 300

  • Основними факторами 300 є [2, 3, 5](унікальні числа, які є коефіцієнтами 300 і простими)
  • Сквактування кожного з цих чисел дасть вам [4, 9, 25]
  • Підсумовуючи цей список, ви отримаєте 4 + 9 + 25 = 38
  • Нарешті відніміть цю суму (38) від початкового числа 300-38 = 262(це результат)

Вхідні дані

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


Вихідні дані

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


Випробування

Input: 3       Output: 2, -2
Input: 10      Output: 8, 4
Input: 50      Output: 48, 35
Input: 1000    Output: 1000, 971
Input: 9999    Output: 9984, 9802


Опрацьовано за прикладом

Розглянемо вхід 10, ми повинні запустити формулу для всіх чисел від 2-10 (включно)

Num PrimeFacs PrimeFacs^2 SumPrimeFacs^2 Result
2   [2]       [4]         4              -2
3   [3]       [9]         9              -6
4   [2]       [4]         4               0
5   [5]       [25]        25             -20
6   [2, 3]    [4, 9]      13             -7
7   [7]       [49]        49             -42
8   [2]       [4]         4               4
9   [3]       [9]         9               0
10  [2, 5]    [4, 25]     29             -19

Як бачите, найбільший результат - 4результат введення значення 8у формулу. Це означає, що вихід для входу 10повинен бути8, 4


Підрахунок та правила

Діють правила за замовчуванням для входів і виходів: За замовчуванням для Code Golf: Методи введення / виведення
Стандартні лазівки заборонені: Пропуски, заборонені за замовчуванням.
Подання можуть бути функціями або повними програмами

Виграє найкоротший код у байтах


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

2
Що повинно статися, якщо для максимального результату пов'язано кілька чисел?
Денніс

1
@ Денніс, чи прийнятно я дозволяти, щоб це було будь-яке число, яке генерує максимальний результат? Я не хочу нав'язувати нове правило, яке порушує всі існуючі рішення.
Кітінг

2
Так, це, мабуть, найкращий варіант. 950 може бути прикладом, коли і [900, 862], і [945, 862] були би достовірними відповідями.
Денніс

1
Можу чи я виводити числа в зворотному порядку, наприклад , для введення 50: 35, 48?
німі

Відповіді:



4

Java 8 лямбда, 247 239 233 225 224 219 198 161 символ

Я думав, що це повинно бути можливим за менше 300 символів, тому що ... ти знаєш ... Ява!

І це дійсно можливо навіть за менше 200 символів!

m->{int n=1,u,f,F[],g,G=g=1<<31;for(;++n<=m;){u=n;F=new int[m+1];for(f=1;++f<=u;)u/=u%f<1?(F[f]=f--):1;f=0;for(int p:F)f+=p*p;g=n-f>g?(G=n)-f:g;}return G+","+g;}

Я не знаю, чи законне це використання імпорту, але я припускаю, що це повинно бути нормально. Ось лямбда невольф на клас:

public class Q80507 {
    static String greatestAfterReduction(int maxNumber) {
        int number = 1, upper, factor, primeFactors[], greatestResult, greatestNumber = greatestResult = 1 << 31; // <-- Integer.MIN_VALUE;
        for (;++number <= maxNumber;) {
            // get unique primefactors
            upper = number;
            primeFactors = new int[maxNumber + 1];
            for (factor = 1; ++factor <= upper;)
                upper /= upper % factor < 1 ? (primeFactors[factor] = factor--) : 1;

            factor = 0;
            for (int prime : primeFactors)
                factor += prime * prime;

            greatestResult = number - factor > greatestResult ? (greatestNumber = number) - factor : greatestResult;
        }
        return greatestNumber + "," + greatestResult;
    }
}

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

Оновлення

Видалено новий рядок з виводу.

Дякуємо @ogregoire за те, що ви граєте в Integer.MIN_VALUE до 1 << 31!

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

Дякуємо @Blue за фокус == 0 до <1!

Видалено пробіл, що залишився. Також для поділу потрібен лише один знак, тому не потрібно витрачати один.

Ще раз дякую @ogregoire за вказівку, що я можу повернути значення замість того, щоб надрукувати його і скласти декларації! Це багато заощадило!

З'ясував, що я можу використовувати тернар замість другого, якщо врятувати ще одну таблицю.

Завдяки @AstronDan для дивного використання масиву , який зберігає імпорт. Це також дало мені можливість скоротити перше, якщо в потрійне.


1
Integer.MIN_VALUEможна скоротити як 1<<31.
Олів'є Грегоар

1
Збережіть 1 байт, якщо замість цього (u% f <1)
Blue

1
Декларуйте всі свої ints на одному і тому ж місці, щоб уникнути повторення intдекількох разів, і присвойте їм їх значення, якщо це можливо.
Олів'є Грегоар

1
Крім того, позбудьтесь цього System.out.println(...)і поверніть значення замість того, щоб друкувати: як згадується в ОП, використовується стандартний метод вводу / виводу.
Олів'є Грегоар

1
Ви також можете використовувати трюк масиву, який я використовував у C #, щоб перетворити хешсет у масив int. Це, ймовірно, дозволить вам скинути імпорт, заощадивши багато байтів.
AstroDan

3

Власне, 21 байт

u2x;`;y;*@-`M;M;)@í@E

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

Пояснення:

u2x;`;y;*@-`M;M;)@í@E
u2x;                   push two copies of range(2, n+1) ([2, n])
    `      `M          map:
     ;                   duplicate
      y;                 push two copies of prime divisors
        *                dot product of prime divisors lists (equivalent to sum of squares)
         @-              subtract from n
             ;M;)      duplicate, two copies of max, move one copy to bottom of stack
                 @í    get index of max element
                   @E  get corresponding element from range

Чи можете ви зв’язатись із цією мовою?
Не те, що Чарльз

1
@NotthatCharles Ви можете натиснути назву мови в онлайн-перекладачі.
Денніс

Гаразд, я Actually Programming Languageне знайшов нічого навіть після перегляду 5-ї сторінки результатів Google. Що це за мова?
Техас Кале

2
@Tejas Ви можете натиснути назву мови, яка надішле вас до джерела: github.com/Mego/Seriously
Amndeep7,

3

MATL , 18 байт

:"@tYfu2^s-]v2#X>w

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

Останній випадок займає онлайн-компілятор занадто багато часу, але він дає правильний результат (на моєму комп’ютері, працює на Matlab, це займає близько 11 секунд):

enter image description here

Пояснення

Безпосереднє застосування описаної процедури.

:         % Implicit input n. Range [1 2 ... n]
"         % For each
  @       %   Push that number
  tYfu    %   Duplicate. Prime factors. Unique values
  2^s-    %   Square. Sum of array values. Subtract
]         % End for each
v         % Concatenate stack contents into vertical vector
2#X>      % Max and arg max
w         % Swap. Implicit display         

3

C #, 194 байт

Мій перший гольф Code :). Я використовував свою улюблену мову, незважаючи на її багатослівність. Я розпочав це як порт функцій C # Java @ Frozn, але знайшов кілька способів зменшити код додатково за допомогою оптимізацій.

string R(int a){int u,f,g,N=g=1<<31;for(int n=1;++n<=a;){u=n;int[]P=new int[a+1];for(f=1;++f<=u;){if(u%f<1){u/=f;P[f]=f--;}}f=0;foreach(var p in P){f+=p*p;}if(n-f>g){g=(N=n)-f;}}return N+","+g;}

Для цього використовується масив для зберігання простих факторів. Оскільки він індексується фактором, він замінить повторні чинники копіями фактора. Це дозволяє функції не мати імпорту. Для цього навіть не потрібна Система.


Це дійсно приємний трюк! Спробую використовувати його в моїй версії
Frozn

3

Bash + GNU комунальні послуги, 74

seq 2 $1|factor|sed -r 's/:?( \w+)\1*/-\1*\1/g'|bc|nl -v2|sort -nrk2|sed q
  • seq генерує всі цілі числа 2 до n
  • factorдає число, за яким слідує двокрапка, а потім розділений пробілом список всіх простих факторів, включаючи дублікати. наприклад результат за 12 є12: 2 2 3
  • sedвидаляє товсту кишку і дублюють фактори, потім генерує необхідну арифметичну експресію. наприклад для 12:12- 2* 2- 3* 3
  • bc оцінює це
  • nl префікси n назад у (починаючи з 2)
  • sort другим стовпцем, чисельно, у порядку зменшення
  • seq друкує перший рядок і закриває.

Ідеон.


2

Брахілог , 48 байт

:2:{eI$pd:{:2^.}a+:I--:I.}fF$\hor:0m:Ir.r~m[F:J]

Пояснення

Main predicate:

:2:{}fF                     Unify F with the list of all binding for which predicate 1 is
                            true, given [Input, 2] as input.
       $\hor:0m             Retrieve the max of F by diagonalizing it, taking the
                            first row, sorting that row and reversing the sorted row.
               :Ir.         Unify the Output with [I, Max],
                   r~m[F:J] [I, Max] is in F at index J (the index is unimportant)


Predicate 1:

eI                          I is an integer in the range given in Input
  $pd                       Get the list of prime factors of I, with no duplicates
     :{:2^.}a               Apply squaring to each element of that list
             +              Sum the list
              :I-           Subtract I from the sum
                 -          Multiply by -1 (let's call it Result)
                  :I.       Unify the Output with [Result, I]

2

Желе , 13 байт

ÆfQ²S_@,µ€ḊṀṚ

Спробуйте в Інтернеті! або перевірити всі тестові випадки .

Як це працює

ÆfQ²S_@,µ€ḊṀṚ  Main link. Argument: n

        µ      Combine the chain to the left into a link.
         €     Apply it to each k in [1, ..., n].
Æf               Yield k's prime factors as a list.
  Q              Unique; deduplicate the prime factors.
   ²             Square each unique prime factor.
    S            Compute their sum.
     _@          Subtract the result from k.
       ,         Pair with k, yielding [result(k), k].
          Ḋ    Dequeue; discard the first pair which corresponds to k = 1.
           Ṁ   Get the maximum (lexicographical order).
            Ṛ  Reverse the pair.

2

05AB1E, 19 17 16 байт

Код:

L©f€n€O®-®)ø¦{¤R

Пояснення:

L                    # make a list of 1..input [1,2,3,4,5,6]
 ©                   # save the list for reuse
  f                  # get primefactors of numbers in list [[],[2],[3],[2],[5],[2,3]]
   €n                # square each factor [[],[4],[9],[4],[25],[4,9]]
     €O              # sum the factors [0,4,9,4,25,13]
       ®-            # subtract from saved list [1,-2,-6,0,-20,-7]
         ®)ø         # zip with saved list [[1,1],[-2,2],[-6,3],[0,4],[-20,5],[-7,6]]
            ¦        # drop the first item (n=1) [[-2,2],[-6,3],[0,4],[-20,5],[-7,6]]
             {       # sort [[-20,5],[-7,6],[-6,3],[-2,2],[0,4]]
              ¤      # get last item [0,4]
               R     # reverse [4,0]

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


2

Юлія, 56 байт

!n=maximum(k->(k-sumabs2(k|>factor|>keys),k),2:n)[[2,1]]

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

Як це працює

З огляду на вхід n , для кожного цілого k, такого, що 2 ≤ k ≤ n , ми формуємо кортеж (f (k), k) , де f (k) - різниця між k і сумою квадратів його простих факторів .

f (k) обчислюється самим k-sumabs2(k|>factor|>keys), котрий коефіцієнт k в Дікт прових ключів і значень експонента витягує всі ключі (прості множники), бере суму їх квадратів і віднімає отримане ціле число від k .

Нарешті, ми беремо лексикографічний максимум утворених кортежів і повертаємо їх, отримуючи доступ до індексів 2 та 1 .


1

Clojure, 215 байт

(fn j[x](apply max-key second(map(fn[w][w(- w(let[y(reduce +(map #(* % %)(set(flatten((fn f[q](let[c(filter(fn[r](=(mod q r)0))(range 2 q))](if(empty? c)q(map f c))))w)))))](if(= y 0)(* w w)y)))])(range 2(inc x)))))

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

Ви можете побачити його онлайн тут: https://ideone.com/1J9i0y


1

R 109 байт

y=sapply(x<-2:scan(),FUN=function(x)x-sum(unique(as.numeric(gmp::factorize(x))^2)));c(x[which.max(y)],max(y))

Я обманював і використовував пакет, gmp.




1

PowerShell v2 +, 124 120 117 байт

2..$args[0]|%{$y=$z=$_;2..$_|%{$y-=$_*$_*!($z%$_)*('1'*$_-match'^(?!(..+)\1+$)..')};if($y-gt$o){$o=$y;$p=$_}}
"$p $o"

Перший рядок обчислює значення, другий - лише вихід.

Ми починаємо із створення діапазону від 2нашого аргументу командного рядка $args[0]і циклуємо це |%{...}. Кожен цикл, з якого ми встановлюємо допоміжні змінні, рівний нашому поточному значенню $y=$z=$_. Потім ми перебираємо кожне число від 2нашого поточного номера. Кожну внутрішню петлю ми перевіряємо, чи є це число дільником !($z%$_)і чи є простим ('1'*$_-match'^(?!(..+)\1+$)..') , і якщо це обидва, ми віднімаємо квадрат від$y (перевірки виконуються за допомогою булевого множення).

Після того як ми пройшли всі прості дільники і відняли квадрати, якщо число, що залишилося, найбільше, що ми бачили досі $y-gt$o, ми встановлюємо вихідні змінні $o=$y;$p=$_. Після того, як ми переглянемо весь діапазон, ми просто виводимо пробіл між ними.


1

Haskell, 91 байт

f m=reverse$maximum[[n-sum[p^2|p<-[2..n],mod n p<1,mod(product[1..p-1]^2)p>0],n]|n<-[2..m]]

Приклад використання: f 50-> [48,35].

Функції основного фактора доступні лише за допомогою import Data.Numbers.Primesяких коштує занадто багато байтів, тому я використовую основну перевірку @ Lynn . Решта пряма вперед: для вхідної mпетлі nнаскрізь [2..m]і у внутрішню петлю pнаскрізь [2..n]. Зберігайте все, pщо є простим і ділиться n, квадратом і сумою.


1

Python 2, 108 105 100 байт

f=lambda n,m=2,p=1:m>n or-~f(n,m+1,p*m*m)-(n%m<p%m)*m*m
r=max(range(2,input()+1),key=f)
print r,f(r)

Перевірте це на Ideone .


1

JavaScript (ES6), 111 105 байт

f=n=>{r=n<2?[]:f(n-1);for(s=[],j=n,i=2;j>1;k%i?i++:j/s[i]=i);s.map(i=>j-=i*i,j=n);return j<r[1]?r:[n,j]}

Поняття не маю, чому я не думав робити це рекурсивно раніше.


1

J, 44 байти

[:((],.~2+I.@e.)>./)@:}.1(-[:+/*:@~.@q:)@+i.

Прямий підхід. Також повертає всі значення nцього результату в максимальне значення.

Використання

   f =: [:((],.~2+I.@e.)>./)@:}.1(-[:+/*:@~.@q:)@+i.
   f 3
2 _2
   f 10
8 4
   f 50
48 35
   f 1000
1000 971
   f 9999
9984 9802
   f 950
900 862
945 862
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.