Karazuba Algorithm with arbitrary basesTiny Encryption Algorithm (TEA) for arbitrary sized dataAlgorithm to...

Diffraction of a wave passing through double slits

POSIX compatible way to get user name associated with a user ID

What is this gigantic dish at Ben Gurion airport?

Is a suit against a University Dorm for changing policies on a whim likely to succeed (USA)?

Why do sellers care about down payments?

Is there any way to land a rover on the Moon without using any thrusters?

What are uses of the byte after BRK instruction on 6502?

What hard drive connector is this?

Why some files are not movable in Windows 10

Real mode flat model

Are space camera sensors usually round, or square?

What does a Light weapon mean mechanically?

How do I say "quirky" in German without sounding derogatory?

What is the derivative of an exponential function with another function as its base?

Can you add polynomial terms to multiple linear regression?

Planar regular languages

How are aircraft depainted?

How do EVA suits manage water excretion?

What officially disallows US presidents from driving?

How to prepare for STEM graduate program while in industry?

Can I fix my boots by gluing the soles back on?

Will the UK home office know about 5 previous visa rejections in other countries?

What is my breathable atmosphere composed of?

How are unbalanced coaxial cables used for broadcasting TV signals without any problems?



Karazuba Algorithm with arbitrary bases


Tiny Encryption Algorithm (TEA) for arbitrary sized dataAlgorithm to get an arbitrary perpendicular vectorChanging algorithm to avoid looping with iterrowsBase converting with strings from bases 1 to 36 to bases 1 to 36Base object to convert positive numbers into other bases (2 <= base <= 35) in Python355 - The Bases Are Loaded (math numbers conversion)(Almost) arbitrary base ints with decorated methodsDijkstra's algorithm with priority queueArbitrary Dice with ProbabilityArbitrary precision Euler-Mascheroni constant via a Brent-McMillan algorithm with no math module






.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty{ margin-bottom:0;
}







8












$begingroup$


I'm working on an implementation of the Karazuba Algorithm. I created a class BN which represents a number in an arbitrary base (and supports elementary operations). The algorithm works - but I'm not sure if I complicated it. Is there a better way to implement it or a way to optimize the code?



def decToBase(n: int, b: int) -> list:
if n == 0:
return [0]
digits = []
while n:
digits.append(int(n % b))
n //= b
return list(reversed(digits))

def baseToDec(n: list, b: int) -> int:
res = 0
for index, i in enumerate(reversed(n)):
res += int(i) * b ** index
return res

from math import log2, ceil, log10, floor

class BN(): # Base Number
def __init__(self, num, base):
if type(num) == list:
self.digits = num
else:
self.digits = decToBase(num, base)
self.base = base
self.length = len(self.digits)

def __add__(self, o):
if self.base != o.base:
raise ValueError("base of summands must be equal")
carry = 0
res = []
for d1, d2 in zip(reversed(self.digits), reversed(o.digits)):
s = int(d1) + int(d2) + carry
res.append(str(s % self.base))
carry = s // self.base
return BN(list(reversed(res)), self.base)

def __mul__(self, o):
# implementation pending
return BN(decToBase(self.getDecimalForm() * o.getDecimalForm(), self.base), self.base)

def __sub__(self, o):
# implementation pending
return BN(decToBase(self.getDecimalForm() - o.getDecimalForm(), self.base), self.base)

def getDecimalForm(self):
return baseToDec(self.digits, self.base)

def karazubaMultiply(a, b, base=2**64):
if a < b:
a, b = b, a # ensure a >= b
next2 = 2 ** ceil(log2(floor(log10(a))+1)) # next power of 2
a, b = BN(a, base), BN(b, base)
a.digits, b.digits = ['0'] * (next2 - a.length) + a.digits, ['0'] * (next2 - b.length) + b.digits
n = next2 // 2
x2, x1 = BN(a.digits[:n], base), BN(a.digits[n:], base)
y2, y1 = BN(b.digits[:n], base), BN(b.digits[n:], base)
p1, p2, p3 = x2 * y2, x1 * y1, (x1 + x2) * (y1 + y2)
p1, p2, p3 = p1.getDecimalForm(), p2.getDecimalForm(), p3.getDecimalForm()

xy = p1 * base ** (2*n) + (p3 - (p1 + p2)) * base ** n + p2

return xy









share|improve this question









New contributor



Thomas is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.






