Permalänk

Stafettlek för programmerare

/* * Stafettlek för programmerare. * * Tävligen är väldigt enkel och består av två moment: * * A) Bidra med kod för att bygga upp ett framework. * B) Använd framework:et för skriva originella program. * * Reglerna är väldigt enkla * - man skall enbart använda funktioner/datastrukturer från denna modul. * - inga funktionsanrop till standardbiblioktet. * - inga "headers" får inkluderas. * - inga externa bibliotek. * * Tanken är alltså att vi skall sluta upp med en jättestor fil som utgör vårt * "standardbibliotek" när vi går över till moment (B). * * Finns inga krav på att man måste bidra till (A) för att få delta i (B) eller * att man måste använda en viss stil. Keep it simple, reuse and code(tm). * * Språk: C * * Senaste versionen av denna fil hittar ni hittar ni på: * * http://www.superdupa.com/public/code/swec/ * * Tips/ideér: * - implementera memcpy/memset/memmove * - vi behöver helt klart de vanligaste strängfunktionerna * - få till lite buffrad output istället för en write_char åt gången * - matematik funktioner (sin/tan/exp/log) * - använd stdin/stdout för att komma åt filer under moment (B). * - implementera lite enkla filformat (t.ex TGA) * * Lycka till! * * PS. Ni som hänger på #c++.se kan väl försöka få hit lite folk. * */ #define NULL ((void*)0) /* *======================================= * Boilerplate and primitive I/O functions (from support.c) *======================================= */ #define assert(expr) \ do{if(!(expr)){assertion_failed(#expr,__FILE__,__LINE__);}}while(0) /* Print error message and terminate program execution. */ extern void err_quit(char *fmt, ...); /* Print developer output. */ extern void trace(char *fmt, ...); /* Report runtime assertion failure. */ extern void assertion_failed(char *expr, char *file, int line); /* Returns 0 if char could not be written to stdout. */ extern int write_char(int ch); /* Returns 1 if the input stream (stdin) has reached end of file. */ extern int is_eof(); /* Returns char value (0-255) or (-1) if read operation from stdin failed. */ extern int read_char(); /* Returns pointer to freshly allocated memoryblock of n bytes. */ extern void *mem_alloc(int num_bytes); /* Deallocate memory block. */ extern void mem_free(void *p); /* *======================================= * Your contribution here [nick] *======================================= */ /* This comment tell us what myfunc returns. */ void myfunc() { } /* *======================================= * Program entrypoint. *======================================= */ #define UNUSED_ARGUMENT(x) ((void)(x)) int main(int argc, char *argv[]) { UNUSED_ARGUMENT(argc); UNUSED_ARGUMENT(argv); return 0; }

Permalänk
Medlem

Tävling är det väl ändå inte?

Permalänk
Medlem

vad är ett framework? och vad ska denna grej vara till för?

idén är jävligt cool :D... bara alla är med på vad som har hänt så!... halvjobbigt att läsa igenom hela scriptet sen när det har 2000 rader kod och inte alla följer samma sätt att skriva kod på..

Visa signatur

/Jeppe

Permalänk
Hedersmedlem

Känns lite ogenomtänkt/nybörjaraktigt.

Tex, vad är det för C? ansi/c89? c99? Vad är det för licens? Allt måste ju rimligen följa samma licens.

Framförallt, vad är meningen/målet? Känns ju lite konstigt att skapa ett standardbibliotek som bara är sämre än tex glibc.

Visa signatur

motor.holy.se - Projekt "Tüsk MiniJänk med Engelsk V8"
"Bingolotto, till och med Loket har trötnat" - Loesje
"Och jag som trodde att världens häftigaste moderator inte existerade!" - Robbster

Permalänk

Klart att det är en tävling. Alla som på något sätt bidragit får sedan rösta fram den skrivit mest användbara funktioner, finurliga lösningar samt den som på snyggast sätt använt koden för att skapa ett coolt program.

Det här kräver dock lite mer fantasi än tidigare tävlingar som figurerat på forumet. Fördelen är dock att man får se lite fler originella grejer än samma lösning på 10 olika språk.

Med "framework" menar jag hela källkodsfilen där jag klistrat in alla bidrag. Slutresultatet blir alltså en massa källkod med förhoppningsvis en mängd olika funktioner skrivna med olika personliga stilar.

Vad är då den bakomliggande tanken?

Jo, man får läsa kod man själv inte skrivit. Man får lära sig att inte skriva samma saker flera gånger utan försöka bygga vidare på existerande kod. Dessutom så kan man ställa frågor i tråden om det skulle vara så att man inte förstår något bidrag.

