Arithmetic sequence - checking - c++

What is the most efficient way to check whether you can create an arithmetic sequence from the specified sequence of numbers?
Currently I sort the sequence and then do this:
#include<bits/stdc++.h>
using namespace std;
static bool sort_using_greater_than(float u, float v)
{
return u > v;
}
int main()
{
int licznik=0, i=0;
double number[100000];
while(~scanf("%f", &number[i]))
{
i++;
licznik++;
}
sort(number,number+100, sort_using_greater_than);
for(int i = 1; i < licznik-1; i++)
{
if(number[i] - number[i+1] != number[0] - number[1])
{
puts("NO");
return 0;
}
}
puts("YES");
}
For test:
1.0 5.0
My code return YES, why?
enter code here
double search_min(double tab[], int n)
{
double min = tab[0];
for(int i = 1; i < n; i++)
{
if(min > tab[i])
min = tab[i];
return min;
}
And, How I can find two smallest element?

The question is unclear but if it means "check that the given numbers can be rearranged to from a single arithmetic sequence", then there is no need to sort.
find the smallest element, in O(N), let a;
find the second smallest, in O(N), let b;
clear an array of N bits in O(N);
for every number c, compute (c - a) / (b - a); if this isn't an integer in range [0,n-1], the answer is no. Otherwise, set the bit at that index (done in O(1) per element);
check that all bits have been set in O(N).
The whole process takes time O(N).

O(n) is the best you are going to get simply by the nature that you must check every element.
I've implemented Yves Daoust's algorithm (with some minor optimizations) as well as your own in C++14 standard code.
Here is yours:
int main(int argc, char* argv[]) {
if(argc == 1) return 0;
//Copy command args to vector of strings.
std::size_t number_count = argc - 1;
std::vector<std::string> cmd_args(number_count);
std::copy(argv + 1, argv + argc, cmd_args.begin());
//Copy convert vector of strings to vector of ints.
std::vector<int> values(number_count);
auto v_begin = values.begin();
for(auto s : cmd_args) {
(*v_begin) = std::stoi(s);
++v_begin;
}
//Sort values in ascending order.
std::sort(values.begin(), values.end());
//Get smallest two values.
std::pair<int, int> two_smallest_values(*values.cbegin(), *(values.cbegin() + 1));
//Calculate differences between each successive number
std::vector<int> differences(values.size() - 1);
for(std::size_t i = 0; i < values.size() - 1; ++i) {
differences[i] = std::abs(values[i] - values[i + 1]);
}
//All values in differences must be the same.
if(std::all_of(differences.cbegin(), differences.cend(), [=](int i) { return i == *differences.cbegin(); })) {
std::cout << "YES\n";
} else {
std::cout << "NO\n";
}
return 0;
}
Here is Yves Daoust's algorithm:
int main(int argc, char* argv[]) {
if(argc == 1) return 0;
//Copy command args to vector of strings.
std::size_t number_count = argc - 1;
std::vector<std::string> cmd_args(number_count);
std::copy(argv + 1, argv + argc, cmd_args.begin());
//Copy convert vector of strings to vector of ints.
auto v_begin = values.begin();
for(auto s : cmd_args) {
(*v_begin) = std::stoi(s);
++v_begin;
}
//Sort values in ascending order.
std::sort(values.begin(), values.end());
//Get smallest two values.
std::pair<int, int> two_smallest_values(*values.cbegin(), *(values.cbegin() + 1));
std::vector<bool> bits(values.size());
bool result = true;
int smallest_diff = (two_smallest_values.second - two_smallest_values.first);
for(auto v : values) {
int numerator = v - two_smallest_values.first;
int denominator = smallest_diff;
if(numerator % denominator != 0) {
result = false;
break;
}
std::size_t i = numerator / denominator;
if(i < 0 || i >= values.size()) {
result = false;
break;
}
bits[i] = true;
}
if(result == false) {
std::cout << "NO\n";
return 0;
}
//Convert vector of bools (bit-packed) to an unsigned int.
unsigned long long bits_value = 0;
unsigned long long i = 0;
for(auto b : bits) {
bits_value |= (b << i++);
}
//Optimization: Single calculation to determine if all bits are set:
if(std::abs(bits_value - (std::pow(2.0, bits.size()) - 1) < 0.01)) {
std::cout << "YES\n";
} else {
std::cout << "NO\n";
}
return 0;
}

Related

Breaking out of loop from function after printing the last prime number of a given range

I'm writing a code to find the last prime number of a given range. Suppose the range is 1 to 50. Then the last prime no. I want to print must be 47. My idea was to maybe reverse the order of prime numbers in the range and then try printing only the first value. Again kinda like if my order was 1 to 50 then I would start printing from 47, 43 and so on and only print 47. But I'm stuck and not getting ideas on how I could do this. here's my code
int prime_bef(int n)
{
int check = 0;
for (int i = 1; i <= n; i++)
{
if (n % i == 0)
{
check++;
}
}
if (check == 2)
{
cout << n << " ";
}
return 0;
}
int main ()
{
int l;
int u;
cin >> l >> u;
for (int i = u; i >= l; i--)
{
prime_bef(i);
}
return 0;
}
You can just use exit() in the place you want to end the program, and it works fine in your case. But by far the best approach is returning a value to test for continuation, it is the most readable.
#include<iostream>
#include <stdlib.h>
using namespace std;
int prime_bef(int n)
{
int check = 0;
for (int i = 1; i <= n; i++)
{
if (n % i == 0)
{
check++;
}
}
if (check == 2)
{
cout << n << " ";
exit(0);
}
return 0;
}
int main ()
{
int l;
int u;
cin >> l >> u;
for (int i = u; i >= l; i--)
{
prime_bef(i);
}
return 0;
}
Same code using bool return type:
#include<iostream>
using namespace std;
bool prime_bef(int n)
{
int check = 0;
for (int i = 1; i <= n; i++)
{
if (n % i == 0)
{
check++;
}
}
if (check == 2)
{
cout << n << " ";
return true;
}
return false;
}
int main ()
{
int l;
int u;
cin >> l >> u;
for (int i = u; i >= l; i--)
{
if(prime_bef(i))
break;
}
return 0;
}
Here is a simple and efficient way to check if the number is prime. I am checking if the number is prime and when it is true I am printing the number and breaking the loop so that only 1 number is printed. You can always remove the break statement and print all prime numbers in range.
#include<iostream>
using namespace std;
bool isPrime(int n){
if(n==2)return true;
if(n%2==0 || n==1)return false;
for(int i=3; i*i<=n; ++i){
if(n%i==0){
return false;
}
}
return true;
}
int main (){
int l, u;
cin>>l>>u;
for (int i = u; i >= l; i--){
if(isPrime(i)){
cout<<i<<"\n";
break;
}
}
return 0;
}
I'll give you a hint... while you are iteratively checking for the prime nature of the number, also check whether the last prime number calculated in the loop is greater than the max term of the range and break the loop when the condition becomes false.
Here a C++17 approach :
#include <cmath>
#include <iostream>
#include <vector>
// type to use for storing primes
using prime_t = unsigned long;
// there is a way to determine an upper bound to the number of primes smaller then a maximum number.
// See : https://primes.utm.edu/howmany.html
// this can be used to estimate the size of the output buffer (vector)
prime_t pi_n(const prime_t max)
{
prime_t pi_n{ max };
if (max > 10)
{
auto ln_n = std::log(static_cast<double>(max));
auto value = static_cast<double>(max) / (ln_n - 1.0);
pi_n = static_cast<prime_t>(value + 0.5);
}
return pi_n;
}
// Calculate prime numbers smaller then max
// https://en.wikipedia.org/wiki/Sieve_of_Eratosthenes
auto calculate_primes(const prime_t max)
{
std::vector<bool> is_primes(max, true);
// 0, 1 are not primes
is_primes[0] = false;
is_primes[1] = false;
// sieve
for (prime_t n = prime_t{ 2 }; n < prime_t{ max }; ++n)
{
if (is_primes[n])
{
auto n2 = n * n;
for (prime_t m = n2; m < max; m += n)
{
is_primes[m] = false;
}
}
}
// avoid unnecessary resizes of vector by pre-allocating enough entries to hold result
prime_t n{ 0 };
std::vector<prime_t> primes;
primes.reserve(pi_n(max));
// add all prime numbers found by the sieve
for (const auto is_prime : is_primes)
{
if (is_prime) primes.push_back(n);
n++;
}
return primes;
}
int main()
{
const prime_t max{ 50 };
auto primes = calculate_primes(max);
// max prime is last one in container
auto max_prime = primes.back();
std::cout << "maximum prime number smaller then " << max << ", is " << max_prime << std::endl;
}

Generate Partition of integer into k different integers (C++)

I have problem with the constraint
I have to partition it to "exact" k "different" integers
e.g. 10 = 1+2+7 -> valid
10 = 2+2+6 -> invalid
I don't want to print them, I want to store them in to vectors or something
I am thinking of recursive solution, but still can't come up with a efficient way to store them...(the solution I found can only print it)
And I think it should store in vector<vector>
the struct should be like this?
Partition(){
....
....
}
Partition_main(){
...
Partition()
....
}
In practice, the problem is to enumerate all the solutions.
This can be done by a DFS.
In the following code, the DFS is implemented with a help of a FIFO (i.e. a std::queue).
The little trick is, for a given candidate at a given step, to calculate the minimum
sum that can be obtained in the next steps.
If this minimum sum is larger than n, then we can stop the research in this direction.
#include <iostream>
#include <vector>
#include <queue>
#include <cassert>
struct Parti {
std::vector<int> v;
int sum = 0;
};
std::vector<std::vector<int>> get_partitions (int n, int k) {
std::vector<std::vector<int>> result;
std::queue<Parti> fifo;
Parti start;
fifo.push(start);
while (!fifo.empty()) {
Parti elt = fifo.front();
fifo.pop();
int sum = elt.sum;
int remain = k-elt.v.size();
if (remain == 1) {
int last = n - sum;
if (k > 1) assert (last > elt.v.back());
elt.v.push_back(last);
result.push_back (elt.v);
continue;
}
int i;
if (elt.v.size() == 0) i = 1;
else i = elt.v.back() + 1;
while (true) {
int min_sum = sum + remain*(2*i + remain - 1)/2;
if (min_sum > n) break;
Parti new_elt = elt;
new_elt.v.push_back(i);
new_elt.sum += i;
fifo.push (new_elt);
++i;
};
}
return result;
}
int main() {
int n = 15;
int k = 4;
auto res = get_partitions (n, k);
if (res.size() == 0) {
std::cout << "no partition possible\n";
return 0;
}
for (const auto& v: res) {
std::cout << n << " = ";
for (int i = 0; i < v.size(); ++i) {
std::cout << v[i];
if (i == v.size()-1) {
std::cout << "\n";
} else {
std::cout << " + ";
}
}
}
return 0;
}

Potential Overflow Comparing Sorts and Comparisons of Various Sorting Algorithms

Im currently working with a simple program which compares the number of comparisons and swaps for a number of common sorting methods and testing it on data sets of size 1000, 2000, 5000, 10000, 50000 and 100000. The program appears to be working perfectly up until 50000 values however for example, testing the insertion method with random values at 50000 values yielded a comparison count of 626936785 however at 100000 values the output was -1788822792. I have included the full code below, is there potentially some sort of overflow occuring as the number of swaps and comparisons grows too large to properly keep track of?
#include <cstdlib>
#include <getopt.h>
#include <iostream>
#include <string>
using namespace std;
long long comparisons;
long long swaps;
bool comp_less(int a, int b){
++comparisons;
return a < b;
}
void swap(int& a, int& b)
{
++swaps;
int t = a;
a = b;
b = t;
}
void selectionSort(int *first, int *last)
{
for(int *i = first; i < (last - 1); ++i){
int *min = i;
for(int *j = i + 1; j < last; ++j){
if(comp_less(*j, *min)){
min = j;
}
}
swap(*i, *min);
}
}
void insertionSort(int* first, int* last)
{
for (int *i = first + 1; i < last; ++i)
{
int temp = *i;
int *j;
for (j = i; j > first && comp_less(temp, *(j - 1)); --j)
{
swap(*j, *(j - 1));
}
*j = temp;
}
}
int *partition(int *first, int *last)
{
int *pivot = last - 1;
int *i = first;
int *j = last - 1;
for (;;)
{
while (comp_less(*i, *pivot) && i < last)
{
++i;
}
while (*j >= *pivot && j > first)
{
--j;
}
if (i >= j)
break;
swap(*i, *j);
}
swap(*(last - 1), *i);
return i;
}
void quickSort(int* first, int* last) {
{
if ((first - last) <= 1)
return;
int *pivot = partition(first, last);
quickSort(first, pivot);
quickSort(pivot + 1, last);
}
}
int main(int argc, char** argv)
{
string algorithm = "selection";
string dataset = "random";
for (int c; (c = getopt(argc, argv, "ravqsin")) != -1;) {
switch (c) {
case 'r':
dataset = "random";
break;
case 'a':
dataset = "sorted";
break;
case 'v':
dataset = "reverse";
break;
case 'q':
algorithm = "quicksort";
break;
case 's':
algorithm = "selection";
break;
case 'i':
algorithm = "insertion";
break;
case 'n':
algorithm = "none";
break;
}
}
argc -= optind;
argv += optind;
const int size = argc > 0 ? atoi(argv[0]) : 10000;
int* data = new int[size];
if (dataset == "sorted") {
for (int i = 0; i < size; ++i) {
data[i] = i;
}
}
else if (dataset == "reverse") {
for (int i = 0; i < size; ++i) {
data[i] = size - i - 1;
}
}
else if (dataset == "random") {
for (int i = 0; i < size; ++i) {
data[i] = rand() % size;
}
}
if (algorithm == "quicksort") {
quickSort(data, data + size);
}
else if (algorithm == "selection") {
selectionSort(data, data + size);
}
else if (algorithm == "insertion") {
insertionSort(data, data + size);
}
else if (algorithm=="none"){
cout<< "Oops!" <<'\n';
exit(1);
}
cout << "OK" << '\n';
cout << "Algorithm: " << algorithm << '\n';
cout << "Data set: " << dataset << '\n';
cout << "Size: " << size << '\n';
cout << "Comparisons: " << comparisons << '\n';
cout << "Swaps: " << swaps << '\n';
return 0;
}
is there potentially some sort of overflow occuring as the number of swaps and comparisons grows too large to properly keep track of?
The output seems to indicate that overflow is happening.
You can add a test to be sure.
void swap(int& a, int& b)
{
++swaps;
if ( swaps == std::numeric_limits<decltype(swaps)>::max() )
{
std::cout << "Number of swaps reached max value. Resetting it 0.\n";
swaps = 0;
}
int t = a;
a = b;
b = t;
}
You can change the type of swaps to unsigned long long to delay the arrival of the maximum value. It's a good practice to stll have that test though.
unsigned long long swaps = 0;

How to define the begin and the end value in C++?

I have an array like this:
600
250
600
600
600
I want to define the begin and the end indexes of this array where the value is greather than 500.
I made a variable which value is 2, because there are two section in my array where the values are greather than 500 (1-1 and 3-5).
So how could I output this:
1 1 3 5
The first 1 means the begin index is 1, the second 1 means the end index is also 1.
The 3 means the next section begin index where the value is greather than 500 is 3.
And the 5 means the end index of the second section is 5.
Using std:
std::vector<std::pair<std::size_t, std::size_t>>
compute_range_greater_than(const std::vector<int>& v, int threshold)
{
std::vector<std::pair<std::size_t, std::size_t>> res;
for (auto it = v.begin(); it != v.end(); /*Empty*/)
{
auto beg = std::find_if(it, v.end(), [=](int i) { return !(i < threshold); });
if (beg == v.end()) {
return res;
}
it = std::find_if(beg, v.end(), [=](int i) { return i < threshold; });
// using 1-index
res.push_back({1 + std::distance(v.begin(), beg), std::distance(v.begin(), it)});
}
return res;
}
Live Demo
Try this:
#include <iostream>
#include <vector>
int main()
{
std::vector<int> v;
v.push_back(10);
v.push_back(200);
v.push_back(170);
v.push_back(160);
v.push_back(20);
v.push_back(300);
v.push_back(12);
v.push_back(230);
std::vector<int> indexes;
int limit = 150;
bool started = false;
for (int i = 0; i < v.size(); i++)
{
int value = v[i];
if (value > limit && !started)
{
started = true;
indexes.push_back(i);
}
else if (value < limit && started)
{
started = false;
indexes.push_back(i - 1);
}
}
if (started)
indexes.push_back(v.size() - 1);
for (int i = 0; i < indexes.size(); i++)
{
if (i % 2 == 0)
std::cout << indexes[i] << "-";
else
std::cout << indexes[i] << "; ";
}
return 0;
}
Here limit is 150, but you can change it. Output is
1-3; 5-5; 7-7;
Good luck :)
You really should consider improving your question by better explaining what you want to do and by providing code that you already wrote (and if you didnt you should do it). However, I am in a good mood, so here you go:
#include <vector>
#include <iostream>
struct BeginAndEndIndex{
int begin;
int end;
BeginAndEndIndex(int begin) : begin(begin),end(begin) {}
};
typdef std::vector<BeginAndEndIndex> IndexV;
typdef std::vector<int> IV;
IndexV findBeginAndEndIndex(const IV& in,int threshold){
IndexV result;
bool isBiggerThanThreshold = false;
for (int i=0;i<in.size();i++){
if (!isBiggerThanThreshold) {
if (in[i]>threshold){
result.push_back(BeginAndEndIndex(i));
isBiggerThanThreshold = true;
}
} else {
if (in[i]<threshold){
result.back().end = i-1;
isBiggerThanThreshold = false;
}
}
}
if (isBiggerThanThreshold){result.back().end = in.size()-1;}
return result;
}
int main(void) {
IV foo {600,250,600,600,600};
IndexV bar = findBeginAndEndIndex(foo,500);
for (int i=0;i<bar.size();i++){
std::cout << bar[i].begin << " " << bar[i].end << std::endl;
}
return 0;
}
I am pretty sure that there is a more elegant way to implement it by using std::algorithms.
Just in straight C and not storing the indices anywhere, the following code produces the exact output that you are asking for:
#include <stdio.h>
int main(int argc, char **argv)
{
int values[] = {600, 250, 600, 600, 600};
int threshhold = 500;
int begIndex = -1;
int endIndex = -1;
int i;
for (i = 0; i < sizeof(values)/sizeof(values[0]); i++)
{
if (values[i] > threshhold)
{
if (begIndex < 0)
{
begIndex = i;
}
endIndex = i;
}
else if (begIndex >= 0)
{
printf("%d %d ", begIndex + 1, endIndex + 1);
begIndex = endIndex = -1;
}
}
if (begIndex >= 0)
printf("%d %d", begIndex + 1, endIndex + 1);
printf("\n");
return 0;
}
Keep in mind the arrays in C/C++ start at zero, not one. Changing the above code to store the begIndex and endIndex pairs should be a trivial operation.

Iterative equivalent a recursive algorithm

I'm trying to modify this program to their equivalent iterative but it becomes very difficult to me because as yet i'm still a newbie, it comes to an algorithm that decomposes a number into its prime factors, here the code:
#include <iostream>
#include <map>
#include <cmath>
std::map< int, std::pair<int, int> > decompositions;
void descompon_number(int num, int root, int i = 2 )
{
auto iterator = decompositions.find(num);
if (iterator == decompositions.end())
{
if (num > 1 && i <= root)
{
if (num % i == 0)
{
int n = num / i;
decompositions[num] = std::make_pair(i, n);
descompon_number(n, (int) std::sqrt(n));
}
else
descompon_number(num, root, i + 1);
}
else
decompositions[num] = std::make_pair(num, 1);
}
}
void show(int num, int factor, int exponent, int see)
{
auto pair = decompositions[num];
if (num <= 1 || factor != pair.first)
{
if (see)
std::cout << factor;
if (exponent > 1 && see)
std::cout << "^" << exponent;
if (pair.first > 1 && see)
std::cout << " * ";
exponent = 0;
}
if (num > 1)
show(pair.second, pair.first, exponent + 1, see);
}
void descompon(int a, int b, int see)
{
if (a <= b)
{
descompon_number(a, (int) std::sqrt(a));
if (see)
std::cout << a << " = ";
show(a, decompositions[a].first, 0, see);
if (see)
std::cout << std::endl;
descompon(a + 1, b, see);
}
}
int main()
{
descompon(2, 100, 1);
return 0;
}
Someone can help me out with this
Finding prime factors iteratively is not very complicated.
Here's the pseudocode how to do this.
Let P be a list of the first n prime numbers, such that Pn <= sqrt(m).
array findPrimeFactors(m)
answer = new array
for p in P
while m can be divided by p
m = m / p
answer.append(p)
if m == 1
break
return answer
Note: empty array is returned if m is prime.
You can use an erastotenes' sieve to compute prime numbers, and later you can use the algorithm posted by popovitsj.
The following code can be optimized, but its main purpose is to show you how to proceed.
Complete example:
#include <iostream>
#include <vector>
using namespace std;
// Returns a vector containing the first <number> prime numbers
vector<int> erastotenes_sieve(int number)
{
vector<int> result;
int *sieve = new int[number];
for (int i = 0; i < number; i++) sieve[i] = 0;
// Traverse the sieve marking multiples.
for (int i = 2; i < number / 2; i++)
for (int j = i + i; j < number; j += i)
sieve[j] = 1;
// Collect unaffected indexes, those are prime numbers.
for (int i = 2; i < number; i++)
if (!sieve[i])
result.push_back(i);
delete [] sieve;
return result;
}
vector<int> descompon_number(int number)
{
vector<int> result;
if (number == 1 || number == 0)
{
result.push_back(number);
return result;
}
for (int &prime : erastotenes_sieve(number))
{
while (number % prime == 0 && number != 1)
{
number /= prime;
result.push_back(prime);
}
}
return result;
}
int main()
{
for (auto &i : descompon_number(20))
{
cout << i << endl;
}
return 0;
}