mersenneforum.org

mersenneforum.org (https://www.mersenneforum.org/index.php)
-   PARI/GP (https://www.mersenneforum.org/forumdisplay.php?f=155)
-   -   PARI's commands (https://www.mersenneforum.org/showthread.php?t=13636)

CRGreathouse 2010-11-30 01:55

As for getting a correct answer, I'd rather write my own than correct yours:
[code]longmultiply(a,b)= {
a=eval(Vec(Str(a)));
b=eval(Vec(Str(b)));
my(res=vector(#a+#b),carry=0);
for(i=1,#a,
for(j=1,#b,
res[i+j] += a[i]*b[j]
)
);
forstep(i=#res,2,-1,
res[i] += carry;
carry = res[i]\10;
res[i] -= 10 * carry
);
res[1] += carry;
if(res[1],
res
,
vecextract(res,2^#res-2)
)
};[/code]

science_man_88 2010-11-30 01:55

[QUOTE=science_man_88;239298]the red is the starts with 0 error, I should add an if around it checking if answer[1]>10 first if so i doubt after the previous step that answer[1] is useful.[/QUOTE]

wrong again that caused more errors to fix. Now I see a logic flaw on my part and using n+m as the length of answer.

CRGreathouse 2010-11-30 01:57

[QUOTE=science_man_88;239298]the red is the starts with 0 error, I should add an if around it checking if answer[1]>10 first if so i doubt after the previous step that answer[1] is useful.[/QUOTE]

I don't know what the purpose of that line is; answer[1] will never be more than 9 (if the program is correct up to that point), but even if it was you wouldn't want to divide by 10.

[QUOTE=science_man_88;239301]wrong again that caused more errors to fix. Now I see a logic flaw on my part and using n+m as the length of answer.[/QUOTE]

The length is good. Look at my answer (post #1816).

science_man_88 2010-11-30 01:58

[QUOTE=CRGreathouse;239300]As for getting a correct answer, I'd rather write my own than correct yours:
[code]longmultiply(a,b)= {
a=eval(Vec(Str(a)));
b=eval(Vec(Str(b)));
my(res=vector(#a+#b),carry=0);
for(i=1,#a,
for(j=1,#b,
res[i+j] += a[i]*b[j]
)
);
forstep(i=#res,2,-1,
res[i] += carry;
carry = res[i]\10;
res[i] -= 10 * carry
);
res[1] += carry;
if(res[1],
res
,
vecextract(res,2^#res-2)
)
};[/code][/QUOTE]

Oh,Really ?

[CODE][0, 1, 0, 0]
[0, 1, 0, 0]
[0, 1, 0, 0]
[0, 1, 0, 0]
[0, 1, 0, 0]
[0, 1, 0, 0]
[0, 1, 0, 0]
[0, 1, 0, 0]
[0, 1, 0, 0]
[0, 1, 0, 0]
[0, 1, 0, 0]
[0, 1, 0, 0]
[0, 1, 0, 0]
[0, 1, 0, 0]
[0, 1, 0, 0]
[0, 1, 0, 0]
[0, 1, 0, 0]
[0, 1, 0, 0]
[0, 1, 0, 0]
[0, 1, 0, 0]
[0, 1, 0, 0]
[0, 1, 0, 0]
[0, 1, 0, 0]
[0, 1, 0, 0]
[0, 1, 0, 0]
[0, 1, 0, 0]
[0, 1, 0, 0]
[0, 1, 0, 0]
[0, 1, 0, 0]
[0, 1, 0, 0]
[0, 1, 0, 0]
[0, 1, 0, 0]
[0, 1, 0, 0]
[0, 1, 0, 0]
[0, 1, 0, 0]
[0, 1, 0, 0]
[0, 1, 0, 0]
[0, 1, 0, 0]
[0, 1, 0, 0]
[0, 1, 0, 0]
[0, 1, 0, 0]
[0, 1, 0, 0]
[0, 1, 0, 0]
[0, 1, 0, 0]
[0, 1, 0, 0]
[0, 1, 0, 0]
[0, 1, 0, 0]
[0, 1, 0, 0]
[0, 1, 0, 0]
[0, 1, 0, 0]
[0, 1, 0, 0]
[0, 1, 0, 0]
[0, 1, 0, 0]
[0, 1, 0, 0]
[0, 1, 0, 0]
[0, 1, 0, 0]
[0, 1, 0, 0]
[0, 1, 0, 0]
[0, 1, 0, 0]
[0, 1, 0, 0]
[0, 1, 0, 0]
[0, 1, 0, 0]
[0, 1, 0, 0]
[0, 1, 0, 0]
[0, 1, 0, 0]
[0, 1, 0, 0]
[0, 1, 0, 0]
[0, 1, 0, 0]
[0, 1, 0, 0]
[0, 1, 0, 0]
[0, 1, 0, 0]
[0, 1, 0, 0]
[0, 1, 0, 0]
[0, 1, 0, 0]
[0, 1, 0, 0]
[0, 1, 0, 0]
[0, 1, 0, 0]
[0, 1, 0, 0]
[0, 1, 0, 0]
[0, 1, 0, 0]
[0, 1, 0, 0]
[0, 1, 0, 0]
[0, 1, 0, 0]
[0, 1, 0, 0]
[0, 1, 0, 0]
[0, 1, 0, 0]
[0, 1, 0, 0]
[0, 1, 0, 0]
[0, 1, 0, 0]
[0, 1, 0, 0]
[0, 1, 0, 0]
[0, 1, 0, 0]
[0, 1, 0, 0]
[0, 1, 0, 0]
[0, 1, 0, 0]
[0, 1, 0, 0]
[0, 1, 0, 0]
[0, 1, 0, 0]
[0, 1, 0, 0]
[0, 1, 0, 0][/CODE]

Is what I got when I added print(answer) on the end.

CRGreathouse 2010-11-30 02:02

[QUOTE=science_man_88;239303]Is what I got when I added print(answer) on the end.[/QUOTE]

Why would you print the result of the global variable answer?
1. My function already returns a result; no need to modify it to see the answer.
2. My function doesn't use "answer" in any way, so it's no surprise that it still has the last value it had when your function used it.
3. If your function had encapsulated its variables with local() or my() then you wouldn't have changed the global "answer" in the first place so you wouldn't get this strange result. This is one of the benefits of using local() and my()!

Remember: Amateurs print, professionals return. Try something like this:
[code]for(a=1,1e3,for(b=1,1e3,if(longmultiply(a,b)!=eval(Vec(Str(a*b))),print(a"*"b))))[/code]

Of course if you're really confident, you can even do
[code]for(a=1,1e3,for(b=1,1e3,if(longmultiply(a,b)!=eval(Vec(Str(a*b))),return([a,b]))))[/code]

science_man_88 2010-11-30 02:07

[QUOTE=CRGreathouse;239304]Why would you print the result of the global variable answer?
1. My function already returns a result; no need to modify it to see the answer.
2. My function doesn't use "answer" in any way, so it's no surprise that it still has the last value it had when your function used it.
3. If your function had encapsulated its variables with local() or my() then you wouldn't have changed the global "answer" in the first place so you wouldn't get this strange result. This is one of the benefits of using local() and my()!

Remember: Amateurs print, professionals return.[/QUOTE]

I'm not a professional, I never intend to be branded professional.

science_man_88 2010-11-30 02:11

[QUOTE=CRGreathouse;239295]A little. Here's how I'd format it:
[code]longmultiply(a,b)= {
my(c=eval(Vec(Str(a))),d=eval(Vec(Str(b))),carry=0,answer=vector(#c+#d));
forstep(x=#d,1,[-1],
forstep(y=#c,1,[-1],
n=((c[y]*d[x])+carry)%10;
answer[#answer-((#d-x+1)+(#c-y+1)-1)] += n;
carry=(c[y]*d[x])\10
)
);
forstep(w=#answer,2,-1,
answer[w-1] += answer[w]\10;
answer[w]=answer[w]%10;
if(w<#answer,answer[w+1]=answer[w])
);
answer[2]=answer[1]%10;
answer[1]=answer[1]\10;
answer
};[/code]

Also changed: length(foo) to #foo, floor(foo/10) to foo\10, foo = foo + n to foo += n, local variables put into a my block. (This is important if you want to avoid clobbering variables! Always do this!)[/QUOTE]

my() to me seems like an easy way to admit something like .[B][U]I[/U][/B] can't find the capitals at the beginning of a sentence.

CRGreathouse 2010-11-30 02:15

[QUOTE=science_man_88;239305]I'm not a professional, I never intend to be branded professional.[/QUOTE]

I'm just trying to convince you to do things the 'right' way since they will make things easier for you.

If you did
[code]longmultiply(a,b)={
\\ blah blah blah...
print(answer)
};[/code]
then you couldn't test your results in a loop like I did above (and you did yourself in a similar loop).

If you did
[code]times10(n)={
a = 5;
b = times2(n);
a*b
};
times2(n)={
a = 2;
a * n
};
times10(1)[/code]
then it doesn't work properly (why?)... but

[code]times10(n)={
my(a = 5, b = times2(n));
a*b
};
times2(n)={
my(a = 2);
a * n
};
times10(1)[/code]
does.

science_man_88 2010-11-30 02:16

[QUOTE=CRGreathouse;239302]I don't know what the purpose of that line is; answer[1] will never be more than 9 (if the program is correct up to that point), but even if it was you wouldn't want to divide by 10.



The length is good. Look at my answer (post #1816).[/QUOTE]

I couldn't get the digits placed properly as i didn't have a formula I found one that worked except a shift I made a shift of all but answer[1] then I shifted answer[1] separately, and yes you would as it determines what stays in position 1.

science_man_88 2010-11-30 02:21

[QUOTE=CRGreathouse;239307]
If you did
[code]times10(n)={
a = 5;
b = times2(n);
a*b
};
times2(n)={
a = 2;
a * n
};
times10(1)[/code]
then it doesn't work properly (why?)... but

[/QUOTE]

lame excuse. and it's simple 2 variables named a.

CRGreathouse 2010-11-30 02:30

[QUOTE=science_man_88;239310]lame excuse. and it's simple 2 variables named a.[/QUOTE]

So let's step back and think about that. You can't call times2() from a function unless you check it to make sure that none of its variables are the same as the ones in the calling function. But what if times2() called another function?

[code]times2(n)={
a = minus1(n);
if(a, times2(a) + 2, 2)
};

minus1(n)={
n - 1
};[/code]

Then you need to check it as well. If it's programmed the way I have it above, you see that the two variables named a collide, but you can make times10 work by changing the variable:
[code]times10(n)={
b = times2(n);
theVariableFormerlyKnownAsA = 5;
theVariableFormerlyKnownAsA*b
};[/code]
But what if I had instead written minus1() as
[code]minus1(n)={
b = n;
b--
}[/code]
Now suddenly you can't call times2() without checking for collisions in that function, or any function that it calls. Of course this goes on forever: what if minus1() called another function? You'd have to check that too.

This becomes surprisingly common with complex functions calling each other, with how few major variable names we use. But the whole issue can be solved in one step -- no looking up functions, and functions in functions, and functions in functions in functions, ... -- by using my().


All times are UTC. The time now is 23:10.

Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2021, Jelsoft Enterprises Ltd.