Üç üçgen sayı [kapalı]


19

Açıklama

Daha önce bu sayılarla ilgili başka birkaç zorluk daha vardı ve umarım bu onların arasında değildir.

N üçgen sayı inci kadar tüm doğal sayıların toplamına eşittir n , basit şeyler. Kendilerini daha fazla bilgilendirmek isteyenler için bir wikipedia sayfası ve OEIS'te bir giriş var .

Şimdi Gauss, her doğal sayının üç üçgen sayının (bunlar dahil 0) toplamı olarak ifade edilebildiğini keşfetti ve örneğin bir kereden fazla bir sayıya sahip olmanın iyi olduğunu, örneğin 0 + 1 + 1 = 2.

Meydan okuma

Göreviniz, doğal bir sayı (dahil 0) verildiğinde, bir argümanı özetleyen üç üçgen sayı yazdırmak üzere bir program veya işlev yazmaktır . Boşluklarla ayrılmış sayıları dizi olarak veya istediğiniz başka bir yöntemle yazdırabilirsiniz. Bununla birlikte, bir dizi, bir aralık veya üçgen sayıların bir listesini içeren (örneğin, aralığı veren tek bir atom) bir dizi, bir aralık veya başka bir toplama şekli elde etmek için herhangi bir yerleşik işlevi kullanmak yasaktır .

Test senaryoları

9 -> 6 + 3 + 0 or 3 + 3 + 3
12 -> 6 + 6 + 0 or 6 + 3 + 3 or 10 + 1 + 1
13 -> 6 + 6 + 1
1 -> 1 + 0 + 0
0 -> 0 + 0 + 0

Not: Birden fazla olası kombinasyon varsa, herhangi birini veya tümünü yazdırabilirsiniz, ancak diğer kombinasyonları yeniden düzenlemenin sonucu olan tüm kombinasyonları ortadan kaldırarak herhangi bir kombinasyonu yalnızca bir kez yazdırmanız gerekir. Gerçekten bir denemek bağlantı ve bir açıklama takdir ediyorum, gerçekten sorunu nasıl çözdüğünü görmek için seviyorum;)

Bu , bu nedenle standart boşluklar geçerlidir. Bayttaki en kısa cevap kazanabilir!


1
12 için 1 + 1 + 10 da yapabilirsiniz.
Outgolfer Erik

1
@steenbergh aher zaman üçgen bir sayı olmayacak
Felipe Nardi Batista

3
" Bir dizi, bir aralık veya üçgen sayıların listesini içeren herhangi bir koleksiyon " almak için yerleşik işlevleri iki şekilde ayrıştırabilirim , ancak ikisi de mantıklı değil. Birincisi, doğrudan bir dizi alan tüm yerleşikleri yasaklar, ancak bu, bildiğim her dilde dizilerin tüm kullanımını yasaklıyor gibi görünüyor; Diğeri, yerleşiklerin " doğrudan ... bir üçgen sayı listesi içeren bir aralık almasını " yasaklar , ancak bunun ne anlama geldiğini bilmiyorum.
Peter Taylor

2
Yani yerleşik bir argüman alan işlevler nve birinci listesini döndürür nüçgen sayılar edilir izin? Hangisini bilmiyorum, ancak bu belirli bir dile karşı oldukça hedeflenmiş hissettiriyor.
Peter Taylor

4
Sizden bu kısıtlamayı kaldırmanızı tavsiye ediyorum. Söz veriyorum, diller arası cevap kalitesini veya adaletini düşündüğünüz şekilde geliştirmeyecektir.
Lynn

Yanıtlar:


8

05AB1E , 10 bayt

Kod:

ÝηO3ãʒOQ}¬

Açıklama:

Ý             # Compute the range [0 .. input]
 η            # Get the prefixes
  O           # Sum each prefix to get the triangle numbers
   3ã         # Cartesian repeat 3 times
     ʒ  }     # Keep elements that
      OQ      #   have the same sum as the input
         ¬    # Retrieve the first element

