ตั้งค่าการคำนวณเชิงทฤษฎี (+ และ *) [ปิด]


10

ตั้งค่าเลขคณิตเชิงทฤษฎี

หลักฐาน

มีการท้าทายสองสามครั้งแล้วที่เกี่ยวข้องกับการคูณโดยไม่มีตัวดำเนินการคูณ ( ที่นี่และที่นี่ ) และความท้าทายนี้อยู่ในหลอดเลือดดำเดียวกัน (ส่วนใหญ่คล้ายกับลิงก์ที่สอง)

ความท้าทายนี้แตกต่างจากก่อนหน้านี้ที่จะใช้คำจำกัดความทางทฤษฎีชุดของตัวเลขธรรมชาติ ( N ):

ป้อนคำอธิบายรูปภาพที่นี่

และ

ป้อนคำอธิบายรูปภาพที่นี่

ตัวอย่างเช่น,

ป้อนคำอธิบายรูปภาพที่นี่

ป้อนคำอธิบายรูปภาพที่นี่

ป้อนคำอธิบายรูปภาพที่นี่

และอื่น ๆ

ความท้าทาย

เป้าหมายของเราคือการใช้การตั้งค่า (ดูด้านล่าง) เพื่อเพิ่มและคูณจำนวนธรรมชาติ เพื่อจุดประสงค์นี้รายการทั้งหมดจะอยู่ในเดียวกัน 'ชุดภาษาที่มีล่ามอยู่ด้านล่าง สิ่งนี้จะให้ความสม่ำเสมอและการให้คะแนนที่ง่ายขึ้น

ล่ามนี้ช่วยให้คุณสามารถจัดการตัวเลขธรรมชาติเป็นชุด งานของคุณคือการเขียนเนื้อหาของโปรแกรมสองรายการ (ดูด้านล่าง) ซึ่งหนึ่งในนั้นจะเพิ่มจำนวนธรรมชาติอีกตัวหนึ่งจะเพิ่มจำนวนทวีคูณ

หมายเหตุเบื้องต้นเกี่ยวกับชุด

ชุดตามโครงสร้างทางคณิตศาสตร์ปกติ นี่คือบางจุดสำคัญ:

  • ไม่มีการสั่งซื้อชุด
  • ไม่มีชุดประกอบด้วยตัวเอง
  • องค์ประกอบอยู่ในเซตหรือไม่นี่คือบูลีน ดังนั้นองค์ประกอบชุดจึงไม่สามารถมีหลายหลากได้ (เช่นองค์ประกอบไม่สามารถอยู่ในชุดได้หลายครั้ง)

ล่ามและข้อมูลเฉพาะ

'โปรแกรม' สำหรับความท้าทายนี้เขียนขึ้นใน 'set language' และประกอบด้วยสองส่วน: ส่วนหัวและเนื้อหา

หัวข้อ

ส่วนหัวนั้นง่ายมาก มันบอกล่ามว่าคุณกำลังแก้ไขโปรแกรมอะไร ส่วนหัวเป็นบรรทัดเปิดของโปรแกรม มันเริ่มต้นด้วย+หรือ*อักขระตามด้วยจำนวนเต็มสองตัวคั่นด้วยช่องว่าง ตัวอย่างเช่น:

+ 3 5

หรือ

* 19 2

เป็นส่วนหัวที่ถูกต้อง ครั้งแรกที่บ่งบอกว่าคุณกำลังพยายามที่จะแก้ปัญหาที่มีความหมายว่าคำตอบของคุณควรจะ3+5 8ที่สองคล้ายกันยกเว้นการคูณ

ร่างกาย

ร่างกายเป็นที่ที่คำแนะนำที่แท้จริงของคุณในการเป็นล่าม นี่คือสิ่งที่ถือว่าเป็นโปรแกรม "การเพิ่ม" หรือ "การคูณ" ของคุณอย่างแท้จริง คำตอบของคุณจะประกอบด้วยเนื้อหาของโปรแกรมสองรายการหนึ่งรายการสำหรับแต่ละงาน จากนั้นคุณจะเปลี่ยนส่วนหัวเพื่อดำเนินการกรณีทดสอบจริง

