WeBWorK Problems

Partition of integers

Re: Partition of integers

by Davide Cervone -
Number of replies: 0
For completeness, here is an example of how to write the custom checker that walks the parse tree to collect the terms, without having to create your own Context or MathObject classes.
    $context = Context("Numeric");
    
    #
    #  Remove everything by addition and commas
    #  from the context
    #
    Parser::Number::NoDecimals();
    $context->variables->clear();
    $context->strings->clear();
    $context->constants->clear();
    $context->functions->disable("all");
    $context->operators->undefine($context->operators->names);
    $context->operators->redefine(["fn",",","+"]);
    $context->operators->remove(" ");
    
    #
    #  Keep student answers unevaluated
    #
    $context->flags->set(
      reduceConstants => 0,
      formatStudentAnswer => 'parsed',
    );
    
    BEGIN_TEXT
    Enter a partition: \{ans_rule\}
    END_TEXT
    
    #
    #  Turn a tree of addition into an array
    #  (should really check that numbers are
    #  positive, since zero could appear here).
    #
    sub getTerms {
      my $bop = shift;
      return $bop->{value} if $bop->class eq "Number";
      Value->Error("Formula doesn't appear to be a partition")
        unless $bop->class eq "BOP" && $bop->{bop} eq "+";
      return (getTerms($bop->{lop}),getTerms($bop->{rop}));
    }

    #
    #  Use a custom checker that collects the numbers
    #  from the partitions and compares the sorted results.
    #
    ANS(Compute("1 + 3 + 5")->cmp(
      cmp_class => "a Partition",
      checker => sub {
        my ($correct,$student,$ans) = @_;
        my $S = join('+',num_sort(getTerms($ans->{student_formula}{tree})));
        my $C = join('+',num_sort(getTerms($correct->{original_formula}{tree})));
        return $C eq $S;
      }
    ));
Hope that helps clarify things.