Чи є це число трикутним?


33

Виклик

Давши додатне ціле число, визначте, чи це трикутне число, і відповідно виведіть одне з будь-яких двох постійних, чітких значень.

Визначення

Трикутне число є числом , яке може бути виражено в вигляді суми послідовних позитивних цілих чисел, починаючи з 1. Крім того, вони можуть бути виражені з формулою n(n + 1) / 2, де nмає деяке позитивне ціле число.

Тестові справи

Truthy:

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

Фальсі:

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

Правила

  • Ваш запис може бути функцією або програмою.
  • Ви можете припустити, що вхід є натуральним числом під 10 6 .
  • Ви повинні вибрати два постійні, чіткі виходи, щоб виділити дві категорії.

Це , тому виграє найкоротший код у байтах на кожній мові.





Чому ви не включили нуль?
Ніл

1
@Neil Я хотів мінімізувати кількість можливих крайових випадків, а обробка нуля - це один із них, який я вважав не надто важливим. Як ви вважаєте, було б краще, якби нуль потрібно обробляти? (Відповідь Jelly наразі не відповідає нулю, наприклад)
ETHproductions

Відповіді:


21

Haskell , 23 байти

Редагувати:

  • -1 байт: @xnor позбувся дужок із a $.

Анонімна функція прийому Intта повернення а Char.

Вихідні дані '1'для трикутних чисел та '0'для інших.

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

Спробуйте в Інтернеті!

  • Використовувати як ((!!)$show.(10^)=<<[0..]) 998991.
  • Згенерує числа 1, 10, 100, 1000, ..., перетворює їх у рядки та з'єднує їх. Потім індексується в отриманий нескінченний рядок

    "1101001000100001000001000000...

6
Образний метод! Ви можете зберегти байт за допомогою (!!)$show.(10^)=<<[0..].
xnor

20

Пітон , 24 байти

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

Спробуйте в Інтернеті!

Виходи Falseдля трикутних чисел, Trueдля решти. Перевіряє, чи 8*n+1ідеальний квадрат. Python візьме ідеальні квадрати для точних цілих плавців незалежно від величини, тому проблем з плаваючою комою немає.


3
(1<<10000)**.5: OverflowError: int занадто великий, щоб перетворити на плавати
isaacg

@isaacg У виклику не потрібні великі введення: "Ви можете припустити, що вхід є натуральним числом під 10 ^ 6"
trichoplax

1
@trichoplax Я думаю, що я спростував претензії xnor у тексті. Подання добре, я згоден.
isaacg

13

Желе , 4 байти

R+\ċ

Спробуйте в Інтернеті!

Як?

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

Я здивований, що сукупне зменшення не робить діапазон автоматично. Чи за цим стоїть вибір дизайну?
ETHproductions

Я не впевнений на 100%, але я думаю, що через хоча б зменшення діадіальної операції (принаймні на даний момент) потрібно було би спричинити діапазон.
Джонатан Аллан

... насправді навіть це, мабуть, не застосовується (наприклад, це проти цього . Здається, реалізація швидкого посилання переорієнтована таким чином, що ітерабельна програма не робить діапазон, навіть якщо діадична операція визначає це для аргументу. Пінг Денніс в поле цей :)
Джонатан Аллан

@ETHproductions /і, \ймовірно, були одними з перших п’яти квек, які були реалізовані, що передбачає ідею передавати цілі аргументи на діапазон.
Денніс

13

Сітківка , 10 байт

(^1|1\1)+$

Введення не одинакове. Вихід 0або 1.

Спробуйте в Інтернеті! (Як тестовий набір, який для зручності робить перетворення від десяткового до унарного.)

Пояснення

Це найосновніша вправа в прямих посиланнях. Більшість людей знайомі з зворотними посиланнями в регулярному вираженні, наприклад, (.)\1щоб відповідати повторюваному символу. Однак деякі більш досконалі аромати дозволяють використовувати зворотний зв'язок перед групою, про яку вона посилається, або всередині неї. У такому випадку його зазвичай називають прямим посиланням. Це може мати сенс, якщо посилання повториться. Він може бути не точно визначений під час першої ітерації, але на наступних ітераціях група пізніше чи навколишнє щось захопило і може бути використане повторно.

Це найчастіше використовується для реалізації повторюваних шаблонів на одинарних рядках. У цьому випадку ми намагаємось зіставити вхідні дані як суму послідовних цілих чисел:

(        # 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
Чому не (^|1\1)+$працює?
Лина монашка

3
@LeakyNun regex двигуни мають оптимізацію, що вони перестають повторювати групу, якщо вона була порожньою n разів, де n - мінімум кількісного показника, який ви використовуєте (у вашому випадку 1; якщо мінімум був 0, то будь-коли буде спробувано один раз) . Якщо ви перейдете +на {2,}, це має спрацювати. Ця оптимізація запобігає нескінченним циклам, але це також єдине, що утримує .NET-регекс від Turing-завершення самостійно.
Мартін Ендер

Це врятувало мене 70 байт: codegolf.stackexchange.com/a/118387
Ніл

Зробіть, що 74 байти, завдяки \G!
Ніл



7

JavaScript (ES6), 30 27 байт

Збережено 2 байти завдяки kamoroso94

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

Тестові справи

Нерекурсивна версія (ES7), 19 байт

Відповідь Порта Аднана .

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

Лише побачивши, що ви відредагували 19-байтне рішення у своїй відповіді за кілька хвилин до того, як я розмістив свою . Чи слід видалити шахту? Який загальноприйнятий етикет на цьому?
Кудлатий

1
@Shaggy Я не думаю, що це справжня проблема. Моя головна відповідь насправді є рекурсивною.
Арнольд

Зменшити до 28 байт за допомогою f=(n,k=1)=>n>0?f(n-k,k+1):!n?
каморосо94

1
@ kamoroso94 Дякую! Оновлено. І третій байт був збережений, опустивши ініціалізацію k.
Арнольд

Elegant use of bitwise NOT as an incrementor for an initially-undefined value; your edit was a pleasure to read after I independently arrived at your prior solution.
apsillers

6

CJam, 11 bytes

ri2*_mQ_)*=

Outputs 1 for triangular, 0 otherwise.

Try it online!

Explanation

Consider input 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

Brain-Flak, 40 bytes

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

Ми з Пшеничним Чарівником провели поєдинок з цього питання. Коли ми вирішили опублікувати наші рішення, ми зв'язали 42 байти, але я знайшов 2-байтний гольф його рішення. Ми вирішили, що буде вважатися вимикачем краватки (моє рішення нижче).

Спробуйте в Інтернеті!

Пояснення:

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

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

Для повного пояснення див. Відповідь Пшеничного майстра .


Мозок-Флак , 42 байти

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

Виходи 0\n(буквальний новий рядок) для триути, а порожній рядок - для помилки.

Ідея полягає в тому, щоб відняти 1, а потім 2, аж до входу. Якщо ви потрапили на 0, то знаєте, що це трикутне число, тож ви можете зупинитися на цьому.

Спробуйте в Інтернеті! (truthy)
Спробуйте в Інтернеті! (помилково)

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

Ось 46-байтне рішення, яке мені здалося цікавим.

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

Outputs 0\n (literal newline) for truthy, the empty string for falsy.

The idea is to count down from input by consecutive numbers, 1 at a time. E.g. input - (1) - (1,1) - (1,1,1). Each time we subtract, if we aren't at 0 yet, we leave an extra value on the stack. That way, if we are at 0 and are still subtracting when we pop we remove the last value on the stack. If the input was a triangular number, we will end exactly at 0, and wont pop the 0.

Try it online! truthy
Try it online! falsy

# 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

Jelly, 5 bytes

