Kompatybilność z wampirami

28

Mało znanym faktem na temat wampirów jest to, że muszą pić krew ofiary, która ma zgodną grupę krwi dawcy. Matryca zgodności dla wampirów jest taka sama jak zwykła matryca dawcy / biorcy krwinek czerwonych . Można to podsumować poniższą tabelą Amerykańskiego Czerwonego Krzyża

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-

Wyzwanie

Napisz funkcję lub program, który pobiera grupę krwi jako dane wejściowe i wyświetla dwie listy:

  1. nieuporządkowana lista typów, które mogą otrzymać darowiznę typu wejściowego
  2. nieuporządkowana lista typów, które mogą dawać darowiznę na typ wejściowy

Jeśli piszesz funkcję, podaj również program testowy, aby wywołać tę funkcję z kilkoma przykładami, dzięki czemu mogę ją łatwo przetestować. W takim przypadku program testowy nie wlicza się do wyniku.

Wkład

Dane wejściowe muszą być ciągiem reprezentującym dokładnie jeden z 8 możliwych rodzajów krwinek czerwonych O− O+ A− A+ B− B+ AB− AB+. Dane wejściowe można podawać zwykłymi metodami (STDIN, argumenty wiersza poleceń, argumenty funkcji itp.).

Jeśli podano inne dane, program / funkcja musi zwrócić puste wyjście lub zgłosić błąd. Zwykle ścisłe sprawdzanie danych wejściowych nie jest świetne w pytań do , ale czułem, że biorąc pod uwagę konsekwencje śmierci w wyniku pomyłki grup krwi, powinienem dodać tę zasadę.

Wydajność

Wynikiem będą dwie czytelne dla człowieka listy grup krwi w dowolnym formacie odpowiednim dla twojego języka. W szczególnych przypadkach, gdy jedna z list wyników zawiera wszystkie 8 typów, tę listę można opcjonalnie zastąpić pojedynczą listą pozycji zawierającą everyone.

Normalne wyjście trafi do jednego z normalnych miejsc (STDOUT, powrót funkcji itp.).

Inne zasady

  • Standardowe luki są zabronione
  • Możesz korzystać z wszelkich istniejących bibliotek stron trzecich, których potrzebujesz, o ile nie są one specjalnie zaprojektowane do tego celu.

Przykłady

  • W przypadku danych wejściowych AB-dwie listy wyjściowe będą następujące:{AB+, AB-}, {AB-, A-, B-, O-}
  • W przypadku danych wejściowych AB+dwie listy wyjściowe to: {AB+}, {O−, O+, A−, A+, B−, B+, AB−, AB+}lub{AB+}, {everyone}

Notatka osobista: Jeśli to możliwe, rozważ oddanie krwi. Bez transfuzji, którą otrzymałem kilka lat temu, być może nie byłoby mnie dzisiaj, więc jestem bardzo wdzięczny tym, którzy są w stanie przekazać darowiznę!

Cyfrowa trauma
źródło
@ MartinBüttner Właściwie akceptuję oba. Najprawdopodobniej drugi formularz da krótszy kod w większości języków, ale być może będzie jakiś szczególny przypadek, w którym użycie pierwszego formularza może być krótsze.
Cyfrowa trauma
3
Stycznie spokrewnione - ta genialna odpowiedź worldbuilding.stackexchange.com/a/11203/2094
Cyfrowa trauma
1
Fakt ten nie jest tak mało znany .
przestał obracać przeciwnie do zegara
1
@leftaroundabout Dzięki - Trochę Fry i Laurie zawsze była moją ulubioną!
Cyfrowa trauma
1
Wybredny wampir, co? Dracula odwraca się w swojej trumnie. Ponadto tytuł brzmi jak nazwa emerytowanego zespołu gotycko-rockowego.
Renae Lider,

Odpowiedzi:

9

Klip , 69

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

Wkład: AB-

Wydajność: {{"AB+", "AB-"}, {"A-", "B-", "AB-", "O-"}}

Wyjaśnienie

Grupa krwi xmoże dać, yjeśli wszystkie xantygeny są zawarte w y. Program definiuje funkcję Fjako, czy xmoże dawać yi Tjako listę typów.

*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
źródło
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;}

Wyjaśnienie

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

Uruchom tutaj: http://repl.it/e98/1

Zauważ, że statictrzeba było dodać do każdej metody, aby wywołać je z metody głównej.

Ypnypn
źródło
2
Dodałem link do łatwego do uruchomienia programu. Edytuj parametr ciągu wewnątrz wywołania funkcji w metodzie głównej, aby zobaczyć wyjścia innych wejść.
mbomb007
5

