المسارات
/
Julia
Julia
/
التمارين
/
البحث عن الكنز في Tisbury
البحث عن الكنز في Tisbury

البحث عن الكنز في Tisbury

تمرين تعلّمي

مقدمة

يتشابه Tuple مع Vector (أي array أحادي البعد) في نواحٍ كثيرة. لكن هناك بعض الفروق المهمة.

  • تُكتب الصفوف بين قوسين هلاليين ( ) بدلًا من قوسين مربعين [ ]، مع أنه يمكن حذف القوسين الهلاليين في الحالات التي لا يكون فيها المعنى ملتبسًا.
  • لا يُشترط أن تكون الصفوف متجانسة: إذ يُخزَّن نوع كل عنصر على حدة.
  • الصفوف غير قابلة للتغيير.

عدم القابلية للتغيير يسمح للمترجم بإجراء تحسينات أكثر، ويجعل الصفوف أسرع أداءً من المتجهات، لذا يُفضَّل استخدامها حين لا تكون القابلية للتغيير ضرورية.

julia> t = (3, 5.2, "xyz")
(3, 5.2, "xyz")

# Non-homogeneous:
julia> dump(t)
Tuple{Int64, Float64, String}
  1: Int64 3
  2: Float64 5.2
  3: String "xyz"

julia> t[2]
5.2

# Immutable:
julia> t[2] = 7.3
ERROR: MethodError: no method matching setindex!(::Tuple{Int64, Float64, String})

توجد أيضًا البانية Tuple()، التي تحوّل أي مجموعة قابلة للتكرار إلى صف. ومن المفيد أنها تتعامل مع السلسلة النصية بوصفها مجموعة قابلة للتكرار من المحارف.

julia> Tuple("Julia")
('J', 'u', 'l', 'i', 'a')

يمكن الوصول إلى عناصر أي صف عبر الفهرس أو المرور عليها بحلقة.

كما يمكن استخدام أي صف رقمي بحت في الدوال الرياضية مثل sum()، تمامًا مثل المصفوفات.

التفكيك

يمكن تفكيك الصف إلى عناصر منفردة باستخدام الإسناد المتعدد. وللعناصر غير المطلوبة، استخدم الشرطة السفلية _ بوصفها متغيرًا صوريًا.

julia> tup = (1, "Julia", true)
(1, "Julia", true)

julia> num, name, _ = tup
(1, "Julia", true)

julia> uppercase(name), 2num
("JULIA", 2)

سيكون مبرمجو Python على دراية تامة بصيغة الإسناد المتعدد هذه.

الصفوف المسماة

يحتوي Tuple على القيم فقط. أما NamedTuple فيقرن كل قيمة باسم.

ويمكن بعد ذلك الوصول إلى الحقول المفردة باستخدام ترميز "النقطة":

julia> nt = (a = 1, b = 7.3)
(a = 1, b = 7.3)

julia> dump(nt)
@NamedTuple{a::Int64, b::Float64}
  a: Int64 1
  b: Float64 7.3

julia> nt.b
7.3

يُخزَّن الاسم داخليًا بوصفه Symbol (نوع غير قابل للتغيير يُسبق بنقطتين رأسيتين :)، لذا تتوفر صيغة بديلة:

julia> nt[:b]
7.3

من السهل الحصول على الأسماء (وتُسمى أيضًا "المفاتيح") أو على القيم بشكل منفصل:

julia> nt
(a = 1, b = 7.3)

julia> keys(nt)
(:a, :b)

julia> values(nt)
(1, 7.3)

لاحظ أن التكرار على صف مسمّى ينتج القيم فقط، بينما تُهمَل الأسماء.

تُعدّ الصفوف (المسمّاة أو غير المسمّاة) وسيلة شائعة جدًا لنقل البيانات المهيكلة من الدوال وإليها. وعدم القابلية للتغيير مفيد في هذه الحالة، لأنه يوفّر أمان البيانات ويتيح للمترجم إجراء تحسينات أكثر جرأة.

التعليمات

Azara وRui زميلان في فريق واحد يتنافسان في رحلة بحث عن الكنز بطابع القراصنة. لدى أحدهما قائمة بالكنوز مع إحداثيات على الخريطة، ولدى الآخر قائمة بأسماء المواقع مع إحداثيات على الخريطة. وقد أُعطيت لهما أيضًا خرائط فارغة فيها موضع البداية مكتوب عنده «أنت هنا».

قائمة Azara قائمة Rui
Treasure Coordinates
Amethyst Octopus 1F
Angry Monkey Figurine 5B
Antique Glass Fishnet Float 3D
Brass Spyglass 4B
Carved Wooden Elephant 8C
Crystal Crab 6A
Glass Starfish 6D
Model Ship in Large Bottle 8A
Pirate Flag 7F
Robot Parrot 1C
Scrimshaw Whale's Tooth 2A
Silver Seahorse 4E
Vintage Pirate Hat 7E
Location Name Coordinates Quadrant
Seaside Cottages ('1', 'C') Blue
Aqua Lagoon (Island of Mystery) ('1', 'F') Yellow
Deserted Docks ('2', 'A') Blue
Spiky Rocks ('3', 'D') Yellow
Abandoned Lighthouse ('4', 'B') Blue
Hidden Spring (Island of Mystery) ('4', 'E') Yellow
Stormy Breakwater ('5', 'B') Purple
Old Schooner ('6', 'A') Purple
Tangled Seaweed Patch ('6', 'D') Orange
Quiet Inlet (Island of Mystery) ('7', 'E') Orange
Windswept Hilltop (Island of Mystery) ('7', 'F') Orange
Harbor Managers Office ('8', 'A') Purple
Foggy Seacave ('8', 'C') Purple

لكن الأمور غير منظمة بعض الشيء: يبدو أن إحداثيات Azara منسّقة ومرتبة بشكل مختلف عن إحداثيات Rui، وعليهما أن ينتقلا بنظرهما بين القائمتين ليكتشفا أي الكنوز يقابل أي المواقع. ولأنهما مبرمجان ناشئان في Julia، فقد جاءا إليك طلبًا للمساعدة في كتابة برنامج صغير (مجموعة من الدوال في الحقيقة) لتنظيم معلومات رحلتهما بشكل أفضل.

1. استخراج الإحداثيات

نفّذ الدالة get_cooordinate() التي تأخذ زوجًا (treasure, coordinate) من قائمة Azara وتُرجع إحداثي الخريطة المستخرج فقط.

julia> get_cooordinate( ("Scrimshaw Whale's Tooth", "2A") )
"2A"

2. تنسيق الإحداثيات

نفّذ الدالة convert_coordinate() التي تأخذ إحداثيًا بالصيغة "2A" وتُرجع مجموعة مرتّبة بالصيغة ('2', 'A').

julia> convert_coordinate("2A")
('2', 'A')

3. مطابقة الإحداثيات

نفّذ الدالة compare_records() التي تأخذ زوجًا (treasure, coordinate) وسجلًا (location, coordinate, quadrant) وتقارن الإحداثيات في كل منهما. أرجع true إذا تطابقت الإحداثيات، وأرجع false إذا لم تتطابق. أعد تنسيق الإحداثيات عند الحاجة لإجراء مقارنة دقيقة.

julia> compare_records(("Brass Spyglass", "4B"), ("Seaside Cottages", ('1', 'C'), "blue"))
false

julia> compare_records(("Model Ship in Large Bottle", "8A"), ("Harbor Managers Office", ('8', 'A'), "purple"))
true

4. دمج السجلات المتطابقة

نفّذ الدالة create_record() التي تأخذ زوجًا (treasure, coordinate) من قائمة Azara وسجلًا (location, coordinate, quadrant) من قائمة Rui وتُرجع (coordinate, location, quadrant, treasure) إذا تطابقت الإحداثيات.

إذا لم تتطابق الإحداثيات، فأرجع مجموعة مرتّبة فارغة. أعد تنسيق الإحداثيات عند الحاجة لإجراء مقارنة دقيقة.

julia> create_record(("Brass Spyglass", "4B"), ("Abandoned Lighthouse", ('4', 'B'), "Blue"))
("4B", "Abandoned Lighthouse", "Blue", "Brass Spyglass")

julia> create_record(("Brass Spyglass", "4B"), ("Seaside Cottages", ('1', 'C'), "Blue"))
()
تعديل عبر GitHub يفتح الرابط في نافذة أو علامة تبويب جديدة
Julia Exercism

مستعد لبدء البحث عن الكنز في Tisbury؟

سجّل في Exercism لتتعلّم وتتقن Julia عبر 35 مفهومًا128 تمرينًا، وإرشاد بشري حقيقي، وكل ذلك مجانًا.