Skip to content
Merged
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
8 changes: 8 additions & 0 deletions config.json
Original file line number Diff line number Diff line change
Expand Up @@ -335,6 +335,14 @@
"prerequisites": [],
"difficulty": 5
},
{
"slug": "relative-distance",
"name": "Relative Distance",
"uuid": "c5895419-cba5-446f-b6df-08919b15b568",
"practices": [],
"prerequisites": [],
"difficulty": 5
},
{
"slug": "minesweeper",
"name": "Minesweeper",
Expand Down
39 changes: 39 additions & 0 deletions exercises/practice/relative-distance/.docs/instructions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# Instructions

Your task is to determine the degree of separation between two individuals in a family tree.
This is similar to the pop culture idea that every Hollywood actor is [within six degrees of Kevin Bacon][six-bacons].

- You will be given an input, with all parent names and their children.
- Each name is unique, a child _can_ have one or two parents.
- The degree of separation is defined as the shortest number of connections from one person to another.
- If two individuals are not connected, return a value that represents "no known relationship."
Please see the test cases for the actual implementation.

## Example

Given the following family tree:

```text
┌──────────┐ ┌──────────┐ ┌───────────┐
│ Helena │ │ Erdős ├─────┤ Shusaku │
└───┬───┬──┘ └─────┬────┘ └────┬──────┘
┌───┘ └───────┐ └───────┬───────┘
┌─────┴────┐ ┌────┴───┐ ┌─────┴────┐
│ Isla ├─────┤ Tariq │ │ Kevin │
└────┬─────┘ └────┬───┘ └──────────┘
│ │
┌────┴────┐ ┌────┴───┐
│ Uma │ │ Morphy │
└─────────┘ └────────┘
```

The degree of separation between Tariq and Uma is 2 (Tariq → Isla → Uma).
There's no known relationship between Isla and Kevin, as there is no connection in the given data.
The degree of separation between Uma and Isla is 1.

~~~~exercism/note
Isla and Tariq are siblings and have a separation of 1.
Similarly, this implementation would report a separation of 2 from you to your father's brother.
~~~~

[six-bacons]: https://en.wikipedia.org/wiki/Six_Degrees_of_Kevin_Bacon
12 changes: 12 additions & 0 deletions exercises/practice/relative-distance/.docs/introduction.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# Introduction

You've been hired to develop **Noble Knots**, the hottest new dating app for nobility!
With centuries of royal intermarriage, things have gotten… _complicated_.
To avoid any _oops-we're-twins_ situations, your job is to build a system that checks how closely two people are related.

Noble Knots is inspired by Iceland's "[Islendinga-App][islendiga-app]," which is backed up by a database that traces all known family connections between Icelanders from the time of the settlement of Iceland.
Your algorithm will determine the **degree of separation** between two individuals in the royal family tree.

Will your app help crown a perfect match?

[islendiga-app]: https://web.archive.org/web/20250816223614/http://www.islendingaapp.is/information-in-english/
19 changes: 19 additions & 0 deletions exercises/practice/relative-distance/.meta/config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"authors": [
"BNAndras"
],
"files": {
"solution": [
"zcl_relative_distance.clas.abap"
],
"test": [
"zcl_relative_distance.clas.testclasses.abap"
],
"example": [
".meta/zcl_relative_distance.clas.abap"
]
},
"blurb": "Given a family tree, calculate the degree of separation.",
"source": "vaeng",
"source_url": "https://github.com/exercism/problem-specifications/pull/2537"
}
31 changes: 31 additions & 0 deletions exercises/practice/relative-distance/.meta/tests.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# This is an auto-generated file.
#
# Regenerating this file via `configlet sync` will:
# - Recreate every `description` key/value pair
# - Recreate every `reimplements` key/value pair, where they exist in problem-specifications
# - Remove any `include = true` key/value pair (an omitted `include` key implies inclusion)
# - Preserve any other key/value pair
#
# As user-added comments (using the # character) will be removed when this file
# is regenerated, comments can be added via a `comment` key.

[4a1ded74-5d32-47fb-8ae5-321f51d06b5b]
description = "Direct parent-child relation"

[30d17269-83e9-4f82-a0d7-8ef9656d8dce]
description = "Sibling relationship"

[8dffa27d-a8ab-496d-80b3-2f21c77648b5]
description = "Two degrees of separation, grandchild"

[34e56ec1-d528-4a42-908e-020a4606ee60]
description = "Unrelated individuals"

[93ffe989-bad2-48c4-878f-3acb1ce2611b]
description = "Complex graph, cousins"

[2cc2e76b-013a-433c-9486-1dbe29bf06e5]
description = "Complex graph, no shortcut, far removed nephew"

[46c9fbcb-e464-455f-a718-049ea3c7400a]
description = "Complex graph, some shortcuts, cross-down and cross-up, cousins several times removed, with unrelated family tree"
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
CLASS zcl_relative_distance DEFINITION
PUBLIC
FINAL
CREATE PUBLIC .

PUBLIC SECTION.
TYPES:
BEGIN OF ty_family,
parent TYPE string,
children TYPE string_table,
END OF ty_family,
ty_family_tree TYPE STANDARD TABLE OF ty_family WITH KEY parent.

