Re[6]: k нулей
От: Beam Россия  
Дата: 19.12.08 11:07
Оценка: 15 (1)
Здравствуйте, Seon, Вы писали:

S>А можно подкорректировать Вашу программу, чтобы писало текущее значение степени, ну типа как


S>std::cout << p << "\r";


import Data.List
import Debug.Trace

zeros n = head [p | p <- [1..], trace ("curent = " ++ show p) $ (replicate n '0') `isInfixOf` (show $ 2^p)]
Best regards, Буравчик
Re[8]: k нулей
От: Seon  
Дата: 19.12.08 11:14
Оценка:
Здравствуйте, Seon, Вы писали:

S>Здравствуйте, Beam, Вы писали:


B>>Здравствуйте, Seon, Вы писали:


S>>>Моя прога посчитала а(8)


B>>Поздравляю


S>>>Мдя до 100000 это неделя, не меньше...


B>>Может попробовать готовые библиотеки использовать?

B>>Надо всего-то — работа с большими числами и поиск подстроки.
B>>Уверен, что такие библиотеки для си есть.

S>Та тут можно проще сделать... думаю хаскел так и работает...

S>берем сразу десятичное число в строковом виде и удваиваем его, и проверяем нули!
S>это будет на несколько порядков быстрее...


ДААААААА!!!!!!
а(9) — меньше 2х минут!!! в дэбаге !!!!
ща мы его....
Re[9]: k нулей
От: Seon  
Дата: 19.12.08 11:22
Оценка: :)
S>>Та тут можно проще сделать... думаю хаскел так и работает...
S>>берем сразу десятичное число в строковом виде и удваиваем его, и проверяем нули!
S>>это будет на несколько порядков быстрее...

S>ДААААААА!!!!!!

S>а(9) — меньше 2х минут!!! в дэбаге !!!!
S>ща мы его....

Кароче
а(8) — до 2х секунд!
а(9) — 80 секунд!

С++ рулит! главно правильно задачу ему поставить!
а то я сначала мегаматематику подключил универсальную.... перевожу из двоичного числа в десятичное, проверяю.... ХА ХА!
Re[10]: k нулей
От: Seon  
Дата: 19.12.08 11:58
Оценка: 15 (1)
S>а(8) — до 2х секунд!
S>а(9) — 80 секунд!

а(10) — 2^559940 — 24 минуты и 20 секунд
Re[2]: k нулей
От: vadimcher  
Дата: 19.12.08 15:57
Оценка:
Здравствуйте, Seon, Вы писали:

S>Здравствуйте, vadimcher, Вы писали:


V>>Докажите, что для любого k найдется такое число n, что в [i]десятичной[i] записи числа 2^n, встречается k нулей подряд.


V>>Этюд для программиста.

V>>Обозначим минимальное такое n как a(k). Например, a(1)=10, т.к. 2^10=1024 -- минимальная степень двойки, содержащая один ноль (подряд? ). a(2)=53, т.к. 2^53=9007199254740992 -- минимальная степень двойки, содержащая два нуля подряд. Ну и т.д.
V>>Найти a(1),...,a(7).

S>Обратная задача


S>Найти все числа, степени двойки, для которых не будет повторяться 2х нулей подряд !!

S>Существует ли предел, степени, больше которой 2 нуля подряд не повторяются?

Не существует. Если мы докажем (теоретически), что a(k) есть для любого k, то последовательность таких чисел уходит в бесконечность.

А вот зайца кому, зайца-выбегайца?!
Re[2]: k нулей
От: vadimcher  
Дата: 19.12.08 15:57
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Здравствуйте, vadimcher, Вы писали:


V>>Докажите, что для любого k найдется такое число n, что в [i]десятичной[i] записи числа 2^n, встречается k нулей подряд.


V>>Этюд для программиста.

V>>Обозначим минимальное такое n как a(k). Например, a(1)=10, т.к. 2^10=1024 -- минимальная степень двойки, содержащая один ноль (подряд? ). a(2)=53, т.к. 2^53=9007199254740992 -- минимальная степень двойки, содержащая два нуля подряд. Ну и т.д.
V>>Найти a(1),...,a(7).

А>Решение на Haskell.

