Euler Project – Problem 21 Solution: 31626

Let d(n) be defined as the sum of proper divisors of n (numbers less than n which divide evenly into n).
If d(a) = b and d(b) = a, where ab, then a and b are an amicable pair and each of a and b are called amicable numbers.

For example, the proper divisors of 220 are 1, 2, 4, 5, 10, 11, 20, 22, 44, 55 and 110; therefore d(220) = 284. The proper divisors of 284 are 1, 2, 4, 71 and 142; so d(284) = 220.

Evaluate the sum of all the amicable numbers under 10000.

Solution:31626

public class Problem21 {
   
    public static void main(String[] args) {

        int sum = 0;
        for (int i = 1; i < 10000; i++) {
            int divSum = getProperDivisorsSum(i);
            if(i!=divSum && i==getProperDivisorsSum(divSum))
            {
                sum+=i;
            }
        }
        System.out.println(sum);
       
    }
   
    private static int getProperDivisorsSum(int num){
        int sum = 0;
        for (int j = 1; j < num; j++) {
            if(num%j==0){
                sum += j;
            }
        }
        return sum;
    }
}

Paper folding facts

Can you fold a paper 8 times? Actually, you can! You can fold paper in half as many times you want. The matter is here to find a paper with an appropriate size and enough power to fold it.

Today I want to write about paper folding and how our brains can get give wrong measurements. If you fold a paper in half one, that’s okey, you just fold it. What if we fold it several times? Let’s imagine we can largest paper and infinite power to fold it.

According to Wikipedia, minimum paper thickness can be 0.07mm.
1 – just folded paper with 0.14mm
10 – this is 1000 page book
23 – you reach 1km width

To be continued …

Euler Project – Problem 20 Solution: 648

n! means n × (n − 1) × … × 3 × 2 × 1

For example, 10! = 10 × 9 × … × 3 × 2 × 1 = 3628800,
and the sum of the digits in the number 10! is 3 + 6 + 2 + 8 + 8 + 0 + 0 = 27.

Find the sum of the digits in the number 100!

Solution

public class Problem20 {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
       
        String product = "1";
        for (int i = 1; i <= 100; i++) {
            product = multiply(product, i);
        }
       
        char[] product_digits = product.toCharArray();
        int sum = 0;
        for (char c : product_digits) {
            int digit = Integer.parseInt(String.valueOf(c));
            sum += digit;
        }
        System.out.println(sum);
       
    }
   
    public static String multiply(String num1, int num2){
       
        char[] num1_digits = num1.toCharArray();
        int remainder = 0;
        String result = "";
        for (int i = num1_digits.length-1; i >= 0; i--) {
            char c = num1_digits[i];
            int digit = Integer.parseInt(String.valueOf(c));
            int x = digit*num2+remainder;
            result=x%10+result;
            remainder = (x-x%10)/10;
        }

        if(remainder>0){
            result = remainder + result;
        }
       
        return result;
       
    }
   
}

Euler Project – Problem 19 Solution: 171

You are given the following information, but you may prefer to do some research for yourself.

  • 1 Jan 1900 was a Monday.
  • Thirty days has September,
    April, June and November.
    All the rest have thirty-one,
    Saving February alone,
    Which has twenty-eight, rain or shine.
    And on leap years, twenty-nine.
  • A leap year occurs on any year evenly divisible by 4, but not on a century unless it is divisible by 400.

How many Sundays fell on the first of the month during the twentieth century (1 Jan 1901 to 31 Dec 2000)?

Solution:

public class Problem19 {

    public static void main(String[] args) {

        final int JANUARY = 0;
        final int FEBRUARY = 1;
        final int MARCH = 2;
        final int APRIL = 3;
        final int MAY = 4;
        final int JUNE = 5;
        final int JULY = 6;
        final int AUGUST = 7;
        final int SEPTEMBER = 8;
        final int OCTOBER = 9;
        final int NOVEMBER = 10;
        final int DECEMBER = 11;

        final int MONDAY = 0;
        final int TUESDAY = 1;
        final int WEDNESDAY = 2;
        final int THURSDAY = 3;
        final int FRIDAY = 4;
        final int SATURDAY = 5;
        final int SUNDAY = 6;

        int count_for_first_of_month_sundays = 0;

        for (int y = 1900, weekday = MONDAY; y <= 2000; y++) {
            for (int m = 0; m < 12; m++) {
                int month_days = 31;
                if (m == FEBRUARY) {
                    if (isYearLeap(y)) {
                        month_days = 29;
                    } else {
                        month_days = 28;
                    }
                } else if (m == SEPTEMBER || m == APRIL || m == JUNE
                        || m == NOVEMBER) {
                    month_days = 30;
                }

                for (int d = 0; d < month_days; d++) {
                    if (d == 0 && weekday == SUNDAY && y > 1900) {
                        count_for_first_of_month_sundays++;
                    }
                    weekday = (weekday + 1) % 7;
                }
            }
        }

        System.out.println(count_for_first_of_month_sundays);

    }

    static Boolean isYearLeap(int year) {
        if (year % 4 == 0) {
            if (year % 100 == 0) {
                if (year % 400 == 0) {
                    return true;
                }
                return false;
            }
            return true;
        }
        return false;
    }
}

Euler Project – Problem 18 Solution

By starting at the top of the triangle below and moving to adjacent numbers on the row below, the maximum total from top to bottom is 23.

3
7 4
2 4 6
8 5 9 3

That is, 3 + 7 + 4 + 9 = 23.

Find the maximum total from top to bottom of the triangle below:

75
95 64
17 47 82
18 35 87 10
20 04 82 47 65
19 01 23 75 03 34
88 02 77 73 07 63 67
99 65 04 28 06 16 70 92
41 41 26 56 83 40 80 70 33
41 48 72 33 47 32 37 16 94 29
53 71 44 65 25 43 91 52 97 51 14
70 11 33 28 77 73 17 78 39 68 17 57
91 71 52 38 17 14 91 43 58 50 27 29 48
63 66 04 68 89 53 67 30 73 16 69 87 40 31
04 62 98 27 23 09 70 98 73 93 38 53 60 04 23

NOTE: As there are only 16384 routes, it is possible to solve this problem by trying every route. However, Problem 67, is the same challenge with a triangle containing one-hundred rows; it cannot be solved by brute force, and requires a clever method! ;o)

Solution:

import java.util.ArrayList;

public class Problem18 {

    public static void main(String[] args) {

        int max_sum = 0;
        String path = "";

        String numbers_string = "75 95 64 17 47 82 18 35 87 10 20 04 82 47 65 19 01 23 75 03 34 88 02 77 73 07 63 67 99 65 04 28 06 16 70 92 41 41 26 56 83 40 80 70 33 41 48 72 33 47 32 37 16 94 29 53 71 44 65 25 43 91 52 97 51 14 70 11 33 28 77 73 17 78 39 68 17 57 91 71 52 38 17 14 91 43 58 50 27 29 48 63 66 04 68 89 53 67 30 73 16 69 87 40 31 04 62 98 27 23 09 70 98 73 93 38 53 60 04 23";
        String[] numbers_array = numbers_string.split(" ");
        ArrayList<int[]> lines = new ArrayList<int[]>();

        // get lines count
        int num = 0;
        int sum = 0;
        while (sum < numbers_array.length) {
            num++;
            sum += num;
        }
        int lines_count = num;
        System.out.println(lines_count);

        //create all lines
        int numbers_count = 0;
        for (int i = 1; i <= lines_count; i++) {
            int[] line = new int[i];
            for (int j = numbers_count, k = 0; j < numbers_count + i; j++, k++) {
                line[k] = Integer.parseInt(numbers_array[j]);
            }
            lines.add(line);
            numbers_count += i;
        }

        //get maximum total
        for (int i = 0; i < Math.pow(2, lines_count - 1); i++) {
            int temp_sum = 0;
            String binary = Integer.toBinaryString(i);
            while (binary.length() < lines_count) {
                binary = "0" + binary;
            }
            char[] direction = binary.toCharArray();
            int index = 0;
            for (int j = 0; j < direction.length; j++) {
                if (direction[j] == '1') {
                    index++;
                }
                temp_sum += lines.get(j)[index];
            }
            if (temp_sum > max_sum) {
                max_sum = temp_sum;
                path = binary;
            }
            System.out.println(i + "th path=" + binary + ":" + temp_sum);
        }

        System.out.println(max_sum);
        System.out.println(path);

    }
}

Euler Project – Problem 17 solution

If the numbers 1 to 5 are written out in words: one, two, three, four, five, then there are 3 + 3 + 5 + 4 + 4 = 19 letters used in total.

If all the numbers from 1 to 1000 (one thousand) inclusive were written out in words, how many letters would be used?

NOTE: Do not count spaces or hyphens. For example, 342 (three hundred and forty-two) contains 23 letters and 115 (one hundred and fifteen) contains 20 letters. The use of “and” when writing out numbers is in compliance with British usage.

