[10] Concurs - Sume defecte

[10] Concurs - Sume defecte

Postby eni4ever » 22 Jun 2011, 02:19

"tl;dr" fans beware: upon reading this post, a 1.5 grams loss in saliva fluids is guaranteed!


Sume defecte [Să-nvățăm când concurăm]

Prolog:
VeveritaCuPedale, un utilizator stimat de altfel de la noi din comunitate, s-a gândit el într-o zi că ar fi tare dacă ar înțelege cum funcționează adunarea într-un procesor. Destinul sau poate chiar bookmark-ul pus pe bitcell i-a adus parte din răspuns chiar aici pe forum.
Parcurgând explicațiile, Veve este supărat : tabelul nu este complet! "Cum este influențată suma unui bit în funcție de restul operației de adunare din rangurile precedente ?" Se întrebă el.
Fiind o fire conștiincioasă și perseverentă, Veve reușește să-și completeze singur tabelul :
Image
Coloanele colorate în albastru reprezintă intrări pentru celula de adunare, iar coloanele colorate în verde - ieșiri.
Pentru a înțelege mai bine celula, Veve s-a apucat să îi dea și o formă care să îmbrace logica și a ajuns la această desen frumos :
Image
Partea frumoasă, așa cum a considerat-o și activistul nostru mic, a fost reușita lui de a sintetiza, pe cât l-a dus căpușorul, cele 2 funcții care modelează comportamentul celulei de adunare :
  • Rezultatul operațiunii de adunare:
  • Restul adunării :
[S-a notat cu - negarea unui termen. Spre exemplu este 1 dacă și numai dacă a = 0 și este 0 dacă a = 1, etc.]

Pe baza acestor funcții și folosind o serie de porți logice, Veve a reușit să creeze circuistica unei astfel de celule sumator :
Pentru calculul bitului de sumă , schema electrică rezultată a fost :
Image
Pentru calculul bitului de rest care se va propaga la următorul rang, schema electrică a fost :
Image

Încapsulând cele 2 circuite în diagrama condensată prezentată sub tabel și multiplicând celula, Veve a reușit într-un final să creeze un sumator pe 16 biți. Modul în care a interconectat cele 16 celule a fost, după cum se observă, în serie :
Image

La testarea sumatorului însă, buba! : stimatul nostru colocatar a observat că ceva nu funcționează așa cum ar trebui. Îi dăm o mână de ajutor să descopere ce anume ?

Descrierea problemei:
Tot ce speculează Veve este că, datorită porților logice vechi recuperate dintr-un calculator ponosit, sigur o poartă este defectă și, în consecință, scoate aceeași valoare logică indiferent de valorile prezente la intrările sale, stricând astfel rezultatul final. Problema este că Veve nu știe nici în care celulă se află poarta buclucașă și nici ce afectează ea (suma sau restul). El are doar niște date de analiză rezultate în urma testării unor valori prin sumator și observând rezultatul.

Ajutați-l pe Veve să descopere poarta buclucașă și demonstrați că ați găsit-o printr-o aplicație care preia 2 numere de maxim 16 biți dintr-un fișier și, în urma procesării, scrie rezultatul obținut de Veve în alt fișier.

Date de analiză:
X = 5; Y = 13 => suma_veve(X, Y) = 50
X = 47; Y = 67 => suma_veve(X, Y) = 114 (fiind mereu setat, uneori suma este corectă)
X = 925; Y = 379 => suma_veve(X, Y) = 1336
X = 30439; Y = 17583 => suma_veve(X, Y) = 48054
X = 49151; Y = 55159 => suma_veve(X, Y) = 38774 (trunchere de rezultat la primii 16 biți)

Date de intrare:
Fișierul "bitcell10.in" conține, separate printr-un spațiu, cele 2 numere naturale X și Y de maxim 16 biți cu semnificația de mai sus.

Date de ieșire:
În "bitcell10.out" : Un singur număr, rezultatul sumatorului lui Veve aplicat pe X și Y-ul citit mai sus. Datorită limitărilor fizice, în caz de situație de overflow ( suma_veve(X, Y) nu încap pe 16 biți), rezultatul se va trunchea la cei mai puțini semnificativi 16 biți!

Exemplu:
"bitcell10.in" : 17 4
"bitcell10.out" : 53

Bonus:
Numerele din fișierul de intrare sunt scrise în baza 10, dar frecvent ... în circuistică, se lucrează pentru claritate, direct cu baza 2. Pentru a interpreta corect baza-non-zecimală a unui număr se folosesc, de regulă, prefixe. Astfel, binar-ul are prefixul "0b". În această idee, ca și bonus, construiți aplicația să poată citi numerele din fișierul de intrare atât în baza implicit 10 cât și în baza 2 (condiționat de prezența prefixului, desigur).

Exemplu bonus:
"bitcell10.in" : 0b1101 12
este totuna cu
"bitcell10.in" : 13 12
deoarece 13 = 1101 (în baza 2)
sau
"bitcell10.in" : 0b0001010 0b100001
este totuna cu
"bitcell10.in" : 10 33

Vă mulțumesc pentru atenție,
Game on!

P.S: Pentru alte date de analiză/nedumeriri, vă rog folosiți forumul.

Perioada de desfășurare:
22-30 Iunie - înscrierea în concurs
1 Iulie - desemnarea câștigătorului
0,0p / 0 votes
Image

"Rațiunea vine în umbre scurte numite suferințe." Victor Adăscăliței
"Bender: Anything less than immortality is a complete waste of time.
Zoidberg: Then suicide it is! Step into my office ..." Futurama S06E06
User avatar
eni4ever
DWord
 
Joined: 03 Jan 2010
Location: Timișoara
Status: 57.83

Re: [10] Concurs - Sume defecte

Postby Mihai » 22 Jun 2011, 04:44

Interesantă problemă, soluția mea o găsiți în atașament.


Dacă vreți să participați, vă rog să-i trimiteți surse lui eni4ever pentru că, din moment ce m-am înscris și eu, n-ar fi prea corect să aleg tot eu câștigătorul :).
3p / 1 votes
Attachments
mihai_C10_bitcell.zip
(6.76 KiB) Downloaded 27 times
User avatar
Mihai
Byte
 
Joined: 29 Dec 2009
Status: 25

Re: [10] Concurs - Sume defecte

Postby DarkByte » 23 Jun 2011, 18:55

E interesanta, intr-adevar ... dar daca-mi pot permite o critica: enuntul e MULT prea lung.

Either way, programul meu e in atasament.
1p / 1 votes
Attachments
bitcell_10.zip
(10.61 KiB) Downloaded 18 times
User avatar
DarkByte
11011011
 
Joined: 29 Dec 2009
Status: 140

Re: [10] Concurs - Sume defecte

Postby eni4ever » 26 Jun 2011, 23:26

up! că nu este greu, ce dracu? ...

Spor (?!?)
0,0p / 0 votes
Image

"Rațiunea vine în umbre scurte numite suferințe." Victor Adăscăliței
"Bender: Anything less than immortality is a complete waste of time.
Zoidberg: Then suicide it is! Step into my office ..." Futurama S06E06
User avatar
eni4ever
DWord
 
Joined: 03 Jan 2010
Location: Timișoara
Status: 57.83

Re: [10] Concurs - Sume defecte

Postby smith » 27 Jun 2011, 14:05

^Aș participa și eu Victore, dar mă stresează bacu' :(
0,0p / 0 votes
Ilea Cristian
User avatar
smith
Enum
 
Joined: 29 Dec 2009
Location: Cluj-Napoca
Status: 82

Re: [10] Concurs - Sume defecte

Postby eni4ever » 01 Jul 2011, 23:59

^ Hai hai, nu mai este bac <-> nu mai este motiv să nu participați! Puteți coda în liniște, zic eu ...

Voi aștepta (cu folos, sper) până în ultimul moment înainte să închei concursul (undeva pe la 11:59) și să desemnez un câștigător.

Spor


L.E. (-- 01 Jul 2011, 22:59 --)

Oh well ... se pare că numai 2 participanți avem.

Amândouă soluții :
DarkByte:
  1. program bitcell_10;
  2.  
  3. {$APPTYPE CONSOLE}
  4.  
  5. // SysUtils - begin
  6. function ExtractFilePath(const FileName: string): string;
  7. var
  8.   i: Integer;
  9. begin
  10.   for i := Length(FileName) downto 1 do
  11.     if (FileName[i] = '')
  12.       then Break;
  13.  
  14.   Result := Copy(FileName, 1, I);
  15. end;
  16.  
  17. function Trim(const S: string): string;
  18. var
  19.   I, L: Integer;
  20. begin
  21.   L := Length(S);
  22.   I := 1;
  23.   while (I <= L) and (S[I] <= ' ') do
  24.     Inc(I);
  25.  
  26.   if (I > L)
  27.     then Result := ''
  28.     else
  29.       begin
  30.         while S[L] <= ' ' do Dec(L);
  31.         Result := Copy(S, I, L - I + 1);
  32.       end;
  33. end;
  34.  
  35. function StrToIntDef(const S: string; Default: Integer): Integer;
  36. var
  37.   E: Integer;
  38. begin
  39.   Val(S, Result, E);
  40.   if E <> 0 then Result := Default;
  41. end;
  42. // SysUtils - end
  43.  
  44. function BinToDec(aBinaryValue: String): Integer;
  45. var
  46.   lIndex: Integer;
  47. begin
  48.   Result := 0;
  49.  
  50.   for lIndex := 1 to Length(aBinaryValue) do
  51.     if (aBinaryValue[lIndex] = '1')
  52.       then Break;
  53.   if (lIndex > 0)
  54.     then aBinaryValue := Copy(aBinaryValue, lIndex, Length(aBinaryValue));
  55.  
  56.   for lIndex := Length(aBinaryValue) downto 1 do
  57.    if (aBinaryValue[lIndex] = '1')
  58.      then Result := Result + (1 shl (Length(aBinaryValue) - lIndex));
  59. end;
  60.  
  61. function GetNumber(aString: String): Word;
  62. begin
  63.   aString := Trim(aString);
  64.  
  65.   if (Pos('b', aString) > 0) or ((Pos('B', aString) > 0))
  66.     then Result := BinToDec(aString)
  67.     else Result := StrToIntDef(aString, 0);
  68. end;
  69.  
  70. procedure GetNumbers(aInputLine: String; var a, b: Word);
  71. var
  72.   lIndex: Integer;
  73.   lFoundDigit: Boolean;
  74. begin
  75.   lFoundDigit := False;
  76.   for lIndex := 1 to Length(aInputLine) do
  77.     begin
  78.       if (aInputLine[lIndex] in ['0' .. '9', 'b', 'B'])
  79.         then lFoundDigit := True
  80.         else
  81.           if lFoundDigit
  82.             then Break;
  83.     end;
  84.  
  85.   a := GetNumber(Copy(aInputLine, 1, lIndex - 1));
  86.   b := GetNumber(Copy(aInputLine, lIndex + 1, Length(aInputLine)));
  87. end;
  88.  
  89. function WrongSum(a, b: Word): Word;
  90. begin
  91.   Result := 32 or (a + b);
  92. end;
  93.  
  94. const
  95.   InputFile = 'bitcell10.in';
  96.   OutputFile = 'bitcell10.out';
  97.  
  98. var
  99.   AppPath, lInput, lTemp: String;
  100.   fInput, fOutput: TextFile;
  101.   a, b: Word;
  102.  
  103. begin
  104.   AppPath := ExtractFilePath(ParamStr(0));
  105.   AssignFile(fInput, AppPath + InputFile);
  106.   Reset(fInput);
  107.  
  108.   lInput := '';
  109.   while not EoF(fInput) do
  110.     begin
  111.       ReadLn(fInput, lTemp);
  112.       lInput := lInput + ' ' + lTemp;
  113.     end;
  114.   CloseFile(fInput);
  115.  
  116.   GetNumbers(lInput, a, b);
  117.  
  118.   AssignFile(fOutput, AppPath + OutputFile);
  119.   Rewrite(fOutput);
  120.   Write(fOutput, WrongSum(a, b));
  121.   CloseFile(fOutput);
  122. end.

Mihai:
  1. #include <cstdio>
  2. #include <cstring>
  3. #include <cstdlib>
  4.  
  5. //citim un numar in baza 2 sau 10 si returnam echivalentul in baza 10
  6. //presupune ca numerele din baza 2 au un singur 0 in prefix - deci 00b10 nu este valid, pe cand 0b10 este
  7. int citire()
  8. {
  9.     char sNumar[19];
  10.     scanf("%s",&sNumar);
  11.     if(strlen(sNumar)>=3&&sNumar[1]=='b')
  12.         return strtol(sNumar+2,NULL,2);
  13.     else
  14.         return strtol(sNumar,NULL,10);
  15. }
  16.  
  17. int main()
  18. {
  19.     int x,y;
  20.  
  21.     //vrem sa citim si sa afisam in fisier
  22.     freopen("bitcell10.in","r",stdin);
  23.     freopen("bitcell10.out","w",stdout);
  24.  
  25.     //citim cele doua valori
  26.     x=citire();
  27.     y=citire();
  28.  
  29.     //rezolvarea propriu-zisa
  30.     printf("%d\n",(x+y|0x20)&0xffff);
  31.    
  32.     //happy end :)
  33.     return 0;
  34. }


s-au descurcat foarte bine pe testele supuse :
Teste wrote:0 0
1 0
0b01 0
0b10 0b01
0b100 1
0b1111111111111111 0
0b1111111111111111 65535


Sincere felicitări amândurora! Întradevăr, bitul 5 din sumă era cel buclucaș rămânând tot timpul setat pe 1.
Totuși, nu poate existadecât un singur câștigător și acela este ... param-pam-pam
Offtopic
Ceea ce a făcut departajarea a fost LOC-ul codului sugerat precum și eleganța de care a dat dovadă în implementare. Simplu și eficient aș zice!

Concursul s-a încheiat, vă mulțumesc pentru participare și (mai ales) pentru răbdare. Mihai, ai cuvântul cu următorul challenge :) .
0,0p / 0 votes
Image

"Rațiunea vine în umbre scurte numite suferințe." Victor Adăscăliței
"Bender: Anything less than immortality is a complete waste of time.
Zoidberg: Then suicide it is! Step into my office ..." Futurama S06E06
User avatar
eni4ever
DWord
 
Joined: 03 Jan 2010
Location: Timișoara
Status: 57.83


Return to Concursuri de programare desktop

Who is online

Users browsing this forum: No registered users and 0 guests

cron