Qvolume цілого числа


31

Стародавнім є знання про те, що кожне невід'ємне ціле число можна переписати як суму чотирьох квадратних цілих чисел. Наприклад, число 1 можна виразити як . Або взагалі для будь-якого невід’ємного цілого числа існують цілі числа такі02+02+02+12na,b,c,d

n=a2+b2+c2+d2

Джозеф-Луї Лагранж довів це в 1700-х роках, і тому його часто називають теоремою Лагранжа .

Це іноді обговорюється стосовно кватерніонів - типу числа, виявленого Вільямом Гамільтоном у 1800-х роках, представленого як

w+xi+yj+zk
де w,x,y,z - дійсні числа, і i,j і k це окремі уявні одиниці, які не множать комутативно. Зокрема, це обговорюється стосовно квадратування кожного компонента кватерніона
w2+x2+y2+z2
Ця кількість іноді називається нормою, або квадратичною нормою , або також квадратом . Деякі сучасні докази теореми Лагранжа використовують кватерніони.

Рудольф Ліпшиц вивчав кватерніони з лише цілими компонентами, звані кватерніонами Ліпшица. Використовуючи квадрати, ми можемо уявити, що кожен кватерніон Ліпшица може думати про наявність друга в цілих числах. Наприклад, кватерніон 0+0i+0j+1k можна вважати пов'язаним з цілим числом 1=02+02+02+12 . Крім того, якщо ми повернемось назад, то кожне ціле число можна вважати таким, що має друга в кватерніонах Ліпшица.

Але є цікава деталь теореми Лагранжа - підсумок не є унікальним. Кожне ціле число може мати кілька різних наборів з чотирьох квадратів, які можна підсумувати для його створення. Наприклад, число 1 можна виразити чотирма способами, використовуючи невід’ємні цілі числа (розглянемо лише негативні для цього завдання):

1=02+02+02+12
1=02+02+12+02
1=02+12+02+02
1=12+02+02+02

Підсумки завжди є квадратами 0 або 1, але вони можуть бути в різних положеннях у виразі.

Для цього виклику давайте також "сортувати" наші суми найнижчих до найвищих, щоб усунути дублікати, щоб ми могли вважати для цієї вправи, що 1 має лише один спосіб представлення як суму чотирьох квадратів:

1=02+02+02+12

Інший приклад - число 42, яке можна виразити чотирма способами (знову ж таки, враховуючи лише негативні елементи a, b, c, d та усунення дублюючих компонентів)

42=02+12+42+52
42=12+12+22+62
42=12+32+42+42
42=22+22+32+52

Що робити, якщо уявити кожен із цих різних способів вираження цілого числа як асоційованого з конкретним кватерніоном? Тоді можна сказати, що число 42 пов'язане з цими чотирма кватерніонами:

0+1i+4j+5k
1+1i+2j+6k
1+3i+4j+4k
2+2i+3j+5k

Якщо уявити стандартну інтерпретацію комп'ютерної графіки кватерніона, де , і є векторами в тривимірному евклідовому просторі, і так компоненти , і кватерніона є тривимірними декартовими координатами, то ми можемо уявити, що кожне ціле число, через цей процес мислення, може бути пов'язане з набором 3-х мірних координат у просторі. Наприклад, число 42 пов'язане з такими чотирма координатами :ijkxyz(x,y,z)

(1,4,5),(1,2,6),(3,4,4),(2,3,5)

Це можна розглядати як точку хмари або набір точок у просторі. Тепер одна цікава річ про набір кінцевих точок у просторі - це те, що завжди можна намалювати навколо них мінімальний обмежувальний ящик - короб, який достатньо великий, щоб вмістити всі точки, але не більший. Якщо ви уявляєте коробку як звичайний ящик, вирівняний з осями , він називається обмежувальним вікном, орієнтованим на вісь . Обмежувальний ящик також має об'єм, обчислюється шляхом визначення його ширини, довжини та висоти та множення їх разом.x,y,z

Тоді ми можемо уявити об'єм обмежувального поля для точок, утворених нашими кватерніонами. Для цілого числа 1 маємо, використовуючи критерії цієї вправи, один кватерніон, квадрант якого 1, . Це дуже проста хмара точок, вона має лише одну точку, тому в обмежувальній коробці є об'єм 0. Однак для цілого числа 42 у нас є чотири кватерніони, і так чотири точки, навколо яких ми можемо намалювати обмежувальне поле. Мінімальна точка коробки - а максимальна - призводить до ширини, довжини та висоти 2, 2 та 2, що дає об'єм 8.0+0i+0j+1k(1,2,4)(3,4,6)

Скажімо, що для цілого qvolume - це об'єм осі, обмеженої віссю обмежувальної коробки всіх 3D-точок, утворених кватерніонами, що мають квадрант, рівний , де компоненти кватерніона є негативними і .nnw+xi+yj+zkw<=x<=y<=z

