Vampir Uyumluluğu


28

Vampirlerle ilgili az bilinen bir gerçek, uyumlu bir donör kanı tipine sahip olan kurbanın kanını içmeleri gerektiğidir. Vampirler için uyumluluk matrisi, normal kırmızı kan hücresi verici / alıcı matrisi ile aynıdır . Bu, aşağıdaki Amerikan Kızıl Haç tablosu ile özetlenebilir.

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-

Meydan okuma

Giriş olarak kan grubunu alan ve iki liste çıktısı alan bir işlev veya program yazın:

  1. girdi türünden bağış alabilecek sıralanmamış tür listesi
  2. giriş türüne bağış verebilecek sıralanmamış tür listesi

Bir işlev yazarsanız, lütfen bu işlevi birkaç örnekle çağırmak için bir test programı da sağlayın, böylece kolayca test edebilirim. Bu durumda, test programı puanınıza sayılmaz.

Giriş

Girdi, 8 olası kırmızı kan hücresi tipinden tam olarak birini temsil eden bir dize olmalıdır O− O+ A− A+ B− B+ AB− AB+. Giriş normal yöntemlerle (STDIN, komut satırı argümanları, fonksiyon argümanları vb.) Verilebilir.

Başka bir giriş yapılırsa, program / fonksiyon boş çıktı döndürmeli veya bir hata atmalıdır. Normalde katı giriş kontrolü, sorularında pek iyi değildir, ancak kan kurallarının yanlış olmasının ölümle sonuçlanmasının bu kuralı eklemem gerektiğini düşündüğümü hissettim.

Çıktı

Çıktı, diliniz için uygun olan formatta, insan tarafından okunabilen iki kan grubu listesi olacaktır. Çıktı listesinden birinin 8 türün tümünü içerdiği özel durumlarda, bu liste isteğe bağlı olarak içeren tek bir öğe listesi ile değiştirilebilir everyone.

Normal çıkış normal yerlerden birine gider (STDOUT, fonksiyon dönüşü, vb.).

Diğer kurallar

  • Standart boşluklar yasaklandı
  • İhtiyacınız olan herhangi bir 3. parti kütüphaneyi, bu amaç için açıkça tasarlanmadıkça kullanabilirsiniz.

Örnekler

  • Giriş AB-için iki çıkış listesi şöyle olacaktır:{AB+, AB-}, {AB-, A-, B-, O-}
  • Giriş AB+için iki çıkış listesi şöyle olabilir: {AB+}, {O−, O+, A−, A+, B−, B+, AB−, AB+}veya{AB+}, {everyone}

Kişisel not: Mümkünse, lütfen kan bağışı yapmayı düşünün. Birkaç yıl önce aldığım transfüzyon olmadan bugün burada olamayabilirim, bu yüzden bağış yapabilenlere minnettarım!


@ MartinBüttner Aslında ikisini de kabul edeceğim. Büyük olasılıkla 2. form çoğu dilde daha kısa kod verir, ancak belki de ilk formun kullanılmasının daha kısa olabileceği bazı özel durumlar olabilir.
Dijital Travma

3
Teğetsel olarak ilişkili - bu mükemmel cevap worldbuilding.stackexchange.com/a/11203/2094
Digital Trauma


1
@leftaroundabout Teşekkürler - Bir parça Fry ve Laurie her zaman benim favorim olmuştur!
Dijital Travma

1
Seçici bir vampir, ha? Drakula tabutunda dönüyor. Ayrıca, başlık emekli bir goth-rock grubunun adı gibi geliyor.
Renae Lider

Yanıtlar:


9

Klips , 69

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

Giriş: AB-

Çıktı: {{"AB+", "AB-"}, {"A-", "B-", "AB-", "O-"}}

açıklama

Tüm antijenlerin dahil edilip edilmediğine bir kan grubu xverebilir . Program, işlevi verebilecek olup olmadığını ve türlerin listesini tanımlar .yxyFxyT

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

açıklama

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

Burada çalıştırın: http://repl.it/e98/1

staticBunları ana yöntemden çağırmak için her yönteme eklenmesi gerektiğini unutmayın .


2
Sizin için kolayca çalıştırılan bir programa bir link ekledim. Diğer girişlerin çıktılarını görmek için ana fonksiyondaki işlev çağrısının içindeki string parametresini düzenleyin.
mbomb007 19.03.2015

