Kotlin Coding with Codility

Content Table:


Find Out the number of interesting Clock with Kotlin


fun main() {
	val count = solution("15:15:00", "15:15:12")
	println(count)
}

fun solution(S: String, T: String): Int {
	val s = S.split(":")
	val t = T.split(":")
	
	val sH = strToTime(s[0])
	val sM = strToTime(s[1])
	val sS = strToTime(s[2])
	
	val tH = strToTime(t[0])
	val tM = strToTime(t[1])
	val tS = strToTime(t[2])
	
	var total = 0
	
	for (h in sH..tH) {
		if(h < tH) {
			for (m in 0..59) {
				for (s in 0..59) {
					if(interestingClock(h,m,s)) total++
				}
			}
		} else {
			for (m in sM..tM) {
				if(m < tM) {
					for (s in 0..59) {
						if(interestingClock(h,m,s)) total++
					}				
				}else {
					for (s in sS..tS) {
						if(interestingClock(h,m,s)) total++
					}				
				}
			}			
		}
	}
	
	return total
}

fun interestingClock(h: Int, m: Int, s: Int): Boolean {
	val list: MutableList<Int> = arrayListOf()
    list.addAll(numToList(h))
    list.addAll(numToList(m))
	list.addAll(numToList(s))
   
    if (list.distinct().count() <= 2)
		return true
	else 
    	return false
}

fun numToList(num: Int): List<Int> {
	val list: MutableList<Int> = mutableListOf()
    if(num < 10){
    	list.add(0)
    	list.add(num)
    }else {
    	list.add(num % 10)
    	list.add(num/10)
    }
    
    return list
}

fun strToTime(s:String): Int {
	if(s.startsWith("0")){
		val chars: Array<Char> = s.toCharArray().toTypedArray()
		return Character.getNumericValue(chars[1])
	}
	
	return s.toInt()
}

Count number of occurrences (or frequency) in a sorted array

Count number of occurrences (or frequency) in a sorted array
Expected time complexity is O(Logn)

– Example:


Input: arr[] = {1, 1, 2, 2, 2, 2, 3,},   x = 2
Output: 4 // x (or 2) occurs 4 times in arr[]

Solution -> Improved Binary Search
1) Use Binary search to get index of the first occurrence of x in arr[]. Let the index of the first occurrence be i.
2) Use Binary search to get index of the last occurrence of x in arr[]. Let the index of the last occurrence be j.
3) Return (j – i + 1);


import java.util.*

fun main() {
	var A = intArrayOf(1, 2, 2, 3, 4)
	println(solution(A, 2))
}

fun solution(A: IntArray, x: Int): Int {
	
	if (A.size == 0)
		return -1
	
	var leftOccur = binarySearchLeftMostOccurs(A, x, 0, A.size - 1)
	var rightOccur = leftOccur
	
	if (leftOccur == -1)
		return -1
	else {
		rightOccur = binarySearchRightMostOccurs(A, x, leftOccur, A.size - 1)
	} 
	
	return rightOccur - leftOccur + 1
}

fun binarySearchLeftMostOccurs(A: IntArray, x: Int, leftmost: Int, rightmost: Int): Int {

	if(leftmost == rightmost) {
		if (A[leftmost] == x) {
			return leftmost
		}
		
		return -1
	}
	
	var pivot = (leftmost + rightmost) / 2
	
	if(A[pivot] == x && ((pivot == leftmost) || (A[pivot - 1] < A[pivot]))) {
		return pivot
	}
	
	if(A[pivot] >= x){
		return binarySearchLeftMostOccurs(A, x, leftmost, pivot)
	}else {
		return binarySearchLeftMostOccurs(A, x, pivot + 1, rightmost)
	}
}

fun binarySearchRightMostOccurs(A: IntArray, x: Int, leftmost: Int, rightmost: Int): Int {
	if(leftmost == rightmost) {
		if (A[rightmost] == x) {
			return rightmost
		}
		
		return -1
	}
	
	var pivot = (leftmost + rightmost) / 2
	
	if(A[pivot] == x && ((pivot == rightmost) || (A[pivot] < A[pivot + 1]))) {
		return pivot
	}
	
	if(A[pivot] <= x){
		return binarySearchRightMostOccurs(A, x, pivot + 1, rightmost)
	}else {
		return binarySearchRightMostOccurs(A, x, leftmost, pivot)
	}
}

Spring Boot RabbitMQ Multiple Consumers Example

– Tutorial: “Spring Boot Rabbitmq Multiple Consumers Example using RabbitMq Exchange to Exchange Topology – Spring Boot Rabbitmq Multiple Listeners”

In the post, I show you how to work with SpringBoot RabbitMq Exchange to Exchange Topology to develop an example “Rabbitmq Multiple Queues and Multiple Listeners”.

* Technologies:

– Java 8
– Maven
– Spring Tool Suite
– Spring Boot
– RabbitMq

RabbitMq Exchange to Exchange – Spring Boot Rabbitmq Multiple Consumers Example

We create a RabbitMQ topology with 2 topic exchanges and 3 binding queues:

Spring Boot Rabbitmq Multiple Queue - with Exchange Topic Architecture
Spring Boot Rabbitmq Multiple Queue – with Exchange Topic Architecture

Scenarios with above design:
– when we send a message with routing key: sys.prod.info, it will be delivered by path: X1 -> Q3.
– when we send a message with routing key: app.prod.error, it will be delivered by path: X1 -> X2 -> {Q2, Q3}.
– when we send a message with routing key: sys.test.error, it will be delivered by path: X1 -> X2 -> Q1.

Practices – Spring Boot Rabbitmq Multiple Consumers Example

In the tutorial, we create 2 SpringBoot project as below:

Spring Boot RabbitMQ Topic - Project Structure
Spring Boot RabbitMQ Topic – Project Structure

– Step to do:
– Create SpringBoot projects
– Define data model
– Implement RabbitMq Producer
– Implement RabbitMq consumer
– Run and check results

Create SpringBoot projects

Using SpringToolSuite, create 2 SpringBoot projects, then add need dependency spring-boot-starter-amqp:


<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-amqp</artifactId>
</dependency>

Define Spring Data Model – Spring Boot Rabbitmq Multiple Consumers Example

Create Log data model for both projects:


package com.loizenai.rabbitmq.model;
 
public class Log {
	private String content;
	private String routingKey;
	
	public Log(){};
	
	public Log(String content, String routingKey){
		this.content = content;
		this.routingKey = routingKey;
	}
	
	public String getContent(){
		return this.content;
	}
	
	public void setContent(String content){
		this.content = content;
	}
	
	public String getRoutingKey(){
		return this.routingKey;
	}
	
	public void setRoutingKey(String routingKey){
		this.routingKey = routingKey;
	}
	
	@Override
	public String toString() {
		return String.format("{content = %s, routingKey = %s}", content, routingKey);
	}
}

Now it’s time for implementation. Let’s go!

Configure SpringBoot RabbitMq Producer – Spring Boot Rabbitmq Multiple Consumers Example


package com.loizenai.rabbitmq.config;
 
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
import org.springframework.amqp.support.converter.MessageConverter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
 
@Configuration
public class RabbitMqConfig {
	
    @Bean
    public MessageConverter jsonMessageConverter(){
        return new Jackson2JsonMessageConverter();
    }
    
    public AmqpTemplate rabbitTemplate(ConnectionFactory connectionFactory) {
        final RabbitTemplate rabbitTemplate = new RabbitTemplate(connectionFactory);
        rabbitTemplate.setMessageConverter(jsonMessageConverter());
        return rabbitTemplate;
    }
}

Open application.properties, add configuration:


spring.rabbitmq.host=localhost
spring.rabbitmq.port=5672
spring.rabbitmq.username=guest
spring.rabbitmq.password=guest
jsa.rabbitmq.exchange=jsa.exchange.logs
jsa.rabbitmq.queue=jsa.queue
jsa.rabbitmq.routingkey=jsa.routingkey

Implement SpringBoot RabbitMq Producer


package com.loizenai.rabbitmq.producer;
 
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
 
import com.loizenai.rabbitmq.model.Log;
 
@Component
public class Producer {
	
	@Autowired
	private AmqpTemplate amqpTemplate;
	
	@Value("${jsa.rabbitmq.exchange}")
	private String exchange;
	
	public void produce(Log logs){
		String routingKey = logs.getRoutingKey();
		amqpTemplate.convertAndSend(exchange, routingKey, logs);
		System.out.println("Send msg = " + logs);
	}
}

Implement SpringBoot RabbitMQ Producer Client


package com.loizenai.rabbitmq;
 
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
 
import com.loizenai.rabbitmq.model.Log;
import com.loizenai.rabbitmq.producer.Producer;
 
@SpringBootApplication
public class SpringRabbitMqProducerApplication  implements CommandLineRunner{
 
	public static void main(String[] args) {
		SpringApplication.run(SpringRabbitMqProducerApplication.class, args);
	}
	
	@Autowired
	Producer producer;
 
	@Override
	public void run(String... args) throws Exception {
		
		/**
		 *  1
		 */
		String content = "2014-03-05 10:58:51.1  INFO 45469 --- [           main] org.apache.catalina.core.StandardEngine  : Starting Servlet Engine: Apache Tomcat/7.0.52";
		String routingKey = "sys.dev.info";
		
		// send to RabbitMQ
		producer.produce(new Log(content, routingKey));
		
		/**
		 *  2
		 */
		content = "2017-10-10 10:57:51.10 ERROR in ch.qos.logback.core.joran.spi.Interpreter@4:71 - no applicable action for [springProperty], current ElementPath is [[configuration][springProperty]]";
		routingKey = "sys.test.error";
		
		// send to RabbitMQ
		producer.produce(new Log(content, routingKey));
		
		/**
		 *  3
		 */
		content = "2017-10-10 10:57:51.112  ERROR java.lang.Exception: java.lang.Exception";
		routingKey = "app.prod.error";
		
		// send to RabbitMQ
		producer.produce(new Log(content, routingKey));
	}
}

Configure SpringBoot RabbitMQ Consumer


package com.loizenai.rabbitmq.config;
 
import org.springframework.amqp.rabbit.config.SimpleRabbitListenerContainerFactory;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
import org.springframework.amqp.support.converter.MessageConverter;
import org.springframework.boot.autoconfigure.amqp.SimpleRabbitListenerContainerFactoryConfigurer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
 
@Configuration
public class RabbitMqConfig {
	
    @Bean
    public MessageConverter jsonMessageConverter(){
        return new Jackson2JsonMessageConverter();
    }
    
    @Bean
    public SimpleRabbitListenerContainerFactory jsaFactory(ConnectionFactory connectionFactory,
            SimpleRabbitListenerContainerFactoryConfigurer configurer) {
        SimpleRabbitListenerContainerFactory factory = new SimpleRabbitListenerContainerFactory();
        configurer.configure(factory, connectionFactory);
        factory.setMessageConverter(jsonMessageConverter());
        return factory;
    }
}

Open application.properties, add configuration:


spring.rabbitmq.host=localhost
spring.rabbitmq.port=5672
spring.rabbitmq.username=guest
spring.rabbitmq.password=guest
jsa.rabbitmq.queue=jsa.queue.logs.application-error
#jsa.rabbitmq.queue=jsa.queue.logs.system-error
#jsa.rabbitmq.queue=jsa.queue.logs.production

Implement SpringBoot RabbitMQ Consumer


package com.loizenai.rabbitmq.consumer;

import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;

import com.loizenai.rabbitmq.model.Log;

@Component
public class Consumer {
	
    @RabbitListener(queues="${jsa.rabbitmq.queue}", containerFactory="jsaFactory")
    public void recievedMessage(Log logs) {
        System.out.println("Recieved Message: " + logs);
    }
}

Run and Check Results – Spring Boot Rabbitmq Multiple Consumers Example

– Setup RabbitMq exchange, queues:

Enable rabbitmq_management by cmd: rabbitmq-plugins enable rabbitmq_management --online. Then go to: http://localhost:15672 -> login with user/password: guest/guest.

– Add RabbitMQ exchanges:

Go to http://localhost:15672/#/exchanges, add 2 exchanges: {jsa.exchange.logs, jsa.exchange.logs.error}.

