Upgrade to Pro — share decks privately, control downloads, hide ads and more …

やり方は一つだけじゃない、正解だけを目指さず寄り道やその先まで自分流に楽しむ趣味プログラミング...

やり方は一つだけじゃない、正解だけを目指さず寄り道やその先まで自分流に楽しむ趣味プログラミングの探求 2025-11-15 YAPC::Fukuoka

Avatar for すぎゃーん

すぎゃーん

November 15, 2025
Tweet

More Decks by すぎゃーん

Other Decks in Technology

Transcript

  1. 自己紹介 use v5.42; use utf8; my $self = { 名前

    => ' すぎゃーん (@sugyan)', 所在 => ' 京都', 職業 => ' ソフトウェアエンジニア', 言語 => ['Perl', 'Python', 'Rust', 'Go', 'OCaml', 'TypeScript'], 趣味 => ' プログラミング', }; 2
  2. Advent of Code とは http://adventofcode.com/ Eric Wastl 氏によって運営 毎年12月に25日まで毎日出題されるパズルを解く 入力が与えられ、そこから解を導く

    2015年から開始していて昨年で10周年 自分は2019年頃から参加 日本の参加者も増えてはいるが、まだ少なめ 8
  3. Advent of Code の特徴 パズルは毎日part1とpart2があり、入力は各partで共通 part1を正解するとpart2が解放される 同じ入力に対して異なる解釈・処理をして別の解を求める 例: 2024 Day

    4。 part1は"XMAS"を、part2は交差(X)の"MAS"を探す MMMSXXMASM MSAMXMSMSA AMXSXMAAMM MSAMASMSMX XMASAMXAMM XXAMMXXAMA SMSMSASXSS SAXAMASAAA MAMMMXMMMM MXMXAXMASX 9
  4. Advent of Code の特徴 入力はユーザーごとに異なる (当然、解も異なる) 競技プログラミングと違ってparseが面倒な場合も 例: 2024 Day

    13 Button A: X+94, Y+34 Button B: X+22, Y+67 Prize: X=8400, Y=5400 Button A: X+26, Y+66 Button B: X+67, Y+21 Prize: X=12748, Y=12176 ... 10
  5. 私とAdvent of Code 回答をGitHubで公開 https://github.com/sugyan/adventofcode 主にRustで、Python, OCamlなどでも挑戦 pub trait Day

    { type Input; type Error: std::error::Error + 'static; type Answer1: Display; type Answer2: Display; fn part1(input: &Self::Input) -> Self::Answer1; fn part2(input: &Self::Input) -> Self::Answer2; } 15
  6. YAPCで発表するにあたって2024年の問題をPerlでも回答 use v5.38; use feature 'class'; class Base { field

    $fh : param; field $lines = []; field $input; ADJUST { while ( defined( my $line = <$fh> ) ) { chomp $line; push $lines->@*, $line; } } method input() { return $input //= $self->parse($lines); } method parse($lines) { return $lines; } method part1() { die "Not implemented" } method part2() { die "Not implemented" } } 16
  7. 例: 2018 Day 5 part1 大文字、小文字のアルファベットからなる長い文字列が与えられる r と R のように隣接する2文字が同じ文字で大文字/小文字が異なる

    ものを取り除く 最終的に残る文字列の長さを求める dabAcCaCBAcCcaDA -> dabAaCBAcCcaDA -> dabCBAcCcaDA -> dabCBAcaDA 18
  8. Perl Mongerなら正規表現でGolf! 効率の悪さなんて気にしない #!perl -pl s/(.)(?!\1)(?i)\1//&&redo;$_=length BEGIN { $/ =

    "\n"; $\ = "\n"; } LINE: while (defined($_ = readline ARGV)) { chomp $_; redo if s/(.)(?!\1)(?i)\1//; $_ = length $_; } continue { die "-p destination: $!\n" unless print $_; } 20
  9. 例: 2024 Day 4 part1 Pythonで2次元座標探索を複素数で実現 class Solution: def __init__(self,

    input) -> None: self.grid = { x + 1j * y: c for y, line in enumerate(input) for x, c in enumerate(line.strip()) } def part1(self) -> int: return Counter( "".join(self.grid.get(p + d * n, "") for n in range(4)) for p in self.grid for d in [1, 1 + 1j, 1j, -1 + 1j, -1, -1 - 1j, -1j, 1 - 1j] )["XMAS"] 21
  10. 例: 2024 Day 14 part2 2次元平面を動き回る点が クリスマスツリーを描く (!?) p=0,4 v=3,-3

    p=6,3 v=-1,-3 p=10,3 v=-1,2 p=2,0 v=2,-1 p=0,0 v=1,3 p=3,0 v=-2,-2 p=7,6 v=-1,-3 p=3,0 v=-1,-2 p=9,3 v=2,3 p=7,3 v=-1,2 ... 23
  11. Bitboardでの判定 各マスが空いているか埋まっているか、の状態をビットで表す 埋めるべきタイル、各ピースをそれぞれ64bit整数値で表現可能 ピースの位置移動はビットシフトで実現できる tile & piece != 0 で衝突判定可能

    00000000 00010000 000000000 00000000 00010000 000000000 00000000 00110000 000000000 00011000 00010000 000100000 00011000 & 00000000 -> 000000000 00000000 00000000 000000000 00000000 00000000 000000000 00000000 00000000 000000000 103481868288 & 271585296 == 268435456 (!= 0) 32