Znajdź n-tą alternatywną sumę

17

Biorąc pod uwagę jedną dodatnią liczbę całkowitą, wyślij „sumę alternatywną”, która odpowiada tej liczbie całkowitej.

Weź przykład z danych wejściowych n=5. Aby znaleźć sumę alternatywną, najpierw utwórz kwadratową siatkę o szerokości i wysokości, nktóra, czytając od lewej do prawej i od góry do dołu, zaczyna się 1i zwiększa o jedną pozycję:

 1  2  3  4  5
 6  7  8  9 10
11 12 13 14 15
16 17 18 19 20
21 22 23 24 25

Następnie weź sumy z siatki, która tworzy „krzyż” (to znaczy oba przekątne połączone):

 1           5
    7     9
      13
   17    19
21          25

1 5 7 9 13 17 19 21 25

Na koniec weź na przemian sumę tej sekwencji:

1+5-7+9-13+17-19+21-25

-11

Kolejny przykład dla n=6(aby pokazać, jak wygląda krzyż dla parzystych n):

 1  2  3  4  5  6
 7  8  9 10 11 12
13 14 15 16 17 18
19 20 21 22 23 24
25 26 27 28 29 30
31 32 33 34 35 36

 1              6
    8       11
      15 16
      21 22
   26       29
31             36

1+6-8+11-15+16-21+22-26+29-31+36

20

Ponieważ jest to , wygra najkrótszy kod w bajtach.

Oto poprawne wyjścia do n=1celu n=100, który można wykorzystać jako przypadków testowych:

1
4
-3
10
-11
20
-23
34
-39
52
-59
74
-83
100
-111
130
-143
164
-179
202
-219
244
-263
290
-311
340
-363
394
-419
452
-479
514
-543
580
-611
650
-683
724
-759
802
-839
884
-923
970
-1011
1060
-1103
1154
-1199
1252
-1299
1354
-1403
1460
-1511
1570
-1623
1684
-1739
1802
-1859
1924
-1983
2050
-2111
2180
-2243
2314
-2379
2452
-2519
2594
-2663
2740
-2811
2890
-2963
3044
-3119
3202
-3279
3364
-3443
3530
-3611
3700
-3783
3874
-3959
4052
-4139
4234
-4323
4420
-4511
4610
-4703
4804
-4899
5002
Klamka
źródło
8
Nit pick: To nie jest naprzemienna suma. Dodajesz pierwsze dwa warunki.
Dennis

Odpowiedzi:

26

Galaretka, 21 19 11 10 7 bajtów

²~³¡H+2

Wypróbuj online!

Pomysł

Załóżmy przez sekundę, że pierwszy składnik końcowej sumy jest odejmowany, a nie dodawany.

Niech n będzie dodatnią liczbą całkowitą.

Nawet skrzynka

 1              6
    8       11
      15 16
      21 22
   26       29
31             36

Różnice między elementami ukośnymi w dolnej połowie rzędów są pierwszymi nieparzystymi liczbami naturalnymi n ÷ 2 . Ponieważ 1 + 3 + 5 +… + (2k + 1) = k 2 , sumują się do (n ÷ 2) 2 = n 2 ÷ 4 .

W tym przykładzie

- 1 + 6 - 8 + 11 - 15 + 16 - 21 + 22 - 26 + 29 - 31 + 36  =
-(1 - 6)-(8 - 11)-(15 - 16)-(21 - 22)-(26 - 29)-(31 - 36) =
(    5   +   3    +    1  )+(   1    +    3    +    5   ) =
             9             +              9               = 18

Zatem suma wynosi 2 × n 2 ÷ 4 = n 2 ÷ 2 .

Dziwna sprawa

 1           5
    7     9
      13
   17    19
21          25

Różnice między elementami ukośnymi w odpowiednich rzędach od góry i od dołu ( 1i 5, i 21i 25oraz 7i 9i 17i 19) są takie same, więc zostaną skasowane na przemian.

W tym przykładzie

- 1 + 5 - 7 + 9 - 13 + 17 - 19 + 21 - 25  =
-(1 - 5)-(7 - 9)- 13 +(17 - 19)+(21 - 25) =
    4   +   2   - 13 -    2    -    4     = -13

Pozostaje tylko minus elementu centralnego, który jest średnią arytmetyczną pierwszej i ostatniej liczby, więc można go obliczyć jako - (n 2 + 1) ÷ 2 .

Ogólna sprawa

Ponieważ ~ x = - (x + 1) dla liczb całkowitych dopełniacza dwóch ( ~ oznacza bitowe NIE), wzór na przypadek nieparzysty można przepisać jako ~ n 2 ÷ 2 .

Ponadto, ponieważ pierwszy składnik ( 1 ) oryginalnej sumy jest dodawany zamiast odejmowany, powyższe formuły pozostawiają błąd 2 , który należy poprawić.

W związku z tym, n p przekrój alternatywnego sumie jest N 2 ÷ 2 + 2 , gdy n jest parzyste, i -n 2 ÷ 2 + 2 , jeśli jest nieparzysta.

