Manter / Largar / Aumentar Sequência

20

Aqui está a sequência da qual estou falando:

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

A partir de 1, mantenha 1, solte os 2 próximos, mantenha os 2 próximos, solte 3, mantenha 3 e assim por diante. Sim, também está no OEIS (A064801) !

O desafio

Dado um número inteiro n>0, encontre o enésimo termo da sequência acima

Casos de teste

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

Isso é código de golfe, então a resposta mais curta em bytes vence! Boa sorte!

Taylor Scott
fonte
3
Podemos escolher entre 0 e 1 indexação?
Mr. Xcoder
1
@ Mr.Xcoder, receio que não. Isso é apenas 1 indexado
Podemos retornar uma lista contendo todos os elementos em ordem?
Assistente de trigo
@ WheatWizard isso é totalmente inaceitável. desculpe

Respostas:

12

Java (OpenJDK 8) , 45 44 bytes

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

Experimente online!

-1 byte graças a @Nevay

Depois de encarar isso por um tempo, notei um padrão. Toda vez que soltamos nnúmeros, o próximo número na sequência é um quadrado perfeito. Vendo isso, dividi mentalmente a sequência em pedaços convenientes: [[1],[4,5],[9,10,11],...]basicamente, o ith chunk começa i*ie itera para cima em busca de ielementos.

Para encontrar o nnúmero th nesta sequência, queremos encontrar primeiro em qual bloco o número está e, em seguida, em qual posição ele ocupa. Nós subtrair o nosso número de incremento ide naté né inferior a i(o que nos dá o nosso pedaço), e, em seguida, basta adicionar n-1para i*iobter a correta positionno pedaço.

Exemplo:

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
fonte
1
Você pode usar return~-n+i*i;para salvar 1 byte.
Nevay 22/08/19
7

Haskell, 48 43 41 bytes

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

4 bytes extras para indexação baseada em 1 em vez de baseada em 0. Uma restrição desnecessária, IMHO.

Experimente 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
fonte
6

Python 3 , 47 46 bytes

1 byte graças ao Sr. Xcoder.

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

Experimente online!

MUITO rápido para números mais altos

Freira Furada
fonte
46 bytes: def f(n):a=round((2*n)**.5);return~-n+a*-~a//2. Não tenho certeza ... Abordagem inteligente!
Mr. Xcoder
Aw, lambdas duplas é um byte extra, eu estava esperando que iria salvar um byte ...
Stephen
Por que alguém negou isso? Existe algum problema com a abordagem que não percebemos?
Sr. Xcoder
@ Mr.Xcoder talvez por causa da observação ousada.
Leaky Nun
a*(a+1)é par para todo número inteiro. O Python reclama da divisão de float em números inteiros? Ele reclama de operações bit a bit em carros alegóricos? Não se: (2*n)**.5+.5|0.
Titus
3

Haskell , 33 bytes

Uma função anônima. Use como((!!)$0:do n<-[1..];[n^2..n^2+n-1]) 1

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

Experimente online!

  • Constrói a sequência como uma lista infinita e depois a indexa nela !!. o0: é um elemento fictício para ajustar a indexação baseada em 0 a 1.
  • A gama [n^2..n^2+n-1] constrói uma subsequência sem lacunas, começando com o quadrado de ne contendon números.
  • A donotação concatena os intervalos construídos para todos n>=1.
Ørjan Johansen
fonte
2

Python 3 , 46 bytes

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

Experimente online!

Mr. Xcoder
fonte
O mesmo algoritmo ... #
Leaky Nun
2

Perl 6 , 43 bytes

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

Teste-o

Expandido:

{  # 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}...*) produz:

(
 (1,),
 (4, 5),
 (9, 10, 11),
 (16, 17, 18, 19),
 (25, 26, 27, 28, 29),
 ...
).Seq
Brad Gilbert b2gills
fonte
2

TeX, 166 bytes

\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}

Uso

\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}

insira a descrição da imagem aqui

Freira Furada
fonte
2

Javascript, 43 38 bytes

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

Experimente online!

Uso o fato de que, para cada número triangular mais um, o resultado é um número quadrado.

Como exemplo: números triangulares são 0, 1, 3, 6, 10 ... então para 1, 2, 4, 7, 11 ... observamos 1, 4, 9, 16, 25 ... em nossa sequência .

Se o índice estiver em algum lugar entre esses números conhecidos, os elementos de nossa sequência avançam apenas um. Por exemplo, para calcular o resultado para 10, pegamos 7 (como um número triangular mais um), pegamos o resultado (16) e adicionamos 10-7 = 3. Assim, 16 + 3 = 19.

mackoo13
fonte
1

05AB1E , 12 bytes

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

Experimente online!

Erik, o Outgolfer
fonte
Abordagem muito legal!
Emigna
@ Emigna Bem, eu só estou fazendo [0..a-1] + a**2, a coisa legal aqui imo é apenas o em ÝÁćn+vez de D<Ýsn+.
Erik the Outgolfer
1

C # (Mono) , 164 bytes

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];}

Experimente online!

TheLethalCoder
fonte
1

Mathematica, 37 bytes

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

Explicação

Range@#+#^2-1&

Functionque pega um número inteiro positivo #e retorna a execução de #números consecutivos na sequência.

...~Array~#

Produz a lista de todas essas execuções até a entrada #

Flatten[...][[#]]

Flattensa lista resultante e retorna o #elemento th.

ngenisis
fonte
1

Tampio , 310 308 bytes

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

Uso: 4:n uniavalia como 9.

Explicação:

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

Da biblioteca padrão:

a `vähennetty` b = b - a
yhteenlasku a b  = a + b
fergusq
fonte
1

JavaScript (ES6), 33 bytes

Solução recursiva inspirada nas observações de Xanderhall .

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

Tente

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>

Shaggy
fonte
0

Python 3 , 50 bytes

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

Experimente online!

Freira Furada
fonte
Isso seria realmente beneficiar de uma porta-programa completo para Python 2 ( 46 bytes - seria amarrar a abordagem recursiva)
Mr. Xcoder
0

Mathematica, 82 bytes

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

Javascript (ES6) 100 98 bytes

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}

Fiz isso rápido, então aposto que há muito espaço para melhorias, apenas loops e contadores básicos.

Adormecido
fonte
0

Retina , 27 bytes

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

Experimente online! Porto da resposta em Python do @ LeakyNun. O primeiro e o último estágios são apenas chatas decimais - conversão unária. O segundo estágio funciona assim: ((^1|1\2)+)é um combinador de números triangular; $1é o número triangular correspondente enquanto $2é o seu índice. O final 1significa que ele corresponde ao maior número triangular estritamente menor que a entrada, resultando em exatamente uma iteração a menos do que o loop Python, o que significa que $1é equivalente a a-ie $2para i-1e sua soma é a-1ou ~-aconforme necessário. ( para corresponder também nesse caso.$& apenas impede que a correspondência seja excluída do resultado.) Observe que para uma entrada 1sem correspondência acontece e a saída é simplesmente a mesma que a entrada. Se você fosse perverso, poderia usar^((^1|1\2)*)1

Neil
fonte
0

MATL , 12 bytes

:"@U@:q+]vG)

Experimente online!

Explicação

:        % 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
fonte
0

PHP, 48 42 37 + 1 bytes

portado da resposta de Leaky Nun

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

Execute como pipe -Fou experimente online .

abordagem direta, 42 + 1 bytes (portado da outra resposta de Leaky Nun )

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

Corra como tubo com -nRou descomente acima de TiO.

solução iterativa mais antiga, 48 + 1 bytes

for(;$argn--;$n++)$c++>$z&&$n+=++$z+$c=1;echo$n;
Titus
fonte