input.zig 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. const std = @import("std");
  2. const shapeModule = @import("shape.zig");
  3. const Shape = shapeModule.Shape;
  4. pub const AreaRequirements = struct {
  5. rows: i32,
  6. cols: i32,
  7. shapesCount: []i32,
  8. };
  9. pub const Input = struct {
  10. shapes: []Shape,
  11. areas: []AreaRequirements,
  12. };
  13. fn parseShape(shapeText: []const u8) Shape {
  14. var it = std.mem.tokenizeScalar(u8, shapeText, '\n');
  15. _ = it.next(); // skip header
  16. var shape: Shape = .{
  17. .data = undefined,
  18. };
  19. for (0..3) |row| {
  20. const rowText = it.next().?;
  21. for (0..3) |col| {
  22. shape.setCell(@intCast(row), @intCast(col), rowText[col]);
  23. }
  24. }
  25. return shape;
  26. }
  27. fn parseAreaRequirements(allocator: std.mem.Allocator, line: []const u8) !AreaRequirements {
  28. var it = std.mem.tokenizeSequence(u8, line, ": ");
  29. const sizeText = it.next().?;
  30. const shapesCountText = it.next().?;
  31. var sizeTextIt = std.mem.tokenizeScalar(u8, sizeText, 'x');
  32. const rowsText = sizeTextIt.next().?;
  33. const colsText = sizeTextIt.next().?;
  34. const rows = try std.fmt.parseInt(i32, rowsText, 10);
  35. const cols = try std.fmt.parseInt(i32, colsText, 10);
  36. var shapesCountTextIt = std.mem.tokenizeScalar(u8, shapesCountText, ' ');
  37. var shapesCount = std.ArrayList(i32).empty;
  38. while (shapesCountTextIt.next()) |shapeCountText| {
  39. const shapeCount = try shapesCount.addOne(allocator);
  40. shapeCount.* = try std.fmt.parseInt(i32, shapeCountText, 10);
  41. }
  42. const area: AreaRequirements = .{
  43. .rows = rows,
  44. .cols = cols,
  45. .shapesCount = shapesCount.items,
  46. };
  47. return area;
  48. }
  49. pub fn parseInput(allocator: std.mem.Allocator, inputBuffer: []u8) !Input {
  50. var shapes = std.ArrayList(Shape).empty;
  51. var areas = std.ArrayList(AreaRequirements).empty;
  52. var i = std.mem.tokenizeSequence(u8, inputBuffer, "\n\n");
  53. while (i.next()) |inputBlock| {
  54. if (inputBlock.len >= 2 and inputBlock[1] == ':') {
  55. const shape = try shapes.addOne(allocator);
  56. shape.* = parseShape(inputBlock);
  57. } else {
  58. var it = std.mem.tokenizeScalar(u8, inputBlock, '\n');
  59. while(it.next()) |line| {
  60. const area = try areas.addOne(allocator);
  61. area.* = try parseAreaRequirements(allocator, line);
  62. }
  63. }
  64. }
  65. const input: Input = .{
  66. .shapes = shapes.items,
  67. .areas = areas.items,
  68. };
  69. return input;
  70. }
  71. pub fn readInputIntoString(allocator: std.mem.Allocator, fileName: []const u8) ![]u8 {
  72. const inputFile = try std.fs.cwd().openFile(
  73. fileName, .{.mode = .read_only,});
  74. defer inputFile.close();
  75. var inputFileReader = inputFile.reader(
  76. try allocator.alignedAlloc(u8, null, 1024));
  77. const inputFileSize = try inputFileReader.getSize();
  78. const inputBuffer = try allocator.alignedAlloc(u8, null, inputFileSize);
  79. try inputFileReader.interface.readSliceAll(inputBuffer);
  80. return inputBuffer;
  81. }