How to remake the program so that words are passed in function arguments in the KOTLIN programming language? - kotlin

Need to create a function that implements the attached algorithm, to which all words are passed in the function arguments.
For example:
f ("dfd" dd "ddd");
My code:
fun main() {
var s = readLine();
var w = Array(128){0} //To mark characters from a word 1
var g = Array(128){0}//When we encounter a space, we add units from the first array to the corresponding elements of the second, zeroing them in the first.
if(s!=null)
{
for(c in s)
{
if(c.toInt() > 127 || c.toInt()<0) {
println("Input error, try again");
return;
}
//Checking for space.
if(c.toInt() != 32) w[c.toInt()] = 1;
else
for(k in 0..127)
{
if(w[k] == 1)
{
g[k] += 1;
w[k] = 0;
}
}
}
//For the last word, if there was no space after it.
for(k in 0..127)
{
if(w[k] == 1)
{
g[k] += 1;
w[k] = 0;
}
}
}
//Displaying matched characters to the screen
for(k in 0..127)
{
if(g[k]>1)
{
println(k.toChar());
}
}
}
This program searches for characters that match at least two words in a string
Example
input: hello world
output: lo

There's already utilities for these in Kotlin, I highly recommend you to read the docs before asking these type of questions.
The groupingBy should do what you want:
readLine()?.let { input ->
input.groupingBy { it }.eachCount()
.forEach { if (it.value > 1 && it.key != ' ') println(it.key) }
}

Related

Kotlin, memory saving

I'm working on Splay Tree. I have a lot of command input (add, delete and etc), Hence the output is also huge (32MB of text in a txt file)
I have a memory problem, I am currently using two MultitableList and I have 200 MB of virtual memory (128 MB is needed for the project)
I run on Linux with the command:
$ kotlinc Kotlin.kt -include-runtime -d outPutFile.jar
$ /usr/bin/time -v java -jar outPutFile.jar
result: Maximum resident set size (kbytes): 249732 (With each launch different sizes but about 200)
how can i reduce the size? I need to change the size after each cycle
class SplayTree {
var ROOT: Node? = null
class Node(val key: Long, var value: String?) {
var _parent: SplayTree.Node? = null
var _RightChild: SplayTree.Node? = null
var _LeftChild: SplayTree.Node? = null
... there is a code here ...
// for output
override fun toString(): String {
if (_parent == null) {
return "[${key} ${value}]"
} else {
return "[${key} ${value} ${_parent!!.key}]"
}
}
}
... there is a code here ...
override fun toString(): String {
if (ROOT == null) {
return "_"
}
println(ROOT)
var NOWqueueList: List<Node?> = listOf(ROOT)
var BABYqueue: MutableList<Node?> = MutableList(0) { null }
//var NOWqueueList = Array<Node?>(1, {ROOT}) // Array
//var BABYqueue = Array<Node?>(1, {null}) // Array
//var n = 1 // Array
for (h in 1 until height(ROOT)) {
// for Array
//var pos = -1
//n *= 2
//BABYqueue = Array<Node?>(n, {null}) //for future line
for (ROOTList in NOWqueueList) {
//pos++ // Array
if ( ROOTList != null){
//left
if (ROOTList.haveLeftBaby()) {
//BABYqueue[pos] = ROOTList._LeftChild // Array
BABYqueue.add(ROOTList._LeftChild)
print(ROOTList._LeftChild.toString())
print(" ")
} else {
//BABYqueue[pos] = null // Array
BABYqueue.add(null)
print("_ ")
}
//pos++ // Array
//right
if (ROOTList.haveRightBaby()) {
//BABYqueue[pos] = ROOTList._RightChild // Array
BABYqueue.add(ROOTList._RightChild)
print(ROOTList._RightChild.toString())
print(" ")
} else {
//BABYqueue[pos] = null
BABYqueue.add(null)
print("_ ")
}
} else{ //если пустой то + 2 "_"
//BABYqueue[pos] = null // Array
//pos++ // Array
//BABYqueue[pos] = null // Array
BABYqueue.add(null)
BABYqueue.add(null)
print("_ _ ")
}
}
//NOWqueueList.clear() //worked when was MultitableList
NOWqueueList = BABYqueue.toList() // equate
//NOWqueueList = BABYqueue.clone() // Array
//println(NOWqueueList.joinToString(" ")) // вывожу готовый
println()
BABYqueue.clear()
}
//NOWqueueList.clear()
BABYqueue.clear()
return " end="
}
}
fun main() {
... there is a code here ...
}
I tried using Array, it still came out as with MultitableList

Use of uninitialized value of type Any in numeric context raku

