Divide and conquer approach for Karatsuba algorithm
up vote
0
down vote
favorite
I'm trying to write Karatsuba Algorithm using the divide and conquer approach in Haskell. I did it with merge sort algorithm but can't figure it out here and it's a little bit embarrassing at this point.
My main function looks like this:
dz test end divide combine x =
if test x then end x
else combine(map(dz test end divide combine) (divide x))
I test it for values 1234
and 5678
: dz test end divide combine [1234, 5678,2]
.
So I have to write test
, end
, divide
and combine
functions.
lengthNumb x = length . show $ x
test (x:x1:xs) = (lengthNumb x) < 4 || (lengthNumb x1) < 4
end (x:y:z:xs) = [x * y, z]
This is pretty straightforward. I just check if both numbers that I want to multiply are at least 4 digits long. If not I just use simple multiplication and carry m
value. I know that Karatsuba works better for bigger numbers but this is just for testing purposes.
divide =
divide (x:x1:x2:xs) =
let y1 = x `div` 10^x2
y2 = x `mod` 10^x2
y3 = x2 `div` 2
z1 = x1 `div` 10^x2
z2 = x1 `mod` 10^x2
in [[y1,y2,y3],[z1,z2,y3],[y1+y2, z1+z2, y3]]
combine [[x, x1],[y,y1],[z,z1]] = x * 10^(2*x1) + y + (z - x - y) * 10^x1
I was told that combine
function should only do the final multiplication. So I guess it should get three numbers as an input (each with their m
value) and then also do the necessary subtraction ( z-x-y
) because I couldn't do it in divide
.
But this is wrong. I get an error:
Occurs check: cannot construct the infinite type: a ~ [a]
Expected type: [[a]] -> [a]
Actual type: [[[a]]] -> [a]
I think it is a problem with the parameters of combine
function but I don't know how to fix it. I also think that there could be a problem with how combine
and divide
work together because in one of the previous iterations the final result of multiplication was wrong.
haskell divide-and-conquer karatsuba
add a comment |
up vote
0
down vote
favorite
I'm trying to write Karatsuba Algorithm using the divide and conquer approach in Haskell. I did it with merge sort algorithm but can't figure it out here and it's a little bit embarrassing at this point.
My main function looks like this:
dz test end divide combine x =
if test x then end x
else combine(map(dz test end divide combine) (divide x))
I test it for values 1234
and 5678
: dz test end divide combine [1234, 5678,2]
.
So I have to write test
, end
, divide
and combine
functions.
lengthNumb x = length . show $ x
test (x:x1:xs) = (lengthNumb x) < 4 || (lengthNumb x1) < 4
end (x:y:z:xs) = [x * y, z]
This is pretty straightforward. I just check if both numbers that I want to multiply are at least 4 digits long. If not I just use simple multiplication and carry m
value. I know that Karatsuba works better for bigger numbers but this is just for testing purposes.
divide =
divide (x:x1:x2:xs) =
let y1 = x `div` 10^x2
y2 = x `mod` 10^x2
y3 = x2 `div` 2
z1 = x1 `div` 10^x2
z2 = x1 `mod` 10^x2
in [[y1,y2,y3],[z1,z2,y3],[y1+y2, z1+z2, y3]]
combine [[x, x1],[y,y1],[z,z1]] = x * 10^(2*x1) + y + (z - x - y) * 10^x1
I was told that combine
function should only do the final multiplication. So I guess it should get three numbers as an input (each with their m
value) and then also do the necessary subtraction ( z-x-y
) because I couldn't do it in divide
.
But this is wrong. I get an error:
Occurs check: cannot construct the infinite type: a ~ [a]
Expected type: [[a]] -> [a]
Actual type: [[[a]]] -> [a]
I think it is a problem with the parameters of combine
function but I don't know how to fix it. I also think that there could be a problem with how combine
and divide
work together because in one of the previous iterations the final result of multiplication was wrong.
haskell divide-and-conquer karatsuba
6
Write type signatures! They will show you everything.
– luqui
Nov 9 at 18:29
5
To elaborate on @luqui's comment: in general, if you add a type signature to each of your functions, the error messages will be closer to the code that needs to change. Often they will also be more concrete & easier to interpret.
– bergey
Nov 9 at 18:34
@luqui I am currently learning how to do it by myself but I am not there yet. I know that I can check signatures using:t
command but that doesn't seem to help much.divide
has[a] -> [[a]]
andcombine
has[[b]] -> b
which looks alright to me.
– SuperM4n
Nov 9 at 18:36
1
"I am not there yet." Just writedivide :: [a] -> [[a]]
above yourdivide
definition, andcombine :: [[b]] -> b
above yourcombine
definition (and similar signatures above other definitions). That tells the type checker what types you expect those functions to be, so it can figure out whether the type error is in the caller or the callee. It helps a lot with error clarity.
– DarthFennec
Nov 9 at 19:00
@DarthFennec I'm sorry, I misunderstood above comments. I wrote "I am not there yet" because I thought that guys above were talking about the derivation of types (I don't know if this is the correct term in English.). I did as you asked and now indeed I have a more detailed error message. I'll try to improve my code, thank you.
– SuperM4n
Nov 9 at 19:11
add a comment |
up vote
0
down vote
favorite
up vote
0
down vote
favorite
I'm trying to write Karatsuba Algorithm using the divide and conquer approach in Haskell. I did it with merge sort algorithm but can't figure it out here and it's a little bit embarrassing at this point.
My main function looks like this:
dz test end divide combine x =
if test x then end x
else combine(map(dz test end divide combine) (divide x))
I test it for values 1234
and 5678
: dz test end divide combine [1234, 5678,2]
.
So I have to write test
, end
, divide
and combine
functions.
lengthNumb x = length . show $ x
test (x:x1:xs) = (lengthNumb x) < 4 || (lengthNumb x1) < 4
end (x:y:z:xs) = [x * y, z]
This is pretty straightforward. I just check if both numbers that I want to multiply are at least 4 digits long. If not I just use simple multiplication and carry m
value. I know that Karatsuba works better for bigger numbers but this is just for testing purposes.
divide =
divide (x:x1:x2:xs) =
let y1 = x `div` 10^x2
y2 = x `mod` 10^x2
y3 = x2 `div` 2
z1 = x1 `div` 10^x2
z2 = x1 `mod` 10^x2
in [[y1,y2,y3],[z1,z2,y3],[y1+y2, z1+z2, y3]]
combine [[x, x1],[y,y1],[z,z1]] = x * 10^(2*x1) + y + (z - x - y) * 10^x1
I was told that combine
function should only do the final multiplication. So I guess it should get three numbers as an input (each with their m
value) and then also do the necessary subtraction ( z-x-y
) because I couldn't do it in divide
.
But this is wrong. I get an error:
Occurs check: cannot construct the infinite type: a ~ [a]
Expected type: [[a]] -> [a]
Actual type: [[[a]]] -> [a]
I think it is a problem with the parameters of combine
function but I don't know how to fix it. I also think that there could be a problem with how combine
and divide
work together because in one of the previous iterations the final result of multiplication was wrong.
haskell divide-and-conquer karatsuba
I'm trying to write Karatsuba Algorithm using the divide and conquer approach in Haskell. I did it with merge sort algorithm but can't figure it out here and it's a little bit embarrassing at this point.
My main function looks like this:
dz test end divide combine x =
if test x then end x
else combine(map(dz test end divide combine) (divide x))
I test it for values 1234
and 5678
: dz test end divide combine [1234, 5678,2]
.
So I have to write test
, end
, divide
and combine
functions.
lengthNumb x = length . show $ x
test (x:x1:xs) = (lengthNumb x) < 4 || (lengthNumb x1) < 4
end (x:y:z:xs) = [x * y, z]
This is pretty straightforward. I just check if both numbers that I want to multiply are at least 4 digits long. If not I just use simple multiplication and carry m
value. I know that Karatsuba works better for bigger numbers but this is just for testing purposes.
divide =
divide (x:x1:x2:xs) =
let y1 = x `div` 10^x2
y2 = x `mod` 10^x2
y3 = x2 `div` 2
z1 = x1 `div` 10^x2
z2 = x1 `mod` 10^x2
in [[y1,y2,y3],[z1,z2,y3],[y1+y2, z1+z2, y3]]
combine [[x, x1],[y,y1],[z,z1]] = x * 10^(2*x1) + y + (z - x - y) * 10^x1
I was told that combine
function should only do the final multiplication. So I guess it should get three numbers as an input (each with their m
value) and then also do the necessary subtraction ( z-x-y
) because I couldn't do it in divide
.
But this is wrong. I get an error:
Occurs check: cannot construct the infinite type: a ~ [a]
Expected type: [[a]] -> [a]
Actual type: [[[a]]] -> [a]
I think it is a problem with the parameters of combine
function but I don't know how to fix it. I also think that there could be a problem with how combine
and divide
work together because in one of the previous iterations the final result of multiplication was wrong.
haskell divide-and-conquer karatsuba
haskell divide-and-conquer karatsuba
asked Nov 9 at 18:18
SuperM4n
9611
9611
6
Write type signatures! They will show you everything.
– luqui
Nov 9 at 18:29
5
To elaborate on @luqui's comment: in general, if you add a type signature to each of your functions, the error messages will be closer to the code that needs to change. Often they will also be more concrete & easier to interpret.
– bergey
Nov 9 at 18:34
@luqui I am currently learning how to do it by myself but I am not there yet. I know that I can check signatures using:t
command but that doesn't seem to help much.divide
has[a] -> [[a]]
andcombine
has[[b]] -> b
which looks alright to me.
– SuperM4n
Nov 9 at 18:36
1
"I am not there yet." Just writedivide :: [a] -> [[a]]
above yourdivide
definition, andcombine :: [[b]] -> b
above yourcombine
definition (and similar signatures above other definitions). That tells the type checker what types you expect those functions to be, so it can figure out whether the type error is in the caller or the callee. It helps a lot with error clarity.
– DarthFennec
Nov 9 at 19:00
@DarthFennec I'm sorry, I misunderstood above comments. I wrote "I am not there yet" because I thought that guys above were talking about the derivation of types (I don't know if this is the correct term in English.). I did as you asked and now indeed I have a more detailed error message. I'll try to improve my code, thank you.
– SuperM4n
Nov 9 at 19:11
add a comment |
6
Write type signatures! They will show you everything.
– luqui
Nov 9 at 18:29
5
To elaborate on @luqui's comment: in general, if you add a type signature to each of your functions, the error messages will be closer to the code that needs to change. Often they will also be more concrete & easier to interpret.
– bergey
Nov 9 at 18:34
@luqui I am currently learning how to do it by myself but I am not there yet. I know that I can check signatures using:t
command but that doesn't seem to help much.divide
has[a] -> [[a]]
andcombine
has[[b]] -> b
which looks alright to me.
– SuperM4n
Nov 9 at 18:36
1
"I am not there yet." Just writedivide :: [a] -> [[a]]
above yourdivide
definition, andcombine :: [[b]] -> b
above yourcombine
definition (and similar signatures above other definitions). That tells the type checker what types you expect those functions to be, so it can figure out whether the type error is in the caller or the callee. It helps a lot with error clarity.
– DarthFennec
Nov 9 at 19:00
@DarthFennec I'm sorry, I misunderstood above comments. I wrote "I am not there yet" because I thought that guys above were talking about the derivation of types (I don't know if this is the correct term in English.). I did as you asked and now indeed I have a more detailed error message. I'll try to improve my code, thank you.
– SuperM4n
Nov 9 at 19:11
6
6
Write type signatures! They will show you everything.
– luqui
Nov 9 at 18:29
Write type signatures! They will show you everything.
– luqui
Nov 9 at 18:29
5
5
To elaborate on @luqui's comment: in general, if you add a type signature to each of your functions, the error messages will be closer to the code that needs to change. Often they will also be more concrete & easier to interpret.
– bergey
Nov 9 at 18:34
To elaborate on @luqui's comment: in general, if you add a type signature to each of your functions, the error messages will be closer to the code that needs to change. Often they will also be more concrete & easier to interpret.
– bergey
Nov 9 at 18:34
@luqui I am currently learning how to do it by myself but I am not there yet. I know that I can check signatures using
:t
command but that doesn't seem to help much. divide
has [a] -> [[a]]
and combine
has [[b]] -> b
which looks alright to me.– SuperM4n
Nov 9 at 18:36
@luqui I am currently learning how to do it by myself but I am not there yet. I know that I can check signatures using
:t
command but that doesn't seem to help much. divide
has [a] -> [[a]]
and combine
has [[b]] -> b
which looks alright to me.– SuperM4n
Nov 9 at 18:36
1
1
"I am not there yet." Just write
divide :: [a] -> [[a]]
above your divide
definition, and combine :: [[b]] -> b
above your combine
definition (and similar signatures above other definitions). That tells the type checker what types you expect those functions to be, so it can figure out whether the type error is in the caller or the callee. It helps a lot with error clarity.– DarthFennec
Nov 9 at 19:00
"I am not there yet." Just write
divide :: [a] -> [[a]]
above your divide
definition, and combine :: [[b]] -> b
above your combine
definition (and similar signatures above other definitions). That tells the type checker what types you expect those functions to be, so it can figure out whether the type error is in the caller or the callee. It helps a lot with error clarity.– DarthFennec
Nov 9 at 19:00
@DarthFennec I'm sorry, I misunderstood above comments. I wrote "I am not there yet" because I thought that guys above were talking about the derivation of types (I don't know if this is the correct term in English.). I did as you asked and now indeed I have a more detailed error message. I'll try to improve my code, thank you.
– SuperM4n
Nov 9 at 19:11
@DarthFennec I'm sorry, I misunderstood above comments. I wrote "I am not there yet" because I thought that guys above were talking about the derivation of types (I don't know if this is the correct term in English.). I did as you asked and now indeed I have a more detailed error message. I'll try to improve my code, thank you.
– SuperM4n
Nov 9 at 19:11
add a comment |
active
oldest
votes
Your Answer
StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");
StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "1"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);
else
createEditor();
);
function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);
);
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53231314%2fdivide-and-conquer-approach-for-karatsuba-algorithm%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
active
oldest
votes
active
oldest
votes
active
oldest
votes
active
oldest
votes
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Some of your past answers have not been well-received, and you're in danger of being blocked from answering.
Please pay close attention to the following guidance:
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53231314%2fdivide-and-conquer-approach-for-karatsuba-algorithm%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
6
Write type signatures! They will show you everything.
– luqui
Nov 9 at 18:29
5
To elaborate on @luqui's comment: in general, if you add a type signature to each of your functions, the error messages will be closer to the code that needs to change. Often they will also be more concrete & easier to interpret.
– bergey
Nov 9 at 18:34
@luqui I am currently learning how to do it by myself but I am not there yet. I know that I can check signatures using
:t
command but that doesn't seem to help much.divide
has[a] -> [[a]]
andcombine
has[[b]] -> b
which looks alright to me.– SuperM4n
Nov 9 at 18:36
1
"I am not there yet." Just write
divide :: [a] -> [[a]]
above yourdivide
definition, andcombine :: [[b]] -> b
above yourcombine
definition (and similar signatures above other definitions). That tells the type checker what types you expect those functions to be, so it can figure out whether the type error is in the caller or the callee. It helps a lot with error clarity.– DarthFennec
Nov 9 at 19:00
@DarthFennec I'm sorry, I misunderstood above comments. I wrote "I am not there yet" because I thought that guys above were talking about the derivation of types (I don't know if this is the correct term in English.). I did as you asked and now indeed I have a more detailed error message. I'll try to improve my code, thank you.
– SuperM4n
Nov 9 at 19:11