Skip to content

Instantly share code, notes, and snippets.

@Vinai
Last active January 13, 2020 09:25
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save Vinai/f98ae4df76c4c3b0167f2ccc7bb7ef70 to your computer and use it in GitHub Desktop.
Save Vinai/f98ae4df76c4c3b0167f2ccc7bb7ef70 to your computer and use it in GitHub Desktop.
List of past code katas. The file names are the [year]-[week-of-year].md. I'll try to update the list each week.

The first kata is the classic BowlingGame Kata from Uncle Bob.

Write a class named Game that has two methods

  • roll(pins : int) is called each time the player rolls a ball. The argument is the number of pins knocked down.
  • score() : int is called only at the very end of the game. It returns the total score for that game.

Here is the original PowerPoint from Uncle Bob with the instructions including the solution steps. The PPT file also includes the rules for the scoring of a bowling game.

This weeks kata is the StringCalculator

The original post describing the kata is a bit inconsistent, but it still is good enough to go by: http://osherove.com/tdd-kata-1/

This week we do the Prime Factors Kata, another classic from Uncle Bob!

The requirement of the kata:

Write a class named PrimeFactors that has one static method: generate(int $n): array. The generate method takes an integer argument and returns an array of integers. That list contains the prime factors in numerical sequence.

The original step solutions in the PPT file linked below are in part specific to Java, with PHP those steps can be ignored (that is, we don't have typed arrays).

In case your math fundamentals have become a little rusty since high school, here a little video refresher explaining prime numbers and prime factorization: http://study.com/academy/lesson/what-is-prime-factorization-definition-examples.html

And here is the original PPT from Uncle Bob himself: http://butunclebob.com/files/downloads/Prime%20Factors%20Kata.ppt

Kata of the week: the WordWrap Kata

The requirements:

You write a class called Wrapper, that has a single static function named wrap() that takes two arguments, a string, and a column number.
The function returns the string, but with line breaks inserted at just the right places to make sure that no line is longer than the column number. You try to break lines at word boundaries.

The special challenge of the kata is to find good small chunks to tests, so the algorithm can be built iteratively. If you end up with a test that forces you to implement the whole algorithm to make it pass a few times go and read the post linked below.

This is another classic from Uncle Bob. Here is the blogpost in which he published it back in 2002: http://thecleancoder.blogspot.de/2010/10/craftsman-62-dark-path.html

This blog post also contains a solution if you end up getting stuck.

Our kata of the week is karate chop:
http://codekata.com/kata/kata02-karate-chop/

Implement a binary search in a sorted list of integers.

The linked kata suggests trying to come up with a different approach each day and make some notes.
I will try to do that (already did the first two in advance as you can see above), but if you are just starting with the katas, I'd recommend to not force it.
Repeating the same for each day, maybe with slight improvements, is great for practice too.

The kata of the week for 16.-20. Jan. 2017: RomanNumerals!  

The task is to derive an algorithm using TDD that converts an arabic numeral, for example 1073,
into the matching roman numeral, MLXXIII.
For the kata there is no need to be able to convert numbers larger than about 3000.

In case you aren't familiar with it, here is the character to number mapping the romans used:
1 --> I, 5 --> V, 10 --> X, 50 --> L, 100 --> C, 500 --> D, 1000 --> M

And here is a description of how the roman numerals are built with those characters (e.g. 4 --> IV):
http://www.novaroma.org/via_romana/numbers.html

Finally, a link to a longer description of the kata with links to videos and even some hints or tasks if this kata is too basic:
http://codingdojo.org/cgi-bin/index.pl?KataRomanNumerals

Kata of the week 23.-29. Jan. 2017: the CoinChanger Kata!

This kata can be relatively quick and simple and nevertheless provides a good opportunity to practice TDD and there are quite a number of ways the resulting algorithm can be done.

Write a program that will correctly determine the least number of coins to be given to the user such that the sum of the coins' value would equal the correct amount of change.

Input: change amount
Input: coin denomination array (ie [1, 5, 10, 25, 100])
Output: number of coins array (ie [1, 0, 1, 0, 0] would represent $0.11

For example
An input of 15 with [1, 5, 10, 25, 100] should return fifteen cents or [0, 1, 1, 0, 0]
An input of 40 with [1, 5, 10, 25, 100] should return two dimes or [0, 1, 1, 1, 0]
If you prefer to return a hash instead of am array, that's ok too. {1 => 1, 5 => 0, 10 => 1, 25 => 0, 100 => 0} equals $0.11

Use Test Driven Development (TDD) to solve this problem. Start writing tests, write enough code to get the tests to pass, and then refactor your code. Allow your design to emerge from writing tests; don't try to solve the problem first.

The original source of the kata by Todd Sedano no longer is online, but it still can be found on the web archive: https://web.archive.org/web/20130216063932/http://craftsmanship.sv.cmu.edu/exercises/coin-change-kata

Kata of the week of 06.-10. February 2017: Functions Pipeline

The task: build a function pipe() that takes any number of callables as arguments and returns a new callable.
The returned callable passes any arguments to the first callable, then the result of that to the next callable, and so on, and will return the final result.
So the processing order is left to right.

Example:

// first apply strtolower(), then apply ucwords second.
$f = pipe('strtolower', 'ucwords');
$f('FOO BAR') === ucwords(strtolower('FOO BAR'));

Optional follow up exercise:
implement a function compose(), which behaves just like pipe() except that the processing order is right to left. Implement it differently from pipe() (e.g. without reversing the input array) and without calling pipe().

Note: In PHP the callables could be function name strings (e.g. "strtolower"), object callables (e.g. [$instance, "doFoo"]), objects that implement ___invoke(), or \Closure instances (so anything that sattisfied the callabletype hint.  In JavaScript they would be function references of anonymous functions.
In other languages just choose the appropriate things :)

Kata of the week: Print Diamond! (13.-17. February 2017)

One of my favorites 🙂 Here is the original task description:

Given a letter print a diamond starting with 'A' with the supplied letter at the widest point.

For example: print-diamond 'E' prints

    A    
   B B   
  C   C
 D     D
E       E
 D     D
  C   C
   B B
    A

For example, print-diamond 'C' prints

  A
 B B
C   C
 B B
  A

The challenge of the kata is to take small steps and split the task into smaller sub tasks, so be weary of writing a test early on that requires a full implementation of the algorithm to make the test pass.

The original description of the kata can be found here: http://claysnow.co.uk/diamond-recycling-and-painting-yourself-into-a-corner/

Kata of the week: Anagrams
(20.-24. February 2017)

Given a file containing one word per line, print out all the combinations of words that are anagrams; each line in the output contains all the words from the input that are anagrams of each other. For example, your program might include in its output:

kinship pinkish
enlist inlets listen silent
boaster boaters borates
fresher refresh
sinks skins
knits stink
rots sort

If you run this on the word list here (http://codekata.com/data/wordlist.txt) you should find 20683 sets of anagrams (a total of 48162 words), including all-time favorites such as

crepitus cuprites pictures piecrust
paste pates peats septa spate tapes tepas
punctilio unpolitic
sunders undress

For added programming pleasure, find the longest words that are anagrams, and find the set of anagrams containing the most words (so “parsley players replays sparely” would not win, having only four words in the set).

Source and full description: http://codekata.com/kata/kata06-anagrams/


if working with files in tests turns out difficult for whatever reason, feel free to use other forms of input/output. Bonus points if you still manage to optimize for big word lists after making it just work

Kata of the week: Reversed Binary Numbers
(27. Feb - 3. Mar)

Your task will be to write a program for reversing numbers in binary. For instance, the binary representation of 13 is 1101, and reversing it gives 1011, which corresponds to number 11.

Input: The input contains a single line with an integer N, 1 ≤ N ≤ 1000000000.

Output: Output one line with one integer, the number we get by reversing the binary representation of N.

Eamples:
Sample input 1
13
Sample output 1
11
Sample input 2
47
Sample output 2
61

This kata is the third puzzle from https://labs.spotify.com/puzzles/

Kata of 2 weeks: Binary Search Tree
(6.-10. and 13.-17.Mar 2017)

Write a program that inserts numbers and searches in a binary tree.

A binary search tree consists of a series of connected nodes. Each node contains a piece of data (e.g. the number 3), a pointer (variable) named left, and a pointer named right. Left and right point at nil, or other nodes. Since these other nodes in turn have other nodes beneath them, we say that the left and right properties are pointing at subtrees. All data in the left subtree is less than or equal to the current node's data, and all data in the right subtree is greater than the current node's data.

Here is a nice description with a bit more detail. The repository also contains a PHP implementation (can't say how it is, I didn't look at it - yet).
https://github.com/rojoangel/12moths-12katas/blob/master/5-binary-search-tree-kata-php/README.md

This week it's a legacy kata: Ugly Trivia
(20.-24. Mar 2017)

The purpose of a legacy code kata is to practice adding test coverage to previously untested code and to clean up the code without breaking it.
This kata in perticular should be tacked with a golden master test (a.k.a. characterization test or scaffolding test).
The legacy code can be found at https://github.com/jbrains/trivia
The original description of the kata can be found at http://kata-log.rocks/ugly-trivia-kata

This week's kata: Boolean Logic Evaluator
(27.-31. Mar 2017)

The objective of this kata is to create a lexer / parser that will accept boolean logic statements as a string, evaluate them and return the boolean result of the expression.
The requirements for the parser are to accept the value tokens 1 (for true) and 0 (for false), deal with the logical tokens &, | and ! (representing the logical operations AND, OR and NOT respectively) and to support logical grouping using the tokens ( and ).

Examples:
Input: (1)
Output: true

Input: 0
Output: false

Input: (0&1)|1
Output: true

Stretch Goal:
Add support for variables in the logic statement, allowing you to pass the class variable names representing a boolean state that it will lookup as part of the expression evaluation. e.g. parse('foo&1', array('foo' => 0)) == false.

Credit: this kata was invented by Peter O'Callaghan - thank you!

This week's kata: Exclamation Marks
(03.-08. Apr 2017)

This is a kata taken from the Code Wars website:

Description:

Each exclamation mark weight is 2; Each question mark weight is 3. Put two string left and right to the balance, Are they balanced?

If the left side is more heavy, return "Left"; If the right side is more heavy, return "Right"; If they are balanced, return "Balance".

Examples

balance("!!","??") === "Right"
balance("!??","?!!") === "Left"
balance("!?!!","?!?") === "Left"
balance("!!???!????","??!!?!!!!!!!") === "Balance"

This week's kata: Bank Accounts
(13.-19. Jan 2019)

This is a kata that got recommended to me by a friend. Not sure if there is a written description available of it somewhere else on the internet, but this is what I heard:

Description:

The goal is to model a simple banking system with several bank accounts with TDD. Supported Operations:

  • Deposit
  • Withdrawal
  • Transfer from one account to another
  • Report all operations for given account

Sounds simple enough, let's give it a try!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment