728x90
728x90

cloudflare에서 도메인을 구매했다.

cloudflare를 선택한 이유는 가장 기본적인 요금만 받기 때문이였다.

 

aws를 사용하거나 클라우드 서버를 사용할 수 있으면 좋으련만 수익이 없는 상태에서 과금 서비스를 이용하기는 싫었다.

홈 서버를 구축하기로 했다.

 

일단 외부에서 도메인으로 접속을 하려면 공인 ip와 도메인을 연결해야 한다.

문제는 공인 ip가 유동 ip라는 것이다.

유동ip일 경우 도메인과 매핑을 해도 ip가 주기적으로 변하기 떄문에 변할 때 마다 수정해줘야 한다.

이를 해결하기 위해 공인 ip를 고정ip로 사용하려면 추가 요금을 월마다 내야한다.

앞서 말했듯이 수익이 생기기 전에 과금 서비스는 최소화하고 싶었다.

 

ip 변할 때 자동으로 DNS 레코드를 수정하도록 해보자.

 

DDNS

DDNS(Dynamic Domain Name System)는 IP 주소가 변경될 때 도메인 이름을 자동으로 업데이트하여 항상 최신 IP로 연결되도록 하는 서비스입니다. 주로 가정용 라우터나 서버에서 공인 IP가 자주 바뀌는 환경에서 사용됩니다. 예를 들어, No-IP나 DynDNS 같은 서비스를 통해 설정할 수 있습니다.

 

공유기에서도 구매한 도메인과 공인ip를 연결하도록 ddns를 설정을 할 수 있지만 우리집 공유기는 안되더라.

하여 python으로 ddns 설정을 하기로 했다.

 

import os
import time

import requests
from cloudflare import Cloudflare
from dotenv import load_dotenv

load_dotenv()
# 환경 변수 로드
API_TOKEN = os.getenv('CF_API_TOKEN')
ZONE_ID = os.getenv('CF_ZONE_ID')
RECORD_NAMES = os.getenv('RECORD_NAMES', '').split(',')

if not API_TOKEN or not ZONE_ID or not RECORD_NAMES:
    print("Error: Missing environment variables (CF_API_TOKEN, CF_ZONE_ID, RECORD_NAMES)")
    exit(1)

# Cloudflare 클라이언트 초기화
cf = Cloudflare(api_token=API_TOKEN)


def get_public_ip():
    """공인 IP 확인"""
    try:
        response = requests.get('https://api.ipify.org')
        external_ip = response.text
        return external_ip
    except requests.RequestException as e:
        print(f"외부 IP 주소를 가져오는 중 오류가 발생했습니다: {e}")
        return None


def get_dns_record_id_and_ip(record_name):
    """DNS 레코드 ID와 현재 IP 가져오기"""
    try:
        records = cf.dns.records.list(zone_id=ZONE_ID, type="A", name=record_name)
        if records and records.result:
            record = records.result[0]
            return record.id, record.content
        else:
            print(f"No record found for {record_name}")
            return None, None
    except Exception as e:
        print(f"Error fetching record for {record_name}: {str(e)}")
        return None, None


def update_dns_record(record_id, record_name, new_ip):
    """DNS 레코드 업데이트"""
    try:
        cf.dns.records.edit(
            dns_record_id=record_id,
            zone_id=ZONE_ID,
            type="A",
            name=record_name,
            content=new_ip,
            ttl=1,  # 자동 TTL
            proxied=True  # Cloudflare 프록시 활성화 (필요 시 False로 변경)
        )
        print(f"Updated {record_name} to {new_ip}")
    except Exception as e:
        print(f"Error updating {record_name}: {str(e)}")

def create_dns_record(record_name, new_ip):
    """DNS 레코드 등록"""
    try:
        cf.dns.records.create(
            zone_id=ZONE_ID,
            type="A",
            name=record_name,
            content=new_ip,
            ttl=1,  # 자동 TTL
            proxied=True  # Cloudflare 프록시 활성화 (필요 시 False로 변경)
        )
        print(f"Created {record_name} to {new_ip}")
    except Exception as e:
        print(f"Error creating {record_name}: {str(e)}")


def main():
    while True:
        current_ip = get_public_ip()
        print(f"Current public IP: {current_ip}")

        for record_name in RECORD_NAMES:
            if not record_name:
                continue
            record_name = record_name.strip()
            record_id, record_ip = get_dns_record_id_and_ip(record_name)
            if record_id:
                if record_ip != current_ip:
                    update_dns_record(record_id, record_name, current_ip)
                else:
                    print(f"No update needed for {record_name}: IP {record_ip} matches current {current_ip}")
            else:
                create_dns_record(record_name, current_ip)

        time.sleep(300)  # 5분 대기


if __name__ == '__main__':
    main()

 

API_TOKEN = cloudflare에서 발급한 API 토큰 / dns 수정 권한을 줘야함
ZONE_ID = cloudflare 대시보드 페이지에서 "영역 ID"라고 번역되는 id
RECORD_NAMES = 매핑할 url를 ,(comma)으로 구분

 

공인 ip를 조회하고

RECORD_NAME를 가져와

dns 레코드에 설정이 없을 경우 create

있는데 공인ip가 다를 경우 update

5분마다 반복하도록 코딩

 

어쨌든 서비스가 원할하게 돌아가려면 고정ip는 필수 일 듯 하다.

5분마다 실행 되기 때문에 공인ip가 변할 경우 최대 5분 동안 서비스가 중지된다.

또한 dns레코드가 수정 될 경우 반영 될 때까지 시간이 걸리기 때문에 최대 72시간까지 소요될 수도 있다고 한다.

물론 유동ip가 변한 걸 본적은 없지만

728x90

'' 카테고리의 다른 글

FastAPI: 빠르고 효율적인 웹 프레임워크  (0) 2024.11.10
Flask를 활용한 REST API 개발: 입문 가이드  (0) 2024.11.09
HTTP: Content-Type  (0) 2023.05.05
728x90

"이 포스팅은 쿠팡 파트너스 활동의 일환으로,

이에 따른 일정액의 수수료를 제공받습니다."

맥북 Dock 크기 및 알림 볼륨, 터미널로 내 마음대로 설정하기!

macOS는 직관적인 GUI(그래픽 사용자 인터페이스)를 제공하지만, 설정의 숫자 값을 알려주지 않습니다. 저는 숫자 변태로 어떤 값을 설정할 때 5의 배수 또는 2의 제곱수로 설정하는 것을 좋아합니다. 공부 못하는 이과생의 특징이죠 아마 많은 이과생?들이 그럴 것이라 생각합니다. 맥북의 터미널로 설정을 좀 더 세밀하게 제어하는 방법을 알려드리려 합니다.