ไวยากรณ์และคำแนะนำ

คำสั่งประกอบด้วยคำสั่งตามด้วยพารามิเตอร์ศูนย์หรือมากกว่า สำหรับวัตถุประสงค์ของการสาธิตต่อไปนี้ตัวอักษรใด ๆ ที่เป็นชื่อของตัวแปร จำได้ว่าตัวแปรทั้งหมดมีการตั้งค่า labelเป็นชื่อของป้ายกำกับ (ป้ายกำกับเป็นคำที่ตามด้วยเครื่องหมายอัฒภาค (เช่นmain_loop:)) intเป็นจำนวนเต็มต่อไปนี้เป็นคำแนะนำที่ถูกต้อง:

การควบคุมการไหล:
  1. jump labelข้ามไปที่ฉลากอย่างไม่มีเงื่อนไข ป้ายกำกับคือ 'คำ' ตามด้วยเครื่องหมายอัฒภาค: เช่นmain_loop:ป้ายกำกับ
  2. je A label ข้ามไปที่ป้ายกำกับหาก A ว่างเปล่า
  3. jne A label ข้ามไปที่ป้ายกำกับหาก A ไม่ว่างเปล่า
  4. jic A B label ข้ามไปที่ป้ายกำกับหาก A ประกอบด้วย B
  5. jidc A B label ข้ามไปที่ป้ายกำกับหาก A ไม่มี B
การกำหนดตัวแปร
  1. assign A Bหรือassign A int ป้อนคำอธิบายรูปภาพที่นี่หรือ
    ที่set(int)เป็นตัวแทนชุดของint
ตั้งค่า Ops
  1. union A B C ป้อนคำอธิบายรูปภาพที่นี่
  2. intersect A B C
  3. difference A B C ป้อนคำอธิบายรูปภาพที่นี่
  4. add A B ป้อนคำอธิบายรูปภาพที่นี่
  5. remove A B ป้อนคำอธิบายรูปภาพที่นี่
แก้จุดบกพร่อง
  1. print A พิมพ์ค่าจริงของ A โดยที่ {} เป็นชุดว่าง
  2. printi variable พิมพ์การแทนค่าจำนวนเต็มของ A หากมีอยู่มิฉะนั้นเอาต์พุตจะเกิดข้อผิดพลาด
ความคิดเห็น
  1. ; เครื่องหมายอัฒภาคบ่งชี้ว่าส่วนที่เหลือของบรรทัดเป็นความคิดเห็นและจะถูกละเว้นโดยล่าม

ข้อมูลเพิ่มเติม

เมื่อเริ่มต้นโปรแกรมมีตัวแปรที่มีอยู่แล้วสามตัว พวกเขามีset1,set2ANSWERและ set1รับค่าของพารามิเตอร์ส่วนหัวแรก set2ใช้ค่าของวินาที ANSWERเป็นชุดเริ่มต้นที่ว่างเปล่า เมื่อโปรแกรมเสร็จสิ้นแล้วล่ามจะตรวจสอบว่าANSWERเป็นจำนวนเต็มของคำตอบของปัญหาทางคณิตศาสตร์ที่กำหนดไว้ในส่วนหัวหรือไม่ หากเป็นเช่นนั้นจะเป็นการระบุว่ามีข้อความให้ stdout

ล่ามยังแสดงจำนวนการทำงานที่ใช้ ทุกคำสั่งเป็นการทำงานเพียงครั้งเดียว การเริ่มต้นฉลากจะต้องเสียค่าใช้จ่ายในการดำเนินการเพียงครั้งเดียว (สามารถเริ่มป้ายกำกับได้ครั้งเดียวเท่านั้น)

คุณอาจมีตัวแปรสูงสุด 20 ตัว (รวมถึงตัวแปร 3 ตัวที่กำหนดไว้ล่วงหน้า) และ 20 ป้ายกำกับ

รหัสล่าม

หมายเหตุที่สำคัญบนตัวแปลภาษานี้

