O que é atribuível a quê?

10

relacionado


O que é atribuível a quê?

Neste desafio, você receberá dois tipos Ae , Be determinará se Aé atribuível a B, Bé atribuído aA , ou nenhum.

O sistema de tipos

(Usarei t para representar qualquer tipo)

Tipos básicos

Os tipos básicos são representados por uma única letra maiúscula, como X. Eles são basicamente classes.

  • Xé atribuível a Yif Yé o mesmo que ou uma classe pai de X.

Tipos de interseção

Os tipos de interseção são representados por intersect<X, Y>e podem ter qualquer número de tipos entre os <'s (por exemplo intersect<X, Y, Z, D, E>).

  • té atribuível a intersect<X1, X2... Xn>se tfor atribuível a todos X.
  • intersect<X1, X2... Xn>é atribuível a tse algum Xfor atribuível a t.

Tipos de união

Os tipos de união são representados por union<X, Y>e podem ter qualquer número de tipos entre os <'s (por exemplo union<X, Y, Z, D, E>).

  • té atribuível a union<X1, X2... Xn>se tfor atribuível a qualquer X.
  • union<X1, X2... Xn>é atribuível a tse todos Xforem atribuíveis a t.

Entrada

Você receberá como entrada:

  • A hierarquia de classes. Você pode escolher o método de entrada para a hierarquia de classes. Você pode inserir uma representação de uma árvore, ou cada tipo com uma lista de seus pais, ou qualquer outra coisa que represente com precisão a hierarquia de classes.
  • Dois tipos (a entrada é flexível, desde que a notação seja consistente, você poderá receber esses tipos da maneira que desejar).

Resultado

Você será um dos três valores consistentes e distintas saída, chamá-los X, Ye Z. Dado dois tipos Ae B, de saída X, se Aé atribuído a B, de saída Y, se Bé atribuído a Ae saída Zde outra forma (Se Aé atribuído para Be Bé atribuído a A, você pode saída X, Y, ambos, ou uma quarta valor).


Casos de teste

Formato:

# 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

Aqui está um link para uma solução Java não utilizada que você pode usar para teste (ela recebe entrada da mesma maneira que os casos de teste)


Isso é código-golfe, portanto, menos bytes em cada idioma vencem para esse idioma!

Phoenix socrático
fonte
Sandbox (excluído)
Socratic Phoenix
@ovs não, A tem os pais B e C.
socrático Phoenix
Desculpas @HalvardHummel; Eu editei o post
Socratic Phoenix
Herdará formar um círculo?
tsh 25/10
O que deve ser produzido se A é atribuível a B e B é atribuído a A?
tsh 25/10

Respostas:

3

Python 3 , 177 bytes

cé um dicionário dos pais de cada tipo ae bsão as duas expressões a serem verificadas. Os tipos são representados por seqüências de caracteres, enquanto as interseções e uniões são representadas por listas com expressões, com o primeiro elemento definido como0 para interseção e1 união

Retorna 0se eles não são atribuíveis um ao outro, 1se aé atribuível a b, 2se bé atribuível a ae 3se ambos são atribuíveis um ao outro

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:])

Experimente online!

Halvard Hummel
fonte
3

JavaScript (ES6), 138 bytes

(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)

pé o mapa pai, que é um objeto JavaScript cujas chaves são os tipos com pais e cujos valores são matrizes de pai (s). Por exemplo, se houver dois tipos Ae Be Bé o pai de A, pseria {A:['B']}.

Os tipos de interseção são representados em ae bcomo um objeto JavaScript com uma chave icujo valor é uma matriz de tipos, enquanto os tipos de união possuem uma chave u. Por exemplo, a interseção de dois tipos Ae Bseria{i:['A','B']} .

O valor de retorno é truese aé atribuível a b, 1se anão é atribuível a, bmas bé atribuível a a, ou 0se nenhum é atribuível um ao outro.

Neil
fonte
2

C ++ 17, 595 bytes

#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;

Experimente online!

Um modelo de variável fque aceita como entrada alguns tipos e interseção i<...>ou união u<...>deles e retorna -1se Aé atribuível a B e 1se Bé atribuível a Ae de 0outra forma.

Ungolfed:

#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;

Uso:

#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
fonte