Compare commits
8 Commits
391eaa30a8
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
17d27f0605
|
|||
|
08cfb39ad5
|
|||
|
41727493ea
|
|||
|
edc0354519
|
|||
|
5087b2a308
|
|||
|
a3e6a9be9b
|
|||
|
de9d6b3f96
|
|||
|
bb5c00c528
|
@@ -2,13 +2,38 @@ from collections import deque
|
|||||||
from typing import Iterable
|
from typing import Iterable
|
||||||
from icecream import ic
|
from icecream import ic
|
||||||
|
|
||||||
from math_objects import Operator, Token
|
from math_objects import Operator, Parenthesis, Token
|
||||||
|
|
||||||
|
__left_parenthesis_error = "__left_parenthesis_error"
|
||||||
|
__right_parenthesis_error = "__right_parenthesis_error"
|
||||||
|
__empty_parentheses_error = "__empty_parentheses_error"
|
||||||
|
|
||||||
|
|
||||||
def translate(tokens: Iterable[Token]) -> Iterable[Token]:
|
def translate(tokens: Iterable[Token]) -> Iterable[Token]:
|
||||||
operator_stack: deque[Operator] = deque()
|
operator_stack: deque[Operator] = deque()
|
||||||
|
previous_stacks: deque[deque[Operator]] = deque()
|
||||||
previous_precedence = 0
|
previous_precedence = 0
|
||||||
|
empty_stack = True
|
||||||
|
|
||||||
for token in tokens:
|
for token in tokens:
|
||||||
|
if isinstance(token, Parenthesis):
|
||||||
|
match token.value:
|
||||||
|
case "(":
|
||||||
|
previous_stacks.append(operator_stack)
|
||||||
|
operator_stack = deque()
|
||||||
|
empty_stack = True
|
||||||
|
case _:
|
||||||
|
if empty_stack:
|
||||||
|
raise SystemError(__empty_parentheses_error)
|
||||||
|
if operator_stack:
|
||||||
|
for item in reversed(operator_stack):
|
||||||
|
yield item
|
||||||
|
try:
|
||||||
|
operator_stack = previous_stacks.pop()
|
||||||
|
except IndexError:
|
||||||
|
raise SyntaxError(__right_parenthesis_error)
|
||||||
|
continue
|
||||||
|
empty_stack = False
|
||||||
if not isinstance(token, Operator):
|
if not isinstance(token, Operator):
|
||||||
yield token
|
yield token
|
||||||
continue
|
continue
|
||||||
@@ -18,7 +43,8 @@ def translate(tokens: Iterable[Token]) -> Iterable[Token]:
|
|||||||
operator_stack.clear()
|
operator_stack.clear()
|
||||||
previous_precedence = token.precedence
|
previous_precedence = token.precedence
|
||||||
operator_stack.append(token)
|
operator_stack.append(token)
|
||||||
ic(len(operator_stack))
|
if previous_stacks:
|
||||||
|
raise SyntaxError(__left_parenthesis_error)
|
||||||
if operator_stack:
|
if operator_stack:
|
||||||
for item in reversed(operator_stack):
|
for item in reversed(operator_stack):
|
||||||
yield item
|
yield item
|
||||||
|
|||||||
@@ -7,7 +7,10 @@ from tokenizer import tokenize
|
|||||||
|
|
||||||
from math_objects import Token, Integer, Operator
|
from math_objects import Token, Integer, Operator
|
||||||
|
|
||||||
equation: str = "1+ 2+3/3-1"# input()
|
equation: str = input()
|
||||||
|
|
||||||
|
if not equation.strip():
|
||||||
|
raise SyntaxError("Пустая строка")
|
||||||
|
|
||||||
tokens: Iterable[Token] = tokenize(equation)
|
tokens: Iterable[Token] = tokenize(equation)
|
||||||
sorted_tokens: Iterable[Token] = translate(tokens)
|
sorted_tokens: Iterable[Token] = translate(tokens)
|
||||||
@@ -18,11 +21,12 @@ for token in sorted_tokens:
|
|||||||
if not isinstance(token, Operator):
|
if not isinstance(token, Operator):
|
||||||
token_stack.append(token)
|
token_stack.append(token)
|
||||||
continue
|
continue
|
||||||
|
try:
|
||||||
b, a = token_stack.pop(), token_stack.pop()
|
b, a = token_stack.pop(), token_stack.pop()
|
||||||
|
except IndexError:
|
||||||
|
raise SyntaxError
|
||||||
ic(a.value, token.value, b.value)
|
ic(a.value, token.value, b.value)
|
||||||
new_integer = Integer(eval(f"{a.value}{token.value}{b.value}"))
|
new_integer = Integer(eval(f"{a.value}{token.value}{b.value}"))
|
||||||
token_stack.append(new_integer)
|
token_stack.append(new_integer)
|
||||||
|
|
||||||
ic(len(token_stack))
|
|
||||||
|
|
||||||
print(token_stack.pop().value)
|
print(token_stack.pop().value)
|
||||||
|
|||||||
@@ -6,7 +6,6 @@ from math_objects import Integer, Operator, Parenthesis, Token
|
|||||||
|
|
||||||
def tokenize(string: str) -> Iterable[Token]:
|
def tokenize(string: str) -> Iterable[Token]:
|
||||||
buffer: deque[str] = deque()
|
buffer: deque[str] = deque()
|
||||||
prediction: Optional[Literal["number"]] = None
|
|
||||||
|
|
||||||
def _take_buffer() -> str:
|
def _take_buffer() -> str:
|
||||||
string = "".join(buffer)
|
string = "".join(buffer)
|
||||||
@@ -15,14 +14,10 @@ def tokenize(string: str) -> Iterable[Token]:
|
|||||||
|
|
||||||
for c in string:
|
for c in string:
|
||||||
if c.isdigit():
|
if c.isdigit():
|
||||||
if prediction != "number" and buffer:
|
|
||||||
yield Integer.create_from_string(_take_buffer())
|
|
||||||
prediction = "number"
|
|
||||||
buffer.append(c)
|
buffer.append(c)
|
||||||
elif c in ["+", "-", "*", "/", "(", ")"]:
|
elif c in ["+", "-", "*", "/", "(", ")"]:
|
||||||
if buffer:
|
if buffer:
|
||||||
yield Integer.create_from_string(_take_buffer())
|
yield Integer.create_from_string(_take_buffer())
|
||||||
prediction = None
|
|
||||||
match c:
|
match c:
|
||||||
case "+" | "-":
|
case "+" | "-":
|
||||||
yield Operator(c, precedence=1)
|
yield Operator(c, precedence=1)
|
||||||
@@ -30,10 +25,9 @@ def tokenize(string: str) -> Iterable[Token]:
|
|||||||
yield Operator(c, precedence=2)
|
yield Operator(c, precedence=2)
|
||||||
case _:
|
case _:
|
||||||
yield Parenthesis(c) # type: ignore
|
yield Parenthesis(c) # type: ignore
|
||||||
prediction = None
|
|
||||||
elif c == " ":
|
elif c == " ":
|
||||||
pass
|
pass
|
||||||
else:
|
else:
|
||||||
raise SyntaxError()
|
raise SyntaxError(f"Недопустимый символ: {c}")
|
||||||
if buffer:
|
if buffer:
|
||||||
yield Integer.create_from_string(_take_buffer())
|
yield Integer.create_from_string(_take_buffer())
|
||||||
|
|||||||
21
task6/entities.py
Normal file
21
task6/entities.py
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
from dataclasses import dataclass
|
||||||
|
from typing import Literal
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class Request:
|
||||||
|
request_time: int
|
||||||
|
plane: Plane
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class ProcessedRequest(Request):
|
||||||
|
start_process_time: int
|
||||||
|
process_time: int
|
||||||
|
type_: Literal["landing", "launching"]
|
||||||
|
|
||||||
|
class Plane:
|
||||||
|
__id_increment = 0
|
||||||
|
|
||||||
|
def __init__(self) -> None:
|
||||||
|
self.id = self.__id_increment
|
||||||
|
Plane.__id_increment += 1
|
||||||
100
task6/main.py
Normal file
100
task6/main.py
Normal file
@@ -0,0 +1,100 @@
|
|||||||
|
from stats import Stats, finalize_waiting_stats, show_stats
|
||||||
|
from entities import Plane, ProcessedRequest, Request
|
||||||
|
from queues import EnforcingQueue, PermissiveQueue, Queue
|
||||||
|
|
||||||
|
from numpy import random
|
||||||
|
from typing import Final, Iterable, Optional
|
||||||
|
|
||||||
|
from numpy.typing import NDArray
|
||||||
|
|
||||||
|
|
||||||
|
def warn_about_outcoming_queue_overload(queue: Queue) -> None:
|
||||||
|
print(f"Outcoming queue is overloaded: {len(queue)} planes/{queue.size} planes")
|
||||||
|
|
||||||
|
def reject_plane(plane: Plane) -> None:
|
||||||
|
stats.rejected_in_requests += 1
|
||||||
|
print(f"Rejected incoming plane №{plane.id}")
|
||||||
|
|
||||||
|
def launch_plane(plane: Plane, stats: Stats) -> None:
|
||||||
|
stats.launches_count += 1
|
||||||
|
print(f"Launched plane №{plane.id}")
|
||||||
|
|
||||||
|
def land_plane(plane: Plane, stats: Stats) -> None:
|
||||||
|
stats.landings_count += 1
|
||||||
|
print(f"Plane №{plane.id} landed")
|
||||||
|
|
||||||
|
def generate_timeline(incoming_planes_per_hour: float, outcoming_planes_per_hour: float, interval_minutes: int) -> Iterable[tuple[int, int]]:
|
||||||
|
def _generate(planes_per_hour: float) -> NDArray:
|
||||||
|
return random.poisson(planes_per_hour / 60, interval_minutes)
|
||||||
|
|
||||||
|
incoming_planes_per_minute = _generate(incoming_planes_per_hour)
|
||||||
|
outcoming_planes_per_minute = _generate(outcoming_planes_per_hour)
|
||||||
|
return zip(incoming_planes_per_minute, outcoming_planes_per_minute)
|
||||||
|
|
||||||
|
def process_new_request(in_queue: Queue[Request], out_queue: Queue[Request], current_time: int, process_duration: int) -> ProcessedRequest:
|
||||||
|
plane: Optional[Plane]
|
||||||
|
if in_queue:
|
||||||
|
request = in_queue.pop()
|
||||||
|
plane = request.plane
|
||||||
|
stats.in_waiting_time.append(current_time - request.request_time)
|
||||||
|
print(f"{current_time}: Processing incoming plane №{plane.id}")
|
||||||
|
process_type = "landing"
|
||||||
|
else:
|
||||||
|
request = out_queue.pop()
|
||||||
|
plane = request.plane
|
||||||
|
stats.out_waiting_time.append(current_time - request.request_time)
|
||||||
|
print(f"{current_time}: Processing outcoming plane №{plane.id}")
|
||||||
|
process_type = "launching"
|
||||||
|
return ProcessedRequest(request.request_time, request.plane, current_time, current_time + process_duration, process_type)
|
||||||
|
|
||||||
|
takeoff_duration: Final[int] = int(input("Takeoff duration: ")) # minutes
|
||||||
|
|
||||||
|
max_queue: Final[int] = int(input("Max queue: "))
|
||||||
|
interval: Final[int] = int(input("Interval: ")) # minutes
|
||||||
|
incoming_planes, outcoming_planes = map(float, input("Planes: ").split()) # per hour
|
||||||
|
|
||||||
|
in_queue: Queue[Request] = EnforcingQueue[Request](max_queue)
|
||||||
|
out_queue: Queue[Request] = PermissiveQueue[Request](max_queue, warn_about_outcoming_queue_overload)
|
||||||
|
|
||||||
|
current_request: Optional[ProcessedRequest] = None
|
||||||
|
|
||||||
|
stats = Stats()
|
||||||
|
timeline = generate_timeline(5,2, interval)
|
||||||
|
|
||||||
|
i = 0
|
||||||
|
|
||||||
|
for i, (in_planes_count, out_planes_count) in enumerate(timeline):
|
||||||
|
stats.total_plane_requests += in_planes_count + out_planes_count
|
||||||
|
stats.in_requests += in_planes_count
|
||||||
|
stats.out_requests += out_planes_count
|
||||||
|
|
||||||
|
for _ in range(in_planes_count):
|
||||||
|
new_plane = Plane()
|
||||||
|
try:
|
||||||
|
in_queue.add(Request(i, new_plane))
|
||||||
|
stats.accepted_in_requests += 1
|
||||||
|
except IndexError:
|
||||||
|
reject_plane(new_plane)
|
||||||
|
stats.rejected_in_requests += 1
|
||||||
|
for _ in range(out_planes_count):
|
||||||
|
new_plane = Plane()
|
||||||
|
out_queue.add(Request(i, new_plane))
|
||||||
|
stats.accepted_out_requests += 1
|
||||||
|
|
||||||
|
if not current_request:
|
||||||
|
if len(in_queue) or len(out_queue):
|
||||||
|
current_request = process_new_request(in_queue, out_queue, i, takeoff_duration)
|
||||||
|
continue
|
||||||
|
stats.sleep_minutes += 1
|
||||||
|
if current_request and current_request.process_time == i:
|
||||||
|
if current_request.type_ == "launching":
|
||||||
|
launch_plane(current_request.plane, stats)
|
||||||
|
else:
|
||||||
|
land_plane(current_request.plane, stats)
|
||||||
|
current_request = None
|
||||||
|
|
||||||
|
stats.in_queued = len(in_queue)
|
||||||
|
stats.out_queued = len(out_queue)
|
||||||
|
|
||||||
|
finalize_waiting_stats(stats, in_queue, out_queue, i)
|
||||||
|
show_stats(stats)
|
||||||
50
task6/queues.py
Normal file
50
task6/queues.py
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
from abc import ABC, abstractmethod
|
||||||
|
from collections import deque
|
||||||
|
from typing import Callable, Optional, Self, override
|
||||||
|
|
||||||
|
|
||||||
|
class Queue[T](ABC):
|
||||||
|
def __init__(self, size: int) -> None:
|
||||||
|
self.size = size
|
||||||
|
self.queue: deque[T] = deque()
|
||||||
|
|
||||||
|
def __len__(self) -> int:
|
||||||
|
return len(self.queue)
|
||||||
|
|
||||||
|
def __bool__(self) -> bool:
|
||||||
|
return bool(self.queue)
|
||||||
|
|
||||||
|
@abstractmethod
|
||||||
|
def add(self, item: T) -> None: pass
|
||||||
|
|
||||||
|
@abstractmethod
|
||||||
|
def pop(self) -> T: pass
|
||||||
|
|
||||||
|
class PermissiveQueue[T](Queue):
|
||||||
|
def __init__(self, size: int, overload_function: Optional[Callable[[Self], None]] = None) -> None:
|
||||||
|
super().__init__(size)
|
||||||
|
self._on_overload = overload_function
|
||||||
|
|
||||||
|
@override
|
||||||
|
def add(self, item: T) -> None:
|
||||||
|
self.queue.append(item)
|
||||||
|
if self._on_overload and len(self.queue) > self.size:
|
||||||
|
self._on_overload(self)
|
||||||
|
|
||||||
|
@override
|
||||||
|
def pop(self) -> T:
|
||||||
|
return self.queue.popleft()
|
||||||
|
|
||||||
|
class EnforcingQueue[T](Queue):
|
||||||
|
def __init__(self, size: int) -> None:
|
||||||
|
super().__init__(size)
|
||||||
|
|
||||||
|
@override
|
||||||
|
def add(self, item: T) -> None:
|
||||||
|
if len(self.queue) >= self.size:
|
||||||
|
raise IndexError
|
||||||
|
self.queue.append(item)
|
||||||
|
|
||||||
|
@override
|
||||||
|
def pop(self) -> T:
|
||||||
|
return self.queue.popleft()
|
||||||
53
task6/stats.py
Normal file
53
task6/stats.py
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
from dataclasses import dataclass, field
|
||||||
|
|
||||||
|
from numpy import average
|
||||||
|
|
||||||
|
from entities import Request
|
||||||
|
from queues import Queue
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class Stats:
|
||||||
|
total_plane_requests = 0
|
||||||
|
|
||||||
|
in_requests = 0
|
||||||
|
out_requests = 0
|
||||||
|
|
||||||
|
accepted_in_requests = 0
|
||||||
|
accepted_out_requests = 0
|
||||||
|
|
||||||
|
rejected_in_requests = 0
|
||||||
|
rejected_out_requests = 0
|
||||||
|
|
||||||
|
landings_count = 0
|
||||||
|
launches_count = 0
|
||||||
|
|
||||||
|
in_queued = 0
|
||||||
|
out_queued = 0
|
||||||
|
|
||||||
|
sleep_minutes = 0
|
||||||
|
|
||||||
|
in_waiting_time: list[float] = field(default_factory=list)
|
||||||
|
out_waiting_time: list[float] = field(default_factory=list)
|
||||||
|
|
||||||
|
def show_stats(stats: Stats) -> None:
|
||||||
|
string = f"""============
|
||||||
|
Total requests: {stats.total_plane_requests}
|
||||||
|
In requests: {stats.in_requests}
|
||||||
|
Out requests: {stats.out_requests}
|
||||||
|
Accepted in requests: {stats.accepted_in_requests}
|
||||||
|
Accepted out requests: {stats.accepted_out_requests}
|
||||||
|
Rejected in/out: {stats.rejected_in_requests}/{stats.rejected_out_requests}
|
||||||
|
Landings: {stats.landings_count}
|
||||||
|
Launches: {stats.launches_count}
|
||||||
|
Left in queues (in/out): {stats.in_queued}/{stats.out_queued}
|
||||||
|
Sleep: {stats.sleep_minutes}
|
||||||
|
Average waiting time (in/out): {average(stats.in_waiting_time)}/{average(stats.out_waiting_time)}
|
||||||
|
"""
|
||||||
|
print(string)
|
||||||
|
|
||||||
|
def finalize_waiting_stats(stats: Stats, in_queue: Queue[Request], out_queue: Queue[Request], current_time: int) -> None:
|
||||||
|
for item in in_queue.queue:
|
||||||
|
stats.in_waiting_time.append(current_time - item.request_time)
|
||||||
|
for item in out_queue.queue:
|
||||||
|
stats.out_waiting_time.append(current_time - item.request_time)
|
||||||
40
task7/main.py
Normal file
40
task7/main.py
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
from itertools import combinations, repeat
|
||||||
|
import random
|
||||||
|
from typing import Any, Final, Iterable
|
||||||
|
from collections import Counter
|
||||||
|
|
||||||
|
from icecream import ic
|
||||||
|
|
||||||
|
|
||||||
|
sets_count: Final[int] = random.randint(2, 1000)
|
||||||
|
elements_count: Final[Iterable[int]] = (random.randint(3, 10000) for _ in repeat(None, sets_count))
|
||||||
|
|
||||||
|
ic(sets_count)
|
||||||
|
|
||||||
|
sets: list[set[int]] = [
|
||||||
|
set(
|
||||||
|
random.sample(range(-2_000_000_000, 2_000_000_000 + 1), count)
|
||||||
|
)
|
||||||
|
for count in elements_count
|
||||||
|
]
|
||||||
|
|
||||||
|
elements_to_sets: dict[int, list[int]] = {}
|
||||||
|
pair_counts: Counter[tuple[int, int]] = Counter()
|
||||||
|
|
||||||
|
for i, set_ in enumerate(sets):
|
||||||
|
for element in set_:
|
||||||
|
elements_to_sets.setdefault(element, list()).append(i)
|
||||||
|
|
||||||
|
ic(len(elements_to_sets))
|
||||||
|
|
||||||
|
for sets_ in filter(lambda x: len(x) > 1, elements_to_sets.values()):
|
||||||
|
pair_counts.update(combinations(sets_, 2))
|
||||||
|
|
||||||
|
sets_with_most_intersections: list[tuple[Any, int]] = pair_counts.most_common(1)
|
||||||
|
|
||||||
|
if sets_with_most_intersections:
|
||||||
|
max_intersection: int = sets_with_most_intersections[0][1]
|
||||||
|
else:
|
||||||
|
max_intersection = 0
|
||||||
|
|
||||||
|
print(max_intersection)
|
||||||
36
task7/naive_approach.py
Normal file
36
task7/naive_approach.py
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
from itertools import repeat
|
||||||
|
import random
|
||||||
|
from typing import Final, Iterable
|
||||||
|
|
||||||
|
from icecream import ic
|
||||||
|
|
||||||
|
|
||||||
|
sets_count: Final[int] = random.randint(2, 1000)
|
||||||
|
elements_count: Final[Iterable[int]] = (random.randint(3, 10000) for _ in repeat(None, sets_count))
|
||||||
|
|
||||||
|
ic(sets_count)
|
||||||
|
|
||||||
|
sets: list[set[int]] = [
|
||||||
|
set(
|
||||||
|
random.sample(range(-2_000_000_000, 2_000_000_000 + 1), count)
|
||||||
|
)
|
||||||
|
for count in elements_count
|
||||||
|
]
|
||||||
|
sets.sort(key=lambda x: len(x), reverse=True)
|
||||||
|
ic(list(map(len, sets)))
|
||||||
|
|
||||||
|
max_intersection = 0
|
||||||
|
|
||||||
|
for i in range(len(sets) - 1):
|
||||||
|
if max_intersection >= len(sets[i]):
|
||||||
|
ic(f"break on {i}")
|
||||||
|
break
|
||||||
|
for j in range(i + 1, len(sets)):
|
||||||
|
if max_intersection > len(sets[j]):
|
||||||
|
ic(f"break on {i};{j}")
|
||||||
|
break
|
||||||
|
if (intersection := len(sets[i].intersection(sets[j]))) > max_intersection:
|
||||||
|
max_intersection = intersection
|
||||||
|
ic(max_intersection)
|
||||||
|
|
||||||
|
print(max_intersection)
|
||||||
27
task8/main.py
Normal file
27
task8/main.py
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
from collections import Counter
|
||||||
|
|
||||||
|
from icecream import ic
|
||||||
|
|
||||||
|
|
||||||
|
string: str = input()
|
||||||
|
max_weight = 0
|
||||||
|
|
||||||
|
def calculate_weight(counter: Counter[str], length: int) -> int:
|
||||||
|
max_occurence: int = counter.most_common(1)[0][1]
|
||||||
|
return max_occurence * length
|
||||||
|
|
||||||
|
counter: Counter[str] = Counter()
|
||||||
|
|
||||||
|
for length in range(1, len(string) + 1):
|
||||||
|
counter.clear()
|
||||||
|
counter.update(
|
||||||
|
string[i:i+length] for i in range(len(string) - length + 1)
|
||||||
|
)
|
||||||
|
# ic(counter)
|
||||||
|
max_weight: int = max(
|
||||||
|
max_weight,
|
||||||
|
calculate_weight(counter, length)
|
||||||
|
)
|
||||||
|
ic(max_weight)
|
||||||
|
|
||||||
|
print(max_weight)
|
||||||
Reference in New Issue
Block a user