×8‘Ʋ

Try it online!

Background

Let n be the input. If n is the kth triangular number, we have

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

which means there will be a natural solution if and only if 1 + 8n is an odd, perfect square. Clearly, checking the parity of 1 + 8n is not required.

How it works

×8‘Ʋ  Main link. Argument: n

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


5

Brain-Flak, 42 bytes

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

Try it online!

Explanation

The goal of this program is to create a state on two stacks and perform constant operation on both stacks until one of them zeros, we can then output depending on which stack we are on. This is similar to programs that determine the sign of a number. These programs put n on one stack and -n on the other and add one and switch stacks until one of the stacks is zero. If the number was negative in the first place the first stack will hit zero, if the number was positive the other stack will hit zero.

Here we create two stacks one that subtracts consecutive numbers from the input and one that just subtracts one. The one that subtracts consecutive numbers will only terminate if the number is triangular, (other wise it will just pass zero and keep going into the negatives). The other one will always terminate for any positive number, but will always do so slower than the first, thus non-triangular numbers will terminate on that stack.

So how do we set up stacks so that the same operation subtracts consecutive numbers on one and subtracts one on the other? On each stack we have the input on top so that in can be checked, below that we have the difference and below that we have the difference of the difference. Each time we run we add the "difference of the difference" to the regular "difference" and subtract that from the input. For the stack that checks for triangularity we set our double difference to be 1 so that we get consecutive integers each time we run, for the other stack we set it to 0 so that we never change the difference, that is it always stays 1. Here is how the stack is set up at the beginning, where n is the input:

-n  -n
 0   1
 1   0

When we finally do terminate we can use these differences to check which stack we are on we pop the top two values and we get 1 for a triangular number and 0 for a non-triangular number.


Annotated code

(([{}](<((())<>)>))<>) 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

Here's a 50 byte solution I like as well.

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

Try it online!


5

Cubix, 23 24 25 bytes

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

0 for truthy and nothing 0 for falsey. Brutes forces by incrementing counter, adding to cumulative sum and comparing to input. Now to try and fit it on a 2x2x2 cube. Did it!

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

Try it online!

  • / Reflect to to face.
  • I10\ get integer input, push 1 (counter), push 0 (sum) and reflect
  • +s;p- loop body. Add sum and counter, drop previous sum, raise input and subtract
  • ? Test the result of the subtraction
    • For 0 result carrying on straight ahead \.uO@ reflect to bottom face, no-op, U-turn, output and halt.
    • For positive result turn right onto bottom face and @ halt
    • For negative result turn left ;qWs)/su drop subtraction, put input to bottom, shift left, swap counter and sum, increment counter, reflect, swap sum and counter, U-turn onto main loop body.

So tantalizingly close... that last byte is going to take a lot of effort and cleverness though.
ETHproductions

Yep, thought I had it but is being elusive
MickyT

1
@ETHproductions found the byte
MickyT

Your code and your unfolded cube appear to be different, the lower right corner is a . on the cube but a 1 in your code.
Wheat Wizard

@WheatWizard Thanks for that, bad editing on my part
MickyT

4

05AB1E, 7 6 bytes

EDIT: Thanks to @Dennis: Saved a byte because I forgot about the increment operator

8*>t.ï

Try it online!

n is triangular if sqrt(8n + 1) is an integer

How it works

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

Probably wasn't available yet at the time, but t.ï can be Ų these days, which is a builtin to check if a number is a square.
Kevin Cruijssen

4

Perl 6, 17 bytes

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

Just checks whether $_, the input to the function, is equal to any of the elements of the triangular addition reduction (1, 1+2, ..., 1+2+...+$_).


4

Alice, 38 22 bytes

A lot of bytes saved thanks to Martin and Leo

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

There is a trailing newline. Outputs 1 for triangular, 0 otherwise.

Try it online!

Explanation

This uses the same approach as my CJam answer, only clumsier. In linearized form, the program becomes

