### header
#[
# 概要
nimのコレクション操作をコツコツと。
* algorithm
* tables
* sets
* lists
* queues
* critbits
* intsets
## 以下メモ
]#
### imports
import algorithm,tables,hashes,math
import sets,lists,critbits,sequtils,queues,intsets,strutils
### 同じ値で埋める(fill)
block:
var ary : array[0..3,int]
# 範囲指定なし
fill(ary,1)
for x in ary:
echo x
# 範囲指定
fill(ary,0,3,5)
for x in ary:
echo x
### リバース
block:
var ary = @[1,2,3,4]
echo ary
ary.reverse
echo ary
var ary2 = ary.reversed
echo ary2
### 検索(バイナリサーチ)
block:
var ary = @[1,2,3,4,5,6,7,8,9]
echo ary.binarySearch(8)
echo ary.smartBinarySearch(3)
### lowerBound
block:
var ary = @[1,2,3,4,5,6]
for x in 0..10 :
echo x," ",ary.lowerBound(x)
### ソート
block:
# cmp関数でソート
var ary = @[3,4,1,8,6,5,7,0,1]
echo ary
ary.sort(system.cmp[int])
echo ary
### ソート(procを渡す)
block:
var ary = @[3,4,1,8,6,5,7,0,1]
ary.sort( proc (x,y:int) : int = cmp(x,y) )
echo ary
### ソート(doを使ったソート)
block:
var ary = @[3,4,1,8,6,5,7,0,1]
ary.sort do (x,y:int) -> int : result = cmp(x,y)
echo ary
### ソート(sorted)
block:
# doを使ったソート
var ary = @[3,4,1,8,6,5,7,0,1]
var ary2 = ary.sorted do (x,y:int) -> int :
result = cmp(x,y)
echo "original=",ary
echo "sorted =",ary2
echo ary.isSorted(system.cmp[int])
echo ary2.isSorted(system.cmp[int])
### 順列 (prevPermutation)
block:
var ary = @[1,2,4,3]
ary.prevPermutation
echo ary
### templateを使ったソート
block:
var ary = @[3,4,1,8,6,5,7,0,1]
echo ary.sortedByIt(it)
### hashesによるハッシュを取得
block:
var name1 = "Mr.スポック"
var name2 = "Mr.スポック"
echo name1.hash == name2.hash
### tables サンプル
#[
tableは、ハッシュキーを拡張したものっぽいです。
独自構造体?をキーにする場合は、hash関数を実装しないと動作しないようです。
]#
type
Person = object
firstName, lastName: string
proc hash(x: Person): Hash =
## Piggyback on the already available string hash proc.
##
## Without this proc nothing works!
result = x.firstName.hash !& x.lastName.hash
result = !$result
proc `$`(x: Person) : string =
result = x.firstName
block:
var
salaries: Table[Person,int] = initTable[Person, int]()
p1, p2, p3: Person
p1.firstName = "Steven"
p1.lastName = "Rogers"
salaries[p1] = 30_000
p2.firstName = "Tony"
p2.lastName = "Stark"
salaries[p2] = 40_000
p3.firstName = "Bruce"
p3.lastName = "Banner"
echo "contains=",salaries.contains(p1)
echo "get value=",salaries[p1]
echo "length=",salaries.len
echo "get or default=", salaries.getOrDefault(p3)
### toTableを使った初期化
let salaries2: Table[Person,int] = {p1:30_000,p2:40_000}.toTable
echo salaries == salaries2
#salaries2[p3] = 10_000
let salaries3: OrderedTable[Person,int] = {p1:30_000,p2:40_000}.toOrderedTable
for k,v in salaries :
echo k
for k,v in salaries2 :
echo k
for k,v in salaries3 :
echo k
### COuntTable キーのみで、その数をカウントする
block:
var count = initCountTable[string]()
count.inc("DEC")
count.inc("DEC")
count.inc("ABC")
count.inc("ABC")
count.inc("ABC")
echo count
count.sort
echo count
### HashSet
block:
# initSetで初期化
var hashSet1: HashSet[string] = initSet[string]()
hashSet1.incl("key1")
hashSet1.incl("key2")
echo "hashSet1=>",hashSet1
echo "contains=>",hashSet1.contains("key1")
# 取り除く
hashSet1.excl("key1")
hashSet1.excl("key2")
echo "hashSet1=>",hashSet1
# 再び追加
hashSet1.incl("key1")
hashSet1.incl("key2")
# toSetで初期化
var hashSet2 = ["key1","key2"].toSet
echo "hashSet2=>",hashSet2
echo "equals =>",hashSet1 == hashSet2
for x in hashSet1.items :
echo "item=>",x
### OrderedHashSet(値を追加した順番を保持)
block:
# initOrderedSetで初期化
var hashSet1: OrderedSet[string] = initOrderedSet[string]()
hashSet1.incl("key1")
hashSet1.incl("key2")
echo "hashSet1=>",hashSet1
# toOrderedSetで初期化
var hashSet2: OrderedSet[string] = ["key1","key2"].toOrderedSet
echo "hashSet2=>",hashSet2
#echo hashSet1 == hashSet2
var hashSet3: OrderedSet[string] = initOrderedSet[string]()
hashSet3.incl("key1")
hashSet3.incl("key2")
echo "equals=>",hashSet1 == hashSet3
### 双方向リンクリスト
block:
var list1 : DoublyLinkedList[int] = initDoublyLinkedList[int]()
# 末尾に追加
list1.append(1)
list1.append(2)
list1.append(3)
list1.append(4)
echo "list1=>",list1
# 先頭に追加
list1.prepend(4)
list1.prepend(5)
list1.prepend(6)
list1.prepend(7)
echo "list1=>",list1
# 検索
echo "find=>",list1.find(7).value
# 削除
list1.remove(list1.find(7))
echo "list1=>",list1
### Queue
block:
var q : Queue[string] = initQueue[string]()
q.enqueue("abc")
q.add("def")
q.add("ghi")
echo "len=>",q.len
echo "q =>",q
var v = q.dequeue()
echo "v =>",v
echo "q =>",q
for v in q :
echo "val=>",v
echo "q =>",q
### Crit-Bit ハッシュ ( http://blog.livedoor.jp/dankogai/archives/51853853.html )
block:
var r: CritBitTree[string]
r["abc"] = "ABC"
r["def"] = "DEF"
echo "tree=>",r.contains("abc")
for x in r.keys :
echo "key=>",x
for k,v in r :
echo "key=>",k," val=>",v
### intsets
block:
var intSet: IntSet = initIntSet()
# キーを追加
intSet.incl 1
intSet.incl 2
# ダンプ
echo intSet
for x in intSet.items :
echo "key=>",x
# 格納されているか?
echo "contains(1)=>",intSet.contains(1)
intSet.excl 1
echo "contains(1)=>",intSet.contains(1)
# containsOrInclを試す
echo "contains(3)=>",intSet.contains(3)
echo " =>",intSet.containsOrIncl(3)
echo "contains(3)=>",intSet.contains(3)
### sequtils.concat
block:
# サンプルのまんま
let
s1 = @[1, 2, 3]
s2 = @[4, 5]
s3 = @[6, 7]
total = concat(s1, s2, s3)
echo total
### sequtils.cycle
block:
let
s = @[1, 2, 3]
total = s.cycle(3)
echo total
### sequtils.repeat
block:
let
total1 = repeat(5, 3)
total2 = repeat(@[1,2,3], 3)
echo "total1=>",total1
echo "total2=>",total2
### sequtils.deduplicate
block:
let
dup1 = @[1, 1, 3, 4, 2, 2, 8, 1, 4]
dup2 = @["a", "a", "c", "d", "d"]
unique1 = deduplicate(dup1)
unique2 = deduplicate(dup2)
echo "unique1=>",unique1
echo "unique2=>",unique2
### sequtils.zip
block:
let
short = @[1, 2, 3]
long = @[6, 5, 4, 3, 2, 1]
words = @["one", "two", "three"]
zip1 = zip(short, long)
zip2 = zip(short, words)
echo "zip1=>", zip1
echo "zip2=>", zip2
echo "zip1[2].b=>", zip1[2].b
echo "zip2[2].b=>", zip2[2].b
### sequtils.distribute
block:
let numbers = @[1, 2, 3, 4, 5, 6, 7]
echo "(2 )=>",numbers.distribute(2)
echo "(2,false)=>",numbers.distribute(2, false)
echo "(3 )=>",numbers.distribute(3)
echo "(3,false)=>",numbers.distribute(3, false)
echo "(4 )=>",numbers.distribute(4)
echo "(4,false)=>",numbers.distribute(4, false)
echo "(5 )=>",numbers.distribute(5)
echo "(5,false)=>",numbers.distribute(5, false)
echo "(6 )=>",numbers.distribute(6)
echo "(6,false)=>",numbers.distribute(6, false)
### sequtils.map
block:
let
a = @[1, 2, 3, 4]
b = map(a, proc(x: int): string = $x)
c = a.map do (x:int) -> string : $(x+1)
echo "b=>",b
echo "c=>",c
### sequtils.apply(var 引数が渡される) deprecatedらしいです。
block:
var a = @["1", "2", "3", "4"]
echo a
map(a, proc(x: var string) = x &= "42")
echo a
### sequtils.filter
block:
let
colors = @["red", "yellow", "black"]
f1 = filter(colors, proc(x: string) : bool = x.len < 6)
f2 = filter(colors) do (x: string) -> bool : x.len > 5
echo "f1=>",f1
echo "f2=>",f2
echo "abc".startsWith("a")
let f3 = colors.map(
proc(x:string) : string = x & " is color"
).filter(
proc (x:string) : bool = x.find("black") != -1
)
echo f3
### sequtils.keepIf
block:
var floats = @[13.0, 12.5, 5.8, 2.0, 6.1, 9.9, 10.1]
keepIf(floats, proc(x: float): bool = x > 10)
echo "floats=>",floats
### sequtils.delete
block:
let outcome = @[1,1,1,1,1,1,1,1]
var dest = @[1,1,1,2,2,2,2,2,2,1,1,1,1,1]
dest.delete(3, 8)
echo "outcom=>",outcome
### sequtils.insert
block:
var dest = @[1,1,1,1,1,1,1,1]
let
src = @[2,2,2,2,2,2]
outcome = @[1,1,1,2,2,2,2,2,2,1,1,1,1,1]
dest.insert(src, 3)
echo "dest=>",dest
### sequtils.all すべての要素にたいして条件を満たすかどうかをチェック
block:
let numbers = @[1, 4, 5, 8, 9, 7, 4]
echo all(numbers, proc (x: int): bool = return x < 10)
echo all(numbers, proc (x: int): bool = return x < 9)
### sequtils.any どれか1つの要素にたいして条件を満たすかどうかをチェック
block:
let numbers = @[1, 4, 5, 8, 9, 7, 4]
echo any(numbers, proc (x: int): bool = return x < 10)
echo any(numbers, proc (x: int): bool = return x > 9)
## sequtils マクロ
### filterIt
block:
let
temperatures = @[-272.15, -2.0, 24.5, 44.31, 99.9, -113.44]
acceptable = filterIt(temperatures, it < 50 and it > -10)
notAcceptable = filterIt(temperatures, it > 50 or it < -10)
echo "acceptable =>",acceptable
echo "notAcceptable=>",notAcceptable
### keepIfIf
block:
var candidates = @["foo", "bar", "baz", "foobar"]
keepItIf(candidates, it.len == 3 and it[0] == 'b')
echo "candidates=>",candidates
### allIt
block:
let numbers = @[1, 4, 5, 8, 9, 7, 4]
echo "numbers=>",allIt(numbers, it < 10)
echo "numbers=>",allIt(numbers, it < 9)
### anyIt
block:
let numbers = @[1, 4, 5, 8, 9, 7, 4]
echo "numbers=>",anyIt(numbers, it > 8)
echo "numbers=>",anyIt(numbers, it > 9)
### toSeq
block:
let
numeric = @[1, 2, 3, 4, 5, 6, 7, 8, 9]
odd_numbers = toSeq(filter(numeric) do (x: int) -> bool:
if x mod 2 == 1:
result = true)
echo "odd_numbers", odd_numbers
### foldl
block:
let
numbers = @[5, 9, 11]
addition = foldl(numbers, a + b)
subtraction = foldl(numbers, a - b)
multiplication = foldl(numbers, a * b)
words = @["nim", "is", "cool"]
concatenation = foldl(words, a & b)
echo addition , " Addition is (((5)+9)+11)"
echo subtraction , " Subtraction is (((5)-9)-11)"
echo multiplication , " Multiplication is (((5)*9)*11)"
echo concatenation
### foldl 初期値あり
block:
let
numbers = @[0, 8, 1, 5]
digits = foldl(numbers, a & (chr(b + ord('0'))), "")
echo digits
### foldr
block:
let
numbers = @[5, 9, 11]
addition = foldr(numbers, a + b)
subtraction = foldr(numbers, a - b)
multiplication = foldr(numbers, a * b)
words = @["nim", "is", "cool"]
concatenation = foldr(words, a & b)
echo addition , " Addition is (5+(9+(11)))"
echo subtraction , " Subtraction is (5-(9-(11)))"
echo multiplication, " Multiplication is (5*(9*(11)))"
echo concatenation
### mapIt
block:
let
nums = @[1, 2, 3, 4]
strings = nums.mapIt(string, $(4 * it))
echo "strings=>",strings
### mapIt
block:
let
nums = @[1, 2, 3, 4]
strings = nums.mapIt(4 * it)
echo "strings=>",strings
### applyIt(自分自身に適用)
block:
var nums = @[1, 2, 3, 4]
nums.applyIt(it * 3)
echo nums[0] + nums[3]
### newSeqWith
import random
block:
var seq2D = newSeqWith(4, newSeq[bool](4))
seq2D[0][0] = true
seq2D[1][0] = true
seq2D[0][1] = true
echo seq2D
var seqRand = newSeqWith(4, random(4))
echo seqRand