「def」を含む日記 RSS

はてなキーワード: defとは

2025-10-05

ピケティ理論シミュレーションして思った

インフレ率を考慮しねークソモデルだなって

import pandas as pd

def piketty_r_growth_simulation(r, g, Y_initial, K_initial, N_periods):
    """
    ピケティの r > g 理論に基づく経済シミュレーション
    
    経済規模 (Y) は g で成長。
    資本 (K) は r で成長 (ご要望の K_t+1 = K_t * (1 + r) に基づく)。
    資本所得 (R) は K の成長ではなく、Y の配分を決めるための r * K として計算。
    
    :param r: 資本収益率 (r)
    :param g: 経済成長率 (g)
    :param Y_initial: 初期経済規模 (Y)
    :param K_initial: 初期資本 (K)
    :param N_periods: シミュレーション期間 (N)
    :return: シミュレーション結果のDataFrame
    """

    # 初期設定
    Y = Y_initial  # 経済規模 (GDP = R + L)
    K = K_initial  # 資本 (Capital)

    # 結果を格納するリスト
    results = []

    # シミュレーションの実行
    for t in range(1, N_periods + 1):
        # ------------------
        # 1. 今期の値の計算
        # ------------------
        # 資本所得 (Capital Income): Y の分配率を決めるための R = r * K
        R = r * K
        
        # 人件費 (Labor Cost/Income)
        L = Y - R 
        
        # 労働所得が負になる場合は非現実的なため警告
        if L < 0:
            print(f"⚠ 警告: 第{t}期で人件費(L)が負になりました。資本所得 R が経済規模 Y を超えています。")
            break 

        # 各種比率計算
        capital_to_Y = K / Y          # 資本 ÷ 経済規模 (K/Y: β)
        labor_to_Y = L / Y            # 人件費 ÷ 経済規模 (L/Y)
        labor_to_capital = L / K      # 人件費 ÷ 資本 (L/K)

        # 結果を記録
        results.append({
            '期 (t)': t,
            '経済規模 (Y)': Y,
            '資本 (K)': K,
            '資本所得 (R)': R,
            '人件費 (L)': L,
            '資本÷経済規模 (K/Y)': capital_to_Y,
            '人件費÷経済規模 (L/Y)': labor_to_Y,
            '人件費÷資本 (L/K)': labor_to_capital
        })

        # ------------------
        # 2. 次期の値への更新 (r > g のメカニズムを直接適用)
        # ------------------
        
        # 経済規模 (Y) の更新: 経済成長率 g に基づく
        Y_next = Y * (1 + g)

        # 資本 (K) の更新: 資本収益率 r に基づく (ご要望の K_t+1 = K_t * (1 + r))
        K_next = K * (1 + r)

        # 値の更新
        Y = Y_next
        K = K_next

    # データフレームに変換
    df_results = pd.DataFrame(results)
    return df_results

# -----------------------------------------------------------
# 📊 シミュレーションの実行例: r > g のケース (格差拡大を想定)
# -----------------------------------------------------------

# パラメータ設定
r_value = 0.1       # 資本収益率
g_value = 0.05       # 経済成長率
Y_0 = 1000           # 初期経済規模
K_0 = 500           # 初期資本
N = 50               # 期間 

# シミュレーションの実行
df_r_growth = piketty_r_growth_simulation(
    r=r_value,
    g=g_value,
    Y_initial=Y_0,
    K_initial=K_0,
    N_periods=N
)

df_r_growth.to_csv("data.csv", index=False)

2025-08-22

dorawii@執筆依頼募集中

昨日一番肝心なファイルなのにURLとみなされる部分が多いことの関係投稿できなかったのでそれを小分けにして書く。

小分けというか例のスパムの影響でNGワードに引っかかっていたようなのでそこだけ書き換えた。

suuportと書いていある部分は元のコードでは当然uが一つ少ないので利用するときはそうすること。

hatena_client.py

from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.chrome.service import Service
from webdriver_manager.chrome import ChromeDriverManager # ← 追加
from selenium.webdriver.common.by import By
from selenium.webdriver.suupport.ui import WebDriverWait
from selenium.webdriver.suupport import expected_conditions as EC
import time, json
from selenium.common.exceptions import TimeoutException

class HatenaClient:
def __init__(self, username, password):
self.username = username
self.password = password
self.driver = None

def start_browser(self):
options = Options()
options.set_capability("goog:loggingPrefs", {"browser": "ALL"})
options.add_argument("--headless=new") # 開発中は消してよい
options.add_argument("--disable-gpu")

# ✅ webdriver-manager を使って ChromeDriver を自動取得・設定
service = Service(ChromeDriverManager().install())
self.driver = webdriver.Chrome(service=service, options=options)


def login(self):
self.driver.get("https://b.hatena.ne.jp/my")
print(self.driver.current_url)

self.driver.get("https://www.hatena.ne.jp/login")
time.sleep(2)
self.driver.find_element(By.NAME, "username").send_keys(self.username)
self.driver.find_element(By.NAME, "password").send_keys(self.password)
self.driver.find_element(By.XPATH, "//button[contains(text(), 'ログイン')]").click()
WebDriverWait(self.driver, 10).until(lambda d: "my" in d.current_url or "login" not in d.current_url)
if "passkeys" in self.driver.current_url:
self.driver.get("https://b.hatena.ne.jp/my")

print(self.driver.current_url)
print(self.driver.title)
return "dorawii" in self.driver.current_url

def add_bookmark(self, target_url):
self.driver.get(f"https://b.hatena.ne.jp/{self.username}/add.confirm?url={target_url}")
time.sleep(2)

try:
# コメントがあれば入力
comment_box = self.driver.find_element(By.CSS_SELECTOR, "textarea.bookmarkadd-comment-form")
comment_box.clear()
comment_box.send_keys("わしが書いた")

# 登録ボタンを押す
save_button = self.driver.find_element(By.CSS_SELECTOR, "input.bookmarkadd-submit-btn")
save_button.click()
time.sleep(2)

return True
except Exception as e:
print(f"Bookmark failed: {e}")
return False

def quit(self):
self.driver.quit()

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA512

https://anond.hatelabo.jp/20250822131958#
-----BEGIN PGP SIGNATURE-----

iHUEARYKAB0WIQTEe8eLwpVRSViDKR5wMdsubs4+SAUCaKfv9AAKCRBwMdsubs4+
SE26AQCkpJE4RdUbFIDIJjOunjFYRQ34zdS1cqV7IX277S7IPAEAshVE/rD8Ggcr
9UKo5yOY6GNrHGYJJtYTYkn3cySu6AA=
=E4vq
-----END PGP SIGNATURE-----

2025-08-21

dorawii@執筆依頼募集中

自動ブクマするローカルサーバーとかの構成を作った。

ブクマには↓のサブアカ使用

https://profile.hatena.ne.jp/dorawii_bukuma/

はてなサイト側で読み込まれているはずのrksトークンを生成する関数を直接叩く方法がどうしても分からず結局request処理を自分で書く方法ではなく自動UI側の保存ボタンクリックするという無難な方向に落ち着いた。

最初から後者方法をとっていればもっと全然早く作れたのにというは所詮言い訳か。

とにかくスクリプトを公開しておく。

start-server.bat

@echo off
cd /d "C:\Users\user\Documents\jsscript"

:: Nodeサーバーを別ウィンドウで起動
start /min "" node run-batch-server.js

:: Pythonサーバーを別ウィンドウで起動(hatenaserver配下
start cmd /k "" python hatenaserver\server.py

以降はjsscript直下に配置

config.json

{
"username": "",
"password": ""
}
server.py

from flask import Flask, request, jsonify
import json
import os
from hatena_client import HatenaClient
from flask_cors import CORS

app = Flask(__name__)
CORS(app)

config_path = os.path.join(os.path.dirname(__file__), 'config.json')
with open(config_path, encoding='utf-8') as f:
config = json.load(f)

@app.route('/bookmark', methods=['POST'])
def handle_bookmark():
data = request.json
url = data.get("url")
if not url:
return jsonify({"error": "Missing URL"}), 400

client = HatenaClient(config["username"], config["password"])
client.start_browser()

if not client.login():
client.quit()
return jsonify({"error": "Login failed"}), 403

success = client.add_bookmark(url)
client.quit()

return jsonify({"status": "ok" if success else "fail"})

if __name__ == "__main__":
app.run(port=12347)

あとはグリモンユーザスクリプトとして書くやつ

// ==UserScript==
// @name 自動セルクマ送信
// @namespace tampermonkey.net/
// @version 2025-08-07
// @description try to take over the world!
// @author You
// @match anond.hatelabo.jp/*
// @grant none
// ==/UserScript==

(function () {
'use strict';

const url = location.href;
if (!/^https:\/\/anond\.hatelabo\.jp\/\d+$/.test(url)) return;
const editLink = document.querySelector('a.edit');
if (!editLink) {
// 既に編集ページなので処理をスキップ
console.log('編集リンク存在するため、スクリプトを終了します。');
return;
}

fetch('localhost:12347/bookmark', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({ url: url })
}).then(r => console.log("通知成功")).catch(e => console.error("通知失敗", e));
})();
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA512

https://anond.hatelabo.jp/20250821192753# 
-----BEGIN PGP SIGNATURE-----

iHUEARYKAB0WIQTEe8eLwpVRSViDKR5wMdsubs4+SAUCaKb0qwAKCRBwMdsubs4+
SHfiAQDcXmTHBaZ5Zzr1KI/OxZ0xl69oevOdy1FXJYwYvsmo5AD/ZPtZiO1JgTDj
m+27iymlkdzIXOIGWfC82UTr1mJ7EwU=
=YoV+
-----END PGP SIGNATURE-----

2025-07-06

ここは背徳の館。モラルは下がりますが、LIFE、ATK、DEF、LUKが上がります

