この数字は三角形ですか?


33

チャレンジ

正の整数を指定して、それが三角数かどうかを判断し、それに応じて任意の2つの定数の異なる値のいずれかを出力します。

定義

三角形の数は、それらはまた、式で表すことができる1から始まる、連続する正の整数の和として表すことができる数でありn(n + 1) / 2nいくつかの正の整数です。

テストケース

真実:

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未満の正の整数であると仮定できます。
  • 2つのカテゴリを区別するには、2つの一定の異なる出力を選択する必要があります。

これはであるため、各言語のバイト単位の最短コードが優先されます。





なぜゼロを含めなかったのですか?
ニール

1
@Neil可能なエッジケースの数を最小限にしたかったのですが、ゼロの処理は重要ではないと感じたものの1つです。ゼロを処理する必要があるとしたらもっと良かったと思いますか?(ゼリーの答えは現在、例えば、ゼロで失敗)
ETHproductions

回答:


21

Haskell、23バイト

編集:

  • -1バイト:@xnorはで括弧を削除しました$

を受け取り、Intを返す匿名関数Char

出力は'1'、三角形の数値および'0'その他の数値です。

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

オンラインでお試しください!

  • として使用し((!!)$show.(10^)=<<[0..]) 998991ます。
  • 数字1、10、100、1000、...を生成し、それらを文字列に変換し、連結します。次に、結果の無限文字列にインデックスを付けます

    "1101001000100001000001000000...

6
想像力豊かな方法!でバイトを保存できます(!!)$show.(10^)=<<[0..]
-xnor

20

Python、24バイト

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

オンラインでお試しください!

残りのFalse三角数の出力True。確認する8*n+1が完全な正方形ます。Pythonは、どんなに大きくても、整数の浮動小数点数を正確に求めるために完全な二乗を使用するため、浮動小数点の問題はありません。


3
(1<<10000)**.5:OverflowError:floatに変換するには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は/\おそらく実装される最初の5つのクイックのうちの1つであり、整数引数を範囲にキャストするというアイデアに先行していました。
デニス

13

網膜、10バイト

(^1|1\1)+$

入力は単項です。出力は0または1です。

オンラインでお試しください!(便宜上、10進数から単進数への変換を行うテストスイートとして。)

説明

これは、前方参照の最も基本的な演習です。ほとんどの人は正規表現の後方参照に精通しています。例えば(.)\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正規表現エンジンは、それが空であった場合、彼らはグループを繰り返し停止することを最適化していのnどこ回nはあなたがしている使用して数量詞の最小値である(1、あなたのケースでは、最小値が0だった場合、それはとにかく、一度試されることになります) 。+to を変更すると{2,}、動作するはずです。この最適化により、無限ループが防止されますが、.NET正規表現が単独でチューリング完全にならないようにする唯一の方法でもあります。
マーティンエンダー

これでちょうど70バイト節約できました:codegolf.stackexchange.com/a/118387
ニール

おかげで74バイトになりました\G
ニール



7

JavaScript(ES6)、30 27バイト

kamoroso94のおかげで2バイト節約

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

テストケース

非再帰バージョン(ES7)、19バイト

アドナンの回答

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

私だけが掲載数分前に、あなたの答えに19バイトのソリューションを編集したことを今見鉱山。私を削除する必要がありますか?一般的に受け入れられているエチケットは何ですか?
シャギー

1
@Shaggyここでは本当の問題だとは思わない。私の「主な」答えは本当に再帰的なものです。
アルノー

f=(n,k=1)=>n>0?f(n-k,k+1):!n?で28バイトに減らす
kamoroso94

1
@ kamoroso94ありがとう!更新しました。また、の初期化を省略することで3番目のバイトが保存されましたk
アーナルド

初期undefined値のインクリメンターとしてのビット単位NOTのエレガントな使用。あなたの編集は、私があなたの前の解決策にたどり着いた後、読むのが楽しみでした。
-apsillers

6

CJam、11バイト

ri2*_mQ_)*=

それ以外の場合1、三角形の出力0

オンラインでお試しください!

説明

入力を検討してください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バイト

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

小麦ウィザードと私は決闘しましたこの質問についてしました。ソリューションの投稿を決めたとき、42バイトに縛られていましたが、彼のソリューションの2バイトのゴルフを見つけました。タイブレーカーとしてカウントすることにしました(私の解決策は以下です)。

オンラインでお試しください!

説明:

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

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

詳細な説明については、ウィートウィザードの回答を参照してください。


Brain-Flak、42バイト

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

0\n真偽の場合は出力(リテラル改行)、偽の場合は空の文字列。

アイデアは、入力を1から2、次に3を差し引くことです。0をヒットした場合、これは三角の数字であることがわかるので、そこで停止できます。

オンラインでお試しください!(真実)
オンラインで試してみてください!(偽)

# 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バイトのソリューションがあります。

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

出力 0\ntruthyの(リテラル改行)、falsyの空の文字列。

アイデアは、入力から連続して1つずつカウントダウンすることです。例えばinput - (1) - (1,1) - (1,1,1)。減算するたびに、まだ0になっていない場合は、スタックに追加の値を残します。そのようにして、0にあり、ポップしたときにまだ減算している場合、スタックの最後の値を削除します。入力が三角形の数であった場合、正確に0で終了し、0をポップしません。

オンラインでお試しください!真実
オンラインで試してみてください!偽物

# 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

ゼリー、5バイト

×8‘Ʋ

オンラインでお試しください!

バックグラウンド

してみましょうnは入力すること。場合は、nがあるのk 番目の三角数、我々は持っています

n=kk+12k2+k2n=0k=121±1+8n

つまり、1 + 8nが奇数の完全な正方形である場合にのみ、自然な解が存在します。明らかに、1 + 8nのパリティをチェックする必要はありません。

使い方

×8‘Ʋ  Main link. Argument: n

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


5

Brain-Flak、42バイト

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

オンラインでお試しください!

説明

このプログラムの目的は、2つのスタックに状態を作成し、両方のスタックのいずれかがゼロになるまで一定の操作を実行することです。その後、現在のスタックに応じて出力できます。これは、数値の符号を決定するプログラムに似ています。これらのプログラムはn1つのスタックに配置され、-nを追加して、スタックの1つがゼロになるまでスタックを切り替えます。最初の数が負の場合、最初のスタックはゼロにヒットし、数が正の場合、他のスタックはゼロにヒットします。

ここでは、入力から連続した数値を減算するスタックと、単に1を減算するスタックの2つのスタックを作成します。連続した数字を減算するものは、数字が三角形の場合にのみ終了します(そうでない場合は、単にゼロを渡して負の値に進みます)。もう一方は常に正の数で終了しますが、常に最初よりも遅くなります。したがって、非三角形の数はそのスタックで終了します。

では、同じ操作で一方の連続番号を減算し、もう一方の連続番号を減算するようにスタックを設定するにはどうすればよいですか?各スタックでは、入力をチェックできるように、入力が上にあり、その下に差があり、下に差の差があります。実行するたびに、「差の差」を通常の「差」に追加し、それを入力から減算します。三角形性をチェックするスタックでは、1実行するたびに連続する整数を取得するように二重の差を設定し、他のスタックでは0差を変更しないように設定します。つまり、常に1のままです。スタックが最初にどのように設定されるか、n入力は次のとおりです。

-n  -n
 0   1
 1   0

最終的に終了するとき、これらの違いを使用して、現在のスタックをチェックして、上位2つの値をポップ1し、三角形の数と0非三角形の数を取得します。


注釈付きコード

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

私も好きな50バイトのソリューションがあります。

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

オンラインでお試しください!


5

Cubix、23 24 25バイト

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

真実の場合は0、偽の場合は0。カウンターをインクリメントし、累積合計に加算し、入力と比較することにより、ブルートは強制します。 次に、2x2x2キューブに試してみます。それをやった!

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

オンラインでお試しください!

  • / 顔に反射します。
  • 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.


弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.