add zip
This commit is contained in:
@ -7,4 +7,5 @@ include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include)
|
||||
|
||||
add_executable(server main.cpp)
|
||||
|
||||
add_executable(client advanced.cpp) # For advanced task
|
||||
add_executable(client advanced.cpp) # For advanced task
|
||||
add_executable(tablegenerator tablegenerator.cpp miniz.c)
|
7833
src/miniz.c
Normal file
7833
src/miniz.c
Normal file
File diff suppressed because it is too large
Load Diff
1422
src/miniz.h
Normal file
1422
src/miniz.h
Normal file
File diff suppressed because it is too large
Load Diff
427
src/tablegenerator.cpp
Normal file
427
src/tablegenerator.cpp
Normal file
@ -0,0 +1,427 @@
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
#include <cstring>
|
||||
#include <iostream>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
#include "miniz.h"
|
||||
//====
|
||||
//
|
||||
// base64 encoding and decoding with C++.
|
||||
// Version: 2.rc.09 (release candidate)
|
||||
//
|
||||
|
||||
#ifndef BASE64_H_C0CE2A47_D10E_42C9_A27C_C883944E704A
|
||||
#define BASE64_H_C0CE2A47_D10E_42C9_A27C_C883944E704A
|
||||
|
||||
#include <string>
|
||||
|
||||
#if __cplusplus >= 201703L
|
||||
#include <string_view>
|
||||
#endif // __cplusplus >= 201703L
|
||||
|
||||
std::string base64_encode(std::string const &s, bool url = false);
|
||||
std::string base64_encode_pem(std::string const &s);
|
||||
std::string base64_encode_mime(std::string const &s);
|
||||
|
||||
std::string base64_decode(std::string const &s, bool remove_linebreaks = false);
|
||||
std::string base64_encode(unsigned char const *, size_t len, bool url = false);
|
||||
|
||||
#if __cplusplus >= 201703L
|
||||
//
|
||||
// Interface with std::string_view rather than const std::string&
|
||||
// Requires C++17
|
||||
// Provided by Yannic Bonenberger (https://github.com/Yannic)
|
||||
//
|
||||
std::string base64_encode(std::string_view s, bool url = false);
|
||||
std::string base64_encode_pem(std::string_view s);
|
||||
std::string base64_encode_mime(std::string_view s);
|
||||
|
||||
std::string base64_decode(std::string_view s, bool remove_linebreaks = false);
|
||||
#endif // __cplusplus >= 201703L
|
||||
|
||||
#endif /* BASE64_H_C0CE2A47_D10E_42C9_A27C_C883944E704A */
|
||||
/*
|
||||
base64.cpp and base64.h
|
||||
|
||||
base64 encoding and decoding with C++.
|
||||
More information at
|
||||
https://renenyffenegger.ch/notes/development/Base64/Encoding-and-decoding-base-64-with-cpp
|
||||
|
||||
Version: 2.rc.09 (release candidate)
|
||||
|
||||
Copyright (C) 2004-2017, 2020-2022 René Nyffenegger
|
||||
|
||||
This source code is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the author be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this source code must not be misrepresented; you must not
|
||||
claim that you wrote the original source code. If you use this source code
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original source code.
|
||||
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
|
||||
René Nyffenegger rene.nyffenegger@adp-gmbh.ch
|
||||
|
||||
*/
|
||||
|
||||
#include <algorithm>
|
||||
#include <stdexcept>
|
||||
|
||||
//
|
||||
// Depending on the url parameter in base64_chars, one of
|
||||
// two sets of base64 characters needs to be chosen.
|
||||
// They differ in their last two characters.
|
||||
//
|
||||
static const char *base64_chars[2] = {
|
||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
||||
"abcdefghijklmnopqrstuvwxyz"
|
||||
"0123456789"
|
||||
"+/",
|
||||
|
||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
||||
"abcdefghijklmnopqrstuvwxyz"
|
||||
"0123456789"
|
||||
"-_"};
|
||||
|
||||
static unsigned int pos_of_char(const unsigned char chr) {
|
||||
//
|
||||
// Return the position of chr within base64_encode()
|
||||
//
|
||||
|
||||
if (chr >= 'A' && chr <= 'Z')
|
||||
return chr - 'A';
|
||||
else if (chr >= 'a' && chr <= 'z')
|
||||
return chr - 'a' + ('Z' - 'A') + 1;
|
||||
else if (chr >= '0' && chr <= '9')
|
||||
return chr - '0' + ('Z' - 'A') + ('z' - 'a') + 2;
|
||||
else if (chr == '+' || chr == '-')
|
||||
return 62; // Be liberal with input and accept both url ('-') and non-url
|
||||
// ('+') base 64 characters (
|
||||
else if (chr == '/' || chr == '_')
|
||||
return 63; // Ditto for '/' and '_'
|
||||
else
|
||||
//
|
||||
// 2020-10-23: Throw std::exception rather than const char*
|
||||
//(Pablo Martin-Gomez, https://github.com/Bouska)
|
||||
//
|
||||
throw std::runtime_error("Input is not valid base64-encoded data.");
|
||||
}
|
||||
|
||||
static std::string insert_linebreaks(std::string str, size_t distance) {
|
||||
//
|
||||
// Provided by https://github.com/JomaCorpFX, adapted by me.
|
||||
//
|
||||
if (!str.length()) {
|
||||
return "";
|
||||
}
|
||||
|
||||
size_t pos = distance;
|
||||
|
||||
while (pos < str.size()) {
|
||||
str.insert(pos, "\n");
|
||||
pos += distance + 1;
|
||||
}
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
template <typename String, unsigned int line_length>
|
||||
static std::string encode_with_line_breaks(String s) {
|
||||
return insert_linebreaks(base64_encode(s, false), line_length);
|
||||
}
|
||||
|
||||
template <typename String>
|
||||
static std::string encode_pem(String s) {
|
||||
return encode_with_line_breaks<String, 64>(s);
|
||||
}
|
||||
|
||||
template <typename String>
|
||||
static std::string encode_mime(String s) {
|
||||
return encode_with_line_breaks<String, 76>(s);
|
||||
}
|
||||
|
||||
template <typename String>
|
||||
static std::string encode(String s, bool url) {
|
||||
return base64_encode(reinterpret_cast<const unsigned char *>(s.data()),
|
||||
s.length(), url);
|
||||
}
|
||||
|
||||
std::string base64_encode(unsigned char const *bytes_to_encode, size_t in_len,
|
||||
bool url) {
|
||||
size_t len_encoded = (in_len + 2) / 3 * 4;
|
||||
|
||||
unsigned char trailing_char = url ? '.' : '=';
|
||||
|
||||
//
|
||||
// Choose set of base64 characters. They differ
|
||||
// for the last two positions, depending on the url
|
||||
// parameter.
|
||||
// A bool (as is the parameter url) is guaranteed
|
||||
// to evaluate to either 0 or 1 in C++ therefore,
|
||||
// the correct character set is chosen by subscripting
|
||||
// base64_chars with url.
|
||||
//
|
||||
const char *base64_chars_ = base64_chars[url];
|
||||
|
||||
std::string ret;
|
||||
ret.reserve(len_encoded);
|
||||
|
||||
unsigned int pos = 0;
|
||||
|
||||
while (pos < in_len) {
|
||||
ret.push_back(base64_chars_[(bytes_to_encode[pos + 0] & 0xfc) >> 2]);
|
||||
|
||||
if (pos + 1 < in_len) {
|
||||
ret.push_back(base64_chars_[((bytes_to_encode[pos + 0] & 0x03) << 4) +
|
||||
((bytes_to_encode[pos + 1] & 0xf0) >> 4)]);
|
||||
|
||||
if (pos + 2 < in_len) {
|
||||
ret.push_back(base64_chars_[((bytes_to_encode[pos + 1] & 0x0f) << 2) +
|
||||
((bytes_to_encode[pos + 2] & 0xc0) >> 6)]);
|
||||
ret.push_back(base64_chars_[bytes_to_encode[pos + 2] & 0x3f]);
|
||||
} else {
|
||||
ret.push_back(base64_chars_[(bytes_to_encode[pos + 1] & 0x0f) << 2]);
|
||||
ret.push_back(trailing_char);
|
||||
}
|
||||
} else {
|
||||
ret.push_back(base64_chars_[(bytes_to_encode[pos + 0] & 0x03) << 4]);
|
||||
ret.push_back(trailing_char);
|
||||
ret.push_back(trailing_char);
|
||||
}
|
||||
|
||||
pos += 3;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
template <typename String>
|
||||
static std::string decode(String const &encoded_string,
|
||||
bool remove_linebreaks) {
|
||||
//
|
||||
// decode(…) is templated so that it can be used with String = const
|
||||
// std::string& or std::string_view (requires at least C++17)
|
||||
//
|
||||
|
||||
if (encoded_string.empty()) return std::string();
|
||||
|
||||
if (remove_linebreaks) {
|
||||
std::string copy(encoded_string);
|
||||
|
||||
copy.erase(std::remove(copy.begin(), copy.end(), '\n'), copy.end());
|
||||
|
||||
return base64_decode(copy, false);
|
||||
}
|
||||
|
||||
size_t length_of_string = encoded_string.length();
|
||||
size_t pos = 0;
|
||||
|
||||
//
|
||||
// The approximate length (bytes) of the decoded string might be one or
|
||||
// two bytes smaller, depending on the amount of trailing equal signs
|
||||
// in the encoded string. This approximation is needed to reserve
|
||||
// enough space in the string to be returned.
|
||||
//
|
||||
size_t approx_length_of_decoded_string = length_of_string / 4 * 3;
|
||||
std::string ret;
|
||||
ret.reserve(approx_length_of_decoded_string);
|
||||
|
||||
while (pos < length_of_string) {
|
||||
//
|
||||
// Iterate over encoded input string in chunks. The size of all
|
||||
// chunks except the last one is 4 bytes.
|
||||
//
|
||||
// The last chunk might be padded with equal signs or dots
|
||||
// in order to make it 4 bytes in size as well, but this
|
||||
// is not required as per RFC 2045.
|
||||
//
|
||||
// All chunks except the last one produce three output bytes.
|
||||
//
|
||||
// The last chunk produces at least one and up to three bytes.
|
||||
//
|
||||
|
||||
size_t pos_of_char_1 = pos_of_char(encoded_string.at(pos + 1));
|
||||
|
||||
//
|
||||
// Emit the first output byte that is produced in each chunk:
|
||||
//
|
||||
ret.push_back(static_cast<std::string::value_type>(
|
||||
((pos_of_char(encoded_string.at(pos + 0))) << 2) +
|
||||
((pos_of_char_1 & 0x30) >> 4)));
|
||||
|
||||
if ((pos + 2 <
|
||||
length_of_string) && // Check for data that is not padded with equal
|
||||
// signs (which is allowed by RFC 2045)
|
||||
encoded_string.at(pos + 2) != '=' &&
|
||||
encoded_string.at(pos + 2) !=
|
||||
'.' // accept URL-safe base 64 strings, too, so check for '.' also.
|
||||
) {
|
||||
//
|
||||
// Emit a chunk's second byte (which might not be produced in the last
|
||||
// chunk).
|
||||
//
|
||||
unsigned int pos_of_char_2 = pos_of_char(encoded_string.at(pos + 2));
|
||||
ret.push_back(static_cast<std::string::value_type>(
|
||||
((pos_of_char_1 & 0x0f) << 4) + ((pos_of_char_2 & 0x3c) >> 2)));
|
||||
|
||||
if ((pos + 3 < length_of_string) && encoded_string.at(pos + 3) != '=' &&
|
||||
encoded_string.at(pos + 3) != '.') {
|
||||
//
|
||||
// Emit a chunk's third byte (which might not be produced in the last
|
||||
// chunk).
|
||||
//
|
||||
ret.push_back(static_cast<std::string::value_type>(
|
||||
((pos_of_char_2 & 0x03) << 6) +
|
||||
pos_of_char(encoded_string.at(pos + 3))));
|
||||
}
|
||||
}
|
||||
|
||||
pos += 4;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
std::string base64_decode(std::string const &s, bool remove_linebreaks) {
|
||||
return decode(s, remove_linebreaks);
|
||||
}
|
||||
|
||||
std::string base64_encode(std::string const &s, bool url) {
|
||||
return encode(s, url);
|
||||
}
|
||||
|
||||
std::string base64_encode_pem(std::string const &s) { return encode_pem(s); }
|
||||
|
||||
std::string base64_encode_mime(std::string const &s) { return encode_mime(s); }
|
||||
|
||||
#if __cplusplus >= 201703L
|
||||
//
|
||||
// Interface with std::string_view rather than const std::string&
|
||||
// Requires C++17
|
||||
// Provided by Yannic Bonenberger (https://github.com/Yannic)
|
||||
//
|
||||
|
||||
std::string base64_encode(std::string_view s, bool url) {
|
||||
return encode(s, url);
|
||||
}
|
||||
|
||||
std::string base64_encode_pem(std::string_view s) { return encode_pem(s); }
|
||||
|
||||
std::string base64_encode_mime(std::string_view s) { return encode_mime(s); }
|
||||
|
||||
std::string base64_decode(std::string_view s, bool remove_linebreaks) {
|
||||
return decode(s, remove_linebreaks);
|
||||
}
|
||||
|
||||
#endif // __cplusplus >= 201703L
|
||||
//====
|
||||
using namespace std;
|
||||
typedef long long LL;
|
||||
int rid[15] = {0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2};
|
||||
int cid[15] = {0, 1, 2, 3, 4, 0, 1, 2, 3, 4, 0, 1, 2, 3, 4};
|
||||
// unordered_map<LL,LL> visible_to_inner;
|
||||
unordered_map<LL, vector<LL>> visible_to_inner;
|
||||
unordered_map<LL, LL> inner_to_visible;
|
||||
vector<LL> valid_visible_status;
|
||||
unordered_map<LL, double> visible_to_probability;
|
||||
void dfs(int depth, LL status) {
|
||||
// if (depth == 15) {
|
||||
for (int status = 0; status < 14348907; status++) {
|
||||
int inner_mp[3][5] = {0}, visible_map[3][5];
|
||||
LL status_tmp = status;
|
||||
for (int i = 0; i < 15; i++) {
|
||||
int row = rid[i], col = cid[i];
|
||||
inner_mp[row][col] = (status_tmp % 3); // uncode the inner_status
|
||||
status_tmp /= 3;
|
||||
}
|
||||
for (int row = 0; row < 3; row++)
|
||||
for (int col = 0; col < 5; col++) {
|
||||
if (inner_mp[row][col] == 0 || inner_mp[row][col] == 1) {
|
||||
visible_map[row][col] = 9; // 9 means unshown to player
|
||||
} else {
|
||||
int mcnt = 0;
|
||||
const int dx[8] = {-1, -1, -1, 0, 0, 1, 1, 1},
|
||||
dy[8] = {-1, 0, 1, -1, 1, -1, 0, 1};
|
||||
for (int i = 0; i < 8; i++) {
|
||||
int nr = row + dx[i], nc = col + dy[i];
|
||||
if (nr < 0 || nr >= 3 || nc < 0 || nc >= 5) continue;
|
||||
mcnt += (inner_mp[nr][nc] == 0 ? 1 : 0);
|
||||
}
|
||||
visible_map[row][col] = mcnt;
|
||||
}
|
||||
}
|
||||
LL visible_status = 0;
|
||||
for (int i = 0; i < 15; i++) {
|
||||
int row = rid[i], col = cid[i];
|
||||
visible_status = visible_status * 10 + visible_map[row][col];
|
||||
}
|
||||
inner_to_visible[status] = visible_status;
|
||||
visible_to_inner[visible_status].push_back(status);
|
||||
}
|
||||
// return;
|
||||
// }
|
||||
// dfs(depth + 1, status * 3 + 0); // 0 = mine and unclicked
|
||||
// dfs(depth + 1, status * 3 + 1); // 1 = no mine and unclicked
|
||||
// dfs(depth + 1, status * 3 + 2); // 2 = no mine and clicked
|
||||
}
|
||||
const int buf_size=4412555 * 4;
|
||||
unsigned char buf[buf_size],buf2[buf_size];
|
||||
int bcnt = 0;
|
||||
void CalculateProbability() {
|
||||
for (auto it = visible_to_inner.begin(); it != visible_to_inner.end(); ++it) {
|
||||
assert(it->second.size() > 0);
|
||||
int mine_cnt = 0;
|
||||
for (int i = 0; i < it->second.size(); i++) {
|
||||
mine_cnt += ((it->second[i] / 729) % 3 == 0 ? 1 : 0);
|
||||
}
|
||||
visible_to_probability[it->first] = double(mine_cnt) / it->second.size();
|
||||
buf[bcnt++] = int((double(mine_cnt) / it->second.size()) * 255);
|
||||
}
|
||||
}
|
||||
size_t compressData(const unsigned char* inputData, size_t inputSize, unsigned char* compressedData, size_t compressedSize) {
|
||||
mz_ulong compressedSizeOut = compressedSize;
|
||||
int compressResult = mz_compress2(compressedData, &compressedSizeOut,
|
||||
inputData, inputSize, MZ_BEST_COMPRESSION);
|
||||
|
||||
if (compressResult != Z_OK) {
|
||||
throw(std::runtime_error("Compression failed."));
|
||||
}
|
||||
|
||||
return compressedSizeOut;
|
||||
}
|
||||
|
||||
size_t decompressData(const unsigned char* compressedData, size_t compressedSize, unsigned char* decompressedData, size_t decompressedSize) {
|
||||
mz_ulong decompressedSizeOut = decompressedSize;
|
||||
int decompressResult = mz_uncompress(decompressedData, &decompressedSizeOut,
|
||||
compressedData, compressedSize);
|
||||
|
||||
if (decompressResult != Z_OK) {
|
||||
throw(std::runtime_error("Decompression failed."));
|
||||
}
|
||||
|
||||
return decompressedSizeOut;
|
||||
}
|
||||
int main() {
|
||||
dfs(0, 0);
|
||||
cout << visible_to_inner.size() << endl;
|
||||
CalculateProbability();
|
||||
freopen("tmp/data.txt", "w", stdout);
|
||||
string raw = base64_encode(buf, bcnt, false);
|
||||
cout << raw << endl;
|
||||
freopen("tmp/compressed.txt", "w", stdout);
|
||||
size_t real_size=compressData(buf, bcnt, buf2, buf_size);
|
||||
string compressed=base64_encode(buf2,real_size,false);
|
||||
cout<<compressed<<endl;
|
||||
return 0;
|
||||
}
|
Reference in New Issue
Block a user