Challenge

Uživatelský avatar
kiRRow
Příspěvky: 710
Registrován: 07 kvě 2019, 07:03
Reputation: 0
Bydliště: Opava

Challenge

Příspěvek od kiRRow » 24 lis 2021, 15:45

Co kdybychom si zde udělali místečko, kde bychom si různě zkoušeli zadávat nějaké zajímavé úlohy z oboru programování i konstrukčních řešení?

Absolutně základní pravidla by byla asi takováto : ( zbytek se doladí )
- Problém musí být samotným autorem vyřešen - žádné plnění cizích úkolů
- Problém by měl být poučný a v praxi využitelný
- Nutno dodat kompletní schéma, program - aby si každý mohl ověřit řešení kohokoliv jiného
- Řešení by mělo i obsahovat to jak jsem k němu přišel a hlavně být otestováno, že je funkční
- Příspěvky by zde měli mít štábní kultůru
- Žádné klábosení kolem, pokud si o tom budete chtít popovídat = samostatné téma ve správné kategorii - jsou tu citace odkazy, tam bude jen zadání a řešení

Co si od toho slibuji :
- Větší aktivita na fóru ( sami víte, že tu je fakt někdy mrtvo )
- Možnost porovnat několik různých přístupů k problému
- Za dobrá řešení dávat lidem +reputaci ( konečně by se dala rozumně použít )
- Určitě tu někdo někdy vymyslel nějaké chytré řešení a má možnost se sním pochlubit - i když to není celý hotový projekt

Zkusím nastínit utopický případ :
Programátor nováček potřebuje odesílat do zařízení HEX data v pořadí 0x01 0x02 0x04 0x08 0x10 0x20 0x40 0x80 0xFE 0xFD 0xFB 0xF7 0xEF 0xDF 0xBF 0x7F, tak vytvoří pole kde to napíše na tvrdo a tu projede pomocí for, v každém cyklu data odešle ... všechno funguje jak má, je spokojený že to tam konečně po 3dnech, 4hodinách dostal ... tak se příjde pochlubit : Musel jsem to a to, tak jsem to vymyslel tak a takhle - dívejte tu mám program.

Příjde člověk zkušenější programování a zjistí, že když ty data převede do desítkové soustavy, tak je to 1 2 4 8 16 32 64 128 254 253 251 247 239 223 191 127 ... a že to jsou v podstatě dvě posloupnosti po 8 krocích ... prvních osm je dvojnásobek toho předchozího a druhých osm je 255 - výsledek z první posloupnosti

Příjde člověk co pomalu vidí Matrix - převede to do bináru a řekne ano jsou to dvě posloupnosti ... 2x cyklus for i=0;i<8;i++ první je 1<<i a ta druhá ~(1<<i)

jankop
Příspěvky: 880
Registrován: 06 zář 2017, 20:04
Reputation: 0
Bydliště: Brno
Kontaktovat uživatele:

Re: Challenge

Příspěvek od jankop » 24 lis 2021, 16:30

Myšlenka to není špatná. pokud se to nezvrhne na příklady s Lucasovou posloupností apod. Mělo by to být prakticky využitelné, atraktivní pro realizaci a přitom jednoduché jak facka :D
Budu o tom přemýšlet, ovšem ty bys měl jít příkladem :D

Uživatelský avatar
kiRRow
Příspěvky: 710
Registrován: 07 kvě 2019, 07:03
Reputation: 0
Bydliště: Opava

Re: Challenge

Příspěvek od kiRRow » 24 lis 2021, 17:44

