Автор Тема: Очень простой цикл  (Прочитано 56060 раз)

ilovb

  • Hero Member
  • *****
  • Сообщений: 2538
  • just another nazi test
    • Просмотр профиля
    • Oberon systems
Re: Очень простой цикл
« Ответ #30 : Май 29, 2012, 11:33:06 am »
Переменная СледующийИндекс конечно не нужна если компилер оптимизирующий

albobin

  • Full Member
  • ***
  • Сообщений: 198
    • Просмотр профиля
Re: Очень простой цикл
« Ответ #31 : Май 29, 2012, 12:27:13 pm »
для разнообразия :)  однострочная функция на мампсе

00(x)  new p   set p=$find(x,$char(0,0))   set:p p=p-2   quit p

возвращает номер позиции (отсчёт с 1)  первого из двух подряд нулевых байтов  в входной строке x  или 0, если таковых нет

ilovb

  • Hero Member
  • *****
  • Сообщений: 2538
  • just another nazi test
    • Просмотр профиля
    • Oberon systems
Re: Очень простой цикл
« Ответ #32 : Май 29, 2012, 12:38:49 pm »
А что значит "00(x)"?  :)

Я так понимаю это библиотечный поиск паттерна в массиве как в строке?

Geniepro

  • Hero Member
  • *****
  • Сообщений: 1955
  • Знайте- истина в том, что повторено трижды подряд!
    • Просмотр профиля
Re: Очень простой цикл
« Ответ #33 : Май 29, 2012, 12:49:51 pm »
для разнообразия :)  однострочная функция на мампсе

00(x)  new p   set p=$find(x,$char(0,0))   set:p p=p-2   quit p

возвращает номер позиции (отсчёт с 1)  первого из двух подряд нулевых байтов  в входной строке x  или 0, если таковых нет
не ну ежели на то пошло, то я тоже могу передлать свой вариант в однострочник:

find_zeroes (y:ys) = find y ys 0 where find 0 (0:_) n = n; find _ (z:zs) n = find z zs (n+1)

Только понятность резко упала, имхо... )))
to iterate is human, to recurse, divine

Салат «рекурсия»: помидоры, огурцы, салат…

albobin

  • Full Member
  • ***
  • Сообщений: 198
    • Просмотр профиля
Re: Очень простой цикл
« Ответ #34 : Май 29, 2012, 12:57:05 pm »
А что значит "00(x)"?  :)

Я так понимаю это библиотечный поиск паттерна в массиве как в строке?
00 - это я такое имя дал функции.
это просто поиск в строке ( в мампсе строки могут содержать любые байты от 0 до 255)
Боюсь, что многое в мампсе будет вызывать вопросы :)   

albobin

  • Full Member
  • ***
  • Сообщений: 198
    • Просмотр профиля
Re: Очень простой цикл
« Ответ #35 : Май 29, 2012, 01:01:26 pm »
Только понятность резко упала, имхо... )))

Вот многострочный вариант :)

00(x)
  new p
  set p=$find(x,$char(0,0))
  set:p p=p-2
  quit p

ilovb

  • Hero Member
  • *****
  • Сообщений: 2538
  • just another nazi test
    • Просмотр профиля
    • Oberon systems
Re: Очень простой цикл
« Ответ #36 : Май 29, 2012, 01:26:52 pm »
00 - это я такое имя дал функции.
Имя из цифр! Круто  ;D

albobin

  • Full Member
  • ***
  • Сообщений: 198
    • Просмотр профиля
Re: Очень простой цикл
« Ответ #37 : Май 29, 2012, 01:47:46 pm »
Имя из цифр! Круто  ;D

Ну, если бы были допустимы русские буковки в идентификаторах, то можно было бы назвать так :)
ИГдеТутУНасНуликиСпрятались(x)

ilovb

  • Hero Member
  • *****
  • Сообщений: 2538
  • just another nazi test
    • Просмотр профиля
    • Oberon systems
Re: Очень простой цикл
« Ответ #38 : Май 29, 2012, 02:20:43 pm »
Я однажды написал процедуру "НажатиеНаЯйца(Кнопка)".
В интерфейсе кассира была кнопка "Яйца" ну и ...  :)

А эту процедуру я бы назвал "НайтиЯйца(Ячейки)"  ;D

ddn

  • Jr. Member
  • **
  • Сообщений: 59
    • Просмотр профиля
Re: Очень простой цикл
« Ответ #39 : Июнь 03, 2012, 01:32:19 pm »
MODULE ms;
IMPORT StdLog, seq;

