Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Merge branch 'release/0.1.2'

  • Loading branch information...
commit fb4865608ec59d9217a2b284e50eeea1a1676963 2 parents 2de3c18 + bc90149
Alan Malloy amalloy authored
9 README.md
View
@@ -38,10 +38,11 @@ vaguely like this:
## Contributors
- * David Byrne <david.r.byrne@gmail.com>
- * Alan Malloy
- * Anthony Grimes
- * Carin Meier
+ * David Byrne (dbyrne)
+ * Alan Malloy (amalloy)
+ * Anthony Grimes (raynes)
+ * Carin Meier (cmeier)
+ * Clint Harrison
Problem sources:
2  project.clj
View
@@ -1,4 +1,4 @@
-(defproject foreclojure "0.1.1"
+(defproject foreclojure "0.1.2"
:description "4clojure - a website for lisp beginners"
:dependencies [[org.clojure/clojure "1.2.1"]
[org.clojure/clojure-contrib "1.2.0"]
4 resources/public/css/style.css
View
@@ -66,6 +66,10 @@ a.novisited {color: #00e;}
border-right: 2px solid white;
}
+.contributor {
+ color: #458B00;
+ font-weight: bold;
+}
#login {
border-right: 2px solid white;
3  src/foreclojure/core.clj
View
@@ -1,7 +1,7 @@
(ns foreclojure.core
(:use compojure.core
[foreclojure static problems login register
- users config social]
+ users config social version]
ring.adapter.jetty
somnium.congomongo
[ring.middleware.reload :only [wrap-reload]])
@@ -30,6 +30,7 @@
users-routes
static-routes
social-routes
+ version-routes
(route/resources "/")
(route/not-found "Page not found"))
652 src/foreclojure/data_set.clj
View
@@ -5,83 +5,83 @@
(do
(mongo! :db :mydb)
(insert! :problems
- {:_id 1
- :title "Nothing but the Truth"
- :times-solved 0
- :description "This is a clojure form. Enter a value which will make the form evaluate to true. Don't over think it! If you are confused, see the <a href='/directions'>getting started</a> page."
- :tags ["elementary"]
- :tests ["(= __ true)"]})
-
- (insert! :problems
- {:_id 2
- :title "Simple Math"
- :times-solved 0
- :description "If you are not familiar with <a href='http://en.wikipedia.org/wiki/Polish_notation'>polish notation</a>, simple arithmetic might seem confusing."
- :tags ["elementary"]
- :tests ["(= (- 10 (* 2 3)) __)"]})
-
- (insert! :problems
- {:_id 3
- :title "Intro to Strings"
- :times-solved 0
- :description "Clojure strings are Java strings. This means that you can use any of the Java string methods on Clojure strings."
- :tags["elementary"]
- :tests ["(= __ (.toUpperCase \"hello world\"))"]})
-
-
- (insert! :problems
- {:_id 4
- :title "Intro to Lists"
- :times-solved 0
- :description "Lists can be constructed with either a function or a quoted form."
- :tags["elementary"]
- :tests ["(= (list __) '(:a :b :c))"]})
-
- (insert! :problems
- {:_id 5
- :title "Lists: conj"
- :times-solved 0
- :description "When operating on a list, the conj function will return a new list with one or more items \"added\" to the front."
- :tags["elementary"]
- :tests ["(= __ (conj '(2 3 4) 1))"
- "(= __ (conj '(3 4) 2 1))"]})
-
- (insert! :problems
- {:_id 6
- :title "Intro to Vectors"
- :times-solved 0
- :description "Vectors can be constructed several ways. You can compare them with lists."
- :tags["elementary"]
- :tests ["(= [__] (list :a :b :c) (vec '(:a :b :c)) (vector :a :b :c))"]})
-
- (insert! :problems
- {:_id 7
- :title "Vectors: conj"
- :times-solved 0
- :description "When operating on a Vector, the conj function will return a new vector with one or more items \"added\" to the end."
- :tags["elementary"]
- :tests ["(= __ (conj [1 2 3] 4))"
- "(= __ (conj [1 2] 3 4))"]})
-
-
- (insert! :problems
- {:_id 8
- :title "Intro to Sets"
- :times-solved 0
- :description "Sets are collections of unique values."
- :tags["elementary"]
- :tests ["(= __ (set '(:a :a :b :c :c :c :c :d :d)))"
- "(= __ (clojure.set/union #{:a :b :c} #{:b :c :d}))"]})
-
- (insert! :problems
- {:_id 9
- :title "Sets: conj"
- :times-solved 0
- :description "When operating on a set, the conj function returns a new set with one or more keys \"added\"."
- :tags["elementary"]
- :tests ["(= #{1 2 3 4} (conj #{1 4 3} __))"]})
-
-
+ {:_id 1
+ :title "Nothing but the Truth"
+ :times-solved 0
+ :description "This is a clojure form. Enter a value which will make the form evaluate to true. Don't over think it! If you are confused, see the <a href='/directions'>getting started</a> page."
+ :tags ["elementary"]
+ :tests ["(= __ true)"]})
+
+ (insert! :problems
+ {:_id 2
+ :title "Simple Math"
+ :times-solved 0
+ :description "If you are not familiar with <a href='http://en.wikipedia.org/wiki/Polish_notation'>polish notation</a>, simple arithmetic might seem confusing."
+ :tags ["elementary"]
+ :tests ["(= (- 10 (* 2 3)) __)"]})
+
+ (insert! :problems
+ {:_id 3
+ :title "Intro to Strings"
+ :times-solved 0
+ :description "Clojure strings are Java strings. This means that you can use any of the Java string methods on Clojure strings."
+ :tags["elementary"]
+ :tests ["(= __ (.toUpperCase \"hello world\"))"]})
+
+
+ (insert! :problems
+ {:_id 4
+ :title "Intro to Lists"
+ :times-solved 0
+ :description "Lists can be constructed with either a function or a quoted form."
+ :tags["elementary"]
+ :tests ["(= (list __) '(:a :b :c))"]})
+
+ (insert! :problems
+ {:_id 5
+ :title "Lists: conj"
+ :times-solved 0
+ :description "When operating on a list, the conj function will return a new list with one or more items \"added\" to the front."
+ :tags["elementary"]
+ :tests ["(= __ (conj '(2 3 4) 1))"
+ "(= __ (conj '(3 4) 2 1))"]})
+
+ (insert! :problems
+ {:_id 6
+ :title "Intro to Vectors"
+ :times-solved 0
+ :description "Vectors can be constructed several ways. You can compare them with lists."
+ :tags["elementary"]
+ :tests ["(= [__] (list :a :b :c) (vec '(:a :b :c)) (vector :a :b :c))"]})
+
+ (insert! :problems
+ {:_id 7
+ :title "Vectors: conj"
+ :times-solved 0
+ :description "When operating on a Vector, the conj function will return a new vector with one or more items \"added\" to the end."
+ :tags["elementary"]
+ :tests ["(= __ (conj [1 2 3] 4))"
+ "(= __ (conj [1 2] 3 4))"]})
+
+
+ (insert! :problems
+ {:_id 8
+ :title "Intro to Sets"
+ :times-solved 0
+ :description "Sets are collections of unique values."
+ :tags["elementary"]
+ :tests ["(= __ (set '(:a :a :b :c :c :c :c :d :d)))"
+ "(= __ (clojure.set/union #{:a :b :c} #{:b :c :d}))"]})
+
+ (insert! :problems
+ {:_id 9
+ :title "Sets: conj"
+ :times-solved 0
+ :description "When operating on a set, the conj function returns a new set with one or more keys \"added\"."
+ :tags["elementary"]
+ :tests ["(= #{1 2 3 4} (conj #{1 4 3} __))"]})
+
+
(insert! :problems
{:_id 10
:title "Intro to Maps"
@@ -90,44 +90,44 @@
:tags["elementary"]
:tests ["(= __ ((hash-map :a 10, :b 20, :c 30) :b))"
"(= __ (:b {:a 10, :b 20, :c 30}))"]})
-
- (insert! :problems
- {:_id 11
- :title "Maps: conj"
- :times-solved 0
- :description "When operating on a map, the conj function returns a new map with one or more key-value pairs \"added\"."
- :tags["elementary"]
- :tests ["(= {:a 1, :b 2, :c 3} (conj {:a 1} __ [:c 3]))"]})
-
- (insert! :problems
- {:_id 12
- :title "Intro to Sequences"
- :times-solved 0
- :description "All Clojure collections support sequencing. You can operate on sequences with functions like first, second, and last."
- :tags["elementary"]
- :tests ["(= __ (first '(3 2 1)))"
- "(= __ (second [2 3 4]))"
- "(= __ (last (list 1 2 3)))"]})
-
- (insert! :problems
- {:_id 13
- :title "Sequences: rest"
- :times-solved 0
- :description "The rest function will return all the items of a sequence except the first."
- :tags["elementary"]
- :tests ["(= __ (rest [10 20 30 40]))"]})
-
- (insert! :problems
- {:_id 14
- :title "Intro to Functions"
- :times-solved 0
- :description "Clojure has many different ways to create functions."
- :tags["elementary"]
- :tests ["(= __ ((fn add-five [x] (+ x 5)) 3))"
- "(= __ ((fn [x] (+ x 5)) 3))"
- "(= __ (#(+ % 5) 3))"
- "(= __ ((partial + 5) 3))"]})
-
+
+ (insert! :problems
+ {:_id 11
+ :title "Maps: conj"
+ :times-solved 0
+ :description "When operating on a map, the conj function returns a new map with one or more key-value pairs \"added\"."
+ :tags["elementary"]
+ :tests ["(= {:a 1, :b 2, :c 3} (conj {:a 1} __ [:c 3]))"]})
+
+ (insert! :problems
+ {:_id 12
+ :title "Intro to Sequences"
+ :times-solved 0
+ :description "All Clojure collections support sequencing. You can operate on sequences with functions like first, second, and last."
+ :tags["elementary"]
+ :tests ["(= __ (first '(3 2 1)))"
+ "(= __ (second [2 3 4]))"
+ "(= __ (last (list 1 2 3)))"]})
+
+ (insert! :problems
+ {:_id 13
+ :title "Sequences: rest"
+ :times-solved 0
+ :description "The rest function will return all the items of a sequence except the first."
+ :tags["elementary"]
+ :tests ["(= __ (rest [10 20 30 40]))"]})
+
+ (insert! :problems
+ {:_id 14
+ :title "Intro to Functions"
+ :times-solved 0
+ :description "Clojure has many different ways to create functions."
+ :tags["elementary"]
+ :tests ["(= __ ((fn add-five [x] (+ x 5)) 3))"
+ "(= __ ((fn [x] (+ x 5)) 3))"
+ "(= __ (#(+ % 5) 3))"
+ "(= __ ((partial + 5) 3))"]})
+
(insert! :problems
{:_id 15
:title "Double Down"
@@ -138,45 +138,45 @@
"(= (__ 3) 6)"
"(= (__ 11) 22)"
"(= (__ 7) 14)"]})
-
- (insert! :problems
- {:_id 16
- :title "Hello World"
- :times-solved 0
- :description "Write a function which returns a personalized greeting."
-
- :tags ["elementary"]
- :tests ["(= (__ \"Dave\") \"Hello, Dave!\")"
- "(= (__ \"Jenn\") \"Hello, Jenn!\")"
+
+ (insert! :problems
+ {:_id 16
+ :title "Hello World"
+ :times-solved 0
+ :description "Write a function which returns a personalized greeting."
+
+ :tags ["elementary"]
+ :tests ["(= (__ \"Dave\") \"Hello, Dave!\")"
+ "(= (__ \"Jenn\") \"Hello, Jenn!\")"
"(= (__ \"Rhea\") \"Hello, Rhea!\")"]})
-
- (insert! :problems
- {:_id 17
- :title "Sequences: map"
- :times-solved 0
- :description "The map function takes two arguments: a function (f) and a sequence (s). Map returns a new sequence consisting of the result of applying f to each item of s. Do not confuse the map function with the map data structure."
- :tags["elementary"]
- :tests ["(= __ (map #(+ % 5) '(1 2 3)))"]})
-
- (insert! :problems
- {:_id 18
- :title "Sequences: filter"
- :times-solved 0
- :description "The filter function takes two arguments: a predicate function (f) and a sequence (s). Filter returns a new sequence consisting of all the items of s for which (f item) returns true."
- :tags["elementary"]
- :tests ["(= __ (filter #(> % 5) '(3 4 5 6 7)))"]})
-
- (insert! :problems
- {:_id 19
- :title "Last Element"
- :times-solved 0
- :restricted ["last"]
- :description "Write a function which returns the last element in a sequence."
- :tags ["easy" "seqs" "core-functions"]
- :tests ["(= (__ [1 2 3 4 5]) 5)"
- "(= (__ '(5 4 3)) 3)"
+
+ (insert! :problems
+ {:_id 17
+ :title "Sequences: map"
+ :times-solved 0
+ :description "The map function takes two arguments: a function (f) and a sequence (s). Map returns a new sequence consisting of the result of applying f to each item of s. Do not confuse the map function with the map data structure."
+ :tags["elementary"]
+ :tests ["(= __ (map #(+ % 5) '(1 2 3)))"]})
+
+ (insert! :problems
+ {:_id 18
+ :title "Sequences: filter"
+ :times-solved 0
+ :description "The filter function takes two arguments: a predicate function (f) and a sequence (s). Filter returns a new sequence consisting of all the items of s for which (f item) returns true."
+ :tags["elementary"]
+ :tests ["(= __ (filter #(> % 5) '(3 4 5 6 7)))"]})
+
+ (insert! :problems
+ {:_id 19
+ :title "Last Element"
+ :times-solved 0
+ :restricted ["last"]
+ :description "Write a function which returns the last element in a sequence."
+ :tags ["easy" "seqs" "core-functions"]
+ :tests ["(= (__ [1 2 3 4 5]) 5)"
+ "(= (__ '(5 4 3)) 3)"
"(= (__ [\"b\" \"c\" \"d\"]) \"d\")"]})
-
+
(insert! :problems
{:_id 20
:title "Penultimate Element"
@@ -186,163 +186,163 @@
:tests ["(= (__ (list 1 2 3 4 5)) 4)"
"(= (__ [\"a\" \"b\" \"c\"]) \"b\")"
"(= (__ [[1 2] [3 4]]) [1 2])"]})
-
- (insert! :problems
- {:_id 21
- :title "Nth Element"
- :times-solved 0
- :restricted ["nth"]
- :description "Write a function which returns the Nth element from a sequence."
- :tags["easy" "seqs" "core-functions"]
- :tests ["(= (__ '(4 5 6 7) 2) 6)"
- "(= (__ [:a :b :c] 0) :a)"
- "(= (__ [1 2 3 4] 1) 2)"
+
+ (insert! :problems
+ {:_id 21
+ :title "Nth Element"
+ :times-solved 0
+ :restricted ["nth"]
+ :description "Write a function which returns the Nth element from a sequence."
+ :tags["easy" "seqs" "core-functions"]
+ :tests ["(= (__ '(4 5 6 7) 2) 6)"
+ "(= (__ [:a :b :c] 0) :a)"
+ "(= (__ [1 2 3 4] 1) 2)"
"(= (__ '([1 2] [3 4] [5 6]) 2) [5 6])"]})
-
- (insert! :problems
- {:_id 22
- :title "Count a Sequence"
- :times-solved 0
- :restricted ["count"]
- :description "Write a function which returns the total number of elements in a sequence."
- :tags["easy" "seqs" "core-functions"]
- :tests ["(= (__ '(1 2 3 3 1)) 5)"
- "(= (__ \"Hello World\") 11)"
- "(= (__ [[1 2] [3 4] [5 6]]) 3)"
+
+ (insert! :problems
+ {:_id 22
+ :title "Count a Sequence"
+ :times-solved 0
+ :restricted ["count"]
+ :description "Write a function which returns the total number of elements in a sequence."
+ :tags["easy" "seqs" "core-functions"]
+ :tests ["(= (__ '(1 2 3 3 1)) 5)"
+ "(= (__ \"Hello World\") 11)"
+ "(= (__ [[1 2] [3 4] [5 6]]) 3)"
"(= (__ '(13)) 1)"
"(= (__ '(:a :b :c)) 3)"]})
-
- (insert! :problems
- {:_id 23
- :title "Reverse a Sequence"
- :times-solved 0
- :restricted ["reverse"]
- :description "Write a function which reverses a sequence."
- :tags["easy" "seqs" "core-functions"]
- :tests ["(= (__ [1 2 3 4 5]) [5 4 3 2 1])"
- "(= (__ (sorted-set 5 7 2 7)) '(7 5 2))"
+
+ (insert! :problems
+ {:_id 23
+ :title "Reverse a Sequence"
+ :times-solved 0
+ :restricted ["reverse"]
+ :description "Write a function which reverses a sequence."
+ :tags["easy" "seqs" "core-functions"]
+ :tests ["(= (__ [1 2 3 4 5]) [5 4 3 2 1])"
+ "(= (__ (sorted-set 5 7 2 7)) '(7 5 2))"
"(= (__ [[1 2][3 4][5 6]]) [[5 6][3 4][1 2]])"]})
-
- (insert! :problems
- {:_id 24
- :title "Sum It All Up"
- :times-solved 0
- :description "Write a function which returns the sum of a sequence of numbers."
- :tags ["easy" "seqs"]
- :tests ["(= (__ [1 2 3]) 6)"
- "(= (__ (list 0 -2 5 5)) 8)"
- "(= (__ #{4 2 1}) 7)"
+
+ (insert! :problems
+ {:_id 24
+ :title "Sum It All Up"
+ :times-solved 0
+ :description "Write a function which returns the sum of a sequence of numbers."
+ :tags ["easy" "seqs"]
+ :tests ["(= (__ [1 2 3]) 6)"
+ "(= (__ (list 0 -2 5 5)) 8)"
+ "(= (__ #{4 2 1}) 7)"
"(= (__ '(0 0 -1)) -1)"
"(= (__ '(1 10 3)) 14)"]})
-
- (insert! :problems
- {:_id 25
- :title "Find the odd numbers"
- :times-solved 0
- :description "Write a function which returns only the odd numbers from a sequence."
- :tags["easy" "seqs"]
- :tests ["(= (__ #{1 2 3 4 5}) '(1 3 5))"
- "(= (__ [4 2 1 6]) '(1))"
+
+ (insert! :problems
+ {:_id 25
+ :title "Find the odd numbers"
+ :times-solved 0
+ :description "Write a function which returns only the odd numbers from a sequence."
+ :tags["easy" "seqs"]
+ :tests ["(= (__ #{1 2 3 4 5}) '(1 3 5))"
+ "(= (__ [4 2 1 6]) '(1))"
"(= (__ [2 2 4 6]) '())"
"(= (__ [1 1 1 3]) '(1 1 1 3))"]})
-
- (insert! :problems
- {:_id 26
- :title "Fibonacci Sequence"
- :times-solved 0
- :description "Write a function which returns the first X fibonacci numbers."
- :tags["easy" "Fibonacci" "seqs"]
- :tests ["(= (__ 3) '(1 1 2))"
- "(= (__ 6) '(1 1 2 3 5 8))"
+
+ (insert! :problems
+ {:_id 26
+ :title "Fibonacci Sequence"
+ :times-solved 0
+ :description "Write a function which returns the first X fibonacci numbers."
+ :tags["easy" "Fibonacci" "seqs"]
+ :tests ["(= (__ 3) '(1 1 2))"
+ "(= (__ 6) '(1 1 2 3 5 8))"
"(= (__ 8) '(1 1 2 3 5 8 13 21))"]})
-
+
(insert! :problems
- {:_id 27
- :title "Palindrome Detector"
- :times-solved 0
- :description "Write a function which returns true if the given sequence is a palindrome.<br/><br>
+ {:_id 27
+ :title "Palindrome Detector"
+ :times-solved 0
+ :description "Write a function which returns true if the given sequence is a palindrome.<br/><br>
Hint: \"racecar\" does not equal '(\\r \\a \\c \\e \\c \\a \\r)"
- :tags["easy" "seqs"]
- :tests ["(false? (__ '(1 2 3 4 5)))"
- "(true? (__ \"racecar\"))"
- "(true? (__ [:foo :bar :foo]))"
+ :tags["easy" "seqs"]
+ :tests ["(false? (__ '(1 2 3 4 5)))"
+ "(true? (__ \"racecar\"))"
+ "(true? (__ [:foo :bar :foo]))"
"(true? (__ '(1 1 3 3 1 1)))"
"(false? (__ '(:a :b :c)))"]})
-
- (insert! :problems
- {:_id 28
- :title "Flatten a Sequence"
- :times-solved 0
- :restricted ["flatten"]
- :description "Write a function which flattens a sequence."
-
- :tags["easy" "seqs" "core-functions"]
- :tests ["(= (__ '((1 2) 3 [4 [5 6]])) '(1 2 3 4 5 6))"
- "(= (__ [\"a\" [\"b\"] \"c\"]) '(\"a\" \"b\" \"c\"))"
+
+ (insert! :problems
+ {:_id 28
+ :title "Flatten a Sequence"
+ :times-solved 0
+ :restricted ["flatten"]
+ :description "Write a function which flattens a sequence."
+
+ :tags["easy" "seqs" "core-functions"]
+ :tests ["(= (__ '((1 2) 3 [4 [5 6]])) '(1 2 3 4 5 6))"
+ "(= (__ [\"a\" [\"b\"] \"c\"]) '(\"a\" \"b\" \"c\"))"
"(= (__ '((((:a))))) '(:a))"]})
-
- (insert! :problems
- {:_id 29
- :title "Get the Caps"
- :times-solved 0
- :description "Write a function which takes a string and returns a new string containing only the capital letters."
- :tags["easy" "strings"]
- :tests ["(= (__ \"HeLlO, WoRlD!\") \"HLOWRD\")"
- "(empty? (__ \"nothing\"))"
+
+ (insert! :problems
+ {:_id 29
+ :title "Get the Caps"
+ :times-solved 0
+ :description "Write a function which takes a string and returns a new string containing only the capital letters."
+ :tags["easy" "strings"]
+ :tests ["(= (__ \"HeLlO, WoRlD!\") \"HLOWRD\")"
+ "(empty? (__ \"nothing\"))"
"(= (__ \"$#A(*&987Zf\") \"AZ\")"]})
-
- (insert! :problems
- {:_id 30
- :title "Compress a Sequence"
- :times-solved 0
- :description "Write a function which removes consecutive duplicates from a sequence."
- :tags ["easy" "seqs"]
- :tests ["(= (apply str (__ \"Leeeeeerrroyyy\")) \"Leroy\")"
- "(= (__ [1 1 2 3 3 2 2 3]) '(1 2 3 2 3))"
+
+ (insert! :problems
+ {:_id 30
+ :title "Compress a Sequence"
+ :times-solved 0
+ :description "Write a function which removes consecutive duplicates from a sequence."
+ :tags ["easy" "seqs"]
+ :tests ["(= (apply str (__ \"Leeeeeerrroyyy\")) \"Leroy\")"
+ "(= (__ [1 1 2 3 3 2 2 3]) '(1 2 3 2 3))"
"(= (__ [[1 2] [1 2] [3 4] [1 2]]) '([1 2] [3 4] [1 2]))"]})
-
- (insert! :problems
- {:_id 31
- :title "Pack a Sequence"
- :times-solved 0
- :description "Write a function which packs consecutive duplicates into sub-lists."
- :tags ["easy" "seqs"]
- :tests ["(= (__ [1 1 2 1 1 1 3 3]) '((1 1) (2) (1 1 1) (3 3)))"
- "(= (__ [:a :a :b :b :c]) '((:a :a) (:b :b) (:c)))"
+
+ (insert! :problems
+ {:_id 31
+ :title "Pack a Sequence"
+ :times-solved 0
+ :description "Write a function which packs consecutive duplicates into sub-lists."
+ :tags ["easy" "seqs"]
+ :tests ["(= (__ [1 1 2 1 1 1 3 3]) '((1 1) (2) (1 1 1) (3 3)))"
+ "(= (__ [:a :a :b :b :c]) '((:a :a) (:b :b) (:c)))"
"(= (__ [[1 2] [1 2] [3 4]]) '(([1 2] [1 2]) ([3 4])))"]})
-
- (insert! :problems
- {:_id 32
- :title "Duplicate a Sequence"
- :times-solved 0
- :description "Write a function which duplicates each element of a sequence."
- :tags ["easy" "seqs"]
- :tests ["(= (__ [1 2 3]) '(1 1 2 2 3 3))"
- "(= (__ [:a :a :b :b]) '(:a :a :a :a :b :b :b :b))"
+
+ (insert! :problems
+ {:_id 32
+ :title "Duplicate a Sequence"
+ :times-solved 0
+ :description "Write a function which duplicates each element of a sequence."
+ :tags ["easy" "seqs"]
+ :tests ["(= (__ [1 2 3]) '(1 1 2 2 3 3))"
+ "(= (__ [:a :a :b :b]) '(:a :a :a :a :b :b :b :b))"
"(= (__ [[1 2] [3 4]]) '([1 2] [1 2] [3 4] [3 4]))"
"(= (__ [44 33]) [44 44 33 33])"]})
(insert! :problems
- {:_id 33
- :title "Replicate a Sequence"
- :times-solved 0
- :description "Write a function which replicates each element of a sequence a variable number of times."
- :tags ["easy" "seqs"]
- :tests ["(= (__ [1 2 3] 2) '(1 1 2 2 3 3))"
- "(= (__ [:a :b] 4) '(:a :a :a :a :b :b :b :b))"
+ {:_id 33
+ :title "Replicate a Sequence"
+ :times-solved 0
+ :description "Write a function which replicates each element of a sequence a variable number of times."
+ :tags ["easy" "seqs"]
+ :tests ["(= (__ [1 2 3] 2) '(1 1 2 2 3 3))"
+ "(= (__ [:a :b] 4) '(:a :a :a :a :b :b :b :b))"
"(= (__ [4 5 6] 1) '(4 5 6))"
"(= (__ [[1 2] [3 4]] 2) '([1 2] [1 2] [3 4] [3 4]))"
"(= (__ [44 33] 2) [44 44 33 33])"]})
-
- (insert! :problems
- {:_id 34
- :title "Implement range"
- :times-solved 0
- :restricted ["range"]
- :description "Write a function which creates a list of all integers in a given range."
- :tags ["easy" "seqs" "core-functions"]
- :tests ["(= (__ 1 4) '(1 2 3))"
- "(= (__ -2 2) '(-2 -1 0 1))"
+
+ (insert! :problems
+ {:_id 34
+ :title "Implement range"
+ :times-solved 0
+ :restricted ["range"]
+ :description "Write a function which creates a list of all integers in a given range."
+ :tags ["easy" "seqs" "core-functions"]
+ :tests ["(= (__ 1 4) '(1 2 3))"
+ "(= (__ -2 2) '(-2 -1 0 1))"
"(= (__ 5 8) '(5 6 7))"]})
(insert! :problems
@@ -352,7 +352,7 @@
:description "Clojure lets you give local names to values using the special let-form."
:tags ["elementary" "syntax"]
:tests ["(= __ (let [x 5] (+ 2 x)))"
- "(= __ (let [x 3, y 10] (- y x)))"
+ "(= __ (let [x 3, y 10] (- y x)))"
"(= __ (let [x 21] (let [y 3] (/ x y))))"]})
(insert! :problems
@@ -362,7 +362,7 @@
:description "Can you bind x, y, and z so that these are all true?"
:tags ["elementary" "math" "syntax"]
:tests ["(= 10 (let __ (+ x y)))"
- "(= 4 (let __ (+ y z)))"
+ "(= 4 (let __ (+ y z)))"
"(= 1 (let __ z))"]})
(insert! :problems
@@ -377,11 +377,11 @@
{:_id 38
:title "Maximum value"
:times-solved 0
- :restricted ["max" "max-key"]
+ :restricted ["max" "max-key"]
:description "Write a function which takes a variable number of parameters and returns the maximum value."
:tags ["easy" "core-functions"]
:tests ["(= (__ 1 8 3 4) 8)"
- "(= (__ 30 20) 30)"
+ "(= (__ 30 20) 30)"
"(= (__ 45 67 11) 67)"]})
@@ -389,25 +389,25 @@
{:_id 39
:title "Interleave Two Seqs"
:times-solved 0
- :restricted ["interleave"]
+ :restricted ["interleave"]
:description "Write a function which takes two sequences and returns the first item from each, then the second item from each, then the third, etc."
:tags ["easy" "seqs" "core-functions"]
- :tests ["(= (__ [1 2 3] [:a :b :c]) '(1 :a 2 :b 3 :c))"
- "(= (__ [1 2] [3 4 5 6]) '(1 3 2 4))"
+ :tests ["(= (__ [1 2 3] [:a :b :c]) '(1 :a 2 :b 3 :c))"
+ "(= (__ [1 2] [3 4 5 6]) '(1 3 2 4))"
"(= (__ [1 2 3 4] [5]) [1 5])"
"(= (__ [30 20] [25 15]) [30 25 20 15])"]})
-
-
+
+
(insert! :problems
{:_id 40
:title "Interpose a Seq"
:times-solved 0
- :restricted ["interpose"]
+ :restricted ["interpose"]
:description "Write a function which separates the items of a sequence by an arbitrary value."
:tags ["easy" "seqs" "core-functions"]
:tests ["(= (__ 0 [1 2 3]) [1 0 2 0 3])"
- "(= (apply str (__ \", \" [\"one\" \"two\" \"three\"])) \"one, two, three\")"
+ "(= (apply str (__ \", \" [\"one\" \"two\" \"three\"])) \"one, two, three\")"
"(= (__ :z [:a :b :c :d]) [:a :z :b :z :c :z :d])"]})
(insert! :problems
@@ -417,7 +417,7 @@
:description "Write a function which drops every Nth item from a sequence."
:tags ["easy" "seqs"]
:tests ["(= (__ [1 2 3 4 5 6 7 8] 3) [1 2 4 5 7 8])"
- "(= (__ [:a :b :c :d :e :f] 2) [:a :c :e])"
+ "(= (__ [:a :b :c :d :e :f] 2) [:a :c :e])"
"(= (__ [1 2 3 4 5 6] 4) [1 2 3 5 6])"]})
(insert! :problems
@@ -427,8 +427,8 @@
:description "Write a function which calculates factorials."
:tags ["easy" "math"]
:tests ["(= (__ 1) 1)"
- "(= (__ 3) 6)"
- "(= (__ 5) 120)"
+ "(= (__ 3) 6)"
+ "(= (__ 5) 120)"
"(= (__ 8) 40320)"]})
(insert! :problems
@@ -438,7 +438,7 @@
:description "Write a function which reverses the interleave process into x number of subsequences."
:tags ["medium" "seqs"]
:tests ["(= (__ [1 2 3 4 5 6] 2) '((1 3 5) (2 4 6)))"
- "(= (__ (range 9) 3) '((0 3 6) (1 4 7) (2 5 8)))"
+ "(= (__ (range 9) 3) '((0 3 6) (1 4 7) (2 5 8)))"
"(= (__ (range 10) 5) '((0 5) (1 6) (2 7) (3 8) (4 9)))"]})
(insert! :problems
@@ -448,8 +448,8 @@
:description "Write a function which can rotate a sequence in either direction."
:tags ["medium" "seqs"]
:tests ["(= (__ 2 [1 2 3 4 5]) '(3 4 5 1 2))"
- "(= (__ -2 [1 2 3 4 5]) '(4 5 1 2 3))"
- "(= (__ 6 [1 2 3 4 5]) '(2 3 4 5 1))"
+ "(= (__ -2 [1 2 3 4 5]) '(4 5 1 2 3))"
+ "(= (__ 6 [1 2 3 4 5]) '(2 3 4 5 1))"
"(= (__ 1 '(:a :b :c)) '(:b :c :a))"
"(= (__ -4 '(:a :b :c)) '(:c :a :b))"]})
@@ -479,8 +479,8 @@
:description "The contains? function checks if a KEY is present in a given collection. This often leads beginner clojurians to use it incorrectly with numerically indexed collections like vectors and lists."
:tags ["easy"]
:tests ["(contains? #{4 5 6} __)"
- "(contains? [1 1 1 1 1] __)"
- "(contains? {4 :a 2 :b} __)"
+ "(contains? [1 1 1 1 1] __)"
+ "(contains? {4 :a 2 :b} __)"
"(not (contains? '(1 2 4) __))"]})
(insert! :problems
@@ -490,7 +490,7 @@
:description "The some function takes a predicate function and a collection. It returns the first logical true value of (predicate x) where x is an item in the collection."
:tags ["easy"]
:tests ["(= __ (some #{2 7 6} [5 6 7 8]))"
- "(= __ (some #(when (even? %) %) [5 6 7 8]))"]})
+ "(= __ (some #(when (even? %) %) [5 6 7 8]))"]})
(insert! :problems
{:_id 49
@@ -500,7 +500,7 @@
:description "Write a function which will split a sequence into two parts."
:tags ["easy" "seqs" "core-functions"]
:tests ["(= (__ 3 [1 2 3 4 5 6]) [[1 2 3] [4 5 6]])"
- "(= (__ 1 [:a :b :c :d]) [[:a] [:b :c :d]])"
+ "(= (__ 1 [:a :b :c :d]) [[:a] [:b :c :d]])"
"(= (__ 2 [[1 2] [3 4] [5 6]]) [[[1 2] [3 4]] [[5 6]]])"]})
(insert! :problems
@@ -510,7 +510,7 @@
:description "Write a function which takes a sequence consisting of items with different types and splits them up into a set of homogeneous sub-sequences. The internal order of each sub-sequence should be maintained, but the sub-sequences themselves can be returned in any order (this is why 'set' is used in the test cases)."
:tags ["medium" "seqs"]
:tests ["(= (set (__ [1 :a 2 :b 3 :c])) #{[1 2 3] [:a :b :c]})"
- "(= (set (__ [:a \"foo\" \"bar\" :b])) #{[:a :b] [\"foo\" \"bar\"]})"
+ "(= (set (__ [:a \"foo\" \"bar\" :b])) #{[:a :b] [\"foo\" \"bar\"]})"
"(= (set (__ [[1 2] :a [3 4] 5 6 :b])) #{[[1 2] [3 4]] [:a :b] [5 6]})"]})
(insert! :problems
@@ -527,11 +527,37 @@
:times-solved 0
:description "Let bindings and function parameter lists support destructuring."
:tags ["easy" "destructuring"]
- :tests ["(= [2 4] (let [[a b c d e f g] (range)] __))"]})))
+ :tests ["(= [2 4] (let [[a b c d e f g] (range)] __))"]})
+ (insert! :problems
+ {:_id 53
+ :title "Longest Increasing Sub-Seq"
+ :times-solved 0
+ :description "Given a vector of integers, find the longest consecutive sub-sequence of increasing numbers. If two sub-sequences have the same length, use the one that occurs first."
+ :tags ["hard" "seqs"]
+ :tests ["(= (__ [1 0 1 2 3 0 4 5]) [0 1 2 3])"
+ "(= (__ [5 6 1 3 2 7]) [5 6])"
+ "(= (__ [2 3 3 4 5]) [3 4 5])"
+ "(= (__ [7 6 5 4]) [])"]})
-(doseq [{id :_id :keys [test secrets]}
- (fetch :problems)]
- (update! :problems
- {:_id id}
- {:$set {:test (concat test secrets) :secrets []}}))
+ (insert! :problems
+ {:_id 54
+ :title "Partition a Sequence"
+ :times-solved 0
+ :restricted ["partition" "partition-all"]
+ :description "Write a function which returns a sequence of lists of x items each. Lists of less than x items should not be returned."
+ :tags ["medium" "seqs" "core-functions"]
+ :tests ["(= (__ 3 (range 9)) '((0 1 2) (3 4 5) (6 7 8)))"
+ "(= (__ 2 (range 8)) '((0 1) (2 3) (4 5) (6 7)))"
+ "(= (__ 3 (range 8)) '((0 1 2) (3 4 5)))"]})
+
+ (insert! :problems
+ {:_id 55
+ :title "Count Occurences"
+ :times-solved 0
+ :restricted ["frequencies"]
+ :description "Write a function which returns a map containing the number of occurences of each distinct item in a sequence."
+ :tags ["medium" "seqs" "core-functions"]
+ :tests ["(= (__ [1 1 2 3 2 1 1]) {1 4, 2 2, 3 1})"
+ "(= (__ [:b :a :b :a :b]) {:a 2, :b 3})"
+ "(= (__ '([1 2] [1 3] [1 3])) {[1 2] 1, [1 3] 2})"]})))
46 src/foreclojure/login.clj
View
@@ -8,35 +8,40 @@
somnium.congomongo)
(:require [sandbar.stateful-session :as session]
[ring.util.response :as response])
- (:import org.apache.commons.mail.SimpleEmail))
+ (:import java.net.URLEncoder
+ org.apache.commons.mail.SimpleEmail))
(def-page my-login-page []
- [:div.error (session/flash-get :error)]
+ [:div.error
+ (session/flash-get :error)
+ (session/flash-get :message)]
(form-to [:post "/login"]
- [:table
- [:tr
- [:td (label :user "Username")]
- [:td (text-field :user)]]
- [:tr
- [:td (label :pwd "Password")]
- [:td (password-field :pwd)]]
- [:tr
- [:td]
- [:td [:button {:type "submit"} "Log In"]]]
- [:tr
- [:td ]
- [:td
- [:a {:href "/login/reset"} "Forgot your password?"]]]]))
+ [:table
+ [:tr
+ [:td (label :user "Username")]
+ [:td (text-field :user)]]
+ [:tr
+ [:td (label :pwd "Password")]
+ [:td (password-field :pwd)]]
+ [:tr
+ [:td]
+ [:td [:button {:type "submit"} "Log In"]]]
+ [:tr
+ [:td]
+ [:td
+ [:a {:href "/login/reset"} "Forgot your password?"]]]]))
(defn do-login [user pwd]
(let [user (.toLowerCase user)
- {db-pwd :pwd} (from-mongo (fetch-one :users :where {:user user}))]
+ {db-pwd :pwd} (from-mongo (fetch-one :users :where {:user user}))
+ location (session/session-get :login-to)]
(if (and db-pwd (.checkPassword (StrongPasswordEncryptor.) pwd db-pwd))
(do (update! :users {:user user}
{:$set {:last-login (java.util.Date.)}}
:upsert false) ; never create new users accidentally
(session/session-put! :user user)
- (response/redirect "/problems"))
+ (session/session-delete-key! :login-to)
+ (response/redirect (or location "/problems")))
(flash-error "Error logging in." "/login"))))
(def-page update-password-page []
@@ -64,8 +69,8 @@
(update! :users {:user user}
{:$set {:pwd new-pwd-hash}}
:upsert false)
- (html-doc
- [:div#update-succeeded "Password for " user " updated successfully"]))
+ (flash-msg (str "Password for " user " updated successfully")
+ "/problems"))
(flash-error why "/login/update")))))
(def-page reset-password-page []
@@ -114,6 +119,7 @@
name " has been reset to " pw ". Make sure to change it"
" soon at https://4clojure.com/login/update - pick"
" something you'll remember!")})
+ (session/session-put! :login-to "/login/update")
(flash-msg "Your password has been reset! You should receive an email soon"
"/login"))
(flash-error "We don't know anyone with that email address!"
22 src/foreclojure/problems.clj
View
@@ -43,7 +43,7 @@
(session/session-put! :code [id code])
(flash-msg (str message " " gist-link) "/problems")))
-(def restricted-list ['use 'require 'in-ns 'future 'agent 'send 'send-off 'pmap 'pcalls])
+(def restricted-list '[use require in-ns future agent send send-off pmap pcalls])
(defn get-tester [restricted]
(into secure-tester (concat restricted-list (map symbol restricted))))
@@ -52,10 +52,8 @@
(defn run-code [id raw-code]
(let [code (.trim raw-code)
- p (get-problem id)
- tests (concat (:tests p) (:secret-tests p))
- func-name (:function-name p)
- sb-tester (get-tester (:restricted p))]
+ {:keys [tests restricted]} (get-problem id)
+ sb-tester (get-tester restricted)]
(if (empty? code)
(do
(session/flash-put! :code code)
@@ -96,12 +94,12 @@
[:b "Enter your code:" [:br]
[:span {:class "error"} (session/flash-get :error)]]]
(form-to [:post "/run-code"]
- (text-area {:id "code-box"
- :spellcheck "false"}
- :code (session/flash-get :code))
- (hidden-field :id id)
- [:br]
- [:button.large {:type "submit"} "Run"])]))
+ (text-area {:id "code-box"
+ :spellcheck "false"}
+ :code (session/flash-get :code))
+ (hidden-field :id id)
+ [:br]
+ [:button.large {:type "submit"} "Run"])]))
(def-page problem-page []
[:div.congrats (session/flash-get :message)]
@@ -134,4 +132,4 @@
(GET "/problems" [] (problem-page))
(GET "/problem/:id" [id] (code-box id))
(POST "/run-code" {{:strs [id code]} :form-params}
- (run-code (Integer. id) code)))
+ (run-code (Integer. id) code)))
16 src/foreclojure/register.clj
View
@@ -10,14 +10,14 @@
(def-page register-page []
[:div.error (session/flash-get :error)]
(form-to [:post "/register"]
- [:table
- (map form-row
- [[text-field :user "Username (4-13 chars.)"]
- [password-field :pwd "Password (7-13 chars.)"]
- [password-field :repeat-pwd "Repeat Password"]
- [text-field :email "Email"]])
- [:tr
- [:td [:button {:type "submit"} "Register"]]]]))
+ [:table
+ (map form-row
+ [[text-field :user "Username (4-13 chars.)"]
+ [password-field :pwd "Password (7-13 chars.)"]
+ [password-field :repeat-pwd "Repeat Password"]
+ [text-field :email "Email"]])
+ [:tr
+ [:td [:button {:type "submit"} "Register"]]]]))
(defn do-register [user pwd repeat-pwd email]
(let [lower-user (.toLowerCase user)]
9 src/foreclojure/users.clj
View
@@ -6,18 +6,23 @@
(defn get-users []
(let [users (from-mongo
(fetch :users
- :only [:user :solved]))
+ :only [:user :solved :contributor]))
sortfn (comp count :solved)]
(reverse (sort-by sortfn users))))
(def-page users-page []
+ [:div [:span.contributor "*"]" 4clojure contributor"]
+ [:br]
[:table#user-table.my-table
[:thead
[:tr
[:th "Username"]
[:th "Problems Solved"]]]
(map-indexed #(vec [:tr (row-class %1)
- [:td (:user %2)]
+ [:td
+ (when (:contributor %2)
+ [:span.contributor "* "])
+ (:user %2)]
[:td {:class "centered"} (count (:solved %2))]])
(get-users))])
12 src/foreclojure/version.clj
View
@@ -0,0 +1,12 @@
+(ns foreclojure.version
+ (:use foreclojure.utils
+ compojure.core
+ [clojure.java.shell :only [sh]]))
+
+(def-page version []
+ (let [sha (:out (sh "git" "rev-parse" "--verify" "HEAD"))]
+ [:p "SHA: "
+ [:a {:href (str "http://github.com/dbyrne/4clojure/commit/" sha)} sha]]))
+
+(defroutes version-routes
+ (GET ["/about/version"] [] (version)))
Please sign in to comment.
Something went wrong with that request. Please try again.