$endgroup$














  • $begingroup$
    You're never going to be anywhere near as fast as the builtin integer type. If you want to display as base_x, then you should just build a class that inherits from int, but displays differently, if you care about speed.
    $endgroup$
    – Gloweye
    9 hours ago










  • $begingroup$
    It's clear that it won't be faster than the builtin multiplication. I just want to implement the algorithm - at maximum speed, for learning purpose.
    $endgroup$
    – Thomas
    9 hours ago


















8












$begingroup$


I'm working on an implementation of the Karazuba Algorithm. I created a class BN which represents a number in an arbitrary base (and supports elementary operations). The algorithm works - but I'm not sure if I complicated it. Is there a better way to implement it or a way to optimize the code?



def decToBase(n: int, b: int) -> list:
if n == 0:
return [0]
digits = []
while n:
digits.append(int(n % b))
n //= b
return list(reversed(digits))

def baseToDec(n: list, b: int) -> int:
res = 0
for index, i in enumerate(reversed(n)):
res += int(i) * b ** index
return res

from math import log2, ceil, log10, floor

class BN(): # Base Number
def __init__(self, num, base):
if type(num) == list:
self.digits = num
else:
self.digits = decToBase(num, base)
self.base = base
self.length = len(self.digits)

def __add__(self, o):
if self.base != o.base:
raise ValueError("base of summands must be equal")
carry = 0
res = []
for d1, d2 in zip(reversed(self.digits), reversed(o.digits)):
s = int(d1) + int(d2) + carry
res.append(str(s % self.base))
carry = s // self.base
return BN(list(reversed(res)), self.base)

def __mul__(self, o):
# implementation pending
return BN(decToBase(self.getDecimalForm() * o.getDecimalForm(), self.base), self.base)

def __sub__(self, o):
# implementation pending
return BN(decToBase(self.getDecimalForm() - o.getDecimalForm(), self.base), self.base)

def getDecimalForm(self):
return baseToDec(self.digits, self.base)

def karazubaMultiply(a, b, base=2**64):
if a < b:
a, b = b, a # ensure a >= b
next2 = 2 ** ceil(log2(floor(log10(a))+1)) # next power of 2
a, b = BN(a, base), BN(b, base)
a.digits, b.digits = ['0'] * (next2 - a.length) + a.digits, ['0'] * (next2 - b.length) + b.digits
n = next2 // 2
x2, x1 = BN(a.digits[:n], base), BN(a.digits[n:], base)
y2, y1 = BN(b.digits[:n], base), BN(b.digits[n:], base)
p1, p2, p3 = x2 * y2, x1 * y1, (x1 + x2) * (y1 + y2)
p1, p2, p3 = p1.getDecimalForm(), p2.getDecimalForm(), p3.getDecimalForm()

xy = p1 * base ** (2*n) + (p3 - (p1 + p2)) * base ** n + p2

return xy









share|improve this question









New contributor



Thomas is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.






$endgroup$














  • $begingroup$
    You're never going to be anywhere near as fast as the builtin integer type. If you want to display as base_x, then you should just build a class that inherits from int, but displays differently, if you care about speed.
    $endgroup$
    – Gloweye
    9 hours ago










  • $begingroup$
    It's clear that it won't be faster than the builtin multiplication. I just want to implement the algorithm - at maximum speed, for learning purpose.
    $endgroup$
    – Thomas
    9 hours ago














8












8








8





$begingroup$


I'm working on an implementation of the Karazuba Algorithm. I created a class BN which represents a number in an arbitrary base (and supports elementary operations). The algorithm works - but I'm not sure if I complicated it. Is there a better way to implement it or a way to optimize the code?



def decToBase(n: int, b: int) -> list:
if n == 0:
return [0]
digits = []
while n:
digits.append(int(n % b))
n //= b
return list(reversed(digits))

def baseToDec(n: list, b: int) -> int:
res = 0
for index, i in enumerate(reversed(n)):
res += int(i) * b ** index
return res

from math import log2, ceil, log10, floor

class BN(): # Base Number
def __init__(self, num, base):
if type(num) == list:
self.digits = num
else:
self.digits = decToBase(num, base)
self.base = base
self.length = len(self.digits)

def __add__(self, o):
if self.base != o.base:
raise ValueError("base of summands must be equal")
carry = 0
res = []
for d1, d2 in zip(reversed(self.digits), reversed(o.digits)):
s = int(d1) + int(d2) + carry
res.append(str(s % self.base))
carry = s // self.base
return BN(list(reversed(res)), self.base)

def __mul__(self, o):
# implementation pending
return BN(decToBase(self.getDecimalForm() * o.getDecimalForm(), self.base), self.base)

