This commit is contained in:
Vladan Popovic 2024-01-13 13:17:01 +01:00
parent cf4f118c22
commit 59b82ee023
8 changed files with 177 additions and 0 deletions

36
hamming/HELP.md Normal file
View 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
View File

@ -0,0 +1,9 @@
default: clean test
test:
dune runtest
clean:
dune clean
.PHONY: clean

46
hamming/README.md Normal file
View 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
View 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
View File

@ -0,0 +1,2 @@
(lang dune 1.1)
(version 2.3.0)

17
hamming/hamming.ml Normal file
View 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
View 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
View 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)