Skip to content

Commit

Permalink
OFMI 2023.5 (#37)
Browse files Browse the repository at this point in the history
* mover ofmi-2023.5

* ofmi-2023.5 public
  • Loading branch information
Janque authored May 11, 2024
1 parent 652bab9 commit f89018c
Show file tree
Hide file tree
Showing 805 changed files with 5,058,600 additions and 0 deletions.
2 changes: 2 additions & 0 deletions 2023.5/dia-1/ofmi-2023-basquet/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
**/*.out
!tests/invalid-cases/*.out
133 changes: 133 additions & 0 deletions 2023.5/dia-1/ofmi-2023-basquet/case-generator.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
import os
import random

base_string = """
{arr}
""".strip(
" \t\n\r"
)

num_subtareas = 1
puntos_por_subtarea = [100]
casos_por_subtarea = [21]
subtarea_agrupada = [False for _ in range(num_subtareas)]
sample_case_names = ["sample", "sample2"]


def has_solution(arr):
for x in arr:
for y in arr:
z = 100 - x - y
if z in arr and x != y and x != z and y != z:
return True
return False


def generate_case(_, case_number):
n = 5
if case_number == 0:
# Generate impossible case
arr = [random.randint(1, 100) for _ in range(n)]
while len(arr) != len(set(arr)) or has_solution(arr):
arr = [random.randint(1, 100) for _ in range(n)]
else:
# Generate random case
a = random.randint(1, 100)
b = random.randint(1, 100)
a, b = min(a, b), max(a, b)
arr = [a, b - a, 100 - b]
while len(arr) != len(set(arr)):
a = random.randint(1, 100)
b = random.randint(1, 100)
a, b = min(a, b), max(a, b)
arr = [a, b - a, 100 - b]
# shuffle the array
random.shuffle(arr)
# add random numbers
for _ in range(n - 3):
x = random.randint(1, 100)
while x in arr:
x = random.randint(1, 100)
arr.append(x)
perm = case_number % 10
for i in range(n):
for j in range(i + 1, n):
perm -= 1
if perm == 0:
arr[i], arr[-2] = arr[-2], arr[i]
arr[j], arr[-1] = arr[-1], arr[j]
return {"arr": " ".join(map(str, arr))}


# This helper function will generate a number that is linearly increasing
# with the case number. This is useful to make cases bigger as the case_number
def linear_incremental(subtarea, case_number, max_number):
casos_subtarea = casos_por_subtarea[subtarea - 1]
# pendiente * casos_subtarea = max_number
pendiente = max_number // casos_subtarea
return pendiente * (case_number + 1)


# This helper function will generate a number that is k-power increasing
# with the case number. This is useful to make cases bigger as the case_number
def power_incremental(subtarea, case_number, max_number, k=4):
casos_subtarea = casos_por_subtarea[subtarea - 1]
# c* casos_subtarea^4 = max_number
c = max_number / (casos_subtarea**k)
return int(c * (case_number + 1) ** k)


def get_case_name(subtarea, case_number):
agrupados = subtarea_agrupada[subtarea - 1]
if agrupados:
return f"sub{subtarea}.{case_number}"
return f"sub{subtarea}_{case_number}"


def get_case_points(subtarea, case_number):
puntos_subtarea = puntos_por_subtarea[subtarea - 1]
casos_subtarea = casos_por_subtarea[subtarea - 1]
agrupados = subtarea_agrupada[subtarea - 1]
if agrupados:
return puntos_subtarea if case_number == 0 else 0
return puntos_subtarea // casos_subtarea + (
1 if puntos_subtarea % casos_subtarea > case_number else 0
)


def write_testplan():
assert len(sample_case_names) == len(set(sample_case_names))
with open("testplan", "w") as f:
for case_name in sample_case_names:
f.write(f"{case_name} 0\n")

for subtarea in range(1, num_subtareas + 1):
for case_number in range(casos_por_subtarea[subtarea - 1]):
case_name = get_case_name(subtarea, case_number)
case_points = get_case_points(subtarea, case_number)
assert case_name not in sample_case_names
with open("testplan", "a") as f:
f.write(f"{case_name} {case_points}\n")


def write_cases():
for subtarea in range(1, num_subtareas + 1):
for case_number in range(casos_por_subtarea[subtarea - 1]):
case_name = get_case_name(subtarea, case_number)
case_path = os.path.join("cases", case_name)
with open(f"{case_path}.in", "w") as f:
case = generate_case(subtarea, case_number)
case_string = base_string.format(**case)
f.write(f"{case_string}\n")


def main():
random.seed(348101)
assert num_subtareas == len(puntos_por_subtarea) == len(casos_por_subtarea)
assert sum(puntos_por_subtarea) == 100
write_testplan()
write_cases()


if __name__ == "__main__":
main()
1 change: 1 addition & 0 deletions 2023.5/dia-1/ofmi-2023-basquet/cases/sample.in
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
40 13 25 20 35
1 change: 1 addition & 0 deletions 2023.5/dia-1/ofmi-2023-basquet/cases/sample2.in
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
14 34 12 59 60
1 change: 1 addition & 0 deletions 2023.5/dia-1/ofmi-2023-basquet/cases/sub1_0.in
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
85 58 82 83 26
1 change: 1 addition & 0 deletions 2023.5/dia-1/ofmi-2023-basquet/cases/sub1_1.in
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
61 9 11 47 42
1 change: 1 addition & 0 deletions 2023.5/dia-1/ofmi-2023-basquet/cases/sub1_10.in
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
36 55 9 22 43
1 change: 1 addition & 0 deletions 2023.5/dia-1/ofmi-2023-basquet/cases/sub1_11.in
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
41 40 24 66 10
1 change: 1 addition & 0 deletions 2023.5/dia-1/ofmi-2023-basquet/cases/sub1_12.in
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
43 51 20 32 17
1 change: 1 addition & 0 deletions 2023.5/dia-1/ofmi-2023-basquet/cases/sub1_13.in
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
70 33 7 2 60
1 change: 1 addition & 0 deletions 2023.5/dia-1/ofmi-2023-basquet/cases/sub1_14.in
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
82 57 11 32 21
1 change: 1 addition & 0 deletions 2023.5/dia-1/ofmi-2023-basquet/cases/sub1_15.in
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
17 48 72 6 77
1 change: 1 addition & 0 deletions 2023.5/dia-1/ofmi-2023-basquet/cases/sub1_16.in
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
27 50 71 6 2
1 change: 1 addition & 0 deletions 2023.5/dia-1/ofmi-2023-basquet/cases/sub1_17.in
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
42 81 51 7 40
1 change: 1 addition & 0 deletions 2023.5/dia-1/ofmi-2023-basquet/cases/sub1_18.in
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
22 55 36 52 23
1 change: 1 addition & 0 deletions 2023.5/dia-1/ofmi-2023-basquet/cases/sub1_19.in
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
50 16 25 7 77
1 change: 1 addition & 0 deletions 2023.5/dia-1/ofmi-2023-basquet/cases/sub1_2.in
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
77 20 99 67 13
1 change: 1 addition & 0 deletions 2023.5/dia-1/ofmi-2023-basquet/cases/sub1_20.in
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
77 7 25 16 50
1 change: 1 addition & 0 deletions 2023.5/dia-1/ofmi-2023-basquet/cases/sub1_3.in
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
85 11 52 64 37
1 change: 1 addition & 0 deletions 2023.5/dia-1/ofmi-2023-basquet/cases/sub1_4.in
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
64 47 10 43 17
1 change: 1 addition & 0 deletions 2023.5/dia-1/ofmi-2023-basquet/cases/sub1_5.in
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
54 48 1 38 8
1 change: 1 addition & 0 deletions 2023.5/dia-1/ofmi-2023-basquet/cases/sub1_6.in
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
14 49 4 89 82
1 change: 1 addition & 0 deletions 2023.5/dia-1/ofmi-2023-basquet/cases/sub1_7.in
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
19 18 9 72 15
1 change: 1 addition & 0 deletions 2023.5/dia-1/ofmi-2023-basquet/cases/sub1_8.in
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
17 26 97 54 57
1 change: 1 addition & 0 deletions 2023.5/dia-1/ofmi-2023-basquet/cases/sub1_9.in
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
12 8 10 80 1
1 change: 1 addition & 0 deletions 2023.5/dia-1/ofmi-2023-basquet/examples/sample.in
1 change: 1 addition & 0 deletions 2023.5/dia-1/ofmi-2023-basquet/examples/sample2.in
25 changes: 25 additions & 0 deletions 2023.5/dia-1/ofmi-2023-basquet/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
{
"title": "Basquetbol",
"source": "OFMI 2023.5 (Juan Carlos Sigler Priego)",
"limits": {
"TimeLimit": 1000,
"MemoryLimit": 134217728,
"InputLimit": 67108864,
"OutputLimit": 67108864,
"ExtraWallTime": 0,
"OverallWallTimeLimit": 60000
},
"validator": {
"name": "custom",
"limits": {
"TimeLimit": 1000
}
},
"misc": {
"alias": "ofmi-2023-basquet",
"visibility": "public",
"languages": "all",
"email_clarifications": 0,
"admin-groups": ["ofmi-2023-5"]
}
}
34 changes: 34 additions & 0 deletions 2023.5/dia-1/ofmi-2023-basquet/solutions/es.markdown
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
Este problema nos pide seleccionar, de entre $5$ números diferentes, $3$ cuya suma sea igual a $100$.

Si nombramos a los $5$ números de la entrada como $a, b, c, d$ y $e$, tenemos $10$ maneras diferentes de seleccionar la suma de tres de ellos:

- $a + b + c$
- $a + b + d$
- $a + b + e$
- $a + c + d$
- $a + c + e$
- $a + d + e$
- $b + c + d$
- $b + c + e$
- $b + d + e$
- $c + d + e$

Entonces, una forma de resolver el problema es calcular estas $10$ sumas y verificar si alguna de ellas es igual a $100$. El siguiente código implementa dicha idea.

<details><summary>Solución verificando las 10 sumas diferentes</summary>

{{solution.cpp}}

</details>

Una alternativa para resolver este problema es, en lugar de guardar los cinco números de la entrada como cinco variables distintas, guardarlos a todos en un arreglo, `playeras`, de tamaño $5$.

Si guardamos los números en las playeras de esa forma, encontrar $3$ de ellos que sumen $100$ equivale a encontrar $3$ índices distintos, $i, j, k$, uno para cada playera a elegir, que cumplan que `playeras[i] + playeras[j] + playeras[k] = 100`. Esto se puede lograr usando tres _fors_ anidados para iterar sobre todas las ternas $i, j, k$ posibles. El siguiente código implementa dicha solución.

<details><summary>Solución guardando los valores en un arreglo</summary>

{{solutionB.cpp}}

</details>

Nota que ambas soluciones prueban todas las formas posibles de seleccionar $3$ números distintos de entre los $5$ que son dados en la entrada, pero la primera solución guarda los números en $5$ variables diferentes mientras que la segunda solución los guarda en un arreglo.
22 changes: 22 additions & 0 deletions 2023.5/dia-1/ofmi-2023-basquet/solutions/parcial.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#include <iostream>

int playeras[6];
int suma_playeras;

int main() {
for (int i = 1; i <= 5; i++) std::cin >> playeras[i];

for (int i = 1; i <= 5; i++) {
for (int j = 2; j <= 5; j++) {
for (int k = 3; k <= 5; k++) {
suma_playeras = playeras[i] + playeras[j] + playeras[k];
if (suma_playeras == 100) {
std::cout << playeras[i] << " " << playeras[j] << " " << playeras[k];
return 0;
}
}
}
}

std::cout << -1;
}
66 changes: 66 additions & 0 deletions 2023.5/dia-1/ofmi-2023-basquet/solutions/solution.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
#include <iostream>

int main() {
// Leemos los 5 números a, b, c, d, e
int a, b, c, d, e;
std::cin >> a >> b >> c >> d >> e;

// Vamos a probar todas las combinaciones de 3 números
// En busca del primero que sume 100.
// En total son 10 combinaciones

// Primera combinación: a, b, c
if (a + b + c == 100) {
std::cout << a << ' ' << b << ' ' << c << '\n';
return 0;
}
// Segunda combinación: a, b, d
if (a + b + d == 100) {
std::cout << a << ' ' << b << ' ' << d << '\n';
return 0;
}
// Tercera combinación: a, b, e
if (a + b + e == 100) {
std::cout << a << ' ' << b << ' ' << e << '\n';
return 0;
}
// Cuarta combinación: a, c, d
if (a + c + d == 100) {
std::cout << a << ' ' << c << ' ' << d << '\n';
return 0;
}
// Quinta combinación: a, c, e
if (a + c + e == 100) {
std::cout << a << ' ' << c << ' ' << e << '\n';
return 0;
}
// Sexta combinación: a, d, e
if (a + d + e == 100) {
std::cout << a << ' ' << d << ' ' << e << '\n';
return 0;
}
// Séptima combinación: b, c, d
if (b + c + d == 100) {
std::cout << b << ' ' << c << ' ' << d << '\n';
return 0;
}
// Octava combinación: b, c, e
if (b + c + e == 100) {
std::cout << b << ' ' << c << ' ' << e << '\n';
return 0;
}
// Novena combinación: b, d, e
if (b + d + e == 100) {
std::cout << b << ' ' << d << ' ' << e << '\n';
return 0;
}
// Décima combinación: c, d, e
if (c + d + e == 100) {
std::cout << c << ' ' << d << ' ' << e << '\n';
return 0;
}

// Ninguna combinación sumó 100
std::cout << -1 << '\n';
return 0;
}
22 changes: 22 additions & 0 deletions 2023.5/dia-1/ofmi-2023-basquet/solutions/solutionB.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#include <iostream>

int playeras[6];
int suma_playeras;

int main() {
for (int i = 1; i <= 5; i++) std::cin >> playeras[i];

for (int i = 1; i <= 3; i++) {
for (int j = i + 1; j <= 4; j++) {
for (int k = j + 1; k <= 5; k++) {
suma_playeras = playeras[i] + playeras[j] + playeras[k];
if (suma_playeras == 100) {
std::cout << playeras[i] << " " << playeras[j] << " " << playeras[k];
return 0;
}
}
}
}

std::cout << -1;
}
Loading

0 comments on commit f89018c

Please sign in to comment.