forum speccy.pl

ZX Spectrum => PROGRAMOWANIE => Wątek zaczęty przez: tdu w 2023.04.13, 17:06:40

Tytuł: Sortowanie tablicy
Wiadomość wysłana przez: tdu w 2023.04.13, 17:06:40
Jak posortowac tablice tekstową DIM(100, 10), oczywiście w Basicu.
Proszę o pomoc.

Tablica zawiera100 słów o długości 10 znaków każde.
Tytuł: Odp: Sortowanie tablicy
Wiadomość wysłana przez: trojacek w 2023.04.13, 17:17:10
Np. quick sortem:
https://pl.m.wikipedia.org/wiki/Sortowanie_szybkie
Tytuł: Odp: Sortowanie tablicy
Wiadomość wysłana przez: steev w 2023.04.13, 18:59:53
A jeśli nie musi być bardzo szybko, a wolisz prosto, to sortowanie bąbelkowe (https://pl.m.wikipedia.org/wiki/Sortowanie_b%C4%85belkowe) :)
Tytuł: Odp: Sortowanie tablicy
Wiadomość wysłana przez: steev w 2023.04.13, 19:08:50
BTW, jedno z moich 'oddly satisfying'...  ;)

(https://lh3.googleusercontent.com/OCPDMCd7xlJT2t7pYBQzBvXvllS-F8vX2RJn13rNDe3eaJXyGM2tSBWsxtnMqzLPoMpW2vvHDXY3DAiDpbDSL4L8WdZ_lrN8DfoXPgs)
Tytuł: Odp: Sortowanie tablicy
Wiadomość wysłana przez: tdu w 2023.04.13, 19:20:29
Ze są takie różne metody to wiem,
chodzi mi bardziej o jakąś przykładową implementacje w ZX Basicu

wystarczy jak posortuje alfabetycznie według pierwszego znaku

a czas wykonania nie powinien byc zbyt długi, sekunda, dwie...
Tytuł: Odp: Sortowanie tablicy
Wiadomość wysłana przez: ZbyniuR w 2023.04.14, 02:41:56
Jeśli w podanym przez ciebie przykładzie DIM(100,10) ta dziesiątka to odpowiednik długości słowa to nie jest to potrzebne. Jedno-wymiarowa tablica a w zasadzie to lista ci wystarczy. A jeśli to tekst to nazwa zmiennej przed nawiasem potrzebuje dolarka.

Z różnych metod polecam metodę przez wybieranie proste. Jest równie krótka jak bąbelkowa, a znacznie od niej szybsza. Wprawdzie metody Shell i Quick są jeszcze szybsze ale dopiero gdy tablica ma kilkaset pozycji, a obie mają niemal 3 razy dłuższy program.

Wygląda to mniej więcej tak:

10 DIM a$(100)
20 FOR n=x TO 2 STEP-1:p$="":FOR m=1 TO n:IF a$(m)>p$ THEN p$=a$(m):p=m
30 NEXT m:t$=a$(n):a$(n)=a$(p):a$(p)=t$:NEXT n

To jest wersja na Amstrada, i mam nadzieję że na Spectrum nie trzeba nic zmieniać. Jakby co to ktoś bystrzejszy poprawi. :)

A jak chcesz sobie namieszać w głowie innymi metodami sortowania to w czasopiśmie Komputer 7/88 na stronie 17 jest o tym niezły artykuł. Jego skany można znaleźć na archive.org  albo na atarionline.pl w dziale czasopisma. :)

Nawiasem mówiąc na czym ma polegać ta metoda "bąbelkowa poprawiona" w tym artykule to nie wiem, bo jest dłuższa i wolniejsza od tej "niepoprawionej". :D

PS.: Wątpię aby Basic posortował taką tablicę w sekundę.
PS2.: Szkoda że ten GIF jest taki szybki, można oczopląsu dostać, mogłyby sie kolorki zmieniać w tych które skończyły, łatwiej byłoby je zauważyć.
Tytuł: Odp: Sortowanie tablicy
Wiadomość wysłana przez: smok.wawelski w 2023.04.14, 12:00:03
Właściwie nie potrzebujesz sortowania tylko przepisanie jednej tablicy do drugiej na podstawie 1 litery każdego rekordu w 1 tablicy.
Zaczynasz od "a" (zakładam, że wszystko jest z małej litery) i wybierasz wszystkie rekordy z 1 tablicy zaczynające się na tę literę i umieszczasz w tablicy drugiej.
Stworzysz w ten sposób drugą tablicę w maksymalnie 100 x 24 operacjach. Jeśli przepiszesz 100 rekordów zanim dojdziesz do "z" to możesz zakończyć szukanie (np. pierwsza tablica ma słowa maksymalnie do "c").

PS. Sam jestem ciekaw ile czasu będzie potrzebne do posortowania 100 rekordów, postaram się napisać ten program w BASICu i wkleję rozwiązanie.
Tytuł: Odp: Sortowanie tablicy
Wiadomość wysłana przez: Phonex w 2023.04.14, 12:46:43
Nie ma szans na posortowanie 100-elementowej tablicy w Basicu w 2 sekundy. Pewnie udało by się w asemblerze.

Sortowanie bąbelkowe z flagą (z flagą wykonuje mniej przebiegów - przestaje gdy nie było zamian):
10 FOR l=100 TO 1 STEP -1
20 LET flag=0
30 FOR k=1 TO l-1
40 IF a$(k,1)>a$(k+1,1) THEN LET p$=a$(k): LET a$(k)=a$(k+1): KET a$(k+1)=p$: LET flag=1
50 NEXT k
60 IF flag THEN NEXT l
Czas: 2min 22sek

