Сейчас на форуме: asfa, _MBK_ (+6 невидимых)

 eXeL@B —› Вопросы новичков —› Обратить функцию.
Посл.ответ Сообщение

Ранг: 38.3 (посетитель)
Активность: 0.020
Статус: Участник

Создано: 14 января 2010 22:57 · Поправил: 4t
· Личное сообщение · #1

Всем привет, с прошедшими и будущими праздниками! Тут такое дело , в одной проге попалась жизненно важная функция, без которой ну никак. Уж очень она нужна. Но загвоздка стала в том, что чет ее обратить не получается. Вроде простенькая, и кода немного требует, ан не дается. Сначала думал решил задачку, при значении индексов 123456 или 654321, получался исходный массив. Но поигравшись с параметра понял, что косячу. Сейчас так наигрался с реверсом этой функции, что код даже при 123456 хрень полнейшую выдает. В общем запарился. Что я имею:

Значит параметры функции следующие:
на входе:
1.) - массив из 7 байт // например (a0, a1, a2, a3, a4, a5, a6)
2.) - 6 значное число. // где цифры этого чила - индексы перестановки, допустимые значения цифр которых: 0-6, цифры уникальны в пределах данного числа, например 123456
на выходе:
1.) тот же самый массив, но с другим расположением элементов // (a6, a0, a1, a2, a3, a4, a5)

Можно заметить, что количество индексов не соответствует размеру массива ).
В этом думаю и загвоздка. В позицию отсутствующего индекса в массиве, в данном примере - 0, вставляется шестой элемент исходного массива.

Вот мое творение, всё это дело реализующее, рипнуто под pascal,
для вычислений использую Algebrus, весит 2мб, код можно в него вставить и будет работать:
Code:
  1. program SortArrayAvers;
  2. var
  3.          imput             :array [0..6] of byte = ($a0,$a1,$a2,$a3,$a4,$a5,$a6); // <- сортируемый массив, пример
  4.          SortParametrs    :integer = 123456; // <- индексы, пример
  5.          output,check     :array [0..6] of byte;
  6.          SortIndex               :array [0..5] of byte;
  7.          i                   :integer;
  8.          s                   :string;
  9. begin
  10. // заполняем значения индексов перестановки
  11. for i:= 0 to 5 do
  12.   begin
  13.     SortIndex[5-i]:= SortParametrs mod 10;
  14.     SortParametrs:= SortParametrs div 10;
  15.   end;
  16.  
  17. // перестановка массива
  18. for i:= 0 to 5 do
  19.   begin
  20.     output[SortIndex[i]]:= imput[i];
  21.     check[SortIndex[i]]:= 1; // метка, что сюда уже записывали
  22.   end;
  23.  
  24. // в какую ячейку не записывали? < - imput[6]
  25. for i:= 0 to 6 do if check[i] = 0 then  output[i]:= imput[6];
  26.  
  27. // печатаем
  28. for i:= 0 to 6 do s:= s + Hex(imput[i]) + ' ';
  29. write(s, ' < - imput'); // сортируемый массив
  30. s:='';
  31.  
  32. for i:= 0 to 5 do s:= s + Hex(SortIndex[i]) + ' ';
  33. write(s, ' < - параметры сортировки'); // параметры сортировки
  34. s:='';
  35.  
  36. write ('результат =');
  37.  
  38. for i:= 0 to 6 do s:= s + Hex(output[i]) + ' ';
  39. write(s,' < - output'); // отсортированный массив
  40. s:='';
  41.  
  42. for i:= 0 to 6 do s:= s + Hex(check[i]) + ' ';
  43. write(s); // метки
  44. end.



Задача.
Имея индексы и изменненый массив, надо получить оригинальный массив.
Пример:
($a0,$a1,$a2,$a3,$a4,$a5,$a6) < - оригинальный

230456
a2, a6, a0, a1, a3, a4 ,a5

634021
a3, a5, a4, a1, a2, a6, a0




Ранг: 673.3 (! !), 400thx
Активность: 0.40.31
Статус: Участник
CyberMonk

Создано: 15 января 2010 16:23 · Поправил: mak
· Личное сообщение · #2

судя по описанию задача сводится к инверсии или инвертированию массива байт , с учетом заполнености , подобного кода в инете и описания очень много по запросу инвертирование массива.

4t пишет:
Задача. Имея индексы и изменненый массив, надо получить оригинальный массив.


Скорее всего ты имеешь ввиду индексную сортировку или индексную инверсию , по этому запросу можно поискать в нете примеры

-----
RE In Progress [!] Coding Hazard [!] Stay Clear of this Cube




Ранг: 38.3 (посетитель)
Активность: 0.020
Статус: Участник

Создано: 15 января 2010 20:20
· Личное сообщение · #3

mak
Ну да, аверс функции - получается индексная сортировка. За исключением отсутствия одного индекса.
Отсортировать то не проблема. Проблема получить из тех же самых индексов и отсортированного массива - исходный массив. По крайней мере у меня пока не получается.
Пробую на бумажке, для одних параметров нахожу алго, меняю индексы, и всё - алго не катит.
Поискал в инете, там куча про сортировку, и индексную тоже, про то как обратить не написано. Собственно искал по теме ещё до того, как задать вопрос здесь.

Пока в аверсе имею следующее, далее дело не идёт.
условие выполняется всегда:
исходный_м[6]:= отсортированный_м[отсутствующий_индекс]
Мож кто-нить попробует осилить, кода то немного. Если надо, выложу оригинальный asm листинг этой функции.




Ранг: 673.3 (! !), 400thx
Активность: 0.40.31
Статус: Участник
CyberMonk

Создано: 15 января 2010 21:34
· Личное сообщение · #4

4t пишет:
выложу оригинальный asm листинг этой функции

=) сразу надобыло , выкладывай конечно , про индексную сортировку я посмотрю у себя , у меня был материал

-----
RE In Progress [!] Coding Hazard [!] Stay Clear of this Cube




Ранг: 38.3 (посетитель)
Активность: 0.020
Статус: Участник

Создано: 15 января 2010 23:49
· Личное сообщение · #5

Усё, осилил, оказалось не так уж и сложно. Получилось примерно так:
Code:
  1. program SortArrayRevers;
  2. var
  3. imput :array [0..6] of byte = ($a6,$a5,$a4,$a3,$a2,$a1,$a0);// <- сортируемый массив, пример
  4. SortParametrs :integer = 654321; // <- индексы, пример
  5. output,check,InvIndex  :array [0..6] of byte;
  6. SortIndex :array [0..5] of byte;
  7. :integer;
  8. :string;
  9. begin
  10. // заполняем значения индексов перестановки
  11. for i:= 0 to 5 do
  12.   begin
  13.     SortIndex[5-i]:= SortParametrs mod 10;
  14.     SortParametrs:= SortParametrs div 10;
  15.   end;
  16.  
  17. //инверсия индексов
  18. for i:= 0 to  5 do
  19.   begin
  20.     InvIndex[SortIndex[i]]:= i;
  21.   end;
  22.  
  23. // поиск отсутствующего индекса
  24. for i:= 0 to 5 do check[SortIndex[i]]:= 1; // метка, что индекс присутствует
  25. for i:= 0 to 6 do if check[i] = 0 then InvIndex[i]:= 6; // запись отсутствующего индекса
  26.  
  27. // сортировка массива
  28. for i:= 0 to 6 do
  29.   begin
  30.     output[InvIndex[i]]:= imput[i];
  31.   end;
  32.  
  33. // для отладки
  34. // печатаем
  35. for i:= 0 to 6 do s:= s + Hex(imput[i]) + ' ';
  36. write(s, ' < - imput'); // сортируемый массив
  37. s:=' ';
  38.  
  39. for i:= 0 to 5 do s:= s + Hex(SortIndex[i]) + ' ';
  40. write(s, ' < - параметры сортировки'); // параметры сортировки
  41. s:='';
  42.  
  43. write ('результат =');
  44.  
  45. for i:= 0 to 6 do s:= s + Hex(output[i]) + ' ';
  46. write(s,' < - output'); // массив
  47. s:='';
  48.  
  49. for i:= 0 to 6 do s:= s + Hex(check[i]) + ' ';
  50. write(s); // метки
  51. s:='';
  52.  
  53. for i:= 0 to 6 do s:= s + Hex(InvIndex[i]) + ' ';
  54. write(s);
  55.  
  56. end.




