M.Hiroi's Home Page

Julia Language Programming

お気楽 Julia プログラミング超入門

[ Home | Light | Julia ]

Julia の基礎知識

●Julia のデータ型

Julia のデータ型は階層構造 (木構造) になっていて、ルートのデータ型が Any になります。型の名前は先頭が英大文字になります。すべての型は Any を継承していると考えてください。

型は抽象型と具象型の二種類があり、実際のデータ (値) に対応するのが具象型で、抽象型は値を生成することはできません。木構造でいえば、「葉」に相当する型が具象型、それ以外の「節」に相当する型が抽象型となります。抽象型を継承して新しい型を作ることはできますが、逆に具象型を継承して新しい型を作ることはできません。

値の型は関数 typeof() や isa() で、上位の型は関数 supertype() で、下位の型 (サブタイプ) は関数 subtypes() で調べることができます。また、Type1 <: Type2 で Type1 が Type2 のサブタイプか調べることもできます。

julia> typeof(12345)
Int64

julia> typeof(1.2345)
Float64

julia> isa(1, Int64)
true

julia> isa(1, Float64)
false

julia> subtypes(Number)
2-element Array{Any,1}:
 Complex
 Real

julia> subtypes(Real)
4-element Array{Any,1}:
 AbstractFloat
 AbstractIrrational
 Integer
 Rational

julia> supertype(Int64)
Signed

julia> supertype(Signed)
Integer

julia> Int64 <: Number
true

julia> Int64 <: Any
true

●基本的なデータ型

julia> 12345
12345

julia> typeof(12345)
Int64

julia> 1.2345
1.2345

julia> typeof(1.2345)
Float64

julia> 1//2
1//2

