Три трикутні числа [закрито]


19

Опис

Раніше вже було чимало інших викликів щодо цих чисел, і я сподіваюся, що цього немає серед них.

П е трикутне число дорівнює сумі всіх натуральних чисел аж до п , прості речі. Є ціла сторінка Вікіпедії і запис в 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.
Ерік Попечитель

1
@steenbergh aне завжди буде трикутним числом
Феліпе Нарді Батіста

3
Я можу проаналізувати " вбудовані функції, щоб безпосередньо отримати масив, діапазон чи будь-яку іншу форму колекції, що містить список трикутних чисел " двома способами, але жоден з них не має сенсу. Перший забороняє всі вбудовані, які безпосередньо отримують масив, але це, здається, забороняє використання масивів на будь-якій мові, яку я знаю; інший забороняє вбудованим " безпосередньо отримувати ... діапазон ... містить список трикутних чисел ", але я не знаю, що це означатиме.
Пітер Тейлор

2
Так вбудовані функції , які приймають аргументи nі повертають список перших nтрикутних чисел є дозволені? Це відчувається досить орієнтованим на якусь конкретну мову, хоча я не знаю, на якій.
Пітер Тейлор

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]

виглядає це: 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

Дуже дякую за метод. Відповідний код Ruby має 57 байт.
Ерік Думініл



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 байт

Дякуємо, що дозволили виводити всі рішення, це було захоплююче відволікання! Я був такий щасливий, що не потрібно витягувати одне рішення і міг просто дати їм усе, що я не помітив витрат, що виникають у зв'язку з уникненням перестановлених рішень. @ Зауваження Лінн пояснило це мені і дозволить мені зберегти 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до вашого коду також є вірною відповіддю? Виведення всіх рішень насправді вам тут не допомагає.
Лінн

@Lynn Ви маєте рацію, звичайно, я відволікався. Спасибі!
Крістіан Сіверс

2

Сітківка , 63 59 байт

.+
$*
^((^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(а може бути і ваш фільтр) може бути записаний коротше як розуміння списку.
Пшеничний майстер


@WheatWizard дякую за ідею, я не можу повірити, що я не думав про розуміння списку для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

Математика, 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



0

R , 66 байт

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

Алгоритм грубої сили; читає nз stdin і повертає кадр даних, де кожен рядок - це комбінація трьох трикутних чисел, до яких додається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]] - чи все в порядку?
Сок

@ racer290 Власне, ні, фільтрація дублікатів не буде вільною за виглядом речей, тому вона не буде коротшою: c
Sok


0

Ruby 61 57 55 байт

Натхненний Python Лінн відповідь . Він генерує випадкові трійні, поки не буде досягнута бажана сума:

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

Для цього потрібен Ruby 2.4. У Ruby 2.3 і пізніших версіях це синтаксична помилка і Range#sumне визначена. Для Ruby 2.3 потрібна ця довша версія (64 байти):

->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 байт - виправлено

Бере ціле число як вхід, виводить масив, [a, b, c]що містить впорядкований список номерів трикутників a + b + c = x, де aнайбільше число трикутника менше або дорівнює вводу, і bє найбільшим числом трикутника, меншим або рівним вхідному мінусу 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}

Пояснення

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трикутне число, тобто чому це працює?
Крістіан Сіверс

Що ж, Dangit, виявляється, це не гарантується. Усі тестові випадки, які я використовував, просто траплялися для отримання дійсної триплети чисел із трикутників. Назад до дошки для малювання.
asgallant

Виправлено зараз, менш задоволений цим рішенням <; o (але, принаймні, воно працює.
asgallant
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.