20240717


gc - Garbage Collector Interface (Python)

Python already has garbage collectors. For example, CPython counts the number of references to a specific memory field, and once the memory is not referenced anymore, the memory will be freed.

If my understanding is correct, I have no idea when and how to use gc module. I can see that my colleagues use it to reduce the memory usage, but I need to check if it's right.

gc - Garbage Collector Interface - Python 3.12.4 Documentation

This module provides an interface to the optional garbage collector. It provides the ability to disable the collector, tune the collection frequency, and set debugging options. It also provides access to unreachable objects that the collector found but cannot free. Since the collector supplements the reference counting already used in Python, you can disable the collector if you are sure your program does not create reference cycles.

gc.collect(generation=2)

With no arguments, run a full collection. The effect of calling gc.collect() while the interpreter is already performing a collection is undefined.

In general, calling gc.collect() is dangerous because CPython's garbage collection is already running, and they would conflict.

However, I found this thread.

Celery doesn't release memory after finishing a task

It's an old thread, but our application seems to face the same issue, running gc.collect() at the end of a task frees huge amount of memory.

So, in our case, calling gc.collect() to free memory used in Celery makes sense.

1992D. Test of Love

greedy approach

I should have noticed that I could check if the person could jump for each position. m is at most 10, so for-looping 10 times for each position does not affect the time complexity. 10 is a constant.

def possible(n: int, m: int, k: int, a: list[str]) -> bool:
    posi: int = -1
    while posi < n:
        if posi >= 0 and a[posi] == "C":
            return False

        elif posi >= 0 and a[posi] == "W":
            posi += 1
            k -= 1

        else:  # posi == -1 or a[posi] == "L"
            # if there is a log in the range, jump to it
            # if there is no log, jump to to the farthest water
            logi: int = -1
            wateri: int = -1
            # at most m = 10, and this loop does not affect the time complexity
            for jumplen in range(1, m + 1):
                if posi + jumplen >= n:
                    logi = n  # goal
                    break

                if a[posi + jumplen] == "L":
                    logi = posi + jumplen
                elif a[posi + jumplen] != "C":
                    wateri = posi + jumplen

            if logi != -1:
                posi = logi
            elif wateri != -1:
                posi = wateri
            else:
                return False

    return k >= 0


for _ in range(int(input())):
    n, m, k = map(int, input().split())
    a: list[str] = list(input())

    if possible(n, m, k, a):
        print("YES")
    else:
        print("NO")

Ketone 60 mg/dl

Cheese 10g Snacks 10g Protein shake 10g Bacon Egg 0g

Total carbohydrate 30g

walking


MUST:

TODO:


index 20240716 20240718