5

Pyth, 61 59 50

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

Burada çalıştır.

Açıklama:

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 Düzenleme için teşekkürler. Kesinlikle Kartezyen olmalıydı :)
or

4

CJam, 64 bayt

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

Bu m*:sbölüm Martin'in CJam'ın cevabından geliyor . (Diğer kısımları henüz okumadım.)

Hala ciddi problemler olacak çünkü iki listenin sırasından asla emin olamayacaklar. Ve Block ArrayList &CJam'ın sonraki sürümlerinde de uygulanabilir.

açıklama

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

Test işlevi:

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

Kan tipinin ikili olarak kodlanması, bir başka antijenin (örn., Kell antijeni ) sadece başka bir bit eklenerek koda kolayca dahil edilmesi avantajına sahiptir .


Zürih'te kan bağışı , CH: Blutspende Zürich


2 karakter kaydetmek "O-O+B-B+A-A+AB-AB+".match(/\w+\W/g)yerine kullanabilirsiniz "O- O+ B- B+ A- A+ AB- AB+".split(" ").
Oriol

Veya sınırlayıcıyı bir sayı yaparak aynı şekilde kaydedebilirsiniz "O-1O+1B-1B+1A-1A+1AB-1AB+".split(1)ve =>işlevini kullanarak da biraz kaydetmelisiniz.
kırmızı-X

Evet, fakat @ /\w+./g
Oriol'ler

Her zaman () yerine yerine (;;) kullanın. En azından aynı uzunlukta, ancak daha kısa olabilir. n=2;while(n--)=>for(n=2;n--;)
edc65

Sonuçta, çok zekice. Standart golf püf noktaları kullanılarak 147'ye kadar kısaltılabilir:http://jsfiddle.net/j2hep8e8/2/
edc65

2

CJam, 94 bayt

Vay canına, bu çok uzun ... sanırım 80'in altındaki bu yaklaşımı golf oynayabilirim, sanırım önce matrisi hesaplayarak ve sonra sadece doğru satır ve sütunu seçerek daha iyi yapabilirim. Neyse, işte burada:

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

Burada test et.

Golf bittiğinde bir açıklama ekleyeceğim.


2

Harika, 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)}]]}

Fikir A, B ve rhesus faktörünü her biri bir bit olarak kodlamaktır. Daha sonra tüm antijenleri alıcı tarafa almak için bitleri tersine çevirebilir ve veren tarafa karşılık gelen antikor olmadığını kontrol etmek için kullanabiliriz. Bu, mevcut JavaScript çözümüyle hemen hemen aynı.

Örnek yürütme

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 bayt

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

Açıklamalar :

  1. Kan tipleri aşağıdaki özelliklere sahiptir: -(örneğin a-) her zaman , grubunuza pozitif eşdeğeri (örn. a) İle negatif meslektaşı olan akişilere verebilirsiniz (örneğin ;ab , bu nedenle a-verir abve ab-). Bu özelliğe dayanarak ve eksi ve artı operatörlerini kullanmak için gösterimleri biraz kötüye kullanma, birçok durumu etkileyebilir. Lütfen kabul edilebilir bulursan bana söyle . Orijinal (postfix) sözdizimine sahip olmayı tercih ediyorsanız, işte golfsüz bir sürüm:

    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. Bu Prolog'dur, bu nedenle etkileşimli ortam her şeyi istendiği gibi sorgulamaya izin verir (aşağıdaki örneğe bakın). Verilmiş, kesinlikle bir çıktı olarak listelerimiz yok, ancak bu eşdeğerdir. Sonuç olarak, doğal olarak hata durumlarını da ele alıyoruz.

Örnek

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.

Sonra yürütürüz 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)])

... uygun formatlama olmadan, soruda verilenle aynı matris.

ayrıntılar

Yüklem g/2olduğu vermek ilişkisi: g(X,Y)araçları kan grubu X'in insan kan grubu Y kişiye kan verebilir .

Grup için alıcı bul a :

[eclipse]: g(a,R).    

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

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

İçin alıcı bul orange_juice (başarısız olmalı):

[eclipse] g(orange_juice,L).

No (0.00s cpu)

İçin bağış bul O- :

[eclipse] g(X,-o).

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

Kim ne verebilir? :

[eclipse] g(X,Y).

.... 27 answers ....