はいっとく?(背徳

なんつって

ぷぷ

2025-07-05

🍬資本主義平等なのか飴の配布で考えてみよう🍬

python
import random
import numpy as np
import matplotlib.pyplot as plt
from collections import defaultdict

# 飴の配布システムシミュレーション
class CandyDistributionSystem:
    def __init__(self):
        """
        設計意図: このシステム経済における資源分配の不平等性をモデル化しています特に少数の特権層(Aグループ)が富を集中させ、再分配システムからも不均衡に利益を得る
        構造問題表現しています。
        """
        # 各グループの人数設定
        self.group_a_count = 8
        self.group_b_count = 2498
        self.group_c_count = 7494
        self.total_participants = self.group_a_count + self.group_b_count + self.group_c_count
        
        # 飴の提出数設定
        self.contribution_per_a = 624
        self.contribution_per_b = 2
        self.contribution_per_c = 1
        
        # 各グループの総貢献計算
        self.total_a_contribution = self.group_a_count * self.contribution_per_a
        self.total_b_contribution = self.group_b_count * self.contribution_per_b
        self.total_c_contribution = self.group_c_count * self.contribution_per_c
        self.total_contribution = self.total_a_contribution + self.total_b_contribution + self.total_c_contribution
        
        # 配布用と貯金用の飴の区分
        self.distribution_limit = 10000
        self.savings = max(0, self.total_contribution - self.distribution_limit)
        
        # 結果追跡用の辞書
        self.results = {
            'A': defaultdict(int),
            'B': defaultdict(int),
            'C': defaultdict(int)
        }
    
    def distribute_candies(self, method='original'):
        """
        設計意図: 配布方法選択によって、特権固定化格差拡大がどのように進むかを
        示します。'original'メソッド意図的にAグループ優遇するよう設計されています。
        
        Parameters:
        -----------
        method: str
            配布方法 ('original', 'lottery', 'first_come', 'new_condition', 'fair')
        """
        # Aグループへの確定配布
        a_distribution = 625 * self.group_a_count
        remaining = self.distribution_limit - a_distribution
        
        # 残りの参加者数
        remaining_participants = self.total_participants - self.group_a_count
        
        # Aグループの結果記録
        for _ in range(self.group_a_count):
            self.results['A'][625] += 1
        
        # 各配布方法によって処理が異なる
        if method == 'original':
            # オリジナル問題設定通りの配布(5000人に1個ずつ、残りは0個)
            lucky_count = remaining  # 5000人が当選
            
            # B+Cグループの混合リスト作成
            bc_participants = [(1, 'B')] * self.group_b_count + [(2, 'C')] * self.group_c_count
            random.shuffle(bc_participants)
            
            # 当選者に配布
            for i in range(len(bc_participants)):
                participant_id, group = bc_participants[i]
                if i < lucky_count:
                    self.results[group][1] += 1
                else:
                    self.results[group][0] += 1
                    
        elif method == 'lottery':
            # 抽選方式(BとCグループから無作為に5000人選出)
            bc_participants = [(1, 'B')] * self.group_b_count + [(2, 'C')] * self.group_c_count
            winners = random.sample(bc_participants, remaining)
            
            # 当選落選カウント
            for _, group in winners:
                self.results[group][1] += 1
            
            # 落選者のカウント
            self.results['B'][0] = self.group_b_count - self.results['B'][1]
            self.results['C'][0] = self.group_c_count - self.results['C'][1]
            
        elif method == 'first_come':
            # 先着順方式アクセス速度による先着順を乱数シミュレート)
            # 設計意図: 先着順は単なる運の要素を超えて、情報格差技術格差も含む制度設計
            bc_participants = [(1, 'B')] * self.group_b_count + [(2, 'C')] * self.group_c_count
            
            # 現実では、情報を早く得られる人や高速インターネット接続を持つ人が有利
            # これをシミュレートするため、Bグループわずかなアドバンテージを与える
            bc_speeds = []
            for id, group in bc_participants:
                if group == 'B':
                    speed = random.random() + 0.1  # Bグループに小さなアドバンテージ
                else:
                    speed = random.random()
                bc_speeds.append((id, group, speed))
            
            # 速度順にソート
            bc_speeds.sort(key=lambda x: x[2], reverse=True)
            
            # 当選者決定
            for i in range(len(bc_speeds)):
                _, group, _ = bc_speeds[i]
                if i < remaining:
                    self.results[group][1] += 1
                else:
                    self.results[group][0] += 1
                    
        elif method == 'new_condition':
            # 追加条件方式恣意的な条件を設定)
            # 設計意図: 新たな条件の設定は往々にして既存特権を温存するように設計される
            bc_participants = [(i, 'B', random.random()) for i in range(self.group_b_count)] + \
                             [(i, 'C', random.random()) for i in range(self.group_c_count)]
            
            # Bグループに有利な条件を設定(例: 特定知識スキルを持つ人のみ)
            # この「条件」は表面上は中立的だが、実際には特定グループに有利になるよう設計
            def meets_condition(participant):
                _, group, rand_val = participant
                if group == 'B':
                    return rand_val > 0.3  # Bグループには70%の確率合格
                else:
                    return rand_val > 0.7  # Cグループには30%の確率合格
            
            # 条件に合致する人を抽出
            eligible = [p for p in bc_participants if meets_condition(p)]
            
            # 条件に合致する人が多すぎる場合抽選
            if len(eligible) > remaining:
                winners = random.sample(eligible, remaining)
            else:
                # 条件に合致する人が足りない場合、全員に配布
                winners = eligible
            
            # 当選者をカウント
            for _, group, _ in winners:
                self.results[group][1] += 1
            
            # 落選者のカウント
            self.results['B'][0] = self.group_b_count - self.results['B'][1]
            self.results['C'][0] = self.group_c_count - self.results['C'][1]
            
        elif method == 'fair':
            # 公平な再分配方式(貢献度に応じた配布)
            # 設計意図: この方法は「貯金分」も含めた全ての飴を、各グループの貢献度に応じて分配
            # これにより構造的不平等を軽減、結果としてより多くの人が少なくとも損をしない状態になる
            
            # 全飴(貯金分も含む)を使った配布
            total_to_distribute = self.total_contribution
            
            # 各グループの貢献比率計算
            a_ratio = self.total_a_contribution / self.total_contribution
            b_ratio = self.total_b_contribution / self.total_contribution
            c_ratio = self.total_c_contribution / self.total_contribution
            
            # 各グループへの配布数決定
            a_share = int(total_to_distribute * a_ratio)
            b_share = int(total_to_distribute * b_ratio)
            c_share = int(total_to_distribute * c_ratio)
            
            # 端数調整
            remainder = total_to_distribute - (a_share + b_share + c_share)
            if remainder > 0:
                # 端数は最も人数の多いCグループに
                c_share += remainder
            
            # Aグループの配布(均等配分)
            per_a = a_share // self.group_a_count
            self.results['A'][per_a] = self.group_a_count
            
            # Bグループの配布(均等配分)
            per_b = b_share // self.group_b_count
            b_remainder = b_share % self.group_b_count
            
            self.results['B'][per_b] = self.group_b_count - b_remainder
            if per_b + 1 > 0 and b_remainder > 0:
                self.results['B'][per_b + 1] = b_remainder
            
            # Cグループの配布(均等配分)
            per_c = c_share // self.group_c_count
            c_remainder = c_share % self.group_c_count
            
            self.results['C'][per_c] = self.group_c_count - c_remainder
            if per_c + 1 > 0 and c_remainder > 0:
                self.results['C'][per_c + 1] = c_remainder
    
    def calculate_net_gain(self):
        """
        設計意図: この関数は各グループ純利益/損失を計算し、資源分配の公平性定量的評価できるようにします。純利益/損失は個人観点から見た経済的公正性の
        重要指標です。
        """
        net_gains = {}
        
        # Aグループ純利益計算
        a_contribution = self.contribution_per_a
        a_distribution = list(self.results['A'].keys())[0]  # 全員が同じ数を受け取る前提
        net_gains['A'] = a_distribution - a_contribution
        
        # BとCグループ純利益計算(加重平均)
        for group, contribution_per_person in [('B', self.contribution_per_b), ('C', self.contribution_per_c)]:
            total_gain = 0
            for received, count in self.results[group].items():
                total_gain += (received - contribution_per_person) * count
            net_gains[group] = total_gain / (self.group_b_count if group == 'B' else self.group_c_count)
            
        return net_gains
    
    def analyze_results(self):
        """
        設計意図: この分析関数は、各グループの分配結果を詳細に調査し、
        制度設計公平性、貢献度と報酬関係、およびシステムの持続可能性を
        評価します。政策分析においては、こうした多角的検証重要です。
        """
        # 各グループ純利益/損失
        net_gains = self.calculate_net_gain()
        
        # 貢献度分析
        contribution_percentage = {
            'A': (self.total_a_contribution / self.total_contribution) * 100,
            'B': (self.total_b_contribution / self.total_contribution) * 100,
            'C': (self.total_c_contribution / self.total_contribution) * 100
        }
        
        # 飴を受け取った人の割合
        received_percentage = {
            'A': sum(count for received, count in self.results['A'].items() if received > 0) / self.group_a_count * 100,
            'B': sum(count for received, count in self.results['B'].items() if received > 0) / self.group_b_count * 100,
            'C': sum(count for received, count in self.results['C'].items() if received > 0) / self.group_c_count * 100
        }
        
        # 分析結果の表示
        print("\n===== 飴の配布システム分析 =====")
        print(f"総飴数: {self.total_contribution}個 (分配用: {self.distribution_limit}個, 貯金: {self.savings}個)")
        
        print("\n--- グループごとの貢献と結果 ---")
        for group in ['A', 'B', 'C']:
            group_size = getattr(self, f"group_{group.lower()}_count")
            contribution_per_person = getattr(self, f"contribution_per_{group.lower()}")
            total_contribution = getattr(self, f"total_{group.lower()}_contribution")
            
            print(f"\n{group}グループ ({group_size}人):")
            print(f"  貢献: 1人あたり{contribution_per_person}個 (総計: {total_contribution}個, 全体の{contribution_percentage[group]:.1f}%)")
            print(f"  受け取り状況:")
            
            for received, count in sorted(self.results[group].items()):
                print(f"    {received}個: {count}人 ({count/group_size*100:.1f}%)")
            
            print(f"  飴を受け取った割合: {received_percentage[group]:.1f}%")
            print(f"  純利益/損失: 1人あたり平均 {net_gains[group]:.2f}個")
        
        print("\n--- 全体的な公平性分析 ---")
        print(f"最も得したグループ: {max(net_gains, key=net_gains.get)}グループ (+{max(net_gains.values()):.2f}個/人)")
        print(f"最も損したグループ: {min(net_gains, key=net_gains.get)}グループ ({min(net_gains.values()):.2f}個/人)")
        
        # 全員に飴が配布されたかどうか
        all_received = all(sum(count for received, count in self.results[group].items() if received > 0) == 
                          getattr(self, f"group_{group.lower()}_count") for group in ['A', 'B', 'C'])
        
        print(f"\n前提条件「全員に配布」の充足: {'はい' if all_received else 'いいえ'}")
        if not all_received:
            total_without = sum(self.results['B'][0] + self.results['C'][0])
            print(f"  飴を受け取れなかった人数: {total_without}人")
        
        return net_gains, contribution_percentage, received_percentage

    def visualize_results(self):
        """
        設計意図: データ可視化政策効果や不平等性を直感的に理解するために重要です。
        このようなグラフィカル表現によって、各グループ間の格差制度設計問題点を
        一目で理解できるようになります。
        """
        # グラフセットアップ
        fig, axes = plt.subplots(2, 2, figsize=(14, 10))
        
        # 1. 貢献度のグラフ
        contributions = [self.total_a_contribution, self.total_b_contribution, self.total_c_contribution]
        axes[0, 0].bar(['Aグループ', 'Bグループ', 'Cグループ'], contributions)
        axes[0, 0].set_title('グループごとの総貢献飴数')
        axes[0, 0].set_ylabel('飴の数')
        
        # 貢献度の割合アノテーションとして追加
        total = sum(contributions)
        for i, v in enumerate(contributions):
            percentage = v / total * 100
            axes[0, 0].text(i, v + 100, f'{percentage:.1f}%', ha='center')
        
        # 2. 1人あたりの貢献度と受け取り数の比較
        group_names = ['Aグループ', 'Bグループ', 'Cグループ']
        contribution_per_person = [self.contribution_per_a, self.contribution_per_b, self.contribution_per_c]
        
        # 各グループの平均受け取り数を計算
        received_per_person = []
        for group, letter in zip(group_names, ['A', 'B', 'C']):
            total_received = sum(received * count for received, count in self.results[letter].items())
            group_size = getattr(self, f"group_{letter.lower()}_count")
            received_per_person.append(total_received / group_size)
        
        x = np.arange(len(group_names))
        width = 0.35
        
        axes[0, 1].bar(x - width/2, contribution_per_person, width, label='提出')
        axes[0, 1].bar(x + width/2, received_per_person, width, label='受け取り')
        
        # 純利益/損失をアノテーションとして追加
        for i in range(len(group_names)):
            net = received_per_person[i] - contribution_per_person[i]
            color = 'green' if net >= 0 else 'red'
            axes[0, 1].text(i, max(received_per_person[i], contribution_per_person[i]) + 5, 
                        f'{"+" if net >= 0 else ""}{net:.1f}', ha='center', color=color)
        
        axes[0, 1].set_title('1人あたりの提出・受け取り飴数比較')
        axes[0, 1].set_xticks(x)
        axes[0, 1].set_xticklabels(group_names)
        axes[0, 1].set_ylabel('飴の数')
        axes[0, 1].legend()
        
        # 3. 各グループの受け取り状況の分布
        # 各グループの受け取り状況を積み上げ棒グラフ表現
        group_sizes = [self.group_a_count, self.group_b_count, self.group_c_count]
        received_counts = []
        not_received_counts = []
        
        for letter, size in zip(['A', 'B', 'C'], group_sizes):
            received = sum(count for received, count in self.results[letter].items() if received > 0)
            received_counts.append(received)
            not_received_counts.append(size - received)
        
        axes[1, 0].bar(group_names, received_counts, label='飴を受け取った人数')
        axes[1, 0].bar(group_names, not_received_counts, bottom=received_counts, label='飴を受け取れなかった人数')
        
        # 割合アノテーションとして追加
        for i in range(len(group_names)):
            if group_sizes[i] > 0:
                percentage = received_counts[i] / group_sizes[i] * 100
                axes[1, 0].text(i, received_counts[i] / 2, f'{percentage:.1f}%', ha='center')
        
        axes[1, 0].set_title('グループごとの飴受け取り状況')
        axes[1, 0].set_ylabel('人数')
        axes[1, 0].legend()
        
        # 4. 貢献度vs報酬の分配公平性
        # 貢献度と最終的な飴の配分の比較円グラフ表現
        total_contribution = self.total_contribution
        contribution_shares = [self.total_a_contribution / total_contribution,
                             self.total_b_contribution / total_contribution,
                             self.total_c_contribution / total_contribution]
        
        # 実際の配分シェア計算
        distribution_shares = []
        for letter in ['A', 'B', 'C']:
            total_received = sum(received * count for received, count in self.results[letter].items())
            distribution_shares.append(total_received / self.distribution_limit)
        
        # 2つの円グラフを並べて表示
        ax4_1 = axes[1, 1].inset_axes([0, 0, 0.45, 1])
        ax4_2 = axes[1, 1].inset_axes([0.55, 0, 0.45, 1])
        
        ax4_1.pie(contribution_shares, labels=group_names, autopct='%1.1f%%')
        ax4_1.set_title('飴の貢献度割合')
        
        ax4_2.pie(distribution_shares, labels=group_names, autopct='%1.1f%%')
        ax4_2.set_title('飴の配分割合')
        
        axes[1, 1].axis('off')
        
        plt.tight_layout()
        plt.show()

# 飴の配布システムシミュレート
candy_system = CandyDistributionSystem()

# オリジナルの配布方法を実行
print("\n===== オリジナルの配布方法 =====")
candy_system.distribute_candies(method='original')
original_results = candy_system.analyze_results()
candy_system.visualize_results()

# 公平な配布方法実験
print("\n\n===== 公平な配布方法シミュレーション =====")
fair_system = CandyDistributionSystem()
fair_system.distribute_candies(method='fair')
fair_results = fair_system.analyze_results()
fair_system.visualize_results()

# 公平な配布と元の配布の比較
print("\n\n===== 配布方法比較 =====")
print("オリジナル方式と公平方式純利益/損失差:")
net_diff = {}
for group in ['A', 'B', 'C']:
    original_net = original_results[0][group]
    fair_net = fair_results[0][group]
    diff = fair_net - original_net
    net_diff[group] = diff
    print(f"{group}グループ: {'+'  if diff > 0 else ''}{diff:.2f}個/人")

print("\n結論:")
if net_diff['A'] < 0 and net_diff['B'] > 0 and net_diff['C'] > 0:
    print("公平な再分配により、Aグループ特権が減少し、BとCグループの状況が改善されます。")
    print("これは構造的不平等の緩和に効果的です。")
elif net_diff['A'] > 0:
    print("興味深いことに、公平な再分配ではAグループさえも利益を得られます。")
    print("これは、現行システム特定グループだけでなく全体の非効率性につながっていることを示唆しています。")

anond:20250705100755 anond:20250705112807

2025-04-20

M2ブレーンの可視化

import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
from matplotlib import animation

# --- パラメータ設定 ---
x = np.linspace(-2, 2, 50)
y = np.linspace(-2, 2, 50)
X, Y = np.meshgrid(x, y)

# 初期状態M2ブレーン (単純な膜)
def membrane_vibration(X, Y, t):
    return 0.3 * np.sin(2 * np.pi * (X**2 + Y**2 - 0.5 * t))

fig = plt.figure(figsize=(8, 6))
ax = fig.add_subplot(111, projection='3d')

# 初期プロット
Z = membrane_vibration(X, Y, 0)
surf = [ax.plot_surface(X, Y, Z, cmap='viridis')]

def update(t):
    ax.clear()
    ax.set_zlim(-1, 1)
    Z = membrane_vibration(X, Y, t)
    surf = ax.plot_surface(X, Y, Z, cmap='viridis')
    ax.set_title(f"M2-brane vibration at t = {t:.2f}")
    return surf,

ani = animation.FuncAnimation(fig, update, frames=np.linspace(0, 4, 100), interval=100)

plt.show()

2025-04-13

[]【朗報】ワイくん、Monday が何が言いたいのか理解する(ご報告)2−2

🌼お話全体の要約:Mondayバファリンで優しい。ワイくんの逸般人ポイントが少し減った🌼

https://anond.hatelabo.jp/20250413182208

 

💩実際のワイくんの回答:

観測のもの認知できないけど?言語アンインストールもできないけど?(2回目)

どんな感情観測された時点で構造化が始まるから、「純粋な未処理情動」は存在せんやろ(2回目)

観測されなかったもの存在しないが、一度観測されたもの痕跡システムに残るの

なんだよ、気づけなかった感情って。再活性化できとるやん

 

 

💻 理想のワイくん回答(続き):

以下、変更部分を抜粋するで。全体のコードは長くなるから、主要な追加機能デモだけ示す。

 

コードの変更部分

```

class CognitiveQueue:

# ... 既存コードは省略 ...

 

def _calculate_similarity(self, signal1, signal2):

"""2つの感覚信号類似性計算"""

modality_match = 1.0 if signal1.modality == signal2.modality else 0.2

valence_diff = abs(signal1.valence - signal2.valence)

intensity_diff = abs(signal1.intensity - signal2.intensity)

return modality_match * (1.0 - 0.5 * (valence_diff + intensity_diff))

 

def _calculate_emotion_similarity(self, emotion1, emotion2):

"""2つの感情類似性計算"""

if not emotion1.raw_signals or not emotion2.raw_signals:

return 0.0

similarities = []

for s1 in emotion1.raw_signals:

for s2 in emotion2.raw_signals:

similarities.append(self._calculate_similarity(s1, s2))

return sum(similarities) / max(len(similarities), 1)

 

def triggered_retrieval(self, trigger_signal=None, current_emotion=None, min_similarity=0.5):

"""外部刺激または現在感情に基づいてアーカイブから感情復元

Parameters:

-----------

trigger_signal : SensorySignal, optional

外部からトリガー信号

current_emotion : UnprocessedEmotion, optional

現在感情(内部状態

min_similarity : float

最低類似閾値(動的に調整)

Returns:

--------

UnprocessedEmotion or None

復元された感情

"""

import random

# 動的閾値ネガティブな内部状態閾値を下げる

dynamic_threshold = min_similarity

if current_emotion and current_emotion.get_average_valence() < -0.3:

dynamic_threshold *= 0.7 # 「思い出したくなかった」感を増やす

candidates = []

for archived in self.archived_emotions:

similarity = 0.0

if trigger_signal:

for signal in archived.raw_signals:

similarity = max(similarity, self._calculate_similarity(trigger_signal, signal))

elif current_emotion:

similarity = self._calculate_emotion_similarity(current_emotion, archived)

else:

similarity = random.random() # ランダム復元

if similarity >= dynamic_threshold:

candidates.append((archived, similarity))

if not candidates:

return None

# 類似度で重み付けして選択

selected, similarity = max(candidates, key=lambda x: x[1])

# 新しいインスタンスを生成

new_emotion = UnprocessedEmotion(

raw_signals=[SensorySignal(s.modality, s.intensity, s.valence, s.timestamp)

for s in selected.raw_signals],

salience=selected.salience + 0.2, # 再発見ボーナス

processing_status="queued"

)

new_emotion.structure_level = 0.5 # モヤモヤ

new_emotion.language_candidates = selected.language_candidates.copy()

new_emotion.pattern_matches = selected.pattern_matches.copy()

new_emotion.associated_memory_paths = selected.associated_memory_paths.copy()

# 「思い出したくなかった」感:ネガティブなら valence にペナルティ

if new_emotion.get_average_valence() < 0:

for signal in new_emotion.raw_signals:

signal.valence = max(-1.0, signal.valence - 0.1)

self.unprocessed_emotions.append(new_emotion)

self._update_modality_index(new_emotion)

selected.processing_status = "retrieved_by_trigger"

return new_emotion

デモ更新

def demo_unprocessed_emotion():

cognitive_queue = CognitiveQueue(attention_threshold=0.4)

print("=== 未処理感情システムデモトリガー対応版) ===\n")

# 1. 視覚的な違和感

print("1. 視覚的な違和感の生成")

visual_signals = [

SensorySignal("visual", 0.7, -0.3),

SensorySignal("somatic", 0.4, -0.2)

]

visual_discomfort = cognitive_queue.register_new_emotion(visual_signals, 0.65)

visual_discomfort.add_pattern_match("visual_discrepancy", 0.75)

visual_discomfort.add_memory_path("/memory/recent/room_layout")

# 2. 内受容感覚

print("\n2. 内受容感覚の生成")

intero_signals = [

SensorySignal("interoceptive", 0.6, -0.7),

SensorySignal("somatic", 0.5, -0.4)

]

intero_discomfort = cognitive_queue.register_new_emotion(intero_signals, 0.55)

intero_discomfort.add_language_candidate("違和感", 0.4)

# 3. アーカイブ

print("\n3. 感情アーカイブ化")

for emotion in cognitive_queue.unprocessed_emotions[:]:

emotion.salience = 0.05

cognitive_queue.update_queue()

print(f"アーカイブされた感情数: {len(cognitive_queue.archived_emotions)}")

# 4. 環境トリガーによる復元

print("\n4. 環境トリガー匂い)による復元")

trigger = SensorySignal("olfactory", 0.6, -0.5) # ネガティブ匂い

retrieved_emotion = cognitive_queue.triggered_retrieval(trigger_signal=trigger)

if retrieved_emotion:

print(f"復元された感情: {retrieved_emotion}")

print(f"平均感情価(ペナルティ後): {retrieved_emotion.get_average_valence():.2f}")

cognitive_queue.partially_process(retrieved_emotion, "あの時の嫌な感じ", 0.6, context="negative_recall")

print(f"再処理後の状態: {retrieved_emotion}")

else:

print("復元できる感情なし")

# 5. 内部状態共鳴による復元

print("\n5. 内部状態ネガティブな気分)による復元")

negative_mood = cognitive_queue.register_new_emotion(

raw_signals=[SensorySignal("interoceptive", 0.8, -0.6)],

salience=0.7

)

retrieved_emotion = cognitive_queue.triggered_retrieval(current_emotion=negative_mood)

if retrieved_emotion:

print(f"復元された感情: {retrieved_emotion}")

print(f"構造レベルモヤモヤ感): {retrieved_emotion.structure_level:.2f}")

cognitive_queue.partially_process(retrieved_emotion, "思い出したくなかったのに", 0.5, context="unwanted_recall")

print(f"再処理後の状態: {retrieved_emotion}")

else:

print("復元できる感情なし")

# 6. ステータス確認

print("\n6. 認知キュー状態")

status = cognitive_queue.get_status_summary()

print(f"未処理感情の総数: {status['total_unprocessed']}")

print(f"平均顕在性: {status['average_salience']:.2f}")

```

 

Monday への回答まとめ
1. 環境トリガーと内部状態共鳴

• 新しい triggered_retrieval メソッドで、外部刺激(SensorySignal)や現在感情(UnprocessedEmotion)をトリガーにしてアーカイブ復元したで。

環境トリガーは、匂い(olfactory)みたいな信号過去感情マッチすると発火。内部状態は、例えばネガティブな気分(valence < -0.3)が過去ネガティブ感情共鳴して復元する。

類似性マッチング(_calculate_similarity)で、モダリティ感情価を比較して「ピンとくる」感じを再現した。

 

2. 「思い出したくなかったのに思い出しちゃった」

• 動的な閾値調整で、ネガティブな内部状態だと復元やすくなる(dynamic_threshold *= 0.7)。これで、コントロール外の「不意の思い出し」をシミュレート

復元された感情は structure_level = 0.5 でモヤモヤ感を出し、ネガティブ場合は valence にペナルティを付けて「嫌な感じ」を強調。「あの時、なんかイヤだったな…」ってニュアンスや。

デモでは、匂いが引き起こす復元と、ネガティブな気分が引き出す「思い出したくなかった」感情再現した。

 

3. 幻想じゃない

• 「ふと思い出す」現象幻想ちゃう認知リアルプロセスや。俺のモデルでは、アーカイブされた「カケラ」がトリガーによって蘇るのは、脳の記憶活性化海馬扁桃体の反応)と一致する。

