View Problem
Separate user interaction and computation.
Allow your program to accept user interaction while conducting a long running computation.
Example:
Hello user! Please input a string to permute: (input thread)
abcdef
Passing on abcdef... (input thread)
Please input another string to permute: (input thread)
lol
Passing on lol... (input thread)
Done Work On abcdef! (worker thread)
Please input another string to permute: (input thread)
EXIT
Quitting, I
--Notice, that this could be accomplished on the command line or within a GUI. The point is that computation and user interaction should take place on separate threads of control.
Submit a new solution for python, clojure, or cpp
There are 6 other solutions in additional languages (fantom, fsharp, groovy, java ...)
Example:
Hello user! Please input a string to permute: (input thread)
abcdef
Passing on abcdef... (input thread)
Please input another string to permute: (input thread)
lol
Passing on lol... (input thread)
Done Work On abcdef! (worker thread)
["abcdef", "abcefd", ... ] (worker thread)
Please input another string to permute: (input thread)
EXIT
Quitting, I
'll let my worker thread know... (input thread)
We're quitting! Alright! (worker thread)
--Notice, that this could be accomplished on the command line or within a GUI. The point is that computation and user interaction should take place on separate threads of control.
clojure
(defn background-computation [_ s]
(let [res (permutations s)]
(println (format "Done Work On %s!" s))
(println res)))
(defn shutdown-app [_]
(println "We're quitting! Alright!")
(shutdown-agents))
(println "Hello user! Please input a string to permute: ")
(let [worker-agent (agent nil)]
(loop [input (str (read))]
(if (= input "EXIT")
(do (println "Quitting, I'll let my worker thread know...")
(send worker-agent shutdown-app))
(do (println (format "Passing on %s..." input))
(send worker-agent background-computation input)
(println "Please input another string to permute: ")
(recur (str (read)))))))
(let [res (permutations s)]
(println (format "Done Work On %s!" s))
(println res)))
(defn shutdown-app [_]
(println "We're quitting! Alright!")
(shutdown-agents))
(println "Hello user! Please input a string to permute: ")
(let [worker-agent (agent nil)]
(loop [input (str (read))]
(if (= input "EXIT")
(do (println "Quitting, I'll let my worker thread know...")
(send worker-agent shutdown-app))
(do (println (format "Passing on %s..." input))
(send worker-agent background-computation input)
(println "Please input another string to permute: ")
(recur (str (read)))))))
cpp
class bg_worker
{
mutex bg_mutex_;
condition_variable work_present_;
deque<string> work_queue_;
result calc_perm(string s) {
result perms = result(new list<string>());
// sleep to simulate lots of work...
this_thread::sleep(posix_time::seconds(3));
sort(s.begin(), s.end());
do {
perms->push_back(s);
} while (next_permutation(s.begin(), s.end()));
return perms;
}
public:
void submit_work(const string &s) {
lock_guard<mutex> lock(bg_mutex_);
work_queue_.push_back(s);
work_present_.notify_one();
}
void operator()() {
for (;;) {
unique_lock<mutex> lock(bg_mutex_);
while (work_queue_.empty())
work_present_.wait(lock);
string s = work_queue_.front();
work_queue_.pop_front();
lock.unlock();
if (s == "EXIT") {
lock_guard<mutex> cout_lock(cout_mutex);
cout << "We're quitting! Alright!" << endl;
break;
}
result perm = calc_perm(s);
lock_guard<mutex> cout_lock(cout_mutex);
cout << "Done Work On " << s << "!" << endl;
cout << perm << endl;
}
}
};
int main()
{
bg_worker worker;
thread bg_thr(boost::ref(worker));
bool done = false;
{
lock_guard<mutex> cout_lock(cout_mutex);
cout << "Hello user! Please input a string to permute:" << endl;
}
while (!done)
{
string input;
cin >> input;
{
lock_guard<mutex> cout_lock(cout_mutex);
if (input == "EXIT") {
cout << "Quitting, I'll let my worker thread know..." << endl;
done = true;
} else {
cout << "Passing on " << input << "..." << endl;
cout << "Please input another string to permute:" << endl;
}
}
worker.submit_work(input);
}
bg_thr.join();
}
{
mutex bg_mutex_;
condition_variable work_present_;
deque<string> work_queue_;
result calc_perm(string s) {
result perms = result(new list<string>());
// sleep to simulate lots of work...
this_thread::sleep(posix_time::seconds(3));
sort(s.begin(), s.end());
do {
perms->push_back(s);
} while (next_permutation(s.begin(), s.end()));
return perms;
}
public:
void submit_work(const string &s) {
lock_guard<mutex> lock(bg_mutex_);
work_queue_.push_back(s);
work_present_.notify_one();
}
void operator()() {
for (;;) {
unique_lock<mutex> lock(bg_mutex_);
while (work_queue_.empty())
work_present_.wait(lock);
string s = work_queue_.front();
work_queue_.pop_front();
lock.unlock();
if (s == "EXIT") {
lock_guard<mutex> cout_lock(cout_mutex);
cout << "We're quitting! Alright!" << endl;
break;
}
result perm = calc_perm(s);
lock_guard<mutex> cout_lock(cout_mutex);
cout << "Done Work On " << s << "!" << endl;
cout << perm << endl;
}
}
};
int main()
{
bg_worker worker;
thread bg_thr(boost::ref(worker));
bool done = false;
{
lock_guard<mutex> cout_lock(cout_mutex);
cout << "Hello user! Please input a string to permute:" << endl;
}
while (!done)
{
string input;
cin >> input;
{
lock_guard<mutex> cout_lock(cout_mutex);
if (input == "EXIT") {
cout << "Quitting, I'll let my worker thread know..." << endl;
done = true;
} else {
cout << "Passing on " << input << "..." << endl;
cout << "Please input another string to permute:" << endl;
}
}
worker.submit_work(input);
}
bg_thr.join();
}
Submit a new solution for python, clojure, or cpp
There are 6 other solutions in additional languages (fantom, fsharp, groovy, java ...)




