Euclidean rhythm: Difference between revisions

Added C++.
m (→‎{{header|RPL}}: improved code a little bit)
(Added C++.)
 
(4 intermediate revisions by 3 users not shown)
Line 17:
* At this point, we can continue the algorithm until only one form remains, but notice that one of the groups has only one element [100], so the algorithm can actually terminate right here and output the concatenation 1001010010100.
 
 
=={{header|ALGOL 68}}==
<syntaxhighlight lang="algol68">
BEGIN # Euclidean Rhythm #
 
# returns the Euclidean rhythm string generated by m and n #
# 0 < m < n must be true #
PROC e rhythm = ( INT m, n )STRING:
BEGIN
[ 1 : n ]STRING r;
# the rhythm string is n elements, initially the first m are #
# set to "1" and the remainder set to "0" #
# the first part is defined by a start and a end and the #
# second part by b start and b end #
FOR i TO m DO r[ i ] := "1" OD;
FOR i FROM m + 1 TO n DO r[ i ] := "0" OD;
INT a start := 1, a end := m;
INT b start := m + 1, b end := n;
# the b elements are appended to the a elements and removed #
# until either a or b or both have less than two elements left #
WHILE a end > a start # at least two elements in a #
AND b end > b start # at least two elements in b #
DO
INT a pos := a start, b pos := b start;
WHILE a pos <= a end AND b pos <= b end DO
r[ a pos ] +:= r[ b pos ];
a pos +:= 1;
b pos +:= 1
OD;
IF b pos < b end THEN
# 2 or more unused elements left in b #
b start := b pos
ELSE
# nothing left in b - use the remains of a #
b start := a pos;
b end := a end;
a end := a pos - 1
FI
OD;
STRING result := "";
FOR i FROM a start TO a end DO result +:= r[ i ] OD;
FOR i FROM b start TO b end DO result +:= r[ i ] OD;
result
END # e rhythm # ;
 
print( ( e rhythm( 5, 13 ), newline ) ); # task test case #
print( ( e rhythm( 3, 8 ), newline ) ) # JaveScriipt test case #
 
END
</syntaxhighlight>
{{out}}
<pre>
1001010010100
10010010
</pre>
 
=={{header|Asymptote}}==
<syntaxhighlight lang="Asymptote">int m = 5;
int n = 13;
 
string r[] = new string[n];
int a_pio = 1, a_fin = m;
int b_pio = m + 1, b_fin = n;
int a_pos, b_pos;
 
for (int i = 1; i <= m; ++i)
r[i] = "1";
for (int i = m + 1; i <= n; ++i)
r[i] = "0";
 
while (a_fin > a_pio && b_fin > b_pio) {
a_pos = a_pio;
b_pos = b_pio;
while (a_pos <= a_fin && b_pos <= b_fin) {
r[a_pos] += r[b_pos];
++a_pos;
++b_pos;
}
if (b_pos < b_fin)
b_pio = b_pos;
else {
b_pio = a_pos;
b_fin = a_fin;
a_fin = a_pos - 1;
}
}
 
string result = "";
for (int i = a_pio; i <= a_fin; ++i)
result += r[i];
for (int i = b_pio; i <= b_fin; ++i)
result += r[i];
 
write(result);</syntaxhighlight>
{{out}}
<pre>10010010</pre>
 
=={{header|BASIC}}==
==={{header|BASIC256}}===
{{trans|FreeBASIC}}
<syntaxhighlight lang="vbnet">arraybase 1
call euclideanrhythm(5, 13)
call euclideanrhythm(3, 8)
end
 
subroutine euclideanrhythm (m,n)
dim r$(n)
a_pio = 1
a_fin = m
b_pio = m+1
b_fin = n
for i = 1 to m
r$[i] = "1"
next i
for i = m+1 to n
r$[i] = "0"
next i
while a_fin > a_pio and b_fin > b_pio
a_pos = a_pio
b_pos = b_pio
while a_pos <= a_fin and b_pos <= b_fin
r$[a_pos] = r$[a_pos] & r$[b_pos]
a_pos = a_pos+1
b_pos = b_pos+1
end while
if b_pos < b_fin then
b_pio = b_pos
else
b_pio = a_pos
b_fin = a_fin
a_fin = a_pos-1
end if
end while
result$ = ""
for i = a_pio to a_fin
result$ = result$ & r$[i]
next i
for i = b_pio to b_fin
result$ = result$ & r$[i]
next i
print result$
end subroutine</syntaxhighlight>
{{out}}
<pre>Same as FreeBASIC entry.</pre>
 
==={{header|Chipmunk Basic}}===
{{trans|FreeBASIC}}
{{works with|Chipmunk Basic|3.6.4}}
<syntaxhighlight lang="vbnet">100 sub euclideanrhythm(m,n)
110 dim r$(n)
120 apio = 1
130 afin = m
140 bpio = m+1
150 bfin = n
160 for i = 1 to m
170 r$(i) = "1"
180 next i
190 for i = m+1 to n
200 r$(i) = "0"
210 next i
220 while afin > apio and bfin > bpio
230 apos = apio
240 bpos = bpio
250 while apos <= afin and bpos <= bfin
260 r$(apos) = r$(apos)+r$(bpos)
270 apos = apos+1
280 bpos = bpos+1
290 wend
300 if bpos < bfin then
310 bpio = bpos
320 else
330 bpio = apos
340 bfin = afin
350 afin = apos-1
360 endif
370 wend
380 result$ = ""
390 for i = apio to afin
400 result$ = result$+r$(i)
410 next i
420 for i = bpio to bfin
430 result$ = result$+r$(i)
440 next i
450 print result$
460 end sub
470 euclideanrhythm(5,13)
480 euclideanrhythm(3,8)
490 end</syntaxhighlight>
<pre>Same as FreeBASIC entry.</pre>
 
==={{header|FreeBASIC}}===
{{trans|ALGOL 68}}
<syntaxhighlight lang="vbnet">Sub EuclideanRhythm (m As Integer, n As Integer)
'Devuelve la cadena de ritmo euclidiano generada por m y n
'0 < m < n debe ser verdadero
Dim As String r(n)
Dim As Integer a_pio = 1, a_fin = m
Dim As Integer b_pio = m + 1, b_fin = n
Dim As Integer a_pos, b_pos
Dim As Integer i
'La cadena rítmica r() tiene n elementos, inicialmente los primeros m
'se establecen en "1" y el resto en "0". La primera parte se define por
'a_inicio y a_final y la segunda parte por b_inicio y b_final
For i = 1 To m
r(i) = "1"
Next i
For i = m + 1 To n
r(i) = "0"
Next i
'Los elementos b se añaden a los elementos a y se eliminan
'hasta que a o b o ambos tienen menos de dos elementos
While a_fin > a_pio And _ 'al menos dos elementos en a
b_fin > b_pio 'al menos dos elementos en b
a_pos = a_pio
b_pos = b_pio
While a_pos <= a_fin And b_pos <= b_fin
r(a_pos) += r(b_pos)
a_pos += 1
b_pos += 1
Wend
If b_pos < b_fin Then '2 o más elementos no utilizados quedan en b
b_pio = b_pos
Else 'no queda nada en b - usa los restos de a
b_pio = a_pos
b_fin = a_fin
a_fin = a_pos - 1
End If
Wend
Dim As String result = ""
For i = a_pio To a_fin
result += r(i)
Next i
For i = b_pio To b_fin
result += r(i)
Next i
Print result
End Sub
 
EuclideanRhythm(5, 13) 'caso de prueba de la tarea
EuclideanRhythm(3, 8) 'caso de prueba de JavaScript
 
Sleep</syntaxhighlight>
{{out}}
<pre>Same as ALGOL 68 entry.</pre>
 
==={{header|Gambas}}===
{{trans|FreeBASIC}}
<syntaxhighlight lang="vbnet">Sub EuclideanRhythm(m As Integer, n As Integer)
 
Dim r As New String[]
Dim a_pio As Integer = 1, a_fin As Integer = m
Dim b_pio As Integer = m + 1, b_fin As Integer = n
Dim a_pos As Integer, b_pos As Integer, i As Integer
For i = 0 To m
r.Add("1")
Next
For i = m + 1 To n
r.Add("0")
Next
While a_fin > a_pio And b_fin > b_pio
a_pos = a_pio
b_pos = b_pio
While a_pos <= a_fin And b_pos <= b_fin
r[a_pos] &= r[b_pos]
a_pos += 1
b_pos += 1
Wend
If b_pos < b_fin Then
b_pio = b_pos
Else
b_pio = a_pos
b_fin = a_fin
a_fin = a_pos - 1
End If
Wend
Dim result As String = ""
For i = a_pio To a_fin
result &= r[i]
Next
For i = b_pio To b_fin
result &= r[i]
Next
Print result
 
End Sub
 
Public Sub Main()
EuclideanRhythm(5, 13) 'caso de prueba de la tarea
EuclideanRhythm(3, 8) 'caso de prueba de JavaScript
End</syntaxhighlight>
{{out}}
<pre>Same as FreeBASIC entry.</pre>
 
==={{header|PureBasic}}===
{{trans|FreeBASIC}}
<syntaxhighlight lang="purebasic">Procedure EuclideanRhythm(m, n)
Dim r.s(n)
Protected.i a_pio = 1, a_fin = m
Protected.i b_pio = m + 1, b_fin = n
Protected.i a_pos, b_pos, i
For i = 1 To m
r(i) = "1"
Next
For i = m + 1 To n
r(i) = "0"
Next
While a_fin > a_pio And b_fin > b_pio
a_pos = a_pio
b_pos = b_pio
While a_pos <= a_fin And b_pos <= b_fin
r(a_pos) + r(b_pos)
a_pos + 1
b_pos + 1
Wend
If b_pos < b_fin
b_pio = b_pos
Else
b_pio = a_pos
b_fin = a_fin
a_fin = a_pos - 1
EndIf
Wend
Protected.s result = ""
For i = a_pio To a_fin
result + r(i)
Next
For i = b_pio To b_fin
result + r(i)
Next
PrintN(result)
EndProcedure
 
OpenConsole()
EuclideanRhythm(5, 13)
EuclideanRhythm(3, 8)
Input()
CloseConsole()</syntaxhighlight>
{{out}}
<pre>Same as FreeBASIC entry.</pre>
 
==={{header|QBasic}}===
{{trans|FreeBASIC}}
{{works with|QBasic|1.1}}
{{works with|QuickBasic|4.5}}
<syntaxhighlight lang="qbasic">SUB EuclideanRhythm (m, n)
DIM r$(n)
apio = 1
afin = m
bpio = m + 1
bfin = n
FOR i = 1 TO m
r$(i) = "1"
NEXT i
FOR i = m + 1 TO n
r$(i) = "0"
NEXT i
WHILE afin > apio AND bfin > bpio
apos = apio
bpos = bpio
WHILE apos <= afin AND bpos <= bfin
r$(apos) = r$(apos) + r$(bpos)
apos = apos + 1
bpos = bpos + 1
WEND
IF bpos < bfin THEN
bpio = bpos
ELSE
bpio = apos
bfin = afin
afin = apos - 1
END IF
WEND
result$ = ""
FOR i = apio TO afin
result$ = result$ + r$(i)
NEXT i
FOR i = bpio TO bfin
result$ = result$ + r$(i)
NEXT i
PRINT result$
END SUB
 
CALL EuclideanRhythm(5, 13)
CALL EuclideanRhythm(3, 8)</syntaxhighlight>
{{out}}
<pre>Same as FreeBASIC entry.</pre>
 
==={{header|True BASIC}}===
{{trans|FreeBASIC}}
<syntaxhighlight lang="qbasic">SUB euclideanrhythm (m,n)
DIM r$(0)
MAT redim r$(n)
LET a_pio = 1
LET a_fin = m
LET b_pio = m+1
LET b_fin = n
FOR i = 1 to m
LET r$(i) = "1"
NEXT i
FOR i = m+1 to n
LET r$(i) = "0"
NEXT i
DO while a_fin > a_pio and b_fin > b_pio
LET a_pos = a_pio
LET b_pos = b_pio
DO while a_pos <= a_fin and b_pos <= b_fin
LET r$(a_pos) = r$(a_pos) & r$(b_pos)
LET a_pos = a_pos+1
LET b_pos = b_pos+1
LOOP
IF b_pos < b_fin then
LET b_pio = b_pos
ELSE
LET b_pio = a_pos
LET b_fin = a_fin
LET a_fin = a_pos-1
END IF
LOOP
LET result$ = ""
FOR i = a_pio to a_fin
LET result$ = result$ & r$(i)
NEXT i
FOR i = b_pio to b_fin
LET result$ = result$ & r$(i)
NEXT i
PRINT result$
END SUB
 