Ранг: 38.3 (посетитель)
Активность: 0.020
Статус: Участник

Создано: 15 января 2010 23:54
· Личное сообщение · #6

mak
вот листинг
Code:
  1. sub_1001A190      proc near
  2.  
  3. Check_Array_4     = dword      ptr -14h
  4. Check_Array_3     = dword      ptr -10h
  5. Output_Array_2    = dword     ptr -0Ch
  6. Output_Array_1    = dword     ptr -8
  7. local_0   = dword  ptr -4
  8.  
  9.                  sub    esp, 14h
  10.                  mov    eax, dword_1005C5FC
  11.                  xor    eax, esp
  12.                  mov    [esp+14h+local_0], eax
  13.                  push   ebx
  14.                  xor    ebx, ebx
  15.                  push   esi
  16.                  mov    esi, ecx
  17.                  mov    byte ptr [esp+1Ch+Check_Array_4], bl
  18.                  mov    byte ptr [esp+1Ch+Check_Array_4+1], bl
  19.                  mov    byte ptr [esp+1Ch+Check_Array_4+2], bl
  20.                  mov    byte ptr [esp+1Ch+Check_Array_4+3], bl
  21.                  mov    byte ptr [esp+1Ch+Check_Array_3], bl
  22.                  mov    byte ptr [esp+1Ch+Check_Array_3+1], bl
  23.                  mov    byte ptr [esp+1Ch+Check_Array_3+2], bl
  24.                  xor    ecx, ecx
  25.  
  26. loc_1001A1C2:
  27.                  mov    eax, ecx
  28.                  and    eax, 80000001h
  29.                  jns    short loc_1001A1D0
  30.                  dec    eax
  31.                  or     eax, 0FFFFFFFEh
  32.                  inc    eax
  33.  
  34. loc_1001A1D0:
  35.                  mov    eax, ecx
  36.                  cdq
  37.                  jnz    short loc_1001A1E3
  38.                  sub    eax, edx
  39.                  sar    eax, 1
  40.                  movzx  eax, byte ptr [eax+esi+7]     ; < ESI указывает на сортируемый массив; ESI + 7 на индексы
  41.                  shr    eax, 4
  42.                  jmp    short loc_1001A1EF
  43. ; ---------------------------------------------------------------------- -----
  44.  
  45. loc_1001A1E3:
  46.                  sub    eax, edx
  47.                  sar    eax, 1
  48.                  movzx  eax, byte ptr [eax+esi+7]
  49.                  and    eax, 0Fh
  50.  
  51. loc_1001A1EF:
  52.                  cmp    eax, 6
  53.                  jg     short loc_1001A24B
  54.                  cmp    byte ptr [esp+eax+1Ch+Check_Array_4], bl
  55.                  jnz    short loc_1001A24B
  56.                  mov    dl, [esi + ecx]
  57.                  inc    ecx
  58.                  cmp    ecx, 6
  59.                  mov    byte ptr [esp+eax+1Ch+Check_Array_4], 1
  60.                  mov    byte ptr [esp+eax+1Ch+Output_Array_2], dl
  61.                  jl     short loc_1001A1C2
  62.                  xor    eax, eax
  63.                  cmp    byte ptr [esp+1Ch+Check_Array_4], bl
  64.                  jz     short loc_1001A21B
  65.  
  66. loc_1001A214:
  67.                  inc    eax
  68.                  cmp    byte ptr [esp+eax+1Ch+Check_Array_4], bl
  69.                  jnz    short loc_1001A214
  70.  
  71. loc_1001A21B:
  72.                  movzx  ecx, byte ptr [esi+6]
  73.                  mov    byte ptr [esp+eax+1Ch+Output_Array_2], cl
  74.                  mov    edx, [esp+1Ch+Output_Array_2]
  75.                  movzx  ecx, byte ptr [esp+1Ch+Output_Array_1+2]
  76.                  mov    ax, word ptr [esp+1Ch+Output_Array_1]
  77.                  mov    [esi], edx
  78.                  mov    [esi+4], ax
  79.                  mov    [esi+6], cl
  80.                  pop    esi
  81.                  pop    ebx
  82.                  mov    ecx, [esp+14h+local_0]
  83.                  xor    ecx, esp
  84.                  call   sub_1002F990
  85.                  add    esp, 14h
  86.                  retn
  87. ; ---------------------------------------------------------------------- -----
  88.  
  89. loc_1001A24B:
  90.                  mov    ecx, [esp+1Ch+local_0] ; // проверку не прошли
  91.                  mov    byte ptr [esi+24h], 1
  92.                  pop    esi
  93.                  pop    ebx
  94.                  xor    ecx, esp
  95.                  call   sub_1002F990
  96.                  add    esp, 14h
  97.                  retn
  98. sub_1001A190       endp


Но теперь появилась другая проблема - генерация этих самих индексов.
То бишь нужно сгенерировать шестизначное число из не повторяющихся цифр. Причем рандомно.
Есть предложения?



Ранг: 19.9 (новичок)
Активность: 0.020
Статус: Участник

Создано: 16 января 2010 02:43 · Поправил: Neo32
· Личное сообщение · #7

В цикле от 1 до 6 получи случайный индекс и если в массиве по этому индексу 0 то пиши туда если Нет получай новый случайный индекс или как вариант используй уже забитый массив и получай случайный индекс(количество перестановок равно факториалу 6)




Ранг: 673.3 (! !), 400thx
Активность: 0.40.31
Статус: Участник
CyberMonk

Создано: 16 января 2010 15:07 · Поправил: mak
· Личное сообщение · #8

Рандомный генератор , по одному числу , со сканом строки на имеющиеся символы ..можно на асме уложится в строчек 15

пс. выше тоже тему говорят , но смотря что имено ты генишь =) ..какое число

-----
RE In Progress [!] Coding Hazard [!] Stay Clear of this Cube




Ранг: 19.9 (новичок)
Активность: 0.020
Статус: Участник

Создано: 16 января 2010 18:07 · Поправил: Neo32
· Личное сообщение · #9

mak сорри за неточность )), вот код демонстрирующий указанный в посте №7 алгоритм
Code:
  1. // for unix fpc compiler =)))))
  2. program myrandom;
  3. var
  4.          a1:array [1..6] of byte;
  5.          i,n:byte;
  6. begin
  7.          randomize;
  8.          for i:=1 to 6 do
  9.                  a1[i]:=0;
  10.          for i:=1 to 6 do
  11.          begin
  12.                  repeat
  13.                         n:=random(6)+1;
  14.                  until a1[n]=0;
  15.                  a1[n]:=i;
  16.          end;
  17.          for i:=1 to 6 do
  18.                  write(a1[i]);
  19.          readln;
  20. end.




Ранг: 38.3 (посетитель)
Активность: 0.020
Статус: Участник

Создано: 16 января 2010 20:58
· Личное сообщение · #10

mak пишет:
но смотря что имено ты генишь =) ..какое число

6 знаков, от 0 до 6, в первом посте написано ).

Neo32
Код работает, ток нолик не генерит )...

mak, Neo32 спасиб за ответы.

Решения найдены. За сим тему закрываю.


 eXeL@B —› Вопросы новичков —› Обратить функцию.
Эта тема закрыта. Ответы больше не принимаются.
   Для печати Для печати