[式 for 変数 = コレクション, ...]
julia> a = [1, 2, 3, 4, 5] 5-element Vector{Int64}: 1 2 3 4 5 julia> [x * x for x = a] 5-element Vector{Int64}: 1 4 9 16 25 julia> [(x, x * x) for x = a] 5-element Vector{Tuple{Int64,Int64}}: (1, 1) (2, 4) (3, 9) (4, 16) (5, 25) julia> [x * x for x = a if x % 2 == 0] 2-element Vector{Int64}: 4 16 julia> [x + y for x = 1 : 3, y = 10 : 13] 3×4 Array{Int64,2}: 11 12 13 14 12 13 14 15 13 14 15 16 julia> [x + y for x = 1 : 3 for y = 10 : 13] 12-element Vector{Int64}: 11 12 13 14 12 13 14 15 13 14 15 16 julia> [x + y for x = 1 : 3, y = 10 : 13 if (x + y) % 2 == 0] 6-element Vector{Int64}: 12 12 14 14 14 16
julia> a 5-element Vector{Int64}: 1 2 3 4 5 julia> b = (x * x for x = a) Base.Generator{Vector{Int64}, var"#19#20"}(var"#19#20"(), [1, 2, 3, 4, 5]) julia> for x in b println(x) end 1 4 9 16 25 julia> collect(b) 5-element Vector{Int64}: 1 4 9 16 25 julia> k = ["foo", "bar", "baz"] 3-element Vector{String}: "foo" "bar" "baz" julia> v = [10, 20, 30] 3-element Vector{Int64}: 10 20 30 julia> d = Dict(key => val for (key, val) = zip(k, v)) Dict{String,Int64} with 3 entries: "bar" => 20 "baz" => 30 "foo" => 10 julia> Set(x * x for x = 1 : 10) Set{Int64} with 10 elements: 64 4 16 49 25 36 81 9 1 100
struct 名前 <: supertype 変数1 :: データ型1 変数2 :: データ型2 ... 変数n :: データ型n end
julia> struct Foo a::Int b::Float64 end julia> x = Foo(1, 1.23456) Foo(1, 1.23456) julia> typeof(x) Foo julia> x.a 1 julia> x.b 1.23456 julia> x.a = 10 ERROR: setfield! immutable struct of type Foo cannot be changed julia> mutable struct Bar a::Int b::Float64 end julia> y = Bar(100, 123.456) Bar(100, 123.456) julia> typeof(y) Bar julia> y.a 100 julia> y.a = 200 200 julia> y Bar(200, 123.456)
julia> struct Foo1 a::Int Foo1(x) = x > 0 ? new(x) : new(-x) end julia> foo1 = Foo1(10) Foo1(10) julia> foo2 = Foo1(-10) Foo1(10)
abstract type 名前 end abstract type 名前 <: supertype end
julia> Foo2 = Union{Int, Nothing} Union{Nothing, Int64} julia> Int <: Foo2 true julia> Nothing <: Foo2 true julia> struct Baz x::Foo2 end julia> Baz(123) Baz(123) julia> Baz(nothing) Baz(nothing)
julia> struct Foo{T} x::T end julia> Foo{Int}(123) Foo{Int64}(123) julia> Foo{Float64}(1.2345) Foo{Float64}(1.2345)
julia> foo(a::Foo{T}) where {T} = a.x foo (generic function with 1 method) julia> x = Foo{Int}(123) Foo{Int64}(123) julia> y = Foo{Float64}(1.2345) Foo{Float64}(1.2345) julia> foo(x) 123 julia> foo(y) 1.2345
julia> struct Bar{T <: Integer} x::T end julia> Bar{Int}(123) Bar{Int64}(123) julia> Bar{Int128}(123) Bar{Int128}(123) julia> Bar{Float64}(1.23) ERROR: TypeError: in Bar, in T, expected T<:Integer, got Type{Float64}
open("test.txt", "r") do fin for s = eachline(fin) println(s) end end
julia> open("test.txt", "w") do fout for i = 1 : 5 write(fout, "hello, Julia!\n") end end julia> open("test.txt") do fin for line = eachline(fin) println(line) end end hello, Julia! hello, Julia! hello, Julia! hello, Julia! hello, Julia! julia> fin = open("test.txt") IOStream(<file test.txt>) julia> read(fin, String) "hello, Julia!\nhello, Julia!\nhello, Julia!\nhello, Julia!\nhello, Julia!\n" julia> close(fin) julia> fin = open("test.txt") IOStream(<file test.txt>) julia> readlines(fin) 5-element Vector{String}: "hello, Julia!" "hello, Julia!" "hello, Julia!" "hello, Julia!" "hello, Julia!" julia> close(fin)
リスト : コマンドライン引数の表示 (test.jl) println(ARGS)
$ julia test.jl abc def ghi ["abc", "def", "ghi"]
julia> try error("oops!") catch err print(err) finally print("finish!!") end ErrorException("oops!")finish!!
julia> try throw("oops") catch err println(err) end oops julia> try throw(ErrorException("oops")) catch err println(err) end ErrorException("oops")
julia> foo() = println("foo!") foo (generic function with 1 method) julia> bar() = (println("bar!"); throw("Global Exit!!")) bar (generic function with 1 method) julia> baz() = println("baz!") baz (generic function with 1 method) julia> test() = (foo(); bar(); baz()) test (generic function with 1 method) julia> try test() catch err println(err) end foo! bar! Global Exit!!
julia> module Foo a, b, c, d = 1, 2, 3, 4 export a, b end Main.Foo julia> Foo.a 1 julia> Foo.b 2 julia> Foo.c 3 julia> Foo.d 4 julia> using .Foo julia> a 1 julia> b 2 julia> c ERROR: UndefVarError: c not defined julia> import .Foo.c julia> c 3 julia> c = 10 ERROR: cannot assign variable Foo.c from module Main
リスト : モジュールの簡単な使用例 (test_mod.jl) module Foo a = 1 set_a(x) = global a = x function show_a() println("Foo.a = $a") println("Foo.Bar.a = $(Bar.a)") println("Foo.Bar.Baz.a = $(Bar.Baz.a)") end module Bar a = 10 set_a(x) = global a = x import ..Foo # 一つ外側のモジュール Foo をインポート function show_a() println("Foo.a = $(Foo.a)") println("Foo.Bar.a = $a") println("Foo.Bar.Baz.a = $(Baz.a)") end module Baz a = 100 set_a(x) = global a = x import ..Bar import ...Foo # 二つ外側のモジュール Foo をインポート function show_a() println("Foo.a = $(Foo.a)") println("Foo.Bar.a = $(Bar.a)") println("Foo.Bar.Baz.a = $a") end end end end
julia> include("test_mod.jl") Main.Foo julia> Foo.Bar.Baz.show_a() Foo.a = 1 Foo.Bar.a = 10 Foo.Bar.Baz.a = 100 julia> Foo.set_a(123) 123 julia> Foo.Bar.Baz.show_a() Foo.a = 123 Foo.Bar.a = 10 Foo.Bar.Baz.a = 100
julia> struct Fibo end julia> Base.iterate(::Fibo, state=(0, 1)) = if state[1] < 0 nothing else (state[1], (state[2], state[1] + state[2])) end julia> for x = Fibo() print(x, " ") end 0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 4181 6765 10946 17711 28657 46368 75025 121393 196418 317811 514229 832040 1346269 2178309 3524578 5702887 9227465 14930352 24157817 39088169 63245986 102334155 165580141 267914296 433494437 701408733 1134903170 1836311903 2971215073 4807526976 7778742049 12586269025 20365011074 32951280099 53316291173 86267571272 139583862445 225851433717 365435296162 591286729879 956722026041 1548008755920 2504730781961 4052739537881 6557470319842 10610209857723 17167680177565 27777890035288 44945570212853 72723460248141 117669030460994 190392490709135 308061521170129 498454011879264 806515533049393 1304969544928657 2111485077978050 3416454622906707 5527939700884757 8944394323791464 14472334024676221 23416728348467685 37889062373143906 61305790721611591 99194853094755497 160500643816367088 259695496911122585 420196140727489673 679891637638612258 1100087778366101931 1779979416004714189 2880067194370816120 4660046610375530309 7540113804746346429 julia> Base.length(::Fibo) = 93 julia> collect(Fibo()) 93-element Vector{Any}: 0 1 1 2 3 5 8 13 21 34 55 89 144 233 ⋮ 23416728348467685 37889062373143906 61305790721611591 99194853094755497 160500643816367088 259695496911122585 420196140727489673 679891637638612258 1100087778366101931 1779979416004714189 2880067194370816120 4660046610375530309 7540113804746346429
julia> for x = Iterators.enumerate(11 : 15) print(x, " ") end (1, 11) (2, 12) (3, 13) (4, 14) (5, 15) julia> for x = Iterators.zip(1 : 5, 11 : 15) print(x, " ") end (1, 11) (2, 12) (3, 13) (4, 14) (5, 15) julia> collect(Iterators.take(Fibo(), 10)) 10-element Vector{Any}: 0 1 1 2 3 5 8 13 21 34 julia> collect(Iterators.take(Iterators.drop(Fibo(), 10), 5)) 5-element Vector{Any}: 55 89 144 233 377 julia> collect(Iterators.take(Iterators.cycle(1 : 4), 10)) 10-element Vector{Int64}: 1 2 3 4 1 2 3 4 1 2 julia> collect(Iterators.take(Iterators.repeated(0), 5)) 5-element Vector{Int64}: 0 0 0 0 0 julia> collect(Iterators.product(1 : 3, 4 : 6)) 3×3 Matrix{Tuple{Int64, Int64}}: (1, 4) (1, 5) (1, 6) (2, 4) (2, 5) (2, 6) (3, 4) (3, 5) (3, 6) julia> for x = Iterators.product(1 : 3, 4 : 6) print(x, " ") end (1, 4) (2, 4) (3, 4) (1, 5) (2, 5) (3, 5) (1, 6) (2, 6) (3, 6) julia> collect(Iterators.flatten(Iterators.product(1 : 3, 4 : 6))) 18-element Vector{Int64}: 1 4 2 4 3 4 1 5 2 5 3 5 1 6 2 6 3 6 julia> collect(Iterators.partition(1 : 10, 3)) 4-element Vector{UnitRange{Int64}}: 1:3 4:6 7:9 10:10 julia> collect(Iterators.partition(collect(1 : 10), 3)) 4-element Vector{SubArray{Int64, 1, Vector{Int64}, Tuple{UnitRange{Int64}}, true}}: [1, 2, 3] [4, 5, 6] [7, 8, 9] [10] julia> collect(Iterators.filter(isodd, 1 : 10)) 5-element Vector{Int64}: 1 3 5 7 9 julia> for x = Iterators.reverse(1 : 10) print(x, " ") end 10 9 8 7 6 5 4 3 2 1 julia> collect(Iterators.take(Iterators.rest(Fibo(), (55, 89)), 10)) 10-element Vector{Any}: 55 89 144 233 377 610 987 1597 2584 4181
julia> a = 1 : 5 1:5 julia> for x = a if x == 3 break end println(x) end 1 2 julia> collect(a) 5-element Vector{Int64}: 1 2 3 4 5 julia> b = Iterators.Stateful(a) Base.Iterators.Stateful{UnitRange{Int64}, Union{Nothing, Tuple{Int64, Int64}}, Int64} (1:5, (1, 1), 5) julia> for x = b if x == 3 break end println(x) end 1 2 julia> collect(b) 2-element Vector{Int64}: 4 5 julia> isempty(b) true
B───D───F /│ │ A │ │ \│ │ C───E───G 図 : 経路図
リスト : 経路の探索 (keiro.jl) #= A = 1, B = 2, C = 3, D = 4, E = 5, F = 6, G = 7 =# # 隣接リスト (配列の配列) adjacent = [ [2, 3], [1, 3, 4], [1, 2, 5], [2, 5, 6], [3, 4, 7], [4], [5] ] # 深さ優先探索 function dfs(goal, xs) if xs[end] == goal println(xs) else for p = adjacent[xs[end]] if p in xs; continue; end push!(xs, p) dfs(goal, xs) pop!(xs) end end end # 幅優先探索 function bfs(start, goal) que = Array{Int,1}[[1]] while length(que) > 0 xs = popfirst!(que) if xs[end] == goal println(xs) else for p = adjacent[xs[end]] if p in xs; continue; end ys = copy(xs) push!(ys, p) push!(que, ys) end end end end # 反復進化 function ids(start, goal) function dfs(xs, limit) if length(xs) == limit if xs[end] == goal println(xs) end else for p = adjacent[xs[end]] if p in xs; continue; end push!(xs, p) dfs(xs, limit) pop!(xs) end end end for limit = 1 : length(adjacent) println("----- $limit -----") dfs([1], limit) end end println("----- dfs -----") dfs(6, [1]) println("----- bfs -----") bfs(1, 6) println("----- ids -----") ids(1, 6)
$ julia keiro.jl ----- dfs ----- [1, 2, 3, 5, 4, 6] [1, 2, 4, 6] [1, 3, 2, 4, 6] [1, 3, 5, 4, 6] ----- bfs ----- [1, 2, 4, 6] [1, 3, 2, 4, 6] [1, 3, 5, 4, 6] [1, 2, 3, 5, 4, 6] ----- ids ----- ----- 1 ----- ----- 2 ----- ----- 3 ----- ----- 4 ----- [1, 2, 4, 6] ----- 5 ----- [1, 3, 2, 4, 6] [1, 3, 5, 4, 6] ----- 6 ----- [1, 2, 3, 5, 4, 6] ----- 7 -----
リスト : ナンバープレースの解法 (numplace.jl) function check(board, x, y, n) # 縦横のチェック for i = 1 : 9 if board[x, i] == n || board[i, y] == n return false end end # 枠のチェック x1 = div(x - 1, 3) * 3 + 1 y1 = div(y - 1, 3) * 3 + 1 for i = 0 : 2, j = 0 : 2 if board[x1 + i, y1 + j] == n return false end end true end function solver(board, x, y) if y == 10 println(board) elseif x == 10 solver(board, 1, y + 1) elseif board[x, y] != 0 solver(board, x + 1, y) else for n = 1 : 9 if !check(board, x, y, n); continue; end board[x, y] = n solver(board, x + 1, y) board[x, y] = 0 end end end # 問題 (出典: 数独 - Wikipedia の問題例) q00 = [ 5 3 0 0 7 0 0 0 0; 6 0 0 1 9 5 0 0 0; 0 9 8 0 0 0 0 6 0; 8 0 0 0 6 0 0 0 3; 4 0 0 8 0 3 0 0 1; 7 0 0 0 2 0 0 0 6; 0 6 0 0 0 0 2 8 0; 0 0 0 4 1 9 0 0 5; 0 0 0 0 8 0 0 7 9 ] println(q00) println("--------") @time solver(copy(q00), 1, 1) println("--------")
$ julia numplace.jl [5 3 0 0 7 0 0 0 0; 6 0 0 1 9 5 0 0 0; 0 9 8 0 0 0 0 6 0; 8 0 0 0 6 0 0 0 3; 4 0 0 8 0 3 0 0 1; 7 0 0 0 2 0 0 0 6; 0 6 0 0 0 0 2 8 0; 0 0 0 4 1 9 0 0 5; 0 0 0 0 8 0 0 7 9] -------- [5 3 4 6 7 8 9 1 2; 6 7 2 1 9 5 3 4 8; 1 9 8 3 4 2 5 6 7; 8 5 9 7 6 1 4 2 3; 4 2 6 8 5 3 7 9 1; 7 1 3 9 2 4 8 5 6; 9 6 1 5 3 7 2 8 4; 2 8 7 4 1 9 6 3 5; 3 4 5 2 8 6 1 7 9] 0.078586 seconds (45.60 k allocations: 2.915 MiB, 87.88% compilation time) --------
1 から 9 までの数字を順番に並べ、間に + と - を補って 100 になる式を作ってください。ただし、1 の前に - 符号はつけないものとします。
例 : 1 + 2 + 3 - 4 + 5 + 6 + 78 + 9 = 100
リスト : 小町算 (komachi.jl) # 計算 function calc_expr(nums, ops) a = nums[1] i = 2 for op = ops a += op == '+' ? nums[i] : -nums[i] i += 1 end a end # 表示 function print_expr(nums, ops) print(nums[1]) i = 2 for op = ops print(op == '+' ? " + " : " - ") print(nums[i]) i += 1 end println(" = 100") end # 小町算の解法 function komachi(n, nums, ops) if n == 10 if calc_expr(nums, ops) == 100 print_expr(nums, ops) end else for op = ['+', '-'] push!(ops, op) push!(nums, n) komachi(n + 1, nums, ops) pop!(nums) pop!(ops) end m = nums[end] nums[end] = m * 10 + n komachi(n + 1, nums, ops) nums[end] = m end end komachi(2, [1], [])
$ julia komachi.jl 1 + 2 + 3 - 4 + 5 + 6 + 78 + 9 = 100 1 + 2 + 34 - 5 + 67 - 8 + 9 = 100 1 + 23 - 4 + 5 + 6 + 78 - 9 = 100 1 + 23 - 4 + 56 + 7 + 8 + 9 = 100 12 + 3 + 4 + 5 - 6 - 7 + 89 = 100 12 + 3 - 4 + 5 + 67 + 8 + 9 = 100 12 - 3 - 4 + 5 - 6 + 7 + 89 = 100 123 + 4 - 5 + 67 - 89 = 100 123 + 45 - 67 + 8 - 9 = 100 123 - 4 - 5 - 6 - 7 + 8 - 9 = 100 123 - 45 - 67 + 89= 100
# # cat.jl : ファイルの連結 # # Copyright (C) 2016-2021 Makoto Hiroi # function cat(fin) for line = eachline(fin) println(line) end end # if length(ARGS) == 0 cat(stdin) else for name = ARGS open(name, "r") do fin cat(fin) end end end
# # wc.jl : 単語のカウント # # Copyright (C) 2016-2021 Makoto Hiroi # function wc(fin) word = 0 inword = false while !eof(fin) c = read(fin, Char) if isspace(c) inword = false elseif !inword inword = true word += 1 end end word end if length(ARGS) == 0 println(wc(stdin)) else open(ARGS[1], "r") do fin println(wc(fin)) end end
julia> split("foo bar baz oops!") 4-element Vector{SubString{String}}: "foo" "bar" "baz" "oops!"
# # grep.jl : 文字列の検索 # # Copyright (C) 2016-2021 Makoto Hiroi # function grep(fin, key) for line = eachline(fin) if occursin(key, line) println(line) end end end if length(ARGS) == 1 # 検索文字列のみ grep(stdin, ARGS[1]) elseif length(ARGS) >= 2 open(ARGS[2]) do fin grep(fin, ARGS[1]) end else println("usage: julia grep.jl key [filename]") end
julia> occursin("hello", "hello, Julia!") true julia> occursin("julia", "hello, Julia!") false
# # tr.jl : 文字の置換 # # Copyright (C) 2016-2021 Makoto Hiroi # function tr(fin, s1, s2) while !eof(fin) c = read(fin, Char) n = findfirst(isequal(c), s1) if n != nothing c = s2[n] end print(c) end end if length(ARGS) >= 2 if length(ARGS[1]) == length(ARGS[2]) if length(ARGS) == 2 tr(stdin, ARGS[1], ARGS[2]) else open(ARGS[3], "r") do fin tr(fin, ARGS[1], ARGS[2]) end end else println("第 1 引数と第 2 引数の長さが異なる") end else println("usage: julia tr str1 str2 [filename]") end
julia> a = "abcde" "abcde" julia> a[1] 'a': ASCII/Unicode U+0061 (category Ll: Letter, lowercase) julia> a[5] 'e': ASCII/Unicode U+0065 (category Ll: Letter, lowercase) julia> a[2:4] "bcd"
julia> findfirst(isequal('J'), "hello, Julia!") 8 julia> findfirst(isequal('j'), "hello, Julia!") julia> findfirst("Julia", "hello, Julia!") 8:12 julia> findfirst("JuliA", "hello, Julia!")
# # gres.jl : 文字列の置換 # # Copyright (C) 2016-2021 Makoto Hiroi # function gres(fin, pat, r) for line = eachline(fin) println(replace(line, pat => r)) end end if length(ARGS) == 2 gres(STDIN, ARGS[1], ARGS[2]) elseif length(ARGS) == 3 open(ARGS[3], "r") do fin gres(fin, ARGS[1], ARGS[2]) end else println("usage: julia gres.jl pattern replace [filename]") end
julia> replace("foo bar baz foo bar baz oops", "foo" => "FOO") "FOO bar baz FOO bar baz oops" julia> replace("foo bar baz foo bar baz oops", "foo" => "FOO", count=1) "FOO bar baz foo bar baz oops"
# # cp.jl : ファイルのコピー # # Copyright (C) 2016-2021 Makoto Hiroi # # バイト単位のコピー function cp(fin, fout) while !eof(fin) write(fout, read(fin, UInt8)) end end # バッファに読み込む function cp1(fin, fout) local n buff = Array{UInt8, 1}(undef, 16) while (n = readbytes!(fin, buff)) == 16 write(fout, buff) end write(fout, buff[1 : n]) end if length(ARGS) == 2 open(ARGS[1], "r") do fin open(ARGS[2], "w") do fout cp(fin, fout) end end else println("usage: julia cp.jl src dst") end
# # entoropy.jl : ファイルのエントロピーを求める # # Copyright (C) 2016-2021 Makoto Hiroi # function entoropy(fin) count = zeros(Int, 256) while !eof(fin) c = read(fin, UInt8) count[c + 1] += 1 end total = sum(count) e = 0.0 for x = count if x == 0; continue; end p = x / total e += - p * log(2, p) end e, e * total / 8 end if length(ARGS) == 1 open(ARGS[1], "r") do fin println(entoropy(fin)) end else println("usage: julia entoropy.jl filename") end