🎉 Exercism Research is now launched. Help Exercism, help science and have some fun at research.exercism.io 🎉
Avatar of bkhl

bkhl's solution

to Nucleotide Count in the Racket Track

Published at Apr 26 2020 · 0 comments
Test suite

Given a single stranded DNA string, compute how many times each nucleotide occurs in the string.

The genetic language of every living thing on the planet is DNA. DNA is a large molecule that is built from an extremely long sequence of individual elements called nucleotides. 4 types exist in DNA and these differ only slightly and can be represented as the following symbols: 'A' for adenine, 'C' for cytosine, 'G' for guanine, and 'T' thymine.

Here is an analogy:

  • twigs are to birds nests as
  • nucleotides are to DNA as
  • legos are to lego houses as
  • words are to sentences as...

For installation and learning resources, refer to the exercism Racket page.

You can run the provided tests through DrRacket, or via the command line.

To run the test through DrRacket, simply open the test file and click the 'Run' button in the upper right.

To run the test from the command line, run the test from the exercise directory with the following command:

raco test nucleotide-count-test.rkt

which will display the following:

raco test: (submod "nucleotide-count-test.rkt" test)
2 success(es) 0 failure(s) 0 error(s) 2 test(s) run
2 tests passed


The Calculating DNA Nucleotides_problem at Rosalind http://rosalind.info/problems/dna/

Submitting Incomplete Solutions

It's possible to submit an incomplete solution so you can see how others have completed the exercise.


#lang racket/base

(require "nucleotide-count.rkt")

(module+ test
  (require rackunit rackunit/text-ui)

  (define suite
     "nucleotide count tests"

     (test-equal? "empty dna strand has no nucleotides"
                  (nucleotide-counts "")
                  '((#\A . 0) (#\C . 0) (#\G . 0) (#\T . 0)))

     (test-equal? "repetitive sequence has only guanine"
                  (nucleotide-counts "GGGGGGGG")
                  '((#\A . 0) (#\C . 0) (#\G . 8) (#\T . 0)))

     (test-equal? "counts all nucleotides"
                  '((#\A . 20) (#\C . 12) (#\G . 17) (#\T . 21)))

     (test-exn "invalid nucleotide" exn:fail? (lambda () (nucleotide-counts "AGGTCCXGA")))))

  (run-tests suite))
#lang racket

    [nucleotide? (-> char? boolean?)]
    [nucleotide-string? (-> string? boolean?)]
      (-> nucleotide-string?
          (listof (cons/c nucleotide?  number?)))]))

(define nucleotides
  '(#\A #\C #\G #\T))

(define (nucleotide? x)
  (member x nucleotides))

(define (nucleotide-string? x)
  (andmap nucleotide? (string->list x)))

(define (nucleotide-counts dna)
  (foldl (λ (nucleotide counts)
            (dict-update counts nucleotide add1))
         (map (λ (nucleotide) (cons nucleotide 0)) nucleotides)
         (string->list dna)))

Community comments

Find this solution interesting? Ask the author a question to learn more.

What can you learn from this solution?

A huge amount can be learned from reading other people’s code. This is why we wanted to give exercism users the option of making their solutions public.

Here are some questions to help you reflect on this solution and learn the most from it.

  • What compromises have been made?
  • Are there new concepts here that you could read more about to improve your understanding?