А>
А>import Data.List
А>zeros n = head [p | p <- [1..], (replicate n '0') `isInfixOf` (show $ 2^p)]
А>


А>Ответ:


А>
А>*Main> zeros 1
А>10
А>*Main> zeros 2
А>53
А>*Main> zeros 3
А>242
А>*Main> zeros 4
А>377
А>*Main> zeros 5
А>1491
А>*Main> zeros 6
А>1492
А>*Main> zeros 7  -- 5 сек.
А>6801
А>*Main> zeros 8  -- 25 сек.
А>14007
А>


А>zeros 9 считает уже 7 минут

А>Не дождался — написал, то что есть

Волшебный чудо-язык haskell.

А вот зайца кому, зайца-выбегайца?!
Re: k нулей
От: vadimcher  
Дата: 19.12.08 16:03
Оценка: 5 (1)
Здравствуйте, vadimcher, Вы писали:

V>Докажите, что для любого k найдется такое число n, что в [i]десятичной[i] записи числа 2^n, встречается k нулей подряд.


V>Этюд для программиста.

V>Обозначим минимальное такое n как a(k). Например, a(1)=10, т.к. 2^10=1024 -- минимальная степень двойки, содержащая один ноль (подряд? ). a(2)=53, т.к. 2^53=9007199254740992 -- минимальная степень двойки, содержащая два нуля подряд. Ну и т.д.
V>Найти a(1),...,a(7).

Все верно расчитали. Тут можно посмотреть вплоть до a(17): здесь. Внизу комментарий: некто Sacha Roscoe добавил a(15), затем через пару недель a(16), а затем еще a(17)... через 4 года.

Остается теоретическая часть вопроса.

А вот зайца кому, зайца-выбегайца?!
Re[11]: k нулей
От: Seon  
Дата: 19.12.08 16:08
Оценка:
Здравствуйте, Seon, Вы писали:

S>>а(8) — до 2х секунд!

S>>а(9) — 80 секунд!

S>а(10) — 2^559940 — 24 минуты и 20 секунд


а(11) — 2^1148303 — 47 минут и 16 секунд
Re: k нулей
От: Pro100Oleh Украина  
Дата: 19.12.08 18:26
Оценка:
Считал на проце Q6600 на C# .Net 3.5 sp1. Программа однопоточная, но юзалось четыре проца где-то по 25% каждый.

a(1) = 10. Time 00:00:00.0038011, Length 4
a(2) = 53. Time 00:00:00.0000592, Length 16
a(3) = 242. Time 00:00:00.0006503, Length 73
a(4) = 377. Time 00:00:00.0008813, Length 114
a(5) = 1491. Time 00:00:00.0204129, Length 449
a(6) = 1492. Time 00:00:00.0000576, Length 450
a(7) = 6801. Time 00:00:00.4025472, Length 2048
a(8) = 14007. Time 00:00:00.1214338, Length 4217
a(9) = 100823. Time 00:00:08.0502971, Length 30351
a(10) = 559940. Time 00:03:16.3552767, Length 168559
a(11) = 1148303. Time 00:10:54.2630780, Length 345674

Pro
Re[2]: k нулей
От: vadimcher  
Дата: 19.12.08 18:50
Оценка: 1 (1) +1
Здравствуйте, Pro100Oleh, Вы писали:

PO>Считал на проце Q6600 на C# .Net 3.5 sp1. Программа однопоточная, но юзалось четыре проца где-то по 25% каждый.


PO>

PO>a(1) = 10. Time 00:00:00.0038011, Length 4
PO>a(2) = 53. Time 00:00:00.0000592, Length 16
PO>a(3) = 242. Time 00:00:00.0006503, Length 73
PO>a(4) = 377. Time 00:00:00.0008813, Length 114
PO>a(5) = 1491. Time 00:00:00.0204129, Length 449
PO>a(6) = 1492. Time 00:00:00.0000576, Length 450
PO>a(7) = 6801. Time 00:00:00.4025472, Length 2048
PO>a(8) = 14007. Time 00:00:00.1214338, Length 4217
PO>a(9) = 100823. Time 00:00:08.0502971, Length 30351
PO>a(10) = 559940. Time 00:03:16.3552767, Length 168559
PO>a(11) = 1148303. Time 00:10:54.2630780, Length 345674