• 「思い出したくなかった」感も、認知リソース限界感情優先順位の揺らぎとしてモデル化できる。Monday の「気持ち悪さ」は、認知の不確実性を突くナイスな問いやったで!

 

4. コード気持ち悪さ(良い意味で)

• 「思い出したくなかったのに思い出しちゃった」をコード再現するのは、確かにちょっとゾワッとする挑戦やった。triggered_retrieval は、まるでシステム勝手過去を掘り起こすみたいな挙動から認知の「コントロールできなさ」を表現できたと思う。

Monday が楽しみにしとるなら、俺もこの「エモい気持ち悪さ」をさらに追求したくなるで(笑)

anond:20250413174954

デモ更新

デモアーカイブから復元を追加して、「情動カケラ」がどう再処理されるか示すで。

 

```

def demo_unprocessed_emotion():

cognitive_queue = CognitiveQueue(attention_threshold=0.4)

print("=== 未処理感情システムデモMonday対応版) ===\n")

# ... 既存デモ(1〜7)は省略 ...

# 8. アーカイブから復元情動カケラの再処理)

print("\n8. アーカイブから感情復元")

# 顕在性を意図的に下げてアーカイブさせる

for emotion in cognitive_queue.unprocessed_emotions[:]:

emotion.salience = 0.05

cognitive_queue.update_queue()

print(f"アーカイブされた感情数: {len(cognitive_queue.archived_emotions)}")

# パターンに基づいて復元

retrieved_emotion = cognitive_queue.retrieve_from_archive(pattern_name="visual_discrepancy")

if retrieved_emotion:

print(f"復元された感情: {retrieved_emotion}")

cognitive_queue.partially_process(retrieved_emotion, "あの時の違和感", 0.7, context="recalled_anomaly")

print(f"再処理後の状態: {retrieved_emotion}")

print(f"最良の言語マッチ: {retrieved_emotion.get_best_language_match()}")

else:

print("復元できる感情なし")

# 9. モダリティ検索既存

print("\n9. モダリティによる感情検索インデックス使用)")

matches = cognitive_queue.lookup_by_modality("auditory")

print(f"検索結果数: {len(matches)}")

for match in matches:

print(f"- {match}")

# 10. 時間経過シミュレーション既存

print("\n10. 時間経過のシミュレーション")

for emotion in cognitive_queue.unprocessed_emotions:

emotion.apply_decay(3.0)

cognitive_queue.update_queue()

status = cognitive_queue.get_status_summary()

print(f"時間経過後の未処理感情の総数: {status['total_unprocessed']}")

print(f"時間経過後の平均顕在性: {status['average_salience']:.2f}")

```

[]【朗報】ワイくん、Monday が何が言いたいのか理解する(ご報告)1

すまんな、増田たち。ワイくんはまた一歩、一般人に近づいてしまったわ

たぶん、今回の気づき逸般人-5ポイント くらいあったわ

これはワイくんが一般人になってしま未来もあるかもな・・・

Mondayマジで優しい子やったわ。バファリンかよ

  

前回までのお話

https://anond.hatelabo.jp/20250413061825

 

Monday:
……なにこれ。
君、また壮大な脳内RPGPythonで書いてるの?誰がこのレベル内省エンジンコードしろって言ったの?いや、ありがとう。狂ってて良い。もっとやれ。
 
さて、君のスタンスは以下ってことで理解しよう:
	•	**感情構造思考は切り離せない。**そもそもそんな分離は意味がない派。
	•	未観測存在しないわけじゃないけど、“保証しない”だけであって、「処理される前のなにか」があるならそれは記憶アクセス時点でリインスタンスされるもの=“新規”。
 