CALL euclideanrhythm(5, 13)
CALL euclideanrhythm(3, 8)
END</syntaxhighlight>
{{out}}
<pre>Same as FreeBASIC entry.</pre>
 
==={{header|Yabasic}}===
{{trans|FreeBASIC}}
<syntaxhighlight lang="vbnet">euclideanrhythm(5, 13)
euclideanrhythm(3, 8)
end
 
sub euclideanrhythm (m,n)
dim r$(n)
apio = 1
afin = m
bpio = m+1
bfin = n
for i = 1 to m
r$(i) = "1"
next i
for i = m+1 to n
r$(i) = "0"
next i
while afin > apio and bfin > bpio
apos = apio
bpos = bpio
while apos <= afin and bpos <= bfin
r$(apos) = r$(apos) + r$(bpos)
apos = apos+1
bpos = bpos+1
wend
if bpos < bfin then
bpio = bpos
else
bpio = apos
bfin = afin
afin = apos-1
fi
wend
result$ = ""
for i = apio to afin
result$ = result$ + r$(i)
next i
for i = bpio to bfin
result$ = result$ + r$(i)
next i
print result$
end sub</syntaxhighlight>
{{out}}
<pre>Same as FreeBASIC entry.</pre>
 
=={{header|C++}}==
{{trans|ALGOL 68}} But the vector <code>r</code> is subscripted from <code>0</code> to <code>n - 1</code>.
<syntaxhighlight lang="cpp">
// Euclidean rhythm
#include <iostream>
#include <string>
#include <vector>
using namespace std;
 
string euclidean_rhythm(const unsigned int m, const unsigned int n)
{
vector<string> r(n);
unsigned int a_start = 0, a_end = m - 1, b_start = m, b_end = n - 1;
for (unsigned int i = 0; i < m; i++)
r[i] = "1";
for (unsigned int i = m; i < n; i++)
r[i] = "0";
while (a_end > a_start && b_end > b_start)
{
unsigned int a_pos = a_start, b_pos = b_start;
while (a_pos <= a_end && b_pos <= b_end)
{
r[a_pos] += r[b_pos];
a_pos++;
b_pos++;
}
if (b_pos <= b_end)
b_start = b_pos;
else
{
b_start = a_pos;
b_end = a_end;
a_end = a_pos - 1;
}
}
string result = "";
for (unsigned int i = a_start; i <= a_end; i++)
result += r[i];
for (unsigned int i = b_start; i <= b_end; i++)
result += r[i];
return result;
}
 
int main()
{
cout << euclidean_rhythm(5, 13) << "\n";
cout << euclidean_rhythm(3, 8) << "\n";
}
</syntaxhighlight>
{{out}}
<pre>
1001010010100
10010010
</pre>
 
=={{header|C#}}==
Line 86 ⟶ 629:
 
</pre>
 
 
 
=={{header|Dart}}==
Line 875 ⟶ 1,416:
<pre>
1001010010100
</pre>
 
=={{header|Sidef}}==
{{trans|Ruby}}
<syntaxhighlight lang="ruby">func e(k, n) {
var s = (^n -> map { |i| i < k ? [1] : [0] })
 
var d = (n - k)
n = max(k, d)
k = min(k, d)
var z = d
 
while ((z > 0) || (k > 1)) {
k.times { |i|
s[i] += s[-1 - i]
}
s = s.first(-k)
z -= k
d = (n - k)
n = max(k, d)
k = min(k, d)
}
 
s.flat.join
}
 
say e(5, 13)</syntaxhighlight>
{{out}}
<pre>
1001010010100
</pre>
 
511

edits