I want to ensure as an example that 2/3 values are within a given threshold. The code below accomplishes this but I'm wondering if there is a more generic approach.
struct foo {
int id;
float item1;
float item2;
float item3;
}
bool ConditionCheck(foo val1, foo val2, foo val3) {
int count = 0;
if (abs(val1.item1 - val2.item1) < val3.item1) {
count++;
}
if (abs(val1.item2 - val2.item2) < val3.item2) {
count++;
}
if (abs(val1.item3 - val2.item3) < val3.item3) {
count++;
}
if (count >= 2) {
return true;
}
return false;
}
The issue stems for the custom structs else having parameters as arrays:
// assuming array holds: [id, item1, item2, item3]
bool ConditionCheck(float (&val1)[4], float (&val2)[4], float(&threshold)[4]) {
int count = 0;
for (unsigned int i = 1; i < 4; ++i) {
if (abs(val1[i] - val2[i]) < threshold[i]) {
count++;
}
}
if (count >= 2) {
return true;
}
return false;
}
You can use an array of pointers to member:
bool ConditionCheck(foo val1, foo val2, foo val3) {
float foo::* ptrs[3] = { &foo::item1, &foo::item2, &foo::item3 };
return std::count_if( &ptrs[0],
&ptrs[3],
[&](float foo::* p)
{
return abs(val1.*p - val2.*p) < val3.*p;
}) >= 2;
}
Related
Problem is to return any one combination from given array that sums up to the target. I'm new to C++. How can I complete the function howSum() below? I can't return null here since the return type is vector. Also I'm having trouble passing the vectors.
JavaScript:
const howSum = (targetSum, numbers) => {
if (targetSum === 0) return [];
if (targetSum < 0) return null;
for (let num of numbers) {
const remainder = targetSum - num;
const remainderResult = howSum(remainder, numbers);
if (remainderResult !== null)
{
return [...remainderResult, num];
}
}
return null;
};
C++:
vector<int> howSum(int targetSum, vector<int> numbers)
{
if(targetSum == 0) return {};
if(targetSum < 0) return; //can't return null here in C++
for (int i = 0; i < numbers.size(); i++)
{
int remainder = targetSum - numbers[i];
vector<int> remainderResult = howSum(remainder, numbers);
if(pass)
{
pass
}
}
}
You can use C++17 std::optional and return std::nullopt when it does not contain value.
#include <optional>
#include <vector>
std::optional<std::vector<int>>
howSum(int targetSum, const std::vector<int>& numbers) {
if (targetSum == 0)
return std::vector<int>{};
if (targetSum < 0)
return std::nullopt;
for (auto numer : numbers) {
const auto remainder = targetSum - numer;
auto remainderResult = howSum(remainder, numbers);
if (remainderResult) {
remainderResult->push_back(targetSum);
return remainderResult;
}
}
return std::nullopt;
}
Let your function return a bool to indicate if the vector result (returned as an out param) is valid or not. It's likely going to be more efficient to pass the array (vector) as an out param reference than as a return value anyway. (Although modern compilers can do some amazing optimizations these days.)
bool howSum(int targetSum, const std::vector<int>& numbers, std::vector<int>& result)
{
result.clear();
if (targetSum == 0) {
return true;
}
if (targetSum < 0) {
return false;
}
for (int num : numbers) {
const int remainder = targetSum - num;
bool recursion_result = howSum(remainder, numbers, result);
if (recursion_result) {
result.push_back(num);
return true;
}
}
return false;
}
I have two vector structs, one contains the codes and cost for each, and another is just orders that contains requested codes and totalCost (to be calculated)
vector parts(codes, cost);
vector orders(codes, totalCost); //totalCost set to 0;
where the parts vector contains something like ('A', 10, 'B', 20);
Where A and B are parts, 10 is cost for A, 20 cost for B.
and the orders vector contains orders such as A,B,C or just A,B Say we receive an order of parts A and B.
how do we go about adding these two based on cost from parts and storing the result in a new int that we gonna use later to add to the vector struct orders (totalCost).
I was trying for several hours, I think I need to use std::transform and maybe std::accumulate? just not sure how to put the two together...
This is what I have written so far:
int totalCost;
for(auto i : customers){
for(auto x : parts){
totalCost = accumulate(i.partsList.begin(), i.partsList.end(), ???);
//then need to store cost for each order for use later
}
I have also tried:
void test(){
int cost;
for(unsigned i =0; i < customers.size(); i++){
for(unsigned x=0; x < partsVec.size(); x++){
for(unsigned z=0; z < customers.at(i).partsList.size(); z++){
if(partsVec.at(x).code == customers.at(i).partsList.at(z)){
cost += partsVec.at(x).cost;
customers.at(i).cost= cost;
}
}
}
}
for(auto i : customers){
cout << i.cost<< endl;
}
}
This output this:
40 //this is correct.
80 //this is incorrect, needs to be 40 as both customers have ordered same parts!
As you can see, this keeps incriminating and I can't figure out a way to stop it.
what I am trying to do, is get the total cost of all parts in partsList based on info from the parts vector. Customers vector has another vector of chars in it called partsList, then I can change the totalCost of each order to value obtained from above using accumulate or some other algorithm
Try something like this:
struct Part
{
char code;
double cost;
Part(char code, double cost)
: code(code), cost(cost)
{
}
};
std::vector<Part> parts;
double costOfPart(char code)
{
for(const Part &part : parts)
{
if (part.code == code)
return part.cost;
}
return 0.0;
}
struct OrderItem
{
char partCode;
size_t quantity;
OrderItem(char partCode, size_t quantity)
: partCode(partCode), quantity(quantity)
{
}
};
struct Order
{
int code;
std::vector<OrderItem> items;
Order(int code)
: code(code)
{
}
void addItem(char partCode, size_t quantity)
{
for (OrderItem &item : items)
{
if (item.partCode == partCode)
{
item.quantity += quantity;
return;
}
}
items.push_back(OrderItem(partCode, quantity));
}
double totalCost() const
{
double total = 0.0;
for (const OrderItem &item : items)
{
total += (costOfPart(item.partCode) * item.quantity);
}
// TOOD: fees, taxes, discounts, etc...
return total;
}
};
std::vector<Order> orders;
double costOfAllOrders()
{
double total = 0.0;
for(const Order &order : orders)
{
total += order.totalCost();
}
return total;
}
double costOfOrder(int orderCode)
{
for(const Order &order : orders)
{
if (order.code == orderCode)
return order.totalCost();
}
return 0.0;
}
...
parts.push_back(Part('A', 10.0));
parts.push_back(Part('B', 20.0));
...
Order order(12345);
order.addItem('A', 1);
orders.push_back(order);
...
double costOfOneOrder = costOfOrder(12345);
double totalCostOfOrders = costOfAllOrders();
...
Or, if you really want to use std::accumulate(), then you can do something like this:
#include <algorithm>
#include <numeric>
struct Part
{
char code;
double cost;
Part(char code, double cost)
: code(code), cost(cost)
{
}
};
std::vector<Part> parts;
double costOfPart(char code)
{
auto iter = std::find_if(parts.begin(), parts.end(),
[=](Part &part){ return part.code == code; }
);
if (iter != parts.end())
return iter->cost;
return 0.0;
}
struct OrderItem
{
char partCode;
size_t quantity;
OrderItem(char partCode, size_t quantity)
: partCode(partCode), quantity(quantity)
{
}
};
struct Order
{
int code;
std::vector<OrderItem> items;
Order(int code)
: code(code)
{
}
void addItem(char partCode, size_t quantity)
{
auto iter = std::find_if(items.begin(), items.end(),
[=](OrderItem &item){ return item.partCode == partCode; }
);
if (iter != items.end())
iter->quantity += quantity;
else
items.emplace_back(partCode, quantity);
}
double totalCost() const
{
double total = std::accumulate(items.begin(), items.end(), 0.0,
[](double totalSoFar, const OrderItem &item) {
return totalSoFar + (costOfPart(item.partCode) * item.quantity);
}
);
// TOOD: fees, taxes, discounts, etc...
return total;
}
};
std::vector<Order> orders;
double costOfAllOrders()
{
return std::accumulate(orders.begin(), orders.end(), 0.0,
[](double totalSoFar, const Order &order){
return totalSoFar + order.totalCost();
}
);
}
double costOfOrder(int orderCode)
{
auto iter = std::find_if(orders.begin(), orders.end(),
[=](Order &order){ return order.code == orderCode; }
);
if (iter != orders.end())
return iter->totalCost();
return 0.0;
}
...
parts.emplace_back('A', 10.0);
parts.emplace_back('B', 20.0);
...
Order order(12345);
order.addItem('A', 1);
orders.push_back(order);
...
double costOfOneOrder = costOfOrder(12345);
double totalCostOfOrders = costOfAllOrders();
...
Update: Based on the code you have added, you are looping all wrong. You need something more like this instead:
auto partCost = [&](char code) -> int {
for(auto &p : partsVec) {
if (p.code == code)
return p.cost;
}
return 0;
}
int totalCost = 0;
for(auto &c : customers){
totalCost += accumulate(c.partsList.begin(), c.partsList.end(), 0,
[&](int totalSoFar, char code) {
return totalSoFar + partCost(code);
}
);
}
Or, just using plain loops:
void test(){
int cost = 0;
for(unsigned i = 0; i < customers.size(); i++) {
auto &c = customers[i];
for(unsigned x = 0; x < c.partsList.size(); x++) {
auto partCode = c.partsList[x];
for(unsigned z = 0; z < partsVec.size(); z++) {
auto &p = partsVec[z];
if (p.code == partCode) {
cost += p.cost;
break;
}
}
}
}
cout << cost << endl;
}
Just find for every part in order it's cost from the parts container, that you pass to lambda in accumulate algorithm. I assume, that either order behaves as a container or each part in order can be obtained and put to a vector.
std::accumulate(order.begin(), order.end(), 0, [&parts](const auto & o) {
return std::find(parts.begin(), parts.end(), o).cost();
}
You may also try and write a "nasty" function object that will behave as a lambda.
class AccumulatorHelper {
public:
vector<Parts>& parts;
AccumulatorHelper(vector<Parts>& p): parts(p) { }
int operator()(const Order& order) {
return std::find(parts.begin(), parts.end(), order.character());
}
};
I have made two classes: stack1 and stack2 and defined my own stack operations of push(), pop(), isempty() and isfull(). I am trying to calculate a postfix expression from an input. I have made another class called operation that is a child of stack1 and stack2, so I can access the functions of push(),pop(), etc.. within operation. I have a function within operation called operate() that does the dirty work on the stacks. Within this function I have a while loop that depends on stack1 not being empty until the operation is complete; HOWEVER, when I step through this function top1, where stack1 is pointing to, has been reset to 0. Is there a way to overcome this/am I doing something wrong? This is the first time I am using classes and such, so I am not sure of the ins and outs.
Here are the definitions of my classes:
class stack1 {
private:
int num1[SIZE/2]; int top1;
public:
void push1(int data)
{
if (is_full1());
else
{
num1[top1] = data;
top1++;
}
}
int pop1(void)
{
if(is_empty1());
else
{
top1--;
return num1[top1];
}
}
int is_empty1(void)
{
if(top1 == 0)
{
return 1;
}else
{
return 0;
}
}
int is_full1(void)
{
if(top1 == SIZE)
{
return 1;
}else
{
return 0;
}
}
stack1()
{
top1 = 0; num1[SIZE/2] = {0};
} };
class stack2 {
private:
int num2[SIZE/2]; int top2; public:
void push2(int data)
{
if (is_full2());
else
{
num2[top2] = data;
top2++;
}
}
int pop2(void)
{
if(is_empty2());
else
{
top2--;
return num2[top2];
}
}
int is_empty2(void)
{
if(top2 == 0)
{
return 1;
}else
{
return 0;
}
}
int is_full2(void)
{
if(top2 == SIZE)
{
return 1;
}else
{
return 0;
}
}
stack2()
{
top2 = 0; num2[SIZE/2] = {0};
} };
class operation: public stack2, public stack1 {
private:
int answer;
int a;
int b;
int num_cnt;
int ans;
int from_st1;
int from_st2;
public:
int c;
int oper(void)
{
answer = 0;
a = 0;
b = 0;
num_cnt = 0;
ans = 0;
c = 0;
stack1 st1;
stack2 st2;
while(!st1.is_empty1())
{
from_st1 = st1.pop1();
if(from_st1 == plus)
{
st2.push2(from_st1);
}else if(from_st1 == minus)
{
st2.push2(from_st1);
}else if(from_st1 == mult)
{
st2.push2(from_st1);
}else if (from_st1 == divide)
{
st2.push2(from_st1);
}else if(num_cnt == 1)
{
num_cnt = 0;
if(ans == 0)
{
answer = b;
ans++;
}
a = from_st1;
from_st2 = st2.pop2();
if(from_st2 == plus)
{
c = a+answer;
}else if(from_st2 == minus)
{
c = a-answer;
}else if(from_st2 == mult)
{
c = a*answer;
}else if(from_st2 == divide)
{
c = a/answer;
}
}else
{
b = from_st1;
}
num_cnt++;
}
return c;
}
operation()
{
answer = 0;
a = 0;
b = 0;
num_cnt = 0;
ans = 0;
from_st1 = 0;
from_st2 = 0;
} };
I think that the "problem" is with the line:
stack1 st1;
stack2 st2;
This will call the default constructor and set the value of the variables top1 and top2 as zero.
A workaround to this would be to initialise these variables with some positive non-zero value.
Hence the code would look something like(focusing only on the changed parts):
class stack1 {
private:
int num1[SIZE/2]; int top1;
public:
.....
stack1()
{
top1 = 0; num1[SIZE/2] = {0};
}
stack1(int top1)
{this.top1 = top1;}
};
class stack2 {
private:
int num2[SIZE/2]; int top2; public:
public:
.....
stack2()
{
top2 = 0; num2[SIZE/2] = {0};
}
stack2(int top2)
{this.top2 = top2;}
};
class operation: public stack2, public stack1 {
.....
public:
int c;
int oper(void)
{
.....
//just an example, can be declared explicitly as well
stack1 st1(5);
stack2 st2(7);
.....
Also, I would advice you to make your code a bit more readable(for instance the presence of 3-liner {} in if cases spanning only a single line). It is just unnecessary consumption of space.
And finally, if the "redefinition" of parent class' variables means the variables re-asserting some value on being inherited, they don't, unless you specify explicitly(such as using a constructor in our case to assign different values to top1 and top2). The inherited class will get a copy of the state of the parent class*.
*meaning they cannot be changed directly by the inherited class. For example if you would've done: int top1=5; initially then top1 would've been 5 until it were to be redefined again somewhere(such as using a constructor)
I take from the problem statement you are trying to build a basic calculator with four operators and need basic expression evaluation done using stack.
Say you have an expression: a+b-cd/e
looks like this in stack: TOP e->/->d->->c->-->b->+->a EMPTY
And this track needs to be evaluated.
Based on these.. you may be looking for something like below:
class stack {
private:
int num[SIZE];
int top;
public:
void push(int data)
{
if (is_full1());
else
{
num[top] = data;
top++;
}
}
int pop(void)
{
if(is_empty());
else
{
top--;
return num[top];
}
}
int is_empty(void)
{
if(top == 0)
{
return 1;
}else
{
return 0;
}
}
int is_full(void)
{
if(top == SIZE)
{
return 1;
}else
{
return 0;
}
}
stack()
{
top = 0; num[SIZE] = {0};
}
};
class operation {
private:
int answer;
int op1;
int op;
boolean isOperator(int val) {
boolen retVal = false;;
if (val == plus ||
val == minus ||
val == divide ||
val == mult) {
retVal = true;
}
else {
retVal = false;
}
return retVal;
}
public:
int oper(stack st1)
{
int from_st1 = 0;
while(!st1.is_empty())
{
from_st1 = st1.pop();
if(isOperator(from_st1))
{
op = from_st1;
}
else if(answer != 0)
{
op1 = from_st1;
if(op == plus)
{
answer = op1 + answer;
}else if(op == minus)
{
answer = op1 - answer;
}else if(op == mult)
{
answer = op1 * answer;
}else if(op == divide)
{
answer = op1 / answer;
}
}
else
{
answer = from_st1;
}
}
return answer;
}
operation()
{
answer = 0;
op1 = 0;
op = 0;
}
};
Note: You can do all evaluation with one stack don't need two stacks. Your operands can not equal to integer values for +, -, * and / for this assignment. You have a valid expression input into stack in main() code.
I've been trying to understand what havn't I initialized in this code and I completely(?) understand what is uninitialized but I don't know how to initialize it.
I am getting the error:
==11931== Conditional jump or move depends on uninitialised value(s)
==11931== at 0x804ABA6: Hashtable<int>::put(int, int) (hash_table.h:169)
==11931== by 0x8048F80: test_put() (hash_table_test.cpp:27)
==11931== by 0x804A551: main (hash_table_test.cpp:52)
==11931== Uninitialised value was created by a heap allocation
==11931== at 0x402ADFC: operator new[](unsigned int) (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==11931== by 0x804A9AE: Hashtable<int>::Hashtable() (hash_table.h:64)
==11931== by 0x8048F62: test_put() (hash_table_test.cpp:26)
==11931== by 0x804A551: main (hash_table_test.cpp:52)
from the valgrind so apparantly I havn't been initializing correctly the c'tor for Hashtable class:
Hashtable() :
ht_keys(2), ht_size(0), dynamicArray(NULL) {
dynamicArray = new Node[ht_keys];
for (int i = 0; i < ht_keys; i++) {
dynamicArray[i].delete_val = false;
dynamicArray[i].key=0;
dynamicArray[i].default_node = false;
}
}
the dynamic array is of type Node* which it's private fields are:
bool delete_val;
T element;
int key;
bool default_node;
the class Node is inside the class Hashtable.
how can I initialize dynamicArray?
here's the full code:
#include <string>
#include <iostream>
#include "library2.h"
#include <iterator>
using namespace std;
#ifndef HASH_TABLE_HPP_
#define HASH_TABLE_HPP_
#define DIV 2
//type T must have c'tor, operator !=
template<class T>
class Hashtable {
public:
class Node {
public:
Node(const T t) :
delete_val(false), element(t), key(0), default_node(true) {
}
Node(bool v, const Node& n) :
delete_val(v), element(n.element), key(0), default_node(
n.default_node) {
}
Node(const Node& n) :
delete_val(false), element(n.element), key(n.key), default_node(
n.default_node) {
}
Node() :
delete_val(false), key(0), default_node(true) {
}
bool operator==(const Node* n) {
if (n) {
if (element != n->element || default_node != n->default_node) {
return false;
}
return true;
}
return false;
}
bool operator!=(const Node n) {
if (!(*this == n)) {
return false;
}
return true;
}
bool delete_val;
T element;
int key;
bool default_node;
};
Hashtable() :
ht_keys(2), ht_size(0), dynamicArray(NULL) {
dynamicArray = new Node[ht_keys];
for (int i = 0; i < ht_keys; i++) {
dynamicArray[i].delete_val = false;
dynamicArray[i].key=0;
dynamicArray[i].default_node = false;
}
}
//seriously damaged programming...
Hashtable(Node* array, int HT_keys, int HT_size) :
ht_keys(HT_keys), ht_size(HT_size) {
dynamicArray = new Node[ht_keys];
if (array != NULL) {
for (int i = 0; i < ht_keys; i++) {
dynamicArray[i] = array[i];
}
}
}
Hashtable(const Hashtable& ht) {
if (&ht == this) {
return;
}
ht_keys = ht.ht_keys;
ht_size = ht.ht_size;
dynamicArray = new Node[ht_keys];
for (int i = 0; i < ht.ht_keys; i++) {
this->dynamicArray[i] = ht.dynamicArray[i];
}
}
~Hashtable() {
delete[] this->dynamicArray;
}
Hashtable operator=(const Hashtable& ht) {
Hashtable<T> newHT = ht;
return newHT;
}
//Returns true if some value equal to value exists within the hash table.
bool contains(Node n, int i) {
if (i < 0 || i > ht_keys || !n) {
return false;
}
if (i == ht_keys) {
return false;
}
//make sure that n.delete_val is not set as true.
if (dynamicArray[i]->element == n.element
&& !dynamicArray[i]->delete_val) {
return true;
}
if (dynamicArray[i]->delete_val) {
return contains(n, i + 1);
}
return false;
return true;
}
//Returns true if some key equal to key exists within the hash table.
bool containsKey(int i) {
if (i < 0 || i > ht_keys) {
return false;
}
if (dynamicArray[i]->element && !dynamicArray[i]->delete_val) {
return true;
}
return false;
}
//Returns true if some value equal to value exists within the hash table.
bool containsValue(T e) {
return true;
}
//Returns an enumeration of the values contained in the hash table.
int enumeration() {
return ht_size;
}
//Returns the object that contains the value associated with key.
//If key is not in the hash table, a null object is returned.
Node get(int i) {
if (i >= 0) {
return dynamicArray[i % ht_keys];
}
Node n;
return n;
}
//Returns true if the hash table is empty;
//returns false if it contains at least one key.
bool isEmpty() {
if (ht_size) {
return false;
}
return true;
}
//Returns an enumeration of the keys contained in the hash table.
int keys();
//Inserts a key and a value into the hash table.
//Returns false if key isn't already in the hash table;
//returns true if key is already in the hash table.
bool put(T e, int i) {
if (e && i > 0) {
Node n;
n.default_node = false;
n.delete_val = false;
n.key = i;
n.element = e;
//line 168
for (int j = (i % ht_keys); j < ht_keys; j = ((j + 1) % ht_keys)) { //line 169
if (!dynamicArray[j % ht_keys].element
|| dynamicArray[j % ht_keys].delete_val) {
dynamicArray[j % ht_keys] = n;
ht_size++;
return true;
}else if (i == (j + 1) % ht_keys) {
rehash();
return put(e, i);
}
}
return false;
}
return false;
}
bool put_aux(Node n, int i, Node* Array, int HT_keys) {
for (int j = (i % HT_keys); j < HT_keys; j = ((j + 1) % HT_keys)) {
if (!Array[j % HT_keys].element || Array[j % HT_keys].delete_val) {
Array[j % HT_keys] = n;
return true;
} else if (Array[j % HT_keys].element == n.element) {
return true;
}
}
return false;
}
//Increases the size of the hash table and rehashes all of its keys.
void rehash() {
int old_ht_keys = ht_keys;
ht_keys = DIV * ht_keys;
Node* newArray = new Node[ht_keys];
if (ht_keys > DIV) {
for (int j = 0; j < old_ht_keys; j++) {
put_aux(dynamicArray[j],dynamicArray[j].key,newArray,ht_keys);
}
}
delete[] dynamicArray;
dynamicArray = newArray;
}
//Removes key and its value.
//Returns the value associated with key.
//If key is not in the hash table, a null objecht_sizet is returned.
T remove(int i) {
if (i >= 0 && i < ht_keys) {
Node deleted_node(true, dynamicArray[i % ht_keys]);
dynamicArray[i % ht_keys] = deleted_node;
ht_size--;
return deleted_node.element;
}
return NULL;
}
//Returns the number of entries in the hash table.
int size() {
return this->ht_size;
}
private:
int ht_keys;
int ht_size;
Node* dynamicArray;
};
#endif /* HASH_TABLE_HPP_ */
It seems to be complaining about the line !dynamicArray[j % ht_keys].element (on line 163 of the code you posted; this would be a lot easier if the code you posted matched the code valgrind was using; right now the code you posted is several lines shorter than the code valgrind is using).
You never initialize the element member when you allocate the memory in the constructor. You then attempt to use it here in a conditional statement. valgrind correctly warns you of the problem.
guys! I am trying to do this:
int (*filterFunc)(Medicine* criteria, Medicine*);
DynamicVector<Medicine>* filter2(Medicine* criteria, filterFunc f); //error
but I get an error: 'filterFunc' is not a type
I am trying to do this because I want a general filter so then I can do this:
int filterPrice(Pet* pet) {
if (pet->price > 10 && pet->price < 100) {
return 0;
}
return 1;
}
VectorDinamic* filter2(Pet* criteria, filterFunc f) {
VectorDinamic* v = getAll(ctr->repo);
VectorDinamic* rez = creazaVectorDinamic();
int nrElems = getNrElemente(v);
int i;
for (i = 0; i < nrElems; i++) {
Pet* pet = get(v, i);
if (!f(criteria, pet)) {
add(rez, copyPet(pet));
}
}
return rez;
}
VectorDinamic* filterByPrice(float price) {
Pet* criteria = createPet(1, "", "", price);
VectorDinamic* rez = filter2(ctr, criteria, filterByPriceGr);
destroyPet(criteria);
return rez;
}
How can I solve this problem?
You forgot a typedef, to declare the type. Otherwise this declaration just creates a variable of type int(*)(Medicine*,Medicine*).
typedef int (*filterFunc)(Medicine* criteria, Medicine*);
//^^^^^^^