ãã¡ãã¯ã¨ã ã¹ãªã¼ Advent Calendar 2023 1æ¥ç®ã®è¨äºã§ãã
Overview
ã¨ã ã¹ãªã¼ã¨ã³ã¸ãã¢ãªã³ã°ã°ã«ã¼ã AIã»æ©æ¢°å¦ç¿ãã¼ã ã§ã½ããã¦ã§ã¢ã¨ã³ã¸ãã¢ããã¦ããä¸æ(po3rin) ã§ãã趣å³ã¯éº»éã§ããªã¼éèã§æ¯å¹´200åè以ä¸æã¡ã¾ãã好ããªéº»éããã¯åç°è³¢ããã§ãã
麻éãå§ããã¨ãã«ä¸çªã®éå£ã«ãªãã®ã¯ç¹æ°è¨ç®ã§ã¯ãªãã§ããããï¼ ç¹ã«ç¬¦è¨ç®ãåå¿è ã®é¢éã®ããã§ããä¸æ¹ç§ã®ãããªåä¸ç´è ã§ãçªç¶ã®ã¬ã¢ãªç¹æ°ç³åã«ã¾ãã¤ããã¨ãããã¾ãã
ããã§ãä»åã¯ãã®äººã«åã£ã麻éã®ç¹æ°è¨ç®åé¡(主ã«ç¬¦è¨ç®ãç¦ç¹ã¨ãªãåé¡)ãçæãã¦ãèªåã§ç¹æ°è¨ç®&ç¹æ°ç³åã®ç·´ç¿ãããæ¹æ³ãæ¢æ±ããã®ã§ãã®ç´¹ä»ããã¾ãã麻éç¨èªãå°ãã ãç»å ´ããã®ã§ã対象èªè ã¯éº»éãå°ãã§ãããã£ããã¨ã®ããã¨ã³ã¸ãã¢ã®æ¹ã§ãã
- Overview
- 麻éã®ç¹æ°è¨ç®ã®é£ãã
- ç¾ç¶ã®ç¹æ°è¨ç®ã®ç·´ç¿æ¹æ³ã®èª²é¡
- ä»åä½ã£ãç¹æ°ç³åç·´ç¿ã·ã¹ãã
- 麻éã®ç¹æ°è¨ç®åé¡ãèªåçæãã
- ç¹æ°ç³åãçºå£°ã§åçãã
- æåèµ·ãã微修æ£
- Future Work
- å°åº: ChatGPTã§éº»éç¹æ°è¨ç®åé¡çæ
- ã¾ã¨ã
麻éã®ç¹æ°è¨ç®ã®é£ãã
麻éã¯ã¢ã¬ãªã®å½¢ã«ãã£ã¦ç¹æ°ã決ã¾ãã¾ããã¢ã¬ãªã®å½¢ããé£æ°ã¨ç¬¦æ°ãå°ããä¸è¨ã®è¡¨ãåç §ãã¦ç¸æã«ã¢ã¬ãªã®ç¹æ°ãç³åãã¾ããä¸è¨ã¯1 ~ 4é£ã20 ~ 70符ã®ç¹æ°ã®è¡¨ã§ã(ãã¡ãã5é£ä»¥ä¸ã80符以ä¸ã®ç¹æ°ãåå¨ãã¾ã)ã
è¦ããã ããªãé£ãããªãããã§ããã麻éä¸ã¯é£ã符ã®è¨ç®ãå³åº§ã«ãªã¢ã«ã¿ã¤ã ã§è¡ãå¿ è¦ããããããåå¿è ãå³åº§ã«ç¹æ°ç³åãããã®ã¯æéããããã¾ããç¹ã«ç¬¦ã®è¨ç®ã¯ééãããããæã麻éã®æ·å± ãé«ããã¦ããè¦å ã ã¨èãã¦ãã¾ãã
ç¾å¨ã麻éç¹æ°è¨ç®ã«æ £ããããã«æ§ã ãªç·´ç¿æ¹æ³ãããã¾ããããããã課é¡ãããã¨èãã¦ãã¾ãã
ç¾ç¶ã®ç¹æ°è¨ç®ã®ç·´ç¿æ¹æ³ã®èª²é¡
æ¸ç±
æ¸ç±ã¯ç¹æ°è¨ç®ã®æ¹æ³ãä½ç³»çã«å¦ã¹ãã®ã§ã¼ãããå§ããåå¿è ã«ã¯ããããã§ããæè¿ã§ã¯ä¸è¨ã®æ¸ç±ã®ããã«æ¸ãã¦è¦ããç³»ãå¤ãå°è±¡ã§ãã
ãã¡ãã®æ¬ã§ã¯é£æ°ã符æ°ã確èªããªãããç¹æ°ãè¨å ¥ãã¦ç·´ç¿ã§ããããã§ãã
ããããããã ãã ã¨ç¹æ°ã ããçãããªã¢ã«ã§ã®ç¹æ°ç³å(é£æ°ãªã©ãç³åãããåã親ãæãç¹æ°ã ããçºå£°ãã)ã®æè¦ã身ã«ã¤ãã¾ããããªã¢ã«ãªç¹æ°ç³åã®æè¦ãå¾ãããã«ã¯ãç¾ç¶ã¯éèã«è¡ã£ã¦å®éã«æã£ã¦ç·´ç¿ããå¿ è¦ãããã¾ããä¾ãã°åã®æºè²«ã¯åãã2000ç¹ã親ãã4000ç¹ããããã®ã§ãã«ãããããããã¨çºå£°ãã¾ãããã®ããã«ç¹æ°ãåã¨è¦ªãããããç¨ã®è¨ãæ¹ã«å¤æããå¿ è¦ãããã¾ãã
ã¢ããª
åãç¾å¨ã麻éåå¿è ã«ãªã¹ã¹ã¡ãã¦ããã¢ããªã¯ãã¡ãã§ãã
apps.apple.comã麻éç¹æ°è¨ç® è¶ å®è·µåé¡éãã¯ã4é£ä»¥ä¸50符以ä¸ããªã©ã®æ¡ä»¶ãã¤ãã¦ç°¡åoré£ããåé¡ã«çµã£ã¦åé¡ã解ããã¨ãã§ãã¾ãããããããã¡ãã®ã¢ããªã§ã¯ã4é£ä»¥ä¸50符以ä¸ããå¿ ãåºé¡ããããã¨ãããã£ã¦ãã¾ãã®ã§ããªã¢ã«ã®éº»éã¨ã¯å°ãããé¢ããæèã«ãªã£ã¦ãã¾ããæ¬çªã§ã±ã¢ã¬ã¹ãã¹ãå¢ãã¾ãã
ã¾ããæ¸ç±ã®èª²é¡ã¨åãããã«åçæ¹æ³ã4æã®é¸æå¼ã ã£ããããã®ã§ããªã¢ã«ã§ã®ç¹æ°ç³å(é£æ°ãªã©ãç³åãããåã親ãæãç¹æ°ã ããçºå£°ãã)ã®æè¦ã身ã«ã¤ãã¾ããã
ããã§ãèªåã¨ãã¦ã¯ãåºé¡ç¯å²ã®æ¡ä»¶ã¯ãªããããã®äººã®ã¬ãã«ã«ãã£ãåé¡ã確ççã«åºé¡ãããããã¨ã¨ããªã¢ã«ã§ã®ç¹æ°ç³åã«åã£ãåçæ¹æ³ããå¿ è¦ãªã®ã§ã¯ãªããã¨èãã¦ãã¾ãã
å®éã«æã£ã¦è¦ãã
ãªã¢ã«ã§ã®ç¹æ°ç³åãè¡ããã®ã§ãæãç·´ç¿ã«ãªãã¾ããã麻éãæã¤é »åº¦ãå°ãªãã¨ä¸ã 身ã«ã¤ãã¾ããããªã¢ã«ãªç¹æ°ç³åæ¹å¼ã§ãåæ°ãããªããæ¹æ³ãå¿ è¦ã ã¨èªåã¯èãã¦ãã¾ãã
...
ããã¾ã§ã§æããæ¸ç±ãã¢ããªã®èª²é¡ãããç§ã®èããæå¼·ã®éº»éç¹æ°è¨ç®åé¡åºé¡ã·ã¹ãã ã¯ä¸è¨ãåãããã®ã ã¨èãã¦ãã¾ãã
- ãªã¢ã«ã§ã®ç¹æ°ç³åã«æ²¿ã£ãåçæ¹æ³(çºå£°)
- åºé¡ç¯å²ã®æ¡ä»¶ã¯ãªããããã®äººã®ã¬ãã«ã«ãã£ãåé¡ã確ççã«åºé¡ããã
- é«éã«å¤§éã®åé¡æ°ãããªããã¨ãã§ãã
ä»åä½ã£ãç¹æ°ç³åç·´ç¿ã·ã¹ãã
ããã¦ä»åä½ã£ããã®ããã¡ãã«ãªãã¾ããGoogle Colabratoryä¸ã§åä½ãã¾ãã
ãã¡ããå®è¡ããã¨ä¸è¨ã®ããã«è¨ç®åé¡ã表示ãã¦ãç¹æ°ç³åã®çºå£°ãã¬ã³ã¼ãã£ã³ã°ãã¦æ£è§£ä¸æ£è§£ãå¤å®ãã¾ãã
麻éã®ç¹æ°è¨ç®åé¡ãèªåçæãã
麻éç¹æ°è¨ç®åé¡åºé¡ã·ã¹ãã ãä½ãããã«ã¯åºé¡å ã¨ãªãåé¡éãå¿ è¦ã«ãªãã¾ããã©ããã«åé¡éãã³ã¼ãããå©ç¨ã§ããå½¢ã§å ¬éããã¦ãªããã¨èãã¾ãããããã®ãããªä¾¿å©ãªãã®ã¯ç§ã調ã¹ãç¯å²ã§ã¯ç¡ãããã§ãã
麻éã¢ããªã§ãã天鳳ãªã©ã®å¯¾å±ãã°ããã¢ã¬ãªå½¢ãæ½åºãã¦ãåé¡éã¨ãã¦ãè¯ãã§ãããä¸ç´è 以ä¸ãç·´ç¿ãããã¬ã¢ãªã¢ã¬ãª(80符以ä¸ãªã©)ã¯æ°ãå°ãªããä¸è¨ã®ãµã¤ãã®èª¿ã¹ã§ã¯3%ããåºç¾ããªãããã§ã(ä½æãã®æ°åã大ããããæ°ããã¾ãã...)ã
ãã®ããã天鳳ã®å¯¾å±ãã°ããåé¡éãä½æããããã«ã¯ãéå»æ°å¹´åã®å¤§éã®ãã°ããã¼ãããªãã¦ã¯ãããªããããæéããããã¾ããããã§ç§ã¯éº»éã®ç¹æ°è¨ç®åé¡ã®èªåçæã«åãçµã¿ã¾ãããããã§ç®æ¨ã®1ã¤ã§ãããåé¡æ°ã«éããã»ã¨ãã©ãªãããéæã§ãã¾ãã
ä»åç§ãä½ã£ãPythonã«ããç¹æ°è¨ç®åé¡ã®èªåçæã¢ã¸ã¥ã¼ã«ã¯OSSã§å ¬éãã¦ãã¾ãã
from mahjong_question_generator import generate_question df = generate_question(n=3) # 3åçæ print(df)
ãã¡ãã®DataFrameã§ã¯åºé¡ã«å¿ è¦ãªä»¥ä¸ã®æ å ±ãå«ãã§ãã¾ãã
round_wind: å ´é¢¨ player_wind: èªé¢¨ hand: æç win_tile: ã¢ã¬ãªç dora_str: ãã©è¡¨ç¤ºç is_riichi: ãªã¼ãã®æç¡ is_tsumo: ãã¢ã®æç¡ is_haitei: ãã¤ãã¤ã®æç¡ is_houtei: ãã¦ãã¤ã®æç¡ hand_value_han: ã¢ã¬ãªã®é£æ° hand_value_hu: ã¢ã¬ãªã®ç¬¦æ° hand_value_cost_additional: åãæãç¹æ° hand_value_cost_main: 親ãæãç¹æ°(ãã³ã®å ´åã¯æ¯ãè¾¼ãã 人ããæãç¹æ°) hand_value_yaku: ã¢ã¬ãªå½¹ã®ãªã¹ã
ããã ãã®æ å ±ãããã°ä¸è¨ã®ããã«Notebookã§åé¡ãåºé¡ã§ãã¾ãã
import time import pandas as pd from IPython.display import display from cmajiang import Shoupai from mahjong_question_generator import generate_question df = generate_question(n=3) # 3åçæ questions = df.to_dict('records') for q in questions[:3]: print('======================================') print(f'å ´é¢¨: {q["round_wind"]}, èªé¢¨: {q["player_wind"]}') print('ãã©è¡¨ç¤ºç') display(Shoupai(q['dora_str'])) print('------------------------------------------------------------------') print('æç') display(Shoupai(q['hand'])) print('ãªã¼ã' if q['is_riichi'] else '', 'ãã¢' if q['is_tsumo'] else 'ãã³', 'æµ·åºæ¸æ' if q['is_haitei'] else '', 'æ²³åºæé' if q['is_houtei'] else '') display(Shoupai(q['win_tile'])) print(f'æ£è§£ã¯ {q["hand_value_han"]}é£{q["hand_value_hu"]}符, {q["hand_value_cost_additional"]}, {q["hand_value_cost_main"]}ã§ãã') print(f'å½¹: {q["hand_value_yaku"]}')
å®è£ ã®ãã¤ã³ã
ã¡ã³ãã®ãã¿ã¼ã³ãéã¿ä»ãã©ã³ãã ãµã³ããªã³ã°ãã¦é£æ度ã調æ´
ä»åã¯ç¹ã«ç¬¦è¨ç®ã«ç¦ç¹ãå½ã¦ã¦ãããããåºç¾ããã¡ã³ãã®ç¨®é¡ã§é£æ度ã調æ´ãã¦ãã¾ããé£ããç¹æ°è¨ç®ã絡ãæã¯æå»ãã«ã³ãå ¥ã£ã¦ããããããã®åºç¾çã§é£æ度ã調æ´ã§ãã¾ãã
TILE_PATTERN = ['run', 'triple', 'chi', 'pon', 'kan'] DEFAULT_TILE_PATTERN_WEIGHTS = [4,1,1,1,1] def hand_candidates(tile_pattern_weights: list[int] = DEFAULT_TILE_PATTERN_WEIGHTS) -> dict: mentsu_list = random.choices(TILE_PATTERN, weights=tile_pattern_weights, k=4) # ... çç¥
å½¹ã®ããæçãå¼·å¼ã«ä½ã
ç¹æ°è¨ç®åé¡ãä½æããéã«ãå½¹ãããæçãæåããçã£ã¦çæããã®ã¯å°ãé£ããã®ã§ãã¡ã³ããé³´ããã¢ã¬ãªçãã©ã³ãã ã§çæãã¦ãæçµçã«å½¹ããªããã°å¼·å¼ã«ãã¤ãã¤ããã¦ãã¤ã®å½¹ãã¤ãã¦ãã¾ãã
# ... é¢æ°ã®ä¸é¨ãæç² # ç¹æ°è¨ç® hand_value = calculator.estimate_hand_value(tiles, win_tile, melds, dora_indicators, config) # å½¹ããªãã£ããå¼·å¶çã«å½¹ãã¤ãã¦åè¨ç® if str(hand_value) == 'no_yaku': is_haitei = is_tsumo and not is_riichi is_houtei = not is_tsumo and not is_riichi config = HandConfig(is_tsumo=is_tsumo, is_riichi=is_riichi, is_haitei=is_haitei, is_houtei=is_houtei, player_wind=player_wind, round_wind=round_wind, options=OptionalRules(has_open_tanyao=True, kiriage=True, kazoe_limit=HandConfig.KAZOE_SANBAIMAN)) hand_value = calculator.estimate_hand_value(tiles, win_tile, melds, dora_indicators, config) # ...
ããã§å½¹ããªãæçãåé¡ã¨ãã¦æ¾ããã¨ãã§ãã¾ããç¹ã«ä»åã®ããã«ç¬¦è¨ç®ã«éããç½®ããåºé¡ã§ã¯ãã¤ãã¤ã ããã¨ãã¦ãã¤ã ããã¨ãªã¼ãã ããã¨ãã¾ãé£æ度ã«å½±é¿ããªãã®ã§ããã®å¼·å¼ãªæ¹æ³ã§è¨±å®¹ãã¦ãã¾ãããã®åé¿çã«éåæãæãããªãã°ããæçã«å½¹ããªããã°ãã®æçã¯æ¨ã¦ã¦ãå½¹ãããæãã§ããã¾ã§çæãããã¨ããè¨å®ã«ããã°è¯ãã§ãããã
majiang-coreã§æçãæåã§ããå½¢å¼ã§åºåãã
ä»åã¯åé¡ã®åºé¡ã«æçãã¢ã¬ãªçããã©è¡¨ç¤ºçã«ç»åã使ãããã£ãã®ã§ä¸è¨ã®ã¢ã¸ã¥ã¼ã«ã使ã£ã¦ãã¾ãã
ãã¡ãã¯ã¤ã³ã¿ã¼ããã麻éã§ããé»è³éº»å°å é¨ã§ä½¿ããã¦ããæç表ç¾ããµãã¼ããã¦ãããããæååã渡ãã°ã§ããã«ç»åãåºåã§ãã¾ãã
cmajiang
ã¯ä¸è¨ã®ããã«SVGã§é常ã«ç¶ºéºã«çãæåã§ããã®ã§ããããã§ãã
ç¹æ°ç³åãçºå£°ã§åçãã
ãªã¢ã«ã«è¿ãå½¢ã®ç¹æ°ç³åã«å¯ããããã«ãç¹æ°ç³åçºå£°ã§åçãå ¥åãããã®ã§ãã¦ã¼ã¶ã¼ã®çºå£°ãã¬ã³ã¼ãã£ã³ã°ãã¦ãæåèµ·ãããã¦è§£çã¨ä¸è´ãããããã§ãã¯ãã¾ãã
æåèµ·ãããµã¼ãã¹ã¨ãã¦Googleã®Cloud Speech-To-Text APIãOpenAIã®Whisperãªã©ãããã¾ããããããä»åã®è¶£å³éçºã®åã§ã¯ç¡æã§å®è¡ãããã¨ããã§ããããã§ä»åã¯é³å£°å¦çãã¼ã«ãããOSSã®ESPnet2ã¨æ¢åã®å¦ç¿æ¸ã¿ã¢ãã«ã使ã£ã¦æåèµ·ãããè¡ãã¾ããã
æåèµ·ãã
ã¾ãã¯Google Colaboratoryä¸ã§çºå£°ãã¬ã³ã¼ãã£ã³ã°ããæ¹æ³ã§ããä¸è¨ã¯ESPnet2ã®ãã¢ã¹ã¯ãªããããæåãã¾ããã
from IPython.display import Javascript from google.colab import output from base64 import b64decode RECORD = """ const sleep = time => new Promise(resolve => setTimeout(resolve, time)) const b2text = blob => new Promise(resolve => { const reader = new FileReader() reader.onloadend = e => resolve(e.srcElement.result) reader.readAsDataURL(blob) }) var record = time => new Promise(async resolve => { stream = await navigator.mediaDevices.getUserMedia({ audio: true }) recorder = new MediaRecorder(stream) chunks = [] recorder.ondataavailable = e => chunks.push(e.data) recorder.start() await sleep(time) recorder.onstop = async ()=>{ blob = new Blob(chunks) text = await b2text(blob) resolve(text) } recorder.stop() }) """ def record(sec, filename='audio.wav'): display(Javascript(RECORD)) s = output.eval_js('record(%d)' % (sec * 1000)) b = b64decode(s.split(',')[1]) with open(filename, 'wb+') as f: f.write(b)
ããã§record
é¢æ°ãå¼ã¹ã°ãæå®æéã ãé²é³ããã¦wavãã¡ã¤ã«ã¨ãã¦ä¿åã§ãã¾ãã
ç¶ãã¦ããã®é³å£°ãã¡ã¤ã«ãæåèµ·ãããã¾ãã
from espnet_model_zoo.downloader import ModelDownloader from espnet2.bin.asr_inference import Speech2Text d = ModelDownloader() speech2text = Speech2Text( **d.download_and_unpack("kan-bayashi/csj_asr_train_asr_transformer_raw_char_sp_valid.acc.ave"), device="cuda" ) speech, sr = librosa.core.load("audio.wav", sr=16000) nbests = speech2text(speech) text, *_ = nbests[0]
ããã§Google Colaboratoryä¸ã§ã¬ã³ã¼ãã£ã³ã°ããã¦ã¼ã¶ã¼ã®åçãæåèµ·ããã§ãã¾ãã
æåèµ·ããçµæã¨æ¯è¼å¯è½ãªå½¢ã«æ£è§£å´ãå¤æãã
ããã§ã²ã¨ã¤åé¡ããããä¸è¨ã®ã³ã¼ãã§æåèµ·ãããè¡ãã¨çºå£°ããç¹æ°ãæ¼¢åã§æåèµ·ããããã¦ãã¾ãã¾ãã
ä¾ãã°ã1300 2600ãã®çºå£°ã¯ãåä¸ç¾äºåå
ç¾ãã¨æåèµ·ããããã¾ãããã®æ¼¢åã®ä¸¦ã³ããã¼ã¹ããã®ã¯é¢åãªã®ã§ãmahjong-question-generatorã§çæããæ£è§£å´ãæ¼¢åã«ãããã¨ã§æ¯è¼å¯è½ãªå½¢ã«ãã¾ããintãæ¼¢åã®æååã«å¤æããéã«ã¯kanjize
ã¨ããã¢ã¸ã¥ã¼ã«ãå©ç¨ãã¾ãã
from kanjize import number2kanji def convert_answer_for_voice_assertion(q: dict) -> str: # é³å£°ãã¼ã¿ã¨æ¯è¼ããããã®åçãç¨æ if q["hand_value_cost_additional"] == 0: # ãã³ answer_for_voice_assertion = number2kanji(q["hand_value_cost_main"]) elif q["hand_value_cost_additional"] == q["hand_value_cost_main"]: # 親ã®ãã¢ããã answer_for_voice_assertion = number2kanji(q["hand_value_cost_main"]) + 'ãªã¼ã«' elif q["hand_value_cost_additional"] != 0: # åã®ãã¢ããã answer_for_voice_assertion = number2kanji(q["hand_value_cost_additional"]) + number2kanji(q["hand_value_cost_main"]) return answer_for_voice_assertion
ããã§answer_for_voice_assertion
å¤æ°ã«æåèµ·ããã¨æ¯è¼å¯è½ãªæååãåå¾ã§ãã¾ãã
æåèµ·ãã微修æ£
ç¹æ°ç³åã®æåèµ·ãããã®ã¾ã¾ã ã¨ããåãããããã«èªèããããã¨ãå¤ãã£ãã®ã§ãæå ã§å¾®ä¿®æ£ãå ãã¦ãã¾ããä¸è¨ã®ä¿®æ£ã§å¤§ä½ã®ç¹æ°ç³åã¯åé¡ãªãæåèµ·ããã§ããããã«ãªãã¾ããã
def adjust_speech(speech: str) -> str: # ãåãããããã«ããããã¨ãå¤ã if text == "ã": text = "å" # ãã¾ã«ããããå ¥ãè¾¼ã if 'ã' in text: text = text.replace('ã', '') return text
ä¸æ¦ãã®å¯¾å¿ã«ã¨ã©ã¾ã£ã¦ãã¾ãããç¹æ°ç³åã¯åºæ¬çã«æ¼¢åã§æåèµ·ãããããã®ã§ãã²ãããªãè¨å·ãåé¤ãããªã©å¤§èãªèª¿æ´ã«ãã¦ãè¯ãããããã¾ããã
Future Work
ä»åã¯åé¡ãPythonã§çæãã¦Google Colaboratoryã§åé¡ãåºãã¨ããã¾ã§ãå®è£ ãã¾ããã
ããããã¯ãã¤ãã£ãã¢ããªåãå¼·åå¦ç¿ã§ãã®ã¦ã¼ã¶ã¼ãééããããåé¡ãåºãããã«é²åãã¦ãããªã©ãèãããã¾ãã
å°åº: ChatGPTã§éº»éç¹æ°è¨ç®åé¡çæ
æåã¯ChatGPTã§ç¹æ°è¨ç®åé¡ãçæã§ãããã¨æãã¾ããããå ¨ç¶ãã¾ãããã¾ããã§ããã
ããã³ãã: åçãã親ã®ãã³ãããã§2ç¿»50符4800ç¹ãã¨ãªã麻éã®ç¹æ°è¨ç®åé¡ãä½ã£ã¦ãã ããã符è¨ç®ãã§ããåé¡ã«ãã¦ãã ãããå®éã«æçã並ãã§ããä¾ãæååã§è¡¨ç¾ãã¦ãã ããã åç: 親ã次ã®ãããªæçã§ãã³ããããã¾ããã æçï¼ãæ±æ±æ±ãããç¼ç¼ç¼ããã2è¬3è¬4è¬ããã5ç´¢6ç´¢7ç´¢ãã対åãã赤ãã©ã ã¢ã¬ãªçï¼ã4è¬ã ãã®å ´åãå½¹ã¯ãªã¼ããä¸çºããã©1ã¨ãªãã¾ãããã®æã®ç¹æ°ãè¨ç®ãã¦ãã ããã
ChatGPTãä½ã£ãåé¡ã¯è§£çã12000ã®åé¡ãªã®ã§ãªã¼ãã¼ã¨ã¯éãã¾ããä»ã«ãä½åãããã³ããã試è¡é¯èª¤ãã¦ã¿ã¾ãããå ¨ç¶ãã¾ãããã¾ããã§ãããChatGPTã§éº»éé¢é£ã®è³ªåãããã®ã¯ã¾ã æ©ããã§ãã
ã¾ã¨ã
ä»åã¯éº»éã®ç¹æ°è¨ç®åé¡ãPythonã§èªåçæãã¦ãå®éã«çºå£°ãã¦ç¹æ°ç³åã®ç·´ç¿ãããæ¹æ³ãæ¢æ±ãã¾ãããã¿ãªãããã¨ã³ã¸ãã¢ãªã³ã°ã§éº»éã©ã¤ããããè¯ããã®ã«ãã¦ããã¾ãããã
We are hiring
ã¨ã ã¹ãªã¼ã§ã¯è¶£å³ãã¨ã³ã¸ãã¢ãªã³ã°ã§ããããããã¯ãããããªã®ã¼ã¯ãªã¨ã³ã¸ãã¢ãéæåéä¸ã§ãã軽ã話ãèãã¦ã¿ãã ãã§ã OK ã§ãã®ã§ããã²ã¨ãã«ã¸ã¥ã¢ã«é¢è«ããç³ãè¾¼ã¿ãã ããï¼