Pyth, 61 59 50

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

Uruchom tutaj.

Wyjaśnienie:

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
źródło
@ user23013 Dziękujemy za edycję. To zdecydowanie powinno być kartezjańskie :)
orlp
4

CJam, 64 bajty

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

m*:sCzęść pochodzi od Marcina CJam odpowiedź . (Nie przeczytałem jeszcze innych części).

Nadal będą występować poważne problemy, ponieważ nigdy nie będą pewni kolejności dwóch list. I Block ArrayList &może być zaimplementowany w późniejszych wersjach CJam.

Wyjaśnienie

"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
źródło
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}

bez golfa:

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

funkcja testowania:

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

Kodowanie grupy krwi w postaci binarnej ma tę zaletę, że inny antygen (np. Antygen Kell ) można łatwo włączyć do kodu, po prostu dodając kolejny bit.


Oddaj krew w Zurychu, CH: Blutspende Zürich

Niklaus Messerli
źródło
Możesz użyć "O-O+B-B+A-A+AB-AB+".match(/\w+\W/g)zamiast "O- O+ B- B+ A- A+ AB- AB+".split(" ")zapisać 2 znaki.
Oriol,
Lub możesz zapisać dokładnie to samo, ustawiając separator na liczbę, "O-1O+1B-1B+1A-1A+1AB-1AB+".split(1)a użycie =>funkcji również powinno zaoszczędzić.
czerwony-X
Tak, ale @ Oriol można dodatkowo skrócić w wyrażeniu regularnym o 1 znak:/\w+./g
manatwork
Zawsze używaj dla (;;) zamiast while (). Przynajmniej taka sama długość, ale może być krótsza. n=2;while(n--)=>for(n=2;n--;)
edc65
W sumie bardzo sprytne. Można skrócić do 147 za pomocą standardowych sztuczek golfowych:http://jsfiddle.net/j2hep8e8/2/
edc65
2

CJam, 94 bajty

Wow, to jest długie ... chociaż myślę, że prawdopodobnie mógłbym grać w golfa przy podejściu poniżej 80, myślę, że lepiej by było, najpierw obliczając matrycę, a następnie wybierając właściwy wiersz i kolumnę. W każdym razie tutaj jest:

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

Sprawdź to tutaj.

Dodam wyjaśnienie, kiedy skończę grać w golfa.

Martin Ender
źródło
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)}]]}

Chodzi o to, aby zakodować współczynnik A, B i Rhesus po jednym bicie. Możemy następnie odwrócić bity, aby uzyskać wszystkie antygeny po stronie otrzymującej i użyć go do sprawdzenia, czy po stronie dawcy nie ma odpowiadających przeciwciał. Jest to mniej więcej to samo, co istniejące rozwiązanie JavaScript.

Przykładowe wykonanie

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̷̰̀ĥ̷̳
źródło
2

Prolog, 119 110 bajtów

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

Uwagi :

  1. Grupy krwi mają następujące właściwości: za każdym razem, gdy masz -(np. a-), Możesz dawać tym samym osobom, co ten, który ma dodatni ekwiwalent twojej grupy (np. a), A także ich negatywnemu odpowiednikowi (np. aDaje ab, więc a-daje abi ab-). Opierając się na tej właściwości i nieco nadużywając notacji, aby skorzystać z operatorów minus i plus, możemy uwzględnić wiele przypadków. Poinformuj mnie, jeśli uznasz to za dopuszczalne . Jeśli wolisz oryginalną składnię (postfiks), oto wersja bez gry w golfa:

    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. To jest Prolog, więc środowisko interaktywne pozwala zapytać o wszystko zgodnie z żądaniem (patrz przykład poniżej). To prawda, że ​​nie mamy list wyłącznie jako danych wyjściowych, ale jest to równoważne. W konsekwencji naturalnie zajmujemy się także przypadkami błędów.

Przykład

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.

Następnie wykonujemy 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)])

... która bez odpowiedniego formatowania jest taką samą matrycą jak ta podana w pytaniu.

Detale

Orzeczenie g/2to dać związki: g(X,Y)Środki ludzi krwi typu X mogą dać krwi ludzi krwi typu Y .

Znajdź odbiorniki dla grupy a:

[eclipse]: g(a,R).    

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

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

Znajdź odbiorniki dla orange_juice(powinien zawieść):

[eclipse] g(orange_juice,L).

No (0.00s cpu)

Znajdź dawców dla O-:

[eclipse] g(X,-o).

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

Kto może dać? :

[eclipse] g(X,Y).

.... 27 answers ....

