Jakub Adamski 444341 10.5 Zadanie 0.1 ------------------------------------- Wykorzystany przykład events03.tcl oraz events03a.tcl. Polecenie fiber to korutina. Możemy np przełączać procesor na kolejne fibery poleceniem fiber yield. Nie załączam kodu - jest na stronie. /// wydruk events03.tcl 0: aaaaaaaaa 1: aaaaaaaaa 2: aaaaaaaaa 0: bbbbbbbbb 1: bbbbbbbbb 2: bbbbbbbbb /// koniec wydruku events03.tcl /// wydruk events03a.tcl #% 2 0 1 3 #% 1 0 3 2 #% 1 0 2 3 #% 0 3 2 1 #% 0 2 3 1 #% 0 3 1 2 #% 0 2 1 3 #% 0 1 3 2 #% 0 1 2 3 /// koniec wydruku events03a.tcl Zadanie 0.2 ------------------------------------- Uruchomiłem przykład z tutoriala do symulatora dotyczący "Przyklad symulacji modelu synchronicznego w tym przykładzie po sieci krąży token zawierający zmienną typu "int", której wartość zwiększa się o 1 po każdym skoku". ///kod source symul_lib.tcl; # ladowanie symulatora # tworzymy graf komunikacyjny (w tym wypadku cykl) set liczbaWierz 5 set sasiedzi(0) {4 1} set sasiedzi(1) {0 2} set sasiedzi(2) {1 3} set sasiedzi(3) {2 4} set sasiedzi(4) {3 0} # główny program na każdym wierzchołku/fiberze... fiber create $liczbaWierz { if {$id==0} {wyslij 1 0} fiber yield; # oznacza koniec rundy while {$run} { # zmienna run pozwala zakonczyć działanie symulacji if {$kom(0)!=""} { set x $kom(0) incr x wyslij 1 $x } fiber yield; # oznacza koniec rundy } } Inicjalizacja; # koniecznie trzeba to wywołać !!! proc wizualizacja {} { fiber_iterate {_puts "$id: $kom0, $kom1"} # petla fiber_iterate iteruje po wszystkich fiberach # proc wizualizacja wywolujemy z konsoli po kazdej rundzie } # !!! do tego miejsca wszystko wykonać !!!!!!!!!!!!!!!!!!!!! fiber yield; runda; wizualizacja # wykonuje kolejna runde... # procedura runda dostarcza wysłane komunikaty if 0 { # to się czasem przydaje: set_run 0; fiber yield; runda; set_run 1; fiber delete # usuwanie fiberów set_run 0; fiber yield; runda; set_run 1; fiber restart # restart kodu fiberów fiber error # wyświetla stan fiberów ({}, ended, error) fiber_eval 0 {set id} # wykonanie kodu w fiberze 0 # UWAGA: fiber_eval wykonuje kod na poziomie globalnym # "fiber0 eval {set id}" wykonuje kod tam gdzie fiber zostal zamrozony... } ///koniec kodu /// wydruk 0: , 1: 0, 2: , 3: , 4: , 0: , 1: , 2: 1, 3: , 4: , 0: , 1: , 2: , 3: 2, 4: , 0: , 1: , 2: , 3: , 4: 3, /// koniec wydruku Zadanie 1 ------------------------------------- Algorytm asynchroniczny wyboru lidera, ring zorientowany. /// kod load ./q3.so source symul_lib.tcl; # definuje wierzchołki set liczbaWierz 5 set sasiedzi(0) {4 1} set sasiedzi(1) {0 2} set sasiedzi(2) {1 3} set sasiedzi(3) {2 4} set sasiedzi(4) {3 0} fiber create $liczbaWierz { set lider ?; # lider to niewiadoma wyslij 0 $id; fiber yield; while {$run} { #jesli mamy komunikat if {$kom(1)!=""} { set x $kom(1); if {$lider==1} { #jest juz liderem } elseif {$x>$id} { #przesylam wartosc dalej wyslij 0 $x; } elseif {$x==0} { #nie jest liderem wyslij 0 $x; set lider 0; } elseif {$x==$id} { #jest liderem set lider 1; wyslij 0 0; } elseif {$x < $id} { } } fiber yield; } } Inicjalizacja; # wizualizacja procedury proc wizualizacja {} { fiber_iterate {_puts "$id: $lider, $kom(1)"} } fiber yield; runda; wizualizacja /// koniec kodu //wydruk 0: ?, 1 1: ?, 2 2: ?, 3 3: ?, 4 4: ?, 0 0: ?, 2 1: ?, 3 2: ?, 4 3: ?, 0 4: 0, 1 0: ?, 3 1: ?, 4 2: ?, 0 3: 0, 4: 0, 2 0: ?, 4 1: ?, 0 2: 0, 3: 0, 4: 0, 3 0: ?, 0 1: 0, 2: 0, 3: 0, 4: 0, 4 0: 0, 1: 0, 2: 0, 3: 0, 0 4: 1, 0 /// koniec wydruku Zadanie 1a ------------------------------------- Algorytm asynchroniczny wyboru lidera, ring niezorientowany. Ring nie jest teraz zorientowany. Muszę napisać dodatkowe warunki /// kod load ./q3.so source symul_lib.tcl; # definuję wierzchołki set liczbaWierz 5 set sasiedzi(0) {4 1} set sasiedzi(1) {0 2} set sasiedzi(2) {1 3} set sasiedzi(3) {2 4} set sasiedzi(4) {3 0} fiber create $liczbaWierz { set lider ?; # wysyłam w jedną stronę wyslij 0 $id; # wysyłam w drugą stronę wyslij 1 $id; fiber yield; while {$run} { if {$kom(0)!="" && $kom(1)!=""} { #jesli obydwa komunikaty nie są puste set x ?; if {$kom(0) > $kom(1)} { #komunikat 1 jest wiekszy od drugiego set x $kom(0); if {$lider==1} { #jest juz lider } elseif {$x==0} { #nie jest liderem wyslij 1 0; set lider 0; } elseif {$x>$id} { #przeslij dalej wyslij 1 $x; } elseif {$x==$id} { #jest liderem set lider 1; wyslij 0 0; wyslij 1 0; } elseif {$x < $id} { } fiber yield; } else { #jesli komunikat 2 jest wiekszy od pierwszego set x $kom(1); if {$lider==1} { #jest juz lider } elseif {$x==0} { #nie jest liderem wyslij 0 $x; set lider 0; } elseif {$x>$id} { #przeslij dalej wyslij 0 $x; } elseif {$x==$id} { #jest liderem set lider 1; wyslij 0 0; wyslij 1 0; } elseif {$x < $id} { } fiber yield; } } elseif {$kom(0)!=""} { #jesli tylko komunikat pierwszy nie jest pusty set x $kom(0); if {$lider==1} { #jest juz lider } elseif {$x==0} { #nie jest liderem wyslij 1 0; set lider 0; } elseif {$x>$id} { #przeslij dalej wyslij 1 $x; } elseif {$x==$id} { #jest liderem set lider 1; wyslij 0 0; wyslij 1 0; } elseif {$x < $id} { } fiber yield; } else { #w przeciwnym wypadku set x $kom(1); if {$lider==1} { #jest juz lider } elseif {$x==0} { #nie jest liderem wyslij 0 $x; set lider 0; } elseif {$x>$id} { #przeslij dalej wyslij 0 $x; } elseif {$x==$id} { #jest liderem set lider 1; wyslij 0 0; wyslij 1 0; } elseif {$x < $id} { } fiber yield; } } } Inicjalizacja; # wizualizacja proc wizualizacja {} { fiber_iterate {_puts "id: $id: lider: $lider, kom0: $kom0, kom1: $kom1"} } fiber yield; runda; wizualizacja /// koniec kodu ///wydruk id: 0: lider: ?, kom0: 4, kom1: 1 id: 1: lider: ?, kom0: 0, kom1: 2 id: 2: lider: ?, kom0: 1, kom1: 3 id: 3: lider: ?, kom0: 2, kom1: 4 id: 4: lider: ?, kom0: 3, kom1: 0 id: 0: lider: ?, kom0: , kom1: 2 id: 1: lider: ?, kom0: 4, kom1: 3 id: 2: lider: ?, kom0: , kom1: 4 id: 3: lider: ?, kom0: , kom1: id: 4: lider: ?, kom0: , kom1: id: 0: lider: ?, kom0: , kom1: id: 1: lider: ?, kom0: , kom1: 4 id: 2: lider: ?, kom0: 4, kom1: id: 3: lider: ?, kom0: , kom1: id: 4: lider: ?, kom0: , kom1: 2 id: 0: lider: ?, kom0: , kom1: 4 id: 1: lider: ?, kom0: , kom1: id: 2: lider: ?, kom0: , kom1: id: 3: lider: ?, kom0: 4, kom1: id: 4: lider: ?, kom0: , kom1: id: 0: lider: ?, kom0: , kom1: id: 1: lider: ?, kom0: , kom1: id: 2: lider: ?, kom0: , kom1: id: 3: lider: ?, kom0: , kom1: id: 4: lider: ?, kom0: 4, kom1: 4 id: 0: lider: ?, kom0: 0, kom1: id: 1: lider: ?, kom0: , kom1: id: 2: lider: ?, kom0: , kom1: id: 3: lider: ?, kom0: , kom1: 0 id: 4: lider: 1, kom0: , kom1: id: 0: lider: 0, kom0: , kom1: id: 1: lider: ?, kom0: 0, kom1: id: 2: lider: ?, kom0: , kom1: 0 id: 3: lider: 0, kom0: , kom1: id: 4: lider: 1, kom0: , kom1: id: 0: lider: 0, kom0: , kom1: id: 1: lider: 0, kom0: , kom1: 0 id: 2: lider: 0, kom0: 0, kom1: id: 3: lider: 0, kom0: , kom1: id: 4: lider: 1, kom0: , kom1: /// koniec wydruku Zadanie 1b ------------------------------------- Wybór lidera, więcej niz 1 lider. Dodatkowy warunek na istnienie lidera, lider pośredni. Nie udało mi się zrobić tego zadania w 100% /// kod #inicjalizacja load ./q3.so source symul_lib.tcl; #wierzchołki set liczbaWierz 5 set sasiedzi(0) {4 1} set sasiedzi(1) {0 2} set sasiedzi(2) {1 3} set sasiedzi(3) {2 4} set sasiedzi(4) {3 0} fiber create $liczbaWierz { set lider ?; wyslij 0 $id; fiber yield; while {$run} { if {$kom(1)!=""} { set x $kom(1); if {$lider==1} { } elseif {$x==$id+2} { set lider 1; #lider 1 wyslij 0 0; } elseif {$x>$id} { wyslij 0 $x; } elseif {$x==0} { wyslij 0 $x; set lider 0; } elseif {$x==$id} { set lider 1; # lider 2 wyslij 0 0; } elseif {$x < $id} { } } fiber yield; } } Inicjalizacja; # wizalizacja proc wizualizacja {} { fiber_iterate {_puts "id: $id, lider: $lider, $kom(1)"} } fiber yield; runda; wizualizacja /// koniec kodu ///wydruk id: 0, lider: ?, 1 id: 1, lider: ?, 2 id: 2, lider: ?, 3 id: 3, lider: ?, 4 id: 4, lider: ?, 0 id: 0, lider: ?, 2 id: 1, lider: ?, 3 id: 2, lider: ?, 4 id: 3, lider: ?, 0 id: 4, lider: 0, 1 id: 0, lider: 1, 0 id: 1, lider: 1, 0 id: 2, lider: 1, 0 id: 3, lider: 0, id: 4, lider: 0, 0 /// koniec wydruku Zadanie 2 ------------------------------------- 8-kolorowanie wierzchołkowe drzewa ukorzenionego. /// kod #inicjalizacja load ./q3.so source symul_lib.tcl; # drzewo ukorzenione set liczbaWierz 7 set sasiedzi(0) {0 1 2} set sasiedzi(1) {0 3 4} set sasiedzi(2) {0 5} set sasiedzi(3) {1} set sasiedzi(4) {1 6} set sasiedzi(5) {2} set sasiedzi(6) {4} #przydatny kod do obsługi bitów set obslugaBitow { proc bity x { # postac binarna liczby usun0 [binary scan [binary format I $x] B* x; set x] } proc usun0 x { # usuwa zera poczatkowe z repr bin liczby set x [string trimleft $x 0] if {$x==""} {set x 0} set x } proc porownanieC {cv cu} { # porownuje 2 kolory, zwraca indeks oraz 2 bity... set dlcu [string len $cu] set dlcv [string len $cv] if {$dlcu<$dlcv} { set cu "[string repeat 0 [expr {$dlcv-$dlcu}]]$cu" } if {$dlcu>$dlcv} { set cv "[string repeat 0 [expr {$dlcu-$dlcv}]]$cv" } set dl [string len $cu] iterate i $dl { set i1 [expr {$dl-$i-1}] # KONIECZNIE trzeba numerowac bity od prawej gdyz # dopisuje sie 0 z lewej i wtedy indeksy by sie zmienialy! set bu [string index $cu $i1] set bv [string index $cv $i1] if {$bu != $bv} {return "$i $bv $bu"} } return {-1 ? ?} } proc wyrownaj {L x} { # dodaje 0 z lewej do L-bitow set dl [string len $x] if {$dl>$L} {error "wyrownaj"} return "[string repeat "0" [expr {$L-$dl}]]$x" } proc bin2dec x { # do 32-bitow binary scan [binary form B* [wyrownaj 32 $x]] I y set y } proc iterate {zm liIter kod} { # wygodna petla upvar $zm i for {set i 0} {$i<$liIter} {incr i} { set e [catch {uplevel $kod} x] if {$e!=0} {return -code $e $x} } } } fiber create $liczbaWierz { #zmienne set new 0 set wielkosc 50 #tworze kolory set kolor_pierwszy [wyrownaj $wielkosc [bity $id_los]] set kolor_drugi 0 set b 0 set por 0 set c 0 #wyslij kolor pierwszy do lisci for {set i 1} {$i < $stopien} {incr i} {wyslij $i $kolor_pierwszy} fiber yield; #główna pętla while {$run} { if {$kom(0)!=""} { #komunikat pierwszy nie jest pusty #ustawiam jako kolor drugi i porównuję z pierwszym set kolor_drugi $kom(0) set por [porownanieC $kolor_pierwszy $kolor_drugi] #wynik porównania set c [lindex $por 1] set b [lindex $por 0] #ustawiam nowy kolor set nowy [wyrownaj $wielkosc "[bity $b]$c"] set kolor_pierwszy $nowy #wysyłam do liści set wielkosc [expr {int(ceil(log($wielkosc)/log(2)) + 1)}] for {set i 1} {$i < $stopien} {incr i} {wyslij $i $kolor_pierwszy} } if { $id == 0 } { #jeśli pierwszy wierzchołek, ustalam kolor, porównuję set kolor_drugi [wyrownaj $wielkosc [bity 0]] set por [porownanieC $kolor_pierwszy $kolor_drugi] #wynik porównania set c [lindex $por 1] set b [lindex $por 0] #ustalam nowy kolor set nowy [wyrownaj $wielkosc "[bity $b]$c"] set kolor_pierwszy $nowy #wysyłam komunikat do liści set wielkosc [expr {int(ceil(log($wielkosc)/log(2)) +1)}] for {set i 1} {$i < $stopien} {incr i} {wyslij $i $kolor_pierwszy} } fiber yield; } } fiber_iterate $obslugaBitow Inicjalizacja; proc wizualizacja {} { fiber_iterate {_puts "id: $id, kolor: $kolor_pierwszy"} } fiber yield; runda; wizualizacja /// koniec kodu /// wydruk id: 0, kolor: 00000000000000000000000000000000000000001100010010 id: 1, kolor: 00000000000000000000000000000000000000000010101001 id: 2, kolor: 00000000000000000000000000000000000000001101011010 id: 3, kolor: 00000000000000000000000000000000000000000100001010 id: 4, kolor: 00000000000000000000000000000000000000000010111010 id: 5, kolor: 00000000000000000000000000000000000000001010100000 id: 6, kolor: 00000000000000000000000000000000000000001111011000 id: 0, kolor: 0000011 id: 1, kolor: 00000000000000000000000000000000000000000000000001 id: 2, kolor: 00000000000000000000000000000000000000000000000111 id: 3, kolor: 00000000000000000000000000000000000000000000000000 id: 4, kolor: 00000000000000000000000000000000000000000000000000 id: 5, kolor: 00000000000000000000000000000000000000000000000010 id: 6, kolor: 00000000000000000000000000000000000000000000000010 id: 0, kolor: 0001 id: 1, kolor: 0000010 id: 2, kolor: 0000101 id: 3, kolor: 0000000 id: 4, kolor: 0000000 id: 5, kolor: 0000000 id: 6, kolor: 0000011 id: 0, kolor: 001 id: 1, kolor: 0000 id: 2, kolor: 0101 id: 3, kolor: 0010 id: 4, kolor: 0010 id: 5, kolor: 0000 id: 6, kolor: 0001 id: 0, kolor: 001 id: 1, kolor: 000 id: 2, kolor: 101 id: 3, kolor: 011 id: 4, kolor: 011 id: 5, kolor: 000 id: 6, kolor: 001 /// koniec wydruku Zadanie 0.3 ------------------------------------- Wizualizacja drzewa. Kolejne kroki opisuję w kodzie zamieszczonym ponizej w komentarzach. Nie zamieszczam wydruku - jest to graficzna wizualizacja. /// kod # inicjalizacja load ./q3.so source symul_graf_lib.tcl # budujemy drzewo set liczbaWierz 0 array unset sasiedzi G::sciezka2 0 10 G::gwiazda2 10 15 0 G::gwiazda2 15 20 1 G::gwiazda2 20 25 2 G::gwiazda2 25 30 3 G::gwiazda2 30 35 4 G::gwiazda2 35 40 5 G::gwiazda2 40 45 6 G::gwiazda2 45 50 7 # rysujemy graf w odpowiedniej kolejności G::rysujGraf -zero 1 # sposób na konfig. połączeń na podstawie ID i nr_połączenia proc tc_pol {id pol} { global sasiedzi set l1 "$id [lindex $sasiedzi($id) $pol]" set l1 [lsort -integer $l1] return "[lindex $l1 0]->[lindex $l1 1]" } # ustawiamy grubość krawędzi .t.c itemconf 1$tc_edge([tc_pol 0 0]) -width 5 .t.c itemconf 1$tc_edge([tc_pol 1 0]) -width 5 .t.c itemconf 1$tc_edge([tc_pol 2 0]) -width 5 .t.c itemconf 1$tc_edge([tc_pol 3 0]) -width 5 # kolorujemy .t.c itemconf 1$tc_node(5) -fill yellow .t.c itemconf 1$tc_node(10) -fill red .t.c itemconf 1$tc_node(15) -fill yellow .t.c itemconf 1$tc_node(20) -fill red /// koniec kodu Zadanie 3 ------------------------------------- Algorytm asynchroniczny wyboru lidera, uzywający O(n logn) komunikatów, dla ringu zorientowanego. Nie udało mi się wykonać zadania, załączam rozwiązane w połowie. /// kod # inicjalizacja load ./q3.so source symul_lib.tcl # ustawienie ringu set liczbaWierz 5 set sasiedzi(0) {4 1} set sasiedzi(1) {0 2} set sasiedzi(2) {1 3} set sasiedzi(3) {2 4} set sasiedzi(4) {3 0} proc reverse li { set len [llength $li] iterate i $len {lappend wynik [lindex $li [expr {$len-$i-1}]]} set wynik } fiber create $liczbaWierz { set lider ? #wysyłam id dalej wyslij 0 "$id_los 0 0" wyslij 1 "$id_los 0 0" fiber yield while {$run} { #wykonuje algorytm ponizej algorytm [czytaj 0] [czytaj 1] fiber yield } } Inicjalizacja; proc wizualizacja {} { _puts --- fiber_iterate {_puts "id: $id, wartosc: $id_los, lider: $lider; $kom0, $kom1"} } fiber_iterate { #to ma przekazac komunikaty proc algorytm {m0 m1} { #ustwiamy zmienne globalny global id id_los stopien lider if {$m0!=""} { #jesli pierwsza wartość nie jest pusta foreach {id0 i0 l0} $m0 break #zwiększam i przekazuje incr i0 wyslij 1 "$id0 $i0 0"; } if {$m1!=""} { #jesli druga zmienna nie jest pusta foreach {id1 i1 l1} $m1 break #zwiększam i ustawiam incr i1 set i1 [expr {$i1+1}] if {$m1==$id}{ #jest lider set lider 1; } wyslij 0 "$id1 $i1 0" } } } fiber yield; runda; wizualizacja; set licznikKom /// koniec kodu /// wydruk --- id: 0, wartosc: 498, lider: ?; {207 0 0}, {416 0 0} id: 1, wartosc: 416, lider: ?; {498 0 0}, {48 0 0} id: 2, wartosc: 48, lider: ?; {416 0 0}, {50 0 0} id: 3, wartosc: 50, lider: ?; {48 0 0}, {207 0 0} id: 4, wartosc: 207, lider: ?; {50 0 0}, {498 0 0} --- id: 0, wartosc: 498, lider: ?; {50 1 0}, id: 1, wartosc: 416, lider: ?; {207 1 0}, id: 2, wartosc: 48, lider: ?; {498 1 0}, id: 3, wartosc: 50, lider: ?; {416 1 0}, id: 4, wartosc: 207, lider: ?; {48 1 0}, --- id: 0, wartosc: 498, lider: ?; , id: 1, wartosc: 416, lider: ?; , id: 2, wartosc: 48, lider: ?; , id: 3, wartosc: 50, lider: ?; , id: 4, wartosc: 207, lider: ?; , --- id: 0, wartosc: 498, lider: ?; , id: 1, wartosc: 416, lider: ?; , id: 2, wartosc: 48, lider: ?; , id: 3, wartosc: 50, lider: ?; , id: 4, wartosc: 207, lider: ?; , /// koniec wydruku Zadanie 5 ------------------------------------- Algorytm kolorujący wierzchołkowo, stałą liczbą kolorów, grafy stałego stopnia, działający w czasie O(log^*n). Algorytm 1) Najpierw generujemy kolor. 2) Powtarzamy w pętli: 2a) Pobranie koloru. 2b) Otrzymujemy kolor sąsiadującego wierzchoka. 2c) Skracamy długość koloru. 2d) Odczytujemy ilość zer i jedynek. 2e) Generujemy zera i jedynki na podstawie otrzymanego koloru. Zadanie 5a ------------------------------------- Algortym z zadania 5 dla ringu. /// kod #inicjalizacja load ./q3.so; source symul_lib.tcl; # ring set liczbaWierz 5 set sasiedzi(0) {4 1} set sasiedzi(1) {0 2} set sasiedzi(2) {1 3} set sasiedzi(3) {2 4} set sasiedzi(4) {3 0} fiber create $liczbaWierz { #zmienne set wielkosc 50 set por 0 set new 0 #ustawiam kolory set kolor_pierwszy [wyrownaj $wielkosc [bity $id_los]] set kolor_drugi 0 set b 0 set c 0 #wysyłam kolor pierwszy for {set i 1} {$i < $stopien} {incr i} {wyslij $i $kolor_pierwszy} fiber yield; #główna pętla while {$run} { if {$kom(0)!=""} { #jesli komunikat pierwszy nie jest pusty set kolor_drugi $kom(0) } else { #jesli jest pusty set kolor_drugi [wyrownaj $wielkosc [bity 0]] } #porownanie koloru drugiego z pierwszym set por [porownanieC $kolor_pierwszy $kolor_drugi] #wynik porownania set c [lindex $por 1] set b [lindex $por 0] #ustawiamy nowy kolor set new [wyrownaj $wielkosc "[bity $b]$c"] set kolor_pierwszy $new #przesylamy dalej set wielkosc [expr {int(ceil(log($wielkosc)/log(2)) + 1)}] for {set i 1} {$i < $stopien} {incr i} {wyslij $i $kolor_pierwszy} fiber yield; } } #obsługa bitów set obslugaBitow { proc bity x { # postac binarna liczby usun0 [binary scan [binary format I $x] B* x; set x] } proc usun0 x { # usuwa zera poczatkowe z repr bin liczby set x [string trimleft $x 0] if {$x==""} {set x 0} set x } proc porownanieC {cv cu} { # porownuje 2 kolory, zwraca indeks oraz 2 bity... set dlcu [string len $cu] set dlcv [string len $cv] if {$dlcu<$dlcv} { set cu "[string repeat 0 [expr {$dlcv-$dlcu}]]$cu" } if {$dlcu>$dlcv} { set cv "[string repeat 0 [expr {$dlcu-$dlcv}]]$cv" } set dl [string len $cu] iterate i $dl { set i1 [expr {$dl-$i-1}] # KONIECZNIE trzeba numerowac bity od prawej gdyz # dopisuje sie 0 z lewej i wtedy indeksy by sie zmienialy! set bu [string index $cu $i1] set bv [string index $cv $i1] if {$bu != $bv} {return "$i $bv $bu"} } return {-1 ? ?} } proc wyrownaj {L x} { # dodaje 0 z lewej do L-bitow set dl [string len $x] if {$dl>$L} {error "wyrownaj"} return "[string repeat "0" [expr {$L-$dl}]]$x" } proc bin2dec x { # do 32-bitow binary scan [binary form B* [wyrownaj 32 $x]] I y set y } proc iterate {zm liIter kod} { # wygodna petla upvar $zm i for {set i 0} {$i<$liIter} {incr i} { set e [catch {uplevel $kod} x] if {$e!=0} {return -code $e $x} } } } fiber_iterate $obslugaBitow Inicjalizacja; #wizualizaca proc wizualizacja {} { fiber_iterate {_puts "$id : $kolor_pierwszy"} } #wykonanie fiber yield; runda; wizualizacja /// koniec kodu /// wydruk 0 : 00000000000000000000000000000000000000001101100101 1 : 00000000000000000000000000000000000000000100110011 2 : 00000000000000000000000000000000000000000111110111 3 : 00000000000000000000000000000000000000001110100110 4 : 00000000000000000000000000000000000000000000000110 0 : 00000000000000000000000000000000000000000000000001 1 : 00000000000000000000000000000000000000000000000011 2 : 00000000000000000000000000000000000000000000000101 3 : 00000000000000000000000000000000000000000000000000 4 : 00000000000000000000000000000000000000000000001010 0 : 0000001 1 : 0000011 2 : 0000010 3 : 0000000 4 : 0000011 0 : 0010 1 : 0011 2 : 0000 3 : 0010 4 : 0001 0 : 000 1 : 001 2 : 000 3 : 011 4 : 001 /// koniec wydruku Zadanie 8 ------------------------------------- Suma ID w ringu. Zliczam sumę ID w ringu, losuję wartości wierzchołków. /// kod load ./q3.so source symul_lib.tcl; # definuję ring set liczbaWierz 6 set sasiedzi(0) {5 1} set sasiedzi(1) {0 2} set sasiedzi(2) {1 3} set sasiedzi(3) {2 4} set sasiedzi(4) {3 5} set sasiedzi(5) {4 0} fiber create $liczbaWierz { # losowanie wartości set suma $id_los #zmienna okreslajaca czy moge liczyc set licz [expr $liczbaWierz - 1] set wynik "" # wysyłam w jedną stronę wyslij 1 $suma fiber yield; while {$run} { if {$wynik!="end" && $kom(0)!=""} { #jesli nie mam jeszcze wyniku i mam komunikat pierwszy if {$licz>0} { # jeśli nadal mogę liczyć set k $kom(0) #obliczam sume set suma [expr $id_los + $k] set licz [expr $licz - 1] wyslij 1 $suma } else { #ustawiam wynik set wynik "end" } } fiber yield; } } Inicjalizacja; # wizualizacja proc wizualizacja {} { fiber_iterate {_puts "id: $id wartosc: $id_los, suma: $suma, licz: $licz, $wynik"} } fiber yield; runda; wizualizacja /// koniec kodu ///wydruk id: 0 wartosc: 751, suma: 751, licz: 5, id: 1 wartosc: 546, suma: 546, licz: 5, id: 2 wartosc: 484, suma: 484, licz: 5, id: 3 wartosc: 872, suma: 872, licz: 5, id: 4 wartosc: 218, suma: 218, licz: 5, id: 5 wartosc: 228, suma: 228, licz: 5, id: 0 wartosc: 751, suma: 979, licz: 4, id: 1 wartosc: 546, suma: 1297, licz: 4, id: 2 wartosc: 484, suma: 1030, licz: 4, id: 3 wartosc: 872, suma: 1356, licz: 4, id: 4 wartosc: 218, suma: 1090, licz: 4, id: 5 wartosc: 228, suma: 446, licz: 4, id: 0 wartosc: 751, suma: 1197, licz: 3, id: 1 wartosc: 546, suma: 1525, licz: 3, id: 2 wartosc: 484, suma: 1781, licz: 3, id: 3 wartosc: 872, suma: 1902, licz: 3, id: 4 wartosc: 218, suma: 1574, licz: 3, id: 5 wartosc: 228, suma: 1318, licz: 3, id: 0 wartosc: 751, suma: 2069, licz: 2, id: 1 wartosc: 546, suma: 1743, licz: 2, id: 2 wartosc: 484, suma: 2009, licz: 2, id: 3 wartosc: 872, suma: 2653, licz: 2, id: 4 wartosc: 218, suma: 2120, licz: 2, id: 5 wartosc: 228, suma: 1802, licz: 2, id: 0 wartosc: 751, suma: 2553, licz: 1, id: 1 wartosc: 546, suma: 2615, licz: 1, id: 2 wartosc: 484, suma: 2227, licz: 1, id: 3 wartosc: 872, suma: 2881, licz: 1, id: 4 wartosc: 218, suma: 2871, licz: 1, id: 5 wartosc: 228, suma: 2348, licz: 1, id: 0 wartosc: 751, suma: 3099, licz: 0, id: 1 wartosc: 546, suma: 3099, licz: 0, id: 2 wartosc: 484, suma: 3099, licz: 0, id: 3 wartosc: 872, suma: 3099, licz: 0, id: 4 wartosc: 218, suma: 3099, licz: 0, id: 5 wartosc: 228, suma: 3099, licz: 0, id: 0 wartosc: 751, suma: 3099, licz: 0, end id: 1 wartosc: 546, suma: 3099, licz: 0, end id: 2 wartosc: 484, suma: 3099, licz: 0, end id: 3 wartosc: 872, suma: 3099, licz: 0, end id: 4 wartosc: 218, suma: 3099, licz: 0, end id: 5 wartosc: 228, suma: 3099, licz: 0, end /// koniec wydruku