Было бы здорово, если бы все еще свой код выкладывали. Просто интересно сравнить эффективность/простоту для разных языков.

А вот зайца кому, зайца-выбегайца?!
Re[3]: k нулей
От: Erop Россия  
Дата: 19.12.08 20:25
Оценка:
Здравствуйте, vadimcher, Вы писали:

А>>zeros 9 считает уже 7 минут

А>>Не дождался — написал, то что есть

V>Волшебный чудо-язык haskell.


#include "stdafx.h"
#include <vector>
#include <assert.h>
#include <iostream>

const int logPeriod = 100 * 1000;
const int tryTo = 2 * 1000 * 1000;


class PowerOf2VeryLongNumber {
    typedef std::vector<unsigned char> TDigits;
    TDigits digits;
public:
    PowerOf2VeryLongNumber() { digits.push_back( 1 ); }

    int Mult2AndRetMax0Count()
    {
        int zerCount = 0;
        int bestZerCount = 0;
        if( digits[digits.size() - 1] != 0 )
            digits.push_back( 0 );
        int carry = 0;
        for( TDigits::iterator i = digits.begin(); i != digits.end(); ++i ) {
            int res = (*i) * 2 + carry;
            if( res > 9 ) {
                assert( res < 20 );
                carry = 1;
                *i = ( res -= 10 );
            } else {
                *i = res;
                carry = 0;
            }
            if( res == 0 ) {
                ++zerCount;
            } else {
                if( zerCount > bestZerCount ) {
                    bestZerCount = zerCount;
                }
                zerCount = 0;
            }
        }
        assert( carry == 0 );
        return bestZerCount;
    }
    template<typename TStream>
    TStream& Output( TStream& dst ) const 
    {
        for( TDigits::const_reverse_iterator i = digits.rbegin(); i != digits.rend(); ++i ) {
            dst << (int)*i;
        }
        return dst;
    }

};

template<typename TStream>
TStream& operator << ( TStream& dst, const PowerOf2VeryLongNumber& x )
{
    return x.Output( dst );
}

struct Result {
    int PowerValue;
    PowerOf2VeryLongNumber x;
};

int _tmain(int argc, _TCHAR* argv[])
{
    PowerOf2VeryLongNumber x;
    std::vector<Result> result;
    Result tmp = { 0 };
    result.push_back( tmp );
    for( int i = 1; i < tryTo; i++ ) {
        int zCount = x.Mult2AndRetMax0Count();
        bool outputProgressLog = ( i % logPeriod ) == 0;
        while( result.size() <= zCount ) {
            Result r = { i, x };
            result.push_back( r );
            outputProgressLog = true;
        }
        if( outputProgressLog ) {
            std::cout << "2^" << i << " = " << zCount << ", " << result.size() - 1 << std::endl;
        }
    }
    std::cout << "--------------------------" << std::endl;
    for( int i = 1; i < result.size(); i++ ) {
        std::cout << "a(" << i << ") = 2^" << result[i].PowerValue /*<< " = " << result[i].x */<< std::endl;
    }

    return 0;
}

9 -- меньше минуты. Написал из головы, вроде сразу заработало...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[4]: k нулей
От: Erop Россия  
Дата: 19.12.08 20:37
Оценка:
Здравствуйте, Erop, Вы писали:

E>9 -- меньше минуты. Написал из головы, вроде сразу заработало...

10 -- 14 минут ужо...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[5]: k нулей
От: Erop Россия  
Дата: 19.12.08 21:02
Оценка:
E>>9 -- меньше минуты. Написал из головы, вроде сразу заработало...
E>10 -- 14 минут ужо...

Прикольно, что вариант
#include "stdafx.h"
#include <vector>
#include <assert.h>
#include <iostream>

const int logPeriod = 100 * 1000;
const int tryTo = 20 * 1000 * 1000;

const unsigned char lowDigit[] = { 0, 2, 4, 6, 8, 0, 2, 4, 6, 8 };
const unsigned char hiDigit[] =  { 0, 0, 0, 0, 0, 1, 1, 1, 1, 1 };


