Трикутні квадратні числа


11

Квадратні числа - це ті, які мають вигляд, n^2де n - ціле число. Вони також називаються ідеальними квадратами, тому що, коли ви берете їх квадратний корінь, ви отримуєте ціле число.

Перші 10 квадратних чисел: ( OEIS )

0, 1, 4, 9, 16, 25, 36, 49, 64, 81


Трикутні числа - це числа, які можуть утворювати рівносторонній трикутник. Число n-го трикутника дорівнює сумі всіх натуральних чисел від 1 до n.

Перші 10 трикутних чисел: ( OEIS )

0, 1, 3, 6, 10, 15, 21, 28, 36, 45


Квадратні трикутні числа - це числа, які є як квадратними, так і трикутними.

Перші 10 квадратних трикутних чисел: ( OEIS )

0, 1, 36, 1225, 41616, 1413721, 48024900, 1631432881, 55420693056, 1882672131025, 63955431761796


Існує нескінченна кількість квадратних чисел, трикутних чисел і квадратних трикутних чисел.

Напишіть програму або названу функцію, яка задає вхідне (параметр або stdin) число n, обчислює nтрикутне квадратне число і виводить / повертає його, де n - додатне ненулеве число. (Для n = 1 повернення 0)

Щоб програма / функція була дійсною подачею, вона повинна мати можливість повернути принаймні всі квадратні трикутники, менші за 2 ^ 31-1.

Бонус

-4 байти за можливість вивести всі квадратні трикутні числа менше 2 ^ 63-1

-4 байти для теоретичного виведення квадратних трикутних чисел будь-якого розміру.

+8 байт-покарання для рішень, які займають неполіномічний час.

Стек бонусів.

Це завдання з гольф-кодом, тож відповідь з найменшими байтами виграє.


Я додав 8-байтовий штраф за рішення, які потребують> O (n) часу, щоб зробити його більш справедливим для тих, хто прагне до швидшого коду.
rodolphito

@Rodolvertice Я не думаю, що ти маєш на увазі лінійний час. Ітераційне рішення, яке я маю, - це квадратичний час, тому що є nкроки, і на кожному кроці арифметика займає лінійний час, оскільки кількість цифр лінійно зростає в n. Я не думаю, що лінійний час можливий. Якщо ви не кажете, що арифметичні операції є постійним часом?
xnor

1
@Rodolvertice Я маю на увазі, що моє ітеративне рішення не є O (n). Я думаю, що найчистіша річ - це замість цього сказати "поліноміальний час". Якщо ви припускаєте лінійну арифметику часу, ви отримуєте дивні речі, як рішення, використовуючи експоненцію, яка називається постійним часом. Амортизація тут не грає.
xnor

1
люблю бачити щось подібне, позначене у найшвидшому коді
Abr001am

2
"Перші 10 квадратних трикутних чисел ..." Напевно ти мав на увазі 11? : P
Алекс А.

Відповіді:


8

CJam, 12 8 байт

XUri{_34*@-Y+}*;

Використовує відношення рецидивів із статті Вікіпедії.

Код завдовжки 16 байт і відповідає обом бонусам.

Спробуйте його в Інтернеті в інтерпретаторі CJam .

Як це працює

Мій код виявився ідентичним xnor у завжди в кожному аспекті, за винятком того, що я використовую стек CJam замість змінних.

XU               e# Push 1 and 0 on the stack.
                 e# Since 34 * 0 - 1 + 2 = 1, this compensates for 1-based indexing.
  ri{        }*  e# Do int(input()) times:
     _34*        e#   Copy the topmost integer and multiply it by 34.
         @-      e#   Subtract the bottommost integer from the result.
           Y+    e#   Add 2.
               ; e# Discard the last result.

Він працює миттєво для дуже великих входів, але понад 3000 він дає помилку діапазону Javascript на онлайн-перекладачі. Я збираюся спробувати це на реалізації Java.
rodolphito

