Drei dreieckige Zahlen [geschlossen]


19

Beschreibung

Es gab schon einige andere Herausforderungen in Bezug auf diese Zahlen, und ich hoffe, dass diese nicht darunter ist.

Die n- te Dreieckszahl entspricht der Summe aller natürlichen Zahlen bis zu n einfachen Sachen. Für diejenigen, die sich weiter informieren möchten, gibt es eine Wikipedia-Seite und einen Eintrag bei OEIS .

Nun fand Gauß heraus, dass jede natürliche Zahl als Summe von drei Dreieckszahlen (einschließlich 0) ausgedrückt werden kann , und es ist in Ordnung, eine Zahl mehr als einmal zu haben, z 0 + 1 + 1 = 2.

Herausforderung

Ihre Aufgabe ist es, ein Programm oder eine Funktion mit einer natürlichen Zahl (einschließlich 0) zu schreiben, die drei Dreieckszahlen ausgibt, die das Argument ergeben. Sie können die durch Leerzeichen getrennten Zahlen als Array oder nach einer anderen Methode ausdrucken. Es ist jedoch verboten , eingebaute Funktionen zu verwenden, um direkt ein Array, einen Bereich oder eine andere Form der Sammlung abzurufen, die eine Liste dreieckiger Zahlen enthält (zum Beispiel ein einzelnes Atom, das den Bereich ergibt).

Testfälle

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

Hinweis: Wenn es mehr als eine mögliche Kombination gibt, können Sie eine oder alle drucken, aber Sie müssen jede Kombination nur einmal drucken, um alle Kombinationen zu entfernen, die das Ergebnis einer Neuanordnung anderer Kombinationen sind. Ich würde mich sehr über einen Try-It-Link und eine Erklärung freuen. Ich freue mich sehr zu sehen, wie Sie das Problem lösen.

Dies ist , daher gelten Standard-Regelungslücken. Möge die kürzeste Antwort in Bytes gewinnen!


1
Für 12 können Sie auch 1 + 1 + 10 machen.
Erik the Outgolfer

1
@steenbergh awird nicht immer eine dreieckige Zahl sein
Felipe Nardi Batista

3
Ich kann " Built-in-Funktionen " auf zwei Arten analysieren, um direkt ein Array, einen Bereich oder eine andere Form der Sammlung zu erhalten, die eine Liste dreieckiger Zahlen enthält , aber keine davon ist sinnvoll. Das erste verbietet alle Builtins, die direkt ein Array erhalten, aber das scheint die Verwendung von Arrays in jeder mir bekannten Sprache zu verbieten; die andere verbietet builtins, " direkt ... einen Bereich ... mit einer Liste von Dreieckszahlen zu erhalten ", aber ich weiß nicht, was das bedeuten würde.
Peter Taylor

2
So integrierte Funktionen , die ein Argument nehmen nund eine Liste der ersten nRückdreieckszahlen sind zulässig? Das fühlt sich eher gegen eine bestimmte Sprache gerichtet an, obwohl ich nicht weiß, welche.
Peter Taylor

4
Ich fordere Sie auf, diese Einschränkung aufzuheben. Ich verspreche Ihnen, dass es die Qualität oder Fairness der sprachübergreifenden Antworten in Ihrer Denkweise nicht verbessert.
Lynn

Antworten:


8

05AB1E , 10 Bytes

Code:

ÝηO3ãʒOQ}¬

Erläuterung:

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

Verwendet die 05AB1E- Codierung. Probieren Sie es online!


Ahhh ... Ja; das würde es tun
Magic Octopus Urn

7

Python 2 , 99 Bytes

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)

Probieren Sie es online!

Ich bin ziemlich erstaunt, dass dies kürzer ist als itertoolsoder ein dreifaches Listenverständnis! Es spuckt (irgendwann) jedes Mal eine zufällige Antwort aus, wenn Sie es ausführen.

Zwei 102er:

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 sieht aus wie 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 für zufällige Ausgabe. :) Ich bin auch überrascht, dass es die kürzeste Lösung gibt (soweit).
Kevin Cruijssen

Vielen Dank für die Methode. Der entsprechende Ruby-Code hat 57 Bytes.
Eric Duminil


3

Brachylog , 13 Bytes

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

Probieren Sie es online!

Wie es funktioniert

⟦⟦ᵐ+ᵐ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 Bytes

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

Dies gibt das erste Ergebnis in lexikografischer Reihenfolge aus.

Probieren Sie es bei MATL Online!

Erläuterung

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 Bytes

Vielen Dank, dass Sie alle Lösungen ausgeben konnten, das war eine faszinierende Ablenkung! Ich war so froh, nicht eine Lösung extrahieren zu müssen und in der Lage zu sein, ihnen alles zu geben, dass ich die Kosten, die durch die Vermeidung von permutierten Lösungen entstehen, nicht bemerkte. @Lynns Bemerkung erklärte mir das und ließ mich 7 Bytes sparen.

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

Dies bindet mehr als genug Dreieckszahlen an lund überprüft alle Kombinationen.


Ist das Löschen der a>=b,b>=cBedingungen und das Hinzufügen !!0von Suffixen zu Ihrem Code nicht auch eine gültige Antwort? Die Ausgabe aller Lösungen hilft Ihnen hier nicht wirklich.
Lynn

@Lynn Du hast natürlich Recht, ich wurde abgelenkt. Vielen Dank!
Christian Sievers

2

Retina , 63 59 Bytes

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

Probieren Sie es online! Link enthält Testfälle. (1(?(1)\1))*ist ein verallgemeinerter Dreieckszahlenvergleicher, aber für die erste Dreieckszahl können wir ein paar Bytes einsparen, indem wir ^für die anfängliche Übereinstimmung verwenden.


1

PHP , 351 Bytes

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

Probieren Sie es online!


1

Python 3 , 119 Bytes

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*

Probieren Sie es online!

Vielen Dank an @WheatWizard für das Speichern von 12 Bytes!


Ihr map(und vielleicht Ihr Filter) kann als Listenverständnis kürzer geschrieben werden.
Weizen-Assistent


@ WheatWizard Danke für die Idee, ich kann nicht glauben, dass ich nicht an ein Listenverständnis für diemap
Chase Vogeli

Filterobjekte sind eine absolut gültige Ausgabe, aber wenn Sie eine Liste ausgeben möchten, können Sie einen Splat wie folgt verwenden[*filter(...)]
Weizen-Assistent

1
Was ich versucht hatte, war, (x,y,z) for x,y,z in...welche länger ist als Ihre, l for l in...die wahrscheinlich für diesen Unterschied verantwortlich ist.
Chase Vogeli

1

C / C ++ - 197 Bytes

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

Schlag für Schlag:

#include<stdio.h>

Benötigt für printf. Könnte für bestimmte Versionen von C entfallen

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

Platzsparend für Schleife.

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

Rekursiver Dreiecksauswerter.

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

Dieser Typ macht das schwere Heben. Drei verschachtelte for-Schleifen iterieren a, b, c von 0 bis n. Beachten Sie, dass b und c jeweils vom vorherigen Wert bis zu n iterieren. Es ist nicht unbedingt erforderlich, die Iteration auf diese Weise zu trimmen, da das returnProblem des "Duplizierens" durch das Kommen in einer Minute behoben wird.

Wenn die Summe der drei Dreiecke auf der inneren Ebene ==den gewünschten Wert ergibt, drucken Sie die Dreiecke aus und kehren Sie zurück.

Sie können das returnSchlüsselwort legal entfernen und den Rückgabetyp von c in void konvertieren, um ein paar weitere Bytes zu sparen und alle möglichen Lösungen zu drucken. Aus diesem Grund sind die Iterationen begrenzt, wenn alle von ihr ausgeführten Schleifen 0zu nDuplikaten führen würden.


1

Mathematica, 63 Bytes

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

Mit Infix Syntax und dass Whack Weg, um Firstdas spart ein sattes 2 Bytes , (t=#;#&@@Select[Table[i(i+1)/2,{i,0,t}]~Tuples~{3},Tr@#==t&])&62 Bytes.
Numbermaniac

Großartig, ich bearbeite
J42161217


0

R , 66 Bytes

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

Brute-Force-Algorithmus; liestn aus stdin und gibt einen Datenrahmen zurück, in dem jede Zeile eine Kombination von 3 Dreieckszahlen ist, die sich summieren n. Bei Bedarf kann ich nur die erste Zeile für +4 Bytes zurückgeben.

Probieren Sie es online!


0

Java 8, 164 Bytes

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

Erläuterung:

Probieren Sie es hier aus.

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 Bytes

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

Erläuterung

x repräsentiert die Eingabe

while(a<=x)r.push(a=i++*i/2) Erstellt ein Array aller Dreieckszahlen bis zu x

Die forSchleife druckt die höchste dreieckige Zahl kleiner als xund subtrahiert diese Zahl dann xfür drei Iterationen. (im Grunde ein gieriger Algorithmus)


Sie haben das gleiche Problem wie ich: Wenn Sie bei jedem Schritt die größte Dreieckszahl <= x nehmen, kann nicht garantiert werden, dass Sie für Ihren dritten Platz eine Dreieckszahl haben. Überprüfen Sie Ihre Ausgabe für x = 103:91 + 10 + 1 = 102
Asgallant

0

Pyth, 19 Bytes

Ich bin so aus der Übung mit Pyth, es ist falsch: /

hfqQsT.C*3+0msSdSQ3

Probieren Sie es hier aus .

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

Sie können möglicherweise ein Byte speichern, indem Sie den Selektor für das erste Listenelement weglassen, da Sie auch alle möglichen Lösungen drucken dürfen.
Racer290

@ racer290 Noch besser, obwohl die Ergebnisse in der Form [[a, b, c], [d, e, f]] vorliegen - wäre das in Ordnung?
Sok

@ racer290 Nein, das Filtern der Duplikate wäre nicht kostenlos, also würde es auch nicht kürzer sein: c
Sok


0

Rubin 61 57 55 Bytes

Inspiriert von Lynns Python- Antwort . Es werden zufällige Triplets erzeugt, bis die gewünschte Summe erreicht ist:

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

Es benötigt Ruby 2.4. In Ruby 2.3 und älteren Versionen handelt es sich um einen Syntaxfehler, der Range#sumnicht definiert ist. Diese längere Version (64 Bytes) wird für Ruby 2.3 benötigt:

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

Hier ist ein kleiner 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]

Probieren Sie es online mit Ruby 2.3!


0

Javascript (ES6), 108 Bytes - behoben

Nimmt eine Ganzzahl als Eingabe, gibt ein Array [a, b, c]mit einer sortierten Liste von Dreiecksnummern aus a + b + c = x, wobei adie größte Dreiecksnummer kleiner oder gleich der Eingabe ist und bdie größte Dreiecksnummer kleiner oder gleich dem Eingabe-Minus ist 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}

Erläuterung

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
}


Sie erklären nicht den interessantesten Teil: Warum ist x-m-n eine Dreieckszahl, dh warum funktioniert das?
Christian Sievers

Na verdammt, es stellt sich heraus, dass es nicht garantiert ist. Alle von mir verwendeten Testfälle ergaben zufällig ein gültiges Triplett von Dreieckszahlen. Zurück zum Zeichenbrett.
Asgallant

Behoben, weniger zufrieden mit dieser Lösung <; o (aber es funktioniert zumindest.
Asgallant
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.