class PowerOf2VeryLongNumber {
    typedef std::vector<unsigned char> TDigits;
    TDigits digits;
public:
    PowerOf2VeryLongNumber() { digits.push_back( 1 ); }

    int Mult2AndRetMax0Count()
    {
        int zerCount = 0;
        int bestZerCount = 0;
        if( digits[digits.size() - 1] != 0 )
            digits.push_back( 0 );
        int carry = 0;
        for( TDigits::iterator i = digits.begin(); i != digits.end(); ++i ) {
            const unsigned char curDig = lowDigit[*i] + carry;
            carry = hiDigit[*i];
            *i = curDig;
            if( curDig == 0 ) {
                ++zerCount;
                if( zerCount > bestZerCount && (i+1)!=digits.end() ) {
                    bestZerCount = zerCount;
                }
            } else {
                zerCount = 0;
            }
        }
        assert( carry == 0 );
        return bestZerCount;
    }
    template<typename TStream>
    TStream& Output( TStream& dst ) const 
    {
        for( TDigits::const_reverse_iterator i = digits.rbegin(); i != digits.rend(); ++i ) {
            dst << (int)*i;
        }
        return dst;
    }

    int Length() const { return digits.size() - ( digits[digits.size() - 1] == 0 ); }

};

template<typename TStream>
TStream& operator << ( TStream& dst, const PowerOf2VeryLongNumber& x )
{
    return x.Output( dst );
}

struct Result {
    int PowerValue;
    PowerOf2VeryLongNumber x;
};

int _tmain(int argc, _TCHAR* argv[])
{
    PowerOf2VeryLongNumber x;
    std::vector<Result> result;
    Result tmp = { 0 };
    result.push_back( tmp );
    for( int i = 1; i < tryTo; i++ ) {
        int zCount = x.Mult2AndRetMax0Count();
        bool outputProgressLog = ( i % logPeriod ) == 0;
        while( result.size() <= zCount ) {
            Result r = { i, x };
            result.push_back( r );
            outputProgressLog = true;
        }
        if( outputProgressLog ) {
            std::cout << "2^" << i << " = " << zCount << ", " << result.size() - 1 
                << ", len = " << x.Length()/* << ", " << x */<< std::endl;
        }
    }
    std::cout << "--------------------------" << std::endl;
    for( int i = 1; i < result.size(); i++ ) {
        std::cout << "a(" << i << ") = 2^" << result[i].PowerValue << ", len = " << result[i].x.Length() 
            /*<< " = " << result[i].x */<< std::endl;
    }

    return 0;
}
Не сильно шибче.

а(10) посчитался на 11-й минуте...
Возможно можно ещё разогнать, если сразу парами цифп оперировать, или, даже, 4-ками...
Может попробую. Интересно же
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[7]: k нулей
От: Beam Россия  
Дата: 19.12.08 21:37
Оценка:
Здравствуйте, Beam, Вы писали:

Код на Java с учетом идей Seon'а

public class KZeros {

    void run(int K) {
        long time = -System.currentTimeMillis();

        // храним 2^n как массив цифр (в обратном порядке)
        int MAXLEN = 100*1000*1000;
        byte[] digits = new byte[MAXLEN];

        int n = 0;     // текущее n
        digits[0] = 1; // цифры числа 2^n, в начале 2^0 = 1
        int len = 1;   // количество цифр в 2^n

        boolean found = false;
        while (!found) {
            n++;
            if (n % 1000 == 0)
                System.out.println(String.format("cur n = %d", n));

            // вычисляем новое 2^(n+1) = 2^n+2^n и заодно подсчитываем нолики
            int countZeros = 0;     // найдено нулей подряд
            byte carryFlag = 0;     // перенос из предыдущего разряда
            for (int i = 0; i < len; i++) {
                byte val = (byte) (digits[i] + digits[i] + carryFlag);
                digits[i] = (byte) (val % 10);
                carryFlag = (byte) (val / 10);
                
                countZeros = digits[i] == 0 ? countZeros + 1 : 0;
                if (countZeros == K) {
                    found = true;
                    break;
                }
            }
            // если остался флаг переноса с самого старшего разряда
            if (!found && carryFlag == 1) {
                digits[len] = 1;
                len++;
                assert len <= MAXLEN;
            }
        }
        System.out.println(String.format("a(%d) = %d", K, n));
        time += System.currentTimeMillis();
        System.out.println(String.format("Time: %1$tM:%1$tS.%1$tL", time));
    }

