hamming
This commit is contained in:
parent
cf4f118c22
commit
59b82ee023
8 changed files with 177 additions and 0 deletions
36
hamming/HELP.md
Normal file
36
hamming/HELP.md
Normal file
|
@ -0,0 +1,36 @@
|
|||
# Help
|
||||
|
||||
## Running the tests
|
||||
|
||||
A `Makefile` is provided with a default target to compile your solution and run the tests. At the command line in your exercise's directory, type:
|
||||
|
||||
```bash
|
||||
make
|
||||
```
|
||||
|
||||
## Submitting your solution
|
||||
|
||||
You can submit your solution using the `exercism submit hamming.ml` command.
|
||||
This command will upload your solution to the Exercism website and print the solution page's URL.
|
||||
|
||||
It's possible to submit an incomplete solution which allows you to:
|
||||
|
||||
- See how others have completed the exercise
|
||||
- Request help from a mentor
|
||||
|
||||
## Need to get help?
|
||||
|
||||
If you'd like help solving the exercise, check the following pages:
|
||||
|
||||
- The [OCaml track's documentation](https://exercism.org/docs/tracks/ocaml)
|
||||
- The [OCaml track's programming category on the forum](https://forum.exercism.org/c/programming/ocaml)
|
||||
- [Exercism's programming category on the forum](https://forum.exercism.org/c/programming/5)
|
||||
- The [Frequently Asked Questions](https://exercism.org/docs/using/faqs)
|
||||
|
||||
Should those resources not suffice, you could submit your (incomplete) solution to request mentoring.
|
||||
|
||||
To get help if you're having trouble, you can use one of the following resources:
|
||||
|
||||
- [Documentation for the Standard Library](http://caml.inria.fr/pub/docs/manual-ocaml/libref/index.html)
|
||||
- [/r/ocaml](https://www.reddit.com/r/ocaml) is the OCaml subreddit.
|
||||
- [StackOverflow](http://stackoverflow.com/questions/tagged/ocaml) can be used to search for your problem and see if it has been answered already. You can also ask and answer questions.
|
9
hamming/Makefile
Normal file
9
hamming/Makefile
Normal file
|
@ -0,0 +1,9 @@
|
|||
default: clean test
|
||||
|
||||
test:
|
||||
dune runtest
|
||||
|
||||
clean:
|
||||
dune clean
|
||||
|
||||
.PHONY: clean
|
46
hamming/README.md
Normal file
46
hamming/README.md
Normal file
|
@ -0,0 +1,46 @@
|
|||
# Hamming
|
||||
|
||||
Welcome to Hamming on Exercism's OCaml Track.
|
||||
If you need help running the tests or submitting your code, check out `HELP.md`.
|
||||
|
||||
## Instructions
|
||||
|
||||
Calculate the Hamming Distance between two DNA strands.
|
||||
|
||||
Your body is made up of cells that contain DNA. Those cells regularly wear out and need replacing, which they achieve by dividing into daughter cells. In fact, the average human body experiences about 10 quadrillion cell divisions in a lifetime!
|
||||
|
||||
When cells divide, their DNA replicates too. Sometimes during this process mistakes happen and single pieces of DNA get encoded with the incorrect information. If we compare two strands of DNA and count the differences between them we can see how many mistakes occurred. This is known as the "Hamming Distance".
|
||||
|
||||
We read DNA using the letters C,A,G and T. Two strands might look like this:
|
||||
|
||||
GAGCCTACTAACGGGAT
|
||||
CATCGTAATGACGGCCT
|
||||
^ ^ ^ ^ ^ ^^
|
||||
|
||||
They have 7 differences, and therefore the Hamming Distance is 7.
|
||||
|
||||
The Hamming Distance is useful for lots of things in science, not just biology, so it's a nice phrase to be familiar with :)
|
||||
|
||||
The Hamming distance is only defined for sequences of equal length, so
|
||||
an attempt to calculate it between sequences of different lengths should
|
||||
not work. The general handling of this situation (e.g., raising an
|
||||
exception vs returning a special value) may differ between languages.
|
||||
|
||||
## Source
|
||||
|
||||
### Contributed to by
|
||||
|
||||
- @daveyarwood
|
||||
- @dvberkel
|
||||
- @iHiD
|
||||
- @kytrinyx
|
||||
- @marionebl
|
||||
- @Peaupote
|
||||
- @sbl
|
||||
- @sshine
|
||||
- @stevejb71
|
||||
- @tmcgilchrist
|
||||
|
||||
### Based on
|
||||
|
||||
The Calculating Point Mutations problem at Rosalind - http://rosalind.info/problems/hamm/
|
16
hamming/dune
Normal file
16
hamming/dune
Normal file
|
@ -0,0 +1,16 @@
|
|||
(executable
|
||||
(name test)
|
||||
(libraries base ounit2))
|
||||
|
||||
(alias
|
||||
(name runtest)
|
||||
(deps (:x test.exe))
|
||||
(action (run %{x})))
|
||||
|
||||
(alias
|
||||
(name buildtest)
|
||||
(deps (:x test.exe)))
|
||||
|
||||
(env
|
||||
(dev
|
||||
(flags (:standard -warn-error -A))))
|
2
hamming/dune-project
Normal file
2
hamming/dune-project
Normal file
|
@ -0,0 +1,2 @@
|
|||
(lang dune 1.1)
|
||||
(version 2.3.0)
|
17
hamming/hamming.ml
Normal file
17
hamming/hamming.ml
Normal file
|
@ -0,0 +1,17 @@
|
|||
open Base
|
||||
|
||||
type nucleotide = A | C | G | T
|
||||
|
||||
let toint = function
|
||||
| A -> 0
|
||||
| C -> 1
|
||||
| G -> 2
|
||||
| T -> 3
|
||||
|
||||
let hamming_distance a b = match (a, b) with
|
||||
| [], [] -> Ok 0
|
||||
| [], _ -> Error "left strand must not be empty"
|
||||
| _, [] -> Error "right strand must not be empty"
|
||||
| l1, l2 -> match List.zip l1 l2 with
|
||||
| Ok res -> Ok (List.filter ~f:(fun (x, y) -> (toint x) <> (toint y)) res |> List.length)
|
||||
| Unequal_lengths -> Error "left and right strands must be of equal length"
|
6
hamming/hamming.mli
Normal file
6
hamming/hamming.mli
Normal file
|
@ -0,0 +1,6 @@
|
|||
open Base
|
||||
|
||||
type nucleotide = A | C | G | T
|
||||
|
||||
(** Compute the hamming distance between the two lists. *)
|
||||
val hamming_distance : nucleotide list -> nucleotide list -> (int, string) Result.t
|
45
hamming/test.ml
Normal file
45
hamming/test.ml
Normal file
|
@ -0,0 +1,45 @@
|
|||
(* hamming - 2.3.0 *)
|
||||
open Base
|
||||
open OUnit2
|
||||
open Hamming
|
||||
|
||||
let printer = function
|
||||
| Error m -> "Error \"" ^ m ^ "\""
|
||||
| Ok x -> "Ok " ^ (Int.to_string x)
|
||||
|
||||
let ae exp got _test_ctxt = assert_equal ~printer exp got
|
||||
|
||||
let dna_of_string s =
|
||||
let f = function
|
||||
| 'A' -> A
|
||||
| 'C' -> C
|
||||
| 'G' -> G
|
||||
| 'T' -> T
|
||||
| _ -> failwith "Big news! New nucleotide discovered" in
|
||||
String.to_list s |> List.map ~f
|
||||
|
||||
let hamdist a b = hamming_distance (dna_of_string a) (dna_of_string b)
|
||||
|
||||
let tests = [
|
||||
"empty strands" >::
|
||||
ae (Ok 0) (hamdist "" "");
|
||||
"single letter identical strands" >::
|
||||
ae (Ok 0) (hamdist "A" "A");
|
||||
"single letter different strands" >::
|
||||
ae (Ok 1) (hamdist "G" "T");
|
||||
"long identical strands" >::
|
||||
ae (Ok 0) (hamdist "GGACTGAAATCTG" "GGACTGAAATCTG");
|
||||
"long different strands" >::
|
||||
ae (Ok 9) (hamdist "GGACGGATTCTG" "AGGACGGATTCT");
|
||||
"disallow first strand longer" >::
|
||||
ae (Error "left and right strands must be of equal length") (hamdist "AATG" "AAA");
|
||||
"disallow second strand longer" >::
|
||||
ae (Error "left and right strands must be of equal length") (hamdist "ATA" "AGTG");
|
||||
"disallow left empty strand" >::
|
||||
ae (Error "left strand must not be empty") (hamdist "" "G");
|
||||
"disallow right empty strand" >::
|
||||
ae (Error "right strand must not be empty") (hamdist "G" "");
|
||||
]
|
||||
|
||||
let () =
|
||||
run_test_tt_main ("hamming tests" >::: tests)
|
Loading…
Add table
Reference in a new issue