Skip to content

Instantly share code, notes, and snippets.

@angusbarnes
Last active July 25, 2018 07:50
Show Gist options
  • Save angusbarnes/2edc7942fdd931d097ca2a93d01b76ae to your computer and use it in GitHub Desktop.
Save angusbarnes/2edc7942fdd931d097ca2a93d01b76ae to your computer and use it in GitHub Desktop.

Clean code challenge #1: FizzBuzz


FiizBuzz is a simple game often used to challenge new coders skills and thinking ability. The rules are easy:

  1. Your program should print all the numbers from 1-100
  2. Any number which is a multiple of three should be printed as "Fizz" instead of the number
  3. Any number which is a multiple of five should be printed as "Buzz" instead of the number
  4. Any number which is a multiple of both three and five should be printed as "FizzBuzz"

HINT: To get the remainder of a divison use the modulo operator (%).

int remainder = 21%5;
//remainder would be equal to 1 as 21/5 gives a remainder of one
See the solution

There a number of different way to solve this so lets brake each one down. The most common way for new programmers probably resemble something like the following:

for(int i = 0; i <=100, i++){
      if(i%15 == 0) {
          print("FizzBuzz");
      } else if(i%3 == 0){
          print("Fizz");
      } else if (i%5 == 0) {
          print("Buzz");
      } else {
          print(i.ToString());
      }
}

Now this works, however I do not believe it to be the clearest to read. Try:

for(int n = 0; n <= 100; n++) {
      string result = "";
      
      if (n%3 == 0) { 
          result += "Fizz";
      }
      if (n%5 == 0) {
          result += "Buzz";
      }
      if (result == ""){
          result = n.ToString();
      }
      
      print(result);
}

Whilst it is technically possible to all the testing on one line, it is rarely advised:

for(int i = 0; i <= 100; i++) {
    print(i%15 ? "FizzBuzz" : i%3 ? "Fizz" : i%5 ? "Buzz" : i.ToString());
}

For further clarity, we could write all of our testing logic in a method and call that from our for loop. This will simplify the reading of our code dramatically.

// Inside our 'Main' or 'Start' method
for(int n = 0; n <= 100; n++) {
      print(FizzBuzz(n));
}


// Somewhere in our code base
public static string FizzBuzz(int n) {
      string result = "";
      
      if (n%3 == 0) { 
          result += "Fizz";
      }
      if (n%5 == 0) {
          result += "Buzz";
      }
      if (result == ""){
          result = n.ToString();
      }
      
      print(result);
}

Clean code challenge #2: The sum of all squares


We have already established a few key concepts of clean coding but there are many more out there. One that I like to talk about is the DRY rule. DRY stands for 'Don't repeat yourself' which is the opposite to WET which means 'Write everything twice'. Both of these rules are fairly self explanatory however it is not always obvious how to implement them best.

The problem:

You have been tasked to create a class wich contains functions for arithmetic with lists. You should include a function for adding all the elements in a list, multiplying all the elements in the list and dividing all the elements list. While completing this challenge consider the DRY principal. Your method signitures should look like the following:

public static int Sum(List<int> numbers) {...};
public static int Product(List<int> numbers) {...};
public static int Quotient(List<int> numbers) {...};

NOTE: All the functions take in list of ints and return a single int. This is how your functions should work.

Only for the brave

Write a function that finds the sum of all squares of a list of ints.


See the solution to this challenge
There are three main methods for doing this challenge. The fisrt way is by using a `for` loop, which is proabably the most common way new programmers would go about doing this.
 public static int Sum(List<int> numbers) {
     int result = 0;
     for(i = 0; i < numbers.Count; i++) {
          result+= numbers[i];                 
     }
     return result;
 }
                                  
 public static int Product(List<int> numbers) {
     int result = 1;
     for(i = 0; i < numbers.Count; i++) {
          result*= numbers[i];                 
     }
     return result;
 }
 //ETC

Now there is nothing particularly wrong with this implementation however it does go against out clean coding pricipal of DRY. You'll not that every function effectively does the exact same thing except we have to change the operator. Often when we see repeated code it is considered standard practice to put that code in a function so that we can reuse it when neccessary. But how can we do this? You may be trying to work out a way in which wwe could take the operator as an arguement like so DoOperation(List<int> numbers, operator op) but unfortunately C# does not have support for this (Java, on the other hand, does). So how can we do this. By using Func's and Lambdas of course.

Func's are a way for us to store functions like a variables and lambdas are a way for us to write inline functions. Combining their powers together we can get something like the following:

public static int Reduce(List<int> numbers, int init, Func<int, int, int> function) {
    int result = init
    for(i = 0; i < numbers.Count; i++) {
        result = function(result, numbers[i]);
    }
}
// This method can now be called like the following:
public static int Sum(List<int> numbers) {
    return Reduce(numbers, 0, (x, y)  => x + y);
}

public static int Product(List<int> numbers) {
    return Reduce(numbers, 1, (x, y)  => x * y);
}

public static int Quotient(List<int> numbers) {
    return Reduce(numbers, 0, (x, y)  => x + y);
}

Now this is already a very good implementation as it avoids repeating code however we could probably do one better. Using extension methods and generic IEnumerables we are able to create a function that can work not only for our maths task's but for any binary list reduction task.

public static TSource Reduce(this IEnumerable<TSource> source, Func<TSource, TSource, TSource> expression) {
       using(IEnumerator<TSource> iterator = listObject.GetEnumerator())
       {
               TSource current = iterator.Current;
               while (iterator.MoveNext())
               {
                   current = expr(current, iterator.Current);
               }
               return current;
       }
}

This can now be called on any Enumerable object such as a List, array or async object.

List<int> numbers = new List<int>() {1, 2, 3, 4, 5};
int sum = numbers.Reduce((x, y) => x + y);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment