AtCoder Programming Guide for beginners(APG4b) 第1章のEX問題をPythonで解く
AtCoder Programming Guide for beginners(APG4b) EX1 ~ EX15の回答
~ AtCoder 300台の貧弱プログラマが脳筋コードでとくAPG4b
概要
- AtCoder rate 300台の貧弱プログラマがAPG4bのEX1 ~ 15(第1章)の内容をPythonで解いていくだけ
前回後輩に頼まれて第2章から解いていったが、どうせなら第1章も解こうじゃないかというただの自己満
今回もさっさと解いていく
- AtCoder Programming Guide for beginners(APG4b) EX1 ~ EX15の回答
EX1 ~ コードテストと出力の練習 ~
この問題を解いていく
print("こんにちは")
print("AtCoder")
EX1の補足
まぁこれはprintで指定された文字列を出力するだけなので補足事項はなし
EX2 ~ エラーの修正
この問題を解いていく
※今回はエラーの修正ということで、問題のコードも載せるが、Pythonでは再現不可のコードがあったため、別のコードで代用した
問題のコード(Python仕様に変更後)
print("いつも2525)
print(”AtCoderくん")
エラーコード
File "Main.py", line 1
print("いつも2525)
^
SyntaxError: unterminated string literal (detected at line 1)
File "Main.py", line 2
print(”AtCoderくん")
^
SyntaxError: invalid character '”' (U+201D)
解答
print("いつも2525")
print("AtCoderくん")
EX2の補足
Pythonはインタプリタ(1行ずつエラーを確認する)なので、最初の文でエラーが出るとそれ以降の行は正しい処理をしているのかはわからないため注意が必要(今回は分かりやすくするため全てのエラーを列挙した)
今回のエラー内容として、1行目は"で閉じていないことが原因であり、2行目は"が全角になっていたことが原因である
EX3 ~ 計算問題 ~
この問題を解いていく
print(100 * (100 + 1) // 2)
EX3の補足
最初、
print(100 * (100 + 1) / 2)
としたが、WAが出た
この原因として、pythonは割り算を行うと割り切れたとしてもintではなく、floatで返す(ex 100 / 2 => 50.0)ことが挙げられる
そのため、intにキャスト(ex int(100 / 2))にするか、//を使って整数にすることでこの問題を解決できる
EX4 ~ ⚪︎年は何秒? ~
この問題を解いていく
year_second = 365 * 24 * 60 * 60 # 1年の秒数 print(year_second * 1) # 2年の秒数 print(year_second * 2) # 5年の秒数 print(year_second * 5) # 10年の秒数 print(year_second * 10)
EX4の補足
今回の問題は1年の秒数を変数に格納しておいて、必要な年数分をかけたものを出力すればいいだけなので補足することはないだろう
EX5 ~ A足すB問題 ~
この問題を解いていく
a, b = map(int, input().split()) print(a + b)
EX5の補足
a + bを行うコードはもっと短く書くことができる
print(sum(map(int, input().split()))
EX6 ~ 電卓をつくろう ~
この問題を解いていく
f = list(input().split())
a, b = int(f[0]), int(f[2])
op = f[1]
if op == '+':
print(a + b)
elif op == '-':
print(a - b)
elif op == '*':
print(a * b)
elif op == '/':
if b == 0:
print("error")
else:
print(a // b)
else:
print("error")
EX6の補足
今回の問題はif文をそれぞれの条件に合わせて分岐させるだけなので補足することはないだろう
EX7 ~ bool値パズル ~
この問題を解いていく
a = True
b = False
c = True
if a:
print("At", end='')
else:
print("Yo", end='')
if not a and b:
print("Bo", end='')
elif not b or c:
print("Co", end='')
if a and b and c:
print("foo!", end='')
elif True and False:
print("yeah!", end='')
elif not a or c:
print("der", end='')
print()
EX7の補足
論理積(and)と論理和(or)の仕組みを覚えておくと良い
and -> どちらもTrueの場合のみTrueを返す
or -> どちらか片方がTrueの場合Trueを返す
EX8 ~ たこ焼きセット ~
この問題を解いていく
pattern = int(input()) if pattern == 2: text = input() print(text + "!") price = int(input()) count = int(input()) print(price * count)
EX8の補足
この問題はpatternが2の時だけ、テキストを入力して出力する動作が追加されるため、if文で分岐させ、テキストを受け取り、出力してから、値段と個数を受け取り、合計金額を出力している
EX9 ~複合代入演算子を使おう ~
この問題を解いていく
x, a, b = map(int, input().split()) # 出力1. xに1を足した値 x += 1 print(x) # 出力2. (1.で出力した値)に(a+b)を掛けた値 x *= (a + b) print(x) # 出力3. (2.で出力した値)に(2.で出力した値)を掛けた値 x *= x print(x) # 出力4. (3.で出力した値)から1を引いた値 x -= 1 print(x)
EX9の補足
出力1で x += 1と書いているが、x = x + 1と同じ挙動を示す
同じ変数に演算を行う場合は、x += 1 や x *= 2 などx 演算子= 何らかの値 を使うことで、x = x 演算子 何らかの値を省略することができる
EX10 ~ 棒グラフの出力 ~
この問題を解いていく
a, b = map(int, input().split()) A = "A:" + "]" * a B = "B:" + "]" * b print(A) print(B)
EX10の補足
文字列は演算子を使うことで文字列同士を繋げることができる
例えば、定義 : A = ""にA += "AtCoder" を行うとAの中身は"AtCoder"となる
掛け算を使う場合 -> 定義 : A = "AtCoder" に A *= 2を行うとAの中身は"AtCoderAtCoder"となる
EX11 ~ 電卓を作ろう2 ~
この問題を解いていく
N = int(input())
A = int(input())
for i in range(N):
op, B = input().split()
B = int(B)
if op == '+':
A += B
print(f"{i+1}:{A}")
elif op == '-':
A -= B
print(f"{i+1}:{A}")
elif op == '*':
A *= B
print(f"{i+1}:{A}")
elif op == '/':
if B == 0:
print("error")
exit()
else:
A = int(A / B)
print(f"{i+1}:{A}")
EX11の補足
Pythonは文字列と整数型を一緒に出力することができないので、整数型の変数を文字列型に変換する必要がある
それを回避するために、formatを使い、整数型を文字列型に変換せずに出力させている
print文のところで使われているfだが、これはformatを使っている
formatの詳しい使い方はPython, formatで書式変換(0埋め、指数表記、16進数など)を参考にすると良いだろう
EX12 ~ 足したり引いたり ~
この問題を解いていく
S = list(input())
N = 1
plus = S.count('+')
minus = S.count('-')
print(N + plus - minus)
EX12の補足
リスト、文字列には特定の文字の出現回数を数える.count()というメソッドがある
そのため、今回書いたコードは
S = input()
N = 1
plus = S.count('+')
minus = S.count('-')
print(N + plus - minus)
と書いてもACを取ることができる
EX13 ~ 平均との差 ~
この問題を解いていく
N = int(input()) A = list(map(int, input().split())) mean = sum(A) // N ans = list(map(lambda x: abs(mean - x), A)) print(*ans, sep='\n')
EX13の補足
print()の第2引数で指定されているsep='\n'は区切り文字(デフォルトは,)を'\n'(改行文字)として扱ってほしいとプログラムに指定してるのである
なので、リストA = [1, 2, 3]があるとしたら、sep='\n'は、A = [1'\n'2'\n'3'\n']となっている
また、リストの前に*がついているが、これはリストを1つ1つ渡す作業を一括で行ってくれる機能になっている
なので、リストA = [1, 2, 3]があるとしたら、*Aは、1 2 3となっている
これら2つを組み合わせることで、for文を使わずに計算結果を1行ごとに出力することができる
※今回のリストを半角空白ごとに出力する(1 2 3のような出力結果にしたい)場合は、sepのところを削除すると良い
EX14 ~ 三人兄弟の身長差 ~
この問題を解いていく
A, B, C = map(int, input().split()) minimum = min(A, B, C) maximum = max(A, B, C) print(maximum - minimum)
EX14の補足
Pythonには元々最大値・最小値を求める関数があるので、それを使うことで今回の問題は簡単に解くことができる
max(): ()内に指定された変数・リストの中の最大値を返してくれる
min(): ()内に指定された変数・リストの中の最小値を返してくれる
EX15 ~ 三人兄弟へのプレゼント ~
この問題を解いていく
N = int(input()) A = sum(list(map(int, input().split()))) B = sum(list(map(int, input().split()))) C = sum(list(map(int, input().split()))) print(A * B * C)
EX15の補足
Pythonには元々合計を求める関数があるので、それを使うことで今回の問題は簡単に解くことができる
sum(): ()内に指定された変数・リストの合計を返してくれる
AtCoder Programming Guide for beginners(APG4b) 第2章のEX問題をPythonで解く
AtCoder Programming Guide for beginners(APG4B) EX16 ~ EX26の回答
~ AtCoder 300代の貧弱プログラマが脳筋コードでとくAPG4B
概要
なぜEX16 ~ 26の範囲なのか?
APG4BをPythonで解いてみたサイトを見てみたが、EX16 ~ EX21までしか解かれているものがなかったため
自分で解いたほうが早くね??と考えたのが始まり
まぁ、ごちゃごちゃいうよりさっさと解いていく
EX16 - 隣り合う同じ値を探す -
この問題を解いてく
// Aの値をlist型で受け取る
A = list(map(int, input().split()))
// Aの要素数-1回だけループする
for i in range(len(A) - 1):
// リストAのi番目の要素とi+1番目の要素が等しいか判定する
if A[i] == A[i+1]:
// 隣り合う同じ値があったためYESを出力する
print("YES")
// プログラムを終了させる
exit()
// 隣り合う同じ値がなかったためNOを出力する
print("NO")
EX16の補足
for文のrangeをAの配列の要素数-1回分ループしているが、問題は5つの要素で固定しているため、
A = list(map(int, input().split()))
for i in range(4):
if A[i] == A[i+1]:
print("YES")
exit()
print("NO")
でも大丈夫である。
※ もう少し簡略化して書くとするならば、
A = list(map(int, input().split()))
// 隣り合う同じ値が1組でも存在すればTrueを返す
flag = any(A[i] == A[i+1] for i in range(4))
if flag:
print("YES")
else:
print("NO")
と書くこともできる。
EX17 ~ 果物屋さんでお買い物
この問題を解いていく
// N, S の値を受け取る
N, S = map(int, input().split())
// Aの値をlist型で受け取る
A = list(map(int, input().split()))
// Pの値をlist型で受け取る
P = list(map(int, input().split()))
// Sと同じ値段になった組み合わせの個数をカウントする変数
count = 0
for a in A:
for p in P:
// (aの値段 + pの値段) が 指定された値段Sと等しいか判別する
if a + p == S:
// 同じの場合カウントを1増やす
count += 1
// カウントを出力する
print(count)
EX17の補足
EX16ではfor i in range(指定範囲)を使っていたが、リストから直接値を受け取ることができるため、for i in リスト名を使うこともできる。
※ 今回は例として i を使っているが、 i の部分は任意の変数名で大丈夫である
EX18 ~ ゲーム大会 ~
この問題を解いていく
NとMの値を受け取る
N, M = map(int, input().split())
l = []
// N行N列のリストlの初期化を行う
for i in range(N):
tmp = []
for j in range(N):
tmp.append('-')
l.append(tmp)
// M試合文ループする
for _ in range(M):
// A, Bの値を受け取る
A, B = map(int, input().split())
// リストlのA-1行B-1列目をoにする
l[A-1][B-1] = 'o'
// リストlのB-1行A-1列目をxにする
l[B-1][A-1] = 'x'
// N行N列分ループする
for i in range(N):
for j in range(N):
// i行目の最後の要素ではないか判別する
if j != N - 1:
// i行目の最後の要素ではない場合 -> リストlのi行j列目の要素と空白文字を出力する
print(l[i][j], end=' ')
else:
// i行目の最後の要素の場合 -> リストlのi行j列目の要素を出力して改行する
print(l[i][j])
EX18の補足
この問題は簡略化することができる。以下が簡略したコードである
N, M = map(int, input().split()) // リスト内包表記を使用したリストlの初期化 l = [['-' for _ in range(N)] for _ in range(N)] for _ in range(M): A, B = map(int, input().split()) l[A-1][B-1] = 'o' l[B-1][A-1] = 'x' for l_i in l: // リストを空白文字つきで出力する print(*l_i)
Pythonリスト内包表記の使い方を参考にすると良い
print文で使用している記法は、例えば以下のリスト
arr = [1, 2, 3, 4, 5]
があったとする。この時print(*arr)を実行すると、
1 2 3 4 5
と出力される。しかも最後の要素の後ろには空白文字は出力されないため覚えておくといいだろう
EX19 ~ 九九の採点 ~
この問題を解いていく
// リストarrに2次元配列の入力を受け取る
arr = [list(map(int, input().split())) for _ in range(9)]
// 正解数をカウントする変数を宣言
correct_cnt = 0
// 不正解数をカウントする変数を宣言
wrong_cnt = 0
// 九九なので9 × 9 回ループする
for i in range(1, 10):
for j in range(1, 10):
// arrのi行j列目の値がi×jと等しいか判別する
if arr[i-1][j-1] == i * j:
// 等しい場合は正解数を1増やす
correct_cnt += 1
else:
// 違う場合は不正解数を1増やす
wrong_cnt += 1
// 間違っていた場所を正しい値に変更する
arr[i-1][j-1] = i*j
// 正しい九九表を出力する
for a in arr:
print(*a)
// 正解数を出力する
print(correct_cnt)
// 不正解数を出力する
print(wrong_cnt)
EX19の補足
最初この問題を解いた時、
arr = [list(map(int, input().split())) for _ in range(9)]
correct_cnt = 0
wrong_cnt = 0
correct_arr = []
for i in range(1, 10):
tmp_arr = []
for j in range(1, 10):
tmp_arr.append(i*j)
if arr[i-1][j-1] == i * j:
correct_cnt += 1
else:
wrong_cnt += 1
correct_arr.append(tmp_arr)
for ca in correct_arr:
print(*ca)
print(correct_cnt)
print(wrong_cnt)
以上のコードのように新しい配列(リスト)に九九を入れて出力していたが、問題文を見てみると、誤った値が書き込まれたマスを正しい値に書き直す とあるため、新しく配列を生成するのではなく元の配列を更新する形に変更した。
EX20 ~ 報告書の枚数 ~
この問題を解いていく
def count_report_num(children, x):
if children.get(x) == None:
return 1
sum = 0
for c in children[x]:
sum += count_report_num(children, c)
sum += 1
return sum
N = int(input())
arr = list(map(int, input().split()))
p = [-1]
for i in range(1, N):
p.append(arr[i-1])
key = list(dict.fromkeys(p))
children = {}
for i in key:
value_list = []
for j in range(N):
if i == p[j]:
value_list.append(j)
children[i] = []
for k in value_list:
children[i].append(k)
for i in range(N):
print(count_report_num(children, i))
EX20の補足
今回の問題は解答が思いつかなかっため、C++の回答例を参考にPythonコードに起こした。
EX21 ~ 計算量の見積もり ~
この問題を解いていく
def f0(N):
return 1
def f1(N, M):
s = 0
for i in range(N):
s += 1
for i in range(M):
s += 1
return s
def f2(N):
s = 0
for i in range(N):
t = N
cnt = 0
while (t > 0):
cnt += 1
t //= 2
s += cnt
return s
def f3(N):
s = 0
for i in range(3):
for j in range(3):
s += 1
return s
def f4(N):
s = 0
for i in range(N):
for j in range(N):
s += i + j
return s
def f5(N, M):
s = 0
for i in range(N):
for j in range(M):
s += i + j
return s
N, M = map(int, input().split())
a0, a1, a2, a3, a4, a5 = -1, -1, -1, -1, -1, -1
// 計算量が多いものをコメントアウトする
a0 = f0(N)
a1 = f1(N, M)
a2 = f2(N)
a3 = f3(N)
# a4 = f4(N)
# a5 = f5(N, M)
print(f'f0: {a0}')
print(f'f1: {a1}')
print(f'f2: {a2}')
print(f'f3: {a3}')
print(f'f4: {a4}')
print(f'f5: {a5}')
EX21の補足
Pythonは107までは計算できるが、108になるとTLEが出てしまうので注意が必要
計算量
- f0の場合 : O(1) = 1 のため、TLEが出る事はない
- f1の場合 : O(N + M) = 106 + 102 < 108 のため、TLEが出る事はない
- f2の場合 : O(NlogN) = 106 * log106 ≒ 106 * 2 * 101 < 108のため、 TLEが出る事はない
- f3の場合 : O(1) = 1 のため、 TLEが出る事はない
- f4の場合 : O(N2) = 106 * 106 > 108 のため、TLEが出る
- f5の場合 : O(NM) = 106 * 102 = 108 のため、TLEが出る
基本的にAtCoderではO(N2)の計算量になるとTLEが出ると考えていいだろう
ただしN<104 程度だとO(N2)でもTLEが出る事はほとんどない(<108になるため)
そのため入力上限を見て適宜計算量を考えていこう
EX22 ~ 2つ目の値でソート ~
この問題を解いていく
N = int(input()) // リスト型とリスト内包表記を使用して二次元配列を作成する arr = [list(map(int, input().split())) for _ in range(N)] // lambda(無記名関数)を使用して、リストの2番目の要素でソートをかける arr = sorted(arr, key=lambda x: x[1]) for a in arr: print(*a)
EX22の補足
lambda式と呼ばれる無記名関数を使用して2番目の要素でソートをかけた
Pythonのlambda(ラムダ式、無名関数)の使い方を参考にすると良いだろう
sorted()は()内に指定されたlistやsetなどをソートした配列を返す関数となっている
同様の処理を行うsort()があるが、こちらはもとのlistやsetをソートする関数となっている
Pythonでリストをソートするsortとsortedの違いを参考にすると良いだろう
ちなみに、sortの計算量はO(NlogN)となっている
EX23 ~ 最頻値 ~
この問題を解いていく
// collectionsライブラリからCounterメソッドをインポート from collections import Counter N = int(input()) arr = list(map(int, input().split())) arr = Counter(arr) arr = sorted(arr.items(), key=lambda x: x[1], reverse=True) print(*arr[0])
EX23の補足
今回は頻度を数えるためにcollectionsライブラリからCounterメソッドをインポートした
PythonのCounterでリストの各要素の出現個数をカウントを参考にすると良いだろう
sorted()の中でreverse=Trueを入れることで降順で並び替えることができる
EX24 ~ 時計の実装 ~
この問題を解いていく
// Clockクラスを定義する
class Clock:
// Clockオブジェクトを生成した際に自動的に実行される
def __init__(self):
self.hour = 0
self.minute = 0
self.second = 0
// 時間を設定する
def set(self, h, m, s):
self.hour = h
self.minute = m
self.second = s
// HH:MM:SS表記にする
def to_str(self):
time = f'{self.hour:02d}:{self.minute:02d}:{self.second:02d}'
return time
// 時間を進めたり戻したりする
def shift(self, diff_second):
multiple = 1
if diff_second < 0:
multiple = -1
diff_second *= multiple
diff_hour = int(diff_second / (60 * 60))
diff_minute = int((diff_second / 60) % 60)
diff_second = diff_second % 60
if multiple > 0:
self.second += diff_second
if self.second >= 60:
self.second -= 60
self.minute += 1
self.minute += diff_minute
if self.minute >= 60:
self.minute -= 60
self.hour += 1
self.hour += diff_hour
if self.hour >= 24:
self.hour -= 24
else:
self.second -= diff_second
if self.second < 0:
self.second += 60
self.minute -= 1
self.minute -= diff_minute
if self.minute < 0:
self.minute += 60
self.hour -= 1
self.hour -= diff_hour
if self.hour < 0:
self.hour += 24
h, m, s = map(int, input().split())
diff_second = int(input())
clock = Clock()
clock.set(h, m, s)
print(clock.to_str())
clock.shift(diff_second)
print(clock.to_str())
EX24の補足
文字列に変数の値を組み込むときにformatを指定している
またその際に、0埋めを行っている
Pythonで文字列・数値をゼロ埋め(ゼロパディング)を参考にすると良いだろう
さらに、今回はClockクラスを定義している
EX25 ~ 集合の操作 ~
この問題を解いていく
N = int(input()) A = set(map(int, input().split())) M = int(input()) B = set(map(int, input().split())) op = list(input().split()) if len(op) > 1: x = int(op[1]) command = op[0] if command == 'intersection': print(* (A & B)) elif command == 'union_set': print(* (A | B)) elif command == 'symmetric_diff': print(* (A ^ B)) elif command == 'subtract': A.remove(x) print(*A) elif command == 'increment': A = list(map(lambda a: a + 1 - 50 if a + 1 >= 50 else a + 1, A)) print(*sorted(A)) elif command == 'decrement': A = list(map(lambda a: a - 1 + 50 if a - 1 < 0 else a - 1, A)) print(*sorted(A))
EX25の補足
setが持っている操作を使えばいいだけなのでそこまで補足するものはないと思う
Python, set型で集合演算(和集合、積集合や部分集合の判定など)を参考にすると良いだろう
EX26 ~ 電卓を作ろう ~
この問題を解いていく
from collections import defaultdict
# command = int
def cmd_int(cmd, intdict):
num = 0
op = cmd[1]
i = 1
while True:
if i == len(cmd) or cmd[i] == ';':
break
if cmd[i] == '+':
if cmd[i+1] in intdict:
num += intdict[cmd[i+1]]
i += 2
else:
num += int(cmd[i+1])
i += 2
elif cmd[i] == '-':
if cmd[i+1] in intdict:
num -= intdict[cmd[i+1]]
i += 2
else:
num -= int(cmd[i+1])
i += 2
elif cmd[i] in intdict:
num += intdict[cmd[i]]
i += 1
elif cmd[i].isdecimal():
num += int(cmd[i])
i += 1
else:
i += 1
return op, num
# command = vec
def cmd_vec(cmd, vecdict, intdict):
vec = []
op = cmd[1]
ops = []
vec_list = []
for i in range(1, len(cmd)):
tmp = []
if cmd[i] == ';':
break
if cmd[i] == '[':
for j in range(i, len(cmd)):
if cmd[j] == ']':
i = j
vec_list.append(tmp)
break
elif cmd[j] == ',' or cmd[j] == '[':
continue
elif cmd[j] in intdict:
tmp.append(intdict[cmd[j]])
else:
tmp.append(int(cmd[j]))
elif cmd[i] in vecdict:
vec_list.append(vecdict[cmd[i]])
elif cmd[i] == '+' or cmd[i] == '-':
ops.append(cmd[i])
if ops == []:
return op, vec_list[0]
i, j = 0, 0
res = []
while True:
if i == len(vec_list):
break
if i == 0:
if ops[j] == '+':
res = [x + y for (x, y) in zip(vec_list[i], vec_list[i+1])]
i += 2
j += 1
elif ops[j] == '-':
res = [x - y for (x, y) in zip(vec_list[i], vec_list[i+1])]
i += 2
j += 1
else:
if ops[j] == '+':
res = [x + y for (x, y) in zip(res, vec_list[i])]
i += 1
j += 1
elif ops[j] == '-':
res = [x - y for (x, y) in zip(res, vec_list[i])]
i += 1
j += 1
return op, res
# command = print_int
def cmd_print_int(cmd, intdict):
num = 0
i = 1
while True:
if i == len(cmd) or cmd[i] == ';':
break
if cmd[i] == '+':
if cmd[i+1] in intdict:
num += intdict[cmd[i+1]]
i += 2
else:
num += int(cmd[i+1])
i += 2
elif cmd[i] == '-':
if cmd[i+1] in intdict:
num -= intdict[cmd[i+1]]
i += 2
else:
num -= int(cmd[i+1])
i += 2
else:
if cmd[i] in intdict:
num += intdict[cmd[i]]
i += 1
else:
num += int(cmd[i])
i += 1
print(num)
# command = print_vec
def cmd_print_vec(cmd, vecdict, intdict):
vec_list = []
ops = []
for i in range(1, len(cmd)):
tmp = []
if cmd[i] == ';':
break
if cmd[i] == '[':
for j in range(i, len(cmd)):
if cmd[j] == ']':
i = j
vec_list.append(tmp)
break
elif cmd[j] == ',' or cmd[j] == '[':
continue
elif cmd[j] in intdict:
tmp.append(intdict[cmd[j]])
else:
tmp.append(int(cmd[j]))
elif cmd[i] in vecdict:
vec_list.append(vecdict[cmd[i]])
elif cmd[i] == '+' or cmd[i] == '-':
ops.append(cmd[i])
i, j = 0, 0
res = []
if ops == []:
print('[ ', end='')
print(*vec_list[0], end='')
print(' ]')
return
while True:
if i == len(vec_list):
break
if i == 0:
if ops[j] == '+':
res = [x + y for (x, y) in zip(vec_list[i], vec_list[i+1])]
i += 2
j += 1
elif ops[j] == '-':
res = [x - y for (x, y) in zip(vec_list[i], vec_list[i+1])]
i += 2
j += 1
else:
if ops[j] == '+':
res = [x + y for (x, y) in zip(res, vec_list[i])]
i += 1
j += 1
elif ops[j] == '-':
res = [x - y for (x, y) in zip(res, vec_list[i])]
i += 1
j += 1
print('[ ', end='')
print(*res, end='')
print(' ]')
# main部分
N = int(input())
intdict = defaultdict(int)
vecdict = defaultdict(int)
for _ in range(N):
cmd = input().split(' ')
if cmd[0] == 'int':
op, num = cmd_int(cmd, intdict)
intdict[op] = num
elif cmd[0] == 'vec':
op, vec = cmd_vec(cmd, vecdict, intdict)
vecdict[op] = vec
elif cmd[0] == 'print_int':
cmd_print_int(cmd, intdict)
elif cmd[0] == 'print_vec':
cmd_print_vec(cmd, vecdict, intdict)
EX26の補足
この問題は基本的に今までの知識の総復習のようなものと考えて良いだろう
今回の解くコツとして、最小の機能ごとに作っていくことが重要である
今回の場合
- 変数を出力する機能
- 配列を出力する機能
- 変数を定義(計算)する機能
- 配列を定義(計算)する機能
この4つの機能を段階的に実装すれば良かった
今回自分が書いたコードには、同じような処理をするところがあったりしたので、そこをさらに関数として切り分けた方が簡潔になる
そうすることによって、
- コードの総量が減り、見やすくかつ管理がしやすくなる
- コードを打つ量が減るため、負担が減る
- 間違っていた場合の手間が減る
などのメリットがあるため、繰り返す処理がある場合は関数化した方が良いと思う(個人の感想なので人それぞれ組みやすいコードを組む方が良い)
補足2
ただ、今までに紹介していなかったcollectionsライブラリのdefaultdictについて少し紹介する
このdefaultdictは存在しないキーがあってもデフォルト値が返ってくる辞書型風のデータ構造である
使い方の例
from collections import defaultdict
# デフォルトの型をint型にする
d1 = defaultdict(int)
print(f'd1: {d1[0]}') # => d1: 0
d2 = defaultdict(lambda : 100)
print(f'd2: {d2[1]}') # => d2: 100
詳しい使い方はPython defaultdict の使い方を参考にすると良いだろう
zip関数とリスト内包表記を使うことで、2つのリストで演算を行うことができる
その例
li1 = [1, 2, 3] li2 = [4, 5, 6] add_li1_li2 = [x + y for (x, y) in zip(li1, li2)] // li1の要素とli2の要素の足し算 print(add_li1_li2) // => [5, 7, 9] mul_li1_li2 = [x * y for (x, y) in zip(li1, li2)] // li1の要素とli2の要素の掛け算 print(mul_li1_li2) // => [4, 10, 18]
もっと詳しく知りたい -> 【python】リスト(list)の要素の四則演算、平均の計算方法【要素ごと、zip、map、lambda】を参考にすると良いだろう