일상에서의 문자 표현 C언어 문자 표현법
문자 A 'A', '65', '\0x41'
문자 [엔터키] '\n'
문자열  홍길동 "홍길동" (O), '홍길동' (X)

 

'홍길동'과 같이 두 개 이상의 문자를 넣을 수 없으며 이 경우 컴파일할 때 문법 오류가 발생한다.

C 문법에서 한글 한 문자 또한 단일 따옴표로 표현할 수 없다. "홍길동", "홍"과 같이 이중 따옴표를 사용(문자열)해야한다.

 

탈출문자

탈출문자  ASCII 문자 의미
\b BS 백스페이스
\t TAB
\n LF 개행
\" " 이중인용부호

 

 

++

C언어의 정수 상수 표현법

 

제일 앞에 보고 2진수인지 8진수인지 16진수인지 판단할 수 있음. 

=========

0b : 이진수

0 : 8진수

0x : 16진수

=========

 

 

 

'프로그래밍 > C,C++' 카테고리의 다른 글

C,C++ - 다양한 연산  (0) 2024.04.03
C,C++ - 입력함수 scanf()  (0) 2024.04.02
C,C++ - 필드폭과 정밀도 지정  (0) 2024.04.02
C, C++ - 변수 생성  (0) 2024.04.01
C언어와 코딩 (INTRO)  (0) 2024.04.01

코딩

> 문제해결과정 + 알맞은 언어

> 컴퓨팅적 사고력, 알고리즘, 코딩

 

기계어

> 0,1의 이진 코드만 이해할 수 있음.

 

어셈블리어 

> 기계어의 이진 명령 대신 ADD나 SUB와 같이 사람이 이해하기 쉬운 기호를 사용하도록 개발된 언어 

> 그런데 이것도 사람이 쓰는 자연어와는 거리가 멀어서 프로그램을 작성하는데에는 어려움이 여전히 있음.

 

고급언어

> 사람이 알아듣기 쉬움.

 

저급언어

> 컴퓨터와 밀접함,

> 기계어나 어셈블리어가 여기에 속함.

 

프로그램 개발 과정

  1. 요구사항 분석
  2. 설계(모듈 - 함수)
  3. 구현
  4. 테스트
  5. 배포 및 유지보수

소스파일은 기계어로 번역함.(컴파일)

 

 

C언어로 작성한 소스 파일에서 실행형 파일을 만들어 실행하는 과정 

 

소스파일 ---(컴파일링 - 컴파일러)---> 목적파일 ---(링킹)---> 실행파일 

(*.c, *.cpp)                                            (*.obj)                          (라이브러리 파일)

 

디버깅: 프로그램의 오류를 찾아내서 수정하는 과정

 

디버깅의 종류

  • 구문오류(컴파일 시간 오류 - 문법이 틀린 경우)
  • 링크오류(ex. 여러 소스 파일에 같은 이름의 함수가 중복으로 정의된 경우...)
  • 실행시간 오류(파일을 열고자 하는데 파일을 찾을 수 없을 때, )
  • 논리오류 (디버깅도구, 로그메시지 - 실행은 되지만 알고리즘이 잘못되어 의도한 대로 작동 X)

 

변수선언 > 입력 > 처리 > 출력

 

컴퓨터는 이산적 데이터만을 처리함.

 

비트는 데이터 표현의 최소 단위

ex) 8bits = 1byte

 

주석처리

  • // (한 줄)
  • /**/ (여러 줄)

'프로그래밍 > C,C++' 카테고리의 다른 글

C,C++ - 다양한 연산  (0) 2024.04.03
C,C++ - 입력함수 scanf()  (0) 2024.04.02
C,C++ - 필드폭과 정밀도 지정  (0) 2024.04.02
C, C++ - 변수 생성  (0) 2024.04.01
C,C++ - 문자, 문자열 상수 표현 문법  (1) 2024.04.01

이 책을 한 줄로 요약하자면 다음과 같다. 

