Skip to content

Commit

Permalink
Merge pull request #1272 from NachiaVivias/count-c4s
Browse files Browse the repository at this point in the history
[問題追加] Counting C4's
  • Loading branch information
maspypy authored Nov 4, 2024
2 parents 282988c + 5be08b4 commit 6d26f5f
Show file tree
Hide file tree
Showing 20 changed files with 718 additions and 0 deletions.
62 changes: 62 additions & 0 deletions graph/counting_c4/checker.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
// https://github.com/MikeMirzayanov/testlib/blob/master/checkers/wcmp.cpp

// The MIT License (MIT)

// Copyright (c) 2015 Mike Mirzayanov

// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:

// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.

// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.

#include "testlib.h"

using namespace std;

int main(int argc, char * argv[])
{
setName("compare sequences of tokens");
registerTestlibCmd(argc, argv);

int n = 0;
string j, p;

while (!ans.seekEof() && !ouf.seekEof())
{
n++;

ans.readWordTo(j);
ouf.readWordTo(p);

if (j != p)
quitf(_wa, "%d%s words differ - expected: '%s', found: '%s'", n, englishEnding(n).c_str(), compress(j).c_str(), compress(p).c_str());
}

if (ans.seekEof() && ouf.seekEof())
{
if (n == 1)
quitf(_ok, "\"%s\"", compress(j).c_str());
else
quitf(_ok, "%d tokens", n);
}
else
{
if (ans.seekEof())
quitf(_wa, "Participant output contains extra tokens");
else
quitf(_wa, "Unexpected EOF in the participants output");
}
}
20 changes: 20 additions & 0 deletions graph/counting_c4/gen/dense.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#include "../params.h"
#include "random.h"
#include <cstdio>

int main(int, char **argv) {
long long seed = atoll(argv[1]);
auto gen = Random(seed);

int n = 10;
int m = M_MAX;

std::printf("%d %d\n", n, m);

for(int i=0; i<m; i++){
int u = gen.uniform(0, n-1);
int v = gen.uniform(0, n-2);
if(u <= v) v += 1;
std::printf("%d %d\n", u, v);
}
}
41 changes: 41 additions & 0 deletions graph/counting_c4/gen/erdos_renyi.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
#include "random.h"
#include <algorithm>
#include <cassert>
#include <cstdio>
#include <set>
#include <utility>
#include <vector>

void erdos_renyi(int n, int m, Random &gen) {
assert(static_cast<long long>(n) * (n - 1) / 2 >= m);

std::vector<std::pair<int, int>> edges(m);
if (static_cast<long long>(n) * (n - 1) / 2 > m * 2) {
// sparse
std::set<std::pair<int, int>> eset;
for (auto &e : edges) {
do {
e = gen.uniform_pair(0, n - 1);
} while (!eset.insert(std::minmax(e.first, e.second)).second);
}
} else {
// dense
std::vector<std::pair<int, int>> all;
for (int u = 0; u < n; ++u) {
for (int v = 0; v < u; ++v) {
if (gen.uniform_bool()) {
all.emplace_back(u, v);
} else {
all.emplace_back(v, u);
}
}
}
gen.shuffle(all.begin(), all.end());
std::copy(all.begin(), all.begin() + m, edges.begin());
}

std::printf("%d %d\n", n, m);
for (const auto &e : edges) {
std::printf("%d %d\n", e.first, e.second);
}
}
6 changes: 6 additions & 0 deletions graph/counting_c4/gen/example_00.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
4 5
0 3
2 0
2 1
2 3
1 3
8 changes: 8 additions & 0 deletions graph/counting_c4/gen/example_01.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
4 7
0 1
0 1
0 1
0 3
0 3
1 2
2 3
15 changes: 15 additions & 0 deletions graph/counting_c4/gen/large_random_simple.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#include "../params.h"
#include "./erdos_renyi.h"
#include "random.h"
#include <algorithm>

int main(int, char **argv) {
long long seed = atoll(argv[1]);
auto gen = Random(seed);

int n = gen.uniform<int>(N_MIN, N_MAX);
int m = gen.uniform<int>(
M_MIN, std::min(M_MAX, static_cast<long long>(n) * (n - 1) / 2));

erdos_renyi(n, m, gen);
}
16 changes: 16 additions & 0 deletions graph/counting_c4/gen/max_complete.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#include "../params.h"
#include "./erdos_renyi.h"
#include "random.h"

int main(int, char **argv) {
long long seed = atoll(argv[1]);
auto gen = Random(seed);

int n = N_MIN;
while (n < N_MAX && n * (n + 1) / 2 <= M_MAX) {
n += 1;
}
int m = n * (n - 1) / 2;

erdos_renyi(n, m, gen);
}
58 changes: 58 additions & 0 deletions graph/counting_c4/gen/max_near_k_simple.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
#include "../params.h"
#include "random.h"
#include <algorithm>
#include <cstdio>
#include <utility>
#include <vector>

std::vector<int> generate_phase(int n, int k){
std::vector<int> nph;
for(int t=0; t<k; t++) nph.push_back((n+t)/k);
return nph;
}

int main(int, char **argv) {
long long seed = atoll(argv[1]);
auto gen = Random(seed);

int m = int(M_MAX);
int k = seed + 2;

int n = 1;
while(true){
n++;
auto nph = generate_phase(n, k);
int nxm = 0;
for(int t=0; t<k; t++) for(int s=0; s<t; s++){
nxm += nph[t] * nph[s];
}
if(nxm >= m) break;
}

auto nph = generate_phase(n, k);
std::vector<int> beg_phase(k+1);
for(int t=0; t<k; t++) beg_phase[t+1] = beg_phase[t] + nph[t];

std::vector<std::pair<int, int>> edges;
for(int t=0; t<k; t++) for(int s=0; s<t; s++){
for(int p=0; p<nph[t]; p++) for(int q=0; q<nph[s]; q++){
int a = beg_phase[t] + p;
int b = beg_phase[s] + q;
edges.push_back({ a, b });
}
}

gen.shuffle(edges.begin(), edges.end());
edges.resize(m);

for (auto &e : edges) {
if (gen.uniform_bool()) {
std::swap(e.first, e.second);
}
}

std::printf("%d %d\n", n, m);
for (const auto &e : edges) {
std::printf("%d %d\n", e.first, e.second);
}
}
13 changes: 13 additions & 0 deletions graph/counting_c4/gen/max_random_simple.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#include "../params.h"
#include "./erdos_renyi.h"
#include "random.h"

int main(int, char **argv) {
long long seed = atoll(argv[1]);
auto gen = Random(seed);

int n = N_MAX;
int m = M_MAX;

erdos_renyi(n, m, gen);
}
2 changes: 2 additions & 0 deletions graph/counting_c4/gen/minimum_00.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
2 1
0 1
42 changes: 42 additions & 0 deletions graph/counting_c4/gen/multiplied_c4.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
#include "../params.h"
#include "random.h"
#include <algorithm>
#include <cstdio>
#include <utility>

int main(int, char **argv) {
long long seed = atoll(argv[1]);
auto gen = Random(seed);

int n = N_MAX;
int m = M_MAX;

// seed 0 : divide equally
// seed 1 : divide randomly

auto sp = gen.choice(3, 1, m-1);
if(seed == 0){
sp[0] = m / 4;
sp[1] = m * 2 / 4;
sp[2] = m * 3 / 4;
}
auto nodes = gen.choice(4, 0, n-1);

std::vector<std::pair<int, int>> edges;
for(int i=0; i<sp[0]; i++) edges.push_back({ nodes[0], nodes[1] });
for(int i=sp[0]; i<sp[1]; i++) edges.push_back({ nodes[1], nodes[2] });
for(int i=sp[1]; i<sp[2]; i++) edges.push_back({ nodes[2], nodes[3] });
for(int i=sp[2]; i<m; i++) edges.push_back({ nodes[3], nodes[0] });

for (auto &e : edges) {
if (gen.uniform_bool()) {
std::swap(e.first, e.second);
}
}
gen.shuffle(edges.begin(), edges.end());

std::printf("%d %d\n", n, m);
for (const auto &e : edges) {
std::printf("%d %d\n", e.first, e.second);
}
}
18 changes: 18 additions & 0 deletions graph/counting_c4/gen/small_dense_simple.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
#include "../params.h"
#include "./erdos_renyi.h"
#include "random.h"

int main(int, char **argv) {
long long seed = atoll(argv[1]);
auto gen = Random(seed);

int N_MAX_2 = 1;
while (N_MAX_2 < N_MAX && N_MAX_2 * (N_MAX_2 + 1) / 2 <= M_MAX) {
N_MAX_2 += 1;
}

int n = gen.uniform<int>(N_MIN, N_MAX_2);
int m = gen.uniform<int>(M_MIN, n * (n - 1) / 2);

erdos_renyi(n, m, gen);
}
20 changes: 20 additions & 0 deletions graph/counting_c4/gen/small_sparse_simple.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#include "../params.h"
#include "./erdos_renyi.h"
#include "random.h"
#include <algorithm>

int main(int, char **argv) {
long long seed = atoll(argv[1]);
auto gen = Random(seed);

int N_MAX_2 = 1;
while (N_MAX_2 < N_MAX && N_MAX_2 * (N_MAX_2 + 1) / 2 <= M_MAX) {
N_MAX_2 += 1;
}

int n = gen.uniform<int>(N_MIN, N_MAX_2);
int m =
gen.uniform<int>(M_MIN, std::min<int>({M_MAX, n * 2, n * (n - 1) / 2}));

erdos_renyi(n, m, gen);
}
35 changes: 35 additions & 0 deletions graph/counting_c4/gen/star.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
#include "../params.h"
#include "random.h"
#include <algorithm>
#include <cstdio>
#include <utility>

int main(int, char **argv) {
long long seed = atoll(argv[1]);
auto gen = Random(seed);

int n = std::min(N_MAX, M_MAX + 1);
int m = n - 1;

int center = gen.uniform(0, n - 1);

std::vector<std::pair<int, int>> edges;
for (int i = 0; i < n; ++i) {
if (i != center) {
edges.emplace_back(center, i);
}
}

for (auto &e : edges) {
if (gen.uniform_bool()) {
std::swap(e.first, e.second);
}
}

gen.shuffle(edges.begin(), edges.end());

std::printf("%d %d\n", n, m);
for (const auto &e : edges) {
std::printf("%d %d\n", e.first, e.second);
}
}
Loading

0 comments on commit 6d26f5f

Please sign in to comment.