Data commit
This commit is contained in:
parent
7387c8f97b
commit
cb5bb5e222
199093 changed files with 3378972 additions and 0 deletions
2
Task/Calkin-Wilf-sequence/00-META.yaml
Normal file
2
Task/Calkin-Wilf-sequence/00-META.yaml
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
---
|
||||
from: http://rosettacode.org/wiki/Calkin-Wilf_sequence
|
||||
34
Task/Calkin-Wilf-sequence/00-TASK.txt
Normal file
34
Task/Calkin-Wilf-sequence/00-TASK.txt
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
The '''Calkin-Wilf sequence''' contains every nonnegative rational number exactly once.
|
||||
|
||||
It can be calculated recursively as follows:
|
||||
|
||||
<big> {{math|a<sub>1</sub>}} = {{math|1}} </big>
|
||||
<big> {{math|a<sub>n+1</sub>}} = {{math|1/(2⌊a<sub>n</sub>⌋+1-a<sub>n</sub>)}} for n > 1 </big>
|
||||
|
||||
|
||||
;Task part 1:
|
||||
* Show on this page terms 1 through 20 of the Calkin-Wilf sequence.
|
||||
|
||||
<br>To avoid floating point error, you may want to use a rational number data type.
|
||||
|
||||
|
||||
It is also possible, given a non-negative rational number, to determine where it appears in the sequence without calculating the sequence. The procedure is to get the continued fraction representation of the rational and use it as the run-length encoding of the binary representation of the term number, beginning from the end of the continued fraction.
|
||||
It only works if the number of terms in the continued fraction is odd- use either of the two equivalent representations to achieve this:
|
||||
|
||||
<big> {{math|[a<sub>0</sub>; a<sub>1</sub>, a<sub>2</sub>, ..., a<sub>n</sub>]}} = {{math|[a<sub>0</sub>; a<sub>1</sub>, a<sub>2</sub> ,..., a<sub>n</sub>-1, 1]}} </big>
|
||||
|
||||
|
||||
;Example:
|
||||
The fraction '''9/4''' has odd continued fraction representation <big> {{math|2; 3, 1}},</big> giving a binary representation of '''100011''',
|
||||
<br>which means '''9/4''' appears as the '''35th''' term of the sequence.
|
||||
|
||||
|
||||
;Task part 2:
|
||||
* Find the position of the number <big>'''<sup>83116</sup>'''<big>'''/'''</big>'''<sub>51639</sub>'''</big> in the Calkin-Wilf sequence.
|
||||
|
||||
|
||||
;See also:
|
||||
* Wikipedia entry: [[wp:Calkin%E2%80%93Wilf_tree|Calkin-Wilf tree]]
|
||||
* [[Continued fraction]]
|
||||
* [[Continued fraction/Arithmetic/Construct from rational number]]
|
||||
<br><br>
|
||||
23
Task/Calkin-Wilf-sequence/11l/calkin-wilf-sequence.11l
Normal file
23
Task/Calkin-Wilf-sequence/11l/calkin-wilf-sequence.11l
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
T CalkinWilf
|
||||
n = 1
|
||||
d = 1
|
||||
|
||||
F ()()
|
||||
V r = (.n, .d)
|
||||
.n = 2 * (.n I/ .d) * .d + .d - .n
|
||||
swap(&.n, &.d)
|
||||
R r
|
||||
|
||||
print(‘The first 20 terms of the Calkwin-Wilf sequence are:’)
|
||||
V cw = CalkinWilf()
|
||||
[String] seq
|
||||
L 20
|
||||
V (n, d) = cw()
|
||||
seq.append(I d == 1 {String(n)} E n‘/’d)
|
||||
print(seq.join(‘, ’))
|
||||
|
||||
cw = CalkinWilf()
|
||||
V index = 1
|
||||
L cw() != (83116, 51639)
|
||||
index++
|
||||
print("\nThe element 83116/51639 is at position "index‘ in the sequence.’)
|
||||
131
Task/Calkin-Wilf-sequence/ALGOL-68/calkin-wilf-sequence.alg
Normal file
131
Task/Calkin-Wilf-sequence/ALGOL-68/calkin-wilf-sequence.alg
Normal file
|
|
@ -0,0 +1,131 @@
|
|||
BEGIN
|
||||
# Show elements 1-20 of the Calkin-Wilf sequence as rational numbers #
|
||||
# also show the position of a specific element in the seuence #
|
||||
# Uses code from the Arithmetic/Rational #
|
||||
# & Continued fraction/Arithmetic/Construct from rational number tasks #
|
||||
|
||||
|
||||
# Code from the Arithmetic/Rational task #
|
||||
# ============================================================== #
|
||||
|
||||
MODE FRAC = STRUCT( INT num #erator#, den #ominator#);
|
||||
|
||||
PROC gcd = (INT a, b) INT: # greatest common divisor #
|
||||
(a = 0 | b |: b = 0 | a |: ABS a > ABS b | gcd(b, a MOD b) | gcd(a, b MOD a));
|
||||
|
||||
PROC lcm = (INT a, b)INT: # least common multiple #
|
||||
a OVER gcd(a, b) * b;
|
||||
|
||||
PRIO // = 9; # higher then the ** operator #
|
||||
OP // = (INT num, den)FRAC: ( # initialise and normalise #
|
||||
INT common = gcd(num, den);
|
||||
IF den < 0 THEN
|
||||
( -num OVER common, -den OVER common)
|
||||
ELSE
|
||||
( num OVER common, den OVER common)
|
||||
FI
|
||||
);
|
||||
|
||||
OP + = (FRAC a, b)FRAC: (
|
||||
INT common = lcm(den OF a, den OF b);
|
||||
FRAC result := ( common OVER den OF a * num OF a + common OVER den OF b * num OF b, common );
|
||||
num OF result//den OF result
|
||||
);
|
||||
|
||||
OP - = (FRAC a, b)FRAC: a + -b,
|
||||
* = (FRAC a, b)FRAC: (
|
||||
INT num = num OF a * num OF b,
|
||||
den = den OF a * den OF b;
|
||||
INT common = gcd(num, den);
|
||||
(num OVER common) // (den OVER common)
|
||||
);
|
||||
|
||||
OP - = (FRAC frac)FRAC: (-num OF frac, den OF frac);
|
||||
|
||||
# ============================================================== #
|
||||
# end code from the Arithmetic/Rational task #
|
||||
|
||||
# code from the Continued fraction/Arithmetic/Construct from rational number task #
|
||||
# ================================================================================#
|
||||
|
||||
# returns the quotient of numerator over denominator and sets #
|
||||
# numerator and denominator to the next values for #
|
||||
# the continued fraction #
|
||||
PROC r2cf = ( REF INT numerator, REF INT denominator )INT:
|
||||
IF denominator = 0
|
||||
THEN 0
|
||||
ELSE INT quotient := numerator OVER denominator;
|
||||
INT prev numerator = numerator;
|
||||
numerator := denominator;
|
||||
denominator := prev numerator MOD denominator;
|
||||
quotient
|
||||
FI # r2cf # ;
|
||||
|
||||
# ====================================================================================#
|
||||
# end code from the Continued fraction/Arithmetic/Construct from rational number task #
|
||||
|
||||
# Additional FRACrelated operators #
|
||||
OP * = ( INT a, FRAC b )FRAC: ( num OF b * a ) // den OF b;
|
||||
OP / = ( FRAC a, b )FRAC: ( num OF a * den OF b ) // ( num OF b * den OF a );
|
||||
OP FLOOR = ( FRAC a )INT: num OF a OVER den OF a;
|
||||
OP + = ( INT a, FRAC b )FRAC: ( a // 1 ) + b;
|
||||
|
||||
FRAC one = 1 // 1;
|
||||
|
||||
# returns the first n elements of the Calkin-Wilf sequence #
|
||||
PROC calkin wilf = ( INT n )[]FRAC:
|
||||
BEGIN
|
||||
[ 1 : n ]FRAC q;
|
||||
IF n > 0 THEN
|
||||
q[ 1 ] := 1 // 1;
|
||||
FOR i FROM 2 TO UPB q DO
|
||||
q[ i ] := one / ( ( 2 * FLOOR q[ i - 1 ] ) + one - q[ i - 1 ] )
|
||||
OD
|
||||
FI;
|
||||
q
|
||||
END # calkin wilf # ;
|
||||
|
||||
# returns the position of a FRAC in the Calkin-Wilf sequence by computing its #
|
||||
# continued fraction representation and converting that to a bit string #
|
||||
# - the position must fit in a 2-bit number #
|
||||
PROC position in calkin wilf sequence = ( FRAC f )INT:
|
||||
IF INT result := 0;
|
||||
[ 1 : 32 ]INT cf; FOR i FROM LWB cf TO UPB cf DO cf[ i ] := 0 OD;
|
||||
INT num := num OF f;
|
||||
INT den := den OF f;
|
||||
INT cf length := 0;
|
||||
FOR i FROM LWB cf WHILE den /= 0 DO
|
||||
cf[ cf length := i ] := r2cf( num, den )
|
||||
OD;
|
||||
NOT ODD cf length
|
||||
THEN # the continued fraction does not have an odd length #
|
||||
-1
|
||||
ELSE # the continued fraction has an odd length so we can compute the seuence length #
|
||||
# build the number by alternating d 1s and 0s where d is the digits of the #
|
||||
# continued fraction, starting at the least significant #
|
||||
INT digit := 1;
|
||||
FOR d pos FROM cf length BY -1 TO 1 DO
|
||||
FOR i TO cf[ d pos ] DO
|
||||
result *:= 2 +:= digit
|
||||
OD;
|
||||
digit := IF digit = 0 THEN 1 ELSE 0 FI
|
||||
OD;
|
||||
result
|
||||
FI # position in calkin wilf sequence # ;
|
||||
|
||||
BEGIN # task #
|
||||
# get and show the first 20 Calkin-Wilf sequence numbers #
|
||||
[]FRAC cw = calkin wilf( 20 );
|
||||
print( ( "The first 20 elements of the Calkin-Wilf sequence are:", newline, " " ) );
|
||||
FOR n FROM LWB cw TO UPB cw DO
|
||||
FRAC sn = cw[ n ];
|
||||
print( ( " ", whole( num OF sn, 0 ), "/", whole( den OF sn, 0 ) ) )
|
||||
OD;
|
||||
print( ( newline ) );
|
||||
# show the position of a specific element in the sequence #
|
||||
print( ( "Position of 83116/51639 in the sequence: "
|
||||
, whole( position in calkin wilf sequence( 83116//51639 ), 0 )
|
||||
)
|
||||
)
|
||||
END
|
||||
END
|
||||
|
|
@ -0,0 +1,98 @@
|
|||
-- Return the first n terms of the sequence. Tree generation. Faster for this purpose.
|
||||
on CalkinWilfSequence(n)
|
||||
script o
|
||||
property sequence : {{1, 1}} -- Initialised with the first term ({numerator, denominator}).
|
||||
end script
|
||||
|
||||
-- Work through the growing sequence list, adding the two children of each term to the end and
|
||||
-- converting each term to text representing the vulgar fraction. Stop adding children halfway through.
|
||||
set halfway to n div 2
|
||||
repeat with position from 1 to n
|
||||
set {numerator, denominator} to item position of o's sequence
|
||||
if (position ≤ halfway) then
|
||||
tell numerator + denominator
|
||||
set end of o's sequence to {numerator, it}
|
||||
if ((position < halfway) or (position * 2 < n)) then set end of o's sequence to {it, denominator}
|
||||
end tell
|
||||
end if
|
||||
set item position of o's sequence to (numerator as text) & "/" & denominator
|
||||
end repeat
|
||||
|
||||
return o's sequence
|
||||
end CalkinWilfSequence
|
||||
|
||||
-- Alternatively, return terms pos1 to pos2. Binary run-length encoding. Doesn't need to work from the beginning of the sequence.
|
||||
on CalkinWilfSequence2(pos1, pos2)
|
||||
script o
|
||||
property sequence : {}
|
||||
end script
|
||||
|
||||
repeat with position from pos1 to pos2
|
||||
-- Build a continued fraction list from the binary run-length encoding of this position index.
|
||||
-- There's no need to put the last value into the list as it's used immediately.
|
||||
set continuedFraction to {}
|
||||
set bitValue to 1
|
||||
set runLength to 0
|
||||
repeat until (position = 0)
|
||||
if (position mod 2 = bitValue) then
|
||||
set runLength to runLength + 1
|
||||
else
|
||||
set end of continuedFraction to runLength
|
||||
set bitValue to (bitValue + 1) mod 2
|
||||
set runLength to 1
|
||||
end if
|
||||
set position to position div 2
|
||||
end repeat
|
||||
-- Work out the numerator and denominator from the continued fraction and derive text representing the vulgar fraction.
|
||||
set numerator to runLength
|
||||
set denominator to 1
|
||||
repeat with i from (count continuedFraction) to 1 by -1
|
||||
tell numerator
|
||||
set numerator to numerator * (item i of continuedFraction) + denominator
|
||||
set denominator to it
|
||||
end tell
|
||||
end repeat
|
||||
set end of o's sequence to (numerator as text) & "/" & denominator
|
||||
end repeat
|
||||
|
||||
return o's sequence
|
||||
end CalkinWilfSequence2
|
||||
|
||||
-- Return the sequence position of the term with the given numerator and denominator.
|
||||
on CalkinWilfSequencePosition(numerator, denominator)
|
||||
-- Build a continued fraction list from the input.
|
||||
set continuedFraction to {}
|
||||
repeat until (denominator is 0)
|
||||
set end of continuedFraction to numerator div denominator
|
||||
set {numerator, denominator} to {denominator, numerator mod denominator}
|
||||
end repeat
|
||||
-- If it has an even number of entries, convert to the equivalent odd number.
|
||||
if ((count continuedFraction) mod 2 is 0) then
|
||||
set last item of continuedFraction to (last item of continuedFraction) - 1
|
||||
set end of continuedFraction to 1
|
||||
end if
|
||||
-- "Binary run-length decode" the entries to get the position index.
|
||||
set position to 0
|
||||
set bitValue to 1
|
||||
repeat with i from (count continuedFraction) to 1 by -1
|
||||
repeat (item i of continuedFraction) times
|
||||
set position to position * 2 + bitValue
|
||||
end repeat
|
||||
set bitValue to (bitValue + 1) mod 2
|
||||
end repeat
|
||||
|
||||
return position
|
||||
end CalkinWilfSequencePosition
|
||||
|
||||
-- Task code:
|
||||
local sequenceResult1, sequenceResult2, positionResult, output, astid
|
||||
set sequenceResult1 to CalkinWilfSequence(20)
|
||||
set sequenceResult2 to CalkinWilfSequence2(1, 20)
|
||||
set positionResult to CalkinWilfSequencePosition(83116, 51639)
|
||||
set astid to AppleScript's text item delimiters
|
||||
set AppleScript's text item delimiters to ", "
|
||||
set output to "First twenty terms of sequence using tree generation:" & (linefeed & sequenceResult1)
|
||||
set output to output & (linefeed & "Ditto using binary run-length encoding:") & (linefeed & sequenceResult1)
|
||||
set AppleScript's text item delimiters to astid
|
||||
set output to output & (linefeed & "83116/51639 is term number " & positionResult)
|
||||
return output
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
"First twenty terms of sequence using tree generation:
|
||||
1/1, 1/2, 2/1, 1/3, 3/2, 2/3, 3/1, 1/4, 4/3, 3/5, 5/2, 2/5, 5/3, 3/4, 4/1, 1/5, 5/4, 4/7, 7/3, 3/8
|
||||
Ditto using binary run-length encoding:
|
||||
1/1, 1/2, 2/1, 1/3, 3/2, 2/3, 3/1, 1/4, 4/3, 3/5, 5/2, 2/5, 5/3, 3/4, 4/1, 1/5, 5/4, 4/7, 7/3, 3/8
|
||||
83116/51639 is term number 123456789"
|
||||
27
Task/Calkin-Wilf-sequence/Arturo/calkin-wilf-sequence.arturo
Normal file
27
Task/Calkin-Wilf-sequence/Arturo/calkin-wilf-sequence.arturo
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
n: new 1
|
||||
d: new 1
|
||||
calkinWilf: function [] .export:[n,d] [
|
||||
n: (d - n) + 2 * (n/d) * d
|
||||
tmp: d
|
||||
d: n
|
||||
n: tmp
|
||||
return @[n d]
|
||||
]
|
||||
|
||||
first20: [[1 1]] ++ map 1..19 => calkinWilf
|
||||
print "The first 20 terms of the Calkwin-Wilf sequence are:"
|
||||
print map first20 'f -> ~"|f\0|/|f\1|"
|
||||
|
||||
n: new 1
|
||||
d: new 1
|
||||
indx: new 1
|
||||
|
||||
target: [83116, 51639]
|
||||
|
||||
while ø [
|
||||
inc 'indx
|
||||
if target = calkinWilf -> break
|
||||
]
|
||||
|
||||
print ""
|
||||
print ["The element" ~"|target\0|/|target\1|" "is at position" indx "in the sequence."]
|
||||
25
Task/Calkin-Wilf-sequence/BQN/calkin-wilf-sequence-1.bqn
Normal file
25
Task/Calkin-Wilf-sequence/BQN/calkin-wilf-sequence-1.bqn
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
GCD ← {m 𝕊⍟(0<m←𝕨|𝕩) 𝕨}
|
||||
_while_ ← {𝔽⍟𝔾∘𝔽_𝕣_𝔾∘𝔽⍟𝔾𝕩}
|
||||
Sim ← { # Simplify a fraction
|
||||
x𝕊1: 𝕨‿1;
|
||||
0𝕊y: 0‿𝕩;
|
||||
⌊𝕨‿𝕩 ÷ 𝕨 GCD 𝕩
|
||||
}
|
||||
Add ← { # Add two fractions
|
||||
0‿b 𝕊 𝕩: 𝕩;
|
||||
𝕨 𝕊 0‿y: 𝕨;
|
||||
a‿b 𝕊 x‿y:
|
||||
((a×y)+x×b) Sim b×y
|
||||
}
|
||||
Next ← {n‿d: ⌽(2×⌊÷´n‿d)‿1 Add (d-n)‿d} # Next term
|
||||
Cal ← {Next⍟𝕩 1‿1}
|
||||
|
||||
•Show Cal 1+↕20
|
||||
|
||||
•Show {
|
||||
cnt‿fr:
|
||||
⟨cnt+1,Next fr⟩
|
||||
} _while_ {
|
||||
cnt‿fr:
|
||||
fr ≢ 83116‿51639
|
||||
} ⟨1,1‿1⟩
|
||||
2
Task/Calkin-Wilf-sequence/BQN/calkin-wilf-sequence-2.bqn
Normal file
2
Task/Calkin-Wilf-sequence/BQN/calkin-wilf-sequence-2.bqn
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
⟨ ⟨ 1 2 ⟩ ⟨ 2 1 ⟩ ⟨ 1 3 ⟩ ⟨ 3 2 ⟩ ⟨ 2 3 ⟩ ⟨ 3 1 ⟩ ⟨ 1 4 ⟩ ⟨ 4 3 ⟩ ⟨ 3 5 ⟩ ⟨ 5 2 ⟩ ⟨ 2 5 ⟩ ⟨ 5 3 ⟩ ⟨ 3 4 ⟩ ⟨ 4 1 ⟩ ⟨ 1 5 ⟩ ⟨ 5 4 ⟩ ⟨ 4 7 ⟩ ⟨ 7 3 ⟩ ⟨ 3 8 ⟩ ⟨ 8 5 ⟩ ⟩
|
||||
⟨ 123456789 ⟨ 83116 51639 ⟩ ⟩
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
( 1:?a
|
||||
& 0:?i
|
||||
& whl
|
||||
' ( 1+!i:<20:?i
|
||||
& (2*div$(!a,1)+1+-1*!a)^-1:?a
|
||||
& out$!a
|
||||
)
|
||||
& ( r2cf
|
||||
= floor
|
||||
. div$(!arg,1):?floor
|
||||
& ( !floor:!arg
|
||||
| !floor r2cf$((!arg+-1*!floor)^-1)
|
||||
)
|
||||
)
|
||||
& ( get-term-num
|
||||
= ans dig pwr
|
||||
. (0,1,1):(?ans,?dig,?pwr)
|
||||
& r2cf$!arg:?n
|
||||
& map
|
||||
$ ( (
|
||||
=
|
||||
. whl
|
||||
' ( !arg+-1:~<0:?arg
|
||||
& !dig*!pwr+!ans:?ans
|
||||
& 2*!pwr:?pwr
|
||||
)
|
||||
& 1+-1*!dig:?dig
|
||||
)
|
||||
. !n
|
||||
)
|
||||
& !ans
|
||||
)
|
||||
& out$(get-term-num$83116/51639)
|
||||
);
|
||||
53
Task/Calkin-Wilf-sequence/C++/calkin-wilf-sequence.cpp
Normal file
53
Task/Calkin-Wilf-sequence/C++/calkin-wilf-sequence.cpp
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
#include <iostream>
|
||||
#include <vector>
|
||||
#include <boost/rational.hpp>
|
||||
|
||||
using rational = boost::rational<unsigned long>;
|
||||
|
||||
unsigned long floor(const rational& r) {
|
||||
return r.numerator()/r.denominator();
|
||||
}
|
||||
|
||||
rational calkin_wilf_next(const rational& term) {
|
||||
return 1UL/(2UL * floor(term) + 1UL - term);
|
||||
}
|
||||
|
||||
std::vector<unsigned long> continued_fraction(const rational& r) {
|
||||
unsigned long a = r.numerator();
|
||||
unsigned long b = r.denominator();
|
||||
std::vector<unsigned long> result;
|
||||
do {
|
||||
result.push_back(a/b);
|
||||
unsigned long c = a;
|
||||
a = b;
|
||||
b = c % b;
|
||||
} while (a != 1);
|
||||
if (result.size() > 0 && result.size() % 2 == 0) {
|
||||
--result.back();
|
||||
result.push_back(1);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
unsigned long term_number(const rational& r) {
|
||||
unsigned long result = 0;
|
||||
unsigned long d = 1;
|
||||
unsigned long p = 0;
|
||||
for (unsigned long n : continued_fraction(r)) {
|
||||
for (unsigned long i = 0; i < n; ++i, ++p)
|
||||
result |= (d << p);
|
||||
d = !d;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
int main() {
|
||||
rational term = 1;
|
||||
std::cout << "First 20 terms of the Calkin-Wilf sequence are:\n";
|
||||
for (int i = 1; i <= 20; ++i) {
|
||||
std::cout << std::setw(2) << i << ": " << term << '\n';
|
||||
term = calkin_wilf_next(term);
|
||||
}
|
||||
rational r(83116, 51639);
|
||||
std::cout << r << " is the " << term_number(r) << "th term of the sequence.\n";
|
||||
}
|
||||
|
|
@ -0,0 +1,80 @@
|
|||
[For Rosetta Code. EDSAC program, Initial Orders 2.
|
||||
Prints the first 20 terms of the Calkin-Wilf sequence.
|
||||
Uses term{n} to calculate term{n + 1}.]
|
||||
|
||||
[Print subroutine for non-negative 17-bit integers.
|
||||
Parameters: 0F = integer to be printed (not preserved)
|
||||
1F = character for leading zero (preserved)
|
||||
Workspace: 4F, 5F. Even address; 40 locations]
|
||||
T 56 K [define load address]
|
||||
GKA3FT34@A1FT35@S37@T36@AFT5FT4FH38#@V4DH30@
|
||||
R32FR16FYFE23@O35@A2FT36@T5FV4DYFL8FT4DA5FL1024F
|
||||
UFA36@G16@OFTFT35@A36@G17@ZFPFPFP4FT1714FZ219D
|
||||
|
||||
[Main routine]
|
||||
T 100 K [define load address]
|
||||
G K [set up relative addressing via @ (theta)]
|
||||
[Constants]
|
||||
[0] P 10 F [maximum index = 20, edit ad lib.]
|
||||
[1] P D [constant 1]
|
||||
[Teleprinter characters]
|
||||
[2] # F [set figures mode]
|
||||
[3] C F [colon (in figures mode)]
|
||||
[4] X F [slash (in figures mode)]
|
||||
[5] ! F [space]
|
||||
[6] @ F [carriage return]
|
||||
[7] & F [line feed]
|
||||
[8] K 4096 F [null]
|
||||
[Variables]
|
||||
[9] P F [index]
|
||||
[10] P F [a (where term = a/b)]
|
||||
[11] P F [b]
|
||||
[Enter with acc = 0]
|
||||
[12] O 2 @ [set teleprinter to figures]
|
||||
A 1 @ [acc := 1]
|
||||
U 9 @ [index := 1]
|
||||
U 10 @ [a := 1]
|
||||
T 11 @ [b := 1 (and clear acc)]
|
||||
E 34 @ [jump to print first term]
|
||||
[Loop back here if not yet printed enough terms]
|
||||
[18] A @ [restore index after test]
|
||||
A 1 @ [add 1]
|
||||
T 9 @ [update index]
|
||||
[Calculate next term. New b := a + b - 2(a mod b).
|
||||
Code below calculates c := (a mod b) - b, then new b := a - b - 2*c]
|
||||
A 10 @ [acc := a]
|
||||
[22] S 11 @ [subtract b]
|
||||
E 22 @ [if acc >= 0, subtract again]
|
||||
T F [result c < 0, store in 0F]
|
||||
A 10 @ [acc := a]
|
||||
S 11 @ [subtract b]
|
||||
S F [subtract c]
|
||||
S F [subtract c]
|
||||
T F [new b = a - b - 2*c; store in 0F]
|
||||
A 11 @ [acc := old b]
|
||||
T 10 @ [copy to a]
|
||||
A F [acc := new b]
|
||||
T 11 @ [copy to b]
|
||||
[Print index and a/b. Assume acc = 0 here.]
|
||||
[34] A 5 @ [space to replace leading 0's]
|
||||
T 1 F [pass to print subroutine]
|
||||
A 9 @ [acc := index]
|
||||
T F [pass to print subroutine]
|
||||
[38] A 38 @ [for return from subroutine]
|
||||
G 56 F [call subroutine, clears acc]
|
||||
O 3 @ [print colon]
|
||||
O 5 @ [print space]
|
||||
A 8 @ [null to replace leading 0's]
|
||||
T 1 F [pass to print subroutine]
|
||||
A10@ TF A46@ G56F O4@ [print a followed by slash]
|
||||
A11@ TF A51@ G56F O6@ O7@ [print b followed by CR LF]
|
||||
[Test whether enough terms have been printed]
|
||||
A 9 @ [acc := index]
|
||||
S @ [subtract maximum index]
|
||||
G 18 @ [loop back if acc < 0]
|
||||
[Exit]
|
||||
O 8 @ [print null to flush teleprinter buffer]
|
||||
Z F [stop]
|
||||
E 12 Z [relative address of entry point]
|
||||
P F [enter with acc = 0]
|
||||
[end]
|
||||
|
|
@ -0,0 +1,111 @@
|
|||
[For Rosetta Code. EDSAC program, Initial Orders 2.]
|
||||
[Finds the index of a given rational in the Calkin-Wilf series.]
|
||||
|
||||
[Library subroutine R2: input of positive integers.
|
||||
Runs during input of the program, and is then overwritten.
|
||||
Allows integers to be written in decimal, rather than as "pseudo-orders".
|
||||
See Wilkes, Williams & Gill, 1951 edn, pp. 96-97, 148.]
|
||||
T 54 K [to access integers via C parameter]
|
||||
P 110 F [where to load integers]
|
||||
GKT20FVDL8FA40DUDTFI40FA40FS39FG@S2FG23FA5@T5@E4@E13Z
|
||||
T #C [tell R2 where to load integers]
|
||||
[F after each integer except the last, and # after the last.]
|
||||
83116F51639#
|
||||
|
||||
[Modified library subroutine P7.
|
||||
Prints signed integer up to 10 digits, left-justified.
|
||||
Input: Number to be printed is at 0D.
|
||||
54 locations. Load at even address. Workspace 4D.]
|
||||
|
||||
T 56 K
|
||||
GKA3FT42@A49@T31@ADE10@T31@A48@T31@SDTDH44#@NDYFLDT4DS43@
|
||||
TFH17@S17@A43@G23@UFS43@T1FV4DAFG50@SFLDUFXFOFFFSFL4FT4DA49@
|
||||
T31@A1FA43@G20@XFP1024FP610D@524D!FO46@O26@XFSFL8FT4DE39@
|
||||
|
||||
[Main routine.]
|
||||
T 120 K [define load address (must be even)]
|
||||
G K [set up relative addressing via @ (theta)]
|
||||
|
||||
[Put 35-bit values first, to ensure each is at an even address]
|
||||
[Variables]
|
||||
[0] P F P F [a]
|
||||
[2] P F P F [b]
|
||||
[4] P F P F [power of 2]
|
||||
[6] P F P F [calculated index]
|
||||
[Constants]
|
||||
T8#Z PF T8Z [clears sandwich digit between 8 and 9]
|
||||
[8] P D P F [35-bit constant 1]
|
||||
[Teleprinter characters]
|
||||
[10] # F [set figures mode]
|
||||
[11] X F [slash (in figures mode)]
|
||||
[12] K 2048 F [set letters mode]
|
||||
[13] I F [letter I]
|
||||
[14] R F [letter R]
|
||||
[15] ! F [space]
|
||||
[16] @ F [carriage return]
|
||||
[17] & F [line feed]
|
||||
[18] K 4096 F [null char]
|
||||
|
||||
[Enter with acc = 0]
|
||||
[19] A #C [acc := initial a]
|
||||
T #@ [copy to variable]
|
||||
A 2#C [acc := initial b]
|
||||
T 2#@ [copy to variable]
|
||||
[23] A 8#@ [acc := 1]
|
||||
[24] T 4#@ [initialize power of 2]
|
||||
T 6#@ [initialize index to 0]
|
||||
[Loop]
|
||||
[26] A #@ [acc := a]
|
||||
[27] S 2#@ [subtract b]
|
||||
[28] E 33 @ [jump if a >= b]
|
||||
[Here if a < b]
|
||||
T D [store a - b in 0D]
|
||||
S D [negate]
|
||||
T 2#@ [b := b - a]
|
||||
E 40 @ [join common code]
|
||||
[Here if a >= b]
|
||||
[33] S 8#@ [acc = a - b; test for a = b]
|
||||
G 45 @ [jump out of loop if so]
|
||||
A 8#@ [restore a - b]
|
||||
T #@ [a := a - b]
|
||||
A 6#@ [acc := index]
|
||||
A 4#@ [inc index by power of 2]
|
||||
T 6#@
|
||||
[Code common to both cases]
|
||||
[40] A 4#@ [acc := power of 2]
|
||||
L D [shift left]
|
||||
G 76 @
|
||||
T 4#@ [update power of 2]
|
||||
E 26 @ [loop back]
|
||||
[Exit from loop.]
|
||||
[45] T D [dump acc to clear it]
|
||||
A 6#@ [acc := index]
|
||||
A 4#@ [add power of 2 ]
|
||||
T 6#@ [store final value of index]
|
||||
[Finished calcualting index, now do printing]
|
||||
O 10 @ [set teleprinter to figures]
|
||||
A #C [acc := initial a]
|
||||
T D [to 0D for printing]
|
||||
[52] A 52 @ [for return from subroutine]
|
||||
G 56 F [call print subroutine, clears acc]
|
||||
O 11 @ [print slash]
|
||||
A 2#C [print initial b similarly]
|
||||
T D
|
||||
[57] A 57 @
|
||||
G 56 F
|
||||
O 12 @ [set teleprinter to letters and print ' IS AT ']
|
||||
O15@ O13@ O27@ O15@ O23@ O24@ O15@
|
||||
O 10 @ [set teleprinter to figures]
|
||||
A 6#@ [acc := calculated index]
|
||||
T D [send to print subroutine]
|
||||
[70] A 70 @
|
||||
G 56 F
|
||||
[72] O16@ O17@ [print CR, LF]
|
||||
O 18 @ [print null to flush teleprinter buffer]
|
||||
Z F [stop]
|
||||
[Here if power of 2 goes negative (accumulator overflow)]
|
||||
[76] O 12 @ [set teleprinter to letters]
|
||||
O28@ O14@ O14@ O76@ O14@ [print'ERROR']
|
||||
G 72 @ [jump to common exit]
|
||||
E 19 Z [relative address of entry point]
|
||||
P F [enter with acc = 0]
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
// Calkin Wilf Sequence. Nigel Galloway: January 9th., 2021
|
||||
let cW=Seq.unfold(fun(n)->Some(n,seq{for n,g in n do yield (n,n+g); yield (n+g,g)}))(seq[(1,1)])|>Seq.concat
|
||||
|
|
@ -0,0 +1 @@
|
|||
cW |> Seq.take 20 |> Seq.iter(fun(n,g)->printf "%d/%d " n g);printfn ""
|
||||
|
|
@ -0,0 +1 @@
|
|||
printfn "%d" (1+Seq.findIndex(fun n->n=(83116,51639)) cW)
|
||||
21
Task/Calkin-Wilf-sequence/Factor/calkin-wilf-sequence.factor
Normal file
21
Task/Calkin-Wilf-sequence/Factor/calkin-wilf-sequence.factor
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
USING: formatting io kernel lists lists.lazy math
|
||||
math.continued-fractions math.functions math.parser prettyprint
|
||||
sequences strings vectors ;
|
||||
|
||||
: next-cw ( x -- y ) [ floor dup + ] [ 1 swap - + recip ] bi ;
|
||||
|
||||
: calkin-wilf ( -- list ) 1 [ next-cw ] lfrom-by ;
|
||||
|
||||
: >continued-fraction ( x -- seq )
|
||||
1vector [ dup last integer? ] [ dup next-approx ] until
|
||||
dup length even? [ unclip-last 1 - suffix! 1 suffix! ] when ;
|
||||
|
||||
: cw-index ( x -- n )
|
||||
>continued-fraction <reversed>
|
||||
[ even? CHAR: 1 CHAR: 0 ? <string> ] map-index concat bin> ;
|
||||
|
||||
! Task
|
||||
"First 20 terms of the Calkin-Wilf sequence:" print
|
||||
20 calkin-wilf ltake [ pprint bl ] leach nl nl
|
||||
|
||||
83116/51639 cw-index "83116/51639 is at index %d.\n" printf
|
||||
34
Task/Calkin-Wilf-sequence/Forth/calkin-wilf-sequence.fth
Normal file
34
Task/Calkin-Wilf-sequence/Forth/calkin-wilf-sequence.fth
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
\ Calkin-Wilf sequence
|
||||
|
||||
: frac. swap . ." / " . ;
|
||||
: cw-next ( num den -- num den ) 2dup / over * 2* over + rot - ;
|
||||
: cw-seq ( n -- )
|
||||
1 1 rot
|
||||
0 do
|
||||
cr 2dup frac. cw-next
|
||||
loop 2drop ;
|
||||
|
||||
variable index
|
||||
variable bit-state
|
||||
variable bit-position
|
||||
: r2cf-next ( num1 den1 -- num2 den2 u ) swap over >r s>d r> sm/rem ;
|
||||
|
||||
: n2bitlength ( n -- )
|
||||
bit-state @ if
|
||||
1 swap lshift 1- bit-position @ lshift index +!
|
||||
else drop then ;
|
||||
|
||||
: index-init true bit-state ! 0 bit-position ! 0 index ! ;
|
||||
: index-build ( n -- )
|
||||
dup n2bitlength bit-position +! bit-state @ invert bit-state ! ;
|
||||
: index-finish ( n 0 -- ) 2drop -1 bit-position +! 1 index-build ;
|
||||
|
||||
: cw-index ( num den -- )
|
||||
index-init
|
||||
begin r2cf-next index-build dup 0<> while repeat
|
||||
index-finish ;
|
||||
|
||||
: cw-demo
|
||||
20 cw-seq
|
||||
cr 83116 51639 2dup frac. cw-index index @ . ;
|
||||
cw-demo
|
||||
108
Task/Calkin-Wilf-sequence/FreeBASIC/calkin-wilf-sequence.basic
Normal file
108
Task/Calkin-Wilf-sequence/FreeBASIC/calkin-wilf-sequence.basic
Normal file
|
|
@ -0,0 +1,108 @@
|
|||
#include "gcd.bas"
|
||||
|
||||
type rational
|
||||
num as integer
|
||||
den as integer
|
||||
end type
|
||||
|
||||
dim shared as rational ONE, TWO
|
||||
ONE.num = 1 : ONE.den = 1
|
||||
TWO.num = 2 : TWO.den = 1
|
||||
|
||||
function simplify( byval a as rational ) as rational
|
||||
dim as uinteger g = gcd( a.num, a.den )
|
||||
a.num /= g : a.den /= g
|
||||
if a.den < 0 then
|
||||
a.den = -a.den
|
||||
a.num = -a.num
|
||||
end if
|
||||
return a
|
||||
end function
|
||||
|
||||
operator + ( a as rational, b as rational ) as rational
|
||||
dim as rational ret
|
||||
ret.num = a.num * b.den + b.num*a.den
|
||||
ret.den = a.den * b.den
|
||||
return simplify(ret)
|
||||
end operator
|
||||
|
||||
operator - ( a as rational, b as rational ) as rational
|
||||
dim as rational ret
|
||||
ret.num = a.num * b.den - b.num*a.den
|
||||
ret.den = a.den * b.den
|
||||
return simplify(ret)
|
||||
end operator
|
||||
|
||||
operator * ( a as rational, b as rational ) as rational
|
||||
dim as rational ret
|
||||
ret.num = a.num * b.num
|
||||
ret.den = a.den * b.den
|
||||
return simplify(ret)
|
||||
end operator
|
||||
|
||||
operator / ( a as rational, b as rational ) as rational
|
||||
dim as rational ret
|
||||
ret.num = a.num * b.den
|
||||
ret.den = a.den * b.num
|
||||
return simplify(ret)
|
||||
end operator
|
||||
|
||||
function floor( a as rational ) as rational
|
||||
dim as rational ret
|
||||
ret.den = 1
|
||||
ret.num = a.num \ a.den
|
||||
return ret
|
||||
end function
|
||||
|
||||
function cw_nextterm( q as rational ) as rational
|
||||
dim as rational ret = (TWO*floor(q))
|
||||
ret = ret + ONE : ret = ret - q
|
||||
return ONE / ret
|
||||
end function
|
||||
|
||||
function frac_to_int( byval a as rational ) as uinteger
|
||||
redim as uinteger cfrac(-1)
|
||||
dim as integer lt = -1, ones = 1, ret = 0
|
||||
do
|
||||
lt += 1
|
||||
redim preserve as uinteger cfrac(0 to lt)
|
||||
cfrac(lt) = floor(a).num
|
||||
a = a - floor(a) : a = ONE / a
|
||||
loop until a.num = 0 or a.den = 0
|
||||
if lt mod 2 = 1 and cfrac(lt) = 1 then
|
||||
lt -= 1
|
||||
cfrac(lt)+=1
|
||||
redim preserve as uinteger cfrac(0 to lt)
|
||||
end if
|
||||
if lt mod 2 = 1 and cfrac(lt) > 1 then
|
||||
cfrac(lt) -= 1
|
||||
lt += 1
|
||||
redim preserve as uinteger cfrac(0 to lt)
|
||||
cfrac(lt) = 1
|
||||
end if
|
||||
for i as integer = lt to 0 step -1
|
||||
for j as integer = 1 to cfrac(i)
|
||||
ret *= 2
|
||||
if ones = 1 then ret += 1
|
||||
next j
|
||||
ones = 1 - ones
|
||||
next i
|
||||
return ret
|
||||
end function
|
||||
|
||||
function disp_rational( a as rational ) as string
|
||||
if a.den = 1 or a.num= 0 then return str(a.num)
|
||||
return str(a.num)+"/"+str(a.den)
|
||||
end function
|
||||
|
||||
dim as rational q
|
||||
q.num = 1
|
||||
q.den = 1
|
||||
for i as integer = 1 to 20
|
||||
print i, disp_rational(q)
|
||||
q = cw_nextterm(q)
|
||||
next i
|
||||
|
||||
q.num = 83116
|
||||
q.den = 51639
|
||||
print disp_rational(q)+" is the "+str(frac_to_int(q))+"th term."
|
||||
91
Task/Calkin-Wilf-sequence/Go/calkin-wilf-sequence.go
Normal file
91
Task/Calkin-Wilf-sequence/Go/calkin-wilf-sequence.go
Normal file
|
|
@ -0,0 +1,91 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math"
|
||||
"math/big"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func calkinWilf(n int) []*big.Rat {
|
||||
cw := make([]*big.Rat, n+1)
|
||||
cw[0] = big.NewRat(1, 1)
|
||||
one := big.NewRat(1, 1)
|
||||
two := big.NewRat(2, 1)
|
||||
for i := 1; i < n; i++ {
|
||||
t := new(big.Rat).Set(cw[i-1])
|
||||
f, _ := t.Float64()
|
||||
f = math.Floor(f)
|
||||
t.SetFloat64(f)
|
||||
t.Mul(t, two)
|
||||
t.Sub(t, cw[i-1])
|
||||
t.Add(t, one)
|
||||
t.Inv(t)
|
||||
cw[i] = new(big.Rat).Set(t)
|
||||
}
|
||||
return cw
|
||||
}
|
||||
|
||||
func toContinued(r *big.Rat) []int {
|
||||
a := r.Num().Int64()
|
||||
b := r.Denom().Int64()
|
||||
var res []int
|
||||
for {
|
||||
res = append(res, int(a/b))
|
||||
t := a % b
|
||||
a, b = b, t
|
||||
if a == 1 {
|
||||
break
|
||||
}
|
||||
}
|
||||
le := len(res)
|
||||
if le%2 == 0 { // ensure always odd
|
||||
res[le-1]--
|
||||
res = append(res, 1)
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
func getTermNumber(cf []int) int {
|
||||
b := ""
|
||||
d := "1"
|
||||
for _, n := range cf {
|
||||
b = strings.Repeat(d, n) + b
|
||||
if d == "1" {
|
||||
d = "0"
|
||||
} else {
|
||||
d = "1"
|
||||
}
|
||||
}
|
||||
i, _ := strconv.ParseInt(b, 2, 64)
|
||||
return int(i)
|
||||
}
|
||||
|
||||
func commatize(n int) string {
|
||||
s := fmt.Sprintf("%d", n)
|
||||
if n < 0 {
|
||||
s = s[1:]
|
||||
}
|
||||
le := len(s)
|
||||
for i := le - 3; i >= 1; i -= 3 {
|
||||
s = s[0:i] + "," + s[i:]
|
||||
}
|
||||
if n >= 0 {
|
||||
return s
|
||||
}
|
||||
return "-" + s
|
||||
}
|
||||
|
||||
func main() {
|
||||
cw := calkinWilf(20)
|
||||
fmt.Println("The first 20 terms of the Calkin-Wilf sequnence are:")
|
||||
for i := 1; i <= 20; i++ {
|
||||
fmt.Printf("%2d: %s\n", i, cw[i-1].RatString())
|
||||
}
|
||||
fmt.Println()
|
||||
r := big.NewRat(83116, 51639)
|
||||
cf := toContinued(r)
|
||||
tn := getTermNumber(cf)
|
||||
fmt.Printf("%s is the %sth term of the sequence.\n", r.RatString(), commatize(tn))
|
||||
}
|
||||
55
Task/Calkin-Wilf-sequence/Haskell/calkin-wilf-sequence.hs
Normal file
55
Task/Calkin-Wilf-sequence/Haskell/calkin-wilf-sequence.hs
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
import Control.Monad (forM_)
|
||||
import Data.Bool (bool)
|
||||
import Data.List.NonEmpty (NonEmpty, fromList, toList, unfoldr)
|
||||
import Text.Printf (printf)
|
||||
|
||||
-- The infinite Calkin-Wilf sequence, a(n), starting with a(1) = 1.
|
||||
calkinWilfs :: [Rational]
|
||||
calkinWilfs = iterate (recip . succ . ((-) =<< (2 *) . fromIntegral . floor)) 1
|
||||
|
||||
-- The index into the Calkin-Wilf sequence of a given rational number, starting
|
||||
-- with 1 at index 1.
|
||||
calkinWilfIdx :: Rational -> Integer
|
||||
calkinWilfIdx = rld . cfo
|
||||
|
||||
-- A continued fraction representation of a given rational number, guaranteed
|
||||
-- to have an odd length.
|
||||
cfo :: Rational -> NonEmpty Int
|
||||
cfo = oddLen . cf
|
||||
|
||||
-- The canonical (i.e. shortest) continued fraction representation of a given
|
||||
-- rational number.
|
||||
cf :: Rational -> NonEmpty Int
|
||||
cf = unfoldr step
|
||||
where
|
||||
step r =
|
||||
case properFraction r of
|
||||
(n, 1) -> (succ n, Nothing)
|
||||
(n, 0) -> (n, Nothing)
|
||||
(n, f) -> (n, Just (recip f))
|
||||
|
||||
-- Ensure a continued fraction has an odd length.
|
||||
oddLen :: NonEmpty Int -> NonEmpty Int
|
||||
oddLen = fromList . go . toList
|
||||
where
|
||||
go [x, y] = [x, pred y, 1]
|
||||
go (x:y:zs) = x : y : go zs
|
||||
go xs = xs
|
||||
|
||||
-- Run-length decode a continued fraction.
|
||||
rld :: NonEmpty Int -> Integer
|
||||
rld = snd . foldr step (True, 0)
|
||||
where
|
||||
step i (b, n) =
|
||||
let p = 2 ^ i
|
||||
in (not b, n * p + bool 0 (pred p) b)
|
||||
|
||||
main :: IO ()
|
||||
main = do
|
||||
forM_ (take 20 $ zip [1 :: Int ..] calkinWilfs) $
|
||||
\(i, r) -> printf "%2d %s\n" i (show r)
|
||||
let r = 83116 / 51639
|
||||
printf
|
||||
"\n%s is at index %d of the Calkin-Wilf sequence.\n"
|
||||
(show r)
|
||||
(calkinWilfIdx r)
|
||||
21
Task/Calkin-Wilf-sequence/J/calkin-wilf-sequence-1.j
Normal file
21
Task/Calkin-Wilf-sequence/J/calkin-wilf-sequence-1.j
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
cw_next_term=: [: % +:@<. + -.
|
||||
|
||||
ccf =: compute_continued_fraction=: 3 :0
|
||||
if. 0 -: y do.
|
||||
, 0
|
||||
else.
|
||||
result=. i. 0
|
||||
remainder=. % y
|
||||
whilst. remainder do.
|
||||
remainder=. % remainder
|
||||
integer_part=. <. remainder
|
||||
remainder=. remainder - integer_part
|
||||
result=. result , integer_part
|
||||
end.
|
||||
end.
|
||||
)
|
||||
|
||||
molcf =: make_odd_length_continued_fraction=: (}: , 1 ,~ <:@{:)^:(0 -: 2 | #)
|
||||
|
||||
NB. base 2 @ reverse @ the cf's representation copies of 1 0 1 0 ...
|
||||
index_cw_term=: #.@|.@(# 1 0 $~ #)@molcf@ccf
|
||||
1
Task/Calkin-Wilf-sequence/J/calkin-wilf-sequence-2.j
Normal file
1
Task/Calkin-Wilf-sequence/J/calkin-wilf-sequence-2.j
Normal file
|
|
@ -0,0 +1 @@
|
|||
ccf=: _1 {"1 |.@(0 1 #: %@{.)^:(0~:{.)^:a:
|
||||
127
Task/Calkin-Wilf-sequence/Java/calkin-wilf-sequence.java
Normal file
127
Task/Calkin-Wilf-sequence/Java/calkin-wilf-sequence.java
Normal file
|
|
@ -0,0 +1,127 @@
|
|||
import java.util.ArrayDeque;
|
||||
import java.util.Deque;
|
||||
|
||||
public final class CalkinWilfSequence {
|
||||
|
||||
public static void main(String[] aArgs) {
|
||||
Rational term = Rational.ONE;
|
||||
System.out.println("First 20 terms of the Calkin-Wilf sequence are:");
|
||||
for ( int i = 1; i <= 20; i++ ) {
|
||||
System.out.println(String.format("%2d", i) + ": " + term);
|
||||
term = nextCalkinWilf(term);
|
||||
}
|
||||
System.out.println();
|
||||
|
||||
Rational rational = new Rational(83_116, 51_639);
|
||||
System.out.println(" " + rational + " is the " + termIndex(rational) + "th term of the sequence.");
|
||||
|
||||
}
|
||||
|
||||
private static Rational nextCalkinWilf(Rational aTerm) {
|
||||
Rational divisor = Rational.TWO.multiply(aTerm.floor()).add(Rational.ONE).subtract(aTerm);
|
||||
return Rational.ONE.divide(divisor);
|
||||
}
|
||||
|
||||
private static long termIndex(Rational aRational) {
|
||||
long result = 0;
|
||||
long binaryDigit = 1;
|
||||
long power = 0;
|
||||
for ( long term : continuedFraction(aRational) ) {
|
||||
for ( long i = 0; i < term; power++, i++ ) {
|
||||
result |= ( binaryDigit << power );
|
||||
}
|
||||
binaryDigit = ( binaryDigit == 0 ) ? 1 : 0;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private static Deque<Long> continuedFraction(Rational aRational) {
|
||||
long numerator = aRational.numerator();
|
||||
long denominator = aRational.denominator();
|
||||
Deque<Long> result = new ArrayDeque<Long>();
|
||||
|
||||
while ( numerator != 1 ) {
|
||||
result.addLast(numerator / denominator);
|
||||
long copyNumerator = numerator;
|
||||
numerator = denominator;
|
||||
denominator = copyNumerator % denominator;
|
||||
}
|
||||
|
||||
if ( ! result.isEmpty() && result.size() % 2 == 0 ) {
|
||||
final long back = result.removeLast();
|
||||
result.addLast(back - 1);
|
||||
result.addLast(1L);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
final class Rational {
|
||||
|
||||
public Rational(long aNumerator, long aDenominator) {
|
||||
if ( aDenominator == 0 ) {
|
||||
throw new ArithmeticException("Denominator cannot be zero");
|
||||
}
|
||||
if ( aNumerator == 0 ) {
|
||||
aDenominator = 1;
|
||||
}
|
||||
if ( aDenominator < 0 ) {
|
||||
numer = -aNumerator;
|
||||
denom = -aDenominator;
|
||||
} else {
|
||||
numer = aNumerator;
|
||||
denom = aDenominator;
|
||||
}
|
||||
final long gcd = gcd(numer, denom);
|
||||
numer = numer / gcd;
|
||||
denom = denom / gcd;
|
||||
}
|
||||
|
||||
public Rational add(Rational aOther) {
|
||||
return new Rational(numer * aOther.denom + aOther.numer * denom, denom * aOther.denom);
|
||||
}
|
||||
|
||||
public Rational subtract(Rational aOther) {
|
||||
return new Rational(numer * aOther.denom - aOther.numer * denom, denom * aOther.denom);
|
||||
}
|
||||
|
||||
public Rational multiply(Rational aOther) {
|
||||
return new Rational(numer * aOther.numer, denom * aOther.denom);
|
||||
}
|
||||
|
||||
public Rational divide(Rational aOther) {
|
||||
return new Rational(numer * aOther.denom, denom * aOther.numer);
|
||||
}
|
||||
|
||||
public Rational floor() {
|
||||
return new Rational(numer / denom, 1);
|
||||
}
|
||||
|
||||
public long numerator() {
|
||||
return numer;
|
||||
}
|
||||
|
||||
public long denominator() {
|
||||
return denom;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return numer + "/" + denom;
|
||||
}
|
||||
|
||||
public static final Rational ONE = new Rational(1, 1);
|
||||
public static final Rational TWO = new Rational(2, 1);
|
||||
|
||||
private long gcd(long aOne, long aTwo) {
|
||||
if ( aTwo == 0 ) {
|
||||
return aOne;
|
||||
}
|
||||
return gcd(aTwo, aOne % aTwo);
|
||||
}
|
||||
|
||||
private long numer;
|
||||
private long denom;
|
||||
|
||||
}
|
||||
66
Task/Calkin-Wilf-sequence/Jq/calkin-wilf-sequence.jq
Normal file
66
Task/Calkin-Wilf-sequence/Jq/calkin-wilf-sequence.jq
Normal file
|
|
@ -0,0 +1,66 @@
|
|||
include "rational"; # see [[Arithmetic/Rational#jq]]
|
||||
|
||||
### Generic Utilities
|
||||
|
||||
# counting from 0
|
||||
def enumerate(s): foreach s as $x (-1; .+1; [., $x]);
|
||||
|
||||
# input string is converted from "base" to an integer, within limits
|
||||
# of the underlying arithmetic operations, and without error-checking:
|
||||
def to_i(base):
|
||||
explode
|
||||
| reverse
|
||||
| map(if . > 96 then . - 87 else . - 48 end) # "a" ~ 97 => 10 ~ 87
|
||||
| reduce .[] as $c
|
||||
# state: [power, ans]
|
||||
([1,0]; (.[0] * base) as $b | [$b, .[1] + (.[0] * $c)])
|
||||
| .[1];
|
||||
|
||||
### The Calkin-Wilf Sequence
|
||||
|
||||
# Emit an array of $n terms
|
||||
def calkinWilf($n):
|
||||
reduce range(1;$n) as $i ( [r(1;1)];
|
||||
radd(1; rminus( rmult(2; (.[$i-1]|rfloor)); .[$i-1])) as $t
|
||||
| .[$i] = rdiv(r(1;1) ; $t)) ;
|
||||
|
||||
# input: a Rational
|
||||
def toContinued:
|
||||
{ a: .n,
|
||||
b: .d,
|
||||
res: [] }
|
||||
| until( .break;
|
||||
.res += [.a / .b | floor]
|
||||
| (.a % .b) as $t
|
||||
| .a = .b
|
||||
| .b = $t
|
||||
| .break = (.a == 1) )
|
||||
| if .res|length % 2 == 0
|
||||
then # ensure always odd
|
||||
.res[-1] += -1
|
||||
| .res += [1]
|
||||
else .
|
||||
end
|
||||
| .res;
|
||||
|
||||
# input: an array representing a continued fraction
|
||||
def getTermNumber:
|
||||
reduce .[] as $n ( {b: "", d: "1"};
|
||||
.b = (.d * $n) + .b
|
||||
| .d = (if .d == "1" then "0" else "1" end))
|
||||
| .b | to_i(2) ;
|
||||
|
||||
# input: a Rational in the Calkin-Wilf sequence
|
||||
def getTermNumber:
|
||||
reduce .[] as $n ( {b: "", d: "1"};
|
||||
.b = (.d * $n) + .b
|
||||
| .d = (if .d == "1" then "0" else "1" end))
|
||||
| .b | to_i(2) ;
|
||||
|
||||
def task(r):
|
||||
"The first 20 terms of the Calkin-Wilf sequence are:",
|
||||
(enumerate(calkinWilf(20)[]) | "\(1+.[0]): \(.[1]|rpp)" ),
|
||||
"",
|
||||
"\(r|rpp) is term # \(r|toContinued|getTermNumber) of the sequence.";
|
||||
|
||||
task( r(83116; 51639) )
|
||||
36
Task/Calkin-Wilf-sequence/Julia/calkin-wilf-sequence.julia
Normal file
36
Task/Calkin-Wilf-sequence/Julia/calkin-wilf-sequence.julia
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
function calkin_wilf(n)
|
||||
cw = zeros(Rational, n + 1)
|
||||
for i in 2:n + 1
|
||||
t = Int(floor(cw[i - 1])) * 2 - cw[i - 1] + 1
|
||||
cw[i] = 1 // t
|
||||
end
|
||||
return cw[2:end]
|
||||
end
|
||||
|
||||
function continued(r::Rational)
|
||||
a, b = r.num, r.den
|
||||
res = []
|
||||
while true
|
||||
push!(res, Int(floor(a / b)))
|
||||
a, b = b, a % b
|
||||
a == 1 && break
|
||||
end
|
||||
return res
|
||||
end
|
||||
|
||||
function term_number(cf)
|
||||
b, d = "", "1"
|
||||
for n in cf
|
||||
b = d^n * b
|
||||
d = (d == "1") ? "0" : "1"
|
||||
end
|
||||
return parse(Int, b, base=2)
|
||||
end
|
||||
|
||||
const cw = calkin_wilf(20)
|
||||
println("The first 20 terms of the Calkin-Wilf sequence are: $cw")
|
||||
|
||||
const r = 83116 // 51639
|
||||
const cf = continued(r)
|
||||
const tn = term_number(cf)
|
||||
println("$r is the $tn-th term of the sequence.")
|
||||
|
|
@ -0,0 +1,90 @@
|
|||
// Little Man Computer, for Rosetta Code.
|
||||
// Displays terms of Calkin-Wilf sequence up to the given index.
|
||||
// The chosen algorithm calculates the i-th term directly from i
|
||||
// (i.e. not using any previous terms).
|
||||
input INP // get number of terms from user
|
||||
BRZ exit // exit if 0
|
||||
STA max_i // store maximum index
|
||||
LDA c1 // index := 1
|
||||
next_i STA i
|
||||
// Write index followed by '->'
|
||||
OTX 3 // non-standard: minimum width 3, no new line
|
||||
LDA asc_hy
|
||||
OTC
|
||||
LDA asc_gt
|
||||
OTC
|
||||
// Find greatest power of 2 not exceeding i,
|
||||
// and count the number of binary digits in i.
|
||||
LDA c1
|
||||
STA pwr2
|
||||
loop2 STA nrDigits
|
||||
LDA i
|
||||
SUB pwr2
|
||||
SUB pwr2
|
||||
BRP double
|
||||
BRA part2 // jump out if next power of 2 would exceed i
|
||||
double LDA pwr2
|
||||
ADD pwr2
|
||||
STA pwr2
|
||||
LDA nrDigits
|
||||
ADD c1
|
||||
BRA loop2
|
||||
// The nth term a/b is calculated from the binary digits of i.
|
||||
// The leading 1 is not used.
|
||||
part2 LDA c1
|
||||
STA a // a := 1
|
||||
STA b // b := 1
|
||||
LDA i
|
||||
SUB pwr2
|
||||
STA diff
|
||||
// Pre-decrement count, since leading 1 is not used
|
||||
dec_ct LDA nrDigits // count down the number of digits
|
||||
SUB c1
|
||||
BRZ output // if all digits done, output the result
|
||||
STA nrDigits
|
||||
// We now want to compare diff with pwr2/2.
|
||||
// Since division is awkward in LMC, we compare 2*diff with pwr2.
|
||||
LDA diff // diff := 2*diff
|
||||
ADD diff
|
||||
STA diff
|
||||
SUB pwr2 // is diff >= pwr2 ?
|
||||
BRP digit_1 // binary digit is 1 if yes, 0 if no
|
||||
// If binary digit is 0 then set b := a + b
|
||||
LDA a
|
||||
ADD b
|
||||
STA b
|
||||
BRA dec_ct
|
||||
// If binary digit is 1 then update diff and set a := a + b
|
||||
digit_1 STA diff
|
||||
LDA a
|
||||
ADD b
|
||||
STA a
|
||||
BRA dec_ct
|
||||
// Now have nth term a/b. Write it to the output.
|
||||
output LDA a // write a
|
||||
OTX 1 // non-standard: minimum width 1; no new line
|
||||
LDA asc_sl // write slash
|
||||
OTC
|
||||
LDA b // write b
|
||||
OTX 11 // non-standard: minimum width 1; add new line
|
||||
LDA i // have we done maximum i yet?
|
||||
SUB max_i
|
||||
BRZ exit // if yes, exit
|
||||
LDA i // if no, increment i and loop back
|
||||
ADD c1
|
||||
BRA next_i
|
||||
exit HLT
|
||||
// Constants
|
||||
c1 DAT 1
|
||||
asc_hy DAT 45
|
||||
asc_gt DAT 62
|
||||
asc_sl DAT 47
|
||||
// Variables
|
||||
i DAT
|
||||
max_i DAT
|
||||
pwr2 DAT
|
||||
nrDigits DAT
|
||||
diff DAT
|
||||
a DAT
|
||||
b DAT
|
||||
// end
|
||||
|
|
@ -0,0 +1,66 @@
|
|||
// Little Man Computer, for Rosetta Code.
|
||||
// Calkin-Wilf sequence: displays index of term entered by user.
|
||||
INP // get numerator from user
|
||||
BRZ exit // exit if 0
|
||||
STA num
|
||||
STA a // initialize a := numerator
|
||||
INP // get denominator from user
|
||||
BRZ exit // exit if 0
|
||||
STA den
|
||||
STA b // initialize b := denominator
|
||||
LDA c0 // initialize index := 0
|
||||
STA index
|
||||
LDA c1 // initialize power of 2 := 1
|
||||
STA pwr2
|
||||
// Build binary digits of the index
|
||||
loop LDA a // is a = b yet?
|
||||
SUB b
|
||||
BRZ break // if yes, break out of loop
|
||||
BRP a_gt_b // jump if a > b
|
||||
// If a < b then b := b - a, binary digit is 0
|
||||
LDA b
|
||||
SUB a
|
||||
STA b
|
||||
BRA double
|
||||
// If a > b then a := a - b, binary digit is 1
|
||||
a_gt_b STA a
|
||||
LDA index
|
||||
ADD pwr2
|
||||
STA index
|
||||
// In either case, on to next power of 2
|
||||
double LDA pwr2
|
||||
ADD pwr2
|
||||
STA pwr2
|
||||
BRA loop
|
||||
// Out of loop, add leading binary digit 1
|
||||
break LDA index
|
||||
ADD pwr2
|
||||
STA index
|
||||
// Output the result
|
||||
LDA num
|
||||
OTX 1 // non-standard: minimum width = 1, no new line
|
||||
LDA asc_sl
|
||||
OTC
|
||||
LDA den
|
||||
OTX 1
|
||||
LDA asc_lt // write '<-' after fraction
|
||||
OTC
|
||||
LDA asc_hy
|
||||
OTC
|
||||
LDA index
|
||||
OTX 11 // non-standard: minimum width = 1, add new line
|
||||
exit HLT
|
||||
// Constants
|
||||
c0 DAT 0
|
||||
c1 DAT 1
|
||||
asc_sl DAT 47
|
||||
asc_lt DAT 60
|
||||
asc_hy DAT 45
|
||||
// Variables
|
||||
num DAT
|
||||
den DAT
|
||||
a DAT
|
||||
b DAT
|
||||
pwr2 DAT
|
||||
index DAT
|
||||
// end
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
ClearAll[a]
|
||||
a[1] = 1;
|
||||
a[n_?(GreaterThan[1])] := a[n] = 1/(2 Floor[a[n - 1]] + 1 - a[n - 1])
|
||||
a /@ Range[20]
|
||||
|
||||
ClearAll[a]
|
||||
a = 1;
|
||||
n = 1;
|
||||
Dynamic[n]
|
||||
done = False;
|
||||
While[! done,
|
||||
a = 1/(2 Floor[a] + 1 - a);
|
||||
n++;
|
||||
If[a == 83116/51639,
|
||||
Print[n];
|
||||
Break[];
|
||||
]
|
||||
]
|
||||
35
Task/Calkin-Wilf-sequence/Nim/calkin-wilf-sequence.nim
Normal file
35
Task/Calkin-Wilf-sequence/Nim/calkin-wilf-sequence.nim
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
type Fraction = tuple[num, den: uint32]
|
||||
|
||||
iterator calkinWilf(): Fraction =
|
||||
## Yield the successive values of the sequence.
|
||||
var n, d = 1u32
|
||||
yield (n, d)
|
||||
while true:
|
||||
n = 2 * (n div d) * d + d - n
|
||||
swap n, d
|
||||
yield (n, d)
|
||||
|
||||
proc `$`(fract: Fraction): string =
|
||||
## Return the representation of a fraction.
|
||||
$fract.num & '/' & $fract.den
|
||||
|
||||
func `==`(a, b: Fraction): bool {.inline.} =
|
||||
## Compare two fractions. Slightly faster than comparison of tuples.
|
||||
a.num == b.num and a.den == b.den
|
||||
|
||||
when isMainModule:
|
||||
|
||||
echo "The first 20 terms of the Calkwin-Wilf sequence are:"
|
||||
var count = 0
|
||||
for an in calkinWilf():
|
||||
inc count
|
||||
stdout.write $an & ' '
|
||||
if count == 20: break
|
||||
stdout.write '\n'
|
||||
|
||||
const Target: Fraction = (83116u32, 51639u32)
|
||||
var index = 0
|
||||
for an in calkinWilf():
|
||||
inc index
|
||||
if an == Target: break
|
||||
echo "\nThe element ", $Target, " is at position ", $index, " in the sequence."
|
||||
120
Task/Calkin-Wilf-sequence/Pascal/calkin-wilf-sequence-1.pas
Normal file
120
Task/Calkin-Wilf-sequence/Pascal/calkin-wilf-sequence-1.pas
Normal file
|
|
@ -0,0 +1,120 @@
|
|||
program CWTerms;
|
||||
|
||||
{-------------------------------------------------------------------------------
|
||||
FreePascal command-line program.
|
||||
Calculates the Calkin-Wilf sequence up to the specified maximum index,
|
||||
where the first term 1/1 has index 1.
|
||||
Command line format is: CWTerms <max_index>
|
||||
|
||||
The program demonstrates 3 algorithms for calculating the sequence:
|
||||
(1) Calculate term[2n] and term[2n + 1] from term[n]
|
||||
(2) Calculate term[n + 1] from term[n]
|
||||
(3) Calculate term[n] directly from n, without using other terms
|
||||
Algorithm 1 is called first, and stores the terms in an array.
|
||||
Then the program calls Algorithms 2 and 3, and checks that they agree
|
||||
with Algorithm 1.
|
||||
-------------------------------------------------------------------------------}
|
||||
|
||||
uses SysUtils;
|
||||
|
||||
type TRational = record
|
||||
Num, Den : integer;
|
||||
end;
|
||||
|
||||
var
|
||||
terms : array of TRational;
|
||||
max_index, k : integer;
|
||||
|
||||
// Routine to calculate array of terms up the the maiximum index
|
||||
procedure CalcTerms_algo_1();
|
||||
var
|
||||
j, k : integer;
|
||||
begin
|
||||
SetLength( terms, max_index + 1);
|
||||
j := 1; // index to earlier term, from which current term is calculated
|
||||
k := 1; // index to current term
|
||||
terms[1].Num := 1;
|
||||
terms[1].Den := 1;
|
||||
while (k < max_index) do begin
|
||||
inc(k);
|
||||
if (k and 1) = 0 then begin // or could write "if not Odd(k)"
|
||||
terms[k].Num := terms[j].Num;
|
||||
terms[k].Den := terms[j].Num + terms[j].Den;
|
||||
end
|
||||
else begin
|
||||
terms[k].Num := terms[j].Num + terms[j].Den;
|
||||
terms[k].Den := terms[j].Den;
|
||||
inc(j);
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
// Method to get each term from the preceding term.
|
||||
// a/b --> b/(a + b - 2(a mod b));
|
||||
function CheckTerms_algo_2() : boolean;
|
||||
var
|
||||
index, a, b, temp : integer;
|
||||
begin
|
||||
result := true;
|
||||
index := 1;
|
||||
a := 1;
|
||||
b := 1;
|
||||
while (index <= max_index) do begin
|
||||
if (a <> terms[index].Num) or (b <> terms[index].Den) then
|
||||
result := false;
|
||||
temp := a + b - 2*(a mod b);
|
||||
a := b;
|
||||
b := temp;
|
||||
inc( index)
|
||||
end;
|
||||
end;
|
||||
|
||||
// Mathod to calcualte each term from its index, without using other terms.
|
||||
function CheckTerms_algo_3() : boolean;
|
||||
var
|
||||
index, a, b, pwr2, idiv2 : integer;
|
||||
begin
|
||||
result := true;
|
||||
for index := 1 to max_index do begin
|
||||
|
||||
idiv2 := index div 2;
|
||||
pwr2 := 1;
|
||||
while (pwr2 <= idiv2) do pwr2 := pwr2 shl 1;
|
||||
a := 1;
|
||||
b := 1;
|
||||
while (pwr2 > 1) do begin
|
||||
pwr2 := pwr2 shr 1;
|
||||
if (pwr2 and index) = 0 then
|
||||
inc( b, a)
|
||||
else
|
||||
inc( a, b);
|
||||
end;
|
||||
if (a <> terms[index].Num) or (b <> terms[index].Den) then
|
||||
result := false;
|
||||
end;
|
||||
end;
|
||||
|
||||
begin
|
||||
// Read and validate maximum index
|
||||
max_index := SysUtils.StrToIntDef( paramStr(1), -1); // -1 if not an integer
|
||||
if (max_index <= 0) then begin
|
||||
WriteLn( 'Maximum index must be a positive integer');
|
||||
exit;
|
||||
end;
|
||||
|
||||
// Calculate terms by algo 1, then check that algos 2 and 3 agree.
|
||||
CalcTerms_algo_1();
|
||||
if not CheckTerms_algo_2() then begin
|
||||
WriteLn( 'Algorithm 2 failed');
|
||||
exit;
|
||||
end;
|
||||
if not CheckTerms_algo_3() then begin
|
||||
WriteLn( 'Algorithm 3 failed');
|
||||
exit;
|
||||
end;
|
||||
|
||||
// Display the terms
|
||||
for k := 1 to max_index do
|
||||
with terms[k] do
|
||||
WriteLn( SysUtils.Format( '%8d: %d/%d', [k, Num, Den]));
|
||||
end.
|
||||
50
Task/Calkin-Wilf-sequence/Pascal/calkin-wilf-sequence-2.pas
Normal file
50
Task/Calkin-Wilf-sequence/Pascal/calkin-wilf-sequence-2.pas
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
program CWIndex;
|
||||
|
||||
{-------------------------------------------------------------------------------
|
||||
FreePascal command-line program.
|
||||
Calculates index of a rational number in the Calkin-Wilf sequence,
|
||||
where the first term 1/1 has index 1.
|
||||
Command line format is
|
||||
CWIndex <numerator> <denominator>
|
||||
e.g. for the Rosetta Code example
|
||||
CWIndex 83116 51639
|
||||
-------------------------------------------------------------------------------}
|
||||
|
||||
uses SysUtils;
|
||||
|
||||
var
|
||||
num, den : integer;
|
||||
a, b : integer;
|
||||
pwr2, index : qword; // 64-bit unsiged
|
||||
begin
|
||||
// Read and validate input.
|
||||
num := SysUtils.StrToIntDef( paramStr(1), -1); // return -1 if not an integer
|
||||
den := SysUtils.StrToIntDef( paramStr(2), -1);
|
||||
if (num <= 0) or (den <= 0) then begin
|
||||
WriteLn( 'Numerator and denominator must be positive integers');
|
||||
exit;
|
||||
end;
|
||||
|
||||
// Input OK, calculate and display index of num/den
|
||||
// The index may overflow 64 bits, so turn on overflow detection
|
||||
{$Q+}
|
||||
a := num;
|
||||
b := den;
|
||||
pwr2 := 1;
|
||||
index := 0;
|
||||
try
|
||||
while (a <> b) do begin
|
||||
if (a < b) then
|
||||
dec( b, a)
|
||||
else begin
|
||||
dec( a, b);
|
||||
inc( index, pwr2);
|
||||
end;
|
||||
pwr2 := 2*pwr2;
|
||||
end;
|
||||
inc( index, pwr2);
|
||||
WriteLn( SysUtils.Format( 'Index of %d/%d is %u', [num, den, index]));
|
||||
except
|
||||
WriteLn( 'Index is too large for 64 bits');
|
||||
end;
|
||||
end.
|
||||
33
Task/Calkin-Wilf-sequence/Perl/calkin-wilf-sequence.pl
Normal file
33
Task/Calkin-Wilf-sequence/Perl/calkin-wilf-sequence.pl
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
use strict;
|
||||
use warnings;
|
||||
use feature qw(say state);
|
||||
|
||||
use ntheory 'fromdigits';
|
||||
use List::Lazy 'lazy_list';
|
||||
use Math::AnyNum ':overload';
|
||||
|
||||
my $calkin_wilf = lazy_list { state @cw = 1; push @cw, 1 / ( (2 * int $cw[0]) + 1 - $cw[0] ); shift @cw };
|
||||
|
||||
sub r2cf {
|
||||
my($num, $den) = @_;
|
||||
my($n, @cf);
|
||||
my $f = sub { return unless $den;
|
||||
my $q = int($num/$den);
|
||||
($num, $den) = ($den, $num - $q*$den);
|
||||
$q;
|
||||
};
|
||||
push @cf, $n while defined($n = $f->());
|
||||
reverse @cf;
|
||||
}
|
||||
|
||||
sub r2cw {
|
||||
my($num, $den) = @_;
|
||||
my $bits;
|
||||
my @f = r2cf($num, $den);
|
||||
$bits .= ($_%2 ? 0 : 1) x $f[$_] for 0..$#f;
|
||||
fromdigits($bits, 2);
|
||||
}
|
||||
|
||||
say 'First twenty terms of the Calkin-Wilf sequence:';
|
||||
printf "%s ", $calkin_wilf->next() for 1..20;
|
||||
say "\n\n83116/51639 is at index: " . r2cw(83116,51639);
|
||||
92
Task/Calkin-Wilf-sequence/Phix/calkin-wilf-sequence.phix
Normal file
92
Task/Calkin-Wilf-sequence/Phix/calkin-wilf-sequence.phix
Normal file
|
|
@ -0,0 +1,92 @@
|
|||
(phixonline)-->
|
||||
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
|
||||
<span style="color: #7060A8;">requires</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"1.0.0"</span><span style="color: #0000FF;">)</span> <span style="color: #000080;font-style:italic;">-- (new even() builtin)</span>
|
||||
|
||||
<span style="color: #008080;">function</span> <span style="color: #000000;">calkin_wilf</span><span style="color: #0000FF;">(</span><span style="color: #004080;">integer</span> <span style="color: #000000;">len</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #004080;">sequence</span> <span style="color: #000000;">cw</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">len</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #004080;">integer</span> <span style="color: #000000;">n</span><span style="color: #0000FF;">=</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">d</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span>
|
||||
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">len</span> <span style="color: #008080;">do</span>
|
||||
<span style="color: #0000FF;">{</span><span style="color: #000000;">n</span><span style="color: #0000FF;">,</span><span style="color: #000000;">d</span><span style="color: #0000FF;">}</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">d</span><span style="color: #0000FF;">,(</span><span style="color: #7060A8;">floor</span><span style="color: #0000FF;">(</span><span style="color: #000000;">n</span><span style="color: #0000FF;">/</span><span style="color: #000000;">d</span><span style="color: #0000FF;">)*</span><span style="color: #000000;">2</span><span style="color: #0000FF;">+</span><span style="color: #000000;">1</span><span style="color: #0000FF;">)*</span><span style="color: #000000;">d</span><span style="color: #0000FF;">-</span><span style="color: #000000;">n</span><span style="color: #0000FF;">}</span>
|
||||
<span style="color: #000000;">cw</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">n</span><span style="color: #0000FF;">,</span><span style="color: #000000;">d</span><span style="color: #0000FF;">}</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
|
||||
<span style="color: #008080;">return</span> <span style="color: #000000;">cw</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
|
||||
|
||||
<span style="color: #008080;">function</span> <span style="color: #000000;">odd_length</span><span style="color: #0000FF;">(</span><span style="color: #004080;">sequence</span> <span style="color: #000000;">cf</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #000080;font-style:italic;">-- replace even length continued fraction with odd length equivalent
|
||||
-- if remainder(length(cf),2)=0 then</span>
|
||||
<span style="color: #008080;">if</span> <span style="color: #7060A8;">even</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">cf</span><span style="color: #0000FF;">))</span> <span style="color: #008080;">then</span>
|
||||
<span style="color: #000000;">cf</span><span style="color: #0000FF;">[$]</span> <span style="color: #0000FF;">-=</span> <span style="color: #000000;">1</span>
|
||||
<span style="color: #000000;">cf</span> <span style="color: #0000FF;">&=</span> <span style="color: #000000;">1</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
|
||||
<span style="color: #008080;">return</span> <span style="color: #000000;">cf</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
|
||||
|
||||
<span style="color: #008080;">function</span> <span style="color: #000000;">to_continued_fraction</span><span style="color: #0000FF;">(</span><span style="color: #004080;">sequence</span> <span style="color: #000000;">r</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #004080;">integer</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">a</span><span style="color: #0000FF;">,</span><span style="color: #000000;">b</span><span style="color: #0000FF;">}</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">r</span>
|
||||
<span style="color: #004080;">sequence</span> <span style="color: #000000;">cf</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{}</span>
|
||||
<span style="color: #008080;">while</span> <span style="color: #004600;">true</span> <span style="color: #008080;">do</span>
|
||||
<span style="color: #000000;">cf</span> <span style="color: #0000FF;">&=</span> <span style="color: #7060A8;">floor</span><span style="color: #0000FF;">(</span><span style="color: #000000;">a</span><span style="color: #0000FF;">/</span><span style="color: #000000;">b</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #0000FF;">{</span><span style="color: #000000;">a</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">b</span><span style="color: #0000FF;">}</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">b</span><span style="color: #0000FF;">,</span> <span style="color: #7060A8;">remainder</span><span style="color: #0000FF;">(</span><span style="color: #000000;">a</span><span style="color: #0000FF;">,</span><span style="color: #000000;">b</span><span style="color: #0000FF;">)}</span>
|
||||
<span style="color: #008080;">if</span> <span style="color: #000000;">a</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">then</span> <span style="color: #008080;">exit</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">while</span>
|
||||
<span style="color: #000000;">cf</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">odd_length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">cf</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #008080;">return</span> <span style="color: #000000;">cf</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
|
||||
|
||||
<span style="color: #008080;">function</span> <span style="color: #000000;">get_term_number</span><span style="color: #0000FF;">(</span><span style="color: #004080;">sequence</span> <span style="color: #000000;">cf</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #004080;">sequence</span> <span style="color: #000000;">b</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{}</span>
|
||||
<span style="color: #004080;">integer</span> <span style="color: #000000;">d</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">1</span>
|
||||
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">cf</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
|
||||
<span style="color: #000000;">b</span> <span style="color: #0000FF;">&=</span> <span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #000000;">d</span><span style="color: #0000FF;">,</span><span style="color: #000000;">cf</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">])</span>
|
||||
<span style="color: #000000;">d</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">1</span><span style="color: #0000FF;">-</span><span style="color: #000000;">d</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
|
||||
<span style="color: #004080;">integer</span> <span style="color: #000000;">t</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">bits_to_int</span><span style="color: #0000FF;">(</span><span style="color: #000000;">b</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #008080;">return</span> <span style="color: #000000;">t</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
|
||||
|
||||
<span style="color: #000080;font-style:italic;">-- additional verification methods (2 of)</span>
|
||||
<span style="color: #008080;">function</span> <span style="color: #000000;">i_to_cf</span><span style="color: #0000FF;">(</span><span style="color: #004080;">integer</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #000080;font-style:italic;">-- sequence b = trim_tail(int_to_bits(i,32),0)&2,</span>
|
||||
<span style="color: #004080;">sequence</span> <span style="color: #000000;">b</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">int_to_bits</span><span style="color: #0000FF;">(</span><span style="color: #000000;">i</span><span style="color: #0000FF;">)&</span><span style="color: #000000;">2</span><span style="color: #0000FF;">,</span>
|
||||
<span style="color: #000000;">cf</span> <span style="color: #0000FF;">=</span> <span style="color: #008080;">iff</span><span style="color: #0000FF;">(</span><span style="color: #000000;">b</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]=</span><span style="color: #000000;">0</span><span style="color: #0000FF;">?{</span><span style="color: #000000;">0</span><span style="color: #0000FF;">}:{})</span>
|
||||
<span style="color: #008080;">while</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">b</span><span style="color: #0000FF;">)></span><span style="color: #000000;">1</span> <span style="color: #008080;">do</span>
|
||||
<span style="color: #008080;">for</span> <span style="color: #000000;">j</span><span style="color: #0000FF;">=</span><span style="color: #000000;">2</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">b</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
|
||||
<span style="color: #008080;">if</span> <span style="color: #000000;">b</span><span style="color: #0000FF;">[</span><span style="color: #000000;">j</span><span style="color: #0000FF;">]!=</span><span style="color: #000000;">b</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]</span> <span style="color: #008080;">then</span>
|
||||
<span style="color: #000000;">cf</span> <span style="color: #0000FF;">&=</span> <span style="color: #000000;">j</span><span style="color: #0000FF;">-</span><span style="color: #000000;">1</span>
|
||||
<span style="color: #000000;">b</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">b</span><span style="color: #0000FF;">[</span><span style="color: #000000;">j</span><span style="color: #0000FF;">..$]</span>
|
||||
<span style="color: #008080;">exit</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">while</span>
|
||||
<span style="color: #000000;">cf</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">odd_length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">cf</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #008080;">return</span> <span style="color: #000000;">cf</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
|
||||
|
||||
<span style="color: #008080;">function</span> <span style="color: #000000;">cf2r</span><span style="color: #0000FF;">(</span><span style="color: #004080;">sequence</span> <span style="color: #000000;">cf</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #004080;">integer</span> <span style="color: #000000;">n</span><span style="color: #0000FF;">=</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">d</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span>
|
||||
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">cf</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">to</span> <span style="color: #000000;">2</span> <span style="color: #008080;">by</span> <span style="color: #0000FF;">-</span><span style="color: #000000;">1</span> <span style="color: #008080;">do</span>
|
||||
<span style="color: #0000FF;">{</span><span style="color: #000000;">n</span><span style="color: #0000FF;">,</span><span style="color: #000000;">d</span><span style="color: #0000FF;">}</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">d</span><span style="color: #0000FF;">,</span><span style="color: #000000;">n</span><span style="color: #0000FF;">+</span><span style="color: #000000;">d</span><span style="color: #0000FF;">*</span><span style="color: #000000;">cf</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]}</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
|
||||
<span style="color: #008080;">return</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">n</span><span style="color: #0000FF;">+</span><span style="color: #000000;">cf</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]*</span><span style="color: #000000;">d</span><span style="color: #0000FF;">,</span><span style="color: #000000;">d</span><span style="color: #0000FF;">}</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
|
||||
|
||||
<span style="color: #008080;">function</span> <span style="color: #000000;">prettyr</span><span style="color: #0000FF;">(</span><span style="color: #004080;">sequence</span> <span style="color: #000000;">r</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #004080;">integer</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">n</span><span style="color: #0000FF;">,</span><span style="color: #000000;">d</span><span style="color: #0000FF;">}</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">r</span>
|
||||
<span style="color: #008080;">return</span> <span style="color: #008080;">iff</span><span style="color: #0000FF;">(</span><span style="color: #000000;">d</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span><span style="color: #0000FF;">?</span><span style="color: #7060A8;">sprintf</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"%d"</span><span style="color: #0000FF;">,</span><span style="color: #000000;">n</span><span style="color: #0000FF;">):</span><span style="color: #7060A8;">sprintf</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"%d/%d"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">n</span><span style="color: #0000FF;">,</span><span style="color: #000000;">d</span><span style="color: #0000FF;">}))</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
|
||||
|
||||
<span style="color: #004080;">sequence</span> <span style="color: #000000;">cw</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">calkin_wilf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">20</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"The first 20 terms of the Calkin-Wilf sequence are:\n"</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">20</span> <span style="color: #008080;">do</span>
|
||||
<span style="color: #004080;">string</span> <span style="color: #000000;">s</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">prettyr</span><span style="color: #0000FF;">(</span><span style="color: #000000;">cw</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]),</span>
|
||||
<span style="color: #000000;">r</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">prettyr</span><span style="color: #0000FF;">(</span><span style="color: #000000;">cf2r</span><span style="color: #0000FF;">(</span><span style="color: #000000;">i_to_cf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">i</span><span style="color: #0000FF;">)))</span>
|
||||
<span style="color: #004080;">integer</span> <span style="color: #000000;">t</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">get_term_number</span><span style="color: #0000FF;">(</span><span style="color: #000000;">to_continued_fraction</span><span style="color: #0000FF;">(</span><span style="color: #000000;">cw</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]))</span>
|
||||
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"%2d: %-4s [==> %2d: %-3s]\n"</span><span style="color: #0000FF;">,</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">i</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">s</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">t</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">r</span><span style="color: #0000FF;">})</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
|
||||
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"\n"</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #004080;">sequence</span> <span style="color: #000000;">r</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">83116</span><span style="color: #0000FF;">,</span><span style="color: #000000;">51639</span><span style="color: #0000FF;">}</span>
|
||||
<span style="color: #004080;">sequence</span> <span style="color: #000000;">cf</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">to_continued_fraction</span><span style="color: #0000FF;">(</span><span style="color: #000000;">r</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #004080;">integer</span> <span style="color: #000000;">tn</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">get_term_number</span><span style="color: #0000FF;">(</span><span style="color: #000000;">cf</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"%d/%d is the %,d%s term of the sequence.\n"</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">r</span><span style="color: #0000FF;">&{</span><span style="color: #000000;">tn</span><span style="color: #0000FF;">,</span><span style="color: #7060A8;">ord</span><span style="color: #0000FF;">(</span><span style="color: #000000;">tn</span><span style="color: #0000FF;">)})</span>
|
||||
<!--
|
||||
13
Task/Calkin-Wilf-sequence/Prolog/calkin-wilf-sequence.pro
Normal file
13
Task/Calkin-Wilf-sequence/Prolog/calkin-wilf-sequence.pro
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
% John Devou: 26-Nov-2021
|
||||
|
||||
% g(N,X):- consecutively generate in X the first N elements of the Calkin-Wilf sequence
|
||||
|
||||
g(N,[A/B|_]-_,A/B):- N > 0.
|
||||
g(N,[A/B|Ls]-[A/C,C/B|Ys],X):- N > 1, M is N-1, C is A+B, g(M,Ls-Ys,X).
|
||||
g(N,X):- g(N,[1/1|Ls]-Ls,X).
|
||||
|
||||
% t(A/B,X):- generate in X the index of A/B in the Calkin-Wilf sequence
|
||||
|
||||
t(A/1,S,C,X):- X is C*(2**(A-1+S)-S).
|
||||
t(A/B,S,C,X):- B > 1, divmod(A,B,M,N), T is 1-S, D is C*2**M, t(B/N,T,D,Y), X is Y + S*C*(2**M-1).
|
||||
t(A/B,X):- t(A/B,1,1,X), !.
|
||||
31
Task/Calkin-Wilf-sequence/Python/calkin-wilf-sequence.py
Normal file
31
Task/Calkin-Wilf-sequence/Python/calkin-wilf-sequence.py
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
from fractions import Fraction
|
||||
from math import floor
|
||||
from itertools import islice, groupby
|
||||
|
||||
|
||||
def cw():
|
||||
a = Fraction(1)
|
||||
while True:
|
||||
yield a
|
||||
a = 1 / (2 * floor(a) + 1 - a)
|
||||
|
||||
def r2cf(rational):
|
||||
num, den = rational.numerator, rational.denominator
|
||||
while den:
|
||||
num, (digit, den) = den, divmod(num, den)
|
||||
yield digit
|
||||
|
||||
def get_term_num(rational):
|
||||
ans, dig, pwr = 0, 1, 0
|
||||
for n in r2cf(rational):
|
||||
for _ in range(n):
|
||||
ans |= dig << pwr
|
||||
pwr += 1
|
||||
dig ^= 1
|
||||
return ans
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
print('TERMS 1..20: ', ', '.join(str(x) for x in islice(cw(), 20)))
|
||||
x = Fraction(83116, 51639)
|
||||
print(f"\n{x} is the {get_term_num(x):_}'th term.")
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
[ $ "bigrat.qky" loadfile ] now!
|
||||
|
||||
[ ' [ [ 1 1 ] ]
|
||||
swap 1 - times
|
||||
[ dup -1 peek do
|
||||
2dup proper 2drop
|
||||
2 * n->v
|
||||
2swap -v 1 n->v v+ v+
|
||||
1/v join nested join ] ] is calkin-wilf ( n --> [ )
|
||||
|
||||
[ 1 & ] is odd ( n --> b )
|
||||
|
||||
[ dup size odd not if
|
||||
[ -1 split do
|
||||
1 - join
|
||||
1 join ] ] is oddcf ( [ --> [ )
|
||||
|
||||
[ 0 swap
|
||||
reverse witheach
|
||||
[ i odd iff
|
||||
<< done
|
||||
dup dip <<
|
||||
bit 1 - | ] ] is rl->n ( [ --> n )
|
||||
|
||||
[ cf oddcf rl->n ] is cw-term ( n/d --> n )
|
||||
|
||||
20 calkin-wilf
|
||||
witheach
|
||||
[ do vulgar$ echo$ sp ]
|
||||
cr cr
|
||||
83116 51639 cw-term echo
|
||||
50
Task/Calkin-Wilf-sequence/REXX/calkin-wilf-sequence.rexx
Normal file
50
Task/Calkin-Wilf-sequence/REXX/calkin-wilf-sequence.rexx
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
/*REXX pgm finds the Nth value of the Calkin─Wilf sequence (which will be a fraction),*/
|
||||
/*────────────────────── or finds which sequence number contains a specified fraction). */
|
||||
numeric digits 2000 /*be able to handle ginormic integers. */
|
||||
parse arg LO HI te . /*obtain optional arguments from the CL*/
|
||||
if LO=='' | LO=="," then LO= 1 /*Not specified? Then use the default.*/
|
||||
if HI=='' | HI=="," then HI= 20 /* " " " " " " */
|
||||
if te=='' | te=="," then te= '/' /* " " " " " " */
|
||||
if datatype(LO, 'W') then call CW_terms /*Is LO numeric? Then show some terms.*/
|
||||
if pos('/', te)>0 then call CW_frac te /*Does TE have a / ? Then find term #*/
|
||||
exit 0
|
||||
/*──────────────────────────────────────────────────────────────────────────────────────*/
|
||||
commas: parse arg ?; do jc=length(?)-3 to 1 by -3; ?=insert(',', ?, jc); end; return ?
|
||||
th: parse arg th; return word('th st nd rd', 1+(th//10) *(th//100%10\==1) *(th//10<4))
|
||||
/*──────────────────────────────────────────────────────────────────────────────────────*/
|
||||
CW_frac: procedure; parse arg p '/' q .; say
|
||||
if q=='' then do; p= 83116; q= 51639; end
|
||||
n= rle2dec( frac2cf(p q) ); @CWS= 'the Calkin─Wilf sequence'
|
||||
say 'for ' p"/"q', the element number for' @CWS "is: " commas(n)th(n)
|
||||
if length(n)<10 then return
|
||||
say; say 'The above number has ' commas(length(n)) " decimal digits."
|
||||
return
|
||||
/*──────────────────────────────────────────────────────────────────────────────────────*/
|
||||
CW_term: procedure; parse arg z; dd= 1; nn= 0
|
||||
do z
|
||||
parse value dd dd*(2*(nn%dd)+1)-nn with nn dd
|
||||
end /*z*/
|
||||
return nn'/'dd
|
||||
/*──────────────────────────────────────────────────────────────────────────────────────*/
|
||||
CW_terms: $=; if LO\==0 then do j=LO to HI; $= $ CW_term(j)','
|
||||
end /*j*/
|
||||
if $=='' then return
|
||||
say 'Calkin─Wilf sequence terms for ' commas(LO) " ──► " commas(HI) ' are:'
|
||||
say strip( strip($), 'T', ",")
|
||||
return
|
||||
/*──────────────────────────────────────────────────────────────────────────────────────*/
|
||||
frac2cf: procedure; parse arg p q; if q=='' then return p; cf= p % q; m= q
|
||||
p= p - cf*q; n= p; if p==0 then return cf
|
||||
do k=1 until n==0; @.k= m % n
|
||||
m= m - @.k * n; parse value n m with m n /*swap N M*/
|
||||
end /*k*/
|
||||
/*for inverse Calkin─Wilf, K must be even.*/
|
||||
if k//2 then do; @.k= @.k - 1; k= k + 1; @.k= 1; end
|
||||
do k=1 for k; cf= cf @.k; end /*k*/
|
||||
return cf
|
||||
/*──────────────────────────────────────────────────────────────────────────────────────*/
|
||||
rle2dec: procedure; parse arg f1 rle; obin= copies(1, f1)
|
||||
do until rle==''; parse var rle f0 f1 rle
|
||||
obin= copies(1, f1)copies(0, f0)obin
|
||||
end /*until*/
|
||||
return x2d( b2x(obin) ) /*RLE2DEC: Run Length Encoding ──► decimal*/
|
||||
32
Task/Calkin-Wilf-sequence/Raku/calkin-wilf-sequence.raku
Normal file
32
Task/Calkin-Wilf-sequence/Raku/calkin-wilf-sequence.raku
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
my @calkin-wilf = Any, 1, {1 / (.Int × 2 + 1 - $_)} … *;
|
||||
|
||||
# Rational to Calkin-Wilf index
|
||||
sub r2cw (Rat $rat) { :2( join '', flat (flat (1,0) xx *) Zxx reverse r2cf $rat ) }
|
||||
|
||||
# The task
|
||||
|
||||
say "First twenty terms of the Calkin-Wilf sequence: ",
|
||||
@calkin-wilf[1..20]».&prat.join: ', ';
|
||||
|
||||
say "\n99991st through 100000th: ",
|
||||
(my @tests = @calkin-wilf[99_991 .. 100_000])».&prat.join: ', ';
|
||||
|
||||
say "\nCheck reversibility: ", @tests».Rat».&r2cw.join: ', ';
|
||||
|
||||
say "\n83116/51639 is at index: ", r2cw 83116/51639;
|
||||
|
||||
|
||||
# Helper subs
|
||||
sub r2cf (Rat $rat is copy) { # Rational to continued fraction
|
||||
gather loop {
|
||||
$rat -= take $rat.floor;
|
||||
last if !$rat;
|
||||
$rat = 1 / $rat;
|
||||
}
|
||||
}
|
||||
|
||||
sub prat ($num) { # pretty Rat
|
||||
return $num unless $num ~~ Rat|FatRat;
|
||||
return $num.numerator if $num.denominator == 1;
|
||||
$num.nude.join: '/';
|
||||
}
|
||||
20
Task/Calkin-Wilf-sequence/Ruby/calkin-wilf-sequence.rb
Normal file
20
Task/Calkin-Wilf-sequence/Ruby/calkin-wilf-sequence.rb
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
cw = Enumerator.new do |y|
|
||||
y << a = 1.to_r
|
||||
loop { y << a = 1/(2*a.floor + 1 - a) }
|
||||
end
|
||||
|
||||
def term_num(rat)
|
||||
num, den, res, pwr, dig = rat.numerator, rat.denominator, 0, 0, 1
|
||||
while den > 0
|
||||
num, (digit, den) = den, num.divmod(den)
|
||||
digit.times do
|
||||
res |= dig << pwr
|
||||
pwr += 1
|
||||
end
|
||||
dig ^= 1
|
||||
end
|
||||
res
|
||||
end
|
||||
|
||||
puts cw.take(20).join(", ")
|
||||
puts term_num (83116/51639r)
|
||||
54
Task/Calkin-Wilf-sequence/Rust/calkin-wilf-sequence.rust
Normal file
54
Task/Calkin-Wilf-sequence/Rust/calkin-wilf-sequence.rust
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
// [dependencies]
|
||||
// num = "0.3"
|
||||
|
||||
use num::rational::Rational;
|
||||
|
||||
fn calkin_wilf_next(term: &Rational) -> Rational {
|
||||
Rational::from_integer(1) / (Rational::from_integer(2) * term.floor() + 1 - term)
|
||||
}
|
||||
|
||||
fn continued_fraction(r: &Rational) -> Vec<isize> {
|
||||
let mut a = *r.numer();
|
||||
let mut b = *r.denom();
|
||||
let mut result = Vec::new();
|
||||
loop {
|
||||
let (q, r) = num::integer::div_rem(a, b);
|
||||
result.push(q);
|
||||
a = b;
|
||||
b = r;
|
||||
if a == 1 {
|
||||
break;
|
||||
}
|
||||
}
|
||||
let len = result.len();
|
||||
if len != 0 && len % 2 == 0 {
|
||||
result[len - 1] -= 1;
|
||||
result.push(1);
|
||||
}
|
||||
result
|
||||
}
|
||||
|
||||
fn term_number(r: &Rational) -> usize {
|
||||
let mut result: usize = 0;
|
||||
let mut d: usize = 1;
|
||||
let mut p: usize = 0;
|
||||
for n in continued_fraction(r) {
|
||||
for _ in 0..n {
|
||||
result |= d << p;
|
||||
p += 1;
|
||||
}
|
||||
d ^= 1;
|
||||
}
|
||||
result
|
||||
}
|
||||
|
||||
fn main() {
|
||||
println!("First 20 terms of the Calkin-Wilf sequence are:");
|
||||
let mut term = Rational::from_integer(1);
|
||||
for i in 1..=20 {
|
||||
println!("{:2}: {}", i, term);
|
||||
term = calkin_wilf_next(&term);
|
||||
}
|
||||
let r = Rational::new(83116, 51639);
|
||||
println!("{} is the {}th term of the sequence.", r, term_number(&r));
|
||||
}
|
||||
34
Task/Calkin-Wilf-sequence/Scheme/calkin-wilf-sequence-1.ss
Normal file
34
Task/Calkin-Wilf-sequence/Scheme/calkin-wilf-sequence-1.ss
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
; Create a terminating Continued Fraction generator for the given rational number.
|
||||
; Returns one term per call; returns #f when no more terms remaining.
|
||||
(define make-continued-fraction-gen
|
||||
(lambda (rat)
|
||||
(let ((num (numerator rat)) (den (denominator rat)))
|
||||
(lambda ()
|
||||
(if (= den 0)
|
||||
#f
|
||||
(let ((ret (quotient num den))
|
||||
(rem (modulo num den)))
|
||||
(set! num den)
|
||||
(set! den rem)
|
||||
ret))))))
|
||||
|
||||
; Return the continued fraction representation of a rational number as a list of terms.
|
||||
(define rat->cf-list
|
||||
(lambda (rat)
|
||||
(let ((cf (make-continued-fraction-gen rat))
|
||||
(lst '()))
|
||||
(let loop ((term (cf)))
|
||||
(when term
|
||||
(set! lst (append lst (list term)))
|
||||
(loop (cf))))
|
||||
lst)))
|
||||
|
||||
; Enforce the length of the given continued fraction list to be odd.
|
||||
; Changes the list in situ (if needed), and returns its possibly changed value.
|
||||
(define continued-fraction-list-enforce-odd-length!
|
||||
(lambda (cf)
|
||||
(when (even? (length cf))
|
||||
(let ((cf-last-cons (list-tail cf (1- (length cf)))))
|
||||
(set-car! cf-last-cons (1- (car cf-last-cons)))
|
||||
(set-cdr! cf-last-cons (cons 1 '()))))
|
||||
cf))
|
||||
35
Task/Calkin-Wilf-sequence/Scheme/calkin-wilf-sequence-2.ss
Normal file
35
Task/Calkin-Wilf-sequence/Scheme/calkin-wilf-sequence-2.ss
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
; Create a Calkin-Wilf sequence generator.
|
||||
(define make-calkin-wilf-gen
|
||||
(lambda ()
|
||||
(let ((an 1))
|
||||
(lambda ()
|
||||
(let ((ret an))
|
||||
(set! an (/ 1 (+ (* 2 (floor an)) 1 (- an))))
|
||||
ret)))))
|
||||
|
||||
; Return the position in the Calkin-Wilf sequence of the given rational number.
|
||||
(define calkin-wilf-position
|
||||
(lambda (rat)
|
||||
; Run-length encodes binary value. Assumes first run is 1's. Args: initial value,
|
||||
; starting place value (a power of 2), and list of run lengths (list must be odd length).
|
||||
(define encode-list-of-runs
|
||||
(lambda (value placeval lstruns)
|
||||
; Encode a single run in a binary value. Args: initial value, bit value (0 or 1),
|
||||
; starting place value (a power of 2), number of places (bits) to encode.
|
||||
; Returns multiple values: the encoded value, and the new place value.
|
||||
(define encode-run
|
||||
(lambda (value bitval placeval places)
|
||||
(if (= places 1)
|
||||
(values (+ value (* bitval placeval)) (* 2 placeval))
|
||||
(encode-run (+ value (* bitval placeval)) bitval (* 2 placeval) (1- places)))))
|
||||
; Loop through the list of runs two at a time. If list of length 1, do a final
|
||||
; '1'-bit encode and return the value. Otherwise, do a '1'-bit then '0'-bit encode,
|
||||
; and recurse to do the next two runs.
|
||||
(let-values (((value-1 placeval-1) (encode-run value 1 placeval (car lstruns))))
|
||||
(if (= 1 (length lstruns))
|
||||
value-1
|
||||
(let-values (((value-2 placeval-2) (encode-run value-1 0 placeval-1 (cadr lstruns))))
|
||||
(encode-list-of-runs value-2 placeval-2 (cddr lstruns)))))))
|
||||
; Return the run-length binary encoding from the odd-length Calkin-Wilf sequence of the
|
||||
; given rational number. This is equal to the number's position in the sequence.
|
||||
(encode-list-of-runs 0 1 (continued-fraction-list-enforce-odd-length! (rat->cf-list rat)))))
|
||||
12
Task/Calkin-Wilf-sequence/Scheme/calkin-wilf-sequence-3.ss
Normal file
12
Task/Calkin-Wilf-sequence/Scheme/calkin-wilf-sequence-3.ss
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
(let ((count 20)
|
||||
(cw (make-calkin-wilf-gen)))
|
||||
(printf "~%First ~a terms of the Calkin-Wilf sequence:~%" count)
|
||||
(do ((num 1 (1+ num)))
|
||||
((> num count))
|
||||
(printf "~2d : ~a~%" num (cw))))
|
||||
|
||||
(printf "~%Positions in Calkin-Wilf sequence of given numbers:~%")
|
||||
(let ((num 9/4))
|
||||
(printf "~a @ ~a~%" num (calkin-wilf-position num)))
|
||||
(let ((num 83116/51639))
|
||||
(printf "~a @ ~a~%" num (calkin-wilf-position num)))
|
||||
21
Task/Calkin-Wilf-sequence/Sidef/calkin-wilf-sequence.sidef
Normal file
21
Task/Calkin-Wilf-sequence/Sidef/calkin-wilf-sequence.sidef
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
func calkin_wilf(n) is cached {
|
||||
return 1 if (n == 1)
|
||||
1/(2*floor(__FUNC__(n-1)) + 1 - __FUNC__(n-1))
|
||||
}
|
||||
|
||||
func r2cw(r) {
|
||||
|
||||
var cfrac = r.as_cfrac
|
||||
cfrac.len.is_odd || return nil
|
||||
|
||||
Num(cfrac.flip.map_kv {|k,v| (k.is_odd ? '0' : '1') * v }.join, 2)
|
||||
}
|
||||
|
||||
with (20) {|n|
|
||||
say "First #{n} terms of the Calkin-Wilf sequence:"
|
||||
say calkin_wilf.map(1..n)
|
||||
}
|
||||
|
||||
with (83116/51639) {|r|
|
||||
say ("\n#{r.as_rat} is at index: ", r2cw(r))
|
||||
}
|
||||
86
Task/Calkin-Wilf-sequence/V-(Vlang)/calkin-wilf-sequence.v
Normal file
86
Task/Calkin-Wilf-sequence/V-(Vlang)/calkin-wilf-sequence.v
Normal file
|
|
@ -0,0 +1,86 @@
|
|||
import math.fractions
|
||||
import math
|
||||
import strconv
|
||||
|
||||
fn calkin_wilf(n int) []fractions.Fraction {
|
||||
mut cw := []fractions.Fraction{len: n+1}
|
||||
cw[0] = fractions.fraction(1, 1)
|
||||
one := fractions.fraction(1, 1)
|
||||
two := fractions.fraction(2, 1)
|
||||
for i in 1..n {
|
||||
mut t := cw[i-1]
|
||||
mut f := t.f64()
|
||||
f = math.floor(f)
|
||||
t = fractions.approximate(f)
|
||||
t*=two
|
||||
t-= cw[i-1]
|
||||
t+=one
|
||||
t=t.reciprocal()
|
||||
cw[i] = t
|
||||
}
|
||||
return cw
|
||||
}
|
||||
|
||||
fn to_continued(r fractions.Fraction) []int {
|
||||
idx := r.str().index('/') or {0}
|
||||
mut a := r.str()[..idx].i64()
|
||||
mut b := r.str()[idx+1..].i64()
|
||||
mut res := []int{}
|
||||
for {
|
||||
res << int(a/b)
|
||||
t := a % b
|
||||
a, b = b, t
|
||||
if a == 1 {
|
||||
break
|
||||
}
|
||||
}
|
||||
le := res.len
|
||||
if le%2 == 0 { // ensure always odd
|
||||
res[le-1]--
|
||||
res << 1
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
fn get_term_number(cf []int) ?int {
|
||||
mut b := ""
|
||||
mut d := "1"
|
||||
for n in cf {
|
||||
b = d.repeat(n)+b
|
||||
if d == "1" {
|
||||
d = "0"
|
||||
} else {
|
||||
d = "1"
|
||||
}
|
||||
}
|
||||
i := strconv.parse_int(b, 2, 64)?
|
||||
return int(i)
|
||||
}
|
||||
|
||||
fn commatize(n int) string {
|
||||
mut s := "$n"
|
||||
if n < 0 {
|
||||
s = s[1..]
|
||||
}
|
||||
le := s.len
|
||||
for i := le - 3; i >= 1; i -= 3 {
|
||||
s = s[0..i] + "," + s[i..]
|
||||
}
|
||||
if n >= 0 {
|
||||
return s
|
||||
}
|
||||
return "-" + s
|
||||
}
|
||||
|
||||
fn main() {
|
||||
cw := calkin_wilf(20)
|
||||
println("The first 20 terms of the Calkin-Wilf sequnence are:")
|
||||
for i := 1; i <= 20; i++ {
|
||||
println("${i:2}: ${cw[i-1]}")
|
||||
}
|
||||
println('')
|
||||
r := fractions.fraction(83116, 51639)
|
||||
cf := to_continued(r)
|
||||
tn := get_term_number(cf) or {0}
|
||||
println("$r is the ${commatize(tn)}th term of the sequence.")
|
||||
}
|
||||
50
Task/Calkin-Wilf-sequence/Wren/calkin-wilf-sequence.wren
Normal file
50
Task/Calkin-Wilf-sequence/Wren/calkin-wilf-sequence.wren
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
import "/rat" for Rat
|
||||
import "/fmt" for Fmt, Conv
|
||||
|
||||
var calkinWilf = Fn.new { |n|
|
||||
var cw = List.filled(n, null)
|
||||
cw[0] = Rat.one
|
||||
for (i in 1...n) {
|
||||
var t = cw[i-1].floor * 2 - cw[i-1] + 1
|
||||
cw[i] = Rat.one / t
|
||||
}
|
||||
return cw
|
||||
}
|
||||
|
||||
var toContinued = Fn.new { |r|
|
||||
var a = r.num
|
||||
var b = r.den
|
||||
var res = []
|
||||
while (true) {
|
||||
res.add((a/b).floor)
|
||||
var t = a % b
|
||||
a = b
|
||||
b = t
|
||||
if (a == 1) break
|
||||
}
|
||||
if (res.count%2 == 0) { // ensure always odd
|
||||
res[-1] = res[-1] - 1
|
||||
res.add(1)
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
var getTermNumber = Fn.new { |cf|
|
||||
var b = ""
|
||||
var d = "1"
|
||||
for (n in cf) {
|
||||
b = (d * n) + b
|
||||
d = (d == "1") ? "0" : "1"
|
||||
}
|
||||
return Conv.atoi(b, 2)
|
||||
}
|
||||
|
||||
var cw = calkinWilf.call(20)
|
||||
System.print("The first 20 terms of the Calkin-Wilf sequence are:")
|
||||
Rat.showAsInt = true
|
||||
for (i in 1..20) Fmt.print("$2d: $s", i, cw[i-1])
|
||||
System.print()
|
||||
var r = Rat.new(83116, 51639)
|
||||
var cf = toContinued.call(r)
|
||||
var tn = getTermNumber.call(cf)
|
||||
Fmt.print("$s is the $,r term of the sequence.", r, tn)
|
||||
Loading…
Add table
Add a link
Reference in a new issue