YAPC::EU 2018 Glasgow Update!
This commit is contained in:
parent
22f33d4004
commit
4e2d22a71d
1170 changed files with 15042 additions and 3047 deletions
|
|
@ -0,0 +1,241 @@
|
|||
#include <iostream>
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
#include <valarray>
|
||||
const std::string input {
|
||||
"................................"
|
||||
".#########.......########......."
|
||||
".###...####.....####..####......"
|
||||
".###....###.....###....###......"
|
||||
".###...####.....###............."
|
||||
".#########......###............."
|
||||
".###.####.......###....###......"
|
||||
".###..####..###.####..####.###.."
|
||||
".###...####.###..########..###.."
|
||||
"................................"
|
||||
};
|
||||
const std::string input2 {
|
||||
".........................................................."
|
||||
".#################...................#############........"
|
||||
".##################...............################........"
|
||||
".###################............##################........"
|
||||
".########.....#######..........###################........"
|
||||
"...######.....#######.........#######.......######........"
|
||||
"...######.....#######........#######......................"
|
||||
"...#################.........#######......................"
|
||||
"...################..........#######......................"
|
||||
"...#################.........#######......................"
|
||||
"...######.....#######........#######......................"
|
||||
"...######.....#######........#######......................"
|
||||
"...######.....#######.........#######.......######........"
|
||||
".########.....#######..........###################........"
|
||||
".########.....#######.######....##################.######."
|
||||
".########.....#######.######......################.######."
|
||||
".########.....#######.######.........#############.######."
|
||||
".........................................................."
|
||||
};
|
||||
|
||||
class ZhangSuen;
|
||||
|
||||
class Image {
|
||||
public:
|
||||
friend class ZhangSuen;
|
||||
using pixel_t = char;
|
||||
static const pixel_t BLACK_PIX;
|
||||
static const pixel_t WHITE_PIX;
|
||||
|
||||
Image(unsigned width = 1, unsigned height = 1)
|
||||
: width_{width}, height_{height}, data_( '\0', width_ * height_)
|
||||
{}
|
||||
Image(const Image& i) : width_{ i.width_}, height_{i.height_}, data_{i.data_}
|
||||
{}
|
||||
Image(Image&& i) : width_{ i.width_}, height_{i.height_}, data_{std::move(i.data_)}
|
||||
{}
|
||||
~Image() = default;
|
||||
Image& operator=(const Image& i) {
|
||||
if (this != &i) {
|
||||
width_ = i.width_;
|
||||
height_ = i.height_;
|
||||
data_ = i.data_;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
Image& operator=(Image&& i) {
|
||||
if (this != &i) {
|
||||
width_ = i.width_;
|
||||
height_ = i.height_;
|
||||
data_ = std::move(i.data_);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
size_t idx(unsigned x, unsigned y) const noexcept { return y * width_ + x; }
|
||||
bool operator()(unsigned x, unsigned y) {
|
||||
return data_[idx(x, y)];
|
||||
}
|
||||
friend std::ostream& operator<<(std::ostream& o, const Image& i) {
|
||||
o << i.width_ << " x " << i.height_ << std::endl;
|
||||
size_t px = 0;
|
||||
for(const auto& e : i.data_) {
|
||||
o << (e?Image::BLACK_PIX:Image::WHITE_PIX);
|
||||
if (++px % i.width_ == 0)
|
||||
o << std::endl;
|
||||
}
|
||||
return o << std::endl;
|
||||
}
|
||||
friend std::istream& operator>>(std::istream& in, Image& img) {
|
||||
auto it = std::begin(img.data_);
|
||||
const auto end = std::end(img.data_);
|
||||
Image::pixel_t tmp;
|
||||
while(in && it != end) {
|
||||
in >> tmp;
|
||||
if (tmp != Image::BLACK_PIX && tmp != Image::WHITE_PIX)
|
||||
throw "Bad character found in image";
|
||||
*it = (tmp == Image::BLACK_PIX)?1:0;
|
||||
++it;
|
||||
}
|
||||
return in;
|
||||
}
|
||||
unsigned width() const noexcept { return width_; }
|
||||
unsigned height() const noexcept { return height_; }
|
||||
struct Neighbours {
|
||||
// 9 2 3
|
||||
// 8 1 4
|
||||
// 7 6 5
|
||||
Neighbours(const Image& img, unsigned p1_x, unsigned p1_y)
|
||||
: img_{img}
|
||||
, p1_{img.idx(p1_x, p1_y)}
|
||||
, p2_{p1_ - img.width()}
|
||||
, p3_{p2_ + 1}
|
||||
, p4_{p1_ + 1}
|
||||
, p5_{p4_ + img.width()}
|
||||
, p6_{p5_ - 1}
|
||||
, p7_{p6_ - 1}
|
||||
, p8_{p1_ - 1}
|
||||
, p9_{p2_ - 1}
|
||||
{}
|
||||
const Image& img_;
|
||||
const Image::pixel_t& p1() const noexcept { return img_.data_[p1_]; }
|
||||
const Image::pixel_t& p2() const noexcept { return img_.data_[p2_]; }
|
||||
const Image::pixel_t& p3() const noexcept { return img_.data_[p3_]; }
|
||||
const Image::pixel_t& p4() const noexcept { return img_.data_[p4_]; }
|
||||
const Image::pixel_t& p5() const noexcept { return img_.data_[p5_]; }
|
||||
const Image::pixel_t& p6() const noexcept { return img_.data_[p6_]; }
|
||||
const Image::pixel_t& p7() const noexcept { return img_.data_[p7_]; }
|
||||
const Image::pixel_t& p8() const noexcept { return img_.data_[p8_]; }
|
||||
const Image::pixel_t& p9() const noexcept { return img_.data_[p9_]; }
|
||||
const size_t p1_, p2_, p3_, p4_, p5_, p6_, p7_, p8_, p9_;
|
||||
};
|
||||
Neighbours neighbours(unsigned x, unsigned y) const { return Neighbours(*this, x, y); }
|
||||
private:
|
||||
unsigned height_ { 0 };
|
||||
unsigned width_ { 0 };
|
||||
std::valarray<pixel_t> data_;
|
||||
};
|
||||
|
||||
constexpr const Image::pixel_t Image::BLACK_PIX = '#';
|
||||
constexpr const Image::pixel_t Image::WHITE_PIX = '.';
|
||||
|
||||
class ZhangSuen {
|
||||
public:
|
||||
|
||||
// the number of transitions from white to black, (0 -> 1) in the sequence P2,P3,P4,P5,P6,P7,P8,P9,P2
|
||||
unsigned transitions_white_black(const Image::Neighbours& a) const {
|
||||
unsigned sum = 0;
|
||||
sum += (a.p9() == 0) && a.p2();
|
||||
sum += (a.p2() == 0) && a.p3();
|
||||
sum += (a.p3() == 0) && a.p4();
|
||||
sum += (a.p8() == 0) && a.p9();
|
||||
sum += (a.p4() == 0) && a.p5();
|
||||
sum += (a.p7() == 0) && a.p8();
|
||||
sum += (a.p6() == 0) && a.p7();
|
||||
sum += (a.p5() == 0) && a.p6();
|
||||
return sum;
|
||||
}
|
||||
|
||||
// The number of black pixel neighbours of P1. ( = sum(P2 .. P9) )
|
||||
unsigned black_pixels(const Image::Neighbours& a) const {
|
||||
unsigned sum = 0;
|
||||
sum += a.p9();
|
||||
sum += a.p2();
|
||||
sum += a.p3();
|
||||
sum += a.p8();
|
||||
sum += a.p4();
|
||||
sum += a.p7();
|
||||
sum += a.p6();
|
||||
sum += a.p5();
|
||||
return sum;
|
||||
}
|
||||
const Image& operator()(const Image& img) {
|
||||
tmp_a_ = img;
|
||||
size_t changed_pixels = 0;
|
||||
do {
|
||||
changed_pixels = 0;
|
||||
// Step 1
|
||||
tmp_b_ = tmp_a_;
|
||||
for(size_t y = 1; y < tmp_a_.height() - 1; ++y) {
|
||||
for(size_t x = 1; x < tmp_a_.width() - 1; ++x) {
|
||||
if (tmp_a_.data_[tmp_a_.idx(x, y)]) {
|
||||
auto n = tmp_a_.neighbours(x, y);
|
||||
auto bp = black_pixels(n);
|
||||
if (bp >= 2 && bp <= 6) {
|
||||
auto tr = transitions_white_black(n);
|
||||
if ( tr == 1
|
||||
&& (n.p2() * n.p4() * n.p6() == 0)
|
||||
&& (n.p4() * n.p6() * n.p8() == 0)
|
||||
) {
|
||||
tmp_b_.data_[n.p1_] = 0;
|
||||
++changed_pixels;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// Step 2
|
||||
tmp_a_ = tmp_b_;
|
||||
for(size_t y = 1; y < tmp_b_.height() - 1; ++y) {
|
||||
for(size_t x = 1; x < tmp_b_.width() - 1; ++x) {
|
||||
if (tmp_b_.data_[tmp_b_.idx(x, y)]) {
|
||||
auto n = tmp_b_.neighbours(x, y);
|
||||
auto bp = black_pixels(n);
|
||||
if (bp >= 2 && bp <= 6) {
|
||||
auto tr = transitions_white_black(n);
|
||||
if ( tr == 1
|
||||
&& (n.p2() * n.p4() * n.p8() == 0)
|
||||
&& (n.p2() * n.p6() * n.p8() == 0)
|
||||
) {
|
||||
tmp_a_.data_[n.p1_] = 0;
|
||||
++changed_pixels;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} while(changed_pixels > 0);
|
||||
return tmp_a_;
|
||||
}
|
||||
private:
|
||||
Image tmp_a_;
|
||||
Image tmp_b_;
|
||||
};
|
||||
|
||||
int main(int argc, char const *argv[])
|
||||
{
|
||||
using namespace std;
|
||||
Image img(32, 10);
|
||||
istringstream iss{input};
|
||||
iss >> img;
|
||||
cout << img;
|
||||
cout << "ZhangSuen" << endl;
|
||||
ZhangSuen zs;
|
||||
Image res = std::move(zs(img));
|
||||
cout << res << endl;
|
||||
|
||||
Image img2(58,18);
|
||||
istringstream iss2{input2};
|
||||
iss2 >> img2;
|
||||
cout << img2;
|
||||
cout << "ZhangSuen with big image" << endl;
|
||||
Image res2 = std::move(zs(img2));
|
||||
cout << res2 << endl;
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -1,5 +1,3 @@
|
|||
/*Abhishek Ghosh, 24th September 2017*/
|
||||
|
||||
#include<stdlib.h>
|
||||
#include<stdio.h>
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue