Implementing Linked List in Kotlin - linked-list

I've recently started learning Kotlin, so I decided to implement some data structures in it.
So, I've tried implementing a singly linked list:
package datastructures
public class LinkedList {
private data class Node(var nodeValue: Int, var next: Node? = null)
private var head: Node? = null
fun insert(n: Int) {
if(head == null) head = Node(n)
else {
var cur = head
while(cur?.next != null) {
cur = cur?.next
}
cur?.next = Node(n)
}
}
fun print() {
var cur = head
while(cur != null) {
print("${cur.nodeValue} ")
cur = cur?.next
}
}
}
fun main(args: Array<String>) {
val n = LinkedList()
n.insert(5)
n.insert(3)
n.print()
}
and I got the following error:
Error:(22, 13) Kotlin: [Internal Error] org.jetbrains.jet.codegen.CompilationException: Back-end (JVM) Internal error: cannot store to value org.jetbrains.jet.codegen.StackValue$OnStack#a0a447f
Cause: cannot store to value org.jetbrains.jet.codegen.StackValue$OnStack#a0a447f
File being compiled and position: (22,13) in C:/Users/Khaled/IdeaProjects/Kotlin/src/LinkedList.kt
PsiElement: cur?.next = Node(n)
The root cause was thrown at: StackValue.java:75
at org.jetbrains.jet.codegen.ExpressionCodegen.genQualified(ExpressionCodegen.java:243)
at org.jetbrains.jet.codegen.ExpressionCodegen.genStatement(ExpressionCodegen.java:262)
at ...
I've been searching here and in google but I can't figure out what's the problem causing this error
Edit:
So I've tried to re-implement the insert function and use requireNotNull() to avoid having the compiler worry about the null-safety stuff.
Here is the code and it's now working:
fun insert(n: Int) {
if (head == null) head = Node(n)
else {
var cur = head!!
while (cur.next != null) {
cur = cur.next!!
}
cur.next = Node(n)
}
}

I think the problem lies in this line:
cur?.next = Node(n)
The problem is that the compiler doesn't know what to do if cur is null. Currently, this results in internal error, but this may be supported in a future version.
For now, the best solution is to rewrite the code such that the compiler could check that cur is never null. The problem is that the compiler assumes that fields declared as var can change at any time, so their values need to be loaded into local variables before checking for null:
var cur = head
if(cur == null) head = Node(n)
else {
var next = cur.next
while(next != null) {
cur = next
next = cur.next
}
cur.next = Node(n)
}

Related

How to print only the value of an enum?

enum Move { rock, paper, scissors }
var playerMove = Move.rock;
print('Player played :${playerMove.name}'); <--- this line here gives me an error
print('AI played :${aiMove.name}'); <--- this line works perfectly though
this is the error code:
Unhandled exception:
NoSuchMethodError: Class 'Move' has no instance getter 'name'.
Receiver: Instance of 'Move'
Tried calling: name
import 'dart:io';
import 'dart:math';
enum Move { rock, paper, scissors }
void main() {
while (true) {
final rng = Random();
stdout.write('Rock, paper, scissors (r,p,s): ');
final input = stdin.readLineSync();
if (input == 'r' || input == 'p' || input == 's') {
var playerMove;
if (input == 'r') {
playerMove = Move.rock;
} else if (input == 'p') {
playerMove = Move.paper;
} else {
playerMove = Move.scissors;
}
var random = rng.nextInt(3);
var aiMove = Move.values[random];
print('Input: $input');
print('Player played :${playerMove.name}');
print('AI played :${aiMove.name}');
if (playerMove == aiMove) {
print("It's a draw");
} else if (playerMove == Move.paper && aiMove == Move.rock ||
playerMove == Move.rock && aiMove == Move.scissors ||
playerMove == Move.scissors && aiMove == Move.paper) {
print('Player win');
} else {
print('You lose');
}
} else if (input == 'q') {
break;
} else {
print('Invalid input');
}
}
}
.name is an extension on enum. Dart extensions are static: they are compile-time syntactic sugar, and they therefore require that the object's type be known at compilation time.
You have code:
var playerMove;
if (input == 'r') {
playerMove = Move.rock;
}
...
var playerMove; does not specify a type for the variable, and there is no initializer to infer its type from. It therefore is implicitly declared as dynamic, and extensions on enum will not be applied to it.
You can fix it by specifying an explicit type:
Move playerMove;

getting full linked list without usage of loop?

LinkedListA = 3->4->5
LinkedListB = 12->6->9
I am simply trying to add linkedlistB at the end of the first linkedlistA.
I am not able to figure out Why the final while loop is able to print
the complete linkedlistA WITH all the nodes added from linkedlistB!
public static void joinLists(Node headA, Node headB)
{
Node currentA = headA;
Node currentB = headB;
while( currentA.nextLink != null )
{
currentA = currentA.nextLink;
}
Node newElement = currentB;
currentA.nextLink = newElement; //there is not loop here as you can see to keep updating the list with newElement taking new currentB value
currentB = currentB.nextLink;
currentA = headA;
while(currentA != null)
{
System.out.println(currentA.data);
currentA = currentA.nextLink; //output 3->4->5->12->6->9 How!?
}
}
My initial logic was doing simply this:-
public static void joinLists(Node headA, Node headB)
{
Node currentA = headA;
Node currentB = headB;
while (currentB != null)
{
currentA = head;
while( currentA.nextLink != null )
{
currentA = currentA.nextLink;
}
Node newElement = currentB;
currentA.nextLink = newElement;
currentB = currentB.nextLink;
}
currentA = headA;
while(currentA != null)
{
System.out.println(currentA.data);
currentA = currentA.nextLink;
}
}
But this doesn't seem to work!
But before that tell me how the first code seems to work?
You made the last node in A (the 5) point to the first node in B (the 12), which exactly corresponds to your output. You don't need a loop because the connections are distributed: each node only knows where the next node is. In attaching B to the end of A, only 1 link changes: the one you changed.
The first loop appends the list headB at the end of list headA.
public static Node joinLists(Node headA, Node headB)
{
if (headA == null)
{
headA = headB;
}
else
{
Node currentA = headA;
while (currentA.nextLink != null)
{
currentA = currentA.nextLink;
}
currentA.nextLink = headB;
}
Node current = headA;
while (current != null)
{
System.out.println(current.data);
current = current.nextLink;
}
return headA;
}
Then the printing loop would work.
In your second loop you tried something out (curretnA = head;).
Less variables will make understanding easier, as shown here.
One must use the return value for the joined list, as headA could be null.
LinkedList Data Structure work by the principal of ValueByReference Logic, that means, each node of linkedList can be stored anywhere in the memory location, we are just linking each node by mapping memory address to "Node.next" field
In First logic Code
Node newElement = currentB;
currentA.nextLink = newElement;
currentB = currentB.nextLink;
Your directly mapping headB pointer to last element in LinkedListA, so it similar to connecting each node in LinkedList.

What will be the time complexity of reversing the linked list in a different way using below code?

