Esse número é triangular?


33

Desafio

Dado um número inteiro positivo, determine se é um número triangular e, consequentemente, produza um dos dois valores constantes e distintos.

Definição

Um número triangular é um número que pode ser expresso como a soma dos números inteiros positivos consecutivos, iniciando em 1. Eles também podem ser expressos com a fórmula n(n + 1) / 2, onde nestá um número inteiro positivo.

Casos de teste

Verdade:

1
3
6
10
15
21
55
276
1540
2701
5050
7626
18915
71253
173166
222111
303031
307720
500500
998991

Falsy:

2
4
5
7
8
9
11
16
32
50
290
555
4576
31988
187394
501500
999999

Regras

  • Sua entrada pode ser uma função ou um programa.
  • Você pode assumir que a entrada é um número inteiro positivo abaixo de 10 6 .
  • Você deve escolher duas saídas distintas e constantes para distinguir as duas categorias.

Isso é , então o código mais curto em bytes em cada idioma vence.





Por que você não incluiu zero?
Neil

1
@ Neil Eu queria minimizar o número possível de casos extremos, e lidar com zero é um deles que considero não muito importante. Você acha que seria melhor se o zero precisasse ser tratado? (A resposta Jelly falhar atualmente no zero, por exemplo)
ETHproductions

Respostas:


21

Haskell , 23 bytes

EDITAR:

  • -1 byte: @xnor se livrou dos parênteses com a $.

Uma função anônima pegando Inte retornando a Char.

A saída é '1'para números triangulares e '0'para outros.

(!!)$show.(10^)=<<[0..]

Experimente online!

  • Use como ((!!)$show.(10^)=<<[0..]) 998991.
  • Gera os números 1, 10, 100, 1000, ..., converte-os em seqüências de caracteres e concatena-os. Em seguida, indexa a sequência infinita resultante

    "1101001000100001000001000000...

6
Um método imaginativo! Você pode salvar um byte com (!!)$show.(10^)=<<[0..].
Xnor 23/05

20

Python , 24 bytes

lambda n:(8*n+1)**.5%1>0

Experimente online!

Saídas Falsepara números triangulares, Truepara o resto. Verifica se 8*n+1é um quadrado perfeito. O Python usará quadrados perfeitos para flutuações exatas de números inteiros, independentemente do tamanho, portanto, não há problemas de ponto flutuante.


3
(1<<10000)**.5: OverflowError: int muito grande para converter a flutuar
isaacg

@isaacg O desafio não requer insumos que grande: "Você pode assumir que a entrada é um inteiro positivo inferior a 10 ^ 6"
Trichoplax

1
@trichoplax Acho que estava contestando a afirmação do xnor no texto. A apresentação está boa, eu concordo.
Isaacg

13

Gelatina , 4 bytes

R+\ċ

Experimente online!

Quão?

R+\ċ - Main link: n
R    - range(n)   -> [1,2,3,...,N]
  \  - cumulative reduce by:
 +   -   addition -> [1,3,6,...,T(N)]
   ċ - count occurrences of right (n) in left -> 1 if triangular, 0 otherwise

Estou surpreso que a redução cumulativa não faça um intervalo automaticamente. Existe uma opção de design por trás disso?
ETHproductions

Não tenho 100% de certeza, mas acho que (pelo menos atualmente) seria necessário, devido à redução da operação diádica que causaria um intervalo a ser feito.
Jonathan Allan

... na verdade, mesmo isso parece não se aplicar (por exemplo, isso vs isso . Parece que a implementação do link rápido substitui tanto que o iterável não faz um intervalo, mesmo que a operação diádica o defina para um argumento. Pinged Dennis to field este :)
Jonathan Allan

O @ETHproductions /e \provavelmente estavam entre as cinco primeiras rápidas a serem implementadas, anteriores à idéia de converter argumentos inteiros no intervalo.
Dennis

13

Retina , 10 bytes

(^1|1\1)+$

A entrada está unária. A saída é 0ou 1.

Experimente online! (Como um conjunto de testes que faz conversão de decimal para unário por conveniência.)

Explicação

Este é o exercício mais básico em referências futuras. A maioria das pessoas está familiarizada com as referências anteriores na regex, por exemplo, (.)\1para corresponder a um caractere repetido. No entanto, alguns dos sabores mais avançados permitem que você use uma referência anterior antes ou dentro do grupo ao qual está se referindo. Nesse caso, geralmente é chamado de referência direta. Isso pode fazer sentido se a referência for repetida. Pode não estar bem definido na primeira iteração, mas nas iterações subseqüentes, o grupo posterior ou o próximo capturou algo e pode ser reutilizado.

