red_nosed_reports.adb 2.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. with Ada.Integer_Text_IO; use Ada.Integer_Text_IO;
  2. with Ada.Containers.Vectors;
  3. with Ada.Containers; use Ada.Containers;
  4. with Ada.Text_IO; use Ada.Text_IO;
  5. -- This code reads its input from standard input
  6. -- Use cat _input.txt | Red_Nosed_Reports_ to get the result
  7. procedure Red_Nosed_Reports is
  8. subtype Level is Positive;
  9. function Reversed_Sort (Left, Right : Level) return Boolean;
  10. package Report is
  11. new Ada.Containers.Vectors (Index_type => Positive,
  12. Element_Type => Level);
  13. use Report;
  14. package Report_Sorting is new Report.Generic_Sorting;
  15. package Reverse_Report_Sorting is
  16. new Report.Generic_Sorting ("<" => Reversed_Sort);
  17. function Reversed_Sort (Left, Right : Level) return Boolean is
  18. begin
  19. return Right < Left;
  20. end Reversed_Sort;
  21. subtype Valid_Range is Positive range 1 .. 3;
  22. Safe_Reports_Number : Natural := 0;
  23. begin
  24. while not End_Of_File loop
  25. declare
  26. Value : Level;
  27. Current_Report : Report.Vector;
  28. begin
  29. while not End_Of_Line loop
  30. Get (Value);
  31. Current_Report.Append (Value);
  32. Put (Value'Image);
  33. Put (" ");
  34. end loop;
  35. -- Check if safe
  36. if Report_Sorting.Is_Sorted (Current_Report)
  37. or else Reverse_Report_Sorting.Is_Sorted (Current_Report)
  38. then
  39. declare
  40. Safe : Boolean := True;
  41. Current_Cursor : Report.Cursor := Current_Report.First;
  42. Previous : Level := Current_Report.First_Element;
  43. begin
  44. while Current_Cursor /= Current_Report.Last and then Safe loop
  45. Next (Current_Cursor);
  46. if abs (Element (Current_Cursor) - Previous)
  47. not in Valid_Range'Range
  48. then
  49. Safe := False;
  50. end if;
  51. Previous := Element (Current_Cursor);
  52. end loop;
  53. if Safe then
  54. Safe_Reports_Number := Safe_Reports_Number + 1;
  55. Put ("Safe");
  56. else
  57. Put ("Unsafe");
  58. end if;
  59. end;
  60. else
  61. Put ("Unsafe");
  62. end if;
  63. -- Skip to next Line
  64. Skip_Line;
  65. end;
  66. New_Line;
  67. end loop;
  68. Put_Line ("Number of Safe is " & Safe_Reports_Number'Image);
  69. end Red_Nosed_Reports;