I'm trying to write an fsharp function to see if a number is an "armstrong" number:
A positive integer is an Armstrong number if it is equal to the sum of the cubes of its digits – e.g., the first such number is 1 and the second is 153.
for example. 1^3 + 5^3 + 3^3 = 153
is there a way in fsharp to extract the individual digits of a number so I can cube them and then add their cubed results together?
You can achieve this by plenty of ways and rich F# and .Net libraries are at your service.
For example, you may convert your candidate number to string, then to character array, then each array element back to digit getting individual digits of the original number as array:
let asDigitArray n =
n.ToString().ToCharArray()
|> Array.map (System.Char.GetNumericValue >> System.Convert.ToInt32)
Checking in FSI
> asDigitArray 12345;;
val it : int [] = [|1; 2; 3; 4; 5|]
Besides, this approach works not just for int, but for long and biginteger arguments too, so you may use asDigitArray function for investigating really big Armstrong number candidates:
> asDigitArray 1234567898765L;;
val it : int [] = [|1; 2; 3; 4; 5; 6; 7; 8; 9; 8; 7; 6; 5|]
> asDigitArray 112233445566778899I;;
val it : int [] = [|1; 1; 2; 2; 3; 3; 4; 4; 5; 5; 6; 6; 7; 7; 8; 8; 9; 9|]
Related
I have an Uint8List data list, for example:
Uint8List uintList = Uint8List.fromList([10, 1]);
How can I convert these numbers to a decimal number?
int decimalValue = ??? // in this case 265
Mees' answer is the correct general method, and it's good to understand how to do bitwise operations manually.
However, Dart does have a ByteData class that has various functions to help parse byte data for you (e.g. getInt16, getUint16). In your case, you can do:
Uint8List uintList = Uint8List.fromList([10, 1]);
int decimalValue = ByteData.view(uintList.buffer).getInt16(0, Endian.little);
print(decimalValue); // Prints: 266.
From what I understand of your question, you want decimalValue to be an integer where the least significant byte is (decimal)10, and the byte after that to be 1. This would result in the value 1 * 256 + 10 = 266. If you meant the bytes the other way around, it would be 10 * 256 + 1 = 2560 + 1 = 2561.
I don't actually have any experience with dart, but I assume code similar to this would work:
int decimalValue = 0;
for (int i = 0; i < uintList.length; i++) {
decimalValue = decimalValue << 8; // shift everything one byte to the left
decimalValue = decimalValue | uintList[i]; // bitwise or operation
}
If it doesn't produce the number you want it to, you might have to iterate through the loop backwards instead, which requires changing one line of code:
for (int i = uintList.length-1; i >= 0; i--) {
printfn "%A" [1..1000]
inside f# interactive shows
[1; 2; 3; 4; 5; 6; 7; 8; 9; 10; 11; 12; 13; 14; 15; 16; 17; 18; 19; 20; 21; 22;
23; 24; 25; 26; 27; 28; 29; 30; 31; 32; 33; 34; 35; 36; 37; 38; 39; 40; 41; 42;
43; 44; 45; 46; 47; 48; 49; 50; 51; 52; 53; 54; 55; 56; 57; 58; 59; 60; 61; 62;
63; 64; 65; 66; 67; 68; 69; 70; 71; 72; 73; 74; 75; 76; 77; 78; 79; 80; 81; 82;
83; 84; 85; 86; 87; 88; 89; 90; 91; 92; 93; 94; 95; 96; 97; 98; 99; 100; ...]
the following settings do not affect the number of list members shown
fsi.PrintSize <- 222 // no effect
fsi.PrintLength <- 222 // no effect
fsi.PrintDepth <- 222 // no effect
fsi.PrintWidth <- 222 // no effect
fsi.ShowIEnumerable <- true // no effect
Is it possible to configure the number of members shown inside f# interactive?
Is it possible t configure this such that (sprintf "%A") considers it outside of f# interactive?
i am asking this because i pretty print records, and currently some of the values are truncated. so the issue on top is to pretty print records without truncated values - just for context.
%A formatting has nice advantages as it nicely layouts records, which i do not want to loose by using StructuredFormatDisplayAttribute.
this formatting is part of formatting a large object with %A, which works perfectly, nicely without any effort. so i am not asking about really printing an isolated list.
inside the f# source:
checked the source code at https://github.com/dotnet/fsharp/blob/b23b2a0f99f12ece94c5ad89aabb9169d51091f3/src/fsharp/utils/sformat.fs
ObjectGraphFormatter apparently does the formatting, accepting format options.
the very last lines might be calling it:
let internal anyToStringForPrintf options (bindingFlags:BindingFlags) (value, typValue) =
let formatter = ObjectGraphFormatter(options, bindingFlags)
formatter.Format (ShowAll, value, typValue) |> layout_to_string options
which is called by toe core Printf module which in turn is internal.
I think I would just do this:
[1..1000]
|> List.take 50
|> List.iter (printf "%A;")
Good day.
What is the best way to create a sequence (maybe finite) or list by the formula below?
For example, from 1 to 9 it will be
1, 2, 4, 5, 10, 11, 22, 23, 46
I think List.fold or List.scan can be used there, but I don't know where to write yield.
The one thing I would add to Torbonde's answer is that it would be worth using the F# big integer literal.
For example, compare the below two answers:
//The integers rapidly become too large hence do not display correctly
let infseq =
(1,1)|>Seq.unfold(fun (x,i) ->
if (i%2 = 0)
then Some(x,(x*2,i+1))
else Some(x,(x+1,i+1)))
let first100 = infseq |>Seq.take(100)|>Array.ofSeq
let infseqBI =
(1I,1I)|>Seq.unfold(fun (x,i)->
if (i%2I = 0I)
then Some(x,(x*2I,i+1I))
else Some(x,(x+1I,i+1I)))
let first100BI = infseqBI |>Seq.take(100)|>Array.ofSeq
val first100 : int [] =
[|1; 2; 4; 5; 10; 11; 22; 23; 46; 47; 94; 95; 190; 191; 382; 383; 766; 767;
1534; 1535; 3070; 3071; 6142; 6143; 12286; 12287; 24574; 24575; 49150;
49151; 98302; 98303; 196606; 196607; 393214; 393215; 786430; 786431;
1572862; 1572863; 3145726; 3145727; 6291454; 6291455; 12582910; 12582911;
25165822; 25165823; 50331646; 50331647; 100663294; 100663295; 201326590;
201326591; 402653182; 402653183; 805306366; 805306367; 1610612734;
1610612735; -1073741826; -1073741825; 2147483646; 2147483647; -2; -1; -2;
-1; -2; -1; -2; -1; -2; -1; -2; -1; -2; -1; -2; -1; -2; -1; -2; -1; -2; -1;
-2; -1; -2; -1; -2; -1; -2; -1; -2; -1; -2; -1; -2; -1|]
val first100BI : System.Numerics.BigInteger [] =
[|1; 2; 4; 5; 10; 11; 22; 23; 46; 47; 94; 95; 190; 191; 382; 383; 766; 767;
1534; 1535; 3070; 3071; 6142; 6143; 12286; 12287; 24574; 24575; 49150;
49151; 98302; 98303; 196606; 196607; 393214; 393215; 786430; 786431;
1572862; 1572863; 3145726; 3145727; 6291454; 6291455; 12582910; 12582911;
25165822; 25165823; 50331646; 50331647; 100663294; 100663295; 201326590;
201326591; 402653182; 402653183; 805306366; 805306367; 1610612734;
1610612735; 3221225470; 3221225471; 6442450942; 6442450943; 12884901886;
12884901887; 25769803774; 25769803775; 51539607550; 51539607551;
103079215102; 103079215103; 206158430206; 206158430207; 412316860414;
412316860415; 824633720830; 824633720831; 1649267441662; 1649267441663;
3298534883326; 3298534883327; 6597069766654; 6597069766655; 13194139533310;
13194139533311; 26388279066622; 26388279066623; 52776558133246;
52776558133247; 105553116266494; 105553116266495; 211106232532990;
211106232532991; 422212465065982; 422212465065983; 844424930131966;
844424930131967; 1688849860263934; 1688849860263935|]
You could do it using a mutable value and a for loop. Alternatively, it is possible to use unfold:
Seq.unfold (fun (a,i) ->
let a' =
if i % 2 = 0
then a*2
else a+1
Some (a', (a',i+1)))
(1,1)
|> Seq.append [1]
You could use a sequence expression recursively:
let rec aSeq a =
seq { yield! [a; a + 1]
yield! aSeq (2 * (a + 1)) }
Inside a sequence expression, yield! embeds another sequence. The code above creates the sequence starting at an odd i and any a. To get the complete sequence, initialize to 1:
let mySeq = aSeq 1
For a finite sequence, you can use Seq.take:
mySeq |> Seq.take 9
This results in the sequence 1; 2; 4; 5; 10; 11; 22; 23; 46.
I have a real 2d matrix. I am taking its fft using fftw. But the result of using a real to complex fft is different from a complex ( with imaginary part equal to zero) to complex fft.
real matrix
0 1 2
3 4 5
6 7 8
result of real to complex fft
36 -4.5+2.59808i -13.5+7.79423i
0 -13.5-7.79423i 0
0 0 0
Code:
int r = 3, c = 3;
int sz = r * c;
double *in = (double*) malloc(sizeof(double) * sz);
fftw_complex *out = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * sz);
fftw_plan p = fftw_plan_dft_r2c_2d(r, c, in, out, FFTW_MEASURE);
for ( int i=0; i<r; ++i ){
for ( int j=0; j<c; ++j ){
in[i*c+j] = i*c + j;
}
}
fftw_execute(p);
using a complex matrix with imaginary part of zero
complex matrix
0+0i 1+0i 2+0i
3+0i 4+0i 5+0i
6+0i 7+0i 8+0i
result of complex to complex fft
36 -4.5 + 2.59808i -4.5 - 2.59808i
-13.5 + 7.79423i 0 0
-13.5 - 7.79423i 0 0
Code:
int r = 3, c = 3;
int sz = r * c;
fftw_complex *out = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * sz);
fftw_complex *inc = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * sz);
p = fftw_plan_dft_2d( r,c, inc, out, FFTW_FORWARD,FFTW_MEASURE);
for ( int i=0; i<r; ++i ){
for ( int j=0; j<c; ++j ){
inc[i*c+j][0] = i*c+j;
inc[i*c+j][1] = 0;
}
}
fftw_execute(p);
I am after the result of complex to complex fft. But the real to complex fft is much faster and my data is real. Am I making a programming mistake or the result should be different?
As indicated in FFTW documentation
Then, after an r2c transform, the output is an n0 × n1 × n2 × … × (nd-1/2 + 1) array of fftw_complex values in row-major order
In other words, the output for your real-to-complex transform of your sample real matrix really is:
36 -4.5+2.59808i
-13.5+7.79423i 0
-13.5-7.79423i 0
You may notice that these two columns match exactly the first two columns of your complex-to-complex transform. The missing column is omitted from the real-to-complex transform since it is redundant due to symmetry. As such, the full 3x3 matrix including the missing column could be constructed using:
fftw_complex *outfull = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * sz);
int outc = (c/2+1);
for ( int i=0; i<r; ++i ){
// copy existing columns
for ( int j=0; j<outc; ++j ){
outfull[i*c+j][0] = out[i*outc+j][0];
outfull[i*c+j][1] = out[i*outc+j][1];
}
// generate missing column(s) from symmetry
for ( int j=outc; j<c; ++j){
int row = (r-i)%r;
int col = c-j;
outfull[i*c+j][0] = out[row*outc+col][0];
outfull[i*c+j][1] = -out[row*outc+col][1];
}
}
(Edited)
I'm trying to parallelize a function to solve a LCS, via the usage of a Parallel.For loop. This function proceeds by diagonals, obtaining the value of the current diagonal cell based on the previous ones.
The sequential function is as follows:
let public lcs_seq_1d_diags (x:char[]) (y:char[]) =
let m = x.Length
let n = y.Length
let mutable dk2 = Array.create (1+m) 0
let mutable dk1 = Array.create (1+m) 0
let mutable dk = Array.create (1+m) 0
for k = 2 to m+n do
let low = max 1 (k-m)
let high = min (k-1) n
for j = low to high do
let i = k - j
if x.[i-1] = y.[j-1] then
dk.[i] <- dk2.[i-1] + 1
else
dk.[i] <- max dk1.[i] dk1.[i-1]
let mutable temp = dk2
dk2 <- dk1
dk1 <- dk
dk <- temp
dk1.[m]
My attempt at parallelization:
let public lcs_par_1d_seq (x:char[]) (y:char[]) =
let m = x.Length
let n = y.Length
let dk2 = Array.create (1+m) 0
let cell2 = ref dk2
printfn "\r\n0: %A" dk2
let dk1 = Array.create (1+m) 0
let cell1 = ref dk1
printfn "1: %A" dk1
let dk = Array.create (1+m) 0
let cell = ref dk
for k = 2 to m+n do
let low = max 1 (k-m)
let high = min (k-1) n
//for each cell in current diagonal
Parallel.For(low, high, (fun j ->
let i = k - j
if x.[i-1] = y.[j-1] then
dk.[i] <- dk2.[i-1] + 1
else
dk.[i] <- max dk1.[i] dk1.[i-1])) |> ignore
if trace then
let ilow = k - high
let ihigh = k - low
printfn "k=%d i=%d..%d dk=%A" k ilow ihigh dk.[ilow..ihigh]
let mutable temp = !cell2
cell2 := !cell1
cell1 := !cell
cell := temp
dk1.[m]
Trace results for the sequential loop:
0: [|0; 0; 0; 0; 0; 0; 0|]
1: [|0; 0; 0; 0; 0; 0; 0|]
k=2 i=1..1 dk=[|0|]
k=3 i=1..2 dk=[|0; 0|]
k=4 i=1..3 dk=[|1; 1; 1|]
k=5 i=1..4 dk=[|1; 1; 1; 1|]
k=6 i=1..5 dk=[|1; 1; 1; 1; 1|]
k=7 i=1..6 dk=[|1; 2; 2; 1; 2; 1|]
k=8 i=1..6 dk=[|1; 2; 2; 2; 2; 2|]
k=9 i=1..6 dk=[|1; 2; 2; 2; 2; 2|]
k=10 i=1..6 dk=[|1; 2; 2; 2; 3; 2|]
k=11 i=2..6 dk=[|2; 2; 2; 3; 3|]
k=12 i=3..6 dk=[|2; 2; 3; 3|]
k=13 i=4..6 dk=[|2; 3; 3|]
k=14 i=5..6 dk=[|3; 4|]
k=15 i=6..6 dk=[|4|]
... duration: 19 ms
res_seq_1d_diags = 4
Press any key to continue . . .
Trace results for the parallel loop:
0: [|0; 0; 0; 0; 0; 0; 0|]
1: [|0; 0; 0; 0; 0; 0; 0|]
k=2 i=1..1 dk=[|0|]
k=3 i=1..2 dk=[|0; 0|]
k=4 i=1..3 dk=[|0; 1; 1|]
k=5 i=1..4 dk=[|0; 0; 0; 0|]
k=6 i=1..5 dk=[|0; 0; 0; 0; 0|]
k=7 i=1..6 dk=[|0; 1; 1; 0; 1; 0|]
k=8 i=1..6 dk=[|0; 0; 0; 0; 0; 1|]
k=9 i=1..6 dk=[|0; 0; 0; 0; 0; 0|]
k=10 i=1..6 dk=[|0; 1; 0; 0; 1; 0|]
k=11 i=2..6 dk=[|1; 0; 0; 0; 1|]
k=12 i=3..6 dk=[|0; 0; 0; 0|]
k=13 i=4..6 dk=[|0; 1; 0|]
k=14 i=5..6 dk=[|1; 1|]
k=15 i=6..6 dk=[|1|]
... duration: 23 ms
res_par_1d_seq = 0
Press any key to continue . . .
The code that produces the trace is:
if trace then
let ilow = k - high
let ihigh = k - low
printfn "k=%d i=%d..%d dk=%A" k ilow ihigh dk.[ilow..ihigh]
'dk' here refers to the values of the cells in each matrix diagonal (ie the first diagonal has 1 cell with the values 0, the 2nd diagonal has 2 cells with the values 0 and 0, etc).
Basically, in the parallel version, some of the threads seem to be overriding each others' values. Any suggestions how I can avoid this and get the values to save properly in the parallel version?
First, since your code doesn't match your output (the length of dk doesn't ever change in your code), I'm not going to try to understand what your code actually does.
Now, your issues has nothing to do with ref cells. The problem is that the value of dk in the current iteration depends on the value of dk1 and dk2 of the previous iteration and on proper rotation of those variables in each iteration. This means your code is not parallelizable, at least not directly.
For parallelizable code, you need to think first of a way to write the code so that each loop is independent of the other. i.e., if your value at i depends on the value at i-1, then the loop is not parallelizable, as you don't know whether i or i-1 will be calculated first.
In your case, probably do something like calculate the LCS for each diagonal i and store that in lcs[i]. That result should be independent of anything located in other diagonals, and thus parallelizable. Then after that loop, you can then return lcs.Max().
I've found the issue - it was that I was not using my refs inside the Parallel loop. It works as intended now. I still much appreciate the help, and have also picked up the books suggested.
Thanks guys.