1. 맥북 Dock 아이콘 크기 설정하기

Dock은 macOS에서 가장 많이 사용되는 인터페이스 중 하나로, 자주 사용하는 앱과 파일에 빠르게 접근할 수 있는 편리한 공간입니다.

 

터미널 명령어를 통한 정밀 설정

defaults write 명령어는 macOS의 숨겨진 설정 파일(Property List, .plist)을 직접 수정하여 시스템 설정(GUI)에서 제공하는 범위를 넘어서는 미세한 조절이나 특정 값을 정확히 설정할 때 사용됩니다.

 

💡 현재 설정된 Dock 아이콘 크기 값 확인하기

설정을 변경하기 전에 현재 값이 궁금하다면 다음 명령어를 터미널에 입력하여 확인해 보세요.

defaults read com.apple.dock tilesize

기본 아이콘 크기 확인:이 명령어는 현재 Dock의 기본 아이콘 크기(픽셀 단위)를 정수 값으로 출력합니다. 예를 들어, 48과 같이 표시될 수 있습니다.

 

defaults read com.apple.dock largesize

확대 시 큰 아이콘 크기 확인:이 명령어는 Dock 확대 효과가 적용될 때 아이콘이 커지는 최대 크기(픽셀 단위)를 출력합니다.

 

Dock 아이콘 크기 설정하기

기본 아이콘 크기 설정:

defaults write com.apple.dock tilesize -int [원하는 숫자]
killall Dock

[원하는 숫자] 부분에 Dock 아이콘의 픽셀 크기를 입력합니다. 일반적으로 macOS Dock 아이콘의 최소 크기는 16px, 최대 크기는 128px입니다. 이 범위를 벗어나면 시각적으로 문제가 발생하거나 시스템이 기본값으로 되돌릴 수 있습니다. (예: Dock 아이콘을 48픽셀로 설정: `defaults write com.apple.dock tilesize -int 48`)

 

확대 시 큰 아이콘 크기 설정 (확대 효과 사용 시):

defaults write com.apple.dock largesize -int [원하는 숫자]
killall Dock

[원하는 숫자] 부분에 마우스 오버 시 확대될 아이콘의 최대 픽셀 크기를 입력합니다. 이 값 역시 16px에서 128px 사이에서 설정하는 것이 일반적입니다.

 

❓ killall Dock 명령어는 무엇인가요? 왜 필요한가요?

killall Dock 명령어는 현재 실행 중인 Dock 애플리케이션 프로세스를 강제로 종료하는 역할을 합니다. macOS에서 defaults write 명령어를 통해 시스템 설정을 변경했을 때, 해당 애플리케이션(이 경우 Dock)이 변경 사항을 즉시 인식하고 적용하지 않는 경우가 많습니다.

이때 killall Dock을 실행하면:

  1. Dock 프로세스 종료: 현재 메모리에서 실행 중인 Dock 프로세스를 강제로 종료시킵니다.
  2. 자동 재시작: macOS는 시스템의 핵심 구성 요소인 Dock이 종료되면 이를 자동으로 감지하고, 몇 초 내에 Dock을 다시 시작합니다.
  3. 설정 적용: Dock이 새로 시작되면서 이전에 defaults write 명령어로 수정했던 설정 파일(com.apple.dock.plist)의 변경된 값들을 다시 읽어와 적용하게 됩니다.

결론적으로, **"Dock을 재시작하여 변경된 설정을 즉시 반영하라!"**는 의미로 사용되며, 터미널을 통해 Dock 설정을 변경할 때 거의 필수적으로 함께 사용됩니다.

 

2. 맥북 알림 볼륨 관련 터미널 설정

맥북의 알림 소리는 특정 이벤트 발생 시 사용자에게 중요한 정보를 전달하는 역할을 합니다. 하지만 때로는 알림 소리가 너무 크거나 작다고 느껴질 수 있습니다. 아쉽게도 맥북의 "알림 볼륨"만을 개별적으로 조절하는 직접적인 defaults write 명령어는 일반 사용자에게 공개되어 있지 않거나 매우 복잡합니다. 대부분의 macOS 시스템 오디오 설정은 osascript (AppleScript)를 사용하거나, coreaudiod와 같은 오디오 데몬을 제어하는 방식이 더 일반적입니다.

 

⚠️ 주의사항: 아래 명령어는 특정 앱의 알림 볼륨만을 조절하는 것이 아니라, 맥북의 전체 시스템 마스터 볼륨을 조절합니다. 특정 앱의 알림 볼륨은 해당 앱의 설정이나 시스템 환경설정의 "알림" 섹션에서 개별적으로 조절해야 합니다.

 

💡 현재 시스템 볼륨 확인하기

osascript -e 'output volume of (get volume settings)'

이 명령어를 터미널에 입력하면 현재 설정된 마스터 볼륨이 0부터 100 사이의 정수 값으로 출력됩니다. 예를 들어, 65와 같이 표시될 수 있습니다.

 

💡 시스템 볼륨 설정하기

osascript -e 'set volume output volume [원하는 숫자]'

[원하는 숫자] 부분에 0부터 100 사이의 볼륨 값을 입력합니다. 숫자가 클수록 볼륨이 커지고, 작을수록 볼륨이 작아집니다. 예를 들어, 조용한 환경에서는 30 정도로 설정하고, 시끄러운 환경에서는 70 이상으로 설정하는 등의 유연한 조절이 가능합니다. (예: 볼륨을 50으로 설정: osascript -e 'set volume output volume 50')

 

💡 시스템 볼륨 음소거/음소거 해제하기

갑작스러운 소리 재생을 막거나, 다시 소리를 켜야 할 때 유용합니다.

  • 음소거:이 명령어를 실행하면 시스템 볼륨이 즉시 음소거됩니다.
  • osascript -e 'set volume with output muted'
  • 음소거 해제:이 명령어를 실행하면 음소거가 해제되고 이전 볼륨 설정으로 돌아갑니다.
  • osascript -e 'set volume without output muted'

 

💡 앱별 알림 볼륨 조절은 어떻게 하나요?

특정 앱의 알림 볼륨을 조절하고 싶다면, 다음 경로를 통해 설정할 수 있습니다.

  1. 시스템 설정 열기: 화면 왼쪽 상단의 Apple 메뉴()를 클릭하고 "시스템 설정"을 선택합니다.
  2. "알림" 이동: 사이드바에서 "알림"을 클릭합니다.
  3. 앱별 설정: 목록에서 원하는 앱을 선택한 후, 해당 앱의 알림 스타일, 사운드 여부 등을 개별적으로 설정할 수 있습니다. 여기서는 볼륨 자체를 조절하기보다는 알림 사운드를 켜거나 끄는 옵션이 주로 제공됩니다.

 

터미널 명령어 사용 시 유의사항

defaults write와 osascript 같은 터미널 명령어는 맥북을 강력하게 제어할 수 있는 도구이지만, 사용 시 몇 가지 주의사항이 있습니다.

  • 정확한 명령어 입력: 터미널 명령어는 대소문자를 구분하며, 띄어쓰기 하나에도 오류가 발생할 수 있습니다. 오타 없이 정확하게 입력하는 것이 중요합니다.
  • 명령어 이해의 중요성: 각 명령어가 어떤 시스템 설정을 변경하는지 정확히 이해하고 사용해야 합니다. 불필요하거나 잘못된 명령어를 실행할 경우, 시스템 오류나 예상치 못한 동작을 유발할 수 있습니다.
  • 백업의 생활화: 중요한 시스템 설정을 변경하기 전에는 항상 Time Machine 등을 이용하여 맥북을 백업해두는 습관을 들이는 것이 좋습니다. 만약의 사태에 대비할 수 있습니다.
  • macOS 업데이트와의 호환성: 일부 defaults write 명령어는 macOS 버전 업데이트 시 더 이상 작동하지 않거나, 설정이 초기화될 수 있습니다. 새로운 macOS 버전으로 업데이트한 후에는 변경된 설정이 잘 유지되는지 확인하는 것이 좋습니다.
  • 정보 출처 확인: 온라인에서 찾은 터미널 명령어를 무작정 따라 하기보다는, 신뢰할 수 있는 출처(Apple 공식 문서, 검증된 기술 블로그 등)의 정보를 참고하는 것이 안전합니다.

 

마치며

오늘은 맥북의 Dock 아이콘 크기를 조절하고, 시스템 볼륨을 터미널 명령어를 통해 제어하는 방법을 더욱 자세히 알아보았습니다. 시스템 설정(GUI)과 터미널 명령어를 적절히 활용하면, 여러분의 맥북을 더욱 효율적이고 개인적인 작업 환경으로 만들 수 있습니다.

defaults write와 osascript는 맥북을 더욱 세밀하게 커스터마이징할 수 있는 강력한 도구이며, 이를 통해 여러분의 맥북 사용 경험이 한층 더 풍부해질 것입니다. 이 포스팅이 여러분의 맥북 커스터마이징 여정에 유용한 가이드가 되기를 바랍니다. 궁금한 점이 있다면 언제든지 댓글로 남겨주세요!

728x90
728x90

언젠가부터 github에 나의 commit이 보이지 않았다.

 

원인은 commit 정보에 담겨있는 user.email과 user.name이 github계정 정보와 다르기 때문이다.

 

0. 앞으로 새로 작성할 커밋부터 올바르게

git config --global user.name  "홍길동"
git config --global user.email "me@example.com"

 

1. 백업

git clone --mirror (원격리포주소) (생성 할 백업 폴더)

 

2. 매핑 파일(authors.map 또는 .mailmap) 작성

홍길동 <new@example.com> <old@example.com>
<new_work@example.com> <work@example.com>

 

<새 이메일> <옛 이메일> --> 이름 변경까지 원하면 앞에 "새 이름 <새메일> <옛메일>"

꺾쇠(괄호) 가 있어야 함

 

2-1. 기록된 이메일 확인

git log --all --format='%ae' | sort -u

 

3. 히스토리 재작성 명령

git filter-repo \
   --mailmap authors.map \       # 또는 --use-mailmap
   --force \                     # 작업 디렉터리 보호 대화 생략
   --refs $(git for-each-ref --format='%(refname)')   # 모든 브랜치·태그

 

파일명을 .mailmap 으로 두면 --use-mailmap, 임의 이름이면 --mailmap authors.map 옵션 사용.

 

 

4. 결과 확인

git log --all --format='%h %an <%ae>' | head
git log --all --format='%ae' | sort -u   # 더는 old@example.com 이 없어야 한다

 

5. 원격 반영

git push --force --all

 

팀원이 있을 경우 기존 커밋 해시가 모두 바뀌므로, 팀원에게 “레포를 새로 클론” 하도록 공지.

 

728x90
728x90

네이버 클라우드의 용량이 꽉 찼습니다.

물론 결제를 한다면 용량을 늘릴 수 있겠습니다만 매월 나가는 돈이 아깝습니다.

그리하여 라즈베리파이에 Seafile을 설치하여 네이버 클라우드를 대신 해보려 합니다.

 

 

0. 플랜(Plan)

라즈베리파이에서 Docker Compose를 이용해 Seafile을 설치하고, 외부에서 접속할 수 있도록 포트포워딩을 설정합니다.

Docker 설치 → Seafile 실행을 위한 YML 파일 작성 → WebDAV 접속을 위한 포트 포워딩 설정

 

 

1. Docker 및 Docker Compose 설치

먼저, 라즈베리파이에 Docker와 Docker Compose를 설치합니다.

 

1.1 패키지 업데이트 및 Docker 설치

sudo apt update && sudo apt upgrade -y
sudo apt install docker.io -y

 

 

1.3 Docker 서비스 활성화 및 사용자 추가

sudo systemctl enable docker
sudo systemctl start docker
sudo usermod -aG docker $USER

 

로그아웃 후 다시 로그인하여 변경 사항을 적용합니다.

 

1.3 Docker Compose 설치

sudo curl -L "https://github.com/docker/compose/releases/latest/download/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose # 설치
sudo chmod +x /usr/local/bin/docker-compose # 권한 부여

 

 

 

2. Seafile Docker Compose 파일 작성

이제 `docker-compose.yml` 파일을 생성하고 Seafile 컨테이너를 설정합니다.

 

2.1 작업 디렉토리 생성

mkdir -p ~/seafile && cd ~/seafile

 

2.2 `docker-compose.yml` 파일 작성

nano docker-compose.yml

 

 

다음 내용을 `docker-compose.yml` 파일에 입력합니다.

