Skip to content

Instantly share code, notes, and snippets.

@dlresende
Last active March 20, 2021 19:51
Show Gist options
  • Save dlresende/60b4c0240ad020a323ad to your computer and use it in GitHub Desktop.
Save dlresende/60b4c0240ad020a323ad to your computer and use it in GitHub Desktop.
FooBarQix Kata

FooBarQix Kata

Write a program that prints numbers from 1 to 100, one number per line. For each printed number, use the following rules:

  1. if the number is divisible by 3 or contains 3, replace 3 by "Foo";
  2. if the number is divisible by 5 or contains 5, replace 5 by "Bar";
  3. if the number is devisible by 7 or contains 7, replace 7 by "Qix".

Example: 1 2 FooFoo 4 BarBar Foo QixQix 8 Foo Bar

More details:

  • divisors have high precedence, ex: 51 -> FooBar
  • the content is analysed in the order they appear, ex: 53 -> BarFoo
  • 13 contains 3 so we print "Foo"
  • 15 is divisible by 3 and 5 and contains 5, so we print “FooBarBar”
  • 33 contains 3 two times and is divisible by 3, so we print “FooFooFoo”
@kannanperoumal
Copy link

kannanperoumal commented Jun 8, 2016

package com.test;
import java.io.PrintStream;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;

/**

  • Kannan Peroumal

  • simple program for test with jdk 1.7
    */
    public class Test {
    private int startPos = 1;
    private int endPos = 100;
    private static final Map<Integer, String> DIVIDER = new HashMap<>();{
    DIVIDER.put(3, "Foo");
    DIVIDER.put(5, "Bar");
    DIVIDER.put(7, "Qix");
    }
    private static final Map<String, Integer> DIVIDER_GROUP_RESULT = new HashMap<>();

    Test(){
    try{

        PrintStream out = System.out;
        out.println("********** START **********");
        out.println();
        while(startPos<=endPos){
            out.println(startPos +" "+ extractWords(startPos));
            startPos++;
        }
        out.println("\n\nGroup result:\n-------------");
        for (Entry<String, Integer> entry : DIVIDER_GROUP_RESULT.entrySet()) {  
            out.println("\""+entry.getKey() + "\" = "+ entry.getValue());
        }
        out.println("********** END **********");
    }
    catch(Exception e){
        System.err.println("Error occured:"+ e);
    }finally{}
    

    }
    private String extractWords(int startPos) throws Exception {
    //StringBuilder result = new StringBuilder();
    String r = "";
    for (Entry<Integer, String> divider : DIVIDER.entrySet()) {
    // checks dividable
    if(startPos % divider.getKey() == 0){
    r += divider.getValue();
    }
    }
    if(startPos > 9){
    // checks double digits
    r += DIVIDER.containsKey(startPos / 10)? DIVIDER.get(startPos / 10) : "";
    startPos = startPos % 10;
    }
    // checks the single digit

    r += DIVIDER.containsKey(startPos)? DIVIDER.get(startPos) : "";
    DIVIDER_GROUP_RESULT.put(r, DIVIDER_GROUP_RESULT.get(r)==null? 1 : DIVIDER_GROUP_RESULT.get(r)+1);
    return r;
    

    }
    public static void main(String[] args) {
    new Test();
    }

}

@kannanperoumal
Copy link

This tool doen't take all my codes on save. It formats and remove some codes automatically, example the original code is
for (Entry<Integer, String> divider : DIVIDER.entrySet()) {
but it added as
for (Entry divider : DIVIDER.entrySet()) {

@kannanperoumal
Copy link

for (Entry<Integer, String> divider : DIVIDER.entrySet()) {

@kannanperoumal
Copy link

Entry<Integer, String>

@sebpiller
Copy link

sebpiller commented Nov 22, 2016

Your implementation seems working, but if you're asked to produce it in an interview I would suggest ...

  • use StringBuilders (at correct places). Interviewers always love to see you know this basics.
  • you are instantiating your map from a static context, and populate it from an anonymous, non-static, block. If it were a list, you would have duplicates inside as soon as you instantiate your object two times. The map saves you here (no key duplicates), but that's only by chance...
  • you have an hidden bug. What happens with the number 100, which is 3 digits long?
  • be more generic. What happens if I change the rule to require processing of numbers up to 1000? hint: your method extractWords would become quite ugly...
  • HashMap is not a good choice. Iteration is not guaranteed to be consistent. Use a LinkedHashMap instead.
  • your class is not thread safe. It not a problem on its own, but should be documented.
  • declaring "throws Exception" in a signature is almost always a bad practice. And here, it is not even needed.
  • you have some magic numbers which you could either 1) remove (good) or 2) extract as constants
  • empty finally blocks are a code mess and should be deleted.
  • don't do everything from the constructor. Often, in real world, constructors should process fast (initialize). Then, a method could be invoked to do some job.

FYI, you may find a better implem here: https://github.com/sebpiller/FooBarQix

@varnit02
Copy link

package com.LinkedList;

import java.util.Arrays;

public class test1 {
public static void main(String[] args) {
foo_bar_qix(303);
}

private static void foo_bar_qix(int num) {

	String result_string = "";

	Boolean flag = false;
	if (num < 3) {
		System.out.println(num);
		return;
	}

	if (num % 3 == 0) {
		result_string += "Foo";
		flag = true;
	}

	if (num % 5 == 0) {
		result_string += "Bar";
		flag = true;
	}

	if (num % 7 == 0) {
		result_string += "Qix";
		flag = true;
	}

	if (num < 9) {
		if (!flag) {
			System.out.println(num);
			return;
		}

		if (num == 3) {
			result_string += "Foo";
		}

		if (num == 5) {
			result_string += "Bar";
		}

		if (num == 7) {
			result_string += "Qix";
		}
	}

	if (num > 9) {

		int[] digits_array = extractDigits(num);
		System.out.println(Arrays.toString(digits_array));
		for (int i = 0; i < digits_array.length; i++) {
			if (digits_array[i] == 3) {
				result_string += "Foo";
			} else if (digits_array[i] == 5) {
				result_string += "Bar";
			} else if (digits_array[i] == 7) {
				result_string += "Qix";
			} 

		}
	}
	System.out.println(result_string);
}

private static int[] extractDigits(int num) {
	int length = Integer.toString(num).length();
	int[] digit_array = new int[length];
	int i = 0;
	while (num >= 1) {
		digit_array[digit_array.length - i - 1] = num % 10;
		num = num / 10;
		i++;
	}
	return digit_array;
}

}

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