Given a linked List $link1, with elements (a->b->c->d->e->f->g->h->i->j), we need to reverse the linked list provided that the reversing will be done in a manner like -
Reverse 1st element (a)
Reverse next 2 elements (a->c->b)
Reverse next 3 elements (a->c->b->f->e->d)
Reverse next 4 elements (a->c->b->f->e->d->j->i->h->g)
....
....
I have created below code in PHP to solve this problem
Things I need -
I need to calculate the time complexity of reverseLinkedList function below.
Need to know if we can optimize reverseLinkedList function to reduce time complexity.
-
class ListNode
{
public $data;
public $next;
function __construct($data)
{
$this->data = $data;
$this->next = NULL;
}
function read_node()
{
return $this->data;
}
}
class LinkList
{
private $first_node;
private $last_node;
private $count;
function __construct()
{
$this->first_node = NULL;
$this->last_node = NULL;
$this->count = 0;
}
function size()
{
return $this->count;
}
public function read_list()
{
$listData = array();
$current = $this->first_node;
while($current != NULL)
{
echo $current->read_node().' ';
$current = $current->next;
}
}
public function reverse_list()
{
if(($this->first_node != NULL)&&($this->first_node->next != NULL))
{
$current = $this->first_node;
$new = NULL;
while ($current != NULL)
{
$temp = $current->next;
$current->next = $new;
$new = $current;
$current = $temp;
}
$this->first_node = $new;
}
}
public function read_node($position)
{
if($position <= $this->count)
{
$current = $this->first_node;
$pos = 1;
while($pos != $position)
{
if($current->next == NULL)
return null;
else
$current = $current->next;
$pos++;
}
return $current->data;
}
else
return NULL;
}
public function insert($data)
{
$new_node = new ListNode($data);
if($this->first_node != NULL)
{
$this->last_node->next = $new_node;
$new_node->next = NULL;
$this->last_node = &$new_node;
$this->count++;
}
else
{
$new_node->next = $this->first_node;
$this->first_node = &$new_node;
if($this->last_node == NULL)
$this->last_node = &$new_node;
$this->count++;
}
}
}
//Create linked list
$link1 = new LinkList();
//Insert elements
$link1->insert('a');
$link1->insert('b');
$link1->insert('c');
$link1->insert('d');
$link1->insert('e');
$link1->insert('f');
$link1->insert('g');
$link1->insert('h');
$link1->insert('i');
$link1->insert('j');
echo "<b>Input :</b><br>";
$link1->read_list();
//function to reverse linked list in specified manner
function reverseLinkedList(&$link1)
{
$size= $link1->size();
if($size>2)
{
$link2=new LinkList();
$link2->insert($link1->read_node(1));
$elements_covered=1;
//reverse
$rev_size=2;
while($elements_covered<$size)
{
$start=$elements_covered+1;
$temp_link = new LinkList();
$temp_link->insert($link1->read_node($start));
for($i=1;$i<$rev_size;$i++)
{
$temp_link->insert($link1->read_node(++$start));
}
$temp_link->reverse_list();
$temp_size=$temp_link->size();
$link2_size=$link2->size();
for($i=1;$i<=$temp_size;$i++)
{
$link2->insert($temp_link->read_node($i));
++$elements_covered;
++$link2_size;
}
++$rev_size;
}
///reverse
//Flip the linkedlist
$link1=$link2;
}
}
///function to reverse linked list in specified manner
//Reverse current linked list $link1
reverseLinkedList($link1);
echo "<br><br><b>Output :</b><br>";
$link1->read_list();
It's O(n)...just one traversal.
And secondly, here tagging it in language is not necessary.
I have provided a Pseudocode here for your reference:
current => head_ref
prev => NULL;
current => head_ref;
next => null;
while (current != NULL)
{
next = current->next;
current->next = prev;
prev = current;
current = next;
}
*head_ref = prev;

An exception of type 'System.OutOfMemoryException' occurred in itextsharp.dll but was not handled in user code