สิ่งต่าง ๆ ช้ามากเมื่อใช้จำนวนมาก (> 30) ในล่ามนี้ ฉันจะร่างเหตุผลสำหรับสิ่งนี้

  • โครงสร้างของเซตเป็นเช่นนั้นในการเพิ่มจำนวนธรรมชาติหนึ่งตัวคุณจะเพิ่มขนาดของโครงสร้างเซตได้อย่างมีประสิทธิภาพ n TH จำนวนธรรมชาติมี2 ^ nเซตว่างภายใน (โดยนี้ผมหมายถึงว่าถ้าคุณมองnเหมือนต้นไม้ที่มีnเซตว่าง. หมายเหตุ: เฉพาะเซตว่างสามารถใบ.) ซึ่งหมายความว่าการจัดการกับ 30 อย่างมีนัยสำคัญ ค่าใช้จ่ายสูงกว่าการติดต่อกับ 20 หรือ 10 (คุณกำลังดู 2 ^ 10 กับ 2 ^ 20 เทียบกับ 2 ^ 30)
  • การตรวจสอบความเท่าเทียมกันซ้ำ เนื่องจากฉากไม่มีการจัดลำดับที่ถูกกล่าวหานี่จึงเป็นวิธีธรรมชาติในการจัดการกับสิ่งนี้
  • มีการรั่วไหลของหน่วยความจำสองแห่งที่ฉันไม่สามารถหาวิธีแก้ไขได้ ฉันไม่ดีที่ C / C ++ ขออภัย เนื่องจากเรากำลังติดต่อกับตัวเลขจำนวนน้อยเท่านั้นและหน่วยความจำที่จัดสรรจะถูกปล่อยให้เป็นอิสระเมื่อสิ้นสุดการทำงานของโปรแกรมนี่จึงไม่น่าเป็นปัญหามากนัก (ก่อนใครบอกว่าใช่ฉันรู้std::vectorฉันทำแบบฝึกหัดนี้เพื่อเรียนรู้ถ้าคุณรู้วิธีแก้ไขโปรดแจ้งให้เราทราบและฉันจะแก้ไขไม่เช่นนั้นฉันจะทิ้งมันไว้ อย่างที่เป็น.)

นอกจากนี้สังเกตเห็นเส้นทางรวมถึงset.hในinterpreter.cppไฟล์ ไม่มี ado เพิ่มเติมซอร์สโค้ด (C ++):

set.h

using namespace std;

//MEMORY LEAK IN THE ADD_SELF METHOD
class set {

    private:
        long m_size;
        set* m_elements;
        bool m_initialized;
        long m_value;

    public:
        set() {

            m_size =0;
            m_initialized = false;
            m_value=0;
        }

        ~set() {
            if(m_initialized) {
                //delete[] m_elements;
            }
        }

        void init() {
            if(!m_initialized) {
                m_elements = new set[0];

                m_initialized = true;
            }
        }

        void uninit() {
            if(m_initialized) {
                //delete[] m_elements;
            }
        }

        long size() {
            return m_size;
        }

        set* elements() {
            return m_elements;
        }

        bool is_empty() {
            if(m_size ==0) {return true;}
            else {return false;}
        }

        bool is_eq(set otherset) {
            if( (*this).size() != otherset.size() ) {
                return false;
            }
            else if ( (*this).size()==0 && otherset.size()==0 ) { 
                return true;
            }
            else {
                for(int i=0;i<m_size;i++) {
                    bool matched = false;
                    for(int j=0;j<otherset.size();j++) {

                        matched = (*(m_elements+i)).is_eq( *(otherset.elements()+j) );
                        if( matched) {
                            break;
                        }
                    }
                    if(!matched) {
                        return false;
                    }
                }
                return true;
            } 
        }

        bool contains(set set1) {
            for(int i=0;i<m_size;i++) {
                if( (*(m_elements+i)).is_eq(set1) ) {
                    return true;
                }
            }
            return false;
        }

        void add(set element) {
            (*this).init();

            bool alreadythere = false;
            for(int i=0;i<m_size;i++) {
                if( (*(m_elements+i)).is_eq(element) ) { 
                    alreadythere=true;
                }
            }
            if(!alreadythere) {
                set *temp = new set[m_size+1];
                for(int i=0; i<m_size; i++) {
                    *(temp+i)= *(m_elements+i);
                }
                *(temp+m_size)=element;

                m_size++;
                delete[] m_elements;
                m_elements = new set[m_size];

                for(int i=0;i<m_size;i++) {
                    *(m_elements+i) = *(temp+i);
                }
                delete[] temp;
            }
        }

        void add_self() {

            set temp_set;
            for(int i=0;i<m_size;i++) {
                temp_set.add( *(m_elements+i) );
            }
            (*this).add(temp_set);
            temp_set.uninit();
        }

        void remove(set set1) {
            (*this).init();
            for(int i=0;i<m_size;i++) {
                if(  (*(m_elements+i)).is_eq(set1) ) {

                    set* temp = new set[m_size-1];
                    for(int j=0;j<m_size;j++) {

                        if(j<i) {
                            *(temp+j)=*(m_elements+j);
                        }
                        else if(j>i) {
                            *(temp+j-1)=*(m_elements+j);
                        }
                    }
                    delete[] m_elements;
                    m_size--;
                    m_elements = new set[m_size];
                    for(int j=0;j<m_size;j++) {
                        *(m_elements+j)= *(temp+j);
                    }
                    delete[] temp;
                    break;
                }
            }
        }

        void join(set set1) {
            for(int i=0;i<set1.size();i++) {
                (*this).add( *(set1.elements()+i) );
            }
        }

        void diff(set set1) {
            for(int i=0;i<set1.size();i++) {
                (*this).remove( *(set1.elements()+i) );
            }
        }

        void intersect(set set1) {
             for(int i=0;i<m_size;i++) {

                bool keep = false;
                 for(int j=0;j<set1.size();j++) {
                     if(  (*(m_elements+i)).is_eq( *(set1.elements()+j) ) ) {
                         keep = true;
                         break;
                     }
                 }
                 if(!keep) {
                    (*this).remove( *(m_elements+i) );
                 }
             }
         }


        void natural(long number) {
            ////////////////////////// 
            //MEMORY LEAK?
            //delete[] m_elements;
            /////////////////////////
            m_size = 0;
            m_elements = new set[m_size];

            for(long i=1;i<=number;i++) {
                (*this).add_self();
            }
            m_value = number;
        }

        void disp() {
            if( m_size==0) {cout<<"{}";}
            else {
                cout<<"{";
                for(int i=0; i<m_size; i++) {
                    (*(m_elements+i)).disp();
                    if(i<m_size-1) {cout<<", ";}
                    //else{cout<<" ";}
                }
                cout<<"}";
            }
        }

        long value() {
            return m_value;
        }

};
const set EMPTY_SET;

interpreter.cpp

#include<fstream>
#include<iostream>
#include<string>
#include<assert.h>
#include<cmath>
#include "headers/set.h"
using namespace std;
string labels[20];
int jump_points[20];
int label_index=0;
const int max_var = 20;
set* set_ptrs[max_var];
string set_names[max_var];
long OPERATIONS = 0;

void assign_var(string name, set other_set) {
    static int index = 0;
    bool exists = false;
    int i = 0;
    while(i<index) {
        if(name==set_names[i]) {
            exists = true;
            break;
        }
        i++;
    }
    if(exists && index<max_var) {
        *(set_ptrs[i]) = other_set;
    }
    else if(!exists && index<max_var) {
        set_ptrs[index] = new set;
        *(set_ptrs[index]) = other_set;
        set_names[index] = name;
        index++;
    }
}

int getJumpPoint(string str) {
    for(int i=0;i<label_index;i++) {
        //cout<<labels[i]<<"\n";
        if(labels[i]==str) {
            //cout<<jump_points[i];
            return jump_points[i];
        }
    }
    cerr<<"Invalid Label Name: '"<<str<<"'\n";
    //assert(0);
    return -1;
}

