Asal Sayı Problemi

July 27, 2020

Bilgisayarımdaki arşivden çıkan bir başka soru ile karşınızdayım. Soru metni elimde yok ama hafızam beni yanıltmıyorsa aşağıdaki gibiydi. Alice ve Bob kendi aralarında bir oyun icat ediyorlar. İki arkadaş 1..10^9 arasındaki bazı asal sayıları bulmak istiyorlar.

Alice: sadece 1,3,5 rakamlarından oluşan asal sayıları sayıyor. Diğer değişle sayının tüm basamakları 1,3,5 rakamından biri olmak zorunda. Bob: sadece 5,7,9 rakamlarından oluşan asal sayıları sayıyor.

İkisi de işlemlerini bitirince buldukları asal sayı miktarını karşılaştırıyor. Kim daha fazla asal sayı bulursa o kazanıyor.

Beklenen girdi: yok. Beklenen çıktı: kim kazandıysa onun adını basıyoruz (Alice veya Bob)

Çözüm

Problemdeki input single pass için çok büyük. Dolayısı ile daha iyi bir çözüme ihtiyacımız var. Sadece 1, 3 ve 5 rakamlarından oluşan tüm tam sayıları bulalım.

Bunun için ağacımsı bir yapı kullanabiliriz ki bize O(2^n) gibi bir karmaşıklık verir. n çok büyük olmadığı için kolayca hesaplayabiliriz.

Basamak sayısı 3 olduğu için perfectly balanced ternary tree oluşturduğumuzda elimizde (3^10 - 1) / 2 = 29524 tane değer olur. Bu sayıları depolamak gibi bir derdimiz yok geldiği gibi işleyebiliriz. Asallık testi için klasik O(sqrt(n)) kompleksitesine sahip bir algoritma kullanırsak tamamız.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
#include <bits/stdc++.h>
using namespace std;

int r = 0; // result

// primality check
bool isPrime(int n) {
    if (n <= 1) return false;
    if (n <= 3) return true;
    if (n % 2 == 0 || n % 3 == 0)
        return false;
    
    for (int i = 5; i * i <= n; i = i + 6)
        if (n % i == 0 || n % (i + 2) == 0)
            return false;
    return true;
}

// Perfectly balanced ternary tree recursion
void primes(vector<int>& rr, int val , int level) {
    if (level == 10) return;
    r+=isPrime(val);
    for (int i = 0; i < rr.size(); i++)
        primes(rr, val * 10 + rr[i], level + 1);
}

int main() {
    vector<int> s = {1,3,5};
    vector<int> t = {5,7,9};

    primes(s, 1, 0);
    r*=-1;
    primes(t, 1, 0);

    if(r > 0) cout << "Alice";
    else cout << "Bob";

    return 0;
}

hidden

John von Neumann – The Man from the Future

Before I read The Man from the Future by Ananyo Bhattacharya, I only knew about John von Neumann in two contexts: that computers use the von Neumann architecture, and that he appeared in a story about a mathematical problem I … Continue reading →

via Henrik Warne's blog

The Review Is the Action Item

2024/05/30The Review Is the Action ItemI like to consider running an incident review to be its own action item. Other follow-ups emerging from it are a plus, but the point is to learn from incidents, and the review gives room for that to happen.This is no…

via Ferd.ca

HOWTO: Change your behavior

In theory, behavior change should be easy. At first glance, it seems like you control your behavior. So, if you desire different behavior, why doesn’t your behavior change as instantly as your desire to change it? In short, lasting change of habitual behavio…

via Matt Might's blog