<commit_before>use v6;

class Math::Polynomial
{
    has @.coefficients;

    multi method new (*@x)
    {
        self.new: @x.item;
    }

    multi method new (@x is copy)
    {
        while @x.elems > 1 && @x[*-1].abs < 1e-13
        {
            # say @x.perl;
            # say @x[*-1];
            @x.pop;
        }

        @x.push: 0 if @x.elems == 0;

        self.bless: *, coefficients => @x;
    }

    multi method Str() returns Str
    {
        @.coefficients.keys.map({"{@.coefficients[$_]} x^$_"}).reverse.join(" + ");
    }

    multi method perl() returns Str
    {
        self.WHAT.perl ~ ".new(" ~ @.coefficients.map({.perl}).join(', ') ~ ")";
    }

    multi method evaluate($x)
    {
        # would be more elegant with Z+, once that works
        my $result = @.coefficients[0] * 0;
        for @.coefficients Z (1, $x, $x * $x ... *) -> $a, $z {
            $result = $result + $a * $z;
        }
        $result;
    }

    multi sub infix:<+>(Math::Polynomial $a, Math::Polynomial $b) is export(:DEFAULT)
    {
        my @poly = gather for ^(+$a.coefficients max +$b.coefficients) -> $i {
            if $i < +$a.coefficients && $i < +$b.coefficients {
                take $a.coefficients[$i] + $b.coefficients[$i];
            } elsif $i < +$a.coefficients {
                take $a.coefficients[$i];
            } else {
                take $b.coefficients[$i];
            }
        }

        $a.new: @poly;
    }

    multi sub infix:<+>(Math::Polynomial $a, $b) is export(:DEFAULT)
    {
        my @ac = $a.coefficients;
        @ac[0] += $b;
        return $a.new: @ac;
    }

    multi sub infix:<+>($b, Math::Polynomial $a) is export(:DEFAULT)
    {
        $a + $b;
    }

    multi sub prefix:<->(Math::Polynomial $a) is export(:DEFAULT)
    {
        $a.new: $a.coefficients.map({-$_});
    }

    multi sub infix:<->(Math::Polynomial $a, Math::Polynomial $b) is export(:DEFAULT)
    {
        -$b + $a;
    }

    multi sub infix:<->(Math::Polynomial $a, $b) is export(:DEFAULT)
    {
        my @ac = $a.coefficients;
        @ac[0] -= $b;
        return $a.new: @ac;
    }

    multi sub infix:<->($b, Math::Polynomial $a) is export(:DEFAULT)
    {
        -$a + $b;
    }

    multi sub infix:<*>(Math::Polynomial $a, Math::Polynomial $b) is export(:DEFAULT)
    {
        my @coef = 0.0 xx ($a.coefficients.elems + $b.coefficients.elems - 1);
        for $a.coefficients.keys -> $m
        {
            for $b.coefficients.keys -> $n
            {
                @coef[$m + $n] += $a.coefficients[$m] * $b.coefficients[$n];
            }
        }

        return $a.new: @coef;
    }

    multi sub infix:<*>(Math::Polynomial $a, $b) is export(:DEFAULT)
    {
        $a.new: $a.coefficients >>*>> $b;
    }

    multi sub infix:<*>($b, Math::Polynomial $a) is export(:DEFAULT)
    {
        $a.new: $a.coefficients >>*>> $b;
    }

    multi sub infix:</>(Math::Polynomial $a, $b) is export(:DEFAULT)
    {
        $a.new: $a.coefficients >>/>> $b;
    }
}
<commit_msg>Refactored to use .kv for efficiency.<commit_after>use v6;

class Math::Polynomial
{
    has @.coefficients;

    multi method new (*@x)
    {
        self.new: @x.item;
    }

    multi method new (@x is copy)
    {
        while @x.elems > 1 && @x[*-1].abs < 1e-13
        {
            # say @x.perl;
            # say @x[*-1];
            @x.pop;
        }

        @x.push: 0 if @x.elems == 0;

        self.bless: *, coefficients => @x;
    }

    multi method Str() returns Str
    {
        @.coefficients.kv.map({ "$^value x^$^key" }).reverse.join: ' + ';
    }

    multi method perl() returns Str
    {
        self.WHAT.perl ~ ".new(" ~ @.coefficients.map({.perl}).join(', ') ~ ")";
    }

    multi method evaluate($x)
    {
        # would be more elegant with Z+, once that works
        my $result = @.coefficients[0] * 0;
        for @.coefficients Z (1, $x, $x * $x ... *) -> $a, $z {
            $result = $result + $a * $z;
        }
        $result;
    }

    multi sub infix:<+>(Math::Polynomial $a, Math::Polynomial $b) is export(:DEFAULT)
    {
        my @poly = gather for ^(+$a.coefficients max +$b.coefficients) -> $i {
            if $i < +$a.coefficients && $i < +$b.coefficients {
                take $a.coefficients[$i] + $b.coefficients[$i];
            } elsif $i < +$a.coefficients {
                take $a.coefficients[$i];
            } else {
                take $b.coefficients[$i];
            }
        }

        $a.new: @poly;
    }

    multi sub infix:<+>(Math::Polynomial $a, $b) is export(:DEFAULT)
    {
        my @ac = $a.coefficients;
        @ac[0] += $b;
        return $a.new: @ac;
    }

    multi sub infix:<+>($b, Math::Polynomial $a) is export(:DEFAULT)
    {
        $a + $b;
    }

    multi sub prefix:<->(Math::Polynomial $a) is export(:DEFAULT)
    {
        $a.new: $a.coefficients.map({-$_});
    }

    multi sub infix:<->(Math::Polynomial $a, Math::Polynomial $b) is export(:DEFAULT)
    {
        -$b + $a;
    }

    multi sub infix:<->(Math::Polynomial $a, $b) is export(:DEFAULT)
    {
        my @ac = $a.coefficients;
        @ac[0] -= $b;
        return $a.new: @ac;
    }

    multi sub infix:<->($b, Math::Polynomial $a) is export(:DEFAULT)
    {
        -$a + $b;
    }

    multi sub infix:<*>(Math::Polynomial $a, Math::Polynomial $b) is export(:DEFAULT)
    {
        my @coef = 0.0 xx ($a.coefficients.elems + $b.coefficients.elems - 1);
        for     $a.coefficients.kv -> $ak, $av {
            for $b.coefficients.kv -> $bk, $bv {
                @coef[ $ak + $bk ] += $av * $bv;
            }
        }

        return $a.new: @coef;
    }

    multi sub infix:<*>(Math::Polynomial $a, $b) is export(:DEFAULT)
    {
        $a.new: $a.coefficients >>*>> $b;
    }

    multi sub infix:<*>($b, Math::Polynomial $a) is export(:DEFAULT)
    {
        $a.new: $a.coefficients >>*>> $b;
    }

    multi sub infix:</>(Math::Polynomial $a, $b) is export(:DEFAULT)
    {
        $a.new: $a.coefficients >>/>> $b;
    }
}

{'fraction_non_alphanumeric': 0.1914787798408488, 'fraction_numerical': 0.005636604774535809, 'mean_word_length': 1.7348141432456936, 'pattern_counts': {'":': 0, '<': 33, '<?xml version=': 0, '>': 61, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '199633', 'n_tokens_mistral': 2339, 'n_tokens_neox': 2201, 'n_words': 488}