Bu sayı üçgen mi?


33

Meydan okuma

Pozitif bir tamsayı verildiğinde, bunun üçgen bir sayı olup olmadığını belirleyin ve buna göre herhangi iki sabit, farklı değerden birini verin.

Tanım

Bir üçgen sayıda Bunlar ayrıca, formül ile ifade edilebilir 1'den başlayarak, birbirini takip eden pozitif tamsayı toplamı olarak ifade edilebilir bir sayıdır n(n + 1) / 2, nbir pozitif tamsayıdır.

Test durumları

Truthy:

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

kurallar

  • Girişiniz bir işlev veya program olabilir.
  • Girişin 10'un altındaki pozitif bir tamsayı olduğunu varsayabilirsiniz. 6'nın .
  • İki kategoriyi ayırt etmek için iki sabit, ayrı çıktı seçmelisiniz.

Bu , yani her dilde bayt cinsinden en kısa kod kazanır.





Neden sıfır eklemedin?
Neil,

1
@Neil Olası kenar davalarının sayısını en aza indirmek istedim ve sıfırı kullanmak çok önemli olmadığını düşündüğümden biriydi. Sıfırın kullanılması gerekiyorsa daha iyi olacağını mı düşünüyorsunuz? (Örneğin, Jelly yanıtı şu anda sıfırda başarısız oluyor)
ETHproductions

Yanıtlar:


21

Haskell , 23 bayt

DÜZENLE:

  • -1 bayt: @ xnor, a ile parantezlerden kurtuldu $.

Anonim bir işlev alan Intve dönen bir a Char.

Çıktı '1'üçgen sayılar ve '0'diğerleri içindir.

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

Çevrimiçi deneyin!

  • Olarak kullanın ((!!)$show.(10^)=<<[0..]) 998991.
  • 1, 10, 100, 1000, ... sayılarını üretir, bunları dizelere dönüştürür ve birleştirir. Sonra ortaya çıkan sonsuz dizeye endeksler

    "1101001000100001000001000000...

6
Yaratıcı bir yöntem! İle bir bayt kaydedebilirsiniz (!!)$show.(10^)=<<[0..].
xnor

20

Python , 24 bayt

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

Çevrimiçi deneyin!

Diğerleri Falseiçin üçgen sayılar için çıktılar True. 8*n+1Mükemmel bir kare olup olmadığını kontrol eder . Python, ne kadar büyük olursa olsun, tam sayıdaki tam yüzer için mükemmel kareler alır, bu nedenle kayan nokta sorunları yoktur.


3
(1<<10000)**.5: OverflowError: int
float'a

@isaacg Zorluk şu kadar büyük girdiler gerektirmiyor: "
Girdinin

1
@trichoplax Ben xnor'ın metindeki iddiasına itiraz ediyorum. Gönderme iyi, katılıyorum.
isaacg

13

Jöle , 4 bayt

R+\ċ

Çevrimiçi deneyin!

Nasıl?

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

Kümülatif azaltmanın otomatik olarak bir aralık oluşturmamasına şaşırdım. Bunun arkasında bir tasarım seçimi var mı?
ETHProductions

% 100 emin değilim, ancak (en azından şu anda) dyadiç operasyonunun düşürülmesine ihtiyaç duyulacağının bir aralığın yapılmasına neden olacağını düşünüyorum.
Jonathan Allan

... aslında hatta mesela (uygulamak görünmüyor bu vs bu . O diyadik operasyon tanımlar bir argüman için bunu bile iterable bir dizi yapmaz böyle uicklink uygulama geçersiz kılmaları görünüyor. pinglenecek Dennis alanına bu bir :)
Jonathan Allan

@ETProductions /ve \muhtemelen uygulanacak ilk beş hızlı program arasında yer aldı;
Dennis,

13

Retina , 10 bayt

(^1|1\1)+$

Giriş bir arada. Çıktı 0veya 1.

Çevrimiçi deneyin! (Kolaylık sağlamak için ondalık birime dönüşüm yapan bir test paketi olarak.)

açıklama

