Compatibilidad con vampiros

28

Un hecho poco conocido sobre los vampiros es que deben beber la sangre de la víctima que tiene un tipo de sangre de donante compatible. La matriz de compatibilidad para vampiros es la misma que la matriz regular de donantes / receptores de glóbulos rojos . Esto se puede resumir en la siguiente tabla de la Cruz Roja Americana

Type    You Can Give Blood To    You Can Receive Blood From
A+      A+, AB+                  A+, A-, O+, O-
O+      O+, A+, B+,AB+           O+, O-
B+      B+, AB+                  B+, B-, O+, O-
AB+     AB+                      everyone
A-      A+, A-, AB+, AB-         A-, O-
O-      everyone                 O-
B-      B+, B-, AB+, AB-         B-  O-
AB-     AB+, AB-                 AB-, A-, B-, O-

Reto

Escriba una función o programa que tome un tipo de sangre como entrada y genere dos listas:

  1. la lista desordenada de tipos que pueden recibir donación del tipo de entrada
  2. la lista desordenada de tipos que pueden donar al tipo de entrada

Si escribe una función, proporcione también un programa de prueba para llamar a esa función con algunos ejemplos, para que pueda probarla fácilmente. En este caso, el programa de prueba no contaría para su puntaje.

Entrada

La entrada debe ser una cadena que represente exactamente uno de los 8 posibles tipos de glóbulos rojos O− O+ A− A+ B− B+ AB− AB+. La entrada puede darse a través de los métodos normales (STDIN, argumentos de línea de comandos, argumentos de función, etc.).

Si se proporciona cualquier otra entrada, entonces el programa / función debe devolver una salida vacía o arrojar un error. Normalmente, la comprobación estricta de las entradas no es excelente en preguntas de , pero me pareció que, dada la implicación de muerte o muerte de los tipos de sangre incorrectos, debería agregar esta regla.

Salida

La salida será dos listas de tipos de sangre legibles por humanos en cualquier formato que sea adecuado para su idioma. En los casos especiales en los que una de las listas de salida contiene los 8 tipos, esta lista puede reemplazarse opcionalmente por una lista de elementos única que contenga everyone.

La salida normal irá a uno de los lugares normales (STDOUT, retorno de función, etc.).

Otras reglas

  • Las lagunas estándar están prohibidas
  • Puede usar las bibliotecas de terceros preexistentes que necesite, siempre que no estén diseñadas explícitamente para este propósito.

Ejemplos

  • Para la entrada AB-, las dos listas de salida serían:{AB+, AB-}, {AB-, A-, B-, O-}
  • Para la entrada AB+, las dos listas de salida serían: {AB+}, {O−, O+, A−, A+, B−, B+, AB−, AB+}o{AB+}, {everyone}

Nota personal: considere donar sangre si puede. Sin la transfusión que recibí hace unos años, es posible que no esté aquí hoy, ¡así que me siento muy agradecido con aquellos que pueden donar!

Trauma digital
fuente
@ MartinBüttner En realidad, aceptaré ambos. Lo más probable es que la segunda forma produzca un código más corto en la mayoría de los idiomas, pero quizás haya algún caso especial en el que el uso de la primera forma podría ser más corto.
Trauma digital
3
Relacionado tangencialmente: esta brillante respuesta worldbuilding.stackexchange.com/a/11203/2094
Digital Trauma
1
Ese hecho no es tan poco conocido .
dejó de girar en contra del reloj el
1
@leftaroundabout Gracias - ¡Un poco de alevines y Laurie siempre ha sido uno de mis favoritos!
Digital Trauma
1
Un vampiro exigente, ¿eh? Drácula está girando en su ataúd. Además, el título suena como el nombre de una banda de goth-rock retirada.
Renae Lider

Respuestas:

9

Clip , 69

*cTx\{fFx`Tf[tFtx}T`[Fx[y!VVx"O-"Vy"O-"}[TC"A+ B+ AB+ O+ A- B- AB- O-

Entrada: AB-

Salida: {{"AB+", "AB-"}, {"A-", "B-", "AB-", "O-"}}

Explicación

Un tipo de sangre xpuede ceder ysi todos xlos antígenos están incluidos y. El programa define la función Fcomo si xpuede dar a y, y Tcomo la lista de tipos.

*cTx                 .- If T contains x (the input)         -.
    \                .- Print                               -.
     {             ` .- a list of                           -.
      fFx`T          .- filter each t in T with F(x,t)      -.
           f[tFtx}T  .- filter each t in T with F(t,x)      -.

[Fx[y              } .- F is a function of x and y          -.
     !V              .- all letters of ... are included in ...   -.
       Vx"O-"        .- x, with O and - removed             -.
             Vy"O-"  .- y, with O and - removed             -. 

[TC"A+ B+ AB+ O+ A- B- AB- O-   .- T is the list of types -.
Ypnypn
fuente
6

Java 8, 373

import java.util.*;void f(String s){List<String>l=new ArrayList(Arrays.asList("A+,B+,AB+,O+,A-,B-,AB-,O-".split(","))),m=new ArrayList(l);int i=l.contains(s)?1:0/0;l.removeIf(x->g(s,x)<1);m.removeIf(x->g(x,s)<1);System.out.print(l+","+m);}int g(String s,String t){for(char c:s.replaceAll("O|-","").toCharArray())if(!t.replaceAll("O|-","").contains(""+c))return 0;return 1;}

Explicación

void f(String s) {
    List<String> l = new ArrayList(Arrays.asList("A+,B+,AB+,O+,A-,B-,AB-,O-".split(","))),
                 m = new ArrayList(l);
    int i = l.contains(s) ? 1 : 0 / 0;
    l.removeIf(x -> g(s, x) < 1);
    m.removeIf(x -> g(x, s) < 1);
    System.out.print(l + "," + m);
}

int g(String s, String t) {
    for (char c : s.replaceAll("O|-", "").toCharArray()) {
        if (!t.replaceAll("O|-", "").contains("" + c)) {
            return 0;
        }
    }
    return 1;
}

Ejecútelo aquí: http://repl.it/e98/1

Tenga en cuenta que statictuvo que agregarse a cada método para llamarlos desde el método principal.

Ypnypn
fuente
2
Agregué un enlace a un programa fácil de ejecutar para usted. Edite el parámetro de cadena dentro de la llamada de función en el método principal para ver las salidas de otras entradas.
mbomb007
5

Pyth, 61 59 50

L-{b"O-"M!-yGyHJmsd*c"A O B AB"d"+-"I}zJfgzTJfgYzJ

Ejecútalo aquí.

Explicación:

L-{b"O-"                         Create function y(b) that makes a set from b's 
                                 characters minus O and -.
M!-yGyH                          Create function g(G,H) that checks if y(G) is 
                                 a subset of y(H).
J                                Assign to J...
 msd                             The concatenation of every element in...
    *c"A O B AB"d"+-"            The Cartesian product of A O B AB and + -.
I}zJ                             If input in J then...
    fgzTJ                        Print all elements e in J if g(input, e).
    fgYzJ                        Print all elements e in J if g(e, input).
orlp
fuente
@ user23013 Gracias por la edición. Definitivamente debería haber sido cartesiano :)
orlp
4

CJam, 64 bytes

"AB"_a+'O+"+-"m*:s:TT{}+Tqa#=a+T4=f&_)f{\-!}\)f-:!]{T]z::*La-p}/

La m*:sparte viene de la respuesta Martin CJam . (Todavía no leí las otras partes).

Todavía habrá algunos problemas serios porque nunca estarán seguros del orden de las dos listas. YBlock ArrayList & podría implementarse en versiones posteriores de CJam.

Explicación

"AB"_a+'O+         " Generate ['A 'B \"AB\" 'O]. ";
"+-"m*:s:T         " Generate the list of blood types and store in T. ";
T{}+
    Tqa#           " Find the input in T. ";
=                  " Find the blood type by the index.
                     If not found, return a block to cause an error. ";
a+                 " Append the verified input to T. ";
T4=                " AB+. ";
f&                 " Intersect each blood type with AB+. ";
_)f{\-!}           " Check emptiness of input - each item. ";
\)f-:!             " Check emptiness of each item - input. ";
]{                 " For both lists: ";
    T]z::*         " Replace items in T where there is a 0 with empty strings. ";
    La-            " Remove empty strings. ";
    p              " Print. ";
}/
jimmy23013
fuente
3

