Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Toni Day 4 #11

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open

Toni Day 4 #11

wants to merge 1 commit into from

Conversation

tonilopezmr
Copy link
Member

Toni's solution for day 4 challenge

Description

Easy day, I have created the recursive and iterative solution.
But the Recursive one, has parts with iterative loops :( any ideas??

Solution

Part 1

fun valid(passphrase: String): Boolean {
    val list = LinkedList(passphrase.split(" "))
    val element = list.poll()
    return validR(list, element)
  }

  tailrec fun validR(passphrase: LinkedList<String>, element: String): Boolean =
      if (passphrase.isEmpty()) true
      else if (passphrase.contains(element)) false
      else {
        val element = passphrase.poll()
        validR(passphrase, element)
      }

  fun countValid(passphrase: List<String>): Int = passphrase
      .fold(0) { acc, a -> if (valid(a)) acc + 1 else acc }

Part 2

fun containsInAnyOrder(passphrase: List<String>, element: String): Boolean =
          passphrase.fold(false) { bcc, b ->
            if (equalsInAnyOrder(element, b)) true
            else bcc
          }

  fun equalsInAnyOrder(a: String, b: String): Boolean = a.fold(true) { acc, it ->
    if (a.length != b.length) false else acc && b.contains(it)
  }

  fun valid(passphrase: String): Boolean {
    val list = LinkedList(passphrase.split(" "))
    val element = list.poll()
    return validR(list, element)
  }

  tailrec fun validR(passphrase: LinkedList<String>, element: String): Boolean =
      if (passphrase.isEmpty()) true
      else if (containsInAnyOrder(passphrase, element)) false
      else {
        val element = passphrase.poll()
        validR(passphrase, element)
      }

  fun countValid(passphrase: List<String>): Int = passphrase
      .fold(0) { acc, a -> if (valid(a)) acc + 1 else acc }

Tests battery

always the same hahah

Happy Advent of Code!

@tonilopezmr tonilopezmr changed the title Day 4 Toni Day 4 Dec 4, 2017
Copy link
Member

@Cotel Cotel left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Quite good. Using Kotlin collection operators will help you a lot 👍


fun valid(passphrase: String): Boolean {
val list = LinkedList(passphrase.split(" "))
val element = list.poll()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suppose you are using LinkedList to get Dequeue behaviour. But did you know you could the same with an immutable list? (Just a bit uglier though, but in Kategory they have implemented methods for (x : xs) haskell notation like)

val list = listOf(1,2,3)
val (head, tail) = Pair(list.first, list.drop(1))
// head -> 1
// tail -> listOf(2,3)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You are droping in the same way, Yes I did with LinkedList to work like (x :xs)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Except, drop is immutable. It returns a new list.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, In kategory, we have several issues with OutOfMemory with drop in ListKW.fold for many elements 👎

else {
val element = passphrase.poll()
validR(passphrase, element)
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why are you using tailrec? Did the IDE suggested it to you or you knew you had to use it?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No! tailrec is for recursion optimization, tailrec coerce to call the method only in the last operation in return https://kotlinlang.org/docs/reference/functions.html and https://medium.com/@JorgeCastilloPr/tail-recursion-and-how-to-use-it-in-kotlin-97353993e17f

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Interesting, I will search if Scala has a tailrec reserved word too 👍

}

fun countValid(passphrase: List<String>): Int = passphrase
.fold(0) { acc, a -> if (valid(a)) acc + 1 else acc }
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You could simplify this like this

fun countValid(passphrase: List<String>): Int = passphrase.count(::valid)

acc
}
}
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess you could simplify this to

return words.all { word -> words.count { it == word } <= 1 }  

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

wooooot?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

all checks all the elements in a collection fulfill a predicate.

count counts how many items in a collection fulfill a predicate.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

too much magic behind this methods

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Declarative magic 😉

fun `in list with 5 passphrase elements only 2 are valid`() {
assertEquals(2, countValid(listOf(
"aa bb cc dd cc",
"miguel say my name miguel",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

😏

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💘


fun equalsInAnyOrder(a: String, b: String): Boolean = a.fold(true) { acc, it ->
if (a.length != b.length) false else acc && b.contains(it)
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is okay but you can check if you strings are anagrams if you sort them and they are equal. That will simplify your solution a lot 👍

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes but I don't what is better for performance? good thought

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't know what will be the cost of sort integrated method. But right now you have 4 nested loops. @JoseLlorensRipolles and me only have 2, I think, and we are using this approach.

@tonilopezmr
Copy link
Member Author

tonilopezmr commented Dec 4, 2017

Please NOT MERGE THIS PR I want see the @Cotel simplifications another day!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants