Problem 24

Problem 24

■書き直したコード

module Problem_0024

(*
【問題】
順列とはモノの順番付きの並びのことである.
たとえば, 3124は数1, 2, 3, 4の一つの順列である.
すべての順列を数の大小でまたは辞書式に並べたものを辞書順と呼ぶ.
0と1と2の順列を辞書順に並べると
012 021 102 120 201 210
になる.
0,1,2,3,4,5,6,7,8,9からなる順列を辞書式に並べたときの100万番目を
答えよ
*)

let inline fac n =
    [1..n]
    |> List.fold (fun l i ->
        l@[i * l.[i-1]]
    ) [1]
let inline div x y = x/y,x%y
let inline exceptlist s l =
    let set1 = Set.ofList l
    Set.difference s set1 |> Set.toArray
// 278391560
// 68 ms
let find () =
    let set0 = set { 0..9 }
    let size = set0.Count - 1
    let except = exceptlist set0
    let faclist = fac size
    let rec combi acc n l =
        if n <= 0 then l
        else
            let a,b = div acc (faclist.[n])
            let arr = except l
            combi b (n-1) (l@[arr.[a]])
    combi 1000000 size []

let run() =
    find ()
    |> List.map((+)48 >> char >> string)
    |> List.reduce(+)

シーケンスで組み合わせ1つ1つ出したかったけど、出来ませんでした!

//総当たりコード
let find () =
    seq { 0L..9999999999L }
    |> Seq.map (sprintf "%010d")
    |> Seq.filter (fun s ->
        s.ToCharArray()
        |> Seq.countBy(fun x -> x)
        |> Seq.exists(snd>>(<)1)
        |> not
    )
    |> Seq.nth 1000000
//余興コード
let find () =
    let set1 = set { 0..9 }
    set1 |> Set.map (fun s1 ->
    let set2 = Set.remove s1 set1
    set2 |> Set.map (fun s2 ->
    let set3 = Set.remove s2 set2
    set3 |> Set.map (fun s3 ->
    let set4 = Set.remove s3 set3
    set4 |> Set.map (fun s4 ->
    let set5 = Set.remove s4 set4
    set5 |> Set.map (fun s5 ->
    let set6 = Set.remove s5 set5
    set6 |> Set.map (fun s6 ->
    let set7 = Set.remove s6 set6
    set7 |> Set.map (fun s7 ->
    let set8 = Set.remove s7 set7
    set8 |> Set.map (fun s8 ->
    let set9 = Set.remove s8 set8
    set9 |> Set.map (fun s9 ->
        let set10 = Set.remove s9 set9
        let s10 = set10 |> Set.toList |> List.head
        [ s1; s2; s3; s4; s5; s6; s7; s8; s9; s10; ]
    )))))))))
    |> Seq.iter (printfn "%A")