Det är heller inte tänkt att detta skall vara en speciell klubb för alla som jätteduktiga på att programmera. Avancerad och komplex kod gör det bara svårare för alla andra.

Lite exempel:

Rampkorv skickar in följande:

/* *======================================= * String search [Rampkorv] *======================================= */ /* Returns location of first match or NULL if char was not found. */ char *SearchForChar(char *str, char ch) { char *p = str; while (p) { if (*p == ch) return p; if (*p == '\0') /* End of string, null terminator. */ break; p++; } return NULL; }

Lite senare bestämmer sig Sirjeppe för att vi behöver en "strlen". Sirjeppe ser möjligheten och använder Rampkorvs kod för att skriva sin funktion:

/* *======================================= * String length [Sirjeppe] *======================================= */ /* Return length of string (>= 0). */ int strlen(char *str) { char *nullPos = SearchForChar(str, '\0'); return (nullPos ? (nullPos - str) : 0); }

Dessa två funktioner kan en tredje person använad för att skriva ett enkelt commandline program (moment B) som kan.....

Jag vet inte riktigt hur stort intresset kan tänkas vara. Det var tänkt som en cool grej, vi har ju liksom en hel duktiga programmerare på forumet som kan dela med sig av lite sjysta tricks samtidigt som alla "lärlinglar" får en gyllene chans att lära sig "hacka".

Finns det inget intresse låter vi helt enkelt tråden dö.

(C89 vs C99? Spelar roll. Licens? Tja, har man några problem med public domain i detta sammanhang får man väl enkelt inte deltaga.)

Permalänk
Medlem

Hade varit mer intreserad om det var C++ det handlar om. Samt ifall funktionerna fick se ut hu de ville, skulle ge mer att göra jobbigt att skriva om alla funktioner som finns innbygda helt från scratch.

Kommer t.ex bli ganska tråkiga program utan outputs inputs o.s.v. annars.

Visa signatur

Speldator: Ryzen 7800X3D, 64GB DDR5, RTX 5090
Server: i7-8700k, 32GB DDR4, RTX2080
Steam deck, Rog Ally + de fiesta konsoler.

Permalänk
Hedersmedlem

Tja, viss roll spelar det ju. Något krav på kompileringsbarhet måste det ju vara om det ska gå att kompilera. Men det är väl lagningsbart.

Imho är det tydligast om man har satt någon licens på sakerna, åtminstånde en av enradstyp ("as is, do what you want"), blir så mycket tydligare så.

Aja. Lek på ni. För att lära sig är det ju väldigt smidigt, speciellt med lite naturlig feedback.

Visa signatur

motor.holy.se - Projekt "Tüsk MiniJänk med Engelsk V8"
"Bingolotto, till och med Loket har trötnat" - Loesje
"Och jag som trodde att världens häftigaste moderator inte existerade!" - Robbster

Permalänk
Hedersmedlem

Kodstilen är ju inget problem, bara köra indent på den.

Exempelvis indent -kr fil.c för att få hela filen till K&R Indenting Style (TIS/TBS).

Visa signatur

Vim
Kinesis Classic Contoured (svart), Svorak (A5)
Medlem i signaturgruppen Vimzealoter.

Permalänk

MugiMugi:

Det krävs som sagt lite fantasi. Du har allt du behöver, du kan skriva en char till stdout och du kan läsa en char från stdin. Det räcker med ca 2-3 funktioner för att du skall kunna få ihop en buffrad fputs/fgets variant.

Poängen är ju så _lite_ kod som möjligt.

Qaztaz:

Jag har aldrig varit med om att någon försökt klistra på en licens för kod man postat på ett forum. Och ja, det här är en lek. Precis som IOCCC.

Ah, well. Det får gå som det går. At least I tried....

--------------------------------

Edit:

Tja, eftersom intresset verkar vara dött så föreslår jag istället en väldigt enkel och något mer språkoberoende tävling.

Skriv en scrabble (alfapet) matchare:

C exempel: boolean scrabble_match(char *word, char *letters);

Dvs:

scrabble_match("rabbit", "abbirts") = true
scrabble_match("rabbit", "xbbirts") = false

Enkelt och tydligt.

(Jag har skrivit en egen variant som hamnat i en uppdaterad version av ovan nämnda kälkodsfil. Leta efter länken. Rekomenderar dock att man skriver en EGEN version innan man tittar på min eller förhoppningsvis andra lösningar.)

Skulle vara sjyst om någon kunde bumpa tråden.

Permalänk
Medlem
Citat:

Ursprungligen inskrivet av BobbyFromDallas
...

Tja, eftersom intresset verkar vara dött så föreslår jag istället en väldigt enkel och något mer språkoberoende tävling.

Skriv en scrabble (alfapet) matchare:

C exempel: boolean scrabble_match(char *word, char *letters);

Dvs:

scrabble_match("rabbit", "abbirts") = true
scrabble_match("rabbit", "xbbirts") = false

Enkelt och tydligt.

(Jag har skrivit en egen variant som hamnat i en uppdaterad version av ovan nämnda kälkodsfil. Leta efter länken. Rekomenderar dock att man skriver en EGEN version innan man tittar på min eller förhoppningsvis andra lösningar.)
...

Hur avgör du vem som är vinnare?

Visa signatur

Sverige är ett så litet land att det bara får plats en åsikt i taget där.

Permalänk

Förstår inte riktigt var hela idén om att det måste finnas en enskild vinnare kommer ifrån? Deltar man och klarar av tävlingsmomentet är man en vinnare.

Finns det ingen som programmerar för att det kul?

Permalänk
Medlem
Citat:

Ursprungligen inskrivet av BobbyFromDallas
Förstår inte riktigt var hela idén om att det måste finnas en enskild vinnare kommer ifrån? Deltar man och klarar av tävlingsmomentet är man en vinnare.

Finns det ingen som programmerar för att det kul?

Klart man programmerar för att det är kul, men att kalla det tävling känns lite fel då det underlättar om man kan avgöra en vinnare.

Visa signatur

Sverige är ett så litet land att det bara får plats en åsikt i taget där.

Permalänk
Glömsk

Fan vad anti alla är här, tycker båda idéerna är intressanta.

Scrabble i python:

def scrabble(word, letters): letters = [l for l in letters] for w in word: if w in letters: letters.remove(w) else: return False return True

Visa signatur

...man is not free unless government is limited. There's a clear cause and effect here that is as neat and predictable as a law of physics: As government expands, liberty contracts.

Permalänk
Medlem

Inte för att jag tror att jag klarar någon av sakerna, men jag håller med Psionicist. Båda idéerna är intressanta.

Visa signatur

Vill du ha svar? Citera mig gärna.

Permalänk

Tack, Psionicist.

Din lösning är vad som kan kallas för "skolboksexemplet".

Problemet är samma metod inte fungerar så bra när man skall matcha mot ett väldigt stort antal ord, t.ex. om man skall försöka härma iTunes/Spotlight sökmetod där resultaten listas i "realtid" eller om en server står för kalaset i form av en webapplikation.

Eftersom intresset är dött även denna gång postar jag min lösning, en algoritm/metod som jag stött på när jag studerat kod fast då i helt annat sammanhang.

Enjoy!

/* *======================================= * Generate primes [bobby] *======================================= */ /* Returns 1 if n can be factored using supplied table of primes. */ int can_factor(int n, int *primes, int num_primes) { int i; for (i = 0; i < num_primes; i++) { if ((n % primes[i]) == 0) return 1; } return 0; } /* Computes the first 'n' primes and stores them into 'sieve'. Note: caller must ensure array size of 'sieves' >= 'n'. */ void gen_primes(int n, int *sieves) { int i, j; if (n > 0) { sieves[0] = 2; for (i = 1; i < n; i++) { /* Search forward from last prime. */ j = sieves[i-1] + 1; while (can_factor(j, sieves, i)) j++; sieves[i] = j; } } } /* *======================================= * Scrabble matcher [bobby] *======================================= */ /* Assign each character a prime factor based on a simplistic character frequency distribution order (higher freq gives low prime). */ void setup_char_prime_table(int *chartab) { int i; int primes[26]; int order[26] = {'e','t','a','h','o','s','n','r','i','l','d','u','w', 'm','c','g','y','f','b','p','k','v','j','x','q','z'}; gen_primes(26, primes); for (i = 0; i < 26; i++) chartab[order[i] - 'a'] = primes[i]; } /* Returns prime factor representation for a given letter [a-z]. */ int char_as_prime(char ch) { static int primes[26]; static int table_init = 0; assert(ch >= 'a' && ch <= 'z'); if (!table_init) { setup_char_prime_table(primes); table_init = 1; } return primes[ch - 'a']; } #define MAX_WORD_VALUE 2147483647 #define MUL_WILL_OVERFLOW(prod, fact) ((MAX_WORD_VALUE / (prod)) < (fact)) /* Compute a numerical representation of word [a-z] using prime factors. */ int make_word_num(char *word) { int i, r, k; /* Abuse the fundamental theorem of arithmetic to create number where each letter maps to a specific prime factor. */ r = 1; for (i = 0; i < strlen(word); i++) { k = char_as_prime(word[i]); /* @Portability: Word probably contained lots of characters with low frequency which would have resulted in an overflow. This is not an algorithmic limitation but rather the lack of a builtin 'bignum'. */ if (MUL_WILL_OVERFLOW(r, k)) err_quit("Overflow during calculation of 'make_word_num'."); r *= k; } return r; } /* Returns 1 if 'word' can be made up by using some or all letters in 'rack'. Note: caller must filter arguments through 'make_word_num'. */ int scrabble_match(int word, int rack) { /* The idea is very simple. If we represent our rack "abab" as 2*3*2*3=36 and the word "abb" as 2*3*3=18 we can easily see that 18 shares factors with 36 and thus the it can be composed using the "factors" from the rack. */ return (rack % word) == 0; } /* * trace("match: %d\n", * scrabble_match( * make_word_num("rabbit"), * make_word_num("abbirt"))); * * trace("match: %d\n", * scrabble_match( * make_word_num("rabbit"), * make_word_num("xbbirt"))); * */

Permalänk
Glömsk
Citat:

Ursprungligen inskrivet av BobbyFromDallas
Din lösning är vad som kan kallas för "skolboksexemplet".

Det är också en "lättläslig" lösning, därför jag använde Python.

Ska försöka slå dig i hastighet nu.

Visa signatur

...man is not free unless government is limited. There's a clear cause and effect here that is as neat and predictable as a law of physics: As government expands, liberty contracts.

Permalänk
Medlem

Har ni nån ordboksfil så man kan testa om man provar att göra en lösning?

Visa signatur

Sverige är ett så litet land att det bara får plats en åsikt i taget där.

Permalänk
Citat:

Ursprungligen inskrivet av Psionicist
Det är också en "lättläslig" lösning, därför jag använde Python.

Ska försöka slå dig i hastighet nu.

Jo, jag vet. Jag försökte inte dissa dig utan bara ge en hint om hur jag hade tänkt att tävlingen skulle sett ut. Först skulle alla få presentera sina lösningar och gnälla över att det var för lätt.

Sedan ändrar man förutsättningarna litegrann och tar tävlingen till en ny nivå.

(Lösningen som jag presenterade långt ifrån den mest optimala lösningen generellt sett. Tror man får växla mellan ett par olika metoder för att uppnå bäst resultat.)

Och ja, jag lovar att aldrig mer försöka mig på något sådant här.

Danel:

Har laddat upp en enkel ordlista:

http://www.superdupa.com/public/code/swec/

Du får trixa lite med datan, ignorera bindestrecken etc..

Runt 57000 ord.

Lycka till allihop!

Permalänk
Glömsk

Okej, efter att ha försökt klurat ut en smartare lösning än Bobbys och misslyckats fick jag svälja och försöka vinna på den totala avsaknaden av slö aritmetik istället. Är lite bitter på den andra loopen dock, skulle vara trevligt att bli av med den.

char scrabble(char *word, char *letters) { /*assert(strlen(word) < strlen(letters));*/ int lookup_word[27] = {0}; int lookup_letters[27] = {0}; int index; char *w = word; while(*letters != 0) { if(*w != 0) { lookup_word[*w - 'a']++; w++; } lookup_letters[*letters - 'a']++; letters++; } w = word; while(*w != 0) { index = *w - 'a'; if(lookup_letters[index] < lookup_word[index]) return 0; w++; } return 1; }

Visa signatur

...man is not free unless government is limited. There's a clear cause and effect here that is as neat and predictable as a law of physics: As government expands, liberty contracts.

Permalänk

När du vill matcha mot 50000 ord vill du inte köra den där loopen.

Vad händer om du sorterar både 'word' och 'letters'?

Ex:

word = rabbit = abbirt
letters = catbibbrs= abbbcirts

Lite precalculation + en juste trädstruktur kanske...

Permalänk
Medlem

Vad mycket kritik ni ger Bobby. Jag tycker det är ett väldigt trevligt initiativ.

Jag bidrar med en lösning.

bool scrabble_match(std::string word, std::string letters) { std::sort(letters.begin(), letters.end()); do { if (word == letters) return true; } while (std::next_permutation(letters.begin(), letters.end())); return false; }

edit: Heh, att sortera båda och jämföra är nog bättre. Min lösning är mer anpassad för att jämföra med en hel ordlista än bara för ett ord. Even then, är det nog bättre att sortera hela ordlistan och jämföra med sorterade letters... hm...

edit2: När jag tänker efter är min lösning rätt dålig, och jag tror jag kanske missförstod frågan lite. Men bättre än inget.