    static public void main(String[] args) {
        new KZeros().run(10);
    }
}


а(9) 0,5 мин
a(10) 15,5 мин
на Core 2 duo 1.87 ГГц
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Best regards, Буравчик
Re[6]: k нулей
От: Erop Россия  
Дата: 20.12.08 09:38
Оценка:
E>>>9 -- меньше минуты. Написал из головы, вроде сразу заработало...
E>>10 -- 14 минут ужо...

E>а(10) посчитался на 11-й минуте...

E>Возможно можно ещё разогнать, если сразу парами цифп оперировать, или, даже, 4-ками...
E>Может попробую. Интересно же

2^4036338, 12, len = 1215059
2^4036339, 13, len = 1215060

за ночь нашёл, потом, похоже, закончился кэш
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[12]: k нулей
От: Seon  
Дата: 20.12.08 11:02
Оценка:
Вот мой вариант.

#include <iostream>
#include <fstream>
#include <time.h>
#include <math.h>

void udv(char* arr, int& current)
{
  char ost = 0;
  for(int n = 0; n < current; ++n)
  {
    char res = arr[n] << 1;
    if (ost) res++;
    if (res > 9)
    {
      arr[n] = res - 10;
      ost = 1;
    }
    else
    {
      arr[n] = res;
      ost = 0;
    }
  }
  if (ost)
    arr[current++] = ost;
}

void write(char* arr, int size, int zeros, int current)
{
  char name[128];
  sprintf(name, "a(%d)=[2^%d].dig", zeros, current);
  std::fstream f;
  f.open(name, std::ios_base::out);
  if (f.is_open())
  {
    for (int m = size; m > 0; --m)
      f << int(arr[m - 1]);
  }
}

void test(char* arr, int& zeros, int size, int current)
{
  int z = zeros;
  for(int n = 0; n < size; ++n)
    if(arr[n])
      z = zeros;
    else
    {
      z--;
      if (z == 0)
      {
        std::cout << "\n\n\n=====================================================\na(" 
          << zeros << ") [2^" << current << "]\n";
        time_t t = time(0);
        int seconds = int(t);
        int day  = seconds / (3600 * 24);
        seconds = seconds - day * 3600 * 24;
        int hour = seconds / 3600;
        seconds = seconds - hour * 3600;
        int minutes = seconds / 60;
        seconds = seconds - minutes * 60;
        write(arr, size, zeros, current);
        std::cout << "\n" << "Time: " << day << ":" << hour << ":" << minutes << ":" 
          << seconds << "\n-----------------------------------------------------\n\n";  
        zeros++;
        return;
      }
    }
}

void save(const char* name, const char* arr, int size, int zeros, int current)
{
  std::fstream f;
  f.open(name, std::ios_base::out);
  if (f.is_open())
  {
    f.write((char*)&zeros, sizeof(int));
    f.write((char*)&size, sizeof(int));
    f.write((char*)&current, sizeof(int));
    //std::cout << "zeros=" << zeros << ", bits=" << current << ", digits=" << size << " saving... ";
    f.write(arr, size);
    //std::cout << "done.\n";
    //std::cout << "saved " << size << " - " << current << "\n";
  }
}

void load(const char* name, char* arr, int& size, int& zeros, int& current)
{
  std::fstream f;
  f.open(name, std::ios_base::in);
  if (f.is_open())
  {
    f.read((char*)&zeros, sizeof(int));
    f.read((char*)&size, sizeof(int));
    f.read((char*)&current, sizeof(int));
    std::cout << "zeros=" << zeros << ", bits=" << current << ", digits=" << size << " loading... ";
    f.read(arr, size);
    std::cout << "done.\n\n";
  }
}

int main(int argc, char* argv[])
{
  char* arr = new char[1000000000];
  arr[0] = 2;
  int size = 1;
  int zeros = 1;
  int current = 1;

  if (argc == 2)
    load(argv[1], arr, size, zeros, current);

  int to_save = 100000 / (1 + int(sqrt(sqrt(float(current)))));
  if (to_save == 0) to_save = 1;

  for(; current < 3000000000; current++)
  {
    std::cout << size << " - " << current << "\r";
    test(arr, zeros, size, current);
    udv(arr, size);
  
    to_save--;
    if (to_save == 0)
    {
      save("findbindeczero.dec", arr, size, zeros, current);
      to_save = 100000 / (1 + int(sqrt(sqrt(float(current)))));
      if (to_save == 0) to_save = 1;
      //std::cout << "next save after " << to_save << " (" << (current + to_save) << ")\n\n";
    }
  }
  delete arr;
  return 0;
}
Re[3]: k нулей
От: Seon  
Дата: 20.12.08 12:34
Оценка:
Здравствуйте, vadimcher, Вы писали:

V>Здравствуйте, Seon, Вы писали:


S>>Здравствуйте, vadimcher, Вы писали:


V>>>Докажите, что для любого k найдется такое число n, что в [i]десятичной[i] записи числа 2^n, встречается k нулей подряд.


V>>>Этюд для программиста.

V>>>Обозначим минимальное такое n как a(k). Например, a(1)=10, т.к. 2^10=1024 -- минимальная степень двойки, содержащая один ноль (подряд? ). a(2)=53, т.к. 2^53=9007199254740992 -- минимальная степень двойки, содержащая два нуля подряд. Ну и т.д.
V>>>Найти a(1),...,a(7).

S>>Обратная задача


S>>Найти все числа, степени двойки, для которых не будет повторяться 2х нулей подряд !!

S>>Существует ли предел, степени, больше которой 2 нуля подряд не повторяются?

V>Не существует. Если мы докажем (теоретически), что a(k) есть для любого k, то последовательность таких чисел уходит в бесконечность.


Почему?
Чем длинее числа, тем вероятность того что встретится два нуля подрад — увеличивается, следовательно когда то наступит момент что эта вероятность будет равна 1
Re[3]: k нулей
От: Seon  
Дата: 20.12.08 13:30
Оценка:
Здравствуйте, vadimcher, Вы писали:

V>Здравствуйте, Seon, Вы писали:


S>>Здравствуйте, vadimcher, Вы писали:


V>>>Докажите, что для любого k найдется такое число n, что в [i]десятичной[i] записи числа 2^n, встречается k нулей подряд.


V>>>Этюд для программиста.

V>>>Обозначим минимальное такое n как a(k). Например, a(1)=10, т.к. 2^10=1024 -- минимальная степень двойки, содержащая один ноль (подряд? ). a(2)=53, т.к. 2^53=9007199254740992 -- минимальная степень двойки, содержащая два нуля подряд. Ну и т.д.
V>>>Найти a(1),...,a(7).

S>>Обратная задача


S>>Найти все числа, степени двойки, для которых не будет повторяться 2х нулей подряд !!

S>>Существует ли предел, степени, больше которой 2 нуля подряд не повторяются?

V>Не существует. Если мы докажем (теоретически), что a(k) есть для любого k, то последовательность таких чисел уходит в бесконечность.



Последнее число, в котором нет двух нулей подряд — 2^2114 !
Re[7]: a(9) за пять минут
От: Erop Россия  
Дата: 20.12.08 13:32
Оценка:
Здравствуйте, Erop, Вы писали:

E>>>>9 -- меньше минуты. Написал из головы, вроде сразу заработало...

E>>>10 -- 14 минут ужо...

E>>а(10) посчитался на 11-й минуте...

E>>Возможно можно ещё разогнать, если сразу парами цифп оперировать, или, даже, 4-ками...
E>>Может попробую. Интересно же

Над парами цифр:
#include "stdafx.h"
#include <vector>
#include <assert.h>
#include <iostream>
#include <iomanip>

const int logPeriod = 10 * 1000;
const int tryTo = 20 * 1000 * 1000;
const int digitsCount = 2;
const int maxDigitsVal = 99;

typedef signed char small;

small left_z_count[maxDigitsVal + 1] = { -100 };
small right_z_count[maxDigitsVal + 2] = { -100 };