Javascript, 167

p=function(t){o="";if((x=(l="O- O+ B- B+ A- A+ AB- AB+".split(" ")).indexOf(t))<0)return;n=2;while(n--){y=8;while(y--)if([y,x][n]-(y&x)==0)o+=" "+l[y];o+=";"}return o}

sin golf:

function p(btype){
    output = "";
    btypeList = "O- O+ B- B+ A- A+ AB- AB+".split(" ");

    btypeInt = btypeList.indexOf(btype);
    // thus we have the scheme
    // btypeInt = 0b(has A antigen)(has B antigen)(has rhesus antigen)

    if(btypeInt < 0) // i.e. broken blood type string
        return;

    for(receiving = 7; receiving >= 0; receiving--)
        if(giving - (receiving & btypeInt) == 0)
            // i.e. the receiving person has at least all the antigens of our donor
            output += " " + btypeList[receiving];

    output += ";";

    for(giving = 7; giving >= 0; giving--)
        if(btypeInt - (receiving & btypeInt) == 0)
            // i.e. the giving person has no antigens that our patient doesn't have
            output += " " + btypeList[receiving];

    return output;
}

función de prueba:

function tester(){
    btypeList = "O- O+ B- B+ A- A+ AB- AB+".split(" ");
    for(i=0; i<8; i++){
        console.log("Patient is " + btypeList[i])
        console.log(p(btypeList[i]))
    }
    console.log("Erroneous blood type => returns void:")
    console.log(p("asdf"))
}

La codificación del tipo de sangre en binario tiene la ventaja de que otro antígeno (por ejemplo, el antígeno de Kell ) se incorpora fácilmente al código simplemente agregando otro bit.


Donar sangre en Zurich, CH: Blutspende Zürich

Niklaus Messerli
fuente
Puede usar en "O-O+B-B+A-A+AB-AB+".match(/\w+\W/g)lugar de "O- O+ B- B+ A- A+ AB- AB+".split(" ")guardar 2 caracteres.
Oriol
O puede guardar exactamente lo mismo haciendo que el delimitador sea un número "O-1O+1B-1B+1A-1A+1AB-1AB+".split(1)y el uso de la =>función también debería guardar algunos.
rojo-X
Sí, pero @ Oriol se puede acortar aún más en la expresión regular por 1 carácter:/\w+./g
manatwork
Siempre use para (;;) en lugar de while (). Al menos la misma longitud, pero puede ser más corta. n=2;while(n--)=>for(n=2;n--;)
edc65
En general, muy inteligente. Se puede acortar a 147 usando trucos de golf estándar:http://jsfiddle.net/j2hep8e8/2/
edc65
2

CJam, 94 bytes

Wow, esto es largo ... aunque creo que probablemente podría jugar golf este enfoque por debajo de 80, creo que podría haberlo hecho mejor calculando primero la matriz y luego simplemente seleccionando la fila y columna correctas. De todos modos, aquí está:

'O'A'B"AB"]:A"+-"m*:sq_a@&!!*_)'++_&\"AB"&A{1$\-!},\;\m*::+p)'-+_&\"AB"&A1>{1$-!},'O+\;\m*::+p

Pruébalo aquí.

Agregaré una explicación cuando termine de jugar al golf.

Martin Ender
fuente
2

Groovy, 115

x={i=(l=('O-O+B-B+A-A+AB-AB+'=~/\w+./)[0..7]).indexOf(it);f=(0..7).&findAll;i<0?[]:[l[f{!(~it&i)}],l[f{!(it&~i)}]]}

La idea es codificar A, B y factor rhesus como un bit cada uno. Luego podemos invertir los bits para obtener todos los antígenos en el lado receptor y usarlo para verificar que no haya anticuerpos correspondientes en el lado donante. Esto es más o menos lo mismo que la solución JavaScript existente.

Ejecución de la muestra

