diff --git a/exercises/practice/hamming/.docs/instructions.md b/exercises/practice/hamming/.docs/instructions.md new file mode 100644 index 0000000..2a48cf4 --- /dev/null +++ b/exercises/practice/hamming/.docs/instructions.md @@ -0,0 +1,27 @@ +# Description + +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 :) + +## Implementation notes + +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. diff --git a/exercises/practice/hamming/.meta/Example.bat b/exercises/practice/hamming/.meta/Example.bat new file mode 100644 index 0000000..7e6c64b --- /dev/null +++ b/exercises/practice/hamming/.meta/Example.bat @@ -0,0 +1,43 @@ +@echo off +setlocal enabledelayedexpansion + +call :getLength "%~1" len[1] +call :getLength "%~2" len[2] + +if "%len[1]%" NEQ "%len[2]%" ( + if "%len[1]%" EQU "0" ( + echo left strand must not be empty + exit /b 1 + ) + if "%len[2]%" EQU "0" ( + echo right strand must not be empty + exit /b 1 + ) + echo left and right strands must be of equal length + exit /b 1 +) + +set "string[1]=%~1" +set "string[2]=%~2" +set /a distance=0 +for /L %%A in (0,1,%len[1]%) do ( + if not "!string[1]:~%%A,1!"=="!string[2]:~%%A,1!" ( + set /a distance+=1 + ) +) +echo !distance! + +exit /b + +:getLength +setlocal EnableDelayedExpansion +set "s=#%~1" +set "len=0" +for %%N in (4096 2048 1024 512 256 128 64 32 16 8 4 2 1) do ( + if "!s:~%%N,1!" neq "" ( + set /a "len+=%%N" + set "s=!s:~%%N!" + ) +) +endlocal&if "%~2" neq "" (set %~2=%len%) else echo %len% +exit /b diff --git a/exercises/practice/hamming/.meta/config.json b/exercises/practice/hamming/.meta/config.json new file mode 100644 index 0000000..134edfe --- /dev/null +++ b/exercises/practice/hamming/.meta/config.json @@ -0,0 +1,17 @@ +{ + "authors": ["sintrode", "GroophyLifefor"], + "files": { + "solution": [ + "Hamming.bat" + ], + "test": [ + "HammingTest.bat" + ], + "example": [ + ".meta/Example.bat" + ] + }, + "blurb": "Calculate the Hamming difference between two DNA strands.", + "source": "The Calculating Point Mutations problem at Rosalind", + "source_url": "https://rosalind.info/problems/hamm/" +} diff --git a/exercises/practice/hamming/.meta/tests.toml b/exercises/practice/hamming/.meta/tests.toml new file mode 100644 index 0000000..73466d6 --- /dev/null +++ b/exercises/practice/hamming/.meta/tests.toml @@ -0,0 +1,13 @@ +# This is an auto-generated file. +# +# Regenerating this file via `configlet sync` will: +# - Recreate every `description` key/value pair +# - Recreate every `reimplements` key/value pair, where they exist in problem-specifications +# - Remove any `include = true` key/value pair (an omitted `include` key implies inclusion) +# - Preserve any other key/value pair +# +# As user-added comments (using the # character) will be removed when this file +# is regenerated, comments can be added via a `comment` key. + +[af9ffe10-dc13-42d8-a742-e7bdafac449d] +description = "Say Hi!" diff --git a/exercises/practice/hamming/Hamming.bat b/exercises/practice/hamming/Hamming.bat new file mode 100644 index 0000000..a86c8fb --- /dev/null +++ b/exercises/practice/hamming/Hamming.bat @@ -0,0 +1,11 @@ +@echo off +setlocal enabledelayedexpansion + +set "row1=%~1" +set "row2=%~2" +set "result=" + +REM Your code goes here + + +echo %result% diff --git a/exercises/practice/hamming/HammingTest.bat b/exercises/practice/hamming/HammingTest.bat new file mode 100644 index 0000000..9f8a4f5 --- /dev/null +++ b/exercises/practice/hamming/HammingTest.bat @@ -0,0 +1,131 @@ +@echo off +REM --------------------------------------------------- +REM Hamming Unit Testing +REM +REM sUnit Testing Framework version: 0.2 +REM --------------------------------------------------- + +:Main + REM Initalize result variable + set "slug=Hamming" + + CALL :Initialize + + REM -------------------- + REM Test Case Start \/\/ + REM Resource: https://github.com/exercism/problem-specifications/blob/main/exercises/hamming/canonical-data.json + REM -------------------- + set "expected=0" + set "if_success=Test passed" + set "if_failed=Test failed: empty strands." + CALL :Assert "" "" + + set "expected=0" + set "if_success=Test passed" + set "if_failed=Test failed: single letter identical strands." + CALL :Assert "A" "A" + + set "expected=1" + set "if_success=Test passed" + set "if_failed=Test failed: single letter different strands." + CALL :Assert "G" "T" + + set "expected=0" + set "if_success=Test passed" + set "if_failed=Test failed: long identical strands." + CALL :Assert "GGACTGAAATCTG" "GGACTGAAATCTG" + + set "expected=9" + set "if_success=Test passed" + set "if_failed=Test failed: long different strands." + CALL :Assert "GGACGGATTCTG" "AGGACGGATTCT" + + set "expected=left and right strands must be of equal length" + set "if_success=Test passed" + set "if_failed=Test failed: disallow first strand longer." + CALL :Assert "AATG" "AAA" + + set "expected=left and right strands must be of equal length" + set "if_success=Test passed" + set "if_failed=Test failed: disallow second strand longer." + CALL :Assert "ATA" "AGTG" + + set "expected=left strand must not be empty" + set "if_success=Test passed" + set "if_failed=Test failed: disallow left empty strand." + CALL :Assert "" "G" + + set "expected=right strand must not be empty" + set "if_success=Test passed" + set "if_failed=Test failed: disallow right empty strand." + CALL :Assert "G" "" + + REM -------------------- + REM Test Case End /\/\/\ + REM -------------------- + + CALL :ResolveStatus + exit /b %errorlevel% +REM End of Main + +REM --------------------------------------------------- +REM Assert [..Parameters(up to 9)] +REM --------------------------------------------------- +GOTO :End REM Prevents the code below from being executed +:Assert +set "stdout=" + +REM Run the program and capture the output then delete the file +CALL %slug%.bat %1 %2 %3 %4 %5 %6 %7 %8 %9 > stdout.bin 2>&1 +set /p stdout=