METHODS degree_of_separation
IMPORTING
family_tree TYPE ty_family_tree
person_a TYPE string
person_b TYPE string
RETURNING
VALUE(result) TYPE i.
PROTECTED SECTION.
PRIVATE SECTION.
TYPES:
BEGIN OF ty_connection,
person TYPE string,
relative TYPE string,
END OF ty_connection,
ty_graph TYPE STANDARD TABLE OF ty_connection WITH EMPTY KEY,
ty_names TYPE STANDARD TABLE OF string WITH EMPTY KEY,
BEGIN OF ty_queue_item,
person TYPE string,
degree TYPE i,
END OF ty_queue_item,
ty_queue TYPE STANDARD TABLE OF ty_queue_item WITH EMPTY KEY.

METHODS build_graph
IMPORTING
family_tree TYPE ty_family_tree
RETURNING
VALUE(result) TYPE ty_graph.

METHODS add_connection
IMPORTING
source TYPE string
target TYPE string
CHANGING
graph TYPE ty_graph.

METHODS has_person
IMPORTING
graph TYPE ty_graph
candidate TYPE string
RETURNING
VALUE(result) TYPE abap_bool.

METHODS relatives_of
IMPORTING
graph TYPE ty_graph
source TYPE string
RETURNING
VALUE(result) TYPE ty_names.

ENDCLASS.


CLASS zcl_relative_distance IMPLEMENTATION.
METHOD degree_of_separation.
result = -1.
DATA(graph) = build_graph( family_tree ).

IF has_person( graph = graph candidate = person_a ) = abap_false.
RETURN.
ENDIF.

IF has_person( graph = graph candidate = person_b ) = abap_false.
RETURN.
ENDIF.

DATA(queue) = VALUE ty_queue( ( person = person_a degree = 0 ) ).
DATA(visited) = VALUE ty_names( ( person_a ) ).

WHILE lines( queue ) > 0.
DATA(current) = queue[ 1 ].
DELETE queue INDEX 1.

IF current-person = person_b.
result = current-degree.
RETURN.
ENDIF.

LOOP AT relatives_of( graph = graph source = current-person ) ASSIGNING FIELD-SYMBOL(<relative>).
IF NOT line_exists( visited[ table_line = <relative> ] ).
APPEND <relative> TO visited.
APPEND VALUE #( person = <relative> degree = current-degree + 1 ) TO queue.
ENDIF.
ENDLOOP.
ENDWHILE.
ENDMETHOD.

METHOD build_graph.
LOOP AT family_tree ASSIGNING FIELD-SYMBOL(<family>).
LOOP AT <family>-children ASSIGNING FIELD-SYMBOL(<child>).
add_connection(
EXPORTING
source = <family>-parent
target = <child>
CHANGING
graph = result ).
add_connection(
EXPORTING
source = <child>
target = <family>-parent
CHANGING
graph = result ).

LOOP AT <family>-children ASSIGNING FIELD-SYMBOL(<sibling>).
IF <child> <> <sibling>.
add_connection(
EXPORTING
source = <child>
target = <sibling>
CHANGING
graph = result ).
ENDIF.
ENDLOOP.
ENDLOOP.
ENDLOOP.
ENDMETHOD.

METHOD add_connection.
IF NOT line_exists( graph[ person = source relative = target ] ).
APPEND VALUE #( person = source relative = target ) TO graph.
ENDIF.
ENDMETHOD.

METHOD has_person.
result = line_exists( graph[ person = candidate ] ).
ENDMETHOD.

METHOD relatives_of.
LOOP AT graph ASSIGNING FIELD-SYMBOL(<connection>) WHERE person = source.
APPEND <connection>-relative TO result.
ENDLOOP.
ENDMETHOD.


ENDCLASS.
10 changes: 10 additions & 0 deletions exercises/practice/relative-distance/package.devc.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<abapGit version="v1.0.0" serializer="LCL_OBJECT_DEVC" serializer_version="v1.0.0">
<asx:abap xmlns:asx="http://www.sap.com/abapxml" version="1.0">
<asx:values>
<DEVC>
<CTEXT>Exercism: Relative Distance</CTEXT>
</DEVC>
</asx:values>
</asx:abap>
</abapGit>
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
CLASS zcl_relative_distance DEFINITION
PUBLIC
FINAL
CREATE PUBLIC .

PUBLIC SECTION.
TYPES:
BEGIN OF ty_family,
parent TYPE string,
children TYPE string_table,
END OF ty_family,
ty_family_tree TYPE STANDARD TABLE OF ty_family WITH KEY parent.

METHODS degree_of_separation
IMPORTING
family_tree TYPE ty_family_tree
person_a TYPE string
person_b TYPE string
RETURNING
VALUE(result) TYPE i.
PROTECTED SECTION.
PRIVATE SECTION.

ENDCLASS.


CLASS zcl_relative_distance IMPLEMENTATION.
METHOD degree_of_separation.
" add solution here
ENDMETHOD.


ENDCLASS.
Loading