groovy> println x("AB+") 
groovy> println x("AB-") 
groovy> println x("A+") 
groovy> println x("A-") 
groovy> println x("B+") 
groovy> println x("B-") 
groovy> println x("O+") 
groovy> println x("O-") 
groovy> println x("X") 

[[AB+], [O-, O+, B-, B+, A-, A+, AB-, AB+]]
[[AB-, AB+], [O-, B-, A-, AB-]]
[[A+, AB+], [O-, O+, A-, A+]]
[[A-, A+, AB-, AB+], [O-, A-]]
[[B+, AB+], [O-, O+, B-, B+]]
[[B-, B+, AB-, AB+], [O-, B-]]
[[O+, B+, A+, AB+], [O-, O+]]
[[O-, O+, B-, B+, A-, A+, AB-, AB+], [O-]]
[]
n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳
fuente
2

Prolog, 119 110 bytes

u(A,B):-member(A:B,[a:ab,b:ab,o:a,o:b,o:ab]);A=B,member(A,[a,ab,b,o]).
g(X,Y):-(X= -A;X=A),(Y= -B;Y=B),u(A,B).

Observaciones :

  1. Tipos de sangre tienen las siguientes propiedades: cada vez que tiene una -(por ejemplo a-), se puede dar a las mismas personas como el que tienen equivalentes positiva de su grupo (por ejemplo a), así como su contrapartida negativa (por ejemplo, ada a ab, por lo que a-da a aby ab-) En base a esta propiedad, y abusando un poco de las notaciones para hacer uso de los operadores menos y más, podemos factorizar muchos casos. Por favor dígame si lo encuentra aceptable . Si prefiere tener la sintaxis original (postfix), aquí hay una versión sin golf:

    blood(X):-member(R,['a+','o+','b+','ab+','a-','b-','ab-']).
    give('o-',R):-blood(R).
    give(X,X):-blood(X).
    give('a+','ab+').
    give('b+','ab+').
    give('o+','a+').
    give('o+','b+').
    give('o+','ab+').
    give('a-','a+').
    give('a-','ab+').
    give('a-','ab-').
    give('b-','b+').
    give('b-','ab+').
    give('b-','ab-').
    give('ab-','ab+').
    
  2. Esto es Prolog, por lo que el entorno interactivo permite consultar todo según lo solicitado (ver ejemplo a continuación). Por supuesto, no tenemos listas estrictamente como salida, pero esto es equivalente. Naturalmente, también manejamos casos de error como consecuencia.

Ejemplo

donors(X,L) :- findall(Y,g(Y,X),L).
receivers(X,L) :- findall(Y,g(X,Y),L).

test :-
    member(X,[a,o,b,ab,-a,-o,-b,-ab]),
    donors(X,D),
    receivers(X,R),
    writeln(X:give_to(R):receive_from(D)),
    fail.
test.

Luego, ejecutamos test:

a : give_to([ab, a]) : receive_from([o, a])
o : give_to([a, b, ab, o]) : receive_from([o])
b : give_to([ab, b]) : receive_from([o, b])
ab : give_to([ab]) : receive_from([a, b, o, ab])
-(a) : give_to([+(ab), +(a), -(ab), -(a)]) : receive_from([-(o), -(a)])
-(o) : give_to([+(a), +(b), +(ab), +(o), -(a), -(b), -(ab), -(o)]) : receive_from([-(o)])
-(b) : give_to([+(ab), +(b), -(ab), -(b)]) : receive_from([-(o), -(b)])
-(ab) : give_to([+(ab), -(ab)]) : receive_from([-(a), -(b), -(o), -(ab)])

... que, sin el formato adecuado, es la misma matriz que la dada en la pregunta.

Detalles

El predicado g/2es el dar relación: g(X,Y)medios personas de tipo de sangre X pueden dar sangre a las personas de tipo de sangre Y .

Encuentra receptores para el grupo a :

[eclipse]: g(a,R).    

R = ab
Yes (0.00s cpu, solution 1, maybe more) ? ;

R = a
Yes (0.00s cpu, solution 2)

Encuentra receptores para orange_juice (debería fallar):

[eclipse] g(orange_juice,L).

No (0.00s cpu)

