www.mikrocontroller.net

Forum: Compiler & IDEs kleine denksportaufgabe in c formulieren


Autor: Werner (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo zusammen, hoffe irgendwer hat eine Idee hierzu.

Empfangen werden ein ReihenByte sowie n SpaltenBytes. Die Anzahl der 
SpaltenBytes ist abhängig von der Anzahl der gesetzten BITs im 
ReihenByte.

Beispiel 1: ReihenByte = 0x01, SpaltenByte = 0x0A. Anhand der gegebenen 
Matrix sollte nun der Wert 4 und 2 zurückgegeben werden.

Beispiel 2: ReihenByte = 0x0A, erstes SpaltenByte = 0x0A... liefert das 
Ergebnis 28 und 26. Nun kommt ein 2tes SpaltenByte 0x0B... liefert die 
Treffer 12, 10, 9.

Es können also mehrere Treffer in einer Reihe sein. Im Beispiel 2 wird 
beim 2ten Durchlauf aus 0x0A = 0x02. Mit anderen Worten, im ersten 
Durchlauf ist 0x0A = 0x08. Die Reihe wird also BITwise abgetastet.

Ich suche also nach einem Algorythmus, welcher die Werte anhand der 
Tabelle zurückgibt.

Hoffe es kommt irgendwie rüber was gemeint ist, bekomme es nicht gelöst.


               SpaltenByte
BIT:      7  6  5  4  3  2  1  0
           ___________________
      7|  64 63 62 61 60 59 58 57
      6|  56 55 54 53 52 51 50 49
      5|  48 47 46 45 44 43 42 41
      4|  40 39 38 37 36 35 34 33
Reihe 3|  32 31 30 29 28 27 26 25
      2|  24 23 22 21 20 19 18 17
      1|  16 15 14 13 12 11 10  9
      0|   8  7  6  5  4  3  2  1

Autor: lkmiller (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
So vielleicht:
#include <stdio.h>

int main(int argc, char* argv[])
{

   int z,s;     // Werte 0x00..0xff
   int r[64];   // max. 64 Ergebnisse
   int idx;     

   z = 0xff;
   s = 0x55;


   idx = 0;
   for(int mz=7; mz>=0; mz-=1) { 
      if(z&(1<<mz)) {
         for(int ms=7; ms>=0; ms-=1) {
            if(s&(1<<ms)) 
               r[idx++]=mz*8+ms+1;
         }
      }
   }


   printf("%d Ergebnis%s:\n", idx, idx==1?" ":"se");
   for(int a=0; a<idx; a++)
      printf("Ergebnis %d = %d\n", a, r[a]);
   getchar();
}

Autor: Werner (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke für die schnelle Antwort, ich fürchte das meine C Kenntnisse hier 
nicht ausreichen. Ich verwende den SDCC, läßt sich das Ganze als 
einzelne Funktion bauen wie z.B.

void decode (uint8_t RowByte, uint8_t ColumnByte)  {

  Algorythmus;
  display_Ausgabe (Treffer);

}

Der Code von Dir ist arg... jedenfalls für mich (Anfänger). Kannst Du 
mir den ein bischen erläutern ?

Mein Code sieht derzeit so aus... hat aber einen Schönheitsfehler 
(funktioniert noch nicht ganz.

void decode (uint8_t RowByte, uint8_t ColumnByte)  {
uint8_t base = 57, crosspoint, i; 
  for (i=0; i < 8; i++)  {              
    if (RowByte & 0x80)  {
      crosspoint = base; 
      while (ColumnByte >>= 1) crosspoint++;  
      int_dsp (crosspoint);       
    }
    base -= 8;                  
    RowByte <<= 1;
  }
}

Autor: lkmiller (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Oder so:
#include <stdio.h>

int main(int argc, char* argv[])
{
   int z,s;     // Werte 0x00..0xff
   int r[64];   // max. 64 Ergebnisse
   int idx;     // Zeiger auf 1.Ergebnis

   z = 0xff;
   s = 0x55;
   idx = 0;
    
   for(int m=0; m<64; m++) 
      if( z&(1<<((m&0x38)>>3)) && s&(1<<(m&3)) ) 
         r[idx++]=m+1;

   printf("%d Ergebnis%s\n", idx, idx==1?" ":"se");
   for(int a=0; a<idx; a++)
      printf("Ergebnis %d = %d\n", a, r[a]);
   getchar();
}

Aaaaaah, streck, räkel, C ist eben eine schöne Sprache.

Autor: Werner (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
int main(int argc, char* argv[])

Ich versteh das nicht, wie sieht das in einer funktion aus ?, wie 
gesagt, nicht GCC, SDCC.

for(int m=0; m<64; m++)

Selbst sowas geht nicht... gut, m kann ich mir auch vorher anlegen.

Nicht böse sein aber ich kapiers mit deiner Syntax nicht.

Autor: lkmiller (Gast)
Datum:
Angehängte Dateien:
  • preview image for dz.gif
    dz.gif
    8,98 KB, 106 Downloads

Bewertung
0 lesenswert
nicht lesenswert
Die Berechnung erfolgt jeweils nur in den Schleifen.
Das
   z = 0xff; // Zeilenbitmuster
   s = 0x55; // Spaltenbitmuster
dient nur zur Eingabe der Spalten und Reihen.

1. Idee
Die Zeilen werden in der äusseren Schleife druchlaufen,
Wenn das entsprechende Bit gesetzt ist werden die Spalten in der inneren 
Schleife abgeklappert.
Wenn dann ein Bit gesetzt ist, wird der Wert berechnet und in ein Feld 
eingetragen.
   idx = 0;
   for(int mz=7; mz>=0; mz-=1) { 
      if(z&(1<<mz)) {
         for(int ms=7; ms>=0; ms-=1) {
            if(s&(1<<ms)) 
               r[idx++]=mz*8+ms+1;
         }
      }
   }


2. Idee
Ein Zähler läuft alle Felder durch.
Jedesmal wird geschaut, ob das entsprechende Bit gesetzt ist.
Falls ja: Eintrag ins Feld.
   for(int m=0; m<64; m++) 
      if( z&(1<<((m&0x38)>>3)) && s&(1<<(m&3)) ) 
         r[idx++]=m+1;



>Mein Code sieht derzeit so aus... hat aber einen Schönheitsfehler
>(funktioniert noch nicht ganz.
Glaub ich dir.
:
  Algorythmus;   // Aufruf ohne Parameter???
:
void decode (uint8_t RowByte, uint8_t ColumnByte)  // Initialwerte????
{
  uint8_t base = 57, crosspoint, i; // 57????

  for (i=0; i < 8; i++)  {              
    if (RowByte & 0x80)  {
      crosspoint = base; 
      while (ColumnByte >>= 1) crosspoint++;  // ColumnByte sollte mal wieder auf 0x80 gesetzt werden????
      int_dsp (crosspoint);       
    }
    base -= 8;                  
    RowByte <<= 1;     // wird in die falsch Richtung geschoben???
  }
}

Ich habe das mit einem C++ Compiler (Visual-C) getestet,
der kann die Inline-Deklaration.
Sonst eben wie gehabt: vorher deklarieren.


Und das Ganze ist doch ein Dreizeiler,
da brauchts doch keine extra Funktion ;-)
Wenn doch, dann:
#include <stdio.h>

int evaluate(int *res, int z, int s) 
{
   int idx=0;
   for(int m=0; m<64; m++) 
      if( z&(1<<((m&0x38)>>3)) && s&(1<<(m&3)) ) 
         res[idx++]=m+1;

   return idx;
}

void ausgabe(int *res, int idx) 
{
   printf("%d Ergebnis%s\n", idx, idx==1?" ":"se");
   for(int a=0; a<idx; a++)
      printf("Ergebnis %d = %d\n", a, res[a]);
}


int main()
{
   int r[64];   // max. 64 Ergebnisse
   int idx;

   idx = evaluate(r,0x0a,0x0a);
   ausgabe(r,idx);

   getchar();
}

Autor: Werner (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Vielleicht nochmal zu meiner Lösung... die ist ok aber Danke für deine 
Hinweise.

Wenn mein ReihenByte nur ein BIT enthält passt es schon. Ich müßte eine 
Schleife drumherum bauen die folgendes macht.

Beispiel: ReihenByte = 0x0A = 00001010... es müßte also 00001000 und 
dann 00000001 übergeben werden... dann stimmt es.

Die 57 kommt hierher... ist der Basis Wert.

7|  64 63 62 61 60 59 58 57

Mein Problem... ne Schleife in der Schleife :-)

Danke Dir für deine Lösung, vielleicht kannst du Dir meine nochmal 
ansehen (für mich zum Verstehen).

Autor: yalu (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Werner:
Ist das ein Zufall, oder heißt du mit zweitem Vornamen Bernd?

  Beitrag "reines C Problem und Denkblockade"

Da wurde das Problem anscheinend schon gelöst.

Autor: Werner (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
nein, ich heiße wie ich heiße und das funktioniert nicht, ist aber 
derselbe Decoder.

Autor: yalu (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Der Unterschied zwischen meinem damals geposteten Code und deinem:

Meine Routine von damals hat die Reihen- und Spaltenbytes von einer
Schnittstelle gelesen, erst ein Reihenbyte und dann in einer Schleife
eine der Anzahl der 1-Bits entsprechende Anzahl von Spaltenbytes.

Du übergibst 1 Reihenbyte als Funktionsargument, was ok ist. Du
übergibst weiterhin 1 Spaltenbyte, aber wo sollen die restlichen
Spaltenbytes herkommen, wenn mehrere erwartet werden?

Autor: Werner (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Kopiere es nochmal von oben:

Die Anzahl der SpaltenBytes ist abhängig von der Anzahl der gesetzten 
BITs im ReihenByte. Die habe ich bereits im RAM liegen. Somit muß ich 
die Funktion eben beliebig oft aufrufen.

Beispiel 1: ReihenByte = 0x01, SpaltenByte = 0x0A. Anhand der gegebenen
Matrix sollte nun der Wert 4 und 2 zurückgegeben werden.

Beispiel 2: ReihenByte = 0x0A, erstes SpaltenByte = 0x0A... liefert das
Ergebnis 28 und 26. Nun kommt ein 2tes SpaltenByte 0x0B... liefert die
Treffer 12, 10, 9.

Es können also mehrere Treffer in einer Reihe sein. Im Beispiel 2 wird
beim 2ten Durchlauf aus 0x0A = 0x02. Mit anderen Worten, im ersten
Durchlauf ist 0x0A = 0x08. Die Reihe wird also BITwise abgetastet.

Autor: icke (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Mich würde mal interessieren, wo dies Problem einegsetzt wird.
Hat das irgendwie eine praktische Anwendung? Wenn ja würde mich ein Link 
auf die Projektseite total reizen. Wenns einen gibt, bitte her damit, 
scheint spannend zu sein und ich wüsste jetzt wirklich gerne was man so 
macht.

Alternativ, wenns schnell gehen muss, würde ich noch einen lookup table 
ins rennen schmeißen, wo man für jedes gesetzte bit als y die Werte 
rausholt. Entsprechend der y-bits kann man ja Analog zu letztem Jahr die 
Xse versuchen zu empfangen.

Ich befürchte aber fast, daß das irgendwie ne rein akademische Aufgabe 
ist, weil yalu ja schon mal das gleiche Ding voriges Jahr bearbeitet 
hatte.

Autor: Simon K. (simon) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Es heißt Algorithmus.

Autor: Werner (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Vielen Dank, hab es hinbekommen.

Autor: yalu (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@icke:

> Mich würde mal interessieren, wo dies Problem einegsetzt wird. Hat
> das irgendwie eine praktische Anwendung?

Zitat aus dem Thread vor einem Jahr von dem dortigen Hilfesuchenden:

> Das Ganze ist ein ziemlich schräges Protokoll aus einem japanischen
> Gehirn. Ich denke ich werde noch ein paar "Nüsse" knacken müssen.
>
> http://bssc.sel.sony.com/Professional/docs/brochur...

Autor: lkmiller (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Ich hatte die Beschreibung nicht ganz kapiert, aber jetzt hab ich's:
(Ausgabe siehe Bild)
#include <stdio.h>

void ausgabe(int *res, int idx) 
{
   printf("%d Ergebnis%s\n", idx, idx==1?" ":"se");
   for(int a=0; a<idx; a++)
      printf("Ergebnis %d = %d\n", a, res[a]);
}


int main(int argc, char* argv[])
{
   int r[64];  // max. 64 Ergebnisse
   int idx;
   int s, ms, mz;

   // wenn alle 8 bits im Zeilenwert gesetzt sind, müssen 8 Spaltenwerte herhalten
   int sb[8] = {0xA,0xB,0,0,0,0,0,0 }; // Beispielwerte
   int z     = 0x0A;  // Beispielwert 

   s=0;
   idx=0;
   for(mz=7; mz>=0; mz-=1) {
      if(z&(1<<mz)) {
         for(ms=7; ms>=0; ms-=1) {
            if(sb[s]&(1<<ms)) 
               r[idx++]=mz*8+ms+1;
         }
         s++;
      }
   }

   ausgabe(r,idx);
}

Autor: lkmiller (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Schade :-(
Wieder nur Zweiter.
Werner hats vor mir schon hinbekommen.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.