cirosdespair/cirosdespair.zig
2025-03-07 09:28:31 +01:00

147 lines
3.2 KiB
Zig

const std = @import("std");
const Composition = struct {
n: u32,
k: u32,
comp: ?[]u32,
allocator: std.mem.Allocator,
fn init(allocator: std.mem.Allocator, n: u32, k: u32) Composition {
return Composition{
.n = n,
.k = k,
.comp = null,
.allocator = allocator,
};
}
fn first(self: *@This()) void {
self.comp = self.allocator.alloc(u32, self.k) catch unreachable;
for (0..self.k - 1) |i| self.comp.?[i] = 0;
self.comp.?[self.k - 1] = self.n;
}
fn next(self: *@This()) ?[]const u32 {
if (self.comp == null) {
self.first();
return self.comp;
}
const c = self.comp.?;
if (c[0] == self.n) return null;
var last = self.k - 1;
while (c[last] == 0) last -= 1;
const z = c[last];
c[last - 1] += 1;
c[last] = 0;
c[self.k - 1] = z - 1;
return c;
}
fn deinit(self: @This()) void {
if (self.comp) |c| {
self.allocator.free(c);
}
}
};
fn andrew(nu: u32) f32 {
const n: f32 = @floatFromInt(nu);
if (n <= 10) return n * 4;
if (n <= 20) return n * 4.1666666666666;
if (n <= 42) return n * 4.3;
return (n * (4.3 + (0.08333333333 * (n - 42))));
}
fn tobias(nu: u32) f32 {
const n: f32 = @floatFromInt(nu);
if (n <= 42) return n * 4.5;
return (n * (4.5 + (0.0166666666 * (n - 42))));
}
fn lukasz(nu: u32) f32 {
const n: f32 = @floatFromInt(nu);
if (n <= 42) return n * 4.666666;
return (n * (4.66666 + (0.0833333333 * @floor(((n - 42) / 3)))));
}
fn mathis(nu: u32) f32 {
const n: f32 = @floatFromInt(nu);
if (n <= 21) return n * 4.8333333333;
return (n * (4.83333 + (0.0833333333 * @floor(((n - 21) / 3)))));
}
fn ciro(nu: u32) f32 {
const n: f32 = @floatFromInt(nu);
if (n <= 21) return n * 5;
return (n * (4 + (0.0833333333 * @floor((n - 21 / 5)))));
}
fn armin(nu: u32) f32 {
const n: f32 = @floatFromInt(nu);
if (n <= 10) return n * 3.5;
return (n * (3.5 + (0.11666666666 * (n - 10))));
}
fn cost(comp: []const u32) f32 {
return andrew(comp[0]) +
tobias(comp[1]) +
lukasz(comp[2]) +
mathis(comp[3]) +
ciro(comp[4]) +
armin(comp[5]);
}
pub fn main() !void {
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
defer _ = gpa.deinit();
const allocator = gpa.allocator();
var min: f32 = 999999;
const min_comp: []u32 = try allocator.alloc(u32, 6);
defer allocator.free(min_comp);
var composition = Composition.init(allocator, 120, 6);
defer composition.deinit();
while (composition.next()) |comp| {
if (cost(comp) < min) {
min = cost(comp);
@memcpy(min_comp, comp);
}
}
const stdout = std.io.getStdOut().writer();
const fmt =
\\Min: {d}
\\Composition:
\\ Andrew: {d}
\\ Tobias: {d}
\\ Lukasz: {d}
\\ Mathis: {d}
\\ Ciro: {d}
\\ Armin: {d}
\\
;
try stdout.print(fmt, .{
min,
min_comp[0],
min_comp[1],
min_comp[2],
min_comp[3],
min_comp[4],
min_comp[5],
});
}