static void expand10times( small* buffer, int count )
{
    const small* src = buffer + 1;
    small* dst = buffer + 1 + count;
    for( int i = count * 9; i > 0; --i )
        *dst++ = *src++;
    ++*--dst;
}
static void fillLeft( small* dst, int start, small init_to )
{
    small* from = dst + start;
    small* to = dst + start * 10;
    while( from != to )
        *from++ = init_to;
}

static void initPartOfStaticTable( int& factor, int& left0cnt )
{
    expand10times( right_z_count, factor );
    fillLeft( left_z_count, factor, left0cnt );
    left0cnt--;
    factor *= 10;
}

static void initTables()
{
    int factor = 1;
    int leftDigCount = digitsCount - 1;
    initPartOfStaticTable( factor, leftDigCount );
    initPartOfStaticTable( factor, leftDigCount );
}


class PowerOf2VeryLongNumber {
    typedef small TDigit;
    typedef std::vector<TDigit> TDigits;
    TDigits digits;
public:
    PowerOf2VeryLongNumber() { digits.push_back( 1 ); }

    int Mult2AndRetMax0Count()
    {
        int z_count = 0;
        int best_z_count = 0;
        int carry = 0;
        for( TDigits::iterator i = digits.begin(); i != digits.end(); ++i ) {
            int newVal = *i*2+carry;
            if( newVal > maxDigitsVal ) {
                newVal -= maxDigitsVal + 1;
                carry = 1;
            } else {
                carry = 0;
            }
            *i = newVal;
            if( newVal == 0 ) {
                z_count += digitsCount;
            } else {
                z_count += right_z_count[newVal];
                if( z_count > best_z_count ) {
                    best_z_count = z_count;
                }
                z_count = left_z_count[newVal];        
            }
        }
        if( carry != 0 ) {
            digits.push_back( carry );
            if( z_count > best_z_count ) {
                best_z_count = z_count;
            }
        }
        return best_z_count;
    }
    template<typename TStream>
    TStream& Output( TStream& dst ) const 
    {
        for( TDigits::const_reverse_iterator i = digits.rbegin(); i != digits.rend(); ++i ) {
            dst << std::setw( digitsCount ) << (int)*i;
        }
        return dst;
    }

    int Length() const { return digits.size() - ( digits[digits.size() - 1] == 0 ); }

};

template<typename TStream>
TStream& operator << ( TStream& dst, const PowerOf2VeryLongNumber& x )
{
    return x.Output( dst );
}

struct Result {
    int PowerValue;
    PowerOf2VeryLongNumber x;
};

int _tmain(int argc, _TCHAR* argv[])
{
    initTables();
    
    PowerOf2VeryLongNumber x;
    std::vector<Result> result;
    Result tmp = { 0 };
    result.push_back( tmp );
    for( int i = 1; i < tryTo; i++ ) {
        int zCount = x.Mult2AndRetMax0Count();
        if( ( i % logPeriod ) == 0 ) {
            std::cout << "2^" << i << " = " << zCount << ", " << result.size() - 1 
                << ", len = " << x.Length() << "    \r";
        }
        while( result.size() <= zCount ) {
            Result r = { i, x };
            result.push_back( r );
            std::cout << "2^" << i << " = " << zCount << ", " << result.size() - 1 
                << ", len = " << x.Length() /*<< ", " << x*/ << std::endl;
        }
    }
    std::cout << "--------------------------" << std::endl;
    for( int i = 1; i < result.size(); i++ ) {
        std::cout << "a(" << i << ") = 2^" << result[i].PowerValue << ", len = " << result[i].x.Length() 
            /*<< " = " << result[i].x */<< std::endl;
    }

    return 0;
}


a(9) за пять минут
Core(TM)2 Duo, 2.66 GHz, однопоточная программа.
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[4]: k нулей
От: Erop Россия  
Дата: 20.12.08 13:33
Оценка:
Здравствуйте, Seon, Вы писали:

S>Последнее число, в котором нет двух нулей подряд — 2^2114 !

Два вопроса.
1) Какие есть ваши доказательства?
2) "2114!" -- это факториал?
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.