This is the multi-page printable view of this section. Click here to print.

Return to the regular view of this page.

Code War

1 - FindPrime

Define a function that takes an integer argument and returns a logical value true or false depending on if the integer is a prime. Per Wikipedia, a prime number ( or a prime ) is a natural number greater than 1 that has no positive divisors other than 1 and itself.

DO NOT TRY to acquire fancy optimizations first

public static boolean isPrime(int num) {  
    // single exception  
    if (num == 2 || num == 5) {  
        return true;  
    } else if (num < 2) {  
        return false;  
    }    // last digit exception  
    switch (num % 10) {  
        case 0:  
        case 2:  
        case 4:  
        case 5:  
        case 6:  
        case 8:  
            return false;  
    }    // else  
    for (int i = 3; i <= Math.sqrt(num); i += 2) {  
        if (num % i == 0) {  
            return false;  
        }    }    return true;  
}

2 - GetMiddle

You are going to be given a non-empty string. Your job is to return the middle character(s) of the string. If the string’s length is odd, return the middle character. If the string’s length is even, return the middle 2 characters.

Two main key-concepts

  1. length is odd get middle number of string
  2. length is even get middle 2 character
public static String getMiddle(String word) {  
    //Code goes here!  
    int length = word.length();  
    if(length == 0) return null;  
    return length%2 != 0 ? String.valueOf(word.charAt(length/2)) : word.substring(length/2-1,length/2+1);  
}

Most part is return substring 2 characters. This method has complexity O(n)

We can improve to O(1), BY replacing substring to charAt

public static String getMiddle(String word) {  
    //Code goes here!  
    int length = word.length();  
    if(length == 0) return null;  
    return length%2 != 0 ? String.valueOf(word.charAt(length/2)) : word.charAt(length/2-1) + "" + word.charAt(length/2);  
}

3 - IsNarcissistic

A Narcissistic Number (or Armstrong Number) is a positive number which is the sum of its own digits, each raised to the power of the number of digits in a given base. In this Kata, we will restrict ourselves to decimal (base 10).

Narcissistic Number (or Armstrong Number) is a positive number which is the sum of its own digits, each raised to the power of the number of digits in a given base. In this Kata, we will restrict ourselves to decimal (base 10).

For example, take 153 (3 digits), which is narcissistic:

    1^3 + 5^3 + 3^3 = 1 + 125 + 27 = 153

and 1652 (4 digits), which isn’t:

    1^4 + 6^4 + 5^4 + 2^4 = 1 + 1296 + 625 + 16 = 1938

The Challenge:

Your code must return true or false (not ’true’ and ‘false’) depending upon whether the given number is a Narcissistic number in base 10.

This may be True and False in your language, e.g. PHP.

Error checking for text strings or other invalid inputs is not required, only valid positive non-zero integers will be passed into the function

image.png

We just use MATH.POW for start

    public static boolean isNarcissistic(int number) {  
        if(number < 0){  
            return false;  
        }        int temp = number;  
        int sum = 0;  
        int count = String.valueOf(temp).length();  
        while(temp != 0) {  
            sum += Math.pow(temp % 10, count);  
            temp = temp / 10;  
        }        boolean isNarcissistic = sum == number;  
        return isNarcissistic;  
    }}

Actually ,There are only few narcissistic numbers in the signed 32-bit with switch case, is easy to flow through all cases

public static boolean isNarcissistic(int number) {  
    switch (number) {  
        case 0:  
        case 1:  
        case 2:  
        case 3:  
        case 4:  
        case 5:  
        case 6:  
        case 7:  
        case 8:  
        case 9:  
        case 153:  
        case 370:  
        case 371:  
        case 407:  
        case 1_634:  
        case 8_208:  
        case 9_474:  
        case 54_748:  
        case 92_727:  
        case 93_084:  
        case 548_834:  
        case 1_741_725:  
        case 4_210_818:  
        case 9_800_817:  
        case 9_926_315:  
        case 24_678_050:  
        case 24_678_051:  
        case 88_593_477:  
        case 146_511_208:  
        case 472_335_975:  
        case 534_494_836:  
        case 912_985_153:  
            return true;  
        default:  
            return false;  
    }}