Visa signatur

:€

Permalänk
Glömsk

Aha, bokstäver ska matchas mot en massa ord inte tvärt om. Man får alltså trolla lite med orden när de läses eftersom de kommer bara läsas en gång.

Får skylla på att jag aldrig spelat scrabble förr.

Visa signatur

...man is not free unless government is limited. There's a clear cause and effect here that is as neat and predictable as a law of physics: As government expands, liberty contracts.

Permalänk
Medlem

Ni avslöjar ideer för mycket tycker jag.

Visa signatur

Sverige är ett så litet land att det bara får plats en åsikt i taget där.

Permalänk
Hedersmedlem
Citat:

Ursprungligen inskrivet av eighty
Vad mycket kritik ni ger Bobby. Jag tycker det är ett väldigt trevligt initiativ.

Jag bidrar med en lösning.

bool scrabble_match(std::string word, std::string letters) { std::sort(letters.begin(), letters.end()); do { if (word == letters) return true; } while (std::next_permutation(letters.begin(), letters.end())); return false; }

edit: Heh, att sortera båda och jämföra är nog bättre. Min lösning är mer anpassad för att jämföra med en hel ordlista än bara för ett ord. Even then, är det nog bättre att sortera hela ordlistan och jämföra med sorterade letters... hm...

edit2: När jag tänker efter är min lösning rätt dålig, och jag tror jag kanske missförstod frågan lite. Men bättre än inget.

Det där går ju inte, det är ju C++, han söker C. Såvidare du inte skriver om funktionen till C förstås.

Jag ska fundera ut något, återkommer isf.

Visa signatur

Vim
Kinesis Classic Contoured (svart), Svorak (A5)
Medlem i signaturgruppen Vimzealoter.

Permalänk
Citat:

Ursprungligen inskrivet av m0REc
Det där går ju inte, det är ju C++, han söker C. Såvidare du inte skriver om funktionen till C förstås.

Jag ska fundera ut något, återkommer isf.

Citat:

Ursprungligen inskrivet av BobbyFromDallas
Tja, eftersom intresset verkar vara dött så föreslår jag istället en väldigt enkel och något mer språkoberoende tävling.

Permalänk
Hedersmedlem
Citat:

Ursprungligen inskrivet av vigge89
citat...

Aha, hade missat det.

Visa signatur

Vim
Kinesis Classic Contoured (svart), Svorak (A5)
Medlem i signaturgruppen Vimzealoter.

Permalänk
Medlem

http://home.student.uu.se/d/daki0267/test/scrabble.rar

Program som går igenom en ordlista och tar fram de matchande orden.
Tar ungefär 5s i uppstart första gången
och en sökning tar ungefär 0.2s

Kod skriven i QB

orkar inte optimera då man oftast orkar vänta 0.2s.
annars om man först sorterar ordlistan samt lagrar den i minnet så kan man nog få ner tiden mer om man nu har bråttom.

Visa signatur

Sverige är ett så litet land att det bara får plats en åsikt i taget där.

Permalänk

Trevligt.

Kan du inte fixa .rar:en så att man kan kolla på koden, .bas filen verkar vara korrupt.

Permalänk
Medlem
Citat:

Ursprungligen inskrivet av BobbyFromDallas
Trevligt.

Kan du inte fixa .rar:en så att man kan kolla på koden, .bas filen verkar vara korrupt.

Den var visst sparad i qb egna format, var därför.

Här får du en som du kan läsa.
http://home.student.uu.se/d/daki0267/test/scrabble.bas

Kom på att man kanske även ska inkludera korta ord som går att bilda utifrån bokstäverna. Får försöka fixa det också.

Visa signatur

Sverige är ett så litet land att det bara får plats en åsikt i taget där.

Permalänk

Ok. Nu får du ursäkta mig om jag är ute och cyklar men jag tror att du har missförstått uppgiften.

Alfapet fungerar så här, man har ett rack med bokstäver som man utifrån försöker bygga ord på ett bräde. För att förenkla skippade jag brädan och fokuserade på huvuduppgiften, matcha olika ord med hjälp av X bokstäver.

Nu inser jag att vilket otroligt dåligt exempel jag valde när jag presenterade uppgiften, men så här var det tänkt i alla fall.

Om man har bokstäverna |s|a|v|e|d| så kan man matcha mot följande "ord" as/vase/save/saved/ etc...

Man behöver alltså inte använda alla bokstäver.

Det här verkar inte alls vara min dag.

(Som tur är så kräver sättet du löst uppgiften bara ett par mindre modikationer för att fungera korrekt.)