Совместимость с вампирами

28

Малоизвестный факт о вампирах заключается в том, что они должны пить кровь жертвы, имеющей совместимую группу донорской крови. Матрица совместимости для вампиров такая же, как и матрица обычных доноров / реципиентов эритроцитов . Это можно суммировать с помощью следующей таблицы Американского Красного Креста.

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-

Вызов

Напишите функцию или программу, которая принимает группу крови в качестве входных данных и выводит два списка:

  1. неупорядоченный список типов, которые могут получить пожертвование типа ввода
  2. неупорядоченный список типов, которые могут дать пожертвование типу ввода

Если вы пишете функцию, то, пожалуйста, также предоставьте тестовую программу для вызова этой функции с несколькими примерами, чтобы я мог легко ее протестировать. В этом случае тестовая программа не будет засчитана в ваш счет.

вход

Входными данными должна быть строка, представляющая ровно один из 8 возможных типов эритроцитов O− O+ A− A+ B− B+ AB− AB+. Входные данные могут быть переданы с помощью обычных методов (STDIN, аргументы командной строки, аргументы функций и т. Д.).

Если задан какой-либо другой ввод, то программа / функция должна вернуть пустой вывод или выдать ошибку. Обычно строгая проверка ввода не очень вопросах , но я чувствовал, что с учетом последствий для жизни и смерти из-за неправильного определения группы крови я должен добавить это правило.

Выход

Результатом будет два читаемых человеком списка групп крови в любом формате, который подходит для вашего языка. В особых случаях, когда один из списка вывода содержит все 8 типов, этот список может быть необязательно заменен одним списком элементов, содержащим everyone.

Нормальный вывод будет идти в одно из нормальных мест (STDOUT, возврат функции и т. Д.).

Другие правила

  • Стандартные лазейки запрещены
  • Вы можете использовать любые существующие сторонние библиотеки, которые вам нужны, если они не предназначены для этой цели.

Примеры

  • Для ввода AB-два списка вывода будут:{AB+, AB-}, {AB-, A-, B-, O-}
  • Для ввода AB+два списка вывода будут: {AB+}, {O−, O+, A−, A+, B−, B+, AB−, AB+}или{AB+}, {everyone}

Личное примечание: пожалуйста, рассмотрите возможность сдачи крови, если вы можете. Без переливания, которое я получил несколько лет назад, я мог бы не быть здесь сегодня, поэтому я очень благодарен тем, кто может сделать пожертвование!

Цифровая травма
источник
@ MartinBüttner На самом деле я приму оба. Скорее всего, вторая форма даст более короткий код на большинстве языков, но, возможно, будет особый случай, когда использование первой формы может быть короче.
Цифровая травма
3
Тангенциально связанный - этот блестящий ответ worldbuilding.stackexchange.com/a/11203/2094
Цифровая травма
1
Этот факт не так малоизвестен .
перестал поворачивать против часовой стрелки
1
@leftaroundabout Спасибо - немного Фрая и Лори всегда была моей любимой!
Цифровая травма
1
Придирчивый вампир, а? Дракула поворачивается в своей шкатулке. Кроме того, название звучит как название отставной готик-рок-группы.
Рене Лидер

Ответы:

9

Клип , 69

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

Входные данные: AB-

Выход: {{"AB+", "AB-"}, {"A-", "B-", "AB-", "O-"}}

объяснение

Группу крови xможно определить, yесли в xнее включены все антигены y. Программа определяет функцию, Fкак xможет ли дать y, и Tкак список типов.

*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
источник
6

Ява 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;}

объяснение

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

Запустите его здесь: http://repl.it/e98/1

Обратите внимание, что staticнужно было добавить к каждому методу, чтобы вызвать их из основного метода.

Ypnypn
источник
2
Я добавил ссылку на легко запускаемую программу для вас. Отредактируйте строковый параметр внутри вызова функции в методе main, чтобы увидеть выходы других входов.
mbomb007
5

Пиф, 61 59 50

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