Sonsuz bir özyinelemeye girmiyoruz (ön testlerde böyleydi).


1

Python, 187 bayt

Farklı yaklaşım:

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]

Muhtemelen biraz daha golf oynayabilir.

Ölçek:

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

Çıktı:

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 bayt

Düzenli ifadelerdeki bazı gereksiz ters eğik çizgiler düzeltildi ve değişkenlerin saklanmasına ve ardından yazdırılmasına karşılık sadece listelerin yazdırılmasını sağladı. Bazen golf oynamaya çalışırken belli şeyleri özlüyorsunuz!

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;

Temel olarak, başka bir kan grubuna bağış yapıp yapamayacağınızı kontrol etmek için girilen kan grubu için özel bir düzenli ifade yapıyorum. Daha sonra kan gruplarında tekrarlanır ve aynı regex'i kendilerine uygular ve belirtilenlere bağış yapıp yapmadıklarını kontrol ederim.

Bu muhtemelen daha da aşağı golf olabilir. Bu benim ilk kez kod golf denemem, heh.


1

Python 2, 168 bayt

Bu, Blackhole'un cevabıyla aynı yöntemdir. Parametre tip listesinde bulunmazsa, hata ile çıkar.

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]

Daha az golf oynadı:

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

Burada çalıştır: http://repl.it/eaB

Ayrıca birkaç küçük değişiklik yaptım ama daha kısa süremedim ...

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

Evet, bu çok uzun, ama beklendiği gibi çalışıyor.

Çok kısaltmak mümkün olabilir:

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

Bunu okumak kolay değil ve yazmak kolay değildi.

Amaçlandığı gibi çalışabilir, verebileceklerinizi ve aldıklarınızı başka bir hatta alabilirsiniz.

Bu T=tür ile bir URL parametresi gerektirir .


1

CJam, 80 bayt

Bu hala çok uzun. Muhtemelen 4 ila 5 bayt daha fazla tıraş yapabilirim.

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

Herhangi bir geçersiz giriş için ya boş bir dizi yazdırır ya da bir hata atar.

Burada çevrimiçi deneyin veya tüm test paketini çalıştırın


XKCD'nin dilencilikte olması planlanıyor mu?
Ypnypn

@Ypnypn yalvarıyor mu? Başlangıçta niyetinde değildim, ama böyle çıktı. Belki dünya bize bir şeyler anlatmaya çalışıyor ...
Doktor

Üzgünüm, başlamak istedim .
Ypnypn

1

APL, 66

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

Burada dene.


Belki bu 66 karakterdir, ama kesinlikle 66 byte değildir. Soru, gerçekte neyin kullanıldığını söylemiyor.
or Marp

1
@orlp code-golf varsayılan olarak bayt cinsinden puanlanır ( wiki etiketine bakın ). Ancak, bir karakterin bir bayt olduğu bir APL kod sayfası olduğu söylenir. Ancak bugünlerde hangi APL kod sayfasının kullanıldığını tam olarak bilmiyorum.
jimmy23013 20.05.2015

@orlp "bayt", ancak "UTF-8 bayt" değil. İşte tüm bu karakterleri içeren bir kod sayfası .
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 gösterir:

/* 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 bayt

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

İşte ungolfed versiyonu:

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

4 byte tasarruf için manatwork sayesinde .


Tamsayı numarayla bölünmüş çok PHP çalışır: explode(1,'A+1O+1B+1AB+1A-1O-1B-1AB-'). Ve zorunlu olarak güzel kodlama alışkanlıklarına uymadığımız için, bazen split()işlev gibi kullanım dışı özellikleri kullanırız .
Manatwork

@ manatwork İyi lekeli! Cevabımı düzelttim, teşekkürler.
Karadelik

0

Perl, 107 112

Sonunda türlerdeki sayıları sayı olarak kodlamak daha kısa kod verdi.

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

Eski versiyon

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

Orlp en olarak Kısmen aynı çözümü , ancak biraz farklı ve tamamen bağımsız olarak tasarlanmış.

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

açıklama

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 bayt

   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- 

İşlev geçersiz girişlerde başarısız olur. Büyük ondalık sayı, tam uyumluluk matrisinin kodlamasıdır.

(Birden fazla nedenden dolayı çok uzun bir çözüm.)

Burada çevrimiçi deneyin.


Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.