Skip to content
This repository was archived by the owner on Feb 26, 2020. It is now read-only.

Commit 01326c1

Browse files
committed
initial commit
0 parents  commit 01326c1

File tree

237 files changed

+26459
-0
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

237 files changed

+26459
-0
lines changed

.gitignore

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
.*.swp
2+
.DS_Store
3+
tmp
4+
.sass-cache
5+
public/codemirror*
6+
public/mathjax*
7+
public/stylesheets
8+
*.rdb
9+
unicorn

DbInit/dbinit.rb

+93
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
#!/usr/bin/env ruby
2+
require "json"
3+
require "fileutils"
4+
5+
require "redis"
6+
require "redis-namespace"
7+
8+
# monkey patch on Ruby Hash
9+
class Hash
10+
def symbolize_keys!
11+
# ref. http://stackoverflow.com/questions/8379596
12+
self.keys.each do |k|
13+
ks = k.respond_to?(:to_sym) ? k.to_sym : k
14+
self[ks] = self.delete k # Preserve order even when k == ks
15+
self[ks].symbolize_keys! if self[ks].kind_of? Hash
16+
end
17+
self
18+
end
19+
end
20+
21+
# database connection
22+
$redis_conn = Redis.new(:thread_safe => true)
23+
$redis = Redis::Namespace.new(:linguist, :redis => $redis_conn)
24+
25+
# select & flush database
26+
$redis.select(0)
27+
$redis.flushdb
28+
29+
# remove tmp
30+
tmpdir_path = File.join(File.dirname(__FILE__), "..", "tmp")
31+
FileUtils.rm_rf(Dir.glob(File.join(tmpdir_path, "*")))
32+
33+
# create global tasks
34+
tasks = JSON.parse(File.read("tasks.json")).map(&:symbolize_keys!)
35+
tasks.each do |task_meta|
36+
text_path = File.join(File.dirname(__FILE__), task_meta[:filename])
37+
text = File.read(text_path).force_encoding(Encoding::UTF_8)
38+
task = {
39+
:id => task_meta[:id],
40+
:title => task_meta[:title],
41+
:initial_text => text
42+
}
43+
redis_key = "tasks:#{task[:id]}"
44+
task.each do |field, value|
45+
$redis.hset(redis_key, field, value)
46+
end
47+
end
48+
49+
# country: ISO Country Codes (e.g. TWN)
50+
# lang: IETF Language Tag (e.g. zh-TW)
51+
52+
# create users
53+
users_data = JSON.parse(File.read("users.json")).symbolize_keys!
54+
default_user = users_data[:default_user].symbolize_keys!
55+
users = users_data[:users].map(&:symbolize_keys!)
56+
users.each do |user_data|
57+
user = default_user.clone
58+
user_data.each do |field, value|
59+
user[field] = value
60+
end
61+
user[:username].downcase!
62+
63+
redis_key = "users:#{user[:username]}"
64+
user.each do |field, value|
65+
$redis.hset(redis_key, field, value)
66+
end
67+
68+
# initialize tasks
69+
tasks_keys = $redis.keys("tasks:*").select{|k| k.count(":") == 1}
70+
tasks_keys.each do |task_key|
71+
task_id = task_key.split(":")[1]
72+
task_text = $redis.hget(task_key, :initial_text)
73+
redis_key = "users:#{user[:username]}:tasks:#{task_id}:revisions"
74+
$redis.rpush(redis_key, {
75+
:text => task_text,
76+
:created_at => Time.now.strftime("%s.%L"),
77+
:created_from => "127.0.0.1"
78+
}.to_json)
79+
end
80+
end
81+
82+
# initialize ISC releases
83+
tasks_keys = $redis.keys("tasks:*").select{|k| k.count(":") == 1}
84+
tasks_keys.each do |task_key|
85+
task_id = task_key.split(":")[1]
86+
redis_key = "users:isc:tasks:#{task_id}:releases"
87+
$redis.rpush(redis_key, {
88+
:revision_num => 0,
89+
:note => 'initial commit',
90+
:created_at => Time.now.strftime("%s.%L"),
91+
:created_from => '127.0.0.1'
92+
}.to_json)
93+
end

DbInit/dump_users.rb

