2023年の振り返り

恒例の、年末の雑な振り返り。

法人化して4年が経った

  • 会社が存続できていることは感謝しかない🙏

仕事について

  • 今年もメインとしてはウェブサイトの制作・更新など。今年も色々とやったなぁ。楽しかった。
  • Podcast制作支援などをしているPitPaさんのロゴリニューアルをさせてもらえて、とっても嬉しかった。
  • Kaigi on Rails 2023のお仕事ができて楽しかった。


  • タイポグラフィ年鑑は今年も出してたんだけどダメだった。うーん行けると思ったんだけどな、悔しい。継続してやっていく。
  • 下に書くけど、来年はフィヨルドブートキャンプが佳境になると思われる(そうしたい)ので、それ自体が忙しくなりそうなことに加えて、「その後どうしていくか」というのを少しずつ定めていきたい。

フィヨルドブートキャンプ(FBC

  • 2021年秋から入会したプログラミングスクール、フィヨルドブートキャンプ
  • 今年も頑張った。でも思うように進まない時期もあった。ざっくり計算すると今年も450時間くらいやったかな?
  • 昨年末、2023年に卒業したいとか書いてたけど、とてもじゃないが無理だった😂
  • 来年いっぱいで卒業というのが現実的かつ必達としたいところ。できればもうちょっと早くにしたいが…。
  • 輪読会に参加するようになって、仲間が増えた気がする。
  • オフラインイベントにも参加したし登壇もした。


記録と発信

  • scrapboxでの日記をずっと継続して書いている
    • https://scrapbox.io/sugie/
    • junebokuさんがやっている Nikki Hub というプロジェクト?にも参加して、8〜9割くらいの日は登録したかな?junebokuさんやtaizoooさんなど他の方の日記もかなり読んでて、面白かった
  • しずかなインターネットを始めた
    • https://sizu.me/sugie
    • 上述のscrapboxが俺のしずかなインターネットだけど、こっちも好き。猫と料理のことを投稿している
  • Podcastを始めた

生活

  • 早朝生活は継続。
    • そろそろ娘の寝る時間も遅くなってくるし、再来年の4月から娘が自分の部屋を持つという話になっている。そうなるとこれまでの早寝が継続できるか微妙になってくる可能性がある
  • ちょこざっぷを始めたけど、お金の都合もあり秋にやめてしまった。
  • 今も朝にウォーキングをしているが、体を動かすのがほぼそれだけなので、もう少し運動しないといけないなと思っている。
  • 上でも書いたけど、scrapbox日記を1年以上継続できて大変嬉しい。日付タグをつけることで1年前の同日の日記リンクが表示されるので、1年前の日記に毎日邂逅できているのが楽しい。
  • 今年は週末に料理をすることが増えた。もっとレポートリーを増やしたいし、今はレシピを見て必要なものを揃えて作る、という幹事なので、もう少し冷蔵庫の中を見て「これとこれがあるからこれ作るかー」みたいなことをできるようになりたい。

総括と2024年

  • 2023年も、家族・仕事・プログラミング学習と充実してあっという間の1年だった。
    • 去年とほとんど同じこと書いてるな、、、
  • 今年は本厄だったけど、無事過ごすことができた。ありがたい。
  • 2024年のお仕事について。来年はまだ過渡期というか、これまでの流れのお仕事はしっかりやりながら、2025年に新しい芽が出るような動きを2024年は始めていきたい。できるかな?
  • 2024年の生活について。これまで通り、ライフワークバランスを保ちながら家族仲良く過ごしていきたい。
  • もーちょい本を読みたい
  • もーちょい英語を勉強したい
  • ドラム叩きたい
  • 誰かとの雑談Podcastもやりたい

【Ruby基礎】AtCoder Beginner Contest 080 A - Parking

■はじめに

Rubyの基礎的な問題をたくさん解くことで基本的な考え方やメソッドの使い方を定着させたい。 基本的にはAtCoderというプログラミングコンテスト競技プログラミング)の過去問を使う。(AtCoderは難易度が分かれており、難易度の低いA問題かB問題を解いていく)

(5/23時点の方針) メソッドの切り分け方や値の受け渡しを練習するために、コード長の短さについては気にせずに書くことにする。

(2022/10/17時点の方針) しばらくはB問題を小さい番号の方からやっていく。たまにA問題もやるかも。

(2023/11/10メモ) 忙しさにかまけて半年くらい空いてしまった。またA問題からやっていく。

■問題

●出典

AtCoder Beginner Contest 080のA問題 https://atcoder.jp/contests/abc080/tasks/abc080_a

