new(max-div): Find number having maximum number of prime divisors.
authorsgf <sgf.dma@gmail.com>
Mon, 23 Jan 2023 12:46:04 +0000 (15:46 +0300)
committersgf <sgf.dma@gmail.com>
Thu, 2 May 2024 15:30:30 +0000 (18:30 +0300)
max-dividers/.gitignore [new file with mode: 0644]
max-dividers/max-div.cpp [new file with mode: 0644]
max-dividers/max-div.go [new file with mode: 0644]
max-dividers/max-div_test.go [new file with mode: 0644]

diff --git a/max-dividers/.gitignore b/max-dividers/.gitignore
new file mode 100644 (file)
index 0000000..cba7efc
--- /dev/null
@@ -0,0 +1 @@
+a.out
diff --git a/max-dividers/max-div.cpp b/max-dividers/max-div.cpp
new file mode 100644 (file)
index 0000000..18863c2
--- /dev/null
@@ -0,0 +1,80 @@
+#include <iostream>
+using namespace std;
+
+// Рекурсия.
+int CountDividers1(int n) {
+    for (int i = 2; i <= n; i++)
+        if (n%i == 0)
+            return 1 + CountDividers1(n/i);
+    return 0;
+}
+
+// Хвостовая рекурсия. Стек вызова функций (теоретически) не будет
+// увеличиваться в сравнении с рекусривной версией (хотя это зависит от
+// компилятора).
+int CountDividers2(int acc, int n) {
+    for (int i = 2; i <= n; i++)
+        if (n%i == 0)
+            return CountDividers2(acc + 1, n/i);
+    return acc;
+}
+
+// Без рекурсии.
+int CountDividers3(int n) {
+    int m = n;
+    int acc = 0;
+    while (m >= 2)
+        for (int i = 2; i <= m; i++)
+            if (m%i == 0) {
+                m /= i;
+                acc++;
+                break;
+            }
+    return acc;
+}
+
+int searchMaxDiv(int start, int end) {
+    int x = 0;
+    int m = 0;
+    for (int n = start; n <= end; n++) {
+        //int c = CountDividers1(n);
+        //int c = CountDividers2(0, n);
+        int c = CountDividers3(n);
+        if (c >= m) {
+            m = c;
+            x = n;
+        }
+    }
+    return x;
+}
+
+int origSearchMaxDiv(int start, int end)
+{
+    int a, c, m, x;
+    m = -1;
+    x = 0;
+    for (int i = start; i <= end; i++) {
+        c = 0;
+        for (int j = 1; j <= i; j++) {
+            if (i % j == 0) {
+                c = c + 1;
+            }
+        }
+        if (c >= m) {
+            m = c;
+            x = i;
+        }
+    }
+    return x;
+}
+
+int main() {
+    int start = 394441;
+    int end = 394505;
+    int x;
+    x = origSearchMaxDiv(start, end);
+    cout << x << endl;
+    x = searchMaxDiv(start, end);
+    cout << x << endl;
+}
+
diff --git a/max-dividers/max-div.go b/max-dividers/max-div.go
new file mode 100644 (file)
index 0000000..03fd394
--- /dev/null
@@ -0,0 +1,74 @@
+
+package main
+
+import (
+    "fmt"
+)
+
+//const start_num = 394441
+const start_num = 1
+//const end_num = 394505
+const end_num = 10
+
+func CountDividers1(n int) int {
+    fmt.Printf("Start with %v\n", n)
+    for i := 2; i <= n; i++ {
+        if n%i == 0 {
+            fmt.Printf("found %v\n", i)
+            return 1 + CountDividers1(n/i)
+        }
+    }
+    return 0
+}
+
+func CountDividers2(acc, n int) int {
+    //fmt.Printf("Start with %v (%v)\n", n, acc)
+    for i := 2; i <= n; i++ {
+        if n%i == 0 {
+            //fmt.Printf("found %v\n", i)
+            return CountDividers2(acc + 1, n/i)
+        }
+    }
+    return acc
+}
+
+func CountDividers3(n int) int {
+    m := n
+    acc := 0
+    for m >= 2 {
+        //fmt.Printf("Go with %v\n", m)
+        for i := 2; i <= m; i++ {
+            if m%i == 0 {
+                //fmt.Printf("found %v\n", i)
+                m /= i
+                acc++
+                break
+            }
+        }
+    }
+    return acc
+}
+
+func searchMaxDiv(start, end int) int {
+    var x, m int
+    for n := start; n <= end; n++ {
+        //fmt.Printf("n = %v\n", n)
+        //c := CountDividers1(n)
+        //c := CountDividers2(0, n)
+        c := CountDividers3(n)
+        //fmt.Printf("  %v has %v dividers\n", n, c)
+        if c >= m {
+            m = c
+            x = n
+        }
+    }
+    fmt.Println(x, m)
+    return x
+}
+
+func main() {
+    r := CountDividers1(1541)
+    fmt.Println(r)
+    searchMaxDiv(2, 16)
+    searchMaxDiv(394441, 394505)
+}
diff --git a/max-dividers/max-div_test.go b/max-dividers/max-div_test.go
new file mode 100644 (file)
index 0000000..1bd0f59
--- /dev/null
@@ -0,0 +1,52 @@
+
+package main
+
+import (
+    "testing"
+)
+
+type tData struct {
+    val int
+    res int
+}
+
+var vals []tData = []tData{
+        {2, 1},
+        {3, 1},
+        {4, 2},
+        {8, 3},
+        {10, 2},
+        {11, 1},
+        {18, 3},
+        {32, 5},
+        {34, 2},
+        {121, 2},
+    }
+
+func TestCountDividers1(t *testing.T) {
+    for _, v := range vals {
+        got := CountDividers1(v.val)
+        if got != v.res {
+            t.Errorf("CountDividers1 test fails at %v with %v instead of %v\n", v.val, got, v.res)
+        }
+    }
+}
+
+func TestCountDividers2(t *testing.T) {
+    for _, v := range vals {
+        got := CountDividers2(0, v.val)
+        if got != v.res {
+            t.Errorf("CountDividers2 test fails at %v with %v instead of %v\n", v.val, got, v.res)
+        }
+    }
+}
+
+func TestCountDividers3(t *testing.T) {
+    for _, v := range vals {
+        got := CountDividers3(v.val)
+        if got != v.res {
+            t.Errorf("CountDividers3 test fails at %v with %v instead of %v\n", v.val, got, v.res)
+        }
+    }
+}
+