Wreszcie bitowe NIE jest inwolucją, tj. ~~ x = x dla wszystkich x . W ten sposób ~~~ x = ~ x , ~~~~ x = x i, ogólnie rzecz biorąc, ~ n x (co oznacza, że ~ stosuje się n razy) to x, jeśli n jest parzyste, a ~ x, jeśli jest nieparzyste.

Zatem możemy przepisać naszą ogólną formułę jako ~ n n 2 ÷ 2 + 2 dla wszystkich liczb całkowitych dodatnich n .

Kod

²~³¡H+2    Main link. Input: n

²          Yield n².
 ~         Apply bitwise NOT to n²...
  ³¡           n times.
    H      Halve the result.
     +2    Add 2.
Dennis
źródło
1
Wiedziałem, że istnieje jakaś prosta formuła, ale twoje wyjaśnienie i wykonanie jest po prostu niesamowite. +1
ETHprodukcje
5

JavaScript, 40 38 22 bajtów

Korzystając z tego nowatorskiego, fantazyjnego rozwiązania w formie zamkniętej, które jest wściekłe!

n=>(n%2?3-n*n:4+n*n)/2

Dzięki ThomasKwa mogę wyeliminować moją kosztowną funkcję rekurencyjną.

Conor O'Brien
źródło
Musisz tylko bitowo NIE raz, jeśli n% 2. Właściwie myślę, że w JS może to być krótsze(n%2?3-n*n:4+n*n)/2
lirtosiast
4

Galaretka, 12 bajtów

RṖµ²+‘×-*$SC

Wypróbuj tutaj .

lirtosiast
źródło
4

CJam, 13 15 bajtów

ri2#_{~}*2/2+

Dwa bajty wyłączone dzięki Dennisowi.

Wypróbuj online!

Luis Mendo
źródło
3
Moja pierwsza odpowiedź na CJam!
Luis Mendo,
1
Wymiana 2%{~}&z {~}*oszczędza dwa bajty.
Dennis,
@Dennis Bardzo dobrze! Dzięki!
Luis Mendo,
3

Minkolang 0,15 , 26 15 13 bajtów

Wykorzystując szalony algorytm Dennisa i dzięki niemu odjechał kolejne dwa bajty. Ten facet jest odpowiedzialny za zmniejszenie o połowę liczby bajtów!

n2;d[~]4+2:N.

Wypróbuj tutaj!

Wyjaśnienie

@VoteToClose n^ 2, stosuj bitowo NIE nrazy, dodaj cztery, zmniejsz o połowę. - Thomas Kwa 7 minut temu

Zobacz odpowiedź Dennisa, aby wyjaśnić, dlaczego to działa. W komentarzu do tej odpowiedzi zasugerował kolejne ulepszenie, które działa, ponieważ :jest dzielenie liczb całkowitych, więc mogę negować szczyt stosu i nie martwić się o +1 z uzupełnieniem binarnym. Ponadto n i n ^ 2 mają tę samą parzystość, co eliminuje potrzebę wymiany.

n                Take number from input - n
 2;              n**2
   d             Duplicates top of stack
    [~]          For loop that negates the top of stack n times
       4+        Add 4
         2:      Divide by 2
           N.    Output as number and stop.
El'endia Starman
źródło
2

GolfScript, 12 bajtów

~2?.{~}*2/2+

Wykorzystuje algorytm z mojej odpowiedzi Jelly . Wypróbuj online!

Jak to działa

~            # Evaluate the input.
 2?          # Square it.
   .         # Push a copy of the square.
    {~}      # Push a code block that applies bitwise NOT.
       *     # Execute it n² times. Since n² and n have the same parity,
             # this is equivalent to executing in only n times.
        2/   # Halve the result.
          2+ # Add 2.
Dennis
źródło
2

ES7, 17 bajtów

n=>-1**n*n*n+4>>1

Prosty port odpowiedzi @ Dennis na Python 2.

Pisząc tę ​​odpowiedź, udało mi się też golfować mój port ES6 do 17 bajtów!

n=>(n*n^-n%2)/2+2
Neil
źródło
2

MATL , 13 27 bajtów

Używając niesamowitych formuł Dennisa:

2^t2\?Q_]2/2+

Wypróbuj online!

Bezpośrednie podejście ( 27 bajtów ):

2^:GtetXdwPXdhutn:-1w^!*s2+
Luis Mendo
źródło
2

Pure Bash, 28

Teraz, kiedy @Dennis pokazał nam, jak to zrobić, wymaga aktualizacji:

echo $[-1**$1*($1*$1+1)/2+2]

Poprzednia odpowiedź:

Narzędzia Bash + GNU, 77

Oto początek:

a=$1
(seq 1 $[a+1] $[a*a]
seq $1 $[a>1?a-1:1] $[a*a])|sort -un|paste -sd+-|bc

N jest przekazywany jako parametr wiersza polecenia.

pastejest tu bardzo przydatny do tworzenia naprzemiennej sumy. Ta -dopcja umożliwia listę znaków separatora, które są używane cyklicznie.

Cyfrowa trauma
źródło
$[-1**$1*$1*$1+4>>1]jest jeszcze krótszy.
Neil,
2

Julia, 41 40 25 19 16 bajtów

n->-n%2$n^2÷2+2

Jest to anonimowa funkcja, która przyjmuje liczbę całkowitą i zwraca liczbę całkowitą. Aby go wywołać, przypisz go do zmiennej.

Podejście tutaj, opracowane przez Dennisa, jest następujące. Najpierw otrzymujemy parzystość n , tj. N (mod 2), i negujemy ją. To daje nam 0 dla parzystych danych wejściowych i -1 dla nieparzystych. Następnie bitowo XOR z n 2 . Kiedy n jest parzyste, jest to tylko n 2, ponieważ XOR z 0 jest tylko liczbą. Gdy n jest nieparzyste, XOR z -1 jest tym samym, co negacja bitowa. Więc w tym momencie albo n 2, albo bitowe NIE z n 2 . Liczbę całkowitą dzielimy przez 2 i dodajemy 2, aby uzyskać wynik.

Zapisałem bajt dzięki Sp3000 w poprzedniej wersji i zapisałem 9 dzięki Dennisowi na tym!

Alex A.
źródło
1

Jolf, 13 bajtów

Wypróbuj tutaj!

½?mρj-3Qj+4Qj
 ?mρj         if parity of j
     -3Qj     return 3 - j*j
         +4Qj else return 4 + j*j
½             (and halve the result)
Conor O'Brien
źródło
1

Python 2, 24 bajty

lambda n:(-1)**n*n*n/2+2

Wykorzystuje algorytm z mojej odpowiedzi Jelly , z niewielką modyfikacją:

Zamiast stosowania ~ n razy, stosujemy - n razy (mnożąc przez (-1) n ). Jest to równoważne, ponieważ ~ x = -x - 1 i piętra dzielenia liczb całkowitych w Pythonie, więc ~ x / 2 = (-x - 1) / 2 = -x / 2 .

Dennis
źródło
1

Pyth, 11 bajtów

+2/u_GQ*QQ2

Wypróbuj online w kompilatorze Pyth .

Jak to działa

Wykorzystuje algorytm z mojej odpowiedzi Jelly , z niewielką modyfikacją:

Zamiast stosowania ~ n razy, stosujemy - n razy (mnożąc przez (-1) n ). Jest to równoważne, ponieważ ~ x = -x - 1 i piętra dzielenia liczb całkowitych w Pyth, więc ~ x / 2 = (-x - 1) / 2 = -x / 2 .

+2/u_GQ*QQ2  Evaluated input: Q

       *QQ   Yield Q².
   u  Q      Set G = Q². For each non-negative integer below Q:
    _G         Set G = -G.
             Return G.
  /       2  Halve the result.
+2           Add 2.
Dennis
źródło
1

dc, 17

Używając tej samej wypróbowanej i przetestowanej formuły Dennis:

?dd*1+r_1r^*2/2+p

Wypróbuj online Och, dlaczego nie zawiera piaskownicy bash Ideone dc?

Test w wierszu poleceń:

for i in {1..100}; do echo $i | dc -e '?dd*1+r_1r^*2/2+p'; done 
Cyfrowa trauma
źródło
?2^1+2~2*1-*2+poszczędza dwa bajty.
Dennis
1

GS2, 9 bajtów

V,@!α2+''

Wykorzystuje algorytm z mojej odpowiedzi Jelly . Wypróbuj online!

V,@e 7+''

jest równie krótki, ale w szczególności nie zawiera znaków spoza ASCII.

Jak to działa

V          Parse the input as an integer n.
 ,         Compute n².
  @        Push a copy of n².
   !       Bitwise NOT.
    α      Make a block of the previous instruction.
     2     Execute the block n² times. Since n² and n have the same parity,
           this is equivalent to executing in only n times.
      +    Halve the result.
       ''  Increment twice.
Dennis
źródło
1

J, 16 bajtów

[:<.2%~4+*:*_1^]

Używa tego samego algorytmu, co moja odpowiedź Jelly. Przetestować go z J.js .

Dennis
źródło
0

Lua, 33 bajty ( Wypróbuj online )

i=(...)print((-1)^i*i*i/2-.5*i%2)

Jak to działa:

i=(...)print((-1)^i*i*i/2-.5*i%2)
i=(...)                           Take input and store to i
       print(
             (-1)^i               Raise (-1) to the i-th power: -1 if odd, 1 if even
                   *i*i/2         Multiply by i squared and halved.
                         -.5*i%2  i%2 is the remainder when i is divided by 2
                                  if i is odd, then i%2 will be 1, and this expression
                                  will evaluate to -0.5
                                  but if i is even, then i%2 will be 0, which makes
                                  this expression evaluate to 0
                                )
Leaky Nun
źródło
0

Dyalog APL, 13 bajtów

⌊2+.5××⍨ׯ1*⊢

Używa tego samego algorytmu, co moja odpowiedź Jelly. Przetestuj na TryAPL .

Dennis
źródło