Raději nic, než něco zvrhlého.
Každý jsme nějak začínali a byli jsme z počátku postaveni před problém, který tehdy vypadal neřešitelně, nyní je to banalita. Stále se vyvíjejí nové věci, člověk se učí a objevuje celý život.
Jako dítě jsem se občas hlásil na programátorské soutěže, když už jsem problém vyřešil, nikdy jsem nevyhrál a vždy jsem valil oči na to kolik jiných řešení je. Programovat jsem se učil/učím sám svými chybami a mnohdy jsem si ani neuvědomoval, že nějakou dělám. Vše fungovalo a bylo OK, dokud se na to nekouknul člověk, který tomu rozuměl více než já.
Komunita zde je super, pro ostatní toho děláme mnoho (a někteří to fakt ani nezaslouží), pojďme dělat i něco pro sebe a pro zábavu :) - až se tu zas bude řešit debounce tlačítka, proč nemít forum, kde je vyřešeno jak .. (ten example je fakt děsnej) .. a pod tím, překopáno jak to udělat tak aby se to dalo použít pro více tlačítek ... a pod tím řešení někoho jiného, co sebral to druhé a přepsal ho tak, že bere i dvojklik ... a někdo potřeboval i detekovat držení, tak to řešení vylepšil, nebo přišel s novým - a k tomu souběžné téma, kde se lidi mohou dohadovat :) ..... aspoň budeme mít slušné místo kam dalšího takového poslat :D
Věčně se tu řeší problém spojování examplů - já to vidím jako důsledek toho, že lidi nechcou mít problém, chcou mít řešení. Ale řešení chci jen tehdy pokud mám problém. Ukažme jak tyto problémy vznikají a jak se řeší ... a jak to jde i vyšperkovat.

Koluje to jako vtip na netu :
Problém = Napiš funkci co veme číslo od 0 do 100 a pokud je sudé napíše ano ...
Řešení = if(a == 0 || a == 2 || a == 4 || a == 6 .... :D

Uživatelský avatar
kiRRow
Příspěvky: 710
Registrován: 07 kvě 2019, 07:03
Reputation: 0
Bydliště: Opava

Re: Challenge

Příspěvek od kiRRow » 25 lis 2021, 14:30

Děkuji za Váš zájem, za příspěvky a za to jak se to zvrhlo : Téma bylo rozděleno viewtopic.php?f=33&t=2929 koukám, že debatě kolem "toho" se v příspěvku nevyhneme, sám jsem vinen. Viděl bych to tak, že až debata skončí, vyberou se příspěvky a ty zkopírují. (Ve formátu zadání s vlastním řešením + odkaz na debatní kroužek - řešení1 - řešení2 ... uzamčeno, pokud se v debatním kroužku objeví řešení3, dodáme ho)

peterple
Příspěvky: 50
Registrován: 22 zář 2021, 20:20
Reputation: 0

Re: Challenge

Příspěvek od peterple » 03 pro 2021, 19:20

Mal by som takúto výzvu.
Naprogramuj sw obsluhu pre tri tlačítka (označené ako +, -, E), ktoré sú pripojené na Arduino. + posúva hodnotu o jedna nahor, - o jedna nadol. Hodnota sa mení v rozsahu od -128 po 127. Začína sa na nule. Tretie sa volá Enter a odošle aktuálnu hodnotu. Pretečenie netreba riešiť. O činnosti program referuje na sériovej linke takto na postupnosť uvoľnení tlačidiel +++++--E-E++

Kód: Vybrat vše

novy stav 1
novy stav 2
novy stav 3
novy stav 4
novy stav 5
novy stav 4
novy stav 3
ENTER 3
novy stav 2
ENTER 2
novy stav 3
novy stav 4
Samozrejme toto je ilustračný príklad a sw musí korektne obslúžiť akúkoľvek postupnosť stisnutí tlačidiel.

Podmienky:
  • na pin je pripojené iba tlačítko, nesmú tam byť žiadne ďalšie súčiastky.
  • výpis má nasledovať po pustení tlačidla nie pri stlačení
  • pre výpis sa musí použiť trieda Serial
  • korektné ošetrenie viacnásobného stisnutia a uvoľnenia tlačidiel (aj tri naraz)
  • zabrať čo najmenej globálnej pamäte SRAM (každý byte SRAM 20 trestných bodov)
  • zabrať čo najmenej programovej pamäte FLASH (každých (aj začatých) 20 byte FLASH sa počíta ako 1 trestný bod)
  • bonusová úloha - autorepeat pre + a - ak je stisnuté dlhšie ako 2 sekundy (-200 trestných bodov)
  • vyhráva ten kto splní úlohu a nazbiera najmenej trestných bodov.
Pre zvýšenie napínavosti by som doporučoval, aby sa kódy posielali moderátorovi, nie do vlákna. Kódy by sa zverejnili po uplynutí nejakého predom dohodnutého času. Kódy vo vlákne by mohli demotivovať riešiteľov pokúsiť sa úlohu vyriešiť.
Odmena, ako na vojne - pochvala pred naštartovanou V3S-kou, alebo pred nastúpenou jednotkou.

AstroMiK
Příspěvky: 468
Registrován: 08 pro 2017, 19:05
Reputation: 0

Re: Challenge

Příspěvek od AstroMiK » 03 pro 2021, 21:02

... Mám to bez autorepeatu.
Za odmazání 200 trestných bodů se mi to nevyplatí (nebo jsem alespoň nepřišel na to, jak to udělat, abych při tom nepoužil moc paměti.).

Můžou se zveřejňovat alespoň průběžné trestné body bez kódu?
On to stejně nakonec někdo napíše v assembleru a bude vymalováno. :D

Kam teda posílat řešení?

peterple
Příspěvky: 50
Registrován: 22 zář 2021, 20:20
Reputation: 0

Re: Challenge

Příspěvek od peterple » 03 pro 2021, 21:50

Neviem. Len som to tak dedukoval na základe predošlej challange
nebo jsem alespoň nepřišel na to, jak to udělat, abych při tom nepoužil moc paměti
Preto je to challenge. Ideálne by mali stačiť dva byte globálnej SRAM lokálne premenné sa nepočítajú

No možno tie trestné body zverejniť pre svoje riešenie nie je zlý nápad.

Assembleristov som sa snažil oklieštiť podmienkou používania triedy Serial. Svoje veci ale človek cez asm prilepiť môže.
Teším sa že aspoň jeden sa na to dal. Inak bonus som zatiaľ nevyriešil ani ja. To ma napadlo až pri písaní zadania na fórum

AstroMiK
Příspěvky: 468
Registrován: 08 pro 2017, 19:05
Reputation: 0

Re: Challenge

Příspěvek od AstroMiK » 03 pro 2021, 22:29

Tak mám i ten autorepeat.
Sice by to pro skutečné použití asi nebylo úplně ideální, ale čísla se při držení tlačítka + nebo - na déle než 2 sekundy opravdu automaticky přičítají a odečítají.

Aktuálně tedy hlásím:
3713 trestných bodů

Verze bez autorepeatu měla:
3889 trestných bodů

Uživatelský avatar
kiRRow
Příspěvky: 710
Registrován: 07 kvě 2019, 07:03
Reputation: 0
Bydliště: Opava

Re: Challenge

Příspěvek od kiRRow » 04 pro 2021, 13:14

Tentokrát to nebudu přesouvat, kódy normálně sem, na začátku jsem psal, že výzva, by mělo být již samotným autorem hotové řešení. "Já to udělal takhle, kdo to udělá lépe ?" ... pravým účelem není soutěžit, ale podebatovat o tom a ukázat svá řešení, podělit se o své nápady -> v absolutně nejlepším případě kolektivně vymyslet nejlepší řešení

AstroMiK
Příspěvky: 468
Registrován: 08 pro 2017, 19:05
Reputation: 0

Re: Challenge

Příspěvek od AstroMiK » 04 pro 2021, 14:10

Takže moje řešení využívá k úsporám paměti následující konstrukce:

- Místo příkazů pinMode() používám přímo registry DDRD a PORTD.
- Místo příkazu digitalRead() používám registr PIND.
- Tři jednobajtové globální proměnné jsem uložil do univerzálních vnitřních registrů procesoru GPIOR0 až 2.
- Pro pomocné proměnné mi stačí 5 bitů, to se vejde do 1 univerzálního registru GPIOR0, takže není nutné deklarovat 5 boolean proměnných.
- Částečná úspora vznikla nahrazením přikazu Serial.println() dvojicí příkazů Serial.print() a Serial.write(10).
- K odrušení zákmitů používám obyčejné delay(50). Dvě takovéto pauzy zároveň slouží k časování odpočtu po desetině sekundy před přepnutím na autorepeater.
- Makro F() pro povinné texty snad nemá cenu rozebírat.

V mojí verzi autorepeateru je trochu blbý, že k opakování dochází v intervalu 2 sekund. Kdyby se měl ale interval opakování zkrátit, zabralo by to víc prostředků.
Takhle to je sice v praxi hůře použitelné, ale podle mě to odpovídá zadání.

Měl jsem problém v situaci, kdy byla delší dobu současně stisknuta obě tlačítka (+) a (-), takže se přešlo do režimu autorepeateru.
Při následném uvolnění tlačítek v pořadí (-) (+) se přičetla jednička. Při uvolnění tlačítek v pořadí (+) (-) se ale neodečetlo nic.
Po opravu jsem provedl trochu nesystémový zákrok, který obě varianty uvolňování tlačítek srovnal - prostě jsem tam "dolepil" jednu podmínku.
Tlačítko, které bude uvolněno poslední, teď ovlivní výsledek svým směrem o 1.


Program:

Kód: Vybrat vše

// Kompilace pro Arduino NANO:
//Projekt zabírá 2194 bytů (7%)  úložného místa pro program. Maximum je 30720 bytů.
//Globální proměnné zabírají 184 bytů (8%)  dynamické paměti, 1864 bytů zůstává pro lokální proměnné. Maximum je 2048 bytů.
//  = 3590 trestnych bodu
   

// zapojeni:
//     D2 = tlacitko PLUS  proti GND
//     D3 = tlacitko MINUS proti GND
//     D4 = tlacitko ENTER proti GND


//==================================================================================
void setup(void)
  {
    Serial.begin(9600);
                                                          
    DDRD  = 0b11100011;                                // D2, D3, D4 = INPUT
    PORTD = 0b00011100;                                // D2, D3, D4 = Pull-Upy

    // misto 3 bajtovych globalnich promennych pouzivam univerzalni GPIO registry v procesoru (uspora 60 trestnych bodu):
    GPIOR0 = 0;                                        // pomocne bity pro predchozi stav tlacitek a styl vypisu
    GPIOR1 = 0;                                        // pomocna promenna pro autorepeat (desetiny sekundy stisku tlacitka)
    GPIOR2 = 128;                                      // to, co se pricita a odecita (v zaveru se zobrazuje hodnota o 128 mensi)
  }


//==================================================================================
void loop(void)
  {

    if ((PIND & 0b00000100) == 0 )                     // D2 (PLUS) stisknuto
      {
         GPIOR0 = GPIOR0 | 0b00000100;                 // pomocny bit2 do HIGH (znacka, ze je tlacitko stisknute)
         if(GPIOR1 < 20)   GPIOR1 ++;                  // odpocet do autorepeatu
//       Serial.println("stisk D2 - plus");
      }

    if ((PIND & 0b00001000) == 0)                      // D3 (MINUS) stisknuto
      {
         GPIOR0 = GPIOR0 | 0b00001000;                 // pomocny bit3 do HIGH (znacka, ze je tlacitko stisknute)
         if(GPIOR1 < 20)   GPIOR1 ++;                  // casovani 20 x 0,1 sek. pro dlouhy stisk tlacitka
//       Serial.println("stisk D3 - minus");
      }

    if ((PIND & 0b00010000) == 0)                      // D4 (ENTER) stisknuto
      {
         GPIOR0 = GPIOR0 | 0b00010000;                 // pomocny bit4 do HIGH (znacka, ze je tlacitko stisknute)
//       Serial.println("stisk D4 - ENTER");
      }

    delay(50);                                         // odruseni zakmitu pri stisku - zaroven slouzi jako prvni polovina casovani pro autorepeater

    if ((PIND & GPIOR0 & 0b00000100) | ((PIND & 0b00001000) and GPIOR1 == 20)) // D2 uvolneno po predchozim stisku, nebo je porad stisknuto (uvolnene je druhe tlacitko D3), ale vyprsela pauza pred autorepeatem
      {
         GPIOR0 = GPIOR0 | 0b10000000;                 // bit7 = znacka pro zobrazeni napisu "novy stav"
         GPIOR0 = GPIOR0 & 0b11111011;                 // pomocny bit2 do LOW  (tlacitko uvolneno)        
         GPIOR2 ++;                                    // pricteni hodnoty (pro typ promenne byte neni nutne resit preteceni - vzdycky bude mezi 0 a 255)

         //-------                                     // NESYSTEMOVY BASTL:
         if (GPIOR1 == 20 and (PIND & 0b00000100))     // Pri autorepeatu byl problem s obema stisknutymi tlacitky zaroven.
           {                                           // Pri uvolnenovani tlacitek v autorepeatu v poradi MINUS -> PLUS se pricetla +1, pri uvolnovani v opacnem poradi se ale neodecetlo nic.
             GPIOR2 --;                                // Timto se chyba odstrani.
           }
         //-------
         
         GPIOR1 = 0;                                   // po kazde zmene cisla se pauza pred autorepeatem nuluje, proto je dalsi opakovani az za 2 sekundy
//       Serial.println("uvolneni D2 - plus");
      }

    if ((PIND & GPIOR0 & 0b00001000) | ((PIND & 0b00000100) and GPIOR1 == 20)) // D3 uvolneno po predchozim stisku, nebo je porad stisknuto (uvolnene je druhe tlacitko D2), ale vyprsela pauza pred autorepeatem
      {
         GPIOR0 = GPIOR0 | 0b10000000;                 // bit7 = znacka pro zobrazeni napisu "novy stav"
         GPIOR0 = GPIOR0 & 0b11110111;                 // pomocny bit3 do LOW (tlacitko uvolneno)
         GPIOR2 --;                                    // odecteni hodnoty
         GPIOR1 = 0;                                   // po kazde zmene cisla se pauza pred autorepeatem nuluje, proto je dalsi opakovani az za 2 sekundy
//       Serial.println("uvolneni D3 - minus");
      }

    if (PIND & GPIOR0 & 0b00010000)                    // D4 uvolneno po predchozim stisku
      {
         GPIOR0 = GPIOR0 | 0b01000000;                 // bit6 = znacka pro zobrazeni napisu "ENTER"
         GPIOR0 = GPIOR0 & 0b11101111;                 // pomocny bit4 do LOW (tlacitko uvolneno)
//       Serial.println("uvolneni D4 - enter");
      }

    delay(50);                                         // odruseni zakmitu pri uvolneni - zaroven slouzi jako druha polovina casovani pro autorepeater

    if (GPIOR0 & 0b11000000)                           // zobrazuje se jen v pripade, ze je nastaveny nektery ze zobrazovacich bitu 6 nebo 7
      {
        if (GPIOR0 & 0b10000000)                       // pri nastavenem bitu 7 se zobrazuje text "novy stav"
          {
            Serial.print(F("novy stav "));
          }
        else                                           // pri nastavenem bitu 6 se zobrazuje text "ENTER"
          {
            Serial.print(F("ENTER "));
          }
    
        Serial.print(GPIOR2 - 128);                    // bajt prevedeny na rozsah -128 az +127
        Serial.write(10);                              // jenom <LF>, protoze println() si vezme o par bajtu vic (ve FLASH i RAM)
        GPIOR0 = GPIOR0 & 0b00111111;                  // smazani zobrazovacich bitu, aby se nezobrazovalo v kazde smycce      
      }
  }

//==================================================================================

Odpovědět

Kdo je online

Uživatelé prohlížející si toto fórum: Žádní registrovaní uživatelé a 3 hosti