julia> typeof(1//2)
Rational{Int64}

julia> 1 + 2im
1 + 2im

julia> typeof(1 + 2im)
Complex{Int64}

julia> true
true

julia> typeof(true)
Bool

julia> 'a'
'a': ASCII/Unicode U+0061 (category Ll: Letter, lowercase)

julia> typeof('a')
Char

julia> "hello, julia!"
"hello, julia!"

julia> typeof("hello, julia!")
String

julia> "abc" * "def"
"abcdef"

julia> "1 + 2 = $(1 + 2)"
"1 + 2 = 3"

julia> r"1 + 2 = $(1 + 2)"
r"1 + 2 = $(1 + 2)"

julia> isempty("")
true

julia> isempty("oops!")
false

●基本的な演算子

julia> 1 + 2
3

julia> 1 - 2
-1

julia> 2 * 3
6

julia> 4 / 2
2.0

julia> div(4, 2)
2

julia> 5 / 2
2.5

julia> div(5, 2)
2

julia> 5 \ 2
0.4

julia> 2 ^ 8
256

julia> 1 < 2
true

julia> 1 > 2
false

julia> 1 == 2
false

julia> 1 != 2
true

julia> 1 < 2 < 3
true

julia> 1 < 2 > 3
false

julia> !true
false

julia> true && true
true

julia> true && false
false

julia> true || false
true

julia> 0b0101 & 0b0011
0x01

julia> 0b0101 | 0b0011
0x07

julia> xor(0b0101, 0b0011)
0x06

julia> 1 << 8
256

julia> 256 >> 8
1

julia> a = 10
10

julia> a += 10
20

julia> a
20

julia> a -= 1
19

julia> a
19

julia> a <<= 1
38

julia> a
38

●基本的なデータ構造

julia> a = [1, 2, 3, 4, 5]
5-element Array{Int64,1}:
 1
 2
 3
 4
 5

julia> a[1]
1

julia> a[5]
5

julia> a[1] = 10
10

julia> a
5-element Array{Int64,1}:
 10
  2
  3
  4
  5

julia> []
Any[]

julia> Int[]
Int64[]

julia> isempty([1, 2, 3])
false

julia> isempty(Int[])
true

julia> b = [1 2 3; 4 5 6; 7 8 9]
3×3 Array{Int64,2}:
 1  2  3
 4  5  6
 7  8  9

julia> b[1, 1]
1

julia> b[2, 1]
4

julia> b[3, 3]
9

julia> b[2, 2] *= 10
50

julia> b
3×3 Array{Int64,2}:
 1   2  3
 4  50  6
 7   8  9

julia> 1 in b
true

julia> 10 in b
false

julia> c = [[1, 2], [3, 4, 5], [6, 7, 8, 9]]
3-element Array{Array{Int64,1},1}:
 [1, 2]
 [3, 4, 5]
 [6, 7, 8, 9]

julia> c[1][1]
1

julia> c[3][4]
9
julia> ()
()

julia> typeof(())
Tuple{}

julia> isempty(())
true

julia> isempty((1, 2, 3))
false

julia> (1,)
(1,)

julia> typeof((1,))
Tuple{Int64}

julia> a = (1, 2, 3)
(1, 2, 3)

julia> a[1]
1

julia> a[2]
2
julia> d = Dict("foo"=>100, "bar"=>200, "baz"=>300)
Dict{String,Int64} with 3 entries:
  "bar" => 200
  "baz" => 300
  "foo" => 100

julia> typeof(d)
Dict{String,Int64}

julia> d["foo"]
100

julia> d["foo"] = 1000
1000

julia> d
Dict{String,Int64} with 3 entries:
  "bar" => 200
  "baz" => 300
  "foo" => 1000

julia> d["oops"] = 2000
2000

julia> d
Dict{String,Int64} with 4 entries:
  "bar"  => 200
  "baz"  => 300
  "oops" => 2000
  "foo"  => 1000

julia> haskey(d, "foo")
true

julia> haskey(d, "Foo")
false

julia> keys(d)
KeySet for a Dict{String,Int64} with 4 entries. Keys:
  "bar"
  "baz"
  "oops"
  "foo"

julia> values(d)
ValueIterator for a Dict{String,Int64} with 4 entries. Values:
  200
  300
  2000
  1000

julia> isempty(d)
false

julia> for k = keys(d)
       delete!(d, k)
       end

julia> isempty(d)
true
julia> a = Set([1, 2, 3, 4])
Set{Int64} with 4 elements:
  4
  2
  3
  1

julia> typeof(a)
Set{Int64}

julia> 1 in a
true

julia> 10 in a
false

julia> isempty(a)
false

julia> length(a)
4

julia> isempty(Set())
true

julia> length(Set())
0

julia> b = Set([3, 4, 5, 6])
Set{Int64} with 4 elements:
  5
  4
  6
  3

julia> union(a, b)
Set{Int64} with 6 elements:
  5
  4
  6
  2
  3
  1

julia> intersect(a, b)
Set{Int64} with 2 elements:
  4
  3

julia> setdiff(a, b)
Set{Int64} with 2 elements:
  2
  1

julia> setdiff(b, a)
Set{Int64} with 2 elements:
  5
  6

●範囲オブジェクト (range object)

julia> 1 : 10
1:10

julia> typeof(1 : 10)
UnitRange{Int64}

julia> 1 : 2 : 10
1:2:9

julia> typeof(1 : 2 : 10)
StepRange{Int64,Int64}

julia> collect(1:5)
5-element Array{Int64,1}:
 1
 2
 3
 4
 5

julia> collect(1:2:5)
3-element Array{Int64,1}:
 1
 3
 5

●制御構造

julia> if true 1 else 0 end
1

julia> if false 1 else 0 end
0

julia> a = true ? 1 : 0
1

julia> a
1

julia> a = false ? 1 : 0
0

julia> a
0
julia> for i = 1:10 println("hello, Julia") end
hello, Julia
hello, Julia
hello, Julia
hello, Julia
hello, Julia
hello, Julia
hello, Julia
hello, Julia
hello, Julia
hello, Julia

julia> for i = 1:3, j = 4:6 println("$i, $j") end
1, 4
1, 5
1, 6
2, 4
2, 5
2, 6
3, 4
3, 5
3, 6

julia> i = 0
0

julia> while i < 10
       println("hello, Julia")
       global i += 1            # global 宣言は 変数 を参照
       end
hello, Julia
hello, Julia
hello, Julia
hello, Julia
hello, Julia
hello, Julia
hello, Julia
hello, Julia
hello, Julia
hello, Julia

julia> [x * x for x = 1:5]
5-element Array{Int64,1}:
  1
  4
  9
 16
 25

julia> [x for x = 1:10 if x % 2 == 0]
5-element Array{Int64,1}:
  2
  4
  6
  8
 10

●関数

julia> foo(x) = x^2
foo (generic function with 1 method)

julia> foo(x, y) = x^2 + y^2
foo (generic function with 2 methods)

julia> foo(x, y, z) = x^2 + y^2 + z^2
foo (generic function with 3 methods)

julia> foo(3)
9

julia> foo(3, 4)
25

julia> foo(3, 4, 5)
50

julia> bar(x::Int) = println("bar:Int")
bar (generic function with 1 method)

julia> bar(x::Float64) = println("bar:Float64")
bar (generic function with 2 methods)

julia> bar(1)
bar:Int

julia> bar(1.2345)
bar:Float64

julia> baz(x::Int, y::Int) = println("baz, Int, Int")
baz (generic function with 1 method)

julia> baz(x::Int, y::Float64) = println("baz, Int, Float")
baz (generic function with 2 methods)

julia> baz(x::Float64, y::Float64) = println("baz, Float, Float")
baz (generic function with 3 methods)]

julia> baz(1, 2)
baz, Int, Int

julia> baz(1, 0.1)
baz, Int, Float

julia> baz(1.1, 1.2)
baz, Float, Float

julia> baz(1.1, 2)
ERROR: MethodError: no method matching baz(::Float64, ::Int64)
Closest candidates are:
  baz(::Float64, ::Float64) at REPL[186]:1
  baz(::Int64, ::Int64) at REPL[184]:1

julia> map(x -> x * x, [1, 2, 3, 4, 5])
5-element Array{Int64,1}:
  1
  4
  9
 16
 25

julia> map([1, 2, 3, 4, 5]) do x x * x end
5-element Array{Int64,1}:
  1
  4
  9
 16
 25

julia> function adder(n) x -> n + x end
adder (generic function with 1 method)

julia> add10 = adder(10)
#23 (generic function with 1 method)

julia> add10(100)
110

julia> add100 = adder(100)
#23 (generic function with 1 method)

julia> add100(100)
200

●変数と有効範囲

リスト : 大域変数と局所変数 (test01.jl)

function foo(n)
    x = 0           # n, x は局所変数
    while x < n
        x += 1
        println(x)
    end
    println(x)
    println(y)      # y は大域変数を参照する
    # println(z)      z は定義されていないのでエラーになる
end

x = 100  # x, y は大域変数
y = 200

foo(5)
$ julia test01.jl
1
2
3
4
5
5
200
リスト : for 文と変数の有効範囲 (test02.jl)

function foo(n)
    x = 0             # x は局所変数 (x_1 とする)
    for x = 0 : n - 1 # 新しい局所変数 x (x_2 とする)
        x += 1
        println(x)
        z = x * 2     # 新しい局所変数 z
        println(z)
    end               # x_2 と z の有効範囲はここまで
    println(x)        # x_1 を参照する
    println(y)        # y は大域変数を参照する
    # println(z)        z は定義されていないのでエラーになる
end

x = 100  # x, y は大域変数
y = 200

foo(5)
$ julia test02.jl
1
2
2
4
3
6
4
8
5
10
0
200
julia> x = 0
0

julia> while x < 5; println("hello, world"); global x += 1 end
hello, world
hello, world
hello, world
hello, world
hello, world

julia> x
5

julia> (local x; for outer x = 1:10 println(x) end; println(x))
1
2
3
4
5
6
7
8
9
10
10

julia> x
5
julia> x, y = 1, 2            # 大域変数
(1, 2)

julia> let x = 10, y = 20     # (A)
       let x = 100, y = 200   # (B)
       println(x, y)          # (B) の x, y を表示
       end                    # (B) で定義した変数の有効範囲はここまで
       println(x, y)          # (A) の x, y を表示
       end                    # (A) で定義した変数の有効範囲はここまで
100200
1020

julia> println(x ,y)          # 大域変数を表示
12

簡単なプログラム

●FizzBuzz

リスト : FizzBuzz 問題

function fizzbuzz()
    for x = 1 : 100
        if x % 15 == 0
            print("FizzBuzz")
        elseif x % 3 == 0
            print("Fizz")
        elseif x % 5 == 0
            print("Buzz")
        else
            print(x)
        end
        print(" ")
    end
end

fizzbuzz()
C>julia fizzbuzz.jl
1 2 Fizz 4 Buzz Fizz 7 8 Fizz Buzz 11 Fizz 13 14 FizzBuzz 16 17 Fizz 19 Buzz Fizz 
22 23 Fizz Buzz 26 Fizz 28 29 FizzBuzz 31 32 Fizz 34 Buzz Fizz 37 38 Fizz Buzz
 41 Fizz 43 44 FizzBuzz 46 47 Fizz 49 Buzz Fizz 52 53 Fizz Buzz 56 Fizz 58 59 
FizzBuzz 61 62 Fizz 64 Buzz Fizz 67 68 Fizz Buzz 71 Fizz 73 74 FizzBuzz 76 77 
Fizz 79 Buzz Fizz 82 83 Fizz Buzz 86 Fizz 88 89 FizzBuzz 91 92 Fizz 94 Buzz Fizz
 97 98 Fizz Buzz

●数値積分

リスト : 中点則で円周率を求める

function midpoint(n)
    w = 1.0 / n
    s = 0.0
    for i = 1 : n
        x = (i - 0.5) * w;
        s += 4.0 / (1.0 + x * x);
    end
    s * w
end

print(midpoint(10000))
C>julia midpoint.jl
3.141592654423134

●平均値と標準偏差

リスト : 平均値と標準偏差

# 乱数で生成した身長のデータ
# データ型は Array{Float64, 1} になる
height = [
    148.7, 149.5, 133.7, 157.9, 154.2, 147.8, 154.6, 159.1, 148.2, 153.1,
    138.2, 138.7, 143.5, 153.2, 150.2, 157.3, 145.1, 157.2, 152.3, 148.3,
    152.0, 146.0, 151.5, 139.4, 158.8, 147.6, 144.0, 145.8, 155.4, 155.5,
    153.6, 138.5, 147.1, 149.6, 160.9, 148.9, 157.5, 155.1, 138.9, 153.0,
    153.9, 150.9, 144.4, 160.3, 153.4, 163.0, 150.9, 153.3, 146.6, 153.3,
    152.3, 153.3, 142.8, 149.0, 149.4, 156.5, 141.7, 146.2, 151.0, 156.5,
    150.8, 141.0, 149.0, 163.2, 144.1, 147.1, 167.9, 155.3, 142.9, 148.7,
    164.8, 154.1, 150.4, 154.2, 161.4, 155.0, 146.8, 154.2, 152.7, 149.7,
    151.5, 154.5, 156.8, 150.3, 143.2, 149.5, 145.6, 140.4, 136.5, 146.9,
    158.9, 144.4, 148.1, 155.5, 152.4, 153.3, 142.3, 155.3, 153.1, 152.3,
]

# 平均値と標準偏差
function meansd(xs)
    m = sum(xs) / length(xs)
    s = 0.0
    for x = xs
        s += (x - m) * (x - m)
    end
    m, sqrt(s / length(xs))
end

# 1 回の読み込みで求める
function meansd2(xs)
    m, s = 0.0, 0.0
    k = length(xs)
    for i = 1 : k
        x = xs[i] - m
        m += x / i
        s += (i - 1) * x * x / i
    end
    m, sqrt(s / k)
end

println(meansd(height))
println(meansd2(height))
C>julia mean.jl
(150.62699999999998, 6.433472701426501)
(150.62699999999998, 6.433472701426506)

●パスカルの三角形

リスト : パスカルの三角形

# 2 次元配列版
function pascal(n)
    table = ones(Int, n, n)
    for i = 3 : n, j = 2 : i - 1
        table[i, j] = table[i - 1, j - 1] + table[i - 1, j]
    end
    for i = 1 : n
        for j = 1 : i
            print(table[i, j], " ")
        end
        println("")
    end
end

# 1 次元配列版
function pascal1(n)
    table = ones(Int, n)
    println(table[1])
    println(table[1], " ", table[2])
    for i = 3 : n
        for j = i - 1 : -1 : 2
            table[j] += table[j - 1]
        end
        # 表示
        for j = 1 : i
            print(table[j], " ")
        end
        println("")
    end
end

pascal(15)
# pascal1(15)
C>julia pascal.jl
1
1 1
1 2 1
1 3 3 1
1 4 6 4 1
1 5 10 10 5 1
1 6 15 20 15 6 1
1 7 21 35 35 21 7 1
1 8 28 56 70 56 28 8 1
1 9 36 84 126 126 84 36 9 1
1 10 45 120 210 252 210 120 45 10 1
1 11 55 165 330 462 462 330 165 55 11 1
1 12 66 220 495 792 924 792 495 220 66 12 1
1 13 78 286 715 1287 1716 1716 1287 715 286 78 13 1
1 14 91 364 1001 2002 3003 3432 3003 2002 1001 364 91 14 1

●素数

リスト : 素数

# 単純版
function checkPrime(ps, x)
    for p = ps
        if p * p > x; break; end
        if x % p == 0; return false; end
    end
    true
end

function makePrimes(n)
    ps = [2]
    x = 1
    for x = 3 : 2 : n
        if checkPrime(ps, x); push!(ps, x); end
    end
    ps
end

# エラトステネスの篩 (1)
function sieve(n)
    ps = [2]
    xs = collect(3 : 2 : n)
    while xs[1] * xs[1] <= n
        p = xs[1]
        push!(ps, p)
        filter!(x -> x % p != 0, xs)
    end
    append!(ps, xs)
end

# エラトステネスの篩 (2)
function sieve1(n)
    ps = [2]
    k = div(n, 2)
    xs = trues(k)
    x = 3
    while x * x <= n
        i = div(x, 2)
        if xs[i]
            push!(ps, x)
            for j = i + x : x : k; xs[j] = false; end
        end
        x += 2
    end
    while x <= n
        i = div(x, 2)
        if xs[i]; push!(ps, x); end
        x += 2
    end
    ps
end

println(makePrimes(1000))
# println(sieve(1000))
# println(sieve1(1000))
C>julia prime.jl
[2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97,101,103,
107,109,113,127,131,137,139,149,151,157,163,167,173,179,181,191,193,197,199,211,
223,227,229,233,239,241,251,257,263,269,271,277,281,283,293,307,311,313,317,331,
337,347,349,353,359,367,373,379,383,389,397,401,409,419,421,431,433,439,443,449,
457,461,463,467,479,487,491,499,503,509,521,523,541,547,557,563,569,571,577,587,
593,599,601,607,613,617,619,631,641,643,647,653,659,661,673,677,683,691,701,709,
719,727,733,739,743,751,757,761,769,773,787,797,809,811,821,823,827,829,839,853,
857,859,863,877,881,883,887,907,911,919,929,937,941,947,953,967,971,977,983,991,
997]

●素因数分解

リスト : 素因数分解 (試し割り)

function factorSub(n, m)
    c = zero(n)
    while n % m == 0
        c += 1
        n = div(n, m)
    end
    c, n
end

function factorization(n)
    x::typeof(n) = 2
    xs = Pair{typeof(n), typeof(n)}[]
    c, m = factorSub(n, x)
    if c > 0
        push!(xs, x => c)
    end
    x = 3
    while x * x <= m
        c, m = factorSub(m, x)
        if c > 0
            push!(xs, x => c)
        end
        x += 2
    end
    if m > 1
        push!(xs, m => one(n))
    end
    xs
end

println(factorization(24))
println(factorization(12345678))
println(factorization(123456789))
println(factorization(1234567890))
println(factorization(1111111111))
for x = 2 : 31
    println(factorization(2 ^ x - 1))
end
C>julia factor.jl
[2 => 3, 3 => 1]
[2 => 1, 3 => 2, 47 => 1, 14593 => 1]
[3 => 2, 3607 => 1, 3803 => 1]
[2 => 1, 3 => 2, 5 => 1, 3607 => 1, 3803 => 1]
[11 => 1, 41 => 1, 271 => 1, 9091 => 1]
[3 => 1]
[7 => 1]
[3 => 1, 5 => 1]
[31 => 1]
[3 => 2, 7 => 1]
[127 => 1]
[3 => 1, 5 => 1, 17 => 1]
[7 => 1, 73 => 1]
[3 => 1, 11 => 1, 31 => 1]
[23 => 1, 89 => 1]
[3 => 2, 5 => 1, 7 => 1, 13 => 1]
[8191 => 1]
[3 => 1, 43 => 1, 127 => 1]
[7 => 1, 31 => 1, 151 => 1]
[3 => 1, 5 => 1, 17 => 1, 257 => 1]
[131071 => 1]
[3 => 3, 7 => 1, 19 => 1, 73 => 1]
[524287 => 1]
[3 => 1, 5 => 2, 11 => 1, 31 => 1, 41 => 1]
[7 => 2, 127 => 1, 337 => 1]
[3 => 1, 23 => 1, 89 => 1, 683 => 1]
[47 => 1, 178481 => 1]
[3 => 2, 5 => 1, 7 => 1, 13 => 1, 17 => 1, 241 => 1]
[31 => 1, 601 => 1, 1801 => 1]
[3 => 1, 2731 => 1, 8191 => 1]
[7 => 1, 73 => 1, 262657 => 1]
[3 => 1, 5 => 1, 29 => 1, 43 => 1, 113 => 1, 127 => 1]
[233 => 1, 1103 => 1, 2089 => 1]
[3 => 2, 7 => 1, 11 => 1, 31 => 1, 151 => 1, 331 => 1]
[2147483647 => 1]

●再帰定義

リスト : 再帰定義

# 階乗
function fact(n)
    if n == 0
        BigInt(1)    # one(n) とすると引数 n のデータ型で値を求める
    else
       n * fact(n - 1)
    end
end

# 階乗 (繰り返し版)
function facti(n)
    a = BigInt(1)    # a::BigInt = 1 でもよい
    for x = 2 : n
      a *= x
    end
    a
end

# フィボナッチ数 (二重再帰)
function fibo(n)
    if n == 0
        0
    elseif n == 1
        1
    else
        fibo(n - 2) + fibo(n - 1)
    end
end

# フィボナッチ数 (繰り返し版)
function fiboi(n)
    a = BigInt(0)    # zero(n)
    b = BigInt(1)    # one(n) とすると引数のデータ型で値を求める
    for _ = 1 : n
        a, b = b, a + b
    end
    a
end

for x = 0:20
    println(fact(x))
end
println(facti(50))
for x = 0:20
    print(fibo(x), " ")
end
println("")
println(fiboi(50))
println(fiboi(100))
C>julia fact.jl
1
1
2
6
24
120
720
5040
40320
362880
3628800
39916800
479001600
6227020800
87178291200
1307674368000
20922789888000
355687428096000
6402373705728000
121645100408832000
2432902008176640000
30414093201713378043612608166064768844377641568960512000000000000
0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 4181 6765
12586269025
354224848179261915075

●高階関数

リスト : 高階関数

# マッピング
function map1(fn, xs)
    a::typeof(xs) = []
    for x = xs
        push!(a, fn(x))
    end
    a
end

# フィルター
function filter1(fn, xs)
    a::typeof(xs) = []
    for x = xs
        if fn(x)
            push!(a, x)
        end
    end
    a
end

# 畳み込み
function foldleft(fn, a, xs)
    for x = xs
        a = fn(a, x)
    end
    a
end

xs = collect(1:10)
println(map1(x -> x * x, xs))
println(map(x -> x * x, xs))
println(filter1(x -> x % 2 == 0, xs))
println(filter(x -> x % 2 == 0, xs))
println(foldleft(+, 0, xs))
println(reduce(+, xs, init=0))
C>julia higher.jl
[1,4,9,16,25,36,49,64,81,100]
[1,4,9,16,25,36,49,64,81,100]
[2,4,6,8,10]
[2,4,6,8,10]
55
55
julia> reduce((x, y) -> (x, y), [1,2,3])
((1, 2), 3)

julia> reduce((x, y) -> (x, y), [1,2,3], init=0)
(((0, 1), 2), 3)

●組み合わせの数

リスト : 組み合わせの数

# 二重再帰 (とても遅い)
function combination_number(n, r)
    if r == 0 || n == r
        BigInt(1)
    else
        combination_number(n - 1, r) + combination_number(n - 1, r - 1)
    end
end

# 末尾再帰
function combination_number1(n, r)
    if n == 0 || r == 0
        BigInt(1)
    else
        div(combination_number1(n, r - 1) * (n - r + 1), r)
    end
end

println(combination_number(22, 11))
println(combination_number1(26, 13))
println(combination_number1(50, 25))
C>julia comb.jl
705432
10400600
126410606437752

●順列と組み合わせ

リスト : 順列と組み合わせ

# xs の中から n 個を選ぶ順列
function permutation(fn, n, xs)
    ys::typeof(xs) = []

    function perm()
        if length(ys) == n
            fn(ys)
        else
            for x = xs
                if x in ys; continue; end
                push!(ys, x)
                perm()
                pop!(ys)
            end
        end
    end

    perm()
end

# xs の中から n 個を選ぶ組み合わせ
function combination(fn, n, xs)
    ys::typeof(xs) = []

    function comb(m)
        if length(ys) == n
            fn(ys)
        elseif m <= length(xs)
            push!(ys, xs[m])
            comb(m + 1)
            pop!(ys)
            comb(m + 1)
        end
    end

    comb(1)
end

permutation(print, 4, [1, 2, 3, 4])
println("")
combination(print, 3, [1, 2, 3, 4, 5])
println("")
C>julia perm.jl
[1, 2, 3, 4][1, 2, 4, 3][1, 3, 2, 4][1, 3, 4, 2][1, 4, 2, 3][1, 4, 3, 2][2, 1, 3, 4][2, 1, 4, 3]
[2, 3, 1, 4][2, 3, 4, 1][2, 4, 1, 3][2, 4, 3, 1][3, 1, 2, 4][3, 1, 4, 2][3, 2, 1, 4][3, 2, 4, 1]
[3, 4, 1, 2][3, 4, 2, 1][4, 1, 2, 3][4, 1, 3, 2][4, 2, 1, 3][4, 2, 3, 1][4, 3, 1, 2][4, 3, 2, 1]
[1, 2, 3][1, 2, 4][1, 2, 5][1, 3, 4][1, 3, 5][1, 4, 5][2, 3, 4][2, 3, 5][2, 4, 5][3, 4, 5]

2021/11/27 改訂: Julia のバージョンを 1.6 に変更

Copyright (C) 2016-2021 Makoto Hiroi
All rights reserved.

[ Home | Light | Julia ]