Encuentra donantes para O- :

[eclipse] g(X,-o).

X = -(o)
Yes (0.00s cpu)

¿Quién puede dar qué? :

[eclipse] g(X,Y).

.... 27 answers ....

No entramos en un bucle de recursión infinito (fue el caso en las pruebas preliminares).

volcado de memoria
fuente
1

Python, 187 bytes

Enfoque diferente:

def D(a,b):X=lambda c:c in a and 1-(c in b);return(X('A')+X('B')+X('+'))<1
T="O- O+ A- A+ B- B+ AB- AB+".split()
X=lambda t:(0,([u for u in T if D(t,u)],[u for u in T if D(u,t)]))[t in T]

Probablemente se pueda jugar un poco más al golf.

Prueba:

for t in T + ["zz"]:
    print t, X(t)

Salida:

O- (['O-', 'O+', 'A-', 'A+', 'B-', 'B+', 'AB-', 'AB+'], ['O-'])
O+ (['O+', 'A+', 'B+', 'AB+'], ['O-', 'O+'])
A- (['A-', 'A+', 'AB-', 'AB+'], ['O-', 'A-'])
A+ (['A+', 'AB+'], ['O-', 'O+', 'A-', 'A+'])
B- (['B-', 'B+', 'AB-', 'AB+'], ['O-', 'B-'])
B+ (['B+', 'AB+'], ['O-', 'O+', 'B-', 'B+'])
AB- (['AB-', 'AB+'], ['O-', 'A-', 'B-', 'AB-'])
AB+ (['AB+'], ['O-', 'O+', 'A-', 'A+', 'B-', 'B+', 'AB-', 'AB+'])
zz 0
Claudiu
fuente
1

Rubí, 237 232 223 221 210 207 bytes

Se corrigieron algunas barras diagonales inversas extrañas en las expresiones regulares y se hizo para que solo imprima las listas en lugar de almacenarlas en variables y luego imprimirlas. ¡A veces te pierdes las cosas obvias cuando intentas jugar al golf!

o=->b{Regexp.new b.gsub(?O,?.).gsub(?+,'.?\\\+').gsub'-','.?(\W)'};b=gets.chop;t=["A+","B+","AB+","O+","A-","B-","AB-","O-"];exit if !t.include? b;p t.reject{|x|!x.match o.(b)};p t.reject{|x|!b.match o.(x)}

Sin golf:

#!/usr/bin/ruby
b=gets.chomp;
types = ["A+","A-","B+","B-","AB+","AB-","O+","O-"];
exit if !types.include?(b);
regex1 = Regexp.new b.gsub("O",".").gsub('+','.?\\\+').gsub('-','.?(\\\+|\\\-)')
donate = types.reject {|x|!x.match(regex1)};
p donate;
receive = types.reject {|x| regex2 = Regexp.new x.gsub("O",".").gsub('+','.?\\\+').gsub('-','.?(\\\+|\\\-)'); !b.match(regex2)};
p receive;

Básicamente, construyo una expresión regular personalizada para el tipo de sangre ingresado para verificar si puede donar a otro tipo de sangre. Luego repito los tipos de sangre y les aplico la misma expresión regular y verifico si pueden donar a la especificada.

Esto probablemente se pueda jugar aún más. Esta es la primera vez que intento jugar golf en código, je.

Mewy
fuente
1

Python 2, 168 bytes

Este es el mismo método que la respuesta de Blackhole. Sale con un error si el parámetro no se encuentra en la lista de tipos.

def f(t):l='A+ O+ B+ AB+ A- O- B- AB-'.split();c=[9,15,12,8,153,255,204,136];i=l.index(t);print[s for s in l if c[i]&1<<l.index(s)],[s for s in l if c[l.index(s)]&1<<i]

Menos golfizado:

def f(t):
    l = 'A+ O+ B+ AB+ A- O- B- AB-'.split()
    c = [9, 15, 12, 8, 153, 255, 204, 136]
    i = l.index(t)
    x = [s for s in l if c[i] & 1 << l.index(s)]
    y = [s for s in l if c[l.index(s)] & 1 << i]
    print x, y

Ejecútalo aquí: http://repl.it/eaB

También probé otros cambios leves, pero no pude hacerlo más corto ...

#172 bytes
def f(t):l='A+ O+ B+ AB+ A- O- B- AB-'.split();c=[9,15,12,8,153,255,204,136];a=lambda x:l.index(x);i=a(t);print[s for s in l if c[i]&1<<a(s)],[s for s in l if c[a(s)]&1<<i]

#171 bytes
def f(t):l='A+ O+ B+ AB+ A- O- B- AB-'.split();c=[9,15,12,8,153,255,204,136];a=lambda x:l.index(x);print[s for s in l if c[a(t)]&1<<a(s)],[s for s in l if c[a(s)]&1<<a(t)]
mbomb007
fuente
1

PHP (287 bytes):

Sí, esto es bastante largo, pero funciona como se esperaba.

Es posible acortar mucho:

!preg_match('@^(AB?|B|O)[+-]$@',$t=$_GET[T])&&die("$t invalid");$S=array_flip($D=split(0,'O+0A+0B+0AB+0O-0A-0B-0AB-'));$L=[[1230,40],[13,1504],[23,2604],[3,$r=12345670],[$r,4],[1537,54],[2637,64],[37,7564]];for($j=0;$j<2;){foreach(str_split($L[$S[$t]][$j++])as$v)echo$D[$v].' ';echo'
';}

Esto no es fácil de leer y no fue fácil de escribir.

Funciona según lo previsto, generando los que puede dar y los que puede recibir en otra línea.

Esto requiere un parámetro de URL T=con el tipo.

Ismael Miguel
fuente
1

CJam, 80 bytes

Esto todavía es demasiado largo. Probablemente puedo reducir 4 a 5 bytes más.

U1023_XKC30D]2/La+"AB"a"OAB"1/+:Mr):P;a#=_P"+-":G&+!!{AfbMff=G1/Pf|]z{~m*:s}%}*`

Para cualquier entrada no válida, imprime una matriz vacía o arroja un error.

Pruébelo en línea aquí o ejecute todo el conjunto de pruebas

Optimizador
fuente
¿Está previsto el XKCD en la mendicidad?
Ypnypn
@Ypnypn mendigando? Inicialmente no tenía intención de hacerlo, pero resultó así. Tal vez el mundo está tratando de decirnos algo ...
Optimizer
Lo siento, quise decir comenzar .
Ypnypn
1

APL, 66

(↓⊃∧/(↓t∘.∊v)(≥,[.5]≤)¨t∊⊃v⌷⍨v⍳⊂⍞)/¨⊂v←,'+-'∘.,⍨('O'∘,,⊂)2↑t←'AB+'

Pruébalo aquí

jimmy23013
fuente
Quizás sean 66 caracteres, pero definitivamente no 66 bytes. Sin embargo, la pregunta no dice qué se usa para anotar.
orlp
1
@orlp code-golf se puntúa en bytes de forma predeterminada (consulte la etiqueta wiki ). Pero se dice que hay una página de códigos APL donde un carácter es un byte. Sin embargo, no sé exactamente qué página de códigos APL se usa hoy en día.
jimmy23013
@orlp "bytes", pero no "UTF-8 bytes". Aquí hay una página de códigos que contiene todos estos caracteres.
Martin Ender
1

C, 224

#define d(x)for(i=0;i<8;i++)if((i x j)==j)printf("%s%s%s%c ",i&2?"A":"",i&4?"B":"",i&6?"":"0","-+"[i&1]);puts("");
main(i,j){char d[4],*c=&d;scanf("%s",c);j=(c[2]?c++,2:0)+(c[1]-'+'?0:1)+(*c>='A'?2:0)+(*c>'A'?2:0);d(&)d(|)}

De golf se muestra:

/* j = 1*(has+) + 2*(hasA) + 4*(hasB) */
#define d(x) for(i=0;i<8;i++) \
                 if((i x j)==j) \
                      printf("%s%s%s%c ",i&2?"A":"",i&4?"B":"",i&6?"":"0","-+"[i&1]); \
             puts("");

