Svmmarivm
Dvae lectiones priores docvervnt qvid sit fvnctio et qvomodo data eivs intrent et exeant; haec docet decernere qvas fvnctiones scribere oporteat. Methodvs est expolitio gradatim: scribitvr main breve qvod fvnctiones nondvm exsistentes vocat, singvlas cvm pacto svo, et in singvlas descenditvr donec ad membra perveniatvr qvae pavcis versibvs scribvntvr. Lectio statvit criteria bonae interfaciei, regvlam «vna fvnctio, vnvm mvnvs» cvm signis qvae eivs violationem prodvnt, et svperonerationem, qvae idem nomen eidem mvneri in generibvs diversis dat. His criteriis algorithmos partis 4, qvi intra main vivebant, rescribit et singvlos seorsvm temptat. Notio qvae omnia conivngit est decompositio descendens: programma bene designatvm vt sva ipsivs specificatio legitvr.
Proposita discendi
- Qvaestionem in qvaestiones minores per expolitionem gradatim decomponere et arborem decompositionis scribere.
- Interfaciem cvivsqve fvnctionis (nomen, parametra, valorem redditvm et pactvm) designare anteqvam corpvs eivs scribatvr.
- Programma monolithicvm partis 4 vt complexvm fvnctionvm cohaerentivm rescribere, et singvlas seorsvm temptare per
maintentaminis. - Designationem aestimare secvndvm regvlam «vna fvnctio, vnvm mvnvs» et absentiam effectvvm occvltorvm.
- Fvnctionem svperonerare, praedicere qvam versionem qvaeqve vocatio eligat, et explicare cvr vocatio ambigva evadat.
Expolitio gradatim
Ab envntiato ad main pavcorvm versvvm
Programmata partis 4 tota intra main scripta svnt. Dvm in vno visorio continentvr, id toleratvr; sed programma dvcentorvm versvvm sic scriptvm postvlat vt omnia simvl in capite habeantvr, et solvm tentamen totivs admittit. Expolitio gradatim, sive designatio descendens, ordinem laboris invertit: primvm scribitvr qvid programma faciat, lingva qvaestionis, vt series vocationvm fvnctionvm qvae nondvm exsistvnt; deinde singvlae earvm fvnctionvm vt nova qvaestio, minor, svmvntvr, et ratio repetitvr donec ad fvnctiones tam simplices perveniatvr vt earvm corpvs sine vlla decompositione scribatvr.
Qvaestio seqvens exemplo inservit. Integer est perfectvs si svmma divisorvm eivs propriorvm (positivorvm qvi a differvnt) aeqvalis est , deficiens si minor est et abvndans si maior: perfectvs est; 8, cvm , deficiens est; 12, cvm , abvndans. Programma qvaeritvr qvod legat et svmmam divisorvm eivs propriorvm speciemqve eivs scribat. Primvs gradvs designationis est main, et ante omnia scribitvr:
#include <cstdint>#include <iostream>#include <print>#include <string>enum class Kind { deficient, perfect, abundant };// Svmma divisorvm positivorvm ipsivs n.// Praecondicio: n >= 1.// Postcondicio: reddit svmmam omnivm divisorvm positivorvm ipsivs n, ipso n inclvso.std::int64_t divisorSum(int n);// Species ipsivs n secvndvm svmmam divisorvm eivs propriorvm.// Praecondicio: n >= 1.// Postcondicio: reddit deficient, perfect vel abundant provt svmma minor, aeqvalis vel maior qvam n est.Kind classify(int n);// Nomen speciei, ad id scribendvm.// Praecondicio: nvlla.// Postcondicio: reddit «deficiens», «perfectvs» vel «abvndans».std::string kindName(Kind kind);int main(){ int n{}; std::cin >> n; std::println("Svmma divisorvm propriorvm nvmeri {}: {}", n, divisorSum(n) - n); std::println("{} est {}", n, kindName(classify(n)));}/usr/bin/x86_64-linux-gnu-ld.bfd: main.o: in function `main':main.cpp:27:(.text+0x22a): undefined reference to `divisorSum(int)'/usr/bin/x86_64-linux-gnu-ld.bfd: main.cpp:28:(.text+0x3fd): undefined reference to `classify(int)'/usr/bin/x86_64-linux-gnu-ld.bfd: main.cpp:28:(.text+0x40d): undefined reference to `kindName[abi:cxx11](Kind)'collect2: error: ld returned 1 exit statusProgramma sine vllo monito compilatvr, qvia qvaeqve vocatio cvm declaratione sva congrvit, qvod solvm compilator inspicit, vt lectio Fvnctiones docvit. Qvod deficit est conivnctio: conivnctor definitiones qvaerit neqve invenit (undefined reference, referentia indefinita; additamentvm [abi:cxx11] est nota interna GCC pro fvnctionibvs qvae std::string reddvnt). Hic statvs est prorsvs is designationis hoc loco: interfacies decretae svnt, corpora non. Si haec ita se habent, main iam vt specificatio programmatis legitvr, et tres declarationes svnt mvnera reliqva, singvla qvaestione originali minora.
Arbor decompositionis
Secvndvs gradvs in singvlas declarationes descendit. kindName est decisio trivm casvvm. classify nititvr divisorSum: nvmervs perfectvs est cvm svmma omnivm eivs divisorvm est . Et divisorSum est circvitvs divisorvm per paria lectionis Algorithmi nvmerici, qvi in consistit. Eventvs vt arbor delineatvr: radix est qvaestio tota; filii cvivsqve nodi, qvaestiones minores qvae evm solvvnt; folia, operationes qvas lingva iam praebet.
Figvra arborem gradatim explicat, eo ordine qvo designata est.
Demonstratio
Primvs gradvs est qvaestio tota,
maincommissa, qvae nondvm decomponitvr.Secvndvs gradvs est
mainqvinqve operationvm: legere, svmmare, classificare, nominare et scribere. Qvisqve nodvs est vocatio; vocationes bibliothecae iam exsistvnt, ceterae declaratae svnt et reliqvae.Tertivs gradvs
classifydecomponit, qvae nihil alivd facit qvamdivisorSumvocare et comparare. Eadem fvnctio bis in arbore apparet, et semel tantvm scribitvr: iterata adhibitio in arbore cernitvr anteqvam codex scribatvr.Vltimvs gradvs svnt folia: examen divisibilitatis et limes parivm, operationes lingvae. His attactis expolitio finitvr, qvia nihil decomponendvm restat.
Arbore perfecta, definitiones ab imo svrsvm scribvntvr, ita vt qvaeqve fvnctio aliis iam scriptis nitatvr:
#include <cstdint>#include <iostream>#include <print>#include <string>enum class Kind { deficient, perfect, abundant };// Svmma divisorvm positivorvm ipsivs n.// Praecondicio: n >= 1.// Postcondicio: reddit svmmam omnivm divisorvm positivorvm ipsivs n, ipso n inclvso.std::int64_t divisorSum(int n){ std::int64_t sum{0}; for (int d{1}; d <= n / d; ++d) { if (n % d == 0) { sum += d; if (d != n / d) { sum += n / d; } } } return sum;}// Species ipsivs n secvndvm svmmam divisorvm eivs propriorvm.// Praecondicio: n >= 1.// Postcondicio: reddit deficient, perfect vel abundant provt svmma minor, aeqvalis vel maior qvam n est.Kind classify(int n){ const std::int64_t proper{divisorSum(n) - n}; if (proper < n) { return Kind::deficient; } if (proper == n) { return Kind::perfect; } return Kind::abundant;}// Nomen speciei, ad id scribendvm.// Praecondicio: nvlla.// Postcondicio: reddit «deficiens», «perfectvs» vel «abvndans».std::string kindName(Kind kind){ if (kind == Kind::deficient) { return "deficiens"; } if (kind == Kind::perfect) { return "perfectvs"; } return "abvndans";}int main(){ int n{}; std::cin >> n; std::println("Svmma divisorvm propriorvm nvmeri {}: {}", n, divisorSum(n) - n); std::println("{} est {}", n, kindName(classify(n)));}28Svmma divisorvm propriorvm nvmeri 28: 2828 est perfectvsTres notae eventvs methodo debentvr. Primo, main non mvtatvm est cvm ea qvae infra svnt scriberentvr. Secvndo, svmma vt std::int64_t redditvr (ex <cstdint>, integer 64 bitvvm qvo etiam lectio Recvrsio vtitvr), qvia pro prope maximvm ipsivs int svmma divisorvm eivs id excedere potest, et id in interfacie decernere omnes vocantes tvetvr. Tertio, qvaeqve fvnctio seorsvm confirmatvr: divisorSum(28) 56 dare debet, divisorSum(1) 1 dare debet et divisorSum(36) 91 dare debet, vbi par semel tantvm nvmeratvr; vltima sectio lectionis has confirmationes in programma convertit.
Argvmentvm oneratvr…