변경이력

돌아가기
3 688개 문자 추가 150개 문자 삭제

2016/11/12 11:10

권용훈

**Ruby** eval 사용(풀이1), 스택 구현(풀이2). 두가지로 풀이. (수정 : 풀이 2 추가) 풀이 1. s-expression을 람다함수 약기 형태로 변환. (수정: "(+)" 처리 추가) ```{.ruby한 뒤 eval. ```{.ruby} calc = proc {|op,*args| args.reduce(op) || 0 } lisp_eval = ->s_exp do calc = proc {|op,*args| args.reduce(args.shift||0, op) } eval s_exp{ eval exp.gsub(/[(\s)]/, '('=>"calc[:", ' '=>',', ')'=>']') } ``` 풀이 2. 토큰을 차례차례 스택에 push. 토큰이 ")"면 스택에서 직전의 연산자까지 꺼내서 계산. 이를 반복. ```{.ruby} calc = proc {|op,*args| args.reduce(op) || 0 } eval_top = ->s { t=[]; t.unshift(s.pop) until t[0].is_a? Symbol; s << calc[*t] } lisp_eval = ->str do tokens = str.gsub(/[(\s)]/, '('=>"calc[:", ' '=>',', ')'=>']')"("=>"",")"=>" )").split. map {|e| e == ")" ? e : e =~ /[[:digit:]]/ ? e.to_i : e.to_sym } tokens.reduce([]) {|stack,e| e == ")" ? eval_top[stack] : stack << e }.pop end ``` **Test** ```{.ruby} # tests : aritiy 1, 3, 4, nested s-exp, complex s-exp cases = ["(+)"] + ["(- 10 3)", "(* 2 3)"] + ["(- 10 3 5)", "(* 2 3 4)"] + ["(* (+ 2 3) (- 5 3))", "(/ (+ 9 1) (+ 2 3))"] + ["(* 1 (- 2 3) 4 (+ 2 -1) 3)" ] expect( cases.map(&lisp_eval) ).to eq [0, 7, 6, 2, 24, 10, 2, -12] ``` **Output** ```{.ruby} lisp_eval["(+ 2 3 5 (* 2 5) (* -2 5))"] #=> 10 ```
**Ruby** eval 사용(풀이1), 스택 구현(풀이2). 두가지로 풀이. (수정 : 풀이 2 추가) 풀이 1. s-expression을 람다함수 약기 형태로 변환. (수정: "(+)" 처리 추가) ```{.ruby한 뒤 eval. ```{.ruby} calc = proc {|op,*args| args.reduce(op) || 0 } lisp_eval = ->s_exp do calc = proc {|op,*args| args.reduce(args.shift||0, op) } eval s_exp{ eval exp.gsub(/[(\s)]/, '('=>"calc[:", ' '=>',', ')'=>']') } ``` 풀이 2. 토큰을 차례차례 스택에 push. 토큰이 ")"면 스택에서 직전의 연산자까지 꺼내서 계산. 이를 반복. ```{.ruby} calc = proc {|op,*args| args.reduce(op) || 0 } eval_top = ->s { t=[]; t.unshift(s.pop) until t[0].is_a? Symbol; s << calc[*t] } lisp_eval = ->str do tokens = str.gsub(/[(\s)]/, '('=>"calc[:", ' '=>',', ')'=>']')"("=>"",")"=>" )").split. map {|e| e == ")" ? e : e =~ /[[:digit:]]/ ? e.to_i : e.to_sym } tokens.reduce([]) {|stack,e| e == ")" ? eval_top[stack] : stack << e }.pop end ``` **Test** ```{.ruby} # tests : aritiy 1, 3, 4, nested s-exp, complex s-exp cases = ["(+)"] + ["(- 10 3)", "(* 2 3)"] + ["(- 10 3 5)", "(* 2 3 4)"] + ["(* (+ 2 3) (- 5 3))", "(/ (+ 9 1) (+ 2 3))"] + ["(* 1 (- 2 3) 4 (+ 2 -1) 3)" ] expect( cases.map(&lisp_eval) ).to eq [0, 7, 6, 2, 24, 10, 2, -12] ``` **Output** ```{.ruby} lisp_eval["(+ 2 3 5 (* 2 5) (* -2 5))"] #=> 10 ```
2 52개 문자 추가 46개 문자 삭제

2016/11/10 05:26

권용훈

1 Original

2016/11/09 01:47

권용훈

코딩도장

코딩도장은 프로그래밍 문제풀이를 통해서 코딩 실력을 수련(Practice)하는 곳입니다.