commit 9e8c9d1fa733578e3c10923f490ed9e8548a969b
parent cc1ac78d6c6f1447063d5f98e289abe534ac4cc7
Author: Walther Chen <walther.chen@gmail.com>
Date:   Wed, 23 Oct 2024 14:56:49 -0400

restructure, ba1a ba1b

Diffstat:
M.gitignore | 5++++-
Aba1a.c3 | 34++++++++++++++++++++++++++++++++++
Aba1b.c3 | 54++++++++++++++++++++++++++++++++++++++++++++++++++++++
Ajustfile | 13+++++++++++++
4 files changed, 105 insertions(+), 1 deletion(-)

diff --git a/.gitignore b/.gitignore @@ -1 +1,4 @@ -data/ +* +!*.c3 +!README.md +!justfile diff --git a/ba1a.c3 b/ba1a.c3 @@ -0,0 +1,34 @@ +module ba1a; + +import std::io; +import std::io::file; +import std::collections; + +fn void! main(String[] args) { + if (args.len != 2) { + io::eprintn("Please supply path to data file"); + return IoError.FILE_NOT_FOUND?; + } + File f = file::open(args[1], "rb")!; + String text = io::treadline(&f)!; + String pattern = io::treadline(&f)!; + io::printn(pattern_count(text, pattern)); +} + +fn int pattern_count(String text, String pattern) { + if (pattern.len == 0) return 0; + int count = 0 ; + for (int i = 0; i <= text.len - pattern.len; i += 1) { + if (text[i:pattern.len] == pattern) { + count += 1; + } + } + return count; +} + +fn void test_pattern_count() @test { + assert(pattern_count("GCGCG", "") == 0); + assert(pattern_count("GCGCG", "G") == 3); + assert(pattern_count("GCGCG", "GCG") == 2); +} + diff --git a/ba1b.c3 b/ba1b.c3 @@ -0,0 +1,54 @@ +module ba1b; + +import std::io; +import std::io::file; +import std::collections; + +def KmerCounts = HashMap(<String, int>); + +fn void! main(String[] args) { + if (args.len != 2) { + io::eprintn("Please supply path to data file"); + return IoError.FILE_NOT_FOUND?; + } + File f = file::open(args[1], "rb")!; + String text = io::treadline(&f)!; + String k_str = io::treadline(&f)!; + int k = k_str.to_integer(int)!; + foreach(word: frequent_words(text, k)) { + io::printf("%s ", word); + } + io::printn(); +} + +fn String[] frequent_words(String text, int k, Allocator alloc= allocator::heap()) { + @pool() { + KmerCounts kmer_counts; + for (int i = 0; i <= text.len - k; i += 1) { + // TODO get_or_update? Annoying to get twice + kmer_counts.@get_or_set(text[i:k], 0); + if (try int* count = kmer_counts.get_ref(text[i:k])) { + *count += 1; + } + } + + int[] counts = kmer_counts.value_tlist(); + int max = 0; + foreach (count: counts) { + if (count > max) max = count; + } + + List(<String>) res; + res.temp_init(); + kmer_counts.@each(; String key, int v) { + if (v == max) { + res.push(key); + } + }; + return res.to_new_array(alloc); + }; +} + +fn void test_frequent_words() @test { + assert(frequent_words("ACGTTGCATGTCGCATGATGCATGAGAGCT", 4) == {"CATG", "GCAT"}); +} diff --git a/justfile b/justfile @@ -0,0 +1,13 @@ +@check: + \fd --glob '*.c3' -x c3c compile -C + +@test: + c3c compile-test . + +# redirects outputs to stderr +@build problem *args="": + c3c compile -O3 {{problem}}.c3 1>&2 + +# using compile-run prints a bunch of logs +run problem *args="": + just build {{problem}} -O3 && ./{{problem}} {{args}} && rm ./{{problem}}