Compatibilità con i vampiri


28

Un fatto poco noto sui vampiri è che devono bere il sangue della vittima che ha un gruppo sanguigno donatore compatibile. La matrice di compatibilità per i vampiri è la stessa della normale matrice donatore / ricevente dei globuli rossi . Questo può essere riassunto dalla seguente tabella della Croce Rossa 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-

Sfida

Scrivi una funzione o un programma che prende un gruppo sanguigno come input e genera due elenchi:

  1. l'elenco non ordinato di tipi che possono ricevere donazioni del tipo di input
  2. l'elenco non ordinato di tipi che possono offrire donazioni al tipo di input

Se scrivi una funzione, ti preghiamo di fornire anche un programma di test per chiamare quella funzione con alcuni esempi, così posso facilmente provarla. In questo caso, il programma di test non conta ai fini del punteggio.

Ingresso

L'input deve essere una stringa che rappresenta esattamente uno degli 8 possibili tipi di globuli rossi O− O+ A− A+ B− B+ AB− AB+. L'input può essere fornito tramite i metodi normali (STDIN, arg della riga di comando, arg della funzione, ecc.).

Se viene fornito qualsiasi altro input, il programma / funzione deve restituire output vuoto o generare un errore. Normalmente un rigoroso controllo degli input non è eccezionale nelle domande sul , ma mi sono sentito dato le implicazioni di morte e morte di sbagliare i gruppi sanguigni che avrei dovuto aggiungere questa regola.

Produzione

L'output sarà costituito da due elenchi leggibili dall'uomo di gruppi sanguigni in qualsiasi formato adatto alla tua lingua. Nei casi speciali in cui uno dell'elenco di output contiene tutti e 8 i tipi, questo elenco può facoltativamente essere sostituito con un singolo elenco di elementi contenente everyone.

L'uscita normale andrà in uno dei posti normali (STDOUT, ritorno funzione, ecc.).

Altre regole

  • Le scappatoie standard sono vietate
  • Puoi utilizzare qualsiasi libreria di terze parti preesistente di cui hai bisogno, a condizione che non siano progettate esplicitamente per questo scopo.

Esempi

  • Per l'input AB-, i due elenchi di output sarebbero:{AB+, AB-}, {AB-, A-, B-, O-}
  • Per l'input AB+, i due elenchi di output sarebbero: {AB+}, {O−, O+, A−, A+, B−, B+, AB−, AB+}o{AB+}, {everyone}

Nota personale: si prega di considerare la donazione di sangue se si è in grado di farlo. Senza la trasfusione che ho ricevuto qualche anno fa, potrei non essere qui oggi, quindi sono molto grato a coloro che sono in grado di donare!


@ MartinBüttner In realtà accetterò entrambi. Molto probabilmente il secondo modulo produrrà un codice più breve nella maggior parte delle lingue, ma forse ci sarà un caso speciale in cui l'utilizzo del primo modulo potrebbe essere più breve.
Trauma digitale

3
Tangenzialmente correlato: questa brillante risposta worldbuilding.stackexchange.com/a/11203/2094
Digital Trauma


1
@leftaroundabout Grazie - Un po 'di fritti e Laurie sono sempre stati i miei preferiti!
Trauma digitale

1
Un vampiro esigente, eh? Dracula si sta girando nella sua bara. Inoltre, il titolo suona come il nome di una band goth-rock in pensione.
Renae Lider,

Risposte:


9

Clip , 69

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

Ingresso: AB-

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

Spiegazione

Un gruppo sanguigno xpuò dare yse tutti xgli antigeni sono inclusi in y. Il programma definisce la funzione Fcome se xpuò dare a y, e Tcome l'elenco dei tipi.

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

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

Spiegazione

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

Eseguilo qui: http://repl.it/e98/1

Si noti che è staticstato necessario aggiungere ogni metodo per chiamarli dal metodo principale.


2
Ho aggiunto un collegamento a un programma di facile esecuzione per te. Modificare il parametro stringa all'interno della chiamata di funzione nel metodo principale per visualizzare gli output degli altri ingressi.
mbomb007,

5

Pyth, 61 59 50

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

Eseguilo qui.

Spiegazione:

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

@ user23013 Grazie per la modifica. Avrebbe sicuramente dovuto essere cartesiano :)
orlp

4

CJam, 64 byte

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

La m*:sparte viene dalla risposta CJam di Martin . (Non ho ancora letto le altre parti.)

Ci saranno ancora alcuni problemi seri perché non saranno mai sicuri dell'ordine delle due liste. E Block ArrayList &potrebbe essere implementato nelle versioni successive di CJam.

Spiegazione

"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. ";
}/

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}

ungolfed:

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

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

La codifica del gruppo sanguigno in binario ha il vantaggio che un altro antigene (ad esempio l' antigene di Kell ) viene facilmente incorporato nel codice semplicemente aggiungendo un altro bit.


Dona sangue a Zurigo, CH: Blutspende Zürich


Puoi usare "O-O+B-B+A-A+AB-AB+".match(/\w+\W/g)invece di "O- O+ B- B+ A- A+ AB- AB+".split(" ")salvare 2 caratteri.
Oriol

Oppure puoi salvare esattamente lo stesso facendo delimitatore un numero "O-1O+1B-1B+1A-1A+1AB-1AB+".split(1)e usando la =>funzione dovresti salvare anche alcuni.
rosso-X

Sì, ma @ Oriol può essere ulteriormente abbreviato nell'espressione regolare di 1 carattere:/\w+./g
manat

Utilizzare sempre per (;;) invece di while (). Almeno la stessa lunghezza, ma può essere più breve. n=2;while(n--)=>for(n=2;n--;)
edc65,

Tutto sommato, molto intelligente. Può essere accorciato a 147 usando trucchi golf standard:http://jsfiddle.net/j2hep8e8/2/
edc65

2

CJam, 94 byte

Wow, questo è lungo ... mentre penso che probabilmente potrei giocare a golf con questo approccio al di sotto degli 80, penso che avrei potuto fare meglio prima calcolando la matrice e poi semplicemente selezionando la riga e la colonna corrette. Ad ogni modo, eccolo qui:

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

Provalo qui.

Aggiungerò una spiegazione quando avrò finito di giocare a golf.


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'idea è di codificare A, B e il fattore rhesus come un bit ciascuno. Possiamo quindi invertire i bit per ottenere tutti gli antigeni sul lato ricevente e usarlo per verificare che non vi siano anticorpi corrispondenti sul lato ricevente. Questo è più o meno lo stesso della soluzione JavaScript esistente.

Esecuzione del campione

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-]]
[]

2

Prolog, 119 110 byte

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

Osservazioni :

  1. I gruppi sanguigni hanno le seguenti proprietà: ogni volta che hai un -(ad esempio a-), puoi dare alle stesse persone di chi ha un equivalente positivo del tuo gruppo (ad esempio a), così come la loro controparte negativa (ad esempio adà a ab, quindi a-dà a abe ab-). Sulla base di questa proprietà e abusando un po 'delle notazioni per utilizzare gli operatori meno e più, possiamo considerare molti casi. Per favore dimmi se lo trovi accettabile . Se preferisci avere la sintassi originale (postfisso), ecco una versione non golfata:

    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. Questo è Prolog, quindi l'ambiente interattivo consente di interrogare tutto come richiesto (vedi esempio sotto). Certo, non abbiamo elenchi rigorosamente come output, ma questo è equivalente. Di conseguenza, gestiamo naturalmente anche casi di errore.

Esempio

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.

Quindi eseguiamo 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)])

... che, senza una corretta formattazione, è la stessa matrice di quella indicata nella domanda.

Dettagli

Il predicato g/2è il dare rapporto: g(X,Y)mezzi persone di sangue di tipo X possono donare il sangue a persone di sangue di tipo Y .

Trova i ricevitori per il gruppo a:

[eclipse]: g(a,R).    

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

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

Trova i ricevitori per orange_juice(dovrebbe fallire):

[eclipse] g(orange_juice,L).

No (0.00s cpu)

Trova donatori per O-:

[eclipse] g(X,-o).

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

Chi può dare cosa? :

[eclipse] g(X,Y).

.... 27 answers ....

Non entriamo in un ciclo di ricorsione infinito (era il caso dei test preliminari).


1

Python, 187 byte

Approccio diverso:

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]

Probabilmente si può giocare a golf un po 'di più.

Test:

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

Produzione:

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

1

Rubino, 237 232 223 221 210 207 byte

Risolti alcuni backslash estranei nelle espressioni regolari e fatti in modo che stampasse gli elenchi invece di memorizzarli in variabili e quindi stamparli. A volte ti mancano le cose ovvie quando cerchi di giocare a 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)}

Ungolfed:

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

Fondamentalmente, costruisco un'espressione regolare personalizzata per il gruppo sanguigno inserito per verificare se è possibile effettuare una donazione a un altro gruppo sanguigno. Quindi eseguo l'iterazione attraverso i gruppi sanguigni e applico la stessa regex a loro e controllo se possono donare a quello specificato.

Probabilmente questo può essere ulteriormente ridotto. Questa è la prima volta che cerco il codice golf, eh.


1

Python 2, 168 byte

Questo è lo stesso metodo della risposta di Blackhole. Esce con un errore se il parametro non viene trovato nell'elenco dei tipi.

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]

Meno 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

Eseguilo qui: http://repl.it/eaB

Ho anche provato un paio di altre lievi modifiche, ma non sono riuscito a farlo più breve ...

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

1

PHP (287 byte):

Sì, questo è piuttosto lungo, ma funziona come previsto.

Potrebbe essere possibile abbreviare molto:

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

Non è facile da leggere e non è facile da scrivere.

Funziona come previsto, producendo quelli a cui puoi dare e quelli da cui puoi ricevere su un'altra linea.

Ciò richiede un parametro URL T=con il tipo.


1

CJam, 80 byte

Questo è ancora troppo lungo. Probabilmente riesco a radere da 4 a 5 byte in più.

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

Per qualsiasi input non valido, stampa un array vuoto o genera un errore.

Provalo online qui o esegui l'intera suite di test


XKCD nell'accattonaggio è previsto?
Ypnypn,

@Ypnypn elemosinando? Inizialmente non avevo intenzione di farlo, ma si è rivelato così. Forse il mondo sta cercando di dirci qualcosa ...
Ottimizzatore

Scusa, intendevo iniziare .
Ypnypn,

1

APL, 66

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

Provalo qui.


Forse sono 66 caratteri, ma sicuramente non 66 byte. La domanda non dice che cosa è usato per segnare però.
orlp

1
Per impostazione predefinita, @orlp code-golf è segnato in byte (vedere il tag wiki ). Ma si dice che esiste una tabella codici APL in cui un carattere è un byte. Tuttavia, non so esattamente quale codepage APL sia utilizzata al giorno d'oggi.
jimmy23013,

@orlp "byte", ma non "UTF-8 byte". Ecco una tabella di codici contenente tutti questi caratteri.
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 mostra:

/* 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(|)
}

1

PHP - 215 212 206 byte

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

Ecco la versione ungolfed:

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

Grazie a manatwork per il salvataggio di 4 byte.


La suddivisione per intero trucco funziona in PHP troppo: explode(1,'A+1O+1B+1AB+1A-1O-1B-1AB-'). E poiché non necessariamente ci teniamo al passo con le buone abitudini di programmazione, a volte utilizziamo funzionalità obsolete, come la split()funzione.
arte

@manatwork Ben individuato! Ho modificato la mia risposta, grazie.
Blackhole,

0

Perl, 107 112

Alla fine codificare i nomi dei tipi in numeri ha dato il codice più breve.

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

Versione precedente

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

0

Pyth, 58

In parte uguale alla soluzione di orlp , ma in qualche modo diversa e completamente auto-progettata.

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

Spiegazione

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)

0

J, 120 byte

   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 funzione ha esito negativo su input non validi. Il grande numero decimale è la codifica della matrice di piena compatibilità.

(Soluzione molto lunga per molteplici motivi.)

Provalo online qui.


Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.