Sortowanie z wyborem - mniej zamian niż w bąbelkowym: tylko jedna na przebieg
10 FOR l=1 TO 99
20 LET min=l
30 FOR k=l+1 TO 100
40 IF a$(k,1)<a$(min,1) THEN LET min=k
50 NEXT k
60 LET p$=a$(l): LET a$(l)=a$(min): LET a$(min)=p$
70 NEXT l
Czas: 1min 30sek, prawie dwa razy szybciej

A sortowanie z wyborem w wersji ZbyniuR: porównywanie do łańcucha p$, a nie elementu tablicy
10 FOR l=1 TO 99
20 LET min=l: LET p$=a$(min)
30 FOR k=l+1 TO 100
40 IF a$(k,1)<p$ THEN LET min=k: LET p$=a$(min)
50 NEXT k
60 LET a$(min)=a$(l): LET a$(l)=p$
70 NEXT l
Czas: 1min 14sek, jeszcze trochę szybciej.

Właściwie nie potrzebujesz sortowania tylko przepisanie jednej tablicy do drugiej na podstawie 1 litery każdego rekordu w 1 tablicy.
...
To jest odmiana sortowania z wyborem, tylko jest jedno kopiowanie a nie dwa. Myślę, że nie wyjdzie poniżej minuty...
Tytuł: Odp: Sortowanie tablicy
Wiadomość wysłana przez: matofesi w 2023.04.14, 13:02:44
a czas wykonania nie powinien byc zbyt długi, sekunda, dwie...

Nie żeby coś, ale 100 tekstów po 10 znaków w BASICu?... Na Spectrum?... "sekunda, dwie"? ;)

Bubble sort na losowo wygenerowanych 100 stringach sortuje trochę ponad dwie minuty. Żeby było zabawniej ten sam algorytm ograniczony warunkiem do pierwszego znaku robi to samo 20 sekund dłużej - porównanie pierwszych znaków dwóch zmiennych wymaga dodatkowych nakładu na obcięcie tych znaków.

Nie wiem na ile inne algorytmy zrobią to szybciej albo na ile da się zoptymalizować, ale mam wrażenie, że bez ASMa to możesz zapomnieć o kilkusekundowych czasach.
Tytuł: Odp: Sortowanie tablicy
Wiadomość wysłana przez: tdu w 2023.04.14, 13:48:23
Wystarczyłaby tablica posortowanych indeksów, może to dałoby się szybciej.
Tytuł: Odp: Sortowanie tablicy
Wiadomość wysłana przez: tdu w 2023.04.14, 13:56:51
@smok.wawelski   też nad takim rozwiazaniem myślałem, tylko co będzie
jak w pierwszej tablicy będzie więcej stringów na tę samą literę, tutaj utknąłem,
ale może za słabo kombinowałem

@ZbyniuR   jak zadeklaruję  a$=DIM(100) to przy zapisie do tablicy zapisuje tylko pierwszy znak stringa
gdy zadeklaruję a$=DIM(100,10)  to zapisuje 10 znaków stringa,
tak mi wyszło z prób.
Tytuł: Odp: Sortowanie tablicy
Wiadomość wysłana przez: matofesi w 2023.04.14, 14:24:46
No dobra... zrobiłem kawałek kodu, który robi brzydkiego bubble sorta w ASMie - sortowanie stu dziesięcioznakowych tekstóœ zajmuje ~sekundę.
Brzydkie, bo robi założenie, że zmienna do sortowania jest deklarowana jako pierwsza przed całą resztą bo liczy sobie adres na chama strzelając w obszar zmiennych. A do tego sam kod jest "odzwierciedleniem" wersji BASICowej.

W załączniku to co mi wyszło
- sort.bas ma w sobie dane, inicjalizację i wywołanie sortowania (oraz wyremowaną wersję sortowania w BASICu).
- sort.asm to właściwy kod sortujący - brzydki więc proszę się nie śmiać ;)
- sort.tap to wersja do odpalenia

Skompilowana wersja się nie uruchamia sama - po RUN inicjuje tablicę, wciąga do niej dane, wyświetla READY i czeka na klawisz. Po wciśnięciu pisze SORTING i liczbę ramek odczytaną ze zmiennych systemowych po czym wykonuje kod sortujący a na koniec pisze DONE i aktualny stan liczby ramek - możemy policzyć  zgrubny czas w 1/50 sekundy. Po wciśnięciu dowolnego klawisza wyświetla posortowaną tablicę.

Cały "eksperyment" pokazuje, że nie specjalnie jest sens się szarpać BASICem - kod sortujący ma ciut ponad 100 bajtów więc nawet jakby go doszlifować żeby był "ładny" to nadal nie powinno być problemu, żeby go zmieścić gdzieś w pamięci.

I jeszcze raz - proszę się nie śmiać ;)
Tytuł: Odp: Sortowanie tablicy
Wiadomość wysłana przez: tdu w 2023.04.14, 17:55:03
Jak dla mnie, fajny kawalek kodu,
jak rozumiem, pobierana jest tablica z adresu
wskazywanego przez zmienną systemową z adresu 23627.

Czyli swoją tablicę muszę zadeklarować jako pierwszą, bo będzie ich kilka.
Po sortowaniu, można ją dalej obrabiać w basicu.

Ilość wierszy tablicy nie będzie stała, będzie się zmieniać w zależności od potrzeb max120, trzeba by to jakoś do kodu przekazać,
długość pojedynczego wiersza to 9 znaków,
litery będą tylko duże,
będą też liczby



Tytuł: Odp: Sortowanie tablicy
Wiadomość wysłana przez: ZbyniuR w 2023.04.14, 20:42:09
Ludzie co wy macie z tymi bombelkami? Od zawsze wiadomo że to najwolniejsza metoda i powinno sie ją wykreślić z podręczników do programowania ze 30 lat temu. Wybierani proste jest ok dwa razy szybsze na tak krótkich tablicach, a im dłuższa tym większą ma przewagę nad bombelkami.

   Prawie ułożona tablica, np taka która po poprzednim sortowaniu dostała nową pozycję albo zmodyfikowano jedną z nich, powinna sie szybciej sortować niż taka kompletnie pomieszana.       

@tdu - Przyjmuję do wiadomości działanie DIM w Speccu. :)

   @Phonex -  A czy mierzyłeś kiedyś prędkość tej samej procedury z upchniętymi rozkazami na maks w linii, w porównaniu do tej która każdy rozkaz ma w osobnej linii?  Bo w CPC z pomiarów widać różnicę między czasem potrzebnym do przeskoczenia do następnego rozkazu oddzielonego dwukropkiem (co jest szybsze), niż do przeskoczenia do następnego rozkazu który jest w następnej linii. Dlatego nie przypadkiem upycham tyle rozkazów ile sie zmieści w linii.        

A wogóle to ten wątek zaczyna przypominać przysłowie, gdzie kucharek 6... ;)
Tytuł: Odp: Sortowanie tablicy
Wiadomość wysłana przez: matofesi w 2023.04.14, 23:52:28
@tdu Trzeba by kod przepisać tak, żeby sobie ROMem ładnie znajdował adres konkretnej zmiennej i dodać przekazywanie parametrów, choć w samych danych jest info o tym jak zmienna była zadeklarowana więc kod może sobie te informacje sam wyjąć. Do tego prawie na pewno dałoby się to zrobić tak, żeby kod był relokowalny... W weekend nie, ale po weekendzie mogę się temu przyjrzeć ;)

@ZbyniuR Bombelki są łatwe do zrozumienia. A poza tym w BASICu przy zadanych na starcie parametrach nawet jak skrócisz czas wykonania o 90% to dalej nie mieścisz się w wymaganiach - schodzisz ze 120 do 12 sekund a miało być "sekunda, dwie". Przejście do ASMa załatwia kwestię czasu na tyle, że przyspieszenie zmianą algorytmu na bardziej skomplikowany/wydajny nie ma tu strategicznego znaczenia - sortując wg. założeń startowych kod robi to w ~sekundę.

A co do tego jak z ZX BASICU działa DIM... Tekstowy DIM z jednym parametrem deklaruje zmienną tekstową o zadanej długości - jeśli zrobisz DIM a$(5) a potem LET a$ = "123456" i PRINT a$ to w wyniku dostaniesz 12345. Jeśli zmienna tekstowa nie jest deklarowana ma rozmiar "dynamiczny". Tekstowy DIM z więcej niż jednym parametrem deklaruje tablicę tekstów o zadanej (ostatnim parametrem) długości. Nie da się zadeklarować tablicy tekstowej z dynamiczną długością tekstów.
Tytuł: Odp: Sortowanie tablicy
Wiadomość wysłana przez: tdu w 2023.04.15, 09:52:45
W moim przypadku, muszę zadeklarować DIM(100,9), jednak tablica będzie zwykle wypełniona tylko częściowo.
Sortowana więc będzie tablica częściowo pusta, ale to chyba nie powinno przeszkadzać.

Zastanawiam się czy może prościej by nie było stworzyć tylko tablice, posortowanych indeksow, tej pierwszej tablicy.

Dziękuję za pomoc, pośpiechu nie ma.
Tytuł: Odp: Sortowanie tablicy
Wiadomość wysłana przez: Phonex w 2023.04.15, 12:27:02
Żeby było zabawniej ten sam algorytm ograniczony warunkiem do pierwszego znaku robi to samo 20 sekund dłużej - porównanie pierwszych znaków dwóch zmiennych wymaga dodatkowych nakładu na obcięcie tych znaków.
No czary z mleka! Nawet nie pomyślałem, że porównywanie dziesięciu elementów będzie szybsze niż jednego :o
Ciężko nawet na to wpaść.
Ten trzeci przykład, który poprzednio zamieściłem, po usunięciu drugiego indeksu, przyspieszył o 10 sekund. Wynik - 1:04


@ZbyniuR w związku z tym co powyżej, spróbowałem łączenia linii, mając nadzieję, że da się zejść poniżej minuty :)
Też stosowałem kiedyś łączenie linii, ale po to żeby skrócić program. Sądziłem że Ty też. Ale myślałem że może być jakiś zysk czasowy.
A tu niespodzianka: po połączeniu - działa dłużej! :o
Po serii szybkich testów okazało się że pętle muszą być na początku linii. FOR w głębi linii spowalnia to sortowanie o 8% (5s), NEXT w głębi linii spowalnia o 2% (1s).
Połączenie innych instrukcji rzeczywiście przyspiesza, ale niewiele o 1-2% (1s).

A jeśli chodzi o sortowania bąbelkowe:
1. Dla prawie posortowanych danych jest bombowo szybkie, po zmianie np. piątego elementu w już posortowanej tablicy uwija się w 6sek! (94% szybciej), bo można zakończyć sortowanie gdy nie ma zamian. Sortowanie wyborem przyspiesza tylko o ~10% bo zyskuje się tylko na niewykonaniu zmian p$ i min. Nawet na tym gifie porównawczym to widać.
2. Kiedyś napisałem na OPUSa sortowanie nazw w katalogu dyskietki (w asemblerze). Program okazał się mało użyteczny, bo posortowanej dyskietki nie wolno było chyba defragmentować (się chyba robiła kaszana). Ale ładnie wyglądał, bo po każdym przebiegu wyświetlałem katalog i widać było jak jeden plik elegancko "wędruje" sobie na koniec ;D Zastosowałem sortowanie  bąbelkowe, nawet nie więdząc, że tak się nazywa - po prostu wymyśliłem że tak zrobię. Nawet Bill Gilbert początkowo się zachwycał ;)


Zastanawiam się czy może prościej by nie było stworzyć tylko tablice, posortowanych indeksow, tej pierwszej tablicy.
Też myślałem, że może być odrobinę szybciej - bo nie będzie trzeba zamieniać elementów, tylko kopiować/wstawiać do drugiej tablicy. Sprawdziłem - nie, jest niestety dłużej.
Stosuje się metodę podobną do algorytmu wyboru, ale bez jego plusów, bo nie eliminuje się z tablicy pierwotnej już wybranego elementu. Więc żeby go drugi raz nie wybrać - trzeba go oznaczyć (np, wpisując literę Z). Więc już mamy tyle samo operacji co w sortowaniu, a jeszcze dochodzi to, że cały czas trzeba przeszukiwać całą tablicę, a w sortowaniu w każdym przejściu przeszukuje się o 1 element krócej.
Plus dodatkowa duża tablica też spowalnia dostęp.


Ułożyła się z tego prawdziwa "seria niefortunnych zdarzeń" ;D
Tytuł: Odp: Sortowanie tablicy
Wiadomość wysłana przez: smok.wawelski w 2023.04.15, 15:29:57

Właściwie nie potrzebujesz sortowania tylko przepisanie jednej tablicy do drugiej na podstawie 1 litery każdego rekordu w 1 tablicy.
...
To jest odmiana sortowania z wyborem, tylko jest jedno kopiowanie a nie dwa. Myślę, że nie wyjdzie poniżej minuty...
21 sekund z optymalizacją, że jeśli znajdziemy już element, który chcemy przepisać do nowej tablicy, to na jego miejsce przepisujemy z końca tablicy inny element i skracamy pętlę o 1. Bez tej optymalizacji "sortowanie" zajmowało 41 sekund.

Oczywiście przy założeniu, że wybieramy rekordy tylko na podstawie 1 litery, jak zaznaczył TDU.

Kod:

5 DIM d$(100,10): DIM s$(100,10)
10 LET r=1
20 FOR l=65 to 99: LET k$=CHR$(l)
30 FOR n=1 to 101-r
40 IF s$(n,1)=k$ THEN LET d$(r)=s$(n): LET s$(n)=s$(100-r)
50 NEXT n
60 NEXT l

PS. Może jak nam TDU powie, do czego potrzebuje tego sortowania, to się nagle okaże, że bez sortowania się obejdzie w ogóle.
Tytuł: Odp: Sortowanie tablicy
Wiadomość wysłana przez: Phonex w 2023.04.15, 16:34:40
Optymalizacja robi robotę :)
Ale gdzieś jest błąd - ostatnich kilka wierszy tablicy wynikowej jest pustych. Różnie, widziałem od 2 do 6.
Tytuł: Odp: Sortowanie tablicy
Wiadomość wysłana przez: matofesi w 2023.04.19, 12:38:58
To jakby to jednak komuś było do czegoś potrzebne, to zapraszam do załącznika :)

sort.bas to oczywiście "demo" - 100 losowych stringów po 10 znaków ładowane do tablicy. Tablica może być zadeklarowana z dowolnymi rozmiarami o ile żaden z dwóch rozmiarów nie przekracza 255. Kod może być załadowany pod - w zasadzie - dowolny adres - jest relokowalny. W linii 25 następuje przekazanie parametru - używam bufora drukarki, żeby nie kombinować. Sorter używa ROMu do znalezienia właściwego adresu i jeśli przed szukaną tablicą jest dużo innych zmiennych to dodaje to chwilę do samego kodu. W linii 50 wywoływany jest sorter - tu przez PRINT USR, bo zwraca ewentualny kod błędu: 0 - posortowane OK, 1 - nie znalazł zmiennej, 2 - liczba stringów większa niż 255, 3 - długość stringa większa niż 255.

sort.tap - tak jak poprzednio skompilowane demo bez autostartu. Załadować, zrobić RUN, poczekać na READY, klepnąć dowolny klawisz - pokażą się FRAMESy początku i końca a pomiędzy kod błędu, klepnąć dowolny klawisz i kod wyświetli posortowaną tablicę.

sort.asm to kod właściwego sortera - nadal jest brzydki ;) A do tego w związku z tym, że @tdu nie potrzebuje rozróżniania wielkości liter sortowanie jest "binarne" bez maskowania.
Tytuł: Odp: Sortowanie tablicy
Wiadomość wysłana przez: tdu w 2023.04.19, 18:03:55
No to zdradze tajemnice, piszę programik START do FDD3000

Wszystko na razie w Basicu, program szczytuje, pliki do tablicy,
wyswietla je na ekranie po 15 rekordow,  mozna przesuwac kursor po jednej pozycji, ale tez po 15,
całymi stronami, w górę i w dół.
Szybkość w miarę, da się pracować, zmieściłem się w 1kB.

Planuję rozbudować program o funkcje, wchodzenia w foldery, zmiany nazw plikow,
zmiany atrybutów, kasowania plikow, itp
Ale to już powiększy plik, chciałbym się zmieścić w 4kB.

No i miło by było posortować tablicę przed jej wyświetleniem,
kod sortujący powinien być w zerowej linii pod adresem 23760.
 
Dziękuje z wykonanie kodu sortującego, pomyśle jak go zastosować.
Tytuł: Odp: Sortowanie tablicy
Wiadomość wysłana przez: Maryjan w 2023.04.19, 18:30:21
Eee... no jak program "szczytuje" to ja gratuluje :)

Ale na poważnie, ciekawy pomysł.
Tytuł: Odp: Sortowanie tablicy
Wiadomość wysłana przez: smok.wawelski w 2023.04.19, 19:07:57
No to możesz zrobić insert w trakcie sczytywania plików - umieszczać je od razu sortując (insertując). Wtedy masz bardzo niewiele operacji za każdym razem, bo tablica jest zawsze jest posortowana. Żeby uniknąć wielokrotnego przepisywania można by mieć - tak jak sugerowałeś - dwie tablice. Jedną z danymi i drugą ze wskaźnikami określającymi pozycję danego rekordu.

PS. Czemu chciałbyś się zmieścić w 4KB?
Tytuł: Odp: Sortowanie tablicy
Wiadomość wysłana przez: trojacek w 2023.04.19, 19:34:59
Pewnie chodzi o czas wczytania po starcie?
Tytuł: Odp: Sortowanie tablicy
Wiadomość wysłana przez: tdu w 2023.04.19, 19:36:28
4kB bo dla dyskietek gęstych, 620kB,
mały plik zawsze zajmie tyle, w tym systemie.

Dla dyskietek normalnych, 140kB, jest to 1kB
Tytuł: Odp: Sortowanie tablicy
Wiadomość wysłana przez: steev w 2023.04.19, 20:40:48
No to zdradze tajemnice, piszę programik START do FDD3000
Jak chcesz źródełko w asm prostego 'startu' z sortowaniem, to służę...
Demo w załączniku.
Tytuł: Odp: Sortowanie tablicy
Wiadomość wysłana przez: trojacek w 2023.04.19, 21:20:53
No to możesz zrobić insert w trakcie sczytywania plików - umieszczać je od razu sortując (insertując).

To jest bardzo dobre podejście, zbliżone do implementacji tzw. listy jednokierunkowej:

https://pl.wikipedia.org/wiki/Lista

Pojedynczy element składa się ze stringa z nazwą oraz wskaźnika na kolejny element (najprościej fizyczny, 16-bitowy adres w pamięci).

Taka lista wymaga w zasadzie implementacji dwóch operacji: "chodzenia" po liście (przechodzenia do kolejnego elementu na podstawie zawartości wskaźnika) oraz wstawiania w wybrane miejsce listy (listę można w dowolnym miejscu przerwać i wsadzić tam nowy element, który scala przerwane fragmenty, tworząc spójną listę).
Czyli po pobraniu nowej nazwy, wędrujemy od początku listy i porównujemy stringi. Gdy natrafimy na string "mniejszy" (wcześniejszy alfabetycznie) od nowego, odpinamy poprzedni element listy, zmieniając mu wskaźnik na nowy element, a nowy element ma stary wskaźnik z tego poprzedniego.
Na koniec wyświetlamy wszystko, idąc od pierwszego elementu listy do jej końca (elementu z zerowym wskaźnikiem na kolejny element, lub na "wartownika", w wariancie z wartownikiem).
Tytuł: Odp: Sortowanie tablicy
Wiadomość wysłana przez: tdu w 2023.04.27, 19:30:44
W końcu dopracowałem, mój program start.
Pobiera katalog dyskietki do tablicy i wyświetla w porcjach po 15 plików.
Jest to wersja maksymalnie okrojona tak aby zmieścić się w 1kB.
Nie ma żadnych ozdóbek ani wodotrysków, ma za zadanie wyświetlić pliki i po
podświetleniu uruchomić wybrany program.

Wyświetla tylko pliki basicowe.
Wczytanie podświetlonego programu Enter.
Przesuwanie podświetlenia: Q i A, oraz 1 i Z następne 15 plików.

PS. W natępnej wersji będzie sortowanie katalogu i wiele dodatkowych opcji,
ale to już raczej 4kB.



Tytuł: Odp: Sortowanie tablicy
Wiadomość wysłana przez: tdu w 2023.05.08, 13:41:29
@matofesi
Po wielu próbach doszedłem do przyczyny niedziałania kodu.
Okazuje się że zadeklarowana tablica musi być takiej samej długości
jak ilość rzeczywiście wpisanych do tablicy a$ stringów.

np. jeśli zadeklaruje DIM(100,5) to nie zadziała gdy ilość wpisów jest mniejsza niż 100.

