Rapid Typing Coding Challenge - c++

The question asks for total time that will be required to type a string on a keyboard, which is represented as two dimensional matrix of characters, with one finger.
input:
2 31
YLrJpXOygVUl6MqBIRFWuAKsH7Gw4Z8
kE0tTQdP1CcxSjamizon9e5NfvDbh32
YE0
The first line contains n and m as input denoting dimensions of the keyboard matrix.
Next n lines contain m characters each denoting the character in the keyboard.
Next line will contain a string S
output:
3
Explanation:
The finger is initially at the first symbol of the keyboard so the time taken to press that key is 0. After that the new key is located at 1,1 so total time taken will be |1-0|+|1-0| i.e. 2 . Now the third key is located at position 1,2 so total time to move to that key will be |2-1|+|1-1| = 1 . So our answer is 3.
The string that's asked to print is in the last input line, YE0, consisting of letters from the above 2-D matrix.
The time calculation logic is:
If you are at cell (x1,y1) of the keyboard and now you want to press the key at (x2,y2) then the time taken will be |x1-x2| + |y1-y2|. You need to calculate the total time taken to type the complete string.
In case it is impossible to type the string you have to print -1.
#include<bits/stdc++.h>
using namespace std;
int main() {
int n,m;
cin>>n>>m;
unordered_map<char, pair<int, int>> map1;
for(int i=0;i<n;i++){
string s;
cin>>s;
for(int j=0;j<m;j++) {
map1.insert({s[j], make_pair(i,j)});
}
}
string key;
cin>>key;
long long total=0;
pair<int,int> sp;
for(int i=0;i<key.length();i++) {
if(map1.find(key[i])==map1.end()) {
total=-1;
break;
} else {
auto it = map1.find(key[i]);
if(i==0) sp=it->second;
pair<int,int> p = it->second;
total+=(abs(p.first-sp.first) + abs(p.second-sp.second));
sp=p;
}
}
cout<<total;
}
This solution is partially accepted and I am not able to figure out the edge cases for which its failing. Can somebody help me?

Here is one failing test case for free.
2 31
YLrJpXOygVUl6MqBIRFWuAKsH7Gw4Z8
kE0tTQdP1CcxSjamizon9e5NfvDbh32
YE 0
Should be -1 because the blank is not in the key matrix.
It fails because you only read in the "word" until first whitespace.
Here is another one:
2 31
YLrJpXOygVUl6MqBIRFW AKsH7Gw4Z8
kE0tTQdP1CcxSjamizon9e5NfvDbh32
Y E0
Shoudl not be -1, but is. Same problem, but with the matrix.
So what you need to do is change your input reading to include white space.

It's mentioned in the question that, "The finger is initially at the first symbol of the keyboard" so when you are parsing the key
In your code if(i==0) sp=it->second; should start from {0,0} to consider the movement from the first symbol of the keyboard to the first symbol of the key.

Related

Irregular spacing in writing a palindrome pattern

#include<iostream>
using namespace std;
int main(){
int n;
cin>>n;
for(int i=1;i<=n;i++){
int space=n-i;
for(int j=1;j<=space;j++){
cout<<" ";
}
for(int k=i;k>=1;k--){
cout<<k<<" ";
}
for(int l=2;l<=i;l++){
cout<<l<<" ";
}
cout<<endl;
}
return 0;
}
I wrote this code for printing a palindrome pattern but the output I received has irregular spacing and no matter what I couldn't find the error in the code.
I assume the "correct" spacing is where all the 1's line up. Here are some steps you could try to solve the problem:
1. How is the position of 1 determined?
The position should be determined by the last line, starting with n — since we don't require any spaces on the front, according to your program.
2. At which position will 1 appear on the last line?
Before the character 1, there are spaces and other numbers — n-1 numbers from n to 2, and also the same number of spaces, since 1 space is presented after every character, except the last, which doesn't matter here. In total, 2(n-1) characters before 1.
3. Finally, How many spaces are required before line k?
For line k, we can use the above step to know that before the character 1 there are 2(k-1) characters, but we need 2(n-1) to fill the length. Thus, we can obtain the required space in front of the line as 2(n-1)-2(k-1) = 2(n-k). That's why you need the "times 2" over there on line 7.
Try to find steps toward problems.

Finding a certain character from lines of input

I am currently trying to solve this kattis problem in C++:
Ecape Wall Maria
Wall Maria has been broken! Eren must evacuate as soon as possible from his house. He must find the fastest route to escape within Wall Maria before the titans rush in. Wall Maria is represented as a N×M grid in which Eren can move horizontally or vertically.
There are burning houses and buildings which prevent Eren from passing through them. The burning houses and buildings are represented as ‘1’. Unburned or safe areas are represented as ‘0’. There are some areas which can be entered but only from a specific direction. These areas can be represented by either ‘U’, ‘D’, ‘L’, or ‘R’. For example, if there is an ‘R’ that means that area can only be entered from the right neighboring tile within Wall Maria’s grid. Similarly, ‘U’ tiles can only be entered from above, ‘D’ tiles can only be entered from below, and ‘L’ tiles can only be entered from the left.
Eren knows the time t at which the titans will rush in. It takes 1 unit of time to traverse 1 zone (which corresponds to 1 tile in the grid). Once he reaches any border of Wall Maria he is safe.
Eren’s starting position is represented by the letter ‘S’. If Eren escapes at or before time t, he is safe. Given his position within Wall Maria determine if it is possible to escape. If it is possible determine the number of zones that must be traversed to lead to the quickest escape.
Input
The input consists of a single test case. The first line contains three integers t (1≤t≤200) , N (1≤N≤100) and M (1≤M≤100). The rest of N lines will be Wall Maria’s grid containing characters ‘1‘, ‘0‘, ‘S‘, ‘U‘, ‘D‘, ‘L‘, or ‘R‘. There is exactly one ‘S‘ in the input.
Output
If it is possible to escape Wall Maria, output the minimum number of zones that must be traversed to escape. If it is not possible to escape, print “NOT POSSIBLE”!
I am having some issues with finding the character "S" in the matrix on input.
I am thinking that once we have the input of the matrix, we find the character "S" and then look to the right, left, up and down of that character. If the character is not = 1 then you repeat the process from that character until you have "left" the matrix.
However, I have tried writing code to look for the starting point (the character "S) but I have been unsuccessful in doing that.
Furthermore, I am not sure how to look around the character once I have found it. I have only gotten to the point where I can accept input, not much further. Help would be appreciated
This is my code so far:
int main(){
int M;
int N;
int t;
string wall;
cin >> t >> N >> M;
//Takes the matrix input
for (int i = 0; i < N; i++)
{
cin >> wall;
}
}
The two steps are:
Decide what data structure you want to use to represent the grid you're about to traverse. std::vector<std::string> is a standard choice here.
Read the grid into the vector line by line, storing the row and column for 'S' as you go.
Here's one approach:
#include <iostream>
#include <string>
#include <vector>
int main() {
int M;
int N;
int t;
int sx = 0;
int sy = 0;
std::cin >> t >> N >> M;
std::vector<std::string> grid(N);
for (int i = 0; i < N; i++) {
std::cin >> grid[i];
size_t pos = grid[i].find("S");
if (pos != std::string::npos) {
sx = pos;
sy = i;
}
}
// show the position; remove when you're ready to solve the problem
std::cout << sx << ", " << sy << "\n";
}
Here's the output on two of the samples:
$ ./a
1 4 4
1S01
1001
1011
0U11
1, 0
$ ./a
2 4 4
1111
1S01
1011
0U11
1, 1

Encrypt by using string c++ with diffrent key on each char

Was given to me a task to do encrypt by 2 string, with allowed only latters and spacebar.
One string is text which should I encrypt and second string is key to encrypt text. Also I should add that text must be longer than key.
Replace letters with numbers. So I decided to use ASCII, maybe if I made numbers on my own it would be easier.
Successive characters to be encrypted are summed up with an following character from key the effect of summing modulo n. Im not so sure what it means with this modulo n.
There is few more points but I can handle them alone.
Here is my 1st try with this but original text is resetting also with key.
int pom=0;
int tabenc[a.length()];
int l=0;
while(pom<=a.length()-1){
for(int k=0;k<a.length();k++){
cout<<"Nr: "<<l<<" Sum char: "<<a[k]+b[k]<<" number text:"<<a[k]<<" number key: "<<b[k]<<endl;
tabenc[pom]=a[pom]+b[k];
pom++;
}
}
And my 2nd try was with 2 fors but here probably i already overthinked. I have no clue how I can manage to do this.
int pom=0;
for(int i=0;i<a.length();i++)
{
pom=a[i];
}
for(int j=0;j<b.length();j++){
pom=a[i]+b[j];
cout<<"Nr: "<<i<<" | Sum: "<<a[i]<<" + "<<b[j]<<" = "<<pom<<endl;
}
cout<<"Nr: "<<i<<" | Sum: "<<a[i]<<" + "<<b[i]<<" = "<<pom<<endl;
}

cpp stringstream read input file algorithm to find LCS

Hi here's my first questions here, I would write as clear as possible, if I am too newbie here, please bear it with me. Thanks
Backgroud: I was asked to solve longest common substring(lcs) problem with given input files in c++.
Its purpose is to optimize the algorithm, so it has limited run-time and RAM requirement.(case insensitive)
My Approach: I used to stringstream to parse the every input line and stored them into a vector. use something like suffix tree to chop the string, sort it and put into a vector array (vector that store vectors) and compare every 2 lines (v1,v2) to find common substirng.(I used nested foop loop to compare each word inside every vector), and then put common substrings back to array and remove v1 and v2.
suffix tree eg. banana -> anana -> nana -> ana -> na -> a..[I stored all 5 elements into the vector]
result: it works for most of the files (normal textfiles)
problem: I got 2 special test case that took me forever to find lcs.
1. has 10000 line input, and each line has ave 3000 chars (include space). It took me 50 mins to find lcs. the requirement is not exceed 5 mins.
2. has 100 line input, and each line has ave 60k chars. It never finish running
what I tried:build a common word dictionary for first 2 sentence
read first two lines and stored into vectors
used suffix tree again to find common elements(substring) and named as dictionary
for rest of input lines,
if (words read is within dictionary)
fine do what I did before, read next one
else if (word is not in dictionary)
ignore this word, read next one
help needed: I still cannot read the first two lines if each line contains 60k char, so building the dict itself would exceed the run time limitations. I am not sure if the hashed table would work way better than vectors. I knew a bit about HT but never write anything with it, so if you can explain HT with patience, I would appreciate that.
Update:
As suggested, I put some code here (first one for parse and store into vector, second involve how I compare 2 string and find common element)
vector< vector<string> > parsed_array;
vector<string> choped_element;
// Num1::read from file in a while loop
while (getline (myfile,line))
{
cout << "< InputlineLoopCounter: "<<InputlineLoopCounter<<endl;:q
choped_element.clear();
choped_element.push_back(line); //whole string as first element, eg'Hello World"
stringstream ss(line);
string copystr (line);
while (ss >> temp)
{
copystr.erase(0,copystr.find_first_of(" \t")+1); // here turns into "World"
choped_element.push_back(copystr);
}
choped_element.pop_back();//since I stored whole string as frist element, last one is not necessary
sort(choped_element.begin(),choped_element.end());
parsed_array.push_back(choped_element);//stored into vector array
InputlineLoopCounter ++;
}
//Num::2 compare part in 2 diff string and assembly into new string
//v1 and v2 and 2 vectors full of chopped strings and v3 should be common element
// eg. v1[0]="hello world"; v1[1]="world"
// eg. v2[0]="I dislike hello world"; v2[1]="dislike hello word"; v2[2]="hello word"; v2[4]="word"
// eg. v3 as result would be v3[0]="hello word";v3[1]="word"
for (size_t i = 0; i < v1len; i++)
{
for (size_t j = 0; j< v2len; j++)
{
stringstream ss1(v1[i]);
string fword1;
ss1>>fword1;
stringstream ss2(v2[j]);
string fword2;
ss2>>fword2;
if(fword1 == fword2) //v1[i] and v2[j] are space seperated words
{
string nword1;
string nword2;
string lcommon;
int comlen = 1;
string combine;
combine.append(fword1);
combine.append(space);
while (ss1>>nword1 && ss2>>nword2)
{
if (nword1 == nword2)
{
combine.append(nword1);
combine.append(space);
comlen ++;
}
else
break;
}
combine.erase(combine.find_last_of(" "));
cout<< "common word: "<<combine<<endl;
v3.push_back(combine);
}
}
}

Solving "Welcome to Code Jam" from Google Code Jam 2009

I am trying to solve the following code jam question,ive made some progress but for few cases my code give wrong outputs..
Welcome to Code jam
So i stumbled on a solution by dev "rem" from russia.
I've no idea how his/her solution is working correctly.. the code...
const string target = "welcome to code jam";
char buf[1<<20];
int main() {
freopen("input.txt", "rt", stdin);
freopen("output.txt", "wt", stdout);
gets(buf);
FOR(test, 1, atoi(buf)) {
gets(buf);
string s(buf);
int n = size(s);
int k = size(target);
vector<vector<int> > dp(n+1, vector<int>(k+1));
dp[0][0] = 1;
const int mod = 10000;
assert(k == 19);
REP(i, n) REP(j, k+1) {// Whats happening here
dp[i+1][j] = (dp[i+1][j]+dp[i][j])%mod;
if (j < k && s[i] == target[j])
dp[i+1][j+1] = (dp[i+1][j+1]+dp[i][j])%mod;
}
printf("Case #%d: %04d\n", test, dp[n][k]);
}
exit(0);
}//credit rem
Can somebody explain whats happening in the two loops?
Thanks.
What he is doing: dynamic programming, this far you can see too.
He has 2D array and you need to understand what is its semantics.
The fact is that dp[i][j] counts the number of ways he can get a subsequence of the first j letters of welcome to code jam using all the letters in the input string upto the ith index. Both indexes are 1 -based to allow for the case of not taking any letters from the strings.
For example if the input is:
welcome to code jjam
The values of dp in different situations are going to be:
dp[1][1] = 1; // first letter is w. perfect just the goal
dp[1][2] = 0; // no way to have two letters in just one-letter string
dp[2][2] = 1; // again: perfect
dp[1][2] = 1; // here we ignore the e. We just need the w.
dp[7][2] = 2; // two ways to construct we: [we]lcome and [w]elcom[e].
The loop you are specifically asking about calculates new dynamic values based on the already calculated ones.
Whoa, I was practicing this problem few days ago and and stumbled across this question.
I suspect that saying "he's doing dynamic programming" won't not explain too much if you did not study DP.
I can give clearer implementation and easier explanation:
string phrase = "welcome to code jam"; // S
string text; getline(cin, text); // T
vector<int> ob(text.size(), 1);
int ans = 0;
for (int p = 0; p < phrase.size(); ++p) {
ans = 0;
for (int i = 0; i < text.size(); ++i) {
if (text[i] == phrase[p]) ans = (ans + ob[i]) % 10000;
ob[i] = ans;
}
}
cout << setfill('0') << setw(4) << ans << endl;
To solve the problem if S had only one character S[0] we could just count number of its occurrences.
If it had only two characters S[0..1] we see that each occurrence T[i]==S[1] increases answer by the number of occurrences of S[0] before index i.
For three characters S[0..2] each occurrence T[i]==S[2] similarly increases answer by number of occurrences of S[0..1] before index i. This number is the same as the answer value at the moment the previous paragraph had processed T[i].
If there were four characters, the answer would be increasing by number of occurrences of the previous three before each index at which fourth character is found, and so on.
As every other step uses values from the previous ones, this can be solved incrementally. On each step p we need to know number of occurrences of previous substring S[0..p-1] before any index i, which can be kept in array of integers ob of the same length as T. Then the answer goes up by ob[i] whenever we encounter S[p] at i. And to prepare ob for the next step, we also update each ob[i] to be the number of occurrences of S[0..p] instead — i.e. to the current answer value.
By the end the latest answer value (and the last element of ob) contain the number of occurrences of whole S in whole T, and that is the final answer.
Notice that it starts with ob filled with ones. The first step is different from the rest; but counting number of occurrences of S[0] means increasing answer by 1 on each occurrence, which is what all other steps do, except that they increase by ob[i]. So when every ob[i] is initially 1, the first step will run just like all others, using the same code.