Isso é mais comumente usado para implementar padrões recorrentes em cadeias unárias. Nesse caso, tentamos corresponder a entrada como a soma dos números inteiros consecutivos:

(        # This is group 1, which we'll repeat 1 or more times.
  ^1     #   Group 1 either matches a single 1 at the beginning of the string.
|        # or
  1\1    #   It matches whatever the previous iteration matched, plus another
         #   1, thereby incrementing our counter.
         # Note that the first alternative only works on the first iteration
         # due to the anchor, and the second alternative only works *after*
         # the first iteration, because only then the reference is valid.
)+
$        # Finally, we make sure that we can exactly hit the end of the
         # string with this process.

1
Por que não (^|1\1)+$funciona?
Leaky Nun

3
Os mecanismos de regex @LeakyNun têm uma otimização de que param de repetir um grupo se ele estiver vazio n vezes onde n é o mínimo do quantificador que você está usando (no seu caso 1; se o mínimo for 0, seria tentado uma vez de qualquer maneira) . Se você mudar +para {2,}, deve funcionar. Essa otimização evita loops infinitos, mas também é a única coisa que impede que o regex .NET seja completo por Turing por conta própria.
Martin Ender

Isso só me salvou 70 bytes: codegolf.stackexchange.com/a/118387
Neil

Faça esses 74 bytes, graças a \G!
911 Neil


8

Mathematica, 16 bytes

OddQ@Sqrt[1+8#]&

Essencialmente uma porta da solução Python da xnor . Saídas Truepara números triangulares, Falsecaso contrário.


7

JavaScript (ES6), 30 27 bytes

Guardado 2 bytes graças a kamoroso94

f=(n,k)=>n>0?f(n+~k,-~k):!n

Casos de teste

Versão não recursiva (ES7), 19 bytes

Resposta do porto de Adnan .

x=>(8*x+1)**.5%1==0

Só vendo agora que você editou a solução de 19 bytes em sua resposta alguns minutos antes de eu publicar a minha . Devo excluir o meu? Qual é a etiqueta geralmente aceita nisso?
Shaggy

1
@ Shaggy Eu não acho que é um problema real aqui. Minha resposta 'principal' realmente é a resposta recursiva.
Arnauld 23/05

Reduza para 28 bytes com f=(n,k=1)=>n>0?f(n-k,k+1):!n?
Kamoroso94 23/05

1
@ kamoroso94 Obrigado! Atualizada. E um terceiro byte foi salvo ao omitir a inicialização de k.
Arnauld 23/05

Uso elegante de NOT bit a bit como um incrementador para um undefinedvalor inicial ; sua edição foi um prazer de ler depois que cheguei à sua solução anterior.
Apsillers 23/05

6

CJam , 11 bytes

ri2*_mQ_)*=

Saídas 1para triangular, 0caso contrário.

Experimente online!

Explicação

Considere entrada 21.

ri               e# Input integer.             STACK: 21
  2*             e# Multiply by 2.             STACK: 42
    _            e# Duplicate.                 STACK: 42, 42
     mQ          e# Integer square root.       STACK: 42, 6
       _)        e# Duplicate, increment.      STACK: 42, 6, 7
         *       e# Multiply.                  STACK: 42, 42
          =      e# Equal?                     STACK: 1

6

Flak cerebral , 40 bytes

(([{}](((()))<>))<>){<>({}({}({})))}{}{}

Assistente de trigo e eu tivemos um duelo sobre esta questão. Quando decidimos postar nossas soluções, estávamos atados a 42 bytes, mas encontrei um golf de 2 bytes de sua solução. Decidimos que contaria como desempate (minha solução está abaixo).

Experimente online!

Explicação:

# Set up the stacks like this:  -input
                                     1     -input
                                     1          1
(([{}](((()))<>))<>)                 ^

# Output 1 for triangular and 0 for non-triangular 
{<>({}({}({})))}{}{}

Para uma explicação completa, consulte a resposta do Assistente de Trigo .


Flak cerebral , 42 bytes

(([({})])<>){(({}())<>{}({})){((<>))}{}{}}

Saídas 0\n(literal newline) para truthy e a string vazia para falsy.

A idéia é subtrair 1 e 2 e 3 até a entrada. Se você pressionar 0, sabe que este é um número triangular, para que você possa parar por aí.

Experimente online! (verdade)
Experimente online! (falso)

# Push -input on both stacks. One is a counter and the other is a running total
(([({})])<>)

