Compatibilité Vampire

28

Un fait peu connu sur les vampires est qu'ils doivent boire le sang de la victime qui a un groupe sanguin de donneur compatible. La matrice de compatibilité pour les vampires est la même que la matrice régulière donneur / receveur de globules rouges . Cela peut être résumé par le tableau suivant de la Croix-Rouge américaine

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-

Défi

Écrivez une fonction ou un programme qui prend un groupe sanguin en entrée et génère deux listes:

  1. la liste non ordonnée des types qui peuvent recevoir un don du type d'entrée
  2. la liste non ordonnée des types qui peuvent faire un don au type d'entrée

Si vous écrivez une fonction, veuillez également fournir un programme de test pour appeler cette fonction avec quelques exemples, afin que je puisse facilement la tester. Dans ce cas, le programme de test ne comptera pas dans votre score.

Contribution

L'entrée doit être une chaîne représentant exactement l'un des 8 types de globules rouges possibles O− O+ A− A+ B− B+ AB− AB+. L'entrée peut être donnée via les méthodes normales (STDIN, arguments de ligne de commande, arguments de fonction, etc.).

Si une autre entrée est donnée, le programme / la fonction doit retourner une sortie vide ou renvoyer une erreur. Normalement, une vérification stricte des entrées n'est pas excellente dans questions de , mais je me sentais, étant donné les implications pour la mort de se tromper sur les groupes sanguins, que je devrais ajouter cette règle.

Sortie

Le résultat sera deux listes lisibles par l'homme de groupes sanguins dans n'importe quel format adapté à votre langue. Dans les cas particuliers où l'une des listes de sortie contient les 8 types, cette liste peut éventuellement être remplacée par une seule liste d'articles contenant everyone.

La sortie normale ira à l'un des endroits normaux (STDOUT, retour de fonction, etc.).

Autres règles

  • Les failles standard sont interdites
  • Vous pouvez utiliser toutes les bibliothèques tierces préexistantes dont vous avez besoin, tant qu'elles ne sont pas conçues expressément à cette fin.

Exemples

  • Pour l'entrée AB-, les deux listes de sortie seraient:{AB+, AB-}, {AB-, A-, B-, O-}
  • Pour l'entrée AB+, les deux listes de sortie seraient: {AB+}, {O−, O+, A−, A+, B−, B+, AB−, AB+}ou{AB+}, {everyone}

Note personnelle: veuillez envisager de donner du sang si vous le pouvez. Sans la transfusion que j'ai reçue il y a quelques années, je ne serais peut-être pas ici aujourd'hui, donc je suis très reconnaissant envers ceux qui peuvent faire un don!

Traumatisme numérique
la source
@ MartinBüttner En fait, j'accepte les deux. Il est fort probable que le 2e formulaire produira un code plus court dans la plupart des langues, mais il y aura peut-être un cas particulier où l'utilisation du premier formulaire pourrait être plus courte.
Digital Trauma
3
Tangentiellement lié - cette brillante réponse worldbuilding.stackexchange.com/a/11203/2094
Digital Trauma
1
Ce fait n'est pas si peu connu .
cessé de tourner dans le sens inverse des aiguilles d'une montre
1
@leftaroundabout Merci - Un peu de Fry et Laurie a toujours été une de mes préférées!
Digital Trauma
1
Un vampire pointilleux, hein? Dracula se retourne dans son cercueil. En outre, le titre sonne comme le nom d'un groupe de rock gothique à la retraite.
Renae Lider

Réponses:

9

Clip , 69

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

Contribution: AB-

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

Explication

Un groupe sanguin xpeut donner ysi tous xles antigènes sont inclus dans y. Le programme définit la fonction Fcomme si elle xpeut donner yet Tcomme la liste des types.

*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
la source
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;}

Explication

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

Exécutez-le ici: http://repl.it/e98/1

Notez qu'il staticfallait ajouter à chaque méthode pour les appeler à partir de la méthode principale.

Ypnypn
la source
2
J'ai ajouté un lien vers un programme facile à exécuter pour vous. Modifiez le paramètre de chaîne à l'intérieur de l'appel de fonction dans la méthode principale pour voir les sorties des autres entrées.
mbomb007
5

Pyth, 61 59 50

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

