├── .github └── workflows │ └── contributors.yml ├── .gitignore ├── LICENSE ├── README.md ├── docs ├── INSTRUCTIONS.md ├── exercise │ ├── day01 │ │ ├── challenge.md │ │ ├── snippet.png │ │ └── solution │ │ │ ├── challenge-done.md │ │ │ ├── img │ │ │ ├── extract-method.png │ │ │ └── simplify-if-else.png │ │ │ ├── snippet.png │ │ │ └── step-by-step.md │ ├── day02 │ │ ├── challenge.md │ │ ├── snippet.png │ │ └── solution │ │ │ ├── challenge-done.md │ │ │ ├── img │ │ │ ├── invert-if.png │ │ │ ├── invert-second-if.png │ │ │ └── remove-redundant-else.png │ │ │ ├── snippet.png │ │ │ └── step-by-step.md │ ├── day03 │ │ ├── challenge.md │ │ ├── snippet.png │ │ └── solution │ │ │ ├── challenge-done.md │ │ │ ├── img │ │ │ ├── define-automatic-suggestions.png │ │ │ ├── define-practice.png │ │ │ ├── explanations.png │ │ │ ├── extract-method.png │ │ │ ├── ide-help.png │ │ │ ├── line-returns.png │ │ │ ├── no-more-rockets.png │ │ │ └── promyze-detection.png │ │ │ ├── snippet.png │ │ │ └── step-by-step.md │ ├── day04 │ │ ├── challenge.md │ │ ├── snippet.png │ │ └── solution │ │ │ ├── challenge-done.md │ │ │ ├── snippet.png │ │ │ └── step-by-step.md │ ├── day05 │ │ ├── challenge.md │ │ ├── snippet.png │ │ └── solution │ │ │ ├── challenge-done.md │ │ │ ├── img │ │ │ ├── extract-method.png │ │ │ ├── extract-variable.png │ │ │ └── foreach.png │ │ │ ├── snippet.png │ │ │ └── step-by-step.md │ ├── day06 │ │ ├── challenge.md │ │ ├── snippet.png │ │ └── solution │ │ │ ├── challenge-done.md │ │ │ ├── img │ │ │ ├── change-expected-result.png │ │ │ ├── extract-parameter.png │ │ │ └── method-source.png │ │ │ ├── snippet.png │ │ │ └── step-by-step.md │ ├── day07 │ │ ├── challenge.md │ │ ├── snippet.png │ │ └── solution │ │ │ ├── challenge-done.md │ │ │ ├── img │ │ │ ├── extract-method.png │ │ │ ├── invert-if.png │ │ │ ├── remove-redundant-else.png │ │ │ ├── snippet-vavr.png │ │ │ └── snippet.png │ │ │ ├── snippet-vavr.png │ │ │ ├── snippet.png │ │ │ └── step-by-step.md │ ├── day08 │ │ ├── challenge.md │ │ ├── img │ │ │ ├── double_loop.jpg │ │ │ └── double_loop.png │ │ ├── snippet.png │ │ └── solution │ │ │ ├── challenge-done.md │ │ │ ├── img │ │ │ ├── chaGTP-answer.png │ │ │ ├── extract-chars.png │ │ │ ├── first-failing-test.png │ │ │ ├── golden-failing.png │ │ │ ├── move-package.png │ │ │ ├── param-test-reason.png │ │ │ ├── simplify-conditional.png │ │ │ ├── snippet-chatgpt.png │ │ │ └── snippet.png │ │ │ └── step-by-step.md │ ├── day09 │ │ ├── challenge.md │ │ ├── snippet.png │ │ └── solution │ │ │ ├── challenge-done.md │ │ │ ├── img │ │ │ ├── generate-code.png │ │ │ └── remove-field.png │ │ │ ├── snippet.png │ │ │ └── step-by-step.md │ ├── day10 │ │ ├── challenge.md │ │ ├── snippet.png │ │ └── solution │ │ │ ├── challenge-done.md │ │ │ ├── img │ │ │ └── remove-convert-safely.png │ │ │ ├── snippet.png │ │ │ └── step-by-step.md │ ├── day11 │ │ ├── challenge.md │ │ ├── snippet.png │ │ └── solution │ │ │ ├── challenge-done.md │ │ │ ├── img │ │ │ ├── configuration.png │ │ │ ├── deming.jpg │ │ │ ├── failing-build.png │ │ │ ├── libyear.webp │ │ │ └── result.png │ │ │ ├── snippet.png │ │ │ └── step-by-step.md │ ├── day12 │ │ ├── challenge.md │ │ ├── snippet.png │ │ └── solution │ │ │ ├── challenge-done.md │ │ │ ├── img │ │ │ ├── class-diagram.png │ │ │ ├── extract-method-duplication.png │ │ │ ├── failure-reason-explained.png │ │ │ ├── red-hello.png │ │ │ └── safe-delete.png │ │ │ ├── snippet.png │ │ │ └── step-by-step.md │ ├── day13 │ │ ├── challenge.md │ │ ├── snippet.png │ │ └── solution │ │ │ ├── challenge-done.md │ │ │ ├── img │ │ │ ├── comment-in-the-builder.png │ │ │ ├── duplication.png │ │ │ ├── extract-method.png │ │ │ └── generate-code-from-usage.png │ │ │ ├── snippet.png │ │ │ └── step-by-step.md │ ├── day14 │ │ ├── challenge.md │ │ ├── snippet.png │ │ └── solution │ │ │ ├── challenge-done.md │ │ │ ├── img │ │ │ ├── convert-not-safe.png │ │ │ ├── failing-test.png │ │ │ └── remove-convert.png │ │ │ ├── snippet-vavr.png │ │ │ ├── snippet.png │ │ │ └── step-by-step.md │ ├── day15 │ │ ├── challenge.md │ │ ├── snippet.png │ │ └── solution │ │ │ ├── challenge-done.md │ │ │ ├── img │ │ │ ├── 2-files.png │ │ │ ├── approval-testing-cheatsheet.png │ │ │ ├── code-coverage.png │ │ │ ├── fail.png │ │ │ ├── file-compare.png │ │ │ ├── first-run.png │ │ │ └── use-combinations.png │ │ │ ├── snippet.png │ │ │ └── step-by-step.md │ ├── day16 │ │ ├── challenge.md │ │ ├── snippet.png │ │ └── solution │ │ │ ├── challenge-done.md │ │ │ ├── img │ │ │ ├── article-contract.png │ │ │ ├── create-constructor.png │ │ │ ├── failing-tests.png │ │ │ ├── return-this.png │ │ │ ├── test-as-a-driver.png │ │ │ └── tests-are-still-failing.png │ │ │ ├── snippet.png │ │ │ └── step-by-step.md │ ├── day17 │ │ ├── challenge.md │ │ ├── snippet.png │ │ └── solution │ │ │ ├── challenge-done.md │ │ │ ├── img │ │ │ ├── create-input.png │ │ │ ├── discoverability.png │ │ │ └── failing-property.png │ │ │ ├── snippet.png │ │ │ └── step-by-step.md │ ├── day18 │ │ ├── challenge.md │ │ ├── snippet.png │ │ └── solution │ │ │ ├── challenge-done.md │ │ │ ├── img │ │ │ ├── a2.png │ │ │ ├── dot-driven-development.png │ │ │ ├── extract-parameter.png │ │ │ ├── getter-void.png │ │ │ ├── lap-archunit.png │ │ │ └── lap.png │ │ │ ├── snippet.png │ │ │ └── step-by-step.md │ ├── day19 │ │ ├── challenge.md │ │ ├── snippet.png │ │ └── solution │ │ │ ├── challenge-done.md │ │ │ ├── img │ │ │ ├── generate-code.png │ │ │ ├── ide-usage-detection.png │ │ │ ├── no-more-exception.png │ │ │ ├── remove-useless-method.png │ │ │ ├── safe-delete-exception.png │ │ │ └── test-as-a-driver.png │ │ │ ├── snippet.png │ │ │ └── step-by-step.md │ ├── day20 │ │ ├── challenge.md │ │ ├── snippet.png │ │ └── solution │ │ │ ├── challenge-done.md │ │ │ ├── img │ │ │ ├── calculator-constrain-input.png │ │ │ ├── callback-hell.webp │ │ │ ├── constrain-input.png │ │ │ ├── generate-calculate.png │ │ │ ├── generate-roll.png │ │ │ └── hollywood-principle.webp │ │ │ ├── snippet-hollywood.png │ │ │ ├── snippet.png │ │ │ └── step-by-step.md │ ├── day21 │ │ ├── challenge.md │ │ ├── img │ │ │ ├── communication-based.png │ │ │ ├── output-based.png │ │ │ └── state-based.png │ │ ├── snippet.png │ │ └── solution │ │ │ ├── challenge-done.md │ │ │ ├── img │ │ │ ├── assertion-fail.png │ │ │ ├── audit-functional.png │ │ │ ├── communication-based.png │ │ │ ├── failure2.png │ │ │ ├── generate-code.png │ │ │ ├── output-based.png │ │ │ ├── red-compiler.png │ │ │ └── state-based.png │ │ │ ├── snippet.png │ │ │ └── step-by-step.md │ ├── day22 │ │ ├── challenge.md │ │ ├── snippet.png │ │ └── solution │ │ │ ├── challenge-done.md │ │ │ ├── img │ │ │ ├── approve-content.png │ │ │ ├── generate-code-from-first-property.png │ │ │ └── generate-code-impl.png │ │ │ ├── snippet.png │ │ │ └── step-by-step.md │ ├── day23 │ │ ├── all-in-one.png │ │ ├── challenge.md │ │ ├── snippet.png │ │ └── solution │ │ │ ├── challenge-done.md │ │ │ ├── img │ │ │ ├── activate-tracing.png │ │ │ ├── change-signature.png │ │ │ ├── coverage.png │ │ │ ├── coverage2.png │ │ │ ├── coverage3.png │ │ │ ├── coverage4.png │ │ │ ├── demo-bracnh-coverage.png │ │ │ ├── demo1.png │ │ │ ├── demo2.png │ │ │ ├── end-strangler.png │ │ │ ├── generate-code-from-usage.png │ │ │ ├── introduced-mutants.png │ │ │ ├── legacy-code-refactoring.png │ │ │ ├── mock-error.png │ │ │ ├── move-closer.png │ │ │ ├── pitest-report.png │ │ │ ├── safe-delete.png │ │ │ ├── tdd.png │ │ │ ├── test-readability.png │ │ │ ├── tips.png │ │ │ └── video.png │ │ │ ├── snippet.png │ │ │ ├── step-by-step.md │ │ │ └── steps │ │ │ ├── 1.cover-the-code.md │ │ │ ├── 2.mutate-some-code.md │ │ │ ├── 3.refactoring.md │ │ │ └── 4.other-refactorings.md │ ├── day24 │ │ ├── cdd.png │ │ ├── challenge.md │ │ ├── snippet.png │ │ └── solution │ │ │ ├── challenge-done.md │ │ │ ├── img │ │ │ ├── complexity.png │ │ │ ├── crappy-driven-development.png │ │ │ ├── crappy-ideas.png │ │ │ └── use-rename.png │ │ │ ├── snippet.png │ │ │ └── step-by-step.md │ ├── day25 │ │ ├── challenge.md │ │ └── sharing.png │ └── pom.xml ├── img │ ├── advent-of-craft.png │ ├── clean-testing.png │ ├── design.png │ ├── discord.png │ ├── functional-programming.png │ ├── proposed-solution.png │ ├── refactoring.png │ └── tdd.png └── learning-paths │ ├── clean-testing.md │ ├── design.md │ ├── functional-programming.md │ ├── refactoring.md │ └── tdd.md ├── exercise ├── c# │ ├── AdventOfCraft.sln │ ├── Day01 │ │ ├── Day01.Tests │ │ │ ├── Day01.Tests.csproj │ │ │ └── EdibleTests.cs │ │ └── Day01 │ │ │ ├── Day01.csproj │ │ │ └── Food.cs │ ├── Day02 │ │ ├── Day02.Tests │ │ │ ├── Day02.Tests.csproj │ │ │ └── FizzBuzzTests.cs │ │ └── Day02 │ │ │ ├── Day02.csproj │ │ │ ├── FizzBuzz.cs │ │ │ └── OutOfRangeException.cs │ ├── Day03 │ │ ├── Day03.Tests │ │ │ ├── Day03.Tests.csproj │ │ │ └── PopulationTests.cs │ │ └── Day03 │ │ │ ├── Day03.csproj │ │ │ └── Person.cs │ ├── Day04 │ │ ├── Day04.Tests │ │ │ ├── ArticleTests.cs │ │ │ └── Day04.Tests.csproj │ │ └── Day04 │ │ │ ├── Blog.cs │ │ │ └── Day04.csproj │ ├── Day05 │ │ ├── Day05.Tests │ │ │ ├── Day05.Tests.csproj │ │ │ └── PopulationTests.cs │ │ └── Day05 │ │ │ ├── Day05.csproj │ │ │ └── Person.cs │ ├── Day06 │ │ ├── Day06.Tests │ │ │ ├── Day06.Tests.csproj │ │ │ └── FizzBuzzTests.cs │ │ └── Day06 │ │ │ ├── Day06.csproj │ │ │ ├── FizzBuzz.cs │ │ │ └── OutOfRangeException.cs │ ├── Day07 │ │ ├── Day07.Tests │ │ │ ├── Day07.Tests.csproj │ │ │ ├── Doubles │ │ │ │ └── CapturingLogger.cs │ │ │ └── PipelineTests.cs │ │ └── Day07 │ │ │ ├── CI │ │ │ ├── Dependencies │ │ │ │ ├── IConfig.cs │ │ │ │ ├── IEmailer.cs │ │ │ │ ├── ILogger.cs │ │ │ │ ├── Project.cs │ │ │ │ └── TestStatus.cs │ │ │ └── Pipeline.cs │ │ │ └── Day07.csproj │ ├── Day08 │ │ ├── Day08.Tests │ │ │ └── Day08.Tests.csproj │ │ └── Day08 │ │ │ └── Day08.csproj │ ├── Day09 │ │ ├── Day09.Tests │ │ │ ├── ClientTests.cs │ │ │ └── Day09.Tests.csproj │ │ └── Day09 │ │ │ ├── Accountability │ │ │ └── Client.cs │ │ │ └── Day09.csproj │ ├── Day10 │ │ ├── Day10.Tests │ │ │ ├── Day10.Tests.csproj │ │ │ └── FizzBuzzTests.cs │ │ └── Day10 │ │ │ ├── Day10.csproj │ │ │ ├── FizzBuzz.cs │ │ │ └── OutOfRangeException.cs │ ├── Day11 │ │ ├── Day11.Tests │ │ │ ├── Day11.Tests.csproj │ │ │ └── RomanNumeralsTests.cs │ │ └── Day11 │ │ │ ├── Day11.csproj │ │ │ └── RomanNumerals.cs │ ├── Day12 │ │ ├── Day12.Tests │ │ │ ├── Day12.Tests.csproj │ │ │ └── GreeterTests.cs │ │ └── Day12 │ │ │ ├── Day12.csproj │ │ │ └── Greeter.cs │ ├── Day13 │ │ ├── Day13.Tests │ │ │ ├── ArticleTests.cs │ │ │ └── Day13.Tests.csproj │ │ └── Day13 │ │ │ ├── Blog.cs │ │ │ └── Day13.csproj │ ├── Day14 │ │ ├── Day14.Tests │ │ │ ├── Day14.Tests.csproj │ │ │ └── FizzBuzzTests.cs │ │ └── Day14 │ │ │ ├── Day14.csproj │ │ │ ├── FizzBuzz.cs │ │ │ └── OutOfRangeException.cs │ ├── Day15 │ │ ├── Day15.Tests │ │ │ └── Day15.Tests.csproj │ │ └── Day15 │ │ │ ├── Day15.csproj │ │ │ ├── DocumentTemplate.cs │ │ │ ├── RecordType.cs │ │ │ └── Template.cs │ ├── Day16 │ │ ├── Day16.Tests │ │ │ ├── ArticleBuilder.cs │ │ │ ├── ArticleTests.cs │ │ │ └── Day16.Tests.csproj │ │ └── Day16 │ │ │ ├── Blog.cs │ │ │ └── Day16.csproj │ ├── Day17 │ │ ├── Day17.Tests │ │ │ ├── Day17.Tests.csproj │ │ │ └── FizzBuzzTests.cs │ │ └── Day17 │ │ │ ├── Day17.csproj │ │ │ └── FizzBuzz.cs │ ├── Day18 │ │ ├── Day18.Tests │ │ │ └── Day18.Tests.csproj │ │ └── Day18 │ │ │ ├── Day18.csproj │ │ │ └── ShittyClass.cs │ ├── Day19 │ │ ├── Day19.Tests │ │ │ ├── ArticleBuilder.cs │ │ │ ├── ArticleTests.cs │ │ │ └── Day19.Tests.csproj │ │ └── Day19 │ │ │ ├── Blog.cs │ │ │ └── Day19.csproj │ ├── Day20 │ │ ├── Day20.Tests │ │ │ ├── Day20.Tests.csproj │ │ │ ├── DiceBuilder.cs │ │ │ └── YahtzeeCalculatorTests.cs │ │ └── Day20 │ │ │ ├── Day20.csproj │ │ │ └── Domain │ │ │ └── Yahtzee │ │ │ └── YahtzeeCalculator.cs │ ├── Day21 │ │ ├── Day21.Tests │ │ │ ├── AuditManagerTests.cs │ │ │ └── Day21.Tests.csproj │ │ └── Day21 │ │ │ ├── AuditManager.cs │ │ │ ├── Day21.csproj │ │ │ └── IFileSystem.cs │ ├── Day22 │ │ ├── Day22.Tests │ │ │ └── Day22.Tests.csproj │ │ └── Day22 │ │ │ └── Day22.csproj │ ├── Day23 │ │ ├── Day23.Tests │ │ │ ├── Day23.Tests.csproj │ │ │ ├── Trip │ │ │ │ ├── TripDAOTests.cs │ │ │ │ └── TripServiceTests.cs │ │ │ └── User │ │ │ │ └── UserTests.cs │ │ └── Day23 │ │ │ ├── Day23.csproj │ │ │ ├── Exception │ │ │ ├── CollaboratorCallException.cs │ │ │ └── UserNotLoggedInException.cs │ │ │ ├── Trip │ │ │ ├── Trip.cs │ │ │ ├── TripDAO.cs │ │ │ └── TripService.cs │ │ │ └── User │ │ │ ├── User.cs │ │ │ └── UserSession.cs │ ├── Day24 │ │ ├── Day24.Tests │ │ │ ├── Day24.Tests.csproj │ │ │ ├── SubmarineTests.cs │ │ │ └── submarine.txt │ │ └── Day24 │ │ │ ├── Day24.csproj │ │ │ ├── Instruction.cs │ │ │ ├── Position.cs │ │ │ └── Submarine.cs │ ├── clean-testing.sln │ ├── design.sln │ ├── functional-programming.sln │ ├── refactoring.sln │ └── tdd.sln ├── java │ ├── day01 │ │ ├── pom.xml │ │ └── src │ │ │ ├── main │ │ │ └── java │ │ │ │ └── food │ │ │ │ └── Food.java │ │ │ └── test │ │ │ └── java │ │ │ └── EdibleTests.java │ ├── day02 │ │ ├── pom.xml │ │ └── src │ │ │ ├── main │ │ │ └── java │ │ │ │ └── games │ │ │ │ ├── FizzBuzz.java │ │ │ │ └── OutOfRangeException.java │ │ │ └── test │ │ │ └── java │ │ │ └── games │ │ │ └── FizzBuzzTests.java │ ├── day03 │ │ ├── pom.xml │ │ └── src │ │ │ ├── main │ │ │ └── java │ │ │ │ └── people │ │ │ │ ├── Person.java │ │ │ │ ├── Pet.java │ │ │ │ └── PetType.java │ │ │ └── test │ │ │ └── java │ │ │ └── PopulationTests.java │ ├── day04 │ │ ├── pom.xml │ │ └── src │ │ │ ├── main │ │ │ └── java │ │ │ │ └── blog │ │ │ │ ├── Article.java │ │ │ │ ├── Comment.java │ │ │ │ └── CommentAlreadyExistException.java │ │ │ └── test │ │ │ └── java │ │ │ └── blog │ │ │ └── ArticleTests.java │ ├── day05 │ │ ├── pom.xml │ │ └── src │ │ │ ├── main │ │ │ └── java │ │ │ │ └── people │ │ │ │ ├── Person.java │ │ │ │ ├── Pet.java │ │ │ │ └── PetType.java │ │ │ └── test │ │ │ └── java │ │ │ ├── PopulationTests.java │ │ │ └── PopulationWithVavrTests.java │ ├── day06 │ │ ├── pom.xml │ │ └── src │ │ │ ├── main │ │ │ └── java │ │ │ │ └── games │ │ │ │ ├── FizzBuzz.java │ │ │ │ └── OutOfRangeException.java │ │ │ └── test │ │ │ └── java │ │ │ └── games │ │ │ └── FizzBuzzTests.java │ ├── day07 │ │ ├── pom.xml │ │ └── src │ │ │ ├── main │ │ │ └── java │ │ │ │ └── ci │ │ │ │ ├── Pipeline.java │ │ │ │ └── dependencies │ │ │ │ ├── Config.java │ │ │ │ ├── Emailer.java │ │ │ │ ├── Logger.java │ │ │ │ ├── Project.java │ │ │ │ └── TestStatus.java │ │ │ └── test │ │ │ └── java │ │ │ └── ci │ │ │ ├── CapturingLogger.java │ │ │ └── PipelineTest.java │ ├── day08 │ │ └── pom.xml │ ├── day09 │ │ ├── pom.xml │ │ └── src │ │ │ ├── main │ │ │ └── java │ │ │ │ └── account │ │ │ │ └── Client.java │ │ │ └── test │ │ │ └── java │ │ │ └── ClientTests.java │ ├── day10 │ │ ├── pom.xml │ │ └── src │ │ │ ├── main │ │ │ └── java │ │ │ │ └── games │ │ │ │ ├── FizzBuzz.java │ │ │ │ └── OutOfRangeException.java │ │ │ └── test │ │ │ └── java │ │ │ └── games │ │ │ └── FizzBuzzTests.java │ ├── day11 │ │ ├── pom.xml │ │ └── src │ │ │ ├── main │ │ │ └── java │ │ │ │ └── roman │ │ │ │ └── numerals │ │ │ │ └── RomanNumerals.java │ │ │ └── test │ │ │ └── java │ │ │ └── roman │ │ │ └── numerals │ │ │ └── RomanNumeralsTest.java │ ├── day12 │ │ ├── pom.xml │ │ └── src │ │ │ ├── main │ │ │ └── java │ │ │ │ └── greeting │ │ │ │ └── Greeter.java │ │ │ └── test │ │ │ └── java │ │ │ └── greeting │ │ │ └── GreeterTest.java │ ├── day13 │ │ ├── pom.xml │ │ └── src │ │ │ ├── main │ │ │ └── java │ │ │ │ └── blog │ │ │ │ ├── Article.java │ │ │ │ ├── Comment.java │ │ │ │ └── CommentAlreadyExistException.java │ │ │ └── test │ │ │ └── java │ │ │ └── blog │ │ │ └── ArticleTests.java │ ├── day14 │ │ ├── pom.xml │ │ └── src │ │ │ ├── main │ │ │ └── java │ │ │ │ └── games │ │ │ │ ├── FizzBuzz.java │ │ │ │ └── OutOfRangeException.java │ │ │ └── test │ │ │ └── java │ │ │ └── games │ │ │ └── FizzBuzzTests.java │ ├── day15 │ │ ├── pom.xml │ │ └── src │ │ │ └── main │ │ │ └── java │ │ │ └── document │ │ │ ├── DocumentTemplateType.java │ │ │ └── RecordType.java │ ├── day16 │ │ ├── pom.xml │ │ └── src │ │ │ ├── main │ │ │ └── java │ │ │ │ └── blog │ │ │ │ ├── Article.java │ │ │ │ ├── Comment.java │ │ │ │ └── CommentAlreadyExistException.java │ │ │ └── test │ │ │ └── java │ │ │ └── blog │ │ │ ├── ArticleBuilder.java │ │ │ └── ArticleTests.java │ ├── day17 │ │ ├── pom.xml │ │ └── src │ │ │ ├── main │ │ │ └── java │ │ │ │ └── games │ │ │ │ └── FizzBuzz.java │ │ │ └── test │ │ │ └── java │ │ │ └── games │ │ │ └── FizzBuzzTests.java │ ├── day18 │ │ ├── pom.xml │ │ └── src │ │ │ └── main │ │ │ └── java │ │ │ └── lap │ │ │ └── ShittyClass.java │ ├── day19 │ │ ├── pom.xml │ │ └── src │ │ │ ├── main │ │ │ └── java │ │ │ │ └── blog │ │ │ │ ├── Article.java │ │ │ │ ├── Comment.java │ │ │ │ └── CommentAlreadyExistException.java │ │ │ └── test │ │ │ └── java │ │ │ └── blog │ │ │ ├── ArticleBuilder.java │ │ │ └── ArticleTests.java │ ├── day20 │ │ ├── pom.xml │ │ └── src │ │ │ ├── main │ │ │ └── java │ │ │ │ └── domain │ │ │ │ └── yahtzee │ │ │ │ └── YahtzeeCalculator.java │ │ │ └── test │ │ │ └── java │ │ │ ├── DiceBuilder.java │ │ │ └── YahtzeeCalculatorTests.java │ ├── day21 │ │ ├── pom.xml │ │ └── src │ │ │ ├── main │ │ │ └── java │ │ │ │ └── audit │ │ │ │ ├── AuditManager.java │ │ │ │ └── FileSystem.java │ │ │ └── test │ │ │ └── java │ │ │ └── audit │ │ │ └── AuditManagerTests.java │ ├── day22 │ │ ├── .tcr │ │ │ ├── config.yml │ │ │ ├── language │ │ │ │ └── java.yml │ │ │ └── toolchain │ │ │ │ └── maven.yml │ │ ├── pom.xml │ │ └── tcrw │ ├── day23 │ │ ├── pom.xml │ │ └── src │ │ │ ├── main │ │ │ └── java │ │ │ │ └── org │ │ │ │ └── craftedsw │ │ │ │ └── tripservicekata │ │ │ │ ├── exception │ │ │ │ ├── CollaboratorCallException.java │ │ │ │ └── UserNotLoggedInException.java │ │ │ │ ├── trip │ │ │ │ ├── Trip.java │ │ │ │ ├── TripDAO.java │ │ │ │ └── TripService.java │ │ │ │ └── user │ │ │ │ ├── User.java │ │ │ │ └── UserSession.java │ │ │ └── test │ │ │ └── java │ │ │ └── org │ │ │ └── craftedsw │ │ │ └── tripservicekata │ │ │ ├── trip │ │ │ ├── TripDAOTest.java │ │ │ └── TripServiceTest.java │ │ │ └── user │ │ │ └── UserTest.java │ ├── day24 │ │ ├── pom.xml │ │ └── src │ │ │ ├── main │ │ │ └── java │ │ │ │ └── submarine │ │ │ │ ├── Instruction.java │ │ │ │ ├── Position.java │ │ │ │ └── Submarine.java │ │ │ └── test │ │ │ ├── java │ │ │ └── submarine │ │ │ │ ├── FileUtils.java │ │ │ │ └── SubmarineTests.java │ │ │ └── resources │ │ │ └── submarine.txt │ ├── pom.xml │ └── tcr │ │ ├── .gitignore │ │ ├── tcr.sh │ │ └── version.txt ├── kotlin │ ├── build.gradle.kts │ ├── day01 │ │ ├── build.gradle.kts │ │ └── src │ │ │ ├── main │ │ │ └── kotlin │ │ │ │ └── food │ │ │ │ └── Food.kt │ │ │ └── test │ │ │ └── kotlin │ │ │ └── EdibleTests.kt │ ├── day02 │ │ ├── build.gradle.kts │ │ └── src │ │ │ ├── main │ │ │ └── kotlin │ │ │ │ └── games │ │ │ │ ├── FizzBuzz.kt │ │ │ │ └── OutOfRangeException.kt │ │ │ └── test │ │ │ └── kotlin │ │ │ └── FizzBuzzTests.kt │ ├── day03 │ │ ├── build.gradle.kts │ │ └── src │ │ │ ├── main │ │ │ └── kotlin │ │ │ │ └── people │ │ │ │ └── Person.kt │ │ │ └── test │ │ │ └── kotlin │ │ │ └── PopulationTests.kt │ ├── day04 │ │ ├── build.gradle.kts │ │ └── src │ │ │ ├── main │ │ │ └── kotlin │ │ │ │ └── blog │ │ │ │ └── Blog.kt │ │ │ └── test │ │ │ └── kotlin │ │ │ └── BlogTests.kt │ ├── day05 │ │ ├── build.gradle.kts │ │ └── src │ │ │ ├── main │ │ │ └── kotlin │ │ │ │ └── people │ │ │ │ └── Person.kt │ │ │ └── test │ │ │ └── kotlin │ │ │ └── PopulationTests.kt │ ├── day06 │ │ ├── build.gradle.kts │ │ └── src │ │ │ ├── main │ │ │ └── kotlin │ │ │ │ └── games │ │ │ │ ├── FizzBuzz.kt │ │ │ │ └── OutOfRangeException.kt │ │ │ └── test │ │ │ └── kotlin │ │ │ └── FizzBuzzTests.kt │ ├── day07 │ │ ├── build.gradle.kts │ │ └── src │ │ │ ├── main │ │ │ └── kotlin │ │ │ │ └── ci │ │ │ │ └── Pipeline.kt │ │ │ └── test │ │ │ └── kotlin │ │ │ ├── CapturingLogger.kt │ │ │ └── PipelineTests.kt │ ├── day08 │ │ └── build.gradle.kts │ ├── day09 │ │ ├── build.gradle.kts │ │ └── src │ │ │ ├── main │ │ │ └── kotlin │ │ │ │ └── account │ │ │ │ └── Client.kt │ │ │ └── test │ │ │ └── kotlin │ │ │ └── ClientTests.kt │ ├── day10 │ │ ├── build.gradle.kts │ │ └── src │ │ │ ├── main │ │ │ └── kotlin │ │ │ │ └── games │ │ │ │ ├── FizzBuzz.kt │ │ │ │ └── OutOfRangeException.kt │ │ │ └── test │ │ │ └── kotlin │ │ │ └── FizzBuzzTests.kt │ ├── day11 │ │ ├── build.gradle.kts │ │ └── src │ │ │ ├── main │ │ │ └── kotlin │ │ │ │ └── roman │ │ │ │ └── numerals │ │ │ │ └── RomanNumerals.kt │ │ │ └── test │ │ │ └── kotlin │ │ │ ├── RomanNumeralsTests.kt │ │ │ └── RomanProperties.kt │ ├── day12 │ │ ├── build.gradle.kts │ │ └── src │ │ │ ├── main │ │ │ └── kotlin │ │ │ │ └── greeting │ │ │ │ └── Greeter.kt │ │ │ └── test │ │ │ └── kotlin │ │ │ └── GreeterTests.kt │ ├── day13 │ │ ├── build.gradle.kts │ │ └── src │ │ │ ├── main │ │ │ └── kotlin │ │ │ │ └── blog │ │ │ │ └── Blog.kt │ │ │ └── test │ │ │ └── kotlin │ │ │ └── BlogTests.kt │ ├── day14 │ │ ├── build.gradle.kts │ │ └── src │ │ │ ├── main │ │ │ └── kotlin │ │ │ │ └── games │ │ │ │ ├── FizzBuzz.kt │ │ │ │ └── OutOfRangeException.kt │ │ │ └── test │ │ │ └── kotlin │ │ │ └── FizzBuzzTests.kt │ ├── day15 │ │ ├── build.gradle.kts │ │ └── src │ │ │ └── main │ │ │ └── kotlin │ │ │ └── document │ │ │ ├── DocumentTemplateType.kt │ │ │ └── RecordType.kt │ ├── day16 │ │ ├── build.gradle.kts │ │ └── src │ │ │ ├── main │ │ │ └── kotlin │ │ │ │ └── blog │ │ │ │ └── Blog.kt │ │ │ └── test │ │ │ └── kotlin │ │ │ ├── ArticleBuilder.kt │ │ │ └── BlogTests.kt │ ├── day17 │ │ ├── build.gradle.kts │ │ └── src │ │ │ ├── main │ │ │ └── kotlin │ │ │ │ └── games │ │ │ │ └── FizzBuzz.kt │ │ │ └── test │ │ │ └── kotlin │ │ │ └── FizzBuzzTests.kt │ ├── day18 │ │ ├── build.gradle.kts │ │ └── src │ │ │ └── main │ │ │ └── kotlin │ │ │ └── ShittyClass.kt │ ├── day19 │ │ ├── build.gradle.kts │ │ └── src │ │ │ ├── main │ │ │ └── kotlin │ │ │ │ └── blog │ │ │ │ └── Blog.kt │ │ │ └── test │ │ │ └── kotlin │ │ │ ├── ArticleBuilder.kt │ │ │ └── BlogTests.kt │ ├── day20 │ │ ├── build.gradle.kts │ │ └── src │ │ │ ├── main │ │ │ └── kotlin │ │ │ │ └── domain │ │ │ │ └── yahtzee │ │ │ │ └── YahtzeeCalculator.kt │ │ │ └── test │ │ │ └── kotlin │ │ │ ├── DiceBuilder.kt │ │ │ └── YahtzeeCalculatorTests.kt │ ├── day21 │ │ ├── build.gradle.kts │ │ └── src │ │ │ ├── main │ │ │ └── kotlin │ │ │ │ └── audit │ │ │ │ ├── AuditManager.kt │ │ │ │ └── FileSystem.kt │ │ │ └── test │ │ │ └── kotlin │ │ │ └── AuditManagerTests.kt │ ├── day22 │ │ ├── .tcr │ │ │ ├── config.yml │ │ │ ├── language │ │ │ │ └── java.yml │ │ │ └── toolchain │ │ │ │ └── maven.yml │ │ ├── build.gradle.kts │ │ └── tcrw │ ├── day23 │ │ ├── build.gradle.kts │ │ └── src │ │ │ └── main │ │ │ └── kotlin │ │ │ └── org │ │ │ └── craftedsw │ │ │ └── tripservicekata │ │ │ ├── exception │ │ │ ├── CollaboratorCallException.kt │ │ │ └── UserNotLoggedInException.kt │ │ │ ├── trip │ │ │ ├── Trip.kt │ │ │ ├── TripDAO.kt │ │ │ └── TripService.kt │ │ │ └── user │ │ │ ├── User.kt │ │ │ └── UserSession.kt │ ├── day24 │ │ ├── build.gradle.kts │ │ └── src │ │ │ ├── main │ │ │ └── kotlin │ │ │ │ └── submarine │ │ │ │ ├── Instruction.kt │ │ │ │ ├── Position.kt │ │ │ │ └── Submarine.kt │ │ │ └── test │ │ │ ├── kotlin │ │ │ └── SubmarineTests.kt │ │ │ └── resources │ │ │ └── submarine.txt │ ├── gradle.properties │ ├── gradle │ │ └── wrapper │ │ │ └── gradle-wrapper.properties │ ├── gradlew │ ├── gradlew.bat │ ├── settings.gradle.kts │ └── tcr │ │ ├── .gitignore │ │ ├── tcr.sh │ │ └── version.txt └── ts │ ├── day01 │ ├── jest.config.js │ ├── package-lock.json │ ├── package.json │ ├── src │ │ └── food.ts │ ├── tests │ │ └── food.spec.ts │ └── tsconfig.json │ ├── day02 │ ├── jest.config.js │ ├── package-lock.json │ ├── package.json │ ├── src │ │ └── fizzbuzz.ts │ ├── tests │ │ └── fizzbuzz.spec.ts │ └── tsconfig.json │ ├── day03 │ ├── jest.config.js │ ├── package-lock.json │ ├── package.json │ ├── src │ │ └── people.ts │ ├── tests │ │ └── people.spec.ts │ └── tsconfig.json │ ├── day04 │ ├── jest.config.js │ ├── package-lock.json │ ├── package.json │ ├── src │ │ └── blog.ts │ ├── tests │ │ └── blog.spec.ts │ └── tsconfig.json │ ├── day05 │ ├── jest.config.js │ ├── package-lock.json │ ├── package.json │ ├── src │ │ └── people.ts │ ├── tests │ │ └── people.spec.ts │ └── tsconfig.json │ ├── day06 │ ├── jest.config.js │ ├── package-lock.json │ ├── package.json │ ├── src │ │ └── fizzbuzz.ts │ ├── tests │ │ └── fizzbuzz.spec.ts │ └── tsconfig.json │ ├── day07 │ ├── jest.config.js │ ├── package-lock.json │ ├── package.json │ ├── src │ │ ├── ci.ts │ │ ├── pipeline.ts │ │ └── project.ts │ ├── tests │ │ ├── capturingLogger.ts │ │ └── pipeline.spec.ts │ └── tsconfig.json │ ├── day08 │ ├── jest.config.js │ ├── package-lock.json │ ├── package.json │ └── tsconfig.json │ ├── day09 │ ├── jest.config.js │ ├── package-lock.json │ ├── package.json │ ├── src │ │ └── accountability.ts │ ├── tests │ │ └── accountability.spec.ts │ └── tsconfig.json │ ├── day10 │ ├── jest.config.js │ ├── package-lock.json │ ├── package.json │ ├── src │ │ └── fizzbuzz.ts │ ├── tests │ │ └── fizzbuzz.spec.ts │ └── tsconfig.json │ ├── day11 │ ├── jest.config.js │ ├── package-lock.json │ ├── package.json │ ├── src │ │ └── romanNumerals.ts │ ├── tests │ │ └── romanNumerals.spec.ts │ └── tsconfig.json │ ├── day12 │ ├── jest.config.js │ ├── package-lock.json │ ├── package.json │ ├── src │ │ └── greeter.ts │ ├── tests │ │ └── greeter.spec.ts │ └── tsconfig.json │ ├── day13 │ ├── jest.config.js │ ├── package-lock.json │ ├── package.json │ ├── src │ │ └── blog.ts │ ├── tests │ │ └── blog.spec.ts │ └── tsconfig.json │ ├── day14 │ ├── jest.config.js │ ├── package-lock.json │ ├── package.json │ ├── src │ │ └── fizzbuzz.ts │ ├── tests │ │ └── fizzbuzz.spec.ts │ └── tsconfig.json │ ├── day15 │ ├── jest.config.js │ ├── package-lock.json │ ├── package.json │ ├── src │ │ ├── documentTemplateType.ts │ │ └── recordType.ts │ └── tsconfig.json │ ├── day16 │ ├── jest.config.js │ ├── package-lock.json │ ├── package.json │ ├── src │ │ └── blog.ts │ ├── tests │ │ ├── articleBuilder.ts │ │ └── blog.spec.ts │ └── tsconfig.json │ ├── day17 │ ├── jest.config.js │ ├── package-lock.json │ ├── package.json │ ├── src │ │ └── fizzbuzz.ts │ ├── tests │ │ └── fizzbuzz.spec.ts │ └── tsconfig.json │ ├── day18 │ ├── jest.config.js │ ├── package-lock.json │ ├── package.json │ ├── src │ │ └── shitty.ts │ └── tsconfig.json │ ├── day19 │ ├── jest.config.js │ ├── package-lock.json │ ├── package.json │ ├── src │ │ └── blog.ts │ ├── tests │ │ ├── articleBuilder.ts │ │ └── blog.spec.ts │ └── tsconfig.json │ ├── day20 │ ├── jest.config.js │ ├── package-lock.json │ ├── package.json │ ├── src │ │ └── yahtzeeCalculator.ts │ ├── tests │ │ ├── diceBuilder.ts │ │ └── yahtzee.spec.ts │ └── tsconfig.json │ ├── day21 │ ├── jest.config.js │ ├── package-lock.json │ ├── package.json │ ├── src │ │ └── audit.ts │ ├── tests │ │ └── audit.spec.ts │ └── tsconfig.json │ ├── day22 │ ├── jest.config.js │ ├── package-lock.json │ ├── package.json │ └── tsconfig.json │ ├── day23 │ ├── jest.config.js │ ├── package-lock.json │ ├── package.json │ ├── src │ │ ├── exception │ │ │ ├── CollaboratorCallException.ts │ │ │ └── UserNotLoggedInException.ts │ │ ├── trip │ │ │ ├── Trip.ts │ │ │ ├── TripDAO.ts │ │ │ └── TripService.ts │ │ └── user │ │ │ ├── User.ts │ │ │ └── UserSession.ts │ ├── tests │ │ └── tripservice.spec.ts │ └── tsconfig.json │ └── day24 │ ├── jest.config.js │ ├── package-lock.json │ ├── package.json │ ├── src │ ├── instruction.ts │ ├── position.ts │ └── submarine.ts │ ├── tests │ ├── fileutils.ts │ ├── submarine.spec.ts │ └── submarine.txt │ └── tsconfig.json └── solution ├── c# ├── AdventOfCraft.sln ├── Day01 │ ├── Day01.Tests │ │ ├── Day01.Tests.csproj │ │ └── EdibleTests.cs │ └── Day01 │ │ ├── DateExtensions.cs │ │ ├── Day01.csproj │ │ └── Food.cs ├── Day02 │ ├── Day02.Tests │ │ ├── Day02.Tests.csproj │ │ └── FizzBuzzTests.cs │ └── Day02 │ │ ├── Day02.csproj │ │ ├── FizzBuzz.cs │ │ └── OutOfRangeException.cs ├── Day03 │ ├── Day03.Tests │ │ ├── Day03.Tests.csproj │ │ └── PopulationTests.cs │ └── Day03 │ │ ├── Day03.csproj │ │ └── Person.cs ├── Day04 │ ├── Day04.Tests │ │ ├── ArticleTests.cs │ │ └── Day04.Tests.csproj │ └── Day04 │ │ ├── Blog.cs │ │ └── Day04.csproj ├── Day05 │ ├── Day05.Tests │ │ ├── Day05.Tests.csproj │ │ └── PopulationTests.cs │ └── Day05 │ │ ├── Day05.csproj │ │ └── Person.cs ├── Day06 │ ├── Day06.Tests │ │ ├── Day06.Tests.csproj │ │ └── FizzBuzzTests.cs │ └── Day06 │ │ ├── Day06.csproj │ │ ├── FizzBuzz.cs │ │ └── OutOfRangeException.cs ├── Day07 │ ├── Day07.Tests │ │ ├── Day07.Tests.csproj │ │ ├── Doubles │ │ │ └── CapturingLogger.cs │ │ ├── Functional │ │ │ └── PipelineTests.cs │ │ └── PipelineTests.cs │ └── Day07 │ │ ├── CI │ │ ├── Dependencies │ │ │ ├── IConfig.cs │ │ │ ├── IEmailer.cs │ │ │ ├── ILogger.cs │ │ │ ├── Project.cs │ │ │ └── TestStatus.cs │ │ ├── Functional │ │ │ └── Pipeline.cs │ │ └── Pipeline.cs │ │ └── Day07.csproj ├── Day08 │ ├── Day08.Tests │ │ ├── Day08.Tests.csproj │ │ ├── Functional │ │ │ └── PasswordTests.cs │ │ └── PasswordValidationTests.cs │ └── Day08 │ │ ├── Day08.csproj │ │ ├── Functional │ │ └── Password.cs │ │ └── PasswordValidation.cs ├── Day09 │ ├── Day09.Tests │ │ ├── ClientTests.cs │ │ └── Day09.Tests.csproj │ └── Day09 │ │ ├── Accountability │ │ └── Client.cs │ │ └── Day09.csproj ├── Day10 │ ├── Day10.Tests │ │ ├── Day10.Tests.csproj │ │ └── FizzBuzzTests.cs │ └── Day10 │ │ ├── Day10.csproj │ │ ├── FizzBuzz.cs │ │ └── OutOfRangeException.cs ├── Day11 │ ├── Day11.Tests │ │ ├── Day11.Tests.csproj │ │ └── RomanNumeralsTests.cs │ ├── Day11 │ │ ├── Day11.csproj │ │ └── RomanNumerals.cs │ └── libyear │ │ └── libyear-result.png ├── Day12 │ ├── Day12.Tests │ │ ├── Day12.Tests.csproj │ │ ├── Functional │ │ │ └── GreeterTests.cs │ │ └── GreeterTests.cs │ └── Day12 │ │ ├── Day12.csproj │ │ ├── Functional │ │ └── GreeterFactory.cs │ │ └── Greeter.cs ├── Day13 │ ├── Day13.Tests │ │ ├── ArticleBonusTests.cs │ │ ├── ArticleBuilder.cs │ │ ├── ArticleTests.cs │ │ └── Day13.Tests.csproj │ └── Day13 │ │ ├── Blog.cs │ │ └── Day13.csproj ├── Day14 │ ├── Day14.Tests │ │ ├── Day14.Tests.csproj │ │ ├── FizzBuzzTests.cs │ │ └── LangExt │ │ │ └── FizzBuzzTests.cs │ └── Day14 │ │ ├── Day14.csproj │ │ ├── FizzBuzz.cs │ │ ├── LangExt │ │ └── FizzBuzz.cs │ │ └── Result.cs ├── Day15 │ ├── Day15.Tests │ │ ├── Day15.Tests.csproj │ │ ├── DocumentTests.Verify_Combinations.verified.txt │ │ └── DocumentTests.cs │ └── Day15 │ │ ├── Day15.csproj │ │ ├── DocumentTemplate.cs │ │ ├── RecordType.cs │ │ ├── Template.cs │ │ └── Templates.cs ├── Day16 │ ├── Day16.Tests │ │ ├── ArticleBuilder.cs │ │ ├── ArticleTests.cs │ │ └── Day16.Tests.csproj │ └── Day16 │ │ ├── Blog.cs │ │ └── Day16.csproj ├── Day17 │ ├── Day17.Tests │ │ ├── Day17.Tests.csproj │ │ └── FizzBuzzTests.cs │ └── Day17 │ │ ├── Day17.csproj │ │ └── FizzBuzz.cs ├── Day18 │ ├── Day18.Tests │ │ ├── ArchUnitExtensions.cs │ │ ├── Day18.Tests.csproj │ │ └── TeamRules.cs │ └── Day18 │ │ ├── Day18.csproj │ │ └── ShittyClass.cs ├── Day19 │ ├── Day19.Tests │ │ ├── ArticleBuilder.cs │ │ ├── ArticleTests.cs │ │ └── Day19.Tests.csproj │ └── Day19 │ │ ├── Blog.cs │ │ └── Day19.csproj ├── Day20 │ ├── Day20.Tests │ │ ├── Constrain.Input │ │ │ ├── RollBuilder.cs │ │ │ └── YahtzeeCalculatorTests.cs │ │ ├── Day20.Tests.csproj │ │ ├── DiceBuilder.cs │ │ ├── Hollywood.Principle │ │ │ └── YahtzeeCalculatorTests.cs │ │ └── Original │ │ │ └── YahtzeeCalculatorTests.cs │ └── Day20 │ │ ├── Day20.csproj │ │ └── Domain │ │ └── Yahtzee │ │ ├── Constrain.Input │ │ ├── Roll.cs │ │ └── YahtzeeCalculator.cs │ │ ├── Hollywood.Principle │ │ └── YahtzeeCalculator.cs │ │ └── Original │ │ └── YahtzeeCalculator.cs ├── Day21 │ ├── Day21.Tests │ │ ├── AuditManagerTests.cs │ │ └── Day21.Tests.csproj │ └── Day21 │ │ ├── AddRecordUseCase.cs │ │ ├── AuditManager.cs │ │ ├── Day21.csproj │ │ ├── IFileSystem.cs │ │ └── Persister.cs ├── Day22 │ ├── Day22.Tests │ │ ├── Day22.Tests.csproj │ │ ├── DiamondTests.Approval.Generate_A_Diamond.verified.txt │ │ └── DiamondTests.cs │ └── Day22 │ │ ├── Day22.csproj │ │ └── Diamond.cs ├── Day23 │ ├── Day23.Tests │ │ ├── Day23.Tests.csproj │ │ ├── FunctionalExtensions.cs │ │ ├── Trips │ │ │ ├── GetTripsByUserShould.cs │ │ │ └── TripRepositoryShould.cs │ │ └── Users │ │ │ ├── UserBuilder.cs │ │ │ └── UserShould.cs │ └── Day23 │ │ ├── Day23.csproj │ │ ├── Exception │ │ ├── CollaboratorCallException.cs │ │ └── UserNotLoggedInException.cs │ │ ├── Trips │ │ ├── ITripRepository.cs │ │ ├── Trip.cs │ │ ├── TripDAO.cs │ │ └── TripService.cs │ │ └── Users │ │ ├── User.cs │ │ └── UserSession.cs ├── Day24 │ ├── Day24.Tests │ │ ├── Day24.Tests.csproj │ │ ├── SubmarineTests.cs │ │ └── submarine.txt │ └── Day24 │ │ ├── Day24.csproj │ │ └── K991_P.cs ├── clean-testing.sln ├── design.sln ├── functional-programming.sln ├── refactoring.sln └── tdd.sln ├── java ├── day01 │ ├── pom.xml │ └── src │ │ ├── main │ │ └── java │ │ │ └── food │ │ │ └── Food.java │ │ ├── pom.xml │ │ └── test │ │ └── java │ │ └── EdibleTests.java ├── day02 │ ├── pom.xml │ └── src │ │ ├── main │ │ └── java │ │ │ └── games │ │ │ ├── FizzBuzz.java │ │ │ └── OutOfRangeException.java │ │ └── test │ │ └── java │ │ └── games │ │ └── FizzBuzzTests.java ├── day03 │ ├── pom.xml │ └── src │ │ ├── main │ │ └── java │ │ │ └── people │ │ │ ├── Person.java │ │ │ ├── Pet.java │ │ │ └── PetType.java │ │ └── test │ │ └── java │ │ ├── PopulationTests.java │ │ └── PopulationWithVavrTests.java ├── day04 │ ├── pom.xml │ └── src │ │ ├── main │ │ └── java │ │ │ └── blog │ │ │ ├── Article.java │ │ │ ├── Comment.java │ │ │ └── CommentAlreadyExistException.java │ │ └── test │ │ └── java │ │ └── blog │ │ └── ArticleTests.java ├── day05 │ ├── pom.xml │ └── src │ │ ├── main │ │ └── java │ │ │ └── people │ │ │ ├── Person.java │ │ │ ├── Pet.java │ │ │ └── PetType.java │ │ └── test │ │ └── java │ │ ├── PopulationTests.java │ │ └── PopulationWithVavrTests.java ├── day06 │ ├── pom.xml │ └── src │ │ ├── main │ │ └── java │ │ │ └── games │ │ │ ├── FizzBuzz.java │ │ │ └── OutOfRangeException.java │ │ └── test │ │ └── java │ │ └── games │ │ └── FizzBuzzTests.java ├── day07 │ ├── pom.xml │ └── src │ │ ├── main │ │ └── java │ │ │ └── ci │ │ │ ├── Pipeline.java │ │ │ ├── dependencies │ │ │ ├── Config.java │ │ │ ├── Emailer.java │ │ │ ├── Logger.java │ │ │ ├── Project.java │ │ │ └── TestStatus.java │ │ │ └── functional │ │ │ └── Pipeline.java │ │ └── test │ │ └── java │ │ └── ci │ │ ├── CapturingLogger.java │ │ ├── PipelineTest.java │ │ └── functional │ │ └── PipelineTest.java ├── day08 │ ├── pom.xml │ └── src │ │ ├── main │ │ └── java │ │ │ └── password │ │ │ ├── PasswordValidation.java │ │ │ └── functional │ │ │ ├── ParsingError.java │ │ │ └── Password.java │ │ └── test │ │ └── java │ │ ├── PasswordValidationTest.java │ │ └── functional │ │ └── PasswordTest.java ├── day09 │ ├── pom.xml │ └── src │ │ ├── main │ │ └── java │ │ │ └── account │ │ │ └── Client.java │ │ └── test │ │ └── java │ │ └── ClientTests.java ├── day10 │ ├── pom.xml │ └── src │ │ ├── main │ │ └── java │ │ │ └── games │ │ │ ├── FizzBuzz.java │ │ │ └── OutOfRangeException.java │ │ └── test │ │ └── java │ │ └── games │ │ └── FizzBuzzTests.java ├── day11 │ ├── pom.xml │ └── src │ │ ├── main │ │ └── java │ │ │ └── roman │ │ │ └── numerals │ │ │ └── RomanNumerals.java │ │ └── test │ │ └── java │ │ └── roman │ │ └── numerals │ │ └── RomanNumeralsTest.java ├── day12 │ ├── pom.xml │ └── src │ │ ├── main │ │ └── java │ │ │ └── greeting │ │ │ ├── Greeter.java │ │ │ └── functional │ │ │ └── GreeterFactory.java │ │ └── test │ │ └── java │ │ └── greeting │ │ ├── GreeterTest.java │ │ └── functional │ │ └── GreeterTest.java ├── day13 │ ├── pom.xml │ └── src │ │ ├── main │ │ └── java │ │ │ └── blog │ │ │ ├── Article.java │ │ │ ├── Comment.java │ │ │ └── CommentAlreadyExistException.java │ │ └── test │ │ └── java │ │ └── blog │ │ ├── ArticleBonusTests.java │ │ ├── ArticleBuilder.java │ │ └── ArticleTests.java ├── day14 │ ├── pom.xml │ └── src │ │ ├── main │ │ └── java │ │ │ └── games │ │ │ ├── FizzBuzz.java │ │ │ ├── Result.java │ │ │ └── vavr │ │ │ └── FizzBuzz.java │ │ └── test │ │ └── java │ │ └── games │ │ ├── FizzBuzzTests.java │ │ └── vavr │ │ └── FizzBuzzTests.java ├── day15 │ ├── pom.xml │ └── src │ │ ├── main │ │ └── java │ │ │ └── document │ │ │ ├── DocumentTemplateType.java │ │ │ └── RecordType.java │ │ └── test │ │ └── java │ │ ├── DocumentTests.combinationTests.approved.txt │ │ └── DocumentTests.java ├── day16 │ ├── pom.xml │ └── src │ │ ├── main │ │ └── java │ │ │ └── blog │ │ │ ├── Article.java │ │ │ ├── Comment.java │ │ │ └── CommentAlreadyExistException.java │ │ └── test │ │ └── java │ │ └── blog │ │ ├── ArticleBuilder.java │ │ └── ArticleTests.java ├── day17 │ ├── pom.xml │ └── src │ │ ├── main │ │ └── java │ │ │ └── games │ │ │ └── FizzBuzz.java │ │ └── test │ │ └── java │ │ └── games │ │ └── FizzBuzzTests.java ├── day18 │ ├── pom.xml │ └── src │ │ ├── main │ │ └── java │ │ │ └── lap │ │ │ └── ShittyClass.java │ │ └── test │ │ ├── java │ │ └── lap │ │ │ └── TeamRules.java │ │ └── resources │ │ └── archunit.properties ├── day19 │ ├── pom.xml │ └── src │ │ ├── main │ │ └── java │ │ │ └── blog │ │ │ ├── Article.java │ │ │ ├── Comment.java │ │ │ └── Error.java │ │ └── test │ │ └── java │ │ └── blog │ │ ├── ArticleBuilder.java │ │ └── ArticleTests.java ├── day20 │ ├── pom.xml │ └── src │ │ ├── main │ │ └── java │ │ │ └── domain │ │ │ └── yahtzee │ │ │ ├── constrain │ │ │ └── input │ │ │ │ ├── Error.java │ │ │ │ ├── Roll.java │ │ │ │ └── YahtzeeCalculator.java │ │ │ ├── hollywood │ │ │ └── principle │ │ │ │ └── YahtzeeCalculator.java │ │ │ └── original │ │ │ └── YahtzeeCalculator.java │ │ └── test │ │ └── java │ │ ├── builders │ │ └── DiceBuilder.java │ │ ├── constrain │ │ └── input │ │ │ └── YahtzeeTests.java │ │ ├── hollywood │ │ └── principle │ │ │ └── YahtzeeCalculatorTests.java │ │ └── original │ │ └── YahtzeeCalculatorTests.java ├── day21 │ ├── pom.xml │ └── src │ │ ├── main │ │ └── java │ │ │ └── audit │ │ │ ├── AddNewVisitor.java │ │ │ ├── AddRecordUseCase.java │ │ │ ├── AuditManager.java │ │ │ ├── FileContent.java │ │ │ ├── FileUpdate.java │ │ │ └── Persister.java │ │ └── test │ │ └── java │ │ └── audit │ │ └── AuditManagerShould.java ├── day22 │ ├── .tcr │ │ ├── config.yml │ │ ├── language │ │ │ └── java.yml │ │ └── toolchain │ │ │ └── maven.yml │ ├── pom.xml │ ├── src │ │ ├── main │ │ │ └── java │ │ │ │ └── diamond │ │ │ │ └── Diamond.java │ │ └── test │ │ │ └── java │ │ │ ├── DiamondTests.Approval.generate_a_diamond.approved.txt │ │ │ └── DiamondTests.java │ └── tcrw ├── day23 │ ├── pom.xml │ └── src │ │ ├── main │ │ └── java │ │ │ └── org │ │ │ └── craftedsw │ │ │ └── tripservicekata │ │ │ ├── exception │ │ │ ├── CollaboratorCallException.java │ │ │ └── UserNotLoggedInException.java │ │ │ ├── trip │ │ │ ├── Trip.java │ │ │ ├── TripDAO.java │ │ │ ├── TripRepository.java │ │ │ └── TripService.java │ │ │ └── user │ │ │ ├── User.java │ │ │ └── UserSession.java │ │ └── test │ │ └── java │ │ └── org │ │ └── craftedsw │ │ └── tripservicekata │ │ ├── trip │ │ ├── GetTripsByUserShould.java │ │ └── TripRepositoryShould.java │ │ └── user │ │ ├── UserBuilder.java │ │ └── UserShould.java ├── day24 │ ├── pom.xml │ └── src │ │ ├── main │ │ └── java │ │ │ └── M │ │ │ └── K991_P.java │ │ └── test │ │ ├── java │ │ └── M │ │ │ ├── FileUtils.java │ │ │ └── SubmarineTests.java │ │ └── resources │ │ └── submarine.txt └── pom.xml ├── kotlin ├── build.gradle.kts ├── day01 │ ├── build.gradle.kts │ └── src │ │ ├── main │ │ └── kotlin │ │ │ └── food │ │ │ └── Food.kt │ │ └── test │ │ └── kotlin │ │ └── EdibleTests.kt ├── day02 │ ├── build.gradle.kts │ └── src │ │ ├── main │ │ └── kotlin │ │ │ └── games │ │ │ ├── FizzBuzz.kt │ │ │ └── OutOfRangeException.kt │ │ └── test │ │ └── kotlin │ │ └── FizzBuzzTests.kt ├── day03 │ ├── build.gradle.kts │ └── src │ │ ├── main │ │ └── kotlin │ │ │ └── people │ │ │ └── Person.kt │ │ └── test │ │ └── kotlin │ │ └── PopulationTests.kt ├── day04 │ ├── build.gradle.kts │ └── src │ │ ├── main │ │ └── kotlin │ │ │ └── blog │ │ │ └── Blog.kt │ │ └── test │ │ └── kotlin │ │ └── BlogTests.kt ├── day05 │ ├── build.gradle.kts │ └── src │ │ ├── main │ │ └── kotlin │ │ │ └── people │ │ │ └── Person.kt │ │ └── test │ │ └── kotlin │ │ └── PopulationTests.kt ├── day06 │ ├── build.gradle.kts │ └── src │ │ ├── main │ │ └── kotlin │ │ │ └── games │ │ │ ├── FizzBuzz.kt │ │ │ └── OutOfRangeException.kt │ │ └── test │ │ └── kotlin │ │ └── FizzBuzzTests.kt ├── day07 │ ├── build.gradle.kts │ └── src │ │ ├── main │ │ └── kotlin │ │ │ └── ci │ │ │ └── Pipeline.kt │ │ └── test │ │ └── kotlin │ │ ├── CapturingLogger.kt │ │ └── PipelineTests.kt ├── day08 │ ├── build.gradle.kts │ └── src │ │ ├── main │ │ └── kotlin │ │ │ └── password │ │ │ ├── ParsingError.kt │ │ │ └── Password.kt │ │ └── test │ │ └── kotlin │ │ └── PasswordValidationTests.kt ├── day09 │ ├── build.gradle.kts │ └── src │ │ ├── main │ │ └── kotlin │ │ │ └── account │ │ │ └── Client.kt │ │ └── test │ │ └── kotlin │ │ └── ClientTests.kt ├── day10 │ ├── build.gradle.kts │ └── src │ │ ├── main │ │ └── kotlin │ │ │ └── games │ │ │ ├── FizzBuzz.kt │ │ │ └── OutOfRangeException.kt │ │ └── test │ │ └── kotlin │ │ └── FizzBuzzTests.kt ├── day11 │ ├── build.gradle.kts │ └── src │ │ ├── main │ │ └── kotlin │ │ │ └── roman │ │ │ └── numerals │ │ │ └── RomanNumerals.kt │ │ └── test │ │ └── kotlin │ │ ├── RomanNumeralsTests.kt │ │ └── RomanProperties.kt ├── day12 │ ├── build.gradle.kts │ └── src │ │ ├── main │ │ └── kotlin │ │ │ └── greeting │ │ │ └── Greeting.kt │ │ └── test │ │ └── kotlin │ │ └── GreeterTests.kt ├── day13 │ ├── build.gradle.kts │ └── src │ │ ├── main │ │ └── kotlin │ │ │ └── blog │ │ │ └── Blog.kt │ │ └── test │ │ └── kotlin │ │ ├── ArticleBuilder.kt │ │ └── BlogTests.kt ├── day14 │ ├── build.gradle.kts │ └── src │ │ ├── main │ │ └── kotlin │ │ │ └── games │ │ │ └── FizzBuzz.kt │ │ └── test │ │ └── kotlin │ │ └── FizzBuzzTests.kt ├── day15 │ ├── build.gradle.kts │ └── src │ │ ├── main │ │ └── kotlin │ │ │ └── document │ │ │ ├── DocumentTemplateType.kt │ │ │ └── RecordType.kt │ │ └── test │ │ └── kotlin │ │ ├── DocumentTests.combinationTests.approved.txt │ │ └── DocumentTests.kt ├── day16 │ ├── build.gradle.kts │ └── src │ │ ├── main │ │ └── kotlin │ │ │ └── blog │ │ │ └── Blog.kt │ │ └── test │ │ └── kotlin │ │ ├── ArticleBuilder.kt │ │ └── BlogTests.kt ├── day17 │ ├── build.gradle.kts │ └── src │ │ ├── main │ │ └── kotlin │ │ │ └── games │ │ │ └── FizzBuzz.kt │ │ └── test │ │ └── kotlin │ │ ├── FizzBuzzProperties.kt │ │ └── FizzBuzzTests.kt ├── day18 │ ├── build.gradle.kts │ └── src │ │ ├── main │ │ └── kotlin │ │ │ └── lap │ │ │ └── ShittyClass.kt │ │ └── test │ │ ├── kotlin │ │ └── TeamRules.kt │ │ └── resources │ │ └── archunit.properties ├── day19 │ ├── build.gradle.kts │ └── src │ │ ├── main │ │ └── kotlin │ │ │ └── blog │ │ │ └── Blog.kt │ │ └── test │ │ └── kotlin │ │ ├── ArticleBuilder.kt │ │ └── BlogTests.kt ├── day20 │ ├── build.gradle.kts │ └── src │ │ ├── main │ │ └── kotlin │ │ │ └── domain │ │ │ └── yahtzee │ │ │ ├── constrain │ │ │ └── input │ │ │ │ ├── Error.kt │ │ │ │ ├── Roll.kt │ │ │ │ └── YahtzeeCalculator.kt │ │ │ ├── hollywood │ │ │ └── principle │ │ │ │ └── YahtzeeCalculator.kt │ │ │ └── original │ │ │ └── YahtzeeCalculator.kt │ │ └── test │ │ └── kotlin │ │ ├── builders │ │ └── DiceBuilder.kt │ │ ├── constrain │ │ └── input │ │ │ └── YahtzeeCalculatorTests.kt │ │ ├── hollywood │ │ └── principle │ │ │ └── YahtzeeCalculatorTests.kt │ │ ├── original │ │ └── YahtzeeCalculatorTests.kt │ │ └── parameters │ │ └── ParameterizedTests.kt ├── day21 │ ├── build.gradle.kts │ └── src │ │ ├── main │ │ └── kotlin │ │ │ └── audit │ │ │ ├── AddNewVisitor.kt │ │ │ ├── AddRecordUseCase.kt │ │ │ ├── AuditManager.kt │ │ │ ├── FileContent.kt │ │ │ ├── FileUpdate.kt │ │ │ └── Persister.kt │ │ └── test │ │ └── kotlin │ │ └── AuditManagerTests.kt ├── day22 │ ├── .tcr │ │ ├── config.yml │ │ ├── language │ │ │ └── java.yml │ │ └── toolchain │ │ │ └── maven.yml │ ├── build.gradle.kts │ ├── src │ │ ├── main │ │ │ └── kotlin │ │ │ │ └── diamond │ │ │ │ └── Diamond.kt │ │ └── test │ │ │ └── kotlin │ │ │ ├── DiamondProperties.kt │ │ │ ├── DiamondTests.kt │ │ │ └── DiamondTests.print diamond for K.approved.txt │ └── tcrw ├── day23 │ ├── build.gradle.kts │ └── src │ │ ├── main │ │ └── kotlin │ │ │ └── org │ │ │ └── craftedsw │ │ │ └── tripservicekata │ │ │ ├── exception │ │ │ ├── CollaboratorCallException.kt │ │ │ └── UserNotLoggedInException.kt │ │ │ ├── trip │ │ │ ├── Trip.kt │ │ │ ├── TripDAO.kt │ │ │ ├── TripRepository.kt │ │ │ └── TripService.kt │ │ │ └── user │ │ │ ├── User.kt │ │ │ └── UserSession.kt │ │ └── test │ │ └── kotlin │ │ └── tripservicekata │ │ ├── trip │ │ ├── RepositoryTests.kt │ │ └── RetrieveTripsByUser.kt │ │ └── user │ │ ├── UserBuilder.kt │ │ └── UserTests.kt ├── day24 │ ├── build.gradle.kts │ └── src │ │ ├── main │ │ └── kotlin │ │ │ └── M │ │ │ └── K991_P.kt │ │ └── test │ │ ├── kotlin │ │ └── SubmarineTests.kt │ │ └── resources │ │ └── submarine.txt ├── gradle.properties ├── gradle │ └── wrapper │ │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat └── settings.gradle.kts └── ts ├── day01 ├── jest.config.js ├── package-lock.json ├── package.json ├── src │ └── food.ts ├── tests │ └── food.spec.ts └── tsconfig.json ├── day02 ├── jest.config.js ├── package-lock.json ├── package.json ├── src │ └── fizzbuzz.ts ├── tests │ └── fizzbuzz.spec.ts └── tsconfig.json ├── day03 ├── jest.config.js ├── package-lock.json ├── package.json ├── src │ └── people.ts ├── tests │ └── people.spec.ts └── tsconfig.json ├── day04 ├── jest.config.js ├── package-lock.json ├── package.json ├── src │ └── blog.ts ├── tests │ └── blog.spec.ts └── tsconfig.json ├── day05 ├── jest.config.js ├── package-lock.json ├── package.json ├── src │ └── people.ts ├── tests │ └── people.spec.ts └── tsconfig.json ├── day06 ├── jest.config.js ├── package-lock.json ├── package.json ├── src │ └── fizzbuzz.ts ├── tests │ └── fizzbuzz.spec.ts └── tsconfig.json ├── day07 ├── jest.config.js ├── package-lock.json ├── package.json ├── src │ ├── ci.ts │ ├── pipeline.ts │ └── project.ts ├── tests │ ├── capturingLogger.ts │ └── pipeline.spec.ts └── tsconfig.json ├── day08 ├── jest.config.js ├── package-lock.json ├── package.json ├── src │ └── password.ts ├── tests │ └── password.spec.ts └── tsconfig.json ├── day09 ├── jest.config.js ├── package.json ├── src │ └── accountability.ts ├── tests │ └── accountability.spec.ts └── tsconfig.json ├── day10 ├── jest.config.js ├── package-lock.json ├── package.json ├── src │ └── fizzbuzz.ts ├── tests │ └── fizzbuzz.spec.ts └── tsconfig.json ├── day11 ├── img │ └── libyear.png ├── jest.config.js ├── package-lock.json ├── package.json ├── src │ └── romanNumerals.ts ├── tests │ └── romanNumerals.spec.ts └── tsconfig.json ├── day12 ├── jest.config.js ├── package-lock.json ├── package.json ├── src │ └── greeter.ts ├── tests │ └── greeter.spec.ts └── tsconfig.json ├── day13 ├── jest.config.js ├── package-lock.json ├── package.json ├── src │ └── blog.ts ├── tests │ ├── articleBuilder.ts │ └── blog.spec.ts └── tsconfig.json ├── day14 ├── jest.config.js ├── package-lock.json ├── package.json ├── src │ ├── fizzbuzz.js │ ├── fizzbuzz.js.map │ └── fizzbuzz.ts ├── tests │ ├── fizzbuzz.spec.js │ ├── fizzbuzz.spec.js.map │ └── fizzbuzz.spec.ts └── tsconfig.json ├── day15 ├── jest.config.js ├── package-lock.json ├── package.json ├── src │ ├── documentTemplateType.ts │ └── recordType.ts ├── tests │ ├── documents.spec.documents_golden_master_for_refactoring.approved.txt │ └── documents.spec.ts └── tsconfig.json ├── day16 ├── jest.config.js ├── package-lock.json ├── package.json ├── src │ └── blog.ts ├── tests │ ├── articleBuilder.ts │ └── blog.spec.ts └── tsconfig.json ├── day17 ├── jest.config.js ├── package-lock.json ├── package.json ├── src │ └── fizzbuzz.ts ├── tests │ └── fizzbuzz.spec.ts └── tsconfig.json ├── day18 ├── jest.config.js ├── package-lock.json ├── package.json ├── src │ └── shitty.ts ├── tests │ └── teamRules.ts └── tsconfig.json ├── day19 ├── jest.config.js ├── package-lock.json ├── package.json ├── src │ └── blog.ts ├── tests │ ├── articleBuilder.ts │ └── blog.spec.ts └── tsconfig.json ├── day20 ├── jest.config.js ├── package-lock.json ├── package.json ├── src │ └── domain │ │ └── yahtzee │ │ ├── constrain-input │ │ ├── roll.ts │ │ └── yahtzeeCalculator.ts │ │ ├── hollywood-principle │ │ └── yahtzeeCalculator.ts │ │ └── original │ │ └── yahtzeeCalculator.ts ├── tests │ ├── constrain-input │ │ └── yahtzee.spec.ts │ ├── diceBuilder.ts │ ├── hollywood-principle │ │ └── yahtzee.spec.ts │ └── original │ │ └── yahtzee.spec.ts └── tsconfig.json ├── day21 ├── jest.config.js ├── package-lock.json ├── package.json ├── src │ ├── addRecordUseCase.ts │ ├── audit.ts │ └── persister.ts ├── tests │ └── audit.spec.ts └── tsconfig.json ├── day22 ├── jest.config.js ├── package-lock.json ├── package.json ├── src │ └── diamond.ts ├── tests │ ├── diamond.spec.diamond_generate_a_pretty_diamond_for_human_eyes.approved.txt │ └── diamond.spec.ts └── tsconfig.json ├── day23 ├── jest.config.js ├── package-lock.json ├── package.json ├── src │ ├── exception │ │ ├── CollaboratorCallException.ts │ │ └── UserNotLoggedInException.ts │ ├── trip │ │ ├── Trip.ts │ │ ├── TripDAO.ts │ │ ├── TripRepository.ts │ │ └── TripService.ts │ └── user │ │ ├── User.ts │ │ └── UserSession.ts ├── tests │ ├── trip │ │ ├── triprepository.spec.ts │ │ └── tripservice.spec.ts │ └── user │ │ ├── user.spec.ts │ │ └── userBuilder.ts └── tsconfig.json └── day24 ├── jest.config.js ├── package-lock.json ├── package.json ├── src └── K991_P.ts ├── tests ├── fileutils.ts ├── submarine.spec.ts └── submarine.txt └── tsconfig.json /docs/exercise/day01/snippet.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/advent-of-craft/2023/178dfa1e2fbd640c65fc903122b1fcda77d7fa9c/docs/exercise/day01/snippet.png -------------------------------------------------------------------------------- /docs/exercise/day01/solution/img/extract-method.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/advent-of-craft/2023/178dfa1e2fbd640c65fc903122b1fcda77d7fa9c/docs/exercise/day01/solution/img/extract-method.png -------------------------------------------------------------------------------- /docs/exercise/day01/solution/img/simplify-if-else.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/advent-of-craft/2023/178dfa1e2fbd640c65fc903122b1fcda77d7fa9c/docs/exercise/day01/solution/img/simplify-if-else.png -------------------------------------------------------------------------------- /docs/exercise/day01/solution/snippet.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/advent-of-craft/2023/178dfa1e2fbd640c65fc903122b1fcda77d7fa9c/docs/exercise/day01/solution/snippet.png -------------------------------------------------------------------------------- /docs/exercise/day02/snippet.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/advent-of-craft/2023/178dfa1e2fbd640c65fc903122b1fcda77d7fa9c/docs/exercise/day02/snippet.png -------------------------------------------------------------------------------- /docs/exercise/day02/solution/img/invert-if.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/advent-of-craft/2023/178dfa1e2fbd640c65fc903122b1fcda77d7fa9c/docs/exercise/day02/solution/img/invert-if.png -------------------------------------------------------------------------------- /docs/exercise/day02/solution/img/invert-second-if.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/advent-of-craft/2023/178dfa1e2fbd640c65fc903122b1fcda77d7fa9c/docs/exercise/day02/solution/img/invert-second-if.png -------------------------------------------------------------------------------- /docs/exercise/day02/solution/img/remove-redundant-else.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/advent-of-craft/2023/178dfa1e2fbd640c65fc903122b1fcda77d7fa9c/docs/exercise/day02/solution/img/remove-redundant-else.png -------------------------------------------------------------------------------- /docs/exercise/day02/solution/snippet.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/advent-of-craft/2023/178dfa1e2fbd640c65fc903122b1fcda77d7fa9c/docs/exercise/day02/solution/snippet.png -------------------------------------------------------------------------------- /docs/exercise/day03/snippet.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/advent-of-craft/2023/178dfa1e2fbd640c65fc903122b1fcda77d7fa9c/docs/exercise/day03/snippet.png -------------------------------------------------------------------------------- /docs/exercise/day03/solution/img/define-automatic-suggestions.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/advent-of-craft/2023/178dfa1e2fbd640c65fc903122b1fcda77d7fa9c/docs/exercise/day03/solution/img/define-automatic-suggestions.png -------------------------------------------------------------------------------- /docs/exercise/day03/solution/img/define-practice.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/advent-of-craft/2023/178dfa1e2fbd640c65fc903122b1fcda77d7fa9c/docs/exercise/day03/solution/img/define-practice.png -------------------------------------------------------------------------------- /docs/exercise/day03/solution/img/explanations.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/advent-of-craft/2023/178dfa1e2fbd640c65fc903122b1fcda77d7fa9c/docs/exercise/day03/solution/img/explanations.png -------------------------------------------------------------------------------- /docs/exercise/day03/solution/img/extract-method.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/advent-of-craft/2023/178dfa1e2fbd640c65fc903122b1fcda77d7fa9c/docs/exercise/day03/solution/img/extract-method.png -------------------------------------------------------------------------------- /docs/exercise/day03/solution/img/ide-help.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/advent-of-craft/2023/178dfa1e2fbd640c65fc903122b1fcda77d7fa9c/docs/exercise/day03/solution/img/ide-help.png -------------------------------------------------------------------------------- /docs/exercise/day03/solution/img/line-returns.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/advent-of-craft/2023/178dfa1e2fbd640c65fc903122b1fcda77d7fa9c/docs/exercise/day03/solution/img/line-returns.png -------------------------------------------------------------------------------- /docs/exercise/day03/solution/img/no-more-rockets.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/advent-of-craft/2023/178dfa1e2fbd640c65fc903122b1fcda77d7fa9c/docs/exercise/day03/solution/img/no-more-rockets.png -------------------------------------------------------------------------------- /docs/exercise/day03/solution/img/promyze-detection.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/advent-of-craft/2023/178dfa1e2fbd640c65fc903122b1fcda77d7fa9c/docs/exercise/day03/solution/img/promyze-detection.png -------------------------------------------------------------------------------- /docs/exercise/day03/solution/snippet.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/advent-of-craft/2023/178dfa1e2fbd640c65fc903122b1fcda77d7fa9c/docs/exercise/day03/solution/snippet.png -------------------------------------------------------------------------------- /docs/exercise/day04/snippet.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/advent-of-craft/2023/178dfa1e2fbd640c65fc903122b1fcda77d7fa9c/docs/exercise/day04/snippet.png -------------------------------------------------------------------------------- /docs/exercise/day04/solution/snippet.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/advent-of-craft/2023/178dfa1e2fbd640c65fc903122b1fcda77d7fa9c/docs/exercise/day04/solution/snippet.png -------------------------------------------------------------------------------- /docs/exercise/day05/snippet.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/advent-of-craft/2023/178dfa1e2fbd640c65fc903122b1fcda77d7fa9c/docs/exercise/day05/snippet.png -------------------------------------------------------------------------------- /docs/exercise/day05/solution/img/extract-method.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/advent-of-craft/2023/178dfa1e2fbd640c65fc903122b1fcda77d7fa9c/docs/exercise/day05/solution/img/extract-method.png -------------------------------------------------------------------------------- /docs/exercise/day05/solution/img/extract-variable.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/advent-of-craft/2023/178dfa1e2fbd640c65fc903122b1fcda77d7fa9c/docs/exercise/day05/solution/img/extract-variable.png -------------------------------------------------------------------------------- /docs/exercise/day05/solution/img/foreach.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/advent-of-craft/2023/178dfa1e2fbd640c65fc903122b1fcda77d7fa9c/docs/exercise/day05/solution/img/foreach.png -------------------------------------------------------------------------------- /docs/exercise/day05/solution/snippet.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/advent-of-craft/2023/178dfa1e2fbd640c65fc903122b1fcda77d7fa9c/docs/exercise/day05/solution/snippet.png -------------------------------------------------------------------------------- /docs/exercise/day06/snippet.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/advent-of-craft/2023/178dfa1e2fbd640c65fc903122b1fcda77d7fa9c/docs/exercise/day06/snippet.png -------------------------------------------------------------------------------- /docs/exercise/day06/solution/img/change-expected-result.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/advent-of-craft/2023/178dfa1e2fbd640c65fc903122b1fcda77d7fa9c/docs/exercise/day06/solution/img/change-expected-result.png -------------------------------------------------------------------------------- /docs/exercise/day06/solution/img/extract-parameter.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/advent-of-craft/2023/178dfa1e2fbd640c65fc903122b1fcda77d7fa9c/docs/exercise/day06/solution/img/extract-parameter.png -------------------------------------------------------------------------------- /docs/exercise/day06/solution/img/method-source.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/advent-of-craft/2023/178dfa1e2fbd640c65fc903122b1fcda77d7fa9c/docs/exercise/day06/solution/img/method-source.png -------------------------------------------------------------------------------- /docs/exercise/day06/solution/snippet.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/advent-of-craft/2023/178dfa1e2fbd640c65fc903122b1fcda77d7fa9c/docs/exercise/day06/solution/snippet.png -------------------------------------------------------------------------------- /docs/exercise/day07/snippet.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/advent-of-craft/2023/178dfa1e2fbd640c65fc903122b1fcda77d7fa9c/docs/exercise/day07/snippet.png -------------------------------------------------------------------------------- /docs/exercise/day07/solution/img/extract-method.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/advent-of-craft/2023/178dfa1e2fbd640c65fc903122b1fcda77d7fa9c/docs/exercise/day07/solution/img/extract-method.png -------------------------------------------------------------------------------- /docs/exercise/day07/solution/img/invert-if.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/advent-of-craft/2023/178dfa1e2fbd640c65fc903122b1fcda77d7fa9c/docs/exercise/day07/solution/img/invert-if.png -------------------------------------------------------------------------------- /docs/exercise/day07/solution/img/remove-redundant-else.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/advent-of-craft/2023/178dfa1e2fbd640c65fc903122b1fcda77d7fa9c/docs/exercise/day07/solution/img/remove-redundant-else.png -------------------------------------------------------------------------------- /docs/exercise/day07/solution/img/snippet-vavr.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/advent-of-craft/2023/178dfa1e2fbd640c65fc903122b1fcda77d7fa9c/docs/exercise/day07/solution/img/snippet-vavr.png -------------------------------------------------------------------------------- /docs/exercise/day07/solution/img/snippet.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/advent-of-craft/2023/178dfa1e2fbd640c65fc903122b1fcda77d7fa9c/docs/exercise/day07/solution/img/snippet.png -------------------------------------------------------------------------------- /docs/exercise/day07/solution/snippet-vavr.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/advent-of-craft/2023/178dfa1e2fbd640c65fc903122b1fcda77d7fa9c/docs/exercise/day07/solution/snippet-vavr.png -------------------------------------------------------------------------------- /docs/exercise/day07/solution/snippet.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/advent-of-craft/2023/178dfa1e2fbd640c65fc903122b1fcda77d7fa9c/docs/exercise/day07/solution/snippet.png -------------------------------------------------------------------------------- /docs/exercise/day08/img/double_loop.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/advent-of-craft/2023/178dfa1e2fbd640c65fc903122b1fcda77d7fa9c/docs/exercise/day08/img/double_loop.jpg -------------------------------------------------------------------------------- /docs/exercise/day08/img/double_loop.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/advent-of-craft/2023/178dfa1e2fbd640c65fc903122b1fcda77d7fa9c/docs/exercise/day08/img/double_loop.png -------------------------------------------------------------------------------- /docs/exercise/day08/snippet.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/advent-of-craft/2023/178dfa1e2fbd640c65fc903122b1fcda77d7fa9c/docs/exercise/day08/snippet.png -------------------------------------------------------------------------------- /docs/exercise/day08/solution/img/chaGTP-answer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/advent-of-craft/2023/178dfa1e2fbd640c65fc903122b1fcda77d7fa9c/docs/exercise/day08/solution/img/chaGTP-answer.png -------------------------------------------------------------------------------- /docs/exercise/day08/solution/img/extract-chars.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/advent-of-craft/2023/178dfa1e2fbd640c65fc903122b1fcda77d7fa9c/docs/exercise/day08/solution/img/extract-chars.png -------------------------------------------------------------------------------- /docs/exercise/day08/solution/img/first-failing-test.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/advent-of-craft/2023/178dfa1e2fbd640c65fc903122b1fcda77d7fa9c/docs/exercise/day08/solution/img/first-failing-test.png -------------------------------------------------------------------------------- /docs/exercise/day08/solution/img/golden-failing.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/advent-of-craft/2023/178dfa1e2fbd640c65fc903122b1fcda77d7fa9c/docs/exercise/day08/solution/img/golden-failing.png -------------------------------------------------------------------------------- /docs/exercise/day08/solution/img/move-package.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/advent-of-craft/2023/178dfa1e2fbd640c65fc903122b1fcda77d7fa9c/docs/exercise/day08/solution/img/move-package.png -------------------------------------------------------------------------------- /docs/exercise/day08/solution/img/param-test-reason.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/advent-of-craft/2023/178dfa1e2fbd640c65fc903122b1fcda77d7fa9c/docs/exercise/day08/solution/img/param-test-reason.png -------------------------------------------------------------------------------- /docs/exercise/day08/solution/img/simplify-conditional.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/advent-of-craft/2023/178dfa1e2fbd640c65fc903122b1fcda77d7fa9c/docs/exercise/day08/solution/img/simplify-conditional.png -------------------------------------------------------------------------------- /docs/exercise/day08/solution/img/snippet-chatgpt.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/advent-of-craft/2023/178dfa1e2fbd640c65fc903122b1fcda77d7fa9c/docs/exercise/day08/solution/img/snippet-chatgpt.png -------------------------------------------------------------------------------- /docs/exercise/day08/solution/img/snippet.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/advent-of-craft/2023/178dfa1e2fbd640c65fc903122b1fcda77d7fa9c/docs/exercise/day08/solution/img/snippet.png -------------------------------------------------------------------------------- /docs/exercise/day09/snippet.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/advent-of-craft/2023/178dfa1e2fbd640c65fc903122b1fcda77d7fa9c/docs/exercise/day09/snippet.png -------------------------------------------------------------------------------- /docs/exercise/day09/solution/img/generate-code.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/advent-of-craft/2023/178dfa1e2fbd640c65fc903122b1fcda77d7fa9c/docs/exercise/day09/solution/img/generate-code.png -------------------------------------------------------------------------------- /docs/exercise/day09/solution/img/remove-field.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/advent-of-craft/2023/178dfa1e2fbd640c65fc903122b1fcda77d7fa9c/docs/exercise/day09/solution/img/remove-field.png -------------------------------------------------------------------------------- /docs/exercise/day09/solution/snippet.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/advent-of-craft/2023/178dfa1e2fbd640c65fc903122b1fcda77d7fa9c/docs/exercise/day09/solution/snippet.png -------------------------------------------------------------------------------- /docs/exercise/day10/snippet.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/advent-of-craft/2023/178dfa1e2fbd640c65fc903122b1fcda77d7fa9c/docs/exercise/day10/snippet.png -------------------------------------------------------------------------------- /docs/exercise/day10/solution/img/remove-convert-safely.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/advent-of-craft/2023/178dfa1e2fbd640c65fc903122b1fcda77d7fa9c/docs/exercise/day10/solution/img/remove-convert-safely.png -------------------------------------------------------------------------------- /docs/exercise/day10/solution/snippet.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/advent-of-craft/2023/178dfa1e2fbd640c65fc903122b1fcda77d7fa9c/docs/exercise/day10/solution/snippet.png -------------------------------------------------------------------------------- /docs/exercise/day11/snippet.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/advent-of-craft/2023/178dfa1e2fbd640c65fc903122b1fcda77d7fa9c/docs/exercise/day11/snippet.png -------------------------------------------------------------------------------- /docs/exercise/day11/solution/img/configuration.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/advent-of-craft/2023/178dfa1e2fbd640c65fc903122b1fcda77d7fa9c/docs/exercise/day11/solution/img/configuration.png -------------------------------------------------------------------------------- /docs/exercise/day11/solution/img/deming.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/advent-of-craft/2023/178dfa1e2fbd640c65fc903122b1fcda77d7fa9c/docs/exercise/day11/solution/img/deming.jpg -------------------------------------------------------------------------------- /docs/exercise/day11/solution/img/failing-build.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/advent-of-craft/2023/178dfa1e2fbd640c65fc903122b1fcda77d7fa9c/docs/exercise/day11/solution/img/failing-build.png -------------------------------------------------------------------------------- /docs/exercise/day11/solution/img/libyear.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/advent-of-craft/2023/178dfa1e2fbd640c65fc903122b1fcda77d7fa9c/docs/exercise/day11/solution/img/libyear.webp -------------------------------------------------------------------------------- /docs/exercise/day11/solution/img/result.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/advent-of-craft/2023/178dfa1e2fbd640c65fc903122b1fcda77d7fa9c/docs/exercise/day11/solution/img/result.png -------------------------------------------------------------------------------- /docs/exercise/day11/solution/snippet.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/advent-of-craft/2023/178dfa1e2fbd640c65fc903122b1fcda77d7fa9c/docs/exercise/day11/solution/snippet.png -------------------------------------------------------------------------------- /docs/exercise/day12/snippet.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/advent-of-craft/2023/178dfa1e2fbd640c65fc903122b1fcda77d7fa9c/docs/exercise/day12/snippet.png -------------------------------------------------------------------------------- /docs/exercise/day12/solution/img/class-diagram.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/advent-of-craft/2023/178dfa1e2fbd640c65fc903122b1fcda77d7fa9c/docs/exercise/day12/solution/img/class-diagram.png -------------------------------------------------------------------------------- /docs/exercise/day12/solution/img/extract-method-duplication.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/advent-of-craft/2023/178dfa1e2fbd640c65fc903122b1fcda77d7fa9c/docs/exercise/day12/solution/img/extract-method-duplication.png -------------------------------------------------------------------------------- /docs/exercise/day12/solution/img/failure-reason-explained.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/advent-of-craft/2023/178dfa1e2fbd640c65fc903122b1fcda77d7fa9c/docs/exercise/day12/solution/img/failure-reason-explained.png -------------------------------------------------------------------------------- /docs/exercise/day12/solution/img/red-hello.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/advent-of-craft/2023/178dfa1e2fbd640c65fc903122b1fcda77d7fa9c/docs/exercise/day12/solution/img/red-hello.png -------------------------------------------------------------------------------- /docs/exercise/day12/solution/img/safe-delete.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/advent-of-craft/2023/178dfa1e2fbd640c65fc903122b1fcda77d7fa9c/docs/exercise/day12/solution/img/safe-delete.png -------------------------------------------------------------------------------- /docs/exercise/day12/solution/snippet.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/advent-of-craft/2023/178dfa1e2fbd640c65fc903122b1fcda77d7fa9c/docs/exercise/day12/solution/snippet.png -------------------------------------------------------------------------------- /docs/exercise/day13/snippet.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/advent-of-craft/2023/178dfa1e2fbd640c65fc903122b1fcda77d7fa9c/docs/exercise/day13/snippet.png -------------------------------------------------------------------------------- /docs/exercise/day13/solution/img/comment-in-the-builder.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/advent-of-craft/2023/178dfa1e2fbd640c65fc903122b1fcda77d7fa9c/docs/exercise/day13/solution/img/comment-in-the-builder.png -------------------------------------------------------------------------------- /docs/exercise/day13/solution/img/duplication.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/advent-of-craft/2023/178dfa1e2fbd640c65fc903122b1fcda77d7fa9c/docs/exercise/day13/solution/img/duplication.png -------------------------------------------------------------------------------- /docs/exercise/day13/solution/img/extract-method.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/advent-of-craft/2023/178dfa1e2fbd640c65fc903122b1fcda77d7fa9c/docs/exercise/day13/solution/img/extract-method.png -------------------------------------------------------------------------------- /docs/exercise/day13/solution/img/generate-code-from-usage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/advent-of-craft/2023/178dfa1e2fbd640c65fc903122b1fcda77d7fa9c/docs/exercise/day13/solution/img/generate-code-from-usage.png -------------------------------------------------------------------------------- /docs/exercise/day13/solution/snippet.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/advent-of-craft/2023/178dfa1e2fbd640c65fc903122b1fcda77d7fa9c/docs/exercise/day13/solution/snippet.png -------------------------------------------------------------------------------- /docs/exercise/day14/snippet.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/advent-of-craft/2023/178dfa1e2fbd640c65fc903122b1fcda77d7fa9c/docs/exercise/day14/snippet.png -------------------------------------------------------------------------------- /docs/exercise/day14/solution/img/convert-not-safe.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/advent-of-craft/2023/178dfa1e2fbd640c65fc903122b1fcda77d7fa9c/docs/exercise/day14/solution/img/convert-not-safe.png -------------------------------------------------------------------------------- /docs/exercise/day14/solution/img/failing-test.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/advent-of-craft/2023/178dfa1e2fbd640c65fc903122b1fcda77d7fa9c/docs/exercise/day14/solution/img/failing-test.png -------------------------------------------------------------------------------- /docs/exercise/day14/solution/img/remove-convert.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/advent-of-craft/2023/178dfa1e2fbd640c65fc903122b1fcda77d7fa9c/docs/exercise/day14/solution/img/remove-convert.png -------------------------------------------------------------------------------- /docs/exercise/day14/solution/snippet-vavr.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/advent-of-craft/2023/178dfa1e2fbd640c65fc903122b1fcda77d7fa9c/docs/exercise/day14/solution/snippet-vavr.png -------------------------------------------------------------------------------- /docs/exercise/day14/solution/snippet.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/advent-of-craft/2023/178dfa1e2fbd640c65fc903122b1fcda77d7fa9c/docs/exercise/day14/solution/snippet.png -------------------------------------------------------------------------------- /docs/exercise/day15/snippet.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/advent-of-craft/2023/178dfa1e2fbd640c65fc903122b1fcda77d7fa9c/docs/exercise/day15/snippet.png -------------------------------------------------------------------------------- /docs/exercise/day15/solution/img/2-files.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/advent-of-craft/2023/178dfa1e2fbd640c65fc903122b1fcda77d7fa9c/docs/exercise/day15/solution/img/2-files.png -------------------------------------------------------------------------------- /docs/exercise/day15/solution/img/approval-testing-cheatsheet.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/advent-of-craft/2023/178dfa1e2fbd640c65fc903122b1fcda77d7fa9c/docs/exercise/day15/solution/img/approval-testing-cheatsheet.png -------------------------------------------------------------------------------- /docs/exercise/day15/solution/img/code-coverage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/advent-of-craft/2023/178dfa1e2fbd640c65fc903122b1fcda77d7fa9c/docs/exercise/day15/solution/img/code-coverage.png -------------------------------------------------------------------------------- /docs/exercise/day15/solution/img/fail.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/advent-of-craft/2023/178dfa1e2fbd640c65fc903122b1fcda77d7fa9c/docs/exercise/day15/solution/img/fail.png -------------------------------------------------------------------------------- /docs/exercise/day15/solution/img/file-compare.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/advent-of-craft/2023/178dfa1e2fbd640c65fc903122b1fcda77d7fa9c/docs/exercise/day15/solution/img/file-compare.png -------------------------------------------------------------------------------- /docs/exercise/day15/solution/img/first-run.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/advent-of-craft/2023/178dfa1e2fbd640c65fc903122b1fcda77d7fa9c/docs/exercise/day15/solution/img/first-run.png -------------------------------------------------------------------------------- /docs/exercise/day15/solution/img/use-combinations.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/advent-of-craft/2023/178dfa1e2fbd640c65fc903122b1fcda77d7fa9c/docs/exercise/day15/solution/img/use-combinations.png -------------------------------------------------------------------------------- /docs/exercise/day15/solution/snippet.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/advent-of-craft/2023/178dfa1e2fbd640c65fc903122b1fcda77d7fa9c/docs/exercise/day15/solution/snippet.png -------------------------------------------------------------------------------- /docs/exercise/day16/snippet.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/advent-of-craft/2023/178dfa1e2fbd640c65fc903122b1fcda77d7fa9c/docs/exercise/day16/snippet.png -------------------------------------------------------------------------------- /docs/exercise/day16/solution/img/article-contract.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/advent-of-craft/2023/178dfa1e2fbd640c65fc903122b1fcda77d7fa9c/docs/exercise/day16/solution/img/article-contract.png -------------------------------------------------------------------------------- /docs/exercise/day16/solution/img/create-constructor.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/advent-of-craft/2023/178dfa1e2fbd640c65fc903122b1fcda77d7fa9c/docs/exercise/day16/solution/img/create-constructor.png -------------------------------------------------------------------------------- /docs/exercise/day16/solution/img/failing-tests.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/advent-of-craft/2023/178dfa1e2fbd640c65fc903122b1fcda77d7fa9c/docs/exercise/day16/solution/img/failing-tests.png -------------------------------------------------------------------------------- /docs/exercise/day16/solution/img/return-this.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/advent-of-craft/2023/178dfa1e2fbd640c65fc903122b1fcda77d7fa9c/docs/exercise/day16/solution/img/return-this.png -------------------------------------------------------------------------------- /docs/exercise/day16/solution/img/test-as-a-driver.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/advent-of-craft/2023/178dfa1e2fbd640c65fc903122b1fcda77d7fa9c/docs/exercise/day16/solution/img/test-as-a-driver.png -------------------------------------------------------------------------------- /docs/exercise/day16/solution/img/tests-are-still-failing.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/advent-of-craft/2023/178dfa1e2fbd640c65fc903122b1fcda77d7fa9c/docs/exercise/day16/solution/img/tests-are-still-failing.png -------------------------------------------------------------------------------- /docs/exercise/day16/solution/snippet.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/advent-of-craft/2023/178dfa1e2fbd640c65fc903122b1fcda77d7fa9c/docs/exercise/day16/solution/snippet.png -------------------------------------------------------------------------------- /docs/exercise/day17/snippet.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/advent-of-craft/2023/178dfa1e2fbd640c65fc903122b1fcda77d7fa9c/docs/exercise/day17/snippet.png -------------------------------------------------------------------------------- /docs/exercise/day17/solution/img/create-input.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/advent-of-craft/2023/178dfa1e2fbd640c65fc903122b1fcda77d7fa9c/docs/exercise/day17/solution/img/create-input.png -------------------------------------------------------------------------------- /docs/exercise/day17/solution/img/discoverability.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/advent-of-craft/2023/178dfa1e2fbd640c65fc903122b1fcda77d7fa9c/docs/exercise/day17/solution/img/discoverability.png -------------------------------------------------------------------------------- /docs/exercise/day17/solution/img/failing-property.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/advent-of-craft/2023/178dfa1e2fbd640c65fc903122b1fcda77d7fa9c/docs/exercise/day17/solution/img/failing-property.png -------------------------------------------------------------------------------- /docs/exercise/day17/solution/snippet.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/advent-of-craft/2023/178dfa1e2fbd640c65fc903122b1fcda77d7fa9c/docs/exercise/day17/solution/snippet.png -------------------------------------------------------------------------------- /docs/exercise/day18/snippet.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/advent-of-craft/2023/178dfa1e2fbd640c65fc903122b1fcda77d7fa9c/docs/exercise/day18/snippet.png -------------------------------------------------------------------------------- /docs/exercise/day18/solution/img/a2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/advent-of-craft/2023/178dfa1e2fbd640c65fc903122b1fcda77d7fa9c/docs/exercise/day18/solution/img/a2.png -------------------------------------------------------------------------------- /docs/exercise/day18/solution/img/dot-driven-development.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/advent-of-craft/2023/178dfa1e2fbd640c65fc903122b1fcda77d7fa9c/docs/exercise/day18/solution/img/dot-driven-development.png -------------------------------------------------------------------------------- /docs/exercise/day18/solution/img/extract-parameter.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/advent-of-craft/2023/178dfa1e2fbd640c65fc903122b1fcda77d7fa9c/docs/exercise/day18/solution/img/extract-parameter.png -------------------------------------------------------------------------------- /docs/exercise/day18/solution/img/getter-void.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/advent-of-craft/2023/178dfa1e2fbd640c65fc903122b1fcda77d7fa9c/docs/exercise/day18/solution/img/getter-void.png -------------------------------------------------------------------------------- /docs/exercise/day18/solution/img/lap-archunit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/advent-of-craft/2023/178dfa1e2fbd640c65fc903122b1fcda77d7fa9c/docs/exercise/day18/solution/img/lap-archunit.png -------------------------------------------------------------------------------- /docs/exercise/day18/solution/img/lap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/advent-of-craft/2023/178dfa1e2fbd640c65fc903122b1fcda77d7fa9c/docs/exercise/day18/solution/img/lap.png -------------------------------------------------------------------------------- /docs/exercise/day18/solution/snippet.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/advent-of-craft/2023/178dfa1e2fbd640c65fc903122b1fcda77d7fa9c/docs/exercise/day18/solution/snippet.png -------------------------------------------------------------------------------- /docs/exercise/day19/snippet.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/advent-of-craft/2023/178dfa1e2fbd640c65fc903122b1fcda77d7fa9c/docs/exercise/day19/snippet.png -------------------------------------------------------------------------------- /docs/exercise/day19/solution/img/generate-code.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/advent-of-craft/2023/178dfa1e2fbd640c65fc903122b1fcda77d7fa9c/docs/exercise/day19/solution/img/generate-code.png -------------------------------------------------------------------------------- /docs/exercise/day19/solution/img/ide-usage-detection.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/advent-of-craft/2023/178dfa1e2fbd640c65fc903122b1fcda77d7fa9c/docs/exercise/day19/solution/img/ide-usage-detection.png -------------------------------------------------------------------------------- /docs/exercise/day19/solution/img/no-more-exception.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/advent-of-craft/2023/178dfa1e2fbd640c65fc903122b1fcda77d7fa9c/docs/exercise/day19/solution/img/no-more-exception.png -------------------------------------------------------------------------------- /docs/exercise/day19/solution/img/remove-useless-method.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/advent-of-craft/2023/178dfa1e2fbd640c65fc903122b1fcda77d7fa9c/docs/exercise/day19/solution/img/remove-useless-method.png -------------------------------------------------------------------------------- /docs/exercise/day19/solution/img/safe-delete-exception.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/advent-of-craft/2023/178dfa1e2fbd640c65fc903122b1fcda77d7fa9c/docs/exercise/day19/solution/img/safe-delete-exception.png -------------------------------------------------------------------------------- /docs/exercise/day19/solution/img/test-as-a-driver.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/advent-of-craft/2023/178dfa1e2fbd640c65fc903122b1fcda77d7fa9c/docs/exercise/day19/solution/img/test-as-a-driver.png -------------------------------------------------------------------------------- /docs/exercise/day19/solution/snippet.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/advent-of-craft/2023/178dfa1e2fbd640c65fc903122b1fcda77d7fa9c/docs/exercise/day19/solution/snippet.png -------------------------------------------------------------------------------- /docs/exercise/day20/snippet.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/advent-of-craft/2023/178dfa1e2fbd640c65fc903122b1fcda77d7fa9c/docs/exercise/day20/snippet.png -------------------------------------------------------------------------------- /docs/exercise/day20/solution/img/calculator-constrain-input.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/advent-of-craft/2023/178dfa1e2fbd640c65fc903122b1fcda77d7fa9c/docs/exercise/day20/solution/img/calculator-constrain-input.png -------------------------------------------------------------------------------- /docs/exercise/day20/solution/img/callback-hell.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/advent-of-craft/2023/178dfa1e2fbd640c65fc903122b1fcda77d7fa9c/docs/exercise/day20/solution/img/callback-hell.webp -------------------------------------------------------------------------------- /docs/exercise/day20/solution/img/constrain-input.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/advent-of-craft/2023/178dfa1e2fbd640c65fc903122b1fcda77d7fa9c/docs/exercise/day20/solution/img/constrain-input.png -------------------------------------------------------------------------------- /docs/exercise/day20/solution/img/generate-calculate.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/advent-of-craft/2023/178dfa1e2fbd640c65fc903122b1fcda77d7fa9c/docs/exercise/day20/solution/img/generate-calculate.png -------------------------------------------------------------------------------- /docs/exercise/day20/solution/img/generate-roll.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/advent-of-craft/2023/178dfa1e2fbd640c65fc903122b1fcda77d7fa9c/docs/exercise/day20/solution/img/generate-roll.png -------------------------------------------------------------------------------- /docs/exercise/day20/solution/img/hollywood-principle.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/advent-of-craft/2023/178dfa1e2fbd640c65fc903122b1fcda77d7fa9c/docs/exercise/day20/solution/img/hollywood-principle.webp -------------------------------------------------------------------------------- /docs/exercise/day20/solution/snippet-hollywood.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/advent-of-craft/2023/178dfa1e2fbd640c65fc903122b1fcda77d7fa9c/docs/exercise/day20/solution/snippet-hollywood.png -------------------------------------------------------------------------------- /docs/exercise/day20/solution/snippet.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/advent-of-craft/2023/178dfa1e2fbd640c65fc903122b1fcda77d7fa9c/docs/exercise/day20/solution/snippet.png -------------------------------------------------------------------------------- /docs/exercise/day21/img/communication-based.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/advent-of-craft/2023/178dfa1e2fbd640c65fc903122b1fcda77d7fa9c/docs/exercise/day21/img/communication-based.png -------------------------------------------------------------------------------- /docs/exercise/day21/img/output-based.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/advent-of-craft/2023/178dfa1e2fbd640c65fc903122b1fcda77d7fa9c/docs/exercise/day21/img/output-based.png -------------------------------------------------------------------------------- /docs/exercise/day21/img/state-based.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/advent-of-craft/2023/178dfa1e2fbd640c65fc903122b1fcda77d7fa9c/docs/exercise/day21/img/state-based.png -------------------------------------------------------------------------------- /docs/exercise/day21/snippet.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/advent-of-craft/2023/178dfa1e2fbd640c65fc903122b1fcda77d7fa9c/docs/exercise/day21/snippet.png -------------------------------------------------------------------------------- /docs/exercise/day21/solution/img/assertion-fail.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/advent-of-craft/2023/178dfa1e2fbd640c65fc903122b1fcda77d7fa9c/docs/exercise/day21/solution/img/assertion-fail.png -------------------------------------------------------------------------------- /docs/exercise/day21/solution/img/audit-functional.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/advent-of-craft/2023/178dfa1e2fbd640c65fc903122b1fcda77d7fa9c/docs/exercise/day21/solution/img/audit-functional.png -------------------------------------------------------------------------------- /docs/exercise/day21/solution/img/communication-based.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/advent-of-craft/2023/178dfa1e2fbd640c65fc903122b1fcda77d7fa9c/docs/exercise/day21/solution/img/communication-based.png -------------------------------------------------------------------------------- /docs/exercise/day21/solution/img/failure2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/advent-of-craft/2023/178dfa1e2fbd640c65fc903122b1fcda77d7fa9c/docs/exercise/day21/solution/img/failure2.png -------------------------------------------------------------------------------- /docs/exercise/day21/solution/img/generate-code.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/advent-of-craft/2023/178dfa1e2fbd640c65fc903122b1fcda77d7fa9c/docs/exercise/day21/solution/img/generate-code.png -------------------------------------------------------------------------------- /docs/exercise/day21/solution/img/output-based.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/advent-of-craft/2023/178dfa1e2fbd640c65fc903122b1fcda77d7fa9c/docs/exercise/day21/solution/img/output-based.png -------------------------------------------------------------------------------- /docs/exercise/day21/solution/img/red-compiler.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/advent-of-craft/2023/178dfa1e2fbd640c65fc903122b1fcda77d7fa9c/docs/exercise/day21/solution/img/red-compiler.png -------------------------------------------------------------------------------- /docs/exercise/day21/solution/img/state-based.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/advent-of-craft/2023/178dfa1e2fbd640c65fc903122b1fcda77d7fa9c/docs/exercise/day21/solution/img/state-based.png -------------------------------------------------------------------------------- /docs/exercise/day21/solution/snippet.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/advent-of-craft/2023/178dfa1e2fbd640c65fc903122b1fcda77d7fa9c/docs/exercise/day21/solution/snippet.png -------------------------------------------------------------------------------- /docs/exercise/day22/snippet.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/advent-of-craft/2023/178dfa1e2fbd640c65fc903122b1fcda77d7fa9c/docs/exercise/day22/snippet.png -------------------------------------------------------------------------------- /docs/exercise/day22/solution/img/approve-content.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/advent-of-craft/2023/178dfa1e2fbd640c65fc903122b1fcda77d7fa9c/docs/exercise/day22/solution/img/approve-content.png -------------------------------------------------------------------------------- /docs/exercise/day22/solution/img/generate-code-from-first-property.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/advent-of-craft/2023/178dfa1e2fbd640c65fc903122b1fcda77d7fa9c/docs/exercise/day22/solution/img/generate-code-from-first-property.png -------------------------------------------------------------------------------- /docs/exercise/day22/solution/img/generate-code-impl.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/advent-of-craft/2023/178dfa1e2fbd640c65fc903122b1fcda77d7fa9c/docs/exercise/day22/solution/img/generate-code-impl.png -------------------------------------------------------------------------------- /docs/exercise/day22/solution/snippet.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/advent-of-craft/2023/178dfa1e2fbd640c65fc903122b1fcda77d7fa9c/docs/exercise/day22/solution/snippet.png -------------------------------------------------------------------------------- /docs/exercise/day23/all-in-one.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/advent-of-craft/2023/178dfa1e2fbd640c65fc903122b1fcda77d7fa9c/docs/exercise/day23/all-in-one.png -------------------------------------------------------------------------------- /docs/exercise/day23/snippet.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/advent-of-craft/2023/178dfa1e2fbd640c65fc903122b1fcda77d7fa9c/docs/exercise/day23/snippet.png -------------------------------------------------------------------------------- /docs/exercise/day23/solution/img/activate-tracing.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/advent-of-craft/2023/178dfa1e2fbd640c65fc903122b1fcda77d7fa9c/docs/exercise/day23/solution/img/activate-tracing.png -------------------------------------------------------------------------------- /docs/exercise/day23/solution/img/change-signature.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/advent-of-craft/2023/178dfa1e2fbd640c65fc903122b1fcda77d7fa9c/docs/exercise/day23/solution/img/change-signature.png -------------------------------------------------------------------------------- /docs/exercise/day23/solution/img/coverage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/advent-of-craft/2023/178dfa1e2fbd640c65fc903122b1fcda77d7fa9c/docs/exercise/day23/solution/img/coverage.png -------------------------------------------------------------------------------- /docs/exercise/day23/solution/img/coverage2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/advent-of-craft/2023/178dfa1e2fbd640c65fc903122b1fcda77d7fa9c/docs/exercise/day23/solution/img/coverage2.png -------------------------------------------------------------------------------- /docs/exercise/day23/solution/img/coverage3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/advent-of-craft/2023/178dfa1e2fbd640c65fc903122b1fcda77d7fa9c/docs/exercise/day23/solution/img/coverage3.png -------------------------------------------------------------------------------- /docs/exercise/day23/solution/img/coverage4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/advent-of-craft/2023/178dfa1e2fbd640c65fc903122b1fcda77d7fa9c/docs/exercise/day23/solution/img/coverage4.png -------------------------------------------------------------------------------- /docs/exercise/day23/solution/img/demo-bracnh-coverage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/advent-of-craft/2023/178dfa1e2fbd640c65fc903122b1fcda77d7fa9c/docs/exercise/day23/solution/img/demo-bracnh-coverage.png -------------------------------------------------------------------------------- /docs/exercise/day23/solution/img/demo1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/advent-of-craft/2023/178dfa1e2fbd640c65fc903122b1fcda77d7fa9c/docs/exercise/day23/solution/img/demo1.png -------------------------------------------------------------------------------- /docs/exercise/day23/solution/img/demo2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/advent-of-craft/2023/178dfa1e2fbd640c65fc903122b1fcda77d7fa9c/docs/exercise/day23/solution/img/demo2.png -------------------------------------------------------------------------------- /docs/exercise/day23/solution/img/end-strangler.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/advent-of-craft/2023/178dfa1e2fbd640c65fc903122b1fcda77d7fa9c/docs/exercise/day23/solution/img/end-strangler.png -------------------------------------------------------------------------------- /docs/exercise/day23/solution/img/generate-code-from-usage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/advent-of-craft/2023/178dfa1e2fbd640c65fc903122b1fcda77d7fa9c/docs/exercise/day23/solution/img/generate-code-from-usage.png -------------------------------------------------------------------------------- /docs/exercise/day23/solution/img/introduced-mutants.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/advent-of-craft/2023/178dfa1e2fbd640c65fc903122b1fcda77d7fa9c/docs/exercise/day23/solution/img/introduced-mutants.png -------------------------------------------------------------------------------- /docs/exercise/day23/solution/img/legacy-code-refactoring.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/advent-of-craft/2023/178dfa1e2fbd640c65fc903122b1fcda77d7fa9c/docs/exercise/day23/solution/img/legacy-code-refactoring.png -------------------------------------------------------------------------------- /docs/exercise/day23/solution/img/mock-error.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/advent-of-craft/2023/178dfa1e2fbd640c65fc903122b1fcda77d7fa9c/docs/exercise/day23/solution/img/mock-error.png -------------------------------------------------------------------------------- /docs/exercise/day23/solution/img/move-closer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/advent-of-craft/2023/178dfa1e2fbd640c65fc903122b1fcda77d7fa9c/docs/exercise/day23/solution/img/move-closer.png -------------------------------------------------------------------------------- /docs/exercise/day23/solution/img/pitest-report.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/advent-of-craft/2023/178dfa1e2fbd640c65fc903122b1fcda77d7fa9c/docs/exercise/day23/solution/img/pitest-report.png -------------------------------------------------------------------------------- /docs/exercise/day23/solution/img/safe-delete.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/advent-of-craft/2023/178dfa1e2fbd640c65fc903122b1fcda77d7fa9c/docs/exercise/day23/solution/img/safe-delete.png -------------------------------------------------------------------------------- /docs/exercise/day23/solution/img/tdd.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/advent-of-craft/2023/178dfa1e2fbd640c65fc903122b1fcda77d7fa9c/docs/exercise/day23/solution/img/tdd.png -------------------------------------------------------------------------------- /docs/exercise/day23/solution/img/test-readability.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/advent-of-craft/2023/178dfa1e2fbd640c65fc903122b1fcda77d7fa9c/docs/exercise/day23/solution/img/test-readability.png -------------------------------------------------------------------------------- /docs/exercise/day23/solution/img/tips.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/advent-of-craft/2023/178dfa1e2fbd640c65fc903122b1fcda77d7fa9c/docs/exercise/day23/solution/img/tips.png -------------------------------------------------------------------------------- /docs/exercise/day23/solution/img/video.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/advent-of-craft/2023/178dfa1e2fbd640c65fc903122b1fcda77d7fa9c/docs/exercise/day23/solution/img/video.png -------------------------------------------------------------------------------- /docs/exercise/day23/solution/snippet.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/advent-of-craft/2023/178dfa1e2fbd640c65fc903122b1fcda77d7fa9c/docs/exercise/day23/solution/snippet.png -------------------------------------------------------------------------------- /docs/exercise/day24/cdd.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/advent-of-craft/2023/178dfa1e2fbd640c65fc903122b1fcda77d7fa9c/docs/exercise/day24/cdd.png -------------------------------------------------------------------------------- /docs/exercise/day24/snippet.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/advent-of-craft/2023/178dfa1e2fbd640c65fc903122b1fcda77d7fa9c/docs/exercise/day24/snippet.png -------------------------------------------------------------------------------- /docs/exercise/day24/solution/img/complexity.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/advent-of-craft/2023/178dfa1e2fbd640c65fc903122b1fcda77d7fa9c/docs/exercise/day24/solution/img/complexity.png -------------------------------------------------------------------------------- /docs/exercise/day24/solution/img/crappy-driven-development.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/advent-of-craft/2023/178dfa1e2fbd640c65fc903122b1fcda77d7fa9c/docs/exercise/day24/solution/img/crappy-driven-development.png -------------------------------------------------------------------------------- /docs/exercise/day24/solution/img/crappy-ideas.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/advent-of-craft/2023/178dfa1e2fbd640c65fc903122b1fcda77d7fa9c/docs/exercise/day24/solution/img/crappy-ideas.png -------------------------------------------------------------------------------- /docs/exercise/day24/solution/img/use-rename.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/advent-of-craft/2023/178dfa1e2fbd640c65fc903122b1fcda77d7fa9c/docs/exercise/day24/solution/img/use-rename.png -------------------------------------------------------------------------------- /docs/exercise/day24/solution/snippet.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/advent-of-craft/2023/178dfa1e2fbd640c65fc903122b1fcda77d7fa9c/docs/exercise/day24/solution/snippet.png -------------------------------------------------------------------------------- /docs/exercise/day25/sharing.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/advent-of-craft/2023/178dfa1e2fbd640c65fc903122b1fcda77d7fa9c/docs/exercise/day25/sharing.png -------------------------------------------------------------------------------- /docs/img/advent-of-craft.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/advent-of-craft/2023/178dfa1e2fbd640c65fc903122b1fcda77d7fa9c/docs/img/advent-of-craft.png -------------------------------------------------------------------------------- /docs/img/clean-testing.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/advent-of-craft/2023/178dfa1e2fbd640c65fc903122b1fcda77d7fa9c/docs/img/clean-testing.png -------------------------------------------------------------------------------- /docs/img/design.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/advent-of-craft/2023/178dfa1e2fbd640c65fc903122b1fcda77d7fa9c/docs/img/design.png -------------------------------------------------------------------------------- /docs/img/discord.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/advent-of-craft/2023/178dfa1e2fbd640c65fc903122b1fcda77d7fa9c/docs/img/discord.png -------------------------------------------------------------------------------- /docs/img/functional-programming.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/advent-of-craft/2023/178dfa1e2fbd640c65fc903122b1fcda77d7fa9c/docs/img/functional-programming.png -------------------------------------------------------------------------------- /docs/img/proposed-solution.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/advent-of-craft/2023/178dfa1e2fbd640c65fc903122b1fcda77d7fa9c/docs/img/proposed-solution.png -------------------------------------------------------------------------------- /docs/img/refactoring.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/advent-of-craft/2023/178dfa1e2fbd640c65fc903122b1fcda77d7fa9c/docs/img/refactoring.png -------------------------------------------------------------------------------- /docs/img/tdd.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/advent-of-craft/2023/178dfa1e2fbd640c65fc903122b1fcda77d7fa9c/docs/img/tdd.png -------------------------------------------------------------------------------- /exercise/c#/Day01/Day01/Day01.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | net8.0 5 | enable 6 | enable 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /exercise/c#/Day01/Day01/Food.cs: -------------------------------------------------------------------------------- 1 | namespace Day01 2 | { 3 | public record Food( 4 | DateOnly ExpirationDate, 5 | bool ApprovedForConsumption, 6 | Guid? InspectorId) 7 | { 8 | public bool IsEdible(Func now) 9 | { 10 | if (ExpirationDate.CompareTo(now()) > 0 && 11 | ApprovedForConsumption && 12 | InspectorId != null) 13 | return true; 14 | return false; 15 | } 16 | } 17 | } -------------------------------------------------------------------------------- /exercise/c#/Day02/Day02/Day02.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | net8.0 5 | enable 6 | enable 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /exercise/c#/Day02/Day02/OutOfRangeException.cs: -------------------------------------------------------------------------------- 1 | namespace Day02 2 | { 3 | public sealed class OutOfRangeException : ArgumentException 4 | { 5 | } 6 | } -------------------------------------------------------------------------------- /exercise/c#/Day03/Day03/Day03.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | net8.0 5 | enable 6 | enable 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /exercise/c#/Day03/Day03/Person.cs: -------------------------------------------------------------------------------- 1 | namespace Day03 2 | { 3 | public record Person(string FirstName, string LastName, params Pet[] Pets); 4 | 5 | public record Pet(PetType Type, string Name, int Age); 6 | 7 | public enum PetType 8 | { 9 | Cat, 10 | Dog, 11 | Hamster, 12 | Turtle, 13 | Bird, 14 | Snake 15 | } 16 | } -------------------------------------------------------------------------------- /exercise/c#/Day04/Day04/Day04.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | net8.0 5 | enable 6 | enable 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /exercise/c#/Day05/Day05/Day05.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | net8.0 5 | enable 6 | enable 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /exercise/c#/Day05/Day05/Person.cs: -------------------------------------------------------------------------------- 1 | namespace Day05 2 | { 3 | public record Person(string FirstName, string LastName, params Pet[] Pets); 4 | 5 | public record Pet(PetType Type, string Name, int Age); 6 | 7 | public enum PetType 8 | { 9 | Cat, 10 | Dog, 11 | Hamster, 12 | Turtle, 13 | Bird, 14 | Snake 15 | } 16 | } -------------------------------------------------------------------------------- /exercise/c#/Day06/Day06/Day06.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | net8.0 5 | enable 6 | enable 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /exercise/c#/Day06/Day06/OutOfRangeException.cs: -------------------------------------------------------------------------------- 1 | namespace Day06 2 | { 3 | public sealed class OutOfRangeException : ArgumentException 4 | { 5 | } 6 | } -------------------------------------------------------------------------------- /exercise/c#/Day07/Day07.Tests/Doubles/CapturingLogger.cs: -------------------------------------------------------------------------------- 1 | using Day07.CI.Dependencies; 2 | 3 | namespace Day07.Tests.Doubles 4 | { 5 | public class CapturingLogger : ILogger 6 | { 7 | private readonly List _lines = []; 8 | public void Info(string message) => _lines.Add($"INFO: {message}"); 9 | public void Error(string message) => _lines.Add($"ERROR: {message}"); 10 | public IReadOnlyList LoggedLines => _lines; 11 | } 12 | } -------------------------------------------------------------------------------- /exercise/c#/Day07/Day07/CI/Dependencies/IConfig.cs: -------------------------------------------------------------------------------- 1 | namespace Day07.CI.Dependencies 2 | { 3 | public interface IConfig 4 | { 5 | bool SendEmailSummary(); 6 | } 7 | } -------------------------------------------------------------------------------- /exercise/c#/Day07/Day07/CI/Dependencies/IEmailer.cs: -------------------------------------------------------------------------------- 1 | namespace Day07.CI.Dependencies 2 | { 3 | public interface IEmailer 4 | { 5 | void Send(string message); 6 | } 7 | } -------------------------------------------------------------------------------- /exercise/c#/Day07/Day07/CI/Dependencies/ILogger.cs: -------------------------------------------------------------------------------- 1 | namespace Day07.CI.Dependencies 2 | { 3 | public interface ILogger 4 | { 5 | void Info(string message); 6 | void Error(string message); 7 | } 8 | } -------------------------------------------------------------------------------- /exercise/c#/Day07/Day07/CI/Dependencies/TestStatus.cs: -------------------------------------------------------------------------------- 1 | namespace Day07.CI.Dependencies 2 | { 3 | public enum TestStatus 4 | { 5 | NoTests, 6 | PassingTests, 7 | FailingTests, 8 | } 9 | } -------------------------------------------------------------------------------- /exercise/c#/Day07/Day07/Day07.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | net8.0 5 | enable 6 | enable 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /exercise/c#/Day08/Day08/Day08.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | net8.0 5 | enable 6 | enable 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /exercise/c#/Day09/Day09/Day09.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | net8.0 5 | enable 6 | enable 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /exercise/c#/Day10/Day10/Day10.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | net8.0 5 | enable 6 | enable 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /exercise/c#/Day10/Day10/OutOfRangeException.cs: -------------------------------------------------------------------------------- 1 | namespace Day10 2 | { 3 | public sealed class OutOfRangeException : ArgumentException 4 | { 5 | } 6 | } -------------------------------------------------------------------------------- /exercise/c#/Day11/Day11/Day11.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | net8.0 5 | enable 6 | enable 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /exercise/c#/Day12/Day12/Day12.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | net8.0 5 | enable 6 | enable 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /exercise/c#/Day13/Day13/Day13.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | net8.0 5 | enable 6 | enable 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /exercise/c#/Day14/Day14/Day14.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | net8.0 5 | enable 6 | enable 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /exercise/c#/Day14/Day14/OutOfRangeException.cs: -------------------------------------------------------------------------------- 1 | namespace Day14 2 | { 3 | public sealed class OutOfRangeException : ArgumentException 4 | { 5 | } 6 | } -------------------------------------------------------------------------------- /exercise/c#/Day15/Day15/Day15.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | net8.0 5 | enable 6 | enable 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /exercise/c#/Day15/Day15/DocumentTemplate.cs: -------------------------------------------------------------------------------- 1 | namespace Day15 2 | { 3 | public enum DocumentTemplate 4 | { 5 | DEERPP, 6 | DEERPM, 7 | AUTP, 8 | AUTM, 9 | SPEC, 10 | GLPP, 11 | GLPM 12 | } 13 | } -------------------------------------------------------------------------------- /exercise/c#/Day15/Day15/RecordType.cs: -------------------------------------------------------------------------------- 1 | namespace Day15 2 | { 3 | public enum RecordType 4 | { 5 | IndividualProspect, 6 | LegalProspect, 7 | All 8 | } 9 | } -------------------------------------------------------------------------------- /exercise/c#/Day16/Day16/Day16.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | net8.0 5 | enable 6 | enable 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /exercise/c#/Day17/Day17/Day17.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | net8.0 5 | enable 6 | enable 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /exercise/c#/Day18/Day18/Day18.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | net8.0 5 | enable 6 | enable 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /exercise/c#/Day18/Day18/ShittyClass.cs: -------------------------------------------------------------------------------- 1 | namespace Day18 2 | { 3 | public class ShittyClass 4 | { 5 | private const string consecutive__underscores__kill__readability = "detect me if you can 😬"; 6 | private const string _external_underscores_kill_it_too = "detect me if you can 🚀"; 7 | 8 | public void GetData() 9 | { 10 | } 11 | 12 | private int IsTrue() => 42; 13 | } 14 | } -------------------------------------------------------------------------------- /exercise/c#/Day19/Day19/Day19.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | net8.0 5 | enable 6 | enable 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /exercise/c#/Day20/Day20/Day20.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | net8.0 5 | enable 6 | enable 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /exercise/c#/Day21/Day21/Day21.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | net8.0 5 | enable 6 | enable 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /exercise/c#/Day21/Day21/IFileSystem.cs: -------------------------------------------------------------------------------- 1 | namespace Day21 2 | { 3 | public interface IFileSystem 4 | { 5 | string[] GetFiles(string directoryName); 6 | void WriteAllText(string filePath, string content); 7 | IEnumerable ReadAllLines(string filePath); 8 | } 9 | } -------------------------------------------------------------------------------- /exercise/c#/Day22/Day22/Day22.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | net8.0 5 | enable 6 | enable 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /exercise/c#/Day23/Day23.Tests/Trip/TripDAOTests.cs: -------------------------------------------------------------------------------- 1 | namespace Day23.Tests.Trip 2 | { 3 | public class TripDAOTests 4 | { 5 | } 6 | } -------------------------------------------------------------------------------- /exercise/c#/Day23/Day23.Tests/Trip/TripServiceTests.cs: -------------------------------------------------------------------------------- 1 | namespace Day23.Tests.Trip 2 | { 3 | public class TripServiceTests 4 | { 5 | } 6 | } -------------------------------------------------------------------------------- /exercise/c#/Day23/Day23.Tests/User/UserTests.cs: -------------------------------------------------------------------------------- 1 | namespace Day23.Tests.User 2 | { 3 | public class UserTests 4 | { 5 | } 6 | } -------------------------------------------------------------------------------- /exercise/c#/Day23/Day23/Day23.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | net8.0 5 | enable 6 | enable 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /exercise/c#/Day23/Day23/Exception/CollaboratorCallException.cs: -------------------------------------------------------------------------------- 1 | namespace Day23.Exception 2 | { 3 | public class CollaboratorCallException(string message) : System.Exception(message); 4 | } -------------------------------------------------------------------------------- /exercise/c#/Day23/Day23/Exception/UserNotLoggedInException.cs: -------------------------------------------------------------------------------- 1 | namespace Day23.Exception 2 | { 3 | public class UserNotLoggedInException : System.Exception 4 | { 5 | } 6 | } -------------------------------------------------------------------------------- /exercise/c#/Day23/Day23/Trip/Trip.cs: -------------------------------------------------------------------------------- 1 | namespace Day23.Trip 2 | { 3 | public class Trip 4 | { 5 | } 6 | } -------------------------------------------------------------------------------- /exercise/c#/Day23/Day23/Trip/TripDAO.cs: -------------------------------------------------------------------------------- 1 | using Day23.Exception; 2 | 3 | namespace Day23.Trip 4 | { 5 | public class TripDAO 6 | { 7 | public static List FindTripsByUser(User.User user) 8 | { 9 | throw new CollaboratorCallException("TripDAO should not be invoked on an unit test."); 10 | } 11 | } 12 | } -------------------------------------------------------------------------------- /exercise/c#/Day24/Day24/Day24.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | net8.0 5 | enable 6 | enable 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /exercise/c#/Day24/Day24/Instruction.cs: -------------------------------------------------------------------------------- 1 | namespace Day24 2 | { 3 | public record Instruction(string Text, int X) 4 | { 5 | public static Instruction FromText(string text) 6 | { 7 | var split = text.Split(" "); 8 | return new Instruction(split[0], int.Parse(split[1])); 9 | } 10 | } 11 | } -------------------------------------------------------------------------------- /exercise/c#/Day24/Day24/Position.cs: -------------------------------------------------------------------------------- 1 | namespace Day24 2 | { 3 | public record Position(int Horizontal, int Depth) 4 | { 5 | public Position ChangeDepth(int newDepth) => this with {Depth = newDepth}; 6 | public Position MoveHorizontally(int newHorizontal) => this with {Horizontal = newHorizontal}; 7 | } 8 | } -------------------------------------------------------------------------------- /exercise/java/day02/src/main/java/games/OutOfRangeException.java: -------------------------------------------------------------------------------- 1 | package games; 2 | 3 | public class OutOfRangeException extends Exception { 4 | } 5 | -------------------------------------------------------------------------------- /exercise/java/day03/src/main/java/people/Person.java: -------------------------------------------------------------------------------- 1 | package people; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | public record Person(String firstName, String lastName, List pets) { 7 | public Person(String firstName, String lastName) { 8 | this(firstName, lastName, new ArrayList<>()); 9 | } 10 | 11 | public Person addPet(PetType petType, String name, int age) { 12 | pets.add(new Pet(petType, name, age)); 13 | return this; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /exercise/java/day03/src/main/java/people/Pet.java: -------------------------------------------------------------------------------- 1 | package people; 2 | 3 | public record Pet(PetType type, String name, int age) { 4 | } 5 | -------------------------------------------------------------------------------- /exercise/java/day03/src/main/java/people/PetType.java: -------------------------------------------------------------------------------- 1 | package people; 2 | 3 | public enum PetType { 4 | CAT, DOG, HAMSTER, TURTLE, BIRD, SNAKE 5 | } 6 | -------------------------------------------------------------------------------- /exercise/java/day04/src/main/java/blog/Comment.java: -------------------------------------------------------------------------------- 1 | package blog; 2 | 3 | import java.time.LocalDate; 4 | 5 | public record Comment(String text, String author, LocalDate creationDate) { 6 | } 7 | -------------------------------------------------------------------------------- /exercise/java/day04/src/main/java/blog/CommentAlreadyExistException.java: -------------------------------------------------------------------------------- 1 | package blog; 2 | 3 | public class CommentAlreadyExistException extends Exception { 4 | } -------------------------------------------------------------------------------- /exercise/java/day05/src/main/java/people/Person.java: -------------------------------------------------------------------------------- 1 | package people; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | public record Person(String firstName, String lastName, List pets) { 7 | public Person(String firstName, String lastName) { 8 | this(firstName, lastName, new ArrayList<>()); 9 | } 10 | 11 | public Person addPet(PetType petType, String name, int age) { 12 | pets.add(new Pet(petType, name, age)); 13 | return this; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /exercise/java/day05/src/main/java/people/Pet.java: -------------------------------------------------------------------------------- 1 | package people; 2 | 3 | public record Pet(PetType type, String name, int age) { 4 | } 5 | -------------------------------------------------------------------------------- /exercise/java/day05/src/main/java/people/PetType.java: -------------------------------------------------------------------------------- 1 | package people; 2 | 3 | public enum PetType { 4 | CAT, DOG, HAMSTER, TURTLE, BIRD, SNAKE 5 | } 6 | -------------------------------------------------------------------------------- /exercise/java/day06/src/main/java/games/OutOfRangeException.java: -------------------------------------------------------------------------------- 1 | package games; 2 | 3 | public class OutOfRangeException extends Exception { 4 | } 5 | -------------------------------------------------------------------------------- /exercise/java/day07/src/main/java/ci/dependencies/Config.java: -------------------------------------------------------------------------------- 1 | package ci.dependencies; 2 | 3 | public interface Config { 4 | boolean sendEmailSummary(); 5 | } 6 | -------------------------------------------------------------------------------- /exercise/java/day07/src/main/java/ci/dependencies/Emailer.java: -------------------------------------------------------------------------------- 1 | package ci.dependencies; 2 | 3 | public interface Emailer { 4 | void send(String message); 5 | } 6 | -------------------------------------------------------------------------------- /exercise/java/day07/src/main/java/ci/dependencies/Logger.java: -------------------------------------------------------------------------------- 1 | package ci.dependencies; 2 | 3 | public interface Logger { 4 | void info(String message); 5 | 6 | void error(String message); 7 | } 8 | -------------------------------------------------------------------------------- /exercise/java/day07/src/main/java/ci/dependencies/TestStatus.java: -------------------------------------------------------------------------------- 1 | package ci.dependencies; 2 | 3 | public enum TestStatus { 4 | NO_TESTS, 5 | PASSING_TESTS, 6 | FAILING_TESTS, 7 | } 8 | -------------------------------------------------------------------------------- /exercise/java/day10/src/main/java/games/OutOfRangeException.java: -------------------------------------------------------------------------------- 1 | package games; 2 | 3 | public class OutOfRangeException extends Exception { 4 | } 5 | -------------------------------------------------------------------------------- /exercise/java/day13/src/main/java/blog/Comment.java: -------------------------------------------------------------------------------- 1 | package blog; 2 | 3 | import java.time.LocalDate; 4 | 5 | public record Comment(String text, String author, LocalDate creationDate) { 6 | } 7 | -------------------------------------------------------------------------------- /exercise/java/day13/src/main/java/blog/CommentAlreadyExistException.java: -------------------------------------------------------------------------------- 1 | package blog; 2 | 3 | public class CommentAlreadyExistException extends Exception { 4 | } -------------------------------------------------------------------------------- /exercise/java/day14/src/main/java/games/OutOfRangeException.java: -------------------------------------------------------------------------------- 1 | package games; 2 | 3 | public class OutOfRangeException extends Exception { 4 | } 5 | -------------------------------------------------------------------------------- /exercise/java/day15/src/main/java/document/RecordType.java: -------------------------------------------------------------------------------- 1 | package document; 2 | 3 | public enum RecordType { 4 | INDIVIDUAL_PROSPECT("IndividualPersonProspect"), 5 | LEGAL_PROSPECT("LegalEntityProspect"), 6 | ALL("All"); 7 | 8 | private final String value; 9 | 10 | RecordType(String value) { 11 | this.value = value; 12 | } 13 | 14 | public String getValue() { 15 | return value; 16 | } 17 | } -------------------------------------------------------------------------------- /exercise/java/day16/src/main/java/blog/Comment.java: -------------------------------------------------------------------------------- 1 | package blog; 2 | 3 | import java.time.LocalDate; 4 | 5 | public record Comment(String text, String author, LocalDate creationDate) { 6 | } 7 | -------------------------------------------------------------------------------- /exercise/java/day16/src/main/java/blog/CommentAlreadyExistException.java: -------------------------------------------------------------------------------- 1 | package blog; 2 | 3 | public class CommentAlreadyExistException extends Exception { 4 | } -------------------------------------------------------------------------------- /exercise/java/day18/src/main/java/lap/ShittyClass.java: -------------------------------------------------------------------------------- 1 | package lap; 2 | 3 | public class ShittyClass { 4 | private final String consecutive__underscores__kill__readability = "detect me if you can 😬"; 5 | private final String _external_underscores_kill_it_too = "detect me if you can 🚀"; 6 | 7 | public void getData() { 8 | } 9 | 10 | private int isTrue() { 11 | return 42; 12 | } 13 | } -------------------------------------------------------------------------------- /exercise/java/day19/src/main/java/blog/Comment.java: -------------------------------------------------------------------------------- 1 | package blog; 2 | 3 | import java.time.LocalDate; 4 | 5 | public record Comment(String text, String author, LocalDate creationDate) { 6 | } 7 | -------------------------------------------------------------------------------- /exercise/java/day19/src/main/java/blog/CommentAlreadyExistException.java: -------------------------------------------------------------------------------- 1 | package blog; 2 | 3 | public class CommentAlreadyExistException extends RuntimeException { 4 | } -------------------------------------------------------------------------------- /exercise/java/day21/src/main/java/audit/FileSystem.java: -------------------------------------------------------------------------------- 1 | package audit; 2 | 3 | import java.util.List; 4 | 5 | public interface FileSystem { 6 | String[] getFiles(String directoryName); 7 | 8 | void writeAllText(String filePath, String content); 9 | 10 | List readAllLines(String filePath); 11 | } 12 | -------------------------------------------------------------------------------- /exercise/java/day22/.tcr/config.yml: -------------------------------------------------------------------------------- 1 | config: 2 | git: 3 | auto-push: false 4 | polling-period: 2s 5 | mob-timer: 6 | duration: 5m0s 7 | tcr: 8 | language: java 9 | toolchain: maven 10 | -------------------------------------------------------------------------------- /exercise/java/day22/.tcr/language/java.yml: -------------------------------------------------------------------------------- 1 | toolchains: 2 | default: maven 3 | compatible-with: [ maven ] 4 | source-files: 5 | directories: [ src/main ] 6 | patterns: [ '(?i)^.*\.java$' ] 7 | test-files: 8 | directories: [ src/test ] 9 | patterns: [ '(?i)^.*\.java$' ] 10 | -------------------------------------------------------------------------------- /exercise/java/day22/.tcr/toolchain/maven.yml: -------------------------------------------------------------------------------- 1 | build: 2 | - os: [ darwin, linux, windows ] 3 | arch: [ "386", amd64, arm64 ] 4 | command: mvn 5 | arguments: [ test-compile ] 6 | test: 7 | - os: [ darwin, linux, windows ] 8 | arch: [ "386", amd64, arm64 ] 9 | command: mvn 10 | arguments: [ test ] 11 | test-result-dir: target/surefire-reports 12 | -------------------------------------------------------------------------------- /exercise/java/day22/tcrw: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | base_dir="$(cd "$(dirname -- "$0")" && pwd)" 4 | . "${base_dir}/../tcr/tcr.sh" 5 | -------------------------------------------------------------------------------- /exercise/java/day23/src/main/java/org/craftedsw/tripservicekata/exception/UserNotLoggedInException.java: -------------------------------------------------------------------------------- 1 | package org.craftedsw.tripservicekata.exception; 2 | 3 | public class UserNotLoggedInException extends RuntimeException { 4 | 5 | private static final long serialVersionUID = 8959479918185637340L; 6 | 7 | } 8 | -------------------------------------------------------------------------------- /exercise/java/day23/src/main/java/org/craftedsw/tripservicekata/trip/Trip.java: -------------------------------------------------------------------------------- 1 | package org.craftedsw.tripservicekata.trip; 2 | 3 | public class Trip { 4 | 5 | } 6 | -------------------------------------------------------------------------------- /exercise/java/day23/src/main/java/org/craftedsw/tripservicekata/trip/TripDAO.java: -------------------------------------------------------------------------------- 1 | package org.craftedsw.tripservicekata.trip; 2 | 3 | import java.util.List; 4 | 5 | import org.craftedsw.tripservicekata.exception.CollaboratorCallException; 6 | import org.craftedsw.tripservicekata.user.User; 7 | 8 | public class TripDAO { 9 | 10 | public static List findTripsByUser(User user) { 11 | throw new CollaboratorCallException( 12 | "TripDAO should not be invoked on an unit test."); 13 | } 14 | 15 | } -------------------------------------------------------------------------------- /exercise/java/day23/src/test/java/org/craftedsw/tripservicekata/trip/TripDAOTest.java: -------------------------------------------------------------------------------- 1 | package org.craftedsw.tripservicekata.trip; 2 | 3 | public class TripDAOTest { 4 | 5 | } 6 | -------------------------------------------------------------------------------- /exercise/java/day23/src/test/java/org/craftedsw/tripservicekata/trip/TripServiceTest.java: -------------------------------------------------------------------------------- 1 | package org.craftedsw.tripservicekata.trip; 2 | 3 | public class TripServiceTest { 4 | 5 | } 6 | -------------------------------------------------------------------------------- /exercise/java/day23/src/test/java/org/craftedsw/tripservicekata/user/UserTest.java: -------------------------------------------------------------------------------- 1 | package org.craftedsw.tripservicekata.user; 2 | 3 | public class UserTest { 4 | 5 | } 6 | -------------------------------------------------------------------------------- /exercise/java/day24/src/main/java/submarine/Instruction.java: -------------------------------------------------------------------------------- 1 | package submarine; 2 | 3 | public record Instruction(String text, int x) { 4 | public static Instruction fromText(String text) { 5 | var split = text.split(" "); 6 | return new Instruction(split[0], Integer.parseInt(split[1])); 7 | } 8 | } -------------------------------------------------------------------------------- /exercise/java/day24/src/main/java/submarine/Position.java: -------------------------------------------------------------------------------- 1 | package submarine; 2 | 3 | public record Position(int horizontal, int depth) { 4 | public Position changeDepth(int newDepth) { 5 | return new Position(horizontal, newDepth); 6 | } 7 | 8 | public Position moveHorizontally(int newHorizontal) { 9 | return new Position(newHorizontal, depth); 10 | } 11 | } -------------------------------------------------------------------------------- /exercise/java/tcr/.gitignore: -------------------------------------------------------------------------------- 1 | # Below files and directories are automatically created 2 | # by tcr.sh and do not need to be committed to this repository 3 | 4 | bin/README.md 5 | doc/** 6 | download/** 7 | LICENSE.md 8 | README.md 9 | bin/** -------------------------------------------------------------------------------- /exercise/java/tcr/version.txt: -------------------------------------------------------------------------------- 1 | tcr-go 0.29.0 2 | -------------------------------------------------------------------------------- /exercise/kotlin/day02/src/main/kotlin/games/OutOfRangeException.kt: -------------------------------------------------------------------------------- 1 | package games 2 | 3 | class OutOfRangeException : Throwable() { 4 | 5 | } 6 | -------------------------------------------------------------------------------- /exercise/kotlin/day03/src/main/kotlin/people/Person.kt: -------------------------------------------------------------------------------- 1 | package people 2 | 3 | enum class PetType { 4 | CAT, 5 | DOG, 6 | HAMSTER, 7 | TURTLE, 8 | BIRD, 9 | SNAKE 10 | } 11 | 12 | data class Pet(val type: PetType, val name: String, val age: Int) 13 | data class Person(val firstName: String, val lastName: String, val pets: List = emptyList()) { 14 | fun addPet(petType: PetType, name: String, age: Int): Person = 15 | Person(firstName, lastName, pets + Pet(petType, name, age)) 16 | } 17 | -------------------------------------------------------------------------------- /exercise/kotlin/day05/src/main/kotlin/people/Person.kt: -------------------------------------------------------------------------------- 1 | package people 2 | 3 | enum class PetType { 4 | CAT, 5 | DOG, 6 | HAMSTER, 7 | TURTLE, 8 | BIRD, 9 | SNAKE 10 | } 11 | 12 | data class Pet(val type: PetType, val name: String, val age: Int) 13 | data class Person(val firstName: String, val lastName: String, val pets: List = emptyList()) { 14 | fun addPet(petType: PetType, name: String, age: Int): Person = 15 | Person(firstName, lastName, pets + Pet(petType, name, age)) 16 | } 17 | -------------------------------------------------------------------------------- /exercise/kotlin/day06/src/main/kotlin/games/OutOfRangeException.kt: -------------------------------------------------------------------------------- 1 | package games 2 | 3 | class OutOfRangeException : Throwable() -------------------------------------------------------------------------------- /exercise/kotlin/day07/src/test/kotlin/CapturingLogger.kt: -------------------------------------------------------------------------------- 1 | import ci.Logger 2 | 3 | 4 | data class CapturingLogger(val lines: MutableList = mutableListOf()) : Logger { 5 | override fun info(message: String) { 6 | lines.add("INFO: $message") 7 | } 8 | 9 | override fun error(message: String) { 10 | lines.add("ERROR: $message") 11 | } 12 | } -------------------------------------------------------------------------------- /exercise/kotlin/day10/src/main/kotlin/games/OutOfRangeException.kt: -------------------------------------------------------------------------------- 1 | package games 2 | 3 | class OutOfRangeException : Throwable() -------------------------------------------------------------------------------- /exercise/kotlin/day14/src/main/kotlin/games/OutOfRangeException.kt: -------------------------------------------------------------------------------- 1 | package games 2 | 3 | class OutOfRangeException : Throwable() -------------------------------------------------------------------------------- /exercise/kotlin/day15/src/main/kotlin/document/RecordType.kt: -------------------------------------------------------------------------------- 1 | package document 2 | 3 | enum class RecordType(val value: String) { 4 | INDIVIDUAL_PROSPECT("IndividualPersonProspect"), 5 | LEGAL_PROSPECT("LegalEntityProspect"), 6 | ALL("All") 7 | } -------------------------------------------------------------------------------- /exercise/kotlin/day18/src/main/kotlin/ShittyClass.kt: -------------------------------------------------------------------------------- 1 | class ShittyClass { 2 | private val consecutive__underscores__kill__readability = "detect me if you can 😬" 3 | private val _external_underscores_kill_it_too = "detect me if you can 🚀" 4 | fun getData() = Unit 5 | fun isTrue() = 42 6 | } -------------------------------------------------------------------------------- /exercise/kotlin/day20/src/test/kotlin/DiceBuilder.kt: -------------------------------------------------------------------------------- 1 | class DiceBuilder private constructor(private val dice: IntArray) { 2 | fun build(): IntArray { 3 | return dice 4 | } 5 | 6 | override fun toString(): String = dice.contentToString() 7 | 8 | companion object { 9 | fun `🎲🎲🎲🎲🎲`(dice1: Int, dice2: Int, dice3: Int, dice4: Int, dice5: Int): DiceBuilder = 10 | DiceBuilder(intArrayOf(dice1, dice2, dice3, dice4, dice5)) 11 | } 12 | } -------------------------------------------------------------------------------- /exercise/kotlin/day21/src/main/kotlin/audit/FileSystem.kt: -------------------------------------------------------------------------------- 1 | package audit 2 | 3 | interface FileSystem { 4 | fun getFiles(directoryName: String): List 5 | fun writeAllText(filePath: String, content: String) 6 | fun readAllLines(filePath: String): List 7 | } -------------------------------------------------------------------------------- /exercise/kotlin/day22/.tcr/config.yml: -------------------------------------------------------------------------------- 1 | config: 2 | git: 3 | auto-push: false 4 | polling-period: 2s 5 | mob-timer: 6 | duration: 5m0s 7 | tcr: 8 | language: kotlin 9 | toolchain: gradle-wrapper 10 | -------------------------------------------------------------------------------- /exercise/kotlin/day22/.tcr/language/java.yml: -------------------------------------------------------------------------------- 1 | toolchains: 2 | default: maven 3 | compatible-with: [ maven ] 4 | source-files: 5 | directories: [ src/main ] 6 | patterns: [ '(?i)^.*\.java$' ] 7 | test-files: 8 | directories: [ src/test ] 9 | patterns: [ '(?i)^.*\.java$' ] 10 | -------------------------------------------------------------------------------- /exercise/kotlin/day22/.tcr/toolchain/maven.yml: -------------------------------------------------------------------------------- 1 | build: 2 | - os: [ darwin, linux, windows ] 3 | arch: [ "386", amd64, arm64 ] 4 | command: mvn 5 | arguments: [ test-compile ] 6 | test: 7 | - os: [ darwin, linux, windows ] 8 | arch: [ "386", amd64, arm64 ] 9 | command: mvn 10 | arguments: [ test ] 11 | test-result-dir: target/surefire-reports 12 | -------------------------------------------------------------------------------- /exercise/kotlin/day22/tcrw: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | base_dir="$(cd "$(dirname -- "$0")" && pwd)" 4 | . "${base_dir}/../tcr/tcr.sh" 5 | -------------------------------------------------------------------------------- /exercise/kotlin/day23/src/main/kotlin/org/craftedsw/tripservicekata/exception/UserNotLoggedInException.kt: -------------------------------------------------------------------------------- 1 | package org.craftedsw.tripservicekata.exception 2 | 3 | class UserNotLoggedInException : RuntimeException() { 4 | 5 | companion object { 6 | private val serialVersionUID: Long = 8959479918185637340L 7 | } 8 | 9 | } 10 | -------------------------------------------------------------------------------- /exercise/kotlin/day23/src/main/kotlin/org/craftedsw/tripservicekata/trip/Trip.kt: -------------------------------------------------------------------------------- 1 | package org.craftedsw.tripservicekata.trip 2 | 3 | class Trip 4 | -------------------------------------------------------------------------------- /exercise/kotlin/day23/src/main/kotlin/org/craftedsw/tripservicekata/trip/TripDAO.kt: -------------------------------------------------------------------------------- 1 | package org.craftedsw.tripservicekata.trip 2 | 3 | import org.craftedsw.tripservicekata.exception.CollaboratorCallException 4 | import org.craftedsw.tripservicekata.user.User 5 | 6 | class TripDAO { 7 | companion object { 8 | fun findTripsByUser(user: User): List { 9 | throw CollaboratorCallException("TripDAO should not be invoked on an unit test.") 10 | } 11 | } 12 | } -------------------------------------------------------------------------------- /exercise/kotlin/day24/src/main/kotlin/submarine/Instruction.kt: -------------------------------------------------------------------------------- 1 | package submarine 2 | 3 | data class Instruction(val text: String, val x: Int) 4 | 5 | fun String.toInstruction(): Instruction = split(" ".toRegex()).dropLastWhile { it.isEmpty() } 6 | .let { split -> 7 | return Instruction(split[0], split[1].toInt()) 8 | } -------------------------------------------------------------------------------- /exercise/kotlin/day24/src/main/kotlin/submarine/Position.kt: -------------------------------------------------------------------------------- 1 | package submarine 2 | 3 | data class Position(val horizontal: Int = 0, val depth: Int = 0) { 4 | fun changeDepth(newDepth: Int): Position = copy(depth = newDepth) 5 | fun moveHorizontally(newHorizontal: Int): Position = copy(horizontal = newHorizontal) 6 | } -------------------------------------------------------------------------------- /exercise/kotlin/gradle.properties: -------------------------------------------------------------------------------- 1 | kotlin.code.style=official 2 | -------------------------------------------------------------------------------- /exercise/kotlin/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.2-bin.zip 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists -------------------------------------------------------------------------------- /exercise/kotlin/tcr/.gitignore: -------------------------------------------------------------------------------- 1 | # Below files and directories are automatically created 2 | # by tcr.sh and do not need to be committed to this repository 3 | 4 | bin/README.md 5 | doc/** 6 | download/** 7 | LICENSE.md 8 | README.md 9 | bin/** -------------------------------------------------------------------------------- /exercise/kotlin/tcr/version.txt: -------------------------------------------------------------------------------- 1 | tcr-go 0.29.0 2 | -------------------------------------------------------------------------------- /exercise/ts/day01/jest.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | transform: {'^.+\\.ts?$': 'ts-jest'}, 3 | testEnvironment: 'node', 4 | testRegex: '/tests/.*\\.(test|spec)?\\.(ts|tsx)$', 5 | moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json', 'node'] 6 | }; -------------------------------------------------------------------------------- /exercise/ts/day01/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "day-1-edible", 3 | "description": "Day 1: Make your production code easier to understand.", 4 | "version": "1.0.0", 5 | "dependencies": { 6 | "typescript": "^5.3.3", 7 | "@types/uuidv4": "^5.0.0" 8 | }, 9 | "devDependencies": { 10 | "jest": "^29.7.0", 11 | "ts-jest": "^29.1.1", 12 | "@types/jest": "^29.5.8" 13 | }, 14 | "scripts": { 15 | "test": "jest" 16 | } 17 | } -------------------------------------------------------------------------------- /exercise/ts/day01/src/food.ts: -------------------------------------------------------------------------------- 1 | type Maybe = NonNullable | null; 2 | 3 | export class Food { 4 | constructor( 5 | public readonly expirationDate: Date, 6 | public readonly approvedForConsumption: boolean, 7 | public readonly inspectorId: Maybe 8 | ) { 9 | } 10 | 11 | isEdible(now: () => Date): boolean { 12 | return this.expirationDate > now() && 13 | this.approvedForConsumption && 14 | this.inspectorId !== null; 15 | } 16 | } -------------------------------------------------------------------------------- /exercise/ts/day01/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "commonjs", 4 | "target": "es6", 5 | "sourceMap": true 6 | }, 7 | "exclude": [ 8 | "node_modules" 9 | ] 10 | } -------------------------------------------------------------------------------- /exercise/ts/day02/jest.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | transform: {'^.+\\.ts?$': 'ts-jest'}, 3 | testEnvironment: 'node', 4 | testRegex: '/tests/.*\\.(test|spec)?\\.(ts|tsx)$', 5 | moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json', 'node'] 6 | }; -------------------------------------------------------------------------------- /exercise/ts/day02/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "day-2-fizzbuzz", 3 | "version": "1.0.0", 4 | "description": "Day 2: One level of indentation.", 5 | "dependencies": { 6 | "typescript": "^5.3.3" 7 | }, 8 | "devDependencies": { 9 | "jest": "^29.7.0", 10 | "ts-jest": "^29.1.1", 11 | "@types/jest": "^29.5.8" 12 | }, 13 | "scripts": { 14 | "test": "jest" 15 | } 16 | } -------------------------------------------------------------------------------- /exercise/ts/day02/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "commonjs", 4 | "target": "es6", 5 | "sourceMap": true 6 | }, 7 | "exclude": [ 8 | "node_modules" 9 | ] 10 | } -------------------------------------------------------------------------------- /exercise/ts/day03/jest.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | transform: {'^.+\\.ts?$': 'ts-jest'}, 3 | testEnvironment: 'node', 4 | testRegex: '/tests/.*\\.(test|spec)?\\.(ts|tsx)$', 5 | moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json', 'node'] 6 | }; -------------------------------------------------------------------------------- /exercise/ts/day03/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "day-3-people", 3 | "description": "Day 3: One dot per line.", 4 | "version": "1.0.0", 5 | "dependencies": { 6 | "typescript": "^5.3.3" 7 | }, 8 | "devDependencies": { 9 | "jest": "^29.7.0", 10 | "ts-jest": "^29.1.1", 11 | "@types/jest": "^29.5.8" 12 | }, 13 | "scripts": { 14 | "test": "jest" 15 | } 16 | } -------------------------------------------------------------------------------- /exercise/ts/day03/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "commonjs", 4 | "target": "es6", 5 | "sourceMap": true 6 | }, 7 | "exclude": [ 8 | "node_modules" 9 | ] 10 | } -------------------------------------------------------------------------------- /exercise/ts/day04/jest.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | transform: {'^.+\\.ts?$': 'ts-jest'}, 3 | testEnvironment: 'node', 4 | testRegex: '/tests/.*\\.(test|spec)?\\.(ts|tsx)$', 5 | moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json', 'node'] 6 | }; -------------------------------------------------------------------------------- /exercise/ts/day04/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "day-4-blog", 3 | "description": "Day 4: Identify the behavior under test and rewrite the tests.", 4 | "version": "1.0.0", 5 | "dependencies": { 6 | "typescript": "^5.3.3" 7 | }, 8 | "devDependencies": { 9 | "jest": "^29.7.0", 10 | "ts-jest": "^29.1.1", 11 | "@types/jest": "^29.5.8" 12 | }, 13 | "scripts": { 14 | "test": "jest" 15 | } 16 | } -------------------------------------------------------------------------------- /exercise/ts/day04/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "commonjs", 4 | "target": "es6", 5 | "sourceMap": true 6 | }, 7 | "exclude": [ 8 | "node_modules" 9 | ] 10 | } -------------------------------------------------------------------------------- /exercise/ts/day05/jest.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | transform: {'^.+\\.ts?$': 'ts-jest'}, 3 | testEnvironment: 'node', 4 | testRegex: '/tests/.*\\.(test|spec)?\\.(ts|tsx)$', 5 | moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json', 'node'] 6 | }; -------------------------------------------------------------------------------- /exercise/ts/day05/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "day-5-people", 3 | "description": "Day 5: No for loop authorized.", 4 | "version": "1.0.0", 5 | "dependencies": { 6 | "typescript": "^5.3.3" 7 | }, 8 | "devDependencies": { 9 | "jest": "^29.7.0", 10 | "ts-jest": "^29.1.1", 11 | "@types/jest": "^29.5.8" 12 | }, 13 | "scripts": { 14 | "test": "jest" 15 | } 16 | } -------------------------------------------------------------------------------- /exercise/ts/day05/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "commonjs", 4 | "target": "es6", 5 | "sourceMap": true 6 | }, 7 | "exclude": [ 8 | "node_modules" 9 | ] 10 | } -------------------------------------------------------------------------------- /exercise/ts/day06/jest.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | transform: {'^.+\\.ts?$': 'ts-jest'}, 3 | testEnvironment: 'node', 4 | testRegex: '/tests/.*\\.(test|spec)?\\.(ts|tsx)$', 5 | moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json', 'node'] 6 | }; -------------------------------------------------------------------------------- /exercise/ts/day06/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "day-6-fizzbuzz", 3 | "version": "1.0.0", 4 | "description": "Day 6: Parameterize your tests.", 5 | "dependencies": { 6 | "typescript": "^5.3.3" 7 | }, 8 | "devDependencies": { 9 | "jest": "^29.7.0", 10 | "ts-jest": "^29.1.1", 11 | "@types/jest": "^29.5.8", 12 | "@types/uuidv4": "^5.0.0" 13 | }, 14 | "scripts": { 15 | "test": "jest" 16 | } 17 | } -------------------------------------------------------------------------------- /exercise/ts/day06/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "commonjs", 4 | "target": "es6", 5 | "sourceMap": true 6 | }, 7 | "exclude": [ 8 | "node_modules" 9 | ] 10 | } -------------------------------------------------------------------------------- /exercise/ts/day07/jest.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | transform: {'^.+\\.ts?$': 'ts-jest'}, 3 | testEnvironment: 'node', 4 | testRegex: '/tests/.*\\.(test|spec)?\\.(ts|tsx)$', 5 | moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json', 'node'] 6 | }; -------------------------------------------------------------------------------- /exercise/ts/day07/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "day-7-pipeline", 3 | "version": "1.0.0", 4 | "description": "Day 7: Simplify the run method by extracting the right behavior.", 5 | "dependencies": { 6 | "typescript": "^5.3.3" 7 | }, 8 | "devDependencies": { 9 | "jest": "^29.7.0", 10 | "ts-jest": "^29.1.1", 11 | "@types/jest": "^29.5.8" 12 | }, 13 | "scripts": { 14 | "test": "jest" 15 | } 16 | } -------------------------------------------------------------------------------- /exercise/ts/day07/src/ci.ts: -------------------------------------------------------------------------------- 1 | export interface Config { 2 | sendEmailSummary(): boolean; 3 | } 4 | 5 | export interface Emailer { 6 | send(message: string): void; 7 | } 8 | 9 | export interface Logger { 10 | info(message: string): void; 11 | 12 | error(message: string): void; 13 | } 14 | 15 | export enum TestStatus { 16 | NoTests, 17 | PassingTests, 18 | FailingTests, 19 | } -------------------------------------------------------------------------------- /exercise/ts/day07/tests/capturingLogger.ts: -------------------------------------------------------------------------------- 1 | import {Logger} from "../src/ci"; 2 | 3 | export class CapturingLogger implements Logger { 4 | private lines: string[] = []; 5 | 6 | info(message: string): void { 7 | this.lines.push(`INFO: ${message}`) 8 | } 9 | 10 | error(message: string): void { 11 | this.lines.push(`ERROR: ${message}`) 12 | } 13 | 14 | loggedLines = () => this.lines; 15 | } -------------------------------------------------------------------------------- /exercise/ts/day07/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "commonjs", 4 | "target": "es6", 5 | "sourceMap": true 6 | }, 7 | "exclude": [ 8 | "node_modules" 9 | ] 10 | } -------------------------------------------------------------------------------- /exercise/ts/day08/jest.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | transform: {'^.+\\.ts?$': 'ts-jest'}, 3 | testEnvironment: 'node', 4 | testRegex: '/tests/.*\\.(test|spec)?\\.(ts|tsx)$', 5 | moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json', 'node'] 6 | }; -------------------------------------------------------------------------------- /exercise/ts/day08/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "day-8-password-validation", 3 | "version": "1.0.0", 4 | "description": "Day 8: Using TDD rules, write a password validation program.", 5 | "dependencies": { 6 | "typescript": "^5.3.3" 7 | }, 8 | "devDependencies": { 9 | "jest": "^29.7.0", 10 | "ts-jest": "^29.1.1", 11 | "@types/jest": "^29.5.8" 12 | }, 13 | "scripts": { 14 | "test": "jest" 15 | } 16 | } -------------------------------------------------------------------------------- /exercise/ts/day08/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "commonjs", 4 | "target": "es6", 5 | "sourceMap": true 6 | }, 7 | "exclude": [ 8 | "node_modules" 9 | ] 10 | } -------------------------------------------------------------------------------- /exercise/ts/day09/jest.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | transform: {'^.+\\.ts?$': 'ts-jest'}, 3 | testEnvironment: 'node', 4 | testRegex: '/tests/.*\\.(test|spec)?\\.(ts|tsx)$', 5 | moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json', 'node'] 6 | }; -------------------------------------------------------------------------------- /exercise/ts/day09/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "day-9-accountability", 3 | "version": "1.0.0", 4 | "description": "Day 9: Fix the code.", 5 | "dependencies": { 6 | "typescript": "^5.3.3" 7 | }, 8 | "devDependencies": { 9 | "jest": "^29.7.0", 10 | "ts-jest": "^29.1.1", 11 | "@types/jest": "^29.5.8" 12 | }, 13 | "scripts": { 14 | "test": "jest" 15 | } 16 | } -------------------------------------------------------------------------------- /exercise/ts/day09/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "commonjs", 4 | "target": "es6", 5 | "sourceMap": true 6 | }, 7 | "exclude": [ 8 | "node_modules" 9 | ] 10 | } -------------------------------------------------------------------------------- /exercise/ts/day10/jest.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | transform: {'^.+\\.ts?$': 'ts-jest'}, 3 | testEnvironment: 'node', 4 | testRegex: '/tests/.*\\.(test|spec)?\\.(ts|tsx)$', 5 | moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json', 'node'] 6 | }; -------------------------------------------------------------------------------- /exercise/ts/day10/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "day-10-fizzbuzz", 3 | "version": "1.0.0", 4 | "description": "Day 10: Dot not use if statement.", 5 | "dependencies": { 6 | "typescript": "^5.3.3" 7 | }, 8 | "devDependencies": { 9 | "jest": "^29.7.0", 10 | "ts-jest": "^29.1.1", 11 | "@types/jest": "^29.5.8" 12 | }, 13 | "scripts": { 14 | "test": "jest" 15 | } 16 | } -------------------------------------------------------------------------------- /exercise/ts/day10/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "commonjs", 4 | "target": "es6", 5 | "sourceMap": true 6 | }, 7 | "exclude": [ 8 | "node_modules" 9 | ] 10 | } -------------------------------------------------------------------------------- /exercise/ts/day11/jest.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | transform: {'^.+\\.ts?$': 'ts-jest'}, 3 | testEnvironment: 'node', 4 | testRegex: '/tests/.*\\.(test|spec)?\\.(ts|tsx)$', 5 | moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json', 'node'] 6 | }; -------------------------------------------------------------------------------- /exercise/ts/day11/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "day-11-roman", 3 | "version": "1.0.0", 4 | "description": "Day 11: Gather a dependency freshness metric.", 5 | "dependencies": { 6 | "typescript": "^5.3.3", 7 | "fp-ts": "^2.16.1" 8 | }, 9 | "devDependencies": { 10 | "jest": "^29.7.0", 11 | "ts-jest": "^29.1.1", 12 | "@types/jest": "^29.5.8", 13 | "fast-check": "^3.15.0" 14 | }, 15 | "scripts": { 16 | "test": "jest" 17 | } 18 | } -------------------------------------------------------------------------------- /exercise/ts/day11/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "commonjs", 4 | "target": "es6", 5 | "sourceMap": true 6 | }, 7 | "exclude": [ 8 | "node_modules" 9 | ] 10 | } -------------------------------------------------------------------------------- /exercise/ts/day12/jest.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | transform: {'^.+\\.ts?$': 'ts-jest'}, 3 | testEnvironment: 'node', 4 | testRegex: '/tests/.*\\.(test|spec)?\\.(ts|tsx)$', 5 | moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json', 'node'] 6 | }; -------------------------------------------------------------------------------- /exercise/ts/day12/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "day-12-greeter", 3 | "version": "1.0.0", 4 | "description": "Day 12: Make your code open for extension.", 5 | "dependencies": { 6 | "typescript": "^5.3.3" 7 | }, 8 | "devDependencies": { 9 | "jest": "^29.7.0", 10 | "ts-jest": "^29.1.1", 11 | "@types/jest": "^29.5.8" 12 | }, 13 | "scripts": { 14 | "test": "jest" 15 | } 16 | } -------------------------------------------------------------------------------- /exercise/ts/day12/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "commonjs", 4 | "target": "es6", 5 | "sourceMap": true 6 | }, 7 | "exclude": [ 8 | "node_modules" 9 | ] 10 | } -------------------------------------------------------------------------------- /exercise/ts/day13/jest.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | transform: {'^.+\\.ts?$': 'ts-jest'}, 3 | testEnvironment: 'node', 4 | testRegex: '/tests/.*\\.(test|spec)?\\.(ts|tsx)$', 5 | moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json', 'node'] 6 | }; -------------------------------------------------------------------------------- /exercise/ts/day13/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "day-13-blog", 3 | "version": "1.0.0", 4 | "description": "Day 13: Find a way to eliminate the irrelevant, and amplify the essentials of those tests.", 5 | "dependencies": { 6 | "typescript": "^5.3.3" 7 | }, 8 | "devDependencies": { 9 | "jest": "^29.7.0", 10 | "ts-jest": "^29.1.1", 11 | "@types/jest": "^29.5.8" 12 | }, 13 | "scripts": { 14 | "test": "jest" 15 | } 16 | } -------------------------------------------------------------------------------- /exercise/ts/day13/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "commonjs", 4 | "target": "es6", 5 | "sourceMap": true 6 | }, 7 | "exclude": [ 8 | "node_modules" 9 | ] 10 | } -------------------------------------------------------------------------------- /exercise/ts/day14/jest.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | transform: {'^.+\\.ts?$': 'ts-jest'}, 3 | testEnvironment: 'node', 4 | testRegex: '/tests/.*\\.(test|spec)?\\.(ts|tsx)$', 5 | moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json', 'node'] 6 | }; -------------------------------------------------------------------------------- /exercise/ts/day14/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "day-14-fizzbuzz", 3 | "version": "1.0.0", 4 | "description": "Day 14: Do not use exceptions anymore.", 5 | "dependencies": { 6 | "typescript": "^5.3.3" 7 | }, 8 | "devDependencies": { 9 | "jest": "^29.7.0", 10 | "ts-jest": "^29.1.1", 11 | "@types/jest": "^29.5.8" 12 | }, 13 | "scripts": { 14 | "test": "jest" 15 | } 16 | } -------------------------------------------------------------------------------- /exercise/ts/day14/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "commonjs", 4 | "target": "es6", 5 | "sourceMap": true 6 | }, 7 | "exclude": [ 8 | "node_modules" 9 | ] 10 | } -------------------------------------------------------------------------------- /exercise/ts/day15/jest.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | preset: "ts-jest", 3 | testEnvironment: "node", 4 | transform: {'^.+\\.ts?$': 'ts-jest'}, 5 | testRegex: '/tests/.*\\.(test|spec)?\\.(ts|tsx)$' 6 | }; -------------------------------------------------------------------------------- /exercise/ts/day15/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "day-15-documents", 3 | "version": "1.0.0", 4 | "description": "Day 15: Put a code under tests.", 5 | "dependencies": { 6 | "typescript": "^5.3.3" 7 | }, 8 | "devDependencies": { 9 | "jest": "^29.7.0", 10 | "ts-jest": "^29.1.1", 11 | "@types/jest": "^29.5.8", 12 | "approvals": "^6.2.4" 13 | }, 14 | "scripts": { 15 | "test": "jest" 16 | } 17 | } -------------------------------------------------------------------------------- /exercise/ts/day15/src/recordType.ts: -------------------------------------------------------------------------------- 1 | export enum RecordType { 2 | INDIVIDUAL_PROSPECT = "IndividualPersonProspect", 3 | LEGAL_PROSPECT = "LegalEntityProspect", 4 | ALL = "All", 5 | } -------------------------------------------------------------------------------- /exercise/ts/day15/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "commonjs", 4 | "target": "es6", 5 | "sourceMap": true, 6 | "esModuleInterop": true 7 | }, 8 | "exclude": [ 9 | "node_modules" 10 | ] 11 | } -------------------------------------------------------------------------------- /exercise/ts/day16/jest.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | transform: {'^.+\\.ts?$': 'ts-jest'}, 3 | testEnvironment: 'node', 4 | testRegex: '/tests/.*\\.(test|spec)?\\.(ts|tsx)$', 5 | moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json', 'node'] 6 | }; -------------------------------------------------------------------------------- /exercise/ts/day16/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "day-16-blog", 3 | "version": "1.0.0", 4 | "description": "Day 16: Make this code immutable.", 5 | "dependencies": { 6 | "typescript": "^5.3.3" 7 | }, 8 | "devDependencies": { 9 | "jest": "^29.7.0", 10 | "ts-jest": "^29.1.1", 11 | "@types/jest": "^29.5.8", 12 | "@faker-js/faker": "^8.3.1" 13 | }, 14 | "scripts": { 15 | "test": "jest" 16 | } 17 | } -------------------------------------------------------------------------------- /exercise/ts/day16/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "commonjs", 4 | "target": "es6", 5 | "sourceMap": true 6 | }, 7 | "exclude": [ 8 | "node_modules" 9 | ] 10 | } -------------------------------------------------------------------------------- /exercise/ts/day17/jest.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | transform: {'^.+\\.ts?$': 'ts-jest'}, 3 | testEnvironment: 'node', 4 | testRegex: '/tests/.*\\.(test|spec)?\\.(ts|tsx)$', 5 | moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json', 'node'] 6 | }; -------------------------------------------------------------------------------- /exercise/ts/day17/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "day-17-fizzbuzz", 3 | "version": "1.0.0", 4 | "description": "Day 17: Design one test that has the impact of thousands", 5 | "dependencies": { 6 | "typescript": "^5.3.3", 7 | "fp-ts": "^2.16.2" 8 | }, 9 | "devDependencies": { 10 | "jest": "^29.7.0", 11 | "ts-jest": "^29.1.1", 12 | "@types/jest": "^29.5.8" 13 | }, 14 | "scripts": { 15 | "test": "jest" 16 | } 17 | } -------------------------------------------------------------------------------- /exercise/ts/day17/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "commonjs", 4 | "target": "es6", 5 | "sourceMap": true 6 | }, 7 | "exclude": [ 8 | "node_modules" 9 | ] 10 | } -------------------------------------------------------------------------------- /exercise/ts/day18/jest.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | transform: {'^.+\\.ts?$': 'ts-jest'}, 3 | testEnvironment: 'node', 4 | testRegex: '/tests/.*\\.(test|spec)?\\.(ts|tsx)$', 5 | moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json', 'node'] 6 | }; -------------------------------------------------------------------------------- /exercise/ts/day18/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "day-18-lap", 3 | "version": "1.0.0", 4 | "description": "Day 18: Automatically detect Linguistic Anti-Patterns (LAP).", 5 | "dependencies": { 6 | "typescript": "^5.3.3" 7 | }, 8 | "devDependencies": { 9 | "jest": "^29.7.0", 10 | "ts-jest": "^29.1.1", 11 | "@types/jest": "^29.5.8" 12 | }, 13 | "scripts": { 14 | "test": "jest" 15 | } 16 | } -------------------------------------------------------------------------------- /exercise/ts/day18/src/shitty.ts: -------------------------------------------------------------------------------- 1 | export class ShittyClass { 2 | private static readonly consecutive__underscores__kill__readability: string = "detect me if you can 😬"; 3 | private static readonly _external_underscores_kill_it_too: string = "detect me if you can 🚀"; 4 | 5 | public getData(): void { 6 | } 7 | 8 | private isTrue(): number { 9 | return 42; 10 | } 11 | } -------------------------------------------------------------------------------- /exercise/ts/day18/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "commonjs", 4 | "target": "es6", 5 | "sourceMap": true 6 | }, 7 | "exclude": [ 8 | "node_modules" 9 | ] 10 | } -------------------------------------------------------------------------------- /exercise/ts/day19/jest.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | transform: {'^.+\\.ts?$': 'ts-jest'}, 3 | testEnvironment: 'node', 4 | testRegex: '/tests/.*\\.(test|spec)?\\.(ts|tsx)$', 5 | moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json', 'node'] 6 | }; -------------------------------------------------------------------------------- /exercise/ts/day19/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "day-19-blog", 3 | "version": "1.0.0", 4 | "description": "Day 19: Loosing up dead weight.", 5 | "dependencies": { 6 | "typescript": "^5.3.3" 7 | }, 8 | "devDependencies": { 9 | "jest": "^29.7.0", 10 | "ts-jest": "^29.1.1", 11 | "@types/jest": "^29.5.8", 12 | "@faker-js/faker": "^8.3.1" 13 | }, 14 | "scripts": { 15 | "test": "jest" 16 | } 17 | } -------------------------------------------------------------------------------- /exercise/ts/day19/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "commonjs", 4 | "target": "es6", 5 | "sourceMap": true 6 | }, 7 | "exclude": [ 8 | "node_modules" 9 | ] 10 | } -------------------------------------------------------------------------------- /exercise/ts/day20/jest.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | transform: {'^.+\\.ts?$': 'ts-jest'}, 3 | testEnvironment: 'node', 4 | testRegex: '/tests/.*\\.(test|spec)?\\.(ts|tsx)$', 5 | moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json', 'node'] 6 | }; -------------------------------------------------------------------------------- /exercise/ts/day20/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "day-20-yahtzee", 3 | "version": "1.0.0", 4 | "description": "Day 20: No more exceptions in our domain.", 5 | "dependencies": { 6 | "typescript": "^5.3.3" 7 | }, 8 | "devDependencies": { 9 | "jest": "^29.7.0", 10 | "ts-jest": "^29.1.1", 11 | "@types/jest": "^29.5.8" 12 | }, 13 | "scripts": { 14 | "test": "jest" 15 | } 16 | } -------------------------------------------------------------------------------- /exercise/ts/day20/tests/diceBuilder.ts: -------------------------------------------------------------------------------- 1 | export class DiceBuilder { 2 | private readonly dice: number[]; 3 | 4 | constructor(dice: number[]) { 5 | this.dice = dice; 6 | } 7 | 8 | static newRoll = (dice1: number, dice2: number, dice3: number, dice4: number, dice5: number): DiceBuilder => 9 | new DiceBuilder([dice1, dice2, dice3, dice4, dice5]); 10 | 11 | build = (): number[] => this.dice; 12 | 13 | toString = () => this.dice.toString(); 14 | } -------------------------------------------------------------------------------- /exercise/ts/day20/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "commonjs", 4 | "target": "es6", 5 | "sourceMap": true 6 | }, 7 | "exclude": [ 8 | "node_modules" 9 | ] 10 | } -------------------------------------------------------------------------------- /exercise/ts/day21/jest.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | transform: {'^.+\\.ts?$': 'ts-jest'}, 3 | testEnvironment: 'node', 4 | testRegex: '/tests/.*\\.(test|spec)?\\.(ts|tsx)$', 5 | moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json', 'node'] 6 | }; -------------------------------------------------------------------------------- /exercise/ts/day21/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "day-21-audit", 3 | "version": "1.0.0", 4 | "description": "Day 21: Refactor the tests and production code to Output-Based tests.", 5 | "dependencies": { 6 | "typescript": "^5.3.3" 7 | }, 8 | "devDependencies": { 9 | "jest": "^29.7.0", 10 | "ts-jest": "^29.1.1", 11 | "@types/jest": "^29.5.8" 12 | }, 13 | "scripts": { 14 | "test": "jest" 15 | } 16 | } -------------------------------------------------------------------------------- /exercise/ts/day21/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "commonjs", 4 | "target": "es6", 5 | "sourceMap": true 6 | }, 7 | "exclude": [ 8 | "node_modules" 9 | ] 10 | } -------------------------------------------------------------------------------- /exercise/ts/day22/jest.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | transform: {'^.+\\.ts?$': 'ts-jest'}, 3 | testEnvironment: 'node', 4 | testRegex: '/tests/.*\\.(test|spec)?\\.(ts|tsx)$', 5 | moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json', 'node'] 6 | }; -------------------------------------------------------------------------------- /exercise/ts/day22/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "day-22-diamond", 3 | "version": "1.0.0", 4 | "description": "Day 22: Design a diamond program using T.D.D and Property-Based Testing.", 5 | "dependencies": { 6 | "typescript": "^5.3.3", 7 | "fp-ts": "^2.16.1" 8 | }, 9 | "devDependencies": { 10 | "jest": "^29.7.0", 11 | "ts-jest": "^29.1.1", 12 | "@types/jest": "^29.5.8", 13 | "fast-check": "^3.15.0" 14 | }, 15 | "scripts": { 16 | "test": "jest" 17 | } 18 | } -------------------------------------------------------------------------------- /exercise/ts/day22/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "commonjs", 4 | "target": "es6", 5 | "sourceMap": true 6 | }, 7 | "exclude": [ 8 | "node_modules" 9 | ] 10 | } -------------------------------------------------------------------------------- /exercise/ts/day23/jest.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | transform: {'^.+\\.ts?$': 'ts-jest'}, 3 | testEnvironment: 'node', 4 | testRegex: '/tests/.*\\.(test|spec)?\\.(ts|tsx)$', 5 | moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json', 'node'] 6 | }; -------------------------------------------------------------------------------- /exercise/ts/day23/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "day-23-trip-service", 3 | "version": "1.0.0", 4 | "description": "Day 23: Refactor the code after putting it under test.", 5 | "dependencies": { 6 | "typescript": "^5.3.3" 7 | }, 8 | "devDependencies": { 9 | "jest": "^29.7.0", 10 | "ts-jest": "^29.1.1", 11 | "@types/jest": "^29.5.8" 12 | }, 13 | "scripts": { 14 | "test": "jest" 15 | } 16 | } -------------------------------------------------------------------------------- /exercise/ts/day23/src/exception/CollaboratorCallException.ts: -------------------------------------------------------------------------------- 1 | export default class CollaboratorCallException extends Error {} 2 | -------------------------------------------------------------------------------- /exercise/ts/day23/src/exception/UserNotLoggedInException.ts: -------------------------------------------------------------------------------- 1 | export default class UserNotLoggedInException extends Error {} 2 | -------------------------------------------------------------------------------- /exercise/ts/day23/src/trip/Trip.ts: -------------------------------------------------------------------------------- 1 | export default class Trip {} 2 | -------------------------------------------------------------------------------- /exercise/ts/day23/src/trip/TripDAO.ts: -------------------------------------------------------------------------------- 1 | import CollaboratorCallException from "../exception/CollaboratorCallException"; 2 | import User from "../user/User"; 3 | import Trip from "./Trip"; 4 | 5 | export default class TripDAO { 6 | public static findTripsByUser(user: User): Trip[] { 7 | throw new CollaboratorCallException( 8 | "TripDAO should not be invoked on an unit test."); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /exercise/ts/day23/src/user/UserSession.ts: -------------------------------------------------------------------------------- 1 | import CollaboratorCallException from "../exception/CollaboratorCallException"; 2 | import User from "./User"; 3 | 4 | class UserSession { 5 | public getLoggedUser(): User { 6 | throw new CollaboratorCallException( 7 | "UserSession.getLoggedUser() should not be called in an unit test", 8 | ); 9 | } 10 | } 11 | 12 | export default new UserSession(); 13 | -------------------------------------------------------------------------------- /exercise/ts/day23/tests/tripservice.spec.ts: -------------------------------------------------------------------------------- 1 | describe("TripServiceShould", () => { 2 | it("...", () => { 3 | 4 | }); 5 | }); -------------------------------------------------------------------------------- /exercise/ts/day23/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "commonjs", 4 | "target": "es6", 5 | "sourceMap": true 6 | }, 7 | "exclude": [ 8 | "node_modules" 9 | ] 10 | } -------------------------------------------------------------------------------- /exercise/ts/day24/jest.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | transform: {'^.+\\.ts?$': 'ts-jest'}, 3 | testEnvironment: 'node', 4 | testRegex: '/tests/.*\\.(test|spec)?\\.(ts|tsx)$', 5 | moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json', 'node'] 6 | }; -------------------------------------------------------------------------------- /exercise/ts/day24/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "day-24-dive", 3 | "version": "1.0.0", 4 | "description": "Day 24: Write the most complicated code you can.", 5 | "dependencies": { 6 | "typescript": "^5.3.3" 7 | }, 8 | "devDependencies": { 9 | "jest": "^29.7.0", 10 | "ts-jest": "^29.1.1", 11 | "@types/jest": "^29.5.8" 12 | }, 13 | "scripts": { 14 | "test": "jest" 15 | } 16 | } -------------------------------------------------------------------------------- /exercise/ts/day24/src/instruction.ts: -------------------------------------------------------------------------------- 1 | export class Instruction { 2 | constructor(public readonly text: string, public readonly x: number) { 3 | } 4 | 5 | public static fromText(text: string): Instruction { 6 | const split = text.split(" "); 7 | return new Instruction(split[0], parseInt(split[1])); 8 | } 9 | } -------------------------------------------------------------------------------- /exercise/ts/day24/src/position.ts: -------------------------------------------------------------------------------- 1 | export class Position { 2 | constructor(public readonly horizontal: number, public readonly depth: number) { 3 | } 4 | 5 | public changeDepth(newDepth: number): Position { 6 | return new Position(this.horizontal, newDepth); 7 | } 8 | 9 | public moveHorizontally(newHorizontal: number): Position { 10 | return new Position(newHorizontal, this.depth); 11 | } 12 | } -------------------------------------------------------------------------------- /exercise/ts/day24/tests/fileutils.ts: -------------------------------------------------------------------------------- 1 | import * as fs from 'fs'; 2 | import * as path from 'path'; 3 | 4 | const getInputAsString = (inputPath: string): string => { 5 | const fullPath = path.join(__dirname, inputPath); 6 | return fs.readFileSync(fullPath, 'utf8'); 7 | }; 8 | 9 | export const getInputAsSeparatedLines = (inputPath: string): string[] => 10 | getInputAsString(inputPath).split(/\r?\n/); -------------------------------------------------------------------------------- /exercise/ts/day24/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "commonjs", 4 | "target": "es6", 5 | "sourceMap": true 6 | }, 7 | "exclude": [ 8 | "node_modules" 9 | ] 10 | } -------------------------------------------------------------------------------- /solution/c#/Day01/Day01/DateExtensions.cs: -------------------------------------------------------------------------------- 1 | namespace Day01 2 | { 3 | public static class DateExtensions 4 | { 5 | public static bool IsGreaterThan(this DateOnly date, DateOnly other) => date.CompareTo(other) > 0; 6 | } 7 | } -------------------------------------------------------------------------------- /solution/c#/Day01/Day01/Day01.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | net8.0 5 | enable 6 | enable 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /solution/c#/Day02/Day02/Day02.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | net8.0 5 | enable 6 | enable 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /solution/c#/Day02/Day02/OutOfRangeException.cs: -------------------------------------------------------------------------------- 1 | namespace Day02 2 | { 3 | public sealed class OutOfRangeException : ArgumentException 4 | { 5 | } 6 | } -------------------------------------------------------------------------------- /solution/c#/Day03/Day03/Day03.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | net8.0 5 | enable 6 | enable 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /solution/c#/Day03/Day03/Person.cs: -------------------------------------------------------------------------------- 1 | namespace Day03 2 | { 3 | public record Person(string FirstName, string LastName, params Pet[] Pets); 4 | 5 | public record Pet(PetType Type, string Name, int Age); 6 | 7 | public enum PetType 8 | { 9 | Cat, 10 | Dog, 11 | Hamster, 12 | Turtle, 13 | Bird, 14 | Snake 15 | } 16 | } -------------------------------------------------------------------------------- /solution/c#/Day04/Day04/Day04.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | net8.0 5 | enable 6 | enable 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /solution/c#/Day05/Day05/Day05.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | net8.0 5 | enable 6 | enable 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /solution/c#/Day05/Day05/Person.cs: -------------------------------------------------------------------------------- 1 | namespace Day05 2 | { 3 | public record Person(string FirstName, string LastName, params Pet[] Pets); 4 | 5 | public record Pet(PetType Type, string Name, int Age); 6 | 7 | public enum PetType 8 | { 9 | Cat, 10 | Dog, 11 | Hamster, 12 | Turtle, 13 | Bird, 14 | Snake 15 | } 16 | } -------------------------------------------------------------------------------- /solution/c#/Day06/Day06/Day06.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | net8.0 5 | enable 6 | enable 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /solution/c#/Day06/Day06/OutOfRangeException.cs: -------------------------------------------------------------------------------- 1 | namespace Day06 2 | { 3 | public sealed class OutOfRangeException : ArgumentException 4 | { 5 | } 6 | } -------------------------------------------------------------------------------- /solution/c#/Day07/Day07.Tests/Doubles/CapturingLogger.cs: -------------------------------------------------------------------------------- 1 | using Day07.CI.Dependencies; 2 | 3 | namespace Day07.Tests.Doubles 4 | { 5 | public class CapturingLogger : ILogger 6 | { 7 | private readonly List _lines = []; 8 | public void Info(string message) => _lines.Add($"INFO: {message}"); 9 | public void Error(string message) => _lines.Add($"ERROR: {message}"); 10 | public IReadOnlyList LoggedLines => _lines; 11 | } 12 | } -------------------------------------------------------------------------------- /solution/c#/Day07/Day07/CI/Dependencies/IConfig.cs: -------------------------------------------------------------------------------- 1 | namespace Day07.CI.Dependencies 2 | { 3 | public interface IConfig 4 | { 5 | bool SendEmailSummary(); 6 | } 7 | } -------------------------------------------------------------------------------- /solution/c#/Day07/Day07/CI/Dependencies/IEmailer.cs: -------------------------------------------------------------------------------- 1 | namespace Day07.CI.Dependencies 2 | { 3 | public interface IEmailer 4 | { 5 | void Send(string message); 6 | } 7 | } -------------------------------------------------------------------------------- /solution/c#/Day07/Day07/CI/Dependencies/ILogger.cs: -------------------------------------------------------------------------------- 1 | namespace Day07.CI.Dependencies 2 | { 3 | public interface ILogger 4 | { 5 | void Info(string message); 6 | void Error(string message); 7 | } 8 | } -------------------------------------------------------------------------------- /solution/c#/Day07/Day07/CI/Dependencies/TestStatus.cs: -------------------------------------------------------------------------------- 1 | namespace Day07.CI.Dependencies 2 | { 3 | public enum TestStatus 4 | { 5 | NoTests, 6 | PassingTests, 7 | FailingTests, 8 | } 9 | } -------------------------------------------------------------------------------- /solution/c#/Day07/Day07/Day07.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | net8.0 5 | enable 6 | enable 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /solution/c#/Day08/Day08/Day08.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | net8.0 5 | enable 6 | enable 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /solution/c#/Day09/Day09/Day09.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | net8.0 5 | enable 6 | enable 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /solution/c#/Day10/Day10/Day10.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | net8.0 5 | enable 6 | enable 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /solution/c#/Day10/Day10/OutOfRangeException.cs: -------------------------------------------------------------------------------- 1 | namespace Day10 2 | { 3 | public sealed class OutOfRangeException : ArgumentException 4 | { 5 | } 6 | } -------------------------------------------------------------------------------- /solution/c#/Day11/Day11/Day11.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | net8.0 5 | enable 6 | enable 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /solution/c#/Day11/libyear/libyear-result.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/advent-of-craft/2023/178dfa1e2fbd640c65fc903122b1fcda77d7fa9c/solution/c#/Day11/libyear/libyear-result.png -------------------------------------------------------------------------------- /solution/c#/Day12/Day12/Day12.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | net8.0 5 | enable 6 | enable 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /solution/c#/Day13/Day13/Day13.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | net8.0 5 | enable 6 | enable 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /solution/c#/Day14/Day14/Day14.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | net8.0 5 | enable 6 | enable 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /solution/c#/Day14/Day14/Result.cs: -------------------------------------------------------------------------------- 1 | namespace Day14 2 | { 3 | public record Result 4 | { 5 | private readonly T? _success; 6 | private Result(T success) => _success = success; 7 | 8 | private Result() 9 | { 10 | } 11 | 12 | public static Result FromSuccess(T success) => new(success); 13 | public static Result Failure() => new(); 14 | 15 | public T? Success() => _success; 16 | public bool Failed() => _success == null; 17 | } 18 | } -------------------------------------------------------------------------------- /solution/c#/Day15/Day15/Day15.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | net8.0 5 | enable 6 | enable 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /solution/c#/Day15/Day15/DocumentTemplate.cs: -------------------------------------------------------------------------------- 1 | namespace Day15 2 | { 3 | public enum DocumentTemplate 4 | { 5 | DEERPP, 6 | DEERPM, 7 | AUTP, 8 | AUTM, 9 | SPEC, 10 | GLPP, 11 | GLPM 12 | } 13 | } -------------------------------------------------------------------------------- /solution/c#/Day15/Day15/RecordType.cs: -------------------------------------------------------------------------------- 1 | namespace Day15 2 | { 3 | public enum RecordType 4 | { 5 | IndividualProspect, 6 | LegalProspect, 7 | All 8 | } 9 | } -------------------------------------------------------------------------------- /solution/c#/Day15/Day15/Template.cs: -------------------------------------------------------------------------------- 1 | namespace Day15 2 | { 3 | public record Template( 4 | DocumentTemplate DocumentTemplate, 5 | RecordType RecordType, 6 | string DocumentType) 7 | { 8 | public override string ToString() => DocumentTemplate.ToString(); 9 | } 10 | } -------------------------------------------------------------------------------- /solution/c#/Day16/Day16/Day16.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | net8.0 5 | enable 6 | enable 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /solution/c#/Day17/Day17/Day17.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | net8.0 5 | enable 6 | enable 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /solution/c#/Day18/Day18/Day18.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | net8.0 5 | enable 6 | enable 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /solution/c#/Day18/Day18/ShittyClass.cs: -------------------------------------------------------------------------------- 1 | namespace Day18 2 | { 3 | public class ShittyClass 4 | { 5 | private const string ConsecutiveUnderscoresKillReadability = "detect me if you can 😬"; 6 | private const string ExternalUnderscoresKillItToo = "detect me if you can 🚀"; 7 | 8 | public void Do() 9 | { 10 | } 11 | 12 | private bool IsTrue() => true; 13 | } 14 | } -------------------------------------------------------------------------------- /solution/c#/Day19/Day19/Day19.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | net8.0 5 | enable 6 | enable 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /solution/c#/Day20/Day20/Day20.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | net8.0 5 | enable 6 | enable 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /solution/c#/Day21/Day21/Day21.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | net8.0 5 | enable 6 | enable 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /solution/c#/Day21/Day21/IFileSystem.cs: -------------------------------------------------------------------------------- 1 | namespace Day21 2 | { 3 | public interface IFileSystem 4 | { 5 | string[] GetFiles(string directoryName); 6 | void WriteAllText(string filePath, string content); 7 | IEnumerable ReadAllLines(string filePath); 8 | } 9 | } -------------------------------------------------------------------------------- /solution/c#/Day22/Day22/Day22.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | net8.0 5 | enable 6 | enable 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /solution/c#/Day23/Day23.Tests/FunctionalExtensions.cs: -------------------------------------------------------------------------------- 1 | namespace Day23.Tests 2 | { 3 | public static class FunctionalExtensions 4 | { 5 | public static T Let(this T obj, Action action) 6 | { 7 | if (obj != null) action(obj); 8 | return obj; 9 | } 10 | } 11 | } -------------------------------------------------------------------------------- /solution/c#/Day23/Day23/Day23.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | net8.0 5 | enable 6 | enable 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /solution/c#/Day23/Day23/Exception/CollaboratorCallException.cs: -------------------------------------------------------------------------------- 1 | namespace Day23.Exception 2 | { 3 | public class CollaboratorCallException(string message) : System.Exception(message); 4 | } -------------------------------------------------------------------------------- /solution/c#/Day23/Day23/Exception/UserNotLoggedInException.cs: -------------------------------------------------------------------------------- 1 | namespace Day23.Exception 2 | { 3 | public class UserNotLoggedInException : System.Exception 4 | { 5 | } 6 | } -------------------------------------------------------------------------------- /solution/c#/Day23/Day23/Trips/ITripRepository.cs: -------------------------------------------------------------------------------- 1 | using Day23.Users; 2 | using LanguageExt; 3 | 4 | namespace Day23.Trips 5 | { 6 | public interface ITripRepository 7 | { 8 | public Seq FindTripsByUser(User user) => TripDAO.FindTripsByUser(user); 9 | } 10 | } -------------------------------------------------------------------------------- /solution/c#/Day23/Day23/Trips/Trip.cs: -------------------------------------------------------------------------------- 1 | namespace Day23.Trips 2 | { 3 | public class Trip 4 | { 5 | } 6 | } -------------------------------------------------------------------------------- /solution/c#/Day23/Day23/Trips/TripDAO.cs: -------------------------------------------------------------------------------- 1 | using Day23.Exception; 2 | using Day23.Users; 3 | using LanguageExt; 4 | 5 | namespace Day23.Trips 6 | { 7 | public static class TripDAO 8 | { 9 | public static Seq FindTripsByUser(User user) 10 | { 11 | throw new CollaboratorCallException("TripDAO should not be invoked on an unit test."); 12 | } 13 | } 14 | } -------------------------------------------------------------------------------- /solution/c#/Day24/Day24/Day24.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | net8.0 5 | enable 6 | enable 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /solution/java/day02/src/main/java/games/OutOfRangeException.java: -------------------------------------------------------------------------------- 1 | package games; 2 | 3 | public class OutOfRangeException extends Exception { 4 | } 5 | -------------------------------------------------------------------------------- /solution/java/day03/src/main/java/people/Person.java: -------------------------------------------------------------------------------- 1 | package people; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | public record Person(String firstName, String lastName, List pets) { 7 | public Person(String firstName, String lastName) { 8 | this(firstName, lastName, new ArrayList<>()); 9 | } 10 | 11 | public Person addPet(PetType petType, String name, int age) { 12 | pets.add(new Pet(petType, name, age)); 13 | return this; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /solution/java/day03/src/main/java/people/Pet.java: -------------------------------------------------------------------------------- 1 | package people; 2 | 3 | public record Pet(PetType type, String name, int age) { 4 | } 5 | -------------------------------------------------------------------------------- /solution/java/day03/src/main/java/people/PetType.java: -------------------------------------------------------------------------------- 1 | package people; 2 | 3 | public enum PetType { 4 | CAT, DOG, HAMSTER, TURTLE, BIRD, SNAKE 5 | } 6 | -------------------------------------------------------------------------------- /solution/java/day04/src/main/java/blog/Comment.java: -------------------------------------------------------------------------------- 1 | package blog; 2 | 3 | import java.time.LocalDate; 4 | 5 | public record Comment(String text, String author, LocalDate creationDate) { 6 | } 7 | -------------------------------------------------------------------------------- /solution/java/day04/src/main/java/blog/CommentAlreadyExistException.java: -------------------------------------------------------------------------------- 1 | package blog; 2 | 3 | public class CommentAlreadyExistException extends Exception { 4 | } -------------------------------------------------------------------------------- /solution/java/day05/src/main/java/people/Person.java: -------------------------------------------------------------------------------- 1 | package people; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | public record Person(String firstName, String lastName, List pets) { 7 | public Person(String firstName, String lastName) { 8 | this(firstName, lastName, new ArrayList<>()); 9 | } 10 | 11 | public Person addPet(PetType petType, String name, int age) { 12 | pets.add(new Pet(petType, name, age)); 13 | return this; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /solution/java/day05/src/main/java/people/Pet.java: -------------------------------------------------------------------------------- 1 | package people; 2 | 3 | public record Pet(PetType type, String name, int age) { 4 | } 5 | -------------------------------------------------------------------------------- /solution/java/day05/src/main/java/people/PetType.java: -------------------------------------------------------------------------------- 1 | package people; 2 | 3 | public enum PetType { 4 | CAT, DOG, HAMSTER, TURTLE, BIRD, SNAKE 5 | } 6 | -------------------------------------------------------------------------------- /solution/java/day06/src/main/java/games/OutOfRangeException.java: -------------------------------------------------------------------------------- 1 | package games; 2 | 3 | public class OutOfRangeException extends Exception { 4 | } 5 | -------------------------------------------------------------------------------- /solution/java/day07/src/main/java/ci/dependencies/Config.java: -------------------------------------------------------------------------------- 1 | package ci.dependencies; 2 | 3 | public interface Config { 4 | boolean sendEmailSummary(); 5 | } 6 | -------------------------------------------------------------------------------- /solution/java/day07/src/main/java/ci/dependencies/Emailer.java: -------------------------------------------------------------------------------- 1 | package ci.dependencies; 2 | 3 | public interface Emailer { 4 | void send(String message); 5 | } 6 | -------------------------------------------------------------------------------- /solution/java/day07/src/main/java/ci/dependencies/Logger.java: -------------------------------------------------------------------------------- 1 | package ci.dependencies; 2 | 3 | public interface Logger { 4 | void info(String message); 5 | 6 | void error(String message); 7 | } 8 | -------------------------------------------------------------------------------- /solution/java/day07/src/main/java/ci/dependencies/TestStatus.java: -------------------------------------------------------------------------------- 1 | package ci.dependencies; 2 | 3 | public enum TestStatus { 4 | NO_TESTS, 5 | PASSING_TESTS, 6 | FAILING_TESTS, 7 | } 8 | -------------------------------------------------------------------------------- /solution/java/day08/src/main/java/password/functional/ParsingError.java: -------------------------------------------------------------------------------- 1 | package password.functional; 2 | 3 | public record ParsingError(String reason) { 4 | public static ParsingError from(String reason) { 5 | return new ParsingError(reason); 6 | } 7 | } -------------------------------------------------------------------------------- /solution/java/day10/src/main/java/games/OutOfRangeException.java: -------------------------------------------------------------------------------- 1 | package games; 2 | 3 | public class OutOfRangeException extends Exception { 4 | } 5 | -------------------------------------------------------------------------------- /solution/java/day13/src/main/java/blog/Comment.java: -------------------------------------------------------------------------------- 1 | package blog; 2 | 3 | import java.time.LocalDate; 4 | 5 | public record Comment(String text, String author, LocalDate creationDate) { 6 | } 7 | -------------------------------------------------------------------------------- /solution/java/day13/src/main/java/blog/CommentAlreadyExistException.java: -------------------------------------------------------------------------------- 1 | package blog; 2 | 3 | public class CommentAlreadyExistException extends Exception { 4 | } -------------------------------------------------------------------------------- /solution/java/day15/src/main/java/document/RecordType.java: -------------------------------------------------------------------------------- 1 | package document; 2 | 3 | public enum RecordType { 4 | INDIVIDUAL_PROSPECT("IndividualPersonProspect"), 5 | LEGAL_PROSPECT("LegalEntityProspect"), 6 | ALL("All"); 7 | private final String value; 8 | 9 | RecordType(String value) { 10 | this.value = value; 11 | } 12 | 13 | public String getValue() { 14 | return value; 15 | } 16 | } -------------------------------------------------------------------------------- /solution/java/day16/src/main/java/blog/Comment.java: -------------------------------------------------------------------------------- 1 | package blog; 2 | 3 | import java.time.LocalDate; 4 | 5 | public record Comment(String text, String author, LocalDate creationDate) { 6 | } 7 | -------------------------------------------------------------------------------- /solution/java/day16/src/main/java/blog/CommentAlreadyExistException.java: -------------------------------------------------------------------------------- 1 | package blog; 2 | 3 | public class CommentAlreadyExistException extends RuntimeException { 4 | } -------------------------------------------------------------------------------- /solution/java/day18/src/main/java/lap/ShittyClass.java: -------------------------------------------------------------------------------- 1 | package lap; 2 | 3 | public class ShittyClass { 4 | private final String consecutive__underscores__kill__readability = "detect me if you can 😬"; 5 | private final String _external_underscores_kill_it_too = "detect me if you can 🚀"; 6 | 7 | public void getData() { 8 | } 9 | 10 | private int isTrue() { 11 | return 42; 12 | } 13 | } -------------------------------------------------------------------------------- /solution/java/day18/src/test/resources/archunit.properties: -------------------------------------------------------------------------------- 1 | archRule.failOnEmptyShould=false -------------------------------------------------------------------------------- /solution/java/day19/src/main/java/blog/Comment.java: -------------------------------------------------------------------------------- 1 | package blog; 2 | 3 | import java.time.LocalDate; 4 | 5 | public record Comment(String text, String author, LocalDate creationDate) { 6 | } 7 | -------------------------------------------------------------------------------- /solution/java/day19/src/main/java/blog/Error.java: -------------------------------------------------------------------------------- 1 | package blog; 2 | 3 | public record Error(String message) { 4 | } 5 | -------------------------------------------------------------------------------- /solution/java/day20/src/main/java/domain/yahtzee/constrain/input/Error.java: -------------------------------------------------------------------------------- 1 | package domain.yahtzee.constrain.input; 2 | 3 | public record Error(String message) { 4 | public static Error error(String message) { 5 | return new Error(message); 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /solution/java/day21/src/main/java/audit/AddNewVisitor.java: -------------------------------------------------------------------------------- 1 | package audit; 2 | 3 | import java.time.LocalDateTime; 4 | 5 | public record AddNewVisitor(String visitor, LocalDateTime time) { 6 | 7 | } 8 | -------------------------------------------------------------------------------- /solution/java/day21/src/main/java/audit/FileContent.java: -------------------------------------------------------------------------------- 1 | package audit; 2 | 3 | import java.util.ArrayList; 4 | 5 | public record FileContent(String fileName, ArrayList lines) { 6 | } -------------------------------------------------------------------------------- /solution/java/day21/src/main/java/audit/FileUpdate.java: -------------------------------------------------------------------------------- 1 | package audit; 2 | 3 | public record FileUpdate(String fileName, String newContent) { 4 | } 5 | -------------------------------------------------------------------------------- /solution/java/day22/.tcr/config.yml: -------------------------------------------------------------------------------- 1 | config: 2 | git: 3 | auto-push: false 4 | polling-period: 2s 5 | mob-timer: 6 | duration: 5m0s 7 | tcr: 8 | language: java 9 | toolchain: maven 10 | -------------------------------------------------------------------------------- /solution/java/day22/.tcr/language/java.yml: -------------------------------------------------------------------------------- 1 | toolchains: 2 | default: maven 3 | compatible-with: [ maven ] 4 | source-files: 5 | directories: [ src/main ] 6 | patterns: [ '(?i)^.*\.java$' ] 7 | test-files: 8 | directories: [ src/test ] 9 | patterns: [ '(?i)^.*\.java$' ] 10 | -------------------------------------------------------------------------------- /solution/java/day22/.tcr/toolchain/maven.yml: -------------------------------------------------------------------------------- 1 | build: 2 | - os: [ darwin, linux, windows ] 3 | arch: [ "386", amd64, arm64 ] 4 | command: mvn 5 | arguments: [ test-compile ] 6 | test: 7 | - os: [ darwin, linux, windows ] 8 | arch: [ "386", amd64, arm64 ] 9 | command: mvn 10 | arguments: [ test ] 11 | test-result-dir: target/surefire-reports 12 | -------------------------------------------------------------------------------- /solution/java/day22/tcrw: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | base_dir="$(cd "$(dirname -- "$0")" && pwd)" 4 | . "${base_dir}/../tcr/tcr.sh" 5 | -------------------------------------------------------------------------------- /solution/java/day23/src/main/java/org/craftedsw/tripservicekata/exception/UserNotLoggedInException.java: -------------------------------------------------------------------------------- 1 | package org.craftedsw.tripservicekata.exception; 2 | 3 | public class UserNotLoggedInException extends RuntimeException { 4 | private static final long serialVersionUID = 8959479918185637340L; 5 | 6 | } -------------------------------------------------------------------------------- /solution/java/day23/src/main/java/org/craftedsw/tripservicekata/trip/Trip.java: -------------------------------------------------------------------------------- 1 | package org.craftedsw.tripservicekata.trip; 2 | 3 | public record Trip() { 4 | 5 | } 6 | -------------------------------------------------------------------------------- /solution/java/day23/src/main/java/org/craftedsw/tripservicekata/trip/TripRepository.java: -------------------------------------------------------------------------------- 1 | package org.craftedsw.tripservicekata.trip; 2 | 3 | import io.vavr.collection.Seq; 4 | import org.craftedsw.tripservicekata.user.User; 5 | 6 | public class TripRepository { 7 | public Seq findTripsByUser(User user) { 8 | return TripDAO.findTripsByUser(user); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /solution/kotlin/day02/src/main/kotlin/games/OutOfRangeException.kt: -------------------------------------------------------------------------------- 1 | package games 2 | 3 | class OutOfRangeException : Throwable() { 4 | 5 | } 6 | -------------------------------------------------------------------------------- /solution/kotlin/day06/src/main/kotlin/games/OutOfRangeException.kt: -------------------------------------------------------------------------------- 1 | package games 2 | 3 | class OutOfRangeException : Throwable() -------------------------------------------------------------------------------- /solution/kotlin/day07/src/test/kotlin/CapturingLogger.kt: -------------------------------------------------------------------------------- 1 | import ci.Logger 2 | 3 | 4 | data class CapturingLogger(val lines: MutableList = mutableListOf()) : Logger { 5 | override fun info(message: String) { 6 | lines.add("INFO: $message") 7 | } 8 | 9 | override fun error(message: String) { 10 | lines.add("ERROR: $message") 11 | } 12 | } -------------------------------------------------------------------------------- /solution/kotlin/day08/src/main/kotlin/password/ParsingError.kt: -------------------------------------------------------------------------------- 1 | package password 2 | 3 | data class ParsingError(val reason: String) { 4 | companion object { 5 | fun from(reason: String): ParsingError { 6 | return ParsingError(reason) 7 | } 8 | } 9 | } -------------------------------------------------------------------------------- /solution/kotlin/day10/src/main/kotlin/games/OutOfRangeException.kt: -------------------------------------------------------------------------------- 1 | package games 2 | 3 | class OutOfRangeException : Throwable() -------------------------------------------------------------------------------- /solution/kotlin/day15/src/main/kotlin/document/RecordType.kt: -------------------------------------------------------------------------------- 1 | package document 2 | 3 | enum class RecordType(val value: String) { 4 | INDIVIDUAL_PROSPECT("IndividualPersonProspect"), 5 | LEGAL_PROSPECT("LegalEntityProspect"), 6 | ALL("All") 7 | } -------------------------------------------------------------------------------- /solution/kotlin/day18/src/main/kotlin/lap/ShittyClass.kt: -------------------------------------------------------------------------------- 1 | package lap 2 | 3 | class ShittyClass { 4 | private val consecutive__underscores__kill__readability = "detect me if you can 😬" 5 | private val _external_underscores_kill_it_too = "detect me if you can 🚀" 6 | fun getData() = Unit 7 | fun isTrue() = 42 8 | } -------------------------------------------------------------------------------- /solution/kotlin/day18/src/test/resources/archunit.properties: -------------------------------------------------------------------------------- 1 | archRule.failOnEmptyShould=false -------------------------------------------------------------------------------- /solution/kotlin/day20/src/main/kotlin/domain/yahtzee/constrain/input/Error.kt: -------------------------------------------------------------------------------- 1 | package domain.yahtzee.constrain.input 2 | 3 | data class Error(val message: String) -------------------------------------------------------------------------------- /solution/kotlin/day20/src/test/kotlin/builders/DiceBuilder.kt: -------------------------------------------------------------------------------- 1 | package builders 2 | 3 | class DiceBuilder private constructor(private val dice: IntArray) { 4 | fun build(): IntArray { 5 | return dice 6 | } 7 | 8 | override fun toString(): String = dice.contentToString() 9 | 10 | companion object { 11 | fun `🎲🎲🎲🎲🎲`(dice1: Int, dice2: Int, dice3: Int, dice4: Int, dice5: Int): DiceBuilder = 12 | DiceBuilder(intArrayOf(dice1, dice2, dice3, dice4, dice5)) 13 | } 14 | } -------------------------------------------------------------------------------- /solution/kotlin/day20/src/test/kotlin/parameters/ParameterizedTests.kt: -------------------------------------------------------------------------------- 1 | package parameters 2 | 3 | import builders.DiceBuilder 4 | 5 | data class NumberRollCase(val dice: DiceBuilder, val number: Int, val expectedResult: Int) 6 | data class RollCase(val dice: DiceBuilder, val expectedResult: Int) 7 | class InvalidRoll(vararg val dice: Int) -------------------------------------------------------------------------------- /solution/kotlin/day21/src/main/kotlin/audit/AddNewVisitor.kt: -------------------------------------------------------------------------------- 1 | package audit 2 | 3 | import java.time.LocalDateTime 4 | 5 | data class AddNewVisitor(val visitor: String, val time: LocalDateTime) -------------------------------------------------------------------------------- /solution/kotlin/day21/src/main/kotlin/audit/FileContent.kt: -------------------------------------------------------------------------------- 1 | package audit 2 | 3 | data class FileContent(val fileName: String, val lines: List) { 4 | fun index(): Int = fileName.split("_")[1].split(".")[0].toInt() 5 | } -------------------------------------------------------------------------------- /solution/kotlin/day21/src/main/kotlin/audit/FileUpdate.kt: -------------------------------------------------------------------------------- 1 | package audit 2 | 3 | data class FileUpdate(val fileName: String, val newContent: String) 4 | -------------------------------------------------------------------------------- /solution/kotlin/day22/.tcr/config.yml: -------------------------------------------------------------------------------- 1 | config: 2 | git: 3 | auto-push: false 4 | polling-period: 2s 5 | mob-timer: 6 | duration: 5m0s 7 | tcr: 8 | language: kotlin 9 | toolchain: gradle-wrapper 10 | -------------------------------------------------------------------------------- /solution/kotlin/day22/.tcr/language/java.yml: -------------------------------------------------------------------------------- 1 | toolchains: 2 | default: maven 3 | compatible-with: [ maven ] 4 | source-files: 5 | directories: [ src/main ] 6 | patterns: [ '(?i)^.*\.java$' ] 7 | test-files: 8 | directories: [ src/test ] 9 | patterns: [ '(?i)^.*\.java$' ] 10 | -------------------------------------------------------------------------------- /solution/kotlin/day22/.tcr/toolchain/maven.yml: -------------------------------------------------------------------------------- 1 | build: 2 | - os: [ darwin, linux, windows ] 3 | arch: [ "386", amd64, arm64 ] 4 | command: mvn 5 | arguments: [ test-compile ] 6 | test: 7 | - os: [ darwin, linux, windows ] 8 | arch: [ "386", amd64, arm64 ] 9 | command: mvn 10 | arguments: [ test ] 11 | test-result-dir: target/surefire-reports 12 | -------------------------------------------------------------------------------- /solution/kotlin/day22/src/test/kotlin/DiamondTests.kt: -------------------------------------------------------------------------------- 1 | import diamond.Diamond.toDiamond 2 | import org.approvaltests.Approvals.verify 3 | import org.junit.jupiter.api.Test 4 | 5 | class DiamondTests { 6 | @Test 7 | fun `print diamond for K`() { 8 | verify('K'.toDiamond().getOrNull()) 9 | } 10 | } -------------------------------------------------------------------------------- /solution/kotlin/day22/tcrw: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | base_dir="$(cd "$(dirname -- "$0")" && pwd)" 4 | . "${base_dir}/../tcr/tcr.sh" 5 | -------------------------------------------------------------------------------- /solution/kotlin/day23/src/main/kotlin/org/craftedsw/tripservicekata/exception/UserNotLoggedInException.kt: -------------------------------------------------------------------------------- 1 | package org.craftedsw.tripservicekata.exception 2 | 3 | class UserNotLoggedInException : RuntimeException() { 4 | 5 | companion object { 6 | private val serialVersionUID: Long = 8959479918185637340L 7 | } 8 | 9 | } 10 | -------------------------------------------------------------------------------- /solution/kotlin/day23/src/main/kotlin/org/craftedsw/tripservicekata/trip/Trip.kt: -------------------------------------------------------------------------------- 1 | package org.craftedsw.tripservicekata.trip 2 | 3 | class Trip 4 | -------------------------------------------------------------------------------- /solution/kotlin/day23/src/main/kotlin/org/craftedsw/tripservicekata/trip/TripDAO.kt: -------------------------------------------------------------------------------- 1 | package org.craftedsw.tripservicekata.trip 2 | 3 | import org.craftedsw.tripservicekata.exception.CollaboratorCallException 4 | import org.craftedsw.tripservicekata.user.User 5 | 6 | class TripDAO { 7 | companion object { 8 | fun findTripsByUser(user: User): List { 9 | throw CollaboratorCallException("TripDAO should not be invoked on an unit test.") 10 | } 11 | } 12 | } -------------------------------------------------------------------------------- /solution/kotlin/day23/src/main/kotlin/org/craftedsw/tripservicekata/trip/TripRepository.kt: -------------------------------------------------------------------------------- 1 | package org.craftedsw.tripservicekata.trip 2 | 3 | import org.craftedsw.tripservicekata.user.User 4 | 5 | class TripRepository { 6 | fun findTripsByUser(user: User): List = TripDAO.findTripsByUser(user) 7 | } -------------------------------------------------------------------------------- /solution/kotlin/day23/src/main/kotlin/org/craftedsw/tripservicekata/user/User.kt: -------------------------------------------------------------------------------- 1 | package org.craftedsw.tripservicekata.user 2 | 3 | import org.craftedsw.tripservicekata.trip.Trip 4 | 5 | class User(val trips: List, val friends: List) { 6 | fun addFriend(user: User) = User(trips = trips, friends = friends + user) 7 | fun addTrip(trip: Trip) = User(trips = trips + trip, friends = friends) 8 | fun isFriendWith(anotherUser: User?): Boolean = friends.contains(anotherUser) 9 | } 10 | -------------------------------------------------------------------------------- /solution/kotlin/gradle.properties: -------------------------------------------------------------------------------- 1 | kotlin.code.style=official 2 | -------------------------------------------------------------------------------- /solution/kotlin/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.2-bin.zip 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists -------------------------------------------------------------------------------- /solution/ts/day01/jest.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | transform: {'^.+\\.ts?$': 'ts-jest'}, 3 | testEnvironment: 'node', 4 | testRegex: '/tests/.*\\.(test|spec)?\\.(ts|tsx)$', 5 | moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json', 'node'] 6 | }; -------------------------------------------------------------------------------- /solution/ts/day01/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "day-1-edible", 3 | "description": "Day 1: Make your production code easier to understand.", 4 | "version": "1.0.0", 5 | "dependencies": { 6 | "typescript": "^5.3.3", 7 | "@types/uuidv4": "^5.0.0" 8 | }, 9 | "devDependencies": { 10 | "jest": "^29.7.0", 11 | "ts-jest": "^29.1.1", 12 | "@types/jest": "^29.5.8" 13 | }, 14 | "scripts": { 15 | "test": "jest" 16 | } 17 | } -------------------------------------------------------------------------------- /solution/ts/day01/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "commonjs", 4 | "target": "es6", 5 | "sourceMap": true 6 | }, 7 | "exclude": [ 8 | "node_modules" 9 | ] 10 | } -------------------------------------------------------------------------------- /solution/ts/day02/jest.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | transform: {'^.+\\.ts?$': 'ts-jest'}, 3 | testEnvironment: 'node', 4 | testRegex: '/tests/.*\\.(test|spec)?\\.(ts|tsx)$', 5 | moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json', 'node'] 6 | }; -------------------------------------------------------------------------------- /solution/ts/day02/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "day-2-fizzbuzz", 3 | "version": "1.0.0", 4 | "description": "Day 2: One level of indentation.", 5 | "dependencies": { 6 | "typescript": "^5.3.3" 7 | }, 8 | "devDependencies": { 9 | "jest": "^29.7.0", 10 | "ts-jest": "^29.1.1", 11 | "@types/jest": "^29.5.8" 12 | }, 13 | "scripts": { 14 | "test": "jest" 15 | } 16 | } -------------------------------------------------------------------------------- /solution/ts/day02/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "commonjs", 4 | "target": "es6", 5 | "sourceMap": true 6 | }, 7 | "exclude": [ 8 | "node_modules" 9 | ] 10 | } -------------------------------------------------------------------------------- /solution/ts/day03/jest.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | transform: {'^.+\\.ts?$': 'ts-jest'}, 3 | testEnvironment: 'node', 4 | testRegex: '/tests/.*\\.(test|spec)?\\.(ts|tsx)$', 5 | moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json', 'node'] 6 | }; -------------------------------------------------------------------------------- /solution/ts/day03/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "day-3-people", 3 | "version": "1.0.0", 4 | "dependencies": { 5 | "typescript": "^5.3.3" 6 | }, 7 | "devDependencies": { 8 | "jest": "^29.7.0", 9 | "ts-jest": "^29.1.1", 10 | "@types/jest": "^29.5.8" 11 | }, 12 | "scripts": { 13 | "test": "jest" 14 | } 15 | } -------------------------------------------------------------------------------- /solution/ts/day03/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "commonjs", 4 | "target": "es6", 5 | "sourceMap": true 6 | }, 7 | "exclude": [ 8 | "node_modules" 9 | ] 10 | } -------------------------------------------------------------------------------- /solution/ts/day04/jest.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | transform: {'^.+\\.ts?$': 'ts-jest'}, 3 | testEnvironment: 'node', 4 | testRegex: '/tests/.*\\.(test|spec)?\\.(ts|tsx)$', 5 | moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json', 'node'] 6 | }; -------------------------------------------------------------------------------- /solution/ts/day04/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "day-4-blog", 3 | "description": "Day 4: Identify the behavior under test and rewrite the tests.", 4 | "version": "1.0.0", 5 | "dependencies": { 6 | "typescript": "^5.3.3" 7 | }, 8 | "devDependencies": { 9 | "jest": "^29.7.0", 10 | "ts-jest": "^29.1.1", 11 | "@types/jest": "^29.5.8" 12 | }, 13 | "scripts": { 14 | "test": "jest" 15 | } 16 | } -------------------------------------------------------------------------------- /solution/ts/day04/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "commonjs", 4 | "target": "es6", 5 | "sourceMap": true 6 | }, 7 | "exclude": [ 8 | "node_modules" 9 | ] 10 | } -------------------------------------------------------------------------------- /solution/ts/day05/jest.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | transform: {'^.+\\.ts?$': 'ts-jest'}, 3 | testEnvironment: 'node', 4 | testRegex: '/tests/.*\\.(test|spec)?\\.(ts|tsx)$', 5 | moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json', 'node'] 6 | }; -------------------------------------------------------------------------------- /solution/ts/day05/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "day-5-people", 3 | "description": "Day 5: No for loop authorized.", 4 | "version": "1.0.0", 5 | "dependencies": { 6 | "typescript": "^5.3.3" 7 | }, 8 | "devDependencies": { 9 | "jest": "^29.7.0", 10 | "ts-jest": "^29.1.1", 11 | "@types/jest": "^29.5.8" 12 | }, 13 | "scripts": { 14 | "test": "jest" 15 | } 16 | } -------------------------------------------------------------------------------- /solution/ts/day05/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "commonjs", 4 | "target": "es6", 5 | "sourceMap": true 6 | }, 7 | "exclude": [ 8 | "node_modules" 9 | ] 10 | } -------------------------------------------------------------------------------- /solution/ts/day06/jest.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | transform: {'^.+\\.ts?$': 'ts-jest'}, 3 | testEnvironment: 'node', 4 | testRegex: '/tests/.*\\.(test|spec)?\\.(ts|tsx)$', 5 | moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json', 'node'] 6 | }; -------------------------------------------------------------------------------- /solution/ts/day06/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "day-6-fizzbuzz", 3 | "version": "1.0.0", 4 | "description": "Day 6: Parameterize your tests.", 5 | "dependencies": { 6 | "typescript": "^5.3.3" 7 | }, 8 | "devDependencies": { 9 | "jest": "^29.7.0", 10 | "ts-jest": "^29.1.1", 11 | "@types/jest": "^29.5.8" 12 | }, 13 | "scripts": { 14 | "test": "jest" 15 | } 16 | } -------------------------------------------------------------------------------- /solution/ts/day06/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "commonjs", 4 | "target": "es6", 5 | "sourceMap": true 6 | }, 7 | "exclude": [ 8 | "node_modules" 9 | ] 10 | } -------------------------------------------------------------------------------- /solution/ts/day07/jest.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | transform: {'^.+\\.ts?$': 'ts-jest'}, 3 | testEnvironment: 'node', 4 | testRegex: '/tests/.*\\.(test|spec)?\\.(ts|tsx)$', 5 | moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json', 'node'] 6 | }; -------------------------------------------------------------------------------- /solution/ts/day07/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "day-7-pipeline", 3 | "version": "1.0.0", 4 | "description": "Day 7: Simplify the run method by extracting the right behavior.", 5 | "dependencies": { 6 | "typescript": "^5.3.3", 7 | "fp-ts": "^2.16.1" 8 | }, 9 | "devDependencies": { 10 | "jest": "^29.7.0", 11 | "ts-jest": "^29.1.1", 12 | "@types/jest": "^29.5.8" 13 | }, 14 | "scripts": { 15 | "test": "jest" 16 | } 17 | } -------------------------------------------------------------------------------- /solution/ts/day07/src/ci.ts: -------------------------------------------------------------------------------- 1 | export interface Config { 2 | sendEmailSummary(): boolean; 3 | } 4 | 5 | export interface Emailer { 6 | send(message: string): void; 7 | } 8 | 9 | export interface Logger { 10 | info(message: string): void; 11 | 12 | error(message: string): void; 13 | } 14 | 15 | export enum TestStatus { 16 | NoTests, 17 | PassingTests, 18 | FailingTests, 19 | } -------------------------------------------------------------------------------- /solution/ts/day07/tests/capturingLogger.ts: -------------------------------------------------------------------------------- 1 | import {Logger} from "../src/ci"; 2 | 3 | export class CapturingLogger implements Logger { 4 | private lines: string[] = []; 5 | 6 | info(message: string): void { 7 | this.lines.push(`INFO: ${message}`) 8 | } 9 | 10 | error(message: string): void { 11 | this.lines.push(`ERROR: ${message}`) 12 | } 13 | 14 | loggedLines = () => this.lines; 15 | } -------------------------------------------------------------------------------- /solution/ts/day07/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "commonjs", 4 | "target": "es6", 5 | "sourceMap": true 6 | }, 7 | "exclude": [ 8 | "node_modules" 9 | ] 10 | } -------------------------------------------------------------------------------- /solution/ts/day08/jest.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | transform: {'^.+\\.ts?$': 'ts-jest'}, 3 | testEnvironment: 'node', 4 | testRegex: '/tests/.*\\.(test|spec)?\\.(ts|tsx)$', 5 | moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json', 'node'] 6 | }; -------------------------------------------------------------------------------- /solution/ts/day08/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "day-8-password-validation", 3 | "version": "1.0.0", 4 | "description": "Day 8: Using TDD rules, write a password validation program.", 5 | "dependencies": { 6 | "typescript": "^5.3.3", 7 | "fp-ts": "^2.16.1" 8 | }, 9 | "devDependencies": { 10 | "jest": "^29.7.0", 11 | "ts-jest": "^29.1.1", 12 | "@types/jest": "^29.5.8" 13 | }, 14 | "scripts": { 15 | "test": "jest" 16 | } 17 | } -------------------------------------------------------------------------------- /solution/ts/day08/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "commonjs", 4 | "target": "es6", 5 | "sourceMap": true 6 | }, 7 | "exclude": [ 8 | "node_modules" 9 | ] 10 | } -------------------------------------------------------------------------------- /solution/ts/day09/jest.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | transform: {'^.+\\.ts?$': 'ts-jest'}, 3 | testEnvironment: 'node', 4 | testRegex: '/tests/.*\\.(test|spec)?\\.(ts|tsx)$', 5 | moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json', 'node'] 6 | }; -------------------------------------------------------------------------------- /solution/ts/day09/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "day-9-accountability", 3 | "version": "1.0.0", 4 | "description": "Day 9: Fix the code.", 5 | "dependencies": { 6 | "typescript": "^5.3.3" 7 | }, 8 | "devDependencies": { 9 | "jest": "^29.7.0", 10 | "ts-jest": "^29.1.1", 11 | "@types/jest": "^29.5.8" 12 | }, 13 | "scripts": { 14 | "test": "jest" 15 | } 16 | } -------------------------------------------------------------------------------- /solution/ts/day09/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "commonjs", 4 | "target": "es6", 5 | "sourceMap": true 6 | }, 7 | "exclude": [ 8 | "node_modules" 9 | ] 10 | } -------------------------------------------------------------------------------- /solution/ts/day10/jest.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | transform: {'^.+\\.ts?$': 'ts-jest'}, 3 | testEnvironment: 'node', 4 | testRegex: '/tests/.*\\.(test|spec)?\\.(ts|tsx)$', 5 | moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json', 'node'] 6 | }; -------------------------------------------------------------------------------- /solution/ts/day10/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "day-10-fizzbuzz", 3 | "version": "1.0.0", 4 | "description": "Day 10: Dot not use if statement.", 5 | "dependencies": { 6 | "typescript": "^5.3.3" 7 | }, 8 | "devDependencies": { 9 | "jest": "^29.7.0", 10 | "ts-jest": "^29.1.1", 11 | "@types/jest": "^29.5.8" 12 | }, 13 | "scripts": { 14 | "test": "jest" 15 | } 16 | } -------------------------------------------------------------------------------- /solution/ts/day10/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "commonjs", 4 | "target": "es6", 5 | "sourceMap": true 6 | }, 7 | "exclude": [ 8 | "node_modules" 9 | ] 10 | } -------------------------------------------------------------------------------- /solution/ts/day11/img/libyear.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/advent-of-craft/2023/178dfa1e2fbd640c65fc903122b1fcda77d7fa9c/solution/ts/day11/img/libyear.png -------------------------------------------------------------------------------- /solution/ts/day11/jest.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | transform: {'^.+\\.ts?$': 'ts-jest'}, 3 | testEnvironment: 'node', 4 | testRegex: '/tests/.*\\.(test|spec)?\\.(ts|tsx)$', 5 | moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json', 'node'] 6 | }; -------------------------------------------------------------------------------- /solution/ts/day11/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "commonjs", 4 | "target": "es6", 5 | "sourceMap": true 6 | }, 7 | "exclude": [ 8 | "node_modules" 9 | ] 10 | } -------------------------------------------------------------------------------- /solution/ts/day12/jest.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | transform: {'^.+\\.ts?$': 'ts-jest'}, 3 | testEnvironment: 'node', 4 | testRegex: '/tests/.*\\.(test|spec)?\\.(ts|tsx)$', 5 | moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json', 'node'] 6 | }; -------------------------------------------------------------------------------- /solution/ts/day12/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "day-12-greeter", 3 | "version": "1.0.0", 4 | "description": "Day 12: Make your code open for extension.", 5 | "dependencies": { 6 | "typescript": "^5.3.3" 7 | }, 8 | "devDependencies": { 9 | "jest": "^29.7.0", 10 | "ts-jest": "^29.1.1", 11 | "@types/jest": "^29.5.8" 12 | }, 13 | "scripts": { 14 | "test": "jest" 15 | } 16 | } -------------------------------------------------------------------------------- /solution/ts/day12/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "commonjs", 4 | "target": "es6", 5 | "sourceMap": true 6 | }, 7 | "exclude": [ 8 | "node_modules" 9 | ] 10 | } -------------------------------------------------------------------------------- /solution/ts/day13/jest.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | transform: {'^.+\\.ts?$': 'ts-jest'}, 3 | testEnvironment: 'node', 4 | testRegex: '/tests/.*\\.(test|spec)?\\.(ts|tsx)$', 5 | moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json', 'node'] 6 | }; -------------------------------------------------------------------------------- /solution/ts/day13/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "day-13-blog", 3 | "version": "1.0.0", 4 | "description": "Day 13: Find a way to eliminate the irrelevant, and amplify the essentials of those tests.", 5 | "dependencies": { 6 | "typescript": "^5.3.3" 7 | }, 8 | "devDependencies": { 9 | "jest": "^29.7.0", 10 | "ts-jest": "^29.1.1", 11 | "@types/jest": "^29.5.8", 12 | "@faker-js/faker": "^8.3.1" 13 | }, 14 | "scripts": { 15 | "test": "jest" 16 | } 17 | } -------------------------------------------------------------------------------- /solution/ts/day13/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "commonjs", 4 | "target": "es6", 5 | "sourceMap": true 6 | }, 7 | "exclude": [ 8 | "node_modules" 9 | ] 10 | } -------------------------------------------------------------------------------- /solution/ts/day14/jest.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | transform: {'^.+\\.ts?$': 'ts-jest'}, 3 | testEnvironment: 'node', 4 | testRegex: '/tests/.*\\.(test|spec)?\\.(ts|tsx)$', 5 | moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json', 'node'] 6 | }; -------------------------------------------------------------------------------- /solution/ts/day14/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "day-14-fizzbuzz", 3 | "version": "1.0.0", 4 | "description": "Day 14: Do not use exceptions anymore.", 5 | "dependencies": { 6 | "typescript": "^5.3.3", 7 | "fp-ts": "^2.16.2" 8 | }, 9 | "devDependencies": { 10 | "jest": "^29.7.0", 11 | "ts-jest": "^29.1.1", 12 | "@types/jest": "^29.5.8" 13 | }, 14 | "scripts": { 15 | "test": "jest" 16 | } 17 | } -------------------------------------------------------------------------------- /solution/ts/day14/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "commonjs", 4 | "target": "es6", 5 | "sourceMap": true 6 | }, 7 | "exclude": [ 8 | "node_modules" 9 | ] 10 | } -------------------------------------------------------------------------------- /solution/ts/day15/jest.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | preset: "ts-jest", 3 | testEnvironment: "node", 4 | transform: {'^.+\\.ts?$': 'ts-jest'}, 5 | testRegex: '/tests/.*\\.(test|spec)?\\.(ts|tsx)$' 6 | }; -------------------------------------------------------------------------------- /solution/ts/day15/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "day-15-documents", 3 | "version": "1.0.0", 4 | "description": "Day 15: Put a code under tests.", 5 | "dependencies": { 6 | "typescript": "^5.3.3" 7 | }, 8 | "devDependencies": { 9 | "jest": "^29.7.0", 10 | "ts-jest": "^29.1.1", 11 | "@types/jest": "^29.5.8", 12 | "approvals": "^6.2.4" 13 | }, 14 | "scripts": { 15 | "test": "jest" 16 | } 17 | } -------------------------------------------------------------------------------- /solution/ts/day15/src/recordType.ts: -------------------------------------------------------------------------------- 1 | export enum RecordType { 2 | INDIVIDUAL_PROSPECT = "IndividualPersonProspect", 3 | LEGAL_PROSPECT = "LegalEntityProspect", 4 | ALL = "All", 5 | } -------------------------------------------------------------------------------- /solution/ts/day15/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "commonjs", 4 | "target": "es6", 5 | "sourceMap": true, 6 | "esModuleInterop": true 7 | }, 8 | "exclude": [ 9 | "node_modules" 10 | ] 11 | } -------------------------------------------------------------------------------- /solution/ts/day16/jest.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | transform: {'^.+\\.ts?$': 'ts-jest'}, 3 | testEnvironment: 'node', 4 | testRegex: '/tests/.*\\.(test|spec)?\\.(ts|tsx)$', 5 | moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json', 'node'] 6 | }; -------------------------------------------------------------------------------- /solution/ts/day16/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "day-16-blog", 3 | "version": "1.0.0", 4 | "description": "Day 16: Make this code immutable.", 5 | "dependencies": { 6 | "typescript": "^5.3.3" 7 | }, 8 | "devDependencies": { 9 | "jest": "^29.7.0", 10 | "ts-jest": "^29.1.1", 11 | "@types/jest": "^29.5.8", 12 | "@faker-js/faker": "^8.3.1" 13 | }, 14 | "scripts": { 15 | "test": "jest" 16 | } 17 | } -------------------------------------------------------------------------------- /solution/ts/day16/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "commonjs", 4 | "target": "es6", 5 | "sourceMap": true 6 | }, 7 | "exclude": [ 8 | "node_modules" 9 | ] 10 | } -------------------------------------------------------------------------------- /solution/ts/day17/jest.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | transform: {'^.+\\.ts?$': 'ts-jest'}, 3 | testEnvironment: 'node', 4 | testRegex: '/tests/.*\\.(test|spec)?\\.(ts|tsx)$', 5 | moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json', 'node'] 6 | }; -------------------------------------------------------------------------------- /solution/ts/day17/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "day-17-fizzbuzz", 3 | "version": "1.0.0", 4 | "description": "Day 17: Design one test that has the impact of thousands", 5 | "dependencies": { 6 | "typescript": "^5.3.3", 7 | "fp-ts": "^2.16.2" 8 | }, 9 | "devDependencies": { 10 | "jest": "^29.7.0", 11 | "ts-jest": "^29.1.1", 12 | "@types/jest": "^29.5.8", 13 | "fast-check": "^3.15.0" 14 | }, 15 | "scripts": { 16 | "test": "jest" 17 | } 18 | } -------------------------------------------------------------------------------- /solution/ts/day17/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "commonjs", 4 | "target": "es6", 5 | "sourceMap": true 6 | }, 7 | "exclude": [ 8 | "node_modules" 9 | ] 10 | } -------------------------------------------------------------------------------- /solution/ts/day18/jest.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | transform: {'^.+\\.ts?$': 'ts-jest'}, 3 | testEnvironment: 'node', 4 | testRegex: '/tests/.*\\.(test|spec)?\\.(ts|tsx)$', 5 | moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json', 'node'] 6 | }; -------------------------------------------------------------------------------- /solution/ts/day18/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "day-18-lap", 3 | "version": "1.0.0", 4 | "description": "Day 18: Automatically detect Linguistic Anti-Patterns (LAP).", 5 | "dependencies": { 6 | "typescript": "^5.3.3" 7 | }, 8 | "devDependencies": { 9 | "jest": "^29.7.0", 10 | "ts-jest": "^29.1.1", 11 | "@types/jest": "^29.5.8", 12 | "ts-arch-unit": "^0.3.0" 13 | }, 14 | "scripts": { 15 | "test": "jest" 16 | } 17 | } -------------------------------------------------------------------------------- /solution/ts/day18/src/shitty.ts: -------------------------------------------------------------------------------- 1 | export class ShittyClass { 2 | private static readonly consecutive__underscores__kill__readability: string = "detect me if you can 😬"; 3 | private static readonly _external_underscores_kill_it_too: string = "detect me if you can 🚀"; 4 | 5 | public getData(): void { 6 | } 7 | 8 | private isTrue(): number { 9 | return 42; 10 | } 11 | } -------------------------------------------------------------------------------- /solution/ts/day18/tests/teamRules.ts: -------------------------------------------------------------------------------- 1 | describe('TeamRules', () => { 2 | // no equivalent of archUnit exists right now for javascript and friends 3 | // ts-arch only enables architecture tests and not at the class / function level (what we needed for this challenge... 🥲) 4 | // https://github.com/ts-arch/ts-arch 5 | // https://github.com/robatwilliams/enforce-frontend-architecture 6 | }); 7 | -------------------------------------------------------------------------------- /solution/ts/day18/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "commonjs", 4 | "target": "es6", 5 | "sourceMap": true 6 | }, 7 | "exclude": [ 8 | "node_modules" 9 | ] 10 | } -------------------------------------------------------------------------------- /solution/ts/day19/jest.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | transform: {'^.+\\.ts?$': 'ts-jest'}, 3 | testEnvironment: 'node', 4 | testRegex: '/tests/.*\\.(test|spec)?\\.(ts|tsx)$', 5 | moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json', 'node'] 6 | }; -------------------------------------------------------------------------------- /solution/ts/day19/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "day-19-blog", 3 | "version": "1.0.0", 4 | "description": "Day 19: Loosing up dead weight.", 5 | "dependencies": { 6 | "typescript": "^5.3.3", 7 | "fp-ts": "^2.16.1" 8 | }, 9 | "devDependencies": { 10 | "jest": "^29.7.0", 11 | "ts-jest": "^29.1.1", 12 | "@types/jest": "^29.5.8", 13 | "@faker-js/faker": "^8.3.1" 14 | }, 15 | "scripts": { 16 | "test": "jest" 17 | } 18 | } -------------------------------------------------------------------------------- /solution/ts/day19/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "commonjs", 4 | "target": "es6", 5 | "sourceMap": true 6 | }, 7 | "exclude": [ 8 | "node_modules" 9 | ] 10 | } -------------------------------------------------------------------------------- /solution/ts/day20/jest.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | transform: {'^.+\\.ts?$': 'ts-jest'}, 3 | testEnvironment: 'node', 4 | testRegex: '/tests/.*\\.(test|spec)?\\.(ts|tsx)$', 5 | moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json', 'node'] 6 | }; -------------------------------------------------------------------------------- /solution/ts/day20/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "day-20-yahtzee", 3 | "version": "1.0.0", 4 | "description": "Day 20: No more exceptions in our domain.", 5 | "dependencies": { 6 | "typescript": "^5.3.3", 7 | "fp-ts": "^2.16.2" 8 | }, 9 | "devDependencies": { 10 | "jest": "^29.7.0", 11 | "ts-jest": "^29.1.1", 12 | "@types/jest": "^29.5.8" 13 | }, 14 | "scripts": { 15 | "test": "jest" 16 | } 17 | } -------------------------------------------------------------------------------- /solution/ts/day20/tests/diceBuilder.ts: -------------------------------------------------------------------------------- 1 | export class DiceBuilder { 2 | private readonly dice: number[]; 3 | 4 | constructor(dice: number[]) { 5 | this.dice = dice; 6 | } 7 | 8 | static newRoll = (dice1: number, dice2: number, dice3: number, dice4: number, dice5: number): DiceBuilder => 9 | new DiceBuilder([dice1, dice2, dice3, dice4, dice5]); 10 | 11 | build = (): number[] => this.dice; 12 | 13 | toString = () => this.dice.toString(); 14 | } -------------------------------------------------------------------------------- /solution/ts/day20/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "commonjs", 4 | "target": "es6", 5 | "sourceMap": true 6 | }, 7 | "exclude": [ 8 | "node_modules" 9 | ] 10 | } -------------------------------------------------------------------------------- /solution/ts/day21/jest.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | transform: {'^.+\\.ts?$': 'ts-jest'}, 3 | testEnvironment: 'node', 4 | testRegex: '/tests/.*\\.(test|spec)?\\.(ts|tsx)$', 5 | moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json', 'node'] 6 | }; -------------------------------------------------------------------------------- /solution/ts/day21/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "day-21-audit", 3 | "version": "1.0.0", 4 | "description": "Day 21: Refactor the tests and production code to Output-Based tests.", 5 | "dependencies": { 6 | "typescript": "^5.3.3" 7 | }, 8 | "devDependencies": { 9 | "jest": "^29.7.0", 10 | "ts-jest": "^29.1.1", 11 | "@types/jest": "^29.5.8" 12 | }, 13 | "scripts": { 14 | "test": "jest" 15 | } 16 | } -------------------------------------------------------------------------------- /solution/ts/day21/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "commonjs", 4 | "target": "es6", 5 | "sourceMap": true 6 | }, 7 | "exclude": [ 8 | "node_modules" 9 | ] 10 | } -------------------------------------------------------------------------------- /solution/ts/day22/jest.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | preset: "ts-jest", 3 | testEnvironment: "node", 4 | transform: {'^.+\\.ts?$': 'ts-jest'}, 5 | testRegex: '/tests/.*\\.(test|spec)?\\.(ts|tsx)$' 6 | }; -------------------------------------------------------------------------------- /solution/ts/day22/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "commonjs", 4 | "target": "es6", 5 | "sourceMap": true, 6 | "esModuleInterop": true 7 | }, 8 | "exclude": [ 9 | "node_modules" 10 | ] 11 | } -------------------------------------------------------------------------------- /solution/ts/day23/jest.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | transform: {'^.+\\.ts?$': 'ts-jest'}, 3 | testEnvironment: 'node', 4 | testRegex: '/tests/.*\\.(test|spec)?\\.(ts|tsx)$', 5 | moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json', 'node'] 6 | }; -------------------------------------------------------------------------------- /solution/ts/day23/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "day-23-trip-service", 3 | "version": "1.0.0", 4 | "description": "Day 23: Refactor the code after putting it under test.", 5 | "dependencies": { 6 | "typescript": "^5.3.3", 7 | "fp-ts": "^2.16.1" 8 | }, 9 | "devDependencies": { 10 | "jest": "^29.7.0", 11 | "ts-jest": "^29.1.1", 12 | "@types/jest": "^29.5.8" 13 | }, 14 | "scripts": { 15 | "test": "jest" 16 | } 17 | } -------------------------------------------------------------------------------- /solution/ts/day23/src/exception/CollaboratorCallException.ts: -------------------------------------------------------------------------------- 1 | export default class CollaboratorCallException extends Error {} 2 | -------------------------------------------------------------------------------- /solution/ts/day23/src/exception/UserNotLoggedInException.ts: -------------------------------------------------------------------------------- 1 | export default class UserNotLoggedInException extends Error {} 2 | -------------------------------------------------------------------------------- /solution/ts/day23/src/trip/Trip.ts: -------------------------------------------------------------------------------- 1 | export default class Trip {} 2 | -------------------------------------------------------------------------------- /solution/ts/day23/src/trip/TripDAO.ts: -------------------------------------------------------------------------------- 1 | import CollaboratorCallException from "../exception/CollaboratorCallException"; 2 | import Trip from "./Trip"; 3 | import {User} from "../user/User"; 4 | 5 | export default class TripDAO { 6 | public static findTripsByUser(user: User): Trip[] { 7 | throw new CollaboratorCallException( 8 | "TripDAO should not be invoked on an unit test."); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /solution/ts/day23/src/trip/TripRepository.ts: -------------------------------------------------------------------------------- 1 | import {User} from "../user/User"; 2 | import Trip from "./Trip"; 3 | import TripDAO from "./TripDAO"; 4 | 5 | export class TripRepository { 6 | findTripsByUser = (user: User): Trip[] => TripDAO.findTripsByUser(user); 7 | } -------------------------------------------------------------------------------- /solution/ts/day23/src/user/UserSession.ts: -------------------------------------------------------------------------------- 1 | import CollaboratorCallException from "../exception/CollaboratorCallException"; 2 | import User from "./User"; 3 | 4 | class UserSession { 5 | public getLoggedUser(): User { 6 | throw new CollaboratorCallException( 7 | "UserSession.getLoggedUser() should not be called in an unit test", 8 | ); 9 | } 10 | } 11 | 12 | export default new UserSession(); 13 | -------------------------------------------------------------------------------- /solution/ts/day23/tests/trip/triprepository.spec.ts: -------------------------------------------------------------------------------- 1 | import {TripRepository} from "../../src/trip/TripRepository"; 2 | import {UserBuilder} from "../user/userBuilder"; 3 | import CollaboratorCallException from "../../src/exception/CollaboratorCallException"; 4 | 5 | describe('trip repository', () => { 6 | test('retrieve user throw an exception', () => { 7 | expect(() => new TripRepository().findTripsByUser(UserBuilder.aUser().build())).toThrow(CollaboratorCallException); 8 | }); 9 | }); -------------------------------------------------------------------------------- /solution/ts/day23/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "commonjs", 4 | "target": "es6", 5 | "sourceMap": true 6 | }, 7 | "exclude": [ 8 | "node_modules" 9 | ] 10 | } -------------------------------------------------------------------------------- /solution/ts/day24/jest.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | transform: {'^.+\\.ts?$': 'ts-jest'}, 3 | testEnvironment: 'node', 4 | testRegex: '/tests/.*\\.(test|spec)?\\.(ts|tsx)$', 5 | moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json', 'node'] 6 | }; -------------------------------------------------------------------------------- /solution/ts/day24/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "day-24-dive", 3 | "version": "1.0.0", 4 | "description": "Day 24: Write the most complicated code you can.", 5 | "dependencies": { 6 | "typescript": "^5.3.3" 7 | }, 8 | "devDependencies": { 9 | "jest": "^29.7.0", 10 | "ts-jest": "^29.1.1", 11 | "@types/jest": "^29.5.8" 12 | }, 13 | "scripts": { 14 | "test": "jest" 15 | } 16 | } -------------------------------------------------------------------------------- /solution/ts/day24/tests/fileutils.ts: -------------------------------------------------------------------------------- 1 | import * as fs from 'fs'; 2 | import * as path from 'path'; 3 | 4 | const getInputAsString = (inputPath: string): string => { 5 | const fullPath = path.join(__dirname, inputPath); 6 | return fs.readFileSync(fullPath, 'utf8'); 7 | }; 8 | 9 | export const getInputAsSeparatedLines = (inputPath: string): string[] => 10 | getInputAsString(inputPath).split(/\r?\n/); -------------------------------------------------------------------------------- /solution/ts/day24/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "commonjs", 4 | "target": "es6", 5 | "sourceMap": true 6 | }, 7 | "exclude": [ 8 | "node_modules" 9 | ] 10 | } --------------------------------------------------------------------------------