Solved Problems
Output a string to the console
Write the string
"Hello World!" to STDOUT
ruby
puts "Hello World!"
$stdout<<"Hello World!"
clojure
(println "Hello World!")
fantom
echo("Hello World!")
Retrieve a string containing ampersands from the variables in a url
My PHP script first does a query to obtain customer info for a form. The form has first name and last name fields among others. The customer has put entries such as
The script variable for first name $_REQUEST
I have tried various functions like urldecode but all to no avail. I even tried encoding the url before the view screen is painted so that the url looks like
Of course this fails for the same reasons. What is a better approach?
"Ron & Jean" in the first name field in the database. Then the edit form script is called with variables such as
"http://myserver.com/custinfo/edit.php?mode=view&fname=Ron & Jean&lname=Smith".
The script variable for first name $_REQUEST
['firstname'] never gets beyond the "Ron" value because of the ampersand in the data.
I have tried various functions like urldecode but all to no avail. I even tried encoding the url before the view screen is painted so that the url looks like
"http://myserver/custinfo/edit.php?mode=view&fname="Ronxxnbsp;xxamp;xxnbsp;Jean"&lname=SMITH". (sorry I had to add the xx to replace the ampersand or it didn't display meaningful url contents the browser sees.)
Of course this fails for the same reasons. What is a better approach?
ruby
gem 'uri-query_params'
require 'uri/query_params'
url = URI("http://myserver.com/custinfo/edit.php?mode=view&fname=Ron%20&%20Jean&lname=Smith")
url.query_params['fname']
# => "Ron & Jean"
require 'uri/query_params'
url = URI("http://myserver.com/custinfo/edit.php?mode=view&fname=Ron%20&%20Jean&lname=Smith")
url.query_params['fname']
# => "Ron & Jean"
url = "http://myserver.com/custinfo/edit.php?mode=view&fname=Ron & Jean&lname=Smith"
url = URI.parse(URI.encode(url))
url = URI.parse(URI.encode(url))
clojure
(->> {"mode" "view"
"fname" "Ron & Jean"
"lname" "Smith"}
(map #(str (URLEncoder/encode (first %) "UTF-8")
"="
(URLEncoder/encode (second %) "UTF-8")))
(reduce (fn [url e] (str url "&" e))
"http://myserver.com/custinfo/edit.php"))
"fname" "Ron & Jean"
"lname" "Smith"}
(map #(str (URLEncoder/encode (first %) "UTF-8")
"="
(URLEncoder/encode (second %) "UTF-8")))
(reduce (fn [url e] (str url "&" e))
"http://myserver.com/custinfo/edit.php"))
fantom
encoded := `http://myserver.com/custinfo/edit.php`.plusQuery(
["fname":"Ron & Jean", "lname":"Smith"]).encode
echo(encoded)
["fname":"Ron & Jean", "lname":"Smith"]).encode
echo(encoded)
string-wrap
Wrap the string
Expected output:
> The quick brown fox jumps over the lazy dog. The quick brown fox jumps over t
> he lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox
> jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The qui
> ck brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy
> dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps o
> ver the lazy dog. The quick brown fox jumps over the lazy dog.
"The quick brown fox jumps over the lazy dog. " repeated ten times to a max width of 78 chars, starting each line with "> "
Expected output:
> The quick brown fox jumps over the lazy dog. The quick brown fox jumps over t
> he lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox
> jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The qui
> ck brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy
> dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps o
> ver the lazy dog. The quick brown fox jumps over the lazy dog.
ruby
str = "The quick brown fox jumps over the lazy dog. " * 10
outarr = str.scan(/[^ ].{0,76}/)
outarr.each{ |line| puts "> %s" % line }
outarr = str.scan(/[^ ].{0,76}/)
outarr.each{ |line| puts "> %s" % line }
clojure
(defn string-wrap [s]
(if (= 0 (count s))
nil
(lazy-seq (cons (apply str (take 78 s))
(string-wrap (drop 78 s))))))
(let [s (apply str (repeat 10 "The quick brown fox jumps over the lazy dog. "))]
(doseq [line (string-wrap s)]
(println "> " line)))
(if (= 0 (count s))
nil
(lazy-seq (cons (apply str (take 78 s))
(string-wrap (drop 78 s))))))
(let [s (apply str (repeat 10 "The quick brown fox jumps over the lazy dog. "))]
(doseq [line (string-wrap s)]
(println "> " line)))
fantom
s:=Str[,].fill("The quick brown fox jumps over the lazy dog. ",10).join
while(s.size>0){
echo("> "+s[0..(77.min(s.size))-1])
s=(s.size>77)?s[77..-1].trim : ""
}
while(s.size>0){
echo("> "+s[0..(77.min(s.size))-1])
s=(s.size>77)?s[77..-1].trim : ""
}
Define a string containing special characters
Define the literal string
"\#{'}${"}/"
ruby
special = '\#{\'}${"}/'
clojure
(def special "\\#{'}${\"}/")
fantom
special := Str<|\#{'}${"}/|>
Define a multiline string
Define the string:
"This
Is
A
Multiline
String"
ruby
text = <<"HERE"
This
Is
A
Multiline
String
HERE
This
Is
A
Multiline
String
HERE
text = "This\nIs\nA\nMultiline\nString"
clojure
(def multiline "This\nIs\nA\nMultiline\nString")
fantom
s := "This
Is
A
Multiline
String"
Is
A
Multiline
String"
Define a string containing variables and expressions
Given variables a=3 and b=4 output
"3+4=7"
ruby
puts "#{a}+#{b}=#{a+b}"
puts "#{a}+#{b}=%s" % (a + b)
clojure
(format "%d + %d = %d" a b (+ a b))
fantom
echo("$a+$b=${a+b}")
Reverse the characters in a string
Given the string
"reverse me", produce the string "em esrever"
ruby
puts "reverse me".reverse
clojure
(require '[clojure.contrib.str-utils2 :as str])
(str/reverse "reverse me")
(str/reverse "reverse me")
(apply str (reverse "reverse me"))
fantom
"reverse me".reverse
Reverse the words in a string
Given the string
"This is a end, my only friend!", produce the string "friend! only my end, the is This"
ruby
reversed = text.split.reverse.join(' ')
clojure
(require '[clojure.contrib.str-utils2 :as str])
(str/join " " (reverse (str/split "this is the end, my only friend!" #" ")))
(str/join " " (reverse (str/split "this is the end, my only friend!" #" ")))
(apply str (interpose " " (reverse (re-seq #"[^\s]+" "This is the end, my only friend!"))))
fantom
"This is a end, my only friend!".split.reverse.join(" ")
Text wrapping
Wrap the string
> The quick brown fox jumps over the lazy dog. The quick brown fox jumps
> over the lazy dog. The quick brown fox jumps over the lazy dog. The
> quick brown fox jumps over the lazy dog. The quick brown fox jumps
> over the lazy dog. The quick brown fox jumps over the lazy dog. The
> quick brown fox jumps over the lazy dog. The quick brown fox jumps
> over the lazy dog. The quick brown fox jumps over the lazy dog. The
> quick brown fox jumps over the lazy dog.
"The quick brown fox jumps over the lazy dog. " repeated ten times to a max width of 78 chars, starting each line with "> ", yielding this result:
> The quick brown fox jumps over the lazy dog. The quick brown fox jumps
> over the lazy dog. The quick brown fox jumps over the lazy dog. The
> quick brown fox jumps over the lazy dog. The quick brown fox jumps
> over the lazy dog. The quick brown fox jumps over the lazy dog. The
> quick brown fox jumps over the lazy dog. The quick brown fox jumps
> over the lazy dog. The quick brown fox jumps over the lazy dog. The
> quick brown fox jumps over the lazy dog.
ruby
prefix = "> "
string = "The quick brown fox jumps over the lazy dog. " * 10
width = 78
realwidth = width - prefix.length
print string.gsub(/(.{1,#{realwidth}})(?: +|$)\n?|(.{#{realwidth}})/, "#{prefix}\\1\\2\n")
string = "The quick brown fox jumps over the lazy dog. " * 10
width = 78
realwidth = width - prefix.length
print string.gsub(/(.{1,#{realwidth}})(?: +|$)\n?|(.{#{realwidth}})/, "#{prefix}\\1\\2\n")
clojure
(doseq [line (re-seq #".{0,70} "
(apply str
(repeat 10 "The quick brown fox jumps over the lazy dog. ")))]
(println ">" line))
(apply str
(repeat 10 "The quick brown fox jumps over the lazy dog. ")))]
(println ">" line))
fantom
buf := Buf()
10.times { buf.writeChars("The quick brown fox jumps over the lazy dog. ") }
buf.flip
out := Env.cur.out
sep := ">"; max := 72 - sep.size - 1
acc := 0; Str? s := null
while ((s = buf.readStrToken) != null)
{
if (acc == 0)
out.print(sep)
acc += s.size
if (acc > max)
{
out.print("\n$sep")
acc = s.size
}
out.print(" $s")
buf.readStrToken(4096) { !it.isSpace }
acc++
}
10.times { buf.writeChars("The quick brown fox jumps over the lazy dog. ") }
buf.flip
out := Env.cur.out
sep := ">"; max := 72 - sep.size - 1
acc := 0; Str? s := null
while ((s = buf.readStrToken) != null)
{
if (acc == 0)
out.print(sep)
acc += s.size
if (acc > max)
{
out.print("\n$sep")
acc = s.size
}
out.print(" $s")
buf.readStrToken(4096) { !it.isSpace }
acc++
}
Remove leading and trailing whitespace from a string
Given the string
" hello " return the string "hello".
ruby
puts " hello ".strip
" hello ".strip!
clojure
(use 'clojure.contrib.str-utils2)
(trim " hello ")
(trim " hello ")
(clojure.string/trim " hello ")
(.trim " hello ")
fantom
s := " hello ".trim
Simple substitution cipher
Take a string and return the ROT13 and ROT47 (Check Wikipedia) version of the string.
For example:
String is: Hello World #123
ROT13 returns: Uryyb Jbeyq #123
ROT47 returns: w6==@ (@C=5 R`ab
For example:
String is: Hello World #123
ROT13 returns: Uryyb Jbeyq #123
ROT47 returns: w6==@ (@C=5 R`ab
ruby
rot13 = "Hello World #123".tr!("A-Za-z", "N-ZA-Mn-za-m")
rot47 = "Hello World #123".tr!("\x21-\x7e", "\x50-\x7e\x21-\x4f")
rot47 = "Hello World #123".tr!("\x21-\x7e", "\x50-\x7e\x21-\x4f")
clojure
(use 'clojure.contrib.cond)
(defn rot13 [s]
(reduce str
(map #(char (let [c (bit-and (int (char %)) 0xDF)]
(+ % (cond-let [i]
(and (>= c (int \A)) (<= c (int \M))) 13
(and (>= c (int \N)) (<= c (int \Z))) -13
true 0))))
(map #(int (char %)) s))))
(defn rot47 [s]
(reduce str
(map #(char (+ % (cond-let [i]
(and (>= % (int \!)) (<= % (int \O))) 47
(and (>= % (int \P)) (<= % (int \~))) -47
true 0)))
(map #(int (char %)) s))))
(defn rot13 [s]
(reduce str
(map #(char (let [c (bit-and (int (char %)) 0xDF)]
(+ % (cond-let [i]
(and (>= c (int \A)) (<= c (int \M))) 13
(and (>= c (int \N)) (<= c (int \Z))) -13
true 0))))
(map #(int (char %)) s))))
(defn rot47 [s]
(reduce str
(map #(char (+ % (cond-let [i]
(and (>= % (int \!)) (<= % (int \O))) 47
(and (>= % (int \P)) (<= % (int \~))) -47
true 0)))
(map #(int (char %)) s))))
fantom
rot := |Str s, |Int c -> Int| remap -> Str|
{
rs := ""
s.each { rs += remap(it).toChar }
return rs
}
rot13 := |Str s -> Str|
{
rot(s) |Int c -> Int|
{
lc := c.lower
c += (lc >= 'a' && lc <= 'm') ? 13
: ((lc >= 'n' && lc <= 'z') ? -13 : 0)
return c
}
}
rot47 := |Str s -> Str|
{
rot(s) |Int c -> Int|
{
c += (c >= '!' && c <= 'O') ? 47
: ((c >= 'P' && c <= '~') ? -47 : 0)
return c
}
}
s := "Hello World #123"
echo("s=$s")
echo("rot13=${rot13(s)}")
echo("rot47=${rot47(s)}")
{
rs := ""
s.each { rs += remap(it).toChar }
return rs
}
rot13 := |Str s -> Str|
{
rot(s) |Int c -> Int|
{
lc := c.lower
c += (lc >= 'a' && lc <= 'm') ? 13
: ((lc >= 'n' && lc <= 'z') ? -13 : 0)
return c
}
}
rot47 := |Str s -> Str|
{
rot(s) |Int c -> Int|
{
c += (c >= '!' && c <= 'O') ? 47
: ((c >= 'P' && c <= '~') ? -47 : 0)
return c
}
}
s := "Hello World #123"
echo("s=$s")
echo("rot13=${rot13(s)}")
echo("rot47=${rot47(s)}")
Make a string uppercase
Transform
"Space Monkey" into "SPACE MONKEY"
ruby
uppper = text.upcase
clojure
(.toUpperCase "Space Monkey")
fantom
s := "Space Monkey".localeUpper
Make a string lowercase
Transform
"Caps ARE overRated" into "caps are overrated"
ruby
"Caps ARE overRated".downcase
clojure
(.toLowerCase "Caps ARE overRated")
fantom
s := "Caps ARE overRated".localeLower
Capitalise the first letter of each word
Transform
"man OF stEEL" into "Man Of Steel"
ruby
caps = text.gsub(/\w+/) { $&.capitalize }
caps = text.split.each{|i| i.capitalize!}.join(' ')
text.split.map(&:capitalize) * ' '
clojure
(use 'clojure.contrib.str-utils2)
(join " " (map capitalize (split "man OF stEEL" #" ")))
(join " " (map capitalize (split "man OF stEEL" #" ")))
fantom
"man OF stEEL".split.map { it.localeLower.localeCapitalize }.join(" ")
Find the distance between two points
ruby
# the hypotenuse sqrt(x**2+y**2)
distance = Math.hypot(x2-x1,y2-y1)
distance = Math.hypot(x2-x1,y2-y1)
clojure
(defstruct point :x :y)
(defn distance
"Euclidean distance between 2 points"
[p1 p2]
(Math/pow (+ (Math/pow (- (:x p1) (:x p2)) 2)
(Math/pow (- (:y p1) (:y p2)) 2))
0.5))
(distance (struct point 0 0) (struct point 1 1)) ; => 1.4142135623730951
(defn distance
"Euclidean distance between 2 points"
[p1 p2]
(Math/pow (+ (Math/pow (- (:x p1) (:x p2)) 2)
(Math/pow (- (:y p1) (:y p2)) 2))
0.5))
(distance (struct point 0 0) (struct point 1 1)) ; => 1.4142135623730951
(defn distance
"Euclidean distance between 2 points"
[[x1 y1] [x2 y2]]
(Math/sqrt
(+ (Math/pow (- x1 x2) 2)
(Math/pow (- y1 y2) 2))))
(distance [2 2] [3 3])
"Euclidean distance between 2 points"
[[x1 y1] [x2 y2]]
(Math/sqrt
(+ (Math/pow (- x1 x2) 2)
(Math/pow (- y1 y2) 2))))
(distance [2 2] [3 3])
fantom
px1 := 34.0f; py1 := 78.0f; px2 := 67.0f; py2 := -45.0f
distance := |Float x1, Float y1, Float x2, Float y2 -> Float|
{ ((x2-x1).pow(2.0f) + (y2-y1).pow(2.0f)).sqrt }
distance(px1, py1, px2, py2)
distance := |Float x1, Float y1, Float x2, Float y2 -> Float|
{ ((x2-x1).pow(2.0f) + (y2-y1).pow(2.0f)).sqrt }
distance(px1, py1, px2, py2)
Zero pad a number
Given the number 42, pad it to 8 characters like 00000042
ruby
42.to_s.rjust(8,"0")
"%08d" % 42
clojure
(defn pad
([x] (if (> 8 (.length (str x))) (pad (str 0 x)) (str x)))
)
([x] (if (> 8 (.length (str x))) (pad (str 0 x)) (str x)))
)
(defn pad [x]
(format "%08d" x))
(format "%08d" x))
(format "%08d" 42)
fantom
formatted := 42.toStr.padl(8, '0')
formatted := 42.toLocale("00000000")
Right Space pad a number
Given the number 1024 right pad it to 6 characters
"1024 "
ruby
1024.to_s.ljust(6)
clojure
(let [s (str 1024)
l (count s)]
(str s (reduce str (repeat (- 6 l) " "))))
l (count s)]
(str s (reduce str (repeat (- 6 l) " "))))
fantom
formatted := 1024.toStr.padr(6)
Format a decimal number
Format the number 7/8 as a decimal with 2 places: 0.88
ruby
(7.0/8.0*100).round/100.0
(7.0/8.0).round(2)
clojure
(format "%3.2f" (/ 7.0 8))
(* 0.01 (Math/round (* 100 (float (/ 7 8)))))
fantom
formatted := (7.0/8.0).toLocale("0.00")
Left Space pad a number
Given the number 73 left pad it to 10 characters
" 73"
ruby
73.to_s.rjust(10)
clojure
(let [s (str 73)
l (count s)]
(str (reduce str (repeat (- 10 l) " ")) s ))
l (count s)]
(str (reduce str (repeat (- 10 l) " ")) s ))
fantom
formatted := 73.toStr.padl(10)
Generate a random integer in a given range
Produce a random integer between 100 and 200 inclusive
ruby
randomInt = rand(200-100+1)+100;
clojure
(+ (rand-int (- 201 100)) 100)
fantom
r := Int.random(100..200)
Generate a repeatable random number sequence
Initialise a random number generator with a seed and generate five decimal values. Reset the seed and produce the same values.
ruby
srand(12345)
first = (1..5).collect {rand}
srand(12345)
second = (1..5).collect {rand}
puts first == second
first = (1..5).collect {rand}
srand(12345)
second = (1..5).collect {rand}
puts first == second
clojure
(dotimes [_ 2]
(let [r (java.util.Random. 12345)]
(dotimes [_ 5]
(println (.nextInt r 100))))
(println))
(let [r (java.util.Random. 12345)]
(dotimes [_ 5]
(println (.nextInt r 100))))
(println))
fantom
rand := Random.makeSeeded(12345)
first := Int[,].fill(0,5).map { rand.next(100..200) }
rand2 := Random.makeSeeded(12345)
second := Int[,].fill(0,5).map { rand2.next(100..200) }
first := Int[,].fill(0,5).map { rand.next(100..200) }
rand2 := Random.makeSeeded(12345)
second := Int[,].fill(0,5).map { rand2.next(100..200) }
Check if a string matches a regular expression
Display
"ok" if "Hello" matches /[A-Z][a-z]+/
ruby
puts "ok" if ("Hello"=~/^[A-Z][a-z]+$/)
clojure
(if (re-matches #"[A-Z][a-z]+" "Hello")
(println "ok"))
(println "ok"))
fantom
if (Regex<|[A-Z][a-z]+|>.matches("Hello"))
echo("ok")
echo("ok")
Check if a string matches with groups
Display
"two" if "one two three" matches /one (.*) three/
ruby
puts $1 if "one two three"=~/^one (.*) three$/
clojure
(if-let [groups (re-matches #"one (.*) three" "one two three")]
(println (second groups)))
(println (second groups)))
fantom
m := Regex<|one (.*) three|>.matcher("one two three")
if (m.matches)
echo("${m.group(1)}")
if (m.matches)
echo("${m.group(1)}")
Check if a string contains a match to a regular expression
Display
"ok" if "abc 123 @#$" matches /\d+/
ruby
puts "ok" if (text=~/\d+/)
clojure
(if (re-find #"\d+" "abc 123 @#$")
(println "ok"))
(println "ok"))
fantom
m := Regex<|\d+|>.matcher("abc 123 @#\$")
if (m.find)
echo("ok")
if (m.find)
echo("ok")
Loop through a string matching a regex and performing an action for each match
Create a list
[fish1,cow3,boat4] when matching "(fish):1 sausage (cow):3 tree (boat):4" with regex /\((\w+)\):(\d+)/
ruby
list = text.scan(/\((\w+)\):(\d+)/).collect{|x| x.join}
list=[]
text.scan(/\((\w+)\):(\d+)/) {
list << $1+$2
}
text.scan(/\((\w+)\):(\d+)/) {
list << $1+$2
}
clojure
(let [matcher (re-matcher #"\((\w+)\):(\d+)" "(fish):1 sausage (cow):3 tree (boat):4")]
(loop [match (re-find matcher)
lst []]
(if match
(recur (re-find matcher) (conj lst (str (second match) (nth match 2))))
lst)))
(loop [match (re-find matcher)
lst []]
(if match
(recur (re-find matcher) (conj lst (str (second match) (nth match 2))))
lst)))
fantom
m := Regex<|\((\w+)\):(\d+)|>.matcher(s)
list := Str[,]
while (m.find) { list.add("${m.group(1)}${m.group(2)}") }
list := Str[,]
while (m.find) { list.add("${m.group(1)}${m.group(2)}") }
Replace the first regex match in a string with a static string
Transform
"Red Green Blue" into "R*d Green Blue" by replacing /e/ with "*"
ruby
p "Red Green Blue".sub(/e/,'*')
clojure
(.replaceFirst (re-matcher #"e" "Red Green Blue") "*")
fantom
replaced := Regex<|e|>.split("Red Green Blue",2).join("*")
Replace all regex matches in a string with a static string
Transform
"She sells sea shells" into "She X X shells" by replacing /se\w+/ with "X"
ruby
replaced = text.gsub(/se\w+/,"X")
clojure
(.replaceAll (re-matcher #"se\w+" "She sells sea shells") "X")
fantom
replaced := Regex<|se\w+|>.split("She sells sea shells").join("X")
Replace all regex matches in a string with a dynamic string
Transform
"The {Quick} Brown {Fox}" into "The kciuQ Brown xoF" by reversing words in braces using the regex /\{(\w+)\}/.
ruby
"The {Quick} Brown {Fox}".gsub(/\{(\w+)\}/) {|s| s[1..-2].reverse }
clojure
(def *string* "The {Quick} Brown {Fox}")
(def *regex* (re-pattern #"\{(\w+)\}"))
(println
(loop [result ""
src *string*
replace-strs (re-seq *regex* *string*)]
(if (empty? src)
result
(let [[match replacement] (first replace-strs)]
(if (= (first src) (first match))
; At the beginning of a sequence that should be replaced.
; Do replacement of a single match
(recur (str result (apply str (reverse replacement)))
(drop (count match) src)
(rest replace-strs))
; else, just copy one char from the source to the result
(recur (str result (first src))
(rest src)
replace-strs))))))
(def *regex* (re-pattern #"\{(\w+)\}"))
(println
(loop [result ""
src *string*
replace-strs (re-seq *regex* *string*)]
(if (empty? src)
result
(let [[match replacement] (first replace-strs)]
(if (= (first src) (first match))
; At the beginning of a sequence that should be replaced.
; Do replacement of a single match
(recur (str result (apply str (reverse replacement)))
(drop (count match) src)
(rest replace-strs))
; else, just copy one char from the source to the result
(recur (str result (first src))
(rest src)
replace-strs))))))
(clojure.string/replace "The {Quick} Brown {Fox}"
#"\{(\w+)\}"
(fn [[_ word]] (apply str (reverse word))))
#"\{(\w+)\}"
(fn [[_ word]] (apply str (reverse word))))
fantom
s := "The {Quick} Brown {Fox}"
m := Regex<|\{(\w+)\}|>.matcher(s)
buf := StrBuf(s.size)
last := 0
while (m.find)
{
buf.add(s[last..m.start-1]).add(m.group(1).reverse)
last = m.end
}
buf.add(s[last..-1])
replaced := buf.toStr
m := Regex<|\{(\w+)\}|>.matcher(s)
buf := StrBuf(s.size)
last := 0
while (m.find)
{
buf.add(s[last..m.start-1]).add(m.group(1).reverse)
last = m.end
}
buf.add(s[last..-1])
replaced := buf.toStr
Define an empty list
Assign the variable
"list" to a list with no elements
ruby
list = []
list = Array.new
clojure
(list)
'()
fantom
list := [,]
Define a static list
Define the list
[One, Two, Three, Four, Five]
ruby
list = ['One', 'Two', 'Three', 'Four', 'Five']
list = %w(One Two Three Four Five)
clojure
(def a '[One Two Three Four Five])
fantom
list := ["One", "Two", "Three", "Four", "Five"]
Join the elements of a list, separated by commas
Given the list
[Apple, Banana, Carrot] produce "Apple, Banana, Carrot"
ruby
string = fruit.join(', ')
clojure
(apply str (interpose ", " '("Apple" "Banana" "Carrot")))
fantom
["Apple", "Banana", "Carrot"].join(", ")
Join the elements of a list, in correct english
Create a function join that takes a List and produces a string containing an english language concatenation of the list. It should work with the following examples:
join(
join(
join(
join(
join(
[Apple, Banana, Carrot]) = "Apple, Banana, and Carrot"
join(
[One, Two]) = "One and Two"
join(
[Lonely]) = "Lonely"
join(
[]) = ""
ruby
def join(arr)
return '' if not arr
case arr.size
when 0 then ''
when 1 then arr[0]
when 2 then arr.join(' and ')
else arr[0..-2].join(', ') + ', and ' + arr[-1]
end
end
return '' if not arr
case arr.size
when 0 then ''
when 1 then arr[0]
when 2 then arr.join(' and ')
else arr[0..-2].join(', ') + ', and ' + arr[-1]
end
end
clojure
(defn join [lst]
(cond
(= (count lst) 0) ""
(= (count lst) 1) (first lst)
(= (count lst) 2) (str (first lst) " and " (second lst))
(> (count lst) 2) (loop [lst lst sb (StringBuilder.)]
(if (empty? lst)
(.toString sb)
(recur (rest lst) (.append sb (cond
(> (count lst) 2) (str (first lst) ", ")
(> (count lst) 1) (str (first lst) ", and ")
(= (count lst) 1) (str (first lst)))))))))
(cond
(= (count lst) 0) ""
(= (count lst) 1) (first lst)
(= (count lst) 2) (str (first lst) " and " (second lst))
(> (count lst) 2) (loop [lst lst sb (StringBuilder.)]
(if (empty? lst)
(.toString sb)
(recur (rest lst) (.append sb (cond
(> (count lst) 2) (str (first lst) ", ")
(> (count lst) 1) (str (first lst) ", and ")
(= (count lst) 1) (str (first lst)))))))))
(defn join
([lst]
(join lst false))
([lst is-long]
(condp = (count lst)
0 ""
1 (first lst)
2 (str (first lst) (if is-long ",") " and " (second lst))
(str (first lst) ", " (join (rest lst) true)))))
([lst]
(join lst false))
([lst is-long]
(condp = (count lst)
0 ""
1 (first lst)
2 (str (first lst) (if is-long ",") " and " (second lst))
(str (first lst) ", " (join (rest lst) true)))))
fantom
join := |List list -> Str|
{
switch(list.size)
{
case 0: return ""
case 1: return list[0]
case 2: return list.join(" and ")
default: return list[0..-2].join(", ") + ", and " + list[-1]
}
}
echo(join(["Apple", "Banana", "Carrot"]))
echo(join(["One", "Two"]))
echo(join(["Lonely"]))
echo(join([,]))
{
switch(list.size)
{
case 0: return ""
case 1: return list[0]
case 2: return list.join(" and ")
default: return list[0..-2].join(", ") + ", and " + list[-1]
}
}
echo(join(["Apple", "Banana", "Carrot"]))
echo(join(["One", "Two"]))
echo(join(["Lonely"]))
echo(join([,]))
Produce the combinations from two lists
Given two lists, produce the list of tuples formed by taking the combinations from the individual lists. E.g. given the letters
["a", "b", "c"] and the numbers [4, 5], produce the list: [["a", 4], ["b", 4], ["c", 4], ["a", 5], ["b", 5], ["c", 5]]
ruby
common = [] ; [4, 5].each {|n| ['a', 'b', 'c'].each {|l| common << [l, n]}}
clojure
(defn combine [lst1 lst2]
(mapcat (fn [x] (map #(list % x) lst1)) lst2))
(mapcat (fn [x] (map #(list % x) lst1)) lst2))
(mapcat (fn [x] (map #(list % x) ["a", "b", "c"])) [4, 5])
fantom
[4,5].each |Int i| { ["a","b","c"].each |Str s| { r.add([i,s]) } }
From a List Produce a List of Duplicate Entries
Taking a list:
Write the code to produce a list of duplicates in the list:
["andrew", "bob", "chris", "bob"]
Write the code to produce a list of duplicates in the list:
["bob"]
ruby
foo = ['andrew', 'bob', 'chris', 'bob']
foo.inject({}) {|h,v| h[v]=h[v].to_i+1; h}.reject{|k,v| v==1}.keys
foo.inject({}) {|h,v| h[v]=h[v].to_i+1; h}.reject{|k,v| v==1}.keys
clojure
(->> '("andrew" "bob" "chris" "bob")
(group-by identity)
(filter #(> (count (second %)) 1))
(map first))
(group-by identity)
(filter #(> (count (second %)) 1))
(map first))
fantom
nameCounts := Str:Int[:] { def = 0 }
["andrew", "bob", "chris", "bob"].each |Str v| { nameCounts[v]++ }
results := nameCounts.findAll |Int v, Str k->Bool| { v > 1 }.keys
echo(results.join(","))
["andrew", "bob", "chris", "bob"].each |Str v| { nameCounts[v]++ }
results := nameCounts.findAll |Int v, Str k->Bool| { v > 1 }.keys
echo(results.join(","))
Fetch an element of a list by index
Given the list
[One, Two, Three, Four, Five], fetch the third element ('Three')
ruby
list = ['One', 'Two', 'Three', 'Four', 'Five']
list[2]
list[2]
['One', 'Two', 'Three', 'Four', 'Five'].fetch(2)
list = ['One', 'Two', 'Three', 'Four', 'Five']
list.at(2)
list.at(2)
['One', 'Two', 'Three', 'Four', 'Five'][2] # <= note the [2] at end of array
clojure
(nth '[One Two Three Four Five] 2)
fantom
["One", "Two", "Three", "Four", "Five"][2]
["One", "Two", "Three", "Four", "Five"].get(2)
Fetch the last element of a list
Given the list
[Red, Green, Blue], access the last element ('Blue')
ruby
['Red', 'Green', 'Blue'][-1]
['Red', 'Green', 'Blue'].at(-1)
['Red', 'Green', 'Blue'].last
['Red', 'Green', 'Blue'].fetch(-1)
clojure
(last '[One Two Three Four Five])
fantom
["Red", "Green", "Blue"][-1]
["One", "Two", "Three", "Four", "Five"].last
Find the common items in two lists
Given two lists, find the common items. E.g. given beans =
['broad', 'mung', 'black', 'red', 'white'] and colors = ['black', 'red', 'blue', 'green'], what are the bean varieties that are also color names?
ruby
common = (beans.intersection(colors)).to_a
clojure
(use 'clojure.set)
(let [beans '[broad mung black red white]
colors '[black red blue green]]
(intersection (set beans) (set colors)))
(let [beans '[broad mung black red white]
colors '[black red blue green]]
(intersection (set beans) (set colors)))
fantom
beans := ["broad", "mung", "black", "red", "white"]
colors := ["black", "red", "blue", "green"]
echo(beans.intersection(colors))
colors := ["black", "red", "blue", "green"]
echo(beans.intersection(colors))
Display the unique items in a list
Display the unique items in a list, e.g. given ages =
[18, 16, 17, 18, 16, 19, 14, 17, 19, 18], display the unique elements, i.e. with duplicates removed.
ruby
ages = [18, 16, 17, 18, 16, 19, 14, 17, 19, 18]
p ages.uniq
p ages.uniq
ages = [18, 16, 17, 18, 16, 19, 14, 17, 19, 18]
ages.uniq!
p ages
ages.uniq!
p ages
ages = (Set.new [18, 16, 17, 18, 16, 19, 14, 17, 19, 18]).to_a
p ages
p ages
clojure
;; returns a set
(set [18, 16, 17, 18, 16, 19, 14, 17, 19, 18])
;;#{14 16 17 18 19}
;; returns a lazy sequence of the unique elements
(distinct [18, 16, 17, 18, 16, 19, 14, 17, 19, 18])
;;(18 16 17 19 14)
(set [18, 16, 17, 18, 16, 19, 14, 17, 19, 18])
;;#{14 16 17 18 19}
;; returns a lazy sequence of the unique elements
(distinct [18, 16, 17, 18, 16, 19, 14, 17, 19, 18])
;;(18 16 17 19 14)
fantom
uniqueAges := [18, 16, 17, 18, 16, 19, 14, 17, 19, 18].unique
echo(uniqueAges)
echo(uniqueAges)
Remove an element from a list by index
Given the list
[Apple, Banana, Carrot], remove the first element to produce the list [Banana, Carrot]
ruby
['Apple', 'Banana', 'Carrot'].shift
fruit.delete_at(0)
clojure
(let [fruit ["Apple" "Banana" "Carrot"]
index 0]
(concat
(take index fruit)
(drop (+ index 1) fruit)))
index 0]
(concat
(take index fruit)
(drop (+ index 1) fruit)))
fantom
list := ["Apple", "Banana", "Carrot"]
list.removeAt(0)
list.removeAt(0)
Remove the last element of a list
ruby
list = ['Apple', 'Banana', 'Carrot']
list.delete_at(-1)
list.delete_at(-1)
list = ['Apple', 'Banana', 'Carrot']
list.pop
list.pop
clojure
(pop ["Apple" "Banana" "Carrot"])
fantom
list := ["Apple", "Banana", "Carrot"]
list.removeAt(-1)
list.removeAt(-1)
list := ["Apple", "Banana", "Carrot"]¨
list.pop
list.pop
Rotate a list
Given a list
["apple", "orange", "grapes", "bananas"], rotate it by removing the first item and placing it on the end to yield ["orange", "grapes", "bananas", "apple"]
ruby
items = ["apple", "orange", "grapes", "bananas"]
items << first = items.shift
# items is rotated
# first contains the first value in the list
items << first = items.shift
# items is rotated
# first contains the first value in the list
clojure
(let [fruit ["apple" "orange" "grapes" "bananas"]]
(concat (rest fruit) [(first fruit)])
(concat (rest fruit) [(first fruit)])
fantom
list := ["apple", "orange", "grapes", "bananas"]
list.add(list.removeAt(0))
list.add(list.removeAt(0))
Gather together corresponding elements from multiple lists
Given several lists, gather together the first element from every list, the second element from every list, and so on for all corresponding index values in the lists. E.g. for these three lists, first =
['Bruce', 'Tommy Lee', 'Bruce'], last = ['Willis', 'Jones', 'Lee'], years = [1955, 1946, 1940] the result should produce 3 actors. The middle actor should be Tommy Lee Jones.
ruby
first = ['Bruce', 'Tommy Lee', 'Bruce']; last = ['Willis', 'Jones', 'Lee']; years = [1955, 1946, 1940]
result = first.zip(last, years)
result = first.zip(last, years)
first = ['Bruce', 'Tommy Lee', 'Bruce']; last = ['Willis', 'Jones', 'Lee']; years = [1955, 1946, 1940]
result = [first, last, years].transpose
result = [first, last, years].transpose
clojure
(defn gatherer [listOfLists]
(if (empty? (first listOfLists))
() ; the base case for recursion
(cons
(map first listOfLists) ; get the first element of each of the lists
(gatherer (map rest listOfLists)) ; gather all the subsequent ones
)
)
)
(def firstnames '("Bruce" "Tommy Lee" "Bruce"))
(def lastnames '("Willis" "Jones" "Lee"))
(def years '(1955 1946 1940))
(println (gatherer [firstnames lastnames years]))
; -> ((Bruce Willis 1955) (Tommy Lee Jones 1946) (Bruce Lee 1940))
(if (empty? (first listOfLists))
() ; the base case for recursion
(cons
(map first listOfLists) ; get the first element of each of the lists
(gatherer (map rest listOfLists)) ; gather all the subsequent ones
)
)
)
(def firstnames '("Bruce" "Tommy Lee" "Bruce"))
(def lastnames '("Willis" "Jones" "Lee"))
(def years '(1955 1946 1940))
(println (gatherer [firstnames lastnames years]))
; -> ((Bruce Willis 1955) (Tommy Lee Jones 1946) (Bruce Lee 1940))
(def firstnames ["Bruce" "Tommy Lee" "Bruce"])
(def lastnames ["Willis" "Jones" "Lee"])
(def years [1955 1946 1940])
(println (map (fn [f l y] [f l y]) firstnames lastnames years))
(def lastnames ["Willis" "Jones" "Lee"])
(def years [1955 1946 1940])
(println (map (fn [f l y] [f l y]) firstnames lastnames years))
fantom
r := [,]
first.size.times |Int i| { r.add([first[i], last[i], years[i]]) }
echo(r)
first.size.times |Int i| { r.add([first[i], last[i], years[i]]) }
echo(r)
List Combinations
Given two source lists (or sets), generate a list (or set) of all the pairs derived by combining elements from the individual lists (sets). E.g. given suites =
['H', 'D', 'C', 'S'] and faces = ['2', '3', '4', '5', '6', '7', '8', '9', '10', 'J', 'Q', 'K', 'A'], generate the deck of 52 cards, confirm the deck size and check it contains an expected card, say 'Ace of Hearts'.
ruby
suites.each {|s| faces.each {|f| cards << [s, f]}}
puts "Deck %s \'Ace of Hearts\'" % if cards.include?(['h', 'A']) then "contains" else "does not contain" end
puts "Deck %s \'Ace of Hearts\'" % if cards.include?(['h', 'A']) then "contains" else "does not contain" end
clojure
(def suites ["H" "D" "C" "S"])
(def faces [2 3 4 5 6 7 8 9 10 "J" "Q" "K" "A"])
(defn listCards [] (for [s suites f faces] [f s]))
(some (partial = ["A" "H"]) (listCards))
; -> true
(count (listCards))
; -> 52
(def faces [2 3 4 5 6 7 8 9 10 "J" "Q" "K" "A"])
(defn listCards [] (for [s suites f faces] [f s]))
(some (partial = ["A" "H"]) (listCards))
; -> true
(count (listCards))
; -> 52
fantom
r := [,]
["2","3","4","5","6","7","8","9","10","J","Q","K","A"].each |Str c|
{ ["H","D","C","S"].each |Str s| { r.add([c,s]) } }
q := ["A","H"]
result := r.contains(q)
echo("Deck size=${r.size}, contains $q? -> $result")
["2","3","4","5","6","7","8","9","10","J","Q","K","A"].each |Str c|
{ ["H","D","C","S"].each |Str s| { r.add([c,s]) } }
q := ["A","H"]
result := r.contains(q)
echo("Deck size=${r.size}, contains $q? -> $result")
Perform an operation on every item of a list
Perform an operation on every item of a list, e.g.
for the list
the list of sizes of the strings, e.g.
for the list
["ox", "cat", "deer", "whale"] calculate
the list of sizes of the strings, e.g.
[2, 3, 4, 5]
ruby
["ox", "cat", "deer", "whale"].map{|i| i.length}
clojure
(map count ["ox" "cat" "deer" "whale"])
fantom
["ox", "cat", "deer", "whale"].map { it.size }
Split a list of things into numbers and non-numbers
Given a list that might contain e.g. a string, an integer, a float and a date,
split the list into numbers and non-numbers.
split the list into numbers and non-numbers.
ruby
now=Time.now
things=["hello", 25, 3.14, now]
numbers=things.select{|i| i.is_a? Numeric}
others=things-numbers
things=["hello", 25, 3.14, now]
numbers=things.select{|i| i.is_a? Numeric}
others=things-numbers
now=Time.now
things=["hello", 25, 3.14, now]
numbers, others=things.partition{|i| i.is_a? Numeric}
things=["hello", 25, 3.14, now]
numbers, others=things.partition{|i| i.is_a? Numeric}
clojure
(def jumble [3 "Bill" 5.7 '("A" "B" "C")]) ; int, string, float, list
(defn numberNonNumberSorter [jumbledList]
(if (empty? jumbledList)
(hash-map :numbers [], :nonnumbers []) ; recursion base case - return two empty lists
(let [head (first jumbledList)] ; let <head> be the first element in the list
(let [tailresult (numberNonNumberSorter (rest jumbledList))] ; tailresult applies recursively to the remainder
(if (number? head) ; is head a number?
(hash-map
:numbers (cons head (tailresult :numbers)) ; add <head> to the numbers
:nonnumbers (tailresult :nonnumbers)) ; leave nonnumbers the same
(hash-map
:numbers (tailresult :numbers) ; leave numbers the same
:nonnumbers (cons head (tailresult :nonnumbers))) ; add <head> to nonnumbers
)
)
)
)
)
(println (numberNonNumberSorter jumble))
; -> {:nonnumbers (Bill (A B C)), :numbers (3 5.7)}
(defn numberNonNumberSorter [jumbledList]
(if (empty? jumbledList)
(hash-map :numbers [], :nonnumbers []) ; recursion base case - return two empty lists
(let [head (first jumbledList)] ; let <head> be the first element in the list
(let [tailresult (numberNonNumberSorter (rest jumbledList))] ; tailresult applies recursively to the remainder
(if (number? head) ; is head a number?
(hash-map
:numbers (cons head (tailresult :numbers)) ; add <head> to the numbers
:nonnumbers (tailresult :nonnumbers)) ; leave nonnumbers the same
(hash-map
:numbers (tailresult :numbers) ; leave numbers the same
:nonnumbers (cons head (tailresult :nonnumbers))) ; add <head> to nonnumbers
)
)
)
)
)
(println (numberNonNumberSorter jumble))
; -> {:nonnumbers (Bill (A B C)), :numbers (3 5.7)}
(group-by number? ["hello" 42 3.14 (Date.)])
fantom
things := ["hello", 25, 3.14, Time.now]
numbers := things.findType(Num#)
nonNumbers := things.exclude { numbers.contains(it) }
numbers := things.findType(Num#)
nonNumbers := things.exclude { numbers.contains(it) }
Test if a condition holds for all items of a list
Given a list, test if a certain logical condition (i.e. predicate) holds for all items of the list.
ruby
[2, 3, 4].all? { |x| x > 1 }
clojure
(every? #(> % 1) [2 3 4])
fantom
echo([2,3,4].all{ it>1 })
Test if a condition holds for any items of a list
Given a list, test if a certain logical condition (i.e. predicate) holds for any items of the list.
ruby
[2, 3, 4].any? { |x| x > 3 }
clojure
; The standard library in Clojure has "not-any?" but (oddly enough) no "any?"
(defn any? [pred coll]
((complement not-any?) pred coll))
(any? #(> % 3) [2 3 4])
(defn any? [pred coll]
((complement not-any?) pred coll))
(any? #(> % 3) [2 3 4])
(some #(> % 3) [2 3 4])
fantom
echo([2,3,4].any{ it==4 })
Define an empty map
ruby
map = {}
clojure
(def m {})
fantom
map := [:]
Define an unmodifiable empty map
ruby
map = {}.freeze
clojure
; Clojure maps are immutable
(def m {})
(def m {})
fantom
map := [:].ro
Define an initial map
Define the map
{circle:1, triangle:3, square:4}
ruby
shapes = {'circle'=>1, 'triangle'=>3, 'square'=>4}
shapes = Hash['circle', 1, 'triangle', 3, 'square', 4]
shapes = { :circle => 1, :triangle => 3, :square => 4 }
clojure
(def m '{circle 1 triangle 1 square 4})
fantom
map := ["circle":1, "triangle":2, "square":4]
Check if a key exists in a map
Given a map pets
{joe:cat,mary:turtle,bill:canary} print "ok" if an pet exists for "mary"
ruby
puts "ok" if map.has_key?('mary')
puts "ok" if map['mary'] # Only works if map entry can't be nil or false
clojure
(if (contains? '{joe cat mary turtle bill canary} 'mary)
(println "ok"))
(println "ok"))
fantom
map := ["joe":"cat", "mary":"turtle", "bill":"canary"]
if (map.containsKey("mary")) echo("ok")
if (map.containsKey("mary")) echo("ok")
Retrieve a value from a map
Given a map pets
{joe:cat,mary:turtle,bill:canary} print the pet for "joe" ("cat")
ruby
puts map['joe']
clojure
(def pets '{joe cat mary turtle bill canary})
(println (get pets 'joe))
(println (get pets 'joe))
fantom
map := ["joe":"cat", "mary":"turtle", "bill":"canary"]
pet := map["joe"]
echo("pet=$pet")
pet := map["joe"]
echo("pet=$pet")
Add an entry to a map
Given an empty pets map, add the mapping from
"rob" to "dog"
ruby
pets['rob']='dog'
clojure
(assoc {} 'rob 'dog)
fantom
map["rob"] = "dog"
Remove an entry from a map
Given a map pets
{joe:cat,mary:turtle,bill:canary} remove the mapping for "bill" and print "canary"
ruby
puts map.delete :bill
clojure
; Maps are immutable
; The following expression will return a new map without the 'bill key
(let [pets '{joe cat mary turtle bill canary}]
(println (get pets 'bill))
(dissoc pets 'bill))
; The following expression will return a new map without the 'bill key
(let [pets '{joe cat mary turtle bill canary}]
(println (get pets 'bill))
(dissoc pets 'bill))
fantom
pet := map.remove("bill")
echo ("pet=$pet")
echo ("pet=$pet")
Create a histogram map from a list
Given the list
[a,b,a,c,b,b], produce a map {a:2, b:3, c:1} which contains the count of each unique item in the list
ruby
histogram = {}
list.each { |item| histogram[item] = (histogram[item] || 0) +1 }
list.each { |item| histogram[item] = (histogram[item] || 0) +1 }
list = %w{a b a c b b}
histogram = list.each_with_object(Hash.new(0)) do |item, hash|
hash[item] += 1
end
p histogram # => {"a"=>2, "b"=>3, "c"=>1}
histogram = list.each_with_object(Hash.new(0)) do |item, hash|
hash[item] += 1
end
p histogram # => {"a"=>2, "b"=>3, "c"=>1}
list.inject(Hash.new(0)) {|h, item| h[item] += 1; h}
clojure
(let [l '[a b a c b b]]
(loop [m {}
d (distinct l)]
(let [item (first d)]
(if (zero? (count d))
m
(recur
(assoc m
item
(count
(filter #(= item %) l)))
(rest d))))))
(loop [m {}
d (distinct l)]
(let [item (first d)]
(if (zero? (count d))
m
(recur
(assoc m
item
(count
(filter #(= item %) l)))
(rest d))))))
(->> [:a :b :a :c :b :b]
(group-by identity)
(reduce (fn [m e] (assoc m (first e) (count (second e)))) {}))
(group-by identity)
(reduce (fn [m e] (assoc m (first e) (count (second e)))) {}))
(reduce conj {} (for [[x xs] (group-by identity "abacbb")] [x (count xs)]))
(frequencies ["a","b","a","c","b","b"])
(frequencies '[a b a c b b])
fantom
list := ["a","b","a","c","b","b"]
map := [Str:Int][:]
list.each |Str s, Int i| { if(!map.containsKey(s)) map.add(s,1); else map[s] = ++map[s] }
echo (map)
map := [Str:Int][:]
list.each |Str s, Int i| { if(!map.containsKey(s)) map.add(s,1); else map[s] = ++map[s] }
echo (map)
Categorise a list
Given the list
[one, two, three, four, five] produce a map {3:[one, two], 4:[four, five], 5:[three]} which sorts elements into map entries based on their length
ruby
lengths = {}
list.each do |x|
len = x.size
lengths[len] = (lengths[len] || [])
lengths[len] << x
end
list.each do |x|
len = x.size
lengths[len] = (lengths[len] || [])
lengths[len] << x
end
lengths = list.group_by {|x| x.size}
list.inject({}) { |h,x| (h[x.size]||=[]) << x; h }
clojure
(loop [m {}
l ["one" "two" "three" "four" "five"]]
(if (zero? (count l))
m
(let [item (first l)
key (count item)]
(recur
(assoc m key (cons item (get m key [])))
(rest l)))))
l ["one" "two" "three" "four" "five"]]
(if (zero? (count l))
m
(let [item (first l)
key (count item)]
(recur
(assoc m key (cons item (get m key [])))
(rest l)))))
(group-by count ["one" "two" "three" "four" "five"])
fantom
list := ["one", "two", "three", "four", "five"]
map := [Int:List][:]
list.each { List l := map[it.size] ?: [,]; map[it.size] = l.add(it) }
echo(map)
map := [Int:List][:]
list.each { List l := map[it.size] ?: [,]; map[it.size] = l.add(it) }
echo(map)
Perform an action if a condition is true (IF .. THEN)
Given a variable name, if the value is
"Bob", display the string "Hello, Bob!". Perform no action if the name is not equal.
ruby
if (name=='Bob')
puts "Hello, Bob!"
end
puts "Hello, Bob!"
end
puts "Hello, Bob!" if name=='Bob'
clojure
(def person "Bob")
(if (= person "Bob")
(println "Hello, Bob!"))
(if (= person "Bob")
(println "Hello, Bob!"))
fantom
if (name=="Bob") echo("Hello, Bob!")
Perform different actions depending on a boolean condition (IF .. THEN .. ELSE)
Given a variable age, if the value is greater than 42 display
"You are old", otherwise display "You are young"
ruby
if (age > 42)
puts "You are old"
else
puts "You are young"
end
puts "You are old"
else
puts "You are young"
end
puts (age>42) ? "You are old" : "You are young"
puts "You are #{age > 42 ? "old" : "young"}"
clojure
(def age 41)
(if (> age 42) "You are old" "You are young")
(if (> age 42) "You are old" "You are young")
fantom
if (age > 42)
echo("You are old")
else
echo("You are young")
echo("You are old")
else
echo("You are young")
echo((age > 42) ? "You are old" : "You are young")
Perform different actions depending on several boolean conditions (IF .. THEN .. ELSIF .. ELSE)
ruby
if age > 84
puts "You are really ancient"
elsif age > 30
puts "You are middle-aged"
else
puts "You are young"
end
puts "You are really ancient"
elsif age > 30
puts "You are middle-aged"
else
puts "You are young"
end
case
when age > 84 then puts "You are really ancient"
when age > 30 then puts "You are middle-aged"
else puts "You are young"
end
when age > 84 then puts "You are really ancient"
when age > 30 then puts "You are middle-aged"
else puts "You are young"
end
clojure
(println
(condp <= age
84 "You are really ancient"
30 "You are middle aged"
"You are young"))
(condp <= age
84 "You are really ancient"
30 "You are middle aged"
"You are young"))
fantom
if (age > 84)
echo("You are really ancient")
else if (age > 30)
echo("You are middle-aged")
else
echo("You are young")
echo("You are really ancient")
else if (age > 30)
echo("You are middle-aged")
else
echo("You are young")
Replacing a conditional with many branches with a switch/case statement
Many languages support more compact forms of branching than just if ... then ... else such as switch or case or match. Use such a form to add an appropriate placing suffix to the numbers 1..40, e.g. 1st, 2nd, 3rd, 4th, ..., 11th, 12th, ... 39th, 40th
ruby
def suffixed(number)
last_digit = number.to_s[-1..-1].to_i
suffix = case last_digit
when 1 then 'st'
when 2 then 'nd'
when 3 then 'rd'
else 'th'
end
suffix = 'th' if (11..13).include?(number)
"#{number}#{suffix}"
end
(1..40).each {|n| puts suffixed(n) }
last_digit = number.to_s[-1..-1].to_i
suffix = case last_digit
when 1 then 'st'
when 2 then 'nd'
when 3 then 'rd'
else 'th'
end
suffix = 'th' if (11..13).include?(number)
"#{number}#{suffix}"
end
(1..40).each {|n| puts suffixed(n) }
clojure
(def n 112)
(println (str n
(let [rem (mod n 100)]
(if (and (>= rem 11) (<= rem 13))
"th"
(condp = (mod n 10)
1 "st"
2 "nd"
3 "rd"
"th")))))
(println (str n
(let [rem (mod n 100)]
(if (and (>= rem 11) (<= rem 13))
"th"
(condp = (mod n 10)
1 "st"
2 "nd"
3 "rd"
"th")))))
fantom
suffix := |Int n -> Str|
{
if ((4..20).contains(n % 100))
return "th"
switch((n.toStr)[-1])
{
case '1': return "st"
case '2': return "nd"
case '3': return "rd"
default: return "th"
}
}
(1..40).each { echo("$it${suffix(it)}") }
{
if ((4..20).contains(n % 100))
return "th"
switch((n.toStr)[-1])
{
case '1': return "st"
case '2': return "nd"
case '3': return "rd"
default: return "th"
}
}
(1..40).each { echo("$it${suffix(it)}") }
Perform an action multiple times based on a boolean condition, checked before the first action (WHILE .. DO)
Starting with a variable x=1, Print the sequence
"1,2,4,8,16,32,64,128," by doubling x and checking that x is less than 150.
ruby
x=1
while x < 150
puts x
x <<= 1
end
while x < 150
puts x
x <<= 1
end
clojure
(take-while #(< % 150) (iterate #(* 2 %) 1))
fantom
x := 1
while (x < 150) {
Env.cur.out.print("$x,")
x *= 2
}
echo
while (x < 150) {
Env.cur.out.print("$x,")
x *= 2
}
echo
Perform an action multiple times based on a boolean condition, checked after the first action (DO .. WHILE)
Simulate rolling a die until you get a six. Produce random numbers, printing them until a six is rolled. An example output might be
"4,2,1,2,6"
ruby
# Ruby has no DO..WHILE construct. Need to write it as a WHILE
rnd = 0
while (rnd != 6)
rnd = rand(6)+1
print rnd
print "," if (rnd!=6)
end
rnd = 0
while (rnd != 6)
rnd = rand(6)+1
print rnd
print "," if (rnd!=6)
end
begin
rnd = rand(6)+1
print rnd
print "," if rnd!=6
end while rnd != 6
rnd = rand(6)+1
print rnd
print "," if rnd!=6
end while rnd != 6
# This uses Enumerators, ad it becomes almost functional style...
games = Enumerator.new do |yielder|
yielder.yield rand(6) + 1 while true
end
puts games.take_while {|roll| roll != 6}.join(",")
games = Enumerator.new do |yielder|
yielder.yield rand(6) + 1 while true
end
puts games.take_while {|roll| roll != 6}.join(",")
clojure
(loop [r (rand-int 6)]
(if (= r 5)
nil
(do
(println r)
(recur (rand-int 6)))))
(if (= r 5)
nil
(do
(println r)
(recur (rand-int 6)))))
fantom
rnd := 0
while(rnd != 6) {
rnd = Int.random(1..6)
Env.cur.out.print(rnd)
if (rnd != 6)
Env.cur.out.print(",")
}
echo
while(rnd != 6) {
rnd = Int.random(1..6)
Env.cur.out.print(rnd)
if (rnd != 6)
Env.cur.out.print(",")
}
echo
Perform an action a fixed number of times (FOR)
Display the string
"Hello" five times like "HelloHelloHelloHelloHello"
ruby
puts "Hello"*5
5.times { print "Hello" }
clojure
(dotimes [_ 5]
(print "Hello"))
(print "Hello"))
fantom
5.times { Env.cur.out.print("Hello") }
for (i := 0; i < 5; i++)
Env.cur.out.print("Hello")
Env.cur.out.print("Hello")
(1..5).each { Env.cur.out.print("Hello") }
Perform an action a fixed number of times with a counter
Display the string
"10 .. 9 .. 8 .. 7 .. 6 .. 5 .. 4 .. 3 .. 2 .. 1 .. Liftoff!"
ruby
10.downto(1) { |n| print n, " .. " }
puts "Liftoff!"
puts "Liftoff!"
clojure
(dotimes [i 10]
(print (str (- 10 i) " .. ")))
(println "Liftoff!")
(print (str (- 10 i) " .. ")))
(println "Liftoff!")
fantom
(10..1).each { Env.cur.out.print("$it .. ") }
Env.cur.out.print("Liftoff!")
Env.cur.out.print("Liftoff!")
for (i := 10; i >= 1; i--)
Env.cur.out.print("$i .. ")
Env.cur.out.print("Liftoff!")
Env.cur.out.print("$i .. ")
Env.cur.out.print("Liftoff!")
Read the contents of a file into a string
ruby
file = File.new("Solution108.rb")
whole_file = file.read
whole_file = file.read
clojure
(slurp "/tmp/foobar")
fantom
contents := File(`file.text`).readAllStr
Process a file one line at a time
Open the source file to your solution and print each line in the file, prefixed by the line number, like:
1> First line of file
2> Second line of file
3> Third line of file
1> First line of file
2> Second line of file
3> Third line of file
ruby
File.open("Solution103.rb").each_with_index { |line, count|
puts "#{count} > #{line}
}
puts "#{count} > #{line}
}
clojure
(defn read-line-by-line [fn]
(reduce str (map (partial format "%d> %s\n")
(iterate inc 1)
(read-lines fn))))
(reduce str (map (partial format "%d> %s\n")
(iterate inc 1)
(read-lines fn))))
fantom
File(`input.text`).readAllLines.each |Str s, Int i| { echo("${i+1}> $s") }
Write a string to a file
ruby
File.new("a_file", "w") << "some text"
clojure
(with-out-writer "output.txt" (println "Hello file!"))
fantom
File(`out.txt`).out.writeChars("some text").flush
Append to a file
ruby
file = File.new('/tmp/test.txt', 'a+') ; file.puts 'This line appended to file!!' ; file.close()
clojure
(with-out-append-writer "output.txt" (println "This is appended to the file"))
fantom
File(`out.txt`).out(true).writeChars("some text").flush
Process each file in a directory
ruby
directory = '/tmp' ; Dir.foreach(directory) {|file| puts "#{file}"}
clojure
; (defn process-file [f] "process one file" body...)
(map process-file (.listFiles (File. ".")))
(map process-file (.listFiles (File. ".")))
fantom
File(`./`).list.each { process(it) }
Process each file in a directory recursively
ruby
def procdir(dirname)
Dir.foreach(dirname) do |dir|
dirpath = dirname + '/' + dir
if File.directory?(dirpath) then
if dir != '.' && dir != '..' then
puts "DIRECTORY: #{dirpath}" ; procdir(dirpath)
end
else
puts "FILE: #{dirpath}"
end
end
end
# ------
procdir('/tmp')
Dir.foreach(dirname) do |dir|
dirpath = dirname + '/' + dir
if File.directory?(dirpath) then
if dir != '.' && dir != '..' then
puts "DIRECTORY: #{dirpath}" ; procdir(dirpath)
end
else
puts "FILE: #{dirpath}"
end
end
end
# ------
procdir('/tmp')
clojure
; (defn process-file [f] "process one file" body...)
(map process-file (file-seq (File. ".")))
(map process-file (file-seq (File. ".")))
fantom
File(`./`).walk { process(it) }
Parse a date and time from a string
Given the string
"2008-05-06 13:29", parse it as a date representing 6th March, 2008 1:29:00pm in the local time zone.
ruby
# With timezone info
puts Time.parse('2008-05-06 13:29')
puts Time.parse('2008-05-06 13:29')
clojure
(.. (SimpleDateFormat. "yyyy-MM-dd HH:mm")
(parse "2008-05-06 13:29"))
(parse "2008-05-06 13:29"))
fantom
dt := DateTime.fromLocale("2008-05-06 13:29", "YYYY-MM-DD hh:mm")
Display information about a date
Display the day of month, day of year, month name and day name of the day 8 days from now.
ruby
require 'date'
next_week = Date.today + 8
puts next_week.day # day of month
puts next_week.yday # day of year
puts next_week.strftime('%B') # month name
puts next_week.strftime('%A') # day name
next_week = Date.today + 8
puts next_week.day # day of month
puts next_week.yday # day of year
puts next_week.strftime('%B') # month name
puts next_week.strftime('%A') # day name
clojure
(let [cal (Calendar/getInstance)]
(.add cal Calendar/DAY_OF_YEAR 8)
(println (.format (SimpleDateFormat. "d, D, MMMM, EEEE")
(.getTime cal))))
(.add cal Calendar/DAY_OF_YEAR 8)
(println (.format (SimpleDateFormat. "d, D, MMMM, EEEE")
(.getTime cal))))
fantom
date := Date.today + 8day
echo(date.day)
echo(date.dayOfYear)
echo(date.month.localeFull)
echo(date.weekday.localeFull)
echo(date.day)
echo(date.dayOfYear)
echo(date.month.localeFull)
echo(date.weekday.localeFull)
Display the current date and time
Create a Date object representing the current date and time. Print it out.
If you can also do this without creating a Date object you can show that too.
If you can also do this without creating a Date object you can show that too.
ruby
puts DateTime.now
clojure
(import 'java.util.Date)
(println (str (Date.)))
(println (str (Date.)))
fantom
echo(DateTime.now)
Define a class
Declare a class named Greeter that takes a string on creation and greets using this string if you call the
"greet" method.
ruby
class Greeter
def initialize(whom) @whom = whom end
def greet() puts "Hello, #{@whom}!" end
end
(Greeter.new("world")).greet()
def initialize(whom) @whom = whom end
def greet() puts "Hello, #{@whom}!" end
end
(Greeter.new("world")).greet()
clojure
(defprotocol IGreeter
(greet [this]))
(deftype Greeter [whom]
IGreeter
(greet [this]
(println (str "Hello, " whom))))
(greet (Greeter. "world"))
(greet [this]))
(deftype Greeter [whom]
IGreeter
(greet [this]
(println (str "Hello, " whom))))
(greet (Greeter. "world"))
(defn greeter [whom]
{:whom whom})
(defn greet [g]
(println (str "Hello, " (:whom g))))
(greet (greeter "world"))
{:whom whom})
(defn greet [g]
(println (str "Hello, " (:whom g))))
(greet (greeter "world"))
fantom
class Greeter
{
private Str whom
new make(Str whom) { this.whom = whom }
Void greet() { echo("Hello, $whom") }
}
Greeter("world").greet
{
private Str whom
new make(Str whom) { this.whom = whom }
Void greet() { echo("Hello, $whom") }
}
Greeter("world").greet
Instantiate object with mutable state
Reimplement the Greeter class so that the
For example, if the greetee is changed to
Hello, Tommy!
The getter would then be used to display the line:
I have just greeted Tommy.
'whom' property or data member remains private but is mutable, and is provided with getter and setter methods. Invoke the setter to change the greetee, invoke 'greet', then use the getter in displaying the line, "I have just greeted {whom}.".
For example, if the greetee is changed to
'Tommy' using the setter, the 'greet' method would display:
Hello, Tommy!
The getter would then be used to display the line:
I have just greeted Tommy.
ruby
class Greeter
attr_accessor :whom
def initialize(whom) @whom = whom end
def greet() puts "Hello, #{@whom}!" end
end
greeter = Greeter.new("world") ; greeter.greet()
greeter.whom = 'Tommy' ; greeter.greet()
puts "I have just greeted %s" % greeter.whom
attr_accessor :whom
def initialize(whom) @whom = whom end
def greet() puts "Hello, #{@whom}!" end
end
greeter = Greeter.new("world") ; greeter.greet()
greeter.whom = 'Tommy' ; greeter.greet()
puts "I have just greeted %s" % greeter.whom
clojure
(defn greeter [whom]
(atom {:whom whom}))
(defn get-whom [g]
(:whom @g))
(defn set-whom [g whom]
(swap! g #(conj % {:whom whom})))
(defn greet [g]
(println (str "Hello, " (:whom @g) "!")))
; using the "class"
(let [g (greeter "world")]
(greet g)
(set-whom g "Tommy")
(greet g)
(println (str "I have just greeted " (get-whom g) ".")))
; or same effect without using any variables
(println (str "I have just greeted "
(get-whom (doto (greeter "world")
(greet)
(set-whom "Tommy")
(greet)))
"."))
(atom {:whom whom}))
(defn get-whom [g]
(:whom @g))
(defn set-whom [g whom]
(swap! g #(conj % {:whom whom})))
(defn greet [g]
(println (str "Hello, " (:whom @g) "!")))
; using the "class"
(let [g (greeter "world")]
(greet g)
(set-whom g "Tommy")
(greet g)
(println (str "I have just greeted " (get-whom g) ".")))
; or same effect without using any variables
(println (str "I have just greeted "
(get-whom (doto (greeter "world")
(greet)
(set-whom "Tommy")
(greet)))
"."))
fantom
class Greeter
{
new make(Str whom) { this.whom = whom }
Void greet() { echo("Hello, $whom!") }
Str whom
}
greeter := Greeter("world")
greeter.greet
greeter.whom = "Tommy"
echo("I have just greeted ${greeter.whom}.")
{
new make(Str whom) { this.whom = whom }
Void greet() { echo("Hello, $whom!") }
Str whom
}
greeter := Greeter("world")
greeter.greet
greeter.whom = "Tommy"
echo("I have just greeted ${greeter.whom}.")
Implement Inheritance Heirarchy
Implement a Shape abstract class which will form the base of an inheritance hierarchy that models 2D geometric shapes. It will have:
* A non-mutable
* A
* A
* A non-mutable
'name' property or data member set by derived or descendant classes at construction time
* A
'area' method intended to be overridden by derived or descendant classes ( double precision floating point return value)
* A
'print' method (also for overriding) will display the shape's name, area, and all shape-specific values
Two derived or descendant classes will be created:
* Circle -> Constructor requires a 'radius' argument, and a 'circumference' method to be implemented
* Rectangle -> Constructor requires 'length' and 'breadth' arguments, and a 'perimeter' method to be implemented
Instantiate an object of each class, and invoke each objects 'print' method to show relevant details.
ruby
class Shape
def initialize(name="") @name = name end
end
class Circle < Shape
def initialize(radius) super("circle") ; @radius = radius end
def area() 3.14159 * @radius * @radius end
def circumference() 2 * 3.14159 * @radius end
def print()
puts "I am a #{@name} with ->"
puts "Radius: %.2f" % @radius
puts "Area: %.2f" % self.area()
puts "Circumference: %.2f\n" % self.circumference()
end
end
class Rectangle < Shape
def initialize(length, breadth) super("rectangle") ; @length = length ; @breadth = breadth end
def area() @length * @breadth end
def perimeter() 2 * @length + 2 * @breadth end
def print()
puts "I am a #{@name} with ->"
printf("Length, Width: %.2f, %.2f\n", @length, @breadth)
puts "Area: %.2f" % self.area()
puts "Perimeter: %.2f\n" % self.perimeter()
end
end
# ------
shapes = [Circle.new(4.2), Rectangle.new(2.7, 3.1), Rectangle.new(6.2, 2.6), Circle.new(17.3)]
shapes.each {|shape| shape.print}
def initialize(name="") @name = name end
end
class Circle < Shape
def initialize(radius) super("circle") ; @radius = radius end
def area() 3.14159 * @radius * @radius end
def circumference() 2 * 3.14159 * @radius end
def print()
puts "I am a #{@name} with ->"
puts "Radius: %.2f" % @radius
puts "Area: %.2f" % self.area()
puts "Circumference: %.2f\n" % self.circumference()
end
end
class Rectangle < Shape
def initialize(length, breadth) super("rectangle") ; @length = length ; @breadth = breadth end
def area() @length * @breadth end
def perimeter() 2 * @length + 2 * @breadth end
def print()
puts "I am a #{@name} with ->"
printf("Length, Width: %.2f, %.2f\n", @length, @breadth)
puts "Area: %.2f" % self.area()
puts "Perimeter: %.2f\n" % self.perimeter()
end
end
# ------
shapes = [Circle.new(4.2), Rectangle.new(2.7, 3.1), Rectangle.new(6.2, 2.6), Circle.new(17.3)]
shapes.each {|shape| shape.print}
clojure
(defmulti area :Shape)
(defmulti print :Shape)
; Circle methods
(defn circle [r]
{:Shape :Circle
:name "Circle"
:radius r})
(defn circumference [c]
(* 2 Math/PI (:radius c)))
(defmethod area :Circle [c]
(* Math/PI (:radius c) (:radius c)))
(defmethod print :Circle [c]
(println (format "I am a %s with ->" (:name c)))
(println (format "Radius: %.2f" (:radius c)))
(println (format "Area: %.2f" (area c)))
(println (format "Circumference: %.2f" (circumference c))))
; Rectangle methods
(defn rectangle [l b]
{:Shape :Rectangle
:name "Rectangle"
:length l
:breadth b})
(defn perimeter [r]
(+ (* 2 (:length r)) (* 2 (:breadth r))))
(defmethod area :Rectangle [r]
(* (:length r) (:breadth r)))
(defmethod print :Rectangle [r]
(println (format "I am a %s with ->" (:name r)))
(println (format "Length, Width: %.2f, %.2f" (:length r) (:breadth r)))
(println (format "Area: %.2f" (area r)))
(println (format "Perimeter: %.2f" (perimeter r))))
; usage of the "classes"
(let [shapes (list (circle 4.2) (rectangle 2.7 3.1) (rectangle 6.2 2.6) (circle 17.3))]
(doseq [shape shapes]
(print shape)))
(defmulti print :Shape)
; Circle methods
(defn circle [r]
{:Shape :Circle
:name "Circle"
:radius r})
(defn circumference [c]
(* 2 Math/PI (:radius c)))
(defmethod area :Circle [c]
(* Math/PI (:radius c) (:radius c)))
(defmethod print :Circle [c]
(println (format "I am a %s with ->" (:name c)))
(println (format "Radius: %.2f" (:radius c)))
(println (format "Area: %.2f" (area c)))
(println (format "Circumference: %.2f" (circumference c))))
; Rectangle methods
(defn rectangle [l b]
{:Shape :Rectangle
:name "Rectangle"
:length l
:breadth b})
(defn perimeter [r]
(+ (* 2 (:length r)) (* 2 (:breadth r))))
(defmethod area :Rectangle [r]
(* (:length r) (:breadth r)))
(defmethod print :Rectangle [r]
(println (format "I am a %s with ->" (:name r)))
(println (format "Length, Width: %.2f, %.2f" (:length r) (:breadth r)))
(println (format "Area: %.2f" (area r)))
(println (format "Perimeter: %.2f" (perimeter r))))
; usage of the "classes"
(let [shapes (list (circle 4.2) (rectangle 2.7 3.1) (rectangle 6.2 2.6) (circle 17.3))]
(doseq [shape shapes]
(print shape)))
fantom
abstract class Shape
{
const Str name
new make(Str name) { this.name = name }
abstract Float area()
abstract Void print()
}
class Circle : Shape
{
private Float radius
new make(Float radius) : super("circle") { this.radius = radius }
Float circumference() { return 2 * Float.pi * radius }
override Float area() { return Float.pi * radius.pow(2.0f) }
override Void print()
{
echo("I am a $name with radius $radius, area $area
and circumference $circumference")
}
}
class Rectangle : Shape
{
private Float length
private Float breadth
new make(Float length, Float breadth) : super("rectangle")
{
this.length = length
this.breadth = breadth
}
Float perimeter() { return 2 * (length + breadth) }
override Float area() { return length * breadth }
override Void print()
{
echo("I am a $name with length $length, breadth $breadth,
area $area and perimeter $perimeter")
}
}
circle := Circle(4.0f)
circle.print
rectangle := Rectangle(2.0f, 5.5f)
rectangle.print
{
const Str name
new make(Str name) { this.name = name }
abstract Float area()
abstract Void print()
}
class Circle : Shape
{
private Float radius
new make(Float radius) : super("circle") { this.radius = radius }
Float circumference() { return 2 * Float.pi * radius }
override Float area() { return Float.pi * radius.pow(2.0f) }
override Void print()
{
echo("I am a $name with radius $radius, area $area
and circumference $circumference")
}
}
class Rectangle : Shape
{
private Float length
private Float breadth
new make(Float length, Float breadth) : super("rectangle")
{
this.length = length
this.breadth = breadth
}
Float perimeter() { return 2 * (length + breadth) }
override Float area() { return length * breadth }
override Void print()
{
echo("I am a $name with length $length, breadth $breadth,
area $area and perimeter $perimeter")
}
}
circle := Circle(4.0f)
circle.print
rectangle := Rectangle(2.0f, 5.5f)
rectangle.print
Implement and use an Interface
Create a Serializable interface consisting of
* Accept a stream or handle or descriptor argument for the source or destination
* Save to destination or restore from source the properties or data members of the implementing class (restrict yourself to the primitive types
Next, create a Person class which has
'save' and 'restore' methods, each of which:
* Accept a stream or handle or descriptor argument for the source or destination
* Save to destination or restore from source the properties or data members of the implementing class (restrict yourself to the primitive types
'int' and 'string')
Next, create a Person class which has
'name' and 'age' properties or data members and implements this interface. Instantiate a Person object, save it to a serial stream, and instantiate a new Person object by restoring it from the serial stream.
ruby
class Person
def initialize(name, age)
@name, @age = name, age
end
end
tom = Person.new("Tom Bones", 23)
File.open('tommy.dump', 'w+') {|f| f.write(Marshal.dump(tommy)) }
toms_clone = Marshal.load(File.read('tommy.dump'))
def initialize(name, age)
@name, @age = name, age
end
end
tom = Person.new("Tom Bones", 23)
File.open('tommy.dump', 'w+') {|f| f.write(Marshal.dump(tommy)) }
toms_clone = Marshal.load(File.read('tommy.dump'))
clojure
(defn person [name age]
{:name name :age age})
(defn show [p]
(println (format "Name=%s Age=%d" (:name p) (:age p))))
(defn save [p filename]
(with-out-writer filename (pr p)))
(defn restore [filename]
(read (PushbackReader. (reader filename))))
(let [p (person "Ken" 38)]
(show p)
(save p *person-fn*))
(let [ser-p (restore *person-fn*)]
(show ser-p))
{:name name :age age})
(defn show [p]
(println (format "Name=%s Age=%d" (:name p) (:age p))))
(defn save [p filename]
(with-out-writer filename (pr p)))
(defn restore [filename]
(read (PushbackReader. (reader filename))))
(let [p (person "Ken" 38)]
(show p)
(save p *person-fn*))
(let [ser-p (restore *person-fn*)]
(show ser-p))
fantom
@Serializable
class Person
{
Str name
Int age
new make(|This| f) { f(this) }
}
person := Person() { name="Tom Bones"; age=23 }
File(`tommy.dump`).out.writeObj(person).close
Person tom := File(`tommy.dump`).in.readObj
class Person
{
Str name
Int age
new make(|This| f) { f(this) }
}
person := Person() { name="Tom Bones"; age=23 }
File(`tommy.dump`).out.writeObj(person).close
Person tom := File(`tommy.dump`).in.readObj
Check your language appears on the langref.org site
Your language name should appear within the HTML found at the http:
//langreg.org main page.
ruby
Net::HTTP.start(URL, 80) do |http|
status = if http.get('/').body =~ /#{SRCHEXP}/ then "offers" else "does not offer" end
puts "http:\/\/#{URL} #{status} #{LANGUAGE}"
end
status = if http.get('/').body =~ /#{SRCHEXP}/ then "offers" else "does not offer" end
puts "http:\/\/#{URL} #{status} #{LANGUAGE}"
end
clojure
(def *url* "http://langref.org/")
(def *lang* "clojure")
(with-open [ stream (.openStream (URL. *url*)) ]
(let [ body (str (line-seq (BufferedReader. (InputStreamReader. stream)))) ]
(str "Language " *lang* " does "
(if-not (re-matches (re-pattern (str ".*" *url* *lang* ".*")) body) "not ")
"exist")))
(def *lang* "clojure")
(with-open [ stream (.openStream (URL. *url*)) ]
(let [ body (str (line-seq (BufferedReader. (InputStreamReader. stream)))) ]
(str "Language " *lang* " does "
(if-not (re-matches (re-pattern (str ".*" *url* *lang* ".*")) body) "not ")
"exist")))
fantom
language := "Fantom"
url := `http://langref.org/`
response := WebClient(url).getStr
if (Regex.fromStr("\\b$language.lower\\b").matcher(response).find)
echo("Language $language appears at ${url}.")
url := `http://langref.org/`
response := WebClient(url).getStr
if (Regex.fromStr("\\b$language.lower\\b").matcher(response).find)
echo("Language $language appears at ${url}.")
Process an XML document
Given the XML Document:
<shopping>
<item name=
<item name=
</shopping>
Print out the total cost of the items, e.g. $14.50
<shopping>
<item name=
"bread" quantity="3" price="2.50"/>
<item name=
"milk" quantity="2" price="3.50"/>
</shopping>
Print out the total cost of the items, e.g. $14.50
ruby
#!/usr/bin/env ruby
# needed to parse xml
require 'rexml/document'
# grab the file
file = File.new('shop.xml')
# load it as an xml document
doc = REXML::Document.new(file)
# initialize the total to 0 as a float
total = 0.0
# cycle through the items
doc.elements.each('shopping/item') do |item|
# add the price to the total
total += item.attributes['price'].to_f
end
# round the total to the nearest 0.01
total = (total*100.0).round/100.0
# pad the output with the proper number of trailing 0's
printf "$%.2f\n", total
# needed to parse xml
require 'rexml/document'
# grab the file
file = File.new('shop.xml')
# load it as an xml document
doc = REXML::Document.new(file)
# initialize the total to 0 as a float
total = 0.0
# cycle through the items
doc.elements.each('shopping/item') do |item|
# add the price to the total
total += item.attributes['price'].to_f
end
# round the total to the nearest 0.01
total = (total*100.0).round/100.0
# pad the output with the proper number of trailing 0's
printf "$%.2f\n", total
clojure
(println (format "Total cost of items are $%#.2f"
(->> (xml-seq (parse *xml-input-stream*))
(filter #(= :item (:tag %))) ; Remove all but the item tags
(map :attrs) ; Keep the attributes
(map (fn [e] (str "(* " (:quantity e) " " (:price e) ")"))) ; Get the total price as a sexp
(map read-string) ; "(* quantity price)" -> (* quantity price)
(map eval) ; (* quantity price) -> quantity*price
(apply +)))) ; Sum all elements
(->> (xml-seq (parse *xml-input-stream*))
(filter #(= :item (:tag %))) ; Remove all but the item tags
(map :attrs) ; Keep the attributes
(map (fn [e] (str "(* " (:quantity e) " " (:price e) ")"))) ; Get the total price as a sexp
(map read-string) ; "(* quantity price)" -> (* quantity price)
(map eval) ; (* quantity price) -> quantity*price
(apply +)))) ; Sum all elements
fantom
sum := 0.0
root := XParser(File(`shop.xml`).in).parseDoc.root
if (root.name == "shopping")
{
root.elems.each
{
if (it.name == "item")
{
quantity := Int.fromStr(it.get("quantity"))
price := Decimal.fromStr(it.get("price"))
sum += quantity * price;
}
}
}
echo("\$$sum")
root := XParser(File(`shop.xml`).in).parseDoc.root
if (root.name == "shopping")
{
root.elems.each
{
if (it.name == "item")
{
quantity := Int.fromStr(it.get("quantity"))
price := Decimal.fromStr(it.get("price"))
sum += quantity * price;
}
}
}
echo("\$$sum")
create some XML programmatically
Given the following CSV:
bread,3,2.50
milk,2,3.50
Produce the equivalent information in XML, e.g.:
<shopping>
<item name=
<item name=
</shopping>
bread,3,2.50
milk,2,3.50
Produce the equivalent information in XML, e.g.:
<shopping>
<item name=
"bread" quantity="3" price="2.50" />
<item name=
"milk" quantity="2" price="3.50" />
</shopping>
ruby
# gem install builder
require 'builder'
xml = Builder::XmlMarkup.new
xml.shopping do
xml.item(:name => "bread", :quantity => 3, :price => "2.50")
xml.item(:name => "milk", :quantity => 2, :price => "3.50")
end
xml
require 'builder'
xml = Builder::XmlMarkup.new
xml.shopping do
xml.item(:name => "bread", :quantity => 3, :price => "2.50")
xml.item(:name => "milk", :quantity => 2, :price => "3.50")
end
xml
clojure
(defn list->xml-item [lst]
(let [[name quantity price] (map str lst)]
{:tag :item
:attrs {:name name
:quantity quantity
:price price}}))
(defn cvs->xml [r]
(->> (map #(read-string (str "(" % ")")) (line-seq r))
(map list->xml-item)
(assoc {:tag :shopping} :content)
(emit)
(with-out-str)))
(println (cvs->xml *cvs-reader*))
(let [[name quantity price] (map str lst)]
{:tag :item
:attrs {:name name
:quantity quantity
:price price}}))
(defn cvs->xml [r]
(->> (map #(read-string (str "(" % ")")) (line-seq r))
(map list->xml-item)
(assoc {:tag :shopping} :content)
(emit)
(with-out-str)))
(println (cvs->xml *cvs-reader*))
fantom
sum := 0.0
rows := CsvInStream(File(`shop.csv`).in).readAllRows
doc := XDoc()
doc.root = XElem("shopping")
{
root := it
rows.each |Str[] row|
{
root.add(XElem("item")
{
XAttr("name", row[0]),
XAttr("quantity", row[1]),
XAttr("price", row[2])
})
}
}
os := File(`shop.xml`).out
doc.write(os)
os.close
rows := CsvInStream(File(`shop.csv`).in).readAllRows
doc := XDoc()
doc.root = XElem("shopping")
{
root := it
rows.each |Str[] row|
{
root.add(XElem("item")
{
XAttr("name", row[0]),
XAttr("quantity", row[1]),
XAttr("price", row[2])
})
}
}
os := File(`shop.xml`).out
doc.write(os)
os.close
Find all Pythagorean triangles with length or height less than or equal to 20
Pythagorean triangles are right angle triangles whose sides comply with the following equation:
a * a + b * b = c * c
where c represents the length of the hypotenuse, and a and b represent the lengths of the other two sides. Find all such triangles where a, b and c are non-zero integers with a and b less than or equal to 20. Sort your results by the size of the hypotenuse. The expected answer is:
a * a + b * b = c * c
where c represents the length of the hypotenuse, and a and b represent the lengths of the other two sides. Find all such triangles where a, b and c are non-zero integers with a and b less than or equal to 20. Sort your results by the size of the hypotenuse. The expected answer is:
[3, 4, 5]
[6, 8, 10]
[5, 12, 13]
[9, 12, 15]
[8, 15, 17]
[12, 16, 20]
[15, 20, 25]
ruby
results=[]
1.upto(20) do |a|
1.upto(20) do |b|
c=Math.sqrt(a**2+b**2)
results<<[a, b, c.to_i] if c.to_i==c && !results.index([b, a, c.to_i])
end
end
results=results.sort_by{|r| r[2]}
puts results
1.upto(20) do |a|
1.upto(20) do |b|
c=Math.sqrt(a**2+b**2)
results<<[a, b, c.to_i] if c.to_i==c && !results.index([b, a, c.to_i])
end
end
results=results.sort_by{|r| r[2]}
puts results
def find_pythag( max=20 )
r = []
1.upto max do |n|
n.upto max do |m|
h = Math.sqrt( n**2 + m**2)
r << [n,m,h.to_i] if (h.round - h).zero?
end
end
r.sort_by { |a| a[2] }
end
r = []
1.upto max do |n|
n.upto max do |m|
h = Math.sqrt( n**2 + m**2)
r << [n,m,h.to_i] if (h.round - h).zero?
end
end
r.sort_by { |a| a[2] }
end
clojure
(defn pythagorean [a b c] (= (+ (* a a) (* b b)) (* c c)))
(defn intsqrt [cc]
(. (. Math sqrt cc) intValue)
)
(defn triples [maxSize]
(filter not-empty
(for [a (range 1 20) b (range a 20)]
(let [c (intsqrt (+ (* a a) (* b b)))]
(if (pythagorean a b c)
[a b c]
()
)))))
(triples 20)
; -> ([3 4 5] [5 12 13] [6 8 10] [8 15 17] [9 12 15] [12 16 20] [15 20 25])
(defn sortByHypotenuse [triples]
(sort-by #(first (rest (rest %))) triples)
)
(sortByHypotenuse (triples 20))
; -> ([3 4 5] [6 8 10] [5 12 13] [9 12 15] [8 15 17] [12 16 20] [15 20 25])
(defn intsqrt [cc]
(. (. Math sqrt cc) intValue)
)
(defn triples [maxSize]
(filter not-empty
(for [a (range 1 20) b (range a 20)]
(let [c (intsqrt (+ (* a a) (* b b)))]
(if (pythagorean a b c)
[a b c]
()
)))))
(triples 20)
; -> ([3 4 5] [5 12 13] [6 8 10] [8 15 17] [9 12 15] [12 16 20] [15 20 25])
(defn sortByHypotenuse [triples]
(sort-by #(first (rest (rest %))) triples)
)
(sortByHypotenuse (triples 20))
; -> ([3 4 5] [6 8 10] [5 12 13] [9 12 15] [8 15 17] [12 16 20] [15 20 25])
(doseq [pt (sort-by #(% 2)
(for [a (range 1 21)
b (range a 21)
:let [aa+bb (+ (* a a) (* b b))
c (Math/round (Math/sqrt aa+bb))]
:when (= aa+bb (* c c))]
[a b c]))]
(println pt))
(for [a (range 1 21)
b (range a 21)
:let [aa+bb (+ (* a a) (* b b))
c (Math/round (Math/sqrt aa+bb))]
:when (= aa+bb (* c c))]
[a b c]))]
(println pt))
fantom
triangles := [,]
(1..20).each |Int a|
{
(a..20).each |Int b|
{
c := (a.pow(2) + b.pow(2)).toFloat.sqrt
if (c % c.toInt == 0.0f && !triangles.contains([b,a,c]))
triangles.add([a,b,c.toInt])
}
}
triangles.sort |Int[] x, Int[] y -> Int| { x[2]-y[2] }
echo(triangles)
(1..20).each |Int a|
{
(a..20).each |Int b|
{
c := (a.pow(2) + b.pow(2)).toFloat.sqrt
if (c % c.toInt == 0.0f && !triangles.contains([b,a,c]))
triangles.add([a,b,c.toInt])
}
}
triangles.sort |Int[] x, Int[] y -> Int| { x[2]-y[2] }
echo(triangles)
Greatest Common Divisor
Find the largest positive integer that divides two given numbers without a remainder. For example, the GCD of 8 and 12 is 4.
ruby
135.gcd(30)
# => 15
# => 15
clojure
(defn gcd [a b]
(if (zero? b)
a
(recur b (mod b a))))
(if (zero? b)
a
(recur b (mod b a))))
fantom
gcd := |Int a, Int b -> Int| {
pair := [a, b].sort
while (pair.first != 0)
pair.set(1, pair.last % pair.first).swap(0, 1)
return pair.last
}
echo(gcd(12, 8)) // a>b, result == 4
echo(gcd(1029, 1071)) // a<b, result == 21
pair := [a, b].sort
while (pair.first != 0)
pair.set(1, pair.last % pair.first).swap(0, 1)
return pair.last
}
echo(gcd(12, 8)) // a>b, result == 4
echo(gcd(1029, 1071)) // a<b, result == 21
produces a copy of its own source code
In computing, a quine is a computer program which produces a copy of its own source code as its only output.
ruby
eval s=%q(puts"eval s=%q(#{s})")
x="x=%p;puts x%%x";puts x%x
clojure
(def s"(def s%s)(printf s(pr-str s))")(printf s(pr-str s))
fantom
class Q
{
static Void main()
{
r := "class Q\n{\n static Void main()\n {\n r := "
s := "\n s := \n echo (r+r.toCode+s[0..9]+s.toCode+s[10..-1])\n }\n}"
echo (r+r.toCode+s[0..9]+s.toCode+s[10..-1])
}
}
{
static Void main()
{
r := "class Q\n{\n static Void main()\n {\n r := "
s := "\n s := \n echo (r+r.toCode+s[0..9]+s.toCode+s[10..-1])\n }\n}"
echo (r+r.toCode+s[0..9]+s.toCode+s[10..-1])
}
}
class Q{static Void main(){s:="class Q{static Void main(){s:=;c:=34.toChar;echo(s[0..<30]+c+s+c+s[30..-1]);}}";c:=34.toChar;echo(s[0..<30]+c+s+c+s[30..-1]);}}
Subdivide A Problem To A Pool Of Workers (No Shared Data)
Take a hard to compute problem and split it up between multiple worker threads. In your solution, try to fully utilize available cores or processors. (I'm looking at you, Python!)
Note: In this question, there should be no need for shared state between worker threads while the problem is being solved. Only after every thread completes computation are the answers recombined into a single output.
Example:
-Input-
(In python syntax)
In other words, a list of random strings.
-Output-
(In python syntax)
In other words, all possible permutations of each input string are computed.
Note: In this question, there should be no need for shared state between worker threads while the problem is being solved. Only after every thread completes computation are the answers recombined into a single output.
Example:
-Input-
(In python syntax)
["ab", "we", "tfe", "aoj"]
In other words, a list of random strings.
-Output-
(In python syntax)
[ ["ab", "ba", "aa", "bb", "a", "b"], ["we", "ew", "ww", "ee", "w", "e"], ...
In other words, all possible permutations of each input string are computed.
ruby
array, threads, answers = ["ab", "we", "tfe", "aoj"], [], []
array.each { |word|
threads << Thread.new(word.split '' ) do |x|
answer = []
x.each { |a|
answer << a
x.each { |b| answer << [a, b].join }
}
answers << answer
end
}
threads.each {|thr| thr.join}
answers
array.each { |word|
threads << Thread.new(word.split '' ) do |x|
answer = []
x.each { |a|
answer << a
x.each { |b| answer << [a, b].join }
}
answers << answer
end
}
threads.each {|thr| thr.join}
answers
clojure
(defn perm-chars [l]
"Returns a list of all possible permutations of strings with the
same size as the input string. This function will return duplicates
if the same character occurs multiple time in the string.
Ex: ab -> (aa ab ba ab)"
(if (string? l)
(recur (repeat (count l) l))
(let [s (first l)
r (rest l)]
(if (empty? r)
(map identity s)
(->> s
(map (fn [c] (map #(str c %) (perm-chars r))))
(flatten))))))
(defn perm-sz [s]
"Returns a list of all possible permutations of the input
string. May return duplicats.
Ex: ab -> (aa ab ba bb a b a b)"
(if-not (empty? s)
(let [r (perm-chars s)]
(if (= (count s) 1)
r
(->> r
(map #(perm-sz (apply str (rest %))))
(flatten)
(lazy-cat r))))))
(defn perm [s]
"Returns a list of all possible permutations of the input
string. The list of string is sorted and does not contain
duplicates.
Ex: ab -> (a aa ab b ba bb)"
(->> (reduce (fn [s e] (conj s e)) #{} (perm-sz s))
(map str)
(sort)))
(println (pmap perm ["ab" "we" "tfe" "aoj"]))
"Returns a list of all possible permutations of strings with the
same size as the input string. This function will return duplicates
if the same character occurs multiple time in the string.
Ex: ab -> (aa ab ba ab)"
(if (string? l)
(recur (repeat (count l) l))
(let [s (first l)
r (rest l)]
(if (empty? r)
(map identity s)
(->> s
(map (fn [c] (map #(str c %) (perm-chars r))))
(flatten))))))
(defn perm-sz [s]
"Returns a list of all possible permutations of the input
string. May return duplicats.
Ex: ab -> (aa ab ba bb a b a b)"
(if-not (empty? s)
(let [r (perm-chars s)]
(if (= (count s) 1)
r
(->> r
(map #(perm-sz (apply str (rest %))))
(flatten)
(lazy-cat r))))))
(defn perm [s]
"Returns a list of all possible permutations of the input
string. The list of string is sorted and does not contain
duplicates.
Ex: ab -> (a aa ab b ba bb)"
(->> (reduce (fn [s e] (conj s e)) #{} (perm-sz s))
(map str)
(sort)))
(println (pmap perm ["ab" "we" "tfe" "aoj"]))
(require 'cojure.contrib.combinatorics)
(pmap (fn [str]
(apply concat (map #(selections str (inc %))
(range (count str)))))
["ab", "we", "tfe", "aoj"])
(pmap (fn [str]
(apply concat (map #(selections str (inc %))
(range (count str)))))
["ab", "we", "tfe", "aoj"])
fantom
using concurrent
// as per Java answer, doesn't duplicate chars from input string, i.e. no 'aa'
const class PermGen : Actor
{
new make(ActorPool pool) : super(pool) {}
Void permutations(Str prefix, Str w, Str[] pset)
{
n := w.size
if (n == 0)
{
if (!pset.contains(prefix))
pset.add(prefix)
return
}
n.times { permutations(prefix + w[it..it], w[0..<it] + w[it+1..<n], pset) }
}
override Obj? receive(Obj? msg)
{
Str word := msg
wordSubPerm := Str[,]
for (Int i := 0; i < word.size; i++)
for (Int j := i; j < word.size; j++)
permutations("", word[i..j], wordSubPerm)
return wordSubPerm
}
}
class SolutionXX
{
static Void main()
{
pool := ActorPool() { maxThreads = 8 }
futures := Future[,]
["ab", "we", "tfe", "aoj"].each { futures.add(PermGen(pool).send(it)) }
futures.each { echo(it.get) }
}
}
// as per Java answer, doesn't duplicate chars from input string, i.e. no 'aa'
const class PermGen : Actor
{
new make(ActorPool pool) : super(pool) {}
Void permutations(Str prefix, Str w, Str[] pset)
{
n := w.size
if (n == 0)
{
if (!pset.contains(prefix))
pset.add(prefix)
return
}
n.times { permutations(prefix + w[it..it], w[0..<it] + w[it+1..<n], pset) }
}
override Obj? receive(Obj? msg)
{
Str word := msg
wordSubPerm := Str[,]
for (Int i := 0; i < word.size; i++)
for (Int j := i; j < word.size; j++)
permutations("", word[i..j], wordSubPerm)
return wordSubPerm
}
}
class SolutionXX
{
static Void main()
{
pool := ActorPool() { maxThreads = 8 }
futures := Future[,]
["ab", "we", "tfe", "aoj"].each { futures.add(PermGen(pool).send(it)) }
futures.each { echo(it.get) }
}
}
Create a multithreaded "Hello World"
Create a program which outputs the string
Example:
-Output-
Thread one says Hello World!
Thread two says Hello World!
Thread four says Hello World!
Thread three says Hello World!
-Notice that the threads can print in any order.
"Hello World" to the console, multiple times, using separate threads or processes.
Example:
-Output-
Thread one says Hello World!
Thread two says Hello World!
Thread four says Hello World!
Thread three says Hello World!
-Notice that the threads can print in any order.
ruby
%w[one two three four].each do |number|
Thread.new(number) { |number|
puts "Thread #{number} says Hello World!"
}.join
end
Thread.new(number) { |number|
puts "Thread #{number} says Hello World!"
}.join
end
clojure
(doseq [msg ["one" "two" "three" "four"]]
(future (println "Thread" msg "says Hello World!")))
(future (println "Thread" msg "says Hello World!")))
(dorun (pmap #(println (str "Thread " % " says Hello World!")) '("one" "two" "three" "four")))
(dorun (map (fn [n] (.start (Thread. #(println (str "Thread " n " says Hello World!")))))
'("one" "two" "three" "four")))
'("one" "two" "three" "four")))
fantom
pool := ActorPool()
["one", "two", "three", "four"].each
{
a := Actor(pool) |Str name| { echo("Thread $name says Hello World!") }
a.send(it)
}
["one", "two", "three", "four"].each
{
a := Actor(pool) |Str name| { echo("Thread $name says Hello World!") }
a.send(it)
}