Exécutez-le ici.

Explication:

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
la source
@ user23013 Merci pour la modification. Cela aurait certainement dû être cartésien :)
orlp
4

CJam, 64 octets

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

La m*:spartie vient de la réponse CJam de Martin . (Je n'ai pas encore lu les autres parties.)

Il y aura encore de sérieux problèmes car ils ne seront jamais sûrs de l'ordre des deux listes. Et Block ArrayList &pourrait être implémenté dans les versions ultérieures de CJam.

Explication

"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
la source
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}

non 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;
}

fonction de test:

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"))
}

Le codage du type sanguin en binaire a l'avantage qu'un autre antigène (par exemple l' antigène Kell ) est facilement incorporé dans le code en ajoutant simplement un autre bit.


Faire un don de sang à Zurich, CH: Blutspende Zürich

Niklaus Messerli
la source
Vous pouvez utiliser "O-O+B-B+A-A+AB-AB+".match(/\w+\W/g)au lieu de "O- O+ B- B+ A- A+ AB- AB+".split(" ")pour enregistrer 2 caractères.
Oriol
Ou vous pouvez enregistrer exactement la même chose en faisant le délimiteur un nombre "O-1O+1B-1B+1A-1A+1AB-1AB+".split(1)et en utilisant la =>fonction devrait en enregistrer aussi.
red-X
Oui, mais @ Oriol peut être encore raccourci dans l'expression régulière par 1 caractère:/\w+./g
manatwork
Utilisez toujours for (;;) au lieu de while (). Au moins la même longueur, mais peut être plus courte. n=2;while(n--)=>for(n=2;n--;)
edc65
Dans l'ensemble, très intelligent. Peut être réduit à 147 en utilisant des figures de golf standard:http://jsfiddle.net/j2hep8e8/2/
edc65
2

CJam, 94 octets

Wow, c'est long ... alors que je pense que je pourrais probablement jouer cette approche en dessous de 80, je pense que j'aurais pu faire mieux en calculant d'abord la matrice et en choisissant simplement la bonne ligne et la bonne colonne. Bref, le voici:

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

Testez-le ici.

J'ajouterai une explication quand j'aurai fini de jouer au golf.

Martin Ender
la source
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)}]]}

L'idée est de coder A, B et le facteur rhésus comme un bit chacun. Nous pouvons ensuite inverser les bits pour obtenir tous les antigènes du côté récepteur et l'utiliser pour vérifier qu'il n'y a pas d'anticorps correspondants du côté donneur. C'est plus ou moins la même chose que la solution JavaScript existante.

Exemple d'exécution

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̷̰̀ĥ̷̳
la source
2

Prolog, 119 110 octets

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

Remarques :

  1. Les groupes sanguins ont les propriétés suivantes: chaque fois que vous en avez -(par exemple a-), vous pouvez donner aux mêmes personnes que celles qui ont un équivalent positif de votre groupe (par exemple a), ainsi que leur contrepartie négative (par exemple, adonne ab, donc a-donne à abet ab-). Sur la base de cette propriété, et en abusant un peu des notations pour utiliser les opérateurs moins et plus, nous pouvons prendre en compte de nombreux cas. Veuillez me dire si vous le trouvez acceptable . Si vous préférez avoir la syntaxe d'origine (postfix), voici une version non-golfée:

    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. Il s'agit de Prolog, donc l'environnement interactif permet de tout interroger comme demandé (voir l'exemple ci-dessous). Certes, nous n'avons pas de listes strictement en sortie, mais c'est équivalent. Nous gérons également naturellement les cas d'erreur.

Exemple

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.

Ensuite, nous exécutons 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)])

... qui, sans mise en forme appropriée, est la même matrice que celle donnée dans la question.

Détails

Le prédicat g/2est le donner relation: g(X,Y)moyens les gens de type sanguin X peut donner du sang aux personnes de type sanguin Y .

Trouver des récepteurs pour le groupe a:

[eclipse]: g(a,R).    

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

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

Rechercher des récepteurs pour orange_juice (devrait échouer):

[eclipse] g(orange_juice,L).

No (0.00s cpu)

Trouver des donateurs pour O- :

[eclipse] g(X,-o).

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

Qui peut donner quoi? :

[eclipse] g(X,Y).

.... 27 answers ....

On n'entre pas dans une boucle de récursion infinie (c'était le cas dans les tests préliminaires).

coredump
la source
1

Python, 187 octets

Une approche différente:

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]

Peut probablement être joué un peu plus.

Tester:

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

Sortie:

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
la source
1

Rubis, 237 232 223 221 210 207 octets

Correction de quelques barres obliques inverses superflues dans les expressions régulières et fait en sorte qu'il imprime simplement les listes au lieu de les stocker dans des variables puis de les imprimer. Parfois, vous manquez les choses évidentes lorsque vous essayez de jouer au 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)}

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

Fondamentalement, je construis une expression régulière personnalisée pour le groupe sanguin entré pour vérifier si vous pouvez faire un don à un autre groupe sanguin. J'itère ensuite les groupes sanguins et leur applique la même expression régulière et vérifie s'ils peuvent faire un don à celui spécifié.

Cela peut probablement être joué encore plus. C'est ma première fois que j'essaye le golf de code, heh.

Mewy
la source
1

Python 2, 168 octets

C'est la même méthode que la réponse de Blackhole. Quitte avec une erreur si le paramètre n'est pas trouvé dans la liste des types.

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]

Moins golfé:

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

Exécutez-le ici: http://repl.it/eaB

J'ai également essayé quelques autres changements légers, mais je n'ai pas pu le raccourcir ...

#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
la source
1

PHP (287 octets):

Oui, c'est assez long, mais ça fonctionne comme prévu.

Il peut être possible de raccourcir beaucoup:

!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'
';}

Ce n'est pas facile à lire et ce n'était pas facile à écrire.

Il fonctionne comme prévu, produisant ceux que vous pouvez donner et ceux que vous pouvez recevoir sur une autre ligne.

Cela nécessite un paramètre d'URL T=avec le type.

Ismael Miguel
la source
1

CJam, 80 octets

C'est encore trop long. Je peux probablement raser 4 à 5 octets de plus.

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

Pour toute entrée non valide, imprime un tableau vide ou renvoie une erreur.

Essayez-le en ligne ici ou exécutez toute la suite de tests

Optimiseur
la source
Le XKCD dans la mendicité est-il destiné?
Ypnypn
@Ypnypn mendiant? Je n'avais pas l'intention de le faire au départ, mais cela s'est avéré comme ça. Peut-être que le monde essaie de nous dire quelque chose ...
Optimizer
Désolé, je voulais dire commencer .
Ypnypn
1

APL, 66

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

Essayez-le ici.

jimmy23013
la source
C'est peut-être 66 caractères, mais certainement pas 66 octets. Cependant, la question ne dit pas ce qui sert à marquer.
orlp
1
@orlp code-golf est marqué en octets par défaut (voir le tag wiki ). Mais on dit qu'il y a une page de code APL où un caractère est un octet. Je ne sais pas exactement quelle page de code APL est utilisée de nos jours, cependant.
jimmy23013
@orlp "octets", mais pas "octets UTF-8". Voici une page de codes contenant tous ces caractères.
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-golfed cela montre:

/* 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
la source
1

PHP - 215 212 206 octets

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);}

Voici la version non golfée:

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);
}

Merci à manatwork pour avoir économisé 4 octets.

Trou noir
la source
La division par tour entier en PHP fonctionne aussi: explode(1,'A+1O+1B+1AB+1A-1O-1B-1AB-'). Et comme nous ne suivons pas nécessairement de bonnes habitudes de codage, nous utilisons parfois des fonctionnalités obsolètes, comme la split()fonction.
manatwork
@manatwork Bien repéré! J'ai édité ma réponse, merci.
Blackhole
0

Perl, 107 112

Enfin, l'encodage des noms de type en chiffres a donné le code le plus court.

#!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+/

Ancienne version

#!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
la source
0

Pyth, 58

En partie la même que la solution orlp , mais quelque peu différente et complètement conçue par soi-même.

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

Explication

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
la source
0

J, 120 octets

   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 fonction échoue sur des entrées invalides. Le grand nombre décimal est l'encodage de la matrice de compatibilité complète.

(Solution très longue pour plusieurs raisons.)

Essayez-le en ligne ici.

randomra
la source