Rosetta Cow project is intended to present solutions to the same task (i.e. to implement cowsay which prints an ASCII cow with a message) in as many different programming languages as possible, to demonstrate how languages are similar and different (similarly as in Rosetta Code).
The Rosetta name comes from The Rosetta Stone.
Implement a command-line application (called cowsay) which prints an ASCII cow with a message in a speech bubble. The width of the enclosing speech bubble must be dynamic, depending on the length of the message.
The first argument of the application is the message. If zero or more than one parameters are provided then a usage information is printed in the console.
The solution must be in a single file. Only standard libraries of the given programming language can be used.
cowsay without arguments:
$ cowsay
Usage: cowsay [message]
cowsay with the "Hello World!" message as argument:
$ cowsay "Hello World!"
____________
< Hello World! >
------------
\ ^__^
\ (oo)\_______
(__)\ )\/\
||----w |
|| ||
C
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
char *template =
" %s \n"
"< %s >\n"
" %s\n"
" \\ ^__^\n"
" \\ (oo)\\_______\n"
" (__)\\ )\\/\\\n"
" ||----w |\n"
" || ||\n";
char *border(char *text, char borderChar) {
int length = strlen(text) + 2;
char *buffer = malloc(length + 1);
memset(buffer, borderChar, length);
buffer[length] = '\0';
return buffer;
}
int main(int argc, char *argv[]) {
if (argc == 2) {
char *text = argv[1];
printf(template, border(text, '_'), text, border(text, '-'));
} else {
printf("Usage: cowsay [message]\n");
}
return 0;
}
Implemented using: gcc (GCC) 7.4.0
Goby
#!/usr/bin/env goby
def template(text)
String.fmt "
%s
< %s >
%s
\\ ^__^
\\ (oo)\\_______
(__)\\ )\\/\\
||----w |
|| ||
", border(text, '_'), text, border(text, '-')
end
def border(text, char)
char * (text.length + 2)
end
if ARGV.length == 1
text = ARGV[0]
puts template(text)
else
puts "Usage: cowsay [message]"
end
Implemented using: goby 0.1.13
Go (Golang)
package main
import (
"fmt"
"os"
"strings"
)
const template string = `
%s
< %s >
%s
\ ^__^
\ (oo)\_______
(__)\ )\/\
||----w |
|| ||
`
func border(text, char string) string {
return strings.Repeat(char, len([]rune(text))+2)
}
func main() {
if len(os.Args) == 2 {
text := os.Args[1]
fmt.Printf(template, border(text, "_"), text, border(text, "-"))
} else {
fmt.Println("Usage: cowsay [message]")
}
}
Implemented using: go version go1.13
Groovy
#!/usr/bin/env groovy
def template(text) {
"""
${border(text, '_')}
< ${text} >
${border(text, '-')}
\\ ^__^
\\ (oo)\\_______
(__)\\ )\\/\\
||----w |
|| ||
"""
}
def border(text, chr) {
chr * (text.length() + 2)
}
if (args.length == 1) {
text = args[0]
println template(text)
} else {
println "Usage: cowsay [message]"
}
Implemented using: Groovy Version: 2.5.8
Io
#!/usr/local/bin/io
template := method(text,
"""
#{border(text, "_")}
< #{text} >
#{border(text, "-")}
\ ^__^
\ (oo)\_______
(__)\ )\/\
||----w |
|| ||
""" interpolate
)
border := method(text, char,
char repeated(text size + 2)
)
if(System args size == 2) then(
text := System args at(1)
template(text) println
) else(
"Usage: cowsay [message]" println
)
Implemented using: Io Programming Language, v. 20110905
Java
public class Cowsay {
private static final String TEMPLATE = """
%s
< %s >
%s
\\ ^__^
\\ (oo)\\_______
(__)\\ )\\/\\
||----w |
|| ||
""";
private static String border(String text, String border) {
return border.repeat(text.length() + 2);
}
public static void main(String[] args) {
if (args.length == 1) {
var text = args[0];
System.out.printf(TEMPLATE, border(text, "_"), text, border(text, "-"));
} else {
System.out.println("Usage: cowsay [message]");
}
}
}
Implemented using: openjdk version 17.0.4
Julia
#!/usr/bin/env julia
template(text) =
"""
$(border(text, '_'))
< $text >
$(border(text, '-'))
\\ ^__^
\\ (oo)\\_______
(__)\\ )\\/\\
||----w |
|| ||
"""
border(text, char) = repeat(char, length(text) + 2)
if length(ARGS) == 1
text = ARGS[1]
println(template(text))
else
println("Usage: cowsay [message]")
end
Implemented using: julia version 1.6.3
JavaScript
#!/usr/bin/env node
function template(text) {
return `
${border(text, '_')}
< ${text} >
${border(text, '-')}
\\ ^__^
\\ (oo)\\_______
(__)\\ )\\/\\
||----w |
|| ||
`;
}
function border(text, char) {
return char.repeat(text.length + 2);
}
const args = process.argv.slice(2);
if (args.length === 1) {
const text = args[0];
console.log(template(text));
} else {
console.log('Usage: cowsay [message]');
}
Implemented using: Node.js v8.10.0
Kotlin
fun template(text: String) =
"""
${border(text, "_")}
< ${text} >
${border(text, "-")}
\ ^__^
\ (oo)\_______
(__)\ )\/\
||----w |
|| ||
""".trimIndent()
fun border(text: String, chr: String) = chr.repeat(text.length + 2)
fun main(args: Array<String>) {
if (args.size == 1) {
val text = args[0]
println(template(text))
} else {
println("Usage: cowsay [message]")
}
}
Implemented using: Kotlin version 1.5.0-release-749
LOLCODE
HAI 1.2
VISIBLE "Welcome to Lolcode Cow!"
I HAS A num_args ITZ COUNT Args
VISIBLE num_args
IF num_args IS 1
I HAS A text ITZ Args
I HAS A length ITZ BOTH SAEM text AN text
I HAS A top_border ITZ REPEAT "_", SUM OF length, 2
I HAS A bottom_border ITZ REPEAT "-", SUM OF length, 2
VISIBLE top_border
VISIBLE " " + text + " "
VISIBLE bottom_border
VISIBLE " \ ^__^"
VISIBLE " \ (oo)\_______"
VISIBLE " (__)\ )\/\"
VISIBLE " ||----w |"
VISIBLE " || ||"
ELSE
VISIBLE "Usage: cowsay [message]"
KTHXBYE
Implemented using: ChatGPT Feb 13 Version
Lua
#!/usr/bin/env lua
local template = [[
%s
< %s >
%s
\ ^__^
\ (oo)\_______
(__)\ )\/\
||----w |
|| ||
]]
function border (text, char)
return string.rep(char, #text + 2)
end
if #arg == 1 then
local text = arg[1]
print(string.format(template, border(text, '_'), text, border(text, '-')))
else
print('Usage: cowsay [message]')
end
Implemented using: Lua 5.3.3
Nim
import os
const template = """
%s
< %s >
%s
\ ^__^
\ (oo)\_______
(__)\ )\/\
||----w |
|| ||
"""
func border(text: string, char: char): string =
char.chr * (text.len + 2)
if paramCount() == 1:
let text = paramStr(1)
let result = template % [border(text, '_'), text, border(text, '-')]
echo result
else:
echo "Usage: cowsay [message]"
Implemented using: ChatGPT Feb 13 Version
Pascal
program cowsay;
uses sysutils, strutils;
const
template: string = concat(
' %s', lineending,
'< %s >', lineending,
' %s', lineending,
' \ ^__^', lineending,
' \ (oo)\_______', lineending,
' (__)\ )\/\', lineending,
' ||----w |', lineending,
' || ||', lineending
);
var
text: string;
function border(text, char: string): string;
begin
border := dupestring(char, length(text) + 2);
end;
begin
if paramcount = 1 then
begin
text := paramstr(1);
writeln(format(template, [border(text, '_'), text, border(text, '-')]));
end
else
writeln('Usage: cowsay [message]');
end.
Implemented using: Free Pascal Compiler version 3.0.4
PHP
#!/usr/local/bin/php
<?php
function template($text, $border) {
return "
{$border($text, '_')}
< {$text} >
{$border($text, '-')}
\ ^__^
\ (oo)\_______
(__)\ )\/\
||----w |
|| ||
";
}
$border = function($text, $char) {
return str_repeat($char, strlen($text) + 2);
};
if ($argc == 2) {
print template($argv[1], $border);
} else {
print "Usage: cowsay [message]\n";
}
?>
Implemented using: PHP 8.0.0 (cli)
PowerShell
function template($text) {
" $(border $text '_')
< $text >
$(border $text '-')
\ ^__^
\ (oo)\_______
(__)\ )\/\
||----w |
|| ||"
}
function border($text, $char) {
$char * ($text.length + 2)
}
if ($args.length -eq 1) {
$text = $args[0]
Write-Host (template $text)
} else {
Write-Host "Usage: cowsay [message]"
}
Implemented using: PowerShell version 5.1.19041.906
Python
#!/usr/bin/python
import sys
template = """
%s
< %s >
%s
\ ^__^
\ (oo)\_______
(__)\ )\/\\
||----w |
|| ||
"""
def border(text, char):
return char * (len(text) + 2)
if len(sys.argv) == 2:
text = sys.argv[1]
print(template % (border(text, "_"), text, border(text, "-")))
else:
print("Usage: cowsay [message]")
Implemented using: Python 2.7.15+
Ruby
#!/usr/bin/env ruby
def template(text)
"
#{border text, '_'}
< #{text} >
#{border text, '-'}
\\ ^__^
\\ (oo)\\_______
(__)\\ )\\/\\
||----w |
|| ||
"
end
def border(text, char)
char * (text.length + 2)
end
if ARGV.size == 1
text = ARGV[0]
puts template(text)
else
puts "Usage: cowsay [message]"
end
Implemented using: ruby 2.5.1p57
Rust
use std::env;
fn template(text: &str) -> String {
format!(
r#"
{}
< {} >
{}
\ ^__^
\ (oo)\_______
(__)\ )\/\
||----w |
|| ||
"#,
border(text, "_"),
text,
border(text, "-")
)
}
fn border(text: &str, chr: &str) -> String {
chr.repeat(text.chars().count() + 2)
}
fn main() {
let args: Vec<String> = env::args().skip(1).collect();
if args.len() == 1 {
let text = &args[0];
println!("{}", template(text));
} else {
println!("Usage: cowsay [message]");
}
}
Implemented using: rustc 1.65.0
Scala
object Cowsay {
val template = """
%s
< %s >
%s
\ ^__^
\ (oo)\_______
(__)\ )\/\
||----w |
|| ||
"""
def border(text: String, char: Char): String = char.toString * (text.length + 2)
def main(args: Array[String]): Unit = {
if (args.length == 1) {
val text = args(0)
val result = template.format(border(text, '_'), text, border(text, '-'))
println(result)
} else {
println("Usage: cowsay [message]")
}
}
}
Implemented using: ChatGPT Feb 13 Version
Bash
#!/bin/bash
TEMPLATE=" %s
< %s >
%s
\\ ^__^
\\ (oo)\\_______
(__)\\ )\\/\\
||----w |
|| ||\n"
border() {
v=$(printf "%-${#1}s" "$2")
echo "$2${v// /$2}$2"
}
if [ $# -eq 1 ]; then
printf "$TEMPLATE" $(border "$1" "_") "$1" $(border "$1" "-")
else
echo "Usage: cowsay [message]"
fi
Implemented using: GNU bash, version 5.0.7
TypeScript
#!/usr/bin/env ts-node
function template(text: string) {
return `
${border(text, '_')}
< ${text} >
${border(text, '-')}
\\ ^__^
\\ (oo)\\_______
(__)\\ )\\/\\
||----w |
|| ||
`
}
function border(text: string, char: string) {
return char.repeat(text.length + 2)
}
const args: string[] = process.argv.slice(2)
if (args.length === 1) {
const text = args[0]
console.log(template(text))
} else {
console.log('Usage: cowsay [message]')
}
Implemented using: ts-node v8.6.2
VBScript
Function template(text)
template = Join(Array( _
" " & border(text, "_"), _
"< " & text & " >", _
" " & border(text, "-"), _
" \ ^__^", _
" \ (oo)\_______", _
" (__)\ )\/\", _
" ||----w |", _
" || ||" _
), vbNewLine)
End Function
Function border(text, char)
Dim i, result
For i = 1 To Len(text) + 2
result = result & char
Next
border = result
End Function
If WScript.Arguments.Length = 1 Then
Dim text
text = WScript.Arguments(0)
WScript.Echo(template(text))
Else
WScript.Echo("Usage: cowsay [message]")
End If
Implemented using: Microsoft (R) Windows Script Host Version 5.812