I am using iTextSharp to create pdf. I have 100k records, but I am getting following exception:
An exception of type 'System.OutOfMemoryException' occurred in
itextsharp.dll but was not handled in user code At the line:
bodyTable.AddCell(currentProperty.GetValue(lst, null).ToString());
Code is:
var doc = new Document(pageSize);
PdfWriter.GetInstance(doc, stream);
doc.Open();
//Get exportable count
int columns = 0;
Type currentType = list[0].GetType();
//PREPARE HEADER
//foreach visible columns check if current object has proerpty
//else search in inner properties
foreach (var visibleColumn in visibleColumns)
{
if (currentType.GetProperties().FirstOrDefault(p => p.Name == visibleColumn.Key) != null)
{
columns++;
}
else
{
//check child property objects
var childProperties = currentType.GetProperties();
foreach (var prop in childProperties)
{
if (prop.PropertyType.BaseType == typeof(BaseEntity))
{
if (prop.PropertyType.GetProperties().FirstOrDefault(p => p.Name == visibleColumn.Key) != null)
{
columns++;
break;
}
}
}
}
}
//header
var headerTable = new PdfPTable(columns);
headerTable.WidthPercentage = 100f;
foreach (var visibleColumn in visibleColumns)
{
if (currentType.GetProperties().FirstOrDefault(p => p.Name == visibleColumn.Key) != null)
{
//headerTable.AddCell(prop.Name);
headerTable.AddCell(visibleColumn.Value);
}
else
{
//check child property objects
var childProperties = currentType.GetProperties();
foreach (var prop in childProperties)
{
if (prop.PropertyType.BaseType == typeof(BaseEntity))
{
if (prop.PropertyType.GetProperties().FirstOrDefault(p => p.Name == visibleColumn.Key) != null)
{
//headerTable.AddCell(prop.Name);
headerTable.AddCell(visibleColumn.Value);
break;
}
}
}
}
}
doc.Add(headerTable);
var bodyTable = new PdfPTable(columns);
bodyTable.Complete = false;
bodyTable.WidthPercentage = 100f;
//PREPARE DATA
foreach (var lst in list)
{
int col = 1;
foreach (var visibleColumn in visibleColumns)
{
var currentProperty = currentType.GetProperties().FirstOrDefault(p => p.Name == visibleColumn.Key);
if (currentProperty != null)
{
if (currentProperty.GetValue(lst, null) != null)
bodyTable.AddCell(currentProperty.GetValue(lst, null).ToString());
else
bodyTable.AddCell(string.Empty);
col++;
}
else
{
//check child property objects
var childProperties = currentType.GetProperties().Where(p => p.PropertyType.BaseType == typeof(BaseEntity));
foreach (var prop in childProperties)
{
currentProperty = prop.PropertyType.GetProperties().FirstOrDefault(p => p.Name == visibleColumn.Key);
if (currentProperty != null)
{
var currentPropertyObjectValue = prop.GetValue(lst, null);
if (currentPropertyObjectValue != null)
{
bodyTable.AddCell(currentProperty.GetValue(currentPropertyObjectValue, null).ToString());
}
else
{
bodyTable.AddCell(string.Empty);
}
break;
}
}
}
}
}
doc.Add(bodyTable);
doc.Close();
A back of the envelope computation of the memory requirements given the data you provided for memory consumption gives 100000 * 40 * (2*20+4) = 167MBs. Well within your memory limit, but it is just a lower bound. I imagine each Cell object is pretty big. If each cell would have a 512 byte overhead you could be well looking at 2GB taken. I reckon it might be even more, as PDF is a complex beast.
So you might realistically be looking at a situation where you are actually running out of memory. If not your computers, then at least the bit C# has set aside for its own thing.
I would do one thing first - check memory consumption like here. You might even do well to try with 10, 100, 1000, 10000, 100000 rows and see up until what number of rows the program works.
You could perhaps try a different thing altogether. If you're trying to print a nicely formatted table with a lot of data, perhaps you could output an HTML document, which can be done incrementally and which you can do by just writing stuff to a file, rather than using a third party library. You can then "print" that HTML document to PDF. StackOverflow to the rescue again with this problem.

Why am I getting this error in a basic Rails+Ember app?

I am trying to do a simple CRUD app using Ember + Rails and I'm getting the following error when trying to go to the /workouts route.
Error while loading route: TypeError {} ember.js?body=1:415
Uncaught TypeError: Object function () {
if (!wasApplied) {
Class.proto(); // prepare prototype...
}
o_defineProperty(this, GUID_KEY, undefinedDescriptor);
o_defineProperty(this, '_super', undefinedDescriptor);
var m = meta(this), proto = m.proto;
m.proto = this;
if (initMixins) {
// capture locally so we can clear the closed over variable
var mixins = initMixins;
initMixins = null;
this.reopen.apply(this, mixins);
}
if (initProperties) {
// capture locally so we can clear the closed over variable
var props = initProperties;
initProperties = null;
var concatenatedProperties = this.concatenatedProperties;
for (var i = 0, l = props.length; i < l; i++) {
var properties = props[i];
Ember.assert("Ember.Object.create no longer supports mixing in other definitions, use createWithMixins instead.", !(properties instanceof Ember.Mixin));
for (var keyName in properties) {
if (!properties.hasOwnProperty(keyName)) { continue; }
var value = properties[keyName],
IS_BINDING = Ember.IS_BINDING;
if (IS_BINDING.test(keyName)) {
var bindings = m.bindings;
if (!bindings) {
bindings = m.bindings = {};
} else if (!m.hasOwnProperty('bindings')) {
bindings = m.bindings = o_create(m.bindings);
}
bindings[keyName] = value;
}
var desc = m.descs[keyName];
Ember.assert("Ember.Object.create no longer supports defining computed properties.", !(value instanceof Ember.ComputedProperty));
Ember.assert("Ember.Object.create no longer supports defining methods that call _super.", !(typeof value === 'function' && value.toString().indexOf('._super') !== -1));
Ember.assert("`actions` must be provided at extend time, not at create time, when Ember.ActionHandler is used (i.e. views, controllers & routes).", !((keyName === 'actions') && Ember.ActionHandler.detect(this)));
if (concatenatedProperties && indexOf(concatenatedProperties, keyName) >= 0) {
var baseValue = this[keyName];
if (baseValue) {
if ('function' === typeof baseValue.concat) {
value = baseValue.concat(value);
} else {
value = Ember.makeArray(baseValue).concat(value);
}
} else {
value = Ember.makeArray(value);
}
}
if (desc) {
desc.set(this, keyName, value);
} else {
if (typeof this.setUnknownProperty === 'function' && !(keyName in this)) {
this.setUnknownProperty(keyName, value);
} else if (MANDATORY_SETTER) {
Ember.defineProperty(this, keyName, null, value); // setup mandatory setter
} else {
this[keyName] = value;
}
}
}
}
}
finishPartial(this, m);
this.init.apply(this, arguments);
m.proto = proto;
finishChains(this);
sendEvent(this, "init");
} has no method 'find'
My code is located here: https://github.com/ecl1pse/ember-workouts
What am I doing wrong?
Edit: Upon further investigation I believe the culprit is
EmberWorkouts.WorkoutsRoute = Ember.Route.extend(
model: -> EmberWorkouts.Workout.find()
This doesn't actually return anything. How do I debug from there?
If I replace that with this
EmberWorkouts.WorkoutsRoute = Ember.Route.extend
model: -> [{title: 'hi'}, {title: 'damn'}]
The view actually renders content.
How do I get the model to collect from Rails properly?
Ember Data's interface has changed a little with the current release:
You can clear out the store.js file entirely. Ember Data will automatically set up a data store for you using the REST Adapter (unless you tell it otherwise).
Use model: -> #store.find('workout') instead.
I tested this with your app and it works.
If you haven't read through the Ember Data Guide in the last week or two (it's changed a lot), I would spend a few minutes on it.
The fix for this error (as of ember-data 1.0.0.beta.6) for me was to make sure that the JSON returned from the server included an "id" field for each model, BUT not to explicitly declare the id when setting up the Ember DS.Model.
jbuilder template:
json.scans do
json.array! #scans do |scan|
json.id scan.id # This prop has to be there
json.name scan.name
end
end
Ember model:
EmberApp.Scan = DS.Model.extend(
// Don't include the id prop here
name: DS.attr("string")
)

Resources