Nie mogę z góry przewidzieć ile tych wpisów do a będzie, może być 10 a może 128,
taka jest maksymalna ilość wpisów w katalogu FDD3000.

Tak naprawdę to przemyśleniach widzę że bardziej przydatna byłaby tablica z posortowanymi indeksami do tablicy a$
proszę  :)
Tytuł: Odp: Sortowanie tablicy
Wiadomość wysłana przez: matofesi w 2023.05.08, 13:55:17
Tablica jest sortowana <b>cała</b> - jeśli nie jest wypełniona w całości to "puste" zapisy zostaną przesortowane na początek. Posortowanie zadanej liczby początkowych elementów tablicy nie powinno być problemem - trzeba by tylko pobierać parametr "z zewnątrz" a nie czytać długość tablicy.

Większym problemem jest to, że z jakiegoś powodu kod nie chce poprawnie działać jak się go umieści w REMie na początku... Owszem - sortuje, ale musi coś kaszanić w obszarze zmiennych i potem np. zmienna indeksowa nie leci po całej tablicy tylko zatrzymuje wyświetlanie po jednym ekranie. A że okazało się, że to co zrobiłem to nie to co ci było potrzebne to jakoś tak zdechło mi zacięcie do dalszych kombinacji ;)

Co do "posortowanych indeksów" zakładam, że chciałbyś mieć tablicę np. a$ zawierającą nazwy plików oraz tablicę np. a w której po "przesortowaniu" dostaniesz indeksy do kolejnych pozycji w a$ tak, żeby wyciąganie danych dawało posortowane wyniki bez faktycznego sortowania tablicy?... Wydaje mi się, że "indekser" byłby bardziej skomplikowany niż sorter... ale nie specjalnie mam koncepcję jak to zrobić, żeby się zbytnio nie narobić a do tego spełnić twoje wymagania co do prędkości oraz rozmiaru kodu.
Tytuł: Odp: Sortowanie tablicy
Wiadomość wysłana przez: tdu w 2023.05.08, 15:14:41
Jeśli chodzi że stwierdziłem że nie działa, to dlatego, że sprawdzalem
Tylko początkowe elementy tablicy, nie spodziewałem się ze będą one na końcu.
Moja wina.

Jeśli z indekserem jest problem, to może udało by się dopracować kod który jest,
Przekazanie długości przez Poke, może być, długość tablicy przed uruchominiem kodu jest znana.

Gorzej że nie dziala na 23760,  tak jakoś kiepsko widze doczytywanie kodu w programie Start.
A może kod przerzucić z 23760 na jakiś inny adres, ldir, przed uruchomieniem.
Przerzucenie 140 bajtów to będzie ułamek sekundy.
Tytuł: Odp: Sortowanie tablicy
Wiadomość wysłana przez: matofesi w 2023.05.08, 15:55:44
Przerzucanie nic nie daje... musiałem coś spaprać w wołaniu kodu z ROMu - sorter wczytany do REMa i przeniesiony "do góry" po pierwszym wywołaniu działa poprawnie, ale jak z kodu BASICa usunę LOAD to następne wywołanie coś kaszani ze zmiennymi i wyświetlanie posortowanej tablicy kończy się po jednym ekranie. I zupełnie nie rozumiem dlaczego.

Żeby było zabawnie jak po load""code dam stop a potem skasuję load i stop to odpalenie sortera od razu kaszani zmienne... Chyba za gupi jestem albo za ciepło - termometr na biurku pokazuje 30.7 °C ;)

Jak znajdę zacięcie, to jeszcze popatrzę, ale jakoś tak nie widzę co bym miał poprawić...
Tytuł: Odp: Sortowanie tablicy
Wiadomość wysłana przez: ZbyniuR w 2023.05.08, 17:36:09
A nie pomogłoby gdyby puste nazwy wypełnić jakimiś znakami które w sortowaniu trafią na koniec jak np znaki podkreślenia?
Tytuł: Odp: Sortowanie tablicy
Wiadomość wysłana przez: tdu w 2023.05.08, 18:25:56
@Zbyniu
Wypelnienie tablicy do 128 stringów spowoduje ze za kazdym razem trzeba te 128 stringów obsłużyc.
A to jest czas, który może denerwować.
W praktyce rzadko na dyskietce jest więcej niż 10, 20 czasem 40 wpisów, 128 to tylko teoria w praktyce raczej niespotykana.
@matofesi
pospiechu nie ma, ale gdybyś znalazł trochę czasu to by było fajnie.
Tytuł: Odp: Sortowanie tablicy
Wiadomość wysłana przez: matofesi w 2023.05.09, 09:38:37
No i chyba problem się wyjaśnił choć niestety nie rozwiązał... Wychodzi mi, że zassemblowany kod ma w środku coś, co powoduje, że - mimo REMa na początku linii - parser BASICowy dziczeje. Jeśli kod się wczytuje do REMa i od razu wykonuje to wszystko jest OK. Jeśli po wczytaniu kod się zatrzyma a potem damy RUN, albo GOTO, które wymusi przejście przez pierwszą linię to parser idzie gdzieś w kartofle i potem zmienna indeksowa nie działa jak należy - wyświetlanie posortowanej tablicy zatrzymuje się po jednym ekranie.

