برنامه نویسی

Codewars – Pick peaks – DEV Community

سلام.

بیل می گوید سلام

من چالش های Codewars و روند فکرم را در این مجموعه پست می کنم. من در صورت امکان از JS و Node 18 استفاده می کنم. فقط برای شفافیت، من از آنها استفاده منصفانه می کنم.

استراحت کردم و الان برگشتم. با این حال، بدون ارسال راه حل در اینجا، برخی از چالش ها را انجام داد. بیایید به یک چالش آسان نزدیک شویم.

پیک پیک ها سرگرم کننده است. شما باید حداکثر محلی را طبق تعریف ریاضی آن پیدا کنید. از GFG:

از نظر ریاضی، f (a) ≥ f (a -h) و f (a) ≥ f (a + h) که در آن h > 0 باشد، سپس a حداکثر نقطه محلی نامیده می شود.

در اصل، ما باید ببینیم که کدام مقادیر از نزدیکترین همسایگانش بزرگتر هستند. اگر همسایه‌ای گم شده است، نمی‌توانیم بررسی کنیم که آیا حداکثر محلی است یا خیر. بنابراین ما مرزهای آرایه را بررسی نمی کنیم.

راه حل زیر بهینه نیست. باید یک پاس باشد. علاوه بر این، به من آموزش داده شد که از مصرف خودداری کنم break و continue. اما این کار را انجام می دهد.

ابتدا قوانین را تعیین می کنیم:

  • اگر آرایه خالی است، آرایه های خالی را برگردانید.
    [] => {pos:[], peaks:[]}
  • اگر مقداری کمتر یا مساوی با مقدار قبلی باشد، به‌طور خودکار کنار گذاشته می‌شود (پلاتوها در قانون دیگری بررسی می‌شوند).
    (array[i] <= array[i-1]) ? discard
  • اگر یک مقدار توسط قانون قبلی کنار گذاشته نشود، و از مقدار بعدی بزرگتر باشد، حداکثر است.
    (array[i] > array[i+1]) ? maximum
  • اگر مقداری با قاعده فوق الذکر نادیده گرفته نشود، و با مقدار بعدی برابر باشد، نیاز به رفتار خاصی دارد. این را بعداً حل خواهیم کرد.

دوم، به یک مقدار بازگشتی خاص نیاز دارد: {pos:[], peaks:[]}
این چالش موقعیت و ارزش حداکثر را می خواهد.

سوم، باید یک حلقه برای آرایه تنظیم کنیم:
for (let i = 1 ; i < arr.length -1 ; i++)
ما از مقدار اول و آخر صرف نظر می کنیم زیرا آنها هرگز طبق تعریف ماکزیمم نخواهند بود.

چهارم، ما قوانین را اجرا می کنیم:

  for (let i = 1 ; i < arr.length -1 ; i++){
    if (arr[i] <= arr[i-1]){
      continue;
    }
    if (arr[i] > arr[i+1]){
      cache.pos.push(i);
      cache.peaks.push(arr[i]);
    }
    if (arr[i] == arr[i+1]){
      // TO DO
    }
  }
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

ما باید قسمت آخر را اصلاح کنیم. این برخورد ویژه ای است که در بالا ذکر شد در هنگام تنظیم قوانین. این فقط یک حلقه دیگر است که به عنوان یک فرآیند فرعی عمل می کند:

    if (arr[i] == arr[i+1]){
      for (let j=i +1 ; j< arr.length - 1; j++){
        if (arr[j] == arr[j+1]){
          continue;
        }
        if (arr[j] < arr[j+1]){
          break;
        }
        if (arr[j] > arr[j+1]){
          cache.pos.push(i);
          cache.peaks.push(arr[i]);
        }
      }
    }
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

مجموع همه اینها این است:

function pickPeaks(arr){
  let cache = {pos:[], peaks:[]};
  if (arr == false) {
    return cache;
  }

  for (let i = 1 ; i < arr.length -1 ; i++){
    if (arr[i] <= arr[i-1]){
      continue;
    }
    if (arr[i] > arr[i+1]){
      cache.pos.push(i);
      cache.peaks.push(arr[i]);
    }
    if (arr[i] == arr[i+1]){
      for (let j=i +1 ; j< arr.length - 1; j++){
        if (arr[j] == arr[j+1]){
          continue;
        }
        if (arr[j] < arr[j+1]){
          break;
        }
        if (arr[j] > arr[j+1]){
          cache.pos.push(i);
          cache.peaks.push(arr[i]);
        }
      }
    }
  }

  return cache;
}
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

و حالا بیایید آن را آزمایش کنیم … بله! گذشت! بیایید ارسال کنیم و …

اوه نه. چی؟؟؟

بیل می گوید سلام

این تست خاص: pickPeaks([1,2,5,4,3,2,3,6,4,1,2,3,3,4,5,3,2,1,2,3,5,5,4,3])
این باید برگردد: {pos:[2,7,14,20], peaks:[5,6,5,5]}
برمی‌گرداند: {pos:[2,7,14,20,20], peaks:[5,6,5,5,5]}

اما چرا؟ منطق منطقی است. و هر حلقه درست است… اوهوم… صبر کنید… تکراری می شود. موقعیت 20، مقدار 5. دو بار آنجاست. اینجا مشکلی وجود دارد:

    if (arr[i] == arr[i+1]){
      for (let j=i +1 ; j< arr.length - 1; j++){
        if (arr[j] == arr[j+1]){
          continue;
        }
        if (arr[j] < arr[j+1]){
          break;
        }
        if (arr[j] > arr[j+1]){
          cache.pos.push(i);
          cache.peaks.push(arr[i]);
        }
      }
    }
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

بعد از مقداری اشکال زدایی با Dev Tools، آن را پیدا کردم. مشکل اینجاست:

        if (arr[j] > arr[j+1]){
          cache.pos.push(i);
          cache.peaks.push(arr[i]);
        }
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

از دست رفته است break بیانیه [...3,5,5,4,3] مقدار دوم را کپی می کند زیرا تنها زمانی از حلقه داخلی خارج می شود که دنباله ای را پیدا کند که در آن شرایط خروج اتفاق می افتد:

        if (arr[j] < arr[j+1]){
          break;
        }
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

وگرنه ادامه میده معلوم شد زمانی که حداکثر را پیدا کرد باید خارج شود:

        if (arr[j] > arr[j+1]){
          cache.pos.push(i);
          cache.peaks.push(arr[i]);
          break; // <------------ EXTREMELY IMPORTANT
        }
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

ثابت شد:

function pickPeaks(arr){
  let cache = {pos:[], peaks:[]};
  if (arr == false) {
    return cache;
  }

  for (let i = 1 ; i < arr.length -1 ; i++){
    if (arr[i] <= arr[i-1]){
      continue;
    }
    if (arr[i] > arr[i+1]){
      cache.pos.push(i);
      cache.peaks.push(arr[i]);
    }
    if (arr[i] == arr[i+1]){
      for (let j=i +1 ; j< arr.length - 1; j++){
        if (arr[j] == arr[j+1]){
          continue;
        }
        if (arr[j] < arr[j+1]){
          break;
        }
        if (arr[j] > arr[j+1]){
          cache.pos.push(i);
          cache.peaks.push(arr[i]);
          break;  // if you don't break, situations like this: 3,5,5,4,3
                  // can duplicate a value..
        }
      }
    }
  }

  return cache;
}
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

ناکارآمد، اما موثر.

مراقب باشید. آب بنوشید 💧💧💧 .

قبلی

نوشته های مشابه

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *

دکمه بازگشت به بالا