05AB1E kodlamasını kullanır . Çevrimiçi deneyin!


Ahhh ... Evet; yapardı.
Sihirli Ahtapot Urn

7

Python 2 , 99 bayt

from random import*
n=input()
while 1:b=sample([a*-~a/2for a in range(n+1)]*3,3);n-sum(b)or exit(b)

Çevrimiçi deneyin!

Bu daha kısa itertoolsveya üçlü bir liste anlama oldukça şaşırdım ! (Sonunda) her çalıştırdığınızda rastgele bir cevap verir.

İki 102:

n=input();r=[a*-~a/2for a in range(n+1)];print[(a,b,c)for a in r for b in r for c in r if a+b+c==n][0]
def f(n):r=[a*-~a/2for a in range(n+1)];return[(a,b,c)for a in r for b in r for c in r if a+b+c==n][0]

itertools 106 gibi görünüyor:

from itertools import*;lambda n:[x for x in product([a*-~a/2for a in range(n+1)],repeat=3)if sum(x)==n][0]

Rastgele çıktı için +1. :) Ayrıca (şimdiye kadar) en kısa çözümü veren şaşırdım.
Kevin Cruijssen

Yöntem için çok teşekkür ederim. Karşılık gelen Ruby kodunda 57 bayt vardır.
Eric Duminil


3

Brachylog , 13 bayt

⟦⟦ᵐ+ᵐj₃⊇Ṫ.+?∧

Çevrimiçi deneyin!

Nasıl çalışır

⟦⟦ᵐ+ᵐj₃⊇Ṫ.+?∧  input: n
⟦              [0 1 ... n]
 ⟦ᵐ            [[0] [0 1] [0 1 2] ... [0 1 ... n]]
   +ᵐ          [0 1 3 ... n(n+1)/2]
     j₃        [0 1 3 ... n(n+1)/2 0 1 3 ... n(n+1)/2 0 1 3 ... n(n+1)/2]
       ⊇       is a superset of
        Ṫ      a list of three elements 
         .     which is the output
          +?   which sums up to be the input

2

MATL , 18 bayt

Q:qYs3Z^t!sG=fX<Y)

Bu, sözcük sonucunun ilk sonucunu verir.

MATL Online'da deneyin !

açıklama

Q     % Implicitly input n. Add 1
:     % Range (inclusive, 1-based): gives [1 2 ... n+1]
q     % Subtract 1 (element-wise): gives [0 1 ... n]
Ys    % Cumulative sum
3Z^   % Cartesian power with exponent 3. Gives a matrix where each row is a
      % Cartesian tuple
t     % Duplicate
!s    % Sum of each row
G=    % Does each entry equal the input?
f     % Find indices that satisfy that condition
X<    % Minimum
Y)    % Use as row index into the Cartesian power matrix. Implicitly display

2

Haskell, 66 59 bayt

Tüm çözümlerin çıktısına izin verdiğiniz için teşekkürler, bu dikkat dağıtıcı! Bir çözümü çıkarmamıza ve izin verilen çözümlerden kaçınmanın maliyetini fark etmediğim her şeyi verebilmem için çok mutluydum. @ Lynn'in sözleri bunu bana açıkladı ve 7 byte tasarruf edeyim.

f n|l<-scanl(+)0[1..n]=[(a,b,c)|c<-l,b<-l,a<-l,a+b+c==n]!!0

Bu, ltüm kombinasyonlara fazlasıyla üçgen sayı bağlar ve denetler.


Koşulları düşürmek a>=b,b>=cve sadece !!0kodunuza sonek vermek geçerli bir cevap değil mi? Tüm çözümlerin çıktıları burada size gerçekten yardımcı olmaz.
Lynn

@Lynn Elbette haklısın, dikkatim dağıldı. Teşekkürler!
Christian Sievers

