このディレクトリの索引

# 出典 :: C/C++の宿題片付けます 129代目 #689 # [2] 問題文(含コード&リンク): POSデータ解析システムを作ってみよう # K氏は、3つのコンビニエンスストア(X店、Y店、Z店)をチェーン店に持つオーナーです。コンビ # ニエンスストアの経営において、売れ筋商品と死に筋商品の的確な把握は死活問題に直結する重要な業務 # です。そこでK氏は、チェーン店に、毎日どんな商品がどれくらい売れたのかといった販売情報を、CS # Vファイルとして送るように指示していました。しかし、送られてくるデータファイルは膨大であり、そ # れらを統合して、全店を通して最も売れた商品はどれで、何が売れていないかを把握することは困難でし # た。つまり、送られてくるデータを適切に活用できないでいました。そこで、K氏はあなたに、こういっ # たことを解決するシステム(POSデータ解析システム)を開発するように頼みました。K氏は、毎日送 # られてくるX、Y、Z店の個別の販売情報を合計した一括データを入手したいそうです。 # <第1ステップ> # まず、あなたは、各店舗から送ってもらうCSV ファイル名を以下のようにするよう、お願いしました。 # X店=data-x.csv Y店=data-y.csv Z店=data-z.csv # また、商品名(全100 品種)は必ず以下の形式で入力するように指示しました。 # 「 Item-00 」から「 Item-99 」までの半角7文字 # さらに、各店から送られてくるレコードのフィールドは、以下の項目にして、売上時刻順に並べてもら # うよう、お願いしました。以下のようなCSV ファイルが送られてくることになります。 # 売上時刻 商品名 売上個数 # 0:12,Item-42,2 # 0:12,Item-03,1 # 0:49,Item-92,3 # ・ # ・ # 23:38,Item-80,1 # また、毎日送られてくるCSVファイルとは別に、単価情報が格納された tanka.csv ファイルを作りま # した。このファイルのレコードのフィールドは、次のようになっていて、商品名順に並んでいます。 # 商品名 単価 # Item-00,150 # Item-01,120 # ・ # Item-99,230 # 最後に、K 氏に提供する統合ファイル(data-all.csv)のレコードの中身は以下のようにして、商品名 # の小さい順にレコードを作りました。 # 商品名 単価 総売上個数 売上高 # ここで、大事なことは、売上情報を統合することです。例えば、単価150 円のItem-23 という商品が、 # X 店では15 個、Y 店では、25 個、Z 店では10 個売れたとすると、以下のようになっているということです。 # Item-23,150,50,7500 # また、全店舗を通して1 個も売れなかった商品情報は載せないことにしました。 # # # <第2ステップ> # K氏から、data-all.csv のレコードの中身を以下のように変更し、レコードを並べる順番も、これまで # の商品名順ではなく、売上順位の高い順にして欲しいと要望がありました。 # 売上順位 商品名 単価 総売上個数 売上高 全売上高にしめる割合(%) # 全売上高とは、全商品の売上高の合計です。全売上高にしめる割合の有効数字は4 桁(10%未満の場合は # 3 桁)にします。例えば、全売上高が100 万円で、該当商品の売上高が12,345 円だとすると、割合(%) # は 1.23 となります。 # 売上順位は、同じ売上高の場合は同一順位とします。 # 例えば、data-all.csv ファイルは次のようになります。 # 1,Item-23,150,50,7500,10.71 # 2,Item-52,240,30,7200,10.28 # 2,Item-53,360,20,7200,10.28 # 4,Item-14,230,30,6900,9.85 # ・ t589_1 :- 基礎情報を得る(TL,XL,YL,ZL), '3つのコンビニエンスストアの情報を集約する第1ステップ'(XL,YL,ZL,TL,_集約ならび), 集約情報から統合ファイル出力(_集約ならび). t589_2 :- 基礎情報を得る(TL,XL,YL,ZL), '3つのコンビニエンスストアの情報を集約する第2ステップ'(XL,YL,ZL,TL,_集約ならび), 集約情報から金額順位順統合ファイル出力(_集約ならび). 基礎情報を得る(TL,XL,YL,ZL) :- get_split_lines('tanka.csv',[',',' '],TL), get_split_lines('data-x.csv',[',',' '],XL), get_split_lines('data-y.csv',[',',' '],YL), get_split_lines('data-z.csv',[',',' '],ZL),!. '3つのコンビニエンスストアの情報を集約する第1ステップ'(XL,YL,ZL,TL,_集約ならび) :- append(XL,YL,ZL,L1), '商品名ごとの単価を得て、数量、金額を集約する'(L1,TL,_集約ならび). '3つのコンビニエンスストアの情報を集約する第2ステップ'(XL,YL,ZL,TL,_集約ならび) :- append(XL,YL,ZL,L1), '商品名ごとの単価を得て、数量、金額を集約する'(L1,TL,_集約ならび), rsort(_集約ならびの一,_金額合計で整列した集約ならび), 総売上金額を得る(_集約ならびの一,_総売上金額), 順位売上比率付き集約ならび(1,1,_金額合計で整列した集約ならび,_集約ならび). 総売上金額を得る(_集約ならびの一,_総売上金額) :- findsum(_金額合計,member([_金額合計,_,_,_],_集約ならびの一),_総売上金額). 順位売上比率付き集約ならび(_,_,_,[],[]) :- !. 順位売上比率付き集約ならび(M,N,_総売上金額,[[A,B,C,D],[A|R2]|R3],[[M,B,C,D,A,E]|R4]) :- E is A / _総売上金額, N2 is N + 1, 順位売上比率付き集約ならび(M,N2,[[A|R2]|R3],R4). 順位売上比率付き集約ならび(M,N,_総売上金額,[[A,B,C,D]|R3],[[M,B,C,D,A,E]|R4]) :- E is A / _総売上金額, N2 is N + 1, 順位売上比率付き集約ならび(N2,N2,R3,R4). 集約情報から統合ファイル出力(LL) :- open('data-all.csv',write,Output), '商品名、単価、数量合計、金額合計の出力'(Output,LL). '商品名、単価、数量合計、金額合計の出力'(Output,[]) :- close(Output). '商品名、単価、数量合計、金額合計の出力'(Output,LL) :- '商品名、単価、数量合計、金額合計の出力して行く'(Output,LL). '商品名、単価、数量合計、金額合計の出力して行く'(Output,[[_商品名,_単価,_数量,_金額]|R]) :- '商品名、単価、数量合計、金額合計を一行出力する'(Output,_商品名,_単価,_数量,_金額), '商品名、単価、数量合計、金額合計の出力'(Output,R). '商品名、単価、数量合計、金額合計を一行出力する'(Output,_商品名,_単価,_数量,_金額) :- concat_atom([_商品名,_単価,_数量,_金額],',',S), swritef(_表示文字列,'%w\n',[S]), write(Output,_表示文字列). 集約情報から金額順位順統合ファイル出力([]). 集約情報から金額順位順統合ファイル出力([[A,B,C,D,E,F]|R]) :- 順位付けして一行表示する(A,B,C,D,E,F), 集約情報から金額順位順統合ファイル出力(R). 順位付けして一行表示する(A,B,C,D,E,F) :- F2 is round(F * 100.0) / 100, swritef(_表示文字列,'%w,%w,%w,%w,%w,%.2f',[A,B,C,D,E,F2]), writef('%w\n',[_表示文字列]). '商品名ごとの単価を得て、数量、金額を集約する'(L1,TL,_集約ならび) :- 売上の存在する商品名を得る(L1,_商品名ならび), findall([_商品名,_単価,_数量合計,_金額合計],( '商品名の単価、数量合計、金額合計'(_商品名ならび,TL,_商品名,_単価,_数量合計,_金額合計)),_集約ならび). '商品名の単価、数量合計、金額合計'(_商品名ならび,TL,_商品名,_単価,_数量合計,_金額合計) :- member(_商品名,_商品名ならび), 商品名の数量合計を得る(_商品名,_数量合計), '単価と金額合計を得る'(TL,_商品名,_単価,_数量合計,_金額合計). '単価と金額合計を得る'(TL,_商品名,_単価,_数量合計), member([_商品名,_単価],TL), _金額合計 is _数量合計 * _単価. 商品名の数量合計を得る(_商品名,_合計数量) :- findsum(_数量,member([_,_商品名,_数量],_合計数量). 売上の存在する商品名を得る(L1,_整列してユニークな商品名ならび) :- 商品名のみ選択(L1,L2), sort(L2,_整列してユニークな商品名ならび). 商品名のみ選択([],[]). 商品名のみ選択([[_,_商品名,_]|R1],[_商品名|R2]) :- 商品名のみ選択(R1,R2). rsort(L,L2) :- sort(L,L1), reverse(L1,L2). findsum(_射影項,_目標,_合計) :- findall(_射影項,_目標,_値ならび), sum_list(_値ならび,_合計).