Kompatibilitas Vampir


28

Fakta kecil yang diketahui tentang vampir adalah bahwa mereka harus meminum darah korban yang memiliki golongan darah donor yang kompatibel. Matriks kompatibilitas untuk vampir sama dengan matriks donor / penerima sel darah merah biasa . Ini dapat diringkas oleh tabel Palang Merah Amerika berikut ini

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-

Tantangan

Tulis fungsi atau program yang menggunakan golongan darah sebagai input dan menghasilkan dua daftar:

  1. daftar tipe yang tidak terurut yang dapat menerima donasi dari tipe input
  2. daftar tipe yang tidak berurutan yang dapat memberikan donasi pada tipe input

Jika Anda menulis suatu fungsi, maka tolong berikan juga program uji untuk memanggil fungsi itu dengan beberapa contoh, jadi saya dapat dengan mudah mengujinya. Dalam hal ini, program pengujian tidak akan menghitung skor Anda.

Memasukkan

Input harus berupa string yang mewakili tepat satu dari 8 jenis sel darah merah yang mungkin O− O+ A− A+ B− B+ AB− AB+. Input dapat diberikan melalui metode normal (STDIN, arg baris perintah, argumen fungsi, dll).

Jika ada input lain yang diberikan maka program / fungsi harus mengembalikan output kosong atau melemparkan kesalahan. Biasanya pengecekan input yang ketat tidak bagus dalam pertanyaan , tapi saya merasa diberi implikasi hidup-mati karena salah golongan darah sehingga saya harus menambahkan aturan ini.

Keluaran

Keluaran akan berupa dua daftar golongan darah yang dapat dibaca manusia dalam format apa pun yang sesuai untuk bahasa Anda. Dalam kasus khusus di mana salah satu daftar output berisi semua 8 jenis, daftar ini secara opsional dapat diganti dengan satu daftar item yang mengandung everyone.

Output normal akan pergi ke salah satu tempat normal (STDOUT, pengembalian fungsi, dll).

Aturan lainnya

  • Celah standar dilarang
  • Anda dapat menggunakan pustaka pihak ke-3 apa pun yang sudah ada sebelumnya yang Anda butuhkan, asalkan tidak dirancang secara eksplisit untuk tujuan ini.

Contohnya

  • Untuk input AB-, dua daftar keluaran adalah:{AB+, AB-}, {AB-, A-, B-, O-}
  • Untuk input AB+, dua daftar keluaran adalah: {AB+}, {O−, O+, A−, A+, B−, B+, AB−, AB+}atau{AB+}, {everyone}

Catatan pribadi: Silakan pertimbangkan untuk mendonorkan darah jika Anda mampu. Tanpa transfusi yang saya terima beberapa tahun yang lalu, saya mungkin tidak ada di sini hari ini, jadi saya merasa sangat berterima kasih kepada mereka yang mampu menyumbang!


@ MartinBüttner Sebenarnya saya akan menerima keduanya. Kemungkinan bentuk kedua akan menghasilkan kode yang lebih pendek di sebagian besar bahasa, tetapi mungkin akan ada beberapa kasus khusus di mana penggunaan formulir pertama bisa lebih pendek.
Digital Trauma

3
Terkait secara tangensial - jawaban yang brilian ini worldbuilding.stackexchange.com/a/11203/2094
Digital Trauma


1
@leftaroundabout Terima kasih - Sedikit Fry dan Laurie selalu menjadi favorit saya!
Digital Trauma

1
Vampir pemilih, eh? Dracula membalikkan petinya. Juga, judulnya terdengar seperti nama pensiunan goth-rock-band.
Renae Lider

Jawaban:


9

Klip , 69

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

Memasukkan: AB-

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

Penjelasan

Golongan darah xdapat diberikan yjika semua xantigen termasuk dalam y. Program mendefinisikan fungsi Fsebagai apakah xdapat memberi y, dan Tsebagai daftar jenis.

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

Penjelasan

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

Jalankan di sini: http://repl.it/e98/1

Catatan yang staticharus ditambahkan ke setiap metode untuk memanggil mereka dari metode utama.


2
Saya menambahkan tautan ke program yang mudah dijalankan untuk Anda. Edit parameter string di dalam pemanggilan fungsi pada metode utama untuk melihat output input lainnya.
mbomb007

5

Pyth, 61 59 50

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

Jalankan di sini.

