SHOW:
|
|
- or go back to the newest paste.
1 | open System | |
2 | open System.IO | |
3 | - | open System.Collections.Generic |
3 | + | open Microsoft.FSharp.Collections |
4 | ||
5 | let flip f a b = f b a | |
6 | ||
7 | - | let rec yobaFold fa fi s = match s with | a, None -> a |
7 | + | |
8 | - | | a, Some(i) -> yobaFold fa fi (fa a i , fi i) |
8 | + | |
9 | |> Seq.length | |
10 | ||
11 | let buildMap ws = let l = Array.length ws - 1 | |
12 | seq{ for i in 0..l do | |
13 | for j in i..l do | |
14 | if diff ws.[i] ws.[j] < 2 | |
15 | then yield i, j; yield j, i } | |
16 | |> Seq.groupBy(fst) | |
17 | |> Seq.map(fun (k,s) -> k, s |> Seq.map(snd)) | |
18 | |> Map.ofSeq | |
19 | ||
20 | type Transmute = {s:int;c:int; h:int list} | |
21 | ||
22 | let transmutes (map:Map<int,_>) start = | |
23 | - | type Transmute = {p: Transmute Option; c:int} |
23 | + | let visit = Seq.fold(fun a {c=c} -> Set.add c a) |
24 | let next vs curs = | |
25 | let nxt c = map.[c.c] | |
26 | - | let visit = Seq.fold(fun a {c=c} -> Set.add c a) |
26 | + | |> Seq.filter(flip Set.contains vs >> not) |
27 | - | let next vs curs = |
27 | + | |> Seq.map(fun n -> {s=start;h = c.c::c.h; c = n}) |
28 | - | let next1 c = map.[c.c] |> Seq.filter(flip Set.contains vs >> not) |
28 | + | curs |> Seq.map(nxt) |> Seq.collect(fun n -> n) |
29 | - | |> Seq.map(fun n -> {p = Some(c); c = n}) |
29 | + | let rec trans vs olds = seq{ yield! olds; |
30 | - | curs |> Seq.map(next1) |> Seq.collect(fun n -> n) |
30 | + | let nvs = visit vs olds |
31 | - | let rec trans vs olds = |
31 | + | let news = next nvs olds |
32 | - | if Seq.isEmpty olds then Seq.empty |
32 | + | if Seq.isEmpty news |> not |
33 | - | else seq{ yield! olds; |
33 | + | then yield! trans nvs news } |
34 | - | let newVs = (visit vs olds) in yield! trans newVs (next newVs olds) } |
34 | + | trans Set.empty [{s=start;c=start; h=[]}] |
35 | - | trans Set.empty [{p=None; c=start}] |
35 | + | |
36 | let findWay words map (start, target) = | |
37 | let s = Array.findIndex ((=)start) words | |
38 | let t = Array.findIndex ((=)target) words | |
39 | let way = transmutes map s |> Seq.tryFind(fun {c=c} -> c=t) | |
40 | match way with | None -> [] | Some(r) -> r.h | |
41 | - | match way with | None -> [] |
41 | + | |
42 | - | | res -> yobaFold(fun a {c=c} -> c::a) (fun {p=p} -> p) ([], res) |
42 | + | let words = File.ReadAllLines @"C:\words.txt" |
43 | - | |> List.map(fun i -> words.[i]) |
43 | + | |
44 | let printWay way = way |> Seq.map(fun i -> words.[i]) |> List.ofSeq | |
45 | - | let words = File.ReadAllLines @"D:\Arc\Dropbox\Dropbox\Projects\FSharp\AprilFpContest\AprilFpContest\bin\Debug\words.txt" |
45 | + | |
46 | //ОРИГИНАЛЬНОЕ ЗАДАНИЕ | |
47 | - | let pairs = ["МУХА","СЛОН"; "ДЕНЬ","НОЧЬ"; "СНЕГ","ВОДА"; "ОТЕЦ", "МАТЬ"; |
47 | + | ["МУХА","СЛОН"; "ДЕНЬ","НОЧЬ"; "СНЕГ","ВОДА"; "ОТЕЦ", "МАТЬ"; |
48 | - | "РУКА","НОГА"; "ЗИМА","ЛЕТО"; "СВЕТ","ТЬМА"; "ЛИПА", "КЛЁН"] |
48 | + | "РУКА","НОГА"; "ЗИМА","ЛЕТО"; "СВЕТ","ТЬМА"; "ЛИПА", "КЛЁН"] |
49 | - | |> Seq.map(fun (s,e) -> s.ToLower(), e.ToLower()) |
49 | + | |> Seq.map(fun (s,e) -> s.ToLower(), e.ToLower()) |
50 | - | pairs |> Seq.map(fun p -> p, findWay words wordsMap p) |> Seq.iter(printfn "%A") |
50 | + | |> Seq.map(fun p -> p, findWay words wordsMap p |> printWay) |
51 | |> Seq.iter(printfn "%A") | |
52 | ||
53 | ||
54 | //ДОПОЛНИТЕЛЬНОЕ ЗАДАНИЕ | |
55 | let mt = wordsMap |> PSeq.map(fun k -> k.Key) | |
56 | |> PSeq.map(transmutes wordsMap) | |
57 | |> PSeq.collect(fun x -> x) | |
58 | |> PSeq.maxBy(fun x -> x.h.Length) | |
59 | Console.WriteLine("{0} - {1}: {2} \n", words.[mt.s], words.[mt.c], mt.h.Length) | |
60 | Console.WriteLine(Seq.reduce(fun a s -> a + " " + s) (printWay mt.h)) | |
61 | ||
62 | Console.ReadLine() |