i2*.2RE.h*-no@

where the i and o are actually in ordinal mode.

Consider input 21 as an example.

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

My first Alice answer
Luis Mendo

1
I have a feeling this could be roughly halved with one of Martin's fancy control structures...
ETHproductions

So do I ... :-)
Luis Mendo

My first Alice golf: Same code, 23 bytes
Nitrodon

A more "standard" layout for this kind of program would be this. That said, you could get rid of the 1 on the stack, and simply output the logical negation of the subtraction (i.e. ...h*-no@)
Leo

4

Japt, 10 7 bytes

Saved 3 bytes thanks to @Luke and @ETHproductions

*8Ä ¬v1

Try it online!

Explanation:

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

õ å+ øU

Explanation:

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

Try it online!


The question asks for two constant distinct ouputs.
xnor

*8Ä ¬u1 c for 9B (outputs 0 if input is triangular, 1 otherwise)
Luke

@Luke You could change u1 c to v1, I believe (switching the outputs)
ETHproductions

7 bytes? Nice! Somehow missed this while posting my own, similar solution late last might. Let me know if you'd like me to delete it.
Shaggy

4

R, 23 19 bytes

Similar approach as other answers. Checks to see if 8x+1 is a perfect square.
-4 bytes thanks Giuseppe and MickyT.

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

Try it online!


2
you can use ! instead of ==0
Giuseppe

This is extra nice since it's vectorized, too!
Giuseppe

1
I think you can get rid of the exterior brackets as well !(8*scan()+1)^.5%%1
MickyT

3

MATL, 5 bytes

t:Ysm

Try it online!

Explanation:

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

I was going to post t:Ys=a. Forgot about m :-)
Luis Mendo

1
@LuisMendo I didn't know about m until I saw this answer. Funny how the two answer are almost identical :D
DJMcMayhem

3

Batch, 72 bytes

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

Outputs 1 on success, nothing on failure. Works for zero too, although not requested by the question for some reason.


3

JavaScript (ES7), 19 18 bytes

From my answer to a related question.

Outputs false for triangular numbers or true for non-triangular, as permitted by the OP.

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

Try It

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


I think you could save a byte with n=>(8*n+1)**.5%1>0 (which would reverse the outputs)
ETHproductions

@ETHproductions: OK, as long as you're allowing it. Is doing so normally permitted, though?
Shaggy

1
It qualifies as "two constant, distinct outputs", so yes. Other decision-problem challenges may require truthy/falsy though.
ETHproductions


3

Mathematica, 28 bytes

!Accumulate@Range@#~FreeQ~#&

I recommend replacing 7! by #. First, it's shorter; more importantly, the current solution is not correct, as it artificially imposes a limit on the size of the input it works on.
Greg Martin

1
OP says: "You may assume that the input is a positive integer under 10^6".But I like your idea and I will take it ,although mine gives the right result for every case using a list of 5040 elements but yours worst case needs a list of 999999 elements.Thanks for the tip!
J42161217

1
Oops sorry, didn't see the OP's comment! Yes, there are some "perverse" incentives in code golfing: that 1-byte savings is more important in a code-golf question than all the efficiency in the world :)
Greg Martin


3

Excel, 31 22 bytes

9 bytes saved thanks to Octopus

Outputs TRUE for triangular numbers. Else FALSE. Checks if 8*n+1 is a perfect square.

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

1
=MOD(SQRT(8*A1+1),1)=0 saves a few bytes
Octopus

2

Brachylog, 5 bytes

≥ℕ⟦+?

Try it online!

Explanation

≥ℕ⟦+?
≥ℕ     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

Note: I know that the other two Python answers are much shorter, but this is the old-school way, more of a by-hand algorithm

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

2

APL (Dyalog), 6 bytes

⊢∊+\∘

Try it online!

Explanation

⊢∊+\∘
                       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

Outputs 0 for false and 1 for true.


Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.