summaryrefslogtreecommitdiff
path: root/src/bundles.adb
diff options
context:
space:
mode:
Diffstat (limited to 'src/bundles.adb')
-rw-r--r--src/bundles.adb146
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;