1diff --git a/.gitignore b/.gitignore
2new file mode 100644
3index 0000000000000000000000000000000000000000..ee7098f17a1cdbf7cb6720972c33cf3b63bed8fc
4--- /dev/null
5+++ b/.gitignore
6@@ -0,0 +1,2 @@
7+zig-out/
8+zig-cache/
9diff --git a/build.zig b/build.zig
10new file mode 100644
11index 0000000000000000000000000000000000000000..17d4fb7f767fc4b073b6f6dbb3b38ca773ce7d2b
12--- /dev/null
13+++ b/build.zig
14@@ -0,0 +1,42 @@
15+const std = @import("std");
16+
17+pub fn build(b: *std.Build) void {
18+ const target = b.standardTargetOptions(.{});
19+
20+ const optimize = b.standardOptimizeOption(.{
21+ .preferred_optimize_mode = std.builtin.OptimizeMode.ReleaseFast,
22+ });
23+
24+ const exe = b.addExecutable(.{
25+ .name = "uf",
26+ .root_source_file = b.path("src/main.zig"),
27+ .target = target,
28+ .optimize = optimize,
29+ .single_threaded = true,
30+ .strip = true,
31+ });
32+
33+ b.installArtifact(exe);
34+
35+ const run_cmd = b.addRunArtifact(exe);
36+
37+ run_cmd.step.dependOn(b.getInstallStep());
38+
39+ if (b.args) |args| {
40+ run_cmd.addArgs(args);
41+ }
42+
43+ const run_step = b.step("run", "Run the app");
44+ run_step.dependOn(&run_cmd.step);
45+
46+ const exe_unit_tests = b.addTest(.{
47+ .root_source_file = b.path("src/main.zig"),
48+ .target = target,
49+ .optimize = optimize,
50+ });
51+
52+ const run_exe_unit_tests = b.addRunArtifact(exe_unit_tests);
53+
54+ const test_step = b.step("test", "Run unit tests");
55+ test_step.dependOn(&run_exe_unit_tests.step);
56+}
57diff --git a/src/main.zig b/src/main.zig
58new file mode 100644
59index 0000000000000000000000000000000000000000..c65a36b41bce665f55e175b5e4d0fba7113be8af
60--- /dev/null
61+++ b/src/main.zig
62@@ -0,0 +1,75 @@
63+const std = @import("std");
64+const File = std.fs.File;
65+const Writer = std.fs.File.Writer;
66+
67+pub fn main() !void {
68+ const in = std.io.getStdIn();
69+ const out = std.io.getStdOut();
70+ Uf.init().streamCopy(in, out) catch |err| {
71+ try std.io.getStdErr().writer().print("Error {}", .{err});
72+ };
73+}
74+
75+const buf_size = 1_000_000;
76+
77+const Uf = struct {
78+ const Self = @This();
79+
80+ var out_buf: [buf_size]u8 = undefined;
81+ var out_index: u32 = 0;
82+
83+ fn init() *const Self {
84+ return &Self{};
85+ }
86+
87+ fn flush(_: *const Self, out: Writer) !void {
88+ _ = try out.write(out_buf[0..out_index]);
89+ out_index = 0;
90+ }
91+
92+ fn writeChar(self: *const Self, out: Writer, c: u8) !void {
93+ if (out_index >= buf_size) {
94+ try self.flush(out);
95+ }
96+ out_buf[out_index] = c;
97+ out_index += 1;
98+ }
99+
100+ fn streamCopy(self: *const Self, in: File, out: File) !void {
101+ const reader = in.reader();
102+ const writer = out.writer();
103+
104+ var hit = false;
105+ var second = false;
106+ var in_buf: [buf_size]u8 = undefined;
107+ while (true) {
108+ const size = try reader.read(&in_buf);
109+
110+ for (in_buf[0..size]) |c| {
111+ if (hit and c == '\n') {
112+ if (second == false) {
113+ second = true;
114+ } else {
115+ continue;
116+ }
117+ } else if (hit and c != '\n') {
118+ if (second) {
119+ try self.writeChar(writer, '\n');
120+ }
121+ hit = false;
122+ second = false;
123+ } else if (c == '\n') {
124+ hit = true;
125+ continue;
126+ }
127+
128+ try self.writeChar(writer, c);
129+ }
130+
131+ if (size != in_buf.len) {
132+ try self.flush(writer);
133+ return;
134+ }
135+ }
136+ }
137+};
138diff --git a/src/root.zig b/src/root.zig
139new file mode 100644
140index 0000000000000000000000000000000000000000..ecfeade1a3ac1a5959545293ac3f34625b4743ce
141--- /dev/null
142+++ b/src/root.zig
143@@ -0,0 +1,10 @@
144+const std = @import("std");
145+const testing = std.testing;
146+
147+export fn add(a: i32, b: i32) i32 {
148+ return a + b;
149+}
150+
151+test "basic add functionality" {
152+ try testing.expect(add(3, 7) == 10);
153+}