I've tried to solve finding the minimum time to print a string if all the letters of the alphabet (A-Z) form a circle:
The printer starts at A.
You can go left to right or right to left.
The next letter is printed from where you left off.
Example for string "BCY":
Going counter-clockwise here to find the minimum time. The total minimum time will be 6 seconds:
A to B takes 1 second
B to C takes 1 second
C to Y takes 4 seconds
Code
The inputs are an integer C that tells you which subtask to solve, and 2 strings S and T. T is only relevant for the second subtask. The output for the first task is just the minimum time required to print the string.
#include <fstream>
#include <cstring>
#include <cmath>
using namespace std;
ifstream fin("circular.in");
ofstream fout("circular.out");
bool dh (char a) {
return a - 'A' > 12;
}
int64_t calc_min(char a, char b) {
int64_t add = 0;
if(dh(a) == dh(b)) {
add = abs(a - b);
}
else if(dh(a) != dh(b) && dh(a) == false)
add = min((a - 'A') + ('Z' - b) + 1, b - a);
else if(dh(a) != dh(b) && dh(a) == true)
add = min((b - 'A') + ('Z' - a) + 1, a - b);
return add;
}
int main() {
int c;
string s, t;
fin >> c >> s >> t;
int64_t times = (dh(s[0]) ? 'Z' - s[0] + 1 : s[0] - 'A');
for(unsigned i = 1; i < s.length(); i++)
times += calc_min(s[i], s[i - 1]);
fout << times << "\n";
return 0;
}
Problem
The correct output is 324479. The string in test case 6 has 50000 characters but pasting 50000 characters into the console yields "26588". Pasting it into "circular.in" gives the correct answer.
If I use cin.tie && sync_with_stdio both set to false, the console bugs out with strings that are >= 800 characters, see test case 4.
Circular Problem stackoverflow on Pastebin (if you'd like to solve both subtasks). The only difference between File Input/Output and Console Input/Output is in test case 6, see https://pastebin.com/v2HeGL74
Is it normal because the string is too big or is there another reason?
Related
I think there's some problem in my vs code I am new to this coding stuff even after writing the correct code it gives me wrong results in almost every second code I write i get uncertain results Plz guys help me with this , plz check running this code in your machine....
#include <iostream>
using namespace std;
int main()
{
char a[30];
cout << "enter the hexadecimal";
cin >> a;
int i = 0, c, digit, decimal = 0, p = 1;
while (a[i] != '\0') {
i++;
}
for (int j = i; j >= 0; j--) {
c = a[j];
if (c >= 48 && c <= 57) {
digit = c - 48;
}
else if (c >= 97 && c <= 112) {
digit = c - 87;
}
decimal += digit * p;
p *= 8;
}
cout << "\ndecimal is " << decimal;
return 0;
}
while entering hexa decimal plz only enter small alphabets i have not taken capital letters into consideration
for cheking hexadecimal to decimal use this site https://www.rapidtables.com/convert/number/hex-to-decimal.html?x=146
There are several problems with the code, but I think that the main one is that you are multiplying p by 8 when it should be 16 (as hex is base-16, not base-8).
You also should take care with invalid inputs. What happens if someone enters an invalid letter 'j' for instance?
Besides, when you calculate the initial length of the string, you are setting ito the position of the array with a '\0' value so when you start processing the input, a[i] is 0 and that leads to using an uninitialized variable (digit has not been assigned a value, this is related to the previous "invalid input" issue).
By the way, I would also use chars in the comparisions instead of ASCII codes, it's easier to see what you are looking for:
if (c >= '0' && c <= '9') {
digit = c - '0';
}
and so on...
I am trying to solve such competitive programming problem:
Alex likes to laugh a lot. Laughter is a sequence of alternating letters "a" and "h". For example, "ahahaha", "hah" and "a" are laughter and "abacaba" and "hh" are not.
Alex speaks very quickly, so all his words merge into one big one. You need to find out how long he can laugh. You have a line - a recording of Alex's conversation. Determine the maximum length of laughter in this conversation.
Input file is called "laugh.in"
Output file is called "laugh.out"
Input data:
The first line of the input file contains a single integer N (1 < N ≤ 10^5) - the length of the string with Alex's conversation. The second line contains a string of small Latin letters of length N - recording Alex's conversation.
Output data:
Output one number - the longest laugh length in Alex's conversation
Here's some examples of how input/output data must look like.
Examples:
Input in laugh.in
5
ahaha
Output in laugh.out
5
Input in laugh.in
24
ahahrunawayahahsofasthah
Output in laugh.out
4
Input in laugh.in
10
ahahaahaha
Output in laugh.out
5
So, here is my code, that is supposed to solve given problem:
#include <algorithm>
#include <cstdio>
#include <iostream>
using namespace std;
int main()
{
freopen("laugh.in", "r", stdin);
freopen("laugh.out", "w", stdout);
ios::sync_with_stdio(false);
cin.tie(nullptr);
int n, i;
cin >> n;
char *s = new char[n + 1];
getchar();
for (i = 0; i < n; i += 1)
{
s[i] = getchar();
}
s[n] = '\0';
int max_length = 0;
int length = 0;
for (i = 0; i < n; i += 1)
{
length += !length && (s[i] == 'a' || s[i] == 'h');
if ((s[i] == 'a' && s[i + 1] == 'h') ||
(s[i] == 'h' && s[i + 1] == 'a'))
{
length += 1;
}
else
{
max_length = max(max_length, length);
length = 0;
}
}
cout << max(max_length, length) << endl;
delete[] s;
return 0;
}
It only passes 13 tests with other 33 resulting in "Wrong answer" verdict.
So why my code is not working? Please, give counter examples to it or explain error.
Any help would be highly appreciated.
First of all, do not write everything in main (learn to avoid it ASAP).
Secondly, the task doesn't say anything about opening files.
Avoid the use of new delete in modern C++; it is a bad practice to use it.
Here is pattern you can start over:
size_t laugh_length(const std::string& s)
{
...
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(nullptr);
size_t l;
cin >> l;
std::string s;
s.reserve(l);
cin >> s;
cout << laugh_length(s) << '\n';
}
After an extra comment form OP I see another bit problem with OP code:
ios::sync_with_stdio(false);
and then use of:
getchar();
which is cstdio API which synchronization has been disabled.
https://wandbox.org/permlink/PJzjc1joKQgmpbwa
vs https://wandbox.org/permlink/aH3OypI94CpgNuxd
So let's say we have the following case: for ”12323465723” possible answers would be ”abcbcdfegbc” (1 2 3 2 3 4 6 5 7 2 3), ”awwdfegw” (1 23 23 4 6 5 7 23), ”lcwdefgw” (12 3 23 4 6 5 7 23), in this case, the user will input numbers from 1 to 26, not divided by any space and the program itself will suggest 3 ways of interpreting the numbers, getting the most of the combinations from 1 to 26 these being the values from a to z
As you can see this is edited, as this is the last part of the problem, Thank you all who have helped me this far, I've managed to solve half of my problem, only the above mentioned one is left.
SOLVED -> Thank you
This involves a decision between 0 to 2 outcomes at each step. The base cases are there are no more characters or none of them can be used. In the latter case, we backtrack to output the entire tree. We store the word in memory like dynamic programming. This naturally leads to a recursive algorithm.
#include <stdlib.h> /* EXIT */
#include <stdio.h> /* (f)printf */
#include <errno.h> /* errno */
#include <string.h> /* strlen */
static char word[2000];
static size_t count;
static void recurse(const char *const str) {
/* Base case when it hits the end of the string. */
if(*str == '\0') { printf("%.*s\n", (int)count, word); return; }
/* Bad input. */
if(*str < '0' || *str > '9') { errno = ERANGE; return; }
/* Zero is not a valid start; backtrack without output. */
if(*str == '0') return;
/* Recurse with one digit. */
word[count++] = *str - '0' + 'a' - 1;
recurse(str + 1);
count--;
/* Maybe recurse with two digits. */
if((*str != '1' && *str != '2')
|| (*str == '1' && (str[1] < '0' || str[1] > '9'))
|| (*str == '2' && (str[1] < '0' || str[1] > '6'))) return;
word[count++] = (str[0] - '0') * 10 + str[1] - '0' + 'a' - 1;
recurse(str + 2);
count--;
}
int main(int argc, char **argv) {
if(argc != 2)
return fprintf(stderr, "Usage: a.out <number>\n"), EXIT_FAILURE;
if(strlen(argv[1]) > sizeof word)
return fprintf(stderr, "Too long.\n"), EXIT_FAILURE;
recurse(argv[1]);
return errno ? (perror("numbers"), EXIT_FAILURE) : EXIT_SUCCESS;
}
When run on your original input, ./a.out 12323465723, it gives,
abcbcdfegbc
abcbcdfegw
abcwdfegbc
abcwdfegw
awbcdfegbc
awbcdfegw
awwdfegbc
awwdfegw
lcbcdfegbc
lcbcdfegw
lcwdfegbc
lcwdfegw
(I think you have made a transposition in lcwdefgw.)
According to ASCII table we know that from 65 to 90 it A to Z.
so below is the simple logic to achieve what you're trying.
int main(){
int n;
cin>>n;
n=n+64;
char a=(char) n;
if (a>=64 && a<=90)
cout<<a;
else cout<<"Error";
return 0;
}
If you want to count the occurencs of "ab" then this will do it:
int main()
{
char line[150];
int grup = 0;
cout << "Enter a line of string: ";
cin.getline(line, 150);
for (int i = 0; line[i] != '\0'; ++i)
{
if (line[i] == 'a' && line[i+1] == 'b')
{
++grup;
}
}
cout << "Occurences of ab: " << grup << endl;
return 0;
}
If you want to convert an int to an ASCII-value you can do that using this code:
// Output ASCII-values
int nr;
do {
cout << "\nEnter a number: ";
cin >> nr;
nr += 96; // + 96 because the ASCII-values of lower case letters start after 96
cout << (char) nr;
} while (nr > 96 && nr < 123);
Here I use the C style of casting values to keep things simple.
Also bear in mind ASCII-values: ASCII Table
Hope this helps.
This could be an interesting problem and you probably tagged it wrong, There's nothing specific to C++ here, but more on algorithm.
First of all the "decode" method that you described from numerical to alphabetical strings is ambiguious. Eg., 135 could be interpreted as either "ace" or "me". Is this simply an oversight or the intended question?
Suppose the ambiguity is just an oversight, and the user will enter numbers properly separated by say a white space (eg., either "1 3 5" or "13 5"). Let nstr be the numerical string, astr be the alphabetical string to count, then you would
Set i=0, cnt=0.
Read the next integer k from nstr (like in this answer).
Decode k into character ch
If ch == astr[i], increment i
If i == astr.length(), set i=0 and increment cnt
Repeat from 2 until reaching the end of nstr.
On the other hand, suppose the ambiguous decode is intended (the numerical string is supposed to have multiple ways to be decoded), further clarification is needed in order to write a solution. For example, how many k's are there in "1111"? Is it 1 or 2, given "1111" can be decoded either as aka or kk, or maybe even 3, if the counting of k doesn't care about how the entire "1111" is decoded?
Alright, so I have two questions and if anyone can help me out I would greatly appreciate it! This is my first programming class, so it would also be my first C++ class and I'm a bit stuck.
So I created a Caesar cipher that shifts the string that the user inputs to the right by a pseudo random number between 8-15. What the complete program needs to do is give the number it is shifted by at the beginning, followed by the encrypted string. If there are spaces in the string that are inputed, they need to take the letter/number that is before the space and shift it by 4. I need to terminate the encryption with an '&' character and that is followed by a '#' character and then the number location of the first space followed by another '#' character and another location of a second space if there is one and so on.
So for example, if I were encrypting a string that was being shifted by 9 and said:
Hello World 123
It should look like this when encrypted:
9qnuuxsfxaumh012#12
My first and more important question. I can't figure out how to make the program output the '#' character followed by the number that tells the location of the space. I've thought of maybe doing some kind of loop that reads the string but I'm coming up blank. If I could get some advice that would be great as this is the only part holding me up from turning this in.
My second question comes from a little confusion within my own code that I would love an English interpretation on how it works since I don't understand it myself. I was first using just for loops to make it so that the character 'z' would wrap back around to 'a' but no matter what I did, I kept getting it to only wrap around after a '{' character which is the next character after 'z' on the ascii table. So I decided to change my method and I read on wikipedia under "Caesar cipher" that you could use a modulus. So I used the equation they gave me which was E(x) = (a + b) mod 26. Well it didn't work. So I started to do a google search and saw 2 different posts where people subtracted the character 'a' and then added the chracter 'a' back on at the end as well as added the variable to itself with +=. So I put it in and it worked.
It looks like this:
output += ((input[count] - 'a' + n) % 26) + 'a';
and I thought it would look like this after reading the wiki and it not working when i put this in
output = ((input[count] + n) % 26)
Same goes for wrapping the numbers as well:
output += ((input[count] - '0' + n) % 10) + '0';
So if someone could explain to me why I am adding output to itself as well as subtracting 'a' in the beginning and then re-adding 'a' at the end so I could understand what's going on. I really don't like having code in a program that I'm going to turn in that I don't even understand myself.
Anyways, I'm sorry for the long read, I just thought I would explain what's going on and what I need clearly so that anyone willing to help would completely understand what I'm saying without me having to follow up with a second post explaining.
And finally here's the full program that I have written:
#include <ctime>
#include <iostream>
#include <string>
#include <cstdlib>
#include <fstream>
using namespace std;
//random number generator between 8 and 15
int random()
{
int value;
value = rand() % (18 - 10) + 8;
return value;
}
int main()
{
//Give random() a seed
srand(time(NULL));
//Declare variables
string input;
int length;
int n = random();
string output;
//Program
cout << "Enter your secret message: " << endl;
getline (cin, input);
cout << n;
length = input.length();
for (int count = 0; count < length; count++)
{
input[count] = tolower(input[count]);
if (input[count] >= 'a' && input[count] <= 'z')
{
output += ((input[count] - 'a' + n) % 26) + 'a';
}
if (input[count] >= '0' && input[count] <= '9')
{
output += ((input[count] - '0' + n) % 10) + '0';
}
else if(input[count] == ' ')
{
if (input[count - 1] >= 'a' && input[count - 1] <= 'z')
{
output += ((input[count - 1] - 'a' + 4) % 26) + 'a';
}
else if (input[count - 1] >= '0' && input[count - 1] <= '9')
{
output += ((input[count - 1] - '0' + 4) % 10) + '0';
}
cout << output;
}
}
cout << output << endl;
return 0;
}
Thanks so much for anyone willing to help!
Two answer the second question:
input[count] - 'a'
This gives you 0 for the letter a, 1 for the letter b, ... 25 for the letter z.
input[count] - 'a' + n
Then you add the number n. Having "a" as an input and being n==2 you will get a 3. But for a "z" as input you will get a 27.
To solve the problem you use the modulus:
(input[count] - 'a' + n) % 26
The result is a 1 for the "z".
((input[count] - 'a' + n) % 26) + 'a'
Now you transfer the number from 0 to 25 back to the corresponding ASCII code.
The point of the seemingly odd expansion is to do the following:
Create a number from 0..25: input[count] - 'a'
Adjust that number by adding your shift amount: + n
Modulo the result with 26 to wrap overflow of 26+ back into 0..25: % 26
And finally, add that result back to the base character: +a``
Your idea of a shortcut:
output = ((input[count] + n) % 26)
simply takes the ascii value of the input char, adds the shift, then modulo 26. The result is a value in 0..25, nowhere near the range of 'a'..'z'.
And before you think just adding 'a' would work, it isn't that simple. For example, suppose you had a shift of 9 and in input char of 'z'
The presented formula that works: (ch - 'a' + n) % 26 + 'a'
(('z' - 'a' + 9) % 26 + 'a'
((122 - 97 + 9) % 26 + 97
34 % 26 + 97
8 + 97
105, the ascii value of 'i'
Your formula, with 'a' adjustment: (ch + n) % 26 + 'a'
('z' + 9) % 26 + 'a'
(122 + 9) % 26 + 97
131 % 26 + 97
1 + 97
98, the ascii value for 'b'.
The problem is the distance from the beginning of the char sequence that is being modulo-adjusted is never accounted for in the modulo reduction. Thus the reason for the formula you find odd.
Regarding how to accumulate a list of space locations. a ostringstream will make that trivial, as would a std::vector<int>. An example of the former looks like this:
#include <ctime>
#include <iostream>
#include <string>
#include <cstdlib>
#include <fstream>
#include <sstream> // for std::ostringstream
using namespace std;
int main()
{
//Give random() a seed
srand(static_cast<unsigned>(time(NULL)));
//Declare variables
string input;
int length;
int n = rand() % (18 - 10) + 8;
string output;
//Program
cout << "Enter your secret message: " << endl;
getline (cin, input);
cout << n;
// string stream to hold the list of space locations.
std::ostringstream oss;
length = input.length();
for (int count = 0; count < length; count++)
{
input[count] = tolower(input[count]);
if (input[count] >= 'a' && input[count] <= 'z')
{
output += ((input[count] - 'a' + n) % 26) + 'a';
}
if (input[count] >= '0' && input[count] <= '9')
{
output += ((input[count] - '0' + n) % 10) + '0';
}
else if(input[count] == ' ')
{
if (input[count - 1] >= 'a' && input[count - 1] <= 'z')
{
output += ((input[count - 1] - 'a' + 4) % 26) + 'a';
}
else if (input[count - 1] >= '0' && input[count - 1] <= '9')
{
output += ((input[count - 1] - '0' + 4) % 10) + '0';
}
// add space location with preamble to string stream
oss << '#' << count;
}
}
// append space accumulated list string to the end after '&'
cout << output << '&' << oss.str() << endl;
return 0;
}
I'm creating a Caesar Cipher in c++ and i can't figure out how to increment a letter.
I need to increment the letter by 1 each time and return the next letter in the alphabet. Something like the following to add 1 to 'a' and return 'b'.
char letter[] = "a";
cout << letter[0] +1;
This snippet should get you started. letter is a char and not an array of chars nor a string.
The static_cast ensures the result of 'a' + 1 is treated as a char.
> cat caesar.cpp
#include <iostream>
int main()
{
char letter = 'a';
std::cout << static_cast<char>(letter + 1) << std::endl;
}
> g++ caesar.cpp -o caesar
> ./caesar
b
Watch out when you get to 'z' (or 'Z'!) and good luck!
It works as-is, but because the addition promotes the expression to int you want to cast it back to char again so that your IOStream renders it as a character rather than a number:
int main() {
char letter[] = "a";
cout << static_cast<char>(letter[0] + 1);
}
Output: b
Also add wrap-around logic (so that when letter[0] is z, you set to a rather than incrementing), and consider case.
You can use 'a'+((letter - 'a'+n)%26);
assuming after 'z' you need 'a' i.e. 'z'+1='a'
#include <iostream>
using namespace std;
int main()
{
char letter='z';
cout<<(char)('a' + ((letter - 'a' + 1) % 26));
return 0;
}
See this https://stackoverflow.com/a/6171969/8511215
Does letter++ work?
All in all char is a numeric type, so it will increment the ascii code.
But I believe it must be defined as char letter not an array. But beware of adding one to 'Z'. You will get '[' =P
#include <iostream>
int main () {
char a = 'a';
a++;
std::cout << a;
}
This seems to work well ;)
char letter = 'a';
cout << ++letter;
waleed#waleed-P17SM-A:~$ nano Good_morning_encryption.cpp
waleed#waleed-P17SM-A:~$ g++ Good_morning_encryption.cpp -o Good_morning_encryption.out
waleed#waleed-P17SM-A:~$ ./Good_morning_encryption.out
Enter your text:waleed
Encrypted text:
jnyrrq
waleed#waleed-P17SM-A:~$ cat Good_morning_encryption.cpp
#include <iostream>
#include <string>
using namespace std;
int main() {
//the string that holds the user input
string text;
//x for the first counter than makes it keeps looping until it encrypts the user input
//len holds the value (int) of the length of the user input ( including spaces)
int x, len;
//simple console output
cout << "Enter your text:";
//gets the user input ( including spaces and saves it to the variable text
getline(cin, text);
//give the variable len the value of the user input length
len = (int)text.length();
//counter that makes it keep looping until it "encrypts" all of the user input (that's why it keeps looping while its less than len
for(x = 0; x < len; x++) {
//checks each letts (and spaces) in the user input (x is the number of the offset keep in mind that it starts from 0 and for example text[x] if the user input was waleed would be w since its text[0]
if (isalpha(text[x])) {
//converts each letter to small letter ( even though it can be done another way by making the check like this if (text[x] =='z' || text[x] == 'Z')
text[x] = tolower(text[x]);
//another counter that loops 13 times
for (int counter = 0; counter < 13; counter++) {
//it checks if the letts text[x] is z and if it is it will make it a
if (text[x] == 'z') {
text[x] = 'a';
}
//if its not z it will keeps increamenting (using the loop 13 times)
else {
text[x]++;
}
}
}
}
//prints out the final value of text
cout << "Encrypted text:\n" << text << endl;
//return 0 (because the the main function is an int so it must return an integer value
return 0;
}
Note: this is called caeser cipher encryption it works like this :
ABCDEFGHIJKLMNOPQRSTUVWXYZ
NOPQRSTUVWXYZABCDEFGHIJKLM
so for example my name is waleed
it will be written as : JNYRRQ
so its simply add 13 letters to each letter
i hope that helped you
It works but don't forget that if you increment 'z' you need to get 'a' so maybe you should pass by a check function that output 'a' when you get 'z'.
cast letter[n] to byte* and increase its referenced value by 1.