Решение на Сметки с ДНК от Теодор Кирилов

Обратно към всички решения

Към профила на Теодор Кирилов

Резултати

  • 20 точки от тестове
  • 0 бонус точки
  • 20 точки общо
  • 12 успешни тест(а)
  • 0 неуспешни тест(а)

Код

pub struct NucleotideCounter {
pub a: usize,
pub c: usize,
pub g: usize,
pub t: usize,
}
pub fn counts(dna: &[char]) -> NucleotideCounter {
let mut cr=NucleotideCounter{
a: 0,
c: 0,
g: 0,
t: 0,
};
for &i in dna
{
if i=='A' {
cr.a=cr.a+1;
}
else
if i=='C' {
cr.c=cr.c+1;
}
else
if i=='G' {
cr.g=cr.g+1;
}
else
if i=='T' {
cr.t=cr.t+1;
}
else {
panic!("error, error, self destruction in 10 9 8 7 6 5 4 ...");
}
}

Индентацията, която отива навътре, не изглежда много добре. Обикновено, ако ще ползваш else if, ще е на един ред и няма да се добавя индентация на следващите блокове, примерно:

for &i in dna
{
    if i=='A' {
        cr.a=cr.a+1;
    }
    else if i=='C' {
        cr.c=cr.c+1;
    }
    else if i=='G' {
        cr.g=cr.g+1;
    }

Допълнително, } else if ... { е най-честото форматиране -- с else-а на същия ред като затварящата скоба. Няма да ти правим проблеми за коя скоба къде отива, но те съветвам да опиташ популярната конвенция. Ако не друго, ще четеш код, който ще изглежда по този начин.

cr
}
pub fn dna_complement(dna: &[char]) -> Vec<char> {
let mut result_vec=Vec::new();
for &i in dna
{
if i=='A' {
result_vec.push('T');
}
else
if i=='C' {
result_vec.push('G');
}
else
if i=='G' {
result_vec.push('C');
}
else
if i=='T' {
result_vec.push('A');
}
else {
panic!("error, error, self destruction in 10 9 8 7 6 5 4 ...");
}
}
result_vec
}
pub fn reverse_rna_complement(dna: &[char]) -> Vec<char> {
let vec_dna=dna_complement(&dna);
let mut vec_rna=Vec::new();
for & i in& vec_dna
{
if i=='T'{
vec_rna.push('U');
}
else {
vec_rna.push(i);
}
}
vec_rna.reverse();
vec_rna
}
#[cfg(test)]
mod tests{
#[test]
fn test_basic() {
use super::*;
let input: Vec<char> = "GC".chars().collect();
let counter = counts(&input);
assert_eq!(counter.g, 1);
assert_eq!(counter.c, 1);
assert_eq!(counter.a, 0);
assert_eq!(counter.t, 0);
assert_eq!(dna_complement(&input), vec!['C', 'G']);
assert_eq!(reverse_rna_complement(&input), vec!['G', 'C']);
}
#[test]
fn my_test_1()
{
use super::*;
let input: Vec<char> = "GGGCTTA".chars().collect();
let counter = counts(&input);
assert_eq!(counter.g, 3);
assert_eq!(counter.c, 1);
assert_eq!(counter.a, 1);
assert_eq!(counter.t, 2);
assert_eq!(dna_complement(&input), vec!['C','C','C', 'G','A','A','T']);
assert_eq!(reverse_rna_complement(&input), vec!['U','A','A', 'G','C','C','C']);
}
#[test]
#[should_panic(expected = "error, error, self destruction in 10 9 8 7 6 5 4 ...")]
fn my_test_2()
{
use super::*;
let input: Vec<char> = "GGCaTTA".chars().collect();
counts(&input);
}
#[test]
#[should_panic(expected = "error, error, self destruction in 10 9 8 7 6 5 4 ...")]
fn my_test_3()
{
use super::*;
//А, С and Т are in cyrillic, they look the same as the latin A, C and T
//but are encoded differently, and thats why the result expected is panic
let input: Vec<char> = "АСТ".chars().collect();
counts(&input);
}
#[test]
fn my_test_4() {
use super::*;
let input: Vec<char> = "GGACTTA".chars().collect();
let counter = counts(&input);
assert_eq!(counter.g, 2);
assert_eq!(counter.c, 1);
assert_eq!(counter.a, 2);
assert_eq!(counter.t, 2);
assert_eq!(dna_complement(&input), vec!['C','C','T','G','A','A','T']);
assert_eq!(reverse_rna_complement(&input), vec!['U','A','A','G','U','C','C']);
}
}

Лог от изпълнението

Compiling solution v0.1.0 (/tmp/d20220112-2706256-10savkq/solution)
    Finished test [unoptimized + debuginfo] target(s) in 5.57s
     Running tests/solution_test.rs (target/debug/deps/solution_test-4c880d3f0adaac34)

running 12 tests
test solution_test::test_counts_basic ... ok
test solution_test::test_counts_big ... ok
test solution_test::test_counts_panic1 - should panic ... ok
test solution_test::test_counts_panic2 - should panic ... ok
test solution_test::test_counts_zero ... ok
test solution_test::test_dna_complement_big ... ok
test solution_test::test_dna_complement_empty ... ok
test solution_test::test_dna_complement_panic - should panic ... ok
test solution_test::test_reverse_rna_complement_big ... ok
test solution_test::test_reverse_rna_complement_empty ... ok
test solution_test::test_reverse_rna_complement_panic1 - should panic ... ok
test solution_test::test_reverse_rna_complement_panic2 - should panic ... ok

test result: ok. 12 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s

История (2 версии и 2 коментара)

Теодор качи първо решение на 24.10.2021 18:51 (преди почти 4 години)

Теодор качи решение на 24.10.2021 19:30 (преди почти 4 години)

pub struct NucleotideCounter {
pub a: usize,
pub c: usize,
pub g: usize,
pub t: usize,
}
pub fn counts(dna: &[char]) -> NucleotideCounter {
let mut cr=NucleotideCounter{
a: 0,
c: 0,
g: 0,
t: 0,
};
for &i in dna
{
if i=='A' {
cr.a=cr.a+1;
}
else
if i=='C' {
cr.c=cr.c+1;
}
else
if i=='G' {
cr.g=cr.g+1;
}
else
if i=='T' {
cr.t=cr.t+1;
}
else {
panic!("error, error, self destruction in 10 9 8 7 6 5 4 ...");
}
}

Индентацията, която отива навътре, не изглежда много добре. Обикновено, ако ще ползваш else if, ще е на един ред и няма да се добавя индентация на следващите блокове, примерно:

for &i in dna
{
    if i=='A' {
        cr.a=cr.a+1;
    }
    else if i=='C' {
        cr.c=cr.c+1;
    }
    else if i=='G' {
        cr.g=cr.g+1;
    }

Допълнително, } else if ... { е най-честото форматиране -- с else-а на същия ред като затварящата скоба. Няма да ти правим проблеми за коя скоба къде отива, но те съветвам да опиташ популярната конвенция. Ако не друго, ще четеш код, който ще изглежда по този начин.

cr
}
pub fn dna_complement(dna: &[char]) -> Vec<char> {
let mut result_vec=Vec::new();
for &i in dna
{
if i=='A' {
result_vec.push('T');
}
else
if i=='C' {
result_vec.push('G');
}
else
if i=='G' {
result_vec.push('C');
}
else
if i=='T' {
result_vec.push('A');
}
else {
panic!("error, error, self destruction in 10 9 8 7 6 5 4 ...");
}
}
result_vec
}
pub fn reverse_rna_complement(dna: &[char]) -> Vec<char> {
let vec_dna=dna_complement(&dna);
let mut vec_rna=Vec::new();
for & i in& vec_dna
{
if i=='T'{
vec_rna.push('U');
}
else {
vec_rna.push(i);
}
}
vec_rna.reverse();
vec_rna
-}
+}
+
+
+
+#[cfg(test)]
+mod tests{
+
+#[test]
+fn test_basic() {
+
+ use super::*;
+ let input: Vec<char> = "GC".chars().collect();
+ let counter = counts(&input);
+
+ assert_eq!(counter.g, 1);
+ assert_eq!(counter.c, 1);
+ assert_eq!(counter.a, 0);
+ assert_eq!(counter.t, 0);
+
+ assert_eq!(dna_complement(&input), vec!['C', 'G']);
+ assert_eq!(reverse_rna_complement(&input), vec!['G', 'C']);
+}
+
+#[test]
+fn my_test_1()
+{
+ use super::*;
+ let input: Vec<char> = "GGGCTTA".chars().collect();
+ let counter = counts(&input);
+ assert_eq!(counter.g, 3);
+ assert_eq!(counter.c, 1);
+ assert_eq!(counter.a, 1);
+ assert_eq!(counter.t, 2);
+ assert_eq!(dna_complement(&input), vec!['C','C','C', 'G','A','A','T']);
+ assert_eq!(reverse_rna_complement(&input), vec!['U','A','A', 'G','C','C','C']);
+}
+
+#[test]
+#[should_panic(expected = "error, error, self destruction in 10 9 8 7 6 5 4 ...")]
+fn my_test_2()
+{
+ use super::*;
+ let input: Vec<char> = "GGCaTTA".chars().collect();
+ counts(&input);
+}
+
+#[test]
+#[should_panic(expected = "error, error, self destruction in 10 9 8 7 6 5 4 ...")]
+fn my_test_3()
+{
+ use super::*;
+ //А, С and Т are in cyrillic, they look the same as the latin A, C and T
+ //but are encoded differently, and thats why the result expected is panic
+ let input: Vec<char> = "АСТ".chars().collect();
+ counts(&input);
+}
+
+#[test]
+fn my_test_4() {
+ use super::*;
+ let input: Vec<char> = "GGACTTA".chars().collect();
+ let counter = counts(&input);
+ assert_eq!(counter.g, 2);
+ assert_eq!(counter.c, 1);
+ assert_eq!(counter.a, 2);
+ assert_eq!(counter.t, 2);
+ assert_eq!(dna_complement(&input), vec!['C','C','T','G','A','A','T']);
+ assert_eq!(reverse_rna_complement(&input), vec!['U','A','A','G','U','C','C']);
+}
+
+}