main(i,j)
{
    char d[4], *c=&d;
    scanf("%s",c);

    j= (c[2]? (c++,2):0)            /* ABx */
            + (c[1]-'+'?0:1)
            + (c[0]>='A'?2:0)
            + (c[0]>'A'?2:0);

    // print possible receipients, and then donators
    d(&)
    d(|)
}
pawel.boczarski
fuente
1

PHP - 215 212 206 bytes

function($t){$c=[9,15,12,8,153,255,204,136];if(($a=array_search($t,$l=split(1,'A+1O+1B+1AB+1A-1O-1B-1AB-')))===!1)die;foreach($l as$k=>$v){if($c[$a]&1<<$k)$x[]=$v;if($c[$k]&1<<$a)$y[]=$v;}var_dump($x,$y);}

Aquí está la versión sin golf:

function ($type)
{
    $typesList = ['A+', 'O+', 'B+', 'AB+', 'A-', 'O-', 'B-', 'AB-'];
    $donationCompatibilityList = [
        0b00001001,
        0b00001111,
        0b00001100,
        0b00001000,
        0b10011001,
        0b11111111,
        0b11001100,
        0b10001000,
    ];

    $idType = array_search($type, $typesList);
    if ($idType === false) {
        die;
    }

    $canGiveToList = [];
    $canReceiveFromList = [];
    foreach ($typesList as $currentIdType => $currentType)
    {
        if ($donationCompatibilityList[$idType] & 1 << $currentIdType ) {
            $canGiveToList[] = $currentType;
        }

        if ($donationCompatibilityList[$currentIdType ] & 1 << $idType) {
            $canReceiveFromList[] = $currentType;
        }
    }

    var_dump($canGiveToList, $canReceiveFromList);
}

Gracias a manatwork por guardar 4 bytes.

Agujero negro
fuente
La división por número entero truco funciona en PHP también: explode(1,'A+1O+1B+1AB+1A-1O-1B-1AB-'). Y como no necesariamente mantenemos buenos hábitos de codificación, a veces usamos características obsoletas, como la split()función.
manatwork
@manatwork Bien visto! He editado mi respuesta, gracias.
Blackhole
0

Perl, 107 112

Finalmente, codificar los nombres de los tipos en números dio el código más corto.

#!perl -p
$x=y/AB+/421/r%9;@a=grep{~$x&$_%9||push@b,$_;!($x&~($_%9))}map{("$_-",$_.1)}0,2,4,42;$_="@a
@b";y/421/AB+/

Versión antigua

#!perl -p
$x=y/AB+/421/r%9;@a=grep!($x&~$_),0..7;@b=grep!(~$x&$_),0..7;$_="@a
@b";s/\d/(map{("$_+","$_-")}0,A,B,AB)[$&]/eg
nutki
fuente
0

Pyth, 58

En parte lo mismo que la solución de orlp , pero algo diferente y completamente auto-diseñado.

M&n+eGeH"+-"!f!}T+H\OPGJsm,+d\++d\-c"O A B AB"dfgzYJfgZzJJ

Explicación

M                          create a function g(G,H) that returns
  n+eGeH"+-"                 G[-1] + H[-1] is not "+-"
 &                          and
            !f!}T+H\OPG      chars of G[:-1] not in H + "O" is falsy (empty)
J                          J =
 s                          merge
  m                          map
   ,+d\++d\-                  lambda d: (d + "+", d + "-")
            c"O A B AB"d      over ["O", "A", "B", "AB"]
fgzYJ                      print all J's items x where g(input, x)
fgZzJ                      print all J's items x where g(x, input)
PurkkaKoodari
fuente
0

J, 120 bytes

   f=.3 :';"1(2 8$,(s-:"*<y,'' '')#8 2 8$#:213472854600871062656691437010712264449x)#s=.<;.2''A+ B+ AB+ O+ A- B- AB- O- '''

   f 'A+'
A+ AB+      
A+ O+ A- O- 

   f 'AB-'
AB+ AB-      
A- B- AB- O- 

La función falla en entradas no válidas. El gran número decimal es la codificación de la matriz de compatibilidad completa.

(Solución muy larga por múltiples razones).

Pruébelo en línea aquí.

randomra
fuente