Bu ileri referanslardaki en temel alıştırmadır. Çoğu insan regex'deki geri referansları bilir; örneğin(.)\1 tekrarlanan bir karakterle eşleşmek için. Bununla birlikte, daha gelişmiş lezzetlerin bazıları, atıfta bulunduğu gruptan önce veya içinde geri dönüş kullanmanıza izin verir. Bu durumda, genellikle bir ileri referans denir. Referans tekrarlanırsa bu anlamlı olabilir. İlk yinelemede iyi tanımlanmamış olabilir, ancak sonraki yinelemelerde daha sonraki veya çevreleyen grup bir şey yakalamış ve yeniden kullanılabilir.

Bu en yaygın olarak, tekli dizgelerde yinelenen kalıpları uygulamak için kullanılır. Bu durumda, girişi ardışık tam sayıların toplamı olarak eşleştirmeye çalışırız:

(        # 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
Neden değil (^|1\1)+$çalışıyor?
Sızdıran Rahibe

3
@LeakyNun regex motorları, n kullandığınız miktar belirleyicinin minimum olduğu n kez boşsa, bir grubu tekrar etmeyi durduracakları bir optimizasyona sahiptir (durum 1; minimum 0 ise, yine de denenir) . Eğer değiştirirseniz için , bu çalışması gerekir. Bu optimizasyon sonsuz döngüleri önler ancak aynı zamanda .NET regex'in kendi başına Turing-complete olmasını engelleyen tek şeydir. +{2,}
Martin Ender

Bu sadece bana 70 bayt kaydedildi codegolf.stackexchange.com/a/118387
Neil

74 bayt olun, teşekkürler \G!
Neil


8

Mathematica, 16 bayt

OddQ@Sqrt[1+8#]&

Temelde bir xnor'ın Python çözümü limanı . Aksi takdirde Trueüçgen sayılar için çıktılar False.


7

JavaScript (ES6), 30 27 bayt

Kamoroso94 sayesinde 2 bayt kaydedildi

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

Test durumları

Özyinelemeli olmayan sürüm (ES7), 19 bayt

Adnan Limanı'nın cevabını .

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

Sadece benimkileri göndermeden birkaç dakika önce 19 baytlık çözümü sizin cevabınıza düzenlediğinizi görmek . Benimkini silmeli miyim? Bu konuda genel kabul görmüş görgü kuralları nedir?
Shaggy

1
@Shaggy Burada gerçek bir sorun olduğunu sanmıyorum. Benim 'ana' cevabım özyinelemeli cevap.
Arnauld

28 byte ile azaltılsın f=(n,k=1)=>n>0?f(n-k,k+1):!nmı?
kamoroso94

1
@ kamoroso94 Teşekkürler! Güncellenmiş. Ve üçüncü bir bayt, ilklendirmenin atlanması ile kurtarıldı k.
Arnauld

Başlangıçta bir undefineddeğer için artırıcı olarak bitsel olmayan zarif kullanım ; Düzenlemeniz, önceki çözümünüze bağımsız olarak ulaştıktan sonra okumak için bir zevkti.
apsillers

6

CJam , 11 bayt

ri2*_mQ_)*=

Aksi takdirde 1üçgen için çıkışlar 0.

Çevrimiçi deneyin!

açıklama

Girişi düşünün 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

Beyin Flak , 40 bayt

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

Buğday Sihirbazı ve ben bir düello vardı bu . Çözümlerimizi göndermeye karar verdiğimizde 42 bayta bağlandık, ancak çözümünün 2 baytlık bir golfünü buldum. Bunun kravat kırıcı olarak sayılmasına karar verdik (çözümüm aşağıdadır).

Çevrimiçi deneyin!

Açıklama:

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

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

Tam bir açıklama için lütfen Buğday Sihirbazı'nın cevabına bakınız .


Brain-Flak , 42 bayt

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

0\nHakikat için çıktılar (değişmez yeni satır) ve sahte için boş dize.

Buradaki fikir, girişe kadar önce 1 sonra 2 sonra 3 çıkartmaktır. 0'a basarsanız, bunun üçgen bir sayı olduğunu bilirsiniz, böylece burada durabilirsiniz.

Çevrimiçi deneyin! (truthy)
Çevrimiçi deneyin! (falsy)

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

İşte ilginç bulduğum 46 baytlık bir çözüm.

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

0\nGerçeklik için çıktılar (değişmez yeni satır), sahte için boş dize.

Buradaki fikir, girişten ardışık sayılarla her defasında 1 geri saymaktır. Örneğininput - (1) - (1,1) - (1,1,1) . Her çıkarttığımızda, eğer henüz 0'da değilsek, yığında ekstra bir değer bırakırız. Bu şekilde, eğer 0'daysak ve pop açıldığında hala çıkarılıyorsa, yığındaki son değeri kaldırırız. Girdi üçgen bir sayıysa, tam olarak 0'da biteceğiz ve 0'ı açmayacağız.

Çevrimiçi deneyin! truthy
Çevrimiçi deneyin! 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

Jöle , 5 bayt

×8‘Ʋ

Çevrimiçi deneyin!

Arka fon

Let n girilebilir. Eğer n ise k inci üçgen sayı, elimizdeki

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

bu, eğer sadece 1 + 8n tek, mükemmel bir kare ise doğal bir çözüm olacaktır . Açıkça, 1 + 8n paritesinin kontrol edilmesi gerekli değildir.

Nasıl çalışır

×8‘Ʋ  Main link. Argument: n

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

5

PowerShell , 31 30 bayt

"$args"-in(1..1e6|%{($s+=$_)})

Çevrimiçi deneyin!

Güzel ve yavaş kaba kuvvet yöntemi. 1 ile 10 6 arasında her toplamdan bir dizi yapın ve argümanın orada olup olmadığını görün.


5

Brain-Flak , 42 bayt

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

Çevrimiçi deneyin!

açıklama

Bu programın amacı, iki yığında bir durum yaratmak ve her iki yığında da sürekli bir işlem yapmak ve bunlardan biri sıfır olunca, hangi yığında olduğumuza bağlı olarak çıktı verebiliyoruz. Bu, bir sayının işaretini belirleyen programlara benzer. Bu programlar nbir yığına koymak ve-n ekler ve yığınlardan biri sıfır olana kadar yığınları değiştirir. İlk etapta sayı negatifse, ilk yığın sıfıra varacaktır, sayı pozitif ise diğer yığın sıfıra varacaktır.

Burada, girişten ardışık sayıları çıkaran ve yalnızca birini çıkaran iki yığın oluştururuz. Ardışık sayıları çıkaran sayı, yalnızca sayı üçgense sona erer, (aksi takdirde sadece sıfıra geçecek ve negatiflere devam edecektir). Diğeri her zaman pozitif bir sayı için sonlanır, ancak her zaman ilkinden daha yavaş olur, böylece üçgen olmayan sayılar o yığında sona erer.

Öyleyse yığınları nasıl ayarlıyoruz ki aynı işlem birinden ardışık sayıları ve diğerini de çıkarıyor? Her bir yığında girdiler üsttedir, böylece kontrol edilebilir, altında fark var ve altında fark var. Çalıştığımız her seferde "farkın farkı" nı normal "fark" a ekliyoruz ve bunu girdiden çıkartıyoruz. Üçgenliği kontrol eden yığın için, çifte farkımızı, 1her çalıştırmamızda ardışık tamsayıları alacağımız şekilde, diğer yığın için 0ise farkı asla değiştirmeyecek şekilde ayarladık , yani her zaman 1 kalacaktır. yığın başlangıçta nasıl kurulur n, girdi nerededir:

-n  -n
 0   1
 1   0

Nihayet sonlandırdığımızda, bu yığları hangi yığında olduğumuzu kontrol etmek için kullanabiliriz, ilk iki değeri alırız ve 1üçgen bir sayı ve 0üçgen olmayan bir sayı alırız .


Açıklamalı kod

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

İşte benim de sevdiğim 50 baytlık bir çözüm.

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

Çevrimiçi deneyin!


5

Cubix , 23 24 25 bayt

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

Truthy için 0 ve falsey için 0 değil . Kuvvetleri, sayacı artırarak, toplam tutara ekleyerek ve girdiyle karşılaştırarak kuvvetlendirir. Şimdi denemek ve 2x2x2 küp üzerinde sığdırmak için. Yaptı!

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

Çevrimiçi deneyin!

  • / Yüzleşmeyi reddetmek.
  • I10\ tamsayı girişini al, 1 (sayıcı), 0 (toplam) bas ve yansıt
  • +s;p-döngü gövdesi. Toplamı ve sayacı ekle, önceki toplamı düşür, girişi arttır ve çıkar
  • ? Çıkarma sonucunu test edin
    • Dümdüz ileride devam eden 0 sonuç \.uO@için alt yüze, operasyon yok, U dönüşü, çıkış ve durma yansımış.
    • Olumlu sonuç için alt yüze sağa dönün ve @durun
    • Negatif sonuç için sola ;qWs)/subırakma çıkarma, girişi aşağıya koyma, sola kaydırma, sayaç ve toplamı değiştirme, artış sayacı, yansıtma, toplamı ve sayacı değiştirme, ana döngü gövdesine U dönüşü.

Öylesine titizlikle yakın ... bu son bayt yine de çok çaba ve zahmete girecek.
ETHProductions

Evet, sahip olduğumu sanıyordum ama
zorlanıyor

1
@ETHproductions byte buldu
MickyT

Kodunuz ve katlanmamış küpünüz farklı görünüyor, sağ alt köşe .küpte bir 1, ancak kodunuzda bir.
Buğday Sihirbazı,

@WheatWizard Bunun için teşekkürler, benim
tarafımdan

4

05AB1E , 7 6 bayt

EDIT : @Dennis sayesinde: Bir bayt kaydedildi, çünkü artış işlecini unuttum

8*>t.ï

Çevrimiçi deneyin!

nsqrt(8n + 1)bir tamsayı ise üçgen

Nasıl çalışır

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

Muhtemelen anda henüz mevcut değildi, ama t.ïolabilir ŲBir sayının kare olup olmadığını kontrol etmek için bir yerleşiği olan bu gün.
Kevin Cruijssen

4

Perl 6 , 17 bayt

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

Sadece $_, fonksiyona yapılan girişin, üçgen ekleme azaltma öğelerinin herhangi birine eşit olup olmadığını kontrol eder (1, 1+2, ..., 1+2+...+$_).


4

Alice , 38 22 bayt

Martin ve Leo sayesinde çok sayıda bayt kurtarıldı

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

Sonunda yeni bir satır var. Aksi takdirde 1üçgen için çıkışlar 0.

Çevrimiçi deneyin!

açıklama

Bu benim CJam cevabım ile aynı yaklaşımı kullanır , sadece sakar. Doğrusallaştırılmış biçimde, program olur

i2*.2RE.h*-no@

nerede iveo sıra modunda aslında.

21Bir örnek olarak girişi düşünün .

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

İlk Alice cevabım
Luis Mendo

1
Martin'in fantezi kontrol yapılarından biriyle kabaca yarıya
inebileceğini hissediyorum

Yani ben ... :-)
Luis Mendo

İlk Alice
golfüm

Programın bu tür için daha "standart" düzen olurdu bu . Yani (yani yığın 1 kurtulmak ve çıkarma basitçe çıkış mantıksal olumsuzluk olabilir dedi ...h*-no@)
Leo

4

Japt , 10 7 bayt

@Luke ve @ETHproductions sayesinde 3 bayt kurtarıldı

*8Ä ¬v1

Çevrimiçi deneyin!

Açıklama:

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

õ å+ øU

Açıklama:

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

Çevrimiçi deneyin!


Soru, iki sabit ayrı çıkış için sorar.
xnor

*8Ä ¬u1 c9B için (giriş üçgense 0 çıkış, aksi takdirde 1)
Luke,

Sen değişebilir @Luke u1 ciçin v1, inanıyorum (çıkışları anahtarlama)
ETHproductions

7 bayt? Güzel! Her nasılsa, son belki de kendi çözümümüzü gönderirken bunu kaçırdım. Silmemi istersen haberim olsun.
Shaggy

4

R , 23 19 bayt

Diğer cevaplar ile benzer bir yaklaşım. 8x+1Mükemmel bir kare olup olmadığını kontrol eder .
-4 bayt Giuseppe ve MickyT teşekkürler.

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

Çevrimiçi deneyin!


2
!yerine kullanabilirsiniz==0
Giuseppe

Bu da vektörleştirildiğinden beri çok güzel!
Giuseppe,

1
Sanırım dış parantezlerden de kurtulabilirsiniz!(8*scan()+1)^.5%%1
MickyT

3

MATL , 5 bayt

t:Ysm

Çevrimiçi deneyin!

Açıklama:

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

Mesaj gönderecektim t:Ys=a. Unuttum 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.


Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.