@Rodolvertice: я перейшов до ітеративного підходу. Насправді це коротше і менш об'єм пам'яті.
Денніс

8

Пітон 2, 45 - 4 - 4 = 37

a=1;b=0
exec"a,b=b,34*b-a+2;"*input()
print a

Ітератує за допомогою рециркуляції

f(0) = 1
f(1) = 0
f(k) = 34*f(k-1)-f(k-2)+2

Теоретично це підтримує номери будь-якого розміру, але працює в експоненційному часі, тому воно не повинно претендувати на бонуси. Має працювати на номери будь-якого розміру. Наприклад, за 100, дає

1185827220993342542557325920096705939276583904852110550753333094088280194260929920844987597980616456388639477930416411849864965254621398934978872054025

Рекурсивне рішення використовує 41 знак, але не повинно кваліфікуватися, оскільки це займає експоненціальний час.

f=lambda k:k>2and 34*f(k-1)-f(k-2)+2or~-k

Це досить хитро, "петля" шляхом множення рядків, ха-ха.
rodolphito

@Rodolvertice: Насправді зовсім не шахрайство. Досить розумний і справді досить поширений на сайті.
Алекс А.

Я вважаю, що ваше рекурсивне рішення має право на отримання бонусу №1, який би його пов’язав із execрішенням. Якщо вам дозволяється змінювати обмеження рекурсії, то воно також може обчислити число квадратного трикутника будь-якого розміру, кваліфікуючи його для №2. Однак я не впевнений, чи відповідає це (@Rodolvertice).
Кейд

7

Pyth, 16 - 4 - 4 = 8 байт

Використовується рекурсивна формула зі статті OEIS.

K1uhh-*34G~KGtQZ

Він використовує команду після призначення, яка є доволі новою і здається дуже цікавою. Використання скорочується до ітераційного n-1часу через індексацію на основі 1.

K1            Set K=1
u       tQ    Reduce input()-1 times
         Z    With zero as base case
 hh            +2
  -           Subtract
   *34G       34 times iterating variable
   ~K         Assign to K and use old value
    G         Assign the iterating variable.

Здається, це многочлен, тому що він циклічно n разів і робить математику та призначення кожної ітерації, але я не комп'ютер. Завершує n = 10000 майже миттєво.

Спробуйте це онлайн .


Я думаю, ви можете уникнути віднімання 1 з вхідних даних, якщо ви почнете одну ітерацію назад на 0,1, а не на 1,0 - дивіться мою відповідь Python.
xnor

@xnor: Я думаю, що він це вже робить. Однак результат, повернений циклом, - це ваш b.
Денніс

5

Оазис , 7 - 4 - 4 = -1 (неконкурентоспроможний)

34*c-»T

Спробуйте в Інтернеті!

Використання a(0) = 0, a(1) = 1; for n >= 2, a(n) = 34 * a(n-1) - a(n-2) + 2

Oasis підтримує довільну точність цілих чисел, тому вона повинна мати можливість переходити до будь-якого числа до тих пір, поки не буде переповнено стек. Повідомте мене, якщо це не зараховується до бонусу через переповнення стека. Можливо також, що саме цей алгоритм є неодночленним, і дайте мені знати, чи це так.

Неконкурентований, оскільки мова ставить перед собою виклик.

Пояснення:

34*c-»T -> 34*c-»10

a(0) = 0
a(1) = 1
a(n) = 34*c-»

34*c-»
34*    # 34*a(n-1)
   c-  # 34*a(n-1)-a(n-2)
     » # 34*a(n-1)-a(n-2)+2

Альтернативне рішення:

-35*d+T

Натомість використовує a(n) = 35*(a(n-1)-a(n-2)) + a(n-3)


Питання говорить For n=1 return 0, але це повертає 1. Це можна виправити, додавши опцію -O .
Grimmy

4

JavaScript (ES6), 29-4 = 25 байт

n=>n>1?34*f(n-1)-f(n-2)+2:n|0

