CodeIQ:キュラゲブレイドを生産しよう★

私自身が表題の問題を解いた時のプログラムについて解説します。
問題の詳細は「キュラゲブレイドを生産しよう★」(CodeIQ)を参照してください。

問題の概要

問題を引用します。

キュラゲブレイドは、1本あたり「キュラゲの皮」×5、「キュラゲの牙」×6、「キュラゲの眼」×2で生産することが可能です。キュラゲを狩って素材を手に入れ、できるだけたくさんのキュラゲブレイドを作ってください。

キュラゲには、小さい「キュラゲ」・大きい「ドスキュラゲ」の2種類が存在します。
小さいキュラゲからは「キュラゲの皮」×2、「キュラゲの牙」×10、「キュラゲの眼」×2が得られます。
大きいドスキュラゲからは「キュラゲの皮」×8、「キュラゲの牙」×2、「キュラゲの眼」×2が得られます。

【入力】
標準入力の1行目は整数値N(1≦N≦1000)で、キュラゲの数を表します。2行目はN文字の文字列データで、小さい「キュラゲ」は"q"、大きい「ドスキュラゲ」は"Q"とします。
【出力】
標準出力に、生産可能なキュラゲブレイドの個数の最大値を出力してください(整数値のみ)。

私のプログラム

Pythonで解答しています。

#!/usr/local/bin/python3
# -*- coding: utf-8 -*-

import fileinput
from operator import add
from operator import floordiv

# 皮, 牙, 眼
Gets = {
	"Q" : (8,2,2),	# キュラゲ大
	"q" : (2,10,2)	# キュラゲ小
}

# 材料 皮, 牙, 眼
Mats = (5,6,2)

def getBlades(n):
	b = list(map(floordiv, n, Mats))
	return min(b)

if __name__ == "__main__":
	lcnt = 0
	Qq = ""
	for line in fileinput.input():
		if not line.strip():
			continue
		elif lcnt == 1:
			Qq = line.strip()

		lcnt += 1


	cnt = [0,0,0]
	for c in Qq:
		cnt = list(map(add, cnt, Gets[c]))

	print(str(getBlades(cnt)))

解説

この問題は簡単です(★1つですし)。
単に入力値から材料の合計を求めて、創り出せるキュラゲブレイドの最大数を求めればよいだけです。

定数

Getsは大小のキュラゲから得られる材料です。入力値が文字列なのでそこから引けるようにDictionaryにしています。Matsはキュラゲブレイドを作るのに必要な材料の量の定義です。

入力値から材料の合計を求める

34〜35行目で行っている処理です。入力値を1文字ずつ(Qかq)を取り出してGetsから材料の数に変換し、cntに合計を加算してゆきます。

getBlades()

この関数で結果を求めます。
生産可能なキュラゲブレイドの数は材料のうち最も少ない(各材料合計/ブレイドの材料に必要な量が最小のもの)に制約されるので、入手した各材料の値をブレイドに必要な量で割ってその最小値を返すだけです。

雑感

どうこういうようなところはありません。素直に処理すればできる内容です。