def __sub__(self, o):
# implementation pending
return BN(decToBase(self.getDecimalForm() - o.getDecimalForm(), self.base), self.base)

def getDecimalForm(self):
return baseToDec(self.digits, self.base)

def karazubaMultiply(a, b, base=2**64):
if a < b:
a, b = b, a # ensure a >= b
next2 = 2 ** ceil(log2(floor(log10(a))+1)) # next power of 2
a, b = BN(a, base), BN(b, base)
a.digits, b.digits = ['0'] * (next2 - a.length) + a.digits, ['0'] * (next2 - b.length) + b.digits
n = next2 // 2
x2, x1 = BN(a.digits[:n], base), BN(a.digits[n:], base)
y2, y1 = BN(b.digits[:n], base), BN(b.digits[n:], base)
p1, p2, p3 = x2 * y2, x1 * y1, (x1 + x2) * (y1 + y2)
p1, p2, p3 = p1.getDecimalForm(), p2.getDecimalForm(), p3.getDecimalForm()

xy = p1 * base ** (2*n) + (p3 - (p1 + p2)) * base ** n + p2

return xy









share|improve this question









New contributor



Thomas is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.






$endgroup$




I'm working on an implementation of the Karazuba Algorithm. I created a class BN which represents a number in an arbitrary base (and supports elementary operations). The algorithm works - but I'm not sure if I complicated it. Is there a better way to implement it or a way to optimize the code?



def decToBase(n: int, b: int) -> list:
if n == 0:
return [0]
digits = []
while n:
digits.append(int(n % b))
n //= b
return list(reversed(digits))

def baseToDec(n: list, b: int) -> int:
res = 0
for index, i in enumerate(reversed(n)):
res += int(i) * b ** index
return res

from math import log2, ceil, log10, floor

class BN(): # Base Number
def __init__(self, num, base):
if type(num) == list:
self.digits = num
else:
self.digits = decToBase(num, base)
self.base = base
self.length = len(self.digits)

def __add__(self, o):
if self.base != o.base:
raise ValueError("base of summands must be equal")
carry = 0
res = []
for d1, d2 in zip(reversed(self.digits), reversed(o.digits)):
s = int(d1) + int(d2) + carry
res.append(str(s % self.base))
carry = s // self.base
return BN(list(reversed(res)), self.base)

def __mul__(self, o):
# implementation pending
return BN(decToBase(self.getDecimalForm() * o.getDecimalForm(), self.base), self.base)

def __sub__(self, o):
# implementation pending
return BN(decToBase(self.getDecimalForm() - o.getDecimalForm(), self.base), self.base)

def getDecimalForm(self):
return baseToDec(self.digits, self.base)

def karazubaMultiply(a, b, base=2**64):
if a < b:
a, b = b, a # ensure a >= b
next2 = 2 ** ceil(log2(floor(log10(a))+1)) # next power of 2
a, b = BN(a, base), BN(b, base)
a.digits, b.digits = ['0'] * (next2 - a.length) + a.digits, ['0'] * (next2 - b.length) + b.digits
n = next2 // 2
x2, x1 = BN(a.digits[:n], base), BN(a.digits[n:], base)
y2, y1 = BN(b.digits[:n], base), BN(b.digits[n:], base)
p1, p2, p3 = x2 * y2, x1 * y1, (x1 + x2) * (y1 + y2)
p1, p2, p3 = p1.getDecimalForm(), p2.getDecimalForm(), p3.getDecimalForm()

xy = p1 * base ** (2*n) + (p3 - (p1 + p2)) * base ** n + p2

return xy






python performance algorithm number-systems






share|improve this question









New contributor



Thomas is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.










share|improve this question









New contributor



Thomas is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.








share|improve this question




share|improve this question








edited 9 hours ago









200_success

136k21 gold badges175 silver badges445 bronze badges




136k21 gold badges175 silver badges445 bronze badges






New contributor



Thomas is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.








asked 9 hours ago









ThomasThomas

411 bronze badge




411 bronze badge




New contributor



Thomas is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.




New contributor




Thomas is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.

















  • $begingroup$
    You're never going to be anywhere near as fast as the builtin integer type. If you want to display as base_x, then you should just build a class that inherits from int, but displays differently, if you care about speed.
    $endgroup$
    – Gloweye
    9 hours ago










  • $begingroup$
    It's clear that it won't be faster than the builtin multiplication. I just want to implement the algorithm - at maximum speed, for learning purpose.
    $endgroup$
    – Thomas
    9 hours ago


















  • $begingroup$
    You're never going to be anywhere near as fast as the builtin integer type. If you want to display as base_x, then you should just build a class that inherits from int, but displays differently, if you care about speed.
    $endgroup$
    – Gloweye
    9 hours ago










  • $begingroup$
    It's clear that it won't be faster than the builtin multiplication. I just want to implement the algorithm - at maximum speed, for learning purpose.
    $endgroup$
    – Thomas
    9 hours ago
















$begingroup$
You're never going to be anywhere near as fast as the builtin integer type. If you want to display as base_x, then you should just build a class that inherits from int, but displays differently, if you care about speed.
$endgroup$
– Gloweye
9 hours ago




$begingroup$
You're never going to be anywhere near as fast as the builtin integer type. If you want to display as base_x, then you should just build a class that inherits from int, but displays differently, if you care about speed.
$endgroup$
– Gloweye
9 hours ago












$begingroup$
It's clear that it won't be faster than the builtin multiplication. I just want to implement the algorithm - at maximum speed, for learning purpose.
$endgroup$
– Thomas
9 hours ago




$begingroup$
It's clear that it won't be faster than the builtin multiplication. I just want to implement the algorithm - at maximum speed, for learning purpose.
$endgroup$
– Thomas
9 hours ago










1 Answer
1






active

oldest

votes


















6














$begingroup$

Combine division and modulus



Use https://docs.python.org/3/library/functions.html#divmod



rather than this:



    digits.append(int(n % b))
n //= b


Replace loop with sum



This



res = 0
for index, i in enumerate(reversed(n)):
res += int(i) * b ** index
return res


is a good candidate for conversion to a generator, i.e.



return sum(int(i) * b**index for index, i in enumerate(reversed(n)))


However, you can get rid of that reversed if you change the power index to be len(n) - index.



Imports at the top



Move this:



from math import log2, ceil, log10, floor


to the top of your file.



Don't compare types



Rather than this:



if type(num) == list:


use isinstance.



Member mutability



You shouldn't care that num is coming in as a list; you should only check that it's iterable. And store it as a tuple, not a list, because you don't (and shouldn't) mutate it in your class code.



Call reversed once



This:



zip(reversed(self.digits), reversed(o.digits))


should be



reversed(zip(self.digits, o.digits))


Don't use strings for math



Just don't. This:



a.digits, b.digits = ['0']


is not a good idea. Use actual digits whenever possible, and it is possible here.






share|improve this answer









$endgroup$


















    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: "196"
    };
    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: false,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: null,
    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/4.0/"u003ecc by-sa 4.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
    });


    }
    });







    Thomas is a new contributor. Be nice, and check out our Code of Conduct.










    draft saved

    draft discarded
















    StackExchange.ready(
    function () {
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f228924%2fkarazuba-algorithm-with-arbitrary-bases%23new-answer', 'question_page');
    }
    );

    Post as a guest















    Required, but never shown

























    1 Answer
    1






    active

    oldest

    votes








    1 Answer
    1






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    6














    $begingroup$

    Combine division and modulus



    Use https://docs.python.org/3/library/functions.html#divmod



    rather than this:



        digits.append(int(n % b))
    n //= b


    Replace loop with sum



    This



    res = 0
    for index, i in enumerate(reversed(n)):
    res += int(i) * b ** index
    return res


    is a good candidate for conversion to a generator, i.e.



    return sum(int(i) * b**index for index, i in enumerate(reversed(n)))


    However, you can get rid of that reversed if you change the power index to be len(n) - index.



    Imports at the top



    Move this:



    from math import log2, ceil, log10, floor


    to the top of your file.



    Don't compare types



    Rather than this:



    if type(num) == list:


    use isinstance.



    Member mutability



    You shouldn't care that num is coming in as a list; you should only check that it's iterable. And store it as a tuple, not a list, because you don't (and shouldn't) mutate it in your class code.



    Call reversed once



    This:



    zip(reversed(self.digits), reversed(o.digits))


    should be



    reversed(zip(self.digits, o.digits))


    Don't use strings for math



    Just don't. This:



    a.digits, b.digits = ['0']


    is not a good idea. Use actual digits whenever possible, and it is possible here.






    share|improve this answer









    $endgroup$




















      6














      $begingroup$

      Combine division and modulus



      Use https://docs.python.org/3/library/functions.html#divmod



      rather than this:



          digits.append(int(n % b))
      n //= b


      Replace loop with sum



      This



      res = 0
      for index, i in enumerate(reversed(n)):
      res += int(i) * b ** index
      return res


      is a good candidate for conversion to a generator, i.e.



      return sum(int(i) * b**index for index, i in enumerate(reversed(n)))


      However, you can get rid of that reversed if you change the power index to be len(n) - index.



      Imports at the top



      Move this:



      from math import log2, ceil, log10, floor


      to the top of your file.



      Don't compare types



      Rather than this:



      if type(num) == list:


      use isinstance.



      Member mutability



      You shouldn't care that num is coming in as a list; you should only check that it's iterable. And store it as a tuple, not a list, because you don't (and shouldn't) mutate it in your class code.



      Call reversed once



      This:



      zip(reversed(self.digits), reversed(o.digits))


      should be



      reversed(zip(self.digits, o.digits))


      Don't use strings for math



      Just don't. This:



      a.digits, b.digits = ['0']


      is not a good idea. Use actual digits whenever possible, and it is possible here.






      share|improve this answer









      $endgroup$


















        6














        6










        6







        $begingroup$

        Combine division and modulus



        Use https://docs.python.org/3/library/functions.html#divmod



        rather than this:



            digits.append(int(n % b))
        n //= b


        Replace loop with sum



        This



        res = 0
        for index, i in enumerate(reversed(n)):
        res += int(i) * b ** index
        return res


        is a good candidate for conversion to a generator, i.e.



        return sum(int(i) * b**index for index, i in enumerate(reversed(n)))


        However, you can get rid of that reversed if you change the power index to be len(n) - index.



        Imports at the top



        Move this:



        from math import log2, ceil, log10, floor


        to the top of your file.



        Don't compare types



        Rather than this:



        if type(num) == list:


        use isinstance.



        Member mutability



        You shouldn't care that num is coming in as a list; you should only check that it's iterable. And store it as a tuple, not a list, because you don't (and shouldn't) mutate it in your class code.



        Call reversed once



        This:



        zip(reversed(self.digits), reversed(o.digits))


        should be



        reversed(zip(self.digits, o.digits))


        Don't use strings for math



        Just don't. This:



        a.digits, b.digits = ['0']


        is not a good idea. Use actual digits whenever possible, and it is possible here.






        share|improve this answer









        $endgroup$



        Combine division and modulus



        Use https://docs.python.org/3/library/functions.html#divmod



        rather than this:



            digits.append(int(n % b))
        n //= b


        Replace loop with sum



        This



        res = 0
        for index, i in enumerate(reversed(n)):
        res += int(i) * b ** index
        return res


        is a good candidate for conversion to a generator, i.e.



        return sum(int(i) * b**index for index, i in enumerate(reversed(n)))


        However, you can get rid of that reversed if you change the power index to be len(n) - index.



        Imports at the top



        Move this:



        from math import log2, ceil, log10, floor


        to the top of your file.



        Don't compare types



        Rather than this:



        if type(num) == list:


        use isinstance.



        Member mutability



        You shouldn't care that num is coming in as a list; you should only check that it's iterable. And store it as a tuple, not a list, because you don't (and shouldn't) mutate it in your class code.



        Call reversed once



        This:



        zip(reversed(self.digits), reversed(o.digits))


        should be



        reversed(zip(self.digits, o.digits))


        Don't use strings for math



        Just don't. This:



        a.digits, b.digits = ['0']


        is not a good idea. Use actual digits whenever possible, and it is possible here.







        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered 9 hours ago









        ReinderienReinderien

        8,37013 silver badges38 bronze badges




        8,37013 silver badges38 bronze badges


























            Thomas is a new contributor. Be nice, and check out our Code of Conduct.










            draft saved

            draft discarded

















            Thomas is a new contributor. Be nice, and check out our Code of Conduct.













            Thomas is a new contributor. Be nice, and check out our Code of Conduct.












            Thomas is a new contributor. Be nice, and check out our Code of Conduct.
















            Thanks for contributing an answer to Code Review Stack Exchange!


            • 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.


            Use MathJax to format equations. MathJax reference.


            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f228924%2fkarazuba-algorithm-with-arbitrary-bases%23new-answer', 'question_page');
            }
            );

            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







            Popular posts from this blog

            Taj Mahal Inhaltsverzeichnis Aufbau | Geschichte | 350-Jahr-Feier | Heutige Bedeutung | Siehe auch |...

            Baia Sprie Cuprins Etimologie | Istorie | Demografie | Politică și administrație | Arii naturale...

            Ciclooctatetraenă Vezi și | Bibliografie | Meniu de navigare637866text4148569-500570979m