Solved Problems
Output a string to the console
Write the string
"Hello World!" to STDOUT
perl
print "Hello World!\n"
erlang
io:format("Hello, World!~n").
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?
perl
print "http://myserver.com/custinfo/edit.php"
."?fname=".urlenc('Ron & Jean')
."&lname=".urlenc('Smith');
sub urlenc{my($s)=@_;$s=~s/([^A-Za-z0-9])/sprintf("%%%02X",ord($1))/seg;$s}
."?fname=".urlenc('Ron & Jean')
."&lname=".urlenc('Smith');
sub urlenc{my($s)=@_;$s=~s/([^A-Za-z0-9])/sprintf("%%%02X",ord($1))/seg;$s}
erlang
% encode ampersand in your string using %XX where XX is hex code for ampersand
% optionally encode spaces for completeness sake to keep URL solid
URL = "http://myserver.com/custinfo/edit.php?mode=view&fname=Ron%20%26%20Jean&lname=Smith",
{_, Query} = string:tokens(URL, "?"),
KeyValuePairs = string:tokens(Query, "&"),...
% optionally encode spaces for completeness sake to keep URL solid
URL = "http://myserver.com/custinfo/edit.php?mode=view&fname=Ron%20%26%20Jean&lname=Smith",
{_, Query} = string:tokens(URL, "?"),
KeyValuePairs = string:tokens(Query, "&"),...
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)
Define a string containing special characters
Define the literal string
"\#{'}${"}/"
perl
$special = '\#{\'}${"}/';
$special = q(\#{'}${"}/);
erlang
Special = "\\#{'}\${\"}/",
fantom
special := Str<|\#{'}${"}/|>
Define a multiline string
Define the string:
"This
Is
A
Multiline
String"
perl
$text = 'This
Is
A
Multiline
String';
Is
A
Multiline
String';
$text = <<EOF;
This
Is
A
Multiline
String
EOF
This
Is
A
Multiline
String
EOF
erlang
Text = "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"
perl
print "$a+$b=${\($a+$b)}\n";
sprintf("%d+%d=%d", $a, $b, $a + $b);
print $a, '+', $b, '=', $a + $b;
erlang
A = 3, B = 4,
io:format("~B+~B=~B~n", [A, B, (A+B)]).
io:format("~B+~B=~B~n", [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"
perl
$_ = reverse "reverse me"; print
erlang
Reversed = lists:reverse("reverse me"),
Reversed = revchars("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"
perl
$reversed = join ' ', reverse split / /, $text;
erlang
Reversed = string:join(lists:reverse(string:tokens("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.
perl
use Text::Wrap;
$text = "The quick brown fox jumps over the lazy dog. ";
$Text::Wrap::columns = 73;
print wrap('> ', '> ', $text x 10);
$text = "The quick brown fox jumps over the lazy dog. ";
$Text::Wrap::columns = 73;
print wrap('> ', '> ', $text x 10);
$_ = "The quick brown fox jumps over the lazy dog. " x 10;
s/(.{0,70}) /> $1\n/g;
print;
s/(.{0,70}) /> $1\n/g;
print;
erlang
TextWrap = textwrap(string:copies(Input, 10), 73 - length(Prefix)),
lists:foreach(fun (Line) -> io:format("~s~n", [string:concat(Prefix, Line)]) end, string:tokens(TextWrap, "\n")).
lists:foreach(fun (Line) -> io:format("~s~n", [string:concat(Prefix, Line)]) end, string:tokens(TextWrap, "\n")).
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".
perl
my $string = " hello ";
$string =~ s{
\A\s* # Any number of spaces at the start of the string
(.+?) # Remember any number of characters until we reach
\s*\z # any number of spaces at the end of the string
}{
$1 # Leave the characters we remembered
}x;
$string =~ s{
\A\s* # Any number of spaces at the start of the string
(.+?) # Remember any number of characters until we reach
\s*\z # any number of spaces at the end of the string
}{
$1 # Leave the characters we remembered
}x;
my $string = " hello ";
$string =~ s{\A\s*}{};
$string =~ s{\s*\z}{};
$string =~ s{\A\s*}{};
$string =~ s{\s*\z}{};
#Modification History:
# 2009-MAR-17: GGARIEPY: [creation] (geoff.gariepy@gmail.com)
$string = " hello ";
$string =~ s/^\s+|\s+$//g; # All the action happens in one regex!
# Regex Notes:
# ^ - anchors to the beginning of the string
# $ - anchors to the end of the string
# g - causes regex to match as many times as possible
# | - logical OR
# 2009-MAR-17: GGARIEPY: [creation] (geoff.gariepy@gmail.com)
$string = " hello ";
$string =~ s/^\s+|\s+$//g; # All the action happens in one regex!
# Regex Notes:
# ^ - anchors to the beginning of the string
# $ - anchors to the end of the string
# g - causes regex to match as many times as possible
# | - logical OR
erlang
Trimmed = string:strip(S),
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
perl
sub rot13 {
my $str = shift;
$str =~ tr/A-Za-z/N-ZA-Mn-za-m/;
return $str;
}
sub rot47 {
my $str = shift;
$str =~ tr/!-~/P-~!-O/;
return $str;
}
my $string = 'Hello World #123';
print "$string\n";
print rot13($string)."\n";
print rot47($string)."\n";
my $str = shift;
$str =~ tr/A-Za-z/N-ZA-Mn-za-m/;
return $str;
}
sub rot47 {
my $str = shift;
$str =~ tr/!-~/P-~!-O/;
return $str;
}
my $string = 'Hello World #123';
print "$string\n";
print rot13($string)."\n";
print rot47($string)."\n";
erlang
rot13(Str) ->
lists:map(fun(A) ->
if
A >= $A, A =< $Z -> ((A - $A + 13) rem 26) + $A;
A >= $a, A =< $z -> ((A - $a + 13) rem 26) + $a;
true -> A
end
end, Str).
rot47(Str) ->
lists:map(fun(A) ->
if
A >= $!, A =< $~ ->
((A - $! + 47) rem 94) + $!;
true -> A
end
end, Str).
lists:map(fun(A) ->
if
A >= $A, A =< $Z -> ((A - $A + 13) rem 26) + $A;
A >= $a, A =< $z -> ((A - $a + 13) rem 26) + $a;
true -> A
end
end, Str).
rot47(Str) ->
lists:map(fun(A) ->
if
A >= $!, A =< $~ ->
((A - $! + 47) rem 94) + $!;
true -> A
end
end, Str).
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"
perl
print uc "Space Monkey"
erlang
io:format("~s~n", [string:to_upper("Space Monkey")]).
fantom
s := "Space Monkey".localeUpper
Make a string lowercase
Transform
"Caps ARE overRated" into "caps are overrated"
perl
print lc "Caps ARE overRated"
erlang
io:format("~s~n", [string:to_lower("Caps ARE overRated")]).
fantom
s := "Caps ARE overRated".localeLower
Capitalise the first letter of each word
Transform
"man OF stEEL" into "Man Of Steel"
perl
$text =~ s/(\w+)/\u\L$1/g;
erlang
Caps = string:join(lists:map(fun(S) -> to_caps(S) end, string:tokens("man OF stEEL", " ")), " "),
fantom
"man OF stEEL".split.map { it.localeLower.localeCapitalize }.join(" ")
Find the distance between two points
perl
use Math::Complex;
$a = Math::Complex->make(0, 3);
$b = Math::Complex->make(4, 0);
$distance = abs($a - $b);
$a = Math::Complex->make(0, 3);
$b = Math::Complex->make(4, 0);
$distance = abs($a - $b);
erlang
Distance = distance({point, 34, 78}, {point, 67, -45}),
io:format("~.2f~n", [Distance]).
io:format("~.2f~n", [Distance]).
Distance = distance(point:new(34, 78), point:new(67, -45)),
io:format("~.2f~n", [Distance]).
io:format("~.2f~n", [Distance]).
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
perl
sprintf("%08d", 42);
erlang
Formatted = io_lib:format("~8..0B", [42]),
io:format("~8..0B~n", [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 "
perl
sprintf("%-6d", 1024);
erlang
Formatted = io_lib:format("~-6B", [1024]),
io:format("~-6B~n", [1024]).
fantom
formatted := 1024.toStr.padr(6)
Format a decimal number
Format the number 7/8 as a decimal with 2 places: 0.88
perl
sprintf("%.2f", 7/8);
erlang
Formatted = io_lib:format("~.2f", [7/8]),
io:format("~.2f~n", [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"
perl
sprintf("%10d", 73);
erlang
Formatted = io_lib:format("~10B", [73]),
io:format("~10B~n", [73]).
fantom
formatted := 73.toStr.padl(10)
Generate a random integer in a given range
Produce a random integer between 100 and 200 inclusive
perl
my $range = 100;
my $minimum = 100;
my $random_number = int(rand($range)) + $minimum;
print "$random_number\n";
my $minimum = 100;
my $random_number = int(rand($range)) + $minimum;
print "$random_number\n";
erlang
RandomInt = gen_rand_integer(100, 200),
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.
perl
srand(12345);
@list1 = map(int(rand(100)+1), (1..5));
srand(12345);
@list2 = map(int(rand(100)+1), (1..5));
print join(', ', @list1) . "\n";
print join(', ', @list2) . "\n";
@list1 = map(int(rand(100)+1), (1..5));
srand(12345);
@list2 = map(int(rand(100)+1), (1..5));
print join(', ', @list1) . "\n";
print join(', ', @list2) . "\n";
erlang
setRNG(RNGState),
io:format("~w~n", [lists:map(fun (_) -> gen_rand_integer(100, 200) end, lists:seq(1, 5))]),
setRNG(RNGState),
io:format("~w~n", [lists:map(fun (_) -> gen_rand_integer(100, 200) end, lists:seq(1, 5))]).
io:format("~w~n", [lists:map(fun (_) -> gen_rand_integer(100, 200) end, lists:seq(1, 5))]),
setRNG(RNGState),
io:format("~w~n", [lists:map(fun (_) -> gen_rand_integer(100, 200) end, lists:seq(1, 5))]).
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]+/
perl
print 'ok' if ('Hello' =~ /[A-Z][a-z]+/);
erlang
String = "Hello", Regexp = "[A-Z][a-z]+",
is_match(String, Regexp) andalso (begin io:format("ok~n"), true end).
is_match(String, Regexp) andalso (begin io:format("ok~n"), true end).
case re:run("Hello", "[A-Z][a-z]+") of {match, _} -> ok end.
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/
perl
print $1 if "one two three"=~/^one (.*) three$/
erlang
case re:run("one two three", "one (.*) three", [{capture, [1], list}]) of {match, Res} -> hd(Res) end.
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+/
perl
print "ok" if ("abc 123 @#\$" =~ m/\d+/)
erlang
% Erlang uses 'egrep'-compatible regular expressions, so shortcuts like '\d' not supported
String = "abc 123 @#$", Regexp = "[0-9]+",
is_match(String, Regexp) andalso (begin io:format("ok~n"), true end).
String = "abc 123 @#$", Regexp = "[0-9]+",
is_match(String, Regexp) andalso (begin io:format("ok~n"), true end).
case re:run("abc 123 @#$", "\\d+") of {match, _} -> ok end.
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+)/
perl
while ($text =~ /\((\w+)\):(\d+)/g) {
push @list, "$1$2"
}
push @list, "$1$2"
}
erlang
solve(S) ->
R = "\\((\\w+?)\\):(\\d+)",
{match, M} = re:run(S,R, [global, {capture, all_but_first, list}]),
[ A++N || [A, N] <- M].
R = "\\((\\w+?)\\):(\\d+)",
{match, M} = re:run(S,R, [global, {capture, all_but_first, list}]),
[ A++N || [A, N] <- M].
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 "*"
perl
$text =~s/e/*/;
erlang
{ok, Replaced, _} = regexp:sub("Red Green Blue", "e", "*"),
re:replace("Red Green Blue", "e", "*", [{return, list}]).
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"
perl
$text = "She sells sea shells";
$text =~ s/se\w+/X/g;
$text =~ s/se\w+/X/g;
erlang
% Erlang uses 'egrep'-compatible regular expressions, so shortcuts like '\w' not supported
{ok, Replaced, _} = regexp:gsub("She sells sea shells", "se[A-Za-z0-9_]+", "X"),
{ok, Replaced, _} = regexp:gsub("She sells sea shells", "se[A-Za-z0-9_]+", "X"),
re:replace("She sells sea shells", "se\\w+", "X", [global, {return, list}]).
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+)\}/.
perl
$text = "The {Quick} Brown {Fox}";
$text =~ s/\{(\w+)\}/reverse($1)/ge;
$text =~ s/\{(\w+)\}/reverse($1)/ge;
erlang
% Erlang regular expressions lack both group capture and backreferences, thus this problem is not directly
% solvable. Presented solution is close, but not on-spec
String = "The {Quick} Brown {Fox}",
{match, FieldList} = regexp:matches(String, "\{([A-Za-z0-9_]+)\}"),
NewString = lists:foldl(fun ({Start, Length}, S) -> replstr(S, lists:reverse(string:substr(S, Start, Length)), Start) end, String, FieldList),
% solvable. Presented solution is close, but not on-spec
String = "The {Quick} Brown {Fox}",
{match, FieldList} = regexp:matches(String, "\{([A-Za-z0-9_]+)\}"),
NewString = lists:foldl(fun ({Start, Length}, S) -> replstr(S, lists:reverse(string:substr(S, Start, Length)), Start) end, String, FieldList),
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
perl
@list = ();
erlang
List = [],
fantom
list := [,]
Define a static list
Define the list
[One, Two, Three, Four, Five]
perl
@list = qw(One Two Three Four Five);
@list = ('One', 'Two', 'Three', 'Four', 'Five');
erlang
List = [one, two, three, four, five],
List = ['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"
perl
print join ', ', qw(Apple Banana Carrot);
# Longer and less efficient than join(), but illustrates
# Perl's foreach operator, which can be useful for
# less trivial problems with lists
@list = ('Apple', 'Banana', 'Carrot');
foreach $fruit (@list) {
print "$fruit,";
}
print "\n";
# Perl's foreach operator, which can be useful for
# less trivial problems with lists
@list = ('Apple', 'Banana', 'Carrot');
foreach $fruit (@list) {
print "$fruit,";
}
print "\n";
my @a = qw/Apple Banana Carrot/;
{
local $, = ", ";
print @a
}
print "\n";
{
local $, = ", ";
print @a
}
print "\n";
my @a = qw/Apple Banana Carrot/;
{
local $" = ", ";
print "@a\n";
}
{
local $" = ", ";
print "@a\n";
}
erlang
Result = string:join(Fruit, ", "),
Result = lists:foldl(fun (E, Acc) -> Acc ++ ", " ++ E end, hd(Fruit), tl(Fruit)),
Result = lists:flatten([ hd(Fruit) | [ ", " ++ X || X <- tl(Fruit)]]).
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(
[]) = ""
perl
sub myjoin {
$_ = join ', ', @_;
s/, ([^,]+)$/ and $1/;
return $_;
}
# Note: I don't think this meets the spec --Geoff
$_ = join ', ', @_;
s/, ([^,]+)$/ and $1/;
return $_;
}
# Note: I don't think this meets the spec --Geoff
sub myjoin {
if ($#_ < 2) {
return join ' and ', @_;
} else {
return join(', ', @_[0..$#_-1]) . ' and ' . $_[-1];
}
}
# Note: I don't think this meets the spec --Geoff
if ($#_ < 2) {
return join ' and ', @_;
} else {
return join(', ', @_[0..$#_-1]) . ' and ' . $_[-1];
}
}
# Note: I don't think this meets the spec --Geoff
# Previous "myjoin()" responses don't meet the spec of including
# the final comma before the "and" if the list has more than
# two elements...this is one way to meet that spec...it may
# not be the most efficient...
sub AnotherMyJoin {
my @list = @_;
if ($#list == -1) {return}
elsif ($#list == 0) {return $list[0]}
elsif ($#list == 1) {return $list[0].' and '.$list[1]}
else {
return join(", ", @list[0..$#list - 1]) . ', and '. $list[$#list];
}
}
# the final comma before the "and" if the list has more than
# two elements...this is one way to meet that spec...it may
# not be the most efficient...
sub AnotherMyJoin {
my @list = @_;
if ($#list == -1) {return}
elsif ($#list == 0) {return $list[0]}
elsif ($#list == 1) {return $list[0].' and '.$list[1]}
else {
return join(", ", @list[0..$#list - 1]) . ', and '. $list[$#list];
}
}
# This is the long way, but it's kind of fun
# It illustrates the use of Perl's reverse()
# operator to work our way through the list
# elements backwards...I wrote this one before
# getting smart and looking at some of the other
# algorithms from the other languages. Still,
# it is only 12 lines of code vs 9 for my other
# solution if you disregard the comments.
sub myjoin {
my @list = reverse(@_); # Reverse original order of elements
my $retval;
# Make our exit here if we were passed an empty list
if ($#list == -1) {return}
# Loop through reversed elements in end-to-start order
for (0..$#list) {
# Add the reversed form of each element plus a space char
$retval .= reverse($list[$_]).' ';
# Add 'and' to lists with two or more elements
# placing it in between final and 'next to final'
$retval .= "dna " if ($#list > 0 and $_== 0);
# Add ',' to each element as long as there are more
# than two elements and the current element isn't the
# final element
$retval .= "," if ($#list > 1 and $_ != $#list);
}
# Remove what will end up as an extraneous leading space
chop($retval);
# Done looping, now reverse things back into correct order and return
$retval = reverse($retval);
return($retval);
}
# It illustrates the use of Perl's reverse()
# operator to work our way through the list
# elements backwards...I wrote this one before
# getting smart and looking at some of the other
# algorithms from the other languages. Still,
# it is only 12 lines of code vs 9 for my other
# solution if you disregard the comments.
sub myjoin {
my @list = reverse(@_); # Reverse original order of elements
my $retval;
# Make our exit here if we were passed an empty list
if ($#list == -1) {return}
# Loop through reversed elements in end-to-start order
for (0..$#list) {
# Add the reversed form of each element plus a space char
$retval .= reverse($list[$_]).' ';
# Add 'and' to lists with two or more elements
# placing it in between final and 'next to final'
$retval .= "dna " if ($#list > 0 and $_== 0);
# Add ',' to each element as long as there are more
# than two elements and the current element isn't the
# final element
$retval .= "," if ($#list > 1 and $_ != $#list);
}
# Remove what will end up as an extraneous leading space
chop($retval);
# Done looping, now reverse things back into correct order and return
$retval = reverse($retval);
return($retval);
}
# Yes, this doesn't meet the spec, the spec is flawed
# the serial comma (Oxford comma) is not required in a list
sub english_join {
return join(', ', @_[0..$#_-1])
. ($#_ ? ' and ' : '' )
. $_[-1];
}
# the serial comma (Oxford comma) is not required in a list
sub english_join {
return join(', ', @_[0..$#_-1])
. ($#_ ? ' and ' : '' )
. $_[-1];
}
erlang
io:format("~s~n", [join(Fruit)]).
% ------
join([]) -> "";
join([W|Ws]) -> join(Ws, W).
join([], S) -> S;
join([W], S) -> join([], S ++ " and " ++ W);
join([W|Ws], S) -> join(Ws, S ++ ", " ++ W).
% ------
join([]) -> "";
join([W|Ws]) -> join(Ws, W).
join([], S) -> S;
join([W], S) -> join([], S ++ " and " ++ W);
join([W|Ws], S) -> join(Ws, S ++ ", " ++ W).
%% According to the reference manual, "string is not a data type in Erlang."
%% Instead it has lists of integers. But I/O functions in general accept
%% IO lists, where an IO list is either a list of IO lists or an integer.
%% This gives you O(1) string concatenation.
-module(commalist).
-export([join/1]).
join([]) -> "";
join([W]) -> W;
join([W1, W2]) -> [W1, " and ", W2];
join([W1, W2, W3]) -> [W1, ", ", W2, ", and ", W3];
join([W1|Ws]) -> [W1, ", ", join(Ws)].
%% Instead it has lists of integers. But I/O functions in general accept
%% IO lists, where an IO list is either a list of IO lists or an integer.
%% This gives you O(1) string concatenation.
-module(commalist).
-export([join/1]).
join([]) -> "";
join([W]) -> W;
join([W1, W2]) -> [W1, " and ", W2];
join([W1, W2, W3]) -> [W1, ", ", W2, ", and ", W3];
join([W1|Ws]) -> [W1, ", ", join(Ws)].
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]]
perl
@letters = qw(a b c);
@numbers = (4, 5);
@list = map { $number=$_; map [$_, $number], @letters; } @numbers;
@numbers = (4, 5);
@list = map { $number=$_; map [$_, $number], @letters; } @numbers;
@letters = qw(a b c);
@numbers = (4, 5);
for $number (@numbers) {
for $letter (@letters) {
push @list, [$letter, $number];
}
}
@numbers = (4, 5);
for $number (@numbers) {
for $letter (@letters) {
push @list, [$letter, $number];
}
}
erlang
Combinations =
lists:foldl(fun (Number, Acc) -> Acc ++ lists:map(fun (Letter) -> {Letter, Number} end, Letters) end, [], Numbers),
lists:foldl(fun (Number, Acc) -> Acc ++ lists:map(fun (Letter) -> {Letter, Number} end, Letters) end, [], Numbers),
Combinations = lists:keysort(2, sofs:to_external(sofs:product(sofs:set(Letters), sofs:set(Numbers))))
[[A, B] || A <- ["a", "b", "c"], B <- [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"]
perl
my @input = ("andrew", "bob", "chris", "bob", "bob");
my %input_count;
my @output = grep { $input_count{$_}++; $input_count{$_} == 2 } @input;
my %input_count;
my @output = grep { $input_count{$_}++; $input_count{$_} == 2 } @input;
erlang
{_, Result} = lists:foldl(
fun(X, {Uniq, Dupl}) -> case lists:member(X, Uniq) of
true -> {Uniq,[X | Dupl]};
_ -> {[X | Uniq], Dupl}
end
end,
{[], []},
List),
fun(X, {Uniq, Dupl}) -> case lists:member(X, Uniq) of
true -> {Uniq,[X | Dupl]};
_ -> {[X | Uniq], Dupl}
end
end,
{[], []},
List),
Fun = fun
([X | Xs], F) -> case lists:member(X, Xs) of
true -> [X | F(Xs, F)];
_ -> F(Xs, F)
end;
([], _) -> []
end,
Result = Fun(List, Fun).
([X | Xs], F) -> case lists:member(X, Xs) of
true -> [X | F(Xs, F)];
_ -> F(Xs, F)
end;
([], _) -> []
end,
Result = Fun(List, Fun).
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')
perl
qw(One Two Three Four Five)[2];
@list = qw(One Two Three Four Five);
$list[2];
$list[2];
erlang
Result = lists:nth(3, List),
Result = element(3, list_to_tuple(List)),
{Left, _} = lists:split(3, List), Result = lists:last(Left),
Result = nth0(2, List),
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')
perl
qw(Red Green Blue)[-1];
@list = qw(Red Green Blue);
$list[-1];
$list[-1];
erlang
Result = lists:last(List),
Result = last(List),
Result = hd(lists:reverse(List)),
Result = lists:nth(length(List), List),
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?
perl
@beans = qw(broad mung black red white);
@colors = qw(black red blue green);
@seen{@beans} = ();
for (@colors) {
push(@intersection, $_) if exists($seen{$_});
}
print join(', ', @intersection);
@colors = qw(black red blue green);
@seen{@beans} = ();
for (@colors) {
push(@intersection, $_) if exists($seen{$_});
}
print join(', ', @intersection);
@beans = qw(broad mung black red white);
@colors = qw(black red blue green);
my %colors_hash = map { $_ => 1 } @colors;
my @intersection = grep { $colors_hash{$_} } @beans;
print join(', ', @intersection),"\n";
@colors = qw(black red blue green);
my %colors_hash = map { $_ => 1 } @colors;
my @intersection = grep { $colors_hash{$_} } @beans;
print join(', ', @intersection),"\n";
@beans = qw/broad mung black red white/;
@colors = qw/black red blue green/;
print join ', ', grep { $_ ~~ @colors } @beans;
@colors = qw/black red blue green/;
print join ', ', grep { $_ ~~ @colors } @beans;
erlang
Beans = sets:from_list([broad, mung, black, red, white]), Colors = sets:from_list([black, red, blue, green]),
Common = sets:to_list(sets:intersection(Beans, Colors)),
Common = sets:to_list(sets:intersection(Beans, 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.
perl
@ages = (18, 16, 17, 18, 16, 19, 14, 17, 19, 18);
@seen{@ages} = ();
@unique = keys %seen;
print join(', ', @unique);
@seen{@ages} = ();
@unique = keys %seen;
print join(', ', @unique);
@ages = (18, 16, 17, 18, 16, 19, 14, 17, 19, 18);
@unique = grep(!$seen{$_}++, @ages);
print join(', ', @unique);
@unique = grep(!$seen{$_}++, @ages);
print join(', ', @unique);
@ages = (18, 16, 17, 18, 16, 19, 14, 17, 19, 18);
print join(', ', grep(!$seen{$_}++, @ages));
print join(', ', grep(!$seen{$_}++, @ages));
@ages = (18, 16, 17, 18, 16, 19, 14, 17, 19, 18);
for (@ages) {
push(@unique, $_) unless $seen{$_}++;
}
print join(', ', @unique);
for (@ages) {
push(@unique, $_) unless $seen{$_}++;
}
print join(', ', @unique);
use List::MoreUtils qw(uniq);
@ages = (18, 16, 17, 18, 16, 19, 14, 17, 19, 18);
print join(', ', uniq(@ages));
@ages = (18, 16, 17, 18, 16, 19, 14, 17, 19, 18);
print join(', ', uniq(@ages));
erlang
Ages = sets:to_list(sets:from_list([18, 16, 17, 18, 16, 19, 14, 17, 19, 18])), io:format("~w~n", [Ages]).
lists:usort([18, 16, 17, 18, 16, 19, 14, 17, 19, 18]).
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]
perl
@list = qw(Apple Banana Carrot);
shift @list;
shift @list;
@list = qw(Apple Banana Carrot);
$offset = 0;
splice(@list, $offset, 1);
$offset = 0;
splice(@list, $offset, 1);
erlang
Result = tl(List),
[_|Result] = List,
N = 1, {Left, Right} = lists:split(N - 1, List), Result = Left ++ tl(Right),
Result = drop(1, List),
fantom
list := ["Apple", "Banana", "Carrot"]
list.removeAt(0)
list.removeAt(0)
Remove the last element of a list
perl
pop @list;
erlang
Result = init(List),
Result = take(length(List) - 1, List),
Result = lists:reverse(tl(lists:reverse(List))),
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"]
perl
@list = qw(apple, orange, grapes, bananas);
push @list, shift @list;
push @list, shift @list;
@list = qw(apple orange grapes bananas);
@list = @list[1..$#list,0];
@list = @list[1..$#list,0];
erlang
N = 1, {Left, Right} = lists:split(N, List), Result = Right ++ Left,
N = 1, Result = rotate(N, List),
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.
perl
my @first = ('Bruce', 'Tommy Lee', 'Bruce');
my @last = ('Willis', 'Jones', 'Lee');
my @years = (1955, 1946, 1940);
my @actors;
my $max = scalar @first;
for my $index (0 .. $max) {
push @actors, [ $first[$index], $last[$index], $years[$index] ];
};
my @last = ('Willis', 'Jones', 'Lee');
my @years = (1955, 1946, 1940);
my @actors;
my $max = scalar @first;
for my $index (0 .. $max) {
push @actors, [ $first[$index], $last[$index], $years[$index] ];
};
erlang
First = ['Bruce', 'Tommy Lee', 'Bruce'], Last = ['Willis', 'Jones', 'Lee'], Years = [1955, 1946, 1940],
Result = lists:zip3(First, Last, Years),
Result = lists:zip3(First, Last, 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'.
perl
@suites = qw(H D C S);
@faces = qw(2 3 4 5 6 7 8 9 10 J Q K A);
@deck = map { $suite=$_; map $suite.$_, @faces; } @suites;
print 'checking deck size: ' . (@deck == 52 ? 'pass' : 'fail') . "\n";
print 'deck contains "Ace of Hearts": ' . (grep(/^HA$/, @deck) ? 'true' : 'false') . "\n";
@faces = qw(2 3 4 5 6 7 8 9 10 J Q K A);
@deck = map { $suite=$_; map $suite.$_, @faces; } @suites;
print 'checking deck size: ' . (@deck == 52 ? 'pass' : 'fail') . "\n";
print 'deck contains "Ace of Hearts": ' . (grep(/^HA$/, @deck) ? 'true' : 'false') . "\n";
erlang
Cards = lists:foldl(fun (Suite, Acc) -> Acc ++ lists:flatmap(fun (Face) -> [{Suite, Face}] end, Faces) end, [], Suites),
io:format("Deck has ~B cards~n", [length(Cards)]),
IsMember = lists:member({h, 'A'}, Cards),
io:format("~s~n", [if IsMember -> "Deck contains 'Ace of Hearts'" ; true -> "'Ace of Hearts' not in deck" end]),
io:format("Deck has ~B cards~n", [length(Cards)]),
IsMember = lists:member({h, 'A'}, Cards),
io:format("~s~n", [if IsMember -> "Deck contains 'Ace of Hearts'" ; true -> "'Ace of Hearts' not in deck" end]),
Cards = sofs:to_external(sofs:product(sofs:set(Suites), sofs:set(Faces))),
io:format("Deck has ~B cards~n", [length(Cards)]),
IsMember = lists:member({h, 'A'}, Cards),
io:format("~s~n", [if IsMember -> "Deck contains 'Ace of Hearts'" ; true -> "'Ace of Hearts' not in deck" end]),
io:format("Deck has ~B cards~n", [length(Cards)]),
IsMember = lists:member({h, 'A'}, Cards),
io:format("~s~n", [if IsMember -> "Deck contains 'Ace of Hearts'" ; true -> "'Ace of Hearts' not in deck" end]),
Deck2 = [{S, V} || S <- [d, c, h, s], V <- [2, 3, 4, 5, 6, 7, 8, 9, 10, 'J', 'Q', 'K', 'A']],
52 = length(Deck2),
true = lists:member({h, 'A'}, Deck2).
52 = length(Deck2),
true = lists:member({h, 'A'}, Deck2).
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]
perl
my @list = qw{ox cat deer whale};
my @lengths = map {length($_)} @list;
print "@list\n";
print "@lengths\n";
my @lengths = map {length($_)} @list;
print "@list\n";
print "@lengths\n";
erlang
lists:map(fun (X) ->length(X) end, List).
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.
perl
use Scalar::Util qw(looks_like_number);
my @things = ('hello',25,3.14,scalar(localtime(time)));
my @numbers;
my @others;
for ( @things ) {
if ( looks_like_number $_ ) {
push @numbers, $_;
} else {
push @other, $_;
}
}
my @things = ('hello',25,3.14,scalar(localtime(time)));
my @numbers;
my @others;
for ( @things ) {
if ( looks_like_number $_ ) {
push @numbers, $_;
} else {
push @other, $_;
}
}
erlang
% Wrapped call to the auxiliary function
number_split(Xs) ->
number_split(Xs, [], []).
% The auxiliary function
number_split([], Num, NonNum) ->
{Num, NonNum};
number_split([X|Xs], Num, NonNum) ->
case is_number(X) of
true ->
number_split(Xs, [X|Num], NonNum);
false ->
number_split(Xs, Num, [X|NonNum])
end.
number_split(Xs) ->
number_split(Xs, [], []).
% The auxiliary function
number_split([], Num, NonNum) ->
{Num, NonNum};
number_split([X|Xs], Num, NonNum) ->
case is_number(X) of
true ->
number_split(Xs, [X|Num], NonNum);
false ->
number_split(Xs, Num, [X|NonNum])
end.
List = ["hello", 25, 3.14, calendar:local_time()],
{Numbers, NonNumbers} = lists:partition(fun(E) -> is_number(E) end, List)
{Numbers, NonNumbers} = lists:partition(fun(E) -> is_number(E) end, List)
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) }
Define an empty map
perl
# %map = {}
# This was wrong, that would have created a hash with one key
# of the stringified hash reference (HASH(0xNUMBERSHERE)) and a
# value of 'undef', as well as triggering a
# "Reference found where even-sized list expected" with the warnings
# pragma enabled
my %map;
# This was wrong, that would have created a hash with one key
# of the stringified hash reference (HASH(0xNUMBERSHERE)) and a
# value of 'undef', as well as triggering a
# "Reference found where even-sized list expected" with the warnings
# pragma enabled
my %map;
erlang
Map = dict:new(),
Map = orddict:new(),
Map = gb_trees:empty(),
Map = ets:new(the_map_name, [set, private, {keypos, 1}]),
fantom
map := [:]
Define an unmodifiable empty map
perl
# perl does not provide unmodifiable maps/hashes, but you could use "constant
# functions", if you really need them
# 2011-07-06 Not actually true, see Hash::Util::lock_hash;
sub MAP () { {} }
# functions", if you really need them
# 2011-07-06 Not actually true, see Hash::Util::lock_hash;
sub MAP () { {} }
use Hash::Util qw/lock_hash/;
# two lines
my %hash;
lock_hash(%hash);
# or in one line
lock_hash(my %locked_hash);
# two lines
my %hash;
lock_hash(%hash);
# or in one line
lock_hash(my %locked_hash);
erlang
% Erlang data structures are immutable - updating a 'map' sees a modified copy created
Map = dict:new(),
% Erlang data structures are immutable - updating a 'map' sees a modified copy created
Map = dict:new(),
fantom
map := [:].ro
Define an initial map
Define the map
{circle:1, triangle:3, square:4}
perl
%map = (circle => 1, triangle => 3, square => 4);
erlang
Map = dict:from_list([{circle, 1}, {triangle, 3}, {square, 4}]),
Map0 = dict:new(),
% Erlang variables are 'single-assignment' i.e. they cannot be reassigned
Map1 = dict:store(circle, 1, Map0),
Map2 = dict:store(triangle, 3, Map1),
Map3 = dict:store(square, 4, Map2),
% Erlang variables are 'single-assignment' i.e. they cannot be reassigned
Map1 = dict:store(circle, 1, Map0),
Map2 = dict:store(triangle, 3, Map1),
Map3 = dict:store(square, 4, Map2),
Map0 = gb_trees:empty(),
Map1 = gb_trees:enter(circle, 1, Map0),
Map2 = gb_trees:enter(triangle, 3, Map1),
Map3 = gb_trees:enter(square, 4, Map2),
Map1 = gb_trees:enter(circle, 1, Map0),
Map2 = gb_trees:enter(triangle, 3, Map1),
Map3 = gb_trees:enter(square, 4, Map2),
Map = gb_trees:from_orddict(lists:keysort(1, [{circle, 1}, {triangle, 3}, {square, 4}])),
Map = ets:new(the_map_name, [ordered_set, private, {keypos, 1}]),
ets:insert(Map, [{circle, 1}, {triangle, 3}, {square, 4}]),
ets:insert(Map, [{circle, 1}, {triangle, 3}, {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"
perl
%pets = (joe => 'cat', mary => 'turtle', bill => 'canary');
print 'ok' if ($pets{'mary'});
print 'ok' if ($pets{'mary'});
%pets = (joe => 'cat', mary => 'turtle', bill => 'canary');
print 'ok' if $pets{'mary'};
print 'ok' if $pets{'mary'};
print 'ok' if $pets{mary};
print 'ok' if exists $pets{mary}
erlang
dict:is_key(mary, Pets) andalso begin io:format("ok~n"), true end.
IsMember = ets:member(Pets, mary), if (IsMember) -> io:format("ok~n") ; true -> false end.
case gb_trees:lookup(mary, Pets) of none -> false ; _ -> io:format("ok~n") end.
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")
perl
%pets = (joe => 'cat', mary => 'turtle', bill=>'canary');
print $pets{joe};
print $pets{joe};
erlang
dict:is_key(joe, Pets) andalso begin io:format("~w~n", [dict:fetch(joe, Pets)]), true end.
case dict:find(joe, Pets) of error -> false ; {ok, Pet} -> io:format("~w~n", [Pet]) end.
IsMember = ets:member(Pets, joe), if (IsMember) -> io:format("~w~n", [ets:lookup_element(Pets, joe, 2)]) ; true -> false end.
case ets:match(Pets, {joe, '$1'}) of [] -> false ; [[Pet]] -> io:format("~w~n", [Pet]) end.
case gb_trees:lookup(joe, Pets) of none -> false ; {value, Pet} -> io:format("~w~n", [Pet]) end.
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"
perl
$pets{rob} = 'dog';
erlang
Pets1 = dict:store(rob, dog, Pets0).
ets:insert(Pets, {rob, dog}).
Pets1 = gb_trees:enter(rob, dog, Pets0).
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"
perl
print delete $pets{bill};
erlang
Pet = dict:fetch(bill, Pets0), Pets1 = dict:erase(bill, Pets0), io:format("~w~n", [Pet]),
Pet = ets:lookup_element(Pets, bill, 2), ets:delete(Pets, bill), io:format("~w~n", [Pet]),
{value, Pet} = gb_trees:lookup(bill, Pets0), Pets1 = gb_trees:delete(bill, Pets0), io:format("~w~n", [Pet]),
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
perl
foreach(@list) {
$histogram{$_}++;
}
$histogram{$_}++;
}
$histogram{$_}++ for @list;
erlang
% Imperative Solution
Histogram = histogram(List),
Histogram = histogram(List),
% Functional (1) Solution
Histogram = histogram(List),
Histogram = histogram(List),
lists:foldl(fun(Elem, OldDict) ->
dict:update_counter(Elem, 1, OldDict)
end,
dict:new(),
[a,b,a,c,b,b])).
dict:update_counter(Elem, 1, OldDict)
end,
dict:new(),
[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
perl
@list = qw(one two three four five);
push @{$map{length($_)}}, $_ for (@list);
push @{$map{length($_)}}, $_ for (@list);
erlang
% Imperative Solution
CatList = categorise(List),
CatList = categorise(List),
% Functional (1) Solution
CatList = categorise(List),
CatList = categorise(List),
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.
perl
if ($name eq "Bob") {
print "Hello, Bob!"
}
print "Hello, Bob!"
}
print "Hello, Bob!" if $name eq "Bob";
erlang
if (Name == "Bob") -> io:format("Hello, ~s!~n", [Name]) ; true -> false end.
case Name of "Bob" -> io:format("Hello, ~s!~n", [Name]) ; _ -> false end.
Name == "Bob" andalso (begin io:format("Hello, ~s!~n", [Name]), true end).
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"
perl
if ($age > 42) {
print "You are old"
}
else {
print "You are young"
}
print "You are old"
}
else {
print "You are young"
}
print 'You are ',($age > 42) ? 'old' : 'young';
erlang
if Age > 42 -> io:format("You are old~n") ; true -> io:format("You are young~n") end.
Message = if Age > 42 -> "old" ; true -> "young" end, io:format("You are ~s~n", [Message]).
case Age > 42 of true -> io:format("You are old~n") ; false -> io:format("You are young~n") end.
case Age of _ when Age > 42 -> io:format("You are old~n") ; _ -> io:format("You are young~n") end.
Message = case Age of _ when Age > 42 -> "old" ; _ -> "young" end, io:format("You are ~s~n", [Message]).
Age > 42 andalso (begin io:format("You are old~n"), true end) orelse (begin io:format("You are young~n"), true end).
(fun (X) when X > 42 -> io:format("You are old~n"); (_) -> io:format("You are young~n") end)(Age).
(fun () when Age > 42 -> io:format("You are old~n"); () -> io:format("You are young~n") end)().
io:format("You are ~s~n", [if Age > 42 -> "old" ; true -> "young" end]).
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)
perl
if ($age > 84) {
print "You are really ancient";
} elsif ($age > 30) {
print "You are middle-aged";
} else {
print "You are young";
}
print "You are really ancient";
} elsif ($age > 30) {
print "You are middle-aged";
} else {
print "You are young";
}
print 'You are ',
$age > 84 ? 'really ancient!'
: $age > 30 ? 'middle-aged'
: 'young';
$age > 84 ? 'really ancient!'
: $age > 30 ? 'middle-aged'
: 'young';
erlang
if
Age > 84 -> io:format("You are really ancient~n");
Age > 30 -> io:format("You are middle-aged~n");
true -> io:format("You are young~n")
end.
Age > 84 -> io:format("You are really ancient~n");
Age > 30 -> io:format("You are middle-aged~n");
true -> io:format("You are young~n")
end.
case Age of
_ when Age > 84 -> io:format("You are really ancient~n");
_ when Age > 30 -> io:format("You are middle-aged~n");
true -> io:format("You are young~n")
end.
_ when Age > 84 -> io:format("You are really ancient~n");
_ when Age > 30 -> io:format("You are middle-aged~n");
true -> io:format("You are young~n")
end.
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
perl
sub suffix {
my $n = shift;
return 'th' if $n % 100 >= 4 && $n % 100 <= 20;
return 'st' if $n % 10 == 1;
return 'nd' if $n % 10 == 2;
return 'rd' if $n % 10 == 3;
return 'th';
}
foreach my $n (1..40) {
print $n.suffix($n)."\n";
}
my $n = shift;
return 'th' if $n % 100 >= 4 && $n % 100 <= 20;
return 'st' if $n % 10 == 1;
return 'nd' if $n % 10 == 2;
return 'rd' if $n % 10 == 3;
return 'th';
}
foreach my $n (1..40) {
print $n.suffix($n)."\n";
}
erlang
Suffix = case Num of
N when N > 10, N < 20 -> "th";
N when N rem 10 =:= 1 -> "st";
N when N rem 10 =:= 2 -> "nd";
N when N rem 10 =:= 3 -> "rd";
_ -> "th"
end,
io_lib:format("~w~s", [Num, Suffix])
N when N > 10, N < 20 -> "th";
N when N rem 10 =:= 1 -> "st";
N when N rem 10 =:= 2 -> "nd";
N when N rem 10 =:= 3 -> "rd";
_ -> "th"
end,
io_lib:format("~w~s", [Num, Suffix])
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.
perl
my $x = 1;
while($x < 150) {
print $x, ",";
$x *=2
}
while($x < 150) {
print $x, ",";
$x *=2
}
erlang
X = 1, print_while_X_less_150(X).
Pred = fun (X) -> X < 150 end,
Action = fun (X) -> io:format("~B,", [X]), X * 2 end,
X = 1,
while_do(Pred, Action, X).
Action = fun (X) -> io:format("~B,", [X]), X * 2 end,
X = 1,
while_do(Pred, Action, X).
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"
perl
do {
my $number = int(rand(6)+1);
print $number;
print ',' if ($number != 6);
} while ($number != 6);
my $number = int(rand(6)+1);
print $number;
print ',' if ($number != 6);
} while ($number != 6);
erlang
Pred = fun (DiceRoll) -> DiceRoll =/= 6 end,
Action = fun (DiceRoll) -> io:format("~B,", [DiceRoll]), dice_roll() end,
do_while(Pred, Action, dice_roll()).
Action = fun (DiceRoll) -> io:format("~B,", [DiceRoll]), dice_roll() end,
do_while(Pred, Action, dice_roll()).
-module(dice).
-export([start/0]).
start() ->
roll(dice_roll()).
roll(6) ->
io:format("6~n", []);
roll(N) ->
io:format("~B,", [N]),
roll(dice_roll()).
dice_roll() -> random:uniform(6).
-export([start/0]).
start() ->
roll(dice_roll()).
roll(6) ->
io:format("6~n", []);
roll(N) ->
io:format("~B,", [N]),
roll(dice_roll()).
dice_roll() -> random:uniform(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"
perl
print "Hello" x 5
print "Hello" for (1..5)
erlang
dotimes(5, fun () -> io:format("Hello") end).
lists:foreach(fun (_) -> io:format("Hello") end, lists:seq(1, 5)).
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!"
perl
for (my $i = 10; $i > 0; $i--) {
print "$i .. ";
}
print "Liftoff!";
print "$i .. ";
}
print "Liftoff!";
print "$_ .. " for reverse 1..10;
print "Liftoff!";
print "Liftoff!";
erlang
fromto(10, 1, -1, fun (X) -> io:format("~B .. ", [X]) end), io:format("Liftoff!~n").
lists:foreach(fun (X) -> io:format("~B .. ", [X]) end, lists:seq(10, 1, -1)), io:format("Liftoff!~n").
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
perl
@file = read()
open(my $fh, '<', $path) or die "can't open $path: $!";
$string = do { local $/; <$fh> };
close $fh;
$string = do { local $/; <$fh> };
close $fh;
erlang
Text = readfile("Solution607.erl"),
Text = readfile("Solution608.erl"),
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
perl
open(my $fh, '<', $path) or die "can't open $path: $!";
$c = 1;
print $c++ . "> $_" for (<$fh>);
close $fh;
$c = 1;
print $c++ . "> $_" for (<$fh>);
close $fh;
open my $fh, '<', $path or die "Can't open $path: $!";
while (<$fh>) {
print "$.> $_";
}
while (<$fh>) {
print "$.> $_";
}
erlang
Reader = fun (IODevice) -> io:get_line(IODevice, "") end,
Worker = fun (Line, N) -> io:format("~B> ~s", [N, Line]), N + 1 end,
while_not_eof("Solution609.erl", Reader, Worker, 1).
Worker = fun (Line, N) -> io:format("~B> ~s", [N, Line]), N + 1 end,
while_not_eof("Solution609.erl", Reader, Worker, 1).
Reader = fun (Filename) -> {ok, Contents} = file:read_file(Filename), Contents end,
Transformer = fun (Line, N) -> string:concat(string:concat(integer_to_list(N), "> "), Line) end,
Printer = fun (Line) -> io:format("~s~n", [Line]) end,
Lines = string:tokens(binary_to_list(Reader("Solution610.erl")), "\n"),
NewLines = lists:zipwith(Transformer, Lines, lists:seq(1, length(Lines))),
lists:foreach(Printer, NewLines).
Transformer = fun (Line, N) -> string:concat(string:concat(integer_to_list(N), "> "), Line) end,
Printer = fun (Line) -> io:format("~s~n", [Line]) end,
Lines = string:tokens(binary_to_list(Reader("Solution610.erl")), "\n"),
NewLines = lists:zipwith(Transformer, Lines, lists:seq(1, length(Lines))),
lists:foreach(Printer, NewLines).
fantom
File(`input.text`).readAllLines.each |Str s, Int i| { echo("${i+1}> $s") }
Write a string to a file
perl
open(my $fh, '>', $path) or die "can't open $path: $!";
print $fh "This line overwites file contents!";
close $fh;
print $fh "This line overwites file contents!";
close $fh;
erlang
Line = "This line overwites file contents!\n",
{ok, IODevice} = file:open("test.txt", [write]), file:write(IODevice, Line), file:close(IODevice).
{ok, IODevice} = file:open("test.txt", [write]), file:write(IODevice, Line), file:close(IODevice).
fantom
File(`out.txt`).out.writeChars("some text").flush
Append to a file
perl
open(my $fh, '>>', $path) or die "can't open $path: $!";
print $fh "This line is appended to the file!";
close $fh;
print $fh "This line is appended to the file!";
close $fh;
erlang
Line = "This line appended to file!\n",
{ok, IODevice} = file:open("test.txt", [append]), file:write(IODevice, Line), file:close(IODevice).
{ok, IODevice} = file:open("test.txt", [append]), file:write(IODevice, Line), file:close(IODevice).
fantom
File(`out.txt`).out(true).writeChars("some text").flush
Process each file in a directory
perl
use File::Glob;
for (<*>) {
process_file($_) if (-f);
}
for (<*>) {
process_file($_) if (-f);
}
erlang
% File basenames only - many tasks require absolute paths to work
lists:foreach(fun (FileOrDirPath) -> Worker(FileOrDirPath) end, file:list_dir(Directory)).
lists:foreach(fun (FileOrDirPath) -> Worker(FileOrDirPath) end, file:list_dir(Directory)).
% Absolute paths provided - will accomodate most tasks
lists:foreach(fun (FileOrDirPath) -> Worker(FileOrDirPath) end, list_dir_path(Directory)).
lists:foreach(fun (FileOrDirPath) -> Worker(FileOrDirPath) end, list_dir_path(Directory)).
fantom
File(`./`).list.each { process(it) }
Process each file in a directory recursively
perl
use File::Glob;
process_directory(".");
sub process_directory {
my $dir = shift;
for my $file (<$dir/*>) {
next unless (-r $file);
if (-f $file) {
process_file($file);
} elsif (-d $file) {
process_directory($file);
}
}
}
process_directory(".");
sub process_directory {
my $dir = shift;
for my $file (<$dir/*>) {
next unless (-r $file);
if (-f $file) {
process_file($file);
} elsif (-d $file) {
process_directory($file);
}
}
}
use File::Find ();
# Traverse desired filesystems
sub process_directory {
my $directory = shift;
File::Find::find({wanted => \&wanted}, $directory);
}
sub wanted {
process_file( $File::Find::name );
}
# Traverse desired filesystems
sub process_directory {
my $directory = shift;
File::Find::find({wanted => \&wanted}, $directory);
}
sub wanted {
process_file( $File::Find::name );
}
erlang
filelib:fold_files(Directory, ".*", true, fun (FileOrDirPath, Acc) -> Worker(FileOrDirPath), Acc end, []).
process_dir(Directory, Worker).
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.
perl
#! /usr/bin/perl
# -*- Mode: CPerl -*-
use strict;
use POSIX;
# 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.
my $ds = "2008-05-06 13:29";
my $y;
my $m;
my $d;
my $hr;
my $mn;
print "Original: ",$ds,"\n";
if ( $ds =~ /(\d{4})-(\d{2})-(\d{2})\s+(\d{2}):(\d{2})/ ){
$y = $1 - 1900;
$m = $2;
$d = $3;
$hr = $4;
$mn = $5;
printf "Nominal: %s\n",
strftime("%e %B, %Y %l:%M:%S%P",0, $mn , $hr, $d, $m,$y);
my $eth = "";
if ( $d == 1 ){
$eth = "st";
} elsif ( $d == 2 ){
$eth = "nd";
} elsif ( $d == 3 ){
$eth = "rd";
} else {
$eth = "th";
}
printf "As required: %d%s %s\n",$d,$eth,
strftime("%B, %Y %l:%M:%S%P",0, $mn , $hr, $d, $m,$y);
}
#eos
# -*- Mode: CPerl -*-
use strict;
use POSIX;
# 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.
my $ds = "2008-05-06 13:29";
my $y;
my $m;
my $d;
my $hr;
my $mn;
print "Original: ",$ds,"\n";
if ( $ds =~ /(\d{4})-(\d{2})-(\d{2})\s+(\d{2}):(\d{2})/ ){
$y = $1 - 1900;
$m = $2;
$d = $3;
$hr = $4;
$mn = $5;
printf "Nominal: %s\n",
strftime("%e %B, %Y %l:%M:%S%P",0, $mn , $hr, $d, $m,$y);
my $eth = "";
if ( $d == 1 ){
$eth = "st";
} elsif ( $d == 2 ){
$eth = "nd";
} elsif ( $d == 3 ){
$eth = "rd";
} else {
$eth = "th";
}
printf "As required: %d%s %s\n",$d,$eth,
strftime("%B, %Y %l:%M:%S%P",0, $mn , $hr, $d, $m,$y);
}
#eos
# Shurely you mean 6th MAY? If not, oh well
use Time::Piece;
my $dt_str = '2008-05-06 13:29';
my $tp = Time::Piece->strptime( $dt_str, '%Y-%m-%d %H:%M');
print $tp,"\n";
use Time::Piece;
my $dt_str = '2008-05-06 13:29';
my $tp = Time::Piece->strptime( $dt_str, '%Y-%m-%d %H:%M');
print $tp,"\n";
erlang
% AFAIK, no datetime-parsing library exists; 'parse_to_datetime' is a simplistic, problem-specific hack
LocalDateTime = erlang:universaltime_to_localtime(parse_to_datetime("2008-05-06 13:29:34")),
LocalDateTime = erlang:universaltime_to_localtime(parse_to_datetime("2008-05-06 13:29:34")),
fantom
dt := DateTime.fromLocale("2008-05-06 13:29", "YYYY-MM-DD hh:mm")
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.
perl
use Class::Date;
my $date = Class::Date->now();
print $date->string()."\n";
print localtime()."\n";
my $date = Class::Date->now();
print $date->string()."\n";
print localtime()."\n";
use Time::Piece ();
# Date object
my $date = Time::Piece::localtime;
print "$date\n";
# no object
print scalar(localtime),"\n";
# Date object
my $date = Time::Piece::localtime;
print "$date\n";
# no object
print scalar(localtime),"\n";
erlang
io:format("~p~n", [calendar:local_time()])
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.
perl
{ package Greeter;
sub new {
my $self = {};
my $type = shift;
$self->{'whom'} = shift;
bless $self, $type;
}
sub greet {
my $self = shift;
print "Hello " . $self->{'whom'} . "!\n";
}
}
my $greeter = Greeter->new("world");
$greeter->greet();
sub new {
my $self = {};
my $type = shift;
$self->{'whom'} = shift;
bless $self, $type;
}
sub greet {
my $self = shift;
print "Hello " . $self->{'whom'} . "!\n";
}
}
my $greeter = Greeter->new("world");
$greeter->greet();
{
package Greeter;
sub new {
my $class = shift;
my $whom = shift or die 'Need a name to greet';
bless \$whom, $class;
}
sub greet {
my $self = shift;
print "Hello $$self!\n";
}
}
my $greeter = Greeter->new("Bob");
$greeter->greet();
package Greeter;
sub new {
my $class = shift;
my $whom = shift or die 'Need a name to greet';
bless \$whom, $class;
}
sub greet {
my $self = shift;
print "Hello $$self!\n";
}
}
my $greeter = Greeter->new("Bob");
$greeter->greet();
erlang
Greeter = make_greeter("world!"),
Greeter(greet).
Greeter(greet).
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
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.
perl
# requires libwww-perl
use LWP::Simple;
if (grep /perl/, get('http://langref.org/')) {
print 'perl appears on langref.org';
} else {
print 'perl does not appear on langref.org';
}
use LWP::Simple;
if (grep /perl/, get('http://langref.org/')) {
print 'perl appears on langref.org';
} else {
print 'perl does not appear on langref.org';
}
erlang
URL = "http://langref.org/", Language = "erlang", Regexp = ".*" ++ URL ++ Language ++ ".*",
case http:request(URL) of
{ok, {_, _, Body}} ->
case regexp:first_match(Body, Regexp) of
{match, _, _} -> io:format("Language ~s exists @ ~s~n", [Language, URL]);
_ -> false
end;
{error, ErrorInfo} -> throw("Error: " ++ http:format_error(ErrorInfo))
end,
case http:request(URL) of
{ok, {_, _, Body}} ->
case regexp:first_match(Body, Regexp) of
{match, _, _} -> io:format("Language ~s exists @ ~s~n", [Language, URL]);
_ -> false
end;
{error, ErrorInfo} -> throw("Error: " ++ http:format_error(ErrorInfo))
end,
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
perl
#! /usr/bin/perl
# -*- Mode: CPerl -*-
use strict;
use XML::Simple;
use Data::Dumper;
# Given the XML Document:
#
# <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
my $xml =
" <shopping>\n"
." <item name=\"bread\" quantity=\"3\" price=\"2.50\"/>\n"
." <item name=\"milk\" quantity=\"2\" price=\"3.50\"/>\n"
." </shopping>\n";
my $xs = XML::Simple->new();
my $ref = $xs->XMLin($xml);
my $stuff = ${$ref}{item};
my $q;
my $p;
my $t;
my $z;
foreach my $item ( sort keys %{$stuff}){
$q = ${$stuff}{$item}{quantity};
$p = ${$stuff}{$item}{price};
$z = $q*$p;
printf "%5.5s %2d @\$%5.2f = \$%5.2f\n",$item,$q,$p,$z;
$t += $z;
}
printf "Total \$%5.2f\n",$t;
#eos
# -*- Mode: CPerl -*-
use strict;
use XML::Simple;
use Data::Dumper;
# Given the XML Document:
#
# <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
my $xml =
" <shopping>\n"
." <item name=\"bread\" quantity=\"3\" price=\"2.50\"/>\n"
." <item name=\"milk\" quantity=\"2\" price=\"3.50\"/>\n"
." </shopping>\n";
my $xs = XML::Simple->new();
my $ref = $xs->XMLin($xml);
my $stuff = ${$ref}{item};
my $q;
my $p;
my $t;
my $z;
foreach my $item ( sort keys %{$stuff}){
$q = ${$stuff}{$item}{quantity};
$p = ${$stuff}{$item}{price};
$z = $q*$p;
printf "%5.5s %2d @\$%5.2f = \$%5.2f\n",$item,$q,$p,$z;
$t += $z;
}
printf "Total \$%5.2f\n",$t;
#eos
use strict;
use XML::Twig;
use Data::Dumper;
my $xml = <<ENDXML;
<shopping>
<item name="bread" quantity="3" price="2.50"/>
<item name="milk" quantity="2" price="3.50"/>
</shopping>
ENDXML
my $xt = XML::Twig->parse( $xml );
my $price;
foreach my $item ($xt->root->children('item')) {
$price += ($item->{att}{price} * $item->{att}{quantity})
}
printf "Total Cost: %.2f\n", $price
use XML::Twig;
use Data::Dumper;
my $xml = <<ENDXML;
<shopping>
<item name="bread" quantity="3" price="2.50"/>
<item name="milk" quantity="2" price="3.50"/>
</shopping>
ENDXML
my $xt = XML::Twig->parse( $xml );
my $price;
foreach my $item ($xt->root->children('item')) {
$price += ($item->{att}{price} * $item->{att}{quantity})
}
printf "Total Cost: %.2f\n", $price
erlang
-include_lib("xmerl/include/xmerl.hrl").
-export([get_total/1]).
get_total(ShoppingList) ->
{XmlElt, _} = xmerl_scan:string(ShoppingList),
Items = xmerl_xpath:string("/shopping/item", XmlElt),
Total = lists:foldl(fun(Item, Tot) ->
[#xmlAttribute{value = PriceString}] = xmerl_xpath:string("/item/@price", Item),
{Price, _} = string:to_float(PriceString),
[#xmlAttribute{value = QuantityString}] = xmerl_xpath:string("/item/@quantity", Item),
{Quantity, _} = string:to_integer(QuantityString),
Tot + Price*Quantity
end,
0, Items),
io:format("$~.2f~n", [Total]).
-export([get_total/1]).
get_total(ShoppingList) ->
{XmlElt, _} = xmerl_scan:string(ShoppingList),
Items = xmerl_xpath:string("/shopping/item", XmlElt),
Total = lists:foldl(fun(Item, Tot) ->
[#xmlAttribute{value = PriceString}] = xmerl_xpath:string("/item/@price", Item),
{Price, _} = string:to_float(PriceString),
[#xmlAttribute{value = QuantityString}] = xmerl_xpath:string("/item/@quantity", Item),
{Quantity, _} = string:to_integer(QuantityString),
Tot + Price*Quantity
end,
0, Items),
io:format("$~.2f~n", [Total]).
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>
perl
#! /usr/bin/perl
# -*- Mode: CPerl -*-
use strict;
use XML::Simple;
use Data::Dumper;
# 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>
#
my $line;
my $item;
my $q;
my $p;
my $z;
my $xs = XML::Simple->new();
my %d = ();
while($line=<DATA>){
chomp $line;
($item,$q,$p) = split ",",$line;
$d{shopping}{item}{$item}{quantity} = $q;
$d{shopping}{item}{$item}{price} = $p;
}
$xml = $xs->XMLout(\%d, KeepRoot => 1);
print $xml,"\n";
__DATA__
bread,3,2.50
milk,2,3.50
# -*- Mode: CPerl -*-
use strict;
use XML::Simple;
use Data::Dumper;
# 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>
#
my $line;
my $item;
my $q;
my $p;
my $z;
my $xs = XML::Simple->new();
my %d = ();
while($line=<DATA>){
chomp $line;
($item,$q,$p) = split ",",$line;
$d{shopping}{item}{$item}{quantity} = $q;
$d{shopping}{item}{$item}{price} = $p;
}
$xml = $xs->XMLout(\%d, KeepRoot => 1);
print $xml,"\n";
__DATA__
bread,3,2.50
milk,2,3.50
use strict;
use XML::Writer;
use Text::CSV;
my $csv = <<ENDOFCSV;
bread,3,2.50
milk,2,3.50
ENDOFCSV
open my $fh, '<', \$csv or die "Can't open string, $!\n";
my $csv = Text::CSV->new;
my $writer = XML::Writer->new(DATA_MODE => 1, DATA_INDENT => 2);
$writer->startTag('shopping');
while (my $arr_ref = $csv->getline($fh)) {
my %attributes;
@attributes{qw/name quantity price/} =
@{$arr_ref}[0..2];
$writer->emptyTag('item' => %attributes)
}
$writer->endTag('shopping');
use XML::Writer;
use Text::CSV;
my $csv = <<ENDOFCSV;
bread,3,2.50
milk,2,3.50
ENDOFCSV
open my $fh, '<', \$csv or die "Can't open string, $!\n";
my $csv = Text::CSV->new;
my $writer = XML::Writer->new(DATA_MODE => 1, DATA_INDENT => 2);
$writer->startTag('shopping');
while (my $arr_ref = $csv->getline($fh)) {
my %attributes;
@attributes{qw/name quantity price/} =
@{$arr_ref}[0..2];
$writer->emptyTag('item' => %attributes)
}
$writer->endTag('shopping');
erlang
to_xml(ShoppingList) ->
Items = lists:map(fun(L) ->
[Name, Quantity, Price] = string:tokens(L, ","),
{item, [{name, Name}, {quantity, Quantity}, {price, Price}], []}
end, string:tokens(ShoppingList, "\n")),
xmerl:export_simple([{shopping, [], Items}], xmerl_xml).
Items = lists:map(fun(L) ->
[Name, Quantity, Price] = string:tokens(L, ","),
{item, [{name, Name}, {quantity, Quantity}, {price, Price}], []}
end, string:tokens(ShoppingList, "\n")),
xmerl:export_simple([{shopping, [], Items}], xmerl_xml).
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]
perl
#!/usr/bin/perl
my @results;
for my $x (1..20) {
for my $y ($x..20) {
my $z = sqrt($x**2+$y**2);
push @results, [$x,$y,$z] if $z == int($z);
}
}
for my $triangle ( sort { $a->[2] <=> $b->[2] } @results) {
print "[".join(',',@$triangle)."]\n";
}
my @results;
for my $x (1..20) {
for my $y ($x..20) {
my $z = sqrt($x**2+$y**2);
push @results, [$x,$y,$z] if $z == int($z);
}
}
for my $triangle ( sort { $a->[2] <=> $b->[2] } @results) {
print "[".join(',',@$triangle)."]\n";
}
erlang
find_all_pythagorean_triangles(L) ->
lists:sort(fun({_, _, H1}, {_, _, H2}) -> H1 =< H2 end,
[ { X, Y, Z } ||
X <- lists:seq(1,L),
Y <- lists:seq(1,L),
Z <- lists:seq(1,2*L),
X*X + Y*Y =:= Z*Z,
Y > X,
Z > Y
]).
main(_) ->
List = find_all_pythagorean_triangles(20).
lists:sort(fun({_, _, H1}, {_, _, H2}) -> H1 =< H2 end,
[ { X, Y, Z } ||
X <- lists:seq(1,L),
Y <- lists:seq(1,L),
Z <- lists:seq(1,2*L),
X*X + Y*Y =:= Z*Z,
Y > X,
Z > Y
]).
main(_) ->
List = find_all_pythagorean_triangles(20).
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.
perl
sub gcd {
my ($a, $b) = @_;
($a,$b) = ($b,$a) if $a > $b;
while ($a) { ($a, $b) = ($b % $a, $a) }
return $b;
}
print gcd( 8, 12 );
my ($a, $b) = @_;
($a,$b) = ($b,$a) if $a > $b;
while ($a) { ($a, $b) = ($b % $a, $a) }
return $b;
}
print gcd( 8, 12 );
my $g = gcd (8, 12);
print $g;
sub gcd {
# Euclid's Algorithm - recursive
my ($c, $d) = @_;
return $c unless $d;
return gcd ($d, $c % $d);
}
print $g;
sub gcd {
# Euclid's Algorithm - recursive
my ($c, $d) = @_;
return $c unless $d;
return gcd ($d, $c % $d);
}
my $g = gcd2 (8, 12);
print $g;
sub gcd2 {
# Dijkstra's Algorithm - recursive
my ($c, $d) = @_;
return $c if $c == $d;
return $c > $d? gcd2 ($c - $d, $d) : gcd2 ($c, $d - $c);
}
print $g;
sub gcd2 {
# Dijkstra's Algorithm - recursive
my ($c, $d) = @_;
return $c if $c == $d;
return $c > $d? gcd2 ($c - $d, $d) : gcd2 ($c, $d - $c);
}
erlang
-module(gcd).
-export([gcd/2]).
gcd(A, 0) -> A;
gcd(A, B) -> gcd(B, A rem B).
-export([gcd/2]).
gcd(A, 0) -> A;
gcd(A, B) -> gcd(B, A rem B).
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
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.
perl
use threads;
foreach my $tid ("one","two","three","four") {
threads->create(
sub { print("Thread $tid says Hello World!\n"); }
)->join();
}
foreach my $tid ("one","two","three","four") {
threads->create(
sub { print("Thread $tid says Hello World!\n"); }
)->join();
}
erlang
-module(spam).
-export([spam/1]).
spam(N) when N<5 ->
spawn(fun() -> io:format("Hello World from thread ~p~n",[N]) end),
spam(N+1);
spam(_) -> void.
-export([spam/1]).
spam(N) when N<5 ->
spawn(fun() -> io:format("Hello World from thread ~p~n",[N]) end),
spam(N+1);
spam(_) -> void.
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)
}
