147 lines
3.2 KiB
Zig
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],
|
|
});
|
|
}
|