Files
test/puzzles/training/array_inversion_count.cpp
2021-03-26 19:34:05 +00:00

90 lines
2.2 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*
VIM: let b:cf5build="clang -std=c++20 -O2 -pthread -lstdc++ -I. {SRC} -o {OUT}"
VIM: let b:cf5run="{OUT}"
*/
#include <iostream>
#include <exception>
#include <chrono>
#include <string>
#include <vector>
#include <unordered_map>
#include <unordered_set>
#include <functional>
/*
https://app.codility.com/programmers/lessons/99-future_training/array_inversion_count/
An array A consisting of N integers is given. An inversion is a pair of indexes (P, Q) such that P < Q and A[Q] < A[P].
Write a function:
int solution(vector<int> &A);
that computes the number of inversions in A, or returns 1 if it exceeds 1,000,000,000.
For example, in the following array:
A[0] = -1 A[1] = 6 A[2] = 3
A[3] = 4 A[4] = 7 A[5] = 4
there are four inversions:
(1,2) (1,3) (1,5) (4,5)
so the function should return 4.
Write an efficient algorithm for the following assumptions:
N is an integer within the range [0..100,000];
each element of array A is an integer within the range [2,147,483,648..2,147,483,647].
*/
int solution(const std::vector<int>& v)
{
std::vector<size_t> iv(v.size(),0);
for (size_t i=0; i<v.size(); ++i){
iv[i] = i;
}
std::stable_sort(iv.begin(), iv.end(), [&v](size_t op1, size_t op2){
return v[op1] < v[op2];
});
size_t count = 0;
for (size_t i=0; i < iv.size(); ++i){
if ( i < iv[i]){
count += iv[i] - i;
}
}
return count;
}
int main ( void )
{try{
auto begin = std::chrono::high_resolution_clock::now();
std::cout << solution({-1, 6, 3, 4, 7, 4}) << std::endl;
std::cout << solution({0, 0, 0, 1, 1, 1}) << std::endl;
std::cout << solution({0, 1, 0, 1, 1, 1}) << std::endl;
std::cout << solution({0}) << std::endl;
std::cout << solution({}) << std::endl;
auto end = std::chrono::high_resolution_clock::now();
std::chrono::duration<double> seconds = end - begin;
std::cout << "Time: " << seconds.count() << std::endl;
return 0;
}
catch ( const std::exception& e )
{
std::cerr << std::endl
<< "std::exception(\"" << e.what() << "\")." << std::endl;
return 2;
}
catch ( ... )
{
std::cerr << std::endl
<< "unknown exception." << std::endl;
return 1;
}}