Створіть програму або функцію, яка, отримавши одне невід'ємне ціле число , виведе 's qvolume.nn

Приклади:

input -> output
0 -> 0
1 -> 0
31 -> 4
32 -> 0
42 -> 8
137 -> 96
1729 -> 10032

Це код-гольф, найменша кількість виграних байтів.


що мені потрібно додати? я мав намір зазначити, що найменша кількість байтів переможе
нехай яскраво

3
Ви забули тег коду-гольфу, я допоміг вам його додати
Втілення Незнання

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

1
Так, але чому б брати лише i, j, k як простір 3D, але не 4D простір?
tsh

1
@tsh, тому що кватерніони не обов'язково представляють 4-мірний евклідовий простір. Гамільтон відкрив їх під час пошуку способу роботи з 3-мірним простором. Можна було б зробити 4d версію, але я розмірковував над їх використанням у 3d-просторі, коли я поставив питання
нехай яскраво

Відповіді:


13

Мова Вольфрама (Mathematica) , 67 58 байт

Volume@BoundingRegion[Rest/@PowersRepresentations[#,4,2]]&

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

                         ...&   Pure function:
PowersRepresentations[#,4,2]    Get the sorted reprs. of # as sums of 4 2nd powers
Rest/@                         Drop the first coordinate of each
BoundingRegion[...]            Find the bounding region, a Cuboid[] or Point[].
                               By default Mathematica finds an axis-aligned cuboid.
Volume                         Find volume; volume of a Point[] is 0.

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

4
Лол, Математика навіть має вбудований для визначення козлів на зображенні , тому наявність вбудованого для цього насправді не дивує мене. xD
Kevin Cruijssen

8

Желе , 17 байт

Żœċ4²S⁼ɗƇ⁸ZḊṢ€I§P

Спробуйте в Інтернеті! (досить повільно - зробіть це досить швидко для всіх тестових випадків із ведучим½ )

Як?

Żœċ4²S⁼ɗƇ⁸ZḊṢ€I§P - Link: non-negative integer, n    e.g. 27
Ż                 - zero-range                            [0,1,2,...,27]
   4              - literal four                          4
 œċ               - combinations with replacement         [[0,0,0,0],[0,0,0,1],...,[0,0,0,27],[0,0,1,1],[0,0,1,2],...,[27,27,27,27]]
        Ƈ         - filter keep those for which:          e.g.: [0,1,1,5]
       ɗ          -   last three links as a dyad:
    ²             -     square (vectorises)                     [0,1,1,25]
     S            -     sum                                     27
      ⁼  ⁸        -     equal to? chain's left argument, n      1
                  -                                       -> [[0,1,1,5],[0,3,3,3],[1,1,3,4]]
          Z       - transpose                             [[0,0,1],[1,3,1],[1,3,3],[5,3,4]]
           Ḋ      - dequeue                               [[1,3,1],[1,3,3],[5,3,4]]
            Ṣ€    - sort each                             [[1,1,3],[1,3,3],[3,4,5]]
              I   - incremental differences (vectorises)  [[ 0,2 ],[ 2,0 ],[ 1,1 ]]
               §  - sum each                              [2,2,2]
                P - product                               8

6

Haskell , 132 123 байт

z=zipWith
(!)=foldr1.z
h n=[0..n]
f n|p<-[[c,b,a]|a<-h n,b<-h a,c<-h b,d<-h c,a^2+b^2+c^2+d^2==n]=product$z(-)(max!p)$min!p

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

Досить просте рішення. Брут примусити всі можливі рішення шляхом повторення всіх значень від 0 до n (спосіб перевибору, але коротший рахунок). Я виводжу точку як список, щоб ми могли використовувати магічний (!)оператор @ Lynn . Цей оператор згортає кожен вимір з функцією зліва, тому max!pповертає список розміру 3, який складається з максимумів уздовж кожного виміру і min!pробить те ж саме для мінімуму. Тоді ми просто знаходимо мінімальний розмір у кожному вимірі (віднімаючи мінімальну величину від max з z(-)) і множимо їх разом.

Дякую @Lynn за зняття 9-ти байтів із складної поштової магії!


1
Я відголив кілька байт, відмовившись від транспозиції на користь певної zipWithлогіки. 123 байт
Лінн

5

Кувалда 0,2, 12 байт

⡌⢎⣟⡊⢘⣚⡏⡨⠍⠁⡇⠨

Використовуйте разом з Mathematica 11.2 та цією версією кувалди, яка передує виклику. Перегляньте історію редагування для версії, яка працює у версії 0.3, яка має графічний інтерфейс і генерує вираз Mathematica.

Це виштовхує вхід до стеку і викликає послідовність команд

{intLiteral[4], intLiteral[2], call["PowersRepresentations", 3], call["Thread", 1], call["Rest", 1], call["Thread", 1], call["BoundingRegion", 1], call["Volume", 1]}

що еквівалентно оцінці наступного коду Wolfram, отриманого з моєї відповіді на мову Wolfram :

Volume[BoundingRegion[Thread@Rest@Thread@PowersRepresentations[#, 4, 2]]]&

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


чи потрібна це математика для її перевірки?
Дон яскравий

@don яскравий Так, сховище має вказівки. Це незавершена робота, поки не дуже зручна у користуванні. Після запуску setup.wls ви можете протестувати або за допомогою wolframscript або interactive_app.wls.
ліртосіаст

2
@Downgoat Так. Я планую впровадити бібліотеку з гольфу, але наразі вона розкладається на звичайну Mathematica.
ліртосіаст

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

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

4

Python 2 , 138 байт

q=lambda n,x=0,*t:[t]*(n==0)if t[3:]else q(n-x*x,x,x,*t)+q(n,x+1,*t+(0,)*(x>n))
p=1
for l in zip(*q(input()))[:3]:p*=max(l)-min(l)
print p

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

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

itertools Можливо, вистрілив, якби він не використовував смішно довгі імена на кшталт itertools.combinations_with_replacement

Пітон 2 , 161 байт

from itertools import*
n=input();p=1
for l in zip(*[t[1:]for t in combinations_with_replacement(range(n+1),4)if sum(x*x for x in t)==n]):p*=max(l)-min(l)
print p

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

Ось чому itertoolsніколи не є відповіддю .


3

JavaScript (ES6),  148  143 байт

n=>(r=[[],[],[]]).map(a=>p*=a.length+~a.indexOf(1),(g=(s,k=0,a=[])=>a[3]?s||r.map(r=>r[a.pop()]=p=1):g(s-k*k,k,[...a,++k],k>s||g(s,k,a)))(n))|p

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

Прокоментував

Ми ініціалізуємо масив з 3 порожніми масивами.r

r = [ [], [], [] ]

Для кожного дійсного значення ми встановимо значення у у першому масиві. Дітто для і з 2-м і 3-м масивами відповідно.x1x+1yz

Розміри обмежувального вікна будуть виведені з відстані між першим і останнім записом, встановленим на в цих масивах.1

Крок 1

Для заповнення ми використовуємо рекурсивну функцію .rg

g = (              // g is a recursive function taking:
  s,               // s   = current sum, initially set to the input n
  k = 0,           // k   = next value to be squared
  a = []           // a[] = list of selected values
) =>               //
  a[3] ?           // if we have 4 values in a[]:
    s ||           //   if s is equal to zero (we've found a valid sum of 4 squares):
      r.map(r =>   //     for each array r[] in r[]:
        r[a.pop()] //       pop the last value from a[]
        = p = 1    //       and set the corresponding value in r[] to 1
                   //       (also initialize p to 1 for later use in step 2)
      )            //     end of map()
  :                // else:
    g(             //   do a recursive call:
      s - k * k,   //     subtract k² from s
      k,           //     pass k unchanged
      [...a, ++k], //     increment k and append it to a[]
      k > s ||     //     if k is less than or equal to s:
        g(s, k, a) //       do another recursive call with s and a[] unchanged
    )              //   end of outer recursive call

Крок 2

Тепер ми можемо обчислити добуток розмірів.p

r.map(a =>         // for each array a[] in r[]:
  p *=             //   multiply p by:
    a.length +     //     the length of a[]
    ~a.indexOf(1)  //     minus 1, minus the index of the first 1 in a[]
) | p              // end of map(); return p



1

Haskell , 108 байт

n%i=sum[maximum[t!!i*b|t<-mapM([0..n]<$f)[0..3],sum(map(^2)t)==n,scanr1 max t==t]|b<-[-1,1]]
f n=n%0*n%1*n%2

Спробуйте в Інтернеті! (тайм-аут на великих тестових випадках)

Тут є якісь дивні оптимізації. Для обчислення maximum l-minimum lсписку lелементів у заданій позиції виявляється коротшим у контексті перетворення їх обох у максимуми, відкидаючи другий доданок: maximum l+maximum(map((-1)*))lабо рівнозначно sum[maximum$map(b*)l||b<-[-1,1]].

Щоб помножити три виміри, виявляється коротше просто написати твір, f n=n%0*n%1*n%2ніж використовувати будь-який цикл. Тут n%iрізниця між min та max i'-ї значень координат, які витягуються за допомогою індексації !!i.

Щоб генерувати дійсні чотири-кортежі, ми беремо списки з чотирьох чисел [0..n], квадрати яких дорівнюють nі знаходяться у зменшенному порядку. Ми перевіряємо реверс-sortedness з tз scanr1 max t==t, який бачить , якщо працює максимум реверсу себе, так як Haskell не має вбудованого роду без дорогого імпорту. Я спробував різні способи рекурсивно генерувати чотири-кортежі, як у моїх відповідях Python, але всі вони були довші, ніж цей спосіб генерування та фільтрування грубої сили.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.