Запустите это здесь.

Объяснение:

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
источник
@ user23013 Спасибо за редактирование. Это определенно должно было быть декартово :)
orlp
4

CJam, 64 байта

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

m*:sЧасть приходит из CJam ответа Мартина . (Я еще не читал другие части.)

Будут все еще некоторые серьезные проблемы, потому что они никогда не будут уверены в порядке двух списков. И Block ArrayList &может быть реализовано в более поздних версиях CJam.

объяснение

"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
источник
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;
}

функция тестирования:

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

Кодирование группы крови в двоичном виде имеет то преимущество, что другой антиген (например, антиген Келла ) легко включается в код, просто добавляя еще один бит.


Сдайте кровь в Цюрихе, CH: Blutspende Zürich

Никлаус Мессерли
источник
Вы можете использовать "O-O+B-B+A-A+AB-AB+".match(/\w+\W/g)вместо того, "O- O+ B- B+ A- A+ AB- AB+".split(" ")чтобы сохранить 2 символа.
Oriol
Или вы можете сохранить точно так же, сделав число разделителем, "O-1O+1B-1B+1A-1A+1AB-1AB+".split(1)и использование =>функции должно сохранить некоторые тоже.
red-X
Да, но @ Oriol's можно еще сократить в регулярном выражении на 1 символ:/\w+./g
manatwork
Всегда используйте for (;;) вместо while (). По крайней мере, такой же длины, но может быть короче. n=2;while(n--)=>for(n=2;n--;)
edc65
В общем, очень умно. Можно сократить до 147 с помощью стандартных гольф-трюков:http://jsfiddle.net/j2hep8e8/2/
edc65
2

CJam, 94 байта

Ничего себе, это долго ... хотя я думаю, что я мог бы, вероятно, использовать этот подход ниже 80, я думаю, что я мог бы добиться большего, сначала вычислив матрицу, а затем просто выбрав правильную строку и столбец. Во всяком случае, вот оно:

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

Проверьте это здесь.

Я добавлю объяснение, когда я закончу играть в гольф.

Мартин Эндер
источник
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)}]]}

Идея состоит в том, чтобы кодировать A, B и резус-фактор в один бит каждый. Затем мы можем инвертировать биты, чтобы получить все антигены на принимающей стороне, и использовать их для проверки отсутствия соответствующих антител на принимающей стороне. Это более или менее аналогично существующему решению JavaScript.

Образец исполнения

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̷̰ĥ̷̳
источник
2

Пролог, 119 110 байт

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

Замечания :

  1. Типы крови имеют следующие свойства: каждый раз, когда у вас есть - (например a-), вы можете давать тем же людям, что и тот, у кого есть положительный эквивалент вашей группы (например a), а также их отрицательный аналог (например, aдает ab, то есть a-дает abи ab-). Основываясь на этом свойстве и немного злоупотребляя нотациями, чтобы использовать операторы минус и плюс, мы можем учитывать множество случаев. Пожалуйста, скажите мне, если вы считаете это приемлемым . Если вы предпочитаете использовать оригинальный (постфиксный) синтаксис, вот версия без игры в гольф:

    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. Это Пролог, поэтому интерактивная среда позволяет запрашивать все, как требуется (см. Пример ниже). Конечно, у нас нет списков строго как вывод, но это эквивалентно. Как следствие, мы также естественным образом обрабатываем ошибки.

пример

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.

Затем мы выполняем 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)])

... которая без надлежащего форматирования является той же самой матрицей, что и приведенная в вопросе.

Детали

Предикат g/2является отдавание отношения: g(X,Y)средства людей типа крови X могут дать кровь для людей типа крови Y .

Найти приемников для группы a:

[eclipse]: g(a,R).    

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

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

Найти получателей для orange_juice(должно произойти сбой):

[eclipse] g(orange_juice,L).

No (0.00s cpu)

Найти доноров для O-:

[eclipse] g(X,-o).

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

Кто что может дать? :

