गणितीय अभिव्यक्ति का दिखावा!


15

आपको 6 नंबर दिए गए हैं: 5 अंक [0-9] और एक लक्ष्य संख्या। आपका लक्ष्य अंकों के बीच परिचालकों को फैलाना है ताकि आप लक्ष्य के करीब पहुंच सकें। आप प्रत्येक अंक का उपयोग करने के बिल्कुल एक बार, और निम्न ऑपरेटरों का उपयोग कर सकते हैं कई के रूप में कई बार के रूप में आप चाहते हैं: + - * / () ^ sqrt sin cos tan। उदाहरण के लिए, अगर मुझे दिया जाता है तो मैं 8 2 4 7 2 65आउटपुट कर सकता हूं 82-(2*7)-4। यह 64 का मूल्यांकन करता है, इस प्रकार मुझे 1 का स्कोर देता है क्योंकि मैं लक्ष्य से 1 दूर था। नोट: आप अंकों के बीच एक दशमलव बिंदु नहीं रख सकते।

मैं गणितीय अभिव्यक्तियों का मूल्यांकन करने के लिए इस StackOverflow उत्तर से कोड का उपयोग कर रहा हूं । इस प्रश्न के निचले भाग में ऐसे प्रोग्राम हैं जिन्हें आप इसका परीक्षण करने के लिए उपयोग कर सकते हैं।

चेनिंग फ़ंक्शंस (अपडेट!)

@mdahmoune ने इस चुनौती के लिए एक नए स्तर की जटिलता का खुलासा किया है। जैसे, मैं एक नई सुविधा जोड़ रहा हूँ: यूनिरी फ़ंक्शंस का पीछा करते हुए। यह पाप, cos, tan और sqrt पर काम करता है। अब लिखने के बजाय लिख sin(sin(sin(sin(10))))सकते हैं sin_4(10)। मूल्यांकनकर्ता में इसे आज़माएं!

इनपुट

5 अंकों के 200 लाइन-अलग-अलग परीक्षण मामले और अंतरिक्ष-अलग होने वाले लक्ष्य संख्या। आप नमूना परीक्षण मामलों को बनाने के लिए प्रश्न के निचले भाग में कार्यक्रम का उपयोग कर सकते हैं, लेकिन मेरे पास आधिकारिक स्कोरिंग के लिए अपने स्वयं के परीक्षण मामले होंगे। लक्ष्य संख्या के लिए निम्नलिखित सीमा के साथ परीक्षण मामलों को 40 परीक्षणों के 5 खंडों में विभाजित किया गया है:

  • धारा 1: [0,1] (5 दशमलव अंक तक)
  • धारा 2: [0,10] (4 दशमलव अंक तक)
  • धारा 3: [0,1000] (3 दशमलव अंक तक)
  • धारा 4: [0,10 6 ] (1 दशमलव बिंदु तक)
  • धारा 5: [0,10 9 ] (0 दशमलव अंक तक)

उत्पादन

200 लाइन ने गणितीय अभिव्यक्तियों को अलग कर दिया। उदाहरण के लिए, यदि परीक्षण का मामला है 5 6 7 8 9 25.807, तो एक संभावित आउटपुट हो सकता है78-59+6

स्कोरिंग

लक्ष्य प्रत्येक गोल अन्य प्रतिस्पर्धी कार्यक्रमों की तुलना में लक्ष्य संख्या के करीब पहुंचना है। मैं मारियो कार्ट 8 स्कोरिंग का उपयोग करने जा रहा हूं , जो है :। यदि कई उत्तरों को एक ही सटीक अंक मिलता है, तो अंक समान रूप से विभाजित हो जाते हैं, निकटतम इंट में गोल हो जाते हैं। उदाहरण के लिए, यदि 5 वें -8 वें स्थान पर कार्यक्रमों को बांधा जाता है, तो वे प्रत्येक (8 + 7 + 6 + 5) / 4 = 6.5 => 7 अंक प्राप्त करते हैं। 200 राउंड के अंत में, जिस कार्यक्रम को सबसे अधिक अंक मिले, वह जीत गया। यदि दो कार्यक्रमों के अंत में समान अंक हैं, तो टाई-ब्रेकर वह प्रोग्राम है जो तेजी से समाप्त हो रहा है।1st: 15 2nd: 12 3rd: 10 4th: 9 5th: 8 6th: 7 7th: 6 8th: 5 9th: 4 10th: 3 11th: 2 12th: 1 13th+: 0

नियम

  1. आप केवल मैक पर C, C ++, Java, PhP, पर्ल, पायथन (2 या 3), रूबी, और स्विफ्ट जैसी भाषाओं में से किसी एक का उपयोग कर सकते हैं। यदि आपके पास एक भाषा है जिसे आप संकलक / दुभाषिया के साथ उपयोग करना चाहते हैं जो एक अपेक्षाकृत छोटा डाउनलोड है जो मैं इसे जोड़ सकता हूं। आप एक भाषा का उपयोग ऑनलाइन दुभाषिया के साथ भी कर सकते हैं, लेकिन यह उतनी तेज़ नहीं चलेगी।
  2. अपने जवाब में निर्दिष्ट करें कि क्या आप ट्रिगर कार्यों को डिग्री या रेडियन में गणना करना चाहते हैं ।
  3. आपके कार्यक्रम को मेरे मैक पर 60 सेकंड के भीतर सभी 200 परीक्षण मामलों (एक फ़ाइल या एसटीडीयूएसटी) के लिए अपने समाधान का उत्पादन करना होगा ।
  4. बेतरतीब होना चाहिए।
  5. सभी परीक्षण मामलों के लिए आपका कुल उत्पादन 1 एमबी से अधिक नहीं हो सकता है ।
  6. यदि आपने अपने समाधान में सुधार किया है और फिर से स्कोर करना चाहते हैं, तो अपने उत्तर में सबसे ऊपर पुनः स्कोर को बोल्ड में जोड़ें।

कार्यक्रम

(यदि आप रेडियन चाहते हैं तो "deg" तर्क को "रेड" में बदलें)

  1. मूल्यांकनकर्ता का परीक्षण करें
  2. परीक्षण मामलों के लिए अपने कार्यक्रम का आउटपुट स्कोर करें
  3. परीक्षण के मामले उत्पन्न करें:

document.getElementById("but").onclick = gen;
var checks = document.getElementById("checks");
for(var i = 1;i<=6;i++) {
var val = i<6 ? i : "All";
var l = document.createElement("label");
l.for = "check" + val;
l.innerText = " "+val+" ";
checks.appendChild(l);
  var check = document.createElement("input");
  check.type = "checkBox";
  check.id = "check"+val;
  if(val == "All") {
  check.onchange = function() {
  if(this.checked == true)  {
  for(var i = 0;i<5;i++) {
    this.parentNode.elements[i].checked = true;
  }
  }
};  
  }
  else {
  check.onchange = function() {
    document.getElementById("checkAll").checked = false;
  }
  }
  checks.appendChild(check);
  
}



function gen() {
var tests = [];
var boxes = checks.elements;
if(boxes[0].checked)genTests(tests,1,5,40);
if(boxes[1].checked)genTests(tests,10,4,40);
if(boxes[2].checked)genTests(tests,1000,3,40);
if(boxes[3].checked)genTests(tests,1e6,1,40);
if(boxes[4].checked)genTests(tests,1e9,0,40);
document.getElementById("box").value =  tests.join("\n");
}

function genTests(testArray,tMax,tDec,n) {
for(var i = 0;i<n;i++) {
  testArray.push(genNums(tMax,tDec).join(" "));
}
}

function genNums(tMax,tDec) {
var nums = genDigits();
nums.push(genTarget(tMax,tDec));
return nums;
}

function genTarget(tMax,tDec) {
  return genRand(tMax,tDec);
}

function genRand(limit,decimals) {
  var r = Math.random()*limit;
  return r.toFixed(decimals);
}

function genDigits() {
  var digits = [];
   for(var i = 0;i<5;i++) {
    digits.push(Math.floor(Math.random()*10));
   }
   return digits;
}
textarea {
  font-size: 14pt;
  font-family: "Courier New", "Lucida Console", monospace;
}

div {
text-align: center;
}
<div>
<label for="checks">Sections: </label><form id="checks"></form>
<input type="button" id="but" value="Generate Test Cases" /><br/><textarea id="box" cols=20 rows=15></textarea>
</div>

लीडरबोर्ड

  1. user202729 ( C ++ ): 2856, 152 जीत
  2. mdahmoune ( पायथन 2 ) [v2]: 2544, 48 जीत

अनुभाग स्कोर (जीत का #):

  1. [0-1] उपयोगकर्ता 202729 : 40, mdahmoune: 0
  2. [0-10] user202729 : 40, mdahmoune: 0
  3. [0-1000] user202729 : 39, mdahmoune: 1
  4. [0-10 6 ] user202729 : 33, mdahmoune: 7
  5. [0-10 9 ] उपयोगकर्ता 202729: 0, mdahmoune : 40

संबंधित: उपयोगकर्ता-निर्दिष्ट संख्याओं का उपयोग करके एक वैध समीकरण बनाएं


क्या कोई विशेष कारण है कि त्रिकोणमितीय फ़ंक्शंस में डिग्री का उपयोग होता है? क्या रेडियन या डिग्री निर्दिष्ट करने के उत्तर के लिए एक विकल्प संभवतः जोड़ा जा सकता है?
नॉटजागन

क्या अंकों के सेट में एक गैर शून्य अंक होना आवश्यक है?
mdahmoune

@mdahmoune परीक्षण मामले बेतरतीब ढंग से उत्पन्न होते हैं, इसलिए अंक सभी 0. हो सकते हैं। आपको बस उस स्थिति में अपना सर्वश्रेष्ठ प्रदर्शन करना होगा। डिग्री मोड में मैं 3283.14 तक सभी तरह से प्राप्त करने में सक्षम था cos(0)/sin(0^0)/sin(0^0)
geokavel

अपने पूर्ण उत्तर के लिए
थैंक्स

क्या यह 5 विभिन्न वर्गों के लिए एक ही स्कोरिंग पद्धति है? ABS (target_value-generated_expression_value)? I
mdahmoune

जवाबों:


3

सी ++

// This program use radian mode

//#define DEBUG

#ifdef DEBUG
#define _GLIBCXX_DEBUG
#include <cassert>
#else
#define assert(x) void(0)
#endif

namespace std {
    /// Used for un-debug.
    struct not_cerr_t {
    } not_cerr;
}

template <typename T>
std::not_cerr_t& operator<<(std::not_cerr_t& not_cerr, T) {return not_cerr;}

#include <iostream>
#include <iomanip>
#include <cmath>
#include <limits>
#include <array>
#include <bitset>
#include <string>
#include <sstream>

#ifndef DEBUG
#define cerr not_cerr
#endif // DEBUG


// String conversion functions, because of some issues with MinGW
template <typename T>
T from_string(std::string st) {
    std::stringstream sst (st);
    T result;
    sst >> result;
    return result;
}

template <typename T>
std::string to_string(T x) {
    std::stringstream sst;
    sst << x;
    return sst.str();
}

template <typename T> int sgn(T val) {
    return (T(0) < val) - (val < T(0));
}


const int N_ITER = 1000, N_DIGIT = 5, NSOL = 4;
std::array<int, N_DIGIT> digits;
double target;

typedef std::bitset<N_ITER> stfunc; // sin-tan expression
// where sin = 0, tan = 1

double eval(const stfunc& fn, int length, double value) {
    while (length --> 0) {
        value = fn[length] ? std::tan(value) : std::sin(value);
    }
    return value;
}

struct stexpr { // just a stfunc with some information
    double x = 0, val = 0; // fn<length>(x) == val
    int length = 0;
    stfunc fn {};
//    bool operator[] (const int x) {return fn[x];}
    double eval() {return val = ::eval(fn, length, x);}
};

struct expr { // general form of stexpr
    // note that expr must be *always* atomic.
    double val = 0;
    std::string expr {};

    void clear() {
        val = 0;
        expr.clear();
    }

    // cos(cos(x)) is in approx 0.5 - 1,
    // so we can expect that sin(x) and tan(x) behaves reasonably nice
    private: void wrapcos2() {
        expr = "(cos_2 " + expr + ")"; // we assume that all expr is atomic
        val = std::cos(std::cos(val));
    }

    public: void wrap1() {
        if (val == 0) {
            expr = "(cos " + expr + ")"; // we assume that all expr is atomic
            val = std::cos(val);
        }
        if (val == 1) return;
        wrapcos2(); // range 0.54 - 1
        int cnt_sqrt = 0;
        for (int i = 0; i < 100; ++i) {
            ++cnt_sqrt;
            val = std::sqrt(val);
            if (val == 1) break;
        }
        expr = "(sqrt_" + to_string(cnt_sqrt) + " " + expr + ")"; // expr must be atomic
    }
};

stexpr nearest(double initial, double target) {
    stexpr result; // built on the fn of that
    result.x = initial;
    double value [N_ITER + 1];
    value[0] = initial;
    for (result.length = 1; result.length <= N_ITER; ++result.length) {
        double x = value[result.length-1];
        if (x < target) {
            result.fn[result.length-1] = 1;
        } else if (x > target) {
            result.fn[result.length-1] = 0;
        } else { // unlikely
            --result.length;
//            result.val = x;
            result.eval();
            assert(result.val == x);
            return result;
        }
        value[result.length] = result.eval(); // this line takes most of the time
        if (value[result.length] == value[result.length-1])
            break;
    }

//    for (int i = 0; i < N_ITER; ++i) {
//        std::cerr << i << '\t' << value[i] << '\t' << (value[i] - target) << '\n';
//    }

    double mindiff = std::numeric_limits<double>::max();
    int resultlength = -1;
    result.length = std::min(N_ITER, result.length);
    for (int l = 0; l <= result.length; ++l) {
        if (std::abs(value[l] - target) < mindiff) {
            mindiff = std::abs(value[l] - target);
            resultlength = l;
        }
    }

    result.length = resultlength;
    double val = value[resultlength];
    assert(std::abs(val - target) == mindiff);
    if (val != target) { // second-order optimization
        for (int i = 1; i < result.length; ++i) {
            // consider pair (i-1, i)
            if (result.fn[i-1] == result.fn[i]) continue; // look for (sin tan) or (tan sin)
            if (val < target && result.fn[i-1] == 0) { // we need to increase val : sin tan -> tan sin
                result.fn[i-1] = 1;
                result.fn[i] = 0;
                double newvalue = result.eval();
//                if (!(newvalue >= val)) std::cerr << "Floating point sin-tan error 1\n";
                if (std::abs(newvalue - target) < std::abs(val - target)) {
//                    std::cerr << "diff improved from " << std::abs(val - target) << " to " << std::abs(newvalue - target) << '\n';
                    val = newvalue;
                } else {
                    result.fn[i-1] = 0;
                    result.fn[i] = 1; // restore
                    #ifdef DEBUG
                    result.eval();
                    assert(val == result.val);
                    #endif // DEBUG
                }
            } else if (val > target && result.fn[i-1] == 1) {
                result.fn[i-1] = 0;
                result.fn[i] = 1;
                double newvalue = result.eval();
//                if (!(newvalue <= val)) std::cerr << "Floating point sin-tan error 2\n";
                if (std::abs(newvalue - target) < std::abs(val - target)) {
//                    std::cerr << "diff improved from " << std::abs(val - target) << " to " << std::abs(newvalue - target) << '\n';
                    val = newvalue;
                } else {
                    result.fn[i-1] = 1;
                    result.fn[i] = 0; // restore
                    #ifdef DEBUG
                    result.eval();
                    assert(val == result.val);
                    #endif // DEBUG
                }
            }
        }
    }
    double newdiff = std::abs(val - target);
    if (newdiff < mindiff) {
        mindiff = std::abs(val - target);
        std::cerr << "ok\n";
    } else if (newdiff > mindiff) {
        std::cerr << "Program error : error value = " << (newdiff - mindiff) << " (should be <= 0 if correct) \n";
        std::cerr << "mindiff = " << mindiff << ", newdiff = " << newdiff << '\n';
    }
    result.eval(); // set result.result
    assert(val == result.val);

    return result;
}

expr nearest(const expr& in, double target) {
    stexpr tmp = nearest(in.val, target);
    expr result;
    for (int i = 0; i < tmp.length; ++i)
        result.expr.append(tmp.fn[i] ? "tan " : "sin ");

    result.expr = "(" + result.expr + in.expr + ")";
    result.val = tmp.val;
    return result;
}

int main() {
    double totalscore = 0;

    assert (std::numeric_limits<double>::is_iec559);
    std::cerr << std::setprecision(23);

//    double initial = 0.61575952241185627;
//    target = 0.6157595200093855;
//    stexpr a = nearest(initial, target);
//    std::cerr << a.val << ' ' << a.length << '\n';
//    return 0;

    while (std::cin >> digits[0]) {
        for (unsigned i = 1; i < digits.size(); ++i) std::cin >> digits[i];
        std::cin >> target;

/*        std::string e;
//        int sum = 0;
//        for (int i : digits) {
//            sum += i;
//            e.append(to_string(i)).push_back('+');
//        }
//        e.pop_back(); // remove the last '+'
//        e = "cos cos (" + e + ")";
//        double val = std::cos(std::cos((double)sum));
//
//        stexpr result = nearest(val, target); // cos(cos(x)) is in approx 0.5 - 1,
//        // so we can expect that sin(x) and tan(x) behaves reasonably nice
//        std::string fns;
//        for (int i = 0; i < result.length; ++i) fns.append(result.fn[i] ? "tan" : "sin").push_back(' ');
//
//        std::cout << (fns + e) << '\n';
//        continue;*/

        std::array<expr, NSOL> sols;
        expr a, b, c, d; // temporary for solutions

        /* ----------------------------------------
           solution 1 : nearest cos cos sum(digits) */

        a.clear();
        for (int i : digits) {
            a.val += i; // no floating-point error here
            a.expr.append(to_string(i)).push_back('+');
        }
        a.expr.pop_back(); // remove the last '+'
        a.expr = "(" + a.expr + ")";
        a.wrap1();

        sols[0] = nearest(a, target);


        /* -----------------------------------------
              solution 2 : a * tan(b) + c (also important) */

        // find b first, then a, then finally c
        a.clear(); b.clear(); c.clear(); // e = a, b = e1, c = e2

        a.expr = to_string(digits[0]);
        a.val = digits[0];
        a.wrap1();

        b.expr = "(" + to_string(digits[1]) + "+" + to_string(digits[2]) + ")";
        b.val = digits[1] + digits[2];
        b.wrap1();

        c.expr = to_string(digits[3]);
        c.val = digits[3];
        c.wrap1();

        d.expr = to_string(digits[4]);
        d.val = digits[4];
        d.wrap1();

        b = nearest(b, std::atan(target));

        double targetA = target / std::tan(b.val);
        int cnt = 0;
        while (targetA < 1 && targetA > 0.9) {
            ++cnt;
            targetA = targetA * targetA;
        }
        a = nearest(a, targetA);
        while (cnt --> 0) {
            a.val = std::sqrt(a.val);
            a.expr = "sqrt " + a.expr;
        }
        a.expr = "(" + a.expr + ")"; // handle number of the form 0.9999999999

        /// partition of any number to easy-to-calculate sum of 2 numbers
        {{{{{{{{{{{{{{{{{{{{{{{{{{{{}}}}}}}}}}}}}}}}}}}}}}}}}}}}

        double targetC, targetD; // near 1, not in [0.9, 1), >= 0.1
        // that is, [0.1, 0.9), [1, inf)

        double target1 = target - (a.val * std::tan(b.val));

        double ac = std::abs(target1), sc = sgn(target1);
        if (ac < .1) targetC = 1 + ac, targetD = -1;
        else if (ac < 1) targetC = 1 + ac/2, targetD = ac/2 - 1;
        else if (ac < 1.8 || ac > 2) targetC = targetD = ac/2;
        else targetC = .8, targetD = ac - .8;

        targetC *= sc; targetD *= sc;

        c = nearest(c, std::abs(targetC)); if (targetC < 0) c.val = -c.val, c.expr = "(-" + c.expr + ")";
        d = nearest(d, std::abs(targetD)); if (targetD < 0) d.val = -d.val, d.expr = "(-" + d.expr + ")";

        sols[1].expr = a.expr + "*tan " + b.expr + "+" + c.expr + "+" + d.expr;
        sols[1].val = a.val * std::tan(b.val) + c.val + d.val;

        std::cerr
        << "\n---Method 2---"
        << "\na = " << a.val
        << "\ntarget a = " << targetA
        << "\nb = " << b.val
        << "\ntan b = " << std::tan(b.val)
        << "\nc = " << c.val
        << "\ntarget c = " << targetC
        << "\nd = " << d.val
        << "\ntarget d = " << targetD
        << "\n";

        /* -----------------------------------------
              solution 3 : (b + c) */

        target1 = target / 2;
        b.clear(); c.clear();

        for (int i = 0; i < N_DIGIT; ++i) {
            expr &ex = (i < 2 ? b : c);
            ex.val += digits[i];
            ex.expr.append(to_string(digits[i])).push_back('+');
        }
        b.expr.pop_back();
        b.expr = "(" + b.expr + ")";
        b.wrap1();

        c.expr.pop_back();
        c.expr = "(" + c.expr + ")";
        c.wrap1();

        b = nearest(b, target1);
        c = nearest(c, target - target1); // approx. target / 2

        sols[2].expr = "(" + b.expr + "+" + c.expr + ")";
        sols[2].val = b.val + c.val;

        /* -----------------------------------------
              solution 4 : a (*|/) (b - c)  (important) */

        a.clear(); b.clear(); c.clear(); // a = a, b = e1, c = e2

        a.expr = to_string(digits[0]);
        a.val = digits[0];
        a.wrap1();

        b.expr = "(" + to_string(digits[1]) + "+" + to_string(digits[2]) + ")";
        b.val = digits[1] + digits[2];
        b.wrap1();

        c.expr = "(" + to_string(digits[3]) + "+" + to_string(digits[4]) + ")";
        c.val = digits[3] + digits[4];
        c.wrap1();


        // (b-c) should be minimized
        bool multiply = target < a.val;
        double factor = multiply ? target / a.val : a.val / target;

        target1 = 1 + 2 * factor; // 1 + 2 * factor and 1 + factor

        std::cerr << "* Method 4 :\n";
        std::cerr << "b initial = " << b.val << ", target = " << target1 << ", ";
        b = nearest(b, target1);
        std::cerr << " get " << b.val << '\n';

        std::cerr << "c initial = " << c.val << ", target = " << b.val - factor << ", ";
        c = nearest(c, b.val - factor); // factor ~= e1.val - e2.val
        std::cerr << " get " << c.val << '\n';

        sols[3].expr = "(" + a.expr + (multiply ? "*(" : "/(") +
        ( b.expr + "-" + c.expr )
        + "))";
        factor = b.val - c.val;
        sols[3].val = multiply ? a.val * factor : a.val / factor;

        std::cerr << "a.val = " << a.val << '\n';

        /* ----------------------------------
                    Final result */

        int minindex = 0;
        assert(NSOL != 0);
        for (int i = 0; i < NSOL; ++i) {
            if (std::abs(target - sols[i].val) < std::abs(target - sols[minindex].val)) minindex = i;
            std::cerr << "Sol " << i << ", diff = " << std::abs(target - sols[i].val) << "\n";
        }
        std::cerr << "Choose " << minindex << "; target = " << target << '\n';
        totalscore += std::abs(target - sols[minindex].val);

        std::cout << sols[minindex].expr << '\n';
    }

    // #undef cerr // in case no-debug
    std::cerr << "total score = " << totalscore << '\n';
}

मानक इनपुट से इनपुट, आउटपुट से मानक आउटपुट।


हां, मुझे लगता है <1MB। ध्यान दें कि यदि प्रोग्राम कुछ का उल्लंघन करता है तो आप घट सकते हैं N_ITER(वर्तमान में 1000 है)
user202729

@geokavel अब यह संदिग्ध है अगर 1 / sin_100000000 (2)अनुमति दी जाए, या sin_1.374059274 (1)
user202729

1 / sin_100000000 (2)यदि आपके पास अपने निपटान में अंक 1 और 2 हैं, तो अनुमति दी जाती है। मुझे नहीं पता कि कैसे sin_1.374059274काम करेगा। एक गैर-पूर्णांक संख्या में पाप को दोहराने का क्या मतलब है?
जियोकावेल

@geokavel लेकिन मूल्यांकन करने के लिए पूर्व सूत्र हमेशा के लिए लेता है, इसलिए स्कोर की गणना करना कठिन नहीं है। बाद में परिभाषित किया जा सकता है en.wikipedia.org/wiki/… | आधिकारिक परीक्षण मामलों पर कार्यक्रम कैसा है?
user202729

मैं देख रहा हूं कि आंशिक आंशिकरण से आपका क्या मतलब है, लेकिन मुझे लगता है कि इसे लागू करना मेरे लिए बहुत कठिन है। आपका कार्यक्रम अच्छे समय में चलता है - केवल 25 सेकंड के लिए।
जियोकॉवेल

2

पायथन 2 , रेडियंस, आधिकारिक परीक्षण पर स्कोर 0.0032

यह दूसरा मसौदा समाधान है, जो 0.0032 अंकों का औसत स्कोर देता है। जैसा कि sinमैंने आउटपुट फॉर्मूला के लिए निम्न कॉम्पैक्ट नोटेशन का उपयोग किया है,

  • sin_1 x=sin(x)
  • sin_2 x=sin(sin(x))
  • ...
  • sin_7 x=sin(sin(sin(sin(sin(sin(sin(x)))))))
  • ...
import math
import bisect
s1=[[float(t) for t in e.split()] for e in s0.split('\n')]
maxi=int(1e7)
A=[]
B=[]
C=[]
D=[]
a=1
for i in range(maxi):
	A.append(a)
	C.append(1/a)
	b=math.sin(a)
	c=a-b
	B.append(1/c)
	D.append(c)
	a=b
B.sort() 
C.sort() 
A.sort() 
D.sort() 
d15={0:'sqrt_100 tan_4 cos_2 sin 0',1:'sqrt_100 tan_4 cos_2 sin 1',2:'sqrt_100 tan_2 cos_2 sin 2',3:'sqrt_100 tan_4 cos_2 sin 3',4:'sqrt_100 tan_4 cos_2 sin 4',5:'sqrt_100 tan_4 cos_2 sin 5',6:'sqrt_100 tan_4 cos_2 sin 6',7:'sqrt_100 tan_2 cos_2 sin 7',8:'sqrt_100 tan_2 cos_2 sin 8',9:'sqrt_100 tan_4 cos_2 sin 9'}
def d16(d):return '('+d15[d]+')'

def S0(l):
	cpt=0
	d=l[:-1]
	r=l[-1]
	a1,a2,a3,a4,a5=[int(t) for t in d]
	i1=bisect.bisect(B, r)-1
	w1=abs(r-B[i1])
	i2=bisect.bisect(C, w1)-1
	w2=abs(w1-C[i2]) 
	s='('+d16(a1)+'/(sin_'+str(i1)+' '+d16(a2)+'-'+'sin_'+str(i1+1)+' '+d16(a3)+')'+'+'+d16(a4)+'/sin_'+str(i2)+' '+d16(a5)+')'
	return (w2,s)

def S1(l):
	cpt=0
	d=l[:-1]
	r=l[-1]
	a1,a2,a3,a4,a5=[int(t) for t in d]
	i1=bisect.bisect(C, r)-1
	w1=abs(r-C[i1])
	i2=bisect.bisect(A, w1)-1
	w2=abs(w1-A[i2]) 
	s='('+d16(a1)+'/sin_'+str(i1)+' '+d16(a2)+'+sin_'+str(maxi-i2-1)+' ('+d16(a3)+'*'+d16(a4)+'*'+d16(a5)+')'
	return (w2,s)

def S2(l):
	cpt=0
	d=l[:-1]
	r=l[-1]
	a1,a2,a3,a4,a5=[int(t) for t in d]
	i1=bisect.bisect(A, r)-1
	w1=abs(r-A[i1])
	i2=bisect.bisect(D, w1)-1
	w2=abs(w1-D[i2]) 
	s='('+'(sin_'+str(maxi-i2-1)+' '+d16(a1)+'-'+'sin_'+str(maxi-i2)+' '+d16(a2)+')'+'+sin_'+str(maxi-i1-1)+' ('+d16(a3)+'*'+d16(a4)+'*'+d16(a5)+'))'
	return (w2,s)

def S3(l):
	cpt=0
	d=l[:-1]
	r=l[-1]
	a1,a2,a3,a4,a5=[int(t) for t in d]
	i1=bisect.bisect(A, r)-1
	w2=abs(r-A[i1])
	s='('+'sin_'+str(maxi-i1-1)+' ('+d16(a1)+'*'+d16(a2)+'*'+d16(a3)+'*'+d16(a4)+'*'+d16(a5)+'))'
	return (w2,s)

def S4(l):
	cpt=0
	d=l[:-1]
	r=l[-1]
	a1,a2,a3,a4,a5=[int(t) for t in d]
	i1=bisect.bisect(B, r)-1
	w2=abs(r-B[i1])
	s='('+d16(a1)+'/(sin_'+str(i1)+' '+d16(a2)+'-'+'sin_'+str(i1+1)+' '+d16(a3)+'*'+d16(a4)+'*'+d16(a5)+')'+')'
	return (w2,s)

def S5(l):
	cpt=0
	d=l[:-1]
	r=l[-1]
	a1,a2,a3,a4,a5=[int(t) for t in d]
	i1=bisect.bisect(C, r)-1
	w2=abs(r-C[i1])
	s='('+d16(a1)+'/sin_'+str(i1)+' '+d16(a2)+'*'+d16(a3)+'*'+d16(a4)+'*'+d16(a5)+')'
	return (w2,s)

def S6(l):
	cpt=0
	d=l[:-1]
	r=l[-1]
	a1,a2,a3,a4,a5=[int(t) for t in d]
	i1=bisect.bisect(D, r)-1
	w2=abs(r-D[i1])
	s='(sin_'+str(maxi-i1-1)+' '+d16(a1)+'-'+'sin_'+str(maxi-i1)+' '+d16(a2)+'*'+d16(a3)+'*'+d16(a4)+'*'+d16(a5)+')'
	return (w2,s)

def all4(s1):
	s=0
	for l in s1:
		f=min(S0(l),S1(l),S2(l),S3(l),S4(l),S5(l),S6(l))
		print f[1]
		s+=f[0]
	s/=len(s1)
	print 'average unofficial score:',s
all4(s1)

इसे ऑनलाइन आज़माएं!


1
आपके कार्यक्रम को आधिकारिक परीक्षणों पर 49.70 का मोय मिलता है। कुछ कारणों से यह निम्नलिखित अंकों के साथ खंड 3 में एक परीक्षण मामले पर वास्तव में बुरा करता है 6 7 8 0 1:।
geokavel

आपका प्रोग्राम +(tan_4 cos_2 sin 6)/(sin_0((-(tan_4 cos_2 sin 7)-(tan_4 cos_2 sin 8)+(tan_4 cos_2 sin 0)+(tan_4 cos_2 sin 1))))उस टेस्ट केस के लिए आउटपुट करता है , जो 0.145 के बराबर है।
जियोकॉवेल

क्षमा करें, मैंने पहली बार आपका आधिकारिक टेस्ट स्कोर गलत लिखा है। आप वास्तव में आधिकारिक परीक्षणों पर औसत से थोड़ा बुरा करते हैं।
जियोकॉवेल
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.