Amb: Difference between revisions

6,388 bytes added ,  18 days ago
m (→‎{{header|J}}: more compact presentation)
(27 intermediate revisions by 14 users not shown)
Line 358:
}</syntaxhighlight>
 
=={{header|BaConBASIC}}==
==={{header|BaCon}}===
This code tries to implement ambsel$() in a generic way. It accepts any amount of string arguments (but at least two). The ambsel$() function generates combinations of the items in the provided arguments using recursion, and sends each combination to a function pointer to verify the requirement. The function pointer can be set to any function.
<syntaxhighlight lang="bacon">DECLARE (*ambassert)() TYPE NUMBER
Line 907 ⟶ 908:
Words 4: (slowly, quickly)
Solution: (that, thing, grows, slowly)
</pre>
 
===Without external libraries===
<syntaxhighlight lang="c++">
#include <functional>
#include <iostream>
#include <numeric>
#include <string>
#include <vector>
 
std::string join(const std::string& delimiter, const std::vector<std::string>& list) {
return list.empty() ? "" : std::accumulate(++list.begin(), list.end(), list[0],
[delimiter](auto& a, auto& b) { return a + delimiter + b; });
}
 
std::vector<std::string> amb(std::function<bool(std::string&, std::string&)> func,
std::vector<std::vector<std::string>> options, std::string previous) {
 
if ( options.empty() ) {
return std::vector<std::string>();
}
 
for ( std::string& option : options.front() ) {
if ( ! previous.empty() && ! func(previous, option) ) {
continue;
}
 
if ( options.size() == 1 ) {
return std::vector<std::string>(1, option);
}
 
std::vector<std::vector<std::string>> next_options(options.begin() + 1, options.end());
std::vector<std::string> result = amb(func, next_options, option);
 
if ( ! result.empty() ) {
result.emplace(result.begin(), option);
return result;
}
}
 
return std::vector<std::string>();
 
}
 
std::string Amb(std::vector<std::vector<std::string>> options) {
std::function<bool(std::string, std::string)> continues =
[](std::string before, std::string after) { return before.back() == after.front(); };
 
std::vector<std::string> amb_result = amb(continues, options, "");
 
return ( amb_result.empty() ) ? "No match found" : join(" ", amb_result);
}
 
int main() {
std::vector<std::vector<std::string>> words = { { "the", "that", "a" },
{ "frog", "elephant", "thing" },
{ "walked", "treaded", "grows" },
{ "slowly", "quickly" } };
 
std::cout << Amb(words) << std::endl;
}
</syntaxhighlight>
{{ out }}
<pre>
that thing grows slowly
</pre>
 
Line 1,057 ⟶ 1,123:
===== 2. Program =====
 
<syntaxhighlight lang="lisp">;; 22.11.11
;; 22.11.18 Ajout macro
 
(defvar *stack* nil)
Line 1,063 ⟶ 1,130:
 
(defun ambnew ()
(setf *stack* nil)
(setf *assert* t))
 
