Bandwagoner

Bandwagoner

تمرين تعلّمي

مقدمة

السجلات

السجل مجموعة من الحقول (التي يمكن أن تكون من أنواع مختلفة) ترتبط ببعضها. لتعريف سجل تُستخدم الكلمة المفتاحية type. تُعرَّف حقول السجل بين المحرفين { و}، ولكل حقل اسم _و_نوع. ولإنشاء سجل، حدّد أسماء الحقول وأسنِد إليها قيمًا بين المحرفين { و}. ويجب إسناد قيمة إلى كل الحقول عند إنشاء السجل. ويمكن الوصول إلى قيم حقول نسخة السجل باستخدام الترميز النقطي.

عند تعريف سجل أو إنشائه، يجب أن يكون كل حقل في سطر منفصل، أو أن تفصل بين الحقول بفواصل منقوطة (;) إذا كانت في سطر واحد.

// Define a record
type Address =
    { Street: string
      HouseNumber: int }

// Create a record
let oldAddress: Address =
    { Street = "Main Street"
      HouseNumber = 17 }

// Single-line alternative
type ConciseAddress = { Street: string; HouseNumber: int }
let conciseAddress: ConciseAddress = { Street = "Main Street"; HouseNumber = 17 }

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

// Copy the old address but change the house number
let newAddress: Address = { oldAddress with HouseNumber = 86 }
newAddress.Street      // => "Main Street"
newAddress.HouseNumber // => 86

للسجلات مساواة بنيوية، وهذا يعني أن نسختين من السجل نفسه بقيم متطابقة تكونان متكافئتين.

وإلى جانب إمكانية استخدام الترميز النقطي للوصول إلى حقول السجل، يمكن أيضًا تفكيك السجلات في الارتباطات وفي مطابقة الأنماط:

let myAddress: Address = { Street = "Broadway"; HouseNumber = 123 }
let { Street = myStreet; HouseNumber = myHouseNumber } = myAddress

match myAddress with
| { HouseNumber = 1 } -> printfn "First house"
| { HouseNumber = houseNumber; Street = street } -> printfn "House number %d on %s" houseNumber street
// => "House number 123 on Broadway

التعليمات

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

ولأنه ليس لديك فريق مفضّل بعد، ستطوّر أيضًا خوارزمية لتحديد ما إذا كان ينبغي لك تشجيع فريق معيّن.

أمامك سبع مهام تساعدك على تطوير خوارزميتك الخاصة لتشجيع فريق ما.

1. عرّف النموذج

عرّف سجل Coach بالحقلين التاليين:

  • Name: اسم المدرب، من النوع string.
  • FormerPlayer: يشير إلى ما إذا كان المدرب لاعبًا سابقًا، من النوع bool.

عرّف سجل Stats بالحقلين التاليين:

  • Wins: عدد مرات الفوز، من النوع int.
  • Losses: عدد مرات الخسارة، من النوع int.

عرّف سجل Team بالحقول الثلاثة التالية:

  • Name: اسم الفريق، من النوع string.
  • Coach: مدرب الفريق، من النوع Coach.
  • Stats: إحصاءات الفريق، من النوع Stats.

2. أنشئ مدرب الفريق

نفّذ الدالة createCoach التي تأخذ اسم المدرب وحالته كلاعب سابق معاملين، وتُرجع سجل Coach الخاص به:

createCoach "Larry Bird" true
// => { Name = "Larry Bird"; FormerPlayer = true }

3. أنشئ إحصاءات الفريق

نفّذ الدالة createStats التي تأخذ عدد مرات الفوز وعدد مرات الخسارة معاملين، وتُرجع سجل Stats الخاص به:

createStats 58 24
// => { Wins = 58; Losses = 24 }

4. أنشئ فريقًا

نفّذ الدالة createTeam التي تأخذ اسم الفريق والمدرب والسجل معاملات، وتُرجع سجل Team الخاص به:

let coach = createCoach "Larry Bird" true
let record = createStats 58 24
createTeam "Indiana Pacers" coach record
// => { Name = "Indiana Pacers"
//      Coach = { Name = "Larry Bird"; FormerPlayer = true }
//      Stats = { Wins = 58; Losses = 24 } }

5. استبدل المدرب

ولأن مالكي فرق NBA لا يتحلّون بالصبر، اكتشفت أن النتائج السيئة للفريق كثيرًا ما تؤدي إلى استبدال المدرب. نفّذ الدالة replaceCoach التي تأخذ الفريق ومدربه الجديد معاملين، وتُرجع الفريق نفسه مع المدرب الجديد:

let coach = createCoach "Larry Bird" true
let record = createStats 58 24
let team = createTeam "Indiana Pacers" coach record

let newCoach = createCoach "Isiah Thomas" true
replaceCoach team newCoach
// => { Name = "Indiana Pacers"
//      Coach = { Name = "Isiah Thomas"; FormerPlayer = true }
//      Stats = { Wins = 58; Losses = 24 } }

6. تحقّق من تطابق الفريقين

أثناء تعمّقك في الإحصاءات، تحتفظ بمصفوفات للفرق وسجلاتها. وأحيانًا تخطئ فتظهر إدخالات مكرّرة في مصفوفتك. نفّذ الدالة isSameTeam التي تأخذ فريقين وتُرجع true إذا كانا الفريق نفسه، وإلا فتُرجع false:

let pacersCoach = createCoach "Larry Bird" true
let pacersStats = createStats 58 24
let pacersTeam = createTeam "Indiana Pacers" pacersCoach pacersStats

let lakersCoach = createCoach "Del Harris" false
let lakersStats = createStats 61 21
let lakersTeam = createTeam "LA Lakers" lakersCoach lakersStats

isSameTeam pacersTeam lakersTeam
// => false

7. تحقّق مما إذا كان ينبغي لك تشجيع فريق

بعد أن نظرت في فرق ومباريات كثيرة، توصّلت إلى خوارزمية. إذا تحقّق أحد ما يلي، فأنت تشجّع ذلك الفريق:

  • اسم المدرب هو "Gregg Popovich"
  • المدرب لاعب سابق
  • اسم الفريق هو "Chicago Bulls"
  • حقّق الفريق 60 فوزًا أو أكثر
  • عدد مرات خسارة الفريق أكثر من عدد مرات فوزه

نفّذ الدالة rootForTeam التي تأخذ فريقًا وتُرجع true إذا كان ينبغي لك تشجيع ذلك الفريق، وإلا، return false:

let spursCoach = createCoach "Gregg Popovich" false
let spursStats = createStats 56 26
let spursTeam = createTeam "San Antonio Spurs" spursCoach spursStats
rootForTeam spursTeam
// => true
تعديل عبر GitHub يفتح الرابط في نافذة أو علامة تبويب جديدة
F# Exercism

مستعد لبدء Bandwagoner؟

سجّل في Exercism لتتعلّم وتتقن F# عبر 18 مفهومًا148 تمرينًا، وإرشاد بشري حقيقي، وكل ذلك مجانًا.