'우리는 예지력을 갖고 미래를 알아맞힐 수는 없지만, 우리가 원하는 미래를 만들기 위해 노력하고 대응할 수 있습니다.'

 

 

 사람들은 예상하지 않은 미래가 오면 두려워한다. 그렇기 때문에 다가오는 미래에 대비하기 위해 각종 예방책과 대응수단을 마련한다. 카이스트 미래전략 2024는 미래에 효과적으로 대비하기 위해 과거와 현재, 미래를 한 권에 담아 독자에게 최대한 주관적인 요소를 배제하고 객관적으로 정보를 전달하고자 한다. 

 첫 번째 목차인 포스트 AI시대 휴머니즘의 미래는 도구가 어떻게 진화를 해왔는지 살펴보고 현 시점에 기술이 얼마만큼 발전했는지 설명한다. 가장 인상깊었던 목차는 초지능 사회를 열어줄 21세기 새로운 도구인데 여러 도구를 소개했지만 그 중 펌웨어의 도전 부분은 많이 충격적이었다. 이전에 필자는 사이버펑크라는 애니메이션을 본 적이 있는데 이 애니메이션은 2070년의 인간의 미래모습을 그린 작품으로 신체에 기계장치가 이식된 채로 살아가는 삶은 어떨지 보여준다. 이 작품을 보면서도 충격이었지만 실제로 비슷하게 그러한 시도를 현재 2023-2024년에 시행되고 있었다는 점이 충격이었다.

 한 가지 예를 소개하자면 최근 바이오닉스 분야에서 가장 뜨거운 이슈는 바로 인공 청각과 인공 시각이다. 인공 청각은 손상된 와우에 전극을 삽입해 전기신호로 변환된 소리를 청신경에 전달하는 장치인데 이미 1970년대에 사용화가 되어 선천적으로 청력을 잃은 많은 청각장애인에게 세상의 소리를 들려주고 있다고 한다. 또 일론머스크의 뇌공학 스타트업인 뉴럴링크는 뇌에 실 형태의 미세전극을 매우 높은 밀도로 정교하게 삽입하고 신경세포를 선택적으로 자극하거나 측정된 신경신호를 무선으로 전송하는 기술을 개발하고 있다. 이 기술이 상용화된다면 뇌를 직접 자극해 사물을 보게하고 소리를 듣게 하고 마비된 사지를 로봇의 힘을 빌려 움직일 수 있게 할 수 있다고 하는데 시간이 많이 걸리기는 하겠지만 실현된다면 이것 자체로 바이오 산업에서 챗GPT 만큼의 파장을 일으킬 수 있을거라고 생각한다. 하지만 이렇게 장애를 가진 사람들의 한계를 극복할 수 있는 장점이 될 수도 있지만 앞서말한 애니메이션 사이버펑크처럼 장애가 없는데도 신체의 기능을 높이기 위한 인간 증강의 기술로 활용될 수도 있다는 불안감도 준다. 이로 인해 인위적으로 개인의 능력을 증강한 사람이 그렇지 않은 사람보다 더 상위 계급이 되어 새로운 양극화를 만들어낼 수 있다. 따라서 우리가 원하는, 즉 인류의 행복을 위해서는 바이오닉스 기술의 감시와 통제는 필수적으로 이행되어야 할 것이다. 

 

 두 번째 목차인 변화에 대처하는 STEPPER 전략에서는 기업이나 국가, 개인, 가정이 다가오는 미래에 어떻게 대처해서 급변하는 사회에 대비할 수 있는지 담았다. 여기서 우리나라가 인구가 꾸준하게 감소하고 있는데 이에 대한 대비로 이민자를 수용해야한다는 얘기가 나온다. 이와 같은 유사 사례로 독일이 이민자 정책에 성공했다는 걸 알고 있었던 필자는 이 책에서 어떤 해결책을 제시할지 궁금했다. 여기서는 이민자 정책의 장단점을 따지기에 앞서 왜 인구감소가 문제인지 이민자 정책을 시행한 뒤의 우리나라가 어떤 사회로 뒤바뀔지를 설명했다. 일단 인구가 줄어든다는 것은 인재가 줄어든다는 것으로 이는 국가경쟁력의 약화로 이어진다. 그렇기에 해외 이민자들을 받아들여 우수인재 유치에 힘써야한다는 것이 주된 내용이었다. 그러나 해외 이민자들을 받아들였을 때의 우리 사회 구성원들이 제대로 수용할 수 있을지는 의문이다. 아직까지 외국인에 대한 편견이나 선입견이 존재하기에 이에 대한 교육이 필요하고 이민자들이 우리나라에 왔을 때 잘 자리잡을 수 있도록 해주는 것이 중요하다. 이 책에서는 인구감소의 문제에 대해 국가가 더욱 적극적으로 힘써줘야한다고 주장하고 있는 듯하다. 필자 또한 개개인의 노력만으로는 이 문제를 해결할 수 없다고 생각하기에 국가가 전면적으로 나서야한다고 생각한다. 이처럼 두 번째 목차에서는 STEPPER가 되기위해 우리는 무엇을 신경써줘야하는지 방향을 알려준다.

 

 '선비정신', 우리 선조들이 정파나 개인의 이해관계를 떠나서 오로지 대의와 국가, 백성을 위해 시시비비를 가리고자 하는 한국 고유의 정신. 요즘 우리나라에서는 이런 모습이 거의 보이지 않는 것 같다. 모두가 선비정신을 갖고 대의와 국가를 위해 자신이 맡은 위치에서 힘쓴다면 지금 현재 우리나라의 위기는 충분히 극복할 수 있을 것이라고 생각한다.

 

 2024년 세계의 정세와 우리나라의 상황, 그리고 산업의 동향을 한 권의 책을 통해 대략적으로 파악하고 자신만의 새로운 인사이트를 얻고 싶은 분들에게 이 책을 추천한다. 

'독서 > 과학' 카테고리의 다른 글

K반도체 대전략  (1) 2024.07.08
AI 이후의 세계  (1) 2024.01.19

한글폰트 적용 - 코랩

!sudo apt-get install -y fonts-nanum
!sudo fc-cache -fv
!rm ~/.cache/matplotlib -rf

 

Fixed Random Seed 

seed 값에 의해 동일한 코드를 사용해도 결과가 다를 수 있기에, 동일한 결과를 위해 seed값을 고정시킵니다.

import numpy as np
import random
import os

def seed_everything(seed):
    random.seed(seed)
    os.environ['PYTHONHASHSEED'] = str(seed)
    np.random.seed(seed)

seed_everything(42) # Seed 고정

 

데이터 불러오기 및 확인 

import pandas as pd

train_df = pd.read_csv('/content/sample_data/train.csv')
test_df = pd.read_csv('/content/sample_data/test.csv')

display(train_df.head(3))
display(test_df.head(3))

 

 

EDA

범주형 변수 확인

# 시각화 패키지 불러오기
import seaborn as sns
import matplotlib.pyplot as plt
import matplotlib.font_manager as fm

# 한글 폰트 설정하기
fe = fm.FontEntry(fname = 'MaruBuri-Regular.otf', name = 'MaruBuri')
fm.fontManager.ttflist.insert(0, fe)
plt.rc('font', family='NanumBarunGothic')

fig, axes = plt.subplots(2, 2, figsize=(25,10)) # 2x2 형식으로 4개 그래프 동시에 표시

sns.countplot(x = train_df['대출기간'], ax=axes[0][0]).set_title('대출기간')
sns.countplot(x = train_df['근로기간'], ax=axes[0][1]).set_title('근로기간')
sns.countplot(x = train_df['주택소유상태'], ax=axes[1][0]).set_title('주택소유상태')
sns.countplot(x = train_df['대출목적'], ax=axes[1][1]).set_title('대출목적')

plt.show()

 

근로기간에서 < 1 year이랑 <1 year이 있는걸 확인했습니다.

둘 다 똑같은 의미를 취하는 것이기에 같게 만들어주는 작업이 필요할 듯 합니다.

그런데 근로기간의 데이터를 다시 한번 살펴보니 year에 3이 들어가있는걸 확인했고 10+ year, 1year도 중복이 되기에 마찬가지로 바꿔줍니다.

 

fig, axes = plt.subplots(2, 2, figsize=(25,10)) # 2x2 형식으로 4개 그래프 동시에 표시

sns.countplot(x = train_df['대출기간'], ax=axes[0][0]).set_title('대출기간')
sns.countplot(x = train_df['근로기간'], ax=axes[0][1]).set_title('근로기간')
sns.countplot(x = train_df['주택소유상태'], ax=axes[1][0]).set_title('주택소유상태')
sns.countplot(x = train_df['대출목적'], ax=axes[1][1]).set_title('대출목적')

plt.show()

 

다시 확인해주면 잘 처리된걸 확인할 수 있습니다.

 

세분화된 변수형 찾기

# '범주형 변수 찾기'
numeric_columns = train_df.select_dtypes(include=['number'])
categorical_col_names = train_df.select_dtypes(include=['object']).columns.tolist()

# '범주형 변수 정보 확인하기'
summary = {}
unique_counts = {}
for col in categorical_col_names:
    summary[col] = train_df[col].value_counts().to_dict()
    unique_counts[col] = train_df[col].nunique()

print(unique_counts)

 

범주형 변수의 경우 범주가 너무 세분화되어 있을 경우, One-Hot Encoding시 차원의 저주에 빠지기 쉽습니다. 따라서 너무 세분화된 범주형 변수를 제거해주기로 결정합니다.

따라서 ID를 제거해줍니다.

 

 

EDA: 수치형 변수 확인하기

결측치 확인

numeric_columns_train = train_df.select_dtypes(include=['number'])
numeric_columns_test = test_df.select_dtypes(include=['number'])

null_tot_train = numeric_columns_train.isnull().sum()
null_tot_test = numeric_columns_test.isnull().sum()

print(null_tot_train)
print(null_tot_test)

 

Describe & info

numeric_columns_train.describe()

부채_대비_소득_비율: max가 9999인게 조금 이상합니다.

총계좌수: max가 169인게 이상합니다. 

최근_2년간_연체_횟수: max가 30번인게 이상합니다.

연간소득: 0인데 대출이 가능했는지 의문이 듭니다. 

min_income = train_df['연간소득'].min()
rows_with_min_income = train_df[train_df['연간소득'] == min_income]
rows_with_min_income

부채_대비_소득_비율의 값이 9999인 것과 연간소득 0인데이터가 중복되는걸 확인할 수 있습니다.

 

이 데이터는 모델을 학습시킬 때 좋지 않다고 판단하여 제거하기로 결정했습니다.

수치형 변수 시각화

# 수치형 변수들을 시각화 (예: 히스토그램)
numeric_columns_train.hist(bins=10, figsize=(10, 6))
plt.suptitle('Numeric Variables Distribution')
plt.show()

 

대출금액을 제외하고 대부분의 데이터들이 좌측편향돼있다는 걸 확인할 수 있습니다.

이걸 로그변환시킬지 아니면 이상치의 값들을 제거해야할지 결정을 해줘야할 듯합니다.

그러나 저는 로그변환을 시도한 데이터가 좋지 않은 예측값을 냈기에 이상치의 값들을 일부분 제거하여 모델을 학습시키는게 좋을 듯 합니다. 

데이터 전처리 1: 학습 및 추론 데이터 설정

제출을 위한 코드와 제가 확인할 코드를 나눠서 진행하였습니다.

from sklearn.model_selection import train_test_split

X = train_df.drop(columns=['ID', '근로기간','대출등급'])
y = train_df['대출등급']
train_x = train_df.drop(columns=['ID', '근로기간', '대출등급'])
train_y = train_df['대출등급']

test_x = test_df.drop(columns=['ID', '근로기간'])
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, stratify=y, random_state=42)

데이터 전처리 2: 범주형 변수 수치화

LabelEncoder를 통해 범주형 변수 수치화를 진행합니다.

from sklearn.preprocessing import LabelEncoder

categorical_features = ['대출기간', '주택소유상태', '대출목적']

for i in categorical_features:
    le = LabelEncoder()
    le=le.fit(train_x[i])
    le=le.fit(X[i])

    train_x[i]=le.transform(train_x[i])
    X[i]=le.transform(X[i])

    for case in np.unique(test_x[i]):
        if case not in le.classes_:
            le.classes_ = np.append(le.classes_, case)
    test_x[i]=le.transform(test_x[i])

display(train_x.head(3))
display(test_x.head(3))

 

 

모델 선정 및 학습

RandomForestClassifier

from sklearn.ensemble import RandomForestClassifier

RFC = RandomForestClassifier()
RFC.fit(X_train, y_train)
max_depth_list = range(20,25)
accuracy = []

for m in max_depth_list:
    RFC = RandomForestClassifier(random_state = 42, max_depth = m)
    RFC.fit(X_train, y_train)
    pred = RFC.predict(X_test)
    score = accuracy_score(pred, y_test)
    accuracy.append(score)

plt.plot(max_depth_list, accuracy)
plt.xlabel('max_depth')
plt.ylabel('accuracy')
plt.show()

최적의 깊이를 찾기위한 코드

from sklearn.metrics import accuracy_score

pred = RFC.predict(X_test)
score = accuracy_score(pred, y_test)
print(f"정확도: {score}")

가장 잘 나온 max_depth의 값을 선택하여 예측한 결과 정확도는 0.8231이 나왔습니다.

 

DecisionTreeClassifier

DT = DecisionTreeClassifier(random_state = 42, criterion = 'entropy', max_depth = 5)
DT.fit(X_train, y_train)
max_depth_list = range(1,101)
accuracy = []

for m in max_depth_list:
    DT = DecisionTreeClassifier(random_state = 42, criterion = 'entropy', max_depth = m)
    DT.fit(X_train, y_train)
    pred = DT.predict(X_test)
    score = accuracy_score(pred, y_test)
    accuracy.append(score)

plt.plot(max_depth_list, accuracy)
plt.xlabel('max_depth')
plt.ylabel('accuracy')
plt.show()

가장 최적의 max_depth

DT = DecisionTreeClassifier(random_state = 42, criterion = 'entropy', max_depth = 19)
DT.fit(train_x, train_y)

 

가장 잘 나온 max_depth로 학습시켜줍니다.

 

KNeighborsClassifier

n_neighbors_list = range(1,10)
accuracy = []

for m in n_neighbors_list:
    KNN = KNeighborsClassifier(n_neighbors = m)
    KNN.fit(X_train, y_train)
    pred = KNN.predict(X_test)
    score = accuracy_score(pred, y_test)
    accuracy.append(score)

plt.plot(n_neighbors_list, accuracy)
plt.xlabel('n_neighors')
plt.ylabel('accuracy')
plt.show()

정확도가 앞서 실행한 두 모델에 비해 현저하게 낮기에 이 모델은 채택안하기로 결정합니다.

 

그래서 예측을 수행하여 데이콘 대회에 제출한 결과

0.79의 정확도를 얻었습니다.

처음으로 대회에 참여하여서 이정도면 나쁘지 않은 결과라고 생각합니다. 

앞으로 더욱 정진하겠습니다!

'프로그래밍 > 프로젝트' 카테고리의 다른 글

ARIMA 모델 검증 및 예측 정확도 평가  (0) 2024.05.21
ARIMA 모델  (0) 2024.05.21
고객 유지를 위한 필요한 행동 예측  (1) 2024.01.14
원본 데이터 보존  (0) 2023.11.28
머신러닝 기초 및 순서  (0) 2023.11.21

문제

어떤 숫자 n이 자신을 제외한 모든 약수들의 합과 같으면, 그 수를 완전수라고 한다.

예를 들어 6은 6 = 1 + 2 + 3 으로 완전수이다.

n이 완전수인지 아닌지 판단해주는 프로그램을 작성하라.

입력

입력은 테스트 케이스마다 한 줄 간격으로 n이 주어진다. (2 < n < 100,000)

입력의 마지막엔 -1이 주어진다.

출력

테스트케이스 마다 한줄에 하나씩 출력해야 한다.

n이 완전수라면, n을 n이 아닌 약수들의 합으로 나타내어 출력한다(예제 출력 참고).

이때, 약수들은 오름차순으로 나열해야 한다.

n이 완전수가 아니라면 n is NOT perfect. 를 출력한다.

예제 입력 1 복사

6
12
28
-1

예제 출력 1 복사

6 = 1 + 2 + 3
12 is NOT perfect.
28 = 1 + 2 + 4 + 7 + 14

 

 

내가 한 틀린 코드

nl = []
ll = []

while True:
    n = int(input())

    if n == -1:
        break
        
    l = []
    
    for i in range(1,n+1):
        if n % i == 0:
            l.append(i)

    l.remove(l[-1])
    ll.append(l)
    nl.append(n)

for j in range(len(ll)):
    if nl[j] == sum(ll[j]):
        print(f"{nl[j]} = ", end = "")

        for k in ll[j]:
            if k == 1:
                print(f"{k}", end = "")

            else:
                print(f" + {k}", end = "")
    else:
        print()
        print(f"{nl[j]} is NOT perfect.")

 

이 코드는 정답이랑 똑같은 형식으로 출력되기는 하는데

출력되는 형식이 이렇게 되면 안되기 떄문에 틀린 문제이다.

한 줄에 하나씩 출력되도록 해야하는데 그렇게 하지 않았기에 틀린문제

 

그럼 어떻게 해야하나?

옛날에 썼던 적이 있는 것 같은데 요즘 안써서 까먹은 join을 써야한다.

join을 통해 반복문 사이에 있는 인자들을 +로 연결해준다는 생각을 해주면 이렇게 길게 코드를 쓰지 않아도 된다.

 

정답 코드

nl = []
ll = []

while True:
    n = int(input())

    if n == -1:
        break
        
    l = []
    
    for i in range(1,n+1):
        if n % i == 0:
            l.append(i)

    l.remove(l[-1])
    ll.append(l)
    nl.append(n)

for j in range(len(ll)):
    if nl[j] == sum(ll[j]):
        temp = ' + '.join(str(i) for i in ll[j])
        print(f"{nl[j]} = {temp}")

    else:
        print(f"{nl[j]} is NOT perfect.")

'알고리즘' 카테고리의 다른 글

백준 파이썬 - 2869  (0) 2024.02.02
백준 파이썬 - 2292  (0) 2024.01.30
백준 파이썬 - 2903  (1) 2024.01.30
백준 파이썬 - 2720  (1) 2024.01.29
백준 파이썬 - 2745  (1) 2024.01.29

문제

땅 위에 달팽이가 있다. 이 달팽이는 높이가 V미터인 나무 막대를 올라갈 것이다.

달팽이는 낮에 A미터 올라갈 수 있다. 하지만, 밤에 잠을 자는 동안 B미터 미끄러진다. 또, 정상에 올라간 후에는 미끄러지지 않는다.

달팽이가 나무 막대를 모두 올라가려면, 며칠이 걸리는지 구하는 프로그램을 작성하시오.

입력

첫째 줄에 세 정수 A, B, V가 공백으로 구분되어서 주어진다. (1 ≤ B < A ≤ V ≤ 1,000,000,000)

출력

첫째 줄에 달팽이가 나무 막대를 모두 올라가는데 며칠이 걸리는지 출력한다.

예제 입력 1 복사

2 1 5

예제 출력 1 복사

4

예제 입력 2 복사

5 1 6

예제 출력 2 복사

2

예제 입력 3 복사

100 99 1000000000

예제 출력 3 복사

999999901

 

 

 

내가 실패한 답들 

A,B,V = map(int, input().split())

now = 0
day = 0

while True:
    now += A
    day += 1
    if now >= V:
        break
    else:
        now -= B

print(day)

 

A,B,V = map(int, input().split())
tot = A-B

now = 0
day = 0

while True:
    now += tot
    day += 1
    if V == now + A or V <= now + A:
        day += 1
        break
        
print(day)

 

출력은 되는데 모두 시간초과로 인해 실패하였다.

 

그래서 알고리즘 분류가 수학으로 돼있어서

x를 다 올라가는 횟수라하고 x-1을 내려가는 횟수라고 해서

식을 세우니 아래와 같은 결과가 나왔다.

 

Ax - B(x - 1) = V

Ax - Bx + B = V

(A - B)x = V - B

X = (V - B)/(A - B)

 

그래서 이걸 바탕으로 코드를 만들었다.

import math

A, B, V = map(int, input().split())
day = (V-B) / (A-B)
print(math.ceil(day))

 

ceil을 한 이유는 올림을 해줘야 우리가 원하는 답이 나오기 때문이다.

예를 들어 day의 값이 5.6이 나오면 5가 답이 아닌 6이 답이 나와야 하기 때문이다. 

 

앞으로 실행시간도 신경써서 코드를 만들어야겠다는 생각을 하게 되는 문제였다. 

'알고리즘' 카테고리의 다른 글

백준 파이썬 - 9506  (1) 2024.02.02
백준 파이썬 - 2292  (0) 2024.01.30
백준 파이썬 - 2903  (1) 2024.01.30
백준 파이썬 - 2720  (1) 2024.01.29
백준 파이썬 - 2745  (1) 2024.01.29

벌집

문제

위의 그림과 같이 육각형으로 이루어진 벌집이 있다. 그림에서 보는 바와 같이 중앙의 방 1부터 시작해서 이웃하는 방에 돌아가면서 1씩 증가하는 번호를 주소로 매길 수 있다. 숫자 N이 주어졌을 때, 벌집의 중앙 1에서 N번 방까지 최소 개수의 방을 지나서 갈 때 몇 개의 방을 지나가는지(시작과 끝을 포함하여)를 계산하는 프로그램을 작성하시오. 예를 들면, 13까지는 3개, 58까지는 5개를 지난다.

입력

첫째 줄에 N(1 ≤ N ≤ 1,000,000,000)이 주어진다.

출력

입력으로 주어진 방까지 최소 개수의 방을 지나서 갈 때 몇 개의 방을 지나는지 출력한다.

예제 입력 1 복사

13

예제 출력 1 복사

3

 

 

정답코드

N = int(input())
first_interval = 1
answer = 1

while True:
    if N == 1:
        print(answer)
        break
    else:
        last_interval = first_interval + 6 * answer
        if N in range(first_interval, last_interval + 1):
            answer += 1
            print(answer)
            break
        else:
            answer += 1
            first_interval = last_interval

 

최소 개수의 방을 지나야한다.

그래서 나는 벌집 모양의 수들이 어떤 관계를 이루고 있는지 확인하였다. 

확인한 결과 1 밑에 2번 그리고 시계 방향으로 수가 증가한다. 

7에서 8로 넘어갈 때 회전하는 층이 바뀐다. 그림으로 설명하면 이렇다. 

1 - 7 - 19 - 37 - ... 이런 식으로 간격이 6 X 1, 6 X 2, 6 X 3 ... 이렇게 증가하는 걸 확인할 수 있다. 

