Forum: Compiler & IDEs kleine denksportaufgabe in c formulieren


von Werner (Gast)


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

von lkmiller (Gast)


Lesenswert?

So vielleicht:
1
#include <stdio.h>
2
3
int main(int argc, char* argv[])
4
{
5
6
   int z,s;     // Werte 0x00..0xff
7
   int r[64];   // max. 64 Ergebnisse
8
   int idx;     
9
10
   z = 0xff;
11
   s = 0x55;
12
13
14
   idx = 0;
15
   for(int mz=7; mz>=0; mz-=1) { 
16
      if(z&(1<<mz)) {
17
         for(int ms=7; ms>=0; ms-=1) {
18
            if(s&(1<<ms)) 
19
               r[idx++]=mz*8+ms+1;
20
         }
21
      }
22
   }
23
24
25
   printf("%d Ergebnis%s:\n", idx, idx==1?" ":"se");
26
   for(int a=0; a<idx; a++)
27
      printf("Ergebnis %d = %d\n", a, r[a]);
28
   getchar();
29
}

von Werner (Gast)


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.
1
void decode (uint8_t RowByte, uint8_t ColumnByte)  {
2
3
  Algorythmus;
4
  display_Ausgabe (Treffer);
5
6
}

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.
1
void decode (uint8_t RowByte, uint8_t ColumnByte)  {
2
uint8_t base = 57, crosspoint, i; 
3
  for (i=0; i < 8; i++)  {              
4
    if (RowByte & 0x80)  {
5
      crosspoint = base; 
6
      while (ColumnByte >>= 1) crosspoint++;  
7
      int_dsp (crosspoint);       
8
    }
9
    base -= 8;                  
10
    RowByte <<= 1;
11
  }
12
}

von lkmiller (Gast)


Lesenswert?

Oder so:
1
#include <stdio.h>
2
3
int main(int argc, char* argv[])
4
{
5
   int z,s;     // Werte 0x00..0xff
6
   int r[64];   // max. 64 Ergebnisse
7
   int idx;     // Zeiger auf 1.Ergebnis
8
9
   z = 0xff;
10
   s = 0x55;
11
   idx = 0;
12
    
13
   for(int m=0; m<64; m++) 
14
      if( z&(1<<((m&0x38)>>3)) && s&(1<<(m&3)) ) 
15
         r[idx++]=m+1;
16
17
   printf("%d Ergebnis%s\n", idx, idx==1?" ":"se");
18
   for(int a=0; a<idx; a++)
19
      printf("Ergebnis %d = %d\n", a, r[a]);
20
   getchar();
21
}

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

von Werner (Gast)


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.

von lkmiller (Gast)


Angehängte Dateien:

Lesenswert?

Die Berechnung erfolgt jeweils nur in den Schleifen.
Das
1
   z = 0xff; // Zeilenbitmuster
2
   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.
1
   idx = 0;
2
   for(int mz=7; mz>=0; mz-=1) { 
3
      if(z&(1<<mz)) {
4
         for(int ms=7; ms>=0; ms-=1) {
5
            if(s&(1<<ms)) 
6
               r[idx++]=mz*8+ms+1;
7
         }
8
      }
9
   }


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



>Mein Code sieht derzeit so aus... hat aber einen Schönheitsfehler
>(funktioniert noch nicht ganz.
Glaub ich dir.
1
:
2
  Algorythmus;   // Aufruf ohne Parameter???
3
:
4
void decode (uint8_t RowByte, uint8_t ColumnByte)  // Initialwerte????
5
{
6
  uint8_t base = 57, crosspoint, i; // 57????
7
8
  for (i=0; i < 8; i++)  {              
9
    if (RowByte & 0x80)  {
10
      crosspoint = base; 
11
      while (ColumnByte >>= 1) crosspoint++;  // ColumnByte sollte mal wieder auf 0x80 gesetzt werden????
12
      int_dsp (crosspoint);       
13
    }
14
    base -= 8;                  
15
    RowByte <<= 1;     // wird in die falsch Richtung geschoben???
16
  }
17
}

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:
1
#include <stdio.h>
2
3
int evaluate(int *res, int z, int s) 
4
{
5
   int idx=0;
6
   for(int m=0; m<64; m++) 
7
      if( z&(1<<((m&0x38)>>3)) && s&(1<<(m&3)) ) 
8
         res[idx++]=m+1;
9
10
   return idx;
11
}
12
13
void ausgabe(int *res, int idx) 
14
{
15
   printf("%d Ergebnis%s\n", idx, idx==1?" ":"se");
16
   for(int a=0; a<idx; a++)
17
      printf("Ergebnis %d = %d\n", a, res[a]);
18
}
19
20
21
int main()
22
{
23
   int r[64];   // max. 64 Ergebnisse
24
   int idx;
25
26
   idx = evaluate(r,0x0a,0x0a);
27
   ausgabe(r,idx);
28
29
   getchar();
30
}

von Werner (Gast)


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).

von yalu (Gast)


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.

von Werner (Gast)


Lesenswert?

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

von yalu (Gast)


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?

von Werner (Gast)


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.

von icke (Gast)


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.

von Simon K. (simon) Benutzerseite


Lesenswert?

Es heißt Algorithmus.

von Werner (Gast)


Lesenswert?

Vielen Dank, hab es hinbekommen.

von yalu (Gast)


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/brochures/mvs8000.pdf

von lkmiller (Gast)


Angehängte Dateien:

Lesenswert?

Ich hatte die Beschreibung nicht ganz kapiert, aber jetzt hab ich's:
(Ausgabe siehe Bild)
1
#include <stdio.h>
2
3
void ausgabe(int *res, int idx) 
4
{
5
   printf("%d Ergebnis%s\n", idx, idx==1?" ":"se");
6
   for(int a=0; a<idx; a++)
7
      printf("Ergebnis %d = %d\n", a, res[a]);
8
}
9
10
11
int main(int argc, char* argv[])
12
{
13
   int r[64];  // max. 64 Ergebnisse
14
   int idx;
15
   int s, ms, mz;
16
17
   // wenn alle 8 bits im Zeilenwert gesetzt sind, müssen 8 Spaltenwerte herhalten
18
   int sb[8] = {0xA,0xB,0,0,0,0,0,0 }; // Beispielwerte
19
   int z     = 0x0A;  // Beispielwert 
20
21
   s=0;
22
   idx=0;
23
   for(mz=7; mz>=0; mz-=1) {
24
      if(z&(1<<mz)) {
25
         for(ms=7; ms>=0; ms-=1) {
26
            if(sb[s]&(1<<ms)) 
27
               r[idx++]=mz*8+ms+1;
28
         }
29
         s++;
30
      }
31
   }
32
33
   ausgabe(r,idx);
34
}

von lkmiller (Gast)


Lesenswert?

Schade :-(
Wieder nur Zweiter.
Werner hats vor mir schon hinbekommen.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.