Сума послідовних непарних чисел


24

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


Виклик

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

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

  1 -> [1]
  2 -> []
  3 -> [3]
  4 -> [1, 3]
  5 -> [5]
  6 -> []
  9 -> [1, 3, 5] (зауважте, що [9] не є коректною відповіддю)
 15 -> [3, 5, 7]
104 -> [23, 25, 27, 29] (зауважте, що [51, 53] не є правильною відповіддю)

Оцінка балів

Це , тому найкоротша відповідь на кожній мові виграє.


2
Чи може моя програма просто працювати вічно, якщо немає рішення?
Денніс

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

6
Не можете 15 дати [-1, 1, 3, 5, 7]? Якщо дозволяються лише позитивні значення, ви повинні так сказати.
xnor

2
@ ЕвгенийНовиков ви пропустили 17
kalsowerus

1
@kalsowerus так. Я неправильно розумію слово "послідовно"
Євгеній Новиков

Відповіді:


11

Haskell, 67 65 63 62 58 байт

Збережено 4 байти завдяки Джуліану Вольфу

f x=[[2*n+1,2*n+3..2*m]|n<-[0..x],m<-[n..x],m^2-n^2==x]!!0

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

Я перевіряю , якщо число може бути виражено як він різницю двох квадратів: m^2-n^2. Потім я можу побудувати список послідовних непарних чисел: [2n+1,2n+3...2m-1]. Зауважте, що оскільки nобраний мінімум , виводиться найдовший список


7
Відмовившись від голосування: було б і дружнішим, і конструктивнішим додати коментар із зазначенням вашої причини, особливо, коли за новим користувачем проголосували голоси.
Джонатан Аллан

1
Якщо я чогось не пропускаю, ви можете зберегти 4 байти, лише підійшовши до xобох nіm
Julian Wolf

Щоб ви знали, користувач спільноти під час редагування вашої відповіді автоматично передав голосування. Я вважаю це помилкою . (CC @JonathanAllan)
Денніс

А-а, це було одне з таких.
Джонатан Аллан

9

Python 2 , 66 62 байт

f=lambda n,k=0,*r:n-sum(r)and f(n,k+1,*range(k%n|1,k/n,2))or r

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

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


1
Якщо вхідні значення досить високі, але є рішення, чи це призведе до RuntimeError ?
Okx

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

9

Желе ,  11  10 байт

-1 байт завдяки Деннісу (використовуйте неявну побудову діапазону - замініть Rm2Ẇна ẆḤ’)

ẆḤ’S_¥Ðḟ⁸Ṫ

Монадійне посилання, що повертає список можливостей, якщо це можливо, чи 0ні.

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

Як?

ẆḤ’S_¥Ðḟ⁸Ṫ - Link: number, n
Ẇ          - all sublists (implicit range of input) note: ordered by increasing length
           -                i.e. [[1], [2], [3], ..., [1,2], [2,3], ..., [1,2,3], ...]]
 Ḥ         - double              [[2], [4], [6], ..., [2,4], [4,6], ..., [2,4,6], ...]]
  ’        - decrement           [[1], [3], [5], ..., [1,3], [3,5], ..., [1,2,5], ...]]
        ⁸  - link's left argument, n
      Ðḟ   - filter out items for which the following yields a truthy value:
     ¥     -   last two links as a dyad:
   S       -     sum
    _      -     subtract the right from the left = sum - n
         Ṫ - tail (last and hence longest such run)

1
ẆḤ’зберігає байт.
Денніс

8

JavaScript (ES7), 87 86 85 81 байт

Повертає список цілих чисел з обмеженим комою або 0якщо рішення не існує.

n=>(g=(s,k,x=n+s)=>(x**.5|0)**2-x?k>n?0:g(s+k,k+2):(n-=k)?k+','+g(-n,k+2):k)(0,1)

Як?

Спочатку шукаємо найменший досконалий квадрат s таким, що x = n + s - ще один досконалий квадрат.

Якщо s існує, n - різниця x - s 2 досконалих квадратів, які можна записати як різницю двох послідовностей послідовних непарних чисел. Потім будуємо отриманий список.

Приклад:

Для n = 104 :

Ми знайшли s = 11² = 121, що задовольняє x = n + s = 225 = 15²

Потім:

15² = 1 + 3 + 5 + 7 + 9 + 11 + 13 + 15 + 17 + 19 + 21 + 23 + 25 + 27 + 29
11² = 1 + 3 + 5 + 7 + 9 + 11 + 13 + 15 + 17 + 19 + 21
104 = 15² - 11² = 23 + 25 + 27 + 29


3
Зачекайте, ви мені скажете, що n^2завжди дорівнює сумі перших nнепарних чисел?
Гм



7

05AB1E , 9 8 байт

-1 байт завдяки Еміньї

ÅÉŒʒOQ}н

Пояснення:

ÅÉ           Generate a list of odd numbers up to, and including, the input
  Œ          Substrings
   ʒ         Only keep values
    O          where the sum
     Q         equals the input
       }     End
             For 9, the result would look like this:
             [[1, 3, 5], [9]]
        н    Get the first value

При неправильному введенні нічого не виводиться.

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


ʒOQ}замість DO¹QÏзбереження байта.
Емінья

@JonathanAllan Docs говорять "нерівномірно", так що, можливо, було б збентежено ...
Ерік the Outgolfer

1
@JonathanAllan Невелика помилка. Виправлено.
Okx

6

Haskell , 61 60 байт

Завдяки @maple_shaft за гоління 1 байт

f n=[k|r<-[1,3..],s<-[r,r+2..n],k<-[[r,r+2..s]],sum k==n]!!0

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

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

Я хотів щось зробити з арифметикою замість жорстокого форсування k, але, fromIntegerздається, це вбило.


Ви можете зберегти один байт, змінивши [1,3..n]на[1,3..]
maple_shaft

1
Ви можете зберегти 7 байт за допомогою функції помічника r?n=[r,r+2..n]. Спробуйте в Інтернеті!
Ørjan Johansen

4

Пітон , 67 байт

f=lambda n,R=[1]:n-sum(R)and f(n,[R+[R[-1]+2],R[1:]][sum(R)>n])or R

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

Я скопіював свою відповідь із попереднього поспіль виклику підсумкових сум і змінив +1на +2. Хто знав, що код для гольфу може бути таким модульним?

Дивна пряма стратегія: пошук інтервалу Rз потрібною сумою.

  • Якщо сума занадто мала, змістіть праву кінцеву точку інтервалу вгору, додавши над ним наступне число 2.
  • Якщо сума занадто велика, підсуньте ліву кінцеву точку, видаливши найменший елемент
  • Якщо сума правильна, виведіть R.

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


4

JavaScript (ES6), 65 64 байт

f=(a,i=1)=>a>i?(c=f(a-i,i+=2))[0]==i?[i-2,...c]:f(a,i):a<i?0:[i]

Повертає масив, якщо є рішення, або 0 для рішення немає.

Це вкрай неефективний, але гострий спосіб вирішення проблеми.

Він шукає перше рішення, використовуючи, a-iі i=1навіть якщо він не працює рекурсивний стек. Якщо це рішення не починається i+2, тоді ми рекурсивно шукаємо перше рішення за допомогою aі i+2.

Безумовно

f=(a,i=1)=>
  a > i ? 
    (c = f(a - i, i += 2))[0] == i ? 
      [i-2, ...c] : 
      f(a, i) :
  a < i ? 
    0 :
    [i]

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

Щоб зрозуміти, наскільки це неефективно, рішення f(104)вимагає 69 535 рекурсивних дзвінків. Стек ніколи не перевищує 51 рівень глибиною, тому немає проблем із переповненням стека.

Для вирішення f(200)необхідних 8,6 мільйонів рекурсивних викликів, з глибиною 99 рівнів. (Його рішення є [11,13,15,17,19,21,23,25,27,29].)

Ось наочне зображення запущеної програми:


3

Python 2.7, 109 108 97 байт

11 байт вниз, Завдяки Еріку Переможнику.

Це мій перший гольф з кодом!

def f(N):
 for n in range(N):
    x=(n*n+N)**.5-n
    if x%1==0:return[2*(k+n)+1for k in range(int(x))]

Як це працює

Я використав добре відому тотожність 1 + 3 + 5 + ... + (2n - 1) = n²

Візьміть справу 15

15 = 3 + 5 + 7 = (1 + 2) + (3 + 2) + (5 + 2) = (1 + 3 + 5) + 3×2 = 3² + 3×2

Взагалі, якщо є x терміни, починаючи з 2n + 1, наприклад

(2n + 1) + (2n + 3) + (2n + 5) ... (2n + (2x-1))


Він дорівнює 2nx + x²

Якщо Nце вхідне ціле число, проблема зводиться до пошуку максимуму xтакого, що

x² + 2nx - N = 0

Це квадратичне рівняння з рішенням

x = sqrt(n² + N) - n

Найдовша послідовність - одна з найбільшою x. Програма повторює nз і 0до, Nколи виявить xце ціле число, вона створює список (2n + 1) + (2n + 3) + (2n + 5) ... (2n + (2x-1))і повертає його.



@EriktheOutgolfer, Спасибі, я забув про використання вкладок (=
dark32

3

Пітон 3, 190 81 байт

def c(q,l,i):
    if sum(l)0:
        l.append(i)
        return c(q,l,i+2)
    elif sum(l)>q:
        l.pop(0)
        return c(q,l,i)
    else:
        print(l)
c(q,[1],1)

c=lambda q,l=[1]:c(q,l+[l[-1]+2])if(sum(l)<q)*l else c(q,l[1:])if sum(l)>q else l

Завдяки @ovs та @ musicman523


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

3
Це не працює в Python 3, тому що у виклику printвідсутні дужки
musicman523

2
Ви можете видалити l.append(i)його просто за l+[i]допомогою рекурсивного дзвінка. Ви можете видалити його l.pop(0)за допомогою l[1:]рекурсивного дзвінка. Ви можете видалити дзвінок cу самому дні, використовуючи замість цього аргументи ключових слів. Ви можете видалити >0по рядку 2. Нарешті, ви можете змінити свої ifта elseвисловлювання у вирази, використовуючи потрійну форму, яка зводить вас до 92 байт як лямбда-вираз. Спробуйте в Інтернеті!
musicman523

1
На основі пропозицій @ musicman523 ми можемо скоротити умови та знизитись iдо загального значення 81 байт .
ов

Я думаю , що ви могли б змінити , sum(l)>q elseщоб q<sum(l)elseврятувати 1 байт.
Zacharý

2

QBIC , 47 байт

{_Cg=q┘q=q+2~g>:|_Xp\?g,[q,a,2|?b,┘g=g+b~g=a|_X

Це намагається підрахувати всі непарні числа від одиниці до тих пір, поки її сума не буде n. Якщо він пройде n, скиньте цикл, збільште 1 на 3 і повторіть спробу. Вийдіть, надрукувавши 0, якщо на початку циклу наш номер > n.

Пояснення

{       Do infinitely
_C      Clear the screen (we basically print every run of odd numbers, but clear out everything that doesn't sum up to n)
g=q     Set g to the first num of this cycle (q starts as 1 in QBIC)    
┘       (Syntatcic linebreak)
q=q+2   Raise q to the next odd number, this sets up both the next outer loop as well as a coming FOR loop
~g>:|   If we start out with a number > n (read as 'a' from the cmd line)
_Xp     THEN quit, printing 0 (the value of the number var 'p')
\       ELSE
[q,a,2| FOR b = q, b <= n, b+=2
?b,┘    PRINT b followed by a tab
g=g+b   Add 'b' to running total 'g'
~g=a|   and if that lands us on 'n'
_X      QUIT (printing nothing: everything is already printed)

1

R , 90 байт

f=function(x,y=1)'if'(length(w<-which(cumsum(r<-y:x*2-1)==x)),r[1:w],'if'(y>x,0,f(x,y+1)))

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

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


1

Python 2 , 89 байт

lambda n,r=range:[v for v in[r(1,n+1,2)[i:j]for i in r(n)for j in r(n+1)]if sum(v)==n][0]

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

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

Створює список усіх відповідних непарних чисел, з r(1,n+1,2)якими є range(start=1, stop=n+1, step=2); створює всі відповідні підрозрізи (плюс деякі порожні) шляхом нарізання, що від iвключно до jексклюзивного з [i:j]поперек iу [0, n), використовуючи r(n)та jв [0, n] , використовуючи r(n+1)(порожні ті , коли i>=jабо iзнаходиться поза межами); фільтри для тих, хто має правильну суму if sum(v)==n; повертає перший (і, отже, найдовший) такий фрагмент, використовуючи [0].




1

PHP , 73 байти

жодне рішення не є нескінченним циклом

for($e=-1;$s-$i=$argn;)$s+=$s<$i?$n[]=$e+=2:-array_shift($n);print_r($n);

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

PHP , 83 байти

нічого не друкує без рішення

кожен вхідний модуль 4 == 2 не має рішення

for($e=-1;($i=$argn)%4-2&&$s-$i;)$s+=$s<$i?$n[]=$e+=2:-array_shift($n);print_r($n);

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


не вдається виявити нерозв’язний вхід
Тит

@Titus fix ...
Jörg Hülsermann

0

Пітон 2 , 122 121 119 115 байт

-1 байт завдяки музиканту523. -4 байти завдяки кроку Хен. ха-ха

def f(n,R=range):r=R(1,n,2);print[i for w in R(1,len(r)+1)for i in[r[j:j+w]for j in R(len(r)-w+1)]if sum(i)==n][-1]

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


1
Це один байт коротший як функція. Спробуйте в Інтернеті!
musicman523

Збережіть байти, якщо ви повторно визначитеся range, Спробуйте це в Інтернеті!
Стівен

Це не вдається для 1 .
Денніс

0

Python 3 , 93 байти

lambda n,r=range:[[*r(s,e+1,2)]for s in r(1,n+1,2)for e in r(s,n+1,2)if(s+e)*(2+e-s)==4*n][0]

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

Єдине, що я зробив, це зазначив, що (s+e)*(2+e-s)==4*nце рівнозначно sum(range(s,e+1,2))==n, і хоча вони однакового розміру, коли r=rangeперший може бути розміщений ближче до ifтвердження.


0

Python 3 , 185 байт

def f(s):
  d={k:v for k,v in{a:(1-a+((a-1)**2+4*s)**(.5))/2 for a in range(1,s,2)}.items()if int(v)==v};m=max(d.keys(), key=(lambda k: d[k]));return list(range(int(m),int(m+2*d[m]),2))

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


Щодо того, як це працює, я намагався запропонувати трохи більш елегантне рішення, ніж простий грубій пошук. Я переставив формулу на суму арифметичної послідовності і застосував квадратичну формулу, щоб отримати вираз(1-a+((a-1)**2+4*s)**(.5))/2 , який відображається в коді. Що вираження обчислює, це задана сума sта перший доданок для арифметичної послідовностіa , довжину послідовності. Ці довжини зберігаються у словнику як значення першим термінам у вигляді ключів.

Далі всі нецілі значення видаляються зі словника, оскільки вони являють собою недійсні послідовності. Звідти ідентифікується найбільше значення і складається max(d.keys(), key=(lambda k: d[k]))послідовність непарних чисел у цій позиції та на цій довжиніlist(range(int(m),int(m+2*d[m]),2)) .


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


Це би спрацювало? repl.it/JTt7 (177 байт)
Zacharý

0

Математика, 56 байт

Last@Cases[Subsequences@Table[n,{n,1,#,2}],x_/;Tr@x==#]&

Functionз першим аргументом #. Table[n,{n,1,#,2}]обчислює список додатних непарних чисел, менших або рівних #. Subsequencesповертає всі послідовності цього списку, упорядковані за збільшенням довжини. Потім беремо, Casesяка збігається x_/;Tr@x==#, тобто послідовності xтакі, що їх сума Tr@xдорівнює вхідній #. Потім беремо Lastтаку послідовність.


0

JavaScript (ES6), 72 байти

n=>(g=s=>s?s>0?g(s-(u+=2)):g(s+l,l+=2):u-l?l+' '+g(s,l+=2):u)(n-1,l=u=1)

Повертає розділений пробілом рядок непарних чисел або кидає на недійсний вхід. 84-байтна версія, яка повертає масив (порожній, коли це доречно):

n=>n%4-2?(g=s=>s?s>0?g(s-(u+=2)):g(s+l,l+=2):u-l?[l,...g(s,l+=2)]:[u])(n-1,l=u=1):[]

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


0

PHP, 78 байт

for($b=-1;$s-$argn;)for($n=[$s=$x=$b+=2];$s<$argn;)$s+=$n[]=$x+=2;print_r($n);

нескінченна петля, якщо немає рішення. вставити ?$b>$argn+2?$n=[]:1:0після$s-$argn щоб замість цього надрукувати порожній масив.

Запустіть -nRабо спробуйте в Інтернеті .


0

C # (.NET Core) , 129 байт

(i)=>{int s,j,b=1,e=3;for(;;){var o="";s=0;for(j=b;j<e;j+=2){s+=j;o+=j+" ";}if(s==i)return o;s=s<i?e+=2:b+=2;if(b==e)return"";}};

Виводить числа в рядку з обмеженим пробілом (будь-який інший символ вимагає просто змінити " " ). Введення без рішення повертає порожній рядок (хоча, якщо працює вічно без помилок, це вірний спосіб вказати рішення, тоді 17 байт можна зберегти, видалившиif(b==e)return""; ).

Алгоритм:

  1. Почніть з [1]
  2. Якщо сума дорівнює цілі, поверніть список
  3. Якщо сума менше цільової, додайте наступне непарне число
  4. Якщо сума більша за цільову, вилучіть перший пункт
  5. Якщо список порожній, поверніть його
  6. Повторіть з 2

Можна писати (i)=>якi=>
aloisdg каже Відновити Моніку

0

C ++, 157 -> 147 байт


-10 байт завдяки DJMcMayhem

поверне 0, якщо немає відповіді, 1 в іншому випадку

останній рядок, який він друкує, - це відповідь

int f(int n){for(int i=1;;i+=2){int v=0;for(int k=i;;k+=2){v+=k;std::cout<<k<<" ";if(v==n)return 1;if(v>n)break;}if(i>n)return 0;std::cout<<"\n";}}

неозорений:

int f(int n)
{
    for (int i = 1;; i += 2)
    {
        int v = 0;
        for (int k = i;; k += 2)
        {
            v += k;
            std::cout << k << " ";
            if (v == n)
                return 1;
            if (v > n)
                break;

        }
        if (i > n)
            return 0;
        std::cout << "\n";
    }
}

це мій перший гольф-код ^^


Ви можете зберегти кілька байт, якби ви зробили це функцією int і повернули 0 або 1. Крім того, ви могли б зробити int v=0;замість цього, int v;....v=0;і якщо ви зробили свій вихідний рядок Newline, ви можете зробити, std::cout<<k<<"\n";а потім повністю видалити другий Newline
DJMcMayhem

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

0

Котлін, 152 байти

fun f(a:Double){var n=Math.sqrt(a).toInt()+1;var x=0;while(n-->0){if(((a/n)-n)%2==0.0){x=((a/n)-n).toInt()+1;while(n-->0){println(x.toString());x+=2}}}}

Спробуйте в Інтернеті (зачекайте 4-5 секунд, компілятор повільний)

Безумовно

fun f(a: Double){
    var n=Math.sqrt(a).toInt()+1;
    var x=0;

    while(n-->0){
        if(((a/n)-n)%2==0.0){
            x=((a/n)-n).toInt()+1;

            while(n-->0){
                println(x.toString());
                x+=2;
            }

        }
    }
}

0

Excel VBA, 139 байт

Subnпорядок, який приймає введення очікуваного цілого типу і повідомляє про найдовшу послідовність послідовних непарних чисел до комірки[A1]

Sub a(n)
For i=1To n Step 2
s=0
For j=i To n Step 2
s=s+j
If s=n Then:For k=i To j-1 Step 2:r=r &k &"+":Next:[A1]=r &j:End
Next j,i
End Sub
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.