Skip to content

Commit 7ace958

Browse files
committed
Merge branch 'feature/2018-1b' into develop
2 parents 19b8609 + 35045b3 commit 7ace958

4 files changed

Lines changed: 3476 additions & 0 deletions

File tree

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
{
2+
"license" : "MIT",
3+
"scripts": {
4+
"test": "jest --watchAll"
5+
},
6+
"devDependencies": {
7+
"jest": "^22.4.3"
8+
}
9+
}
Lines changed: 227 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,227 @@
1+
'use strict'
2+
3+
//
4+
// solve
5+
//
6+
function solve(prob) {
7+
8+
if (Number.isInteger(100 / prob.N)) {
9+
return 100
10+
}
11+
12+
if (prob.voteValue - Math.floor(prob.voteValue) >= 0.5) {
13+
let sumPercent = prob.unvotedCount * Math.ceil(prob.voteValue)
14+
sumPercent += prob.langPercentRounded.reduce((acc, cur) => acc + cur, 0)
15+
return sumPercent
16+
}
17+
18+
const candidates = prob.langPercentRaw.map((raw, index) => {
19+
return {
20+
index: index,
21+
fraction: raw - Math.floor(raw)
22+
}
23+
})
24+
.filter(val => {
25+
return (val.fraction > 0 && val.fraction < 0.5)
26+
})
27+
.sort((a, b) => {
28+
return b.fraction - a.fraction
29+
})
30+
31+
let n = prob.N
32+
let unvotedCount = prob.unvotedCount
33+
let voteValue = prob.voteValue
34+
let langCount = prob.langCount
35+
let langPercentRaw = prob.langPercentRaw
36+
let langPercentRounded = prob.langPercentRounded
37+
38+
for (let i = 0; i < candidates.length; i++) {
39+
while (unvotedCount > 0 && !isEqualMoreThan05(langPercentRaw[candidates[i].index]) ) {
40+
langCount[candidates[i].index] += 1
41+
langPercentRaw[candidates[i].index] = getPercentRaw(langCount[candidates[i].index], n)
42+
unvotedCount -= 1
43+
}
44+
45+
langPercentRounded[candidates[i].index] = Math.round(langPercentRaw[candidates[i].index])
46+
}
47+
48+
while (unvotedCount > 0) {
49+
langCount.push(1)
50+
langPercentRaw.push(voteValue)
51+
unvotedCount -= 1
52+
53+
while (unvotedCount > 0 && !isEqualMoreThan05(langPercentRaw[langPercentRaw.length - 1]) ) {
54+
langCount[langCount.length - 1] += 1
55+
langPercentRaw[langPercentRaw.length - 1] = getPercentRaw(langCount[langCount.length - 1], n)
56+
unvotedCount -= 1
57+
}
58+
59+
langPercentRounded.push(Math.round(langPercentRaw[langPercentRaw.length - 1]))
60+
}
61+
62+
return langPercentRounded.reduce((acc, cur) => acc + cur, 0)
63+
}
64+
65+
function isEqualMoreThan05(value) {
66+
return (value - Math.floor(value)) >= 0.5
67+
}
68+
69+
function getPercentRaw(count, n) {
70+
return count / n * 100
71+
}
72+
73+
//
74+
// processCases
75+
//
76+
function processCases(probs) {
77+
for (let index = 0; index < probs.length; index++) {
78+
const result = solve(probs[index])
79+
console.log(`Case #${index + 1}: ${result}`)
80+
}
81+
}
82+
83+
//
84+
// CaseParser
85+
//
86+
class CaseParser {
87+
constructor(caseNumber) {
88+
this.caseNo = caseNumber
89+
90+
this.N = 0
91+
this.L = 0
92+
this.langCount = []
93+
this.langPercentRaw = []
94+
this.langPercentRounded = []
95+
this.votedCount = 0
96+
97+
this.state = '1'
98+
}
99+
100+
readline(line) {
101+
switch (this.state) {
102+
case '1': {
103+
const firstLine = line.split(' ')
104+
this.N = parseInt(firstLine[0])
105+
this.L = parseInt(firstLine[1])
106+
107+
this.state = 'rows'
108+
break
109+
}
110+
111+
case 'rows': {
112+
const chars = line.split(' ')
113+
this.langCount = chars.map(char => parseInt(char))
114+
this.langPercentRaw = this.langCount.map((count) => {
115+
return count / this.N * 100
116+
})
117+
118+
this.langPercentRounded = this.langPercentRaw.map(raw => Math.round(raw))
119+
120+
this.votedCount = this.langCount.reduce((acc, cur) => {
121+
return acc + cur
122+
}, 0)
123+
124+
this.state = 'done'
125+
break
126+
}
127+
}
128+
}
129+
130+
isComplete() {
131+
return (this.state === 'done')
132+
}
133+
134+
getCase() {
135+
return {
136+
caseNo: this.caseNo,
137+
N: this.N,
138+
L: this.L,
139+
langCount: this.langCount,
140+
langPercentRaw: this.langPercentRaw,
141+
langPercentRounded: this.langPercentRounded,
142+
votedCount: this.votedCount,
143+
unvotedCount: this.N - this.votedCount,
144+
voteValue: 100 / this.N
145+
}
146+
}
147+
}
148+
149+
//
150+
// ProblemParser
151+
//
152+
class ProblemParser {
153+
constructor() {
154+
this.t = 0
155+
this.currentT = 0
156+
this.cases = []
157+
this.caseParser = new CaseParser(1)
158+
this.state = 't'
159+
}
160+
161+
readline(line) {
162+
switch (this.state) {
163+
case 't': {
164+
this.t = parseInt(line)
165+
this.state = 'case'
166+
break
167+
}
168+
169+
case 'case': {
170+
this.caseParser.readline(line)
171+
172+
if (this.caseParser.isComplete()) {
173+
this.cases.push(this.caseParser.getCase())
174+
this.currentT += 1
175+
this.caseParser = new CaseParser(this.currentT + 1)
176+
}
177+
178+
break
179+
}
180+
}
181+
182+
if (this.currentT === this.t) {
183+
this.state = 'done'
184+
}
185+
}
186+
187+
isComplete() {
188+
return (this.state === 'done')
189+
}
190+
191+
getCases() {
192+
return this.cases
193+
}
194+
}
195+
196+
//
197+
// Main
198+
//
199+
function main() {
200+
const readline = require('readline')
201+
const problemParser = new ProblemParser()
202+
203+
const rl = readline.createInterface({
204+
input: process.stdin,
205+
output: process.stdout
206+
})
207+
208+
rl.on('line', (line) => {
209+
problemParser.readline(line)
210+
211+
if (problemParser.isComplete()) {
212+
rl.close()
213+
}
214+
}).on('close', () => {
215+
processCases(problemParser.getCases())
216+
}
217+
)
218+
}
219+
220+
if (!module.parent) {
221+
main()
222+
}
223+
224+
module.exports = {
225+
solve,
226+
CaseParser
227+
}
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
const {solve, CaseParser} = require('./solution')
2+
3+
test('1', () => {
4+
const caseParser = new CaseParser(1)
5+
caseParser.readline('3 2')
6+
caseParser.readline('1 1')
7+
8+
const result = solve(caseParser.getCase())
9+
10+
expect(result).toBe(100)
11+
})
12+
13+
test('2', () => {
14+
const caseParser = new CaseParser(2)
15+
caseParser.readline('10 3')
16+
caseParser.readline('1 3 2')
17+
18+
const result = solve(caseParser.getCase())
19+
20+
expect(result).toBe(100)
21+
})
22+
23+
test('3', () => {
24+
const caseParser = new CaseParser(3)
25+
caseParser.readline('6 2')
26+
caseParser.readline('3 1')
27+
28+
const result = solve(caseParser.getCase())
29+
30+
expect(result).toBe(101)
31+
})
32+
33+
test('4', () => {
34+
const caseParser = new CaseParser(4)
35+
caseParser.readline('9 8')
36+
caseParser.readline('1 1 1 1 1 1 1 1')
37+
38+
const result = solve(caseParser.getCase())
39+
40+
expect(result).toBe(99)
41+
})
42+
43+
44+
test('5', () => {
45+
const caseParser = new CaseParser(5)
46+
caseParser.readline('9 4')
47+
caseParser.readline('1 1 1 1')
48+
49+
const result = solve(caseParser.getCase())
50+
51+
expect(result).toBe(100)
52+
})
53+
54+
55+
test('6', () => {
56+
const caseParser = new CaseParser(6)
57+
caseParser.readline('2 1')
58+
caseParser.readline('1')
59+
60+
const result = solve(caseParser.getCase())
61+
62+
expect(result).toBe(100)
63+
})
64+
65+
66+
test('7', () => {
67+
const caseParser = new CaseParser(7)
68+
caseParser.readline('3 1')
69+
caseParser.readline('1')
70+
71+
const result = solve(caseParser.getCase())
72+
73+
expect(result).toBe(100)
74+
})

0 commit comments

Comments
 (0)