https://kotlinlang.org logo
#codereview
Title
# codereview
s

skendrick

10/03/2019, 2:55 PM
Hi 😄, Here’s a programming puzzle I solved with Kotlin. Please pick it apart, if ya like! I’ve been doing Kotlin for like 5 days. But also lemme know if the approach was off or unclear! tldr problem description: print a diamond start from A to
someLetter
Copy code
··A··
·B·B·
C···C
·B·B·
··A··
The problem description & the solution: https://gist.github.com/adnauseum/4a7c9762d57f3b82b1dd18b1204af3cb If you want to review it, 1) thanks, 2) leave a comment in a thread or on the gist—whatever is easiest for you. 🙇 THANK YOU! Actually, the fact that anybody would leave a comment is mind-blowing, so thanks for even reading and putting in the effort!
👍 3
t

Timmy

10/03/2019, 7:02 PM
Looks good! I did the challenge before looking at your code and came up with the same algorithm and mostly the same code. Here is what I did differently: - Since no OOP is involved a top level function is enough, no need for the DiamondPrinter class - My return type is the complete string (non-nullable). Your list is fine but should be non-nullable - I used mapIndexed, which does the same as .withIndex().map {} - I used dropLast(1) instead of slice() since it has a more readable meaning - In the when statement multiple conditions have the same effect, so combine them like so:
leftOfMiddleIndex, rightOfMiddleIndex -> letter
- Skipped some variable definitions (leftOfMiddleIndex and rightOfMiddleIndex) and just inlined them to where they are used (not that important) - I used an imperative approach to constructing the lines with stringBuilder (
repeat(numLettersPerRow) {append(...)}
). Might be more performant than constructing a list then joining it, but at this scale it doesn't matter. Actually I like your approach better. - Used a + instead of .plus() - I didn't use a separate function makeRow and just had that in the lambda. If you want to keep your makeRow function, use a method reference (
lettersUsedInDiamond.mapIndexed(::makeRow)
)
s

skendrick

10/03/2019, 7:07 PM
Ahh, this is perfect! The class and return type were part of the website’s requirement I found the problem on exercism.io (hate the name of that site) 😄. These are great insights! THANK YOU!!! 😄
Wow, @Timmy, just implemented your suggestions. These were exactly the things I was looking for. Tytyty 🙇
Now, how can I get this whole thing to be one line of code 🤔 😆
b

bjonnh

10/08/2019, 11:21 PM
fun diamond(size: Int): List<String> { require(size in 1..26) return (0 until size).map { var str = "" repeat (size-it-1) { str += "." } str += (it+65).toChar() repeat (2*it-1) { str += "." } if (it!=0) str += (it+65).toChar() repeat (size-it-1) { str+="." } str += "\n" str }.let { it + it.dropLast(1).reversed() } }
is one way
fun diamond(size: Int): List<String> { require(size in 1..26) return (0 until size).map { var str = "" repeat (size-it-1) { str += "." } str += (it+65).toChar() repeat (2*it-1) { str += "." } str }.mapIndexed { index, it -> it+it.dropLast(max(2*index-1,1)).reversed()+"\n" } .let { it + it.dropLast(1).reversed() } }
that's another way that use symmetry
And this is an even more functional way:
fun diamond(size: Int): List<String> { require(size in 1..26) return (0 until size).map { i -> (i + 65).toChar().let { c -> Array(size * 2 - 1) { '.' }.also { it[size - i - 1] = c it[size + i - 1] = c }.joinToString("") + "\n" } }.let { it + it.dropLast(1).reversed() } }
🍝 1
3 Views