long strToLong(string str) { 
    long j=str.size()-1;
    long value = 0;
    for(long i=0;i<str.size();i++) {
        long x = str[i]-48;
        assert(x>=0 && x<=9);  // Crash if there was a non digit character
        value+=x*floor( pow(10,j) );
        j--;
    }
    return value;
}

long getValue(string str) {
    for(int i=0;i<max_var;i++) {
        if(set_names[i]==str) {
            set set1;
            set1.natural( (*(set_ptrs[i])).size() );
            if( set1.is_eq( *(set_ptrs[i]) )   ) {
                return (*(set_ptrs[i])).size();
            }
            else {
                cerr<<"That is not a valid integer construction";
                return 0;
            }
        }
    }
    return strToLong(str);
}

int main(int argc, char** argv){
    if(argc<2){std::cerr<<"No input file given"; return 1;}
    ifstream inf(argv[1]);
    if(!inf){std::cerr<<"File open failed";return 1;}
    assign_var("ANSWER", EMPTY_SET);
    int answer;
    string str;
    inf>>str; 
    if(str=="*") { 
        inf>>str;
        long a = strToLong(str);
        inf>>str;
        long b = strToLong(str);
        answer = a*b;
        set set1; set set2;
        set1.natural(a); set2.natural(b);
        assign_var("set1", set1);
        assign_var("set2",set2);
        //cout<<answer;
    }
    else if(str=="+") {
        inf>>str;
        long a = strToLong(str);
        inf>>str;
        long b = strToLong(str);
        answer = a+b;
        set set1; set set2;
        set1.natural(a); set2.natural(b);
        assign_var("set1", set1);
        assign_var("set2",set2);
        //cout<<answer;
    }
    else{ 
         cerr<<"file must start with '+' or '*'"; 
        return 1;
    }

    // parse for labels
    while(inf) {
        if(inf) {   
            inf>>str;
            if(str[str.size()-1]==':') {
                str.erase(str.size()-1);
                labels[label_index] = str; 
                jump_points[label_index] = inf.tellg();
                //cout<<str<<": "<<jump_points[label_index]<<"\n";
                label_index++;
                OPERATIONS++;
            }
        }
    }

    inf.clear();
    inf.seekg(0,ios::beg);
    // parse for everything else

    while(inf) {
        if(inf) {
            inf>>str;

            if(str==";") {
                getline(inf, str,'\n');
            }

            // jump label
            if(str=="jump") {    
                inf>>str;
                inf.seekg( getJumpPoint(str),ios::beg);
                OPERATIONS++;
            }

            // je set label
            if(str=="je") {        
                inf>>str;
                for(int i=0;i<max_var;i++) {
                    if( set_names[i]==str) {
                        if( (*(set_ptrs[i])).is_eq(EMPTY_SET) ) {
                            inf>>str;
                            inf.seekg( getJumpPoint(str),ios::beg);
                            OPERATIONS++; 
                        }
                        break;
                    }
                }
            }

            // jne set label
            if(str=="jne") {
                inf>>str;
                for(int i=0;i<max_var;i++) {
                    if( set_names[i]==str) {
                        if(! (*(set_ptrs[i])).is_eq(EMPTY_SET) ) {
                            inf>>str;
                            inf.seekg( getJumpPoint(str),ios::beg);
                            OPERATIONS++; 
                        }
                        break;
                    }
                }
            }

            // jic set1 set2 label 
            // jump if set1 contains set2
            if(str=="jic") {
                inf>>str;
                string str2;
                inf>>str2;
                set set1;
                set set2;
                for(int i=0;i<max_var;i++) {
                    if( set_names[i]==str ) {
                        set1 = *(set_ptrs[i]);
                    }
                    if(set_names[i]==str2) {
                        set2 = *(set_ptrs[i]);
                    }
                }
                if( set1.contains(set2) ) {
                    inf>>str;
                    inf.seekg( getJumpPoint(str),ios::beg);
                    OPERATIONS++; 
                }
                else {inf>>str;}
            }

            // jidc set1 set2 label
            // jump if set1 doesn't contain set2
            if(str=="jidc") {
                inf>>str;
                string str2;
                inf>>str2;
                set set1;
                set set2;
                for(int i=0;i<max_var;i++) {
                    if( set_names[i]==str ) {
                        set1 = *(set_ptrs[i]);
                    }
                    if(set_names[i]==str2) {
                        set2 = *(set_ptrs[i]);
                    }
                }
                if( !set1.contains(set2) ) {
                    inf>>str;
                    inf.seekg( getJumpPoint(str),ios::beg);
                    OPERATIONS++; 
                }
                else {inf>>str;}
            }

            // assign variable set/int
            if(str=="assign") {
                inf>>str;
                string str2;
                inf>>str2;
                set set1;
                set1.natural( getValue(str2) );
                assign_var(str,set1);
                OPERATIONS++;

            }

            // union set1 set2 set3
            // set1 = set2 u set3
            if(str=="union") {
                inf>>str;
                int i=0;
                while(i<max_var) {
                    if( set_names[i] == str ) {
                        break;
                    }
                    i++;
                }

                set set1;
                set set2;
                string str1;
                inf>>str1;
                string str2;
                inf>>str2;
                for(int j=0;j<max_var;j++) {
                    if( str1 == set_names[j] ) {
                        set1= *(set_ptrs[j]); 
                    }
                    if( str2 == set_names[j] ) {
                        set2= *(set_ptrs[j]);
                    }
                }
                set1.join(set2);
                if(i==max_var) {
                    assign_var(str,set1);
                }
                else {
                    set_names[i]= str;
                    set_ptrs[i] = new set;
                    *(set_ptrs[i]) = set1;
                }
                OPERATIONS++;

            }

            // intersect set1 set2 set3
            // set1 = set2^set3
            if(str == "intersect") {
                inf>>str;
                int i=0;
                while(i<max_var) {
                    if( set_names[i] == str ) {
                        break;
                    }
                    i++;
                }

                set set1;
                set set2;
                string str1;
                inf>>str1;
                string str2;
                inf>>str2;
                for(int j=0;j<max_var;j++) {
                    if( str1 == set_names[j] ) {
                        set1= *(set_ptrs[j]); 
                    }
                    if( str2 == set_names[j] ) {
                        set2= *(set_ptrs[j]);
                    }
                }
                set1.intersect(set2);
                if(i==max_var) {
                    assign_var(str,set1);
                }
                else {
                    set_names[i]= str;
                    set_ptrs[i] = new set;
                    *(set_ptrs[i]) = set1;
                }
                OPERATIONS++;
            }


            // difference set1 set2 set3
            // set1 = set2\set3
            if(str == "difference") {
                inf>>str;
                int i=0;
                while(i<max_var) {
                    if( set_names[i] == str ) {
                        break;
                    }
                    i++;
                }

                set set1;
                set set2;
                string str1;
                inf>>str1;
                string str2;
                inf>>str2;
                for(int j=0;j<max_var;j++) {
                    if( str1 == set_names[j] ) {
                        set1= *(set_ptrs[j]); 
                    }
                    if( str2 == set_names[j] ) {
                        set2= *(set_ptrs[j]);
                    }
                }
                set1.diff(set2);
                if(i==max_var) {
                    assign_var(str,set1);
                }
                else {
                    set_names[i]= str;
                    set_ptrs[i] = new set;
                    *(set_ptrs[i]) = set1;
                }
                OPERATIONS++;
            }

            // add set1 set2
            // put set2 in set 1
            if(str=="add") {
                inf>>str;
                int i = 0; int j =0;
                while(i<max_var) {
                    if(set_names[i]==str) {
                        break;
                    }
                    i++;
                }
                inf>>str;
                while(j<max_var) {
                    if(set_names[j]==str) {
                    break;
                    }   
                    j++;             
                }
                set set2 = *(set_ptrs[j]);
                if( ! (*(set_ptrs[i])).is_eq(set2) ){
                    (*(set_ptrs[i])).add(set2);
                }
                else {
                    (*(set_ptrs[i])).add_self();
                }
                OPERATIONS++;
            }

            // remove set1 set2
            // remove set2 from set1
            if(str=="remove") {
                inf>>str;
                int i = 0; int j =0;
                while(i<max_var) {
                    if(set_names[i]==str) {
                        break;
                    }
                    i++;
                }
                inf>>str;
                while(j<max_var) {
                    if(set_names[j]==str) {
                    break;
                    }   
                    j++;             
                }
                set set2 = *(set_ptrs[j]);
                (*(set_ptrs[i])).remove(set2);
                OPERATIONS++;
            }

            // print set
            // prints true representation of set
            if(str=="print") {
                inf>>str;
                for(int i=0;i<max_var;i++) {
                    if(set_names[i]==str) {
                        (*(set_ptrs[i])).disp();
                    }
                }
                cout<<"\n";
            }

            // printi set
            // prints integer representation of set, if exists.
            if(str=="printi") {
                inf>>str;
                cout<<getValue(str);
                cout<<"\n";
            }
        }
    }

    cout<<"You used "<<OPERATIONS<<" operations\n";
    set testset;
    testset.natural(answer);
    switch( testset.is_eq( *(set_ptrs[0]) ) ) {
        case 1:
            cout<<"Your answer is correct, the set 'ANSWER' is equivalent "<<answer<<".\n";
            break;
        case 0:
            cout<<"Your answer is incorrect\n";
    }
   // cout<<"\n";
    return 0;
}

สภาพการชนะ

คุณอยู่ที่สองเขียนสองโปรแกรมBODIESซึ่งหนึ่งในนั้นคูณตัวเลขในส่วนหัวที่อื่น ๆ ซึ่งจะเพิ่มตัวเลขในส่วนหัว

นี่เป็นท้าทายที่สุด สิ่งที่เร็วที่สุดจะถูกกำหนดโดยจำนวนของการดำเนินการที่ใช้เพื่อแก้ไขกรณีทดสอบสองกรณีสำหรับแต่ละโปรแกรม กรณีทดสอบคือบรรทัดส่วนหัวต่อไปนี้:

สำหรับนอกจากนี้:

+ 15 12

และ

+ 12 15

และสำหรับการคูณ

* 4 5

และ

* 5 4

คะแนนสำหรับแต่ละกรณีคือจำนวนการปฏิบัติการที่ใช้ (ล่ามจะระบุหมายเลขนี้เมื่อเสร็จสิ้นโปรแกรม) คะแนนรวมคือผลรวมของคะแนนสำหรับแต่ละกรณีทดสอบ

ดูรายการตัวอย่างของฉันสำหรับตัวอย่างของรายการที่ถูกต้อง

ผลงานที่ชนะจะเป็นไปตาม:

  1. มีสองโปรแกรมเนื้อความหนึ่งซึ่งคูณและหนึ่งซึ่งเพิ่ม
  2. มีคะแนนรวมต่ำสุด (ผลรวมคะแนนในกรณีทดสอบ)
  3. ให้เวลาและหน่วยความจำเพียงพอทำงานได้กับจำนวนเต็มใด ๆ ที่ล่ามสามารถจัดการได้ (~ 2 ^ 31)
  4. แสดงไม่มีข้อผิดพลาดเมื่อทำงาน
  5. ห้ามใช้คำสั่งการดีบัก
  6. ไม่ใช้ประโยชน์จากข้อบกพร่องในล่าม ซึ่งหมายความว่าโปรแกรมจริงของคุณควรถูกต้องเป็นรหัสหลอกเช่นเดียวกับโปรแกรมที่แปลได้ใน 'set language'
  7. ไม่ใช้ช่องโหว่มาตรฐาน (ซึ่งหมายความว่าไม่มีกรณีทดสอบการเข้ารหัส)