# Count up from -input to 0
{
  # Push the new total which is: (counter += 1) + total (popped) + input (not popped)
  # This effectively adds 1, then 2, then 3 and so on to the running total
  (({}())<>{}({}))
  # If not 0
  {
    # Push to 0s and switch stacks to "protect" the other values
    ((<>))
  # End if
  }
  # Pop the two 0s, or empty the stack if we hit 0
  {}{}
# End loop
}

Aqui está uma solução de 46 bytes que eu achei interessante.

{<>(({}())){({}[()]<>{(<({}[()])>)}{}<>)}{}<>}

Saídas 0\n(literal newline) para truthy, a string vazia para falsy.

A idéia é fazer a contagem regressiva da entrada por números consecutivos, 1 de cada vez. Por exemploinput - (1) - (1,1) - (1,1,1) . Cada vez que subtraímos, se ainda não estamos em 0, deixamos um valor extra na pilha. Dessa forma, se estivermos em 0 e ainda subtrairmos quando aparecermos, removemos o último valor da pilha. Se a entrada for um número triangular, terminaremos exatamente em 0 e não exibiremos o 0.

Experimente online! truthy
Experimente online! falsear

# Implicit input (call it I)

# Until we reach 0, or the stack is empty
{
  # Add 1 to the other stack and push it twice. This is our counter.
  <>(({}()))
  # While counter != 0
  {
    # counter -= 1
    ({}[()]
    # if I != 0 
    <>{
      # I -= 1, and push 0 to escape the if
      (<({}[()])>)
    # End if
    }
    # Pop from the stack with I. This is either the 0 from the if, or I
    {}
    # Get ready for next loop End while
    <>)
  # End While
  }
  # Pop the counter that we were subtracting from
  {}<>
# End Until we reach 0, or the stack is empty.
}

6

Gelatina , 5 bytes

×8‘Ʋ

Experimente online!

fundo

Seja n a entrada. Se n é o k- ésimo número triangular, temos

n=k(k+1)2k2+k2n=0k=12(1±1+8n),

o que significa que haverá uma solução natural se e somente se 1 + 8n for um quadrado ímpar e perfeito. Claramente, a verificação da paridade de 1 + 8n não é necessária.

Como funciona

×8‘Ʋ  Main link. Argument: n

×8     Yield 8n.
  ‘    Increment, yielding 8n + 1.
   Ʋ  Test if the result is a perfect square.


5

Flak cerebral , 42 bytes

(([{}](<((())<>)>))<>){<>({}({}({})))}{}{}

Experimente online!

Explicação

O objetivo deste programa é criar um estado em duas pilhas e executar uma operação constante em ambas as pilhas até que um deles seja zeros. Podemos então produzir dependendo da pilha em que estamos. Isso é semelhante aos programas que determinam o sinal de um número. Esses programas colocam numa pilha e-n a outra e adicionam uma e alterna as pilhas até que uma delas seja zero. Se o número foi negativo em primeiro lugar, a primeira pilha atingirá zero, se o número for positivo, a outra pilha atingirá zero.

Aqui, criamos duas pilhas, uma que subtrai números consecutivos da entrada e outra que apenas subtrai um. Aquele que subtrai números consecutivos só terminará se o número for triangular (caso contrário, passará zero e continuará indo para os negativos). O outro sempre terminará para qualquer número positivo, mas sempre será mais lento que o primeiro, portanto, números não triangulares terminarão nessa pilha.

Então, como configuramos pilhas para que a mesma operação subtraia números consecutivos em um e subtraia um no outro? Em cada pilha, temos a entrada no topo para que possa ser verificado, abaixo disso temos a diferença e abaixo temos a diferença da diferença. Cada vez que executamos, adicionamos a "diferença da diferença" à "diferença" regular e subtraímos isso da entrada. Para a pilha que verifica a triangularidade, configuramos nossa dupla diferença para 1que possamos obter números inteiros consecutivos cada vez que executamos, para a outra pilha que configuramos para 0que nunca alteremos a diferença, ou seja, ela sempre permanece 1. Aqui está como a pilha é configurada no início, onde nestá a entrada:

-n  -n
 0   1
 1   0

Quando finalmente terminamos, podemos usar essas diferenças para verificar em qual pilha estamos, exibimos os dois principais valores e obtemos 1um número triangular e 0um número não triangular.


Código anotado

(([{}](<((())<>)>))<>) Set up the stack
{                      While
 <>                    Switch stacks
 ({}({}({})))          Add bottom to second to bottom, add second to bottom to top
}                      End while
{}{}                   Pop the top two values

Aqui está uma solução de 50 bytes que eu gosto também.

{(({}[()]))}(([[]])<>){({}{}())<>}({}{()<><{}>}{})

Experimente online!


