Policzmy...
Policz do 2 i wracaj do 1
Policz do 4 i wracaj do 1
Policz do 6 i wracaj do 1
... ok, rozumiesz ...
połącz je wszystkie, a otrzymasz następującą sekwencję
{1,2,1,2,3,4,3,2,1,2,3,4,5,6,5,4,3,2,1,2,3,4,5,6,7,8,7,6,5,4,3,2,1,2,3...}
Wyzwanie
Biorąc pod uwagę liczbę całkowitą n>0
dla 1-indeksowanego (lub n>=0
dla 0-indeksowanego), wypisz n-ty składnik tej sekwencji
Przypadki testowe
Input->Output
1->1
68->6
668->20
6667->63
10000->84
Zasady
Twój program musi być w stanie obliczyć rozwiązania do n = 10000 w niecałą minutę
To jest golf golfowy , więc wygrywa najkrótszy kod w bajtach!
Odpowiedzi:
JavaScript (ES7),
59 ... 4443 bajtyZaoszczędził 1 bajt dzięki Tytusowi
Oczekiwany wkład: 1-indeksowany.
Początkowo zainspirowany formułą dla A004738 , która jest podobną sekwencją. Ale ostatecznie przepisałem to całkowicie.
Przypadki testowe
Pokaż fragment kodu
W jaki sposób?
Sekwencja może być ułożona w trójkąt, z lewą częścią w porządku rosnącym, a prawą w kolejności malejącej.
Poniżej znajdują się pierwsze 4 wiersze zawierające pierwsze 32 wyrażenia:
Teraz wprowadzimy kilka zmiennych:
Zaczynamy od 2 elementów u góry i dodajemy 4 elementy w każdym nowym rzędzie. Dlatego liczbę elementów w rzędzie r indeksowanym przez 0 można wyrazić jako:
1-indeksowana pozycja początkowa x rzędu r jest sumą wszystkich poprzednich wyrażeń w tej serii arytmetycznej plus jeden, co prowadzi do:
Odwrotnie, biorąc pod uwagę 1-indeksowaną pozycję n w sekwencji, odpowiedni wiersz można znaleźć za pomocą:
lub jako kod JS:
Kiedy znamy r (n) , odejmujemy pozycję początkową x (r) minus jeden od n :
Porównując n o o (R) / 2 + 1 = 2r + 2 dowiedzieć się, czy znajdują się w części wstępującej lub zstępującej części:
Jeśli to wyrażenie jest prawdziwe, zwracamy n . W przeciwnym razie zwracamy 4 (r + 1) - n . Ale ponieważ r zostało już zwiększone w ostatnim stwierdzeniu, jest to uproszczone jako:
źródło
Haskell , 37 bajtów
Wypróbuj online!
Zero indeksowane. Generuje listę i indeksuje do niej. Dzięki Ørjan Johansen za oszczędność 2 bajtów!
Haskell , 38 bajtów
Wypróbuj online!
Zero indeksowane. Generuje listę i indeksuje do niej.
Haskell , 39 bajtów
Wypróbuj online!
Zero indeksowane. Metoda rekurencyjna.
źródło
Python , 46 bajtów
Wypróbuj online!
Zero indeksowane.
źródło
Łuska , 8 bajtów
1-indeksowany. Wypróbuj online!
Wyjaśnienie
źródło
Perl 6 , 29 bajtów
Wypróbuj online
W oparciu o 0
Rozszerzony:
Wewnętrzna sekwencja
1...$+=2...2
tworzyAby był oparty na 1, dodaj
0,
przed drugim{
lub dodaj-1
po$_
źródło
R, 64 bajty
Funkcja, która przyjmuje argument
n
. Tworzy wektor2:n
z przyrostem 2. Dla każdego z nich, wektor1:(x-1)
ix:2
jest tworzony. To w sumie będzie dłuższe niżn
. Myunlist
, aby uzyskać wektor i wziąćn
-ty wpis.źródło
1:n*2
zamiastseq(2,n,2)
? Będzie większy niż potrzebujesz, ale to powinno być w porządku! Również nie sądzę, to pracowałseq(2,n,2)
nan=1
tak!Python 2 , 56 bajtów
Wypróbuj online!
To jest indeksowane na 0.
-1 bajt dzięki @JustinMariner
Jak to działa
Zauważmy, że 1-indeksowana
n
-ta grupa (1, 2, ... 2n ..., 2, 1
) występuje z elementów o numerze 0-indeksowanych2(n-1)^2
do2n^2
.Aby znaleźć element w indeksie
x
, możemy znaleźć numer grupy,n
któryx
jest w nim. Na podstawie tego obliczamy odległość od środka grupy, którax
jest. (Ta odległość wynosiabs(2*n**2+2*n+2-x)
).Ponieważ jednak elementy zmniejszają się dalej od środka grupy, odejmujemy odległość od maksymalnej wartości grupy.
źródło
print 2*n-abs(2*n*n+2*n+1-x)+2
-2*n*n+2*n
można2*n*-~n
i+2+2*n
można ją zmienić-~n*2
, co pozwala nam przenieść ją na początek, co oszczędza bajty ( 53 bajty )05AB1E , 8 bajtów
Kod:
Wykorzystuje kodowanie 05AB1E . Wypróbuj online!
Wyjaśnienie:
źródło
€1
jest dziwne ...JavaScript, 39 bajtów
źródło
Galaretka ,
10, 9 bajtówWypróbuj online!
Również 1 zindeksowany i kończy się dość szybko.
Jeden bajt zapisany dzięki @ErikTheOutgolfer!
Wyjaśnienie:
Hipotetycznie powiedzmy, że input (
a
) to 3.źródło
Ḥ€ŒḄ€Ṗ€Fị@
, więc możesz użyćµ€
dla -1 (trzy lub więcej monad€
na początku):ḤŒḄṖµ€Fị@
ḤŒḄṖ
<newline>,½ĊÇ€Fị@
aby 12 spełniało wymagania 10.000 (lokalne uruchomienie 9-bajtowego kodu zajmuje około 2:20 na moim i7 i wykorzystuje 7 GB)MATL , 15 bajtów
Na podstawie 1.
Wypróbuj online!
Przekroczono limit czasu dla największych przypadków testowych w TIO, ale kończy się z czasem na moim komputerze stacjonarnym (kompilator działający na MATLAB R2017a). Aby wyświetlić czas, który upłynął, dodaj
Z`
na końcu kodu.Wyjaśnienie
Kod generuje o wiele więcej terminów niż to konieczne. W szczególności oblicza
n
„kawałki” sekwencji, w których każdy kawałek jest zliczaniem w górę i z powrotem do 1.źródło
Łuska ,
1210 bajtówWypróbuj online!
1-indeksowany, działa dość szybko
Wyjaśnienie
źródło
…
Mathematica, 90 bajtów
Wypróbuj online!
źródło
Siatkówka , 62 bajty
Wypróbuj online! Link zawiera przypadki testowe. Dane wejściowe są indeksowane 1. Pierwszy etap to konwersja dziesiętna na jednostkową. W drugim etapie najwyższa liczba kwadratowa znajduje się
s
dokładnie poniżej połowyn
;$1
jests²
, podczas gdy$2
jest2s-1
. Oblicza dwie wartości, po pierwsze liczbę liczb w bieżącym przebiegu w górę / w dół, która jest4(s+1) = 4s+4 = 2$2+6
, a po drugie pozycję w tym przebiegu, któran-2s² = n-(2$1+1)+1 = n-$&+1
wymaga tylko1
uzupełnienia1
zastosowanego w celu wymuszenia ścisłej nierówności. Ostatni etap jest następnie liczony od tej pozycji do początku i końca przebiegu, a następnie przyjmuje niższy wynik i konwertuje go na liczbę dziesiętną.źródło
Mathematica, 67 bajtów
Wypróbuj online!
źródło
Perl 5 , 43 + 1 (-p) = 44 bajty
Wypróbuj online!
Pracowałem nad formułą do bezpośredniego obliczenia n-tego elementu. Potem zobaczyłem, że @ fireflame241 wykonał tę pracę i grałem w golfa w Perlu.
# Perl 5 , 50 + 1 (-n) = 51 bajtówWypróbuj online!
Wyniki są indeksowane 0.
źródło
Haskell ,
11581 bajtówWypróbuj online!
Tutaj dzieje się trochę magii. Prawdopodobnie może być krótszy, gdybym użył normalnego podejścia.
Wyjaśnienie
Najpierw zdefiniujemy
%
.%
jest funkcją, która przyjmuje dwie zmiennex
orazy
. Tworzy listęscanl(+)y[y+1,y+3..]
i stwierdza, że pierwszy element tej listy jest większy niżx
.scanl(+)
po prostu wykonuje sumy iteracyjne, aby uzyskać liczby trójkątne, które moglibyśmy zrobićscanl(+)0[1..]
, aby uzyskać liczby kwadratowe, które zrobilibyśmyscanl(+)0[1,3..]
. Dwie listy, które będziemy konstruować, sąscanl(+)2[3,5..]
iscanl(+)1[2,4..]
są to punkty przegięcia wzoru.Teraz definiujemy główną funkcję,
g
która zajmujex
. Jeślix
jest jeden, to zwracamy,1
ponieważ jest to pierwsza wartość. W przeciwnym razie sprawdzamy dwa kolejne punkty przegięcia, jeśli przegięcie w dół jest większe1%x>2x
zwracamy następcę, wg$x-1
przeciwnym razie zwracamy poprzednikag$x-1
.Ok, ale dlaczego to działa?
Przede wszystkim „Co ze sposobem, w jaki znajdujemy wierzchołki?”. Ważne jest, aby zwrócić uwagę na odległość między kolejnymi wierzchołkami tego samego typu. Zauważysz, że różnice rosną za każdym razem o 2. Ma to sens, ponieważ podstawy trójkątów stają się za każdym razem szersze o 2. Możemy zrobić stałą różnicę listy, używając literału listy tak
[2,4..]
i używamyscanl(+)
do przekształcania tych list w nasze listy wierzchołków, w zależności od położenia pierwszego wierzchołka i pierwszej różnicy.Teraz, gdy mamy już sposób na znalezienie wierzchołków w górę i w dół, możemy wykorzystać te informacje do uzyskania wartości. Mówimy, że pierwszą wartością jest
1
inaczej, musimy wziąć następcę lub poprzednika. Jeśli następny wierzchołek jest skierowany w górę, chcemy wziąć poprzednika, w przeciwnym razie weźmiemy następcę.Haskell ,
565146 bajtówOto moje lepsze rozwiązanie z mniejszą matematyką i mniejszą liczbą bajtów.
Wypróbuj online!
źródło
Pyke , 14 bajtów
Wypróbuj tutaj!
źródło
C # (.NET Core) , 120 bajtów
Objaśnienie: całkiem proste, pierwsza zagnieżdżona pętla wspina się na maksimum, druga schodzi z powrotem do 2. Powtórzenie dla każdej wielokrotności 2.
Wypróbuj online!
źródło
Rubinowy ,
7875 bajtówOszczędność 1 bajtu dzięki Stepowi Henowi
Zaoszczędzony 1 bajt dzięki Mr. Xcoder
Wypróbuj online!
Mam nadzieję, że uda mi się uzyskać wskazówki dotyczące dalszego zmniejszania liczby bajtów. Próbowałem zastosować proste podejście.
źródło
c=1 if
można zagrać w golfa doc=1if
->n{a=0;b=2;c=1;n.times{if a==b then c=0;b+=2;end;c=1if a==1;a+=c<1?-1:1};a}
Java (OpenJDK 8) , 53 bajty
Wypróbuj online!
-2 bajty dzięki Nevay.
1-indeksowany.
TL; DR Podzieliliśmy sekwencję na wygodne fragmenty, znajdź kawałek
n
, a następnie znajdźnth
pozycję w kawałku.Tutaj możemy podzielić sekwencję jak
[[1,2],[1,2,3,4,3,2],[1,2,3,4,5,6,5,4,3,2],...]
, co daje nam wielkość porcji4i-2
. Począwszy odi=2
, odejmujemyi
odn
zasadniczo ruchu w górę kawałek na raz. Gdy spełnimyn<=i
, wiemy, żen
jest to pozycja prawidłowej wartości w bieżącej porcji.Następnie otrzymujemy wartość, porównując
n
doi
wielkości porcji. Punkt środkowy każdej części jest równyi/2+1
; jeślin
jest mniejszy, po prostu wracamyn
. Jeślin
jest większy, wracamyi-n+2
.Przykład
źródło
+1
,return n>i/2?i-n+2:n
wystarczy.Python 2 , 5! bajtów (120 bajtów: P)
Wypróbuj online!
Prosto, tworzy listę, a następnie przyjmuje element wejściowy
źródło
Python 3 ,
184156 bajtówWypróbuj online!
gra w golfa z generatorem Pythona do „leniwej” oceny
źródło
QBIC , 47 bajtów
Wyjaśnienie
źródło
Röda , 54 bajty
Wypróbuj online!
Zadzwoń z:
try f(n)
Ta funkcja szybko zwraca odpowiedź, ale potem wykonuje kilka niepotrzebnych obliczeń i ostatecznie kończy się pamięć.
Ponieważ funkcja zwraca rzeczywistą odpowiedź wkrótce po jej wywołaniu (wyraźnie poniżej minuty), myślę, że ta odpowiedź jest poprawna.
(W Röda funkcje mogą zwracać wartości, zanim wyjdą z powodu równoległości).
źródło
C # (.NET Core) ,
99 9586 bajtówWypróbuj online!
Funkcja Lambda, która przyjmuje i zwraca liczbę całkowitą. Pojedyncza pętla, która obsługuje zliczanie w górę i w dół.
źródło
PHP, 65 + 1 bajtów
Uruchom jako potok z
-R
lub wypróbuj go online (lub odkomentuj jedną z pozostałych wersji).Port rekursywnego JavaScript tsh zajmuje 66 bajtów:
Port rozwiązania Arnaulda zajmuje 62 + 1:
Golfowy port Javy Xanderhall ma jak najkrótszy kod (55 + 1 bajtów):
źródło
Pyth ,
1918 bajtówWypróbuj tutaj!
źródło