I'm trying to solve the problem "is Subsequence"
https://leetcode.com/problems/is-subsequence/
in kotlin. I decided to use recursion. The is the solution:
const val first = "abc"
const val second = "ahbgdc"
fun isSubsequence(first: String, second :String): Boolean {
if(first.isEmpty())
return true
if(second.isEmpty())
return false
return subCheck((first.length).minus(1),(second.length).minus(1))
}
fun subCheck(s: Int, t: Int): Boolean {
println("$s $t")
if(s == -1) return true
if(t == -1) return false
if(first[s] == second[t]) subCheck(s.minus(1),t.minus(1))
return subCheck(s,t.minus(1))
}
fun main() {
println(isSubsequence(first, second))
}
I've been struggling to find where the problem is since it always returns false with this input and when I tried to debug it I found that the value of s and t reach -1 and -1. however instead of returning true, the values of s and t change to 0 and -1.
this is the the output of the println statement:
1 4
1 3
1 2
0 1
0 0
-1 -1
0 -1
1 1
1 0
1 -1
2 4
2 3
2 2
2 1
2 0
2 -1
false
I'm writing a function that allows you to remove certain numbers from an int arraylist.
My code
for (i in 1 until 4) {
divider = setDivider(i)
for(index in 0 until numbers.size){
if(index <= numbers.size){
if (numbers[index] % divider == 0 && !isDone) {
numbers.removeAt(index)
}
}else{
isDone = true
}
}
if(isDone)
break
}
the function to set the divider
fun setDivider(divider: Int): Int {
when (divider) {
1 -> return 2
2 -> return 3
3 -> return 5
4 -> return 7
}
return 8
}
I do not know why the ide is giving me the error Index 9 out of bounds for length 9.
Author explained in the comments that the goal is to remove all numbers that are divisible by 2, 3, 5 and 7.
It can be achieved much easier by utilizing ready to use functions from stdlib:
val dividers = listOf(2, 3, 5, 7)
numbers.removeAll { num ->
dividers.any { num % it == 0 }
}
It removes elements that satisfy the provided condition (is divisible) for any of provided dividers.
Also, it is often cleaner to not modify a collection in-place, but to create an entirely new collection:
val numbers2 = numbers.filterNot { num ->
dividers.any { num % it == 0 }
}
This does what I'd expect. fib(13) returns 233.
sub fib(Int $a --> Int) {
return 0 if $a == 0;
return 1 if $a == 1;
return fib($a -1) + fib($a -2);
}
my $square = -> $x { $x * 2 }; # this works with no return value
my #list = <1 2 3 4 5 6 7 8 9>.map( $square );
# returns [2 4 6 8 10 12 14 16 18]
I tried implementing fib() using an anonymous sub
my $fib = -> Int $x --> Int {
return 0 if $x == 0;
return 1 if $x == 1;
return $fib($x - 1) + $fib($x - 2);
}
$fib(13)
I get the following error when running that with explicit returns.
Attempt to return outside of any Routine
in block at test.p6 line 39
So I got rid of the return values.
my $fib = -> Int $x --> Int {
0 if $x == 0;
1 if $x == 1;
$fib($x - 1) + $fib($x - 2);
}
say $fib(13);
This last version never returns. Is there a way to write an anonymous recursive function without return values?
According to the documentation :
Blocks that aren't of type Routine (which is a subclass of Block) are
transparent to return.
sub f() {
say <a b c>.map: { return 42 };
# ^^^^^^ exits &f, not just the block }
The last statement is the implicit return value of the block
So you can try:
my $fib = -> Int $x --> Int {
if ( $x == 0 ) {
0; # <-- Implicit return value
}
elsif ( $x == 1 ) {
1; # <-- Implicit return value
}
else {
$fib($x - 1) + $fib($x - 2); # <-- Implicit return value
}
}
Three more options:
sub
You can write anonymous routines by using sub without a name:
my $fib = sub (Int $x --> Int) {
return 0 if $x == 0;
return 1 if $x == 1;
return $fib($x - 1) + $fib($x - 2);
}
say $fib(13); # 233
See #HåkonHægland's answer for why this (deliberately) doesn't work with non-routine blocks.
leave
The design anticipated your question:
my $fib = -> Int $x --> Int {
leave 0 if $x == 0;
leave 1 if $x == 1;
leave $fib($x - 1) + $fib($x - 2);
}
compiles. Hopefully you can guess that what it does -- or rather is supposed to do -- is exactly what you wanted to do.
Unfortunately, if you follow the above with:
say $fib(13);
You get a run-time error "leave not yet implemented".
My guess is that this'll get implemented some time in the next few years and the "Attempt to return outside of any Routine" error message will then mention leave. But implementing it has very low priority because it's easy to write sub as above, or write code as #HåkonHægland did, or use a case/switch statement construct as follows, and that's plenty good enough for now.
case/switch (when/default)
You can specify the parameter as $_ instead of $x and then you're all set to use constructs that refer to the topic:
my $fib = -> Int $_ --> Int {
when 0 { 0 }
when 1 { 1 }
$fib($_ - 1) + $fib($_ - 2)
}
say $fib(13); # 233
See when.
Blocks don't need to declare the return type. You can still return whatever you want, though. The problem is not in using return, it's in the declaration of the Int.
use v6;
my $fib = -> Int $x {
if $x == 0 {
0;
} elsif $x == 1 {
1;
} else {
$fib($x - 1) + $fib($x - 2);
}
}
say $fib(13) ;
The problem is that the return value needs to be the last executed. In the way you have done it, if it finds 0 or 1 it keeps running, getting to the last statement, when it will start all over again.
Alternatively, you can use given instead of the cascaded ifs. As long as whatever it returns is the last issued, it's OK.
Given the data set below:
a | b | c | d
1 | 3 | 7 | 11
1 | 5 | 7 | 11
1 | 3 | 8 | 11
1 | 5 | 8 | 11
1 | 6 | 8 | 11
Perform a reverse Cartesian product to get:
a | b | c | d
1 | 3,5 | 7,8 | 11
1 | 6 | 8 | 11
I am currently working with scala, and my input/output data type is currently:
ListBuffer[Array[Array[Int]]]
I have come up with a solution (seen below), but feel it could be optimized. I am open to optimizations of my approach, and completely new approaches. Solutions in scala and c# are preferred.
I am also curious if this could be done in MS SQL.
My current solution:
def main(args: Array[String]): Unit = {
// Input
val data = ListBuffer(Array(Array(1), Array(3), Array(7), Array(11)),
Array(Array(1), Array(5), Array(7), Array(11)),
Array(Array(1), Array(3), Array(8), Array(11)),
Array(Array(1), Array(5), Array(8), Array(11)),
Array(Array(1), Array(6), Array(8), Array(11)))
reverseCartesianProduct(data)
}
def reverseCartesianProduct(input: ListBuffer[Array[Array[Int]]]): ListBuffer[Array[Array[Int]]] = {
val startIndex = input(0).size - 1
var results:ListBuffer[Array[Array[Int]]] = input
for (i <- startIndex to 0 by -1) {
results = groupForward(results, i, startIndex)
}
results
}
def groupForward(input: ListBuffer[Array[Array[Int]]], groupingIndex: Int, startIndex: Int): ListBuffer[Array[Array[Int]]] = {
if (startIndex < 0) {
val reduced = input.reduce((a, b) => {
mergeRows(a, b)
})
return ListBuffer(reduced)
}
val grouped = if (startIndex == groupingIndex) {
Map(0 -> input)
}
else {
groupOnIndex(input, startIndex)
}
val results = grouped.flatMap{
case (index, values: ListBuffer[Array[Array[Int]]]) =>
groupForward(values, groupingIndex, startIndex - 1)
}
results.to[ListBuffer]
}
def groupOnIndex(list: ListBuffer[Array[Array[Int]]], index: Int): Map[Int, ListBuffer[Array[Array[Int]]]] = {
var results = Map[Int, ListBuffer[Array[Array[Int]]]]()
list.foreach(a => {
val key = a(index).toList.hashCode()
if (!results.contains(key)) {
results += (key -> ListBuffer[Array[Array[Int]]]())
}
results(key) += a
})
results
}
def mergeRows(a: Array[Array[Int]], b: Array[Array[Int]]): Array[Array[Int]] = {
val zipped = a.zip(b)
val merged = zipped.map{ case (array1: Array[Int], array2: Array[Int]) =>
val m = array1 ++ array2
quickSort(m)
m.distinct
.array
}
merged
}
The way this works is:
Loop over columns, from right to left (the groupingIndex specifies which column to run on. This column is the only one which does not have to have values equal to each other in order to merge the rows.)
Recursively group the data on all other columns (not groupingIndex).
After grouping all columns, it is assumed that the data in each group have equivalent values in every column except for the grouping column.
Merge the rows with the matching columns. Take the distinct values for each column and sort each one.
I apologize if some of this does not make sense, my brain is not functioning today.
Here is my take on this. Code is in Java but could easily be converted into Scala or C#.
I run groupingBy on all combinations of n-1 and go with the one that has the lowest count, meaning largest merge depth, so this is kind of a greedy approach. However it is not guaranteed that you will find the optimal solution, meaning minimize the number k which is np-hard to do, see link here for an explanation, but you will find a solution that is valid and do it rather fast.
Full example here: https://github.com/jbilander/ReverseCartesianProduct/tree/master/src
Main.java
import java.util.*;
import java.util.stream.Collectors;
public class Main {
public static void main(String[] args) {
List<List<Integer>> data = List.of(List.of(1, 3, 7, 11), List.of(1, 5, 7, 11), List.of(1, 3, 8, 11), List.of(1, 5, 8, 11), List.of(1, 6, 8, 11));
boolean done = false;
int rowLength = data.get(0).size(); //4
List<Table> tables = new ArrayList<>();
// load data into table
for (List<Integer> integerList : data) {
Table table = new Table(rowLength);
tables.add(table);
for (int i = 0; i < integerList.size(); i++) {
table.getMap().get(i + 1).add(integerList.get(i));
}
}
// keep track of count, needed so we know when to stop iterating
int numberOfRecords = tables.size();
// start algorithm
while (!done) {
Collection<List<Table>> result = getMinimumGroupByResult(tables, rowLength);
if (result.size() < numberOfRecords) {
tables.clear();
for (List<Table> tableList : result) {
Table t = new Table(rowLength);
tables.add(t);
for (Table table : tableList) {
for (int i = 1; i <= rowLength; i++) {
t.getMap().get(i).addAll(table.getMap().get(i));
}
}
}
numberOfRecords = tables.size();
} else {
done = true;
}
}
tables.forEach(System.out::println);
}
private static Collection<List<Table>> getMinimumGroupByResult(List<Table> tables, int rowLength) {
Collection<List<Table>> result = null;
int min = Integer.MAX_VALUE;
for (List<Integer> keyCombination : getKeyCombinations(rowLength)) {
switch (rowLength) {
case 4: {
Map<Tuple3<TreeSet<Integer>, TreeSet<Integer>, TreeSet<Integer>>, List<Table>> map =
tables.stream().collect(Collectors.groupingBy(t -> new Tuple3<>(
t.getMap().get(keyCombination.get(0)),
t.getMap().get(keyCombination.get(1)),
t.getMap().get(keyCombination.get(2))
)));
if (map.size() < min) {
min = map.size();
result = map.values();
}
}
break;
case 5: {
//TODO: Handle n = 5
}
break;
case 6: {
//TODO: Handle n = 6
}
break;
}
}
return result;
}
private static List<List<Integer>> getKeyCombinations(int rowLength) {
switch (rowLength) {
case 4:
return List.of(List.of(1, 2, 3), List.of(1, 2, 4), List.of(2, 3, 4), List.of(1, 3, 4));
//TODO: handle n = 5, n = 6, etc...
}
return List.of(List.of());
}
}
Output of tables.forEach(System.out::println)
Table{1=[1], 2=[3, 5, 6], 3=[8], 4=[11]}
Table{1=[1], 2=[3, 5], 3=[7], 4=[11]}
or rewritten for readability:
a | b | c | d
--|-------|---|---
1 | 3,5,6 | 8 | 11
1 | 3,5 | 7 | 11
If you were to do all this in sql (mysql) you could possibly use group_concat(), I think MS SQL has something similar here: simulating-group-concat or STRING_AGG if SQL Server 2017, but I think you would have to work with text columns which is a bit nasty in this case:
e.g.
create table my_table (A varchar(50) not null, B varchar(50) not null,
C varchar(50) not null, D varchar(50) not null);
insert into my_table values ('1','3,5','4,15','11'), ('1','3,5','3,10','11');
select A, B, group_concat(C order by C) as C, D from my_table group by A, B, D;
Would give the result below, so you would have to parse and sort and update the comma separated result for any next merge iteration (group by) to be correct.
['1', '3,5', '3,10,4,15', '11']
I've seen that this is possible in other languages but need something like this in objective-c
I have an enum similar to this
typedef enum {
option1 = 1 << 0,
option2 = 1 << 1,
option3 = 1 << 2
...
...
} SomePossibleOptions;
and then a user can create a mask of the wanted options
SomePossibleOptions myOptions = option1 | option2;
[self.someObject performOperationsForOptions:myOptions];
-(void)performOperationsForOptions:(SomePossibleOptions)theOptions
{
if (myOptions & option1)
{
// do something
}
if (myOptions & option2
{
// do something
}
//(could use a switch statement)
}
But would much rather use some sort of syntax
foreach (option in myoption)
{
//do something
}
Sometimes I use a last value in my normal enums called "SomeEnumCount", which then has exactly the number of items I have in the enum, so I can make a loop for that.
In your case it would be something like this:
typedef enum {
option1 = 1 << 0,
option2 = 1 << 1,
option3 = 1 << 2,
...
...
optionCount = 1 << n
} SomePossibleOptions;
Or maybe you can call it OptionNone, if you have one like that, and that would be always the last one.
And to make a loop you have to make something like this
NSInteger optionsCount = (int)log2(optionCount);
for (NSInteger i = 0; i < optionsCount; i++) {
SomePossibleOptions option = (SomePossibleOptions)(1 << i);
//handle your options here
}
I hope it helps!
EDIT: Maybe I misunderstood the question. If you want to loop on just the options that are masked together, you should write a function, based on the above. Something like:
- (NSArray *)optionsInMask:(SomePossibleOptions)maskedOptions {
NSMutableArray * options = [NSMutableArray array];
NSInteger optionsCount = (int)log2(optionCount);
for (NSInteger i = 0; i < optionsCount; i++) {
SomePossibleOptions option = (SomePossibleOptions)(1 << i);
if (maskedOptions & option) {
[options addObject:[NSValue valueWithInteger:option]];
}
}
return [NSArray arrayWithArray:options];
}
And then you can loop it like:
for (NSValue * value in [self optionsInMask:myOptions]) {
SomePossibleOption option = (SomePossibleOptions)[value integerValue];
//your code here
}