diff options
Diffstat (limited to 'src/bundles.adb')
-rw-r--r-- | src/bundles.adb | 146 |
1 files changed, 146 insertions, 0 deletions
diff --git a/src/bundles.adb b/src/bundles.adb index 6a2d71d..3902971 100644 --- a/src/bundles.adb +++ b/src/bundles.adb @@ -1,8 +1,154 @@ +with Ada.Text_IO; +with CSV; + + package body Bundles is + procedure Add_To_Map + (BMap : in out Bundle_Maps.Map; + Item : in Given_Prefs.Preference_Array) + is + procedure Update_Bundle + (B : in out Bundle) is + begin + Add (B, Item); + end Update_Bundle; + + procedure Update_Vector + (C : Candidates.CandidateID; + V : Bundle_Vectors.Vector) is + begin + V.Update_Element (V.First_Index, Update_Bundle'Access); + end Update_Vector; + + Place : Candidates.CandidateID := Item (Given_Prefs.Preference_Range'First); + Current_Cursor : Bundle_Maps.Cursor := Result.Find (Place); + begin + if Current_Cursor /= Bundle_Maps.No_Element then + BMap.Update_Element (Current_Cursor, Update_Vector'Access); + else + declare + New_Bundle : Bundle := Empty_Bundle; + begin + Add (New_Bundle, Item); + BMap.Insert (Place, Bundle_Vectors.Empty_Vector & New_Bundle); + end; + end if; + end Add_To_Map; + + + + + procedure Read_Bundles + (Filename : in String; + Result : out Bundle_Maps.Map) + is + package My_CSV is new CSV; + use Ada.Text_IO; + + Input_File : File_Type; + Current_Record : My_CSV.CSV_Record; + Current_Prefs : Given_Prefs.Preference_Array; + begin + Open (Input_File, In_File, Filename); + + Result := Bundle_Maps.Empty_Map; + while not End_Of_File (Input_File) loop + Current_Record := My_CSV.Parse_Line (Get_Line (Input_File)); + if Current_Record.Length > 0 then + Current_Prefs := Given_Prefs.Parse_Preferences (Current_Record.Last_Element); + if Current_Prefs (Given_Prefs.Preference_Range'First) /= Candidates.No_Candidate then + Add_To_Map (Result, Current_Prefs); + end if; + end if; + end loop; + + Close (Input_File); + end Read_Bundles; + + + + + procedure Add + (This : in out Bundle; + Item : in Given_Prefs.Preference_Array) is + begin + for P of This.Papers loop + if P.Prefs = Item then + P.How_Many := P.How_Many + 1; + return; + end if; + end if; + This.Papers.Append ( (How_Many => 1, Prefs => Item) ); + end Add; + + + + + procedure Transfer + (This : in out Bundle; + From, To : in Candidates.CandidateID; + Excluded : in Candidates.CandidateID_Vector; + Value : in Rationals.Fraction; + Result : out Bundle) + is + Position : Positive; + begin + Result := Empty_Bundle; + Result.Worth := This.Worth * Value; + for P of This.Papers loop + Position := Given_Prefs.Preference_Range'First; + + while Position <= Given_Prefs.Preference_Range'Last and then + P.Prefs (Position) /= From + loop + Position := Position + 1; + end loop; + Position := Position + 1; + + while Position <= Given_Prefs.Preference_Range'Last and then + Excluded.Contains (P.Prefs (Position)) + loop + Position := Position + 1; + end loop; + + if Position <= Given_Prefs.Preference_Range'Last and then + P.Prefs (Position) = To + then + Result.Papers.Append (P); + end if; + end loop; + end Transfer; + + + + + function Count_Votes + (This : in Bundle) + return Natural is + begin + return Rationals.Floor (Count_Papers (This) * This.Worth); + end Count_Votes; + + + + + function Count_Papers + (This : in Bundle) + return Natural + is + Result : Natural := 0; + begin + for P of This.Papers loop + Result := Result + P.How_Many; + end loop; + return Result; + end Count_Papers; + + end Bundles; |