Skip to content

Commit

Permalink
Merge pull request #1050 from maspypy/longest_common_substring
Browse files Browse the repository at this point in the history
[問題追加] Longest common substring
  • Loading branch information
maspypy authored Nov 12, 2023
2 parents 2f96c0a + 1c17526 commit 7d62d45
Show file tree
Hide file tree
Showing 16 changed files with 591 additions and 0 deletions.
71 changes: 71 additions & 0 deletions string/longest_common_substring/checker.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
// 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);

string s = inf.readToken();
string t = inf.readToken();
int n = s.size(), m = t.size();

int a1 = ans.readInt(0, n);
int b1 = ans.readInt(0, n);
int c1 = ans.readInt(0, m);
int d1 = ans.readInt(0, m);

int a2 = ouf.readInt(0, n);
int b2 = ouf.readInt(0, n);
int c2 = ouf.readInt(0, m);
int d2 = ouf.readInt(0, m);

auto check = [&](int a, int b, int c, int d) -> int {
// ng: -1
// ok: length
if (!(0 <= a && a <= b && b <= n)) return -1;
if (!(0 <= c && c <= d && d <= m)) return -1;
if (a == b && a != 0) return -1;
if (c == d && c != 0) return -1;
if (b - a != d - c) return -1;
int n = b - a;
for (int i = 0; i < n; ++i) {
if (s[a + i] != t[c + i]) return -1;
}
return b - a;
};

int x1 = check(a1, b1, c1, d1);
int x2 = check(a2, b2, c2, d2);

if (x1 == -1 || x1 < x2) {
quitf(_fail, "participant has the better answer");
}
if (x2 == -1) { quitf(_wa, "not common substrings"); }
if (x2 < x1) { quitf(_wa, "not longest"); }
quitf(_ok, "ok");
}
22 changes: 22 additions & 0 deletions string/longest_common_substring/gen/all_same.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#include <cstdio>
#include <string>
#include "random.h"
#include "../params.h"

using namespace std;

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

int n = gen.uniform(N_MAX - 10000, N_MAX);
int m = gen.uniform(N_MAX - 10000, N_MAX);

char c = gen.uniform('a', 'z');
string s(n, c);
string t(m, c);

printf("%s\n", s.c_str());
printf("%s\n", t.c_str());
return 0;
}
2 changes: 2 additions & 0 deletions string/longest_common_substring/gen/example_00.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
abcdef
abcxdef
2 changes: 2 additions & 0 deletions string/longest_common_substring/gen/example_01.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
aaa
bbbb
2 changes: 2 additions & 0 deletions string/longest_common_substring/gen/example_02.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
abcabcabc
cabcabcab
2 changes: 2 additions & 0 deletions string/longest_common_substring/gen/example_03.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
aaa
aaaaa
32 changes: 32 additions & 0 deletions string/longest_common_substring/gen/max_large_ans.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
#include <iostream>
#include "random.h"
#include "../params.h"

using namespace std;

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

int KIND[] = {2, 3, 10, 26};

int n = gen.uniform(N_MAX - 100, N_MAX);
int m = gen.uniform(N_MAX - 100, N_MAX);
int K = KIND[seed % 4];

string s, t;
for (int i = 0; i < n; ++i) { s += 'a' + gen.uniform(0, K - 1); }
for (int i = 0; i < m; ++i) { t += 'a' + gen.uniform(0, K - 1); }

int L = gen.uniform<int>(min(n, m) / 2, min(n, m));
int p = gen.uniform<int>(0, n - L);
int q = gen.uniform<int>(0, m - L);
for (int i = 0; i < L; ++i) {
char ch = 'a' + gen.uniform(0, K - 1);
s[p + i] = t[q + i] = ch;
}

printf("%s\n", s.c_str());
printf("%s\n", t.c_str());
return 0;
}
24 changes: 24 additions & 0 deletions string/longest_common_substring/gen/max_random.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#include <iostream>
#include "random.h"
#include "../params.h"

using namespace std;

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

int KIND[] = {2, 3, 10, 26};

int n = gen.uniform(N_MAX - 100, N_MAX);
int m = gen.uniform(N_MAX - 100, N_MAX);
int K = KIND[seed % 4];

string s, t;
for (int i = 0; i < n; ++i) { s += 'a' + gen.uniform(0, K - 1); }
for (int i = 0; i < m; ++i) { t += 'a' + gen.uniform(0, K - 1); }

printf("%s\n", s.c_str());
printf("%s\n", t.c_str());
return 0;
}
24 changes: 24 additions & 0 deletions string/longest_common_substring/gen/random.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#include <iostream>
#include "random.h"
#include "../params.h"

using namespace std;

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

