add dev scafold and day 1 solution

This commit is contained in:
Vladan Popovic 2022-12-01 23:45:12 +01:00
parent 49e961c0fd
commit 739b24dfbe
15 changed files with 2631 additions and 0 deletions

2
.ocamlformat Normal file
View file

@ -0,0 +1,2 @@
profile = default
version = 0.24.1

12
LICENCE Normal file
View file

@ -0,0 +1,12 @@
Copyright (C) 2022 by vladan
Permission to use, copy, modify, and/or distribute this software for any purpose
with or without fee is hereby granted.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
THIS SOFTWARE.

13
README.md Normal file
View file

@ -0,0 +1,13 @@
# Advent of Code 2022 solutions in OCaml
To run the a single day you'd need to run a nix development shell with:
```
$ nix develop
```
And then call the executable for e.g. day 1:
```
$ dune exec d1
```

4
bin/d1/dune Normal file
View file

@ -0,0 +1,4 @@
(executable
(public_name d1)
(name main)
(libraries core utils))

2267
bin/d1/input.txt Normal file

File diff suppressed because it is too large Load diff

21
bin/d1/main.ml Normal file
View file

@ -0,0 +1,21 @@
let sum_callories input =
let rec aux elv res = function
| [] -> elv :: res
| x :: xs -> if x = "" then aux 0 (elv :: res) xs
else aux (elv + (int_of_string x)) res xs in
aux 0 [] input
open Utils
let summed = read_file "bin/d1/input.txt"
|> sum_callories
|> List.sort compare
|> List.rev ;;
open Core
let first = List.hd summed |> Option.value ~default:0 ;;
let second = List.take summed 3 |> List.fold ~init:0 ~f:(+) ;;
"\n1: " ^ (string_of_int first) ^
"\n2: " ^ (string_of_int second) |> print_endline

3
bin/dune Normal file
View file

@ -0,0 +1,3 @@
(executable
(public_name aoc2022)
(name main))

3
bin/main.ml Normal file
View file

@ -0,0 +1,3 @@
print_endline "\n" ;;
print_endline "Nothing here. You can run an executable for a single day with:" ;;
print_endline "dune exec d1" ;;

23
dune-project Normal file
View file

@ -0,0 +1,23 @@
(lang dune 3.2)
(name aoc2022)
(generate_opam_files false)
(source
(uri https://gitea.vp.mk/vladan/aoc2022))
(authors "Vladan Popovic")
(maintainers "Vladan Popovic")
(license LICENSE)
(package
(name aoc2022)
(synopsis "Advent of Code 2022 solutions in OCaml")
(description "Advent of Code 2022 solutions in OCaml")
(depends ocaml dune)
(tags
(AoC2022 "Advent of Code")))
; See the complete stanza docs at https://dune.readthedocs.io/en/stable/dune-files.html#dune-project

57
flake.lock Normal file
View 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
}

211
flake.nix Normal file
View file

@ -0,0 +1,211 @@
{
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}.aoc2022;
aoc2022 = ocamlPackages.buildDunePackage {
pname = "aoc2022";
version = "0.1.0";
duneVersion = "3";
src = sources.ocaml;
strictDeps = true;
preBuild = ''
dune build aoc2022.opam
'';
};
};
# Flake checks
#
# $ nix flake check
#
checks = {
# Run tests for the `aoc2022` package
aoc2022 =
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}.aoc2022.overrideAttrs
(oldAttrs: {
name = "check-${oldAttrs.name}";
doCheck = true;
buildPhase = patchDuneCommand oldAttrs.buildPhase;
checkPhase = patchDuneCommand oldAttrs.checkPhase;
# skip installation (this will be tested in the `aoc2022-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.core
];
# Tools from packages
inputsFrom = [
self.packages.${system}.aoc2022
];
};
};
});
}

2
lib/dune Normal file
View file

@ -0,0 +1,2 @@
(library
(name utils))

11
lib/utils.ml Normal file
View file

@ -0,0 +1,11 @@
let read_file name =
let ic = open_in name in
let try_read () =
try Some (input_line ic)
with End_of_file -> None in
let rec aux acc =
match try_read () with
| Some s -> aux (s::acc)
| None -> close_in ic; acc in
aux []

0
test/aoc2022.ml Normal file
View file

2
test/dune Normal file
View file

@ -0,0 +1,2 @@
(test
(name aoc2022))