Penjelasan:

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 Terima kasih atas hasil editnya. Seharusnya Cartesian :)
orlp

4

CJam, 64 byte

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

Bagian itu m*:sberasal dari jawaban CJam Martin . (Saya belum membaca bagian lain.)

Masih akan ada beberapa masalah serius karena mereka tidak akan pernah yakin tentang urutan kedua daftar tersebut. Dan Block ArrayList &mungkin diimplementasikan dalam versi CJam nanti.

Penjelasan

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

fungsi pengujian:

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

Pengkodean golongan darah dalam biner memiliki keuntungan bahwa antigen lain (mis. Antigen Kell ) mudah dimasukkan ke dalam kode hanya dengan menambahkan bit lain.


Donasi darah di Zurich, CH: Blutspende Zürich


Anda dapat menggunakan "O-O+B-B+A-A+AB-AB+".match(/\w+\W/g)alih-alih "O- O+ B- B+ A- A+ AB- AB+".split(" ")menyimpan 2 karakter.
Oriol

Atau Anda dapat menyimpan persis sama dengan membuat pembatas nomor "O-1O+1B-1B+1A-1A+1AB-1AB+".split(1)dan menggunakan =>fungsi juga harus menyimpan beberapa.
red-X

Ya, tetapi @ Oriol dapat lebih pendek dalam ekspresi reguler dengan 1 karakter:/\w+./g
manatwork

Selalu gunakan untuk (;;) alih-alih sementara (). Setidaknya panjang yang sama, tetapi bisa lebih pendek. n=2;while(n--)=>for(n=2;n--;)
edc65

Secara keseluruhan, sangat pintar. Dapat disingkat menjadi 147 menggunakan trik golf standar:http://jsfiddle.net/j2hep8e8/2/
edc65

2

CJam, 94 byte

Wow, ini panjang ... sementara saya pikir saya mungkin bisa golf pendekatan ini di bawah 80, saya pikir saya mungkin telah melakukan lebih baik dengan pertama menghitung matriks dan kemudian hanya memilih baris dan kolom yang benar. Bagaimanapun, ini dia:

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

Uji di sini.

Saya akan menambahkan penjelasan ketika saya selesai bermain 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)}]]}

Idenya adalah untuk mengkodekan faktor A, B dan rhesus masing-masing satu bit. Kami kemudian dapat membalikkan bit untuk mendapatkan semua antigen pada sisi penerima dan menggunakannya untuk memeriksa bahwa tidak ada antibodi yang sesuai pada sisi pemberian. Ini kurang lebih sama dengan solusi JavaScript yang ada.

Eksekusi sampel

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

Komentar :

  1. Golongan darah memiliki sifat-sifat berikut: setiap kali Anda memiliki -(misalnya a-), Anda dapat memberikan kepada orang yang sama dengan orang yang memiliki setara positif dengan kelompok Anda (misalnya a), serta rekan negatif mereka (misalnya amemberi ab, jadi a-memberi kepada abdan ab-). Berdasarkan pada properti ini, dan sedikit menyalahgunakan notasi untuk menggunakan operator minus dan plus, kami dapat memfaktorkan banyak kasus. Tolong beritahu saya jika Anda menemukannya dapat diterima . Jika Anda lebih suka memiliki sintaks (postfix) asli, berikut ini adalah versi non-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. Ini adalah Prolog, sehingga lingkungan interaktif memungkinkan untuk menanyakan segala sesuatu seperti yang diminta (lihat contoh di bawah). Memang, kami tidak memiliki daftar ketat sebagai output, tetapi ini setara. Kami juga secara alami menangani kasus kesalahan sebagai konsekuensinya.

Contoh

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.

Lalu, kita jalankan 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)])

... yang, tanpa pemformatan yang tepat, adalah matriks yang sama dengan yang diberikan dalam pertanyaan.

Detail

Predikat g/2adalah memberi hubungan: g(X,Y)berarti orang dari golongan darah X dapat memberikan darah kepada orang-orang dari golongan darah Y .

Temukan penerima untuk grup a:

[eclipse]: g(a,R).    

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

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

Temukan penerima untuk orange_juice(harus gagal):

[eclipse] g(orange_juice,L).

No (0.00s cpu)

Temukan donor untuk O-:

[eclipse] g(X,-o).

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

Siapa yang bisa memberi apa? :

[eclipse] g(X,Y).