[eclipse] g(X,Y).

.... 27 answers ....

Мы не идем в бесконечный цикл рекурсии (это было в предварительных тестах).

CoreDump
источник
1

Python, 187 байт

Другой подход:

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]

Возможно, можно играть в гольф немного больше.

Тест:

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

Выход:

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

Рубин, 237 232 223 221 210 207 байт

Исправлены некоторые посторонние обратные слеши в регулярных выражениях и сделано так, что он просто распечатывает списки, а не сохраняет их в переменных, а затем печатает их. Иногда вы упускаете очевидные вещи, пытаясь играть в гольф!

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;

По сути, я создаю собственное регулярное выражение для введенной группы крови, чтобы проверить, можете ли вы сделать пожертвование другой группе крови. Затем я перебираю группы крови и применяю к ним то же регулярное выражение и проверяю, могут ли они пожертвовать указанному.

Это, вероятно, может быть в гольфе еще больше. Это моя первая попытка игры в гольф, хе.

Mewy
источник
1

Python 2, 168 байт

Это тот же метод, что и ответ Blackhole. Выход с ошибкой, если параметр не найден в списке типов.

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]

Менее гольф:

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

Запустите это здесь: http://repl.it/eaB

Я также попробовал пару других небольших изменений, но не мог сделать это немного короче ...

#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
источник
1

PHP (287 байт):

Да, это довольно долго, но работает как положено.

Может быть возможно сократить много:

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

Это не легко читать и было нелегко написать.

Он работает по назначению, выводя те, которые вы можете дать, и те, которые вы можете получить, на другой строке.

Для этого требуется параметр URL T=с типом.

Исмаэль Мигель
источник
1

CJam, 80 байтов

Это все еще слишком долго. Возможно, я смогу сбрить еще 4-5 байтов.

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

Для любого неверного ввода либо печатает пустой массив, либо выдает ошибку.

Попробуйте онлайн здесь или запустите весь набор тестов

оптимизатор
источник
XKCD в попрошайничестве предназначен?
Ypnypn
@Ypnypn попрошайничать? Я не собирался изначально, но так получилось. Может быть, мир пытается нам что-то сказать ...
Оптимизатор
Извините, я имел в виду начало .
Ypnypn
1

APL, 66

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

Попробуй это здесь.

jimmy23013
источник
Может быть, это 66 символов, но определенно не 66 байтов. Вопрос не говорит, что раньше забивало.
2015 г.
1
По умолчанию кодовый гольф @orlp оценивается в байтах (см. тег wiki ). Но сказано, что есть кодовая страница APL, где один символ - один байт. Я точно не знаю, какая кодовая страница APL используется в настоящее время.
jimmy23013
@orlp "байты", но не "UTF-8 байтов". Вот кодовая страница, содержащая все эти символы.
Мартин Эндер
1

С, 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(|)}

Де-гольф это показывает:

/* 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
источник
1

PHP - 215 212 206 байт

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

Вот негольфированная версия:

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

Спасибо manatwork за сохранение 4 байта.

Черная дыра
источник
Раскол целочисленной трюк работает в PHP тоже: explode(1,'A+1O+1B+1AB+1A-1O-1B-1AB-'). И поскольку мы не обязательно следим за хорошими привычками кодирования, иногда мы используем устаревшие функции, такие как split()функция.
manatwork
@manatwork Хорошо заметили! Я отредактировал свой ответ, спасибо.
Blackhole
0

Perl, 107 112

Наконец, кодирование имен типов в числах дало более короткий код.

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

Старая версия

#!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
источник
0

Пиф, 58

Отчасти то же самое, что и решение orlp , но несколько другое и полностью разработанное самим собой.

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

объяснение

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
источник
0

J, 120 байт

   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- 

Функция не работает на недопустимых входах. Большое десятичное число - это кодирование полной матрицы совместимости.

(Очень длинное решение по нескольким причинам.)

Попробуйте это онлайн здесь.

randomra
источник