Trois nombres triangulaires [fermé]

19

La description

Il y a eu pas mal d'autres défis concernant ces chiffres auparavant, et j'espère que celui-ci n'en fait pas partie.

Le n ème nombre triangulaire est égal à la somme de tous les nombres naturels jusqu'à n , trucs simples. Il y a une page wikipedia et une entrée à OEIS , pour ceux qui souhaitent s'informer davantage.

Maintenant, Gauss a découvert que chaque nombre naturel peut être exprimé comme une somme de trois nombres triangulaires (ceux-ci incluent 0), et il est bon d'avoir un nombre plus d'une fois, par exemple 0 + 1 + 1 = 2.

Défi

Votre tâche consiste à écrire un programme ou une fonction, étant donné un nombre naturel (y compris 0), imprime trois nombres triangulaires qui résument l'argument. Vous pouvez imprimer les nombres séparés par des espaces, comme un tableau ou par une autre méthode que vous aimez. Cependant, il est interdit d'utiliser des fonctions intégrées pour obtenir directement un tableau, une plage ou toute autre forme de collection contenant une liste de nombres triangulaires (par exemple un seul atome qui donne la plage).

Cas de test

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

Remarque: S'il existe plusieurs combinaisons possibles, vous pouvez imprimer une ou toutes les combinaisons, mais vous ne devez imprimer une seule combinaison qu'une seule fois, en éliminant toutes les combinaisons résultant de la réorganisation d'autres combinaisons. J'apprécierais vraiment un lien d'essai et une explication, j'aime vraiment voir comment vous résolvez le problème;)

Il s'agit de , donc les failles standard s'appliquent. Que la réponse la plus courte en octets gagne!

racer290
la source
1
Pour 12, vous pouvez également faire 1 + 1 + 10.
Erik the Outgolfer
1
@steenbergh ane sera pas toujours un nombre triangulaire
Felipe Nardi Batista
3
Je peux analyser "les fonctions intégrées pour obtenir directement un tableau, une plage ou toute autre forme de collection contenant une liste de nombres triangulaires " de deux manières, mais aucune d'elles n'a de sens. Le premier interdit tous les buildins qui obtiennent directement un tableau, mais cela semble interdire toute utilisation de tableaux dans toutes les langues que je connais; l'autre interdit aux buildins "d' obtenir directement ... une plage ... contenant une liste de nombres triangulaires ", mais je ne sais pas ce que cela signifierait.
Peter Taylor
2
Les fonctions intégrées qui prennent un argument net renvoient une liste des premiers nnombres triangulaires sont-elles autorisées? Cela semble plutôt ciblé par rapport à un langage spécifique, même si je ne sais pas lequel.
Peter Taylor
4
Je vous exhorte à lever cette restriction. Je vous promets que cela n'améliorera pas la qualité des réponses inter-langues ou l'équité dans votre façon de penser.
Lynn

Réponses:

8

05AB1E , 10 octets

Code:

ÝηO3ãʒOQ}¬

Explication:

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

Utilise l' encodage 05AB1E . Essayez-le en ligne!

Adnan
la source
Ahhh ... Ouais; ça le ferait.
Magic Octopus Urn
7

Python 2 , 99 octets

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)

Essayez-le en ligne!

Je suis assez étonné que ce soit plus court que itertoolsou une compréhension de la triple liste! Il (éventuellement) crache une réponse aléatoire à chaque fois que vous l'exécutez.

