I used a for loop to find antilog of the given number.
int g = 0, m, diff = 10;
for(j = 0; g <= diff; j++)
{
g = pow(2, j);
}
m = j - 2;
cout << m;
It gives the power of 2 for which g is the number just less than diff.
I tried the base change theorem of log to find the antilog of the number something like this:
m = log(diff) / log(2);
without the for loop, but in this case whenever there is a number that is an exact multiple of 2s for example 8, then it gives 2 as the answer and not 3.
And using for loop for doing so is in a program is exceeding the time limit.
Is there a shorter and reliable way to do so?
Here is a fun solution without looping:
function antilog(int input) {
int pow2 = input - 1;
pow2 |= pow2 >> 16; // turn on all bits < MSB
pow2 |= pow2 >> 8;
pow2 |= pow2 >> 4;
pow2 |= pow2 >> 2;
pow2 |= pow2 >> 1;
pow2++; // get least pow2 >= input
return // construct binary offset of pow2 bit
((pow2 & 0xffff0000) != 0) << 4
| ((pow2 & 0xff00ff00) != 0) << 3
| ((pow2 & 0xf0f0f0f0) != 0) << 2
| ((pow2 & 0xcccccccc) != 0) << 1
| ((pow2 & 0xaaaaaaaa) != 0);
}
The latter half of which was adapted from some part of the bit twiddling hacks. (Knowing the source, there is probably some other function faster than this doing what you've asked.
Solutions aside, it should be noted that what particularly is causing your solution to be slow is the repeated calls to pow, which is a relatively expensive function. Because you are doing integer arithmetic (and what's more, multiplying by 2, every computer's favorite number), it is much more efficient to write your loop as the following:
int g=1,m,diff=10;
for(j = 0; g <= diff && g <<= 1; j++) /* empty */;
m=j-2;
cout<<m;
Which is quite the hack. int g=1 initializes g to the value it takes on the first time the code executes the body of the loop you've written. The loop conditions g <= diff && g <<= 1 evaluates to g <= diff. (Notice that this is a problem if diff >= 1 << (8 * sizeof(int) - 2), the greatest power of two we can store in an int). The empty statement simply allows us to have a well-formed for statement the compiler (mostly) won't complain about.
Use integer arithmetic and build up the power incrementally. For example:
#include <iostream>
using namespace std;
int main()
{
for (int diff = 1; diff < 129; diff += 5)
{
int p = 1;
int j;
for (j = 0; p <= diff; j++)
{
p *= 2;
}
cout << diff << " = " << (j - 1) << '\n';
}
}
Sample output:
1 = 0
6 = 2
11 = 3
16 = 4
21 = 4
26 = 4
31 = 4
36 = 5
41 = 5
46 = 5
51 = 5
56 = 5
61 = 5
66 = 6
71 = 6
76 = 6
81 = 6
86 = 6
91 = 6
96 = 6
101 = 6
106 = 6
111 = 6
116 = 6
121 = 6
126 = 6
An alternative test strategy tests boundaries:
#include <iostream>
using namespace std;
int main()
{
int diff[] = { 1, 2, 3, 4, 5, 7, 8, 9, 15, 16, 17, 31, 32, 33, 63, 64, 65 };
int size = sizeof(diff) / sizeof(diff[0]);
for (int i = 0; i < size; i++)
{
int p = 1;
int j;
for (j = 0; p <= diff[i]; j++)
{
p *= 2;
}
cout << diff[i] << " = " << (j - 1) << '\n';
}
}
Sample output:
1 = 0
2 = 1
3 = 1
4 = 2
5 = 2
7 = 2
8 = 3
9 = 3
15 = 3
16 = 4
17 = 4
31 = 4
32 = 5
33 = 5
63 = 5
64 = 6
65 = 6
Clearly, the inside of the test loop should be wrapped into an antilog2 function — except for the printing operation.
Related
I want to fill a 8 x 8 matrix with values in a special order (see example below), but I don´t know how to do that. Each numer stands for the ordering number: For example: #3 in the matrix is the third value of a e.g. a measurment I want to add.
The Order should be:
1 2 5 6 17 18 21 22
3 4 7 8 19 20 23 24
9 10 13 14 25 26 29 30
11 12 15 16 27 28 31 32
33 34 37 38 49 50 53 54
35 36 39 40 51 52 55 56
41 42 45 46 57 58 61 62
43 44 47 48 59 60 63 64
Does anybody knows an algorithmus to do that?
I have tried this, but that´s not a good way to to it, and it´s not working for the whole matrix
int b= 0, ii = 0, a = 0, iii = 0
i are different measurement values
and now a for loop
if (ii == 1)
{
b++;
}
if (ii == 2)
{
a++, b--;
}
if (ii == 3)
{
b ++;
}
tempMatrix[a][b] = i;
cout << "TempMatrix " << tempMatrix[a][b] << " a " << a << " b " << b << endl;
if (ii == 3)
{
ii = -1;
a --;
b ++;
}
if (iii == 7)
{
a = a + 2;
b = 0;
iii = -1;
}
Use recursion:
#include <iostream>
using namespace std;
void f(int a[8][8], int current, int x, int y, int size) {
if (size == 1) {
a[x][y] = current;
return;
} else {
size /= 2;
int add_for_each_square = size * size;
f(a, current, x, y, size);
f(a, current + add_for_each_square, x, y + size, size);
f(a, current + 2 * add_for_each_square, x + size, y, size);
f(a, current + 3 * add_for_each_square, x + size, y + size, size);
}
}
int main() {
int a[8][8];
f(a, 1, 0, 0, 8);
for (int i = 0; i < 8; ++i) {
for (int j = 0; j < 8; ++j) {
cout << a[i][j] << " ";
}
cout << endl;
}
}
If the matrix will always be a fixed size, then you can generate two lookup tables for row and column indexes into the matrix. Then, just pass your index through these tables to get the desired positions in the matrix.
const auto MATRIX_SIZE = 8;
const std::array<int, MATRIX_SIZE*MATRIX_SIZE> row_lookup = {{...}}; //put pre-computed values here.
const std::array<int, MATRIX_SIZE*MATRIX_SIZE> col_lookup = {{...}};
for(size_t i = 0; i < MATRIX_SIZE * MATRIX_SIZE; i++)
{
auto val = get_coefficient(i);
auto row = row_lookup[i];
auto col = col_lookup[i];
mat[col][row] = val;
}
I am not that skilled or advanced in C++ and I have trouble solving a problem.
I know how to do it mathematically but I can't write the source code, my algorithm is wrong and messy.
So, the problem is that I have to write a code that reads a number ( n ) from the keyboard and then it has to find a sum that is equal to n squared ( n ^ 2 ) and the number of sum's elements has to be equal to n.
For example 3^2 = 9, 3^2 = 2 + 3 + 4, 3 elements and 3^2 is 9 = 2 + 3 + 4.
I had several attempts but none of them were successful.
I know I'm borderline stupid but at least I tried.
If anyone has the time to look over this problem and is willing to help me I'd be very thankful.
1
#include <iostream>
#include <list>
#include <algorithm>
using namespace std;
int main()
{
//1,3,5,7,9,11,13,15,17,19,21,23,25,27..
int n;
list<int> l;
cin >> n;
if ( n % 2 == 0 ){
cout << "Wrong." << endl;
}
for ( int i = 1; i <= 99;i+=2){
l.push_back(i);
}
//List is full with 1,3,5,7,9,11,13,15,17,19,21,23,25,27..
list<int>::iterator it = find(begin(l),end(l), n);
}
2
#include <iostream>
#include <bits/stdc++.h>
using namespace std;
int main()
{
// 3^2 = 2 + 3 + 4
// 7^2 = 4 + 5 + 6 + 7 + 8 + 9 + 10
int n;
int numbers[100];
for (int i = 0; i <= 100; i++){
numbers[i] = i;
}
cin >> n;
int requiredSum;
requiredSum = n * n;
//while(sum < requiredSum){
// for(int i = 1; i < requiredSum; i++){
// sum += i;
// sumnums.push_back(sum);
// }
//}
int sum = 0;
std::vector<int> sumnums;
while(sum < requiredSum){
for(int i = 1; i < requiredSum; i++){
sum += i;
sumnums.push_back(sum);
}
}
for(int i=0; i<sumnums.size(); ++i)
std::cout << sumnums[i] << ' ';
}
Update:
The numbers of the sum have to be consecutive numbers.Like 3 * 3 has to be equal to 2 + 3 + 4 not 3 + 3 + 3.
So, my first try was that I found a rule for each sum.
Like 3 * 3 = 2 + 3 + 4, 5 * 5 = 3 + 4 + 5 + 6 + 7, 7 * 7 = 4 + 5 + 6 + 7 + 8 + 9 + 10.
Every sum starts with the second element of the previous sum and continues for a number of elements equal to n - 1, like 3 * 3 = 2 + 3 + 4, 5 * 5 , the sum for 5 * 5 starts with 3 + another 4 elements.
And another algorithm would be #molbdnilo 's, like 3 * 3 = 3 + 3 + 3 = 3 + 3 + 3 - 1 + 1, 3 * 3 = ( 3 - 1 ) + 3 + ( 3 + 1 ), but then 5 * 5 = (5 - 2) + ( 5 - 1 ) + 5 + 5 + 1 + 5 + 2
Let's do a few special cases by hand.
(The division here is integer division.)
3^2: 9
2 + 3 + 4 = 9
x-1 x x+1
1 is 3/2
5: 25
3 + 4 + 5 + 6 + 7 = 25
x-2 x-1 x x+1 x+2
2 is 5/2
7: 49
4 + 5 + 6 + 7 + 8 + 9 + 10
x-3 x-2 x-1 x x+1 x+2 x+3
3 is 7/2
It appears that we're looking for the sequence from n - n / 2 to n + n / 2.
(Or, equivalently, n / 2 + 1 to n / 2 + n, but I like symmetry.)
Assuming that this is correct (the proof left as an exercise ;-):
int main()
{
int n = 0;
std::cin >> n;
if (n % 2 == 0)
{
std::cout << "Must be odd\n";
return -1;
}
int delta = n / 2;
for (int i = n - delta; i <= n + delta; i++)
{
std::cout << i << " ";
}
std::cout << std::endl;
}
If there is not constraints on what are the elements forming the sum, the simplest solution is just to sum up the number n, n times, which is always n^2.
int main()
{
int n;
cout<<"Enter n: ";
cin >> n;
for(int i=0; i<n-1; i++){
cout<<n<<"+";
}
cout<<n<<"="<<(n*n);
return 0;
}
Firstly, better use std::vector<> than std::list<>, at least while you have less than ~million elements (it will be faster, because of inside structure of the containers).
Secondly, prefer ++i usage, instead of, i++. Specially in situation like that
...for(int i = 1; i < requiredSum; i++)...
Take a look over here
Finally,
the only error you had that you were simply pushing new numbers inside container (std::list, std::vector, etc.) instead of summing them, so
while(sum < requiredSum){
for(int i = 1; i < requiredSum; i++){
sum += i;
sumnums.push_back(sum);
}
change to
// will count our numbers
amountOfNumbers = 1;
while(sum < requiredSum && amountOfNumber < n)
{
sum += amountOfNumbers;
++amountOfNumbers;
}
// we should make -1 to our amount
--amountOfNumber;
// now let's check our requirements...
if(sum == requiredSum && amountOfNumbers == n)
{
cout << "Got it!";
// you can easily cout them, if you wish, because you have amountOfNumbers.
// implementation of that I am leaving for you, because it is not hard ;)
}
else
{
cout << "Damn it!;
}
I assumed that you need sequential sum of numbers that starts from 1 and equals to n*n and their amount equils to n.
If something wrong or need explanation, please, do not hesitate to contact me.
Upd. amountOfNumber < n intead <=
Also, regarding "not starting from 1". You said that you know how do it on paper, than could you provide your algorithm, then we can better understand your problem.
Upd.#2: Correct and simple answer.
Sorry for such a long answer. I came up with a great and simple solution.
Your condition requires this equation x+(x+1)+(x+2)+... = n*n to be true then we can easily find a solution.
nx+ArPrg = nn, where is
ArPrg - Arithmetic progression (ArPrg = ((n-1)*(1+n-1))/2)
After some manipulation with only unknown variable x, our final equation will be
#include <iostream>
int main()
{
int n;
std::cout << "Enter x: ";
std::cin >> n;
auto squareOfN = n * n;
if (n % 2 == 0)
{
std::cout << "Can't count this.\n";
}
auto x = n - (n - 1) / 2;
std::cout << "Our numbers: ";
for (int i = 0; i < n; ++i)
std::cout << x + i << " ";
return 0;
}
Math is cool :)
I've solved this c++ exercise by brute force checking all combinations in my own way. I'm wondering if there's a better, more elegant, and/or shorter/faster solution?
Here's the translated problem: ("nothing" refers to concatenation)
/*
Write a program that outputs the number of possible ways to:
Combine ascending digits 1...9 using +, -, and "nothing" to get the result of input x.
Example:
Input: 100
Output: 11
(That's because we have 11 ways to get 100:)
123 - 45 - 67 + 89 = 100
123 + 4 - 5 + 67 - 89 = 100
123 + 45 - 67 + 8 - 9 = 100
123 - 4 - 5 - 6 - 7 + 8 - 9 = 100
12 - 3 - 4 + 5 - 6 + 7 + 89 = 100
12 + 3 + 4 + 5 - 6 - 7 + 89 = 100
12 + 3 - 4 + 5 + 67 + 8 + 9 = 100
1 + 23 - 4 + 56 + 7 + 8 + 9 = 100
1 + 2 + 34 - 5 + 67 - 8 + 9 = 100
1 + 23 - 4 + 5 + 6 + 78 - 9 = 100
1 + 2 + 3 - 4 + 5 + 6 + 78 + 9 = 100
*/
Here's my solution:
#include<iostream>
using namespace std;
int power(int a, int n) {
int rez = 1;
for (int i = 0; i<n; i++) {
rez *= a;
}
return rez;
}
void makeCombo(int c, int C[]) {
int digit = 0;
while (c != 0) {
C[digit] = c % 3;
c /= 3;
digit++;
}
}
bool testCombo(int C[], int x) {
int a = 9;
int sum = 0;
int concatenator = 0;
int concatenation = 0;
for (int i = 0; i < 8; i++) {
if (C[7-i] == 0) {
concatenator += a*power(10,concatenation);
concatenation++;
} else if (C[7-i] == 1) {
sum += a*power(10,concatenation);
sum += concatenator;
concatenator = 0;
concatenation = 0;
} else if (C[7-i] == 2) {
sum -= a*power(10,concatenation);
sum -= concatenator;
concatenator = 0;
concatenation = 0;
}
a--;
}
sum += a*power(10,concatenation);
sum += concatenator;
return (sum == x);
}
int main() {
int x, count = 0;
cin >> x;
int combo = 0;
int C[8] = {0,0,0,0,0,0,0,0};
while (combo < power(3,8)) {
makeCombo(combo, C);
if (testCombo(C, x)) { count++; }
combo++;
}
cout << count << endl;
return 0;
}
I've heard that there's a short recursive solution possible and I'm wondering how you would solve this like that, and/or is there an even "better" solution, and how can you "see it"?
The trick to all such challenges is not to do the same work twice. That is to say, 12345678-9, 12345678+9 and 12345678 * 10 + 9 all share the same logic to evaluate 12345678.
There are many ways in which this can be achieved, but a recursive solution is reasonable enough.
Update: This is not my solution but is the recursive one I've heard about. Way faster than my initial solution, and very elegant.
#include <iostream>
using namespace std;
int x;
int count(int n, int num, int sum) {
if (n == 9) { return sum + num == x; }
int next = n + 1;
int counter = 0;
counter += count(next, next, sum + num);
counter += count(next, -next, sum + num);
num *= 10;
if (num < 0)
num -= next;
else
num += next;
counter += count(next, num, sum);
return counter;
}
int main(int x) {
cin >> x;
cout << count(1, 1, 0) << endl;
return 0;
}
Here you can find a full working recursive sample:
I wrote two recursive methods,
test_combo - to evaluate the combo
make_combo - to generate the combo
#include<iostream>
using namespace std;
//recursivly evaluate the combo.
int test_combo( const std::string& s, int sign)
{
size_t next_pos = s.find_first_of("+-");
int sum = sign * strtol(s.substr(0,next_pos).c_str(),0,0);;
if(next_pos == string::npos)
{
return sum;
}
else
{
char op = s[next_pos];
switch(op)
{
case '+':
sum+=test_combo(s.substr(next_pos+1),1);
return sum;
case '-':
sum+=test_combo(s.substr(next_pos+1),-1);
return sum;
}
}
}
//recursivly build the combo.
void make_combo(int n, const std::string& s )
{
if(n==10)
{
int sum=test_combo(s,1);
if(sum==100)
cout<<s<<"="<<sum<<endl;
}
else
{
char next_digit = '0'+n; //we have 3 options:
make_combo(n+1,s+next_digit); //append next digit with no op
make_combo(n+1,s+'+'+next_digit); //append next digit with + op
make_combo(n+1,s+'-'+next_digit); //append next digit with - op
}
}
int main()
{
make_combo(2,"1");//string always start with a '1'
return 0;
}
I want to print the following number sequence:
1 2 3 6 7 8 11 12 13 16 17 18...
It prints three positive integers then skips two following values and then repeats the process.
Here's a simple way just using a for loop statement:
for (int i = 1; i < 100; i += ((i%5) == 3) ? 3 : 1)
{
// ...
}
As pointed out by Franck you can simply use the modulo operator.
The modulo operator gives you the rest of a division as a result.
0 / 10 = 0; 0 % 10 = 0;
10 / 10 = 1; 10 % 10 = 0;
11 / 10 = 1; 11 % 10 = 1;
12 / 10 = 1; 12 % 10 = 2;
20 / 10 = 2; 20 % 10 = 0;
21 / 10 = 2; 21 % 10 = 1;
27 / 10 = 2; 21 % 10 = 7;
0 % 3 = 0;
1 % 3 = 1;
2 % 3 = 2;
3 % 3 = 0;
4 % 3 = 1;
5 % 3 = 2;
6 % 3 = 0;
7 % 3 = 1;
8 % 3 = 2;
9 % 3 = 0;
...
From your example I assume that you want to skip values ending on 4 or 9.
You have 2 possibilities to archive this:
use % 10 and check the result for being either 4 or 9
use % 5 and check the result for being either 4
The result would look something like this:
for (int i=1; i<=100; i++)
{
if(i%5 == 4) continue; //Skip
std::cout << i << " ";
}
It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 10 years ago.
It was given by my colleague, to print values 1 2 3 4 .... 15 15 ..... 4 3 2 1 with only one for loop, no functions, no goto statements and without the use of any conditional statements or ternary operators.
So I employed typecasting to solve it, but it is not an exact solution since 15 is not printed twice.
int main()
{
int i, j;
for(i = 1, j = 0;j < 29;j++, i += int(j/15)*-2 + 1)
cout<<i<<endl;
}
Output: 1 2 3 4 ... 15 14 13 .... 2 1
Any alternative solutions?
You can loop from 1 to 30, then use the fact that (i/16) will be "0" for your ascending part and "1" for your descending part.
for (int i = 1; i < 31; i++)
{
int number = (1-i/16) * i + (i/16) * (31 - i);
printf("%d ", number);
}
for (int i=0; i<1; i++)
{
std::cout << "1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1"
}
How about this:
std::string first;
std::string second;
for ( int i = 1 ; i <= 15 ; i++ )
{
std::ostringstream s;
s << i;
first += s.str();
second = s.str() + second;
}
std::cout << first << second;
Alternative:
static int bla[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1};
for (int i = 0; i < 30; i++)
{
printf("%d\n", bla[i]);
}
The good one, it is faster in execution as compare to all ...
XOR bit #4 (i.e. j & 0x10) with bits 3:0. You will need to find a way to "repeat" that bit into 4 positions.
for (int i=1;i<31;++i)
{
cout<<(((i<<27>>31|i)&(~i<<27>>31|~i))&15)<<" ";
}
#include <iostream>
int main()
{
for(int i = 1; i < 31; i++) std::cout << ((i/16)-1)*-i+(i/16)*(i^0x1F) << " ";
std::cout << std::endl;
}
const int N = 15;
for(int i = 1; i <= 2 * N; ++i)
printf("%d ", i + (i > N) * (1 + 2 * (N - i)));
I have seen many complicated answers, yet no one exploited the symmetry as is.
std::string head = "1";
std::string tail = "1";
for (unsigned i = 2; i != 16; ++i) {
std::string const elem = boost::lexical_cast<std::string>(i);
head = head + " " + elem;
tail = elem + " " + tail;
}
std::cout << head << " " << tail << "\n";
In action at ideone (minus lexical_cast):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1
It works simply, and for any magnitude of the upper bound (as far as your computer as enough memory).
for (int i = 1; i < 30; i++)
printf("%d\n", (-((i & 16) >> 4) + 1) * i + ((i & 16) >> 4) * (14 - (i & 15)));
int main()
{
for(int i = 15, j = 30, k = 15; i <= 30; i++, j--, k -= 2)
{
cout << (j - i) * (k % 2) << endl << (j - i - 1) * (k % 2) << endl;
}
return 0;
}
This what I came up with. It goes the other way, ie: 15 -> 0 -> 15. Just more food for thought. Uses mod and k to work out if negative number. I - J meet in the middle. Its by no means perfect and there are some other better answers.