Hogyan kell barátságos számokat keresni free pascal-ban?
idái jutottam el, és nem tudom, hol rontom el:
Program baratsagos;
Uses crt;
Var i,j,y:word;
szam1,szam2:word;
Begin
Szam1:=0;
Szam2:=0;
For i:=1 to 10000 do
for j:=1 to i div 2 do
Begin
If i mod j = 0 then
szam1:= szam1+j;
for y:=1 to szam1 div 2 do
if szam1 mod y =0 then
Szam2:=szam2+y;
If i = szam2 then Writeln(i,' ',szam2);
End;
End.
A ciklus feltételnél most "változó div 2" szerepel, ezt kell
lecserélni gyök(változó) függvényre. (odafigyelve, hogy a gyök(változó) valós eredményt ad, abból int-et kell csinálni.
https://hastebin [dot] com/ixizoweyul.php
Itt meg a kimenete:
220 - 284
1184 - 1210
2620 - 2924
5020 - 5564
6232 - 6368
#1 "Miért i div 2-ig mész? Gyök(i)-ig kell menni az adja meg az osztókat. Egy kis matek tudás nem ártana..."
Ez így nem igaz. A szám gyökéig bezárólag csak az osztók felét kapod meg, de ha az összes osztót fel akarod sorolni, akkor az a szám feléig tart. A 10-nek tán nem osztója az 5? Persze csinálhatod azt, amit az előző kolléga, és ha osztót találsz, az osztás elvégzésével megkapod a párját is, ebben az esetben elég gyökig menni, de ez a végeredményen nem változtat, legfeljebb optimálisabb.
"Nyilván mindkét helyen ezt javítani kell. Ez biztosan hiba, de lehet benne máshol hiba, de ez egyből észrevehető."
Nem, ez nem hiba, maximum kevésbé hatékony. A végeredményen nem változtat. Ahhoz képest hogy a matektudást emlegeted, nem nagyon sikerül eltalálni a dolgokat.
Az elképzeléssel nincs különösebb gond, csak a megvalósítással.
A legfőbb, végzetes hiba: Nem elég a program elején nullázni a szam1 és szam2 változókat. Most a belső ciklusokban nem nulla kezdőértékkel indulnak, hanem az előzőleg bent felejtett értékekkel, ami tökéletesen értelmetlenné teszi a további ügyeskedést. Tehát a külső ciklus minden lefutásakor, még a belsők indítása előtt állítsd őket nullára.
Második, fontos hiba: A belső ciklusok közül az első megkeresi neked a reménybeli barátságos számot, a második pedig ellenőrzi, hogy valóban az-e. Az utána következő if i = szam2 vizsgálat ennek megfelelően szam1 barátságos szám mivoltát igazolta, vagyis azt kell az i mellé kiíratnod, nem pedig az i-vel garantáltan megegyező szam2-t:
if i = szam2 then WriteLn(i, ' ', szam1);
Harmadik, kevésbé lényeges hiba: A vizsgálat során adódnak olyan számok, amelyek megegyeznek az osztóik összegével (6, 28, 496, 8128). Ilyenkor az eredmény megegyezik az eredeti számmal, vagyis fölösleges kiíratni, hiszen valójában semmiféle barátságos számot nem találtál.
Negyedik, ami nem is hiba, hanem lényegtelen apróság: Az y változó szükségtelen, a második belső ciklusban is használhatod a j-t.
+ Ja! Itt a fentiek szerint módosított programod kimenete – nem olyan szép, mint a kollégáé, mert az algoritmus egyszerűségéért cserébe a párok megfordítását is kiírja:
220 --> 284
284 --> 220
1184 --> 1210
1210 --> 1184
2620 --> 2924
2924 --> 2620
5020 --> 5564
5564 --> 5020
6232 --> 6368
6368 --> 6232
Bizony, Kérdező példát vehetne a barátságos számokról...
Közben annyit módosítottam a programon, hogy egy tömbben tárolja a megtalált számokat, és azoknak már nem keresi a párját. A mostani kimenet, ötszázezerig:
220 ❤ 284
1184 ❤ 1210
2620 ❤ 2924
5020 ❤ 5564
6232 ❤ 6368
10744 ❤ 10856
12285 ❤ 14595
17296 ❤ 18416
63020 ❤ 76084
66928 ❤ 66992
67095 ❤ 71145
69615 ❤ 87633
79750 ❤ 88730
100485 ❤ 124155
122265 ❤ 139815
122368 ❤ 123152
141664 ❤ 153176
142310 ❤ 168730
171856 ❤ 176336
176272 ❤ 180848
185368 ❤ 203432
196724 ❤ 202444
280540 ❤ 365084
308620 ❤ 389924
319550 ❤ 430402
356408 ❤ 399592
437456 ❤ 455344
469028 ❤ 486178
Kapcsolódó kérdések:
Minden jog fenntartva © 2025, www.gyakorikerdesek.hu
GYIK | Szabályzat | Jogi nyilatkozat | Adatvédelem | Cookie beállítások | WebMinute Kft. | Facebook | Kapcsolat: info(kukac)gyakorikerdesek.hu
Ha kifogással szeretne élni valamely tartalommal kapcsolatban, kérjük jelezze e-mailes elérhetőségünkön!