4 - NumberFun

You might know some pretty large perfect squares. But what about the NEXT one?

You might know some pretty large perfect squares. But what about the NEXT one?

Complete the findNextSquare method that finds the next integral perfect square after the one passed as a parameter. Recall that an integral perfect square is an integer n such that sqrt(n) is also an integer.

If the argument is itself not a perfect square then return either -1 or an empty value like None or null, depending on your language. You may assume the argument is non-negative.

https://www.codewars.com/kata/56269eb78ad2e4ced1000013

To be honest, there is no better way to utilize hardware instructions than by designing an algorithm yourself.

However, we can use an existing algorithm here.

image.png

public static long findNextSquare(long sq) {  
  
    // perfect number should end with 0, 9, 5, 4, 1  
    int back = (int)(sq % 10);  
    // indicate input is perfect square or not  
    if(back != 0 && back != 9 && back != 5 && back != 4 && back != 1 && back != 6){  
        return -1L;  
    }  
    // maybe a perfect number  
    else{  
  
        // find square root  
        // use repeated substraction        
        int factor = 1, i = 0;  
        while(sq > 0){  
            sq -= factor;  
            i++;  
            factor += 2;  
        }        
        long sqrt = i+1;  
        if(sq == 0) return sqrt*sqrt;  
        else return -1L;  
    }
}

Test cases

@Test  
public void test1() {  
    assertEquals(144, NumberFun.findNextSquare(121));  
}  
  
  
@Test  
public void test2() {  
    assertEquals(-1, NumberFun.findNextSquare(155));  
}  
  
@Test  
public void test3() {  
    assertEquals(320356, NumberFun.findNextSquare(319225));  
}  
  
@Test  
public void test4() {  
    assertEquals(15241630849L, NumberFun.findNextSquare(15241383936L));  
}  
  
@Test  
public void test5() {  
    assertEquals(-1, NumberFun.findNextSquare(342786627));  
}  
  
  
@Test  
public void randomTest1() {  
    long input = (long)(Math.random()*100000L)+1;  
    long square = input*input;  
  
    assertEquals(square+(input*2+1), NumberFun.findNextSquare(square));  
}

The key part is type conversion—we need to convert int to long. Be careful, as the result of our calculation may exceed the range of int.

For example:

return (long) * (long);

is different from

return (long)(int * int);

The latter may cause a loss of accuracy.

5 - Palindrome

ATM machines allow 4 or 6 digit PIN codes and PIN codes cannot contain anything but exactly 4 digits or exactly 6 digits.

String.Match()

ATM machines allow 4 or 6 digit PIN codes and PIN codes cannot contain anything but exactly 4 digits or exactly 6 digits.

If the function is passed a valid PIN string, return true, else return false.

two important cases

  • no letters
  • length limited

key: how to limit string in certain format

  1. ASII code to range numbers, use String.length to limit digits length

==be aware of ture and false== we can simply coding

 // 1416ms  
    public static boolean validatePin(String pin) {  
        // Your code here...  
        int l = pin.length();  
//        boolean o = (l == 4) || (l == 6) ? true : false;  
              // boolean o = (l==4) || (l==6);  
//        for reach can't apply to string  
        for(char c : pin.toCharArray()) {  
            if(c<48 || c>57){  
                o = false;  
            }        }        return o;  
    }
  1. use built-in regex Patterns String.match()
 public static boolean validatePin(String pin) {
    return pin.matches("\\d{4}|\\d{6}");
  }

\d means 0-9, but java can not use \d so replace with \\d match 4 or 6 digits use \\d{4} but remember no space before or after like \\d{4} or \\d{4}

  1. pre-compile to improve performance

we need compile patterns every time which is time-consuming with pre-compile we can save performance

static Pattern pattern = Pattern.compile("\\d{4}|\\d{6}");

public static boolean validatePin(String pin) {  
    // pre compile improve performance  
    return pattern.matcher(pin).matches();  
}

