Autor |
Beitrag |
Narses
Beiträge: 10181
Erhaltene Danke: 1254
W10ent
TP3 .. D7pro .. D10.2CE
|
Verfasst: Di 25.12.12 01:09
Moin!
Die Lösung lautet:
1290880921 (hex: $4CF14799, bin: 1001100111100010100011110011001)
Viel Glück bei der Auslosung der Preise!
cu
Narses
_________________ There are 10 types of people - those who understand binary and those who don´t.
Für diesen Beitrag haben gedankt: Christian S., Mathematiker
|
|
Mathematiker
Beiträge: 2622
Erhaltene Danke: 1447
Win 7, 8.1, 10
Delphi 5, 7, 10.1
|
Verfasst: Di 25.12.12 01:14
Hallo,
nachdem ich mich bisher richtig blöd bei den Adventsrätseln angestellt hatte, kam zum Glück das vierte. Danke dafür , Ihr habt mich wieder etwas aufgebaut.
Das Rätsel war genau auf meiner Wellenlängen. 15 Minuten Programm schreiben, 1 Sekunde Programmlauf und die Lösung war da. Endlich mal richtig.
Solche Rätsel finde ich schön. Ach, wären doch alle so gewesen!
Beste Grüße und schöne Weihnachtsfeiertage
Mathematiker
_________________ Töten im Krieg ist nach meiner Auffassung um nichts besser als gewöhnlicher Mord. Albert Einstein
|
|
Tilo
Beiträge: 1098
Erhaltene Danke: 13
Win7 geg. WInXP oder sogar Win98
Rad2007
|
Verfasst: Di 25.12.12 09:38
Mathematiker hat folgendes geschrieben : |
Das Rätsel war genau auf meiner Wellenlängen. 15 Minuten Programm schreiben, 1 Sekunde Programmlauf und die Lösung war da. |
Morgen Mathematiker,
Kannst Du bitte mal die Optimierungen beim Berechnen erläutern? Meine Maschine brauchte 30 Minuten und mehr.
Lag vieleicht auch daran, dass ich von unten (Start 1) gestartet bin. Als einzige Optimierung habe ich nur dass bearbeiten der ungeraden Zahlen (binäre Pallindrome) gefunden.
Beste Grüße,
Tilo
|
|
Mathematiker
Beiträge: 2622
Erhaltene Danke: 1447
Win 7, 8.1, 10
Delphi 5, 7, 10.1
|
Verfasst: Di 25.12.12 09:46
Hallo Tilo,
Tilo hat folgendes geschrieben : | Kannst Du bitte mal die Optimierungen beim Berechnen erläutern? |
Zuerst bin ich davon ausgegangen, dass die Zahlen ungerade sein müssen. Andernfalls ist die Dualzahl kein Palindrom.
Da auch die Dezimalzahl Palindrom ist, habe ich nur solche Palindrome konstruiert und untersucht; zum einen alle Ziffernfolgen von 19999 bis 1 herumgedreht und angefügt (ergibt Zahlen mit geradzahlig vielen Ziffern) und dann noch von 9999 bis 1, allerdings mit einer in der Mitte eingefügten Ziffer (ergibt Zahlen mit ungeradzahlig vielen Ziffern).
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67: 68: 69: 70: 71: 72: 73: 74: 75: 76: 77: 78: 79: 80:
| procedure TForm1.BerechnenClick(Sender: TObject); var p,w,j,zeit:integer; u,k:string; procedure test(k:string); var z,y,i,s,rest:integer; dual,dual2:string; drei:array[0..9] of integer; hdop:array[0..16] of integer; doppelt:boolean; begin z:=strtoint(k); s:=0; for i:=1 to length(k) do s:=s+ord(k[i])-48; if (s mod 4=0) then begin y:=z; dual:=''; dual2:=''; repeat rest:=y mod 2; dual:=chr(48+rest)+dual; dual2:=dual2+chr(48+rest); y:=y div 2; until y=0;
if dual=dual2 then begin fillchar(drei,sizeof(drei),0); for i:=1 to length(k) do inc(drei[ord(k[i])-48]); doppelt:=false; i:=0; repeat if drei[i]>2 then doppelt:=true; inc(i); until doppelt or (i>9);
if not doppelt then begin fillchar(hdop,sizeof(hdop),0); y:=z; repeat rest:=y mod 16; inc(hdop[rest]); y:=y div 16; until y=0; doppelt:=false; for i:=1 to 16 do if hdop[i]>=2 then doppelt:=true; if doppelt then listbox1.items.add(inttostr(z)); end; end; end; end; begin zeit:=gettickcount; w:=19999; repeat k:=inttostr(w); if k[1] in ['2','4','6','8'] then begin k[1]:=chr(ord(k[1])-1); w:=strtoint(k); end; u:=''; for j:=1 to length(k) do u:=k[j]+u; test(k+u); dec(w); until w<1;
w:=9999; repeat k:=inttostr(w); if k[1] in ['2','4','6','8'] then begin k[1]:=chr(ord(k[1])-1); w:=strtoint(k); end; u:=''; for j:=1 to length(k) do u:=k[j]+u; for p:=0 to 9 do if pos(chr(48+p),k)=0 then test(k+inttostr(p)+u); dec(w); until w<1; listbox1.items.add('fertig'); label1.caption:=format('%d ms',[gettickcount-zeit]); end; |
Beste Grüße
Mathematiker
_________________ Töten im Krieg ist nach meiner Auffassung um nichts besser als gewöhnlicher Mord. Albert Einstein
|
|
Horst_H
Beiträge: 1652
Erhaltene Danke: 243
WIN10,PuppyLinux
FreePascal,Lazarus
|
Verfasst: Di 25.12.12 09:53
Hallo,
15 min, ach Herrje, ich werde doch dement.
Ich hatte einen Fehler in Quersumme und nicht gemerkt
Edit: Laufzeit 3 ms.
Jetzt funktioniert es
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67: 68: 69: 70: 71: 72: 73: 74: 75: 76: 77: 78: 79: 80: 81: 82: 83: 84: 85: 86: 87: 88: 89: 90: 91: 92: 93: 94: 95: 96: 97: 98: 99: 100: 101: 102: 103: 104: 105: 106: 107: 108: 109: 110: 111: 112: 113: 114: 115: 116: 117: 118: 119: 120: 121: 122: 123: 124: 125: 126: 127: 128: 129: 130: 131: 132: 133: 134: 135: 136: 137: 138: 139: 140: 141: 142: 143: 144: 145: 146: 147: 148: 149: 150: 151: 152: 153: 154: 155: 156: 157: 158: 159: 160: 161: 162: 163: 164: 165: 166: 167: 168: 169: 170: 171: 172:
| {$IFDEF DELPHI} {$AppTYPE CONSOLE} {$ELSE} {$IFDEF FPC} {$MODE Delphi} {$Smartlink On} {$OPTIMIZATION ON} {$OPTIMIZATION Regvar} {$OPTIMIZATION Peephole} {$OPTIMIZATION cse} {$OPTIMIZATION asmcse} {$ENDIF} {$ENDIF} uses sysutils; type tPalin = record palMid, palMax, palQsum : integer; palPal : DWord; palFeld : array[0..5] of integer; end;
Var gblCount : integer;
function GeneratePalin(var p:tPalin):DWord; var i,k : integer; begin with p do begin result := palFeld[0]; palQsum := result; i := 0; while i < palMid do begin inc(i); k := palFeld[i]; inc(palQsum,k); result := result*10+k; end; while i < palMax do begin inc(i); k := palFeld[PalMax-i]; inc(palQsum,k); result := result*10+k; end; end; end;
function NextPal(var p:tPalin):boolean; var i,j : integer; begin result := false; with p do begin i := palMid;
repeat j := palFeld[i]; inc(j); IF j > 9 then begin palFeld[i] := 0; dec(i); IF i < 0 then EXIT; end else begin palFeld[i] := j; break; end; until false;
palPal := GeneratePalin(p); IF paLPal < MaxLongint then result := true; end; end;
function PalinInit(max:integer):tPalin; var i : integer; begin with result do begin palMax := max-1; palMid := (max-1) div 2; for i := 0 to palMid do palFeld[i] := 0; palFeld[0] := 1; palPal := GeneratePalin(result); end; end;
function BinaerPalinTest(n: DWord):boolean; var i,j : cardinal; begin result := false; IF (n AND 1) = 0 then EXIT; j := 1;
i := 1 shl 31; while (i AND n) = 0 do i := i shr 1;
while i>j do begin IF ((n AND i) = 0) = ((n AND j) = 0) then begin i := i shr 1; inc(j,j); end else EXIT; end; result := true; end;
var p:tPalin; i : integer; n : Cardinal; Begin gblCount := 0; For i := 1 to 10 do begin p := PalinInit(i); while NextPal(p) do IF (p.palQsum AND 3) = 0 then begin n := p.palPal; IF BinaerPalinTest(n) then writeln(i:3,n:12,' ', IntToHex(n,8),' ',p.palQsum); end; end; readln; end. |
Ausgabe:
Quelltext 1: 2: 3: 4:
| 5 32223 00007DDF 12 5 53835 0000D24B 24 6 585585 0008EF71 36 10 1290880921 4CF14799 40 |
Gruß Horst
Edit:
Ich habe den Binaertest geändert, um das höchste Bit zu finden.
Mit bsrDword dauert es 2,9 ms und nun 3 ms.Mit trunc(ln(n)/ln(2) in 4,3 ms
Der Test auf doppelte Hex lohnt sich bei nur 4 Möglichkeiten zuvor nicht wirklich.
Zuletzt bearbeitet von Horst_H am Di 25.12.12 19:28, insgesamt 1-mal bearbeitet
|
|
Xion
Beiträge: 1952
Erhaltene Danke: 128
Windows XP
Delphi (2005, SmartInspect), SQL, Lua, Java (Eclipse), C++ (Visual Studio 2010, Qt Creator), Python (Blender), Prolog (SWIProlog), Haskell (ghci)
|
Verfasst: Di 25.12.12 10:18
Dann auch hier mal mein Programm
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67: 68: 69: 70: 71: 72: 73: 74: 75: 76: 77: 78: 79: 80: 81: 82: 83: 84: 85: 86: 87: 88: 89: 90: 91: 92: 93: 94: 95: 96: 97: 98: 99: 100: 101: 102: 103: 104: 105: 106: 107: 108: 109: 110: 111: 112: 113: 114: 115: 116: 117: 118: 119: 120: 121: 122: 123: 124: 125: 126: 127: 128: 129: 130: 131: 132: 133: 134: 135: 136: 137: 138: 139: 140: 141: 142: 143: 144: 145: 146: 147: 148: 149: 150: 151: 152: 153: 154: 155: 156: 157: 158: 159: 160: 161: 162: 163: 164: 165: 166: 167: 168: 169: 170: 171: 172: 173: 174: 175: 176: 177: 178: 179: 180: 181: 182: 183: 184: 185: 186: 187: 188: 189: 190: 191: 192: 193: 194: 195: 196: 197: 198: 199: 200: 201: 202: 203: 204: 205: 206: 207: 208: 209: 210: 211: 212: 213: 214: 215: 216: 217: 218: 219: 220: 221: 222: 223: 224: 225: 226: 227: 228: 229: 230: 231: 232: 233: 234: 235: 236: 237: 238: 239: 240: 241: 242: 243: 244: 245: 246: 247: 248: 249: 250: 251: 252: 253: 254: 255:
| unit Unit1;
interface
uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, Math, XVHashing;
type TIndividuum=record Bin: String; Dec: String; Hex: String; end;
type TForm1 = class(TForm) Memo1: TMemo; Button1: TButton; Button2: TButton; CBRule1: TCheckBox; CBRule2: TCheckBox; CBRule3: TCheckBox; CBRule4: TCheckBox; CBRule5: TCheckBox; CBRule6: TCheckBox; procedure Button2Click(Sender: TObject); procedure Button1Click(Sender: TObject); private function ConvertBinToDec(BinValue: String): String; function IsPalindrom(S: String): boolean; function ConvertBinToHex(BinValue: String): String; function DecDigitToHex( I: Int64): String; function FlipString(S: String): String; procedure AddSolution(Indiv: TIndividuum); function CheckIndividuum( var Indiv: TIndividuum ): boolean; function ConvertDecToBin(DecValue: String): String; function Quersumme(DecValue: String): integer; function GetMaxOccuranceCount( S: String ): integer; public Solutions: array of TIndividuum; end;
var Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject); var R: integer; Indiv: TIndividuum; S,FlipS: String; begin SetLength(Solutions, 0);
for R:= 0 to 21474 do begin S:=inttostr(R); FlipS:=FlipString(S);
Indiv.Hex:=''; Indiv.Bin:=''; Indiv.Dec:=S+FlipS; if CheckIndividuum(Indiv) then AddSolution(Indiv);
Indiv.Hex:=''; Indiv.Bin:=''; Indiv.Dec:=Copy(S,1,Length(S)-1)+FlipS; if CheckIndividuum(Indiv) then AddSolution(Indiv); end;
Memo1.Text:='Generation done'; end;
procedure TForm1.Button2Click(Sender: TObject); var P: integer; begin Memo1.Clear; for P:= 0 to High(Solutions) do Memo1.Lines.Add( Solutions[P].Dec+'^10 '+Solutions[P].Bin+'^2 '+Solutions[P].Hex+'^16'); end;
function TForm1.CheckIndividuum( var Indiv: TIndividuum ): boolean; begin Result:=True;
Indiv.Bin := ConvertDecToBin(Indiv.Dec); Result:=IsPalindrom(Indiv.Bin);
if (CBRule2.Checked) and (Result) then Result:= (Quersumme(Indiv.Dec) mod 4) = 0;
if (CBRule3.Checked) and (Result) then Result:= GetMaxOccuranceCount( Indiv.Dec )<=2;
Indiv.Hex := ConvertBinToHex(Indiv.Bin); if (CBRule4.Checked) and (Result) then Result:= GetMaxOccuranceCount( Indiv.Hex )>=2; end;
function TForm1.Quersumme(DecValue: String): integer; var A: integer; begin Result:=0; for A:= 1 to Length(DecValue) do Result:=Result+strtoint(DecValue[A]); end;
function TForm1.ConvertBinToDec(BinValue: String): String; var I: Int64; A: integer; C: integer; begin I:=0; C:=1; for A:= Length(BinValue) downto 1 do begin I:=I+strToInt(BinValue[A])*c; C:=C*2; end;
Result:=inttostr(I); end;
function TForm1.ConvertDecToBin(DecValue: String): String; var I: integer; begin Result:=''; I:=strtoint(DecValue);
while I<>0 do begin if I mod 2 =0 then Result:='0'+Result else Result:='1'+Result; I:=I div 2; end; if Result='' then Result:='0'; end;
function TForm1.DecDigitToHex( I: Int64): String; begin if I<10 then Result:=inttostr(I) else begin case I of 10: Result:='A'; 11: Result:='B'; 12: Result:='C'; 13: Result:='D'; 14: Result:='E'; 15: Result:='F'; else Result:='X'; end; end; end;
function TForm1.ConvertBinToHex(BinValue: String): String; var I: Int64; A: integer; C: integer; block: integer; begin Result:=''; I:=0; C:=1; block:=0; for A:= Length(BinValue) downto 1 do begin I:=I+strToInt(BinValue[A])*c; C:=C*2; block:=block+1; if block=4 then begin block:=0; Result:=DecDigitToHex(I)+Result; I:=0; c:=1; end; end;
if block>0 then begin block:=0; Result:=DecDigitToHex(I)+Result; I:=0; end; end;
function TForm1.IsPalindrom(S: String): boolean; var start: integer; C: integer; len: integer; begin start:=1; while (S[start]='0')and(start<=Length(S)) do start:=start+1;
len:=Length(S); Result:=true; for C:=start to len do if S[C]<>S[len-C+start] then Result:=false; end;
function TForm1.FlipString(S: String): String; var R: integer; begin Result:=''; for R:=Length(S) downto 1 do Result:=Result+S[R]; end;
procedure TForm1.AddSolution(Indiv: TIndividuum); var R: integer; begin R:=Length(Solutions); SetLength(Solutions,R+1); Solutions[R]:=Indiv; end;
function TForm1.GetMaxOccuranceCount( S: String ): integer; var HashTable: THashTable; err: String; A,OldCount: integer; begin HashTable:=THashTable.Create(101); Result:=0;
for A:= 1 to Length(S) do begin OldCount:=HashTable.Lookup(ord(S[A]),err); if err<>'' then OldCount:=0; HashTable.Insert(ord(S[A]),OldCount+1); if Result<OldCount+1 then Result:=OldCount+1; end;
HashTable.Free; end;
end. |
Einloggen, um Attachments anzusehen!
_________________ a broken heart is like a broken window - it'll never heal
In einem gut regierten Land ist Armut eine Schande, in einem schlecht regierten Reichtum. (Konfuzius)
|
|
Flamefire
Beiträge: 1207
Erhaltene Danke: 31
Win 10
Delphi 2009 Pro, C++ (Visual Studio)
|
Verfasst: Di 25.12.12 12:12
Meine Lösung war extrem naiv und ohne Optimierung bzgl der Auswahl der Zahlen. Bruteforce und durch. Hab halt nur effektive Algorithmen zum Regeltest verwendet. Also ohne Strings etc.
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52:
| bool checkQS2Mal(int i){ int ct[10]; int sum=0; int palin=0; int zahl=i; for(int j=0;j<10;j++) ct[j]=0; while(i>0){ int ziffer=i%10; if(ct[ziffer]>1) return false; ct[ziffer]++; sum+=ziffer; palin=palin*10+ziffer; i/=10; } return (sum%4==0) && (zahl==palin); }
bool checkBinPalin(int i){ int palin=0; int zahl=i; while(i>0){ palin=palin*2+i%2; i/=2; } return zahl==palin; }
bool check2Hex(int i){ bool ct[16]; for(int j=0;j<16;j++) ct[j]=false; while(i>0){ int ziffer=i%16; if(ct[ziffer]) return true; ct[ziffer]=true; i/=16; } return false; }
int main(int argc, char** argv) { for(int i=1; i<0x7FFFFFFF;i++){ if(i%8388608==0) cout << "Current: " << i << endl; if(!checkQS2Mal(i)) continue; if(!checkBinPalin(i)) continue; if(!check2Hex(i)) continue; cout << i << endl; } return 0; } |
|
|
Jann1k
Beiträge: 866
Erhaltene Danke: 43
Win 7
TurboDelphi, Visual Studio 2010
|
Verfasst: Di 25.12.12 12:49
Ich hatte mich zuerst extremst verrannt, weil die inttohex Funktion führende Nullen erzeugt. Als ich das mit fixen Werten getestet hatte, war dem aber nicht so. Hatte etwas gedauert bis ich den Fehlern entdeckt habe, da er von mir schon ausgeschlossen wurde.
|
|
Troubadix
Beiträge: 28
Erhaltene Danke: 9
WIN 7
C# (VS2010 Express)
|
Verfasst: Di 25.12.12 13:32
Hallo,
mein kleines Programm braucht 24 Minuten um die Lösung zu finden. Hab mich halt nicht lange mit optimierungen aufgehalten sondern bin ganz naiv an die Sache ran gegangen.
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57:
| static void Main(string[] args) { DateTime startTime = DateTime.Now; for (Int64 i = 1; i <= 2147483647; i+=2) { if (getQuersumme(i) % 4 == 0 && isPalindrom(i, 2) && isPalindrom(i, 10) && checkRepeats(i, 10) < 3 && checkRepeats(i, 16) == 2) { Console.WriteLine(i); Console.WriteLine((DateTime.Now - startTime).TotalSeconds.ToString()); break; } } Console.ReadLine(); }
static bool isPalindrom(Int64 number, Int32 numberBase) { char[] sNumber = Convert.ToString(number, numberBase).ToArray(); char[] sReverse = sNumber.Reverse().ToArray(); for (Int32 i = 0; i < sNumber.Count(); i++) if (sNumber[i] != sReverse[i]) return false; return true; }
static Int64 getQuersumme(Int64 number) { string sNumber = Convert.ToString(number, 10); Int64 quersumme = 0; for (Int32 i = 0; i < sNumber.Length; i++) { quersumme += Convert.ToInt64(sNumber[i].ToString()); } return quersumme; }
static Int32 checkRepeats(Int64 number, Int32 numberBase) { Int32 repeats = 0; string sNumber = Convert.ToString(number, numberBase); Int32[] numberCounts = new Int32[numberBase]; for (Int32 i = 0; i < sNumber.Length; i++) { numberCounts[Convert.ToInt32(sNumber[i].ToString(), numberBase)]++; } for (Int32 i = 0; i < numberBase; i++) if (numberCounts[i] > repeats) repeats = numberCounts[i];
return repeats; } |
Gruß
Troubadix
|
|
jfheins
Beiträge: 918
Erhaltene Danke: 158
Win 10
VS 2013, VS2015
|
Verfasst: Di 25.12.12 22:41
Ich habe mir gedacht, dass ich erstmal überhaupt nur binäre Palindrome generiere. Dadurch fällt nämlich schonmal eine ganze Menge weg.
Leider hat das Entwickeln und testen der Funktion lange gedauert, aber die Berechnung flupt in unter einer Sekunde durch.
Man braucht dann nämlich nur noch 15 bits variieren, die andere Hälfte ergibt sich ja aus der Palindrombedingung.
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37:
| static void Main(string[] args) { for (int length = 3; length <= 32; length++) { int limit = 1 << ((length - 1) / 2);
for (int i = 0; i < limit; i++) { var zahl = genPalindrome(i, length - 1);
if (isDecPalin(zahl) && Quersummme(zahl)) { System.Console.Write(zahl); System.Console.Write('\t'); System.Console.Write(zahl.ToString("X")); System.Console.Write('\t'); System.Console.WriteLine(Convert.ToString(zahl, 2)); } } }
System.Console.WriteLine("Fertig gerechnet :-)"); System.Console.ReadLine(); }
static int genPalindrome(int value, int len) { value = (value << 1) | 1; int low = value & 0xFF; int high = (value >> 8) & 0xFF; int reverse = (BitReverseTable256[low] << 8) | BitReverseTable256[high]; if (len <= 15) return value | (reverse >> (15 - len)); else return value | (reverse << (len - 15)); } |
|
|
|