Triangular number rozwiązanie równania

Triangular number rozwiązanie równania
GO
  • Rejestracja:około 6 lat
  • Ostatnio:około miesiąc
  • Postów:92
0

Witam

mam do rozwiązania zadanie
Triangular number jest liczbą punktów, która może wypełnić trójkąt równoboczny. Np liczba 6 jest taką liczbą bo trójkat zbudowany z takiej liczby punktów jest równoboczny. Ogólnie problem sprowadza się do rozwiązania równania T(n) = n * (n + 1) / 2, gdzie T(n) jest daną szukaną zaś jest n. Poniżej moje rozwiązanie:

Kopiuj
#include <stdbool.h>

bool is_triangular(int t) {
unsigned long long int delta = 1+8*t;
double x1=(-1-sqrt(delta))/2.0;
  if(x1>0&&floor(x1)==x1)
    return true;  
double x2=(-1+sqrt(delta))/2.0;
    if(x2>0&&floor(x2)==x2)
      return true;
return false;
}

Program przechodzi wszystkie test a wykrzacza mi się na t == 458000245 i t == 1979494660
Nie wiem gdzie jest bład

Shalom
  • Rejestracja:około 21 lat
  • Ostatnio:prawie 3 lata
  • Lokalizacja:Space: the final frontier
  • Postów:26433
1

Czyli mamy funkcje f(x) = 1/2 * x^2 +1/2 * x - t i szukamy dla niej miejsca zerowego.
delta = b^2 - 4ac = 1/4 + 4*1/2*T(n) = 1/4 + 2*T(n)
Skąd u ciebie delta=1+8*t to nie wiem.


"Nie brookliński most, ale przemienić w jasny, nowy dzień najsmutniejszą noc - to jest dopiero coś!"
TomaszLiMoon
delta jest wyliczana z równania f(x) = x^2 + x - 2t, które posiada takie same pierwiastki jak równanie f(x) = 1/2 * x^2 +1/2 * x - t. I chodź delta będzie się w tym przypadku różniła, to dla każdego t będącego liczbą trójkątną, pierwiastek z delty musi być liczbą całkowitą.
Shalom
No ok ale OP mógl w takim razie napisać jasno że szuka pierwiastków f(x) = x^2 + x - 2t a nie kombinować ;)
lion137
  • Rejestracja:około 8 lat
  • Ostatnio:minuta
  • Postów:4924
0

@gonskabalbinka:
Musisz policzyć pierwiastek całkowity z 1 + 8*Tn, z założenia istnieje, więc pierwiastek z delty znajdujesz:

Kopiuj
unsigned long long sqrt_delta(unsigned long long n) {
    return   (unsigned long long) sqrt(1 + 8 * n);
}

W ten sposób double jest zamkniete w funkcji, a resztę robisz na inegerach.
Edycja: Wtedy rozwiąznie:

Kopiuj
unsigned long long solution(unsigned long long n) {
    return (-1 + sqrt_delta(n)) / 2;
}

https://www.wolframalpha.com/input/?i=1979494660+triangular+number


edytowany 3x, ostatnio: lion137
_13th_Dragon
  • Rejestracja:ponad 19 lat
  • Ostatnio:3 miesiące
0
gonskabalbinka napisał(a):
Kopiuj
double x1=(-1-sqrt(delta))/2.0;
  if(x1>0&&floor(x1)==x1)

Wynik funkcji sqrt(delta) zawsze będzie dodatni.
Stad -1-sqrt(delta) zawsze będzie ujemne.
Proszę o wytłumaczenie czemu się spodziewasz że x1>0 może być prawdą?

Poza tym nie należy się spodziewać że wyrażenie floor(x1)==x1 będzie prawdą w związku z niedokładnością obliczeń.


Wykonuję programy na zamówienie, pisać na Priv.
Asm/C/C++/Pascal/Delphi/Java/C#/PHP/JS oraz inne języki.
GO
Po Twoim wytłumaczeniu nie spodziewam się. Nie przemyślałem
_13th_Dragon
  • Rejestracja:ponad 19 lat
  • Ostatnio:3 miesiące
0
Kopiuj
unsigned long long int delta=0.25+0.5*t; // (1/4 + 2*t)/4
double x=sqrt(delta)-0.5;

Wykonuję programy na zamówienie, pisać na Priv.
Asm/C/C++/Pascal/Delphi/Java/C#/PHP/JS oraz inne języki.
edytowany 1x, ostatnio: _13th_Dragon
koszalek-opalek
  • Rejestracja:około 9 lat
  • Ostatnio:ponad 2 lata
0

Niedokładności w IEEE 754.

Bardzo często pomijane przez programistów, a przy dużych liczbach wyraźnie widoczne, bo cyfry znaczące kończą się już przed przecinkiem...

Łatwo sprawdzić w językach, które pozwalają na całkowicie dokładnie obliczenia na dowolnie dużych liczbach całkowitych (jak Python czy Haskell). Na przykład, wziąłem Twoje t == 458000245 i w Pythonie dostaję coś takiego:

Kopiuj
>>> 458000245**2 == 458000245.0**2
False
>>> 458000245**2
209764224420060025
>>> 458000245.0**2
2.0976422442006003e+17

Więc tego rodzaju programy nie mają szans działać dokładnie dla dużych liczb jeśli robisz jakiekolwiek obliczenia w IEEE 754. Jak to mówią: "Komputer nie nadaje się do obliczeń". :)

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.