Pierwiastek kwadratowy z czwartorzędu

11

tło

Czwartorzęd jest systemem liczbowym, który rozszerza liczby zespolone. Czwartorzęd ma następującą postać

za+bja+dojot+rek

gdzie są liczbami rzeczywistymi, a są trzema podstawowymi jednostkami czwartorzędowymi . Jednostki mają następujące właściwości:za,b,do,reja,jot,k

ja2)=jot2)=k2)=-1
jajot=k,jotk=ja,kja=jot
jotja=-k,kjot=-ja,jak=-jot

Zauważ, że mnożenie czwartorzędu nie jest przemienne .

Zadanie

Biorąc pod uwagę nierealny czwartorzęd, oblicz co najmniej jeden z pierwiastków kwadratowych.

W jaki sposób?

Zgodnie z odpowiedzią Math.SE możemy wyrazić dowolny nierealny czwartorzęd w następującej formie:

q=za+bu

gdzie są liczbami rzeczywistymi, a jest urojonym wektorem jednostkowym w postaci z . Każdy taki ma właściwość , więc można go postrzegać jako jednostkę urojoną.za,buxi+yj+zkx2+y2+z2=1uu2=1

Następnie kwadrat wygląda następująco:q

q2=(a2b2)+2abu

Odwrotnie, biorąc pod uwagę ćwiartkę , możemy znaleźć pierwiastek kwadratowy z rozwiązując następujące równaniaq=x+yuq

x=a2b2,y=2ab

który jest identyczny z procesem znajdowania pierwiastka kwadratowego liczby zespolonej.

Zauważ, że ujemna liczba rzeczywista ma nieskończenie wiele pierwiastków czwartorzędowych, ale nierealna czwórka ma tylko dwa pierwiastki kwadratowe .

Wejście i wyjście

Wejście jest nierealnym czwartorzędem. Można go traktować jako cztery liczby rzeczywiste (zmiennoprzecinkowe), w dowolnej kolejności i dowolnej strukturze. Nierealne oznacza, że ​​co najmniej jedno z jest niezerowe.b,c,d

Wyjście to jeden lub dwa ćwiartki, które w kwadracie są równe wejściowi.

Przypadki testowe

   Input (a, b, c, d)  =>  Output (a, b, c, d) rounded to 6 digits

 0.0,  1.0,  0.0,  0.0 =>  0.707107,  0.707107,  0.000000,  0.000000
 1.0,  1.0,  0.0,  0.0 =>  1.098684,  0.455090,  0.000000,  0.000000
 1.0, -1.0,  1.0,  0.0 =>  1.168771, -0.427800,  0.427800,  0.000000
 2.0,  0.0, -2.0, -1.0 =>  1.581139,  0.000000, -0.632456, -0.316228
 1.0,  1.0,  1.0,  1.0 =>  1.224745,  0.408248,  0.408248,  0.408248
 0.1,  0.2,  0.3,  0.4 =>  0.569088,  0.175720,  0.263580,  0.351439
99.0,  0.0,  0.0,  0.1 =>  9.949876,  0.000000,  0.000000,  0.005025

Wygenerowano przy użyciu tego skryptu Python . Dla każdego przypadku testowego podana jest tylko jedna z dwóch poprawnych odpowiedzi; druga to wszystkie cztery wartości zanegowane.

Kryterium punktacji i wygranej

Obowiązują standardowe zasady . Najkrótszy program lub funkcja w bajtach w każdym języku wygrywa.

Bubbler
źródło
Czy możemy wziąć czwartorzęd jako a, (b, c, d)?
nwellnhof
@nwellnhof Sure. Nawet coś podobnego a,[b,[c,[d]]]jest w porządku, jeśli można w ten sposób zaoszczędzić bajty :)
Bubbler

Odpowiedzi:

29

APL (NARS) , 2 bajty

NARS ma wbudowane wsparcie dla czwartorzędów. ¯ \ _ (⍨) _ / ¯

Adám
źródło
4
Nic na to nie poradzę: powinieneś wpisać „¯_ (ツ) _ / ¯” w swojej odpowiedzi
Barranka
7
Upuściłeś to \
Andrew
@Barranka Gotowe.
Adám
@Andrew obwinia to za aplikację na Androida ... Dziękujemy za
wzięcie
2
Byłoby lepiej, gdyby tak było¯\_(⍨)√¯
Zacharý
8

Python 2 , 72 bajty

def f(a,b,c,d):s=((a+(a*a+b*b+c*c+d*d)**.5)*2)**.5;print s/2,b/s,c/s,d/s

Wypróbuj online!

Mniej więcej surowa formuła. Pomyślałem, że mógłbym użyć pętli ze zrozumieniem listy b,c,d, ale wydaje się, że jest ona dłuższa. Pythonowi naprawdę przeszkadza brak operacji wektorowych, w szczególności skalowanie i norma.

Python 3 , 77 bajtów

def f(a,*l):r=a+sum(x*x for x in[a,*l])**.5;return[x/(r*2)**.5for x in[r,*l]]

Wypróbuj online!

Bezpośrednie rozwiązanie kwadratu było również krótsze niż użycie pierwiastka kwadratowego w Pythonie do rozwiązania go, tak jak w opisie problemu.

xnor
źródło
„Dane wejściowe są nierealnym czwartorzędem. Możesz przyjąć je jako cztery liczby rzeczywiste (zmiennoprzecinkowe), w dowolnej kolejności i strukturze według własnego wyboru”. Możesz więc uznać to za serię pand lub tablicę numpy. Serie mają skalowanie z prostym mnożeniem i istnieją różne sposoby uzyskania norm, takie jak (s*s).sum()**.5.
Accumumulation
6

Wolfram Language (Mathematica) , 19 bajtów

