Comment detail

METHINKS IT IS A WEASEL (Nested Flatten)

This comment is reply for 6309 ocean: お題を次のように変更しました。 1...(METHINKS IT IS A WEASEL). Go to thread root.

C++に移植してみました。

  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
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
#include <iostream>
#include <iomanip>
#include <string>
#include <vector>
#include <algorithm>
#include <cstdlib> // rand, RAND_MAX
#include <cassert>
#include <ctime>

const std::string goal = "METHINKS IT IS LIKE A WEASEL";

size_t random(size_t n) // [0, n)
{
    assert(n > 0);

    return static_cast<size_t>(std::rand() * (n + 1.0) / (RAND_MAX + 1.0));
}

char random_char()
{
    static const char table[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ ";

    return table[random(sizeof(table))];
}

std::string random_string()
{
    std::string s;

    s.resize(goal.size());

    std::generate(s.begin(), s.end(), random_char);

    return s;
}

class sentence
{
public:
    explicit sentence(const std::string& s = random_string());

    const std::string& str() const
    {
        return _s;
    }

    friend bool operator<(const sentence& lhs, const sentence& rhs)
    {
        return lhs._diff < rhs._diff;
    }

private:
    std::string _s;
    size_t _diff;
};

sentence::sentence(const std::string& s) : _s(s), _diff(0)
{
    assert(s.size() == goal.size());

    for (size_t i = 0; i < s.size(); ++i)
    {
        if (s[i] != goal[i])
        {
            ++_diff;
        }
    }
}

int main()
{
    std::srand(std::time(NULL));

    const size_t count = 300;

    std::vector<sentence> v(count);

    for (size_t generation = 1; ; ++generation)
    {
        std::sort(v.begin(), v.end());

        v.erase(v.begin() + count, v.end());

        std::cout << std::setw(4) << generation << ": " << v.front().str() << std::endl;

        if (v.front().str() == goal)
        {
            break;
        }

        for (size_t i = 0; i < count; ++i)
        {
            std::string s = v[i].str();

            s[random(s.size())] = random_char();

            v.push_back(sentence(s));
        }
    }
}

本当にこれで高速化するか試してませんが・・・部分ソートというのがあるみたいなので、使ってみました。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
--- main.cpp.old    Wed May 21 13:00:14 2008
+++ main.cpp.new    Wed May 21 19:04:41 2008
@@ -78,7 +78,7 @@
 
     for (size_t generation = 1; ; ++generation)
     {
-        std::sort(v.begin(), v.end());
+        std::partial_sort(v.begin(), v.begin() + count, v.end());
 
         v.erase(v.begin() + count, v.end());

Index

Feed

Other

Link

Pathtraq

loading...