●問題文

駐車場があり、以下の二種類のプランのどちらかを選んで駐車できます。

  • プラン 1 : T 時間駐車した場合、A×T 円が駐車料金となる。
  • プラン 2 : 駐車した時間に関わらず B 円が駐車料金となる。

N 時間駐車するとき、駐車料金は最小でいくらになるか求めてください。

●制約

  • 1≦N≦20
  • 1≦A≦100
  • 1≦B≦2000
  • 入力は全て整数

●入力

入力は以下の形式で標準入力から与えられる。

N 
A 
B

●出力

駐車料金が最小で x 円のとき、x を出力せよ。

■回答

●愚直に書く

n*abの小さいほうが解答、ということかな。

n, a, b = gets.split.map(&:to_i)
puts [n*a, b].min

通った!

●メソッド化して書く

メソッドを作る練習のために、あえてそういう書き方をする。 久しぶりなのでやっておくか…! (↑っていう記載が2023/6/22の投稿にもあった汗)

メインメソッド、小さい方を出すメソッド、標準入力を取得するメソッドの3つを作成。

def main
  n, a, b = read_nums
  puts show_min(n, a, b)
end

def show_min(n, a, b)
   [n * a, b].min
end

def read_nums
  gets.split.map(&:to_i)
end

main

通った!

●11/13追記

juneboku さんにアドバイスをいただきました、いつも大感謝…!🙏

  • show_min メソッドについて、表示は行っていないので show って言わない方がよさそう

→確かに、showしてないなぁと思いました😂 小さい方を「判定」しているのでjudge_minくらいかな…!

リファクタリング/別アプローチ

もっと短い書き方あるのかな。 ちょっと思いつかないのでパス。

●他の方の回答例

改行やスペースを省いているかどうかの違いだけで、上位の皆さんも全員同じでした。

●出てきたメソッド等

公式リファレンスを見る訓練。

■振り返りなど

久しぶりで標準入力の取り方も忘れていた。 また定期的にやっていきたい。

【Ruby基礎】AtCoder Beginner Contest 032 B - 高橋君とパスワード

■はじめに

Rubyの基礎的な問題をたくさん解くことで基本的な考え方やメソッドの使い方を定着させたい。 基本的にはAtCoderというプログラミングコンテスト競技プログラミング)の過去問を使う。(AtCoderは難易度が分かれており、難易度の低いA問題かB問題を解いていく)

(5/23時点の方針) メソッドの切り分け方や値の受け渡しを練習するために、コード長の短さについては気にせずに書くことにする。

(2022/10/17時点の方針) しばらくはB問題を小さい番号の方からやっていく。たまにA問題もやるかも。

■問題

●出典

AtCoder Beginner Contest 032のB問題 https://atcoder.jp/contests/abc032/tasks/abc032_b

●問題文

高橋君の会社には、秘密の金庫があります。この金庫にはパスワードをかけているのですが、高橋君はそのパスワードを忘れてしまいました。 しかし、幸運なことに、手元にはパスワードのヒントが以下のように書かれていました。

  • パスワードは、この紙に書かれている文字列 s の長さ k の部分文字列(※)のどれかである。

高橋君は、ありうるパスワードを全部試せば金庫を開けられる!と喜びました。 しかし、文字列 s はとても長い可能性があるし、しかも同じ部分文字列が複数個文字列 s 中に存在する可能性もあります。明らかに、重複したパスワードを繰り返し試す必要はありません。 そこで、手動で全てのパスワードを試す前に、試す必要がある異なるパスワードの数がいくつあるかを数えることにしました。

あなたの仕事は、文字列 s の内容が与えられるので、試す必要がある異なるパスワードの数がいくつあるかを高橋君に教えてあげることです。

(※)文字列 s の「部分文字列」とは、文字列 s に含まれるある区間を取り出した文字列のことです。 例えば、abc の部分文字列として a,b,c,ab,bc,abc などが挙げられます。 acba などは部分文字列ではないことに注意してください。

●入力

入力は以下の形式で標準入力から与えられる。

s
k
  • 1 行目には、ヒントの紙に書かれている文字列 s(1≦∣s∣≦300) が与えられる。s は英小文字(a-z)のみから成る。∣s∣ は文字列 s の長さを表す。
  • 2 行目には、パスワードとしてありうる整数 k(1≦k≦300) が与えられる。 k は ∣s∣ よりも大きいことがある。

●出力

出力は以下の形式で標準出力に行うこと。 1 行目に、パスワードとして考えられる文字列の数を出力せよ。末尾の改行を忘れないこと。

■回答

●愚直に書く

これは苦手なやつだ…。

標準入力としては1行目の文字列を取り、2行目の整数を取る。

その後にループ処理の中で文字列の中から必要な文字数分だけ順番に要素を取り出してそれを配列に入れていき、最後に重複を省いてカウントすれば良さそう。

と、文字で書くのは良いとしてどうやってコードに落とし込むか…。

(下記に至るまでかなりの試行錯誤があった)

ループの回数は何回だろう?初めの例から考えると、 abcabcで6文字あってその中で2文字の部分文字列を取り出すから、愚直に数え上げると['ab', 'bc', 'ca', 'ab', 'bc']を取り出す。つまり5個取り出す。 全部で6文字ある中から5個取り出す →全部の文字数 - 部分文字列の文字数 + 1、という感じか。

文字列の中から、n番目からl文字取り出すにはどうすればいいんだろう? るりまによると、self[nth, len]nth 文字目から長さ len 文字の部分文字列を新しく作って返します。とのこと。

str = gets.chomp
l = gets.to_i

array = []
(str.length - l + 1).times do |i|
  array << str[i, l]
end

puts array.uniq.size

通った!

●メソッド化して書く

メソッドを作る練習のために、あえてそういう書き方をする。 今日は割愛。

リファクタリング/別アプローチ

これも今日は割愛。 他の方の回答例から学ぶアプローチにする。

●他の方の回答例

上位の方々の回答をざっと眺めた。 ポイントは以下の2つ。

  • .cahrsで文字列を配列に分解する
  • each_consで配列の要素を重複ありで区切っていき、to_aで新しく配列にまとめる

なるほど〜。

整理した回答がこちら。

str = gets.chomp.chars
l = gets.to_i

puts str.each_cons(l).to_a.uniq.size

これで通ることを確認できた。

●出てきたメソッド等

公式リファレンスを見る訓練。

■振り返りなど

今日は難しかったけど、まずはこれくらいの難易度をモタつかずに解けるようになりたい。

【Ruby基礎】AtCoder Beginner Contest 031 B - 運動管理

■はじめに

Rubyの基礎的な問題をたくさん解くことで基本的な考え方やメソッドの使い方を定着させたい。 基本的にはAtCoderというプログラミングコンテスト競技プログラミング)の過去問を使う。(AtCoderは難易度が分かれており、難易度の低いA問題かB問題を解いていく)

(5/23時点の方針) メソッドの切り分け方や値の受け渡しを練習するために、コード長の短さについては気にせずに書くことにする。

(2022/10/17時点の方針) しばらくはB問題を小さい番号の方からやっていく。たまにA問題もやるかも。

■問題

●出典

AtCoder Beginner Contest 031のB問題 https://atcoder.jp/contests/abc031/tasks/abc031_b

●問題文

高橋君は AtCoder 社のマスコットキャラクターである。

マスコットキャラクターとしての魅力を維持するために、高橋君は適度な運動をすることになっている。高橋君は週の運動時間が L 分以上 H 分以下でなければならない。

しかしながら、青木君は最近、高橋君が運動しているところを見ていない。高橋君の運動状況が気になった青木君は、高橋君の過去 N 週間の運動時間が制限にあっているのか、そして足りないなら少なくともあと何分運動する必要があったのかを計算するプログラムを作成することにした。

●制約

  • ああああ

●入力

入力は以下の形式で標準入力から与えられる。

L H
N
A1
A2
:
AN
  • 1 行目には、2 個の整数 L, H(1≦L≦H≦10^4 ) が空白区切りで与えられる。これは、高橋君が週に L 分以上 H 分以下の運動をしなければならないことを表す。
  • 2 行目には、整数 N(1≦N≦50) が与えられる。これは青木君が N 週分の運動時間について調べていることを表す。
  • 3 行目からの N 行には、高橋君の運動状況を表す整数が与えられる。N 行の内 i(1≦i≦N) 行目には、整数 Ai (0≦Ai ≦10^4 ) が与えられる。これは i 個前の週において高橋君が Ai 分運動したことを表す。

●出力

出力は N 行からなる。i(1≦i≦N) 行目には、i 個前の週において高橋君が必要な分よりも多く運動している場合は −1 を、そうでない場合は追加で必要な運動時間の最小値を分単位で 1 行に出力せよ。 出力の末尾にも改行を入れること。

■回答

●愚直に書く

久しぶりのB問題。 まずは標準入力をちゃんと取るところから。

l, h = gets.split.map(&:to_i)
n = gets.to_i
a = n.times.map do |line|
  line = gets.to_i