services:
  db:
    image: mariadb:latest
    container_name: seafile-mysql
    restart: always
    environment:
      - MYSQL_ROOT_PASSWORD=rootpass
      - MYSQL_DATABASE=seafile
      - MYSQL_USER=seafile
      - MYSQL_PASSWORD=seafilepass
    volumes:
      - ./mysql:/var/lib/mysql

  memcached:
    image: memcached:latest
    container_name: seafile-memcached
    entrypoint: memcached -m 256
    restart: unless-stopped

  seafile:
    image: seafileltd/seafile-mc:12.0-latest
    container_name: seafile
    restart: always
    ports:
      - "80:80"
      - "443:443"
      - "8080:8080"
    environment:
      - DB_HOST=db
      - DB_ROOT_PASSWD=rootpass
      - TIME_ZONE=Asia/Seoul
      - SEAFILE_ADMIN_EMAIL=admin@example.com
      - SEAFILE_ADMIN_PASSWORD=adminpass
      - SEAFILE_SERVER_LETSENCRYPT=false
      - JWT_PRIVATE_KEY=<openssl rand -base64 32>
    volumes:
      - ./seafile-data:/shared
    depends_on:
      - db

environment, ports는 사용자에 맞게 수정 필요

JWT_PRIVATE_KEY는 openssl rand -base64 32을 실행한 결과를 붙여 넣기

SEAFILE_SERVER_LETSENCRYPT=false 를 true 수정하면 ssl 인증서를 SEAFILE_ADMIN_EMAIL=admin@example.com 에 설정된 도메인으로 발급받아 https를 사용할 수 있다.

ports는 ( 라즈베리파이 포트 ):( docker 포트 )으로 설정합니다.

 

2.3 컨테이너 실행

docker-compose up -d

 

 

3. 공유기 포트포워딩 설정

외부에서 Seafile에 접속할 수 있도록 공유기에서 포트포워딩을 설정해야 합니다.

 

3.1 공유기 관리자 페이지 접속

1. 웹 브라우저에서 공유기 주소 입력 (예: 192.168.0.1)

2. 로그인 후 **포트포워딩 설정** 메뉴로 이동

 

3.2 포트포워딩 규칙 추가

| 서비스 이름 | 내부 IP (라즈베리파이) | 내부 포트 | 외부 포트 | 프로토콜 |
| Seafile HTTP | `192.168.0.X` | `80` | `80` | TCP |
| Seafile HTTPS | `192.168.0.X` | `443` | `443` | TCP |

 

3.3 DDNS 설정

외부에서 접속은 공인IP:PORT를 입력하여 접속 할 수 있습니다만

보통 IP는 유동 IP입니다. 물론 IP가 변한걸 본적이 없지만

DDNS 설정을 통해 IP부분을 대신할 문자를 설정 할 수 있습니다.

 

마무리

이제 Seafile이 라즈베리파이에서 동작하며, 외부에서도 접근이 가능합니다. 보안을 위해 SSL 설정과 방화벽 설정을 추가하는 것을 권장합니다.

728x90
728x90

바야흐로 데이터의 시대입니다. 데이터를 잘 활용하는 능력은 이제 특정 직무에만 국한된 것이 아닙니다. 리서치, 기획, 마케팅 등 다양한 직군에서도 데이터 분석 능력을 요구받고 있죠. 문제는 수많은 데이터 속에서 필요한 정보를 어떻게 잘 활용하느냐입니다. 그래서 개발자나 데이터 분석가가 아닌 직군에서 데이터를 더 잘 활용하고 싶은 분들을 위해 제가 공부하며 도움이 되었던 책들을 요약해 소개해드리겠습니다.

 

1. 데이터 읽기의 기술 (차현나)

추천 이유: 데이터의 본질을 이해하는 데 도움이 되는 책입니다. 데이터를 다룰 때 중요한 것은 기술이 아니라 올바른 질문을 던지는 것임을 알려줍니다. SQL이나 Python 같은 기술을 배우기 전에 왜 데이터를 다루는지를 먼저 생각하게 하는 좋은 책입니다.

 

2. 데이터 리터러시 (강양석)

추천 이유: 이 책은 데이터가 비즈니스 환경에서 어떻게 쓰이는지에 대해 구체적인 사례와 조언을 제공합니다. 기술적인 설명보다는 데이터의 활용 맥락을 이해하는 데 중점을 둔 도서로, 직장에서 데이터를 어떻게 사용해야 할지 고민하는 분들에게 추천합니다.

 

3. 세상에서 가장 쉬운 통계학입문 (고지마 히로유키)

추천 이유: 데이터 분석의 기초가 되는 통계학을 쉽게 설명합니다. 통계에 대한 두려움을 덜어내고 기본적인 개념을 익히기 좋은 책입니다. 예를 들어 A/B 테스트 같은 실무에서 자주 접하는 통계적 개념을 알기 쉽게 설명해 줍니다.

 

4. 확률적 사고의 힘 (다부치 나오야)

추천 이유: 데이터를 분석할 때 100% 확실한 답은 없습니다. 이 책은 확률적 사고를 통해 불확실성을 받아들이고, 이를 바탕으로 더 나은 결정을 내릴 수 있는 관점을 제공합니다. 데이터를 다룰 때 완벽함을 추구하려는 압박감에서 벗어나게 해주는 좋은 도서입니다.

 

5. 알라딘: 데이터를 부탁해

추천 이유: 앞의 책들이 데이터에 대한 관점과 사고방식을 다루었다면, 이 책은 실제 데이터를 다루는 데 필요한 기술과 이론을 설명합니다. 분석을 배우려는 사람에게 기술적인 이해도를 높이는 데 유용한 참고서입니다.

728x90
728x90

소수는 수학에서 언제나 특별한 존재입니다. 1과 자기 자신 외에는 나눠지지 않는 소수는 그 자체로도 아름답지만, 그들이 이루는 등차수열, 즉 '소수 등차수열'은 또 다른 매력을 가지고 있습니다. 이번 포스팅에서는 소수 등차수열에 대해 쉽게 이해할 수 있도록 설명해 보겠습니다.

 

소수 등차수열이란?

소수 등차수열(Prime Arithmetic Sequence)은 말 그대로 각 항이 소수로 이루어진 등차수열입니다. 등차수열은 연속된 항들 간의 차이가 일정한 수열을 말하며, 소수 등차수열은 이 조건을 만족하면서 모든 항이 소수여야 합니다. 쉽게 말해, 각 항이 일정한 차이를 가지면서도 모두 소수인 수열을 말하는 것입니다

 

소수 등차수열의 예시

  • 3, 7, 11
    • 이 수열은 각 항 사이의 차이가 4입니다.
    • 모든 항이 소수(3, 7, 11)로 구성되어 있습니다.
  • 5, 11, 17, 23
    • 이 수열의 각 항 사이의 차이는 6입니다.
    • 5, 11, 17, 23 역시 모두 소수이기 때문에 소수 등차수열로 인정됩니다.

이와 같이 소수 등차수열을 찾기 위해서는 각 항 사이의 차이(공차)가 일정하고, 모든 항이 소수인지 확인해야 합니다.

 

등차수열의 일반적인 특징

등차수열은 모든 연속된 두 항 사이의 차이가 일정한 수열입니다. 수열의 일반 항을 구할 수 있는 공식은 다음과 같습니다:

a𝜋 = a𝜀 + (n-1) ⋅ d

  • 여기서 a𝜀는 첫 번째 항, d는 공차입니다.
  • 소수 등차수열의 경우, 이 일반 항을 계산했을 때 모든 결과값이 소수가 되어야 합니다.

소수 등차수열을 찾는 방법

소수 등차수열을 찾는 것은 생각보다 어려운 작업입니다. 왜냐하면 소수는 일반적인 숫자들과는 다르게 규칙적으로 배치되지 않기 때문입니다. 그러나 다음과 같은 과정을 통해 소수 등차수열을 찾을 수 있습니다:

  1. 소수 생성: 원하는 범위 내에서 모든 소수를 구합니다. 이를 위해 '에라토스테네스의 체' 같은 알고리즘을 사용할 수 있습니다.
  2. 등차수열 조건 확인: 구한 소수 목록에서 공차를 설정하고, 그 공차를 기준으로 수열을 형성해 보면서 해당 항이 모두 소수인지 확인합니다.

 

파이썬으로 소수 등차수열 찾기

개발자 블로그를 위한 실습으로, n개의 연속된 소수로 이루어진 등차수열을 찾는 파이썬 코드를 추가해 보았습니다. 아래 코드는 주어진 소수 범위 내에서 n개의 소수 등차수열을 찾아 출력하는 예시입니다:

from sympy import isprime

def find_prime_arithmetic_sequence(n, limit):
    primes = [i for i in range(2, limit) if isprime(i)]
    length = len(primes)
    
    for i in range(length - n + 1):
        for j in range(i + 1, length):
            d = primes[j] - primes[i]
            sequence = [primes[i] + k * d for k in range(n)]
            if all(isprime(x) for x in sequence):
                print(f"소수 등차수열 발견: {sequence}")
                return sequence
    
    print("조건에 맞는 소수 등차수열을 찾지 못했습니다.")
    return None

# n개의 연속된 소수 등차수열 찾기 예시
n = 4
limit = 1000
find_prime_arithmetic_sequence(n, limit)
  • 설명:
    • isprime() 함수는 주어진 수가 소수인지 판별합니다. 이는 sympy 라이브러리를 이용하여 구현되었습니다.
    • find_prime_arithmetic_sequence() 함수는 첫 번째 인자로 찾고자 하는 수열의 길이 n, 두 번째 인자로 소수 탐색의 범위를 지정하는 limit을 받습니다.
    • 모든 소수를 구한 후, 이들 중에서 가능한 모든 등차수열을 탐색하며, 해당 수열의 모든 항이 소수인지 확인합니다.

위 코드를 통해 특정한 길이의 소수 등차수열을 찾을 수 있습니다. 예를 들어 n=4, limit=1000으로 설정했을 때, 길이가 4인 소수 등차수열을 찾아낼 수 있습니다.

 

실제 발견된 긴 소수 등차수열

소수 등차수열은 수학 연구에서도 중요한 주제입니다. 특히 긴 소수 등차수열을 발견하는 것은 소수의 분포와 성질을 이해하는 데 큰 도움을 주기 때문입니다. 2004년에는 세 명의 수학자가 10개 이상의 항을 가지는 가장 긴 소수 등차수열을 발견하면서 큰 주목을 받았습니다. 이 발견은 소수들이 매우 규칙적으로 배치될 수 있다는 가능성을 열어준 중요한 사례였습니다.

 

결론

소수 등차수열은 단순히 숫자들의 나열이 아닌, 수학의 아름다움과 규칙성을 보여주는 흥미로운 예시입니다. 소수들의 등차수열은 그들 사이에 존재하는 숨겨진 패턴과 규칙성을 탐구하는 데 도움을 주며, 이 과정에서 우리는 수학의 무한한 가능성을 엿볼 수 있습니다.

수학을 공부하는 사람이라면 한 번쯤 소수 등차수열에 대해 탐구해 보는 것도 재미있을 것입니다. 작은 소수들이 어떻게 아름다운 수열을 이루는지, 그리고 그 속에서 발견되는 규칙성은 우리가 숫자에 대해 갖고 있던 시각을 새롭게 바꾸어 줄 것입니다.

728x90
728x90

숫자에는 우리가 미처 알지 못했던 흥미로운 규칙과 비밀이 숨어 있습니다. 이번 포스팅에서는 몇 가지 간단한 규칙을 통해 숫자의 매력을 탐구해볼까요? 각 숫자의 배수성 판단을 위한 재미있는 규칙을 살펴보며, 이를 효율적으로 활용할 방법에 대해 알아보겠습니다.

 

2의 배수: 마지막 자리가 짝수인지 확인

숫자가 짝수인지 판단하는 가장 간단한 방법은 마지막 자리를 보는 것입니다. 마지막 자리가 0, 2, 4, 6, 8 중 하나라면 그 숫자는 짝수입니다.

예시:

  • 12 → 짝수
  • 35 → 홀수
number = 12
if number % 2 == 0:
    print(f"{number}은 짝수입니다.")
else:
    print(f"{number}은 홀수입니다.")

 

3의 배수: 각 자리 숫자의 합

어떤 숫자가 3의 배수인지 확인할 때, 각 자리 숫자의 합이 3으로 나누어지는지 확인하면 됩니다.

예시:

  • 27 → (3의 배수)
  • 134 → (3의 배수가 아님)
def is_multiple_of_3(number):
    digit_sum = sum(int(digit) for digit in str(number))
    return digit_sum % 3 == 0

number = 27
if is_multiple_of_3(number):
    print(f"{number}은 3의 배수입니다.")
else:
    print(f"{number}은 3의 배수가 아닙니다.")

 

4의 배수: 마지막 두 자리가 4의 배수

