筋トレ

会社帰りにジムに寄って、機械使って筋トレしてたところ、トレーナーさんに声かけてもらって、正しい機械の使い方とかを教えてもらった。筋肉をつけるならば20回30回とかやらなくて良くて、できるかギリギリの重さで10回くらいやればokらしい。

ということは、全体で30分くらいでひととおり廻れるかも、という発見。会社帰りに立ち寄るのは時間遅くなるし結構めんどくさいのでこれは朗報です。人見知り発揮してなかなか聞けないんですが、プロの話は聞くものですね~。

Human Resource Machine

play.google.com

ここ最近「Human Resource Machine」というスマホゲーをやっていて、ついこの間クリアしました。プログラミングの要素をうまいことゲームに落とし込んでいて、おもしろかったです。後半はソートとか出てきて割とガチでプログラミング組まなきゃいけなくて、プログラミング経験がないとちょっと難しいかもしれません。(短手数クリアはプログラマでも難しい...!)

 

またストーリーもあります。主人公は新入社員として入社して、1問クリアすることに1年経過する設定になってるんですが、全部で40問近くあるので最後のほうにはビジュアルも変わっておじさん(or おばさん)になります。だんだん頭が薄くなっていったりして、それが非常に哀愁を誘います…。

約40年、一途にお仕事をつづけた結果、主人公がどうなるのか…気になる方はやってみてください。

Tenka1 Programmer Beginner Contest

tenka1-2019-beginner.contest.atcoder.jp
2完。40分遅れで始めたとはいえCが解けなかったのが悔しい。。左が白、右が黒の並びになればいいところまではわかったけど、ロジックに穴がありWA食らいました。もうちょいサンプル欲しかったなぁという負け惜しみ。

Cは左側が白、右側が黒というように分かれればよくて、[0, i)までを白領域、[i, N)までを黒領域(i == 0なら全部黒、i == Nなら全部白)とすると、「白領域の黒の数と黒領域の白の数の和」がひっくり返せばいい数になるので、あとはiを[0, N]まで動かして最小値を探索すればok。前回使った累積和が出てきたけど見事に活用できなかったな。

N = int(input())
S = input()

cum_sum_b = [0]
cum_sum_w = [0]

sum_b = 0
sum_w = 0
for i, s in enumerate(S):
    if s == '#':
        sum_b += 1
    else:
        sum_w += 1
    cum_sum_b.append(sum_b)
    cum_sum_w.append(sum_w)

ans = N
for i in range(0, N + 1):
    count = cum_sum_b[i] + cum_sum_w[N] - cum_sum_w[i]
    ans = min(ans, count)

print(ans)

Pythonで、多分こんな雰囲気。


Dは解説聞かないと正直解ける気しなかったです。
解き方は解説動画に任せて式の立て方としては、
i = 0...N, j = 0...{a0...aNの総和s}として、
R == j で残りはGorBで塗る組み合わせの数(dp0)と、R == jで残りはGで塗る組み合わせの数(dp1)をそれぞれDPで出し、
dp0からR>=sの時の組み合わせの数、dp1からR==G==s/2の時の組み合わせの数がわかるので、そこから答えを求める
という感じのよう。

import math

N = int(input())
a = [int(input()) for _ in range(N)]
s = sum(a)

# Calculate counts of (R >= s / 2)
dp = [[0 for _ in range(s + 1)] for _ in range(N + 1)]
for i in range(N + 1):
    for j in range(s + 1):
        if i == 0:
            dp[i][j] = 1 if j == 0 else 0
        else:
            dp[i][j] = dp[i - 1][j] * 2 + (dp[i - 1][j - a[i - 1]] if j >= a[i - 1] else 0)
c0 = sum(dp[N][math.ceil(s / 2):])

# Calculate counts of (R == s / 2 and G == s / 2)
dp = [[0 for _ in range(s // 2 + 1)] for _ in range(N + 1)]
for i in range(N + 1):
    for j in range(s // 2 + 1):
        if i == 0:
            dp[i][j] = 1 if j == 0 else 0
        else:
            dp[i][j] = dp[i - 1][j] + (dp[i - 1][j - a[i - 1]] if j >= a[i - 1] else 0)
c1 = dp[N][s // 2] if s % 2 == 0 else 0

ans = (3 ** N - 3 * c0 + 3 * c1) % 998244353
print(ans)

ただこれだとTLEするPythonには辛い仕様で、通すにはnumpy芸が必要なよう。

import math
import numpy as np

N = int(input())
a = np.array([int(input()) for _ in range(N)])
s = np.sum(a)

dp0 = np.zeros((N + 1, s + 1), dtype=np.int64)
dp0[0, 0] = 1
dp1 = np.zeros((N + 1, s // 2 + 1), dtype=np.int64)
dp1[0, 0] = 1

mod = 998244353
for i, x in enumerate(a):
    dp0[i + 1, :] += dp0[i, :] * 2 % mod
    dp0[i + 1, x:] += dp0[i, :-x] % mod
    dp1[i + 1, :] += dp1[i, :] % mod
    dp1[i + 1, x:] += dp1[i, :-x] % mod

# Counts of (R >= s / 2)
c0 = int(np.sum(dp0[N][math.ceil(s / 2):]))
# Counts of (R == s / 2 and G == s / 2)
c1 = int(dp1[N][s // 2]) if s % 2 == 0 else 0

ans = (3 ** N - 3 * c0 + 3 * c1) % mod
print(ans)

こんな感じにすればいけそう。マイナスのインデックスが慣れないですが、リストの長さ-xと同じですね。
numpyも慣れないといけないけど、なかなかむずい。。

ABC124

atcoder.jp

3完。Dのテストケースで1個だけWA出て死亡。。変に分岐複雑にしちゃったからどこかミスってるんだろうけど結局どこかわからなかったです。ウボァ

ある数列があって、その[l, r)の区間の和を求めたい場合は累積和(Cumulative sum)を使う。

nums = [1, 2, 3, 4, 5] # 適当な数列
cum_sums = [0]
for i in range(len(nums)):
    cum_sums.append(cum_sums[i] + nums[i])

l = 1
r = 4
ans = cum_sums[r] - cum_sums[l]
print(ans) # => 9 (2 + 3 + 4)

Pythonだとこんな雰囲気。

ABC123

atcoder.jp

参加しました。A-Cは解けてDが解けず。。

Dは、全探索するとTLEになるのでうまく枝刈りをしようという問題。解説されると単純だけど、この辺は慣れも必要そう。

別の解き方として、候補をPriority Queueにつっこんで、大きい方から出して答えに追加していくというもの。この考え方のパターンは別の問題でも使えそうです (ダイクストラ法がこんな感じ)。

 

1年近くサボったせいで緑まで落ちちゃったので、水色復活してABC全部解けるくらいまではもう少し頑張ろうかな。あと覚えたことを忘れないように今回、前回のように日記に書いてこうと思う...。

HELLO, DESIGN

前の記事で企画書を10分で書けという内容の本を読みましたが、もう少し具体的に商品を作る上での設計のノウハウみたいなのを知りたいと思い、「HELLO, DESIGN」という本を読んでみました。帯に「デザインはみんなのものだ」と書かれてますが、この本も前回の本と同様、特別な能力がなくてもできるんだというスタンスで書かれてそうなのが気に入って選びました。

HELLO,DESIGN 日本人とデザイン (NewsPicks Book)
 

 

 前回の「企画」の定義と同様、この本も「デザイン」を「課題の解決のために行うこと」のように定義しており、自分の認識が補われるような感じで素直に読み進めることができました。前の本に比べると、より会社やチームで動くときのノウハウや必要なマインドが説明されていて、これはこれでためになりました。

 これまで企画やデザインって自分の中で正解がわからないし、ロジカルに組み立てられる基準とかがなくて、確信がないからあまり意見も出しづらいというのがあったんですが、そのあたりが少し晴れた気がします。本はなんでもいいと思うんですが、エンジニアもこのあたり、かじっておいて損はなさそうだと思いました。