(defundefmacro ambsel (symbolname domain)
`(progn (defparameter ,name (first ,domain))
(pushnew symbol *stack*)
(pushnew ',name *stack*)
(set symbol (first domain))
(setf (get symbol',name 'domain) ,domain)))
 
(defun ambassert (assert)
Line 1,076 ⟶ 1,143:
t
(labels ((probe (&optional (stack *stack*))
(let* ((symbolname (first stack))
(domain (get symbolname 'domain)))
(dolist (value domain)
(set symbolname value)
(cond ((eval *assert*) (return t))
((probe (rest stack)) (return t)))))))
Line 1,091 ⟶ 1,158:
===== 4. Execution =====
 
<pre>(defvarambsel *a* nil'("the" "that" "a"))
(ambsel *b* '("frog" "elephant" "thing"))
(defvar *b* nil)
(ambsel *c* '("walked" "treaded" "grows"))
(defvar *c* nil)
(defvarambsel *d* nil'("slowly" "quickly"))
(ambsel '*a* '("the" "that" "a"))
(ambsel '*b* '("frog" "elephant" "thing"))
(ambsel '*c* '("walked" "treaded" "grows"))
(ambsel '*d* '("slowly" "quickly"))
(ambassert '(match *a* *b*))
(ambassert '(match *b* *c*))
(ambassert '(match *c* *d*))
(format t "~a ~a ~a ~a~%"list *a* *b* *c* *d*)</pre>
 
{{out}}
<pre>("that" "thing" "grows" "slowly")</pre>
<pre>T
that thing grows slowly</pre>
 
===== 5. Magic square =====
 
''Complexity : 0(n<sup>2</sup>)''
 
<syntaxhighlight lang="lisp">(defun magic-square (a b c d e f g h i)
(and (/= a b c d e f g h i)
(= (+ a b c)
(+ d e f)
(+ g h i)
(+ a d g)
(+ b e h)
(+ c f i)
(+ a e i)
(+ c e g))))</syntaxhighlight>
 
<pre>(ambsel *a* '(1 2 3 4 5 6 7 8 9))
(ambsel *b* '(1 2 3 4 5 6 7 8 9))
(ambsel *c* '(1 2 3 4 5 6 7 8 9))
(ambsel *d* '(1 2 3 4 5 6 7 8 9))
(ambsel *e* '(1 2 3 4 5 6 7 8 9))
(ambsel *f* '(1 2 3 4 5 6 7 8 9))
(ambsel *g* '(1 2 3 4 5 6 7 8 9))
(ambsel *h* '(1 2 3 4 5 6 7 8 9))
(ambsel *i* '(1 2 3 4 5 6 7 8 9))
(ambassert '(magic-square *a* *b* *c* *d* *e* *f* *g* *h* *i*))
(list *a* *b* *c*) (list *d* *e* *f*) (list *g* *h* *i*)</pre>
 
{{out}}
<pre>(8 3 4)
(1 5 9)
(6 7 2)</pre>
That's all Folks !
 
Line 1,321 ⟶ 1,414:
 
=={{header|Elena}}==
ELENA 56.0 :
<syntaxhighlight lang="elena">import system'routines;
import extensions;
import extensions'routines;
 
// --- Joinable --
 
joinable(former,later) = (former[former.Length - 1] == later[0]);
Line 1,350 ⟶ 1,445:
}
};
 
// --- AmbValueCollection ---
 
class AmbValueCollection
{
object theCombinator_combinator;
constructor new(params object[] args)
{
theCombinator_combinator := SequentialEnumerator.newload(params args)
}
 
seek(cond)
{
theCombinator_combinator.reset();
 
theCombinator_combinator.seekEach::(v => dispatcher.eval(v,cond))
}
do(f)
{
var result := theCombinator.get()*_combinator;
if (nil != result)
{
Line 1,380 ⟶ 1,477:
}
}
 
// --- ambOperator ---
 
singleton ambOperator
Line 1,386 ⟶ 1,485:
= AmbValueCollection.new(params args);
}
 
// --- Program ---
 
public program()
Line 1,397 ⟶ 1,498:
new object[]{"walked", "treaded", "grows"},
new object[]{"slowly", "quickly"})
.seek::(a,b,c,d => joinable(a,b) && joinable(b,c) && joinable(c,d) )
.do::(a,b,c,d) { console.printLine(a," ",b," ",c," ",d) }
}
catch(Exception e)
{
console.printLine:("AMB is angry")
};
Line 1,896 ⟶ 1,997:
return s
end</syntaxhighlight>
 
=={{header|Insitux}}==
<syntaxhighlight lang="insitux">(function amb op res
(filter #(= res (.. .. op args))
(.. for vec (skip 2 args))))
 
(var safe= @(= (0 args)))
(var predicate (comp vec (map (juxt 0 -1)) flatten (skip 1) (partition 2) (map (.. safe=)) (.. and)))
 
(amb predicate true ["the" "that" "a"] ["frog" "elephant" "thing"] ["walked" "treaded" "grows"] ["slowly" "quickly"])
 
;returns [["that" "thing" "grows" "slowly"]]</syntaxhighlight>
 
=={{header|J}}==
Line 1,930 ⟶ 2,043:
│that│thing│grows│slowly│
└────┴─────┴─────┴──────┘</syntaxhighlight>
 
 
=={{header|Java}}==
<syntaxhighlight lang="java">
 
import java.util.ArrayList;
import java.util.List;
import java.util.function.BiFunction;
import java.util.stream.Collectors;
import java.util.stream.Stream;
 
public final class AmbTask {
 
public static void main(String[] aArgs) {
List<List<String>> words = List.of(
List.of( "the", "that", "a" ),
List.of( "frog", "elephant", "thing" ),
List.of( "walked", "treaded", "grows" ),
List.of( "slowly", "quickly" ) );
 
System.out.println(Amb(words));
}
private static String Amb(List<List<String>> aOptions) {
BiFunction<String, String, Boolean> continues = (before, after) -> before.endsWith(after.substring(0, 1));
List<String> ambResult = amb(continues, aOptions, "");
return ( ambResult.isEmpty() ) ? "No match found" : String.join(" ", ambResult);
}
private static List<String> amb(
BiFunction<String, String, Boolean> aBiFunction, List<List<String>> aOptions, String aPrevious) {
if ( aOptions.isEmpty() ) {
return new ArrayList<String>();
}
 
for ( String option : aOptions.get(0) ) {
if ( ! aPrevious.isEmpty() && ! aBiFunction.apply(aPrevious, option) ) {
continue;
}
if ( aOptions.size() == 1 ) {
return Stream.of(option).collect(Collectors.toList());
}
List<String> result = (ArrayList<String>) amb(aBiFunction, aOptions.subList(1, aOptions.size()), option);
if ( ! result.isEmpty() ) {
result.add(0, option);
return result;
}
}
return new ArrayList<String>();
}
}
</syntaxhighlight>
{{ out }}
<pre>
that thing grows slowly
</pre>
 
=={{header|JavaScript}}==
Line 2,273 ⟶ 2,448:
 
=={{header|langur}}==
{{works with|langur|0.11}}
This would build every valid set, but for the sample data, there's only one.
 
<syntaxhighlight lang="langur">val .wordsets = [
wfw/the that a/,
wfw/frog elephant thing/,
wfw/walked treaded grows/,
wfw/slowly quickly/,
]
 
val .alljoin = ffn(.words) { for[=true] .i of len(.words)-1 {
if last(.words[.i]) != first(.words[.i+1]): break = false
}}
 
# .amb expects 2 or more arguments
val .amb = ffn(...[2 to.. -1] .words) { if(.alljoin(.words): join " ", .words) }
 
writeln join "\n", filter( mapX( .amb, .wordsets...))</syntaxhighlight>
</syntaxhighlight>
 
{{out}}
Line 2,692 ⟶ 2,867:
=ret
}
a=(1, 2, 3)
b=(7, 6, 4, 5)
Line 2,714 ⟶ 2,889:
Print "Small Pythagorean triples problem:"
a=range(1,11)
b=a
z=a
failure=lambda (a, b, z)->{
=not (a^2+b^2=z^2 and b>a)
}
all=amb(Any,failure, a, ba, za)
k=each(all)
while k
Line 2,725 ⟶ 2,898:
Print z#str$()
end while
a=range(1,6)
c=range(0,6)
N=9
failure=lambda N (a, b, c, d, e)->{
=not (a+b+c+d+e=N and a>=b and b>=c and c>=d and d>=e)
}
all=amb(Any,failure, a, a, c, c, c)
k=each(all)
document ret$
while k
z=array(k)
ret$=replace$("+0", " ", z#str$("+"))+" ="+str$(N)+{
}
end while
Sort descending ret$
Print #-2, ret$
clipboard ret$
}
AmbFunction
Line 2,734 ⟶ 2,923:
that thing grows slowly
Small Pythagorean triples problem:
4 3 5
3 4 5
8 6 10
6 8 10
5+4 = 9
5+3+1 = 9
5+2+2 = 9
5+2+1+1 = 9
5+1+1+1+1 = 9
4+4+1 = 9
4+3+2 = 9
4+3+1+1 = 9
4+2+2+1 = 9
4+2+1+1+1 = 9
3+3+3 = 9
3+3+2+1 = 9
3+3+1+1+1 = 9
3+2+2+2 = 9
3+2+2+1+1 = 9
2+2+2+2+1 = 9
</pre>
 
Line 3,183 ⟶ 3,386:
use re 'eval';
 
sub amb :prototype($@) {
my $var = shift;
join ' || ', map { "(?{ $var = '$_' })" } @_;
Line 4,154 ⟶ 4,357:
=={{header|REXX}}==
===version 1===
An assumption was made that equivalent lowercase and uppercase (Latin) letters are considered a match,
<br>although that isn't case here for these words &nbsp; (required by this task).
<syntaxhighlight lang="rexx">/*REXX program demonstrates the Amd operator, choosing a word from each set. */
@.1 = "the that a"
@.2 = "frog elephant thing"
@.3 = "walked treaded grows"
@.4 = "slowly quickly"
@.0 = 4 /*define the number of sets being ised.*/
call Amb 1 /*find all word combinations that works*/
exit /*stick a fork in it, we're all done. */
/*──────────────────────────────────────────────────────────────────────────────────────*/
Amb: procedure expose @.; parse arg # x; arg . u /*ARG uppercases U value. */
if #>@.0 then do; y= word(u, 1) /*Y: is a uppercased U. */
do n=2 to words(u); ?= word(u, n)
if left(?, 1) \== right(y, 1) then return; y= ?
end /*n*/
say strip(x) /*¬show superfluous blanks.*/
end
do j=1 for words(@.#); call Amb #+1 x word(@.#, j) /*gen all combos recursively*/
end /*j*/; return</syntaxhighlight>
{{out|output|text=&nbsp; when using the default internal inputs:}}
<pre>
that thing grows slowly
</pre>
 
===version 2===
<syntaxhighlight lang="rexx"> /* REXX **************************************************************
* 25.08.2013 Walter Pachl derived from PL/I
Line 4,265 ⟶ 4,442:
End
Return</syntaxhighlight>
Output: {{out|output|text=identical to PL/I's i}}
<pre>Input:
the frog walked slowly
that elephant treaded quickly
a thing grows
if trots
 
--> the elephant trots slowly
--> that thing grows slowly
--> if frog grows slowly</pre>
 
===version 2===
An assumption was made that equivalent lowercase and uppercase (Latin) letters are considered a match,
<br>although that isn't case here for these words &nbsp; (required by this task).
<syntaxhighlight lang="rexx">/*REXX program demonstrates the Amd operator, choosing a word from each set. */
@.1 = "the that a"
@.2 = "frog elephant thing"
@.3 = "walked treaded grows"
@.4 = "slowly quickly"
@.0 = 4 /*define the number of sets being ised.*/
call Amb 1 /*find all word combinations that works*/
exit /*stick a fork in it, we're all done. */
/*--------------------------------------------------------------------------------------*/
Amb: procedure expose @.; parse arg # x; arg . u /*ARG uppercases U value. */
if #>@.0 then do; y= word(u, 1) /*Y: is a uppercased U. */
do n=2 to words(u); ?= word(u, n)
if left(?, 1) \== right(y, 1) then return; y= ?
end /*n*/
say strip(x) /*¬show superfluous blanks.*/
end
do j=1 for words(@.#); call Amb #+1 x word(@.#, j) /*gen all combos recursively*/
end /*j*/; return</syntaxhighlight>
{{out|output|text=&nbsp; when using the default internal inputs:}}
<pre>that thing grows slowly</pre>
 
=={{header|Ring}}==
Line 5,078 ⟶ 5,288:
uBasic/4tH has limited support for arrays, so some workarounds are required to make this work.
<syntaxhighlight lang="text"> ' set up the arrays
Push Dup("the"), Dup("that"), Dup("a") : a = FUNC(_Ambsel (0))
Push Dup("frog"), Dup("elephant"), Dup("thing") : b = FUNC(_Ambsel (a))
Push Dup("walked"), Dup("treaded"), Dup("grows") : c = FUNC(_Ambsel (b))
Push Dup("slowly"), Dup("quickly") : f = FUNC(_Ambsel (c))
' we'll reuse variable f ;-)
Proc _Ambassert (_Connect) ' now assert the function required
Line 5,117 ⟶ 5,327:
0 OK, 0:772
</pre>
 
=={{header|VBScript}}==
=====Implementation=====
Line 5,152 ⟶ 5,363:
{{out}}
<pre>
that thing grows slowly
</pre>
 
=={{header|V (Vlang)}}==
<syntaxhighlight lang="Rust">
fn main() {
word_set := [["the", "that", "a"],
["frog", "elephant", "thing"],
["walked", "treaded", "grows"],
["slowly", "quickly"]]
text := amb(word_set)
if text != "" {println("Correct answer is: \n ${text} \n")}
else {println("Failed to find a correct answer.")}
}
 
fn word_check(str_1 string, str_2 string) bool {
if str_1.substr_ni(str_1.len - 1, str_1.len) == str_2.substr_ni(0, 1) {return true}
return false
}
 
fn amb(arrays[][]string) string {
for words_0 in arrays[0] {
for words_1 in arrays[1] {
for words_2 in arrays[2] {
for words_3 in arrays[3] {
if word_check(words_0, words_1) && word_check(words_1, words_2) && word_check(words_2, words_3) {
return "${words_0} ${words_1} ${words_2} ${words_3}"
}
}
}
}
}
return ""
}
</syntaxhighlight>
 
{{out}}
<pre>
Correct answer is:
that thing grows slowly
</pre>
Line 5,158 ⟶ 5,408:
{{trans|Go}}
Based on the 'alternative' version.
<syntaxhighlight lang="ecmascriptwren">var finalRes = []
 
var amb // recursive closure
Line 5,183 ⟶ 5,433:
[ "walked", "treaded", "grows" ],
[ "slowly", "quickly" ]
]
}
 
if (amb.call(wordsets, [])) {
885

edits