W związku z tym żeby sorter zadziałał poprawnie nie możesz dopuścić do tego, żeby kod parser analizował pierwszą linię. Czyli... po wczytaniu do REMa sortera musisz od razu zapisać program z LINE 10 - załadowany w ten sposób nie przechodzi (w odróżnieniu od goto 10 czy run 10) przez pierwszą linię i działa poprawnie. Jakiekolwiek zatrzymanie i ponowne uruchomienie wymagające od BASICa przeglądania pamięci kaszani dane w dziwny sposób.

W załączniku wszystko co potrzebne :)
sort_b.tap to pełne demo - kod startuje od linii 9999, wczytuje sorter do REMa i skacze do linii 10. Ustawia parametry, wczytuje dane i wyświetla przed posortowaniem. Potem READY, klawisz, sortowanie, klawisz i wyświetla jeszcze raz posortowane. Nazwę tablicy POKEujesz pod 23296, liczbę pozycji z początku, które ma ci przesortować pod 23298 - demo pokazuje w praktyce sortowanie pierwszej połowy stupozycyjnej tablicy.

sort.bas to źródło BASICowe tego samego programu
sort.asm to właściwy sorter
sort_asm.tap to sam skompilowany sorter w formie TAPa
sort.bin to to samo jako czysty kod binarny

Tytuł: Odp: Sortowanie tablicy
Wiadomość wysłana przez: trojacek w 2023.05.09, 13:58:16
zassemblowany kod ma w środku coś, co powoduje, że - mimo REMa na początku linii - parser BASICowy dziczeje.

Może kod dwukropka?
Tytuł: Odp: Sortowanie tablicy
Wiadomość wysłana przez: matofesi w 2023.05.09, 14:02:34
zassemblowany kod ma w środku coś, co powoduje, że - mimo REMa na początku linii - parser BASICowy dziczeje.

Może kod dwukropka?

No właśnie to nie powinno mieć znaczenia - REM pomija wszystko co jest dalej do końca linii. A przynajmniej powinien pomijać i ignorować.
Tytuł: Odp: Sortowanie tablicy
Wiadomość wysłana przez: Phonex w 2023.05.09, 14:38:54
Stawiam na "koniec linii" przed końcem linii ;)
Czyli 13 - kod ENTER.
Sam ENTER nie jest zabójczy, ale odczytane po nim dwa bajty zinterpretowane przez część procedur BASICa jako "numer linii" muszą dawać wynik w dozwolonym zakresie (9999). Na 100% wykłada się na tym READ, bo nie znajduje linii DATA jeśli nie jest wskazana konkretnie przez RESTORE nn.
Możliwe że bajty zinterpretowane jako "długość linii" też mają znaczenie...
Tytuł: Odp: Sortowanie tablicy
Wiadomość wysłana przez: matofesi w 2023.05.09, 14:42:41
Stawiam na "koniec linii" przed końcem linii ;)
Czyli 13 - kod ENTER.

Nope. Nie ma entera w kodzie.
Tytuł: Odp: Sortowanie tablicy
Wiadomość wysłana przez: Phonex w 2023.05.09, 14:47:12
To może kody kolorów? X,n gdzie X to 16...21, a n niedozwolona dla danego kodu wartość.
Chociaż nie wiem co to ma do tablic, psuje wyświetlanie przez LIST.
Tytuł: Odp: Sortowanie tablicy
Wiadomość wysłana przez: matofesi w 2023.05.09, 14:48:10
To musi być coś głębszego - zawartość REMa nie rozwala samego programu bo całość jest w stanie się wykonać póki parser nie przejedzie przez program. I wtedy też zachowuje się dziwnie bo nie wyrzuca błędów itp. tylko zachowuje się jakby coś się kaszaniło w zmiennej indeksowej (w wypadku mojego programu - i). Podejrzewam, że coś tam się psuje w środku - zmienne indeksowe przechowują informację o pętli a nie tylko wartość...

Nigdy nie robiłem kodu, który siedziałby w REMie i robił coś więcej niż wczytywanie bloku bez nagłówka itp. i jeszcze musiał "gadać" z BASICem ;)
Tytuł: Odp: Sortowanie tablicy
Wiadomość wysłana przez: matofesi w 2023.05.09, 15:04:41
No to wiem ciut więcej... Kaszani sprawę nie parsowanie w trakcie wykonania tylko wyświetlenie zerowej linii z REMem. Jak się program odpali i po jego zakończeniu bez wyświetlania treści zrobi kolejny raz RUN to się wykonuje poprawnie. Dopiero jak się wyświetli kod to kolejne wykonanie już się kaszani. Czyli prawdopodobnie jakaś kombinacja kodów sterujących powoduje, że coś się zmienia w zmiennych systemowych...

Tytuł: Odp: Sortowanie tablicy
Wiadomość wysłana przez: Phonex w 2023.05.09, 15:13:42
To samo jest w OPENERZE, też nie wyświetla "scroll?".
Jednak niedozwolone kody kolorów lub AT/TAB. Czyli 16..23, n

Można to ominąć dodając na początku linii 31 "PRINT #2;:"

EDIT: szajs! nie zawsze działa. Tzn. działa po LIST, a nie po AUTO-LIST (po naciśnięciu ENTER).
Tytuł: Odp: Sortowanie tablicy
Wiadomość wysłana przez: matofesi w 2023.05.09, 15:15:44
Hmmm... Czyżby dziwny zestaw kodów powodował, że się dane kanałów psują?

