Définir l'arithmétique théorique (+ et *) [fermé]

10

Définir l'arithmétique théorique

Prémisse

Il y a déjà eu quelques défis qui impliquent la multiplication sans l'opérateur de multiplication ( ici et ici ) et ce défi est dans la même veine (le plus similaire au deuxième lien).

Ce défi, contrairement aux précédents, utilisera une définition théorique définie des nombres naturels ( N ):

entrez la description de l'image ici

et

entrez la description de l'image ici

par exemple,

entrez la description de l'image ici

entrez la description de l'image ici

entrez la description de l'image ici

etc.

Le défi

Notre objectif est d'utiliser des opérations d'ensemble (voir ci-dessous), pour ajouter et multiplier des nombres naturels. À cet effet, toutes les entrées seront dans la même «langue définie» dont l'interprète est ci-dessous . Cela assurera la cohérence et facilitera la notation.

Cet interpréteur vous permet de manipuler des nombres naturels sous forme d'ensembles. Votre tâche sera d'écrire deux corps de programme (voir ci-dessous), dont l'un ajoute des nombres naturels, l'autre les multiplie.

Notes préliminaires sur les décors

Les ensembles suivent la structure mathématique habituelle. Voici quelques points importants:

  • Les ensembles ne sont pas commandés.
  • Aucun ensemble ne se contient
  • Les éléments sont dans un ensemble ou non, c'est booléen. Par conséquent, les éléments d'ensemble ne peuvent pas avoir de multiplicités (c'est-à-dire qu'un élément ne peut pas être dans un ensemble plusieurs fois.)

Interprète et spécificités

Un «programme» pour ce défi est écrit en «langue définie» et se compose de deux parties: un en-tête et un corps.

Entête

L'en-tête est très simple. Il indique à l'interprète le programme que vous résolvez. L'en-tête est la première ligne du programme. Il commence par le caractère +ou *, suivi de deux entiers, séparés par des espaces. Par exemple:

+ 3 5

ou

* 19 2

sont des en-têtes valides. Le premier indique que vous essayez de résoudre 3+5, ce qui signifie que votre réponse devrait être 8. Le second est similaire sauf avec la multiplication.

Corps

Le corps est l'endroit où se trouvent réellement vos instructions à l'interprète. C'est ce qui constitue vraiment votre programme «d'addition» ou de «multiplication». Votre réponse comprendra deux corps de programme, un pour chaque tâche. Vous modifierez ensuite les en-têtes pour effectuer réellement les cas de test.

Syntaxe et instructions

Les instructions consistent en une commande suivie de zéro ou plusieurs paramètres. Aux fins des démonstrations suivantes, tout caractère alphabétique est le nom d'une variable. Rappelons que toutes les variables sont des ensembles. labelest le nom d'une étiquette (les étiquettes sont des mots suivis de points-virgules (c.-à-d. main_loop:), intest un entier. Voici les instructions valides:

Contrôle de flux:
  1. jump labelsauter sans condition à l'étiquette. Une étiquette est un «mot» suivi d'un point-virgule: par exemple, main_loop:est une étiquette.
  2. je A label passer à l'étiquette si A est vide
  3. jne A label passer à l'étiquette si A n'est pas vide
  4. jic A B label passer à l'étiquette si A contient B
  5. jidc A B label passer à l'étiquette si A ne contient pas B
Affectation variable
  1. assign A Bou assign A int entrez la description de l'image iciou
    set(int)est la représentation d'ensemble deint
Définir les opérations
  1. union A B C entrez la description de l'image ici
  2. intersect A B C
  3. difference A B C entrez la description de l'image ici
  4. add A B entrez la description de l'image ici
  5. remove A B entrez la description de l'image ici
Débogage
  1. print A affiche la vraie valeur de A, où {} est l'ensemble vide
  2. printi variable affiche une représentation entière de A, si elle existe, sinon génère une erreur.
commentaires
  1. ; Le point-virgule indique que le reste de la ligne est un commentaire et sera ignoré par l'interpréteur

Plus d'infos

Au démarrage du programme, il existe trois variables préexistantes. Ils sont set1,set2 et ANSWER. set1prend la valeur du premier paramètre d'en-tête. set2prend la valeur de la seconde. ANSWERest initialement l'ensemble vide. À la fin du programme, l'interpréteur vérifie si ANSWERest la représentation entière de la réponse au problème arithmétique défini dans l'en-tête. Si c'est le cas, il l'indique avec un message à stdout.

L'interprète affiche également le nombre d'opérations utilisées. Chaque instruction est une opération. Le lancement d'une étiquette coûte également une opération (les étiquettes ne peuvent être lancées qu'une seule fois).

Vous pouvez avoir un maximum de 20 variables (y compris les 3 variables prédéfinies) et 20 étiquettes.

Code interprète

NOTES IMPORTANTES SUR CET INTERPRÈTE

Les choses sont très lentes lors de l'utilisation de grands nombres (> 30) dans cet interprète. Je vais en expliquer les raisons.

  • La structure des ensembles est telle qu'en augmentant d'un nombre naturel, vous doublez effectivement la taille de la structure de l'ensemble. Le n ème nombre naturel contient 2 ^ n ensembles vides (j'entends par là que si vous regardez n comme un arbre, il y a n ensembles vides. Notez que seuls les ensembles vides peuvent être des feuilles.) Cela signifie que traiter 30 est significativement plus coûteux que de traiter 20 ou 10 (vous regardez 2 ^ 10 vs 2 ^ 20 vs 2 ^ 30).
  • Les contrôles d'égalité sont récursifs. Étant donné que les décors ne seraient pas commandés, cela semblait être le moyen naturel de résoudre ce problème.
  • Il y a deux fuites de mémoire que je n'ai pas réussi à résoudre. Je suis mauvais en C / C ++, désolé. Étant donné que nous ne traitons que de petits nombres et que la mémoire allouée est libérée à la fin du programme, cela ne devrait pas vraiment être un problème majeur. (Avant que quelqu'un ne dise quoi que ce soit, oui je le sais std::vector; je faisais cela comme un exercice d'apprentissage. Si vous savez comment le réparer, faites-le moi savoir et je ferai les modifications, sinon, puisque cela fonctionne, je le laisserai comme si.)

Notez également le chemin d'accès inclus set.hdans le interpreter.cppfichier. Sans plus tarder, le code source (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;
}

Condition gagnante

Vous êtes deux, écrivez deux CORPS de programme , dont l'un multiplie les nombres dans les en-têtes, dont l'autre ajoute les nombres dans les en-têtes.

Il s'agit d'un défi de . Ce qui est le plus rapide sera déterminé par le nombre d'opérations utilisées pour résoudre deux cas de test pour chaque programme. Les cas de test sont les en-têtes suivants:

Pour plus:

+ 15 12

et

+ 12 15

et pour la multiplication

* 4 5

et

* 5 4

Un score pour chaque cas est le nombre d'opérations utilisées (l'interprète indiquera ce nombre à la fin du programme). Le score total est la somme des scores de chaque scénario de test.

Voir mon exemple d'entrée pour un exemple d'entrée valide.

Une soumission gagnante satisfait aux critères suivants:

  1. contient deux organes de programme, un qui multiplie et un qui ajoute
  2. a le score total le plus bas (somme des scores dans les cas de test)
  3. Avec suffisamment de temps et de mémoire, fonctionne pour tout entier pouvant être traité par l'interpréteur (~ 2 ^ 31)
  4. N'affiche aucune erreur lors de l'exécution
  5. N'utilise pas de commandes de débogage
  6. N'exploite pas les défauts de l'interpréteur. Cela signifie que votre programme réel doit être valide en tant que pseudo-code ainsi qu'en tant que programme interprétable en «langue définie».
  7. N'exploite pas les failles standard (cela signifie pas de cas de test de codage en dur.)

Veuillez consulter mon exemple pour une implémentation de référence et un exemple d'utilisation du langage.

Liam
la source
@ Calvin'sHobbies Je pensais que c'était juste mon navigateur. Y a-t-il un endroit facile pour faire les photos?
Liam
@LiamNoronha: Je m'en suis occupé. $$...$$fonctionne sur Meta, mais pas sur Main. J'ai utilisé CodeCogs pour générer les images.
El'endia Starman
Merci @ El'endiaStarman pour avoir corrigé la notation de balisage
Liam
3
pas assez de place pour l'optimisation
Liam
4
Je vote pour fermer cette question comme hors sujet car il n'y a pas assez de place pour l'optimisation
Liam

Réponses:

1

Exemple de réponse, 1323 opérations

Notez qu'il s'agit d'un exemple et non d'une véritable entrée.

Corps d'addition

Notez que ce corps ne fonctionnera pas sans en-tête.

Les commentaires ne sont pas nécessaires dans une réponse réelle, mais sont là pour aider à enseigner les bases de la langue.

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:

Pour le cas de test

+ 15 12

utilise 440 operationset pour le cas de test

+ 12 15

utilise 299 operations.

Organe de multiplication

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:

Pour le cas de test

* 4 5

utilise 305 operationset pour le cas de test

* 5 4

utilise 279 operations.

Par conséquent, mon score total est440+299+305+279 = 1323

Liam
la source
Malheureusement, la seule amélioration à laquelle je peux penser est de trier les entrées dans minet en maxutilisant unionet intersection, de sorte que les deux additions et les deux multiplications obtiennent le même score (inférieur). Cela ne semble pas être une amélioration suffisante pour arracher le reste de cette solution de référence. ;)
Martin Ender
@ MartinBüttner Hah Je pensais juste que mes premières tentatives seraient assez horribles. Eh bien, si c'est le cas, nous pourrions aussi bien clore la question
Liam
Eh, ce n'est pas parce que je ne vois rien de mieux que des approches bien meilleures. Nous verrons ...;)
Martin Ender
@ MartinBüttner J'avais peur que quelque chose comme ça se produise, mais comme je mettais très peu d'efforts dans les solutions, je pensais qu'elles seraient faciles à battre. Je vais lui donner une semaine ou deux.
Liam