Nie wchodzimy w nieskończoną pętlę rekurencyjną (tak było w testach wstępnych).

rdzeń rdzeniowy
źródło
1

Python, 187 bajtów

Odmienne podejście:

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]

Prawdopodobnie można go trochę pograć w golfa.

Test:

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

Wydajność:

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
źródło
1

Rubinowy, 237 232 223 221 210 207 bajtów

Naprawiono niektóre obce ukośniki odwrotne w wyrażeniach regularnych i sprawiło, że drukuje listy w przeciwieństwie do przechowywania ich w zmiennych, a następnie drukowania. Czasami brakuje ci oczywistych rzeczy podczas gry w golfa!

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

Nie golfowany:

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

Zasadniczo tworzę niestandardowe wyrażenie regularne dla wprowadzonej grupy krwi, aby sprawdzić, czy możesz przekazać darowiznę na inną grupę krwi. Następnie iteruję grupy krwi i stosuję wobec nich ten sam regex i sprawdzam, czy mogą przekazać darowiznę na rzecz określonego.

Prawdopodobnie można to jeszcze pograć w golfa. To jest moja pierwsza próba golfa kodowego, heh.

Mewy
źródło
1

Python 2, 168 bajtów

Jest to ta sama metoda, co odpowiedź Blackhole. Wychodzi z błędem, jeśli parametru nie ma na liście typów.

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]

Mniej golfa:

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

Uruchom tutaj: http://repl.it/eaB

Próbowałem też kilku innych drobnych zmian, ale nie mogłem tego skrócić ...

#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
źródło
1

PHP (287 bajtów):

Tak, to jest dość długie, ale działa zgodnie z oczekiwaniami.

Może być możliwe znaczne skrócenie:

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

Nie jest to łatwe do odczytania i nie było łatwe do napisania.

Działa zgodnie z przeznaczeniem, generując te, które możesz dać i te, które możesz otrzymać w innej linii.

Wymaga to parametru adresu URL T=z typem.

Ismael Miguel
źródło
1

CJam, 80 bajtów

To wciąż za długo. Prawdopodobnie mogę ogolić jeszcze 4 do 5 bajtów.

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

W przypadku każdego nieprawidłowego wejścia drukuje pustą tablicę lub zgłasza błąd.

Wypróbuj online tutaj lub uruchom cały pakiet testowy

Optymalizator
źródło
Czy XKCD na początku jest zamierzone?
Ypnypn,
@Ypnypn żebranie? Początkowo nie zamierzałem, ale tak się okazało. Może świat próbuje nam coś powiedzieć ...
Optymalizator
Przepraszam, miałem na myśli początek .
Ypnypn
1

APL, 66

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

Wypróbuj tutaj.

jimmy23013
źródło
Może to 66 znaków, ale zdecydowanie nie 66 bajtów. Pytanie nie mówi jednak, co było wykorzystywane do zdobywania punktów.
orlp
1
@orlp code-golf jest domyślnie oceniany w bajtach (patrz tag wiki ). Mówi się jednak, że istnieje strona kodowa APL, w której jeden znak to jeden bajt. Jednak nie wiem dokładnie, która strona kodowa APL jest obecnie używana.
jimmy23013
@orlp „bajty”, ale nie „UTF-8 bajtów”. Oto strona kodowa zawierająca wszystkie te znaki.
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(|)}

Gra w golfa pokazuje:

/* 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
źródło
1

PHP - 215 212 206 bajtów

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

Oto wersja bez golfa:

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

Dzięki manatwork do zapisywania 4 bajty.

Czarna dziura
źródło
Podział przez całkowitą sztuczka działa w PHP za: explode(1,'A+1O+1B+1AB+1A-1O-1B-1AB-'). A ponieważ niekoniecznie nadążamy za przyjemnymi nawykami kodowania, czasami używamy przestarzałych funkcji, takich jak split()funkcja.
manatwork
@manatwork Dobrze zauważony! Zredagowałem swoją odpowiedź, dzięki.
Blackhole
0

Perl, 107 112

Ostatecznie kodowanie nazw typów w liczbach dało krótszy kod.

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

Starsza wersja

#!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
źródło
0

Pyth, 58

Częściowo to samo, co rozwiązanie Orlp , ale nieco inne i całkowicie samodzielnie zaprojektowane.

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

Wyjaśnienie

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
źródło
0

J, 120 bajtów

   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- 

Funkcja zawodzi przy nieprawidłowych wejściach. Duża liczba dziesiętna to kodowanie macierzy pełnej zgodności.

(Bardzo długie rozwiązanie z wielu powodów.)

Wypróbuj online tutaj.

randomra
źródło