Число целого числа

31

Это древнее знание, что каждое неотрицательное целое число может быть переписано как сумма четырех квадратов целых чисел. Например, число 1 может быть выражено как 02+02+02+12 . Или, вообще, для любого неотрицательного целого числа N существуют целые числа a,б,с,d такие что

Nзнак равноa2+б2+с2+d2

Джозеф-Луи Лагранж доказал это в 1700-х годах, и поэтому его часто называют теоремой Лагранжа .

Это иногда обсуждается в связи с кватернионами - типом чисел, обнаруженным Уильямом Гамильтоном в 1800-х годах, представленном как

вес+Икся+YJ+ZК
где вес,Икс,Y,Z - действительные числа, а я,J и К - это различные мнимые единицы, которые не размножаются коммутативно. В частности, это обсуждается в связи с возведением в квадрат каждого компонента кватерниона
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+1я+4J+5К
1+1я+2J+6К
1+3я+4J+4К
2+2я+3J+5К

If we imagine the standard computer graphics interpretation of a quaternion, where я, J and К are vectors in three dimensional Euclidean space, and so the Икс, Y and Z components of the quaternion are 3 dimensional Cartesian coordinates, then we can imagine that each integer, through this thought process, can be associated with a set of 3 dimensional coordinates in space. For example, the number 42 is associated with the following four (Икс,Y,Z) coordinates:

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

Это можно рассматривать как облако точек или набор точек в пространстве. Теперь, одна интересная вещь о наборе конечных точек в пространстве - это то, что вы всегда можете нарисовать вокруг них минимальную ограничивающую рамку - коробку, которая достаточно велика, чтобы вместить все точки, но не больше. Если вы представляете, что это обычное поле, выровненное по осям Икс,Y,Z , оно называется ограничивающим прямоугольником, выровненным по оси . Ограничительная рамка также имеет объем, который вычисляется путем определения его ширины, длины и высоты и умножения их вместе.

Затем мы можем представить объем ограничивающего прямоугольника для точек, образованных нашими кватернионами. Для целого числа 1 мы используем, используя критерии этого упражнения, один кватернион, чей квадрант равен 1, 0+0я+0J+1К . Это очень простое облако точек, оно имеет только одну точку, поэтому его ограничивающий прямоугольник имеет объем 0. Однако для целого числа 42 у нас есть четыре кватерниона и четыре точки, вокруг которых мы можем нарисовать ограничивающий прямоугольник. Минимальная точка поля - (1,2,4) а максимальная - (3,4,6) resulting in a width, length, and height of 2, 2, and 2, giving a volume of 8.

Let's say that for an integer N, the qvolume is the volume of the axis-aligned bounding box of all the 3D points formed by quaternions that have a quadrance equal to N, where the components of the quaternion вес+Икся+YJ+ZК are non-negative and вес<=Икс<=Y<=Z.

Create a program or function that, given a single non-negative integer N, will output N's qvolume.

Examples:

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

This is code-golf, smallest number of bytes wins.

don bright
источник
what do i need to add? i meant to indicate that smallest number of bytes would win
don bright
3
You forgot the code-golf tag, I helped you add it
Embodiment of Ignorance
1
This is a nice challenge but it would be even better IMHO if it was a bit less verbose. Also, beware of irrelevant links (I'm not saying that all your links are irrelevant, but only a few of them really bring meaningful information for the challenge, while the other ones are just distracting).
Arnauld
1
Yes, but why take only i, j, k as 3D space but not 4D space?
tsh
1
@tsh because Quaternions don't necessarily represent a 4 dimensional Euclidean space. Hamilton discovered them while searching for a way to work with 3 dimensional space. It would be possible to do a 4d version but i was pondering their use in 3d space when i made the question
don bright

Ответы:

13

Wolfram Language (Mathematica), 67 58 bytes

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

Try it online!

                         ...&   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.
lirtosiast
источник
4
wow, i had no idea that something like PowersRepresentations would be a built in in a language. i actually thought about making a challenge to show the different ways to sum an integer as four squares but im glad i did not.
don bright
4
Lol, Mathematica even has a builtin for determining goats in an image, so having a builtin for this really doesn't surprise me. xD
Kevin Cruijssen
8

Jelly, 17 bytes

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

Try it online! (pretty slow - make it fast enough for all the test cases with a leading ½)

How?

Żœċ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
Jonathan Allan
источник
6

Haskell, 132 123 bytes

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

Try it online!

Pretty straightforward solution. Brute force all the possible solutions by iterating over all the values from 0 to n (way overkill but shorter bytecount). I output the point as a list so we can use @Lynn's magic (!) operator. That operator collapses each dimension with the function on the left side so max!p returns a list of size 3 which consists of the maximums along each dimension and min!p does the same for minimum. Then we just find the minimum size in each dimension (by subtracting the min value from the max with z(-)) and multiply them together.

Thanks a lot to @Lynn for taking off 9 bytes with some folding zip magic!

user1472751
источник
1
Я сбрил несколько байтов, отказавшись от транспонирования в пользу некоторой zipWithлогики. 123 байта
Линн
5

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

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

Используйте с Mathematica 11.2 и этой версией Sledgehammer, которая предшествует вызову. Смотрите историю изменений для версии, которая работает в версии 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 Language :

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

Попробуйте онлайн!

lirtosiast
источник
does this require mathematica to test it?
don bright
@don bright Yes, the repository has instructions. It's a work in progress so not very user-friendly yet. After running setup.wls you can test either with wolframscript or interactive_app.wls.
lirtosiast
2
@Downgoat Yes. I plan to implement a golfing library, but currently it decompresses to plain Mathematica.
lirtosiast
2
@pipe Старая версия должна работать (теперь, когда я думаю об этом, код точно такой же на одной старой версии), но мне придется загрузить ее и снова запустить установку. (С тех пор изменения в основном заключались в написании графического интерфейса и рефакторинге кода без каких-либо серьезных изменений в функциональности.) Поскольку этот ответ является самым коротким, представляется важным доказать соответствие требованиям, поэтому я сделаю это завтра утром.
Lirtosiast
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

Попробуйте онлайн!

Рекурсивно генерирует обратно отсортированные кватернионы с заданной нормой, а затем принимает произведение между максимальным и минимальным значениями всех возможных значений в первых трех индексах.

itertools возможно, был бы выстрел, если бы он не использовал смехотворно длинные имена, такие как itertools.combinations_with_replacement

Python 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никогда не ответ .

XNOR
источник
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 = [ [], [], [] ]

Для каждого действительного значения Иксмы установим 1 значение в Икс+1в первом массиве. То же самое дляY а также Z со вторым и третьим массивами соответственно.

Размеры ограничительной рамки будут выведены из расстояния между первой и последней записью, установленной на 1 в этих массивах.

Шаг 1

Заполнить рмы используем рекурсивную функцию г,

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

Теперь мы можем вычислить продукт п размеров.

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
Arnauld
источник
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разница между минимальным и максимальным iзначениями координат, которые извлекаются при индексировании !!i.

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

XNOR
источник