¿Qué se puede asignar a qué?

10

relacionado


¿Qué se puede asignar a qué?

En este desafío se le dará dos tipos, Ay By determinar si Aes asignable a B, Bse puede asignar aA o no.

El sistema de tipos

(Usaré t para representar cualquier tipo)

Tipos basicos

Los tipos básicos están representados por una sola letra mayúscula, como X. Son básicamente clases.

  • Xes asignable a Ysi Yes lo mismo o una clase padre de X.

Tipos de intersección

Los tipos de intersección están representados por intersect<X, Y>, y pueden tener cualquier número de tipos entre los <'s (por ejemplo intersect<X, Y, Z, D, E>).

  • tes asignable a intersect<X1, X2... Xn>si tes asignable a todos X.
  • intersect<X1, X2... Xn>es asignable a tsi alguno Xes asignable a t.

Tipos de unión

Los tipos de unión están representados por union<X, Y>y pueden tener cualquier número de tipos entre los <'s (por ejemplo union<X, Y, Z, D, E>).

  • tes asignable a union<X1, X2... Xn>si tes asignable a cualquiera X.
  • union<X1, X2... Xn>es asignable a tsi todos Xson asignables a t.

Entrada

Recibirá como entrada:

  • La jerarquía de clases. Puede elegir el método de entrada para la jerarquía de clases. Puede ingresar una representación de un árbol, o cada tipo con una lista de sus padres, o cualquier otra cosa que represente con precisión la jerarquía de clases.
  • Dos tipos (la entrada es flexible, siempre y cuando la notación sea consistente, puede recibir estos tipos como desee).

Salida

Se quiere una salida de tres valores reales y claras, los llaman X, Yy Z. Habida cuenta de dos tipos Ay B, de salida X, si Aes asignable a B, la salida Ysi Bes asignable a Ay la salida Zde otro modo (si Aes asignable a By Bes asignable a A, que puede emitir X, Y, ambos, o un cuarto valor).


Casos de prueba

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

Aquí hay un enlace a una solución Java no protegida que puede usar para las pruebas (toma la entrada de la misma manera que los casos de prueba)


Este es el código de golf, ¡así que menos bytes en cada idioma ganan para ese idioma!

Fénix Socrático
fuente
Sandbox (eliminado)
Socratic Phoenix
@ovs no, A tiene padres B y C.
Phoenix Socrático
@HalvardHummel disculpas; He editado la publicación
Socratic Phoenix
¿Heredará forma un círculo?
tsh
¿Qué debería generar si tanto A es asignable a B como B es asignable a A?
tsh

Respuestas:

3

Python 3 , 177 bytes

ces un diccionario de los padres de cada tipo, ay bson las dos expresiones para verificar. Los tipos están representados por cadenas, mientras que las intersecciones y las uniones están representadas por listas con expresiones, con el primer elemento establecido 0para intersección y 1unión

Devuelve 0si no se pueden asignar entre sí, 1si ase pueden asignar b, 2si bse pueden asignar ay 3si ambos se pueden asignar entre sí

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

Pruébalo en línea!

Halvard Hummel
fuente
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)

pes el mapa padre, que es un objeto JavaScript cuyas claves son los tipos con padres y cuyos valores son matrices de padres. Por ejemplo, si hay dos tipos Ay By Bes el padre de, Aentonces psería {A:['B']}.

Los tipos de intersección se representan en ay bcomo un objeto JavaScript con una clave icuyo valor es una matriz de tipos, mientras que los tipos de unión tienen una clave de u. Por ejemplo, la intersección de dos tipos Ay Bsería{i:['A','B']} .

El valor de retorno es truesi aes asignable a b, 1si ano es asignable a bperob es asignable a a, o 0si ninguno de los dos es asignable entre sí.

Neil
fuente
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;

Pruébalo en línea!

Una plantilla variable fque acepta como entrada algunos tipos e intersección i<...>o unión u<...>de ellos y devuelve -1si Aes asignable B y 1si Bes asignable aA y de lo 0contrario.

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

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
fuente