5

Cubix , 23 24 25 bytes

I1Wq/)s.;0..s;p-?\.+O@u

0 para verdade e nada 0 para falsey. Forças brutas incrementando o contador, adicionando à soma acumulada e comparando à entrada. Agora, tente encaixá-lo em um cubo 2x2x2. Fiz isso!

    I 1
    W q
/ ) s . ; 0 . .
s ; p - ? \ . +
    O @
    u .

Experimente online!

  • / Reflita para enfrentar.
  • I10\ obter entrada inteira, pressione 1 (contador), pressione 0 (soma) e reflita
  • +s;p-corpo do laço. Adicione soma e contador, reduza a soma anterior, aumente a entrada e subtraia
  • ? Teste o resultado da subtração
    • Para 0 resultado, continuar em frente \.uO@reflete na face inferior, no-op, inversão de marcha, saída e parada.
    • Para obter resultados positivos, vire à direita na face inferior e @pare
    • Para resultados negativos, vire a ;qWs)/susubtração da gota esquerda , coloque a entrada para baixo, mude para a esquerda, contador e somatório de trocas, contador de incremento, refletido, soma e contador de trocas, giro em U no corpo do loop principal.

Tão tentadoramente perto ... esse último byte precisará de muito esforço e inteligência.
ETHproductions

Sim, pensei que tinha, mas está sendo ilusório #
MickyT 22/17/17

1
@ETHproductions encontrou o byte
MickyT

Seu código e seu cubo desdobrado parecem diferentes, o canto inferior direito é um .no cubo, mas um 1no seu código.
Assistente de trigo

Graças @WheatWizard para que, mau edição da minha parte
MickyT

4

05AB1E , 7 6 bytes

EDIT : Graças a @Dennis: salvei um byte porque esqueci o operador de incremento

8*>t.ï

Experimente online!

né triangular se sqrt(8n + 1)é um número inteiro

Como funciona

8* # multiply implicit input by 8
  > # add one
   t # sqrt
    .ï # is integer

Provavelmente ainda não estava disponível no momento, mas t.ïpode estar Ųnos dias de hoje, que é um recurso interno para verificar se um número é um quadrado.
Kevin Cruijssen 14/02

4

Perl 6 , 17 bytes

{$_∈[\+] 1..$_}

Apenas verifica se $_, a entrada da função é igual a qualquer um dos elementos da redução de adição triangular (1, 1+2, ..., 1+2+...+$_).


4

Alice , 38 22 bytes

Muitos bytes salvos graças a Martin e Leo

/ i \ 2 * .2RE.h * -n / o @

Há uma nova linha à direita. Saídas 1para triangular, 0caso contrário.

Experimente online!

Explicação

Isso usa a mesma abordagem da minha resposta CJam , apenas mais desajeitada. De forma linearizada, o programa se torna

i2*.2RE.h*-no@

onde o ie oestá realmente no modo ordinal.

Considere a entrada 21como um exemplo.

i         Input integer                       STACK: 21
2*        Multiply by 2                       STACK: 42
.         Duplicate                           STACK: 42, 42
2RE       Integer square root                 STACK: 42, 6
.         Duplicate                           STACK: 42, 6, 6
h         Increment                           STACK: 42, 6, 7
*         Multiply                            STACK: 42, 42
-         Subtract                            STACK: 0
n         Logical negation                    STACK: 1
o         Output integer                      STACK:
@         End program

Minha primeira resposta de Alice
Luis Mendo

1
Tenho a sensação de que poderia ser aproximadamente metade com uma das estruturas de controle fantasia de Martin ...
ETHproductions

Eu também ... :-)
Luis Mendo

Meu primeiro golf Alice: mesmo código, 23 bytes
Nitrodon

Um layout mais "padrão" para esse tipo de programa seria esse . Dito isto, você pode se livrar do 1 na pilha, e simplesmente saída da negação lógica da subtração (ie ...h*-no@)
Leo

4

Japonês , 10 7 bytes

Economizou 3 bytes graças a @Luke e @ETHproductions

*8Ä ¬v1

Experimente online!

Explicação:

*8Ä ¬v1
    ¬    // Square root of:
*8       //   Input * 8
  Ä      //   +1
     v1  // Return 1 if divisible by 1; Else, return 0

õ å+ øU

Explicação:

õ å+ øU
õ           // Create a range from [1...Input]
  å+        // Cumulative reduce by addition
     øU     // Does it contain the input?

Experimente online!


A questão pede duas saídas distintas constantes.
Xnor

*8Ä ¬u1 cpara 9B (saídas 0 se a entrada for triangular, 1 caso contrário)
Luke