โปรดดูตัวอย่างการใช้งานอ้างอิงและตัวอย่างการใช้ภาษา


@ Calvin's งานอดิเรกความคิดนั่นเป็นเพียงเบราว์เซอร์ของฉัน มีสถานที่ที่สะดวกในการทำรูปภาพหรือไม่?
เลียม

@ LiamNoronha: ฉันดูแลมัน $$...$$ใช้ได้กับ Meta แต่ไม่ใช่ใน Main ฉันใช้CodeCogsเพื่อสร้างภาพ
El'endia Starman

ขอบคุณ @ El'endiaStarman สำหรับการแก้ไขสัญลักษณ์มาร์กอัป
เลียม

3
ห้องไม่เพียงพอสำหรับการเพิ่มประสิทธิภาพ
เลียม

4
ฉันลงคะแนนให้ปิดคำถามนี้เป็นแบบปิดหัวข้อเนื่องจากมีพื้นที่ไม่เพียงพอสำหรับการเพิ่มประสิทธิภาพ
Liam

คำตอบ:


1

ตัวอย่างคำตอบการปฏิบัติการ 1323

โปรดทราบว่านี่เป็นตัวอย่างไม่ใช่รายการจริง

ร่างกายนอกจากนี้

โปรดทราบว่าเนื้อหานี้จะไม่ทำงานหากไม่มีส่วนหัว

ความคิดเห็นไม่จำเป็นในคำตอบจริง แต่มีไว้เพื่อช่วยสอนพื้นฐานของภาษา

assign ANSWER set2                  ; ANSWER = set2
main:                               ; create label 'main'
    add ANSWER ANSWER               ; Answer union {Answer}, i.e. ANSWER++
    assign looper1 0
    assign looper2 0
    jump dec
    continue:
        intersect set1 set1 looper2 ; set1 = set1 intersect looper2, i.e. set1 = min(set1,looper2)
        jne set1 main
        jump end
dec:
    add looper1 looper1             ; looper1++
    jidc set1 looper1 continue      ; jump if looper >= set1    
    add looper2 looper2             ; looper2++
    jump dec
end:

สำหรับกรณีทดสอบ

+ 15 12

ใช้440 operationsและสำหรับกรณีทดสอบ

+ 12 15

299 operationsการใช้งาน

สูตรคูณ

assign mult_loop 0
main:
    jic set1 mult_loop addition    
    jump end

addition:
    assign temp2 set2
    main_add:
        add ANSWER ANSWER
        assign looper1 0
        assign looper2 0
        jump dec
        cont_add:
            intersect temp2 temp2 looper2
            jne temp2 main_add
            jump end_add
    dec:
        add looper1 looper1
        jidc temp2 looper1 cont_add
        add looper2 looper2
        jump dec
    end_add:
        add mult_loop mult_loop
        jump main

end:

สำหรับกรณีทดสอบ

* 4 5

ใช้305 operationsและสำหรับกรณีทดสอบ

* 5 4

279 operationsการใช้งาน

ดังนั้นคะแนนรวมของฉันคือ440+299+305+279 = 1323


น่าเสียดายที่การปรับปรุงเพียงอย่างเดียวที่ฉันคิดได้ก็คือการเรียงลำดับข้อมูลเข้าminและการmaxใช้unionและintersectionเพื่อให้การเพิ่มเติมสองรายการและการคูณสองครั้งได้รับคะแนน (ต่ำกว่า) เดียวกัน ดูเหมือนจะไม่เป็นการปรับปรุงที่เพียงพอเพื่อตัดส่วนที่เหลือของโซลูชันอ้างอิงนี้ ;)
Martin Ender

@ MartinBüttnerฮะฉันแค่คิดว่าความพยายามครั้งแรกของฉันจะน่ากลัวมาก ถ้าเป็นอย่างนั้นเราก็อาจปิดคำถามได้แล้ว
เลียม

เอ๊ะเพียงเพราะฉันไม่สามารถคิดในสิ่งที่ดีกว่าไม่ได้หมายความว่ามีวิธีที่ดีกว่ามาก เราจะเห็น ... ;)
Martin Ender

@ MartinBüttnerฉันกลัวบางสิ่งเช่นนี้อาจเกิดขึ้น แต่เนื่องจากฉันใช้ความพยายามเพียงเล็กน้อยในการแก้ปัญหาฉันจึงคิดว่าพวกเขาจะเอาชนะได้ง่าย ฉันจะให้หนึ่งสัปดาห์หรือมากกว่านั้น
เลียม
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.