ការរាប់៖ Permutation និង Combination
មាតិកា
- រាប់ដោយមិនរាយបញ្ជី
- Rule of Product
- PIN និង Password៖ ការរាប់ String
- Factorial៖ ការរាប់លំដាប់
- Permutation៖ លំដាប់សំខាន់
- Combination៖ លំដាប់មិនសំខាន់
- ហេតុអ្វី Brute Force ផ្ទុះ
- BigInt សម្រាប់ចំនួនធំៗ
- Pagination និង Batching
- រូបមន្ត៖ Module counting
- សាកល្បងដោយខ្លួនឯង
1. រាប់ដោយមិនរាយបញ្ជី
តើមាន PIN 4 ខ្ទង់ខុសៗគ្នាប៉ុន្មាន? អ្នកអាចសរសេរវាទាំងអស់ចេញមក៖
0000, 0001, 0002 ហើយបន្តទៅទៀត។ វាអាចធ្វើបាន ប៉ុន្តែយឺត ហើយចំពោះសំណួរធំជាងនេះ ("password 8 តួអក្សរមានប៉ុន្មាន?") វាមិនអាចធ្វើទៅរួចទេ។
ការរាប់គឺជាជំនាញគណិតវិទ្យាក្នុងការទទួលបាន ចំនួន នៃលទ្ធភាព
ដោយមិនចាំបាច់បង្កើតបញ្ជីឡើយ។
អ្នកសរសេរកម្មវិធីត្រូវការវាញឹកញាប់ជាងអ្វីដែលអ្នកស្មាន៖
- តើទ្រង់ទ្រាយ password មួយរឹងមាំប៉ុនណា ហើយអ្នកវាយប្រហារត្រូវការពេលប៉ុន្មាន?
- តើ form ដែលមាន dropdown ប្រាំ ពិតជាមាន test case ប៉ុន្មាន?
- តើតារាងត្រូវការប៉ុន្មានទំព័រ ប្រសិនបើវាបង្ហាញម្តង 10 ជួរ?
- តើ loop "សាកល្បងគ្រប់ការផ្សំ" នឹងចប់នៅថ្ងៃនេះ ឬក្រោយពេលព្រះអាទិត្យរលត់?
សំណួរចុងក្រោយភ្ជាប់ដោយផ្ទាល់ទៅនឹង
Function, ការលូតលាស់ និង Logarithm
និង សញ្ញា Big-O។
ការរាប់ប្រាប់អ្នកថា n ធំប៉ុនណា។ Big-O ប្រាប់ថាវាធ្វើអ្វីដល់
កូដរបស់អ្នក។
2. Rule of Product
ច្បាប់តែមួយនៅពីក្រោយស្ទើរតែគ្រប់យ៉ាងក្នុងជំពូកនេះគឺ rule of product៖ ប្រសិនបើអ្នកធ្វើជម្រើសជាច្រើនបន្តបន្ទាប់គ្នា ចំនួនលទ្ធផលសរុប គឺជាចំនួនជម្រើសនៃការជ្រើសរើសនីមួយៗ គុណ គ្នា។
ហាងកាហ្វេតូចមួយផ្តល់ឈុតអាហារថ្ងៃត្រង់៖
- មុខម្ហូបមេ 3 (បាយឆា មី អាម៉ុក)
- ភេសជ្ជៈ 2 (តែទឹកកក កាហ្វេ)
- បង្អែម 4
const mains = 3;
const drinks = 2;
const desserts = 4;
console.log(mains * drinks * desserts); // 24
មានឈុតអាហារថ្ងៃត្រង់ខុសៗគ្នា 24។ ហេតុអ្វីគុណ មិនមែនបូក? ជ្រើសបាយឆាមុន៖
វាអាចទៅជាមួយភេសជ្ជៈ 2 ហើយភេសជ្ជៈនីមួយៗអាចទៅជាមួយបង្អែម 4
ដូច្នេះបាយឆាតែមួយមុខមាន 8 ឈុត។ មីមាន 8 ទៀត អាម៉ុកមាន 8 ទៀត៖
8 + 8 + 8 = 24។ ការគុណគ្រាន់តែជាផ្លូវកាត់នៃការបូកម្តងហើយម្តងទៀតនោះ។
ប្រើ ការបូក នៅពេលជម្រើសជាជម្រើសជំនួស ("មុខម្ហូបមេ ឬ ភេសជ្ជៈ") និង ការគុណ នៅពេលអ្នកធ្វើរឿងមួយ ហើយបន្ទាប់មក រឿងមួយទៀត។
គំនិតដូចគ្នានេះរាប់ form ។ ទំព័រចុះឈ្មោះដែលមាន dropdown ប្រទេស (200
ជម្រើស) dropdown ភាសា (10 ជម្រើស) និងប៊ូតុង radio ផែនការ (3
ជម្រើស) មាន 200 * 10 * 3 = 6,000 ការផ្សំនៃ input។ គ្មាននរណាសាកល្បងទាំងអស់ដោយដៃទេ
ប៉ុន្តែឥឡូវអ្នកដឹងទំហំនៃបញ្ហាហើយ។
3. PIN និង Password៖ ការរាប់ String
String ដែលមានប្រវែងថេរ ដែលគ្រប់ទីតាំងត្រូវបានបំពេញដោយឯករាជ្យ
ពីសំណុំនិមិត្តសញ្ញាតែមួយ គឺជា rule of product ក្នុងទម្រង់សាមញ្ញបំផុត។
ប្រសិនបើមាននិមិត្តសញ្ញា s ដើម្បីជ្រើសរើស និងទីតាំង L ចំនួននោះគឺ៖
s * s * s * ... (L times) = s ^ L
^ នៅទីនេះមានន័យថា "ស្វ័យគុណ" ដែល JavaScript សរសេរជា **។ នៅទីនេះ
s ** L មានន័យថា "គុណ s នឹងខ្លួនវា L ដង"។ PIN 4 ខ្ទង់មាន 10
និមិត្តសញ្ញា (0-9) និង 4 ទីតាំង៖
console.log(10 ** 4); // 10000
console.log(10 ** 6); // 1000000
ដូច្នេះមាន PIN 4 ខ្ទង់ចំនួន 10,000 និង PIN 6 ខ្ទង់ចំនួន 1,000,000។ ការបន្ថែម ពីរខ្ទង់ធ្វើឲ្យចន្លោះធំជាងមុន 100 ដង ពីព្រោះទីតាំងថ្មីនីមួយៗ គុណចំនួននឹង 10។
នេះជា alphabet របស់ password ដែលនិយមប្រើ៖
| Alphabet | និមិត្តសញ្ញា |
|---|---|
| ខ្ទង់ | 10 |
| អក្សរតូច | 26 |
| អក្សរតូច + អក្សរធំ | 52 |
| អក្សរ + ខ្ទង់ | 62 |
| គ្រប់គ្រាប់ចុច ASCII ដែលអាចបោះពុម្ពបានលើក្តារចុច | ប្រហែល 94 |
Password 8 តួអក្សរដែលធ្វើពីអក្សរ និងខ្ទង់ មាន 62 ** 8 លទ្ធភាព។
តោះគណនាវា៖
console.log(62 ** 8); // 218340105584896
console.log(26 ** 8); // 208827064576
នោះប្រហែល 218 ទ្រីលាន ប្រៀបធៀបនឹង 209 ពាន់លាន។ ការអនុញ្ញាតឲ្យមានអក្សរធំ និងខ្ទង់ ធ្វើឲ្យចន្លោះធំជាងមុនប្រហែល 1,000 ដង។ ជាទូទៅ ការបន្ថែម ប្រវែង ជួយច្រើនជាងការបន្ថែម និមិត្តសញ្ញា ពីព្រោះប្រវែងគឺជា exponent។
4. Factorial៖ ការរាប់លំដាប់
ឥឡូវជាសំណួរផ្សេង។ អ្នកមានមិត្តភក្តិ 3 នាក់ គឺដារា សុភា និងវីរៈ ហើយអ្នកចង់ឲ្យពួកគេឈរតម្រៀបជួរថតរូប។ តើមានលំដាប់ប៉ុន្មាន?
- មាន 3 ជម្រើសសម្រាប់អ្នកឈរទីមួយ។
- បន្ទាប់មកនៅសល់ 2 នាក់សម្រាប់កន្លែងទីពីរ។
- បន្ទាប់មកនៅសល់ 1 នាក់សម្រាប់កន្លែងចុងក្រោយ។
Rule of product៖ 3 * 2 * 1 = 6។ លំដាប់ទាំងប្រាំមួយគឺ DSV, DVS, SDV, SVD,
VDS, VSD។
ការគុណចំនួនមួយនឹងគ្រប់ចំនួនគត់ដែលតូចជាងវារហូតដល់ 1 ត្រូវបានហៅថា
factorial សរសេរជា n! ហើយអានថា "n factorial"៖
| n | n! | ការគណនា |
|---|---|---|
| 0 | 1 | កំណត់ជា 1 (មានវិធីតែមួយក្នុងការតម្រៀបអ្វីទាំងអស់) |
| 1 | 1 | 1 |
| 2 | 2 | 2 * 1 |
| 3 | 6 | 3 * 2 * 1 |
| 4 | 24 | 4 * 3 * 2 * 1 |
| 5 | 120 | 5 * 4 * 3 * 2 * 1 |
| 10 | 3,628,800 |
សូមកត់សម្គាល់ថាវាលូតលាស់លឿនប៉ុនណា។ មនុស្សដប់នាក់អាចឈរតម្រៀបជួរបានជាងនៅ
3.6 លានលំដាប់ខុសៗគ្នា។ យើងនឹងសរសេរ factorial នៅក្នុងរូបមន្ត
នៅចុងជំពូកនេះ។
5. Permutation៖ លំដាប់សំខាន់
ការប្រណាំងមួយមានអ្នករត់ 8 នាក់ ហើយ 3 នាក់ដំបូងទទួលបានមាស ប្រាក់ និងសំរិទ្ធ។ តើអាចមាន podium ខុសៗគ្នាប៉ុន្មាន?
- 8 ជម្រើសសម្រាប់មាស។
- នៅសល់ 7 សម្រាប់ប្រាក់។
- នៅសល់ 6 សម្រាប់សំរិទ្ធ។
console.log(8 * 7 * 6); // 336
នេះគឺជា permutation៖ ការជ្រើសរើសធាតុ k ពី n ដែល លំដាប់
សំខាន់ (មាស ប្រាក់ សំរិទ្ធ ខុសពី សំរិទ្ធ ប្រាក់ មាស)។
អ្នកគុណតែ k តួដំបូងនៃ factorial៖
P(n, k) = n * (n-1) * ... * (n-k+1) = n! / (n-k)!
P(8, 3) = 8! / 5! = 336។ / (n-k)! គ្រាន់តែលុបកន្ទុយនៃ
ការគុណវែងដែលអ្នកមិនត្រូវការចោល។
នៅពេល k ស្មើនឹង n (តម្រៀបគ្រប់គ្នា) អ្នកទទួលបាន factorial ធម្មតា៖
P(5, 5) = 5! = 120។
ការប្រើប្រាស់ជាក់ស្តែង៖ ចំនួនវិធីក្នុងការចាត់ថ្នាក់លទ្ធផលស្វែងរក ចាត់កៅអី ឬ ជ្រើសរើសប្រធាន អនុប្រធាន និងហិរញ្ញិកពីក្រុមមួយ។
6. Combination៖ លំដាប់មិនសំខាន់
ឥឡូវជាឆ្នោត។ អ្នកជ្រើសលេខ 6 ពី 49 ហើយលំដាប់ដែលអ្នកជ្រើសមិន
សំខាន់ទេ។ ការជ្រើស 3, 17, 22, 30, 41, 48 គឺជាសំបុត្រដូចគ្នានឹង
48, 41, 30, 22, 17, 3។
នេះគឺជា combination៖ ការជ្រើសរើសធាតុ k ពី n ដែលលំដាប់
មិន សំខាន់។ វាត្រូវបានសរសេរជា C(n, k) ហើយអានថា "n choose k"។
តើយើងទទួលបានវាដោយរបៀបណា? ចាប់ផ្តើមពី permutation ដែលរាប់គ្រប់លំដាប់
ដោយឡែកពីគ្នា បន្ទាប់មកចែកនឹងចំនួនវិធីតម្រៀបធាតុ k ដែលបានជ្រើស
(k!) ពីព្រោះលំដាប់ទាំងនោះរាប់ជាការជ្រើសរើសតែមួយដូចគ្នា៖
C(n, k) = P(n, k) / k! = n! / (k! * (n-k)!)
ការត្រួតពិនិត្យតូចមួយ៖ ជ្រើសមនុស្ស 2 នាក់ពី A, B, C, D។
Permutations: AB BA AC CA AD DA BC CB BD DB CD DC (12)
Combinations: AB AC AD BC BD CD (6)
P(4, 2) = 12 ហើយ 12 / 2! = 6។ គូនីមួយៗត្រូវបានរាប់ពីរដង ម្តងក្នុងមួយ
លំដាប់ ដូច្នេះការចែកនឹង 2 ដោះស្រាយបាន។
| សំណួរ | លំដាប់សំខាន់ទេ? | ឈ្មោះ | រូបមន្ត |
|---|---|---|---|
| Podium 3 នាក់ពីអ្នករត់ 8 នាក់ | បាទ/ចាស | Permutation | P(8,3) = 336 |
| ជ្រើសក្រុម 3 នាក់ពីមនុស្ស 8 នាក់ | ទេ | Combination | C(8,3) = 56 |
| ឆ្នោត៖ លេខ 6 ពី 49 | ទេ | Combination | C(49,6) = 13,983,816 |
| PIN 4 ខ្ទង់ | បាទ/ចាស អនុញ្ញាតឲ្យដដែល | Power | 10 ** 4 |
ការសាកល្បងសាមញ្ញ៖ តើការប្តូរការជ្រើសពីរ បង្កើតលទ្ធផលផ្សេងឬទេ? បើ បាទ/ចាស វាជា permutation។ បើទេ វាជា combination។
Combination ក៏លេចឡើងក្នុងការធ្វើតេស្តដែរ៖ ប្រសិនបើអ្នកមាន feature 20 ហើយចង់
តេស្តគ្រប់ គូ របស់វាជាមួយគ្នា អ្នកត្រូវការតេស្តគូ C(20, 2) = 190។
វាក៏រាប់ "ការចាប់ដៃ" ដែរ៖ ក្នុងកិច្ចប្រជុំមនុស្ស n នាក់ដែលគ្រប់គ្នា
ជំរាបសួរគ្នា មានការចាប់ដៃ C(n, 2) ដែលជា
n * (n - 1) / 2។ នោះគឺជារូបរាងដូចគ្នាបេះបិទនឹង nested loop ក្នុង
សញ្ញា Big-O ដែលជា
មូលហេតុដែល nested loop ត្រូវបានហៅថា O(n²)។
7. ហេតុអ្វី Brute Force ផ្ទុះ
Brute force មានន័យថាសាកល្បងគ្រប់លទ្ធភាពរហូតដល់មួយដំណើរការ។ ការរាប់ ប្រាប់អ្នកថាតើវាប្រាកដនិយមឬអត់។ ឧបមាថាកុំព្យូទ័រអាចពិនិត្យការទាយមួយ ពាន់លាន (1,000,000,000) ក្នុងមួយវិនាទី។ យើងប្រើចំនួនខាងលើ៖
| អ្វីដែលអ្នកកំពុងទាយ | លទ្ធភាព | ពេលវេលាក្នុងល្បឿន 1 ពាន់លាន/វិនាទី |
|---|---|---|
| PIN 4 ខ្ទង់ | 10,000 | 0.00001 វិនាទី |
| អក្សរតូច 8 (26⁸) | ប្រហែល 209 ពាន់លាន | ប្រហែល 3.5 នាទី |
| អក្សរ + ខ្ទង់ 8 (62⁸) | ប្រហែល 218 ទ្រីលាន | ប្រហែល 2.5 ថ្ងៃ |
| តួអក្សរដែលអាចបោះពុម្ពបាន 12 (94¹²) | ប្រហែល 4.8 x 10²³ | ប្រហែល 15 លានឆ្នាំ |
| តម្រៀបធាតុ 15 (15!) | 1.3 ទ្រីលាន | ប្រហែល 22 នាទី |
| តម្រៀបធាតុ 20 (20!) | 2.4 x 10¹⁸ | ប្រហែល 77 ឆ្នាំ |
គួរញែករូបរាងនៃការលូតលាស់ទាំងពីរចេញពីគ្នា។
- Exponential ដូច
s ** L៖ តួអក្សរបន្ថែមនីមួយៗគុណការងារ នឹងs។ ប្រវែងគឺជាមិត្តរបស់អ្នក ក្នុងនាមជាអ្នកការពារ។ - Factorial ដូច
n!៖ ធាតុបន្ថែមនីមួយៗគុណការងារនឹងnថ្មី។ នេះលូតលាស់លឿនជាង exponential ទៅទៀត។
នេះគឺជាមូលហេតុពិតដែល PIN 4 ខ្ទង់លើទូរស័ព្ទត្រូវបានការពារដោយ "រង់ចាំ 30 វិនាទីបន្ទាប់ពីព្យាយាមច្រើនដង" មិនមែនដោយទំហំរបស់វាទេ។ ជាមួយនឹងលទ្ធភាពតែ 10,000 ទំហំតែម្យ៉ាងមិនអាចការពារវាបានទេ។ ការពន្យារពេលទើបអាច។
ក៏សូមកត់សម្គាល់ជួរ factorial ដែរ៖ "សាកល្បងគ្រប់លំដាប់" ល្អសម្រាប់ធាតុ 10 ហើយ គ្មានសង្ឃឹមសម្រាប់ 20។ បញ្ហាដូចជាការរកផ្លូវខ្លីបំផុតដែលដើរកាត់ទីក្រុងច្រើន ជួបជញ្ជាំងនេះ ហើយនោះជាមូលហេតុមួយដែលអ្នកសរសេរកម្មវិធីបង្កើត algorithm ឆ្លាតជាងជំនួសឲ្យ brute force។ អ្នកនឹងជួបការគិតបែបនេះម្តងទៀតក្នុង ស៊េរី Data Structures & Algorithms ដែលបានគ្រោងទុក។
8. BigInt សម្រាប់ចំនួនធំៗ
ឥឡូវជាបញ្ហាជាក់ស្តែង។ សាកល្បង factorial នៃ 25 ជាមួយចំនួនធម្មតា៖
let result = 1;
for (let i = 2; i <= 25; i++) {
result *= i;
}
console.log(result); // 1.5511210043330986e+25
JavaScript បោះពុម្ពវាជា scientific notation ហើយវាលែងត្រឹមត្រូវពិតប្រាកដទៀតហើយ។ ដូចដែលអ្នកបានឃើញក្នុង
Integer, Overflow និងភាពជាក់លាក់
number ធម្មតាត្រឹមត្រូវពិតប្រាកដតែរហូតដល់ Number.MAX_SAFE_INTEGER ដែល
ជា 9007199254740991 (ប្រហែល 9 ក្វាទ្រីលាន)។ បញ្ហារាប់ហួសវា
យ៉ាងលឿន៖ 18! នៅតែសមទាំងអស់ ប៉ុន្តែ 19! និងលើសពីនេះមិនសមទេ។
ចម្លើយគឺ BigInt ជាប្រភេទចំនួនដែលអាចធំបានតាមដែលអង្គចងចាំអនុញ្ញាត។
អ្នកសរសេរ BigInt literal ដោយដាក់ n ក្រោយខ្ទង់ ហើយអ្នកមិនអាច
លាយវាជាមួយចំនួនធម្មតាបានទេ៖
let result = 1n;
for (let i = 2n; i <= 25n; i++) {
result *= i;
}
console.log(result); // 15511210043330985984000000n
ច្បាប់ដែលត្រូវចងចាំ៖
5nគឺជា BigInt,5គឺជា number។5n + 5បោះTypeError។ បំប្លែង ដោយBigInt(5)ឬNumber(5n)។/លើ BigInt ទម្លាក់សំណល់៖7n / 2nគឺ3n។**ដំណើរការ៖10n ** 30nត្រឹមត្រូវពិតប្រាកដ។console.logបោះពុម្ពnនៅចុងសម្រាប់ BigInt ប៉ុន្តែString(x)និង template string (${x}) មិនរួមបញ្ចូលវាទេ។
Function រាប់របស់យើងនឹងត្រឡប់ BigInt ដើម្បីឲ្យចម្លើយនៅត្រឹមត្រូវពិតប្រាកដ។ ប្រសិនបើ
អ្នកចង់បានតែទំហំប្រហាក់ប្រហែល ប្រើ Number(x) ហើយទទួលយកការបង្គត់ខ្លះ។
9. Pagination និង Batching
ការរាប់ក៏គ្របដណ្តប់ការងារធម្មតាមួយដែរ៖ តើបញ្ជីត្រូវការប៉ុន្មានទំព័រ? តារាងបង្ហាញ 10 ជួរក្នុងមួយទំព័រ ហើយ API ត្រឡប់ 95 ជួរ។
console.log(95 / 10); // 9.5
console.log(Math.ceil(95 / 10)); // 10
Math.ceil បង្គត់ ឡើង។ អ្នកត្រូវការដប់ទំព័រ ពីព្រោះទំព័រចុងក្រោយផ្ទុក
5 ជួរដែលនៅសល់។ ការបង្គត់ចុះនឹងបាត់ 5 ជួរនោះ ហើយការបង្គត់ទៅជិតបំផុត
នឹងផ្តល់ 10 នៅទីនេះ ប៉ុន្តែ 9 សម្រាប់ 94 ជួរ (9.4) ដែលនឹង
ខុស។ ច្បាប់គឺសាមញ្ញ៖ pages = ceil(items / pageSize)។
Edge case ដែលគួរតេស្ត៖
| items | pageSize | លទ្ធផល | មូលហេតុ |
|---|---|---|---|
| 95 | 10 | 10 | ទំព័រចុងក្រោយមិនពេញ |
| 100 | 10 | 10 | ពេញសមរម្យ |
| 101 | 10 | 11 | ធាតុមួយហៀរចេញ |
| 0 | 10 | 0 | គ្មានទំព័រ (សម្រេចចិត្តថាតើ UI របស់អ្នកចង់បាន 1 ឬអត់) |
រូបមន្តដូចគ្នាបំបែកការងារជា batch។ ការផ្ញើអ៊ីមែល 2,500 ដោយមាន
ដែនកំណត់ 100 ក្នុងមួយ request ត្រូវការ Math.ceil(2500 / 100) = 25 request។
ការបញ្ចូលជួរ database 10,001 ជាក្រុមៗ 1,000 ត្រូវការ 11 ក្រុម ហើយ
ក្រុមចុងក្រោយស្ទើរតែទទេ។ ការធ្វើ ceil ខុសគឺជា off-by-one bug បុរាណ
ដែលធាតុពីរបីចុងក្រោយមិនដែលត្រូវបានដំណើរការដោយស្ងាត់ៗ។
ទំព័រ p (រាប់ចាប់ពី 1) ចាប់ផ្តើមនៅ index (p - 1) * pageSize៖
const items = Array.from({ length: 95 }, (_, i) => i + 1);
const pageSize = 10;
const page = 10;
const start = (page - 1) * pageSize; // 90
console.log(items.slice(start, start + pageSize)); // [ 91, 92, 93, 94, 95 ]
10. រូបមន្ត៖ Module counting
បង្កើត src/counting.js ក្នុងគម្រោង mathlab របស់អ្នក។ គ្រប់ function ដែល
អាចផលិតចម្លើយធំត្រឡប់ BigInt។
// src/counting.js — រាប់អ្វីៗដោយមិនរាយបញ្ជី។
export function factorial(n) {
if (!Number.isInteger(n) || n < 0) {
throw new RangeError("factorial needs a whole number >= 0");
}
let result = 1n;
for (let i = 2n; i <= BigInt(n); i++) {
result *= i;
}
return result;
}
// ការជ្រើសមានលំដាប់៖ n * (n-1) * ... * (n-k+1)
export function permutations(n, k = n) {
if (k > n) return 0n;
let result = 1n;
for (let i = 0; i < k; i++) {
result *= BigInt(n - i);
}
return result;
}
// ការជ្រើសគ្មានលំដាប់ ("n choose k")។ ការចែកគ្រប់ជំហានរក្សា
// តម្លៃកណ្តាលឲ្យជាចំនួនគត់ត្រឹមត្រូវ។
export function combinations(n, k) {
if (k > n) return 0n;
const small = Math.min(k, n - k);
let result = 1n;
for (let i = 1; i <= small; i++) {
result = (result * BigInt(n - small + i)) / BigInt(i);
}
return result;
}
// តើមាន string ប៉ុន្មានដែលមានតួអក្សរ `length` ពី alphabet ទំហំនេះ។
export function passwordSpace(alphabetSize, length) {
return BigInt(alphabetSize) ** BigInt(length);
}
// តើត្រូវការប៉ុន្មានទំព័រដើម្បីបង្ហាញ totalItems ដោយ pageSize ក្នុងមួយទំព័រ?
export function pageCount(totalItems, pageSize) {
if (pageSize <= 0) throw new RangeError("pageSize must be positive");
return Math.ceil(totalItems / pageSize);
}
កំណត់សម្គាល់ខ្លះអំពីការរចនា៖
permutations(n, k = n)គុណតែkតួ ដូច្នេះវាមិនដែលគណនាn!ទាំងមូលរួចចែកទេ។combinationsប្រើmin(k, n - k)ពីព្រោះC(49, 6)ស្មើនឹងC(49, 43)ហើយការធ្វើ 6 ជំហានខ្លីជាង 43។ នៅគ្រប់ជំហាន លទ្ធផលដែលកំពុងដំណើរការ គឺជាចំនួន combination ដោយខ្លួនវាផ្ទាល់ ដូច្នេះការចែកតែងតែត្រឹមត្រូវ។pageCountត្រឡប់ចំនួនធម្មតា៖ ចំនួនទំព័រគឺតូច។
ឥឡូវបន្ថែម export ទៅ src/index.js៖
export * from "./counting.js";
បន្ទាប់មកបន្ថែមកូដនេះទៅ demo.js (ឬឯកសារថ្មី) ហើយដំណើរការ node demo.js៖
import {
factorial, permutations, combinations, passwordSpace, pageCount,
} from "./src/index.js";
console.log(factorial(5)); // 120n
console.log(factorial(25)); // 15511210043330985984000000n
console.log(permutations(8, 3)); // 336n
console.log(combinations(5, 2)); // 10n
console.log(combinations(49, 6)); // 13983816n
console.log(passwordSpace(10, 4)); // 10000n
console.log(passwordSpace(62, 8)); // 218340105584896n
console.log(passwordSpace(94, 12)); // 475920314814253376475136n
console.log(pageCount(95, 10)); // 10
console.log(pageCount(101, 10)); // 11
ចម្លើយ 12 តួអក្សរខ្ពស់ជាង Number.MAX_SAFE_INTEGER ឆ្ងាយ ដូច្នេះ
number ធម្មតាមិនអាចបង្ហាញវាបានត្រឹមត្រូវពិតប្រាកដទេ។ នោះហើយជាតម្លៃរបស់ BigInt។
អ្នកក៏អាចប៉ាន់ស្មានថាការវាយប្រហារ brute force ចំណាយពេលប៉ុន្មានដែរ៖
const guessesPerSecond = 1e9;
const seconds = Number(passwordSpace(62, 8)) / guessesPerSecond;
console.log(seconds / 3600 / 24); // about 2.53 (days)
Number(...) បំប្លែង BigInt ដើម្បីឲ្យយើងអាចចែកនឹងចំនួនធម្មតា។
ការបង្គត់បន្តិចបន្តួចមិនអីទេ ពីព្រោះយើងចង់បានតែការប៉ាន់ស្មាន។
11. សាកល្បងដោយខ្លួនឯង
- ឈុតអាហារថ្ងៃត្រង់។ ហាងកាហ្វេបន្ថែមមុខម្ហូបមេទីបួន និងភេសជ្ជៈទីបី។ ដោយប្រើ rule of product តើឥឡូវមានឈុតអាហារថ្ងៃត្រង់ប៉ុន្មាន? ពិនិត្យដោយកូដ។
- ដំឡើង PIN។ ប្រើ
passwordSpaceដើម្បីប្រៀបធៀប PIN 4 ខ្ទង់ 6 ខ្ទង់ និង 8 ខ្ទង់។ តើខ្ទង់បន្ថែមពីរគ្រប់ដងគុណចន្លោះដោយកត្តាប៉ុន្មាន? បន្ទាប់មកគណនាថា 8 ខ្ទង់ត្រូវចំណាយពេលប៉ុន្មាន ក្នុងល្បឿនមួយពាន់លានការទាយ ក្នុងមួយវិនាទី។ - Permutation ឬ combination? សម្រាប់ករណីនីមួយៗ ប្រាប់ថាវាជាអ្វី បន្ទាប់មកគណនា
ដោយ
mathlab៖ (ក) ជ្រើសសិស្ស 3 នាក់ក្នុងចំណោម 10 នាក់ដើម្បីបង្កើតគណៈកម្មការ (ខ) ចាត់សិស្ស 3 នាក់ក្នុងចំណោម 10 នាក់ជាប្រធានក្រុម អនុប្រធានក្រុម និង លេខាធិការ (គ) ជ្រើសបៀ 5 សន្លឹកពីឈុតបៀ 52 សន្លឹក។ ពិនិត្យថា (ខ) គឺ3! = 6ដងនៃ (ក) ពិតប្រាកដ។ - Symmetry។ បោះពុម្ព
combinations(10, 3)និងcombinations(10, 7)។ ហេតុអ្វី វាស្មើគ្នា? (ណែនាំ៖ ការជ្រើស 3 ដើម្បីដាក់បញ្ចូល គឺដូចគ្នានឹងការជ្រើស 7 ដើម្បីទុកចោល។) - Pagination។ សរសេរ
pageSlice(items, page, pageSize)ដែលត្រឡប់ ធាតុសម្រាប់មួយទំព័រ ដោយប្រើpageCountដើម្បីបដិសេធលេខទំព័រដែល ខ្ពស់ពេក។ តេស្តជាមួយធាតុ 95 ដោយ 10 ក្នុងមួយទំព័រ ទំព័រ 1, 10 និង 11។ - តើ Number ចុះចាញ់នៅពេលណា? រក
nតូចបំផុតដែលNumber(factorial(n)) > Number.MAX_SAFE_INTEGER។ Loopnឡើងលើ ហើយឈប់នៅពេលលក្ខខណ្ឌជា true។ អ្នកគួររកឃើញថាវាគឺ 19។
ការរាប់បានប្រាប់អ្នកថាមានលទ្ធភាពប៉ុន្មាន។ ជំពូកបន្ទាប់សួរសំណួរ
គួរឲ្យចាប់អារម្មណ៍ជាង៖ តើនីមួយៗ ទំនង ប៉ុនណា? បន្តជាមួយ
មូលដ្ឋានគ្រឹះប្រូបាប
ដែល randomInt expected value និង birthday paradox ពឹងលើការរាប់ទាំងនេះ
ពិតប្រាកដ។
ទិញកាហ្វេជូនខ្ញុំ
ចូលចិត្តមេរៀននេះមែនទេ? សូមពិចារណាទិញកាហ្វេជូនខ្ញុំមួយកែវ ដើម្បីគាំទ្រការបង្កើតមាតិកាឥតគិតថ្លៃបន្ថែមទៀត!