2016 Update
This commit is contained in:
parent
948b86eafa
commit
dcf5d15da3
7965 changed files with 139854 additions and 31002 deletions
|
|
@ -39,14 +39,17 @@ A ''hint'' at a way to generate members of the sequence is to modify a routine u
|
|||
the above showing that <code>11</code> in decimal is <math>1\times 2^3 + 0\times 2^2 + 1\times 2^1 + 1\times 2^0</math>.<br>
|
||||
Reflected this would become <code>.1101</code> or <math>1\times 2^{-1} + 1\times 2^{-2} + 0\times 2^{-3} + 1\times 2^{-4}</math>
|
||||
|
||||
'''Task Description'''
|
||||
|
||||
;Task description:
|
||||
* Create a function/method/routine that given ''n'', generates the ''n'''th term of the van der Corput sequence in base 2.
|
||||
* Use the function to compute ''and display'' the first ten members of the sequence. (The first member of the sequence is for ''n''=0).
|
||||
|
||||
* As a stretch goal/extra credit, compute and show members of the sequence for bases other than 2.
|
||||
|
||||
''See also''
|
||||
|
||||
|
||||
;See also:
|
||||
* [http://www.puc-rio.br/marco.ind/quasi_mc.html#low_discrep The Basic Low Discrepancy Sequences]
|
||||
* [[Non-decimal radices/Convert]]
|
||||
* [[wp:Van der Corput sequence|Van der Corput sequence]]
|
||||
<br><br>
|
||||
|
|
|
|||
|
|
@ -1,19 +1,34 @@
|
|||
defmodule Van_der_corput do
|
||||
def sequence( n ), do: sequence( n, 2 )
|
||||
|
||||
def sequence( 0, _base ), do: 0.0
|
||||
def sequence( n, base ) do
|
||||
List.to_float( '0.' ++ ( for x <- sequence_loop(n, base), do: Integer.to_char_list(x) ) |> List.flatten )
|
||||
def sequence( n, base \\ 2 ) do
|
||||
"0." <> (Integer.to_string(n, base) |> String.reverse )
|
||||
end
|
||||
|
||||
def sequence_loop( 0, _base ), do: []
|
||||
def sequence_loop( n, base ) do
|
||||
new_n = div(n, base)
|
||||
digit = rem(n, base)
|
||||
[digit | sequence_loop( new_n, base )]
|
||||
def float( n, base \\ 2 ) do
|
||||
Integer.digits(n, base) |> Enum.reduce(0, fn i,acc -> (i + acc) / base end)
|
||||
end
|
||||
|
||||
def fraction( n, base \\ 2 ) do
|
||||
str = Integer.to_string(n, base) |> String.reverse
|
||||
denominator = Enum.reduce(1..String.length(str), 1, fn _,acc -> acc*base end)
|
||||
reduction( String.to_integer(str, base), denominator )
|
||||
end
|
||||
|
||||
defp reduction( 0, _ ), do: "0"
|
||||
defp reduction( numerator, denominator ) do
|
||||
gcd = gcd( numerator, denominator )
|
||||
"#{ div(numerator, gcd) }/#{ div(denominator, gcd) }"
|
||||
end
|
||||
|
||||
defp gcd( a, 0 ), do: a
|
||||
defp gcd( a, b ), do: gcd( b, rem(a, b) )
|
||||
end
|
||||
|
||||
Enum.each(2..5, fn base ->
|
||||
IO.puts "Base #{base}: #{inspect Enum.map(0..9, fn x -> Van_der_corput.sequence(x, base) end)}"
|
||||
funs = [ {"Float(Base):", &Van_der_corput.sequence/2},
|
||||
{"Float(Decimal):", &Van_der_corput.float/2 },
|
||||
{"Fraction:", &Van_der_corput.fraction/2} ]
|
||||
Enum.each(funs, fn {title, fun} ->
|
||||
IO.puts title
|
||||
Enum.each(2..5, fn base ->
|
||||
IO.puts " Base #{ base }: #{ Enum.map_join(0..9, ", ", &fun.(&1, base)) }"
|
||||
end)
|
||||
end)
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
sub vdc($value, $base = 2) {
|
||||
my @values := $value, { $_ div $base } ... 0;
|
||||
my @denoms := $base, { $_ * $base } ... *;
|
||||
[+] do for @values Z @denoms -> $v, $d {
|
||||
my @values = $value, { $_ div $base } ... 0;
|
||||
my @denoms = $base, { $_ * $base } ... *;
|
||||
[+] do for (flat @values Z @denoms) -> $v, $d {
|
||||
$v mod $base / $d;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,16 +1,16 @@
|
|||
/*REXX pgm converts an integer (or a range)──►van der Corput # in base 2*/
|
||||
numeric digits 1000 /*handle anything the user wants.*/
|
||||
parse arg a b . /*obtain the number(s) [maybe]. */
|
||||
if a=='' then do; a=0; b=10; end /*if none specified, use defaults*/
|
||||
if b=='' then b=a /*assume a "range" of a single #.*/
|
||||
/*REXX program converts an integer (or a range) ──► a Van der Corput number in base 2.*/
|
||||
numeric digits 1000 /*handle almost anything the user wants*/
|
||||
parse arg a b . /*obtain the optional arguments from CL*/
|
||||
if a=='' then parse value 0 10 with a b /*Not specified? Then use the defaults*/
|
||||
if b=='' then b=a /*assume a range for a single number.*/
|
||||
|
||||
do j=a to b /*traipse through the range. */
|
||||
_=vdC(abs(j)) /*convert ABS value of integer.*/
|
||||
leading=substr('-',2+sign(j)) /*if needed, elide leading sign.*/
|
||||
say leading || _ /*show number (with leading - ?)*/
|
||||
do j=a to b /*traipse through the range of numbers.*/
|
||||
_=VdC( abs(j) ) /*convert absolute value of an integer.*/
|
||||
leading=substr('-', 2 + sign(j) ) /*if needed, elide the leading sign. */
|
||||
say leading || _ /*show number, with leading minus sign?*/
|
||||
end /*j*/
|
||||
exit /*stick a fork in it, we're done.*/
|
||||
/*──────────────────────────────────VDC [van der Corput] subroutine─────*/
|
||||
vdC: procedure; y=x2b(d2x(arg(1)))+0 /*convert to hex, then binary. */
|
||||
if y==0 then return 0 /*handle special case of zero. */
|
||||
else return '.'reverse(y) /*heavy lifting by REXX*/
|
||||
exit /*stick a fork in it, we're all done. */
|
||||
/*──────────────────────────────────────────────────────────────────────────────────────*/
|
||||
VdC: procedure; y=x2b( d2x( arg(1) ) ) + 0 /*convert to hexadecimal, then binary.*/
|
||||
if y==0 then return 0 /*handle the special case of zero. */
|
||||
else return '.'reverse(y) /*heavy lifting is performed by REXX. */
|
||||
|
|
|
|||
|
|
@ -1,56 +1,52 @@
|
|||
/*REXX pgm converts an integer (or a range) ──► van der Corput number */
|
||||
/*in base 2, or optionally, any other base up to and including base 90.*/
|
||||
numeric digits 1000 /*handle anything the user wants.*/
|
||||
parse arg a b r . /*obtain the number(s) [maybe]. */
|
||||
if a=='' then do; a=0; b=10; end /*if none specified, use defaults*/
|
||||
if b=='' then b=a /*assume a "range" of a single #.*/
|
||||
if r=='' then r=2 /*assume a radix (base) of 2. */
|
||||
z= /*placeholder for a list of nums.*/
|
||||
|
||||
do j=a to b /*traipse through the range. */
|
||||
_=vdC(abs(j), abs(r)) /*convert ABS value of integer.*/
|
||||
_=substr('-', 2+sign(j))_ /*if needed, keep leading - sign.*/
|
||||
if r>0 then say _ /*if positive base, just show it.*/
|
||||
else z=z _ /* ··· else build a list· */
|
||||
/*REXX program converts an integer (or a range) ──► a Van der Corput number, */
|
||||
/*─────────────── in base 2, or optionally, any other base up to and including base 90.*/
|
||||
numeric digits 1000 /*handle almost anything the user wants*/
|
||||
parse arg a b r . /*obtain optional arguments from the CL*/
|
||||
if a=='' | a=="," then parse value 0 10 with a b /*Not specified? Then use the defaults*/
|
||||
if b=='' | b=="," then b=a /* " " " " " " */
|
||||
if r=='' | r=="," then r=2 /* " " " " " " */
|
||||
z= /*a placeholder for a list of numbers. */
|
||||
do j=a to b /*traipse through the range of integers*/
|
||||
_=VdC( abs(j), abs(r) ) /*convert the ABSolute value of integer*/
|
||||
_=substr('-', 2+sign(j) )_ /*if needed, keep the leading - sign.*/
|
||||
if r>0 then say _ /*if positive base, then just show it. */
|
||||
else z=z _ /* ··· else append (build) a list. */
|
||||
end /*j*/
|
||||
|
||||
if z\=='' then say strip(z) /*if list wanted, then show it. */
|
||||
exit /*stick a fork in it, we're done.*/
|
||||
/*──────────────────────────────────BASE subroutine (up to base 90)─────*/
|
||||
base: procedure; parse arg x,toB,inB /*get a number, toBase, inBase */
|
||||
/*┌────────────────────────────────────────────────────────────────────┐
|
||||
┌─┘ Input to this subroutine (all must be positive whole numbers): └─┐
|
||||
│ │
|
||||
│ x (is required). │
|
||||
│ toBase the base to convert X to. │
|
||||
│ inBase the base X is expressed in. │
|
||||
│ │
|
||||
│ toBase or inBase can be omitted which causes the default of │
|
||||
└─┐ 10 to be used. The limits of both are: 2 ──► 90. ┌─┘
|
||||
└────────────────────────────────────────────────────────────────────┘*/
|
||||
@abc='abcdefghijklmnopqrstuvwxyz' /*Latin lowercase alphabet chars.*/
|
||||
@abcU=@abc; upper @abcU /*go whole hog and extend chars. */
|
||||
@@@=0123456789 || @abc || @abcU /*prefix 'em with numeric digits.*/
|
||||
@@@=@@@'<>[]{}()?~!@#$%^&*_+-=|\/;:~' /*add some special chars as well,*/
|
||||
/*spec. chars should be viewable.*/
|
||||
numeric digits 1000 /*what the hey, support biggies. */
|
||||
maxB=length(@@@) /*max base (radix) supported here*/
|
||||
parse arg x,toB,inB /*get a number, toBase, inBase */
|
||||
if toB=='' then toB=10 /*if skipped, assume default (10)*/
|
||||
if inB=='' then inB=10 /* " " " " " */
|
||||
/*══════════════════════════════════convert X from base inB ──► base 10.*/
|
||||
#=0; do j=1 for length(x)
|
||||
_=substr(x,j,1) /*pick off a "digit" from X. */
|
||||
v=pos(_,@@@) /*get the value of this "digits".*/
|
||||
if v==0 | v>inB then call erd x,j,inB /*illegal "digit" ? */
|
||||
#=#*inB + v - 1 /*construct new num, dig by dig. */
|
||||
end /*j*/
|
||||
/*══════════════════════════════════convert # from base 10 ──► base toB.*/
|
||||
y=; do while #>=toB /*deconstruct the new number (#).*/
|
||||
y=substr(@@@,(#//toB)+1,1)y /* construct the output number. */
|
||||
#=# % toB /*··· and whittle # down also. */
|
||||
end /*while*/
|
||||
if z\=='' then say strip(z) /*if a list is wanted, then display it.*/
|
||||
exit /*stick a fork in it, we're all done. */
|
||||
/*──────────────────────────────────────────────────────────────────────────────────────*/
|
||||
base: procedure; parse arg x, toB, inB /*get a number, toBase, and inBase. */
|
||||
/*┌───────────────────────────────────────────────────────────────────┐
|
||||
┌─┘ Input to this function: x (is required & must be an integer).└─┐
|
||||
│ toBase the base to convert X to. │
|
||||
│ inBase the base X is expressed in. │
|
||||
│ │
|
||||
│ toBase or inBase can be omitted which causes the default of 10 │
|
||||
└─┐ to be used. Both have a limit of: 2 ──► 90.┌─┘
|
||||
└───────────────────────────────────────────────────────────────────┘*/
|
||||
@abc= 'abcdefghijklmnopqrstuvwxyz' /*the Latin lowercase alphabet chars. */
|
||||
@abcU=@abc; upper @abcU /*go whole hog and extend characters. */
|
||||
@@@= 0123456789 || @abc || @abcU /*prefix them with some numeric digits.*/
|
||||
@@@= @@@'<>[]{}()?~!@#$%^&*_+-=|\/;:`' /*add some special characters as well, */
|
||||
/*special characters should be viewable*/
|
||||
numeric digits 1000 /*what the hey, support biggy numbers.*/
|
||||
maxB=length(@@@) /*maximum base (radix) supported here. */
|
||||
if toB=='' then toB=10 /*if skipped, then assume default (10)*/
|
||||
if inB=='' then inB=10 /* " " " " " " */
|
||||
#=0 /* [↓] convert base inB X ──► base 10*/
|
||||
do j=1 for length(x)
|
||||
_=substr(x, j, 1) /*pick off a "digit" (numeral) from X.*/
|
||||
v=pos(_, @@@) /*get the value of this "digit"/numeral*/
|
||||
if v==0|v>inB then call erd x,j,inB /*is it an illegal "digit" (numeral) ? */
|
||||
#=#*inB + v - 1 /*construct new number, digit by digit.*/
|
||||
end /*j*/
|
||||
y= /* [↓] convert base 10 # ──► base toB.*/
|
||||
do while #>=toB /*deconstruct the new number (#). */
|
||||
y=substr(@@@, #//toB + 1, 1)y /* construct the output number, ··· */
|
||||
#=# % toB /* ··· and also whittle down #. */
|
||||
end /*while*/
|
||||
|
||||
return substr(@@@,#+1,1)y
|
||||
/*──────────────────────────────────VDC [van der Corput] subroutine─────*/
|
||||
vdC: return '.'reverse(base(arg(1),arg(2))) /*convert, reverse, append.*/
|
||||
return substr(@@@, #+1, 1)y
|
||||
/*──────────────────────────────────────────────────────────────────────────────────────*/
|
||||
VdC: return '.'reverse(base(arg(1), arg(2))) /*convert the #, reverse the #, append.*/
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue