Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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