<p>I was going through the Go Tour when my friend gave me the following puzzle:</p>
<p>Make 24 by combining the numbers 1, 3, 4, and 6 using the usual operators +, -, *, and /, and parentheses. You may use each of 1, 3, 4, 6 only once.</p>
<p>It's a pretty tricky puzzle; with most sets of 4 single digit numbers it's relatively easy but this variant has only one solution. I couldn't figure it out myself, so I wrote a Go program to do it!</p>
<p>Link: <a href="https://play.golang.org/p/ghehA5iiWv">https://play.golang.org/p/ghehA5iiWv</a></p>
<p>(Running the program will print the answer, so <strong>don't run it if you want to do the puzzle yourself</strong>.)</p>
<p>Mostly looking to make it more idiomatic, simpler, better style. Note that beyond solving the problem, I wanted to print the answer in a pleasing format. Hence the struct <code>Num</code> that documents how each value is derived (though I don't know if this is the best way to do it). Thanks in advance!</p>
<hr/>**评论:**<br/><br/>adonovan76: <pre><p>Fun problem! I couldn't resist attacking it myself; you can see my alternative approach here:
<a href="http://play.golang.org/p/YBxXcB-D7R" rel="nofollow">http://play.golang.org/p/YBxXcB-D7R</a></p></pre>jeffrallen: <pre><p>Welcome to Go! Great work getting yourself this far and asking for a review.</p>
<p>Here's some comments:</p>
<ol>
<li><p>This program is not big enough to be written particularly idiomatically. Go's most important idioms are related to how data moves across package boundaries, how objects are composed, etc.</p></li>
<li><p>Kind of too bad that the 24 is hardcoded in find24. Not to mention in the name of the function! Wouldn't it be possible to ask this program how to make other integers out of the numbers?</p></li>
<li><p>Globals = bad. In this tiny program, the global "solutions" is an ok solution. But would it have been possible to make find24 return a slice of solutions and build up that slice using "solutions = append(solutions, find24(new_nums))".</p></li>
<li><p>I really like the slice of functions called ops. A comment explaining why there are 6 ops and not 4 would be welcome.</p></li>
<li><p>The loop to make new_nums does not say what it is doing. It would be easer to read if the inner loop was like "for j, y := range remove(nums, x)"</p></li>
<li><p>Your program divides. Division by zero will ruin your user's day. I can see why it doesn't happen with these numbers. But to be more general, you should protect against div/0.</p></li>
<li><p>floating point numbers and == are not a good fit. The general solution it to subtract the result from the target and check to see if the absolute value of the resulting difference is less than an epsilon.</p>
<p>-jeff</p></li>
</ol></pre>swimmer91: <pre><p>I think this is pretty good! It's clean and well-structured. The documentation is sufficient, but not overdone. It works too, which is of course the most important thing! haha</p>
<p>A few things:</p>
<ol>
<li><p>Stylistically, I would make find24 a pure function. That is, I would have it take in a slice of numbers and return a slice of solutions.</p></li>
<li><p>I would also make find24 take in a slice of primitives (either ints or floats). Then convert them into Num types yourself. That way the caller doesn't have to deal with Num structs.</p></li>
<li><p>A comment indicating that 'solutions' is being used as a set would be nice. I mean it's pretty apparent from reading the code, but it's always a good idea to explain why you're doing something abnormal. Idk, maybe this is more of an accepted idiom than I realize.</p></li>
<li><p>If you're concerned with printing the answer in a pleasing format, perhaps print "no solutions found" rather than nothing.</p></li>
<li><p>It doesn't work with irreducible fractions containing primes. A trivial example is [5, (24/5)]. Perhaps you should just limit the function to taking in integers. Or find a way to make it work for any set of floats.</p></li>
<li><p>I haven't actually spent time evaluating this, but if you're using recursion and not memoizing, you're probably doing extra work. This isn't actually a big deal as your function is fast enough for its use case. However, just be aware that recursive functions like this can blow up without memoization (even then, it needs to be thought out). <a href="http://rayhightower.com/blog/2014/04/12/recursion-and-memoization/" rel="nofollow">Here's an example with a function which calculates fibonacci(n)</a>. In the non-memoized version, the number of computations blows up exponentially. The memoized version is O(n). Pretty big difference!</p></li>
</ol>
<p>So yeah, overall, this looks really good! All the points I brought up are pretty minor.</p></pre>
这是一个分享于 的资源,其中的信息可能已经有所发展或是发生改变。
入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889
- 请尽量让自己的回复能够对别人有帮助
- 支持 Markdown 格式, **粗体**、~~删除线~~、
`单行代码`
- 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
- 图片支持拖拽、截图粘贴等方式上传