[تمرين] : عمل محاكاة للدالة rgb - SMP3 - 28-04-2013
السلام عليكم و رحمة الله و بركاته
المطلوب : عمل دالة MakeRGB تعمل نفس عمل الدالة RGB
+ عمل محاكاة للدوال التالية GetRValue,GetGValue,GetBValue
PHP كود : function MakeRGB(r, g, b: Byte): COLORREF; function GetBValueX(RGB:Cardinal):Byte; function GetGValueX(RGB:Cardinal):Byte; function GetRValueX(RGB:Cardinal):Byte;
الشروط :
- يمنع استخدام دوال جاهزة
- يمنع استخدام التعليمات التالية : XOR , OR,SHL,SHR,ROR,ROL
-يمكنك ان أحببت أن تستخدم الأسمبلي بشرط مراعاة الشرطين السابقين
المدة : أسبوع قابل للتمديد (على حسب الحلول)
[COLOR="Red"]انتهت مدة التمرين
[/COLOR]------------------------------------------------
عدد الأعضاء الذين استطاعوا حل التحدي اثنين فقط (كنت أتوقع الكثير ) :
[COLOR="red"]- B.M.AbdelAziZ
- ALmuhhnad[/COLOR]
حلول الأخ B.M.AbdelAziZ :
PHP كود : { By B.M.AbdelAziZ } function MakeRGB(r, g, b: Byte): COLORREF; begin result:=b*$10000+g*$100+r; end; function GetBValueX(RGB:Cardinal):Byte; begin result:= RGB div $10000; end; function GetGValueX(RGB:Cardinal):Byte; begin result:= RGB div $100; end; function GetRValueX(RGB:Cardinal):Byte; begin result:= RGB div 1; end; {-------------------------------------------------------------------------} type TCoulor = record case Integer of 0:(color: Dword); 1:(r,g,b,nop: byte); end; Var Coulor : TCoulor; function MakeRGB2(r, g, b: Byte): COLORREF; begin Coulor.r:=r; Coulor.g:=g; Coulor.b:=b; result:=Coulor.color; end; function GetBValueX2(RGB:Cardinal):Byte; begin result:=Coulor.b; end; function GetGValueX2(RGB:Cardinal):Byte; begin result:=Coulor.g; end; function GetRValueX2(RGB:Cardinal):Byte; begin result:=Coulor.r; end;
حلول الأخ ALmuhhnad :
PHP كود : { By ALmuhhnad } function MakeRGB(R,G,B : Byte):Cardinal ; begin Result := B * $10000; asm MOV EAX,0 MOV EAX,Result MOV AH,G MOV AL,R MOV Result,EAX end; end;
function GetRValue_T(RGB : Cardinal):Byte ; begin asm MOV EAX,RGB MOV Result,AL end; end;
function GetGValue_T(RGB : Cardinal):Byte ; begin asm MOV EAX,RGB MOV Result,AH end; end;
function GetBValue_T(RGB : Cardinal):Byte ; begin Result := RGB div $10000; end; {-------------------------------------------------------------------------} function MakeRGB2(R,G,B : Byte):Cardinal ; begin asm MOV EAX,0 MOV AL,B MOV ECX,$10000 MUL EAX,ECX MOV AL,G MOV CX,$100 MUL AX,CX MOV AL,R MOV Result,EAX end; end; function GetRValueX(RGB : Cardinal):Byte; asm MOV BYTE PTR DS:[Result],AL end;
function GetGValueX(RGB : Cardinal):Byte; asm MOV BYTE PTR DS:[Result],AH end;
function GetBValueX(RGB : Cardinal):Byte; asm PUSH EAX MOV CL,BYTE PTR DS:[ESP+2] POP EAX MOV AL,CL end; function MakeRGB3(R,G,B : Byte):Cardinal; asm MOV BYTE PTR DS:[Result],AL MOV BYTE PTR DS:[Result+1],DL MOV BYTE PTR DS:[Result+2],CL end; function GetBValueX2(RGB : Cardinal):Byte; asm SAR EAX,$10 end;
حلول صاحب التحدي SMP3 :
PHP كود : { By SMP3 } function GetRValueX(RGB:Cardinal):Byte; var RGBB:PByte; begin RGBB:= @RGB ; Result:=RGBB^; end;
function GetGValueX(RGB:Cardinal):Byte; var RGBB:PByte; begin RGBB:= @RGB ; Inc(RGBB); Result:=RGBB^; end;
function GetBValueX(RGB:Cardinal):Byte; var RGBB:PByte; begin RGBB:= @RGB ; Inc(RGBB,2); Result:=RGBB^; end;
function MakeRGB(R, G, B: Byte): COLORREF; begin Result := ((B * $10000) + (G * $100) - (B * $10000) and (G * $100)) ; Result := Result + R - ( Result and R); end;
{-------------------------------------------------------------------------------------}
type TRGB = record R:Byte; G:Byte; B:Byte; end; PRGB= ^TRGB ;
function GetRValueX2(RGB:Cardinal):Byte; var RGBStruc:PRGB; begin RGBStruc:=@RGB; Result:=RGBStruc.R; end;
function GetGValueX2(RGB:Cardinal):Byte; var RGBStruc:PRGB; begin RGBStruc:=@RGB; Result:=RGBStruc.G; end;
function GetBValueX2(RGB:Cardinal):Byte; var RGBStruc:PRGB; begin RGBStruc:=@RGB; Result:=RGBStruc.B; end;
function MakeRGB2(R,G,B:Byte):COLORREF; var RGBStruc:TRGB; RGB:PInteger; P:PByte; begin RGBStruc.R:=R; RGBStruc.G:=G; RGBStruc.B:=B; P:=@RGBStruc.B; Inc(P); P^:=$00; RGB:=@RGBStruc.R; Result:=RGB^; end;
{-------------------------------------------------------------------------------------} {$IFNDEF PUREPASCAL}
function GetRValueX3(RGB:Cardinal):Byte; asm {$IFDEF CPUX64} MOV AL,CL {$ENDIF} end;
function GetGValueX3(RGB:Cardinal):Byte; asm {$IFDEF CPUX64} MOV AL,CH {$ELSE !CPUX64} MOV AL,AH {$ENDIF !CPUX64} end;
function GetBValueX3(RGB:Cardinal):Byte; asm {$IFDEF CPUX64} BSWAP ECX MOV AL,CH {$ELSE !CPUX64} BSWAP EAX MOV AL,AH {$ENDIF !CPUX64} end;
function MakeRGB3(R,G,B:Byte): COLORREF; asm {$IFDEF CPUX64} MOV AL,CL MOV AH,DL BSWAP EAX MOV AL,R8B XOR AL,AL //MOV AH,00 XCHG AL,AH BSWAP EAX {$ELSE !CPUX64} MOV AH,DL BSWAP EAX MOV AH,CL XOR AL,AL //MOV AL,00 BSWAP EAX {$ENDIF !CPUX64} end;
{-------------------------------------------------------------------------------------}
function GetRValueX4(RGB:Cardinal):Byte;{$IFDEF CPUX86}pascal;{$ENDIF} asm {$IFDEF CPUX86} MOV AL,[EBP+$8] {$ELSE !CPUX86} PUSH RCX POP RCX MOV AL,[RSP-$8] {$ENDIF !CPUX86} end; function GetGValueX4(RGB:Cardinal):Byte;{$IFDEF CPUX86}pascal;{$ENDIF} asm {$IFDEF CPUX86} MOV AL,[EBP+$9] {$ELSE !CPUX86} PUSH RCX POP RCX MOV AL,[RSP-$7] {$ENDIF !CPUX86} end; function GetBValueX4(RGB:Cardinal):Byte;{$IFDEF CPUX86}pascal;{$ENDIF} asm {$IFDEF CPUX86} MOV AL,[EBP+$A] {$ELSE !CPUX86} PUSH RCX POP RCX MOV AL,[RSP-$6] {$ENDIF !CPUX86} end;
(*function MakeRGB4(R,G,B:Byte):COLORREF; asm {$IFDEF CPUX64} MOV [EBP+$8],CL MOV [EBP+$9],DL MOV [EBP+$A],R8B MOV [EBP+$B],$00 MOV EAX,[EBP+$8] {$ELSE !CPUX64} MOV [EBP-$4],AL MOV [EBP-$3],DL MOV [EBP-$2],CL MOV [EBP-$1],$00 MOV EAX,[EBP-$4] {$ENDIF !CPUX64} end;*)
function MakeRGB4(R,G,B:Byte):COLORREF; asm {$IFDEF CPUX86} MOV BYTE [Result+$0],AL MOV BYTE [Result+$1],CL MOV BYTE [Result+$2],DL {$ELSE} MOV BYTE [Result+$0],CL MOV BYTE [Result+$1],DL MOV BYTE [Result+$2],R8B {$ENDIF} MOV BYTE [Result+$3],$00 end;
{-------------------------------------------------------------------------------------}
function GetRValueX5(RGB:Cardinal):Byte; asm {$IFDEF CPUX86} PUSH EAX POP EAX MOV AL,BYTE PTR DS:[ESP-$4] {$ELSE !CPUX86} PUSH RCX POP RCX MOV AL,[RSP-$8] {$ENDIF !CPUX86} end; function GetGValueX5(RGB:Cardinal):Byte; asm {$IFDEF CPUX86} PUSH EAX POP EAX MOV AL,BYTE PTR DS:[ESP-$3] {$ELSE !CPUX86} PUSH RCX POP RCX MOV AL,[RSP-$7] {$ENDIF !CPUX86} end; function GetBValueX5(RGB:Cardinal):Byte; asm {$IFDEF CPUX86} PUSH EAX POP EAX MOV AL,BYTE PTR DS:[ESP-$2] {$ELSE !CPUX86} PUSH RCX POP RCX MOV AL,[RSP-$6] {$ENDIF !CPUX86} end;
{-------------------------------------------------------------------------------------}
function SwapX(X:Cardinal):Cardinal ; asm {$IFNDEF CPUX86} MOV EAX,ECX {$ENDIF} BSWAP EAX end;
function GetRValueX6(RGB:Cardinal):Byte; begin Result:=Byte(RGB); end;
function GetGValueX6(RGB:Cardinal):Byte; begin Result:=Byte(SwapX(WORD(RGB)*$10000)); end;
function GetBValueX6(RGB:Cardinal):Byte; begin Result:=Byte(SwapX(RGB*$100)); //Result:=Byte(SwapX((RGB-WORD(RGB))*$100)); end; {$ENDIF !PUREPASCAL}
هدية للأخ virtual :
PHP كود : A Or B = (A+B) - (A And B)
[تمرين] : عمل محاكاة للدالة rgb - محمد عبد العزيز - 29-04-2013
وعليكم السلام ورحمة الله
حل سريع باستخدام IntToHex/StrToInt/Copy دون دعم لليونيكود
كود : function MakeRGB(r, g, b: Byte): COLORREF;
begin
result:=StrToInt('$00'+IntToHex(b,2)+IntToHex(g,2)+IntToHex(r,2));
end;
function GetBValueX(RGB:Cardinal):Byte;
begin
result:=StrToInt('$'+copy(IntToHex(RGB,8),3,2) );
end;
function GetGValueX(RGB:Cardinal):Byte;
begin
result:=StrToInt('$'+copy(IntToHex(RGB,8),5,2) );
end;
function GetRValueX(RGB:Cardinal):Byte;
begin
result:=StrToInt('$'+copy(IntToHex(RGB,8),7,2) );
end;
[تمرين] : عمل محاكاة للدالة rgb - SMP3 - 29-04-2013
b.m.abdelaziz كتب :وعليكم السلام ورحمة الله
حل سريع باستخدام inttohex/strtoint/copy دون دعم لليونيكود
[color="purple"]و عليكم السلام
حل سليم و صحيح لكنك خالفت الشرط الأول !!![/color]
إقتباس :- يمنع استخدام دوال جاهزة
+ ليس هناك داعي لدعم اليونيكود في مثل هذه الحالات ..
[تمرين] : عمل محاكاة للدالة rgb - virtual - 29-04-2013
هل انت متأكد من عدم استخدام or ؟
الناتج للدالة MakeRGB على ما اعتقد سيكون
كود : result := ( b shl 16) or (g shl 8 ) or r ;
بدون shl ستكون
كود : result := (b * 65536) or (g * 256) or r;
الا اذا كان هناك emulation لل or بواسطة ال and ؟؟
[تمرين] : عمل محاكاة للدالة rgb - SMP3 - 30-04-2013
virtual كتب :الا اذا كان هناك emulation لل or بواسطة ال and ؟؟
نعم يمكن كتابتها بدون استخدام التعليمة or و بدون emulation
ملاحظة : حول تعليمة shl
كود : b:= a shl 1 shl 1 shl 1 shl 1 shl 1 shl 1 shl 1 shl 1; // a shl 8 .
b:= a *2*2*2*2*2*2*2*2;// a shl 8 .
b:= a * 256 ;// a shl 8 .
[تمرين] : عمل محاكاة للدالة rgb - SMP3 - 30-04-2013
على فكرة أخي virtual : يمكن عمل emulation للتعليمة or باستخدام ثلاث تعليمات مختلفة !!
-------------------------------
سأتركك تحاول معها
[تمرين] : عمل محاكاة للدالة rgb - virtual - 30-04-2013
يبدو انها تعليمة واحدة فقط !
كود : function MakeRGB(r,g,b : byte):COLORREF;
begin
result := (b * $ffff) + (g * $ff) + r;
end;
a or b = a + b
a and b= a * b
[تمرين] : عمل محاكاة للدالة rgb - SMP3 - 30-04-2013
إقتباس :a or b = a + b
a and b= a * b
a or b = a + b => غير صحيح ..
ما رأيك ب :
كود : 80 or 82 = 82 <> 80 + 82
نفس الأمر للتعليمة and ..
حاول مرة أخرى ...
[تمرين] : عمل محاكاة للدالة rgb - محمد عبد العزيز - 30-04-2013
إقتباس :حل سليم و صحيح لكنك خالفت الشرط الأول !!!
لم انتبه للشرط الاول بسبب السرعة...هذا حل أخر بوقت اقل من السابق!
كود : function MakeRGB(r, g, b: Byte): COLORREF;
begin
result:=b*$10000+g*$100+r;
end;
function GetBValueX(RGB:Cardinal):Byte;
begin
result:= RGB div $10000;
end;
function GetGValueX(RGB:Cardinal):Byte;
begin
result:= RGB div $100;
end;
function GetRValueX(RGB:Cardinal):Byte;
begin
result:= RGB div 1;
end;
[تمرين] : عمل محاكاة للدالة rgb - virtual - 30-04-2013
عفوا لم انتبه . جو العمل المتعب لم يترك لي مجال للتفكير
a or b = a + b صحيح لكن على مستوى البت الواحد 1 و 0
يبدو ان اجابة الاستاذ B.M.AbdelAziZ هي الصحيحة
|