Easy way to sort default array in Vala - sorting

I tried it like this, but it doesn't work. And I think it's too complicated a way to sort an array. I need something like System.Array.Sort () of C#
int[] data = { 3, 9, 2, 7, 5 };
var arr = new Array<int> ();
arr.append_vals (data,data.length);
arr.sort((a, b) => {
return (int) (a > b) - (int) (a < b);
});
for (int i=0;i<arr.length;i++) {
print(#"$(arr.index(i))\t");
}
also tried that, the array is still not sorted.
using Posix;
int cmpfunc(ref int a, ref int b) {
return (int) (a > b) - (int) (a < b);
}
void main() {
int[] data = { 3, 9, 2, 7, 5 };
Posix.qsort (data, data.length, sizeof(string), (Posix.compar_fn_t) cmpfunc);
foreach (int st in data) {
print(#"$st\t");
}
}

The Posix.qsort function needs to know the size of each element in the array, sizeof(int), but you're giving it the size of a different type, sizeof(string).

Related

Suggestion to write a number as a sum of three numbers where each number is at least two

I'm trying to find all possible combinations to write a number as a sum of three numbers, where each number is at least 2.
So basically for 6 it would be like:
2 2 2
For 7 it would be:
2 2 3 or 2 3 2 or 3 2 2
I was wondering if there's a better approach to this than running 3 loops.
EDIT:
public class Problem {
public static void main(String args[]) {
int N = 7, n1, n2, n3;
for (n1 = 2; n1 <= N; n1++) {
for (n2 = 2; n2 <= N; n2++) {
for (n3 = 2; n3 <= N; n3++) {
if ( (n1+n2+n3)==N ) {
System.out.println(n1 + " " + n2 + " " + n3);
}
}
}
}
}
}
This solution works, but I was thinking if there's another approach to this.
You're looking to partition an integer n into k parts, where each part has a minimum value min. The classic approach here would be to use recursion.
Initially we create an array to hold the parts, initialize them to min and remove k*min from n to get the remainder.
static List<int[]> partitions(int n, int k, int min)
{
int[] parts = new int [k];
Arrays.fill(parts, min);
int rem = n - k*min;
List<int[]> results = new ArrayList<>();
partition(results, parts, rem);
return results;
}
We now use a recursive method to explore adding 1 to each of the parts in turn. If the remainder reaches 0 we have a solution and add the current solution to the results.
static void partition(List<int[]> results, int[] parts, int rem)
{
if(rem <= 0)
{
if(rem == 0) results.add(parts.clone());
return;
}
for(int i=0; i<parts.length; i++)
{
parts[i] += 1;
partition(results, parts, rem-1);
parts[i] -= 1;
}
}
Test:
public static void main(String[] args)
{
for(int[] res : partitions(7, 3, 2))
System.out.println(Arrays.toString(res));
}
Output:
[3, 2, 2]
[2, 3, 2]
[2, 2, 3]
it is my suggestion
create a class to model each answer of equation here we create a static inner class to model each answer:
public static class Answer{
private int a;
private int b;
private int c;
public Answer(int a, int b, int c) {
this.a = a;
this.b = b;
this.c = c;
}
public int getA() {
return a;
}
public int getB() {
return b;
}
public int getC() {
return c;
}
#Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Answer answer = (Answer) o;
return a == answer.a &&
b == answer.b &&
c == answer.c;
}
#Override
public int hashCode() {
return Objects.hash(a, b, c);
}
#Override
public String toString() {
return "Answer{" +
"a=" + a +
", b=" + b +
", c=" + c +
'}';
}
}
then a recursive algorithm to produce results:
// don't call this method directly only combination method must call it
private Set<Answer> combinationHelper(int n){
Set<Answer> results = new HashSet<>();
if(n < 0)
return results;
if(n == 0) {
results.add(new Answer(0, 0, 0));
return results;
}
Set<Answer> remain = combinationHelper(n - 1);
remain.forEach(element -> {
int a = element.getA();
int b = element.getB();
int c = element.getC();
results.add(new Answer(a + 1, b, c));
results.add(new Answer(a, b + 1, c));
results.add(new Answer(a, b, c + 1));
});
return results;
}
public Set<Answer> combination(int n){
Set<Answer> results = combinationHelper(n - 6);
return results.stream()
.map(a -> new Answer(a.getA() + 2, a.getB() + 2, a.getC() + 2))
.collect(Collectors.toSet());
}
then call it like this:
System.out.println(new Comb().combination(6));
System.out.println(new Comb().combination(7));
which produces results:
[Answer{a=2, b=2, c=2}]
[Answer{a=2, b=3, c=2}, Answer{a=3, b=2, c=2}, Answer{a=2, b=2, c=3}]
if you don't like the idea of adding another model class to your application you can easily use arrays instead
non-recursive approach:
public List<String> combination(int n){
List<String> result = new ArrayList<>();
if(n < 6)
return result;
BitSet bits = new BitSet(n - 6);
bits.set(0, n - 6);
IntStream
.range(0, n - 5)
.forEach(i ->
IntStream.range(i, n - 5).forEach(j ->
result.add(String.format("%s %d %d %d %s", "{", bits.get(0, i).length() + 2, bits.get(i, j).length() + 2, bits.get(j, n).length() + 2, "}"))));
return result;
}
results for non-recursive approach:
for input 7:
[{ 2 2 3 }, { 2 3 2 }, { 3 2 2 }]
for input 6:
[{ 2 2 2 }]

Choose n unique elements from n lists

I have been thinking about a programing problem. If we have n lists, we want to output n diffrent elements (each one from a different list). I suspect this can be solved with some kind of a backtrack algorithm but I don't see how to correctly implement it.
Though you could solve this with backtracking as suggested in a comment, a more efficient solution would be to use a max-flow algorithm.
Model it as a graph. A Source, a Sink a node for each distinct element and a node for each list.
You have the source connected to each distinct element. Each element connected to every list it is in. and the lists connected to a sink node. Each edge with capacity 1.
The maximum flow is the maximum number of distinct elements from distinct lists you can select.
https://en.wikipedia.org/wiki/Maximum_flow_problem
https://en.wikipedia.org/wiki/Edmonds%E2%80%93Karp_algorithm
I'm not exactly sure that this has no bugs and solves what is being asked; and I hope I have understood the question right this time :)
//test
int[][] arr = new int[][] {
new int[] { 1, 1, 1, 1, 6 },
new int[] { 1, 1, 1, 1, 5 },
new int[] { 1, 1, 1, 4, 9 },
new int[] { 1, 1, 3, 8, 1 },
new int[] { 1, 2, 7, 1, 1 },
new int[] { 1, 1, 1, 1, 1 } };
int[] res = getItems(arr).ToArray(); //6,5,4,3,2,1
private static IEnumerable<T> getItems<T>(T[][] array)
{
int N = array.GetLength(0);
item<T>[] items = new item<T>[N];
HashSet<T> hs = new HashSet<T>();
for (int i = 0; i < N; i++)
{
bool ok = false;
T[] arr = array[i];
for (int j = items[i].Index; j < arr.Length; j++)
{
T val = arr[j];
if (hs.Add(val))
{
items[i] = new item<T>() { Val = val, Index = j };
ok = true;
break;
}
}
if (!ok)
{
item<T> item;
do
{
if (i == 0) throw new Exception("no solution");
items[i] = new item<T>();
item = items[--i];
item.Index++;
items[i] = item;
}
while (item.Index >= array[i].Length);
hs.Clear();
for (int j = 0; j < i; j++)
hs.Add(array[j][items[j].Index]);
i--;
}
}
return hs;
}
private struct item<T>
{
public T Val;
public int Index;
public override string ToString()
{
return string.Format("Val:{0} Index:{1}", Val, Index);
}
}

Optimal way to group time intervals based on projected points

Imagine we have sorted list of time intervals (sorted by time of beginning).
I'm looking for optimal solution to 'project' these intervals to axis, having as a result an array of objects, describing: projected interval start&end time and arrays of source intervals that fall into projected intevals.
Let me explain on example: imagine we have 4 intervals as input (sorted by start time, then by end time):
[---R1---)
[-----R2-----)
[---------R3-------)
[----R4----)
--|-----|--|----|----|-----|---> t (time axis)
1 3 2 3 2
In that case I'm expecting to get array of 5 elements, each element is an object describing interval start/end and a list of source intervals. Numbers under axis on chart shows number of items in that list.
Please, help me to find fastest way to solve this task
Something like this?
def groupIntervals(intervals):
events = {}
for start, stop, name in intervals:
if start not in events: events[start] = []
events[start].append(('start', name))
if stop not in events: events[stop] = []
events[stop].append(('stop', name))
last = None
output = []
active = set()
for time in sorted(events.keys()):
if active and last is not None:
output.append((last, time, active.copy()))
last = time
for action, name in events[time]:
if action == 'start': active.add(name)
elif action == 'stop': active.remove(name)
else: assert False
return output
Example usage:
>>> groupIntervals([(1, 3, 'R1'), (2, 5, 'R2'), (2, 6, 'R3'),
... (4, 6, 'R4')])
[(1, 2, set(['R1'])),
(2, 3, set(['R1', 'R2', 'R3'])),
(3, 4, set(['R2', 'R3'])),
(4, 5, set(['R4', 'R2', 'R3'])),
(5, 6, set(['R4', 'R3']))]
C++ version with cleverer data structure usage.
#include <cstdio>
#include <limits>
#include <list>
#include <queue>
#include <string>
#include <vector>
struct Interval {
Interval(std::string name, int start, int stop);
std::string name;
int start;
int stop;
};
Interval::Interval(std::string name, int start, int stop)
: name(name), start(start), stop(stop) {
}
typedef std::list<std::vector<Interval>::const_iterator> ActiveList;
struct StopEvent {
StopEvent(int stop, ActiveList::iterator j);
int stop;
ActiveList::iterator j;
};
StopEvent::StopEvent(int stop, ActiveList::iterator j)
: stop(stop), j(j) {
}
struct StopEventGreater {
bool operator()(StopEvent const& a,
StopEvent const& b) const;
};
bool StopEventGreater::operator()(StopEvent const& a,
StopEvent const& b) const {
return a.stop > b.stop;
}
void Sweep(std::vector<Interval> const& intervals) {
std::vector<Interval>::const_iterator i(intervals.begin());
std::priority_queue<StopEvent,
std::vector<StopEvent>,
StopEventGreater> active_queue;
ActiveList active_list;
int last_time(std::numeric_limits<int>::min());
while (i != intervals.end() || !active_queue.empty()) {
bool start(i != intervals.end() &&
(active_queue.empty() || i->start < active_queue.top().stop));
int time(start ? i->start : active_queue.top().stop);
if (time != last_time && !active_list.empty()) {
std::printf("[%d, %d):", last_time, time);
for (ActiveList::const_iterator j(active_list.begin());
j != active_list.end();
++j) {
std::printf(" %s", (*j)->name.c_str());
}
std::putchar('\n');
}
last_time = time;
if (start) {
active_queue.push(StopEvent(i->stop,
active_list.insert(active_list.end(), i)));
++i;
} else {
active_list.erase(active_queue.top().j);
active_queue.pop();
}
}
}
int main(void) {
std::vector<Interval> intervals;
intervals.push_back(Interval("R1", 0, 4));
intervals.push_back(Interval("R2", 1, 9));
intervals.push_back(Interval("R3", 1, 11));
intervals.push_back(Interval("R4", 6, 11));
Sweep(intervals);
}
Finally I've found the most effective way. It uses one sorting operation and O(N*2) iterations to build result.
public IEnumerable<DateProjectedItems<T>> Project(IList<T> items)
{
if (items.Count <= 1)
{
if (items.Count == 0)
{
yield break;
}
yield return new DateProjectedItems<T>
{
DateRange = items[0].DateRange,
Items = items
};
}
else
{
var endOrdered = items.OrderBy(i => i.DateRange.DateTimeTo).ToList();
var active = new List<T>();
DateTime? last = null;
foreach (var pair in TwoArrayIterator(items, endOrdered))
{
DateTime current = pair.Key == 1 ? pair.Value.DateRange.DateTimeFrom : pair.Value.DateRange.DateTimeTo;
if (last != null && current != last)
{
yield return new DateProjectedItems<T>
{
DateRange = new DateRange(last.Value, current),
Items = active.ToList()
};
}
if (pair.Key == 1)
{
active.Add(pair.Value);
}
else
{
active.Remove(pair.Value);
}
last = current;
}
}
}
public IEnumerable<KeyValuePair<int, T>> TwoArrayIterator(IList<T> arr1, IList<T> arr2)
{
var index1 = 0;
var index2 = 0;
while (index1 < arr1.Count || index2 < arr2.Count)
{
if (index1 >= arr1.Count)
yield return new KeyValuePair<int, T>(2, arr2[index2++]);
else if (index2 >= arr2.Count)
yield return new KeyValuePair<int, T>(1, arr1[index1++]);
else
{
var elt1 = arr1[index1];
var elt2 = arr2[index2];
if (elt1.DateRange.DateTimeFrom < elt2.DateRange.DateTimeTo)
{
index1++;
yield return new KeyValuePair<int, T>(1, elt1);
}
else
{
index2++;
yield return new KeyValuePair<int, T>(2, elt2);
}
}
}
}

Data structure choice for dynamic programming

In order to implement a DP algorithm for detecting whether a word is breakable into sub-words of length 'n' to 1, what should be the choice of data structure for caching DP results.
Example: the word 'pita' can be broken into 'pit', 'it' & 'i' which are all valid dictionary words as well.
The DP algorithm should detect such words.
I can imagine I need start from words of length 1 and build up substrings of increasing lengths but I am not able to arrive at a data structure which can efficiently store the subproblem's results
if you work on your word sequential you don't need to track previous word as you don't reach them again, but you can use a cache to cache previously lookup sub word in the dictionary.
If i understand the problem, then i think the following Java code may help you:
String term = "pita";
Set<String> dictionary = new HashSet<String>();
boolean ans = true;
for(int i = 0; i < term.length() && ans == true; i++) {
for(int j = i + 1; j < term.length(); j++) {
String subTerm = term.substring(i, j);
if(!dictionary.contains(subTerm)){
ans = false;
break;
}
}
}
System.out.println("ans [" = ans + "]");
For dictionary you can use a hash table and it support to take O(1) to check if the sub
word exist or not. if you cache previously checked sub word it will take the same O(1)
I think this problem is fitted in sorting and searching technique not in DP because
it did not use a previous answer to produce current answer.
There is no need for special datastructure as such a boolean DP array would be sufficient :-
isSentence[j] tell the substring str[j to n] is valid concatenation of
english words/word where n is last index
isSentence[j] = or(isword(str[j to i]) && isSentece[i+1]) for all i
from j to n
or here means logical OR of all subproblem and isword is dictionary
lookup which returns boolean value and && logical AND
I can imagine I need start from words of length 1 and build up substrings of increasing lengths but I am not able to arrive at a data structure which can efficiently store the subproblem's results
The following is a pseudo-code written in Java might not compile
TrieNode.java
class TrieNode
{
public TrieNode (double a, double b, double g, int size)
{
this.alpha = a;
this.beta = b;
this.gamma = g;
this.next = new TrieNode [size];
}
public double alpha, beta, gamma;
public TrieNode [] next;
}
You can replace alpha, beta, gamma with your parameters for the problem.
Trie.java
class Trie
{
private TrieNode root;
private char base;
private final int ALPHABET_SIZE;
public Trie (int ALPHABET_SIZE, char base_char)
{
this.base = base_char;
this.root=new TrieNode(0,0,0,ALPHABET_SIZE);
}
public boolean insert (String word, double [] param)
{
TrieNode current = this.root;
int i = (-1);
if (!validate(word))
return false;
char [] c = word.toCharArray();
for (int i = 0; i < (c.length-1); i++)
{
if (current.next[c[i]-base] == null)
current.next[c[i]-base] = new TrieNode (0,0,0,ALPHABET_SIZE);
current = current.next[c[i]-base];
}
if (current.next[c[i]-base] == null)
current.next[c[i]-base] = new TrieNode (0,0,0,ALPHABET_SIZE);
current.next[c[i]-base].alpha = param[0];
current.next[c[i]-base].beta = param[1];
current.next[c[i]-base].gamma = param[2];
return true;
}
public boolean validate (String word)
{
for (char c : word.toCharArray())
if (c < base || c > (base+ALPHABET_SIZE-1))
return false;
}
}
This is an index-based Trie, with safe insert function.
MappedTrie.java
class MappedTrie
{
public final char [] ALPHABET;
private Trie trie;
MappedTrie (char [] alphabet)
{
ALPHABET = alphabet;
trie = new Trie (ALPHABET.length,0);
}
public boolean insert (String word, double [] param)
{
if (!validate(word))
return false;
String key = "";
for (char c : word.toCharArray())
key += encode(c);
return trie.insert(key,param);
}
private char encode (char c)
{
for (int i=0; i<ALPHABET.length; i++)
if (c == ALPHABET[i])
return i;
}
private char decode (char d)
{
return ALPHABET[d];
}
public boolean validate (String word)
{
boolean exist = false;
for (char c : word.toCharArray())
{
exist = false;
for (char d : ALPHABET) if (c == d) { exist = true; break; }
if (!exist) return false;
}
return true;
}
}
In case of a custom alphabet where characters are not adjecent, we can map it over index.
Test
class Test
{
public static void main (String [] args)
{
// 'a'+0, 'a'+1, 'a'+2
MappedTrie k = new MappedTrie(3, 'a');
k.insert("aa", { 0.1, 0.2, 0.3 });
k.insert("ab", { 0.4, 0.5, 0.6 });
k.insert("ac", { 0.7, 0.8, 0.9 });
k.insert("ba", { 0.01, 0.02, 0.03 });
k.insert("bb", { 0.04, 0.05, 0.06 });
k.insert("bc", { 0.07, 0.08, 0.09 });
k.insert("ca", { 0.001, 0.002, 0.003 });
k.insert("cb", { 0.004, 0.005, 0.006 });
k.insert("cc", { 0.007, 0.008, 0.009 });
// 'a' => 0, 'b' => 1, 'c' => 2
MappedTrie t = new MappedTrie({'a','b','c'});
t.insert("aa", { 0.1, 0.2, 0.3 });
t.insert("ab", { 0.4, 0.5, 0.6 });
t.insert("ac", { 0.7, 0.8, 0.9 });
t.insert("ba", { 0.01, 0.02, 0.03 });
t.insert("bb", { 0.04, 0.05, 0.06 });
t.insert("bc", { 0.07, 0.08, 0.09 });
t.insert("ca", { 0.001, 0.002, 0.003 });
t.insert("cb", { 0.004, 0.005, 0.006 });
t.insert("cc", { 0.007, 0.008, 0.009 });
}
}
I think using unordered_map<string, int> or unordered_set<string> might be very helpful.

Even-odd sort incompatibility

I am new to Java and I have faced the following problem. I need to sort array of integers in ascending order so that even numbers will be in one half and odd ones in the other.
So, I have a special comparator:
static class EvenOddSort implements Comparator<Integer> {
#Override
public int compare(Integer x, Integer y) {
if (x == y) {
return 0;
}
if (y % 2 == 0) {
if (x < y) {
return -1;
} else {
return 1;
}
}
if (x % 2 == 0) {
if (x < y) {
return 1;
} else {
return -1;
}
}
return 0;
}
}
And the following sort method:
public Integer[] sortEvenOdd(Integer[] nums) {
EvenOddSort customSort = new EvenOddSort();
Arrays.sort(nums, customSort);
return nums;
}
Also I have the following test:
#Test
public void testSortEvenOdd1() {
Integer[] nums = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
Integer[] expected = { 2, 4, 6, 8, 10, 1, 3, 5, 7, 9 };
assertArrayEquals(expected, tasks5.sortEvenOdd(nums));
}
It fails when I run it on openJDK6 and successful on openJDK7.
arrays first differed at element [0]; expected:<2> but was:<1> junit.framework.AssertionFailedError: arrays first differed at element [0]; expected:<2> but was:<1>
Could you help me to make it compatible across all openJDK's?
Also, it would be great to know what I am doing wrong.
Any ideas are welcome!
Your whole comparator is broken, I kept seeing more problems with it.
Just do something like this:
if (x%2 != y%2) {
if (x%2==0) {
return -1;
} else {
return 1;
}
} else {
return x.compareTo(y);
}
First check to see if they are not both odd or both even. If they are different then sort based on odd or even.
Then if they are both odd or both even fall back to the standard Integer compare functionality.

Resources