I've come across a programming question at reddit (Take a look at the link for the question)
This was one the solutions in Python:
s="112213"
k=2
result=0
for i in range(len(s)):
num_seen = 0
window = {}
for ind in range(i, len(s)):
if not s[ind] in window:
num_seen += 1
window[s[ind]] = 1
else:
window[s[ind]] += 1
if window[s[ind]] == k:
num_seen -= 1
if num_seen == 0:
result +=1
elif window[s[ind]] > k:
break
print(result)
I've tried to port this solution into Raku and here is my code:
my #s=<1 1 2 2 1 3>;
my $k=2;
my $res=0;
for ^#s {
my $seen = 0;
my %window;
for #s[$_..*] {
if $^a == %window.keys.none {
$seen++;
%window{$^a} = 1;}
else {
%window{$^a} += 1;}
if %window{$^a} == $k {
$seen--;
if $seen == 0 {
$res++;} }
elsif %window{$^a} > $k {
last;}}}
say $res;
It gives this error:
Use of an uninitialized value of type Any in a numeric context in a block at ... line 13
How to fix it?
I don't feel that's a MRE. There are too many issues with it for me to get in to. What I did instead is start from the original Python and translated that. I'll add some comments:
my \s="112213" .comb; # .comb to simulate Python string[n] indexing.
my \k=2;
my $result=0; # result is mutated so give it a sigil
for ^s -> \i { # don't use $^foo vars with for loops
my $num_seen = 0;
my \window = {}
for i..s-1 -> \ind {
if s[ind] == window.keys.none { # usefully indent code!
$num_seen += 1;
window{s[ind]} = 1
} else {
window{s[ind]} += 1
}
if window{s[ind]} == k {
$num_seen -= 1;
if $num_seen == 0 {
$result +=1
}
} elsif window{s[ind]} > k {
last
}
}
}
print($result)
displays 4.
I'm not saying that's a good solution in Raku. It's just a relatively mechanical translation. Hopefully it's helpful.
As usual, the answer by #raiph is correct. I just want to do the minimal changes to your program that get it right. In this case, it's simply adding indices to both loops to make stuff clearer. You were using the context variable $_ in the first, and $^a in the second (inner), and it was getting unnecesarily confusing.
my #s=<1 1 2 2 1 3>;
my $k=2;
my $res=0;
for ^#s -> $i {
my $seen = 0;
my %window;
for #s[$i..*] -> $c {
if $c == %window.keys.none {
$seen++;
%window{$c} = 1;
} else {
%window{$c} += 1;
}
if %window{$c} == $k {
$seen--;
if $seen == 0 {
$res++;
}
} elsif %window{$c} > $k {
last;
}
}
}
say $res;
As you see , besides trying to indent everything a bit more properly, the only additional thing is to add -> $i and -> $c so that loops are indexed, and then use them where you were using implicit variables.

Return Option inside Loop

The program aims to use a loop to check if the index of a iterator variable meets certain criteria (i.g., index == 3). If find the desired index, return Some(123), else return None.
fn main() {
fn foo() -> Option<i32> {
let mut x = 5;
let mut done = false;
while !done {
x += x - 3;
if x % 5 == 0 {
done = true;
}
for (index, value) in (5..10).enumerate() {
println!("index = {} and value = {}", index, value);
if index == 3 {
return Some(123);
}
}
return None; //capture all other other possibility. So the while loop would surely return either a Some or a None
}
}
}
The compiler gives this error:
error[E0308]: mismatched types
--> <anon>:7:9
|
7 | while !done {
| ^ expected enum `std::option::Option`, found ()
|
= note: expected type `std::option::Option<i32>`
= note: found type `()`
I think the error source might be that a while loop evaluates to a (), thus it would return a () instead of Some(123). I don't know how to return a valid Some type inside a loop.
The value of any while true { ... } expression is always (). So the compiler expects your foo to return an Option<i32> but finds the last value in your foo body is ().
To fix this, you can add a return None outside the original while loop. You can also use the loop construct like this:
fn main() {
// run the code
foo();
fn foo() -> Option<i32> {
let mut x = 5;
loop {
x += x - 3;
for (index, value) in (5..10).enumerate() {
println!("index = {} and value = {}", index, value);
if index == 3 {
return Some(123);
}
}
if x % 5 == 0 {
return None;
}
}
}
}
The behaviour of while true { ... } statements is maybe a bit quirky and there have been a few requests to change it.

Infix to Postfix Conversion

I'm trying to code that converts infix expressions to postfix expressions. Currently, the program works correctly if I enter for e.g "5+6" it will output the correct answer which is "5 6 +". The problem occurs when I enter more than one operator for e.g "5+6-3", it outputs and incorrect answer "+3-". Can someone please point out where I'm making the error ? Thanks, in advance !
void main(){
Stack *s = new Stack;
string input;
cout <<"Enter Expression"<<endl;
cin>>input;
InfixToPostfix(input);
system("PAUSE");
}
string InfixToPostfix(string input){
Stack *S = new Stack();
string postfix = "";
for (int i=0; i < input.length();i++){
if (input[i]== ' '||input[i]==',') continue;
else if (IsOperator(input[i]))
{
while(!S->IsStackEmpty() && S->StackTop() != '(' && HasHigherPrecedence(S->StackTop(),input[i]))
{
postfix=S->StackTop();
S->Pop();
}
S->Push(input[i]);
}
else if(IsOperand(input[i]))
{
postfix +=input[i];
}
else if (input[i] == '(')
{
S->Push(input[i]);
}
else if (input[i]==')')
{
while(!S->IsStackEmpty() && S->StackTop() != '('){
postfix += S->StackTop();
S->Pop();
}
S->Pop();
}
}
while(!S->IsStackEmpty()){
postfix +=S->StackTop();
S->Pop();
}
cout <<""<<postfix;
return postfix;
}
bool IsOperand(char C)
{
if(C>= '0' && C<= '9') return true;
if(C>= 'a' && C<= 'z') return true;
if(C>= 'A' && C<= 'Z') return true;
return false;
}
bool IsOperator(char C)
{
if(C=='+' || C== '-' || C =='*' || C == '/' ||C == '$')
{
return true;
}else{
return false;
}
}
int IsRightAssociative(char op)
{
if(op=='$'){
return true;
}else{
return false;
}
}
int GetOperatorWeight(char op){
int weight = -1;
switch(op)
{
case'+':
case '-':
weight=1;
break;
case '*':
case '/':
weight=2;
break;
case '$':
weight=3;
break;
}
return weight;
}
int HasHigherPrecedence ( char op1, char op2)
{
int op1Weight= GetOperatorWeight(op1);
int op2Weight = GetOperatorWeight(op2);
if(op1Weight == op2Weight)
{
if(IsRightAssociative(op1))
{
return false;
}else{
return true;
}
return op1Weight > op2Weight ? true:false;
}
}
One suggestion: use a tree, rather than a stack, as an intermediate data structure. Let the operator with lowest precedence be the root of the tree and build it recursively from there. Then walk through the tree from left to right, again recursively, to generate the postfix version. That way, you can also keep track of the maximum stack depth for the postfix version, which can be important as many hand-held RPN calculators, for example, have very limited stack depths.

How to access Topic name from pdfs using poppler?

I am using poppler, and I want to access topic or headings of a particular page number using poppler, so please tell me how to do this using poppler.
Using the glib API. Don't know which API you want.
I'm pretty sure there is no topic/heading stored with a particular page.
You have to walk the index, if there is one.
Walk the index with backtracking. If you are lucky, each index node contains a PopplerActionGotoDest (check type!).
You can grab the title from the PopplerAction object (gchar *title) and get the page number from the included PopplerDest (int page_num).
page_num should be the first page of the section.
Assuming your PDF has an index containing PopplerActionGotoDest objects.
Then you simply walk it, checking for the page_num.
If page_num > searched_num, go back one step.
When you are at the correct parent, walk the childs. This should give you the best match.
I just made some code for it:
gchar* getTitle(PopplerIndexIter *iter, int num, PopplerIndexIter *last,PopplerDocument *doc)
{
int cur_num = 0;
int next;
PopplerAction * action;
PopplerDest * dest;
gchar * title = NULL;
PopplerIndexIter * last_tmp;
do
{
action = poppler_index_iter_get_action(iter);
if (action->type != POPPLER_ACTION_GOTO_DEST) {
printf("No GOTO_DEST!\n");
return NULL;
}
//get page number of current node
if (action->goto_dest.dest->type == POPPLER_DEST_NAMED) {
dest = poppler_document_find_dest (doc, action->goto_dest.dest->named_dest);
cur_num = dest->page_num;
poppler_dest_free(dest);
} else {
cur_num = action->goto_dest.dest->page_num;
}
//printf("cur_num: %d, %d\n",cur_num,num);
//free action, as we don't need it anymore
poppler_action_free(action);
//are there nodes following this one?
last_tmp = poppler_index_iter_copy(iter);
next = poppler_index_iter_next (iter);
//descend
if (!next || cur_num > num) {
if ((!next && cur_num < num) || cur_num == num) {
//descend current node
if (last) {
poppler_index_iter_free(last);
}
last = last_tmp;
}
//descend last node (backtracking)
if (last) {
/* Get the the action and do something with it */
PopplerIndexIter *child = poppler_index_iter_get_child (last);
gchar * tmp = NULL;
if (child) {
tmp = getTitle(child,num,last,doc);
poppler_index_iter_free (child);
} else {
action = poppler_index_iter_get_action(last);
if (action->type != POPPLER_ACTION_GOTO_DEST) {
tmp = NULL;
} else {
tmp = g_strdup (action->any.title);
}
poppler_action_free(action);
poppler_index_iter_free (last);
}
return tmp;
} else {
return NULL;
}
}
if (cur_num > num || (next && cur_num != 0)) {
// free last index_iter
if (last) {
poppler_index_iter_free(last);
}
last = last_tmp;
}
}
while (next);
return NULL;
}
getTitle gets called by:
for (i = 0; i < num_pages; i++) {
iter = poppler_index_iter_new (document);
title = getTitle(iter,i,NULL,document);
poppler_index_iter_free (iter);
if (title) {
printf("title of %d: %s\n",i, title);
g_free(title);
} else {
printf("%d: no title\n",i);
}
}