(*
MODULE seq;
VAR
oes*, open: BOOLEAN;
len, pos: LONGINT;
(* ~undefined(open) & ~undefined(len) & (0 <= len) & (len < MAX(LONGINT)) *)
(* open <= ~undefined(oes) & ~undefined(pos) & (1 <= pos) & (pos <= len + 1) & (oes = (pos = len + 1)) *)
(* ~open <= undefined(oes) & undefined(pos) *)

(* open' & (0 <= i') & (i' <= len') *)
PROCEDURE element (i: LONGINT): BYTE;
(* (len = len') & open & (pos = pos') & (Result = (element number i')) *)

(* ~open' *)
PROCEDURE reset*;
(* (len = len') & open & (pos = 1) *)

(* open' *)
PROCEDURE close*;
(* (len = len') & ~open *)

(* open' & ~oes' *)
PROCEDURE read* (OUT a: BYTE);
(* (len = len') & open & (pos = pos' + 1) & ~undefined(a) & (a = element(pos')) & ((a = 0) OR (a = 1)) *)
BEGIN
END seq.
*)

VAR
a: BYTE;
i: INTEGER;

(* seq.open' & ~undefined(i') & (i' = seq.pos' - 2) & (def: element(0) = 1) & ~undefined(a') & (a' = element(i' + 1)) *)
PROCEDURE p* (VAR a, i: INTEGER);
VAR b: BOOLEAN;
BEGIN
b := FALSE;
WHILE ((a # 0) OR ~b) & ~seq.oes & (i < MAX(INTEGER)) DO
b := (a = 0);
seq.read(a);
INC(i)
END;
IF (a = 0) & b THEN
StdLog.Int(i);
StdLog.Ln
ELSIF seq.oes THEN
StdLog.Bool(FALSE);
StdLog.Ln
ELSE
StdLog.String('limit length');
StdLog.Ln
END
END
(* (seq.len = seq.len') & seq.open & (def: element(0) = 1) & ~undefined(i) *)
(* i = min({j | j IN {i' .. MIN(seq.len, MAX(INTEGER)) - 1}: (element(j) = 0) & (element(j + 1) = 0)} + {MIN(seq.len, MAX(INTEGER))}) *)
(* (seq.pos = i + 2) & ~(a) & (a = element(i + 1)) *)

BEGIN
seq.reset; (* seq.open *)
a := 1; (* a = element(0) *)
i := -1; (* i = seq.pos - 2 *)
p(a, i); (* p(a, i); p(a, i); p(a, i); ... *)
seq.close (* ~seq.open *)
END ms.
Сам алгоритм:
a := 1;
b := FALSE;
i := -1;
WHILE ((a # 0) OR ~b) & ~seq.oes & (i < MAX(INTEGER)) DO
b := (a = 0);
seq.read(a);
INC(i)
END;
IF (a = 0) & b THEN
StdLog.Int(i);
StdLog.Ln
ELSIF seq.oes THEN
StdLog.Bool(FALSE);
StdLog.Ln
ELSE
StdLog.String('limit length');
StdLog.Ln
END

ddn

  • Jr. Member
  • **
  • Сообщений: 59
    • Просмотр профиля
Re: Очень простой цикл
« Ответ #40 : Июнь 03, 2012, 01:47:01 pm »
Последовательность нумеруется с 1, последовательный доступ как в файле.
А в чем сложность: в удалении мелких повторных вычислений, поиск новых форм цикла, или это чисто вопрос педагогики?

vlad

  • Hero Member
  • *****
  • Сообщений: 1391
    • Просмотр профиля
Re: Очень простой цикл
« Ответ #41 : Июнь 04, 2012, 01:12:57 pm »
А в чем сложность: в удалении мелких повторных вычислений, поиск новых форм цикла, или это чисто вопрос педагогики?

Нет никакой сложности. Просто этот цикл не вписывался ни в одни из библиотечных шаблонов. Поэтому пришлось его сочинять. Наивное решение казалось не совсем првильным (что коробило, потому что если уж дело дошло до "ручного" цикла, то хотелось составить его максимально правильно). Решение через КА - черезчур громоздким. Поэтому было интересно кто как такое решает.

vlad

  • Hero Member
  • *****
  • Сообщений: 1391
    • Просмотр профиля
Re: Очень простой цикл
« Ответ #42 : Июнь 04, 2012, 06:41:19 pm »
А тем временем появлися вариант с ЦД. Причем от самого info21!
http://forum.oberoncore.ru/viewtopic.php?p=72954#p72954
      i := 0;
      oneZero := FALSE;
      LOOP IF (i < LEN(a)) & ~oneZero THEN
         oneZero := a[i] = 0;
         INC(i);
      ELSIF (i < LEN(a)) & (a[i] # 0) THEN
         oneZero := FALSE;
         INC(i);
      ELSE EXIT END END;
     
      IF (i < LEN(a)) & oneZero THEN
         Log.String("нашли: ");  Log.Int( i-1 );  Log.Ln;
      ELSE
         Log.String("не нашли");  Log.Ln;
      END;

ИМХО, самый нечитабельный вариант из всех. Хотя я верю, что этот код легко пишется "автоматом по постусловию".
« Последнее редактирование: Июнь 04, 2012, 06:43:49 pm от vlad »

Berserker

  • Sr. Member
  • ****
  • Сообщений: 254
    • Просмотр профиля
Re: Очень простой цикл
« Ответ #43 : Июнь 04, 2012, 07:30:12 pm »
NumZeroes := 0;
Success   := FALSE;
i         := 0;

WHILE (i < LEN(a)) & ~Success DO
  IF a[i] = 0 THEN
    INC(NumZeroes);
    Success := NumZeroes = 2;
  ELSE
    NumZeroes := 0;
  END;

 INC(i);
END;

Berserker

  • Sr. Member
  • ****
  • Сообщений: 254
    • Просмотр профиля
Re: Очень простой цикл
« Ответ #44 : Июнь 04, 2012, 07:58:55 pm »
CONST
  CHAIN_LEN   = 7;
  CHAIN_BYTE  = 0;

ChainLen  := 0;
i         := 0;

WHILE (i < LEN(a)) & (ChainLen < CHAIN_LEN) DO
  IF a[i] = CHAIN_BYTE THEN
    INC(ChainLen);
  ELSE
    ChainLen := 0;
  END;

 INC(i);
END;

Обновление.