Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- Program NamesAddition;
- uses sysutils;
- const
- BASE = 9; {система счислення}
- N = 255;
- ALLOW_LEADING_ZEROS = false; {чи дозволяються нулі на початку слова}
- var
- a,b,c : string;
- cnt_uniq : integer;
- cnt_solutions : longint;
- symbol_exist : array[0..N] of boolean;
- val, pt : array[0..N] of integer;
- {Встановлення верхнього регістру для літер імені `s` та
- відмітки про те, значення яких літер треба перебирати}
- function PrepareName(s : string) : string;
- var i : integer;
- begin
- s := UpperCase(s);
- for i := 1 to length(s) do
- symbol_exist[ord(s[i])] := true;
- exit(s);
- end;
- {Знаходження значення імені `s` з наявної комбінації літери-цифри}
- function GetVal(s : string) : longint;
- var i, res : longint;
- begin
- res := 0;
- for i := 1 to length(s) do
- res := res * base + val[pt[ord(s[i])]];
- GetVal := res;
- end;
- {Підстановка замість цифр у імені `s` значень замість літер}
- function GetStr(s : string) : string;
- var i,x : integer;
- res : string;
- begin
- res := '';
- for i := 1 to length(s) do begin
- x := val[pt[ord(s[i])]];
- if x < 10 then
- res := res + chr(x+48)
- else
- res := res + chr(x-10+97);
- end;
- exit(res);
- end;
- {Виведення знайденої комбінація літер-цифер}
- procedure Print();
- var i : integer;
- begin
- cnt_solutions := cnt_solutions + 1;
- WriteLn();
- for i := 1 to N do if symbol_exist[i] then Write(chr(i)); WriteLn();
- for i := 1 to N do if symbol_exist[i] then Write(val[pt[i]]); WriteLn();
- WriteLn(GetStr(a), ' + ', GetStr(b), ' = ', GetStr(c), ' [', base, '-base]');
- if base <> 10 then
- WriteLn(GetVal(a), ' + ', GetVal(b), ' = ', GetVal(c), ' [10-base]');
- end;
- {Перевірка, що знайдена комбінація літери-цифри задовольняє умові}
- function Check() : boolean;
- begin
- if not ALLOW_LEADING_ZEROS then
- begin
- if (length(a) > 1) and (val[pt[ord(a[1])]] = 0) then exit(false);
- if (length(b) > 1) and (val[pt[ord(b[1])]] = 0) then exit(false);
- if (length(c) > 1) and (val[pt[ord(c[1])]] = 0) then exit(false);
- end;
- exit(GetVal(a)+GetVal(b) = GetVal(c));
- end;
- {Рекурсивний перебір за O(BASE!) операцій}
- procedure RecUniq(pos : integer);
- var i,t : integer;
- begin
- if pos = 0 then
- begin
- if Check() then
- Print();
- exit();
- end;
- for i := 0 to pos do
- begin
- t := val[i]; val[i] := val[pos]; val[pos] := t;
- RecUniq(pos-1);
- t := val[i]; val[i] := val[pos]; val[pos] := t;
- end;
- end;
- {Рекурсивний перебір за O(N^BASE) операцій, де N -- кількість різних букв у іменах}
- procedure RecNotUniq(pos : integer);
- var i : integer;
- begin
- if pos = cnt_uniq then
- begin
- if Check() then
- Print();
- exit();
- end;
- for i := 0 to base-1 do
- begin
- val[pos] := i;
- RecNotUniq(pos+1);
- end;
- end;
- procedure Bruteforce();
- var i : integer;
- begin
- for i := 0 to N do
- if symbol_exist[i] then begin
- pt[i] := cnt_uniq;
- cnt_uniq := cnt_uniq + 1;
- end;
- for i := 0 to base-1 do
- val[i] := i;
- {WriteLn('Unique numbers:');}
- RecUniq(base-1);
- {WriteLn('Non-unique numbers:');
- RecNotUniq(0);}
- end;
- begin
- a := 'Anna'; b := 'Luisa'; c := 'Sussen';
- a := 'Karl'; b := 'Michel'; c := 'Kramek';
- a := PrepareName(a);
- b := PrepareName(b);
- c := PrepareName(c);
- writeln(a, ' + ', b, ' = ', c, ' [', base, '-base]');
- writeln('Run bruteforce...');
- cnt_solutions := 0;
- Bruteforce();
- WriteLn('Finished. Found ', cnt_solutions, ' solution(s)!');
- end.
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement