-
Notifications
You must be signed in to change notification settings - Fork 1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Talk #1
Comments
That's brilliant! Many thanks for creating this repo. I've made changes to 6 modules in recent days, namely: Wren-big The changes include the addition of complex matrices, formatting support for complex numbers and a bag class. I wonder if I could ask you to update these six modules directly from the RC source code. The existing modules are now feature complete and I've no plans to change any of them again unless bugs surface. So hopefully these will be the last changes for a while apart, of course, from adding new modules to the collection. Thanks again for your efforts here. |
Ok updated the 777 files so far 👍 |
Wow, I hadn't realized that you intended to upload the code for all the RC tasks to the repo as well as the library modules! That's great but it does give us some problems:
Incidentally, I tend to make contributions to RC most days (I'm going to add a couple more tasks after I've posted this) so it's not going to be easy to keep track of task changes but I will make a note of what I do (and anyone else does) from now on and perhaps we can update periodically. |
Ok I added the additional contributors and all affected files changed the license to FDL 1.2 |
Sorry that I managed to mess up the list of 7 cases originally authored by Fusta which I later changed though I've corrected it now. I've been through the affected cases and the following will need correction some time to keep the license position in order: Apply a callback to an array - wrtten solely by Fusta. I agree that where external libraries have been used we should just refer to them in a comment. For the WrenGo cases, it might suffice to do nothing further because the Go 'import' statement makes it clear where the code is coming from. Other than that, I think things should now be as accurate as we can get them. Incidentally, I've noticed that the script seems to be skipping the odd task. I've only looked at the first few letters but Benford's Law, Bitmap/Bresenham's line algorithm and Catalan numbers/Pascal's triangle are missing. The cases are listed in snippets.log though they don't appear for some reason in snippets.makefile. Perhaps you could check this out. Many thanks again for your efforts :) |
Ok added the proper licenses and missing files (maybe with the |
@PureFox48 I have been testing out Wren Go and it seems like a good way of implementing custom functions to the Wren interpreter. Don't know if it would be a good idea creating a custom "Wren CLI" with Wren Go and use it for things outside the limits of Wren CLI. What do you think? Example package main
import (
"fmt"
"io/ioutil"
wren "github.com/crazyinfin8/WrenGo"
)
func main() {
vm := wren.NewVM()
vm.SetModule("main", wren.NewModule(wren.ClassMap{
"MyClass": wren.NewClass(nil, nil, wren.MethodMap{
"static sayHello()": func(vm *wren.VM, parameters []interface{}) (interface{}, error) {
println("Hello from MyClass but from Go")
return nil, nil
},
}),
}))
content, err := ioutil.ReadFile("main.wren")
if err != nil {
}
fmt.Println(string(content))
vm.InterpretString("main", string(content))
} main.wren foreign class MyClass {
foreign static sayHello()
}
MyClass.sayHello() |
Thanks for fixing those problems. It' s probably the presence of the apostrophe that was causing those files to be missed as you surmised. With regard to WrenGo I think it would be feasible to create a custom Wren-CLI with it though it would be a lot of work. The advantage, of course, is that you'd be able to get rid of libuv and use the cross-platform Go standard libraries for file, network, crypto, regex etc. though all these would need to be suitably wrapped so you could use them from Wren. Although I'm a big admirer of Go there are some drawbacks to using it for this kind of work. Whilst it compiles much faster than C/C++, execution speed is not as good - about on a par with the JVM and .NET languages in my experience. Also the runtime is large as it needs to deal with stuff such as garbage collection and co-routines. Consequently executables are large too. However, a bigger concern is WrenGo itself which has a number of issues which I've filed on the repo but have yet to receive a reply. The most serious issue is that it only deals with float32 rather than float64 at present. I think this must be an oversight by the author as I can't think of any obvious reason why this should be so. Anyway the author's commitment to the repo and keeping it up to date has to be in doubt. Having said that, it was the only one of the 3 (?) Wren/Go binders which was up to date and I could get to work. Although I've only used embedding when absolutely necessary on RC (nobody on there wants to be bothered to compile a host program as well as the Wren code!), it's worked fine when I've used it though I think I used C instead on the last one I did. On balance, I think it's better to wait and see what Wren-CLI 0.4.0 has to offer (and intends to offer in future) before embarking on a project such as this. |
Thanks. Yes for this use case is best to rely on WrenCLI and Vanilla Wren Go. |
I'm pleased to say that my reservations about WrenGo were premature as the author has now responded to the issues and fixed a couple of things including the float64 bug. Better still, the whole repo has been updated to Wren 0.4.0- Pre so I'm happy now that it's a viable vehicle for embedding Wren in a Go application. Will be using it more on RC in future :) |
@PureFox48 it seems tau value is wrong https://tauday.com/ it should be 2 times PI https://rosettacode.org/mw/index.php?title=Category_talk:Wren-math&action=edit§ion=1
|
It's not actually wrong. It's just a different usage of the I'll need to check the various modules to see if there is anything else we can remove because it's now been implemented in Wren 0.4.0. I've added a lot of stuff to RC since we last spoke about this and we're now up to 1,104 tasks completed. Three more modules have been added - When Wren-cli 0.4.0 is eventually released (I upgraded to the latest build earlier today), it might be an idea to run your script again to upload the latest versions of everything to keep the two sites synchronized. |
Understood 👍 Quick question. Do you have a zip file with all your code?. You can upload it here as a comment and it would make the update process more easy and quickly. In another comment I'm working on a playground app (and including your libs) to quickly working with Wren and having real time feedback. https://github.com/NinjasCL/wren-playground 💯 |
I'm afraid I don't and it would very difficult to make one from the files I have on my machine. When I started adding Wren snippets to RC, I didn't think they'd have any permanent value to anyone (even myself) and so I've made no attempt to synchronize what's on RC with what's on my machine. The file names will usually be different (I'm lazy so prefer short names), I may have written several solutions for the same task and only posted one of them, I may have edited the RC file direct and not bothered to update my local version and so forth. The only exception to this is the 19 modules where it's important to keep the two copies synchronized. I wonder whether, given the 'shifting sands', the aims of this repo are too ambitious and we should just archive (or even remove altogether) the task solutions and concentrate on the modules? I don't often make changes to the latter and, when I do, I could change the file on the repo at the same time - you wouldn't need to do anything in this regard. As long as the module file contains a link back to its RC page, there will be plenty of examples listed for those interested to get their teeth into. They can simply copy and paste the code for an example from RC. Your Wren-playground looks promising. Are you thinking of supporting DOME stuff as well in that? |
Hello @PureFox48
I don't think so, supporting DOME would require more sophisticated code, as an IDE maybe. I notice that there is this task: https://rosettacode.org/wiki/Nonogram_solver#Wren But I could not find the inverse case, where you have a solved Nonogram and you must show the numbers to solve it. Example
Solution ["C BA CB BB F AE F A B", "AB CA AE GA E C D C"] I searched in Rosetta and is not found there. Would be this be difficult to solve? |
I more or less modified the code but have weird results in big nonograms // from https://rosettacode.org/wiki/Nonogram_solver#Wren
import "./pattern" for Pattern
import "./math" for Nums, Boolean
var p = Pattern.new("/s")
var genSequence // recursive
genSequence = Fn.new { |ones, numZeros|
if (ones.isEmpty) return ["0" * numZeros]
var result = []
var x = 1
while (x < numZeros - ones.count + 2) {
var skipOne = ones.skip(1).toList
for (tail in genSequence.call(skipOne, numZeros - x)) {
result.add("0" * x + ones[0] + tail)
}
x = x + 1
}
return result
}
/* If all the candidates for a row have a value in common for a certain cell,
then it's the only possible outcome, and all the candidates from the
corresponding column need to have that value for that cell too. The ones
that don't, are removed. The same for all columns. It goes back and forth,
until no more candidates can be removed or a list is empty (failure).
*/
var reduce = Fn.new { |a, b|
var countRemoved = 0
for (i in 0...a.count) {
var commonOn = List.filled(b.count, true)
var commonOff = List.filled(b.count, false)
// determine which values all candidates of a[i] have in common
for (candidate in a[i]) {
for (i in 0...b.count) {
commonOn[i] = Boolean.and(commonOn[i], candidate[i])
commonOff[i] = Boolean.or(commonOff[i], candidate[i])
}
}
// remove from b[j] all candidates that don't share the forced values
for (j in 0...b.count) {
var fi = i
var fj = j
var removals = false
b[j].each { |cnd|
if ((commonOn[fj] && !cnd[fi]) || (!commonOff[fj] && cnd[fi])) {
b[j].remove(cnd)
removals = true
}
}
if (removals) countRemoved = countRemoved + 1
if (b[j].isEmpty) return -1
}
}
return countRemoved
}
var reduceMutual = Fn.new { |cols, rows|
var countRemoved1 = reduce.call(cols, rows)
if (countRemoved1 == -1) return -1
var countRemoved2 = reduce.call(rows, cols)
if (countRemoved2 == -1) return -1
return countRemoved1 + countRemoved2
}
// collect all possible solutions for the given clues
var getCandidates = Fn.new { |data, len|
var result = []
for (s in data) {
var lst = []
var a = s.bytes
var sumChars = Nums.sum(a.map { |b| b - 64 })
var prep = a.map { |b| "1" * (b - 64) }.toList
for (r in genSequence.call(prep, len - sumChars + 1)) {
var bits = r[1..-1].bytes
var len = bits.count
if (len % 64 != 0) len = (len/64).ceil * 64
var bitset = List.filled(len, false)
for (i in 0...bits.count.min(bitset.count)) bitset[i] = bits[i] == 49
lst.add(bitset)
}
result.add(lst)
}
return result
}
var lettersToNumbers = Fn.new{|data|
var result = []
for (s in data) {
result.add(s.bytes.map{|char| char - 64}.toList)
}
return result
}
var newPuzzle = Fn.new { |data|
var rowData = p.splitAll(data[0])
var colData = p.splitAll(data[1])
var rows_numbers = lettersToNumbers.call(rowData)
var cols_numbers = lettersToNumbers.call(colData)
var rows = getCandidates.call(rowData, colData.count)
var cols = getCandidates.call(colData, rowData.count)
while (true) {
var numChanged = reduceMutual.call(cols, rows)
if (numChanged == -1) {
System.print("No solution")
return
}
if (numChanged <= 0) break
}
var count = 0
for (row in rows) {
for (i in 0...cols.count) {
System.write(row[0][i] ? "■ " : ". ")
}
// Print Rows
for (number in rows_numbers[count]) {
System.write(number.toString + " ")
}
System.print()
count = count + 1
}
var max_rows = rows.count
var max_cols = 0
for(col in cols_numbers) {
if (col.count >= max_cols) {
max_cols = col.count
}
}
for(index in 0...max_cols) {
for(col in cols_numbers) {
count = count + 1
if (index < col.count) {
System.write(col[index].toString + " ")
}
}
System.print()
}
}
/*
// Example
var p1 = ["C BA CB BB F AE F A B", "AB CA AE GA E C D C"]
var p2 = [
"F CAC ACAC CN AAA AABB EBB EAA ECCC HCCC",
"D D AE CD AE A DA BBB CC AAB BAA AAB DA AAB AAA BAB AAA CD BBA DA"
]
var p3 = [
"CA BDA ACC BD CCAC CBBAC BBBBB BAABAA ABAD AABB BBH " +
"BBBD ABBAAA CCEA AACAAB BCACC ACBH DCH ADBE ADBB DBE ECE DAA DB CC",
"BC CAC CBAB BDD CDBDE BEBDF ADCDFA DCCFB DBCFC ABDBA BBF AAF BADB DBF " +
"AAAAD BDG CEF CBDB BBB FC"
]
var p4 = [
"E BCB BEA BH BEK AABAF ABAC BAA BFB OD JH BADCF Q Q R AN AAN EI H G",
"E CB BAB AAA AAA AC BB ACC ACCA AGB AIA AJ AJ " +
"ACE AH BAF CAG DAG FAH FJ GJ ADK ABK BL CM"
]
for (puzzleData in [p1, p2, p3, p4]) newPuzzle.call(puzzleData)
*/
|
I can't say I remember much about that particular task but, if you want to round-trip the results, this seems to be working OK. Note that I've imported fmt.wren to get the column counts to line up properly. import "./pattern" for Pattern
import "./math" for Nums, Boolean
import "./fmt" for Fmt
var p = Pattern.new("/s")
var genSequence // recursive
genSequence = Fn.new { |ones, numZeros|
if (ones.isEmpty) return ["0" * numZeros]
var result = []
var x = 1
while (x < numZeros - ones.count + 2) {
var skipOne = ones.skip(1).toList
for (tail in genSequence.call(skipOne, numZeros - x)) {
result.add("0" * x + ones[0] + tail)
}
x = x + 1
}
return result
}
/* If all the candidates for a row have a value in common for a certain cell,
then it's the only possible outcome, and all the candidates from the
corresponding column need to have that value for that cell too. The ones
that don't, are removed. The same for all columns. It goes back and forth,
until no more candidates can be removed or a list is empty (failure).
*/
var reduce = Fn.new { |a, b|
var countRemoved = 0
for (i in 0...a.count) {
var commonOn = List.filled(b.count, true)
var commonOff = List.filled(b.count, false)
// determine which values all candidates of a[i] have in common
for (candidate in a[i]) {
for (i in 0...b.count) {
commonOn[i] = Boolean.and(commonOn[i], candidate[i])
commonOff[i] = Boolean.or(commonOff[i], candidate[i])
}
}
// remove from b[j] all candidates that don't share the forced values
for (j in 0...b.count) {
var fi = i
var fj = j
var removals = false
b[j].each { |cnd|
if ((commonOn[fj] && !cnd[fi]) || (!commonOff[fj] && cnd[fi])) {
b[j].remove(cnd)
removals = true
}
}
if (removals) countRemoved = countRemoved + 1
if (b[j].isEmpty) return -1
}
}
return countRemoved
}
var reduceMutual = Fn.new { |cols, rows|
var countRemoved1 = reduce.call(cols, rows)
if (countRemoved1 == -1) return -1
var countRemoved2 = reduce.call(rows, cols)
if (countRemoved2 == -1) return -1
return countRemoved1 + countRemoved2
}
// collect all possible solutions for the given clues
var getCandidates = Fn.new { |data, len|
var result = []
for (s in data) {
var lst = []
var a = s.bytes
var sumChars = Nums.sum(a.map { |b| b - 64 })
var prep = a.map { |b| "1" * (b - 64) }.toList
for (r in genSequence.call(prep, len - sumChars + 1)) {
var bits = r[1..-1].bytes
var len = bits.count
if (len % 64 != 0) len = (len/64).ceil * 64
var bitset = List.filled(len, false)
for (i in 0...bits.count.min(bitset.count)) bitset[i] = bits[i] == 49
lst.add(bitset)
}
result.add(lst)
}
return result
}
var newPuzzle = Fn.new { |data|
var rowData = p.splitAll(data[0])
var colData = p.splitAll(data[1])
var rows = getCandidates.call(rowData, colData.count)
var cols = getCandidates.call(colData, rowData.count)
while (true) {
var numChanged = reduceMutual.call(cols, rows)
if (numChanged == -1) {
System.print("No solution")
return
}
if (numChanged <= 0) break
}
var rowCounts = []
var colCounts = []
for (r in 0...rows.count) {
var rowCount = []
var count = 0
var row = rows[r]
for (c in 0...cols.count) {
if (row[0][c]) {
count = count + 1
} else if (count > 0) {
rowCount.add(count)
count = 0
}
}
if (count > 0) rowCount.add(count)
rowCounts.add(rowCount)
}
for (c in 0...cols.count) {
var colCount = []
var count = 0
for (r in 0...rows.count) {
var row = rows[r]
if (row[0][c]) {
count = count + 1
} else if (count > 0) {
colCount.add(count)
count = 0
}
}
if (count > 0) colCount.add(count)
colCounts.add(colCount)
}
var maxColCount = 0
for (cc in colCounts) {
if (cc.count > maxColCount) maxColCount = cc.count
}
for (r in 0...rows.count) {
var row = rows[r]
for (c in 0...cols.count) {
System.write(row[0][c] ? " # " : " . ")
}
for (rc in 0...rowCounts[r].count) {
System.write(" %(rowCounts[r][rc])")
}
System.print()
}
for (i in 1..maxColCount) {
for (cc in colCounts) {
if (i <= cc.count) Fmt.write("$2d ", cc[i-1]) else System.write(" ")
}
System.print()
}
System.print()
}
var p1 = ["C BA CB BB F AE F A B", "AB CA AE GA E C D C"]
var p2 = [
"F CAC ACAC CN AAA AABB EBB EAA ECCC HCCC",
"D D AE CD AE A DA BBB CC AAB BAA AAB DA AAB AAA BAB AAA CD BBA DA"
]
var p3 = [
"CA BDA ACC BD CCAC CBBAC BBBBB BAABAA ABAD AABB BBH " +
"BBBD ABBAAA CCEA AACAAB BCACC ACBH DCH ADBE ADBB DBE ECE DAA DB CC",
"BC CAC CBAB BDD CDBDE BEBDF ADCDFA DCCFB DBCFC ABDBA BBF AAF BADB DBF " +
"AAAAD BDG CEF CBDB BBB FC"
]
var p4 = [
"E BCB BEA BH BEK AABAF ABAC BAA BFB OD JH BADCF Q Q R AN AAN EI H G",
"E CB BAB AAA AAA AC BB ACC ACCA AGB AIA AJ AJ " +
"ACE AH BAF CAG DAG FAH FJ GJ ADK ABK BL CM"
]
for (puzzleData in [p1, p2, p3, p4]) newPuzzle.call(puzzleData)
|
Thanks 💯 |
Incidentally, if you want to recover the letters we started with rather than the corresponding numbers, fmt.write has a '$c" verb which converts from a numeric codepoint to its unicode character and saves you having to write your own routine to do this. So, if we replace the 'newPuzzle' function in the previous version with the following: var newPuzzle = Fn.new { |data|
var rowData = p.splitAll(data[0])
var colData = p.splitAll(data[1])
var rows = getCandidates.call(rowData, colData.count)
var cols = getCandidates.call(colData, rowData.count)
while (true) {
var numChanged = reduceMutual.call(cols, rows)
if (numChanged == -1) {
System.print("No solution")
return
}
if (numChanged <= 0) break
}
var rowCounts = []
var colCounts = []
for (r in 0...rows.count) {
var rowCount = []
var count = 0
var row = rows[r]
for (c in 0...cols.count) {
if (row[0][c]) {
count = count + 1
} else if (count > 0) {
rowCount.add(count)
count = 0
}
}
if (count > 0) rowCount.add(count)
rowCounts.add(rowCount)
}
for (c in 0...cols.count) {
var colCount = []
var count = 0
for (r in 0...rows.count) {
var row = rows[r]
if (row[0][c]) {
count = count + 1
} else if (count > 0) {
colCount.add(count)
count = 0
}
}
if (count > 0) colCount.add(count)
colCounts.add(colCount)
}
var maxColCount = 0
for (cc in colCounts) {
if (cc.count > maxColCount) maxColCount = cc.count
}
for (r in 0...rows.count) {
var row = rows[r]
for (c in 0...cols.count) {
System.write(row[0][c] ? "# " : ". ")
}
for (rc in 0...rowCounts[r].count) {
Fmt.write("$c", rowCounts[r][rc] + 64)
}
System.print()
}
for (i in 1..maxColCount) {
for (cc in colCounts) {
if (i <= cc.count) Fmt.write("$c ", cc[i-1] + 64) else System.write(" ")
}
System.print()
}
System.print()
} we now get:
|
Hello,
@PureFox48
I have made this repository to archive the Rosetta Wren code.
Please, would you kindly provide a zip file (attached here) with all the modules and code available so far?. If that's not possible it's ok and I will extract the data directly from Rosseta's page.
I would greatly appreciate it if you could update this issue whenever is possible to update the files.
Thank you very much for your kindness and awesome labor at creating Wren examples and code.
The text was updated successfully, but these errors were encountered: