Помощь новичкам

Полного аналога нет и быть не может в языке со статической типизацией. Есть [Cache].

[Cache] это и есть @lru_cache(None). Никакой логики чистки кэша у [Cache] нет.

Спасибо.

Прошу помощи. Задание 21 ЕГЭ.

Решение на Питон

from functools import lru_cache
def moves(h):
    a,b=h
    return(a+1,b),(a*2,b),(a,b+1),(a,b*2)
@lru_cache(None)
def game(h):
    if sum(h)>=62:
        return "w"
    if any(game(m)=="w" for m in moves(h)):
        return "P1"
    if all(game(m)=="P1" for m in moves(h)):
        return "B1"
    if any(game(m)=="B1" for m in moves(h)):
        return "P2"
    if all(game(m)=="P1" or game(m)=="P2" for m in moves(h)):        
        return "B2"

for s in range(1,52):
    if game((10,s)) is not None:
        print(s,  game((10,s)) )

Переписал на PascalABC.NET как сумел:

function moves(h:(integer,integer)):((integer,integer),
                                      (integer,integer),
                                      (integer,integer),
                                      (integer,integer));
  var a,b:integer;
begin
  (a,b):=h;
  result:=((a+1,b),(a*2,b),(a,b+1),(a,b*2))
end;

[Cache]
function game(h:(integer,integer)):string ;
begin
  result := 'N';
  
  if (h[0]+h[1])>=62 then 
    begin
      result:='w';
      exit
    end;  
  if (game(moves(h)[0])='w') or
     (game(moves(h)[1])='w') or
     (game(moves(h)[2])='w') or
     (game(moves(h)[3])='w') then 
     begin
       result := 'P1';
       exit
     end;
  if (game(moves(h)[0])='P1') and
     (game(moves(h)[1])='P1') and
     (game(moves(h)[2])='P1') and
     (game(moves(h)[3])='P1') then 
     begin
       result := 'B1';
       exit
     end;
     
  if (game(moves(h)[0])='B1') or
     (game(moves(h)[1])='B1') or
     (game(moves(h)[2])='B1') or
     (game(moves(h)[3])='B1') then   
     begin
       result := 'P2';
       exit
     end;
  
  if ((game(moves(h)[0])='P1') or (game(moves(h)[0])='P2')) and
     ((game(moves(h)[1])='P1') or (game(moves(h)[1])='P2')) and
     ((game(moves(h)[2])='P1') or (game(moves(h)[2])='P2')) and
     ((game(moves(h)[3])='P1') or (game(moves(h)[3])='P2')) then 
     begin
       result := 'B2';  
       exit
     end;
end;  
begin
  for var s:=1 to 51 do 
    begin
      if game((10,s)) <> 'N' then writeln(s, game((10,s)))
    end
end.     

Работает медленнее. Как ускорить или написать решение по другому (проще)?

А что такое медленнее? У меня мгновенно. К тому же время не выдаётся

Делаю цикл до 70 и сумму 80 и жду…

Жуть какая… это чтобы показать, насколько Питон “передовой” ? ))

function moves(h: (integer, integer)): array of (integer, integer);
begin
  var (a, b) := h;
  Result := Arr((a + 1, b), (a * 2, b), (a, b + 1), (a, b * 2))
end;

[Cache]
function game(h: (integer, integer)): string;
begin
  Result := 'N';
  if (h[0] + h[1]) >= 62 then begin Result := 'w'; exit end;  
  var r := moves(h);
  if r.Any(t -> game(t) = 'w') then begin Result := 'P1'; exit end;
  if r.All(t -> game(t) = 'P1') then begin Result := 'B1'; exit end;
  if r.Any(t -> game(t) = 'B1') then begin Result := 'P2'; exit end;
  if r.All(t -> (game(t) = 'P1') or (game(t) = 'P2')) then Result := 'B2'
end;

begin
  for var s := 1 to 51 do 
  begin
    var r := game((10, s));
    if r <> 'N' then Writeln(s, r)
  end
end.

Вы про это?

Нет.

Да.

Что у меня не так?

Понял. Версия: Версия

Теперь при 70: Снимок70new

При 80: 00:00:00.0098089

  учебник для 11 класса Ч2, 2013.    стр.59      
}
program MyProgram1; 
  type 
    TBook = record
      author:string[40];
      title:string[80];
      count:integer;
    end;  
  
  const N = 100;
  
  var 
    B:TBook;
    Books:array[1..N] of TBook;
  
begin
  Writeln(sizeof(TBook));  // почему 24 ???
  //Writeln(sizeof(B));       не работает
  //Writeln(sizeof(Books));
end.

Прокомментируйте, пожалуйста. Почему 24? И как узнать размер массива в байтах?

Две ссылки по 8 байт, integer - 4 байта - ну и на выравнивание - 4 байта.

1 лайк

А что вы называете размером массива? Он может достаточно сложно храниться. И он - тоже ссылка, поэтому используя sizeof, вы получите 8 байт.

Учебник для 11 класса - древний и плохой. В стандарте Паскаля не прописано, как должен храниться массив или строка.

type
  T = record
    A, B: int64;
    C: integer;
  end;
  
begin
  sizeof(T).Println; // 24
  RunTimeSizeOf(T.Create.GetType()).Println // 20
end.

Так должно быть? RunTimeSizeOf, конечно, не задокументирована, но всё же.

RunTimeSizeOf используется в типизированных файлах, так что все правильно. А в памяти запись выравнивается для эффективной работы с памятью.

1 лайк

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

type 
  TBook = record
    author:string[40];
    title:string[80];
    count:integer;
  end;  
  
const N = 100;
  
var 
  B:TBook;
  Books:array[1..N] of TBook;

begin
  var f: file of TBook;
  Assign(f, 'TBook.bin');
  Rewrite(f);
  for var i := 1 to N do
  begin
    B.author := 'a' * 40; // 41 байт
    B.title := 'b' * 80; // 81 байт
    B.count := i; // 4 байта
    Write(f, B) // 124 байта
  end;
  Close(f)
end.

Еще Н.Вирт решил, что “его” строка имеет длину максимум 254 символа, поэтому первый символ строки - однобайтный дескриптор длины. Итого 124 символа на запись.

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

1 лайк

RunTimeSizeOf не задокументирована