Qu'est-ce qui peut être attribué à quoi?

10

en relation


Qu'est-ce qui peut être attribué à quoi?

Dans ce défi , vous recevrez deux types, Aet Bet déterminer si Aest assignable B, Best assignable Aou non plus .

Le système de type

(Je vais utiliser tpour représenter tout type)

Types de base

Les types de base sont représentés par une seule majuscule, comme X. Ce sont essentiellement des classes.

  • Xest affectable à Ysi Yest soit identique à, soit à une classe parent de X.

Types d'intersection

Les types d'intersection sont représentés par intersect<X, Y>, et peuvent avoir n'importe quel nombre de types entre les <(par exemple intersect<X, Y, Z, D, E>).

  • test assignable à intersect<X1, X2... Xn>if test assignable à tous X.
  • intersect<X1, X2... Xn>est attribuable à ts'il en Xest t.

Types d'unions

Les types d'union sont représentés par union<X, Y>et peuvent avoir n'importe quel nombre de types entre les <(par exemple union<X, Y, Z, D, E>).

  • test attribuable à union<X1, X2... Xn>if test attribuable à tout X.
  • union<X1, X2... Xn>est assignable à tsi tous Xsont assignables à t.

Contribution

Vous recevrez en entrée:

  • La hiérarchie des classes. Vous pouvez choisir la méthode de saisie pour la hiérarchie des classes. Vous pouvez saisir une représentation d'un arbre, ou chaque type avec une liste de ses parents, ou tout autre élément qui représente avec précision la hiérarchie des classes.
  • Deux types (l'entrée est flexible, tant que la notation est cohérente, vous pouvez recevoir ces types comme vous le souhaitez).

Production

Vous aurez une sortie de trois valeurs cohérentes et distinctes, les appeler X, Yet Z. Compte tenu de deux types Aet B, sortie Xsi Aest assignable B, sortie Ysi Best assignable Aet sortie Zautrement (Si Aest assignable Bet Best assignable A, vous pouvez sortir X, Y, les deux, ou une quatrième valeur).


Cas de test

Format:

# of types
[type, parents...]
[type, parents...]
Type a
Type b

2
[A,B]
[B]
A
B
--
A is assignable to B


3
[A,B,C]
[B,C]
[C]
intersect<A,C>
A
--
A is assignable to intersect<A,C>


3
[A,B,C]
[B,C]
[C]
union<A,C>
A
--
A is assignable to union<A,C>


3
[A,B,C]
[B,C]
[C]
intersect<B,C>
A
--
A is assignable to intersect<B,C>


3
[A,B,C]
[X,Y,Z]
[T,U,V]
intersect<union<A,T,X>,intersect<A,B>,Y>
intersect<T,C,X>
--
intersect<T,C,X> and intersect<union<A,T,X>,intersect<A,B>,Y> are not assignable to each other    

1
[A]
A
A
--
A is assignable to A


3
[A,B,C]
[X,Y,Z]
[T,U,V]
intersect<A,intersect<A,B>,Y>
intersect<T,C,X>
--
intersect<T,C,X> and intersect<A,intersect<A,B>,Y> are not assignable to each other


2
[A]
[B]
A
B
--
B and A are not assignable to each other

3
[A,B,C]
[X,Y,Z]
[T,U,V]
intersect<union<A,X>,intersect<A,B>,Y>
intersect<T,C,X>
--
intersect<T,C,X> and intersect<union<A,X>,intersect<A,B>,Y> are not assignable to each other

Voici un lien vers une solution Java non golfée fonctionnelle que vous pouvez utiliser pour les tests (elle prend les données de la même manière que les cas de test)


Il s'agit de code-golf, donc le moins d'octets dans chaque langue gagne pour cette langue!

Phénix socratique
la source
Sandbox (supprimé)
Socratic Phoenix
@ovs non, A a les parents B et C.
Socratic Phoenix
@HalvardHummel excuses; J'ai édité le post
Socratic Phoenix
Héritera-t-il d'un cercle?
tsh
Que devrait produire si A est attribuable à B et B est attribuable à A?
tsh

Réponses:

3

Python 3 , 177 octets

cest un dictionnaire des parents de chaque type, aet bsont les deux expressions à vérifier. Les types sont représentés par des chaînes, tandis que les intersections et les unions sont représentées par des listes d'expressions, le premier élément étant défini sur 0pour intersection et 1pour union

Renvoie 0s'ils ne peuvent pas être attribués les uns aux autres, 1si aest attribuable à b, 2si best attribuable à aet 3si les deux sont assignables les uns aux autres

lambda c,a,b:y(a,b,c)+2*y(b,a,c)
y=lambda a,b,c:(b in c[a]or a==b if b[0]in c else[all,any][b[0]](y(a,x,c)for x in b[1:]))if a[0]in c else[any,all][a[0]](y(x,b,c)for x in a[1:])

Essayez-le en ligne!

Halvard Hummel
la source
3

JavaScript (ES6), 138 octets

(p,a,b,g=(a,b)=>a==b||(p[a]||a.i||a.u||[])[a.u?'every':'some'](t=>g(t,b))||(b.i||b.u||[])[b.i?'every':'some'](t=>g(a,t)))=>g(a,b)||+g(b,a)

pest la carte parent, qui est un objet JavaScript dont les clés sont les types avec parents et dont les valeurs sont des tableaux de parent (s). Par exemple, s'il existe deux types Aet Bet Best le parent de Aalors ce pserait {A:['B']}.

Les types d'intersection sont représentés dans aet en btant qu'objet JavaScript avec une clé idont la valeur est un tableau de types, tandis que les types d'union ont une clé de u. Par exemple, l'intersection de deux types Aet Bserait {i:['A','B']}.

La valeur de retour est trueif aest assignable à b, 1if an'est pas assignable à bmais best assignable à a, ou 0si aucun n'est assignable à l'autre.

Neil
la source
2

C ++ 17, 595 octets

#include<type_traits>
#define p(x)template<class...T>class x;
#define d(a,b)disjunction<s<a,b>...>{};
#define c(a,b)conjunction<s<a,b>...>{};
#define u(x)u<x...>
#define i(x)i<x...>
#define k struct s
#define e ...A
#define t(a,b)template<class a,class b>
using namespace std;p(i)p(u)t(B,D)k:disjunction<is_base_of<B,D>,is_same<B,D>>{};t(a,e)k<a,u(A)>:d(a,A)t(a,e)k<a,i(A)>:c(a,A)t(a,e)k<u(A),a>:c(A,a)t(a,e)k<i(A),a>:d(A,a)t(e,...B)k<i(A),i(B)>:d(A,i(B))t(e,...B)k<u(A),u(B)>:c(A,u(B))t(e,...B)k<i(A),u(B)>:d(A,u(B))t(e,...B)k<u(A),i(B)>:c(A,u(B))t(A,B)int f=s<A,B>::value?-1:s<B,A>::value?1:0;

Essayez-le en ligne!

Un modèle de variable fqui accepte en entrée certains types et intersections i<...>ou l'union u<...>de ceux-ci et retourne -1si Aest assignable à B et 1si Best assignable à Aet 0autrement.

Non golfé:

#include <type_traits>
using namespace std;

template<class...T>class Intersect;
template<class...T>class Union;

template<class A,class B>
struct is_assignable_to:
    disjunction<is_base_of<A,B>,is_same<A,B>>{};

template<class a,class...A>
struct is_assignable_to<a,Union<A...>>:
    disjunction<is_assignable_to<a,A>...>{};

template<class a,class...A>
struct is_assignable_to<a,Intersect<A...>>:
    conjunction<is_assignable_to<a,A>...>{};

template<class a,class...A>
struct is_assignable_to<Union<A...>,a>:
    conjunction<is_assignable_to<A,a>...>{};

template<class a,class...A>
struct is_assignable_to<Intersect<A...>,a>:
    disjunction<is_assignable_to<A,a>...>{};

template<class...A,class...B>
struct is_assignable_to<Intersect<A...>,Intersect<B...>>:
    disjunction<is_assignable_to<A,Intersect<B...>>...>{};

template<class...A,class...B>
struct is_assignable_to<Union<A...>,Union<B...>>:
    conjunction<is_assignable_to<A,Union<B...>>...>{};

template<class...A,class...B>
struct is_assignable_to<Intersect<A...>,Union<B...>>:
    disjunction<is_assignable_to<A,Union<B...>>...>{};

template<class...A,class...B>
struct is_assignable_to<Union<A...>,Intersect<B...>>:
    conjunction<is_assignable_to<A,Intersect<B...>>...>{};

template <class A,class B>
int f = is_assignable_to<A,B>::value?-1:is_assignable_to<B,A>::value?1:0;

Usage:

#include <iostream>
int main(){
    struct B{};
    struct C{};
    struct Y{};
    struct Z{};
    struct U{};
    struct V{};
    struct A:B,C{};
    struct X:Y,Z{};
    struct T:U,V{};
    std::cout << f<Intersect<A,Intersect<A,B>,Y>,Union<T,C,X>>; 
}
rahnema1
la source