숫자가 4의 배수인지 확인하려면 마지막 두 자리가 4로 나누어떨어지는지 보면 됩니다.

예시:

  • 316 → (4의 배수)
  • 123 → (4의 배수가 아님)
number = 316
last_two_digits = int(str(number)[-2:])
if last_two_digits % 4 == 0:
    print(f"{number}은 4의 배수입니다.")
else:
    print(f"{number}은 4의 배수가 아닙니다.")

 

5의 배수: 마지막 자리가 0 또는 5

5의 배수인지 확인하려면 숫자의 끝이 0이나 5인지 확인하세요.

예시:

  • 25 → 5의 배수
  • 42 → 5의 배수가 아님
number = 25
if str(number)[-1] in ('0', '5'):
    print(f"{number}은 5의 배수입니다.")
else:
    print(f"{number}은 5의 배수가 아닙니다.")

 

6의 배수: 2의 배수이면서 3의 배수

숫자가 6의 배수인지 확인하려면 두 가지 조건을 모두 만족해야 합니다: 짝수이면서 각 자리 숫자의 합이 3으로 나눠져야 합니다.

예시:

  • 18 → 짝수이고 (3의 배수, 따라서 6의 배수)
  • 20 → 짝수지만 (3의 배수가 아님)
def is_multiple_of_6(number):
    return number % 2 == 0 and sum(int(digit) for digit in str(number)) % 3 == 0

number = 18
if is_multiple_of_6(number):
    print(f"{number}은 6의 배수입니다.")
else:
    print(f"{number}은 6의 배수가 아닙니다.")

 

7의 배수: 독특한 규칙

7의 배수를 확인하는 규칙은 다소 복잡할 수 있습니다. 숫자에서 나누기 10을 한 몫에서 1의 자리 숫자에 2를 곱한 숫자를 뺍니다.

예시:

  • 371 → 37 - (1 x 2), 35는 7의 배수
def is_multiple_of_7(number):
    while number > 99:
        last_digit = number % 10
        remaining_number = number // 10
        number = remaining_number - (last_digit * 2)
    return number % 7 == 0

number = 371
if is_multiple_of_7(number):
    print(f"{number}은 7의 배수입니다.")
else:
    print(f"{number}은 7의 배수가 아닙니다.")

 

8의 배수: 마지막 세 자리에 주목하라

숫자가 8의 배수인지 확인하려면 마지막 세 자리가 8로 나누어떨어지는지 보면 됩니다.

예시:

  • 1048 → (8의 배수)
  • 1234 → (8의 배수가 아님)
number = 1048
last_three_digits = int(str(number)[-3:])
if last_three_digits % 8 == 0:
    print(f"{number}은 8의 배수입니다.")
else:
    print(f"{number}은 8의 배수가 아닙니다.")

 

9의 배수: 각 자리 수의 합이 9의 배수

각 자리 숫자의 합이 9로 나누어지는지 확인하면 그 숫자가 9의 배수인지 알 수 있습니다.

예시:

  • 729 → (9의 배수)
  • 812 → (9의 배수가 아님)
def is_multiple_of_9(number):
    digit_sum = sum(int(digit) for digit in str(number))
    return digit_sum % 9 == 0

number = 729
if is_multiple_of_9(number):
    print(f"{number}은 9의 배수입니다.")
else:
    print(f"{number}은 9의 배수가 아닙니다.")

 

마무리: 숫자의 규칙을 활용해보세요!

이렇게 다양한 숫자의 규칙들을 알고 있다면, 숫자와 관련된 문제를 더 빠르고 효율적으로 풀 수 있습니다. 간단한 규칙 하나가 큰 차이를 만들어낼 수 있죠. 앞으로 숫자를 다룰 때 이러한 규칙을 떠올리며 활용해 보세요!

 

독자에게 질문!

  • 숫자 2532는 어떤 규칙에 해당할까요?
  • 여러분이 알고 있는 다른 흥미로운 숫자 규칙은 무엇인가요?

댓글로 여러분의 생각을 나눠보세요! 😊

728x90
728x90

전자책(eBook)을 수험서처럼 활용하거나 필기를 하려면 Goodnote나 Notability 같은 어플에서 열고 싶을 때가 많죠. 그러나 이런 기능이 기본 앱에서는 제한적이라 불편할 수 있습니다.

이번에 소개할 코드는 알라딘 전자책을 캡처해서 PNG 이미지로 만드는 과정을 자동화한 것입니다.(windows 환경) 이 매크로 도구는 페이지를 빠르고 정확하게 스캔해주는 기능을 제공합니다. 이를 통해 공부 자료로 활용하기 쉽게 전자책을 정리할 수 있습니다.

 

매크로 도구 소개

이 매크로 도구의 핵심은 알라딘 eBook 서비스에서 eBook 페이지를 캡처하는 반복 작업을 자동화하는 Python 스크립트입니다. pyautogui를 사용한 자동화, pynput을 사용한 마우스 제어, 그리고 실시간 확대를 위한 tkinter와 같은 강력한 Python 라이브러리 조합을 사용하여 이 스크립트는 전체 과정을 단순화합니다. 최소한의 수동 입력으로 몇 번의 클릭만으로 콘텐츠를 추출할 수 있습니다.

이 매크로를 효과적으로 사용하는 방법과 기능을 좀 더 자세히 살펴보겠습니다.

 

매크로 도구의 주요 기능

  1. 마우스 좌표 캡처: 스크립트는 화면에서 캡처하려는 영역을 정의할 시작과 끝 좌표를 선택하도록 합니다. 사용자는 두 지점(시작과 끝)을 클릭하여 영역을 설정할 수 있으며, 도구는 이 지점을 기록하여 정확한 스크린샷 작업을 준비합니다.
  2. 정밀한 선택을 위한 실시간 확대기: 주요 기능 중 하나는 tkinterPIL(Pillow) 라이브러리로 구축된 실시간 확대 창입니다. 이 확대기는 마우스 포인터 주변의 확대된 뷰를 제공하여, eBook 페이지의 시작과 끝 지점을 정확하게 선택할 수 있게 합니다. 작은 텍스트나 세부 사항을 다룰 때 특히 유용하여 오류를 최소화하는 데 도움을 줍니다.
  3. 자동 핫키 및 드래그 동작: 좌표가 설정되면, 스크립트는 기본 Windows 화면 캡처 도구를 불러오는 Win + Shift + S 단축키를 누릅니다. 이후 마우스 커서를 시작 지점으로 이동시킨 후 끝 지점까지 자동으로 드래그하여 페이지를 캡처합니다.
  4. 페이지 넘기기: 효율성을 더욱 높이기 위해, 스크립트는 오른쪽 화살표 키를 눌러 eBook의 다음 페이지로 이동하는 동작을 자동으로 수행합니다. 이 기능은 책을 수동으로 넘기는 시간을 최소화하여 연속적으로 페이지를 캡처할 수 있게 합니다.

 

