Working for the FBI might seem like an interesting job, but that particular morning, detective Finalist was just another employee sipping his coffee from a shiny corporation mug. The first few months working here were full of excitement and enticing new casesâ¦nowâ¦it just seemed like a load of paperwork and occasional trips to the White Collar file library. As he finished his last drop of coffee, detective Finalist saw his computer screen light up. Great, he thought, more assignments coming my way⦠maybe another drunken farmer who chopped up his wife and made her into compost⦠just another list of cases to sort.
You are given n variable declarations and a printf instruction. You must display the output of the instruction.
A variable declaration is a string of the form name=value
, where name
is a single lowercase letter of the latin alphabet.
The printf instruction is a greatly simplified version of the homonymous C function. For this problem:
A printf instruction is a string of the form format_string, arg1, arg2, ...
(with 0 or more arguments)
A format_string is a sequence of words, separated by spaces (exactly one space between each two consecutive words). The words which start with a %
are special; they are called format specifiers. The i
th format specifier will be replaced with the value of the i
th variable, formatted according to these rules:
- If the format specifier is
%s
, the value is a string which should be printed directly - If the format specifier is
%WIDTHd
, the value is an integer which should be padded with spaces until it is WIDTH characters long, then printed. Thus:- If the value is 5 and the format string is
%3d
, print" 5"
(without the quotes). - If the value is 100 and the format string is
%3d
, print"100"
(without the quotes).
- If the value is 5 and the format string is
- If the format specifier is
%.PRECISIONf
, the value is a decimal number which should be rounded to PRECISION digits after the decimal point, then printed. Thus:- If the value is 5.31 and the format string is
%.2f
, print"5.3"
(without the quotes). - If the value is 3.14159 and the format string is
%.4f
, print"3.1416"
(without the quotes). - If the value is 1.1 and the format string is
%.5f
, print"1.10000"
(without the quotes)
- If the value is 5.31 and the format string is
- All other words (those not starting with
%
) should be printed literally
Input
N
, the number of variables, will be on the first line. The next N lines will contain variable declarations (variable_name=value
, with no spaces next to the =
).The printf instruction (
format,variable_name1,variable_name2,...,variable_namen
, with one comma between each two arguments) will be on the last line. Output
The output of the instruction will be on solely one line.Constraints
The names of the variables are made up of one letter.The format string will not contain the character
,
.1 ≤ WIDTH, PRECISION ≤ 5
1 < N < 10
All lines in the input contain less than 100 characters.
For the
%WIDTHd
format specifier, the integer is at most WIDTH
digits long.Example
Input | Output |
---|---|
2 o=widgets p=13.365 Buy %s @ %.2f each,o,p | Buy widgets @ 13.37 each |
3 a=1 b=10 c=100 The first three powers of %s are %4d %4d %4d,a,a,b,c | The first three powers of 1 are 1 10 100 |
2 b=3 a=Ana %s are %s mere,a,b | Ana are 3 mere |
The regular solution (Marius Gavrilescu)
Since format specifiers are whole words, we can iterate through the words of the format string, passing each of them to printf (with an argument if needed). We will use astd::map
to map variable names to values. 1 #include<cstdio> 2 #include<cstdlib> 3 #include<cstring> 4 #include<map> 5 6 std::map<char, char*> vars; // Map from variable names to values 7 char c, s[105], *vs; // vs points to the name of the previous variable 8 9 char* next() { // This function returns the name of the next variable 10 vs+=2; // Advance to the next variable name 11 return vars[*vs]; // Return the value of the variable 12 } 13 14 int main(){ 15 int n; 16 scanf("%d ", &n); // Read the number of variables 17 while(n--){ 18 scanf("%c=%s ", &c, s); // Read the variable name and value 19 vars[c] = strdup(s); // Store the variable in the map 20 } 21 fgets(s, 105, stdin); // Read the last line 22 23 vs = strchr(s, ',') - 1; // Two characters before the first variable name 24 vs[1] = 0; // Remove the comma to terminate the format string here 25 26 for(char *w = strtok(s, " "); w != NULL; w = strtok(NULL, " ")){ 27 char type = w[strlen(w) - 1]; // The last character of this word, e.g. d for %5d 28 if(w[0] != '%') // If the word is not a format specifier... 29 printf(w); // ...print it directly 30 else if(type == 's') // If the format specifier ends with a s... 31 printf(w, next()); // ...pass it to printf as-is (= as a string) 32 else if(type == 'd') // If the format specifier ends with a d... 33 printf(w, atoi(next())); // ...pass it to printf as an int 34 else // Otherwise (if it ends with a f)... 35 printf(w, atof(next())); // ...pass it to printf as a float 36 putchar(' '); // Put a space after this word 37 } 38 39 return 0; 40 }
The easy solution (Marius Gavrilescu)
An easier way to solve this problem is to directly call printf with the given format string and arguments. This can't be done portably in C. Fortunately, some other languages do not have this restriction.1 #!/usr/bin/perl 2 use v5.14; 3 use warnings; 4 5 my @args = <>; # Read all lines 6 chomp @args; # Remove the final newline from all lines 7 shift @args; # Get rid of the first line 8 my ($format, @vars) = split ',', pop @args; # Split the last line into a format string and variables 9 my %args = map { split '=' } @args; # Create a hash from variable names to values 10 11 printf $format, map { $args{$_} } @vars; # Pass the format string and variable values to printf