Spring Boot RabbitMQ Topic Connection
Spring Boot RabbitMQ Topic Connection

– Add RabbitMQ Queue:

Go to http://localhost:15672/#/queues, add 3 queues: {jsa.queue.logs.application-error, jsa.queue.logs.system-error, jsa.queue.logs.production}.

Spring Boot Rabbitmq Topic Create Exchange
Spring Boot Rabbitmq Topic Create Exchange

– Binding the queues & exchanges:

Spring Boot RabbitMQ Topic 2 Queue 1
Spring Boot RabbitMQ Topic 2 Queue 1
SpringBoot RabbitMQ Topic Exchange Bindling -
SpringBoot RabbitMQ Topic Exchange Bindling

– Run SpringBoot-RabbitMQ-Producer with commandline mvn spring-boot:run,

-> Console’s logs:


Send msg = {content = 2014-03-05 10:58:51.1  INFO 45469 --- [           main] org.apache.catalina.core.StandardEngine  : Starting Servlet Engine: Apache Tomcat/7.0.52, routingKey = sys.prod.info}
Send msg = {content = 2017-10-10 10:57:51.10 ERROR in ch.qos.logback.core.joran.spi.Interpreter@4:71 - no applicable action for [springProperty], current ElementPath is [[configuration][springProperty]], routingKey = sys.test.error}
Send msg = {content = 2017-10-10 10:57:51.112  ERROR java.lang.Exception: java.lang.Exception, routingKey = app.prod.error}

– See queues’ status:

Springboot Rabbitmq Topic After Consume in jsa_logs_sys
Springboot Rabbitmq Topic After Consume in jsa_logs_sys

– Run SpringBoot-RabbitMQ-Consumer which listen to jsa.queue.logs.application-error queue with configuration:

jsa.rabbitmq.queue=jsa.queue.logs.application-error:

– Console’s logs:


Recieved Message: {content = 2017-10-10 10:57:51.112  ERROR java.lang.Exception: java.lang.Exception, routingKey = app.prod.error}

– Run SpringBoot-RabbitMQ-Consumer which listen to jsa.queue.logs.system-error queue with configuration:

jsa.rabbitmq.queue=jsa.queue.logs.system-error:

-> Console’s logs:


Recieved Message: {content = 2017-10-10 10:57:51.10 ERROR in ch.qos.logback.core.joran.spi.Interpreter@4:71 - no applicable action for [springProperty], current ElementPath is [[configuration][springProperty]], routingKey = sys.test.error}

– Run SpringBoot-RabbitMQ-Consumer which listen to jsa.queue.logs.production queue with configuration:

jsa.rabbitmq.queue=jsa.queue.logs.production:

– Console’s logs:


Recieved Message: {content = 2014-03-05 10:58:51.1  INFO 45469 --- [           main] org.apache.catalina.core.StandardEngine  : Starting Servlet Engine: Apache Tomcat/7.0.52, routingKey = sys.prod.info}
Recieved Message: {content = 2017-10-10 10:57:51.112  ERROR java.lang.Exception: java.lang.Exception, routingKey = app.prod.error}

Read More

Related posts:


– Reference Link: RabbitMQ Exchange Topic

SourceCode

SpringBoot-RabbitMQ-Producer
SpringBoot-RabbitMQ-Consumer

Sequelize belongstomany Example – Nodejs/Express

– Tutorial “Sequelize belongstomany Example – Sequelize Many to Many Association Example with Nodejs/Express + MySQL”

In the post, we got started with Sequelize One-To-Many association. Today we’re gonna create Sequelize Many-To-Many association models with NodeJS/Express, MySQL.

Continue reading “Sequelize belongstomany Example – Nodejs/Express”

Kotlin Map to List Example

In the tutorial, I show how to convert Kotlin Map to List with detail steps and clearly examples.

Convert Kotlin Map to List with Basic Method

– Use public fun Map.toList(): List to returns a [List] containing all key-value pairs:


val simpleMap = hashMapOf("foo" to 1, "bar" to 2)
val pairKeyValueList = simpleMap.toList()
println(pairKeyValueList) // [(bar, 2), (foo, 1)]

– Use public Collection values() to return a view of the values:


val valueList = simpleMap.values
println(valueList) // [2, 1]

– Use public Set keySet() to return a set view of the keys:


val keyList = simpleMap.keys
println(keyList) // [bar, foo]

Convert Map to List in Kotlin with Map Object

– When working with Map Object, we can associate with map(transform: (T) -> R) function to customize a returned-list:

val custStores = mutableMapOf<Long, Customer>()
custStores.put(1, Customer("Jack", 20, Address("NANTERRE CT", "77471")))
custStores.put(2, Customer("Peter", 25, Address("W NORMA ST", "77009")))
 
val addressList = custStores.values.map{ x -> x.address }
println(addressList) // [Address(street=NANTERRE CT, postcode=77471), Address(street=W NORMA ST, postcode=77009)]

– Use MutableList interface to modifiable list:

var mutableAddressList: MutableList<Address> = mutableListOf<Address>();
mutableAddressList.addAll(custStores.values.map{ x -> x.address })
mutableAddressList.add(Address("E NAVAHO TRL", "77449"));
println(mutableAddressList) // [Address(street=NANTERRE CT, postcode=77471), Address(street=W NORMA ST, postcode=77009), Address(street=E NAVAHO TRL, postcode=77449)]

Create Kotlin Model

– Create an Address model:

data class Address(
  var street : String? = null,
  var postcode : String? = null
){}

– Create an Customer model:

data class Customer(
  var name: String? = null,
  var age: Int? = null,
  var address: Address = Address()) {
}

Kotlin Program Map to List

fun main(args : Array) {
  //
  // 1. Work with basic Map
  //
  val simpleMap = hashMapOf("foo" to 1, "bar" to 2)
  println(simpleMap) // {bar=2, foo=1}
  
  // 1.1 a List with pair Key-Value 
  val pairKeyValueList = simpleMap.toList()
  println(pairKeyValueList) // [(bar, 2), (foo, 1)]
  
  // 1.2 a List with values
  val valueList = simpleMap.values
  println(valueList) // [2, 1]
  
  // 1.3 a List with keys 
  val keyList = simpleMap.keys
  println(keyList) // [bar, foo]
  
  //
  // 2. Work with Object Map
  //
  val custStores = mutableMapOf()
  custStores.put(1, Customer("Jack", 20, Address("NANTERRE CT", "77471")))
  custStores.put(2, Customer("Peter", 25, Address("W NORMA ST", "77009")))
  println(custStores); // {1=Customer(name=Jack, age=20, address=Address(street=NANTERRE CT, postcode=77471)), 2=Customer(name=Peter, age=25, address=Address(street=W NORMA ST, postcode=77009))}
  
  // 2.1 a List with pair Key-Value Objects
  val pairKeyValueCustList = custStores.toList();
  println(pairKeyValueCustList) // [(1, Customer(name=Jack, age=20, address=Address(street=NANTERRE CT, postcode=77471))), (2, Customer(name=Peter, age=25, address=Address(street=W NORMA ST, postcode=77009)))]
  
  // 2.2 a List with Object Values
  val customersList = custStores.values
  println(customersList) // [Customer(name=Jack, age=20, address=Address(street=NANTERRE CT, postcode=77471)), Customer(name=Peter, age=25, address=Address(street=W NORMA ST, postcode=77009))]
  
  // 2.3 Customize Objects with map function: (Customer -> Address)
  val addressList = custStores.values.map{ x -> x.address }
  println(addressList) // [Address(street=NANTERRE CT, postcode=77471), Address(street=W NORMA ST, postcode=77009)]
  
  // 2.4 Using MutableList interface for a modifiable List
  var mutableAddressList: MutableList
= mutableListOf
(); mutableAddressList.addAll(custStores.values.map{ x -> x.address }) mutableAddressList.add(Address("E NAVAHO TRL", "77449")); println(mutableAddressList) // [Address(street=NANTERRE CT, postcode=77471), Address(street=W NORMA ST, postcode=77009), Address(street=E NAVAHO TRL, postcode=77449)] }

– Reference: Kotlin Collection Transformations

– Related posts: