-
Notifications
You must be signed in to change notification settings - Fork 35
/
Copy patheuler-0022.cpp
140 lines (123 loc) · 3.44 KB
/
euler-0022.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
// ////////////////////////////////////////////////////////
// # Title
// Names scores
//
// # URL
// https://projecteuler.net/problem=22
// http://euler.stephan-brumme.com/22/
//
// # Problem
// Using [names.txt](https://projecteuler.net/project/resources/p022_names.txt), a 46K text file containing over five-thousand first names, begin by sorting it into alphabetical order.
// Then working out the alphabetical value for each name, multiply this value by its alphabetical position in the list to obtain a name score.
//
// For example, when the list is sorted into alphabetical order, COLIN, which is worth 3 + 15 + 12 + 9 + 14 = 53, is the 938th name in the list.
// So, COLIN would obtain a score of 938 x 53 = 49714.
//
// What is the total of all the name scores in the file?
//
// # Solved by
// Stephan Brumme
// February 2017
//
// # Algorithm
// When using an ''std::set'' all its elements are automatically sorted.
// A second container, my ''std::map'' named ''sorted'' contains each name as a key and its position in that set.
//
// All names are written in uppercase - and my program doesn't verify it.
// The value of a name is defined as the sum of its letters where A=1, B=2, ... which boils down to ''value += c - 'A' + 1''
//
// # Hackerrank
// The modified Hackerrank differs significantly and is surprisingly easier than the original problem.
//
// # Note
// Project Euler's file can be easily parsed in C++.
// Initially I included it in my source code (which works flawlessly) but then decided to read from STDIN.
#include <iostream>
#include <string>
#include <map>
#include <set>
//#define ORIGINAL
// read a single name from STDIN, syntax: "abc","def","xyz"
std::string readName()
{
std::string result;
while (true)
{
// read one character
char c = std::cin.get();
// no more input ?
if (!std::cin)
break;
// ignore quotes
if (c == '"')
continue;
// finish when a comma appears
if (c == ',')
break;
// nope, just an ordinary letter (no further checks whether c in 'A'..'Z')
result += c;
}
return result;
}
int main()
{
// note: an std::set is always sorted
std::set<std::string> names;
#ifdef ORIGINAL
while (true)
{
// read a single name, abort when empty
auto name = readName();
if (name.empty())
break;
names.insert(name);
}
#else
unsigned int numNames;
std::cin >> numNames;
while (numNames--)
{
// Hackerrank's names are separated by a space
std::string name;
std::cin >> name;
// add to our set
names.insert(name);
}
#endif
// walk through all names in alphabetic order, keep track of their position
// store both information as [name] => [pos]
std::map<std::string, unsigned int> sorted;
unsigned int pos = 1;
for (auto name : names)
sorted[name] = pos++;
#ifdef ORIGINAL
// original problem
unsigned int sum = 0;
for (auto name : sorted)
{
unsigned int value = 0;
// 'A' = 1, 'B' = 2, ..., 'Z' = 26
for (auto c : name.first)
value += c - 'A' + 1;
// multiply by position
sum += value * name.second;
}
std::cout << sum << std::endl;
#else
unsigned int queries;
std::cin >> queries;
while (queries--)
{
std::string name;
std::cin >> name;
unsigned int value = 0;
// 'A' = 1, 'B' = 2, ..., 'Z' = 26
for (auto c : name)
value += c - 'A' + 1;
// multiply by position
value *= sorted[name];
std::cout << value << std::endl;
}
#endif
return 0;
}