+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
#!/usr/bin/env ruby
2+
require "json"
3+
require "fileutils"
4+
5+
require "redis"
6+
require "redis-namespace"
7+
8+
# monkey patch on Ruby Hash
9+
class Hash
10+
def symbolize_keys!
11+
# ref. http://stackoverflow.com/questions/8379596
12+
self.keys.each do |k|
13+
ks = k.respond_to?(:to_sym) ? k.to_sym : k
14+
self[ks] = self.delete k # Preserve order even when k == ks
15+
self[ks].symbolize_keys! if self[ks].kind_of? Hash
16+
end
17+
self
18+
end
19+
end
20+
21+
# dump users
22+
users = JSON.parse(File.read("users.json")).symbolize_keys![:users]
23+
users.each do |user|
24+
user.symbolize_keys!
25+
fields = [:username, :password, :lang]
26+
puts fields.map{|f| %Q{"#{user[f]}"}}.join(",")
27+
end

DbInit/friends.md

+84
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
# Friends
2+
3+
We build a social network from \\(n\\) people numbered 0, ... , \\(n - 1\\). Some pairs of people in the network will be friends. If person \\(x\\) becomes a friend of person \\(y\\), then person \\(y\\) also becomes a friend of person \\(x\\).
4+
5+
The people are added to the network in \\(n\\) stages, which are also numbered from \\(0\\) to \\(n-1\\). Person \\(i\\) is added in stage \\(i\\). In stage 0, person 0 is added as the only person of the network. In each of the next \\(n - 1\\) stages, a person is added to the network by a *host*, who may be any person already in the network. At stage \\(i\\) (\\(0 < i < n\\)), the host for that stage can add the incoming person \\(i\\) into the network by one of the following three protocols:
6+
7+
* *IamYourFriend* makes person \\(i\\) a friend of the host only.
8+
9+
* *MyFriendsAreYourFriends* makes person \\(i\\) a friend of *each* friend of the host. Note that this protocol does *not* make person \\(i\\) a friend of the host.
10+
11+
* *WeAreYourFriends* makes person \\(i\\) a friend of the host, and also a friend of *each* friend of the host.
12+
13+
After we build the network we would like to pick a *sample* for a survey, that is, choose a group of people from the network. Since friends usually have similar interests, the sample should not include any pair of people who are friends with each other. Each person has a survey *confidence*, expressed as a positive integer, and we would like to find a sample with the maximum total confidence.
14+
15+
## Example
16+
17+
| stage | host | protocol | friend relations added |
18+
| ----- | ---- | -------- | ---------------------- |
19+
| 1 | 0 | IamYourFriend | (1, 0) |
20+
| 2 | 0 | MyFriendsAreYourFriends | (2, 1) |
21+
| 3 | 1 | WeAreYourFriends | (3, 1), (3, 0), (3, 2) |
22+
| 4 | 2 | MyFriendsAreYourFriends | (4, 1), (4, 3) |
23+
|5 | 0 | IamYourFriend | (5, 0) |
24+
25+
26+
Initially the network contains only person 0. The host of stage 1 (person 0) invites the new person 1 through the IamYourFriend protocol, hence they become friends. The host of stage 2 (person 0 again) invites person 2 by MyFriendsAreYourFriends, which makes person 1 (the only friend of the host) the only friend of person 2. The host of stage 3 (person 1) adds person 3 through WeAreYourFriends, which makes person 3 a friend of person 1 (the host) and people 0 and 2 (the friends of the host). Stages 4 and 5 are also shown in the table above. The final network is shown in the following figure, in which the numbers inside the circles show the labels of people, and the numbers next to the circles show the survey confidence. The sample consisting of people 3 and 5 has total survey confidence equal to 20 + 15 = 35, which is the maximum possible total confidence.
27+
28+
![](/assets/tasks/friend.png)
29+
30+
## Task
31+
32+
Given the description of each stage and the confidence value of each person, find a sample with the maximum total confidence. You only need to implement the function `findSample`.
33+
34+
* `findSample(n, confidence, host, protocol)`
35+
* `n`: the number of people.
36+
* `confidence`: array of length \\(n\\); `confidence[i]` gives the confidence value of person \\(i\\).
37+
* `host`: array of length \\(n\\); `host[i]` gives the host of stage \\(i\\).
38+
* `protocol`: array of length \\(n\\); `protocol[i]` gives the protocol code used in stage \\(i\\) (\\(0 < i < n\\)): 0 for IamYourFriend, 1 for MyFriendsAreYourFriends, and 2 for WeAreYourFriends.
39+
* Since there is no host in stage 0, `host[0]` and `protocol[0]` are undefined and should not be accessed by your program.
40+
* The function should return the maximum possible total confidence of a sample.
41+
42+
## Subtasks
43+
44+
Some subtasks use only a subset of protocols, as shown in the following table.
45+
46+
| subtask | points | \\(n\\) | confidence | protocols used |
47+
| ------- | ------ | ------- | ---------- | ---- |
48+
| 1 | 11 | \\(2 \leq n \leq 10\\) | \\(1 \leq \mbox{confidence} \leq 1,000,000\\) | All three protocols |
49+
| 2 | 8 | \\(2 \leq n \leq 1,000\\) | \\(1 \leq \mbox{confidence} \leq 1,000,000\\) | Only MyFriendsAreYourFriends |
50+
| 3 | 8 | \\(2 \leq n \leq 1,000\\) | \\(1 \leq \mbox{confidence} \leq 1,000,000\\) | Only WeAreYourFriends |
51+
| 4 | 19 | \\(2 \leq n \leq 1,000\\) | \\(1 \leq \mbox{confidence} \leq 1,000,000\\) | Only IamYourFriend |
52+
| 5 | 23 | \\(2 \leq n \leq 1,000\\) | All confidence values are 1 | Both MyFriendsAreYourFriends and IamYourFriend |
53+
| 6 | 31 | \\(2 \leq n \leq 100,000\\) | \\(1 \leq \mbox{confidence} \leq 10,000\\) | All three protocols |
54+
55+
<br><br>
56+
## Implementation details
57+
58+
You have to submit exactly one file, called `friend.c`, `friend.cpp` or `friend.pas`. This file should implement the subprogram described above, using the following signatures. You also need to include a header file `friend.h` for C/C++ implementation.
59+
60+
### C/C++ program
61+
62+
```
63+
int findSample(int n, int confidence[], int host[], int protocol[]);
64+
```
65+
66+
### Pascal programs
67+
68+
```
69+
function findSample(n: longint, confidence: array of longint, host: array
70+
of longint; protocol: array of longint): longint;
71+
```
72+
73+
74+
### Sample grader
75+
76+
The sample grader reads the input in the following format:
77+
78+
* line 1: `n`
79+
* line 2: `confidence[0]`, ..., `confidence[n-1]`
80+
* line 3: `host[1]`, `protocol[1]`, `host[2]`, `protocol[2]`, ..., `host[n-1]`, `protocol[n-1]`
81+
82+
The sample grader will print the return value of `findSample`.
83+
84+