Bo tak - nie wyświetla się "scroll?".
Tytuł: Odp: Sortowanie tablicy
Wiadomość wysłana przez: matofesi w 2023.05.09, 15:34:51
No i znalazłem przyczynę - DJNZ ma kod $10 czyli INK. Jak się do tego doda przesunięcie ujemne to się kaszani. Oraz LD D,n z kodem $16 - AT z dwoma parametrami w tym drugi zdecydowanie za duży.

@Phonex Dzięki za nakierowanie we właściwą stronę :)

W załączniku jeszcze raz to samo tylko tym razem się nie kaszani ;)
Tytuł: Odp: Sortowanie tablicy
Wiadomość wysłana przez: tdu w 2023.05.09, 15:48:54
@matofesi
Wielkie dzięki za pomoc, stawiam piwo, jeśli tylko chciałbyś przyjechać do Gdańska, oferuje tez nocleg dla 2 osób, w promocyjnej cenie i w/w piwo.

Testy będę robił dopiero po niedzieli, jutro wyjeżdżam na majówkę.
Tytuł: Odp: Sortowanie tablicy
Wiadomość wysłana przez: Phonex w 2023.05.09, 15:52:13
Chciałem doradzić zakodowanie procedury (np. XOR 16) tak, żeby znikły te kody i wykonywanie po przeniesieniu wyżej i odkodowaniu.
Ale nie zdążyłem - okazuje się, że szybciej jest przerobić kod :D

Znalazłem też kolejny, łatwiejszy sposób na ominięcie tego problemu: ten poprzedni sposób "PRINT #2;:" nie zawsze działa, ale zawsze działa jak się dopisze w linii 31 "LIST 10000:"
Tytuł: Odp: Sortowanie tablicy
Wiadomość wysłana przez: tdu w 2023.05.10, 07:56:00
Pojedynczy rekord odczytany z katalogu dyskietki ma długość 32 bajty.
Nazwa pliku to bajt 2 do 9, nie ma sensu więc sortowanie całej tablicy.
Można jakoś wymusić w kodzie głębokość sortowania?  może kolejny poke.
Pierwszy bajt jest stały i nie wpłynie na efekt sortowania, zresztą mogę go wyciąć przy tworzeniu tablicy.
Bajtów powyżej 9 nie mogę wyciąć bo są tam dodatkowe informacje o pliku.
Tytuł: Odp: Sortowanie tablicy
Wiadomość wysłana przez: matofesi w 2023.05.10, 09:38:57
No da się... Oczywiście kosztem rozmiaru - teraz doszliśmy do 159 bajtów.

23299 przechowuje długość początkowego kawałka który ma brać do porównania. Jeśli jest tam zero, to zostanie ustawione na długość całego stringa jeśli co innego to ta wartość zostanie użyta w porównaniach i nie jest już dalej kontrolowana. Można więc zrobić dim(50,10) a potem poke 23299,20 i sorter będzie porównywał dwudziestoznakowe kawałki ale zamieniał będzie zgodnie z zadeklarowanym rozmiarem.
Tytuł: Odp: Sortowanie tablicy
Wiadomość wysłana przez: tdu w 2023.05.10, 11:19:29
Super, to jest teraz to o co chodziło.
(chyba że coś jeszcze wyjdzie czego nie mogę przewidzieć)

Testy niestety dopiero po niedzieli.
Jeśli chodzi o długość to już mało istotne czy 140 czy 160.

Jeszcze raz dziękuje, również innym forumowiczom
którzy aktywnie włączyli się do dyskusji.
Tytuł: Odp: Sortowanie tablicy
Wiadomość wysłana przez: tdu w 2023.06.21, 10:51:59
No i w końcu jest pierwsza użytkowa wersja programu
START dla FDD3000 który tworze od prawie dwóch miesięcy,
powinien on się znaleźć na każdej dyskietce działającej z TOS

Program czyta katalog dyskietki, sortuje go i wyświetla
w porcjach po 15 plików (klawisze 1,q,a,z)

Wczytanie programów (tylko basic), klawisz ENTER.

Ponadto w menu1 ogólne
I info o dostepnych dyskach
S nagranie programu START
F format na 140kB
G format na 620kB
K katalog systemowy
L wczytanie z tasmy
J kopia całej zawartości dyskietki

menu2 plikowe
K kopia pliku
U usuwanie pliku
Z zmiana nazwy pliku
I info o pliku

Program mieści się w 4kB czyli jednostce alokacji dla dysków 620kB

Program nie obsługuje katalogów i atrybutów, przynajmniej w tej wersji,
nie wiem czy warto to dorabiać bo mało kto i tak z tego korzysta,
a wydłuży to czas odczytu dyskietki, co i teraz jest na granicy akceptacji.
Poza tym program zajmie już kolejne 4kB.

Czas odczytu dyskietki można skrócić przez edycje linii 2 programu
zmieniając LET z=64, na wartość mniejszą np.32, zleży to od ilości
plików na dyskietce, w typowych zastosowaniach 140kB powinno wystarczyć
z=20, ale dla ekstremistów może być pełne 128, tyle maksymalnie plikow
może by na dyskietce.

Nie gwarantuje że program jest bez wad, więc liczę na Wasze uwagi,
powstanie wtedy kolejna poprawiona wersja.

Podziękowania dla Matofesi za wykonanie kodu sortującego tablicę z nazwami plików.
Tytuł: Odp: Sortowanie tablicy
Wiadomość wysłana przez: tdu w 2023.06.21, 10:54:11
Tutaj powinien być załącznik