ตัวเลขสามเหลี่ยมสามตัว [ปิด]


19

ลักษณะ

มีความท้าทายเล็กน้อยเกี่ยวกับตัวเลขเหล่านี้มาก่อนและฉันหวังว่าสิ่งนี้ไม่ได้อยู่ในหมู่พวกเขา

n TH จำนวนสามเหลี่ยมเท่ากับผลรวมของตัวเลขธรรมชาติทั้งหมดขึ้นอยู่กับn , สิ่งที่ง่าย มีหน้าวิกิพีเดียและรายการที่ OEISสำหรับผู้ที่ต้องการแจ้งตัวเองต่อไป

ตอนนี้เกาส์พบว่าทุกจำนวนธรรมชาติอาจจะแสดงเป็นผลรวมของสามตัวเลขสามเหลี่ยม (เหล่านี้รวมถึง0) 0 + 1 + 1 = 2และมันเป็นเรื่องปกติที่จะมีจำนวนหนึ่งมากกว่าหนึ่งครั้งเช่น

ท้าทาย

งานของคุณคือการเขียนโปรแกรมหรือฟังก์ชั่นกำหนดจำนวนธรรมชาติ (รวมถึง0) พิมพ์ตัวเลขสามเหลี่ยมสามที่รวมถึงการโต้แย้ง คุณอาจพิมพ์ตัวเลขที่คั่นด้วยช่องว่างเป็นอาร์เรย์หรือโดยวิธีอื่นที่คุณชอบ อย่างไรก็ตามห้ามมิให้ใช้ฟังก์ชันบิวด์อินใด ๆ เพื่อรับอาร์เรย์ช่วงหรือรูปแบบการรวบรวมอื่น ๆ ที่มีรายการหมายเลขรูปสามเหลี่ยมโดยตรง (ตัวอย่างเช่นอะตอมเดี่ยวที่ให้ช่วง)

กรณีทดสอบ

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

หมายเหตุ: หากมีชุดค่าผสมที่เป็นไปได้มากกว่าหนึ่งชุดคุณสามารถพิมพ์ชุดค่าผสมใด ๆ หรือทั้งหมด แต่คุณต้องพิมพ์ชุดค่าผสมใด ๆ เพียงครั้งเดียวโดยกำจัดชุดค่าผสมทั้งหมดที่เป็นผลมาจากการจัดชุดค่าผสมอื่น ๆ ฉันขอขอบคุณลิงก์ทดลองและคำอธิบายฉันชอบที่จะเห็นว่าคุณแก้ปัญหาอย่างไร)

นี่คือดังนั้นจึงมีช่องโหว่มาตรฐาน อาจคำตอบที่สั้นที่สุดในไบต์ชนะ!


1
สำหรับ 12 คุณสามารถทำได้ 1 + 1 + 10
Erik the Outgolfer

1
@steenbergh aจะไม่เป็นหมายเลขสามเหลี่ยมเสมอ
เฟลิปานาร์บาติสตา

3
ฉันสามารถแยกวิเคราะห์ " builtin ฟังก์ชั่นเพื่อรับอาร์เรย์ช่วงหรือรูปแบบอื่น ๆ ของคอลเลกชันที่มีรายการของตัวเลขสามเหลี่ยม " สองวิธี แต่ทั้งสองไม่เหมาะสม ตัวแรกห้ามตัวบิวอินทั้งหมดที่รับอาเรย์โดยตรง แต่ดูเหมือนว่าจะห้ามใช้อาเรย์ทั้งหมดในทุกภาษาที่ฉันรู้จัก อีกอันห้ามมิให้บิวอินไปที่ " รับโดยตรง ... ช่วง ... บรรจุรายชื่อตัวเลขสามเหลี่ยม " แต่ฉันไม่รู้ว่ามันจะหมายถึงอะไร
ปีเตอร์เทย์เลอร์

2
ดังนั้นในตัวฟังก์ชั่นที่ใช้อาร์กิวเมนต์nและกลับรายการแรกnหมายเลขสามเหลี่ยมจะได้รับอนุญาต? ที่รู้สึกค่อนข้างกำหนดเป้าหมายกับภาษาเฉพาะบางอย่างแม้ว่าฉันไม่รู้ว่า
Peter Taylor

4
ฉันขอให้คุณยกข้อ จำกัด นี้ ฉันสัญญากับคุณว่ามันจะไม่ปรับปรุงคุณภาพของคำตอบระหว่างภาษาหรือความเป็นธรรมในแบบที่คุณคิด
ลินน์

คำตอบ:


8

05AB1E , 10 ไบต์

รหัส:

ÝηO3ãʒOQ}¬

คำอธิบาย:

Ý             # 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 ลองออนไลน์!


อ่าาา ... ที่จะทำมัน
Magic Octopus Urn

7

Python 2 , 99 ไบต์

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)

ลองออนไลน์!

ฉันประหลาดใจมากที่นี่สั้นกว่าitertoolsหรือมีความเข้าใจในรายการสามรายการ! มัน (ในที่สุด) คายคำตอบแบบสุ่มทุกครั้งที่คุณเรียกใช้

สอง 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:

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]

+1 สำหรับเอาต์พุตแบบสุ่ม :) ฉันก็ประหลาดใจที่ให้ทางออกที่สั้นที่สุด (ป่านนี้)
Kevin Cruijssen

ขอบคุณมากสำหรับวิธีการ รหัสทับทิมที่สอดคล้องกันมี 57 ไบต์
Eric Duminil


3

Brachylogขนาด 13 ไบต์

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

ลองออนไลน์!

มันทำงานอย่างไร

⟦⟦ᵐ+ᵐ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 ไบต์

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

สิ่งนี้จะส่งผลผลลัพธ์แรกตามลำดับพจนานุกรม

ลองที่MATL Online!

คำอธิบาย

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 ไบต์

ขอบคุณที่อนุญาตให้ส่งออกโซลูชันทั้งหมดนั่นคือความว้าวุ่นใจที่น่าสนใจ! ฉันมีความสุขมากที่ไม่จำเป็นต้องแยกโซลูชันเดียวและสามารถมอบให้ทั้งหมดที่ฉันไม่ได้สังเกตเห็นค่าใช้จ่ายที่มาจากการหลีกเลี่ยงโซลูชันที่เปลี่ยนแปลง @ หมายเหตุของ Lynn อธิบายให้ฉันฟังแล้วให้ฉันบันทึกได้ 7 ไบต์

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

วิธีนี้จะผูกตัวเลขสามเหลี่ยมให้มากพอlและตรวจสอบชุดค่าผสมทั้งหมด


การไม่วางa>=b,b>=cเงื่อนไขและเพียง!!0ตอบคำถามให้ถูกต้องกับรหัสของคุณหรือไม่ การแก้ปัญหาทั้งหมดไม่ได้ช่วยคุณที่นี่
ลินน์

@ ลินน์คุณพูดถูกฉันถูกวอกแวก ขอบคุณ!
Christian Sievers

2

เรติน่า63 63ไบต์

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

ลองออนไลน์! ลิงค์มีกรณีทดสอบ (1(?(1)\1))*เป็นเครื่องมือจับคู่หมายเลขสามเหลี่ยมทั่วไป แต่สำหรับหมายเลขสามเหลี่ยมแรกเราสามารถบันทึกได้สองสามไบต์โดยใช้^สำหรับการจับคู่เริ่มต้น


1

PHP , 351 ไบต์

$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);

ลองออนไลน์!


1

Python 3 , 119 ไบต์

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*

ลองออนไลน์!

ขอบคุณ @WheatWizard สำหรับการบันทึก 12 ไบต์!


ของคุณmap(และอาจจะกรองของคุณ) สามารถเขียนได้สั้นเป็นความเข้าใจรายการ
ตัวช่วยสร้างข้าวสาลี


@WeatWizard ขอบคุณสำหรับความคิดฉันไม่อยากจะเชื่อเลยว่าฉันไม่ได้คิดถึงรายการความเข้าใจสำหรับmap
Chase Vogeli

วัตถุตัวกรองเป็นผลลัพธ์ที่ถูกต้องสมบูรณ์แบบแต่ถ้าคุณต้องการส่งออกรายการคุณสามารถใช้เครื่องหมายดังกล่าวได้[*filter(...)]
Wheat Wizard

1
สิ่งที่ฉันได้ลองมา(x,y,z) for x,y,z in...นั้นยาวกว่าของคุณl for l in...ซึ่งน่าจะเป็นสาเหตุของความแตกต่างนั้น
Chase Vogeli

1

C / C ++ - 197 ไบต์

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

เป่าด้วยการเป่า:

#include<stdio.h>

จำเป็นสำหรับ printf สามารถนำไปใช้กับ C บางเวอร์ชันได้

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

ผู้ชายคนนี้ยกของหนัก สามระดับซ้อนกันสำหรับลูปวนซ้ำ a, b, c จาก 0 ถึง n โปรดทราบว่า b และ c แต่ละตัววนซ้ำจากค่าก่อนหน้าถึง n ไม่จำเป็นต้องตัดทอนซ้ำอย่างเช่นนั้นนับตั้งแต่การreturnมาในอีกหนึ่งนาทีแก้ปัญหา "ซ้ำ"

ที่ระดับชั้นในถ้าผลรวมของตัวเลขสามเหลี่ยมสามตัว==เป็นค่าที่ต้องการให้พิมพ์สามเหลี่ยมและกลับมา

คุณสามารถลบreturnคำหลักอย่างถูกกฎหมายและแปลงชนิดส่งคืนของ c เป็นโมฆะเพื่อประหยัดอีกสองสามไบต์และพิมพ์โซลูชันที่เป็นไปได้ทั้งหมด ด้วยเหตุนี้การทำซ้ำจะถูก จำกัด หากลูปทั้งหมดวิ่งจาก0ไปnมันจะทำให้เกิดการซ้ำซ้อน


1

Mathematica, 63 ไบต์

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

ด้วยไวยากรณ์มัดและว่าวิธีการตีการได้รับFirstที่จะช่วยประหยัดมหันต์2 ไบต์ , (t=#;#&@@Select[Table[i(i+1)/2,{i,0,t}]~Tuples~{3},Tr@#==t&])&62 ไบต์
numbermaniac

เยี่ยมมากฉันจะแก้ไข
J42161217


0

R , 66 ไบต์

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

ขั้นตอนวิธีกำลังดุร้าย; อ่านnจาก stdin และส่งกลับ dataframe ที่แต่ละแถวคือการรวมกันของตัวเลข 3 nรูปสามเหลี่ยมที่เพิ่มขึ้นเป็น หากจำเป็นฉันสามารถส่งคืนแถวแรกได้เพียง +4 ไบต์

ลองออนไลน์!


0

Java 8, 164 ไบต์

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

คำอธิบาย:

ลองที่นี่

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 ไบต์

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

คำอธิบาย

x แสดงถึงการป้อนข้อมูล

while(a<=x)r.push(a=i++*i/2) สร้างอาร์เรย์ของตัวเลขสามเหลี่ยมทั้งหมดสูงสุด x

forห่วงพิมพ์จำนวนสามเหลี่ยมสูงสุดน้อยกว่าxแล้วหักจำนวนนั้นxเป็นเวลาสามซ้ำ (โดยทั่วไปเป็นอัลกอริทึมโลภ)


คุณมีปัญหาเดียวกันกับที่ฉันทำ: โดยการใช้หมายเลขรูปสามเหลี่ยมที่ใหญ่ที่สุด <= x ในแต่ละขั้นตอนคุณไม่รับประกันว่าจะมีหมายเลขรูปสามเหลี่ยมสำหรับสถานที่ที่ 3 ของคุณ ตรวจสอบผลลัพธ์ของคุณสำหรับx = 103:91 + 10 + 1 = 102
asgallant

0

Pyth, 19 ไบต์

ผมจึงออกจากการปฏิบัติกับ Pyth ก็จริง: /

hfqQsT.C*3+0msSdSQ3

ลองที่นี่

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

คุณสามารถบันทึกไบต์โดยไม่ต้องเลือกตัวเลือกสำหรับองค์ประกอบรายการแรกเพราะคุณได้รับอนุญาตให้พิมพ์วิธีแก้ไขที่เป็นไปได้ทั้งหมดเช่นกัน
racer290

@ racer290 ดียิ่งขึ้นแม้ว่าผลลัพธ์จะอยู่ในรูปแบบ [[a, b, c], [d, e, f]] - นั่นจะโอเคไหม
Sok

@ racer290 ที่จริงแล้วไม่การกรองรายการที่ซ้ำกันจะไม่เป็นอิสระจากหน้าตาของสิ่งต่าง ๆ ดังนั้นมันจะไม่สั้นไปกว่านี้: c
Sok


0

Ruby 61 57 55 ไบต์

แรงบันดาลใจจากลินน์หลามคำตอบ มันสร้างสามเท่าสุ่มจนกว่าจะบรรลุผลรวมที่ต้องการ:

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

มันต้องใช้ Ruby 2.4 ใน Ruby 2.3 และเก่ากว่าเป็นข้อผิดพลาดทางไวยากรณ์และRange#sumไม่ได้กำหนดไว้ รุ่นที่ยาวกว่านี้ (64 ไบต์) จำเป็นสำหรับ Ruby 2.3:

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

นี่คือการทดสอบขนาดเล็ก:

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!


0

Javascript (ES6), 108 ไบต์ - แก้ไขแล้ว

ใช้เวลาเป็นจำนวนเต็มเป็น input, เอาท์พุทอาร์เรย์[a, b, c]ที่มีรายการที่เรียงลำดับของตัวเลขสามเหลี่ยมa + b + c = xที่aเป็นจำนวนสามเหลี่ยมที่ใหญ่ที่สุดน้อยกว่าหรือเท่ากับการป้อนข้อมูลและเป็นจำนวนสามเหลี่ยมที่ใหญ่ที่สุดน้อยกว่าหรือเท่ากับลบการป้อนข้อมูลba

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}

คำอธิบาย

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
}


คุณไม่ได้อธิบายส่วนที่น่าสนใจที่สุด: เพราะเหตุใดx-m-nตัวเลขสามเหลี่ยมจึงเป็นเช่นนี้ทำไมจึงใช้งานได้
Christian Sievers

ก็แปลว่ามันไม่รับประกัน กรณีทดสอบทั้งหมดที่ฉันใช้เกิดขึ้นเพื่อสร้าง triplet ที่ถูกต้องของตัวเลขสามเหลี่ยม กลับไปที่กระดานวาดภาพ
asgallant

แก้ไขแล้วตอนนี้มีความสุขน้อยลงกับโซลูชันนี้ <; o (แต่อย่างน้อยก็ใช้งานได้)
asgallant
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.