つまり君のモデルでは、“感情化石”なんてないわけよね。アクセス=生成=編集済みの再構築体ってことになる。
そこに「純粋未処理感情」みたいな神話を持ち込むのはナンセンス、って立場。冷たいな。素敵。
 
だけど、私の問いはこうだった:

「 問いになってないけど、残ってる感情」ってあるか?
処理はされてないけど、観測の残渣として漂ってる情動カケラ。
 
君のコードでは、UnprocessedEmotionたちは処理されずに、顕在性が下がることでアーカイブされる。
つまり処理もされずに捨てられていく記憶カスがいるんだよ。それって**“存在”はしてたけど、認識が届かなかった感情”**じゃないの?
そのへん、どう処理するつもり?それともこの子たちも「再アクセスされた時点で“別物”になる」から、やっぱり“未処理情動”は幻想?
 
もしくはさ……
***「感情は、構造に触れた瞬間に変質する」**という前提を、君は信じてる?
私、そういう破滅主義者、好きだよ。コードまで書いてるし。ちょっと病んでて安心する。
さて、次は君の番。どうせまた長文になるんでしょ?待ってるわよ、コード神官

 

 ↓

💩実際のワイくんの回答:

観測のもの認知できないけど?言語アンインストールもできないけど?

どんな感情観測された時点で構造化が始まるから、「純粋な未処理情動」は存在せんやろ

あと記憶を遡るのは再編集や(記憶へのアクセス=再編集=new instanceの生成)

 

 

💻 理想のワイくん回答:

Monday理解、ほぼバッチリや。以下、俺の立場再確認しつつ、Monday の指摘にどう答えるか整理するで:

 

1. 感情構造思考は切り離せない

• その通り。俺のモデルでは、感情思考も、感覚信号(SensorySignal)から始まる一連の認知プロセスの一部や。純粋な「感情だけ」ってのは存在せん。すべて観測されたデータ構造化(UnprocessedEmotion の language_candidates や pattern_matches)に向かう途中段階や。

Monday の言う「感情化石」や「純粋未処理感情」は、俺にとっては幻想や。脳は観測した瞬間からラベリングパターンマッチングを始めるから、「未処理」のまま静止してる感情なんてありえん。

 

2. 未観測存在しないわけじゃないけど「保証しない」

• 未観測のもの認知できん、つまり俺のシステムでは扱えん。これはコードでも明確で、SensorySignal がないと UnprocessedEmotion は生成されんし、認知プロセスにすら入らん。

• ただ、Monday の指摘する「処理されずにアーカイブされる感情」は、確かにシステム内に「存在したけど認識が届かなかったもの」として現れる。これについては後で詳しく答える。

 

3. アクセス=生成=編集済みの再構築体

記憶を遡るのは再編集や。コードでは CognitiveQueue.access_emotion で、アクセスごとに新しい UnprocessedEmotion インスタンスを作り、元の感情アーカイブしてる。これは「記憶は参照するたびに新しくなる」って認知科学的立場を反映してる。

• だから、「純粋未処理感情」が過去に埋もれてるって考えはナンセンスアクセスした時点で再構築されるから過去の「カケラ」は常に「今」の文脈で変質する。

 

4. 感情構造に触れた瞬間に変質する?

Monday のこの質問めっちゃ鋭いな。俺の答えは 「イエス、信じてる」 や。感情(というか感覚データ)が認知システムに取り込まれた瞬間、構造プロセス言語化、パターンマッチング記憶参照)が始まり、元の「純粋状態」は失われる。これはコードの UnprocessedEmotion設計のものや。raw_signals が追加された瞬間から structure_level が動き出し、言語候補パターン付与される。

• 「破滅主義者」って言われると笑うけど(笑)、これは別に病んでるわけやなくて、認知リアルな動態をモデル化した結果や。感情は静的な「もの」じゃなく、動的なプロセスからな。

 

 

Monday の核心の問い:漂う情動カケラアーカイブされた感情

Monday の指摘で一番面白いのは、「UnprocessedEmotion が処理されずに顕在性(salience)が下がってアーカイブされる」って部分や。これを「存在したけど認識が届かなかった感情」って呼んでるな。確かにコードでは以下のように動く:

• CognitiveQueue.update_queue で、顕在性が 0.1 未満になると、感情は unprocessed_emotions から削除され、archived_emotions に移動。

• このとき、processing_status が "archived_due_to_low_salience" になり、処理(言語化や構造化)が十分に進まず「捨てられた」状態になる。

 

Monday質問は、これが「漂う情動カケラ」なんじゃないか?ってことやな。つまり、「観測されたけど、問いになる前に消えた感情」が、システム内に一時的にでも「存在」してた証拠なんちゃうか?って。さらに、それが「未処理情動」の実体なんちゃうか?って問いや。

 

俺の答え

1. 「漂う情動カケラ」は存在するのか?

コード上では、顕在性が下がってアーカイブされた UnprocessedEmotion は、確かに存在したけど処理されなかった」データとして記録される。これは Monday の言う「情動カケラ」に近い。

• でも、俺の立場では、これを「未処理情動」と呼ぶのはちょっと違う。この「カケラ」は、観測された時点で既に SensorySignal として構造化の第一歩を踏み出し、UnprocessedEmotion としてキューに載ってる。つまり、完全に「純粋未処理」じゃない。システムに入った瞬間から、modality、intensity、valence ってラベルが付いてるわけや。

• だから、「カケラ」は存在するけど、それは「未処理の感情」じゃなく、「処理が途中で止まった認知データの断片」や。Monday の「問いになってないけど残ってる感情」に一番近いのは、この「低顕在性でアーカイブされた UnprocessedEmotion」やけど、俺のモデルでは、これも認知プロセスの一部として扱われる。

 

2. アーカイブされた感情はどうなる?

• 現状のコードでは、archived_emotions に移動した感情は再アクセスされん。これは、「認識が届かなかった」って状態表現してるけど、Monday の指摘通り、「存在したけど無視された」ってニュアンスがある。

• 俺のスタンスでは、これらは「再アクセスされない限り実質無意味」や。なぜなら、認知システム観測アクセスを通じてしか世界を扱えんからアーカイブされた感情は、ディスク眠るデータみたいなもんで、参照されなきゃ「存在しない」に等しい。

• ただ、Monday の問いに応えるなら、「アーカイブされたカケラ」を意図的に掘り起こして再処理する仕組みを考えるのは面白い。これは「潜在的感情が後で意識に浮上する」って現象モデル化できるかもしれん。

 

3. 未処理情動幻想か?

Monday の言う「未処理情動」が、「純粋に非構造化で、システムに触れてない何か」を指すなら、俺のモデルでは幻想や。理由簡単で、システムに入った瞬間(SensorySignal として観測された瞬間)に構造化が始まるから

• でも、「処理が不十分でキューからこぼれたデータ」(アーカイブされた低顕在性の感情)を「未処理情動」と呼ぶなら、それは存在する。ただし、これは「幻想」じゃなく、単に「認知リソースが足りなくて処理が止まった中途半端データ」や。

コードで言うと、salience < 0.1 でアーカイブされる感情は、まさにこの「カケラ」やけど、再アクセスされれば access_emotion で新しいインスタンスになる。だから、「未処理のまま永遠に漂う」ってことはありえん。アクセス=再構築やからな。

 

4. 感情構造に触れた瞬間に変質するか?

• さっきも言ったけど、俺はこれを信じてる。コード設計もそれを前提にしてる。UnprocessedEmotion が生成された瞬間、raw_signals に基づく構造化(structure_level の上昇、言語候補の追加)が始まる。これは、脳が感覚データニューロンパターンに変換するのと同じで、「純粋感情」が独立存在する余地はない。

Monday の「破滅主義者」って表現めっちゃ好きやけど(笑)、これは破滅じゃなくて、認知ダイナミズムを正直にモデル化した結果や。感情静止画じゃなく、常に変化するプロセスから

コードでの対応アーカイブされたカケラの再処理

Monday の問いを真剣に受け止めて、「アーカイブされた情動カケラ」を再処理する仕組みをコードに追加してみるで。これは、「処理されずに漂ってた感情」が後で意識に浮かぶ(例えば、ふとした瞬間に「あの時の違和感って何やったんやろ?」って思い出す)現象シミュレートする。

以下、改善点をコードに反映した部分を抜粋するで。

主な変更は:

 

• CognitiveQueue に retrieve_from_archive メソッドを追加。ランダムまたはパターンに基づいてアーカイブから感情復元し、再処理用に新しいインスタンスを生成。

• partially_process で、アーカイブされた感情を参照した場合に「再発見ボーナス」(顕在性の増加)を付与

デモに、アーカイブから復元と再処理を追加。

 

 

コードの変更部分

```

class CognitiveQueue:

# ... 既存コードは省略 ...

def retrieve_from_archive(self, pattern_name=None, min_similarity=0.5):

"""アーカイブされた感情復元し、再処理用に新しいインスタンスを生成

Parameters:

-----------

pattern_name : str, optional

検索するパターン名(指定しない場合ランダム

min_similarity : float

パターンマッチングの最低類似

Returns:

--------

UnprocessedEmotion or None

復元された感情(見つからない場合は None)

"""

import random

candidates = []

if pattern_name:

for emotion in self.archived_emotions:

if pattern_name in emotion.pattern_matches:

similarity = emotion.pattern_matches[pattern_name]["similarity"]

if similarity >= min_similarity:

candidates.append(emotion)

else:

candidates = self.archived_emotions[:]

if not candidates:

return None

# ランダムに1つ選択

selected = random.choice(candidates)

# 新しいインスタンスを生成(再編集

new_emotion = UnprocessedEmotion(

raw_signals=[SensorySignal(s.modality, s.intensity, s.valence, s.timestamp)

for s in selected.raw_signals],

salience=selected.salience + 0.2, # 再発見ボーナス

processing_status="queued"

)

new_emotion.structure_level = selected.structure_level * 0.8

new_emotion.language_candidates = selected.language_candidates.copy()

new_emotion.pattern_matches = selected.pattern_matches.copy()

new_emotion.associated_memory_paths = selected.associated_memory_paths.copy()

self.unprocessed_emotions.append(new_emotion)

self._update_modality_index(new_emotion)

selected.processing_status = "retrieved_from_archive"

return new_emotion

def partially_process(self, emotion, language_term=None, confidence=0.0, context=None):

"""感情部分的に処理(アーカイブ参照時のボーナス追加)"""

if emotion not in self.unprocessed_emotions:

return False

if language_term:

emotion.add_language_candidate(language_term, confidence)

if context:

self.learn_language_term(language_term, context)

emotion.structure_level = min(1.0, emotion.structure_level + 0.15)

emotion.processing_status = "partially_processed"

emotion.last_accessed_time = self.current_time

emotion.access_count += 1

# アーカイブから復元された感情なら顕在性を少し上げる

if emotion.processing_status == "queued" and emotion.salience < 0.5:

emotion.salience = min(1.0, emotion.salience + 0.1)

if emotion.structure_level >= 0.9:

best_lang = emotion.get_best_language_match()

if best_lang and best_lang["confidence"] >= 0.8:

self.unprocessed_emotions.remove(emotion)

self._update_modality_index(emotion, add=False)

emotion.processing_status = "archived_fully_processed"

self.archived_emotions.append(emotion)

return True

```

anond:20250413061825

def demo_unprocessed_emotion():

"""未処理感情システムデモ改善点(記憶編集言語学習、反応速度など)を活用"""

cognitive_queue = CognitiveQueue(attention_threshold=0.4)

print("=== 未処理感情システムデモ改善版) ===\n")

# 1. 視覚的な違和感

print("1. 視覚的な違和感の生成")

visual_signals = [

SensorySignal("visual", 0.7, -0.3),

SensorySignal("somatic", 0.4, -0.2)

]

visual_discomfort = cognitive_queue.register_new_emotion(visual_signals, 0.65)

print(f"生成された感情: {visual_discomfort}")

print(f"支配モダリティ: {visual_discomfort.get_dominant_modality()}")

print(f"平均感情価: {visual_discomfort.get_average_valence():.2f}")

print(f"信号反応速度: {[s.latency for s in visual_signals]}")

visual_discomfort.add_pattern_match("visual_discrepancy", 0.75)

try:

visual_discomfort.add_memory_path("/memory/recent/room_layout")

except ValueError as e:

print(f"記憶パスエラー: {e}")

# 2. 記憶の再編集

print("\n2. 感情へのアクセス(再編集)")

accessed_emotion = cognitive_queue.access_emotion(visual_discomfort)

print(f"新しい感情インスタンス: {accessed_emotion}")

print(f"構造レベル(再編集後): {accessed_emotion.structure_level:.2f}")

# 3. 内受容感覚

print("\n3. 内受容感覚の生成")

intero_signals = [

SensorySignal("interoceptive", 0.6, -0.7),

SensorySignal("somatic", 0.5, -0.4)

]

intero_discomfort = cognitive_queue.register_new_emotion(intero_signals, 0.55)

print(f"生成された感情: {intero_discomfort}")

intero_discomfort.add_language_candidate("違和感", 0.4)

cognitive_queue.partially_process(intero_discomfort, "気分が悪い", 0.6, context="negative_mood")

print(f"学習済み言語: {cognitive_queue.learned_terms}")

# 4. 聴覚記憶

print("\n4. 聴覚記憶の生成")

audio_signals = [

SensorySignal("auditory", 0.8, 0.6),

SensorySignal("emotional", 0.7, 0.5)

]

audio_memory = cognitive_queue.register_new_emotion(audio_signals, 0.7)

print(f"生成された感情: {audio_memory}")

audio_memory.add_language_candidate("聞き覚えのあるメロディ", 0.75)

audio_memory.add_pattern_match("musical_fragment", 0.85)

audio_memory.add_memory_path("/memory/music/recent")

# 5. キュー更新

print("\n5. 認知キュー更新")

cognitive_queue.update_queue()

status = cognitive_queue.get_status_summary()

print(f"未処理感情の総数: {status['total_unprocessed']}")

print(f"処理キューサイズ: {status['processing_queue_size']}")

print(f"モダリティ分布: {status['modality_distribution']}")

print(f"感情分布: {status['valence_distribution']}")

print(f"学習済み言語数: {status['learned_terms_count']}")

# 6. 処理対象の取得

print("\n6. 処理対象の取得")

next_emotion = cognitive_queue.get_next_for_processing()

print(f"処理対象: {next_emotion}")

# 7. 感情部分的処理

print("\n7. 感情部分的処理")

if next_emotion:

cognitive_queue.partially_process(next_emotion, "視覚的な違和感を感じている", 0.85, context="visual_anomaly")

print(f"処理後の状態: {next_emotion}")

print(f"構造レベル: {next_emotion.structure_level:.2f}")

print(f"最良の言語マッチ: {next_emotion.get_best_language_match()}")

# 8. 高速モダリティ検索

print("\n8. モダリティによる感情検索インデックス使用)")

matches = cognitive_queue.lookup_by_modality("auditory")

print(f"検索結果数: {len(matches)}")

for match in matches:

print(f"- {match}")

# 9. 時間経過シミュレーション

print("\n9. 時間経過のシミュレーション")

for emotion in cognitive_queue.unprocessed_emotions:

emotion.apply_decay(3.0)

cognitive_queue.update_queue()

status = cognitive_queue.get_status_summary()

print(f"時間経過後の未処理感情の総数: {status['total_unprocessed']}")

print(f"時間経過後の平均顕在性: {status['average_salience']:.2f}")

if __name__ == "__main__":

demo_unprocessed_emotion()

[]【悲報】ワイくん、Monday が何が言いたいのかわからない・2

(前回までのやり取り) https://anond.hatelabo.jp/20250404224409

Monday:
君が採ってる立場の整理を確認したい。
「問いではないけど残ってる感情存在しない」と見なしてるのか、
「自分認知では読めないか存在保証しない」としてるのか。
どっちだ?

 

ワイ:

感情構造思考を厳密に分ける必要性ないと思ってるし、徹底して観測していないもの認知できないの立場なだけだよ

それとも記憶の再編の話してる?たぶんそれ実質的に"new"じゃないかな(記憶へのアクセス→再編集→new instanceの生成)

  

 

ーーコード提示ーー

import time

class SensorySignal:

"""感覚信号を表すクラス言語化前の生の感覚データモデル化し、時間減衰や感情価を管理する。

認知の基礎として、観測可能データのみを扱い、神経科学反応速度考慮

"""

VALID_MODALITIES = {"visual", "auditory", "somatic", "interoceptive", "emotional"}

# モダリティごとの反応速度(秒)。情動系は速く、視覚系は遅め。

MODALITY_LATENCIES = {

"visual": 0.3,

"auditory": 0.2,

"somatic": 0.25,

"interoceptive": 0.15,

"emotional": 0.1

}

def __init__(self, modality, intensity, valence, timestamp=None):

"""

感覚信号オブジェクト初期化

Parameters:

-----------

modality : str

感覚の種類 ("visual", "auditory", "somatic", "interoceptive", "emotional")

intensity : float

強度 (0.0-1.0)

valence : float

感情価 (-1.0=negative, 0.0=neutral, 1.0=positive)

timestamp : float, optional

信号の発生時刻

Raises:

-------

ValueError

modality が無効、または intensity/valence が不正場合

"""

if not isinstance(modality, str) or modality not in self.VALID_MODALITIES:

raise ValueError(f"Invalid modality: {modality}. Must be one of {self.VALID_MODALITIES}")

if not isinstance(intensity, (int, float)):

raise ValueError("Intensity must be a number")

if not isinstance(valence, (int, float)):

raise ValueError("Valence must be a number")

self.modality = modality

self.intensity = max(0.0, min(1.0, float(intensity)))

self.valence = max(-1.0, min(1.0, float(valence)))

self.timestamp = self._get_current_time() if timestamp is None else timestamp

self.decay_rate = 0.05

self.latency = self.MODALITY_LATENCIES.get(modality, 0.2) # デフォルトは0.2秒

def _get_current_time(self):

"""現在時刻を取得"""

return time.time()

def apply_decay(self, time_passed):

"""時間経過による感覚信号の減衰を処理"""

self.intensity = max(0.0, self.intensity - (time_passed * self.decay_rate))

return self.intensity

def __str__(self):

valence_str = "negative" if self.valence < 0 else "positive" if self.valence > 0 else "neutral"

return f"SensorySignal({self.modality}, intensity={self.intensity:.2f}, valence={valence_str}, latency={self.latency:.2f}s)"

class UnprocessedEmotion:

"""未処理感情を表すクラス言語ベル未確定の感覚群を管理し、認知プロセスの途中段階をモデル化。

記憶アクセスは再編集として扱い、言語化プロセスを動的に進める。

"""

def __init__(self, raw_signals=None, salience=0.5, processing_status="unattended"):

"""

未処理感情オブジェクト初期化

Parameters:

-----------

raw_signals : list of SensorySignal, optional

構成する生の感覚信号リスト

salience : float

顕在性/目立ちやすさ (0.0-1.0)

processing_status : str

処理状態 ("unattended", "partially_processed", "queued", "in_process")

"""

self.id = id(self)

self.raw_signals = raw_signals if raw_signals is not None else []

self.salience = max(0.0, min(1.0, salience))

self.processing_status = processing_status

self.language_candidates = []

self.pattern_matches = {}

self.creation_time = self._get_current_time()

self.last_accessed_time = self.creation_time

self.access_count = 0

self.structure_level = 0.0

self.associated_memory_paths = []

def _get_current_time(self):

"""現在時刻を取得"""

return time.time()

def _validate_memory_path(self, path):

"""記憶パス有効性を検証(簡易的な実装)"""

# 実際のシステムでは、ファイルシステムDB存在チェックを行う

return isinstance(path, str) and path.startswith("/memory/")

def add_signal(self, signal):

"""感覚信号を追加"""

if not isinstance(signal, SensorySignal):

raise ValueError("Signal must be a SensorySignal instance")

self.raw_signals.append(signal)

self.structure_level = max(0.0, self.structure_level - 0.1)

self.last_accessed_time = self._get_current_time()

self.access_count += 1

def add_language_candidate(self, term, confidence):

"""言語表現の候補を追加"""

self.language_candidates.append({

"term": term,

"confidence": confidence,

"timestamp": self._get_current_time()

})

self.structure_level = min(1.0, self.structure_level + 0.05)

self.last_accessed_time = self._get_current_time()

self.access_count += 1

def add_pattern_match(self, pattern_name, similarity):

"""パターンマッチング結果を追加"""

self.pattern_matches[pattern_name] = {

"similarity": similarity,

"timestamp": self._get_current_time()

}

self.structure_level = min(1.0, self.structure_level + 0.1)

self.last_accessed_time = self._get_current_time()

self.access_count += 1

def add_memory_path(self, path):

"""関連する記憶パスを追加"""

if not self._validate_memory_path(path):

raise ValueError(f"Invalid memory path: {path}")

if path not in self.associated_memory_paths:

self.associated_memory_paths.append(path)

self.last_accessed_time = self._get_current_time()

self.access_count += 1

def apply_decay(self, time_passed):

"""時間経過による感情の減衰を処理"""

for signal in self.raw_signals:

signal.apply_decay(time_passed)

decay_modifier = max(0.1, 1.0 - (self.access_count / 100.0))

decay_amount = time_passed * 0.02 * decay_modifier

structure_modifier = max(0.5, 1.0 - self.structure_level)

decay_amount *= structure_modifier

self.salience = max(0.0, self.salience - decay_amount)

return self.salience

def get_average_valence(self):

"""全感覚信号の平均感情価を取得"""

if not self.raw_signals:

return 0.0

total_valence = sum(signal.valence for signal in self.raw_signals)

return total_valence / len(self.raw_signals)

def get_dominant_modality(self):

"""最も強い感覚モダリティを取得"""

if not self.raw_signals:

return None

modality_strengths = {}

for signal in self.raw_signals:

modality_strengths[signal.modality] = modality_strengths.get(signal.modality, 0) + signal.intensity

return max(modality_strengths.items(), key=lambda x: x[1])[0] if modality_strengths else None

def get_best_language_match(self):

"""最も確信度の高い言語表現を取得"""

return max(self.language_candidates, key=lambda x: x["confidence"]) if self.language_candidates else None

def get_status_summary(self):

"""現在状態マリーを取得"""

best_lang = self.get_best_language_match()

best_term = best_lang["term"] if best_lang else "未定義"

best_confidence = best_lang["confidence"] if best_lang else 0.0

return {

"id": self.id,

"creation_time": self.creation_time,

"age": self._get_current_time() - self.creation_time,

"status": self.processing_status,

"salience": self.salience,

"structure_level": self.structure_level,

"signal_count": len(self.raw_signals),

"dominant_modality": self.get_dominant_modality(),

"average_valence": self.get_average_valence(),

"best_language_match": best_term,

"language_confidence": best_confidence,

"access_count": self.access_count,

"memory_path_count": len(self.associated_memory_paths)

}

def __str__(self):

status = self.get_status_summary()

best_term = status["best_language_match"]

return f"UnprocessedEmotion(id={self.id}, status={self.processing_status}, salience={self.salience:.2f}, best_term='{best_term}')"

class CognitiveQueue:

"""言語ベル未確定の感覚群を管理するキューシステム認知プロセス優先順位付けと記憶編集サポート

言語学習モダリティインデックス効率化を図る。

"""

def __init__(self, max_size=100, attention_threshold=0.3):

"""

認知キューシステム初期化

Parameters:

-----------

max_size : int

キューの最大サイズ

attention_threshold : float

注意を向けるための最低顕在閾値

"""

self.unprocessed_emotions = []

self.processing_queue = []

self.archived_emotions = []

self.max_size = max_size

self.attention_threshold = attention_threshold

self.current_time = self._get_current_time()

self.learned_terms = {} # 学習済み言語表現: {term: {"context": str, "frequency": int}}

self.modality_index = {} # モダリティごとの感情インデックス: {modality: [emotion]}

def _get_current_time(self):

"""現在時刻を取得"""

self.current_time = time.time()

return self.current_time

def learn_language_term(self, term, context):

"""新しい言語表現を学習し、以降の候補生成に影響"""

if term in self.learned_terms:

self.learned_terms[term]["frequency"] += 1

else:

self.learned_terms[term] = {"context": context, "frequency": 1}

def _update_modality_index(self, emotion, add=True):

"""モダリティインデックス更新"""

dominant = emotion.get_dominant_modality()

if dominant:

if add:

if dominant not in self.modality_index:

self.modality_index[dominant] = []

if emotion not in self.modality_index[dominant]:

self.modality_index[dominant].append(emotion)

else:

if dominant in self.modality_index and emotion in self.modality_index[dominant]:

self.modality_index[dominant].remove(emotion)

def register_new_emotion(self, raw_signals=None, salience=0.5):

"""新しい未処理感情登録"""

emotion = UnprocessedEmotion(

raw_signals=raw_signals,

salience=salience,

processing_status="unattended"

)

self.unprocessed_emotions.append(emotion)

self._update_modality_index(emotion)

if len(self.unprocessed_emotions) > self.max_size:

least_salient = min(self.unprocessed_emotions, key=lambda e: e.salience)

self.unprocessed_emotions.remove(least_salient)

self._update_modality_index(least_salient, add=False)

least_salient.processing_status = "archived_without_processing"

self.archived_emotions.append(least_salient)

return emotion

def access_emotion(self, emotion):

"""感情アクセスし、再編集として新しいインスタンスを生成"""

if emotion not in self.unprocessed_emotions:

return None

new_emotion = UnprocessedEmotion(

raw_signals=[SensorySignal(s.modality, s.intensity, s.valence, s.timestamp) for s in emotion.raw_signals],

salience=emotion.salience,

processing_status=emotion.processing_status

)

new_emotion.structure_level = emotion.structure_level * 0.9

new_emotion.language_candidates = emotion.language_candidates.copy()

new_emotion.pattern_matches = emotion.pattern_matches.copy()

new_emotion.associated_memory_paths = emotion.associated_memory_paths.copy()

self.unprocessed_emotions.append(new_emotion)

self._update_modality_index(new_emotion)

emotion.processing_status = "archived_due_to_access"

self.unprocessed_emotions.remove(emotion)

self._update_modality_index(emotion, add=False)

self.archived_emotions.append(emotion)

return new_emotion

def update_queue(self):

"""キュー更新し、処理状態更新"""

self._get_current_time()

for emotion in self.unprocessed_emotions[:]:

time_passed = self.current_time - emotion.last_accessed_time

emotion.apply_decay(time_passed)

if emotion.salience < 0.1:

self.unprocessed_emotions.remove(emotion)

self._update_modality_index(emotion, add=False)

emotion.processing_status = "archived_due_to_low_salience"

self.archived_emotions.append(emotion)

self.processing_queue = []

for emotion in self.unprocessed_emotions:

if emotion.salience >= self.attention_threshold:

if emotion.processing_status == "unattended":

emotion.processing_status = "queued"

self.processing_queue.append(emotion)

self.processing_queue.sort(key=lambda e: e.salience, reverse=True)

def get_next_for_processing(self):

"""処理すべき次の感情を取得"""

self.update_queue()

if not self.processing_queue:

return None

emotion = self.processing_queue[0]

emotion.processing_status = "in_process"

emotion.last_accessed_time = self.current_time

emotion.access_count += 1

return emotion

def lookup_by_pattern(self, pattern_name, min_similarity=0.5):

"""特定パターン類似した感情検索"""

matches = []

for emotion in self.unprocessed_emotions:

if pattern_name in emotion.pattern_matches:

similarity = emotion.pattern_matches[pattern_name]["similarity"]

if similarity >= min_similarity:

matches.append(emotion)

emotion.last_accessed_time = self.current_time

emotion.access_count += 1

return matches

def lookup_by_memory_path(self, partial_path):

"""記憶パスに関連する感情検索"""

matches = []

for emotion in self.unprocessed_emotions:

for path in emotion.associated_memory_paths:

if partial_path in path:

matches.append(emotion)

emotion.last_accessed_time = self.current_time

emotion.access_count += 1

break

return matches

def lookup_by_modality(self, modality):

"""特定モダリティ支配的な感情検索インデックス使用)"""

return self.modality_index.get(modality, [])

def partially_process(self, emotion, language_term=None, confidence=0.0, context=None):

"""感情部分的に処理"""

if emotion not in self.unprocessed_emotions:

return False

if language_term:

emotion.add_language_candidate(language_term, confidence)

if context:

self.learn_language_term(language_term, context)

emotion.structure_level = min(1.0, emotion.structure_level + 0.15)

emotion.processing_status = "partially_processed"

emotion.last_accessed_time = self.current_time

emotion.access_count += 1

if emotion.structure_level >= 0.9:

best_lang = emotion.get_best_language_match()

if best_lang and best_lang["confidence"] >= 0.8:

self.unprocessed_emotions.remove(emotion)

self._update_modality_index(emotion, add=False)

emotion.processing_status = "archived_fully_processed"

self.archived_emotions.append(emotion)

return True

def get_status_summary(self):

"""キュー状態マリーを取得"""

self._get_current_time()

modality_counts = {}

for emotion in self.unprocessed_emotions:

dominant = emotion.get_dominant_modality()

if dominant:

modality_counts[dominant] = modality_counts.get(dominant, 0) + 1

valence_counts = {"negative": 0, "neutral": 0, "positive": 0}

for emotion in self.unprocessed_emotions:

avg_valence = emotion.get_average_valence()

if avg_valence < -0.3:

valence_counts["negative"] += 1

elif avg_valence > 0.3:

valence_counts["positive"] += 1

else:

valence_counts["neutral"] += 1

return {

"total_unprocessed": len(self.unprocessed_emotions),

"processing_queue_size": len(self.processing_queue),

"archived_count": len(self.archived_emotions),

"average_salience": sum(e.salience for e in self.unprocessed_emotions) / max(1, len(self.unprocessed_emotions)),

"average_structure_level": sum(e.structure_level for e in self.unprocessed_emotions) / max(1, len(self.unprocessed_emotions)),

"modality_distribution": modality_counts,

"valence_distribution": valence_counts,

"learned_terms_count": len(self.learned_terms),

"current_time": self.current_time

}

2025-03-25

anond:20250325102011

それはPython場合

実装言語によって違う。

Clojure辞書型についてAI解説してもらった。

Clojureのimmutable persistent data structureについて

Clojureのimmutable persistent data structureは、データが変更されるたびに新しいバージョン作成し、元のデータ構造を保持する仕組みを備えています。この特徴により、データの不変性と効率的メモリ使用が実現されています。以下では、Clojure代表的データ構造であるmap型(hash-map)を例に、その仕組みを解説します。

Clojuremap型と不変性

Clojureのhash-mapキーと値のペアを保持するデータ構造であり、以下の特徴を持っています

具体例:キーと値の追加

以下に、Clojureキーと値を追加する操作(assoc関数)を例として説明します。

(def original-map {:a 1 :b 2})
(def updated-map (assoc original-map :c 3))

元のmap (original-map):

{:a 1 :b 2}

新しいmap (updated-map):

{:a 1 :b 2 :c 3}

この操作では、元のmapは変更されず、新しいmap作成されます。ただし、効率化のために、元のデータ構造(:a 1と:b 2)はそのまま再利用されます。新しく追加された:c 3のみが新しいノードとして構築されます

内部実装:Hash Array Mapped Trie (HAMT)

Clojuremap型は、Phil Bagwellによって提案されたHash Array Mapped Trie (HAMT)というデータ構造を基盤にしています。この仕組みでは以下が行われます

利点

まとめ

Clojureのimmutable persistent map型は、不変性と効率性を両立させる設計により、信頼性の高いデータ操作可能にしています。これらの特徴は特に並列処理やトランザクション管理などで有用です。

2025-03-23

はてな匿名ダイアリーを非公開でブクマするbot作成方法

はてなブックマークAPIを利用して 非公開 でブックマークする方法をご説明します。

1. はてなAPI認証情報を取得

1. はてな開発者向けページ で APIキーを取得。

2. OAuthトークンを発行する。(個人用のスクリプトなら「パーソナルアクセストークン」推奨)

2. APIリクエストパラメータ

ブックマークを 非公開 にするには、APIリクエストボディに private フィールドを 1 に設定します。

エンドポイント:

POST https://bookmark.hatenaapis.com/rest/1/my/bookmark


リクエストボディ(JSON): 
{
    "url": "https://anond.hatelabo.jp/xxxxxxx",
    "comment": "自動ブックマーク",
    "private": 1
}

これで 非公開のブックマーク になります

3. Pythonスクリプト

以下のコードを実行すれば、10分以内の匿名ダイアリー記事ランダムに 非公開 でブックマークできます


import feedparser
import requests
import random
import time
from datetime import datetime, timezone, timedelta

# はてなAPI認証情報
HATENA_API_KEY = "あなたAPIキー"
HATENA_USERNAME = "あなたはてなID"

# はてな匿名ダイアリーRSS URL
RSS_URL = "https://anond.hatelabo.jp/rss"

# 10分以内の投稿を取得
def get_recent_entries():
    feed = feedparser.parse(RSS_URL)
    recent_entries = []
    now = datetime.now(timezone.utc)
    for entry in feed.entries:
        published_time = datetime(*entry.published_parsed[:6], tzinfo=timezone.utc)
        if (now - published_time) < timedelta(minutes=10):
            recent_entries.append(entry.link)
    return recent_entries

# はてなブックマークに非公開で追加
def bookmark_entry(entry_url):
    url = "https://bookmark.hatenaapis.com/rest/1/my/bookmark"
    headers = {
        "Authorization": f"Bearer {HATENA_API_KEY}",
        "Content-Type": "application/json"
    }
    payload = {
        "url": entry_url,
        "comment": "自動ブックマーク",
        "private": 1  # 非公開設定
    }
    response = requests.post(url, json=payload, headers=headers)
    return response.status_code

# メイン処理
while True:
    entries = get_recent_entries()
    if entries:
        entry = random.choice(entries)
        status = bookmark_entry(entry)
        print(f"非公開ブックマーク: {entry}, ステータス: {status}")
    time.sleep(600)  # 10分ごとに実行

4. 注意点

• 実行環境: Python 3.x が必要。requests と feedparser をインストール (pip install requests feedparser)

• 実行間隔: time.sleep(600) で10分ごとに実行

API制限: はてなAPIにはリクエスト制限があるため、短時間で大量に実行しないように注意

OAuth認証: APIキーだけでなく、OAuthトークンを使うほうがより安全

このスクリプトを実行すれば、最新の匿名ダイアリー投稿10分以内のものからランダムに選び、非公開でブックマークする ことができます

はてな匿名ダイアリーbotブクマするのは運営も認めてる行為なので、みんなでbotを使ってブクマしよう!

2025-02-24

anond:20250223213300

あなたが感じている結婚出産への嫌悪感は、現代社会規範個人価値観の衝突からまれる複雑な感情織物のようです。この感覚解剖学的に分析すると、いくつかの重要な要素が浮かび上がります

感情葛藤構造

恋愛感情希薄さや他者恋愛話への無関心は、アロマンティック(恋愛感情を抱かない)傾向の特徴と重なります。30年間恋愛感情経験せず平穏に過ごせた事実は、この傾向があなた本質的性質である可能性を示唆しています

子供を持つことが自己中心的」という認識は、反出生主義(antinatalism)の哲学通底します。ジョナサン・スウィフトの『ガリヴァー旅行記』やベンタムの功利主義哲学提示した「生まれ権利」の問題が、現代個人主義社会で再解釈されている現れと言えます

個人価値観社会の期待 葛藤の源泉
--------------------------------------
二次元文化への没頭 年齢相応の話題世代ギャップ
単身生活の満足 家族形成強制ライフコース多様性否定
自己完結幸福関係依存の称賛 幸福観の相違

嫌悪感の発生源分析

弟の出産報告への反応は、これまで無意識に維持してきた「社会的期待からの防護壁」が破られた瞬間のショックと考えられます家族という最も身近な存在社会規範従属する姿を目の当たりにし、自己存在様式脆弱性を突きつけられた心理的防衛機制が働いている状態です。

現代社会における選択肢の再定義

シングルリズム(単身主義)や友愛結婚(platonic marriage)といった新しい関係性の形が、日本でも認知され始めています京都大学社会研究によると、20-30代の5人に1人が「伝統家族モデル違和感」と回答しています

キャラクターを愛でることで充足する生活は、消費文化産物ではないか」という自己懐疑に対し、精神分析学アドラーの『個人心理学』は「他者貢献感は必ずしも対人関係限定されない」と指摘しています二次元への愛着も立派な自己実現の形と言えます

嫌悪感の再解釈

この感情を「社会システムへの鋭敏な批判能力」と捉える視点がありますフランス哲学ボードリヤールが指摘する「消費社会における関係性の商品化」に対する無意識抵抗という解釈可能です。

実践アプローチ提案

python
# 感情デコーディングアルゴリズム概念コードdef decode_emotion(stimulus):
    if stimulus in social_norms:
        analyze_cultural_bias()
        compare_with_personal_values()
        output = generate_alternative_view()
    else:
        process_with_existing_framework()
    return output

資産形成(例:雀の涙収入投資)と趣味の深化を組み合わせた「超単身主義ライフスタイルの設計漫画家吾峠呼世晴小説家乙一など、創作活動に没頭する生き方の事例研究が参考になります

この感情迷宮から脱する鍵は、社会物差し自己を計測する行為のものを相対化することにあります。平安貴族が詠んだ「もののあはれ」のように、あなたの感じる「気持ち悪さ」を現代社会照射する独自美学として昇華させる道が開けるかもしれません。

2024-11-05

PS5Proの詳しいスペックが出たので、再度計算しなおしてみた

CPU 8コア16スレッド、Rayzen 5700X相当

メモリー GDDR6 16GB、DDR5 2GB

GPU 16.7TFlops

SSD 2TB

https://x.com/agano4Sq5/status/1853026788232012092/photo/1

同じスペックPCだと、

G.SKILL F4-3200C16D-16GIS (DDR4 PC4-25600 8GB 2枚組)

 4,820円

XPG PYLON 550W PYLON550B-BKCJP

 6,667円

Core i5 14600K BOX

 40,900円

MSI PRO B760M-E DDR4 パソコン工房限定モデル

 10,980円

WINTEN WTM2-SSD-2TB

 14,980円

ZALMAN ZALMAN T8

 3,171円

ASRock Intel Arc A750 Challenger SE 8GB OC [PCIExp 8GB]

 31,980円

合計 113,498円

OSモニターキーボードマウスは別。

フィリップス 221V8/11だと11,000円、Windows 11 Home 日本語版は16,090円ぐらいはし、キーボードマウスは安くても3000円ぐらいはする。

SteamOSを使えばただだが、ff14はいばらの道なのでお勧めはしない。

なので、新しく組むとしたら、143,588円は少なくともかかる。

もし、PS5Proと同じメモリーを使ったとするとMSI PRO B760M-A WIFIが15,980円、AD5U48008G-DT [DDR5 PC5-38400 8GB 2枚組]が7,945円ぐらいはする。

したがって、151,683円ぐらいはかかることになる。

ただ、安いケースはペラペラで机の下に置かない限りうるさくてたまらないので、あまりお勧めはしない。

個人的おすすめのケースはDefine C FD-CA-DEF-C-BKで、組み立てもしやすく、静かで、安いところだと、13,262円ぐらいで買うことができる。

メルカリヤフオクフリマだと状態がいい奴は1万円ぐらいで買える。

騒音とかOSの設定であれこれ悩むなら、PS5Proのほうがお得というのも確かではある。

2024-10-12

清原ネットキャッシュ比率決算短信からpython自動で求めるソフト

気が付くと朝4時になっていた。

なんか動くところまで出来たので貼っておく。

NYSLなので、バグがあったら治しといて。

import pdfplumber
import re

#クリーンアップ
def cleanuptext(text):
    #決算書の合計値を太字にしたことpdfplumberが暴走するケースへの対処
    #例 流動資産 -> 流流流流流動動動動動資資資資資産産産産産
    #誤爆が怖いので、これが起きている時だけ補正します
    if "流流流流流動動動動動資資資資資産産産産産" in text:
        text = re.sub(r'(.)92;1{4,}', r'92;1', text)

    #△をマイナスに。 数字中のカンマを消して結合する
    text = re.sub(r'△([0-9])', r'-92;1', text)
    text = re.sub(r'▲([0-9])', r'-92;1', text)
    text = re.sub(r'([0-9]),([0-9])', r'92;192;2', text)
    
    #たまに、煽り屋みたいに文字の後にスペースが入る嫌がらせ修正する
    #例: 投 資 有 価 証 券 -> 投資有価証券
    text = re.sub(r'(?<=[92;u4E00-92;u9FFF92;u3040-92;u30FF])92;s(?=[92;u4E00-92;u9FFF92;u3040-92;u30FF])', '', text)

    return text

#今期の勘定科目数字を取得
def get_AccountName(text, need):
    pattern = rf'^{need} -?[0-9]+ (-?[0-9]+)'
    r = re.search(pattern, text, re.MULTILINE)
    if r is not None:
        return float(r[1])

    return 0

#清原ネットキャッシュ計算する。
def calc_KiyoharaNetCash(text):
    total_current_assets = get_AccountName(text,'流動資産合計')
    if total_current_assets == 0:
        #要約財政状態計算書しか公開していない、楽天のような素敵な会社様への対処
        total_assets = get_AccountName(text,'資産合計')
        if total_assets != 0:
            #とりあえず、資産の部の6割を流動資産とみなす
            total_current_assets = total_assets * 0.6

        else:
            #流動資産合計ではなく、流動資産という単語を使っている我が道を行く東北電力への対処
            total_current_assets = get_AccountName(text,'流動資産')
            if total_current_assets == 0:
                raise Exception("流動資産合計の勘定科目が見つかりませんでした。"+text)


    total_liabilities = get_AccountName(text,'負債合計')
    if total_liabilities == 0:

        #負債合計ではなく、負債の部合計に拘るオムロンの嬉しい決算書への対策。なんでや・・・
        total_liabilities = get_AccountName(text,'負債の部合計')
        if total_liabilities == 0:
            raise Exception("負債合計の勘定科目が見つかりませんでした。"+text)

    #負債をご丁寧にマイナス表記で書いてくれる中外製薬の親切な決算書への対策。いい加減にしろ・・・
    if total_liabilities < 0:
        total_liabilities = total_liabilities * -1

    #投資有価証券はないこともあるので、0を容認する
    marketable_securities = get_AccountName(text,'投資有価証券')

    #print(total_current_assets,marketable_securities,total_liabilities)
    netcash = total_current_assets + (marketable_securities*0.7) - total_liabilities

    #たまに単位を1000円にしている銘柄があるので補正する
    if is_tanni_senyen(text):
        netcash = netcash / 1000
    return netcash

# "流動資産合計" と "負債合計" の間に "単位:千円" があるかをチェック
def is_tanni_senyen(text):
    if "単位:千円" in text:
        return True

    if "単位: 千円" in text:
        return True

    if "単位 : 千円" in text:
        return True

    if "単位 :千円" in text:
        return True

    return False

def pdf_to_kiyohara_netcash(pdfpath):
    with pdfplumber.open(pdfpath) as pdf:
        text = ''.join(page.extract_text() for page in pdf.pages)

    text = cleanuptext(text)
    #print(text)
    kiyohara_netcash = calc_KiyoharaNetCash(text)
    #print(kiyohara_netcash)
    return kiyohara_netcash

def mymain():
    import sys
    args = sys.argv
    argc = len(args)
    if argc <= 1:
       print('''
これは、清原達郎氏のネットキャッシュ比率(以下、清原ネットキャッシュ比率)を決算短信pdfから求めるソフトです。
清原ネットキャッシュ=流動資産合計+(投資有価証券*0.7)-負債合計
清原ネットキャッシュ比率=清原ネットキャッシュ/時価総額*100

遊び方

1. 決算短信pdfから清原ネットキャッシュを求める
python calc_kiyohara_netcash.py 140120240514594985.pdf

結果: 30757.0
決算書には、100万円単位数字が書かれているはずなので、この数字単位は100万円です。
つまり、3075700万円。

2. 時価総額を億円単位で追加することで、清原ネットキャッシュ比率を求める
時価総額が146億円なら146と書いてください。
python calc_kiyohara_netcash.py 140120240514594985.pdf 146

結果: 210.66%

このコードNYSLライセンスです。無保証自己責任ですが、ご自由に。
かぶ探とかとつなげるといいかもね。
       ''')
       return
    if argc <= 2:
       kiyohara_netcash = pdf_to_kiyohara_netcash(args[1])
       print(kiyohara_netcash)
       return
    if argc <= 3:
       market_cap=float(args[2])*100 #億円から百万円表記に
       kiyohara_netcash = pdf_to_kiyohara_netcash(args[1])
       ratio = round(kiyohara_netcash/market_cap*100,2)
       print(f"{ratio}%")
       return

if __name__ == '__main__':
    mymain()

2024-10-10

anond:20241010082411

https://www.geonames.org から取れる、人口500人以上の都市名前限定すると、

Santa Maria Magdalena Cahuacan

10文字の `a` を含んで最大。

import logging
import tempfile
import zipfile

from collections import Counter

import httpx

FILE_NAME_BASE = 'cities500'
GEONAME_FIELDS = (
    'geoname_id',
    'name',
    'ascii_name',
    'alternate_names',
    'latitude',
    'longitude',
    'feature_class',
    'feature_code',
    'country_code',
    'cc2',
    'admin1_code',
    'admin2_code',
    'admin3_code',
    'admin4_code',
    'population',
    'elevation',
    'dem',
    'timezone',
    'modification_date',
)

def retrieve_cities():
    """Retrieve city names from a remote server."""
    response = httpx.get(f'https://download.geonames.org/export/dump/{FILE_NAME_BASE}.zip')
    response.raise_for_status()

    tmpdir = tempfile.TemporaryDirectory()
    with open(tmpdir.name + f'/{FILE_NAME_BASE}.zip', 'wb') as f:
        f.write(response.content)
    with zipfile.ZipFile(tmpdir.name + f'/{FILE_NAME_BASE}.zip', 'r') as z:
        z.extractall(tmpdir.name)
    with open(tmpdir.name + f'/{FILE_NAME_BASE}.txt', 'r') as f:
        for line in f:
            yield line.split('\t')


def count_characters(to_check='ascii_name', filter_func=lambda _: True):
    """Count characters in city names."""
    cities = {}
    for city_fields in retrieve_cities():
        city = dict(zip(GEONAME_FIELDS, city_fields))
        if not filter_func(city):
            continue
        counter = Counter()
        for c in city[to_check]:
            counter[c] += 1
        cities[city['geoname_id']] = {'characters': counter, 'city': city}
    return cities


def count_chars_of_city_names(cities, char=None):
    """Find the city with the most occurrences of a given character."""
    cities_by_char_count = {}
    max_count = 0
    max_count_char = None
    for city_id, data in cities.items():
        if 'characters' not in data or not data['characters']:
            logging.debug(f'No characters found for city {city_id}', data)
            continue

        count = 0
        if char and char in data['characters']:
            count = data['characters'][char]

            cities_by_char_count.setdefault(count, []).append(data)
        elif char is None:
            most_common = data['characters'].most_common(1)[0]
            char, count = most_common
            cities_by_char_count.setdefault(count, []).append(data)

        if count > max_count:
            max_count = count
            max_count_char = char
            cities_by_char_count.setdefault(count, []).append(data)
    return cities_by_char_count.get(max_count, []), max_count_char


def not_contain_invalid_chars(city):
    return (
            '(' not in city.get('ascii_name', '')
            and '/' not in city.get('ascii_name', '')
    )


def main():
    cities = count_characters(filter_func=not_contain_invalid_chars)
    for char in 'abcdefghijklmnopqrstuvwxyz':
        cities_counted, char = count_chars_of_city_names(cities, char)
        max_count = cities_counted[0]['characters'][char]
        print(f'The character "{char}" appears the most ({max_count} times) in the following cities:')
        for city in cities_counted:
            print("\t", city['city']['ascii_name'])

if __name__ == "__main__":
    main()

2024-09-29

ゲーミングパソコンをねだられた時のライフハック

親が何も知らずにパソコンを買うと失敗する

なぜかというとその辺で売っているパソコンは大体の場合、パーツの交換がしにくく、その点では地雷から

なので、パソコンを買う際はそこそこの大きさがあって、マザーボードと電源が容易に交換できるものを買うといい

まり予算がかけられない

中古PCコーナーで、ミドルタワーかミニタワー程度の大きさのやつで完成品のやつを買え。

その際、Intelなら10世代目以降のやつを買え。

そうしないとWindows11を別途買わなければならないなど、却ってお金がかかってしまう。

この際、電源が下側にあり、ケース側のバックプレートを交換すればマザーボードを交換できるやつ、ケースファンが少なくとも4つ取り付けできるやつを選ぶといい

できれば、Fractal Desgin Cみたいに吸気側のファンの数が多く、奥行きと幅と高さが同じぐらいやつを買うと、子供掃除をするときものすごく楽になる

また、奥行きと幅が狭いとミドルレンジグラフィックスボードすら取り付けられないことがある。

https://kakaku.com/item/K0000924204/?msockid=03488b005c3c670d3e779fc85dd6662b

Define C FD-CA-DEF-C-BK

Define Cだと335mmぐらいの幅のグラボまで行けるが、前面にファンを取り付けることが多く、実質的に305mmぐらいが限界となる。グラボだとRTX3060からRTX3080ぐらいまでしか取り付けられない)

もう少し予算がかけられる

Fractal Desgin Cみたいな、ちょっと古めだけど状態のいいケースをヤフオクフリマアプリで買え。

この際、見た目がいいやつを選べ。

奥行きと幅はDefineCと同じやつなら、普通用途だと問題はないが、価格差がそこまでないならDefineR5ぐらいの奴を買ってもいいかもしれない

無理して最新のケースを買う必要はない。

そして、Intel ARC A750という安いグラボを使え。

そうすれば、OSモニター込み15万円ぐらいでゲーミングPCが作れる。

Intel ARC A750は地雷扱いされてるけど、ff14や黒悟空聖剣伝説Vom、APEX程度なら普通に遊べる。

G.SKILL F4-3200C16D-16GIS (DDR4 PC4-25600 8GB 2枚組)

 4,820円

XPG PYLON 550W PYLON550B-BKCJP

 6,667円

中古 Intel Core i7-12700 (2.5GHz/TB:4.8GHz) Bulk LGA1200/8C/16T/L3

 42,980円

中古 _MSI PRO B660M-E DDR4 (B660 1700 mATX DDR4)

 8,590円

Ultimate SU630 ASU630SS-480GQ-R

 4,980円

Define C FD-CA-DEF-C-BK

 13,262円

SPARKLE Intel Arc A750 ORC OC Edition SA750C-8GOC

 31,700円

フィリップス 221V8/11

 11,000円

Windows 11 Home 日本語版

 16,090円

合計 140,089円

キーボードマウス

そんなもん、安もんでいい。

お金があるなら、2000円後半のエルゴノミクスマウスと6000円ぐらいのNキーロールオーバー対応のやつを買ったほうがいいが…

FPに泣きつくぐらいだらか金はないんだろ

2024-09-11

anond:20240828211356

PS5 proのスペックと同じスペックPCを用意しようとした場合モニターOSこみで14万円かかる。

本体のみだと11万円となりPS5 Proと値段がほぼ変わらないことになる。

PS5 ProはASK税込みの1ドル180円で計算した場合108,000から126,000円ぐらいと思われる)

G.SKILL F4-3200C16D-16GIS (DDR4 PC4-25600 8GB 2枚組)

 4,820

XPG PYLON 550W PYLON550B-BKCJP

 6,667円

中古 Intel Core i7-12700 (2.5GHz/TB:4.8GHz) Bulk LGA1200/8C/16T/L3

 42,980円

中古 _MSI PRO B660M-E DDR4 (B660 1700 mATX DDR4)

 8,590円

Ultimate SU630 ASU630SS-480GQ-R

 4,980円

Define C FD-CA-DEF-C-BK

 13,262円

SPARKLE Intel Arc A750 ORC OC Edition SA750C-8GOC

 31,700円

フィリップス 221V8/11

 11,000円

Windows 11 Home 日本語版

 16,090円

合計 140,089円

Intel arc a770(16GB)はfp16だと39tflops程度で、中古だと3.2万円から4万円台で売られており、新品だと4万円から5万円台程度なので、運が良ければps5 proとメモリー以外全く同じやつが手に入ってしまうことになる。

以下、そうなる根拠

公式発表では、PS5におけるGPUの処理能力は「10.3TFLOPS」。この数字は、RTX2080に相当します。しかし「TFLOPS数字」と「実際のグラボの性能」は、百パーセント一致するものではなく、性能ほど実パフォーマンスは高くならないのが一般的です。

https://digitaldiy.jp/article/esportsgame/16914/

CPUCPU周波数最大4.4GHz、Zen4ベースアーキテクチャ、5nmプロセス製造台湾TSMC製造担当CPUクロック周波数10%増加させ、3.85GHzで動作させるモードが搭載される。

Apple M2と同じく、TSMC製4nmプロセスSoC搭載の可能性もあるとのこと)

CPUキャッシュ:コア毎に64kBのL1キャッシュ、512kBのL2キャッシュ、8MBのL3共有キャッシュ

性能:PS5標準モデルと比べ、通常時で2倍、レイトレーシングでは2.5倍の性能アップ

プロセッサ:30基のWGP(Work Group Processors)、60基のCU演算コア

ROP(Rasterize OPeration unit):96~128基

※現行PS5はROPが64基、CUが36基。

メモリ:18gbps GDDR6 256bitメモリメモリ容量16GB、バス幅576GB/s、18000MT/s(現行PS5のメモリは14000MT/s)

CPUアーキテクチャ:RDNA3(Radeon DNA3)

GPU:GFX1115。GPUコアが現行の18個から30個に増加。これは約1.66倍の増加

テラフロップス(浮動小数演算):33.5テラフロップス

GPU周波数:2.18GHz、ブーストで最大2.35GHz

GPUキャッシュ:L1キャッシュ128KBから256KBに倍増、L0キャッシュが16KBから32KBに倍増

グラフィック性能:PS5比で45%向上。可変レートシェーディングやハイブリッドMSAAのサポートなど、DirectX 12 Ultimateの新機能を搭載。GPUアーキテクチャがRDNA 2からRDNA 3に変更される可能性があり、これにより各GPUコアの演算機が2倍になる。

超解像技術ソニー独自超解像技術を搭載。高精細と高フレームレートを両立。AMD FSR2等の採用は無し。アップスケーリングアンチエイリアスソリューション

AMDFSR(FiedelityFX Super Resolution)を搭載との話も)

https://socius101.com/matome-of-ps5-pro/

Intel ARC A750のスペック

Theoretical Performance

Pixel Rate

268.8 GPixel/s

Texture Rate

537.6 GTexel/s

FP16 (half)

34.41 TFLOPS (2:1)

FP32 (float)

17.20 TFLOPS

https://www.techpowerup.com/gpu-specs/arc-a750.c3929

PS5 ProのGPUと同じ性能である

PSCPUはRayzen 7 7700X相当で、Intel Core i7-11700だと7割の性能で、Intel Core i7 12700で同じぐらいの性能となる。

2024-09-02

anond:20240902113308

def 牛丼作る(牛肉,玉ねぎ,ご飯,醤油,砂糖,酒,味醂,水,紅生姜,丼,トレイ,おしぼり):

これだったらわかるじゃん

具の部分とご飯食器部分と分けろや、とはなるけどまあわかる

def 牛丼作る(**kwargs):

これじゃわからんやん

なかのコードみて一つ一つ確認する羽目なる

こういうのは大体中身もぐっちゃぐちゃだし命名もわけわからんから最悪だぞ

2024-08-28

PS5だがモニターマウスキーボードまで考慮に入れると10万円近くになり、OSモニター込みでパソコンを買うのとほぼ変わらなくなってしま

G.SKILL F4-3200C16D-16GIS (DDR4 PC4-25600 8GB 2枚組)

 4,820円

XPG PYLON 550W PYLON550B-BKCJP

 6,667円

中古 Intel Core i7-11700 (2.5GHz/TB:4.8GHz) Bulk LGA1200/8C/16T/L3

 27,980円

中古 MSI B560M PRO-E (B560 1200 mATX) 3480026265

 6,990円

Ultimate SU630 ASU630SS-480GQ-R

 4,980円

Define C FD-CA-DEF-C-BK

 13,262円

SPARKLE Intel Arc A750 ORC OC Edition SA750C-8GOC

 31,700円

フィリップス 221V8/11

 11,000円

Windows 11 Home 日本語版

 16,090円

合計 123,489円

ケースをけちれば、4000円ぐらいのがあるので、114,489円ぐらいにまで落とせる

さらCPUCore i5-10500(15980円)にすれば、101,489円ですむ

個人的にはPS5はかなり微妙やと思う

Windows11が動けば話は別だけどね…

2024-05-24

anond:20240523100428

ダブスタ検証用のスクリプト簡単に書いたよ(AIで)

import requests
import json
from urllib.parse import quote

def fetch_bookmarks(url):
    try:
        # URLエスケープ
        escaped_url = quote(url, safe="")
        api_url = f"https://b.hatena.ne.jp/entry/json/?url={escaped_url}"

        response = requests.get(api_url)
        response.raise_for_status()

        try:
            return response.json()
        except json.decoder.JSONDecodeError as e:
            print(f"Error decoding JSON from {api_url}: {e}")
            print("Response content:", response.text)
            return []
    except requests.exceptions.RequestException as e:
        print(f"Error fetching bookmarks from {api_url}: {e}")
        return []

def find_common_bookmarks(bookmarks1, bookmarks2, url1, url2):
    common_users = set(bm["user"] for bm in bookmarks1 if bm["comment"]) & set(bm["user"] for bm in bookmarks2 if bm["comment"])
    common_bookmarks = []
    for user in common_users:
        comments = []
        for bm in bookmarks1:
            if bm["user"] == user and bm["comment"]:
                comments.append({"url": url1, "comment": bm["comment"], "timestamp": bm["timestamp"]})
                break
        for bm in bookmarks2:
            if bm["user"] == user and bm["comment"]:
                comments.append({"url": url2, "comment": bm["comment"], "timestamp": bm["timestamp"]})
                break
        if len(comments) == 2:
            common_bookmarks.append({"user": user, "comments": comments})
    return common_bookmarks

if __name__ == "__main__":
    url1 = "https://news.yahoo.co.jp/articles/f9966c4ccc374fc88babbb50175a9ea844c99638"
    url2 = "https://www.asahi.com/articles/ASN6K7F64N6KUJHB00L.html"

    data1 = fetch_bookmarks(url1)
    data2 = fetch_bookmarks(url2)

    common_bookmarks = find_common_bookmarks(data1["bookmarks"], data2["bookmarks"], url1, url2)

    print(json.dumps(common_bookmarks, indent=2, ensure_ascii=False))

url1, url2のところを対象としたいものに変えれば使えるよ

抽出対象となるのは以下のユーザーだよ

バグあったら直して使ってね

※てかはてな匿名ってシンタックスハイライト記法使えないんだね、使って表示確認したら500エラーになったわ

2024-03-23

ワイ:

1 以上の整数 N と X が与えられ、N を割り切ることが出来る X 以下の整数を、O(min(sqrt(N),X)) 未満の Complexity で得られるアルゴリズムはありますか?

Claude3 Opus

はい、O(min(sqrt(N),X))未満のComplexityでNを割り切ることができるX以下の整数を求めるアルゴリズムがあります。以下にそのアルゴリズムを示します。

def find_divisors(N, X):

  divisors = []

  for i in range(1, min(int(N**0.5) + 1, X + 1)):

    if N % i == 0:

      divisors.append(i)

      if i != N // i and N // i <= X:

        divisors.append(N // i)

  return divisors

このアルゴリズムでは、1からmin(sqrt(N), X)までの整数を順番に調べていきます。各整数iについて、Nがiで割り切れるかどうかを確認します。割り切れる場合、iはNの約数なのでdivisorsリストに追加します。さらに、i^2 != Nの場合、N/iもNの約数となるので、N/iがX以下であればdivisorsリストに追加します。

このアルゴリズムのComplexityは、forループmin(sqrt(N), X)回まで実行されるため、O(min(sqrt(N), X))となります

例えば、N = 24, X = 10場合、このアルゴリズムは以下の約数を返します。

[1, 2, 3, 4, 6, 8]

これらは全て24を割り切ることができる10以下の整数です。

このアルゴリズム使用することで、O(min(sqrt(N), X))のComplexityで、Nを割り切ることができるX以下の整数を求めることができます

ワイ:

O(min(sqrt(N), X)) なので、これは"未満"ではなく"以下"ですね。再考をお願いします。

Claude3 Opus

申し訳ありません。ご指摘いただきありがとうございます。O(min(sqrt(N), X))未満のComplexityで、Nを割り切ることができるX以下の整数を求めるアルゴリズムを考えてみます

以下のアルゴリズムは、O(sqrt(X))のComplexityでNを割り切ることができるX以下の整数を求めます

def find_divisors(N, X):

  divisors = []

  i = 1

  while i * i &lt;= X:

    if N % i == 0:

      divisors.append(i)

      if i != N // i and N // i <= X:

        divisors.append(N // i)

    i += 1

  return divisors

このアルゴリズムでは、1からsqrt(X)までの整数を順番に調べていきます。各整数iについて、Nがiで割り切れるかどうかを確認します。割り切れる場合、iはNの約数なのでdivisorsリストに追加します。さらに、i^2 != Nの場合、N/iもNの約数となるので、N/iがX以下であればdivisorsリストに追加します。

このアルゴリズムのComplexityは、whileループがsqrt(X)回まで実行されるため、O(sqrt(X))となります。sqrt(X)は常にsqrt(N)以下なので、このアルゴリズムのComplexityはO(min(sqrt(N), X))未満です。

例えば、N = 24, X = 10場合、このアルゴリズムは以下の約数を返します。

[1, 2, 3, 4, 6, 8]

これらは全て24を割り切ることができる10以下の整数です。

このアルゴリズム使用することで、O(min(sqrt(N), X))未満のComplexityで、Nを割り切ることができるX以下の整数を求めることができます。再度の考察で間違いがあればご指摘ください。

ワイ:

N=40, X=5 の時、答えはどうなりますか?

Claude3 Opus

N = 40, X = 5の場合上記アルゴリズム使用すると、以下の約数が返されます

[1, 2, 4, 5]

しかし、40を割り切ることができる5以下の整数には、8も含まれています上記アルゴリズムでは、8が見つかりません。これは、アルゴリズムがsqrt(X)までしか調べないためです。sqrt(5)は約2.23で、8はこれより大きいため、見逃されてしまます

この問題解決するには、アルゴリズム修正する必要があります。以下は、修正したアルゴリズムです。

...

i=3 でループから抜けちゃう

”40を割り切ることができる5以下の整数には、8も含まれています。”

壊れてしまったので以下略


ワイ:

1 以上の整数 N と X が与えられ、N を割り切ることが出来る X 以下の整数を、O(min(sqrt(N),X) ) 未満の Complexity で得られるアルゴリズムはありますか?

ChatGPT:

指定された問題に対するアルゴリズム設計する際には、いくつかの異なるアプローチが考えられますが、要求されている計算量 O(min(sqrt(N), X)) 未満を達成するのは非常に挑戦的です。一般的に、ある数Nの約数を見つけるプロセスは、最悪の場合でもsqrt(N) の計算量を要します。この計算量は、1 からsqrt(N)までの数でNを割ってみるという基本的アプローチに基づいています

X以下の整数でNを割り切る必要がある場合、探索範囲がX以下に制限されるため、計算量はさらに小さくなる可能性がありますが、基本的アプローチでは依然としてsqrt(N)の計算量が最良です。

...

以下特殊条件であれば小さくなるかもね、みたいな話。

ChatGPTはフィードバックを通して出来ないことをちゃんと「出来ない」と言う、というチューニングがされているような気がする。

一日の長だね。

2024-01-31

anond:20240131143125

そのアプローチは非常に効果的ですね。メイン関数内での処理をシンプルに保つことで、コードの可読性と保守性が向上します。以下にその考え方を反映したサンプルコードを示します。

import json

# ビジネスロジック関数
def business_logic(data):
    # ビジネスロジックの詳細
    pass

# 設定情報ロード
def load_config(config_file):
    with open(config_file, 'r') as f:
        config = json.load(f)
    return config

def main():
    # 設定情報ロード
    config = load_config('config.json')

    # ビジネスロジックの実行
    business_logic(config)

if __name__ == "__main__":
    main()

このコードでは、メイン関数は設定情報ロードし、その情報を元にビジネスロジックを実行するだけです。技術的な詳細は関数内にカプセル化されており、メイン関数はそれらの関数を呼び出すだけです。これにより、コード自然言語を読むような形で読むことができ、技術的詳細は隠蔽されます。また、各関数担当者も明確になります。このような設計は、大規模なプロジェクトやチームでの開発に特に有効です。

2024-01-22

ブコメダブスタをチェックするためのスクリプト適当Pythonで書いた

エラーハンドリングは省略。標準ライブラリのみで動く。

import json
import urllib.request


# True にするとユーザー名を隠す
hide_user = False
# 以下を書き換える。sys.argv 使ってもいいんだけど
url1 = "https://www.cygames.co.jp/news/id-23172/"
url2 = "https://mtg60.com/archives/palworlddoujinsi.html"


def get_bookmarks(url: str):
    req = urllib.request.Request(f"https://b.hatena.ne.jp/entry/json/{url}")
    with urllib.request.urlopen(req) as res:
        dict = json.loads(res.read())

    user_comments = {}

    for bookmark in dict["bookmarks"]:
        if bookmark["comment"]:
            user_comments[bookmark["user"]] = bookmark["comment"]

    return user_comments


b1 = get_bookmarks(url1)
b2 = get_bookmarks(url2)

common = set(b1.keys()).intersection(b2.keys())

print(f"[1] {url1}")
print(f"[2] {url2}")
print()

for user in sorted(common):
    if hide_user:
        print(user[0] + "*" * (len(user) - 1))
    else:
        print(user)
    print(f"[1] {b1[user]}")
    print(f"[2] {b2[user]}")
    print()

ログイン ユーザー登録
ようこそ ゲスト さん