Clojure https://yyhh.org/notebook/clojure en 函数式编程的两种路线 https://yyhh.org/blog/2018/08/%E5%87%BD%E6%95%B0%E5%BC%8F%E7%BC%96%E7%A8%8B%E7%9A%84%E4%B8%A4%E7%A7%8D%E8%B7%AF%E7%BA%BF <span>函数式编程的两种路线</span> <span><a title="View user profile." href="/user/huahai" lang="" about="/user/huahai" typeof="schema:Person" property="schema:name" datatype="">Huahai</a></span> <span>Sun, 08/26/2018 - 07:30</span> <div class="field field--name-field-notebook field--type-entity-reference field--label-hidden field__items"> <div class="field__item"><div about="/notebook/clojure" id="taxonomy-term-35" class="taxonomy-term vocabulary-notebook"> <a href="/notebook/clojure"> <div class="field field--name-name field--type-string field--label-hidden field__item">Clojure</div> </a> <div class="content"> </div> </div> </div> </div> <div class="field field--name-field-opinion field--type-entity-reference field--label-hidden field__items"> <div class="field__item"><div about="/opinion/technology" id="taxonomy-term-22" class="taxonomy-term vocabulary-opinion"> <a href="/opinion/technology"> <div class="field field--name-name field--type-string field--label-hidden field__item">Technology</div> </a> <div class="content"> </div> </div> </div> </div> <div class="field field--name-body field--type-text-with-summary field--label-hidden field__item"><div class="tex2jax_process"><p>可能很多人没有意识到,函数式编程(FP)有两种非常不同的路线。</p> <p>一条路线,为类型疯狂。这条路线的语言以Haskell为代表。这种FP,一切以类型为<br /> 中心,编程的主要任务,是要把类型搞对了,让编译器高兴,号称是“如果程序编译通<br /> 过了,程序就是对的”。这条线来自学术界,有很长的历史,是FP的主流路线,有很多<br /> 其他FP语言以此为模版。科班出身的同学们说到FP,说的就是这条路线的FP。可能他们<br /> 上学的时候学过Haskell,甚至可能还给Haskell课当过助教,但是他们恨死了Haskell<br /> 。所以这些同学们,是打死不信FP能实用的。</p> <p>科班出身的同学们不知道的是,FP还有另一条路线,与Haskell完全不同,它为数据疯<br /> 狂。这条路线的语言目前只有一个样本,就是Clojure。这条路线是野路子,来自一个<br /> 没有CS背景的学音乐的程序员,名字叫Rich Hickey。他发明Clojure是让自己还可以继<br /> 续编程下去。他当时主要用C++编程接活,还在NYU教过C++。但2007年的时候他觉得自<br /> 己身心俱疲,被并行编程快搞疯了,觉得非FP不可。他还用过Common Lisp,觉得Lisp<br /> 很好,所以就想搞个FP的Lisp。于是他用了2年时间写了Clojure,发在Common Lisp的<br /> 邮件组里面。目前Clojure是Redmonk排名21的编程语言。</p> <p>刚开始的时候,Clojure主要被当成一个并发语言来宣传的,主要宣传它的software&nbsp;<br /> transactional memory的机制,比如atom, ref, agent这些有控制的mutation。</p> <p>在十年以后的今天,几乎没有人提这些了。人们在使用中发现,其实大部分的代码,不<br /> 需要mutation。Clojure的真正优势,在于它面向数据的编程模式。</p> <p>面向数据的编程(DOP)有哪些特征?我个人总结一下,有这几点:</p> <p>1. 数据是第一位的。</p> <p>Lisp说“代码也是数据”。Clojure是一种Lisp,当然代码也是数据,这似乎不算有啥<br /> 新意。但当Lisp说代码是数据的时候,主要是说Lisp可以用宏来操作代码,而Clojure<br /> 并不鼓励用宏。那啥意思呢?原来在Clojure里面,有这样一个说头,“能用数据干的<br /> 事,不要用函数干,能用函数干的事,不要用宏干”。连函数都不是第一位的!</p> <p>为什么?因为按照其能被组合的能力排序:数据》函数》宏。宏的可组合性最差,有的<br /> 宏完全不能被组合。函数的组合方式也很有限,就两种,一个是函数组合(f (h (g x)<br /> )),另外就是函数本身可以被传来传去。而数据的可组合方式是无限的。所以在<br /> Clojure里面,数据是第一位的。</p> <p>2. 数据是显式的。</p> <p>既然数据是第一位的,那么它在程序中是裸露的,不用封装隐藏起来,也不需要转换,<br /> 数据能在代码里面看见,所见即所得,数据在代码中有字面的表示。</p> <p>3. 数据是普通的。</p> <p>不需要类型,不需要特别的结构,不需要DSL, 只需要用几种普通的不变数据结构就足<br /> 够了。Clojure程序一般就用映射{},列表(),矢量[],集合#{}这四种不变数据结构来<br /> 代表一切。</p> <p>为啥这四种就够了,因为他们分别表示了所有计算需要表示的抽象概念:映射当然很重<br /> 要,根据范畴论的数学基础理论,有了映射就有了一切数学;列表表示了计算机特有的<br /> 执行的概念,列表的第一个元素是特殊的,表示执行何种功能,这就是Lisp的强大之处<br /> ;矢量是Clojure特有的,与列表区分开,是突出不具备执行功能的纯数据,只用来表<br /> 示顺序的概念;集合也被分出来,用来表示纯数据中没有顺序概念的东西,这也是数学<br /> 的传统基础。</p> <p>不需要类型,这是Clojure与Haskell最大的分歧。类型能保证的东西很有限,比如不能<br /> 保证程序的语义是正确的,而它带来了过多的对程序员限制,算是得不偿失。</p> <p>没有类型,那如何保证程序是对的?完全靠测试么?Clojure的回答是,靠spec。 spec<br /> 是对程序行为的一种描述,用来描述数据应该是什么样子的,比如一个map应该含有什<br /> 么key,等等,还可以用来描述函数的输入输出应该是什么样的,比如输入应该是奇数<br /> ,输出是符合某个等式的,等等。这比目前所有类型系统都要更强,因为这个描述语言<br /> 可以用一般的Clojure代码,所以是图灵完备的。有了spec,可以在编译时报错,可以<br /> 自动产生成千上万个测试,可以在运行时检测输入输出,等等。spec是可选的,而不是<br /> 编译器强加的一个负担。</p> <p>我觉得未来属于面向数据的编程,你也试试看?</p> </div></div> <section> <h2>Add new comment</h2> <drupal-render-placeholder callback="comment.lazy_builders:renderForm" arguments="0=node&amp;1=188&amp;2=comment_node_blog&amp;3=comment_node_blog" token="2VdRs548VE63vl2RtPhAAFN3Q09xqNm47lWqIgWKiHY"></drupal-render-placeholder> </section> <strong class="node_view"></strong> Sun, 26 Aug 2018 06:30:35 +0000 Huahai 188 at https://yyhh.org Data-Oriented Programming (DOP) https://yyhh.org/blog/2016/12/data-oriented-programming-dop <span>Data-Oriented Programming (DOP)</span> <span><a title="View user profile." href="/user/huahai" lang="" about="/user/huahai" typeof="schema:Person" property="schema:name" datatype="">Huahai</a></span> <span>Sat, 12/03/2016 - 23:33</span> <div class="field field--name-field-notebook field--type-entity-reference field--label-hidden field__items"> <div class="field__item"><div about="/notebook/clojure" id="taxonomy-term-35" class="taxonomy-term vocabulary-notebook"> <a href="/notebook/clojure"> <div class="field field--name-name field--type-string field--label-hidden field__item">Clojure</div> </a> <div class="content"> </div> </div> </div> </div> <div class="field field--name-field-opinion field--type-entity-reference field--label-hidden field__items"> <div class="field__item"><div about="/opinion/technology" id="taxonomy-term-22" class="taxonomy-term vocabulary-opinion"> <a href="/opinion/technology"> <div class="field field--name-name field--type-string field--label-hidden field__item">Technology</div> </a> <div class="content"> </div> </div> </div> </div> <div class="field field--name-body field--type-text-with-summary field--label-hidden field__item"><div class="tex2jax_process"><p>JSON is arguably the world's most popular human readable data format today.&nbsp; It has largely replaced XML as the data exchange format on the Internet. One of the key reasons for the proliferation of JSON is its simplicity.&nbsp; The data structure are very limited: only arrays, enclosed with []; and objects, enclosed with {}. That's it. It cannot be simpler.</p> <p>Apparently, this dead simple data format is enough to represent the vast landscape of data that JSON becomes the de-facto data format for Web services. Most Web APIs we use today speaks JSON. However, JSON is not native for most programming languages. It becomes a pain to convert to and back from JSON in programming languages.</p> <p>What if we develop a Data-Oriented Programming (DOP) language, that can speak something similar to JSON natively?</p> <p>Luckily, this language already exists. It is called Clojure!</p> <p>In Clojure, [] means the same thing as in JSON, {} means essentially the same thing as well: a key value map. The only thing added, which makes it a programming language instead of a purely data format, is a pair of (). What () enables is the abilities to define and call functions. With this additon, we get a fully general purpose programming language.</p> <p>As you may have suspected, using () to define and call functions is what Lisp do. So you are right, in this sense, Clojure is a Lisp. But with the ability to handle data like in JSON, it is a Data-Oriented Programming language.</p> <p>So, there you have it, Clojure is the first DOP language, a DOP Lisp.</p> </div></div> <section> <h2>Add new comment</h2> <drupal-render-placeholder callback="comment.lazy_builders:renderForm" arguments="0=node&amp;1=179&amp;2=comment_node_blog&amp;3=comment_node_blog" token="p6f-yHhiXNlpSBYvxl7UyaOgwPZoiCd6HBcxaQBOd_g"></drupal-render-placeholder> </section> <strong class="node_view"></strong> Sat, 03 Dec 2016 23:33:44 +0000 Huahai 179 at https://yyhh.org Switching to Spacemacs from Vim for Clojure/ClojureScript Development https://yyhh.org/blog/2015/08/switching-spacemacs-vim-clojure-clojurescript-development <span>Switching to Spacemacs from Vim for Clojure/ClojureScript Development</span> <span><a title="View user profile." href="/user/huahai" lang="" about="/user/huahai" typeof="schema:Person" property="schema:name" datatype="">Huahai</a></span> <span>Thu, 08/13/2015 - 07:00</span> <div class="field field--name-field-notebook field--type-entity-reference field--label-hidden field__items"> <div class="field__item"><div about="/notebook/clojure" id="taxonomy-term-35" class="taxonomy-term vocabulary-notebook"> <a href="/notebook/clojure"> <div class="field field--name-name field--type-string field--label-hidden field__item">Clojure</div> </a> <div class="content"> </div> </div> </div> <div class="field__item"><div about="/notebook/spacemacs" id="taxonomy-term-39" class="taxonomy-term vocabulary-notebook"> <a href="/notebook/spacemacs"> <div class="field field--name-name field--type-string field--label-hidden field__item">Spacemacs</div> </a> <div class="content"> </div> </div> </div> </div> <div class="field field--name-field-opinion field--type-entity-reference field--label-hidden field__items"> <div class="field__item"><div about="/opinion/technology" id="taxonomy-term-22" class="taxonomy-term vocabulary-opinion"> <a href="/opinion/technology"> <div class="field field--name-name field--type-string field--label-hidden field__item">Technology</div> </a> <div class="content"> </div> </div> </div> </div> <div class="field field--name-body field--type-text-with-summary field--label-hidden field__item"><div class="tex2jax_process"><p>Clojure has been my primary programming language for a couple of years now. During this period, I have relied on my trusty Vim text editor as the development environment. Coding Clojure in Vim had been an enjoyable experience with these excellent Vim plugins:</p> <ol><li><a href="https://github.com/guns/vim-clojure-static">vim-clojure-static</a></li> <li><a href="https://github.com/tpope/vim-fireplace">fireplace.vim</a></li> <li><a href="http://www.vim.org/scripts/script.php?script_id=3998">paredit.vim</a></li> <li><a href="https://github.com/luochen1990/rainbow">Rainbow Parentheses Improved</a></li> <li><a href="https://github.com/guns/vim-clojure-highlight">vim-clojure-highlight</a></li> <li><a href="https:://github.com/venantius/vim-cljfmt">vim-cljfmt</a></li> </ol><p>So, why am I switching? Well, Clojure is, after all, a LISP. The tooling coverage for Clojure in the LISP's natural habitat, Emacs, is simply more complete than in Vim. I did not realize the extent of the discrepancy until last week, when some guys in the Clojure meetup demonstrated impressive refactoring features of their Emacs Clojure development environment.</p> <p>To be fair, fireplace is doing an adequate job of supporting the most of dynamic features necessary for Clojure programming: code evaluation, documents lookup, tests and so on. I have been productive with it in the last couple of years. On the other hand, as my projects grow bigger and more complex, better support for debugging and refactoring seems to become desirable. These capabilities exist in Emacs.</p> <p>Of course, I am not about to give up the Vim style text editing. As a HCI researcher in my previous life, I know that theoretically, Vim style text editing is simply better than text editing with GUI and a mouse, because Fitts' Law is real and it hurts. In addition, the superiority of modal editor vi over non-modal editor emacs for text editing has been empirically established as far back as 1983<a class="see-footnote" id="footnoteref1_3c8zmld" title="Poller, M.F., Garter, S.K. A Comparative Study of Moded and Modeless Text Editing by Experienced Editor Users. In Proceedings of CHI '83, pp 166-170" href="#footnote1_3c8zmld">1</a>.</p> <p>For my case, an ideal situation would be to keep the text editing style of Vim, but use it in Emacs to get the benefit of extensive Clojure support. Not surprisingly, plenty of people have worked towards such solutions. The latest effort is in the form of <a href="https://github.com/syl20bnr/spacemacs">spacemacs</a>, a fantastic open source project that is enjoying an outpouring enthusiasm from the community, earning more than 3000 github stars in a very short time.</p> <p>I had to try it. Try as I did. And I can say that I am not disappointed.</p> <p>To be honest, the on-boarding process left a lot to be desired. First, on OSX, there's already a default installation of emacs, which would not work with spacemacs. The recommended homebrew installation of emacs is simple enough, but one needs to rename the default emacs and make the homebrew one the default. This is not mentioned in the guide.</p> <p>I found configuring the editor to be surprisingly easy, considering I knew nothing about emacs before (other than the key combination to quit from one). The majority of the Vim key bindings I tried work as desired. The ones that did not work are not hard to change. Within a couple of hours, I have managed to create a configuration that replicates most of the key bindings of paredit.vim, which I need to be productive coding Clojure. Here are my <code>dotspacemacs/config</code> to achieve these and more.</p> <div><font face="monospace"><font color="#9a7200">(</font><font color="#719899"><strong>defun</strong></font> remove-background-color <font color="#9a7200">()</font><br />   <font color="#009799">"Useful for transparent terminal."</font><br />   <font color="#9a7200">(</font><font color="#719899"><strong>unless</strong></font> <font color="#9a7200">(</font>display-graphic-p <font color="#9a7200">(</font>selected-frame<font color="#9a7200">))</font><br />     <font color="#9a7200">(</font>set-face-background <font color="#9a7200">'</font><font color="#9a7599">default</font> <font color="#009799">"unspecified-bg"</font> <font color="#9a7200">(</font>selected-frame<font color="#9a7200">))))</font><br /><font color="#9a7200">(</font><font color="#719899"><strong>defun</strong></font> dotspacemacs/config <font color="#9a7200">()</font><br />   <font color="#009799">"Configuration function.</font><br /><font color="#009799"> This function is called at the very end of Spacemacs initialization after</font><br /><font color="#009799">layers configuration."</font><br />   <font color="#719872">;; Make evil-mode up/down operate in screen lines instead of logical lines</font><br />   <font color="#9a7200">(</font>define-key evil-motion-state-map <font color="#009799">"j"</font> <font color="#9a7200">'</font><font color="#9a7599">evil-next-visual-line</font><font color="#9a7200">)</font><br />   <font color="#9a7200">(</font>define-key evil-motion-state-map <font color="#009799">"k"</font> <font color="#9a7200">'</font><font color="#9a7599">evil-previous-visual-line</font><font color="#9a7200">)</font><br />   <font color="#719872">;; Also in visual mode</font><br />   <font color="#9a7200">(</font>define-key evil-visual-state-map <font color="#009799">"j"</font> <font color="#9a7200">'</font><font color="#9a7599">evil-next-visual-line</font><font color="#9a7200">)</font><br />   <font color="#9a7200">(</font>define-key evil-visual-state-map <font color="#009799">"k"</font> <font color="#9a7200">'</font><font color="#9a7599">evil-previous-visual-line</font><font color="#9a7200">)</font><br />   <font color="#719872">;; clojure mode config</font><br />   <font color="#9a7200">(</font><font color="#719899"><strong>require</strong></font> <font color="#9a7200">'</font><font color="#9a7599">clojure-mode-extra-font-locking</font><font color="#9a7200">)</font><br />   <font color="#9a7200">(</font>add-hook <font color="#9a7200">'</font><font color="#9a7599">clojure-mode-hook</font> <font color="#9a7200"><strong>#'smartparens-strict-mode</strong></font><font color="#9a7200">)</font><br />   <font color="#9a7200">(</font>add-hook <font color="#9a7200">'</font><font color="#9a7599">clojure-mode-hook</font> <font color="#9a7200"><strong>#'evil-smartparens-mode</strong></font><font color="#9a7200">)</font><br />   <font color="#9a7200">(</font>add-hook <font color="#9a7200">'</font><font color="#9a7599">clojure-mode-hook</font> <font color="#9a7200"><strong>#'rainbow-delimiters-mode</strong></font><font color="#9a7200">)</font><br />   <font color="#719872">;; start a light theme when launched as GUI</font><br />   <font color="#9a7200">(</font><font color="#719899"><strong>when</strong></font> <font color="#9a7200">(</font>display-graphic-p<font color="#9a7200">)</font><br />       <font color="#9a7200">(</font><font color="#719899"><strong>progn</strong></font><br />         <font color="#9a7200">(</font>disable-theme <font color="#9a7200">'</font><font color="#9a7599">darkburn</font><font color="#9a7200">)</font><br />         <font color="#9a7200">(</font>load-theme <font color="#9a7200">'</font><font color="#9a7599">leuven</font> <font color="#719899"><strong>t</strong></font><font color="#9a7200">)</font><br />         <font color="#9a7200">(</font>enable-theme <font color="#9a7200">'</font><font color="#9a7599">leuven</font><font color="#9a7200">)))</font><br />   <font color="#719872">;; remove background color for both server and client</font><br />   <font color="#9a7200">(</font>add-hook <font color="#9a7200">'</font><font color="#9a7599">window-setup-hook</font> <font color="#9a7200">'</font><font color="#9a7599">remove-background-color</font><font color="#9a7200">)</font><br />   <font color="#9a7200">(</font>add-hook <font color="#9a7200">'</font><font color="#9a7599">server-visit-hook</font> <font color="#9a7200">'</font><font color="#9a7599">remove-background-color</font><font color="#9a7200">)</font><br />   <font color="#719872">;; remove trailing whitespace when saving</font><br />   <font color="#9a7200">(</font>add-hook <font color="#9a7200">'</font><font color="#9a7599">before-save-hook</font> <font color="#9a7200">'</font><font color="#9a7599">delete-trailing-whitespace</font><font color="#9a7200">)</font><br />   <font color="#719872">;; toggle comments</font><br />   <font color="#9a7200">(</font>define-key evil-normal-state-map <font color="#009799">",c "</font> <font color="#009799">" cl"</font><font color="#9a7200">)</font><br />   <font color="#719872">;; match paredit.vim key-binding</font><br />   <font color="#9a7200">(</font>define-key evil-normal-state-map <font color="#009799">",W"</font> <font color="#009799">" kw"</font><font color="#9a7200">)</font>  <font color="#719872">; wrap with ()</font><br />   <font color="#9a7200">(</font>define-key evil-normal-state-map <font color="#009799">",w["</font>        <font color="#719872">; wrap with []</font><br />     <font color="#9a7200">(</font><font color="#719899"><strong>lambda</strong></font> <font color="#9a7200">(</font><font color="#9a7200"><strong>&amp;optional</strong></font> arg<font color="#9a7200">)</font> <font color="#9a7200">(</font>interactive <font color="#009799">"P"</font><font color="#9a7200">)</font> <font color="#9a7200">(</font>sp-wrap-with-pair <font color="#009799">"["</font><font color="#9a7200">)))</font><br />   <font color="#9a7200">(</font>define-key evil-normal-state-map <font color="#009799">",w{"</font>        <font color="#719872">; wrap with {}</font><br />     <font color="#9a7200">(</font><font color="#719899"><strong>lambda</strong></font> <font color="#9a7200">(</font><font color="#9a7200"><strong>&amp;optional</strong></font> arg<font color="#9a7200">)</font> <font color="#9a7200">(</font>interactive <font color="#009799">"P"</font><font color="#9a7200">)</font> <font color="#9a7200">(</font>sp-wrap-with-pair <font color="#009799">"{"</font><font color="#9a7200">)))</font><br />   <font color="#9a7200">(</font>define-key evil-normal-state-map <font color="#009799">",S"</font> <font color="#009799">" kW"</font><font color="#9a7200">)</font>  <font color="#719872">; splice, i.e unwrap an sexp</font><br />   <font color="#9a7200">(</font>define-key evil-normal-state-map <font color="#009799">",J"</font> <font color="#009799">" kJ"</font><font color="#9a7200">)</font>  <font color="#719872">; join two sexps</font><br />   <font color="#9a7200">(</font>define-key evil-normal-state-map <font color="#009799">",O"</font> <font color="#9a7200">'</font><font color="#9a7599">sp-split-sexp</font><font color="#9a7200">)</font> <font color="#719872">; split an sexp</font><br />   <font color="#9a7200">(</font>define-key evil-normal-state-map <font color="#009799">",I"</font> <font color="#009799">" kr"</font><font color="#9a7200">)</font>  <font color="#719872">; raise current symbol</font><br />   <font color="#9a7200">(</font>define-key evil-normal-state-map <font color="#9a7200">(</font>kbd <font color="#009799">", &lt;up&gt;"</font><font color="#9a7200">)</font> <font color="#009799">" kE"</font><font color="#9a7200">)</font> <font color="#719872">; splice kill backward</font><br />   <font color="#9a7200">(</font>define-key evil-normal-state-map <font color="#9a7200">(</font>kbd <font color="#009799">", &lt;down&gt;"</font><font color="#9a7200">)</font> <font color="#009799">" ke"</font><font color="#9a7200">)</font> <font color="#719872">; forward</font><br />   <font color="#719872">;; These are different from vim, here cursor should NOT be on delimits</font><br />   <font color="#9a7200">(</font>define-key evil-normal-state-map <font color="#009799">",&gt;"</font> <font color="#009799">" ks"</font><font color="#9a7200">)</font>  <font color="#719872">; forward slurp</font><br />   <font color="#9a7200">(</font>define-key evil-normal-state-map <font color="#009799">",&lt;"</font> <font color="#009799">" kS"</font><font color="#9a7200">)</font>  <font color="#719872">; backward slurp</font><br /><font color="#9a7200">)</font></font></div> <div> </div> <p>As can be seen, all these functionality of Vim have already been coded up by someone and included in spacemacs as functions, all I did was changing their key-bindings. That was easy <img alt="smiley" height="23" src="/libraries/smiley/images/regular_smile.png" width="23" />. I am looking forward to the journey ahead with spacemacs.</p> <ul class="footnotes"><li class="footnote" id="footnote1_3c8zmld"><a class="footnote-label" href="#footnoteref1_3c8zmld">1.</a> Poller, M.F., Garter, S.K. A Comparative Study of Moded and Modeless Text Editing by Experienced Editor Users. In Proceedings of CHI '83, pp 166-170</li> </ul></div></div> <section> <h2>Add new comment</h2> <drupal-render-placeholder callback="comment.lazy_builders:renderForm" arguments="0=node&amp;1=178&amp;2=comment_node_blog&amp;3=comment_node_blog" token="UHxrIgav-Wt4wvomEc5xli2jD6WomvXCG-Os8YZvGLs"></drupal-render-placeholder> </section> <strong class="node_view"></strong> Thu, 13 Aug 2015 06:00:47 +0000 Huahai 178 at https://yyhh.org Count Number of Maps: First Exercises of Conceptual Mathematics in Clojure https://yyhh.org/blog/2012/05/count-number-maps-first-exercises-conceptual-mathematics-clojure <span>Count Number of Maps: First Exercises of Conceptual Mathematics in Clojure </span> <span><a title="View user profile." href="/user/huahai" lang="" about="/user/huahai" typeof="schema:Person" property="schema:name" datatype="">Huahai</a></span> <span>Wed, 05/16/2012 - 21:33</span> <div class="field field--name-field-notebook field--type-entity-reference field--label-hidden field__items"> <div class="field__item"><div about="/notebook/math" id="taxonomy-term-25" class="taxonomy-term vocabulary-notebook"> <a href="/notebook/math"> <div class="field field--name-name field--type-string field--label-hidden field__item">Math</div> </a> <div class="content"> </div> </div> </div> <div class="field__item"><div about="/notebook/clojure" id="taxonomy-term-35" class="taxonomy-term vocabulary-notebook"> <a href="/notebook/clojure"> <div class="field field--name-name field--type-string field--label-hidden field__item">Clojure</div> </a> <div class="content"> </div> </div> </div> <div class="field__item"><div about="/notebook/categorytheory" id="taxonomy-term-38" class="taxonomy-term vocabulary-notebook"> <a href="/notebook/categorytheory"> <div class="field field--name-name field--type-string field--label-hidden field__item">CategoryTheory</div> </a> <div class="content"> </div> </div> </div> </div> <div class="field field--name-body field--type-text-with-summary field--label-hidden field__item"><div class="tex2jax_process"><p>As <a href="http://yyhh.org/blog/2012/04/start-learning-category-theory">previously mentioned</a>, I am learning category theory, beginning with <a href="http://en.wikipedia.org/wiki/William_Lawvere">Lawvere</a>'s <a href="http://www.amazon.com/Conceptual-Mathematics-First-Introduction-Categories/dp/052171916X">Conceptual Mathematics</a> book. This is a very elementry book that assumes almost nothing as a background. However, it is still a math book, which requires doing some exercises. Since the book provides no answer to exercises, I decide to make my own and post them here as I did them. Hopefully someone will find them useful. </p> <p>Since a large part of category theory is constructive, I will try to implement the concepts computationally in order to understand them better. Cateogry theory has been implemented as types in some strong typed languages such as <a href="http://www.cs.man.ac.uk/~david/categories/">ML</a> and Haskell. I think it would be fun to see how it would look in a dynamic typed language such as Clojure. Even if I could not go very far, at minimum, I will have a mechanical means to check my solutions to the exercises. </p> <p>The first article of the book deals with the category of sets, and the main topic is about maps between sets. The second article talks about isomorphisms and related concepts. Some exercises (on page 20 and 47) are of the "how many maps are there" variety. Here are some Clojure code I used to calculate the results.</p> <div class="codeblock"> <font face="monospace"><br /><span><font color="#912f11">(</font></span><span><font color="#800090">ns</font></span> CM.core<br />   <font color="#cd3700">(</font><span><font color="#1f3f81"><b>:use</b></font></span> clojure.math.combinatorics<font color="#cd3700">)</font><span><font color="#912f11">)</font></span> <p><span><font color="#912f11">(</font></span><span><font color="#800090">defn</font></span> all-maps<br />   <span><font color="#077807">"Return a lazy sequence of all the possible maps from a domain to </font></span><br /><span><font color="#077807">  a codomain"</font></span><br />   <span><font color="#912f11">[</font></span>domain codomain<span><font color="#912f11">]</font></span><br />   <font color="#cd3700">(</font><span><font color="#1f3f81"><b>map</b></font></span> <span><font color="#912f11">#(</font></span><span><font color="#007080">conj</font></span> <span><font color="#912f11">{</font></span><span><font color="#1f3f81"><b>:domain</b></font></span> domain <span><font color="#1f3f81"><b>:codomain</b></font></span> codomain<span><font color="#912f11">}</font></span> <span><font color="#912f11">[</font></span><span><font color="#1f3f81"><b>:rule</b></font></span> <span><font color="#912f11">(</font></span><span><font color="#007080">zipmap</font></span> %<span><font color="#077807">1</font></span> %<span><font color="#077807">2</font></span><span><font color="#912f11">)])</font></span><br />        <font color="#ee9a00">(</font><span><font color="#007080">repeat</font></span> domain<font color="#ee9a00">)</font><br />        <font color="#ee9a00">(</font><span><font color="#007080">apply</font></span> <span><font color="#007080">cartesian-product</font></span> <font color="#cdcd00">(</font><span><font color="#007080">repeat</font></span> <font color="#698b22">(</font><span><font color="#007080">count</font></span> domain<font color="#698b22">)</font> codomain<font color="#cdcd00">)</font><font color="#ee9a00">)</font><font color="#cd3700">)</font><span><font color="#912f11">)</font></span></p> <p><span><font color="#912f11">(</font></span><span><font color="#800090">defn</font></span> same-mapping-rule?<br />   <span><font color="#077807">"Return true if two mapping rules give the same results for a domain"</font></span><br />   <span><font color="#912f11">[</font></span>domain r1 r2<span><font color="#912f11">]</font></span><br />   <font color="#cd3700">(</font><span><font color="#007080">every?</font></span> <span><font color="#007080">identity</font></span> <font color="#ee9a00">(</font><span><font color="#1f3f81"><b>map</b></font></span> <span><font color="#007080">=</font></span> <font color="#cdcd00">(</font><span><font color="#1f3f81"><b>map</b></font></span> r1 domain<font color="#cdcd00">)</font> <font color="#cdcd00">(</font><span><font color="#1f3f81"><b>map</b></font></span> r2 domain<font color="#cdcd00">)</font><font color="#ee9a00">)</font><font color="#cd3700">)</font><span><font color="#912f11">)</font></span></p> <p><span><font color="#912f11">(</font></span><span><font color="#800090">defn</font></span> same-map?<br />   <span><font color="#077807">"Return true if two maps are the same"</font></span><br />   <span><font color="#912f11">[</font></span>f g<span><font color="#912f11">]</font></span><br />   <font color="#cd3700">(</font><span><font color="#800090">and</font></span> <font color="#ee9a00">(</font><span><font color="#007080">=</font></span> <font color="#cdcd00">(</font><span><font color="#1f3f81"><b>:domain</b></font></span> f<font color="#cdcd00">)</font> <font color="#cdcd00">(</font><span><font color="#1f3f81"><b>:domain</b></font></span> g<font color="#cdcd00">)</font><font color="#ee9a00">)</font><br />        <font color="#ee9a00">(</font><span><font color="#007080">=</font></span> <font color="#cdcd00">(</font><span><font color="#1f3f81"><b>:codomain</b></font></span> f<font color="#cdcd00">)</font> <font color="#cdcd00">(</font><span><font color="#1f3f81"><b>:codomain</b></font></span> g<font color="#cdcd00">)</font><font color="#ee9a00">)</font><br />        <font color="#ee9a00">(</font>same-mapping-rule? <font color="#cdcd00">(</font><span><font color="#1f3f81"><b>:domain</b></font></span> f<font color="#cdcd00">)</font> <font color="#cdcd00">(</font><span><font color="#1f3f81"><b>:rule</b></font></span> f<font color="#cdcd00">)</font> <font color="#cdcd00">(</font><span><font color="#1f3f81"><b>:rule</b></font></span> g<font color="#cdcd00">)</font><font color="#ee9a00">)</font><font color="#cd3700">)</font><span><font color="#912f11">)</font></span></p> <p><span><font color="#912f11">(</font></span><span><font color="#800090">defn</font></span> compose-map<br />   <span><font color="#077807">"Return a composed map, also ensure domains and codomains match"</font></span><br />   <span><font color="#912f11">[</font></span>f g<span><font color="#912f11">]</font></span><br />   <font color="#cd3700">(</font><span><font color="#912f11">if</font></span> <font color="#ee9a00">(</font><span><font color="#007080">=</font></span> <font color="#cdcd00">(</font><span><font color="#1f3f81"><b>:codomain</b></font></span> g<font color="#cdcd00">)</font> <font color="#cdcd00">(</font><span><font color="#1f3f81"><b>:domain</b></font></span> f<font color="#cdcd00">)</font><font color="#ee9a00">)</font><br />     <span><font color="#912f11">{</font></span><span><font color="#1f3f81"><b>:domain</b></font></span> <span><font color="#912f11">(</font></span><span><font color="#1f3f81"><b>:domain</b></font></span> g<span><font color="#912f11">)</font></span>, <span><font color="#1f3f81"><b>:codomain</b></font></span> <span><font color="#912f11">(</font></span><span><font color="#1f3f81"><b>:codomain</b></font></span> f<span><font color="#912f11">)</font></span>, <br />      <span><font color="#1f3f81"><b>:rule</b></font></span> <span><font color="#912f11">(</font></span><span><font color="#007080">comp</font></span> <font color="#cd3700">(</font><span><font color="#1f3f81"><b>:rule</b></font></span> f<font color="#cd3700">)</font> <font color="#cd3700">(</font><span><font color="#1f3f81"><b>:rule</b></font></span> g<font color="#cd3700">)</font><span><font color="#912f11">)}</font></span><br />     <font color="#ee9a00">(</font><span><font color="#1f3f81"><b>throw</b></font></span> <font color="#cdcd00">(</font>Exception. <span><font color="#077807">"Cannot compose, domain does not match codomain"</font></span><font color="#cdcd00">)</font><font color="#ee9a00">)</font><font color="#cd3700">)</font><span><font color="#912f11">)</font></span></p> <p><span><font color="#912f11">(</font></span><span><font color="#800090">defn</font></span> composed? <br />   <span><font color="#077807">"Return true if map f and map g compose to map c"</font></span><br />   <span><font color="#912f11">[</font></span>f g c<span><font color="#912f11">]</font></span><br />   <font color="#cd3700">(</font>same-map? c <font color="#ee9a00">(</font>compose-map f g<font color="#ee9a00">)</font><font color="#cd3700">)</font><span><font color="#912f11">)</font></span><br />   <br /><span><font color="#912f11">(</font></span><span><font color="#800090">defn</font></span> idempotent? <br />   <span><font color="#077807">"Return true if the given map return the same results as when it is </font></span><br /><span><font color="#077807">  applied twice"</font></span><br />   <span><font color="#912f11">[</font></span>f<span><font color="#912f11">]</font></span><br />   <font color="#cd3700">(</font>composed? f f f<font color="#cd3700">)</font><span><font color="#912f11">)</font></span></p> <p><span><font color="#912f11">(</font></span><span><font color="#800090">defn</font></span> solutions<br />   <span><font color="#077807">"Return a lazy sequence of maps that match the given predicates and go</font></span><br /><span><font color="#077807">  from the given domain to given codomain"</font></span><br />   <span><font color="#912f11">[</font></span>pred domain codomain<span><font color="#912f11">]</font></span><br />   <font color="#cd3700">(</font><span><font color="#1f3f81"><b>filter</b></font></span> pred <font color="#ee9a00">(</font>all-maps domain codomain<font color="#ee9a00">)</font><font color="#cd3700">)</font><span><font color="#912f11">)</font></span></p> <p><span><font color="#912f11">(</font></span><span><font color="#800090">defn</font></span> idempotent-maps<br />   <span><font color="#077807">"Return a lazy sequence of idempotent maps between a domain and itself </font></span><br /><span><font color="#077807">  as the codomain"</font></span><br />   <span><font color="#912f11">[</font></span>domain<span><font color="#912f11">]</font></span><br />   <font color="#cd3700">(</font>solutions idempotent? domain domain<font color="#cd3700">)</font><span><font color="#912f11">)</font></span></p> <p><span><font color="#912f11">(</font></span><span><font color="#800090">defn</font></span> choice<br />   <span><font color="#077807">"Return a lazy sequence of maps that are applied before the given map to</font></span><br /><span><font color="#077807">  return the same results as the given composed map, i.e. solution of </font></span><br /><span><font color="#077807">  choice problem"</font></span><br />   <span><font color="#912f11">[</font></span>f c<span><font color="#912f11">]</font></span><br />   <font color="#cd3700">(</font>solutions <span><font color="#912f11">#(</font></span>composed? f <span><font color="#912f11">%</font></span> c<span><font color="#912f11">)</font></span> <font color="#ee9a00">(</font><span><font color="#1f3f81"><b>:domain</b></font></span> c<font color="#ee9a00">)</font> <font color="#ee9a00">(</font><span><font color="#1f3f81"><b>:domain</b></font></span> f<font color="#ee9a00">)</font><font color="#cd3700">)</font><span><font color="#912f11">)</font></span></p> <p><span><font color="#912f11">(</font></span><span><font color="#800090">defn</font></span> determination<br />   <span><font color="#077807">"Return a lazy sequence of maps that are applied after the given map to</font></span><br /><span><font color="#077807">  return the same results as the given composed map, i.e. solution of </font></span><br /><span><font color="#077807">  determination problem"</font></span><br />   <span><font color="#912f11">[</font></span>g c<span><font color="#912f11">]</font></span><br />   <font color="#cd3700">(</font>solutions <span><font color="#912f11">#(</font></span>composed? <span><font color="#912f11">%</font></span> g c<span><font color="#912f11">)</font></span> <font color="#ee9a00">(</font><span><font color="#1f3f81"><b>:codomain</b></font></span> g<font color="#ee9a00">)</font> <font color="#ee9a00">(</font><span><font color="#1f3f81"><b>:codomain</b></font></span> c<font color="#ee9a00">)</font><font color="#cd3700">)</font><span><font color="#912f11">)</font></span></p> <p><span><font color="#912f11">(</font></span><span><font color="#800090">defn</font></span> section<br />   <span><font color="#077807">"Return a lazy sequence of maps that are sections of the given map"</font></span><br />   <span><font color="#912f11">[</font></span>f<span><font color="#912f11">]</font></span><br />   <font color="#cd3700">(</font>choice f <span><font color="#912f11">{</font></span><span><font color="#1f3f81"><b>:domain</b></font></span> <span><font color="#912f11">(</font></span><span><font color="#1f3f81"><b>:codomain</b></font></span> f<span><font color="#912f11">)</font></span> <span><font color="#1f3f81"><b>:codomain</b></font></span> <span><font color="#912f11">(</font></span><span><font color="#1f3f81"><b>:codomain</b></font></span> f<span><font color="#912f11">)</font></span> <span><font color="#1f3f81"><b>:rule</b></font></span> <span><font color="#007080">identity</font></span><span><font color="#912f11">}</font></span><font color="#cd3700">)</font><span><font color="#912f11">)</font></span></p> <p><span><font color="#912f11">(</font></span><span><font color="#800090">defn</font></span> retraction<br />   <span><font color="#077807">"Return a lazy sequence of maps that are retractions of the given map"</font></span><br />   <span><font color="#912f11">[</font></span>f<span><font color="#912f11">]</font></span><br />   <font color="#cd3700">(</font>determination f <span><font color="#912f11">{</font></span><span><font color="#1f3f81"><b>:domain</b></font></span> <span><font color="#912f11">(</font></span><span><font color="#1f3f81"><b>:domain</b></font></span> f<span><font color="#912f11">)</font></span> <span><font color="#1f3f81"><b>:codomain</b></font></span> <span><font color="#912f11">(</font></span><span><font color="#1f3f81"><b>:domain</b></font></span> f<span><font color="#912f11">)</font></span> <span><font color="#1f3f81"><b>:rule</b></font></span> <span><font color="#007080">identity</font></span><span><font color="#912f11">}</font></span><font color="#cd3700">)</font><span><font color="#912f11">)</font></span></p> <p><span><font color="#912f11">(</font></span><span><font color="#800090">defn</font></span> composed-solution-pairs <br />   <span><font color="#077807">"Return a lazy sequence of pairs of maps that compose to a given map, with</font></span><br /><span><font color="#077807">  the given shared domain in between"</font></span><br />   <span><font color="#912f11">[</font></span>domain c<span><font color="#912f11">]</font></span><br />   <font color="#cd3700">(</font><span><font color="#1f3f81"><b>filter</b></font></span> <br />     <span><font color="#912f11">#(</font></span>composed? <span><font color="#912f11">(</font></span><span><font color="#007080">first</font></span> %<span><font color="#912f11">)</font></span> <span><font color="#912f11">(</font></span><span><font color="#007080">last</font></span> %<span><font color="#912f11">)</font></span> c<span><font color="#912f11">)</font></span><br />     <font color="#ee9a00">(</font><span><font color="#1f3f81"><b>for</b></font></span> <span><font color="#912f11">[</font></span>g <span><font color="#912f11">(</font></span>all-maps <font color="#cd3700">(</font><span><font color="#1f3f81"><b>:domain</b></font></span> c<font color="#cd3700">)</font> domain<span><font color="#912f11">)</font></span><br />           f <span><font color="#912f11">(</font></span>all-maps domain <font color="#cd3700">(</font><span><font color="#1f3f81"><b>:codomain</b></font></span> c<font color="#cd3700">)</font><span><font color="#912f11">)]</font></span><br />       <span><font color="#912f11">[</font></span>f g<span><font color="#912f11">]</font></span><font color="#ee9a00">)</font><font color="#cd3700">)</font><span><font color="#912f11">)</font></span><br />       <br /><span><font color="#912f11">(</font></span><span><font color="#800090">defn</font></span> retraction-section-pairs<br />   <span><font color="#077807">"Return a lazy sequence of pairs of maps r and s, where r goes from domain</font></span><br /><span><font color="#077807">  X to domain A,  s goes from A to X, and r of s is the same as the identity </font></span><br /><span><font color="#077807">  map on A."</font></span><br />   <span><font color="#912f11">[</font></span>A X<span><font color="#912f11">]</font></span><br />   <font color="#cd3700">(</font>composed-solution-pairs X <span><font color="#912f11">{</font></span><span><font color="#1f3f81"><b>:domain</b></font></span> A <span><font color="#1f3f81"><b>:codomain</b></font></span> A <span><font color="#1f3f81"><b>:rule</b></font></span> <span><font color="#007080">identity</font></span><span><font color="#912f11">}</font></span><font color="#cd3700">)</font><span><font color="#912f11">)</font></span></p> <p><span><font color="#912f11">(</font></span><span><font color="#912f11">def</font></span> A <span><font color="#912f11">#{</font></span><span><font color="#077807">"John"</font></span> <span><font color="#077807">"Mary"</font></span> <span><font color="#077807">"Sam"</font></span><span><font color="#912f11">})</font></span><br /><span><font color="#912f11">(</font></span><span><font color="#912f11">def</font></span> B <span><font color="#912f11">#{</font></span><span><font color="#077807">"eggs"</font></span> <span><font color="#077807">"coffee"</font></span><span><font color="#912f11">})</font></span><br /><span><font color="#912f11">(</font></span><span><font color="#912f11">def</font></span> U <span><font color="#912f11">#{</font></span><span><font color="#1f3f81"><b>:b</b></font></span> <span><font color="#1f3f81"><b>:p</b></font></span> <span><font color="#1f3f81"><b>:q</b></font></span> <span><font color="#1f3f81"><b>:r</b></font></span> <span><font color="#1f3f81"><b>:s</b></font></span><span><font color="#912f11">})</font></span><br /><span><font color="#912f11">(</font></span><span><font color="#912f11">def</font></span> D <span><font color="#912f11">#{</font></span><span><font color="#077807">0</font></span> <span><font color="#077807">1</font></span><span><font color="#912f11">})</font></span></p> <p><span><font color="#912f11">(</font></span><span><font color="#912f11">def</font></span> one-a <span><font color="#912f11">{</font></span><span><font color="#1f3f81"><b>:domain</b></font></span> A <span><font color="#1f3f81"><b>:codomain</b></font></span> A <span><font color="#1f3f81"><b>:rule</b></font></span> <span><font color="#007080">identity</font></span><span><font color="#912f11">})</font></span><br /><span><font color="#912f11">(</font></span><span><font color="#912f11">def</font></span> one-b <span><font color="#912f11">{</font></span><span><font color="#1f3f81"><b>:domain</b></font></span> B <span><font color="#1f3f81"><b>:codomain</b></font></span> B <span><font color="#1f3f81"><b>:rule</b></font></span> <span><font color="#007080">identity</font></span><span><font color="#912f11">})</font></span><br /><span><font color="#912f11">(</font></span><span><font color="#912f11">def</font></span> one-d <span><font color="#912f11">{</font></span><span><font color="#1f3f81"><b>:domain</b></font></span> D <span><font color="#1f3f81"><b>:codomain</b></font></span> D <span><font color="#1f3f81"><b>:rule</b></font></span> <span><font color="#007080">identity</font></span><span><font color="#912f11">})</font></span></p> <p><span><font color="#912f11">(</font></span><span><font color="#912f11">def</font></span> g <span><font color="#912f11">{</font></span><span><font color="#1f3f81"><b>:domain</b></font></span> U <span><font color="#1f3f81"><b>:codomain</b></font></span> D <span><font color="#1f3f81"><b>:rule</b></font></span> <span><font color="#912f11">{</font></span><span><font color="#1f3f81"><b>:b</b></font></span> <span><font color="#077807">0</font></span> <span><font color="#1f3f81"><b>:p</b></font></span> <span><font color="#077807">0</font></span> <span><font color="#1f3f81"><b>:q</b></font></span> <span><font color="#077807">0</font></span> <span><font color="#1f3f81"><b>:r</b></font></span> <span><font color="#077807">1</font></span> <span><font color="#1f3f81"><b>:s</b></font></span> <span><font color="#077807">1</font></span><span><font color="#912f11">}})</font></span><br /><span><font color="#912f11">(</font></span><span><font color="#912f11">def</font></span> f <span><font color="#912f11">{</font></span><span><font color="#1f3f81"><b>:domain</b></font></span> D <span><font color="#1f3f81"><b>:codomain</b></font></span> U <span><font color="#1f3f81"><b>:rule</b></font></span> <span><font color="#912f11">{</font></span><span><font color="#077807">0</font></span> <span><font color="#1f3f81"><b>:b</b></font></span> <span><font color="#077807">1</font></span> <span><font color="#1f3f81"><b>:r</b></font></span><span><font color="#912f11">}})</font></span><br /><span><font color="#912f11">(</font></span><span><font color="#912f11">def</font></span> u <span><font color="#912f11">{</font></span><span><font color="#1f3f81"><b>:domain</b></font></span> D <span><font color="#1f3f81"><b>:codomain</b></font></span> U <span><font color="#1f3f81"><b>:rule</b></font></span> <span><font color="#912f11">{</font></span><span><font color="#077807">0</font></span> <span><font color="#1f3f81"><b>:b</b></font></span> <span><font color="#077807">1</font></span> <span><font color="#1f3f81"><b>:b</b></font></span><span><font color="#912f11">}})</font></span><br /></p></font> </div> <p>In this code, maps in category theory are simply implemented as Clojure's map data structure. So a map in category theory will have three keys in the implementation, a :domain, a :codomain, and a :rule. The first two are sets, and the last one is a function, which defines the actual mapping rule from domain to codomain. </p> <p><b><i>Article 1, Exercise 2. </i></b> How many different maps $f$ are there with domain $A$ and codomain $B$? </p> <p>Domain $A$ has 3 elements "John", "Mary" and "Sam", codomain $B$ has 2 elements "eggs" and "coffee". To find the answer, evaluate this in REPL:</p> <div class="codeblock"> CM.core=&gt; (count (all-maps A B))<br /> 8 </div> <p>For our domain of 3 elements and codomain of 2 elements, the number of maps is 8, or $2^3$. If we try some other domains (Exercise 3, 4, 5), we will soon discover that the answer is always $$n^m$$ where $n$ and $m$ is the size of codomain and domain, respectively. The reason is simple: each and every element of the domain can pick any one of the elment of codomain as the target. So the first element in the domain has $n$ choices of target, the second can pick $n$ choices as well, and so on, doing this $m$ times, and multipling them all up gives the answer.</p> <p><b><i>Article 1, Exercise 6. </i></b> How many different maps $A \stackrel{f}{\longrightarrow} A$ satisfy $f \circ f = f$?</p> <p>Basically, this is asking how many maps are there that composes with itself to get the same results as itself. Such maps are called idempotent maps. The code to find the answer:</p> <div class="codeblock"> CM.core=&gt; (count (idempotent-maps A))<br /> 10 </div> <p>Let's try Exercise 7, the number of idempotent maps for $B$:</p> <div class="codeblock"> CM.core=&gt; (count (idempotent-maps B))<br /> 3 </div> <p>How about a domain with 4, 5 or 6 elments?</p> <div class="codeblock"> CM.core=&gt; (count (idempotent-maps #{1 2 3 4}))<br /> 41<br /> CM.core=&gt; (count (idempotent-maps #{1 2 3 4 5}))<br /> 196<br /> CM.core=&gt; (count (idempotent-maps #{1 2 3 4 5 6}))<br /> 1057 </div> <p>Hmm, 3, 10, 41, 196, 1057, ... what is the regularity here? It is not obvious. Let's examine the details of the first two maps and look at their rules:</p> <div class="codeblock"> CM.core=&gt; (map :rule (idempotent-maps B))<br /> ({"eggs" "coffee", "coffee" "coffee"} {"eggs" "eggs", "coffee" "coffee"} {"eggs" "eggs", "coffee" "eggs"})<br /> CM.core=&gt; (map :rule (idempotent-maps A))<br /> ({"Sam" "John", "Mary" "John", "John" "John"} {"Sam" "Sam", "Mary" "John", "John" "John"} {"Sam" "John", "Mary" "Mary", "John" "John"} {"Sam" "Mary", "Mary" "Mary", "John" "John"} {"Sam" "Sam", "Mary" "Mary", "John" "John"} {"Sam" "Sam", "Mary" "Sam", "John" "John"} {"Sam" "Mary", "Mary" "Mary", "John" "Mary"} {"Sam" "Sam", "Mary" "Mary", "John" "Mary"} {"Sam" "Sam", "Mary" "Mary", "John" "Sam"} {"Sam" "Sam", "Mary" "Sam", "John" "Sam"}) </div> <p>The regularity seems to be this: either an element must map to itself, or it must map to an elment that maps to itself. For example, for domain $B$, if "eggs" maps to itself, "coffee" must either map to "coffee" or to "eggs". Cross mappings are not allowed. So "eggs" maps to "coffee" and "coffee" maps to "eggs" is illegal.</p> <p>Given this regularity, let's work out a formula for the number of idempotent maps. For a 2 element domain, there are two cases: both elements map to themselves, or both map to one element, so the total is ${2 \choose 2} + {2 \choose 1} = 3$; For a 3 element domain, there are three cases: all map to themselves, two map to themselves and the third maps to one of them, or all three map to one, total is ${3 \choose 3} + {3 \choose 2}{2^1} + {3 \choose 1} = 1+ 3\times2 + 3 = 10$; For 4 element domain, four cases: all map to themselves, three map to themselves and the fouth to one of three, two map to themselves and remaining two map to those two, or all map to one: ${4 \choose 4} + {4 \choose 3}{3^1} + {4 \choose 2}{2^2} + {4 \choose 1} = 1 + 4\times3 + 6\times4 + 4 = 41$; and so on... A general formula for the number of idempotent maps emerges, it is $$\sum\limits_{k=0}^n {n \choose k}k^{n-k}$$ Where $n$ is the size of the domain. Notice that we used the results of the previous exercise in the derivation: the number of maps is $|codomain|^{|domain|}$.</p> <p><b><i>Article 1, Exercise 8. </i></b> Can you find a pair of maps $A \stackrel{f}{\longrightarrow} B \stackrel{g}{\longrightarrow} A$ for which $g \circ f = 1_A$? </p> <p>OK, this is asking if we can find a pair of maps that compose to an identity map of domain $A$, with the map $B$ in between. Let's see:</p> <div class="codeblock"> CM.core=&gt; (count (composed-solution-pairs B one-a))<br /> 0 </div> <p>No such map pair exists, so it is not possible to go through $B$ back to $A$. What about going through $A$ itself? </p> <div class="codeblock"> CM.core=&gt; (count (composed-solution-pairs A one-a))<br /> 6 </div> <p>There are 6 such map pairs. It is the same as going through another 3 element domain: </p> <div class="codeblock"> CM.core=&gt; (count (composed-solution-pairs #{1 2 3} one-a))<br /> 6 </div> <p>So when the domains have the same number of elements, it is possible for the map compositions to go through them back and forth. Let's look at the details of these map pairs:</p> <div class="codeblock"> CM.core=&gt; (composed-solution-pairs #{1 2 3} one-a)<br /> ([{:rule {3 "Sam", 2 "Mary", 1 "John"}, :domain #{1 2 3}, :codomain #{"John" "Mary" "Sam"}} {:rule {"Sam" 3, "Mary" 2, "John" 1}, :domain #{"John" "Mary" "Sam"}, :codomain #{1 2 3}}] [{:rule {3 "Mary", 2 "Sam", 1 "John"}, :domain #{1 2 3}, :codomain #{"John" "Mary" "Sam"}} {:rule {"Sam" 2, "Mary" 3, "John" 1}, :domain #{"John" "Mary" "Sam"}, :codomain #{1 2 3}}] [{:rule {3 "Sam", 2 "John", 1 "Mary"}, :domain #{1 2 3}, :codomain #{"John" "Mary" "Sam"}} {:rule {"Sam" 3, "Mary" 1, "John" 2}, :domain #{"John" "Mary" "Sam"}, :codomain #{1 2 3}}] [{:rule {3 "Mary", 2 "John", 1 "Sam"}, :domain #{1 2 3}, :codomain #{"John" "Mary" "Sam"}} {:rule {"Sam" 1, "Mary" 3, "John" 2}, :domain #{"John" "Mary" "Sam"}, :codomain #{1 2 3}}] [{:rule {3 "John", 2 "Sam", 1 "Mary"}, :domain #{1 2 3}, :codomain #{"John" "Mary" "Sam"}} {:rule {"Sam" 2, "Mary" 1, "John" 3}, :domain #{"John" "Mary" "Sam"}, :codomain #{1 2 3}}] [{:rule {3 "John", 2 "Mary", 1 "Sam"}, :domain #{1 2 3}, :codomain #{"John" "Mary" "Sam"}} {:rule {"Sam" 1, "Mary" 2, "John" 3}, :domain #{"John" "Mary" "Sam"}, :codomain #{1 2 3}}]) </div> <p>Obviously, for each pair, the two map rules are simply the reverse of the another, i.e. flipping the arrows around. If a map has an inverse, it is unique. These maps are called isomorphic, bijective, or one-to-one and onto. </p> <p>In fact, when the map in the middle has larger size than $A$, there may also be map pairs that compose to the identity of $A$. </p> <div class="codeblock"> CM.core=&gt; (count (composed-solution-pairs #{1 2 3 4} one-a))<br /> 72 </div> <p>In such pairs, each map is called <i>retraction</i> and <i>section</i> to each other. Let's calculate the number of retractions and sections.</p> <p><b><i>Article 2, Exercise 5 (1) </i></b> Given map $g$ (see code for its definition), how many maps $f$ are there with $g \circ f = 1_{\{0, 1\}}$?</p> <p>This is asking the number of sections of the map $g$, which has a 5 element domain $U$, and a 2 element codomain $D$. Three of the elments of $U$, b, p, q, map to 0 in $D$; two elements of $U$, r and s, map to 1 in $D$. The answer can be found by:</p> <div class="codeblock"> CM.core=&gt; (count (section g))<br /> 6 </div> <p>Basically, each section $f$ must choose two elements in $U$ to map 0 and 1 to, such that $g$ can map the results back to form an identity map on {0, 1}. For element 0, $f$ can choose one of b, p or q to map to; for element 1, $f$ can choose one of r and s. Therefore, the number of possible $f$ is $2 \times 3 = 6$. </p> <p>Obviously, not all maps have sections. </p> <div class="codeblock"> CM.core=&gt; (count (section f))<br /> 0 </div> <p>To have sections, the map must have a domain size larger than or equal to the codomain size. In addition, each elment of the codomain must be mapped to. Such map property is called surjective or onto. The general formula for the number of sections for map $g$ is therefore $$\prod_{i=1}^{n}m_i$$ where $n$ is the size of the codomain of $g$, and $m_i$ is the number of elements in the domain of $g$ that map to the $i$th element of the codomain.</p> <p><b><i>Article 2, Exercise 5 (2) </i></b> Choose a particular such $f$ (see code for its definition), how many maps $g$ satisfy $g \circ f = 1_{\{0, 1\}}$?</p> <p>Given a chosen $f$, this question is asking its number of retractions. The answer is: </p> <div class="codeblock"> CM.core=&gt; (count (retraction f))<br /> 8 </div> <p>For given $f$, 0 and 1 each maps to its own element in $U$, its retraction only need to flip the arrows to point back to 0 and 1, the remaining three element in $U$ can freely choose any of 0 and 1 to map to, so the number of retractions is the same as the total number of maps from a 3 element domain to a 2 element codomain, $2^3$. The general formula is $$n^{m-n}$$ where $n$ is the size of domain of $f$, and $m$ is its codomain size. To have retraction, a map must have a domain smaller or equal to the size of its codomain. In addition, it must be a one-to-one mapping, also called injective mapping. </p> <p><i><b>Number of section-retraction pairs</b></i> On page 117 of the book, the above formula for the number of retractions and sections of a given map are given, but it also says that the formula for the number of pairs of section/retraction in term of $m$ and $n$ is rather complicated. As it turns out, it is simple to derive a formula that is not complicated at all. First, each element of the smaller domain (size $n$) must map injectively to the lager domain (size $m$), the number of possibilities is just the number of permutation of choosing $n$ out of $m$. Then the remaining $m-n$ in the larger domain can freely choose any of the $n$ to map back to. Finally, we time up the two terms to arrive at $$\frac{m!}{(m-n)!}n^{m-n}$$ where $n$ is the size of domain $A$, m is the size of the domain $X$, $n \le m$, and $A \stackrel{s}{\longrightarrow} X \stackrel{r}{\longrightarrow} A$ satisfy $r \circ s = 1_A$.</p> <p>The formula seem to be correct as verified by the code:</p> <div class="codeblock"> CM.core=&gt; (count (retraction-section-pairs #{1 2} #{:a}))<br /> 0<br /> CM.core=&gt;(count (retraction-section-pairs #{1} #{:a}))<br /> 1<br /> CM.core=&gt; (count (retraction-section-pairs #{1 2} #{:a :b}))<br /> 2<br /> CM.core=&gt; (count (retraction-section-pairs #{1 2} #{:a :b}))<br /> 2<br /> CM.core=&gt; (count (retraction-section-pairs #{1 2} #{:a :b :c}))<br /> 12<br /> CM.core=&gt; (count (retraction-section-pairs #{1 2} #{:a :b :c :d :e}))<br /> 160<br /> CM.core=&gt; (count (retraction-section-pairs #{1 2 3} #{:a :b :c}))<br /> 6<br /> CM.core=&gt; (count (retraction-section-pairs #{1 2 3} #{:a :b :c :d}))<br /> 72<br /> CM.core=&gt; (count (retraction-section-pairs #{1 2 3 4} #{:a :b :c :d}))<br /> 24<br /> CM.core=&gt; (count (retraction-section-pairs #{1 2 3 4} #{:a :b :c :d :e}))<br /> 480<br /> CM.core=&gt; (count (retraction-section-pairs #{1 2 3 4 5} #{:a :b :c :d :e}))<br /> 120<br /> CM.core=&gt; (count (retraction-section-pairs #{1 2 3 4} #{:a :b :c :d :e :f}))<br /> 5760<br /> CM.core=&gt; (count (retraction-section-pairs #{1 2 3 4 5} #{:a :b :c :d :e :f}))<br /> 3600 </div> <p>Don't try the last two function calls, as they will run a long long time.</p> </div></div> <section> <h2>Add new comment</h2> <drupal-render-placeholder callback="comment.lazy_builders:renderForm" arguments="0=node&amp;1=153&amp;2=comment_node_blog&amp;3=comment_node_blog" token="_L_AyMuM_-y6wIUtU1GJ-JKg4M37FCUSCBk_GDrq2PE"></drupal-render-placeholder> </section> <strong class="node_view"></strong> Wed, 16 May 2012 20:33:16 +0000 Huahai 153 at https://yyhh.org My solutions for problems No. 76-100 on 4clojure.com https://yyhh.org/blog/2011/06/my-solutions-problems-no-76-100-4clojure-com <span>My solutions for problems No. 76-100 on 4clojure.com</span> <span><a title="View user profile." href="/user/huahai" lang="" about="/user/huahai" typeof="schema:Person" property="schema:name" datatype="">Huahai</a></span> <span>Sun, 06/05/2011 - 06:36</span> <div class="field field--name-field-notebook field--type-entity-reference field--label-hidden field__items"> <div class="field__item"><div about="/notebook/clojure" id="taxonomy-term-35" class="taxonomy-term vocabulary-notebook"> <a href="/notebook/clojure"> <div class="field field--name-name field--type-string field--label-hidden field__item">Clojure</div> </a> <div class="content"> </div> </div> </div> </div> <div class="field field--name-body field--type-text-with-summary field--label-hidden field__item"><div class="tex2jax_process"><p>Finally done with all the 100 problems listed on 4clojure.com so far :-). When new problems appears there, I will probably do them when I have some time to kill, but I will not post my solutions here any more. If I found interesting programming exercises, I may submit to 4clojure as well. </p> <p>This has been a great learning experience. I become very familiar with the core Clojure functions, especially the great sequence library. The functional way of writing code is so much fun, I wish I have been exposed to it earlier. Now I am hooked and would like to learn more. It's a pity there ain't many functional algorithm books around. The one I found is Chris Okasaki's "Purely Functional Data Structures", but the exposition language is Standard ML. Let's hope it can be easily translated into Clojure... </p> <div class="codeblock"> <font face="monospace"><br /><span><font color="#786000">; 77: Write a function which finds all the anagrams in a vector of words. A </font></span><br /><span><font color="#786000">; word x is an anagram of word y if all the letters in x can be rearranged in </font></span><br /><span><font color="#786000">; a different order to form y. Your function should return a set of sets, where</font></span><br /><span><font color="#786000">; each sub-set is a group of words which are anagrams of each other. Each </font></span><br /><span><font color="#786000">; sub-set should have at least two words. Words without any anagrams should not</font></span><br /><span><font color="#786000">; be included in the result.</font></span><br /><span><font color="#786000">; (= (__ ["meat" "mat" "team" "mate" "eat"]) #{#{"meat" "team" "mate"}})</font></span><br /><span><font color="#786000">; (= (__ ["veer" "lake" "item" "kale" "mite" "ever"]) </font></span><br /><span><font color="#786000">;   #{#{"veer" "ever"} #{"lake" "kale"} #{"mite" "item"}})</font></span><br /><span><font color="#912f11">(</font></span><span><font color="#912f11">fn</font></span> <span><font color="#912f11">[</font></span>coll<span><font color="#912f11">]</font></span><br />   <font color="#cd3700">(</font><span><font color="#800090">-&gt;&gt;</font></span> <font color="#ee9a00">(</font><span><font color="#007080">group-by</font></span> <span><font color="#007080">frequencies</font></span> coll<font color="#ee9a00">)</font><br />     <font color="#ee9a00">(</font><span><font color="#007080">vals</font></span><font color="#ee9a00">)</font><br />     <font color="#ee9a00">(</font><span><font color="#1f3f81"><b>filter</b></font></span> <span><font color="#912f11">#(</font></span><span><font color="#007080">&gt;</font></span> <span><font color="#912f11">(</font></span><span><font color="#007080">count</font></span> %<span><font color="#912f11">)</font></span> <span><font color="#077807">1</font></span><span><font color="#912f11">)</font></span><font color="#ee9a00">)</font><br />     <font color="#ee9a00">(</font><span><font color="#1f3f81"><b>map</b></font></span> <span><font color="#007080">set</font></span> <font color="#ee9a00">)</font><br />     <span><font color="#007080">set</font></span><font color="#cd3700">)</font><span><font color="#912f11">)</font></span><br /><span><font color="#786000">; anagrams have the same distribution of characters </font></span> <p><span><font color="#786000">; 79: Write a function which calculates the sum of the minimal path through a </font></span><br /><span><font color="#786000">; triangle. The triangle is represented as a vector of vectors. The path should </font></span><br /><span><font color="#786000">; start at the top of the triangle and move to an adjacent number on the next </font></span><br /><span><font color="#786000">; row until the bottom of the triangle is reached. </font></span><br /><span><font color="#786000">; (= (__ [  [1]</font></span><br />           <span><font color="#786000">;[2 4]</font></span><br />          <span><font color="#786000">;[5 1 4]</font></span><br />         <span><font color="#786000">;[2 3 4 5]])</font></span><br />    <span><font color="#786000">;(+ 1 2 1 3)</font></span><br />    <span><font color="#786000">;7)</font></span><br /><span><font color="#912f11">(</font></span><span><font color="#912f11">fn</font></span> <span><font color="#912f11">[</font></span>triangle<span><font color="#912f11">]</font></span> <br />   <font color="#cd3700">(</font><span><font color="#007080">apply</font></span> <span><font color="#007080">min</font></span> <font color="#ee9a00">(</font><font color="#cdcd00">(</font><span><font color="#912f11">fn</font></span> path-sum <span><font color="#912f11">[</font></span>p<span><font color="#912f11">]</font></span> <br />                 <font color="#698b22">(</font><span><font color="#007080">concat</font></span> <br />                   <font color="#008b00">(</font><span><font color="#912f11">if</font></span> <font color="#96cdcd">(</font><span><font color="#007080">=</font></span> <font color="#00688b">(</font><span><font color="#007080">count</font></span> triangle<font color="#00688b">)</font> <font color="#00688b">(</font><span><font color="#007080">count</font></span> p<font color="#00688b">)</font><font color="#96cdcd">)</font> <br />                     <span><font color="#912f11">[(</font></span><span><font color="#1f3f81"><b>reduce</b></font></span> <span><font color="#007080">+</font></span> <font color="#cd3700">(</font><span><font color="#1f3f81"><b>map-indexed</b></font></span> <span><font color="#912f11">#(</font></span><span><font color="#007080">get-in</font></span> triangle <span><font color="#912f11">[</font></span>%<span><font color="#077807">1</font></span> %<span><font color="#077807">2</font></span><span><font color="#912f11">])</font></span> p<font color="#cd3700">)</font><span><font color="#912f11">)]</font></span> <br />                     <font color="#96cdcd">(</font><span><font color="#912f11">let</font></span> <span><font color="#912f11">[</font></span>x <span><font color="#912f11">(</font></span><span><font color="#007080">last</font></span> p<span><font color="#912f11">)]</font></span> <br />                       <font color="#00688b">(</font><span><font color="#007080">concat</font></span> <br />                         <font color="#483d8b">(</font>path-sum <font color="#9400d3">(</font><span><font color="#007080">conj</font></span> p x<font color="#9400d3">)</font><font color="#483d8b">)</font> <br />                         <font color="#483d8b">(</font>path-sum <font color="#9400d3">(</font><span><font color="#007080">conj</font></span> p <span><font color="#912f11">(</font></span><span><font color="#007080">inc</font></span> x<span><font color="#912f11">)</font></span><font color="#9400d3">)</font><font color="#483d8b">)</font><font color="#00688b">)</font><font color="#96cdcd">)</font><font color="#008b00">)</font><font color="#698b22">)</font><font color="#cdcd00">)</font> <br />               <span><font color="#912f11">[</font></span><span><font color="#077807">0</font></span><span><font color="#912f11">]</font></span><font color="#ee9a00">)</font><font color="#cd3700">)</font><span><font color="#912f11">)</font></span><br /><span><font color="#786000">; We enumerate all possible paths. The next step in a path can only go to the </font></span><br /><span><font color="#786000">; same or the plus one row index as the previous step, so the paths form a</font></span><br /><span><font color="#786000">; binary tree. We walk the tree recursively, building a row index vector p for</font></span><br /><span><font color="#786000">; each path.</font></span></p> <p><span><font color="#786000">; 81: Reimplement set intersection</font></span><br /><span><font color="#912f11">#(</font></span><span><font color="#007080">set</font></span> <span><font color="#912f11">(</font></span><span><font color="#1f3f81"><b>filter</b></font></span> %<span><font color="#077807">1</font></span> %<span><font color="#077807">2</font></span><span><font color="#912f11">))</font></span><br /><span><font color="#786000">; sets are functions too, so this works</font></span></p> <p><span><font color="#786000">; 82: A word chain consists of a set of words ordered so that each word differs</font></span><br /><span><font color="#786000">; by only one letter from the words directly before and after it. The one </font></span><br /><span><font color="#786000">; letter difference can be either an insertion, a deletion, or a substitution. </font></span><br /><span><font color="#786000">; Here is an example word chain:</font></span><br /><span><font color="#786000">; cat -&gt; cot -&gt; coat -&gt; oat -&gt; hat -&gt; hot -&gt; hog -&gt; dog</font></span><br /><span><font color="#786000">; Write a function which takes a sequence of words, and returns true if they </font></span><br /><span><font color="#786000">; can be arranged into one continous word chain, and false if they cannot.</font></span><br /><span><font color="#786000">; (= false (__ #{"cot" "hot" "bat" "fat"}))</font></span><br /><span><font color="#786000">; (= true (__ #{"spout" "do" "pot" "pout" "spot" "dot"}))</font></span><br /><span><font color="#912f11">(</font></span><span><font color="#912f11">fn</font></span> <span><font color="#912f11">[</font></span>word-set<span><font color="#912f11">]</font></span><br />   <font color="#cd3700">(</font><span><font color="#800090">letfn</font></span> <span><font color="#912f11">[(</font></span>edit-dist <span><font color="#912f11">[</font></span>a b<span><font color="#912f11">]</font></span> <br />             <font color="#cd3700">(</font><span><font color="#1f3f81"><b>cond</b></font></span> <br />               <font color="#ee9a00">(</font><span><font color="#007080">not</font></span> <font color="#cdcd00">(</font><span><font color="#800090">or</font></span> a b<font color="#cdcd00">)</font><font color="#ee9a00">)</font> <span><font color="#077807">0</font></span> <br />               <font color="#ee9a00">(</font><span><font color="#007080">not</font></span> b<font color="#ee9a00">)</font> <font color="#ee9a00">(</font><span><font color="#007080">count</font></span> a<font color="#ee9a00">)</font> <br />               <font color="#ee9a00">(</font><span><font color="#007080">not</font></span> a<font color="#ee9a00">)</font> <font color="#ee9a00">(</font><span><font color="#007080">count</font></span> b<font color="#ee9a00">)</font> <br />               <span><font color="#1f3f81"><b>:else</b></font></span> <font color="#ee9a00">(</font><span><font color="#912f11">let</font></span> <span><font color="#912f11">[</font></span>ra <span><font color="#912f11">(</font></span><span><font color="#007080">next</font></span> a<span><font color="#912f11">)</font></span> rb <span><font color="#912f11">(</font></span><span><font color="#007080">next</font></span> b<span><font color="#912f11">)]</font></span> <br />                       <font color="#cdcd00">(</font><span><font color="#912f11">if</font></span> <font color="#698b22">(</font><span><font color="#007080">=</font></span> <font color="#008b00">(</font><span><font color="#007080">first</font></span> a<font color="#008b00">)</font> <font color="#008b00">(</font><span><font color="#007080">first</font></span> b<font color="#008b00">)</font><font color="#698b22">)</font> <br />                         <font color="#698b22">(</font>edit-dist ra rb<font color="#698b22">)</font> <br />                         <font color="#698b22">(</font><span><font color="#007080">+</font></span> <span><font color="#077807">1</font></span> <font color="#008b00">(</font><span><font color="#007080">min</font></span> <br />                                <font color="#96cdcd">(</font>edit-dist ra rb<font color="#96cdcd">)</font> <br />                                <font color="#96cdcd">(</font>edit-dist ra b<font color="#96cdcd">)</font> <br />                                <font color="#96cdcd">(</font>edit-dist a rb<font color="#96cdcd">)</font><font color="#008b00">)</font><font color="#698b22">)</font><font color="#cdcd00">)</font><font color="#ee9a00">)</font><font color="#cd3700">)</font><span><font color="#912f11">)</font></span><br />           <span><font color="#912f11">(</font></span>find-paths <span><font color="#912f11">[</font></span>graph start seen<span><font color="#912f11">]</font></span> <br />             <font color="#cd3700">(</font><span><font color="#912f11">if</font></span> <font color="#ee9a00">(</font>seen start<font color="#ee9a00">)</font> <br />               seen<br />               <font color="#ee9a00">(</font><span><font color="#1f3f81"><b>for</b></font></span> <span><font color="#912f11">[</font></span>n <span><font color="#912f11">(</font></span>graph start<span><font color="#912f11">)]</font></span> <br />                 <font color="#cdcd00">(</font>find-paths graph n <font color="#698b22">(</font><span><font color="#007080">conj</font></span> seen start<font color="#698b22">)</font><font color="#cdcd00">)</font><font color="#ee9a00">)</font><font color="#cd3700">)</font><span><font color="#912f11">)]</font></span> <br />     <font color="#ee9a00">(</font><span><font color="#912f11">let</font></span> <span><font color="#912f11">[</font></span>graph <span><font color="#912f11">(</font></span><span><font color="#007080">into</font></span> <span><font color="#912f11">{}</font></span> <br />                       <font color="#cd3700">(</font><span><font color="#1f3f81"><b>for</b></font></span> <span><font color="#912f11">[</font></span>s word-set<span><font color="#912f11">]</font></span> <br />                         <span><font color="#912f11">[</font></span>s <span><font color="#912f11">(</font></span><span><font color="#1f3f81"><b>filter</b></font></span> <span><font color="#912f11">#(</font></span><span><font color="#007080">=</font></span> <span><font color="#077807">1</font></span> <span><font color="#912f11">(</font></span>edit-dist s %<span><font color="#912f11">))</font></span> word-set<span><font color="#912f11">)]</font></span><font color="#cd3700">)</font><span><font color="#912f11">)]</font></span><br />       <font color="#cdcd00">(</font><span><font color="#912f11">if</font></span> <font color="#698b22">(</font><span><font color="#007080">some</font></span> <font color="#008b00">(</font><span><font color="#912f11">fn</font></span> <span><font color="#912f11">[</font></span>w<span><font color="#912f11">]</font></span> <br />                   <font color="#96cdcd">(</font><span><font color="#007080">some</font></span> <span><font color="#912f11">#(</font></span><span><font color="#007080">=</font></span> word-set <span><font color="#912f11">%</font></span><span><font color="#912f11">)</font></span> <br />                         <font color="#00688b">(</font><span><font color="#007080">flatten</font></span> <font color="#483d8b">(</font>find-paths graph w <span><font color="#912f11">#{}</font></span><font color="#483d8b">)</font><font color="#00688b">)</font><font color="#96cdcd">)</font><font color="#008b00">)</font> <br />                 word-set<font color="#698b22">)</font> <br />         <span><font color="#077807">true</font></span> <span><font color="#077807">false</font></span><font color="#cdcd00">)</font><font color="#ee9a00">)</font><font color="#cd3700">)</font><span><font color="#912f11">)</font></span><br /><span><font color="#786000">; This problem consists of two sub-problems: A. Determine the edit distance </font></span><br /><span><font color="#786000">; between two strings. For brevity, we just used the standard recursive </font></span><br /><span><font color="#786000">; algorithm instead of dynamic programming. B. For the graph of strings </font></span><br /><span><font color="#786000">; connected by edges of edit distance 1, find a simple (no loop) path that </font></span><br /><span><font color="#786000">; goes through all strings once and only once. The graph is represented as</font></span><br /><span><font color="#786000">; a map of adjacent node lists. We enumerate all simple paths in the graph </font></span><br /><span><font color="#786000">; until we found one going through all nodes.</font></span></p> <p><span><font color="#786000">; 84: Write a function which generates the transitive closure of a binary </font></span><br /><span><font color="#786000">; relation. The relation will be represented as a set of 2 item vectors.</font></span><br /><span><font color="#786000">; (let [divides #{[8 4] [9 3] [4 2] [27 9]}]</font></span><br /><span><font color="#786000">;   (= (__ divides) #{[4 2] [8 4] [8 2] [9 3] [27 9] [27 3]}))</font></span><br /><span><font color="#786000">; (let [progeny</font></span><br /><span><font color="#786000">;       #{["father" "son"] ["uncle" "cousin"] ["son" "grandson"]}]</font></span><br /><span><font color="#786000">;         (= (__ progeny)</font></span><br /><span><font color="#786000">;              #{["father" "son"] ["father" "grandson"]</font></span><br /><span><font color="#786000">;                     ["uncle" "cousin"] ["son" "grandson"]}))</font></span><br /><span><font color="#912f11">(</font></span><span><font color="#912f11">fn</font></span> <span><font color="#912f11">[</font></span>relation<span><font color="#912f11">]</font></span><br />   <font color="#cd3700">(</font><span><font color="#800090">letfn</font></span> <span><font color="#912f11">[(</font></span>expand <span><font color="#912f11">[</font></span>r<span><font color="#912f11">]</font></span> <br />             <font color="#cd3700">(</font><span><font color="#912f11">let</font></span> <span><font color="#912f11">[</font></span>m <span><font color="#912f11">(</font></span><span><font color="#007080">into</font></span> <span><font color="#912f11">{}</font></span> r<span><font color="#912f11">)]</font></span> <br />               <font color="#ee9a00">(</font><span><font color="#800090">-&gt;&gt;</font></span> <font color="#cdcd00">(</font><span><font color="#007080">concat</font></span> <br />                      r<br />                      <font color="#698b22">(</font><span><font color="#1f3f81"><b>for</b></font></span> <span><font color="#912f11">[[</font></span>k v<span><font color="#912f11">]</font></span> m<span><font color="#912f11">]</font></span> <br />                        <font color="#008b00">(</font><span><font color="#1f3f81"><b>when-let</b></font></span> <span><font color="#912f11">[</font></span>nv <span><font color="#912f11">(</font></span>m v<span><font color="#912f11">)]</font></span> <span><font color="#912f11">[</font></span>k nv<span><font color="#912f11">]</font></span><font color="#008b00">)</font><font color="#698b22">)</font><font color="#cdcd00">)</font> <br />                 <font color="#cdcd00">(</font><span><font color="#1f3f81"><b>filter</b></font></span> <span><font color="#007080">identity</font></span><font color="#cdcd00">)</font> <br />                 <span><font color="#007080">set</font></span><font color="#ee9a00">)</font><font color="#cd3700">)</font><span><font color="#912f11">)</font></span><br />           <span><font color="#912f11">(</font></span>first-consecutive <span><font color="#912f11">[</font></span>pred <span><font color="#912f11">[</font></span>f <span><font color="#912f11">&amp;</font></span> rs<span><font color="#912f11">]]</font></span> <br />             <font color="#cd3700">(</font><span><font color="#1f3f81"><b>when</b></font></span> rs<br />               <font color="#ee9a00">(</font><span><font color="#912f11">if</font></span> <font color="#cdcd00">(</font>pred f <font color="#698b22">(</font><span><font color="#007080">first</font></span> rs<font color="#698b22">)</font><font color="#cdcd00">)</font><br />                 f<br />                 <font color="#cdcd00">(</font><span><font color="#1f3f81"><b>recur</b></font></span> pred rs<font color="#cdcd00">)</font><font color="#ee9a00">)</font><font color="#cd3700">)</font><span><font color="#912f11">)]</font></span><br />     <font color="#ee9a00">(</font>first-consecutive <span><font color="#007080">=</font></span> <font color="#cdcd00">(</font><span><font color="#007080">iterate</font></span> expand relation<font color="#cdcd00">)</font><font color="#ee9a00">)</font><font color="#cd3700">)</font><span><font color="#912f11">)</font></span><br /><span><font color="#786000">; we iteratively expand the set of transitive relation, until the set no </font></span><br /><span><font color="#786000">; longer changes</font></span></p> <p><span><font color="#786000">; 85: Write a function which generates the power set of a given set. The power </font></span><br /><span><font color="#786000">; set of a set x is the set of all subsets of x, including the empty set and x </font></span><br /><span><font color="#786000">; itself.</font></span><br /><span><font color="#786000">; (= (__ #{1 :a}) #{#{1 :a} #{:a} #{} #{1}})</font></span><br /><span><font color="#912f11">(</font></span><span><font color="#912f11">fn</font></span> <span><font color="#912f11">[</font></span>s<span><font color="#912f11">]</font></span><br />   <font color="#cd3700">(</font><span><font color="#1f3f81"><b>reduce</b></font></span> <br />     <font color="#ee9a00">(</font><span><font color="#912f11">fn</font></span> <span><font color="#912f11">[</font></span>init e<span><font color="#912f11">]</font></span> <br />       <font color="#cdcd00">(</font><span><font color="#007080">set</font></span> <font color="#698b22">(</font><span><font color="#007080">concat</font></span> init <font color="#008b00">(</font><span><font color="#1f3f81"><b>map</b></font></span> <span><font color="#912f11">#(</font></span><span><font color="#007080">conj</font></span> <span><font color="#912f11">%</font></span> e<span><font color="#912f11">)</font></span> init<font color="#008b00">)</font> <span><font color="#912f11">[#{</font></span>e<span><font color="#912f11">}]</font></span><font color="#698b22">)</font><font color="#cdcd00">)</font><font color="#ee9a00">)</font><br />     <span><font color="#912f11">#{#{}}</font></span> s<font color="#cd3700">)</font><span><font color="#912f11">)</font></span><br /><span><font color="#786000">; we just add one element at a time</font></span></p> <p><span><font color="#786000">; 86: Happy numbers are positive integers that follow a particular formula: take</font></span><br /><span><font color="#786000">; each individual digit, square it, and then sum the squares to get a new number</font></span><br /><span><font color="#786000">; Repeat with the new number and eventually, you might get to a number whose </font></span><br /><span><font color="#786000">; squared sum is 1. This is a happy number. An unhappy number (or sad number) is</font></span><br /><span><font color="#786000">; one that loops endlessly. Write a function that determines if a number is </font></span><br /><span><font color="#786000">; happy or not.</font></span><br /><span><font color="#786000">; (= (__ 7) true)</font></span><br /><span><font color="#786000">; (= (__ 986543210) true)</font></span><br /><span><font color="#912f11">(</font></span><span><font color="#912f11">fn</font></span> <span><font color="#912f11">[</font></span>x<span><font color="#912f11">]</font></span><br />   <font color="#cd3700">(</font><span><font color="#800090">letfn</font></span> <span><font color="#912f11">[(</font></span>digits <span><font color="#912f11">[</font></span>n<span><font color="#912f11">]</font></span><br />             <font color="#cd3700">(</font><span><font color="#1f3f81"><b>for</b></font></span> <span><font color="#912f11">[</font></span>y <span><font color="#912f11">(</font></span><span><font color="#007080">iterate</font></span> <font color="#cd3700">(</font><span><font color="#007080">partial</font></span> <span><font color="#007080">*</font></span> <span><font color="#077807">10</font></span><font color="#cd3700">)</font> <span><font color="#077807">1</font></span><span><font color="#912f11">)</font></span> <span><font color="#1f3f81"><b>:while</b></font></span> <span><font color="#912f11">(</font></span><span><font color="#007080">&lt;=</font></span> y n<span><font color="#912f11">)]</font></span><br />               <font color="#ee9a00">(</font><span><font color="#007080">rem</font></span> <font color="#cdcd00">(</font><span><font color="#007080">int</font></span> <font color="#698b22">(</font><span><font color="#007080">/</font></span> n y<font color="#698b22">)</font><font color="#cdcd00">)</font> <span><font color="#077807">10</font></span><font color="#ee9a00">)</font><font color="#cd3700">)</font><span><font color="#912f11">)</font></span><br />           <span><font color="#912f11">(</font></span>sqr-sum <span><font color="#912f11">[</font></span>ds<span><font color="#912f11">]</font></span><br />             <font color="#cd3700">(</font><span><font color="#1f3f81"><b>reduce</b></font></span> <span><font color="#007080">+</font></span> <font color="#ee9a00">(</font><span><font color="#1f3f81"><b>map</b></font></span> <span><font color="#912f11">#(</font></span><span><font color="#007080">*</font></span> <span><font color="#912f11">%</font></span> <span><font color="#912f11">%</font></span><span><font color="#912f11">)</font></span> ds<font color="#ee9a00">)</font><font color="#cd3700">)</font><span><font color="#912f11">)]</font></span><br />     <font color="#ee9a00">(</font><span><font color="#912f11">let</font></span> <span><font color="#912f11">[</font></span>r <span><font color="#912f11">(</font></span><span><font color="#007080">some</font></span> <span><font color="#912f11">#{</font></span><span><font color="#077807">1</font></span> <span><font color="#077807">4</font></span><span><font color="#912f11">}</font></span> <font color="#cd3700">(</font><span><font color="#007080">iterate</font></span> <font color="#ee9a00">(</font><span><font color="#007080">comp</font></span> sqr-sum digits<font color="#ee9a00">)</font> x<font color="#cd3700">)</font><span><font color="#912f11">)]</font></span><br />       <font color="#cdcd00">(</font><span><font color="#1f3f81"><b>cond</b></font></span><br />         <font color="#698b22">(</font><span><font color="#007080">=</font></span> <span><font color="#077807">1</font></span> r<font color="#698b22">)</font> <span><font color="#077807">true</font></span><br />         <font color="#698b22">(</font><span><font color="#007080">=</font></span> <span><font color="#077807">4</font></span> r<font color="#698b22">)</font> <span><font color="#077807">false</font></span><font color="#cdcd00">)</font><font color="#ee9a00">)</font><font color="#cd3700">)</font><span><font color="#912f11">)</font></span><br /><span><font color="#786000">; it turns out that 4 is a sad number, as it results into an infinite loop</font></span></p> <p><span><font color="#786000">; 88: Write a function which returns the symmetric difference of two sets. The</font></span><br /><span><font color="#786000">; symmetric difference is the set of items belonging to one but not both of </font></span><br /><span><font color="#786000">; the two sets.</font></span><br /><span><font color="#786000">; (= (__ #{1 2 3 4 5 6} #{1 3 5 7}) #{2 4 6 7})</font></span><br /><span><font color="#912f11">#(</font></span><span><font color="#007080">set</font></span> <span><font color="#912f11">(</font></span><span><font color="#007080">remove</font></span> <font color="#cd3700">(</font><span><font color="#007080">set</font></span> <font color="#ee9a00">(</font><span><font color="#1f3f81"><b>filter</b></font></span> %<span><font color="#077807">1</font></span> %<span><font color="#077807">2</font></span><font color="#ee9a00">)</font><font color="#cd3700">)</font> <font color="#cd3700">(</font><span><font color="#007080">into</font></span> %<span><font color="#077807">1</font></span> %<span><font color="#077807">2</font></span><font color="#cd3700">)</font><span><font color="#912f11">))</font></span><br /><span><font color="#786000">; we remove the intersection from the union</font></span></p> <p><span><font color="#786000">; 89: Starting with a graph you must write a function that returns true if it </font></span><br /><span><font color="#786000">; is possible to make a tour of the graph in which every edge is visited exactly</font></span><br /><span><font color="#786000">; once.  The graph is represented by a vector of tuples, where each tuple </font></span><br /><span><font color="#786000">; represents a single edge.  The rules are: </font></span><br /><span><font color="#786000">; - You can start at any node.  </font></span><br /><span><font color="#786000">; - You must visit each edge exactly once.  </font></span><br /><span><font color="#786000">; - All edges are undirected.</font></span><br /><span><font color="#786000">; (= true (__ [[1 2] [2 3] [3 4] [4 1]]))</font></span><br /><span><font color="#786000">; (= false (__ [[1 2] [2 3] [2 4] [2 5]]))</font></span><br /><span><font color="#786000">; (= false (__ [[:a :b] [:a :b] [:a :c] [:c :a] [:a :d] [:b :d] [:c :d]]))</font></span><br /><span><font color="#786000">; (= true (__ [[:a :b] [:a :c] [:c :b] [:a :e] [:b :e] [:a :d] [:b :d] </font></span><br /><span><font color="#786000">;              [:c :e] [:d :e] [:c :f] [:d :f]]))</font></span><br /><span><font color="#912f11">(</font></span><span><font color="#912f11">fn</font></span> <span><font color="#912f11">[</font></span>edge-list<span><font color="#912f11">]</font></span><br />   <font color="#cd3700">(</font><span><font color="#912f11">let</font></span> <span><font color="#912f11">[</font></span>graph <span><font color="#912f11">(</font></span><span><font color="#007080">apply</font></span> <span><font color="#007080">merge-with</font></span> <br />                 <span><font color="#912f11">#(</font></span><span><font color="#007080">into</font></span> <span><font color="#912f11">%1</font></span> <span><font color="#912f11">%2</font></span><span><font color="#912f11">)</font></span> <br />                 <font color="#cd3700">(</font><span><font color="#007080">apply</font></span> <span><font color="#007080">concat</font></span> <br />                   <font color="#ee9a00">(</font><span><font color="#1f3f81"><b>map-indexed</b></font></span> <br />                     <font color="#cdcd00">(</font><span><font color="#912f11">fn</font></span> <span><font color="#912f11">[</font></span>i <span><font color="#912f11">[</font></span>k v<span><font color="#912f11">]]</font></span> <br />                       <span><font color="#912f11">[{</font></span>k <span><font color="#912f11">#{{</font></span><span><font color="#1f3f81"><b>:node</b></font></span> v <span><font color="#1f3f81"><b>:index</b></font></span> i<span><font color="#912f11">}}}</font></span> <br />                        <span><font color="#912f11">{</font></span>v <span><font color="#912f11">#{{</font></span><span><font color="#1f3f81"><b>:node</b></font></span> k <span><font color="#1f3f81"><b>:index</b></font></span> i<span><font color="#912f11">}}}]</font></span><font color="#cdcd00">)</font> <br />                     edge-list<font color="#ee9a00">)</font><font color="#cd3700">)</font><span><font color="#912f11">)]</font></span><br />     <font color="#ee9a00">(</font><span><font color="#912f11">if</font></span> <font color="#cdcd00">(</font><span><font color="#007080">some</font></span><br />           <font color="#698b22">(</font><span><font color="#912f11">fn</font></span> <span><font color="#912f11">[</font></span>node<span><font color="#912f11">]</font></span> <br />             <font color="#008b00">(</font><span><font color="#007080">some</font></span> <br />               <span><font color="#007080">identity</font></span> <br />               <font color="#96cdcd">(</font><span><font color="#007080">flatten</font></span> <br />                 <font color="#00688b">(</font><font color="#483d8b">(</font><span><font color="#912f11">fn</font></span> visit <span><font color="#912f11">[</font></span>n vs<span><font color="#912f11">]</font></span> <br />                    <font color="#9400d3">(</font><span><font color="#912f11">if</font></span> <span><font color="#912f11">(</font></span><span><font color="#007080">every?</font></span> <span><font color="#912f11">#(</font></span>vs <span><font color="#912f11">(</font></span><span><font color="#1f3f81"><b>:index</b></font></span> %<span><font color="#912f11">))</font></span> <font color="#cd3700">(</font>graph n<font color="#cd3700">)</font><span><font color="#912f11">)</font></span> <br />                      <span><font color="#912f11">(</font></span><span><font color="#912f11">if</font></span> <font color="#cd3700">(</font><span><font color="#007080">every?</font></span> <span><font color="#007080">identity</font></span> vs<font color="#cd3700">)</font> <span><font color="#077807">true</font></span> <span><font color="#077807">false</font></span><span><font color="#912f11">)</font></span> <br />                      <span><font color="#912f11">(</font></span><span><font color="#1f3f81"><b>for</b></font></span> <span><font color="#912f11">[</font></span>x <span><font color="#912f11">(</font></span>graph n<span><font color="#912f11">)]</font></span> <br />                        <font color="#cd3700">(</font><span><font color="#1f3f81"><b>when-not</b></font></span> <font color="#ee9a00">(</font>vs <font color="#cdcd00">(</font><span><font color="#1f3f81"><b>:index</b></font></span> x<font color="#cdcd00">)</font><font color="#ee9a00">)</font> <br />                          <font color="#ee9a00">(</font>visit <font color="#cdcd00">(</font><span><font color="#1f3f81"><b>:node</b></font></span> x<font color="#cdcd00">)</font> <font color="#cdcd00">(</font><span><font color="#007080">assoc</font></span> vs <font color="#698b22">(</font><span><font color="#1f3f81"><b>:index</b></font></span> x<font color="#698b22">)</font> <span><font color="#077807">true</font></span><font color="#cdcd00">)</font><font color="#ee9a00">)</font><font color="#cd3700">)</font><span><font color="#912f11">)</font></span><font color="#9400d3">)</font><font color="#483d8b">)</font><br />                  node <font color="#483d8b">(</font><span><font color="#007080">vec</font></span> <font color="#9400d3">(</font><span><font color="#007080">repeat</font></span> <span><font color="#912f11">(</font></span><span><font color="#007080">count</font></span> edge-list<span><font color="#912f11">)</font></span> <span><font color="#077807">false</font></span><font color="#9400d3">)</font><font color="#483d8b">)</font><font color="#00688b">)</font><font color="#96cdcd">)</font><font color="#008b00">)</font><font color="#698b22">)</font> <br />           <font color="#698b22">(</font><span><font color="#007080">set</font></span> <font color="#008b00">(</font><span><font color="#007080">apply</font></span> <span><font color="#007080">concat</font></span> edge-list<font color="#008b00">)</font><font color="#698b22">)</font><font color="#cdcd00">)</font> <br />       <span><font color="#077807">true</font></span> <span><font color="#077807">false</font></span><font color="#ee9a00">)</font><font color="#cd3700">)</font><span><font color="#912f11">)</font></span><br /><span><font color="#786000">; This problem looks similar to problem 82 as both are graph traversals, but</font></span><br /><span><font color="#786000">; the graphs are quite different. Here redundent edges exist, so we cannot use</font></span><br /><span><font color="#786000">; a set or a map to track edge visits, we instead use a vector of booleans. </font></span><br /><span><font color="#786000">; Also, the condition is to traverse all edges instead of all nodes. We again </font></span><br /><span><font color="#786000">; use a map of adjacent node lists as the graph, but supplement each adjacent </font></span><br /><span><font color="#786000">; node with the index of the corresponding edge. Finally, here a node can be </font></span><br /><span><font color="#786000">; visited multiple times, and we terminates a path at a node only when all of </font></span><br /><span><font color="#786000">; its edges have already been visited.</font></span></p> <p><span><font color="#786000">; 91: Given a graph, determine whether the graph is connected. A connected </font></span><br /><span><font color="#786000">; graph is such that a path exists between any two given nodes.  </font></span><br /><span><font color="#786000">; -Your function must return true if the graph is connected and false otherwise.</font></span><br /><span><font color="#786000">; -You will be given a set of tuples representing the edges of a graph. Each </font></span><br /><span><font color="#786000">;  member of a tuple being a vertex/node in the graph.  </font></span><br /><span><font color="#786000">; -Each edge is undirected (can be traversed either direction). </font></span><br /><span><font color="#786000">;  (= false (__ #{[1 2] [2 3] [3 1] [4 5] [5 6] [6 4]}))</font></span><br /><span><font color="#786000">;  (= true (__ #{[1 2] [2 3] [3 1][4 5] [5 6] [6 4] [3 4]}))</font></span><br /><span><font color="#912f11">(</font></span><span><font color="#912f11">fn</font></span> <span><font color="#912f11">[</font></span>edge-list<span><font color="#912f11">]</font></span><br />   <font color="#cd3700">(</font><span><font color="#912f11">let</font></span> <span><font color="#912f11">[</font></span>graph <span><font color="#912f11">(</font></span><span><font color="#007080">apply</font></span> <span><font color="#007080">merge-with</font></span> <br />                 <span><font color="#912f11">#(</font></span><span><font color="#007080">into</font></span> <span><font color="#912f11">%1</font></span> <span><font color="#912f11">%2</font></span><span><font color="#912f11">)</font></span> <br />                 <font color="#cd3700">(</font><span><font color="#007080">apply</font></span> <span><font color="#007080">concat</font></span> <br />                   <font color="#ee9a00">(</font><span><font color="#1f3f81"><b>map</b></font></span> <font color="#cdcd00">(</font><span><font color="#912f11">fn</font></span> <span><font color="#912f11">[[</font></span>k v<span><font color="#912f11">]]</font></span> <span><font color="#912f11">[{</font></span>k <span><font color="#912f11">#{</font></span>v<span><font color="#912f11">}}</font></span> <span><font color="#912f11">{</font></span>v <span><font color="#912f11">#{</font></span>k<span><font color="#912f11">}}]</font></span><font color="#cdcd00">)</font> edeg-list<font color="#ee9a00">)</font><font color="#cd3700">)</font><span><font color="#912f11">)]</font></span> <br />     <font color="#ee9a00">(</font><span><font color="#912f11">if</font></span> <font color="#cdcd00">(</font><span><font color="#007080">some</font></span> <span><font color="#912f11">#(</font></span><span><font color="#007080">=</font></span> <span><font color="#912f11">(</font></span><span><font color="#007080">count</font></span> %<span><font color="#912f11">)</font></span> <span><font color="#912f11">(</font></span><span><font color="#007080">count</font></span> graph<span><font color="#912f11">))</font></span> <br />               <font color="#698b22">(</font><span><font color="#007080">flatten</font></span> <br />                 <font color="#008b00">(</font><font color="#96cdcd">(</font><span><font color="#912f11">fn</font></span> paths <span><font color="#912f11">[</font></span>node seen<span><font color="#912f11">]</font></span> <br />                    <font color="#00688b">(</font><span><font color="#912f11">if</font></span> <font color="#483d8b">(</font>seen node<font color="#483d8b">)</font> <br />                      seen<br />                      <font color="#483d8b">(</font><span><font color="#1f3f81"><b>for</b></font></span> <span><font color="#912f11">[</font></span>x <span><font color="#912f11">(</font></span>graph node<span><font color="#912f11">)]</font></span> <br />                        <font color="#9400d3">(</font>paths x <span><font color="#912f11">(</font></span><span><font color="#007080">conj</font></span> seen node<span><font color="#912f11">)</font></span><font color="#9400d3">)</font><font color="#483d8b">)</font><font color="#00688b">)</font><font color="#96cdcd">)</font> <br />                  <font color="#96cdcd">(</font><span><font color="#007080">ffirst</font></span> graph<font color="#96cdcd">)</font> <span><font color="#912f11">#{}</font></span><font color="#008b00">)</font><font color="#698b22">)</font><font color="#cdcd00">)</font> <br />       <span><font color="#077807">true</font></span> <span><font color="#077807">false</font></span><font color="#ee9a00">)</font><font color="#cd3700">)</font><span><font color="#912f11">)</font></span><br /><span><font color="#786000">;  This graph traversal problem is simpler than both 82 and 89. We only  need </font></span><br /><span><font color="#786000">;  to start searching from any one of the nodes instead of all nodes. But the </font></span><br /><span><font color="#786000">;  pattern of the code is similar.</font></span></p> <p><span><font color="#786000">; 92: Write a function to parse a Roman-numeral string and return the number it</font></span><br /><span><font color="#786000">; represents. You can assume that the input will be well-formed, in upper-case,</font></span><br /><span><font color="#786000">; and follow the subtractive principle. You don't need to handle any numbers </font></span><br /><span><font color="#786000">; greater than MMMCMXCIX (3999), the largest number representable with </font></span><br /><span><font color="#786000">; ordinary letters.</font></span><br /><span><font color="#786000">; (= 827 (__ "DCCCXXVII"))</font></span><br /><span><font color="#786000">; (= 48 (__ "XLVIII"))</font></span><br /><span><font color="#912f11">(</font></span><span><font color="#912f11">fn</font></span> <span><font color="#912f11">[</font></span>s<span><font color="#912f11">]</font></span><br />   <font color="#cd3700">(</font><span><font color="#912f11">let</font></span> <span><font color="#912f11">[</font></span>snum <span><font color="#912f11">{[</font></span><span><font color="#077807">\C</font></span> <span><font color="#077807">\M</font></span><span><font color="#912f11">]</font></span> <span><font color="#077807">900</font></span>  <span><font color="#912f11">[</font></span><span><font color="#077807">\C</font></span> <span><font color="#077807">\D</font></span><span><font color="#912f11">]</font></span> <span><font color="#077807">400</font></span> <span><font color="#912f11">[</font></span><span><font color="#077807">\X</font></span> <span><font color="#077807">\C</font></span><span><font color="#912f11">]</font></span> <span><font color="#077807">90</font></span> <br />              <span><font color="#912f11">[</font></span><span><font color="#077807">\X</font></span> <span><font color="#077807">\L</font></span><span><font color="#912f11">]</font></span> <span><font color="#077807">40</font></span> <span><font color="#912f11">[</font></span><span><font color="#077807">\I</font></span> <span><font color="#077807">\X</font></span><span><font color="#912f11">]</font></span> <span><font color="#077807">9</font></span> <span><font color="#912f11">[</font></span><span><font color="#077807">\I</font></span> <span><font color="#077807">\V</font></span><span><font color="#912f11">]</font></span> <span><font color="#077807">4</font></span><span><font color="#912f11">}</font></span><br />         nums <span><font color="#912f11">{</font></span><span><font color="#077807">\I</font></span> <span><font color="#077807">1</font></span> <span><font color="#077807">\V</font></span> <span><font color="#077807">5</font></span> <span><font color="#077807">\X</font></span> <span><font color="#077807">10</font></span> <span><font color="#077807">\L</font></span> <span><font color="#077807">50</font></span> <span><font color="#077807">\C</font></span> <span><font color="#077807">100</font></span> <span><font color="#077807">\D</font></span> <span><font color="#077807">500</font></span> <span><font color="#077807">\M</font></span> <span><font color="#077807">1000</font></span><span><font color="#912f11">}]</font></span><br />     <font color="#ee9a00">(</font><span><font color="#800090">letfn</font></span> <span><font color="#912f11">[(</font></span>sum-snum <span><font color="#912f11">[[</font></span>f <span><font color="#912f11">&amp;</font></span> r<span><font color="#912f11">]]</font></span><br />                       <font color="#cd3700">(</font><span><font color="#912f11">if</font></span> f<br />                         <font color="#ee9a00">(</font><span><font color="#007080">+</font></span> <font color="#cdcd00">(</font><span><font color="#1f3f81"><b>if-let</b></font></span> <span><font color="#912f11">[</font></span>n <span><font color="#912f11">(</font></span>snum <span><font color="#912f11">[</font></span>f <span><font color="#912f11">(</font></span><span><font color="#007080">first</font></span> r<span><font color="#912f11">)])]</font></span> <br />                              n <span><font color="#077807">0</font></span><font color="#cdcd00">)</font><br />                            <font color="#cdcd00">(</font>sum-snum r<font color="#cdcd00">)</font><font color="#ee9a00">)</font><br />                         <span><font color="#077807">0</font></span><font color="#cd3700">)</font><span><font color="#912f11">)</font></span><br />             <span><font color="#912f11">(</font></span>del-snum <span><font color="#912f11">[[</font></span>f <span><font color="#912f11">&amp;</font></span> r<span><font color="#912f11">]]</font></span><br />                          <font color="#cd3700">(</font><span><font color="#1f3f81"><b>when</b></font></span> f<br />                            <font color="#ee9a00">(</font><span><font color="#912f11">if</font></span> <font color="#cdcd00">(</font>snum <span><font color="#912f11">[</font></span>f <span><font color="#912f11">(</font></span><span><font color="#007080">first</font></span> r<span><font color="#912f11">)]</font></span><font color="#cdcd00">)</font><br />                              <font color="#cdcd00">(</font>del-snum <font color="#698b22">(</font><span><font color="#007080">rest</font></span> r<font color="#698b22">)</font><font color="#cdcd00">)</font><br />                              <font color="#cdcd00">(</font><span><font color="#007080">cons</font></span> f <font color="#698b22">(</font>del-snum r<font color="#698b22">)</font><font color="#cdcd00">)</font><font color="#ee9a00">)</font><font color="#cd3700">)</font><span><font color="#912f11">)]</font></span><br />       <font color="#cdcd00">(</font><span><font color="#1f3f81"><b>reduce</b></font></span> <span><font color="#007080">+</font></span> <font color="#698b22">(</font>sum-snum s<font color="#698b22">)</font> <font color="#698b22">(</font><span><font color="#1f3f81"><b>map</b></font></span> nums <font color="#008b00">(</font>del-snum s<font color="#008b00">)</font><font color="#698b22">)</font><font color="#cdcd00">)</font><font color="#ee9a00">)</font><font color="#cd3700">)</font><span><font color="#912f11">)</font></span><br /><span><font color="#786000">; We first find and sum the special numbers (4, 9, etc), remove them and sum</font></span><br /><span><font color="#786000">; the rest.  </font></span></p> <p><span><font color="#786000">; 93: Write a function which flattens any nested combination of sequential </font></span><br /><span><font color="#786000">; things (lists, vectors, etc.), but maintains the lowest level sequential </font></span><br /><span><font color="#786000">; items. The result should be a sequence of sequences with only one level of </font></span><br /><span><font color="#786000">; nesting.</font></span><br /><span><font color="#786000">; (= (__ '((1 2)((3 4)((((5 6))))))) '((1 2)(3 4)(5 6)))</font></span><br /><span><font color="#912f11">(</font></span><span><font color="#912f11">fn</font></span> pf <span><font color="#912f11">[</font></span>coll<span><font color="#912f11">]</font></span><br />   <font color="#cd3700">(</font><span><font color="#912f11">let</font></span> <span><font color="#912f11">[</font></span>l <span><font color="#912f11">(</font></span><span><font color="#007080">first</font></span> coll<span><font color="#912f11">)</font></span> r <span><font color="#912f11">(</font></span><span><font color="#007080">next</font></span> coll<span><font color="#912f11">)]</font></span><br />     <font color="#ee9a00">(</font><span><font color="#007080">concat</font></span> <br />       <font color="#cdcd00">(</font><span><font color="#912f11">if</font></span> <font color="#698b22">(</font><span><font color="#800090">and</font></span> <font color="#008b00">(</font><span><font color="#007080">sequential?</font></span> l<font color="#008b00">)</font> <font color="#008b00">(</font><span><font color="#007080">not</font></span> <font color="#96cdcd">(</font><span><font color="#007080">sequential?</font></span> <font color="#00688b">(</font><span><font color="#007080">first</font></span> l<font color="#00688b">)</font><font color="#96cdcd">)</font><font color="#008b00">)</font><font color="#698b22">)</font><br />         <span><font color="#912f11">[</font></span>l<span><font color="#912f11">]</font></span><br />         <font color="#698b22">(</font>pf l<font color="#698b22">)</font><font color="#cdcd00">)</font><br />       <font color="#cdcd00">(</font><span><font color="#1f3f81"><b>when</b></font></span> <font color="#698b22">(</font><span><font color="#007080">sequential?</font></span> r<font color="#698b22">)</font><br />         <font color="#698b22">(</font>pf r<font color="#698b22">)</font><font color="#cdcd00">)</font><font color="#ee9a00">)</font><font color="#cd3700">)</font><span><font color="#912f11">)</font></span><br /><span><font color="#786000">; this is just a slight modification of the solution to problem 28.</font></span></p> <p><span><font color="#786000">; 94: The game of life is a cellular automaton devised by mathematician John </font></span><br /><span><font color="#786000">; Conway.  The 'board' consists of both live (#) and dead ( ) cells. Each cell </font></span><br /><span><font color="#786000">; interacts with its eight neighbours (horizontal, vertical, diagonal), and its</font></span><br /><span><font color="#786000">; next state is dependent on the following rules: 1) Any live cell with fewer </font></span><br /><span><font color="#786000">; than two live neighbours dies, as if caused by under-population.  2) Any live</font></span><br /><span><font color="#786000">; cell with two or three live neighbours lives on to the next generation.  3) </font></span><br /><span><font color="#786000">; Any live cell with more than three live neighbours dies, as if by overcrowding</font></span><br /><span><font color="#786000">; . 4) Any dead cell with exactly three live neighbours becomes a live cell, as</font></span><br /><span><font color="#786000">; if by reproduction.  Write a function that accepts a board, and returns a </font></span><br /><span><font color="#786000">; board representing the next generation of cells.</font></span><br /><span><font color="#786000">;(= (__ ["      " </font></span><br />         <span><font color="#786000">;" ##   "</font></span><br />         <span><font color="#786000">;" ##   "</font></span><br />         <span><font color="#786000">;"   ## "</font></span><br />         <span><font color="#786000">;"   ## "</font></span><br />         <span><font color="#786000">;"      "])</font></span><br />    <span><font color="#786000">;["      " </font></span><br />     <span><font color="#786000">;" ##   "</font></span><br />     <span><font color="#786000">;" #    "</font></span><br />     <span><font color="#786000">;"    # "</font></span><br />     <span><font color="#786000">;"   ## "</font></span><br />     <span><font color="#786000">;"      "])</font></span><br /><span><font color="#912f11">(</font></span><span><font color="#912f11">fn</font></span> <span><font color="#912f11">[</font></span>board<span><font color="#912f11">]</font></span><br />   <font color="#cd3700">(</font><span><font color="#912f11">let</font></span> <span><font color="#912f11">[</font></span>offsets <span><font color="#912f11">[[</font></span><span><font color="#077807">-1</font></span> <span><font color="#077807">-1</font></span><span><font color="#912f11">]</font></span> <span><font color="#912f11">[</font></span><span><font color="#077807">-1</font></span> <span><font color="#077807">0</font></span><span><font color="#912f11">]</font></span> <span><font color="#912f11">[</font></span><span><font color="#077807">-1</font></span> <span><font color="#077807">1</font></span><span><font color="#912f11">]</font></span><br />                  <span><font color="#912f11">[</font></span><span><font color="#077807">0</font></span> <span><font color="#077807">-1</font></span><span><font color="#912f11">]</font></span> <span><font color="#912f11">[</font></span><span><font color="#077807">0</font></span> <span><font color="#077807">1</font></span><span><font color="#912f11">]</font></span><br />                  <span><font color="#912f11">[</font></span><span><font color="#077807">1</font></span> <span><font color="#077807">-1</font></span><span><font color="#912f11">]</font></span> <span><font color="#912f11">[</font></span><span><font color="#077807">1</font></span> <span><font color="#077807">0</font></span><span><font color="#912f11">]</font></span> <span><font color="#912f11">[</font></span><span><font color="#077807">1</font></span> <span><font color="#077807">1</font></span><span><font color="#912f11">]]</font></span><br />         height <span><font color="#912f11">(</font></span><span><font color="#007080">count</font></span> board<span><font color="#912f11">)</font></span><br />         width <span><font color="#912f11">(</font></span><span><font color="#007080">count</font></span> <font color="#cd3700">(</font><span><font color="#007080">first</font></span> board<font color="#cd3700">)</font><span><font color="#912f11">)</font></span><br />         get-state <span><font color="#912f11">(</font></span><span><font color="#912f11">fn</font></span> <span><font color="#912f11">[[</font></span>x y<span><font color="#912f11">]</font></span> <span><font color="#912f11">[</font></span>dx dy<span><font color="#912f11">]]</font></span><br />                     <font color="#cd3700">(</font><span><font color="#912f11">let</font></span> <span><font color="#912f11">[</font></span>c <span><font color="#912f11">(</font></span><span><font color="#007080">+</font></span> x dx<span><font color="#912f11">)</font></span> r <span><font color="#912f11">(</font></span><span><font color="#007080">+</font></span> y dy<span><font color="#912f11">)]</font></span> <br />                       <font color="#ee9a00">(</font><span><font color="#912f11">if</font></span> <font color="#cdcd00">(</font><span><font color="#800090">or</font></span> <font color="#698b22">(</font><span><font color="#007080">&lt;</font></span> c <span><font color="#077807">0</font></span><font color="#698b22">)</font> <font color="#698b22">(</font><span><font color="#007080">=</font></span> c width<font color="#698b22">)</font> <font color="#698b22">(</font><span><font color="#007080">&lt;</font></span> r <span><font color="#077807">0</font></span><font color="#698b22">)</font> <font color="#698b22">(</font><span><font color="#007080">=</font></span> r height<font color="#698b22">)</font><font color="#cdcd00">)</font><br />                         <span><font color="#077807">\space</font></span><br />                         <font color="#cdcd00">(</font><span><font color="#007080">get-in</font></span> board <span><font color="#912f11">[</font></span>r c<span><font color="#912f11">]</font></span><font color="#cdcd00">)</font><font color="#ee9a00">)</font><font color="#cd3700">)</font><span><font color="#912f11">)</font></span><br />         count-lives <span><font color="#912f11">(</font></span><span><font color="#912f11">fn</font></span> <span><font color="#912f11">[</font></span>p<span><font color="#912f11">]</font></span><br />                       <font color="#cd3700">(</font><span><font color="#1f3f81"><b>reduce</b></font></span> <span><font color="#007080">+</font></span> <font color="#ee9a00">(</font><span><font color="#1f3f81"><b>map</b></font></span> <span><font color="#912f11">#(</font></span><span><font color="#912f11">if</font></span> <span><font color="#912f11">(</font></span><span><font color="#007080">=</font></span> <span><font color="#077807">\#</font></span> <font color="#cd3700">(</font>get-state p %<font color="#cd3700">)</font><span><font color="#912f11">)</font></span> <span><font color="#077807">1</font></span> <span><font color="#077807">0</font></span><span><font color="#912f11">)</font></span> offsets<font color="#ee9a00">)</font><font color="#cd3700">)</font><span><font color="#912f11">)</font></span><br />         next-state <span><font color="#912f11">(</font></span><span><font color="#912f11">fn</font></span> <span><font color="#912f11">[</font></span>s p<span><font color="#912f11">]</font></span><br />                      <font color="#cd3700">(</font><span><font color="#912f11">let</font></span> <span><font color="#912f11">[</font></span>n <span><font color="#912f11">(</font></span>count-lives p<span><font color="#912f11">)]</font></span> <br />                        <font color="#ee9a00">(</font><span><font color="#912f11">if</font></span> <font color="#cdcd00">(</font><span><font color="#800090">or</font></span> <font color="#698b22">(</font><span><font color="#007080">=</font></span> n <span><font color="#077807">3</font></span><font color="#698b22">)</font><br />                                <font color="#698b22">(</font><span><font color="#800090">and</font></span> <font color="#008b00">(</font><span><font color="#007080">=</font></span> s <span><font color="#077807">\#</font></span><font color="#008b00">)</font> <font color="#008b00">(</font><span><font color="#007080">=</font></span> n <span><font color="#077807">2</font></span><font color="#008b00">)</font><font color="#698b22">)</font><font color="#cdcd00">)</font><br />                          <span><font color="#077807">\#</font></span><br />                          <span><font color="#077807">\space</font></span><font color="#ee9a00">)</font><font color="#cd3700">)</font><span><font color="#912f11">)]</font></span> <br />     <font color="#ee9a00">(</font><span><font color="#800090">-&gt;&gt;</font></span> <font color="#cdcd00">(</font><span><font color="#1f3f81"><b>for</b></font></span> <span><font color="#912f11">[</font></span>y <span><font color="#912f11">(</font></span><span><font color="#007080">range</font></span> height<span><font color="#912f11">)</font></span> x <span><font color="#912f11">(</font></span><span><font color="#007080">range</font></span> width<span><font color="#912f11">)]</font></span><br />            <font color="#698b22">(</font>next-state <font color="#008b00">(</font><span><font color="#007080">get-in</font></span> board <span><font color="#912f11">[</font></span>y x<span><font color="#912f11">]</font></span><font color="#008b00">)</font> <span><font color="#912f11">[</font></span>x y<span><font color="#912f11">]</font></span><font color="#698b22">)</font><font color="#cdcd00">)</font><br />       <font color="#cdcd00">(</font><span><font color="#007080">partition</font></span> width<font color="#cdcd00">)</font><br />       <font color="#cdcd00">(</font><span><font color="#1f3f81"><b>map</b></font></span> <span><font color="#912f11">#(</font></span><span><font color="#007080">apply</font></span> <span><font color="#007080">str</font></span> <span><font color="#912f11">%</font></span><span><font color="#912f11">)</font></span><font color="#cdcd00">)</font><br />       <span><font color="#007080">vec</font></span><font color="#ee9a00">)</font><font color="#cd3700">)</font><span><font color="#912f11">)</font></span><br /><span><font color="#786000">; This is straight-forward. The only tricky part is to remember that the order </font></span><br /><span><font color="#786000">; of paramaters for the get-in function and the x-y coordinates is opposite to </font></span><br /><span><font color="#786000">; each other.   </font></span></p> <p><span><font color="#786000">; 95: Write a predicate which checks whether or not a given sequence represents</font></span><br /><span><font color="#786000">; a binary tree. Each node in the tree must have a value, a left child, and a </font></span><br /><span><font color="#786000">; right child.</font></span><br /><span><font color="#786000">; (= (__ '(:a (:b nil nil) nil)) true)</font></span><br /><span><font color="#786000">; (= (__ '(:a (:b nil nil))) false)</font></span><br /><span><font color="#786000">; (= (__ [1 nil [2 [3 nil nil] [4 nil nil]]]) true)</font></span><br /><span><font color="#912f11">(</font></span><span><font color="#912f11">fn</font></span> bt? <span><font color="#912f11">[</font></span>t<span><font color="#912f11">]</font></span><br />   <font color="#cd3700">(</font><span><font color="#912f11">if</font></span> <font color="#ee9a00">(</font><span><font color="#800090">or</font></span> <font color="#cdcd00">(</font><span><font color="#007080">not</font></span> <font color="#698b22">(</font><span><font color="#007080">sequential?</font></span> t<font color="#698b22">)</font><font color="#cdcd00">)</font><br />           <font color="#cdcd00">(</font><span><font color="#800090">and</font></span> <font color="#698b22">(</font><span><font color="#007080">=</font></span> <span><font color="#077807">3</font></span> <font color="#008b00">(</font><span><font color="#007080">count</font></span> t<font color="#008b00">)</font><font color="#698b22">)</font><br />                <font color="#698b22">(</font>bt? <font color="#008b00">(</font><span><font color="#007080">second</font></span> t<font color="#008b00">)</font><font color="#698b22">)</font><br />                <font color="#698b22">(</font>bt? <font color="#008b00">(</font><span><font color="#007080">last</font></span> t<font color="#008b00">)</font><font color="#698b22">)</font><font color="#cdcd00">)</font><font color="#ee9a00">)</font><br />     <span><font color="#077807">true</font></span> <span><font color="#077807">false</font></span><font color="#cd3700">)</font><span><font color="#912f11">)</font></span><br /><span><font color="#786000">; I think one of the unit tests of the problem is wrong: </font></span><br /><span><font color="#786000">; (= (__ [1 [2 [3 [4 false nil] nil] nil] nil]) false)</font></span><br /><span><font color="#786000">; why shouldn't "false" be a legal tree node, or why should leaf have to be nil? </font></span></p> <p><span><font color="#786000">; 96: Let us define a binary tree as "symmetric" if the left half of the tree </font></span><br /><span><font color="#786000">; is the mirror image of the right half of the tree. Write a predicate to </font></span><br /><span><font color="#786000">; determine whether or not a given binary tree is symmetric.</font></span><br /><span><font color="#786000">; (= (__ '(:a (:b nil nil) (:b nil nil))) true)</font></span><br /><span><font color="#786000">; (= (__ '(:a (:b nil nil) nil)) false)</font></span><br /><span><font color="#786000">; (= (__ [1 [2 nil [3 [4 [5 nil nil] [6 nil nil]] nil]]</font></span><br />           <span><font color="#786000">;[2 [3 nil [4 [6 nil nil] [5 nil nil]]] nil]]) true)</font></span><br /><span><font color="#912f11">(</font></span><span><font color="#912f11">fn</font></span> <span><font color="#912f11">[</font></span>t<span><font color="#912f11">]</font></span><br />   <font color="#cd3700">(</font><font color="#ee9a00">(</font><span><font color="#912f11">fn</font></span> mir? <span><font color="#912f11">[</font></span>l r<span><font color="#912f11">]</font></span><br />      <font color="#cdcd00">(</font><span><font color="#912f11">if</font></span> <font color="#698b22">(</font><span><font color="#800090">or</font></span> <font color="#008b00">(</font><span><font color="#007080">=</font></span> <span><font color="#077807">nil</font></span> l r<font color="#008b00">)</font><br />              <font color="#008b00">(</font><span><font color="#800090">and</font></span> <font color="#96cdcd">(</font><span><font color="#007080">=</font></span> <font color="#00688b">(</font><span><font color="#007080">first</font></span> l<font color="#00688b">)</font> <font color="#00688b">(</font><span><font color="#007080">first</font></span> r<font color="#00688b">)</font><font color="#96cdcd">)</font><br />                   <font color="#96cdcd">(</font>mir? <font color="#00688b">(</font><span><font color="#007080">second</font></span> l<font color="#00688b">)</font> <font color="#00688b">(</font><span><font color="#007080">last</font></span> r<font color="#00688b">)</font><font color="#96cdcd">)</font><br />                   <font color="#96cdcd">(</font>mir? <font color="#00688b">(</font><span><font color="#007080">last</font></span> l<font color="#00688b">)</font> <font color="#00688b">(</font><span><font color="#007080">second</font></span> r<font color="#00688b">)</font><font color="#96cdcd">)</font><font color="#008b00">)</font><font color="#698b22">)</font><br />        <span><font color="#077807">true</font></span> <span><font color="#077807">false</font></span><font color="#cdcd00">)</font><font color="#ee9a00">)</font> <br />    <font color="#ee9a00">(</font><span><font color="#007080">second</font></span> t<font color="#ee9a00">)</font> <font color="#ee9a00">(</font><span><font color="#007080">last</font></span> t<font color="#ee9a00">)</font><font color="#cd3700">)</font><span><font color="#912f11">)</font></span></p> <p><span><font color="#786000">; 97: Pascal's triangle is a triangle of numbers computed using the following </font></span><br /><span><font color="#786000">; rules: </font></span><br /><span><font color="#786000">; - The first row is 1.</font></span><br /><span><font color="#786000">; - Each successive row is computed by adding together adjacent numbers in the </font></span><br /><span><font color="#786000">;   row above, and adding a 1 to the beginning and end of the row.  </font></span><br /><span><font color="#786000">; Write a function which returns the nth row of Pascal's Triangle.</font></span><br /><span><font color="#786000">; (= (map __ (range 1 6))</font></span><br />    <span><font color="#786000">;[     [1]</font></span><br />         <span><font color="#786000">;[1 1]</font></span><br />        <span><font color="#786000">;[1 2 1]</font></span><br />       <span><font color="#786000">;[1 3 3 1]</font></span><br />      <span><font color="#786000">;[1 4 6 4 1]])</font></span><br /><span><font color="#912f11">(</font></span><span><font color="#912f11">fn</font></span> <span><font color="#912f11">[</font></span>n<span><font color="#912f11">]</font></span><br />   <font color="#cd3700">(</font><span><font color="#007080">nth</font></span> <font color="#ee9a00">(</font><span><font color="#007080">iterate</font></span> <br />          <font color="#cdcd00">(</font><span><font color="#912f11">fn</font></span> <span><font color="#912f11">[</font></span>pre<span><font color="#912f11">]</font></span> <br />            <font color="#698b22">(</font><span><font color="#007080">vec</font></span> <br />              <font color="#008b00">(</font><span><font color="#007080">concat</font></span> <br />                <span><font color="#912f11">[</font></span><span><font color="#077807">1</font></span><span><font color="#912f11">]</font></span> <br />                <font color="#96cdcd">(</font><span><font color="#1f3f81"><b>map</b></font></span> <font color="#00688b">(</font><span><font color="#912f11">fn</font></span> <span><font color="#912f11">[[</font></span>f s<span><font color="#912f11">]]</font></span> <font color="#483d8b">(</font><span><font color="#007080">+</font></span> f s<font color="#483d8b">)</font><font color="#00688b">)</font> <font color="#00688b">(</font><span><font color="#007080">partition</font></span> <span><font color="#077807">2</font></span> <span><font color="#077807">1</font></span> pre<font color="#00688b">)</font><font color="#96cdcd">)</font> <br />                <span><font color="#912f11">[</font></span><span><font color="#077807">1</font></span><span><font color="#912f11">]</font></span><font color="#008b00">)</font><font color="#698b22">)</font><font color="#cdcd00">)</font><br />          <span><font color="#912f11">[</font></span><span><font color="#077807">1</font></span><span><font color="#912f11">]</font></span><font color="#ee9a00">)</font><br />        <font color="#ee9a00">(</font><span><font color="#007080">dec</font></span> n<font color="#ee9a00">)</font><font color="#cd3700">)</font><span><font color="#912f11">)</font></span><br /></p></font> </div> </div></div> <ul class="links inline"><li class="comment-add"><a href="/blog/2011/06/my-solutions-problems-no-76-100-4clojure-com#comment-form" title="Share your thoughts and opinions." hreflang="und">Add new comment</a></li></ul><section> <a id="comment-44"></a> <article data-comment-user-id="0" class="js-comment comment"> <mark class="hidden" data-comment-timestamp="1330131873"></mark> <footer class="attribution"> <article typeof="schema:Person" about="/user/0"> <div class="field field--name-user-picture field--type-image field--label-hidden field__item"> <img src="/sites/default/files/styles/thumbnail/public/default_images/default-user-image.png?itok=hWWOuuKw" width="100" height="100" alt="Profile picture for user Nik" title="Anonymous user" typeof="foaf:Image" /> </div> </article> <div class="comment-submitted"> <p class="commenter-name"> <a rel="nofollow" href="http://mattdeboard.net" lang="" typeof="schema:Person" property="schema:name" datatype="">Matt</a> </p> <p class="comment-time"> Sat, 02/25/2012 - 01:04 </p> </div> </footer> <div class="comment-text"> <div class="comment-arrow"></div> <h3><a href="/comment/44#comment-44" class="permalink" rel="bookmark" hreflang="en">Problem #95</a></h3> <div class="content"> <div class="field field--name-comment-body field--type-text-long field--label-hidden field__item"><div class="tex2jax_process"><p>re: Your solution to #95, and pardon me if this is kind of a "data structures 101" question, implies that 'nil' is a binary tree. Why is this so?</p> </div></div> <drupal-render-placeholder callback="comment.lazy_builders:renderLinks" arguments="0=44&amp;1=default&amp;2=en&amp;3=" token="qf3mmt8euf92bfJyrUCgxLdeia7MEJffOVboYOALmzg"></drupal-render-placeholder> </div> </div> </article> <div class="indented"><a id="comment-48"></a> <article data-comment-user-id="1" class="js-comment comment"> <mark class="hidden" data-comment-timestamp="1330635685"></mark> <footer class="attribution"> <article typeof="schema:Person" about="/user/huahai"> <div class="field field--name-user-picture field--type-image field--label-hidden field__item"> <img src="/sites/default/files/styles/thumbnail/public/pictures/2017-11/huahai.jpg?itok=ZwjJWYAc" width="88" height="100" alt="Profile picture for user Huahai" typeof="foaf:Image" /> </div> </article> <div class="comment-submitted"> <p class="commenter-name"> <a title="View user profile." href="/user/huahai" lang="" about="/user/huahai" typeof="schema:Person" property="schema:name" datatype="">Huahai</a> </p> <p class="comment-time"> Thu, 03/01/2012 - 21:01 </p> </div> <p class="visually-hidden">In reply to <a href="/comment/44#comment-44" class="permalink" rel="bookmark" hreflang="en">Problem #95</a> by <a rel="nofollow" href="http://mattdeboard.net" lang="" typeof="schema:Person" property="schema:name" datatype="">Matt</a></p> </footer> <div class="comment-text"> <div class="comment-arrow"></div> <h3><a href="/comment/48#comment-48" class="permalink" rel="bookmark" hreflang="en">Interesting point</a></h3> <div class="content"> <div class="field field--name-comment-body field--type-text-long field--label-hidden field__item"><div class="tex2jax_process"><p>I think it's up to the definition of a binary tree.&nbsp; Wikipedia defines a binary tree as such: "In <a href="http://en.wikipedia.org/wiki/Computer_science" title="Computer science">computer science</a>, a <b>binary tree</b> is a <a href="http://en.wikipedia.org/wiki/Tree_%28data_structure%29" title="Tree (data structure)">tree data structure</a> in which each node has at most two <a href="http://en.wikipedia.org/wiki/Child_node" title="Child node" class="mw-redirect">child nodes</a>". If we take such a definition literally, which I am, a single nil can be a binary tree if it is passed in as a tree type. Unless the definition requires that the tree data structure must not be a single nil, but it is not defined in such way, and the question is not explicit about this either.</p> </div></div> <drupal-render-placeholder callback="comment.lazy_builders:renderLinks" arguments="0=48&amp;1=default&amp;2=en&amp;3=" token="OrvEVqV-UezZv7CqEUFdTN7wkGEbOXOU7VDTkUNmtKE"></drupal-render-placeholder> </div> </div> </article> </div> <h2>Add new comment</h2> <drupal-render-placeholder callback="comment.lazy_builders:renderForm" arguments="0=node&amp;1=117&amp;2=comment_node_blog&amp;3=comment_node_blog" token="zXNRKgaAmmv_xxruDsmA7keUcB8LpdA83pqyOTAewtQ"></drupal-render-placeholder> </section> <strong class="node_view"></strong> Sun, 05 Jun 2011 05:36:58 +0000 Huahai 117 at https://yyhh.org My solutions for problems No. 51-75 on 4clojure.com https://yyhh.org/blog/2011/05/my-solutions-problems-no-51-75-4clojure-com <span>My solutions for problems No. 51-75 on 4clojure.com</span> <span><a title="View user profile." href="/user/huahai" lang="" about="/user/huahai" typeof="schema:Person" property="schema:name" datatype="">Huahai</a></span> <span>Wed, 05/25/2011 - 02:59</span> <div class="field field--name-field-notebook field--type-entity-reference field--label-hidden field__items"> <div class="field__item"><div about="/notebook/clojure" id="taxonomy-term-35" class="taxonomy-term vocabulary-notebook"> <a href="/notebook/clojure"> <div class="field field--name-name field--type-string field--label-hidden field__item">Clojure</div> </a> <div class="content"> </div> </div> </div> </div> <div class="field field--name-body field--type-text-with-summary field--label-hidden field__item"><div class="tex2jax_process"><p>This post continues the <a href="http://yyhh.org/blog/2011/05/my-solutions-first-50-problems-4clojure-com">previous one</a>, on my solutions for small clojure programming problems on <a href="http://www.4clojure.com">4clojure.com</a>. Doing these problems seems to be addictive as I could not seem to stop myself. The site recently added a golf league feature, so one can see how short one's own solution compared with others. If a lot of people got a much shorter solution than yours, you know you are not thinking in the right way. This little competition makes the site even more attractive. Anyhow, the code is here:</p> <div class="codeblock"> <font face="monospace"><br /><span><font color="#786000">; 53: Given a vector of integers, find the longest consecutive sub-sequence of</font></span><br /><span><font color="#786000">; increasing numbers.  If two sub-sequences have the same length, use the one </font></span><br /><span><font color="#786000">; that occurs first. An increasing sub-sequence must have a length of 2 or </font></span><br /><span><font color="#786000">; greater to qualify.</font></span><br /><span><font color="#786000">; (= (__ [1 0 1 2 3 0 4 5]) [0 1 2 3])</font></span><br /><span><font color="#786000">; (= (__ [7 6 5 4]) [])</font></span><br /><span><font color="#912f11">(</font></span><span><font color="#912f11">fn</font></span> <span><font color="#912f11">[</font></span>coll<span><font color="#912f11">]</font></span><br />   <font color="#cd3700">(</font><span><font color="#800090">-&gt;&gt;</font></span> <font color="#ee9a00">(</font><span><font color="#007080">partition</font></span> <span><font color="#077807">2</font></span> <span><font color="#077807">1</font></span> coll<font color="#ee9a00">)</font> <br />     <font color="#ee9a00">(</font><span><font color="#007080">partition-by</font></span> <span><font color="#912f11">#(</font></span><span><font color="#007080">-</font></span> <span><font color="#912f11">(</font></span><span><font color="#007080">second</font></span> %<span><font color="#912f11">)</font></span> <span><font color="#912f11">(</font></span><span><font color="#007080">first</font></span> %<span><font color="#912f11">))</font></span><font color="#ee9a00">)</font> <br />     <font color="#ee9a00">(</font><span><font color="#1f3f81"><b>filter</b></font></span> <span><font color="#912f11">#(</font></span><span><font color="#007080">=</font></span> <span><font color="#077807">1</font></span> <span><font color="#912f11">(</font></span><span><font color="#007080">-</font></span> <font color="#cd3700">(</font><span><font color="#007080">second</font></span> <font color="#ee9a00">(</font><span><font color="#007080">first</font></span> %<font color="#ee9a00">)</font><font color="#cd3700">)</font> <font color="#cd3700">(</font><span><font color="#007080">ffirst</font></span> %<font color="#cd3700">)</font><span><font color="#912f11">))</font></span><font color="#ee9a00">)</font> <br />     <font color="#ee9a00">(</font><span><font color="#1f3f81"><b>reduce</b></font></span> <span><font color="#912f11">#(</font></span><span><font color="#912f11">if</font></span> <span><font color="#912f11">(</font></span><span><font color="#007080">&lt;</font></span> <font color="#cd3700">(</font><span><font color="#007080">count</font></span> %<span><font color="#077807">1</font></span><font color="#cd3700">)</font> <font color="#cd3700">(</font><span><font color="#007080">count</font></span> %<span><font color="#077807">2</font></span><font color="#cd3700">)</font><span><font color="#912f11">)</font></span> <span><font color="#912f11">%2</font></span> <span><font color="#912f11">%1</font></span><span><font color="#912f11">)</font></span> <span><font color="#912f11">[]</font></span><font color="#ee9a00">)</font><br />     <span><font color="#007080">flatten</font></span><br />     <span><font color="#007080">distinct</font></span><font color="#cd3700">)</font><span><font color="#912f11">)</font></span><br /><span><font color="#786000">; we first create a list of neighoring pairs, partition them by their pair </font></span><br /><span><font color="#786000">; differences, keep those with difference 1, finally return the longest one</font></span> <p><span><font color="#786000">; 54: Write a function which returns a sequence of lists of x items each. </font></span><br /><span><font color="#786000">; Lists of less than x items should not be returned. </font></span><br /><span><font color="#786000">; (= (__ 3 (range 8)) '((0 1 2) (3 4 5))) </font></span><br /><span><font color="#786000">; forbidden: partition, partition-all</font></span><br /><span><font color="#912f11">(</font></span><span><font color="#912f11">fn</font></span> partition2 <span><font color="#912f11">[</font></span>n coll<span><font color="#912f11">]</font></span><br />   <font color="#cd3700">(</font><span><font color="#1f3f81"><b>when</b></font></span> <font color="#ee9a00">(</font><span><font color="#007080">&lt;=</font></span> n <font color="#cdcd00">(</font><span><font color="#007080">count</font></span> coll<font color="#cdcd00">)</font><font color="#ee9a00">)</font><br />     <font color="#ee9a00">(</font><span><font color="#007080">cons</font></span> <font color="#cdcd00">(</font><span><font color="#007080">take</font></span> n coll<font color="#cdcd00">)</font> <font color="#cdcd00">(</font>partition2 n <font color="#698b22">(</font><span><font color="#007080">drop</font></span> n coll<font color="#698b22">)</font><font color="#cdcd00">)</font><font color="#ee9a00">)</font><font color="#cd3700">)</font><span><font color="#912f11">)</font></span><br /><span><font color="#786000">; we recursively take n items till not enough items</font></span></p> <p><span><font color="#786000">; 55: Write a function that returns a map containing the number of occurences </font></span><br /><span><font color="#786000">; of each distinct item in a sequence.</font></span><br /><span><font color="#786000">; (= (__ [1 1 2 3 2 1 1]) {1 4, 2 2, 3 1})</font></span><br /><span><font color="#786000">; forbidden: frequencies</font></span><br /><span><font color="#912f11">(</font></span><span><font color="#912f11">fn</font></span> <span><font color="#912f11">[</font></span>coll<span><font color="#912f11">]</font></span><br />   <font color="#cd3700">(</font><span><font color="#912f11">let</font></span> <span><font color="#912f11">[</font></span>gp <span><font color="#912f11">(</font></span><span><font color="#007080">group-by</font></span> <span><font color="#007080">identity</font></span> coll<span><font color="#912f11">)]</font></span> <br />     <font color="#ee9a00">(</font><span><font color="#007080">zipmap</font></span> <font color="#cdcd00">(</font><span><font color="#007080">keys</font></span> gp<font color="#cdcd00">)</font> <font color="#cdcd00">(</font><span><font color="#1f3f81"><b>map</b></font></span> <span><font color="#912f11">#(</font></span><span><font color="#007080">count</font></span> <span><font color="#912f11">(</font></span><span><font color="#007080">second</font></span> %<span><font color="#912f11">))</font></span> gp<font color="#cdcd00">)</font><font color="#ee9a00">)</font><font color="#cd3700">)</font><span><font color="#912f11">)</font></span><br /><span><font color="#786000">; note a map entry is just a two item vector, first item is the key, the</font></span><br /><span><font color="#786000">; second item is the value</font></span></p> <p><span><font color="#786000">; 56: Write a function which removes the duplicates from a sequence. Order of </font></span><br /><span><font color="#786000">; the items must be maintained.</font></span><br /><span><font color="#786000">; (= (__ [1 2 1 3 1 2 4]) [1 2 3 4])</font></span><br /><span><font color="#786000">; forbidden: distinct</font></span><br /><span><font color="#912f11">(</font></span><span><font color="#912f11">fn</font></span> <span><font color="#912f11">[</font></span>coll<span><font color="#912f11">]</font></span> <br />   <font color="#cd3700">(</font><font color="#ee9a00">(</font><span><font color="#912f11">fn</font></span> step <span><font color="#912f11">[[</font></span>x <span><font color="#912f11">&amp;</font></span> xs<span><font color="#912f11">]</font></span> seen<span><font color="#912f11">]</font></span> <br />      <font color="#cdcd00">(</font><span><font color="#1f3f81"><b>when</b></font></span> x<br />        <font color="#698b22">(</font><span><font color="#912f11">if</font></span> <font color="#008b00">(</font>seen x<font color="#008b00">)</font> <br />          <font color="#008b00">(</font>step xs seen<font color="#008b00">)</font><br />          <font color="#008b00">(</font><span><font color="#007080">cons</font></span> x <font color="#96cdcd">(</font>step xs <font color="#00688b">(</font><span><font color="#007080">conj</font></span> seen x<font color="#00688b">)</font><font color="#96cdcd">)</font><font color="#008b00">)</font><font color="#698b22">)</font><font color="#cdcd00">)</font><font color="#ee9a00">)</font> <br />    coll <span><font color="#912f11">#{}</font></span><font color="#cd3700">)</font><span><font color="#912f11">)</font></span><br /><span><font color="#786000">; we recursively go through the sequence, use a set to keep track of items </font></span><br /><span><font color="#786000">; we've seen, only return those we have not seen before. </font></span><br />   </p> <p><span><font color="#786000">; 58: Write a function which allows you to create function compositions. The </font></span><br /><span><font color="#786000">; parameter list should take a variable number of functions, and create a </font></span><br /><span><font color="#786000">; function applies them from right-to-left.</font></span><br /><span><font color="#786000">; (= [3 2 1] ((__ rest reverse) [1 2 3 4]))</font></span><br /><span><font color="#786000">; forbidden: comp</font></span><br /><span><font color="#912f11">(</font></span><span><font color="#912f11">fn</font></span> <span><font color="#912f11">[</font></span>x <span><font color="#912f11">&amp;</font></span> xs<span><font color="#912f11">]</font></span><br />   <font color="#cd3700">(</font><span><font color="#912f11">fn</font></span> <span><font color="#912f11">[</font></span><span><font color="#912f11">&amp;</font></span> args<span><font color="#912f11">]</font></span><br />     <font color="#ee9a00">(</font><font color="#cdcd00">(</font><span><font color="#912f11">fn</font></span> step <span><font color="#912f11">[[</font></span>f <span><font color="#912f11">&amp;</font></span> fs<span><font color="#912f11">]</font></span> a<span><font color="#912f11">]</font></span><br />        <font color="#698b22">(</font><span><font color="#912f11">if</font></span> fs<br />          <font color="#008b00">(</font>f <font color="#96cdcd">(</font>step fs a<font color="#96cdcd">)</font><font color="#008b00">)</font><br />          <font color="#008b00">(</font><span><font color="#007080">apply</font></span> f a<font color="#008b00">)</font><font color="#698b22">)</font><font color="#cdcd00">)</font><br />      <font color="#cdcd00">(</font><span><font color="#007080">cons</font></span> x xs<font color="#cdcd00">)</font> args<font color="#ee9a00">)</font><font color="#cd3700">)</font><span><font color="#912f11">)</font></span><br /><span><font color="#786000">; step function takes the function list and the arguments, recursively builds</font></span><br /><span><font color="#786000">; an ever deeper call stack till at the end of the list, where the right most </font></span><br /><span><font color="#786000">; function is called with the given arguments.</font></span><br />     </p> <p><span><font color="#786000">; 59: Take a set of functions and return a new function that takes a variable </font></span><br /><span><font color="#786000">; number of arguments and returns sequence containing the result of applying </font></span><br /><span><font color="#786000">; each function left-to-right to the argument list.</font></span><br /><span><font color="#786000">; (= [21 6 1] ((__ + max min) 2 3 5 1 6 4))</font></span><br /><span><font color="#786000">; forbidden: juxt</font></span><br /><span><font color="#912f11">(</font></span><span><font color="#912f11">fn</font></span> <span><font color="#912f11">[</font></span>x <span><font color="#912f11">&amp;</font></span> xs<span><font color="#912f11">]</font></span><br />   <font color="#cd3700">(</font><span><font color="#912f11">fn</font></span> <span><font color="#912f11">[</font></span><span><font color="#912f11">&amp;</font></span> args<span><font color="#912f11">]</font></span><br />     <font color="#ee9a00">(</font><span><font color="#1f3f81"><b>map</b></font></span> <span><font color="#912f11">#(</font></span><span><font color="#007080">apply</font></span> <span><font color="#912f11">%</font></span> args<span><font color="#912f11">)</font></span> <font color="#cdcd00">(</font><span><font color="#007080">cons</font></span> x xs<font color="#cdcd00">)</font><font color="#ee9a00">)</font><font color="#cd3700">)</font><span><font color="#912f11">)</font></span></p> <p><span><font color="#786000">; 60: Write a function which behaves like reduce, but returns each </font></span><br /><span><font color="#786000">; intermediate value of the reduction. Your function must accept either two </font></span><br /><span><font color="#786000">; or three arguments, and the return sequence must be lazy.</font></span><br /><span><font color="#786000">; (= (take 5 (__ + (range))) [0 1 3 6 10])</font></span><br /><span><font color="#786000">; (= (__ conj [1] [2 3 4]) [[1] [1 2] [1 2 3] [1 2 3 4]])</font></span><br /><span><font color="#786000">; forbidden: reductions</font></span><br /><span><font color="#912f11">(</font></span><span><font color="#912f11">fn</font></span> reductions2<br />   <font color="#cd3700">(</font><span><font color="#912f11">[</font></span>f init <span><font color="#912f11">[</font></span>x <span><font color="#912f11">&amp;</font></span> xs<span><font color="#912f11">]]</font></span> <br />    <font color="#ee9a00">(</font><span><font color="#007080">cons</font></span> init <font color="#cdcd00">(</font><span><font color="#800090">lazy-seq</font></span> <font color="#698b22">(</font><span><font color="#1f3f81"><b>when</b></font></span> x <font color="#008b00">(</font>reductions2 f <font color="#96cdcd">(</font>f init x<font color="#96cdcd">)</font> xs<font color="#008b00">)</font><font color="#698b22">)</font><font color="#cdcd00">)</font><font color="#ee9a00">)</font><font color="#cd3700">)</font> <br />   <font color="#cd3700">(</font><span><font color="#912f11">[</font></span>f coll<span><font color="#912f11">]</font></span> <br />    <font color="#ee9a00">(</font>reductions2 f <font color="#cdcd00">(</font><span><font color="#007080">first</font></span> coll<font color="#cdcd00">)</font> <font color="#cdcd00">(</font><span><font color="#007080">rest</font></span> coll<font color="#cdcd00">)</font><font color="#ee9a00">)</font><font color="#cd3700">)</font><span><font color="#912f11">)</font></span></p> <p><span><font color="#786000">; 61: Write a function which takes a vector of keys and a vector of values </font></span><br /><span><font color="#786000">; and constructs a map from them.</font></span><br /><span><font color="#786000">; (= (__ [:a :b :c] [1 2 3]) {:a 1, :b 2, :c 3})</font></span><br /><span><font color="#786000">; forbidden: zipmap</font></span><br /><span><font color="#912f11">#(</font></span><span><font color="#007080">into</font></span> <span><font color="#912f11">{}</font></span> <span><font color="#912f11">(</font></span><span><font color="#1f3f81"><b>map</b></font></span> <span><font color="#007080">vector</font></span> %<span><font color="#077807">1</font></span> %<span><font color="#077807">2</font></span><span><font color="#912f11">))</font></span></p> <p><span><font color="#786000">; 62. Given a side-effect free function f and an initial value x </font></span><br /><span><font color="#786000">; write a function which returns an infinite lazy sequence of x,</font></span><br /><span><font color="#786000">; (f x), (f (f x)), (f (f (f x))), etc.  </font></span><br /><span><font color="#786000">; (= (take 5 (__ #(* 2 %) 1)) [1 2 4 8 16])</font></span><br /><span><font color="#786000">; forbidden: iterate</font></span><br /><span><font color="#912f11">(</font></span><span><font color="#912f11">fn</font></span> iterate2 <span><font color="#912f11">[</font></span>f x<span><font color="#912f11">]</font></span><br />   <font color="#cd3700">(</font><span><font color="#007080">cons</font></span> x <font color="#ee9a00">(</font><span><font color="#800090">lazy-seq</font></span> <font color="#cdcd00">(</font>iterate2 f <font color="#698b22">(</font>f x<font color="#698b22">)</font><font color="#cdcd00">)</font><font color="#ee9a00">)</font><font color="#cd3700">)</font><span><font color="#912f11">)</font></span><br /><span><font color="#786000">; it turns out that clojure's own implmentation is the same </font></span></p> <p><span><font color="#786000">; 63. Given a function f and a sequence s, write a function which returns a </font></span><br /><span><font color="#786000">; map. The keys should be the values of f applied to each item in s. The value</font></span><br /><span><font color="#786000">; at each key should be a vector of corresponding items in the order they </font></span><br /><span><font color="#786000">; appear in s.</font></span><br /><span><font color="#786000">; (= (__ #(&gt; % 5) #{1 3 6 8}) {false [1 3], true [6 8]})</font></span><br /><span><font color="#786000">; forbidden group-by</font></span><br /><span><font color="#912f11">(</font></span><span><font color="#912f11">fn</font></span> <span><font color="#912f11">[</font></span>f s<span><font color="#912f11">]</font></span><br />   <font color="#cd3700">(</font><font color="#ee9a00">(</font><span><font color="#912f11">fn</font></span> step <span><font color="#912f11">[</font></span>ret f <span><font color="#912f11">[</font></span>x <span><font color="#912f11">&amp;</font></span> xs<span><font color="#912f11">]]</font></span><br />      <font color="#cdcd00">(</font><span><font color="#912f11">if</font></span> x<br />        <font color="#698b22">(</font><span><font color="#912f11">let</font></span> <span><font color="#912f11">[</font></span>k <span><font color="#912f11">(</font></span>f x<span><font color="#912f11">)]</font></span><br />          <font color="#008b00">(</font>step <font color="#96cdcd">(</font><span><font color="#007080">assoc</font></span> ret k <font color="#00688b">(</font><span><font color="#007080">conj</font></span> <font color="#483d8b">(</font><span><font color="#007080">get</font></span> ret k <span><font color="#912f11">[]</font></span><font color="#483d8b">)</font> x<font color="#00688b">)</font><font color="#96cdcd">)</font> f xs<font color="#008b00">)</font><font color="#698b22">)</font><br />        ret<font color="#cdcd00">)</font><font color="#ee9a00">)</font><br />     <span><font color="#912f11">{}</font></span> f <font color="#ee9a00">(</font><span><font color="#007080">seq</font></span> s<font color="#ee9a00">)</font><font color="#cd3700">)</font><span><font color="#912f11">)</font></span><br /><span><font color="#786000">; the get function takes a default argument for when the key is not found,</font></span><br /><span><font color="#786000">; which is used to initialize a vector here. Note the use of seq for s, as</font></span><br /><span><font color="#786000">; the collection may be a set, where the [x &amp; xs] destructering doesn't work.</font></span><br /><span><font color="#786000">; Intead of recursively going over a sequence, we can also use reduce:</font></span><br /><span><font color="#912f11">(</font></span><span><font color="#912f11">fn</font></span> <span><font color="#912f11">[</font></span>f s<span><font color="#912f11">]</font></span><br />   <font color="#cd3700">(</font><span><font color="#1f3f81"><b>reduce</b></font></span> <br />     <font color="#ee9a00">(</font><span><font color="#912f11">fn</font></span> <span><font color="#912f11">[</font></span>ret x<span><font color="#912f11">]</font></span><br />       <font color="#cdcd00">(</font><span><font color="#912f11">let</font></span> <span><font color="#912f11">[</font></span>k <span><font color="#912f11">(</font></span>f x<span><font color="#912f11">)]</font></span><br />         <font color="#698b22">(</font><span><font color="#007080">assoc</font></span> ret k <font color="#008b00">(</font><span><font color="#007080">conj</font></span> <font color="#96cdcd">(</font><span><font color="#007080">get</font></span> ret k <span><font color="#912f11">[]</font></span><font color="#96cdcd">)</font> x<font color="#008b00">)</font><font color="#698b22">)</font><font color="#cdcd00">)</font><font color="#ee9a00">)</font><br />     <span><font color="#912f11">{}</font></span> s<font color="#cd3700">)</font><span><font color="#912f11">)</font></span></p> <p><span><font color="#786000">; 65: Write a function which takes a collection and returns one of :map, :set,</font></span><br /><span><font color="#786000">; :list, or :vector - describing the type of collection it was given. </font></span><br /><span><font color="#786000">; (= :map (__ {:a 1, :b 2}))</font></span><br /><span><font color="#786000">; forbidden: class, type, Class, vector?, sequential?, list?, seq?, map?, set?</font></span><br /><span><font color="#786000">; instance? getClass</font></span><br /><span><font color="#912f11">(</font></span><span><font color="#912f11">fn</font></span> <span><font color="#912f11">[</font></span>coll<span><font color="#912f11">]</font></span><br />   <font color="#cd3700">(</font><span><font color="#912f11">let</font></span> <span><font color="#912f11">[</font></span>x <span><font color="#912f11">(</font></span><span><font color="#007080">rand-int</font></span> <span><font color="#077807">100</font></span><span><font color="#912f11">)</font></span> y <span><font color="#912f11">(</font></span><span><font color="#007080">rand-int</font></span> <span><font color="#077807">100</font></span><span><font color="#912f11">)</font></span> <br />         p <span><font color="#912f11">[</font></span>x y<span><font color="#912f11">]</font></span> c <span><font color="#912f11">(</font></span><span><font color="#007080">conj</font></span> coll z<span><font color="#912f11">)]</font></span><br />     <font color="#ee9a00">(</font><span><font color="#1f3f81"><b>cond</b></font></span> <br />       <font color="#cdcd00">(</font><span><font color="#007080">=</font></span> y <font color="#698b22">(</font><span><font color="#007080">get</font></span> c x<font color="#698b22">)</font><font color="#cdcd00">)</font> <span><font color="#1f3f81"><b>:map</b></font></span><br />       <font color="#cdcd00">(</font><span><font color="#007080">=</font></span> p <font color="#698b22">(</font><span><font color="#007080">get</font></span> c p<font color="#698b22">)</font><font color="#cdcd00">)</font> <span><font color="#1f3f81"><b>:set</b></font></span><br />       <font color="#cdcd00">(</font><span><font color="#007080">=</font></span> x <font color="#698b22">(</font><span><font color="#007080">last</font></span> <font color="#008b00">(</font><span><font color="#007080">conj</font></span> c x<font color="#008b00">)</font><font color="#698b22">)</font><font color="#cdcd00">)</font> <span><font color="#1f3f81"><b>:vector</b></font></span><br />       <span><font color="#1f3f81"><b>:else</b></font></span> <span><font color="#1f3f81"><b>:list</b></font></span><font color="#ee9a00">)</font><font color="#cd3700">)</font><span><font color="#912f11">)</font></span><br /><span><font color="#786000">; we conj a random two element vector into the collection, map will treat it </font></span><br /><span><font color="#786000">; as a new key value pair, others treat it as a single item; set is a map too,</font></span><br /><span><font color="#786000">; so we can get the vector back with itself as the key; vector and list are </font></span><br /><span><font color="#786000">; differentiated by the position of the conj.</font></span></p> <p><span><font color="#786000">; 67: Write a function which returns the first x number of prime numbers. </font></span><br /><span><font color="#912f11">(</font></span><span><font color="#912f11">fn</font></span> <span><font color="#912f11">[</font></span>x<span><font color="#912f11">]</font></span><br />   <font color="#cd3700">(</font><span><font color="#007080">take</font></span> x<br />         <font color="#ee9a00">(</font><span><font color="#007080">remove</font></span> <br />           <font color="#cdcd00">(</font><span><font color="#912f11">fn</font></span> <span><font color="#912f11">[</font></span>n<span><font color="#912f11">]</font></span> <br />             <font color="#698b22">(</font><span><font color="#007080">some</font></span> <span><font color="#912f11">#(</font></span><span><font color="#007080">=</font></span> <span><font color="#077807">0</font></span> <span><font color="#912f11">(</font></span><span><font color="#007080">mod</font></span> n %<span><font color="#912f11">))</font></span> <font color="#008b00">(</font><span><font color="#007080">range</font></span> <span><font color="#077807">2</font></span> <font color="#96cdcd">(</font><span><font color="#007080">inc</font></span> <font color="#00688b">(</font><span><font color="#007080">int</font></span> <font color="#483d8b">(</font>Math/sqrt n<font color="#483d8b">)</font><font color="#00688b">)</font><font color="#96cdcd">)</font><font color="#008b00">)</font><font color="#698b22">)</font><font color="#cdcd00">)</font><br />           <font color="#cdcd00">(</font><span><font color="#007080">iterate</font></span> <span><font color="#007080">inc</font></span> <span><font color="#077807">2</font></span><font color="#cdcd00">)</font><font color="#ee9a00">)</font><font color="#cd3700">)</font><span><font color="#912f11">)</font></span><br /><span><font color="#786000">; we just test each number n, each divided by numbers from 2 up to sqrt(n)</font></span></p> <p><span><font color="#786000">; 69: Write a function which takes a function f and a variable number of maps.</font></span><br /><span><font color="#786000">; Your function should return a map that consists of the rest of the maps </font></span><br /><span><font color="#786000">; conj-ed onto the first. If a key occurs in more than one map, the mapping(s)</font></span><br /><span><font color="#786000">; from the latter (left-to-right) should be combined with the mapping in the </font></span><br /><span><font color="#786000">; result by calling (f val-in-result val-in-latter)</font></span><br /><span><font color="#786000">; (= (__ - {1 10, 2 20} {1 3, 2 10, 3 15}) {1 7, 2 10, 3 15})</font></span><br /><span><font color="#786000">; forbidden: merge-with</font></span><br /><span><font color="#912f11">(</font></span><span><font color="#912f11">fn</font></span> <span><font color="#912f11">[</font></span>f m <span><font color="#912f11">&amp;</font></span> ms<span><font color="#912f11">]</font></span><br />   <font color="#cd3700">(</font><span><font color="#1f3f81"><b>reduce</b></font></span> <br />     <font color="#ee9a00">(</font><span><font color="#912f11">fn</font></span> <span><font color="#912f11">[</font></span>ret x<span><font color="#912f11">]</font></span><br />       <font color="#cdcd00">(</font><span><font color="#1f3f81"><b>reduce</b></font></span> <br />         <font color="#698b22">(</font><span><font color="#912f11">fn</font></span> <span><font color="#912f11">[</font></span>r k<span><font color="#912f11">]</font></span> <br />           <font color="#008b00">(</font><span><font color="#007080">conj</font></span> r <font color="#96cdcd">(</font><span><font color="#912f11">if</font></span> <font color="#00688b">(</font>r k<font color="#00688b">)</font> <span><font color="#912f11">[</font></span>k <span><font color="#912f11">(</font></span>f <font color="#cd3700">(</font>r k<font color="#cd3700">)</font> <font color="#cd3700">(</font>x k<font color="#cd3700">)</font><span><font color="#912f11">)]</font></span> <font color="#00688b">(</font><span><font color="#007080">find</font></span> x k<font color="#00688b">)</font><font color="#96cdcd">)</font><font color="#008b00">)</font><font color="#698b22">)</font> <br />         ret <font color="#698b22">(</font><span><font color="#007080">keys</font></span> x<font color="#698b22">)</font><font color="#cdcd00">)</font><font color="#ee9a00">)</font> <br />     <font color="#ee9a00">(</font><span><font color="#007080">cons</font></span> m ms<font color="#ee9a00">)</font><font color="#cd3700">)</font><span><font color="#912f11">)</font></span><br /><span><font color="#786000">; note a map is a function itself, so (r k) and (x k) works</font></span></p> <p><span><font color="#786000">; 70: Write a function which splits a sentence up into a sorted list of words.</font></span><br /><span><font color="#786000">; Capitalization should not affect sort order and punctuation should be ignored</font></span><br /><span><font color="#786000">; (= (__  "Have a nice day.") ["a" "day" "Have" "nice"])</font></span><br /><span><font color="#912f11">(</font></span><span><font color="#912f11">fn</font></span> <span><font color="#912f11">[</font></span>s<span><font color="#912f11">]</font></span><br />   <font color="#cd3700">(</font><span><font color="#007080">sort-by</font></span> <span><font color="#912f11">#(</font></span>.toLowerCase <span><font color="#912f11">%</font></span><span><font color="#912f11">)</font></span> <font color="#ee9a00">(</font><span><font color="#007080">re-seq</font></span> <span><font color="#077807">#"\w+"</font></span> s<font color="#ee9a00">)</font><font color="#cd3700">)</font><span><font color="#912f11">)</font></span></p> <p><span><font color="#786000">; 73: A tic-tac-toe board is represented by a two dimensional vector. X is </font></span><br /><span><font color="#786000">; represented by :x, O is represented by :o, and empty is represented by :e. A </font></span><br /><span><font color="#786000">; player wins by placing three Xs or three Os in a horizontal, vertical, or </font></span><br /><span><font color="#786000">; diagonal row. Write a function which analyzes a tic-tac-toe board and returns</font></span><br /><span><font color="#786000">; :x if X has won, :o if O has won, and nil if neither player has won.</font></span><br /><span><font color="#786000">; (= nil (__ [[:e :e :e]</font></span><br />             <span><font color="#786000">;[:e :e :e]</font></span><br />             <span><font color="#786000">;[:e :e :e]]))</font></span><br /><span><font color="#786000">;(= :x (__ [[:x :e :o]</font></span><br />            <span><font color="#786000">;[:x :e :e]</font></span><br />            <span><font color="#786000">;[:x :e :o]]))</font></span><br /><span><font color="#912f11">(</font></span><span><font color="#912f11">fn</font></span> <span><font color="#912f11">[</font></span>board<span><font color="#912f11">]</font></span><br />   <font color="#cd3700">(</font><span><font color="#912f11">let</font></span> <span><font color="#912f11">[</font></span>i <span><font color="#912f11">[</font></span><span><font color="#077807">0</font></span> <span><font color="#077807">1</font></span> <span><font color="#077807">2</font></span><span><font color="#912f11">]</font></span><br />         c <span><font color="#912f11">(</font></span><span><font color="#007080">take</font></span> <span><font color="#077807">12</font></span> <font color="#cd3700">(</font><span><font color="#007080">cycle</font></span> i<font color="#cd3700">)</font><span><font color="#912f11">)</font></span><br />         p <span><font color="#912f11">(</font></span><span><font color="#007080">flatten</font></span> <font color="#cd3700">(</font><span><font color="#1f3f81"><b>map</b></font></span> <span><font color="#912f11">#(</font></span><span><font color="#007080">repeat</font></span> <span><font color="#077807">3</font></span> <span><font color="#912f11">%</font></span><span><font color="#912f11">)</font></span> i<font color="#cd3700">)</font><span><font color="#912f11">)</font></span><br />         zip <span><font color="#912f11">#(</font></span><span><font color="#1f3f81"><b>map</b></font></span> <span><font color="#007080">vector</font></span> <span><font color="#912f11">%1</font></span> <span><font color="#912f11">%2</font></span><span><font color="#912f11">)</font></span><br />         win? <span><font color="#912f11">(</font></span><span><font color="#912f11">fn</font></span> <span><font color="#912f11">[</font></span>w<span><font color="#912f11">]</font></span> <br />                <font color="#cd3700">(</font><span><font color="#007080">some</font></span> <br />                  <font color="#ee9a00">(</font><span><font color="#912f11">fn</font></span> <span><font color="#912f11">[</font></span>x<span><font color="#912f11">]</font></span> <font color="#cdcd00">(</font><span><font color="#007080">every?</font></span> <span><font color="#912f11">#(</font></span><span><font color="#007080">=</font></span> w <span><font color="#912f11">(</font></span><span><font color="#007080">get-in</font></span> board %<span><font color="#912f11">))</font></span> x<font color="#cdcd00">)</font><font color="#ee9a00">)</font> <br />                  <font color="#ee9a00">(</font><span><font color="#007080">partition</font></span> <br />                    <span><font color="#077807">3</font></span> <font color="#cdcd00">(</font><span><font color="#007080">into</font></span> <font color="#698b22">(</font>zip <font color="#008b00">(</font><span><font color="#007080">into</font></span> i p<font color="#008b00">)</font> c<font color="#698b22">)</font> <font color="#698b22">(</font>zip c <font color="#008b00">(</font><span><font color="#007080">into</font></span> <font color="#96cdcd">(</font><span><font color="#007080">reverse</font></span> i<font color="#96cdcd">)</font> p<font color="#008b00">)</font><font color="#698b22">)</font><font color="#cdcd00">)</font><font color="#ee9a00">)</font><font color="#cd3700">)</font><span><font color="#912f11">)]</font></span><br />     <font color="#ee9a00">(</font><span><font color="#1f3f81"><b>cond</b></font></span> <br />       <font color="#cdcd00">(</font>win? <span><font color="#1f3f81"><b>:x</b></font></span><font color="#cdcd00">)</font> <span><font color="#1f3f81"><b>:x</b></font></span><br />       <font color="#cdcd00">(</font>win? <span><font color="#1f3f81"><b>:o</b></font></span><font color="#cdcd00">)</font> <span><font color="#1f3f81"><b>:o</b></font></span><font color="#ee9a00">)</font><font color="#cd3700">)</font><span><font color="#912f11">)</font></span><br /><span><font color="#786000">; we basically enumerate all possible winning positions, which fall into</font></span><br /><span><font color="#786000">; some regular patterns. I am sure there are better ways, but in the </font></span><br /><span><font color="#786000">; interest of time... Note the use of get-in to fetech value in a multiple </font></span><br /><span><font color="#786000">; dimensional vector: (get-in board [x y])</font></span></p> <p><span><font color="#786000">; 74: Given a string of comma separated integers, write a function which </font></span><br /><span><font color="#786000">; returns a new comma separated string that only contains the numbers </font></span><br /><span><font color="#786000">; which are perfect squares.</font></span><br /><span><font color="#786000">; (= (__ "4,5,6,7,8,9") "4,9")</font></span><br /><span><font color="#912f11">(</font></span><span><font color="#912f11">fn</font></span> <span><font color="#912f11">[</font></span>s<span><font color="#912f11">]</font></span><br />   <font color="#cd3700">(</font><span><font color="#800090">-&gt;&gt;</font></span> <font color="#ee9a00">(</font><span><font color="#007080">re-seq</font></span> <span><font color="#077807">#"\d+"</font></span> s<font color="#ee9a00">)</font><br />     <font color="#ee9a00">(</font><span><font color="#1f3f81"><b>map</b></font></span> <span><font color="#912f11">#(</font></span>Integer/parseInt <span><font color="#912f11">%</font></span><span><font color="#912f11">)</font></span><font color="#ee9a00">)</font><br />     <font color="#ee9a00">(</font><span><font color="#1f3f81"><b>filter</b></font></span> <font color="#cdcd00">(</font><span><font color="#912f11">fn</font></span> <span><font color="#912f11">[</font></span>x<span><font color="#912f11">]</font></span><br />               <font color="#698b22">(</font><span><font color="#912f11">let</font></span> <span><font color="#912f11">[</font></span>r <span><font color="#912f11">(</font></span><span><font color="#007080">int</font></span> <font color="#cd3700">(</font>Math/sqrt x<font color="#cd3700">)</font><span><font color="#912f11">)]</font></span><br />                 <font color="#008b00">(</font><span><font color="#007080">=</font></span> x <font color="#96cdcd">(</font><span><font color="#007080">*</font></span> r r<font color="#96cdcd">)</font><font color="#008b00">)</font><font color="#698b22">)</font><font color="#cdcd00">)</font><font color="#ee9a00">)</font><br />     <font color="#ee9a00">(</font><span><font color="#007080">interpose</font></span> <span><font color="#077807">","</font></span><font color="#ee9a00">)</font><br />     <font color="#ee9a00">(</font><span><font color="#007080">apply</font></span> <span><font color="#007080">str</font></span><font color="#ee9a00">)</font><font color="#cd3700">)</font><span><font color="#912f11">)</font></span></p> <p><span><font color="#786000">; 75: Two numbers are coprime if their greatest common divisor equals 1. </font></span><br /><span><font color="#786000">; Euler's totient function f(x) is defined as the number of positive integers </font></span><br /><span><font color="#786000">; less than x which are coprime to x. The special case f(1) equals 1. Write a </font></span><br /><span><font color="#786000">; function which calculates Euler's totient function.</font></span><br /><span><font color="#786000">; (= (__ 10) (count '(1 3 7 9)) 4)</font></span><br /><span><font color="#912f11">(</font></span><span><font color="#912f11">fn</font></span> <span><font color="#912f11">[</font></span>n<span><font color="#912f11">]</font></span><br />   <font color="#cd3700">(</font><span><font color="#800090">-&gt;&gt;</font></span> <font color="#ee9a00">(</font><span><font color="#007080">range</font></span> <span><font color="#077807">2</font></span> n<font color="#ee9a00">)</font><br />     <font color="#ee9a00">(</font><span><font color="#1f3f81"><b>filter</b></font></span> <font color="#cdcd00">(</font><span><font color="#912f11">fn</font></span> <span><font color="#912f11">[</font></span>x<span><font color="#912f11">]</font></span><br />               <font color="#698b22">(</font><span><font color="#007080">=</font></span> <span><font color="#077807">1</font></span> <font color="#008b00">(</font><font color="#96cdcd">(</font><span><font color="#912f11">fn</font></span> gcd <span><font color="#912f11">[</font></span>a b<span><font color="#912f11">]</font></span><br />                       <font color="#00688b">(</font><span><font color="#912f11">if</font></span> <font color="#483d8b">(</font><span><font color="#007080">=</font></span> <span><font color="#077807">0</font></span> b<font color="#483d8b">)</font> a <font color="#483d8b">(</font>gcd b <font color="#9400d3">(</font><span><font color="#007080">mod</font></span> a b<font color="#9400d3">)</font><font color="#483d8b">)</font><font color="#00688b">)</font><font color="#96cdcd">)</font><br />                     x n<font color="#008b00">)</font><font color="#698b22">)</font><font color="#cdcd00">)</font><font color="#ee9a00">)</font><br />     <span><font color="#007080">count</font></span><br />     <span><font color="#007080">inc</font></span><font color="#cd3700">)</font><span><font color="#912f11">)</font></span></p> <p></p></font> </div> </div></div> <ul class="links inline"><li class="comment-add"><a href="/blog/2011/05/my-solutions-problems-no-51-75-4clojure-com#comment-form" title="Share your thoughts and opinions." hreflang="und">Add new comment</a></li></ul><section> <a id="comment-19"></a> <article data-comment-user-id="0" class="js-comment comment"> <mark class="hidden" data-comment-timestamp="1312945440"></mark> <footer class="attribution"> <article typeof="schema:Person" about="/user/0"> <div class="field field--name-user-picture field--type-image field--label-hidden field__item"> <img src="/sites/default/files/styles/thumbnail/public/default_images/default-user-image.png?itok=hWWOuuKw" width="100" height="100" alt="Profile picture for user Nik" title="Anonymous user" typeof="foaf:Image" /> </div> </article> <div class="comment-submitted"> <p class="commenter-name"> <span lang="" typeof="schema:Person" property="schema:name" datatype="">angel</span> </p> <p class="comment-time"> Wed, 08/10/2011 - 04:04 </p> </div> </footer> <div class="comment-text"> <div class="comment-arrow"></div> <h3><a href="/comment/19#comment-19" class="permalink" rel="bookmark" hreflang="en">slution 69</a></h3> <div class="content"> <div class="field field--name-comment-body field--type-text-long field--label-hidden field__item"><div class="tex2jax_process"><p>Hi..sorry but I don't understand the solution 69...I've tried understand but its hard..would you explain it a bit more detailed..would be usefull for me..thanks a lot !!</p> </div></div> <drupal-render-placeholder callback="comment.lazy_builders:renderLinks" arguments="0=19&amp;1=default&amp;2=en&amp;3=" token="pFM0YP_kPDKouK2EtUL6FOjpmw7K7wAbolYISDNrUb4"></drupal-render-placeholder> </div> </div> </article> <div class="indented"><a id="comment-20"></a> <article data-comment-user-id="1" class="js-comment comment"> <mark class="hidden" data-comment-timestamp="1313000424"></mark> <footer class="attribution"> <article typeof="schema:Person" about="/user/huahai"> <div class="field field--name-user-picture field--type-image field--label-hidden field__item"> <img src="/sites/default/files/styles/thumbnail/public/pictures/2017-11/huahai.jpg?itok=ZwjJWYAc" width="88" height="100" alt="Profile picture for user Huahai" typeof="foaf:Image" /> </div> </article> <div class="comment-submitted"> <p class="commenter-name"> <a title="View user profile." href="/user/huahai" lang="" about="/user/huahai" typeof="schema:Person" property="schema:name" datatype="">Huahai</a> </p> <p class="comment-time"> Wed, 08/10/2011 - 19:20 </p> </div> <p class="visually-hidden">In reply to <a href="/comment/19#comment-19" class="permalink" rel="bookmark" hreflang="en">slution 69</a> by <span lang="" typeof="schema:Person" property="schema:name" datatype="">angel</span></p> </footer> <div class="comment-text"> <div class="comment-arrow"></div> <h3><a href="/comment/20#comment-20" class="permalink" rel="bookmark" hreflang="en">merge-with</a></h3> <div class="content"> <div class="field field--name-comment-body field--type-text-long field--label-hidden field__item"><div class="tex2jax_process"><p>Hi angel,</p> <p>Thank you for stopping by. Let's read the code outside-in.</p> <p>The outer reduce runs through all the (variable numbers of) input maps to accumulate results, and it takes two arguments: The first is an anonymous function defined in place (explained below), that does the result calculation for each input map; and the second argument is just the list of input maps (cons together the first and the rest).</p> <p>The outer anonymous function of the outer reduce takes two arguments: ret is the accumulated result map so far, x is the next input map to be processed. This function uses a reduce function to run through the keys of x to accumulate results, starting with ret as the initial value.</p> <p>At each step (i.e., at different key of x), an inner anonymous function is used to calculate the new result map. This function take two arguments: r is the existing result map, k is the key currently being worked on. The work is very simple: if the key k already exists in the result map r, we use the given function f to calculate the new value of k using the combination of its value in r (existing map) and its value in x (input map), and conj the new key-value pair (a two-element vector) to the result map; if k does not exist in r, we simply conj the key-value pair in x (accessed by the find function) to the result map.</p> <p>Thinking on a higher level, we start with the first input map, taking it as the initial value of the result map, run through the rest of the input maps, and keep merging their values to the result map. Reduce is the perfect function for such a result accumulation purpose.</p> <p>As you know, this is an implementation of merge-with function. My implementation<span>, though a bit shorter, is actually similar to Clojure's own implementation, you can (source merge-with) in REPL to read theirs, which might be more readable, I am not sure.</span></p> <p>I hope this explanation helps. Please feel free to ask more questions.</p> </div></div> <drupal-render-placeholder callback="comment.lazy_builders:renderLinks" arguments="0=20&amp;1=default&amp;2=en&amp;3=" token="mjQjIFksqJ6ZjM-qsZdXnbdMOPuJzQMyYgUZM2WJMiA"></drupal-render-placeholder> </div> </div> </article> <div class="indented"><a id="comment-21"></a> <article data-comment-user-id="0" class="js-comment comment"> <mark class="hidden" data-comment-timestamp="1313008549"></mark> <footer class="attribution"> <article typeof="schema:Person" about="/user/0"> <div class="field field--name-user-picture field--type-image field--label-hidden field__item"> <img src="/sites/default/files/styles/thumbnail/public/default_images/default-user-image.png?itok=hWWOuuKw" width="100" height="100" alt="Profile picture for user Nik" title="Anonymous user" typeof="foaf:Image" /> </div> </article> <div class="comment-submitted"> <p class="commenter-name"> <span lang="" typeof="schema:Person" property="schema:name" datatype="">angel</span> </p> <p class="comment-time"> Wed, 08/10/2011 - 21:35 </p> </div> <p class="visually-hidden">In reply to <a href="/comment/20#comment-20" class="permalink" rel="bookmark" hreflang="en">merge-with</a> by <a title="View user profile." href="/user/huahai" lang="" about="/user/huahai" typeof="schema:Person" property="schema:name" datatype="">Huahai</a></p> </footer> <div class="comment-text"> <div class="comment-arrow"></div> <h3><a href="/comment/21#comment-21" class="permalink" rel="bookmark" hreflang="en">thanks</a></h3> <div class="content"> <div class="field field--name-comment-body field--type-text-long field--label-hidden field__item"><div class="tex2jax_process"><p>Hi..thanks for the usefull answer..now it is clear for me...thanks again......</p> </div></div> <drupal-render-placeholder callback="comment.lazy_builders:renderLinks" arguments="0=21&amp;1=default&amp;2=en&amp;3=" token="Ggjh53CjBkn-negFdWrONd_yCijxV8Mb1wMgJ0wJqUw"></drupal-render-placeholder> </div> </div> </article> <div class="indented"><a id="comment-23"></a> <article data-comment-user-id="1" class="js-comment comment"> <mark class="hidden" data-comment-timestamp="1313014275"></mark> <footer class="attribution"> <article typeof="schema:Person" about="/user/huahai"> <div class="field field--name-user-picture field--type-image field--label-hidden field__item"> <img src="/sites/default/files/styles/thumbnail/public/pictures/2017-11/huahai.jpg?itok=ZwjJWYAc" width="88" height="100" alt="Profile picture for user Huahai" typeof="foaf:Image" /> </div> </article> <div class="comment-submitted"> <p class="commenter-name"> <a title="View user profile." href="/user/huahai" lang="" about="/user/huahai" typeof="schema:Person" property="schema:name" datatype="">Huahai</a> </p> <p class="comment-time"> Wed, 08/10/2011 - 23:11 </p> </div> <p class="visually-hidden">In reply to <a href="/comment/21#comment-21" class="permalink" rel="bookmark" hreflang="en">thanks</a> by <span lang="" typeof="schema:Person" property="schema:name" datatype="">angel</span></p> </footer> <div class="comment-text"> <div class="comment-arrow"></div> <h3><a href="/comment/23#comment-23" class="permalink" rel="bookmark" hreflang="en">You are welcome</a></h3> <div class="content"> <div class="field field--name-comment-body field--type-text-long field--label-hidden field__item"><div class="tex2jax_process"><p>Clojure is a fun language to play with. Happy coding <img src="/sites/all/libraries/tinymce/jscripts/tiny_mce/plugins/emotions/img/smiley-cool.gif" alt="Cool" title="Cool" border="0"></p> </div></div> <drupal-render-placeholder callback="comment.lazy_builders:renderLinks" arguments="0=23&amp;1=default&amp;2=en&amp;3=" token="_lwPPJxAcgI7OLm8g8DrLbktb0ltUs7K5ctqtdtgsRg"></drupal-render-placeholder> </div> </div> </article> </div></div></div> <h2>Add new comment</h2> <drupal-render-placeholder callback="comment.lazy_builders:renderForm" arguments="0=node&amp;1=116&amp;2=comment_node_blog&amp;3=comment_node_blog" token="6L7teB5nic38SOSreLhxb4SsIc_yW-wuGaEw0EVi4HY"></drupal-render-placeholder> </section> <strong class="node_view"></strong> Wed, 25 May 2011 01:59:29 +0000 Huahai 116 at https://yyhh.org My solutions for the first 50 problems on 4clojure.com https://yyhh.org/blog/2011/05/my-solutions-first-50-problems-4clojure-com <span>My solutions for the first 50 problems on 4clojure.com</span> <span><a title="View user profile." href="/user/huahai" lang="" about="/user/huahai" typeof="schema:Person" property="schema:name" datatype="">Huahai</a></span> <span>Thu, 05/19/2011 - 00:13</span> <div class="field field--name-field-notebook field--type-entity-reference field--label-hidden field__items"> <div class="field__item"><div about="/notebook/clojure" id="taxonomy-term-35" class="taxonomy-term vocabulary-notebook"> <a href="/notebook/clojure"> <div class="field field--name-name field--type-string field--label-hidden field__item">Clojure</div> </a> <div class="content"> </div> </div> </div> </div> <div class="field field--name-body field--type-text-with-summary field--label-hidden field__item"><div class="tex2jax_process"><p>For someone without previous Lisp experience, the hardest part of learning <a href="http://clojure.org">Clojure</a> programming seems to be the functional way of doing things. It is like math, one really needs to do some exercises in order to master it. At this point, <a href="http://www.4clojure.com">4clojure.com</a> seems to be the best place for getting such exercises. It has a lot of problems for new clojurians to solve. These problems ask one to fill in the blank __ so the given expressions are true. To give a little challenge, some clojure built-in functions are forbidden to use for some problems. New problems are added from time to time on the site, so it surely can keep me entertained for a while.</p> <p>I just finished the first 50 problems and think it might be helpful to post the solutions here. I tried to be functional and avoided using loops in the code. Some solutions are skipped as they seem trivial even for a functional newbie like myself. My solutions are probably just awful, but it is a fun experience nevertheless. I will post more solutions when I am done with them (Solutions <a href="http://yyhh.org/blog/2011/05/my-solutions-problems-no-51-75-4clojure-com">No.50-75</a> and <a href="http://yyhh.org/blog/2011/06/my-solutions-problems-no-76-100-4clojure-com">76-100</a>) Update: please find better solutions for problem 21, 27 and 44, contributed by visitors in the comments section below. Thank you guys for the nice solutions. I appreciate it.</p> <div class="codeblock"><font face="monospace"><span><font color="#786000">; 21: Write a function which returns the Nth element from a sequence.</font></span><br /><span><font color="#786000">; (= (__ '(4 5 6 7) 2) 6)</font></span><br /><span><font color="#786000">; forbidden: nth</font></span><br /><span><font color="#912f11">(</font></span><span><font color="#912f11">fn</font></span> <span><font color="#912f11">[</font></span>coll n<span><font color="#912f11">]</font></span> <br />   <font color="#cd3700">(</font><font color="#ee9a00">(</font><span><font color="#007080">apply</font></span> <span><font color="#007080">comp</font></span> <font color="#cdcd00">(</font><span><font color="#007080">cons</font></span> <span><font color="#007080">first</font></span> <font color="#698b22">(</font><span><font color="#007080">repeat</font></span> n <span><font color="#007080">rest</font></span><font color="#698b22">)</font><font color="#cdcd00">)</font><font color="#ee9a00">)</font> coll<font color="#cd3700">)</font><span><font color="#912f11">)</font></span><br /><span><font color="#786000">; We first compose n rest functions to get progressively shorter lists </font></span></font></div> <div class="codeblock"><font face="monospace"><span><font color="#786000">; till the </font></span><span><font color="#786000">desired element is the head, then take the head. A less </font></span></font></div> <div class="codeblock"><font face="monospace"><span><font color="#786000">; </font></span></font><font face="monospace"><span><font color="#786000">fancy version just </font></span><span><font color="#786000">uses nthnext, but it feels like cheating:</font></span><br /><span><font color="#912f11">(</font></span><span><font color="#912f11">fn</font></span> <span><font color="#912f11">[</font></span>coll n<span><font color="#912f11">]</font></span><br />   <font color="#cd3700">(</font><span><font color="#007080">first</font></span> <font color="#ee9a00">(</font><span><font color="#007080">nthnext</font></span> coll n<font color="#ee9a00">)</font><font color="#cd3700">)</font><span><font color="#912f11">)</font></span></font></div> <div class="codeblock"> </div> <div class="codeblock"> <font face="monospace"><span><font color="#786000">; 22: Write a function which returns the total number of elements in </font></span></font></div> <div class="codeblock"><font face="monospace"><span><font color="#786000">; a sequence.</font></span><br /><span><font color="#786000">; (= (__ '(1 2 3 3 1)) 5)</font></span><br /><span><font color="#786000">; forbidden: count</font></span><br /><span><font color="#912f11">#(</font></span><span><font color="#1f3f81"><strong>reduce</strong></font></span> <span><font color="#007080">+</font></span> <span><font color="#912f11">(</font></span><span><font color="#1f3f81"><strong>map</strong></font></span> <font color="#cd3700">(</font><span><font color="#912f11">fn</font></span> <span><font color="#912f11">[</font></span>x<span><font color="#912f11">]</font></span> <span><font color="#077807">1</font></span><font color="#cd3700">)</font> %<span><font color="#912f11">))</font></span><br /><span><font color="#786000">; We just turn each element into 1 and then add them up</font></span><br /><span><font color="#786000">; Note that (fn [x] 1) can be replaced by (constantly 1)</font></span></font></div> <div class="codeblock"> </div> <div class="codeblock"> <font face="monospace"><span><font color="#786000">; 23: Write a function which reverses a sequence.</font></span><br /><span><font color="#786000">; (= (__ [1 2 3 4 5]) [5 4 3 2 1])</font></span><br /><span><font color="#786000">; forbidden: reverse</font></span><br /><span><font color="#912f11">#(</font></span><span><font color="#007080">into</font></span> <span><font color="#912f11">()</font></span> <span><font color="#912f11">%</font></span><span><font color="#912f11">)</font></span><br /><span><font color="#786000">; We exploit the property of the list, which alway add new element </font></span><br /><span><font color="#786000">; in front of the head. Also that the clojure sequences' equality</font></span><br /><span><font color="#786000">; evaluation is element based, so [1 2 3] equals to '(1 2 3)</font></span></font></div> <div class="codeblock"> </div> <div class="codeblock"> <font face="monospace"><span><font color="#786000">; 26: Write a function which returns the first X fibonacci numbers.</font></span><br /><span><font color="#786000">; (= (__ 6) '(1 1 2 3 5 8))</font></span><br /><span><font color="#912f11">(</font></span><span><font color="#912f11">fn</font></span> <span><font color="#912f11">[</font></span>x<span><font color="#912f11">]</font></span><br />   <font color="#cd3700">(</font><span><font color="#007080">take</font></span> x<br />     <font color="#ee9a00">(</font><font color="#cdcd00">(</font><span><font color="#912f11">fn</font></span> fib <span><font color="#912f11">[</font></span>a b<span><font color="#912f11">]</font></span><br />         <font color="#698b22">(</font><span><font color="#007080">cons</font></span> a <font color="#008b00">(</font><span><font color="#800090">lazy-seq</font></span> <font color="#96cdcd">(</font>fib b <font color="#00688b">(</font><span><font color="#007080">+</font></span> a b<font color="#00688b">)</font><font color="#96cdcd">)</font><font color="#008b00">)</font><font color="#698b22">)</font><font color="#cdcd00">)</font> <br />       <span><font color="#077807">1</font></span> <span><font color="#077807">1</font></span><font color="#ee9a00">)</font><font color="#cd3700">)</font><span><font color="#912f11">)</font></span> <br /><span><font color="#786000">; we first recursively construct a lazy sequence of infinite number of </font></span><br /><span><font color="#786000">; fibonacci numbers</font></span></font></div> <div class="codeblock"> </div> <div class="codeblock"> <font face="monospace"><span><font color="#786000">; 27: Write a function which returns true if the given sequence is</font></span></font></div> <div class="codeblock"><font face="monospace"><span><font color="#786000">; a palindrome.</font></span><br /><span><font color="#786000">; (true? (__ '(1 1 3 3 1 1))) </font></span><br /><span><font color="#912f11">(</font></span><span><font color="#912f11">fn</font></span> <span><font color="#912f11">[</font></span>coll<span><font color="#912f11">]</font></span><br />   <font color="#cd3700">(</font><span><font color="#912f11">let</font></span> <span><font color="#912f11">[</font></span>rc <span><font color="#912f11">(</font></span><span><font color="#007080">reverse</font></span> coll<span><font color="#912f11">)</font></span> n <span><font color="#912f11">(</font></span><span><font color="#007080">count</font></span> coll<span><font color="#912f11">)]</font></span><br />     <font color="#ee9a00">(</font><span><font color="#007080">every?</font></span> <span><font color="#007080">identity</font></span> <br />       <font color="#cdcd00">(</font><span><font color="#1f3f81"><strong>map</strong></font></span> <span><font color="#912f11">#(</font></span><span><font color="#007080">=</font></span> <span><font color="#912f11">(</font></span><span><font color="#007080">nth</font></span> coll %<span><font color="#912f11">)</font></span> <span><font color="#912f11">(</font></span><span><font color="#007080">nth</font></span> rc %<span><font color="#912f11">))</font></span> <font color="#698b22">(</font><span><font color="#007080">range</font></span> <font color="#008b00">(</font><span><font color="#007080">/</font></span> <font color="#96cdcd">(</font><span><font color="#007080">dec</font></span> n<font color="#96cdcd">)</font> <span><font color="#077807">2</font></span><font color="#008b00">)</font><font color="#698b22">)</font><font color="#cdcd00">)</font><font color="#ee9a00">)</font><font color="#cd3700">)</font><span><font color="#912f11">)</font></span><br /><span><font color="#786000">; we naively compare half of the pairs of elment e(i) and e(n-i-1)</font></span></font></div> <div class="codeblock"> </div> <div class="codeblock"> <font face="monospace"><span><font color="#786000">; 28: Write a function which flattens a sequence.</font></span><br /><span><font color="#786000">; (= (__ '((1 2) 3 [4 [5 6]])) '(1 2 3 4 5 6)) </font></span><br /><span><font color="#786000">; forbidden: flatten</font></span><br /><span><font color="#912f11">(</font></span><span><font color="#912f11">fn</font></span> flt <span><font color="#912f11">[</font></span>coll<span><font color="#912f11">]</font></span><br />   <font color="#cd3700">(</font><span><font color="#912f11">let</font></span> <span><font color="#912f11">[</font></span>l <span><font color="#912f11">(</font></span><span><font color="#007080">first</font></span> coll<span><font color="#912f11">)</font></span> r <span><font color="#912f11">(</font></span><span><font color="#007080">next</font></span> coll<span><font color="#912f11">)]</font></span><br />     <font color="#ee9a00">(</font><span><font color="#007080">concat</font></span> <br />       <font color="#cdcd00">(</font><span><font color="#912f11">if</font></span> <font color="#698b22">(</font><span><font color="#007080">sequential?</font></span> l<font color="#698b22">)</font><br />         <font color="#698b22">(</font>flt l<font color="#698b22">)</font><br />         <span><font color="#912f11">[</font></span>l<span><font color="#912f11">]</font></span><font color="#cdcd00">)</font><br />       <font color="#cdcd00">(</font><span><font color="#1f3f81"><strong>when</strong></font></span> <font color="#698b22">(</font><span><font color="#007080">sequential?</font></span> r<font color="#698b22">)</font><br />         <font color="#698b22">(</font>flt r<font color="#698b22">)</font><font color="#cdcd00">)</font><font color="#ee9a00">)</font><font color="#cd3700">)</font><span><font color="#912f11">)</font></span><br /><span><font color="#786000">; we basically treat the nested collection as a tree and recursively </font></span></font></div> <div class="codeblock"><font face="monospace"><span><font color="#786000">; walk the </font></span><span><font color="#786000">tree. Clojure's flatten use a tree-seq to walk the tree.</font></span></font></div> <div class="codeblock"> </div> <div class="codeblock"> <font face="monospace"><span><font color="#786000">; 29: Write a function which takes a string and returns a new </font></span></font></div> <div class="codeblock"><font face="monospace"><span><font color="#786000">; string containing</font></span><span><font color="#786000"> only the capital letters.</font></span><br /><span><font color="#786000">; (= (__ "HeLlO, WoRlD!") "HLOWRD")    </font></span><br /><span><font color="#912f11">(</font></span><span><font color="#912f11">fn</font></span> <span><font color="#912f11">[</font></span>coll<span><font color="#912f11">]</font></span><br />   <font color="#cd3700">(</font><span><font color="#007080">apply</font></span> <span><font color="#007080">str</font></span> <font color="#ee9a00">(</font><span><font color="#1f3f81"><strong>filter</strong></font></span> <span><font color="#912f11">#(</font></span>Character/isUpperCase <span><font color="#912f11">%</font></span><span><font color="#912f11">)</font></span> coll<font color="#ee9a00">)</font><font color="#cd3700">)</font><span><font color="#912f11">)</font></span><br /><span><font color="#786000">; note the use of apply here, as str takes a number of args instead</font></span><br /><span><font color="#786000">; of a character collection</font></span></font></div> <div class="codeblock"> </div> <div class="codeblock"> <font face="monospace"><span><font color="#786000">; 30: Write a function which removes consecutive duplicates from a sequence.</font></span><br /><span><font color="#786000">;  (= (apply str (__ "Leeeeeerrroyyy")) "Leroy")</font></span><br /><span><font color="#912f11">(</font></span><span><font color="#912f11">fn</font></span> cmprs <span><font color="#912f11">[</font></span>coll<span><font color="#912f11">]</font></span><br />   <font color="#cd3700">(</font><span><font color="#1f3f81"><strong>when-let</strong></font></span> <span><font color="#912f11">[[</font></span>f <span><font color="#912f11">&amp;</font></span> r<span><font color="#912f11">]</font></span> <span><font color="#912f11">(</font></span><span><font color="#007080">seq</font></span> coll<span><font color="#912f11">)]</font></span> <br />     <font color="#ee9a00">(</font><span><font color="#912f11">if</font></span> <font color="#cdcd00">(</font><span><font color="#007080">=</font></span> f <font color="#698b22">(</font><span><font color="#007080">first</font></span> r<font color="#698b22">)</font><font color="#cdcd00">)</font> <br />       <font color="#cdcd00">(</font>cmprs r<font color="#cdcd00">)</font> <br />       <font color="#cdcd00">(</font><span><font color="#007080">cons</font></span> f <font color="#698b22">(</font>cmprs r<font color="#698b22">)</font><font color="#cdcd00">)</font><font color="#ee9a00">)</font><font color="#cd3700">)</font><span><font color="#912f11">)</font></span>  <br /><span><font color="#786000">; Basically a variant of the filter function. Note the sequence </font></span></font></div> <div class="codeblock"><font face="monospace"><span><font color="#786000">; is destructed</font></span><span><font color="#786000"> into first element f and the rest r. </font></span> <p><span><font color="#786000">; 31: Write a function which packs consecutive duplicates into sub-lists.</font></span><br /><span><font color="#786000">; (= (__ [1 1 2 1 1 1 3 3]) '((1 1) (2) (1 1 1) (3 3)))</font></span><br /><span><font color="#912f11">(</font></span><span><font color="#912f11">fn</font></span> <span><font color="#912f11">[</font></span>coll<span><font color="#912f11">]</font></span><br />   <font color="#cd3700">(</font><font color="#ee9a00">(</font><span><font color="#912f11">fn</font></span> pack <span><font color="#912f11">[</font></span>res prev coll<span><font color="#912f11">]</font></span><br />     <font color="#cdcd00">(</font><span><font color="#1f3f81"><strong>if-let</strong></font></span> <span><font color="#912f11">[[</font></span>f <span><font color="#912f11">&amp;</font></span> r<span><font color="#912f11">]</font></span> <span><font color="#912f11">(</font></span><span><font color="#007080">seq</font></span> coll<span><font color="#912f11">)]</font></span> <br />       <font color="#698b22">(</font><span><font color="#912f11">if</font></span> <font color="#008b00">(</font><span><font color="#007080">=</font></span> f <font color="#96cdcd">(</font><span><font color="#007080">first</font></span> prev<font color="#96cdcd">)</font><font color="#008b00">)</font> <br />         <font color="#008b00">(</font>pack res <font color="#96cdcd">(</font><span><font color="#007080">conj</font></span> prev f<font color="#96cdcd">)</font> r<font color="#008b00">)</font> <br />         <font color="#008b00">(</font>pack <font color="#96cdcd">(</font><span><font color="#007080">conj</font></span> res prev<font color="#96cdcd">)</font> <span><font color="#912f11">[</font></span>f<span><font color="#912f11">]</font></span> r<font color="#008b00">)</font><font color="#698b22">)</font><font color="#cdcd00">)</font> <br />      <font color="#cdcd00">(</font><span><font color="#007080">conj</font></span> res prev<font color="#cdcd00">)</font><font color="#ee9a00">)</font><br />     <span><font color="#912f11">[]</font></span> <span><font color="#912f11">[(</font></span><span><font color="#007080">first</font></span> coll<span><font color="#912f11">)]</font></span> <font color="#ee9a00">(</font><span><font color="#007080">rest</font></span> coll<font color="#ee9a00">)</font><font color="#cd3700">)</font><span><font color="#912f11">)</font></span>  <br /><span><font color="#786000">; res is the final list, prev keeps the immediate previous sub-list. </font></span><br /><span><font color="#786000">; A much simpler version use partition-by:</font></span><br /><span><font color="#912f11">#(</font></span><span><font color="#007080">partition-by</font></span> <span><font color="#007080">identity</font></span> <span><font color="#912f11">%</font></span><span><font color="#912f11">)</font></span></p> <p><span><font color="#786000">; 33: Write a function which replicates each element of a sequence </font></span></p></font></div> <div class="codeblock"><font face="monospace"><span><font color="#786000">; n number of </font></span><span><font color="#786000">times.</font></span><br /><span><font color="#786000">; (= (__ [1 2 3] 2) '(1 1 2 2 3 3)) </font></span><br /><span><font color="#912f11">(</font></span><span><font color="#912f11">fn</font></span> <span><font color="#912f11">[</font></span>coll n<span><font color="#912f11">]</font></span><br />   <font color="#cd3700">(</font><span><font color="#007080">apply</font></span> <span><font color="#007080">concat</font></span> <font color="#ee9a00">(</font><span><font color="#1f3f81"><strong>map</strong></font></span> <span><font color="#912f11">#(</font></span><span><font color="#007080">repeat</font></span> n <span><font color="#912f11">%</font></span><span><font color="#912f11">)</font></span> coll<font color="#ee9a00">)</font><font color="#cd3700">)</font><span><font color="#912f11">)</font></span><br /><span><font color="#786000">; or more succintly: </font></span><br /><span><font color="#912f11">(</font></span><span><font color="#912f11">fn</font></span> <span><font color="#912f11">[</font></span>coll n<span><font color="#912f11">]</font></span><br />   <font color="#cd3700">(</font><span><font color="#1f3f81"><strong>mapcat</strong></font></span> <span><font color="#912f11">#(</font></span><span><font color="#007080">repeat</font></span> n <span><font color="#912f11">%</font></span><span><font color="#912f11">)</font></span> coll<font color="#cd3700">)</font><span><font color="#912f11">)</font></span> <p><span><font color="#786000">; 34: Write a function which creates a list of all integers in a </font></span></p></font></div> <div class="codeblock"><font face="monospace"><span><font color="#786000">; given range. </font></span><br /><span><font color="#786000">; (= (__ 1 4) '(1 2 3))</font></span><br /><span><font color="#786000">; forbidden: range</font></span><br /><span><font color="#912f11">(</font></span><span><font color="#912f11">fn</font></span> <span><font color="#912f11">[</font></span>s e<span><font color="#912f11">]</font></span><br />   <font color="#cd3700">(</font><span><font color="#007080">take</font></span> <font color="#ee9a00">(</font><span><font color="#007080">-</font></span> e s<font color="#ee9a00">)</font> <font color="#ee9a00">(</font><span><font color="#007080">iterate</font></span> <span><font color="#007080">inc</font></span> s<font color="#ee9a00">)</font><font color="#cd3700">)</font><span><font color="#912f11">)</font></span> <p><span><font color="#786000">; 38: Write a function which takes a variable number of parameters </font></span></p></font></div> <div class="codeblock"><font face="monospace"><span><font color="#786000">; and returns </font></span><span><font color="#786000">the maximum value.</font></span><br /><span><font color="#786000">; forbidden: max, max-key</font></span><br /><span><font color="#786000">; (= (__ 1 8 3 4) 8)</font></span><br /><span><font color="#912f11">(</font></span><span><font color="#912f11">fn</font></span> <span><font color="#912f11">[</font></span>x <span><font color="#912f11">&amp;</font></span> xs<span><font color="#912f11">]</font></span><br />   <font color="#cd3700">(</font><span><font color="#1f3f81"><strong>reduce</strong></font></span> <span><font color="#912f11">#(</font></span><span><font color="#912f11">if</font></span> <span><font color="#912f11">(</font></span><span><font color="#007080">&lt;</font></span> %<span><font color="#077807">1</font></span> %<span><font color="#077807">2</font></span><span><font color="#912f11">)</font></span> <span><font color="#912f11">%2</font></span> <span><font color="#912f11">%1</font></span><span><font color="#912f11">)</font></span> x xs<font color="#cd3700">)</font><span><font color="#912f11">)</font></span> <p><span><font color="#786000">; 39: Write a function which takes two sequences and returns the first</font></span></p></font></div> <div class="codeblock"><font face="monospace"><span><font color="#786000">; item </font></span><span><font color="#786000">from each, then the second item from each, then the third, etc.</font></span><br /><span><font color="#786000">; (= (__ [1 2] [3 4 5 6]) '(1 3 2 4))</font></span><br /><span><font color="#786000">; forbidden: interleave</font></span><br /><span><font color="#912f11">#(</font></span><span><font color="#1f3f81"><strong>mapcat</strong></font></span> <span><font color="#007080">vector</font></span> <span><font color="#912f11">%1</font></span> <span><font color="#912f11">%2</font></span><span><font color="#912f11">)</font></span>  <p><span><font color="#786000">; 40: Write a function which separates the items of a sequence by </font></span></p></font></div> <div class="codeblock"><font face="monospace"><span><font color="#786000">; an arbitrary </font></span><span><font color="#786000">value.</font></span><br /><span><font color="#786000">; (= (__ 0 [1 2 3]) [1 0 2 0 3])</font></span><br /><span><font color="#786000">; forbidden: interpose</font></span><br /><span><font color="#912f11">(</font></span><span><font color="#912f11">fn</font></span> <span><font color="#912f11">[</font></span>sep coll<span><font color="#912f11">]</font></span><br />   <font color="#cd3700">(</font><span><font color="#007080">drop-last</font></span> <font color="#ee9a00">(</font><span><font color="#1f3f81"><strong>mapcat</strong></font></span> <span><font color="#007080">vector</font></span> coll <font color="#cdcd00">(</font><span><font color="#007080">repeat</font></span> sep<font color="#cdcd00">)</font><font color="#ee9a00">)</font><font color="#cd3700">)</font><span><font color="#912f11">)</font></span> <p><span><font color="#786000">; 41: Write a function which drops every Nth item from a sequence.</font></span><br /><span><font color="#786000">; (= (__ [1 2 3 4 5 6 7 8] 3) [1 2 4 5 7 8])  </font></span><br /><span><font color="#912f11">(</font></span><span><font color="#912f11">fn</font></span> <span><font color="#912f11">[</font></span>coll n<span><font color="#912f11">]</font></span><br />   <font color="#cd3700">(</font><span><font color="#007080">flatten</font></span> <br />     <font color="#ee9a00">(</font><span><font color="#007080">concat</font></span> <br />       <font color="#cdcd00">(</font><span><font color="#1f3f81"><strong>map</strong></font></span> <span><font color="#912f11">#(</font></span><span><font color="#007080">drop-last</font></span> <span><font color="#912f11">%</font></span><span><font color="#912f11">)</font></span> <font color="#698b22">(</font><span><font color="#007080">partition</font></span> n coll<font color="#698b22">)</font><font color="#cdcd00">)</font> <br />       <font color="#cdcd00">(</font><span><font color="#007080">take-last</font></span> <font color="#698b22">(</font><span><font color="#007080">rem</font></span> <font color="#008b00">(</font><span><font color="#007080">count</font></span> coll<font color="#008b00">)</font> n<font color="#698b22">)</font> coll<font color="#cdcd00">)</font><font color="#ee9a00">)</font><font color="#cd3700">)</font><span><font color="#912f11">)</font></span><br /><span><font color="#786000">; We partition the sequence, drop last one from each, then stitch them</font></span></p></font></div> <div class="codeblock"><font face="monospace"><span><font color="#786000">; back</font></span><span><font color="#786000"> take care the remaining elements too</font></span> <p><span><font color="#786000">; 42: Write a function which calculates factorials.</font></span><br /><span><font color="#786000">; (= (__ 5) 120)</font></span><br /><span><font color="#912f11">(</font></span><span><font color="#912f11">fn</font></span> <span><font color="#912f11">[</font></span>n<span><font color="#912f11">]</font></span><br />   <font color="#cd3700">(</font><span><font color="#007080">apply</font></span> <span><font color="#007080">*</font></span> <font color="#ee9a00">(</font><span><font color="#007080">range</font></span> <span><font color="#077807">1</font></span> <font color="#cdcd00">(</font><span><font color="#007080">inc</font></span> n<font color="#cdcd00">)</font><font color="#ee9a00">)</font><font color="#cd3700">)</font><span><font color="#912f11">)</font></span><br /><span><font color="#786000">; clojure arithmetic functions can take a variable number of arguments</font></span></p> <p><span><font color="#786000">; 43: Write a function which reverses the interleave process into n </font></span></p></font></div> <div class="codeblock"><font face="monospace"><span><font color="#786000">; number of </font></span><span><font color="#786000">subsequences.</font></span><br /><span><font color="#786000">; (= (__ [1 2 3 4 5 6] 2) '((1 3 5) (2 4 6)))</font></span><br /><span><font color="#912f11">(</font></span><span><font color="#912f11">fn</font></span> <span><font color="#912f11">[</font></span>coll n<span><font color="#912f11">]</font></span><br />   <font color="#cd3700">(</font><span><font color="#007080">apply</font></span> <span><font color="#1f3f81"><strong>map</strong></font></span> <span><font color="#007080">list</font></span> <font color="#ee9a00">(</font><span><font color="#007080">partition</font></span> n coll<font color="#ee9a00">)</font><font color="#cd3700">)</font><span><font color="#912f11">)</font></span><br /><span><font color="#786000">; exploit map function's ability to take a variable number of </font></span></font></div> <div class="codeblock"><font face="monospace"><span><font color="#786000">; collections as </font></span><span><font color="#786000">arguments</font></span> <p><span><font color="#786000">; 44: Write a function which can rotate a sequence in either direction.</font></span><br /><span><font color="#786000">; (= (__ 2 [1 2 3 4 5]) '(3 4 5 1 2))</font></span><br /><span><font color="#786000">; (= (__ -2 [1 2 3 4 5]) '(4 5 1 2 3))</font></span><br /><span><font color="#912f11">(</font></span><span><font color="#912f11">fn</font></span> <span><font color="#912f11">[</font></span>n coll<span><font color="#912f11">]</font></span><br />   <font color="#cd3700">(</font><span><font color="#912f11">let</font></span> <span><font color="#912f11">[</font></span>ntime <span><font color="#912f11">(</font></span><span><font color="#912f11">if</font></span> <font color="#cd3700">(</font><span><font color="#007080">neg?</font></span> n<font color="#cd3700">)</font> <font color="#cd3700">(</font><span><font color="#007080">-</font></span> n<font color="#cd3700">)</font> n<span><font color="#912f11">)</font></span><br />         lshift <span><font color="#912f11">#(</font></span><span><font color="#007080">concat</font></span> <span><font color="#912f11">(</font></span><span><font color="#007080">rest</font></span> %<span><font color="#912f11">)</font></span> <span><font color="#912f11">[(</font></span><span><font color="#007080">first</font></span> %<span><font color="#912f11">)])</font></span><br />         rshift <span><font color="#912f11">#(</font></span><span><font color="#007080">cons</font></span> <span><font color="#912f11">(</font></span><span><font color="#007080">last</font></span> %<span><font color="#912f11">)</font></span> <span><font color="#912f11">(</font></span><span><font color="#007080">drop-last</font></span> %<span><font color="#912f11">))]</font></span><br />     <font color="#ee9a00">(</font><font color="#cdcd00">(</font><span><font color="#007080">apply</font></span> <span><font color="#007080">comp</font></span> <font color="#698b22">(</font><span><font color="#007080">repeat</font></span> ntime <font color="#008b00">(</font><span><font color="#912f11">if</font></span> <font color="#96cdcd">(</font><span><font color="#007080">neg?</font></span> n<font color="#96cdcd">)</font> rshift lshift<font color="#008b00">)</font><font color="#698b22">)</font><font color="#cdcd00">)</font> coll<font color="#ee9a00">)</font><font color="#cd3700">)</font><span><font color="#912f11">)</font></span></p> <p><span><font color="#786000">; 50: Write a function which takes a sequence consisting of items </font></span></p></font></div> <div class="codeblock"><font face="monospace"><span><font color="#786000">; with different</font></span><span><font color="#786000"> types and splits them up into a set of homogeneous </font></span></font></div> <div class="codeblock"><font face="monospace"><span><font color="#786000">; sub-sequences. The internal</font></span><span><font color="#786000"> order of each sub-sequence should be </font></span></font></div> <div class="codeblock"><font face="monospace"><span><font color="#786000">; maintained, but the sub-sequences </font></span><span><font color="#786000">themselves can be returned in </font></span></font></div> <div class="codeblock"><font face="monospace"><span><font color="#786000">; any order (this is why 'set' is used in the </font></span><span><font color="#786000">test cases).</font></span><br /><span><font color="#786000">; (= (set (__ [1 :a 2 :b 3 :c])) #{[1 2 3] [:a :b :c]})</font></span><br /><span><font color="#912f11">#(</font></span><span><font color="#007080">vals</font></span> <span><font color="#912f11">(</font></span><span><font color="#007080">group-by</font></span> <span><font color="#007080">type</font></span> %<span><font color="#912f11">))</font></span></font></div> <div class="codeblock"> </div> <div class="codeblock"> </div> </div></div> <ul class="links inline"><li class="comment-add"><a href="/blog/2011/05/my-solutions-first-50-problems-4clojure-com#comment-form" title="Share your thoughts and opinions." hreflang="und">Add new comment</a></li></ul><section> <a id="comment-3"></a> <article data-comment-user-id="0" class="js-comment comment"> <mark class="hidden" data-comment-timestamp="1312243846"></mark> <footer class="attribution"> <article typeof="schema:Person" about="/user/0"> <div class="field field--name-user-picture field--type-image field--label-hidden field__item"> <img src="/sites/default/files/styles/thumbnail/public/default_images/default-user-image.png?itok=hWWOuuKw" width="100" height="100" alt="Profile picture for user Nik" title="Anonymous user" typeof="foaf:Image" /> </div> </article> <div class="comment-submitted"> <p class="commenter-name"> <span lang="" typeof="schema:Person" property="schema:name" datatype="">Bob Shock</span> </p> <p class="comment-time"> Tue, 08/02/2011 - 01:10 </p> </div> </footer> <div class="comment-text"> <div class="comment-arrow"></div> <h3><a href="/comment/3#comment-3" class="permalink" rel="bookmark" hreflang="en">Problem 44</a></h3> <div class="content"> <div class="field field--name-comment-body field--type-text-long field--label-hidden field__item"><div class="tex2jax_process"><p>I struggled with that one a lot. My first solution was about twice as long as yours. Then I figured out it was simply a matter of splitting the collection in half at the right place, then joining the two pieces back together in the opposite order.</p> <p><code></code></p> <p>#(let [<br /> [l r] (split-at (mod % (count %2)) %2)]<br /> (concat r l))</p> <p></p> </div></div> <drupal-render-placeholder callback="comment.lazy_builders:renderLinks" arguments="0=3&amp;1=default&amp;2=en&amp;3=" token="0OyyOQQqaGvdq26UA1cWNzmOvoFjuLoAqp4RXqYk6XA"></drupal-render-placeholder> </div> </div> </article> <div class="indented"><a id="comment-4"></a> <article data-comment-user-id="1" class="js-comment comment"> <mark class="hidden" data-comment-timestamp="1312268280"></mark> <footer class="attribution"> <article typeof="schema:Person" about="/user/huahai"> <div class="field field--name-user-picture field--type-image field--label-hidden field__item"> <img src="/sites/default/files/styles/thumbnail/public/pictures/2017-11/huahai.jpg?itok=ZwjJWYAc" width="88" height="100" alt="Profile picture for user Huahai" typeof="foaf:Image" /> </div> </article> <div class="comment-submitted"> <p class="commenter-name"> <a title="View user profile." href="/user/huahai" lang="" about="/user/huahai" typeof="schema:Person" property="schema:name" datatype="">Huahai</a> </p> <p class="comment-time"> Tue, 08/02/2011 - 07:58 </p> </div> <p class="visually-hidden">In reply to <a href="/comment/3#comment-3" class="permalink" rel="bookmark" hreflang="en">Problem 44</a> by <span lang="" typeof="schema:Person" property="schema:name" datatype="">Bob Shock</span></p> </footer> <div class="comment-text"> <div class="comment-arrow"></div> <h3><a href="/comment/4#comment-4" class="permalink" rel="bookmark" hreflang="en">very nice</a></h3> <div class="content"> <div class="field field--name-comment-body field--type-text-long field--label-hidden field__item"><div class="tex2jax_process"><p>Yours is short and sweet. I didn't think in that way. split-at is good to know too. Thank a lot.</p> </div></div> <drupal-render-placeholder callback="comment.lazy_builders:renderLinks" arguments="0=4&amp;1=default&amp;2=en&amp;3=" token="XOtoOEajTmGO-ySbCbuuJ-3RWGWOq9TFLYj6XhVpmVk"></drupal-render-placeholder> </div> </div> </article> </div><a id="comment-24"></a> <article data-comment-user-id="0" class="js-comment comment"> <mark class="hidden" data-comment-timestamp="1313447514"></mark> <footer class="attribution"> <article typeof="schema:Person" about="/user/0"> <div class="field field--name-user-picture field--type-image field--label-hidden field__item"> <img src="/sites/default/files/styles/thumbnail/public/default_images/default-user-image.png?itok=hWWOuuKw" width="100" height="100" alt="Profile picture for user Nik" title="Anonymous user" typeof="foaf:Image" /> </div> </article> <div class="comment-submitted"> <p class="commenter-name"> <a rel="nofollow" href="http://citizen428.net" lang="" typeof="schema:Person" property="schema:name" datatype="">citizen428</a> </p> <p class="comment-time"> Mon, 08/15/2011 - 23:31 </p> </div> </footer> <div class="comment-text"> <div class="comment-arrow"></div> <h3><a href="/comment/24#comment-24" class="permalink" rel="bookmark" hreflang="en">The solution to problem 21</a></h3> <div class="content"> <div class="field field--name-comment-body field--type-text-long field--label-hidden field__item"><div class="tex2jax_process"><p>The solution to problem 21 seems a bit too complicated:</p> <p><code>(fn [coll n] (first (drop n coll)))</code></p> </div></div> <drupal-render-placeholder callback="comment.lazy_builders:renderLinks" arguments="0=24&amp;1=default&amp;2=en&amp;3=" token="Y0HrI9yD7LjoeB0ikoxwOJbC_PCRB8j86_jHY_zw1Fw"></drupal-render-placeholder> </div> </div> </article> <div class="indented"><a id="comment-25"></a> <article data-comment-user-id="1" class="js-comment comment"> <mark class="hidden" data-comment-timestamp="1313613032"></mark> <footer class="attribution"> <article typeof="schema:Person" about="/user/huahai"> <div class="field field--name-user-picture field--type-image field--label-hidden field__item"> <img src="/sites/default/files/styles/thumbnail/public/pictures/2017-11/huahai.jpg?itok=ZwjJWYAc" width="88" height="100" alt="Profile picture for user Huahai" typeof="foaf:Image" /> </div> </article> <div class="comment-submitted"> <p class="commenter-name"> <a title="View user profile." href="/user/huahai" lang="" about="/user/huahai" typeof="schema:Person" property="schema:name" datatype="">Huahai</a> </p> <p class="comment-time"> Wed, 08/17/2011 - 21:30 </p> </div> <p class="visually-hidden">In reply to <a href="/comment/24#comment-24" class="permalink" rel="bookmark" hreflang="en">The solution to problem 21</a> by <a rel="nofollow" href="http://citizen428.net" lang="" typeof="schema:Person" property="schema:name" datatype="">citizen428</a></p> </footer> <div class="comment-text"> <div class="comment-arrow"></div> <h3><a href="/comment/25#comment-25" class="permalink" rel="bookmark" hreflang="en">agreed</a></h3> <div class="content"> <div class="field field--name-comment-body field--type-text-long field--label-hidden field__item"><div class="tex2jax_process"><p>You are right, that solution is too complicated. When I wrote that, I had not been used to the functional way of thinking, which is more high level and declarative. As you can see, that solution was still trying to do things sequentially, basically trying to do a loop by function composition. Your solution is more declarative: just drops the last n elements and does not care about how they are dropped.</p> <p>Another lesson is that one really needs to get acquainted with <a href="http://clojure.org/sequences">seq library of Clojure</a>. I did not know about the drop function when I wrote my solution.</p> <p>Thanks for sharing your solution. I appreciate it. <br><br></p> </div></div> <drupal-render-placeholder callback="comment.lazy_builders:renderLinks" arguments="0=25&amp;1=default&amp;2=en&amp;3=" token="qem1Dc2wrT4twn13D1hSVNT8keaYj3Io-NP0vJGKzsI"></drupal-render-placeholder> </div> </div> </article> </div><a id="comment-29"></a> <article data-comment-user-id="0" class="js-comment comment"> <mark class="hidden" data-comment-timestamp="1314741476"></mark> <footer class="attribution"> <article typeof="schema:Person" about="/user/0"> <div class="field field--name-user-picture field--type-image field--label-hidden field__item"> <img src="/sites/default/files/styles/thumbnail/public/default_images/default-user-image.png?itok=hWWOuuKw" width="100" height="100" alt="Profile picture for user Nik" title="Anonymous user" typeof="foaf:Image" /> </div> </article> <div class="comment-submitted"> <p class="commenter-name"> <span lang="" typeof="schema:Person" property="schema:name" datatype="">x_rex</span> </p> <p class="comment-time"> Tue, 08/30/2011 - 22:57 </p> </div> </footer> <div class="comment-text"> <div class="comment-arrow"></div> <h3><a href="/comment/29#comment-29" class="permalink" rel="bookmark" hreflang="en">Problem 27</a></h3> <div class="content"> <div class="field field--name-comment-body field--type-text-long field--label-hidden field__item"><div class="tex2jax_process"><p>Solution to the problem 27 is as simple as:<br /> #(= (seq %) (reverse %))</p> </div></div> <drupal-render-placeholder callback="comment.lazy_builders:renderLinks" arguments="0=29&amp;1=default&amp;2=en&amp;3=" token="4n4ptbBP0AliduNAuNHQiAPytAHPtuJgZKkRRToI18o"></drupal-render-placeholder> </div> </div> </article> <div class="indented"><a id="comment-30"></a> <article data-comment-user-id="1" class="js-comment comment"> <mark class="hidden" data-comment-timestamp="1314763416"></mark> <footer class="attribution"> <article typeof="schema:Person" about="/user/huahai"> <div class="field field--name-user-picture field--type-image field--label-hidden field__item"> <img src="/sites/default/files/styles/thumbnail/public/pictures/2017-11/huahai.jpg?itok=ZwjJWYAc" width="88" height="100" alt="Profile picture for user Huahai" typeof="foaf:Image" /> </div> </article> <div class="comment-submitted"> <p class="commenter-name"> <a title="View user profile." href="/user/huahai" lang="" about="/user/huahai" typeof="schema:Person" property="schema:name" datatype="">Huahai</a> </p> <p class="comment-time"> Wed, 08/31/2011 - 05:03 </p> </div> <p class="visually-hidden">In reply to <a href="/comment/29#comment-29" class="permalink" rel="bookmark" hreflang="en">Problem 27</a> by <span lang="" typeof="schema:Person" property="schema:name" datatype="">x_rex</span></p> </footer> <div class="comment-text"> <div class="comment-arrow"></div> <h3><a href="/comment/30#comment-30" class="permalink" rel="bookmark" hreflang="en">Good one</a></h3> <div class="content"> <div class="field field--name-comment-body field--type-text-long field--label-hidden field__item"><div class="tex2jax_process"><p>This is a nice example of the difference between functional and imperative thinking. Here the thinking is on the collection level, &nbsp;not element-wise comparison, like an imperative programmer would do. &nbsp;I guess it takes a lot to unlearn twenty years of imperative programming&nbsp;<img src="/sites/all/libraries/tinymce/jscripts/tiny_mce/plugins/emotions/img/smiley-smile.gif" alt="Smile" title="Smile" border="0"></p> </div></div> <drupal-render-placeholder callback="comment.lazy_builders:renderLinks" arguments="0=30&amp;1=default&amp;2=en&amp;3=" token="7KamS9md4nLnx4i124hsbdFI0Dngd3yFy624fpC9VIY"></drupal-render-placeholder> </div> </div> </article> </div><a id="comment-31"></a> <article data-comment-user-id="0" class="js-comment comment"> <mark class="hidden" data-comment-timestamp="1315589298"></mark> <footer class="attribution"> <article typeof="schema:Person" about="/user/0"> <div class="field field--name-user-picture field--type-image field--label-hidden field__item"> <img src="/sites/default/files/styles/thumbnail/public/default_images/default-user-image.png?itok=hWWOuuKw" width="100" height="100" alt="Profile picture for user Nik" title="Anonymous user" typeof="foaf:Image" /> </div> </article> <div class="comment-submitted"> <p class="commenter-name"> <span lang="" typeof="schema:Person" property="schema:name" datatype="">bjc</span> </p> <p class="comment-time"> Fri, 09/09/2011 - 18:28 </p> </div> </footer> <div class="comment-text"> <div class="comment-arrow"></div> <h3><a href="/comment/31#comment-31" class="permalink" rel="bookmark" hreflang="en">I wish they would put some of these up alongside the problems</a></h3> <div class="content"> <div class="field field--name-comment-body field--type-text-long field--label-hidden field__item"><div class="tex2jax_process"><p>I really love how elegantly you have solved these solutions, far better than my attempts (the functional way of thinking still makes my brain hurt) Thanks for taking the time to document your thought processes along with the problems. I've found it more useful than reading documentation as the problem domain is more succinct.</p> <p>Thanks!</p> </div></div> <drupal-render-placeholder callback="comment.lazy_builders:renderLinks" arguments="0=31&amp;1=default&amp;2=en&amp;3=" token="TfcTym3RFCv7pWBG63bLKLLzNEB5pc2ByBwJiCZUDr4"></drupal-render-placeholder> </div> </div> </article> <div class="indented"><a id="comment-32"></a> <article data-comment-user-id="1" class="js-comment comment"> <mark class="hidden" data-comment-timestamp="1315860826"></mark> <footer class="attribution"> <article typeof="schema:Person" about="/user/huahai"> <div class="field field--name-user-picture field--type-image field--label-hidden field__item"> <img src="/sites/default/files/styles/thumbnail/public/pictures/2017-11/huahai.jpg?itok=ZwjJWYAc" width="88" height="100" alt="Profile picture for user Huahai" typeof="foaf:Image" /> </div> </article> <div class="comment-submitted"> <p class="commenter-name"> <a title="View user profile." href="/user/huahai" lang="" about="/user/huahai" typeof="schema:Person" property="schema:name" datatype="">Huahai</a> </p> <p class="comment-time"> Mon, 09/12/2011 - 21:53 </p> </div> <p class="visually-hidden">In reply to <a href="/comment/31#comment-31" class="permalink" rel="bookmark" hreflang="en">I wish they would put some of these up alongside the problems</a> by <span lang="" typeof="schema:Person" property="schema:name" datatype="">bjc</span></p> </footer> <div class="comment-text"> <div class="comment-arrow"></div> <h3><a href="/comment/32#comment-32" class="permalink" rel="bookmark" hreflang="en">Thank you for your nice words</a></h3> <div class="content"> <div class="field field--name-comment-body field--type-text-long field--label-hidden field__item"><div class="tex2jax_process"><p>I am glad that this is helpful.&nbsp; Happy Clojuring <img src="/sites/all/libraries/tinymce/jscripts/tiny_mce/plugins/emotions/img/smiley-cool.gif" alt="Cool" title="Cool" border="0"></p> </div></div> <drupal-render-placeholder callback="comment.lazy_builders:renderLinks" arguments="0=32&amp;1=default&amp;2=en&amp;3=" token="jq4Ec-y1qsP57EP-n5He1zEXIj34lMlEXe7GGeXB2RI"></drupal-render-placeholder> </div> </div> </article> </div><a id="comment-41"></a> <article data-comment-user-id="0" class="js-comment comment"> <mark class="hidden" data-comment-timestamp="1329040234"></mark> <footer class="attribution"> <article typeof="schema:Person" about="/user/0"> <div class="field field--name-user-picture field--type-image field--label-hidden field__item"> <img src="/sites/default/files/styles/thumbnail/public/default_images/default-user-image.png?itok=hWWOuuKw" width="100" height="100" alt="Profile picture for user Nik" title="Anonymous user" typeof="foaf:Image" /> </div> </article> <div class="comment-submitted"> <p class="commenter-name"> <span lang="" typeof="schema:Person" property="schema:name" datatype="">Anonymous</span> </p> <p class="comment-time"> Sun, 02/12/2012 - 09:50 </p> </div> </footer> <div class="comment-text"> <div class="comment-arrow"></div> <h3><a href="/comment/41#comment-41" class="permalink" rel="bookmark" hreflang="en">problem #21 - your solution</a></h3> <div class="content"> <div class="field field--name-comment-body field--type-text-long field--label-hidden field__item"><div class="tex2jax_process"><p>problem #21 - your solution is confusing..simple one below</p> <p>(fn[col x ]<br /> (first (drop x col)))</p> </div></div> <drupal-render-placeholder callback="comment.lazy_builders:renderLinks" arguments="0=41&amp;1=default&amp;2=en&amp;3=" token="A0mMZoJGsihZPNFFHICIThJQIiBjCGLmlqY3bTfE61U"></drupal-render-placeholder> </div> </div> </article> <div class="indented"><a id="comment-42"></a> <article data-comment-user-id="1" class="js-comment comment"> <mark class="hidden" data-comment-timestamp="1329115484"></mark> <footer class="attribution"> <article typeof="schema:Person" about="/user/huahai"> <div class="field field--name-user-picture field--type-image field--label-hidden field__item"> <img src="/sites/default/files/styles/thumbnail/public/pictures/2017-11/huahai.jpg?itok=ZwjJWYAc" width="88" height="100" alt="Profile picture for user Huahai" typeof="foaf:Image" /> </div> </article> <div class="comment-submitted"> <p class="commenter-name"> <a title="View user profile." href="/user/huahai" lang="" about="/user/huahai" typeof="schema:Person" property="schema:name" datatype="">Huahai</a> </p> <p class="comment-time"> Mon, 02/13/2012 - 06:44 </p> </div> <p class="visually-hidden">In reply to <a href="/comment/41#comment-41" class="permalink" rel="bookmark" hreflang="en">problem #21 - your solution</a> by <span lang="" typeof="schema:Person" property="schema:name" datatype="">Anonymous</span></p> </footer> <div class="comment-text"> <div class="comment-arrow"></div> <h3><a href="/comment/42#comment-42" class="permalink" rel="bookmark" hreflang="en">duplicate</a></h3> <div class="content"> <div class="field field--name-comment-body field--type-text-long field--label-hidden field__item"><div class="tex2jax_process"><p><a href="http://yyhh.org/blog/2011/05/my-solutions-first-50-problems-4clojure-com#comment-24">citizen428</a> has already posted the same solution. Thank you for stopping by.</p> </div></div> <drupal-render-placeholder callback="comment.lazy_builders:renderLinks" arguments="0=42&amp;1=default&amp;2=en&amp;3=" token="jTyXG9yPp5HG-5eFR3y5lHxuBvcV4a0q5S4t0pXGl_g"></drupal-render-placeholder> </div> </div> </article> </div><a id="comment-60"></a> <article data-comment-user-id="0" class="js-comment comment"> <mark class="hidden" data-comment-timestamp="1344798368"></mark> <footer class="attribution"> <article typeof="schema:Person" about="/user/0"> <div class="field field--name-user-picture field--type-image field--label-hidden field__item"> <img src="/sites/default/files/styles/thumbnail/public/default_images/default-user-image.png?itok=hWWOuuKw" width="100" height="100" alt="Profile picture for user Nik" title="Anonymous user" typeof="foaf:Image" /> </div> </article> <div class="comment-submitted"> <p class="commenter-name"> <a rel="nofollow" href="http://www.kresimirbojcic.com" lang="" typeof="schema:Person" property="schema:name" datatype="">Kresimir Bojcic</a> </p> <p class="comment-time"> Sun, 08/12/2012 - 20:06 </p> </div> </footer> <div class="comment-text"> <div class="comment-arrow"></div> <h3><a href="/comment/60#comment-60" class="permalink" rel="bookmark" hreflang="en">#21 </a></h3> <div class="content"> <div class="field field--name-comment-body field--type-text-long field--label-hidden field__item"><div class="tex2jax_process"><p>#( ( vec %) %2)</p> </div></div> <drupal-render-placeholder callback="comment.lazy_builders:renderLinks" arguments="0=60&amp;1=default&amp;2=en&amp;3=" token="0CDArCatQRqJT4OrfK2NuyBfkQJk_wewnihtk0do6ds"></drupal-render-placeholder> </div> </div> </article> <div class="indented"><a id="comment-61"></a> <article data-comment-user-id="1" class="js-comment comment"> <mark class="hidden" data-comment-timestamp="1344926314"></mark> <footer class="attribution"> <article typeof="schema:Person" about="/user/huahai"> <div class="field field--name-user-picture field--type-image field--label-hidden field__item"> <img src="/sites/default/files/styles/thumbnail/public/pictures/2017-11/huahai.jpg?itok=ZwjJWYAc" width="88" height="100" alt="Profile picture for user Huahai" typeof="foaf:Image" /> </div> </article> <div class="comment-submitted"> <p class="commenter-name"> <a title="View user profile." href="/user/huahai" lang="" about="/user/huahai" typeof="schema:Person" property="schema:name" datatype="">Huahai</a> </p> <p class="comment-time"> Tue, 08/14/2012 - 07:38 </p> </div> <p class="visually-hidden">In reply to <a href="/comment/60#comment-60" class="permalink" rel="bookmark" hreflang="en">#21 </a> by <a rel="nofollow" href="http://www.kresimirbojcic.com" lang="" typeof="schema:Person" property="schema:name" datatype="">Kresimir Bojcic</a></p> </footer> <div class="comment-text"> <div class="comment-arrow"></div> <h3><a href="/comment/61#comment-61" class="permalink" rel="bookmark" hreflang="en">Neat</a></h3> <div class="content"> <div class="field field--name-comment-body field--type-text-long field--label-hidden field__item"><div class="tex2jax_process"><p>This solution takes advantage of the fact that a Clojure vector is a function. This function returns an element of the vector with the given index.</p> <p>Thanks for contributing this one. Love it. &nbsp;</p> </div></div> <drupal-render-placeholder callback="comment.lazy_builders:renderLinks" arguments="0=61&amp;1=default&amp;2=en&amp;3=" token="tsivEkW1RiHRG_UaEPA1wqC-QJ7_6xFADnCl06IjNSg"></drupal-render-placeholder> </div> </div> </article> </div><a id="comment-123"></a> <article data-comment-user-id="0" class="js-comment comment"> <mark class="hidden" data-comment-timestamp="1375377096"></mark> <footer class="attribution"> <article typeof="schema:Person" about="/user/0"> <div class="field field--name-user-picture field--type-image field--label-hidden field__item"> <img src="/sites/default/files/styles/thumbnail/public/default_images/default-user-image.png?itok=hWWOuuKw" width="100" height="100" alt="Profile picture for user Nik" title="Anonymous user" typeof="foaf:Image" /> </div> </article> <div class="comment-submitted"> <p class="commenter-name"> <a rel="nofollow" href="http://bernsteinbear.com" lang="" typeof="schema:Person" property="schema:name" datatype="">Max Bernstein</a> </p> <p class="comment-time"> Thu, 08/01/2013 - 18:11 </p> </div> </footer> <div class="comment-text"> <div class="comment-arrow"></div> <h3><a href="/comment/123#comment-123" class="permalink" rel="bookmark" hreflang="en">For exercise number 21... could be done shorter</a></h3> <div class="content"> <div class="field field--name-comment-body field--type-text-long field--label-hidden field__item"><div class="tex2jax_process"><p><code>#(.get %1 %2)</code></p> </div></div> <drupal-render-placeholder callback="comment.lazy_builders:renderLinks" arguments="0=123&amp;1=default&amp;2=en&amp;3=" token="Lkj0iuFijUJ-olizimeC0BRZLjZ1IFpYnqZNpsErgJA"></drupal-render-placeholder> </div> </div> </article> <a id="comment-124"></a> <article data-comment-user-id="0" class="js-comment comment"> <mark class="hidden" data-comment-timestamp="1375380537"></mark> <footer class="attribution"> <article typeof="schema:Person" about="/user/0"> <div class="field field--name-user-picture field--type-image field--label-hidden field__item"> <img src="/sites/default/files/styles/thumbnail/public/default_images/default-user-image.png?itok=hWWOuuKw" width="100" height="100" alt="Profile picture for user Nik" title="Anonymous user" typeof="foaf:Image" /> </div> </article> <div class="comment-submitted"> <p class="commenter-name"> <a rel="nofollow" href="http://bernsteinbear.com" lang="" typeof="schema:Person" property="schema:name" datatype="">Max Bernstein</a> </p> <p class="comment-time"> Thu, 08/01/2013 - 19:08 </p> </div> </footer> <div class="comment-text"> <div class="comment-arrow"></div> <h3><a href="/comment/124#comment-124" class="permalink" rel="bookmark" hreflang="en">Problem 26 - fibonacci</a></h3> <div class="content"> <div class="field field--name-comment-body field--type-text-long field--label-hidden field__item"><div class="tex2jax_process"><p>Mine is a bit more verbose...<br /><code>(fn [ind] (map (fn fib [x] (if (&lt;= x 2) 1 (+ (fib (- x 1)) (fib (- x 2))))) (map #(+ 1 %) (range ind))))</code></p> <p>Basically, make a fibonacci function, map it to a range offset by 1.</p> </div></div> <drupal-render-placeholder callback="comment.lazy_builders:renderLinks" arguments="0=124&amp;1=default&amp;2=en&amp;3=" token="yQPsg0HFX0Ze5JuXX1e9v4luBJYO0zmg-se__ZXi-iI"></drupal-render-placeholder> </div> </div> </article> <a id="comment-125"></a> <article data-comment-user-id="0" class="js-comment comment"> <mark class="hidden" data-comment-timestamp="1375380671"></mark> <footer class="attribution"> <article typeof="schema:Person" about="/user/0"> <div class="field field--name-user-picture field--type-image field--label-hidden field__item"> <img src="/sites/default/files/styles/thumbnail/public/default_images/default-user-image.png?itok=hWWOuuKw" width="100" height="100" alt="Profile picture for user Nik" title="Anonymous user" typeof="foaf:Image" /> </div> </article> <div class="comment-submitted"> <p class="commenter-name"> <a rel="nofollow" href="http://bernsteinbear.com" lang="" typeof="schema:Person" property="schema:name" datatype="">Max Bernstein</a> </p> <p class="comment-time"> Thu, 08/01/2013 - 19:11 </p> </div> </footer> <div class="comment-text"> <div class="comment-arrow"></div> <h3><a href="/comment/125#comment-125" class="permalink" rel="bookmark" hreflang="en">Problem 27 - palindrome?</a></h3> <div class="content"> <div class="field field--name-comment-body field--type-text-long field--label-hidden field__item"><div class="tex2jax_process"><p><code>(fn [x] (= (reverse x) (seq s)))</code></p> </div></div> <drupal-render-placeholder callback="comment.lazy_builders:renderLinks" arguments="0=125&amp;1=default&amp;2=en&amp;3=" token="_NakHHDQJ0PxH_pCazqnJZ5w-HvWhePNGXkgqgjGb50"></drupal-render-placeholder> </div> </div> </article> <a id="comment-126"></a> <article data-comment-user-id="0" class="js-comment comment"> <mark class="hidden" data-comment-timestamp="1375383200"></mark> <footer class="attribution"> <article typeof="schema:Person" about="/user/0"> <div class="field field--name-user-picture field--type-image field--label-hidden field__item"> <img src="/sites/default/files/styles/thumbnail/public/default_images/default-user-image.png?itok=hWWOuuKw" width="100" height="100" alt="Profile picture for user Nik" title="Anonymous user" typeof="foaf:Image" /> </div> </article> <div class="comment-submitted"> <p class="commenter-name"> <a rel="nofollow" href="http://bernsteinbear.com" lang="" typeof="schema:Person" property="schema:name" datatype="">Max Bernstein</a> </p> <p class="comment-time"> Thu, 08/01/2013 - 19:53 </p> </div> </footer> <div class="comment-text"> <div class="comment-arrow"></div> <h3><a href="/comment/126#comment-126" class="permalink" rel="bookmark" hreflang="en">Problem 30 - compression</a></h3> <div class="content"> <div class="field field--name-comment-body field--type-text-long field--label-hidden field__item"><div class="tex2jax_process"><p><code>#(map first (partition-by identity %))</code></p> <p>`partition-by identity` separates into a seq separated by sections of elements. then you get the first of each section and return the seq.</p> </div></div> <drupal-render-placeholder callback="comment.lazy_builders:renderLinks" arguments="0=126&amp;1=default&amp;2=en&amp;3=" token="otlmmicKMJ8N_RvcjbzAUqjpIu-_i5JUg9qa5A0YI_s"></drupal-render-placeholder> </div> </div> </article> <a id="comment-127"></a> <article data-comment-user-id="0" class="js-comment comment"> <mark class="hidden" data-comment-timestamp="1375388650"></mark> <footer class="attribution"> <article typeof="schema:Person" about="/user/0"> <div class="field field--name-user-picture field--type-image field--label-hidden field__item"> <img src="/sites/default/files/styles/thumbnail/public/default_images/default-user-image.png?itok=hWWOuuKw" width="100" height="100" alt="Profile picture for user Nik" title="Anonymous user" typeof="foaf:Image" /> </div> </article> <div class="comment-submitted"> <p class="commenter-name"> <a rel="nofollow" href="http://bernsteinbear.com" lang="" typeof="schema:Person" property="schema:name" datatype="">Max Bernstein</a> </p> <p class="comment-time"> Thu, 08/01/2013 - 21:24 </p> </div> </footer> <div class="comment-text"> <div class="comment-arrow"></div> <h3><a href="/comment/127#comment-127" class="permalink" rel="bookmark" hreflang="en">For program 40</a></h3> <div class="content"> <div class="field field--name-comment-body field--type-text-long field--label-hidden field__item"><div class="tex2jax_process"><p><code>#(mapcat vector (repeat (count %2) %1) %2)</code></p> <p>You can use your previous solution, and mapcat (or interleave) 2 seqs.</p> </div></div> <drupal-render-placeholder callback="comment.lazy_builders:renderLinks" arguments="0=127&amp;1=default&amp;2=en&amp;3=" token="nQ3R74qTUGtW5nRi0snnjGuFBWOzBC1s3-NE7KChDb0"></drupal-render-placeholder> </div> </div> </article> <div class="indented"><a id="comment-128"></a> <article data-comment-user-id="0" class="js-comment comment"> <mark class="hidden" data-comment-timestamp="1375388935"></mark> <footer class="attribution"> <article typeof="schema:Person" about="/user/0"> <div class="field field--name-user-picture field--type-image field--label-hidden field__item"> <img src="/sites/default/files/styles/thumbnail/public/default_images/default-user-image.png?itok=hWWOuuKw" width="100" height="100" alt="Profile picture for user Nik" title="Anonymous user" typeof="foaf:Image" /> </div> </article> <div class="comment-submitted"> <p class="commenter-name"> <a rel="nofollow" href="http://bernsteinbear.com" lang="" typeof="schema:Person" property="schema:name" datatype="">Max Bernstein</a> </p> <p class="comment-time"> Thu, 08/01/2013 - 21:28 </p> </div> <p class="visually-hidden">In reply to <a href="/comment/127#comment-127" class="permalink" rel="bookmark" hreflang="en">For program 40</a> by <a rel="nofollow" href="http://bernsteinbear.com" lang="" typeof="schema:Person" property="schema:name" datatype="">Max Bernstein</a></p> </footer> <div class="comment-text"> <div class="comment-arrow"></div> <h3><a href="/comment/128#comment-128" class="permalink" rel="bookmark" hreflang="en">Sorry, the correct and better way:</a></h3> <div class="content"> <div class="field field--name-comment-body field--type-text-long field--label-hidden field__item"><div class="tex2jax_process"><p><code>#(drop-last (interleave %2 (repeat (count %2) %1)))</code></p> </div></div> <drupal-render-placeholder callback="comment.lazy_builders:renderLinks" arguments="0=128&amp;1=default&amp;2=en&amp;3=" token="7vqmOTjVYHHwVPhDCKVPNujdwqIm-AOTVCQHj3bECwo"></drupal-render-placeholder> </div> </div> </article> </div><a id="comment-139"></a> <article data-comment-user-id="0" class="js-comment comment"> <mark class="hidden" data-comment-timestamp="1380831905"></mark> <footer class="attribution"> <article typeof="schema:Person" about="/user/0"> <div class="field field--name-user-picture field--type-image field--label-hidden field__item"> <img src="/sites/default/files/styles/thumbnail/public/default_images/default-user-image.png?itok=hWWOuuKw" width="100" height="100" alt="Profile picture for user Nik" title="Anonymous user" typeof="foaf:Image" /> </div> </article> <div class="comment-submitted"> <p class="commenter-name"> <span lang="" typeof="schema:Person" property="schema:name" datatype="">cybergrind</span> </p> <p class="comment-time"> Thu, 10/03/2013 - 21:25 </p> </div> </footer> <div class="comment-text"> <div class="comment-arrow"></div> <h3><a href="/comment/139#comment-139" class="permalink" rel="bookmark" hreflang="en">Problem 27</a></h3> <div class="content"> <div class="field field--name-comment-body field--type-text-long field--label-hidden field__item"><div class="tex2jax_process"><p>27. (fn [what] (= (reverse what) ((comp reverse reverse) what)))</p> </div></div> <drupal-render-placeholder callback="comment.lazy_builders:renderLinks" arguments="0=139&amp;1=default&amp;2=en&amp;3=" token="9dR6oWoSu8xGDsrLwTZ5lPaUpvRXPC1RgJEa1kOzHDY"></drupal-render-placeholder> </div> </div> </article> <a id="comment-143"></a> <article data-comment-user-id="0" class="js-comment comment"> <mark class="hidden" data-comment-timestamp="1382212173"></mark> <footer class="attribution"> <article typeof="schema:Person" about="/user/0"> <div class="field field--name-user-picture field--type-image field--label-hidden field__item"> <img src="/sites/default/files/styles/thumbnail/public/default_images/default-user-image.png?itok=hWWOuuKw" width="100" height="100" alt="Profile picture for user Nik" title="Anonymous user" typeof="foaf:Image" /> </div> </article> <div class="comment-submitted"> <p class="commenter-name"> <span lang="" typeof="schema:Person" property="schema:name" datatype="">Anonymous</span> </p> <p class="comment-time"> Sat, 10/19/2013 - 20:49 </p> </div> </footer> <div class="comment-text"> <div class="comment-arrow"></div> <h3><a href="/comment/143#comment-143" class="permalink" rel="bookmark" hreflang="en">Problem 44</a></h3> <div class="content"> <div class="field field--name-comment-body field--type-text-long field--label-hidden field__item"><div class="tex2jax_process"><p>I have a solution that I believe to be just a bit more concise than the previous comment.<br /><code><br /> (fn rotate[n seq]<br /> (let [n (mod n (count seq))]<br /> (concat (drop n seq) (take n seq))))<br /></code></p> </div></div> <drupal-render-placeholder callback="comment.lazy_builders:renderLinks" arguments="0=143&amp;1=default&amp;2=en&amp;3=" token="85bZtehIzN2j2sPdGtt9rI2PT7ljz4rLeBPk800mu4c"></drupal-render-placeholder> </div> </div> </article> <a id="comment-149"></a> <article data-comment-user-id="0" class="js-comment comment"> <mark class="hidden" data-comment-timestamp="1385072073"></mark> <footer class="attribution"> <article typeof="schema:Person" about="/user/0"> <div class="field field--name-user-picture field--type-image field--label-hidden field__item"> <img src="/sites/default/files/styles/thumbnail/public/default_images/default-user-image.png?itok=hWWOuuKw" width="100" height="100" alt="Profile picture for user Nik" title="Anonymous user" typeof="foaf:Image" /> </div> </article> <div class="comment-submitted"> <p class="commenter-name"> <span lang="" typeof="schema:Person" property="schema:name" datatype="">Anonymous</span> </p> <p class="comment-time"> Thu, 11/21/2013 - 22:14 </p> </div> </footer> <div class="comment-text"> <div class="comment-arrow"></div> <h3><a href="/comment/149#comment-149" class="permalink" rel="bookmark" hreflang="en">a simpler solution for</a></h3> <div class="content"> <div class="field field--name-comment-body field--type-text-long field--label-hidden field__item"><div class="tex2jax_process"><p>a simpler solution for #28:<br /> (fn flat [x] (apply concat (map #(if (sequential? %) (flat %) [%]) x)))</p> </div></div> <drupal-render-placeholder callback="comment.lazy_builders:renderLinks" arguments="0=149&amp;1=default&amp;2=en&amp;3=" token="OZelAavOx2szdpHj15yTngtu3ijyw3PVi4PnhUA9lEs"></drupal-render-placeholder> </div> </div> </article> <a id="comment-168"></a> <article data-comment-user-id="0" class="js-comment comment"> <mark class="hidden" data-comment-timestamp="1401219166"></mark> <footer class="attribution"> <article typeof="schema:Person" about="/user/0"> <div class="field field--name-user-picture field--type-image field--label-hidden field__item"> <img src="/sites/default/files/styles/thumbnail/public/default_images/default-user-image.png?itok=hWWOuuKw" width="100" height="100" alt="Profile picture for user Nik" title="Anonymous user" typeof="foaf:Image" /> </div> </article> <div class="comment-submitted"> <p class="commenter-name"> <span lang="" typeof="schema:Person" property="schema:name" datatype="">Kevin Litwack</span> </p> <p class="comment-time"> Tue, 05/27/2014 - 20:32 </p> </div> </footer> <div class="comment-text"> <div class="comment-arrow"></div> <h3><a href="/comment/168#comment-168" class="permalink" rel="bookmark" hreflang="en">(slightly pedantic) bug in solution #30</a></h3> <div class="content"> <div class="field field--name-comment-body field--type-text-long field--label-hidden field__item"><div class="tex2jax_process"><p>Here's the bug:</p> <p><code><br /> user=&gt; (cmprs [1 1 2 2 nil nil])<br /> (1 2)<br /></code></p> <p>Because (first r) returns nil if r is emtpy, any trailing nils in the input collection will be lost. This fixes it:</p> <p><code><br /> (defn cmprs2 [coll]</code></p> <p> (when-let [[f &amp; r] (seq coll)]<br /> (if (and (nil? f) (empty? r))<br /> (list f)</p> <p> (if (= f (first r))<br /> (cmprs2 r)<br /> (cons f (cmprs2 r))))))</p> <p>user=&gt; (cmprs2 [1 1 2 2 nil nil])<br /> (1 2 nil)<br /></p> </div></div> <drupal-render-placeholder callback="comment.lazy_builders:renderLinks" arguments="0=168&amp;1=default&amp;2=en&amp;3=" token="9_J82nYsGEZb5lXcfi_UFOPO9JuI4el2__sSx94ylkU"></drupal-render-placeholder> </div> </div> </article> <a id="comment-176"></a> <article data-comment-user-id="0" class="js-comment comment"> <mark class="hidden" data-comment-timestamp="1409167420"></mark> <footer class="attribution"> <article typeof="schema:Person" about="/user/0"> <div class="field field--name-user-picture field--type-image field--label-hidden field__item"> <img src="/sites/default/files/styles/thumbnail/public/default_images/default-user-image.png?itok=hWWOuuKw" width="100" height="100" alt="Profile picture for user Nik" title="Anonymous user" typeof="foaf:Image" /> </div> </article> <div class="comment-submitted"> <p class="commenter-name"> <span lang="" typeof="schema:Person" property="schema:name" datatype="">Andro</span> </p> <p class="comment-time"> Wed, 08/27/2014 - 20:23 </p> </div> </footer> <div class="comment-text"> <div class="comment-arrow"></div> <h3><a href="/comment/176#comment-176" class="permalink" rel="bookmark" hreflang="en">Problem 21</a></h3> <div class="content"> <div class="field field--name-comment-body field--type-text-long field--label-hidden field__item"><div class="tex2jax_process"><p>I checked the code of drop and this is the solution I used.</p> <p>(fn element-at [list n]<br /> (let [go (fn [list n] (if (and (pos? n) list) (recur (rest list) (dec n)) list))]<br /> (first(go list n))))</p> </div></div> <drupal-render-placeholder callback="comment.lazy_builders:renderLinks" arguments="0=176&amp;1=default&amp;2=en&amp;3=" token="DLfLNaxt9ktUpx3AXaf67IBala6bFmVTM21kvfqbmDQ"></drupal-render-placeholder> </div> </div> </article> <a id="comment-191"></a> <article data-comment-user-id="0" class="js-comment comment"> <mark class="hidden" data-comment-timestamp="1511738167"></mark> <footer class="attribution"> <article typeof="schema:Person" about="/user/0"> <div class="field field--name-user-picture field--type-image field--label-hidden field__item"> <img src="/sites/default/files/styles/thumbnail/public/default_images/default-user-image.png?itok=hWWOuuKw" width="100" height="100" alt="Profile picture for user Nik" title="Anonymous user" typeof="foaf:Image" /> </div> </article> <div class="comment-submitted"> <p class="commenter-name"> <span lang="" typeof="schema:Person" property="schema:name" datatype="">Youn Chin</span> </p> <p class="comment-time"> Wed, 12/09/2015 - 04:51 </p> </div> </footer> <div class="comment-text"> <div class="comment-arrow"></div> <h3><a href="/comment/191#comment-191" class="permalink" rel="bookmark" hreflang="en">Problem 41</a></h3> <div class="content"> <div class="field field--name-comment-body field--type-text-long field--label-hidden field__item"><div class="tex2jax_process"><p>Solution for Problem #41 can be slightly altered to handle the partitioned items in one go, by checking the size of item:<br /> (fn [col n] (flatten (concat (map #(if (= n (count %)) (drop-last %) %) (partition-all n col)))))</p> <p>BTW, great site, very helpful to see discussions.</p> </div></div> <drupal-render-placeholder callback="comment.lazy_builders:renderLinks" arguments="0=191&amp;1=default&amp;2=en&amp;3=" token="rvZ9S8fZC_63-0-Pb8lReRTXiMHGFQxfZXU_xhQvH1Y"></drupal-render-placeholder> </div> </div> </article> <h2>Add new comment</h2> <drupal-render-placeholder callback="comment.lazy_builders:renderForm" arguments="0=node&amp;1=115&amp;2=comment_node_blog&amp;3=comment_node_blog" token="VN-skdiQaHBpY2yFgaAEBpa03pXm1ELprugOgZbGg9g"></drupal-render-placeholder> </section> <strong class="node_view"></strong> Wed, 18 May 2011 23:13:55 +0000 Huahai 115 at https://yyhh.org Develop clojure Web applications with vim https://yyhh.org/blog/2011/05/develop-clojure-web-applications-vim <span>Develop clojure Web applications with vim</span> <span><a title="View user profile." href="/user/huahai" lang="" about="/user/huahai" typeof="schema:Person" property="schema:name" datatype="">Huahai</a></span> <span>Tue, 05/03/2011 - 00:02</span> <div class="field field--name-field-notebook field--type-entity-reference field--label-hidden field__items"> <div class="field__item"><div about="/notebook/clojure" id="taxonomy-term-35" class="taxonomy-term vocabulary-notebook"> <a href="/notebook/clojure"> <div class="field field--name-name field--type-string field--label-hidden field__item">Clojure</div> </a> <div class="content"> </div> </div> </div> </div> <div class="field field--name-body field--type-text-with-summary field--label-hidden field__item"><div class="tex2jax_process"><p>I recently started to learn <a href="http://clojure.org">clojure</a> programming. It is an interesting experience. Ever since I learned computer programming almost 20 years ago, in Pascal, on a VAX minicomputer terminal, I have not experienced this newbie sensation with a computer language. The sense of excitement and novelty is high, and the eagerness to put the language to use is higher still. So for my new project at work, I am doing it with clojure. </p> <p>This is a visual analytics project, and the visual part will be on the Web. It amazes me <a href="http://www.glenstampoultzis.net/blog/clojure-web-infrastructure/">how much work</a> has already been done for the Web using this 3 years old language. So it should be easy for me to get started. Here's what I have so far.</p> <p><b><br /> Know your lein<br /></b></p> <p>The standard build tool for clojure projects these days seems to be lein, short for <a href="https://github.com/technomancy/leiningen">leiningen</a>. It is just a script, download it, make it executable, put it on your path. Also make sure you have java installed. Now go to whatever directory your project will live in, run lein:</p> <p><code>lein new myproject</code></p> <p>This creates the default project structure for a project creatively named "myproject", and downloads dependencies from the Internet, including clojure itself (clojure is built on java virtual machine, so the clojure language runtime is just a jar file). </p> <p>Now in the "mypoject" directory, there is a "project.clj" file. This file controls everything about the project, except the writing code part. Edit the file according to your needs. There is a very extensive <a href="https://github.com/technomancy/leiningen/blob/master/sample.project.clj">sample project.clj</a> that I find very informative. My project.clj so far looks like this:</p> <div class="codeblock"> <font face="monospace"><br /><font color="#375288"> 1 </font><span><font color="#912f11">(</font></span>defproject myproject <span><font color="#077807">"0.0.1-SNAPSHOT"</font></span><br /><font color="#375288"> 2 </font>  <span><font color="#1f3f81"><b>:description</b></font></span> <span><font color="#077807">"MyProject has super duper visual analytics capabilities"</font></span><br /><font color="#375288"> 3 </font>  <span><font color="#1f3f81"><b>:dependencies</b></font></span> <span><font color="#912f11">[[</font></span>org.clojure/clojure <span><font color="#077807">"1.2.1"</font></span><span><font color="#912f11">]</font></span><br /><font color="#375288"> 4 </font>                 <span><font color="#912f11">[</font></span>org.clojure/clojure-contrib <span><font color="#077807">"1.2.0"</font></span><span><font color="#912f11">]</font></span><br /><font color="#375288"> 5 </font>                 <span><font color="#912f11">[</font></span>compojure <span><font color="#077807">"0.6.2"</font></span><span><font color="#912f11">]</font></span><br /><font color="#375288"> 6 </font>                 <span><font color="#912f11">[</font></span>hiccup <span><font color="#077807">"0.3.4"</font></span><span><font color="#912f11">]</font></span><br /><font color="#375288"> 7 </font>                 <span><font color="#912f11">[</font></span>ring <span><font color="#077807">"0.3.7"</font></span><span><font color="#912f11">]</font></span><br /><font color="#375288"> 8 </font>                 <span><font color="#912f11">[</font></span>commons-logging <span><font color="#077807">"1.1.1"</font></span><span><font color="#912f11">]</font></span><br /><font color="#375288"> 9 </font>                 <span><font color="#912f11">[</font></span>org.apache.lucene/lucene-core <span><font color="#077807">"3.1.0"</font></span><span><font color="#912f11">]</font></span><br /><font color="#375288">10 </font>                 <span><font color="#912f11">[</font></span>xalan <span><font color="#077807">"2.7.1"</font></span><span><font color="#912f11">]</font></span><br /><font color="#375288">11 </font>                 <span><font color="#912f11">[</font></span>javaewah <span><font color="#077807">"0.1.0"</font></span><span><font color="#912f11">]</font></span><br /><font color="#375288">12 </font>                 <span><font color="#912f11">[</font></span>com.my.work/secret-lib1 <span><font color="#077807">"0.3.4b"</font></span><span><font color="#912f11">]</font></span><br /><font color="#375288">13 </font>                 <span><font color="#912f11">[</font></span>com.my.work/secret-lib2 <span><font color="#077807">"0.1.0"</font></span><span><font color="#912f11">]]</font></span><br /><font color="#375288">14 </font>  <span><font color="#1f3f81"><b>:dev-dependencies</b></font></span> <span><font color="#912f11">[[</font></span>lein-ring <span><font color="#077807">"0.4.0"</font></span><span><font color="#912f11">]</font></span><br /><font color="#375288">15 </font>                     <span><font color="#786000">;[org.clojars.autre/lein-vimclojure "1.0.0"]</font></span><br /><font color="#375288">16 </font>                     <span><font color="#912f11">[</font></span>clj-stacktrace <span><font color="#077807">"0.2.1"</font></span><span><font color="#912f11">]]</font></span> <br /><font color="#375288">17 </font>  <span><font color="#1f3f81"><b>:repositories</b></font></span> <br /><font color="#375288">18 </font>            <span><font color="#912f11">{</font></span><span><font color="#077807">"myrepo"</font></span> <br /><font color="#375288">19 </font>             <span><font color="#912f11">{</font></span><span><font color="#1f3f81"><b>:url</b></font></span> <br /><font color="#375288">20 </font>              <span><font color="#077807">"<a href="http://myrepo.my.com:8080/artifactory/libs-release-local">http://myrepo.my.com:8080/artifactory/libs-release-local</a>"</font></span><span><font color="#912f11">}}</font></span><br /><font color="#375288">21 </font>  <span><font color="#1f3f81"><b>:source-path</b></font></span> <span><font color="#077807">"src/clojure"</font></span><br /><font color="#375288">22 </font>  <span><font color="#1f3f81"><b>:java-source-path</b></font></span> <span><font color="#077807">"src/java"</font></span><br /><font color="#375288">23 </font>  <span><font color="#1f3f81"><b>:warn-on-reflection</b></font></span> <span><font color="#077807">true</font></span><br /><font color="#375288">24 </font>  <span><font color="#786000">;:main com.my.myproject.runtime.core)</font></span><br /><font color="#375288">25 </font>  <span><font color="#1f3f81"><b>:ring</b></font></span> <span><font color="#912f11">{</font></span><span><font color="#1f3f81"><b>:handler</b></font></span> com.my.myproject.runtime.core/app<span><font color="#912f11">})</font></span><br /></font> </div> <p>Let me explain line by line. The first line is the project name and the current version number (using the so called <a href="http://semver.org">semantic versioning</a> scheme). </p> <p>The third line starts the dependencies definition. These dependencies are libraries written in jvm languages such as java or clojure. lein will automatically find and download them from public repositories if they are publicly available. This is the case for libraries referred in line 3 - 10, where the last three libs are open source java libs and the rest are open source clojure libs: <a href="https://github.com/weavejester/compojure">compojure</a> is a lightweight Web framework, which builds upon <a href="https://github.com/mmcgrana/ring">ring</a>, which abstract HTTP into a simple API, <a href="https://github.com/weavejester/hiccup">hiccup</a> allows one to write html in clojure syntax. </p> <p>The lib on line 11 is also open source, however, it has not been packaged by the author and submitted to a pubic repository, so lein will not be able to find it. What I did was to package it as a jar file myself and deploy it to a private repository I setup for my team, so my team members can all access to the same libs without needing to commit the libs to our version control system, which is not suitable for handling binary data. This private repository is defined on line 17 to 20. Here the repository server is a standard installation of <a href="http://www.jfrog.com/products.php">artifactory</a>. The libs on line 12 and 13 are our in-house developed java libraries, which are deployed the same way.</p> <p>By default, lein expect clojure code in "myproject/src". Since we will be mixing java code and clojure code, we put them in separate folders. These are defined in line 21 and 22. </p> <p>Line 14 starts the dev-dependencies. These are the dependencies for developers' convenience and will not be included in the final product. <a href="https://github.com/weavejester/lein-ring">lein-ring</a> is a plugin for facilitating Web development in clojure that utilizes ring. Basically, it adds a ring command for lein. For example,</p> <p><code>lein ring server-headless</code></p> <p>will start a jetty server with the Web app running on port 3000 (default). The Web app is defined on line 25, which is just a simple app to show a greeting in this case. The code consists of two files. core.clj defines the main routing table for the Web app:</p> <div class="codeblock"> <font face="monospace"><br /><font color="#375288"> 1 </font><span><font color="#912f11">(</font></span><span><font color="#800090">ns</font></span> com.my.myproject.runtime.core<br /><font color="#375288"> 2 </font>  <font color="#cd3700">(</font><span><font color="#1f3f81"><b>:use</b></font></span> compojure.core<br /><font color="#375288"> 3 </font>        hiccup.middleware<br /><font color="#375288"> 4 </font>        com.my.myproject.runtime.views<font color="#cd3700">)</font><br /><font color="#375288"> 5 </font>  <font color="#cd3700">(</font><span><font color="#1f3f81"><b>:require</b></font></span> <span><font color="#912f11">[</font></span>compojure.route <span><font color="#1f3f81"><b>:as</b></font></span> route<span><font color="#912f11">]</font></span><br /><font color="#375288"> 6 </font>            <span><font color="#912f11">[</font></span>compojure.handler <span><font color="#1f3f81"><b>:as</b></font></span> handler<span><font color="#912f11">]</font></span><font color="#cd3700">)</font><span><font color="#912f11">)</font></span><br /><font color="#375288"> 7 </font><br /><font color="#375288"> 8 </font><span><font color="#912f11">(</font></span>defroutes main-routes<br /><font color="#375288"> 9 </font>  <font color="#cd3700">(</font>GET <span><font color="#077807">"/"</font></span> <span><font color="#912f11">[]</font></span> <font color="#ee9a00">(</font>index-page<font color="#ee9a00">)</font><font color="#cd3700">)</font><br /><font color="#375288">10 </font>  <font color="#cd3700">(</font>route/not-found <font color="#ee9a00">(</font>page-404<font color="#ee9a00">)</font><font color="#cd3700">)</font><br /><font color="#375288">11 </font>  <font color="#cd3700">(</font>route/resources <span><font color="#077807">"/"</font></span><font color="#cd3700">)</font><span><font color="#912f11">)</font></span><br /><font color="#375288">12 </font><br /><font color="#375288">13 </font><span><font color="#912f11">(</font></span><span><font color="#912f11">def</font></span> app<br /><font color="#375288">14 </font>  <font color="#cd3700">(</font><span><font color="#800090">-&gt;</font></span> <font color="#ee9a00">(</font>handler/site main-routes<font color="#ee9a00">)</font><br /><font color="#375288">15 </font>      <font color="#ee9a00">(</font>wrap-base-url<font color="#ee9a00">)</font><font color="#cd3700">)</font><span><font color="#912f11">)</font></span><br /></font> </div> <p>views.clj defines the pages to show:</p> <div class="codeblock"> <font face="monospace"><br /><font color="#375288"> 1 </font><span><font color="#912f11">(</font></span><span><font color="#800090">ns</font></span> com.my.myproject.runtime.views<br /><font color="#375288"> 2 </font>  <font color="#cd3700">(</font><span><font color="#1f3f81"><b>:use</b></font></span> <span><font color="#912f11">[</font></span>hiccup core page-helpers<span><font color="#912f11">]</font></span><font color="#cd3700">)</font><span><font color="#912f11">)</font></span><br /><font color="#375288"> 3 </font><br /><font color="#375288"> 4 </font><span><font color="#912f11">(</font></span><span><font color="#800090">defn</font></span> index-page <span><font color="#912f11">[]</font></span><br /><font color="#375288"> 5 </font>  <font color="#cd3700">(</font>html<br /><font color="#375288"> 6 </font>    <span><font color="#912f11">[</font></span><span><font color="#1f3f81"><b>:head</b></font></span> <br /><font color="#375288"> 7 </font>     <span><font color="#912f11">[</font></span><span><font color="#1f3f81"><b>:title</b></font></span> <span><font color="#077807">"Welcome"</font></span><span><font color="#912f11">]</font></span> <br /><font color="#375288"> 8 </font>     <span><font color="#912f11">(</font></span>include-css <span><font color="#077807">"/css/style.css"</font></span><span><font color="#912f11">)]</font></span><br /><font color="#375288"> 9 </font>    <span><font color="#912f11">[</font></span><span><font color="#1f3f81"><b>:body</b></font></span><br /><font color="#375288">10 </font>     <span><font color="#912f11">[</font></span><span><font color="#1f3f81"><b>:h1</b></font></span> <br /><font color="#375288">11 </font>       <span><font color="#077807">"Hello World!"</font></span><span><font color="#912f11">]]</font></span><font color="#cd3700">)</font><span><font color="#912f11">)</font></span><br /><font color="#375288">12 </font><br /><font color="#375288">13 </font><span><font color="#912f11">(</font></span><span><font color="#800090">defn</font></span> page-404 <span><font color="#912f11">[]</font></span><br /><font color="#375288">14 </font>  <font color="#cd3700">(</font>html<br /><font color="#375288">15 </font>    <span><font color="#912f11">[</font></span><span><font color="#1f3f81"><b>:head</b></font></span> <br /><font color="#375288">16 </font>     <span><font color="#912f11">[</font></span><span><font color="#1f3f81"><b>:title</b></font></span> <span><font color="#077807">"Sorry"</font></span><span><font color="#912f11">]</font></span> <br /><font color="#375288">17 </font>     <span><font color="#912f11">(</font></span>include-css <span><font color="#077807">"/css/style.css"</font></span><span><font color="#912f11">)]</font></span><br /><font color="#375288">18 </font>    <span><font color="#912f11">[</font></span><span><font color="#1f3f81"><b>:body</b></font></span><br /><font color="#375288">19 </font>     <span><font color="#912f11">[</font></span><span><font color="#1f3f81"><b>:h1</b></font></span> <span><font color="#077807">"Page not found"</font></span><span><font color="#912f11">]]</font></span><font color="#cd3700">)</font><span><font color="#912f11">)</font></span><br /></font> </div> <p>One very nice thing about lein-ring is that it will automatically pick up any changes made in the project. That's right, live changes, no need to wait for the code to compile, restart the server, etc, just refresh the browser and you will see the changes. This is extremely convenient for Web development, especially for experimentation in clojure REPL.</p> <p><b>vimclojure</b></p> <p>I am a vi addict. For my fix, there is a <a href="http://www.vim.org/scripts/script.php?script_id=2501">vimclojure</a> plugin for clojure development with vim. To have dynamic features such as code snippet evaluation, code completion etc, there is a need to start a nailgun server so vimclojure can contact with a clojure REPL. This script is what I use:</p> <div class="codeblock"> <font face="monospace"><br /><font color="#375288"> 1 </font><span><font color="#786000"># clojure jar is also installed in ~/.vim/lib</font></span><br /><font color="#375288"> 2 </font><span><font color="#007080">CL_CP</font></span>=.:~/.vim/lib/*<br /><font color="#375288"> 3 </font><br /><font color="#375288"> 4 </font><span><font color="#1f3f81"><b>if </b></font></span><span><font color="#1f3f81"><b>[</b></font></span> <span><font color="#1f3f81"><b>-f</b></font></span> <span><font color="#1f3f81"><b>"</b></font></span><span><font color="#077807">project.clj</font></span><span><font color="#1f3f81"><b>"</b></font></span> <span><font color="#1f3f81"><b>]</b></font></span><span><font color="#1f3f81"><b>;</b></font></span> <span><font color="#1f3f81"><b>then</b></font></span><br /><font color="#375288"> 5 </font>  <span><font color="#007080">CP</font></span>=<span><font color="#912f11">`lein classpath`</font></span>:<span><font color="#1f3f81"><b>"</b></font></span><span><font color="#800090">$CL_CP</font></span><span><font color="#1f3f81"><b>"</b></font></span><br /><font color="#375288"> 6 </font><span><font color="#1f3f81"><b>else</b></font></span><br /><font color="#375288"> 7 </font>  <span><font color="#007080">CP</font></span>=<span><font color="#1f3f81"><b>"</b></font></span><span><font color="#800090">$CL_CP</font></span><span><font color="#1f3f81"><b>"</b></font></span><br /><font color="#375288"> 8 </font><span><font color="#1f3f81"><b>fi</b></font></span><br /><font color="#375288"> 9 </font><br /><font color="#375288">10 </font><span><font color="#1f3f81"><b>if </b></font></span><span><font color="#1f3f81"><b>[</b></font></span> <span><font color="#800090">$#</font></span> <span><font color="#1f3f81"><b>-eq</b></font></span> <span><font color="#077807">0</font></span> <span><font color="#1f3f81"><b>]</b></font></span><span><font color="#1f3f81"><b>;</b></font></span> <span><font color="#1f3f81"><b>then</b></font></span> <br /><font color="#375288">11 </font>     <span><font color="#1f3f81"><b>exec</b></font></span> java -server -cp <span><font color="#1f3f81"><b>"</b></font></span><span><font color="#800090">$CP</font></span><span><font color="#1f3f81"><b>"</b></font></span> vimclojure.nailgun.NGServer <span><font color="#077807">127</font></span>.<span><font color="#077807">0</font></span>.<span><font color="#077807">0</font></span>.<span><font color="#077807">1</font></span><br /><font color="#375288">12 </font><span><font color="#1f3f81"><b>else</b></font></span><br /><font color="#375288">13 </font>     <span><font color="#1f3f81"><b>exec</b></font></span> java -server -cp <span><font color="#1f3f81"><b>"</b></font></span><span><font color="#800090">$CP</font></span><span><font color="#1f3f81"><b>"</b></font></span> vimclojure.nailgun.NGServer <span><font color="#800090">$1</font></span> <br /><font color="#375288">14 </font><span><font color="#1f3f81"><b>fi</b></font></span><br /></font> </div> <p>I normally run this script in the root directory of the project, this allows "lein classpath" to pick up all the classpaths for the REPL session. There's also a lein-vimclojure plungin that will install vimclojure and start a nailgun server for you, but I found it does not load "user.clj", so my convenient functions defined there are not autoloaded. I will stick to my script.</p> <p>For better navigation of clojure source code, vim users need <a href="http://www.vim.org/scripts/script.php?script_id=273">TagList</a> plugin. The plugin does not automatically work with clojure though. <a href="http://kuriqoo.blogspot.com/2011/02/using-clojure-in-vim.html">This blog post</a> has a solution, and it worked for me. Basically, this tells TagList to treat clojure code just like other Lisp code, which it is. </p> <p>That's all folks.</p> </div></div> <section> <h2>Add new comment</h2> <drupal-render-placeholder callback="comment.lazy_builders:renderForm" arguments="0=node&amp;1=114&amp;2=comment_node_blog&amp;3=comment_node_blog" token="PUkAFqs0FmeR-HUnjiVkRD8xYp20a1wdHTYOrkFacSM"></drupal-render-placeholder> </section> <strong class="node_view"></strong> Mon, 02 May 2011 23:02:25 +0000 Huahai 114 at https://yyhh.org