this is similiar to my previous question,
but there is another improvisation, how is the code if i want to skip some white spaces, for this case is "enter", for example:
5 5 10
1 2 3 4 5
1 2 3 4 5
1 2 3 4 5
1 2 3 4 5
1 2 3 4 5
<- this white space
3 4 4
1 2 3 4
1 2 3 4
1 2 3 4
i try to my best but couldn't find how to skip the white space
thank you for the help :)
This is the answer, thanks to Ramon :
let readMap (path:string) =
let lines = File.ReadAllLines path
let [|x; y; n|] = lines.[0].Split() |> Array.map int
let data =
[|
for l in (lines |> Array.toSeq |> Seq.skip 1 |> Seq.filter(System.String.IsNullOrEmpty >> not)) do
yield l.Split()
|]
x,y,n,data
Another way to write your readMap function is to use if expression inside the list comprehension. I think this is actually more readable if you're using comprehensions (because you don't have to combine two ways of writing things):
let readMap (path:string) =
let lines = File.ReadAllLines path
let [|x; y; n|] = lines.[0].Split() |> Array.map int
let data =
[|
for l in lines |> Seq.skip 1 do
if not (System.String.IsNullOrEmpty(l)) then
yield l.Split()
|]
x,y,n,data
I also removed the call to Array.toSeq, because F# allows you to use array in a place where seq is expected without an explicit conversion (seq is actually IEnumerable and array implements it).
What about this:
val items : string list
items
|> List.filter (System.String.IsNullOrEmpty >> not)
?
Related
Example input: {1;2;3;4...}
How to take first 2 numbers & and add them ?
Put result into new sequence
Then take next 2 numbers & add them
Put result into new sequence
etc..
let nat = Seq.initInfinite (fun i -> i + 1)
Result should be: {3; 7...}
You could do something like this:
let nat = Seq.initInfinite (fun i -> i + 1)
let f (s:seq<int>) =
Seq.chunkBySize 2 s
|> Seq.map Seq.sum
f nat // seq [3; 7; 11; 15; ...]
I'm pretty new to programming in F#, and I am working on a project at the moment, with a function that takes an integer and returns a string value.
My problem (se my code below) is that no matter what I do, I cant return the values of my str, calling my function.
let mulTable (n:int):string = string n
let mutable m = 1
let mutable str = ""
while m < 10 do
str <- "m\t" + str
m <- m + 1
printfn "%A" (mulTable str)
My idea here is that I want to store the value of m, in str, så that str in the end of my while loop contains the values of "1 2 3 4 5 6 7 8 9". But no matter what I try my printfn "%A" mulTable str, returns "this expressions was exspected to have type int, but here has type string". I have tried converting my str to a string in my mutable value like:
let mutable str = ""
let mutable str1 = str |> int
and then I try to call my str1 using function mulTable instead of calling str. But still it does not work.
What am I missing here? I've been trying every single possible solution I can think of, without being able to solve my problem.
A fix of your own algorithm could be:
let getSequenceAsString max =
let concat s x = sprintf "%s\t%i" s x
let mutable m = 1
let mutable str = ""
while m < max do
str <- concat str m
m <- m + 1
str
printfn "%A" (getSequenceAsString 10)
But as others have shown it's a lot of work that can be done more easily:
open System
let getSequenceAsString max =
String.Join("\t", [1..max-1])
If you want each number reverted as you ask for in a comment it could be done this way:
let getSequenceAsString min max =
let revert x =
let rec rev y acc =
match y with
| 0 -> acc
| _ -> rev (y / 10) (sprintf "%s%i" acc (y % 10))
rev x ""
String.Join("\t", ([min..max-1] |> List.map revert))
printfn "%A" (getSequenceAsString 95 105)
Gives:
"59 69 79 89 99 001 101 201 301 401"
You can easily join an array of strings into a string array, and then print it out if necessary.
open System
let xs = [1..9] |> List.map string
//you should avoid using mutable variables, and instead generate your list of numbers with an list comprehension or something similar.
String.Join("\t", xs)
//A little exploration of the List/Array/String classes will bring this method up: "concatenates the members of a collection using the separator string.
This gives me:
val it : string = "1 2 3 4 5 6 7 8 9"
I've adjusted the code to make it produce results similar to what you wanted:
let mulTable (n:int):string = string n
let mutable m = 1
let mutable str = ""
while m < 10 do
str <- mulTable m+ "\t" + str
m <- m + 1
printfn "%A" (str)
I've used your mulTable to convert m to string, but for printfn you don't need to use that, because str is already a string.
Still the result would be 9 8 7 6 5 4 3 2 1
There are more then one way to revert the string, one of them would be to split the string into an array of characthers and then revert the array. From resulting array we will build a new string again. It would look something like:
printf "%A" (new System.String(str.ToCharArray() |> Array.rev ))
Edit
To achieve the same result, I would suggest to use more functional style, using recursion and avoiding mutating variables.
let getNumbersString upperLimit =
let rec innerRecursion rem acc=
match rem with
| 0 -> acc
| _ -> innerRecursion (rem-1) (sprintf "%i "rem::acc)
innerRecursion upperLimit [] |> String.concat ""
getNumbersString 9
Will result in
val it : string = "1 2 3 4 5 6 7 8 9 "
I'm trying to modify a matrix like this one:
/ 1 2 3 \
\ 4 5 6 /
to return:
/ 1 4 \
| 2 5 |
\ 3 6 /
Instead it is flipping my matrix by the corners. This is the code I have so far:
Let rec matrixadjust = function
| (_::_) : : as xss-> List.map List.head xss :: matrixadjust (List.map List.tail xss)
| _ ->[];;
I think that the best way to work with matrix is using the Array2D data structure. You can build an Array2D from an array of arrays and then create a new Array2D to acomplish what you want:
let arrayOfArrays = [| [| 1; 2; 3 |]; [|4; 5; 6 |] |]
let array2d = Array2D.init 2 3 (fun row column -> arrayOfArrays.[row].[column])
let newArray = Array2D.init (array2d |> Array2D.length2) (array2d |> Array2D.length1) (fun r c -> array2d.[c,r])
Assuming your data structure is a list of lists where each sub-list represents a row you could do it like this. Basically it loops once per source-list row and accumulates the result in the partial binding. Since its doing list accumulation, it reverses the order of the values so you have to do a List.rev on each row at the end.
let flip matrix =
match matrix with
| [] -> []
| x::xs ->
let rec loop matrix partial =
match matrix with
| [] -> partial
| y::ys ->let newPartial = (y, partial) ||> List.map2(fun x y->x::y)
loop ys newPartial
let length = List.length x
loop matrix (List.init length (fun _ -> [] ))
|> List.map(fun x->x |> List.rev)
i'm using F#. I want to solve some problem that require me to read the input from a file, i don't know what to do. The first line in the file consist of three numbers, the first two numbers is the x and y for an map for the next line. The example file:
5 5 10
1 2 3 4 5
1 2 3 4 5
1 2 3 4 5
1 2 3 4 5
1 2 3 4 5
the meaning of 5 5 10 is the next line have 5x5 map and 10 is just some numbers that i need to solve the problem, the next until the end of the line is contents of the map that i have to solve using the 10 and i want to save this map numbers in 2 dimensional array. Someone can help me to write a code to save the all the numbers from the file so i can process it?
* Sorry my english is bad, hope my question can be understood :)
The answer for my own question :
Thanks for the answer from Daniel and Ankur. For my own purpose i mix code from both of you:
let readMap2 (path:string) =
let lines = File.ReadAllLines path
let [|x; y; n|] = lines.[0].Split() |> Array.map int
let data =
[|
for l in (lines |> Array.toSeq |> Seq.skip 1) do
yield l.Split() |> Array.map int
|]
x,y,n,data
Many Thanks :D
Here's some quick and dirty code. It returns a tuple of the last number in the header (10 in this case) and a two-dimensional array of the values.
open System.IO
let readMap (path:string) =
use reader = new StreamReader(path)
match reader.ReadLine() with
| null -> failwith "empty file"
| line ->
match line.Split() with
| [|_; _; _|] as hdr ->
let [|x; y; n|] = hdr |> Array.map int
let vals = Array2D.zeroCreate y x
for i in 0..(y-1) do
match reader.ReadLine() with
| null -> failwith "unexpected end of file"
| line ->
let arr = line.Split() |> Array.map int
if arr.Length <> x then failwith "wrong number of fields"
else for j in 0..(x-1) do vals.[i, j] <- arr.[j]
n, vals
| _ -> failwith "bad header"
In case the file is this much only (no further data to process) and always in correct format (no need to handle missing data etc) then it would be as simple as:
let readMap (path:string) =
let lines = File.ReadAllLines path
let [|_; _; n|] = lines.[0].Split() |> Array.map int
[|
for l in (lines |> Array.toSeq |> Seq.skip 1) do
yield l.Split() |> Array.map int
|]
I'm learning F#, and I am having trouble understanding why this crashes. It's an attempt to solve Project Euler problem 2.
let rec fibonacci n =
if n = 1 then
1
elif n = 2 then
2
else
fibonacci (n - 1) + fibonacci (n - 2)
let debugfibonacci n =
printfn "CALC: %d" n
fibonacci n
let isEven n =
n % 2 = 0
let isUnderLimit n =
n < 55
let getSequence =
//[1..30]
Seq.initInfinite (fun n -> n)
|> Seq.map debugfibonacci
|> Seq.filter isEven
|> Seq.takeWhile isUnderLimit
Seq.iter (fun x -> printfn "%d" x) getSequence
The final version would call a sum function (and would have a higher limit than 55), but this is learning code.
As is, this gives a StackOverflowException. However, if I comment in the [1..30] and comment out the Seq.initInfinite, I get:
CALC: 1
CALC: 2
2
CALC: 3
CALC: 4
CALC: 5
8
CALC: 6
CALC: 7
CALC: 8
34
CALC: 9
CALC: 10
CALC: 11
It appears to be generating items on demand, as I would expect in LINQ. So why does it blow up when used with initInfinite?
Seq.initInfinite returns a sequence that starts at 0.
Your fibonacci function results in a stack overflow when called with zero, because it never hits the terminating cases.
You can solve this by starting from Seq.initInfinite (fun n -> n + 1)
You're starting with 0 with initInfinite, which then recurses -1, -2, ...
(By the way, if you're using the Visual Studio debugger, this is easy to diagnose, by checking the call stack and locals window.)