diff --git a/tasks/easy/arrays/largest_perimeter_triangle.toml b/tasks/easy/arrays/largest_perimeter_triangle.toml new file mode 100644 index 0000000..4cad740 --- /dev/null +++ b/tasks/easy/arrays/largest_perimeter_triangle.toml @@ -0,0 +1,187 @@ +base_score = 100 +level = "easy" +name = "largest_perimeter_triangle" +tags = ["arrays", "math", "geometry", "sorting"] +time_to_solve_sec = 200 + +description_en = """ +Given an integer array `nums` representing the lengths of line segments, return the largest perimeter of a triangle with a non-zero area, formed from three of these lengths. + +If it is impossible to form any triangle, return `0`. + +A triangle can be formed by three segments of lengths $a$, $b$, and $c$ if and only if the sum of the lengths of any two segments is strictly greater than the length of the third segment (i.e., $a + b > c$). +""" + +description_ru = """ +Дан массив целых чисел `nums`, представляющий длины отрезков. Верните наибольший периметр треугольника с ненулевой площадью, который можно составить из трех таких отрезков. + +Если составить треугольник невозможно, верните `0`. + +Треугольник можно составить из трех отрезков с длинами $a$, $b$ и $c$, если и только если сумма длин любых двух отрезков строго больше длины третьего отрезка (то есть $a + b > c$). +""" + +limits = """ +- $3 \\leq \\text{len}(nums) \\leq 10^4$ +- $1 \\leq nums[i] \\leq 10^6$ +""" + +solution = """ +def solution(nums: list) -> int: + nums.sort(reverse=True) + for i in range(len(nums) - 2): + if nums[i] < nums[i+1] + nums[i+2]: + return nums[i] + nums[i+1] + nums[i+2] + return 0 +""" + +examples = """ +solution([1, 2, 1]) == 0 +solution([2, 1, 2]) == 5 +solution([3, 6, 2, 3]) == 8 +solution([3, 2, 3, 4]) == 10 +""" + +[[input_signature]] +argument_name = "nums" +[input_signature.type] +name = "array" +[input_signature.type.nested] +name = "integer" + +[output_signature.type] +name = "integer" + +[[asserts]] +arguments = [[2, 1, 2]] +comment = "Simple valid triangle" +expected = 5 + +[[asserts]] +arguments = [[1, 2, 1]] +comment = "Degenerate triangle (impossible)" +expected = 0 + +[[asserts]] +arguments = [[3, 2, 3, 4]] +comment = "Multiple elements, forms 3, 3, 4" +expected = 10 + +[[asserts]] +arguments = [[3, 6, 2, 3]] +comment = "Elements form 3, 3, 2" +expected = 8 + +[[asserts]] +arguments = [[3, 4, 5]] +comment = "Exact 3 elements, right triangle" +expected = 12 + +[[asserts]] +arguments = [[1, 1, 1]] +comment = "Equilateral triangle" +expected = 3 + +[[asserts]] +arguments = [[2, 2, 2, 2]] +comment = "Four equal elements" +expected = 6 + +[[asserts]] +arguments = [[10, 9, 8, 2, 1]] +comment = "Descending sequence" +expected = 27 + +[[asserts]] +arguments = [[100, 1, 1, 1]] +comment = "One huge element, rest forms small triangle" +expected = 3 + +[[asserts]] +arguments = [[10, 5, 4, 3]] +comment = "Largest element skipped" +expected = 12 + +[[asserts]] +arguments = [[1, 2, 3, 4, 5, 6]] +comment = "Consecutive numbers" +expected = 15 + +[[asserts]] +arguments = [[1, 1, 2, 3, 5, 8, 13]] +comment = "Fibonacci sequence (no triangle possible)" +expected = 0 + +[[asserts]] +arguments = [[1, 1, 2, 3, 5, 8, 13, 20]] +comment = "Slightly modified Fibonacci (valid)" +expected = 41 + +[[asserts]] +arguments = [[5, 5, 10, 10, 20]] +comment = "Repeated elements, skips 20" +expected = 25 + +[[asserts]] +arguments = [[7, 8, 9, 100, 101, 102]] +comment = "Two distinct groups, largest group works" +expected = 303 + +[[asserts]] +arguments = [[10, 10, 10, 100, 100, 100]] +comment = "Two distinct groups of equal elements" +expected = 300 + +[[asserts]] +arguments = [[10, 10, 100, 100]] +comment = "Isosceles triangle from large elements" +expected = 210 + +[[asserts]] +arguments = [[1, 2, 1, 10]] +comment = "Impossible even with more elements" +expected = 0 + +[[asserts]] +arguments = [[9, 8, 7, 6, 5]] +comment = "Descending sequence starting at 9" +expected = 24 + +[[asserts]] +arguments = [[1000, 1000, 1000]] +comment = "Large values" +expected = 3000 + +[[asserts]] +arguments = [[5, 12, 13]] +comment = "Pythagorean triple" +expected = 30 + +[[asserts]] +arguments = [[3, 4, 5, 6, 8, 10]] +comment = "Multiple triples" +expected = 24 + +[[asserts]] +arguments = [[2, 3, 4, 5, 10]] +comment = "Largest element cannot be used" +expected = 12 + +[[asserts]] +arguments = [[1, 1, 1, 1000]] +comment = "One huge outlier" +expected = 3 + +[[asserts]] +arguments = [[100, 10, 10, 10]] +comment = "One huge, three identical smaller" +expected = 30 + +[[asserts]] +arguments = [[2, 2, 3]] +comment = "Valid isosceles" +expected = 7 + +[[asserts]] +arguments = [[1, 10, 100, 1000, 10000]] +comment = "Powers of 10 (no triangle possible)" +expected = 0 diff --git a/tasks/easy/arrays/max_stock_profit.toml b/tasks/easy/arrays/max_stock_profit.toml new file mode 100644 index 0000000..74a6cb6 --- /dev/null +++ b/tasks/easy/arrays/max_stock_profit.toml @@ -0,0 +1,198 @@ +base_score = 100 +level = "easy" +name = "max_stock_profit" +tags = ["arrays", "greedy", "math"] +time_to_solve_sec = 250 + +description_en = """ +Given an array `prices` where `prices[i]` is the price of a given stock on the $i$-th day. + +You want to maximize your profit by choosing a single day to buy one stock and choosing a different day in the future to sell that stock. + +Return the maximum profit you can achieve from this transaction. If you cannot achieve any profit, return `0`. +""" + +description_ru = """ +Дан массив `prices`, где `prices[i]` — это цена акции в $i$-й день. + +Вы хотите максимизировать свою прибыль, выбрав один день для покупки одной акции и другой день в будущем для ее продажи. + +Верните максимальную прибыль, которую вы можете получить от этой сделки. Если получить прибыль невозможно, верните `0`. +""" + +limits = """ +- $1 \\leq \\text{len}(\\text{prices}) \\leq 10^5$ +- $0 \\leq \\text{prices}[i] \\leq 10^4$ +""" + +solution = """ +def solution(prices: list) -> int: + max_p, min_p = 0, float('inf') + for price in prices: + min_p = min(min_p, price) + max_p = max(max_p, price - min_p) + return max_p +""" + +examples = """ +solution([1]) == 0 +solution([1, 2]) == 1 +solution([2, 1]) == 0 +solution([7, 6, 4, 3, 1]) == 0 +solution([7, 1, 5, 3, 6, 4]) == 5 +""" + +[[input_signature]] +argument_name = "prices" +[input_signature.type] +name = "array" +[input_signature.type.nested] +name = "integer" + +[output_signature.type] +name = "integer" + +[[asserts]] +arguments = [[7, 1, 5, 3, 6, 4]] +comment = "Buy on day 2, sell on day 5" +expected = 5 + +[[asserts]] +arguments = [[7, 6, 4, 3, 1]] +comment = "Decreasing prices, no profit possible" +expected = 0 + +[[asserts]] +arguments = [[1, 2]] +comment = "Two days, profit possible" +expected = 1 + +[[asserts]] +arguments = [[2, 1]] +comment = "Two days, decreasing prices" +expected = 0 + +[[asserts]] +arguments = [[1]] +comment = "Single day, no transaction possible" +expected = 0 + +[[asserts]] +arguments = [[1, 1, 1, 1]] +comment = "Constant prices" +expected = 0 + +[[asserts]] +arguments = [[2, 4, 1]] +comment = "Max price before min price" +expected = 2 + +[[asserts]] +arguments = [[3, 2, 6, 5, 0, 3]] +comment = "Multiple peaks and valleys" +expected = 4 + +[[asserts]] +arguments = [[1, 2, 3, 4, 5]] +comment = "Increasing prices" +expected = 4 + +[[asserts]] +arguments = [[5, 4, 3, 2, 1]] +comment = "Strictly decreasing prices" +expected = 0 + +[[asserts]] +arguments = [[1, 5, 1, 5, 1, 5]] +comment = "Alternating low and high" +expected = 4 + +[[asserts]] +arguments = [[10000, 0]] +comment = "Max possible value then 0" +expected = 0 + +[[asserts]] +arguments = [[0, 10000]] +comment = "0 then max possible value" +expected = 10000 + +[[asserts]] +arguments = [[3, 3, 5, 0, 0, 3, 1, 4]] +comment = "Mixed elements with zeroes" +expected = 4 + +[[asserts]] +arguments = [[7, 2, 5, 1, 6, 4]] +comment = "Best buy is later in the array" +expected = 5 + +[[asserts]] +arguments = [[8, 9, 2, 5, 4, 7, 1]] +comment = "Highest peak at start, best profit in middle" +expected = 5 + +[[asserts]] +arguments = [[5, 1, 5, 1, 5]] +comment = "Repeating pattern" +expected = 4 + +[[asserts]] +arguments = [[10, 20, 30, 40, 50, 60, 70, 80, 90, 100]] +comment = "Long increasing sequence" +expected = 90 + +[[asserts]] +arguments = [[100, 90, 80, 70, 60, 50, 40, 30, 20, 10]] +comment = "Long decreasing sequence" +expected = 0 + +[[asserts]] +arguments = [[1, 2, 10, 1, 20]] +comment = "Two distinct upward trends" +expected = 19 + +[[asserts]] +arguments = [[20, 1, 10, 2, 11]] +comment = "Buy at absolute min, sell at local max" +expected = 10 + +[[asserts]] +arguments = [[10, 8, 7, 5, 2]] +comment = "No profit, all decreasing" +expected = 0 + +[[asserts]] +arguments = [[2, 2, 2, 2, 3]] +comment = "Flat then small increase" +expected = 1 + +[[asserts]] +arguments = [[3, 2, 1, 4, 5, 6]] +comment = "Drop to min, then steady increase" +expected = 5 + +[[asserts]] +arguments = [[1, 100]] +comment = "Simple max gain" +expected = 99 + +[[asserts]] +arguments = [[5, 8, 2, 10]] +comment = "Two possible buy days" +expected = 8 + +[[asserts]] +arguments = [[10, 2, 8, 1, 7]] +comment = "Profit 6 on both valid transactions, best is 6" +expected = 6 + +[[asserts]] +arguments = [[1, 2, 4, 2, 5, 7, 2, 4, 9, 0, 8]] +comment = "Complex long array" +expected = 8 + +[[asserts]] +arguments = [[0, 0, 0, 0]] +comment = "All zeroes" +expected = 0 diff --git a/tasks/easy/arrays/maximum_altitude.toml b/tasks/easy/arrays/maximum_altitude.toml new file mode 100644 index 0000000..2e1bbe2 --- /dev/null +++ b/tasks/easy/arrays/maximum_altitude.toml @@ -0,0 +1,184 @@ +base_score = 100 +level = "easy" +name = "maximum_altitude" +tags = ["arrays", "math"] +time_to_solve_sec = 200 + +description_en = """ +A cyclist starts their journey at an altitude of $0$. You are given an integer array `gain` of length $n$, where `gain[i]` represents the net altitude gain between point $i$ and point $i + 1$. + +Return the highest altitude the cyclist reaches during their journey. +""" + +description_ru = """ +Велосипедист начинает свой путь на высоте $0$. Вам дан целочисленный массив `gain` длины $n$, где `gain[i]` — это изменение высоты между точкой $i$ и точкой $i + 1$. + +Верните максимальную высоту, которой достигнет велосипедист за время пути. +""" + +limits = """ +- $1 \\leq \\text{len}(\\text{gain}) \\leq 100$ +- $-100 \\leq \\text{gain}[i] \\leq 100$ +""" + +solution = """ +def solution(gain: list) -> int: + curr = max_alt = 0 + for g in gain: + curr += g + max_alt = max(max_alt, curr) + return max_alt +""" + +examples = """ +solution([0]) == 0 +solution([1]) == 1 +solution([-5, 1, 5, 0, -7]) == 1 +solution([10, -5, 10, -5]) == 15 +solution([-4, -3, -2, -1, 4, 3, 2]) == 0 +""" + +[[input_signature]] +argument_name = "gain" +[input_signature.type] +name = "array" +[input_signature.type.nested] +name = "integer" + +[output_signature.type] +name = "integer" + +[[asserts]] +arguments = [[-5, 1, 5, 0, -7]] +comment = "Max altitude reached in the middle" +expected = 1 + +[[asserts]] +arguments = [[-4, -3, -2, -1, 4, 3, 2]] +comment = "Never goes above starting altitude" +expected = 0 + +[[asserts]] +arguments = [[10, -5, 10, -5]] +comment = "Fluctuating altitude" +expected = 15 + +[[asserts]] +arguments = [[1]] +comment = "Single positive element" +expected = 1 + +[[asserts]] +arguments = [[-1]] +comment = "Single negative element" +expected = 0 + +[[asserts]] +arguments = [[0]] +comment = "Single zero element" +expected = 0 + +[[asserts]] +arguments = [[0, 0, 0]] +comment = "All zeros" +expected = 0 + +[[asserts]] +arguments = [[5, 5, 5]] +comment = "Constantly ascending" +expected = 15 + +[[asserts]] +arguments = [[-5, -5, -5]] +comment = "Constantly descending" +expected = 0 + +[[asserts]] +arguments = [[100, 100, -100, 50]] +comment = "Large peak then drop" +expected = 200 + +[[asserts]] +arguments = [[-100, 50, 60, -20]] +comment = "Large drop then peak" +expected = 10 + +[[asserts]] +arguments = [[10, 20, 30, 40, 50]] +comment = "Monotonically increasing" +expected = 150 + +[[asserts]] +arguments = [[-10, -20, -30, -40, -50]] +comment = "Monotonically decreasing" +expected = 0 + +[[asserts]] +arguments = [[50, -50, 50, -50]] +comment = "Oscillating starting positive" +expected = 50 + +[[asserts]] +arguments = [[-50, 50, -50, 50]] +comment = "Oscillating starting negative" +expected = 0 + +[[asserts]] +arguments = [[1, -1, 1, -1, 1, -1]] +comment = "Small oscillations starting positive" +expected = 1 + +[[asserts]] +arguments = [[-1, 1, -1, 1, -1, 1]] +comment = "Small oscillations starting negative" +expected = 0 + +[[asserts]] +arguments = [[100]] +comment = "Max possible single value" +expected = 100 + +[[asserts]] +arguments = [[-100]] +comment = "Min possible single value" +expected = 0 + +[[asserts]] +arguments = [[0, 1, -1, 0, 2, -2]] +comment = "Mixed with zeros" +expected = 2 + +[[asserts]] +arguments = [[5, 4, 3, 2, 1]] +comment = "Decreasing positive steps" +expected = 15 + +[[asserts]] +arguments = [[-5, 4, 3, 2, 1]] +comment = "Starts with dip, then recovers" +expected = 5 + +[[asserts]] +arguments = [[-10, 2, 3, 4, 5]] +comment = "Starts with big dip, recovers over time" +expected = 4 + +[[asserts]] +arguments = [[2, 3, -10, 4, 5]] +comment = "Dip in the middle" +expected = 5 + +[[asserts]] +arguments = [[10, -20, 30, -40, 50]] +comment = "Increasing oscillation amplitudes" +expected = 30 + +[[asserts]] +arguments = [[1, 2, 3, 4, 5, -15, 20]] +comment = "Drops completely then rises again" +expected = 20 + +[[asserts]] +arguments = [[50, 50, -100, 1, 2]] +comment = "Peak at the start, drop, small rise" +expected = 100 diff --git a/tasks/easy/arrays/permutation_period.toml b/tasks/easy/arrays/permutation_period.toml new file mode 100644 index 0000000..ed69ddb --- /dev/null +++ b/tasks/easy/arrays/permutation_period.toml @@ -0,0 +1,219 @@ +base_score = 100 +level = "easy" +name = "permutation_period" +tags = ["arrays", "math", "simulation"] +time_to_solve_sec = 250 + +description_en = """ +You are given an array `p` of length $n$ containing integers from $0$ to $n - 1$. + +Imagine we have an initial array $\\text{arr} = [0, 1, 2, \\dots, n - 1]$. +In one step, we permute the elements of $\\text{arr}$ such that the new array is $\\text{new\\_arr}$, where $\\text{new\\_arr}[i] = \\text{arr}[p[i]]$. + +Return the minimum number of steps required to return $\\text{arr}$ to its initial state $[0, 1, 2, \\dots, n - 1]$. +If it is impossible to ever return to the initial state, return $-1$. +""" + +description_ru = """ +Вам дан массив `p` длины $n$, содержащий целые числа от $0$ до $n - 1$. + +Представьте, что у нас есть исходный массив $\\text{arr} = [0, 1, 2, \\dots, n - 1]$. +За один шаг мы переставляем элементы $\\text{arr}$ так, что получается новый массив $\\text{new\\_arr}$, где $\\text{new\\_arr}[i] = \\text{arr}[p[i]]$. + +Верните минимальное количество шагов, за которое массив $\\text{arr}$ вернется в свое исходное состояние $[0, 1, 2, \\dots, n - 1]$. +Если вернуться в исходное состояние невозможно, верните $-1$. +""" + +limits = """ +- $1 \\leq \\text{len}(p) \\leq 30$ +- $0 \\leq p[i] < \\text{len}(p)$ +""" + +solution = """ +def solution(p: list[int]) -> int: + if len(set(p)) != len(p): return -1 + curr, target, steps = list(p), list(range(len(p))), 1 + while curr != target: curr, steps = [curr[i] for i in p], steps + 1 + return steps +""" + +examples = """ +solution([0]) == 1 +solution([1, 0]) == 2 +solution([1, 2, 0]) == 3 +solution([0, 1, 1]) == -1 +solution([1, 2, 0, 4, 3]) == 6 +""" + +[[input_signature]] +argument_name = "p" +[input_signature.type] +name = "array" +[input_signature.type.nested] +name = "integer" + +[output_signature.type] +name = "integer" + +[[asserts]] +arguments = [[0]] +comment = "Length 1, identical" +expected = 1 + +[[asserts]] +arguments = [[1, 0]] +comment = "Length 2, swap" +expected = 2 + +[[asserts]] +arguments = [[0, 1]] +comment = "Length 2, identical" +expected = 1 + +[[asserts]] +arguments = [[1, 2, 0]] +comment = "Cycle of 3" +expected = 3 + +[[asserts]] +arguments = [[0, 1, 2]] +comment = "Length 3, identical" +expected = 1 + +[[asserts]] +arguments = [[1, 0, 2]] +comment = "Cycle of 2 and 1" +expected = 2 + +[[asserts]] +arguments = [[1, 2, 3, 0]] +comment = "Cycle of 4" +expected = 4 + +[[asserts]] +arguments = [[1, 0, 3, 2]] +comment = "Two cycles of 2" +expected = 2 + +[[asserts]] +arguments = [[1, 2, 0, 4, 3]] +comment = "Cycles of 3 and 2 (LCM = 6)" +expected = 6 + +[[asserts]] +arguments = [[1, 2, 3, 4, 0]] +comment = "Cycle of 5" +expected = 5 + +[[asserts]] +arguments = [[0, 0, 0]] +comment = "Invalid permutation" +expected = -1 + +[[asserts]] +arguments = [[1, 1]] +comment = "Invalid permutation" +expected = -1 + +[[asserts]] +arguments = [[2, 0, 1, 4, 3, 5]] +comment = "Cycles of 3, 2, 1" +expected = 6 + +[[asserts]] +arguments = [[1, 2, 3, 0, 5, 6, 4]] +comment = "Cycles of 4 and 3 (LCM = 12)" +expected = 12 + +[[asserts]] +arguments = [[1, 2, 3, 4, 0, 6, 7, 8, 5]] +comment = "Cycles of 5 and 4 (LCM = 20)" +expected = 20 + +[[asserts]] +arguments = [[1, 2, 3, 4, 5, 0, 7, 8, 9, 6]] +comment = "Cycles of 6 and 4 (LCM = 12)" +expected = 12 + +[[asserts]] +arguments = [[1, 2, 3, 4, 5, 6, 0, 8, 9, 7]] +comment = "Cycles of 7 and 3 (LCM = 21)" +expected = 21 + +[[asserts]] +arguments = [[1, 2, 3, 4, 5, 6, 7, 0, 9, 8]] +comment = "Cycles of 8 and 2" +expected = 8 + +[[asserts]] +arguments = [[1, 2, 3, 4, 5, 6, 7, 8, 0, 9]] +comment = "Cycles of 9 and 1" +expected = 9 + +[[asserts]] +arguments = [[1, 2, 0, 4, 5, 6, 7, 3, 9, 10, 11, 12, 13, 8, 15, 14]] +comment = "Cycles of 3, 5, 6, 2 (LCM = 30)" +expected = 30 + +[[asserts]] +arguments = [[1, 2, 3, 4, 0, 6, 7, 8, 9, 10, 11, 5, 13, 14, 12]] +comment = "Cycles of 5, 7, 3 (LCM = 105)" +expected = 105 + +[[asserts]] +arguments = [[0, 1, 2, 3, 4, 5, 6, 7, 8, 8]] +comment = "Not a permutation" +expected = -1 + +[[asserts]] +arguments = [[1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 0]] +comment = "Not a permutation with 0 duplicates" +expected = -1 + +[[asserts]] +arguments = [[2, 2, 2, 2, 2]] +comment = "All same elements" +expected = -1 + +[[asserts]] +arguments = [ + [ + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 0, + 16, + 17, + 18, + 19, + 20, + 21, + 22, + 23, + 24, + 25, + 26, + 27, + 28, + 29, + 15, + ], +] +comment = "Two cycles of 15" +expected = 15 + +[[asserts]] +arguments = [[1, 0, 3, 4, 2, 6, 7, 8, 5, 10, 11, 12, 13, 9]] +comment = "Cycles of 2, 3, 4, 5 (LCM = 60)" +expected = 60 diff --git a/tasks/easy/arrays/summary_ranges.toml b/tasks/easy/arrays/summary_ranges.toml new file mode 100644 index 0000000..e9bdf71 --- /dev/null +++ b/tasks/easy/arrays/summary_ranges.toml @@ -0,0 +1,196 @@ +base_score = 100 +level = "easy" +name = "summary_ranges" +tags = ["arrays", "strings"] +time_to_solve_sec = 300 + +description_en = """ +You are given a sorted array of unique integers `nums`. + +Return the smallest sorted list of ranges that cover all the numbers in the array exactly. That is, each element of `nums` is covered by exactly one of the ranges, and there is no integer `x` such that `x` is in one of the ranges but not in `nums`. + +Each range `[a, b]` in the list should be formatted as: +- `"a->b"` if $a \\neq b$ +- `"a"` if $a = b$ +""" + +description_ru = """ +Вам дан отсортированный массив уникальных целых чисел `nums`. + +Верните минимальный отсортированный список диапазонов, которые в точности покрывают все числа в массиве. Это означает, что каждый элемент `nums` покрыт ровно одним диапазоном, и не существует такого целого числа `x`, которое находится в одном из диапазонов, но отсутствует в `nums`. + +Каждый диапазон `[a, b]` в списке должен быть отформатирован как: +- `"a->b"`, если $a \\neq b$ +- `"a"`, если $a = b$ +""" + +limits = """ +- $0 \\leq \\text{len}(nums) \\leq 10^4$ +- $-10^9 \\leq nums[i] \\leq 10^9$ +- $nums[i] < nums[i+1]$ +""" + +solution = """ +def solution(nums: list[int]) -> list[str]: + res = [] + for n in nums: + if res and res[-1][1] == n - 1: + res[-1][1] = n + else: + res.append([n, n]) + return [f"{s}->{e}" if s != e else str(s) for s, e in res] +""" + +examples = """ +solution([]) == [] +solution([-1]) == ["-1"] +solution([0, 1, 2, 4, 5, 7]) == ["0->2", "4->5", "7"] +solution([0, 2, 3, 4, 6, 8, 9]) == ["0", "2->4", "6", "8->9"] +""" + +[[input_signature]] +argument_name = "nums" +[input_signature.type] +name = "array" +[input_signature.type.nested] +name = "integer" + +[output_signature.type] +name = "array" +[output_signature.type.nested] +name = "string" + +[[asserts]] +arguments = [[]] +comment = "Empty array" +expected = [] + +[[asserts]] +arguments = [[0]] +comment = "Single element zero" +expected = ["0"] + +[[asserts]] +arguments = [[-1]] +comment = "Single negative element" +expected = ["-1"] + +[[asserts]] +arguments = [[1, 2]] +comment = "Single pair" +expected = ["1->2"] + +[[asserts]] +arguments = [[1, 3]] +comment = "Two disconnected elements" +expected = ["1", "3"] + +[[asserts]] +arguments = [[0, 1, 2, 4, 5, 7]] +comment = "Mix of intervals and single elements" +expected = ["0->2", "4->5", "7"] + +[[asserts]] +arguments = [[0, 2, 3, 4, 6, 8, 9]] +comment = "Another mix from examples" +expected = ["0", "2->4", "6", "8->9"] + +[[asserts]] +arguments = [[1, 2, 3, 4, 5]] +comment = "One single interval" +expected = ["1->5"] + +[[asserts]] +arguments = [[2, 4, 6, 8]] +comment = "All isolated elements" +expected = ["2", "4", "6", "8"] + +[[asserts]] +arguments = [[-5, -4, -3, -1, 0, 1]] +comment = "Negative to positive transition" +expected = ["-5->-3", "-1->1"] + +[[asserts]] +arguments = [[-2, -1, 1, 2]] +comment = "Symmetric around zero" +expected = ["-2->-1", "1->2"] + +[[asserts]] +arguments = [[10, 11, 12, 13, 14, 15]] +comment = "Larger strictly consecutive range" +expected = ["10->15"] + +[[asserts]] +arguments = [[-10, -9, -8, 0, 1, 2, 8, 9, 10]] +comment = "Multiple separate continuous intervals" +expected = ["-10->-8", "0->2", "8->10"] + +[[asserts]] +arguments = [[-1000000000, 1000000000]] +comment = "Extreme values without overflow issues" +expected = ["-1000000000", "1000000000"] + +[[asserts]] +arguments = [[100, 101, 102, 103, 105, 106, 107]] +comment = "Two large consecutive ranges" +expected = ["100->103", "105->107"] + +[[asserts]] +arguments = [[1, 2, 3, 5, 6, 7, 9, 10, 11]] +comment = "Triplets" +expected = ["1->3", "5->7", "9->11"] + +[[asserts]] +arguments = [[-50, -49, -48]] +comment = "Negative sequence" +expected = ["-50->-48"] + +[[asserts]] +arguments = [[0, 1]] +comment = "Smallest consecutive positive" +expected = ["0->1"] + +[[asserts]] +arguments = [[-1, 0]] +comment = "Zero included" +expected = ["-1->0"] + +[[asserts]] +arguments = [[-3, -2, -1]] +comment = "Small negative sequence" +expected = ["-3->-1"] + +[[asserts]] +arguments = [[10, 20, 30, 40]] +comment = "Tens apart" +expected = ["10", "20", "30", "40"] + +[[asserts]] +arguments = [[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]] +comment = "Long zero to nine sequence" +expected = ["0->9"] + +[[asserts]] +arguments = [[-100, -99, -98, -96, -95, -94]] +comment = "Two negative chunks" +expected = ["-100->-98", "-96->-94"] + +[[asserts]] +arguments = [[7, 8, 9, 10, 12, 13]] +comment = "Two differently sized chunks" +expected = ["7->10", "12->13"] + +[[asserts]] +arguments = [[4, 6, 8, 10, 12]] +comment = "Even numbers" +expected = ["4", "6", "8", "10", "12"] + +[[asserts]] +arguments = [[1, 3, 5, 7, 9]] +comment = "Odd numbers" +expected = ["1", "3", "5", "7", "9"] + +[[asserts]] +arguments = [[-10, -5, 0, 5, 10]] +comment = "Step of 5" +expected = ["-10", "-5", "0", "5", "10"] diff --git a/tasks/easy/arrays/toeplitz_matrix.toml b/tasks/easy/arrays/toeplitz_matrix.toml new file mode 100644 index 0000000..b755945 --- /dev/null +++ b/tasks/easy/arrays/toeplitz_matrix.toml @@ -0,0 +1,200 @@ +base_score = 100 +level = "easy" +name = "toeplitz_matrix" +tags = ["arrays", "matrices"] +time_to_solve_sec = 200 + +description_en = """ +Given an $m \\times n$ `matrix`, return `True` if the matrix is Toeplitz. Otherwise, return `False`. + +A matrix is **Toeplitz** if every diagonal from top-left to bottom-right has the same elements. +""" + +description_ru = """ +Дана матрица `matrix` размером $m \\times n$. Верните `True`, если матрица является Тёплицевой. В противном случае верните `False`. + +Матрица называется **Тёплицевой**, если каждая диагональ от верхнего левого угла до нижнего правого состоит из одинаковых элементов. +""" + +limits = """ +- $1 \\leq m, n \\leq 20$ +- $0 \\leq \\text{matrix}[i][j] \\leq 100$ +""" + +solution = """ +def solution(matrix: list[list[int]]) -> bool: + for i in range(1, len(matrix)): + for j in range(1, len(matrix[0])): + if matrix[i][j] != matrix[i-1][j-1]: + return False + return True +""" + +examples = """ +solution([[1]]) == True +solution([[1, 2], [3, 1]]) == True +solution([[1, 2], [2, 2]]) == False +solution([[1, 2, 3], [4, 1, 2], [5, 4, 1]]) == True +""" + +[[input_signature]] +argument_name = "matrix" +[input_signature.type] +name = "array" +[input_signature.type.nested] +name = "array" +[input_signature.type.nested.nested] +name = "integer" + +[output_signature.type] +name = "boolean" + +[[asserts]] +arguments = [[[1]]] +comment = "1x1 matrix is always Toeplitz" +expected = true + +[[asserts]] +arguments = [[[1, 2, 3, 4]]] +comment = "1xN matrix is always Toeplitz" +expected = true + +[[asserts]] +arguments = [[[1], [2], [3], [4]]] +comment = "Mx1 matrix is always Toeplitz" +expected = true + +[[asserts]] +arguments = [[[1, 2], [3, 1]]] +comment = "2x2 Toeplitz matrix" +expected = true + +[[asserts]] +arguments = [[[1, 2], [2, 2]]] +comment = "2x2 non-Toeplitz matrix" +expected = false + +[[asserts]] +arguments = [[[1, 2, 3, 4], [5, 1, 2, 3], [9, 5, 1, 2]]] +comment = "3x4 Toeplitz matrix" +expected = true + +[[asserts]] +arguments = [[[1, 2, 3, 4], [5, 1, 9, 3], [9, 5, 1, 2]]] +comment = "3x4 non-Toeplitz matrix with one incorrect element" +expected = false + +[[asserts]] +arguments = [[[1, 2], [1, 2]]] +comment = "Columns are identical, but diagonals are not" +expected = false + +[[asserts]] +arguments = [[[0, 0], [0, 0]]] +comment = "Matrix with all zeros" +expected = true + +[[asserts]] +arguments = [[[1, 2, 3], [4, 5, 6], [7, 8, 9]]] +comment = "Sequential matrix is not Toeplitz" +expected = false + +[[asserts]] +arguments = [[[3, 3, 3], [3, 3, 3], [3, 3, 3]]] +comment = "Matrix with all identical elements" +expected = true + +[[asserts]] +arguments = [[[1, 2, 3], [2, 1, 2], [3, 2, 1]]] +comment = "Symmetric Toeplitz matrix" +expected = true + +[[asserts]] +arguments = [[[1, 2, 3], [2, 1, 4], [3, 2, 1]]] +comment = "Almost symmetric but non-Toeplitz" +expected = false + +[[asserts]] +arguments = [[[9, 8, 7, 6], [5, 9, 8, 7], [4, 5, 9, 8], [3, 4, 5, 9]]] +comment = "4x4 Toeplitz matrix" +expected = true + +[[asserts]] +arguments = [[[9, 8, 7, 6], [5, 9, 8, 7], [4, 5, 9, 8], [3, 4, 5, 1]]] +comment = "4x4 non-Toeplitz matrix, last element wrong" +expected = false + +[[asserts]] +arguments = [[[1, 2, 3, 4, 5], [6, 1, 2, 3, 4], [7, 6, 1, 2, 3]]] +comment = "3x5 Toeplitz matrix" +expected = true + +[[asserts]] +arguments = [[[1, 2, 3, 4, 5], [6, 1, 2, 3, 4], [7, 6, 1, 2, 9]]] +comment = "3x5 non-Toeplitz matrix" +expected = false + +[[asserts]] +arguments = [[[1, 1], [2, 1], [3, 2], [4, 3]]] +comment = "4x2 Toeplitz matrix" +expected = true + +[[asserts]] +arguments = [[[1, 1], [2, 1], [3, 2], [4, 4]]] +comment = "4x2 non-Toeplitz matrix" +expected = false + +[[asserts]] +arguments = [[[5, 4, 3], [6, 5, 4], [7, 6, 5], [8, 7, 6]]] +comment = "4x3 Toeplitz matrix" +expected = true + +[[asserts]] +arguments = [[[5, 4, 3], [6, 5, 4], [7, 6, 5], [8, 7, 5]]] +comment = "4x3 non-Toeplitz matrix" +expected = false + +[[asserts]] +arguments = [[[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]]] +comment = "Identity matrix is Toeplitz" +expected = true + +[[asserts]] +arguments = [[[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 0]]] +comment = "Slightly modified identity matrix" +expected = false + +[[asserts]] +arguments = [[[8, 8, 8, 8], [8, 8, 8, 8], [8, 8, 8, 8], [8, 8, 8, 8]]] +comment = "4x4 matrix of 8s" +expected = true + +[[asserts]] +arguments = [[[1, 2], [3, 1], [4, 3], [5, 4], [6, 5]]] +comment = "5x2 Toeplitz matrix" +expected = true + +[[asserts]] +arguments = [[[1, 2, 3, 4, 5, 6]]] +comment = "1x6 matrix" +expected = true + +[[asserts]] +arguments = [[[1, 2], [2, 1], [1, 2]]] +comment = "Alternating elements form a valid Toeplitz pattern" +expected = true + +[[asserts]] +arguments = [[[1, 1, 1, 1], [2, 2, 2, 2]]] +comment = "Rows are internally identical but diagonals are not" +expected = false + +[[asserts]] +arguments = [[[1, 1, 1, 1], [2, 1, 1, 1]]] +comment = "Shifted identical rows form a Toeplitz matrix" +expected = true + +[[asserts]] +arguments = [[[3, 4, 5, 6], [2, 3, 4, 5], [1, 2, 3, 4]]] +comment = "Another valid 3x4 Toeplitz matrix" +expected = true diff --git a/tasks/easy/arrays/town_judge.toml b/tasks/easy/arrays/town_judge.toml new file mode 100644 index 0000000..e5bf7c5 --- /dev/null +++ b/tasks/easy/arrays/town_judge.toml @@ -0,0 +1,306 @@ +base_score = 100 +level = "easy" +name = "town_judge" +tags = ["arrays", "graphs"] +time_to_solve_sec = 250 + +description_en = """ +In a town, there are $n$ people labeled from $1$ to $n$. There is a rumor that one of these people is secretly the town judge. + +The town judge satisfies two properties: +1. The town judge trusts nobody. +2. Everybody (except for the town judge) trusts the town judge. + +You are given an array `trust` where `trust[i] = [a, b]` representing that the person labeled `a` trusts the person labeled `b`. + +Return the label of the town judge if they exist and can be identified, or return `-1` otherwise. + +Every trust pair is distinct, with both labels between $1$ and $n$ and different from each other. +""" + +description_ru = """ +В городе живут $n$ людей, пронумерованных от $1$ до $n$. Ходят слухи, что один из них — городской судья. + +Судья должен соответствовать двум условиям: +1. Судья никому не доверяет. +2. Все остальные жители города (кроме самого судьи) доверяют судье. + +Вам дан массив пар `trust`, где `trust[i] = [a, b]` означает, что человек `a` доверяет человеку `b`. + +Верните номер городского судьи, если он существует, иначе верните `-1`. + +Все пары доверия различны; обе метки находятся от $1$ до $n$ и отличаются друг от друга. +""" + +limits = """ +- $1 \\leq n \\leq 1000$ +- $0 \\leq \\text{len}(\\text{trust}) \\leq 10^4$ +- $\\text{trust}[i][0] \\neq \\text{trust}[i][1]$ + +- $1 \\leq \\text{trust}[i][0], \\text{trust}[i][1] \\leq n$ +""" + +solution = """ +def solution(n: int, trust: list) -> int: + d = [0] * (n + 1) + for a, b in trust: + d[a] -= 1 + d[b] += 1 + for i in range(1, n + 1): + if d[i] == n - 1: + return i + return -1 +""" + +examples = """ +solution(2, [[1, 2]]) == 2 +solution(3, [[1, 3], [2, 3]]) == 3 +solution(3, [[1, 2], [2, 3]]) == -1 +solution(3, [[1, 3], [2, 3], [3, 1]]) == -1 +""" + +[[input_signature]] +argument_name = "n" +[input_signature.type] +name = "integer" + +[[input_signature]] +argument_name = "trust" +[input_signature.type] +name = "array" +[input_signature.type.nested] +name = "array" +[input_signature.type.nested.nested] +name = "integer" + +[output_signature.type] +name = "integer" + +[[asserts]] +arguments = [2, [[1, 2]]] +comment = "Simple case: 1 trusts 2" +expected = 2 + +[[asserts]] +arguments = [3, [[1, 3], [2, 3]]] +comment = "Everyone trusts 3" +expected = 3 + +[[asserts]] +arguments = [3, [[1, 3], [2, 3], [3, 1]]] +comment = "Judge trusts someone (invalid)" +expected = -1 + +[[asserts]] +arguments = [3, [[1, 2], [2, 3]]] +comment = "No one is trusted by everyone else" +expected = -1 + +[[asserts]] +arguments = [4, [[1, 3], [1, 4], [2, 3], [2, 4], [4, 3]]] +comment = "3 is trusted by 1, 2, 4 and trusts no one" +expected = 3 + +[[asserts]] +arguments = [1, []] +comment = "Single person is the judge by default" +expected = 1 + +[[asserts]] +arguments = [2, []] +comment = "Two people, no trust" +expected = -1 + +[[asserts]] +arguments = [4, [[1, 2], [1, 3], [2, 1], [2, 3], [4, 1], [4, 2], [4, 3]]] +comment = "3 is trusted by everyone" +expected = 3 + +[[asserts]] +arguments = [4, [[1, 4], [2, 4], [3, 4], [4, 1]]] +comment = "Judge trusts someone" +expected = -1 + +[[asserts]] +arguments = [3, [[1, 2], [2, 1]]] +comment = "Cyclic trust with no clear judge" +expected = -1 + +[[asserts]] +arguments = [2, [[2, 1]]] +comment = "2 trusts 1" +expected = 1 + +[[asserts]] +arguments = [5, [[1, 5], [2, 5], [3, 5], [4, 5]]] +comment = "Everyone trusts 5" +expected = 5 + +[[asserts]] +arguments = [5, [[1, 5], [2, 5], [3, 5], [4, 5], [5, 4]]] +comment = "5 trusts 4, cannot be judge" +expected = -1 + +[[asserts]] +arguments = [3, [[1, 3], [1, 2], [2, 3]]] +comment = "3 is the judge" +expected = 3 + +[[asserts]] +arguments = [4, [[1, 2], [2, 3], [3, 4]]] +comment = "No one trusted by all" +expected = -1 + +[[asserts]] +arguments = [5, [[1, 2], [2, 3], [3, 4], [4, 5], [5, 1]]] +comment = "Trust cycle" +expected = -1 + +[[asserts]] +arguments = [6, [[1, 6], [2, 6], [3, 6], [4, 6], [5, 6]]] +comment = "6 is judge" +expected = 6 + +[[asserts]] +arguments = [6, [[1, 6], [2, 6], [3, 6], [4, 6], [5, 6], [1, 2]]] +comment = "Extra trust between non-judges" +expected = 6 + +[[asserts]] +arguments = [3, [[1, 2], [2, 3], [3, 2]]] +comment = "2 is trusted by 1 and 3, but 2 trusts 3" +expected = -1 + +[[asserts]] +arguments = [4, [[1, 4], [2, 4], [3, 4], [1, 2], [2, 1]]] +comment = "Complex non-judge trust" +expected = 4 + +[[asserts]] +arguments = [2, [[1, 2], [2, 1]]] +comment = "Mutual trust" +expected = -1 + +[[asserts]] +arguments = [5, [[1, 3], [2, 3], [4, 3], [5, 3], [1, 2], [2, 4]]] +comment = "3 is judge, others have complex relations" +expected = 3 + +[[asserts]] +arguments = [ + 10, + [ + [ + 1, + 10, + ], + [ + 2, + 10, + ], + [ + 3, + 10, + ], + [ + 4, + 10, + ], + [ + 5, + 10, + ], + [ + 6, + 10, + ], + [ + 7, + 10, + ], + [ + 8, + 10, + ], + [ + 9, + 10, + ], + ], +] +comment = "Large group judge" +expected = 10 + +[[asserts]] +arguments = [4, [[1, 4], [2, 4]]] +comment = "Not everyone trusts 4" +expected = -1 + +[[asserts]] +arguments = [3, [[1, 2], [1, 3]]] +comment = "No one trusted by 2 people" +expected = -1 + +[[asserts]] +arguments = [ + 5, + [ + [ + 1, + 2, + ], + [ + 1, + 3, + ], + [ + 1, + 4, + ], + [ + 1, + 5, + ], + [ + 2, + 3, + ], + [ + 2, + 4, + ], + [ + 2, + 5, + ], + [ + 3, + 4, + ], + [ + 3, + 5, + ], + [ + 4, + 5, + ], + ], +] +comment = "5 is the judge" +expected = 5 + +[[asserts]] +arguments = [3, [[1, 3], [2, 3], [2, 1]]] +comment = "3 is the judge" +expected = 3 + +[[asserts]] +arguments = [4, [[2, 1], [3, 1], [4, 1]]] +comment = "1 is judge, others trust 1" +expected = 1 + +[[asserts]] +arguments = [3, [[1, 3], [2, 3], [1, 2]]] +comment = "1 trusts 2 and 3, 2 trusts 3" +expected = 3 diff --git a/tasks/easy/dp/rum_thirst.toml b/tasks/easy/dp/rum_thirst.toml index 1e8af92..3389402 100644 --- a/tasks/easy/dp/rum_thirst.toml +++ b/tasks/easy/dp/rum_thirst.toml @@ -1,10 +1,22 @@ -base_score = 100 -description_en = "A pirate walks along a deck lined with barrels of rum. Each barrel contains a certain number of liters (given as an array of non‑negative integers). The pirate cannot take rum from two adjacent barrels (that would make noise). What is the maximum total amount of rum he can drink unnoticed?\n" -description_ru = "Пират идет по палубе, заставленной бочками с ромом. В каждой бочке разное количество литров (задано массивом неотрицательных целых чисел). Он не может брать ром из двух соседних бочек (поднимется шум). Какое максимальное количество рома он может выпить незаметно?\n" -examples = "solution([]) == 0\nsolution([5]) == 5\nsolution([5, 3]) == 5\nsolution([5, 3, 7]) == 12\nsolution([2, 7, 9, 3, 1]) == 12\n" -level = "easy" -limits = "- $0 \\leq \\text{len}(\\text{barrels}) \\leq 1000$\n- $0 \\leq \\text{barrels}[i] \\leq 1000$\n" -name = "rum_thirst" +base_score = 100 +level = "easy" +name = "rum_thirst" +tags = ["dp", "algo", "collections"] +time_to_solve_sec = 180 + +description_en = """ +A pirate walks along a deck lined with barrels of rum. Each barrel contains a certain number of liters (given as an array of non‑negative integers). The pirate cannot take rum from two adjacent barrels (that would make noise). What is the maximum total amount of rum he can drink unnoticed? +""" + +description_ru = """ +Пират идет по палубе вдоль ряда бочек с ромом. В каждой бочке есть некоторое количество литров (задано массивом неотрицательных целых чисел). Он не может брать ром из двух соседних бочек (поднимется шум). Какое максимальное количество рома он может выпить незаметно? +""" + +limits = """ +- $0 \\leq \\text{len}(\\text{barrels}) \\leq 1000$ +- $0 \\leq \\text{barrels}[i] \\leq 1000$ +""" + solution = """ def solution(barrels: list[int]) -> int: prev2 = prev1 = 0 @@ -12,15 +24,25 @@ def solution(barrels: list[int]) -> int: prev2, prev1 = prev1, max(prev1, prev2 + x) return prev1 """ -tags = ["dp", "algo", "collections"] -time_to_solve_sec = 180 + +examples = """ +solution([]) == 0 +solution([5]) == 5 +solution([5, 3]) == 5 +solution([5, 3, 7]) == 12 +solution([2, 7, 9, 3, 1]) == 12 +""" + [[input_signature]] argument_name = "barrels" - [input_signature.type] name = "array" [input_signature.type.nested] name = "integer" + +[output_signature.type] +name = "integer" + [[asserts]] arguments = [[]] comment = "Test 1" @@ -309,11 +331,3 @@ arguments = [ ] comment = "Test 29" expected = 5307 - -[[asserts]] -arguments = [[]] -comment = "Test 30" -expected = 0 - -[output_signature.type] -name = "integer" diff --git a/tasks/easy/hashmaps/peak_performance_sum.toml b/tasks/easy/hashmaps/peak_performance_sum.toml new file mode 100644 index 0000000..87f8b7e --- /dev/null +++ b/tasks/easy/hashmaps/peak_performance_sum.toml @@ -0,0 +1,185 @@ +base_score = 100 +level = "easy" +name = "peak_performance_sum" +tags = ["hashmaps", "arrays"] +time_to_solve_sec = 250 + +description_en = """ +You are given two arrays of the same length: `teams` and `scores`. +For each index $i$, `teams[i]` is the name of a team, and `scores[i]` is the score they achieved in a specific match. + +A team can participate in multiple matches. Find the **highest** score achieved by each unique team across all their matches, and return the sum of these highest scores. + +If the input arrays are empty, return $0$. +""" + +description_ru = """ +Вам даны два массива одинаковой длины: `teams` и `scores`. +Для каждого индекса $i$, `teams[i]` — это название команды, а `scores[i]` — количество баллов, которые она получила в конкретном матче. + +Команда может участвовать в нескольких матчах. Найдите **наивысший** балл, полученный каждой уникальной командой за все её матчи, и верните сумму этих наивысших баллов. + +Если входные массивы пусты, верните $0$. +""" + +limits = """ +- $0 \\leq \\text{len}(\\text{teams}) = \\text{len}(\\text{scores}) \\leq 10^4$ +- $-10^4 \\leq \\text{scores}[i] \\leq 10^4$ +""" + +solution = """ +def solution(teams: list, scores: list) -> int: + best = {} + for t, s in zip(teams, scores): + best[t] = max(best.get(t, s), s) + return sum(best.values()) +""" + +examples = """ +solution([], []) == 0 +solution(["A", "B"], [10, 20]) == 30 +solution(["A", "A"], [-10, -5]) == -5 +solution(["A", "B", "A"], [10, 20, 30]) == 50 +""" + +[[input_signature]] +argument_name = "teams" +[input_signature.type] +name = "array" +[input_signature.type.nested] +name = "string" + +[[input_signature]] +argument_name = "scores" +[input_signature.type] +name = "array" +[input_signature.type.nested] +name = "integer" + +[output_signature.type] +name = "integer" + +[[asserts]] +arguments = [[], []] +comment = "Empty arrays" +expected = 0 + +[[asserts]] +arguments = [["A"], [10]] +comment = "Single team, single score" +expected = 10 + +[[asserts]] +arguments = [["A", "A"], [10, 20]] +comment = "Single team, multiple increasing scores" +expected = 20 + +[[asserts]] +arguments = [["A", "A"], [20, 10]] +comment = "Single team, multiple decreasing scores" +expected = 20 + +[[asserts]] +arguments = [["A", "A"], [-10, -5]] +comment = "Single team, negative increasing scores" +expected = -5 + +[[asserts]] +arguments = [["A", "A"], [-5, -10]] +comment = "Single team, negative decreasing scores" +expected = -5 + +[[asserts]] +arguments = [["A", "B"], [10, 20]] +comment = "Two distinct teams" +expected = 30 + +[[asserts]] +arguments = [["A", "B", "A"], [10, 20, 30]] +comment = "Two teams, one improves" +expected = 50 + +[[asserts]] +arguments = [["A", "B", "A", "B"], [5, 5, 5, 5]] +comment = "Multiple teams with identical scores" +expected = 10 + +[[asserts]] +arguments = [["Red", "Blue", "Green"], [-10, -20, -30]] +comment = "Distinct teams with negative scores" +expected = -60 + +[[asserts]] +arguments = [["T1", "T2", "T1", "T2"], [100, -100, -50, 50]] +comment = "Mix of negative and positive improvements" +expected = 150 + +[[asserts]] +arguments = [["X"], [0]] +comment = "Single zero score" +expected = 0 + +[[asserts]] +arguments = [["X", "X", "X"], [0, 0, 0]] +comment = "Multiple zero scores for one team" +expected = 0 + +[[asserts]] +arguments = [["TeamA", "TeamB", "TeamC", "TeamA"], [15, 25, 35, 10]] +comment = "Later score is lower" +expected = 75 + +[[asserts]] +arguments = [["Alpha", "Beta", "Alpha", "Beta", "Gamma"], [1, 2, 3, 4, 5]] +comment = "Various teams interleaving" +expected = 12 + +[[asserts]] +arguments = [["Z", "Y", "X", "W"], [10, 10, 10, 10]] +comment = "All distinct teams, same score" +expected = 40 + +[[asserts]] +arguments = [["T1", "T1", "T1", "T1", "T1"], [-1, -2, -3, -4, -5]] +comment = "Strictly decreasing negative sequence" +expected = -1 + +[[asserts]] +arguments = [["T1", "T1", "T1", "T1", "T1"], [-5, -4, -3, -2, -1]] +comment = "Strictly increasing negative sequence" +expected = -1 + +[[asserts]] +arguments = [["One"], [9999]] +comment = "Large single value" +expected = 9999 + +[[asserts]] +arguments = [["A", "B", "C", "D", "E"], [1, -1, 2, -2, 3]] +comment = "Alternating positive and negative base line" +expected = 3 + +[[asserts]] +arguments = [["Cats", "Dogs", "Cats", "Dogs"], [13, 14, 13, 15]] +comment = "Minor score adjustments" +expected = 28 + +[[asserts]] +arguments = [["A", "a"], [10, 20]] +comment = "Case sensitivity test" +expected = 30 + +[[asserts]] +arguments = [["Team1", "Team2", "Team3", "Team1"], [-1000, 500, 0, -500]] +comment = "Deep negative improvement" +expected = 0 + +[[asserts]] +arguments = [["Same", "Same", "Different"], [50, 50, 100]] +comment = "Duplicate scores on same team" +expected = 150 + +[[asserts]] +arguments = [["A", "B", "C", "A", "B", "C"], [1, 2, 3, 4, 5, 6]] +comment = "Double pass of the same teams" +expected = 15 diff --git a/tasks/easy/math/custom_fibonacci.toml b/tasks/easy/math/custom_fibonacci.toml new file mode 100644 index 0000000..8497ba3 --- /dev/null +++ b/tasks/easy/math/custom_fibonacci.toml @@ -0,0 +1,199 @@ +base_score = 100 +level = "easy" +name = "custom_fibonacci" +tags = ["math", "algorithms"] +time_to_solve_sec = 200 + +description_en = """ +Given three integers `f0`, `f1`, and `n`. + +Consider a sequence where the first two elements are `f0` and `f1`, and every subsequent element is the sum of the two preceding elements. + +Return `True` if `n` belongs to this sequence, and `False` otherwise. +""" + +description_ru = """ +Даны три целых числа `f0`, `f1` и `n`. + +Рассмотрим последовательность, первые два элемента которой равны `f0` и `f1`, а каждый последующий элемент равен сумме двух предыдущих. + +Верните `True`, если `n` принадлежит этой последовательности, и `False` в противном случае. +""" + +limits = """ +- $0 \\leq f_0, f_1 \\leq 1000$ +- $0 \\leq n \\leq 10^9$ +""" + +solution = """ +def solution(f0: int, f1: int, n: int) -> bool: + if n in (f0, f1): return True + if f0 == 0 and f1 == 0: return False + while f1 < n: + f0, f1 = f1, f0 + f1 + return f1 == n +""" + +examples = """ +solution(0, 1, 5) == True +solution(2, 1, 4) == True +solution(10, 20, 100) == False +""" + +[[input_signature]] +argument_name = "f0" +[input_signature.type] +name = "integer" + +[[input_signature]] +argument_name = "f1" +[input_signature.type] +name = "integer" + +[[input_signature]] +argument_name = "n" +[input_signature.type] +name = "integer" + +[output_signature.type] +name = "boolean" + +[[asserts]] +arguments = [0, 1, 5] +comment = "Classic Fibonacci, n = 5 is in the sequence" +expected = true + +[[asserts]] +arguments = [0, 1, 8] +comment = "Classic Fibonacci, n = 8 is in the sequence" +expected = true + +[[asserts]] +arguments = [0, 1, 4] +comment = "Classic Fibonacci, n = 4 is NOT in the sequence" +expected = false + +[[asserts]] +arguments = [2, 1, 3] +comment = "Lucas numbers, 3 is in (2, 1, 3)" +expected = true + +[[asserts]] +arguments = [2, 1, 4] +comment = "Lucas numbers, 4 is in (2, 1, 3, 4)" +expected = true + +[[asserts]] +arguments = [2, 1, 7] +comment = "Lucas numbers, 7 is in (2, 1, 3, 4, 7)" +expected = true + +[[asserts]] +arguments = [2, 1, 10] +comment = "Lucas numbers, 10 is NOT in sequence" +expected = false + +[[asserts]] +arguments = [0, 0, 0] +comment = "Zero sequence, n = 0" +expected = true + +[[asserts]] +arguments = [0, 0, 5] +comment = "Zero sequence, n = 5 is NOT in sequence" +expected = false + +[[asserts]] +arguments = [5, 5, 10] +comment = "Equal starting numbers, 10 is in sequence" +expected = true + +[[asserts]] +arguments = [5, 5, 15] +comment = "Equal starting numbers, 15 is in sequence" +expected = true + +[[asserts]] +arguments = [5, 5, 20] +comment = "Equal starting numbers, 20 is NOT in sequence" +expected = false + +[[asserts]] +arguments = [10, 20, 30] +comment = "Multiples of 10, 30 is in sequence" +expected = true + +[[asserts]] +arguments = [10, 20, 50] +comment = "Multiples of 10, 50 is in sequence" +expected = true + +[[asserts]] +arguments = [10, 20, 80] +comment = "Multiples of 10, 80 is in sequence" +expected = true + +[[asserts]] +arguments = [10, 20, 130] +comment = "Multiples of 10, 130 is in sequence" +expected = true + +[[asserts]] +arguments = [10, 20, 100] +comment = "Multiples of 10, 100 is NOT in sequence" +expected = false + +[[asserts]] +arguments = [100, 1, 101] +comment = "Decreasing start, 101 is in sequence" +expected = true + +[[asserts]] +arguments = [100, 1, 102] +comment = "Decreasing start, 102 is in sequence" +expected = true + +[[asserts]] +arguments = [100, 1, 203] +comment = "Decreasing start, 203 is in sequence" +expected = true + +[[asserts]] +arguments = [100, 1, 200] +comment = "Decreasing start, 200 is NOT in sequence" +expected = false + +[[asserts]] +arguments = [5, 10, 5] +comment = "n is equal to f0" +expected = true + +[[asserts]] +arguments = [5, 10, 10] +comment = "n is equal to f1" +expected = true + +[[asserts]] +arguments = [50, 60, 10] +comment = "n is smaller than both f0 and f1" +expected = false + +[[asserts]] +arguments = [0, 1, 102334155] +comment = "Large Fibonacci number" +expected = true + +[[asserts]] +arguments = [0, 1, 102334156] +comment = "Large number NOT in Fibonacci sequence" +expected = false + +[[asserts]] +arguments = [0, 1, 701408733] +comment = "Another large Fibonacci number" +expected = true + +[[asserts]] +arguments = [13, 21, 5] +comment = "n is smaller than f0, f1 with Fibonacci sequence" +expected = false diff --git a/tasks/easy/math/expanded_notation_array.toml b/tasks/easy/math/expanded_notation_array.toml new file mode 100644 index 0000000..cd902f9 --- /dev/null +++ b/tasks/easy/math/expanded_notation_array.toml @@ -0,0 +1,199 @@ +base_score = 100 +level = "easy" +name = "expanded_notation_array" +tags = ["math", "strings", "parsing", "arrays"] +time_to_solve_sec = 250 + +description_en = """ +Expanded Notation means an integer is written as the sum of its digits multiplied with its place value (in strictly descending powers of $10$). + +For example, $85063 = 8 \\times 10000 + 5 \\times 1000 + 6 \\times 10 + 3$. + +You are given an array of strings `arr`, where each string represents a non-negative integer in expanded notation. The strings use `"x"` for multiplication and `"+"` for addition, with no spaces. Your task is to compute the sum for each string and return an array of these numbers in their normal integer form. + +Each term is a single digit multiplied by a power of ten; a units term may omit `x1`. Place values strictly decrease within each string. Each resulting integer is at most $2 \\cdot 10^9$. +""" + +description_ru = """ +Развернутая запись означает, что целое число записано в виде суммы его цифр, умноженных на их разрядное значение (в строго убывающих степенях $10$). + +Например, $85063 = 8 \\times 10000 + 5 \\times 1000 + 6 \\times 10 + 3$. + +Вам дан массив строк `arr`, где каждая строка представляет неотрицательное целое число в развернутой записи. В строках используется `"x"` для умножения и `"+"` для сложения, без пробелов. Ваша задача — вычислить сумму для каждой строки и вернуть массив этих чисел в обычном целом виде. + +Каждое слагаемое — одна цифра, умноженная на степень десяти; у единиц можно опустить `x1`. Разрядные значения в каждой строке строго убывают. Каждое полученное целое число не превышает $2 \\cdot 10^9$. +""" + +limits = """ +- $1 \\leq \\text{len}(arr) \\leq 100$ +- $1 \\leq \\text{len}(arr[i]) \\leq 100$ +- $0 \\leq \\text{value}(arr[i]) \\leq 2 \\cdot 10^9$ +""" + +solution = """ +def solution(arr: list[str]) -> list[int]: + def value(term): + factors = term.split('x') + return int(factors[0]) * (int(factors[1]) if len(factors) == 2 else 1) + return [sum(value(term) for term in s.split('+')) for s in arr] +""" + +examples = """ +solution(["1x1"]) == [1] +solution(["9x10", "1x1"]) == [90, 1] +solution(["7x100+2x1", "8x10000+5x1000+6x10+3"]) == [702, 85063] +""" + +[[input_signature]] +argument_name = "arr" +[input_signature.type] +name = "array" +[input_signature.type.nested] +name = "string" + +[output_signature.type] +name = "array" +[output_signature.type.nested] +name = "integer" + +[[asserts]] +arguments = [["8x10000+5x1000+6x10+3x1"]] +comment = "Complex example from description" +expected = [85063] + +[[asserts]] +arguments = [["7x100+2x1", "1x1"]] +comment = "Multiple elements" +expected = [702, 1] + +[[asserts]] +arguments = [["1x1"]] +comment = "Single digit" +expected = [1] + +[[asserts]] +arguments = [["9x10", "4x100000+2x100"]] +comment = "Varying lengths" +expected = [90, 400200] + +[[asserts]] +arguments = [["1x1000+1x1"]] +comment = "One thousand and one" +expected = [1001] + +[[asserts]] +arguments = [["1x10", "1x100", "1x1000"]] +comment = "Increasing powers of ten" +expected = [10, 100, 1000] + +[[asserts]] +arguments = [["5x1000+5x10", "6x10000+6x100+6x1", "7x1000000"]] +comment = "Array with three different complexities" +expected = [5050, 60606, 7000000] + +[[asserts]] +arguments = [["9x1000+9x100+9x10+9x1"]] +comment = "All nines" +expected = [9999] + +[[asserts]] +arguments = [ + [ + "1x100000000+2x10000000+3x1000000+4x100000+5x10000+6x1000+7x100+8x10+9x1", + ], +] +comment = "Consecutive digits" +expected = [123456789] + +[[asserts]] +arguments = [["2x1000000+1x1", "3x10"]] +comment = "Millions and tens" +expected = [2000001, 30] + +[[asserts]] +arguments = [["4x100+4x1", "5x100+5x10"]] +comment = "Hundreds" +expected = [404, 550] + +[[asserts]] +arguments = [["5x10000+5x1000"]] +comment = "Fifty five thousand" +expected = [55000] + +[[asserts]] +arguments = [["8x100000000", "9x100000000+9x1000000+9x10000+9x100+9x1"]] +comment = "Alternating nines and zeros" +expected = [800000000, 909090909] + +[[asserts]] +arguments = [["1x10000+1x1000+1x100+1x10+1x1", "2x100+2x10+2x1"]] +comment = "All ones and all twos" +expected = [11111, 222] + +[[asserts]] +arguments = [["3x10+3x1", "4x1"]] +comment = "All threes and fours" +expected = [33, 4] + +[[asserts]] +arguments = [["1x1000000000"]] +comment = "One billion" +expected = [1000000000] + +[[asserts]] +arguments = [["1x1000000000+1x10000000+1x100000+1x1000+1x10"]] +comment = "Alternating ones and zeros" +expected = [1010101010] + +[[asserts]] +arguments = [["5x10000+4x1000+3x100+2x10+1x1", "1x1"]] +comment = "Descending digits" +expected = [54321, 1] + +[[asserts]] +arguments = [ + [ + "9x100000000+8x10000000+7x1000000+6x100000+5x10000+4x1000+3x100+2x10+1x1", + ], +] +comment = "Long descending digits" +expected = [987654321] + +[[asserts]] +arguments = [["9x100+9x10+9x1", "8x100+8x10+8x1"]] +comment = "Nines and eights" +expected = [999, 888] + +[[asserts]] +arguments = [["7x1000+2x1", "6x1000+3x10", "5x1000+4x100"]] +comment = "Zeros in different positions" +expected = [7002, 6030, 5400] + +[[asserts]] +arguments = [["1x10000", "2x10000", "3x10000"]] +comment = "Same order of magnitude" +expected = [10000, 20000, 30000] + +[[asserts]] +arguments = [["1x100000", "2x1000000"]] +comment = "Powers of ten variations" +expected = [100000, 2000000] + +[[asserts]] +arguments = [["1x1000000+2x100000+3x10000", "4x1000+5x100+6x10+7x1"]] +comment = "Split full number across array elements" +expected = [1230000, 4567] + +[[asserts]] +arguments = [["8x100000+5x100+3x1", "2x10000+4x100+1x1"]] +comment = "Various missing place values" +expected = [800503, 20401] +[[asserts]] +arguments = [["7x100+2", "8x10000+5x1000+6x10+3"]] +comment = "Units may omit multiplication by one" +expected = [702, 85063] + +[[asserts]] +arguments = [["0", "9"]] +comment = "Bare units and zero" +expected = [0, 9] diff --git a/tasks/easy/math/primes_with_prime_digit_sum.toml b/tasks/easy/math/primes_with_prime_digit_sum.toml new file mode 100644 index 0000000..bbcaac5 --- /dev/null +++ b/tasks/easy/math/primes_with_prime_digit_sum.toml @@ -0,0 +1,183 @@ +base_score = 100 +level = "easy" +name = "primes_with_prime_digit_sum" +tags = ["math", "numbers"] +time_to_solve_sec = 250 + +description_en = """ +Find all prime numbers in the inclusive range $[a, b]$ such that the sum of their digits is also a prime number. Return the result as an array. + +Return the numbers in increasing order. +""" + +description_ru = """ +Найдите все простые числа на отрезке $[a, b]$ (включительно), сумма цифр которых также является простым числом. Верните результат в виде массива. + +Верните числа в порядке возрастания. +""" + +limits = """ +- $1 \\leq a \\leq b \\leq 10^4$ +""" + +solution = """ +def solution(a: int, b: int) -> list: + P = lambda n: n > 1 and all(n % i for i in range(2, int(n**0.5) + 1)) + return [x for x in range(a, b + 1) if P(x) and P(sum(map(int, str(x))))] +""" + +examples = """ +solution(30, 40) == [] +solution(10, 20) == [11] +solution(1, 10) == [2, 3, 5, 7] +""" + +[[input_signature]] +argument_name = "a" +[input_signature.type] +name = "integer" + +[[input_signature]] +argument_name = "b" +[input_signature.type] +name = "integer" + +[output_signature.type] +name = "array" +[output_signature.type.nested] +name = "integer" + +[[asserts]] +arguments = [1, 10] +comment = "Single digit primes" +expected = [2, 3, 5, 7] + +[[asserts]] +arguments = [10, 20] +comment = "First two-digit numbers" +expected = [11] + +[[asserts]] +arguments = [20, 30] +comment = "Twenties" +expected = [23, 29] + +[[asserts]] +arguments = [30, 40] +comment = "No matching primes in this range" +expected = [] + +[[asserts]] +arguments = [40, 50] +comment = "Forties" +expected = [41, 43, 47] + +[[asserts]] +arguments = [50, 60] +comment = "Fifties without matches" +expected = [] + +[[asserts]] +arguments = [60, 70] +comment = "Sixties" +expected = [61, 67] + +[[asserts]] +arguments = [70, 80] +comment = "Seventies without matches" +expected = [] + +[[asserts]] +arguments = [80, 90] +comment = "Eighties" +expected = [83, 89] + +[[asserts]] +arguments = [90, 100] +comment = "Nineties without matches" +expected = [] + +[[asserts]] +arguments = [100, 120] +comment = "Early hundreds" +expected = [101, 113] + +[[asserts]] +arguments = [130, 140] +comment = "Range with consecutive valid primes" +expected = [131, 137, 139] + +[[asserts]] +arguments = [190, 200] +comment = "Late hundreds" +expected = [191, 193, 197, 199] + +[[asserts]] +arguments = [200, 210] +comment = "Early two-hundreds with no valid primes" +expected = [] + +[[asserts]] +arguments = [200, 250] +comment = "Larger slice in two-hundreds" +expected = [223, 227, 229, 241] + +[[asserts]] +arguments = [300, 320] +comment = "Early three-hundreds" +expected = [311, 313, 317] + +[[asserts]] +arguments = [400, 420] +comment = "Early four-hundreds" +expected = [401, 409] + +[[asserts]] +arguments = [500, 520] +comment = "Early five-hundreds without matches" +expected = [] + +[[asserts]] +arguments = [600, 620] +comment = "Early six-hundreds" +expected = [601, 607] + +[[asserts]] +arguments = [700, 720] +comment = "Early seven-hundreds" +expected = [719] + +[[asserts]] +arguments = [800, 820] +comment = "Early eight-hundreds" +expected = [809] + +[[asserts]] +arguments = [900, 920] +comment = "Early nine-hundreds" +expected = [911, 919] + +[[asserts]] +arguments = [990, 1000] +comment = "Approaching one thousand" +expected = [991] + +[[asserts]] +arguments = [1, 1] +comment = "Single value 1 (not prime)" +expected = [] + +[[asserts]] +arguments = [2, 2] +comment = "Single value 2 (prime)" +expected = [2] + +[[asserts]] +arguments = [11, 11] +comment = "Single value boundary check" +expected = [11] + +[[asserts]] +arguments = [1000, 1010] +comment = "Past one thousand without matches" +expected = [] diff --git a/tasks/easy/math/self_dividing_numbers.toml b/tasks/easy/math/self_dividing_numbers.toml new file mode 100644 index 0000000..184327f --- /dev/null +++ b/tasks/easy/math/self_dividing_numbers.toml @@ -0,0 +1,187 @@ +base_score = 100 +level = "easy" +name = "self_dividing_numbers" +tags = ["math", "loops"] +time_to_solve_sec = 240 + +description_en = """ +A self-dividing number is a number that is divisible by every digit it contains. +For example, `128` is a self-dividing number because $128 \\pmod 1 = 0$, $128 \\pmod 2 = 0$, and $128 \\pmod 8 = 0$. + +A self-dividing number is not allowed to contain the digit `0`. + +Given two integers `left` and `right`, return an array of all the self-dividing numbers in the range `[left, right]` (inclusive). + +Return the numbers in increasing order. +""" + +description_ru = """ +Самоделящееся число — это число, которое без остатка делится на каждую из своих цифр. +Например, `128` является самоделящимся числом, так как $128 \\pmod 1 = 0$, $128 \\pmod 2 = 0$ и $128 \\pmod 8 = 0$. + +Самоделящееся число не должно содержать цифру `0`. + +Даны два целых числа `left` и `right`. Верните массив всех самоделящихся чисел в диапазоне `[left, right]` (включительно). + +Верните числа в порядке возрастания. +""" + +limits = """ +- $1 \\leq \\text{left} \\leq \\text{right} \\leq 10^4$ +""" + +solution = """ +def solution(left: int, right: int) -> list[int]: + return [n for n in range(left, right + 1) if all(int(d) != 0 and n % int(d) == 0 for d in str(n))] +""" + +examples = """ +solution(47, 49) == [48] +solution(10, 15) == [11, 12, 15] +solution(1, 10) == [1, 2, 3, 4, 5, 6, 7, 8, 9] +""" + +[[input_signature]] +argument_name = "left" +[input_signature.type] +name = "integer" + +[[input_signature]] +argument_name = "right" +[input_signature.type] +name = "integer" + +[output_signature.type] +name = "array" +[output_signature.type.nested] +name = "integer" + +[[asserts]] +arguments = [1, 10] +comment = "Single digits" +expected = [1, 2, 3, 4, 5, 6, 7, 8, 9] + +[[asserts]] +arguments = [10, 15] +comment = "Small range with zero" +expected = [11, 12, 15] + +[[asserts]] +arguments = [47, 49] +comment = "Short range with one match" +expected = [48] + +[[asserts]] +arguments = [1, 22] +comment = "Range across two tens" +expected = [1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 15, 22] + +[[asserts]] +arguments = [13, 14] +comment = "Range with no self-dividing numbers" +expected = [] + +[[asserts]] +arguments = [47, 85] +comment = "Mid-size range" +expected = [48, 55, 66, 77] + +[[asserts]] +arguments = [128, 128] +comment = "Three-digit match" +expected = [128] + +[[asserts]] +arguments = [100, 110] +comment = "Range full of zeros" +expected = [] + +[[asserts]] +arguments = [111, 115] +comment = "Range with small identical digits" +expected = [111, 112, 115] + +[[asserts]] +arguments = [15, 21] +comment = "Cross-tens range with one match" +expected = [15] + +[[asserts]] +arguments = [33, 33] +comment = "Identical digits self-dividing" +expected = [33] + +[[asserts]] +arguments = [23, 23] +comment = "Single number, non self-dividing" +expected = [] + +[[asserts]] +arguments = [312, 312] +comment = "Three-digit match check" +expected = [312] + +[[asserts]] +arguments = [41, 45] +comment = "Check divisibility logic" +expected = [44] + +[[asserts]] +arguments = [80, 90] +comment = "High two-digits range" +expected = [88] + +[[asserts]] +arguments = [300, 311] +comment = "Zeros and non-dividing" +expected = [] + +[[asserts]] +arguments = [200, 212] +comment = "Zeros jumping to valid" +expected = [212] + +[[asserts]] +arguments = [72, 73] +comment = "Exact bounds" +expected = [] + +[[asserts]] +arguments = [1000, 1010] +comment = "Thousands with zeros" +expected = [] + +[[asserts]] +arguments = [120, 130] +comment = "Hundreds range" +expected = [122, 124, 126, 128] + +[[asserts]] +arguments = [999, 999] +comment = "Maximum triple digits" +expected = [999] + +[[asserts]] +arguments = [24, 25] +comment = "Adjacent values" +expected = [24] + +[[asserts]] +arguments = [104, 104] +comment = "Contains zero, despite other checks" +expected = [] + +[[asserts]] +arguments = [61, 65] +comment = "Range with no matches" +expected = [] + +[[asserts]] +arguments = [25, 30] +comment = "Range leading to zero" +expected = [] + +[[asserts]] +arguments = [300, 315] +comment = "Wider range in hundreds" +expected = [312, 315] diff --git a/tasks/easy/strings/center_strings.toml b/tasks/easy/strings/center_strings.toml new file mode 100644 index 0000000..4ab44da --- /dev/null +++ b/tasks/easy/strings/center_strings.toml @@ -0,0 +1,206 @@ +base_score = 100 +level = "easy" +name = "center_strings" +tags = ["strings", "formatting"] +time_to_solve_sec = 200 + +description_en = """ +Given an array of strings, return a new array where each string is centered to the length of the longest string in the original array, padded with spaces (`" "`). + +If the padding is uneven (i.e., the difference between the maximum length and the current string's length is odd), place the extra space as follows: +- If the target width is odd and the margin is odd, the extra space goes to the **left**. +- Otherwise, the extra space goes to the **right**. + +If the input array is empty, return an empty array. +""" + +description_ru = """ +Дан массив строк. Верните новый массив, в котором каждая строка отцентрирована по длине самой длинной строки в исходном массиве и дополнена пробелами (`" "`). + +Если количество добавляемых пробелов нечетное, расположите дополнительный пробел по следующим правилам: +- Если целевая ширина нечетная и общая разница нечетная, дополнительный пробел добавляется **слева**. +- Во всех остальных случаях дополнительный пробел добавляется **справа**. + +Если исходный массив пуст, верните пустой массив. +""" + +limits = """ +- $0 \\leq \\text{len}(strings) \\leq 100$ +- $0 \\leq \\text{len}(strings[i]) \\leq 100$ +""" + +solution = """ +def solution(strings: list[str]) -> list[str]: + if not strings: + return [] + max_len = max(len(s) for s in strings) + return [s.center(max_len) for s in strings] +""" + +examples = """ +solution([]) == [] +solution(["hi", "hello"]) == [" hi ", "hello"] +solution(["a", "abc", "a"]) == [" a ", "abc", " a "] +""" + +[[input_signature]] +argument_name = "strings" +[input_signature.type] +name = "array" +[input_signature.type.nested] +name = "string" + +[output_signature.type] +name = "array" +[output_signature.type.nested] +name = "string" + +[[asserts]] +arguments = [[]] +comment = "Empty array" +expected = [] + +[[asserts]] +arguments = [["hello"]] +comment = "Single string" +expected = ["hello"] + +[[asserts]] +arguments = [["a", "abc"]] +comment = "Odd max len, odd string, even margin -> equal padding" +expected = [" a ", "abc"] + +[[asserts]] +arguments = [["ab", "abcd"]] +comment = "Even max len, even string, even margin -> equal padding" +expected = [" ab ", "abcd"] + +[[asserts]] +arguments = [["a", "abcd"]] +comment = "Even max len, odd string, odd margin -> extra space right" +expected = [" a ", "abcd"] + +[[asserts]] +arguments = [["abc", "a"]] +comment = "Max string first" +expected = ["abc", " a "] + +[[asserts]] +arguments = [["hi", "hello"]] +comment = "Odd max len, even string, odd margin -> extra space left" +expected = [" hi ", "hello"] + +[[asserts]] +arguments = [["", "a"]] +comment = "Odd max len, empty string, odd margin" +expected = [" ", "a"] + +[[asserts]] +arguments = [["", "ab"]] +comment = "Even max len, empty string, even margin" +expected = [" ", "ab"] + +[[asserts]] +arguments = [["A", "BB", "CCC", "DDDD"]] +comment = "Multiple lengths with max 4" +expected = [" A ", " BB ", "CCC ", "DDDD"] + +[[asserts]] +arguments = [["*", "***", "*****"]] +comment = "Stars with max 5" +expected = [" * ", " *** ", "*****"] + +[[asserts]] +arguments = [["python", "is", "fun"]] +comment = "Words with max 6" +expected = ["python", " is ", " fun "] + +[[asserts]] +arguments = [["short", "loooong"]] +comment = "Words with max 7" +expected = [" short ", "loooong"] + +[[asserts]] +arguments = [["1", "123456789"]] +comment = "1 char to 9 chars" +expected = [" 1 ", "123456789"] + +[[asserts]] +arguments = [["12", "123456789"]] +comment = "2 chars to 9 chars (extra space left)" +expected = [" 12 ", "123456789"] + +[[asserts]] +arguments = [["123", "123456789"]] +comment = "3 chars to 9 chars" +expected = [" 123 ", "123456789"] + +[[asserts]] +arguments = [["1234", "123456789"]] +comment = "4 chars to 9 chars (extra space left)" +expected = [" 1234 ", "123456789"] + +[[asserts]] +arguments = [["12345", "123456789"]] +comment = "5 chars to 9 chars" +expected = [" 12345 ", "123456789"] + +[[asserts]] +arguments = [["123456", "123456789"]] +comment = "6 chars to 9 chars (extra space left)" +expected = [" 123456 ", "123456789"] + +[[asserts]] +arguments = [["1234567", "123456789"]] +comment = "7 chars to 9 chars" +expected = [" 1234567 ", "123456789"] + +[[asserts]] +arguments = [["12345678", "123456789"]] +comment = "8 chars to 9 chars (extra space left)" +expected = [" 12345678", "123456789"] + +[[asserts]] +arguments = [["word", ""]] +comment = "Empty string padded to even length" +expected = ["word", " "] + +[[asserts]] +arguments = [["even", "odd lengths"]] +comment = "4 chars to 11 chars (extra space left)" +expected = [" even ", "odd lengths"] + +[[asserts]] +arguments = [["same", "size"]] +comment = "Already same size" +expected = ["same", "size"] + +[[asserts]] +arguments = [["a", "a", "a"]] +comment = "All identical" +expected = ["a", "a", "a"] + +[[asserts]] +arguments = [[" ", " "]] +comment = "Spaces only" +expected = [" ", " "] + +[[asserts]] +arguments = [["x", "y", "longword"]] +comment = "Single chars to even max length" +expected = [" x ", " y ", "longword"] + +[[asserts]] +arguments = [["", "", ""]] +comment = "All empty strings" +expected = ["", "", ""] + +[[asserts]] +arguments = [["align", "me", "please", "to", "center"]] +comment = "Multiple mixed strings, max 6" +expected = ["align ", " me ", "please", " to ", "center"] + +[[asserts]] +arguments = [["12345", "1234", "123", "12", "1", ""]] +comment = "Decreasing lengths, max 5" +expected = ["12345", " 1234", " 123 ", " 12 ", " 1 ", " "] diff --git a/tasks/easy/strings/digit_snake_formatter.toml b/tasks/easy/strings/digit_snake_formatter.toml new file mode 100644 index 0000000..a85285b --- /dev/null +++ b/tasks/easy/strings/digit_snake_formatter.toml @@ -0,0 +1,208 @@ +base_score = 100 +level = "easy" +name = "digit_snake_formatter" +tags = ["strings", "formatting"] +time_to_solve_sec = 250 + +description_en = """ +Transform a digit string `n` into a "snake" format based on an integer `c`: + +1. Extract the first `c` digits from string `n`. If `c` exceeds the length of `n`, use all available digits. +2. Split the resulting substring into chunks of $8$ characters. +3. Pad the final chunk with the character `X` on the right until it reaches a length of $8$. +4. Reverse chunks located at odd indices ($1, 3, 5, \\dots$). Keep chunks at even indices ($0, 2, 4, \\dots$) as they are. +5. Return the chunks joined by newline characters (`\\n`). +""" + +description_ru = """ +Преобразуйте строку цифр `n` в формат «змейки» на основе целого числа `c`: + +1. Возьмите первые `c` цифр из строки `n`. Если `c` больше длины `n`, используйте все имеющиеся цифры. +2. Разделите полученную подстроку на блоки по $8$ символов. +3. Дополните последний блок символом `X` справа, пока его длина не станет равной $8$. +4. Разверните блоки, находящиеся на нечетных индексах ($1, 3, 5, \\dots$). Блоки на четных индексах ($0, 2, 4, \\dots$) оставьте без изменений. +5. Верните блоки, объединенные символом переноса строки (`\\n`). +""" + +limits = """ +- $0 \\leq \\text{len}(n) \\leq 1000$ +- $0 \\leq c \\leq 1000$ +- $n \\in \\{0,1,2,3,4,5,6,7,8,9\\}^*$ +""" + +solution = """ +def solution(n: str, c: int) -> str: + s = n[:c] + chunks = [s[i:i+8].ljust(8, 'X') for i in range(0, len(s), 8)] + return "\\n".join(x[::-1] if i % 2 else x for i, x in enumerate(chunks)) +""" + +examples = """ +solution("", 5) == "" +solution("123", 0) == "" +solution("123", 2) == "12XXXXXX" +solution("1234567890", 10) == "12345678\\nXXXXXX09" +""" + +[[input_signature]] +argument_name = "n" +[input_signature.type] +name = "string" + +[[input_signature]] +argument_name = "c" +[input_signature.type] +name = "integer" + +[output_signature.type] +name = "string" + +[[asserts]] +arguments = ["", 10] +comment = "Empty string input" +expected = "" + +[[asserts]] +arguments = ["12345", 0] +comment = "Zero characters requested" +expected = "" + +[[asserts]] +arguments = ["1", 1] +comment = "Single character padding" +expected = "1XXXXXXX" + +[[asserts]] +arguments = ["12345678", 8] +comment = "Exactly one full chunk" +expected = "12345678" + +[[asserts]] +arguments = ["123456789", 9] +comment = "Two chunks, second needs padding and reversal" +expected = "12345678\nXXXXXXX9" + +[[asserts]] +arguments = ["1234567890123456", 16] +comment = "Two full chunks, second reversed" +expected = "12345678\n65432109" + +[[asserts]] +arguments = ["111111112222222233333333", 24] +comment = "Three full chunks" +expected = "11111111\n22222222\n33333333" + +[[asserts]] +arguments = ["123", 5] +comment = "c is greater than string length" +expected = "123XXXXX" + +[[asserts]] +arguments = ["0000000000000000", 16] +comment = "Identical digits" +expected = "00000000\n00000000" + +[[asserts]] +arguments = ["12345678123456781234567812345678", 32] +comment = "Four full chunks" +expected = "12345678\n87654321\n12345678\n87654321" + +[[asserts]] +arguments = ["987654321", 5] +comment = "c is smaller than first chunk size" +expected = "98765XXX" + +[[asserts]] +arguments = ["1234567890", 11] +comment = "c is larger than length, but logic handles it" +expected = "12345678\nXXXXXX09" + +[[asserts]] +arguments = ["123456781", 9] +comment = "Last chunk is single digit" +expected = "12345678\nXXXXXXX1" + +[[asserts]] +arguments = ["123456781234567", 15] +comment = "Last chunk is almost full" +expected = "12345678\nX7654321" + +[[asserts]] +arguments = ["1234567887654321", 16] +comment = "Reversing a reversed sequence" +expected = "12345678\n12345678" + +[[asserts]] +arguments = ["01234567890123456789", 20] +comment = "Three chunks, middle one full reversed" +expected = "01234567\n54321098\n6789XXXX" + +[[asserts]] +arguments = ["12121212", 8] +comment = "Repeating pattern" +expected = "12121212" + +[[asserts]] +arguments = ["1234123412341234", 16] +comment = "Repeating chunks" +expected = "12341234\n43214321" + +[[asserts]] +arguments = ["1111111100000000", 16] +comment = "Switching values between chunks" +expected = "11111111\n00000000" + +[[asserts]] +arguments = ["5555", 2] +comment = "c limits string to less than original" +expected = "55XXXXXX" + +[[asserts]] +arguments = ["123456789012345678901234567890", 25] +comment = "Multiple chunks with padding at the very end" +expected = "12345678\n65432109\n78901234\nXXXXXXX5" + +[[asserts]] +arguments = ["888888887777777766666666", 20] +comment = "Non-full third chunk" +expected = "88888888\n77777777\n6666XXXX" + +[[asserts]] +arguments = ["0000000100000002", 16] +comment = "Check specific digit placement" +expected = "00000001\n20000000" + +[[asserts]] +arguments = ["123456789999999912345678", 24] +comment = "Middle chunk all 9s" +expected = "12345678\n99999999\n12345678" + +[[asserts]] +arguments = ["1000000020000000", 16] +comment = "Zeros and specific digits" +expected = "10000000\n00000002" + +[[asserts]] +arguments = ["1234567812345678123456781234567812345678", 40] +comment = "Five chunks check" +expected = "12345678\n87654321\n12345678\n87654321\n12345678" + +[[asserts]] +arguments = ["111122223333444455556666", 24] +comment = "Alternating even/odd reversal" +expected = "11112222\n44443333\n55556666" + +[[asserts]] +arguments = ["12345678", 9] +comment = "c slightly larger than len(n)" +expected = "12345678" + +[[asserts]] +arguments = ["9", 1] +comment = "Min non-zero case" +expected = "9XXXXXXX" + +[[asserts]] +arguments = ["12345678901234567890", 17] +comment = "Last chunk is single char, index 2 (even)" +expected = "12345678\n65432109\n7XXXXXXX" diff --git a/tasks/easy/strings/fancy_number.toml b/tasks/easy/strings/fancy_number.toml index 9273d3e..89314d9 100644 --- a/tasks/easy/strings/fancy_number.toml +++ b/tasks/easy/strings/fancy_number.toml @@ -5,184 +5,217 @@ tags = ["strings", "games"] time_to_solve_sec = 300 description_en = """ -Given a number, find whether it is fancy or not. +Given a number, find whether it is **fancy** or not. -A fancy number is one which when rotated $180$ degrees is the same. +A number is called **fancy** if it does not change when rotated $180$ degrees. With this rotation: +- $6$ becomes $9$; +- $9$ becomes $6$; +- $0$, $1$, $8$ remain themselves; +- other digits break. -When rotated: $6$ becomes $9$, $9$ becomes $6$, and $8$, $1$, $0$ remain themselves (do not change). +Use the usual decimal representation without leading zeros. Negative numbers are never fancy; zero is fancy. """ description_ru = """ -Дано число, определите причудливое оно или нет. +Дано число. Определите, **причудливое** оно или нет. -Число является причудливым, если при развороте на $180$ градусов остается самим собой. +Число называется **причудливым**, если при перевороте на $180$ градусов остается самим собой. При таком перевороте: +- $6$ становится $9$; +- $9$ становится $6$; +- $0$, $1$ и $8$ остаются сами собой; +- остальные цифры перестают быть цифрами. -При повороте: $6$ становится $9$, $9$ становится $6$, а $8$, $1$ и $0$ остаются сами собой (не меняются). +Используйте обычную десятичную запись без ведущих нулей. Отрицательные числа не бывают причудливыми; ноль является причудливым. """ limits = """ -- $1 \\leq \\text{len}(\\text{num\\_str}) \\leq 10$ -- $\\text{num\\_str} \\in \\{0, 1, 6, 8, 9\\}^*$ +- $-10^9 \\leq \\text{number} \\leq 10^9$ """ solution = """ -def solution(num_str: str) -> bool: - mapping = {'0': '0', '1': '1', '6': '9', '8': '8', '9': '6'} - rotated = '' - for char in reversed(num_str): - if char not in mapping: +def solution(number: int) -> bool: + num_str = str(number) + mapping = {"0": "0", "1": "1", "6": "9", "8": "8", "9": "6"} + rotated = "" + for digit in reversed(num_str): + if digit not in mapping: return False - rotated += mapping[char] + rotated += mapping[digit] return rotated == num_str """ examples = """ -solution("96") == True -solution("916") == True -solution("996") == False -solution("9081806") == True -solution("9088806") == True +solution(69) == True +solution(369) == False +solution(996) == False +solution(9788) == False +solution(9081806) == True """ [[input_signature]] -argument_name = "num_str" +argument_name = "number" [input_signature.type] -name = "string" +name = "integer" [output_signature.type] name = "boolean" [[asserts]] -arguments = ["9081806"] -comment = "Fancy seven digit" -expected = true +arguments = [-369] +comment = "Not fancy" +expected = false [[asserts]] -arguments = ["916"] +arguments = [916] comment = "Fancy three digit" expected = true [[asserts]] -arguments = ["9088806"] -comment = "Fancy with eights" -expected = true +arguments = [926] +comment = "Not fancy three digit" +expected = false [[asserts]] -arguments = ["996"] +arguments = [996] comment = "Not symmetric" expected = false [[asserts]] -arguments = ["96"] -comment = "Simple fancy pair" -expected = true - -[[asserts]] -arguments = ["0"] +arguments = [0] comment = "Single zero" expected = true [[asserts]] -arguments = ["1"] +arguments = [1] comment = "Single one" expected = true [[asserts]] -arguments = ["8"] +arguments = [8] comment = "Single eight" expected = true [[asserts]] -arguments = ["6"] +arguments = [6] comment = "Single six not fancy" expected = false [[asserts]] -arguments = ["9"] +arguments = [9] comment = "Single nine not fancy" expected = false [[asserts]] -arguments = ["69"] +arguments = [69] comment = "Sixty-nine fancy" expected = true [[asserts]] -arguments = ["88"] +arguments = [88] comment = "Double eight" expected = true [[asserts]] -arguments = ["11"] -comment = "Double one" -expected = true +arguments = [417] +comment = "Bad digits" +expected = false [[asserts]] -arguments = ["00"] -comment = "Double zero" -expected = true +arguments = [404] +comment = "Error code" +expected = false [[asserts]] -arguments = ["101"] -comment = "One zero one" -expected = true +arguments = [848] +comment = "Eight four eight" +expected = false [[asserts]] -arguments = ["808"] -comment = "Eight zero eight" -expected = true +arguments = [602] +comment = "Six zero two" +expected = false [[asserts]] -arguments = ["609"] -comment = "Six zero nine" -expected = true +arguments = [18581] +comment = "Not fancy five digit" +expected = false [[asserts]] -arguments = ["1881"] -comment = "Fancy four digit" +arguments = [1001] +comment = "Palindromic and fancy" expected = true [[asserts]] -arguments = ["1001"] -comment = "One zero zero one" +arguments = [6889] +comment = "Fancy six eight eight nine" expected = true [[asserts]] -arguments = ["9696"] -comment = "Nine six nine six" -expected = true +arguments = [9119] +comment = "Nine one one nine" +expected = false [[asserts]] -arguments = ["6889"] -comment = "Fancy six eight eight nine" -expected = true +arguments = [9788] +comment = "Random not fancy number" +expected = false [[asserts]] -arguments = ["8008"] -comment = "Eight zero zero eight" -expected = true +arguments = [45154] +comment = "Not fancy" +expected = false [[asserts]] -arguments = ["9119"] -comment = "Nine one one nine" +arguments = [20102] +comment = "Five digit not fancy" expected = false [[asserts]] -arguments = ["60109"] -comment = "Five digit fancy" +arguments = [96896] +comment = "Five digit fancy variant" expected = true [[asserts]] -arguments = ["90806"] -comment = "Five digit fancy variant" -expected = true +arguments = [-111] +comment = "Negative with ones" +expected = false [[asserts]] -arguments = ["111"] -comment = "Triple one" +arguments = [-888] +comment = "Negative with eights" +expected = false + +[[asserts]] +arguments = [9081806] +comment = "Fancy seven digit" expected = true [[asserts]] -arguments = ["888"] -comment = "Triple eight" +arguments = [9162916] +comment = "Not fancy seven digit" +expected = false + +[[asserts]] +arguments = [9088806] +comment = "Fancy with eights" expected = true + +[[asserts]] +arguments = [96966969] +comment = "Palindromic but not fancy" +expected = false + +[[asserts]] +arguments = [-600080009] +comment = "Long negative number" +expected = false + +[[asserts]] +arguments = [-1000000000] +comment = "Input bound" +expected = false + +[[asserts]] +arguments = [1000000000] +comment = "Input bound" +expected = false diff --git a/tasks/easy/strings/longest_balanced_segment.toml b/tasks/easy/strings/longest_balanced_segment.toml new file mode 100644 index 0000000..76b9534 --- /dev/null +++ b/tasks/easy/strings/longest_balanced_segment.toml @@ -0,0 +1,199 @@ +base_score = 100 +level = "easy" +name = "longest_balanced_segment" +tags = ["strings", "hash-map", "algorithms"] +time_to_solve_sec = 250 + +description_en = """ +A binary segment is called balanced if it contains the same number of $0$s and $1$s. + +Given a binary string $s$, determine the length of the longest balanced contiguous segment. If no such segment exists, return $0$. +""" + +description_ru = """ +Бинарный сегмент называется сбалансированным, если он содержит одинаковое количество $0$ и $1$. + +Дана бинарная строка $s$. Определите длину самого длинного сбалансированного непрерывного сегмента. Если такого сегмента не существует, верните $0$. +""" + +limits = """ +- $0 \\leq \\text{len}(s) \\leq 10^5$ +- $s[i] \\in \\{0, 1\\}$ +""" + +solution = """ +def solution(s: str) -> int: + d, c, r = {0: -1}, 0, 0 + for i, v in enumerate(s): + c += 1 if v == '1' else -1 + if c in d: r = max(r, i - d[c]) + else: d[c] = i + return r +""" + +examples = """ +solution("0") == 0 +solution("01") == 2 +solution("111") == 0 +solution("1100") == 4 +solution("11010") == 4 +solution("101010") == 6 +""" + +[[input_signature]] +argument_name = "s" +[input_signature.type] +name = "string" + +[output_signature.type] +name = "integer" + +[[asserts]] +arguments = [""] +comment = "Empty string case" +expected = 0 + +[[asserts]] +arguments = ["0"] +comment = "Single character zero" +expected = 0 + +[[asserts]] +arguments = ["1"] +comment = "Single character one" +expected = 0 + +[[asserts]] +arguments = ["01"] +comment = "Smallest balanced segment" +expected = 2 + +[[asserts]] +arguments = ["10"] +comment = "Smallest balanced reversed" +expected = 2 + +[[asserts]] +arguments = ["000"] +comment = "Multiple zeros, no balance" +expected = 0 + +[[asserts]] +arguments = ["111"] +comment = "Multiple ones, no balance" +expected = 0 + +[[asserts]] +arguments = ["001"] +comment = "Balanced part at the end" +expected = 2 + +[[asserts]] +arguments = ["110"] +comment = "Balanced part at the end with one" +expected = 2 + +[[asserts]] +arguments = ["100"] +comment = "Balanced part at the start" +expected = 2 + +[[asserts]] +arguments = ["011"] +comment = "Balanced part at the start with zero" +expected = 2 + +[[asserts]] +arguments = ["0011"] +comment = "Fully balanced symmetric" +expected = 4 + +[[asserts]] +arguments = ["1100"] +comment = "Fully balanced symmetric reversed" +expected = 4 + +[[asserts]] +arguments = ["0101"] +comment = "Alternating fully balanced" +expected = 4 + +[[asserts]] +arguments = ["1010"] +comment = "Alternating fully balanced starting with one" +expected = 4 + +[[asserts]] +arguments = ["000111"] +comment = "Longer fully balanced symmetric" +expected = 6 + +[[asserts]] +arguments = ["111000"] +comment = "Longer fully balanced symmetric reversed" +expected = 6 + +[[asserts]] +arguments = ["11010"] +comment = "Balanced segment within unbalanced string" +expected = 4 + +[[asserts]] +arguments = ["10101"] +comment = "Alternating with trailing extra char" +expected = 4 + +[[asserts]] +arguments = ["001100"] +comment = "Balanced segment embedded in zeros" +expected = 4 + +[[asserts]] +arguments = ["01110"] +comment = "Short balanced segments at edges" +expected = 2 + +[[asserts]] +arguments = ["00001"] +comment = "Large imbalance, small result" +expected = 2 + +[[asserts]] +arguments = ["11110"] +comment = "Large imbalance with ones" +expected = 2 + +[[asserts]] +arguments = ["00011"] +comment = "Imbalanced prefix" +expected = 4 + +[[asserts]] +arguments = ["11100"] +comment = "Imbalanced prefix with ones" +expected = 4 + +[[asserts]] +arguments = ["010101"] +comment = "Long alternating balanced" +expected = 6 + +[[asserts]] +arguments = ["101010"] +comment = "Long alternating balanced starting with one" +expected = 6 + +[[asserts]] +arguments = ["0000111"] +comment = "Large imbalance at start" +expected = 6 + +[[asserts]] +arguments = ["1111000"] +comment = "Large imbalance at start with ones" +expected = 6 + +[[asserts]] +arguments = ["01101100"] +comment = "Full string is balanced with internal patterns" +expected = 8 diff --git a/tasks/easy/strings/longest_common_prefix.toml b/tasks/easy/strings/longest_common_prefix.toml new file mode 100644 index 0000000..75b3119 --- /dev/null +++ b/tasks/easy/strings/longest_common_prefix.toml @@ -0,0 +1,187 @@ +base_score = 100 +level = "easy" +name = "longest_common_prefix" +tags = ["strings", "arrays"] +time_to_solve_sec = 250 + +description_en = """ +Write a function to find the longest common prefix string amongst an array of strings. + +If there is no common prefix, return an empty string `""`. +""" + +description_ru = """ +Напишите функцию для поиска самого длинного общего префикса среди массива строк. + +Если общего префикса нет, верните пустую строку `""`. +""" + +limits = """ +- $1 \\leq \\text{len}(\\text{strs}) \\leq 200$ +- $0 \\leq \\text{len}(\\text{strs}[i]) \\leq 200$ +""" + +solution = """ +def solution(strs: list[str]) -> str: + res = "" + for chars in zip(*strs): + if len(set(chars)) != 1: break + res += chars[0] + return res +""" + +examples = """ +solution(["a"]) == "a" +solution(["dog", "racecar", "car"]) == "" +solution(["flower", "flow", "flight"]) == "fl" +""" + +[[input_signature]] +argument_name = "strs" +[input_signature.type] +name = "array" +[input_signature.type.nested] +name = "string" + +[output_signature.type] +name = "string" + +[[asserts]] +arguments = [["flower", "flow", "flight"]] +comment = "Standard case with a common prefix" +expected = "fl" + +[[asserts]] +arguments = [["dog", "racecar", "car"]] +comment = "No common prefix" +expected = "" + +[[asserts]] +arguments = [["a"]] +comment = "Single string" +expected = "a" + +[[asserts]] +arguments = [[""]] +comment = "Single empty string" +expected = "" + +[[asserts]] +arguments = [["", "b"]] +comment = "First string is empty" +expected = "" + +[[asserts]] +arguments = [["a", ""]] +comment = "Last string is empty" +expected = "" + +[[asserts]] +arguments = [["ab", "a"]] +comment = "Longest prefix is the entire second string" +expected = "a" + +[[asserts]] +arguments = [["a", "ab"]] +comment = "Longest prefix is the entire first string" +expected = "a" + +[[asserts]] +arguments = [["abc", "abc", "abc"]] +comment = "All strings are identical" +expected = "abc" + +[[asserts]] +arguments = [["abc", "abcd", "abcde"]] +comment = "Strings in increasing length" +expected = "abc" + +[[asserts]] +arguments = [["abcde", "abcd", "abc"]] +comment = "Strings in decreasing length" +expected = "abc" + +[[asserts]] +arguments = [["ab", "a", "abc"]] +comment = "Shortest string is in the middle" +expected = "a" + +[[asserts]] +arguments = [["inters", "interstellar", "internet", "internal"]] +comment = "Long prefix" +expected = "inter" + +[[asserts]] +arguments = [["throne", "throne"]] +comment = "Two identical strings" +expected = "throne" + +[[asserts]] +arguments = [["throne", "dungeon"]] +comment = "Two completely different strings" +expected = "" + +[[asserts]] +arguments = [["prefix", "prefixes", "preform"]] +comment = "Prefix variation" +expected = "pref" + +[[asserts]] +arguments = [["apple", "ape", "april"]] +comment = "Common starting letters" +expected = "ap" + +[[asserts]] +arguments = [["car", "cir"]] +comment = "Single common character" +expected = "c" + +[[asserts]] +arguments = [["c", "c"]] +comment = "Identical single characters" +expected = "c" + +[[asserts]] +arguments = [["c", "d"]] +comment = "Different single characters" +expected = "" + +[[asserts]] +arguments = [["alone", "aloof", "albatross"]] +comment = "Common start" +expected = "al" + +[[asserts]] +arguments = [["zebra", "z", "zephyr"]] +comment = "Single character bounds the prefix" +expected = "z" + +[[asserts]] +arguments = [["same", "same", "same", "same", "same"]] +comment = "Many identical strings" +expected = "same" + +[[asserts]] +arguments = [["a", "a", "b"]] +comment = "One string breaks the prefix at the end" +expected = "" + +[[asserts]] +arguments = [["abcdefgh", "abcdefghij", "abcdefghijk", "abcdefghijkl"]] +comment = "Increasing length with long common prefix" +expected = "abcdefgh" + +[[asserts]] +arguments = [["x", "x", "x", "y"]] +comment = "Break at last string single character" +expected = "" + +[[asserts]] +arguments = [["hello", "helloworld", "hell"]] +comment = "Substring in middle" +expected = "hell" + +[[asserts]] +arguments = [["python", "pyramid", "pyrite", "pyre"]] +comment = "Another normal case" +expected = "py" diff --git a/tasks/easy/strings/string_blocks_transposition.toml b/tasks/easy/strings/string_blocks_transposition.toml new file mode 100644 index 0000000..1cb79c4 --- /dev/null +++ b/tasks/easy/strings/string_blocks_transposition.toml @@ -0,0 +1,205 @@ +base_score = 100 +level = "easy" +name = "string_blocks_transposition" +tags = ["strings", "formatting"] +time_to_solve_sec = 200 + +description_en = """ +You are given a string `s` and an integer `k`. + +If the length of the string `s` is not divisible by `k`, return an empty string `""`. +Otherwise, split the string into blocks of length `k`. Construct and return a new string by taking the first character from each block, then the second character from each block, and so on, up to the `k`-th character. +""" + +description_ru = """ +Дана строка `s` и целое число `k`. + +Если длина строки `s` не делится на `k`, верните пустую строку `""`. +В противном случае разбейте строку на блоки длины `k`. Сформируйте и верните новую строку, беря сначала первый символ из каждого блока, затем второй символ из каждого блока, и так далее, вплоть до `k`-го символа. +""" + +limits = """ +- $0 \\leq \\text{len}(s) \\leq 100$ +- $1 \\leq k \\leq 100$ +""" + +solution = """ +def solution(s: str, k: int) -> str: + if len(s) % k != 0: + return "" + return "".join(s[i::k] for i in range(k)) +""" + +examples = """ +solution("abc", 2) == "" +solution("abcdef", 2) == "acebdf" +solution("abcdef", 3) == "adbecf" +""" + +[[input_signature]] +argument_name = "s" +[input_signature.type] +name = "string" + +[[input_signature]] +argument_name = "k" +[input_signature.type] +name = "integer" + +[output_signature.type] +name = "string" + +[[asserts]] +arguments = ["abcdef", 2] +comment = "Even length, divided into blocks of 2" +expected = "acebdf" + +[[asserts]] +arguments = ["abcdef", 3] +comment = "Length 6, divided into blocks of 3" +expected = "adbecf" + +[[asserts]] +arguments = ["abc", 2] +comment = "Length not divisible by k" +expected = "" + +[[asserts]] +arguments = ["abcdef", 1] +comment = "k equals 1" +expected = "abcdef" + +[[asserts]] +arguments = ["abcdef", 6] +comment = "k equals string length" +expected = "abcdef" + +[[asserts]] +arguments = ["abcdef", 4] +comment = "Length not divisible by 4" +expected = "" + +[[asserts]] +arguments = ["", 1] +comment = "Empty string" +expected = "" + +[[asserts]] +arguments = ["", 5] +comment = "Empty string with larger k" +expected = "" + +[[asserts]] +arguments = ["a", 1] +comment = "Single character string" +expected = "a" + +[[asserts]] +arguments = ["ab", 1] +comment = "Length 2, k=1" +expected = "ab" + +[[asserts]] +arguments = ["ab", 2] +comment = "Length 2, k=2" +expected = "ab" + +[[asserts]] +arguments = ["hello", 5] +comment = "String length equals k" +expected = "hello" + +[[asserts]] +arguments = ["hello", 2] +comment = "Length 5, k=2 (not divisible)" +expected = "" + +[[asserts]] +arguments = ["helloworld", 2] +comment = "Longer string, k=2" +expected = "hloolelwrd" + +[[asserts]] +arguments = ["123456789", 3] +comment = "Numeric string, blocks of 3" +expected = "147258369" + +[[asserts]] +arguments = ["1234567890", 5] +comment = "Numeric string, blocks of 5" +expected = "1627384950" + +[[asserts]] +arguments = ["aabbcc", 2] +comment = "Pairs of characters, k=2" +expected = "abcabc" + +[[asserts]] +arguments = ["ababab", 2] +comment = "Repeating pattern, k=2" +expected = "aaabbb" + +[[asserts]] +arguments = ["abcdefgh", 4] +comment = "Length 8, blocks of 4" +expected = "aebfcgdh" + +[[asserts]] +arguments = ["abcdefgh", 8] +comment = "Length 8, k=8" +expected = "abcdefgh" + +[[asserts]] +arguments = ["x", 5] +comment = "Length 1, k=5 (not divisible)" +expected = "" + +[[asserts]] +arguments = ["xxxxxxxx", 2] +comment = "Homogeneous string" +expected = "xxxxxxxx" + +[[asserts]] +arguments = ["python", 2] +comment = "Length 6, k=2" +expected = "ptoyhn" + +[[asserts]] +arguments = ["python", 3] +comment = "Length 6, k=3" +expected = "phyotn" + +[[asserts]] +arguments = ["programming", 1] +comment = "Length 11, k=1" +expected = "programming" + +[[asserts]] +arguments = ["programming", 2] +comment = "Length 11, k=2 (not divisible)" +expected = "" + +[[asserts]] +arguments = ["coder", 5] +comment = "Length 5, k=5" +expected = "coder" + +[[asserts]] +arguments = ["xyzxyzxyz", 3] +comment = "Repeating pattern, k=3" +expected = "xxxyyyzzz" + +[[asserts]] +arguments = ["ABCDEFGHIJKLMNOPQRST", 4] +comment = "Length 20, k=4" +expected = "AEIMQBFJNRCGKOSDHLPT" + +[[asserts]] +arguments = ["abcabcabc", 3] +comment = "Repeating triplets, k=3" +expected = "aaabbbccc" + +[[asserts]] +arguments = ["12345678", 2] +comment = "Sequence of 8 numbers, k=2" +expected = "13572468" diff --git a/tasks/elementary/math/sum_of_two_equals_third.toml b/tasks/elementary/math/sum_of_two_equals_third.toml index 2691dd7..f146fac 100644 --- a/tasks/elementary/math/sum_of_two_equals_third.toml +++ b/tasks/elementary/math/sum_of_two_equals_third.toml @@ -1,144 +1,198 @@ -base_score = 100 -level = "easy" +base_score = 30 +level = "elementary" name = "sum_of_two_equals_third" tags = ["math", "collections"] -time_to_solve_sec = 300 +time_to_solve_sec = 60 description_en = """ -Given three integers `nums = [a, b, c]`, determine whether the sum of **two** of them equals the **third**. +Given three integers, determine whether the sum of two of them equals the third one. Return `True` if such a pair exists, otherwise return `False`. """ description_ru = """ -Даны три целых числа `nums = [a, b, c]`. Определите, существует ли пара чисел, сумма которых равна третьему. +Даны три целых числа. Определите, существует ли пара чисел, сумма которых равна третьему. Верните `True`, если такая пара существует, иначе `False`. """ limits = """ -- $-10^6 \\leq a,b,c \\leq 10^6$ +- $-10^9 \\leq x, y, z \\leq 10^9$ """ solution = """ -def solution(nums: list) -> bool: - nums.sort() - return nums[0] + nums[1] == nums[2] +def solution(x: int, y: int, z: int) -> bool: + return x + y == z or x + z == y or y + z == x """ examples = """ -solution([1, 2, 3]) == True -solution([3, 1, 3]) == False -solution([3, 1, 2]) == True +solution(3, 1, 2) == True +solution(2, 3, 4) == False +solution(-7, -2, 5) == True """ [[input_signature]] -argument_name = "nums" +argument_name = "x" +[input_signature.type] +name = "integer" + +[[input_signature]] +argument_name = "y" +[input_signature.type] +name = "integer" + +[[input_signature]] +argument_name = "z" [input_signature.type] -name = "array" -[input_signature.type.nested] name = "integer" [output_signature.type] name = "boolean" [[asserts]] -arguments = [[1, 2, 3]] +arguments = [3, 1, 2] expected = true [[asserts]] -arguments = [[5, 5, 10]] +arguments = [5, 5, 10] expected = true [[asserts]] -arguments = [[3, 7, 10]] +arguments = [3, 7, 10] expected = true [[asserts]] -arguments = [[10, 15, 25]] +arguments = [10, 25, 15] expected = true [[asserts]] -arguments = [[100, 200, 300]] +arguments = [-1, -2, -3] expected = true [[asserts]] -arguments = [[1000, 2000, 3000]] +arguments = [-5, 0, 5] expected = true [[asserts]] -arguments = [[50, 50, 100]] +arguments = [-7, -2, -5] expected = true [[asserts]] -arguments = [[123, 456, 579]] +arguments = [-7, -2, 5] expected = true [[asserts]] -arguments = [[1, 999, 1000]] +arguments = [-9, -7, -2] expected = true [[asserts]] -arguments = [[50000, 50000, 100000]] +arguments = [-7, -10, 3] expected = true +[[asserts]] +arguments = [8, -3, 5] +expected = true [[asserts]] -arguments = [[50571, 33109, 83680]] +arguments = [-4, -6, -10] expected = true [[asserts]] -arguments = [[1, 1, 3]] -expected = false +arguments = [0, 0, 0] +expected = true [[asserts]] -arguments = [[2, 2, 5]] +arguments = [11, 0, 11] +expected = true + +[[asserts]] +arguments = [-23, -23, 0] +expected = true + +[[asserts]] +arguments = [0, 0, 100] expected = false [[asserts]] -arguments = [[10, 20, 40]] +arguments = [-3, 8, -5] expected = false [[asserts]] -arguments = [[100, 200, 400]] +arguments = [-10, 15, 5] +expected = true + +[[asserts]] +arguments = [-2, 7, 9] +expected = true + +[[asserts]] +arguments = [10, -15, -5] +expected = true + +[[asserts]] +arguments = [20, -30, -10] +expected = true + +[[asserts]] +arguments = [-5, 3, -2] +expected = true + +[[asserts]] +arguments = [7, -12, -5] +expected = true + +[[asserts]] +arguments = [1, 1, 3] expected = false [[asserts]] -arguments = [[1000, 2000, 4000]] +arguments = [2, 2, 5] expected = false [[asserts]] -arguments = [[5000, 5000, 11000]] +arguments = [10, 20, 40] expected = false [[asserts]] -arguments = [[999, 999, 1999]] +arguments = [5372, 4396, 7179] expected = false [[asserts]] -arguments = [[5372, 4396, 7179]] +arguments = [58611, 74697, 89900] expected = false [[asserts]] -arguments = [[58611, 74697, 89900]] +arguments = [1, 2, 4] expected = false [[asserts]] -arguments = [[1, 2, 4]] +arguments = [7, 8, 16] expected = false [[asserts]] -arguments = [[7, 8, 16]] +arguments = [99, 100, 200] expected = false [[asserts]] -arguments = [[99, 100, 200]] +arguments = [1, 1, 1] expected = false [[asserts]] -arguments = [[1, 1, 1]] +arguments = [10000, 19999, 10000] expected = false [[asserts]] -arguments = [[10000, 10000, 19999]] +arguments = [500000000, 500000000, 1000000000] +expected = true + +[[asserts]] +arguments = [-500000000, -1000000000, -500000000] +expected = true + +[[asserts]] +arguments = [0, -1000000000, 1000000000] +expected = true + +[[asserts]] +arguments = [1000000000, 1, -1000000000] expected = false diff --git a/tasks/medium/algo/insert_interval.toml b/tasks/medium/algo/insert_interval.toml new file mode 100644 index 0000000..0ab4398 --- /dev/null +++ b/tasks/medium/algo/insert_interval.toml @@ -0,0 +1,241 @@ +base_score = 150 +level = "medium" +name = "insert_interval" +tags = ["algo", "intervals", "sorting"] +time_to_solve_sec = 400 + +description_en = """ +You are given an array of non-overlapping `intervals` where $\\text{intervals}[i] = [start_i, end_i]$ represent the start and the end of the $i$-th interval. The array `intervals` is sorted in ascending order by $start_i$. + +You are also given an array $\\text{new\\_interval} = [start, end]$ that represents the start and end of another interval. + +Insert $\\text{new\\_interval}$ into `intervals` such that `intervals` is still sorted in ascending order by $start_i$ and `intervals` still does not have any overlapping intervals (merge overlapping intervals if necessary). + +Return `intervals` after the insertion. + +Intervals include both endpoints, so intervals sharing an endpoint overlap. +""" + +description_ru = """ +Вам дан массив непересекающихся интервалов `intervals`, где $\\text{intervals}[i] = [start_i, end_i]$ представляют начало и конец $i$-го интервала. Массив `intervals` отсортирован по возрастанию $start_i$. + +Вам также дан массив $\\text{new\\_interval} = [start, end]$, который представляет собой начало и конец другого интервала. + +Вставьте $\\text{new\\_interval}$ в `intervals` так, чтобы `intervals` оставался отсортированным по возрастанию $start_i$ и не содержал пересекающихся интервалов (при необходимости объедините пересекающиеся интервалы). + +Верните `intervals` после вставки. + +Интервалы включают оба конца, поэтому интервалы с общей конечной точкой пересекаются. +""" + +limits = """ +- $0 \\leq \\text{len}(\\text{intervals}) \\leq 10^4$ +- $\\text{len}(\\text{intervals}[i]) == 2$ +- $\\text{len}(\\text{new\\_interval}) == 2$ +- $0 \\leq \\text{start}_i \\leq \\text{end}_i \\leq 10^5$ +- $0 \\leq \\text{new\\_interval}[0] \\leq \\text{new\\_interval}[1] \\leq 10^5$ +""" + +solution = """ +def solution(intervals: list[list[int]], new_interval: list[int]) -> list[list[int]]: + res = [] + i = 0 + n = len(intervals) + + while i < n and intervals[i][1] < new_interval[0]: + res.append(intervals[i]) + i += 1 + + start, end = new_interval[0], new_interval[1] + while i < n and intervals[i][0] <= end: + start = min(start, intervals[i][0]) + end = max(end, intervals[i][1]) + i += 1 + res.append([start, end]) + + while i < n: + res.append(intervals[i]) + i += 1 + + return res +""" + +examples = """ +solution([], [5, 7]) == [[5, 7]] +solution([[1, 5]], [2, 3]) == [[1, 5]] +solution([[1, 3], [6, 9]], [2, 5]) == [[1, 5], [6, 9]] +solution([[1, 2], [3, 5], [6, 7], [8, 10], [12, 16]], [4, 8]) == [[1, 2], [3, 10], [12, 16]] +""" + +[[input_signature]] +argument_name = "intervals" +[input_signature.type] +name = "array" +[input_signature.type.nested] +name = "array" +[input_signature.type.nested.nested] +name = "integer" + +[[input_signature]] +argument_name = "new_interval" +[input_signature.type] +name = "array" +[input_signature.type.nested] +name = "integer" + +[output_signature.type] +name = "array" +[output_signature.type.nested] +name = "array" +[output_signature.type.nested.nested] +name = "integer" + +[[asserts]] +arguments = [[], [5, 7]] +comment = "Empty intervals" +expected = [[5, 7]] + +[[asserts]] +arguments = [[[1, 3], [6, 9]], [2, 5]] +comment = "Merge with first interval" +expected = [[1, 5], [6, 9]] + +[[asserts]] +arguments = [[[1, 2], [3, 5], [6, 7], [8, 10], [12, 16]], [4, 8]] +comment = "Merge multiple intervals" +expected = [[1, 2], [3, 10], [12, 16]] + +[[asserts]] +arguments = [[[1, 5]], [2, 3]] +comment = "New interval completely inside" +expected = [[1, 5]] + +[[asserts]] +arguments = [[[1, 5]], [0, 6]] +comment = "New interval covers all" +expected = [[0, 6]] + +[[asserts]] +arguments = [[[1, 5]], [6, 8]] +comment = "Insert at the end without merge" +expected = [[1, 5], [6, 8]] + +[[asserts]] +arguments = [[[3, 5]], [1, 2]] +comment = "Insert at the beginning without merge" +expected = [[1, 2], [3, 5]] + +[[asserts]] +arguments = [[[1, 2], [5, 6]], [3, 4]] +comment = "Insert in the middle without merge" +expected = [[1, 2], [3, 4], [5, 6]] + +[[asserts]] +arguments = [[[1, 2], [5, 6]], [2, 5]] +comment = "Merge exactly touching boundaries" +expected = [[1, 6]] + +[[asserts]] +arguments = [[[1, 2], [3, 4], [5, 6]], [2, 5]] +comment = "Merge touching multiple boundaries" +expected = [[1, 6]] + +[[asserts]] +arguments = [[[1, 5], [6, 9]], [1, 5]] +comment = "Exact duplicate interval" +expected = [[1, 5], [6, 9]] + +[[asserts]] +arguments = [[[1, 5]], [1, 5]] +comment = "Duplicate single interval" +expected = [[1, 5]] + +[[asserts]] +arguments = [[[1, 5], [8, 9]], [5, 8]] +comment = "Bridge two intervals" +expected = [[1, 9]] + +[[asserts]] +arguments = [[[1, 2], [4, 5], [7, 8]], [2, 7]] +comment = "Bridge three intervals exactly" +expected = [[1, 8]] + +[[asserts]] +arguments = [[[1, 2], [3, 4], [5, 6], [7, 8], [9, 10]], [1, 10]] +comment = "Swallow many small intervals" +expected = [[1, 10]] + +[[asserts]] +arguments = [[[2, 3], [5, 6], [8, 9]], [0, 1]] +comment = "Insert completely before all" +expected = [[0, 1], [2, 3], [5, 6], [8, 9]] + +[[asserts]] +arguments = [[[2, 3], [5, 6], [8, 9]], [10, 11]] +comment = "Insert completely after all" +expected = [[2, 3], [5, 6], [8, 9], [10, 11]] + +[[asserts]] +arguments = [[[2, 4], [7, 9]], [4, 7]] +comment = "Exact fill the gap" +expected = [[2, 9]] + +[[asserts]] +arguments = [[[1, 1]], [1, 2]] +comment = "Point interval merged" +expected = [[1, 2]] + +[[asserts]] +arguments = [[[1, 3], [6, 9]], [3, 6]] +comment = "Connect two intervals perfectly" +expected = [[1, 9]] + +[[asserts]] +arguments = [[[0, 0], [2, 2], [4, 4]], [0, 4]] +comment = "Merge multiple points" +expected = [[0, 4]] + +[[asserts]] +arguments = [[[0, 2], [4, 6], [8, 10]], [3, 7]] +comment = "Merge with partial overlaps" +expected = [[0, 2], [3, 7], [8, 10]] + +[[asserts]] +arguments = [[[1, 3], [5, 7], [9, 11]], [4, 8]] +comment = "Merge middle elements" +expected = [[1, 3], [4, 8], [9, 11]] + +[[asserts]] +arguments = [[[1, 100]], [50, 60]] +comment = "New interval is a subsegment" +expected = [[1, 100]] + +[[asserts]] +arguments = [[[10, 20], [30, 40], [50, 60]], [15, 55]] +comment = "Merge all with offsets" +expected = [[10, 60]] + +[[asserts]] +arguments = [[[1, 2], [3, 4], [5, 6]], [3, 3]] +comment = "New interval is a point inside existing" +expected = [[1, 2], [3, 4], [5, 6]] + +[[asserts]] +arguments = [[[1, 2], [4, 5]], [3, 3]] +comment = "New interval is an isolated point" +expected = [[1, 2], [3, 3], [4, 5]] + +[[asserts]] +arguments = [[[1, 5], [10, 15], [20, 25]], [6, 9]] +comment = "Insert large gap without merge" +expected = [[1, 5], [6, 9], [10, 15], [20, 25]] + +[[asserts]] +arguments = [[[1, 5], [10, 15], [20, 25]], [12, 22]] +comment = "Merge last two partially" +expected = [[1, 5], [10, 25]] + +[[asserts]] +arguments = [[[0, 1000]], [0, 1000]] +comment = "Same exact large bounds" +expected = [[0, 1000]] diff --git a/tasks/medium/arrays/valid_sudoku.toml b/tasks/medium/arrays/valid_sudoku.toml new file mode 100644 index 0000000..099d1f8 --- /dev/null +++ b/tasks/medium/arrays/valid_sudoku.toml @@ -0,0 +1,2869 @@ +base_score = 150 +level = "medium" +name = "valid_sudoku" +tags = ["arrays", "matrix", "hash"] +time_to_solve_sec = 450 + +description_en = """ +Determine if a $9 \\times 9$ Sudoku board is valid. Only the filled cells need to be validated according to the following rules: + +1. Each row must contain the digits `"1"`-`"9"` without repetition. +2. Each column must contain the digits `"1"`-`"9"` without repetition. +3. Each of the nine $3 \\times 3$ sub-boxes of the grid must contain the digits `"1"`-`"9"` without repetition. + +The Sudoku board could be partially filled, where empty cells are filled with the character `"."`. +""" + +description_ru = """ +Определите, является ли поле для судоку $9 \\times 9$ валидным. Только заполненные ячейки необходимо проверять в соответствии со следующими правилами: + +1. Каждая строка должна содержать цифры от `"1"` до `"9"` без повторений. +2. Каждый столбец должен содержать цифры от `"1"` до `"9"` без повторений. +3. Каждый из девяти подквадратов $3 \\times 3$ должен содержать цифры от `"1"` до `"9"` без повторений. + +Поле судоку может быть частично заполнено, пустые ячейки обозначаются символом `"."`. +""" + +limits = """ +- $\\text{len}(\\text{board}) = 9$ +- $\\text{len}(\\text{board}[i]) = 9$ +- $\\text{board}[i][j] \\in \\{"1", \\dots, "9", "."\\}$ +""" + +solution = """ +def solution(board: list) -> bool: + r = [set() for _ in range(9)] + c = [set() for _ in range(9)] + b = [set() for _ in range(9)] + + for i in range(9): + for j in range(9): + v = board[i][j] + if v != ".": + k = (i // 3) * 3 + j // 3 + if v in r[i] or v in c[j] or v in b[k]: + return False + r[i].add(v) + c[j].add(v) + b[k].add(v) + return True +""" + +examples = """ +solution([ + ["5","3",".",".","7",".",".",".","."], + ["6",".",".","1","9","5",".",".","."], + [".","9","8",".",".",".",".","6","."], + ["8",".",".",".","6",".",".",".","3"], + ["4",".",".","8",".","3",".",".","1"], + ["7",".",".",".","2",".",".",".","6"], + [".","6",".",".",".",".","2","8","."], + [".",".",".","4","1","9",".",".","5"], + [".",".",".",".","8",".",".","7","9"] +]) == True +solution([ + ["8","3",".",".","7",".",".",".","."], + ["6",".",".","1","9","5",".",".","."], + [".","9","8",".",".",".",".","6","."], + ["8",".",".",".","6",".",".",".","3"], + ["4",".",".","8",".","3",".",".","1"], + ["7",".",".",".","2",".",".",".","6"], + [".","6",".",".",".",".","2","8","."], + [".",".",".","4","1","9",".",".","5"], + [".",".",".",".","8",".",".","7","9"] +]) == False +""" + +[[input_signature]] +argument_name = "board" +[input_signature.type] +name = "array" +[input_signature.type.nested] +name = "array" +[input_signature.type.nested.nested] +name = "string" + +[output_signature.type] +name = "boolean" + +[[asserts]] +arguments = [ + [ + [ + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ], + [ + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ], + [ + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ], + [ + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ], + [ + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ], + [ + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ], + [ + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ], + [ + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ], + [ + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ], + ], +] +comment = "Completely empty board" +expected = true + +[[asserts]] +arguments = [ + [ + [ + "5", + "3", + ".", + ".", + "7", + ".", + ".", + ".", + ".", + ], + [ + "6", + ".", + ".", + "1", + "9", + "5", + ".", + ".", + ".", + ], + [ + ".", + "9", + "8", + ".", + ".", + ".", + ".", + "6", + ".", + ], + [ + "8", + ".", + ".", + ".", + "6", + ".", + ".", + ".", + "3", + ], + [ + "4", + ".", + ".", + "8", + ".", + "3", + ".", + ".", + "1", + ], + [ + "7", + ".", + ".", + ".", + "2", + ".", + ".", + ".", + "6", + ], + [ + ".", + "6", + ".", + ".", + ".", + ".", + "2", + "8", + ".", + ], + [ + ".", + ".", + ".", + "4", + "1", + "9", + ".", + ".", + "5", + ], + [ + ".", + ".", + ".", + ".", + "8", + ".", + ".", + "7", + "9", + ], + ], +] +comment = "Valid partial board" +expected = true + +[[asserts]] +arguments = [ + [ + [ + "8", + "3", + ".", + ".", + "7", + ".", + ".", + ".", + ".", + ], + [ + "6", + ".", + ".", + "1", + "9", + "5", + ".", + ".", + ".", + ], + [ + ".", + "9", + "8", + ".", + ".", + ".", + ".", + "6", + ".", + ], + [ + "8", + ".", + ".", + ".", + "6", + ".", + ".", + ".", + "3", + ], + [ + "4", + ".", + ".", + "8", + ".", + "3", + ".", + ".", + "1", + ], + [ + "7", + ".", + ".", + ".", + "2", + ".", + ".", + ".", + "6", + ], + [ + ".", + "6", + ".", + ".", + ".", + ".", + "2", + "8", + ".", + ], + [ + ".", + ".", + ".", + "4", + "1", + "9", + ".", + ".", + "5", + ], + [ + ".", + ".", + ".", + ".", + "8", + ".", + ".", + "7", + "9", + ], + ], +] +comment = "Invalid partial board (two '8's in first column)" +expected = false + +[[asserts]] +arguments = [ + [ + [ + "1", + "2", + "3", + "4", + "5", + "6", + "7", + "8", + "9", + ], + [ + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ], + [ + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ], + [ + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ], + [ + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ], + [ + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ], + [ + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ], + [ + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ], + [ + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ], + ], +] +comment = "Valid single row" +expected = true + +[[asserts]] +arguments = [ + [ + [ + "1", + "2", + "3", + "4", + "5", + "6", + "7", + "8", + "1", + ], + [ + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ], + [ + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ], + [ + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ], + [ + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ], + [ + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ], + [ + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ], + [ + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ], + [ + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ], + ], +] +comment = "Invalid single row (duplicate '1')" +expected = false + +[[asserts]] +arguments = [ + [ + [ + "1", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ], + [ + "2", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ], + [ + "3", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ], + [ + "4", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ], + [ + "5", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ], + [ + "6", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ], + [ + "7", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ], + [ + "8", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ], + [ + "9", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ], + ], +] +comment = "Valid single column" +expected = true + +[[asserts]] +arguments = [ + [ + [ + "1", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ], + [ + "2", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ], + [ + "3", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ], + [ + "4", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ], + [ + "5", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ], + [ + "6", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ], + [ + "7", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ], + [ + "8", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ], + [ + "1", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ], + ], +] +comment = "Invalid single column (duplicate '1')" +expected = false + +[[asserts]] +arguments = [ + [ + [ + "1", + "2", + "3", + ".", + ".", + ".", + ".", + ".", + ".", + ], + [ + "4", + "5", + "6", + ".", + ".", + ".", + ".", + ".", + ".", + ], + [ + "7", + "8", + "9", + ".", + ".", + ".", + ".", + ".", + ".", + ], + [ + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ], + [ + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ], + [ + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ], + [ + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ], + [ + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ], + [ + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ], + ], +] +comment = "Valid single box" +expected = true + +[[asserts]] +arguments = [ + [ + [ + "1", + "2", + "3", + ".", + ".", + ".", + ".", + ".", + ".", + ], + [ + "4", + "5", + "6", + ".", + ".", + ".", + ".", + ".", + ".", + ], + [ + "7", + "8", + "1", + ".", + ".", + ".", + ".", + ".", + ".", + ], + [ + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ], + [ + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ], + [ + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ], + [ + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ], + [ + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ], + [ + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ], + ], +] +comment = "Invalid single box (duplicate '1')" +expected = false + +[[asserts]] +arguments = [ + [ + [ + "5", + "3", + "4", + "6", + "7", + "8", + "9", + "1", + "2", + ], + [ + "6", + "7", + "2", + "1", + "9", + "5", + "3", + "4", + "8", + ], + [ + "1", + "9", + "8", + "3", + "4", + "2", + "5", + "6", + "7", + ], + [ + "8", + "5", + "9", + "7", + "6", + "1", + "4", + "2", + "3", + ], + [ + "4", + "2", + "6", + "8", + "5", + "3", + "7", + "9", + "1", + ], + [ + "7", + "1", + "3", + "9", + "2", + "4", + "8", + "5", + "6", + ], + [ + "9", + "6", + "1", + "5", + "3", + "7", + "2", + "8", + "4", + ], + [ + "2", + "8", + "7", + "4", + "1", + "9", + "6", + "3", + "5", + ], + [ + "3", + "4", + "5", + "2", + "8", + "6", + "1", + "7", + "9", + ], + ], +] +comment = "Fully solved valid board" +expected = true + +[[asserts]] +arguments = [ + [ + [ + "5", + "3", + "4", + "6", + "7", + "8", + "9", + "1", + "2", + ], + [ + "6", + "7", + "2", + "1", + "9", + "5", + "3", + "4", + "8", + ], + [ + "1", + "9", + "8", + "3", + "4", + "2", + "5", + "6", + "7", + ], + [ + "8", + "5", + "9", + "7", + "6", + "1", + "4", + "2", + "3", + ], + [ + "4", + "2", + "6", + "8", + "5", + "3", + "7", + "9", + "1", + ], + [ + "7", + "1", + "3", + "9", + "2", + "4", + "8", + "5", + "6", + ], + [ + "9", + "6", + "1", + "5", + "3", + "7", + "2", + "8", + "4", + ], + [ + "2", + "8", + "7", + "4", + "1", + "9", + "6", + "3", + "5", + ], + [ + "3", + "4", + "5", + "2", + "8", + "6", + "1", + "7", + "3", + ], + ], +] +comment = "Invalid fully filled board (duplicate '3' in bottom right)" +expected = false + +[[asserts]] +arguments = [ + [ + [ + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ], + [ + ".", + "1", + ".", + ".", + ".", + ".", + ".", + "2", + ".", + ], + [ + ".", + ".", + ".", + ".", + "3", + ".", + ".", + ".", + ".", + ], + [ + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ], + [ + ".", + ".", + "4", + ".", + ".", + ".", + "5", + ".", + ".", + ], + [ + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ], + [ + ".", + ".", + ".", + ".", + "6", + ".", + ".", + ".", + ".", + ], + [ + ".", + "7", + ".", + ".", + ".", + ".", + ".", + "8", + ".", + ], + [ + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ], + ], +] +comment = "Valid sparse board" +expected = true + +[[asserts]] +arguments = [ + [ + [ + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ], + [ + ".", + "1", + ".", + ".", + ".", + ".", + ".", + "2", + ".", + ], + [ + ".", + ".", + ".", + ".", + "3", + ".", + ".", + ".", + ".", + ], + [ + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ], + [ + ".", + ".", + "4", + ".", + ".", + ".", + "5", + ".", + ".", + ], + [ + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ], + [ + ".", + ".", + ".", + ".", + "6", + ".", + ".", + ".", + ".", + ], + [ + ".", + "1", + ".", + ".", + ".", + ".", + ".", + "8", + ".", + ], + [ + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ], + ], +] +comment = "Invalid sparse board (duplicate '1' in column 1)" +expected = false + +[[asserts]] +arguments = [ + [ + [ + "9", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + "9", + ], + [ + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ], + [ + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ], + [ + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ], + [ + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ], + [ + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ], + [ + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ], + [ + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ], + [ + "9", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + "9", + ], + ], +] +comment = "9 in all corners (invalid due to row/col sharing)" +expected = false + +[[asserts]] +arguments = [ + [ + [ + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + "9", + ], + [ + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ], + [ + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ], + [ + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ], + [ + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ], + [ + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ], + [ + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ], + [ + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ], + [ + "9", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ], + ], +] +comment = "Two 9s in different corners (valid)" +expected = true + +[[asserts]] +arguments = [ + [ + [ + "1", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ], + [ + ".", + "2", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ], + [ + ".", + ".", + "3", + ".", + ".", + ".", + ".", + ".", + ".", + ], + [ + ".", + ".", + ".", + "4", + ".", + ".", + ".", + ".", + ".", + ], + [ + ".", + ".", + ".", + ".", + "5", + ".", + ".", + ".", + ".", + ], + [ + ".", + ".", + ".", + ".", + ".", + "6", + ".", + ".", + ".", + ], + [ + ".", + ".", + ".", + ".", + ".", + ".", + "7", + ".", + ".", + ], + [ + ".", + ".", + ".", + ".", + ".", + ".", + ".", + "8", + ".", + ], + [ + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + "9", + ], + ], +] +comment = "Valid main diagonal" +expected = true + +[[asserts]] +arguments = [ + [ + [ + "1", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ], + [ + ".", + "2", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ], + [ + ".", + ".", + "1", + ".", + ".", + ".", + ".", + ".", + ".", + ], + [ + ".", + ".", + ".", + "4", + ".", + ".", + ".", + ".", + ".", + ], + [ + ".", + ".", + ".", + ".", + "5", + ".", + ".", + ".", + ".", + ], + [ + ".", + ".", + ".", + ".", + ".", + "6", + ".", + ".", + ".", + ], + [ + ".", + ".", + ".", + ".", + ".", + ".", + "7", + ".", + ".", + ], + [ + ".", + ".", + ".", + ".", + ".", + ".", + ".", + "8", + ".", + ], + [ + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + "9", + ], + ], +] +comment = "Invalid diagonal (top-left box has duplicate '1')" +expected = false + +[[asserts]] +arguments = [ + [ + [ + ".", + ".", + ".", + ".", + ".", + ".", + "1", + "2", + "3", + ], + [ + ".", + ".", + ".", + ".", + ".", + ".", + "4", + "5", + "6", + ], + [ + ".", + ".", + ".", + ".", + ".", + ".", + "7", + "8", + "9", + ], + [ + "1", + "2", + "3", + ".", + ".", + ".", + ".", + ".", + ".", + ], + [ + "4", + "5", + "6", + ".", + ".", + ".", + ".", + ".", + ".", + ], + [ + "7", + "8", + "9", + ".", + ".", + ".", + ".", + ".", + ".", + ], + [ + ".", + ".", + ".", + "1", + "2", + "3", + ".", + ".", + ".", + ], + [ + ".", + ".", + ".", + "4", + "5", + "6", + ".", + ".", + ".", + ], + [ + ".", + ".", + ".", + "7", + "8", + "9", + ".", + ".", + ".", + ], + ], +] +comment = "Valid blocks staggered across grid" +expected = true + +[[asserts]] +arguments = [ + [ + [ + ".", + ".", + ".", + ".", + ".", + ".", + "1", + "2", + "3", + ], + [ + ".", + ".", + ".", + ".", + ".", + ".", + "4", + "5", + "6", + ], + [ + ".", + ".", + ".", + ".", + ".", + ".", + "7", + "8", + "9", + ], + [ + "1", + "2", + "3", + ".", + ".", + ".", + ".", + ".", + ".", + ], + [ + "4", + "5", + "6", + ".", + ".", + ".", + ".", + ".", + ".", + ], + [ + "7", + "8", + "9", + ".", + ".", + ".", + ".", + ".", + ".", + ], + [ + ".", + ".", + ".", + "1", + "2", + "3", + ".", + ".", + ".", + ], + [ + ".", + ".", + ".", + "4", + "5", + "6", + ".", + ".", + ".", + ], + [ + ".", + ".", + ".", + "7", + "8", + "1", + ".", + ".", + ".", + ], + ], +] +comment = "Invalid staggered blocks (duplicate '1' in bottom-middle box)" +expected = false + +[[asserts]] +arguments = [ + [ + [ + ".", + ".", + "4", + ".", + ".", + ".", + "6", + "3", + ".", + ], + [ + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ], + [ + "5", + ".", + ".", + ".", + ".", + "9", + ".", + ".", + ".", + ], + [ + ".", + ".", + ".", + "5", + "6", + ".", + ".", + ".", + ".", + ], + [ + "4", + ".", + "3", + ".", + ".", + ".", + ".", + ".", + "1", + ], + [ + ".", + ".", + ".", + "7", + ".", + ".", + ".", + ".", + ".", + ], + [ + ".", + ".", + ".", + "5", + ".", + ".", + ".", + ".", + ".", + ], + [ + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ], + [ + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ], + ], +] +comment = "Invalid due to two 5s in the middle column (col 3)" +expected = false + +[[asserts]] +arguments = [ + [ + [ + ".", + "1", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ], + [ + "1", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ], + [ + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ], + [ + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ], + [ + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ], + [ + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ], + [ + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ], + [ + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ], + [ + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ], + ], +] +comment = "Two identical numbers in the same box, but different row/col" +expected = false + +[[asserts]] +arguments = [ + [ + [ + ".", + ".", + ".", + "1", + ".", + ".", + "1", + ".", + ".", + ], + [ + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ], + [ + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ], + [ + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ], + [ + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ], + [ + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ], + [ + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ], + [ + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ], + [ + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ], + ], +] +comment = "Two identical numbers in the same row, but different box/col" +expected = false + +[[asserts]] +arguments = [ + [ + [ + ".", + ".", + ".", + "1", + ".", + ".", + ".", + ".", + ".", + ], + [ + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ], + [ + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ], + [ + ".", + ".", + ".", + "1", + ".", + ".", + ".", + ".", + ".", + ], + [ + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ], + [ + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ], + [ + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ], + [ + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ], + [ + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ], + ], +] +comment = "Two identical numbers in the same col, but different box/row" +expected = false + +[[asserts]] +arguments = [ + [ + [ + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ], + [ + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ], + [ + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ], + [ + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ], + [ + ".", + ".", + ".", + ".", + "5", + ".", + ".", + ".", + ".", + ], + [ + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ], + [ + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ], + [ + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ], + [ + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ], + ], +] +comment = "Single element is always valid" +expected = true + +[[asserts]] +arguments = [ + [ + [ + "3", + ".", + "6", + "5", + ".", + "8", + "4", + ".", + ".", + ], + [ + "5", + "2", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ], + [ + ".", + "8", + "7", + ".", + ".", + ".", + ".", + "3", + "1", + ], + [ + ".", + ".", + "3", + ".", + "1", + ".", + ".", + "8", + ".", + ], + [ + "9", + ".", + ".", + "8", + "6", + "3", + ".", + ".", + "5", + ], + [ + ".", + "5", + ".", + ".", + "9", + ".", + "6", + ".", + ".", + ], + [ + "1", + "3", + ".", + ".", + ".", + ".", + "2", + "5", + ".", + ], + [ + ".", + ".", + ".", + ".", + ".", + ".", + ".", + "7", + "4", + ], + [ + ".", + ".", + "5", + "2", + ".", + "6", + "3", + ".", + ".", + ], + ], +] +comment = "Complex real valid puzzle" +expected = true + +[[asserts]] +arguments = [ + [ + [ + "3", + ".", + "6", + "5", + ".", + "8", + "4", + ".", + ".", + ], + [ + "5", + "2", + ".", + ".", + ".", + ".", + ".", + ".", + ".", + ], + [ + ".", + "8", + "7", + ".", + ".", + ".", + ".", + "3", + "1", + ], + [ + ".", + ".", + "3", + ".", + "1", + ".", + ".", + "8", + ".", + ], + [ + "9", + ".", + ".", + "8", + "6", + "3", + ".", + ".", + "5", + ], + [ + ".", + "5", + ".", + ".", + "9", + ".", + "6", + ".", + ".", + ], + [ + "1", + "3", + ".", + ".", + ".", + ".", + "2", + "5", + ".", + ], + [ + ".", + ".", + ".", + ".", + ".", + ".", + ".", + "7", + "4", + ], + [ + ".", + ".", + "5", + "2", + ".", + "6", + "3", + ".", + "8", + ], + ], +] +comment = "Complex real valid puzzle" +expected = true diff --git a/tasks/medium/dp/black_mark.toml b/tasks/medium/dp/black_mark.toml index 6f137f8..273f212 100644 --- a/tasks/medium/dp/black_mark.toml +++ b/tasks/medium/dp/black_mark.toml @@ -1,13 +1,26 @@ -base_score = 150 -description_en = "You have a list of $n$ pirates ($n \\leq 20$) and $n$ dangerous tasks. Each pirate has a fear level for each task, given as an $n \\times n$ matrix `fear` where `fear[i][j]` is the fear of pirate $i$ for task $j$. You need to assign each pirate exactly one distinct task so that the total sum of fear levels is minimized. Return the minimal possible total.\n" -description_ru = "У вас есть список из $n$ пиратов ($n \\leq 20$) и $n$ опасных заданий. Каждый пират имеет свой уровень страха перед каждым заданием, заданный матрицей `fear` размером $n \\times n$, где `fear[i][j]` — уровень страха пирата $i$ перед заданием $j$. Необходимо назначить каждому пирату ровно одно уникальное задание так, чтобы суммарный уровень страха был минимальным. Верните минимально возможную сумму.\n" -examples = "solution([[5]]) == 5\nsolution([[1,2],[3,4]]) == 5\nsolution([[10,1],[1,10]]) == 2\n" -level = "medium" +base_score = 150 +level = "medium" +name = "black_mark" +tags = ["dp", "algo", "scheduling"] +time_to_solve_sec = 400 + +description_en = """ +You have a list of $n$ pirates ($n \\leq 20$) and $n$ dangerous tasks. Each pirate has a fear level for each task, given as an $n \\times n$ matrix `fear` where `fear[i][j]` is the fear of pirate $i$ for task $j$. + +You have to assign each pirate exactly one distinct task so that the total sum of fear levels is minimized. Return the minimal possible total. +""" + +description_ru = """ +У вас есть список из $n$ пиратов ($n \\leq 20$) и $n$ опасных заданий. Каждый пират имеет свой уровень страха перед каждым заданием, заданный матрицей `fear` размером $n \\times n$, где `fear[i][j]` — уровень страха пирата $i$ перед заданием $j$. + +Необходимо назначить каждому пирату ровно одно уникальное задание так, чтобы суммарный уровень страха был минимальным. Верните минимально возможную сумму. +""" + limits = """ - $1 \\leq n \\leq 20$ - $0 \\leq \\text{fear}[i][j] \\leq 1000$ """ -name = "black_mark" + solution = """ def solution(fear: list[list[int]]) -> int: n = len(fear) @@ -22,17 +35,25 @@ def solution(fear: list[list[int]]) -> int: dp[new_mask] = min(dp[new_mask], dp[mask] + fear[i][j]) return dp[(1 << n) - 1] """ -tags = ["dp", "algo", "scheduling"] -time_to_solve_sec = 400 + +examples = """ +solution([[5]]) == 5 +solution([[1, 2], [3, 4]]) == 5 +solution([[10, 1], [1, 10]]) == 2 +""" + [[input_signature]] argument_name = "fear" - [input_signature.type] name = "array" [input_signature.type.nested] name = "array" [input_signature.type.nested.nested] name = "integer" + +[output_signature.type] +name = "integer" + [[asserts]] arguments = [[[5]]] comment = "Test 1" @@ -63,11 +84,6 @@ arguments = [[[979]]] comment = "Test 6" expected = 979 -[[asserts]] -arguments = [[[244]]] -comment = "Test 7" -expected = 244 - [[asserts]] arguments = [ [ @@ -108,37 +124,27 @@ arguments = [ ], ], ] -comment = "Test 8" +comment = "Test 7" expected = 777 -[[asserts]] -arguments = [[[638]]] -comment = "Test 9" -expected = 638 - [[asserts]] arguments = [[[813, 588, 842], [83, 497, 781], [268, 38, 1]]] -comment = "Test 10" +comment = "Test 8" expected = 672 [[asserts]] arguments = [[[332, 971], [155, 405]]] -comment = "Test 11" +comment = "Test 9" expected = 737 -[[asserts]] -arguments = [[[233]]] -comment = "Test 12" -expected = 233 - [[asserts]] arguments = [[[475, 628, 383], [274, 142, 191], [888, 693, 7]]] -comment = "Test 13" +comment = "Test 10" expected = 624 [[asserts]] arguments = [[[586, 34, 440], [495, 592, 16], [212, 474, 833]]] -comment = "Test 14" +comment = "Test 11" expected = 262 [[asserts]] @@ -170,7 +176,7 @@ arguments = [ ], ], ] -comment = "Test 15" +comment = "Test 12" expected = 1749 [[asserts]] @@ -213,17 +219,17 @@ arguments = [ ], ], ] -comment = "Test 16" +comment = "Test 13" expected = 1375 [[asserts]] arguments = [[[266, 298, 702], [932, 701, 822], [870, 912, 191]]] -comment = "Test 17" +comment = "Test 14" expected = 1158 [[asserts]] arguments = [[[110, 631], [720, 774]]] -comment = "Test 18" +comment = "Test 15" expected = 884 [[asserts]] @@ -266,8 +272,5 @@ arguments = [ ], ], ] -comment = "Test 19" +comment = "Test 16" expected = 716 - -[output_signature.type] -name = "integer" diff --git a/tasks/medium/dp/turtle_max_path_sum.toml b/tasks/medium/dp/turtle_max_path_sum.toml new file mode 100644 index 0000000..fd6f358 --- /dev/null +++ b/tasks/medium/dp/turtle_max_path_sum.toml @@ -0,0 +1,180 @@ +base_score = 150 +level = "medium" +name = "turtle_max_path_sum" +tags = ["dp", "matrix", "arrays"] +time_to_solve_sec = 400 + +description_en = """ +You are given an $m \\times n$ matrix of integers. A turtle starts its journey in the top-left corner $(0, 0)$ and wants to reach the bottom-right corner $(m-1, n-1)$. + +The turtle can only move **right** or **down**. + +Return the maximum sum of the elements along its path. +""" + +description_ru = """ +Дана матрица целых чисел размером $m \\times n$. Черепашка начинает свой путь в левом верхнем углу $(0, 0)$ и хочет добраться до правого нижнего угла $(m-1, n-1)$. + +Черепашка может двигаться только **вправо** или **вниз**. + +Верните максимальную сумму элементов на ее пути. +""" + +limits = """ +- $1 \\leq m, n \\leq 100$ +- $-1000 \\leq \\text{matrix}[i][j] \\leq 1000$ +""" + +solution = """ +def solution(matrix: list[list[int]]) -> int: + for i in range(len(matrix)): + for j in range(len(matrix[0])): + if i > 0 and j > 0: matrix[i][j] += max(matrix[i-1][j], matrix[i][j-1]) + elif i > 0: matrix[i][j] += matrix[i-1][j] + elif j > 0: matrix[i][j] += matrix[i][j-1] + return matrix[-1][-1] +""" + +examples = """ +solution([[0]]) == 0 +solution([[1, 2], [3, 4]]) == 8 +solution([[-1, -2], [-3, -4]]) == -7 +solution([[1, 2, 3], [4, 5, 6], [7, 8, 9]]) == 29 +""" + +[[input_signature]] +argument_name = "matrix" +[input_signature.type] +name = "array" +[input_signature.type.nested] +name = "array" +[input_signature.type.nested.nested] +name = "integer" + +[output_signature.type] +name = "integer" + +[[asserts]] +arguments = [[[1]]] +comment = "Single element matrix" +expected = 1 + +[[asserts]] +arguments = [[[0]]] +comment = "Single zero" +expected = 0 + +[[asserts]] +arguments = [[[-5]]] +comment = "Single negative element" +expected = -5 + +[[asserts]] +arguments = [[[1, 2, 3]]] +comment = "Single row" +expected = 6 + +[[asserts]] +arguments = [[[1], [2], [3]]] +comment = "Single column" +expected = 6 + +[[asserts]] +arguments = [[[1, 2], [3, 4]]] +comment = "2x2 positive matrix" +expected = 8 + +[[asserts]] +arguments = [[[-1, -2], [-3, -4]]] +comment = "2x2 negative matrix" +expected = -7 + +[[asserts]] +arguments = [[[0, 0], [0, 0]]] +comment = "2x2 zero matrix" +expected = 0 + +[[asserts]] +arguments = [[[1, 2, 3], [4, 5, 6], [7, 8, 9]]] +comment = "3x3 sequential numbers" +expected = 29 + +[[asserts]] +arguments = [[[-1, -2, -3], [-4, -5, -6], [-7, -8, -9]]] +comment = "3x3 sequential negative numbers" +expected = -21 + +[[asserts]] +arguments = [[[5, 5, 5], [1, 1, 5], [1, 1, 5]]] +comment = "Path along the right edge is optimal" +expected = 25 + +[[asserts]] +arguments = [[[1, 5, 1], [1, 5, 1], [1, 5, 1]]] +comment = "Path down the middle" +expected = 17 + +[[asserts]] +arguments = [[[9, 9, 9], [1, 1, 9], [1, 1, 9]]] +comment = "Path making an L-shape" +expected = 45 + +[[asserts]] +arguments = [[[1, 1, 1], [9, 9, 1], [1, 9, 9]]] +comment = "Optimal path zigzags" +expected = 37 + +[[asserts]] +arguments = [[[100, -100, -100], [-100, 100, -100], [-100, -100, 100]]] +comment = "Diagonal positive numbers surrounded by negative" +expected = 100 + +[[asserts]] +arguments = [[[1, -1, 1], [-1, 1, -1], [1, -1, 1]]] +comment = "Alternating 1s and -1s" +expected = 1 + +[[asserts]] +arguments = [[[0, 10, 0], [0, 10, 0], [0, 10, 0]]] +comment = "Straight vertical high values" +expected = 30 + +[[asserts]] +arguments = [[[10, 0, 0], [0, 10, 0], [0, 0, 10]]] +comment = "Diagonal values" +expected = 30 + +[[asserts]] +arguments = [[[1, 1, 1, 1], [1, 1, 1, 1]]] +comment = "Uniform 2x4 matrix" +expected = 5 + +[[asserts]] +arguments = [[[2, 2, 2, 2], [2, 2, 2, 2], [2, 2, 2, 2]]] +comment = "Uniform 3x4 matrix" +expected = 12 + +[[asserts]] +arguments = [[[1, 2], [3, 4], [5, 6], [7, 8]]] +comment = "Narrow 4x2 matrix" +expected = 24 + +[[asserts]] +arguments = [[[1, 3, 5, 7], [2, 4, 6, 8]]] +comment = "Wide 2x4 matrix" +expected = 24 + +[[asserts]] +arguments = [[[1, 2, 3, 4, 5]]] +comment = "1x5 matrix" +expected = 15 + +[[asserts]] +arguments = [[[5], [4], [3], [2], [1]]] +comment = "5x1 matrix" +expected = 15 + +[[asserts]] +arguments = [[[0, -1, -2], [-3, -4, -5], [-6, -7, -8]]] +comment = "Negative sequence starting with zero" +expected = -16 diff --git a/tasks/medium/games/feeding_kraken.toml b/tasks/medium/games/feeding_kraken.toml index ae578a6..490f972 100644 --- a/tasks/medium/games/feeding_kraken.toml +++ b/tasks/medium/games/feeding_kraken.toml @@ -6,10 +6,14 @@ time_to_solve_sec = 300 description_en = """ You and the Kraken take turns taking gold coins from three piles containing `a`, `b`, and `c` coins. On each turn, a player may take any positive number of coins from exactly one pile. The player who takes the last coin survives. Determine whether you can win if both players play optimally and you move first. + +If all piles are empty, return `False`. """ description_ru = """ Вы и Кракен по очереди берете золотые монеты из трех кучек, в которых лежат `a`, `b` и `c` монет. За один ход можно взять любое положительное количество монет ровно из одной кучки. Тот, кто заберет последнюю монету, выживает. Определите, сможете ли вы победить, если оба игрока играют оптимально и вы ходите первым. + +Если все кучки пусты, верните `False`. """ limits = """ @@ -18,12 +22,12 @@ limits = """ solution = """ def solution(a: int, b: int, c: int) -> bool: - return (a ^ b ^ c) != 0 + return a ^ b ^ c != 0 """ examples = """ -solution(0, 0, 0) == False solution(1, 0, 0) == True +solution(0, 0, 0) == False solution(1, 1, 0) == False solution(1, 2, 3) == False """ @@ -195,3 +199,8 @@ expected = true arguments = [50, 7, 7] comment = "Test 30" expected = true + +[[asserts]] +arguments = [0, 0, 0] +comment = "Empty position is losing" +expected = false diff --git a/tasks/medium/games/game_of_life_step.toml b/tasks/medium/games/game_of_life_step.toml new file mode 100644 index 0000000..a5e5782 --- /dev/null +++ b/tasks/medium/games/game_of_life_step.toml @@ -0,0 +1,363 @@ +base_score = 150 +level = "medium" +name = "game_of_life_step" +tags = ["games", "simulation", "algorithms"] +time_to_solve_sec = 450 + +description_en = """ +You are given a 2D integer array `grid` representing the current state of a grid in Conway's Game of Life. `1` represents a live cell and `0` represents a dead cell. + +Calculate and return the next state of the grid after exactly one step. + +The rules are: +1. A live cell with fewer than `2` live neighbors dies (underpopulation). +2. A live cell with `2` or `3` live neighbors lives on. +3. A live cell with more than `3` live neighbors dies (overpopulation). +4. A dead cell with exactly `3` live neighbors becomes a live cell (reproduction). + +Neighbors are the 8 cells horizontally, vertically, or diagonally adjacent. + +Update all cells simultaneously. Cells outside the grid are dead; the grid does not wrap around. +""" + +description_ru = """ +Вам дан двумерный массив целых чисел `grid`, представляющий текущее состояние сетки в «Игре Жизнь» Конвея, где `1` представляет живую клетку, а `0` — мертвую. + +Рассчитайте и верните следующее состояние сетки ровно через один шаг. + +Правила: +1. Живая клетка, у которой меньше `2` живых соседей, умирает (от недонаселения). +2. Живая клетка с `2` или `3` живыми соседями продолжает жить. +3. Живая клетка, у которой больше `3` живых соседей, умирает (от перенаселения). +4. Мертвая клетка, у которой ровно `3` живых соседа, становится живой (размножение). + +Соседями считаются 8 клеток по горизонтали, вертикали и диагонали. + +Все клетки обновляются одновременно. Клетки за границей поля мертвы; противоположные края поля не соединены. +""" + +limits = """ +- $1 \\leq \\text{len}(grid) \\leq 50$ +- $1 \\leq \\text{len}(grid[0]) \\leq 50$ +- $grid[i][j] \\in \\{0, 1\\}$ +""" + +solution = """ +def solution(grid: list) -> list: + m, n = len(grid), len(grid[0]) + res = [[0] * n for _ in range(m)] + for i in range(m): + for j in range(n): + lives = sum(grid[r][c] for r in range(max(0, i-1), min(m, i+2)) + for c in range(max(0, j-1), min(n, j+2))) - grid[i][j] + if grid[i][j] == 1 and lives in (2, 3): + res[i][j] = 1 + if grid[i][j] == 0 and lives == 3: + res[i][j] = 1 + return res +""" + +examples = """ +solution([[1]]) == [[0]] +solution([[1, 1], [1, 1]]) == [[1, 1], [1, 1]] +solution([[0, 1, 0], [0, 1, 0], [0, 1, 0]]) == [[0, 0, 0], [1, 1, 1], [0, 0, 0]] +""" + +[[input_signature]] +argument_name = "grid" +[input_signature.type] +name = "array" +[input_signature.type.nested] +name = "array" +[input_signature.type.nested.nested] +name = "integer" + +[output_signature.type] +name = "array" +[output_signature.type.nested] +name = "array" +[output_signature.type.nested.nested] +name = "integer" + +[[asserts]] +arguments = [[[0]]] +comment = "1x1 dead" +expected = [[0]] + +[[asserts]] +arguments = [[[1]]] +comment = "1x1 live" +expected = [[0]] + +[[asserts]] +arguments = [[[0, 0]]] +comment = "1x2 dead" +expected = [[0, 0]] + +[[asserts]] +arguments = [[[1, 1]]] +comment = "1x2 live" +expected = [[0, 0]] + +[[asserts]] +arguments = [[[1], [1]]] +comment = "2x1 live" +expected = [[0], [0]] + +[[asserts]] +arguments = [[[0, 0], [0, 0]]] +comment = "2x2 dead" +expected = [[0, 0], [0, 0]] + +[[asserts]] +arguments = [[[1, 1], [1, 1]]] +comment = "2x2 block (Still life)" +expected = [[1, 1], [1, 1]] + +[[asserts]] +arguments = [[[1, 0], [0, 0]]] +comment = "2x2 single live" +expected = [[0, 0], [0, 0]] + +[[asserts]] +arguments = [[[1, 1], [0, 0]]] +comment = "2x2 two live" +expected = [[0, 0], [0, 0]] + +[[asserts]] +arguments = [[[1, 1], [1, 0]]] +comment = "2x2 three live (creates block)" +expected = [[1, 1], [1, 1]] + +[[asserts]] +arguments = [[[0, 0, 0], [0, 0, 0], [0, 0, 0]]] +comment = "3x3 dead" +expected = [[0, 0, 0], [0, 0, 0], [0, 0, 0]] + +[[asserts]] +arguments = [[[0, 0, 0], [0, 1, 0], [0, 0, 0]]] +comment = "3x3 center live" +expected = [[0, 0, 0], [0, 0, 0], [0, 0, 0]] + +[[asserts]] +arguments = [[[0, 0, 0], [1, 1, 1], [0, 0, 0]]] +comment = "3x3 blinker horizontal (Oscillator)" +expected = [[0, 1, 0], [0, 1, 0], [0, 1, 0]] + +[[asserts]] +arguments = [[[0, 1, 0], [0, 1, 0], [0, 1, 0]]] +comment = "3x3 blinker vertical (Oscillator)" +expected = [[0, 0, 0], [1, 1, 1], [0, 0, 0]] + +[[asserts]] +arguments = [[[0, 1, 0], [1, 0, 1], [0, 1, 0]]] +comment = "3x3 tub (Still life)" +expected = [[0, 1, 0], [1, 0, 1], [0, 1, 0]] + +[[asserts]] +arguments = [[[1, 1, 1], [1, 1, 1], [1, 1, 1]]] +comment = "3x3 all live" +expected = [[1, 0, 1], [0, 0, 0], [1, 0, 1]] + +[[asserts]] +arguments = [[[0, 1, 0], [1, 1, 1], [0, 1, 0]]] +comment = "3x3 cross" +expected = [[1, 1, 1], [1, 0, 1], [1, 1, 1]] + +[[asserts]] +arguments = [[[1, 0, 0], [1, 1, 0], [0, 0, 0]]] +comment = "3x3 L-shape" +expected = [[1, 1, 0], [1, 1, 0], [0, 0, 0]] + +[[asserts]] +arguments = [[[0, 0, 0, 0], [0, 1, 1, 0], [0, 1, 1, 0], [0, 0, 0, 0]]] +comment = "4x4 block in center" +expected = [[0, 0, 0, 0], [0, 1, 1, 0], [0, 1, 1, 0], [0, 0, 0, 0]] + +[[asserts]] +arguments = [[[0, 0, 0, 0], [0, 1, 1, 1], [1, 1, 1, 0], [0, 0, 0, 0]]] +comment = "4x4 toad phase 1 (Oscillator)" +expected = [[0, 0, 1, 0], [1, 0, 0, 1], [1, 0, 0, 1], [0, 1, 0, 0]] + +[[asserts]] +arguments = [[[0, 0, 1, 0], [1, 0, 0, 1], [1, 0, 0, 1], [0, 1, 0, 0]]] +comment = "4x4 toad phase 2 (Oscillator)" +expected = [[0, 0, 0, 0], [0, 1, 1, 1], [1, 1, 1, 0], [0, 0, 0, 0]] + +[[asserts]] +arguments = [[[1, 1, 0, 0], [1, 1, 0, 0], [0, 0, 1, 1], [0, 0, 1, 1]]] +comment = "4x4 beacon (Oscillator)" +expected = [[1, 1, 0, 0], [1, 0, 0, 0], [0, 0, 0, 1], [0, 0, 1, 1]] + +[[asserts]] +arguments = [[[1, 1, 1, 1], [1, 1, 1, 1], [1, 1, 1, 1], [1, 1, 1, 1]]] +comment = "4x4 all live" +expected = [[1, 0, 0, 1], [0, 0, 0, 0], [0, 0, 0, 0], [1, 0, 0, 1]] + +[[asserts]] +arguments = [[[0, 1, 0], [0, 0, 1], [1, 1, 1], [0, 0, 0]]] +comment = "4x3 glider step 1" +expected = [[0, 0, 0], [1, 0, 1], [0, 1, 1], [0, 1, 0]] + +[[asserts]] +arguments = [[[0, 0, 0, 0], [1, 1, 1, 1], [0, 0, 0, 0]]] +comment = "3x4 horizontal line" +expected = [[0, 1, 1, 0], [0, 1, 1, 0], [0, 1, 1, 0]] + +[[asserts]] +arguments = [ + [ + [ + 0, + 0, + 0, + 0, + 0, + ], + [ + 0, + 1, + 1, + 1, + 0, + ], + [ + 0, + 1, + 1, + 1, + 0, + ], + [ + 0, + 1, + 1, + 1, + 0, + ], + [ + 0, + 0, + 0, + 0, + 0, + ], + ], +] +comment = "5x5 3x3 square in center" +expected = [ + [ + 0, + 0, + 1, + 0, + 0, + ], + [ + 0, + 1, + 0, + 1, + 0, + ], + [ + 1, + 0, + 0, + 0, + 1, + ], + [ + 0, + 1, + 0, + 1, + 0, + ], + [ + 0, + 0, + 1, + 0, + 0, + ], +] + +[[asserts]] +arguments = [ + [ + [ + 0, + 0, + 0, + 0, + 0, + ], + [ + 0, + 0, + 0, + 0, + 0, + ], + [ + 0, + 0, + 0, + 0, + 0, + ], + [ + 0, + 0, + 0, + 0, + 0, + ], + [ + 0, + 0, + 0, + 0, + 0, + ], + ], +] +comment = "5x5 completely empty" +expected = [ + [ + 0, + 0, + 0, + 0, + 0, + ], + [ + 0, + 0, + 0, + 0, + 0, + ], + [ + 0, + 0, + 0, + 0, + 0, + ], + [ + 0, + 0, + 0, + 0, + 0, + ], + [ + 0, + 0, + 0, + 0, + 0, + ], +] diff --git a/tasks/medium/graphs/flood_fill.toml b/tasks/medium/graphs/flood_fill.toml new file mode 100644 index 0000000..e0853c3 --- /dev/null +++ b/tasks/medium/graphs/flood_fill.toml @@ -0,0 +1,2592 @@ +base_score = 150 +level = "medium" +name = "flood_fill" +tags = ["graphs"] +time_to_solve_sec = 400 + +description_en = """ +An image is represented by a 2D integer array `image`, where `image[i][j]` represents the pixel value of the image. + +You are also given three integers `sr`, `sc`, and `color`. You should perform a flood fill on the image starting from the pixel `image[sr][sc]`. + +To perform a flood fill, consider the starting pixel, plus any pixels connected 4-directionally to the starting pixel of the same color as the starting pixel, plus any pixels connected 4-directionally to those pixels (also with the same color), and so on. Replace the color of all of the aforementioned pixels with `color`. + +Return the modified image after performing the flood fill. +""" + +description_ru = """ +Изображение представлено в виде двумерного массива целых чисел `image`, где `image[i][j]` — это значение пикселя. + +Вам также даны три целых числа: `sr`, `sc` и `color`. Вы должны выполнить заливку (flood fill) изображения, начиная с пикселя `image[sr][sc]`. + +Для выполнения заливки возьмите начальный пиксель, а также все соседние по вертикали и горизонтали пиксели того же цвета, что и начальный. Затем возьмите соседние пиксели для добавленных пикселей (также того же цвета), и так далее. Замените цвет всех этих пикселей на новый `color`. + +Верните измененное изображение после выполнения заливки. +""" + +limits = """ +- $1 \\leq \\text{len}(\\text{image}) \\leq 50$ +- $1 \\leq \\text{len}(\\text{image}[0]) \\leq 50$ +- $0 \\leq \\text{image}[i][j], \\text{color} \\leq 100$ +- $0 \\leq \\text{sr} < \\text{len}(\\text{image})$ +- $0 \\leq \\text{sc} < \\text{len}(\\text{image}[0])$ +""" + +solution = """ +def solution(image: list[list[int]], sr: int, sc: int, color: int) -> list[list[int]]: + old = image[sr][sc] + stack = [(sr, sc)] + while stack: + r, c = stack.pop() + if old != color and 0 <= r < len(image) and 0 <= c < len(image[0]) and image[r][c] == old: + image[r][c] = color + stack.extend(((r - 1, c), (r + 1, c), (r, c - 1), (r, c + 1))) + return image +""" + +examples = """ +solution([[1]], 0, 0, 2) == [[2]] +solution([[0, 0], [0, 0]], 0, 0, 2) == [[2, 2], [2, 2]] +solution([[1, 1, 1], [1, 1, 0], [1, 0, 1]], 1, 1, 2) == [[2, 2, 2], [2, 2, 0], [2, 0, 1]] +""" + +[[input_signature]] +argument_name = "image" +[input_signature.type] +name = "array" +[input_signature.type.nested] +name = "array" +[input_signature.type.nested.nested] +name = "integer" + +[[input_signature]] +argument_name = "sr" +[input_signature.type] +name = "integer" + +[[input_signature]] +argument_name = "sc" +[input_signature.type] +name = "integer" + +[[input_signature]] +argument_name = "color" +[input_signature.type] +name = "integer" + +[output_signature.type] +name = "array" +[output_signature.type.nested] +name = "array" +[output_signature.type.nested.nested] +name = "integer" + +[[asserts]] +arguments = [[[1]], 0, 0, 2] +comment = "1x1 grid, standard fill" +expected = [[2]] + +[[asserts]] +arguments = [[[2]], 0, 0, 2] +comment = "1x1 grid, same color no change" +expected = [[2]] + +[[asserts]] +arguments = [[[1, 1], [1, 1]], 0, 0, 3] +comment = "2x2 grid, all same color" +expected = [[3, 3], [3, 3]] + +[[asserts]] +arguments = [[[1, 2], [3, 4]], 0, 0, 5] +comment = "2x2 grid, distinct colors, start top-left" +expected = [[5, 2], [3, 4]] + +[[asserts]] +arguments = [[[1, 2], [3, 4]], 1, 1, 5] +comment = "2x2 grid, distinct colors, start bottom-right" +expected = [[1, 2], [3, 5]] + +[[asserts]] +arguments = [[[1, 1, 1], [1, 1, 0], [1, 0, 1]], 1, 1, 2] +comment = "Classic connected component shape" +expected = [[2, 2, 2], [2, 2, 0], [2, 0, 1]] + +[[asserts]] +arguments = [[[0, 0, 0], [0, 0, 0]], 0, 0, 0] +comment = "Grid already the target color" +expected = [[0, 0, 0], [0, 0, 0]] + +[[asserts]] +arguments = [[[1, 2, 1], [2, 1, 2], [1, 2, 1]], 1, 1, 3] +comment = "Checkerboard, isolated center" +expected = [[1, 2, 1], [2, 3, 2], [1, 2, 1]] + +[[asserts]] +arguments = [[[1, 2, 1], [2, 1, 2], [1, 2, 1]], 0, 0, 3] +comment = "Checkerboard, isolated corner" +expected = [[3, 2, 1], [2, 1, 2], [1, 2, 1]] + +[[asserts]] +arguments = [[[1, 1, 1], [2, 2, 2], [1, 1, 1]], 1, 1, 3] +comment = "Horizontal stripe" +expected = [[1, 1, 1], [3, 3, 3], [1, 1, 1]] + +[[asserts]] +arguments = [[[1, 2, 1], [1, 2, 1], [1, 2, 1]], 1, 1, 3] +comment = "Vertical stripe" +expected = [[1, 3, 1], [1, 3, 1], [1, 3, 1]] + +[[asserts]] +arguments = [[[0, 0, 0], [0, 1, 0], [0, 0, 0]], 1, 1, 2] +comment = "Single central pixel different from background" +expected = [[0, 0, 0], [0, 2, 0], [0, 0, 0]] + +[[asserts]] +arguments = [[[0, 0, 0], [0, 1, 0], [0, 0, 0]], 0, 0, 2] +comment = "Surrounding background avoiding center" +expected = [[2, 2, 2], [2, 1, 2], [2, 2, 2]] + +[[asserts]] +arguments = [[[1, 0, 0], [0, 1, 0], [0, 0, 1]], 0, 0, 2] +comment = "Diagonal connection (does not spread)" +expected = [[2, 0, 0], [0, 1, 0], [0, 0, 1]] + +[[asserts]] +arguments = [[[1, 1, 1, 1]], 0, 2, 5] +comment = "1D horizontal row" +expected = [[5, 5, 5, 5]] + +[[asserts]] +arguments = [[[1], [1], [1], [1]], 2, 0, 5] +comment = "1D vertical column" +expected = [[5], [5], [5], [5]] + +[[asserts]] +arguments = [[[1, 1, 1], [1, 0, 1], [1, 1, 1]], 0, 0, 2] +comment = "Ring shape, fill outside" +expected = [[2, 2, 2], [2, 0, 2], [2, 2, 2]] + +[[asserts]] +arguments = [[[1, 1, 1], [1, 0, 1], [1, 1, 1]], 1, 1, 2] +comment = "Ring shape, fill inside" +expected = [[1, 1, 1], [1, 2, 1], [1, 1, 1]] + +[[asserts]] +arguments = [[[0, 1, 0], [1, 0, 1], [0, 1, 0]], 1, 1, 2] +comment = "Hollow cross, fill center" +expected = [[0, 1, 0], [1, 2, 1], [0, 1, 0]] + +[[asserts]] +arguments = [[[0, 1, 0], [1, 1, 1], [0, 1, 0]], 1, 1, 2] +comment = "Filled cross, fill cross" +expected = [[0, 2, 0], [2, 2, 2], [0, 2, 0]] + +[[asserts]] +arguments = [[[7, 7, 8], [7, 8, 8], [9, 9, 9]], 0, 0, 1] +comment = "Asymmetric blob shape" +expected = [[1, 1, 8], [1, 8, 8], [9, 9, 9]] + +[[asserts]] +arguments = [[[2, 2, 2, 2], [2, 3, 3, 2], [2, 3, 3, 2], [2, 2, 2, 2]], 1, 1, 4] +comment = "Square inside a square" +expected = [[2, 2, 2, 2], [2, 4, 4, 2], [2, 4, 4, 2], [2, 2, 2, 2]] + +[[asserts]] +arguments = [[[5, 5, 5], [5, 5, 5], [5, 5, 5]], 2, 2, 5] +comment = "3x3 all same, target color is same" +expected = [[5, 5, 5], [5, 5, 5], [5, 5, 5]] + +[[asserts]] +arguments = [[[1, 2, 3], [4, 5, 6], [7, 8, 9]], 2, 2, 0] +comment = "All distinct numbers" +expected = [[1, 2, 3], [4, 5, 6], [7, 8, 0]] + +[[asserts]] +arguments = [[[1, 1], [0, 1]], 1, 1, 3] +comment = "L-shape component" +expected = [[3, 3], [0, 3]] + +[[asserts]] +arguments = [[[0, 1], [1, 1]], 0, 1, 3] +comment = "Reverse L-shape component" +expected = [[0, 3], [3, 3]] + +[[asserts]] +arguments = [[[1, 1], [1, 1], [1, 1]], 0, 0, 2] +comment = "3x2 full block" +expected = [[2, 2], [2, 2], [2, 2]] + +[[asserts]] +arguments = [ + [ + [ + 1, + 1, + 1, + 1, + 1, + ], + [ + 1, + 0, + 0, + 0, + 1, + ], + [ + 1, + 0, + 1, + 0, + 1, + ], + [ + 1, + 0, + 0, + 0, + 1, + ], + [ + 1, + 1, + 1, + 1, + 1, + ], + ], + 2, + 2, + 2, +] +comment = "Nested rings, center isolated pixel" +expected = [ + [ + 1, + 1, + 1, + 1, + 1, + ], + [ + 1, + 0, + 0, + 0, + 1, + ], + [ + 1, + 0, + 2, + 0, + 1, + ], + [ + 1, + 0, + 0, + 0, + 1, + ], + [ + 1, + 1, + 1, + 1, + 1, + ], +] + +[[asserts]] +arguments = [ + [ + [ + 1, + 1, + 1, + 1, + 1, + ], + [ + 1, + 0, + 0, + 0, + 1, + ], + [ + 1, + 0, + 1, + 0, + 1, + ], + [ + 1, + 0, + 0, + 0, + 1, + ], + [ + 1, + 1, + 1, + 1, + 1, + ], + ], + 0, + 0, + 2, +] +comment = "Nested rings, outer boundary" +expected = [ + [ + 2, + 2, + 2, + 2, + 2, + ], + [ + 2, + 0, + 0, + 0, + 2, + ], + [ + 2, + 0, + 1, + 0, + 2, + ], + [ + 2, + 0, + 0, + 0, + 2, + ], + [ + 2, + 2, + 2, + 2, + 2, + ], +] +[[asserts]] +arguments = [ + [ + [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + ], + [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + ], + [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + ], + [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + ], + [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + ], + [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + ], + [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + ], + [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + ], + [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + ], + [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + ], + [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + ], + [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + ], + [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + ], + [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + ], + [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + ], + [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + ], + [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + ], + [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + ], + [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + ], + [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + ], + [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + ], + [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + ], + [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + ], + [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + ], + [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + ], + [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + ], + [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + ], + [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + ], + [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + ], + [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + ], + [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + ], + [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + ], + [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + ], + [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + ], + [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + ], + [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + ], + [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + ], + [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + ], + [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + ], + [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + ], + [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + ], + [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + ], + [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + ], + [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + ], + [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + ], + [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + ], + [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + ], + [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + ], + [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + ], + [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + ], + ], + 0, + 0, + 1, +] +comment = "Large connected region without recursive depth limits" +expected = [ + [ + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + ], + [ + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + ], + [ + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + ], + [ + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + ], + [ + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + ], + [ + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + ], + [ + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + ], + [ + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + ], + [ + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + ], + [ + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + ], + [ + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + ], + [ + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + ], + [ + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + ], + [ + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + ], + [ + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + ], + [ + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + ], + [ + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + ], + [ + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + ], + [ + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + ], + [ + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + ], + [ + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + ], + [ + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + ], + [ + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + ], + [ + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + ], + [ + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + ], + [ + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + ], + [ + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + ], + [ + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + ], + [ + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + ], + [ + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + ], + [ + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + ], + [ + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + ], + [ + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + ], + [ + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + ], + [ + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + ], + [ + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + ], + [ + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + ], + [ + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + ], + [ + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + ], + [ + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + ], + [ + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + ], + [ + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + ], + [ + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + ], + [ + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + ], + [ + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + ], + [ + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + ], + [ + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + ], + [ + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + ], + [ + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + ], + [ + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + ], +] diff --git a/tasks/medium/graphs/topological_sort_possible.toml b/tasks/medium/graphs/topological_sort_possible.toml new file mode 100644 index 0000000..c0ccc7a --- /dev/null +++ b/tasks/medium/graphs/topological_sort_possible.toml @@ -0,0 +1,207 @@ +base_score = 150 +level = "medium" +name = "topological_sort_possible" +tags = ["graphs", "algorithms", "topological_sort"] +time_to_solve_sec = 400 + +description_en = """ +You are given `n` nodes labeled from $0$ to $n - 1$ and a list of directed `edges`. + +Each edge $[u, v]$ indicates that node $u$ must appear before node $v$ in a topological ordering. + +Return `True` if it is possible to topologically sort the graph (i.e., it contains no directed cycles), and `False` otherwise. +""" + +description_ru = """ +Вам дано `n` вершин, пронумерованных от $0$ до $n - 1$, и список ориентированных ребер `edges`. + +Каждое ребро $[u, v]$ означает, что вершина $u$ должна идти перед вершиной $v$ в топологической сортировке. + +Верните `True`, если граф можно отсортировать топологически (то есть в нем нет ориентированных циклов), и `False` в противном случае. +""" + +limits = """ +- $1 \\leq n \\leq 10^4$ +- $0 \\leq \\text{len}(\\text{edges}) \\leq 10^4$ +- $\\text{edges}[i] = [u, v]$ +- $0 \\leq u, v < n$ +""" + +solution = """ +def solution(n: int, edges: list) -> bool: + from graphlib import TopologicalSorter, CycleError + + graph = {i: set() for i in range(n)} + for u, v in edges: + graph[v].add(u) + + try: + TopologicalSorter(graph).prepare() + return True + except CycleError: + return False +""" + +examples = """ +solution(1, []) == True +solution(2, [[0, 1]]) == True +solution(2, [[0, 1], [1, 0]]) == False +solution(4, [[0, 1], [1, 2], [2, 3]]) == True +""" + +[[input_signature]] +argument_name = "n" +[input_signature.type] +name = "integer" + +[[input_signature]] +argument_name = "edges" +[input_signature.type] +name = "array" +[input_signature.type.nested] +name = "array" +[input_signature.type.nested.nested] +name = "integer" + +[output_signature.type] +name = "boolean" + +[[asserts]] +arguments = [1, []] +comment = "Single node without edges" +expected = true + +[[asserts]] +arguments = [2, [[0, 1]]] +comment = "Two nodes, simple directed edge" +expected = true + +[[asserts]] +arguments = [2, [[0, 1], [1, 0]]] +comment = "Two nodes, cycle" +expected = false + +[[asserts]] +arguments = [3, [[0, 1], [1, 2]]] +comment = "Three nodes, straight line" +expected = true + +[[asserts]] +arguments = [3, [[0, 1], [1, 2], [2, 0]]] +comment = "Three nodes, simple cycle" +expected = false + +[[asserts]] +arguments = [4, [[0, 1], [1, 2], [2, 3]]] +comment = "Four nodes, straight line" +expected = true + +[[asserts]] +arguments = [4, [[0, 1], [1, 2], [2, 3], [3, 0]]] +comment = "Four nodes, full cycle" +expected = false + +[[asserts]] +arguments = [4, [[0, 1], [2, 3]]] +comment = "Disconnected components, no cycles" +expected = true + +[[asserts]] +arguments = [5, [[0, 1], [1, 2], [3, 4], [4, 3]]] +comment = "Disconnected components, one has a cycle" +expected = false + +[[asserts]] +arguments = [3, [[0, 1], [0, 2]]] +comment = "Tree pointing outwards" +expected = true + +[[asserts]] +arguments = [3, [[1, 0], [2, 0]]] +comment = "Tree pointing inwards" +expected = true + +[[asserts]] +arguments = [4, [[0, 1], [0, 2], [1, 3], [2, 3]]] +comment = "Diamond shape, acyclic" +expected = true + +[[asserts]] +arguments = [4, [[0, 1], [1, 3], [3, 2], [2, 0]]] +comment = "Cycle of 4 nodes" +expected = false + +[[asserts]] +arguments = [1, [[0, 0]]] +comment = "Self-loop edge" +expected = false + +[[asserts]] +arguments = [5, [[0, 1], [1, 2], [2, 3], [3, 4], [1, 3]]] +comment = "DAG with a forward edge" +expected = true + +[[asserts]] +arguments = [5, [[0, 1], [1, 2], [2, 3], [3, 4], [3, 1]]] +comment = "Line with a back edge (cycle of 3)" +expected = false + +[[asserts]] +arguments = [6, [[0, 1], [1, 2], [3, 4], [4, 5]]] +comment = "Two separate paths" +expected = true + +[[asserts]] +arguments = [6, [[0, 1], [1, 2], [2, 0], [3, 4], [4, 5], [5, 3]]] +comment = "Two separate cyclic components" +expected = false + +[[asserts]] +arguments = [2, [[0, 1], [0, 1]]] +comment = "Duplicate edges, no cycles" +expected = true + +[[asserts]] +arguments = [3, [[0, 1], [1, 2], [2, 0], [0, 1]]] +comment = "Cycle with duplicate edges" +expected = false + +[[asserts]] +arguments = [5, []] +comment = "Multiple nodes with no edges" +expected = true + +[[asserts]] +arguments = [7, [[0, 1], [0, 2], [1, 3], [1, 4], [2, 5], [2, 6]]] +comment = "Binary tree structure" +expected = true + +[[asserts]] +arguments = [7, [[0, 1], [1, 2], [2, 3], [3, 4], [4, 5], [5, 6], [6, 0]]] +comment = "Large cycle of 7 nodes" +expected = false + +[[asserts]] +arguments = [4, [[0, 1], [0, 2], [0, 3], [1, 2], [1, 3], [2, 3]]] +comment = "Complete DAG" +expected = true + +[[asserts]] +arguments = [4, [[0, 1], [1, 2], [2, 3], [3, 1]]] +comment = "Lollipop graph (line going into a cycle)" +expected = false + +[[asserts]] +arguments = [5, [[0, 4], [1, 4], [2, 4], [3, 4]]] +comment = "Star graph directed to center" +expected = true + +[[asserts]] +arguments = [5, [[4, 0], [4, 1], [4, 2], [4, 3]]] +comment = "Star graph directed from center" +expected = true + +[[asserts]] +arguments = [8, [[0, 1], [1, 2], [3, 4], [4, 5], [6, 7], [7, 6]]] +comment = "Large forest with one cycle hidden" +expected = false diff --git a/tasks/medium/regex/log_ip_sanitizer.toml b/tasks/medium/regex/log_ip_sanitizer.toml index 03cf08d..2ad1f7f 100644 --- a/tasks/medium/regex/log_ip_sanitizer.toml +++ b/tasks/medium/regex/log_ip_sanitizer.toml @@ -5,13 +5,14 @@ tags = ["regex", "strings"] time_to_solve_sec = 300 description_en = """ -You're given a log line as a string `s`. +You're given a log line as a string `s`. Replace every **valid** IPv4 address with the exact text `[REDACTED]`. A valid IPv4 is four decimal octets separated by dots: `a.b.c.d`, where each `a..d` is in `0..255`. Leading zeros are allowed (e.g. `001.002.003.004`). An IPv4 must not be part of a longer digit sequence (it's bounded by non-digits or string ends). +Process valid addresses from left to right without overlapping replacements. Return the transformed string. Keep all other characters unchanged. If there are no valid IPv4 addresses, return the original string. @@ -25,6 +26,7 @@ description_ru = """ Ведущие нули разрешены (например, `001.002.003.004`). IPv4 не должен быть частью более длинной цифровой последовательности (он ограничен нецифровыми символами или концами строки). +Обрабатывайте корректные адреса слева направо без пересекающихся замен. Верните преобразованную строку. Все остальные символы должны остаться без изменений. Если корректных IPv4 нет — верните исходную строку. @@ -35,10 +37,10 @@ limits = """ """ examples = """ +solution("256.0.0.1") == "256.0.0.1" solution("no ip here") == "no ip here" solution("255.255.255.255") == "[REDACTED]" solution("ip=1.2.3.4, ok") == "ip=[REDACTED], ok" -solution("256.0.0.1") == "256.0.0.1" solution("1.1.1.1 2.2.2.2") == "[REDACTED] [REDACTED]" """ @@ -46,7 +48,7 @@ solution = """ import re def solution(s: str) -> str: - octet = r'(?:25[0-5]|2[0-4]\\d|[01]?\\d\\d?)' + octet = r'0*(?:25[0-5]|2[0-4][0-9]|1[0-9]{2}|[0-9]{1,2})' ipv4 = rf'(? int: """ examples = """ -solution([2,1,5,6,2,3]) == 10 -solution([2,4]) == 4 -solution([1]) == 1 solution([]) == 0 +solution([1]) == 1 +solution([2, 4]) == 4 +solution([2, 1, 5, 6, 2, 3]) == 10 """ [[input_signature]] diff --git a/tasks/medium/strings/minimum_bracket_reversals.toml b/tasks/medium/strings/minimum_bracket_reversals.toml new file mode 100644 index 0000000..e57b0b4 --- /dev/null +++ b/tasks/medium/strings/minimum_bracket_reversals.toml @@ -0,0 +1,208 @@ +base_score = 150 +level = "medium" +name = "minimum_bracket_reversals" +tags = ["strings", "greedy", "stack"] +time_to_solve_sec = 400 + +description_en = """ +Given a string `s` consisting only of parentheses `(` and `)`, determine the minimum number of parentheses reversals required to make the string balanced. + +A reversal changes `(` to `)` or `)` to `(`. +If it is impossible to balance the string, return `-1`. +""" + +description_ru = """ +Дана строка `s`, состоящая только из круглых скобок `(` и `)`, определите минимальное количество переворотов скобок, необходимое для того, чтобы сделать строку сбалансированной. + +Переворот меняет `(` на `)` или `)` на `(`. +Если сбалансировать строку невозможно, верните `-1`. +""" + +limits = """ +- $0 \\leq \\text{len}(s) \\leq 10^5$ +""" + +solution = """ +def solution(s: str) -> int: + if len(s) % 2 != 0: + return -1 + o = c = 0 + for x in s: + if x == '(': + o += 1 + elif o > 0: + o -= 1 + else: + c += 1 + return (o + 1) // 2 + (c + 1) // 2 +""" + +examples = """ +solution("()") == 0 +solution(")(") == 2 +solution("(((") == -1 +solution(")))(((") == 4 +""" + +[[input_signature]] +argument_name = "s" +[input_signature.type] +name = "string" + +[output_signature.type] +name = "integer" + +[[asserts]] +arguments = [""] +comment = "Empty string" +expected = 0 + +[[asserts]] +arguments = [")("] +comment = "Two reversals needed" +expected = 2 + +[[asserts]] +arguments = ["("] +comment = "Odd length string" +expected = -1 + +[[asserts]] +arguments = [")"] +comment = "Odd length string" +expected = -1 + +[[asserts]] +arguments = ["((("] +comment = "Odd length string with all opens" +expected = -1 + +[[asserts]] +arguments = ["(())"] +comment = "Balanced nested brackets" +expected = 0 + +[[asserts]] +arguments = ["()()"] +comment = "Balanced consecutive brackets" +expected = 0 + +[[asserts]] +arguments = ["(((("] +comment = "All open brackets" +expected = 2 + +[[asserts]] +arguments = ["))))"] +comment = "All close brackets" +expected = 2 + +[[asserts]] +arguments = ["(((())"] +comment = "More open than close" +expected = 1 + +[[asserts]] +arguments = [")))((("] +comment = "Fully inverted" +expected = 4 + +[[asserts]] +arguments = [")))(("] +comment = "Odd length mixed" +expected = -1 + +[[asserts]] +arguments = [")(())((("] +comment = "Complex mixed string" +expected = 3 + +[[asserts]] +arguments = ["()()()()()()()()()()()()"] +comment = "Long balanced string" +expected = 0 + +[[asserts]] +arguments = ["))))))))))))))))))))))))"] +comment = "Long all closing" +expected = 12 + +[[asserts]] +arguments = ["(((((((((((((((((((((((("] +comment = "Long all opening" +expected = 12 + +[[asserts]] +arguments = ["()))(())())(()"] +comment = "Almost balanced" +expected = 3 + +[[asserts]] +arguments = ["))(())(())())(("] +comment = "Repeated inverted pairs" +expected = -1 + +[[asserts]] +arguments = ["(((((((((())))))))))"] +comment = "Deep nesting" +expected = 0 + +[[asserts]] +arguments = ["))))(((("] +comment = "Symmetric inverted" +expected = 4 + +[[asserts]] +arguments = [")(()))"] +comment = "Needs one open flip" +expected = 1 + +[[asserts]] +arguments = ["))))))"] +comment = "Six closing" +expected = 3 + +[[asserts]] +arguments = ["(("] +comment = "Two opening" +expected = 1 + +[[asserts]] +arguments = ["))"] +comment = "Two closing" +expected = 1 + +[[asserts]] +arguments = [")))("] +comment = "Three close one open" +expected = 3 + +[[asserts]] +arguments = [")((("] +comment = "One close three open" +expected = 3 + +[[asserts]] +arguments = ["())))"] +comment = "One open four close" +expected = -1 + +[[asserts]] +arguments = ["(()("] +comment = "Three open one close" +expected = 1 + +[[asserts]] +arguments = [")()("] +comment = "Alternating inverted" +expected = 2 + +[[asserts]] +arguments = ["()()()()()()()()()()()()(("] +comment = "Balanced with two opens at end" +expected = 1 + +[[asserts]] +arguments = ["))()()()()()()()()()()()()"] +comment = "Balanced with two closes at start" +expected = 1 diff --git a/tasks/medium/strings/underscore.toml b/tasks/medium/strings/underscore.toml index ca28a9f..3022796 100644 --- a/tasks/medium/strings/underscore.toml +++ b/tasks/medium/strings/underscore.toml @@ -17,18 +17,17 @@ limits = """ """ solution = """ +import re + def solution(text: str) -> str: - import re - s = text.replace('-', '_') - s = re.sub(r'([a-z\\d])([A-Z])', r'\\1_\\2', s) - s = re.sub(r'([A-Z]+)([A-Z][a-z])', r'\\1_\\2', s) - s = s.replace('::', '/') - return s.lower() + for pattern in [r'([a-z\\d])([A-Z])', '([A-Z]+)([A-Z][a-z])']: + text = re.sub(pattern, r'\\1_\\2', text) + return text.replace('-', '_').replace('::', '/').lower() """ examples = """ -solution("ActiveModel::Errors") == "active_model/errors" solution("HelloHowAreYou") == "hello_how_are_you" +solution("ActiveModel::Errors") == "active_model/errors" solution("MyNAMEIsBOND-JamesBond") == "my_name_is_bond_james_bond" solution("MAINCompany::BEST-MAINUser") == "main_company/best_main_user" """ @@ -165,3 +164,18 @@ expected = "css_style" arguments = ["SQLQuery"] comment = "SQL acronym" expected = "sql_query" + +[[asserts]] +arguments = ["version2Thing"] +comment = "Uppercase word after a digit" +expected = "version2_thing" + +[[asserts]] +arguments = ["HTML5Parser"] +comment = "Uppercase word after a digit" +expected = "html5_parser" + +[[asserts]] +arguments = ["user1ID"] +comment = "Uppercase word after a digit" +expected = "user1_id"