I have a text file with 1s, 2s and 3s like below:
1
1
2
3
3
3
1
2
2
2
2
1
..and I am trying to find a way to find out how many in a row for each.
For example if I was checking 1 it would output:
1 in a row: 2, 2 in a row: 1, 3 in a row: 0, 4 in a row: 0....
all the way to 20 in a row (array size), since there is 2 1s in a row once and then 2 1s by themselves (only 1 in a row)
I am trying to calculate HOW MANY TIMES the number 1 is only 1 in a row, 2 in a row, 3 in a row, etc up to 20 (if i had a longer list)
So far this is what I have, however I don't know what to do at the ??? line:
int main()
{
ifstream file("test.txt");
string linebuffer;
int sequenceCounts[20];
int onez = 0;
while (file && getline(file, linebuffer)){
if (linebuffer.length() == 0)continue;
{
if (linebuffer == "1")
{
??? while the next is 1->onez++
sequenceCounts[onez]++;
}
}
}
return 0;
}
Try something along the lines of this:
int sequenceCounts[20];
int currentOnes = 0;
while (file && getline(file, linebuffer)){
if (linebuffer.length() == 0){
if (currentOnes > 0){
sequenceCounts[currentOnes]++;
}
continue;
}
if (linebuffer == "1")
{
currentOnes++; //We found another 1,
//meaning the current group is bigger than in the last line.
} else if (currentOnes > 0){
//This line does not contain a "1", but the previous lines did
sequenceCounts[currentOnes]++;
currentOnes = 0;
}
}
Basically each time you encounter a "1" you increase a counter how long your current sequence is. When the sequence is finished (a line without a "1" but with "1"s before) you increase the counter for that particular number of "1"s and reset your counter for the current sequence.
Edit: previous failed if the file ended with a "1"
I did this using a vector and a simple map to hold the longest consecutive streak, so you'd merely have to read the lines, parse them to ints, and add them to a vector.
#include <iostream>
#include <cstdlib>
#include <vector>
#include <fstream>
#include <algorithm>
#include <map>
int mostConsec(const std::vector<int> &vec) {
std::map<int, size_t> consecMap;
size_t count = 0;
int current = vec.front();
for (auto i : vec) {
if (consecMap.count(current) == 0)
consecMap[current] = 0;
if (i == current) {
count += 1;
if (consecMap[current] <= count)
consecMap[current] = count;
}
else {
count = 1;
}
current = i;
}
auto ptr = std::max_element(
consecMap.begin(),
consecMap.end(),
[](const std::pair<int, size_t> &p1, const std::pair<int, size_t> &p2) {return p1.second < p2.second; }
);
return ptr->first;
}
int main(int argc, char **argv) {
std::vector<int> v;
std::ifstream inFile("test.txt");
int tmp;
while (inFile >> tmp)
v.push_back(tmp);
inFile.close();
int most = mostConsec(v);
std::cout << most << std::endl;
system("pause");
}
Related
My task is:
Implement a binary search on an array of numbers sorted in non-decreasing order.
It is forbidden to use ready-made binary search functions from standard libraries.
The first line contains an integer n — the number of numbers in the array 1 <= n <= 3*10^5. The second line contains n numbers of the array separated by a space. All numbers are integers and belong to the interval from -2^31 to 2^31 inclusive. The numbers in the array are sorted in non-decreasing order. The third line contains an integer k — the number of requests 1 <= k <= 3*10^5. The fourth line contains k space-separated integers-requests from -2^31 to 2^31 - 1 inclusive.
For each query number x on a separate line print numbers b, l and r separated by a space, where:
b is equal to 1 if x is present in the array, or 0 otherwise;
l is the index of the first element greater than or equal to x;
r is the index of the first element greater than x.
Array elements are numbered with indices from 0 to n-1. If there are no suitable elements in the array, we will agree that the returned value will be equal to n.
Input example:
1
1
3
0 1 2
Output for the input above must be:
0 0 0
1 0 1
0 1 1
Here is my code for the task above:
#include <algorithm>
#include <iostream>
#include <sstream>
#include <string>
#include <vector>
using string = std::string;
using stringstream = std::stringstream;
template <typename T> using vector = std::vector<T>;
int string_to_int(stringstream& stream, const string &value) {
int result;
stream << value;
stream >> result;
stream.clear();
return result;
}
template <typename T> int binary_search(const vector<T> &source, int item) {
int low = 0;
int high = source.size() - 1;
while (low <= high) {
int middle_index = low + (high - low) / 2;
int middle = source[middle_index];
if (middle == item)
return middle_index;
if (item < middle)
high = middle_index - 1;
else
low = middle_index + 1;
}
return source.size();
}
void split_string_to_words(const string &source, vector<string> &words) {
string temp;
words.reserve(100);
for (int i = 0; i < source.length(); ++i) {
if (source[i] == ' ') {
words.push_back(std::move(temp));
temp.clear();
} else
temp.push_back(source[i]);
}
words.push_back(temp);
}
int main() {
stringstream stream;
string line;
getline(std::cin, line);
int item_count = string_to_int(stream, line);
getline(std::cin, line);
vector<string> string_items;
split_string_to_words(line, string_items);
vector<int> items(item_count);
std::transform(string_items.begin(), string_items.end(), items.begin(),
[&](string number) { return string_to_int(stream, number); });
getline(std::cin, line);
int search_item_count = string_to_int(stream, line);
getline(std::cin, line);
vector<string> search_string_items;
split_string_to_words(line, search_string_items);
vector<int> search_items(search_item_count);
std::transform(search_string_items.begin(), search_string_items.end(),
search_items.begin(),
[&](string number) { return string_to_int(stream, number); });
for (auto item : search_items) {
int index = binary_search(items, item);
std::cout << (1 - (index == items.size())) << " ";
int l = 0;
while (l < items.size() && items[l] < item)
l++;
int r = l;
while (r < items.size() && items[r] <= item)
r++;
std::cout << l << " " << r << std::endl;
}
}
I don't know how to speed up my code. It exceeds 2s on some test cases (but the input data is not shown in the iRunner2).
Note that stoi doesn't work in iRunner2.
Suppose I have a given sum, say sum = 4. I am also given a vector = {2,4}. There are two ways to generate the given sum from the given vector (elements may be reused).
One way is just {4} cause 4 = 4.
Second way is {2,2} cause 2 + 2 = 4.
I have to find the shortest possible combination, therefore in this particular case the answer is {4}.
Here is my approach - I go through the tree, and when on the leaf I get a 0, we hit the base case, return {} vector, and fill up the vector while traversing the tree. When I get to a node, I choose the smaller of the two (or more) vectors. This way when I reach the root node, I should get a vector of the shortest combination that can yield me the target sum.
As of yet, I do not care about time constraints as such, I know there's a lot of repetitive computing going on so I will have to memoize it once I can get the basic version correct.
I have been trying to figure why this code is not working. Any insight would be appreciated.
#include <vector>
#include <algorithm>
#include <iostream>
using namespace std;
vector<int> findBestSum(int targetSum, const vector<int> &elements, vector<vector<int>> &temp) {
if (targetSum == 0)
return {};
else if (targetSum < 0)
return {-1};
else {
vector<int> small;
for (auto &i : elements) {
int remainder = targetSum - i;
vector<int> returnedVector = findBestSum(remainder, elements, temp);
if ((!returnedVector.empty() && find(returnedVector.begin(), returnedVector.end(), -1) == returnedVector.end()) || returnedVector.empty()) {
returnedVector.push_back(i);
temp.push_back(returnedVector);
}
int smallestLength = temp[0].size();
for (auto &j : temp)
if (smallestLength >= j.size())
small = j;
}
return small;
}
}
int main() {
int targetSum = 6;
const vector<int> elements{2, 3, 5}; // answer should be [3,3] however I just get a 3...
vector<vector<int>> temp;
vector<int> bestSumVector = findBestSum(targetSum, elements, temp);
for (auto i : bestSumVector)
cout << i << " ";
}
Update (14th of July, 2021):
After a few busy months I have tried to lock horns with this problem and this time my code looks like this:
#include <iostream>
#include <vector>
#include <map>
#include <numeric>
using namespace std;
bool howSum(int &targetSum, vector<int> &elementVector, vector<int> &howSumVector, vector<vector<int>> &allSums) {
static int originaltargetsum = targetSum;
if (targetSum == 0)
return true;
else if (targetSum < 0)
return false;
else {
for (auto i : elementVector) {
int remainder = targetSum - i;
bool flag = howSum(remainder, elementVector, howSumVector, allSums);
if (flag) {
howSumVector.push_back(i);
if (targetSum == originaltargetsum ||
accumulate(howSumVector.begin(), howSumVector.end(), 0) == originaltargetsum) {
allSums.push_back(howSumVector);
howSumVector.clear();
}
return true;
}
}
return false;
}
}
int main() {
int sum = 8;
vector<int> elements = {1, 4, 5};
vector<vector<int>> allSums = {};
vector<int> workingBench = {};
howSum(sum, elements, workingBench, allSums);
for (auto &i : allSums) {
for (auto &j : i) {
cout << j << " ";
}
cout << endl;
}
}
For this I have sum as 8 and elements as {1, 4, 5}.
Also I'm storing and displaying all possible solutions right now (once that is correctly done, finding shortest vector and memoization should be easy). Possible solutions in this case are:
[1, 1, 1, 1, 1, 1, 1, 1]
[4, 4]
[5, 1, 1, 1]
[4, 1, 1, 1, 1]
Currently my code only shows the first possible combination. I'm pretty sure I'm returning true and false incorrectly, please help me out here.
I took a stab at this. I do have a working solution, hopefully it is what you want:
#include <iostream>
#include <vector>
#include <algorithm>
void howSum(int targetSum, const std::vector<int> & elementVector, const std::vector<int> & howSumVector, std::vector<std::vector<int>> & allSums)
{
static int originaltargetsum = targetSum;
if (targetSum == 0)
{
allSums.push_back(howSumVector);
return;
}
else if (targetSum < 0)
{
return;
}
else
{
for (const auto i : elementVector)
{
// an element less than or equal to 0 would cause an infinite loop
if (i <= 0)
continue;
std::vector<int> newSumVector = howSumVector;
newSumVector.push_back(i);
std::vector<int> newElementVector;
std::copy_if(std::begin(elementVector), std::end(elementVector), std::back_inserter(newElementVector), [i](int element){ return element >= i; });
howSum(targetSum - i, newElementVector, newSumVector, allSums);
}
}
}
int main()
{
int sum = 8;
std::vector<int> elements = { 1, 4, 5 };
std::vector<std::vector<int>> allSums = {};
std::vector<int> workingBench = {};
howSum(sum, elements, workingBench, allSums);
for (const auto & i : allSums)
{
for (const auto & j : i)
{
std::cout << j << " ";
}
std::cout << std::endl;
}
return 0;
}
I think, in general, you were over-thinking or over-engineering the problem. Like others have mentioned, your current code is returning true too early, and nothing besides the first element/combination is tested. With recursion, it is important to take care in your return cases - really, you only want a base case or two, and otherwise you want to recur.
With the solution I have here, the main thing I have added is copying the current combination of elements for each element you need to test. That solves your main issue of not testing every combination of numbers. In addition to that, it seemed better to append to allSums when the targetSum was reached. With those changes, I was able to do away with the bool return value and simplify the code a bit. Running the code above gives these solutions:
1 1 1 1 1 1 1 1
1 1 1 1 4
1 1 1 4 1
1 1 1 5
1 1 4 1 1
1 1 5 1
1 4 1 1 1
1 5 1 1
4 1 1 1 1
4 4
5 1 1 1
This does have some duplicates (because of the order things are tested) but I felt like it is good enough since you only want the smallest solution, 4 4. To find this, you would just need to sort the allSums vector by inner vector size and then take the first entry.
I think you need to change the implementation to correctly process elements of the vector.
In your implementation it doesn't go over all vector items, just the first one.
This is one way to do it if you use vector elements as the first parameter in your function.
vector<int> findBestSum(int element, int targetSum, const vector<int>& elements,
vector<vector<int>>& temp) {
if (targetSum == 0)
return {};
else if (targetSum < 0)
return { -1 };
else {
int remainder = targetSum - element;
vector<int> returnedVector = findBestSum(element, remainder, elements, temp);
if ((!returnedVector.empty() && find(returnedVector.begin(), returnedVector.end(), -1) == returnedVector.end()) || returnedVector.empty()) {
returnedVector.push_back(element);
return returnedVector;
}
return returnedVector;
}
}
int main() {
const int targetSum = 6;
const vector<int> elements{ 2, 3, 5 }; // answer should be [3,3] however I just get a 3...
vector<vector<int>> temp;
for (auto i : elements) {
vector<int> returnedVector = findBestSum(i, targetSum, elements, temp);
if ((!returnedVector.empty() && find(returnedVector.begin(), returnedVector.end(), -1) == returnedVector.end()) || returnedVector.empty())
temp.push_back(returnedVector);
}
if (temp.size() > 0) {
vector<int> bestSum = {};
size_t small = 0;
size_t smallestLength = temp[0].size();
for (auto& j : temp)
if (smallestLength >= j.size()) {
small = j.size();
bestSum = j;
}
for (auto i : bestSum)
cout << i << " ";
}
else
cout << " sum not found" << endl;
}
I am pretty new to coding so I am sure this is a stupid question. For a class I need to code an algorithm that determines the least amount of change to make some amount of money in C++.
This code needs to read numbers from a txt file so that the first line is the coin types (aka 1 cent, 2 cents, 4 cents, etc.). The second line is the total number that I want sorted into change. Then third line is a new set of coin types and the fourth line is a new total. The general pattern continues.
The txt file looks like -
1 2 5
10
1 3 7 12
29
1 2 4 8
15
1 7 11
14
I easily created the change algorithm myself, I am having problems getting the first line to be read into an array and then the next line to be read into a variable.
My code for the coinChange algorithm.
int coinChange(int coins[], int total, int size)
{
//Set high minimum
int min = 999999999;
//For all of the coins, see if it equals the value of total
for (int i = 0; i < size; i++) {
if (coins[i] == total) {
//If so return 1
return 1;
}
}
//Loop through
for (int j = 1; j <= total / 2; j++) {
if ((coinChange(coins, j, size) + coinChange(coins, total - j, size)) < min) {
min = coinChange(coins, j, size) + coinChange(coins, total - j, size);
}
}
return min;
}
I have tried using fgets and fscanf with no success so any advice would be very helpful.
If you use c++ as tadman commented already you can use something like that:
#include <iostream>
#include <string>
#include <sstream>
#include <vector>
int main()
{
std::stringstream ss("1 2 5\n10\n1 3 7 12\n29\n");
std::string line;
while(std::getline(ss, line))
{
std::stringstream lines(line);
std::vector<int> values;
std::string string_value;
while(std::getline(lines, string_value, ' '))
values.push_back(std::stoi(string_value));
std::getline(ss, line);
int value = std::stoi(line);
std::cout << "got: ";
for(const auto& v : values) std::cout << v << ", ";
std::cout << value << std::endl;
}
return 0;
}
Try it here http://cpp.sh/33bmy .
This reads a complete line and splits the coin types apart using a std::istringstream. The total amount on the next line is extracted the usual way.
I changed your function signature to take a std::vector and an int. Most of your code should remain the same if you replace your use of size with coins.size().
#include <iostream>
#include <string>
#include <sstream>
#include <vector>
int coinChange(const std::vector<int> &coins, int total)
{
// Set high minimum
int min = 999999999;
//
// Your code here. Don't need a size parameter, use coins.size() instead
//
return min;
}
int main()
{
std::vector<int> coins;
int total;
std::string line;
while (std::getline(std::cin >> std::ws, line) && std::cin >> total) {
std::istringstream iss(line);
for (int coin; iss >> coin; ) {
coins.push_back(coin);
}
coinChange(coins, total);
coins.clear(); // reset vector before the next inputs
}
}
Note: the use of std::ws inside the std::getline call is there to consume any leftover whitespace or newline from a previous input.
Recently I have been trying to do a problem that requires me to find all the different combinations with selecting only 1 element from each row. For example, I'm inputting n rows with 2 strings per row. However, I only want to find all the different combinations where I choose 1 string from each row.
Example:
Input:
3
alex bob
straw mat
eat drink
Example combination:
alex straw drink
This results in 2^n combinations, which in this case would be 2^3 = 8 combinations. However, if I was to use n for loops to find the combinations
e.g.
#include <iostream>
#include <cstring>
#include <string>
using namespace std;
int n;
int main(int argc, char ** argv) {
cin >> n; //rows of words
string words[n][2]; //the words with 2 words per row
for (int i = 0; i < n; i++) {
for (int j = 0; j < 2; j++) {
cin >> words[i][j]; //input of words
}
}
//finding all possible combinations
for (int i =0; i<n; i++){
for (int j=0; j<2; j++){
for (int x=0; x<2; x++){
//and so on per n
}
}
}
return 0;
}
this would take n for loops to find out all the combinations of the array with only taking one item from each row. What would be the best and simplest approach to finding all different combinations with size n as I would take 1 string out of the two in each row? Thanks.
You can do recursion.
Assuming C++11, something like this maybe (didn't try to compile this though):
// finding all possible combinations
std::vector<std::vector<std::string>> combinations;
const auto processLine = [&](const std::vector<std::string>& currentCombination, int line) {
std::vector<std::string> combination0 = currentCombination;
std::vector<std::string> combination1 = currentCombination;
combination0.push_back(words[line][0]);
combination1.push_back(words[line][1]);
if (line + 1 < n) {
// process next line
processLine(combination0, line + 1);
processLine(combination1, line + 1);
}
else {
// last line - keep the result
combinations.push_back(combination0);
combinations.push_back(combination1);
}
};
std::vector<std::string> empty;
processLine(empty, 0);
// print results
for (const auto& combination : combinations) {
for (const auto& word : combination) {
std::cout << word << " ";
}
std::cout << std::endl;
}
A very simple solution for a setting where you have always 2 elements per row would be to use datatype integer and interpret each bit as a decision for the first or the second column in the respective row; then simply count from 0 to 2^n - 1 in order to get all combinations.
Applied to your example this would look as follows:
int bits meaning
0 000 alex,straw,eat
1 001 alex,straw,drink
2 010 alex,mat,eat
3 011 alex,mat,dring
4 100 bob,straw,eat
5 101 bob,straw,drink
6 110 bob,mat,eat
7 111 bob,mat,drink
For any of the given integer values 0..7, use bit shift operators or &-bitmask to map each bit to a column index:
void getCombinationRepresentedByIntValue(vector<string>& combination, int value) {
int mask = 1;
for (int i=n-1; i>=0; i--) {
if (value & mask)
combination.push_back(words[i][1]);
else
combination.push_back(words[i][0]);
mask = mask << 1;
}
}
That seems to answer your question :
int ct[n]; // count of the number of pass
int current = 0; // index of the current word (n)
/* while not all combinaison have been exploited */
while (current >= 0)
{
cout << words[current][ct[current]]; /* <<<<< can be used another way*/
/* down to the next word */
current ++; // to get the next word
if (current >=n) { // at the end of the list
cout << " ";
current--; // restore last
ct[current]++; // increment number of time we passed
/* find the previous not completely exploited */
while (current >= 0 && ct[current]> 1) /* <<< change 1 to any number of words per line */
{
ct[current] = 0;
current--;
if (current >= 0) ct[current]++;
}
if (current > 0 ) current = 0;
}
}
With your example :
Input :
3
alex bob
straw mat
eat drink
output :
alexstraweat
alexstrawdrink
alexmateat
alexmatdrink
bobstraweat
bobstrawdrink
bobmateat
bobmatdrink
hope it helps !
So I've got a homework problem:
Let G be a directed graph on n vertices.
Call G sortable if the vertices can be distinctly numbered from 1 to n (no two vertices have the same number) such that each vertex with incoming edges has at least one predecessor with a lower number. For example, Let NUM(v) be the number assigned to vertex v and consider a vertex x with incoming edges from three other vertices r, y, and z. Then NUM(x) must be bigger than at least one of NUM(r), NUM(y), and NUM(z).
Furthermore the algorithm must be linear; O(|V|+|E|).
Traversing the graph is easy enough but I have no idea how to check the parents of the vertex to see if the num of any of the parents are lower than that of the child.
How should I keep reference of the parents of the vertex I'm on?
The following adjacency lists are input files (Just samples the actual test cases have around 8k vertices).
1->2
2->3
3->1
Is not Sortable.
1->2
2->3
3->4
4->2
Is Sortable.
The problem can be in done in C++/C and I've chosen C++ for use of STL.
I store the graph using adjacency lists, the input files are edge lists.
Would this do it?
Create an adjacency matrix. If row points to col, then put a 1
there.
Scan down each col to the first 1. If col <= row then fail.
Otherwise, pass.
Here are the tables for your two examples:
1 2 3
1 0 1 0
2 0 0 1
3 1 0 0
1 2 3 4
1 0 1 0 0
2 0 0 1 0
3 0 0 0 1
4 0 1 0 0
If you are worried about space because it has to handle 8k vertices, then you can use a sparse representation if you know the input is sparse. But really, I think 64M ints should not be cause for concern.
GCC 4.7.3: g++ -Wall -Wextra -std=c++0x sortable-graph.cpp
#include <iostream>
#include <map>
#include <sstream>
#include <string>
#include <vector>
std::string trim(const std::string& str) {
std::string s;
std::stringstream ss(str);
ss >> s;
return s;
}
using graph = std::vector<std::vector<int>>;
graph read(std::istream& is) {
graph G;
std::vector<std::pair<int, int>> edges;
std::map<std::string, int> labels;
int max = -1;
// Assume input is a list of edge definitions, one per line. Each line is:
// "label -> label" where white space is optional, "->" is a literal, and
// "label" does not contain "->" or white space.
// This can be vastly simplified if we can assume sensible int labels.
std::string l;
while (std::getline(is, l)) {
// Parse the labels.
const auto n = l.find("->");
const auto lhs = trim(l.substr(0, n));
const auto rhs = trim(l.substr(n + 2));
// Convert the labels to ints.
auto i = labels.find(lhs);
if (i == labels.end()) { labels[lhs] = ++max; }
auto j = labels.find(rhs);
if (j == labels.end()) { labels[rhs] = ++max; }
// Remember the edge.
edges.push_back({labels[lhs], labels[rhs]});
}
// Resize the adjacency matrix.
G.resize(max+1);
for (auto& v : G) { v.resize(max+1); }
// Mark the edges.
for (const auto& e : edges) { G[e.first][e.second] = 1; }
return G;
}
bool isSortable(const graph& G) {
const int s = G.size();
for (int col = 0; col < s; ++col) {
for (int row = 0; row < s; ++row) {
if (G[row][col] == 1) {
if (col <= row) { return false; }
break;
}
}
}
return true;
}
void print(std::ostream& os, const graph& G) {
const int s = G.size();
for (int row = 0; row < s; ++row) {
for (int col = 0; col < s; ++col) {
os << G[row][col] << " ";
}
os << "\n";
}
}
int main() {
const auto G = read(std::cin);
print(std::cout, G);
const auto b = isSortable(G);
std::cout << (b ? "Is Sortable.\n" : "Is not Sortable.\n");
}
Now that I look at it, I guess this is O(V^2).
Take two! This one is O(|V|+|E|).
GCC 4.7.3: g++ -Wall -Wextra -std=c++0x sortable-graph.cpp
#include <iostream>
#include <map>
#include <sstream>
#include <string>
#include <vector>
std::string trim(const std::string& str) {
std::string s;
std::stringstream ss(str);
ss >> s;
return s;
}
using edges = std::vector<std::pair<int, int>>;
void read(std::istream& is, edges& E, int& max) {
std::map<std::string, int> labels;
max = -1;
// Assume input is a list of edge definitions, one per line. Each line is:
// "label -> label" where white space is optional, "->" is a literal, and
// "label" does not contain "->" or white space.
// This can be vastly simplified if we can assume sensible int labels.
std::string l;
while (std::getline(is, l)) {
// Parse the labels.
const auto n = l.find("->");
const auto lhs = trim(l.substr(0, n));
const auto rhs = trim(l.substr(n + 2));
// Convert the labels to ints.
auto i = labels.find(lhs);
if (i == labels.end()) { labels[lhs] = ++max; }
auto j = labels.find(rhs);
if (j == labels.end()) { labels[rhs] = ++max; }
// Remember the edge.
E.push_back({labels[lhs], labels[rhs]});
}
}
bool isSortable(const edges& E, int max) {
std::vector<int> num(max+1, max+1);
for (const auto& e : E) {
num[e.second] = std::min(e.first, num[e.second]);
}
for (int i = 0; i < num.size(); ++i) {
if (num[i] != max + 1 && i <= num[i]) { return false; }
}
return true;
}
int main() {
edges E;
int max;
read(std::cin, E, max);
const auto b = isSortable(E, max);
std::cout << (b ? "Is Sortable.\n" : "Is not Sortable.\n");
}