int KIND[] = {2, 3, 10, 26};

int n = gen.uniform(1, (int)N_MAX);
int m = gen.uniform(1, (int)N_MAX);
int K = KIND[seed % 4];

string s, t;
for (int i = 0; i < n; ++i) { s += 'a' + gen.uniform(0, K - 1); }
for (int i = 0; i < m; ++i) { t += 'a' + gen.uniform(0, K - 1); }

printf("%s\n", s.c_str());
printf("%s\n", t.c_str());
return 0;
}
18 changes: 18 additions & 0 deletions string/longest_common_substring/gen/small.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
#include <iostream>
#include "random.h"

using namespace std;

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

int n = gen.uniform(1, 5);
int m = gen.uniform(1, 5);
string s, t;
for (int i = 0; i < n; ++i) s += gen.uniform('a', 'b');
for (int i = 0; i < m; ++i) t += gen.uniform('a', 'b');
printf("%s\n", s.c_str());
printf("%s\n", t.c_str());
return 0;
}
58 changes: 58 additions & 0 deletions string/longest_common_substring/hash.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
{
"all_same_00.in": "b9bd0fa1bb3f5a754014d874d10eefa186a73dd8bc74096c07e9efb9bba685c2",
"all_same_00.out": "0802837b1908a9683c325c7e7719b7ce1e2a09f203b427be5703543633045cf7",
"all_same_01.in": "b9ed981369b0e58c1d2e4ca8e704fac49dcee8030671ece396ecd72d8c001ce2",
"all_same_01.out": "f1b6252408c85cf2c5e50bdcf49e7867336c9badf823d10cb255687806cb3eb5",
"all_same_02.in": "04cb0f5e3a17daf1d0a7e1dad9b0b50400002b43e6752b9d70ea158b3afb1663",
"all_same_02.out": "55d773babd80603f1824ad1ab27486973ef211da7cb81a2a6f596e8c55c1a007",
"all_same_03.in": "6c69ba6c810aca172e3098180445feb84f0c6546edc7f5d4f413b31aa2450a06",
"all_same_03.out": "138392b026f56fd35952d9cf7b0efdab78d1351a16ce04865c81af56d12f81e3",
"example_00.in": "768e4422298833c3db3565dfd038edf75629a368cb396d2578edb57a005d01ff",
"example_00.out": "787174cfc13e56b3c86f1a7f6c2f961ab8165dd56431b0246cd1bf3b60e587c4",
"example_01.in": "d9de1a4597743916125cc694cc827ea593c56feece622d9204057afa966b3224",
"example_01.out": "c5bea6d5172950ed3fc3f0433afd51fc1913e545f5dd34c849c65dc166209a00",
"example_02.in": "8396a5c3d02efac4ead5a5dd2403e11a7f48caca917e5de2a759fc46c653355a",
"example_02.out": "fe3573c102e23f09c712eeb66a9e71f478873b4a33ef5983ebdfac798ceb537a",
"example_03.in": "cb5c441d64a6a143b9465c7d7dfab63956c159b232932386797b44123e2d7b4b",
"example_03.out": "ab545c8c6e6abe6139551a30c54bbee20671b923d6a19f241fb9b4bcc8f8feb8",
"max_large_ans_00.in": "67d4e1b771eb8bfc763bff549d78f86cd5a481b6dd82bda4eb2b1c813e5cb6e8",
"max_large_ans_00.out": "89b77884d667aaf3d8c56524e9fb5caa3d2bf8003fb287f1d3781b6fdb420a28",
"max_large_ans_01.in": "34bea1f5a4c81b9d216a6ff4fbefa58a4e89872b64129bde8d353da16afadcb7",
"max_large_ans_01.out": "cc9f90c6fe7833b3db6ddace18651ced849c4e1e021aefbb0aa5ce85023de418",
"max_large_ans_02.in": "cf1e9a1f8653369bf16b9189634ad38de44840c2641b78b1d3c61c56bf62d4bf",
"max_large_ans_02.out": "20b6912107dda0836c2ae814ed67d535daabb5881da27f138a1889e9fa75dbb7",
"max_large_ans_03.in": "210903e5e814b8a764a9a374ebbd1349288d7299ea8936441d1f039862a5c33d",
"max_large_ans_03.out": "c53a05e9f46138ff86db77d7d8fc681c266738b3e483a1b1d8759193aa7475c0",
"max_random_00.in": "b3d353839c943aa3ea4edcacb04cd21c21064d459717cd2bed892e5aa8d37f21",
"max_random_00.out": "33b0dcc0e3d4dbe2f5ee46738b7018792265f33576275f7df918e612568d84cf",
"max_random_01.in": "bbea89c72e5d3d8c3cca4bbd2de1a1939d65e045ef9ccb35c9bdd376a4796e6d",
"max_random_01.out": "c9cfcb871e4c4bf7076ac5976b6e88d83db9dc0942d1ab14132ba910eb4e37e2",
"max_random_02.in": "bb6c65c9de9509a2f2864ef4e1afc799ccad38820dd39f315b70715948c1dcd5",
"max_random_02.out": "778ef6097097c7467cc0f36fd6c758a72f6f43a01ca635c08afcdb60335f42c5",
"max_random_03.in": "254bc554eb96acfc0fcc9fed8a59851332a118ce425104b7fa4779a3c83fdd42",
"max_random_03.out": "b33ab751dbe776539a138d1502ee43e07e46379fce51c332157673637401d528",
"random_00.in": "d61695c3ec0758d3a9670a714c24fde0e67d7f6a095282cd01c69a908c34540a",
"random_00.out": "0d19965cb326b49062dcd59f65b44a1584932a87858f25bc49eb358eee90bbd4",
"random_01.in": "3daa89e99a47011ac287e5f7ce91d597dc747c95e650f3c689fb16f94cb87af7",
"random_01.out": "a942ff3da294900ad072e4e761de7e08f1e5f69825ef46ae3a71393e62937edc",
"random_02.in": "6b0a2b426bd1a9ebfbe46419c028a2f46877f1552e828a3783a9d4f5d869a127",
"random_02.out": "59be375c6a4139c0d552af57ee988672d4f857724b277bc62f0a936c5a1e0e14",
"random_03.in": "15cd2048bb2bc1bdc9de64fa35e1fbd8fb4a767d0efc8bded1c5cbe7aa1836e2",
"random_03.out": "e438f8d13a747129f17ef1c8dd3bbd928710b67d9c719ab2faa4f9f2c00a0aef",
"small_00.in": "cb4ef1059e8effea3931f9689e974bb477499175620ed487832fa2b9b8351e1c",
"small_00.out": "09603ed93118aad395dedbacc3e28f129d6d3005b847f8e67b235e419cf2abcf",
"small_01.in": "6a2eafd4bfc7282c1630f181ad7cbfab23108c0ce49b08839df692bc396db2bc",
"small_01.out": "ee109cef07f982a81f899fc10cd1a655fb13cb872330d07253c4b7bcc79d238b",
"small_02.in": "b95c43ccb0eee946906695c962f4ab7560b0a4c8eb1204e4b323ec5fd5fc13a8",
"small_02.out": "787174cfc13e56b3c86f1a7f6c2f961ab8165dd56431b0246cd1bf3b60e587c4",
"small_03.in": "2b7dc3c75a19c838ecf1288e6114654a503188730c19815a360c15cf1ac55e96",
"small_03.out": "c599325de6373b90181705169530b2a8f8c6edef9b23d6d8b4ce8bfd6417f77c",
"small_04.in": "1ff4855096547a55218bf0db1220fd913ad3f9635be926d8689d866c483bebe8",
"small_04.out": "ee109cef07f982a81f899fc10cd1a655fb13cb872330d07253c4b7bcc79d238b",
"small_05.in": "f34abe824989e8f63970827fcd282b62c21670e5614c789b29b5012bbb6c2774",
"small_05.out": "552311cd45ba8a4fe63329ed90c1bfccff644e32c3c8e65885a975414da07bf7",
"small_06.in": "c5d1851ef36ec1bf11e88c22370849af8037b875bdbbaa1cfbff078fefd968f2",
"small_06.out": "ae66db8c4386d209a3eeacfc5cd232d11a1bcd195a96010c90a0e8090726227c",
"small_07.in": "1cc1f30d51e045e022a44560fadf99edddd5d71d22744132cf24e401fa2baddf",
"small_07.out": "1128e50b56ce8805fe2a5b9cb97b8f20fd03dce87777343f4841bc2bc80add33"
}
30 changes: 30 additions & 0 deletions string/longest_common_substring/info.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
title = 'Longest Common Substring'
timelimit = 5.0
forum = "https://github.com/yosupo06/library-checker-problems/issues/889"

[[tests]]
name = "example.in"
number = 4
[[tests]]
name = "small.cpp"
number = 8
[[tests]]
name = "random.cpp"
number = 4
[[tests]]
name = "max_random.cpp"
number = 4
[[tests]]
name = "max_large_ans.cpp"
number = 4
[[tests]]
name = "all_same.cpp"
number = 4

[[solutions]]
name = "naive.cpp"
allow_tle = true


[params]
N_MAX = 500_000
Loading

0 comments on commit 7d62d45

Please sign in to comment.