@Luke Você poderia mudar u1 cpara v1, acredito (alternar as saídas)
ETHproductions

7 bytes? Agradável! De alguma forma, perdi isso ao postar minha própria solução semelhante no final da última tentativa. Deixe-me saber se você gostaria que eu a excluísse.
Shaggy

4

R , 23 19 bytes

Abordagem semelhante a outras respostas. Verifica se 8x+1é um quadrado perfeito.
-4 bytes graças a Giuseppe e MickyT.

!(8*scan()+1)^.5%%1

Experimente online!


2
você pode usar em !vez de==0
Giuseppe

Isso é muito bom, pois também é vetorizado!
Giuseppe

1
Eu acho que você pode se livrar dos suportes externos também #!(8*scan()+1)^.5%%1
MickyT

3

MATL , 5 bytes

t:Ysm

Experimente online!

Explicação:

t       % Duplicate input
 :      % Range(1, input)
  Ys    % Cumulative sum. This will push the first *n* triangular numbers
    m   % ismember. Pushes true if the input is contained within the array we just pushed

Eu estava indo postar t:Ys=a. Esqueceu-se de m:-)
Luis Mendo

1
@LuisMendo eu não sabia maté que vi esta resposta . Engraçado como as duas respostas são quase idênticas: D
DJMcMayhem

3

Lote, 72 bytes

@set/aj=i=0
:l
@if %1% gtr %j% set/aj+=i+=1&goto l
@if %1==%j% echo 1

Saídas 1 em caso de sucesso, nada em caso de falha. Também funciona para zero, embora não seja solicitado pela pergunta por algum motivo.


3

JavaScript (ES7), 19 18 bytes

Da minha resposta a uma pergunta relacionada .

Saídas falsepara números triangulares ou truenão triangulares, conforme permitido pelo OP.

n=>(8*n+1)**.5%1>0

Tente

f=
n=>(8*n+1)**.5%1>0
oninput=_=>o.innerText=f(+i.value)
<input id=i type=number><pre id=o>


Eu acho que você poderia salvar um byte com n=>(8*n+1)**.5%1>0(que iria inverter as saídas)
ETHproductions

@ETHproductions: OK, desde que você permita. É normalmente permitido fazer isso?
Shaggy

1
Ele é qualificado como "duas saídas constantes e distintas", então sim. Outros desafios de problemas de decisão podem exigir verdade / falsidade.
ETHproductions


3

Mathematica, 28 bytes

!Accumulate@Range@#~FreeQ~#&

Eu recomendo substituir 7!por #. Primeiro, é mais curto; mais importante, a solução atual não está correta, pois impõe artificialmente um limite no tamanho da entrada em que trabalha.
Greg Martin

1
O OP diz: "Você pode assumir que a entrada é um número inteiro positivo abaixo de 10 ^ 6". Mas eu gosto da sua idéia e a aceitarei, embora a minha dê o resultado certo para cada caso, usando uma lista de 5040 elementos, mas o seu pior caso precisa de uma lista de 999999 elementos.Obrigado pela dica!
J42161217

1
Ops, desculpe, não vi o comentário do OP! Sim, existem alguns incentivos "perversos" no golfe de código: que a economia de 1 byte é mais importante em uma questão de golfe de código do que toda a eficiência do mundo :)
Greg Martin


3

Excel, 31 22 bytes

9 bytes salvos graças ao Octopus

Saídas TRUEpara números triangulares. Outra coisa FALSE. Verifica se 8*n+1é um quadrado perfeito.

=MOD(SQRT(8*B1+1),1)=0

1
=MOD(SQRT(8*A1+1),1)=0salva alguns bytes
Octopus

2

Braquilog , 5 bytes

≥ℕ⟦+?

Experimente online!

Explicação

≥ℕ⟦+?
≥ℕ     There is a number from 0 to {the input} inclusive
  ⟦    such that the range from 0 to that number
   +   has a sum
    ?  that equals the input


2

Python - 52 bytes

Nota: Eu sei que as outras duas respostas Python são muito mais curtas, mas esta é a maneira antiga, mais um algoritmo manual

n=input();i=s=0
while s<n:s=(i*i+i)/2;i+=1
print s>n

2

APL (Dyalog) , 6 bytes

⊢∊+\∘

Experimente online!

Explicação

⊢∊+\∘
                       Creates a range from 1 to the right_argument
  +\                    Cumulative sum of this range; 1 1+2 1+2+3 .. 1+2+..+n. These are the triangular numbers
⊢∊                      Does the right argument belong to this list of integers in this cumulative sum

Saídas 0para false e 1true.


Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.