-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathconvfrom.cpp
66 lines (58 loc) · 1.63 KB
/
convfrom.cpp
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
#include <fstream>
#include <iterator>
#include <iostream>
#include <array>
#include <vector>
using raw = std::array<uint8_t, 3>;
using to = std::array<uint8_t, 8>;
constexpr std::array<char, 8> convFrom{
'>', '<', '+', '-', '[', ']', '.', ','
};
to to3bits(raw from)
{
to buf;
buf[0] = from[0] >> 5;
buf[1] = (from[0] & 0b00011100) >> 2;
buf[2] = ((from[0] & 0b11) << 1) | (from[1] >> 7);
buf[3] = (from[1] & 0b01110000) >> 4;
buf[4] = (from[1] & 0b00001110) >> 1;
buf[5] = ((from[1] & 0b1) << 2) | (from[2] >> 6);
buf[6] = (from[2] & 0b00111000) >> 3;
buf[7] = from[2] & 0b111;
return buf;
}
void padTo3(std::vector<uint8_t>& vec) {
int j = vec.size() % 3;
if (j == 0) return;
for (int i = 0; i < (3-j); ++i) vec.push_back(0);
}
std::vector<raw> groupRaw(const std::vector<uint8_t>& vec) {
std::vector<raw> buf;
buf.reserve(vec.size()/3);
for (int i = 3; i <= vec.size(); i += 3)
buf.push_back(raw { vec[i-3], vec[i-2], vec[i-1] });
return buf;
}
std::vector<to> rawToTo(const std::vector<raw>& vec) {
std::vector<to> buf;
buf.reserve(vec.size());
for (const raw& it : vec) buf.push_back(to3bits(it));
return buf;
}
std::vector<uint8_t> flattenTo(const std::vector<to>& vec) {
std::vector<uint8_t> buf;
buf.reserve(vec.size()*8);
for (const to& it : vec) {
for (uint8_t n : it) buf.push_back(n);
}
return buf;
}
int main(int argc, char* argv[])
{
std::istream_iterator<uint8_t> begin(std::cin), end;
std::vector<uint8_t> bytes(begin, end);
padTo3(bytes);
std::vector<uint8_t> decode = flattenTo(rawToTo(groupRaw(bytes)));
for (uint8_t i : decode) std::cout.put(convFrom[i]);
return 0;
}