Odin programming language

bmaxa

Legenda
Poruka
70.815
Nov jezik, svidja mi se, kompajliran naravno, poshto mrzim interpretere (osim Pike-a )
Elem.
Nema automatic memory managment, chak ni C++ RAII, no ima defer {} shto je postalo
popularno od Golanga. Jezici na koje chekam su Jai i google Carbon.
No Odin je tu, pa sam malo uchio prethodnih par dana.
Elem, ima tagovane unije, generics, i sve shto treba. Ne podrzhava OO naravno,
poshto to vishe nije u trendu...
E sad ima native string tip koji drzhi unicode. Ima slajseve, dinamicke nizove,
ne podrzava pointer aritmetiku native, zato sto autor misli da slajsevi to
zamenjuju, no moze da se izvede po potrebi.
Funkcije mogu da vracaju vise rezultata kao u Golang, pa je tu veoma slican
error handling.
Da ne pricam mnogo, ovo sam pretabao na njega, k-nucleotide bench,
koji chita lanac DNK, i pronalazi odredjene kombinacije i frekvenciju
pojavljivanja.
input.txt za pogram je ovde:
https://www.icloud.com/iclouddrive/029_4lu4NQuBbeK0g-y23aPrg#input
kompajlira se sa odin build ime_dira_gde_je_program -o:speed
startuje sa ime_programa.bin < input.txt
izlaz izgleda ovako:
Kod:
bmaxa@Branimirs-Air odinprograms % time ./k-nucleotide.bin < k-nucleotide/input.txt
A 30.295
T 30.151
C 19.800
G 19.754

AA 9.177
TA 9.132
AT 9.131
TT 9.091
CA 6.002
AC 6.001
AG 5.987
GA 5.984
CT 5.971
TC 5.971
GT 5.957
TG 5.956
CC 3.917
GC 3.911
CG 3.909
GG 3.902

1471758    GGT
446535    GGTA
47336    GGTATT
893    GGTATTTTAATT
893    GGTATTTTAATTTATAGT

./k-nucleotide.bin < k-nucleotide/input.txt 37.13s user 0.90s system 273% cpu 13.917 total
FACTOR je konstanta koja odredjuje broj threadova, poshto nisam nashao da ima u core
libu broj detektovanih cpu-a. Povetjajte po zhelji.
 

Prilozi

  • main.odin.zip
    1,4 KB · Pregleda: 2
evo josh jednog programcheta, mogu priznati nashao sam bug u chitanju csv fajlova, read_all vratja nil ukoliko ne naleti na .EOF,
a .EOF je promenjen u .No_Progress, da se to detektovati, netju da prijavljujem :p
Elem ovaj program poredi dva csv fajla SKU-a (stock keeping unita) i odredjuje broj razlika.
Kod:
package compare

import "core:fmt"
import "core:io"
import "core:encoding/csv"
import "core:time"
import "core:os"

marker_feed :: "compare/marker.txt"
current_feed :: "compare/current.txt"

main :: proc() {
  start := time.now()
  defer timeTrack(start,"Total Processing")
  marker_feed_dict := parseTSV(marker_feed)
  current_feed_dict := parseTSV(current_feed)
  rem :: proc(m:$T){
    for value in m {
      delete(value)
    }
  }
  defer { rem(marker_feed_dict);rem(current_feed_dict);delete(marker_feed_dict);delete(current_feed_dict) }
  fmt.printf(" \nMarker Feed # %d , Current Feed # %d \n\n", len(marker_feed_dict), len(current_feed_dict))
  fmt.printf(" SKU Count present in Dec 21st and missing in Oct 8 %d \n", len(compare_feed_dict(marker_feed_dict, current_feed_dict)))
  fmt.printf(" SKU Count present in Oct 8th  and missing in Dec 21 %d \n", len(compare_feed_dict(current_feed_dict, marker_feed_dict)))
}
compare_feed_dict::proc(a:map[string][]string, b:map[string][]string)-> map[string][]string {
  fmt.printf(" Marker Feed # %d , Current Feed # %d", len(a), len(b))
  missing_sku := make(map[string][]string)
  for key, value in a {
      if _, ok := b[key]; !ok {
      missing_sku[key] = value
    }
  }
  return missing_sku
}

parseTSV:: proc (filename: string)->map[string][]string {
  f,err := os.open(filename)
  defer os.close(f)
  if err != os.ERROR_NONE {
    fmt.println("cannot open",filename)
    return nil
  }
  reader := io.Reader{stream = os.stream_from_handle(f) }
  defer io.destroy(reader.stream)
  csvParser: csv.Reader
  csv.reader_init(&csvParser,reader)
  csvParser.comma = '\t'
  csvParser.lazy_quotes = true
  defer csv.reader_destroy(&csvParser)
  err1 : csv.Error
  records: [dynamic][]string = make([dynamic][]string,0)
  record : []string
  defer delete(records)
  for {
    record,err1 = csv.read(&csvParser)
    if err1 != nil {
      delete(record)
      break
    }
    append(&records,record)
  }
  if err1 != nil && err1 != io.Error.No_Progress{
    fmt.println("error parsing", err1)
  }
  rc := make(map[string][]string)
  delete(records[0])
  recordsiter := records[1:] // first is header
  for record in recordsiter {
    rc[record[3]]=record
  }

  return rc
}

timeTrack::proc(start: time.Time, name: string) {
  fmt.printf("--- %s took %v milliseconds ---\n", name, time.duration_milliseconds(time.since(start)))
}
https://www.icloud.com/iclouddrive/0f2ZUcjPahX1J7yegBlXvAH8g#compare
 
lici na Go, izgleda da izbacujemo ';' go i js su tu na pola puta.

sta radi konstrukt:

csvParser: csv.Reader

ili
err1 : csv.Error
records: [dynamic][]string = make([dynamic][]string,0)
record : []string

implicitne deklaracije variabila?
svidja mi se citljivost
baci neki link na neki manual
to je definisanje varijable koja tip automatski preuzima kroz inicijalizaciju, isto kao u Go a znachi ime : nespecificaran_tip = vrednost_od_koje_dobija_tip
https://odin-lang.org/docs/overview/
 
Па када имаш толико времена, седи и начин да пишеш нормално.
Почни од тога да је српско писмо фонетско, један фонет једна графема.
Када савладаш матерњи, јави се.
Look, I can write decent English, with this keyboard, but since few will
understand, I am forced to write Serbian :p
 
Look, I can write decent English, with this keyboard, but since few will
understand, I am forced to write Serbian :p
Не тупи, дугмићи су кинески, као и на мојој тастатури и није реч о дугмићима него правопису!
И ја куцкам са qwerty тастатуре тако да те глупости са тастатуром можеш продавати неком другом.
 
A sad josh jedan mali program:
https://www.icloud.com/iclouddrive/01exYHXFirwkB8PIhhPCaq0nQ#2dsrch
Kod:
package main

import "core:fmt"
import "core:strconv"
import "core:bufio"
import "core:os"
import "core:strings"

main :: proc() {
  r := openReader()
  defer bufio.reader_destroy(&r)
  line, err := bufio.reader_read_string(&r, '\n')
  line = strings.trim_right(line,"\n")
  tests,ok := strconv.parse_int(line)
  delete(line)
  if !ok {
    fmt.println("error reading tests")
    return
  }
  for _ in 0..<tests{
    G := readMatrix(&r)
    P := readMatrix(&r)
    rem :: proc(m:[dynamic]string) {
        for i in m{
          delete(i)
        }
        delete(m)
    }
    defer {
      rem(G);rem(P)
    }
    found := false
    for i in 0..<len(G)-len(P)+1 {
      for _,j in P {
        index := strings.index(G[i+j],P[j])
        if index == -1 { break }
        else if j == len(P) - 1 {
          found = true
          break
        }
      }
    }
    if found { fmt.println("YES") }
    else { fmt.println("NO") }
  }
  fmt.println("tests:",tests)
}

readMatrix :: proc(r:^bufio.Reader) -> (result:[dynamic]string) {
  line, err := bufio.reader_read_string(r, '\n')
  flds := strings.fields(line)
  defer delete (line)
  result = make([dynamic]string,0)
  fmt.println(flds)
  R,ok := strconv.parse_int(flds[0])
  fmt.println("R:",R)
  delete(flds)
  if !ok {
    fmt.println("cannot read number of rows")
    return
  }
  for _ in 0..<R {
    line,_:= bufio.reader_read_string(r, '\n')
    line = strings.trim_right(line,"\n")
    append(&result, line)
  }
  fmt.println("result len:",len(result))
  return
}

openReader :: proc()->bufio.Reader {
  r: bufio.Reader
  bufio.reader_init(&r, {os.stream_from_handle(os.stdin)})
  return r
}
u principu primer kako chitati fajl... pretrazhivanje matrica...
Kod:
bmaxa@Branimirs-Air odinprograms % ./2dsrch.bin < 2dsrch/out.txt
["1000", "1000"]
R: 1000
result len: 1000
["188", "475"]
R: 188
result len: 188
YES
["1000", "1000"]
R: 1000
result len: 1000
["204", "274"]
R: 204
result len: 204
YES
["1000", "1000"]
R: 1000
result len: 1000
["362", "483"]
R: 362
result len: 362
NO
["1000", "1000"]
R: 1000
result len: 1000
["4", "4"]
R: 4
result len: 4
YES
["1000", "1000"]
R: 1000
result len: 1000
["4", "4"]
R: 4
result len: 4
NO
tests: 5
 
Poboljshana verzija k-nucleotide, custom implementirana Hash tabela, i enkodovanje gena umesto hashiranje stringa.
Ovde se mogu videti i generichke strukture i generichke f-je, i to mozhe da se upotrebi za druge stvari...
btw, neshto forum baguje kod odin pograma, ne mogu da ubacim izmedju code tagova, javlja greshku :P
 

Prilozi

  • main.odin.zip
    2,1 KB · Pregleda: 0
a sada primer kreiranja binarnog stabla i korishtjenja Arena alokatora;
Kod:
package main

import "core:fmt"
import "core:strconv"
import "core:os"
import "core:math"
import "core:mem"

MIN_DEPTH :: 4
main :: proc() {
  n := strconv.parse_int(os.args[1]) or_else 10
  max_depth := math.max(MIN_DEPTH+2,n)
  allocbuf := make([dynamic]u8,int(math.pow(f64(2),f64(max_depth+1)))*max_depth*size_of(Node))
  arena : mem.Arena
  mem.arena_init(&arena,allocbuf[:])
  global_allocator := context.allocator
  context.allocator = mem.arena_allocator(&arena)
  {
    stretch_depth := max_depth + 1;
    stretch_tree := makeTree(stretch_depth)
    defer { free_all() }
    fmt.printf("stretch tree of depth %d\t check: %d\n", stretch_depth, check(stretch_tree) );
  }
  long_lived_tree := makeTree(max_depth)
  defer { delete (allocbuf) }
  depth:int= MIN_DEPTH;
  for ;depth <= max_depth; depth += 2 {
    allocbuf := make([dynamic]u8,int(math.pow(f64(2),f64(depth+1)))*depth*size_of(Node),global_allocator)
    defer delete(allocbuf)
    arena : mem.Arena
    mem.arena_init(&arena,allocbuf[:])
    context.allocator = mem.arena_allocator(&arena)
    iterations := 1 << u8(max_depth - depth + MIN_DEPTH)
    sum: u64 = 0
    for _ in 0..<iterations {
      tree := makeTree(depth)
      defer { free_all() }
      sum += u64(check(tree))
    }
    fmt.printf("%d\t trees of depth %d\t check: %d\n", iterations, depth, sum )
  }

  fmt.printf("long lived tree of depth %d\t check: %d\n", max_depth, check(long_lived_tree))
}

Node :: struct {
  left,right:^Node,
}

makeTree::proc(depth:int)->^Node {
  node := new(Node)
  if node == nil {
    fmt.println("alloc error")
    return node
  }
  if depth > 0 {
    node.left = makeTree(depth-1)
    node.right = makeTree(depth-1)
  }
  return node
}
check::proc(tree:^Node)->int {
  sum : int = 1
  if tree == nil { return 0 }
  if tree.left != nil {
    sum += check(tree.left)
  }
  if tree.right != nil {
    sum += check(tree.right)
  }
  return sum
}
 
Program za rahunanje cifara broje e:
Kod:
package main

import "core:fmt"
import "core:math"
import "core:math/big"
import "core:strconv"
import "core:os"

main :: proc () {
  big.initialize_constants()
  defer big.destroy_constants()
  n :i64= 27
  if len(os.args)>1 {
    if _n,ok := strconv.parse_i64(os.args[1]); ok {
      n = _n
    }
  }
  k := binary_search(n)
  p,q := sum_terms(0, k-1)
  defer { big.destroy(p);big.destroy(q);free(p);free(q)}
  big.add(p,p,q)
  a := new(big.Int)
  defer {big.destroy(a);free(a)}
  big.set(a,10)
  big.pow(a,a,int(n-1))
  answer := p
  big.mul(answer,answer,a)
  big.div(answer,answer,q)
  s,_ := big.int_to_string(answer)
  defer delete(s)
  for i := i64(0); i<n;i+=10 {
    if i+10<=n {
      fmt.printf("%s\t:%d\n",s[i:i+10],i+10)
    } else {
      fmt.printf("%-10s\t:%d\n",s[i:n],n)
    }
  }
}
sum_terms::proc(a,b:i64)->(l,r:^big.Int){
  l,r = new(big.Int),new(big.Int)
  if b==a+1 {
    big.copy(l,big.INT_ONE)
    big.set(r,b)
    return
  }
  mid := (a+b)/2
  p_left,q_left := sum_terms(a,mid)
  defer { big.destroy(p_left);big.destroy(q_left);free(p_left);free(q_left)}
  p_right,q_right := sum_terms(mid,b)
  defer { big.destroy(p_right);big.destroy(q_right);free(p_right);free(q_right)}
  big.mul(l,p_left,q_right)
  big.add(l,l,p_right)
  big.mul(r,q_left,q_right)
  return
}
binary_search::proc(n:i64)->i64{
  a,b : i64 = 0,1
  for !test_k(n,b) {
    a=b
    b *= 2
  }
  for b-a>1 {
    m := a+(b-a)/2
    if test_k(n,m){
      b = m
    } else {
      a = m
    }
  }
  return b
}
test_k::proc(n,k:i64)->bool {
  if k <= 0 {return false}
  k := f64(k)
  ln_k_factorial := k*math.ln(k)-k+0.5*math.ln(math.TAU*k)
  log10_k_factorial := ln_k_factorial/math.LN10
  return log10_k_factorial>=f64(n+50)
}
 

Back
Top