Tre numeri triangolari [chiuso]


19

Descrizione

Ci sono state molte altre sfide riguardanti questi numeri prima, e spero che questo non sia tra questi.

Il n -esimo numero triangolare è uguale alla somma di tutti i numeri naturali fino a n , roba semplice. Ci sono una pagina di Wikipedia e una voce su OEIS , per coloro che desiderano informarsi ulteriormente.

Ora, Gauss ha scoperto che ogni numero naturale può essere espresso come una somma di tre numeri triangolari (questi includono 0), ed è bene avere un numero più di una volta, ad es 0 + 1 + 1 = 2.

Sfida

Il tuo compito è scrivere un programma o una funzione, dato un numero naturale (incluso 0), stampare tre numeri triangolari che si sommano all'argomento. Puoi stampare i numeri separati da spazi, come una matrice o con un altro metodo che ti piace. Tuttavia, è vietato utilizzare qualsiasi funzione incorporata per ottenere direttamente un array, un intervallo o qualsiasi altra forma di raccolta contenente un elenco di numeri triangolari (ad esempio un singolo atomo che produce l'intervallo).

Casi 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

Nota: se esiste più di una combinazione possibile, è possibile stampare una o tutte, ma è necessario stampare una combinazione una sola volta, eliminando tutte le combinazioni che sono il risultato della riorganizzazione di altre combinazioni. Apprezzerei molto un link di prova e una spiegazione, mi piace molto vedere come risolvi il problema;)

Questo è , quindi si applicano scappatoie standard. Che vinca la risposta più breve in byte!


1
Per 12 puoi anche fare 1 + 1 + 10.
Erik the Outgolfer

1
@steenbergh anon sarà sempre un numero triangolare
Felipe Nardi Batista,

3
Posso analizzare " funzioni integrate per ottenere direttamente una matrice, un intervallo o qualsiasi altra forma di raccolta contenente un elenco di numeri triangolari " in due modi, ma nessuno dei due ha senso. Il primo vieta tutti i builtin che ottengono direttamente un array, ma ciò sembra vietare qualsiasi uso di array in ogni lingua che conosco; l'altro proibisce ai builtin di " ottenere direttamente ... un intervallo ... contenente un elenco di numeri triangolari ", ma non so cosa significherebbe.
Peter Taylor,

2
Quindi sono consentite funzioni integrate che accettano un argomento ne restituiscono un elenco dei primi nnumeri triangolari ? Sembra piuttosto mirato contro un linguaggio specifico, anche se non so quale.
Peter Taylor,

4
Vi esorto a revocare questa limitazione. Ti prometto che non migliorerà la qualità della risposta inter-lingua o l'equità nel modo in cui pensi.
Lynn,

Risposte:


8

05AB1E , 10 byte

Codice:

ÝηO3ãʒOQ}¬

Spiegazione:

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

Utilizza la codifica 05AB1E . Provalo online!


Ahhh ... Sì; lo farebbe.
Magic Octopus Urn,

7

Python 2 , 99 byte

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)

Provalo online!

Sono piuttosto sorpreso che sia più breve di itertools o una tripla comprensione delle liste! (Eventualmente) sputa una risposta casuale ogni volta che la esegui.

Due 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 sembra essere 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 per output casuale. :) Sono anche sorpreso che dia la soluzione più breve (finora).
Kevin Cruijssen,

Grazie mille per il metodo. Il corrispondente codice Ruby ha 57 byte.
Eric Duminil,

3

Gelatina , 12 byte

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

Provalo online!

Come funziona

0r+\œċ3S=¥Ðf   input: n
0r             [0 1 ... n]
  +\           cumsum
    œċ3        combinations of 3 elements, with repetition
          Ðf   filter on
       S          sum
        =         equals n

Si prega di prendere in considerazione l'aggiunta di una spiegazione .. =)
racer290,

2
@ racer290 fatto.
Leaky Nun,

3

Brachylog , 13 byte

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

Provalo online!

Come funziona

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

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

Questo produce il primo risultato in ordine lessicografico.

Provalo su MATL Online!

Spiegazione

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 byte

Grazie per aver permesso di produrre tutte le soluzioni, è stata una distrazione affascinante! Ero così felice di non aver bisogno di estrarre una soluzione ed essere in grado di dare loro tutto quello che non ho notato il costo che deriva dall'evitare soluzioni permutate. @L'osservazione di Lynn mi ha spiegato che mi ha permesso di salvare 7 byte.

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

Ciò lega numeri triangolari più che sufficienti le controlla tutte le combinazioni.


Abbandonare le a>=b,b>=ccondizioni e aggiungere semplicemente il suffisso !!0al codice è anche una risposta valida? Presentare tutte le soluzioni non ti aiuta davvero qui.
Lynn,

@Lynn Hai ragione, ovviamente, mi sono distratto. Grazie!
Christian Sievers,

2

Retina , 63 59 byte

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

Provalo online! Il link include casi di test. (1(?(1)\1))*è un comparatore di numeri triangolari generalizzato, ma per il primo numero triangolare possiamo salvare alcuni byte usando ^per la corrispondenza iniziale.


1

PHP , 351 byte

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

Provalo online!


1

Python 3 , 119 byte

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*

Provalo online!

Grazie a @WheatWizard per aver salvato 12 byte!


Il tuo map(e forse il tuo filtro) può essere scritto più breve come comprensione dell'elenco.
Wheat Wizard


@WheatWizard grazie per l'idea, non posso credere di non aver pensato a una comprensione della lista per ilmap
Chase Vogeli,

Gli oggetti filtro hanno un output perfettamente valido, ma se vuoi produrre un elenco puoi usare uno splat in questo modo[*filter(...)]
Wheat Wizard

1
Quello che avevo provato era (x,y,z) for x,y,z in...che è più lungo del tuo e l for l in...che probabilmente spiega questa differenza.
Chase Vogeli,

1

C / C ++ - 197 byte

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

Colpo per colpo:

#include<stdio.h>

Necessario per printf. Potrebbe essere eluito per alcune versioni di C

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

Salvaspazio per loop.

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

Valutatore di triangoli ricorsivi.

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

Questo ragazzo fa il sollevamento pesante. Tre cicli annidati per iterare a, b, c da 0 a n, notare che b e c ogni iterano dal valore precedente fino a n. Non è strettamente necessario tagliare l'iterazione in questo modo dal momento chereturn arrivo in un minuto risolve il problema "duplicato".

A livello interno, se la somma dei tre numeri del triangolo == il valore desiderato, stampa i triangoli e ritorna.

È possibile rimuovere legalmente la returnparola chiave e convertire il tipo restituito di c in void per salvare qualche byte in più e stampare tutte le possibili soluzioni. E 'per questo motivo che iterazioni sono limitati, se tutti i loop correvano da 0ad nesso causerebbe duplicati.


1

Mathematica, 63 byte

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

Con la sintassi infix e quel modo strabiliante di ottenere Firstche salva un enorme 2 byte , (t=#;#&@@Select[Table[i(i+1)/2,{i,0,t}]~Tuples~{3},Tr@#==t&])&per 62 byte.
numbermaniac,

Ottimo, lo modificherò
J42161217 il

0

CJam , 26 byte

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

Porta della mia risposta MATL. Questo è un blocco anonimo che prevede l'input nello stack e lo sostituisce con l'array di output.

Provalo online!


0

R , 66 byte

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

Algoritmo di forza bruta; legge nda stdin e restituisce un frame di dati in cui ogni riga è una combinazione di 3 numeri triangolari che si sommanon . Se necessario, posso restituire solo la prima riga per +4 byte.

Provalo online!


0

Java 8, 164 byte

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

Spiegazione:

Provalo qui.

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 byte

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

Spiegazione

x rappresenta l'input

while(a<=x)r.push(a=i++*i/2) Crea una matrice di tutti i numeri triangolari fino a x

Il forciclo stampa il numero triangolare più alto in meno di x, quindi sottrae quel numero da x, per tre iterazioni. (fondamentalmente un avido algoritmo)


Ho lo stesso problema che ho: prendendo il numero del triangolo più grande <= x ad ogni passo, non è garantito che tu abbia un numero di triangolo per il tuo terzo posto. Controlla la tua uscita per x = 103:91 + 10 + 1 = 102
asgallant

0

Pyth, 19 byte

Sono così fuori allenamento con Pyth, non è vero: /

hfqQsT.C*3+0msSdSQ3

Provalo qui .

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

È possibile salvare un byte tralasciando il selettore per il primo elemento dell'elenco perché è consentito stampare anche tutte le possibili soluzioni.
racer290,

@ racer290 Ancora meglio, anche se i risultati saranno nella forma [[a, b, c], [d, e, f]] - sarebbe ok?
Diceva il

@ racer290 In realtà, no, filtrare i duplicati non sarebbe libero dall'aspetto delle cose, quindi non sarebbe più breve: c
Sok


0

Ruby 61 57 55 byte

Ispirato dalla risposta Python di Lynn . Genera terzine casuali fino al raggiungimento della somma desiderata:

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

Richiede Ruby 2.4. In Ruby 2.3 e precedenti, è un errore di sintassi e Range#sumnon è definito. Questa versione più lunga (64 byte) è necessaria per Ruby 2.3:

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

Ecco un piccolo 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]

Provalo online con Ruby 2.3!


0

Javascript (ES6), 108 byte - risolto

Accetta un numero intero come input, genera un array [a, b, c]contenente un elenco ordinato di numeri di triangoli a + b + c = x, dove aè il numero di triangoli più grande minore o uguale all'input ed bè il numero di triangoli più grande minore o uguale all'input meno 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}

Spiegazione

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
}


Non stai spiegando la parte più interessante: perché è x-m-nun numero triangolare, cioè perché funziona?
Christian Sievers,

Bene dannazione, si scopre che non è garantito. Tutti i casi di test che ho usato sono appena successi per produrre una tripletta valida di numeri triangolari. Torna al tavolo da disegno.
incantato il

Risolto ora, meno soddisfatto di questa soluzione <; o (ma almeno funziona.
asgallant
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.