그래서 구간을 1 ~ 7, 7 ~ 19, 19 ~ 37... 이런 식으로 잡을 수 있도록 변수를 설정해주었다. 

 

코드 설명

1.

N = int(input())
first_interval = 1
answer = 1

 

N에는 구하려는 숫자를 입력한다.

그리고 처음에 있는 숫자방인 1을 first_interval로 잡아준다.

숫자방 1에 있을 때도 방을 거친 것이 되기 때문에 초기값을 answer = 1로 잡아준다. 

 

2.

while True:
    if N == 1:
        print(answer)
        break
    else:
        last_interval = first_interval + 6 * answer
        if N in range(first_interval, last_interval + 1):
            answer += 1
            print(answer)
            break
        else:
            answer += 1
            first_interval = last_interval

 

N이 만약에 1이라면 그냥 출력할 수 있도록 한다.

그게 아니면 last_interval을 설정하여 거치는 방의 횟수를 구할 수 있도록 한다.

예를 들면 1 ~ 7의 범위 안에 숫자가 있는지 확인하고 있다면 방을 한번 더 거친 것이기 때문에 

answer에 1을 더할 수 있도록 한다.

그러고 난 다음에 print(answer)을 한다. 

 

1 ~ 7의 범위 안에 없다면 다음 범위로 넘어가야 하기 때문에 else 을 통해 다음 범위로 넘어갈 수 있도록 한다. 

'알고리즘' 카테고리의 다른 글

백준 파이썬 - 9506  (1) 2024.02.02
백준 파이썬 - 2869  (0) 2024.02.02
백준 파이썬 - 2903  (1) 2024.01.30
백준 파이썬 - 2720  (1) 2024.01.29
백준 파이썬 - 2745  (1) 2024.01.29

문제

상근이는 친구들과 함께 SF영화를 찍으려고 한다. 이 영화는 외계 지형이 필요하다. 실제로 우주선을 타고 외계 행성에 가서 촬영을 할 수 없기 때문에, 컴퓨터 그래픽으로 CG처리를 하려고 한다.

외계 지형은 중앙 이동 알고리즘을 이용해서 만들려고 한다.

알고리즘을 시작하면서 상근이는 정사각형을 이루는 점 4개를 고른다. 그 후에는 다음과 같은 과정을 거쳐서 지형을 만든다.

  1. 정사각형의 각 변의 중앙에 점을 하나 추가한다.
  2. 정사각형의 중심에 점을 하나 추가한다.

초기 상태에서 위와 같은 과정을 한 번 거치면 총 4개의 정사각형이 새로 생긴다. 이와 같은 과정을 상근이가 만족할 때 까지 계속한다.

상근이는 어떤 점은 한 개 보다 많은 정사각형에 포함될 수 있다는 사실을 알았다. 메모리 소모량을 줄이기 위해서 중복하는 점을 한 번만 저장하려고 한다. 과정을 N번 거친 후 점 몇 개를 저장해야 하는지 구하는 프로그램을 작성하시오.

입력

첫째 줄에 N이 주어진다. (1 ≤ N ≤ 15)

출력

첫째 줄에 과정을 N번 거친 후 점의 수를 출력한다.

 

 

정답 코드 

N = int(input())
init = 2

for i in range(N):
    init = init + 2 ** i

res = init ** 2
print(res)

 

규칙을 잘 찾으면 바로 답이 나오는 문제 

'알고리즘' 카테고리의 다른 글

백준 파이썬 - 2869  (0) 2024.02.02
백준 파이썬 - 2292  (0) 2024.01.30
백준 파이썬 - 2720  (1) 2024.01.29
백준 파이썬 - 2745  (1) 2024.01.29
백준 파이썬 - 2563  (0) 2024.01.24

1. Fake it till you make it.

2. Big shoes to fill!

3. What do you miss most about England when in America?

4. Is there anything New York has over London?

5. Camaraderie(동료애)

6. What do you look for in a script these days?

7. Because I'll just pick them apart!

8. How many times has your husband seen the film?

9. And I would like one to work directly with you.

10. I'm not great with older people.

11. You know how I'm with my parents.

12. Why do I have to have one?

13. Because you have to set the tone!

14. It was so above and beyond! 

15. I am indebted to you forever.

16. You seem like you're more with it.

17. I guess I just need a little downtime.

'일상 > 영어' 카테고리의 다른 글

24.08.27  (2) 2024.08.28
24.08.22  (0) 2024.08.28
24.01.27  (0) 2024.01.27

문제

미국으로 유학간 동혁이는 세탁소를 운영하고 있다. 동혁이는 최근에 아르바이트로 고등학생 리암을 채용했다.

동혁이는 리암에게 실망했다.

리암은 거스름돈을 주는 것을 자꾸 실수한다.

심지어 $0.5달러를 줘야하는 경우에 거스름돈으로 $5달러를 주는것이다!

어쩔수 없이 뛰어난 코딩 실력을 발휘해 리암을 도와주는 프로그램을 작성하려고 하지만, 디아블로를 하느라 코딩할 시간이 없어서 이 문제를 읽고 있는 여러분이 대신 해주어야 한다.

거스름돈의 액수가 주어지면 리암이 줘야할 쿼터(Quarter, $0.25)의 개수, 다임(Dime, $0.10)의 개수, 니켈(Nickel, $0.05)의 개수, 페니(Penny, $0.01)의 개수를 구하는 프로그램을 작성하시오. 거스름돈은 항상 $5.00 이하이고, 손님이 받는 동전의 개수를 최소로 하려고 한다. 예를 들어, $1.24를 거슬러 주어야 한다면, 손님은 4쿼터, 2다임, 0니켈, 4페니를 받게 된다.

입력

첫째 줄에 테스트 케이스의 개수 T가 주어진다. 각 테스트 케이스는 거스름돈 C를 나타내는 정수 하나로 이루어져 있다. C의 단위는 센트이다. (1달러 = 100센트) (1<=C<=500)

출력

각 테스트케이스에 대해 필요한 쿼터의 개수, 다임의 개수, 니켈의 개수, 페니의 개수를 공백으로 구분하여 출력한다.

예제 입력 1 복사

3
124
25
194

예제 출력 1 복사

4 2 0 4
1 0 0 0
7 1 1 4

 

 

내가 만든  정답 코드

T = int(input())
Q = 25
D = 10
N = 5
P = 1

Q_list = []
D_list = []
N_list = []
P_list = []

for i in range(T):
    C = int(input())
    Quarter = C // Q
    Dime = (C - Quarter * Q) // D
    Nickel = (C - Quarter * Q - Dime * D) // N
    Penny = (C - Quarter * Q - Dime * D - Nickel * N) // P
    Q_list.append(Quarter)
    D_list.append(Dime)
    N_list.append(Nickel)
    P_list.append(Penny)

for i in range(T):
    print(f"{Q_list[i]} {D_list[i]} {N_list[i]} {P_list[i]}")

 

 

다른 사람들의 코드 

n = int(input())

for _ in range(n):
	money = int(input())
	for i in [25, 10, 5, 1]:
		print(money//i, end=' ')
		money = money%i

 

 

다른 사람들이 쓴 코드는 내가 일일이 복잡하게 모든 걸 쓴 코드에 비해 훨씬 간결하다.

여기서 보면 나는 25,10,5,1을 처음에 변수를 통해 설정해준 반면에 여기서는 리스트를 통해 반복문을 돌게 하여 나누도록 하였다. 내가 124에서 100을 빼고 20을 빼고 하는 식으로 코드를 짰는데 굳이 이렇게 안하고 124를 25로 나누고 10으로 나누고 각각 한 몫을 구해서 출력하도록 했으면 더 좋았을 것 같다. 

 

 

사람들 말로는 이 문제가 전형적인 그리드 문제라고 한다. 

그리드가 뭔지 몰라서 나는 찾아봤다. 

 

그리디 알고리즘(욕심쟁이 알고리즘, Greedy Algorithm)이란 "매 선택에서 지금 이 순간 당장 최적인 답을 선택하여 적합한 결과를 도출하자"라는 모토를 가지는 알고리즘 설계 기법이다.[1]

 

그리디 알고리즘 - 나무위키

그리디 알고리즘(욕심쟁이 알고리즘, Greedy Algorithm)이란 "매 선택에서 지금 이 순간 당장 최적인 답을 선택하여 적합한 결과를 도출하자"라는 모토를 가지는 알고리즘 설계 기법이다.[1] 예를 들

namu.wiki

 

이거 보면서 생각난게 머신러닝의 가지치기 기법인데 혹시 연관이 있나 싶다. 

'알고리즘' 카테고리의 다른 글

백준 파이썬 - 2292  (0) 2024.01.30
백준 파이썬 - 2903  (1) 2024.01.30
백준 파이썬 - 2745  (1) 2024.01.29
백준 파이썬 - 2563  (0) 2024.01.24
백준 파이썬 - 10798  (0) 2024.01.19

+ Recent posts