Збережено 5 байт завдяки @IsmaelMiguel !

Мені довелося жорстко кодувати 0, 1 і негативні елементи, щоб уникнути нескінченної рекурсії.

Консоль, я назвав функцію f:

f(1);  // 0
f(13); // 73804512832419600
f(30); // 7.885505171090779e+42 or 7885505171090779000000000000000000000000000

EDIT : Виявляється, JavaScript округлятиме числа до 16 (15) цифр (Spec), оскільки ці числа занадто великі, що викликає переповнення. Покладіть 714341252076979033 у свою консоль JavaScript і переконайтесь у цьому самі. Це більше обмеження JavaScript


Я не думаю, що це може бути бонусом. f(15)повинен повернутися 85170343853180456676, не 85170343853180450000.
Денніс

@Dennis JavaScript повинен бути обрізним. .-. Так, JavaScript округляє 16 цифр, коли
Пуховик,

Спробуйте це: n=>n?n<2?0:34*f(n-1)-f(n-2)+2:1(31 байт). Я тестував до 5-го числа.
Ісмаїл Мігель

1
Тут тепер є 29-байти рішення: n=>n>1?34*f(n-1)-f(n-2)+2:!!n. Він повертається falseна 0, trueна 1і 36на 2. Якщо ви хочете, щоб він повернув номер, його можна замінити !!nна +!!n.
Ісмаїл Мігель

1
Виправлена ​​проблема. Використовуйте це: n=>n>1?34*f(n-1)-f(n-2)+2:n|0(той самий підрахунок байтів, тепер повертає завжди цифри)
Ісмаель Мігель

3

Excel VBA - 90 байт

Використання відношення рецидиву зі сторінки Вікіпедії:

n = InputBox("n")
x = 0
y = 1
For i = 1 To n
Cells(i, 1) = x
r = 34 * y - x + 2
x = y
y = r
Next i

Коли буде виконано, вам буде запропоновано n, тоді послідовність до і включає n виводиться у стовпчик A:

вихід

Він може бути запущений до і включати n = 202, перш ніж він видасть помилку переповнення.


2

[Не змагається] Pyth (14 - 4 - 4 = 6 байт)

K1u/^tG2~KGQ36

Використовували перший рецидив від OEIS , що після 0,1,36 можна знайти A n = (A n-1 -1) 2 / A n-2 . A Не змагається, тому що це рішення починається з 36, якщо ви опускаєтесь нижче, ви ділите на нуль (тому введення 0 дає 36). Також довелося встановити жорсткий код 36.

Спробуйте тут


2

Java, 53 - 4 = 49 байт

Це ще одна проста рекурсія, але мені часто не доводиться публікувати Java з оцінкою <50, тож ...

long g(int n){return n<2?n<1?1:0:34*g(n-1)-g(n-2)+2;}

Тепер, для чого - то НЕ -recursive, він отримує зовсім небагато довше. Це одночасно довше (112-4 = 108) -і повільніше, тому я не знаю, чому я його публікую, окрім того, щоб мати щось ітеративне:

long f(int n){long a=0,b,c,d=0;for(;a<1l<<32&n>0;)if((c=(int)Math.sqrt(b=(a*a+a++)/2))*c==b){d=b;n--;}return d;}

2

Джулія, 51 байт - 4 - 4 = 43

f(n)=(a=b=big(1);b-=1;for i=1:n a,b=b,34b-a+2end;a)

Для цього використовується перше відношення рецидиву, вказане на сторінці Вікіпедії для квадратних трикутних чисел. Він обчислює n = 1000 за 0,006 секунд, а n = 100000 за 6,93 секунди. Це кілька байт більше , ніж рекурсивне рішення , але це спосіб швидше.

Недоліковані + пояснення:

function f(n)
    # Set a and b to be big integers
    a = big(1)
    b = big(0)

    # Iterate n times
    for i = 1:n
        # Use the recurrence relation, Luke
        a, b = b, 34*b - a + 2
    end

    # Return a
    a
end

Приклади:

julia> for i = 1:4 println(f(i)) end
0
1
36
1225

julia> @time for i = 1:1000 println(f(i)) end
0
... (further printing omitted here)
elapsed time: 1.137734341 seconds (403573226 bytes allocated, 38.75% gc time)

2

PHP, 65 59 56-4 = 52 байти

while($argv[1]--)while((0|$r=sqrt($s+=$f++))-$r);echo$s;

повторюйте, поки квадратний корінь $sє ∈ℤ: додайте $fдо суми $s, збільшення $f; рази
повторити $argv[1].
сума виводу


1

Пролог, 70 74 - 4 - 4 = 66

n(X,R):-n(X,0,1,R).
n(X,A,B,R):-X=0,R=A;Z is X-1,E is 34*B-A+2,n(Z,B,E,R).

Виконання n(100,R)результатів:

X = 40283218019606612026870715051828504163181534465162581625898684828251284020309760525686544840519804069618265491900426463694050293008018241080068813316496

n(10000,X)На моєму комп’ютері потрібно близько 1 секунди .

Редагувати : версія 66 - рекурсивна. Попередня рекурсивна версія:

n(X,[Z|R]):-X>1,Y is X-1,n(Y,R),R=[A,B|_],Z is 34*A-B+2;X=1,Z=1,R=[0];Z=0.

Вони мають однакову довжину в байтах, але без хвоста-рекурсивна генерує стек переповнює повз певну точку (на моєму комп’ютері близько 20500).


1

Javascript ES6, 77 75 71 символів

// 71 chars
f=n=>{for(q=t=w=0;n;++q)for(s=q*q;t<=s;t+=++w)s==t&&--n&console.log(s)}

// No multiplication, 75 chars
f=n=>{for(s=t=w=0,q=-1;n;s+=q+=2)for(;t<=s;t+=++w)s==t&&--n&console.log(s)}

// Old, 77 chars
f=n=>{for(s=t=w=0,q=-1;n;s+=q+=2){for(;t<s;t+=++w);s==t&&--n&console.log(s)}}
  • Рішення лінійне.
  • Рішення може виводити всі числа менше 2 ^ 53 через тип чисел.
  • Сам алгоритм можна використовувати для необмежених чисел.

Тест:

f(11)

0
1
36
1225
41616
1413721
48024900
1631432881
55420693056
1882672131025
63955431761796


1

Желе , 13 - 8 = 5 байт

Це кваліфікується для обох бонусів.

×8‘,µÆ²Ạ
0Ç#Ṫ

Спробуйте в Інтернеті!

У чаті поруч із птахом coinheringaahing .

Пояснення

× 8 ', µÆ²Ạ ~ Посилання помічника.

× 8 ~ 8 кратне число.
  '~ Приріст.
   , ~ У парі з поточним номером.
    µ ~ Починає нове монадичне (1-arg) посилання.
     Ʋ ~ Векторизований "Чи площа?".
       Ạ ~ Усі. Повертайте 1, лише якщо обидва є непростими.



0Ç # Ṫ ~ Головна посилання.

0 # ~ Починаючи з 0, збирайте перші N цілих чисел із результатами трити, коли застосовано:
 Ç ~ Останнє посилання як монада.
   Ṫ ~ Останній елемент. Висновок неявно.



0

APL (NARS), 67 символів, 134 байти

r←f w;c;i;m
c←0⋄i←¯1⋄r←⍬
→2×⍳0≠1∣√1+8×m←i×i+←1⋄r←r,m⋄→2×⍳w>c+←1

тест:

  f 10
0 1 36 1225 41616 1413721 48024900 1631432881 55420693056 1882672131025 

f шукатиме в квадратичній послідовності елементи, які є і трикутниками, тому вони повинні дотримуватися трикутної контрольної формули в APL: 0 = 1∣√1 + 8 × m з числом m для перевірки.

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