Rosetta Code/Run examples: Difference between revisions

Added Wren
m (→‎{{header|Phix}}: replaced a few {{)
(Added Wren)
Line 2,081:
=={{header|UNIX Shell}}==
See [[C1R Implementation]] for an incomplete implementation. (only supports [[C]])
 
=={{header|Wren}}==
{{trans|Go}}
{{libheader|WrenGo}}
{{libheader|Wren-set}}
{{libheader|Wren-pattern}}
{{libheader|Wren-str}}
An embedded program with a Go host as Wren-cli currently has no way to download web pages.
 
This is designed to work for Go, Perl, Python and Wren itself though see the remarks in the Go entry about using the first three languages and other more general points.
 
As far as Wren is concerned, in addition to Wren-cli programs, this should be able to run DOME, Wren-gmp, Wren-sql and Wren-i64 programs as it is easy to detect when these are being used and the filename is always given as a command line argument. All Wren modules are assumed to be present in the current working directory.
 
However, no attempt has been made - at least for now - to run other embedded programs (which can be identified by the presence of the 'foreign' keyword) due to a number of technical difficulties in doing so.
<lang ecmascript>/* rc_run_examples.wren */
 
import "./set" for Set
import "./pattern" for Pattern
import "./str" for Str
 
class Http {
// gets the response body, copies it to a string and automatically closes it
foreign static getBodyText(url)
}
 
class Html {
foreign static unescapeString(s)
}
 
class Stdin {
foreign static readLine()
}
 
class IOUtil {
foreign static writeFile(fileName, text)
 
foreign static removeFile(fileName)
}
 
class Exec {
foreign static run2(lang, fileName)
foreign static run3(lang, param, fileName)
}
 
var getAllTasks = Fn.new {
var p = Pattern.new("<li><a href/=\"//wiki//[+0^\"]\"")
var url1 = "http://rosettacode.org/wiki/Category:Programming_Tasks"
var url2 = "http://rosettacode.org/wiki/Category:Draft_Programming_Tasks"
var urls = [url1, url2]
var tasks = Set.new()
for (url in urls) {
var body = Http.getBodyText(url)
// find all tasks
var matches = p.findAll(body)
for (match in matches) {
// exclude any 'category' references
var task = match.capsText[0]
if (!task.startsWith("Category:")) tasks.add(task)
}
}
return tasks
}
 
var tasks = getAllTasks.call()
var langs = ["go", "perl", "python", "wren"]
while (true) {
System.write("Enter the exact name of the task : ")
var task = Stdin.readLine().trim().replace(" ", "_")
if (!tasks.contains(task)) {
System.print("Sorry a task with that name doesn't exist.")
} else {
var url = "https://rosettacode.org/mw/index.php?title=" + task + "&action=edit"
var page = Http.getBodyText(url).replace("&lt;", "<")
var lang
while (true) {
System.write("Enter the language Go/Perl/Python/Wren : ")
lang = Str.lower(Stdin.readLine().trim())
if (langs.contains(lang)) break
System.print("Sorry that language is not supported.")
}
var lang2
var lang3
var ext
if (lang == "go") {
lang2 = "Go"
lang3 = "[go|Go|GO]"
ext = "go"
} else if (lang == "perl") {
lang2 = "Perl"
lang3 = "[perl|Perl]"
ext = "pl"
} else if (lang == "python") {
lang2 = "Python"
lang3 = "[python|Python]"
ext = "py"
} else if (lang == "wren") {
lang2 = "Wren"
lang3 = "[ecmascript|Ecmascript]"
ext = "wren"
}
var fileName = "rc_temp." + ext
var p1 = Pattern.new("/=/={{header/|%(lang2)}}/=/=")
var p2 = Pattern.new("<lang %(lang3)>")
var p3 = Pattern.new("<//lang>")
var s = p1.split(page, 1, 0)
if (s.count > 1) s = p2.split(s[1], 1, 0)
var preamble = s[0]
if (s.count > 1) s = p3.split(s[1], 1, 0)
if (s.count == 1) {
System.print("No runnable task entry for that language was detected.")
} else if (lang == "wren" && s[0].contains(" foreign ")) {
System.print("This is an embedded script which cannot be run automatically at present.")
} else {
var source = Html.unescapeString(s[0])
System.print("\nThis is the source code for the first or only runnable program:\n")
System.print(source)
System.write("\nDo you want to run it y/n : ")
var yn = Stdin.readLine().trim()[0]
// note that the executable names may differ from the ones I'm currently using
if (yn == "y" || yn == "Y") {
IOUtil.writeFile(fileName, source)
if (lang == "go") {
Exec.run3("go", "run", fileName)
} else if (lang == "perl") {
Exec.run2("perl", fileName)
} else if (lang == "python") {
Exec.run2("python3", fileName)
} else if (lang == "wren") {
if (preamble.contains("{{libheader|DOME}}")) {
Exec.run2("dome171", fileName)
} else if (preamble.contains("{{libheader|Wren-gmp}}")) {
Exec.run2("./wren-gmp", fileName)
} else if (preamble.contains("{{libheader|Wren-sql}}")) {
Exec.run2("./wren-sql", fileName)
} else if (preamble.contains("{{libheader|Wren-i64}}")) {
Exec.run2("./wren-i64", fileName)
} else { // Wren-cli
Exec.run2("wren4", fileName)
}
}
IOUtil.removeFile(fileName)
}
}
System.write("\nDo another one y/n : ")
var yn = Stdin.readLine().trim()[0]
if (yn != "y" && yn != "Y") return
}
}</lang>
We now embed this script in the following Go program and run it:
<lang go>/* go run rc_run_examples.go */
 
package main
 
import (
"bufio"
wren "github.com/crazyinfin8/WrenGo"
"html"
"io/ioutil"
"log"
"net/http"
"os"
"os/exec"
"strings"
)
 
type any = interface{}
 
var in = bufio.NewReader(os.Stdin)
 
func check(err error) {
if err != nil {
log.Fatal(err)
}
}
 
func getBodyText(vm *wren.VM, parameters []any) (any, error) {
url := parameters[1].(string)
resp, _ := http.Get(url)
body, _ := ioutil.ReadAll(resp.Body)
resp.Body.Close()
return string(body), nil
}
 
func unescapeString(vm *wren.VM, parameters []any) (any, error) {
s := parameters[1].(string)
return html.UnescapeString(s), nil
}
 
func readLine(vm *wren.VM, parameters []any) (any, error) {
l, err := in.ReadString('\n')
check(err)
return l, nil
}
 
func writeFile(vm *wren.VM, parameters []any) (any, error) {
fileName := parameters[1].(string)
text := parameters[2].(string)
err := ioutil.WriteFile(fileName, []byte(text), 0666)
check(err)
return nil, nil
}
 
func removeFile(vm *wren.VM, parameters []any) (any, error) {
fileName := parameters[1].(string)
err := os.Remove(fileName)
check(err)
return nil, nil
}
 
func run2(vm *wren.VM, parameters []any) (any, error) {
lang := parameters[1].(string)
fileName := parameters[2].(string)
cmd := exec.Command(lang, fileName)
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
cmd.Run()
return nil, nil
}
 
func run3(vm *wren.VM, parameters []any) (any, error) {
lang := parameters[1].(string)
param := parameters[2].(string)
fileName := parameters[3].(string)
cmd := exec.Command(lang, param, fileName)
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
cmd.Run()
return nil, nil
}
 
func moduleFn(vm *wren.VM, name string) (string, bool) {
if name != "meta" && name != "random" && !strings.HasSuffix(name, ".wren") {
name += ".wren"
}
return wren.DefaultModuleLoader(vm, name)
}
 
func main() {
cfg := wren.NewConfig()
cfg.LoadModuleFn = moduleFn
vm := cfg.NewVM()
 
httpMethodMap := wren.MethodMap{
"static getBodyText(_)": getBodyText,
}
 
htmlMethodMap := wren.MethodMap{
"static unescapeString(_)": unescapeString,
}
 
stdinMethodMap := wren.MethodMap{
"static readLine()": readLine,
}
 
ioutilMethodMap := wren.MethodMap{
"static writeFile(_,_)": writeFile,
"static removeFile(_)": removeFile,
}
 
execMethodMap := wren.MethodMap{
"static run2(_,_)": run2,
"static run3(_,_,_)": run3,
}
 
classMap := wren.ClassMap{
"Http": wren.NewClass(nil, nil, httpMethodMap),
"Html": wren.NewClass(nil, nil, htmlMethodMap),
"Stdin": wren.NewClass(nil, nil, stdinMethodMap),
"IOUtil": wren.NewClass(nil, nil, ioutilMethodMap),
"Exec": wren.NewClass(nil, nil, execMethodMap),
}
 
module := wren.NewModule(classMap)
fileName := "rc_run_examples.wren"
vm.SetModule(fileName, module)
vm.InterpretFile(fileName)
vm.Free()
}</lang>
 
{{out}}
Sample run:
<pre>
Enter the exact name of the task : Palindrome dates
Enter the language Go/Perl/Python/Wren : Go
 
This is the source code for the first or only runnable program:
 
package main
 
import (
"fmt"
"time"
)
 
func reverse(s string) string {
chars := []rune(s)
for i, j := 0, len(chars)-1; i < j; i, j = i+1, j-1 {
chars[i], chars[j] = chars[j], chars[i]
}
return string(chars)
}
 
func main() {
const (
layout = "20060102"
layout2 = "2006-01-02"
)
fmt.Println("The next 15 palindromic dates in yyyymmdd format after 20200202 are:")
date := time.Date(2020, 2, 2, 0, 0, 0, 0, time.UTC)
count := 0
for count < 15 {
date = date.AddDate(0, 0, 1)
s := date.Format(layout)
r := reverse(s)
if r == s {
fmt.Println(date.Format(layout2))
count++
}
}
}
 
Do you want to run it y/n : y
The next 15 palindromic dates in yyyymmdd format after 20200202 are:
2021-12-02
2030-03-02
2040-04-02
2050-05-02
2060-06-02
2070-07-02
2080-08-02
2090-09-02
2101-10-12
2110-01-12
2111-11-12
2120-02-12
2121-12-12
2130-03-12
2140-04-12
 
Do another one y/n : y
Enter the exact name of the task : Palindrome dates
Enter the language Go/Perl/Python/Wren : Perl
 
This is the source code for the first or only runnable program:
 
use Time::Piece;
my $d = Time::Piece->strptime("2020-02-02", "%Y-%m-%d");
 
for (my $k = 1 ; $k <= 15 ; $d += Time::Piece::ONE_DAY) {
my $s = $d->strftime("%Y%m%d");
if ($s eq reverse($s) and ++$k) {
print $d->strftime("%Y-%m-%d\n");
}
}
 
Do you want to run it y/n : y
2020-02-02
2021-12-02
2030-03-02
2040-04-02
2050-05-02
2060-06-02
2070-07-02
2080-08-02
2090-09-02
2101-10-12
2110-01-12
2111-11-12
2120-02-12
2121-12-12
2130-03-12
 
Do another one y/n : y
Enter the exact name of the task : Palindrome dates
Enter the language Go/Perl/Python/Wren : Python
 
This is the source code for the first or only runnable program:
 
'''Palindrome dates'''
 
from datetime import datetime
from itertools import chain
 
 
# palinDay :: Int -> [ISO Date]
def palinDay(y):
'''A possibly empty list containing the palindromic
date for the given year, if such a date exists.
'''
s = str(y)
r = s[::-1]
iso = '-'.join([s, r[0:2], r[2:]])
try:
datetime.strptime(iso, '%Y-%m-%d')
return [iso]
except ValueError:
return []
 
 
# --------------------------TEST---------------------------
# main :: IO ()
def main():
'''Count and samples of palindromic dates [2021..9999]
'''
palinDates = list(chain.from_iterable(
map(palinDay, range(2021, 10000))
))
for x in [
'Count of palindromic dates [2021..9999]:',
len(palinDates),
'\nFirst 15:',
'\n'.join(palinDates[0:15]),
'\nLast 15:',
'\n'.join(palinDates[-15:])
]:
print(x)
 
 
# MAIN ---
if __name__ == '__main__':
main()
 
Do you want to run it y/n : y
Count of palindromic dates [2021..9999]:
284
 
First 15:
2021-12-02
2030-03-02
2040-04-02
2050-05-02
2060-06-02
2070-07-02
2080-08-02
2090-09-02
2101-10-12
2110-01-12
2111-11-12
2120-02-12
2121-12-12
2130-03-12
2140-04-12
 
Last 15:
9170-07-19
9180-08-19
9190-09-19
9201-10-29
9210-01-29
9211-11-29
9220-02-29
9221-12-29
9230-03-29
9240-04-29
9250-05-29
9260-06-29
9270-07-29
9280-08-29
9290-09-29
 
Do another one y/n : y
Enter the exact name of the task : Palindrome dates
Enter the language Go/Perl/Python/Wren : Wren
 
This is the source code for the first or only runnable program:
 
import "/fmt" for Fmt
import "/date" for Date
 
var isPalDate = Fn.new { |date|
date = date.format(Date.rawDate)
return date == date[-1..0]
}
 
Date.default = Date.isoDate
System.print("The next 15 palindromic dates in yyyy-mm-dd format after 2020-02-02 are:")
var date = Date.new(2020, 2, 2)
var count = 0
while (count < 15) {
date = date.addDays(1)
if (isPalDate.call(date)) {
System.print(date)
count = count + 1
}
}
 
Do you want to run it y/n : y
The next 15 palindromic dates in yyyy-mm-dd format after 2020-02-02 are:
2021-12-02
2030-03-02
2040-04-02
2050-05-02
2060-06-02
2070-07-02
2080-08-02
2090-09-02
2101-10-12
2110-01-12
2111-11-12
2120-02-12
2121-12-12
2130-03-12
2140-04-12
 
Do another one y/n : y
Enter the exact name of the task : Deceptive numbers
Enter the language Go/Perl/Python/Wren : Wren
 
This is the source code for the first or only runnable program:
 
/* deceptive_numbers.wren */
 
import "./gmp" for Mpz
import "./math" for Int
 
var count = 0
var limit = 25
var n = 17
var repunit = Mpz.from(1111111111111111)
var deceptive = []
while (count < limit) {
if (!Int.isPrime(n) && n % 3 != 0 && n % 5 != 0) {
if (repunit.isDivisibleUi(n)) {
deceptive.add(n)
count = count + 1
}
}
n = n + 2
repunit.mul(100).add(11)
}
System.print("The first %(limit) deceptive numbers are:")
System.print(deceptive)
 
Do you want to run it y/n : y
The first 25 deceptive numbers are:
[91, 259, 451, 481, 703, 1729, 2821, 2981, 3367, 4141, 4187, 5461, 6533, 6541, 6601, 7471, 7777, 8149, 8401, 8911, 10001, 11111, 12403, 13981, 14701]
 
Do another one y/n : n
</pre>
9,476

edits