코드 리뷰 및 설명

이제 각 코드의 주요 부분을 코드 리뷰 형식으로 분석해 보겠습니다.

 

1. 라이브러리 임포트

import time
import pyautogui
from pynput.mouse import Listener, Controller
import threading
import numpy as np
import tkinter as tk
from PIL import Image, ImageTk, ImageDraw
  • pyautogui: 마우스 이동, 키 입력 시뮬레이션, 화면 캡처 등 자동화 작업에 사용됩니다. 다소 직관적이지만 Windows 환경에서는 권한 문제로 인해 정상 동작하지 않을 수도 있으므로, 관리자 권한으로 실행해야 할 수 있습니다.
  • pynput.mouse: 마우스 이벤트를 제어하고 좌표를 설정하는 데 사용됩니다. Listener는 클릭 이벤트를 감지하고, Controller는 마우스를 프로그램적으로 제어하는 역할을 합니다.
  • tkinter & PIL: GUI 구성 및 이미지 처리를 위해 사용됩니다. 특히 확대기를 만들어 더 정밀한 좌표 설정이 가능하게 합니다.

 

2. 실시간 확대기 기능

def live_magnifier():
    global root
    root = tk.Tk()
    root.title("Magnifier")
    label = tk.Label(root)
    label.pack()

    zoom_size = 100
    zoom_factor = 3

    def update_frame():
        if start_point is None or end_point is None:
            x, y = mouse.position
            try:
                screenshot = pyautogui.screenshot(region=(x - zoom_size // 2, y - zoom_size // 2, zoom_size, zoom_size))
                frame = screenshot.resize((zoom_size * zoom_factor, zoom_size * zoom_factor), Image.LANCZOS)
                draw = ImageDraw.Draw(frame)
                pointer_x = zoom_size * zoom_factor // 2
                pointer_y = zoom_size * zoom_factor // 2
                radius = 5
                draw.ellipse((pointer_x - radius, pointer_y - radius, pointer_x + radius, pointer_y + radius), fill='red')
                tk_image = ImageTk.PhotoImage(frame)
                label.config(image=tk_image)
                label.image = tk_image
            except Exception as e:
                print(f"Error with live magnifier: {e}")

            root.after(100, update_frame)
        else:
            root.destroy()

    update_frame()
    root.mainloop()
  • Tkinter UI 구성: 확대기 창을 생성하고 Label 위젯에 이미지를 표시합니다.
  • 스크린샷 및 확대: pyautogui.screenshot()을 사용하여 마우스 주변을 캡처하고 확대합니다. 이 과정에서 성능 문제가 발생할 수 있으므로 너무 높은 확대 배율은 피하는 것이 좋습니다.
  • 마우스 포인터 표시: 현재 확대된 이미지 중앙에 마우스 포인터를 빨간 원으로 표시하여 사용자가 정확한 위치를 파악할 수 있도록 도와줍니다.

 

3. 마우스 클릭 이벤트 리스너

def on_click(x, y, button, pressed):
    global start_point, end_point
    if pressed:
        if start_point is None:
            start_point = (x, y)
            print(f"Start point set at: {start_point}")
        elif end_point is None:
            end_point = (x, y)
            print(f"End point set at: {end_point}")
            return False
  • 시작 및 끝 좌표 설정: 첫 번째 클릭은 시작 좌표, 두 번째 클릭은 끝 좌표를 설정합니다. 이렇게 설정된 좌표는 이후 스크린샷에 사용됩니다.
  • Listener 종료: 두 번째 좌표 설정 후 return False로 리스너를 종료합니다. 불필요한 이벤트 감지를 막아 성능을 개선합니다.

 

4. 매크로 동작

def macro():
    for _ in range(1):
        time_s = 0.3
        pyautogui.hotkey('win', 'shift', 's')
        time.sleep(time_s)

        if start_point is not None and end_point is not None:
            start_x, start_y = start_point
            end_x, end_y = end_point
            pyautogui.moveTo(start_x, start_y)
            pyautogui.dragTo(end_x, end_y, duration=0.5, button='left')
            time.sleep(time_s)
        else:
            print("Error: Start and end points are not set.")
            return

        pyautogui.press('right')
        time.sleep(time_s)
  • 화면 캡처 호출: pyautogui.hotkey('win', 'shift', 's')로 화면 캡처 도구를 호출합니다. 여기서 time.sleep(time_s)을 통해 적절한 대기 시간을 주어 도구가 실행될 시간을 확보합니다.
  • 드래그 캡처: 설정된 좌표를 사용해 드래그하여 영역을 선택합니다. 이때 duration을 통해 드래그 속도를 조절할 수 있습니다. 너무 빠르게 설정하면 정확한 영역을 선택하지 못할 수도 있으니 적절히 조정합니다.
  • 페이지 넘김: 캡처 후 다음 페이지로 이동하기 위해 오른쪽 화살표 키를 누릅니다.

 

주요 이점 및 코드 개선 아이디어

  • 효율성: 반복 작업을 최소화하고 빠른 캡처가 가능합니다.
  • 정확성: 확대 기능을 통해 캡처 영역의 경계를 정확하게 지정할 수 있습니다.
  • 코드 개선: pyautogui의 다양한 기능을 활용해 사용자의 작업 패턴에 맞게 매크로를 커스터마이징할 수 있습니다. 추가적으로, 스레딩과 최적화 기법을 사용해 확대기 성능을 개선할 여지도 있습니다.

 

결론

이 매크로 도구를 사용하면 알라딘 서비스에서 eBook 페이지를 손쉽고 간편하게 캡처할 수 있습니다. 반복 작업에 대한 효율적인 솔루션을 찾고 있는 사람에게 이 매크로는 상당한 시간을 절약해 줄 수 있습니다.

더 많은 자동화 도구에 관심이 있거나 다른 서비스에 맞게 스크립트를 맞춤화하는 방법에 대해 깊이 알아보고 싶다면, 댓글로 알려주세요! 함께 자동화를 좀 더 연구해 봅시다.

728x90
728x90

소인수 분해는 주어진 정수를 소수들의 곱으로 표현하는 과정으로, 수학적 이론부터 암호학까지 다양한 분야에서 중요한 역할을 합니다. 이번 포스팅에서는 대표적인 소인수 분해 알고리즘들을 소개하고, 각각의 코드 구현과 시간 복잡도를 살펴보겠습니다.

 

1. 단순 나눗셈 (Trial Division)

알고리즘 소개

단순 나눗셈은 가장 기본적인 소인수 분해 방법으로, 작은 소수들로 주어진 수를 하나씩 나누어 떨어지는지를 확인합니다. 구현이 간단하지만, 큰 수에 대해서는 매우 비효율적입니다.

 

코드 구현

def trial_division(n):
    factors = []
    # 2로 나누어 떨어지는 경우 처리
    while n % 2 == 0:
        factors.append(2)
        n //= 2
    # 홀수들로 나누기 시작
    i = 3
    while i * i <= n:
        while n % i == 0:
            factors.append(i)
            n //= i
        i += 2
    # 남은 소수 추가
    if n > 1:
        factors.append(n)
    return factors

 

시간 복잡도

  • 시간 복잡도: \( O(\sqrt{n}) \)
  • 작은 수에 대해서는 효율적이지만, nn이 큰 수일수록 실행 시간이 급격히 증가합니다.

2. 페르마 인수분해법 (Fermat's Factorization Method)

알고리즘 소개

페르마 인수분해법은 주어진 홀수 합성수 NN을 두 제곱수의 차로 표현하여 인수분해하는 방법입니다. 즉, N=x2−y2N = x^2 - y^2 형태로 변환하여 N=(x+y)(x−y)N = (x + y)(x - y)로 인수분해합니다.

 

코드 구현

import math

def fermat_factorization(n):
    x = math.isqrt(n) + 1
    while True:
        y_squared = x * x - n
        y = math.isqrt(y_squared)
        if y * y == y_squared:
            return [x - y, x + y]
        x += 1

 

시간 복잡도

  • 시간 복잡도: \( O(N^{1/4}) \)
  • NN이 두 소수의 곱인 경우 빠르게 인수분해할 수 있지만, 인수들이 서로 가까운 수일 때 효과적입니다.

3. 폴라드 로 알고리즘 (Pollard's Rho Algorithm)

알고리즘 소개

폴라드 로 알고리즘은 확률적 방법으로, 작은 인수를 가진 큰 수를 효율적으로 인수분해합니다. 함수의 반복 계산과 최대공약수를 이용하여 인수를 찾습니다.

 

코드 구현

import random
import math

def pollards_rho(n):
    if n % 2 == 0:
        return 2
    x = random.randrange(2, n)
    y = x
    c = random.randrange(1, n)
    d = 1
    while d == 1:
        x = (x * x + c) % n
        y = (y * y + c) % n
        y = (y * y + c) % n
        d = math.gcd(abs(x - y), n)
        if d == n:
            return pollards_rho(n)
    return d

 

시간 복잡도

  • 평균 시간 복잡도: \( O(n^{1/4}) \)
  • 확률적 알고리즘으로, 일반적으로 빠르게 인수를 찾지만 최악의 경우 시간이 오래 걸릴 수 있습니다.

4. 폴라드 p-1 알고리즘 (Pollard's p-1 Algorithm)

알고리즘 소개

폴라드 p-1 알고리즘은 p−1p - 1이 작은 소인수들로 구성된 소수 pp를 인수로 가진 합성수를 인수분해하는 데 효과적입니다.

 

코드 구현

import math

def pollards_p_minus_one(n, B=13):
    a = 2
    for j in range(2, B + 1):
        a = pow(a, j, n)
    d = math.gcd(a - 1, n)
    if 1 < d < n:
        return d
    else:
        return None

 

시간 복잡도

  • 시간 복잡도: \( O(B \times \log n) \)
  • BB는 소인수의 크기에 따라 선택되며, 작은 인수를 가진 수에 대해 효율적입니다.

5. 타원곡선 방법 (Elliptic Curve Method, ECM)

알고리즘 소개

ECM은 타원곡선을 이용하여 큰 수의 소인수를 찾는 알고리즘입니다. 작은 인수를 찾는 데 특히 효율적이며, 현재 가장 빠른 알고리즘 중 하나입니다.

 

시간 복잡도

  • 평균 시간 복잡도: \( O(e^{\sqrt{\ln p \ln \ln p}}) \)
  • 여기서 pp는 찾고자 하는 소인수입니다.
  • 작은 소인수를 찾는 데 매우 효율적입니다.

6. 이차 체 방법 (Quadratic Sieve, QS)

알고리즘 소개

이차 체 방법은 큰 수의 인수분해에 효율적인 알고리즘으로, 병렬 처리가 가능하여 현대 컴퓨터에서 많이 사용됩니다.

 

시간 복잡도

  • 시간 복잡도: \( O(e^{\sqrt{\ln n \ln \ln n}}) \)
  • nn이 큰 수에 대해서도 준수한 성능을 보입니다.

7. 수체 체 방법 (Number Field Sieve, NFS)

알고리즘 소개

수체 체 방법은 현재 가장 빠른 일반적인 인수분해 알고리즘으로, 매우 큰 수의 인수분해에 사용됩니다.

 

시간 복잡도

  • 시간 복잡도: \( O(e^{(c(\ln n)^{1/3} (\ln \ln n)^{2/3})}) \)
  • 매우 큰 수에 대해서도 효율적입니다.

8. 디슨의 알고리즘 (Dixon's Factorization Method)

알고리즘 소개

디슨의 알고리즘은 합동 관계를 이용하여 합성수를 인수분해하는 확률적 알고리즘입니다. 이차 체 방법의 기반이 되었습니다.

 

코드 구현

import math
import random

def dixons_factorization(n):
    # 기본 구현은 매우 복잡하므로 간단한 버전을 제공합니다.
    # 실제로는 선형 대수와 합동 방정식을 사용합니다.
    return None  # 구현이 복잡하여 생략

 

시간 복잡도

  • 시간 복잡도: \( O(e^{\sqrt{\ln n \ln \ln n}}) \)
  • 이차 체 방법보다 비효율적이어서 현재는 잘 사용되지 않습니다.

마무리

소인수 분해는 수학적 흥미뿐만 아니라 실용적인 응용 분야에서도 중요한 문제입니다. 각 알고리즘은 수의 크기와 형태에 따라 효율성이 다르므로, 상황에 맞게 적절한 알고리즘을 선택해야 합니다.

 

참고 자료

728x90
728x90