public class Main {

    static String[] numbers_under_twenty = new String[]{"", "one", "two", "three", "four", "five",
            "six", "seven", "eight", "nine",
            "ten", "eleven", "twelve", "thirteen", "fourteen", "fifteen",
            "sixteen", "seventeen", "eighteen", "nineteen"};
    static String[] tens = new String[]{"", "ten", "twenty", "thirty","forty","fifty",
            "sixty","seventy","eighty","ninety"};
    static String hundred = "hundred";
    static String thousand = "thousand";
    static String and = "and";
   
    public static void main(String[] args) {
       
        int sum = 0;
        for (int i = 1; i <= 1000; i++) {
            sum+=getLettersCount(i);
        }
        System.out.println(sum);
       
    }

    private static int getLettersCount(int num) {

        int letters_count = 0;
       
        if(num%100<20){
            letters_count += numbers_under_twenty[num%100].length();
        }
        else
        {
            letters_count += numbers_under_twenty[num%10].length();
            letters_count += tens[(num%100-num%10)/10].length();
        }
       
        if(num>=100 && num<1000){
            letters_count += numbers_under_twenty[(num%1000-num%100)/100].length();
            letters_count += hundred.length();
            if(num%100!=0){
                letters_count+=and.length();
            }
        }
       
        if(num==1000){
            letters_count += numbers_under_twenty[1].length();
            letters_count += thousand.length();
        }

        return letters_count;
    }
   
}

Android.SQLite – Optimize SELECT query with LIKE

For the last 2 days I was trying to optimize my SELECT query with LIKE operator. Even I tried to use FTS tables. It was fast, but it did not return the result as I intended. So I tried another way

I have this table:

CREATE TABLE meaning(
KEY TEXT,
VALUE TEXT,
entries BLOB);

Then created INDEX on key column:

CREATE INDEX index_key ON meaning(KEY);

Then I was getting data using this query:

SELECT rowid AS _id, VALUE, entries
FROM meaning
WHERE KEY
LIKE 'dog%'
ORDER BY KEY
LIMIT 100

Result was coming in 510ms. I tried to optimize my select query. Actually, this was not because of SELECT query. It was because of INDEX(index_key). I found that LIKE is not case sensitive so logical step is to make INDEX not case sensitive. It was done in this way:

CREATE INDEX index_key ON meaning (KEY COLLATE NOCASE);

Now same query as stated before, is returning result in 83ms which means more than 6 times faster. In applications, like a dictionary which required incremental search which difference is enormous.

Android – SlidingTabLayout tab text color selector

custom_tab.xml

<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
   android:layout_width="wrap_content"
   android:layout_height="match_parent"
   android:textSize="14sp"
   android:textStyle="bold"
   android:padding="16dp"
   android:textColor="@color/tab_text_color"
   android:gravity="center"
/>

tab_text_color.xml

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:color="@color/white" android:state_selected="true"/>
    <item android:color="@color/orange_inactive_bar"/>
</selector>

Android – Change toolbar text color

Toolbar:

    <android.support.v7.widget.Toolbar
       android:id="@+id/my_awesome_toolbar"
       android:layout_height="wrap_content"
       android:layout_width="match_parent"
       android:minHeight="?attr/actionBarSize"
       android:background="@color/orange_toolbar"
       app:theme="@style/ToolBarStyle"
       />

values/styles.xml

    <style name="ToolBarStyle" parent="Theme.AppCompat">
        <item name="android:textColorPrimary">@android:color/white</item>
        <item name="android:textColorSecondary">@android:color/white</item>
        <item name="actionMenuTextColor">@android:color/white</item>
    </style>

Android – How to add toolbar

Add Toolbar to layout xml:

    <android.support.v7.widget.Toolbar
       android:id="@+id/my_awesome_toolbar"
       android:layout_height="wrap_content"
       android:layout_width="match_parent"
       android:minHeight="?attr/actionBarSize"
       android:background="@color/orange_toolbar" />

Inside the onCreate method:

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Toolbar toolbar = (Toolbar) findViewById(R.id.my_awesome_toolbar);
        setSupportActionBar(toolbar);

If you try to run your app after adding toolbar it can give following error:

java.lang.IllegalStateException: This Activity already has an action bar supplied by the window decor. Do not request Window.FEATURE_ACTION_BAR and set windowActionBar to false in your theme to use a Toolbar instead.

In this case just disable your action bar in values/styles.xml

    <!-- Base application theme. -->
    <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
        <item name="windowActionBar">false</item>
    </style>