end

# 以下は確認用
p l, h
p n
p a

これで標準入力は取れた。

次に、配列aの各要素がl以上h以下かどうかを判定していく感じか。

l, h = gets.split.map(&:to_i)
n = gets.to_i
a = n.times.map do |line|
  line = gets.to_i
end

a.each do |elm|
  if elm < l
    puts l - elm
  elsif elm > h
    puts -1
  else
    puts 0
  end
end

通った!

●メソッド化して書く

メソッドを作る練習のために、あえてそういう書き方をする。

メインメソッド、判定用メソッド、標準入力を取るメソッド2つの計4つ。 メインメソッド内のeachを回す部分をさらに別メソッドに分けても良いかな?

def main
  l, h = read_target
  a = read_record
  a.each do |elm|
    puts judge(l, h, elm)
  end
end

def judge(l, h, elm)
  if elm < l
    l - elm
  elsif elm > h
    -1
  else
    0
  end
end

def read_target
  gets.split.map(&:to_i)
end

def read_record
  n = gets.to_i
  n.times.map do |line|
    line = gets.to_i
  end
end

main

通った!

リファクタリング/別アプローチ

色々試したけど上手く整理できなかったので割愛…!

●他の方の回答例

maxを使った解答があり、なるほどと思った。

自分の回答に取り入れると以下のような感じ。

l, h = gets.split.map(&:to_i)
n = gets.to_i
a = n.times.map do |line|
  line = gets.to_i
end

a.each do |elm|
  if elm <= h
    puts [l - elm, 0].max
  else
    puts -1
  end
end

これだとif内がシンプルになるしそれによって三項演算子にもしやすい。なるほど。

●出てきたメソッド等

公式リファレンスを見る訓練。

■振り返りなど

計算するのにちょっと混乱してしまった。 とはいえB問題を愚直にでも解けたので良かった。

【Ruby基礎】AtCoder Beginner Contest 079 A - Good Integer

■はじめに

Rubyの基礎的な問題をたくさん解くことで基本的な考え方やメソッドの使い方を定着させたい。 基本的にはAtCoderというプログラミングコンテスト競技プログラミング)の過去問を使う。(AtCoderは難易度が分かれており、難易度の低いA問題かB問題を解いていく)

(5/23時点の方針) メソッドの切り分け方や値の受け渡しを練習するために、コード長の短さについては気にせずに書くことにする。

(2022/10/17時点の方針) しばらくはB問題を小さい番号の方からやっていく。たまにA問題もやるかも。

■問題

●出典

AtCoder Beginner Contest 079のA問題 https://atcoder.jp/contests/abc079/tasks/abc079_a

●問題文

1118 のような、3 つ以上の同じ数字が連続して並んだ 4 桁の整数を 良い整数 とします。 4 桁の整数 N が与えられるので、N が 良い整数 かどうかを答えてください。

●制約

  • 1000≦N≦9999
  • 入力は整数からなる

●入力

入力は以下の形式で標準入力から与えられる。

N

●出力

N が 良い整数 ならば Yes を、そうでなければ No を出力せよ。

■回答

●愚直に書く

えーと、1つずつ配列に入れて、要素が重複してたらまとめるようなメソッドがあった気がするのでそれをやって、まとめた後の要素数が1か2であれば大丈夫か? いや、それだと1122みたいな時もまとめた後の要素数が2になるからダメだな。。。

うーん、愚直に考えて、まず配列の要素をsortして、1番目と2番目と3番目が等しければYesってことで良いか…?

やってみよう。

n = gets.chomp.split("").map(&:to_i).sort
if n[0] == n[1] && n[0] == n[2]
  puts "Yes"
else
  puts "No"
end

通った! もうちょっとスマートな方法はありそう…!

●メソッド化して書く

メソッドを作る練習のために、あえてそういう書き方をする。

今日は割愛。

リファクタリング/別アプローチ

絶対もっとシンプルにできそう、、、

やたら試行錯誤してしまったが、sortしているので、「1番目と2番目と3番目が等しければ」ではなく1番目と3番目が等しければ」だけで今回の条件は満たせそう。

n = gets.chomp.split("").map(&:to_i).sort
if n[0] == n[2]
  puts "Yes"
else
  puts"No"
end

通った!

三項演算子にして、

n = gets.chomp.split("").map(&:to_i).sort
puts n[0] == n[2] ? "Yes" : "No"

通った!

●他の方の回答例

アッ、正規表現…! そうか正規表現でできたのか〜。 ただ、回答例を見てもどういう書き方になっているかよく掴めていない…。

puts gets[/(.)\1\1/]?:Yes: :No

/(.)\1\1/、特に\1がわからなかったのでChatGPTさんに聞いた。

なるほど、/(.)\1\1/は同じ文字が3回連続ということか。

あと以下の回答もあって、これは力技だけどわかりやすい…!

puts gets=~/111|222|333|444|555|666|777|888|999|000/ ? "Yes" : "No"

●出てきたメソッド等

公式リファレンスを見る訓練。

■振り返りなど

正規表現を思いつけず悔しかった。 あと正規表現の理解が浅く、もうちょっと勉強せねばと思った。

【Ruby基礎】AtCoder Beginner Contest 078 A - HEX

■はじめに

Rubyの基礎的な問題をたくさん解くことで基本的な考え方やメソッドの使い方を定着させたい。 基本的にはAtCoderというプログラミングコンテスト競技プログラミング)の過去問を使う。(AtCoderは難易度が分かれており、難易度の低いA問題かB問題を解いていく)

(5/23時点の方針) メソッドの切り分け方や値の受け渡しを練習するために、コード長の短さについては気にせずに書くことにする。

(2022/10/17時点の方針) しばらくはB問題を小さい番号の方からやっていく。たまにA問題もやるかも。

■問題

●出典

AtCoder Beginner Contest 078のA問題 https://atcoder.jp/contests/abc078/tasks/abc078_a

●問題文

プログラミングでは 16 進数がよく使われます。 16 進数では 0,1,...,9 の数字の他に A, B, C, D, E, F の 6 つのアルファベットを使い,それぞれ 10,11,12,13,14,15 を表します。 この問題では 2 つのアルファベット X,Y が与えられます。 X と Y はどちらも A, B, C, D, E, F のうちどれかです。 X と Y を 16 進数として見たとき,どちらのほうが大きいかを判定してください。

●制約

  • X,Y は A, B, C, D, E, F のうちどれかである。

●入力

入力は以下の形式で標準入力から与えられる。

X 
Y

●出力

X のほうが小さいならば <, Y のほうが小さいならば >, 等しいならば = と出力してください。

■回答

●愚直に書く

問題がややこしいけど、要はABCDEFの中から2文字がチョイスされてそれを比較すれば良さそう。

a, b = gets.split
if a > b
  puts ">"
elsif a < b
  puts "<"
else
  puts "="
end

通った!

●メソッド化して書く

メソッドを作る練習のために、あえてそういう書き方をする。 久しぶりなのでやってみるか…!

メインメソッド、大小記号を判定するメソッド、標準入力を取得するメソッドの3つを作成。 久しぶりすぎて忘れていたので過去投稿も参考にしつつ作成した。

def main
  a, b = read_str
  puts judge(a, b)
end

def judge(a, b)
  if a > b
    ">"
  elsif a < b
    "<"
  else
    "="
  end
end

def read_str
  gets.split
end

main

通った!

リファクタリング/別アプローチ

if文のところもうちょっとスッキリできそうな気がするけど思いつかないなぁ。 なんとなく宇宙船演算子<=>)が活かせそうな気がするんだけどうまく落とし込めない。

と思いながら過去の自分の投稿で宇宙船演算子が出てきたものを見返していたら思いついた!

a, b = gets.split
puts "=><"[a <=> b]

通った〜〜〜うれしい!!

ちなみに参照した過去記事はこちら https://sugie.co/2022/11/22/ruby-abc071a/

今回でいうと、a <=> bを評価した時に-101が返って来るので、=><という文字列のインデックス部分に[a <=> b]を入れることで下記のようになる。

  • aがbより手前の文字→宇宙船演算子-1が返る→puts "=><"[-1]なので<が出力
  • aがbと同じ文字→宇宙船演算子0が返る→puts "=><"[0]なので=が出力
  • aがbより後の文字→宇宙船演算子1が返る→puts "=><"[1]なので>が出力

●他の方の回答例

上位層はほとんど宇宙船演算子を使っていた。 三項演算子入れ子を使っている人もチラホラ。

●出てきたメソッド等

公式リファレンスを見る訓練。

■振り返りなど

久しぶりにAtCoderできて楽しかった。 宇宙船演算子を使えて嬉しかった。

【GitHub】リモートmainブランチの最新状態をローカルの作業用ブランチに取り込む

自分用のメモ。

  1. git switch mainで一旦mainブランチに移動
  2. git pullでリモートのmainを取り込む
  3. git switch branch1で作業用ブランチに移動
  4. git merge mainでmainの最新状態作業用ブランチに取り込む