Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
package com.thealgorithms.datastructures.lists;

import java.util.Objects;

/**
* Node structure for the generic linked list.
*
* @param <E> the type of element held in this node
*/
class LinkedList<E> {
E value;
LinkedList<E> next;

LinkedList(E value) {
this.value = value;
this.next = null;
}
}

/**
* A Self-Organizing Linked List implementation using the Move-To-Front (MTF) strategy.
* When an element is searched, it is automatically moved to the head of the list
* to optimize subsequent lookups.
*
* @param <E> the type of elements held in this list
*/
public class SelfOrganizingLinkedList<E> {
private LinkedList<E> head;
private int size;

public SelfOrganizingLinkedList() {
this.size = 0;
this.head = null;
}

/** Inserts a new value at the end of the list. */
public void insert(E value) {
LinkedList<E> newNode = new LinkedList<>(value);
if (head == null) {
head = newNode;
} else {
LinkedList<E> temp = head;
while (temp.next != null) {
temp = temp.next;
}
temp.next = newNode;
}
size++;
}

/**
* Searches for a value in the list.
* If found, moves the node to the front (head) of the list.
*
* @param key the value to search for
* @return true if the element is present, false otherwise
*/
public boolean search(E key) {
if (head == null) {
return false;
}
if (Objects.equals(head.value, key)) {
return true;
}

LinkedList<E> prev = head;
LinkedList<E> curr = head.next;

while (curr != null && !Objects.equals(curr.value, key)) {
prev = curr;
curr = curr.next;
}

if (curr == null) {
return false;
}

prev.next = curr.next;
curr.next = head;
head = curr;
return true;
}

/** Gets the current head of the list. */
public E getHeadValue() {
return head != null ? head.value : null;
}

/** Returns the size of the list. */
public int getSize() {
return size;
}

/** Returns true if the list contains no elements. */
public boolean isEmpty() {
return head == null;
}
}

37 changes: 37 additions & 0 deletions src/main/java/com/thealgorithms/maths/DisariumNumber.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package com.thealgorithms.maths;

/**
* Disarium number is a number where the sum of its digits powered
* with their respective positions is equal to the number itself.
* Example: 135 = 1^1 + 3^2 + 5^3 = 1 + 9 + 125 = 135
*
* @see <a href="https://en.wikipedia.org/wiki/Disarium_number">Disarium Number</a>
*/
public final class DisariumNumber {

private DisariumNumber() {
}

/**
* Checks if a number is a Disarium number.
*
* @param number the number to check (must be positive)
* @return true if number is Disarium, false otherwise
* @throws IllegalArgumentException if number is not positive
*/
public static boolean isDisarium(int number) {
if (number <= 0) {
throw new IllegalArgumentException("Input must be a positive integer.");
}
int digits = String.valueOf(number).length();
int temp = number;
int sum = 0;
while (temp > 0) {
int lastDigit = temp % 10;
sum += (int) Math.pow(lastDigit, digits);
digits--;
temp /= 10;
}
return sum == number;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
package com.thealgorithms.datastructures.lists;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertTrue;

import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;

public class SelfOrganizingLinkedListTest {
private SelfOrganizingLinkedList<Integer> list;

@BeforeEach
void setUp() {
list = new SelfOrganizingLinkedList<>();
}

@Test
void testSearchOnEmptyList() {
assertFalse(list.search(10));
assertNull(list.getHeadValue());
}

@Test
void testSearchElementAtHeadValueDoesNotChangeStructure() {
list.insert(10);
list.insert(20);
list.insert(30);

assertTrue(list.search(10));
assertEquals(10, list.getHeadValue());
}

@Test
void testMoveMiddleElementToFront() {
list.insert(10);
list.insert(20);
list.insert(30);
list.insert(40);

// Search middle element '30'
assertTrue(list.search(30));

// '30' should now be the new head
assertEquals(30, list.getHeadValue());
}

@Test
void testMoveLastElementToFront() {
list.insert(10);
list.insert(20);
list.insert(30);

// Search last element '30'
assertTrue(list.search(30));

assertEquals(30, list.getHeadValue());
}

@Test
void testSearchNonExistentElement() {
list.insert(10);
list.insert(20);

assertFalse(list.search(99));
assertEquals(10, list.getHeadValue()); // Head remains unchanged
}

@Test
void testMultipleSearchesSequentialMoveToFront() {
list.insert(1);
list.insert(2);
list.insert(3);

list.search(2); // Head becomes 2
assertEquals(2, list.getHeadValue());

list.search(3); // Head becomes 3
assertEquals(3, list.getHeadValue());

list.search(1); // Head becomes 1
assertEquals(1, list.getHeadValue());
}
}
32 changes: 32 additions & 0 deletions src/test/java/com/thealgorithms/maths/DisariumNumberTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package com.thealgorithms.maths;

import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;

import org.junit.jupiter.api.Test;

class DisariumNumberTest {

@Test
void testDisariumNumbers() {
assertTrue(DisariumNumber.isDisarium(1));
assertTrue(DisariumNumber.isDisarium(89));
assertTrue(DisariumNumber.isDisarium(135));
assertTrue(DisariumNumber.isDisarium(175));
assertTrue(DisariumNumber.isDisarium(518));
}

@Test
void testNonDisariumNumbers() {
assertFalse(DisariumNumber.isDisarium(10));
assertFalse(DisariumNumber.isDisarium(100));
assertFalse(DisariumNumber.isDisarium(200));
}

@Test
void testInvalidInput() {
assertThrows(IllegalArgumentException.class, () -> DisariumNumber.isDisarium(0));
assertThrows(IllegalArgumentException.class, () -> DisariumNumber.isDisarium(-5));
}
}
Loading