.... 27 answers ....

Kami tidak masuk ke loop rekursi tak terbatas (itu terjadi dalam tes pendahuluan).


1

Python, 187 byte

Pendekatan yang berbeda:

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]

Mungkin bisa bermain golf lebih banyak.

Uji:

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

Keluaran:

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

Ruby, 237 232 223 221 210 207 byte

Memperbaiki beberapa garis miring terbalik di ekspresi reguler dan membuatnya jadi hanya mencetak daftar yang bertentangan dengan menyimpannya ke variabel dan kemudian mencetaknya. Terkadang Anda melewatkan hal-hal yang jelas ketika mencoba bermain 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)}

Tidak Disatukan:

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

Pada dasarnya, saya membuat ekspresi reguler khusus untuk jenis darah yang dimasukkan untuk memeriksa apakah Anda dapat menyumbang ke jenis darah lain. Saya kemudian beralih melalui golongan darah dan menerapkan regex yang sama untuk mereka dan memeriksa apakah mereka dapat menyumbang ke yang ditentukan.

Ini mungkin bisa diturunkan lebih banyak lagi. Ini pertama kalinya saya mencoba kode golf, heh.


1

Python 2, 168 byte

Ini adalah metode yang sama dengan jawaban Blackhole. Keluar dengan kesalahan jika parameter tidak ditemukan dalam daftar tipe.

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]

Kurang bermain 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

Jalankan di sini: http://repl.it/eaB

Saya juga mencoba beberapa perubahan kecil lainnya, tetapi tidak bisa lebih pendek ...

#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 bytes):

Ya, ini cukup panjang, tetapi berfungsi seperti yang diharapkan.

Dimungkinkan untuk mempersingkat banyak:

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

Ini tidak mudah dibaca dan tidak mudah untuk ditulis.

Ini berfungsi sebagaimana mestinya, menghasilkan yang dapat Anda berikan dan yang Anda dapat terima dari pada baris lain.

Ini membutuhkan parameter URL T=dengan jenisnya.


1

CJam, 80 byte

Ini masih terlalu lama. Mungkin saya bisa mengurangi 4 hingga 5 byte lebih banyak.

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

Untuk input yang tidak valid, mencetak array kosong, atau melempar kesalahan.

Cobalah online di sini atau jalankan seluruh test suite


Apakah XKCD dalam permintaan itu dimaksudkan?
Ypnypn

@Ypnypn memohon? Awalnya saya tidak berniat, tapi ternyata seperti itu. Mungkin dunia mencoba memberi tahu kami sesuatu ...
Pengoptimal

Maaf, maksud saya awal .
Ypnypn

1

APL, 66

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

Coba di sini.


Mungkin itu 66 karakter, tapi jelas bukan 66 byte. Pertanyaannya tidak mengatakan apa yang digunakan untuk mencetak skor.
orlp

1
@atau kode-golf dinilai dalam byte secara default (lihat tag wiki ). Tetapi dikatakan ada halaman kode APL di mana satu karakter adalah satu byte. Saya tidak tahu persis halaman kode APL mana yang digunakan saat ini.
jimmy23013

@ orlp "byte", tetapi bukan "UTF-8 byte". Ini adalah halaman kode yang berisi semua karakter ini.
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 itu menunjukkan:

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

Ini adalah versi yang tidak dikoleksi:

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

Berkat manatwork karena telah menghemat 4 byte.


Perpecahan dengan trik bilangan bulat bekerja di PHP juga: explode(1,'A+1O+1B+1AB+1A-1O-1B-1AB-'). Dan karena kita tidak selalu mengikuti kebiasaan pengkodean yang bagus, kadang-kadang kita menggunakan fitur yang sudah usang, seperti split()fungsinya.
manatwork

@manatwork Terlihat dengan baik! Saya sudah mengedit jawaban saya, terima kasih.
Lubang Hitam

0

Perl, 107 112

Akhirnya, pengkodean nama tipe dalam angka memberi kode yang lebih pendek.

#!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 yang lebih lama

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

Sebagian sama dengan solusi orlp , tetapi agak berbeda dan sepenuhnya dirancang sendiri.

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

Penjelasan

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- 

Fungsi gagal pada input yang tidak valid. Angka desimal besar adalah penyandian dari matriks kompatibilitas penuh.

(Solusi yang sangat panjang karena berbagai alasan.)

Cobalah online di sini.


Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.