DbInit/genpwd.rb

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
#!/usr/bin/env ruby
2+
3+
def make_password (len=6)
4+
chars = "ABCDEFGHJKLMNPQRTUVWXYZ2346789".split(//)
5+
result = ""; len.times { result += chars.sample }
6+
result
7+
end
8+
9+
outputs = []
10+
11+
users_path = File.join(File.dirname(__FILE__), "users.json")
12+
lines = File.read(users_path).split(/\n/)
13+
lines.each do |line|
14+
if line =~ /"password":/
15+
line = line.gsub('"password":""', %Q{"password":"#{make_password}"})
16+
end
17+
outputs << line
18+
end
19+
20+
puts outputs.join("\n")

DbInit/gondola.md

+134
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
1+
# Gondola
2+
3+
Mao-Kong Gondola is a famous attraction in Taipei. The gondola system consists of a circular rail, a single station, and \\(n\\) gondolas numbered consecutively from 1 to \\(n\\) running around the rail in a fixed direction. Initially after gondola \\(i\\) passes the station, the next gondola to pass the station will be gondola \\(i+1\\) if \\(i < n\\), or gondola 1 if \\(i=n\\).
4+
5+
Gondolas may break down. Luckily we have an infinite supply of spare gondolas, which are numbered \\(n + 1\\), \\(n + 2\\), and so on. When a gondola breaks down we replace it (in the same position on the track) with the first available spare gondola, that is, the one with the lowest number. For example, if there are five gondolas and gondola 1 breaks down, then we will replace it with gondola 6.
6+
7+
You like to stand at the station and watch the gondolas as they pass by. A *gondola sequence* is a series of \\(n\\) numbers of gondolas that pass the station. It is possible that one or more gondolas broke down (and were replaced) before you arrived, but none of the gondolas break down while you are watching.
8+
9+
Note that the same configuration of gondolas on the rail can give multiple gondola sequences, depending on which gondola passes first when you arrive at the station. For example, if none of the gondolas have broken down then both (2, 3, 4, 5, 1) and (4, 5, 1, 2, 3) are possible gondola sequences, but (4, 3, 2, 5, 1) is not (because the gondolas appear in the wrong order).
10+
11+
If gondola 1 breaks down, then we might now observe the gondola sequence (4, 5, 6, 2, 3). If gondola 4 breaks down next, we replace it with gondola 7 and we might observe the gondola sequence (6, 2, 3, 7, 5). If gondola 7 breaks down after this, we replace it with gondola 8 and we may now observe the gondola sequence (3, 8, 5, 6, 2).
12+
13+
| broken gondola | new gondola | possible gondola sequence |
14+
| ---------------- | ---------------- | ----------------- |
15+
| 1 | 6 | (4, 5, 6, 2, 3) |
16+
| 4 | 7 | (6, 2, 3, 7, 5) |
17+
| 7 | 8 | (3, 8, 5, 6, 2) |
18+
19+
A *replacement sequence* is a sequence consisting of the numbers of the gondolas that have broken down, in the order in which they break down. In the previous example the replacement sequence is (1, 4, 7). A replacement sequence \\(r\\) *produces* a gondola sequence \\(g\\) if, after gondolas break down according to the replacement sequence \\(r\\), the gondola sequence \\(g\\) may be observed.
20+
21+
22+
## Gondola Sequence Checking
23+
24+
In the first three subtasks you must check whether an input sequence is a gondola sequence. See the table below for examples of sequences that are and are not gondola sequences. You need to implement a function `valid`.
25+
<br>
26+
27+
* `valid(n, inputSeq)`
28+
* `n`: the length of the input sequence.
29+
* `inputSeq`: array of length \\(n\\); `inputSeq[i]` is element \\(i\\) of the input sequence, for \\(0 \leq i \leq n - 1\\).
30+
* The function should return 1 if the input sequence is a gondola sequence, or 0 otherwise.
31+
32+
### Subtasks 1, 2, 3
33+
34+
| subtask | points | \\(n\\) | `inputSeq` |
35+
| ------- | ------ | ------- | ----- |
36+
| 1 | 5 | \\(n \leq 100\\) | has each number from 1 to \\(n\\) exactly once |
37+
| 2 | 5 | \\(n \leq 100,000\\) | \\(1 \leq\\) `inputSeq[i]` \\(\leq n\\) |
38+
| 3 | 10 | \\(n \leq 100,000\\) | \\(1 \leq\\) `inputSeq[i]` \\(\leq 250,000\\) |
39+
40+
<br><br>
41+
### Examples
42+
43+
| subtask | `inputSeq` | return value | note |
44+
| ----- | ----- | ----- | ----- |
45+
| 1 | (1, 2, 3, 4, 5, 6, 7) | 1 | |
46+
| 1 | (3, 4, 5, 6, 1, 2) | 1 | |
47+
| 1 | (1, 5, 3, 4, 2, 7, 6) | 0 | 1 cannot appear just before 5 |
48+
| 1 | (4, 3, 2, 1) | 0 | 4 cannot appear just before 3 |
49+
| 2 | (1, 2, 3, 4, 5, 6, 5) | 0 | two gondolas numbered 5 |
50+
| 3 | (2, 3, 4, 9, 6, 7, 1) | 1 | replacement sequence (5, 8) |
51+
| 3 | (10, 4, 3, 11, 12) | 0 | 4 cannot appear just before 3 |
52+
53+
## Replacement Sequence
54+
55+
In the next three subtasks you must construct a possible replacement sequence that produces a given gondola sequence. Any such replacement sequence will be accepted. You need to implement a function `replacement`.
56+
57+
* `replacement(n, gondolaSeq, replacementSeq)`
58+
* `n` is the length of the gondola sequence.
59+
* `gondolaSeq`: array of length \\(n\\); `gondolaSeq` is guaranteed to be a gondola sequence, and `gondolaSeq[i]` is element \\(i\\) of the sequence, for \\(0 \leq i \leq n - 1\\).
60+
* The function should return \\(l\\), the length of the replacement sequence.
61+
* `replacementSeq`: array that is sufficiently large to store the replacement sequence; you should return your sequence by placing element \\(i\\) of your replacement sequence into `replacementSeq[i]`, for \\(0 \leq i \leq l - 1\\).
62+
63+
### Subtasks 4, 5, 6
64+
65+
| subtask | points | \\(n\\) | `gondolaSeq` |
66+
| ------- | ------ | ------- | ----- |
67+
| 4 | 5 | \\(n \leq 100\\) | \\(1 \leq\\) `gondolaSeq[i]` \\(\leq n + 1\\) |
68+
| 5 | 10 | \\(n \leq 1,000\\) | \\(1 \leq\\) `gondolaSeq[i]` \\(\leq 5,000\\) |
69+
| 6 | 20 | \\(n \leq 100,000\\) | \\(1 \leq\\) `gondolaSeq[i]` \\(\leq 250,000\\) |
70+
71+
### Examples
72+
73+
| subtask | `gondolaSeq` | return value | `replacementSeq` |
74+
| ----- | ----- | ----- | ----- |
75+
| 4 | (3, 1, 4) | 1 | (2) |
76+
| 4 | (5, 1, 2, 3, 4) | 0 | ( ) |
77+
| 5 | (2, 3, 4, 9, 6, 7, 1) | 2 | (5, 8) |
78+
79+
## Count Replacement Sequences
80+
81+
In the next four subtasks you must count the number of possible replacement sequences that produce a given sequence (which may or may not be a gondola sequence), modulo <strong>1,000,000,009</strong>. You need to implement a function `countReplacement`.
82+
83+
* `countReplacement(n, inputSeq)`
84+
* `n`: the length of the input sequence.
85+
* `inputSeq`: array of length \\(n\\); `inputSeq[i]` is element \\(i\\) of the input sequence, for \\(0 \leq i \leq n - 1\\).
86+
* If the input sequence is a gondola sequence, then count the number of replacement sequences that produce this gondola sequence (which could be extremely large), *and return this number modulo <strong>1,000,000,009</strong>*. If the input sequence is not a gondola sequence, the function should return 0. If the input sequence is a gondola sequence but no gondolas broke down, the function should return 1.
87+
88+
### Subtasks 7, 8, 9, 10
89+
90+
| subtask | points | \\(n\\) | `inputSeq` |
91+
| ------- | ------ | ------- | ----- |
92+
| 7 | 5 | \\(4 \leq n \leq 50\\) | \\(1 \leq\\) `inputSeq[i]` \\(\leq n + 3\\)
93+
| 8 | 15 | \\(4 \leq n \leq 50\\) | \\(1 \leq\\) `inputSeq[i]` \\(\leq 100\\), and at least \\(n - 3\\) of the initial gondolas \\(1,\ldots,n\\) did not break down. |
94+
| 9 | 15 | \\(n \leq 100,000\\) | \\(1 \leq\\) `inputSeq[i]` \\(\leq 250,000\\) |
95+
| 10 | 10 | \\(n \leq 100,000\\) | \\(1 \leq\\) `inputSeq[i]` \\(\leq 1,000,000,000\\) |
96+
97+
### Examples
98+
99+
| subtask | `inputSeq` | return value | replacement sequence |
100+
| ----- | ----- | ----- | ----- |
101+
| 7 | (1, 2, 7, 6) | 2 | (3, 4, 5) or (4, 5, 3) |
102+
| 8 | (2, 3, 4, 12, 6, 7, 1) | 1 | (5, 8, 9, 10, 11) |
103+
| 9 | (4, 7, 4, 7) | 0 | `inputSeq` is not a gondola sequence |
104+
| 10 | (3, 4) | 2 | (1, 2) or (2, 1) |
105+
106+
## Implementation details
107+
108+
You have to submit exactly one file, called `gondola.c`, `gondola.cpp` or `gondola.pas`. This file should implement the subprograms described above, using the following signatures. You also need to include a header file `gondola.h` for C/C++ implementation.
109+
110+
### C/C++ programs
111+
112+
```
113+
int valid(int n, int inputSeq[]);
114+
int replacement(int n, int gondolaSeq[], int replacementSeq[]);
115+
int countReplacement(int n, int inputSeq[]);
116+
```
117+
118+
### Pascal programs
119+
120+
```
121+
function valid(n: longint; inputSeq: array of longint): integer;
122+
function replacement(n: longint; gondolaSeq: array of longint;
123+
var replacementSeq: array of longint): longint;
124+
function countReplacement(n: longint; inputSeq: array of longint):
125+
longint;
126+
```
127+
128+
### Sample grader
129+
130+
The sample grader reads the input in the following format:
131+
132+
* line 1: `T`, the subtask number your program intends to solve (\\(1 \leq T \leq 10\\)).
133+
* line 2: `n`, the length of the input sequence.
134+
* line 3: If `T` is 4, 5, or 6, this line contains `inputSeq[0]`, ..., `inputSeq[n-1]`. Otherwise this line contains `gondolaSeq[0]`, ..., `gondolaSeq[n-1]`.

0 commit comments

Comments
 (0)