first two easy exercises
This commit is contained in:
commit
8c221fed78
20 changed files with 562 additions and 0 deletions
4
.envrc
Normal file
4
.envrc
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
# shellcheck shell=bash
|
||||||
|
# For use with direnv.
|
||||||
|
# Installing nix-direnv will ensure a smoother experience.
|
||||||
|
use flake
|
23
dune-project
Normal file
23
dune-project
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
(lang dune 3.2)
|
||||||
|
|
||||||
|
(name exercism)
|
||||||
|
|
||||||
|
(generate_opam_files false)
|
||||||
|
|
||||||
|
(source
|
||||||
|
(uri https://gitea.vp.mk/vladan/exercism))
|
||||||
|
|
||||||
|
(authors "Vladan Popovic")
|
||||||
|
(maintainers "Vladan Popovic")
|
||||||
|
|
||||||
|
(license LICENSE)
|
||||||
|
|
||||||
|
(package
|
||||||
|
(name exercism)
|
||||||
|
(synopsis "Exercism OCaml exercises")
|
||||||
|
(description "Exercism OCaml exercises")
|
||||||
|
(depends ocaml dune)
|
||||||
|
(tags
|
||||||
|
(exercism "Exercism OCaml exercises")))
|
||||||
|
|
||||||
|
; See the complete stanza docs at https://dune.readthedocs.io/en/stable/dune-files.html#dune-project
|
57
flake.lock
Normal file
57
flake.lock
Normal file
|
@ -0,0 +1,57 @@
|
||||||
|
{
|
||||||
|
"nodes": {
|
||||||
|
"flake-utils": {
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1667395993,
|
||||||
|
"narHash": "sha256-nuEHfE/LcWyuSWnS8t12N1wc105Qtau+/OdUAjtQ0rA=",
|
||||||
|
"owner": "numtide",
|
||||||
|
"repo": "flake-utils",
|
||||||
|
"rev": "5aed5285a952e0b949eb3ba02c12fa4fcfef535f",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "numtide",
|
||||||
|
"repo": "flake-utils",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"nix-filter": {
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1666547822,
|
||||||
|
"narHash": "sha256-razwnAybPHyoAyhkKCwXdxihIqJi1G6e1XP4FQOJTEs=",
|
||||||
|
"owner": "numtide",
|
||||||
|
"repo": "nix-filter",
|
||||||
|
"rev": "1a3b735e13e90a8d2fd5629f2f8363bd7ffbbec7",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "numtide",
|
||||||
|
"repo": "nix-filter",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"nixpkgs": {
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1669867399,
|
||||||
|
"narHash": "sha256-Z8RXSFYOsIsTG96ROKtV0eZ8Q7u4irFWm6ELqfw7mT8=",
|
||||||
|
"owner": "NixOS",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"rev": "38e591dd05ffc8bdf79dc752ba78b05e370416fa",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"id": "nixpkgs",
|
||||||
|
"type": "indirect"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"root": {
|
||||||
|
"inputs": {
|
||||||
|
"flake-utils": "flake-utils",
|
||||||
|
"nix-filter": "nix-filter",
|
||||||
|
"nixpkgs": "nixpkgs"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"root": "root",
|
||||||
|
"version": 7
|
||||||
|
}
|
214
flake.nix
Normal file
214
flake.nix
Normal file
|
@ -0,0 +1,214 @@
|
||||||
|
{
|
||||||
|
description = "A flake demonstrating how to build OCaml projects with Dune";
|
||||||
|
|
||||||
|
# Flake dependency specification
|
||||||
|
#
|
||||||
|
# To update all flake inputs:
|
||||||
|
#
|
||||||
|
# $ nix flake update --commit-lockfile
|
||||||
|
#
|
||||||
|
# To update individual flake inputs:
|
||||||
|
#
|
||||||
|
# $ nix flake lock --update-input <input> ... --commit-lockfile
|
||||||
|
#
|
||||||
|
inputs = {
|
||||||
|
# Convenience functions for writing flakes
|
||||||
|
flake-utils.url = "github:numtide/flake-utils";
|
||||||
|
# Precisely filter files copied to the nix store
|
||||||
|
nix-filter.url = "github:numtide/nix-filter";
|
||||||
|
};
|
||||||
|
|
||||||
|
outputs = { self, nixpkgs, flake-utils, nix-filter }:
|
||||||
|
# Construct an output set that supports a number of default systems
|
||||||
|
flake-utils.lib.eachDefaultSystem (system:
|
||||||
|
let
|
||||||
|
# Legacy packages that have not been converted to flakes
|
||||||
|
legacyPackages = nixpkgs.legacyPackages.${system};
|
||||||
|
# OCaml packages available on nixpkgs
|
||||||
|
ocamlPackages = legacyPackages.ocamlPackages;
|
||||||
|
# Library functions from nixpkgs
|
||||||
|
lib = legacyPackages.lib;
|
||||||
|
|
||||||
|
# Filtered sources (prevents unecessary rebuilds)
|
||||||
|
sources = {
|
||||||
|
ocaml = nix-filter.lib {
|
||||||
|
root = ./.;
|
||||||
|
include = [
|
||||||
|
".ocamlformat"
|
||||||
|
"dune-project"
|
||||||
|
(nix-filter.lib.inDirectory "bin")
|
||||||
|
(nix-filter.lib.inDirectory "lib")
|
||||||
|
(nix-filter.lib.inDirectory "test")
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
nix = nix-filter.lib {
|
||||||
|
root = ./.;
|
||||||
|
include = [
|
||||||
|
(nix-filter.lib.matchExt "nix")
|
||||||
|
];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
in
|
||||||
|
{
|
||||||
|
# Exposed packages that can be built or run with `nix build` or
|
||||||
|
# `nix run` respectively:
|
||||||
|
#
|
||||||
|
# $ nix build .#<name>
|
||||||
|
# $ nix run .#<name> -- <args?>
|
||||||
|
#
|
||||||
|
packages = {
|
||||||
|
# The package that will be built or run by default. For example:
|
||||||
|
#
|
||||||
|
# $ nix build
|
||||||
|
# $ nix run -- <args?>
|
||||||
|
#
|
||||||
|
default = self.packages.${system}.exercism;
|
||||||
|
|
||||||
|
exercism = ocamlPackages.buildDunePackage {
|
||||||
|
pname = "exercism";
|
||||||
|
version = "0.1.0";
|
||||||
|
duneVersion = "3";
|
||||||
|
src = sources.ocaml;
|
||||||
|
|
||||||
|
strictDeps = true;
|
||||||
|
|
||||||
|
preBuild = ''
|
||||||
|
dune build exercism.opam
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
# Flake checks
|
||||||
|
#
|
||||||
|
# $ nix flake check
|
||||||
|
#
|
||||||
|
checks = {
|
||||||
|
# Run tests for the `exercism` package
|
||||||
|
exercism =
|
||||||
|
let
|
||||||
|
# Patches calls to dune commands to produce log-friendly output
|
||||||
|
# when using `nix ... --print-build-log`. Ideally there would be
|
||||||
|
# support for one or more of the following:
|
||||||
|
#
|
||||||
|
# In Dune:
|
||||||
|
#
|
||||||
|
# - have workspace-specific dune configuration files
|
||||||
|
#
|
||||||
|
# In NixPkgs:
|
||||||
|
#
|
||||||
|
# - allow dune flags to be set in in `ocamlPackages.buildDunePackage`
|
||||||
|
# - alter `ocamlPackages.buildDunePackage` to use `--display=short`
|
||||||
|
# - alter `ocamlPackages.buildDunePackage` to allow `--config-file=FILE` to be set
|
||||||
|
patchDuneCommand =
|
||||||
|
let
|
||||||
|
subcmds = [ "build" "test" "runtest" "install" ];
|
||||||
|
in
|
||||||
|
lib.replaceStrings
|
||||||
|
(lib.lists.map (subcmd: "dune ${subcmd}") subcmds)
|
||||||
|
(lib.lists.map (subcmd: "dune ${subcmd} --display=short") subcmds);
|
||||||
|
in
|
||||||
|
|
||||||
|
self.packages.${system}.exercism.overrideAttrs
|
||||||
|
(oldAttrs: {
|
||||||
|
name = "check-${oldAttrs.name}";
|
||||||
|
doCheck = true;
|
||||||
|
buildPhase = patchDuneCommand oldAttrs.buildPhase;
|
||||||
|
checkPhase = patchDuneCommand oldAttrs.checkPhase;
|
||||||
|
# skip installation (this will be tested in the `exercism-app` check)
|
||||||
|
installPhase = "touch $out";
|
||||||
|
});
|
||||||
|
|
||||||
|
# Check Dune and OCaml formatting
|
||||||
|
dune-fmt = legacyPackages.runCommand "check-dune-fmt"
|
||||||
|
{
|
||||||
|
nativeBuildInputs = [
|
||||||
|
ocamlPackages.dune_3
|
||||||
|
ocamlPackages.ocaml
|
||||||
|
legacyPackages.ocamlformat
|
||||||
|
];
|
||||||
|
}
|
||||||
|
''
|
||||||
|
echo "checking dune and ocaml formatting"
|
||||||
|
dune build \
|
||||||
|
--display=short \
|
||||||
|
--no-print-directory \
|
||||||
|
--root="${sources.ocaml}" \
|
||||||
|
--build-dir="$(pwd)/_build" \
|
||||||
|
@fmt
|
||||||
|
touch $out
|
||||||
|
'';
|
||||||
|
|
||||||
|
# Check documentation generation
|
||||||
|
dune-doc = legacyPackages.runCommand "check-dune-doc"
|
||||||
|
{
|
||||||
|
ODOC_WARN_ERROR = "true";
|
||||||
|
nativeBuildInputs = [
|
||||||
|
ocamlPackages.dune_3
|
||||||
|
ocamlPackages.ocaml
|
||||||
|
ocamlPackages.odoc
|
||||||
|
];
|
||||||
|
}
|
||||||
|
''
|
||||||
|
echo "checking ocaml documentation"
|
||||||
|
dune build \
|
||||||
|
--display=short \
|
||||||
|
--no-print-directory \
|
||||||
|
--root="${sources.ocaml}" \
|
||||||
|
--build-dir="$(pwd)/_build" \
|
||||||
|
@doc
|
||||||
|
touch $out
|
||||||
|
'';
|
||||||
|
|
||||||
|
# Check Nix formatting
|
||||||
|
nixpkgs-fmt = legacyPackages.runCommand "check-nixpkgs-fmt"
|
||||||
|
{ nativeBuildInputs = [ legacyPackages.nixpkgs-fmt ]; }
|
||||||
|
''
|
||||||
|
echo "checking nix formatting"
|
||||||
|
nixpkgs-fmt --check ${sources.nix}
|
||||||
|
touch $out
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
# Development shells
|
||||||
|
#
|
||||||
|
# $ nix develop .#<name>
|
||||||
|
# $ nix develop .#<name> --command dune build @test
|
||||||
|
#
|
||||||
|
# [Direnv](https://direnv.net/) is recommended for automatically loading
|
||||||
|
# development environments in your shell. For example:
|
||||||
|
#
|
||||||
|
# $ echo "use flake" > .envrc && direnv allow
|
||||||
|
# $ dune build @test
|
||||||
|
#
|
||||||
|
devShells = {
|
||||||
|
default = legacyPackages.mkShell {
|
||||||
|
# Development tools
|
||||||
|
packages = [
|
||||||
|
# Source file formatting
|
||||||
|
legacyPackages.nixpkgs-fmt
|
||||||
|
legacyPackages.ocamlformat
|
||||||
|
# For `dune build --watch ...`
|
||||||
|
legacyPackages.fswatch
|
||||||
|
# For `dune build @doc`
|
||||||
|
ocamlPackages.odoc
|
||||||
|
# OCaml editor support
|
||||||
|
ocamlPackages.ocaml-lsp
|
||||||
|
# Nicely formatted types on hover
|
||||||
|
ocamlPackages.ocamlformat-rpc-lib
|
||||||
|
# Fancy REPL thing
|
||||||
|
ocamlPackages.utop
|
||||||
|
ocamlPackages.angstrom
|
||||||
|
ocamlPackages.ounit
|
||||||
|
ocamlPackages.ounit2
|
||||||
|
ocamlPackages.ppx_sexp_conv
|
||||||
|
];
|
||||||
|
|
||||||
|
# Tools from packages
|
||||||
|
inputsFrom = [
|
||||||
|
self.packages.${system}.exercism
|
||||||
|
];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
});
|
||||||
|
}
|
36
hello-world/HELP.md
Normal file
36
hello-world/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 hello_world.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
hello-world/Makefile
Normal file
9
hello-world/Makefile
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
default: clean test
|
||||||
|
|
||||||
|
test:
|
||||||
|
dune runtest
|
||||||
|
|
||||||
|
clean:
|
||||||
|
dune clean
|
||||||
|
|
||||||
|
.PHONY: clean
|
42
hello-world/README.md
Normal file
42
hello-world/README.md
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
# Hello World
|
||||||
|
|
||||||
|
Welcome to Hello World on Exercism's OCaml Track.
|
||||||
|
If you need help running the tests or submitting your code, check out `HELP.md`.
|
||||||
|
|
||||||
|
## Instructions
|
||||||
|
|
||||||
|
The classical introductory exercise.
|
||||||
|
Just say "Hello, World!".
|
||||||
|
|
||||||
|
["Hello, World!"][hello-world] is the traditional first program for beginning programming in a new language or environment.
|
||||||
|
|
||||||
|
The objectives are simple:
|
||||||
|
|
||||||
|
- Modify the provided code so that it produces the string "Hello, World!".
|
||||||
|
- Run the test suite and make sure that it succeeds.
|
||||||
|
- Submit your solution and check it at the website.
|
||||||
|
|
||||||
|
If everything goes well, you will be ready to fetch your first real exercise.
|
||||||
|
|
||||||
|
[hello-world]: https://en.wikipedia.org/wiki/%22Hello,_world!%22_program
|
||||||
|
|
||||||
|
## Source
|
||||||
|
|
||||||
|
### Created by
|
||||||
|
|
||||||
|
- @dvberkel
|
||||||
|
|
||||||
|
### Contributed to by
|
||||||
|
|
||||||
|
- @daveyarwood
|
||||||
|
- @iHiD
|
||||||
|
- @kytrinyx
|
||||||
|
- @marionebl
|
||||||
|
- @Peaupote
|
||||||
|
- @sbl
|
||||||
|
- @sshine
|
||||||
|
- @stevejb71
|
||||||
|
|
||||||
|
### Based on
|
||||||
|
|
||||||
|
This is an exercise to introduce users to using Exercism - https://en.wikipedia.org/wiki/%22Hello,_world!%22_program
|
16
hello-world/dune
Normal file
16
hello-world/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))))
|
1
hello-world/dune-project
Normal file
1
hello-world/dune-project
Normal file
|
@ -0,0 +1 @@
|
||||||
|
(lang dune 1.1)
|
1
hello-world/hello_world.ml
Normal file
1
hello-world/hello_world.ml
Normal file
|
@ -0,0 +1 @@
|
||||||
|
let hello = "Hello, World!"
|
4
hello-world/hello_world.mli
Normal file
4
hello-world/hello_world.mli
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
(*
|
||||||
|
Returns "Hello, World!"
|
||||||
|
*)
|
||||||
|
val hello: string
|
11
hello-world/test.ml
Normal file
11
hello-world/test.ml
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
open OUnit2
|
||||||
|
open Hello_world
|
||||||
|
|
||||||
|
let ae exp got _test_ctxt = assert_equal ~printer:(fun x -> x) exp got
|
||||||
|
|
||||||
|
let tests = [
|
||||||
|
"Say Hi!" >:: ae "Hello, World!" hello;
|
||||||
|
]
|
||||||
|
|
||||||
|
let () =
|
||||||
|
run_test_tt_main ("Hello World tests" >::: tests)
|
36
leap/HELP.md
Normal file
36
leap/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 leap.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
leap/Makefile
Normal file
9
leap/Makefile
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
default: clean test
|
||||||
|
|
||||||
|
test:
|
||||||
|
dune runtest
|
||||||
|
|
||||||
|
clean:
|
||||||
|
dune clean
|
||||||
|
|
||||||
|
.PHONY: clean
|
51
leap/README.md
Normal file
51
leap/README.md
Normal file
|
@ -0,0 +1,51 @@
|
||||||
|
# Leap
|
||||||
|
|
||||||
|
Welcome to Leap on Exercism's OCaml Track.
|
||||||
|
If you need help running the tests or submitting your code, check out `HELP.md`.
|
||||||
|
|
||||||
|
## Instructions
|
||||||
|
|
||||||
|
Given a year, report if it is a leap year.
|
||||||
|
|
||||||
|
The tricky thing here is that a leap year in the Gregorian calendar occurs:
|
||||||
|
|
||||||
|
```text
|
||||||
|
on every year that is evenly divisible by 4
|
||||||
|
except every year that is evenly divisible by 100
|
||||||
|
unless the year is also evenly divisible by 400
|
||||||
|
```
|
||||||
|
|
||||||
|
For example, 1997 is not a leap year, but 1996 is.
|
||||||
|
1900 is not a leap year, but 2000 is.
|
||||||
|
|
||||||
|
## Notes
|
||||||
|
|
||||||
|
Though our exercise adopts some very simple rules, there is more to learn!
|
||||||
|
|
||||||
|
For a delightful, four minute explanation of the whole leap year phenomenon, go watch [this youtube video][video].
|
||||||
|
|
||||||
|
[video]: https://www.youtube.com/watch?v=xX96xng7sAE
|
||||||
|
|
||||||
|
## Source
|
||||||
|
|
||||||
|
### Created by
|
||||||
|
|
||||||
|
- @tmcgilchrist
|
||||||
|
|
||||||
|
### Contributed to by
|
||||||
|
|
||||||
|
- @daveyarwood
|
||||||
|
- @dvberkel
|
||||||
|
- @iHiD
|
||||||
|
- @ismaelga
|
||||||
|
- @kytrinyx
|
||||||
|
- @marionebl
|
||||||
|
- @Peaupote
|
||||||
|
- @pminten
|
||||||
|
- @sbl
|
||||||
|
- @sshine
|
||||||
|
- @stevejb71
|
||||||
|
|
||||||
|
### Based on
|
||||||
|
|
||||||
|
CodeRanch Cattle Drive, Assignment 3 - https://coderanch.com/t/718816/Leap
|
16
leap/dune
Normal file
16
leap/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))))
|
1
leap/dune-project
Normal file
1
leap/dune-project
Normal file
|
@ -0,0 +1 @@
|
||||||
|
(lang dune 1.1)
|
2
leap/leap.ml
Normal file
2
leap/leap.ml
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
let leap_year year =
|
||||||
|
(year mod 4 = 0 && year mod 100 <> 0) || year mod 400 = 0
|
1
leap/leap.mli
Normal file
1
leap/leap.mli
Normal file
|
@ -0,0 +1 @@
|
||||||
|
val leap_year: int -> bool
|
28
leap/test.ml
Normal file
28
leap/test.ml
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
open OUnit2
|
||||||
|
open Leap
|
||||||
|
|
||||||
|
let ae exp got _test_ctxt = assert_equal exp got ~printer:string_of_bool
|
||||||
|
|
||||||
|
let tests = [
|
||||||
|
"year not divisible by 4 in common year" >::
|
||||||
|
ae false (leap_year 2015);
|
||||||
|
"year divisible by 2, not divisible by 4 in common year" >::
|
||||||
|
ae false (leap_year 1970);
|
||||||
|
"year divisible by 4, not divisible by 100 in leap year" >::
|
||||||
|
ae true (leap_year 1996);
|
||||||
|
"year divisible by 4 and 5 is still a leap year" >::
|
||||||
|
ae true (leap_year 1960);
|
||||||
|
"year divisible by 100, not divisible by 400 in common year" >::
|
||||||
|
ae false (leap_year 2100);
|
||||||
|
"year divisible by 100 but not by 3 is still not a leap year" >::
|
||||||
|
ae false (leap_year 1900);
|
||||||
|
"year divisible by 400 is leap year" >::
|
||||||
|
ae true (leap_year 2000);
|
||||||
|
"year divisible by 400 but not by 125 is still a leap year" >::
|
||||||
|
ae true (leap_year 2400);
|
||||||
|
"year divisible by 200, not divisible by 400 in common year" >::
|
||||||
|
ae false (leap_year 1800);
|
||||||
|
]
|
||||||
|
|
||||||
|
let () =
|
||||||
|
run_test_tt_main ("leap tests" >::: tests)
|
Loading…
Reference in a new issue