Описание
Банки, пытаясь увеличить свою прибыль, попросили инженеров разработать сканер, который автоматически считывает номера чеков. Известно, что любой чек имеет девятизначный номер и для каждого номера чека выполняется следующее условие: (d1+2·d2+...+9·d9) mod 11 = 0, где di равно i-й цифре номера (цифры нумеруются справа налево: d9d8d7d6d5d4d3d2d1)

Сканер, считывая номер, преобразовывает горизонтальные и вертикальные линии в символы "|" (ASCII-код 124) и "_" (ASCII-код 95) соответственно. В результате сканирования выдается картинка, составленная из этих символов и пробелов. Пример правильного изображения цифр после сканирования приведен в примере входного файла

Задача
К сожалению, иногда сканер допускает ошибки, и некоторые линии могут пропадать. Вы должны написать программу, которая восстанавливает исходный номер чека, считая выполненными следующие условия:

  • если отсканированное число является корректным номером чека, то это и есть исходный номер

  • испорчено не более одной цифры

  • при сканировании не появляются дополнительные линии


Входные данные
Входной файл содержит отсканированную картинку в виде 3 строк по 27 символов в каждой. Изображение каждой цифры занимает квадрат размером 3
×3 символа

Выходные данные
Запишите в выходной файл либо корректный номер чека, либо строку "
failure", если номер восстановить нельзя, либо строку "ambiguous", если существует более одного решения


Например:

SCANNER.IN
  _  _     _  _  _  _  _
| _| _||_||_ |_   ||_||_|
||_  _|  | _||_|  ||_| _|


SCANNER
.OUT
123456789






Комментарии

Задача авторами не комментировалась
 



Решение

{$A+,B-,D+,E-,F-,G+,I+,L+,N+,O-,P-,Q-,R-,S-,T-,V+,X+,Y+}
{$M 65520,0,655360}

program
scanner;
c
onst
  Chars:Array[0..9]Of Word=(2+8+32+64+128+256,32+256,2+16+32+64+128,
                            2+16+32+128+256,8+16+32+256,2+8+16+128+256,
                            2+8+16+64+128+256,2+32+256,2+8+16+32+64+128+256,
                            2+8+16+32+128+256);
var
  Src:Array[1..9,0..2,0..2]Of Char;
  SrcB:Array[1..9]Of Word;
  Res:String;

Procedure
Load;
Var
  I,J,K:Byte;
  St:String;
Begin
  Assign(Input,'scanner.in');
  ReSet(Input);
  For I:=0 To 2 Do Begin
    ReadLn(St);
    While Length(St)<27 Do St:=St+' ';
    For J:=1 To 9 Do
      For K:=0 To 2 Do
        Src[J,K,I]:=St[(J-1)*3+K+1];
  End;
  Close(Input);
End;

Procedure
Run;
Var
  I,J,K:Byte;
  MayBe:Array[1..9,0..9]Of Boolean;
  Eq:Array[1..9]Of Byte;
  NotEq,NotEq1:Byte;
Function Check:Boolean;
Var
  I:Byte;
  Sum:LongInt;
Begin
  Sum:=0;
  For I:=1 To 9 Do Sum:=Sum+I*Eq[10-I];
  Check:=Sum Mod 11=0;
End;

Procedure
MakeRes;
Var
  I:Byte;
Begin
  Res:='';
  For I:=1 To 9 Do Res:=Res+Chr(Eq[I]+48);
End;
Begin
  NotEq:=0;
  For I:=1 To 9 Do Begin
    SrcB[I]:=0;
    For J:=0 To 2 Do
      For K:=0 To 2 Do
        SrcB[I]:=SrcB[I]+Ord((Src[I,J,K]='|') Or (Src[I,J,K]='_'))*(1 Shl (K*3+J));
    Eq[I]:=10;
    For J:=0 To 9 Do Begin
      If SrcB[I]=Chars[J] Then Eq[I]:=J;
      MayBe[I,J]:=(SrcB[I] And Chars[J])=SrcB[I];
    End;
    If Eq[I]=10 Then Begin Inc(NotEq); NotEq1:=I; End;
  End;
  Case NotEq Of
    0:Begin
      If Check Then MakeRes Else Res:='failure';
      For I:=1 To 9 Do Begin
        For J:=0 To 9 Do If (Eq[I]<>J) And MayBe[I,J] Then Begin
          K:=Eq[I];
          Eq[I]:=J;
          If Check Then
            If Res='failure' Then MakeRes Else Begin Res:='ambiguous'; Exit; End;
          Eq[I]:=K;
        End;
      End;
    End;
    1:Begin
      Res:='failure';
      For J:=0 To 9 Do If MayBe[NotEq1,J] Then Begin
        Eq[NotEq1]:=J;
        If Check Then
          If Res='failure' Then MakeRes Else Begin Res:='ambiguous'; Exit; End;
      End;
    End;
    Else Res:='failure';
  End;
End;

Procedure
Save;
Var
  I,J:Byte;
Begin
  Assign(Output,'scanner.out');
  ReWrite(Output);
  WriteLn(Res);
  Close(Output);
End;

Begin

  Load;
  Run;
  Save;
End.

 


© Особенности национальных задач по информатике