Deux 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 semble être de 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]
Lynn
la source
+1 pour une sortie aléatoire. :) Je suis également surpris que cela donne la solution la plus courte (jusqu'à présent).
Kevin Cruijssen
Merci beaucoup pour la méthode. Le code Ruby correspondant a 57 octets.
Eric Duminil
3

Gelée , 12 octets

0r+\œċ3S=¥Ðf

Essayez-le en ligne!

Comment ça fonctionne

0r+\œċ3S=¥Ðf   input: n
0r             [0 1 ... n]
  +\           cumsum
    œċ3        combinations of 3 elements, with repetition
          Ðf   filter on
       S          sum
        =         equals n
Leaky Nun
la source
Veuillez envisager d'ajouter une explication .. =)
racer290
2
@ racer290 terminé.
Leaky Nun
3

Brachylog , 13 octets

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

Essayez-le en ligne!

Comment ça fonctionne

⟦⟦ᵐ+ᵐ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
Leaky Nun
la source
2

MATL , 18 octets

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

Cela produit le premier résultat dans l'ordre lexicographique.

Essayez-le sur MATL Online!

Explication

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
Luis Mendo
la source
2

Haskell, 66 59 octets

Merci d'avoir permis de produire toutes les solutions, c'était une distraction fascinante! J'étais tellement heureux de ne pas avoir besoin d'extraire une seule solution et de pouvoir leur donner tout ce que je n'ai pas remarqué le coût qui découle de l'évitement des solutions permutées. @ La remarque de Lynn m'a expliqué cela et m'a permis d'économiser 7 octets.

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

Cela lie plus que suffisamment de nombres triangulaires let vérifie toutes les combinaisons.

Christian Sievers
la source
La suppression des a>=b,b>=cconditions et le suffixe !!0de votre code ne sont-ils pas également une réponse valide? La sortie de toutes les solutions ne vous aide pas vraiment ici.
Lynn
@Lynn Vous avez bien sûr raison, je me suis distrait. Merci!
Christian Sievers
2

Rétine , 63 59 octets

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

Essayez-le en ligne! Le lien inclut des cas de test. (1(?(1)\1))*est un comparateur de nombres triangulaires généralisé, mais pour le premier nombre triangulaire, nous pouvons économiser quelques octets en utilisant ^pour la correspondance initiale.

Neil
la source
1

PHP , 351 octets

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

Essayez-le en ligne!

Jörg Hülsermann
la source
1

Python 3 , 119 octets

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*

Essayez-le en ligne!

Merci à @WheatWizard pour avoir économisé 12 octets!

Chase Vogeli
la source
Votre map(et peut-être votre filtre) peut être écrit plus court comme une compréhension de liste.
Wheat Wizard
@WheatWizard merci pour l'idée, je n'arrive pas à croire que je n'ai pas pensé à une liste de compréhension pour lemap
Chase Vogeli
Les objets de filtre sont une sortie parfaitement valide, mais si vous voulez sortir une liste, vous pouvez utiliser un splat comme ça[*filter(...)]
Wheat Wizard
1
Ce que j'avais essayé était (x,y,z) for x,y,z in...qui est plus long que le vôtre, l for l in...ce qui explique probablement cette différence.
Chase Vogeli
1

C / C ++ - 197 octets

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

Coup par coup:

#include<stdio.h>

Nécessaire pour printf. Pourrait être élidé pour certaines versions de C

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

Économie d'espace pour la boucle.

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

Évaluateur de triangle récursif.

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

Ce gars fait le gros du travail. Trois boucles imbriquées pour itérer a, b, c de 0 à n, notez que b et c itèrent chacun de la valeur précédente jusqu'à n. Il n'est pas strictement nécessaire de couper l'itération comme ça, car l' returnarrivée en une minute résout le problème de "doublon".

Au niveau intérieur, si la somme des trois triangles numérote ==la valeur souhaitée, imprimez les triangles et revenez.

Vous pouvez supprimer légalement le returnmot - clé et convertir le type de retour de c en void pour économiser quelques octets de plus et imprimer toutes les solutions possibles. Il est pour cette raison que les itérations sont limitées, si toutes les boucles allaient de 0la nlui causerait des doublons.

dgnuff
la source
1

Mathematica, 63 octets

(t=#;#&@@Select[Table[i(i+1)/2,{i,0,t}]~Tuples~{3},Tr@#==t&]‌​)&
J42161217
la source
Avec la syntaxe infixe et cette façon détraquée d'obtenir Firstqui sauve un énorme 2 octets , (t=#;#&@@Select[Table[i(i+1)/2,{i,0,t}]~Tuples~{3},Tr@#==t&])&pour 62 octets.
numbermaniac
Super, je vais éditer
J42161217
0

CJam , 26 octets

{_),[{\_@+}*]3m*_{:+}%@#=}

Port de ma réponse MATL. Il s'agit d'un bloc anonyme qui attend l'entrée sur la pile et la remplace par le tableau de sortie.

Essayez-le en ligne!

Luis Mendo
la source
0

R , 66 octets

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

Algorithme de force brute; lit à npartir de stdin et renvoie une trame de données où chaque ligne est une combinaison de 3 nombres triangulaires qui s'additionnent n. Si nécessaire, je peux renvoyer uniquement la première ligne pour +4 octets.

Essayez-le en ligne!

Giuseppe
la source
0

Java 8, 164 octets

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

Explication:

Essayez-le ici.

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
Kevin Cruijssen
la source
0

JavaScript, 108 octets

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

Explication

x représente l'entrée

while(a<=x)r.push(a=i++*i/2) Crée un tableau de tous les nombres triangulaires jusqu'à x

La forboucle imprime le plus grand nombre triangulaire inférieur à x, puis soustrait ce nombre à x, pour trois itérations. (essentiellement un algorithme gourmand)

WaffleCohn
la source
Vous avez le même problème que moi: en prenant le plus grand nombre de triangle <= x à chaque étape, vous n'êtes pas assuré d'avoir un numéro de triangle pour votre 3e place. Vérifiez votre sortie pour x = 103:91 + 10 + 1 = 102
asgallant
0

Pyth, 19 octets

Je suis tellement hors de pratique avec Pyth, c'est faux: /

hfqQsT.C*3+0msSdSQ3

Essayez-le ici .

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
Sok
la source
Vous pouvez éventuellement enregistrer un octet en omettant le sélecteur pour le premier élément de la liste car vous êtes également autorisé à imprimer toutes les solutions possibles.
racer290
@ racer290 Encore mieux, même si les résultats seront sous la forme [[a, b, c], [d, e, f]] - serait-ce correct?
Sok
@ racer290 En fait, non, le filtrage des doublons ne serait pas gratuit par l'apparence des choses, donc ce ne serait pas plus court: c
Sok
0

Rubis 61 57 55 octets

Inspiré par la réponse Python de Lynn . Il génère des triplets aléatoires jusqu'à ce que la somme souhaitée soit atteinte:

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

Il nécessite Ruby 2.4. Dans Ruby 2.3 et versions antérieures, il s'agit d'une erreur de syntaxe et elle Range#sumn'est pas définie. Cette version plus longue (64 octets) est nécessaire pour Ruby 2.3:

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

Voici un petit 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]

Essayez-le en ligne avec Ruby 2.3!

Eric Duminil
la source
0

Javascript (ES6), 108 octets - corrigé

Prend un entier comme entrée, génère un tableau [a, b, c]contenant une liste triée de nombres de triangle a + b + c = x, où aest le plus grand nombre de triangle inférieur ou égal à l'entrée, et best le plus grand nombre de triangle inférieur ou égal au moins d'entrée 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}

Explication

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
}

impitoyable
la source
Vous n'expliquez pas la partie la plus intéressante: pourquoi x-m-nun nombre triangulaire, c'est-à-dire pourquoi cela fonctionne-t-il?
Christian Sievers
Eh bien dangit, il s'avère que ce n'est pas garanti. Tous les cas de test que j'ai utilisés se sont avérés justement produire un triplet valide de nombres triangulaires. Retour à la planche à dessin.
asgallant
Fixé maintenant, moins satisfait de cette solution <; o (mais au moins ça marche.
asgallant