package main
import (
"fmt"
"math"
)
func pow(x, n, lim float64) float64 {
if v := math.Pow(x, n); v < lim {
return v
} else {
fmt.Printf("%g >= %g\n", v, lim)
}
// can't use v here, though
return lim
}
func main() {
fmt.Println(
pow(3, 2, 10),
pow(3, 3, 20),
)
}
this code is from "A Tour of GO"
Expectation:
9
10
27 >= 20
20
Output:
27 >= 20
9 20
I don't understand about this. help me!
Println function will output of both pow functions in a single line and then it adds \n after returning from Println function.
package main
import (
"fmt"
"math"
)
func pow(x, n, lim float64) float64 {
if v := math.Pow(x, n); v < lim {
return v
}else {
fmt.Printf("%g >= %g\n", v, lim)
}
// can't use v here, though
return lim
}
func main() {
fmt.Println(pow(3, 2, 10))
fmt.Println(pow(3, 3, 20))
}
Playground
And 10 which is the limit in first if case will never print.
9
10
27 >= 20
20
Because pow function is returned before in the function.
Arguments are evaluated first, and the Println inside pow is in an if block so it runs conditionally.
First, the arguments to the Println in main() are evaluated. The first call to pow results in 9 which is less than lim, so pow itself prints nothing and returns 9. The second call to pow results in 27 which is greater than lim, so pow prints 27 >= 20 and returns 20. Then, with the arguments handled, the call to Println in main is executed, printing 9 20.
Related
Let n=5, then for matrix
1 2 3 4 5
16 17 18 19 6
15 24 25 20 7
14 23 22 21 8
13 12 11 10 9
then sum of diagonal elements is:
=1+17+25+21+9+5+19+23+13
Sum for n=15?
One way is to make the spiral matrix and then by a loop, we get the answer, but its time and space complexity is large.
Like this https://www.geeksforgeeks.org/sum-diagonals-spiral-odd-order-square-matrix/
but the problem here starts 1 from the center.
Consider the outer "shell" of the matrix. The sum of the values at the four vertices, given a size of n (5 in your example) and a starting value of s (1 in your example) is
s + (s + (n-1)) + (s + (n-1)*2) + (s + (n-1)*3) = 4*s + (n - 1)*6
The same applies to the inner values, once updated n and s:
s = s + 4 * (n - 1)
n = n - 2
If n becomes less then 2, well, either we have the central element or nothing (n is even).
Based on Bob_'s answer, Here is a recursive code in CPP as requested by OP
int shellcalc(int n,int s){
if(n==1)
return s;
else if(n==0)
return 0;
else
{
int sum=4*s+(n-1)*6;
int snew=s+4*(n-1);
int nnew=n-2;
return sum+shellcalc(nnew,snew);
}
}
try it out here https://rextester.com/FLJD46264
Python - https://rextester.com/MDMV32855
int gcd (int a, int b)
{
if (b == 0)
return a;
if (a == 0)
return b;
return gcd (b, a % b);
}
What is the result of gcd (5, 15)?
I ended up getting 15 but I'm not sure if it's correct, all the loops are confusing me.
Here are the recursive calls that are made in order
gcd(5, 15)
gcd(5, 5) # Because 5 % 15 = 5
gcd(5, 0)
So the return value of gcd(5, 15) is 5
Let a = 5 and b = 15;
In the first loop we check if either of a and b are 0 , they are not so we call
gcd(15,0); because 5%15 = 5.
So a = 15 , b = 5.
we call gcd(5,15%5) i.e gcd(5,0).
The answer is 5;
See the recursive calls in this way:
gcd(5, 15)
|
gcd(15, 5 (as 5 % 15) ) // 'b' simply takes position of 'a'
|
gcd(5, 0 (as 15 % 5) )
|
if (b == 0) return a; // a is 5, so returned value is 5.
return 5;
return 5;
return 5;
gcd (5, 15) returns gcd (15, 5 % 15) == gcd (15, 5), which in turn returns gcd (5, 5 % 15) == gcd (5, 5), which returns gcd (5, 5 % 5) == gcd (5, 0) == 5. So you should be returning 5.
A good way to see what's happening is to insert printf statements at the beginning of the function and at the two final return points showing what happens:
gcd(5,15)
gcd(15,5)
gcd(5,0)
5
An example Python implementation:
def gcd (a, b):
print("gcd({0},{1})".format(a, b))
if b == 0:
print(a)
return a
if a == 0:
print(b)
return b
return gcd (b, a % b)
gcd(5,15)
int sum_down(int x)
{
if (x >= 0)
{
x = x - 1;
int y = x + sum_down(x);
return y + sum_down(x);
}
else
{
return 1;
}
}
What is this smallest integer value of the parameter x, so that the returned value is greater than 1.000.000 ?
Right now I am just doing it by trial and error and since this question is asked via a paper format. I don't think I will have enough time to do trial and error. Question is, how do you guys visualise this quickly such that it can be solved easily. Thanks guys and I am new to programming so thanks in advance!
The recursion logic:
x = x - 1;
int y = x + sum_down(x);
return y + sum_down(x);
can be simplified to:
x = x - 1;
int y = x + sum_down(x) + sum_down(x);
return y;
which can be simplified to:
int y = (x-1) + sum_down(x-1) + sum_down(x-1);
return y;
which can be simplified to:
return (x-1) + 2*sum_down(x-1);
Put in mathematical form,
f(N) = (N-1) + 2*f(N-1)
with the recursion terminating when N is -1. f(-1) = 1.
Hence,
f(0) = -1 + 2*1 = 1
f(1) = 0 + 2*1 = 2
f(2) = 1 + 2*2 = 5
...
f(18) = 17 + 2*f(17) = 524269
f(19) = 18 + 2*524269 = 1048556
Your program can be written this way (sorry about c#):
public static void Main()
{
int i = 0;
int j = 0;
do
{
i++;
j = sum_down(i);
Console.Out.WriteLine("j:" + j);
} while (j < 1000000);
Console.Out.WriteLine("i:" + i);
}
static int sum_down(int x)
{
if (x >= 0)
{
return x - 1 + 2 * sum_down(x - 1);
}
else
{
return 1;
}
}
So at first iteration you'll get 2, then 5, then 12... So you can neglect the x-1 part since it'll stay little compared to the multiplication.
So we have:
i = 1 => sum_down ~= 4 (real is 2)
i = 2 => sum_down ~= 8 (real is 5)
i = 3 => sum_down ~= 16 (real is 12)
i = 4 => sum_down ~= 32 (real is 27)
i = 5 => sum_down ~= 64 (real is 58)
So we can say that sum_down(x) ~= 2^x+1. Then it's just basic math with 2^x+1 < 1 000 000 which is 19.
A bit late, but it's not that hard to get an exact non-recursive formula.
Write it up mathematically, as explained in other answers already:
f(-1) = 1
f(x) = 2*f(x-1) + x-1
This is the same as
f(-1) = 1
f(x+1) = 2*f(x) + x
(just switched from x and x-1 to x+1 and x, difference 1 in both cases)
The first few x and f(x) are:
x: -1 0 1 2 3 4
f(x): 1 1 2 5 12 27
And while there are many arbitrary complicated ways to transform this into a non-recursive formula, with easy ones it often helps to write up what the difference is between each two elements:
x: -1 0 1 2 3 4
f(x): 1 1 2 5 12 27
0 1 3 7 15
So, for some x
f(x+1) - f(x) = 2^(x+1) - 1
f(x+2) - f(x) = (f(x+2) - f(x+1)) + (f(x+1) - f(x)) = 2^(x+2) + 2^(x+1) - 2
f(x+n) - f(x) = sum[0<=i<n](2^(x+1+i)) - n
With eg. a x=0 inserted, to make f(x+n) to f(n):
f(x+n) - f(x) = sum[0<=i<n](2^(x+1+i)) - n
f(0+n) - f(0) = sum[0<=i<n](2^(0+1+i)) - n
f(n) - 1 = sum[0<=i<n](2^(i+1)) - n
f(n) = sum[0<=i<n](2^(i+1)) - n + 1
f(n) = sum[0<i<=n](2^i) - n + 1
f(n) = (2^(n+1) - 2) - n + 1
f(n) = 2^(n+1) - n - 1
No recursion anymore.
How about this :
int x = 0;
while (sum_down(x) <= 1000000)
{
x++;
}
The loop increments x until the result of sum_down(x) is superior to 1.000.000.
Edit : The result would be 19.
While trying to understand and simplify the recursion logic behind the sum_down() function is enlightening and informative, this snippet tend to be logical and pragmatic in that it does not try and solve the problem in terms of context, but in terms of results.
Two lines of Python code to answer your question:
>>> from itertools import * # no code but needed for dropwhile() and count()
Define the recursive function (See R Sahu's answer)
>>> f = lambda x: 1 if x<0 else (x-1) + 2*f(x-1)
Then use the dropwhile() function to remove elements from the list [0, 1, 2, 3, ....] for which f(x)<=1000000, resulting in a list of integers for which f(x) > 1000000. Note: count() returns an infinite "list" of [0, 1, 2, ....]
The dropwhile() function returns a Python generator so we use next() to get the first value of the list:
>>> next(dropwhile(lambda x: f(x)<=1000000, count()))
19
package main
import (
"fmt"
"runtime"
"sync"
)
var wg sync.WaitGroup
func alphabets() {
for char := 'a'; char < 'a'+26; char++ {
fmt.Printf("%c ", char)
}
wg.Done() //decrement number of goroutines to wait for
}
func numbers() {
for number := 1; number < 27; number++ {
fmt.Printf("%d ", number)
}
wg.Done()
}
func main() {
runtime.GOMAXPROCS(2)
wg.Add(2) //wait for two goroutines
fmt.Println("Starting Go Routines")
go alphabets()
go numbers()
fmt.Println("\nWaiting To Finish")
wg.Wait() //wait for the two goroutines to finish executing
fmt.Println("\nTerminating Program")
}
I expect the output to be mixed up(for lack of a better word), but instead; a sample output is:
$ go run parallel_prog.go
Starting Go Routines
Waiting To Finish
a b c d e f g h i j k l m n o p q r s t u v w x y z 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
Terminating Program
What I'm I missing?
Thanks,
You're missing nothing. It's working. The calls aren't showing up "interlaced" (mixed up) not because they're not being parallelized, but because they're happening really fast.
You can easily add some calls to time.Sleep to see the parallelization better. By sleeping, we know 100% that printing alphabets and numbers should be interlaced.
Your program with Sleep calls to "force" interlacing
package main
import (
"fmt"
"sync"
"time"
)
var wg sync.WaitGroup
func alphabets() {
defer wg.Done()
for char := 'a'; char < 'a'+26; char++ {
fmt.Printf("%c ", char)
time.Sleep(time.Second * 2)
}
}
func numbers() {
defer wg.Done()
for number := 1; number < 27; number++ {
fmt.Printf("%d ", number)
time.Sleep(time.Second * 3)
}
}
func main() {
fmt.Println("Starting Go Routines")
wg.Add(2)
go alphabets()
go numbers()
fmt.Println("\nWaiting To Finish")
wg.Wait()
fmt.Println("\nTerminating Program")
}
Note
You probably already know this, but setting GOMAXPROCS doesn't have any effect on whether or not this example is executed in parallel, just how many resources it consumes.
The GOMAXPROCS setting controls how many operating systems threads attempt to execute code simultaneously. For example, if GOMAXPROCS is 4, then the program will only execute code on 4 operating system threads at once, even if there are 1000 goroutines. The limit does not count threads blocked in system calls such as I/O.
Source: Go 1.5 GOMAXPROCS Default
Are you using the Go playground by any chance? When I run your code locally, I get:
Starting Go Routines
Waiting To Finish
1 2 3 4 5 6 7 8 9 10 11 12 a 13 14 15 16 17 b 18 19 c 20 21 d 22 23 e 24 25 f 26 g h i j k l m n o p q r s t u v w x y z
Terminating Program
The playground is deterministic in nature. Goroutines don't yield as often and don't run in multiple threads.
So I'm trying to make a graphing application, and I'm using Desmos as a base for that.
The thing I'm struggling with is the way Desmos handles the subdivisions of the axes. When you zoom in or out the scales are always on "easy" simple numbers like 5, 100, 1000 etc. So my question is: how does one go about simplifying their scale with any level of zoom?
BTW: Using C++
I was going to write a description of how to do this in general, but then I realize that the code may be easier than explaining.
Most important step: define precisely what you mean by "easy simple" numbers.
Example #1: 1, 2, 4, 8, 16, 32, 64, 128, ... , 1073741824, ...
These are powers of two. So, a straightforward ceil(log(x)/log(2.0)) will solve it.
Example #2: 1, 2, 5, 10, 20, 50, 100, 200, 500, 1000, 2000, 5000, 10000, ...
There is a mixture of powers of two, and some multiples of it. Let's take a closer look.
A subset of these can be described as powers of ten.
Changing the formula to ceil(log(x)/log(10.0)) will solve it.
For each power-of-ten, its multiples by 2.0 and 5.0 are also "easy simple numbers".
Inside each iteration, after checking the power-of-ten value, also check the two multiples. If it fits inside one of the multiple, that value can be returned as result.
Code
The following code is only meant to explain the concept. It is not efficient - an efficient version should have used logarithm to get the result in O(1) time.
#include <iostream>
#include <vector>
#include <limits>
#include <stdexcept>
#include <algorithm>
using namespace std;
double getNiceAxisLength(double value, double baseLength, double step, const std::vector<double>& subSteps)
{
typedef std::vector<double>::const_iterator VecDoubleIter;
if (value < 0.0)
{
throw std::invalid_argument("Error: value must be non-negative. Take absolute value if necessary.");
}
if (baseLength <= 0.0)
{
throw std::invalid_argument("Error: baseLength must be positive.");
}
if (step <= 1.0)
{
throw std::invalid_argument("Error: step must be strictly greater than 1.");
}
for (VecDoubleIter iter = subSteps.begin(); iter != subSteps.end(); ++iter)
{
double subStep = *iter;
if (subStep <= 1.0 || subStep >= step)
{
throw std::invalid_argument("Error: each subStep must be strictly greater than 1, and strictly smaller than step.");
}
}
// make ascending.
std::vector<double> sortedSubSteps(subSteps.begin(), subSteps.end());
std::sort(sortedSubSteps.begin(), sortedSubSteps.end());
if (value <= baseLength)
{
return baseLength;
}
double length = baseLength;
double terminateLength = numeric_limits<double>::max() / step;
while (length < terminateLength)
{
for (VecDoubleIter iter = sortedSubSteps.begin(); iter != sortedSubSteps.end(); ++iter)
{
double subStep = *iter;
if (value <= length * subStep)
{
return (length * subStep);
}
}
double nextLength = length * step;
if (value <= nextLength)
{
return nextLength;
}
length = nextLength;
}
return baseLength;
}
int main()
{
double baseLength = 1.0;
double step = 10.0;
std::vector<double> subSteps;
subSteps.push_back(2.5);
subSteps.push_back(5);
for (int k = 0; k < 1000; k += ((k >> 2) + 1))
{
double value = k;
double result = getNiceAxisLength(value, baseLength, step, subSteps);
cout << "k: " << value << " result: " << result << endl;
}
cout << "Hello world!" << endl;
return 0;
}
Output
k: 0 result: 1
k: 1 result: 1
k: 2 result: 2.5
k: 3 result: 5
k: 4 result: 5
k: 6 result: 10
k: 8 result: 10
k: 11 result: 25
k: 14 result: 25
k: 18 result: 25
k: 23 result: 25
k: 29 result: 50
k: 37 result: 50
k: 47 result: 50
k: 59 result: 100
k: 74 result: 100
k: 93 result: 100
k: 117 result: 250
k: 147 result: 250
k: 184 result: 250
k: 231 result: 250
k: 289 result: 500
k: 362 result: 500
k: 453 result: 500
k: 567 result: 1000
k: 709 result: 1000
k: 887 result: 1000
Hello world!
Hello world!