2

Retina , 63 59 bayt

.+
$*
^((^1|1\2)*)((1(?(4)\4))*)((1(?(6)\6))*)$
$.1 $.3 $.5

Çevrimiçi deneyin! Bağlantı, test senaryolarını içerir. (1(?(1)\1))*genelleştirilmiş bir üçgen sayı eşleştiricisidir, ancak ilk üçgen sayı ^için ilk eşleşme için birkaç bayt kaydedebiliriz .


1

PHP , 351 bayt

$r=[];function f($a=[],$c=0){global$argn,$t,$r;if($c<3){$n=$argn-array_sum($a);$z=array_filter($t,$f=function($v)use($n,$c){return$v>=$n/(3-$c)&&$v<=$n;});foreach($z as$v){$u=array_merge($a,[$v]);if(($w=$n-$v)<1){if(!$w){$u=array_pad($u,3,0);sort($u);if(!in_array($u,$r)){$r[]=$u;}}}else f($u,$c+1);}}}for($t=[0];$argn>$t[]=$e+=++$i;);f();print_r($r);

Çevrimiçi deneyin!


1

Python 3 , 119 bayt

lambda n:[l for l in combinations_with_replacement([(t**2+t)/2for t in range(n)],3)if sum(l)==n]
from itertools import*

Çevrimiçi deneyin!

@WheatWizard'a 12 bayt kaydettiği için teşekkürler!


Sizin map(ve belki de filtrenizin) liste kavraması olarak daha kısa yazılabilir.
Buğday Büyücüsü


@WheatWizard fikir için teşekkürler, için bir liste anlama düşünmedim inanamıyorummap
Chase Vogeli

Filtre nesneleri son derece geçerli çıktıdır, ancak bir liste çıktısı almak istiyorsanız böyle bir uyarıyı kullanabilirsiniz[*filter(...)]
Wheat Wizard

1
Denediğim şey (x,y,z) for x,y,z in..., l for l in...muhtemelen bu farkı açıklayandan daha uzun .
Chase Vogeli

1

C / C ++ - 197 bayt

#include<stdio.h>
#define f(i,l,u) for(int i=l;i<=u;i++)
int t(int n){return n>1?n+t(n-1):n;}
int c(int n){f(a,0,n)f(b,a,n)f(c,b,n)if(t(a)+t(b)+t(c)==n)return printf("%d %d %d\n",t(a),t(b),t(c));}

Darbe üstüne darbe:

#include<stdio.h>

Yazdırma için gerekli f. C'nin belirli sürümleri için seçilebilir

#define f(i,l,u) for(int i=l;i<=u;i++)

Döngü için yerden tasarruf.

int t(int n){return n>1?n+t(n-1):n;}

Özyinelemeli üçgen değerlendirici.

int c(int n){f(a,0,n)f(b,a,n)f(c,b,n)if(t(a)+t(b)+t(c)==n)return printf("%d %d %d\n",t(a),t(b),t(c));}

Bu adam ağır kaldırma yapıyor. Döngüler için iç içe üç, a, b, c'yi 0'dan n'ye yineler, b ve c'nin her birinin önceki değerden n'ye kadar yinelendiğini unutmayın. returnBir dakika içinde gelen "yinelenen" sorunu çözdüğü için yinelemenin böyle kesilmesi kesinlikle gerekli değildir .

İç seviyede, üç üçgenin toplamı ==istenen değeri numaralandırıyorsa , üçgenleri yazdırın ve geri dönün.

returnAnahtar kelimeyi yasal olarak kaldırabilir ve birkaç bayt kaydetmek ve olası tüm çözümleri yazdırmak için c dönüş türünü geçersiz hale getirebilirsiniz . Tüm döngüler kaçtı eğer yineleme, sınırlı olduğunu bu nedenle içindir 0üzere nkopyalarının oluşmasına neden olur buna.


1

Mathematica, 63 bayt

(t=#;#&@@Select[Table[i(i+1)/2,{i,0,t}]~Tuples~{3},Tr@#==t&]‌​)&

İnfix sözdizimi ve almanın o vurmak yolu ile Firstbir kuyruklu kaydeder 2 bayt , (t=#;#&@@Select[Table[i(i+1)/2,{i,0,t}]~Tuples~{3},Tr@#==t&])&62 bayt için.
numbermaniac

Harika, ben düzenleyeceğim
J42161217


0

R , 66 bayt

n=scan();b=expand.grid(rep(list(cumsum(0:n)),3));b[rowSums(b)==n,]

Kaba kuvvet algoritması; nstdin'den okur ve her satırın en fazla 3 üçgen sayının birleşimi olduğu bir veri çerçevesi döndürür n. Gerekirse, +4 bayt için yalnızca ilk satırı döndürebilirim.

Çevrimiçi deneyin!


0

Java 8, 164 bayt

n->{int t[]=new int[n+1],i=0,j=0;for(;i<=n;)if(Math.sqrt(8*i+++1)%1==0)t[j++]=i-1;for(int a:t)for(int b:t)for(int c:t)if(a+b+c==n)return new int[]{c,b,a};return t;}

Açıklama:

Burada deneyin.

n->{                     // Method with int parameter and int-array return-type
  int t[]=new int[n+1],  //  Create an int-array to store triangular numbers
      i=0,j=0;           //  Two index-integers
  for(;i<=n;)            //  Loop (1) from 0 to `n` (inclusive)
    if(Math.sqrt(8*i+++1)%1==0) 
                         //   If `i` is a triangular number
      t[j++]=i-1;        //    Add it to array `t`
                         //  End of for-loop (1) (implicit / single-line body)
  for(int a:t)           //  Loop (2) over the triangular numbers
    for(int b:t)         //   Inner loop (3) over the triangular numbers
      for(int c:t)       //    Inner loop (4) over the triangular numbers
        if(a+b+c==n)     //     If the three triangular numbers sum equal the input
          return new int[]{c,b,a};
                         //      Return these three triangular numbers as int-array
                         //    End of loop (4) (implicit / single-line body)
                         //   End of loop (3) (implicit / single-line body)
                         //  End of loop (2) (implicit / single-line body)
  return t;              //  Return `t` if no sum is found (Java methods always need a
                         //  return-type, and `t` is shorter than `null`;
                         //  since we can assume the test cases will always have an answer,
                         //  this part can be interpret as dead code)
}                        // End of method

0

JavaScript, 108 bayt

r=[],i=a=b=0
while(a<=x)r.push(a=i++*i/2)
for(a=0;a<3;){
b=r[i]
if(b<=x){
x-=b
a++
console.log(b)}
else i--}

açıklama

x girişi temsil eder

while(a<=x)r.push(a=i++*i/2) X'e kadar olan tüm üçgen sayılardan oluşan bir dizi oluşturur

forDöngü en yüksek üçgen sayı az yazdırır x, sonra gelen bu sayıyı çıkarır xüç tekrarlamalar için. (temelde açgözlü bir algoritma)


Yaptığım aynı sorunla karşı karşıyasınız: her adımda <= x en büyük üçgen numarasını alarak, 3. sıranız için bir üçgen numaranız olduğu garanti edilmez. Çıktınızı kontrol edin x = 103:91 + 10 + 1 = 102
asgallant

0

Pyth, 19 bayt

Pyth'le çok pratik değilim , bu doğru değil: /

hfqQsT.C*3+0msSdSQ3

Burada deneyin .

hfqQsT.C*3+0msSdSQ3  Implicit: Q=input()

                SQ   Range 1-n
            m        Map the above over d:
              Sd       Range 1-d
             s         Sum the above
                     Yields [1,3,6,10,...]
          +0         Prepend 0 to the above
        *3           Triplicate the above
      .C          3  All combinations of 3 of the above
 f                   Filter the above over T:
    sT                 Where sum of T
  qQ                   Is equal to input
h                    Take the first element of that list

Muhtemelen tüm çözümleri yazdırmanıza izin verildiğinden, ilk liste öğesi için seçiciyi bırakarak bir bayt kaydedebilirsiniz.
racer290

@ racer290 Daha da iyisi, sonuçlar [[a, b, c], [d, e, f]] şeklinde olsa da - bu iyi olur mu?
Sok

@ racer290 Aslında, hayır, kopyaları filtrelemek şeylerin görünüşü tarafından özgür olmayacaktır, bu yüzden daha kısa olmaz: c
Sok


0

Yakut 61 57 55 bayt

Lynn'in Python cevabından esinlenmiştir . İstenen toplam elde edilene kadar rastgele üçüz üretir:

->n{x=Array.new 3{(0..rand(n+1)).sum}until x&.sum==n;x}

Ruby 2.4 gerektirir. Ruby 2.3 ve daha eski sürümlerde sözdizimi hatasıdır ve Range#sumtanımlanmamıştır. Bu daha uzun sürüm (64 bayt) Ruby 2.3 için gereklidir:

->n{x=Array.new(3){(a=rand(n+1))*-~a/2}until x&.inject(:+)==n;x}

İşte küçük bir test:

f=->n{x=Array.new 3{(0..rand(n+1)).sum}until x&.sum==n;x}
# => #<Proc:0x000000018aa5d8@(pry):6 (lambda)>
f[0]
# => [0, 0, 0]
f[13]
# => [0, 3, 10]
f[5]
# => [3, 1, 1]
f[27]
# => [21, 3, 3]
f[27]
# => [0, 21, 6]
f[300]
# => [3, 21, 276]

Ruby 2.3 ile çevrimiçi deneyin!


0

Javascript (ES6), 108 bayt - sabit

Girdi olarak bir tamsayı alır, sıralı [a, b, c]bir üçgen sayı listesi içeren bir dizi çıkarır a + b + c = x; burada a, girdiden küçük veya girdiye eşit ben büyük üçgen numarası ve giriş eksi eşit veya eşit olmayan en büyük üçgen numarasıdır a.

x=>{t=[0],t.f=t.forEach,i=j=k=0;for(;j<x;t[i]=j+=i++);t.f(a=>t.f(b=>t.f(c=>a+b+c==x?k=[a,b,c]:0)));return k}

açıklama

x=>{
    t=[0],                               // initialize an array of triangle numbers
    t.f=t.forEach,                       // copy forEach method into t.f,
                                         // saves a net of 4 bytes
    i=j=k=0;
    for(;j<x;t[i]=j+=i++);               // populate t with all triangle numbers that
                                         // we could possibly need
    t.f(                                 // loop over all t
        a=>t.f(                          // loop over all t
            b=>t.f(                      // loop over all t
                c=>a+b+c==x?k=[a,b,c]:0  // if a+b+c = x, set k = [a,b,c], else noop
                                         // using a ternary here saves 1 byte vs
                                         // if statement
                                         // iterating over t like this will find all
                                         // permutations of [a,b,c] that match, but
                                         // we will only return the last one found,
                                         // which happens to be sorted in descending order
            )
        )
    );
    return k
}


En ilginç kısmı x-m-naçıklamıyorsunuz : neden üçgen bir sayı, yani bu neden çalışıyor?
Christian Sievers

Eh, dangit, ortaya çıktığı garanti değil. Kullandığım tüm test senaryoları geçerli bir üçgen sayısı üçlüsü oluşturdu. Çizim tahtasına geri dön.
asgallant

Şimdi düzeltildi, bu çözümden daha az memnun <; o (ama en azından işe yarıyor.
asgallant
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.