Sqrt
<<Quaternions`

Wypróbuj online!

Mathematica ma również wbudowane Quaternion, ale jest bardziej gadatliwa.


Chociaż wbudowane wyglądają fajnie, rób upvote rozwiązania, które również nie używają wbudowanych! Nie chcę, aby głosy na pytania do HNQ były wypaczone.

użytkownik202729
źródło
4

JavaScript (ES7), 55 53 bajtów

Oparty na bezpośredniej formule stosowanej przez xnor .

Pobiera dane wejściowe jako tablicę.

q=>q.map(v=>1/q?v/2/q:q=((v+Math.hypot(...q))/2)**.5)

Wypróbuj online!

W jaki sposób?

q=[a,b,c,d]

x=za+za2)+b2)+do2)+re2)2)

I zwraca:

[x,b2)x,do2)x,re2)x]

q =>                            // q[] = input array
  q.map(v =>                    // for each value v in q[]:
    1 / q ?                     //   if q is numeric (2nd to 4th iteration):
      v / 2 / q                 //     yield v / 2q
    :                           //   else (1st iteration, with v = a):
      q = (                     //     compute x (as defined above) and store it in q
        (v + Math.hypot(...q))  //     we use Math.hypot(...q) to compute:
        / 2                     //       (q[0]**2 + q[1]**2 + q[2]**2 + q[3]**2) ** 0.5
      ) ** .5                   //     yield x
  )                             // end of map()
Arnauld
źródło
3

Haskell , 51 bajtów

f(a:l)|r<-a+sqrt(sum$(^2)<$>a:l)=(/sqrt(r*2))<$>r:l

Wypróbuj online!

Formuła bezpośrednia. Główna sztuczka polegająca na wyrażeniu rzeczywistej części wyniku jako r/sqrt(r*2)równoległej do wyimaginowanej wyrażenia części, która pozwala zaoszczędzić kilka bajtów:

54 bajty

f(a:l)|s<-sqrt$2*(a+sqrt(sum$(^2)<$>a:l))=s/2:map(/s)l

Wypróbuj online!

xnor
źródło
3

Węgiel drzewny , 32 bajty

≔X⊗⁺§θ⁰XΣEθ×ιι·⁵¦·⁵η≧∕ηθ§≔θ⁰⊘ηIθ

Wypróbuj online! Link jest do pełnej wersji kodu. Port odpowiedzi na Python @ xnor. Wyjaśnienie:

≔X⊗⁺§θ⁰XΣEθ×ιι·⁵¦·⁵η

|x+yu|=x2)+y2)=(za2)-b2))2)+(2)zab)2)=za2)+b2)x2)za2)2)za

≧∕ηθ

y=2)zabb2)za

§≔θ⁰⊘η

2)za

Iθ

Rzuć wartości na ciąg i niejawnie wydrukuj.

Neil
źródło
3

Java 8, 84 bajtów

(a,b,c,d)->(a=Math.sqrt(2*(a+Math.sqrt(a*a+b*b+c*c+d*d))))/2+" "+b/a+" "+c/a+" "+d/a

Port odpowiedzi @xnor na Python 2 .

Wypróbuj online.

Wyjaśnienie:

(a,b,c,d)->           // Method with four double parameters and String return-type
  (a=                 //  Change `a` to:
     Math.sqrt(       //   The square root of:
       2*             //    Two times:
         (a+          //     `a` plus,
          Math.sqrt(  //     the square-root of:
            a*a       //      `a`  squared,
            +b*b      //      `b` squared,
            +c*c      //      `c` squared,
            +d*d))))  //      And `d` squared summed together
  /2                  //  Then return this modified `a` divided by 2
  +" "+b/a            //  `b` divided by the modified `a`
  +" "+c/a            //  `c` divided by the modified `a`
  +" "+d/a            //  And `d` divided by the modified `a`, with space delimiters
Kevin Cruijssen
źródło
2

05AB1E , 14 bajtów

nOtsн+·t©/¦®;š

Port odpowiedzi @xnor na Python 2 .

Wypróbuj online lub sprawdź wszystkie przypadki testowe .

Wyjaśnienie:

n                 # Square each number in the (implicit) input-list
 O                # Sum them
  t               # Take the square-root of that
   sн+            # Add the first item of the input-list
      ·           # Double it
       t          # Take the square-root of it
        ©         # Store it in the register (without popping)
         /        # Divide each value in the (implicit) input with it
          ¦       # Remove the first item
           ®;     # Push the value from the register again, and halve it
             š    # Prepend it to the list (and output implicitly)
Kevin Cruijssen
źródło
2

C # .NET, 88 bajtów

(a,b,c,d)=>((a=System.Math.Sqrt(2*(a+System.Math.Sqrt(a*a+b*b+c*c+d*d))))/2,b/a,c/a,d/a)

Port mojej odpowiedzi w Javie 8 , ale zwraca Tuple zamiast String. Myślałem, że byłoby to krótsze, ale niestety Math.Sqrtwymaga System-importu w C # .NET, kończąc na 4 bajtach dłuższych zamiast 10 bajtach krótszych ..>.>

Deklaracja lambda wygląda jednak dość zabawnie:

System.Func<double, double, double, double, (double, double, double, double)> f =

Wypróbuj online.

Kevin Cruijssen
źródło
1

Perl 6 , 49 bajtów

{;(*+@^b>>².sum**.5*i).sqrt.&{.re,(@b X/2*.re)}}

Wypróbuj online!

Funkcja Curried przyjmuje dane wejściowe jako f(b,c,d)(a). Zwraca kwaternion jako a,(b,c,d).

Wyjaśnienie

{;                                             }  # Block returning WhateverCode
     @^b>>².sum**.5     # Compute B of quaternion written as q = a + B*u
                        # (length of vector (b,c,d))
  (*+              *i)  # Complex number a + B*i
                      .sqrt  # Square root of complex number
                           .&{                }  # Return
                              .re,  # Real part of square root
                                  (@b X/2*.re)  # b,c,d divided by 2* real part
nwellnhof
źródło