test-case

@Test  
public void validPins() {  
    assertEquals(true, Solution.validatePin("1234"));  
    assertEquals(true, Solution.validatePin("0000"));  
    assertEquals(true, Solution.validatePin("1111"));  
    assertEquals(true, Solution.validatePin("123456"));  
    assertEquals(true, Solution.validatePin("098765"));  
    assertEquals(true, Solution.validatePin("000000"));  
    assertEquals(true, Solution.validatePin("090909"));  
}  
  
@Test  
public void nonDigitCharacters() {  
    assertEquals(false, Solution.validatePin(" a234"));  
    assertEquals(false, Solution.validatePin(".234"));  
    assertEquals(false, Solution.validatePin("utp4564utp"));  
    assertEquals(false, Solution.validatePin("newline"));  
}  
  
@Test  
public void invalidLengths() {  
    assertEquals(false, Solution.validatePin("1"));  
    assertEquals(false, Solution.validatePin("12"));  
    assertEquals(false, Solution.validatePin("123"));  
    assertEquals(false, Solution.validatePin("12345"));  
    assertEquals(false, Solution.validatePin("1234567"));  
    assertEquals(false, Solution.validatePin(" 1234"));  
    assertEquals(false, Solution.validatePin(" 1234 "));  
    assertEquals(false, Solution.validatePin("1234 "));  
    assertEquals(false, Solution.validatePin("1.234"));  
    assertEquals(false, Solution.validatePin("00000000"));  
    assertEquals(false, Solution.validatePin("00000"));  
    assertEquals(false, Solution.validatePin("00000a"));  
}

6 - PangramChecker

A pangram is a sentence that contains every single letter of the alphabet at least once. For example, the sentence “The quick brown fox jumps over the lazy dog” is a pangram, because it uses the letters A-Z at least once (case is irrelevant).Given a string, detect whether or not it is a pangram. Return True if it is, False if not. Ignore numbers and punctuation

String.chars() Stream.map() Stream.distinct() Character.isAlphabetic()

Pre-pocess String. Use HashSet remove redundent numbers and non-alpha

public static boolean check(String sentence){  
    // sort chars in sentences  
    char[] charArray = sentence.toLowerCase().trim().toCharArray();  
    Arrays.sort(charArray);  
    HashSet<Character> set = new HashSet<>();  
    for (int i = 0; i < charArray.length; i++) {  
        if(set.contains(charArray[i])){  
            continue;  
        }else if(charArray[i] >= 97 && charArray[i] <= 122){  
            set.add(charArray[i]);  
        }    }    System.out.println(set);  
    return set.size() == 26;  
}

That’s not beautiful enough, for removing we can use distinct() and filter()

public static boolean check(String sentence) {
return sentence.chars().map(Character::toLowerCase).filter(Character::isAlphabetic).distinct().count() == 26;  
}

But we can also check if sentence contain all A-Z, with a special for loop

public static boolean check(String sentence) {  
    sentence = sentence.toLowerCase().trim();  
    for (char c = 'a'; c < 'z'; c++) {  
        if (!sentence.contains("" + c)) {  
            return false;  
        }    }    return true;  
}

Two solution have same complexity O(n), both are great.

7 - PhoneNumber

Write a function that accepts an array of 10 integers (between 0 and 9), that returns a string of those numbers in the form of a phone number.

String.format()

First try, Prefixed numbers is fixed

we can simply cut out

public static String createPhoneNumber(int[] numbers) {  
    // Your code here!  
    String country = numbers[0] + "" + numbers[1] + "" + numbers[2];  
    String area = numbers[3] + "" + numbers[4] + "" + numbers[5];  
    String pop = "";  
    for (int i = 6; i <= numbers.length - 1; i++) {  
        pop = pop + numbers[i] + "";  
    }    return "(" + country + ")" + " " + area + "-" + pop;  
}

76ms

But There has an more elegant way to do so.

Use String.format()

