├── iOS ├── Swift.md ├── 02_storyboard.md └── 01_xcode_fundamental.md ├── .gitignore ├── Python ├── Django │ ├── source │ │ └── django_girls_blog_tutorial │ │ │ ├── blog │ │ │ ├── __init__.py │ │ │ ├── migrations │ │ │ │ ├── __init__.py │ │ │ │ ├── 0002_post_nothing.py │ │ │ │ └── 0001_initial.py │ │ │ ├── tests.py │ │ │ ├── apps.py │ │ │ ├── admin.py │ │ │ ├── forms.py │ │ │ ├── templates │ │ │ │ └── blog │ │ │ │ │ ├── post_edit.html │ │ │ │ │ ├── post_list.html │ │ │ │ │ ├── post_detail.html │ │ │ │ │ └── base.html │ │ │ ├── urls.py │ │ │ ├── models.py │ │ │ ├── static │ │ │ │ └── css │ │ │ │ │ └── blog.css │ │ │ └── views.py │ │ │ ├── mysite │ │ │ ├── __init__.py │ │ │ ├── wsgi.py │ │ │ └── urls.py │ │ │ ├── README.md │ │ │ ├── db.sqlite3 │ │ │ ├── static │ │ │ └── admin │ │ │ │ ├── fonts │ │ │ │ ├── README.txt │ │ │ │ ├── Roboto-Bold-webfont.woff │ │ │ │ ├── Roboto-Light-webfont.woff │ │ │ │ └── Roboto-Regular-webfont.woff │ │ │ │ ├── img │ │ │ │ ├── tooltag-arrowright.svg │ │ │ │ ├── README.txt │ │ │ │ ├── tooltag-add.svg │ │ │ │ ├── icon-addlink.svg │ │ │ │ ├── icon-changelink.svg │ │ │ │ ├── icon-deletelink.svg │ │ │ │ ├── icon-yes.svg │ │ │ │ ├── search.svg │ │ │ │ ├── icon-alert.svg │ │ │ │ ├── icon-no.svg │ │ │ │ ├── inline-delete.svg │ │ │ │ ├── icon-unknown.svg │ │ │ │ ├── icon-unknown-alt.svg │ │ │ │ ├── icon-clock.svg │ │ │ │ ├── gis │ │ │ │ │ ├── move_vertex_off.svg │ │ │ │ │ └── move_vertex_on.svg │ │ │ │ ├── icon-calendar.svg │ │ │ │ ├── calendar-icons.svg │ │ │ │ ├── LICENSE │ │ │ │ └── sorting-icons.svg │ │ │ │ ├── js │ │ │ │ ├── prepopulate.min.js │ │ │ │ ├── jquery.init.js │ │ │ │ ├── collapse.min.js │ │ │ │ ├── vendor │ │ │ │ │ ├── xregexp │ │ │ │ │ │ └── LICENSE-XREGEXP.txt │ │ │ │ │ └── jquery │ │ │ │ │ │ └── LICENSE-JQUERY.txt │ │ │ │ ├── collapse.js │ │ │ │ └── prepopulate.js │ │ │ │ └── css │ │ │ │ ├── fonts.css │ │ │ │ ├── dashboard.css │ │ │ │ └── login.css │ │ │ └── manage.py │ └── 010_image_file.md ├── codewars │ ├── 046_recursive_reverse_string.md │ ├── 057_find_employee_role.md │ ├── 054_build_a_pile_of_cubes.md │ ├── 028_where_my_anagrams_at.md │ ├── 041_least_common_multiple.md │ ├── 058_multiplication_tables.md │ ├── 061_linkedlist_01.md │ ├── 056_playing_with_digits.md │ ├── 010_narcissistic_number.md │ ├── 007_vowel_count.md │ ├── 055_double_cola.md │ ├── 002_square_digits.md │ ├── 052_function_iteration.md │ ├── 014_feynman_square_question.md │ ├── 015_lambda_open_closed_principle.md │ ├── 063_linkedlist_03.md │ ├── 040_common_denominators.md │ ├── 059_take_a_ten_minute_walk.md │ ├── 021_trailing_zeros.md │ ├── 004_what_dominates_your_array.md │ ├── 013_digital_root.md │ ├── 006_you_are_a_square.md │ ├── 039_rgb_to_hex_conversion.md │ ├── 053_regex_validate_pin_code.md │ ├── 038_convert_camel_snake.md │ ├── 064_linkedlist_04.md │ ├── 051_pete_the_baker.md │ ├── 008_sequence_sum.md │ ├── 026_counting_duplicates.md │ ├── 020_camel_case.md │ ├── 049_WeIrD_StRiNg_CaSe.md │ ├── 017_sum_of_many_ints.md │ ├── 050_format_a_string_of_names.md │ ├── 016_castle_grayskull.md │ ├── 045_explosive_sum.md │ ├── 044_strip_url_params.md │ ├── 001_filter_the_number.md │ ├── 024_nesting_structure_comparison.md │ ├── 009_linked_lists-get_nth_node.md │ ├── 012_title_case.md │ ├── 048_pagination_helper.md │ ├── 034_find_the_parity_outlier.md │ ├── 060_dont_eat_the_last_cake.md │ ├── 018_order_weight.md │ ├── 037_metric_units_1.md │ ├── 042_get_perfect_power.md │ ├── 062_linkedlist_02.md │ ├── 047_evil_autocorrect_prank.md │ └── 005_find_the_longest_gap.md ├── spyder.md ├── argparse.md ├── crawling │ └── web_crawling.md └── tkinter_gui.md ├── Data_science └── README.md ├── Ruby_on_Rails ├── Coderbyte │ ├── easy │ │ ├── first_reverse.rb │ │ ├── simple_adding.rb │ │ ├── word_count.rb │ │ ├── vowel_count.rb │ │ ├── time_convert.rb │ │ ├── alpahbet_soup.rb │ │ ├── ex_oh.rb │ │ ├── first_factorial.rb │ │ ├── palindrome.rb │ │ ├── check_nums.rb │ │ ├── letter_capitalize.rb │ │ ├── longest_word.rb │ │ ├── array_addition_I.rb │ │ ├── ab_check.rb │ │ ├── letter_changes.rb │ │ ├── arith_geo.rb │ │ ├── second_great_low.rb │ │ └── letter_count.rb │ ├── .DS_Store │ ├── README.md │ ├── medium │ │ ├── prime_time.rb │ │ ├── binary_converter.rb │ │ ├── arith_geo_II.rb │ │ └── prime_mover.md │ └── LICENSE.md ├── ProjectEuler │ ├── README.md │ ├── source │ │ ├── P001_ThreeFive.rb │ │ ├── P003_PrimeFactor.rb │ │ └── P002_Fibonacci.rb │ └── LICENSE.md ├── standard_controller_actions.md └── request-response_cycle.md ├── C ├── algorithm │ ├── README.md │ ├── 011_num_cnt.md │ ├── 002_str_rev.md │ ├── 012_word_cnt.md │ ├── 015_fraction.md │ ├── 008_palindrome.md │ ├── 010_ox_quiz.md │ ├── 003_atoi.md │ ├── 013_han_num.md │ ├── 014_str_repeat.md │ └── 005_n_queen.md └── list.md ├── Data_structure └── README.md ├── config.ru ├── Home.md ├── JavaScript ├── requirejs.md ├── codewars │ ├── 006_sort_object.md │ ├── 020_find_the_mine.md │ ├── 005_descending_order.md │ ├── 032_the_coupon_code.md │ ├── 023_bit_calculator.md │ ├── 014_largest_5digit_number.md │ ├── 021_unique_in_order.md │ ├── 028_squares_sequence.md │ ├── 012_your_order_please.md │ ├── 018_convert_hex_to_rgb.md │ ├── 019_array_helpers.md │ ├── 026_regex_count_lowercase_letters.md │ ├── 002_sort_with_arrow_function.md │ ├── 029_sum_all_the_arrays.md │ ├── 004_insert_dashes.md │ ├── 031_object_extend.md │ ├── 007_search_for_letters.md │ ├── 022_luck_check.md │ ├── 009_replace_with_alphabet_position.md │ ├── 027_rotate_for_a_max.md │ ├── 016_rot13.md │ ├── 001_monotone_travel.md │ ├── 030_math_issues.md │ ├── 010_decode_the_morse_code.md │ ├── 003_vampire_number.md │ ├── 015_guess_the_gifts.md │ ├── 011_good_vs_evil.md │ └── 017_human_readable_time.md ├── leafletjs.md ├── es6_map_set.md ├── promise.md ├── apply_bind_call.md ├── React │ └── weather_ajax_tutorial.md ├── ajax_getstarted.md ├── Meteor │ └── rocketchat_streamer.md └── canvas_svg │ └── canvas_svg_s65_3.md ├── Algorithm ├── exercises │ ├── gcd.md │ ├── Reverse_str_recursion.md │ ├── the_sieve_of_Eratosthenes.md │ ├── permutation.md │ ├── recursive_power.md │ ├── minimum_classroom.md │ └── parenthesis.md ├── greedy_algorithm.md ├── Dijkstra.md ├── dynamic_programming.md └── binary_search.md ├── Java └── design_pattern │ └── strategy_pattern.md ├── Server ├── heroku.md └── nginx.md ├── README.md ├── LICENSE ├── Go └── go_fundamental.md ├── HTML-CSS └── purecss_fundamental.md └── ETC ├── oh_my_zsh.md ├── crawling_facebook_replies.md └── tmux.md /iOS/Swift.md: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | restart.txt 3 | .ipynb_checkpoints 4 | -------------------------------------------------------------------------------- /Python/Django/source/django_girls_blog_tutorial/blog/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /Python/Django/source/django_girls_blog_tutorial/mysite/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /Python/Django/source/django_girls_blog_tutorial/blog/migrations/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /Data_science/README.md: -------------------------------------------------------------------------------- 1 | Moved to [TIL-DataScience](https://github.com/Gyubin/TIL-DataScience) 2 | -------------------------------------------------------------------------------- /Python/Django/source/django_girls_blog_tutorial/README.md: -------------------------------------------------------------------------------- 1 | # foodgram 2 | Only food photos in Instagram. 3 | -------------------------------------------------------------------------------- /Ruby_on_Rails/Coderbyte/easy/first_reverse.rb: -------------------------------------------------------------------------------- 1 | def FirstReverse(str) 2 | return str.reverse 3 | end 4 | -------------------------------------------------------------------------------- /Ruby_on_Rails/Coderbyte/easy/simple_adding.rb: -------------------------------------------------------------------------------- 1 | def SimpleAdding(num) 2 | return num*(num+1)/2 3 | end 4 | -------------------------------------------------------------------------------- /C/algorithm/README.md: -------------------------------------------------------------------------------- 1 | # C로 알고리즘 문제 풀기 2 | 3 | - 001-008: 42 school에서 풀었던 문제들 중 괜찮았던 것 4 | - 009-: 백준 온라인 저지 5 | -------------------------------------------------------------------------------- /Ruby_on_Rails/Coderbyte/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gyubin/TIL/HEAD/Ruby_on_Rails/Coderbyte/.DS_Store -------------------------------------------------------------------------------- /Ruby_on_Rails/Coderbyte/easy/word_count.rb: -------------------------------------------------------------------------------- 1 | def WordCount(str) 2 | return str.split(' ').count 3 | end 4 | -------------------------------------------------------------------------------- /Ruby_on_Rails/Coderbyte/easy/vowel_count.rb: -------------------------------------------------------------------------------- 1 | def VowelCount(str) 2 | return str.scan(/[AEIOUaeiou]/).count 3 | end 4 | -------------------------------------------------------------------------------- /Data_structure/README.md: -------------------------------------------------------------------------------- 1 | # Data structure 2 | 3 | Moved to this repository. 4 | 5 | https://github.com/Gyubin/Data-Structure 6 | -------------------------------------------------------------------------------- /Python/Django/source/django_girls_blog_tutorial/blog/tests.py: -------------------------------------------------------------------------------- 1 | from django.test import TestCase 2 | 3 | # Create your tests here. 4 | -------------------------------------------------------------------------------- /Ruby_on_Rails/Coderbyte/README.md: -------------------------------------------------------------------------------- 1 | # Coder byte by ruby 2 | Solve the coderbyte problem by ruby.
3 | go -> [coderbyte site](http://www.coderbyte.com/) 4 | -------------------------------------------------------------------------------- /Python/Django/source/django_girls_blog_tutorial/blog/apps.py: -------------------------------------------------------------------------------- 1 | from django.apps import AppConfig 2 | 3 | 4 | class BlogConfig(AppConfig): 5 | name = 'blog' 6 | -------------------------------------------------------------------------------- /Python/Django/source/django_girls_blog_tutorial/db.sqlite3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gyubin/TIL/HEAD/Python/Django/source/django_girls_blog_tutorial/db.sqlite3 -------------------------------------------------------------------------------- /Ruby_on_Rails/ProjectEuler/README.md: -------------------------------------------------------------------------------- 1 | # Project Euler by ruby. 2 | Solve the project euler quiz.
3 | go => [Project Euler Korea](http://euler.synap.co.kr) 4 | -------------------------------------------------------------------------------- /config.ru: -------------------------------------------------------------------------------- 1 | require "gollum/app" 2 | 3 | Precious::App.set(:gollum_path, File.dirname(__FILE__)) 4 | Precious::App.set(:wiki_options, {}) 5 | run Precious::App 6 | 7 | -------------------------------------------------------------------------------- /Ruby_on_Rails/Coderbyte/easy/time_convert.rb: -------------------------------------------------------------------------------- 1 | def TimeConvert(num) 2 | hours = num / 60 3 | minutes = num - hours*60 4 | return hours.to_s + ':' + minutes.to_s 5 | end 6 | -------------------------------------------------------------------------------- /Ruby_on_Rails/Coderbyte/easy/alpahbet_soup.rb: -------------------------------------------------------------------------------- 1 | def AlphabetSoup(str) 2 | str_array = str.split(//).sort 3 | return str_array.join 4 | #return str.chars.sort.join 5 | end 6 | -------------------------------------------------------------------------------- /Python/Django/source/django_girls_blog_tutorial/blog/admin.py: -------------------------------------------------------------------------------- 1 | from django.contrib import admin 2 | from .models import Post 3 | 4 | # Register your models here. 5 | admin.site.register(Post) 6 | -------------------------------------------------------------------------------- /Ruby_on_Rails/Coderbyte/easy/ex_oh.rb: -------------------------------------------------------------------------------- 1 | def ExOh(str) 2 | if str.scan(/x/).count == str.scan(/o/).count 3 | return 'true' 4 | else 5 | return 'false' 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /Ruby_on_Rails/Coderbyte/easy/first_factorial.rb: -------------------------------------------------------------------------------- 1 | def FirstFactorial(num) 2 | result = 1 3 | while num>1 4 | result = result*num 5 | num = num -1 6 | end 7 | return result 8 | end 9 | -------------------------------------------------------------------------------- /Python/Django/source/django_girls_blog_tutorial/static/admin/fonts/README.txt: -------------------------------------------------------------------------------- 1 | Roboto webfont source: https://www.google.com/fonts/specimen/Roboto 2 | Weights used in this project: Light (300), Regular (400), Bold (700) 3 | -------------------------------------------------------------------------------- /Ruby_on_Rails/ProjectEuler/source/P001_ThreeFive.rb: -------------------------------------------------------------------------------- 1 | i = 1 2 | sum = 0 3 | 4 | while i < 1000 5 | if i % 3 == 0 || i % 5 == 0 6 | sum += i 7 | end 8 | i += 1 9 | end 10 | 11 | puts sum 12 | -------------------------------------------------------------------------------- /Python/Django/source/django_girls_blog_tutorial/static/admin/fonts/Roboto-Bold-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gyubin/TIL/HEAD/Python/Django/source/django_girls_blog_tutorial/static/admin/fonts/Roboto-Bold-webfont.woff -------------------------------------------------------------------------------- /Ruby_on_Rails/Coderbyte/easy/palindrome.rb: -------------------------------------------------------------------------------- 1 | def Palindrome(str) 2 | str = str.downcase.split(' ').join 3 | if str == str.reverse 4 | return 'true' 5 | else 6 | return 'false' 7 | end 8 | end 9 | -------------------------------------------------------------------------------- /Python/Django/source/django_girls_blog_tutorial/static/admin/fonts/Roboto-Light-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gyubin/TIL/HEAD/Python/Django/source/django_girls_blog_tutorial/static/admin/fonts/Roboto-Light-webfont.woff -------------------------------------------------------------------------------- /Python/Django/source/django_girls_blog_tutorial/static/admin/fonts/Roboto-Regular-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gyubin/TIL/HEAD/Python/Django/source/django_girls_blog_tutorial/static/admin/fonts/Roboto-Regular-webfont.woff -------------------------------------------------------------------------------- /Ruby_on_Rails/Coderbyte/easy/check_nums.rb: -------------------------------------------------------------------------------- 1 | def CheckNums(num1,num2) 2 | if num2 > num1 3 | return 'true' 4 | elsif num1 == num2 5 | return '-1' 6 | else 7 | return 'false' 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /Home.md: -------------------------------------------------------------------------------- 1 | #TIL - Today I Learned. 2 | ================================ 3 | 어제보다 조금 더 많이 알기만 하면 된다. 다른 사람과 비교하지 말고 나와 비교하자. 화이팅. 4 | 5 | -2015.10.14 시작- 6 | ```js 7 | function test() { 8 | console.log("Hello TIL."); 9 | } 10 | ``` 11 | -------------------------------------------------------------------------------- /Python/Django/source/django_girls_blog_tutorial/blog/forms.py: -------------------------------------------------------------------------------- 1 | from django import forms 2 | from .models import Post 3 | 4 | class PostForm(forms.ModelForm): 5 | 6 | class Meta: 7 | model = Post 8 | fields = ('title', 'text',) 9 | -------------------------------------------------------------------------------- /Ruby_on_Rails/Coderbyte/easy/letter_capitalize.rb: -------------------------------------------------------------------------------- 1 | def LetterCapitalize(str) 2 | str_array = str.split 3 | result = "" 4 | str_array.each do |a| 5 | result = result + " " + a.capitalize 6 | end 7 | return result 8 | end 9 | -------------------------------------------------------------------------------- /Ruby_on_Rails/Coderbyte/medium/prime_time.rb: -------------------------------------------------------------------------------- 1 | def PrimeTime(num) 2 | limit = Math.sqrt(num) 3 | 4 | (2...limit).to_a.each do |n| 5 | if num % n == 0 6 | return 'false' 7 | end 8 | end 9 | return 'true' 10 | end 11 | -------------------------------------------------------------------------------- /Ruby_on_Rails/ProjectEuler/source/P003_PrimeFactor.rb: -------------------------------------------------------------------------------- 1 | #not completed yet 2 | def prime(number) 3 | i = 1 4 | while number != 1 5 | i += 1 6 | number /= i until number % i != 0 7 | end 8 | p i 9 | end 10 | 11 | prime(600851475143) 12 | -------------------------------------------------------------------------------- /JavaScript/requirejs.md: -------------------------------------------------------------------------------- 1 | # RequireJS 2 | 3 | Javascript가 쓰이는 프론트엔드, 백엔드 모든 곳에서 점점 규모가 커지고 복잡해지고 있다. 관리 개념에서 모듈화가 필요해졌는데 JavaScript 기본적으로 관련 기능을 제공하지 않는다. 협업할 때도 불편하고, 의존도 파악도 어렵다. ES6에서부터는 기능이 추가되었지만 RequireJS 라이브러리가 유용하게 사용되어왔다. 4 | 5 | ## 1. 설치 6 | 7 | `npm install requirejs` 8 | -------------------------------------------------------------------------------- /Algorithm/exercises/gcd.md: -------------------------------------------------------------------------------- 1 | # GCD, Greatest Common Divisor 2 | 3 | 유클리드 호제법을 이용해 최대 공약수를 재귀용법으로 풀었다. 4 | 5 | 유클리드 호제법이란 A, B가 있을 때 최대공약수는 A를 B로 나누었을 때 나머지와 B의 최대공약수가 같다는 정의다. 6 | 7 | ```py 8 | def gcd(x, y) : 9 | if y == 0: 10 | return x 11 | else: 12 | return gcd(y, x % y) 13 | ``` 14 | -------------------------------------------------------------------------------- /Ruby_on_Rails/Coderbyte/medium/binary_converter.rb: -------------------------------------------------------------------------------- 1 | def BinaryConverter(str) 2 | binary_array = str.split(//) 3 | len = binary_array.length 4 | i = 0 5 | sum = 0 6 | 7 | binary_array.each do |num| 8 | sum += num.to_i * (2**(len-1-i)) 9 | i += 1 10 | end 11 | 12 | return sum.to_s 13 | end 14 | -------------------------------------------------------------------------------- /Python/Django/source/django_girls_blog_tutorial/manage.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | import os 3 | import sys 4 | 5 | if __name__ == "__main__": 6 | os.environ.setdefault("DJANGO_SETTINGS_MODULE", "mysite.settings") 7 | 8 | from django.core.management import execute_from_command_line 9 | 10 | execute_from_command_line(sys.argv) 11 | -------------------------------------------------------------------------------- /Python/Django/source/django_girls_blog_tutorial/static/admin/img/tooltag-arrowright.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /Java/design_pattern/strategy_pattern.md: -------------------------------------------------------------------------------- 1 | # Strategy Pattern 2 | 3 | 참고: 헤드퍼스트 디자인패턴, [hyeonstorage 블로그](http://hyeonstorage.tistory.com/m/post/146) 4 | 5 | ~~(상속과 인터페이스 구현을 파이썬으로 해보려했는데 파이썬은 Duck typing을 하기 때문에 사실상 의미가 없었다. 자바로 수정)~~ 6 | 7 | ## 1. 개념 8 | 9 | - 디자인 원칙: 변하는 부분과, 변하지 않는 부분 분리하기. 10 | - strategy pattern: 변하는 부분을 캡슐화하고, 인터페이스에 위임해서 어떤 행동을 할지 결정한다. 11 | 12 | -------------------------------------------------------------------------------- /Python/Django/source/django_girls_blog_tutorial/blog/templates/blog/post_edit.html: -------------------------------------------------------------------------------- 1 | {% extends 'blog/base.html' %} 2 | 3 | {% block content %} 4 |

New post

5 |
{% csrf_token %} 6 | {{ form.as_p }} 7 | 8 |
9 | {% endblock %} 10 | -------------------------------------------------------------------------------- /Ruby_on_Rails/ProjectEuler/source/P002_Fibonacci.rb: -------------------------------------------------------------------------------- 1 | previous_number = 1 2 | present_number = 2 3 | temp = 0 4 | sum = 0 5 | 6 | while present_number <= 4000000 7 | if present_number % 2 == 0 8 | sum += present_number 9 | end 10 | temp = previous_number + present_number 11 | previous_number = present_number 12 | present_number = temp 13 | end 14 | 15 | puts sum 16 | -------------------------------------------------------------------------------- /JavaScript/codewars/006_sort_object.md: -------------------------------------------------------------------------------- 1 | # #6 Return a sorted list of objects 2 | 3 | 002_sort_with_arrow ~~ 문제와 같은 형태다. object가 원소로 되어있는 리스트를 정렬하는 것. 그런데 여기선 매개변수로 정렬 기준이 될 것을 추가로 넣어줬다. 이 때는 dot notation으로 접근하면 안된다. `[ ]`를 통해야 한다. 다른 해답과 같다. 4 | 5 | ## 1. 내 코드 6 | 7 | ```js 8 | function sortList (sortBy, list) { 9 | return list.sort(function(i, j){return j[sortBy] - i[sortBy]}); 10 | } 11 | ``` 12 | -------------------------------------------------------------------------------- /Python/codewars/046_recursive_reverse_string.md: -------------------------------------------------------------------------------- 1 | # #46 Recursive reverse string 2 | 3 | 재귀 연습하기. 재귀 용법으로 문자열 뒤집기. 4 | 5 | ## 1. 내 코드 6 | 7 | ```py 8 | def reverse(str): 9 | if len(str) == 1: return str 10 | return reverse(str[1:]) + str[0] 11 | ``` 12 | 13 | - 길이가 1이면 그냥 재귀 없이 그냥 문자열을 리턴하는 조건을 걸기 14 | - 첫 번째 글자를 맨 뒤로 보내기 15 | - 문자열을 인덱스 1부터 잘라서 함수의 매개변수로 넣는다. 재귀. 16 | 17 | 다른 코드도 역시 동일한 패턴이다. 18 | -------------------------------------------------------------------------------- /Python/Django/source/django_girls_blog_tutorial/static/admin/img/README.txt: -------------------------------------------------------------------------------- 1 | All icons are taken from Font Awesome (http://fontawesome.io/) project. 2 | The Font Awesome font is licensed under the SIL OFL 1.1: 3 | - http://scripts.sil.org/OFL 4 | 5 | SVG icons source: https://github.com/encharm/Font-Awesome-SVG-PNG 6 | Font-Awesome-SVG-PNG is licensed under the MIT license (see file license 7 | in current folder). 8 | -------------------------------------------------------------------------------- /Python/Django/source/django_girls_blog_tutorial/static/admin/img/tooltag-add.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /Python/Django/source/django_girls_blog_tutorial/static/admin/img/icon-addlink.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /Python/Django/source/django_girls_blog_tutorial/blog/urls.py: -------------------------------------------------------------------------------- 1 | from django.conf.urls import url 2 | from . import views 3 | 4 | urlpatterns = [ 5 | url(r'^$', views.post_list, name='post_list'), 6 | url(r'^post/(?P\d+)/$', views.post_detail, name='post_detail'), 7 | url(r'^post/new$', views.post_new, name='post_new'), 8 | url(r'^post/(?P\d+)/edit/$', views.post_edit, name='post_edit'), 9 | ] 10 | -------------------------------------------------------------------------------- /Python/codewars/057_find_employee_role.md: -------------------------------------------------------------------------------- 1 | # #57 Find an employees role in the company 2 | 3 | dict로 된 직원 정보가 여럿 담긴 리스트를 활용해서 특정 이름의 직원 정보를 찾고, 직책을 리턴하면 된다. 간단하다. 4 | 5 | ## 1. 내 코드 6 | 7 | ```py 8 | def find_employees_role(name): 9 | for i in employees: 10 | if (i['first_name'] + ' ' + i['last_name']) == name: 11 | return i['role'] 12 | return "Does not work here!" 13 | ``` 14 | 15 | 다른 답변들과 같다. 16 | -------------------------------------------------------------------------------- /JavaScript/codewars/020_find_the_mine.md: -------------------------------------------------------------------------------- 1 | # #20 Find the Mine 2 | 3 | array가 들어있는 array, 즉 2차원 배열을 입력받아서 1의 위치를 row, col 값으로 리턴하는 문제다. 4 | 5 | ## 1. 내 코드 6 | 7 | ```js 8 | function mineLocation(field){ 9 | for (var i = 0; i < field.length; i++) { 10 | for (var j = 0; j < field[0].length; j++) { 11 | if (field[i][j] === 1) return [i, j]; 12 | } 13 | } 14 | } 15 | ``` 16 | 17 | for 중첩해서 i, j를 바로 리턴했다. 다른 해답들과 같은 코드. 18 | -------------------------------------------------------------------------------- /Python/Django/source/django_girls_blog_tutorial/static/admin/js/prepopulate.min.js: -------------------------------------------------------------------------------- 1 | (function(c){c.fn.prepopulate=function(e,f,g){return this.each(function(){var a=c(this),b=function(){if(!a.data("_changed")){var b=[];c.each(e,function(a,d){d=c(d);0 2 | 3 | 4 | -------------------------------------------------------------------------------- /Python/codewars/054_build_a_pile_of_cubes.md: -------------------------------------------------------------------------------- 1 | # #54 Build a pile of Cubes 2 | 3 | 어떤 숫자를 입력받아서 1부터 n까지 자연수의 세제곱의 합으로 표현될 수 있는지 알아내는 함수. 있다면 n을, 없으면 -1을 리턴한다. 4 | 5 | ## 1. 내 코드 6 | 7 | ```py 8 | def find_nb(m): 9 | n = 0 10 | while m > 0: 11 | n += 1 12 | m -= n ** 3 13 | return n if m == 0 else -1 14 | ``` 15 | 16 | 단순한 문제와 답이다. 이게 왜 6급인걸까. 1부터 순서대로 m에서 빼 가면서 0을 기점으로 멈춘다. m이 0이면 숫자를 찾아낸거고 아니라면 잘못된 값이므로 -1을 리턴한다. 다른 답도 내 것과 같다. 17 | -------------------------------------------------------------------------------- /Python/Django/source/django_girls_blog_tutorial/static/admin/img/icon-deletelink.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /Python/codewars/028_where_my_anagrams_at.md: -------------------------------------------------------------------------------- 1 | # #28 Where my anagrams at. 2 | 3 | 첫 매개변수로 단어 하나를, 두 번째 매개변수로 여러 단어를 모아둔 리스트를 받는다. 리스트의 단어 중 첫 매개변수의 anagram인 것만 다시 리스트에 담아서 리턴한다. 4 | 5 | ## 1. 내 코드 6 | 7 | ```python 8 | def anagrams(word, words): 9 | return [w for w in words if sorted(w) == sorted(word)] 10 | ``` 11 | 12 | `sorted` 함수를 활용하면 문자열이 정렬되어 리스트가 된다. anagram이 결국 단어 종류와 개수는 똑같으므로 이게 같은지만 확인하면 된다. 문제가 쉬워서 그런지 다들 답변이 비슷했고 내 것과 일치했다. 13 | 14 | 오히려 모든 애너그램 단어들을 다 찾아서 리스트로 리턴하는 문제가 더 어려울 것 같다. 15 | -------------------------------------------------------------------------------- /Python/Django/source/django_girls_blog_tutorial/static/admin/img/icon-yes.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /Python/Django/source/django_girls_blog_tutorial/mysite/wsgi.py: -------------------------------------------------------------------------------- 1 | """ 2 | WSGI config for mysite project. 3 | 4 | It exposes the WSGI callable as a module-level variable named ``application``. 5 | 6 | For more information on this file, see 7 | https://docs.djangoproject.com/en/1.9/howto/deployment/wsgi/ 8 | """ 9 | 10 | import os 11 | 12 | from django.core.wsgi import get_wsgi_application 13 | 14 | os.environ.setdefault("DJANGO_SETTINGS_MODULE", "mysite.settings") 15 | 16 | application = get_wsgi_application() 17 | -------------------------------------------------------------------------------- /Python/Django/source/django_girls_blog_tutorial/blog/templates/blog/post_list.html: -------------------------------------------------------------------------------- 1 | {% extends 'blog/base.html' %} 2 | 3 | {% block content %} 4 | {% for post in posts %} 5 |
6 |
7 | {{ post.published_date }} 8 |
9 |

{{ post.title }}

10 |

{{ post.text|linebreaks }}

11 |
12 | {% endfor %} 13 | {% endblock content %} 14 | -------------------------------------------------------------------------------- /Ruby_on_Rails/Coderbyte/easy/longest_word.rb: -------------------------------------------------------------------------------- 1 | def LongestWord(sen) 2 | i = 0 3 | sen.each_byte do |c| 4 | if !(c >= 65 && c <= 90) && !(c >= 97 && c <= 122) 5 | sen[i] = ' ' 6 | end 7 | i += 1 8 | end 9 | 10 | split_array = sen.split(' ') 11 | longest_word = "" 12 | temp_count = 0 13 | 14 | split_array.each do |a| 15 | if a.length > longest_word.length 16 | longest_word = a 17 | end 18 | end 19 | return longest_word 20 | end 21 | -------------------------------------------------------------------------------- /Python/Django/source/django_girls_blog_tutorial/static/admin/img/search.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /Ruby_on_Rails/Coderbyte/easy/array_addition_I.rb: -------------------------------------------------------------------------------- 1 | def ArrayAdditionI(arr) 2 | max_num = arr.max 3 | puts(max_num) 4 | arr.delete(max_num) 5 | puts(arr.length) 6 | 7 | (2..arr.length).to_a.each do |n| 8 | arr.combination(n).to_a.each do |array| 9 | sum = 0 10 | array.each do |num| 11 | sum += num 12 | end 13 | if sum == max_num 14 | return 'true' 15 | end 16 | end 17 | end 18 | return 'false' 19 | end 20 | -------------------------------------------------------------------------------- /JavaScript/codewars/005_descending_order.md: -------------------------------------------------------------------------------- 1 | # #5 Descending Order 2 | 3 | 숫자를 입력받아서 숫자들을 역순으로 재배치해서 리턴한다. 4 | 5 | ## 1. 내 코드 6 | 7 | ```js 8 | function descendingOrder(n){ 9 | return n.toString().split('').sort().reverse().join('') * 1; 10 | } 11 | ``` 12 | 13 | 다 이전 문제에서 설명했던 함수들이다. 특별한 건 문자열을 숫자로 바꿀 때 `*1`을 해주면 된다는 것. 숫자를 문자열로 바꿀 때 `+ ''`를 하는 것과 비슷 14 | 15 | ## 2. 다른 해답 16 | 17 | - 다른 답들도 똑같은 형태를 취했다. 다만 사용한 함수가 조금 달랐다. 18 | - `reverse` 대신 `sort` 매개변수로 함수 지정 `sort(function(a,b){b-a})` 19 | - `*1` 대신 `parseInt()` 사용. 비슷한걸로 `parseFloat`도 있다. 20 | -------------------------------------------------------------------------------- /Python/codewars/041_least_common_multiple.md: -------------------------------------------------------------------------------- 1 | # #41 Least Common Multiple 2 | 3 | 운 좋게 40번 문제와 겹친 문제다. 최소 공배수를 구하는 문제다. 4 | 5 | # 1. 내 코드 6 | 7 | ```py 8 | def gcd(*args): 9 | from fractions import gcd 10 | return reduce(gcd, args) 11 | 12 | def lcm(*args): 13 | return reduce(lambda x, y: (x * y) // gcd(x, y), args) 14 | ``` 15 | 16 | # 2. 다른 해답 17 | 18 | 어차피 2개 수만 gcd로 구할거라서 아래처럼 바로 gcd를 활용해도 괜찮겠다. 19 | 20 | ```py 21 | from fractions import gcd 22 | def lcm(*args): 23 | return reduce(lambda x,y: x * y / gcd(x,y), args) 24 | ``` 25 | -------------------------------------------------------------------------------- /Algorithm/exercises/Reverse_str_recursion.md: -------------------------------------------------------------------------------- 1 | # Reverse string using recursion 2 | 3 | A 문자열이 가 B 문자열에 포함되어있는지 검사하는 함수 4 | 5 | ```py 6 | def strContain(A, B) : 7 | if len(A) > len(B): 8 | return "No" 9 | elif len(A) == 0: 10 | return "Yes" 11 | else: 12 | if A[0] in B: 13 | return strContain(A[1:], B) 14 | else: 15 | return "No" 16 | ``` 17 | 18 | - A 문자열이 더 짧으면 당연히 포함이 안되니 바로 X 19 | - 재귀를 활용해서 A 문자열 앞 문자부터 줄여가면서 재 호출 20 | - A 문자가 소진되면 종료해야해서 기저조건을 A의 길이로 설정 21 | - 재귀 호출로 리턴되는 값 따로 변형 없이 바로 리턴 22 | -------------------------------------------------------------------------------- /JavaScript/leafletjs.md: -------------------------------------------------------------------------------- 1 | # Leaflet js 2 | 3 | 인터렉티브 지도를 만들 수 있는 라이브러리 4 | 5 | ```html 6 | 10 | 13 | ``` 14 | 15 | -------------------------------------------------------------------------------- /Python/codewars/058_multiplication_tables.md: -------------------------------------------------------------------------------- 1 | # #58 Multiplication Tables 2 | 3 | row, col 값을 매개변수로 받아서 r*c 어레이를 만든다. 첫 행은 1부터 row까지의 값이고 두, 세번째 행들은 2, 3을 곱한 값이면 된다. 4 | 5 | ## 1. 내 코드 6 | 7 | ```py 8 | def multiplication_table(row,col): 9 | result = [] 10 | for r in range(row): 11 | result.append([(r+1)*(c+1) for c in range(col)]) 12 | return result 13 | ``` 14 | 15 | ## 2. 다른 해답 16 | 17 | ```py 18 | def multiplication_table(row,col): 19 | return [[(i+1)*(j+1) for j in range(col)] for i in range(row)] 20 | ``` 21 | 22 | for 문을 중첩해서 써서 바로 리턴했다. 23 | -------------------------------------------------------------------------------- /JavaScript/codewars/032_the_coupon_code.md: -------------------------------------------------------------------------------- 1 | # #32 The Coupon Code 2 | 3 | 쿠폰이 올바른지 아닌지를 체크하는 문제다. 코드가 일치하는지 확인하고, 만료일보다 이전인지 확인하면 된다. 4 | 5 | ## 1. 코드 6 | 7 | ```js 8 | function checkCoupon(enteredCode, correctCode, currentDate, expirationDate){ 9 | return enteredCode === correctCode && Date.parse(expirationDate) >= Date.parse(currentDate) 10 | } 11 | ``` 12 | 13 | - 쿠폰 코드는 단순히 `===`를 써서 같은지 확인한다. 14 | - 날짜는 찾아보니 `Date.parse(dateString)` 함수가 있었다. 날짜 형태의 문자열을 매개변수로 넣으면 Date 객체를 만들어낸다. 만들어진 객체는 부등호 연산이 가능하다. 15 | - 다른 해답을 보니 그냥 `new Date(datestring)` 형태로 객체를 생성해서 비교할 수도 있었다. 16 | -------------------------------------------------------------------------------- /Python/Django/source/django_girls_blog_tutorial/static/admin/css/fonts.css: -------------------------------------------------------------------------------- 1 | @font-face { 2 | font-family: 'Roboto'; 3 | src: url('../fonts/Roboto-Bold-webfont.woff'); 4 | font-weight: 700; 5 | font-style: normal; 6 | } 7 | 8 | @font-face { 9 | font-family: 'Roboto'; 10 | src: url('../fonts/Roboto-Regular-webfont.woff'); 11 | font-weight: 400; 12 | font-style: normal; 13 | } 14 | 15 | @font-face { 16 | font-family: 'Roboto'; 17 | src: url('../fonts/Roboto-Light-webfont.woff'); 18 | font-weight: 300; 19 | font-style: normal; 20 | } 21 | -------------------------------------------------------------------------------- /Python/Django/source/django_girls_blog_tutorial/static/admin/img/icon-alert.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /Python/codewars/061_linkedlist_01.md: -------------------------------------------------------------------------------- 1 | # #61 Linked Lists - Push & BuildOneTwoThree 2 | 3 | 파이썬으로 링크드 리스트 만드는 문제. 4 | 5 | ```py 6 | class Node(object): 7 | def __init__(self, data): 8 | self.data = data 9 | self.next = None 10 | 11 | def push(head, data): 12 | n = Node(data) 13 | n.next = head 14 | return n 15 | 16 | def build_one_two_three(): 17 | return push(push(Node(3), 2), 1) 18 | ``` 19 | 20 | - `push`: 이건 쉽게했다. data를 가지고 Node 객체 생성한 후에 head를 연결해주는 것. 21 | - `build_one_two_three`: 이해가 쉽지 않았다. 위 코드처럼 뭉쳐서 리턴해도 `Node(3)` 부분이 없어지지 않고 리턴되는건지 아직도 아리송하다. 22 | -------------------------------------------------------------------------------- /Python/Django/source/django_girls_blog_tutorial/blog/templates/blog/post_detail.html: -------------------------------------------------------------------------------- 1 | {% extends 'blog/base.html' %} 2 | 3 | {% block content %} 4 |
5 | {% if post.published_date %} 6 |
7 | {{ post.published_date }} 8 |
9 | {% endif %} 10 | 11 |

{{ post.title }}

12 |

{{ post.text|linebreaks }}

13 |
14 | {% endblock %} 15 | -------------------------------------------------------------------------------- /Python/codewars/056_playing_with_digits.md: -------------------------------------------------------------------------------- 1 | # #56 Playing with digits 2 | 3 | 89라는 숫자는 `8^1 + 9^2 = 89*1`로 표현될 수 있다. 즉 n이라는 숫자가 `a*100 + b*10 + c*1`일 때 `a^p + b^(p+1) + c^(p+2) = n*k`로 표현될 수 있다면 k를 리턴하는 문제다. 4 | 5 | ## 1. 내 코드 6 | 7 | ```py 8 | def dig_pow(n, p): 9 | result = 0 10 | for i, d in enumerate(str(n)): 11 | result += int(d) ** (p+i) 12 | return -1 if result % n else result / n 13 | ``` 14 | 15 | - n을 문자열로 해서 하나하나 for 반복을 돌린다. p 값을 1씩 증가시켜야하므로 enumerate를 사용했다. 16 | - result 값을 두고 계산한 전체 수를 더하고, n으로 딱 나눠떨어지는지 여부에 따라 -1 혹은 k 값(result / n)을 리턴한다. 17 | - 최고 득표 답과 같다. 18 | -------------------------------------------------------------------------------- /Ruby_on_Rails/Coderbyte/easy/ab_check.rb: -------------------------------------------------------------------------------- 1 | def ABCheck(str) 2 | array_a_index = [] 3 | array_b_index = [] 4 | index = 0 5 | 6 | str.each_char do |c| 7 | if c == 'a' 8 | array_a_index.push(index) 9 | elsif c == 'b' 10 | array_b_index.push(index) 11 | end 12 | index += 1 13 | end 14 | 15 | array_a_index.each do |num_a| 16 | array_b_index.each do |num_b| 17 | if (num_a - num_b).abs == 4 18 | return 'true' 19 | end 20 | end 21 | end 22 | return 'false' 23 | end 24 | -------------------------------------------------------------------------------- /Python/codewars/010_narcissistic_number.md: -------------------------------------------------------------------------------- 1 | # #10 Narcissistic Number check 2 | 각 자리의 숫자들을 원래 수의 자리수로 제곱한다. 즉 세 자리 수면 각 자리 수를 3제곱하고, 4자리 수면 4제곱한다. 이 제곱된 수의 합이 원래 수와 같으면 narcissistic number이다. 이걸 체크하는 함수. 3 | 4 | ## 1. 내 코드 5 | 6 | ```python 7 | def narcissistic( value ): 8 | narcissistic_number = sum(int(i)**len(str(value)) for i in str(value)) 9 | if value == narcissistic_number: 10 | return True 11 | else: 12 | return False 13 | ``` 14 | 15 | ## 2. 다른 해답 16 | 17 | 다 비슷하게 했다. 다만 리턴할 때 나처럼 if 문을 활용한게 아니라 'return value==narcissistic_number' 이라고만 했다. 더 간결하고 좋은 것 같다. 앞으로는 이렇게. 18 | -------------------------------------------------------------------------------- /iOS/02_storyboard.md: -------------------------------------------------------------------------------- 1 | # Stroyboard 2 | 3 | ## 1. UI 만들기 4 | 5 | - Navigator panel에서 `Main.storyboard` 파일로 UI를 만든다. 6 | - 우측 Utility Panel의 **Object library**에서 각종 요소를 드래그 앤 드롭으로 캔버스에 위치시킬 수 있다. 7 | - Object 하나를 선택하고 우측 inspector에서 속성들을 설정해줄 수 있다. 8 | + identity: 선택한 오브젝트의 클래스 9 | + attribute: 색깔, 폰트, 크기, 텍스트 등을 변경 10 | + size: 선택한 오브젝트의 위치와 크기 11 | + connection: 오브젝트와 코드간의 연결 정보 제공 12 | 13 | ## 2. 속성 조절 14 | 15 | - View 요소로 배경을 설정해줄 수 있다. 16 | - front/back: 스토리보드 좌측 하단의 Document outline 클릭. Object들의 위계가 들어있다. 메뉴에서 뒤로 보내기, 앞으로 보내기로 설정할 수도 있다. 17 | - Scene: 전체 장면을 구성하는 View Object를 Scene이라고 한다. 18 | -------------------------------------------------------------------------------- /C/algorithm/011_num_cnt.md: -------------------------------------------------------------------------------- 1 | # #10 숫자의 개수 2 | 3 | 세 숫자를 입력받아 모두 곱한 후, 특정 숫자가 몇 번 결과값에 사용되었는지 나타낸다. 예를 들어 1123이라면 `0 2 1 1 0 0 0 0 0 0`를 한 줄씩 띄워서 출력하면 된다. 4 | 5 | ## 1. 내 코드 6 | 7 | ```c 8 | #include 9 | 10 | int main(void) 11 | { 12 | int a, b, c, tmp, i; 13 | int arr[10] = {0}; 14 | 15 | scanf("%d", &a); 16 | scanf("%d", &b); 17 | scanf("%d", &c); 18 | tmp = a * b * c; 19 | while (tmp > 0) 20 | { 21 | arr[tmp % 10]++; 22 | tmp /= 10; 23 | } 24 | for (i = 0; i < 10; i++) 25 | printf("%d\n", arr[i]); 26 | return (0); 27 | } 28 | ``` 29 | -------------------------------------------------------------------------------- /Python/Django/source/django_girls_blog_tutorial/static/admin/img/icon-no.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /Ruby_on_Rails/Coderbyte/easy/letter_changes.rb: -------------------------------------------------------------------------------- 1 | def LetterChanges(str) 2 | i = 0 3 | str.each_byte do |c| 4 | if (c >= 65 && c <= 89) 5 | str[i] = (c+1).chr 6 | elsif c == 90 7 | str[i] = 65.chr 8 | end 9 | 10 | if (c >= 97 && c <= 121) 11 | str[i] = (c+1).chr 12 | if c+1 == 97 || c+1 == 101 || c+1 == 105 || c+1 == 111 || c+1 == 117 13 | str[i] = (c-31).chr 14 | end 15 | elsif c == 122 16 | str[i] = 65.chr 17 | end 18 | 19 | i += 1 20 | end 21 | return str 22 | end 23 | -------------------------------------------------------------------------------- /Ruby_on_Rails/Coderbyte/easy/arith_geo.rb: -------------------------------------------------------------------------------- 1 | def ArithGeo(arr) 2 | arith_cnt = 0 3 | geo_cnt = 0 4 | 5 | arith_dif = arr[1] - arr[0] 6 | geo_multi = arr[1] / arr[0].to_f 7 | 8 | (1...arr.length - 1).to_a.each do |e| 9 | if arith_dif == (arr[e+1] - arr[e]) 10 | arith_cnt += 1 11 | elsif geo_multi == arr[e+1]/arr[e].to_f 12 | geo_cnt += 1 13 | end 14 | end 15 | 16 | if arith_cnt == arr.length - 2 17 | return 'Arithmetic' 18 | elsif geo_cnt == arr.length - 2 19 | return 'Geometric' 20 | else 21 | return -1 22 | end 23 | end 24 | -------------------------------------------------------------------------------- /Ruby_on_Rails/Coderbyte/medium/arith_geo_II.rb: -------------------------------------------------------------------------------- 1 | def ArithGeoII(arr) 2 | arith_cnt = 0 3 | geo_cnt = 0 4 | arith_dif = arr[1] - arr[0] 5 | geo_multi = arr[1] / arr[0].to_f 6 | 7 | (1...arr.length - 1).to_a.each do |e| 8 | if arith_dif == (arr[e+1] - arr[e]) 9 | arith_cnt += 1 10 | elsif geo_multi == arr[e+1]/arr[e].to_f 11 | geo_cnt += 1 12 | end 13 | end 14 | 15 | if arith_cnt == arr.length - 2 16 | return 'Arithmetic' 17 | elsif geo_cnt == arr.length - 2 18 | return 'Geometric' 19 | else 20 | return -1 21 | end 22 | end 23 | -------------------------------------------------------------------------------- /Python/Django/source/django_girls_blog_tutorial/static/admin/img/inline-delete.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /Python/Django/source/django_girls_blog_tutorial/static/admin/css/dashboard.css: -------------------------------------------------------------------------------- 1 | /* DASHBOARD */ 2 | 3 | .dashboard .module table th { 4 | width: 100%; 5 | } 6 | 7 | .dashboard .module table td { 8 | white-space: nowrap; 9 | } 10 | 11 | .dashboard .module table td a { 12 | display: block; 13 | padding-right: .6em; 14 | } 15 | 16 | /* RECENT ACTIONS MODULE */ 17 | 18 | .module ul.actionlist { 19 | margin-left: 0; 20 | } 21 | 22 | ul.actionlist li { 23 | list-style-type: none; 24 | } 25 | 26 | ul.actionlist li { 27 | overflow: hidden; 28 | text-overflow: ellipsis; 29 | -o-text-overflow: ellipsis; 30 | } 31 | -------------------------------------------------------------------------------- /C/algorithm/002_str_rev.md: -------------------------------------------------------------------------------- 1 | # 002 String reverse 2 | 3 | ## 1. 문제 4 | 5 | 문자 배열을 포인터로 입력받아서 따로 문자 배열 선언 없이 문자열을 reverse한 후 그 포인터를 리턴하는 문제다. 6 | 7 | ## 2. 내 코드 8 | 9 | ```c 10 | char *ft_strrev(char *str) 11 | { 12 | int i; 13 | int size; 14 | char tmp; 15 | 16 | size = 0; 17 | while (str[size]) 18 | size++; 19 | size--; 20 | i = 0; 21 | while (i < size) 22 | { 23 | tmp = str[i]; 24 | str[i] = str[size]; 25 | str[size] = tmp; 26 | i++; 27 | size--; 28 | } 29 | return (str); 30 | } 31 | ``` 32 | 33 | - 포인터를 한칸씩 이동하며 문자열의 크기를 구한다. 34 | - 널 문자를 제외한 끝 문자와 첫문자를 하나씩 스왑한다. 35 | -------------------------------------------------------------------------------- /Python/Django/source/django_girls_blog_tutorial/blog/migrations/0002_post_nothing.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # Generated by Django 1.9 on 2015-12-06 08:38 3 | from __future__ import unicode_literals 4 | 5 | from django.db import migrations, models 6 | 7 | 8 | class Migration(migrations.Migration): 9 | 10 | dependencies = [ 11 | ('blog', '0001_initial'), 12 | ] 13 | 14 | operations = [ 15 | migrations.AddField( 16 | model_name='post', 17 | name='nothing', 18 | field=models.CharField(default='nothing hi', max_length=10), 19 | preserve_default=False, 20 | ), 21 | ] 22 | -------------------------------------------------------------------------------- /Python/codewars/007_vowel_count.md: -------------------------------------------------------------------------------- 1 | # #7 Vowel Count 2 | 문자열을 입력 받아서 모음 철자 개수를 리턴하는 함수. 3 | 4 | ## 1. 내 코드 5 | 6 | 통과는 됐지만 대문자 'AEIOU'는 체크 안해줬다. 다른 분들 코드 보고 그 부분 고쳤음. 정규표현식을 써서 aeiou 알파벳들을 하나하나 리스트에 넣었고, 그 길이를 리턴했다. 7 | 8 | ```python 9 | import re 10 | def getCount(inputStr): 11 | return len(re.findall('[aeiou]', inputStr, re.IGNORECASE)) 12 | ``` 13 | 14 | ## 2. 다른 해답 15 | 16 | python에서 'in' syntax는 정말 활용 방안이 많은 것 같다. 리스트 내포 for문을 활용해서 inputStr에서 문자를 하나하나 체크하면서 만약 "aeiouAEIOU"라는 문자열에 문자가 속해있다면 리스트에 1을 추가한다. 최종적으로 모든 수를 sum 해서 리턴. 17 | 18 | ```python 19 | def getCount(inputStr): 20 | return sum(1 for let in inputStr if let in "aeiouAEIOU") 21 | ``` 22 | -------------------------------------------------------------------------------- /Python/codewars/055_double_cola.md: -------------------------------------------------------------------------------- 1 | # #55 Double Cola 2 | 3 | 5명의 사람이 자판기 앞에 일렬로 서 있다. 콜라를 뽑아먹으면 맨 뒤로 가서 다시 차례를 기다리는데 다음 번엔 2배로 콜라를 많이 뽑아 먹는다. r번째 콜라는 누가 먹게 되는지 계산하는 문제. 4 | 5 | ## 1. 내 코드 6 | 7 | ```py 8 | def whoIsNext(names, r): 9 | if r <= 5: return names[r-1] 10 | exp = -1 11 | while r > 0: 12 | exp += 1 13 | r -= 5*(2**exp) 14 | r += 5*(2**exp) 15 | return names[r / 2**exp] 16 | ``` 17 | 18 | - 5번째까지는 바로 r-1번째 인덱스의 사람을 리턴한다. 2의 0 제곱이 1이라서 생기는 예외다. 19 | - 5명이 먹을 때마다 2배씩 늘어나므로 한 바퀴를 돌 때 소비되는 콜라의 개수는 `5 * 2**exp`다. 계속 r에서 빼준다. 20 | - r이 음수가 되는 시점에서 반복을 멈추고 음수가 되기 전 r 값을 구한다. 21 | - 한 사람이 먹는 콜라 개수로 나눠서 얻는 몫이 이름 리스트의 인덱스가 된다. 22 | -------------------------------------------------------------------------------- /Ruby_on_Rails/Coderbyte/easy/second_great_low.rb: -------------------------------------------------------------------------------- 1 | def SecondGreatLow(arr) 2 | if arr.length == 2 3 | return arr[1].to_s + ' ' + arr[0].to_s 4 | end 5 | 6 | second_min = 0 7 | second_max = 0 8 | arr = arr.sort 9 | 10 | (0...arr.length-1).to_a.each do |e| 11 | if arr[e] arr[(e+2)*-1] 19 | second_max = arr[(e+2)*-1] 20 | break 21 | end 22 | end 23 | 24 | return second_min.to_s + ' ' + second_max.to_s 25 | end 26 | -------------------------------------------------------------------------------- /Python/codewars/002_square_digits.md: -------------------------------------------------------------------------------- 1 | # #2 Square Every Digit 2 | 3 | 각 자리 숫자를 제곱한 수로 연결된 숫자. 9119 -> 811181 4 | 5 | ## 내 코드 6 | 7 | ```python 8 | def square_digits(num): 9 | str_num = str(num) 10 | result = "" 11 | for ch in str_num: 12 | ch_num = pow(int(ch), 2) 13 | result += str(ch_num) 14 | return int(result) 15 | ``` 16 | 17 | ## 다른 해답 18 | 19 | ```python 20 | def square_digits(num): 21 | return int(''.join(str(int(d)**2) for d in str(num))) 22 | ``` 23 | 24 | 리스트 내포 '표현식 for 항목 in iterable if 조건문'를 활용했다. 25 | 26 | - 표현식: 'str(int(d)**2)' 27 | - 항목: d 28 | - iterable: str(num) 29 | 30 | 리턴되는 값을 빈 문자열 ''에다가 계속 join한 후 마지막에 정수로 바꿔서 리턴한다. 31 | -------------------------------------------------------------------------------- /JavaScript/codewars/023_bit_calculator.md: -------------------------------------------------------------------------------- 1 | # #23 Bit Calculator 2 | 3 | (parseInt 메소드를 쓰지 않고)두 개의 문자열 이진수를 10진법으로 변환하고 더한 결과를 리턴하는 문제다. 4 | 5 | ## 1. 내 코드 6 | 7 | ```js 8 | function calculate(num1,num2){ 9 | function convert(p, c, i) { 10 | return p + c * Math.pow(2, i); 11 | } 12 | var result1 = num1.split('').reverse().reduce(convert, 0); 13 | var result2 = num2.split('').reverse().reduce(convert, 0); 14 | return result1 + result2; 15 | } 16 | ``` 17 | 18 | - 내부에 이진수를 10진수로 바꾸는 함수를 만들었다. reduce의 콜백 함수를 만들거라서 매개변수를 p, c, i를 주었다. 순서대로 이전 값, 현재값, 현재값의 인덱스이다. 19 | - num1, num2가 문자열이므로 split, reverse, reduce 함수를 조합해서 바로 결과를 구했고 더해서 리턴했다. 20 | - 다른 해답은 for 문으로 이진수 변환하는 단순한 코드라서 따로 적지 않았다. 21 | -------------------------------------------------------------------------------- /Python/Django/source/django_girls_blog_tutorial/static/admin/js/collapse.min.js: -------------------------------------------------------------------------------- 1 | (function(a){a(document).ready(function(){a("fieldset.collapse").each(function(b,c){0===a(c).find("div.errors").length&&a(c).addClass("collapsed").find("h2").first().append(' ('+gettext("Show")+")")});a("fieldset.collapse a.collapse-toggle").click(function(b){a(this).closest("fieldset").hasClass("collapsed")?a(this).text(gettext("Hide")).closest("fieldset").removeClass("collapsed").trigger("show.fieldset",[a(this).attr("id")]):a(this).text(gettext("Show")).closest("fieldset").addClass("collapsed").trigger("hide.fieldset", 2 | [a(this).attr("id")]);return!1})})})(django.jQuery); 3 | -------------------------------------------------------------------------------- /Python/Django/source/django_girls_blog_tutorial/static/admin/img/icon-unknown.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /Python/Django/source/django_girls_blog_tutorial/static/admin/img/icon-unknown-alt.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /Ruby_on_Rails/Coderbyte/medium/prime_mover.md: -------------------------------------------------------------------------------- 1 | #Prime mover 2 | 파라미터로 숫자를 넣으면 그 순서의 소수(prime number)를 리턴하는 함수를 짜는 것. 3 | 4 | ```ruby 5 | def PrimeMover(num) 6 | return 2 if num == 1 7 | cnt = 1 8 | prime_num = 1 9 | while cnt < num 10 | prime_num += 2 11 | is_prime = true 12 | (3..Math.sqrt(prime_num)).step(2) do |i| 13 | if prime_num % i == 0 14 | is_prime = false 15 | break 16 | end 17 | end 18 | cnt += 1 if is_prime 19 | end 20 | prime_num 21 | end 22 | ``` 23 | 생각했던 흐름과 똑같은 다른 사람 코드가 있어서 참고해서 약간 수정했다. 기본적으로 1/2 승수 수까지만 반복문 돌리는 것은 똑같았지만 2씩 점프해서 반복하는 것은 처음 봐서 추가했다. iterator에 .step(num) 하고 block에 코드를 넣으면 되는 것 같다. 24 | -------------------------------------------------------------------------------- /Python/codewars/052_function_iteration.md: -------------------------------------------------------------------------------- 1 | # #52 Function iteration 2 | 3 | 함수와 n(횟수)을 매개변수에 넣으면 그 함수를 n번 실행한 결과를 내놓는 새로운 함수를 리턴하게 하는 문제다. 4 | 5 | ## 1. 내 코드 6 | 7 | ```py 8 | def create_iterator(func, n): 9 | def nth_iterator(num): 10 | for i in range(n): 11 | num = func(num) 12 | return num 13 | return nth_iterator 14 | ``` 15 | 16 | - 클로저 개념으로 처음 입력받은 n 값을 사용했고, for 문으로 함수를 여러번 호출했다. 마지막에 함수 리턴. 17 | 18 | ## 2. 다른 해답 19 | 20 | ```py 21 | def create_iterator(func, n): 22 | if n == 1: return func 23 | return lambda x : func(create_iterator(func, n-1)(x)) 24 | ``` 25 | 26 | - for문 대신 재귀 용법을 썼다. 27 | - n이 1이면 바로 리턴하면 되고, 아니라면 create_iterator 함수를 func의 매개변수에 넣어서 재 호출했다. 28 | - 즉 func(func(func(func(x)))) 이런식으로 중첩 호출되는 방식이다. 29 | -------------------------------------------------------------------------------- /Python/codewars/014_feynman_square_question.md: -------------------------------------------------------------------------------- 1 | # #14 Feynman's square question 2 | 정사각형으로 이루어진 정사각형에서 총 정사각형 개수를 구하는 문제다. 1개짜리 정사각형이면 1개, 4개로 이루어진 정사각형이면 5개 같은 식이다. 3 | 4 | ## 1. 내 코드 5 | n*n 정사각형에서 1*1 정사각형은 n*n개만큼 있다. 2*2 정사각형은 (n-1)*(n-1)개 만큼 있고. 각 크기의 정사각형 개수를 리스트에 넣어서 sum 한 후 리턴했다. 6 | 7 | ```python 8 | def count_squares(n): 9 | return sum((n-i)**2 for i in xrange(n)) 10 | ``` 11 | 12 | 13 | ## 2. 다른 해답 14 | 다행히 최고 득표의 해답은 나와 똑같은 코드였다. 하지만 역시 수학 문제이다보니 수학 공식을 알고리즘으로 택한 답변도 있었고, 재귀를 사용한 예도 있었다. 재귀를 사용한 예는 구하는 방식 자체는 내 답과 동일했다. 15 | 16 | ```python 17 | # 수학 공식 18 | def count_squares(n): 19 | return n*(n+1)*(2*n+1)/6 20 | 21 | # 재귀 사용 22 | def count_squares(n): 23 | if n == 1: return 1 24 | else: return n**2 + count_squares(n - 1) 25 | ``` 26 | -------------------------------------------------------------------------------- /Python/Django/source/django_girls_blog_tutorial/blog/models.py: -------------------------------------------------------------------------------- 1 | from django.db import models 2 | from django.utils import timezone 3 | 4 | # Create your models here. 5 | 6 | class Post(models.Model): 7 | author = models.ForeignKey('auth.User') 8 | title = models.CharField(max_length=200) 9 | text = models.TextField() 10 | created_date = models.DateTimeField( 11 | default=timezone.now) 12 | published_date = models.DateTimeField( 13 | blank=True, null=True) 14 | nothing = models.CharField(max_length=10) 15 | 16 | def publish(self): 17 | self.published_date = timezone.now() 18 | self.save() 19 | 20 | def __str__(self): 21 | return self.title 22 | 23 | def hi(self): 24 | print('hi') 25 | 26 | -------------------------------------------------------------------------------- /Python/Django/source/django_girls_blog_tutorial/static/admin/img/icon-clock.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /Python/codewars/015_lambda_open_closed_principle.md: -------------------------------------------------------------------------------- 1 | # #15 Lambdas as a mechanism for Open/Closed 2 | 3 | >이 문제 풀고 6 kyu 등급으로 올라갔다. 은근히 기분 좋다. 4 | 5 | open/closed principle이란 코드는 수정에 있어선 닫혀있어야 하지만, 추가(혹은 확장)에 대해서는 열려있어야 한다는 의미다. 즉 객체를 아예 바꾸지 않더라도 안에 기능(함수)를 추가할 수 있어야 한다. 이걸 할 수 있는 방법 중 하나가 람다를 쓰는 것이다. 아래 예제가 람다를 사용하는 형태 중 하나다. 6 | 7 | ```python 8 | spoken = lambda greeting: greeting.capitalize() + '.' 9 | shouted = lambda greeting: greeting.upper() + '!' 10 | whispered = lambda greeting: greeting.lower() + '.' 11 | 12 | greet = lambda style, msg: style(msg) 13 | ``` 14 | 15 | 쉬운 문제라서 그런지 다른 사람들의 해답과 똑같았다. 재밌었던 것은 16 | 17 | - 람다를 조합할 수 있는데 괄호를 붙여 매개변수임을 나타내는 방식이 통한다는 것. 설마 되나 하고 적어봤는데 되더라. 신기. 18 | - 또 문자열에서 title()이라는 함수도 호출할 수 있다는 것. whitespace로 띄워진 모든 단어들의 첫글자를 대문자화 한다. 19 | -------------------------------------------------------------------------------- /JavaScript/codewars/014_largest_5digit_number.md: -------------------------------------------------------------------------------- 1 | # #14 Largest 5 digit number in a series 2 | 3 | 문자열 타입의 숫자를 받아서 5자리의 연속된 수 중 가장 큰 수를 리턴하는 문제. 4 | 5 | ## 1. 내 코드 6 | 7 | ```js 8 | function solution(digits){ 9 | var result = 0; 10 | for (var i = 0; i < digits.length-4; i++) { 11 | var temp = digits.slice(i, i+5) * 1; 12 | result = result >= temp ? result : temp; 13 | } 14 | return result; 15 | } 16 | ``` 17 | 18 | - for 반복을 돌아서 모든 substring을 구해서 이전 값과 큰지, 다른지 판단하고 마지막에 리턴했다. 19 | 20 | ## 2. 다른 해답 21 | 22 | ```js 23 | function solution(digits){ 24 | if (digits.length <= 5) return Number(digits); 25 | return Math.max(Number(digits.substr(0, 5)), solution(digits.substr(1))); 26 | } 27 | ``` 28 | 29 | - 재귀 사용. 30 | - `String.prototype.substr(start, end)` : substring을 만드는 함수다. 뒤에 end 수를 입력하지 않으면 자동으로 끝까지 자른다. 31 | -------------------------------------------------------------------------------- /C/algorithm/012_word_cnt.md: -------------------------------------------------------------------------------- 1 | # #12 단어의 개수 2 | 3 | - 문제 링크: https://www.acmicpc.net/problem/1152 4 | - 영어 대소문자와 띄어쓰기만으로 이루어진 문장이 주어질 때 단어의 개수를 구하라. 단어는 띄어쓰기 하나로 구분된다. 5 | 6 | ## 1. 내 코드 7 | 8 | ```c 9 | #include 10 | 11 | int is_sep(char c); 12 | 13 | int main(void) 14 | { 15 | int i, cnt; 16 | char str[1000001]; 17 | 18 | scanf("%[^\n]s", str); 19 | cnt = 0; 20 | i = 0; 21 | while (str[i]) 22 | { 23 | if (!is_sep(str[i]) && is_sep(str[i + 1])) 24 | cnt++; 25 | i++; 26 | } 27 | printf("%d\n", cnt); 28 | return (0); 29 | } 30 | 31 | int is_sep(char c) 32 | { 33 | if (c == ' ' || c == '\0') 34 | return (1); 35 | return (0); 36 | } 37 | ``` 38 | 39 | - 현재 문자가 알파벳이고, 그 다음 문자가 공백일 때만 단어 개수를 1씩 늘렸다. 40 | - scanf에서 입력 조건을 커스텀 설정했다. 개행 문자를 만날 때까지 받아들인다. 41 | -------------------------------------------------------------------------------- /Python/codewars/063_linkedlist_03.md: -------------------------------------------------------------------------------- 1 | # #63 Linked Lists - Insert Nth Node 2 | 3 | 링크드 리스트에서 특정 위치에 원소를 추가하는 문제 4 | 5 | ## 1. 내 코드 6 | 7 | ```py 8 | class Node(object): 9 | def __init__(self, data, nxt = None): 10 | self.data = data 11 | self.next = nxt 12 | 13 | def insert_nth(head, index, data): 14 | if index == 0: return Node(data, head) 15 | if head and index > 0: 16 | head.next = insert_nth(head.next, index - 1, data) 17 | return head 18 | raise ValueError 19 | ``` 20 | 21 | - 재귀를 이용. 이전 문제와 비슷하게. 22 | - 인덱스와 head의 조건이 맞지 않으면 에러를 일으킨다. 23 | 24 | ## 2. 다른 코드 25 | 26 | ```py 27 | def insert_nth(head, n, data): 28 | if n==0: 29 | head=Node(data,head) 30 | else: 31 | head.next=insert_nth(head.next,n-1,data) 32 | if not head: raise "Something's fucky!" 33 | return head 34 | ``` 35 | -------------------------------------------------------------------------------- /JavaScript/codewars/021_unique_in_order.md: -------------------------------------------------------------------------------- 1 | # #21 Unique In Order 2 | 3 | 같은 문자가 반복되면 하나로 줄여서 리턴한다. 4 | 5 | ## 1. 내 코드 6 | 7 | ```js 8 | var uniqueInOrder = function(iterable) { 9 | var result = []; 10 | var prev; 11 | for(var i = 0; i < iterable.length; i++){ 12 | if(iterable[i] != prev) { 13 | result.push(iterable[i]); 14 | } 15 | prev = iterable[i]; 16 | } 17 | return result; 18 | } 19 | ``` 20 | 21 | 단순하게 처음부터 끝까지 반복을 돌리는데 이전 값을 계속 저장했다. 비교해서 다를 때만 결과 리스트에 넣었다. 22 | 23 | ## 2. 다른 해답 24 | 25 | ```js 26 | function uniqueInOrder(it) { 27 | var result = []; 28 | var last; 29 | for (var i = 0; i < it.length; i++) { 30 | if (it[i] !== last) { 31 | result.push(last = it[i]); 32 | } 33 | } 34 | return result; 35 | } 36 | ``` 37 | 38 | 나와 똑같은 방식이지만 이전 값과 다를 때만 prev 값을 바꿔줬다. 그리고 변수에다 값을 대입함과 동시에 매개변수로 넘길 수 있다. 이 점 기억. 39 | -------------------------------------------------------------------------------- /Python/codewars/040_common_denominators.md: -------------------------------------------------------------------------------- 1 | # #40 Common Denominators 2 | 3 | '2개 원소를 가진 리스트'를 원소로 가진 리스트를 매개변수로 받는다. 예를 들어 `[[1, 2], [1, 3], [1, 4]]`를 받는다고 하자. 그리고 같은 길이의 `[[N1, D], [N2, D], [N3, D]]` 형태를 리턴해야 한다. 다만 1/2, 1/3, 1/4와 N1/D, N2/D, N3/D의 값이 같아야 한다. 4 | 5 | ## 1. 내 코드 6 | 7 | 이 [gist](https://gist.github.com/endolith/114336)를 참고해서 gcd(great common denominator)와 lcm(least common multiple)을 구했다. 그 후론 특별할게 없었다. 매개변수로 받은 리스트에서 원소인 각 리스트의 두 번째 원소들의 lcm을 구했고, 바로 문제의 연산을 적용해서 리스트를 리턴했다. 최고 득표 해답과 동일한 답이다. 그리고 이 문제를 풀고 `4kyu`가 되었다. 8 | 9 | ```py 10 | def gcd(numbers): 11 | from fractions import gcd 12 | return reduce(gcd, numbers) 13 | 14 | def lcm(numbers): 15 | def lcm(a, b): 16 | return (a * b) // gcd([a, b]) 17 | return reduce(lcm, numbers, 1) 18 | 19 | def convertFracts(lst): 20 | D = lcm([j for i, j in lst]) 21 | return [[n * D / de, D] for n, de in lst] 22 | ``` 23 | -------------------------------------------------------------------------------- /C/algorithm/015_fraction.md: -------------------------------------------------------------------------------- 1 | # 분수 찾기 2 | 3 | - 문제 링크: https://www.acmicpc.net/problem/1193 4 | - 링크에 접속하면 분수 표가 있다. 숫자를 입력받아 그 숫자 번째의 분수를 출력하는 문제 5 | 6 | ## 1. 내 코드 7 | 8 | ```c 9 | #include 10 | 11 | int main(void) 12 | { 13 | int num; 14 | int line; 15 | int tmp; 16 | 17 | scanf("%d", &num); 18 | line = 1; 19 | while (1) 20 | { 21 | tmp = line * (line + 1) / 2; 22 | if (tmp >= num) 23 | break ; 24 | line++; 25 | } 26 | if (line % 2 == 0) 27 | printf("%d/%d\n", line - tmp + num, tmp - num + 1); 28 | else 29 | printf("%d/%d\n", tmp - num + 1, line - tmp + num); 30 | return (0); 31 | } 32 | ``` 33 | 34 | - 대각선으로 묶으면 분자와 분모의 합이 같다. 35 | - 대각선을 하나씩 넘어갈수록 분자 분모의 합이 1씩 커지고, 분수의 개수도 1개씩 늘어난다. 36 | - 대각선을 `line`이라 두고, `n(n+1)/2` 공식을 활용해 어느 라인에 찾고자 하는 분수가 위치하는지 찾아낸다. 37 | - 홀수, 짝수 line이 각각 순서가 반대로 되어있으므로 마지막에 반대로 출력해준다. 38 | -------------------------------------------------------------------------------- /C/algorithm/008_palindrome.md: -------------------------------------------------------------------------------- 1 | # Palindrome 2 | 3 | 처음부터, 뒤로부터 읽어도 똑같이 읽히는 단어를 팰린드롬이라 한다. 다음 코드는 팰린드롬 판별 함수다. 4 | 5 | ```c 6 | #include 7 | 8 | void ft_putchar(char c); 9 | void ft_putstr(char *str); 10 | 11 | int main(void) 12 | { 13 | char str[1001]; 14 | int ret; 15 | int i; 16 | 17 | ft_putstr("string: "); 18 | ret = read(0, str, 1000); 19 | str[--ret] = '\0'; 20 | i = 0; 21 | ret--; 22 | while (i < ret) 23 | { 24 | if (str[i] != str[ret]) 25 | { 26 | ft_putstr("It's not.\n"); 27 | return (0); 28 | } 29 | i++; 30 | ret--; 31 | } 32 | ft_putstr("It's palindrome\n"); 33 | return (0); 34 | } 35 | 36 | void ft_putchar(char c) 37 | { 38 | write(1, &c, 1); 39 | } 40 | 41 | void ft_putstr(char *str) 42 | { 43 | while (*str) 44 | ft_putchar(*str++); 45 | } 46 | ``` 47 | -------------------------------------------------------------------------------- /JavaScript/codewars/028_squares_sequence.md: -------------------------------------------------------------------------------- 1 | # #28 Squares sequence 2 | 3 | 며칠 몸이 안 좋아서 오늘은 쉬어가는 겸 쉬운 문제 풀었다. 또 ECMAScript 6가 나오면서 문법이 엄청나게 바뀌었는데.. 그 부분 다시 정리해야겠다. 결국엔 이쪽으로 다 바뀔 것 같다. 4 | 5 | 매개변수 x, n을 받는다. 배열에 x를 시작으로 총 n개를 집어넣게 되는데 각 원소는 이전 원소의 제곱이다. 6 | 7 | ## 1. 내 코드 8 | 9 | ```js 10 | function squares(x, n) { 11 | var result = [x]; 12 | for (var i = 0; i < n-1; i++) { 13 | result.push(Math.pow(result[i], 2)); 14 | } 15 | return result; 16 | } 17 | ``` 18 | 19 | 다른 코드와 같다. Math.pow() 함수 대신 x를 두 번 곱한 점이나, 반복문 종류를 다른 것을 쓰는 등만 다를 뿐이다. 20 | 21 | 다만 다른 코드를 보면서 배열 생성에 대해서 새로운 것을 알게됐다. 파이썬은 일정 길이의 리스트를 쉽게 정의할 수 있다(`arr = [0] * 10`) 자바스크립트는 그런게 없는 것 같아 가끔 불편할 때가 있었는데 너무도 쉽게 다음처럼 정의가 가능했다. `var arr = Array(10)` 물론 값은 모두 undefined지만 길이 자체는 10이다. 이걸 활용하면 위 문제를 다음처럼 해결할 수도 있다. 다른 해답이다. 22 | 23 | ```js 24 | function squares(x, n) { 25 | return Array.apply(0, Array(n)).map(function(_,i){return i? x=x*x : x}) 26 | } 27 | ``` 28 | -------------------------------------------------------------------------------- /JavaScript/es6_map_set.md: -------------------------------------------------------------------------------- 1 | # ECMAScript6 Map, Set, WeakMap, WeakSet 2 | 3 | ES6에서 새롭게 생긴 4가지 자료구조다. 4 | 5 | ## 1. Maps 6 | 7 | Map의 key는 임의의 값이 될 수 있다. 8 | 9 | ```js 10 | const map = new Map(); // create an empty Map 11 | const KEY = {}; 12 | 13 | map.set(KEY, 123); 14 | map.get(KEY) // 123 15 | map.has(KEY) // true 16 | map.delete(KEY); // true 17 | map.has(KEY) // false 18 | ``` 19 | 20 | Map을 선언할 때는 아래처럼 생성자 안에 [key, value] pair로 여러개를 집어넣을 수 있다. 이차원 배열 형태다. 21 | 22 | ```js 23 | const map = new Map([ 24 | [ 1, 'one' ], 25 | [ 2, 'two' ], 26 | [ 3, 'three' ], // trailing comma is ignored 27 | ]); 28 | ``` 29 | 30 | ## 2. Sets 31 | 32 | unique한 값들의 집합이다. 생성자의 매개변수로는 무조건 iterable을 넣어야 한다. 원소를 여러개 넣는건 안된다. 세 번째 코드는 `...`을 사용해서 새롭게 만들어진 Set을 배열의 원소로 바로 넣었다. `...` 용법은 다시 정리하겠다. 33 | 34 | ```js 35 | const arr = [5, 1, 5, 7, 7, 5]; 36 | const arr_set = new Set(arr); 37 | const unique = [...new Set(arr)]; // [ 5, 1, 7 ] 38 | ``` 39 | -------------------------------------------------------------------------------- /Algorithm/exercises/the_sieve_of_Eratosthenes.md: -------------------------------------------------------------------------------- 1 | # 소수 - 에라토스테네스의 체 2 | 3 | 특정 수까지 소수가 몇 개인지 구하는 문제 4 | 5 | ```py 6 | def prime_cnt(n): 7 | result = [1] * (n+1) 8 | cnt = 0 9 | for i in range(2, n+1): 10 | if result[i]: 11 | cnt += 1 12 | for j in range(i+i, n+1, i): 13 | result[j] = 0 14 | return cnt 15 | 16 | def main(): 17 | num = int(input("number input:")) 18 | print("prime count:", prime_cnt(num)) 19 | 20 | if __name__ == "__main__": 21 | main() 22 | ``` 23 | 24 | - 소수의 개수를 구할 때 쉽게는 그냥 모든 수를 하나하나 소수인지 검사하는 방법이 있다. 하지만 소수인지 검사하는 일이 연산을 많이 필요해서 시간이 오래걸린다. 그래서 "에라토스테네스의 체"라는 방법을 이용한다. 25 | - `result = [1] * (n+1)` : 인덱스가 해당 숫자를 의미한다. 값은 그 숫자가 소수인지 아닌지를 1, 0으로 나타낸다. 우선 모든 숫자가 소수라고 가정한다. 26 | - for문으로 반복하는데 2부터 시작하는 것은 소수가 2부터 시작하기 때문이고, n+1까지 반복하는 것은 원하는 숫자 n까지 반복하기 위해서다. 27 | - 만약 소수라면, 즉 값이 1이라면 소수를 찾았으므로 `cnt` 값을 1 증가시킨다. 그리고 그 소수 이후의 배수는 모두 소수가 아니므로 찾아서 0으로 바꾼다. 28 | -------------------------------------------------------------------------------- /Python/codewars/059_take_a_ten_minute_walk.md: -------------------------------------------------------------------------------- 1 | # #59 Take a Ten Minute Walk 2 | 3 | 동서남북 방향을 가리키는 원소들이 들어있는 배열을 입력받는다. 한 번 이동할 때 1분이 걸리고 현재 10분의 여유 시간이 있는 상태다. 정확히 10분동안 걸어서 다시 원래 지점으로 돌아와야한다. 입력받은 배열대로 움직였을 때 위와 같다면 True, 아니라면 False 리턴한다. 4 | 5 | ## 1. 내 코드 6 | 7 | ```py 8 | def isValidWalk(walk): 9 | if len(walk) != 10: return False 10 | n, s, e, w = 0, 0, 0, 0 11 | for c in walk: 12 | if c == 'n': n += 1 13 | if c == 's': s += 1 14 | if c == 'e': e += 1 15 | if c == 'w': w += 1 16 | if n == s and e == w: return True 17 | return False 18 | ``` 19 | 20 | - 처음에 배열의 길이가 10이 아니라면 바로 False 리턴하다. 21 | - n, s, e, w 변수를 만들고, walk 리스트 반복을 돌려서 해당 문자일 때 변수를 +1 한다. 22 | - n과 s가 같고, e와 w가 같으면 본래로 돌아오는 것이므로 True를 리턴한다. 23 | 24 | ## 2. 다른 해답 25 | 26 | ```py 27 | def isValidWalk(walk): 28 | return len(walk) == 10 and walk.count('n') == walk.count('s') and walk.count('e') == walk.count('w') 29 | ``` 30 | 31 | 리스트에 붙어있는 count 함수를 활용했다. 32 | -------------------------------------------------------------------------------- /Python/codewars/021_trailing_zeros.md: -------------------------------------------------------------------------------- 1 | # #21 Number of trailing zeros of N! 2 | 3 | 입력받은 매개변수의 팩토리얼 값에서 마지막 자리의 연속된 0의 개수를 구하는 문제다. 100이면 2, 1130이면 1, 3582000은 3 이런 식이다. 4 | 5 | ## 1. 내 코드 6 | 7 | 팩토리얼 값에서 10이 몇 번 곱해지는지 구하면 된다. 2와 5의 공통된 곱 수를 구하면 되는데 팩토리얼 값을 보니 2는 항상 5보다 곱수가 많았다. 그래서 5가 몇 번 곱해지는지만 구하기로 했다. 그런데 25의 배수는 곱 수가 2번 추가되고, 125의 배수는 곱수가 3번 추가되었다. 그래서 25는 2를 더해주고, 125는 3을 더해줘야하나 싶었는데 중복되더라. 결국 5의 배수, 25의 배수, 125 등등의 5의 제곱수들의 배수들 각각에 1씩만 더해주면 되겠다 싶었다. 그래서 아래와 같이 n 이하의 5의 최대 제곱수를 구하고(그 이상은 나눠지지도 않는다) n을 하나하나 나눠서 몫을 합한 후 리턴했다. 8 | 9 | ```python 10 | def zeros(n): 11 | i = 0 12 | while 5**i < n: i += 1 13 | return sum(n/(5**j) for j in range(1, i)) 14 | ``` 15 | 16 | ## 2. 다른 해답 17 | 18 | 나와 똑같은 원리이지만 재귀를 써서 더 멋지게 구했다. 내가 원래 수인 n을 5로 나누고, 25로 나누고 125로 나누고 625 등등으로 나눈 몫을 더한거나, 원래 수를 계속해서 5로 나누고, 또 나누고, 또 나누는 각각의 몫을 더한거나 같은 값이다. 더 깔끔하다. 19 | 20 | ```python 21 | def zeros(n): 22 | x = n/5 23 | return x+zeros(x) if x else 0 24 | ``` 25 | -------------------------------------------------------------------------------- /Python/codewars/004_what_dominates_your_array.md: -------------------------------------------------------------------------------- 1 | # #4 What dominates your array? 2 | 정수로 이루어진 배열을 받는다. 원소 전체 개수의 과반수를 차지하는 원소를 리턴하면 된다. 과반수가 없다면 -1을 리턴한다. 3 | 4 | ## 1. 내 코드 5 | arr 원소 하나하나를 반복문으로 돌면서 count 메소드로 과반수 이상인지 체크한다. 맞으면 바로 리턴하고 없으면 반복문이 끝나고 -1을 리턴한다. 6 | 7 | ```python 8 | def dominator(arr): 9 | for i in arr: 10 | if arr.count(i) > len(arr)/2: 11 | return i 12 | return -1 13 | ``` 14 | 15 | ## 2. 다른 코드 16 | 모두 비슷한 결과물이라서 나랑 달랐던 해답을 골랐다. 17 | 18 | Counter는 hashable object에서 수를 세아리는데 특화된 클래스다. 아래 코드는 arr을 매개변수로 Counter 객체를 만들고, most_common 함수를 통해 가장 많이 나타나는 원소를 고른 것이다. 매개변수로 1이 들어갔기 때문에 하나만 뽑은 것이고, 리스트를 리턴하기 때문에 [0]로 첫 번째 원소를 뽑았다. 변수 두 개로 받은 것은 리스트의 원소 하나 하나가 '값'과 '값의 개수'를 튜플로 리턴하기 때문이다. 마지막엔 과반수인지 체크하고 리턴한다. 19 | 20 | ```python 21 | from collections import Counter 22 | 23 | def dominator(arr): 24 | if not arr: 25 | return -1 26 | k, v = Counter(arr).most_common(1)[0] 27 | return k if v > len(arr) / 2 else -1 28 | ``` 29 | -------------------------------------------------------------------------------- /Python/codewars/013_digital_root.md: -------------------------------------------------------------------------------- 1 | # #13 Digital Root 2 | 자연수를 입력받아서 각 자리수를 더한 값을 리턴하는 함수다. 만약 각 자리수의 합이 10 이상이면 또 같은 작업을 반복한다. 3 | 4 | ## 1. 내 코드 5 | 매개변수로 받은 자연수를 문자열화 해서 각 자리수에 int를 적용하는 map 함수를 사용했다. 10보다 크면 다시 호출하는 형태로 재귀를 활용했다. 6 | 7 | ```python 8 | def digital_root(n): 9 | result = sum(map(int, str(n))) 10 | return result if result < 10 else digital_root(result) 11 | ``` 12 | 13 | ## 2. 다른 해답 14 | 15 | ### A. 최고 득표 16 | 내 해답도 꽤 줄인 코드가 아닌가 싶었지만 허를 찔렸다. 특히 처음부터 n이 10보다 작은지 검사를 한다는 측면에서 나보다 훨씬 나은 코드다. 뒤에 map과 sum을 쓴 부분은 나와 똑같다. 멋지다. 17 | 18 | ```python 19 | def digital_root(n): 20 | return n if n < 10 else digital_root(sum(map(int,str(n)))) 21 | ``` 22 | 23 | ### B. 두 번째 득표 but.. 24 | 이걸 좋은 코드라고 해야할지 모르겠다. 이 코드를 봤을 때 어떻게 동일한 결과가 나오는지 이해할 수가 없었다. 하지만 같은 문제를 더 빠르게 연산해서 해결한다는 점에선 좋은 알고리즘이라고 할 수 있지 않을까. 성능 면에선 더 나을 것이다. sum, map, int, str, if, 재귀 등등을 조합한 것보단. 그래도 난 A 답변이 더 좋다. 25 | 26 | ```python 27 | def digital_root(n): 28 | return n%9 or n and 9 29 | ``` 30 | -------------------------------------------------------------------------------- /Server/heroku.md: -------------------------------------------------------------------------------- 1 | # Heroku 2 | 3 | 참고 : Heroku tutorial [python](https://devcenter.heroku.com/articles/getting-started-with-python), [node](https://devcenter.heroku.com/articles/getting-started-with-nodejs#deploy-the-app) 4 | 5 | ## 1. 설치 및 로그인 6 | 7 | - `brew install heroku` : CLI 설치 8 | - `heroku login` : 아이디와 비밀번호 입력하면 로그인된다. 9 | - `heroku create project-name` 10 | + 적어준 프로젝트명으로 프로젝트 생성된다. 로컬에 프로젝트가 생성되는게 아니라 원격 저장소에 생김 11 | + 터미널에 뜬 주소로 들어가보면 실제로 해당 페이지를 볼 수 있다. 12 | 13 | ## 2. 예제 프로젝트 14 | 15 | - `git clone https://github.com/heroku/node-js-getting-started.git` : 샘플 프로젝트 다운로드 16 | - `cd node~~` : 해당 프로젝트 디렉토리로 들어가서 17 | + `heroku create` : 원격 저장소가 만들어지고, heroku라는 이름으로 remote가 자동 설정된다. 18 | + `git push heroku master` : heroku에 현재 프로젝트 push 19 | - `heroku ps:scale web=1` 20 | + 1개의 인스턴스로 웹앱 실행하겠다는 의미(최소 1개) 21 | - `heroku open` : 주소를 치고 들어가도 되지만 이 명령어로 브라우저에서 해당 주소를 열 수 있다. 22 | - `heroku logs --tail` : 로그 보기. tail 옵션을 붙이면 계속 띄워둘 수 있다. 없이 실행하면 그 시점의 로그를 출력 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # TIL 2 | Today I Learned. Daily commit. 3 | 4 | ## 1. 목표 5 | 6 | 2016년 1월 20일 100일 돌파 기념으로 조금 규칙을 갖고 기록하기로 다짐. 7 | 8 | - 오전에 후다닥 미리미리 할 것들 9 | + **(필수)** 1일 1 웹페이지 조각 만들기: 웹페이지에서 css로 마리오 그리기, 햄버거 메뉴 효과 pure css로 그려보기, 메뉴 형태 종류별로 하나씩 만들어보기 등등 10 | + **(필수)** [알고리즘교재](http://www.yes24.com/24/Goods/8006522?Acode=101) 보고 하루에 한 문제씩 Python, JavaScript로 동시에 풀기 11 | + 1일 1 문제 풀이: codewars.com 등 다양한 알고리즘 사이트에서 문제 하나씩 풀기. 다른 사람 답변 있으면 함께 기록하고 비교 분석하기. 12 | + ~~오전에 헬스도 하고, 아침점심 밥도 좀 하고, 책도 좀 보고 하려면 위에것만 해도 바쁨.. ㅜㅜ~~ 13 | - 오후, 저녁 본 공부 14 | + **(필수)** 선형대수, 이산수학 이론 공부 + Python 코딩화 15 | + **(필수)** 통계학 이론 + 데이터 분석, 머신러닝 이론 및 라이브러리 해석 + 관련 논문 or 책 + Python 코드 기록 넘기기 16 | + **(필수)** Django로 foodgram 등 계획한 서비스 만들기 17 | + 모르는거 공부하기 (nginx, spark, redis, node, grunt, google analytics 등등) 18 | 19 | ## 2. 다짐 20 | 21 | - 절대 어뷰징은 없다. 22 | - 밤 12시 다 돼서 급하게 커밋하지 말고 미리미리 해두자. 23 | - 중요한 것은 포기하지 않는 것. 더딘 것을 염려하지 말고, 멈출 것을 염려하자. 24 | - 최대한 빠른 시일 내에 **개발 인턴**에게 기대되는 수준을 갖추자. 25 | -------------------------------------------------------------------------------- /Python/Django/source/django_girls_blog_tutorial/blog/static/css/blog.css: -------------------------------------------------------------------------------- 1 | .page-header { 2 | background-color: #ff9400; 3 | margin-top: 0; 4 | padding: 20px 20px 20px 40px; 5 | } 6 | 7 | .page-header h1, .page-header h1 a, .page-header h1 a:visited, .page-header h1 a:active { 8 | color: #ffffff; 9 | font-size: 36pt; 10 | text-decoration: none; 11 | } 12 | 13 | .content { 14 | margin-left: 40px; 15 | } 16 | 17 | h1, h2, h3, h4 { 18 | font-family: 'Lobster', cursive; 19 | } 20 | 21 | .date { 22 | float: right; 23 | color: #828282; 24 | } 25 | 26 | .save { 27 | float: right; 28 | } 29 | 30 | .post-form textarea, .post-form input { 31 | width: 100%; 32 | } 33 | 34 | .top-menu, .top-menu:hover, .top-menu:visited { 35 | color: #ffffff; 36 | float: right; 37 | font-size: 26pt; 38 | margin-right: 20px; 39 | } 40 | 41 | .post { 42 | margin-bottom: 70px; 43 | } 44 | 45 | .post h1 a, .post h1 a:visited { 46 | color: #000000; 47 | } 48 | -------------------------------------------------------------------------------- /Python/codewars/006_you_are_a_square.md: -------------------------------------------------------------------------------- 1 | # #6 You're a square! 2 | 매개변수로 받은 정수가 어떤 수의 제곱수인지 검증하는 함수 3 | 4 | ## 1. 내 코드 5 | 우선 0 이상인지 검증한다. 그 후 제곱근을 씌운 결과가 실수가 아닌 정수인지 검증한다. 제곱수라면 정수일 것이므로. 결과에 따라 True, False를 리턴한다. 6 | 7 | ```python 8 | import math 9 | def is_square(n): 10 | if n < 0: return False 11 | square_root = pow(n, 0.5) 12 | if square_root == math.floor(square_root): 13 | return True 14 | else: 15 | return False 16 | ``` 17 | 18 | ## 2. 다른 해답 19 | 20 | ### A. math.sqrt(num), is_integer() 21 | 22 | 정수인가? 문자열인가? 실수인가? 같은 검증 함수들은 대부분 존재하는 것 같다. is_integer()는 float 객체에 달려있는 함수다. Integer 타입에선 동작하지 않는다. 23 | 24 | math.sqrt 함수는 제곱근을 해서 결과값을 float형으로 리턴한다. 25 | 26 | n>0과 함께 and 연산자를 통해서 True, False를 최종 리턴한다. 간결!! 27 | 28 | ```python 29 | from math import sqrt 30 | def is_square(n): 31 | return n > 0 and sqrt(n).is_integer() 32 | # return n > -1 and math.sqrt(n) % 1 == 0; 33 | # 이런 식으로 is_integer 대신 1로 나눈 나머지가 0인지 아닌지를 판별하는 코드도 있었다. 기발하네. 34 | ``` 35 | -------------------------------------------------------------------------------- /Python/Django/source/django_girls_blog_tutorial/mysite/urls.py: -------------------------------------------------------------------------------- 1 | """mysite URL Configuration 2 | 3 | The `urlpatterns` list routes URLs to views. For more information please see: 4 | https://docs.djangoproject.com/en/1.9/topics/http/urls/ 5 | Examples: 6 | Function views 7 | 1. Add an import: from my_app import views 8 | 2. Add a URL to urlpatterns: url(r'^$', views.home, name='home') 9 | Class-based views 10 | 1. Add an import: from other_app.views import Home 11 | 2. Add a URL to urlpatterns: url(r'^$', Home.as_view(), name='home') 12 | Including another URLconf 13 | 1. Add an import: from blog import urls as blog_urls 14 | 2. Import the include() function: from django.conf.urls import url, include 15 | 3. Add a URL to urlpatterns: url(r'^blog/', include(blog_urls)) 16 | """ 17 | from django.conf.urls import url, include 18 | from django.contrib import admin 19 | 20 | urlpatterns = [ 21 | url(r'^admin/', admin.site.urls), 22 | url(r'', include('blog.urls')), 23 | ] 24 | -------------------------------------------------------------------------------- /C/algorithm/010_ox_quiz.md: -------------------------------------------------------------------------------- 1 | # #10 OX quiz 2 | 3 | - 문제 링크: https://www.acmicpc.net/problem/8958 4 | - OX 퀴즈에서 맞고 틀린 것을 다음처럼 표현한다. 5 | + `OOXXOXXOOO` 6 | - 맞추면 1점인데 연속으로 맞추면 점수를 1점씩 더 받는다. 위 경우엔 점수가 7 | + `1+2+0+0+1+0+0+1+2+3` 이렇게 된다. 8 | - 점수를 구하는 프로그램 만들기. 9 | 10 | ## 1. 내 코드 11 | 12 | ```c 13 | #include 14 | 15 | int main(void) 16 | { 17 | int case_num; 18 | char str[81]; 19 | int score; 20 | int add; 21 | int i; 22 | 23 | scanf("%d", &case_num); 24 | while(case_num) 25 | { 26 | score = 0; 27 | add = 1; 28 | i = 0; 29 | scanf("%s", str); 30 | while (str[i]) 31 | { 32 | if (str[i] == 'O') 33 | { 34 | score += add; 35 | add++; 36 | } 37 | else 38 | { 39 | add = 1; 40 | } 41 | i++; 42 | } 43 | printf("%d\n", score); 44 | case_num--; 45 | } 46 | return (0); 47 | } 48 | ``` 49 | -------------------------------------------------------------------------------- /Algorithm/exercises/permutation.md: -------------------------------------------------------------------------------- 1 | # Permutation 2 | 3 | a부터 시작해서 n개의 알파벳에서 r 만큼 permutation을 한다. => nPr 4 | 5 | ```py 6 | def getPermutation(n, r) : 7 | alphabets = [chr(i + 97) for i in range(n)] 8 | if r == 1: 9 | return alphabets 10 | else: 11 | prev = getPermutation(n, r - 1) 12 | result = [] 13 | for el in prev: 14 | for c in alphabets: 15 | if c not in el: 16 | result.append(el + c) 17 | return result 18 | 19 | def main(): 20 | firstLine = [int(x) for x in input().split()] 21 | print('\n'.join(getPermutation(firstLine[0], firstLine[1]))) 22 | 23 | if __name__ == "__main__": 24 | main() 25 | ``` 26 | 27 | - 예를 들어 n = 4, r = 2라면 "ab ac ad ba bc bd ca cb cd da db dc"를 리턴하면 된다. 28 | - 핵심 아이디어는 먼저 나올 알파벳을 구하고("a, b, c, d"), 이 결과값에 다음에 붙을 수 있는 알파벳을 붙이는 것으로 반복하는 것이다. 즉 "a"는 "ab ac ad"로 원소가 1개에서 3개가 된다. 29 | - 재귀를 이용했고 r을 1씩 줄여나가면서 깊이 들어갔다. r이 1일 때는 그대로 하나짜리 알파벳들 리스트를 리턴한다. 30 | - r이 1이 아닐 때는 재귀를 호출하고, 결과값에 더 붙일 수 있는 알파벳을 체크해서 붙인 결과를 최종 리턴하게 된다. 31 | -------------------------------------------------------------------------------- /Python/codewars/039_rgb_to_hex_conversion.md: -------------------------------------------------------------------------------- 1 | # #39 RGB To Hex Conversion 2 | 3 | RGB 값을 받아서 문자열로 바꾼다. `0, 0, 0`을 받으면 '000000'을, `255, 255, 255`를 받으면 'FFFFFF'를 리턴하는 식이다. 4 | 5 | ## 1. 내 코드 6 | 7 | 간단하게 숫자 범위를 나누어서 16진수로 바꿔주었다. 8 | 9 | ```py 10 | def change(n): 11 | if n >= 0 and n <= 9: return '0' + str(n) 12 | elif n < 0: return '00' 13 | elif n > 255: return 'FF' 14 | else: return hex(n)[2:].upper() 15 | def rgb(r, g, b): 16 | r, g, b = change(r), change(g), change(b) 17 | return r + g + b 18 | ``` 19 | 20 | ## 2. 다른 답 21 | 22 | - 최고득표 해답이다. 훨씬 세련된 방식이다. round라는 람다를 만들었는데 min, max 함수를 적절히 활용해서 조건 분기를 대신했다. 23 | - format 활용 : `"{:02X}"` 24 | + `02` : 2칸 간격인데 공백은 0으로 채우겠다. 25 | + `X`는 16진수를 나타낸다. 26 | + [공식문서](https://docs.python.org/3/library/string.html#string-formatting)에 자세히 나와있다. format을 활용할 때 중괄호 `{ }` 안에 `:` 콜론 뒤는 스펙을 나타낸다. 즉 `'{:02X}'`는 `'%02X'`와 같은 의미다. 27 | 28 | ```py 29 | def rgb(r, g, b): 30 | round = lambda x: min(255, max(x, 0)) 31 | return ("{:02X}" * 3).format(round(r), round(g), round(b)) 32 | ``` 33 | -------------------------------------------------------------------------------- /Ruby_on_Rails/standard_controller_actions.md: -------------------------------------------------------------------------------- 1 | #Standard Controller Actions 2 | 참조 링크: [Codecademy article](https://www.codecademy.com/articles/standard-controller-actions) 3 | 4 | 루비 온 레일즈는 7가지 표준 컨트롤러 액션을 미리 정의해놨다. 코드카데미 루비 과정에서 '반복하지마!' 라고 말했듯이 데이터를 가공하고 보여주는 액션들이 일반적으로 많이 쓰이기 때문에 아예 디폴트로 설정해둔 것이다. 5 | 6 | ![standard_controller_actions](https://s3.amazonaws.com/codecademy-content/projects/3/seven-actions.svg) 7 | 8 | 위 표에서처럼(이걸 코드카데미에서 벡터 이미지로 만들어놨다. 헐 짱이다..) 총 7가지 액션이 존재한다. 데이터를 모두 보여주는 액션, 만드는 HTML form 창 보여주는 액션, 데이터 받아서 저장하는 액션, 특정 데이터 보여주는 액션, 특정 데이터 수정하는 form 보여주는 액션, 수정된 데이터 받아서 데이터 다시 저장하는 액션, 특정 데이터 지우는 액션 이렇게 7가지다. 9 | 10 | 즉 위 설명(표)순서대로 index, new, create, show, edit, update, destroy 액션이 만들어진다. 11 | 12 | ##사용법 13 | 7개 모든 액션을 routes에 적용하는 방법은 routes.rb에 다음 코드처럼 *resources*와 컨트롤러 명을 심볼 형태로 적어주면 된다. 14 | ```ruby 15 | # /config/routes.rb 16 | resources :messages # messages는 컨트롤러 명 17 | resources :signups, only [:index, :show] # signups 컨트롤러에 index, show 액션만 추가하고 싶다면 지정해줄 수 있다. 18 | ``` 19 | 위와 같이 routes.rb 파일을 수정한 후에 shell에다 *rake routes* 명령어 입력하면 끝. 20 | -------------------------------------------------------------------------------- /JavaScript/codewars/012_your_order_please.md: -------------------------------------------------------------------------------- 1 | # #12 Your order, please 2 | 3 | 문장을 매개변수로 받는데 각 단어에 단어의 순서를 의미하는 숫자가 끼어있다. 이 순서에 맞게 단어를 다시 재배열한다. 4 | 5 | ## 1. 내 코드 6 | 7 | ```js 8 | function order(words){ 9 | var result = []; 10 | words = words.split(' '); 11 | for (var i = 1; i < 10; i++) { 12 | for (var j in words) { 13 | if (words[j].indexOf(i) > -1) { 14 | result.push(words[j]); 15 | continue; 16 | } 17 | } 18 | } 19 | return result.join(' '); 20 | } 21 | ``` 22 | 23 | - 단어를 뽑아내고, 단어의 글자에 숫자가 포함되어있는지 검사한다. 24 | - 1이 있는지 단어 전체를 검사하고, 있으면 결과 array에 추가하는 방식이다. 25 | - 마지막에 합쳐서 리턴한다. 26 | 27 | ## 2. 다른 해답 28 | 29 | ```js 30 | function order(words){ 31 | return words.split(' ').sort(function(a, b){ 32 | return a.match(/\d/) - b.match(/\d/); 33 | }).join(' '); 34 | } 35 | ``` 36 | 37 | - 멋지다. 내가 for 반복을 중첩해서 사용한 것을 sort와 정규표현식을 통해 해결했다. 기가 막힌다. 38 | - split으로 단어를 구분해서 array로 만들었고 이것을 sort한다. sort의 기준은 정규표현식으로 단어에서 숫자를 매칭해서 뽑아냈고 그것을 뺄셈해서 순서를 오름차순으로 정했다. 39 | - 마지막으로 붙여서 리턴했다. 40 | - 다시 한 번 말하지만 정규표현식은 최고고, 위 답은 멋지다. 41 | -------------------------------------------------------------------------------- /Python/codewars/053_regex_validate_pin_code.md: -------------------------------------------------------------------------------- 1 | # #53 Regex validate PIN code 2 | 3 | 입력받은 문자열이 숫자로 이루어진 4자리 혹은 6자리 PIN 코드인지 확인해서 True, False를 리턴하는 문제다. 4 | 5 | ## 1. 내 코드 6 | 7 | ```py 8 | import re 9 | def validate_pin(pin): 10 | if len(pin) == 4 and re.match(r'\d{4}', pin): return True 11 | if len(pin) == 6 and re.match(r'\d{6}', pin): return True 12 | return False 13 | ``` 14 | 15 | - 만약 길이가 4이고, 정규표현식으로 숫자 4개가 match 된다면 True를 리턴한다. 6개인 경우도 동일하게 if문을 더 써줬다. 16 | - 두 개의 if문에 해당이 되지 않으면 마지막에 False를 리턴한다. 17 | 18 | ## 2. 다른 코드 19 | 20 | ### 2.1 최고 득표 21 | 22 | ```py 23 | def validate_pin(pin): 24 | return len(pin) in (4, 6) and pin.isdigit() 25 | ``` 26 | 27 | - 정규표현식을 안 쓰고 문제를 풀었다. pin의 길이가 4 또는 6일 경우를 튜플에 속하는지로 표현했고, `isdigit()` 함수를 통해 숫자인지 판별했다. 28 | - 머리 좋다. 29 | 30 | ### 2.2 정규표현식 간결화 31 | 32 | ```py 33 | import re 34 | def validate_pin(pin): 35 | return bool(re.match(r'^(\d{4}|\d{6})$',pin)) 36 | ``` 37 | 38 | - 내가 처음 원했던 정규표현식만을 활용한 코드다. 난 정규표현식의 앞 뒤에 `^ &`를 붙일 생각을 못했다. 그래서 len 함수를 안 쓰면 '1234aa'같은 것도 match돼서 문제였다. 39 | - 마지막에 `bool`로 형변환해서 리턴. 40 | -------------------------------------------------------------------------------- /Python/codewars/038_convert_camel_snake.md: -------------------------------------------------------------------------------- 1 | # #38 Convert PascalCase string into snake_case 2 | 3 | CamelCase 문자열을 snake_case 문자열로 형태를 바꾸는 문제다. 5급 짜리 문젠데 의외로 쉬웠다. 4 | 5 | ## 1. 내 코드 6 | 7 | ```py 8 | def to_underscore(string): 9 | if not isinstance(string, str): return str(string) 10 | result = [string[0].lower()] 11 | for c in string[1:]: 12 | if ord(c) >= 65 and ord(c) <= 90: 13 | result.append('_' + c.lower()) 14 | continue 15 | result.append(c) 16 | return ''.join(result) 17 | ``` 18 | 19 | - 매개변수가 문자열인지 확인하고 아니라면 바로 문자열화해서 리턴했다. 20 | - 첫 글자는 앞에 '_'를 붙일 필요가 없어서 소문자화해서 바로 결과 리스트에 넣었다. 21 | - 두 번째 문자부터 반복을 돌아서 대문자라면 앞에 '_'를 붙였다. 22 | - 만약 대문자가 아니면 바로 리스트에 넣었다. 23 | 24 | ## 2. 다른 해답 25 | 26 | ```py 27 | import re 28 | def to_underscore(string): 29 | return re.sub(r'(.)([A-Z])', r'\1_\2', str(string)).lower() 30 | ``` 31 | 32 | - 정규표현식 활용했다. 앞에 어떤 문자든 있어도 되는(개행문자 제외) 대문자 한 글자가 있다. 그 패턴을 찾는다. 앞에 글자를 넣는 이유는 첫 글자는 제외하기 위해서다. 33 | - 그룹을 backreference해서 첫 번째 그룹과 두 번째 그룹 사이에, 즉 어떤 앞선 어떤 글자와 대문자 사이에 '_'를 삽입한다. 34 | - 마지막에 소문자화하고 끝낸다. 35 | -------------------------------------------------------------------------------- /Python/codewars/064_linkedlist_04.md: -------------------------------------------------------------------------------- 1 | # #64 Linked Lists - Sorted Insert 2 | 3 | 이미 데이터를 기준으로 오름차순 정렬이 되어있는 링크드 리스트다. 여기서 data 하나를 올바른 위치에 끼워넣는 함수를 짜는 문제. 4 | 5 | ## 1. 내 코드 6 | 7 | ```py 8 | class Node(object): 9 | def __init__(self, data): 10 | self.data = data 11 | self.next = None 12 | 13 | def sorted_insert(head, data): 14 | if not head: return Node(data) 15 | if head.data <= data: 16 | if head.next: 17 | head.next = sorted_insert(head.next, data) 18 | return head 19 | else: 20 | head.next = Node(data) 21 | return head 22 | else: 23 | tmp = Node(data) 24 | tmp.next = head 25 | return tmp 26 | ``` 27 | 28 | - head가 None일 경우 바로 Node를 생성해서 리턴. 29 | - head의 데이터가 주어진 data보다 작은 경우, 즉 올바른 순서인 경우 재귀를 호출해서 다음 턴으로 넘긴다. 30 | + 다만 다음 노드가 있을 경우에만 넘긴다. 31 | + 만약 해당 노드가 마지막 노드였다면 다음 노드를 주어진 data로 새롭게 생성해서 next를 연결해 준 다음 리턴한다. 32 | + 재귀로 호출된 것은 이후의 링크드리스트이므로, 현재 시점의 head의 next로 정해주면 된다. 33 | - 주어진 data보다 큰 경우, 새롭게 Node를 생성하고, next를 현재 head로 지정해준 다음, 생성한 Node를 리턴해준다. 34 | -------------------------------------------------------------------------------- /JavaScript/codewars/018_convert_hex_to_rgb.md: -------------------------------------------------------------------------------- 1 | # #18 Convert A Hex String To RGB 2 | 3 | 5급 짜리 문젠데 엄청 쉬운거 나왔다. `#124232` 같은 색을 나타내는 rgb 문자열을 받아서 r, g, b int 값을 가지는 객체로 리턴하는 문제다. 4 | 5 | ## 1. 내 코드 6 | 7 | ```js 8 | function hexStringToRGB(hexString) { 9 | return { 10 | r : parseInt(hexString.slice(1, 3), 16), 11 | g : parseInt(hexString.slice(3, 5), 16), 12 | b : parseInt(hexString.slice(5), 16) 13 | } 14 | } 15 | ``` 16 | 17 | 단순하게 slice로 부분 부분 끊어서 16진수로 parseInt 썼다. 18 | 19 | ## 2. 다른 해답 20 | 21 | 가장 많이 나온 해답, 최고 득표 해답은 나와 같았고 아래와 같은 해답도 있었다. 22 | 23 | ```js 24 | function hexStringToRGB(hexString) { 25 | var rgb = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hexString); 26 | return { 27 | r: parseInt(rgb[1], 16), 28 | g: parseInt(rgb[2], 16), 29 | b: parseInt(rgb[3], 16) 30 | }; 31 | } 32 | ``` 33 | 34 | - 정규표현식 활용했다. `#` 이후부터 탐색을 시작하고, `a-f` 그리고 `숫자`가 2개만 나오는 그룹을 세 개 찾았다. 마지막에 `$`을 넣어서 문장의 끝임을 명시했고, `i`로 대소문자 구분을 없앴다. 35 | - `REGEX.exec(str)` : 정규표현식을 매개변수의 문자열에 적용시키는 함수다. 36 | - 그래서 결과값을 하나씩 객체에 담아 리턴한다. rgb의 첫 번째 원소는 매칭된 전체 문자열이다. 그래서 인덱스가 1, 2, 3이다. 37 | -------------------------------------------------------------------------------- /Python/Django/010_image_file.md: -------------------------------------------------------------------------------- 1 | # #10 이미지 파일 관리하기 2 | 3 | 'Photo 모델로 Admin 영역에서 데이터 다루기' [글](http://blog.hannal.com/2014/10/start_with_django_webframework_04/)이다. 4 | 5 | ## 1. 이미지 파일을 admin에서 관리해보기 6 | 7 | - photo app의 `admin.py`에서 `admin.site.register(Photo)` 추가 8 | - `models.py`에서 이미지 파일 경로 추가 9 | 10 | ```py 11 | image_file = models.ImageField(upload_to='static_files/uploaded/original/%Y/%m/%d') 12 | filtered_image_file = models.ImageField(upload_to='static_files/uploaded/filtered/%Y/%m/%d') 13 | ``` 14 | 15 | - Photo 클래스의 객체가 지워지면 파일도 지워지도록 하려면 Photo 클래스의 `delete` 메소드를 오버라이드해주면 된다. 원래 models.Model에 있는 메소드다. 16 | 17 | ```python 18 | class Photo(models.Model): 19 | def delete(self, *args, **kwargs): 20 | self.image_file.delete() 21 | self.filtered_image_file.delete() 22 | super(Photo, self).delete(*args, **kwargs) 23 | ``` 24 | 25 | ## 2. 추가 개념 정리 26 | 27 | - photo app의 admin.py 파일을 수정하고 저장하면 파이썬 내장 웹서버가 자동으로 재실행된다. 28 | - 예를 들어 created_at 필드처럼 자동 입력이 되도록 해놓았으면 admin 페이지에서 새 객체를 추가하려고 할 때 입력 폼이 나타나지 않는다. 29 | - TextField에서 blank 옵션을 True로 주면 빈 칸으로 저장해도 오류를 띄우지 않는다. 30 | -------------------------------------------------------------------------------- /Ruby_on_Rails/ProjectEuler/LICENSE.md: -------------------------------------------------------------------------------- 1 | Copyright (c) 2015 Gyubin Son 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in 11 | all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE. -------------------------------------------------------------------------------- /Ruby_on_Rails/Coderbyte/LICENSE.md: -------------------------------------------------------------------------------- 1 | Copyright (c) 2015 Gyubin Son 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in 11 | all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE. 20 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Gyubin Son 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /Python/codewars/051_pete_the_baker.md: -------------------------------------------------------------------------------- 1 | # #51 Pete, the baker 2 | 3 | recipe dictionary, available dictionary 두 객체를 매개변수로 받는다. 가능한 재료 중에서 레시피를 몇 개나 만들 수 있는지 리턴하는 문제. 4 | 5 | ## 1. 내 코드 6 | 7 | ```py 8 | def cakes(recipe, available): 9 | result = -1 10 | for k in recipe: 11 | if k in available: 12 | hey = available[k] / recipe[k] 13 | if result == -1: result = hey 14 | if hey == 0: return 0 15 | if hey < result: result = hey 16 | else: 17 | return 0 18 | return result 19 | ``` 20 | 21 | - 레시피에서 key를 뽑아서, 만약 key가 available에 없으면 바로 0을 리턴한다. 22 | - 만약 재료에 있다면 재료량을 조리법량으로 나눈다. 이 값이 최대로 만들 수 있는 전체 요리량이다. 23 | - 첫 result 값을 -1로 줘서 처음엔 무조건 대입되도록 하고, 0이 대입되면 바로 0을 리턴한다. 반복을 돌면서 최대 요리량이 result보다 작다면 result 값을 갱신해준다. 전체 반복을 돈 후에 result를 리턴한다. 24 | 25 | ## 2. 다른 해답 26 | 27 | ```py 28 | def cakes(recipe, available): 29 | return min([available.get(k,0)/v for k,v in recipe.iteritems()]) 30 | ``` 31 | 32 | - recipe에서 키, 밸류를 뽑아서 for 내포 리스트를 만든다. 33 | - 리스트에 적용될 값은 available에서 키로 값을 뽑는데 만약 없다면 0을 리턴해야하므로 get 함수를 썼다. 이 값을 밸류로 나눈 값이다. 34 | - 이렇게 만들어진 함수에서 가장 작은 값을 리턴한다. 35 | - 매우 머리가 좋다. 36 | -------------------------------------------------------------------------------- /Python/codewars/008_sequence_sum.md: -------------------------------------------------------------------------------- 1 | # #8 Sequence Sum 2 | 0부터 입력받은 정수까지 각 숫자 당 합을 원소로 하는 리스트를 리턴한다. 설명이 어렵다. 즉 3을 입력 받으면 [0, 1, 3, 6]이고, -2를 입력받으면 [0, -1, -3]을 리턴해야 한다. 3 | 4 | ## 1. 내 코드 5 | 6 | 원래는 n이 0 이상인지 if 문으로 분기해서 코드를 따로 썼었는데 절대값으로 바꾸는 abs()를 써서 한 줄로 쓰는 것으로 바꿨다. 그런데 꼭 한 줄로 짧게 적는게 이해하기 좋은 코드는 아닐 수도 있겠다. 7 | 8 | 리스트 내포를 사용했다. 정수를 절대값으로 바꿔서 range 함수로 리스트를 만들었다. 만들어진 리스트의 원소를 i로 받아서 다시 range 리스트를 만들어서 합을 구했다. 9 | 10 | ```python 11 | def sum_of_n(n): 12 | return [sum(range(i+1)) * (1 if n >= 0 else -1) for i in range(abs(n)+1)] 13 | 14 | # 원래 코드 15 | # if n >= 0: 16 | # return [sum(range(i+1)) for i in range(n+1)] 17 | # else: 18 | # return [sum(range(i+1))*-1 for i in range((n-1)*-1)] 19 | ``` 20 | 21 | ## 2. 다른 해답 22 | 23 | 내가 참고한 코드. abs 사용한 것을 내 코드에도 적용했다. 이 분은 xrange를 썼는데 range와 거의 활용도는 같지만 list를 리턴하는게 아니라 xrange 객체를 리턴하는 함수다. 메모리를 절약할 수 있다고 한다. 즐겨 써야겠다. 24 | 25 | - xrange(stop): 이 형태로 쓰면 range와 똑같다. 26 | - xrange(start, stop[, step]): 이 형태로 쓰면 시작과 끝을 지정할 수 있고, 간격도 설정할 수 있다. 간격은 써도 되고 안 써도 된다. 27 | 28 | ```python 29 | def sum_of_n(n): 30 | return [(-1 if n < 0 else 1) * sum(xrange(i+1)) for i in xrange(abs(n)+1)] 31 | ``` 32 | -------------------------------------------------------------------------------- /Algorithm/exercises/recursive_power.md: -------------------------------------------------------------------------------- 1 | # Power function with recursion 2 | 3 | ## 1. 재귀용법으로 거듭제곱 구하기 4 | 5 | ```py 6 | def getPower(m, n): 7 | if n == 0: 8 | return 1 9 | tmp = getPower(m, n // 2) 10 | if n % 2 == 0: 11 | return tmp * tmp 12 | else: 13 | return m * tmp * tmp 14 | ``` 15 | 16 | - `A^2 * A^4`는 `A^(2+4)` 로 표현할 수 있다. 이 원리를 구현한 것이다. 17 | - 만약 2의 10 제곱을 구한다 하면: `2^5`의 제곱을 구하고, `2^5`는 `2^2`의 제곱에 2를 한 번 곱해주는 것으로 구하는 식으로 계속 아래로 내려가면 된다. 18 | - 즉 지수가 짝수인지 홀수인지 따라 분기해서 처리하면 됨. 간단하지만 강력한 알고리즘 19 | 20 | ## 2. 거듭제곱의 나머지 구하기 21 | 22 | ```py 23 | LIMIT_NUMBER = 1000000007 24 | 25 | def getPower(m, n): 26 | if n == 0: 27 | return 1 28 | tmp = getPower(m, n // 2) 29 | if n % 2 == 0: 30 | return tmp * tmp % LIMIT_NUMBER 31 | else: 32 | return m * tmp * tmp % LIMIT_NUMBER 33 | ``` 34 | 35 | - m의 n 제곱을 LIMIT_NUMBER로 나눈 나머지를 구하는 것이다. 36 | - 위 1번 코드와 같은 원리인데 매번 리턴할 때 나머지만 리턴한다. 37 | - 원리는 다음과 같다. 예를 들어 2의 5제곱을 5로 나눈다고 하자. 38 | + 2의 3제곱부터 5보다 커지게 된다. `2^3 = 8 = 5 + 3` 39 | + 2의 4제곱이라면 위 식에서 `2^4 = 16 = 5*2 + 3*2` 처럼 양 변에 2를 곱해준 것이 된다. 보면 어차피 나머지가 아닌 부분은 5의 배수이므로 계산할 필요가 없다. 계속 나머지만 계산해나가면 됨 40 | -------------------------------------------------------------------------------- /JavaScript/codewars/019_array_helpers.md: -------------------------------------------------------------------------------- 1 | # #19 Array Helpers 2 | 3 | Array에서 바로 dot notation으로 호출할 수 있는 함수들을 만드는 것. square, sum, cube, average, even, odd를 새로 내가 만들면 된다. 4 | 5 | ## 1. 내 코드 6 | 7 | ```js 8 | Array.prototype.square = function() { 9 | return this.map(function(e) { 10 | return e*e; 11 | }); 12 | } 13 | 14 | Array.prototype.cube = function() { 15 | return this.map(function(e) { 16 | return e*e*e; 17 | }); 18 | } 19 | 20 | Array.prototype.average = function() { 21 | if (this.length === 0) return NaN; 22 | return this.sum() / this.length; 23 | } 24 | 25 | Array.prototype.even = function() { 26 | return this.filter(function(e){ 27 | if (!(e % 2)) return e; 28 | }); 29 | } 30 | 31 | Array.prototype.sum = function() { 32 | return this.reduce(function(prev, cur) { 33 | return prev + cur; 34 | }); 35 | } 36 | 37 | Array.prototype.odd = function() { 38 | return this.filter(function(e){ 39 | if (e % 2) return e; 40 | }); 41 | } 42 | ``` 43 | 44 | - Array의 prototype에다가 함수를 하나하나 만들면 된다. 45 | - map, reduce, filter를 적절하게 썼고 다른 답과 똑같았다. 46 | - 하나 달랐던건 average 함수에서 Array 원소가 없을 때 예외처리인데 굳이 NaN을 따로 리턴하지 않아도 계산식에서 자연스럽게 NaN 결과가 나간다. 47 | -------------------------------------------------------------------------------- /Python/Django/source/django_girls_blog_tutorial/static/admin/img/gis/move_vertex_off.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /Python/Django/source/django_girls_blog_tutorial/static/admin/img/gis/move_vertex_on.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /Python/Django/source/django_girls_blog_tutorial/static/admin/img/icon-calendar.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /Python/codewars/026_counting_duplicates.md: -------------------------------------------------------------------------------- 1 | # #26 Counting duplicates 2 | 3 | 매개변수로 받은 문자열에서 중복되는 알파벳이 몇 개인지 리턴하는 문제다. 대소문자 구별하지 않는다. 4 | 5 | ## 1. 내 코드 6 | 7 | 최고 득표 해답과 살짝 다르다. 뭐 똑같네 하고 다시 보다가 반복 회수가 나보다 적더라. 내 코드 아래에 붙여넣었다. 대소문자를 구별하지 않으므로 upper를 활용했고, 하나씩 뽑아서 count 함수를 활용해 1보다 크면 리스트에 넣었다. 그리고 그것을 set으로 만들어서 길이를 리턴했다. 최고득표 해답은 애초에 반복문 돌릴 때 set을 활용하더라. 반복이 얼마나 많이 있느냐에 따라서 반복회수가 내 답보다 적어진다. 머리 좋다! 8 | 9 | ```python 10 | # 내꺼 11 | def duplicate_count(text): 12 | return len(set([c for c in text.upper() if text.upper().count(c) > 1])) 13 | 14 | # 최고 득표 15 | def duplicate_count(text): 16 | return len([c for c in set(text.lower()) if text.lower().count(c) > 1]) 17 | ``` 18 | 19 | ## 2. 다른 해답 20 | 21 | Counter 클래스를 활용했다. lower를 적용한 텍스트로 Counter 객체를 만들고 내장함수인 iteritems 메소드로 문자와 문자 개수 딕셔너리 객체를 하나하나 리턴했다. 그래서 개수가 1보다 크면 1을 리스트에 넣고 최종 sum을 한 코드다. 22 | 23 | 근데 이건 python2에서만 작동한다. python3에선 iteritems 대신 items()를 활용하면 된다. 주석 참조 24 | 25 | ```python 26 | from collections import Counter 27 | 28 | def duplicate_count(text): 29 | return sum(1 for c, n in Counter(text.lower()).iteritems() if n > 1) 30 | # return sum(1 for c, n in Counter(text.lower()).items() if n > 1) 31 | ``` 32 | -------------------------------------------------------------------------------- /JavaScript/codewars/026_regex_count_lowercase_letters.md: -------------------------------------------------------------------------------- 1 | # #26 Regex count lowercase letters 2 | 3 | 정규 표현식으로 소문자가 몇 개인지 리턴하는 문제다. 4 | 5 | ## 1. 내 코드 6 | 7 | ```js 8 | function lowercaseCount(str){ 9 | var re = /[a-z]/g; 10 | var cnt = 0; 11 | while(re.exec(str)) { 12 | cnt += 1; 13 | } 14 | return cnt; 15 | } 16 | ``` 17 | 18 | - 정규표현식 객체를 소문자 중 아무거나 하나로 지정하고 global 옵션을 넣는다. g 옵션은 ~all 같은 개념이다. searchAll, matchAll 이런식으로 문자열 전체에서 매칭되는 값을 찾는다. exec에서는 이미 찾은 것은 넘어가고 다음 것을 찾아 리턴한다. 19 | - cnt 변수를 선언해두고 찾아질 때마다 1씩 플러스한다. while 반복문의 조건은 str에서 re와 매칭되는 문자열이 있다면 그것에 대한 정보를 배열로 리턴하는 것이다. global 옵션을 주었고 찾아지면 다음 걸로 넘어가니까 마지막까지 찾아지면 리턴값이 없어서 while 반복문을 빠져나오게 된다. 20 | 21 | ## 2. 다른 해답 22 | 23 | ### A. 최고 득표 24 | 25 | g옵션으로 match를 실행시켰기 때문에 모든 매칭 문자열을 배열에 담아 리턴한다. 만약 매칭이 없다면 null을 리턴하는데 이 때 빈 배열을 `||` 연산하여 빈 배열이 리턴되게 한다. 마지막에 length를 리턴. 26 | 27 | ```js 28 | function lowercaseCount(str){ 29 | return (str.match(/[a-z]/g) || []).length 30 | } 31 | ``` 32 | 33 | ### B. 다음 득표 34 | 35 | 맨 앞에 `^`를 주어 소문자 알파벳이 '아닌' 것들을 g 옵션으로 모두 골랐다. 그리고 그 것을 빈 문자열로 바꾼다. 즉 없앴다. 그리고 문자열 자체의 length를 리턴했다. 36 | 37 | ```js 38 | const lowercaseCount = str => str.replace(/[^a-z]/g, '').length; 39 | ``` 40 | -------------------------------------------------------------------------------- /JavaScript/codewars/002_sort_with_arrow_function.md: -------------------------------------------------------------------------------- 1 | # #2 Sort with arrow function 2 | 3 | age, name 속성을 가진 Objects가 들어있는 리스트를 매개변수로 받고, age 속성에 따라서 Objects를 오름차순으로 정렬하는 함수다. 4 | 5 | ## 1. 내 코드 6 | 7 | ```js 8 | var OrderPeople = function(people){ 9 | return people.sort(function(a, b){return a.age - b.age}); 10 | } 11 | ``` 12 | 13 | ## 2. 다른 해답 14 | 15 | ```js 16 | var OrderPeople = function(people){ 17 | return people.sort((a,b) => a.age - b.age ); 18 | } 19 | ``` 20 | 21 | - sort 함수의 매개변수에 순서 정렬 기준을 의미하는 함수를 넣을 수 있다. 22 | - arrow function: 함수 표현식의 축약형이다. 아래처럼 쓰면 된다. [참고링크](https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Functions/%EC%95%A0%EB%A1%9C%EC%9A%B0_%ED%8E%91%EC%85%98) 23 | 24 | ```js 25 | // 기본 문법: 26 | (파라미터1, 파라미터2, 파라미터N) => { 구문 } 27 | (파라미터1, 파라미터2, 파라미터N) => 표현식 28 | // 괄호 생략시, 표현식은 return 구문으로 취급된다: => { return 표현식; } 29 | 30 | // 파라미터가 한 개인 경우, 파라미터의 괄호는 생략될 수 있다: 31 | 유일파라미터 => { 구문 } 32 | 유일파라미터 => 표현식 33 | 34 | // 파라미터가 하나가 없는 경우, 파라미터 괄호는 반드시 표기해야 한다: 35 | () => { 구문 } 36 | 37 | // 고급: 38 | // 본문을 괄호로 감싸 객체 표현식을 린턴하게 할 수 있다: 39 | 파라미터들 => ({foo: bar}) 40 | 41 | // 레스트 파라미터(가변 파라미터)를 사용할 수 있다. 42 | (파라미터1, 파라미터2, ...가변파라미터) => { 구문 } 43 | ``` 44 | -------------------------------------------------------------------------------- /C/list.md: -------------------------------------------------------------------------------- 1 | # List - Data Structure 2 | 3 | ## 0. 개념 4 | 5 | - 자료를 순서대로 저장한다. 6 | - 배열 리스트, 연결리스트 두 종류 존재. 7 | - 추상 자료형 8 | + `list creat_list(int len);`: 최대 원소 개수를 입력받아 리스트 만들어 리턴 9 | + `void delete_list(list l);`: 지우기 10 | + `int is_full(list l);`: 리스트가 꽉 찼는지 T/F로 리턴 11 | + `int add_element(list l, int p, void *data);`: 데이터를 p 인덱스에 추가하고 성공 실패를 리턴 12 | + `int remove_element(list l, int p);`: 리스트에서 p 인덱스 원소 제거 후 성공/실패 리턴 13 | + `void clear_list(list l);`: 리스트 모든 원소 제거 14 | + `int get_list_length(list l);`: 리스트 원소 개수 리턴 15 | + `void *get_element(list l, int p);` 리스트에서 특정 인덱스의 원소 리턴 16 | + `void display_list(list l);`: 모든 원소 출력. 디버깅용. 17 | 18 | ## 1. Array list 19 | 20 | - 배열을 활용 21 | - 원소 추가: 뒤 원소들을 모두 한 칸씩 뒤로 이동시켜야 22 | - 원소 제거: 제거한 원소의 우측 원소들을 한칸 씩 당겨야 23 | 24 | ```c 25 | #ifndef __ARRAY_LIST_H 26 | # define __ARRAY_LIST_H 27 | 28 | typedef struct array_list_node_type 29 | { 30 | int data; 31 | } array_list_node; 32 | 33 | typedef struct array_list_type 34 | { 35 | int max_element_count; 36 | int current_element_count; 37 | array_list_node *ptr_element; 38 | } array_list; 39 | 40 | #endif 41 | ``` 42 | 43 | ## 2. Linked list 44 | -------------------------------------------------------------------------------- /Python/Django/source/django_girls_blog_tutorial/static/admin/img/calendar-icons.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /JavaScript/codewars/029_sum_all_the_arrays.md: -------------------------------------------------------------------------------- 1 | # #29 Sum ALL the arrays 2 | 3 | 배열의 원소를 모두 합한 결과를 리턴한다. 매개변수로 들어오는 배열의 원소가 배열일 수도 있고, 문자열일 수도 있다. 4 | 5 | ## 1. 내 코드 6 | 7 | ```js 8 | function arraySum(arr) { 9 | return arr.reduce(function (p, c) { 10 | if (typeof c === 'string' || typeof c === 'function') { c = 0; } 11 | if (typeof c === "object") { c = arraySum(c); } 12 | return p+c; 13 | }, 0); 14 | } 15 | ``` 16 | 17 | - `reduce` 함수를 활용해서 합한 값을 리턴했다. 가장 기본적인 것이고 모든 원소가 숫자면 이것으로도 동작한다. 18 | - 하지만 원소에 문자열, 배열, 함수가 들어올 수도 있다. 그래서 배열일 경우엔 재귀로 함수를 다시 호출했고, 다른 경우엔 값을 0으로 해서 결국 더하는 값을 없게 했다. 19 | 20 | ## 2. 다른 해답 21 | 22 | ### 2.1 23 | 24 | ```js 25 | function arraySum(arr) { 26 | var output = 0; 27 | for (var i in arr) { 28 | var item = arr[i]; 29 | if ( typeof(item) === "number" ) { output += item; } 30 | if ( item.constructor === Array ) { output += arraySum(item); } 31 | } 32 | return output; 33 | } 34 | ``` 35 | 36 | 내부 원리는 똑같고, 내가 reduce를 쓴 것과 다르게 for 문으로 반복 돌렸다. 37 | 38 | ### 2.2 39 | 40 | ```js 41 | function arraySum(arr) { 42 | return arr.reduce((n, x) => n + (Array.isArray(x) ? arraySum(x) : isNaN(x) ? 0 : x), 0) 43 | } 44 | ``` 45 | 46 | 내 코드를 짧게 줄인 것. 47 | -------------------------------------------------------------------------------- /Python/codewars/020_camel_case.md: -------------------------------------------------------------------------------- 1 | # #20 Convert string to camel case 2 | '-', '_'를 기준으로 camel case 형태로 문자열을 바꿔서 리턴하는 문제다. 맨 앞 글자는 굳이 대문자로 바꾸지 않고 원래 형태를 따른다. 3 | 4 | ## 1. 내 코드 5 | '-'를 '_'로 모두 바꾼 후 언더바를 기준으로 split했다. 그리고 첫 단어는 건드릴 필요 없으니 바로 넣고, 나머지 단어들을 capitalize 해서 join 후 첫 단어와 + 연산했다. 6 | 7 | ```python 8 | def to_camel_case(text): 9 | text = text.replace('-', '_').split('_') 10 | return text[0] + ''.join(word.capitalize() for word in text[1:]) 11 | ``` 12 | 13 | ## 2. 다른 해답 14 | 15 | ### A. 최고 득표. 내가 처음 원했던 흐름 16 | 이렇게 하고자 했지만, 구현을 못했다. 좋은 걸 배웠다. 17 | 18 | - 정규표현식을 사용했다. 정규표현식에 split이 있었다. 그냥 split에 어떻게 정규표현식을 적용하지 고민했었는데 여기에 답이 있었다. re.split(pattern, text) 형태로 넣어주면 된다. 19 | - reduce 역시 사용하고자 했는데 앞에 함수 부분에 join이나 capitalize를 어떻게 넣어야할지 고민했다. 람다를 사용하면 됐다. 20 | + reduce는 function, iterable, initializer 세 가지 매개변수를 받는다. 이 중에서 function과 iterable만 매개변수로 들어왔다. 21 | + iterable의 첫, 두번째 원소가 p, n으로 적용된다. p는 그냥 두고, n만 capitalize 해준다. 그리고 이 두 문자열을 + 연산한 값이 다음 p로 들어가고, iterable의 그 다음 원소가 n으로 되서 끝까지 반복한다. 22 | 23 | ```python 24 | import re 25 | def to_camel_case(text): 26 | return reduce(lambda p,n: p + n[0].upper() + n[1:], re.split('[-_]', text)) 27 | # 패턴을 이렇게 해도 된다. re.split('_|-', text) 28 | ``` 29 | -------------------------------------------------------------------------------- /Python/Django/source/django_girls_blog_tutorial/static/admin/img/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 Code Charm Ltd 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | this software and associated documentation files (the "Software"), to deal in 7 | the Software without restriction, including without limitation the rights to 8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | the Software, and to permit persons to whom the Software is furnished to do so, 10 | subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /Python/codewars/049_WeIrD_StRiNg_CaSe.md: -------------------------------------------------------------------------------- 1 | # #49 WeIrD StRiNg CaSe 2 | 3 | 문자열을 입력받아서 공백으로 구분된 단어 별로 문자 단위 CamelCase를 적용하는 문제다. 이 파일 제목같이. 4 | 5 | ## 1. 내 코드 6 | 7 | ```py 8 | def to_weird_case(string): 9 | result = [] 10 | for word in string.split(' '): 11 | for i, c in enumerate(word): 12 | if i % 2 : result.append(c.lower()) 13 | else: result.append(c.upper()) 14 | result.append(' ') 15 | return ''.join(result[:-1]) 16 | ``` 17 | 18 | - 중첩 for 문을 사용했다. 우선 단어로 구분하고, 단어에서 인덱스에 따라 대문자화할지 소문자화할지 정했다. 19 | - 합칠 때는 단어 간 공백도 필요하므로 내부 for 문이 끝날 때마다 공백을 추가해줬는데 마지막 리턴할 때는 끝의 공백은 필요없으므로 제외하고 붙여서 리턴했다. 20 | 21 | ## 2. 다른 해답 22 | 23 | 원리는 나와 같다. word 단위로 함수를 짜고, ' ' 단위로 join한 것이 나와 다르다. 24 | 25 | ```py 26 | # 첫 번째 27 | def to_weird_case_word(string): 28 | return "".join(c.upper() if i%2 == 0 else c for i, c in enumerate(string.lower())) 29 | def to_weird_case(string): 30 | return " ".join(to_weird_case_word(str) for str in string.split()) 31 | 32 | # 두 번째 33 | def to_weird_case(string): 34 | recase = lambda s: "".join([c.upper() if i % 2 == 0 else c.lower() for i, c in enumerate(s)]) 35 | return " ".join([recase(word) for word in string.split(" ")]) 36 | ``` 37 | -------------------------------------------------------------------------------- /Go/go_fundamental.md: -------------------------------------------------------------------------------- 1 | # Go 2 | 3 | ## 0. 설치 4 | 5 | 참고 링크: [vsouza gist](https://gist.github.com/vsouza/77e6b20520d07652ed7d) 6 | 7 | - `.zshrc` or `.bashrc` 파일에 추가 8 | 9 | ```sh 10 | export GOPATH=$HOME/golang 11 | export GOROOT=/usr/local/opt/go/libexec 12 | export PATH=$PATH:$GOPATH/bin 13 | export PATH=$PATH:$GOROOT/bin 14 | ``` 15 | 16 | - `install.sh` 파일을 다음 코드로 만들어서 실행 17 | 18 | ```sh 19 | echo "Please enter your golang path (ex: $HOME/golang) :" 20 | read gopath 21 | 22 | echo "Please enter your github username (ex: vsouza) :" 23 | read user 24 | 25 | 26 | mkdir $gopath 27 | mkdir -p $gopath/src/github.com/$user 28 | 29 | export GOPATH=$gopath 30 | export GOROOT=/usr/local/opt/go/libexec 31 | export PATH=$PATH:$GOPATH/bin 32 | export PATH=$PATH:$GOROOT/bin 33 | 34 | /usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)" 35 | brew update 36 | brew install go 37 | brew install git 38 | brew install mercurial 39 | 40 | go get golang.org/x/tools/cmd/godoc 41 | go get golang.org/x/tools/cmd/vet 42 | 43 | echo "go to https://golang.org/doc/code.html and enjoy :D" 44 | ``` 45 | -------------------------------------------------------------------------------- /Python/codewars/017_sum_of_many_ints.md: -------------------------------------------------------------------------------- 1 | # #17 Sum of many ints 2 | f(n, m) 형태로 두 개의 자연수를 입력받는 함수가 있다. 1부터 n까지 m으로 나눈 나머지를 모두 더한 값을 리턴해야 한다. 그냥 일반적으로 코드를 짜면 너무나 큰 수가 입력되기에 시간 제한으로 합격이 안된다. 3 | 4 | ## 1. 내 코드 5 | n, m으로 들어오는 입력값이 자연수임에도 불구하고 float형태로 들어온다. 그래서 처음에 정수화 해줬다.(처음에 xrange 썼다가 자꾸 float 에러나서 매우 어이가 없었다. 근데 생각해보니 결국 xrange 안썼으니 안바꿔줘도 되는 것 같다.) 그리고 1부터 n까지 자연수의 합은 n(n+1)/2 라는 유명한 공식을 활용해서 각각 적용했다. 6 | 7 | ```python 8 | def f(n, m): 9 | n = int(n) 10 | m = int(m) 11 | 12 | if n < m: 13 | return n*(n+1)/2 14 | elif n == m: 15 | return n*(n+1)/2 - n 16 | else: 17 | sum = (m-1)*m/2 18 | multiplier = n / m 19 | sum *= multiplier 20 | a = n % m 21 | sum += a*(a+1)/2 22 | return sum 23 | ``` 24 | 25 | ## 2. 최고득표. divmod 26 | 이 문제가 한 줄로 짤 수 있는 거였구나 자괴감을 느꼈다. 좀 더 분발해야지. 27 | 28 | - n을 m으로 나눈 몫과 나머지를 re, c 변수에 담는다. 29 | - 1부터 m-1까지의 합에다 몫을 곱하고, 1부터 나머지까지의 수의 합을 더한다. 30 | - 기가 막힌다!!!!!!!!!! 31 | 32 | ```python 33 | def f(n, m): 34 | re, c = divmod(n,m) 35 | return m*(m-1)/2*re + (c+1)*c/2 36 | ``` 37 | 38 | >읽는 순서대로 쭉쭉 단순하게 이해되는 코드는 변형이나 가독성이나 재사용성에 있어서는 좋은 것 같다. 하지만 성능은 안좋을 수도 있다. 좀 더 압축적으로 단계를 건너뛰어 짧은 연산으로 빠르게 문제를 해결하는게 알고리즘이구나 생각이 들었다. 39 | -------------------------------------------------------------------------------- /Python/Django/source/django_girls_blog_tutorial/static/admin/img/sorting-icons.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /Python/Django/source/django_girls_blog_tutorial/blog/migrations/0001_initial.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # Generated by Django 1.9 on 2015-12-06 08:26 3 | from __future__ import unicode_literals 4 | 5 | from django.conf import settings 6 | from django.db import migrations, models 7 | import django.db.models.deletion 8 | import django.utils.timezone 9 | 10 | 11 | class Migration(migrations.Migration): 12 | 13 | initial = True 14 | 15 | dependencies = [ 16 | migrations.swappable_dependency(settings.AUTH_USER_MODEL), 17 | ] 18 | 19 | operations = [ 20 | migrations.CreateModel( 21 | name='Post', 22 | fields=[ 23 | ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), 24 | ('title', models.CharField(max_length=200)), 25 | ('text', models.TextField()), 26 | ('created_date', models.DateTimeField(default=django.utils.timezone.now)), 27 | ('published_date', models.DateTimeField(blank=True, null=True)), 28 | ('author', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)), 29 | ], 30 | ), 31 | ] 32 | -------------------------------------------------------------------------------- /C/algorithm/003_atoi.md: -------------------------------------------------------------------------------- 1 | # 003 atoi - alphabet(?) to integer 2 | 3 | ## 1. 문제 4 | 5 | atoi의 a가 알파벳을 의미하는게 맞는지 모르겠다. 문자열 타입으로 정수를 입력받아서 정수로 타입을 바꿔서 리턴하는 문제다. 음수 체크해야하고 만약 `123a324` 형태라면 a 직전까지 계산하면 된다. 즉 123. 6 | 7 | ## 2. 코드 8 | 9 | ```c 10 | int my_pow(int base, int exp) 11 | { 12 | int result; 13 | 14 | result = 1; 15 | while (exp > 0) 16 | { 17 | result *= base; 18 | exp--; 19 | } 20 | return (result); 21 | } 22 | 23 | int ft_atoi(char *str) 24 | { 25 | int result; 26 | int digit; 27 | int is_negative; 28 | 29 | is_negative = 0; 30 | if (*str == '-') 31 | { 32 | is_negative = 1; 33 | str++; 34 | } 35 | digit = 0; 36 | while (*str <= '9' && *str >= '0') 37 | { 38 | digit++; 39 | str++; 40 | } 41 | str -= digit; 42 | result = 0; 43 | while (*str <= '9' && *str >= '0') 44 | { 45 | result += (*str - '0') * my_pow(10, digit - 1); 46 | digit--; 47 | str++; 48 | } 49 | return (is_negative ? result * -1 : result); 50 | } 51 | ``` 52 | 53 | - 먼저 첫 글자를 확인해서 `-`라면 미ㅣㄹ 체크를 해둔다. 최종 결과에 -1을 곱하기 위해. 54 | - 문자가 숫자 이외의 것이라면 그 직전까지만 반복을 돈다. 55 | - 먼저 자리수를 구하고 각 자리마다 자리수를 이용해서 10의 제곱을 곱한다음 결과값에 더한다. 56 | -------------------------------------------------------------------------------- /Python/Django/source/django_girls_blog_tutorial/static/admin/js/vendor/xregexp/LICENSE-XREGEXP.txt: -------------------------------------------------------------------------------- 1 | The MIT License 2 | 3 | Copyright (c) 2007-2012 Steven Levithan 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /Python/codewars/050_format_a_string_of_names.md: -------------------------------------------------------------------------------- 1 | # #50 Format a string of names like 'Bart, Lisa & Maggie' 2 | 3 | key가 'name'이고 value에 이름이 들어있는 dict가 여럿 들어있는 리스트를 매개변수로 받는다. 이 이름들을 comma로 연결시켜서 문자열을 리턴하는데 마지막 둘은 ampersand로 연결해야한다. 4 | 5 | ## 1. 내 코드 6 | 7 | ```py 8 | def namelist(names): 9 | temp = [o['name'] for o in names] 10 | if len(temp) <= 0: return '' 11 | elif len(temp) == 1: return ''.join(temp) 12 | elif len(temp) == 2: return ' & '.join(temp) 13 | else: return ', '.join(temp[:-1]) + ' & ' + temp[-1] 14 | ``` 15 | 16 | - dict에서 name만 뽑아서 리스트로 만들었다. 17 | - 이 리스트의 길이에 따라서 조건을 걸었다. 0보다 작으면 빈문자열, 1이면 그냥 리턴, 2면 ampersand로 연결, 그 이상일 때는 마지막 원소 제외하고 콤마로 연결한 다음 마지막만 ampersand로 연결했다. 18 | 19 | ## 2. 다른 해답 20 | 21 | ```py 22 | def namelist(names): 23 | if len(names) > 1: 24 | return '{} & {}'.format(', '.join(name['name'] for name in names[:-1]), 25 | names[-1]['name']) 26 | elif names: 27 | return names[0]['name'] 28 | else: 29 | return '' 30 | ``` 31 | 32 | - 첫 번째 조건만 본다. 33 | - `'{} & {}'.format(string, string)` : 문자열 안에 중괄호가 들어있을 때 `format` 함수를 호출하면 매개변수의 값이 중괄호에서 대체된다. 34 | - 첫 번째 매개변수는 마지막 원소를 제외한 모든 이름들을 comma로 연결한 문자열이고 35 | - 두 번째는 마지막 원소의 이름 값이다. 36 | - 앞부분과 뒷부분을 ampersand로 이었다. 37 | -------------------------------------------------------------------------------- /HTML-CSS/purecss_fundamental.md: -------------------------------------------------------------------------------- 1 | # Pure.css 2 | 3 | 참고 링크: [seoh.github.io](http://seoh.github.io/pure-site/grids.html), [공식 홈페이지](http://purecss.io/start/) 4 | 5 | 부트스트랩 말고 다른거 써보고싶어서 선택한 css 모듈이다. js 없이 오직 css로만 구성되어있어서 가볍고 빠르다. 그리고 뭔가 디자인이 예쁘다. 6 | 7 | ## 0. 설치 8 | 9 | - CDN 사용 10 | 11 | ```html 12 | 13 | ``` 14 | 15 | - 직접 호스팅: 경로에 맞게 링크하기. 16 | 17 | ```sh 18 | # 두 코드 중에 아무거나 터미널에서 실행 19 | bower install --save pure 20 | npm install purecss 21 | ``` 22 | 23 | ## 1. 그리드 24 | 25 | `pure-g` 클래스로 row를 만들고, 그 내부에 `pure-u-*` 클래스로 column을 만든다. 자체 커스텀 그리드를 만들고 싶으면 [yui](http://yui.github.io/gridbuilder/)에서 만든다. 26 | 27 | ```html 28 | 37 | 38 |
39 |
40 | 41 |
42 |
43 |
...
44 |
45 |
46 | ``` 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | -------------------------------------------------------------------------------- /JavaScript/codewars/004_insert_dashes.md: -------------------------------------------------------------------------------- 1 | # #4 Insert dashes 2 | 3 | 홀수 사이엔 대시를 넣어서 문자열을 리턴하는 문제다. 4 | 5 | ## 1. 내 코드 6 | 7 | - 이전 숫자가 홀수인지를 판별하는 `isPrevOdd` 변수를 두고, 숫자를 문자열화해서 for 반복을 돌았다. 8 | - 현재 숫자가 홀수라면 `isPrevOdd`에 따라 대시를 삽입할 것인지 하지 않을 것인지 정한다. 그리고 공통적으로 `isPrevOdd`를 true로 바꿔준다. 9 | - 현재 숫자가 짝수라면 대시를 삽입하지 않고, `isPrevOdd`를 false로 바꿔준다. 10 | 11 | ```js 12 | function insertDash(num) { 13 | num = num + ''; 14 | var result = ''; 15 | var isPrevOdd = false; 16 | for (var i = 0; i < num.length; i++) { 17 | if (num[i] % 2) { 18 | if (isPrevOdd) result = result + '-' + num[i]; 19 | else result += num[i]; 20 | isPrevOdd = true; 21 | } else { 22 | result += num[i]; 23 | isPrevOdd = false; 24 | } 25 | } 26 | return result; 27 | } 28 | ``` 29 | 30 | ## 2. 다른 해답 31 | 32 | 자바스크립트 정규표현식을 다시 훑어봐야겠다. 파이썬이랑 뭐가 다른지 확인하자. 정규표현식은 정말 강력한 도구다. 33 | 34 | ```js 35 | function insertDash(num) { 36 | return num.toString().replace(/[13579](?=[13579])/g, "$&-"); 37 | } 38 | ``` 39 | 40 | - Number를 String으로 바꾸는 또 다른 방법: `toString()` 41 | - `$`는 뒤에 쓰이면 텍스트의 마지막을 의미하기도 하지만, 앞에서 쓰이면 그룹을 `$1`, `$2`와 같이 특정해서 활용할 수 있다. 위의 `$&`는 매칭되는 전체를 의미한다. 42 | - `(?=[13579])`는 전방 탐색으로 포함되지 않으면서 홀수 뒤에 홀수가 온다는 것을 의미한다. 43 | -------------------------------------------------------------------------------- /ETC/oh_my_zsh.md: -------------------------------------------------------------------------------- 1 | # oh-my-zsh 2 | 3 | 참고 자료: [nolboo blog](https://nolboo.github.io/blog/2015/08/21/oh-my-zsh/), [공식 repository](https://github.com/robbyrussell/oh-my-zsh) 4 | 5 | 맥 기본 터미널 앱을 계속 써왔다. 슬슬 bash의 단색 테마도 질리고 좀 더 편리하게 터미널을 사용해보고싶기도 해서 추천받은 oh-my-zsh를 쓰기로 했다. 바꾸는 김에 iterm도 사용하려고 바꿨는데 둘 다 만족한다. 6 | 7 | ## 1. 설치 8 | 9 | - 우선 homebrew를 통해 `zsh`를 설치하고, 버전 확인해본다. 10 | 11 | ```sh 12 | brew install zsh 13 | zsh --version 14 | ``` 15 | 16 | - `/etc/shells` 파일을 vi로 열어서 맨 아래에 아래 코드를 추가해준다. `which zsh` 명령어를 shell에 쳤을 때 나오는 결과다. 잘 됐는지 확인하려면 `echo $SHELL` 했을 때 zsh 경로가 뜨면 된다. 17 | 18 | ``` 19 | /usr/local/bin/zsh 20 | ``` 21 | 22 | - 기본 쉘을 변경한다. 터미널을 열었을 때 bash가 아니라 zsh를 열게 하는 명령어다. 23 | ```sh 24 | chsh -s /usr/local/bin/zsh 25 | # chsh -s `which zsh` 26 | ``` 27 | 28 | - 이제 oh-my-zsh를 설치한다. 29 | 30 | ```sh 31 | $ curl -L https://raw.github.com/robbyrussell/oh-my-zsh/master/tools/install.sh | sh 32 | ``` 33 | 34 | ## 2. 몇 가지 팁 35 | 36 | - 자동완성: 여러 경로를 앞 부분만 입력해도 탭으로 완성시킬 수 있다. 원래 `cd hello/abc/def/gf`를 했어야 하는것을 `cd h/a/d/g`를 치고 탭을 누르면 자동완성된다. 37 | - `cd -`를 입력하면 바로 이전에 위치했었던 디렉토리로 이동할 수 있다. 저 상태에서 탭을 누르면 이전 디렉토리 기록들이 쭉 뜬다. 38 | - 자동 완성에서 탭을 두 번 누르면 파일 목록을 띄워주는데 상하좌우 이동키로 선택할 수 있다. 39 | - git 브랜치 표시된다. 40 | - 명령어 스펠 체크 기능 켜주면 편하다. `setopt correct` 41 | -------------------------------------------------------------------------------- /JavaScript/codewars/031_object_extend.md: -------------------------------------------------------------------------------- 1 | # #31 Object extend 2 | 3 | 매개변수로 입력받은 모든 값 중 Object만 뽑아서 합친다. property name이 겹치면 먼저 넣어진 매개변수 Object의 property 값을 선택하면 된다. 문제에서 `isObject` 함수를 정의해서 쓰게 해줬다. 4 | 5 | ## 1. 내 코드 6 | 7 | ```js 8 | var extend = function() { 9 | if (arguments.length === 0) return {} 10 | var result = {}; 11 | for (var i = 0; i < arguments.length; i++) { 12 | var target = arguments[i]; 13 | if (!isObject(target)) continue; 14 | for (var j in target) { 15 | if (!(j in result)) { result[j] = target[j]; } // 이 부분. 16 | } 17 | } 18 | return result; 19 | } 20 | ``` 21 | 22 | 문제는 단순한데 생각치 못한 곳에서 버그가 있었다. 위 코드에 '이 부분'이라고 표시해둔 곳에 조건 부분이다. `if(!(j in result))` 이렇게 `in` 을 쓰려면 전체를 괄호로 감싸줘야한다. 괄호 없이 `if(!j in result)` 이렇게 쓰면 `!j` 값이 조건절의 값으로 들어가기 때문에 매 번 false가 나올 수 밖에 없다. result object에 계속 값이 안들어가서 확인해보니 저 부분이 문제였다. 23 | 24 | ## 2. 다른 해답 25 | 26 | ```js 27 | var extend = function() { 28 | var combined = {}; 29 | Array.prototype.slice.call(arguments).filter(isObject).reduceRight(function(i,obj){ 30 | Object.keys(obj).forEach(function(k){combined[k] = obj[k]}) 31 | },null); 32 | return combined; 33 | } 34 | ``` 35 | 36 | - 나와 원리 자체는 같은데 `filter` 함수로 `isObject`를 쓴 점, 37 | - 역방향 reduce인 `reduceRight` 함수를 써서 단순히 순서대로 대입하면 알아서 첫 객체의 property 값이 최종 선택된다는 점이 다르다. 38 | -------------------------------------------------------------------------------- /Python/Django/source/django_girls_blog_tutorial/static/admin/js/collapse.js: -------------------------------------------------------------------------------- 1 | /*global gettext*/ 2 | (function($) { 3 | 'use strict'; 4 | $(document).ready(function() { 5 | // Add anchor tag for Show/Hide link 6 | $("fieldset.collapse").each(function(i, elem) { 7 | // Don't hide if fields in this fieldset have errors 8 | if ($(elem).find("div.errors").length === 0) { 9 | $(elem).addClass("collapsed").find("h2").first().append(' (' + gettext("Show") + 11 | ')'); 12 | } 13 | }); 14 | // Add toggle to anchor tag 15 | $("fieldset.collapse a.collapse-toggle").click(function(ev) { 16 | if ($(this).closest("fieldset").hasClass("collapsed")) { 17 | // Show 18 | $(this).text(gettext("Hide")).closest("fieldset").removeClass("collapsed").trigger("show.fieldset", [$(this).attr("id")]); 19 | } else { 20 | // Hide 21 | $(this).text(gettext("Show")).closest("fieldset").addClass("collapsed").trigger("hide.fieldset", [$(this).attr("id")]); 22 | } 23 | return false; 24 | }); 25 | }); 26 | })(django.jQuery); 27 | -------------------------------------------------------------------------------- /Python/argparse.md: -------------------------------------------------------------------------------- 1 | # argparse 2 | 3 | 커맨드라인에서 `.py` 파일에 옵션을 주고 실행할 때 사용하는 방법 4 | 5 | ```py 6 | import argparse 7 | 8 | parser = argparse.ArgumentParser(description='Process some integers.') 9 | parser.add_argument('integers', metavar='N', type=int, nargs='+', 10 | help='an integer for the accumulator') 11 | parser.add_argument('--sum', dest='accumulate', action='store_const', 12 | const=sum, default=max, 13 | help='sum the integers (default: find the max)') 14 | 15 | args = parser.parse_args() 16 | print(args.accumulate(args.integers)) 17 | ``` 18 | 19 | - 위처럼 파일을 만들고 `-h` 옵션을 주고 실행하면 다음이 출력된다. 20 | 21 | ``` 22 | usage: prog.py [-h] [--sum] N [N ...] 23 | 24 | Process some integers. 25 | 26 | positional arguments: 27 | N an integer for the accumulator 28 | 29 | optional arguments: 30 | -h, --help show this help message and exit 31 | --sum sum the integers (default: find the max) 32 | ``` 33 | 34 | - `parser` 인스턴스 만들 때 description은 전체 소개글이다. 35 | - `parser.add_argument` : argument 지정 36 | + 첫 번째 매개변수: argument로 지정할 문자열. 37 | + `type` : 타입 지정 38 | + `default` : 위 케이스에선 `--sum`이 없으면 `max` 함수 실행 39 | + `help` : 해당 argument의 소개, 의미. 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | -------------------------------------------------------------------------------- /Ruby_on_Rails/request-response_cycle.md: -------------------------------------------------------------------------------- 1 | #Request-Response Cycle 2 | request/response cycle은 유저의 request가 어떤 flow를 타고 흘러가는지에 대한 정보다. 이 플로우를 잘 이해하면 오류가 났을 때 어느 부분을 봐야 하고 어디를 어떻게 수정해야하는지 알 수 있다. Codecademy article인 Request-Response Cycle 1, 2, 3편을 간추려봤다. 3 | 4 | 1. [Request-Response Cycle 1](https://www.codecademy.com/articles/request-response-cycle-static) 5 | 2. [Request-Response Cycle 2](https://www.codecademy.com/articles/request-response-cycle-dynamic) 6 | 3. [Request-Response Cycle 3](https://www.codecademy.com/articles/request-response-cycle-forms) 7 | 8 | ##1편, 2편 9 | 1편 내용에 db가 추가된 것이 2편이라서 2편만 나타낸다. 10 | ![How it Works](https://s3.amazonaws.com/codecademy-content/projects/3/request-response-cycle-dynamic.svg) 11 | ======== 12 | 1. 브라우저에 http://localhost:8000/welcome 을 입력하고 엔터를 친다. 이것은 도메인과 연결된 프로젝트에 /welcome 이라는 request를 날리는 것을 의미한다. 13 | 2. request는 /config/routes.rb의 **router**를 만나게 된다. 14 | 3. router는 routes.rb에 적힌대로 URL을 구분하여 맞는 controller로 request를 보낸다. 15 | 4. controller는 request를 받아서 처리한다. 내부에 db 관련 소스가 있다면 model에 데이터를 달라고 요청을 보낸다. 16 | 5. 모델이 데이터를 다시 컨트롤러의 액션에게 준다. 17 | 6.처리가 끝나면 controller는 매칭되는 view로 request를 전달한다. 18 | 7.view는 HTML 형식으로 페이지를 render한다. 19 | 8.마지막으로 controller가 HTML 파일을 브라우저로 전송한다. 20 | 21 | ##3편 22 | form이 있을 때 request flow가 어떻게 되는지 나타낸다. 1, 2편과 크게 다를 것이 없으며 db가 없는 플로우가 GET, 있는 플로우가 POST이다. 23 | -------------------------------------------------------------------------------- /JavaScript/promise.md: -------------------------------------------------------------------------------- 1 | # Promise 2 | 3 | 비동기 프로그래밍을 위한 콜백이 아닌 새로운 패턴이다. Promise를 지원하는 함수에서 해당 함수가 성공, 실패했을 때 어떻게 할지 정의해놓는다. 기존 콜백 함수에서처럼 자유로운게 아니라 같은 방식으로 통일된다. 4 | 5 | ## 1. API 6 | 7 | - Constructor: 프로미스를 지원하는 함수를 만드는 방법이다. 8 | 9 | ```js 10 | var promise = new Promise(function(resolve, reject) { 11 | // 작업 코드. 작업이 끝나면 resolve 또는 reject를 호출 12 | }); 13 | ``` 14 | 15 | - Instance Method: 성공 또는 실패했을 때 호출되는 `then` 메소드 16 | + 매개변수는 optional이다. 17 | + 오류 처리만 하려면 아래 코드의 2, 3번째처럼 하면 된다. 같은 의미다. 18 | 19 | ```js 20 | promise.then(onFulfilled, onRejected) 21 | 22 | promise.then(undefined, onRejected) 23 | promise.catch(onRejected) 24 | ``` 25 | 26 | - Static Method: `Promise.all()`, `Promise.resolve()` 등 존재 27 | 28 | ## 2. 예제 29 | 30 | ```js 31 | function asyncFunction() { 32 | return new Promise(function (resolve, reject) { 33 | setTimeout(function () { 34 | resolve('Async Hello world'); 35 | }, 2000); 36 | }); 37 | } 38 | 39 | asyncFunction().then(function (value) { 40 | console.log(value); // 'Async Hello world' 41 | }).catch(function (error) { 42 | console.log(error); 43 | }); 44 | ``` 45 | 46 | - `asyncFunction`: Promise 객체를 생성해서 리턴하는 함수. 47 | - 2000ms 이후 성공했을 때의 함수를 호출하게된다. 문자열 매개변수를 넣어서. 48 | - `then`으로 성공했을 때의 함수를 정의하고, `catch`로 에러가 났을 때의 작업을 정의한다. 49 | -------------------------------------------------------------------------------- /iOS/01_xcode_fundamental.md: -------------------------------------------------------------------------------- 1 | # Xcode 시작하기 2 | 3 | ## 0. 메뉴 및 프로젝트 종류 4 | 5 | - playground는 swift 언어 연습장. 6 | - 새 프로젝트 시작하면 선택할 수 있는 템플릿이 존재 7 | + Master-Detail : 업무용 앱 제작 템플릿. 하나를 선택하면 상세 페이지가 뜨는 형태 8 | + Page-Based : 책 형태의 앱. 여러장의 페이지를 넘길 수 있는 뷰. 9 | + Single View : 기본 뷰 하나가 제공. 간단한 기능을 구현해 볼 때 가장 많이 사용. 10 | + Tabbed : 화면 아래에 탭을 가지는 형태의 뷰 11 | + Game : 게임 제작 12 | 13 | ## 1. 프로젝트 생성 옵션 14 | 15 | - Organization Identifier는 자기 도메인 역순으로. 앱 구분. 16 | - Device Universal: 아이폰, 아이패드 동시 지원 17 | - Core Data: sqlite 데이터베이스를 사용할건지. 18 | - Unit Tests: 단위 테스트 할건지 19 | - UI Tests: 앱의 UI가 정상적으로 동작하는지 확인 20 | 21 | ## 2. Panel 22 | 23 | - Navigator Panel(좌측): 프로젝트를 구성하는 파일들의 목록 24 | - Debug Area(하단) 25 | + Variables View: 실행이 멈췄을 때 Heap과 Stack의 오브젝트들을 보여줌 26 | + Console: 로그 메시지를 보여줌 27 | - Utilities Panel(우측) 28 | + Navigator Panel의 선택에 따라 달라진다. 29 | + File Inspector와 Quick Help Inspector는 비교적 덜 중요 30 | + 스토리보드 파일을 선택하면 나오는 Identity , Attribute , Size, Connections Inspector가 더 중요함 31 | + 아래쪽에 붙어있는 4개의 라이브러리 패널중 가장 활용도 높은 건 Object Library 32 | 33 | ## 3. Editor 34 | 35 | - Standard Editor: 에디터 영역 전체 사용 36 | - Assistant Editor: 화면을 반으로 갈라서 UI와 코드를 연결할 때 사용 37 | - Version Editor - Git나 Mercurial 같은 소스코드 버전 컨트롤을 할 때 사용. 38 | 39 | ## 4. 시뮬레이터 40 | 41 | 왼쪽 상단 재생버튼, 즉 Run 버튼을 누르면 시뮬레이터에서 현재 프로젝트가 열린다. 42 | -------------------------------------------------------------------------------- /JavaScript/codewars/007_search_for_letters.md: -------------------------------------------------------------------------------- 1 | # #7 Search for letters 2 | 3 | 매개변수로 받은 문자열에 알파벳이 몇 가지나 존재하는지 1과 0으로 나타낸다. 순서대로 a부터 z까지며 있으면 1, 없으면 0으로 나타내서 리턴한다. 리턴 예는 '1110000000000000000000000'이고 a, b, c만 존재한다는 의미다. 4 | 5 | ## 1. 내 코드 6 | 7 | - 모든 원소가 0으로 되고 원소 개수가 26개인 Array 만든다. 8 | - 문자열을 우선 대문자화해서 변수를 줄인다. 9 | - 문자열의 길이만큼 반복을 돌아서 아스키코드값이 A, Z 사이에 있으면 해당하는 array의 원소를 1로 바꾼다. 10 | 11 | ```js 12 | function change(string){ 13 | var result = []; 14 | while (result.length < 26) 15 | result.push(0); 16 | 17 | string = string.toUpperCase(); 18 | for (var i = 0; i < string.length; i++) { 19 | var ascii_num = string[i].charCodeAt(0); 20 | if (ascii_num >= 65 && ascii_num <= 90) 21 | result[ascii_num - 65] = 1 22 | } 23 | return result.join(''); 24 | } 25 | ``` 26 | 27 | ## 2. 다른 해답 28 | 29 | ```js 30 | function change(string) { 31 | string = string.toLowerCase() 32 | return 'abcdefghijklmnopqrstuvwxyz'.split('').map(function (c) { 33 | return string.indexOf(c) !== -1 ? 1 : 0; 34 | }).join(''); 35 | } 36 | ``` 37 | 38 | - 역시 변수를 줄이기 위해 모두 소문자로 바꾼다. 39 | - 소문자 알파벳이 모두 들어있는 리스트를 만들고 `map` 함수를 호출한다. map은 호출한 배열의 원소 하나하나에 매개변수로 받는 function을 적용하는 것이다. 40 | - 매개변수의 함수는 문자열에서 해당 알파벳이 있으면 1을, 없으면 0을 리턴하는 함수다. `indexOf`는 알파벳이 존재하면 첫 알파벳의 인덱스를 리턴하고, 아예 없으면 -1을 리턴한다. -1이 아닌 경우라는 조건을 활용했다. 41 | - 머리가 매우 좋은 것 같다. 42 | -------------------------------------------------------------------------------- /C/algorithm/013_han_num.md: -------------------------------------------------------------------------------- 1 | # #13 한수 2 | 3 | - 문제 링크: https://www.acmicpc.net/problem/1065 4 | - 어떤 양의 정수 X의 자리수가 등차수열을 이룬다면, 그 수를 한수라고 한다. 등차수열은 연속된 두 개의 수의 차이가 일정한 수열을 말한다. N이 주어졌을 때, 1보다 크거나 같고, N보다 작거나 같은 한수의 개수를 출력하는 프로그램을 작성하시오. 5 | 6 | ## 1. 내 코드 7 | 8 | ```c 9 | #include 10 | 11 | int check_han_num(int num); 12 | 13 | int main(void) 14 | { 15 | int i, cnt, num; 16 | 17 | scanf("%d", &num); 18 | if (num < 100) 19 | { 20 | cnt = num; 21 | } 22 | else 23 | { 24 | cnt = 99; 25 | for (i = 100; i <= num; i++) 26 | { 27 | if (check_han_num(i)) 28 | cnt++; 29 | } 30 | } 31 | printf("%d\n", cnt); 32 | return (0); 33 | } 34 | 35 | int check_han_num(int num) 36 | { 37 | int i, digit; 38 | int arr[4]; 39 | 40 | digit = 0; 41 | while (num > 0) 42 | { 43 | arr[digit] = num % 10; 44 | digit++; 45 | num /= 10; 46 | } 47 | for (i = 0; i < digit - 2; i++) 48 | { 49 | if (arr[i] - arr[i + 1] != arr[i + 1] - arr[i + 2]) 50 | return (0); 51 | } 52 | return (1); 53 | } 54 | ``` 55 | 56 | - 최대 수가 1000이므로 최대 자리 수는 4다. 크기 4인 정수형 배열을 만들고 각 자리수를 대입해준다. 동시에 자리수도 계산해둔다. 57 | - 첫 번쨰 수와 두 번쨰 수의 차, 두 번째 수와 세 번쨰 수의 차이를 매 번 비교해서 다르다면 바로 0을 리턴한다. 반복은 자리수에서 2를 뺀 수까지 한다. 58 | -------------------------------------------------------------------------------- /ETC/crawling_facebook_replies.md: -------------------------------------------------------------------------------- 1 | # facebook 댓글 크롤링하기 2 | 3 | 특정 포스트에서 댓글을 쓴 사람을 모두 뽑아달라는 의뢰를 받았다. 그 중에서도 이미지를 업로드한 댓글만 선정해야한다. 언어를 하나만 쓰면 더 좋았을텐데 그냥 생각나는 방법대로 JavaScript, Python 둘 다 썼다. 4 | 5 | ## 1. 이미지가 있는 댓글 선택 6 | 7 | ```js 8 | const replWithImg = document.getElementsByClassName('scaledImageFitHeight') 9 | 10 | const result = [] 11 | for (var i = 0; i < replWithImg.length; i++) { 12 | result.push(replWithImg[i].parentNode.parentNode.parentNode.parentNode.parentNode.childNodes[0].childNodes[0].innerHTML) 13 | } 14 | ``` 15 | 16 | - `scaledImageFitHeight` : 댓글에 있는 이미지의 클래스 명이다. 17 | - 이미지를 골라서 부모, 부모, 부모....등으로 찾아올라가서 댓글을 쓴 부분을 찾았다. 18 | - 아이디(유저명)이 들어가있는 result 를 출력해서 복사해서 파일을 하나 만들어 붙여넣었다.(원래라면 이걸 바로 csv 파일로 저장하면 되는데 그 방법을 못찾아서 그냥 익숙한 Python으로 해버렸다.) 19 | 20 | ## 2. csv로 저장 21 | 22 | ```py 23 | import csv 24 | 25 | result = [] 26 | i = 0 27 | with open('tmp.dat') as fp: 28 | for line in fp: 29 | if (i + 1) %3 == 0: 30 | result.append(str(line)[1:-2]) 31 | i += 1 32 | 33 | with open('result.csv', 'w') as fp: 34 | wr = csv.writer(fp, quoting=csv.QUOTE_ALL) 35 | for row in result: 36 | wr.writerow([row]) 37 | ``` 38 | 39 | - 출력해서 복사하면 `1, :, name, 2, :, name, 3, :, .........` 이런식으로 한 줄에 하나씩 쭉 붙여넣어진다. 그래서 name 부분만 집어서 새로운 리스트에 넣었다. 40 | - csv 라이브러리를 활용해 새로운 csv 파일로 썼다. 마지막 라인의 row를 리스트로 감싸준 이유는 이것을 하나의 row로 인식하게 하기 위해서다. 41 | -------------------------------------------------------------------------------- /JavaScript/apply_bind_call.md: -------------------------------------------------------------------------------- 1 | # apply, bind, call 함수 정리 2 | 3 | 셋 모두 특정 함수를 실행할 때 `this`를 바꿔서 적용할 수 있게 한다. 즉 어떤 함수가 내부 구현에서 `this`를 활용한다면, 이 함수를 호출하는 scope를 다양하게 바꿀 수 있다는 의미다. 4 | 5 | ## 1. 함수 원형 6 | 7 | - `fun.apply(thisArg, [argsArray])` 8 | - `fun.bind(thisArg[, arg1[, arg2[, ...]]])` 9 | - `fun.call(thisArg[, arg1[, arg2[, ...]]])` 10 | 11 | ## 2. 차이점 12 | 13 | - apply와 call의 차이점은 두 번째 변수가 한 번에 모여서 array로 들어가느냐, 변수 하나하나로 들어가느냐의 차이다. 14 | - apply, call과 bind의 차이점은 앞의 두 함수는 호출했을 때 바로 함수를 '실행'하지만 bind는 scope를 변경한 함수를 리턴한다는 점이다. 15 | 16 | ## 3. 예제 17 | 18 | ```js 19 | // 재사용하기 ===================================== 20 | function Student(name, age, gender) { 21 | this.name = name 22 | this.age = age 23 | this.gender = gender 24 | } 25 | 26 | var gyubin = {}; 27 | Student.apply(gyubin, ["Gyubin Son", 28, "male"]) 28 | 29 | var jordan = {}; 30 | Student.call(jordan, "Michael Jordan", 54, "male") 31 | 32 | // scope가 다른 같은 이름의 변수들 ================= 33 | window.color = "red" 34 | var o = {color: "blue"} 35 | 36 | function sayColor() { 37 | alert(this.color) 38 | } 39 | 40 | sayColor() // red 41 | sayColor.call(this) // red 42 | sayColor.call(window) // red 43 | sayColor.call(o) // blue 44 | ``` 45 | 46 | - 함수 하나를 scope 변환해서 여러번 재사용할 수 있다. 47 | - 다만 위와 같은 예제에선 `gyubin`, `jordan`이란 변수에 empty object가 대입되어있어야 한다. 48 | - 상속 개념 쉽게 구현할 수 있다. 클래스 내부에서 실행하면 된다. 49 | -------------------------------------------------------------------------------- /JavaScript/codewars/022_luck_check.md: -------------------------------------------------------------------------------- 1 | # #22 Luck check 2 | 3 | 문자열 타입의 숫자를 입력받아 중간을 자른다. 앞 숫자들의 합과 뒷 숫자들의 합이 같으면 true, 틀리면 false 리턴한다. 짝수자리라면 정확하게 반으로 나누고 홀수 자리라면 정 중앙 숫자의 왼쪽, 오른쪽을 계산한다. 4 | 5 | ## 1. 내 코드 6 | 7 | ```js 8 | function luckCheck(ticket){ 9 | var left_index = parseInt(ticket.length / 2); 10 | var right_index = left_index; 11 | if (ticket.length % 2 == 1) right_index += 1; 12 | 13 | var left = ticket.slice(0, left_index).split('').reduce(function(p, c){ 14 | return p + parseInt(c); 15 | }, 0); 16 | var right = ticket.slice(right_index).split('').reduce(function(p, c){ 17 | return p + parseInt(c); 18 | }, 0); 19 | return left === right ? true : false; 20 | } 21 | ``` 22 | 23 | - 앞 뒤를 나누는 인덱스를 각각 선언하고, 만약 홀수 자리인 경우 뒤 인덱스에 1을 더해줬다. 24 | - 문자열을 정해준 인덱스까지 자르고, reduce 함수를 통해 값을 모든 숫자를 더해줬다. 25 | 26 | # 2. 다른 해답 27 | 28 | ```js 29 | function luckCheck(ticket){ 30 | var long = ticket.length; 31 | var left = ticket.split('').splice(0, long/2); 32 | var right = ticket.split('').splice((long % 2 == 0? long/2: long/2 + 1), long); 33 | return left.reduce((a, b) => +a + +b) == right.reduce((a, b) => +a + +b); 34 | } 35 | ``` 36 | 37 | - 앞과 뒷 부분을 구분하는 인덱스를 구하는 방식은 같다. 그런데 slice의 매개변수로 float형이 들어갈 수 있는지는 몰랐다. 굳이 parseInt 함수를 쓰지 않아도 자연스럽게 slice 가능하다. 38 | - true, false를 리턴하기 위해 reduce 결과를 비교하는 구문을 리턴했다. 그리고 parseInt와 초기값을 지정하지 않고 변수 앞에 `+`를 붙여서 쉽게 숫자형으로 타입 변환했다. 39 | -------------------------------------------------------------------------------- /Algorithm/greedy_algorithm.md: -------------------------------------------------------------------------------- 1 | # Greedy Algorithm 2 | 3 | 참고링크: [나무위키](https://namu.wiki/w/그리디%20알고리즘), [janghw 티스토리](http://janghw.tistory.com/entry/알고리즘-Greedy-Algorithm-탐욕-알고리즘) 4 | 5 | 매 순간 최선의 선택을 하는 알고리즘이다. 특정 선택을 할 때마다 최선의 선택을 하면 결국엔 최종적으로 가장 최적의 답을 찾는 원리. 하지만 전술의 승리가 항상 전략의 승리로 가는 것은 아닌 것처럼 예외가 존재한다. 6 | 7 | ## 1. 거스름돈 예제 8 | 9 | - 문제 내용: 1원, 7원, 10원짜리 동전이 있고 14원을 거슬러줘야한다. 10 | - greedy 알고리즘으로는 10원부터 시작해서 10원 1개, 1원 4개로 거슬러줄 것이다. 하지만 7원짜리를 사용하면 단 2개로 거슬러줄 수 있다. 11 | - greedy, 즉 탐욕 알고리즘으로 불리는 이유는 다음처럼 현재만 바라보고 욕심을 부려서 최대한 특정 작업을 완수하려 하기 떄문이다.\ 12 | - 그래서 아래 거스름돈 예제같은 경우엔 각 동전이 서로 배수 관계를 가지는지 먼저 알아봐야한다. 즉 각 단계의 최적의 해를 모았을 때 전체의 최적 해가 되는지를 먼저 확인하고 탐욕 알고리즘을 써야 함. 13 | 14 | ```c 15 | #include 16 | 17 | int main(void) 18 | { 19 | int m, i = 0, f = 0; 20 | int coin[3] = {10, 7, 1}; 21 | int count[3] = {0, 0, 0}; 22 | 23 | scanf("%d", &m); 24 | while (i < 3) 25 | { 26 | if (coin[i] > m) 27 | { 28 | i++; 29 | } 30 | else if (coin[i] < m) 31 | { 32 | m -= coin[i]; 33 | count[i]++; 34 | } 35 | else 36 | { 37 | f = 1; 38 | count[i]++; 39 | break; 40 | } 41 | } 42 | if (f) 43 | printf("%d, %d, %d\n", count[0], count[1], count[2]); 44 | else 45 | printf("Can't give change.\n"); 46 | return 0; 47 | } 48 | ``` 49 | -------------------------------------------------------------------------------- /Python/codewars/016_castle_grayskull.md: -------------------------------------------------------------------------------- 1 | # #16 By the Power Set of Castle Grayskull 2 | 한 마디로 입력받은 리스트의 멱집합(power set)을 구하는 문제다. iterable 객체를 매개변수로 받아서 그 원소를 combination 한 모든 결과를 각각 리스트에 넣어서 결과값에 넣는다. 즉 [1, 2, 3]이면 [[], [1], [2], [3], [1, 2], [1, 3], [2, 3], [1, 2, 3]] 을 리턴해야 한다. 3 | 4 | ## 1. 내 코드 5 | combinations라는 함수를 사용했다. 첫 번째 매개변수에 iterable을 넣고, 두 번째 매개변수에 몇 개를 뽑을 건지 넣어주면 된다. 0개부터 iterable 전체 수까지 뽑아야 하므로 전체 길이의 +1까지 xrange를 돌렸다. combinations 객체를 반복문으로 뽑아내면 결과물이 튜플이라서 list화 해줬다. (뿌듯한건 최고 득표 해답과 똑같았다. 다만 그 해답은 억지로 한 줄로 줄여놨는데 내 입장에선 가독성 안좋고 별로더라.) 6 | 7 | ```python 8 | from itertools import combinations 9 | def power(s): 10 | result = [] 11 | for i in xrange(len(s)+1): 12 | result += [list(j) for j in combinations(s, i)] 13 | return result 14 | ``` 15 | 16 | ## 2. 다른 해답: chain, chain.from_iterable 17 | itertools 모듈에 chain 관련 함수들도 있었다. 이를 활용하면 따로 리스트 변수를 선언해서 합친 후 리턴할 필요 없이 바로 리턴할 수 있다. 18 | 19 | - from itertools import chain: chain(*iterables) 형태로 사용된다. 여러 개의 iterable이 매개변수로 들어가면 그걸 다 연결시켜서 마치 하나의 연결된 iterable처럼 사용할 수 있다. 20 | - 위 chain 클래스의 클래스 메소드다. chain.from_iterable(iterable) 형태로 사용된다. 매개변수로 들어온 iterable의 원소들을 chain한다는 의미다. 더 깊이 들어가진 않고 딱 매개변수로 받은 iterable의 원소까지만 chain한다. 즉 매개변수 iterable의 원소의 원소까지는 안들어간다. 21 | 22 | ```python 23 | def power(s): 24 | from itertools import chain, combinations 25 | return chain.from_iterable(combinations(s, r) for r in range(len(s) + 1)) 26 | ``` 27 | -------------------------------------------------------------------------------- /Python/codewars/045_explosive_sum.md: -------------------------------------------------------------------------------- 1 | # #45 Explosive Sum 2 | 3 | 매개변수로 받은 수를 다른 자연수의 합으로 나타낼 수 있는 가짓수를 구하는 문제다. 3이라면 1+1+1, 1+2, 3 이렇게 3가지가 있겠다. 4 | 5 | ## 1. 내 코드 6 | 7 | 참고 링크: [위키피디아](https://en.wikipedia.org/wiki/Partition_(number_theory)) 8 | 9 | ```py 10 | def exp_sum(n): 11 | if n < 0: 12 | return 0 13 | dp = [1]+[0]*n 14 | 15 | for num in xrange(1, n+1): 16 | for i in xrange(num, n+1): 17 | dp[i] += dp[i-num] 18 | 19 | return dp[-1] 20 | ``` 21 | 22 | ## 2. 다른 해답 23 | 24 | ```py 25 | class Memoize: 26 | def __init__(self, func): 27 | self.func = func 28 | self.cache = {} 29 | def __call__(self, arg): 30 | if arg not in self.cache: 31 | self.cache[arg] = self.func(arg) 32 | return self.cache[arg] 33 | 34 | @Memoize 35 | def exp_sum(n): 36 | if n == 0: return 1 37 | result = 0; k = 1; sign = 1; 38 | while True: 39 | pent = (3*k**2 - k) // 2 40 | if pent > n: break 41 | result += sign * exp_sum(n - pent) 42 | pent += k 43 | if pent > n: break 44 | result += sign * exp_sum(n - pent) 45 | k += 1; sign = -sign; 46 | return result 47 | ``` 48 | 49 | ```py 50 | def exp_sum(n): 51 | if n < 0: return 0 52 | A = [1] + [0]*n 53 | for i in range(n): 54 | A = [sum(A[:k+1][::-i-1]) for k in range(n+1)] 55 | return A[-1] 56 | ``` 57 | -------------------------------------------------------------------------------- /Python/Django/source/django_girls_blog_tutorial/blog/templates/blog/base.html: -------------------------------------------------------------------------------- 1 | {% load staticfiles %} 2 | 3 | 4 | Django Girls blog 5 | 6 | 7 | 8 | 9 | 10 | 11 | 17 |
18 |
19 |
20 | {% block content %} 21 | {% endblock %} 22 |
23 |
24 |
25 | 26 | 27 | -------------------------------------------------------------------------------- /Python/Django/source/django_girls_blog_tutorial/static/admin/js/vendor/jquery/LICENSE-JQUERY.txt: -------------------------------------------------------------------------------- 1 | Copyright jQuery Foundation and other contributors, https://jquery.org/ 2 | 3 | This software consists of voluntary contributions made by many 4 | individuals. For exact contribution history, see the revision history 5 | available at https://github.com/jquery/jquery 6 | 7 | ==== 8 | 9 | Permission is hereby granted, free of charge, to any person obtaining 10 | a copy of this software and associated documentation files (the 11 | "Software"), to deal in the Software without restriction, including 12 | without limitation the rights to use, copy, modify, merge, publish, 13 | distribute, sublicense, and/or sell copies of the Software, and to 14 | permit persons to whom the Software is furnished to do so, subject to 15 | the following conditions: 16 | 17 | The above copyright notice and this permission notice shall be 18 | included in all copies or substantial portions of the Software. 19 | 20 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 21 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 22 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 23 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 24 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 25 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 26 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 27 | -------------------------------------------------------------------------------- /C/algorithm/014_str_repeat.md: -------------------------------------------------------------------------------- 1 | # #14 문자열 반복 2 | 3 | - 문제 링크: https://www.acmicpc.net/problem/2675 4 | - 문자열 S를 입력받은 후에, 각 문자를 R번 반복해 새 문자열 T를 만든 후 출력하는 프로그램을 작성하시오. 5 | - S에는 QR Code "alphanumeric" 문자만 들어있다. 6 | + `0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ$%*+-./:` 7 | - 입력 8 | + 첫째 줄: 테스트 케이스의 개수 T(1 <= T <= 1,000) 9 | + 각 테스트 케이스: 반복 횟수 R(1 <= R <= 8), 문자열 S가 공백으로 구분되어 주어진다. 10 | + S의 길이는 적어도 1이며, 20글자를 넘지 않는다. 11 | 12 | ## 1. 내 코드 13 | 14 | ```c 15 | #include 16 | 17 | int main(void) 18 | { 19 | int case_num = 0; 20 | int repeat = 0; 21 | int hold = 0; 22 | int i = 0; 23 | char str[21] = {0}; 24 | 25 | scanf("%d", &case_num); 26 | while (case_num--) 27 | { 28 | scanf("%d", &repeat); 29 | scanf("%s", str); 30 | i = 0; 31 | while (str[i]) 32 | { 33 | hold = repeat; 34 | while (hold--) 35 | printf("%c", str[i]); 36 | i++; 37 | } 38 | printf("\n"); 39 | } 40 | return (0); 41 | } 42 | ``` 43 | 44 | ## 2. 다른 사람 코드 45 | 46 | ```c 47 | #include 48 | 49 | int main() 50 | { 51 | int t, r, i, j; 52 | char s[21]; 53 | 54 | scanf("%d", &t); 55 | 56 | while(t--) { 57 | scanf("%d %s", &r, s); 58 | for(i=0; s[i]!=0; i++) 59 | for(j=0; j= 65 && e.charCodeAt(0) <= 90; 11 | }); 12 | return text.map(function(e) { 13 | return e.charCodeAt(0) - 64 14 | }).join(' '); 15 | } 16 | ``` 17 | 18 | - 우선 filter를 활용해서 알파벳만 골라냈다. 19 | - map을 활용해서 알파벳을 아스키코드 값 - 64를 적용해서 순서를 나타내는 숫자로 바꿨다. 20 | - 최종적으로 ' ' 공백을 기준으로 array의 원소들을 문자열로 연결시켰다. 21 | 22 | ## 2. 다른 해답 23 | 24 | ### A. 최고 득표 25 | 26 | ```js 27 | function alphabetPosition(text) { 28 | var result = ""; 29 | for (var i = 0; i < text.length; i++){ 30 | var code = text.toUpperCase().charCodeAt(i) 31 | if (code > 64 && code < 91) result += (code - 64) + " "; 32 | } 33 | return result.slice(0, result.length-1); 34 | } 35 | ``` 36 | 37 | - `charCodeAt(i)` 함수는 문자열에서 호출되어 i 인덱스가 가리키는 문자의 아스키코드를 리턴하는 함수다. 만약 아스키코드가 A-Z 중에 하나라면 결과 문자열에 그 숫자를 추가하고 뒤에 공백을 넣는다. 38 | - 반복이 끝나면 마지막에 필요없는 공백이 하나 있으므로 `slice`를 활용하여 마지막 공백은 제외하고 리턴한다. 39 | 40 | ### B. 정규표현식 41 | 42 | ```js 43 | let alphabetPosition = (text) => text.toUpperCase().replace(/[^A-Z]/g, '').split('').map(ch => ch.charCodeAt(0) - 64).join(' '); 44 | ``` 45 | 46 | - arrrow function 활용했다. A-Z가 아닌 것들은 모두 빈 문자열로 바꿔서 없애버렸다. 47 | - split을 활용해서 리스트로 만들고 아스키코드로 만들어 join했다. 48 | - 나는 filter를 썼지만 이 사람은 정규표현식을 활용했다. 이게 더 깔끔하다. 49 | -------------------------------------------------------------------------------- /Python/codewars/044_strip_url_params.md: -------------------------------------------------------------------------------- 1 | # #44 Strip Url Params 2 | 3 | URL 뒤에 붙는 Query String의 키 밸류 쌍에서 중복된 것과, 매개변수로 들어오는 키 값은 버린다. 4 | 5 | ## 1. 내 코드 6 | 7 | ```py 8 | import re 9 | def strip_url_params(url, params_to_strip = []): 10 | if '?' not in url: return url 11 | q = url.index('?') 12 | params = url[q+1:].split('&') 13 | 14 | no_duplicates = set() 15 | result = [] 16 | for p in params: 17 | r = re.match(r'.+?(?==)', p).group() 18 | if r not in params_to_strip and r not in no_duplicates: 19 | no_duplicates.add(r) 20 | result.append(p) 21 | return url[:q+1] + '&'.join(result) 22 | ``` 23 | 24 | - '?'가 없으면 바로 리턴한다. 25 | - '?' 인덱스를 찾고, 그 뒤의 쿼리스트링을 '&'을 기준으로 split한다. 26 | - 키 밸류 쌍을 반복문으로 돈다. 정규표현식으로 '=' 앞에 있는 키를 뽑아내고, 이 키가 params_to_strip 리스트에 없어야 하고, 키를 모아둔 no_duplicates 세트에 없다면 결과값에 추가한다. no_duplicates 세트에도 추가해서 똑같은 키가 또 추가되지 않도록 한다. 27 | - '?'까지의 url과 result 값을 '&'으로 연결시킨 문자열을 리턴한다. 28 | 29 | ## 2. 다른 해답 30 | 31 | ```py 32 | def strip_url_params(url, params_to_strip = []): 33 | if '?' not in url: 34 | return url 35 | hier, query = url.split('?') 36 | params = {} 37 | for param in query.split('&'): 38 | k, v = param.split('=') 39 | if k not in params and k not in params_to_strip: 40 | params[k] = v 41 | return '{0}?{1}'.format(hier, '&'.join('='.join(kv) for kv in params.items())) 42 | ``` 43 | 44 | - 나와 같은 흐름이다. 다만 정규표현식 대신 split을 더 사용했고, 중복을 제외하기 위해 세트 대신 딕셔너리를 썼다. 45 | -------------------------------------------------------------------------------- /Python/crawling/web_crawling.md: -------------------------------------------------------------------------------- 1 | # Web Crawling 2 | 3 | 파이썬으로 크롤링 하는 방법. 기본 함수 활용부터 scrapy, beautiful soup까지. 4 | 5 | ## 1. 가장 기초. request, response 6 | 7 | 참고 링크: [30분만에 따라하는 동시성 스크래퍼](http://www.slideshare.net/cornchz/pyconkr-2014-30) 8 | 9 | 기본적인 웹의 동작방식은 클라이언트가 서버에 Request를 보내고(브라우저에서 URL을 입력하는 행위), 서버가 그에 맞는 html 정보를 다시 클라이언트에 전달하는 것이다. 이와 똑같이 브라우저가 아닌 코드에서 request를 날리고 전달 받은 텍스트를 변수로 저장한다. 10 | 11 | ### A. requests 활용해서 html 텍스트 다운받기 12 | 한 페이지 html 텍스트를 죄다 다운로드하고 그 텍스트를 리턴하는 함수를 만들었다. 13 | 14 | ```python 15 | import requests 16 | def fetch_page(url): 17 | r = requests.get(url) 18 | html = r.text.encode('utf-8') 19 | return html 20 | ``` 21 | 22 | ### B. html에서 원하는 부분만 뽑아내기 23 | scrapy 라이브러리의 Selector를 사용한다. 예를 들어 techneedle 블로그에서 타이틀, 콘텐트, 링크, 저자를 뽑아오고싶을 때 다음처럼 작성한다. 24 | 25 | ```python 26 | from scrapy.selector import Selector 27 | 28 | def get_contents(text): 29 | sel = Selector(text = text) 30 | item = {} 31 | item['title'] = sel.xpath('//title/text()').extract()[0].encode('utf-8') 32 | item['content'] = sel.xpath('//div[@class="entry-content"]/p/text()').extract()[0].encode('utf-8') 33 | item['link'] = sel.xpath('/html/head/link[@rel="canonical"]/@href').extract()[0].encode('utf-8') 34 | item['author'] = sel.xpath('//div[@class="wp-about-author-text"]/h3/a/text()').extract()[0].encode('utf-8') 35 | return item 36 | 37 | html_text = fetch_page("http://techneedle.com/archives/21768/") 38 | item = get_contents(html_text) 39 | print(item) 40 | ``` 41 | 42 | -------------------------------------------------------------------------------- /Algorithm/Dijkstra.md: -------------------------------------------------------------------------------- 1 | # Dijkstra 최단 경로 찾기 2 | 3 | 참고 링크: [소프트웨어야 놀자](http://www.playsw.or.kr/repo/cast/105), [위키피디아](https://ko.wikipedia.org/wiki/데이크스트라_알고리즘) 4 | 5 | ## 1. 개요 6 | 7 | ![가중치 그래프](http://ncc.phinf.naver.net/20150323_119/1427076082573xIOpa_JPEG/03.jpg) 8 | 9 | 최단 경로를 찾는 알고리즘이다. 원을 정점(定點, 위치가 정해진 점)이라 하고 연결선을 간선이라고 한다. 위 그림을 가중치 그래프라고 하고, 간선에 적힌 숫자가 가중치가 된다. 만약 A에서 C로 간다면 가중치가 최소가 되는 'A-B-C' 루트가 최단이 된다. 이것을 알아낼 때 하나하나 검사해볼 수도 있지만 복잡한 길에선 너무 경우의 수가 많아진다. 10 | 11 | ## 2. 알고리즘 과정 12 | 13 | - ① 지도상의 모든 건물들과 집에서 각 건물들까지의 최단 거리를 나타내는 표를 만든다. 14 | - ② 집과 직접 길로 이어진 건물들까지의 최단 거리는 지도에 표시된 값으로 적고 그렇지 않은 건물들은 빈 칸으로 놓아둔다. 여기서 빈 칸의 값은 무한대를 뜻한다. 15 | - ③ 거리가 가장 짧은 건물부터 긴 건물 순으로 방문하고 방문한 건물은 색깔로 칠해 구별한다. 이때 방문한 경로도 색칠한다. 16 | - ④ 새로운 건물을 방문하면 그 건물과 이어진 건물들까지의 거리를 새로 바꾼다. 단, 이전에 이미 최단 거리가 구해졌었다면 거리를 서로 비교해 작은 것으로 바꾸거나 유지한다. 17 | - ⑤ 그래프의 모든 건물들을 방문할 때까지 ③,④의 과정을 반복한다. 18 | 19 | ## 3. 의사 코드 20 | 21 | ``` 22 | function Dijkstra(G, w, s) 23 | for each vertex v in V[G] // 초기화 24 | d[v] := infinity 25 | previous[v] := undefined 26 | d[s] := 0 //덮어쓰기 27 | S := empty set 28 | Q := set of all vertices 29 | while Q is not an empty set // 알고리즘의 실행 30 | u := Extract_Min(Q) //집합 Q에서 d[u]가 최소인 u를 찾아 빼냄 31 | S := S union {u} //빼낸 u를 S에 삽입 32 | for each v with edge (u,v) defined 33 | if d[v] > d[u] + w(u,v) 34 | d[v] := d[u] + w(u,v) // 변(u,v)의 경감 35 | previous[v] := u //경로 추적할 때 쓰임// 36 | ``` 37 | -------------------------------------------------------------------------------- /JavaScript/codewars/027_rotate_for_a_max.md: -------------------------------------------------------------------------------- 1 | # #27 Rotate for a Max 2 | 3 | 매개변수로 숫자를 받는다. 처음엔 첫 번째 숫자를 맨 뒤로 옮긴다. 두 번째엔 만들어진 숫자에서 두 번째 수를, 세 번째엔 두 번째에서 만들어진 수의 세 번째 수를 맨 뒤로 옮긴다. 이를 마지막 수에 도달할 때까지 반복한다. 기본 숫자 포함, 각 단계에서 만들어진 모든 수 중에서 가장 큰 수를 리턴하면 된다. 다음 예에선 68957이 리턴되면 된다. `56789 -> 67895 -> 68957 -> 68579 -> 68597` 4 | 5 | ## 1. 내 코드 6 | 7 | - 단계가 지날 때마다 맨 앞의 숫자들은 변하지 않았다. 첫 단계가 지나면 맨 앞자리 수는 다음 수에서도 변하지 않았고, 두 번째 단계가 지나면 두 번째 수가 뒤에서도 똑같이 유지됐다. 그래서 단계가 지날때마다 뒷 부분의 수에 다시 함수를 재귀로 호출하면 어떨까 생각했다. 그런데 만약 숫자가 `6640`처럼 같은 숫자가 반복되고 그 다음에 작은 숫자가 오는 경우 이전 단계로 되돌아가는 것이 너무 어려웠다. 8 | - 그래서 모든 단계의 숫자들을 다 배열에 집어넣고 마지막에 그 배열에서 가장 큰 수를 리턴하는 것으로 단순하게 짰다. 9 | 10 | ```js 11 | function maxRot(n) { 12 | var result = [n]; 13 | n = (n+'').split(''); 14 | var len = n.length; 15 | for (var i = 0; i < len; i++){ 16 | var temp = n[i]; 17 | n = n.slice(0, i).concat(n.slice(i+1)); 18 | n.push(temp); 19 | result.push(n.join('') * 1); 20 | } 21 | return Math.max.apply(null, result); 22 | } 23 | ``` 24 | 25 | ## 2. 다른 해답 26 | 27 | - 나와 원리는 같은데 더 간결하게 짰다. 나는 배열로 만들어 slice 함수를 적용했는데 여기선 문자열에서 바로 slice를 사용했다. 배열에서 concat 함수를 써서 연결하는 것보다 + 를 통해 문자열 연결하는게 훨씬 쉽다. 28 | - Math의 max 함수는 숫자 형태인 문자열도 마치 숫자처럼 알아서 형변환하여 결과값을 리턴한다. 여기서 처음 알았다. 29 | 30 | ```js 31 | function maxRot(n) { 32 | var str = n.toString(); 33 | var arr = [str]; 34 | for (var i=0;i<=str.length-1 ;i++){ 35 | str = str.slice(0,i)+str.slice(i+1)+str[i]; 36 | arr.push(str.split().join()); 37 | } 38 | return Math.max.apply(null, arr); 39 | } 40 | ``` 41 | -------------------------------------------------------------------------------- /JavaScript/codewars/016_rot13.md: -------------------------------------------------------------------------------- 1 | # #16 ROT 13 2 | 3 | 알파벳에서 a-m과 n-z를 뒤바꾸는 함수. 4 | 5 | ## 1. 내 코드 6 | 7 | ```js 8 | function rot13(str) { 9 | return str.split('').map(function(e){ 10 | var ascii = e.charCodeAt(); 11 | if ((ascii >= 65 && ascii <= 77)||(ascii >= 97 && ascii <= 109)) 12 | return String.fromCharCode(ascii + 13); 13 | else if ((ascii >= 78 && ascii <= 90)||(ascii >= 110 && ascii <= 122)) 14 | return String.fromCharCode(ascii - 13); 15 | else 16 | return e 17 | }).join(''); 18 | } 19 | ``` 20 | 21 | - 아스키코드값으로 `A-Ma-m`과 `N-Zn-z`를 걸러내서 바꾼다. 끝. 22 | 23 | ## 2. 다른 해답 24 | 25 | ### A. 최고 득표 26 | 27 | ```js 28 | function rot13(str) { 29 | return str.replace(/[a-z]/ig, function(x){ 30 | return String.fromCharCode(x.charCodeAt(0) + (x.toLowerCase() <= 'm' ? 13: -13)); 31 | }); 32 | } 33 | ``` 34 | 35 | - `replace` : replace의 매개변수로 '정규표현식', '콜백함수'가 들어갔다. 이런 형태로 썼을 때 함수는 정규표현식에 매칭되는 부분마다 적용된다. 콜백 함수의 첫 번째 매개변수는 매칭되는 문자열이고, 두 번째는 전체 문자열에서 매칭된 문자열의 시작 인덱스, 세 번째는 전체 문자열이 들어가게 된다. 위처럼 하나만 쓰면 매칭 문자열만 쓸 수 있다. 36 | - 'm'을 기준으로 13을 더할 것인지 뺄 것인지 정해서 코드가 단순해졌다. 37 | 38 | ### B. test 39 | 40 | ```js 41 | function rot13(str) { 42 | return str.split('').map(function(e) { 43 | return /[A-Ma-m]/.test(e) ? String.fromCharCode(e.charCodeAt(0) + 13) : 44 | /[N-Zn-z]/.test(e) ? String.fromCharCode(e.charCodeAt(0) - 13) : e; 45 | }).join(''); 46 | } 47 | ``` 48 | 49 | - `RegExp.prototype.test()` : 다음처럼 사용한다. `regexObj.test(str)`. 만약 str이 regexObj와 매칭된다면 true를 리턴한다. 나중에 filter 함수와 같이 잘 쓰이겠다. 50 | - 삼항연산자 참 잘 쓴다. 51 | -------------------------------------------------------------------------------- /Python/codewars/001_filter_the_number.md: -------------------------------------------------------------------------------- 1 | # #1 Filter the number 2 | 3 | 입력받은 문자열에서 숫자만 뽑아내어 연결시킨 수를 리턴한다. 'a1b2c3'이면 123을 리턴하는 방식. 4 | 5 | ## 1. 내 코드 6 | 7 | 정규표현식을 활용했다. 숫자만을 뽑아내는 형태인 \d를 활용해서 매칭되는 모든 숫자 하나하나를 리스트로 받았다. 받은 리스트를 공백없이 join으로 붙이고 정수화해서 리턴했다. 8 | 9 | ```python 10 | import re 11 | 12 | def filter_string(string): 13 | p = re.compile("\d") 14 | num_list = p.findall(string) 15 | result = int("".join(num_list)) 16 | return result 17 | ``` 18 | 19 | ## 2. 다른 해답 20 | filter 함수, re 모듈의 sub 함수, isdigit 함수를 활용한 해답들이 있었다. 21 | 22 | ### A. filter, isdigit 23 | 24 | - 'filter(function, iterable)' 형태로 사용된다. iterable의 원소 중 function의 조건을 만족하는 원소만 뽑아내 filter 객체를 리턴한다.(python3에선 필터 객체, python2에선 리스트를 리턴) iterable 객체이며 리스트로 바꾸고싶으면 list() 하면 된다. 25 | - str.isdigit() isdigit() 함수는 문자열에서 호출할 수 있다. "10".isdigit()은 True를 리턴하고, "a1b2c3".isdigit()은 False를 리턴한다. 26 | - re.sub(pattern, repl, string, count=0, flags=0) string에서 pattern에 해당하는 문자열을 repl로 바꾼다. count는 최대 바꾸는 회수를 말하고 flags는 확실히는 모르겠지만 re.IGNORECASE 같은 것이 들어가서 조건을 정하는 것 같다. 27 | 28 | ### B. 코드 29 | 30 | ```python 31 | ########################### isdigit을 조건으로 filter 32 | def filter_string(string): 33 | return int(filter(str.isdigit, string)) 34 | 35 | ########################### 문자가 아닌 것을 없애버린다. 36 | import re 37 | def filter_string(string): 38 | nb = re.sub(r'\D', '' ,string) 39 | return int(nb) 40 | 41 | ########################### isdigit 활용한 리스트 내포형 42 | def filter_string(string): 43 | result = [el for el in string if el.isdigit()] 44 | return int(''.join(result)) 45 | ``` 46 | -------------------------------------------------------------------------------- /Python/codewars/024_nesting_structure_comparison.md: -------------------------------------------------------------------------------- 1 | # #24 Nesting Structure Comparison 2 | 3 | - 입력받은 2개의 리스트의 구조가 똑같은지를 검사하는 함수 4 | - 원소가 1개인 리스트와, 일반 숫자나 문자열 값 하나는 같음으로 친다. 5 | - 원소가 0개인 리스트는 정수 하나와 다르다고 나온다. 6 | 7 | ## 1. 내 코드 8 | 9 | - 재귀를 썼다. 두 비교 대상이 모두 리스트라면 함수를 재귀로 다시 호출했고, flag boolean 값을 계속 리턴하고 받으면서 연결했다. 10 | - 비교하는 두 대상의 길이를 구했다. 리스트라면 길이를, 아니라면 길이가 1이라고 정했다. 11 | - 기본 flag 값은 True인데 길이가 다르다면 False라고 했다. 12 | 13 | ```python 14 | def same_structure_as(original,other): 15 | flag = True 16 | len_original = len(original) if isinstance(original, list) else 1 17 | len_other = len(other) if isinstance(other, list) else 1 18 | if len_original == len_other: 19 | if isinstance(original, list) and isinstance(other, list): 20 | for org, oth in zip(original, other): 21 | flag = same_structure_as(org, oth) 22 | else: 23 | flag = False 24 | return flag 25 | ``` 26 | 27 | ## 2. 다른 해답 28 | 29 | 나는 리스트가 아닌 원소와, 원소가 하나인 리스트를 비교하기 위해서 먼저 길이를 타나내는 변수 2개를 정의하고 시작했었다. 그렇기 때문에 조건 3개를 다음 답처럼 and로 연결시킬 수 없었다. 길이는 같지만 리스트가 아닌 타입이 있더라도 True일 수 있기 때문이다. 그래서 길이 비교와, 타입이 리스트인지를 조건문 2개로 분기했다. 하지만 아래 답은 3가지 조건을 뭉쳐놓는 대신 else에서 예외를 처리했다. 나머지는 같은 흐름이다. 30 | 31 | ```python 32 | def same_structure_as(original,other): 33 | if isinstance(original, list) and isinstance(other, list) and len(original) == len(other): 34 | for o1, o2 in zip(original, other): 35 | if not same_structure_as(o1, o2): return False 36 | else: return True 37 | else: return not isinstance(original, list) and not isinstance(other, list) 38 | ``` 39 | -------------------------------------------------------------------------------- /JavaScript/codewars/001_monotone_travel.md: -------------------------------------------------------------------------------- 1 | # #1 Monotone travel 2 | 3 | array의 원소들이 갈 수록 올라가는지 확인하는 함수를 짜는 것이다. 내 코드는 설명이 필요없을 정도로 간단한 코드다. 4 | 5 | ## 1. 내 코드 6 | 7 | ```js 8 | var isMonotone = function(arr){ 9 | for (var i = 0; i < arr.length - 1; i++) { 10 | if (arr[i+1] < arr[i]) return false; 11 | } 12 | return true; 13 | } 14 | ``` 15 | 16 | ## 2. 다른 해답 17 | 18 | ### A. every 활용(설명참고 [MDN](https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Array/every)) 19 | 20 | ```js 21 | var isMonotone = function(arr){ 22 | return arr.every(function(x, idx) { 23 | return idx === 0 ? true : arr[idx] >= arr[idx-1]; 24 | }); 25 | } 26 | ``` 27 | 28 | 모든 요소가 전달한 콜백 함수의 조건에 만족하는지 확인하는 것이다. 콜백 함수에는 세 가지 매개변수가 들어갈 수 있는데 순서대로 '하나씩 뽑을 원소', '원소의 인덱스', '현재 처리 중인 배열'이다. 위 경우는 앞의 2가지 매개변수만 활용했다. 인덱스가 0이면 그냥 true를 리턴하고 아니라면 현재 원소가 이전 원소보다 같거나 큰지를 확인한다. 29 | 30 | ### B. reduce 활용 31 | 32 | ```js 33 | var isMonotone = function(arr){ 34 | return arr.reduce(function(p, c, i, arr){ 35 | return p && (c <= arr[i+1] || i == arr.length - 1); 36 | }, true); 37 | } 38 | ``` 39 | 40 | 다른 언어에서의 reduce 함수와 비슷하다. 역시 원소를 하나하나 가져와서 누적하고 최종 적으로 하나의 값을 리턴하는 함수다. 기본적으로 다음 `arr.reduce(callback[, initialValue])` 형태를 가지며 콜백함수의 매개변수로는 순서대로 previousValue, currentValue, currentIndex, array를 받을 수 있다. 콜백함수는 이전값과 현재값을 어떻게 연산할 것인지를 정의해준다. 41 | 42 | 위 경우는 initialValue를 true로 넣었다. 그리고 현재값이 다음 값보다 같거나 작은지 boolean 값을 이전값과 and 연산했다. 다음 값을 뽑아올 때 인덱스를 +1 했기 때문에 마지막엔 존재하지 않는 값을 뽑아올 것이다. 이 때 undefined가 리턴되는데 `||`를 활용해서 인덱스가 마지막 인덱스면 true를 리턴한다. A 답과 달리 매번 인덱스값을 비교하지 않고 마지막에 한 번만 비교하기 때문에 연산 수를 줄였다. 43 | -------------------------------------------------------------------------------- /Python/codewars/009_linked_lists-get_nth_node.md: -------------------------------------------------------------------------------- 1 | # #9 Linked Lists - Get Nth Node 2 | Node라는 클래스가 있다. 인스턴스 변수로 data와 next를 가지고 있고 next는 다음 노드를 가리킨다. 즉 linked list이다. get_nth 함수는 노드 객체와 index 정수 변수를 받아서 linked list의 index 번째 노드를 리턴하는 함수다. 3 | 4 | 추가로 리스트에 없는 인덱스를 입력하는 경우, node 객체 대신 빈 객체를 입력하는 경우엔 에러를 띄워야한다. 5 | 6 | ## 1. 내 코드 7 | 8 | - 우선 index가 0보다 작은 경우와 node가 None인 경우에 각각 에러를 발생시켰다. 9 | - cnt 변수에 현재 node 객체 순서를 저장했고, 매 반복마다 1씩 증가시켜서 원하는 index까지 반복문을 돌렸다. 10 | - 리스트 인덱스가 3까지인데 더 큰 수가 인덱스로 입력했을 경우는 node.next 자체를 조건문으로 삼아서 없는 경우엔 인덱스 에러를 발생시켰다. 11 | - 최종까지 아무 에러도 나지 않았으면 node를 리턴했다. 12 | 13 | ```python 14 | class Node(object): 15 | def __init__(self, data): 16 | self.data = data 17 | self.next = None 18 | 19 | def get_nth(node, index): 20 | if index < 0: raise IndexError 21 | if node == None: raise Error 22 | cnt = 0 23 | while cnt < index: 24 | if node.next: 25 | node = node.next 26 | cnt += 1 27 | else: raise IndexError 28 | return node 29 | ``` 30 | 31 | ## 2. 다른 해답 32 | 대부분 재귀를 사용했고 비슷한 흐름이었다. 그 중에서 가장 깔끔한 코드를 골랐다. 33 | 34 | ```python 35 | def get_nth(node, index): 36 | if node and index >= 0: 37 | return node if index < 1 else get_nth(node.next, index - 1) 38 | raise ValueError 39 | ``` 40 | > 나는 재귀 사용은 생각도 못했는데 아쉽다. 후.. 41 | 42 | - and 연산자는 가장 우선순위가 낮다. index>=0과 node를 and 연산한다. node도 None이 아니어야 하고, index도 0 이상이어야 한다. 43 | - index가 1보다 작으면 node를 리턴하는데 아니라면 get_nth 함수를 다시 재귀로 호출한다. 다만 node는 다음 노드를, index 값은 1을 빼서 넣는다. 44 | - 재귀로 호출될 때마다 if 조건으로 검사하게 되는데 통과하지 못하면 ValueError를 띄운다. 되게 깔끔한 코드다. 45 | 46 | -------------------------------------------------------------------------------- /Python/Django/source/django_girls_blog_tutorial/static/admin/css/login.css: -------------------------------------------------------------------------------- 1 | /* LOGIN FORM */ 2 | 3 | body.login { 4 | background: #f8f8f8; 5 | } 6 | 7 | .login #header { 8 | height: auto; 9 | padding: 5px 16px; 10 | } 11 | 12 | .login #header h1 { 13 | font-size: 18px; 14 | } 15 | 16 | .login #header h1 a { 17 | color: #fff; 18 | } 19 | 20 | .login #content { 21 | padding: 20px 20px 0; 22 | } 23 | 24 | .login #container { 25 | background: #fff; 26 | border: 1px solid #eaeaea; 27 | border-radius: 4px; 28 | overflow: hidden; 29 | width: 28em; 30 | min-width: 300px; 31 | margin: 100px auto; 32 | } 33 | 34 | .login #content-main { 35 | width: 100%; 36 | } 37 | 38 | .login .form-row { 39 | padding: 4px 0; 40 | float: left; 41 | width: 100%; 42 | border-bottom: none; 43 | } 44 | 45 | .login .form-row label { 46 | padding-right: 0.5em; 47 | line-height: 2em; 48 | font-size: 1em; 49 | clear: both; 50 | color: #333; 51 | } 52 | 53 | .login .form-row #id_username, .login .form-row #id_password { 54 | clear: both; 55 | padding: 8px; 56 | width: 100%; 57 | -webkit-box-sizing: border-box; 58 | -moz-box-sizing: border-box; 59 | box-sizing: border-box; 60 | } 61 | 62 | .login span.help { 63 | font-size: 10px; 64 | display: block; 65 | } 66 | 67 | .login .submit-row { 68 | clear: both; 69 | padding: 1em 0 0 9.4em; 70 | margin: 0; 71 | border: none; 72 | background: none; 73 | text-align: left; 74 | } 75 | 76 | .login .password-reset-link { 77 | text-align: center; 78 | } 79 | -------------------------------------------------------------------------------- /JavaScript/codewars/030_math_issues.md: -------------------------------------------------------------------------------- 1 | # #30 Math Issues 2 | 3 | Math 모듈에서 올림, 내림, 반올림 함수를 각각 구현하는 것. 4 | 5 | ## 1. 내 코드 6 | 7 | ```js 8 | Math.hasNoDot = function(number) { 9 | var re = /[.]/; 10 | if (!re.exec(String(number))) return true; 11 | return false; 12 | } 13 | 14 | Math.round = function(number) { 15 | if (Math.hasNoDot(number)) return number; 16 | var re = /[.](\d)/; 17 | return Number(re.exec(String(number))[1]) >= 5 ? Math.ceil(number) : Math.floor(number); 18 | }; 19 | 20 | Math.ceil = function(number) { 21 | if (Math.hasNoDot(number)) return number; 22 | var re = /(\d+)[.]/; 23 | return Number(re.exec(String(number))[1]) + 1; 24 | }; 25 | 26 | Math.floor = function(number) { 27 | if (Math.hasNoDot(number)) return number; 28 | var re = /(\d+)[.]/; 29 | return Number(re.exec(String(number))[1]); 30 | }; 31 | ``` 32 | 33 | - 정규표현식을 활용했다. 34 | - `.`이 있는지 없는지에 따라 다르기 때문에 점이 있는지 확인하는 함수 `hasNoDot`을 만들었다. `.`이 없으면 true를 리턴한다. 각 함수마다 맨 앞에서 호출되고 `.`이 없다면 숫자를 바로 리턴한다. 35 | - 자연수가 아니라면 36 | + `ceil`, `floor` : 올림과 내림이기 때문에 `.` 바로 앞 숫자를 뽑아서 활용한다. 올림이면 뽑은 수에 1을 더하고, 내림이면 그대로 둬서 리턴한다. 37 | + `round` : `.` 바로 뒤에 있는 숫자가 5보다 크면 ceil 함수를 호출하고, 작으면 floor 함수를 호출한다. 38 | 39 | ## 2. 다른 해답 40 | 41 | ```js 42 | Math.round = function(number) { 43 | return (number - parseInt(number) >= 0.5) ? parseInt(number) + 1 : parseInt(number) ; 44 | }; 45 | 46 | Math.ceil = function(number) { 47 | return (parseInt(number) === number) ? number : parseInt(number) + 1; 48 | }; 49 | 50 | Math.floor = function(number) { 51 | return parseInt(number); 52 | }; 53 | ``` 54 | 55 | `parseInt` 함수로 굉장히 쉽게 해결했다. 굳이 나처럼 정규표현식 쓸 필요가 없었다. 56 | -------------------------------------------------------------------------------- /Algorithm/exercises/minimum_classroom.md: -------------------------------------------------------------------------------- 1 | # 최소 강의실 구하기 2 | 3 | ## 1. 문제 4 | 5 | 시작, 끝 시간이 정해진 강의들이 여러개 있다. 시간이 겹치는 경우가 있을 때 필요한 최소 강의실 개수를 구하면 된다. 6 | 7 | 입력 데이터는 첫 줄에 강의 수를 입력받고, 다음 각 줄마다 강의의 시작과 끝 시간이 입력된다. 8 | 9 | ``` 10 | 8 11 | 15 21 12 | 20 25 13 | 3 8 14 | 2 14 15 | 6 27 16 | 7 13 17 | 12 18 18 | 6 20 19 | ``` 20 | 21 | ## 2. 코드 22 | 23 | ```py 24 | def find_min_room(num_class, classes): 25 | size = 0 26 | for i in range(num_class): 27 | if size < classes[i][1]: 28 | size = classes[i][1] 29 | if size == 0: return 0 30 | time_table = [0] * size 31 | for elem in classes: 32 | for i in range(elem[0], elem[1]): 33 | time_table[i] += 1 34 | return max(time_table) 35 | 36 | def read_inputs(): 37 | num_class = int(input()) 38 | classes = [] 39 | for i in range(num_class): 40 | line = [int(x) for x in input().split()] 41 | start = line[0] 42 | end = line[1] 43 | classes.append((start, end)) 44 | 45 | return num_class, classes 46 | 47 | def main(): 48 | num_class, classes = read_inputs() 49 | ans = find_min_room(num_class, classes) 50 | print(ans) 51 | 52 | if __name__ == "__main__": 53 | main() 54 | ``` 55 | 56 | - 각 시간대별로 몇 개의 강의가 진행되는지 구하고, 그 중에서 최대값을 구하면 강의실 개수가 나온다. 인덱스가 시간대를 나타내는 배열을 만들고 값으로 진행되는 수업의 개수를 저장한다. 57 | - `find_min_room` 함수 58 | + `size`와 첫 번째 for 반복은 전체 배열의 크기를 알기 위한 것이다. 각 수업에서 끝 시간중에 가장 큰 값을 구한다. 만약 그 값이 0이라면 애초에 수업이 없는 것이므로 바로 0을 리턴하고 종료한다. 59 | + size 크기만큼 `time_table` 배열을 만들고 각 수업마다 시작시간 인덱스부터 끝 시간 인덱스까지 수업이 원소에 1을 증가시킨다. 그 시간에 수업이 있는 것이므로 60 | + 최종으로 가장 높은 값을 max 함수를 써서 리턴한다. 61 | -------------------------------------------------------------------------------- /Python/Django/source/django_girls_blog_tutorial/blog/views.py: -------------------------------------------------------------------------------- 1 | from django.shortcuts import render, get_object_or_404, redirect 2 | from .models import Post 3 | from django.utils import timezone 4 | from .forms import PostForm 5 | 6 | def post_list(request): 7 | posts = Post.objects.filter(published_date__lte=timezone.now()).order_by('published_date') 8 | return render(request, 'blog/post_list.html', {'posts':posts}) 9 | 10 | def post_detail(request, pk): 11 | post = get_object_or_404(Post, pk=pk) 12 | return render(request, 'blog/post_detail.html', {'post' : post}) 13 | 14 | def post_new(request): 15 | if request.method == "POST": 16 | form = PostForm(request.POST) 17 | if form.is_valid(): 18 | post = form.save(commit=False) 19 | post.author = request.user 20 | post.published_date = timezone.now() 21 | post.save() 22 | return redirect('blog.views.post_detail', pk=post.pk) 23 | else: 24 | form = PostForm() 25 | return render(request, 'blog/post_edit.html', {'form': form}) 26 | 27 | def post_edit(request, pk): 28 | post = get_object_or_404(Post, pk=pk) 29 | if request.method == "POST": 30 | form = PostForm(request.POST, instance=post) 31 | if form.is_valid(): 32 | post = form.save(commit=False) 33 | post.author = request.user 34 | post.published_date = timezone.now() 35 | post.save() 36 | return redirect('blog.views.post_detail', pk=post.pk) 37 | else: 38 | form = PostForm(instance=post) 39 | return render(request, 'blog/post_edit.html', {'form': form}) 40 | -------------------------------------------------------------------------------- /Python/codewars/012_title_case.md: -------------------------------------------------------------------------------- 1 | # #12 Title Case 2 | 첫 번째 매개변수로 받은 문자열을 제목 포맷으로 바꾼다. 첫 단어는 무조건 대문자로 시작하고, 나머지 단어들도 첫 단어를 대문자로 바꾸지만 두 번째 매개변수로 들어온 문자열에 포함된 단어라면 그냥 모두 소문자로 둔다. 두 번째 매개변수는 white space로 구분되어 이루어진 문자열이다. 3 | 4 | ## 내 코드와 최고 득표 코드 비교 5 | 6 | 다른 해답 중 가장 압도적인 득표를 받았던 코드와 내 코드가 매우 흡사해서 기분이 좋다. 7 | 8 | - 공통점 9 | + 매개변수 minor_words를 받을 때 디폴트 값으로 빈 문자열을 지정한 점 10 | + capitalize, lower, split을 사용하여 매개변수로 받은 두 문자열을 리스트 형태로 바꾼 점 11 | + 타이틀 리스트를 for문으로 돌리고 if문으로 각 단어가 minor 리스트에 포함되는지 안되는지 분기해서 capitalize 적용한 점. 12 | + 마지막 join 써서 리턴한 것. 13 | - 차이점 14 | + 입력 받은 title 문자열을 나는 title_list라는 새로운 변수로 받았는데 어차피 title 문자열이 다시 쓰이진 않았다. 변수를 괜히 하나 더 쓴 셈이었다. minor_words 역시 마찬가지. 15 | + capitalize()라는 함수가 첫 글자에만 적용되는 것인 줄 알았다. 그래서 일부러 사전에 lower()를 통해 모든 글자를 소문자로 바꿨다. 하지만 그게 아니라 자동으로 첫 글자 빼고는 모두 소문자로 바꿔주더라. 즉 title 문자열에 lower()는 필요없었던 셈. 16 | + for문과 if문의 내용 자체는 동일했지만 나와는 다르게 리스트 내포 for문을 활용하고, 한 줄짜리 if문을 표현식으로 활용해서 한 줄로 적었다. 한 줄짜리를 보니 간결하긴 하지만 가독성은 내 코드가 더 좋지 않은가 생각도 조금 들지만, 고수들이 보기엔 나보다 해답 코드가 더 가독성이 좋을 수도 있겠다 생각이 들었다. 17 | 18 | ```python 19 | #### 내 코드 20 | def title_case(title, minor_words=''): 21 | title_list = title.lower().capitalize().split() 22 | minor_list = minor_words.lower().split() 23 | for index, word in enumerate(title_list): 24 | if word not in minor_list: 25 | title_list[index] = word.capitalize() 26 | return ' '.join(title_list) 27 | 28 | #### 최고 득표 코드 29 | def title_case(title, minor_words=''): 30 | title = title.capitalize().split() 31 | minor_words = minor_words.lower().split() 32 | return ' '.join([word if word in minor_words else word.capitalize() for word in title]) 33 | ``` 34 | -------------------------------------------------------------------------------- /JavaScript/codewars/010_decode_the_morse_code.md: -------------------------------------------------------------------------------- 1 | # #10 Decode the Morse code 2 | 3 | Morse code 3부작 중 [1편](http://www.codewars.com/kata/decode-the-morse-code) ( [2편](http://www.codewars.com/kata/decode-the-morse-code-advanced), [3편](http://www.codewars.com/kata/decode-the-morse-code-for-real) ) 이다. 1편은 가장 쉬운 문제로 해독하는 함수를 작성하는 것이다. 글자는 빈 칸 한 개로 구분되고, 단어는 빈 칸 3개로 구분된다. `MORSE_CODE`라는 object를 통해 코드를 글자로 변환할 수 있다. 4 | 5 | ## 1. 내 코드 6 | 7 | ```js 8 | String.prototype.replaceAll = function(org, dest) { 9 | return this.split(org).join(dest); 10 | } 11 | 12 | var decodeMorse = function(morseCode){ 13 | morseCode = morseCode.trim().replaceAll(' ', ' space ').split(' '); 14 | var result = [] 15 | for (var i = 0; i < morseCode.length; i++) { 16 | if (morseCode[i] === 'space') 17 | result.push(' '); 18 | else 19 | result.push(MORSE_CODE[morseCode[i]]); 20 | } 21 | return result.join('') 22 | } 23 | ``` 24 | 25 | - `trim` : 문자열 앞 뒤의 빈칸을 제거했다. 26 | - `replaceAll` : `replace` 밖에 없어서 문자열의 prototype에다가 추가해줬다. trim의 결과물에다가 빈 칸 세 개를 ' space '로 바꿔줬다. space 부분에서 단어를 구분하라는 의미다. 27 | - split 결과물인 리스트에서 반복을 돌았다. 만약 space라면 한 칸을 띄우고, 아니라면 해독해서 집어넣었다. 28 | 29 | ## 2. 다른 해답 30 | 31 | ```js 32 | decodeMorse = function(morseCode){ 33 | function decodeMorseLetter(letter) { 34 | return MORSE_CODE[letter]; 35 | } 36 | function decodeMorseWord(word) { 37 | return word.split(' ').map(decodeMorseLetter).join(''); 38 | } 39 | return morseCode.trim().split(' ').map(decodeMorseWord).join(' '); 40 | } 41 | ``` 42 | 43 | - 글자를 해독하는 함수, 단어를 해독하는 함수를 따로 만들었다. 44 | - 매개변수로 받은 문자열을 ' '로 구분해서 단어 별로 떼어놓았고, 그것을 다시 각각 ' '으로 구분해서 함수를 적용했다. 45 | - 훨씬 가독성이 좋다. 46 | -------------------------------------------------------------------------------- /Algorithm/dynamic_programming.md: -------------------------------------------------------------------------------- 1 | # Dynamic Programming - DP 2 | 3 | ## 1. 개념 4 | 5 | - 정의: 어떤 문제를 풀기위해 문제를 잘게 쪼깨고, 그 문제들의 답을 활용하는 방식의 알고리즘 6 | 7 | ## 2. 피보나치 예제 8 | 9 | - 재귀 알고리즘은 다음과 같다. 하지만 메모리를 굉장히 많이 잡아먹는다. 10 | 11 | ```c 12 | int fibo(int n) 13 | { 14 | if(n <= 2) 15 | return 1; 16 | else 17 | return f(n-1)+f(n-2); 18 | } 19 | ``` 20 | 21 | - 그래서 배열을 활용한다. 22 | + 적절한 배열의 크기를 설정한다. 인덱스 0, 1 자리에는 1을 넣고 나머지엔 0 대입 23 | + 마지막 계산한 지점의 인덱스를 기록해둔다. 24 | + 이전의 두 값을 다시 함수로 계산하는게 아니라 그냥 배열에서 값을 가져오기만 한다. 25 | 26 | ```c 27 | int f_data[100] = {1, 1}; 28 | int last_pos = 1; 29 | 30 | int f(int n) 31 | { 32 | int i; 33 | 34 | if (f_data[n-1] == 0) 35 | { 36 | for(i=last_pos+1; i= self.page_count(): return -1 30 | elif page_index == self.page_count() - 1: return self.item_count() % self.items_per_page 31 | else: return self.items_per_page 32 | 33 | # determines what page an item is on. Zero based indexes. 34 | # this method should return -1 for item_index values that are out of range 35 | def page_index(self, item_index): 36 | if item_index < 0 or item_index >= self.item_count(): return -1 37 | else: return item_index // self.items_per_page 38 | ``` 39 | -------------------------------------------------------------------------------- /Python/codewars/034_find_the_parity_outlier.md: -------------------------------------------------------------------------------- 1 | # #34 Find The Parity Outlier 2 | 3 | 하나만 빼고 모두 짝수거나 홀수인 리스트를 매개변수로 받는다. 다른 수를 찾는 문제다. 4 | 5 | ## 1. 내 코드 6 | 7 | 리스트가 엄청 커질 수 있다고 했다. 하나하나 검사해야하므로 한 번은 무조건 리스트를 처음부터 반복해야 한다. 대신 여러번 반복 안시키도록 노력했다. 첫 세 원소를 검사해서 다수를 차지하는 것이 짝수인지 홀수인지 검사한다. 그리고 처음부터 반복해서 그 반대인 수가 나오면 리턴하는 방식을 취했다. 8 | 9 | ```python 10 | def find_outlier(integers): 11 | check = [i % 2 for i in integers[:3]] 12 | num_mod = 0 13 | if check.count(0) == 1: 14 | return integers[check.index(0)] 15 | elif check.count(1) == 1: 16 | return integers[check.index(1)] 17 | else: 18 | num_mod = check[0] 19 | for num in integers: 20 | if num % 2 != num_mod: 21 | return num 22 | ``` 23 | 24 | ## 2. 다른 해답 25 | 26 | 득표가 가장 많은 답은 따로 없었다. for반복을 한 번만 쓰면서 나보다 더 단순한 방법을 사용한 답을 골랐다. 27 | 28 | ### A. set의 뺄셈 활용 29 | 30 | filter 함수를 사용해서 짝수만 따로 뽑았다. 만약 짝수 리스트의 원소가 1개라면 바로 그 원소를 리턴하고, 만약 아니라면 전체 리스트와, 짝수 리스트를 set으로 만들어서 둘을 뺐다. 그러면 결국 홀수 하나만 남을 것이므로 그것을 리턴하면 된다. set을 활용한 점이 인상깊었다. 31 | 32 | ```python 33 | def find_outlier(integers): 34 | even = filter(lambda x: x % 2 == 0, integers) 35 | return even[0] if len(even) == 1 else list(set(integers) - set(even))[0] 36 | ``` 37 | 38 | ### A. 내 방식을 세련되게 바꿈. sorted 39 | 40 | sorted을 활용하다니 정말 기가막힌 방식이다. 첫 세 원소를 뽑아서 mod 2를 한 후 그것을 정렬했다. 그러면 어떤 상황에서든(000 111 011 001) 중간 원소는 메인 타입이 된다. 나는 하나하나 if 문을 활용했는데 훨씬 멋진 방식이다. 41 | 42 | 하지만 마지막 다른 원소를 찾는 과정에서 내 경우엔 중간에 찾아지면 바로 멈추는 방식이지만 이 경우는 무조건 전체 리스트를 모두 반복해야한다. 리스트가 엄청나게 길어질 경우 내 방식이 좀 더 효율적이라 할 수 있다. 43 | 44 | ```python 45 | def find_outlier(integers): 46 | main_type = sorted([x%2 for x in integers[:3]])[1] 47 | return [x for x in integers if x%2!=main_type][0] 48 | ``` 49 | -------------------------------------------------------------------------------- /Server/nginx.md: -------------------------------------------------------------------------------- 1 | # NGINX 2 | 3 | ## 0. 설치 4 | 5 | - CentOS에 설치하는 방법이다. 6 | - nginx 전용 저장소 등록 `/etc/yum.repos.d/nginx.repo` 파일을 만들어서 아래 코드 입력 7 | 8 | ``` 9 | [nginx] 10 | name=nginx repo 11 | baseurl=http://nginx.org/packages/centos/$releasever/$basearch/ 12 | gpgcheck=0 13 | enabled=1 14 | ``` 15 | 16 | - `sudo yum install nginx`: 설치 명령어 17 | - `systemctl enable nginx`: 재부팅시 nginx가 자동 실행되도록 하기 18 | - `systemctl start nginx`: 지금 당장 쓰기 위해서 19 | 20 | ## 1. 기본 설정 21 | 22 | ### 1.1 방화벽 설정 23 | 24 | - CentOS 7부터 기본 방화벽 시스템이 firewalld로 변경되었다. 25 | - `systemctl enable firewalld`: 재부팅시 자동으로 해당 방화벽이 실행되도록 변경 26 | - `systemctl start firewalld`: 지금 당장 재부팅하지 않고 실행해야하니까 명령어 실행한다. 27 | - `yum install firewalld`: 해당 방화벽을 관리할 수 있는 패키지다. 28 | - 80포트를 허용해야하므로 아래 명령어 순차 실행 29 | + `firewall-cmd --permanent --zone=public --add-service=http` 30 | + `firewall-cmd --permanent --zone=public --add-service=https` 31 | + `firewall-cmd --reload` 32 | 33 | ### 1.2 설정 파일 34 | 35 | - `/etc/nginx`: nginx 설정파일이 위치 36 | + `/etc/nginx/nginx.conf`: 기본 설정 파일이다. 37 | + `/etc/nginx/conf.d`: 위 기본 설정 파일에서 `server` 블락을 보면 이 디렉토리의 .conf 파일을 include하는 것을 볼 수 있다. server 설정해주면 된다. 38 | - `/usr/share/nginx/html`: 디폴트 사용자 디렉토리 39 | 40 | ## etc. 에러 예시 41 | 42 | - 80 port 에러 43 | + nginx를 start했을 때 `[emerg]: bind() to 0.0.0.0:80 failed (98: Address already in use)` 라는 에러가 난다면 44 | + `yum install -y psmisc` 패키지 설치한 후 45 | + `sudo fuser -k 80/tcp` 명령으로 80포트 사용하는 process를 없앤다. 46 | + 그 후 다시 start 해주면 된다. `systemctl start nginx.service` 47 | - CentOS에서 루트 유저 만들기: `usermod -aG wheel username` 48 | - uWSGI 설치하기 49 | + `yum groupinstall "Development Tools"` 50 | + `yum install python-devel` 51 | + `pip install uwsgi` 52 | -------------------------------------------------------------------------------- /Python/codewars/060_dont_eat_the_last_cake.md: -------------------------------------------------------------------------------- 1 | # #60 Don't Eat the Last Cake! 2 | 3 | 독이 든 케이크가 한 개 있는 케이크들이 있다. 독이 든 것을 먹으면 지는 게임이다. 독 케이크는 명확하게 표시되어있기 때문에 마지막에 먹게될 것이다. 즉 마지막 케이크를 먹는 사람이 지는 게임이다. 4 | 5 | - 마지막 케이크를 먹으면 지는 게임 6 | - 자기 턴에 1개, 2개, 3개씩 먹을 수 있는데 앞 턴에 상대가 먹은 수는 고를 수 없다. 앞 턴에 상대가 2개를 먹으면 나는 1개, 3개 중에서만 먹을 수 있다. 첫 시작은 1, 2, 3개 모두 가능 7 | - 만약 앞 턴에 1개를 먹었는데 다음에 케이크가 1개만 남았을 경우엔 턴을 실행할 수 없기 때문에 스킵된다. 그러면 상대가 한 번 더 케이크를 먹게 된다. 8 | - 먼저할지, 나중에할지 선택 가능하다. 9 | 10 | Player 클래스를 만드는 문제다. 처음에 시작할지 말지를 결정하는 `firsmove`, 케이크 몇 개를 먹을지 정하는 `move`를 구현하면 된다. 11 | 12 | ## 1. 내 코드 13 | 14 | ```py 15 | class Player: 16 | def __init__(self, cakes): 17 | self.cakes = cakes 18 | 19 | def firstmove(self, cakes): 20 | return cakes > 2 and cakes % 4 != 2 21 | 22 | def move(self, cakes, last): 23 | return 3 if cakes % 4 < 3 else 1 24 | ``` 25 | 26 | - 술게임 베스킨라빈스 31의 필승 공식이 적용된다. 상대에게 `4n + 2` 값을 던져주면 무조건 이긴다. 하지만 베스킨라빈스 게임에서와 달리 상대방이 앞턴에 선택한 숫자를 못 고르기 때문에 단순 계산으로 계속 4n+2를 던져줄 순 없다. 예를 들어 컴퓨터가 10에서 2를 골라 8을 내게 줬을 때, 내가 다시 2를 줘서 4n+2인 6을 던져줄 수 없다. 2가 이미 쓰였기 때문이다. 27 | - `firstmove`: 케이크 시작 수가 4n+2일 때만 상대부터 시작하게 해주면 되고, 나머지는 내가 먼저 시작한다. 다만 케이크 수가 1일 땐 상대가 먼저 시작하게 해야한다. 28 | - `move` 29 | + `4n+3`: 1을 골라서 4n+2를 상대에게 준다. 내 턴에 4n+3이 되는 경우는 게임 시작 때 혹은 아래 4n의 경우에서 내가 3을 고르고 상대가 2를 고른 경우다. 즉 내가 1을 고르지 못할 경우의 수는 없다. 30 | + `4n+1`: 3을 골라서 4n+2를 상대에게 준다. 4n+1이 내 턴에 오는 경우 역시 게임 시작 때와 상대가 4n+2였을 때 1을 고른 경우다. 역시 내가 3을 고르지 못할 경우는 없다. 31 | + `4n`: 가장 중요한 부분이다. 같은 방식으로 2를 고르는 것이 아니라 3을 고른다. 그러면 4n+1이 상대에게 넘어가게 되고 1이나 2만 고를 수 있게 된다. 상대가 1을 고르면 다시 4n이 나에게 넘어오게 되고, 2를 고르면 4n+3이 되어서 내가 다시 1을 골라 4n+2를 상대에게 줄 수 있다. 4n+2도 losing position이지만 4n도 그렇다. 계속 4n이 상대에게 넘어가게 되면 결국 내가 4에서 3을 골라 1을 주게된다. 32 | + `4n+2`: 위 3가지 경우에서 계속 회피했기 때문에 불가능한 사건이다. 33 | -------------------------------------------------------------------------------- /JavaScript/codewars/003_vampire_number.md: -------------------------------------------------------------------------------- 1 | # #3 Vampire Number 2 | 3 | 두 수를 매개변수로 받아서 곱한다. 곱한 수가 매개변수의 두 수로 그대로 이루어져있으면 true를 리턴한다. 예를 들어 6과 21을 곱했으면 6, 2, 1이라는 숫자가 그대로 존재해야 한다. 곱의 결과가 126이므로 true다. 4 | 5 | ## 1. 내 코드 6 | 7 | 무지하게 길다. 파이썬에 익숙해서 짜던대로 짜면 다른 결과를 내놓는 경우가 다반사였다. 특히 Array로 타입을 바꾸는 것, 리스트와 String에서 `in`을 써서 원소가 있는지 알아보는 것 등이 파이썬과 달랐다. 그래서 아래처럼 무식하게 짰다. 8 | 9 | ```js 10 | var vampire_test = function(a, b){ 11 | var a_array = []; 12 | for (var i = 0; i < String(a).length; i++) { 13 | a_array.push(String(a)[i]); 14 | } 15 | var b_array = []; 16 | for (var i = 0; i < String(b).length; i++) { 17 | b_array.push(String(b)[i]); 18 | } 19 | var ab_array = []; 20 | for (var i = 0; i < String(a*b).length; i++) { 21 | ab_array.push(String(a*b)[i]); 22 | } 23 | 24 | pre = a_array.concat(b_array).sort(); 25 | pos = ab_array.sort(); 26 | if (pre.length !== pos.length) 27 | return false; 28 | for (var i = 0; i < pre.length; i++) 29 | if (pre[i] !== pos[i]) 30 | return false; 31 | return true; 32 | } 33 | ``` 34 | 35 | ## 2. 다른 해답 36 | 37 | 아직 내가 모르는 함수들이 많다. 아래처럼 짜도록 차근차근 공부하자. 모든 답이 다음 코드처럼 `''+Number`, `split`, `sort`, `join`을 사용했다. 38 | 39 | - `숫자형 + ''` : 빈 문자열을 숫자와 덧셈하면 `String(숫자형)`과 같은 효과다. 40 | - `split(thing)` : thing을 기준으로 split한다. 41 | - `sort` : Array 뒤에서 호출되어 정렬한다. 42 | - `join(thing)` : Array의 원소들을 thing으로 연결한다. 마지막에 join을 쓰는 이유는 Array끼리 비교가 불가능하기 떄문이다. 같은 원소를 가지고 있더라도 Array끼리는 `===` 비교에서 무조건 false를 리턴한다. join을 통해 문자열로 만들어 비교해줘야 한다. 43 | - 결국 내 방식과 같은 방식인데 함수를 활용해서 코드를 극도로 줄였다. 44 | 45 | ```js 46 | function vampire_test(a, b){ 47 | return sortStr(a + '' + b) == sortStr(a * b + ''); 48 | } 49 | function sortStr(v){ return v.split('').sort().join('') } 50 | ``` 51 | -------------------------------------------------------------------------------- /Python/Django/source/django_girls_blog_tutorial/static/admin/js/prepopulate.js: -------------------------------------------------------------------------------- 1 | /*global URLify*/ 2 | (function($) { 3 | 'use strict'; 4 | $.fn.prepopulate = function(dependencies, maxLength, allowUnicode) { 5 | /* 6 | Depends on urlify.js 7 | Populates a selected field with the values of the dependent fields, 8 | URLifies and shortens the string. 9 | dependencies - array of dependent fields ids 10 | maxLength - maximum length of the URLify'd string 11 | allowUnicode - Unicode support of the URLify'd string 12 | */ 13 | return this.each(function() { 14 | var prepopulatedField = $(this); 15 | 16 | var populate = function() { 17 | // Bail if the field's value has been changed by the user 18 | if (prepopulatedField.data('_changed')) { 19 | return; 20 | } 21 | 22 | var values = []; 23 | $.each(dependencies, function(i, field) { 24 | field = $(field); 25 | if (field.val().length > 0) { 26 | values.push(field.val()); 27 | } 28 | }); 29 | prepopulatedField.val(URLify(values.join(' '), maxLength, allowUnicode)); 30 | }; 31 | 32 | prepopulatedField.data('_changed', false); 33 | prepopulatedField.change(function() { 34 | prepopulatedField.data('_changed', true); 35 | }); 36 | 37 | if (!prepopulatedField.val()) { 38 | $(dependencies.join(',')).keyup(populate).change(populate).focus(populate); 39 | } 40 | }); 41 | }; 42 | })(django.jQuery); 43 | -------------------------------------------------------------------------------- /JavaScript/React/weather_ajax_tutorial.md: -------------------------------------------------------------------------------- 1 | # Weather AJAX tutorial 2 | 3 | 검색창을 만들어서 지역을 검색하면 아래쪽에 날씨 정보가 추가되는 예제. 다음 [보일러플레이트](https://github.com/StephenGrider/ReduxSimpleStarter)를 사용한다. 4 | 5 | ## 0. 구조 6 | 7 | ![Imgur](http://i.imgur.com/WNFZhFU.png) 8 | 9 | ## 1. SearchBar 10 | 11 | - 위 구조에서 봤을 때 SearchBar는 Container다. 입력된 검색어를 관리해줘야 한다. `src/containers/search_bar.js` 파일을 생성하고 해당 class를 다음처럼 생성. 12 | 13 | ```js 14 | import React, { Component } from 'react'; 15 | 16 | export default class SearchBar extends Component { 17 | constructor(props) { 18 | super(props); 19 | this.state = { term: '' }; 20 | this.onInputChange = this.onInputChange.bind(this); 21 | } 22 | onInputChange(event) { 23 | this.setState({ term: event.target.value }); 24 | } 25 | render() { 26 | return ( 27 |
28 | 34 | 35 | 36 | 37 |
38 | ); 39 | } 40 | } 41 | ``` 42 | 43 | - `components/app.js` 파일에 위에서 만든 SearchBar 클래스를 import하고 init한다. 44 | - controlled field 개념 다시 짚기: form element이 value가 state의 value에 의해 결정되는 것. 우리가 입력한 것이 아니다. 45 | - 검색어는 redux-level까지 갈 필요가 없으므로 해당 Component의 state로만 구현해서 쓴다. class를 만들고 내부 constructor에서 `this.state`를 만든다. 46 | - `onChange` 속성에 함수 레퍼런스를 지정할 때 this 설정하는 문제는 위처럼 bind를 활용할 수 있다. constructor에서 bind를 해준 것으로 재설정하는 방식. 47 | -------------------------------------------------------------------------------- /JavaScript/codewars/015_guess_the_gifts.md: -------------------------------------------------------------------------------- 1 | # #15 Guess the gifts! 2 | 3 | wishlist array에는 name, size, clatters, weight 키를 가진 object들이 여러개 들어있고 presents array에는 wishlist의 object에서 name 키가 없는 object들이 들어있다. presents array의 object가 무엇인지 맞추는 함수다. 4 | 5 | ## 1. 내 코드 6 | 7 | ```js 8 | function guessGifts(wishlist, presents) { 9 | var result = []; 10 | wishlist.forEach(function(eWish) { 11 | presents.forEach(function(ePre) { 12 | if (eWish['size'] === ePre['size'] && 13 | eWish['clatters'] === ePre['clatters'] && 14 | eWish['weight'] === ePre['weight']) 15 | if (!result.contains(eWish['name'])) 16 | result.push(eWish['name']); 17 | }); 18 | }); 19 | return result; 20 | } 21 | 22 | Array.prototype.contains = function(obj) { 23 | var i = this.length; 24 | while (i--) 25 | if (this[i] === obj) 26 | return true; 27 | return false; 28 | } 29 | ``` 30 | 31 | - 내 코드는 왜 이렇게 긴가. 32 | - wishlist의 원소를 하나하나 돌고, 그 원소마다 presents 리스트에 있는 원소인지를 확인해서 맞으면 result에 넣었다. 33 | - 확인 조건은 size, clatters, weight 값이 똑같아야 하는 것. 그리고 중복 방지를 위해 contains 함수를 새로 만들어서 result array에 있는지 없는지 확인했다. 34 | 35 | ## 2. 다른 해답 36 | 37 | ```js 38 | function guessGifts(wishlist, presents) { 39 | return wishlist.filter(function(x){ 40 | return presents.some(function(y){ 41 | return x.size == y.size && x.clatters == y.clatters && x.weight == y.weight; 42 | }); 43 | }).map(function(x){ return x.name; }); 44 | } 45 | ``` 46 | 47 | - 원리는 내 코드와 같지만 `filter`와 `some` 함수를 통해 코드를 간결하게 했다. 자주 이 함수들 써서 익숙해져야겠다. 그래야 문제를 보면 바로 생각이 난다. 이 함수를 쓸 생각도 못했다. 48 | - filter를 써서 조건에 맞는 object를 골라내고, map으로 이름만 뽑아 리턴했다. 49 | - 사이에 조건은 나와 같고 some 함수로 중복을 제거했다. presents array에서 하나라도 조건을 만족하는게 있으면 true를 리턴하기 때문에 자연스럽게 중복이 제거된다. `==` 대신 `===` 를 쓰는게 더 나았을 것 같다. 50 | -------------------------------------------------------------------------------- /Python/codewars/018_order_weight.md: -------------------------------------------------------------------------------- 1 | # #18 Weight for weight 2 | 공백으로 구분되는 몸무게들이 적혀있는 문자열을 입력 받는다. 몸무게 각 자리 수의 합을 기준으로 오름차순으로 몸무게 원래 값들을 정렬한다. 만약 각 자리 수의 합이 같다면 원래 몸무게를 문자열이라고 했을 때 오름차순으로 정렬되면 된다. 3 | 4 | ## 1. 내 코드 5 | 6 | - 문자열을 공백 기준으로 split 후 리턴값인 리스트를 for문으로 반복했다. 7 | - 각 자리 수의 합을 key로, 원래 숫자가 담긴 리스트를 value로 하는 딕셔너리를 만들었다. 각 자리 수의 합이 같을 경우를 대비해서 리스트를 value로 했으며, 같은 경우엔 리스트에 append시켰다. 정렬은 그 때 그 때 sort를 활용했다. 8 | - 딕셔너리에서 키값을 뽑아내어 리스트로 만든 후 정렬했다. 9 | - 정렬된 키 리스트에서 하나씩 뽑아내어 딕셔너리의 값을 뽑아낸 후 join해서 리턴했다. 딕셔너리의 value 자체가 리스트여서 두 번 join했다. 10 | 11 | ```python 12 | def order_weight(strng): 13 | match = {} 14 | for str_num in strng.split(): 15 | key = sum(int(i) for i in str_num) 16 | if key in match: 17 | match[key].append(str_num) 18 | match[key].sort() 19 | else: 20 | match[key] = [str_num] 21 | ordered_list = list(match.keys()) 22 | ordered_list.sort() 23 | return " ".join(" ".join(match[key]) for key in ordered_list) 24 | ``` 25 | 26 | ## 2. 다른 해답: sorted 함수 사용 27 | sort 함수에(혹은 sorted) 정렬 기준을 지정할 수 있다는게 중요. 기억하자. 28 | 29 | - ```sorted(iterable[, key][, reverse])``` 형태로 사용된다. 30 | - iterable을 매개변수로받아서 정렬한 후 리턴한다.(디폴트는 오름차순) 31 | - key와 reverse 매개변수가 있으며, 이를 사용하려면 명칭까지 적어줘야 한다. key=무엇, reverse=무엇 이런식으로. 32 | - key: 함수가 들어간다. lambda가 들어갈 수도 있다. iterable의 원소 하나가 이 함수에 매개변수로 들어가며, 리턴된 값이 비교값으로 사용된다. key의 기본값은 None이라서 아무것도 안 적으면 원소 값 자체가 비교된다. 33 | - reverse: True, False 값이 들어간다. 기본값은 False이며 True가 적용되면 key의 비교가 반대로 적용된다. 34 | - 풀이 방식: 우선 문자열을 split으로 쪼개자마자 정렬했다. 자리수합이 같을 경우의 정렬 이슈를 해결했다. 그 후에 다시 정렬을 하는데 그 기준은 각자리수의 합으로 지정했다. 정렬된 리스트를 공백 한 칸씩 띄워붙여 리턴했다.(쩐다) 35 | 36 | ```python 37 | def order_weight(_str): 38 | return ' '.join(sorted(sorted(_str.split(' ')), key=lambda x: sum(int(c) for c in x))) 39 | ``` 40 | -------------------------------------------------------------------------------- /Python/codewars/037_metric_units_1.md: -------------------------------------------------------------------------------- 1 | # #37 Metric Units - 1 2 | 3 | 자연수를 매개변수로 받아서 아래 표의 심볼을 활용하여 소수점 첫째자리까지 나타내면 된다. 예를 들어 51500m는 5.15km인 식이다. 4 | 5 | | name | symbol | 1000**m | 10**n | 6 | |-------|--------|---------|-------| 7 | | yotta | Y | 8 | 24 | 8 | | zetta | Z | 7 | 21 | 9 | | exa | E | 6 | 18 | 10 | | peta | P | 5 | 15 | 11 | | tera | T | 4 | 12 | 12 | | giga | G | 3 | 9 | 13 | | mega | M | 2 | 6 | 14 | | kilo | k | 1 | 3 | 15 | 16 | ## 1. 내 코드 17 | 18 | - x 값으로 자연수지만 float 타입으로 들어오는 경우가 있어서 integer 타입으로 바꿔줬다. 19 | - 심볼을 리스트화했다. 0번째 인덱스는 쓰이지 않으므로 내 마음대로. 20 | - 큰수부터 나눠지는지 테스트할 것이므로 8에서 0까지 역순으로 for문을 돌았다. 여기서 뽑아진 i는 1000의 지수로 쓰였다. 21 | - 만약 x가 1000의 i제곱으로 나눴을 때 몫이 있다면 그 단위로 변환할 수 있음을 의미한다. float 타입으로 바꿔서 다시 나누고, 만약 정수라면 뒤에 소수점을 없애기 위해 integer 타입으로 결과를 바꿔준다. 22 | - 반복문에서 해당사항이 없다면 1000 미만의 숫자이므로 바로 'm'을 붙여서 리턴한다. 23 | 24 | ```python 25 | def meters(x): 26 | x = int(x) 27 | symbols = ['CODEWARS', 'k', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y'] 28 | for i in range(8, 0, -1): 29 | if x / 1000**i: 30 | result = float(x) / 1000**i 31 | if result.is_integer(): 32 | result = int(result) 33 | return str(result) + symbols[i] + 'm' 34 | return str(x) + 'm' 35 | ``` 36 | 37 | ## 2. 다른 해답 38 | 39 | 아래 답이 가장 많았다. 1000 이상일 경우 1000.0으로 나누면서 반복을 하는데 i 값을 늘려가면서 인덱스를 상향했다. 만약 8 이상일 경우엔 무조건 8로 맞추는 코드가 추가로 있으면 좋을 것 같다. 특히 `%g`를 활용한 것이 인상깊었다. 1.0일 경우 1로 바꿔서 출력을 해줘야하는데 %g로 간단히 해결했다. 40 | 41 | ```python 42 | def meters(x): 43 | s = ['m', 'km', 'Mm', 'Gm', 'Tm', 'Pm', 'Em', 'Zm', 'Ym'] 44 | i = 0 45 | while x >= 1000: 46 | x /= 1000.0 47 | i += 1 48 | return '%g%s' % (x, s[i]) 49 | ``` 50 | -------------------------------------------------------------------------------- /Python/codewars/042_get_perfect_power.md: -------------------------------------------------------------------------------- 1 | # #42 What's a Perfect Power anyway? 2 | 3 | 매개변수로 받은 숫자가 제곱수인지 판별하는 함수다. 수를 `m의 k승` 형태로 표현해서 `[m, k]`를 리턴한다. 예를 들어 125라면 [5, 3]을 리턴하고 36이라면 [6, 2]를 리턴한다. 4 | 5 | ## 1. 내 코드 6 | 7 | ```py 8 | from functools import reduce # python 3.x 9 | from fractions import gcd 10 | from operator import mul 11 | 12 | def isPP(n): 13 | primes = get_primes(n) 14 | g = reduce(lambda x, y: gcd(x, y), primes.values()) 15 | if g == 1: return None 16 | base = reduce(mul, [k**(v/g) for k, v in primes.items()]) 17 | return [base, g] 18 | 19 | def get_primes(n): 20 | k = 2 21 | result = {} 22 | while n != 1: 23 | while True: 24 | if n % k == 0: 25 | if k in result: 26 | result[k] += 1 27 | else: 28 | result[k] = 1 29 | n /= k 30 | else: 31 | break 32 | k += 1 33 | return result 34 | ``` 35 | 36 | - 소인수분해하는 함수를 만들었다. 예를 들어 100을 입력받으면 `{2:2, 5:2}`를 리턴하는 형태다. 37 | - 여기서 value에 해당하는 지수들의 최대공약수를 구했다. 최대 공약수가 1이 아니라면 완전 제곱수로 나타낼 수 있다. 38 | - 소인수 분해한 딕셔너리에서 각 키 값에 밸류를 g로 나눈 값을 곱해준다. 이렇게 구해진 키값들을 모두 곱하면 최종 리턴값의 첫 번째 원소인 밑 수가 된다. 39 | 40 | ## 2. 다른 해답 41 | 42 | ```py 43 | from math import log, sqrt 44 | 45 | def isPP(n): 46 | for b in xrange(2, int(sqrt(n))+1): # python 3.x -> use 'range' 47 | e = int(round(log(n, b))) 48 | if b ** e == n: 49 | return [b, e] 50 | return None 51 | ``` 52 | 53 | - 어떤 큰 수의 경우에선 내 코드가 바로 답을 내놓는데 반해, 이 코드는 몇 초가 걸리는 등의 성능 차이가 있기도 했다. 하지만 내 경우에도 느린 경우가 있어서 큰 차이는 없어보인다. 54 | - 에라토스테네스의 체의 원리에서처럼 딱 제곱근 숫자까지만 for 반복했다. log 함수를 써서 매개변수로 받은 n이 b의 제곱수라면 [b, e]를 리턴했다. 나도 처음에 이 방식을 썼었는데 round를 쓸 생각을 못했다. 내 경우 로그함수의 리턴값이 3.0000004가 나올 때가 있었는데 이 때 이 값으로 제곱해봤더니 원래 값과 달랐다. 그래서 이 방식이 아니구나 싶어서 넘겼는데 이렇게 오차를 피해갔다. 기억해두자. 55 | -------------------------------------------------------------------------------- /JavaScript/codewars/011_good_vs_evil.md: -------------------------------------------------------------------------------- 1 | # #11 Good vs Evil 2 | 3 | 천사팀 6 유닛, 악마팀 7 유닛이 있다. 각 유닛별로 점수가 다르다. 각 팀의 유닛 마리 수 정보를 매개변수로 받아서 누가 이겼는지 리턴하는 함수다. 4 | 5 | ## 1. 내 코드 6 | 7 | ```js 8 | function goodVsEvil(good, evil){ 9 | function calculate(race, worth) { 10 | var result = 0; 11 | race = race.split(' '); 12 | for (var i = 0; i < race.length; i++) { 13 | result += 1 * race[i] * worth[i] 14 | } 15 | return result; 16 | } 17 | var good_worth = [1, 2, 3, 3, 4, 10]; 18 | var evil_worth = [1, 2, 2, 2, 3, 5, 10]; 19 | 20 | var good_score = calculate(good, good_worth); 21 | var evil_score = calculate(evil, evil_worth); 22 | 23 | if (good_score > evil_score) 24 | return "Battle Result: Good triumphs over Evil" 25 | else if (good_score < evil_score) 26 | return "Battle Result: Evil eradicates all trace of Good" 27 | else 28 | return "Battle Result: No victor on this battle field" 29 | } 30 | ``` 31 | 32 | - 팀과 유닛 점수 정보를 입력받아서 점수를 계산하는 함수를 내부에 만든다. for 반복을 돌아서 매칭되는 것을 곱해서 결과값에 더한 후 리턴한다. 33 | - 만든 함수를 각각 적용하여 if로 분기해서 마무리한다. 34 | 35 | ## 2. 다른 해답 36 | 37 | ```js 38 | function goodVsEvil(good, evil) { 39 | var getWorth = function( side, worth ) { 40 | return side.split(' ').reduce( function(result, value, index) { 41 | return result + (worth[index] * value); 42 | }, 0); 43 | } 44 | 45 | var result = getWorth( good, [1,2,3,3,4,10] ) - getWorth( evil, [1,2,2,2,3,5,10] ); 46 | 47 | return result > 0 ? "Battle Result: Good triumphs over Evil" : 48 | result < 0 ? "Battle Result: Evil eradicates all trace of Good" : 49 | "Battle Result: No victor on this battle field"; 50 | } 51 | ``` 52 | 53 | - reduce는 함수와 초기값을 매개변수로 받는다. 매개변수의 함수는 순서대로 이전값, 현재값, 현재인덱스, 배열을 매개변수로 받는다. 처음에 나도 reduce를 사용하려 했지만 현재인덱스를 이용할 생각을 못했다. 깔끔하다. 54 | - 아래는 똑같다. 삼항 연산자를 연속으로 사용하는 걸로 if를 대신했다. 55 | -------------------------------------------------------------------------------- /Algorithm/binary_search.md: -------------------------------------------------------------------------------- 1 | # Binary search 2 | 3 | ## 1. 의미 4 | 5 | - 이진 탐색은 전체 데이터를 순서대로 검색하는 것이 아니라, 데이터를 반으로 쪼개서 좌우에서 찾는다. 6 | - 사용하는 변수들 7 | + `start`: 시작 인덱스로 항상 찾는 수보다 작은 값을 가리킨다. 8 | + `end`: 마지막 인덱스로 항상 찾는 수보다 큰 값을 가리킨다. 9 | + `mid`: start와 end를 합해서 2로 나눈 값, 중앙값이다. 10 | - 특정 값을 찾는 경우 11 | + start, end 값을 확인할 때 바로 찾아질 수 있다. 12 | + 찾고자 하는 데이터가 중앙값보다 크면 우측 데이터 중에서 다시 찾고, 중앙값보다 작으면 왼쪽 데이터 중에서 찾는다. 13 | + start와 end 인덱스가 바로 인접하면(붙으면) 찾는 수는 없다는 의미 14 | - 데이터가 정렬되어있음을 가정한다. 15 | - 시간복잡도는 `{\log_2 n}`, 즉 `log n`으로 매우 작다. 16 | 17 | ## 2. 코드 18 | 19 | ### 2.1 C 20 | 21 | ```c 22 | int binary_search(int arr[], int size, int target) 23 | { 24 | int start = 0 25 | int end = size - 1 26 | int mid; 27 | 28 | if (arr[start] == target) 29 | { 30 | return start 31 | } 32 | if (arr[end] == target) 33 | { 34 | return end 35 | } 36 | while (start <= end) 37 | { 38 | mid = (start + end) / 2; 39 | if (arr[mid] > target) 40 | end = mid - 1; 41 | else if (arr[mid] < target) 42 | start = mid + 1; 43 | else 44 | return mid; 45 | } 46 | return -1; 47 | } 48 | ``` 49 | 50 | - `start`는 왼쪽 끝 인덱스, `end`는 마지막 인덱스이다. 만약 start가 end보다 커지는 때가 오면 사이에 정답이 없으므로 -1을 리턴한다. 51 | - `mid`는 중앙값을 의미한다. 52 | - 중앙값이 찾으려는 값 `target`보다 크면 `end`를 중앙 바로 전 값으로 당긴다. 반대라면 `start` 값을 중앙 바로 다음 값으로 민다. 찾으려는 영역을 재설정. 53 | - 값을 찾으면 해당 원소 값이 속한 인덱스인 `mid`를 바로 리턴하고 아니면 계속 반복문을 돈다. 54 | 55 | ### 2.2 Python 56 | 57 | ```py 58 | def binarySearch(array, value): 59 | start = 0 60 | end = len(array) 61 | 62 | while start+1 < end: 63 | mid = (start + end) // 2 64 | if array[mid] < value: 65 | start = mid 66 | elif array[mid] > value: 67 | end = mid 68 | else: 69 | return True 70 | return False 71 | ``` 72 | -------------------------------------------------------------------------------- /Python/codewars/062_linkedlist_02.md: -------------------------------------------------------------------------------- 1 | # #62 Linked Lists - Length & Count 2 | 3 | 링크드 리스트 시리즈 2번째. 61번째 푼 문제에서 이어진다. 길이와, 특정 데이터의 개수를 구하는 문제다. 4 | 5 | ## 1. 내 코드 6 | 7 | ```py 8 | class Node(object): 9 | def __init__(self, data): 10 | self.data = data 11 | self.next = None 12 | 13 | def length(node): 14 | if node == None: return 0 15 | cnt = 1 16 | while(node.next): 17 | node = node.next 18 | cnt += 1 19 | return cnt 20 | 21 | def count(node, data): 22 | if node == None: return 0 23 | cnt = 1 if node.data == data else 0 24 | while(node.next): 25 | node = node.next 26 | if node.data == data: 27 | cnt += 1 28 | return cnt 29 | ``` 30 | 31 | - 만약 None이 매개변수로 들어오면 분기해준다. 32 | - node의 next가 있을 때를 조건으로 줬는데 아래 다른 해답처럼 node 자체를 조건으로 주는게 더 깔끔했을 것. 33 | 34 | ## 2. 다른 해답 35 | 36 | ### 2.1 내 코드를 더 깔끔하게 37 | 38 | Node 클래스 객체 자체를 조건으로 두니까 다 해결됐다. 39 | 40 | ```py 41 | class Node(object): 42 | def __init__(self, data): 43 | self.data = data 44 | self.next = None 45 | 46 | def length(node): 47 | leng = 0 48 | while node: 49 | leng += 1 50 | node = node.next 51 | return leng 52 | 53 | def count(node, data): 54 | c = 0 55 | while node: 56 | if node.data==data: 57 | c += 1 58 | node = node.next 59 | return c 60 | ``` 61 | 62 | ## 2.2 재귀 63 | 64 | ```py 65 | class Node(object): 66 | def __init__(self, data): 67 | self.data = data 68 | self.next = None 69 | 70 | def length(node): 71 | if node: 72 | return 1 + length(node.next) 73 | return 0 74 | 75 | def count(node, data): 76 | if node: 77 | if node.data == data: 78 | return 1 + count(node.next, data) 79 | return count(node.next, data) 80 | return 0 81 | ``` 82 | 83 | - length, count 함수 모두 재귀로 짰다. 정말 깔끔하다. 84 | - 재귀가 잘 짜면 정말 아름답다. 85 | -------------------------------------------------------------------------------- /ETC/tmux.md: -------------------------------------------------------------------------------- 1 | # tmux 2 | 3 | 터미널에서는 일반적으로 하나의 탭이 곧 하나의 세션이다. 탭을 새로 생성하면 세션이 만들어지고, 탭을 종료하면 세션도 종료된다. 만약 굉장히 오랜 시간 연산을 해야하는 프로그램을 실행한다면 터미널을 계속 열어둬야한다. 24시간이 걸린다면 노트북을 덮지 않고 계속 열어둔 상태로 가지고 다녀야한다. 좀 더 편리하게 터미널을 사용해보자. 4 | 5 | ## 0. 참고 링크 6 | 7 | 설치는 `brew install tmux` 8 | 9 | - official: https://github.com/tmux/tmux 10 | - shoutcut&cheatsheet: https://gist.github.com/MohamedAlaa/2961058 11 | - tmux course: https://robots.thoughtbot.com/a-tmux-crash-course 12 | - tmux guide: http://www.hamvocke.com/blog/a-quick-and-easy-guide-to-tmux/ 13 | - tmux book: https://leanpub.com/the-tao-of-tmux/read#leanpub-auto-styles 14 | - outsider: https://blog.outsider.ne.kr/699#footnote_699_1 15 | 16 | ## 1. 구조 17 | 18 | - 가장 상위에 세션이 존재하고, 하나의 세션엔 연결된 여러 하위 window, pane이 존재 19 | + window는 말 그대로 하나의 창을 말하고, 20 | + pane은 윈도우를 여러 창으로 나눴을 때 각각을 말한다. 21 | - 세션을 kill하지 않는 이상 네트워크 접속과 상관없이 세션은 계속 유지된다. 22 | - 유지된 세션을 사용자가 추가 작업할 수 있도록 터미널 화면으로 띄우는 것을 attach라고 하고, 백그라운드로 보내는 것을 detach라고 한다. 23 | - 세션을 완전히 종료하고 싶을 때 kill한다. 24 | 25 | ## 2. 주요 명령어 26 | 27 | ### 2.1 command 28 | 29 | - 세션 시작 30 | + `tmux` : 세션 시작. 이름 자동 설정 31 | + `tmux new -s session_name` 32 | - 기존 세션 띄우기: `tmux attach -t session_name` 33 | - 현재 존재하는 세션 리스팅: `tmux ls` 34 | - 현재 존재하는 세션 지우기: `tmux kill-session -t session_name` 35 | 36 | ### 2.2 shortcut 37 | 38 | - 생성소멸 & 붙이고 떼기 39 | + `Ctrl-b c` : Create new window 40 | + `Ctrl-b d` : Detach current client 41 | + `Ctrl-b l` : Move to previously selected window 42 | + `Ctrl-b &` : Kill the current window 43 | - 윈도우&pane 이동 44 | + `Ctrl-b n` : Move to the next window 45 | + `Ctrl-b p` : Move to the previous window 46 | + `Ctrl-b o` Switch to the next pane 47 | - 윈도우 수정 48 | + `Ctrl-b ,` : Rename the current window 49 | + `Ctrl-b %` : Split the current window into two panes 50 | + `Ctrl-b q` : Show pane numbers (used to switch between panes) 51 | - 헬프: `Ctrl-b ?` 52 | -------------------------------------------------------------------------------- /Python/codewars/047_evil_autocorrect_prank.md: -------------------------------------------------------------------------------- 1 | # 47 Evil Autocorrect Prank 2 | 3 | 사람을 앞에 두고 자꾸 여자친구와 문자를 하는 친구를 고깝게 여긴 한 프로그래머가 'you', 'u'를 'your sister'로 바꿔버리는 스크립트를 짜도록 문제를 냈다. 'I love you'가 'I love your sister'가 돼버리는 무시무시한 코드다. 대소문자는 무시하고, 'you'는 'youuuuu'처럼 뒤에 u가 더 붙어도 상관없고, 어느 단어의 일부가 아닌 것만 허용된다. 4 | 5 | ## 1. 내 코드 6 | 7 | ```py 8 | import re 9 | def autocorrect(input): 10 | REGEX = re.compile(r'^you+$|^u$', re.IGNORECASE) 11 | input = REGEX.sub('your sister', input) 12 | REGEX = re.compile(r'^you+(\W+)', re.IGNORECASE) 13 | input = REGEX.sub('your sister\g<1>', input) 14 | REGEX = re.compile(r'^u(\W+)', re.IGNORECASE) 15 | input = REGEX.sub('your sister\g<1>', input) 16 | REGEX = re.compile(r' you+(\W+)', re.IGNORECASE) 17 | input = REGEX.sub(' your sister\g<1>', input) 18 | REGEX = re.compile(r' u(\W+)', re.IGNORECASE) 19 | input = REGEX.sub(' your sister\g<1>', input) 20 | REGEX = re.compile(r'(\W+)you+$', re.IGNORECASE) 21 | input = REGEX.sub('\g<1>your sister', input) 22 | REGEX = re.compile(r'(\W+)u$', re.IGNORECASE) 23 | return REGEX.sub('\g<1>your sister', input) 24 | ``` 25 | 26 | - 전방탐색이 내 뜻대로 잘 안돼서 하드코딩했다. 27 | - 'you', 'u'가 홀로 딱 있는 경우, 맨 앞에 있는 경우, 중간에 있는 경우, 맨 뒤에 있는 경우를 각각 나눠서 모두 작업했다. 28 | - `sub` 함수에서 뒤 혹은 앞에 특수문자가 붙어나오는 경우가 있어서 단순히 ' ' 공백 한 칸으로 처리하면 안됐다. 그래서 grouping으로 그 부분만 집어서 추가해줬다. 29 | - 매우 무식한 코드다. 부끄럽다.. 그래도 통과는 했다. 30 | 31 | ## 2. 다른 해답 32 | 33 | ```py 34 | import re 35 | def autocorrect(input): 36 | return re.sub(r'(?i)\b(u|you+)\b', "your sister", input) 37 | ``` 38 | 39 | - `\b` 40 | + backreference가 아니다. backreference가 되려면 `( )` 속에서 맨 앞에 위치해야한다. 41 | + 여기서는 단어 구분자다. 패턴을 `r'\bcode\b'` 라고 쓴다면 'code'만 딱 매칭되고 'xcode', 'supercodefighter' 이것들은 매칭 안된다. 주로 whitespace로 구분되지만 `- , : . @`같은 거도 구분된다. `\b`를 파이썬 컴파일러가 백스페이스로 인식하므로 이것을 쓸 땐 꼭 raw string으로 써야한다. 42 | - `(?i)` : case insensitive를 의미한다. sub에선 대소문자 무시를 어떻게 지정해줄지 몰랐었는데 패턴 문자열에서 저런식으로 붙여주면 되는거였다. 43 | -------------------------------------------------------------------------------- /Algorithm/exercises/parenthesis.md: -------------------------------------------------------------------------------- 1 | # 괄호 관련 문제 2 | 3 | 스택을 활용한 문제다. 괄호들이 열고 닫히는 관계가 성립하기 때문에 스택을 활용하면 매우 쉽게 풀린다. 4 | 5 | ## 1. 괄호 계산 순서 구하기 6 | 7 | ```py 8 | def find_order(p) : 9 | order = [0] * len(p) 10 | cnt = 1 11 | stack = [] 12 | for i, c in enumerate(p): 13 | if c == '(': 14 | stack.append(i) 15 | else: 16 | order[stack.pop()] = cnt 17 | order[i] = cnt 18 | cnt += 1 19 | return order 20 | 21 | def main(): 22 | p = input() 23 | print(*find_order(p)) 24 | 25 | if __name__ == "__main__": 26 | main() 27 | ``` 28 | 29 | - 주어지는 괄호 문자열은 정상적인 것으로 간주 30 | - 순서가 입력될 배열을 미리 선언한다. 길이는 괄호의 숫자만큼이다. 31 | - 여는 괄호라면 스택에 추가한다. 닫힐 때 그 괄호가 계산되는 것이므로 아직은 계산 순서가 올라가지 않는다. 해당 인덱스 값만 필요하므로 스택에 인덱스만 넣는다. 32 | - 만약 닫는 괄호라면 스택의 top에 있는 괄호와 매칭되는 것일 수 밖에 없다. 두 인덱스에 해당하는 순서 배열의 값을 cnt 값으로 변경한다. cnt는 순서이므로 추가될 때마다 1씩 올린다. 33 | 34 | ## 2. 올바른 괄호 구성인지 검증 35 | 36 | ```py 37 | def check_parenthesis(p): 38 | stack = [] 39 | for c in p: 40 | if c == '(' or c == '{' or c == '[': 41 | stack.append(c) 42 | else: 43 | if len(stack) == 0: 44 | return False 45 | open_p = stack.pop() 46 | if open_p == '(' and c != ')': 47 | return False 48 | if open_p == '{' and c != '}': 49 | return False 50 | if open_p == '[' and c != ']': 51 | return False 52 | return True if not len(stack) else False 53 | 54 | def main(): 55 | p = input() 56 | print("result:", check_parenthesis(p)) 57 | 58 | if __name__ == "__main__": 59 | main() 60 | ``` 61 | 62 | - 괄호는 `(){}[]` 형태가 들어오고 다른 문자는 들어오지 않는다고 가정 63 | - 여는 괄호가 들어오면 스택에 쌓는다. 64 | - 닫는 괄호를 만나면 65 | + 이전에 여는 괄호가 있었는지 확인한다. 스택이 비었으면 바로 False 리턴 66 | + 스택의 top에 있는 여는 괄호가 닫는 괄호와 매칭되는지 확인하고 아니라면 False를 리턴한다. 67 | - 모든 괄호를 다 검사했을 때 여전히 stack에 여는괄호가 남아있다면 제대로 안 닫힌 것이므로 False를 리턴하고 비었다면 모두 정상적으로 닫힌 것이므로 True 리턴한다. 68 | -------------------------------------------------------------------------------- /JavaScript/ajax_getstarted.md: -------------------------------------------------------------------------------- 1 | # ajax 시작하기 2 | 3 | 참고 링크: [MDN](https://developer.mozilla.org/ko/docs/AJAX/Getting_Started) 4 | 5 | AJAX는 웹 개발에서 필수다. 가장 잘 쓰이는 것은 페이지 전체를 리프레쉬 하지 않고 화면의 특정 부분을 변경할 수 있는 것이다. JavaScript를 통해 json이나 HTML 등의 텍스트 파일을 받아오고 변경할 수 있다. 6 | 7 | ## 1. 간단한 예제 8 | 9 | 출처: [w3schools](http://www.w3schools.com/ajax/) 10 | 11 | ```html 12 | 13 | 14 | 15 |

Let AJAX change this text

16 | 17 | 35 | 36 | 37 | ``` 38 | 39 | - html 40 | + 변경할 요소를 만든다. 예제에선 div#demo 요소다. 41 | + 이벤트를 일으키는 버튼을 만들고 onclick 속성을 내 함수로 지정해뒀다. 42 | - js 43 | + 버튼을 눌렀을 때 실행할 `loadDoc` 함수를 만든다. 44 | + `XMLHttpRequest` 객체 생성. IE와 다른 브라우저들을 분기한다. 45 | + `xhttp.onreadystatechange` : 요청을 보낸 후 응답을 받았을 때 어떤 행동을 할지 onreadystatechange property에 함수 형태로 대입한다. 정상적으로 동작할 때만 스크립트가 실행되도록 if문으로 감싼다. 46 | + onreadystatechange에 할당되는 함수에서 내부 코드는 원하는 형태로 짜면 되는데 XMLHttpRequest 객체의 다양한 속성을 활용할 수 있다. 위 예제에는 텍스트를 바꾸는거라서 `xhttp.responseText`를 활용했다. 47 | + XMLHttpRequest 객체를 활용해 GET 방식으로 `open()`하고, 마지막에 `send()` 해준다. open 함수엔 GET, POST 지정하고(모두 대문자), 두 번째 매개변수로 URL을 적으면 된다. 세번째로 비동기(Asynchronous) 식으로 수행될건지 여부를 넣는데 당연히 true를 적어준다. 48 | -------------------------------------------------------------------------------- /Python/tkinter_gui.md: -------------------------------------------------------------------------------- 1 | # Tkinter: Python GUI Package 2 | 3 | 참고 링크: [tutorialspoint](http://www.tutorialspoint.com/python/python_gui_programming.htm) 4 | 5 | # 0. 시작 6 | 7 | - `class Tkinter.Tk(screenName=None, baseName=None, className='Tk', useTk=1)` 8 | - `Tkinter.Tk` 클래스는 toplevel 위젯이다. 앱의 메인 윈도우로 작용한다. 매개변수 없이 아래 코드처럼 인스턴스를 만든다. 9 | - `mainloop()` 함수는 무한 반복을 도는 함수다. 스택오버플로우의 [질답](http://stackoverflow.com/questions/8683217/when-do-i-need-to-call-mainloop-in-a-tkinter-application)에서 흐름을 잘 설명해놓았다. 항상 이벤트를 받고 처리하기 위해 계속 반복을 도는 것이다. 이 함수가 실행되면 윈도우 창이 하나 뜬다. 10 | 11 | ```py 12 | import Tkinter 13 | top = Tkinter.Tk() 14 | top.mainloop() 15 | ``` 16 | 17 | # 1. Tkinter 요소들 18 | 19 | - Widgets 20 | + `Button` : 말 그대로 버튼. 21 | + `Canvas` : 선이나 원, 다각형, 사각형 등을 그리는데 사용된다. 22 | + `Checkbutton` : 체크박스로 옵션을 나타내기 위해 쓰인다. 복수 선택 가능하다. 23 | + `Entry` : 유저에게 한 줄짜리 문자열을 입력받기 위해 사용한다. 24 | + `Frame` : 다른 위젯을 담아두는 container 역할을 한다. 25 | + `Label` : 다른 위젯에 한 줄짜리 caption을 달아준다. image도 담을 수 있다. 26 | + `Listbox` : 옵션들의 리스트를 사용자에게 제공. 27 | + `Menubutton` : menu를 보여주는 위젯 28 | + `Menu` : 사용자가 다양한 명령을 지시할 수 있도록 하는 위젯. Menubutton 위젯 안에 포함된다. 29 | + `Message` : 사용자가 입력하는 여러 줄의 문자열 공간을 나타낸다. 30 | + `Radiobutton` : 많은 옵션을 라디오버튼으로 나타내게 한다. 하나만 선택 가능. 31 | + `Scale` : 슬라이더 위젯을 나타냄 32 | + `Scrollbar` : Listbox 같은 위젯에 스크롤링을 가능하게 해준다. 33 | + `Text` : 여러 줄의 텍스트를 보여주는데 사용 34 | + `Toplevel` : 분리된 윈도우 container를 제공한다. 35 | + `Spinbox` : Entry 위젯의 변형이다. 고정된 숫자값을 선택해야할 때 사용 36 | + `PanedWindow` : 수평 또는 수직으로 정렬된 pane을 포함하는 container다. 37 | + `LabelFrame` : 단순한 container 위젯이다. 복잡한 윈도우 레이아웃에서 간격을 벌리거나 container로서 작용한다. 38 | + `tkMessageBox` : 메시지 박스를 나타낸다. 39 | - Attributes 40 | + Dimensions 41 | + Colors 42 | + Fonts 43 | + Anchors 44 | + Relief styles 45 | + Bitmaps 46 | + Cursors 47 | - Geometry Management : 위젯을 부모 위젯 안에서 잘 정돈하기 위해 여러 메소드를 가지고 있다. 48 | + `pack()` : 부모 위젯에 넣기 전에 위젯들을 하나의 블록에다 담는 것. 49 | + `grid()` : 그리드 구조로 부모 위젯에 담는다. 50 | + `place()` : 부모 위젯의 특정 위치에 위치시키는 것. 51 | -------------------------------------------------------------------------------- /JavaScript/codewars/017_human_readable_time.md: -------------------------------------------------------------------------------- 1 | # #17 Human Readable Time 2 | 3 | 단순한 문제인데 꽤 헤맸다. '초'를 입력받아서 시, 분, 초 형태로 변환하는 문제다. 4 | 5 | # 1. 내 코드 6 | 7 | ```js 8 | function humanReadable(seconds) { 9 | var sec = seconds % 60 10 | var min = ((seconds - sec) / 60) % 60; 11 | var hour = (seconds - sec - min*60) / 3600; 12 | return [hour, min, sec].map(function (e) { 13 | return e < 10 ? '0' + e : e; 14 | }).join(':'); 15 | } 16 | ``` 17 | 18 | - js에선 `/`로 나눗셈을 하면 정수, 실수 할 거 없이 무조건 '제대로' 나눠버린다. 몫만 남겨주지 않는다. 예를 들어 `1/2`이든 `1.0/2`이든 간에 결과는 0.5다. 그래서 위처럼 나머지를 빼준 후에 나눗셈을 했다. 19 | - `Math.floor(floatNum)`, `parseInt(floatNum)` 함수를 썼어야 했다. 소수점 자리를 '버림'해준다. 좀 더 깔끔하게 짤 수 있었다. 20 | - 사실 `parseInt(str, rule)`는 문자열을 받아서 정수로 변환해주는 함수다. 두 번째 매개변수로 10, 8, 2 같은 진법 기준을 적용할 수도 있다. [outsider 블로그](https://blog.outsider.ne.kr/361)에 설명이 잘 나와있다. 21 | - 마찬가지로 `parseFloat(str)`도 문자열을 받아서 실수로 변환해준다. 22 | 23 | ```js 24 | parseInt("123.456"); // 123 25 | parseInt("100mile"); // 100 26 | parseInt("w25"); // NaN 27 | parseInt("05"); // 5 28 | parseInt("09"); // 0 29 | parseInt("0x35"); // 53 30 | parseInt("1101", 2); // 13 31 | parseInt("09", 10); // 9 32 | parseInt("10", 8); // 8 33 | 34 | parseFloat("123.456"); // 123.456 35 | parseFloat("100.5mile"); // 100.5 36 | parseFloat("w25"); // NaN 37 | parseFloat("05"); // 5 38 | parseFloat("09"); // 9 39 | parseFloat("0x35"); // 0 40 | ``` 41 | 42 | # 2. 다른 해답 43 | 44 | ```js 45 | function humanReadable(seconds) { 46 | var pad = function(x) { return (x < 10) ? "0"+x : x; } 47 | return pad(parseInt(seconds / (60*60))) + ":" + 48 | pad(parseInt(seconds / 60 % 60)) + ":" + 49 | pad(seconds % 60) 50 | } 51 | ``` 52 | 53 | ```js 54 | function humanReadable(seconds) { 55 | return [seconds / 3600, seconds % 3600 / 60, seconds % 60].map(function(v) { 56 | v = Math.floor(v).toString(); 57 | return v.length == 1 ? '0' + v : v; 58 | }).join(':'); 59 | } 60 | ``` 61 | -------------------------------------------------------------------------------- /JavaScript/Meteor/rocketchat_streamer.md: -------------------------------------------------------------------------------- 1 | # RocketChat Streamer 2 | 3 | 참고링크: [github readme](https://github.com/RocketChat/meteor-streamer/blob/master/packages%2Frocketchat-streamer%2FREADME.md) 4 | 5 | 서버와 클라이언트 간 통신을 위한 패키지다. subscription으로 클라이언트에 데이터를 보내는 것이 어려울 때가 있다. 이벤트 다루듯 할 수 있게 쉽게 만든 패키지다. server to client, client to server 어느 방향으로도 가능하다. 6 | 7 | ## 0. 설치 8 | 9 | ```sh 10 | meteor add rocketchat:streamer 11 | ``` 12 | 13 | 프로젝트 디렉토리에서 위 명령어로 추가 14 | 15 | ## 1. 사용 16 | 17 | ```js 18 | const streamer = new Meteor.Streamer('chat'); 19 | 20 | if(Meteor.isClient) { 21 | sendMessage = function(message) { 22 | streamer.emit('message', message); 23 | console.log('me: ' + message); 24 | }; 25 | 26 | streamer.on('message', function(message) { 27 | console.log('user: ' + message); 28 | }); 29 | } 30 | 31 | if (Meteor.isServer) { 32 | streamer.allowRead('all'); 33 | streamer.allowWrite('all'); 34 | } 35 | ``` 36 | 37 | - 위 예는 한 클라이언트에서 메시지를 보내면(`emit`) -> 서버를 거쳐서 -> 모든 다른 클라이언트들에게 retransmit 되는(`on`) 예제다. 38 | - 먼저 Streamer 객체를 만든다. 매개변수로 들어가는 문자열은 여러 Streamer가 있을 때 각각을 구분하기 위해 지정되고 unique하게 설정하면 된다. 39 | - `emit` : 데이터를 보낼 때 사용. 클라이언트에서 보내면 서버가 받고, 서버가 보내면 모든 클라이언트가 받는다. 만약 서버에서 재송신 설정이 되어있다면 클라이언트에서 보냈을 때 모든 다른 클라이언트에게 이벤트를 보낼 수 있다. 이 설정은 아래에서 다시 설명. 40 | + 첫 번째 매개변수는 해당 이벤트의 이름이고 streamer의 name과는 다르다. 41 | + 두 번째 매개변수는 보낼 데이터 42 | - `on` : `emit`으로 보낸 데이터를 받을 때 사용 43 | + 첫 번째 매개변수는 이벤트명. 같은 이벤트라면 `emit`에서와 같은 이름을 지정해야한다. 44 | + 두 번째 매개변수는 콜백 함수. 받는 데이터를 매개변수로 받는다. 45 | - `streamer.allowRead([eventName], permission);` : 서버에서만 쓰이고, 클라이언트 당 한 번만 설정되는데 데이터에 따라서 permission을 다르게 조절할 수 없다. 46 | + 이벤트명은 옵션. 써주면 특정하는거고, 안 쓰면 모든 이벤트다. 47 | + permission은 함수나 문자열을 넣는다. 함수는 event명을 매개변수로 받고 boolean을 리턴한다. 문자열은 `all`, `logged`, `none` 세 가지가 있는데 순서대로 모두 허용, 로그인한 유저에게만 허용, 허용하지 않음의 의미. 48 | - `streamer.allowEmit([eventName], permission);`: 서버에서만 쓰인다. `allowRead`와 다르게 매 번 permission을 설정하기 때문에 데이터에 따라서 다르게 적용이 가능하다. 대신 연산량이 많다. 상세 정보는 allowRead와 같음. 49 | - `streamer.allowWrite([eventName], permission);`: 서버에서만 쓰이고 이벤트를 쓸 수 있는지의 권한이다. 즉 이벤트를 만들 수 있는지, 보낼 수 있는지에 대한 권한. 50 | -------------------------------------------------------------------------------- /C/algorithm/005_n_queen.md: -------------------------------------------------------------------------------- 1 | # 005 N-Queen 알고리즘 2 | 3 | ## 1. 문제 4 | 5 | n by n 체스 판에 퀸을 n개 배치하는데 서로가 한 번에 서로에게 갈 수 없어야 한다. 즉 서로 잡아먹을 수 있는 위치에 없어야 한다. 이 때 배치할 수 있는 가짓수를 구하라. 6 | 7 | ## 2. 코드 8 | 9 | ```c 10 | #include 11 | 12 | int my_abs(int n); 13 | int check(int cur); 14 | void print_arr(int *g_arr); 15 | void ft_find(int cur); 16 | int ft_eight_queens_puzzle(void); 17 | 18 | int g_cnt = 0; 19 | int g_arr[8] = {0, 0, 0, 0, 0, 0, 0, 0}; 20 | 21 | int main(void) 22 | { 23 | printf("%d\n", ft_eight_queens_puzzle()); 24 | return (0); 25 | } 26 | 27 | int my_abs(int n) 28 | { 29 | return (n >= 0 ? n : n * -1); 30 | } 31 | 32 | int check(int cur) 33 | { 34 | int i; 35 | 36 | i = 0; 37 | while (i < cur) 38 | { 39 | if (g_arr[i] == g_arr[cur] || cur - i == my_abs(g_arr[cur] - g_arr[i])) 40 | return (0); 41 | i++; 42 | } 43 | return (1); 44 | } 45 | 46 | void print_arr(int *g_arr) 47 | { 48 | int i; 49 | 50 | i = 0; 51 | while (i < 8) 52 | { 53 | printf("%d ", g_arr[i]); 54 | i++; 55 | } 56 | printf("\n"); 57 | } 58 | 59 | void ft_find(int cur) 60 | { 61 | int i; 62 | 63 | if (cur == 8) 64 | { 65 | g_cnt++; 66 | return ; 67 | } 68 | i = 0; 69 | while (i < 8) 70 | { 71 | g_arr[cur] = i; 72 | if (check(cur)) 73 | ft_find(cur + 1); 74 | i++; 75 | } 76 | } 77 | 78 | int ft_eight_queens_puzzle(void) 79 | { 80 | ft_find(0); 81 | return (g_cnt); 82 | } 83 | ``` 84 | 85 | - 퀸의 위치를 나타내는 배열을 선언하는데 1차원 배열이다. 배열의 인덱스와 값 둘을 활용해서 인덱스는 row, 값은 col을 나타내는데 쓴다. 86 | - `if (g_arr[i] == g_arr[cur] || cur - i == my_abs(g_arr[cur] - g_arr[i]))` 이 조건은 퀸이 한 번에 갈 수 있는 곳에 다른 말이 존재하는지 검사할 때 쓰는 조건이다. 87 | + 인덱스 값 즉 row 값은 당연히 다르므로 생략하고, 컬럼 값이 같은지 체크한다. 88 | + 대각선에 위치한 원소가 있는지 검색할 때는 인덱스끼리의 차와 값끼리의 차가 같은지 보면 된다. 판에서 대각선은 기울기 1, -1의 직선이다. 두 값의 차가 같으면 기울기가 1 또는 -1이므로 대각선 상에 위치하는게 된다. 89 | - 재귀 함수를 이용해서 만약 끝까지 도달했을 때만 cnt를 1씩 증가시킨다. 끝이 아닐 때는 모두 확인해야하므로 while 반복문으로 8개 컬럼 값을 하나하나 체크하고, 체크가 오케이일 때만 다음 row로 넘어간다. 90 | -------------------------------------------------------------------------------- /JavaScript/canvas_svg/canvas_svg_s65_3.md: -------------------------------------------------------------------------------- 1 | # Canvas & SVG S65 3회차 2 | 3 | ## 1. svg 4 | 5 | - path data 6 | + M 7 | + Z 8 | + LHV 9 | + Cubic Bezier curveto 10 | + Bezier 11 | + ? 12 | - command case 13 | + uppercase: absolute coordinates 14 | + lowercase: relative coordinates 15 | - Bezier curve 16 | + publicized by Pierre Bezier 17 | + applied in 18 | * computer graphics 19 | * animation 20 | * fonts 21 | 22 | ## 2. ES6 23 | 24 | - destructing. 해체식. 좌변엔 무조건 식별자만 있어야 하는데 식이 오게 됨. 25 | 26 | ```js 27 | let [a, b] = [10, 20]; 28 | arr = [1, 2]; 29 | a = arr[0], b = arr[1]; 30 | [a, b] = arr 31 | 32 | let [a=3, b] = [1, 2, 3]; 33 | let [a,,b] = [1, 2, 3]; 34 | ``` 35 | 36 | ```js 37 | let {a:c, b:d} = {a:1, b:2}; 38 | let {a:c, b:d} = {a,b} 39 | let {c, d } = {c:a, d:b}; 40 | let {a:c, d=3} = {a,b}; 41 | ({c, d} = {c:a, d:b}); 42 | 43 | obj = {a:1, b:2}; 44 | 45 | let c = obj.a 46 | let d = obj.b 47 | 48 | let {a:c, b:d} = obj; 49 | ``` 50 | 51 | 콜론 앞이 키, 뒤가 변수 이름. 52 | 53 | 이제 역따옴표가 escape 문자열이 됨. 이 안에 모든걸 기술할 수 있다. 마크다운 문법인거네. 그리고 ${} 안에 표현식을 쓸 수 있다. 값이기만 하면. 일종의 eval 54 | 55 | 자바스크립트에는 값이라는 개념. 하나로 떨어지는 것. 반대로 문이라는 개념도 있음. if 문. 할당할 수 있는건 값. ${} 안에는 값으로 떨어지면 다 됨. expression은 안된다. 56 | 57 | ``` 58 | let a = [1, 2, 3]; 59 | let b = {a:1, b:3}; 60 | let c = `000${a} 61 | 111${b.a + b.b} 62 | 222`; 63 | 64 | console.log(c); 65 | ``` 66 | 67 | ``` 68 | let a = `${[1, 2, 3]}` // "1, 2, 3" 69 | ``` 70 | 71 | ``` 72 | let a = `${(() => 3))()}`; 73 | ``` 74 | 75 | ``` 76 | let tag = [str, ...ex] => str.reduce( 77 | (prev, curr, idx) => prev + curr + (ex[idx]?ex[idx].toString():''), '' 78 | ); 79 | ``` 80 | 81 | ``` 82 | let a = 'abcabc'; 83 | a.replace(/(a|b)c(a)/g, function(v0, v1, v2){ 84 | return ''; 85 | }); 86 | ``` 87 | 88 | ``` 89 | console.log(tag`1111 90 | ${1} 91 | 22 92 | ${2} 93 | `); 94 | 95 | let tag = (stringArray, ...values) => 'aaa'; 96 | ``` 97 | 98 | ```js 99 | let tag = (str, ...ex) => (ex.forEach((v) => console.log(v)), 'aa'); 100 | ``` 101 | -------------------------------------------------------------------------------- /Python/codewars/005_find_the_longest_gap.md: -------------------------------------------------------------------------------- 1 | # #5 Find the longest gap 2 | 정수를 매개변수로 받아서 2진수로 변환한 후 1과 1 사이의 간격 중 가장 큰 수치를 리턴하는 함수를 짜는 문제. 3 | 4 | ## 1. 내 코드 5 | 매우 길다. 10진수를 2진수로 만드는 코드를 직접 하나하나 짰다. 6 | 7 | ```python 8 | def gap(num): 9 | # binary 숫자가 담긴 binary_list 만들기 10 | binary_list = [] 11 | while True: 12 | binary_list.append(num % 2) 13 | num /= 2 14 | if num < 2: 15 | if num == 1: 16 | binary_list.append(num) 17 | break 18 | binary_list.reverse() 19 | 20 | # 1이 위치한 인덱스 구해서 리스트에 넣기 21 | indices = [] 22 | cnt = 0 23 | for i in binary_list: 24 | if i == 1: 25 | indices.append(cnt) 26 | cnt += 1 27 | 28 | # 인덱스 간의 차를 리스트에 넣기 29 | difference = [] 30 | for i in range(len(indices)-1): 31 | difference.append(indices[i+1] - indices[i]) 32 | 33 | # 차이값이 1보다 큰 것만 남기기. 원소가 있으면 최대값-1 리턴, 없으면 0 리턴 34 | result = filter(lambda x: x > 1, difference) 35 | if result: 36 | return max(result) - 1 37 | else: 38 | return 0 39 | ``` 40 | 41 | ## 2. 다른 해답 42 | 43 | ### A. bin, strip, split 44 | 특히 split을 통해 gap을 구하는 것을 보고 정말 기발하다 생각했다. 45 | 46 | - 첫 줄: bin 함수로 2진수를 나타내는 문자열을 만든다. 앞에 붙는 '0b' 제거하고, 양 끝의 0들은 있어봤자 gap과 의미가 없으니 strip으로 없앤다. 47 | - 둘 째: "1"을 기준으로 split하면 "100101"일 경우 ["", "00", "0", ""] 이렇게 리턴된다. 즉 여기서 가장 길이가 긴 원소의 길이를 리턴하면 된다. map 함수를 통해 len 함수를 원소마다 적용해서 리스트로 만들고, 거기서 max 함수로 최대 길이를 리턴한다. 48 | 49 | ```python 50 | def gap(num): 51 | s = bin(num)[2:].strip("0") 52 | return max(map(len, s.split("1"))) 53 | ``` 54 | 55 | ### B. 정규표현식 활용 56 | 정규표현식을 빨리 숙달해야겠다. 무궁무진한 활용도다. 감탄. 57 | 58 | - 1과 1 사이에 0이 0개 이상 들어가는 패턴을 만들었다. 59 | - 리스트 내포 for문을 활용했다. 60 | - iterable: findall(REGEX, bin(num)) + [''] => 마지막에 None 문자열이 들어있는 리스트를 추가해주는 이유는 정규표현식과 매칭되는 패턴이 없을 때 빈 리스트가 리턴되기 때문이다. for문 자체가 돌질 않는다. 0을 리턴하기 위함이다. 61 | - iterable의 원소 하나하나를 a로 받고 len(a) 값을 리스트에 저장했다. 그리고 원소 중 최대값을 리턴 62 | 63 | ```python 64 | from re import compile, findall 65 | REGEX = compile(r'(?=1(0+)1)') 66 | def gap(num): 67 | return max(len(a) for a in findall(REGEX, bin(num)) + ['']) 68 | ``` 69 | --------------------------------------------------------------------------------