-
Notifications
You must be signed in to change notification settings - Fork 164
Expand file tree
/
Copy path1.zig
More file actions
133 lines (113 loc) · 4.13 KB
/
1.zig
File metadata and controls
133 lines (113 loc) · 4.13 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
// From https://github.com/tiehuis/zig-benchmarks-game/blob/master/src/fasta.zig
const std = @import("std");
const max_line_length = 60;
const im = 139968;
const ia = 3877;
const ic = 29573;
var seed: u32 = 42;
fn nextRandom(max: f64) f64 {
seed = (seed * ia + ic) % im;
return max * @as(f64, @floatFromInt(seed)) / @as(f64, @floatFromInt(im));
}
const AminoAcid = struct {
l: u8,
p: f64,
};
fn repeatAndWrap(out: anytype, comptime sequence: []const u8, count: usize) void {
var padded_sequence: [sequence.len + max_line_length]u8 = undefined;
for (&padded_sequence, 0..) |*e, i| {
e.* = sequence[i % sequence.len];
}
var off: usize = 0;
var idx: usize = 0;
while (idx < count) {
const rem = count - idx;
const line_length = @min(@as(usize, max_line_length), rem);
_ = out.write(padded_sequence[off .. off + line_length]) catch unreachable;
_ = out.writeByte('\n') catch unreachable;
off += line_length;
if (off > sequence.len) {
off -= sequence.len;
}
idx += line_length;
}
}
fn generateAndWrap(out: anytype, comptime nucleotides: []const AminoAcid, count: usize) void {
var cum_prob: f64 = 0;
var cum_prob_total: [nucleotides.len]f64 = undefined;
for (nucleotides, 0..) |n, i| {
cum_prob += n.p;
cum_prob_total[i] = cum_prob * im;
}
var line: [max_line_length + 1]u8 = undefined;
line[max_line_length] = '\n';
var idx: usize = 0;
while (idx < count) {
const rem = count - idx;
const line_length = @min(@as(usize, max_line_length), rem);
for (line[0..line_length]) |*col| {
const r = nextRandom(im);
var c: usize = 0;
for (cum_prob_total) |n| {
if (n <= r) {
c += 1;
}
}
col.* = nucleotides[c].l;
}
line[line_length] = '\n';
_ = out.write(line[0 .. line_length + 1]) catch unreachable;
idx += line_length;
}
}
const Out = struct {
pub fn write(_: Out, bytes: []const u8) !usize {
return try std.posix.write(std.posix.STDOUT_FILENO, bytes);
}
pub fn writeByte(self: Out, b: u8) !void {
_ = try self.write(&[_]u8{b});
}
};
pub fn main() !void {
const stdout = Out{};
const n = try get_n();
const homo_sapiens_alu = "GGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTC" ++
"AGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCG" ++
"TGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGG" ++
"AGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAA";
_ = try stdout.write(">ONE Homo sapiens alu\n");
repeatAndWrap(stdout, homo_sapiens_alu, 2 * n);
const iub_nucleotide_info = &[_]AminoAcid{
AminoAcid{ .l = 'a', .p = 0.27 },
AminoAcid{ .l = 'c', .p = 0.12 },
AminoAcid{ .l = 'g', .p = 0.12 },
AminoAcid{ .l = 't', .p = 0.27 },
AminoAcid{ .l = 'B', .p = 0.02 },
AminoAcid{ .l = 'D', .p = 0.02 },
AminoAcid{ .l = 'H', .p = 0.02 },
AminoAcid{ .l = 'K', .p = 0.02 },
AminoAcid{ .l = 'M', .p = 0.02 },
AminoAcid{ .l = 'N', .p = 0.02 },
AminoAcid{ .l = 'R', .p = 0.02 },
AminoAcid{ .l = 'S', .p = 0.02 },
AminoAcid{ .l = 'V', .p = 0.02 },
AminoAcid{ .l = 'W', .p = 0.02 },
AminoAcid{ .l = 'Y', .p = 0.02 },
};
_ = try stdout.write(">TWO IUB ambiguity codes\n");
generateAndWrap(stdout, iub_nucleotide_info, 3 * n);
const homo_sapien_nucleotide_info = &[_]AminoAcid{
AminoAcid{ .l = 'a', .p = 0.3029549426680 },
AminoAcid{ .l = 'c', .p = 0.1979883004921 },
AminoAcid{ .l = 'g', .p = 0.1975473066391 },
AminoAcid{ .l = 't', .p = 0.3015094502008 },
};
_ = try stdout.write(">THREE Homo sapiens frequency\n");
generateAndWrap(stdout, homo_sapien_nucleotide_info, 5 * n);
}
fn get_n() !usize {
var arg_it = std.process.args();
_ = arg_it.skip();
const arg = arg_it.next() orelse return 10;
return try std.fmt.parseInt(u64, arg, 10);
}