package humaneval.buggy;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;

/*
 * In this Kata, you have to sort an array of non-negative integers according to
    number of ones in their binary representation in ascending order.
    For similar number of ones, sort based on decimal value.

    It must be implemented like this:
    >>> sort_array([1, 5, 2, 3, 4]) == [1, 2, 3, 4, 5]
    >>> sort_array([-2, -3, -4, -5, -6]) == [-6, -5, -4, -3, -2]
    >>> sort_array([1, 0, 2, 3, 4]) [0, 1, 2, 3, 4]
 */

public class SORT_ARRAY_BINARY {
   public static int number_ones(int n) {
      if(n < 0) n *= -1;
      int count = 0;
      while(n > 0) {
         count += n & 1;
         n >>= 1;
      }
      return count;
   }

   public static ArrayList<Integer> sort_array_binary(ArrayList<Integer> arr) {
      Collections.sort(arr, new Comparator<Integer>() {
         @Override
         public int compare(Integer o1, Integer o2) {
            int num_ones_o1 = number_ones(o1);
            int num_ones_o2 = number_ones(o2);
            if(num_ones_o1 == num_ones_o2) {
               if(o1 == o2) return 1;
               if(o1 < o2) return 0;
               if(o1 > o2) return -1;
            }
            if(num_ones_o1 < num_ones_o2) return -1;
            else return 1;
         }
      });
      return arr;
   }
}

package humaneval;

import java.util.ArrayList;
import java.util.Arrays;

public class TEST_SORT_ARRAY_BINARY {
    @org.junit.Test(timeout=3000)
    public void test_0() throws java.lang.Exception {
        ArrayList<Integer> input = new ArrayList<>(Arrays.asList(1, 5, 2, 3, 4));
        ArrayList<Integer> result = humaneval.buggy.SORT_ARRAY_BINARY.sort_array_binary(input);
        ArrayList<Integer> desired = new ArrayList<>(Arrays.asList(1, 2, 4, 3, 5));
        org.junit.Assert.assertEquals(desired, result);
    }
    @org.junit.Test(timeout=3000)
    public void test_1() throws java.lang.Exception {
        ArrayList<Integer> input = new ArrayList<>(Arrays.asList(-2, -3, -4, -5, -6));
        ArrayList<Integer> result = humaneval.buggy.SORT_ARRAY_BINARY.sort_array_binary(input);
        ArrayList<Integer> desired = new ArrayList<>(Arrays.asList(-4, -2, -6, -5, -3));
        org.junit.Assert.assertEquals(desired, result);
    }
    @org.junit.Test(timeout=3000)
    public void test_2() throws java.lang.Exception {
        ArrayList<Integer> input = new ArrayList<>(Arrays.asList(1, 0, 2, 3, 4));
        ArrayList<Integer> result = humaneval.buggy.SORT_ARRAY_BINARY.sort_array_binary(input);
        ArrayList<Integer> desired = new ArrayList<>(Arrays.asList(0, 1, 2, 4, 3));
        org.junit.Assert.assertEquals(desired, result);
    }
    @org.junit.Test(timeout=3000)
    public void test_3() throws java.lang.Exception {
        ArrayList<Integer> input = new ArrayList<>();
        ArrayList<Integer> result = humaneval.buggy.SORT_ARRAY_BINARY.sort_array_binary(input);
        ArrayList<Integer> desired = new ArrayList<>();
        org.junit.Assert.assertEquals(desired, result);
    }
    @org.junit.Test(timeout=3000)
    public void test_4() throws java.lang.Exception {
        ArrayList<Integer> input = new ArrayList<>(Arrays.asList(2, 5, 77, 4, 5, 3, 5, 7, 2, 3, 4));
        ArrayList<Integer> result = humaneval.buggy.SORT_ARRAY_BINARY.sort_array_binary(input);
        ArrayList<Integer> desired = new ArrayList<>(Arrays.asList(2, 2, 4, 4, 3, 3, 5, 5, 5, 7, 77));
        org.junit.Assert.assertEquals(desired, result);
    }
    @org.junit.Test(timeout=3000)
    public void test_5() throws java.lang.Exception {
        ArrayList<Integer> input = new ArrayList<>(Arrays.asList(3, 6, 44, 12, 32, 5));
        ArrayList<Integer> result = humaneval.buggy.SORT_ARRAY_BINARY.sort_array_binary(input);
        ArrayList<Integer> desired = new ArrayList<>(Arrays.asList(32, 3, 5, 6, 12, 44));
        org.junit.Assert.assertEquals(desired, result);
    }
    @org.junit.Test(timeout=3000)
    public void test_6() throws java.lang.Exception {
        ArrayList<Integer> input = new ArrayList<>(Arrays.asList(2, 4, 8, 16, 32));
        ArrayList<Integer> result = humaneval.buggy.SORT_ARRAY_BINARY.sort_array_binary(input);
        ArrayList<Integer> desired = new ArrayList<>(Arrays.asList(2, 4, 8, 16, 32));
        org.junit.Assert.assertEquals(desired, result);
    }
}