public static String createPhoneNumber(int[] numbers){  
    return String.format("(%d%d%d) %d%d%d-%d%d%d%d",numbers[0],numbers[1],numbers[2],numbers[3],numbers[4],numbers[5],numbers[6],numbers[7],numbers[8],numbers[9] );  
}

But this method have to compile formatter, which caused extra time.

Over all, we can use StringBuffer to put Strings together.

public static String createPhoneNumber(int[] numbers) {  
    // Your code here!  
   return new StringBuilder()  
           .append("(")  
           .append(numbers[0])  
           .append(numbers[1])  
           .append(numbers[2])  
           .append(") ")  
           .append(numbers[3])  
           .append(numbers[4])  
           .append(numbers[5])  
           .append("-")  
           .append(numbers[6])  
           .append(numbers[7])  
           .append(numbers[8])  
           .append(numbers[9])  
           .toString();  
}

76ms

Actually, It did not saving time, but use less space.

So recommend third method.

8 - SpinWords

Write a function that takes in a string of one or more words, and returns the same string, but with all words that have five or more letters reversed (Just like the name of this Kata). Strings passed in will consist of only letters and spaces. Spaces will be included only when more than one word is present.

StringBuilder.reverse() String.join()

Test Sample is complex, we can process to beauty input

first try

public static String spinWords(String sentence) {  
    //TODO: Code stuff here  
    StringBuilder result = new StringBuilder();  
    StringBuilder word = new StringBuilder();  
    int count = 0;  
    for (int i = 0; i < sentence.length(); i++) {  
        char ch = sentence.charAt(i);  
        if (ch == ' ') {  
            if(count >= 5) {  
                result.append(reverse(word));  
            }            else {  
                result.append(word.toString());  
            }            result.append(" ");  
            word = new StringBuilder("");  
            count = 0;  
            continue;  
        }        word.append(ch);  
        count++;  
        if (i == sentence.length() - 1) {  
            if(count >= 5) {  
                result.append(reverse(word));  
            }            else result.append(word.toString());  
        }    }    return result.toString();  
}  
  
public static String reverse(StringBuilder word) {  
    StringBuilder result = new StringBuilder();  
    for (int i = word.length() - 1; i >= 0; i--) {  
        result.append(word.charAt(i));  
    }    return result.toString();  
}

That way too difficult. Actually, StringBuilder has method reverse

we can preprocess to separated words, and join in space.

public static String spinWords(String sentence)  {  
    //preprocess  
    String[] words = sentence.split(" ");  
    // what if replaced with enhanced-loop?  
    //  words[i] is directly modified because we assign a new string to the same index in the array.    //for(int i=0; i<words.length; i++) {  
        if (words[i].length() >= 5){  
            words[i] = new StringBuilder(words[i]).reverse().toString();  
        }    }    return String.join(" ", words);  
}

9 - StringSplit

Complete the solution so that it splits the string into pairs of two characters. If the string contains an odd number of characters then it should replace the missing second character of the final pair with an underscore (’_’).

similar as GetMiddle

Different part is This kata need return all numbers (included ‘__’)

Add __ in front of loop

public static String[] solution(String s) {  
    //Write your code here  
    int l = s.length();  
    if(l%2 != 0){  
        s = s+"_";  
        l += 1;  
    }    String[] result = new String[l/2];  
    int j = 0;  
    for(int i =0; i<=l-2;){  
             substring complexity is O(n)  
        result[j]=(s.substring(i,i+2));  
        i+=2;  
        j++;  
    }    return result;  
}

Same as [[GetMiddle]] we can replace substring with charAt

//34ms  
    public static String[] solution(String s) {  
        //Write your code here  
        int l = s.length();  
        if(l%2 != 0){  
            s = s+"_";  
            l += 1;  
        }        String[] result = new String[l/2];  
        int j = 0;  
        for(int i =0; i<=l-2;){  
            result[j]=(s.charAt(i) + "" + s.charAt(i+1));  
            i+=2;  
            j++;  
        }        return result;  
    }}

NOTE!! String.substring() have complexity of O(n), be careful when use it!