Zachowaj / upuść / zwiększ sekwencję

20

Oto sekwencja, o której mówię:

{1, 4, 5, 9, 10, 11, 16, 17, 18, 19, 25, 26, 27...}

Począwszy od 1, zachowaj 1, upuść kolejne 2, zachowaj następne 2, upuść 3, zachowaj 3 i tak dalej. Tak, dotyczy to również OEIS (A064801) !

Wyzwanie

Biorąc pod uwagę liczbę całkowitą n>0, znajdź n-ty składnik powyższej sekwencji

Przypadki testowe

Input -> Output       
1->1  
22->49  
333->683
4444->8908
12345->24747

To jest golf golfowy, więc wygrywa najkrótsza odpowiedź w bajtach! Powodzenia!

Taylor Scott
źródło
3
Czy możemy wybrać indeksowanie od 0 do 1?
Pan Xcoder,
1
@ Mr.Xcoder Obawiam się, że nie. Jest to tylko 1 indeksowany
Czy możemy zwrócić listę zawierającą wszystkie elementy w kolejności?
Wheat Wizard
@WheatWizard jest to całkowicie niedopuszczalne. przepraszam

Odpowiedzi:

12

Java (OpenJDK 8) , 45 44 bajtów

n->{int i=0;for(;++i<n;n-=i);return~-n+i*i;}

Wypróbuj online!

-1 bajt dzięki @Nevay

Po chwili wpatrywania się w to zauważyłem pewien wzór. Za każdym razem, gdy upuszczamy nliczby, następną liczbą w sekwencji jest idealny kwadrat. Widząc to, mentalnie podzieliłem sekwencję na wygodne fragmenty: [[1],[4,5],[9,10,11],...]Zasadniczo, ifragment th zaczyna się od i*ii iteruje w górę dla ielementów.

Aby znaleźć nliczbę th w tej sekwencji, chcemy najpierw ustalić, w której części znajduje się liczba, a następnie jaką pozycję zajmuje w tej części. Odejmujemy nasz numer przyrost iod nmomentu njest mniejszy niż i(co daje nam nasz kawałek), a następnie po prostu dodać n-1do i*iuzyskać poprawne positionw kawałku.

Przykład:

n = 8
n > 1? Yes, n = n - 1 = 7
n > 2? Yes, n = n - 2 = 5
n > 3? Yes, n = n - 3 = 2
n > 4? No, result is 4 * 4 + 2 - 1 = 17
Xanderhall
źródło
1
Możesz użyć, return~-n+i*i;aby zapisać 1 bajt.
Nevay
7

Haskell, 48 43 41 bajtów

n#l=[l..l+n]++(n+1)#(l+2*n+3)
((0:0#1)!!)

4 dodatkowe bajty dla indeksowania 1 zamiast 0. Niepotrzebne ograniczenie, IMHO.

Wypróbuj online!

n#l             -- n is one less than the number of element to keep/drop and
                -- l the next number where the keep starts
   [l..l+n]     -- keep (n+1) numbers starting at l
   ++           -- and append a recursive call
   (n+1)#       -- where n is incremented by 1 and
      (l+2*n+3) -- l skips the elements to keep & drop

0#1             -- start with n=1 and l=0 and
 0:             -- prepend a dummy value to shift from 0 to 1-based index
    !!          -- pick the i-th element from the list 
nimi
źródło
6

Python 3 , 47 46 bajtów

1 bajt dzięki Mr. Xcoder.

def f(n):a=round((2*n)**.5);return~-n+a*-~a//2

Wypróbuj online!

BARDZO szybko dla wyższych liczb

Leaky Nun
źródło
46 bajtów: def f(n):a=round((2*n)**.5);return~-n+a*-~a//2. Nie jestem jednak pewien ... Sprytne podejście!
Pan Xcoder,
Aw, podwójne lambdy to jeden dodatkowy bajt, miałem nadzieję, że uratuje bajt ...
Stephen
Dlaczego ktoś głosował za tym? Czy jest jakiś problem z podejściem, którego nie zauważyliśmy?
Pan Xcoder,
@ Mr.Xcoder może z powodu korkowej uwagi.
Leaky Nun
a*(a+1)jest nawet dla każdej liczby całkowitej. Czy Python skarży się na podział zmiennoprzecinkowy na liczbach całkowitych? Czy narzeka na bitowe operacje na pływakach? Jeśli nie: (2*n)**.5+.5|0.
Tytus
3

Haskell , 33 bajty

Anonimowa funkcja. Użyj jako((!!)$0:do n<-[1..];[n^2..n^2+n-1]) 1

(!!)$0:do n<-[1..];[n^2..n^2+n-1]

Wypróbuj online!

  • Konstruuje sekwencję jako nieskończoną listę, a następnie indeksuje do niej za pomocą !!. The0: to element fikcyjny umożliwiający dostosowanie indeksowania od 0 do 1.
  • Zakres [n^2..n^2+n-1]tworzy podciąg bez przerw, zaczynając od kwadratu ni zawierającegon liczby.
  • doNotacja Łączy zbudowane dla wszystkich zakresów n>=1.
Ørjan Johansen
źródło
2

Python 3 , 46 bajtów

f=lambda x,y=0,z=0:y<x and f(x,y+z,z+1)or~-y+x

Wypróbuj online!

Pan Xcoder
źródło
Ten sam algorytm ...
Leaky Nun
2

Perl 6 , 43 bajtów

{(1..*).rotor({++$=>++$+1}...*).flat[$_-1]}

Sprawdź to

Rozszerzony:

{  # bare block lambda with implicit parameter 「$_」

  ( 1 .. * )                  # range starting from 1

  .rotor(                     # break it into chunks

    { ++$  =>  ++$ + 1} ... * # infinite Seq of increasing pairs
    #   1  =>    1 + 1    ==>   1 => 2 ( grab 1 skip 2 )
    #   2  =>    2 + 1    ==>   2 => 3
    #   3  =>    3 + 1    ==>   3 => 4
    # ...  =>  ... + 1

  ).flat\                     # reduce the sequence of lists to a flat sequence
  [ $_ - 1 ]                  # index into the sequence
                              # (adjusting to 0-based index)
}

(1..*).rotor({++$=>++$+1}...*) produkuje:

(
 (1,),
 (4, 5),
 (9, 10, 11),
 (16, 17, 18, 19),
 (25, 26, 27, 28, 29),
 ...
).Seq
Brad Gilbert b2gills
źródło
2

TeX, 166 bajtów

\newcommand{\f}[1]{\count0=0\count1=0\loop\advance\count0 by\the\count1\advance\count1 by1\ifnum\count0<#1\repeat\advance\count0 by#1\advance\count0 by-1
\the\count0}

Stosowanie

\documentclass[12pt,a4paper]{article}
\begin{document}
\newcommand{\f}[1]{\count0=0\count1=0\loop\advance\count0 by\the\count1\advance\count1 by1\ifnum\count0<#1\repeat\advance\count0 by#1\advance\count0 by-1
\the\count0}

\f{1}

\f{22}

\f{333}

\f{4444}

\f{12345}
\end{document}

enter image description here

Leaky Nun
źródło
2

JavaScript, 43 38 bajtów

n=>eval("for(r=1;n>r;)n-=r++;r*r+n-1")

Wypróbuj online!

Korzystam z faktu, że dla każdej liczby trójkątnej plus jeden wynik jest liczbą kwadratową.

Na przykład: liczby trójkątne to 0, 1, 3, 6, 10 ... więc dla 1, 2, 4, 7, 11 ... obserwujemy 1, 4, 9, 16, 25 ... w naszej sekwencji .

Jeśli indeks znajduje się gdzieś pomiędzy tymi znanymi liczbami, elementy naszej sekwencji przesuwają się tylko o jeden. Na przykład, aby obliczyć wynik dla 10, bierzemy 7 (jako liczbę trójkątną plus jeden), bierzemy wynik (16) i dodajemy 10-7 = 3. Zatem 16 + 3 = 19.

mackoo13
źródło
1

05AB1E , 12 bajtów

LεÝÁćn+}˜¹<è

Wypróbuj online!

Erik the Outgolfer
źródło
Bardzo fajne podejście!
Emigna
@Emigna Cóż, po prostu robię [0..a-1] + a**2, fajną rzeczą tutaj imo jest po prostu ÝÁćn+zamiast D<Ýsn+.
Erik the Outgolfer
1

C # (mono) , 164 bajty

using System.Linq;n=>{var a=new int[1]{1}.ToList();for(int i=1,m;a.Count<n;a.AddRange(new int[++i*2].Select((_,d)=>m+d+1).Skip(i).Take(i)))m=a.Max();return a[n-1];}

Wypróbuj online!

TheLethalCoder
źródło
1

Mathematica, 37 bajtów

Flatten[Range@#+#^2-1&~Array~#][[#]]&

Wyjaśnienie

Range@#+#^2-1&

Functionktóra przyjmuje dodatnią liczbę całkowitą #i zwraca #ciąg kolejnych liczb w sekwencji.

...~Array~#

Tworzy listę wszystkich takich przebiegów aż do wejścia #

Flatten[...][[#]]

Flattenswynikowa lista i zwraca #element th.

ngenisis
źródło
1

Tampio , 310 308 bajtów

n:n uni on n unena 1:lle
a unena k:lle on a vuona k:lla vähennettynä a:sta ja k
a vuona nollalla ja k on a
a vuona k:lla vähennettynä nollasta ja k on a
a vuona b:n seuraajalla ja k on yhteenlaskun kutsuttuna k:n kerrottuna 2:lla arvolla ja k:n vähennettynä a:sta arvolla unena k:n seuraajalle seuraaja

Zastosowanie: 4:n uniocenia na 9.

Wyjaśnienie:

n:n uni on n unena 1:lle
uni(n)  =  n `uni` 1

a unena k:lle on  a vuona  k:lla vähennettynä a:sta ja k
a `uni` k     =  (a `vuo` (k     `vähennetty` a)    )  k

 a vuona nollalla ja k on a
(a `vuo` 0        )  k =  a

 a vuona  k:lla vähennettynä nollasta ja k on a
(a `vuo` (k     `vähennetty` 0)       )  k =  a

 a vuona  b:n seuraajalla ja k on
(a `vuo` (b   + 1)        )  k =

 yhteenlaskun kutsuttuna k:n kerrottuna 2:lla arvolla
(yhteenlasku            (k   *          2     )

 ja k:n vähennettynä a:sta arvolla unena  k:n seuraajalle seuraaja
((  k   `vähennetty` a     )       `uni` (k   + 1)   )  ) + 1

Ze standardowej biblioteki:

a `vähennetty` b = b - a
yhteenlasku a b  = a + b
fergusq
źródło
1

JavaScript (ES6), 33 bajty

Rozwiązanie rekurencyjne inspirowane obserwacjami Xanderhall .

f=(n,x=1)=>n<x?n+x*x-1:f(n-x,++x)

Spróbuj

o.innerText=(
f=(n,x=1)=>n<x?n+x*x-1:f(n-x,++x)
)(i.value=12345);oninput=_=>o.innerText=f(+i.value)
<input id=i type=number><pre id=o>

Kudłaty
źródło
0

Python 3 , 50 bajtów

def f(n):
 a=i=0
 while a<n:a+=i;i+=1
 return~-a+n

Wypróbuj online!

Leaky Nun
źródło
To naprawdę skorzystałoby z portu pełnego programu do Pythona 2 ( 46 bajtów - powiązałoby podejście rekurencyjne)
Pan Xcoder
0

Mathematica, 82 bajty

Complement[Range[3#],Array[#+⌊((r=Sqrt[1+8#])-1)/2⌋⌊(r+1)/2⌋/2&,3#]][[#]]&
J42161217
źródło
0

JavaScript (ES6) 100 98 bajtów

var k=n=>{var s=[],i=1,c=1,j;while(s.length<n){for(j=i;j<i+c;j++){s.push(j)}i+=c*2+1;c++}return s}

Niby zrobiłem to szybko, więc założę się, że jest dużo miejsca na ulepszenia, tylko podstawowe pętle i liczniki.

Śpiący
źródło
0

Siatkówka , 27 bajtów

.+
$*
((^1|1\2)+)1
$1$2$&
1

Wypróbuj online! Port odpowiedzi Python @ LeakyNun. Pierwszy i ostatni etap to tylko nudna konwersja dziesiętna. Drugi etap działa w następujący sposób:((^1|1\2)+) jest dopasowaniem liczb trójkątnych; $1jest dopasowaną liczbą trójkątną, a $2jej indeksem. Trailing 1oznacza, że ​​pasuje do największej liczby trójkątnej dokładnie mniejszej niż wartość wejściowa, co powoduje dokładnie jedną mniejszą iterację niż pętla Pythona, co oznacza, że $1jest ona równoważna a-ii $2do, i-1a ich suma jest równa a-1lub równa się w tym przypadku.~-a w miarę potrzeb. ( $&po prostu zapobiega usunięciu dopasowania z wyniku). Zauważ, że dla danych wejściowych 1nie występuje dopasowanie, a dane wyjściowe są po prostu takie same jak dane wejściowe. Gdybyś był przewrotny, mógłbyś użyć^((^1|1\2)*)1

Neil
źródło
0

MATL , 12 bajtów

:"@U@:q+]vG)

Wypróbuj online!

Wyjaśnienie

:        % Push range [1 2 ... n], where n is implicit input
"        % For each k in that range
  @U     %   Push k^2
  @:     %   Push range [1 2 ... k]
  q      %   Subtract 1: gives [0 1 ... k-1]
  +      %   Add: gives [k^2 k^2+1 ... k^2+k-1]
]        % End
v        % Concatenate all numbers into a column vector
G)       % Get n-th entry. Implicitly display
Luis Mendo
źródło
0

PHP, 48 42 37 + 1 bajtów

przeniesione z odpowiedzi Leaky Nun

while($argn>$a+=$i++);echo$a+~-$argn;

Uruchom jako potok z -Flub spróbuj online .

bezpośrednie podejście, 42 + 1 bajtów (przeniesione z innej odpowiedzi Leaky Nun )

<?=($a=(2*$argn)**.5+.5|0)*-~$a/2+~-$argn;

Uruchom jako rura z -nRlub odkomentuj powyżej TiO.

starsze iteracyjne rozwiązanie, 48 + 1 bajtów

for(;$argn--;$n++)$c++>$z&&$n+=++$z+$c=1;echo$n;
Tytus
źródło