| import random | |
| import string | |
| def generate_string(length, pattern_type="random"): | |
| if pattern_type == "random": | |
| return ''.join(random.choice('abcdefghijklmnopqrstuvwxyz') for _ in range(length)) | |
| elif pattern_type == "repetitive": | |
| base = random.choice('abcde') | |
| return base * length | |
| elif pattern_type == "alternating": | |
| chars = random.sample('abcdefghij', 2) | |
| return ''.join(chars[i % 2] for i in range(length)) | |
| elif pattern_type == "palindromic": | |
| half = ''.join(random.choice('abcde') for _ in range(length // 2)) | |
| if length % 2 == 0: | |
| return half + half[::-1] | |
| else: | |
| return half + random.choice('abcde') + half[::-1] | |
| def generate_adversarial_case_1(): | |
| # Case 1: Many queries on repetitive string | |
| initial_string = generate_string(1000, "repetitive") | |
| operations = [] | |
| # Add many queries that will have long LCP values | |
| for _ in range(100): | |
| x = random.randint(1, len(initial_string)) | |
| y = random.randint(1, len(initial_string)) | |
| operations.append(f"Q {x} {y}") | |
| # Add some modifications to break patterns | |
| for _ in range(20): | |
| pos = random.randint(1, len(initial_string)) | |
| char = random.choice('xyz') # Different from repetitive pattern | |
| operations.append(f"R {pos} {char}") | |
| # Query after modification | |
| x = random.randint(1, len(initial_string)) | |
| y = random.randint(1, len(initial_string)) | |
| operations.append(f"Q {x} {y}") | |
| result = initial_string + "\n" + str(len(operations)) + "\n" | |
| result += "\n".join(operations) | |
| return result | |
| def generate_adversarial_case_2(): | |
| # Case 2: Many insertions creating long string | |
| initial_string = generate_string(100, "random") | |
| operations = [] | |
| current_length = len(initial_string) | |
| # Insert many characters | |
| for _ in range(200): | |
| pos = random.randint(0, current_length) | |
| char = random.choice('abcdefghij') | |
| operations.append(f"I {pos} {char}") | |
| current_length += 1 | |
| # Occasionally query | |
| if random.random() < 0.3: | |
| x = random.randint(1, current_length) | |
| y = random.randint(1, current_length) | |
| operations.append(f"Q {x} {y}") | |
| result = initial_string + "\n" + str(len(operations)) + "\n" | |
| result += "\n".join(operations) | |
| return result | |
| def generate_adversarial_case_3(): | |
| # Case 3: Alternating pattern with strategic modifications | |
| initial_string = generate_string(500, "alternating") | |
| operations = [] | |
| # Query positions that should have predictable LCP | |
| for i in range(50): | |
| x = i * 2 + 1 | |
| y = i * 2 + 3 | |
| if x <= len(initial_string) and y <= len(initial_string): | |
| operations.append(f"Q {x} {y}") | |
| # Modify to break alternating pattern | |
| for i in range(30): | |
| pos = random.randint(1, len(initial_string)) | |
| char = random.choice('xyz') | |
| operations.append(f"R {pos} {char}") | |
| # Query nearby positions | |
| if pos > 1: | |
| operations.append(f"Q {pos-1} {pos}") | |
| if pos < len(initial_string): | |
| operations.append(f"Q {pos} {pos+1}") | |
| result = initial_string + "\n" + str(len(operations)) + "\n" | |
| result += "\n".join(operations) | |
| return result | |
| def generate_adversarial_case_4(): | |
| # Case 4: Palindromic string with edge case queries | |
| initial_string = generate_string(800, "palindromic") | |
| operations = [] | |
| # Query symmetric positions | |
| mid = len(initial_string) // 2 | |
| for i in range(40): | |
| left = mid - i | |
| right = mid + i + 1 | |
| if left >= 1 and right <= len(initial_string): | |
| operations.append(f"Q {left} {right}") | |
| # Insert at middle to break palindrome | |
| operations.append(f"I {mid} z") | |
| # Query again after breaking palindrome | |
| for i in range(20): | |
| left = mid - i | |
| right = mid + i + 2 # +2 because we inserted one char | |
| if left >= 1 and right <= len(initial_string) + 1: | |
| operations.append(f"Q {left} {right}") | |
| result = initial_string + "\n" + str(len(operations)) + "\n" | |
| result += "\n".join(operations) | |
| return result | |
| def generate_adversarial_case_5(): | |
| # Case 5: Maximum operations with mixed patterns | |
| initial_string = generate_string(1000, "random") | |
| operations = [] | |
| current_length = len(initial_string) | |
| for _ in range(1000): | |
| op_type = random.choice(['Q', 'R', 'I']) | |
| if op_type == 'Q': | |
| x = random.randint(1, current_length) | |
| y = random.randint(1, current_length) | |
| operations.append(f"Q {x} {y}") | |
| elif op_type == 'R': | |
| pos = random.randint(1, current_length) | |
| char = random.choice('abcdefghijklmnopqrstuvwxyz') | |
| operations.append(f"R {pos} {char}") | |
| else: # Insert | |
| if current_length < 100000: # Respect length constraint | |
| pos = random.randint(0, current_length) | |
| char = random.choice('abcdefghijklmnopqrstuvwxyz') | |
| operations.append(f"I {pos} {char}") | |
| current_length += 1 | |
| result = initial_string + "\n" + str(len(operations)) + "\n" | |
| result += "\n".join(operations) | |
| return result | |
| def construct_inputs(): | |
| inputs = [] | |
| # Generate different adversarial cases | |
| inputs.append(generate_adversarial_case_1()) | |
| inputs.append(generate_adversarial_case_2()) | |
| inputs.append(generate_adversarial_case_3()) | |
| inputs.append(generate_adversarial_case_4()) | |
| inputs.append(generate_adversarial_case_5()) | |
| # Add some edge cases | |
| # Single character string | |
| inputs.append("a\n3\nQ 1 1\nR 1 b\nQ 1 1") | |
| # Empty operations | |
| inputs.append("test\n0") | |
| # Only queries | |
| inputs.append("abcdef\n6\nQ 1 2\nQ 2 3\nQ 3 4\nQ 4 5\nQ 5 6\nQ 1 6") | |
| return inputs | |
Xet Storage Details
- Size:
- 5.97 kB
- Xet hash:
- 2308ab542e66c23e8d498c5ec226a3ab7ded7191dbb9cff75b2649c1f3057110
·
Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.